From 19d701ddf07d855128ded0cf2b573ce468e3bdd6 Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Wed, 20 Jan 2016 01:10:01 +0000 Subject: Removing Suricata and Audit from source repo, and updated build.sh to avoid building suricata. Will re-address this in C release via tar balls. Change-Id: I3710076f8b7f3313cb3cb5260c4eb0a6834d4f6e Signed-off-by: Ashlee Young --- framework/src/suricata/src/Makefile.am | 502 - framework/src/suricata/src/action-globals.h | 36 - framework/src/suricata/src/alert-debuglog.c | 526 - framework/src/suricata/src/alert-debuglog.h | 30 - framework/src/suricata/src/alert-fastlog.c | 386 - framework/src/suricata/src/alert-fastlog.h | 33 - framework/src/suricata/src/alert-prelude.c | 885 - framework/src/suricata/src/alert-prelude.h | 31 - framework/src/suricata/src/alert-syslog.c | 427 - framework/src/suricata/src/alert-syslog.h | 33 - framework/src/suricata/src/alert-unified2-alert.c | 1981 -- framework/src/suricata/src/alert-unified2-alert.h | 50 - .../src/suricata/src/app-layer-dcerpc-common.h | 246 - framework/src/suricata/src/app-layer-dcerpc-udp.c | 1115 - framework/src/suricata/src/app-layer-dcerpc-udp.h | 30 - framework/src/suricata/src/app-layer-dcerpc.c | 6411 ------ framework/src/suricata/src/app-layer-dcerpc.h | 44 - .../src/suricata/src/app-layer-detect-proto.c | 3780 ---- .../src/suricata/src/app-layer-detect-proto.h | 197 - framework/src/suricata/src/app-layer-dns-common.c | 1141 -- framework/src/suricata/src/app-layer-dns-common.h | 259 - framework/src/suricata/src/app-layer-dns-tcp.c | 682 - framework/src/suricata/src/app-layer-dns-tcp.h | 38 - framework/src/suricata/src/app-layer-dns-udp.c | 635 - framework/src/suricata/src/app-layer-dns-udp.h | 37 - framework/src/suricata/src/app-layer-events.c | 137 - framework/src/suricata/src/app-layer-events.h | 83 - framework/src/suricata/src/app-layer-ftp.c | 681 - framework/src/suricata/src/app-layer-ftp.h | 133 - framework/src/suricata/src/app-layer-htp-body.c | 264 - framework/src/suricata/src/app-layer-htp-body.h | 36 - framework/src/suricata/src/app-layer-htp-file.c | 1635 -- framework/src/suricata/src/app-layer-htp-file.h | 34 - framework/src/suricata/src/app-layer-htp-libhtp.c | 219 - framework/src/suricata/src/app-layer-htp-libhtp.h | 51 - framework/src/suricata/src/app-layer-htp-mem.c | 150 - framework/src/suricata/src/app-layer-htp-mem.h | 26 - framework/src/suricata/src/app-layer-htp-xff.c | 364 - framework/src/suricata/src/app-layer-htp-xff.h | 54 - framework/src/suricata/src/app-layer-htp.c | 6525 ------ framework/src/suricata/src/app-layer-htp.h | 294 - framework/src/suricata/src/app-layer-modbus.c | 2671 --- framework/src/suricata/src/app-layer-modbus.h | 129 - framework/src/suricata/src/app-layer-nbss.h | 66 - framework/src/suricata/src/app-layer-parser.c | 1387 -- framework/src/suricata/src/app-layer-parser.h | 235 - framework/src/suricata/src/app-layer-protos.c | 91 - framework/src/suricata/src/app-layer-protos.h | 69 - framework/src/suricata/src/app-layer-smb.c | 2717 --- framework/src/suricata/src/app-layer-smb.h | 166 - framework/src/suricata/src/app-layer-smb2.c | 690 - framework/src/suricata/src/app-layer-smb2.h | 83 - framework/src/suricata/src/app-layer-smtp.c | 5025 ----- framework/src/suricata/src/app-layer-smtp.h | 165 - framework/src/suricata/src/app-layer-ssh.c | 2607 --- framework/src/suricata/src/app-layer-ssh.h | 79 - framework/src/suricata/src/app-layer-ssl.c | 4319 ---- framework/src/suricata/src/app-layer-ssl.h | 178 - framework/src/suricata/src/app-layer-template.c | 541 - framework/src/suricata/src/app-layer-template.h | 69 - .../src/suricata/src/app-layer-tls-handshake.c | 204 - .../src/suricata/src/app-layer-tls-handshake.h | 40 - framework/src/suricata/src/app-layer.c | 3521 ---- framework/src/suricata/src/app-layer.h | 141 - framework/src/suricata/src/conf-yaml-loader.c | 949 - framework/src/suricata/src/conf-yaml-loader.h | 33 - framework/src/suricata/src/conf.c | 1532 -- framework/src/suricata/src/conf.h | 93 - framework/src/suricata/src/counters.c | 1500 -- framework/src/suricata/src/counters.h | 150 - framework/src/suricata/src/data-queue.c | 93 - framework/src/suricata/src/data-queue.h | 64 - framework/src/suricata/src/debug.h | 31 - framework/src/suricata/src/decode-erspan.c | 81 - framework/src/suricata/src/decode-erspan.h | 37 - framework/src/suricata/src/decode-ethernet.c | 152 - framework/src/suricata/src/decode-ethernet.h | 52 - framework/src/suricata/src/decode-events.c | 27 - framework/src/suricata/src/decode-events.h | 252 - framework/src/suricata/src/decode-gre.c | 400 - framework/src/suricata/src/decode-gre.h | 83 - framework/src/suricata/src/decode-icmpv4.c | 784 - framework/src/suricata/src/decode-icmpv4.h | 345 - framework/src/suricata/src/decode-icmpv6.c | 1642 -- framework/src/suricata/src/decode-icmpv6.h | 259 - framework/src/suricata/src/decode-ipv4.c | 1913 -- framework/src/suricata/src/decode-ipv4.h | 254 - framework/src/suricata/src/decode-ipv6.c | 1001 - framework/src/suricata/src/decode-ipv6.h | 334 - framework/src/suricata/src/decode-mpls.c | 325 - framework/src/suricata/src/decode-mpls.h | 34 - framework/src/suricata/src/decode-null.c | 89 - framework/src/suricata/src/decode-null.h | 27 - framework/src/suricata/src/decode-ppp.c | 312 - framework/src/suricata/src/decode-ppp.h | 76 - framework/src/suricata/src/decode-pppoe.c | 460 - framework/src/suricata/src/decode-pppoe.h | 82 - framework/src/suricata/src/decode-raw.c | 232 - framework/src/suricata/src/decode-raw.h | 28 - framework/src/suricata/src/decode-sctp.c | 83 - framework/src/suricata/src/decode-sctp.h | 51 - framework/src/suricata/src/decode-sll.c | 76 - framework/src/suricata/src/decode-sll.h | 38 - framework/src/suricata/src/decode-tcp.c | 521 - framework/src/suricata/src/decode-tcp.h | 297 - framework/src/suricata/src/decode-template.c | 97 - framework/src/suricata/src/decode-template.h | 37 - framework/src/suricata/src/decode-teredo.c | 112 - framework/src/suricata/src/decode-teredo.h | 19 - framework/src/suricata/src/decode-udp.c | 218 - framework/src/suricata/src/decode-udp.h | 193 - framework/src/suricata/src/decode-vlan.c | 279 - framework/src/suricata/src/decode-vlan.h | 55 - framework/src/suricata/src/decode.c | 573 - framework/src/suricata/src/decode.h | 1050 - framework/src/suricata/src/defrag-config.c | 162 - framework/src/suricata/src/defrag-config.h | 32 - framework/src/suricata/src/defrag-hash.c | 716 - framework/src/suricata/src/defrag-hash.h | 103 - framework/src/suricata/src/defrag-queue.c | 144 - framework/src/suricata/src/defrag-queue.h | 84 - framework/src/suricata/src/defrag-timeout.c | 153 - framework/src/suricata/src/defrag-timeout.h | 33 - framework/src/suricata/src/defrag.c | 2584 --- framework/src/suricata/src/defrag.h | 125 - framework/src/suricata/src/detect-ack.c | 302 - framework/src/suricata/src/detect-ack.h | 40 - .../src/suricata/src/detect-app-layer-event.c | 836 - .../src/suricata/src/detect-app-layer-event.h | 37 - .../src/suricata/src/detect-app-layer-protocol.c | 407 - .../src/suricata/src/detect-app-layer-protocol.h | 34 - framework/src/suricata/src/detect-asn1.c | 1366 -- framework/src/suricata/src/detect-asn1.h | 47 - framework/src/suricata/src/detect-base64-data.c | 236 - framework/src/suricata/src/detect-base64-data.h | 25 - framework/src/suricata/src/detect-base64-decode.c | 778 - framework/src/suricata/src/detect-base64-decode.h | 33 - framework/src/suricata/src/detect-byte-extract.c | 4897 ----- framework/src/suricata/src/detect-byte-extract.h | 71 - framework/src/suricata/src/detect-bytejump.c | 1429 -- framework/src/suricata/src/detect-bytejump.h | 121 - framework/src/suricata/src/detect-bytetest.c | 1580 -- framework/src/suricata/src/detect-bytetest.h | 129 - framework/src/suricata/src/detect-classtype.c | 342 - framework/src/suricata/src/detect-classtype.h | 31 - framework/src/suricata/src/detect-content.c | 2824 --- framework/src/suricata/src/detect-content.h | 102 - framework/src/suricata/src/detect-csum.c | 1647 -- framework/src/suricata/src/detect-csum.h | 39 - framework/src/suricata/src/detect-dce-iface.c | 1837 -- framework/src/suricata/src/detect-dce-iface.h | 45 - framework/src/suricata/src/detect-dce-opnum.c | 2950 --- framework/src/suricata/src/detect-dce-opnum.h | 43 - framework/src/suricata/src/detect-dce-stub-data.c | 1848 -- framework/src/suricata/src/detect-dce-stub-data.h | 30 - framework/src/suricata/src/detect-depth.c | 156 - framework/src/suricata/src/detect-depth.h | 31 - .../src/suricata/src/detect-detection-filter.c | 665 - .../src/suricata/src/detect-detection-filter.h | 44 - framework/src/suricata/src/detect-distance.c | 270 - framework/src/suricata/src/detect-distance.h | 31 - framework/src/suricata/src/detect-dns-query.c | 1180 -- framework/src/suricata/src/detect-dns-query.h | 33 - framework/src/suricata/src/detect-dsize.c | 838 - framework/src/suricata/src/detect-dsize.h | 42 - .../src/suricata/src/detect-engine-address-ipv4.c | 1614 -- .../src/suricata/src/detect-engine-address-ipv4.h | 39 - .../src/suricata/src/detect-engine-address-ipv6.c | 2279 --- .../src/suricata/src/detect-engine-address-ipv6.h | 43 - framework/src/suricata/src/detect-engine-address.c | 5419 ----- framework/src/suricata/src/detect-engine-address.h | 63 - framework/src/suricata/src/detect-engine-alert.c | 337 - framework/src/suricata/src/detect-engine-alert.h | 38 - .../src/suricata/src/detect-engine-analyzer.c | 926 - .../src/suricata/src/detect-engine-analyzer.h | 42 - .../src/suricata/src/detect-engine-apt-event.c | 79 - .../src/suricata/src/detect-engine-apt-event.h | 34 - .../src/detect-engine-content-inspection.c | 588 - .../src/detect-engine-content-inspection.h | 64 - .../src/suricata/src/detect-engine-dcepayload.c | 10192 ---------- .../src/suricata/src/detect-engine-dcepayload.h | 32 - framework/src/suricata/src/detect-engine-dns.c | 163 - framework/src/suricata/src/detect-engine-dns.h | 40 - framework/src/suricata/src/detect-engine-event.c | 412 - framework/src/suricata/src/detect-engine-event.h | 256 - framework/src/suricata/src/detect-engine-file.c | 301 - framework/src/suricata/src/detect-engine-file.h | 37 - .../src/suricata/src/detect-engine-filedata-smtp.c | 562 - .../src/suricata/src/detect-engine-filedata-smtp.h | 43 - framework/src/suricata/src/detect-engine-hcbd.c | 1116 - framework/src/suricata/src/detect-engine-hcbd.h | 45 - framework/src/suricata/src/detect-engine-hcd.c | 1878 -- framework/src/suricata/src/detect-engine-hcd.h | 39 - framework/src/suricata/src/detect-engine-hhd.c | 3905 ---- framework/src/suricata/src/detect-engine-hhd.h | 41 - framework/src/suricata/src/detect-engine-hhhd.c | 2616 --- framework/src/suricata/src/detect-engine-hhhd.h | 39 - framework/src/suricata/src/detect-engine-hmd.c | 1827 -- framework/src/suricata/src/detect-engine-hmd.h | 39 - framework/src/suricata/src/detect-engine-hrhd.c | 3545 ---- framework/src/suricata/src/detect-engine-hrhd.h | 40 - framework/src/suricata/src/detect-engine-hrhhd.c | 2643 --- framework/src/suricata/src/detect-engine-hrhhd.h | 39 - framework/src/suricata/src/detect-engine-hrl.c | 4221 ---- framework/src/suricata/src/detect-engine-hrl.h | 34 - framework/src/suricata/src/detect-engine-hrud.c | 3726 ---- framework/src/suricata/src/detect-engine-hrud.h | 40 - framework/src/suricata/src/detect-engine-hsbd.c | 4515 ----- framework/src/suricata/src/detect-engine-hsbd.h | 45 - framework/src/suricata/src/detect-engine-hscd.c | 2097 -- framework/src/suricata/src/detect-engine-hscd.h | 39 - framework/src/suricata/src/detect-engine-hsmd.c | 2097 -- framework/src/suricata/src/detect-engine-hsmd.h | 39 - framework/src/suricata/src/detect-engine-hua.c | 1855 -- framework/src/suricata/src/detect-engine-hua.h | 39 - framework/src/suricata/src/detect-engine-iponly.c | 2321 --- framework/src/suricata/src/detect-engine-iponly.h | 53 - framework/src/suricata/src/detect-engine-loader.c | 300 - framework/src/suricata/src/detect-engine-loader.h | 57 - framework/src/suricata/src/detect-engine-modbus.c | 1345 -- framework/src/suricata/src/detect-engine-modbus.h | 41 - framework/src/suricata/src/detect-engine-mpm.c | 2990 --- framework/src/suricata/src/detect-engine-mpm.h | 99 - framework/src/suricata/src/detect-engine-payload.c | 1113 - framework/src/suricata/src/detect-engine-payload.h | 36 - framework/src/suricata/src/detect-engine-port.c | 2850 --- framework/src/suricata/src/detect-engine-port.h | 68 - framework/src/suricata/src/detect-engine-proto.c | 627 - framework/src/suricata/src/detect-engine-proto.h | 48 - .../src/suricata/src/detect-engine-siggroup.c | 2420 --- .../src/suricata/src/detect-engine-siggroup.h | 96 - .../src/suricata/src/detect-engine-sigorder.c | 2201 -- .../src/suricata/src/detect-engine-sigorder.h | 81 - framework/src/suricata/src/detect-engine-state.c | 2346 --- framework/src/suricata/src/detect-engine-state.h | 244 - framework/src/suricata/src/detect-engine-tag.c | 1519 -- framework/src/suricata/src/detect-engine-tag.h | 63 - .../src/suricata/src/detect-engine-template.c | 46 - .../src/suricata/src/detect-engine-template.h | 25 - .../src/suricata/src/detect-engine-threshold.c | 689 - .../src/suricata/src/detect-engine-threshold.h | 46 - framework/src/suricata/src/detect-engine-uri.c | 4222 ---- framework/src/suricata/src/detect-engine-uri.h | 36 - framework/src/suricata/src/detect-engine.c | 3291 --- framework/src/suricata/src/detect-engine.h | 121 - framework/src/suricata/src/detect-fast-pattern.c | 20156 ------------------- framework/src/suricata/src/detect-fast-pattern.h | 67 - framework/src/suricata/src/detect-file-data.c | 280 - framework/src/suricata/src/detect-file-data.h | 30 - framework/src/suricata/src/detect-fileext.c | 315 - framework/src/suricata/src/detect-fileext.h | 38 - framework/src/suricata/src/detect-filemagic.c | 498 - framework/src/suricata/src/detect-filemagic.h | 46 - framework/src/suricata/src/detect-filemd5.c | 428 - framework/src/suricata/src/detect-filemd5.h | 37 - framework/src/suricata/src/detect-filename.c | 321 - framework/src/suricata/src/detect-filename.h | 39 - framework/src/suricata/src/detect-filesize.c | 532 - framework/src/suricata/src/detect-filesize.h | 42 - framework/src/suricata/src/detect-filestore.c | 443 - framework/src/suricata/src/detect-filestore.h | 45 - framework/src/suricata/src/detect-flags.c | 1341 -- framework/src/suricata/src/detect-flags.h | 59 - framework/src/suricata/src/detect-flow.c | 1127 -- framework/src/suricata/src/detect-flow.h | 43 - framework/src/suricata/src/detect-flowbits.c | 1156 -- framework/src/suricata/src/detect-flowbits.h | 45 - framework/src/suricata/src/detect-flowint.c | 2178 -- framework/src/suricata/src/detect-flowint.h | 86 - framework/src/suricata/src/detect-flowvar.c | 357 - framework/src/suricata/src/detect-flowvar.h | 56 - framework/src/suricata/src/detect-fragbits.c | 581 - framework/src/suricata/src/detect-fragbits.h | 58 - framework/src/suricata/src/detect-fragoffset.c | 396 - framework/src/suricata/src/detect-fragoffset.h | 38 - framework/src/suricata/src/detect-ftpbounce.c | 560 - framework/src/suricata/src/detect-ftpbounce.h | 31 - framework/src/suricata/src/detect-geoip.c | 618 - framework/src/suricata/src/detect-geoip.h | 46 - framework/src/suricata/src/detect-gid.c | 202 - framework/src/suricata/src/detect-gid.h | 45 - framework/src/suricata/src/detect-hostbits.c | 1473 -- framework/src/suricata/src/detect-hostbits.h | 34 - .../src/suricata/src/detect-http-client-body.c | 2407 --- .../src/suricata/src/detect-http-client-body.h | 29 - framework/src/suricata/src/detect-http-cookie.c | 1277 -- framework/src/suricata/src/detect-http-cookie.h | 33 - framework/src/suricata/src/detect-http-header.c | 1822 -- framework/src/suricata/src/detect-http-header.h | 30 - framework/src/suricata/src/detect-http-hh.c | 2106 -- framework/src/suricata/src/detect-http-hh.h | 29 - framework/src/suricata/src/detect-http-hrh.c | 2233 -- framework/src/suricata/src/detect-http-hrh.h | 29 - framework/src/suricata/src/detect-http-method.c | 833 - framework/src/suricata/src/detect-http-method.h | 33 - .../src/suricata/src/detect-http-raw-header.c | 1557 -- .../src/suricata/src/detect-http-raw-header.h | 29 - framework/src/suricata/src/detect-http-raw-uri.c | 566 - framework/src/suricata/src/detect-http-raw-uri.h | 30 - .../src/suricata/src/detect-http-server-body.c | 3873 ---- .../src/suricata/src/detect-http-server-body.h | 29 - framework/src/suricata/src/detect-http-stat-code.c | 688 - framework/src/suricata/src/detect-http-stat-code.h | 34 - framework/src/suricata/src/detect-http-stat-msg.c | 564 - framework/src/suricata/src/detect-http-stat-msg.h | 33 - framework/src/suricata/src/detect-http-ua.c | 2110 -- framework/src/suricata/src/detect-http-ua.h | 29 - framework/src/suricata/src/detect-http-uri.c | 556 - framework/src/suricata/src/detect-http-uri.h | 34 - framework/src/suricata/src/detect-icmp-id.c | 500 - framework/src/suricata/src/detect-icmp-id.h | 34 - framework/src/suricata/src/detect-icmp-seq.c | 390 - framework/src/suricata/src/detect-icmp-seq.h | 35 - framework/src/suricata/src/detect-icode.c | 528 - framework/src/suricata/src/detect-icode.h | 44 - framework/src/suricata/src/detect-id.c | 384 - framework/src/suricata/src/detect-id.h | 39 - framework/src/suricata/src/detect-ipopts.c | 386 - framework/src/suricata/src/detect-ipopts.h | 80 - framework/src/suricata/src/detect-ipproto.c | 9609 --------- framework/src/suricata/src/detect-ipproto.h | 48 - framework/src/suricata/src/detect-iprep.c | 1030 - framework/src/suricata/src/detect-iprep.h | 46 - framework/src/suricata/src/detect-isdataat.c | 1249 -- framework/src/suricata/src/detect-isdataat.h | 44 - framework/src/suricata/src/detect-itype.c | 529 - framework/src/suricata/src/detect-itype.h | 42 - framework/src/suricata/src/detect-l3proto.c | 391 - framework/src/suricata/src/detect-l3proto.h | 33 - framework/src/suricata/src/detect-lua-extensions.c | 627 - framework/src/suricata/src/detect-lua-extensions.h | 35 - framework/src/suricata/src/detect-lua.c | 2088 -- framework/src/suricata/src/detect-lua.h | 72 - framework/src/suricata/src/detect-mark.c | 353 - framework/src/suricata/src/detect-mark.h | 61 - framework/src/suricata/src/detect-metadata.c | 49 - framework/src/suricata/src/detect-metadata.h | 31 - framework/src/suricata/src/detect-modbus.c | 897 - framework/src/suricata/src/detect-modbus.h | 64 - framework/src/suricata/src/detect-msg.c | 211 - framework/src/suricata/src/detect-msg.h | 31 - framework/src/suricata/src/detect-noalert.c | 53 - framework/src/suricata/src/detect-noalert.h | 31 - framework/src/suricata/src/detect-nocase.c | 127 - framework/src/suricata/src/detect-nocase.h | 31 - framework/src/suricata/src/detect-offset.c | 158 - framework/src/suricata/src/detect-offset.h | 31 - framework/src/suricata/src/detect-parse.c | 3439 ---- framework/src/suricata/src/detect-parse.h | 68 - framework/src/suricata/src/detect-pcre.c | 4193 ---- framework/src/suricata/src/detect-pcre.h | 54 - framework/src/suricata/src/detect-pkt-data.c | 152 - framework/src/suricata/src/detect-pkt-data.h | 30 - framework/src/suricata/src/detect-pktvar.c | 259 - framework/src/suricata/src/detect-pktvar.h | 38 - framework/src/suricata/src/detect-priority.c | 221 - framework/src/suricata/src/detect-priority.h | 34 - framework/src/suricata/src/detect-rawbytes.c | 93 - framework/src/suricata/src/detect-rawbytes.h | 31 - framework/src/suricata/src/detect-reference.c | 376 - framework/src/suricata/src/detect-reference.h | 58 - framework/src/suricata/src/detect-replace.c | 845 - framework/src/suricata/src/detect-replace.h | 51 - framework/src/suricata/src/detect-rev.c | 83 - framework/src/suricata/src/detect-rev.h | 31 - framework/src/suricata/src/detect-rpc.c | 609 - framework/src/suricata/src/detect-rpc.h | 58 - framework/src/suricata/src/detect-sameip.c | 222 - framework/src/suricata/src/detect-sameip.h | 30 - framework/src/suricata/src/detect-seq.c | 243 - framework/src/suricata/src/detect-seq.h | 40 - framework/src/suricata/src/detect-sid.c | 165 - framework/src/suricata/src/detect-sid.h | 31 - .../src/suricata/src/detect-ssh-proto-version.c | 700 - .../src/suricata/src/detect-ssh-proto-version.h | 40 - .../src/suricata/src/detect-ssh-software-version.c | 673 - .../src/suricata/src/detect-ssh-software-version.h | 37 - framework/src/suricata/src/detect-ssl-state.c | 913 - framework/src/suricata/src/detect-ssl-state.h | 42 - framework/src/suricata/src/detect-ssl-version.c | 804 - framework/src/suricata/src/detect-ssl-version.h | 53 - framework/src/suricata/src/detect-stream_size.c | 532 - framework/src/suricata/src/detect-stream_size.h | 48 - framework/src/suricata/src/detect-tag.c | 488 - framework/src/suricata/src/detect-tag.h | 105 - .../src/suricata/src/detect-template-buffer.c | 170 - .../src/suricata/src/detect-template-buffer.h | 25 - framework/src/suricata/src/detect-template.c | 303 - framework/src/suricata/src/detect-template.h | 41 - framework/src/suricata/src/detect-threshold.c | 1525 -- framework/src/suricata/src/detect-threshold.h | 95 - framework/src/suricata/src/detect-tls-version.c | 722 - framework/src/suricata/src/detect-tls-version.h | 35 - framework/src/suricata/src/detect-tls.c | 853 - framework/src/suricata/src/detect-tls.h | 48 - framework/src/suricata/src/detect-tos.c | 430 - framework/src/suricata/src/detect-tos.h | 34 - framework/src/suricata/src/detect-ttl.c | 638 - framework/src/suricata/src/detect-ttl.h | 42 - framework/src/suricata/src/detect-uricontent.c | 1983 -- framework/src/suricata/src/detect-uricontent.h | 42 - framework/src/suricata/src/detect-urilen.c | 700 - framework/src/suricata/src/detect-urilen.h | 44 - framework/src/suricata/src/detect-window.c | 367 - framework/src/suricata/src/detect-window.h | 33 - framework/src/suricata/src/detect-within.c | 292 - framework/src/suricata/src/detect-within.h | 31 - framework/src/suricata/src/detect-xbits.c | 545 - framework/src/suricata/src/detect-xbits.h | 52 - framework/src/suricata/src/detect.c | 12343 ------------ framework/src/suricata/src/detect.h | 1290 -- framework/src/suricata/src/flow-bit.c | 483 - framework/src/suricata/src/flow-bit.h | 50 - framework/src/suricata/src/flow-hash.c | 860 - framework/src/suricata/src/flow-hash.h | 89 - framework/src/suricata/src/flow-manager.c | 1285 -- framework/src/suricata/src/flow-manager.h | 48 - framework/src/suricata/src/flow-private.h | 100 - framework/src/suricata/src/flow-queue.c | 168 - framework/src/suricata/src/flow-queue.h | 85 - framework/src/suricata/src/flow-storage.c | 296 - framework/src/suricata/src/flow-storage.h | 45 - framework/src/suricata/src/flow-timeout.c | 572 - framework/src/suricata/src/flow-timeout.h | 32 - framework/src/suricata/src/flow-util.c | 179 - framework/src/suricata/src/flow-util.h | 153 - framework/src/suricata/src/flow-var.c | 168 - framework/src/suricata/src/flow-var.h | 73 - framework/src/suricata/src/flow.c | 1147 -- framework/src/suricata/src/flow.h | 584 - framework/src/suricata/src/host-bit.c | 503 - framework/src/suricata/src/host-bit.h | 41 - framework/src/suricata/src/host-queue.c | 144 - framework/src/suricata/src/host-queue.h | 84 - framework/src/suricata/src/host-storage.c | 337 - framework/src/suricata/src/host-storage.h | 45 - framework/src/suricata/src/host-timeout.c | 180 - framework/src/suricata/src/host-timeout.h | 33 - framework/src/suricata/src/host.c | 695 - framework/src/suricata/src/host.h | 157 - framework/src/suricata/src/ippair-bit.c | 506 - framework/src/suricata/src/ippair-bit.h | 42 - framework/src/suricata/src/ippair-queue.c | 143 - framework/src/suricata/src/ippair-queue.h | 83 - framework/src/suricata/src/ippair-storage.c | 299 - framework/src/suricata/src/ippair-storage.h | 45 - framework/src/suricata/src/ippair-timeout.c | 159 - framework/src/suricata/src/ippair-timeout.h | 32 - framework/src/suricata/src/ippair.c | 691 - framework/src/suricata/src/ippair.h | 154 - framework/src/suricata/src/log-dnslog.c | 362 - framework/src/suricata/src/log-dnslog.h | 29 - framework/src/suricata/src/log-droplog.c | 507 - framework/src/suricata/src/log-droplog.h | 31 - framework/src/suricata/src/log-file.c | 465 - framework/src/suricata/src/log-file.h | 29 - framework/src/suricata/src/log-filestore.c | 499 - framework/src/suricata/src/log-filestore.h | 29 - framework/src/suricata/src/log-httplog.c | 738 - framework/src/suricata/src/log-httplog.h | 33 - framework/src/suricata/src/log-pcap.c | 1197 -- framework/src/suricata/src/log-pcap.h | 34 - framework/src/suricata/src/log-stats.c | 288 - framework/src/suricata/src/log-stats.h | 29 - framework/src/suricata/src/log-tcp-data.c | 345 - framework/src/suricata/src/log-tcp-data.h | 30 - framework/src/suricata/src/log-tlslog.c | 396 - framework/src/suricata/src/log-tlslog.h | 35 - framework/src/suricata/src/log-tlsstore.c | 439 - framework/src/suricata/src/log-tlsstore.h | 29 - framework/src/suricata/src/output-file.c | 298 - framework/src/suricata/src/output-file.h | 46 - framework/src/suricata/src/output-filedata.c | 485 - framework/src/suricata/src/output-filedata.h | 50 - framework/src/suricata/src/output-flow.c | 235 - framework/src/suricata/src/output-flow.h | 50 - framework/src/suricata/src/output-json-alert.c | 700 - framework/src/suricata/src/output-json-alert.h | 36 - framework/src/suricata/src/output-json-dns.c | 448 - framework/src/suricata/src/output-json-dns.h | 29 - framework/src/suricata/src/output-json-drop.c | 427 - framework/src/suricata/src/output-json-drop.h | 30 - .../src/suricata/src/output-json-email-common.c | 459 - .../src/suricata/src/output-json-email-common.h | 46 - framework/src/suricata/src/output-json-file.c | 311 - framework/src/suricata/src/output-json-file.h | 29 - framework/src/suricata/src/output-json-flow.c | 485 - framework/src/suricata/src/output-json-flow.h | 29 - framework/src/suricata/src/output-json-http.c | 615 - framework/src/suricata/src/output-json-http.h | 36 - framework/src/suricata/src/output-json-netflow.c | 467 - framework/src/suricata/src/output-json-netflow.h | 29 - framework/src/suricata/src/output-json-smtp.c | 296 - framework/src/suricata/src/output-json-smtp.h | 32 - framework/src/suricata/src/output-json-ssh.c | 351 - framework/src/suricata/src/output-json-ssh.h | 35 - framework/src/suricata/src/output-json-stats.c | 387 - framework/src/suricata/src/output-json-stats.h | 29 - framework/src/suricata/src/output-json-template.c | 217 - framework/src/suricata/src/output-json-template.h | 23 - framework/src/suricata/src/output-json-tls.c | 411 - framework/src/suricata/src/output-json-tls.h | 36 - framework/src/suricata/src/output-json.c | 633 - framework/src/suricata/src/output-json.h | 61 - framework/src/suricata/src/output-lua.c | 1069 - framework/src/suricata/src/output-lua.h | 29 - framework/src/suricata/src/output-packet.c | 241 - framework/src/suricata/src/output-packet.h | 46 - framework/src/suricata/src/output-stats.c | 241 - framework/src/suricata/src/output-stats.h | 57 - framework/src/suricata/src/output-streaming.c | 469 - framework/src/suricata/src/output-streaming.h | 55 - framework/src/suricata/src/output-tx.c | 308 - framework/src/suricata/src/output-tx.h | 45 - framework/src/suricata/src/output.c | 701 - framework/src/suricata/src/output.h | 125 - framework/src/suricata/src/packet-queue.c | 198 - framework/src/suricata/src/packet-queue.h | 34 - framework/src/suricata/src/pkt-var.c | 124 - framework/src/suricata/src/pkt-var.h | 33 - framework/src/suricata/src/ptxdump.py | 71 - framework/src/suricata/src/queue.h | 543 - framework/src/suricata/src/reputation.c | 2354 --- framework/src/suricata/src/reputation.h | 123 - .../src/suricata/src/respond-reject-libnet11.c | 541 - .../src/suricata/src/respond-reject-libnet11.h | 33 - framework/src/suricata/src/respond-reject.c | 180 - framework/src/suricata/src/respond-reject.h | 35 - framework/src/suricata/src/runmode-af-packet.c | 590 - framework/src/suricata/src/runmode-af-packet.h | 33 - framework/src/suricata/src/runmode-erf-dag.c | 150 - framework/src/suricata/src/runmode-erf-dag.h | 32 - framework/src/suricata/src/runmode-erf-file.c | 279 - framework/src/suricata/src/runmode-erf-file.h | 31 - framework/src/suricata/src/runmode-ipfw.c | 104 - framework/src/suricata/src/runmode-ipfw.h | 31 - framework/src/suricata/src/runmode-napatech.c | 235 - framework/src/suricata/src/runmode-napatech.h | 37 - framework/src/suricata/src/runmode-netmap.c | 459 - framework/src/suricata/src/runmode-netmap.h | 33 - framework/src/suricata/src/runmode-nflog.c | 254 - framework/src/suricata/src/runmode-nflog.h | 32 - framework/src/suricata/src/runmode-nfq.c | 100 - framework/src/suricata/src/runmode-nfq.h | 31 - framework/src/suricata/src/runmode-pcap-file.c | 281 - framework/src/suricata/src/runmode-pcap-file.h | 31 - framework/src/suricata/src/runmode-pcap.c | 328 - framework/src/suricata/src/runmode-pcap.h | 31 - framework/src/suricata/src/runmode-pfring.c | 525 - framework/src/suricata/src/runmode-pfring.h | 34 - framework/src/suricata/src/runmode-tile.c | 287 - framework/src/suricata/src/runmode-tile.h | 41 - framework/src/suricata/src/runmode-unittests.c | 311 - framework/src/suricata/src/runmode-unittests.h | 29 - framework/src/suricata/src/runmode-unix-socket.c | 838 - framework/src/suricata/src/runmode-unix-socket.h | 42 - framework/src/suricata/src/runmodes.c | 927 - framework/src/suricata/src/runmodes.h | 100 - framework/src/suricata/src/source-af-packet.c | 1919 -- framework/src/suricata/src/source-af-packet.h | 137 - framework/src/suricata/src/source-erf-dag.c | 670 - framework/src/suricata/src/source-erf-dag.h | 32 - framework/src/suricata/src/source-erf-file.c | 308 - framework/src/suricata/src/source-erf-file.h | 30 - framework/src/suricata/src/source-ipfw.c | 796 - framework/src/suricata/src/source-ipfw.h | 70 - framework/src/suricata/src/source-mpipe.c | 1095 - framework/src/suricata/src/source-mpipe.h | 93 - framework/src/suricata/src/source-napatech.c | 402 - framework/src/suricata/src/source-napatech.h | 44 - framework/src/suricata/src/source-netmap.c | 1098 - framework/src/suricata/src/source-netmap.h | 73 - framework/src/suricata/src/source-nflog.c | 550 - framework/src/suricata/src/source-nflog.h | 66 - framework/src/suricata/src/source-nfq-prototypes.h | 32 - framework/src/suricata/src/source-nfq.c | 1277 -- framework/src/suricata/src/source-nfq.h | 110 - framework/src/suricata/src/source-pcap-file.c | 475 - framework/src/suricata/src/source-pcap-file.h | 35 - framework/src/suricata/src/source-pcap.c | 826 - framework/src/suricata/src/source-pcap.h | 70 - framework/src/suricata/src/source-pfring.c | 682 - framework/src/suricata/src/source-pfring.h | 70 - framework/src/suricata/src/stream-tcp-inline.c | 657 - framework/src/suricata/src/stream-tcp-inline.h | 36 - framework/src/suricata/src/stream-tcp-private.h | 246 - framework/src/suricata/src/stream-tcp-reassemble.c | 8757 -------- framework/src/suricata/src/stream-tcp-reassemble.h | 110 - framework/src/suricata/src/stream-tcp-sack.c | 960 - framework/src/suricata/src/stream-tcp-sack.h | 63 - framework/src/suricata/src/stream-tcp-util.c | 264 - framework/src/suricata/src/stream-tcp-util.h | 47 - framework/src/suricata/src/stream-tcp.c | 10820 ---------- framework/src/suricata/src/stream-tcp.h | 232 - framework/src/suricata/src/stream.c | 290 - framework/src/suricata/src/stream.h | 79 - framework/src/suricata/src/suricata-common.h | 343 - framework/src/suricata/src/suricata.c | 2564 --- framework/src/suricata/src/suricata.h | 197 - framework/src/suricata/src/threads-arch-tile.h | 114 - framework/src/suricata/src/threads-debug.h | 389 - framework/src/suricata/src/threads-profile.h | 218 - framework/src/suricata/src/threads.c | 151 - framework/src/suricata/src/threads.h | 300 - framework/src/suricata/src/threadvars.h | 130 - framework/src/suricata/src/tm-modules.c | 283 - framework/src/suricata/src/tm-modules.h | 97 - framework/src/suricata/src/tm-queuehandlers.c | 67 - framework/src/suricata/src/tm-queuehandlers.h | 56 - framework/src/suricata/src/tm-queues.c | 126 - framework/src/suricata/src/tm-queues.h | 44 - framework/src/suricata/src/tm-threads-common.h | 133 - framework/src/suricata/src/tm-threads.c | 2203 -- framework/src/suricata/src/tm-threads.h | 205 - framework/src/suricata/src/tmqh-flow.c | 510 - framework/src/suricata/src/tmqh-flow.h | 48 - framework/src/suricata/src/tmqh-nfq.c | 55 - framework/src/suricata/src/tmqh-nfq.h | 29 - framework/src/suricata/src/tmqh-packetpool.c | 599 - framework/src/suricata/src/tmqh-packetpool.h | 83 - framework/src/suricata/src/tmqh-ringbuffer.c | 151 - framework/src/suricata/src/tmqh-ringbuffer.h | 30 - framework/src/suricata/src/tmqh-simple.c | 155 - framework/src/suricata/src/tmqh-simple.h | 34 - framework/src/suricata/src/unix-manager.c | 1030 - framework/src/suricata/src/unix-manager.h | 51 - framework/src/suricata/src/util-action.c | 1627 -- framework/src/suricata/src/util-action.h | 31 - framework/src/suricata/src/util-affinity.c | 323 - framework/src/suricata/src/util-affinity.h | 94 - framework/src/suricata/src/util-atomic.c | 73 - framework/src/suricata/src/util-atomic.h | 476 - framework/src/suricata/src/util-base64.c | 151 - framework/src/suricata/src/util-base64.h | 55 - framework/src/suricata/src/util-binsearch.c | 112 - framework/src/suricata/src/util-binsearch.h | 32 - .../src/suricata/src/util-bloomfilter-counting.c | 410 - .../src/suricata/src/util-bloomfilter-counting.h | 47 - framework/src/suricata/src/util-bloomfilter.c | 290 - framework/src/suricata/src/util-bloomfilter.h | 67 - framework/src/suricata/src/util-buffer.c | 87 - framework/src/suricata/src/util-buffer.h | 177 - framework/src/suricata/src/util-byte.c | 629 - framework/src/suricata/src/util-byte.h | 292 - framework/src/suricata/src/util-checksum.c | 90 - framework/src/suricata/src/util-checksum.h | 36 - framework/src/suricata/src/util-cidr.c | 48 - framework/src/suricata/src/util-cidr.h | 31 - .../src/suricata/src/util-classification-config.c | 839 - .../src/suricata/src/util-classification-config.h | 62 - framework/src/suricata/src/util-clock.h | 40 - framework/src/suricata/src/util-conf.c | 65 - framework/src/suricata/src/util-conf.h | 32 - framework/src/suricata/src/util-coredump-config.c | 206 - framework/src/suricata/src/util-coredump-config.h | 31 - framework/src/suricata/src/util-cpu.c | 231 - framework/src/suricata/src/util-cpu.h | 39 - framework/src/suricata/src/util-crypt.c | 306 - framework/src/suricata/src/util-crypt.h | 84 - framework/src/suricata/src/util-cuda-buffer.c | 1358 -- framework/src/suricata/src/util-cuda-buffer.h | 111 - framework/src/suricata/src/util-cuda-handlers.c | 363 - framework/src/suricata/src/util-cuda-handlers.h | 50 - framework/src/suricata/src/util-cuda-vars.c | 74 - framework/src/suricata/src/util-cuda-vars.h | 65 - framework/src/suricata/src/util-cuda.c | 5455 ----- framework/src/suricata/src/util-cuda.h | 323 - framework/src/suricata/src/util-daemon.c | 195 - framework/src/suricata/src/util-daemon.h | 38 - framework/src/suricata/src/util-debug-filters.c | 1009 - framework/src/suricata/src/util-debug-filters.h | 136 - framework/src/suricata/src/util-debug.c | 1653 -- framework/src/suricata/src/util-debug.h | 551 - framework/src/suricata/src/util-decode-asn1.c | 904 - framework/src/suricata/src/util-decode-asn1.h | 220 - framework/src/suricata/src/util-decode-der-get.c | 278 - framework/src/suricata/src/util-decode-der-get.h | 43 - framework/src/suricata/src/util-decode-der.c | 787 - framework/src/suricata/src/util-decode-der.h | 96 - framework/src/suricata/src/util-decode-mime.c | 3003 --- framework/src/suricata/src/util-decode-mime.h | 245 - framework/src/suricata/src/util-device.c | 273 - framework/src/suricata/src/util-device.h | 49 - framework/src/suricata/src/util-enum.c | 84 - framework/src/suricata/src/util-enum.h | 36 - framework/src/suricata/src/util-error.c | 318 - framework/src/suricata/src/util-error.h | 310 - framework/src/suricata/src/util-file.c | 932 - framework/src/suricata/src/util-file.h | 192 - framework/src/suricata/src/util-fix_checksum.c | 58 - framework/src/suricata/src/util-fix_checksum.h | 37 - framework/src/suricata/src/util-fmemopen.c | 198 - framework/src/suricata/src/util-fmemopen.h | 55 - framework/src/suricata/src/util-hash-lookup3.c | 999 - framework/src/suricata/src/util-hash-lookup3.h | 63 - framework/src/suricata/src/util-hash.c | 432 - framework/src/suricata/src/util-hash.h | 61 - framework/src/suricata/src/util-hashlist.c | 518 - framework/src/suricata/src/util-hashlist.h | 65 - framework/src/suricata/src/util-host-info.c | 106 - framework/src/suricata/src/util-host-info.h | 29 - framework/src/suricata/src/util-host-os-info.c | 1660 -- framework/src/suricata/src/util-host-os-info.h | 38 - framework/src/suricata/src/util-ioctl.c | 248 - framework/src/suricata/src/util-ioctl.h | 27 - framework/src/suricata/src/util-ip.c | 112 - framework/src/suricata/src/util-ip.h | 32 - framework/src/suricata/src/util-logopenfile-tile.c | 370 - framework/src/suricata/src/util-logopenfile-tile.h | 32 - framework/src/suricata/src/util-logopenfile.c | 646 - framework/src/suricata/src/util-logopenfile.h | 140 - framework/src/suricata/src/util-lua-common.c | 772 - framework/src/suricata/src/util-lua-common.h | 42 - framework/src/suricata/src/util-lua-dns.c | 321 - framework/src/suricata/src/util-lua-dns.h | 33 - framework/src/suricata/src/util-lua-http.c | 348 - framework/src/suricata/src/util-lua-http.h | 33 - framework/src/suricata/src/util-lua-ssh.c | 227 - framework/src/suricata/src/util-lua-ssh.h | 33 - framework/src/suricata/src/util-lua-tls.c | 186 - framework/src/suricata/src/util-lua-tls.h | 33 - framework/src/suricata/src/util-lua.c | 276 - framework/src/suricata/src/util-lua.h | 95 - framework/src/suricata/src/util-magic.c | 676 - framework/src/suricata/src/util-magic.h | 35 - framework/src/suricata/src/util-mem.h | 313 - framework/src/suricata/src/util-memcmp.c | 407 - framework/src/suricata/src/util-memcmp.h | 502 - framework/src/suricata/src/util-memcpy.h | 47 - framework/src/suricata/src/util-memrchr.c | 67 - framework/src/suricata/src/util-memrchr.h | 30 - framework/src/suricata/src/util-misc.c | 1141 -- framework/src/suricata/src/util-misc.h | 55 - framework/src/suricata/src/util-mpm-ac-bs.c | 2802 --- framework/src/suricata/src/util-mpm-ac-bs.h | 101 - .../src/suricata/src/util-mpm-ac-cuda-kernel.cu | 96 - framework/src/suricata/src/util-mpm-ac-gfbs.c | 2722 --- framework/src/suricata/src/util-mpm-ac-gfbs.h | 110 - .../src/suricata/src/util-mpm-ac-tile-small.c | 100 - framework/src/suricata/src/util-mpm-ac-tile.c | 2855 --- framework/src/suricata/src/util-mpm-ac-tile.h | 174 - framework/src/suricata/src/util-mpm-ac.c | 3341 --- framework/src/suricata/src/util-mpm-ac.h | 221 - framework/src/suricata/src/util-mpm-b2g.c | 2832 --- framework/src/suricata/src/util-mpm-b2g.h | 127 - framework/src/suricata/src/util-mpm-b3g.c | 1807 -- framework/src/suricata/src/util-mpm-b3g.h | 130 - framework/src/suricata/src/util-mpm-wumanber.c | 3219 --- framework/src/suricata/src/util-mpm-wumanber.h | 97 - framework/src/suricata/src/util-mpm.c | 785 - framework/src/suricata/src/util-mpm.h | 324 - framework/src/suricata/src/util-optimize.h | 52 - framework/src/suricata/src/util-path.c | 66 - framework/src/suricata/src/util-path.h | 31 - framework/src/suricata/src/util-pidfile.c | 127 - framework/src/suricata/src/util-pidfile.h | 33 - framework/src/suricata/src/util-pool-thread.c | 458 - framework/src/suricata/src/util-pool-thread.h | 100 - framework/src/suricata/src/util-pool.c | 737 - framework/src/suricata/src/util-pool.h | 87 - framework/src/suricata/src/util-print.c | 272 - framework/src/suricata/src/util-print.h | 58 - framework/src/suricata/src/util-privs.c | 246 - framework/src/suricata/src/util-privs.h | 98 - .../src/suricata/src/util-profiling-keywords.c | 390 - framework/src/suricata/src/util-profiling-locks.c | 241 - framework/src/suricata/src/util-profiling-locks.h | 45 - framework/src/suricata/src/util-profiling-rules.c | 679 - framework/src/suricata/src/util-profiling.c | 1160 -- framework/src/suricata/src/util-profiling.h | 282 - framework/src/suricata/src/util-proto-name.c | 116 - framework/src/suricata/src/util-proto-name.h | 42 - framework/src/suricata/src/util-radix-tree.c | 4228 ---- framework/src/suricata/src/util-radix-tree.h | 135 - framework/src/suricata/src/util-random.c | 48 - framework/src/suricata/src/util-random.h | 30 - framework/src/suricata/src/util-reference-config.c | 808 - framework/src/suricata/src/util-reference-config.h | 53 - framework/src/suricata/src/util-ringbuffer.c | 1088 - framework/src/suricata/src/util-ringbuffer.h | 136 - framework/src/suricata/src/util-rohash.c | 249 - framework/src/suricata/src/util-rohash.h | 48 - framework/src/suricata/src/util-rule-vars.c | 532 - framework/src/suricata/src/util-rule-vars.h | 36 - framework/src/suricata/src/util-runmodes.c | 751 - framework/src/suricata/src/util-runmodes.h | 69 - framework/src/suricata/src/util-running-modes.c | 62 - framework/src/suricata/src/util-running-modes.h | 33 - framework/src/suricata/src/util-signal.c | 67 - framework/src/suricata/src/util-signal.h | 31 - framework/src/suricata/src/util-spm-bm.c | 382 - framework/src/suricata/src/util-spm-bm.h | 49 - framework/src/suricata/src/util-spm-bs.c | 139 - framework/src/suricata/src/util-spm-bs.h | 36 - framework/src/suricata/src/util-spm-bs2bm.c | 176 - framework/src/suricata/src/util-spm-bs2bm.h | 38 - framework/src/suricata/src/util-spm.c | 2368 --- framework/src/suricata/src/util-spm.h | 61 - framework/src/suricata/src/util-storage.c | 545 - framework/src/suricata/src/util-storage.h | 75 - framework/src/suricata/src/util-strlcatu.c | 79 - framework/src/suricata/src/util-strlcpyu.c | 75 - framework/src/suricata/src/util-syslog.c | 78 - framework/src/suricata/src/util-syslog.h | 31 - framework/src/suricata/src/util-threshold-config.c | 2909 --- framework/src/suricata/src/util-threshold-config.h | 33 - framework/src/suricata/src/util-time.c | 304 - framework/src/suricata/src/util-time.h | 54 - framework/src/suricata/src/util-unittest-helper.c | 1081 - framework/src/suricata/src/util-unittest-helper.h | 63 - framework/src/suricata/src/util-unittest.c | 326 - framework/src/suricata/src/util-unittest.h | 54 - framework/src/suricata/src/util-validate.h | 111 - framework/src/suricata/src/util-var-name.c | 204 - framework/src/suricata/src/util-var-name.h | 34 - framework/src/suricata/src/util-var.c | 130 - framework/src/suricata/src/util-var.h | 65 - framework/src/suricata/src/util-vector.h | 43 - framework/src/suricata/src/win32-misc.c | 108 - framework/src/suricata/src/win32-misc.h | 44 - framework/src/suricata/src/win32-service.c | 394 - framework/src/suricata/src/win32-service.h | 35 - framework/src/suricata/src/win32-syslog.h | 80 - 823 files changed, 473355 deletions(-) delete mode 100644 framework/src/suricata/src/Makefile.am delete mode 100644 framework/src/suricata/src/action-globals.h delete mode 100644 framework/src/suricata/src/alert-debuglog.c delete mode 100644 framework/src/suricata/src/alert-debuglog.h delete mode 100644 framework/src/suricata/src/alert-fastlog.c delete mode 100644 framework/src/suricata/src/alert-fastlog.h delete mode 100644 framework/src/suricata/src/alert-prelude.c delete mode 100644 framework/src/suricata/src/alert-prelude.h delete mode 100644 framework/src/suricata/src/alert-syslog.c delete mode 100644 framework/src/suricata/src/alert-syslog.h delete mode 100644 framework/src/suricata/src/alert-unified2-alert.c delete mode 100644 framework/src/suricata/src/alert-unified2-alert.h delete mode 100644 framework/src/suricata/src/app-layer-dcerpc-common.h delete mode 100644 framework/src/suricata/src/app-layer-dcerpc-udp.c delete mode 100644 framework/src/suricata/src/app-layer-dcerpc-udp.h delete mode 100644 framework/src/suricata/src/app-layer-dcerpc.c delete mode 100644 framework/src/suricata/src/app-layer-dcerpc.h delete mode 100644 framework/src/suricata/src/app-layer-detect-proto.c delete mode 100644 framework/src/suricata/src/app-layer-detect-proto.h delete mode 100644 framework/src/suricata/src/app-layer-dns-common.c delete mode 100644 framework/src/suricata/src/app-layer-dns-common.h delete mode 100644 framework/src/suricata/src/app-layer-dns-tcp.c delete mode 100644 framework/src/suricata/src/app-layer-dns-tcp.h delete mode 100644 framework/src/suricata/src/app-layer-dns-udp.c delete mode 100644 framework/src/suricata/src/app-layer-dns-udp.h delete mode 100644 framework/src/suricata/src/app-layer-events.c delete mode 100644 framework/src/suricata/src/app-layer-events.h delete mode 100644 framework/src/suricata/src/app-layer-ftp.c delete mode 100644 framework/src/suricata/src/app-layer-ftp.h delete mode 100644 framework/src/suricata/src/app-layer-htp-body.c delete mode 100644 framework/src/suricata/src/app-layer-htp-body.h delete mode 100644 framework/src/suricata/src/app-layer-htp-file.c delete mode 100644 framework/src/suricata/src/app-layer-htp-file.h delete mode 100644 framework/src/suricata/src/app-layer-htp-libhtp.c delete mode 100644 framework/src/suricata/src/app-layer-htp-libhtp.h delete mode 100644 framework/src/suricata/src/app-layer-htp-mem.c delete mode 100644 framework/src/suricata/src/app-layer-htp-mem.h delete mode 100644 framework/src/suricata/src/app-layer-htp-xff.c delete mode 100644 framework/src/suricata/src/app-layer-htp-xff.h delete mode 100644 framework/src/suricata/src/app-layer-htp.c delete mode 100644 framework/src/suricata/src/app-layer-htp.h delete mode 100644 framework/src/suricata/src/app-layer-modbus.c delete mode 100644 framework/src/suricata/src/app-layer-modbus.h delete mode 100644 framework/src/suricata/src/app-layer-nbss.h delete mode 100644 framework/src/suricata/src/app-layer-parser.c delete mode 100644 framework/src/suricata/src/app-layer-parser.h delete mode 100644 framework/src/suricata/src/app-layer-protos.c delete mode 100644 framework/src/suricata/src/app-layer-protos.h delete mode 100644 framework/src/suricata/src/app-layer-smb.c delete mode 100644 framework/src/suricata/src/app-layer-smb.h delete mode 100644 framework/src/suricata/src/app-layer-smb2.c delete mode 100644 framework/src/suricata/src/app-layer-smb2.h delete mode 100644 framework/src/suricata/src/app-layer-smtp.c delete mode 100644 framework/src/suricata/src/app-layer-smtp.h delete mode 100644 framework/src/suricata/src/app-layer-ssh.c delete mode 100644 framework/src/suricata/src/app-layer-ssh.h delete mode 100644 framework/src/suricata/src/app-layer-ssl.c delete mode 100644 framework/src/suricata/src/app-layer-ssl.h delete mode 100644 framework/src/suricata/src/app-layer-template.c delete mode 100644 framework/src/suricata/src/app-layer-template.h delete mode 100644 framework/src/suricata/src/app-layer-tls-handshake.c delete mode 100644 framework/src/suricata/src/app-layer-tls-handshake.h delete mode 100644 framework/src/suricata/src/app-layer.c delete mode 100644 framework/src/suricata/src/app-layer.h delete mode 100644 framework/src/suricata/src/conf-yaml-loader.c delete mode 100644 framework/src/suricata/src/conf-yaml-loader.h delete mode 100644 framework/src/suricata/src/conf.c delete mode 100644 framework/src/suricata/src/conf.h delete mode 100644 framework/src/suricata/src/counters.c delete mode 100644 framework/src/suricata/src/counters.h delete mode 100644 framework/src/suricata/src/data-queue.c delete mode 100644 framework/src/suricata/src/data-queue.h delete mode 100644 framework/src/suricata/src/debug.h delete mode 100644 framework/src/suricata/src/decode-erspan.c delete mode 100644 framework/src/suricata/src/decode-erspan.h delete mode 100644 framework/src/suricata/src/decode-ethernet.c delete mode 100644 framework/src/suricata/src/decode-ethernet.h delete mode 100644 framework/src/suricata/src/decode-events.c delete mode 100644 framework/src/suricata/src/decode-events.h delete mode 100644 framework/src/suricata/src/decode-gre.c delete mode 100644 framework/src/suricata/src/decode-gre.h delete mode 100644 framework/src/suricata/src/decode-icmpv4.c delete mode 100644 framework/src/suricata/src/decode-icmpv4.h delete mode 100644 framework/src/suricata/src/decode-icmpv6.c delete mode 100644 framework/src/suricata/src/decode-icmpv6.h delete mode 100644 framework/src/suricata/src/decode-ipv4.c delete mode 100644 framework/src/suricata/src/decode-ipv4.h delete mode 100644 framework/src/suricata/src/decode-ipv6.c delete mode 100644 framework/src/suricata/src/decode-ipv6.h delete mode 100644 framework/src/suricata/src/decode-mpls.c delete mode 100644 framework/src/suricata/src/decode-mpls.h delete mode 100644 framework/src/suricata/src/decode-null.c delete mode 100644 framework/src/suricata/src/decode-null.h delete mode 100644 framework/src/suricata/src/decode-ppp.c delete mode 100644 framework/src/suricata/src/decode-ppp.h delete mode 100644 framework/src/suricata/src/decode-pppoe.c delete mode 100644 framework/src/suricata/src/decode-pppoe.h delete mode 100644 framework/src/suricata/src/decode-raw.c delete mode 100644 framework/src/suricata/src/decode-raw.h delete mode 100644 framework/src/suricata/src/decode-sctp.c delete mode 100644 framework/src/suricata/src/decode-sctp.h delete mode 100644 framework/src/suricata/src/decode-sll.c delete mode 100644 framework/src/suricata/src/decode-sll.h delete mode 100644 framework/src/suricata/src/decode-tcp.c delete mode 100644 framework/src/suricata/src/decode-tcp.h delete mode 100644 framework/src/suricata/src/decode-template.c delete mode 100644 framework/src/suricata/src/decode-template.h delete mode 100644 framework/src/suricata/src/decode-teredo.c delete mode 100644 framework/src/suricata/src/decode-teredo.h delete mode 100644 framework/src/suricata/src/decode-udp.c delete mode 100644 framework/src/suricata/src/decode-udp.h delete mode 100644 framework/src/suricata/src/decode-vlan.c delete mode 100644 framework/src/suricata/src/decode-vlan.h delete mode 100644 framework/src/suricata/src/decode.c delete mode 100644 framework/src/suricata/src/decode.h delete mode 100644 framework/src/suricata/src/defrag-config.c delete mode 100644 framework/src/suricata/src/defrag-config.h delete mode 100644 framework/src/suricata/src/defrag-hash.c delete mode 100644 framework/src/suricata/src/defrag-hash.h delete mode 100644 framework/src/suricata/src/defrag-queue.c delete mode 100644 framework/src/suricata/src/defrag-queue.h delete mode 100644 framework/src/suricata/src/defrag-timeout.c delete mode 100644 framework/src/suricata/src/defrag-timeout.h delete mode 100644 framework/src/suricata/src/defrag.c delete mode 100644 framework/src/suricata/src/defrag.h delete mode 100644 framework/src/suricata/src/detect-ack.c delete mode 100644 framework/src/suricata/src/detect-ack.h delete mode 100644 framework/src/suricata/src/detect-app-layer-event.c delete mode 100644 framework/src/suricata/src/detect-app-layer-event.h delete mode 100644 framework/src/suricata/src/detect-app-layer-protocol.c delete mode 100644 framework/src/suricata/src/detect-app-layer-protocol.h delete mode 100644 framework/src/suricata/src/detect-asn1.c delete mode 100644 framework/src/suricata/src/detect-asn1.h delete mode 100644 framework/src/suricata/src/detect-base64-data.c delete mode 100644 framework/src/suricata/src/detect-base64-data.h delete mode 100644 framework/src/suricata/src/detect-base64-decode.c delete mode 100644 framework/src/suricata/src/detect-base64-decode.h delete mode 100644 framework/src/suricata/src/detect-byte-extract.c delete mode 100644 framework/src/suricata/src/detect-byte-extract.h delete mode 100644 framework/src/suricata/src/detect-bytejump.c delete mode 100644 framework/src/suricata/src/detect-bytejump.h delete mode 100644 framework/src/suricata/src/detect-bytetest.c delete mode 100644 framework/src/suricata/src/detect-bytetest.h delete mode 100644 framework/src/suricata/src/detect-classtype.c delete mode 100644 framework/src/suricata/src/detect-classtype.h delete mode 100644 framework/src/suricata/src/detect-content.c delete mode 100644 framework/src/suricata/src/detect-content.h delete mode 100644 framework/src/suricata/src/detect-csum.c delete mode 100644 framework/src/suricata/src/detect-csum.h delete mode 100644 framework/src/suricata/src/detect-dce-iface.c delete mode 100644 framework/src/suricata/src/detect-dce-iface.h delete mode 100644 framework/src/suricata/src/detect-dce-opnum.c delete mode 100644 framework/src/suricata/src/detect-dce-opnum.h delete mode 100644 framework/src/suricata/src/detect-dce-stub-data.c delete mode 100644 framework/src/suricata/src/detect-dce-stub-data.h delete mode 100644 framework/src/suricata/src/detect-depth.c delete mode 100644 framework/src/suricata/src/detect-depth.h delete mode 100644 framework/src/suricata/src/detect-detection-filter.c delete mode 100644 framework/src/suricata/src/detect-detection-filter.h delete mode 100644 framework/src/suricata/src/detect-distance.c delete mode 100644 framework/src/suricata/src/detect-distance.h delete mode 100644 framework/src/suricata/src/detect-dns-query.c delete mode 100644 framework/src/suricata/src/detect-dns-query.h delete mode 100644 framework/src/suricata/src/detect-dsize.c delete mode 100644 framework/src/suricata/src/detect-dsize.h delete mode 100644 framework/src/suricata/src/detect-engine-address-ipv4.c delete mode 100644 framework/src/suricata/src/detect-engine-address-ipv4.h delete mode 100644 framework/src/suricata/src/detect-engine-address-ipv6.c delete mode 100644 framework/src/suricata/src/detect-engine-address-ipv6.h delete mode 100644 framework/src/suricata/src/detect-engine-address.c delete mode 100644 framework/src/suricata/src/detect-engine-address.h delete mode 100644 framework/src/suricata/src/detect-engine-alert.c delete mode 100644 framework/src/suricata/src/detect-engine-alert.h delete mode 100644 framework/src/suricata/src/detect-engine-analyzer.c delete mode 100644 framework/src/suricata/src/detect-engine-analyzer.h delete mode 100644 framework/src/suricata/src/detect-engine-apt-event.c delete mode 100644 framework/src/suricata/src/detect-engine-apt-event.h delete mode 100644 framework/src/suricata/src/detect-engine-content-inspection.c delete mode 100644 framework/src/suricata/src/detect-engine-content-inspection.h delete mode 100644 framework/src/suricata/src/detect-engine-dcepayload.c delete mode 100644 framework/src/suricata/src/detect-engine-dcepayload.h delete mode 100644 framework/src/suricata/src/detect-engine-dns.c delete mode 100644 framework/src/suricata/src/detect-engine-dns.h delete mode 100644 framework/src/suricata/src/detect-engine-event.c delete mode 100644 framework/src/suricata/src/detect-engine-event.h delete mode 100644 framework/src/suricata/src/detect-engine-file.c delete mode 100644 framework/src/suricata/src/detect-engine-file.h delete mode 100644 framework/src/suricata/src/detect-engine-filedata-smtp.c delete mode 100644 framework/src/suricata/src/detect-engine-filedata-smtp.h delete mode 100644 framework/src/suricata/src/detect-engine-hcbd.c delete mode 100644 framework/src/suricata/src/detect-engine-hcbd.h delete mode 100644 framework/src/suricata/src/detect-engine-hcd.c delete mode 100644 framework/src/suricata/src/detect-engine-hcd.h delete mode 100644 framework/src/suricata/src/detect-engine-hhd.c delete mode 100644 framework/src/suricata/src/detect-engine-hhd.h delete mode 100644 framework/src/suricata/src/detect-engine-hhhd.c delete mode 100644 framework/src/suricata/src/detect-engine-hhhd.h delete mode 100644 framework/src/suricata/src/detect-engine-hmd.c delete mode 100644 framework/src/suricata/src/detect-engine-hmd.h delete mode 100644 framework/src/suricata/src/detect-engine-hrhd.c delete mode 100644 framework/src/suricata/src/detect-engine-hrhd.h delete mode 100644 framework/src/suricata/src/detect-engine-hrhhd.c delete mode 100644 framework/src/suricata/src/detect-engine-hrhhd.h delete mode 100644 framework/src/suricata/src/detect-engine-hrl.c delete mode 100644 framework/src/suricata/src/detect-engine-hrl.h delete mode 100644 framework/src/suricata/src/detect-engine-hrud.c delete mode 100644 framework/src/suricata/src/detect-engine-hrud.h delete mode 100644 framework/src/suricata/src/detect-engine-hsbd.c delete mode 100644 framework/src/suricata/src/detect-engine-hsbd.h delete mode 100644 framework/src/suricata/src/detect-engine-hscd.c delete mode 100644 framework/src/suricata/src/detect-engine-hscd.h delete mode 100644 framework/src/suricata/src/detect-engine-hsmd.c delete mode 100644 framework/src/suricata/src/detect-engine-hsmd.h delete mode 100644 framework/src/suricata/src/detect-engine-hua.c delete mode 100644 framework/src/suricata/src/detect-engine-hua.h delete mode 100644 framework/src/suricata/src/detect-engine-iponly.c delete mode 100644 framework/src/suricata/src/detect-engine-iponly.h delete mode 100644 framework/src/suricata/src/detect-engine-loader.c delete mode 100644 framework/src/suricata/src/detect-engine-loader.h delete mode 100644 framework/src/suricata/src/detect-engine-modbus.c delete mode 100644 framework/src/suricata/src/detect-engine-modbus.h delete mode 100644 framework/src/suricata/src/detect-engine-mpm.c delete mode 100644 framework/src/suricata/src/detect-engine-mpm.h delete mode 100644 framework/src/suricata/src/detect-engine-payload.c delete mode 100644 framework/src/suricata/src/detect-engine-payload.h delete mode 100644 framework/src/suricata/src/detect-engine-port.c delete mode 100644 framework/src/suricata/src/detect-engine-port.h delete mode 100644 framework/src/suricata/src/detect-engine-proto.c delete mode 100644 framework/src/suricata/src/detect-engine-proto.h delete mode 100644 framework/src/suricata/src/detect-engine-siggroup.c delete mode 100644 framework/src/suricata/src/detect-engine-siggroup.h delete mode 100644 framework/src/suricata/src/detect-engine-sigorder.c delete mode 100644 framework/src/suricata/src/detect-engine-sigorder.h delete mode 100644 framework/src/suricata/src/detect-engine-state.c delete mode 100644 framework/src/suricata/src/detect-engine-state.h delete mode 100644 framework/src/suricata/src/detect-engine-tag.c delete mode 100644 framework/src/suricata/src/detect-engine-tag.h delete mode 100644 framework/src/suricata/src/detect-engine-template.c delete mode 100644 framework/src/suricata/src/detect-engine-template.h delete mode 100644 framework/src/suricata/src/detect-engine-threshold.c delete mode 100644 framework/src/suricata/src/detect-engine-threshold.h delete mode 100644 framework/src/suricata/src/detect-engine-uri.c delete mode 100644 framework/src/suricata/src/detect-engine-uri.h delete mode 100644 framework/src/suricata/src/detect-engine.c delete mode 100644 framework/src/suricata/src/detect-engine.h delete mode 100644 framework/src/suricata/src/detect-fast-pattern.c delete mode 100644 framework/src/suricata/src/detect-fast-pattern.h delete mode 100644 framework/src/suricata/src/detect-file-data.c delete mode 100644 framework/src/suricata/src/detect-file-data.h delete mode 100644 framework/src/suricata/src/detect-fileext.c delete mode 100644 framework/src/suricata/src/detect-fileext.h delete mode 100644 framework/src/suricata/src/detect-filemagic.c delete mode 100644 framework/src/suricata/src/detect-filemagic.h delete mode 100644 framework/src/suricata/src/detect-filemd5.c delete mode 100644 framework/src/suricata/src/detect-filemd5.h delete mode 100644 framework/src/suricata/src/detect-filename.c delete mode 100644 framework/src/suricata/src/detect-filename.h delete mode 100644 framework/src/suricata/src/detect-filesize.c delete mode 100644 framework/src/suricata/src/detect-filesize.h delete mode 100644 framework/src/suricata/src/detect-filestore.c delete mode 100644 framework/src/suricata/src/detect-filestore.h delete mode 100644 framework/src/suricata/src/detect-flags.c delete mode 100644 framework/src/suricata/src/detect-flags.h delete mode 100644 framework/src/suricata/src/detect-flow.c delete mode 100644 framework/src/suricata/src/detect-flow.h delete mode 100644 framework/src/suricata/src/detect-flowbits.c delete mode 100644 framework/src/suricata/src/detect-flowbits.h delete mode 100644 framework/src/suricata/src/detect-flowint.c delete mode 100644 framework/src/suricata/src/detect-flowint.h delete mode 100644 framework/src/suricata/src/detect-flowvar.c delete mode 100644 framework/src/suricata/src/detect-flowvar.h delete mode 100644 framework/src/suricata/src/detect-fragbits.c delete mode 100644 framework/src/suricata/src/detect-fragbits.h delete mode 100644 framework/src/suricata/src/detect-fragoffset.c delete mode 100644 framework/src/suricata/src/detect-fragoffset.h delete mode 100644 framework/src/suricata/src/detect-ftpbounce.c delete mode 100644 framework/src/suricata/src/detect-ftpbounce.h delete mode 100644 framework/src/suricata/src/detect-geoip.c delete mode 100644 framework/src/suricata/src/detect-geoip.h delete mode 100644 framework/src/suricata/src/detect-gid.c delete mode 100644 framework/src/suricata/src/detect-gid.h delete mode 100644 framework/src/suricata/src/detect-hostbits.c delete mode 100644 framework/src/suricata/src/detect-hostbits.h delete mode 100644 framework/src/suricata/src/detect-http-client-body.c delete mode 100644 framework/src/suricata/src/detect-http-client-body.h delete mode 100644 framework/src/suricata/src/detect-http-cookie.c delete mode 100644 framework/src/suricata/src/detect-http-cookie.h delete mode 100644 framework/src/suricata/src/detect-http-header.c delete mode 100644 framework/src/suricata/src/detect-http-header.h delete mode 100644 framework/src/suricata/src/detect-http-hh.c delete mode 100644 framework/src/suricata/src/detect-http-hh.h delete mode 100644 framework/src/suricata/src/detect-http-hrh.c delete mode 100644 framework/src/suricata/src/detect-http-hrh.h delete mode 100644 framework/src/suricata/src/detect-http-method.c delete mode 100644 framework/src/suricata/src/detect-http-method.h delete mode 100644 framework/src/suricata/src/detect-http-raw-header.c delete mode 100644 framework/src/suricata/src/detect-http-raw-header.h delete mode 100644 framework/src/suricata/src/detect-http-raw-uri.c delete mode 100644 framework/src/suricata/src/detect-http-raw-uri.h delete mode 100644 framework/src/suricata/src/detect-http-server-body.c delete mode 100644 framework/src/suricata/src/detect-http-server-body.h delete mode 100644 framework/src/suricata/src/detect-http-stat-code.c delete mode 100644 framework/src/suricata/src/detect-http-stat-code.h delete mode 100644 framework/src/suricata/src/detect-http-stat-msg.c delete mode 100644 framework/src/suricata/src/detect-http-stat-msg.h delete mode 100644 framework/src/suricata/src/detect-http-ua.c delete mode 100644 framework/src/suricata/src/detect-http-ua.h delete mode 100644 framework/src/suricata/src/detect-http-uri.c delete mode 100644 framework/src/suricata/src/detect-http-uri.h delete mode 100644 framework/src/suricata/src/detect-icmp-id.c delete mode 100644 framework/src/suricata/src/detect-icmp-id.h delete mode 100644 framework/src/suricata/src/detect-icmp-seq.c delete mode 100644 framework/src/suricata/src/detect-icmp-seq.h delete mode 100644 framework/src/suricata/src/detect-icode.c delete mode 100644 framework/src/suricata/src/detect-icode.h delete mode 100644 framework/src/suricata/src/detect-id.c delete mode 100644 framework/src/suricata/src/detect-id.h delete mode 100644 framework/src/suricata/src/detect-ipopts.c delete mode 100644 framework/src/suricata/src/detect-ipopts.h delete mode 100644 framework/src/suricata/src/detect-ipproto.c delete mode 100644 framework/src/suricata/src/detect-ipproto.h delete mode 100644 framework/src/suricata/src/detect-iprep.c delete mode 100644 framework/src/suricata/src/detect-iprep.h delete mode 100644 framework/src/suricata/src/detect-isdataat.c delete mode 100644 framework/src/suricata/src/detect-isdataat.h delete mode 100644 framework/src/suricata/src/detect-itype.c delete mode 100644 framework/src/suricata/src/detect-itype.h delete mode 100644 framework/src/suricata/src/detect-l3proto.c delete mode 100644 framework/src/suricata/src/detect-l3proto.h delete mode 100644 framework/src/suricata/src/detect-lua-extensions.c delete mode 100644 framework/src/suricata/src/detect-lua-extensions.h delete mode 100644 framework/src/suricata/src/detect-lua.c delete mode 100644 framework/src/suricata/src/detect-lua.h delete mode 100644 framework/src/suricata/src/detect-mark.c delete mode 100644 framework/src/suricata/src/detect-mark.h delete mode 100644 framework/src/suricata/src/detect-metadata.c delete mode 100644 framework/src/suricata/src/detect-metadata.h delete mode 100644 framework/src/suricata/src/detect-modbus.c delete mode 100644 framework/src/suricata/src/detect-modbus.h delete mode 100644 framework/src/suricata/src/detect-msg.c delete mode 100644 framework/src/suricata/src/detect-msg.h delete mode 100644 framework/src/suricata/src/detect-noalert.c delete mode 100644 framework/src/suricata/src/detect-noalert.h delete mode 100644 framework/src/suricata/src/detect-nocase.c delete mode 100644 framework/src/suricata/src/detect-nocase.h delete mode 100644 framework/src/suricata/src/detect-offset.c delete mode 100644 framework/src/suricata/src/detect-offset.h delete mode 100644 framework/src/suricata/src/detect-parse.c delete mode 100644 framework/src/suricata/src/detect-parse.h delete mode 100644 framework/src/suricata/src/detect-pcre.c delete mode 100644 framework/src/suricata/src/detect-pcre.h delete mode 100644 framework/src/suricata/src/detect-pkt-data.c delete mode 100644 framework/src/suricata/src/detect-pkt-data.h delete mode 100644 framework/src/suricata/src/detect-pktvar.c delete mode 100644 framework/src/suricata/src/detect-pktvar.h delete mode 100644 framework/src/suricata/src/detect-priority.c delete mode 100644 framework/src/suricata/src/detect-priority.h delete mode 100644 framework/src/suricata/src/detect-rawbytes.c delete mode 100644 framework/src/suricata/src/detect-rawbytes.h delete mode 100644 framework/src/suricata/src/detect-reference.c delete mode 100644 framework/src/suricata/src/detect-reference.h delete mode 100644 framework/src/suricata/src/detect-replace.c delete mode 100644 framework/src/suricata/src/detect-replace.h delete mode 100644 framework/src/suricata/src/detect-rev.c delete mode 100644 framework/src/suricata/src/detect-rev.h delete mode 100644 framework/src/suricata/src/detect-rpc.c delete mode 100644 framework/src/suricata/src/detect-rpc.h delete mode 100644 framework/src/suricata/src/detect-sameip.c delete mode 100644 framework/src/suricata/src/detect-sameip.h delete mode 100644 framework/src/suricata/src/detect-seq.c delete mode 100644 framework/src/suricata/src/detect-seq.h delete mode 100644 framework/src/suricata/src/detect-sid.c delete mode 100644 framework/src/suricata/src/detect-sid.h delete mode 100644 framework/src/suricata/src/detect-ssh-proto-version.c delete mode 100644 framework/src/suricata/src/detect-ssh-proto-version.h delete mode 100644 framework/src/suricata/src/detect-ssh-software-version.c delete mode 100644 framework/src/suricata/src/detect-ssh-software-version.h delete mode 100644 framework/src/suricata/src/detect-ssl-state.c delete mode 100644 framework/src/suricata/src/detect-ssl-state.h delete mode 100644 framework/src/suricata/src/detect-ssl-version.c delete mode 100644 framework/src/suricata/src/detect-ssl-version.h delete mode 100644 framework/src/suricata/src/detect-stream_size.c delete mode 100644 framework/src/suricata/src/detect-stream_size.h delete mode 100644 framework/src/suricata/src/detect-tag.c delete mode 100644 framework/src/suricata/src/detect-tag.h delete mode 100644 framework/src/suricata/src/detect-template-buffer.c delete mode 100644 framework/src/suricata/src/detect-template-buffer.h delete mode 100644 framework/src/suricata/src/detect-template.c delete mode 100644 framework/src/suricata/src/detect-template.h delete mode 100644 framework/src/suricata/src/detect-threshold.c delete mode 100644 framework/src/suricata/src/detect-threshold.h delete mode 100644 framework/src/suricata/src/detect-tls-version.c delete mode 100644 framework/src/suricata/src/detect-tls-version.h delete mode 100644 framework/src/suricata/src/detect-tls.c delete mode 100644 framework/src/suricata/src/detect-tls.h delete mode 100644 framework/src/suricata/src/detect-tos.c delete mode 100644 framework/src/suricata/src/detect-tos.h delete mode 100644 framework/src/suricata/src/detect-ttl.c delete mode 100644 framework/src/suricata/src/detect-ttl.h delete mode 100644 framework/src/suricata/src/detect-uricontent.c delete mode 100644 framework/src/suricata/src/detect-uricontent.h delete mode 100644 framework/src/suricata/src/detect-urilen.c delete mode 100644 framework/src/suricata/src/detect-urilen.h delete mode 100644 framework/src/suricata/src/detect-window.c delete mode 100644 framework/src/suricata/src/detect-window.h delete mode 100644 framework/src/suricata/src/detect-within.c delete mode 100644 framework/src/suricata/src/detect-within.h delete mode 100644 framework/src/suricata/src/detect-xbits.c delete mode 100644 framework/src/suricata/src/detect-xbits.h delete mode 100644 framework/src/suricata/src/detect.c delete mode 100644 framework/src/suricata/src/detect.h delete mode 100644 framework/src/suricata/src/flow-bit.c delete mode 100644 framework/src/suricata/src/flow-bit.h delete mode 100644 framework/src/suricata/src/flow-hash.c delete mode 100644 framework/src/suricata/src/flow-hash.h delete mode 100644 framework/src/suricata/src/flow-manager.c delete mode 100644 framework/src/suricata/src/flow-manager.h delete mode 100644 framework/src/suricata/src/flow-private.h delete mode 100644 framework/src/suricata/src/flow-queue.c delete mode 100644 framework/src/suricata/src/flow-queue.h delete mode 100644 framework/src/suricata/src/flow-storage.c delete mode 100644 framework/src/suricata/src/flow-storage.h delete mode 100644 framework/src/suricata/src/flow-timeout.c delete mode 100644 framework/src/suricata/src/flow-timeout.h delete mode 100644 framework/src/suricata/src/flow-util.c delete mode 100644 framework/src/suricata/src/flow-util.h delete mode 100644 framework/src/suricata/src/flow-var.c delete mode 100644 framework/src/suricata/src/flow-var.h delete mode 100644 framework/src/suricata/src/flow.c delete mode 100644 framework/src/suricata/src/flow.h delete mode 100644 framework/src/suricata/src/host-bit.c delete mode 100644 framework/src/suricata/src/host-bit.h delete mode 100644 framework/src/suricata/src/host-queue.c delete mode 100644 framework/src/suricata/src/host-queue.h delete mode 100644 framework/src/suricata/src/host-storage.c delete mode 100644 framework/src/suricata/src/host-storage.h delete mode 100644 framework/src/suricata/src/host-timeout.c delete mode 100644 framework/src/suricata/src/host-timeout.h delete mode 100644 framework/src/suricata/src/host.c delete mode 100644 framework/src/suricata/src/host.h delete mode 100644 framework/src/suricata/src/ippair-bit.c delete mode 100644 framework/src/suricata/src/ippair-bit.h delete mode 100644 framework/src/suricata/src/ippair-queue.c delete mode 100644 framework/src/suricata/src/ippair-queue.h delete mode 100644 framework/src/suricata/src/ippair-storage.c delete mode 100644 framework/src/suricata/src/ippair-storage.h delete mode 100644 framework/src/suricata/src/ippair-timeout.c delete mode 100644 framework/src/suricata/src/ippair-timeout.h delete mode 100644 framework/src/suricata/src/ippair.c delete mode 100644 framework/src/suricata/src/ippair.h delete mode 100644 framework/src/suricata/src/log-dnslog.c delete mode 100644 framework/src/suricata/src/log-dnslog.h delete mode 100644 framework/src/suricata/src/log-droplog.c delete mode 100644 framework/src/suricata/src/log-droplog.h delete mode 100644 framework/src/suricata/src/log-file.c delete mode 100644 framework/src/suricata/src/log-file.h delete mode 100644 framework/src/suricata/src/log-filestore.c delete mode 100644 framework/src/suricata/src/log-filestore.h delete mode 100644 framework/src/suricata/src/log-httplog.c delete mode 100644 framework/src/suricata/src/log-httplog.h delete mode 100644 framework/src/suricata/src/log-pcap.c delete mode 100644 framework/src/suricata/src/log-pcap.h delete mode 100644 framework/src/suricata/src/log-stats.c delete mode 100644 framework/src/suricata/src/log-stats.h delete mode 100644 framework/src/suricata/src/log-tcp-data.c delete mode 100644 framework/src/suricata/src/log-tcp-data.h delete mode 100644 framework/src/suricata/src/log-tlslog.c delete mode 100644 framework/src/suricata/src/log-tlslog.h delete mode 100644 framework/src/suricata/src/log-tlsstore.c delete mode 100644 framework/src/suricata/src/log-tlsstore.h delete mode 100644 framework/src/suricata/src/output-file.c delete mode 100644 framework/src/suricata/src/output-file.h delete mode 100644 framework/src/suricata/src/output-filedata.c delete mode 100644 framework/src/suricata/src/output-filedata.h delete mode 100644 framework/src/suricata/src/output-flow.c delete mode 100644 framework/src/suricata/src/output-flow.h delete mode 100644 framework/src/suricata/src/output-json-alert.c delete mode 100644 framework/src/suricata/src/output-json-alert.h delete mode 100644 framework/src/suricata/src/output-json-dns.c delete mode 100644 framework/src/suricata/src/output-json-dns.h delete mode 100644 framework/src/suricata/src/output-json-drop.c delete mode 100644 framework/src/suricata/src/output-json-drop.h delete mode 100644 framework/src/suricata/src/output-json-email-common.c delete mode 100644 framework/src/suricata/src/output-json-email-common.h delete mode 100644 framework/src/suricata/src/output-json-file.c delete mode 100644 framework/src/suricata/src/output-json-file.h delete mode 100644 framework/src/suricata/src/output-json-flow.c delete mode 100644 framework/src/suricata/src/output-json-flow.h delete mode 100644 framework/src/suricata/src/output-json-http.c delete mode 100644 framework/src/suricata/src/output-json-http.h delete mode 100644 framework/src/suricata/src/output-json-netflow.c delete mode 100644 framework/src/suricata/src/output-json-netflow.h delete mode 100644 framework/src/suricata/src/output-json-smtp.c delete mode 100644 framework/src/suricata/src/output-json-smtp.h delete mode 100644 framework/src/suricata/src/output-json-ssh.c delete mode 100644 framework/src/suricata/src/output-json-ssh.h delete mode 100644 framework/src/suricata/src/output-json-stats.c delete mode 100644 framework/src/suricata/src/output-json-stats.h delete mode 100644 framework/src/suricata/src/output-json-template.c delete mode 100644 framework/src/suricata/src/output-json-template.h delete mode 100644 framework/src/suricata/src/output-json-tls.c delete mode 100644 framework/src/suricata/src/output-json-tls.h delete mode 100644 framework/src/suricata/src/output-json.c delete mode 100644 framework/src/suricata/src/output-json.h delete mode 100644 framework/src/suricata/src/output-lua.c delete mode 100644 framework/src/suricata/src/output-lua.h delete mode 100644 framework/src/suricata/src/output-packet.c delete mode 100644 framework/src/suricata/src/output-packet.h delete mode 100644 framework/src/suricata/src/output-stats.c delete mode 100644 framework/src/suricata/src/output-stats.h delete mode 100644 framework/src/suricata/src/output-streaming.c delete mode 100644 framework/src/suricata/src/output-streaming.h delete mode 100644 framework/src/suricata/src/output-tx.c delete mode 100644 framework/src/suricata/src/output-tx.h delete mode 100644 framework/src/suricata/src/output.c delete mode 100644 framework/src/suricata/src/output.h delete mode 100644 framework/src/suricata/src/packet-queue.c delete mode 100644 framework/src/suricata/src/packet-queue.h delete mode 100644 framework/src/suricata/src/pkt-var.c delete mode 100644 framework/src/suricata/src/pkt-var.h delete mode 100644 framework/src/suricata/src/ptxdump.py delete mode 100644 framework/src/suricata/src/queue.h delete mode 100644 framework/src/suricata/src/reputation.c delete mode 100644 framework/src/suricata/src/reputation.h delete mode 100644 framework/src/suricata/src/respond-reject-libnet11.c delete mode 100644 framework/src/suricata/src/respond-reject-libnet11.h delete mode 100644 framework/src/suricata/src/respond-reject.c delete mode 100644 framework/src/suricata/src/respond-reject.h delete mode 100644 framework/src/suricata/src/runmode-af-packet.c delete mode 100644 framework/src/suricata/src/runmode-af-packet.h delete mode 100644 framework/src/suricata/src/runmode-erf-dag.c delete mode 100644 framework/src/suricata/src/runmode-erf-dag.h delete mode 100644 framework/src/suricata/src/runmode-erf-file.c delete mode 100644 framework/src/suricata/src/runmode-erf-file.h delete mode 100644 framework/src/suricata/src/runmode-ipfw.c delete mode 100644 framework/src/suricata/src/runmode-ipfw.h delete mode 100644 framework/src/suricata/src/runmode-napatech.c delete mode 100644 framework/src/suricata/src/runmode-napatech.h delete mode 100644 framework/src/suricata/src/runmode-netmap.c delete mode 100644 framework/src/suricata/src/runmode-netmap.h delete mode 100644 framework/src/suricata/src/runmode-nflog.c delete mode 100644 framework/src/suricata/src/runmode-nflog.h delete mode 100644 framework/src/suricata/src/runmode-nfq.c delete mode 100644 framework/src/suricata/src/runmode-nfq.h delete mode 100644 framework/src/suricata/src/runmode-pcap-file.c delete mode 100644 framework/src/suricata/src/runmode-pcap-file.h delete mode 100644 framework/src/suricata/src/runmode-pcap.c delete mode 100644 framework/src/suricata/src/runmode-pcap.h delete mode 100644 framework/src/suricata/src/runmode-pfring.c delete mode 100644 framework/src/suricata/src/runmode-pfring.h delete mode 100644 framework/src/suricata/src/runmode-tile.c delete mode 100644 framework/src/suricata/src/runmode-tile.h delete mode 100644 framework/src/suricata/src/runmode-unittests.c delete mode 100644 framework/src/suricata/src/runmode-unittests.h delete mode 100644 framework/src/suricata/src/runmode-unix-socket.c delete mode 100644 framework/src/suricata/src/runmode-unix-socket.h delete mode 100644 framework/src/suricata/src/runmodes.c delete mode 100644 framework/src/suricata/src/runmodes.h delete mode 100644 framework/src/suricata/src/source-af-packet.c delete mode 100644 framework/src/suricata/src/source-af-packet.h delete mode 100644 framework/src/suricata/src/source-erf-dag.c delete mode 100644 framework/src/suricata/src/source-erf-dag.h delete mode 100644 framework/src/suricata/src/source-erf-file.c delete mode 100644 framework/src/suricata/src/source-erf-file.h delete mode 100644 framework/src/suricata/src/source-ipfw.c delete mode 100644 framework/src/suricata/src/source-ipfw.h delete mode 100644 framework/src/suricata/src/source-mpipe.c delete mode 100644 framework/src/suricata/src/source-mpipe.h delete mode 100644 framework/src/suricata/src/source-napatech.c delete mode 100644 framework/src/suricata/src/source-napatech.h delete mode 100644 framework/src/suricata/src/source-netmap.c delete mode 100644 framework/src/suricata/src/source-netmap.h delete mode 100644 framework/src/suricata/src/source-nflog.c delete mode 100644 framework/src/suricata/src/source-nflog.h delete mode 100644 framework/src/suricata/src/source-nfq-prototypes.h delete mode 100644 framework/src/suricata/src/source-nfq.c delete mode 100644 framework/src/suricata/src/source-nfq.h delete mode 100644 framework/src/suricata/src/source-pcap-file.c delete mode 100644 framework/src/suricata/src/source-pcap-file.h delete mode 100644 framework/src/suricata/src/source-pcap.c delete mode 100644 framework/src/suricata/src/source-pcap.h delete mode 100644 framework/src/suricata/src/source-pfring.c delete mode 100644 framework/src/suricata/src/source-pfring.h delete mode 100644 framework/src/suricata/src/stream-tcp-inline.c delete mode 100644 framework/src/suricata/src/stream-tcp-inline.h delete mode 100644 framework/src/suricata/src/stream-tcp-private.h delete mode 100644 framework/src/suricata/src/stream-tcp-reassemble.c delete mode 100644 framework/src/suricata/src/stream-tcp-reassemble.h delete mode 100644 framework/src/suricata/src/stream-tcp-sack.c delete mode 100644 framework/src/suricata/src/stream-tcp-sack.h delete mode 100644 framework/src/suricata/src/stream-tcp-util.c delete mode 100644 framework/src/suricata/src/stream-tcp-util.h delete mode 100644 framework/src/suricata/src/stream-tcp.c delete mode 100644 framework/src/suricata/src/stream-tcp.h delete mode 100644 framework/src/suricata/src/stream.c delete mode 100644 framework/src/suricata/src/stream.h delete mode 100644 framework/src/suricata/src/suricata-common.h delete mode 100644 framework/src/suricata/src/suricata.c delete mode 100644 framework/src/suricata/src/suricata.h delete mode 100644 framework/src/suricata/src/threads-arch-tile.h delete mode 100644 framework/src/suricata/src/threads-debug.h delete mode 100644 framework/src/suricata/src/threads-profile.h delete mode 100644 framework/src/suricata/src/threads.c delete mode 100644 framework/src/suricata/src/threads.h delete mode 100644 framework/src/suricata/src/threadvars.h delete mode 100644 framework/src/suricata/src/tm-modules.c delete mode 100644 framework/src/suricata/src/tm-modules.h delete mode 100644 framework/src/suricata/src/tm-queuehandlers.c delete mode 100644 framework/src/suricata/src/tm-queuehandlers.h delete mode 100644 framework/src/suricata/src/tm-queues.c delete mode 100644 framework/src/suricata/src/tm-queues.h delete mode 100644 framework/src/suricata/src/tm-threads-common.h delete mode 100644 framework/src/suricata/src/tm-threads.c delete mode 100644 framework/src/suricata/src/tm-threads.h delete mode 100644 framework/src/suricata/src/tmqh-flow.c delete mode 100644 framework/src/suricata/src/tmqh-flow.h delete mode 100644 framework/src/suricata/src/tmqh-nfq.c delete mode 100644 framework/src/suricata/src/tmqh-nfq.h delete mode 100644 framework/src/suricata/src/tmqh-packetpool.c delete mode 100644 framework/src/suricata/src/tmqh-packetpool.h delete mode 100644 framework/src/suricata/src/tmqh-ringbuffer.c delete mode 100644 framework/src/suricata/src/tmqh-ringbuffer.h delete mode 100644 framework/src/suricata/src/tmqh-simple.c delete mode 100644 framework/src/suricata/src/tmqh-simple.h delete mode 100644 framework/src/suricata/src/unix-manager.c delete mode 100644 framework/src/suricata/src/unix-manager.h delete mode 100644 framework/src/suricata/src/util-action.c delete mode 100644 framework/src/suricata/src/util-action.h delete mode 100644 framework/src/suricata/src/util-affinity.c delete mode 100644 framework/src/suricata/src/util-affinity.h delete mode 100644 framework/src/suricata/src/util-atomic.c delete mode 100644 framework/src/suricata/src/util-atomic.h delete mode 100644 framework/src/suricata/src/util-base64.c delete mode 100644 framework/src/suricata/src/util-base64.h delete mode 100644 framework/src/suricata/src/util-binsearch.c delete mode 100644 framework/src/suricata/src/util-binsearch.h delete mode 100644 framework/src/suricata/src/util-bloomfilter-counting.c delete mode 100644 framework/src/suricata/src/util-bloomfilter-counting.h delete mode 100644 framework/src/suricata/src/util-bloomfilter.c delete mode 100644 framework/src/suricata/src/util-bloomfilter.h delete mode 100644 framework/src/suricata/src/util-buffer.c delete mode 100644 framework/src/suricata/src/util-buffer.h delete mode 100644 framework/src/suricata/src/util-byte.c delete mode 100644 framework/src/suricata/src/util-byte.h delete mode 100644 framework/src/suricata/src/util-checksum.c delete mode 100644 framework/src/suricata/src/util-checksum.h delete mode 100644 framework/src/suricata/src/util-cidr.c delete mode 100644 framework/src/suricata/src/util-cidr.h delete mode 100644 framework/src/suricata/src/util-classification-config.c delete mode 100644 framework/src/suricata/src/util-classification-config.h delete mode 100644 framework/src/suricata/src/util-clock.h delete mode 100644 framework/src/suricata/src/util-conf.c delete mode 100644 framework/src/suricata/src/util-conf.h delete mode 100644 framework/src/suricata/src/util-coredump-config.c delete mode 100644 framework/src/suricata/src/util-coredump-config.h delete mode 100644 framework/src/suricata/src/util-cpu.c delete mode 100644 framework/src/suricata/src/util-cpu.h delete mode 100644 framework/src/suricata/src/util-crypt.c delete mode 100644 framework/src/suricata/src/util-crypt.h delete mode 100644 framework/src/suricata/src/util-cuda-buffer.c delete mode 100644 framework/src/suricata/src/util-cuda-buffer.h delete mode 100644 framework/src/suricata/src/util-cuda-handlers.c delete mode 100644 framework/src/suricata/src/util-cuda-handlers.h delete mode 100644 framework/src/suricata/src/util-cuda-vars.c delete mode 100644 framework/src/suricata/src/util-cuda-vars.h delete mode 100644 framework/src/suricata/src/util-cuda.c delete mode 100644 framework/src/suricata/src/util-cuda.h delete mode 100644 framework/src/suricata/src/util-daemon.c delete mode 100644 framework/src/suricata/src/util-daemon.h delete mode 100644 framework/src/suricata/src/util-debug-filters.c delete mode 100644 framework/src/suricata/src/util-debug-filters.h delete mode 100644 framework/src/suricata/src/util-debug.c delete mode 100644 framework/src/suricata/src/util-debug.h delete mode 100644 framework/src/suricata/src/util-decode-asn1.c delete mode 100644 framework/src/suricata/src/util-decode-asn1.h delete mode 100644 framework/src/suricata/src/util-decode-der-get.c delete mode 100644 framework/src/suricata/src/util-decode-der-get.h delete mode 100644 framework/src/suricata/src/util-decode-der.c delete mode 100644 framework/src/suricata/src/util-decode-der.h delete mode 100644 framework/src/suricata/src/util-decode-mime.c delete mode 100644 framework/src/suricata/src/util-decode-mime.h delete mode 100644 framework/src/suricata/src/util-device.c delete mode 100644 framework/src/suricata/src/util-device.h delete mode 100644 framework/src/suricata/src/util-enum.c delete mode 100644 framework/src/suricata/src/util-enum.h delete mode 100644 framework/src/suricata/src/util-error.c delete mode 100644 framework/src/suricata/src/util-error.h delete mode 100644 framework/src/suricata/src/util-file.c delete mode 100644 framework/src/suricata/src/util-file.h delete mode 100644 framework/src/suricata/src/util-fix_checksum.c delete mode 100644 framework/src/suricata/src/util-fix_checksum.h delete mode 100644 framework/src/suricata/src/util-fmemopen.c delete mode 100644 framework/src/suricata/src/util-fmemopen.h delete mode 100644 framework/src/suricata/src/util-hash-lookup3.c delete mode 100644 framework/src/suricata/src/util-hash-lookup3.h delete mode 100644 framework/src/suricata/src/util-hash.c delete mode 100644 framework/src/suricata/src/util-hash.h delete mode 100644 framework/src/suricata/src/util-hashlist.c delete mode 100644 framework/src/suricata/src/util-hashlist.h delete mode 100644 framework/src/suricata/src/util-host-info.c delete mode 100644 framework/src/suricata/src/util-host-info.h delete mode 100644 framework/src/suricata/src/util-host-os-info.c delete mode 100644 framework/src/suricata/src/util-host-os-info.h delete mode 100644 framework/src/suricata/src/util-ioctl.c delete mode 100644 framework/src/suricata/src/util-ioctl.h delete mode 100644 framework/src/suricata/src/util-ip.c delete mode 100644 framework/src/suricata/src/util-ip.h delete mode 100644 framework/src/suricata/src/util-logopenfile-tile.c delete mode 100644 framework/src/suricata/src/util-logopenfile-tile.h delete mode 100644 framework/src/suricata/src/util-logopenfile.c delete mode 100644 framework/src/suricata/src/util-logopenfile.h delete mode 100644 framework/src/suricata/src/util-lua-common.c delete mode 100644 framework/src/suricata/src/util-lua-common.h delete mode 100644 framework/src/suricata/src/util-lua-dns.c delete mode 100644 framework/src/suricata/src/util-lua-dns.h delete mode 100644 framework/src/suricata/src/util-lua-http.c delete mode 100644 framework/src/suricata/src/util-lua-http.h delete mode 100644 framework/src/suricata/src/util-lua-ssh.c delete mode 100644 framework/src/suricata/src/util-lua-ssh.h delete mode 100644 framework/src/suricata/src/util-lua-tls.c delete mode 100644 framework/src/suricata/src/util-lua-tls.h delete mode 100644 framework/src/suricata/src/util-lua.c delete mode 100644 framework/src/suricata/src/util-lua.h delete mode 100644 framework/src/suricata/src/util-magic.c delete mode 100644 framework/src/suricata/src/util-magic.h delete mode 100644 framework/src/suricata/src/util-mem.h delete mode 100644 framework/src/suricata/src/util-memcmp.c delete mode 100644 framework/src/suricata/src/util-memcmp.h delete mode 100644 framework/src/suricata/src/util-memcpy.h delete mode 100644 framework/src/suricata/src/util-memrchr.c delete mode 100644 framework/src/suricata/src/util-memrchr.h delete mode 100644 framework/src/suricata/src/util-misc.c delete mode 100644 framework/src/suricata/src/util-misc.h delete mode 100644 framework/src/suricata/src/util-mpm-ac-bs.c delete mode 100644 framework/src/suricata/src/util-mpm-ac-bs.h delete mode 100644 framework/src/suricata/src/util-mpm-ac-cuda-kernel.cu delete mode 100644 framework/src/suricata/src/util-mpm-ac-gfbs.c delete mode 100644 framework/src/suricata/src/util-mpm-ac-gfbs.h delete mode 100644 framework/src/suricata/src/util-mpm-ac-tile-small.c delete mode 100644 framework/src/suricata/src/util-mpm-ac-tile.c delete mode 100644 framework/src/suricata/src/util-mpm-ac-tile.h delete mode 100644 framework/src/suricata/src/util-mpm-ac.c delete mode 100644 framework/src/suricata/src/util-mpm-ac.h delete mode 100644 framework/src/suricata/src/util-mpm-b2g.c delete mode 100644 framework/src/suricata/src/util-mpm-b2g.h delete mode 100644 framework/src/suricata/src/util-mpm-b3g.c delete mode 100644 framework/src/suricata/src/util-mpm-b3g.h delete mode 100644 framework/src/suricata/src/util-mpm-wumanber.c delete mode 100644 framework/src/suricata/src/util-mpm-wumanber.h delete mode 100644 framework/src/suricata/src/util-mpm.c delete mode 100644 framework/src/suricata/src/util-mpm.h delete mode 100644 framework/src/suricata/src/util-optimize.h delete mode 100644 framework/src/suricata/src/util-path.c delete mode 100644 framework/src/suricata/src/util-path.h delete mode 100644 framework/src/suricata/src/util-pidfile.c delete mode 100644 framework/src/suricata/src/util-pidfile.h delete mode 100644 framework/src/suricata/src/util-pool-thread.c delete mode 100644 framework/src/suricata/src/util-pool-thread.h delete mode 100644 framework/src/suricata/src/util-pool.c delete mode 100644 framework/src/suricata/src/util-pool.h delete mode 100644 framework/src/suricata/src/util-print.c delete mode 100644 framework/src/suricata/src/util-print.h delete mode 100644 framework/src/suricata/src/util-privs.c delete mode 100644 framework/src/suricata/src/util-privs.h delete mode 100644 framework/src/suricata/src/util-profiling-keywords.c delete mode 100644 framework/src/suricata/src/util-profiling-locks.c delete mode 100644 framework/src/suricata/src/util-profiling-locks.h delete mode 100644 framework/src/suricata/src/util-profiling-rules.c delete mode 100644 framework/src/suricata/src/util-profiling.c delete mode 100644 framework/src/suricata/src/util-profiling.h delete mode 100644 framework/src/suricata/src/util-proto-name.c delete mode 100644 framework/src/suricata/src/util-proto-name.h delete mode 100644 framework/src/suricata/src/util-radix-tree.c delete mode 100644 framework/src/suricata/src/util-radix-tree.h delete mode 100644 framework/src/suricata/src/util-random.c delete mode 100644 framework/src/suricata/src/util-random.h delete mode 100644 framework/src/suricata/src/util-reference-config.c delete mode 100644 framework/src/suricata/src/util-reference-config.h delete mode 100644 framework/src/suricata/src/util-ringbuffer.c delete mode 100644 framework/src/suricata/src/util-ringbuffer.h delete mode 100644 framework/src/suricata/src/util-rohash.c delete mode 100644 framework/src/suricata/src/util-rohash.h delete mode 100644 framework/src/suricata/src/util-rule-vars.c delete mode 100644 framework/src/suricata/src/util-rule-vars.h delete mode 100644 framework/src/suricata/src/util-runmodes.c delete mode 100644 framework/src/suricata/src/util-runmodes.h delete mode 100644 framework/src/suricata/src/util-running-modes.c delete mode 100644 framework/src/suricata/src/util-running-modes.h delete mode 100644 framework/src/suricata/src/util-signal.c delete mode 100644 framework/src/suricata/src/util-signal.h delete mode 100644 framework/src/suricata/src/util-spm-bm.c delete mode 100644 framework/src/suricata/src/util-spm-bm.h delete mode 100644 framework/src/suricata/src/util-spm-bs.c delete mode 100644 framework/src/suricata/src/util-spm-bs.h delete mode 100644 framework/src/suricata/src/util-spm-bs2bm.c delete mode 100644 framework/src/suricata/src/util-spm-bs2bm.h delete mode 100644 framework/src/suricata/src/util-spm.c delete mode 100644 framework/src/suricata/src/util-spm.h delete mode 100644 framework/src/suricata/src/util-storage.c delete mode 100644 framework/src/suricata/src/util-storage.h delete mode 100644 framework/src/suricata/src/util-strlcatu.c delete mode 100644 framework/src/suricata/src/util-strlcpyu.c delete mode 100644 framework/src/suricata/src/util-syslog.c delete mode 100644 framework/src/suricata/src/util-syslog.h delete mode 100644 framework/src/suricata/src/util-threshold-config.c delete mode 100644 framework/src/suricata/src/util-threshold-config.h delete mode 100644 framework/src/suricata/src/util-time.c delete mode 100644 framework/src/suricata/src/util-time.h delete mode 100644 framework/src/suricata/src/util-unittest-helper.c delete mode 100644 framework/src/suricata/src/util-unittest-helper.h delete mode 100644 framework/src/suricata/src/util-unittest.c delete mode 100644 framework/src/suricata/src/util-unittest.h delete mode 100644 framework/src/suricata/src/util-validate.h delete mode 100644 framework/src/suricata/src/util-var-name.c delete mode 100644 framework/src/suricata/src/util-var-name.h delete mode 100644 framework/src/suricata/src/util-var.c delete mode 100644 framework/src/suricata/src/util-var.h delete mode 100644 framework/src/suricata/src/util-vector.h delete mode 100644 framework/src/suricata/src/win32-misc.c delete mode 100644 framework/src/suricata/src/win32-misc.h delete mode 100644 framework/src/suricata/src/win32-service.c delete mode 100644 framework/src/suricata/src/win32-service.h delete mode 100644 framework/src/suricata/src/win32-syslog.h (limited to 'framework/src/suricata/src') diff --git a/framework/src/suricata/src/Makefile.am b/framework/src/suricata/src/Makefile.am deleted file mode 100644 index 4af253a8..00000000 --- a/framework/src/suricata/src/Makefile.am +++ /dev/null @@ -1,502 +0,0 @@ -noinst_HEADERS = action-globals.h \ - app-layer-nbss.h app-layer-dcerpc-common.h \ - debug.h \ - flow-private.h queue.h source-nfq-prototypes.h \ - suricata-common.h threadvars.h util-binsearch.h \ - util-validate.h -bin_PROGRAMS = suricata - -suricata_SOURCES = \ -alert-debuglog.c alert-debuglog.h \ -alert-fastlog.c alert-fastlog.h \ -alert-prelude.c alert-prelude.h \ -alert-syslog.c alert-syslog.h \ -alert-unified2-alert.c alert-unified2-alert.h \ -app-layer.c app-layer.h \ -app-layer-dcerpc.c app-layer-dcerpc.h \ -app-layer-dcerpc-udp.c app-layer-dcerpc-udp.h \ -app-layer-detect-proto.c app-layer-detect-proto.h \ -app-layer-dns-common.c app-layer-dns-common.h \ -app-layer-dns-tcp.c app-layer-dns-tcp.h \ -app-layer-dns-udp.c app-layer-dns-udp.h \ -app-layer-events.c app-layer-events.h \ -app-layer-ftp.c app-layer-ftp.h \ -app-layer-htp-body.c app-layer-htp-body.h \ -app-layer-htp.c app-layer-htp.h \ -app-layer-htp-file.c app-layer-htp-file.h \ -app-layer-htp-libhtp.c app-layer-htp-libhtp.h \ -app-layer-htp-mem.c app-layer-htp-mem.h \ -app-layer-htp-xff.c app-layer-htp-xff.h \ -app-layer-modbus.c app-layer-modbus.h \ -app-layer-parser.c app-layer-parser.h \ -app-layer-protos.c app-layer-protos.h \ -app-layer-smb2.c app-layer-smb2.h \ -app-layer-smb.c app-layer-smb.h \ -app-layer-smtp.c app-layer-smtp.h \ -app-layer-template.c app-layer-template.h \ -app-layer-ssh.c app-layer-ssh.h \ -app-layer-ssl.c app-layer-ssl.h \ -app-layer-tls-handshake.c app-layer-tls-handshake.h \ -conf.c conf.h \ -conf-yaml-loader.c conf-yaml-loader.h \ -counters.c counters.h \ -data-queue.c data-queue.h \ -decode.c decode.h \ -decode-erspan.c decode-erspan.h \ -decode-ethernet.c decode-ethernet.h \ -decode-events.c decode-events.h \ -decode-gre.c decode-gre.h \ -decode-icmpv4.c decode-icmpv4.h \ -decode-icmpv6.c decode-icmpv6.h \ -decode-ipv4.c decode-ipv4.h \ -decode-ipv6.c decode-ipv6.h \ -decode-null.c decode-null.h \ -decode-ppp.c decode-ppp.h \ -decode-pppoe.c decode-pppoe.h \ -decode-raw.c decode-raw.h \ -decode-sctp.c decode-sctp.h \ -decode-sll.c decode-sll.h \ -decode-tcp.c decode-tcp.h \ -decode-teredo.c decode-teredo.h \ -decode-udp.c decode-udp.h \ -decode-vlan.c decode-vlan.h \ -decode-mpls.c decode-mpls.h \ -decode-template.c decode-template.h \ -defrag-config.c defrag-config.h \ -defrag.c defrag.h \ -defrag-hash.c defrag-hash.h \ -defrag-queue.c defrag-queue.h \ -defrag-timeout.c defrag-timeout.h \ -detect-ack.c detect-ack.h \ -detect-app-layer-event.c detect-app-layer-event.h \ -detect-app-layer-protocol.c detect-app-layer-protocol.h \ -detect-asn1.c detect-asn1.h \ -detect-base64-data.c detect-base64-data.h \ -detect-base64-decode.c detect-base64-decode.h \ -detect-byte-extract.c detect-byte-extract.h \ -detect-bytejump.c detect-bytejump.h \ -detect-bytetest.c detect-bytetest.h \ -detect.c detect.h \ -detect-classtype.c detect-classtype.h \ -detect-content.c detect-content.h \ -detect-csum.c detect-csum.h \ -detect-dce-iface.c detect-dce-iface.h \ -detect-dce-opnum.c detect-dce-opnum.h \ -detect-dce-stub-data.c detect-dce-stub-data.h \ -detect-depth.c detect-depth.h \ -detect-detection-filter.c detect-detection-filter.h \ -detect-distance.c detect-distance.h \ -detect-dns-query.c detect-dns-query.h \ -detect-dsize.c detect-dsize.h \ -detect-engine-address.c detect-engine-address.h \ -detect-engine-address-ipv4.c detect-engine-address-ipv4.h \ -detect-engine-address-ipv6.c detect-engine-address-ipv6.h \ -detect-engine-alert.c detect-engine-alert.h \ -detect-engine-analyzer.c detect-engine-analyzer.h \ -detect-engine-apt-event.c detect-engine-apt-event.h \ -detect-engine.c detect-engine.h \ -detect-engine-content-inspection.c detect-engine-content-inspection.h \ -detect-engine-dcepayload.c detect-engine-dcepayload.h \ -detect-engine-dns.c detect-engine-dns.h \ -detect-engine-modbus.c detect-engine-modbus.h \ -detect-engine-event.c detect-engine-event.h \ -detect-engine-file.c detect-engine-file.h \ -detect-engine-filedata-smtp.c detect-engine-filedata-smtp.h \ -detect-engine-hcbd.c detect-engine-hcbd.h \ -detect-engine-hcd.c detect-engine-hcd.h \ -detect-engine-hhd.c detect-engine-hhd.h \ -detect-engine-hhhd.c detect-engine-hhhd.h \ -detect-engine-hmd.c detect-engine-hmd.h \ -detect-engine-hrhd.c detect-engine-hrhd.h \ -detect-engine-hrhhd.c detect-engine-hrhhd.h \ -detect-engine-hrud.c detect-engine-hrud.h \ -detect-engine-hrl.c detect-engine-hrl.h \ -detect-engine-hsbd.c detect-engine-hsbd.h \ -detect-engine-hscd.c detect-engine-hscd.h \ -detect-engine-hsmd.c detect-engine-hsmd.h \ -detect-engine-hua.c detect-engine-hua.h \ -detect-engine-iponly.c detect-engine-iponly.h \ -detect-engine-loader.c detect-engine-loader.h \ -detect-engine-mpm.c detect-engine-mpm.h \ -detect-engine-payload.c detect-engine-payload.h \ -detect-engine-port.c detect-engine-port.h \ -detect-engine-proto.c detect-engine-proto.h \ -detect-engine-siggroup.c detect-engine-siggroup.h \ -detect-engine-sigorder.c detect-engine-sigorder.h \ -detect-engine-state.c detect-engine-state.h \ -detect-engine-tag.c detect-engine-tag.h \ -detect-engine-template.c detect-engine-template.h \ -detect-engine-threshold.c detect-engine-threshold.h \ -detect-engine-uri.c detect-engine-uri.h \ -detect-fast-pattern.c detect-fast-pattern.h \ -detect-file-data.c detect-file-data.h \ -detect-fileext.c detect-fileext.h \ -detect-filemagic.c detect-filemagic.h \ -detect-filemd5.c detect-filemd5.h \ -detect-filename.c detect-filename.h \ -detect-filesize.c detect-filesize.h \ -detect-filestore.c detect-filestore.h \ -detect-flags.c detect-flags.h \ -detect-flowbits.c detect-flowbits.h \ -detect-flow.c detect-flow.h \ -detect-flowint.c detect-flowint.h \ -detect-flowvar.c detect-flowvar.h \ -detect-fragbits.c detect-fragbits.h \ -detect-fragoffset.c detect-fragoffset.h \ -detect-ftpbounce.c detect-ftpbounce.h \ -detect-geoip.c detect-geoip.h \ -detect-gid.c detect-gid.h \ -detect-hostbits.c detect-hostbits.h \ -detect-http-client-body.c detect-http-client-body.h \ -detect-http-cookie.c detect-http-cookie.h \ -detect-http-header.c detect-http-header.h \ -detect-http-hh.c detect-http-hh.h \ -detect-http-hrh.c detect-http-hrh.h \ -detect-http-method.c detect-http-method.h \ -detect-http-raw-header.c detect-http-raw-header.h \ -detect-http-raw-uri.c detect-http-raw-uri.h \ -detect-http-server-body.c detect-http-server-body.h \ -detect-http-stat-code.c detect-http-stat-code.h \ -detect-http-stat-msg.c detect-http-stat-msg.h \ -detect-http-ua.c detect-http-ua.h \ -detect-http-uri.c detect-http-uri.h \ -detect-icmp-id.c detect-icmp-id.h \ -detect-icmp-seq.c detect-icmp-seq.h \ -detect-icode.c detect-icode.h \ -detect-id.c detect-id.h \ -detect-ipopts.c detect-ipopts.h \ -detect-ipproto.c detect-ipproto.h \ -detect-iprep.c detect-iprep.h \ -detect-isdataat.c detect-isdataat.h \ -detect-itype.c detect-itype.h \ -detect-l3proto.c detect-l3proto.h \ -detect-lua.c detect-lua.h \ -detect-lua-extensions.c detect-lua-extensions.h \ -detect-mark.c detect-mark.h \ -detect-metadata.c detect-metadata.h \ -detect-msg.c detect-msg.h \ -detect-noalert.c detect-noalert.h \ -detect-nocase.c detect-nocase.h \ -detect-offset.c detect-offset.h \ -detect-parse.c detect-parse.h \ -detect-pcre.c detect-pcre.h \ -detect-pkt-data.c detect-pkt-data.h \ -detect-pktvar.c detect-pktvar.h \ -detect-priority.c detect-priority.h \ -detect-rawbytes.c detect-rawbytes.h \ -detect-reference.c detect-reference.h \ -detect-replace.c detect-replace.h \ -detect-rev.c detect-rev.h \ -detect-rpc.c detect-rpc.h \ -detect-sameip.c detect-sameip.h \ -detect-seq.c detect-seq.h \ -detect-sid.c detect-sid.h \ -detect-ssh-proto-version.c detect-ssh-proto-version.h \ -detect-ssh-software-version.c detect-ssh-software-version.h \ -detect-ssl-state.c detect-ssl-state.h \ -detect-ssl-version.c detect-ssl-version.h \ -detect-stream_size.c detect-stream_size.h \ -detect-tag.c detect-tag.h \ -detect-template.c detect-template.h \ -detect-template-buffer.c detect-template-buffer.h \ -detect-threshold.c detect-threshold.h \ -detect-tls.c detect-tls.h \ -detect-tls-version.c detect-tls-version.h \ -detect-tos.c detect-tos.h \ -detect-ttl.c detect-ttl.h \ -detect-uricontent.c detect-uricontent.h \ -detect-urilen.c detect-urilen.h \ -detect-window.c detect-window.h \ -detect-within.c detect-within.h \ -detect-modbus.c detect-modbus.h \ -detect-xbits.c detect-xbits.h \ -flow-bit.c flow-bit.h \ -flow.c flow.h \ -flow-hash.c flow-hash.h \ -flow-manager.c flow-manager.h \ -flow-queue.c flow-queue.h \ -flow-storage.c flow-storage.h \ -flow-timeout.c flow-timeout.h \ -flow-util.c flow-util.h \ -flow-var.c flow-var.h \ -host.c host.h \ -host-bit.c host-bit.h \ -host-queue.c host-queue.h \ -host-storage.c host-storage.h \ -host-timeout.c host-timeout.h \ -ippair.c ippair.h \ -ippair-bit.c ippair-bit.h \ -ippair-queue.c ippair-queue.h \ -ippair-storage.c ippair-storage.h \ -ippair-timeout.c ippair-timeout.h \ -log-dnslog.c log-dnslog.h \ -log-droplog.c log-droplog.h \ -log-file.c log-file.h \ -log-filestore.c log-filestore.h \ -log-httplog.c log-httplog.h \ -log-pcap.c log-pcap.h \ -log-stats.c log-stats.h \ -log-tcp-data.c log-tcp-data.h \ -log-tlslog.c log-tlslog.h \ -log-tlsstore.c log-tlsstore.h \ -output.c output.h \ -output-file.c output-file.h \ -output-filedata.c output-filedata.h \ -output-flow.c output-flow.h \ -output-json-alert.c output-json-alert.h \ -output-json-dns.c output-json-dns.h \ -output-json-drop.c output-json-drop.h \ -output-json-email-common.c output-json-email-common.h \ -output-json-file.c output-json-file.h \ -output-json-flow.c output-json-flow.h \ -output-json-netflow.c output-json-netflow.h \ -output-json-http.c output-json-http.h \ -output-json-smtp.c output-json-smtp.h \ -output-json-ssh.c output-json-ssh.h \ -output-json-stats.c output-json-stats.h \ -output-json-tls.c output-json-tls.h \ -output-json-template.c output-json-template.h \ -output-lua.c output-lua.h \ -output-packet.c output-packet.h \ -output-stats.c output-stats.h \ -output-streaming.c output-streaming.h \ -output-tx.c output-tx.h \ -output-json.c output-json.h \ -packet-queue.c packet-queue.h \ -pkt-var.c pkt-var.h \ -reputation.c reputation.h \ -respond-reject.c respond-reject.h \ -respond-reject-libnet11.h respond-reject-libnet11.c \ -runmode-af-packet.c runmode-af-packet.h \ -runmode-erf-dag.c runmode-erf-dag.h \ -runmode-erf-file.c runmode-erf-file.h \ -runmode-ipfw.c runmode-ipfw.h \ -runmode-napatech.c runmode-napatech.h \ -runmode-netmap.c runmode-netmap.h \ -runmode-nfq.c runmode-nfq.h \ -runmode-nflog.c runmode-nflog.h \ -runmode-pcap.c runmode-pcap.h \ -runmode-pcap-file.c runmode-pcap-file.h \ -runmode-pfring.c runmode-pfring.h \ -runmode-unittests.c runmode-unittests.h \ -runmode-unix-socket.c runmode-unix-socket.h \ -runmode-tile.c runmode-tile.h \ -runmodes.c runmodes.h \ -source-af-packet.c source-af-packet.h \ -source-erf-dag.c source-erf-dag.h \ -source-erf-file.c source-erf-file.h \ -source-ipfw.c source-ipfw.h \ -source-mpipe.c source-mpipe.h \ -source-napatech.c source-napatech.h \ -source-netmap.c source-netmap.h \ -source-nfq.c source-nfq.h \ -source-nflog.c source-nflog.h \ -source-pcap.c source-pcap.h \ -source-pcap-file.c source-pcap-file.h \ -source-pfring.c source-pfring.h \ -stream.c stream.h \ -stream-tcp.c stream-tcp.h stream-tcp-private.h \ -stream-tcp-inline.c stream-tcp-inline.h \ -stream-tcp-reassemble.c stream-tcp-reassemble.h \ -stream-tcp-sack.c stream-tcp-sack.h \ -stream-tcp-util.c stream-tcp-util.h \ -suricata.c suricata.h \ -threads.c threads.h threads-arch-tile.h \ -threads-debug.h threads-profile.h \ -tm-modules.c tm-modules.h \ -tmqh-flow.c tmqh-flow.h \ -tmqh-nfq.c tmqh-nfq.h \ -tmqh-packetpool.c tmqh-packetpool.h \ -tmqh-ringbuffer.c tmqh-ringbuffer.h \ -tmqh-simple.c tmqh-simple.h \ -tm-queuehandlers.c tm-queuehandlers.h \ -tm-queues.c tm-queues.h \ -tm-threads.c tm-threads.h tm-threads-common.h \ -unix-manager.c unix-manager.h \ -util-action.c util-action.h \ -util-atomic.c util-atomic.h \ -util-base64.c util-base64.h \ -util-bloomfilter-counting.c util-bloomfilter-counting.h \ -util-bloomfilter.c util-bloomfilter.h \ -util-buffer.c util-buffer.h \ -util-byte.c util-byte.h \ -util-checksum.c util-checksum.h \ -util-cidr.c util-cidr.h \ -util-classification-config.c util-classification-config.h \ -util-conf.c util-conf.h \ -util-coredump-config.c util-coredump-config.h \ -util-cpu.c util-cpu.h \ -util-crypt.c util-crypt.h \ -util-cuda.c util-cuda.h \ -util-cuda-buffer.c util-cuda-buffer.h \ -util-cuda-handlers.c util-cuda-handlers.h \ -util-cuda-vars.c util-cuda-vars.h \ -util-daemon.c util-daemon.h \ -util-debug.c util-debug.h \ -util-debug-filters.c util-debug-filters.h \ -util-decode-asn1.c util-decode-asn1.h \ -util-decode-der.c util-decode-der.h \ -util-decode-der-get.c util-decode-der-get.h \ -util-decode-mime.c util-decode-mime.h \ -util-device.c util-device.h \ -util-enum.c util-enum.h \ -util-error.c util-error.h \ -util-file.c util-file.h \ -util-fix_checksum.c util-fix_checksum.h \ -util-fmemopen.c util-fmemopen.h \ -util-hash.c util-hash.h \ -util-hashlist.c util-hashlist.h \ -util-hash-lookup3.c util-hash-lookup3.h \ -util-host-os-info.c util-host-os-info.h \ -util-host-info.c util-host-info.h \ -util-ioctl.h util-ioctl.c \ -util-ip.h util-ip.c \ -util-logopenfile.h util-logopenfile.c \ -util-logopenfile-tile.h util-logopenfile-tile.c \ -util-lua.c util-lua.h \ -util-lua-common.c util-lua-common.h \ -util-lua-dns.c util-lua-dns.h \ -util-lua-http.c util-lua-http.h \ -util-lua-tls.c util-lua-tls.h \ -util-lua-ssh.c util-lua-ssh.h \ -util-magic.c util-magic.h \ -util-memcmp.c util-memcmp.h \ -util-memcpy.h \ -util-mem.h \ -util-memrchr.c util-memrchr.h \ -util-misc.c util-misc.h \ -util-mpm-ac-bs.c util-mpm-ac-bs.h \ -util-mpm-ac.c util-mpm-ac.h \ -util-mpm-ac-gfbs.c util-mpm-ac-gfbs.h \ -util-mpm-ac-tile.c util-mpm-ac-tile.h \ -util-mpm-ac-tile-small.c \ -util-mpm-b2g.c util-mpm-b2g.h \ -util-mpm-b3g.c util-mpm-b3g.h \ -util-mpm.c util-mpm.h \ -util-mpm-wumanber.c util-mpm-wumanber.h \ -util-optimize.h \ -util-path.c util-path.h \ -util-pidfile.c util-pidfile.h \ -util-pool.c util-pool.h \ -util-pool-thread.c util-pool-thread.h \ -util-print.c util-print.h \ -util-privs.c util-privs.h \ -util-profiling.c util-profiling.h \ -util-profiling-locks.c util-profiling-locks.h \ -util-profiling-rules.c \ -util-profiling-keywords.c \ -util-proto-name.c util-proto-name.h \ -util-radix-tree.c util-radix-tree.h \ -util-random.c util-random.h \ -util-reference-config.c util-reference-config.h \ -util-ringbuffer.c util-ringbuffer.h \ -util-rohash.c util-rohash.h \ -util-rule-vars.c util-rule-vars.h \ -util-runmodes.c util-runmodes.h \ -util-running-modes.c util-running-modes.h \ -util-signal.c util-signal.h \ -util-spm-bm.c util-spm-bm.h \ -util-spm-bs2bm.c util-spm-bs2bm.h \ -util-spm-bs.c util-spm-bs.h \ -util-spm.c util-spm.h util-clock.h \ -util-storage.c util-storage.h \ -util-strlcatu.c \ -util-strlcpyu.c \ -util-syslog.c util-syslog.h \ -util-threshold-config.c util-threshold-config.h \ -util-time.c util-time.h \ -util-unittest.c util-unittest.h \ -util-unittest-helper.c util-unittest-helper.h \ -util-validate.h util-affinity.h util-affinity.c \ -util-var.c util-var.h \ -util-var-name.c util-var-name.h \ -util-vector.h \ -win32-misc.c win32-misc.h \ -win32-service.c win32-service.h \ -win32-syslog.h - -EXTRA_DIST = util-mpm-ac-cuda-kernel.cu ptxdump.py - -# set the include path found by configure -AM_CPPFLAGS = $(all_includes) - -# the library search path. -suricata_LDFLAGS = $(all_libraries) -suricata_LDADD = $(HTP_LDADD) - -# Rules to build CUDA ptx modules -if BUILD_CUDA -BUILT_SOURCES = cuda-ptxdump.h - -suricata_CUDA_KERNELS = \ -util-mpm-ac-cuda-kernel.cu - -NVCCFLAGS=-O2 - -SUFFIXES = \ -.ptx_sm_10 \ -.ptx_sm_11 \ -.ptx_sm_12 \ -.ptx_sm_13 \ -.ptx_sm_20 \ -.ptx_sm_21 \ -.ptx_sm_30 \ -.ptx_sm_35 - -PTXS = $(suricata_CUDA_KERNELS:.cu=.ptx_sm_10) -PTXS += $(suricata_CUDA_KERNELS:.cu=.ptx_sm_11) -PTXS += $(suricata_CUDA_KERNELS:.cu=.ptx_sm_12) -PTXS += $(suricata_CUDA_KERNELS:.cu=.ptx_sm_13) -PTXS += $(suricata_CUDA_KERNELS:.cu=.ptx_sm_20) -PTXS += $(suricata_CUDA_KERNELS:.cu=.ptx_sm_21) -PTXS += $(suricata_CUDA_KERNELS:.cu=.ptx_sm_30) -PTXS += $(suricata_CUDA_KERNELS:.cu=.ptx_sm_35) - -.cu.ptx_sm_10: - $(NVCC) $(NVCCFLAGS) -o $@ -arch=sm_10 -ptx $< - -.cu.ptx_sm_11: - $(NVCC) $(NVCCFLAGS) -o $@ -arch=sm_11 -ptx $< - -.cu.ptx_sm_12: - $(NVCC) $(NVCCFLAGS) -o $@ -arch=sm_12 -ptx $< - -.cu.ptx_sm_13: - $(NVCC) $(NVCCFLAGS) -o $@ -arch=sm_13 -ptx $< - -.cu.ptx_sm_20: - $(NVCC) $(NVCCFLAGS) -o $@ -arch=sm_20 -ptx $< - -.cu.ptx_sm_21: - $(NVCC) $(NVCCFLAGS) -o $@ -arch=sm_21 -ptx $< - -.cu.ptx_sm_30: - $(NVCC) $(NVCCFLAGS) -o $@ -arch=sm_30 -ptx $< - -.cu.ptx_sm_35: - $(NVCC) $(NVCCFLAGS) -o $@ -arch=sm_35 -ptx $< - -cuda-ptxdump.h: $(PTXS) - $(PYTHON) ptxdump.py cuda-ptxdump $(PTXS) - -CLEANFILES = $(PTXS) cuda-ptxdump.h -endif - -# default CFLAGS -AM_CFLAGS = ${OPTIMIZATION_CFLAGS} ${GCC_CFLAGS} ${CLANG_CFLAGS} ${SECCFLAGS} ${PCAP_CFLAGS} -Wall -Wno-unused-parameter -std=gnu99 -DLOCAL_STATE_DIR=\"$(localstatedir)\" -# different flags for different cases -if DEBUG -AM_CFLAGS += -ggdb -O0 -endif - -AM_LDFLAGS = ${SECLDFLAGS} - -if BUILD_UNITTESTS -check-am: - -mkdir $(top_builddir)/qa/log/ - $(top_builddir)/src/suricata -u -l $(top_builddir)/qa/log/ - -rm -rf $(top_builddir)/qa/log -endif - -distclean-local: - -rm -rf $(top_builddir)/src/build-info.h diff --git a/framework/src/suricata/src/action-globals.h b/framework/src/suricata/src/action-globals.h deleted file mode 100644 index aa46bd29..00000000 --- a/framework/src/suricata/src/action-globals.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __ACTION_GLOBALS_H__ -#define __ACTION_GLOBALS_H__ - -/* Changing them as flags, so later we can have alerts - * and drop simultaneously */ -#define ACTION_ALERT 0x01 -#define ACTION_DROP 0x02 -#define ACTION_REJECT 0x04 -#define ACTION_REJECT_DST 0x08 -#define ACTION_REJECT_BOTH 0x10 -#define ACTION_PASS 0x20 - -#endif /* __ACTION_GLOBALS_H__ */ diff --git a/framework/src/suricata/src/alert-debuglog.c b/framework/src/suricata/src/alert-debuglog.c deleted file mode 100644 index 5df1f4c1..00000000 --- a/framework/src/suricata/src/alert-debuglog.c +++ /dev/null @@ -1,526 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" -#include "stream.h" -#include "app-layer-protos.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" - -#include "pkt-var.h" - -#include "util-unittest.h" - -#include "util-debug.h" -#include "util-buffer.h" - -#include "output.h" -#include "alert-debuglog.h" -#include "util-privs.h" -#include "flow-var.h" -#include "flow-bit.h" -#include "util-var-name.h" -#include "util-optimize.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#include "stream-tcp-reassemble.h" - -#define DEFAULT_LOG_FILENAME "alert-debug.log" - -#define MODULE_NAME "AlertDebugLog" - -typedef struct AlertDebugLogThread_ { - LogFileCtx *file_ctx; - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - MemBuffer *buffer; -} AlertDebugLogThread; - -/** - * \brief Function to log the FlowVars in to alert-debug.log - * - * \param aft Pointer to AltertDebugLog Thread - * \param p Pointer to the packet - * - */ -static void AlertDebugLogFlowVars(AlertDebugLogThread *aft, const Packet *p) -{ - const GenericVar *gv = p->flow->flowvar; - uint16_t i; - while (gv != NULL) { - if (gv->type == DETECT_FLOWVAR || gv->type == DETECT_FLOWINT) { - FlowVar *fv = (FlowVar *) gv; - - if (fv->datatype == FLOWVAR_TYPE_STR) { - MemBufferWriteString(aft->buffer, "FLOWVAR idx(%"PRIu32"): ", - fv->idx); - for (i = 0; i < fv->data.fv_str.value_len; i++) { - if (isprint(fv->data.fv_str.value[i])) { - MemBufferWriteString(aft->buffer, "%c", - fv->data.fv_str.value[i]); - } else { - MemBufferWriteString(aft->buffer, "\\%02X", - fv->data.fv_str.value[i]); - } - } - } else if (fv->datatype == FLOWVAR_TYPE_INT) { - MemBufferWriteString(aft->buffer, "FLOWVAR idx(%"PRIu32"): " - " %" PRIu32 "\"", fv->idx, fv->data.fv_int.value); - } - } - gv = gv->next; - } -} - -/** - * \brief Function to log the FlowBits in to alert-debug.log - * - * \param aft Pointer to AltertDebugLog Thread - * \param p Pointer to the packet - * - * \todo const Packet ptr, requires us to change the - * debuglog_flowbits_names logic. - */ -static void AlertDebugLogFlowBits(AlertDebugLogThread *aft, Packet *p) -{ - int i; - for (i = 0; i < p->debuglog_flowbits_names_len; i++) { - if (p->debuglog_flowbits_names[i] != NULL) { - MemBufferWriteString(aft->buffer, "FLOWBIT: %s\n", - p->debuglog_flowbits_names[i]); - } - } - - SCFree(p->debuglog_flowbits_names); - p->debuglog_flowbits_names = NULL; - p->debuglog_flowbits_names_len = 0; - - return; -} - -/** - * \brief Function to log the PktVars in to alert-debug.log - * - * \param aft Pointer to AltertDebugLog Thread - * \param p Pointer to the packet - * - */ -static void AlertDebugLogPktVars(AlertDebugLogThread *aft, const Packet *p) -{ - const PktVar *pv = p->pktvar; - - while(pv != NULL) { - MemBufferWriteString(aft->buffer, "PKTVAR: %s\n", pv->name); - PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - pv->value, pv->value_len); - pv = pv->next; - } -} - -/** \todo doc - * assume we have aft lock */ -static int AlertDebugPrintStreamSegmentCallback(const Packet *p, void *data, uint8_t *buf, uint32_t buflen) -{ - AlertDebugLogThread *aft = (AlertDebugLogThread *)data; - - MemBufferWriteString(aft->buffer, "STREAM DATA LEN: %"PRIu32"\n", buflen); - MemBufferWriteString(aft->buffer, "STREAM DATA:\n"); - - PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - buf, buflen); - - return 1; -} - -static TmEcode AlertDebugLogger(ThreadVars *tv, const Packet *p, void *thread_data) -{ - AlertDebugLogThread *aft = (AlertDebugLogThread *)thread_data; - int i; - char timebuf[64]; - const char *pkt_src_str = NULL; - - if (p->alerts.cnt == 0) - return TM_ECODE_OK; - - MemBufferReset(aft->buffer); - - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - MemBufferWriteString(aft->buffer, "+================\n" - "TIME: %s\n", timebuf); - if (p->pcap_cnt > 0) { - MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); - } - pkt_src_str = PktSrcToString(p->pkt_src); - MemBufferWriteString(aft->buffer, "PKT SRC: %s\n", pkt_src_str); - - char srcip[46], dstip[46]; - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - } - - MemBufferWriteString(aft->buffer, "SRC IP: %s\n" - "DST IP: %s\n" - "PROTO: %" PRIu32 "\n", - srcip, dstip, p->proto); - if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { - MemBufferWriteString(aft->buffer, "SRC PORT: %" PRIu32 "\n" - "DST PORT: %" PRIu32 "\n", - p->sp, p->dp); - if (PKT_IS_TCP(p)) { - MemBufferWriteString(aft->buffer, "TCP SEQ: %"PRIu32"\n" - "TCP ACK: %"PRIu32"\n", - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - } - } - - /* flow stuff */ - MemBufferWriteString(aft->buffer, "FLOW: to_server: %s, " - "to_client: %s\n", - p->flowflags & FLOW_PKT_TOSERVER ? "TRUE" : "FALSE", - p->flowflags & FLOW_PKT_TOCLIENT ? "TRUE" : "FALSE"); - - if (p->flow != NULL) { - int applayer = 0; - FLOWLOCK_RDLOCK(p->flow); - applayer = StreamTcpAppLayerIsDisabled(p->flow); - CreateTimeString(&p->flow->startts, timebuf, sizeof(timebuf)); - MemBufferWriteString(aft->buffer, "FLOW Start TS: %s\n", timebuf); - MemBufferWriteString(aft->buffer, "FLOW PKTS TODST: %"PRIu32"\n" - "FLOW PKTS TOSRC: %"PRIu32"\n" - "FLOW Total Bytes: %"PRIu64"\n", - p->flow->todstpktcnt, p->flow->tosrcpktcnt, - p->flow->todstbytecnt + p->flow->tosrcbytecnt); - MemBufferWriteString(aft->buffer, - "FLOW IPONLY SET: TOSERVER: %s, TOCLIENT: %s\n" - "FLOW ACTION: DROP: %s\n" - "FLOW NOINSPECTION: PACKET: %s, PAYLOAD: %s, APP_LAYER: %s\n" - "FLOW APP_LAYER: DETECTED: %s, PROTO %"PRIu16"\n", - p->flow->flags & FLOW_TOSERVER_IPONLY_SET ? "TRUE" : "FALSE", - p->flow->flags & FLOW_TOCLIENT_IPONLY_SET ? "TRUE" : "FALSE", - p->flow->flags & FLOW_ACTION_DROP ? "TRUE" : "FALSE", - p->flow->flags & FLOW_NOPACKET_INSPECTION ? "TRUE" : "FALSE", - p->flow->flags & FLOW_NOPAYLOAD_INSPECTION ? "TRUE" : "FALSE", - applayer ? "TRUE" : "FALSE", - (p->flow->alproto != ALPROTO_UNKNOWN) ? "TRUE" : "FALSE", p->flow->alproto); - AlertDebugLogFlowVars(aft, p); - AlertDebugLogFlowBits(aft, (Packet *)p); /* < no const */ - FLOWLOCK_UNLOCK(p->flow); - } - - AlertDebugLogPktVars(aft, p); - -/* any stuff */ -/* Sig details? */ - - MemBufferWriteString(aft->buffer, - "PACKET LEN: %" PRIu32 "\n" - "PACKET:\n", - GET_PKT_LEN(p)); - PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - GET_PKT_DATA(p), GET_PKT_LEN(p)); - - MemBufferWriteString(aft->buffer, "ALERT CNT: %" PRIu32 "\n", - p->alerts.cnt); - - for (i = 0; i < p->alerts.cnt; i++) { - const PacketAlert *pa = &p->alerts.alerts[i]; - if (unlikely(pa->s == NULL)) { - continue; - } - - MemBufferWriteString(aft->buffer, - "ALERT MSG [%02d]: %s\n" - "ALERT GID [%02d]: %" PRIu32 "\n" - "ALERT SID [%02d]: %" PRIu32 "\n" - "ALERT REV [%02d]: %" PRIu32 "\n" - "ALERT CLASS [%02d]: %s\n" - "ALERT PRIO [%02d]: %" PRIu32 "\n" - "ALERT FOUND IN [%02d]: %s\n", - i, pa->s->msg, - i, pa->s->gid, - i, pa->s->id, - i, pa->s->rev, - i, pa->s->class_msg ? pa->s->class_msg : "", - i, pa->s->prio, - i, - pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH ? "STREAM" : - (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH ? "STATE" : "PACKET")); - if (pa->flags & PACKET_ALERT_FLAG_TX) { - MemBufferWriteString(aft->buffer, - "ALERT IN TX [%02d]: %"PRIu64"\n", i, pa->tx_id); - } else { - MemBufferWriteString(aft->buffer, - "ALERT IN TX [%02d]: N/A\n", i); - } - if (p->payload_len > 0) { - MemBufferWriteString(aft->buffer, - "PAYLOAD LEN: %" PRIu32 "\n" - "PAYLOAD:\n", - p->payload_len); - PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - p->payload, p->payload_len); - } - if ((pa->flags & PACKET_ALERT_FLAG_STATE_MATCH) || - (pa->flags & PACKET_ALERT_FLAG_STREAM_MATCH)) { - /* This is an app layer or stream alert */ - int ret; - uint8_t flag; - if (!(PKT_IS_TCP(p)) || p->flow == NULL || - p->flow->protoctx == NULL) { - return TM_ECODE_OK; - } - /* IDS mode reverse the data */ - /** \todo improve the order selection policy */ - if (p->flowflags & FLOW_PKT_TOSERVER) { - flag = FLOW_PKT_TOCLIENT; - } else { - flag = FLOW_PKT_TOSERVER; - } - ret = StreamSegmentForEach((const Packet *)p, flag, - AlertDebugPrintStreamSegmentCallback, - (void *)aft); - if (ret < 0) { - return TM_ECODE_FAILED; - } - } - } - - SCMutexLock(&aft->file_ctx->fp_mutex); - (void)MemBufferPrintToFPAsString(aft->buffer, aft->file_ctx->fp); - fflush(aft->file_ctx->fp); - aft->file_ctx->alerts += p->alerts.cnt; - SCMutexUnlock(&aft->file_ctx->fp_mutex); - - return TM_ECODE_OK; -} - -static TmEcode AlertDebugLogDecoderEvent(ThreadVars *tv, const Packet *p, void *thread_data) -{ - AlertDebugLogThread *aft = (AlertDebugLogThread *)thread_data; - int i; - char timebuf[64]; - const char *pkt_src_str = NULL; - - if (p->alerts.cnt == 0) - return TM_ECODE_OK; - - MemBufferReset(aft->buffer); - - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - MemBufferWriteString(aft->buffer, - "+================\n" - "TIME: %s\n", timebuf); - if (p->pcap_cnt > 0) { - MemBufferWriteString(aft->buffer, - "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); - } - pkt_src_str = PktSrcToString(p->pkt_src); - MemBufferWriteString(aft->buffer, "PKT SRC: %s\n", pkt_src_str); - MemBufferWriteString(aft->buffer, - "ALERT CNT: %" PRIu32 "\n", p->alerts.cnt); - - for (i = 0; i < p->alerts.cnt; i++) { - const PacketAlert *pa = &p->alerts.alerts[i]; - if (unlikely(pa->s == NULL)) { - continue; - } - - MemBufferWriteString(aft->buffer, - "ALERT MSG [%02d]: %s\n" - "ALERT GID [%02d]: %" PRIu32 "\n" - "ALERT SID [%02d]: %" PRIu32 "\n" - "ALERT REV [%02d]: %" PRIu32 "\n" - "ALERT CLASS [%02d]: %s\n" - "ALERT PRIO [%02d]: %" PRIu32 "\n", - i, pa->s->msg, - i, pa->s->gid, - i, pa->s->id, - i, pa->s->rev, - i, pa->s->class_msg, - i, pa->s->prio); - } - - MemBufferWriteString(aft->buffer, - "PACKET LEN: %" PRIu32 "\n" - "PACKET:\n", - GET_PKT_LEN(p)); - PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - GET_PKT_DATA(p), GET_PKT_LEN(p)); - - SCMutexLock(&aft->file_ctx->fp_mutex); - aft->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), - MEMBUFFER_OFFSET(aft->buffer), aft->file_ctx); - aft->file_ctx->alerts += p->alerts.cnt; - SCMutexUnlock(&aft->file_ctx->fp_mutex); - - return TM_ECODE_OK; -} - -static TmEcode AlertDebugLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - AlertDebugLogThread *aft = SCMalloc(sizeof(AlertDebugLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(AlertDebugLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for DebugLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - /** Use the Ouptut Context (file pointer and mutex) */ - aft->file_ctx = ((OutputCtx *)initdata)->data; - - /* 1 mb seems sufficient enough */ - aft->buffer = MemBufferCreateNew(1 * 1024 * 1024); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode AlertDebugLogThreadDeinit(ThreadVars *t, void *data) -{ - AlertDebugLogThread *aft = (AlertDebugLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(AlertDebugLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void AlertDebugLogExitPrintStats(ThreadVars *tv, void *data) -{ - AlertDebugLogThread *aft = (AlertDebugLogThread *)data; - if (aft == NULL) { - return; - } - - SCLogInfo("(%s) Alerts %" PRIu64 "", tv->name, aft->file_ctx->alerts); -} - -static void AlertDebugLogDeInitCtx(OutputCtx *output_ctx) -{ - if (output_ctx != NULL) { - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - if (logfile_ctx != NULL) { - LogFileFreeCtx(logfile_ctx); - } - SCFree(output_ctx); - } -} - -/** - * \brief Create a new LogFileCtx for alert debug logging. - * - * \param ConfNode containing configuration for this logger. - * - * \return output_ctx if succesful, NULL otherwise - */ -static OutputCtx *AlertDebugLogInitCtx(ConfNode *conf) -{ - LogFileCtx *file_ctx = NULL; - - file_ctx = LogFileNewCtx(); - if (file_ctx == NULL) { - SCLogDebug("couldn't create new file_ctx"); - goto error; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - goto error; - } - - OutputCtx *output_ctx = SCMalloc(sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) - goto error; - - memset(output_ctx, 0x00, sizeof(OutputCtx)); - output_ctx->data = file_ctx; - output_ctx->DeInit = AlertDebugLogDeInitCtx; - - SCLogDebug("Alert debug log output initialized"); - return output_ctx; - -error: - if (file_ctx != NULL) { - LogFileFreeCtx(file_ctx); - } - - return NULL; -} - -static int AlertDebugLogCondition(ThreadVars *tv, const Packet *p) -{ - return (p->alerts.cnt ? TRUE : FALSE); -} - -static int AlertDebugLogLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - if (PKT_IS_IPV4(p) || PKT_IS_IPV6(p)) { - return AlertDebugLogger(tv, p, thread_data); - } else if (p->events.cnt > 0) { - return AlertDebugLogDecoderEvent(tv, p, thread_data); - } - return TM_ECODE_OK; -} - -void TmModuleAlertDebugLogRegister (void) -{ - tmm_modules[TMM_ALERTDEBUGLOG].name = MODULE_NAME; - tmm_modules[TMM_ALERTDEBUGLOG].ThreadInit = AlertDebugLogThreadInit; - tmm_modules[TMM_ALERTDEBUGLOG].Func = NULL; - tmm_modules[TMM_ALERTDEBUGLOG].ThreadExitPrintStats = AlertDebugLogExitPrintStats; - tmm_modules[TMM_ALERTDEBUGLOG].ThreadDeinit = AlertDebugLogThreadDeinit; - tmm_modules[TMM_ALERTDEBUGLOG].RegisterTests = NULL; - tmm_modules[TMM_ALERTDEBUGLOG].cap_flags = 0; - tmm_modules[TMM_ALERTDEBUGLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterPacketModule(MODULE_NAME, "alert-debug", - AlertDebugLogInitCtx, AlertDebugLogLogger, AlertDebugLogCondition); -} diff --git a/framework/src/suricata/src/alert-debuglog.h b/framework/src/suricata/src/alert-debuglog.h deleted file mode 100644 index 8eb38d97..00000000 --- a/framework/src/suricata/src/alert-debuglog.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __ALERT_DEBUGLOG_H__ -#define __ALERT_DEBUGLOG_H__ - -void TmModuleAlertDebugLogRegister (void); - -#endif /* __ALERT_DEBUGLOG_H__ */ - diff --git a/framework/src/suricata/src/alert-fastlog.c b/framework/src/suricata/src/alert-fastlog.c deleted file mode 100644 index 41630f8a..00000000 --- a/framework/src/suricata/src/alert-fastlog.c +++ /dev/null @@ -1,386 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Logs alerts in a line based text format compatible to Snort's - * alert_fast format. - * - * \todo Support classifications - * \todo Support more than just IPv4/IPv6 TCP/UDP. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" - -#include "threads.h" -#include "tm-threads.h" -#include "threadvars.h" -#include "util-debug.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-reference.h" -#include "util-classification-config.h" - -#include "output.h" -#include "alert-fastlog.h" - -#include "util-privs.h" -#include "util-print.h" -#include "util-proto-name.h" -#include "util-optimize.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#define DEFAULT_LOG_FILENAME "fast.log" - -#define MODULE_NAME "AlertFastLog" - -/* The largest that size allowed for one alert string. */ -#define MAX_FASTLOG_ALERT_SIZE 2048 -/* The largest alert buffer that will be written at one time, possibly - * holding multiple alerts. */ -#define MAX_FASTLOG_BUFFER_SIZE (2 * MAX_FASTLOG_ALERT_SIZE) - -TmEcode AlertFastLogThreadInit(ThreadVars *, void *, void **); -TmEcode AlertFastLogThreadDeinit(ThreadVars *, void *); -void AlertFastLogExitPrintStats(ThreadVars *, void *); -void AlertFastLogRegisterTests(void); -static void AlertFastLogDeInitCtx(OutputCtx *); - -int AlertFastLogCondition(ThreadVars *tv, const Packet *p); -int AlertFastLogger(ThreadVars *tv, void *data, const Packet *p); - -void TmModuleAlertFastLogRegister (void) -{ - tmm_modules[TMM_ALERTFASTLOG].name = MODULE_NAME; - tmm_modules[TMM_ALERTFASTLOG].ThreadInit = AlertFastLogThreadInit; - tmm_modules[TMM_ALERTFASTLOG].ThreadExitPrintStats = AlertFastLogExitPrintStats; - tmm_modules[TMM_ALERTFASTLOG].ThreadDeinit = AlertFastLogThreadDeinit; - tmm_modules[TMM_ALERTFASTLOG].RegisterTests = AlertFastLogRegisterTests; - tmm_modules[TMM_ALERTFASTLOG].cap_flags = 0; - tmm_modules[TMM_ALERTFASTLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterPacketModule(MODULE_NAME, "fast", - AlertFastLogInitCtx, AlertFastLogger, AlertFastLogCondition); -} - -typedef struct AlertFastLogThread_ { - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - LogFileCtx* file_ctx; -} AlertFastLogThread; - -int AlertFastLogCondition(ThreadVars *tv, const Packet *p) -{ - return (p->alerts.cnt ? TRUE : FALSE); -} - -static inline void AlertFastLogOutputAlert(AlertFastLogThread *aft, char *buffer, - int alert_size) -{ - SCMutex *file_lock = &aft->file_ctx->fp_mutex; - /* Output the alert string and count alerts. Only need to lock here. */ - SCMutexLock(file_lock); - aft->file_ctx->alerts++; - aft->file_ctx->Write(buffer, alert_size, aft->file_ctx); - SCMutexUnlock(file_lock); -} - -int AlertFastLogger(ThreadVars *tv, void *data, const Packet *p) -{ - AlertFastLogThread *aft = (AlertFastLogThread *)data; - int i; - char timebuf[64]; - int decoder_event = 0; - - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - char srcip[46], dstip[46]; - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - } else { - decoder_event = 1; - } - - /* Buffer to store the generated alert strings. The buffer is - * filled with alert strings until it doesn't have room to store - * another full alert, only then is the buffer written. This is - * more efficient for multiple alerts and only slightly slower for - * single alerts. - */ - char alert_buffer[MAX_FASTLOG_BUFFER_SIZE]; - - for (i = 0; i < p->alerts.cnt; i++) { - const PacketAlert *pa = &p->alerts.alerts[i]; - if (unlikely(pa->s == NULL)) { - continue; - } - - char *action = ""; - if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { - action = "[Drop] "; - } else if (pa->action & ACTION_DROP) { - action = "[wDrop] "; - } - - char proto[16] = ""; - if (likely(decoder_event == 0)) { - if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) { - strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto)); - } else { - snprintf(proto, sizeof(proto), "PROTO:%03" PRIu32, IP_GET_IPPROTO(p)); - } - } - - /* Create the alert string without locking. */ - int size = 0; - if (likely(decoder_event == 0)) { - PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, - "%s %s[**] [%" PRIu32 ":%" PRIu32 ":%" - PRIu32 "] %s [**] [Classification: %s] [Priority: %"PRIu32"]" - " {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "\n", timebuf, action, - pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio, - proto, srcip, p->sp, dstip, p->dp); - } else { - PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, - "%s %s[**] [%" PRIu32 ":%" PRIu32 - ":%" PRIu32 "] %s [**] [Classification: %s] [Priority: " - "%" PRIu32 "] [**] [Raw pkt: ", timebuf, action, pa->s->gid, - pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio); - PrintBufferRawLineHex(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, - GET_PKT_DATA(p), GET_PKT_LEN(p) < 32 ? GET_PKT_LEN(p) : 32); - if (p->pcap_cnt != 0) { - PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, - "] [pcap file packet: %"PRIu64"]\n", p->pcap_cnt); - } else { - PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, "]\n"); - } - } - - /* Write the alert to output file */ - AlertFastLogOutputAlert(aft, alert_buffer, size); - } - - return TM_ECODE_OK; -} - -TmEcode AlertFastLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - AlertFastLogThread *aft = SCMalloc(sizeof(AlertFastLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(AlertFastLogThread)); - if(initdata == NULL) - { - SCLogDebug("Error getting context for AlertFastLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - /** Use the Ouptut Context (file pointer and mutex) */ - aft->file_ctx = ((OutputCtx *)initdata)->data; - - *data = (void *)aft; - return TM_ECODE_OK; -} - -TmEcode AlertFastLogThreadDeinit(ThreadVars *t, void *data) -{ - AlertFastLogThread *aft = (AlertFastLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - /* clear memory */ - memset(aft, 0, sizeof(AlertFastLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -void AlertFastLogExitPrintStats(ThreadVars *tv, void *data) -{ - AlertFastLogThread *aft = (AlertFastLogThread *)data; - if (aft == NULL) { - return; - } - - SCLogInfo("Fast log output wrote %" PRIu64 " alerts", aft->file_ctx->alerts); -} - -/** - * \brief Create a new LogFileCtx for "fast" output style. - * \param conf The configuration node for this output. - * \return A LogFileCtx pointer on success, NULL on failure. - */ -OutputCtx *AlertFastLogInitCtx(ConfNode *conf) -{ - LogFileCtx *logfile_ctx = LogFileNewCtx(); - if (logfile_ctx == NULL) { - SCLogDebug("AlertFastLogInitCtx2: Could not create new LogFileCtx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(logfile_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) - return NULL; - output_ctx->data = logfile_ctx; - output_ctx->DeInit = AlertFastLogDeInitCtx; - - return output_ctx; -} - -static void AlertFastLogDeInitCtx(OutputCtx *output_ctx) -{ - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - LogFileFreeCtx(logfile_ctx); - SCFree(output_ctx); -} - -/*------------------------------Unittests-------------------------------------*/ - -#ifdef UNITTESTS - -static int AlertFastLogTest01() -{ - int result = 0; - uint8_t *buf = (uint8_t *) "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n"; - - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - return result; - } - - de_ctx->flags |= DE_QUIET; - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"FastLog test\"; content:\"GET\"; " - "Classtype:unknown; sid:1;)"); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt == 1) { - result = (strcmp(p->alerts.alerts[0].s->class_msg, "Unknown are we") == 0); - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); - return result; -} - -static int AlertFastLogTest02() -{ - int result = 0; - uint8_t *buf = (uint8_t *) "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - return result; - } - - de_ctx->flags |= DE_QUIET; - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"FastLog test\"; content:\"GET\"; " - "Classtype:unknown; sid:1;)"); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt == 1) { - result = (strcmp(p->alerts.alerts[0].s->class_msg, - "Unknown are we") == 0); - if (result == 0) - printf("p->alerts.alerts[0].class_msg %s: ", p->alerts.alerts[0].s->class_msg); - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief This function registers unit tests for AlertFastLog API. - */ -void AlertFastLogRegisterTests(void) -{ - -#ifdef UNITTESTS - - UtRegisterTest("AlertFastLogTest01", AlertFastLogTest01, 1); - UtRegisterTest("AlertFastLogTest02", AlertFastLogTest02, 1); - -#endif /* UNITTESTS */ - -} diff --git a/framework/src/suricata/src/alert-fastlog.h b/framework/src/suricata/src/alert-fastlog.h deleted file mode 100644 index ac3c45a7..00000000 --- a/framework/src/suricata/src/alert-fastlog.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __ALERT_FASTLOG_H__ -#define __ALERT_FASTLOG_H__ - -void TmModuleAlertFastLogRegister(void); -void TmModuleAlertFastLogIPv4Register(void); -void TmModuleAlertFastLogIPv6Register(void); -OutputCtx *AlertFastLogInitCtx(ConfNode *); - -#endif /* __ALERT_FASTLOG_H__ */ - diff --git a/framework/src/suricata/src/alert-prelude.c b/framework/src/suricata/src/alert-prelude.c deleted file mode 100644 index a053e38b..00000000 --- a/framework/src/suricata/src/alert-prelude.c +++ /dev/null @@ -1,885 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pierre Chifflier - * \author Yoann Vandoorselaere - * - * Logs alerts to the Prelude system, using IDMEF (RFC 4765) messages. - * - * Each message contains the alert description and reference (using - * the SID/GID), and a normalized description (assessment, impact, - * sources etc.) - * - * libprelude handles the connection with the manager (collecting component), - * spooling and sending the event asynchronously. It also offers transport - * security (using TLS and trusted certificates) and reliability (events - * are retransmitted if not sent successfully). - * - * This modules requires a Prelude profile to work (see man prelude-admin - * and the Prelude Handbook for help). - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-time.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-print.h" - -#include "output.h" -#include "util-privs.h" -#include "util-optimize.h" - -#include "stream.h" - -#ifndef PRELUDE - -/* Handle the case where no PRELUDE support is compiled in. */ - -static TmEcode AlertPreludeThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogDebug("Can't init Prelude output thread - Prelude support was disabled during build."); - return TM_ECODE_FAILED; -} - -static TmEcode AlertPreludeThreadDeinit(ThreadVars *t, void *data) -{ - return TM_ECODE_FAILED; -} - -void TmModuleAlertPreludeRegister (void) -{ - tmm_modules[TMM_ALERTPRELUDE].name = "AlertPrelude"; - tmm_modules[TMM_ALERTPRELUDE].ThreadInit = AlertPreludeThreadInit; - tmm_modules[TMM_ALERTPRELUDE].ThreadDeinit = AlertPreludeThreadDeinit; -} - -#else /* implied we do have PRELUDE support */ - -#include - -#define ANALYZER_CLASS "NIDS" -#define ANALYZER_MODEL "Suricata" -#define ANALYZER_MANUFACTURER "http://www.openinfosecfoundation.org/" -#define ANALYZER_SID_URL "http://www.snort.org/search/sid/" - -#define SNORT_MAX_OWNED_SID 1000000 -#define DEFAULT_ANALYZER_NAME "suricata" - -#define DEFAULT_PRELUDE_PROFILE "suricata" - -static unsigned int info_priority = 4; -static unsigned int low_priority = 3; -static unsigned int mid_priority = 2; - -/** - * This holds global structures and variables. Since libprelude is thread-safe, - * there is no need to store a mutex. - */ -typedef struct AlertPreludeCtx_ { - /** The client (which has the send function) */ - prelude_client_t *client; - int log_packet_content; - int log_packet_header; -} AlertPreludeCtx; - -/** - * This holds per-thread specific structures and variables. - */ -typedef struct AlertPreludeThread_ { - /** Pointer to the global context */ - AlertPreludeCtx *ctx; -} AlertPreludeThread; - - -/** - * \brief Initialize analyzer description - * - * \return 0 if ok - */ -static int SetupAnalyzer(idmef_analyzer_t *analyzer) -{ - int ret; - prelude_string_t *string; - - SCEnter(); - - ret = idmef_analyzer_new_model(analyzer, &string); - if (unlikely(ret < 0)) - SCReturnInt(ret); - prelude_string_set_constant(string, ANALYZER_MODEL); - - ret = idmef_analyzer_new_class(analyzer, &string); - if (unlikely(ret < 0)) - SCReturnInt(ret); - prelude_string_set_constant(string, ANALYZER_CLASS); - - ret = idmef_analyzer_new_manufacturer(analyzer, &string); - if (unlikely(ret < 0)) - SCReturnInt(ret); - prelude_string_set_constant(string, ANALYZER_MANUFACTURER); - - ret = idmef_analyzer_new_version(analyzer, &string); - if (unlikely(ret < 0)) - SCReturnInt(ret); - prelude_string_set_constant(string, VERSION); - - SCReturnInt(0); -} - -/** - * \brief Create event impact description (see section - * 4.2.6.1 of RFC 4765). - * The impact contains the severity, completion (succeeded or failed) - * and basic classification of the attack type. - * Here, we don't set the completion since we don't know it (default - * is unknown). - * - * \return 0 if ok - */ -static int EventToImpact(const PacketAlert *pa, const Packet *p, idmef_alert_t *alert) -{ - int ret; - prelude_string_t *str; - idmef_impact_t *impact; - idmef_assessment_t *assessment; - idmef_impact_severity_t severity; - - SCEnter(); - - ret = idmef_alert_new_assessment(alert, &assessment); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_assessment_new_impact(assessment, &impact); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - if ( (unsigned int)pa->s->prio < mid_priority ) - severity = IDMEF_IMPACT_SEVERITY_HIGH; - - else if ( (unsigned int)pa->s->prio < low_priority ) - severity = IDMEF_IMPACT_SEVERITY_MEDIUM; - - else if ( (unsigned int)pa->s->prio < info_priority ) - severity = IDMEF_IMPACT_SEVERITY_LOW; - - else - severity = IDMEF_IMPACT_SEVERITY_INFO; - - idmef_impact_set_severity(impact, severity); - - if (PACKET_TEST_ACTION(p, ACTION_DROP)) { - idmef_action_t *action; - - ret = idmef_action_new(&action); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - idmef_action_set_category(action, IDMEF_ACTION_CATEGORY_BLOCK_INSTALLED); - idmef_assessment_set_action(assessment, action, 0); - } - - if (pa->s->class_msg) { - ret = idmef_impact_new_description(impact, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - prelude_string_set_ref(str, pa->s->class_msg); - } - - SCReturnInt(0); -} - -/** - * \brief Add Source and Target fields to the IDMEF alert. - * These objects contains IP addresses, source and destination - * ports (see sections 4.2.4.3 and 4.2.4.4 of RFC 4765). - * - * \return 0 if ok - */ -static int EventToSourceTarget(const Packet *p, idmef_alert_t *alert) -{ - int ret; - idmef_node_t *node; - idmef_source_t *source; - idmef_target_t *target; - idmef_address_t *address; - idmef_service_t *service; - prelude_string_t *string; - static char saddr[128], daddr[128]; - uint8_t ip_vers; - uint8_t ip_proto; - - SCEnter(); - - if ( !p ) - SCReturnInt(0); - - if ( ! IPH_IS_VALID(p) ) - SCReturnInt(0); - - if (PKT_IS_IPV4(p)) { - ip_vers = 4; - ip_proto = IPV4_GET_RAW_IPPROTO(p->ip4h); - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), saddr, sizeof(saddr)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), daddr, sizeof(daddr)); - } else if (PKT_IS_IPV6(p)) { - ip_vers = 6; - ip_proto = IPV6_GET_L4PROTO(p); - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), saddr, sizeof(saddr)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), daddr, sizeof(daddr)); - } else - SCReturnInt(0); - - ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_source_new_service(source, &service); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - if ( p->tcph || p->udph ) - idmef_service_set_port(service, p->sp); - - idmef_service_set_ip_version(service, ip_vers); - idmef_service_set_iana_protocol_number(service, ip_proto); - - ret = idmef_source_new_node(source, &node); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_address_new_address(address, &string); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - prelude_string_set_ref(string, saddr); - - ret = idmef_alert_new_target(alert, &target, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_target_new_service(target, &service); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - if ( p->tcph || p->udph ) - idmef_service_set_port(service, p->dp); - - idmef_service_set_ip_version(service, ip_vers); - idmef_service_set_iana_protocol_number(service, ip_proto); - - ret = idmef_target_new_node(target, &node); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_address_new_address(address, &string); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - prelude_string_set_ref(string, daddr); - - SCReturnInt(0); -} - -/** - * \brief Add binary data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * - * \return 0 if ok - */ -static int AddByteData(idmef_alert_t *alert, const char *meaning, const unsigned char *data, size_t size) -{ - int ret; - prelude_string_t *str; - idmef_additional_data_t *ad; - - SCEnter(); - - if ( ! data || ! size ) - SCReturnInt(0); - - ret = idmef_alert_new_additional_data(alert, &ad, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(0); - - ret = idmef_additional_data_set_byte_string_ref(ad, data, size); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting byte string data: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - ret = idmef_additional_data_new_meaning(ad, &str); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating additional-data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - ret = prelude_string_set_ref(str, meaning); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting byte string data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - SCReturnInt(0); -} - -/** - * \brief Add integer data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * - * \return 0 if ok - */ -static int AddIntData(idmef_alert_t *alert, const char *meaning, uint32_t data) -{ - int ret; - prelude_string_t *str; - idmef_additional_data_t *ad; - - SCEnter(); - - ret = idmef_alert_new_additional_data(alert, &ad, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - idmef_additional_data_set_integer(ad, data); - - ret = idmef_additional_data_new_meaning(ad, &str); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error creating additional-data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - ret = prelude_string_set_ref(str, meaning); - if (unlikely(ret < 0)) { - SCLogDebug("%s: error setting integer data meaning: %s.", - prelude_strsource(ret), prelude_strerror(ret)); - SCReturnInt(-1); - } - - SCReturnInt(0); -} - -/** - * \brief Add IPv4 header data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * - * \return 0 if ok - */ -static int PacketToDataV4(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - SCEnter(); - - AddIntData(alert, "ip_ver", IPV4_GET_RAW_VER(p->ip4h)); - AddIntData(alert, "ip_hlen", IPV4_GET_RAW_HLEN(p->ip4h)); - AddIntData(alert, "ip_tos", IPV4_GET_RAW_IPTOS(p->ip4h)); - AddIntData(alert, "ip_len", ntohs(IPV4_GET_RAW_IPLEN(p->ip4h))); - - AddIntData(alert, "ip_id", ntohs(IPV4_GET_RAW_IPID(p->ip4h))); - - AddIntData(alert, "ip_off", ntohs(IPV4_GET_RAW_IPOFFSET(p->ip4h))); - - AddIntData(alert, "ip_ttl", IPV4_GET_RAW_IPTTL(p->ip4h)); - AddIntData(alert, "ip_proto", IPV4_GET_RAW_IPPROTO(p->ip4h)); - - AddIntData(alert, "ip_sum", ntohs(p->ip4h->ip_csum)); - - SCReturnInt(0); -} - -/** - * \brief Add IPv6 header data, to be stored in the Additional Data - * field of the IDMEF alert (see section 4.2.4.6 of RFC 4765). - * - * \return 0 if ok - */ -static int PacketToDataV6(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert) -{ - return 0; -} - - -/** - * \brief Convert IP packet to an IDMEF alert (RFC 4765). - * This function stores the alert SID (description and reference), - * the payload of the packet, and pre-processed data. - * - * \return 0 if ok - */ -static int PacketToData(const Packet *p, const PacketAlert *pa, idmef_alert_t *alert, AlertPreludeCtx *ctx) -{ - SCEnter(); - - if (unlikely(p == NULL)) - SCReturnInt(0); - - AddIntData(alert, "snort_rule_sid", pa->s->id); - AddIntData(alert, "snort_rule_rev", pa->s->rev); - - if (ctx->log_packet_header) { - if ( PKT_IS_IPV4(p) ) - PacketToDataV4(p, pa, alert); - - else if ( PKT_IS_IPV6(p) ) - PacketToDataV6(p, pa, alert); - - if ( PKT_IS_TCP(p) ) { - AddIntData(alert, "tcp_seq", ntohl(p->tcph->th_seq)); - AddIntData(alert, "tcp_ack", ntohl(p->tcph->th_ack)); - - AddIntData(alert, "tcp_off", TCP_GET_RAW_OFFSET(p->tcph)); - AddIntData(alert, "tcp_res", TCP_GET_RAW_X2(p->tcph)); - AddIntData(alert, "tcp_flags", p->tcph->th_flags); - - AddIntData(alert, "tcp_win", ntohs(p->tcph->th_win)); - AddIntData(alert, "tcp_sum", ntohs(p->tcph->th_sum)); - AddIntData(alert, "tcp_urp", ntohs(p->tcph->th_urp)); - - } - - else if ( PKT_IS_UDP(p) ) { - AddIntData(alert, "udp_len", ntohs(p->udph->uh_len)); - AddIntData(alert, "udp_sum", ntohs(p->udph->uh_sum)); - } - - else if ( PKT_IS_ICMPV4(p) ) { - AddIntData(alert, "icmp_type", p->icmpv4h->type); - AddIntData(alert, "icmp_code", p->icmpv4h->code); - AddIntData(alert, "icmp_sum", ntohs(p->icmpv4h->checksum)); - - } - } - - if (ctx->log_packet_content) - AddByteData(alert, "payload", p->payload, p->payload_len); - - SCReturnInt(0); -} - -/** - * \brief Store reference on rule (SID and GID) in the IDMEF alert, - * and embed an URL pointing to the rule description. - * - * \return 0 if ok - */ -static int AddSnortReference(idmef_classification_t *class, int gen_id, int sig_id) -{ - int ret; - prelude_string_t *str; - idmef_reference_t *ref; - - SCEnter(); - - if ( sig_id >= SNORT_MAX_OWNED_SID ) - SCReturnInt(0); - - ret = idmef_classification_new_reference(class, &ref, IDMEF_LIST_APPEND); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_reference_new_name(ref, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - idmef_reference_set_origin(ref, IDMEF_REFERENCE_ORIGIN_VENDOR_SPECIFIC); - - if ( gen_id == 0 ) - ret = prelude_string_sprintf(str, "%u", sig_id); - else - ret = prelude_string_sprintf(str, "%u:%u", gen_id, sig_id); - - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_reference_new_meaning(ref, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = prelude_string_sprintf(str, "Snort Signature ID"); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = idmef_reference_new_url(ref, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - if ( gen_id == 0 ) - ret = prelude_string_sprintf(str, ANALYZER_SID_URL "%u", sig_id); - else - ret = prelude_string_sprintf(str, ANALYZER_SID_URL "%u-%u", gen_id, sig_id); - - SCReturnInt(ret); -} - -/** - * \brief Create event classification description (see section - * 4.2.4.2 of RFC 4765). - * The classification is the "name" of the alert, identification of the - * rule signature, and additional information on the rule. - * - * \return 0 if ok - */ -static int EventToReference(const PacketAlert *pa, const Packet *p, idmef_classification_t *class) -{ - int ret; - prelude_string_t *str; - - SCEnter(); - - ret = idmef_classification_new_ident(class, &str); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - if ( pa->s->gid == 0 ) - ret = prelude_string_sprintf(str, "%u", pa->s->id); - else - ret = prelude_string_sprintf(str, "%u:%u", pa->s->gid, pa->s->id); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - ret = AddSnortReference(class, pa->s->gid, pa->s->id); - if (unlikely(ret < 0)) - SCReturnInt(ret); - - SCReturnInt(0); -} - -static int PreludePrintStreamSegmentCallback(const Packet *p, void *data, uint8_t *buf, uint32_t buflen) -{ - int ret; - - ret = AddByteData((idmef_alert_t *)data, "stream-segment", buf, buflen); - if (ret == 0) - return 1; - else - return -1; -} - -/** - * \brief Initialize thread-specific data. Each thread structure contains - * a pointer to the \a AlertPreludeCtx context. - * - * \return TM_ECODE_OK if ok, else TM_ECODE_FAILED - */ -static TmEcode AlertPreludeThreadInit(ThreadVars *t, void *initdata, void **data) -{ - AlertPreludeThread *aun; - - SCEnter(); - - if(unlikely(initdata == NULL)) - { - SCLogDebug("Error getting context for Prelude. \"initdata\" argument NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - aun = SCMalloc(sizeof(AlertPreludeThread)); - if (unlikely(aun == NULL)) - SCReturnInt(TM_ECODE_FAILED); - memset(aun, 0, sizeof(AlertPreludeThread)); - - /** Use the Ouput Context */ - aun->ctx = ((OutputCtx *)initdata)->data; - - *data = (void *)aun; - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Free thread-specific data. - * - * \return TM_ECODE_OK if ok, else TM_ECODE_FAILED - */ -static TmEcode AlertPreludeThreadDeinit(ThreadVars *t, void *data) -{ - AlertPreludeThread *aun = (AlertPreludeThread *)data; - - SCEnter(); - - if (unlikely(aun == NULL)) { - SCLogDebug("AlertPreludeThreadDeinit done (error)"); - SCReturnInt(TM_ECODE_FAILED); - } - - /* clear memory */ - memset(aun, 0, sizeof(AlertPreludeThread)); - SCFree(aun); - - SCReturnInt(TM_ECODE_OK); -} - -static void AlertPreludeDeinitCtx(OutputCtx *output_ctx) -{ - AlertPreludeCtx *ctx = (AlertPreludeCtx *)output_ctx->data; - - prelude_client_destroy(ctx->client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCFree(output_ctx); -} - -/** \brief Initialize the Prelude logging module: initialize - * library, create the client and try to establish the connection - * to the Prelude Manager. - * Client flags are set to force asynchronous (non-blocking) mode for - * both alerts and heartbeats. - * This function requires an existing Prelude profile to work. - * - * \return A newly allocated AlertPreludeCtx structure, or NULL - */ -static OutputCtx *AlertPreludeInitCtx(ConfNode *conf) -{ - int ret; - prelude_client_t *client; - AlertPreludeCtx *ctx; - const char *prelude_profile_name; - const char *log_packet_content; - const char *log_packet_header; - OutputCtx *output_ctx; - - SCEnter(); - - ret = prelude_init(0, NULL); - if (unlikely(ret < 0)) { - prelude_perror(ret, "unable to initialize the prelude library"); - SCReturnPtr(NULL, "AlertPreludeCtx"); - } - - prelude_profile_name = ConfNodeLookupChildValue(conf, "profile"); - if (prelude_profile_name == NULL) - prelude_profile_name = DEFAULT_PRELUDE_PROFILE; - - log_packet_content = ConfNodeLookupChildValue(conf, "log-packet-content"); - log_packet_header = ConfNodeLookupChildValue(conf, "log-packet-header"); - - ret = prelude_client_new(&client, prelude_profile_name); - if ( unlikely(ret < 0 || client == NULL )) { - prelude_perror(ret, "Unable to create a prelude client object"); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnPtr(NULL, "AlertPreludeCtx"); - } - - ret = prelude_client_set_flags(client, prelude_client_get_flags(client) | PRELUDE_CLIENT_FLAGS_ASYNC_TIMER|PRELUDE_CLIENT_FLAGS_ASYNC_SEND); - if (unlikely(ret < 0)) { - SCLogDebug("Unable to set asynchronous send and timer."); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnPtr(NULL, "AlertPreludeCtx"); - } - - SetupAnalyzer(prelude_client_get_analyzer(client)); - - ret = prelude_client_start(client); - if (unlikely(ret < 0)) { - prelude_perror(ret, "Unable to start prelude client"); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnPtr(NULL, "AlertPreludeCtx"); - } - - ctx = SCMalloc(sizeof(AlertPreludeCtx)); - if (unlikely(ctx == NULL)) { - prelude_perror(ret, "Unable to allocate memory"); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnPtr(NULL, "AlertPreludeCtx"); - } - - ctx->client = client; - ctx->log_packet_content = 0; - ctx->log_packet_header = 1; - if (log_packet_content && ConfValIsTrue(log_packet_content)) - ctx->log_packet_content = 1; - if (log_packet_header && ConfValIsFalse(log_packet_header)) - ctx->log_packet_header = 0; - - output_ctx = SCMalloc(sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(ctx); - prelude_perror(ret, "Unable to allocate memory"); - prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS); - SCReturnPtr(NULL, "AlertPreludeCtx"); - } - - output_ctx->data = ctx; - output_ctx->DeInit = AlertPreludeDeinitCtx; - - SCReturnPtr((void*)output_ctx, "OutputCtx"); -} - -static int AlertPreludeCondition(ThreadVars *tv, const Packet *p) -{ - if (p->alerts.cnt == 0) - return FALSE; - if (!IPH_IS_VALID(p)) - return FALSE; - return TRUE; -} - -/** - * \brief Handle Suricata alert: convert it to and IDMEF alert (see RFC 4765) - * and send it asynchronously (so, this function does not block and returns - * immediately). - * If the destination Prelude Manager is not available, the alert is spooled - * (and the function also returns immediately). - * An IDMEF object is created, and all available information is added: IP packet - * header and data, rule signature ID, additional data like URL pointing to - * rule description, CVE, etc. - * The IDMEF alert has a reference to all created objects, so freeing it will - * automatically free all allocated memory. - * - * \note This function is thread safe. - * - * \return TM_ECODE_OK if ok, else TM_ECODE_FAILED - */ -static int AlertPreludeLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - AlertPreludeThread *apn = (AlertPreludeThread *)thread_data; - int ret; - idmef_time_t *time; - idmef_alert_t *alert; - prelude_string_t *str; - idmef_message_t *idmef = NULL; - idmef_classification_t *class; - const PacketAlert *pa; - - SCEnter(); - - if (unlikely(apn == NULL || apn->ctx == NULL)) { - SCReturnInt(TM_ECODE_FAILED); - } - - if (p->alerts.cnt == 0) - SCReturnInt(TM_ECODE_OK); - - if ( !IPH_IS_VALID(p) ) - SCReturnInt(TM_ECODE_OK); - - /* XXX which one to add to this alert? Lets see how Snort solves this. - * For now just take last alert. */ - pa = &p->alerts.alerts[p->alerts.cnt-1]; - if (unlikely(pa->s == NULL)) - goto err; - - ret = idmef_message_new(&idmef); - if (unlikely(ret < 0)) - SCReturnInt(TM_ECODE_FAILED); - - ret = idmef_message_new_alert(idmef, &alert); - if (unlikely(ret < 0)) - goto err; - - ret = idmef_alert_new_classification(alert, &class); - if (unlikely(ret < 0)) - goto err; - - if (pa->s->msg) { - ret = idmef_classification_new_text(class, &str); - if (unlikely(ret < 0)) - goto err; - - prelude_string_set_ref(str, pa->s->msg); - } - - ret = EventToImpact(pa, p, alert); - if (unlikely(ret < 0)) - goto err; - - ret = EventToReference(pa, p, class); - if (unlikely(ret < 0)) - goto err; - - ret = EventToSourceTarget(p, alert); - if (unlikely(ret < 0)) - goto err; - - ret = PacketToData(p, pa, alert, apn->ctx); - if (unlikely(ret < 0)) - goto err; - - if (PKT_IS_TCP(p) && (pa->flags & PACKET_ALERT_FLAG_STATE_MATCH)) { - uint8_t flag; - if (p->flowflags & FLOW_PKT_TOSERVER) { - flag = FLOW_PKT_TOCLIENT; - } else { - flag = FLOW_PKT_TOSERVER; - } - ret = StreamSegmentForEach(p, flag, - PreludePrintStreamSegmentCallback, - (void *)alert); - } - if (unlikely(ret < 0)) - goto err; - - ret = idmef_alert_new_detect_time(alert, &time); - if (unlikely(ret < 0)) - goto err; - idmef_time_set_from_timeval(time, &p->ts); - - ret = idmef_time_new_from_gettimeofday(&time); - if (unlikely(ret < 0)) - goto err; - idmef_alert_set_create_time(alert, time); - - idmef_alert_set_analyzer(alert, idmef_analyzer_ref(prelude_client_get_analyzer(apn->ctx->client)), IDMEF_LIST_PREPEND); - - /* finally, send event */ - prelude_client_send_idmef(apn->ctx->client, idmef); - idmef_message_destroy(idmef); - - SCReturnInt(TM_ECODE_OK); - -err: - if (idmef != NULL) - idmef_message_destroy(idmef); - SCReturnInt(TM_ECODE_FAILED); -} - -void TmModuleAlertPreludeRegister (void) -{ - tmm_modules[TMM_ALERTPRELUDE].name = "AlertPrelude"; - tmm_modules[TMM_ALERTPRELUDE].ThreadInit = AlertPreludeThreadInit; - tmm_modules[TMM_ALERTPRELUDE].Func = NULL; - tmm_modules[TMM_ALERTPRELUDE].ThreadDeinit = AlertPreludeThreadDeinit; - tmm_modules[TMM_ALERTPRELUDE].cap_flags = 0; - tmm_modules[TMM_ALERTPRELUDE].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterPacketModule("AlertPrelude", "alert-prelude", AlertPreludeInitCtx, - AlertPreludeLogger, AlertPreludeCondition); -} -#endif /* PRELUDE */ - diff --git a/framework/src/suricata/src/alert-prelude.h b/framework/src/suricata/src/alert-prelude.h deleted file mode 100644 index 7a30e847..00000000 --- a/framework/src/suricata/src/alert-prelude.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * - * \file - * - * \author Pierre Chifflier - * \author Yoann Vandoorselaere - */ - -#ifndef __ALERT_PRELUDE_H__ -#define __ALERT_PRELUDE_H__ - -void TmModuleAlertPreludeRegister (void); - -#endif /* __ALERT_PRELUDE_H__ */ diff --git a/framework/src/suricata/src/alert-syslog.c b/framework/src/suricata/src/alert-syslog.c deleted file mode 100644 index 13151dd9..00000000 --- a/framework/src/suricata/src/alert-syslog.c +++ /dev/null @@ -1,427 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - * Logs alerts in a line based text format in to syslog. - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "flow.h" -#include "conf.h" - -#include "threads.h" -#include "tm-threads.h" -#include "threadvars.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-reference.h" - -#include "output.h" -#include "alert-syslog.h" - -#include "util-classification-config.h" -#include "util-debug.h" -#include "util-print.h" -#include "util-proto-name.h" -#include "util-syslog.h" -#include "util-optimize.h" -#include "util-logopenfile.h" - -#ifndef OS_WIN32 - -#define DEFAULT_ALERT_SYSLOG_FACILITY_STR "local0" -#define DEFAULT_ALERT_SYSLOG_FACILITY LOG_LOCAL0 -#define DEFAULT_ALERT_SYSLOG_LEVEL LOG_ERR -#define MODULE_NAME "AlertSyslog" - -static int alert_syslog_level = DEFAULT_ALERT_SYSLOG_LEVEL; - -typedef struct AlertSyslogThread_ { - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - LogFileCtx* file_ctx; -} AlertSyslogThread; - -/** - * \brief Function to clear the memory of the output context and closes the - * syslog interface - * - * \param output_ctx pointer to the output context to be cleared - */ -static void AlertSyslogDeInitCtx(OutputCtx *output_ctx) -{ - if (output_ctx != NULL) { - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - if (logfile_ctx != NULL) { - LogFileFreeCtx(logfile_ctx); - } - SCFree(output_ctx); - } - closelog(); -} - -/** - * \brief Create a new LogFileCtx for "syslog" output style. - * - * \param conf The configuration node for this output. - * \return A OutputCtx pointer on success, NULL on failure. - */ -OutputCtx *AlertSyslogInitCtx(ConfNode *conf) -{ - const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); - if (facility_s == NULL) { - facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; - } - - LogFileCtx *logfile_ctx = LogFileNewCtx(); - if (logfile_ctx == NULL) { - SCLogDebug("AlertSyslogInitCtx: Could not create new LogFileCtx"); - return NULL; - } - - int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); - if (facility == -1) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," - " now using \"%s\" as syslog facility", facility_s, - DEFAULT_ALERT_SYSLOG_FACILITY_STR); - facility = DEFAULT_ALERT_SYSLOG_FACILITY; - } - - const char *level_s = ConfNodeLookupChildValue(conf, "level"); - if (level_s != NULL) { - int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); - if (level != -1) { - alert_syslog_level = level; - } - } - - const char *ident = ConfNodeLookupChildValue(conf, "identity"); - /* if null we just pass that to openlog, which will then - * figure it out by itself. */ - - openlog(ident, LOG_PID|LOG_NDELAY, facility); - - OutputCtx *output_ctx = SCMalloc(sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCLogDebug("AlertSyslogInitCtx: Could not create new OutputCtx"); - return NULL; - } - memset(output_ctx, 0x00, sizeof(OutputCtx)); - - output_ctx->data = logfile_ctx; - output_ctx->DeInit = AlertSyslogDeInitCtx; - - SCLogInfo("Syslog output initialized"); - - return output_ctx; -} - -/** - * \brief Function to initialize the AlertSystlogThread and sets the output - * context pointer - * - * \param tv Pointer to the threadvars - * \param initdata Pointer to the output context - * \param data pointer to pointer to point to the AlertSyslogThread - */ -static TmEcode AlertSyslogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - if(initdata == NULL) { - SCLogDebug("Error getting context for AlertSyslog. \"initdata\" " - "argument NULL"); - return TM_ECODE_FAILED; - } - - AlertSyslogThread *ast = SCMalloc(sizeof(AlertSyslogThread)); - if (unlikely(ast == NULL)) - return TM_ECODE_FAILED; - - memset(ast, 0, sizeof(AlertSyslogThread)); - - /** Use the Ouptut Context (file pointer and mutex) */ - ast->file_ctx = ((OutputCtx *)initdata)->data; - - *data = (void *)ast; - return TM_ECODE_OK; -} - -/** - * \brief Function to deinitialize the AlertSystlogThread - * - * \param tv Pointer to the threadvars - * \param data pointer to the AlertSyslogThread to be cleared - */ -static TmEcode AlertSyslogThreadDeinit(ThreadVars *t, void *data) -{ - AlertSyslogThread *ast = (AlertSyslogThread *)data; - if (ast == NULL) { - return TM_ECODE_OK; - } - - /* clear memory */ - memset(ast, 0, sizeof(AlertSyslogThread)); - - SCFree(ast); - return TM_ECODE_OK; -} - -/** - * \brief Function which is called to print the IPv4 alerts to the syslog - * - * \param tv Pointer to the threadvars - * \param p Pointer to the packet - * \param data pointer to the AlertSyslogThread - * - * \return On succes return TM_ECODE_OK - */ -static TmEcode AlertSyslogIPv4(ThreadVars *tv, const Packet *p, void *data) -{ - AlertSyslogThread *ast = (AlertSyslogThread *)data; - int i; - char *action = ""; - - if (p->alerts.cnt == 0) - return TM_ECODE_OK; - - SCMutexLock(&ast->file_ctx->fp_mutex); - - ast->file_ctx->alerts += p->alerts.cnt; - - for (i = 0; i < p->alerts.cnt; i++) { - const PacketAlert *pa = &p->alerts.alerts[i]; - if (unlikely(pa->s == NULL)) { - continue; - } - - char srcip[16], dstip[16]; - - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - - if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { - action = "[Drop] "; - } else if (pa->action & ACTION_DROP) { - action = "[wDrop] "; - } - - if (SCProtoNameValid(IPV4_GET_IPPROTO(p)) == TRUE) { - syslog(alert_syslog_level, "%s[%" PRIu32 ":%" PRIu32 ":%" - PRIu32 "] %s [Classification: %s] [Priority: %"PRIu32"]" - " {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "", action, pa->s->gid, - pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, pa->s->prio, - known_proto[IPV4_GET_IPPROTO(p)], srcip, p->sp, dstip, p->dp); - } else { - syslog(alert_syslog_level, "%s[%" PRIu32 ":%" PRIu32 ":%" - PRIu32 "] %s [Classification: %s] [Priority: %"PRIu32"]" - " {PROTO:%03" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "", - action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, - pa->s->prio, IPV4_GET_IPPROTO(p), srcip, p->sp, dstip, p->dp); - } - } - SCMutexUnlock(&ast->file_ctx->fp_mutex); - - return TM_ECODE_OK; -} - -/** - * \brief Function which is called to print the IPv6 alerts to the syslog - * - * \param tv Pointer to the threadvars - * \param p Pointer to the packet - * \param data pointer to the AlertSyslogThread - * - * \return On succes return TM_ECODE_OK - */ -static TmEcode AlertSyslogIPv6(ThreadVars *tv, const Packet *p, void *data) -{ - AlertSyslogThread *ast = (AlertSyslogThread *)data; - int i; - char *action = ""; - - if (p->alerts.cnt == 0) - return TM_ECODE_OK; - - SCMutexLock(&ast->file_ctx->fp_mutex); - - ast->file_ctx->alerts += p->alerts.cnt; - - for (i = 0; i < p->alerts.cnt; i++) { - const PacketAlert *pa = &p->alerts.alerts[i]; - if (unlikely(pa->s == NULL)) { - continue; - } - - char srcip[46], dstip[46]; - - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - - if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { - action = "[Drop] "; - } else if (pa->action & ACTION_DROP) { - action = "[wDrop] "; - } - - if (SCProtoNameValid(IPV6_GET_L4PROTO(p)) == TRUE) { - syslog(alert_syslog_level, "%s[%" PRIu32 ":%" PRIu32 ":%" - "" PRIu32 "] %s [Classification: %s] [Priority: %" - "" PRIu32 "] {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "", - action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, - pa->s->prio, known_proto[IPV6_GET_L4PROTO(p)], srcip, p->sp, - dstip, p->dp); - - } else { - syslog(alert_syslog_level, "%s[%" PRIu32 ":%" PRIu32 ":%" - "" PRIu32 "] %s [Classification: %s] [Priority: %" - "" PRIu32 "] {PROTO:%03" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "", - action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, pa->s->class_msg, - pa->s->prio, IPV6_GET_L4PROTO(p), srcip, p->sp, dstip, p->dp); - } - - } - SCMutexUnlock(&ast->file_ctx->fp_mutex); - - return TM_ECODE_OK; -} - -/** - * \brief Function which is called to print the decode alerts to the syslog - * - * \param tv Pointer to the threadvars - * \param p Pointer to the packet - * \param data pointer to the AlertSyslogThread - * \param pq pointer the to packet queue - * \param postpq pointer to the post processed packet queue - * - * \return On succes return TM_ECODE_OK - */ -static TmEcode AlertSyslogDecoderEvent(ThreadVars *tv, const Packet *p, void *data) -{ - AlertSyslogThread *ast = (AlertSyslogThread *)data; - int i; - char *action = ""; - - if (p->alerts.cnt == 0) - return TM_ECODE_OK; - - SCMutexLock(&ast->file_ctx->fp_mutex); - - ast->file_ctx->alerts += p->alerts.cnt; - char temp_buf_hdr[512]; - char temp_buf_pkt[65] = ""; - char temp_buf_tail[32]; - char alert[2048] = ""; - - for (i = 0; i < p->alerts.cnt; i++) { - const PacketAlert *pa = &p->alerts.alerts[i]; - if (unlikely(pa->s == NULL)) { - continue; - } - - if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { - action = "[Drop] "; - } else if (pa->action & ACTION_DROP) { - action = "[wDrop] "; - } - - snprintf(temp_buf_hdr, sizeof(temp_buf_hdr), "%s[%" PRIu32 ":%" PRIu32 - ":%" PRIu32 "] %s [Classification: %s] [Priority: %" PRIu32 - "] [**] [Raw pkt: ", action, pa->s->gid, pa->s->id, pa->s->rev, pa->s->msg, - pa->s->class_msg, pa->s->prio); - strlcpy(alert, temp_buf_hdr, sizeof(alert)); - - PrintRawLineHexBuf(temp_buf_pkt, sizeof(temp_buf_pkt), GET_PKT_DATA(p), GET_PKT_LEN(p) < 32 ? GET_PKT_LEN(p) : 32); - strlcat(alert, temp_buf_pkt, sizeof(alert)); - - if (p->pcap_cnt != 0) { - snprintf(temp_buf_tail, sizeof(temp_buf_tail), "] [pcap file packet: %"PRIu64"]", - p->pcap_cnt); - } else { - temp_buf_tail[0] = ']'; - temp_buf_tail[1] = '\0'; - } - strlcat(alert, temp_buf_tail, sizeof(alert)); - - syslog(alert_syslog_level, "%s", alert); - } - SCMutexUnlock(&ast->file_ctx->fp_mutex); - - return TM_ECODE_OK; -} - -/** - * \brief Function to print the total alert while closing the engine - * - * \param tv Pointer to the output threadvars - * \param data Pointer to the AlertSyslogThread data - */ -static void AlertSyslogExitPrintStats(ThreadVars *tv, void *data) -{ - AlertSyslogThread *ast = (AlertSyslogThread *)data; - if (ast == NULL) { - return; - } - - SCLogInfo("(%s) Alerts %" PRIu64 "", tv->name, ast->file_ctx->alerts); -} - -static int AlertSyslogCondition(ThreadVars *tv, const Packet *p) -{ - return (p->alerts.cnt > 0 ? TRUE : FALSE); -} - -static int AlertSyslogLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - if (PKT_IS_IPV4(p)) { - return AlertSyslogIPv4(tv, p, thread_data); - } else if (PKT_IS_IPV6(p)) { - return AlertSyslogIPv6(tv, p, thread_data); - } else if (p->events.cnt > 0) { - return AlertSyslogDecoderEvent(tv, p, thread_data); - } - - return TM_ECODE_OK; -} - -#endif /* !OS_WIN32 */ - -/** \brief Function to register the AlertSyslog module */ -void TmModuleAlertSyslogRegister (void) -{ -#ifndef OS_WIN32 - tmm_modules[TMM_ALERTSYSLOG].name = MODULE_NAME; - tmm_modules[TMM_ALERTSYSLOG].ThreadInit = AlertSyslogThreadInit; - tmm_modules[TMM_ALERTSYSLOG].Func = NULL; - tmm_modules[TMM_ALERTSYSLOG].ThreadExitPrintStats = AlertSyslogExitPrintStats; - tmm_modules[TMM_ALERTSYSLOG].ThreadDeinit = AlertSyslogThreadDeinit; - tmm_modules[TMM_ALERTSYSLOG].RegisterTests = NULL; - tmm_modules[TMM_ALERTSYSLOG].cap_flags = 0; - tmm_modules[TMM_ALERTSYSLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterPacketModule(MODULE_NAME, "syslog", - AlertSyslogInitCtx, AlertSyslogLogger, AlertSyslogCondition); - -#endif /* !OS_WIN32 */ -} diff --git a/framework/src/suricata/src/alert-syslog.h b/framework/src/suricata/src/alert-syslog.h deleted file mode 100644 index 976a1122..00000000 --- a/framework/src/suricata/src/alert-syslog.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - * alert syslog modeule header file - * - */ - -#ifndef __ALERT_SYSLOG_H__ -#define __ALERT_SYSLOG_H__ - -void TmModuleAlertSyslogRegister(void); - -#endif /* __ALERT_SYSLOG_H__ */ - diff --git a/framework/src/suricata/src/alert-unified2-alert.c b/framework/src/suricata/src/alert-unified2-alert.c deleted file mode 100644 index facc66b2..00000000 --- a/framework/src/suricata/src/alert-unified2-alert.c +++ /dev/null @@ -1,1981 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * \author Eric Leblond - * \author Ignacio Sanchez - * \author Duarte Silva - * - * Logs alerts in a format compatible to Snort's unified2 format, so it should - * be readable by Barnyard2. - */ - -#include "suricata-common.h" -#include "runmodes.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" -#include "pkt-var.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "alert-unified2-alert.h" -#include "decode-ipv4.h" - -#include "flow.h" - -#include "host.h" -#include "util-profiling.h" -#include "decode.h" - -#include "util-error.h" -#include "util-debug.h" -#include "util-time.h" -#include "util-byte.h" -#include "util-misc.h" -#include "util-logopenfile.h" - -#include "app-layer-parser.h" -#include "app-layer-htp.h" -#include "app-layer.h" -#include "app-layer-htp-xff.h" - -#include "output.h" -#include "alert-unified2-alert.h" -#include "util-privs.h" - -#include "stream.h" -#include "stream-tcp-inline.h" - -#include "util-optimize.h" - -#ifndef IPPROTO_SCTP -#define IPPROTO_SCTP 132 -#endif - -#define DEFAULT_LOG_FILENAME "unified2.alert" - -/**< Default log file limit in MB. */ -#define DEFAULT_LIMIT 32 * 1024 * 1024 - -/**< Minimum log file limit in MB. */ -#define MIN_LIMIT 1 * 1024 * 1024 - -/* Default Sensor ID value */ -static uint32_t sensor_id = 0; - -/** - * Unified2 Extra Data Header - * - */ -typedef struct Unified2ExtraDataHdr_ { - uint32_t event_type; - uint32_t event_length; -} __attribute__((__packed__)) Unified2ExtraDataHdr; - -/** - * Unified2 Extra Data (currently used only for XFF) - * - */ -typedef struct Unified2ExtraData_ { - uint32_t sensor_id; - uint32_t event_id; - uint32_t event_second; - uint32_t type; /* EventInfo */ - uint32_t data_type; /*EventDataType */ - uint32_t blob_length; /* Length of the data + sizeof(blob_length) + sizeof(data_type)*/ -} Unified2ExtraData; - -/** - * Unified2 file header struct - * - * Used for storing file header options. - */ -typedef struct Unified2AlertFileHeader_ { - uint32_t type; /**< unified2 type header */ - uint32_t length; /**< unified2 struct size length */ -} Unified2AlertFileHeader; - -/** - * Unified2 Ipv4 struct - * - * Used for storing ipv4 type values. - */ -typedef struct AlertIPv4Unified2_ { - uint32_t sensor_id; /**< sendor id */ - uint32_t event_id; /**< event id */ - uint32_t event_second; /**< event second */ - uint32_t event_microsecond; /**< event microsecond */ - uint32_t signature_id; /**< signature id */ - uint32_t generator_id; /**< generator id */ - uint32_t signature_revision; /**< signature revision */ - uint32_t classification_id; /**< classification id */ - uint32_t priority_id; /**< priority id */ - uint32_t src_ip; /**< source ip */ - uint32_t dst_ip; /**< destination ip */ - uint16_t sp; /**< source port */ - uint16_t dp; /**< destination port */ - uint8_t protocol; /**< protocol */ - uint8_t packet_action; /**< packet action */ -} AlertIPv4Unified2; - -/** - * Unified2 Ipv6 type struct - * - * Used for storing ipv6 type values. - */ -typedef struct AlertIPv6Unified2_ { - uint32_t sensor_id; /**< sendor id */ - uint32_t event_id; /**< event id */ - uint32_t event_second; /**< event second */ - uint32_t event_microsecond; /**< event microsecond */ - uint32_t signature_id; /**< signature id */ - uint32_t generator_id; /**< generator id */ - uint32_t signature_revision; /**< signature revision */ - uint32_t classification_id; /**< classification id */ - uint32_t priority_id; /**< priority id */ - struct in6_addr src_ip; /**< source ip */ - struct in6_addr dst_ip; /**< destination ip */ - uint16_t sp; /**< source port */ - uint16_t dp; /**< destination port */ - uint8_t protocol; /**< protocol */ - uint8_t packet_action; /**< packet action */ -} AlertIPv6Unified2; - -/** - * Unified2 packet type struct - * - * Used for storing packet type values. - */ -typedef struct AlertUnified2Packet_ { - uint32_t sensor_id; /**< sensor id */ - uint32_t event_id; /**< event id */ - uint32_t event_second; /**< event second */ - uint32_t packet_second; /**< packet second */ - uint32_t packet_microsecond; /**< packet microsecond */ - uint32_t linktype; /**< link type */ - uint32_t packet_length; /**< packet length */ - uint8_t packet_data[4]; /**< packet data */ -} Unified2Packet; - -/** Extracted XFF IP is v4 */ -#define UNIFIED2_ALERT_XFF_IPV4 8 -/** Extracted XFF IP is v4 */ -#define UNIFIED2_ALERT_XFF_IPV6 16 - -typedef struct Unified2AlertFileCtx_ { - LogFileCtx *file_ctx; - HttpXFFCfg *xff_cfg; - uint32_t flags; /**< flags for all alerts */ -} Unified2AlertFileCtx; - -#define UNIFIED2_ALERT_FLAGS_EMIT_PACKET (1 << 0) - -/** - * Unified2 thread vars - * - * Used for storing file options. - */ -typedef struct Unified2AlertThread_ { - Unified2AlertFileCtx *unified2alert_ctx; /**< LogFileCtx pointer */ - uint8_t *data; /**< Per function and thread data */ - /** Pointer to the Unified2AlertFileHeader contained in - * the pointer data. */ - Unified2AlertFileHeader *hdr; - /** Pointer to the Unified2Packet contained in - * the pointer data. */ - Unified2Packet *phdr; - /** Pointer to the IPv4 or IPv6 header contained in - * the pointer data. */ - void *iphdr; - int datalen; /**< Length of per function and thread data */ - int offset; /**< Offset used to now where to fill data */ - int length; /**< Length of data for current alert */ - uint8_t xff_flags; /**< XFF flags for the current alert */ - uint32_t xff_ip[4]; /**< The XFF reported IP address for the current alert */ - uint32_t event_id; -} Unified2AlertThread; - -#define UNIFIED2_PACKET_SIZE (sizeof(Unified2Packet) - 4) - -SC_ATOMIC_DECLARE(unsigned int, unified2_event_id); /**< Atomic counter, to link relative event */ - -/** prototypes */ -//TmEcode Unified2Alert (ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode Unified2AlertThreadInit(ThreadVars *, void *, void **); -TmEcode Unified2AlertThreadDeinit(ThreadVars *, void *); -static int Unified2IPv4TypeAlert(ThreadVars *, const Packet *, void *); -static int Unified2IPv6TypeAlert(ThreadVars *, const Packet *, void *); -static int Unified2PacketTypeAlert(Unified2AlertThread *, const Packet *, uint32_t, int); -void Unified2RegisterTests(void); -int Unified2AlertOpenFileCtx(LogFileCtx *, const char *); -static void Unified2AlertDeInitCtx(OutputCtx *); - -int Unified2Condition(ThreadVars *tv, const Packet *p); -int Unified2Logger(ThreadVars *tv, void *data, const Packet *p); - -#define MODULE_NAME "Unified2Alert" - -void TmModuleUnified2AlertRegister(void) -{ - tmm_modules[TMM_ALERTUNIFIED2ALERT].name = MODULE_NAME; - tmm_modules[TMM_ALERTUNIFIED2ALERT].ThreadInit = Unified2AlertThreadInit; -// tmm_modules[TMM_ALERTUNIFIED2ALERT].Func = Unified2Alert; - tmm_modules[TMM_ALERTUNIFIED2ALERT].ThreadDeinit = Unified2AlertThreadDeinit; - tmm_modules[TMM_ALERTUNIFIED2ALERT].RegisterTests = Unified2RegisterTests; - tmm_modules[TMM_ALERTUNIFIED2ALERT].cap_flags = 0; - tmm_modules[TMM_ALERTUNIFIED2ALERT].flags = TM_FLAG_LOGAPI_TM; - - //OutputRegisterModule(MODULE_NAME, "unified2-alert", Unified2AlertInitCtx); - OutputRegisterPacketModule(MODULE_NAME, "unified2-alert", - Unified2AlertInitCtx, Unified2Logger, Unified2Condition); -} - -/** - * \brief Function to close unified2 file - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param aun Unified2 thread variable. - */ - -int Unified2AlertCloseFile(ThreadVars *t, Unified2AlertThread *aun) -{ - if (aun->unified2alert_ctx->file_ctx->fp != NULL) { - fclose(aun->unified2alert_ctx->file_ctx->fp); - } - aun->unified2alert_ctx->file_ctx->size_current = 0; - - return 0; -} - -/** - * \brief Function to rotate unified2 file - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param aun Unified2 thread variable. - * \retval 0 on succces - * \retval -1 on failure - */ - -int Unified2AlertRotateFile(ThreadVars *t, Unified2AlertThread *aun) -{ - if (Unified2AlertCloseFile(t,aun) < 0) { - SCLogError(SC_ERR_UNIFIED2_ALERT_GENERIC, - "Error: Unified2AlertCloseFile failed"); - return -1; - } - if (Unified2AlertOpenFileCtx(aun->unified2alert_ctx->file_ctx,aun->unified2alert_ctx-> - file_ctx->prefix) < 0) { - SCLogError(SC_ERR_UNIFIED2_ALERT_GENERIC, - "Error: Unified2AlertOpenFileCtx, open new log file failed"); - return -1; - } - return 0; -} - -/** - * \brief Wrapper for fwrite - * - * This function is basically a wrapper for fwrite which take - * in charge a size counter. - * - * \return 1 in case of success - */ -static int Unified2Write(Unified2AlertThread *aun) -{ - int ret; - - ret = fwrite(aun->data, aun->length, 1, aun->unified2alert_ctx->file_ctx->fp); - if (ret != 1) { - SCLogError(SC_ERR_FWRITE, "Error: fwrite failed: %s", strerror(errno)); - return -1; - } - - aun->unified2alert_ctx->file_ctx->size_current += aun->length; - return 1; -} - -int Unified2Condition(ThreadVars *tv, const Packet *p) { - if (likely(p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG))) - return FALSE; - return TRUE; -} - -/** - * \brief Unified2 main entry function - * - * \retval TM_ECODE_OK all is good - * \retval TM_ECODE_FAILED serious error - */ -int Unified2Logger(ThreadVars *t, void *data, const Packet *p) -{ - int ret = 0; - Unified2AlertThread *aun = (Unified2AlertThread *)data; - aun->xff_flags = XFF_DISABLED; - - HttpXFFCfg *xff_cfg = aun->unified2alert_ctx->xff_cfg; - - /* overwrite mode can only work per u2 block, not per individual - * alert. So we'll look for an XFF record once */ - if ((xff_cfg->flags & XFF_OVERWRITE) && p->flow != NULL) { - char buffer[XFF_MAXLEN]; - int have_xff_ip = 0; - - FLOWLOCK_RDLOCK(p->flow); - if (FlowGetAppProtocol(p->flow) == ALPROTO_HTTP) { - have_xff_ip = HttpXFFGetIP(p, xff_cfg, buffer, XFF_MAXLEN); - } - FLOWLOCK_UNLOCK(p->flow); - - if (have_xff_ip) { - /** Be sure that we have a nice zeroed buffer */ - memset(aun->xff_ip, 0, 4 * sizeof(uint32_t)); - - /** We can only have override mode if packet IP version matches - * the XFF IP version, otherwise fall-back to extra data */ - if (inet_pton(AF_INET, buffer, aun->xff_ip) == 1) { - if (PKT_IS_IPV4(p)) { - aun->xff_flags = (UNIFIED2_ALERT_XFF_IPV4|XFF_OVERWRITE); - } else { - aun->xff_flags = (UNIFIED2_ALERT_XFF_IPV4|XFF_EXTRADATA); - } - } else if (inet_pton(AF_INET6, buffer, aun->xff_ip) == 1) { - if (PKT_IS_IPV6(p)) { - aun->xff_flags = (UNIFIED2_ALERT_XFF_IPV6|XFF_OVERWRITE); - } else { - aun->xff_flags = (UNIFIED2_ALERT_XFF_IPV6|XFF_EXTRADATA); - } - } - } - } - - if (PKT_IS_IPV4(p)) { - ret = Unified2IPv4TypeAlert (t, p, data); - } else if(PKT_IS_IPV6(p)) { - ret = Unified2IPv6TypeAlert (t, p, data); - } else { - /* we're only supporting IPv4 and IPv6 */ - return TM_ECODE_OK; - } - - if (ret != 0) { - return TM_ECODE_FAILED; - } - - return TM_ECODE_OK; -} - -typedef struct _FakeIPv4Hdr { - IPV4Hdr ip4h; - TCPHdr tcph; -} __attribute__((__packed__)) FakeIPv4Hdr; - -static int Unified2ForgeFakeIPv4Header(FakeIPv4Hdr *fakehdr, const Packet *p, int pkt_len, char invert) -{ - fakehdr->ip4h.ip_verhl = p->ip4h->ip_verhl; - fakehdr->ip4h.ip_proto = p->ip4h->ip_proto; - if (! invert) { - fakehdr->ip4h.s_ip_src.s_addr = p->ip4h->s_ip_src.s_addr; - fakehdr->ip4h.s_ip_dst.s_addr = p->ip4h->s_ip_dst.s_addr; - } else { - fakehdr->ip4h.s_ip_dst.s_addr = p->ip4h->s_ip_src.s_addr; - fakehdr->ip4h.s_ip_src.s_addr = p->ip4h->s_ip_dst.s_addr; - } - fakehdr->ip4h.ip_len = htons((uint16_t)pkt_len); - - if (! invert) { - fakehdr->tcph.th_sport = p->tcph->th_sport; - fakehdr->tcph.th_dport = p->tcph->th_dport; - } else { - fakehdr->tcph.th_dport = p->tcph->th_sport; - fakehdr->tcph.th_sport = p->tcph->th_dport; - } - fakehdr->tcph.th_offx2 = 0x50; /* just the TCP header, no options */ - - return 1; -} - -typedef struct _FakeIPv6Hdr { - IPV6Hdr ip6h; - TCPHdr tcph; -} __attribute__((__packed__)) FakeIPv6Hdr; - -/** - * \param payload_len length of the payload - */ -static int Unified2ForgeFakeIPv6Header(FakeIPv6Hdr *fakehdr, const Packet *p, int payload_len, char invert) -{ - fakehdr->ip6h.s_ip6_vfc = p->ip6h->s_ip6_vfc; - fakehdr->ip6h.s_ip6_nxt = IPPROTO_TCP; - fakehdr->ip6h.s_ip6_plen = htons(sizeof(TCPHdr) + payload_len); - if (!invert) { - memcpy(fakehdr->ip6h.s_ip6_addrs, p->ip6h->s_ip6_addrs, 32); - } else { - memcpy(fakehdr->ip6h.s_ip6_src, p->ip6h->s_ip6_dst, 16); - memcpy(fakehdr->ip6h.s_ip6_dst, p->ip6h->s_ip6_src, 16); - } - if (! invert) { - fakehdr->tcph.th_sport = p->tcph->th_sport; - fakehdr->tcph.th_dport = p->tcph->th_dport; - } else { - fakehdr->tcph.th_dport = p->tcph->th_sport; - fakehdr->tcph.th_sport = p->tcph->th_dport; - } - fakehdr->tcph.th_offx2 = 0x50; /* just the TCP header, no options */ - - return 1; -} - -/** - * \brief Write a faked Packet in unified2 file for each stream segment. - */ -static int Unified2PrintStreamSegmentCallback(const Packet *p, void *data, uint8_t *buf, uint32_t buflen) -{ - int ret = 1; - Unified2AlertThread *aun = (Unified2AlertThread *)data; - Unified2AlertFileHeader *hdr = (Unified2AlertFileHeader*)(aun->data); - Unified2Packet *phdr = (Unified2Packet *)(hdr + 1); - /** Prepare the pointers to extra data structures should they be required. - * If they are required we will shift the *hdr and the *phdr */ - Unified2AlertFileHeader *eu2hdr = (Unified2AlertFileHeader*)(aun->data); - Unified2ExtraDataHdr *ehdr = (Unified2ExtraDataHdr *)(eu2hdr + 1); - Unified2ExtraData *dhdr = (Unified2ExtraData *) (ehdr + 1); - uint32_t *edxff = (uint32_t *) (dhdr + 1); - - aun->length = 0; - aun->offset = 0; - - // If XFF is in extra data mode... - if (aun->xff_flags & XFF_EXTRADATA) { - memset(dhdr, 0, sizeof(Unified2ExtraData)); - - if (aun->xff_flags & UNIFIED2_ALERT_XFF_IPV4) { - eu2hdr->type = htonl (UNIFIED2_IDS_EVENT_EXTRADATA_TYPE); - eu2hdr->length = htonl(sizeof (Unified2ExtraDataHdr) - + sizeof (Unified2ExtraData) + sizeof(uint32_t)); - ehdr->event_type = htonl(UNIFIED2_EXTRADATA_TYPE_EXTRA_DATA); - ehdr->event_length = htonl(sizeof (Unified2ExtraDataHdr) - + sizeof (Unified2ExtraData) + sizeof(uint32_t)); - dhdr->sensor_id = 0; - dhdr->event_id = aun->event_id; - dhdr->event_second = htonl(p->ts.tv_sec); - dhdr->data_type = htonl(UNIFIED2_EXTRADATA_TYPE_BLOB); - dhdr->type = htonl(UNIFIED2_EXTRADATA_CLIENT_IPV4_TYPE); - dhdr->blob_length = htonl(3 * sizeof(uint32_t)); - aun->length += sizeof(Unified2AlertFileHeader) + sizeof (Unified2ExtraDataHdr) - + sizeof (Unified2ExtraData) + sizeof(uint32_t); - aun->offset += sizeof(Unified2AlertFileHeader) + sizeof (Unified2ExtraDataHdr) - + sizeof (Unified2ExtraData) + sizeof(uint32_t); - *edxff=aun->xff_ip[0]; - /** Shift the *hdr and *phdr pointers */ - hdr = (Unified2AlertFileHeader*)(edxff + 1); - phdr = (Unified2Packet *)(hdr + 1); - } - else if (aun->xff_flags & UNIFIED2_ALERT_XFF_IPV6) { - eu2hdr->type = htonl(UNIFIED2_IDS_EVENT_EXTRADATA_TYPE); - eu2hdr->length = htonl(sizeof (Unified2ExtraDataHdr) - + sizeof (Unified2ExtraData) + 4 * sizeof(uint32_t)); - ehdr->event_type = htonl(UNIFIED2_EXTRADATA_TYPE_EXTRA_DATA); - ehdr->event_length = htonl(sizeof (Unified2ExtraDataHdr) - + sizeof (Unified2ExtraData) + 4 * sizeof(uint32_t)); - dhdr->sensor_id = 0; - dhdr->event_id = aun->event_id; - dhdr->event_second = htonl(p->ts.tv_sec); - dhdr->data_type = htonl(UNIFIED2_EXTRADATA_TYPE_BLOB); - dhdr->type = htonl(UNIFIED2_EXTRADATA_CLIENT_IPV6_TYPE); - dhdr->blob_length = htonl(6 * sizeof(uint32_t)); - aun->length += sizeof(Unified2AlertFileHeader) + sizeof (Unified2ExtraDataHdr) - + sizeof (Unified2ExtraData) + 4 * sizeof(uint32_t); - aun->offset += sizeof(Unified2AlertFileHeader) + sizeof (Unified2ExtraDataHdr) - + sizeof (Unified2ExtraData) + 4 * sizeof(uint32_t); - memcpy(edxff, aun->xff_ip, 4 * sizeof(uint32_t)); - /** Shift the *hdr and *phdr pointers */ - hdr = (Unified2AlertFileHeader*)(edxff + 4); - phdr = (Unified2Packet *)(hdr + 1); - } - } - - int ethh_offset = 0; - EthernetHdr ethhdr = { {0,0,0,0,0,0}, {0,0,0,0,0,0}, htons(ETHERNET_TYPE_IPV6) }; - uint32_t hdr_length = 0; - int datalink = p->datalink; - - memset(hdr, 0, sizeof(Unified2AlertFileHeader)); - memset(phdr, 0, sizeof(Unified2Packet)); - - hdr->type = htonl(UNIFIED2_PACKET_TYPE); - aun->hdr = hdr; - - phdr->sensor_id = htonl(sensor_id); - phdr->linktype = htonl(datalink); - phdr->event_id = aun->event_id; - phdr->event_second = phdr->packet_second = htonl(p->ts.tv_sec); - phdr->packet_microsecond = htonl(p->ts.tv_usec); - aun->phdr = phdr; - - if (p->datalink != DLT_EN10MB) { - /* We have raw data here */ - phdr->linktype = htonl(DLT_RAW); - datalink = DLT_RAW; - } - - aun->length += sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE; - aun->offset += sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE; - - /* Include Packet header */ - if (PKT_IS_IPV4(p)) { - FakeIPv4Hdr fakehdr; - hdr_length = sizeof(FakeIPv4Hdr); - - if (p->datalink == DLT_EN10MB) { - /* Fake this */ - ethh_offset = 14; - datalink = DLT_EN10MB; - phdr->linktype = htonl(datalink); - aun->length += ethh_offset; - - if (aun->length > aun->datalen) { - SCLogError(SC_ERR_INVALID_VALUE, "len is too big for thread data"); - goto error; - } - ethhdr.eth_type = htons(ETHERNET_TYPE_IP); - - memcpy(aun->data + aun->offset, ðhdr, 14); - aun->offset += ethh_offset; - } - - memset(&fakehdr, 0, hdr_length); - aun->length += hdr_length; - Unified2ForgeFakeIPv4Header(&fakehdr, p, hdr_length + buflen, 0); - if (aun->length > aun->datalen) { - SCLogError(SC_ERR_INVALID_VALUE, "len is too big for thread data"); - goto error; - } - /** If XFF is in overwrite mode... */ - if (aun->xff_flags & XFF_OVERWRITE) { - BUG_ON(aun->xff_flags & UNIFIED2_ALERT_XFF_IPV6); - - if (p->flowflags & FLOW_PKT_TOCLIENT) { - fakehdr.ip4h.s_ip_dst.s_addr = aun->xff_ip[0]; - } else { - fakehdr.ip4h.s_ip_src.s_addr = aun->xff_ip[0]; - } - } - - memcpy(aun->data + aun->offset, &fakehdr, hdr_length); - aun->iphdr = (void *)(aun->data + aun->offset); - aun->offset += hdr_length; - - } else if (PKT_IS_IPV6(p)) { - FakeIPv6Hdr fakehdr; - hdr_length = sizeof(FakeIPv6Hdr); - - if (p->datalink == DLT_EN10MB) { - /* Fake this */ - ethh_offset = 14; - datalink = DLT_EN10MB; - phdr->linktype = htonl(datalink); - aun->length += ethh_offset; - if (aun->length > aun->datalen) { - SCLogError(SC_ERR_INVALID_VALUE, "len is too big for thread data"); - goto error; - } - ethhdr.eth_type = htons(ETHERNET_TYPE_IPV6); - - memcpy(aun->data + aun->offset, ðhdr, 14); - aun->offset += ethh_offset; - } - - memset(&fakehdr, 0, hdr_length); - Unified2ForgeFakeIPv6Header(&fakehdr, p, buflen, 1); - - aun->length += hdr_length; - if (aun->length > aun->datalen) { - SCLogError(SC_ERR_INVALID_VALUE, "len is too big for thread data"); - goto error; - } - /** If XFF is in overwrite mode... */ - if (aun->xff_flags & XFF_OVERWRITE) { - BUG_ON(aun->xff_flags & UNIFIED2_ALERT_XFF_IPV4); - - if (p->flowflags & FLOW_PKT_TOCLIENT) { - memcpy(fakehdr.ip6h.s_ip6_dst, aun->xff_ip, 4 * sizeof(uint32_t)); - } else { - memcpy(fakehdr.ip6h.s_ip6_src, aun->xff_ip, 4 * sizeof(uint32_t)); - } - } - - memcpy(aun->data + aun->offset, &fakehdr, hdr_length); - aun->iphdr = (void *)(aun->data + aun->offset); - aun->offset += hdr_length; - } else { - goto error; - } - - /* update unified2 headers for length */ - aun->hdr->length = htonl(UNIFIED2_PACKET_SIZE + ethh_offset + - hdr_length + buflen); - aun->phdr->packet_length = htonl(ethh_offset + hdr_length + buflen); - - /* copy stream segment payload in */ - aun->length += buflen; - - if (aun->length > aun->datalen) { - SCLogError(SC_ERR_INVALID_VALUE, "len is too big for thread" - " data: %d vs %d", aun->length, aun->datalen); - goto error; - } - - memcpy(aun->data + aun->offset, buf, buflen); - aun->offset += buflen; - - /* rebuild checksum */ - if (PKT_IS_IPV6(p)) { - FakeIPv6Hdr *fakehdr = (FakeIPv6Hdr *)aun->iphdr; - - fakehdr->tcph.th_sum = TCPV6CalculateChecksum(fakehdr->ip6h.s_ip6_addrs, - (uint16_t *)&fakehdr->tcph, buflen + sizeof(TCPHdr)); - } else { - FakeIPv4Hdr *fakehdr = (FakeIPv4Hdr *)aun->iphdr; - - fakehdr->tcph.th_sum = TCPCalculateChecksum(fakehdr->ip4h.s_ip_addrs, - (uint16_t *)&fakehdr->tcph, buflen + sizeof(TCPHdr)); - fakehdr->ip4h.ip_csum = IPV4CalculateChecksum((uint16_t *)&fakehdr->ip4h, - IPV4_GET_RAW_HLEN(&fakehdr->ip4h)); - } - - /* write out */ - ret = Unified2Write(aun); - if (ret != 1) { - goto error; - } - return 1; - -error: - aun->length = 0; - aun->offset = 0; - return -1; -} - - -/** - * \brief Function to fill unified2 packet format into the file. If the alert - * was generated based on a stream chunk we call the stream function - * to generate the record. - * - * Barnyard2 doesn't like DLT_RAW + IPv6, so if we don't have an ethernet - * header, we create a fake one. - * - * No need to lock here, since it's already locked. - * - * \param aun thread local data - * \param p Packet - * \param stream pointer to stream chunk - * \param event_id unique event id - * \param stream state/stream match, try logging stream segments - * - * \retval 0 on succces - * \retval -1 on failure - */ -static int Unified2PacketTypeAlert(Unified2AlertThread *aun, const Packet *p, uint32_t event_id, int stream) -{ - int ret = 0; - - if (!(aun->unified2alert_ctx->flags & UNIFIED2_ALERT_FLAGS_EMIT_PACKET)) - return 1; - - /* try stream logging first */ - if (stream) { - SCLogDebug("logging the state"); - uint8_t flag; - - if (p->flowflags & FLOW_PKT_TOSERVER) { - flag = FLOW_PKT_TOCLIENT; - } else { - flag = FLOW_PKT_TOSERVER; - } - - /* make event id available to callback */ - aun->event_id = event_id; - - /* run callback for all segments in the stream */ - ret = StreamSegmentForEach(p, flag, Unified2PrintStreamSegmentCallback, (void *)aun); - } - - /* or no segment could been logged or no segment have been logged */ - if (ret == 0) { - SCLogDebug("no stream, no state: falling back to payload logging"); - - Unified2AlertFileHeader *hdr = (Unified2AlertFileHeader*)(aun->data); - Unified2Packet *phdr = (Unified2Packet *)(hdr + 1); - int len = (sizeof(Unified2AlertFileHeader) + UNIFIED2_PACKET_SIZE); - int datalink = p->datalink; -#ifdef HAVE_OLD_BARNYARD2 - int ethh_offset = 0; - EthernetHdr ethhdr = { {0,0,0,0,0,0}, {0,0,0,0,0,0}, htons(ETHERNET_TYPE_IPV6) }; -#endif - memset(hdr, 0, sizeof(Unified2AlertFileHeader)); - memset(phdr, 0, sizeof(Unified2Packet)); - - hdr->type = htonl(UNIFIED2_PACKET_TYPE); - aun->hdr = hdr; - - phdr->sensor_id = htonl(sensor_id); - phdr->linktype = htonl(datalink); - phdr->event_id = event_id; - phdr->event_second = phdr->packet_second = htonl(p->ts.tv_sec); - phdr->packet_microsecond = htonl(p->ts.tv_usec); - aun->phdr = phdr; - - /* we need to reset offset and length which could - * have been modified by the segment logging */ - aun->offset = len; - len += GET_PKT_LEN(p); - aun->length = len; - - /* Unified 2 packet header is the one of the packet. */ - phdr->linktype = htonl(p->datalink); -#ifdef HAVE_OLD_BARNYARD2 - /* Fake datalink to avoid bug with old barnyard2 */ - if (PKT_IS_IPV6(p) && (!p->ethh)) { - /* Fake this */ - ethh_offset = 14; - datalink = DLT_EN10MB; - phdr->linktype = htonl(datalink); - aun->length += ethh_offset; - if (aun->length > aun->datalen) { - SCLogError(SC_ERR_INVALID_VALUE, "len is too big for thread data: %d vs %d", - len, aun->datalen - aun->offset); - return -1; - } - ethhdr.eth_type = htons(ETHERNET_TYPE_IPV6); - - memcpy(aun->data + aun->offset, ðhdr, 14); - aun->offset += ethh_offset; - } -#endif - - if (len > aun->datalen) { - SCLogError(SC_ERR_INVALID_VALUE, "len is too big for thread data: %d vs %d", - len, aun->datalen - aun->offset); - return -1; - } - hdr->length = htonl(UNIFIED2_PACKET_SIZE + GET_PKT_LEN(p)); - phdr->packet_length = htonl(GET_PKT_LEN(p)); - memcpy(aun->data + aun->offset, GET_PKT_DATA(p), GET_PKT_LEN(p)); - - ret = Unified2Write(aun); - } - - if (ret < 1) { - return -1; - } - - return 1; -} - -/** - * \brief Function to fill unified2 ipv6 ids type format into the file. - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param p Packet struct used to decide for ipv4 or ipv6 - * \param data Unified2 thread data. - * - * \retval 0 on succces - * \retval -1 on failure - */ -static int Unified2IPv6TypeAlert(ThreadVars *t, const Packet *p, void *data) -{ - Unified2AlertThread *aun = (Unified2AlertThread *)data; - Unified2AlertFileHeader hdr; - AlertIPv6Unified2 *phdr; - AlertIPv6Unified2 gphdr; - const PacketAlert *pa; - int offset, length; - int ret; - unsigned int event_id; - - if (likely(p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG))) - return 0; - - phdr = (AlertIPv6Unified2 *)(aun->data + - sizeof(Unified2AlertFileHeader)); - - length = (sizeof(Unified2AlertFileHeader) + sizeof(AlertIPv6Unified2)); - offset = length; - - memset(aun->data, 0, aun->datalen); - - hdr.type = htonl(UNIFIED2_IDS_EVENT_IPV6_TYPE); - hdr.length = htonl(sizeof(AlertIPv6Unified2)); - - /* fill the gphdr structure with the data of the packet */ - memset(&gphdr, 0, sizeof(gphdr)); - /* FIXME this need to be copied for each alert */ - gphdr.sensor_id = htonl(sensor_id); - gphdr.event_second = htonl(p->ts.tv_sec); - gphdr.event_microsecond = htonl(p->ts.tv_usec); - gphdr.src_ip = *(struct in6_addr*)GET_IPV6_SRC_ADDR(p); - gphdr.dst_ip = *(struct in6_addr*)GET_IPV6_DST_ADDR(p); - /** If XFF is in overwrite mode... */ - if (aun->xff_flags & XFF_OVERWRITE) { - BUG_ON(aun->xff_flags & UNIFIED2_ALERT_XFF_IPV4); - - if (p->flowflags & FLOW_PKT_TOCLIENT) { - gphdr.dst_ip = *(struct in6_addr*)aun->xff_ip; - } else { - gphdr.src_ip = *(struct in6_addr*)aun->xff_ip; - } - } - gphdr.protocol = p->proto; - - if(PACKET_TEST_ACTION(p, ACTION_DROP)) - gphdr.packet_action = UNIFIED2_BLOCKED_FLAG; - else - gphdr.packet_action = 0; - - switch(gphdr.protocol) { - case IPPROTO_ICMPV6: - if(p->icmpv6h) { - gphdr.sp = htons(p->icmpv6h->type); - gphdr.dp = htons(p->icmpv6h->code); - } else { - gphdr.sp = 0; - gphdr.dp = 0; - } - break; - case IPPROTO_ICMP: - if(p->icmpv4h) { - gphdr.sp = htons(p->icmpv4h->type); - gphdr.dp = htons(p->icmpv4h->code); - } else { - gphdr.sp = 0; - gphdr.dp = 0; - } - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - gphdr.sp = htons(p->sp); - gphdr.dp = htons(p->dp); - break; - default: - gphdr.sp = 0; - gphdr.dp = 0; - break; - } - - uint16_t i = 0; - for (; i < p->alerts.cnt + 1; i++) { - if (i < p->alerts.cnt) - pa = &p->alerts.alerts[i]; - else { - if (!(p->flags & PKT_HAS_TAG)) - break; - pa = PacketAlertGetTag(); - } - - if (unlikely(pa->s == NULL)) - continue; - - HttpXFFCfg *xff_cfg = aun->unified2alert_ctx->xff_cfg; - - if ((xff_cfg->flags & XFF_EXTRADATA) && p->flow != NULL) { - char buffer[XFF_MAXLEN]; - int have_xff_ip = 0; - - FLOWLOCK_RDLOCK(p->flow); - if (FlowGetAppProtocol(p->flow) == ALPROTO_HTTP) { - if (pa->flags & PACKET_ALERT_FLAG_TX) { - have_xff_ip = HttpXFFGetIPFromTx(p, pa->tx_id, xff_cfg, buffer, XFF_MAXLEN); - } else { - have_xff_ip = HttpXFFGetIP(p, xff_cfg, buffer, XFF_MAXLEN); - } - } - FLOWLOCK_UNLOCK(p->flow); - - if (have_xff_ip) { - memset(aun->xff_ip, 0, 4 * sizeof(uint32_t)); - - if (inet_pton(AF_INET, buffer, aun->xff_ip) == 1) { - aun->xff_flags = (UNIFIED2_ALERT_XFF_IPV4|XFF_EXTRADATA); - } else if (inet_pton(AF_INET6, buffer, aun->xff_ip) == 1) { - aun->xff_flags = (UNIFIED2_ALERT_XFF_IPV6|XFF_EXTRADATA); - } - } - } - - /* reset length and offset */ - aun->offset = offset; - aun->length = length; - memset(aun->data + aun->offset, 0, aun->datalen - aun->offset); - - /* copy the part common to all alerts */ - memcpy(aun->data, &hdr, sizeof(hdr)); - memcpy(phdr, &gphdr, sizeof(gphdr)); - - /* fill the header structure with the data of the alert */ - event_id = htonl(SC_ATOMIC_ADD(unified2_event_id, 1)); - phdr->event_id = event_id; - phdr->generator_id = htonl(pa->s->gid); - phdr->signature_id = htonl(pa->s->id); - phdr->signature_revision = htonl(pa->s->rev); - phdr->classification_id = htonl(pa->s->class); - phdr->priority_id = htonl(pa->s->prio); - - SCMutexLock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - if ((aun->unified2alert_ctx->file_ctx->size_current + length) > - aun->unified2alert_ctx->file_ctx->size_limit) { - if (Unified2AlertRotateFile(t,aun) < 0) { - aun->unified2alert_ctx->file_ctx->alerts += i; - SCMutexUnlock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - return -1; - } - } - - if (Unified2Write(aun) != 1) { - aun->unified2alert_ctx->file_ctx->alerts += i; - SCMutexUnlock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - return -1; - } - - memset(aun->data, 0, aun->length); - aun->length = 0; - aun->offset = 0; - - /* stream flag based on state match, but only for TCP */ - int stream = (gphdr.protocol == IPPROTO_TCP) ? - (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0) : 0; - ret = Unified2PacketTypeAlert(aun, p, phdr->event_id, stream); - if (ret != 1) { - SCLogError(SC_ERR_FWRITE, "Error: fwrite failed: %s", strerror(errno)); - aun->unified2alert_ctx->file_ctx->alerts += i; - SCMutexUnlock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - return -1; - } - fflush(aun->unified2alert_ctx->file_ctx->fp); - aun->unified2alert_ctx->file_ctx->alerts++; - SCMutexUnlock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - } - - return 0; -} - -/** - * \brief Function to fill unified2 ipv4 ids type format into the file. - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param p Packet struct used to decide for ipv4 or ipv6 - * \param data Unified2 thread data. - * \retval 0 on succces - * \retval -1 on failure - */ - -static int Unified2IPv4TypeAlert (ThreadVars *tv, const Packet *p, void *data) -{ - Unified2AlertThread *aun = (Unified2AlertThread *)data; - Unified2AlertFileHeader hdr; - AlertIPv4Unified2 *phdr; - AlertIPv4Unified2 gphdr; - const PacketAlert *pa; - int offset, length; - int ret; - unsigned int event_id; - - if (likely(p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG))) - return 0; - - phdr = (AlertIPv4Unified2 *)(aun->data + - sizeof(Unified2AlertFileHeader)); - - length = (sizeof(Unified2AlertFileHeader) + sizeof(AlertIPv4Unified2)); - offset = length; - - memset(aun->data, 0, aun->datalen); - - hdr.type = htonl(UNIFIED2_IDS_EVENT_TYPE); - hdr.length = htonl(sizeof(AlertIPv4Unified2)); - - /* fill the gphdr structure with the data of the packet */ - memset(&gphdr, 0, sizeof(gphdr)); - gphdr.sensor_id = htonl(sensor_id); - gphdr.event_id = 0; - gphdr.event_second = htonl(p->ts.tv_sec); - gphdr.event_microsecond = htonl(p->ts.tv_usec); - gphdr.src_ip = p->ip4h->s_ip_src.s_addr; - gphdr.dst_ip = p->ip4h->s_ip_dst.s_addr; - /** If XFF is in overwrite mode... */ - if (aun->xff_flags & XFF_OVERWRITE) { - BUG_ON(aun->xff_flags & UNIFIED2_ALERT_XFF_IPV6); - - if (p->flowflags & FLOW_PKT_TOCLIENT) { - gphdr.dst_ip = aun->xff_ip[0]; - } else { - gphdr.src_ip = aun->xff_ip[0]; - } - } - gphdr.protocol = IPV4_GET_RAW_IPPROTO(p->ip4h); - - if(PACKET_TEST_ACTION(p, ACTION_DROP)) - gphdr.packet_action = UNIFIED2_BLOCKED_FLAG; - else - gphdr.packet_action = 0; - - /* TODO inverse order if needed, this should be done on a - * alert basis */ - switch(gphdr.protocol) { - case IPPROTO_ICMP: - if(p->icmpv4h) { - gphdr.sp = htons(p->icmpv4h->type); - gphdr.dp = htons(p->icmpv4h->code); - } - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - gphdr.sp = htons(p->sp); - gphdr.dp = htons(p->dp); - break; - default: - gphdr.sp = 0; - gphdr.dp = 0; - break; - } - - uint16_t i = 0; - for (; i < p->alerts.cnt + 1; i++) { - if (i < p->alerts.cnt) - pa = &p->alerts.alerts[i]; - else { - if (!(p->flags & PKT_HAS_TAG)) - break; - pa = PacketAlertGetTag(); - } - - if (unlikely(pa->s == NULL)) - continue; - - HttpXFFCfg *xff_cfg = aun->unified2alert_ctx->xff_cfg; - - if ((xff_cfg->flags & XFF_EXTRADATA) && p->flow != NULL) { - char buffer[XFF_MAXLEN]; - int have_xff_ip = 0; - - FLOWLOCK_RDLOCK(p->flow); - if (FlowGetAppProtocol(p->flow) == ALPROTO_HTTP) { - if (pa->flags & PACKET_ALERT_FLAG_TX) { - have_xff_ip = HttpXFFGetIPFromTx(p, pa->tx_id, xff_cfg, buffer, XFF_MAXLEN); - } else { - have_xff_ip = HttpXFFGetIP(p, xff_cfg, buffer, XFF_MAXLEN); - } - } - FLOWLOCK_UNLOCK(p->flow); - - if (have_xff_ip) { - memset(aun->xff_ip, 0, 4 * sizeof(uint32_t)); - - if (inet_pton(AF_INET, buffer, aun->xff_ip) == 1) { - aun->xff_flags = (UNIFIED2_ALERT_XFF_IPV4|XFF_EXTRADATA); - } else if (inet_pton(AF_INET6, buffer, aun->xff_ip) == 1) { - aun->xff_flags = (UNIFIED2_ALERT_XFF_IPV6|XFF_EXTRADATA); - } - } - } - - /* reset length and offset */ - aun->offset = offset; - aun->length = length; - memset(aun->data + aun->offset, 0, aun->datalen - aun->offset); - - /* copy the part common to all alerts */ - memcpy(aun->data, &hdr, sizeof(hdr)); - memcpy(phdr, &gphdr, sizeof(gphdr)); - - /* fill the hdr structure with the alert data */ - event_id = htonl(SC_ATOMIC_ADD(unified2_event_id, 1)); - phdr->event_id = event_id; - phdr->generator_id = htonl(pa->s->gid); - phdr->signature_id = htonl(pa->s->id); - phdr->signature_revision = htonl(pa->s->rev); - phdr->classification_id = htonl(pa->s->class); - phdr->priority_id = htonl(pa->s->prio); - - /* check and enforce the filesize limit */ - SCMutexLock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - - if ((aun->unified2alert_ctx->file_ctx->size_current + length) > - aun->unified2alert_ctx->file_ctx->size_limit) { - if (Unified2AlertRotateFile(tv,aun) < 0) { - aun->unified2alert_ctx->file_ctx->alerts += i; - SCMutexUnlock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - return -1; - } - } - - if (Unified2Write(aun) != 1) { - aun->unified2alert_ctx->file_ctx->alerts += i; - SCMutexUnlock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - return -1; - } - - memset(aun->data, 0, aun->length); - aun->length = 0; - aun->offset = 0; - - /* Write the alert (it doesn't lock inside, since we - * already locked here for rotation check) - */ - int stream = (gphdr.protocol == IPPROTO_TCP) ? - (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH) ? 1 : 0) : 0; - ret = Unified2PacketTypeAlert(aun, p, event_id, stream); - if (ret != 1) { - aun->unified2alert_ctx->file_ctx->alerts += i; - SCMutexUnlock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - return -1; - } - - fflush(aun->unified2alert_ctx->file_ctx->fp); - aun->unified2alert_ctx->file_ctx->alerts++; - SCMutexUnlock(&aun->unified2alert_ctx->file_ctx->fp_mutex); - } - - return 0; -} - -/** - * \brief Thread init function. - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param initdata Unified2 thread initial data. - * \param data Unified2 thread data. - * \retval TM_ECODE_OK on succces - * \retval TM_ECODE_FAILED on failure - */ - -TmEcode Unified2AlertThreadInit(ThreadVars *t, void *initdata, void **data) -{ - Unified2AlertThread *aun = SCMalloc(sizeof(Unified2AlertThread)); - if (unlikely(aun == NULL)) - return TM_ECODE_FAILED; - memset(aun, 0, sizeof(Unified2AlertThread)); - if(initdata == NULL) - { - SCLogDebug("Error getting context for Unified2Alert. \"initdata\" argument NULL"); - SCFree(aun); - return TM_ECODE_FAILED; - } - /** Use the Ouptut Context (file pointer and mutex) */ - aun->unified2alert_ctx = ((OutputCtx *)initdata)->data; - - aun->data = SCMalloc(sizeof(Unified2AlertFileHeader) + sizeof(Unified2Packet) + - IPV4_MAXPACKET_LEN + sizeof(Unified2ExtraDataHdr) + sizeof (Unified2ExtraData)); - if (aun->data == NULL) { - SCFree(aun); - return TM_ECODE_FAILED; - } - aun->datalen = sizeof(Unified2AlertFileHeader) + sizeof(Unified2Packet) + - IPV4_MAXPACKET_LEN + sizeof(Unified2ExtraDataHdr) + sizeof(Unified2ExtraData); - - *data = (void *)aun; - - return TM_ECODE_OK; -} - -/** - * \brief Thread deinit function. - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param data Unified2 thread data. - * \retval TM_ECODE_OK on succces - * \retval TM_ECODE_FAILED on failure - */ - -TmEcode Unified2AlertThreadDeinit(ThreadVars *t, void *data) -{ - Unified2AlertThread *aun = (Unified2AlertThread *)data; - if (aun == NULL) { - goto error; - } - - if (!(aun->unified2alert_ctx->file_ctx->flags & LOGFILE_ALERTS_PRINTED)) { - SCLogInfo("Alert unified2 module wrote %"PRIu64" alerts", - aun->unified2alert_ctx->file_ctx->alerts); - - /* Do not print it for each thread */ - aun->unified2alert_ctx->file_ctx->flags |= LOGFILE_ALERTS_PRINTED; - - } - - if (aun->data != NULL) { - SCFree(aun->data); - aun->data = NULL; - } - aun->datalen = 0; - /* clear memory */ - memset(aun, 0, sizeof(Unified2AlertThread)); - SCFree(aun); - return TM_ECODE_OK; - -error: - return TM_ECODE_FAILED; -} - -/** \brief Create a new LogFileCtx from the provided ConfNode. - * \param conf The configuration node for this output. - * \return NULL if failure, LogFileCtx* to the file_ctx if succesful - * */ -OutputCtx *Unified2AlertInitCtx(ConfNode *conf) -{ - int ret = 0; - LogFileCtx* file_ctx = NULL; - OutputCtx* output_ctx = NULL; - HttpXFFCfg *xff_cfg = NULL; - - file_ctx = LogFileNewCtx(); - if (file_ctx == NULL) { - SCLogError(SC_ERR_UNIFIED2_ALERT_GENERIC, "Couldn't create new file_ctx"); - goto error; - } - - const char *filename = NULL; - if (conf != NULL) { /* To faciliate unit tests. */ - filename = ConfNodeLookupChildValue(conf, "filename"); - } - if (filename == NULL) - filename = DEFAULT_LOG_FILENAME; - file_ctx->prefix = SCStrdup(filename); - if (unlikely(file_ctx->prefix == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate file prefix"); - exit(EXIT_FAILURE); - } - - const char *s_limit = NULL; - file_ctx->size_limit = DEFAULT_LIMIT; - if (conf != NULL) { - s_limit = ConfNodeLookupChildValue(conf, "limit"); - if (s_limit != NULL) { - if (ParseSizeStringU64(s_limit, &file_ctx->size_limit) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Failed to initialize unified2 output, invalid limit: %s", - s_limit); - exit(EXIT_FAILURE); - } - if (file_ctx->size_limit < 4096) { - SCLogInfo("unified2-alert \"limit\" value of %"PRIu64" assumed to be pre-1.2 " - "style: setting limit to %"PRIu64"mb", file_ctx->size_limit, file_ctx->size_limit); - uint64_t size = file_ctx->size_limit * 1024 * 1024; - file_ctx->size_limit = size; - } else if (file_ctx->size_limit < MIN_LIMIT) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Failed to initialize unified2 output, limit less than " - "allowed minimum: %d.", MIN_LIMIT); - exit(EXIT_FAILURE); - } - } - } - - if (conf != NULL) { - const char *sensor_id_s = NULL; - sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id"); - if (sensor_id_s != NULL) { - if (ByteExtractStringUint32(&sensor_id, 10, 0, sensor_id_s) == -1) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize unified2 output, invalid sensor-id: %s", sensor_id_s); - exit(EXIT_FAILURE); - } - } - } - - uint32_t flags = UNIFIED2_ALERT_FLAGS_EMIT_PACKET; - if (conf != NULL) { - const char *payload = NULL; - payload = ConfNodeLookupChildValue(conf, "payload"); - if (payload) { - if (ConfValIsFalse(payload)) { - flags &= ~UNIFIED2_ALERT_FLAGS_EMIT_PACKET; - } else if (!ConfValIsTrue(payload)) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize unified2 output, invalid payload: %s", payload); - exit(EXIT_FAILURE); - } - } - } - - ret = Unified2AlertOpenFileCtx(file_ctx, filename); - if (ret < 0) - goto error; - - output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) - goto error; - - xff_cfg = SCMalloc(sizeof(HttpXFFCfg)); - if (unlikely(xff_cfg == NULL)) { - goto error; - } - memset(xff_cfg, 0x00, sizeof(HttpXFFCfg)); - - if (conf != NULL) { - HttpXFFGetCfg(conf, xff_cfg); - } - - Unified2AlertFileCtx *unified2alert_ctx = SCMalloc(sizeof(Unified2AlertFileCtx)); - if (unlikely(unified2alert_ctx == NULL)) { - goto error; - } - memset(unified2alert_ctx, 0x00, sizeof(Unified2AlertFileCtx)); - - unified2alert_ctx->file_ctx = file_ctx; - unified2alert_ctx->xff_cfg = xff_cfg; - unified2alert_ctx->flags = flags; - output_ctx->data = unified2alert_ctx; - output_ctx->DeInit = Unified2AlertDeInitCtx; - - SCLogInfo("Unified2-alert initialized: filename %s, limit %"PRIu64" MB", - filename, file_ctx->size_limit / (1024*1024)); - - SC_ATOMIC_INIT(unified2_event_id); - - return output_ctx; - -error: - if (xff_cfg != NULL) { - SCFree(xff_cfg); - } - if (output_ctx != NULL) { - SCFree(output_ctx); - } - - return NULL; -} - -static void Unified2AlertDeInitCtx(OutputCtx *output_ctx) -{ - if (output_ctx != NULL) { - Unified2AlertFileCtx *unified2alert_ctx = (Unified2AlertFileCtx *) output_ctx->data; - if (unified2alert_ctx != NULL) { - LogFileCtx *logfile_ctx = unified2alert_ctx->file_ctx; - if (logfile_ctx != NULL) { - LogFileFreeCtx(logfile_ctx); - } - HttpXFFCfg *xff_cfg = unified2alert_ctx->xff_cfg; - if (xff_cfg != NULL) { - SCFree(xff_cfg); - } - SCFree(unified2alert_ctx); - } - SCFree(output_ctx); - } -} - -/** \brief Read the config set the file pointer, open the file - * \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx() - * \param prefix Prefix of the log file. - * \return -1 if failure, 0 if succesful - * */ -int Unified2AlertOpenFileCtx(LogFileCtx *file_ctx, const char *prefix) -{ - int ret = 0; - char *filename = NULL; - if (file_ctx->filename != NULL) - filename = file_ctx->filename; - else { - filename = SCMalloc(PATH_MAX); /* XXX some sane default? */ - if (unlikely(filename == NULL)) - return -1; - file_ctx->filename = filename; - - memset(filename, 0x00, PATH_MAX); - } - - /** get the time so we can have a filename with seconds since epoch */ - struct timeval ts; - memset(&ts, 0x00, sizeof(struct timeval)); - - extern int run_mode; - if (run_mode == RUNMODE_UNITTEST) - TimeGet(&ts); - else - gettimeofday(&ts, NULL); - - /* create the filename to use */ - char *log_dir; - log_dir = ConfigGetLogDirectory(); - - snprintf(filename, PATH_MAX, "%s/%s.%" PRIu32, log_dir, prefix, (uint32_t)ts.tv_sec); - - file_ctx->fp = fopen(filename, "ab"); - if (file_ctx->fp == NULL) { - SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", filename, - strerror(errno)); - ret = -1; - } - - return ret; -} - - -#ifdef UNITTESTS - -/** - * \test Test the ethernet+ipv4+tcp unified2 test - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int Unified2Test01(void) -{ - ThreadVars tv; - DecodeThreadVars dtv; - PacketQueue pq; - void *data = NULL; - OutputCtx *oc; - LogFileCtx *lf; - Unified2AlertFileCtx *uaf = NULL; - Signature s; - - uint8_t raw_ipv4_tcp[] = { - 0x00, 0x14, 0xbf, 0xe8, 0xcb, 0x26, 0xaa, 0x00, - 0x04, 0x00, 0x0a, 0x04, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3c, 0x8c, 0x55, 0x40, 0x00, 0x40, 0x06, - 0x69, 0x86, 0xc0, 0xa8, 0x0a, 0x68, 0x4a, 0x7d, - 0x2f, 0x53, 0xc2, 0x40, 0x00, 0x50, 0x1f, 0x00, - 0xa4, 0xd4, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, - 0x16, 0xd0, 0x3d, 0x4e, 0x00, 0x00, 0x02, 0x04, - 0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a, 0x00, 0x1c, - 0x28, 0x81, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, - 0x03, 0x06}; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int ret; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&pq, 0, sizeof(PacketQueue)); - memset(&s, 0, sizeof(Signature)); - - p->alerts.cnt++; - p->alerts.alerts[p->alerts.cnt-1].s = &s; - p->alerts.alerts[p->alerts.cnt-1].s->id = 1; - p->alerts.alerts[p->alerts.cnt-1].s->gid = 1; - p->alerts.alerts[p->alerts.cnt-1].s->rev = 1; - SET_PKT_LEN(p, sizeof(raw_ipv4_tcp)); - - FlowInitConfig(FLOW_QUIET); - - DecodeEthernet(&tv, &dtv, p, raw_ipv4_tcp, sizeof(raw_ipv4_tcp), &pq); - - - oc = Unified2AlertInitCtx(NULL); - if (oc == NULL) { - goto end; - } - uaf = oc->data; - if (uaf == NULL) - return 0; - lf = uaf->file_ctx; - if(lf == NULL) { - goto end; - } - ret = Unified2AlertThreadInit(&tv, oc, &data); - if(ret == TM_ECODE_FAILED) { - goto end; - } - ret = Unified2Logger(&tv, data, p); - if(ret == TM_ECODE_FAILED) { - goto end; - } - ret = Unified2AlertThreadDeinit(&tv, data); - if(ret == -1) { - goto end; - } - - Unified2AlertDeInitCtx(oc); - - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 1; - -end: - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 0; -} - -/** - * \test Test the ethernet+ipv6+tcp unified2 test - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int Unified2Test02(void) -{ - ThreadVars tv; - DecodeThreadVars dtv; - PacketQueue pq; - void *data = NULL; - OutputCtx *oc; - LogFileCtx *lf; - Unified2AlertFileCtx *uaf = NULL; - Signature s; - - uint8_t raw_ipv6_tcp[] = { - 0x00, 0x11, 0x25, 0x82, 0x95, 0xb5, 0x00, 0xd0, - 0x09, 0xe3, 0xe8, 0xde, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x28, 0x06, 0x40, 0x20, 0x01, - 0x06, 0xf8, 0x10, 0x2d, 0x00, 0x00, 0x02, 0xd0, - 0x09, 0xff, 0xfe, 0xe3, 0xe8, 0xde, 0x20, 0x01, - 0x06, 0xf8, 0x09, 0x00, 0x07, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe7, 0x41, - 0x00, 0x50, 0xab, 0xdc, 0xd6, 0x60, 0x00, 0x00, - 0x00, 0x00, 0xa0, 0x02, 0x16, 0x80, 0x41, 0xa2, - 0x00, 0x00, 0x02, 0x04, 0x05, 0xa0, 0x04, 0x02, - 0x08, 0x0a, 0x00, 0x0a, 0x22, 0xa8, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x03, 0x03, 0x05 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int ret; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&pq, 0, sizeof(PacketQueue)); - memset(&s, 0, sizeof(Signature)); - - p->alerts.cnt++; - p->alerts.alerts[p->alerts.cnt-1].s = &s; - p->alerts.alerts[p->alerts.cnt-1].s->id = 1; - p->alerts.alerts[p->alerts.cnt-1].s->gid = 1; - p->alerts.alerts[p->alerts.cnt-1].s->rev = 1; - SET_PKT_LEN(p, sizeof(raw_ipv6_tcp)); - - FlowInitConfig(FLOW_QUIET); - - DecodeEthernet(&tv, &dtv, p, raw_ipv6_tcp, sizeof(raw_ipv6_tcp), &pq); - - oc = Unified2AlertInitCtx(NULL); - if (oc == NULL) { - goto end; - } - uaf = oc->data; - if (uaf == NULL) - return 0; - lf = uaf->file_ctx; - if(lf == NULL) { - goto end; - } - ret = Unified2AlertThreadInit(&tv, oc, &data); - if(ret == -1) { - goto end; - } - ret = Unified2Logger(&tv, data, p); - if(ret == TM_ECODE_FAILED) { - goto end; - } - ret = Unified2AlertThreadDeinit(&tv, data); - if(ret == -1) { - goto end; - } - - Unified2AlertDeInitCtx(oc); - - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 1; - -end: - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 0; -} - - -/** - * \test Test the GRE unified2 test - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int Unified2Test03(void) -{ - ThreadVars tv; - DecodeThreadVars dtv; - PacketQueue pq; - void *data = NULL; - OutputCtx *oc; - LogFileCtx *lf; - Unified2AlertFileCtx *uaf = NULL; - Signature s; - - uint8_t raw_gre[] = { - 0x00, 0x0e, 0x50, 0x06, 0x42, 0x96, 0xaa, 0x00, - 0x04, 0x00, 0x0a, 0x04, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x74, 0x35, 0xa2, 0x40, 0x00, 0x40, 0x2f, - 0xef, 0xcb, 0x0a, 0x00, 0x00, 0x64, 0x0a, 0x00, - 0x00, 0x8a, 0x30, 0x01, 0x88, 0x0b, 0x00, 0x54, - 0x00, 0x00, 0x00, 0x18, 0x29, 0x5f, 0xff, 0x03, - 0x00, 0x21, 0x45, 0x00, 0x00, 0x50, 0xf4, 0x05, - 0x40, 0x00, 0x3f, 0x06, 0x20, 0xb8, 0x50, 0x7e, - 0x2b, 0x2d, 0xd4, 0xcc, 0xd6, 0x72, 0x0a, 0x92, - 0x1a, 0x0b, 0xc9, 0xaf, 0x24, 0x02, 0x8c, 0xdd, - 0x45, 0xf6, 0x80, 0x18, 0x21, 0xfc, 0x10, 0x7c, - 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x08, 0x19, - 0x1a, 0xda, 0x84, 0xd6, 0xda, 0x3e, 0x50, 0x49, - 0x4e, 0x47, 0x20, 0x73, 0x74, 0x65, 0x72, 0x6c, - 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x72, 0x65, 0x65, - 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x65, 0x74, - 0x0d, 0x0a}; - Packet *p = PacketGetFromAlloc(); - Packet *pkt; - if (unlikely(p == NULL)) - return 0; - int ret; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&pq, 0, sizeof(PacketQueue)); - memset(&s, 0, sizeof(Signature)); - - p->alerts.cnt++; - p->alerts.alerts[p->alerts.cnt-1].s = &s; - p->alerts.alerts[p->alerts.cnt-1].s->id = 1; - p->alerts.alerts[p->alerts.cnt-1].s->gid = 1; - p->alerts.alerts[p->alerts.cnt-1].s->rev = 1; - SET_PKT_LEN(p, sizeof(raw_gre)); - - FlowInitConfig(FLOW_QUIET); - - DecodeEthernet(&tv, &dtv, p, raw_gre, sizeof(raw_gre), &pq); - - oc = Unified2AlertInitCtx(NULL); - if (oc == NULL) { - goto end; - } - uaf = oc->data; - if (uaf == NULL) - return 0; - lf = uaf->file_ctx; - if(lf == NULL) { - goto end; - } - ret = Unified2AlertThreadInit(&tv, oc, &data); - if(ret == -1) { - goto end; - } - ret = Unified2Logger(&tv, data, p); - if(ret == TM_ECODE_FAILED) { - goto end; - } - ret = Unified2AlertThreadDeinit(&tv, data); - if(ret == -1) { - goto end; - } - - Unified2AlertDeInitCtx(oc); - - pkt = PacketDequeue(&pq); - while (pkt != NULL) { - PACKET_RECYCLE(pkt); - SCFree(pkt); - pkt = PacketDequeue(&pq); - } - - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 1; - -end: - pkt = PacketDequeue(&pq); - while (pkt != NULL) { - PACKET_RECYCLE(pkt); - SCFree(pkt); - pkt = PacketDequeue(&pq); - } - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 0; -} - -/** - * \test Test the PPP unified2 test - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int Unified2Test04(void) -{ - ThreadVars tv; - DecodeThreadVars dtv; - PacketQueue pq; - void *data = NULL; - OutputCtx *oc; - LogFileCtx *lf; - Unified2AlertFileCtx *uaf = NULL; - Signature s; - - uint8_t raw_ppp[] = { - 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c, - 0x4d, 0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, - 0xbf, 0x01, 0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, - 0xea, 0x37, 0x00, 0x17, 0x6d, 0x0b, 0xba, 0xc3, - 0x00, 0x00, 0x00, 0x00, 0x60, 0x02, 0x10, 0x20, - 0xdd, 0xe1, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4}; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int ret; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&pq, 0, sizeof(PacketQueue)); - memset(&s, 0, sizeof(Signature)); - - p->alerts.cnt++; - p->alerts.alerts[p->alerts.cnt-1].s = &s; - p->alerts.alerts[p->alerts.cnt-1].s->id = 1; - p->alerts.alerts[p->alerts.cnt-1].s->gid = 1; - p->alerts.alerts[p->alerts.cnt-1].s->rev = 1; - SET_PKT_LEN(p, sizeof(raw_ppp)); - - FlowInitConfig(FLOW_QUIET); - - DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), &pq); - - oc = Unified2AlertInitCtx(NULL); - if (oc == NULL) { - goto end; - } - uaf = oc->data; - if (uaf == NULL) - return 0; - lf = uaf->file_ctx; - if(lf == NULL) { - goto end; - } - ret = Unified2AlertThreadInit(&tv, oc, &data); - if(ret == -1) { - goto end; - } - ret = Unified2Logger(&tv, data, p); - if(ret == TM_ECODE_FAILED) { - goto end; - } - ret = Unified2AlertThreadDeinit(&tv, data); - if(ret == -1) { - goto end; - } - - Unified2AlertDeInitCtx(oc); - - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 1; - -end: - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 0; -} - -/** - * \test Test the ethernet+ipv4+tcp droped unified2 test - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int Unified2Test05(void) -{ - ThreadVars tv; - DecodeThreadVars dtv; - PacketQueue pq; - void *data = NULL; - OutputCtx *oc; - LogFileCtx *lf; - Unified2AlertFileCtx *uaf = NULL; - Signature s; - - uint8_t raw_ipv4_tcp[] = { - 0x00, 0x14, 0xbf, 0xe8, 0xcb, 0x26, 0xaa, 0x00, - 0x04, 0x00, 0x0a, 0x04, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3c, 0x8c, 0x55, 0x40, 0x00, 0x40, 0x06, - 0x69, 0x86, 0xc0, 0xa8, 0x0a, 0x68, 0x4a, 0x7d, - 0x2f, 0x53, 0xc2, 0x40, 0x00, 0x50, 0x1f, 0x00, - 0xa4, 0xd4, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, - 0x16, 0xd0, 0x3d, 0x4e, 0x00, 0x00, 0x02, 0x04, - 0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a, 0x00, 0x1c, - 0x28, 0x81, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, - 0x03, 0x06}; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int ret; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&pq, 0, sizeof(PacketQueue)); - memset(&s, 0, sizeof(Signature)); - - p->alerts.cnt++; - p->alerts.alerts[p->alerts.cnt-1].s = &s; - p->alerts.alerts[p->alerts.cnt-1].s->id = 1; - p->alerts.alerts[p->alerts.cnt-1].s->gid = 1; - p->alerts.alerts[p->alerts.cnt-1].s->rev = 1; - SET_PKT_LEN(p, sizeof(raw_ipv4_tcp)); - - FlowInitConfig(FLOW_QUIET); - - DecodeEthernet(&tv, &dtv, p, raw_ipv4_tcp, sizeof(raw_ipv4_tcp), &pq); - - p->action = ACTION_DROP; - - oc = Unified2AlertInitCtx(NULL); - if (oc == NULL) { - goto end; - } - uaf = oc->data; - if (uaf == NULL) - return 0; - lf = uaf->file_ctx; - if(lf == NULL) { - goto end; - } - ret = Unified2AlertThreadInit(&tv, oc, &data); - if(ret == -1) { - goto end; - } - ret = Unified2Logger(&tv, data, p); - if(ret == TM_ECODE_FAILED) { - goto end; - } - ret = Unified2AlertThreadDeinit(&tv, data); - if(ret == TM_ECODE_FAILED) { - goto end; - } - - Unified2AlertDeInitCtx(oc); - - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 1; - -end: - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - return 0; -} - -/** - * \test Test the Rotate process - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int Unified2TestRotate01(void) -{ - int ret = 0; - int r = 0; - ThreadVars tv; - OutputCtx *oc; - LogFileCtx *lf; - Unified2AlertFileCtx *uaf = NULL; - void *data = NULL; - char *filename = NULL; - - oc = Unified2AlertInitCtx(NULL); - if (oc == NULL) - return 0; - uaf = oc->data; - if (uaf == NULL) - return 0; - lf = uaf->file_ctx; - if (lf == NULL) - return 0; - filename = SCStrdup(lf->filename); - if (unlikely(filename == NULL)) - return 0; - - memset(&tv, 0, sizeof(ThreadVars)); - - ret = Unified2AlertThreadInit(&tv, oc, &data); - if (ret == TM_ECODE_FAILED) { - LogFileFreeCtx(lf); - if (filename != NULL) - SCFree(filename); - return 0; - } - - TimeSetIncrementTime(1); - - ret = Unified2AlertRotateFile(&tv, data); - if (ret == -1) - goto error; - - if (strcmp(filename, lf->filename) == 0) { - SCLogError(SC_ERR_UNIFIED2_ALERT_GENERIC, - "filename \"%s\" == \"%s\": ", filename, lf->filename); - goto error; - } - - r = 1; - -error: - ret = Unified2AlertThreadDeinit(&tv, data); - if(ret == TM_ECODE_FAILED) { - printf("Unified2AlertThreadDeinit error"); - } - if (oc != NULL) - Unified2AlertDeInitCtx(oc); - if (filename != NULL) - SCFree(filename); - return r; -} -#endif - -/** - * \brief this function registers unit tests for Unified2 - */ -void Unified2RegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("Unified2Test01 -- Ipv4 test", Unified2Test01, 1); - UtRegisterTest("Unified2Test02 -- Ipv6 test", Unified2Test02, 1); - UtRegisterTest("Unified2Test03 -- GRE test", Unified2Test03, 1); - UtRegisterTest("Unified2Test04 -- PPP test", Unified2Test04, 1); - UtRegisterTest("Unified2Test05 -- Inline test", Unified2Test05, 1); - UtRegisterTest("Unified2TestRotate01 -- Rotate File", Unified2TestRotate01, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/alert-unified2-alert.h b/framework/src/suricata/src/alert-unified2-alert.h deleted file mode 100644 index d4d3b2ec..00000000 --- a/framework/src/suricata/src/alert-unified2-alert.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * \author Breno Silva - */ - -#ifndef __ALERT_UNIFIED2_ALERT_H__ -#define __ALERT_UNIFIED2_ALERT_H__ - -/** Unified2 Option packet action */ -#define UNIFIED2_PACKET_FLAG 1 -#define UNIFIED2_BLOCKED_FLAG 0x20 - -/** Unified2 Header Types */ -#define UNIFIED2_EVENT_TYPE 1 -#define UNIFIED2_PACKET_TYPE 2 -#define UNIFIED2_IDS_EVENT_TYPE 7 -#define UNIFIED2_EVENT_EXTENDED_TYPE 66 -#define UNIFIED2_PERFORMANCE_TYPE 67 -#define UNIFIED2_PORTSCAN_TYPE 68 -#define UNIFIED2_IDS_EVENT_IPV6_TYPE 72 -#define UNIFIED2_IDS_EVENT_MPLS_TYPE 99 -#define UNIFIED2_IDS_EVENT_IPV6_MPLS_TYPE 100 -#define UNIFIED2_IDS_EVENT_EXTRADATA_TYPE 110 -#define UNIFIED2_EXTRADATA_CLIENT_IPV4_TYPE 1 -#define UNIFIED2_EXTRADATA_CLIENT_IPV6_TYPE 1 -#define UNIFIED2_EXTRADATA_TYPE_BLOB 1 -#define UNIFIED2_EXTRADATA_TYPE_EXTRA_DATA 4 - -void TmModuleUnified2AlertRegister(void); -OutputCtx *Unified2AlertInitCtx(ConfNode *); - -#endif /* __ALERT_UNIFIED2_ALERT_H__ */ - diff --git a/framework/src/suricata/src/app-layer-dcerpc-common.h b/framework/src/suricata/src/app-layer-dcerpc-common.h deleted file mode 100644 index cdda5630..00000000 --- a/framework/src/suricata/src/app-layer-dcerpc-common.h +++ /dev/null @@ -1,246 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Kirby Kuehl - */ - -#ifndef __APP_LAYER_DCERPC_COMMON_H__ -#define __APP_LAYER_DCERPC_COMMON_H__ - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "flow.h" -#include "queue.h" -#include "util-byte.h" - -void RegisterDCERPCParsers(void); -void DCERPCParserTests(void); -void DCERPCParserRegisterTests(void); - -// http://www.opengroup.org/onlinepubs/9629399/chap12.htm#tagcjh_17_06 -#define REQUEST 0 -#define PING 1 -#define RESPONSE 2 -#define FAULT 3 -#define WORKING 4 -#define NOCALL 5 -#define REJECT 6 -#define ACK 7 -#define CL_CANCEL 8 -#define FACK 9 -#define CANCEL_ACK 10 -#define BIND 11 -#define BIND_ACK 12 -#define BIND_NAK 13 -#define ALTER_CONTEXT 14 -#define ALTER_CONTEXT_RESP 15 -#define SHUTDOWN 17 -#define CO_CANCEL 18 -#define ORPHANED 19 -#if 0 -typedef struct { - uint8_t rpc_vers; /* 4 RPC protocol major version (4 LSB only)*/ - uint8_t ptype; /* Packet type (5 LSB only) */ - uint8_t flags1; /* Packet flags */ - uint8_t flags2; /* Packet flags */ - uint8_t drep[3]; /* Data representation format label */ - uint8_t serial_hi; /* High byte of serial number */ - uuid_t object; /* Object identifier */ - uuid_t if_id; /* Interface identifier */ - uuid_t act_id; /* Activity identifier */ - unsigned long server_boot;/* Server boot time */ - unsigned long if_vers; /* Interface version */ - unsigned long seqnum; /* Sequence number */ - unsigned short opnum; /* Operation number */ - unsigned short ihint; /* Interface hint */ - unsigned short ahint; /* Activity hint */ - unsigned short len; /* Length of packet body */ - unsigned short fragnum; /* Fragment number */ - unsigned small auth_proto; /* Authentication protocol identifier*/ - unsigned small serial_lo; /* Low byte of serial number */ -} dc_rpc_cl_pkt_hdr_t; -#endif - -#define RESERVED_01 0x01 -#define LASTFRAG 0x02 -#define FRAG 0x04 -#define NOFACK 0x08 -#define MAYBE 0x10 -#define IDEMPOTENT 0x20 -#define BROADCAST 0x40 -#define RESERVED_80 0x80 - -#define CANCEL_PENDING 0x02 -#define RESERVED_04 0x04 -#define RESERVED_10 0x10 -#define RESERVED_20 0x20 -#define RESERVED_40 0x40 -#define RESERVED_80 0x80 - -typedef struct DCERPCHdr_ { - uint8_t rpc_vers; /**< 00:01 RPC version should be 5 */ - uint8_t rpc_vers_minor; /**< 01:01 minor version */ - uint8_t type; /**< 02:01 packet type */ - uint8_t pfc_flags; /**< 03:01 flags (see PFC_... ) */ - uint8_t packed_drep[4]; /**< 04:04 NDR data representation format label */ - uint16_t frag_length; /**< 08:02 total length of fragment */ - uint16_t auth_length; /**< 10:02 length of auth_value */ - uint32_t call_id; /**< 12:04 call identifier */ -} DCERPCHdr; - -#define DCERPC_HDR_LEN 16 - -typedef struct DCERPCHdrUdp_ { - uint8_t rpc_vers; /**< 4 RPC protocol major version (4 LSB only)*/ - uint8_t type; /**< Packet type (5 LSB only) */ - uint8_t flags1; /**< Packet flags */ - uint8_t flags2; /**< Packet flags */ - uint8_t drep[3]; /**< Data representation format label */ - uint8_t serial_hi; /**< High byte of serial number */ - uint8_t objectuuid[16]; - uint8_t interfaceuuid[16]; - uint8_t activityuuid[16]; - uint32_t server_boot; /**< Server boot time */ - uint32_t if_vers; /**< Interface version */ - uint32_t seqnum; /**< Sequence number */ - uint16_t opnum; /**< Operation number */ - uint16_t ihint; /**< Interface hint */ - uint16_t ahint; /**< Activity hint */ - uint16_t fraglen; /**< Length of packet body */ - uint16_t fragnum; /**< Fragment number */ - uint8_t auth_proto; /**< Authentication protocol identifier*/ - uint8_t serial_lo; /**< Low byte of serial number */ -} DCERPCHdrUdp; - -#define DCERPC_UDP_HDR_LEN 80 - -#define DCERPC_UUID_ENTRY_FLAG_FF 0x0001 /**< FIRST flag set on the packet - that contained this uuid entry */ - -typedef struct DCERPCUuidEntry_ { - uint16_t ctxid; - uint16_t internal_id; - uint16_t result; - uint8_t uuid[16]; - uint16_t version; - uint16_t versionminor; - uint16_t flags; /**< DCERPC_UUID_ENTRY_FLAG_* flags */ - TAILQ_ENTRY(DCERPCUuidEntry_) next; -} DCERPCUuidEntry; - -typedef struct DCERPCBindBindAck_ { - uint8_t numctxitems; - uint8_t numctxitemsleft; - uint8_t ctxbytesprocessed; - uint16_t ctxid; - uint8_t uuid[16]; - uint16_t version; - uint16_t versionminor; - DCERPCUuidEntry *uuid_entry; - TAILQ_HEAD(, DCERPCUuidEntry_) uuid_list; - /* the interface uuids that the server has accepted */ - TAILQ_HEAD(, DCERPCUuidEntry_) accepted_uuid_list; - uint16_t uuid_internal_id; - uint16_t secondaryaddrlen; - uint16_t secondaryaddrlenleft; - uint16_t result; -} DCERPCBindBindAck; - -typedef struct DCERPCRequest_ { - uint16_t ctxid; - uint16_t opnum; - /* holds the stub data for the request */ - uint8_t *stub_data_buffer; - /* length of the above buffer */ - uint32_t stub_data_buffer_len; - /* used by the dce preproc to indicate fresh entry in the stub data buffer */ - uint8_t stub_data_fresh; - uint8_t first_request_seen; -} DCERPCRequest; - -typedef struct DCERPCResponse_ { - /* holds the stub data for the response */ - uint8_t *stub_data_buffer; - /* length of the above buffer */ - uint32_t stub_data_buffer_len; - /* used by the dce preproc to indicate fresh entry in the stub data buffer */ - uint8_t stub_data_fresh; -} DCERPCResponse; - -typedef struct DCERPC_ { - DCERPCHdr dcerpchdr; - DCERPCBindBindAck dcerpcbindbindack; - DCERPCRequest dcerpcrequest; - DCERPCResponse dcerpcresponse; - uint16_t bytesprocessed; - uint8_t pad; - uint16_t padleft; - uint16_t transaction_id; - /* indicates if the dcerpc pdu state is in the middle of processing - * a fragmented pdu */ - uint8_t pdu_fragged; -} DCERPC; - -typedef struct DCERPCUDP_ { - DCERPCHdrUdp dcerpchdrudp; - DCERPCBindBindAck dcerpcbindbindack; - DCERPCRequest dcerpcrequest; - DCERPCResponse dcerpcresponse; - uint16_t bytesprocessed; - uint16_t fraglenleft; - uint8_t *frag_data; - DCERPCUuidEntry *uuid_entry; - TAILQ_HEAD(, uuid_entry) uuid_list; -} DCERPCUDP; - -/** First fragment */ -#define PFC_FIRST_FRAG 0x01 -/** Last fragment */ -#define PFC_LAST_FRAG 0x02 -/** Cancel was pending at sender */ -#define PFC_PENDING_CANCEL 0x04 -#define PFC_RESERVED_1 0x08 -/** supports concurrent multiplexing of a single connection. */ -#define PFC_CONC_MPX 0x10 -/** only meaningful on `fault' packet; if true, guaranteed - * call did not execute. */ -#define PFC_DID_NOT_EXECUTE 0x20 -/** `maybe' call semantics requested */ -#define PFC_MAYBE 0x40 -/** if true, a non-nil object UUID was specified in the handle, and - * is present in the optional object field. If false, the object field - * is omitted. */ -#define PFC_OBJECT_UUID 0x80 - -#define REASON_NOT_SPECIFIED 0 -#define TEMPORARY_CONGESTION 1 -#define LOCAL_LIMIT_EXCEEDED 2 -#define CALLED_PADDR_UNKNOWN 3 /* not used */ -#define PROTOCOL_VERSION_NOT_SUPPORTED 4 -#define DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */ -#define USER_DATA_NOT_READABLE 6 /* not used */ -#define NO_PSAP_AVAILABLE 7 /* not used */ - -int32_t DCERPCParser(DCERPC *, uint8_t *, uint32_t); -void hexdump(const void *buf, size_t len); -void printUUID(char *type, DCERPCUuidEntry *uuid); - -#endif /* __APP_LAYER_DCERPC_COMMON_H__ */ - diff --git a/framework/src/suricata/src/app-layer-dcerpc-udp.c b/framework/src/suricata/src/app-layer-dcerpc-udp.c deleted file mode 100644 index 58d714d0..00000000 --- a/framework/src/suricata/src/app-layer-dcerpc-udp.c +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * Copyright (c) 2009, 2010 Open Information Security Foundation - * - * \author Kirby Kuehl - * - * \todo Updated by AS: Inspect the possibilities of sending junk start at the - * start of udp session to avoid alproto detection. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "debug.h" -#include "decode.h" - -#include "flow-util.h" - -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-debug.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer.h" - -#include "util-spm.h" -#include "util-unittest.h" - -#include "app-layer-dcerpc-udp.h" - -enum { - DCERPC_FIELD_NONE = 0, - DCERPC_PARSE_DCERPC_HEADER, - DCERPC_PARSE_DCERPC_BIND, - DCERPC_PARSE_DCERPC_BIND_ACK, - DCERPC_PARSE_DCERPC_REQUEST, - /* must be last */ - DCERPC_FIELD_MAX, -}; - -/** \internal - * \retval stub_len or 0 in case of error */ -static uint32_t FragmentDataParser(Flow *f, void *dcerpcudp_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len) -{ - SCEnter(); - DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpcudp_state; - uint8_t **stub_data_buffer = NULL; - uint32_t *stub_data_buffer_len = NULL; - uint8_t *stub_data_fresh = NULL; - uint16_t stub_len = 0; - void *ptmp; - - /* request PDU. Retrieve the request stub buffer */ - if (sstate->dcerpc.dcerpchdrudp.type == REQUEST) { - stub_data_buffer = &sstate->dcerpc.dcerpcrequest.stub_data_buffer; - stub_data_buffer_len = &sstate->dcerpc.dcerpcrequest.stub_data_buffer_len; - stub_data_fresh = &sstate->dcerpc.dcerpcrequest.stub_data_fresh; - - /* response PDU. Retrieve the response stub buffer */ - } else { - stub_data_buffer = &sstate->dcerpc.dcerpcresponse.stub_data_buffer; - stub_data_buffer_len = &sstate->dcerpc.dcerpcresponse.stub_data_buffer_len; - stub_data_fresh = &sstate->dcerpc.dcerpcresponse.stub_data_fresh; - } - - stub_len = (sstate->dcerpc.fraglenleft < input_len) ? sstate->dcerpc.fraglenleft : input_len; - - if (stub_len == 0) { - SCReturnUInt(0); - } - /* if the frag is the the first frag irrespective of it being a part of - * a multi frag PDU or not, it indicates the previous PDU's stub would - * have been buffered and processed and we can use the buffer to hold - * frags from a fresh request/response */ - if (sstate->dcerpc.dcerpchdrudp.flags1 & PFC_FIRST_FRAG) { - *stub_data_buffer_len = 0; - } - - ptmp = SCRealloc(*stub_data_buffer, *stub_data_buffer_len + stub_len); - if (ptmp == NULL) { - SCFree(*stub_data_buffer); - *stub_data_buffer = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - SCReturnUInt(0); - } - - *stub_data_buffer = ptmp; - memcpy(*stub_data_buffer + *stub_data_buffer_len, input, stub_len); - - *stub_data_fresh = 1; - /* length of the buffered stub */ - *stub_data_buffer_len += stub_len; - - sstate->dcerpc.fraglenleft -= stub_len; - sstate->dcerpc.bytesprocessed += stub_len; - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - int i = 0; - for (i = 0; i < stub_len; i++) { - SCLogDebug("0x%02x ", input[i]); - } - } -#endif - - SCReturnUInt((uint32_t)stub_len); -} - -/** - * \brief DCERPCParseHeader parses the 16 byte DCERPC header - * A fast path for normal decoding is used when there is enough bytes - * present to parse the entire header. A slow path is used to parse - * fragmented packets. - */ -static int DCERPCUDPParseHeader(Flow *f, void *dcerpcudp_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t *p = input; - DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpcudp_state; - if (input_len) { - switch (sstate->bytesprocessed) { - case 0: - // fallthrough - /* above statement to prevent coverity FPs from the switch - * fall through */ - if (input_len >= DCERPC_UDP_HDR_LEN) { - sstate->dcerpc.dcerpchdrudp.rpc_vers = *p; - if (sstate->dcerpc.dcerpchdrudp.rpc_vers != 4) { - SCLogDebug("DCERPC UDP Header did not validate"); - SCReturnInt(-1); - } - sstate->dcerpc.dcerpchdrudp.type = *(p + 1); - sstate->dcerpc.dcerpchdrudp.flags1 = *(p + 2); - sstate->dcerpc.dcerpchdrudp.flags2 = *(p + 3); - sstate->dcerpc.dcerpchdrudp.drep[0] = *(p + 4); - sstate->dcerpc.dcerpchdrudp.drep[1] = *(p + 5); - sstate->dcerpc.dcerpchdrudp.drep[2] = *(p + 6); - sstate->dcerpc.dcerpchdrudp.serial_hi = *(p + 7); - sstate->dcerpc.dcerpchdrudp.objectuuid[3] = *(p + 8); - sstate->dcerpc.dcerpchdrudp.objectuuid[2] = *(p + 9); - sstate->dcerpc.dcerpchdrudp.objectuuid[1] = *(p + 10); - sstate->dcerpc.dcerpchdrudp.objectuuid[0] = *(p + 11); - sstate->dcerpc.dcerpchdrudp.objectuuid[5] = *(p + 12); - sstate->dcerpc.dcerpchdrudp.objectuuid[4] = *(p + 13); - sstate->dcerpc.dcerpchdrudp.objectuuid[7] = *(p + 14); - sstate->dcerpc.dcerpchdrudp.objectuuid[6] = *(p + 15); - sstate->dcerpc.dcerpchdrudp.objectuuid[8] = *(p + 16); - sstate->dcerpc.dcerpchdrudp.objectuuid[9] = *(p + 17); - sstate->dcerpc.dcerpchdrudp.objectuuid[10] = *(p + 18); - sstate->dcerpc.dcerpchdrudp.objectuuid[11] = *(p + 19); - sstate->dcerpc.dcerpchdrudp.objectuuid[12] = *(p + 20); - sstate->dcerpc.dcerpchdrudp.objectuuid[13] = *(p + 21); - sstate->dcerpc.dcerpchdrudp.objectuuid[14] = *(p + 22); - sstate->dcerpc.dcerpchdrudp.objectuuid[15] = *(p + 23); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[3] = *(p + 24); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[2] = *(p + 25); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[1] = *(p + 26); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[0] = *(p + 27); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[5] = *(p + 28); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[4] = *(p + 29); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[7] = *(p + 30); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[6] = *(p + 31); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[8] = *(p + 32); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[9] = *(p + 33); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[10] = *(p + 34); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[11] = *(p + 35); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[12] = *(p + 36); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[13] = *(p + 37); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[14] = *(p + 38); - sstate->dcerpc.dcerpchdrudp.interfaceuuid[15] = *(p + 39); - sstate->dcerpc.dcerpchdrudp.activityuuid[3] = *(p + 40); - sstate->dcerpc.dcerpchdrudp.activityuuid[2] = *(p + 41); - sstate->dcerpc.dcerpchdrudp.activityuuid[1] = *(p + 42); - sstate->dcerpc.dcerpchdrudp.activityuuid[0] = *(p + 43); - sstate->dcerpc.dcerpchdrudp.activityuuid[5] = *(p + 44); - sstate->dcerpc.dcerpchdrudp.activityuuid[4] = *(p + 45); - sstate->dcerpc.dcerpchdrudp.activityuuid[7] = *(p + 46); - sstate->dcerpc.dcerpchdrudp.activityuuid[6] = *(p + 47); - sstate->dcerpc.dcerpchdrudp.activityuuid[8] = *(p + 48); - sstate->dcerpc.dcerpchdrudp.activityuuid[9] = *(p + 49); - sstate->dcerpc.dcerpchdrudp.activityuuid[10] = *(p + 50); - sstate->dcerpc.dcerpchdrudp.activityuuid[11] = *(p + 51); - sstate->dcerpc.dcerpchdrudp.activityuuid[12] = *(p + 52); - sstate->dcerpc.dcerpchdrudp.activityuuid[13] = *(p + 53); - sstate->dcerpc.dcerpchdrudp.activityuuid[14] = *(p + 54); - sstate->dcerpc.dcerpchdrudp.activityuuid[15] = *(p + 55); - if (sstate->dcerpc.dcerpchdrudp.drep[0] == 0x10) { - sstate->dcerpc.dcerpchdrudp.server_boot = *(p + 56); - sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 57) << 8; - sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 58) << 16; - sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 59) << 24; - sstate->dcerpc.dcerpchdrudp.if_vers = *(p + 60); - sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 61) << 8; - sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 62) << 16; - sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 63) << 24; - sstate->dcerpc.dcerpchdrudp.seqnum = *(p + 64); - sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 65) << 8; - sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 66) << 16; - sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 67) << 24; - sstate->dcerpc.dcerpchdrudp.opnum = *(p + 68); - sstate->dcerpc.dcerpchdrudp.opnum |= *(p + 69) << 8; - sstate->dcerpc.dcerpchdrudp.ihint = *(p + 70); - sstate->dcerpc.dcerpchdrudp.ihint |= *(p + 71) << 8; - sstate->dcerpc.dcerpchdrudp.ahint = *(p + 72); - sstate->dcerpc.dcerpchdrudp.ahint |= *(p + 73) << 8; - sstate->dcerpc.dcerpchdrudp.fraglen = *(p + 74); - sstate->dcerpc.dcerpchdrudp.fraglen |= *(p + 75) << 8; - sstate->dcerpc.dcerpchdrudp.fragnum = *(p + 76); - sstate->dcerpc.dcerpchdrudp.fragnum |= *(p + 77) << 8; - } else { - sstate->dcerpc.dcerpchdrudp.server_boot = *(p + 56) << 24; - sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 57) << 16; - sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 58) << 8; - sstate->dcerpc.dcerpchdrudp.server_boot |= *(p + 59); - sstate->dcerpc.dcerpchdrudp.if_vers = *(p + 60) << 24; - sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 61) << 16; - sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 62) << 8; - sstate->dcerpc.dcerpchdrudp.if_vers |= *(p + 63); - sstate->dcerpc.dcerpchdrudp.seqnum = *(p + 64) << 24; - sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 65) << 16; - sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 66) << 8; - sstate->dcerpc.dcerpchdrudp.seqnum |= *(p + 67); - sstate->dcerpc.dcerpchdrudp.opnum = *(p + 68) << 24; - sstate->dcerpc.dcerpchdrudp.opnum |= *(p + 69) << 16; - sstate->dcerpc.dcerpchdrudp.ihint = *(p + 70) << 8; - sstate->dcerpc.dcerpchdrudp.ihint |= *(p + 71); - sstate->dcerpc.dcerpchdrudp.ahint = *(p + 72) << 8; - sstate->dcerpc.dcerpchdrudp.ahint |= *(p + 73); - sstate->dcerpc.dcerpchdrudp.fraglen = *(p + 74) << 8; - sstate->dcerpc.dcerpchdrudp.fraglen |= *(p + 75); - sstate->dcerpc.dcerpchdrudp.fragnum = *(p + 76) << 8; - sstate->dcerpc.dcerpchdrudp.fragnum |= *(p + 77); - } - sstate->fraglenleft = sstate->dcerpc.dcerpchdrudp.fraglen; - sstate->dcerpc.dcerpchdrudp.auth_proto = *(p + 78); - sstate->dcerpc.dcerpchdrudp.serial_lo = *(p + 79); - sstate->bytesprocessed = DCERPC_UDP_HDR_LEN; - sstate->uuid_entry = (DCERPCUuidEntry *) SCCalloc(1, - sizeof(DCERPCUuidEntry)); - if (sstate->uuid_entry == NULL) { - SCReturnUInt(-1); - } else { - memcpy(sstate->uuid_entry->uuid, - sstate->dcerpc.dcerpchdrudp.activityuuid, - sizeof(sstate->dcerpc.dcerpchdrudp.activityuuid)); - TAILQ_INSERT_HEAD(&sstate->uuid_list, sstate->uuid_entry, - next); -#ifdef UNITTESTS - if (RunmodeIsUnittests()) { - printUUID("DCERPC UDP", sstate->uuid_entry); - - } -#endif - } - SCReturnUInt(80); - break; - } else { - sstate->dcerpc.dcerpchdrudp.rpc_vers = *(p++); - if (sstate->dcerpc.dcerpchdrudp.rpc_vers != 4) { - SCLogDebug("DCERPC UDP Header did not validate"); - SCReturnInt(-1); - } - if (!(--input_len)) - break; - /* We fall through to the next case if we still have input. - * Same applies for other cases as well */ - } - /* fall through */ - case 1: - sstate->dcerpc.dcerpchdrudp.type = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 2: - sstate->dcerpc.dcerpchdrudp.flags1 = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 3: - sstate->dcerpc.dcerpchdrudp.flags2 = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 4: - sstate->dcerpc.dcerpchdrudp.drep[0] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 5: - sstate->dcerpc.dcerpchdrudp.drep[1] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 6: - sstate->dcerpc.dcerpchdrudp.drep[2] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 7: - sstate->dcerpc.dcerpchdrudp.serial_hi = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 8: - sstate->dcerpc.dcerpchdrudp.objectuuid[3] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 9: - sstate->dcerpc.dcerpchdrudp.objectuuid[2] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 10: - sstate->dcerpc.dcerpchdrudp.objectuuid[1] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 11: - sstate->dcerpc.dcerpchdrudp.objectuuid[0] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 12: - sstate->dcerpc.dcerpchdrudp.objectuuid[5] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 13: - sstate->dcerpc.dcerpchdrudp.objectuuid[4] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 14: - sstate->dcerpc.dcerpchdrudp.objectuuid[7] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 15: - sstate->dcerpc.dcerpchdrudp.objectuuid[6] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 16: - sstate->dcerpc.dcerpchdrudp.objectuuid[8] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 17: - sstate->dcerpc.dcerpchdrudp.objectuuid[9] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 18: - sstate->dcerpc.dcerpchdrudp.objectuuid[10] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 19: - sstate->dcerpc.dcerpchdrudp.objectuuid[11] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 20: - sstate->dcerpc.dcerpchdrudp.objectuuid[12] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 21: - sstate->dcerpc.dcerpchdrudp.objectuuid[13] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 22: - sstate->dcerpc.dcerpchdrudp.objectuuid[14] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 23: - sstate->dcerpc.dcerpchdrudp.objectuuid[15] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 24: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[3] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 25: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[2] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 26: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[1] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 27: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[0] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 28: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[5] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 29: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[4] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 30: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[7] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 31: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[6] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 32: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[8] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 33: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[9] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 34: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[10] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 35: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[11] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 36: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[12] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 37: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[13] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 38: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[14] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 39: - sstate->dcerpc.dcerpchdrudp.interfaceuuid[15] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 40: - sstate->dcerpc.dcerpchdrudp.activityuuid[3] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 41: - sstate->dcerpc.dcerpchdrudp.activityuuid[2] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 42: - sstate->dcerpc.dcerpchdrudp.activityuuid[1] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 43: - sstate->dcerpc.dcerpchdrudp.activityuuid[0] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 44: - sstate->dcerpc.dcerpchdrudp.activityuuid[5] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 45: - sstate->dcerpc.dcerpchdrudp.activityuuid[4] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 46: - sstate->dcerpc.dcerpchdrudp.activityuuid[7] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 47: - sstate->dcerpc.dcerpchdrudp.activityuuid[6] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 48: - sstate->dcerpc.dcerpchdrudp.activityuuid[8] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 49: - sstate->dcerpc.dcerpchdrudp.activityuuid[9] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 50: - sstate->dcerpc.dcerpchdrudp.activityuuid[10] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 51: - sstate->dcerpc.dcerpchdrudp.activityuuid[11] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 52: - sstate->dcerpc.dcerpchdrudp.activityuuid[12] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 53: - sstate->dcerpc.dcerpchdrudp.activityuuid[13] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 54: - sstate->dcerpc.dcerpchdrudp.activityuuid[14] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 55: - sstate->dcerpc.dcerpchdrudp.activityuuid[15] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 56: - sstate->dcerpc.dcerpchdrudp.server_boot = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 57: - sstate->dcerpc.dcerpchdrudp.server_boot |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 58: - sstate->dcerpc.dcerpchdrudp.server_boot |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 59: - sstate->dcerpc.dcerpchdrudp.server_boot |= *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 60: - sstate->dcerpc.dcerpchdrudp.if_vers = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 61: - sstate->dcerpc.dcerpchdrudp.if_vers |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 62: - sstate->dcerpc.dcerpchdrudp.if_vers |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 63: - sstate->dcerpc.dcerpchdrudp.if_vers |= *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 64: - sstate->dcerpc.dcerpchdrudp.seqnum = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 65: - sstate->dcerpc.dcerpchdrudp.seqnum |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 66: - sstate->dcerpc.dcerpchdrudp.seqnum |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 67: - sstate->dcerpc.dcerpchdrudp.seqnum |= *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 68: - sstate->dcerpc.dcerpchdrudp.opnum = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 69: - sstate->dcerpc.dcerpchdrudp.opnum |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 70: - sstate->dcerpc.dcerpchdrudp.ihint = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 71: - sstate->dcerpc.dcerpchdrudp.ihint |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 72: - sstate->dcerpc.dcerpchdrudp.ahint = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 73: - sstate->dcerpc.dcerpchdrudp.ahint |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 74: - sstate->dcerpc.dcerpchdrudp.fraglen = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 75: - sstate->dcerpc.dcerpchdrudp.fraglen |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 76: - sstate->dcerpc.dcerpchdrudp.fragnum = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 77: - sstate->dcerpc.dcerpchdrudp.fragnum |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 78: - sstate->dcerpc.dcerpchdrudp.auth_proto = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 79: - sstate->dcerpc.dcerpchdrudp.serial_lo = *(p++); - if (sstate->dcerpc.dcerpchdrudp.drep[0] != 0x10) { - sstate->dcerpc.dcerpchdrudp.server_boot = SCByteSwap32(sstate->dcerpc.dcerpchdrudp.server_boot); - sstate->dcerpc.dcerpchdrudp.if_vers= SCByteSwap32(sstate->dcerpc.dcerpchdrudp.if_vers); - sstate->dcerpc.dcerpchdrudp.seqnum= SCByteSwap32(sstate->dcerpc.dcerpchdrudp.seqnum); - sstate->dcerpc.dcerpchdrudp.opnum = SCByteSwap16(sstate->dcerpc.dcerpchdrudp.opnum); - sstate->dcerpc.dcerpchdrudp.ihint= SCByteSwap16(sstate->dcerpc.dcerpchdrudp.ihint); - sstate->dcerpc.dcerpchdrudp.ahint = SCByteSwap16(sstate->dcerpc.dcerpchdrudp.ahint); - sstate->dcerpc.dcerpchdrudp.fraglen = SCByteSwap16(sstate->dcerpc.dcerpchdrudp.fraglen); - sstate->dcerpc.dcerpchdrudp.fragnum = SCByteSwap16(sstate->dcerpc.dcerpchdrudp.fragnum); - } - sstate->fraglenleft = sstate->dcerpc.dcerpchdrudp.fraglen; - sstate->uuid_entry = (DCERPCUuidEntry *) SCCalloc(1, - sizeof(DCERPCUuidEntry)); - if (sstate->uuid_entry == NULL) { - SCReturnUInt(-1); - } else { - memcpy(sstate->uuid_entry->uuid, - sstate->dcerpc.dcerpchdrudp.activityuuid, - sizeof(sstate->dcerpc.dcerpchdrudp.activityuuid)); - TAILQ_INSERT_HEAD(&sstate->uuid_list, sstate->uuid_entry, - next); -#ifdef UNITTESTS - if (RunmodeIsUnittests()) { - printUUID("DCERPC UDP", sstate->uuid_entry); - } -#endif - } - --input_len; - break; - } - } - sstate->bytesprocessed += (p - input); - SCReturnInt((p - input)); -} - -static int DCERPCUDPParse(Flow *f, void *dcerpc_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - uint32_t retval = 0; - uint32_t parsed = 0; - int hdrretval = 0; - SCEnter(); - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - DCERPCUDPState *sstate = (DCERPCUDPState *) dcerpc_state; - while (sstate->bytesprocessed < DCERPC_UDP_HDR_LEN && input_len) { - hdrretval = DCERPCUDPParseHeader(f, dcerpc_state, pstate, input, - input_len); - if (hdrretval == -1 || hdrretval > (int32_t)input_len) { - sstate->bytesprocessed = 0; - SCReturnInt(hdrretval); - } else { - parsed += hdrretval; - input_len -= hdrretval; - } - } - -#if 0 - printf("Done with DCERPCUDPParseHeader bytesprocessed %u/%u left %u\n", - sstate->bytesprocessed, sstate->dcerpc.dcerpchdrudp.fraglen, input_len); - printf("\nDCERPC Version:\t%u\n", sstate->dcerpc.dcerpchdrudp.rpc_vers); - printf("DCERPC Type:\t%u\n", sstate->dcerpc.dcerpchdrudp.ptype); - printf("DCERPC Flags1:\t0x%02x\n", sstate->dcerpc.dcerpchdrudp.flags1); - printf("DCERPC Flags2:\t0x%02x\n", sstate->dcerpc.dcerpchdrudp.flags2); - printf("DCERPC Packed Drep:\t%02x %02x %02x\n", - sstate->dcerpc.dcerpchdrudp.drep[0], sstate->dcerpc.dcerpchdrudp.drep[1], - sstate->dcerpc.dcerpchdrudp.drep[2]); - printf("DCERPC Frag Length:\t0x%04x %u\n", sstate->dcerpc.dcerpchdrudp.fraglen, - sstate->dcerpc.dcerpchdrudp.fraglen); - printf("DCERPC Frag Number:\t0x%04x\n", sstate->dcerpc.dcerpchdrudp.fragnum); - printf("DCERPC OpNum:\t0x%04x\n", sstate->dcerpc.dcerpchdrudp.opnum); -#endif - - while (sstate->bytesprocessed >= DCERPC_UDP_HDR_LEN - && sstate->bytesprocessed < sstate->dcerpc.dcerpchdrudp.fraglen - && input_len) { - retval = FragmentDataParser(f, dcerpc_state, pstate, input + parsed, - input_len); - if (retval || retval > input_len) { - parsed += retval; - input_len -= retval; - } else if (input_len) { - SCLogDebug("Error parsing DCERPC UDP Fragment Data"); - parsed -= input_len; - input_len = 0; - sstate->bytesprocessed = 0; - } - } - - if (sstate->bytesprocessed == sstate->dcerpc.dcerpchdrudp.fraglen) { - sstate->bytesprocessed = 0; - } - if (pstate == NULL) - SCReturnInt(-1); - - SCReturnInt(1); -} - -static void *DCERPCUDPStateAlloc(void) -{ - void *s = SCMalloc(sizeof(DCERPCUDPState)); - if (unlikely(s == NULL)) - return NULL; - - memset(s, 0, sizeof(DCERPCUDPState)); - return s; -} - -static void DCERPCUDPStateFree(void *s) -{ - DCERPCUDPState *sstate = (DCERPCUDPState *) s; - - DCERPCUuidEntry *item; - - while ((item = TAILQ_FIRST(&sstate->uuid_list))) { - //printUUID("Free", item); - TAILQ_REMOVE(&sstate->uuid_list, item, next); - SCFree(item); - } - if (sstate->dcerpc.dcerpcrequest.stub_data_buffer != NULL) { - SCFree(sstate->dcerpc.dcerpcrequest.stub_data_buffer); - sstate->dcerpc.dcerpcrequest.stub_data_buffer = NULL; - sstate->dcerpc.dcerpcrequest.stub_data_buffer_len = 0; - } - if (sstate->dcerpc.dcerpcresponse.stub_data_buffer != NULL) { - SCFree(sstate->dcerpc.dcerpcresponse.stub_data_buffer); - sstate->dcerpc.dcerpcresponse.stub_data_buffer = NULL; - sstate->dcerpc.dcerpcresponse.stub_data_buffer_len = 0; - } - SCFree(s); -} - -static int DCERPCUDPRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_DCERPC, - "|04 00|", 2, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - - return 0; -} - -void RegisterDCERPCUDPParsers(void) -{ - char *proto_name = "dcerpc"; - - if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_DCERPC, proto_name); - if (DCERPCUDPRegisterPatternsForProtocolDetection() < 0) - return; - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - "dcerpc"); - return; - } - - if (AppLayerParserConfParserEnabled("udp", "dcerpc")) { - AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DCERPC, STREAM_TOSERVER, - DCERPCUDPParse); - AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DCERPC, STREAM_TOCLIENT, - DCERPCUDPParse); - AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_DCERPC, DCERPCUDPStateAlloc, - DCERPCUDPStateFree); - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_UDP, ALPROTO_DCERPC, STREAM_TOSERVER); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", "dcerpc"); - } -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_UDP, ALPROTO_DCERPC, DCERPCUDPParserRegisterTests); -#endif - - return; -} - -/* UNITTESTS */ -#ifdef UNITTESTS -/** \test DCERPC UDP Header Parsing and UUID handling - */ - -int DCERPCUDPParserTest01(void) -{ - int result = 1; - Flow f; - uint8_t dcerpcrequest[] = { - 0x04, 0x00, 0x2c, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, - 0x3f, 0x98, 0xf0, 0x5c, 0xd9, 0x63, 0xcc, 0x46, - 0xc2, 0x74, 0x51, 0x6c, 0x8a, 0x53, 0x7d, 0x6f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x70, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x32, 0x24, 0x58, 0xfd, - 0xcc, 0x45, 0x64, 0x49, 0xb0, 0x70, 0xdd, 0xae, - 0x74, 0x2c, 0x96, 0xd2, 0x60, 0x5e, 0x0d, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x5e, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x7c, 0x5e, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x80, 0x96, 0xf1, 0xf1, - 0x2a, 0x4d, 0xce, 0x11, 0xa6, 0x6a, 0x00, 0x20, - 0xaf, 0x6e, 0x72, 0xf4, 0x0c, 0x00, 0x00, 0x00, - 0x4d, 0x41, 0x52, 0x42, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0d, 0xf0, 0xad, 0xba, - 0x00, 0x00, 0x00, 0x00, 0xa8, 0xf4, 0x0b, 0x00, - 0x10, 0x09, 0x00, 0x00, 0x10, 0x09, 0x00, 0x00, - 0x4d, 0x45, 0x4f, 0x57, 0x04, 0x00, 0x00, 0x00, - 0xa2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, - 0x38, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, - 0xd8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, - 0xc8, 0x00, 0x00, 0x00, 0x4d, 0x45, 0x4f, 0x57, - 0xd8, 0x08, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc4, 0x28, 0xcd, 0x00, - 0x64, 0x29, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0xb9, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x46, 0xab, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x46, 0xa5, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x46, 0xa6, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x46, 0xa4, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x46, 0xad, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x46, 0xaa, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x46, 0x07, 0x00, 0x00, 0x00, - 0x60, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x28, 0x06, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, - 0x50, 0x00, 0x00, 0x00, 0x4f, 0xb6, 0x88, 0x20, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, - 0x48, 0x00, 0x00, 0x00, 0x07, 0x00, 0x66, 0x00, - 0x06, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x0c, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x98, 0x93, - 0x98, 0x4f, 0xd2, 0x11, 0xa9, 0x3d, 0xbe, 0x57, - 0xb2, 0x00, 0x00, 0x00, 0x32, 0x00, 0x31, 0x00, - 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, - 0x80, 0x00, 0x00, 0x00, 0x0d, 0xf0, 0xad, 0xba, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x4d, 0x45, 0x4f, 0x57, 0x04, 0x00, 0x00, 0x00, - 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, - 0x3b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x81, 0xc5, 0x17, 0x03, - 0x80, 0x0e, 0xe9, 0x4a, 0x99, 0x99, 0xf1, 0x8a, - 0x50, 0x6f, 0x7a, 0x85, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, - 0x30, 0x00, 0x00, 0x00, 0x78, 0x00, 0x6e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd8, 0xda, 0x0d, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x2f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, - 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x2e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, - 0x68, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xff, 0xff, - 0x68, 0x8b, 0x0b, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0x02, 0x00, 0x00, 0x5c, 0x00, 0x5c, 0x00, - 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, - 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, - 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, - 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, 0x31, 0x00, - 0x31, 0x00, 0x31, 0x00, 0x9d, 0x13, 0x00, 0x01, - 0xcc, 0xe0, 0xfd, 0x7f, 0xcc, 0xe0, 0xfd, 0x7f, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90}; - uint32_t requestlen = sizeof(dcerpcrequest); - - TcpSession ssn; - DCERPCUuidEntry *uuid_entry; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_UDP; - f.protomap = FlowGetProtoMapping(f.proto); - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_START, dcerpcrequest, requestlen); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCUDPState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdrudp.rpc_vers != 4) { - printf("expected dcerpc version 0x04, got 0x%02x : ", - dcerpc_state->dcerpc.dcerpchdrudp.rpc_vers); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdrudp.fraglen != 1392) { - printf("expected dcerpc fraglen 0x%02x , got 0x%02x : ", 1392, dcerpc_state->dcerpc.dcerpchdrudp.fraglen); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdrudp.opnum != 4) { - printf("expected dcerpc opnum 0x%02x , got 0x%02x : ", 4, dcerpc_state->dcerpc.dcerpchdrudp.opnum); - result = 0; - goto end; - } - - TAILQ_FOREACH(uuid_entry, &dcerpc_state->uuid_list, next) { - printUUID("REQUEST", uuid_entry); - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -void DCERPCUDPParserRegisterTests(void) -{ - UtRegisterTest("DCERPCUDPParserTest01", DCERPCUDPParserTest01, 1); -} -#endif diff --git a/framework/src/suricata/src/app-layer-dcerpc-udp.h b/framework/src/suricata/src/app-layer-dcerpc-udp.h deleted file mode 100644 index c9054d6d..00000000 --- a/framework/src/suricata/src/app-layer-dcerpc-udp.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2009,2010 Open Information Security Foundation - * - * \author Kirby Kuehl - */ - -#ifndef __APP_LAYER_DCERPC_UDP_H__ -#define __APP_LAYER_DCERPC_UDP_H__ - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-dcerpc-common.h" -#include "flow.h" -#include "queue.h" -#include "util-byte.h" - -typedef struct DCERPCUDPState_ { - DCERPCUDP dcerpc; - uint16_t bytesprocessed; - uint16_t fraglenleft; - uint8_t *frag_data; - DCERPCUuidEntry *uuid_entry; - TAILQ_HEAD(, DCERPCUuidEntry_) uuid_list; -} DCERPCUDPState; - -void RegisterDCERPCUDPParsers(void); -void DCERPCUDPParserTests(void); -void DCERPCUDPParserRegisterTests(void); - -#endif /* __APP_LAYER_DCERPC_UDP_H__ */ diff --git a/framework/src/suricata/src/app-layer-dcerpc.c b/framework/src/suricata/src/app-layer-dcerpc.c deleted file mode 100644 index 44705ea9..00000000 --- a/framework/src/suricata/src/app-layer-dcerpc.c +++ /dev/null @@ -1,6411 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Kirby Kuehl - * \author Anoop Saldanha - * - * \file DCE/RPC parser and decoder - * - * \todo Remove all the unnecessary per byte incremental loops with a full one - * time jump, i.e. - * - * input[0], input_len - * for (i = 0; i < x; i++) - * input++; - * - * with - * - * input += x; - * - * You'll be surprised at how many such cases we have here. We also need - * to do the same for htp parser. Should speed up the engine drastically. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-debug.h" - -#include "flow-util.h" - -#include "detect-engine-state.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer.h" - -#include "util-spm.h" -#include "util-unittest.h" - -#include "app-layer-dcerpc.h" - -enum { - DCERPC_FIELD_NONE = 0, - DCERPC_PARSE_DCERPC_HEADER, - DCERPC_PARSE_DCERPC_BIND, - DCERPC_PARSE_DCERPC_BIND_ACK, - DCERPC_PARSE_DCERPC_REQUEST, - /* must be last */ - DCERPC_FIELD_MAX, -}; - -/* \brief hexdump function from libdnet, used for debugging only */ -void hexdump(/*Flow *f,*/ const void *buf, size_t len) -{ - /* dumps len bytes of *buf to stdout. Looks like: - * [0000] 75 6E 6B 6E 6F 77 6E 20 - * 30 FF 00 00 00 00 39 00 unknown 0.....9. - * (in a single line of course) - */ - - const unsigned char *p = buf; - unsigned char c; - size_t n; - char bytestr[4] = {0}; - char addrstr[10] = {0}; - char hexstr[ 16*3 + 5] = {0}; - char charstr[16*1 + 5] = {0}; - for (n=1; n<=len; n++) { - if (n%16 == 1) { - /* store address for this line */ -#if __WORDSIZE == 64 - snprintf(addrstr, sizeof(addrstr), "%.4"PRIx64, - ((uint64_t)p-(uint64_t)buf) ); -#else - snprintf(addrstr, sizeof(addrstr), "%.4"PRIx32, - ((uint32_t)p-(uint32_t)buf) ); -#endif - } - - c = *p; - if (isalnum(c) == 0) { - c = '.'; - } - - /* store hex str (for left side) */ - snprintf(bytestr, sizeof(bytestr), "%02X ", *p); - strlcat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1); - - /* store char str (for right side) */ - snprintf(bytestr, sizeof(bytestr), "%c", c); - strlcat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1); - - if(n%16 == 0) { - /* line completed */ - printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); - hexstr[0] = 0; - charstr[0] = 0; - } else if(n%8 == 0) { - /* half line: add whitespaces */ - strlcat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1); - strlcat(charstr, " ", sizeof(charstr)-strlen(charstr)-1); - } - p++; /* next byte */ - } - - if (strlen(hexstr) > 0) { - /* print rest of buffer if not empty */ - printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); - } -} - -/** - * \brief printUUID function used to print UUID, Major and Minor Version Number - * and if it was Accepted or Rejected in the BIND_ACK. - */ -void printUUID(char *type, DCERPCUuidEntry *uuid) -{ - uint8_t i = 0; - if (uuid == NULL) { - return; - } - printf("%s UUID [%2u] %s ", type, uuid->ctxid, - (uuid->result == 0) ? "Accepted" : "Rejected"); - for (i = 0; i < 16; i++) { - printf("%02x", uuid->uuid[i]); - } - printf(" Major Version 0x%04x Minor Version 0x%04x\n", uuid->version, - uuid->versionminor); -} - -/** - * \brief DCERPCParseSecondaryAddr reads secondaryaddrlen bytes from the BIND_ACK - * DCERPC call. - */ -static uint32_t DCERPCParseSecondaryAddr(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t *p = input; - while (dcerpc->dcerpcbindbindack.secondaryaddrlenleft-- && input_len--) { - SCLogDebug("0x%02x ", *p); - p++; - } - dcerpc->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -static uint32_t PaddingParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t *p = input; - while (dcerpc->padleft-- && input_len--) { - SCLogDebug("0x%02x ", *p); - p++; - } - dcerpc->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -static uint32_t DCERPCGetCTXItems(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t *p = input; - if (input_len) { - switch (dcerpc->dcerpcbindbindack.ctxbytesprocessed) { - case 0: - if (input_len >= 4) { - dcerpc->dcerpcbindbindack.numctxitems = *p; - dcerpc->dcerpcbindbindack.numctxitemsleft = dcerpc->dcerpcbindbindack.numctxitems; - dcerpc->dcerpcbindbindack.ctxbytesprocessed += 4; - dcerpc->bytesprocessed += 4; - SCReturnUInt(4U); - } else { - dcerpc->dcerpcbindbindack.numctxitems = *(p++); - dcerpc->dcerpcbindbindack.numctxitemsleft = dcerpc->dcerpcbindbindack.numctxitems; - if (!(--input_len)) - break; - } - /* fall through */ - case 1: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 2: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 3: - p++; - input_len--; - break; - } - } - dcerpc->dcerpcbindbindack.ctxbytesprocessed += (p - input); - dcerpc->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -/** - * \brief DCERPCParseBINDCTXItem is called for each CTXItem found the DCERPC BIND call. - * each UUID is added to a TAILQ. - */ - -static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t *p = input; - - if (input_len) { - switch (dcerpc->dcerpcbindbindack.ctxbytesprocessed) { - case 0: - if (input_len >= 44) { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.ctxid = *(p); - dcerpc->dcerpcbindbindack.ctxid |= *(p + 1) << 8; - dcerpc->dcerpcbindbindack.uuid[3] = *(p + 4); - dcerpc->dcerpcbindbindack.uuid[2] = *(p + 5); - dcerpc->dcerpcbindbindack.uuid[1] = *(p + 6); - dcerpc->dcerpcbindbindack.uuid[0] = *(p + 7); - dcerpc->dcerpcbindbindack.uuid[5] = *(p + 8); - dcerpc->dcerpcbindbindack.uuid[4] = *(p + 9); - dcerpc->dcerpcbindbindack.uuid[7] = *(p + 10); - dcerpc->dcerpcbindbindack.uuid[6] = *(p + 11); - dcerpc->dcerpcbindbindack.uuid[8] = *(p + 12); - dcerpc->dcerpcbindbindack.uuid[9] = *(p + 13); - dcerpc->dcerpcbindbindack.uuid[10] = *(p + 14); - dcerpc->dcerpcbindbindack.uuid[11] = *(p + 15); - dcerpc->dcerpcbindbindack.uuid[12] = *(p + 16); - dcerpc->dcerpcbindbindack.uuid[13] = *(p + 17); - dcerpc->dcerpcbindbindack.uuid[14] = *(p + 18); - dcerpc->dcerpcbindbindack.uuid[15] = *(p + 19); - dcerpc->dcerpcbindbindack.version = *(p + 20); - dcerpc->dcerpcbindbindack.version |= *(p + 21) << 8; - dcerpc->dcerpcbindbindack.versionminor = *(p + 22); - dcerpc->dcerpcbindbindack.versionminor |= *(p + 23) << 8; - } else { /* Big Endian */ - dcerpc->dcerpcbindbindack.ctxid = *(p) << 8; - dcerpc->dcerpcbindbindack.ctxid |= *(p + 1); - dcerpc->dcerpcbindbindack.uuid[0] = *(p + 4); - dcerpc->dcerpcbindbindack.uuid[1] = *(p + 5); - dcerpc->dcerpcbindbindack.uuid[2] = *(p + 6); - dcerpc->dcerpcbindbindack.uuid[3] = *(p + 7); - dcerpc->dcerpcbindbindack.uuid[4] = *(p + 8); - dcerpc->dcerpcbindbindack.uuid[5] = *(p + 9); - dcerpc->dcerpcbindbindack.uuid[6] = *(p + 10); - dcerpc->dcerpcbindbindack.uuid[7] = *(p + 11); - dcerpc->dcerpcbindbindack.uuid[8] = *(p + 12); - dcerpc->dcerpcbindbindack.uuid[9] = *(p + 13); - dcerpc->dcerpcbindbindack.uuid[10] = *(p + 14); - dcerpc->dcerpcbindbindack.uuid[11] = *(p + 15); - dcerpc->dcerpcbindbindack.uuid[12] = *(p + 16); - dcerpc->dcerpcbindbindack.uuid[13] = *(p + 17); - dcerpc->dcerpcbindbindack.uuid[14] = *(p + 18); - dcerpc->dcerpcbindbindack.uuid[15] = *(p + 19); - dcerpc->dcerpcbindbindack.version = *(p + 20) << 8; - dcerpc->dcerpcbindbindack.version |= *(p + 21); - dcerpc->dcerpcbindbindack.versionminor = *(p + 22) << 8; - dcerpc->dcerpcbindbindack.versionminor |= *(p + 23); - } - //if (dcerpc->dcerpcbindbindack.ctxid == dcerpc->dcerpcbindbindack.numctxitems - // - dcerpc->dcerpcbindbindack.numctxitemsleft) { - - dcerpc->dcerpcbindbindack.uuid_entry = (DCERPCUuidEntry *)SCCalloc(1, sizeof(DCERPCUuidEntry)); - if (dcerpc->dcerpcbindbindack.uuid_entry == NULL) { - SCLogDebug("UUID Entry is NULL"); - SCReturnUInt(0); - } - - dcerpc->dcerpcbindbindack.uuid_entry->internal_id = dcerpc->dcerpcbindbindack.uuid_internal_id++; - - memcpy(dcerpc->dcerpcbindbindack.uuid_entry->uuid, - dcerpc->dcerpcbindbindack.uuid, - sizeof(dcerpc->dcerpcbindbindack.uuid)); - - dcerpc->dcerpcbindbindack.uuid_entry->ctxid = dcerpc->dcerpcbindbindack.ctxid; - dcerpc->dcerpcbindbindack.uuid_entry->version = dcerpc->dcerpcbindbindack.version; - dcerpc->dcerpcbindbindack.uuid_entry->versionminor = dcerpc->dcerpcbindbindack.versionminor; - - /* store the first frag flag in the uuid as pfc_flags will - * be overwritten by new packets. */ - if (dcerpc->dcerpchdr.pfc_flags & PFC_FIRST_FRAG) { - dcerpc->dcerpcbindbindack.uuid_entry->flags |= DCERPC_UUID_ENTRY_FLAG_FF; - } - - TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.uuid_list, - dcerpc->dcerpcbindbindack.uuid_entry, - next); - -#ifdef UNITTESTS - if (RunmodeIsUnittests()) { - printUUID("BIND", dcerpc->dcerpcbindbindack.uuid_entry); - } -#endif - dcerpc->dcerpcbindbindack.numctxitemsleft--; - dcerpc->bytesprocessed += (44); - dcerpc->dcerpcbindbindack.ctxbytesprocessed += (44); - SCReturnUInt(44U); - - //} else { - // SCLogDebug("ctxitem %u, expected %u\n", dcerpc->dcerpcbindbindack.ctxid, - // dcerpc->dcerpcbindbindack.numctxitems - dcerpc->dcerpcbindbindack.numctxitemsleft); - // SCReturnUInt(0); - //} - } else { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.ctxid = *(p++); - } else { - dcerpc->dcerpcbindbindack.ctxid = *(p++) << 8; - } - if (!(--input_len)) - break; - } - /* fall through */ - case 1: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.ctxid |= *(p++) << 8; - } else { - dcerpc->dcerpcbindbindack.ctxid |= *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 2: - /* num transact items */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 3: - /* reserved */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 4: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[3] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[0] = *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 5: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[2] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[1] = *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 6: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[1] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[2] = *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 7: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[0] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[3] = *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 8: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[5] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[4] = *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 9: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[4] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[5] = *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 10: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[7] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[6] = *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 11: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[6] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[7] = *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 12: - /* The following bytes are in the same order for both big and little endian */ - dcerpc->dcerpcbindbindack.uuid[8] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 13: - dcerpc->dcerpcbindbindack.uuid[9] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 14: - dcerpc->dcerpcbindbindack.uuid[10] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 15: - dcerpc->dcerpcbindbindack.uuid[11] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 16: - dcerpc->dcerpcbindbindack.uuid[12] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 17: - dcerpc->dcerpcbindbindack.uuid[13] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 18: - dcerpc->dcerpcbindbindack.uuid[14] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 19: - dcerpc->dcerpcbindbindack.uuid[15] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 20: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.version = *(p++); - } else { - dcerpc->dcerpcbindbindack.version = *(p++) << 8; - } - if (!(--input_len)) - break; - /* fall through */ - case 21: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.version |= *(p++) << 8; - } else { - dcerpc->dcerpcbindbindack.version |= *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 22: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.versionminor = *(p++); - } else { - dcerpc->dcerpcbindbindack.versionminor = *(p++) << 8; - } - if (!(--input_len)) - break; - /* fall through */ - case 23: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.versionminor |= *(p++) << 8; - } else { - dcerpc->dcerpcbindbindack.versionminor |= *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 24: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 25: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 26: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 27: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 28: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 29: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 30: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 31: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 32: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 33: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 34: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 35: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 36: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 37: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 38: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 39: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 40: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 41: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 42: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 43: - p++; - --input_len; - //if (dcerpc->dcerpcbindbindack.ctxid == dcerpc->dcerpcbindbindack.numctxitems - dcerpc->dcerpcbindbindack.numctxitemsleft) { - dcerpc->dcerpcbindbindack.uuid_entry = (DCERPCUuidEntry *) - SCCalloc(1, sizeof(DCERPCUuidEntry)); - if (dcerpc->dcerpcbindbindack.uuid_entry == NULL) { - SCLogDebug("UUID Entry is NULL\n"); - SCReturnUInt(0); - } - - dcerpc->dcerpcbindbindack.uuid_entry->internal_id = - dcerpc->dcerpcbindbindack.uuid_internal_id++; - memcpy(dcerpc->dcerpcbindbindack.uuid_entry->uuid, - dcerpc->dcerpcbindbindack.uuid, - sizeof(dcerpc->dcerpcbindbindack.uuid)); - dcerpc->dcerpcbindbindack.uuid_entry->ctxid = dcerpc->dcerpcbindbindack.ctxid; - dcerpc->dcerpcbindbindack.uuid_entry->version = dcerpc->dcerpcbindbindack.version; - dcerpc->dcerpcbindbindack.uuid_entry->versionminor = dcerpc->dcerpcbindbindack.versionminor; - - /* store the first frag flag in the uuid as pfc_flags will - * be overwritten by new packets. */ - if (dcerpc->dcerpchdr.pfc_flags & PFC_FIRST_FRAG) { - dcerpc->dcerpcbindbindack.uuid_entry->flags |= DCERPC_UUID_ENTRY_FLAG_FF; - } - - TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.uuid_list, - dcerpc->dcerpcbindbindack.uuid_entry, - next); -#ifdef UNITTESTS - if (RunmodeIsUnittests()) { - printUUID("BINDACK", dcerpc->dcerpcbindbindack.uuid_entry); - } -#endif - dcerpc->dcerpcbindbindack.numctxitemsleft--; - dcerpc->bytesprocessed += (p - input); - dcerpc->dcerpcbindbindack.ctxbytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); - - //} else { - // SCLogDebug("ctxitem %u, expected %u\n", dcerpc->dcerpcbindbindack.ctxid, - // dcerpc->dcerpcbindbindack.numctxitems - dcerpc->dcerpcbindbindack.numctxitemsleft); - // SCReturnUInt(0); - //} - break; - } - } - dcerpc->dcerpcbindbindack.ctxbytesprocessed += (p - input); - dcerpc->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -/** - * \brief DCERPCParseBINDACKCTXItem is called for each CTXItem found in - * the BIND_ACK call. The result (Accepted or Rejected) is added to the - * correct UUID from the BIND call. - */ -static uint32_t DCERPCParseBINDACKCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t *p = input; - DCERPCUuidEntry *uuid_entry; - - if (input_len) { - switch (dcerpc->dcerpcbindbindack.ctxbytesprocessed) { - case 0: - if (input_len >= 24) { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.result = *p; - dcerpc->dcerpcbindbindack.result |= *(p + 1) << 8; - } else { - dcerpc->dcerpcbindbindack.result = *p << 8; - dcerpc->dcerpcbindbindack.result |= *(p + 1); - } - TAILQ_FOREACH(uuid_entry, &dcerpc->dcerpcbindbindack.uuid_list, next) { - if (uuid_entry->internal_id == dcerpc->dcerpcbindbindack.uuid_internal_id) { - uuid_entry->result = dcerpc->dcerpcbindbindack.result; -#ifdef UNITTESTS - if (RunmodeIsUnittests()) { - printUUID("BIND_ACK", uuid_entry); - } -#endif - if (uuid_entry->result != 0) - break; - - dcerpc->dcerpcbindbindack.uuid_entry = (DCERPCUuidEntry *) - SCCalloc(1, sizeof(DCERPCUuidEntry)); - if (dcerpc->dcerpcbindbindack.uuid_entry != NULL) { - memcpy(dcerpc->dcerpcbindbindack.uuid_entry, - uuid_entry, - sizeof(DCERPCUuidEntry)); - TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.accepted_uuid_list, - dcerpc->dcerpcbindbindack.uuid_entry, - next); - } - break; - } - } - dcerpc->dcerpcbindbindack.uuid_internal_id++; - dcerpc->dcerpcbindbindack.numctxitemsleft--; - dcerpc->bytesprocessed += (24); - dcerpc->dcerpcbindbindack.ctxbytesprocessed += (24); - SCReturnUInt(24U); - } else { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.result = *(p++); - } else { - dcerpc->dcerpcbindbindack.result = *(p++) << 8; - } - if (!(--input_len)) - break; - } - /* fall through */ - case 1: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.result |= *(p++) << 8; - } else { - dcerpc->dcerpcbindbindack.result |= *(p++); - } - if (!(--input_len)) - break; - /* fall through */ - case 2: - /* num transact items */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 3: - /* reserved */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 4: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 5: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 6: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 7: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 8: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 9: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 10: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 11: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 12: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 13: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 14: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 15: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 16: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 17: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 18: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 19: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 20: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 21: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 22: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 23: - TAILQ_FOREACH(uuid_entry, &dcerpc->dcerpcbindbindack.uuid_list, next) { - if (uuid_entry->internal_id == dcerpc->dcerpcbindbindack.uuid_internal_id) { - uuid_entry->result = dcerpc->dcerpcbindbindack.result; -#ifdef UNITTESTS - if (RunmodeIsUnittests()) { - printUUID("BIND_ACK", uuid_entry); - } -#endif - if (uuid_entry->result != 0) - break; - - dcerpc->dcerpcbindbindack.uuid_entry = (DCERPCUuidEntry *) - SCCalloc(1, sizeof(DCERPCUuidEntry)); - if (dcerpc->dcerpcbindbindack.uuid_entry != NULL) { - memcpy(dcerpc->dcerpcbindbindack.uuid_entry, - uuid_entry, - sizeof(DCERPCUuidEntry)); - TAILQ_INSERT_HEAD(&dcerpc->dcerpcbindbindack.accepted_uuid_list, - dcerpc->dcerpcbindbindack.uuid_entry, - next); - } - break; - } - } - dcerpc->dcerpcbindbindack.uuid_internal_id++; - dcerpc->dcerpcbindbindack.numctxitemsleft--; - p++; - --input_len; - break; - - } - } - dcerpc->dcerpcbindbindack.ctxbytesprocessed += (p - input); - dcerpc->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -static uint32_t DCERPCParseBIND(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - DCERPCUuidEntry *item; - uint8_t *p = input; - if (input_len) { - switch (dcerpc->bytesprocessed) { - case 16: - dcerpc->dcerpcbindbindack.numctxitems = 0; - if (input_len >= 12) { - while ((item = TAILQ_FIRST(&dcerpc->dcerpcbindbindack.uuid_list))) { - TAILQ_REMOVE(&dcerpc->dcerpcbindbindack.uuid_list, item, next); - SCFree(item); - } - if (dcerpc->dcerpchdr.type == BIND) { - while ((item = TAILQ_FIRST(&dcerpc->dcerpcbindbindack.accepted_uuid_list))) { - TAILQ_REMOVE(&dcerpc->dcerpcbindbindack.accepted_uuid_list, item, next); - SCFree(item); - } - TAILQ_INIT(&dcerpc->dcerpcbindbindack.accepted_uuid_list); - } - dcerpc->dcerpcbindbindack.uuid_internal_id = 0; - dcerpc->dcerpcbindbindack.numctxitems = *(p + 8); - dcerpc->dcerpcbindbindack.numctxitemsleft = dcerpc->dcerpcbindbindack.numctxitems; - TAILQ_INIT(&dcerpc->dcerpcbindbindack.uuid_list); - dcerpc->bytesprocessed += 12; - SCReturnUInt(12U); - } else { - /* max_xmit_frag */ - p++; - if (!(--input_len)) - break; - } - /* fall through */ - case 17: - /* max_xmit_frag */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 18: - /* max_recv_frag */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 19: - /* max_recv_frag */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 20: - /* assoc_group_id */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 21: - /* assoc_group_id */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 22: - /* assoc_group_id */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 23: - /* assoc_group_id */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 24: - while ((item = TAILQ_FIRST(&dcerpc->dcerpcbindbindack.uuid_list))) { - TAILQ_REMOVE(&dcerpc->dcerpcbindbindack.uuid_list, item, next); - SCFree(item); - } - if (dcerpc->dcerpchdr.type == BIND) { - while ((item = TAILQ_FIRST(&dcerpc->dcerpcbindbindack.accepted_uuid_list))) { - TAILQ_REMOVE(&dcerpc->dcerpcbindbindack.accepted_uuid_list, item, next); - SCFree(item); - } - TAILQ_INIT(&dcerpc->dcerpcbindbindack.accepted_uuid_list); - } - dcerpc->dcerpcbindbindack.uuid_internal_id = 0; - dcerpc->dcerpcbindbindack.numctxitems = *(p++); - dcerpc->dcerpcbindbindack.numctxitemsleft = dcerpc->dcerpcbindbindack.numctxitems; - TAILQ_INIT(&dcerpc->dcerpcbindbindack.uuid_list); - if (!(--input_len)) - break; - /* fall through */ - case 25: - /* pad byte 1 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 26: - /* pad byte 2 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 27: - /* pad byte 3 */ - p++; - --input_len; - break; - /* fall through */ - default: - dcerpc->bytesprocessed++; - SCReturnUInt(1); - break; - } - } - dcerpc->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -static uint32_t DCERPCParseBINDACK(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t *p = input; - - switch (dcerpc->bytesprocessed) { - case 16: - dcerpc->dcerpcbindbindack.uuid_internal_id = 0; - dcerpc->dcerpcbindbindack.numctxitems = 0; - if (input_len >= 10) { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.secondaryaddrlen = *(p + 8); - dcerpc->dcerpcbindbindack.secondaryaddrlen |= *(p + 9) << 8; - } else { - dcerpc->dcerpcbindbindack.secondaryaddrlen = *(p + 8) << 8; - dcerpc->dcerpcbindbindack.secondaryaddrlen |= *(p + 9); - } - dcerpc->dcerpcbindbindack.secondaryaddrlenleft = dcerpc->dcerpcbindbindack.secondaryaddrlen; - dcerpc->bytesprocessed += 10; - SCReturnUInt(10U); - } else { - /* max_xmit_frag */ - p++; - if (!(--input_len)) - break; - } - /* fall through */ - case 17: - /* max_xmit_frag */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 18: - /* max_recv_frag */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 19: - /* max_recv_frag */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 20: - /* assoc_group_id */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 21: - /* assoc_group_id */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 22: - /* assoc_group_id */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 23: - /* assoc_group_id */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 24: - dcerpc->dcerpcbindbindack.secondaryaddrlen = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 25: - dcerpc->dcerpcbindbindack.secondaryaddrlen |= *(p++); - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.secondaryaddrlen = SCByteSwap16(dcerpc->dcerpcbindbindack.secondaryaddrlen); - } - dcerpc->dcerpcbindbindack.secondaryaddrlenleft = dcerpc->dcerpcbindbindack.secondaryaddrlen; - SCLogDebug("secondaryaddrlen %u 0x%04x\n", dcerpc->dcerpcbindbindack.secondaryaddrlen, - dcerpc->dcerpcbindbindack.secondaryaddrlen); - --input_len; - break; - default: - dcerpc->bytesprocessed++; - SCReturnUInt(1); - break; - } - dcerpc->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -static uint32_t DCERPCParseREQUEST(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t *p = input; - - switch (dcerpc->bytesprocessed) { - case 16: - dcerpc->dcerpcbindbindack.numctxitems = 0; - if (input_len >= 8) { - if (dcerpc->dcerpchdr.type == REQUEST) { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcrequest.ctxid = *(p + 4); - dcerpc->dcerpcrequest.ctxid |= *(p + 5) << 8; - dcerpc->dcerpcrequest.opnum = *(p + 6); - dcerpc->dcerpcrequest.opnum |= *(p + 7) << 8; - } else { - dcerpc->dcerpcrequest.ctxid = *(p + 4) << 8; - dcerpc->dcerpcrequest.ctxid |= *(p + 5); - dcerpc->dcerpcrequest.opnum = *(p + 6) << 8; - dcerpc->dcerpcrequest.opnum |= *(p + 7); - } - dcerpc->dcerpcrequest.first_request_seen = 1; - } - dcerpc->bytesprocessed += 8; - SCReturnUInt(8U); - } else { - /* alloc hint 1 */ - p++; - if (!(--input_len)) - break; - } - /* fall through */ - case 17: - /* alloc hint 2 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 18: - /* alloc hint 3 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 19: - /* alloc hint 4 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 20: - /* context id 1 */ - dcerpc->dcerpcrequest.ctxid = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 21: - /* context id 2 */ - dcerpc->dcerpcrequest.ctxid |= *(p++) << 8; - if (!(dcerpc->dcerpchdr.packed_drep[0] & 0x10)) { - dcerpc->dcerpcrequest.ctxid = SCByteSwap16(dcerpc->dcerpcrequest.ctxid); - } - dcerpc->dcerpcrequest.first_request_seen = 1; - if (!(--input_len)) - break; - /* fall through */ - case 22: - if (dcerpc->dcerpchdr.type == REQUEST) { - dcerpc->dcerpcrequest.opnum = *(p++); - } else { - p++; - } - if (!(--input_len)) - break; - /* fall through */ - case 23: - if (dcerpc->dcerpchdr.type == REQUEST) { - dcerpc->dcerpcrequest.opnum |= *(p++) << 8; - if (!(dcerpc->dcerpchdr.packed_drep[0] & 0x10)) { - dcerpc->dcerpcrequest.opnum = SCByteSwap16(dcerpc->dcerpcrequest.opnum); - } - } else { - p++; - } - --input_len; - break; - default: - dcerpc->bytesprocessed++; - SCReturnUInt(1); - break; - } - dcerpc->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -/** \internal - * \retval stub_len or 0 in case of error */ -static uint32_t StubDataParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t **stub_data_buffer = NULL; - uint32_t *stub_data_buffer_len = NULL; - uint8_t *stub_data_fresh = NULL; - uint16_t stub_len = 0; - void *ptmp; - - /* request PDU. Retrieve the request stub buffer */ - if (dcerpc->dcerpchdr.type == REQUEST) { - stub_data_buffer = &dcerpc->dcerpcrequest.stub_data_buffer; - stub_data_buffer_len = &dcerpc->dcerpcrequest.stub_data_buffer_len; - stub_data_fresh = &dcerpc->dcerpcrequest.stub_data_fresh; - - /* response PDU. Retrieve the response stub buffer */ - } else { - stub_data_buffer = &dcerpc->dcerpcresponse.stub_data_buffer; - stub_data_buffer_len = &dcerpc->dcerpcresponse.stub_data_buffer_len; - stub_data_fresh = &dcerpc->dcerpcresponse.stub_data_fresh; - } - - stub_len = (dcerpc->padleft < input_len) ? dcerpc->padleft : input_len; - if (stub_len == 0) { - SCLogError(SC_ERR_DCERPC, "stub_len is NULL. We shouldn't be seeing " - "this. In case you are, there is something gravely wrong " - "with the dcerpc parser"); - SCReturnInt(0); - } - - /* To see what is in this stub fragment */ - //hexdump(input, stub_len); - /* if the frag is the the first frag irrespective of it being a part of - * a multi frag PDU or not, it indicates the previous PDU's stub would - * have been buffered and processed and we can use the buffer to hold - * frags from a fresh request/response. Also if the state is in the - * process of processing a fragmented pdu, we should append to the - * existing stub and not reset the stub buffer */ - if ((dcerpc->dcerpchdr.pfc_flags & PFC_FIRST_FRAG) && - !dcerpc->pdu_fragged) { - *stub_data_buffer_len = 0; - /* just a hack to get thing working. We shouldn't be setting - * this var here. The ideal thing would have been to use - * an extra state var, to indicate that the stub parser has made a - * fresh entry after reseting the buffer, but maintaing an extra var - * would be a nuisance, while we can achieve the same thing with - * little or no effort, with a simple set here, although semantically - * it is a wrong thing to set it here, since we still can't conclude - * if a pdu is fragmented or not at this point, if we are parsing a PDU - * that has some stub data in the first segment, but it still doesn't - * contain the entire PDU */ - dcerpc->pdu_fragged = 1; - } - - ptmp = SCRealloc(*stub_data_buffer, *stub_data_buffer_len + stub_len); - if (ptmp == NULL) { - SCFree(*stub_data_buffer); - *stub_data_buffer = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - SCReturnUInt(0); - } - *stub_data_buffer = ptmp; - - memcpy(*stub_data_buffer + *stub_data_buffer_len, input, stub_len); - - *stub_data_fresh = 1; - /* length of the buffered stub */ - *stub_data_buffer_len += stub_len; - /* To see the total reassembled stubdata */ - //hexdump(*stub_data_buffer, *stub_data_buffer_len); - - dcerpc->padleft -= stub_len; - dcerpc->bytesprocessed += stub_len; - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - int i = 0; - for (i = 0; i < stub_len; i++) { - SCLogDebug("0x%02x ", input[i]); - } - } -#endif - - SCReturnUInt((uint32_t)stub_len); -} - -/** - * \brief DCERPCParseHeader parses the 16 byte DCERPC header - * A fast path for normal decoding is used when there is enough bytes - * present to parse the entire header. A slow path is used to parse - * fragmented packets. - * \retval -1 if DCERPC Header does not validate - * \retval Number of bytes processed - */ -static int DCERPCParseHeader(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - uint8_t *p = input; - - if (input_len) { - SCLogDebug("dcerpc->bytesprocessed %u", dcerpc->bytesprocessed); - switch (dcerpc->bytesprocessed) { - case 0: - if (input_len >= DCERPC_HDR_LEN) { - dcerpc->dcerpchdr.rpc_vers = *p; - dcerpc->dcerpchdr.rpc_vers_minor = *(p + 1); - if ((dcerpc->dcerpchdr.rpc_vers != 5) || - ((dcerpc->dcerpchdr.rpc_vers_minor != 0) && - (dcerpc->dcerpchdr.rpc_vers_minor != 1))) { - SCLogDebug("DCERPC Header did not validate"); - SCReturnInt(-1); - } - dcerpc->dcerpchdr.type = *(p + 2); - SCLogDebug("dcerpc->dcerpchdr.type %02x", - dcerpc->dcerpchdr.type); - dcerpc->dcerpchdr.pfc_flags = *(p + 3); - dcerpc->dcerpchdr.packed_drep[0] = *(p + 4); - dcerpc->dcerpchdr.packed_drep[1] = *(p + 5); - dcerpc->dcerpchdr.packed_drep[2] = *(p + 6); - dcerpc->dcerpchdr.packed_drep[3] = *(p + 7); - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpchdr.frag_length = *(p + 8); - dcerpc->dcerpchdr.frag_length |= *(p + 9) << 8; - dcerpc->dcerpchdr.auth_length = *(p + 10); - dcerpc->dcerpchdr.auth_length |= *(p + 11) << 8; - dcerpc->dcerpchdr.call_id = *(p + 12) << 24; - dcerpc->dcerpchdr.call_id |= *(p + 13) << 16; - dcerpc->dcerpchdr.call_id |= *(p + 14) << 8; - dcerpc->dcerpchdr.call_id |= *(p + 15); - } else { - dcerpc->dcerpchdr.frag_length = *(p + 8) << 8; - dcerpc->dcerpchdr.frag_length |= *(p + 9); - dcerpc->dcerpchdr.auth_length = *(p + 10) << 8; - dcerpc->dcerpchdr.auth_length |= *(p + 11); - dcerpc->dcerpchdr.call_id = *(p + 12); - dcerpc->dcerpchdr.call_id |= *(p + 13) << 8; - dcerpc->dcerpchdr.call_id |= *(p + 14) << 16; - dcerpc->dcerpchdr.call_id |= *(p + 15) << 24; - } - dcerpc->bytesprocessed = DCERPC_HDR_LEN; - SCReturnInt(16); - break; - } else { - dcerpc->dcerpchdr.rpc_vers = *(p++); - if (!(--input_len)) - break; - } - /* fall through */ - case 1: - dcerpc->dcerpchdr.rpc_vers_minor = *(p++); - if ((dcerpc->dcerpchdr.rpc_vers != 5) || - ((dcerpc->dcerpchdr.rpc_vers_minor != 0) && - (dcerpc->dcerpchdr.rpc_vers_minor != 1))) { - SCLogDebug("DCERPC Header did not validate"); - SCReturnInt(-1); - } - if (!(--input_len)) - break; - /* fall through */ - case 2: - dcerpc->dcerpchdr.type = *(p++); - SCLogDebug("dcerpc->dcerpchdr.type %02x", - dcerpc->dcerpchdr.type); - if (!(--input_len)) - break; - /* fall through */ - case 3: - dcerpc->dcerpchdr.pfc_flags = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 4: - dcerpc->dcerpchdr.packed_drep[0] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 5: - dcerpc->dcerpchdr.packed_drep[1] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 6: - dcerpc->dcerpchdr.packed_drep[2] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 7: - dcerpc->dcerpchdr.packed_drep[3] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 8: - dcerpc->dcerpchdr.frag_length = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 9: - dcerpc->dcerpchdr.frag_length |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 10: - dcerpc->dcerpchdr.auth_length = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 11: - dcerpc->dcerpchdr.auth_length |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 12: - dcerpc->dcerpchdr.call_id = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 13: - dcerpc->dcerpchdr.call_id |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 14: - dcerpc->dcerpchdr.call_id |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 15: - dcerpc->dcerpchdr.call_id |= *(p++) << 24; - if (!(dcerpc->dcerpchdr.packed_drep[0] & 0x10)) { - dcerpc->dcerpchdr.frag_length = SCByteSwap16(dcerpc->dcerpchdr.frag_length); - dcerpc->dcerpchdr.auth_length = SCByteSwap16(dcerpc->dcerpchdr.auth_length); - dcerpc->dcerpchdr.call_id = SCByteSwap32(dcerpc->dcerpchdr.call_id); - } - --input_len; - break; - default: - dcerpc->bytesprocessed++; - SCReturnInt(1); - } - } - dcerpc->bytesprocessed += (p - input); - SCReturnInt((p - input)); -} - -static inline void DCERPCResetParsingState(DCERPC *dcerpc) -{ - dcerpc->bytesprocessed = 0; - dcerpc->pdu_fragged = 0; - dcerpc->dcerpcbindbindack.ctxbytesprocessed = 0; - - return; -} - -static inline void DCERPCResetStub(DCERPC *dcerpc) -{ - if (dcerpc->dcerpchdr.type == REQUEST) - dcerpc->dcerpcrequest.stub_data_buffer_len = 0; - else if (dcerpc->dcerpchdr.type == RESPONSE) - dcerpc->dcerpcresponse.stub_data_buffer_len = 0; - - return; -} - -static inline int DCERPCThrowOutExtraData(DCERPC *dcerpc, uint8_t *input, - uint16_t input_len) -{ - int parsed = 0; - /* the function always assumes that - * dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length */ - if (input_len > (dcerpc->dcerpchdr.frag_length - dcerpc->bytesprocessed)) { - parsed = dcerpc->dcerpchdr.frag_length - dcerpc->bytesprocessed; - } else { - parsed = input_len; - } - dcerpc->bytesprocessed += parsed; - - return parsed; -} - -/** - * \todo - Currently the parser is very generic. Enable target based - * reassembly. - * - Disable reiniting tailq for mid and last bind/alter_context pdus. - * - Use a PM to search for subsequent 05 00 when we see an inconsistent - * pdu. This should be done for each platform based on how it handles - * a condition where it has receives a segment with 2 pdus, while the - * first pdu in the segment is corrupt. - */ -int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - uint32_t retval = 0; - uint32_t parsed = 0; - int hdrretval = 0; - - dcerpc->dcerpcrequest.stub_data_fresh = 0; - dcerpc->dcerpcresponse.stub_data_fresh = 0; - - /* temporary use. we will get rid of this later, once we have ironed out - * all the endless loops cases */ - int counter = 0; - - while (input_len) { - /* in case we have any corner cases remainging, we have this */ - if (counter++ == 30) { - SCLogDebug("Somehow seem to be stuck inside the dce " - "parser for quite sometime. Let's get out of here."); - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - - while (dcerpc->bytesprocessed < DCERPC_HDR_LEN && input_len) { - hdrretval = DCERPCParseHeader(dcerpc, input + parsed, input_len); - if (hdrretval == -1 || hdrretval > (int32_t)input_len) { - SCLogDebug("Error parsing dce header. Discarding " - "PDU and reseting parsing state to parse next PDU"); - /* error parsing pdu header. Let's clear the dce state */ - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } else { - parsed += hdrretval; - input_len -= hdrretval; - } - } - SCLogDebug("Done with DCERPCParseHeader bytesprocessed %u/%u left %u", - dcerpc->bytesprocessed, dcerpc->dcerpchdr.frag_length, input_len); -#if 0 - printf("Done with DCERPCParseHeader bytesprocessed %u/%u input_len left %u\n", - dcerpc->bytesprocessed, dcerpc->dcerpchdr.frag_length, input_len); - printf("\nDCERPC Version:\t%u\n", dcerpc->dcerpchdr.rpc_vers); - printf("DCERPC Version Minor:\t%u\n", dcerpc->dcerpchdr.rpc_vers_minor); - printf("DCERPC Type:\t%u\n", dcerpc->dcerpchdr.type); - printf("DCERPC Flags:\t0x%02x\n", dcerpc->dcerpchdr.pfc_flags); - printf("DCERPC Packed Drep:\t%02x %02x %02x %02x\n", - dcerpc->dcerpchdr.packed_drep[0], dcerpc->dcerpchdr.packed_drep[1], - dcerpc->dcerpchdr.packed_drep[2], dcerpc->dcerpchdr.packed_drep[3]); - printf("DCERPC Frag Length:\t0x%04x %u\n", - dcerpc->dcerpchdr.frag_length, dcerpc->dcerpchdr.frag_length); - printf("DCERPC Auth Length:\t0x%04x\n", dcerpc->dcerpchdr.auth_length); - printf("DCERPC Call Id:\t0x%08x\n", dcerpc->dcerpchdr.call_id); -#endif - - /* check if we have parsed the entire input passed in the header parser. - * If we have, time to leave */ - if (input_len == 0) { - if (dcerpc->bytesprocessed < 10) { - /* if the parser is known to be fragmented at this stage itself, - * we reset the stub buffer here itself */ - if (!dcerpc->pdu_fragged && (dcerpc->dcerpchdr.pfc_flags & PFC_FIRST_FRAG)) { - DCERPCResetStub(dcerpc); - } - dcerpc->pdu_fragged = 1; - } else { - if (dcerpc->bytesprocessed >= dcerpc->dcerpchdr.frag_length) { - SCLogDebug("Weird DCE PDU"); - DCERPCResetParsingState(dcerpc); - } else { - /* if the parser is known to be fragmented at this stage itself, - * we reset the stub buffer here itself */ - if (!dcerpc->pdu_fragged && (dcerpc->dcerpchdr.pfc_flags & PFC_FIRST_FRAG)) { - DCERPCResetStub(dcerpc); - } - dcerpc->pdu_fragged = 1; - } - } - SCReturnInt(parsed); - } - switch (dcerpc->dcerpchdr.type) { - case BIND: - case ALTER_CONTEXT: - while (dcerpc->bytesprocessed < DCERPC_HDR_LEN + 12 - && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length - && input_len) { - retval = DCERPCParseBIND(dcerpc, input + parsed, input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - } else if (input_len) { - SCLogDebug("Error Parsing DCERPC %s PDU", - (dcerpc->dcerpchdr.type == BIND) ? - "BIND" : "ALTER_CONTEXT"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } - SCLogDebug("Done with DCERPCParseBIND bytesprocessed %u/%u numctxitems %u", - dcerpc->bytesprocessed, dcerpc->dcerpchdr.frag_length, - dcerpc->dcerpcbindbindack.numctxitems); - while (dcerpc->dcerpcbindbindack.numctxitemsleft && dcerpc->bytesprocessed - < dcerpc->dcerpchdr.frag_length && input_len) { - retval = DCERPCParseBINDCTXItem(dcerpc, input + parsed, input_len); - if (retval && retval <= input_len) { - if (dcerpc->dcerpcbindbindack.ctxbytesprocessed == 44) { - dcerpc->dcerpcbindbindack.ctxbytesprocessed = 0; - } - parsed += retval; - input_len -= retval; - SCLogDebug("BIND processed %u/%u ctxitems %u/%u input_len left %u\n", - dcerpc->bytesprocessed, - dcerpc->dcerpchdr.frag_length, - dcerpc->dcerpcbindbindack.numctxitemsleft, - dcerpc->dcerpcbindbindack.numctxitems, input_len); - } else if (input_len) { - //parsed -= input_len; - SCLogDebug("Error Parsing CTX Item %u\n", parsed); - parsed = 0; - input_len = 0; - dcerpc->dcerpcbindbindack.numctxitemsleft = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); - } else if (dcerpc->bytesprocessed > dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } else { - /* temporary fix */ - if (input_len) { - retval = DCERPCThrowOutExtraData(dcerpc, input + parsed, - input_len); - if (retval && retval <= input_len) { - input_len -= retval; - parsed += retval; - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); - } else { - dcerpc->pdu_fragged = 1; - } - } else { - SCLogDebug("Error Parsing DCERPC"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } else { - dcerpc->pdu_fragged = 1; - } - } - break; - - case BIND_ACK: - case ALTER_CONTEXT_RESP: - while (dcerpc->bytesprocessed < DCERPC_HDR_LEN + 9 - && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length - && input_len) { - retval = DCERPCParseBINDACK(dcerpc, input + parsed, input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - SCLogDebug("DCERPCParseBINDACK processed %u/%u input_len left %u", - dcerpc->bytesprocessed, - dcerpc->dcerpchdr.frag_length, input_len); - } else if (input_len) { - SCLogDebug("Error parsing %s\n", - (dcerpc->dcerpchdr.type == BIND_ACK) ? - "BIND_ACK" : "ALTER_CONTEXT_RESP"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } - - while (dcerpc->bytesprocessed < DCERPC_HDR_LEN + 10 - + dcerpc->dcerpcbindbindack.secondaryaddrlen - && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { - retval = DCERPCParseSecondaryAddr(dcerpc, input + parsed, input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - SCLogDebug("DCERPCParseSecondaryAddr %u/%u left %u secondaryaddr len(%u)", - dcerpc->bytesprocessed, dcerpc->dcerpchdr.frag_length, input_len, - dcerpc->dcerpcbindbindack.secondaryaddrlen); - } else if (input_len) { - SCLogDebug("Error parsing Secondary Address"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } - - if (dcerpc->bytesprocessed == DCERPC_HDR_LEN + 10 - + dcerpc->dcerpcbindbindack.secondaryaddrlen) { - if (dcerpc->bytesprocessed % 4) { - dcerpc->pad = (4 - dcerpc->bytesprocessed % 4); - dcerpc->padleft = dcerpc->pad; - } - } - - while (dcerpc->bytesprocessed < DCERPC_HDR_LEN + 10 - + dcerpc->dcerpcbindbindack.secondaryaddrlen + dcerpc->pad - && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { - retval = PaddingParser(dcerpc, input + parsed, input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - SCLogDebug("PaddingParser %u/%u left %u pad(%u)", - dcerpc->bytesprocessed, dcerpc->dcerpchdr.frag_length, input_len, - dcerpc->pad); - } else if (input_len) { - SCLogDebug("Error parsing DCERPC Padding"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } - - while (dcerpc->bytesprocessed >= DCERPC_HDR_LEN + 10 + dcerpc->pad - + dcerpc->dcerpcbindbindack.secondaryaddrlen && dcerpc->bytesprocessed - < DCERPC_HDR_LEN + 14 + dcerpc->pad + dcerpc->dcerpcbindbindack.secondaryaddrlen - && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { - retval = DCERPCGetCTXItems(dcerpc, input + parsed, input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - SCLogDebug("DCERPCGetCTXItems %u/%u (%u)", dcerpc->bytesprocessed, - dcerpc->dcerpchdr.frag_length, dcerpc->dcerpcbindbindack.numctxitems); - } else if (input_len) { - SCLogDebug("Error parsing CTX Items"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } - - if (dcerpc->bytesprocessed == DCERPC_HDR_LEN + 14 + dcerpc->pad - + dcerpc->dcerpcbindbindack.secondaryaddrlen) { - dcerpc->dcerpcbindbindack.ctxbytesprocessed = 0; - } - - while (dcerpc->dcerpcbindbindack.numctxitemsleft && dcerpc->bytesprocessed - < dcerpc->dcerpchdr.frag_length && input_len) { - retval = DCERPCParseBINDACKCTXItem(dcerpc, input + parsed, input_len); - if (retval && retval <= input_len) { - if (dcerpc->dcerpcbindbindack.ctxbytesprocessed == 24) { - dcerpc->dcerpcbindbindack.ctxbytesprocessed = 0; - } - parsed += retval; - input_len -= retval; - } else if (input_len) { - SCLogDebug("Error parsing CTX Items"); - parsed = 0; - input_len = 0; - dcerpc->dcerpcbindbindack.numctxitemsleft = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } - SCLogDebug("BINDACK processed %u/%u input_len left %u", - dcerpc->bytesprocessed, - dcerpc->dcerpchdr.frag_length, input_len); - - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - /* response and request done */ - if (dcerpc->dcerpchdr.type == BIND_ACK) { - /* update transaction id */ - dcerpc->transaction_id++; - SCLogDebug("transaction_id updated to %"PRIu16, - dcerpc->transaction_id); - } - DCERPCResetParsingState(dcerpc); - } else if (dcerpc->bytesprocessed > dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } else { - /* temporary fix */ - if (input_len) { - retval = DCERPCThrowOutExtraData(dcerpc, input + parsed, - input_len); - if (retval && retval <= input_len) { - input_len -= retval; - parsed += retval; - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); - } else { - dcerpc->pdu_fragged = 1; - } - } else { - SCLogDebug("Error Parsing DCERPC"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } else { - dcerpc->pdu_fragged = 1; - } - } - break; - - case REQUEST: - case RESPONSE: - while (dcerpc->bytesprocessed < DCERPC_HDR_LEN + 8 - && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length - && input_len) { - retval = DCERPCParseREQUEST(dcerpc, input + parsed, input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - dcerpc->padleft = dcerpc->dcerpchdr.frag_length - dcerpc->bytesprocessed; - } else if (input_len) { - SCLogDebug("Error parsing DCERPC %s", - (dcerpc->dcerpchdr.type == REQUEST) ? "REQUEST" : "RESPONSE"); - parsed = 0; - dcerpc->padleft = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } - - while (dcerpc->bytesprocessed >= DCERPC_HDR_LEN + 8 - && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length - && dcerpc->padleft && input_len) { - retval = StubDataParser(dcerpc, input + parsed, input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - } else if (input_len) { - SCLogDebug("Error parsing DCERPC Stub Data"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } - - if (dcerpc->dcerpchdr.type == REQUEST) { - SCLogDebug("REQUEST processed %u frag length %u opnum %u input_len %u", dcerpc->bytesprocessed, - dcerpc->dcerpchdr.frag_length, dcerpc->dcerpcrequest.opnum, input_len); - } else { - SCLogDebug("RESPONSE processed %u frag length %u opnum %u input_len %u", dcerpc->bytesprocessed, - dcerpc->dcerpchdr.frag_length, dcerpc->dcerpcrequest.opnum, input_len); - } - - /* don't see how we could break the parser for request pdus, by - * pusing bytesprocessed beyond frag_length. Let's have the - * check anyways */ - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); - } else if (dcerpc->bytesprocessed > dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } else { - if (!dcerpc->pdu_fragged && - (dcerpc->dcerpchdr.pfc_flags & PFC_FIRST_FRAG)) { - DCERPCResetStub(dcerpc); - } - /* temporary fix */ - if (input_len) { - retval = DCERPCThrowOutExtraData(dcerpc, input + parsed, - input_len); - if (retval && retval <= input_len) { - input_len -= retval; - parsed += retval; - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); - } else { - dcerpc->pdu_fragged = 1; - } - } else { - SCLogDebug("Error Parsing DCERPC"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - } else { - dcerpc->pdu_fragged = 1; - } - } - - /* response and request done */ - if (dcerpc->dcerpchdr.type == RESPONSE) { - /* update transaction id */ - dcerpc->transaction_id++; - SCLogDebug("transaction_id updated to %"PRIu16, - dcerpc->transaction_id); - } - break; - - default: - SCLogDebug("DCERPC Type 0x%02x not implemented yet", dcerpc->dcerpchdr.type); - retval = DCERPCThrowOutExtraData(dcerpc, input + parsed, - input_len); - if (retval && retval <= input_len) { - input_len -= retval; - parsed += retval; - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); - } else { - dcerpc->pdu_fragged = 1; - } - } else { - SCLogDebug("Error Parsing DCERPC"); - parsed = 0; - input_len = 0; - DCERPCResetParsingState(dcerpc); - SCReturnInt(0); - } - break; - } - } - - SCReturnInt(parsed); -} - -static int DCERPCParse(Flow *f, void *dcerpc_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data, int dir) -{ - SCEnter(); - - int32_t retval = 0; - DCERPCState *sstate = (DCERPCState *) dcerpc_state; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - if (sstate->dcerpc.bytesprocessed != 0 && sstate->data_needed_for_dir != dir) { - SCReturnInt(-1); - } - - retval = DCERPCParser(&sstate->dcerpc, input, input_len); - if (retval == -1) { - SCReturnInt(0); - } - - sstate->data_needed_for_dir = dir; - - if (pstate == NULL) - SCReturnInt(-1); - - SCReturnInt(1); -} - -static int DCERPCParseRequest(Flow *f, void *dcerpc_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - return DCERPCParse(f, dcerpc_state, pstate, input, input_len, - local_data, 0); -} - -static int DCERPCParseResponse(Flow *f, void *dcerpc_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - return DCERPCParse(f, dcerpc_state, pstate, input, input_len, - local_data, 1); -} - -static void *DCERPCStateAlloc(void) -{ - SCEnter(); - - DCERPCState *s = SCMalloc(sizeof(DCERPCState)); - if (unlikely(s == NULL)) { - SCReturnPtr(NULL, "void"); - } - memset(s, 0, sizeof(DCERPCState)); - - s->dcerpc.transaction_id = 1; - - SCReturnPtr((void *)s, "void"); -} - -static void DCERPCStateFree(void *s) -{ - DCERPCState *sstate = (DCERPCState *) s; - - DCERPCUuidEntry *item; - - while ((item = TAILQ_FIRST(&sstate->dcerpc.dcerpcbindbindack.uuid_list))) { - //printUUID("Free", item); - TAILQ_REMOVE(&sstate->dcerpc.dcerpcbindbindack.uuid_list, item, next); - SCFree(item); - } - - while ((item = TAILQ_FIRST(&sstate->dcerpc.dcerpcbindbindack.accepted_uuid_list))) { - //printUUID("Free", item); - TAILQ_REMOVE(&sstate->dcerpc.dcerpcbindbindack.accepted_uuid_list, item, next); - SCFree(item); - } - - if (sstate->dcerpc.dcerpcrequest.stub_data_buffer != NULL) { - SCFree(sstate->dcerpc.dcerpcrequest.stub_data_buffer); - sstate->dcerpc.dcerpcrequest.stub_data_buffer = NULL; - sstate->dcerpc.dcerpcrequest.stub_data_buffer_len = 0; - } - if (sstate->dcerpc.dcerpcresponse.stub_data_buffer != NULL) { - SCFree(sstate->dcerpc.dcerpcresponse.stub_data_buffer); - sstate->dcerpc.dcerpcresponse.stub_data_buffer = NULL; - sstate->dcerpc.dcerpcresponse.stub_data_buffer_len = 0; - } - - SCFree(s); -} - -static int DCERPCRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_DCERPC, - "|05 00|", 2, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_DCERPC, - "|05 00|", 2, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - - return 0; -} - -void RegisterDCERPCParsers(void) -{ - char *proto_name = "dcerpc"; - - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_DCERPC, proto_name); - if (DCERPCRegisterPatternsForProtocolDetection() < 0) - return; - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - proto_name); - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_DCERPC, STREAM_TOSERVER, - DCERPCParseRequest); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_DCERPC, STREAM_TOCLIENT, - DCERPCParseResponse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCStateAlloc, - DCERPCStateFree); - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_DCERPC, STREAM_TOSERVER); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_DCERPC, DCERPCParserRegisterTests); -#endif - - return; -} - -/* UNITTESTS */ -#ifdef UNITTESTS -/** \test DCERPC Header Parsing and BIND / BIND_ACK multiple UUID handling -*/ - -/* set this to 1 to see problem */ - -int DCERPCParserTest01(void) -{ - int result = 1; - Flow f; - uint8_t dcerpcbind[] = { - 0x05, 0x00, - 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x3c, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x16, - 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2c, 0xd0, - 0x28, 0xda, 0x76, 0x91, 0xf6, 0x6e, 0xcb, 0x0f, - 0xbf, 0x85, 0xcd, 0x9b, 0xf6, 0x39, 0x01, 0x00, - 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x2c, 0x75, 0xce, 0x7e, 0x82, 0x3b, - 0x06, 0xac, 0x1b, 0xf0, 0xf5, 0xb7, 0xa7, 0xf7, - 0x28, 0xaf, 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0xe3, 0xb2, - 0x10, 0xd1, 0xd0, 0x0c, 0xcc, 0x3d, 0x2f, 0x80, - 0x20, 0x7c, 0xef, 0xe7, 0x09, 0xe0, 0x04, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, - 0x01, 0x00, 0xde, 0x85, 0x70, 0xc4, 0x02, 0x7c, - 0x60, 0x23, 0x67, 0x0c, 0x22, 0xbf, 0x18, 0x36, - 0x79, 0x17, 0x01, 0x00, 0x02, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x41, 0x65, - 0x29, 0x51, 0xaa, 0xe7, 0x7b, 0xa8, 0xf2, 0x37, - 0x0b, 0xd0, 0x3f, 0xb3, 0x36, 0xed, 0x05, 0x00, - 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, - 0x01, 0x00, 0x14, 0x96, 0x80, 0x01, 0x2e, 0x78, - 0xfb, 0x5d, 0xb4, 0x3c, 0x14, 0xb3, 0x3d, 0xaa, - 0x02, 0xfb, 0x06, 0x00, 0x00, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x3b, 0x04, - 0x68, 0x3e, 0x63, 0xfe, 0x9f, 0xd8, 0x64, 0x55, - 0xcd, 0xe7, 0x39, 0xaf, 0x98, 0x9f, 0x03, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, - 0x01, 0x00, 0x16, 0x7a, 0x4f, 0x1b, 0xdb, 0x25, - 0x92, 0x55, 0xdd, 0xae, 0x9e, 0x5b, 0x3e, 0x93, - 0x66, 0x93, 0x04, 0x00, 0x01, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0xe8, 0xa4, - 0x8a, 0xcf, 0x95, 0x6c, 0xc7, 0x8f, 0x14, 0xcc, - 0x56, 0xfc, 0x7b, 0x5f, 0x4f, 0xe8, 0x04, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x01, 0x00, 0xd8, 0xda, 0xfb, 0xbc, 0xa2, 0x55, - 0x6f, 0x5d, 0xc0, 0x2d, 0x88, 0x6f, 0x00, 0x17, - 0x52, 0x8d, 0x06, 0x00, 0x03, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x3f, 0x17, - 0x55, 0x0c, 0xf4, 0x23, 0x3c, 0xca, 0xe6, 0xa0, - 0xaa, 0xcc, 0xb5, 0xe3, 0xf9, 0xce, 0x04, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, - 0x01, 0x00, 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, - 0xd0, 0x11, 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, - 0x2e, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0xc9, 0x9f, - 0x3e, 0x6e, 0x82, 0x0a, 0x2b, 0x28, 0x37, 0x78, - 0xe1, 0x13, 0x70, 0x05, 0x38, 0x4d, 0x01, 0x00, - 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x01, 0x00, 0x11, 0xaa, 0x4b, 0x15, 0xdf, 0xa6, - 0x86, 0x3f, 0xfb, 0xe0, 0x09, 0xb7, 0xf8, 0x56, - 0xd2, 0x3f, 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x0e, 0x00, 0x01, 0x00, 0xee, 0x99, - 0xc4, 0x25, 0x11, 0xe4, 0x95, 0x62, 0x29, 0xfa, - 0xfd, 0x26, 0x57, 0x02, 0xf1, 0xce, 0x03, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x01, 0x00, 0xba, 0x81, 0x9e, 0x1a, 0xdf, 0x2b, - 0xba, 0xe4, 0xd3, 0x17, 0x41, 0x60, 0x6d, 0x2d, - 0x9e, 0x28, 0x03, 0x00, 0x03, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0xa0, 0x24, - 0x03, 0x9a, 0xa9, 0x99, 0xfb, 0xbe, 0x49, 0x11, - 0xad, 0x77, 0x30, 0xaa, 0xbc, 0xb6, 0x02, 0x00, - 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x01, 0x00, 0x32, 0x04, 0x7e, 0xae, 0xec, 0x28, - 0xd1, 0x55, 0x83, 0x4e, 0xc3, 0x47, 0x5d, 0x1d, - 0xc6, 0x65, 0x02, 0x00, 0x03, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x12, 0x00, 0x01, 0x00, 0xc6, 0xa4, - 0x81, 0x48, 0x66, 0x2a, 0x74, 0x7d, 0x56, 0x6e, - 0xc5, 0x1d, 0x19, 0xf2, 0xb5, 0xb6, 0x03, 0x00, - 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, - 0x01, 0x00, 0xcb, 0xae, 0xb3, 0xc0, 0x0c, 0xf4, - 0xa4, 0x5e, 0x91, 0x72, 0xdd, 0x53, 0x24, 0x70, - 0x89, 0x02, 0x05, 0x00, 0x03, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x01, 0x00, 0xb8, 0xd0, - 0xa0, 0x1a, 0x5e, 0x7a, 0x2d, 0xfe, 0x35, 0xc6, - 0x7d, 0x08, 0x0d, 0x33, 0x73, 0x18, 0x02, 0x00, - 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, - 0x01, 0x00, 0x21, 0xd3, 0xaa, 0x09, 0x03, 0xa7, - 0x0b, 0xc2, 0x06, 0x45, 0xd9, 0x6c, 0x75, 0xc2, - 0x15, 0xa8, 0x01, 0x00, 0x03, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x16, 0x00, 0x01, 0x00, 0xe1, 0xbd, - 0x59, 0xfc, 0xbc, 0xa9, 0x95, 0xc2, 0x68, 0x79, - 0xf3, 0x75, 0xe0, 0xae, 0x6c, 0xe5, 0x04, 0x00, - 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x17, 0x00, - 0x01, 0x00, 0x06, 0x52, 0xb4, 0x71, 0x70, 0x15, - 0x4e, 0xf5, 0x7f, 0x08, 0x86, 0x14, 0xe6, 0x17, - 0xd5, 0x97, 0x04, 0x00, 0x00, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00}; - - uint8_t dcerpcbindack[] = { - 0x05, 0x00, 0x0c, 0x03, - 0x10, 0x00, 0x00, 0x00, 0x6c, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xb8, 0x10, 0xb8, 0x10, - 0xce, 0x47, 0x00, 0x00, 0x0c, 0x00, 0x5c, 0x50, - 0x49, 0x50, 0x45, 0x5c, 0x6c, 0x73, 0x61, 0x73, - 0x73, 0x00, 0xf6, 0x6e, 0x18, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - uint8_t dcerpcrequest[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x0b, - 0x00, 0x09, 0x00, 0x45, 0x00, 0x2c, 0x00, 0x4d, - 0x00, 0x73, 0x00, 0x53, 0x00, 0x59, 0x00, 0x2a, - 0x00, 0x4a, 0x00, 0x7a, 0x00, 0x3e, 0x00, 0x58, - 0x00, 0x21, 0x00, 0x4a, 0x00, 0x30, 0x00, 0x41, - 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x3c, 0x00, 0x48, - 0x00, 0x24, 0x00, 0x38, 0x00, 0x54, 0x00, 0x60, - 0x00, 0x2d, 0x00, 0x29, 0x00, 0x64, 0x00, 0x5b, - 0x00, 0x77, 0x00, 0x3a, 0x00, 0x4c, 0x00, 0x24, - 0x00, 0x23, 0x00, 0x66, 0x00, 0x43, 0x00, 0x68, - 0x00, 0x22, 0x00, 0x55, 0x00, 0x29, 0x00, 0x2c, - 0x00, 0x4f, 0x00, 0x5a, 0x00, 0x50, 0x00, 0x61, - 0x00, 0x2a, 0x00, 0x6f, 0x00, 0x2f, 0x00, 0x4d, - 0x00, 0x68, 0x00, 0x3a, 0x00, 0x5c, 0x00, 0x67, - 0x00, 0x68, 0x00, 0x68, 0x00, 0x49, 0x00, 0x45, - 0x00, 0x4c, 0x00, 0x72, 0x00, 0x53, 0x00, 0x4c, - 0x00, 0x25, 0x00, 0x4d, 0x00, 0x67, 0x00, 0x2e, - 0x00, 0x4f, 0x00, 0x64, 0x00, 0x61, 0x00, 0x73, - 0x00, 0x24, 0x00, 0x46, 0x00, 0x35, 0x00, 0x2e, - 0x00, 0x45, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x41, - 0x00, 0x33, 0x00, 0x38, 0x00, 0x47, 0x00, 0x71, - 0x00, 0x5a, 0x00, 0x37, 0x00, 0x7a, 0x00, 0x35, - 0x00, 0x6b, 0x00, 0x3c, 0x00, 0x26, 0x00, 0x37, - 0x00, 0x69, 0x00, 0x75, 0x00, 0x36, 0x00, 0x37, - 0x00, 0x47, 0x00, 0x21, 0x00, 0x2d, 0x00, 0x69, - 0x00, 0x37, 0x00, 0x78, 0x00, 0x5f, 0x00, 0x72, - 0x00, 0x4b, 0x00, 0x5c, 0x00, 0x74, 0x00, 0x3e, - 0x00, 0x52, 0x00, 0x7a, 0x00, 0x49, 0x00, 0x31, - 0x00, 0x5a, 0x00, 0x7b, 0x00, 0x29, 0x00, 0x3b, - 0x00, 0x78, 0x00, 0x3b, 0x00, 0x55, 0x00, 0x3e, - 0x00, 0x35, 0x00, 0x2b, 0x00, 0x4e, 0x00, 0x4f, - 0x00, 0x59, 0x00, 0x38, 0x00, 0x2a, 0x00, 0x59, - 0x00, 0x6b, 0x00, 0x42, 0x00, 0x4c, 0x00, 0x3e, - 0x00, 0x6a, 0x00, 0x49, 0x00, 0x2c, 0x00, 0x79, - 0x00, 0x6e, 0x00, 0x35, 0x00, 0x4f, 0x00, 0x49, - 0x00, 0x55, 0x00, 0x35, 0x00, 0x61, 0x00, 0x72, - 0x00, 0x77, 0x00, 0x38, 0x00, 0x32, 0x00, 0x24, - 0x00, 0x46, 0x00, 0x32, 0x00, 0x32, 0x00, 0x27, - 0x00, 0x64, 0x00, 0x5a, 0x00, 0x77, 0x00, 0x2e, - 0x00, 0x37, 0x00, 0x77, 0x00, 0x2e, 0x00, 0x28, - 0x00, 0x63, 0x00, 0x4f, 0x00, 0x67, 0x00, 0x64, - 0x00, 0x39, 0x00, 0x37, 0x00, 0x31, 0x00, 0x30, - 0x00, 0x28, 0x00, 0x2e, 0x00, 0x6f, 0x00, 0x3e, - 0x00, 0x59, 0x00, 0x28, 0x00, 0x67, 0x00, 0x52, - 0x00, 0x35, 0x00, 0x5a, 0x00, 0x7c, 0x00, 0x56, - 0x00, 0x6a, 0x00, 0x5c, 0x00, 0x3c, 0x00, 0x30, - 0x00, 0x59, 0x00, 0x5c, 0x00, 0x5e, 0x00, 0x38, - 0x00, 0x54, 0x00, 0x5c, 0x00, 0x5b, 0x00, 0x42, - 0x00, 0x62, 0x00, 0x70, 0x00, 0x34, 0x00, 0x5c, - 0x00, 0x57, 0x00, 0x7a, 0x00, 0x4b, 0x00, 0x2f, - 0x00, 0x6b, 0x00, 0x6a, 0x00, 0x4f, 0x00, 0x41, - 0x00, 0x33, 0x00, 0x52, 0x00, 0x36, 0x00, 0x27, - 0x00, 0x30, 0x00, 0x6d, 0x00, 0x4a, 0x00, 0x30, - 0x00, 0x78, 0x00, 0x46, 0x00, 0x65, 0x00, 0x4e, - 0x00, 0x29, 0x00, 0x66, 0x00, 0x3f, 0x00, 0x72, - 0x00, 0x71, 0x00, 0x75, 0x00, 0x4c, 0x00, 0x2b, - 0x00, 0x5c, 0x00, 0x46, 0x00, 0x52, 0x00, 0x7b, - 0x00, 0x5c, 0x00, 0x69, 0x00, 0x66, 0x00, 0x56, - 0x00, 0x31, 0x00, 0x2d, 0x00, 0x72, 0x00, 0x61, - 0x00, 0x68, 0x00, 0x28, 0x00, 0x7d, 0x00, 0x58, - 0x00, 0x2a, 0x00, 0x7b, 0x00, 0x28, 0x00, 0x5b, - 0x00, 0x54, 0x00, 0x3a, 0x00, 0x26, 0x00, 0x52, - 0x00, 0x44, 0x00, 0x60, 0x00, 0x50, 0x00, 0x65, - 0x00, 0x48, 0x00, 0x7d, 0x00, 0x2a, 0x00, 0x74, - 0x00, 0x49, 0x00, 0x7b, 0x00, 0x21, 0x00, 0x61, - 0x00, 0x52, 0x00, 0x43, 0x00, 0x5f, 0x00, 0x5a, - 0x00, 0x74, 0x00, 0x5c, 0x00, 0x62, 0x00, 0x68, - 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x2b, 0x00, 0x6f, - 0x00, 0x7c, 0x00, 0x42, 0x00, 0x67, 0x00, 0x32, - 0x00, 0x58, 0x00, 0x35, 0x00, 0x30, 0x00, 0x2f, - 0x00, 0x2d, 0x00, 0x60, 0x00, 0x62, 0x00, 0x51, - 0x00, 0x2a, 0x00, 0x30, 0x00, 0x31, 0x00, 0x48, - 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x5d, 0x00, 0x25, - 0x00, 0x58, 0x00, 0x4a, 0x00, 0x76, 0x00, 0x32, - 0x00, 0x62, 0x00, 0x27, 0x00, 0x42, 0x00, 0x40, - 0x00, 0x53, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x50, - 0x00, 0x3d, 0x00, 0x40, 0x00, 0x76, 0x00, 0x38, - 0x00, 0x58, 0x00, 0x39, 0x00, 0x63, 0x00, 0x3c, - 0x00, 0x5b, 0x00, 0x23, 0x00, 0x53, 0x00, 0x7a, - 0x00, 0x54, 0x00, 0x74, 0x00, 0x61, 0x00, 0x76, - 0x00, 0x4a, 0x00, 0x3e, 0x00, 0x33, 0x00, 0x75, - 0x00, 0x66, 0x00, 0x2d, 0x00, 0x48, 0x00, 0x33, - 0x00, 0x71, 0x00, 0x76, 0x00, 0x48, 0x00, 0x71, - 0x00, 0x41, 0x00, 0x6f, 0x00, 0x2a, 0x00, 0x67, - 0x00, 0x70, 0x00, 0x21, 0x00, 0x70, 0x00, 0x4b, - 0x00, 0x52, 0x00, 0x58, 0x00, 0x68, 0x00, 0x23, - 0x00, 0x39, 0x00, 0x46, 0x00, 0x4d, 0x00, 0x51, - 0x00, 0x57, 0x00, 0x3a, 0x00, 0x79, 0x00, 0x7b, - 0x00, 0x6c, 0x00, 0x55, 0x00, 0x33, 0x00, 0x65, - 0x00, 0x49, 0x00, 0x72, 0x00, 0x30, 0x00, 0x4f, - 0x00, 0x41, 0x00, 0x6e, 0x00, 0x31, 0x00, 0x4a, - 0x00, 0x60, 0x00, 0x79, 0x00, 0x70, 0x00, 0x4f, - 0x00, 0x58, 0x00, 0x75, 0x00, 0x44, 0x00, 0x59, - 0x00, 0x58, 0x00, 0x46, 0x00, 0x3d, 0x00, 0x46, - 0x00, 0x74, 0x00, 0x51, 0x00, 0x57, 0x00, 0x6e, - 0x00, 0x2d, 0x00, 0x47, 0x00, 0x23, 0x00, 0x45, - 0x00, 0x60, 0x00, 0x4c, 0x00, 0x72, 0x00, 0x4e, - 0x00, 0x74, 0x00, 0x40, 0x00, 0x76, 0x00, 0x75, - 0x00, 0x74, 0x00, 0x56, 0x00, 0x44, 0x00, 0x29, - 0x00, 0x62, 0x00, 0x58, 0x00, 0x31, 0x00, 0x78, - 0x00, 0x32, 0x00, 0x52, 0x00, 0x4a, 0x00, 0x6b, - 0x00, 0x55, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6f, - 0x00, 0x4a, 0x00, 0x54, 0x00, 0x7d, 0x00, 0x68, - 0x00, 0x3f, 0x00, 0x28, 0x00, 0x21, 0x00, 0x53, - 0x00, 0x48, 0x00, 0x5a, 0x00, 0x34, 0x00, 0x36, - 0x00, 0x35, 0x00, 0x64, 0x00, 0x4e, 0x00, 0x75, - 0x00, 0x69, 0x00, 0x23, 0x00, 0x75, 0x00, 0x55, - 0x00, 0x43, 0x00, 0x75, 0x00, 0x2f, 0x00, 0x73, - 0x00, 0x62, 0x00, 0x6f, 0x00, 0x37, 0x00, 0x4e, - 0x00, 0x25, 0x00, 0x25, 0x00, 0x21, 0x00, 0x3d, - 0x00, 0x3c, 0x00, 0x71, 0x00, 0x3e, 0x00, 0x3f, - 0x00, 0x30, 0x00, 0x36, 0x00, 0x62, 0x00, 0x63, - 0x00, 0x53, 0x00, 0x54, 0x00, 0x5d, 0x00, 0x61, - 0x00, 0x4c, 0x00, 0x28, 0x00, 0x2b, 0x00, 0x4c, - 0x00, 0x4e, 0x00, 0x66, 0x00, 0x5f, 0x00, 0x4b, - 0x00, 0x43, 0x00, 0x75, 0x00, 0x45, 0x00, 0x37, - 0x00, 0x28, 0x00, 0x56, 0x00, 0x36, 0x00, 0x6a, - 0x00, 0x3e, 0x00, 0x64, 0x00, 0x34, 0x00, 0x6a, - 0x00, 0x7d, 0x00, 0x4a, 0x00, 0x66, 0x00, 0x7a, - 0x00, 0x3e, 0x00, 0x75, 0x00, 0x38, 0x00, 0x7b, - 0x00, 0x42, 0x00, 0x76, 0x00, 0x29, 0x00, 0x4c, - 0x00, 0x65, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x4b, - 0x00, 0x2b, 0x00, 0x51, 0x00, 0x47, 0x00, 0x22, - 0x00, 0x48, 0x00, 0x3d, 0x00, 0x49, 0x00, 0x44, - 0x00, 0x5d, 0x00, 0x59, 0x00, 0x63, 0x00, 0x5c, - 0x00, 0x24, 0x00, 0x35, 0x00, 0x34, 0x00, 0x70, - 0x00, 0x69, 0x00}; - uint32_t requestlen = sizeof(dcerpcrequest); - - uint32_t bindlen = sizeof(dcerpcbind); - uint32_t bindacklen = sizeof(dcerpcbindack); - TcpSession ssn; - DCERPCUuidEntry *uuid_entry; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_START, dcerpcbind, bindlen); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdr.rpc_vers != 5) { - printf("expected dcerpc version 0x05, got 0x%02x : ", - dcerpc_state->dcerpc.dcerpchdr.rpc_vers); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdr.type != BIND) { - printf("expected dcerpc type 0x%02x , got 0x%02x : ", BIND, dcerpc_state->dcerpc.dcerpchdr.type); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdr.frag_length != 1084) { - printf("expected dcerpc frag_length 0x%02x , got 0x%02x : ", 1084, dcerpc_state->dcerpc.dcerpchdr.frag_length); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpcbindack, bindacklen); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (dcerpc_state->dcerpc.dcerpchdr.type != BIND_ACK) { - printf("expected dcerpc type 0x%02x , got 0x%02x : ", BIND_ACK, dcerpc_state->dcerpc.dcerpchdr.type); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdr.frag_length != 620) { - printf("expected dcerpc frag_length 0x%02x , got 0x%02x : ", 620, dcerpc_state->dcerpc.dcerpchdr.frag_length); - result = 0; - goto end; - } - TAILQ_FOREACH(uuid_entry, &dcerpc_state->dcerpc.dcerpcbindbindack.uuid_list, next) { - printUUID("BIND_ACK", uuid_entry); - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_EOF, dcerpcrequest, requestlen); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (dcerpc_state->dcerpc.dcerpchdr.type != REQUEST) { - printf("expected dcerpc type 0x%02x , got 0x%02x : ", REQUEST, dcerpc_state->dcerpc.dcerpchdr.type); - result = 0; - goto end; - } -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test DCERPC Request decoding and opnum parsing. -*/ -int DCERPCParserTest02(void) -{ - int result = 1; - Flow f; - uint8_t dcerpcrequest[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x0b, - 0x00, 0x09, 0x00, 0x45, 0x00, 0x2c, 0x00, 0x4d, - 0x00, 0x73, 0x00, 0x53, 0x00, 0x59, 0x00, 0x2a, - 0x00, 0x4a, 0x00, 0x7a, 0x00, 0x3e, 0x00, 0x58, - 0x00, 0x21, 0x00, 0x4a, 0x00, 0x30, 0x00, 0x41, - 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x3c, 0x00, 0x48, - 0x00, 0x24, 0x00, 0x38, 0x00, 0x54, 0x00, 0x60, - 0x00, 0x2d, 0x00, 0x29, 0x00, 0x64, 0x00, 0x5b, - 0x00, 0x77, 0x00, 0x3a, 0x00, 0x4c, 0x00, 0x24, - 0x00, 0x23, 0x00, 0x66, 0x00, 0x43, 0x00, 0x68, - 0x00, 0x22, 0x00, 0x55, 0x00, 0x29, 0x00, 0x2c, - 0x00, 0x4f, 0x00, 0x5a, 0x00, 0x50, 0x00, 0x61, - 0x00, 0x2a, 0x00, 0x6f, 0x00, 0x2f, 0x00, 0x4d, - 0x00, 0x68, 0x00, 0x3a, 0x00, 0x5c, 0x00, 0x67, - 0x00, 0x68, 0x00, 0x68, 0x00, 0x49, 0x00, 0x45, - 0x00, 0x4c, 0x00, 0x72, 0x00, 0x53, 0x00, 0x4c, - 0x00, 0x25, 0x00, 0x4d, 0x00, 0x67, 0x00, 0x2e, - 0x00, 0x4f, 0x00, 0x64, 0x00, 0x61, 0x00, 0x73, - 0x00, 0x24, 0x00, 0x46, 0x00, 0x35, 0x00, 0x2e, - 0x00, 0x45, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x41, - 0x00, 0x33, 0x00, 0x38, 0x00, 0x47, 0x00, 0x71, - 0x00, 0x5a, 0x00, 0x37, 0x00, 0x7a, 0x00, 0x35, - 0x00, 0x6b, 0x00, 0x3c, 0x00, 0x26, 0x00, 0x37, - 0x00, 0x69, 0x00, 0x75, 0x00, 0x36, 0x00, 0x37, - 0x00, 0x47, 0x00, 0x21, 0x00, 0x2d, 0x00, 0x69, - 0x00, 0x37, 0x00, 0x78, 0x00, 0x5f, 0x00, 0x72, - 0x00, 0x4b, 0x00, 0x5c, 0x00, 0x74, 0x00, 0x3e, - 0x00, 0x52, 0x00, 0x7a, 0x00, 0x49, 0x00, 0x31, - 0x00, 0x5a, 0x00, 0x7b, 0x00, 0x29, 0x00, 0x3b, - 0x00, 0x78, 0x00, 0x3b, 0x00, 0x55, 0x00, 0x3e, - 0x00, 0x35, 0x00, 0x2b, 0x00, 0x4e, 0x00, 0x4f, - 0x00, 0x59, 0x00, 0x38, 0x00, 0x2a, 0x00, 0x59, - 0x00, 0x6b, 0x00, 0x42, 0x00, 0x4c, 0x00, 0x3e, - 0x00, 0x6a, 0x00, 0x49, 0x00, 0x2c, 0x00, 0x79, - 0x00, 0x6e, 0x00, 0x35, 0x00, 0x4f, 0x00, 0x49, - 0x00, 0x55, 0x00, 0x35, 0x00, 0x61, 0x00, 0x72, - 0x00, 0x77, 0x00, 0x38, 0x00, 0x32, 0x00, 0x24, - 0x00, 0x46, 0x00, 0x32, 0x00, 0x32, 0x00, 0x27, - 0x00, 0x64, 0x00, 0x5a, 0x00, 0x77, 0x00, 0x2e, - 0x00, 0x37, 0x00, 0x77, 0x00, 0x2e, 0x00, 0x28, - 0x00, 0x63, 0x00, 0x4f, 0x00, 0x67, 0x00, 0x64, - 0x00, 0x39, 0x00, 0x37, 0x00, 0x31, 0x00, 0x30, - 0x00, 0x28, 0x00, 0x2e, 0x00, 0x6f, 0x00, 0x3e, - 0x00, 0x59, 0x00, 0x28, 0x00, 0x67, 0x00, 0x52, - 0x00, 0x35, 0x00, 0x5a, 0x00, 0x7c, 0x00, 0x56, - 0x00, 0x6a, 0x00, 0x5c, 0x00, 0x3c, 0x00, 0x30, - 0x00, 0x59, 0x00, 0x5c, 0x00, 0x5e, 0x00, 0x38, - 0x00, 0x54, 0x00, 0x5c, 0x00, 0x5b, 0x00, 0x42, - 0x00, 0x62, 0x00, 0x70, 0x00, 0x34, 0x00, 0x5c, - 0x00, 0x57, 0x00, 0x7a, 0x00, 0x4b, 0x00, 0x2f, - 0x00, 0x6b, 0x00, 0x6a, 0x00, 0x4f, 0x00, 0x41, - 0x00, 0x33, 0x00, 0x52, 0x00, 0x36, 0x00, 0x27, - 0x00, 0x30, 0x00, 0x6d, 0x00, 0x4a, 0x00, 0x30, - 0x00, 0x78, 0x00, 0x46, 0x00, 0x65, 0x00, 0x4e, - 0x00, 0x29, 0x00, 0x66, 0x00, 0x3f, 0x00, 0x72, - 0x00, 0x71, 0x00, 0x75, 0x00, 0x4c, 0x00, 0x2b, - 0x00, 0x5c, 0x00, 0x46, 0x00, 0x52, 0x00, 0x7b, - 0x00, 0x5c, 0x00, 0x69, 0x00, 0x66, 0x00, 0x56, - 0x00, 0x31, 0x00, 0x2d, 0x00, 0x72, 0x00, 0x61, - 0x00, 0x68, 0x00, 0x28, 0x00, 0x7d, 0x00, 0x58, - 0x00, 0x2a, 0x00, 0x7b, 0x00, 0x28, 0x00, 0x5b, - 0x00, 0x54, 0x00, 0x3a, 0x00, 0x26, 0x00, 0x52, - 0x00, 0x44, 0x00, 0x60, 0x00, 0x50, 0x00, 0x65, - 0x00, 0x48, 0x00, 0x7d, 0x00, 0x2a, 0x00, 0x74, - 0x00, 0x49, 0x00, 0x7b, 0x00, 0x21, 0x00, 0x61, - 0x00, 0x52, 0x00, 0x43, 0x00, 0x5f, 0x00, 0x5a, - 0x00, 0x74, 0x00, 0x5c, 0x00, 0x62, 0x00, 0x68, - 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x2b, 0x00, 0x6f, - 0x00, 0x7c, 0x00, 0x42, 0x00, 0x67, 0x00, 0x32, - 0x00, 0x58, 0x00, 0x35, 0x00, 0x30, 0x00, 0x2f, - 0x00, 0x2d, 0x00, 0x60, 0x00, 0x62, 0x00, 0x51, - 0x00, 0x2a, 0x00, 0x30, 0x00, 0x31, 0x00, 0x48, - 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x5d, 0x00, 0x25, - 0x00, 0x58, 0x00, 0x4a, 0x00, 0x76, 0x00, 0x32, - 0x00, 0x62, 0x00, 0x27, 0x00, 0x42, 0x00, 0x40, - 0x00, 0x53, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x50, - 0x00, 0x3d, 0x00, 0x40, 0x00, 0x76, 0x00, 0x38, - 0x00, 0x58, 0x00, 0x39, 0x00, 0x63, 0x00, 0x3c, - 0x00, 0x5b, 0x00, 0x23, 0x00, 0x53, 0x00, 0x7a, - 0x00, 0x54, 0x00, 0x74, 0x00, 0x61, 0x00, 0x76, - 0x00, 0x4a, 0x00, 0x3e, 0x00, 0x33, 0x00, 0x75, - 0x00, 0x66, 0x00, 0x2d, 0x00, 0x48, 0x00, 0x33, - 0x00, 0x71, 0x00, 0x76, 0x00, 0x48, 0x00, 0x71, - 0x00, 0x41, 0x00, 0x6f, 0x00, 0x2a, 0x00, 0x67, - 0x00, 0x70, 0x00, 0x21, 0x00, 0x70, 0x00, 0x4b, - 0x00, 0x52, 0x00, 0x58, 0x00, 0x68, 0x00, 0x23, - 0x00, 0x39, 0x00, 0x46, 0x00, 0x4d, 0x00, 0x51, - 0x00, 0x57, 0x00, 0x3a, 0x00, 0x79, 0x00, 0x7b, - 0x00, 0x6c, 0x00, 0x55, 0x00, 0x33, 0x00, 0x65, - 0x00, 0x49, 0x00, 0x72, 0x00, 0x30, 0x00, 0x4f, - 0x00, 0x41, 0x00, 0x6e, 0x00, 0x31, 0x00, 0x4a, - 0x00, 0x60, 0x00, 0x79, 0x00, 0x70, 0x00, 0x4f, - 0x00, 0x58, 0x00, 0x75, 0x00, 0x44, 0x00, 0x59, - 0x00, 0x58, 0x00, 0x46, 0x00, 0x3d, 0x00, 0x46, - 0x00, 0x74, 0x00, 0x51, 0x00, 0x57, 0x00, 0x6e, - 0x00, 0x2d, 0x00, 0x47, 0x00, 0x23, 0x00, 0x45, - 0x00, 0x60, 0x00, 0x4c, 0x00, 0x72, 0x00, 0x4e, - 0x00, 0x74, 0x00, 0x40, 0x00, 0x76, 0x00, 0x75, - 0x00, 0x74, 0x00, 0x56, 0x00, 0x44, 0x00, 0x29, - 0x00, 0x62, 0x00, 0x58, 0x00, 0x31, 0x00, 0x78, - 0x00, 0x32, 0x00, 0x52, 0x00, 0x4a, 0x00, 0x6b, - 0x00, 0x55, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6f, - 0x00, 0x4a, 0x00, 0x54, 0x00, 0x7d, 0x00, 0x68, - 0x00, 0x3f, 0x00, 0x28, 0x00, 0x21, 0x00, 0x53, - 0x00, 0x48, 0x00, 0x5a, 0x00, 0x34, 0x00, 0x36, - 0x00, 0x35, 0x00, 0x64, 0x00, 0x4e, 0x00, 0x75, - 0x00, 0x69, 0x00, 0x23, 0x00, 0x75, 0x00, 0x55, - 0x00, 0x43, 0x00, 0x75, 0x00, 0x2f, 0x00, 0x73, - 0x00, 0x62, 0x00, 0x6f, 0x00, 0x37, 0x00, 0x4e, - 0x00, 0x25, 0x00, 0x25, 0x00, 0x21, 0x00, 0x3d, - 0x00, 0x3c, 0x00, 0x71, 0x00, 0x3e, 0x00, 0x3f, - 0x00, 0x30, 0x00, 0x36, 0x00, 0x62, 0x00, 0x63, - 0x00, 0x53, 0x00, 0x54, 0x00, 0x5d, 0x00, 0x61, - 0x00, 0x4c, 0x00, 0x28, 0x00, 0x2b, 0x00, 0x4c, - 0x00, 0x4e, 0x00, 0x66, 0x00, 0x5f, 0x00, 0x4b, - 0x00, 0x43, 0x00, 0x75, 0x00, 0x45, 0x00, 0x37, - 0x00, 0x28, 0x00, 0x56, 0x00, 0x36, 0x00, 0x6a, - 0x00, 0x3e, 0x00, 0x64, 0x00, 0x34, 0x00, 0x6a, - 0x00, 0x7d, 0x00, 0x4a, 0x00, 0x66, 0x00, 0x7a, - 0x00, 0x3e, 0x00, 0x75, 0x00, 0x38, 0x00, 0x7b, - 0x00, 0x42, 0x00, 0x76, 0x00, 0x29, 0x00, 0x4c, - 0x00, 0x65, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x4b, - 0x00, 0x2b, 0x00, 0x51, 0x00, 0x47, 0x00, 0x22, - 0x00, 0x48, 0x00, 0x3d, 0x00, 0x49, 0x00, 0x44, - 0x00, 0x5d, 0x00, 0x59, 0x00, 0x63, 0x00, 0x5c, - 0x00, 0x24, 0x00, 0x35, 0x00, 0x34, 0x00, 0x70, - 0x00, 0x69, 0x00}; - uint32_t requestlen = sizeof(dcerpcrequest); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_START, dcerpcrequest, requestlen); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdr.rpc_vers != 5) { - printf("expected dcerpc version 0x05, got 0x%02x : ", - dcerpc_state->dcerpc.dcerpchdr.rpc_vers); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdr.type != REQUEST) { - printf("expected dcerpc type 0x%02x , got 0x%02x : ", REQUEST, dcerpc_state->dcerpc.dcerpchdr.type); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdr.frag_length != 1024) { - printf("expected dcerpc frag_length 0x%02x , got 0x%02x : ", 1024, dcerpc_state->dcerpc.dcerpchdr.frag_length); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 9) { - printf("expected dcerpc opnum 0x%02x , got 0x%02x : ", 9, dcerpc_state->dcerpc.dcerpcrequest.opnum); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test Test endianness handling -*/ -int DCERPCParserTest03(void) -{ - int result = 1; - Flow f; - uint8_t dcerpcrequest[] = { - 0x05, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x09, 0x45, 0x00, 0x2c, 0x00, 0x4d, - 0x00, 0x73, 0x00, 0x53, 0x00, 0x59, 0x00, 0x2a, - 0x00, 0x4a, 0x00, 0x7a, 0x00, 0x3e, 0x00, 0x58, - 0x00, 0x21, 0x00, 0x4a, 0x00, 0x30, 0x00, 0x41, - 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x3c, 0x00, 0x48, - 0x00, 0x24, 0x00, 0x38, 0x00, 0x54, 0x00, 0x60, - 0x00, 0x2d, 0x00, 0x29, 0x00, 0x64, 0x00, 0x5b, - 0x00, 0x77, 0x00, 0x3a, 0x00, 0x4c, 0x00, 0x24, - 0x00, 0x23, 0x00, 0x66, 0x00, 0x43, 0x00, 0x68, - 0x00, 0x22, 0x00, 0x55, 0x00, 0x29, 0x00, 0x2c, - 0x00, 0x4f, 0x00, 0x5a, 0x00, 0x50, 0x00, 0x61, - 0x00, 0x2a, 0x00, 0x6f, 0x00, 0x2f, 0x00, 0x4d, - 0x00, 0x68, 0x00, 0x3a, 0x00, 0x5c, 0x00, 0x67, - 0x00, 0x68, 0x00, 0x68, 0x00, 0x49, 0x00, 0x45, - 0x00, 0x4c, 0x00, 0x72, 0x00, 0x53, 0x00, 0x4c, - 0x00, 0x25, 0x00, 0x4d, 0x00, 0x67, 0x00, 0x2e, - 0x00, 0x4f, 0x00, 0x64, 0x00, 0x61, 0x00, 0x73, - 0x00, 0x24, 0x00, 0x46, 0x00, 0x35, 0x00, 0x2e, - 0x00, 0x45, 0x00, 0x6f, 0x00, 0x40, 0x00, 0x41, - 0x00, 0x33, 0x00, 0x38, 0x00, 0x47, 0x00, 0x71, - 0x00, 0x5a, 0x00, 0x37, 0x00, 0x7a, 0x00, 0x35, - 0x00, 0x6b, 0x00, 0x3c, 0x00, 0x26, 0x00, 0x37, - 0x00, 0x69, 0x00, 0x75, 0x00, 0x36, 0x00, 0x37, - 0x00, 0x47, 0x00, 0x21, 0x00, 0x2d, 0x00, 0x69, - 0x00, 0x37, 0x00, 0x78, 0x00, 0x5f, 0x00, 0x72, - 0x00, 0x4b, 0x00, 0x5c, 0x00, 0x74, 0x00, 0x3e, - 0x00, 0x52, 0x00, 0x7a, 0x00, 0x49, 0x00, 0x31, - 0x00, 0x5a, 0x00, 0x7b, 0x00, 0x29, 0x00, 0x3b, - 0x00, 0x78, 0x00, 0x3b, 0x00, 0x55, 0x00, 0x3e, - 0x00, 0x35, 0x00, 0x2b, 0x00, 0x4e, 0x00, 0x4f, - 0x00, 0x59, 0x00, 0x38, 0x00, 0x2a, 0x00, 0x59, - 0x00, 0x6b, 0x00, 0x42, 0x00, 0x4c, 0x00, 0x3e, - 0x00, 0x6a, 0x00, 0x49, 0x00, 0x2c, 0x00, 0x79, - 0x00, 0x6e, 0x00, 0x35, 0x00, 0x4f, 0x00, 0x49, - 0x00, 0x55, 0x00, 0x35, 0x00, 0x61, 0x00, 0x72, - 0x00, 0x77, 0x00, 0x38, 0x00, 0x32, 0x00, 0x24, - 0x00, 0x46, 0x00, 0x32, 0x00, 0x32, 0x00, 0x27, - 0x00, 0x64, 0x00, 0x5a, 0x00, 0x77, 0x00, 0x2e, - 0x00, 0x37, 0x00, 0x77, 0x00, 0x2e, 0x00, 0x28, - 0x00, 0x63, 0x00, 0x4f, 0x00, 0x67, 0x00, 0x64, - 0x00, 0x39, 0x00, 0x37, 0x00, 0x31, 0x00, 0x30, - 0x00, 0x28, 0x00, 0x2e, 0x00, 0x6f, 0x00, 0x3e, - 0x00, 0x59, 0x00, 0x28, 0x00, 0x67, 0x00, 0x52, - 0x00, 0x35, 0x00, 0x5a, 0x00, 0x7c, 0x00, 0x56, - 0x00, 0x6a, 0x00, 0x5c, 0x00, 0x3c, 0x00, 0x30, - 0x00, 0x59, 0x00, 0x5c, 0x00, 0x5e, 0x00, 0x38, - 0x00, 0x54, 0x00, 0x5c, 0x00, 0x5b, 0x00, 0x42, - 0x00, 0x62, 0x00, 0x70, 0x00, 0x34, 0x00, 0x5c, - 0x00, 0x57, 0x00, 0x7a, 0x00, 0x4b, 0x00, 0x2f, - 0x00, 0x6b, 0x00, 0x6a, 0x00, 0x4f, 0x00, 0x41, - 0x00, 0x33, 0x00, 0x52, 0x00, 0x36, 0x00, 0x27, - 0x00, 0x30, 0x00, 0x6d, 0x00, 0x4a, 0x00, 0x30, - 0x00, 0x78, 0x00, 0x46, 0x00, 0x65, 0x00, 0x4e, - 0x00, 0x29, 0x00, 0x66, 0x00, 0x3f, 0x00, 0x72, - 0x00, 0x71, 0x00, 0x75, 0x00, 0x4c, 0x00, 0x2b, - 0x00, 0x5c, 0x00, 0x46, 0x00, 0x52, 0x00, 0x7b, - 0x00, 0x5c, 0x00, 0x69, 0x00, 0x66, 0x00, 0x56, - 0x00, 0x31, 0x00, 0x2d, 0x00, 0x72, 0x00, 0x61, - 0x00, 0x68, 0x00, 0x28, 0x00, 0x7d, 0x00, 0x58, - 0x00, 0x2a, 0x00, 0x7b, 0x00, 0x28, 0x00, 0x5b, - 0x00, 0x54, 0x00, 0x3a, 0x00, 0x26, 0x00, 0x52, - 0x00, 0x44, 0x00, 0x60, 0x00, 0x50, 0x00, 0x65, - 0x00, 0x48, 0x00, 0x7d, 0x00, 0x2a, 0x00, 0x74, - 0x00, 0x49, 0x00, 0x7b, 0x00, 0x21, 0x00, 0x61, - 0x00, 0x52, 0x00, 0x43, 0x00, 0x5f, 0x00, 0x5a, - 0x00, 0x74, 0x00, 0x5c, 0x00, 0x62, 0x00, 0x68, - 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x2b, 0x00, 0x6f, - 0x00, 0x7c, 0x00, 0x42, 0x00, 0x67, 0x00, 0x32, - 0x00, 0x58, 0x00, 0x35, 0x00, 0x30, 0x00, 0x2f, - 0x00, 0x2d, 0x00, 0x60, 0x00, 0x62, 0x00, 0x51, - 0x00, 0x2a, 0x00, 0x30, 0x00, 0x31, 0x00, 0x48, - 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x5d, 0x00, 0x25, - 0x00, 0x58, 0x00, 0x4a, 0x00, 0x76, 0x00, 0x32, - 0x00, 0x62, 0x00, 0x27, 0x00, 0x42, 0x00, 0x40, - 0x00, 0x53, 0x00, 0x7c, 0x00, 0x7d, 0x00, 0x50, - 0x00, 0x3d, 0x00, 0x40, 0x00, 0x76, 0x00, 0x38, - 0x00, 0x58, 0x00, 0x39, 0x00, 0x63, 0x00, 0x3c, - 0x00, 0x5b, 0x00, 0x23, 0x00, 0x53, 0x00, 0x7a, - 0x00, 0x54, 0x00, 0x74, 0x00, 0x61, 0x00, 0x76, - 0x00, 0x4a, 0x00, 0x3e, 0x00, 0x33, 0x00, 0x75, - 0x00, 0x66, 0x00, 0x2d, 0x00, 0x48, 0x00, 0x33, - 0x00, 0x71, 0x00, 0x76, 0x00, 0x48, 0x00, 0x71, - 0x00, 0x41, 0x00, 0x6f, 0x00, 0x2a, 0x00, 0x67, - 0x00, 0x70, 0x00, 0x21, 0x00, 0x70, 0x00, 0x4b, - 0x00, 0x52, 0x00, 0x58, 0x00, 0x68, 0x00, 0x23, - 0x00, 0x39, 0x00, 0x46, 0x00, 0x4d, 0x00, 0x51, - 0x00, 0x57, 0x00, 0x3a, 0x00, 0x79, 0x00, 0x7b, - 0x00, 0x6c, 0x00, 0x55, 0x00, 0x33, 0x00, 0x65, - 0x00, 0x49, 0x00, 0x72, 0x00, 0x30, 0x00, 0x4f, - 0x00, 0x41, 0x00, 0x6e, 0x00, 0x31, 0x00, 0x4a, - 0x00, 0x60, 0x00, 0x79, 0x00, 0x70, 0x00, 0x4f, - 0x00, 0x58, 0x00, 0x75, 0x00, 0x44, 0x00, 0x59, - 0x00, 0x58, 0x00, 0x46, 0x00, 0x3d, 0x00, 0x46, - 0x00, 0x74, 0x00, 0x51, 0x00, 0x57, 0x00, 0x6e, - 0x00, 0x2d, 0x00, 0x47, 0x00, 0x23, 0x00, 0x45, - 0x00, 0x60, 0x00, 0x4c, 0x00, 0x72, 0x00, 0x4e, - 0x00, 0x74, 0x00, 0x40, 0x00, 0x76, 0x00, 0x75, - 0x00, 0x74, 0x00, 0x56, 0x00, 0x44, 0x00, 0x29, - 0x00, 0x62, 0x00, 0x58, 0x00, 0x31, 0x00, 0x78, - 0x00, 0x32, 0x00, 0x52, 0x00, 0x4a, 0x00, 0x6b, - 0x00, 0x55, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6f, - 0x00, 0x4a, 0x00, 0x54, 0x00, 0x7d, 0x00, 0x68, - 0x00, 0x3f, 0x00, 0x28, 0x00, 0x21, 0x00, 0x53, - 0x00, 0x48, 0x00, 0x5a, 0x00, 0x34, 0x00, 0x36, - 0x00, 0x35, 0x00, 0x64, 0x00, 0x4e, 0x00, 0x75, - 0x00, 0x69, 0x00, 0x23, 0x00, 0x75, 0x00, 0x55, - 0x00, 0x43, 0x00, 0x75, 0x00, 0x2f, 0x00, 0x73, - 0x00, 0x62, 0x00, 0x6f, 0x00, 0x37, 0x00, 0x4e, - 0x00, 0x25, 0x00, 0x25, 0x00, 0x21, 0x00, 0x3d, - 0x00, 0x3c, 0x00, 0x71, 0x00, 0x3e, 0x00, 0x3f, - 0x00, 0x30, 0x00, 0x36, 0x00, 0x62, 0x00, 0x63, - 0x00, 0x53, 0x00, 0x54, 0x00, 0x5d, 0x00, 0x61, - 0x00, 0x4c, 0x00, 0x28, 0x00, 0x2b, 0x00, 0x4c, - 0x00, 0x4e, 0x00, 0x66, 0x00, 0x5f, 0x00, 0x4b, - 0x00, 0x43, 0x00, 0x75, 0x00, 0x45, 0x00, 0x37, - 0x00, 0x28, 0x00, 0x56, 0x00, 0x36, 0x00, 0x6a, - 0x00, 0x3e, 0x00, 0x64, 0x00, 0x34, 0x00, 0x6a, - 0x00, 0x7d, 0x00, 0x4a, 0x00, 0x66, 0x00, 0x7a, - 0x00, 0x3e, 0x00, 0x75, 0x00, 0x38, 0x00, 0x7b, - 0x00, 0x42, 0x00, 0x76, 0x00, 0x29, 0x00, 0x4c, - 0x00, 0x65, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x4b, - 0x00, 0x2b, 0x00, 0x51, 0x00, 0x47, 0x00, 0x22, - 0x00, 0x48, 0x00, 0x3d, 0x00, 0x49, 0x00, 0x44, - 0x00, 0x5d, 0x00, 0x59, 0x00, 0x63, 0x00, 0x5c, - 0x00, 0x24, 0x00, 0x35, 0x00, 0x34, 0x00, 0x70, - 0x00, 0x69, 0x00}; - uint32_t requestlen = sizeof(dcerpcrequest); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_START, dcerpcrequest, requestlen); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] != 0x01) { - printf("expected dcerpc data representation 0x01, got 0x%02x : ", - dcerpc_state->dcerpc.dcerpchdr.packed_drep[0]); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpchdr.frag_length != 1024) { - printf("expected dcerpc frag_length 0x%02x , got 0x%02x : ", 1024, dcerpc_state->dcerpc.dcerpchdr.frag_length); - result = 0; - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 9) { - printf("expected dcerpc opnum 0x%02x , got 0x%02x : ", 9, dcerpc_state->dcerpc.dcerpcrequest.opnum); - result = 0; - goto end; - } -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \todo Needs to be rewritten - */ -int DCERPCParserTest04(void) -{ - /* AWS - Disabled this test since clamav FPs on the payloads used. - * We will have to rewrite this test with new payloads. Will be done - * as a part of dcerpc update/fixes */ -#if 0 - int result = 1; - Flow f; - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x48, 0x1a, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - uint8_t request3[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x26, 0x65, 0x3c, 0x6e, 0x6d, 0x64, 0x24, 0x39, - 0x56, 0x43, 0x3e, 0x61, 0x5c, 0x54, 0x42, 0x23, - 0x75, 0x6b, 0x71, 0x27, 0x66, 0x2e, 0x6e, 0x3d, - 0x58, 0x23, 0x54, 0x77, 0x3b, 0x52, 0x6b, 0x50, - 0x3b, 0x74, 0x2c, 0x54, 0x25, 0x5c, 0x51, 0x7c, - 0x29, 0x7c, 0x5f, 0x4a, 0x35, 0x5c, 0x3d, 0x3f, - 0x33, 0x55, 0x3b, 0x5a, 0x57, 0x31, 0x59, 0x4f, - 0x6d, 0x6d, 0x7b, 0x3e, 0x38, 0x4d, 0x68, 0x75, - 0x64, 0x21, 0x50, 0x63, 0x47, 0x42, 0x56, 0x39, - 0x6c, 0x6f, 0x61, 0x53, 0x32, 0x56, 0x43, 0x52, - 0x43, 0x67, 0x26, 0x45, 0x28, 0x6b, 0x77, 0x28, - 0x7c, 0x64, 0x61, 0x24, 0x38, 0x6b, 0x59, 0x2a, - 0x4f, 0x6e, 0x5b, 0x57, 0x24, 0x54, 0x33, 0x37, - 0x47, 0x58, 0x4b, 0x58, 0x3d, 0x21, 0x38, 0x7c, - 0x2c, 0x24, 0x5f, 0x67, 0x3a, 0x41, 0x3e, 0x2a, - 0x72, 0x66, 0x2d, 0x6b, 0x66, 0x7b, 0x2b, 0x75, - 0x78, 0x2f, 0x4d, 0x4c, 0x51, 0x70, 0x5d, 0x55, - 0x54, 0x3c, 0x63, 0x46, 0x6b, 0x64, 0x4d, 0x25, - 0x45, 0x21, 0x34, 0x65, 0x48, 0x32, 0x58, 0x4c, - 0x70, 0x4c, 0x4c, 0x75, 0x5c, 0x77, 0x68, 0x78, - 0x34, 0x5c, 0x2d, 0x39, 0x58, 0x3b, 0x40, 0x71, - 0x77, 0x47, 0x32, 0x2e, 0x3c, 0x61, 0x6f, 0x6d, - 0x5f, 0x43, 0x74, 0x36, 0x4f, 0x21, 0x44, 0x66, - 0x36, 0x62, 0x30, 0x29, 0x5a, 0x34, 0x66, 0x4e, - 0x51, 0x23, 0x4e, 0x38, 0x51, 0x78, 0x74, 0x58, - 0x2e, 0x6d, 0x51, 0x49, 0x55, 0x73, 0x2a, 0x71, - 0x3c, 0x74, 0x38, 0x6f, 0x5d, 0x4b, 0x74, 0x68, - 0x65, 0x4a, 0x58, 0x41, 0x55, 0x29, 0x42, 0x69, - 0x55, 0x3b, 0x2b, 0x47, 0x64, 0x3b, 0x77, 0x72, - 0x74, 0x38, 0x53, 0x5c, 0x69, 0x49, 0x49, 0x5b, - 0x31, 0x41, 0x6a, 0x4e, 0x2c, 0x6a, 0x63, 0x3f, - 0x58, 0x4e, 0x25, 0x3e, 0x57, 0x41, 0x61, 0x26, - 0x5e, 0x24, 0x69, 0x7a, 0x38, 0x60, 0x73, 0x70, - 0x7d, 0x63, 0x34, 0x78, 0x4d, 0x50, 0x35, 0x69, - 0x49, 0x22, 0x45, 0x44, 0x3f, 0x6e, 0x75, 0x64, - 0x57, 0x3a, 0x61, 0x60, 0x34, 0x21, 0x61, 0x21, - 0x2a, 0x78, 0x7b, 0x52, 0x43, 0x50, 0x5b, 0x76, - 0x5f, 0x4b, 0x6a, 0x5d, 0x23, 0x5b, 0x57, 0x40, - 0x53, 0x51, 0x33, 0x21, 0x35, 0x7d, 0x31, 0x46, - 0x65, 0x52, 0x28, 0x25, 0x30, 0x5a, 0x37, 0x7c, - 0x2c, 0x3d, 0x2a, 0x48, 0x24, 0x5a, 0x2f, 0x47, - 0x64, 0x73, 0x64, 0x3d, 0x7a, 0x5b, 0x34, 0x5e, - 0x42, 0x22, 0x32, 0x47, 0x6e, 0x58, 0x3b, 0x3e, - 0x25, 0x2f, 0x58, 0x78, 0x42, 0x66, 0x71, 0x56, - 0x2a, 0x66, 0x66, 0x5b, 0x55, 0x35, 0x7a, 0x41, - 0x7c, 0x7c, 0x6a, 0x2d, 0x59, 0x25, 0x22, 0x34, - 0x5a, 0x61, 0x37, 0x48, 0x39, 0x31, 0x4a, 0x55, - 0x6a, 0x68, 0x40, 0x2f, 0x45, 0x69, 0x46, 0x25, - 0x51, 0x7d, 0x4f, 0x71, 0x21, 0x33, 0x55, 0x50, - 0x56, 0x5f, 0x75, 0x27, 0x64, 0x36, 0x7a, 0x39, - 0x40, 0x6a, 0x77, 0x38, 0x5d, 0x39, 0x30, 0x5e, - 0x74, 0x54, 0x24, 0x3f, 0x3d, 0x79, 0x3b, 0x27, - 0x7d, 0x68, 0x7d, 0x40, 0x71, 0x7a, 0x65, 0x54, - 0x50, 0x66, 0x33, 0x3c, 0x42, 0x69, 0x6e, 0x3c, - 0x63, 0x63, 0x69, 0x7a, 0x5e, 0x7b, 0x76, 0x26, - 0x71, 0x6f, 0x4a, 0x6d, 0x70, 0x73, 0x66, 0x3b, - 0x26, 0x70, 0x43, 0x5b, 0x52, 0x4c, 0x6d, 0x51, - 0x2a, 0x66, 0x6c, 0x3e, 0x68, 0x6a, 0x31, 0x41, - 0x79, 0x72, 0x37, 0x47, 0x7d, 0x2b, 0x3c, 0x40, - 0x6b, 0x75, 0x56, 0x70, 0x7b, 0x2d, 0x5f, 0x33, - 0x30, 0x30, 0x21, 0x35, 0x7a, 0x7a, 0x67, 0x48, - 0x5e, 0x3b, 0x73, 0x50, 0x54, 0x47, 0x23, 0x2b, - 0x4c, 0x4e, 0x2f, 0x24, 0x44, 0x34, 0x23, 0x5d, - 0x76, 0x51, 0x5a, 0x73, 0x72, 0x3e, 0x47, 0x77, - 0x40, 0x28, 0x65, 0x2e, 0x2a, 0x75, 0x3c, 0x2a, - 0x27, 0x4a, 0x3f, 0x3c, 0x66, 0x2d, 0x21, 0x79, - 0x2d, 0x2b, 0x78, 0x7c, 0x5a, 0x73, 0x46, 0x6b, - 0x39, 0x65, 0x5e, 0x3d, 0x38, 0x40, 0x32, 0x3e, - 0x21, 0x62, 0x34, 0x41, 0x58, 0x53, 0x67, 0x34, - 0x58, 0x56, 0x61, 0x5b, 0x3e, 0x4e, 0x2c, 0x5b, - 0x73, 0x35, 0x34, 0x35, 0x21, 0x3a, 0x61, 0x5f, - 0x6e, 0x45, 0x78, 0x44, 0x28, 0x23, 0x48, 0x65, - 0x53, 0x47, 0x6e, 0x2c, 0x38, 0x5e, 0x2c, 0x57, - 0x58, 0x30, 0x7a, 0x3b, 0x4b, 0x4a, 0x74, 0x7d, - 0x3e, 0x4d, 0x30, 0x24, 0x76, 0x66, 0x6d, 0x2e, - 0x74, 0x75, 0x28, 0x48, 0x5c, 0x23, 0x6c, 0x46, - 0x27, 0x46, 0x6e, 0x34, 0x63, 0x21, 0x58, 0x54, - 0x50, 0x2f, 0x40, 0x47, 0x40, 0x32, 0x36, 0x48, - 0x5f, 0x7d, 0x4a, 0x41, 0x6e, 0x60, 0x2c, 0x4a, - 0x6a, 0x67, 0x6c, 0x41, 0x27, 0x23, 0x30, 0x48, - 0x6a, 0x49, 0x73, 0x26, 0x77, 0x75, 0x4d, 0x65, - 0x5b, 0x34, 0x79, 0x67, 0x61, 0x5b, 0x5c, 0x2b, - 0x71, 0x3f, 0x62, 0x51, 0x3a, 0x53, 0x42, 0x26, - 0x6f, 0x36, 0x57, 0x3f, 0x2b, 0x34, 0x24, 0x30, - 0x60, 0x55, 0x70, 0x65, 0x70, 0x57, 0x5d, 0x68, - 0x36, 0x52, 0x5d, 0x3f, 0x6a, 0x3a, 0x33, 0x31, - 0x6c, 0x4e, 0x57, 0x79, 0x49, 0x79, 0x69, 0x71, - 0x6f, 0x70, 0x6a, 0x76, 0x4b, 0x2f, 0x33, 0x51, - 0x68, 0x30, 0x2e, 0x77, 0x78, 0x55, 0x2f, 0x53, - 0x52, 0x5e, 0x57, 0x60, 0x3b, 0x6f, 0x69, 0x61, - 0x6c, 0x60, 0x5a, 0x34, 0x5a, 0x35, 0x4b, 0x28, - 0x54, 0x32, 0x6a, 0x35, 0x36, 0x6d, 0x68, 0x47, - 0x5c, 0x74, 0x2e, 0x5f, 0x6c, 0x6d, 0x55, 0x42, - 0x77, 0x64, 0x7d, 0x53, 0x4d, 0x39, 0x2c, 0x41, - 0x42, 0x23, 0x3a, 0x73, 0x40, 0x60, 0x5d, 0x38, - 0x6d, 0x36, 0x56, 0x57, 0x2a, 0x28, 0x3d, 0x3b, - 0x5c, 0x75, 0x35, 0x2d, 0x69, 0x2d, 0x44, 0x51, - 0x27, 0x63, 0x66, 0x33, 0x46, 0x42, 0x2e, 0x36, - 0x6b, 0x7b, 0x2c, 0x23, 0x3b, 0x5a, 0x50, 0x2a, - 0x65, 0x28, 0x3b, 0x3c, 0x51, 0x3f, 0x4d, 0x63, - 0x38, 0x25, 0x74, 0x2e, 0x51, 0x22, 0x31, 0x74, - 0x35, 0x33, 0x23, 0x2d, 0x3f, 0x77, 0x26, 0x2c, - 0x55, 0x6d, 0x27, 0x39, 0x79, 0x76, 0x63, 0x4b, - 0x43, 0x4a, 0x3a, 0x6b, 0x59, 0x55, 0x65, 0x26, - 0x2f, 0x3f, 0x56, 0x67, 0x5a, 0x77, 0x71, 0x22, - 0x51, 0x2b, 0x6d, 0x4c, 0x2c, 0x57, 0x66, 0x76, - 0x37, 0x70, 0x5f, 0x52, 0x29, 0x44, 0x52, 0x22, - 0x57, 0x37, 0x27, 0x79, 0x29, 0x5c, 0x57, 0x3b, - 0x54, 0x3c, 0x3f, 0x53, 0x35, 0x27, 0x5e, 0x7c, - 0x49, 0x77, 0x57, 0x5a, 0x22, 0x76, 0x7c, 0x5b, - 0x2f, 0x53, 0x5e, 0x55, 0x6d, 0x64, 0x67, 0x34, - 0x41, 0x23, 0x76, 0x67, 0x23, 0x78, 0x6a, 0x63, - 0x27, 0x68, 0x43, 0x7d, 0x58, 0x49, 0x2d, 0x79, - 0x2e, 0x75, 0x60, 0x6b, 0x34, 0x48, 0x6f, 0x4a, - 0x6c, 0x48, 0x40, 0x68, 0x5f, 0x35, 0x25, 0x6c, - 0x38, 0x5c, 0x30, 0x32, 0x4c, 0x36, 0x31, 0x29, - 0x74, 0x4a, 0x55, 0x56, 0x6d, 0x4e, 0x23, 0x54, - 0x2e, 0x69, 0x78, 0x61, 0x76, 0x66, 0x22, 0x44, - 0x73, 0x25, 0x44, 0x29, 0x2a, 0x28, 0x3b, 0x67, - 0x48, 0x58, 0x37, 0x4a, 0x76, 0x76, 0x51, 0x4a, - 0x61, 0x70, 0x51, 0x74, 0x40, 0x23, 0x29, 0x63, - 0x69, 0x4a, 0x29, 0x23, 0x34, 0x6a, 0x3b, 0x25, - 0x28, 0x54, 0x45, 0x33, 0x28, 0x44, 0x30, 0x61, - 0x5b, 0x60, 0x51, 0x3f, 0x68, 0x50, 0x70, 0x3d, - 0x58, 0x2e, 0x6e, 0x59, 0x5a, 0x62, 0x66, 0x4d, - 0x7a, 0x2e, 0x37, 0x37, 0x3d, 0x7b, 0x74, 0x79, - 0x48, 0x45, 0x77, 0x56, 0x33, 0x76, 0x71, 0x60, - 0x74, 0x3f, 0x61, 0x22, 0x52, 0x51, 0x71, 0x69 - }; - uint32_t request3_len = sizeof(request3); - - uint8_t request4[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x75, 0x3e, 0x76, 0x3e, 0x66, 0x6b, 0x6b, 0x3e, - 0x6d, 0x59, 0x38, 0x2b, 0x63, 0x4d, 0x2c, 0x73, - 0x54, 0x57, 0x34, 0x25, 0x5b, 0x42, 0x7d, 0x5d, - 0x37, 0x34, 0x2c, 0x79, 0x24, 0x4b, 0x74, 0x73, - 0x25, 0x36, 0x73, 0x3a, 0x2c, 0x55, 0x69, 0x3c, - 0x58, 0x67, 0x33, 0x53, 0x67, 0x5c, 0x61, 0x7b, - 0x44, 0x2e, 0x42, 0x2d, 0x6b, 0x50, 0x55, 0x24, - 0x70, 0x58, 0x60, 0x38, 0x42, 0x45, 0x70, 0x6d, - 0x2f, 0x27, 0x27, 0x2c, 0x21, 0x6d, 0x57, 0x6e, - 0x43, 0x3c, 0x5b, 0x27, 0x7a, 0x34, 0x49, 0x5a, - 0x69, 0x30, 0x3f, 0x6f, 0x77, 0x70, 0x39, 0x2d, - 0x51, 0x74, 0x4b, 0x25, 0x70, 0x51, 0x64, 0x4d, - 0x75, 0x52, 0x5e, 0x3e, 0x37, 0x30, 0x5d, 0x3b, - 0x2c, 0x72, 0x25, 0x6c, 0x6f, 0x79, 0x69, 0x3c, - 0x5b, 0x73, 0x3d, 0x41, 0x28, 0x28, 0x64, 0x60, - 0x4b, 0x7a, 0x2c, 0x4a, 0x6b, 0x3d, 0x2e, 0x6c, - 0x7a, 0x54, 0x70, 0x61, 0x6f, 0x4b, 0x40, 0x28, - 0x59, 0x31, 0x25, 0x21, 0x57, 0x79, 0x4b, 0x31, - 0x6f, 0x4e, 0x71, 0x2b, 0x3c, 0x24, 0x30, 0x28, - 0x3c, 0x61, 0x28, 0x4b, 0x35, 0x61, 0x4d, 0x55, - 0x5e, 0x66, 0x34, 0x5f, 0x61, 0x70, 0x7b, 0x67, - 0x51, 0x55, 0x68, 0x78, 0x26, 0x3a, 0x27, 0x4e, - 0x71, 0x79, 0x4f, 0x67, 0x2c, 0x5a, 0x79, 0x75, - 0x59, 0x3a, 0x33, 0x4a, 0x36, 0x71, 0x72, 0x6d, - 0x49, 0x3e, 0x53, 0x59, 0x2b, 0x2b, 0x27, 0x4e, - 0x50, 0x5d, 0x21, 0x55, 0x64, 0x4b, 0x72, 0x73, - 0x25, 0x55, 0x26, 0x4f, 0x3a, 0x21, 0x54, 0x29, - 0x4f, 0x64, 0x51, 0x59, 0x60, 0x7b, 0x7c, 0x6f, - 0x3e, 0x65, 0x74, 0x6a, 0x5b, 0x52, 0x2c, 0x56, - 0x4e, 0x45, 0x53, 0x4b, 0x7c, 0x38, 0x49, 0x4b, - 0x4e, 0x4f, 0x4a, 0x47, 0x5e, 0x7c, 0x46, 0x3b, - 0x67, 0x2e, 0x43, 0x79, 0x35, 0x55, 0x59, 0x6d, - 0x38, 0x70, 0x2f, 0x59, 0x4f, 0x27, 0x63, 0x40, - 0x66, 0x2d, 0x39, 0x4f, 0x3d, 0x2e, 0x4c, 0x67, - 0x71, 0x7d, 0x34, 0x22, 0x52, 0x4e, 0x36, 0x7b, - 0x2c, 0x39, 0x4d, 0x42, 0x60, 0x75, 0x74, 0x72, - 0x4f, 0x72, 0x68, 0x3a, 0x51, 0x31, 0x2d, 0x21, - 0x4a, 0x35, 0x47, 0x6d, 0x69, 0x3c, 0x50, 0x4c, - 0x59, 0x66, 0x4c, 0x71, 0x24, 0x3a, 0x36, 0x67, - 0x24, 0x5a, 0x59, 0x28, 0x7c, 0x21, 0x5e, 0x77, - 0x68, 0x5e, 0x7b, 0x6e, 0x56, 0x62, 0x36, 0x29, - 0x6f, 0x4f, 0x5d, 0x57, 0x56, 0x2b, 0x75, 0x2a, - 0x2c, 0x69, 0x63, 0x51, 0x74, 0x6e, 0x5e, 0x46, - 0x50, 0x28, 0x2c, 0x3b, 0x32, 0x53, 0x28, 0x78, - 0x59, 0x72, 0x39, 0x5e, 0x44, 0x5c, 0x77, 0x60, - 0x72, 0x44, 0x3b, 0x75, 0x68, 0x39, 0x55, 0x3e, - 0x44, 0x50, 0x76, 0x3c, 0x48, 0x46, 0x43, 0x22, - 0x56, 0x27, 0x21, 0x31, 0x33, 0x4a, 0x5a, 0x74, - 0x41, 0x58, 0x3f, 0x39, 0x29, 0x71, 0x73, 0x30, - 0x57, 0x70, 0x33, 0x62, 0x7b, 0x4a, 0x75, 0x3e, - 0x4d, 0x4c, 0x4e, 0x55, 0x63, 0x38, 0x66, 0x7d, - 0x68, 0x7d, 0x6f, 0x23, 0x55, 0x50, 0x3d, 0x34, - 0x46, 0x5e, 0x2f, 0x55, 0x27, 0x62, 0x68, 0x7c, - 0x6c, 0x21, 0x2b, 0x63, 0x4b, 0x47, 0x6b, 0x6a, - 0x5b, 0x7b, 0x5c, 0x71, 0x37, 0x7c, 0x52, 0x2b, - 0x2f, 0x4a, 0x47, 0x70, 0x78, 0x50, 0x2f, 0x75, - 0x28, 0x4c, 0x60, 0x4c, 0x4c, 0x54, 0x6b, 0x68, - 0x63, 0x4f, 0x47, 0x39, 0x2a, 0x70, 0x51, 0x7d, - 0x28, 0x59, 0x52, 0x46, 0x4b, 0x38, 0x27, 0x49, - 0x50, 0x5d, 0x25, 0x22, 0x5f, 0x48, 0x2c, 0x2f, - 0x67, 0x59, 0x5d, 0x7d, 0x21, 0x3d, 0x72, 0x4f, - 0x5c, 0x5b, 0x41, 0x47, 0x5f, 0x56, 0x69, 0x42, - 0x55, 0x60, 0x68, 0x4b, 0x77, 0x44, 0x4c, 0x3b, - 0x7d, 0x5a, 0x58, 0x43, 0x7a, 0x33, 0x22, 0x58, - 0x58, 0x6f, 0x74, 0x53, 0x57, 0x6d, 0x6e, 0x29, - 0x6b, 0x33, 0x71, 0x68, 0x29, 0x48, 0x67, 0x35, - 0x52, 0x41, 0x6b, 0x36, 0x4f, 0x46, 0x31, 0x24, - 0x73, 0x56, 0x40, 0x48, 0x37, 0x51, 0x24, 0x2a, - 0x59, 0x21, 0x74, 0x76, 0x25, 0x2e, 0x4a, 0x74, - 0x32, 0x29, 0x5f, 0x57, 0x7c, 0x58, 0x30, 0x2c, - 0x7b, 0x70, 0x5b, 0x51, 0x73, 0x27, 0x4a, 0x28, - 0x77, 0x2a, 0x43, 0x28, 0x2e, 0x32, 0x3d, 0x38, - 0x36, 0x2e, 0x6b, 0x40, 0x6c, 0x76, 0x54, 0x66, - 0x4a, 0x5c, 0x25, 0x62, 0x2e, 0x61, 0x48, 0x30, - 0x28, 0x41, 0x40, 0x69, 0x3c, 0x39, 0x36, 0x4b, - 0x64, 0x50, 0x76, 0x3d, 0x52, 0x50, 0x77, 0x33, - 0x3b, 0x65, 0x59, 0x31, 0x5c, 0x48, 0x6a, 0x74, - 0x78, 0x5b, 0x74, 0x60, 0x47, 0x27, 0x60, 0x22, - 0x4a, 0x72, 0x25, 0x34, 0x5d, 0x3a, 0x21, 0x66, - 0x61, 0x7b, 0x34, 0x41, 0x3b, 0x3a, 0x27, 0x44, - 0x48, 0x7c, 0x7a, 0x74, 0x3a, 0x68, 0x59, 0x48, - 0x61, 0x32, 0x49, 0x61, 0x40, 0x22, 0x33, 0x75, - 0x29, 0x76, 0x5b, 0x24, 0x5b, 0x5c, 0x76, 0x5c, - 0x28, 0x75, 0x36, 0x26, 0x2c, 0x65, 0x5e, 0x51, - 0x7b, 0x3a, 0x7d, 0x4f, 0x35, 0x73, 0x6b, 0x5b, - 0x5c, 0x37, 0x35, 0x6b, 0x41, 0x35, 0x40, 0x3a, - 0x22, 0x28, 0x6c, 0x71, 0x46, 0x68, 0x7b, 0x66, - 0x56, 0x24, 0x7c, 0x54, 0x28, 0x30, 0x22, 0x4e, - 0x3c, 0x65, 0x69, 0x36, 0x44, 0x53, 0x3d, 0x6c, - 0x5f, 0x73, 0x6c, 0x6f, 0x5e, 0x27, 0x23, 0x4e, - 0x60, 0x45, 0x2f, 0x3d, 0x37, 0x28, 0x51, 0x29, - 0x77, 0x6a, 0x6b, 0x2a, 0x2a, 0x51, 0x26, 0x4c, - 0x4e, 0x71, 0x77, 0x73, 0x71, 0x2d, 0x5a, 0x2c, - 0x23, 0x3d, 0x5f, 0x62, 0x63, 0x2e, 0x72, 0x2a, - 0x75, 0x66, 0x43, 0x56, 0x5f, 0x21, 0x64, 0x66, - 0x35, 0x3b, 0x7a, 0x45, 0x3f, 0x4f, 0x57, 0x22, - 0x5a, 0x45, 0x65, 0x37, 0x58, 0x5b, 0x43, 0x66, - 0x4f, 0x5d, 0x6e, 0x41, 0x41, 0x62, 0x5e, 0x39, - 0x65, 0x6f, 0x43, 0x4b, 0x5e, 0x51, 0x42, 0x3f, - 0x2d, 0x68, 0x4b, 0x6e, 0x46, 0x6f, 0x21, 0x44, - 0x3c, 0x22, 0x46, 0x31, 0x31, 0x2e, 0x56, 0x2e, - 0x77, 0x48, 0x68, 0x23, 0x4a, 0x36, 0x52, 0x5d, - 0x61, 0x47, 0x71, 0x2e, 0x3a, 0x4a, 0x5b, 0x56, - 0x6b, 0x52, 0x2a, 0x4c, 0x4f, 0x24, 0x34, 0x60, - 0x70, 0x58, 0x7a, 0x76, 0x4b, 0x68, 0x24, 0x5f, - 0x51, 0x6d, 0x75, 0x45, 0x48, 0x21, 0x53, 0x4d, - 0x27, 0x75, 0x5f, 0x50, 0x3e, 0x40, 0x3f, 0x5e, - 0x64, 0x41, 0x5f, 0x68, 0x48, 0x30, 0x71, 0x4b, - 0x66, 0x2c, 0x2f, 0x76, 0x4b, 0x23, 0x46, 0x34, - 0x50, 0x58, 0x52, 0x69, 0x2b, 0x6e, 0x7a, 0x33, - 0x53, 0x43, 0x43, 0x35, 0x54, 0x30, 0x73, 0x63, - 0x3b, 0x43, 0x52, 0x29, 0x45, 0x37, 0x71, 0x79, - 0x5a, 0x26, 0x24, 0x72, 0x73, 0x4e, 0x44, 0x38, - 0x5b, 0x71, 0x36, 0x3a, 0x4f, 0x5b, 0x71, 0x28, - 0x71, 0x79, 0x72, 0x40, 0x6e, 0x51, 0x72, 0x29, - 0x3d, 0x4f, 0x33, 0x22, 0x73, 0x5a, 0x30, 0x71, - 0x58, 0x54, 0x59, 0x48, 0x29, 0x2b, 0x5c, 0x73, - 0x6f, 0x4e, 0x60, 0x2a, 0x72, 0x39, 0x50, 0x59, - 0x6f, 0x48, 0x3e, 0x62, 0x6c, 0x62, 0x49, 0x6c, - 0x2c, 0x3f, 0x43, 0x3f, 0x32, 0x7c, 0x6f, 0x6c, - 0x39, 0x26, 0x26, 0x7b, 0x5d, 0x65, 0x6f, 0x41, - 0x7c, 0x42, 0x2b, 0x65, 0x6f, 0x3e, 0x7b, 0x69, - 0x46, 0x4d, 0x68, 0x68, 0x5a, 0x33, 0x25, 0x5d, - 0x6f, 0x48, 0x7c, 0x77, 0x7d, 0x3f, 0x4e, 0x30, - 0x69, 0x65, 0x28, 0x2e, 0x34, 0x34, 0x41, 0x43, - 0x5e, 0x30, 0x23, 0x3b, 0x60, 0x79, 0x5b, 0x26, - 0x7c, 0x77, 0x3e, 0x43, 0x24, 0x31, 0x3a, 0x56, - 0x24, 0x3c, 0x60, 0x3f, 0x60, 0x55, 0x6a, 0x68 - }; - uint32_t request4_len = sizeof(request4); - - uint8_t request5[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x69, 0x3e, 0x72, 0x44, 0x31, 0x6b, 0x28, 0x2f, - 0x79, 0x37, 0x58, 0x5d, 0x5f, 0x68, 0x71, 0x47, - 0x7a, 0x68, 0x7c, 0x6c, 0x65, 0x3c, 0x74, 0x67, - 0x59, 0x5c, 0x3d, 0x28, 0x65, 0x28, 0x58, 0x74, - 0x44, 0x62, 0x2e, 0x36, 0x54, 0x2f, 0x24, 0x34, - 0x4b, 0x6d, 0x3a, 0x7b, 0x60, 0x71, 0x5a, 0x77, - 0x4a, 0x27, 0x25, 0x70, 0x75, 0x56, 0x78, 0x73, - 0x2e, 0x38, 0x6c, 0x70, 0x66, 0x7b, 0x7b, 0x2d, - 0x78, 0x27, 0x65, 0x63, 0x58, 0x4f, 0x7d, 0x5c, - 0x31, 0x3e, 0x36, 0x6e, 0x65, 0x61, 0x2e, 0x4e, - 0x26, 0x68, 0x2b, 0x33, 0x7d, 0x54, 0x2c, 0x28, - 0x47, 0x3a, 0x31, 0x47, 0x56, 0x32, 0x74, 0x51, - 0x79, 0x65, 0x42, 0x45, 0x60, 0x55, 0x6f, 0x48, - 0x61, 0x23, 0x72, 0x62, 0x74, 0x3a, 0x5a, 0x26, - 0x2d, 0x41, 0x58, 0x62, 0x75, 0x4b, 0x37, 0x2e, - 0x3f, 0x2a, 0x6e, 0x2e, 0x2c, 0x43, 0x6f, 0x53, - 0x5f, 0x48, 0x7a, 0x53, 0x7b, 0x54, 0x28, 0x30, - 0x2b, 0x7a, 0x34, 0x33, 0x28, 0x2b, 0x23, 0x23, - 0x72, 0x38, 0x25, 0x30, 0x35, 0x66, 0x76, 0x46, - 0x2a, 0x57, 0x7a, 0x60, 0x38, 0x5a, 0x26, 0x4f, - 0x78, 0x43, 0x2c, 0x7d, 0x3d, 0x76, 0x7d, 0x66, - 0x48, 0x7d, 0x3e, 0x59, 0x31, 0x58, 0x6b, 0x30, - 0x76, 0x45, 0x6e, 0x70, 0x72, 0x5f, 0x3c, 0x70, - 0x6d, 0x77, 0x42, 0x75, 0x42, 0x73, 0x68, 0x5e, - 0x5f, 0x72, 0x2b, 0x2a, 0x70, 0x38, 0x7a, 0x4c, - 0x58, 0x2e, 0x5e, 0x2d, 0x2d, 0x78, 0x67, 0x5a, - 0x77, 0x34, 0x5a, 0x50, 0x76, 0x2d, 0x2b, 0x77, - 0x37, 0x6e, 0x38, 0x2d, 0x7b, 0x44, 0x78, 0x67, - 0x52, 0x57, 0x79, 0x43, 0x7d, 0x6d, 0x4d, 0x32, - 0x23, 0x37, 0x51, 0x4b, 0x41, 0x60, 0x6e, 0x53, - 0x4e, 0x78, 0x37, 0x37, 0x60, 0x56, 0x64, 0x52, - 0x25, 0x46, 0x53, 0x5f, 0x2b, 0x56, 0x2b, 0x3b, - 0x40, 0x37, 0x33, 0x37, 0x23, 0x43, 0x36, 0x6b, - 0x6b, 0x5d, 0x35, 0x28, 0x7d, 0x6a, 0x2c, 0x68, - 0x28, 0x4b, 0x4a, 0x6c, 0x27, 0x35, 0x51, 0x66, - 0x30, 0x39, 0x28, 0x4d, 0x61, 0x2f, 0x64, 0x36, - 0x59, 0x39, 0x68, 0x4b, 0x24, 0x51, 0x7b, 0x6e, - 0x38, 0x49, 0x55, 0x72, 0x5f, 0x33, 0x5c, 0x26, - 0x45, 0x2f, 0x71, 0x66, 0x33, 0x3d, 0x36, 0x68, - 0x65, 0x48, 0x42, 0x40, 0x58, 0x61, 0x4f, 0x50, - 0x70, 0x5e, 0x3c, 0x5d, 0x56, 0x43, 0x4c, 0x41, - 0x45, 0x54, 0x76, 0x4b, 0x21, 0x25, 0x45, 0x4c, - 0x5e, 0x58, 0x23, 0x7d, 0x34, 0x61, 0x5c, 0x53, - 0x2a, 0x47, 0x37, 0x22, 0x6d, 0x31, 0x42, 0x6e, - 0x22, 0x72, 0x62, 0x55, 0x59, 0x66, 0x28, 0x73, - 0x55, 0x50, 0x5c, 0x6f, 0x52, 0x40, 0x3e, 0x3b, - 0x44, 0x2a, 0x51, 0x3d, 0x4d, 0x47, 0x3a, 0x57, - 0x3e, 0x29, 0x29, 0x7d, 0x40, 0x36, 0x41, 0x3f, - 0x58, 0x77, 0x3b, 0x41, 0x2d, 0x64, 0x5a, 0x72, - 0x7c, 0x7d, 0x30, 0x68, 0x54, 0x34, 0x40, 0x21, - 0x7d, 0x2b, 0x2d, 0x2b, 0x6d, 0x5f, 0x49, 0x57, - 0x68, 0x65, 0x79, 0x2c, 0x21, 0x41, 0x31, 0x55, - 0x27, 0x4d, 0x78, 0x55, 0x2f, 0x61, 0x62, 0x78, - 0x58, 0x25, 0x3a, 0x4b, 0x3e, 0x67, 0x44, 0x7c, - 0x7d, 0x52, 0x3d, 0x3e, 0x3b, 0x62, 0x2d, 0x28, - 0x48, 0x70, 0x2c, 0x79, 0x31, 0x5a, 0x5e, 0x3f, - 0x6a, 0x30, 0x78, 0x41, 0x44, 0x60, 0x4e, 0x63, - 0x63, 0x2e, 0x31, 0x79, 0x2b, 0x47, 0x57, 0x26, - 0x22, 0x6a, 0x46, 0x43, 0x70, 0x30, 0x51, 0x7d, - 0x21, 0x3c, 0x68, 0x74, 0x40, 0x5a, 0x6e, 0x71, - 0x3f, 0x76, 0x73, 0x2e, 0x29, 0x3f, 0x6a, 0x55, - 0x21, 0x72, 0x65, 0x75, 0x5e, 0x6b, 0x39, 0x6e, - 0x3e, 0x76, 0x42, 0x41, 0x65, 0x3f, 0x2b, 0x37, - 0x70, 0x7a, 0x7a, 0x29, 0x50, 0x66, 0x21, 0x67, - 0x3f, 0x54, 0x32, 0x5f, 0x73, 0x27, 0x59, 0x6f, - 0x39, 0x4b, 0x4e, 0x23, 0x54, 0x3b, 0x39, 0x21, - 0x38, 0x41, 0x33, 0x44, 0x57, 0x6b, 0x51, 0x30, - 0x6a, 0x76, 0x62, 0x2c, 0x5c, 0x5e, 0x49, 0x3e, - 0x59, 0x38, 0x5e, 0x4a, 0x59, 0x77, 0x34, 0x25, - 0x4f, 0x76, 0x6a, 0x68, 0x6f, 0x73, 0x7c, 0x3d, - 0x2d, 0x64, 0x6c, 0x7a, 0x3d, 0x2c, 0x26, 0x28, - 0x58, 0x2b, 0x4b, 0x45, 0x68, 0x38, 0x74, 0x63, - 0x7b, 0x4a, 0x63, 0x52, 0x26, 0x54, 0x3c, 0x46, - 0x77, 0x2d, 0x6b, 0x78, 0x63, 0x7b, 0x6a, 0x50, - 0x26, 0x42, 0x62, 0x63, 0x65, 0x6b, 0x63, 0x54, - 0x4d, 0x47, 0x59, 0x48, 0x2e, 0x60, 0x7c, 0x4d, - 0x33, 0x4d, 0x61, 0x72, 0x76, 0x72, 0x21, 0x4d, - 0x2b, 0x43, 0x58, 0x47, 0x4a, 0x36, 0x2d, 0x7b, - 0x32, 0x72, 0x21, 0x78, 0x22, 0x38, 0x2c, 0x7a, - 0x34, 0x44, 0x45, 0x66, 0x31, 0x7b, 0x37, 0x68, - 0x62, 0x65, 0x62, 0x6d, 0x4e, 0x7c, 0x75, 0x38, - 0x2a, 0x73, 0x27, 0x64, 0x33, 0x4f, 0x21, 0x41, - 0x7c, 0x41, 0x3f, 0x60, 0x68, 0x34, 0x72, 0x5b, - 0x38, 0x33, 0x6f, 0x65, 0x3e, 0x5a, 0x7d, 0x25, - 0x49, 0x50, 0x60, 0x36, 0x59, 0x5e, 0x6b, 0x25, - 0x66, 0x7a, 0x7d, 0x71, 0x40, 0x6c, 0x2c, 0x6e, - 0x6a, 0x5a, 0x24, 0x5a, 0x76, 0x21, 0x67, 0x39, - 0x4b, 0x4a, 0x31, 0x24, 0x66, 0x66, 0x2e, 0x58, - 0x43, 0x46, 0x75, 0x6c, 0x47, 0x28, 0x4f, 0x21, - 0x75, 0x77, 0x6f, 0x71, 0x48, 0x3f, 0x4d, 0x4c, - 0x51, 0x37, 0x3b, 0x41, 0x4d, 0x41, 0x48, 0x28, - 0x71, 0x24, 0x2f, 0x7a, 0x22, 0x49, 0x4a, 0x39, - 0x44, 0x43, 0x68, 0x21, 0x3a, 0x34, 0x4e, 0x52, - 0x7a, 0x60, 0x71, 0x61, 0x6d, 0x51, 0x58, 0x2a, - 0x59, 0x4c, 0x4a, 0x59, 0x6b, 0x77, 0x78, 0x2e, - 0x27, 0x78, 0x76, 0x48, 0x4f, 0x46, 0x79, 0x2c, - 0x54, 0x42, 0x7b, 0x2c, 0x52, 0x41, 0x54, 0x2b, - 0x2c, 0x33, 0x6b, 0x70, 0x77, 0x2e, 0x2e, 0x41, - 0x25, 0x7a, 0x48, 0x6e, 0x71, 0x55, 0x6a, 0x43, - 0x5a, 0x2c, 0x6c, 0x76, 0x6d, 0x71, 0x72, 0x4d, - 0x76, 0x5b, 0x7b, 0x22, 0x4b, 0x45, 0x31, 0x30, - 0x26, 0x53, 0x75, 0x3f, 0x26, 0x59, 0x36, 0x2f, - 0x68, 0x4f, 0x34, 0x5e, 0x2b, 0x30, 0x63, 0x68, - 0x7b, 0x32, 0x5e, 0x77, 0x7d, 0x7b, 0x53, 0x5f, - 0x63, 0x53, 0x77, 0x7a, 0x7d, 0x35, 0x28, 0x3e, - 0x41, 0x6f, 0x5b, 0x31, 0x78, 0x7b, 0x2b, 0x51, - 0x23, 0x43, 0x46, 0x6a, 0x32, 0x32, 0x25, 0x45, - 0x57, 0x43, 0x22, 0x50, 0x60, 0x32, 0x70, 0x2e, - 0x79, 0x2e, 0x6b, 0x33, 0x67, 0x6c, 0x43, 0x5b, - 0x3b, 0x68, 0x53, 0x53, 0x6a, 0x48, 0x59, 0x5f, - 0x30, 0x72, 0x7d, 0x6b, 0x37, 0x24, 0x75, 0x52, - 0x50, 0x2b, 0x75, 0x35, 0x24, 0x3b, 0x6e, 0x53, - 0x56, 0x34, 0x23, 0x54, 0x65, 0x4f, 0x78, 0x3e, - 0x46, 0x7d, 0x25, 0x3f, 0x2f, 0x49, 0x6b, 0x49, - 0x47, 0x45, 0x24, 0x38, 0x3b, 0x68, 0x6c, 0x4f, - 0x29, 0x21, 0x50, 0x32, 0x67, 0x47, 0x5a, 0x72, - 0x76, 0x21, 0x39, 0x67, 0x3c, 0x72, 0x47, 0x43, - 0x4a, 0x2e, 0x31, 0x32, 0x34, 0x3c, 0x53, 0x2d, - 0x22, 0x5b, 0x5b, 0x6a, 0x77, 0x75, 0x31, 0x68, - 0x30, 0x45, 0x43, 0x5f, 0x60, 0x5d, 0x56, 0x67, - 0x66, 0x55, 0x6a, 0x72, 0x77, 0x7b, 0x44, 0x61, - 0x22, 0x64, 0x36, 0x39, 0x6e, 0x44, 0x37, 0x54, - 0x45, 0x46, 0x6f, 0x58, 0x35, 0x51, 0x3c, 0x62, - 0x49, 0x3a, 0x50, 0x58, 0x56, 0x5d, 0x77, 0x6f, - 0x56, 0x64, 0x7b, 0x49, 0x39, 0x21, 0x31, 0x2d, - 0x5f, 0x56, 0x56, 0x33, 0x31, 0x69, 0x4a, 0x52, - 0x62, 0x5b, 0x6e, 0x65, 0x7c, 0x3d, 0x31, 0x55, - 0x3d, 0x75, 0x25, 0x61, 0x50, 0x71, 0x45, 0x29 - }; - uint32_t request5_len = sizeof(request5); - - uint8_t request6[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x5b, 0x56, 0x3d, 0x5a, 0x6b, 0x43, 0x73, 0x26, - 0x65, 0x3b, 0x38, 0x79, 0x26, 0x5e, 0x60, 0x59, - 0x40, 0x71, 0x7c, 0x72, 0x28, 0x29, 0x69, 0x32, - 0x72, 0x5a, 0x6c, 0x55, 0x43, 0x65, 0x3f, 0x4a, - 0x21, 0x66, 0x59, 0x30, 0x76, 0x39, 0x21, 0x69, - 0x4b, 0x25, 0x5d, 0x6e, 0x5f, 0x24, 0x2b, 0x38, - 0x70, 0x78, 0x35, 0x7d, 0x39, 0x36, 0x31, 0x72, - 0x44, 0x49, 0x45, 0x3d, 0x25, 0x50, 0x24, 0x3b, - 0x52, 0x27, 0x66, 0x46, 0x5d, 0x4f, 0x34, 0x50, - 0x26, 0x5a, 0x25, 0x3e, 0x3f, 0x34, 0x4b, 0x35, - 0x77, 0x3a, 0x3f, 0x3e, 0x23, 0x4e, 0x30, 0x23, - 0x70, 0x72, 0x33, 0x34, 0x60, 0x2a, 0x4a, 0x32, - 0x6e, 0x29, 0x54, 0x73, 0x5f, 0x26, 0x71, 0x3a, - 0x78, 0x5d, 0x3f, 0x31, 0x48, 0x59, 0x61, 0x44, - 0x5c, 0x38, 0x4f, 0x41, 0x73, 0x67, 0x62, 0x73, - 0x33, 0x52, 0x77, 0x73, 0x57, 0x49, 0x7a, 0x59, - 0x26, 0x21, 0x34, 0x38, 0x2b, 0x5f, 0x5f, 0x37, - 0x74, 0x28, 0x46, 0x3d, 0x43, 0x42, 0x26, 0x66, - 0x63, 0x37, 0x6d, 0x2a, 0x65, 0x3f, 0x71, 0x2d, - 0x4c, 0x72, 0x29, 0x4b, 0x3a, 0x77, 0x64, 0x6a, - 0x6b, 0x42, 0x70, 0x5c, 0x51, 0x38, 0x71, 0x25, - 0x4c, 0x7c, 0x6f, 0x74, 0x71, 0x39, 0x71, 0x25, - 0x3f, 0x62, 0x23, 0x45, 0x5f, 0x77, 0x59, 0x56, - 0x56, 0x67, 0x78, 0x3a, 0x2e, 0x4e, 0x27, 0x59, - 0x65, 0x2f, 0x64, 0x3c, 0x62, 0x40, 0x69, 0x52, - 0x36, 0x49, 0x3e, 0x3b, 0x2c, 0x47, 0x4f, 0x3e, - 0x61, 0x78, 0x2d, 0x45, 0x71, 0x3f, 0x7b, 0x55, - 0x34, 0x36, 0x47, 0x5e, 0x36, 0x51, 0x3d, 0x5a, - 0x4b, 0x75, 0x44, 0x72, 0x61, 0x44, 0x71, 0x4e, - 0x42, 0x6a, 0x2c, 0x34, 0x40, 0x3b, 0x40, 0x31, - 0x31, 0x75, 0x4b, 0x32, 0x71, 0x69, 0x3a, 0x5d, - 0x31, 0x25, 0x53, 0x2a, 0x61, 0x54, 0x68, 0x2a, - 0x76, 0x71, 0x57, 0x67, 0x56, 0x23, 0x7d, 0x70, - 0x7d, 0x28, 0x57, 0x5f, 0x2f, 0x4c, 0x71, 0x2e, - 0x40, 0x63, 0x49, 0x5b, 0x7c, 0x7b, 0x56, 0x76, - 0x77, 0x46, 0x69, 0x56, 0x3d, 0x75, 0x31, 0x3b, - 0x35, 0x40, 0x37, 0x2c, 0x51, 0x37, 0x49, 0x6a, - 0x79, 0x68, 0x53, 0x31, 0x4c, 0x6f, 0x57, 0x4c, - 0x48, 0x31, 0x6a, 0x30, 0x2b, 0x69, 0x30, 0x56, - 0x58, 0x4b, 0x76, 0x3b, 0x60, 0x6d, 0x35, 0x4d, - 0x74, 0x2f, 0x74, 0x2c, 0x54, 0x4f, 0x6e, 0x3f, - 0x38, 0x56, 0x5c, 0x67, 0x2b, 0x4a, 0x35, 0x30, - 0x67, 0x7d, 0x58, 0x24, 0x59, 0x54, 0x48, 0x2e, - 0x28, 0x7d, 0x6e, 0x51, 0x55, 0x68, 0x56, 0x54, - 0x59, 0x31, 0x4a, 0x65, 0x5a, 0x5e, 0x27, 0x76, - 0x76, 0x65, 0x6d, 0x2f, 0x75, 0x63, 0x67, 0x52, - 0x5e, 0x29, 0x58, 0x3d, 0x5c, 0x3f, 0x54, 0x7c, - 0x67, 0x21, 0x6e, 0x75, 0x67, 0x35, 0x77, 0x31, - 0x3d, 0x26, 0x3f, 0x60, 0x45, 0x2d, 0x2b, 0x45, - 0x5d, 0x3f, 0x55, 0x73, 0x59, 0x4c, 0x5e, 0x6c, - 0x30, 0x4a, 0x4e, 0x47, 0x55, 0x42, 0x6a, 0x4b, - 0x32, 0x3c, 0x75, 0x6e, 0x36, 0x51, 0x5f, 0x4c, - 0x68, 0x72, 0x72, 0x27, 0x3b, 0x51, 0x59, 0x7b, - 0x68, 0x7b, 0x3b, 0x54, 0x35, 0x37, 0x7c, 0x44, - 0x43, 0x36, 0x4c, 0x4f, 0x67, 0x62, 0x4e, 0x39, - 0x4b, 0x7a, 0x49, 0x36, 0x68, 0x38, 0x4c, 0x4a, - 0x64, 0x33, 0x35, 0x2f, 0x3e, 0x5c, 0x58, 0x61, - 0x23, 0x5b, 0x50, 0x6e, 0x34, 0x44, 0x60, 0x28, - 0x54, 0x41, 0x5c, 0x31, 0x53, 0x2d, 0x58, 0x58, - 0x54, 0x28, 0x77, 0x51, 0x6f, 0x64, 0x4c, 0x68, - 0x34, 0x79, 0x45, 0x66, 0x2c, 0x26, 0x77, 0x64, - 0x5f, 0x6c, 0x3b, 0x71, 0x28, 0x4d, 0x68, 0x2a, - 0x6b, 0x37, 0x6a, 0x34, 0x51, 0x27, 0x2a, 0x46, - 0x3a, 0x2e, 0x35, 0x21, 0x21, 0x79, 0x51, 0x44, - 0x58, 0x5d, 0x6f, 0x65, 0x6b, 0x76, 0x68, 0x3a, - 0x43, 0x70, 0x36, 0x41, 0x6b, 0x56, 0x64, 0x75, - 0x5b, 0x37, 0x24, 0x56, 0x7c, 0x6e, 0x6c, 0x41, - 0x3a, 0x60, 0x56, 0x38, 0x55, 0x63, 0x77, 0x4d, - 0x6e, 0x50, 0x3c, 0x3d, 0x7a, 0x44, 0x71, 0x42, - 0x4b, 0x55, 0x75, 0x72, 0x61, 0x60, 0x65, 0x6f, - 0x7a, 0x26, 0x64, 0x46, 0x67, 0x74, 0x29, 0x2a, - 0x5b, 0x62, 0x41, 0x28, 0x62, 0x30, 0x34, 0x33, - 0x40, 0x79, 0x7a, 0x38, 0x56, 0x38, 0x73, 0x22, - 0x7a, 0x7d, 0x73, 0x2a, 0x2a, 0x28, 0x2b, 0x63, - 0x27, 0x6f, 0x3d, 0x3e, 0x2c, 0x56, 0x23, 0x32, - 0x4b, 0x3b, 0x58, 0x4d, 0x72, 0x4c, 0x49, 0x6f, - 0x30, 0x76, 0x23, 0x21, 0x21, 0x3c, 0x49, 0x56, - 0x7a, 0x56, 0x79, 0x2f, 0x50, 0x7a, 0x5b, 0x21, - 0x21, 0x4a, 0x48, 0x61, 0x33, 0x52, 0x49, 0x2e, - 0x30, 0x7d, 0x2c, 0x2d, 0x67, 0x23, 0x55, 0x62, - 0x66, 0x52, 0x5a, 0x61, 0x75, 0x63, 0x3c, 0x39, - 0x69, 0x41, 0x31, 0x6b, 0x4e, 0x6f, 0x25, 0x34, - 0x74, 0x30, 0x21, 0x3a, 0x40, 0x72, 0x44, 0x40, - 0x60, 0x4c, 0x53, 0x74, 0x42, 0x64, 0x44, 0x49, - 0x76, 0x67, 0x21, 0x79, 0x36, 0x3c, 0x37, 0x70, - 0x4f, 0x58, 0x29, 0x71, 0x2a, 0x3a, 0x4d, 0x5d, - 0x67, 0x68, 0x52, 0x63, 0x23, 0x24, 0x4b, 0x21, - 0x3f, 0x68, 0x69, 0x6c, 0x66, 0x66, 0x42, 0x28, - 0x59, 0x35, 0x34, 0x6f, 0x2d, 0x6a, 0x25, 0x66, - 0x34, 0x54, 0x5d, 0x50, 0x26, 0x41, 0x22, 0x4f, - 0x34, 0x79, 0x3c, 0x50, 0x68, 0x2d, 0x5f, 0x7b, - 0x63, 0x7d, 0x58, 0x2e, 0x73, 0x46, 0x2f, 0x54, - 0x61, 0x27, 0x74, 0x45, 0x23, 0x72, 0x31, 0x7d, - 0x63, 0x4b, 0x43, 0x5e, 0x44, 0x54, 0x2c, 0x38, - 0x58, 0x24, 0x75, 0x6c, 0x50, 0x3c, 0x23, 0x5f, - 0x35, 0x57, 0x4f, 0x7b, 0x2f, 0x57, 0x29, 0x73, - 0x58, 0x2a, 0x66, 0x3e, 0x49, 0x42, 0x5a, 0x6b, - 0x75, 0x6a, 0x38, 0x3f, 0x73, 0x44, 0x42, 0x46, - 0x2d, 0x39, 0x66, 0x5b, 0x28, 0x3e, 0x63, 0x62, - 0x53, 0x75, 0x65, 0x64, 0x79, 0x32, 0x35, 0x71, - 0x22, 0x6a, 0x7b, 0x41, 0x2b, 0x26, 0x43, 0x79, - 0x58, 0x6f, 0x71, 0x25, 0x24, 0x34, 0x72, 0x5b, - 0x4a, 0x2c, 0x5c, 0x77, 0x23, 0x42, 0x27, 0x6a, - 0x67, 0x51, 0x5f, 0x3c, 0x75, 0x2c, 0x3f, 0x43, - 0x45, 0x5b, 0x48, 0x65, 0x6f, 0x6c, 0x27, 0x65, - 0x21, 0x3e, 0x33, 0x37, 0x5f, 0x2b, 0x2e, 0x24, - 0x22, 0x47, 0x4e, 0x33, 0x5b, 0x7b, 0x21, 0x3c, - 0x53, 0x69, 0x2e, 0x31, 0x3d, 0x48, 0x57, 0x3a, - 0x56, 0x48, 0x6b, 0x47, 0x5d, 0x33, 0x41, 0x6c, - 0x66, 0x4c, 0x61, 0x67, 0x32, 0x69, 0x53, 0x2c, - 0x2f, 0x3e, 0x36, 0x68, 0x37, 0x28, 0x40, 0x21, - 0x76, 0x27, 0x44, 0x26, 0x24, 0x6a, 0x30, 0x75, - 0x2a, 0x73, 0x48, 0x36, 0x52, 0x4a, 0x3b, 0x51, - 0x4e, 0x2f, 0x23, 0x36, 0x4b, 0x49, 0x33, 0x5a, - 0x70, 0x2c, 0x54, 0x5b, 0x67, 0x48, 0x53, 0x5d, - 0x21, 0x3e, 0x6b, 0x52, 0x6a, 0x3c, 0x48, 0x29, - 0x68, 0x27, 0x32, 0x75, 0x61, 0x7c, 0x51, 0x2e, - 0x7b, 0x49, 0x2f, 0x5b, 0x3d, 0x74, 0x5a, 0x28, - 0x26, 0x29, 0x2c, 0x30, 0x54, 0x74, 0x45, 0x55, - 0x4a, 0x3d, 0x39, 0x35, 0x66, 0x56, 0x28, 0x6d, - 0x6e, 0x38, 0x7b, 0x2b, 0x40, 0x31, 0x56, 0x61, - 0x74, 0x2b, 0x79, 0x5f, 0x63, 0x51, 0x53, 0x52, - 0x7d, 0x73, 0x4e, 0x2e, 0x45, 0x3b, 0x22, 0x28, - 0x6c, 0x2b, 0x47, 0x21, 0x50, 0x2a, 0x7c, 0x45, - 0x48, 0x57, 0x3e, 0x2f, 0x6d, 0x66, 0x6c, 0x51, - 0x23, 0x6c, 0x37, 0x4d, 0x4b, 0x4b, 0x66, 0x55, - 0x69, 0x2e, 0x4a, 0x69, 0x71, 0x7c, 0x71, 0x30, - 0x5c, 0x43, 0x46, 0x63, 0x5a, 0x23, 0x75, 0x40 - }; - uint32_t request6_len = sizeof(request6); - - uint8_t request7[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x5d, 0x32, 0x55, 0x71, 0x51, 0x45, 0x4e, 0x54, - 0x34, 0x21, 0x46, 0x77, 0x5e, 0x5b, 0x75, 0x62, - 0x2b, 0x5c, 0x34, 0x26, 0x72, 0x2b, 0x2c, 0x64, - 0x4b, 0x65, 0x56, 0x72, 0x31, 0x7d, 0x6a, 0x5f, - 0x70, 0x26, 0x32, 0x29, 0x7d, 0x21, 0x5b, 0x3e, - 0x5e, 0x53, 0x3d, 0x48, 0x5e, 0x2a, 0x4c, 0x37, - 0x3d, 0x59, 0x79, 0x21, 0x4f, 0x56, 0x79, 0x2a, - 0x4e, 0x28, 0x61, 0x7d, 0x2c, 0x58, 0x2f, 0x78, - 0x5c, 0x3f, 0x5c, 0x42, 0x6d, 0x2f, 0x71, 0x54, - 0x25, 0x31, 0x73, 0x38, 0x6c, 0x31, 0x5a, 0x2e, - 0x42, 0x5b, 0x2d, 0x41, 0x24, 0x4c, 0x37, 0x40, - 0x39, 0x7d, 0x2a, 0x67, 0x60, 0x6a, 0x7a, 0x62, - 0x24, 0x4e, 0x3f, 0x2e, 0x69, 0x35, 0x28, 0x65, - 0x77, 0x53, 0x23, 0x44, 0x59, 0x71, 0x31, 0x5c, - 0x40, 0x5d, 0x3a, 0x27, 0x46, 0x55, 0x30, 0x56, - 0x21, 0x74, 0x3e, 0x73, 0x41, 0x22, 0x52, 0x68, - 0x40, 0x6c, 0x37, 0x3e, 0x62, 0x5a, 0x2e, 0x21, - 0x23, 0x33, 0x27, 0x73, 0x68, 0x26, 0x60, 0x67, - 0x70, 0x58, 0x50, 0x42, 0x58, 0x27, 0x3a, 0x35, - 0x6f, 0x51, 0x62, 0x78, 0x25, 0x2c, 0x7b, 0x66, - 0x34, 0x6a, 0x5a, 0x39, 0x60, 0x70, 0x41, 0x2d, - 0x65, 0x26, 0x5a, 0x67, 0x58, 0x2d, 0x3e, 0x56, - 0x6d, 0x30, 0x4b, 0x4d, 0x5d, 0x45, 0x41, 0x3d, - 0x6e, 0x27, 0x4e, 0x5a, 0x7d, 0x2e, 0x62, 0x4d, - 0x42, 0x70, 0x31, 0x24, 0x73, 0x5c, 0x78, 0x77, - 0x50, 0x73, 0x27, 0x48, 0x3d, 0x35, 0x2c, 0x4b, - 0x40, 0x2d, 0x25, 0x77, 0x5d, 0x3d, 0x6b, 0x50, - 0x6f, 0x57, 0x73, 0x2f, 0x4f, 0x6e, 0x4c, 0x6e, - 0x56, 0x7b, 0x55, 0x3c, 0x6d, 0x60, 0x47, 0x53, - 0x56, 0x39, 0x3b, 0x51, 0x61, 0x71, 0x75, 0x73, - 0x6b, 0x70, 0x58, 0x5f, 0x2c, 0x27, 0x74, 0x49, - 0x2c, 0x2b, 0x53, 0x2d, 0x5b, 0x79, 0x43, 0x34, - 0x39, 0x5a, 0x38, 0x3e, 0x2d, 0x66, 0x70, 0x3d, - 0x49, 0x51, 0x29, 0x4d, 0x5d, 0x4c, 0x57, 0x4a, - 0x2f, 0x41, 0x69, 0x56, 0x57, 0x77, 0x49, 0x58, - 0x75, 0x28, 0x29, 0x4a, 0x6d, 0x54, 0x4f, 0x4f, - 0x3f, 0x58, 0x5f, 0x58, 0x6f, 0x39, 0x22, 0x4d, - 0x5d, 0x31, 0x75, 0x43, 0x2f, 0x7d, 0x31, 0x3d, - 0x4c, 0x4d, 0x76, 0x74, 0x4d, 0x57, 0x3b, 0x56, - 0x57, 0x48, 0x2b, 0x5d, 0x32, 0x67, 0x51, 0x6e, - 0x60, 0x39, 0x6f, 0x64, 0x38, 0x37, 0x52, 0x4b, - 0x52, 0x42, 0x32, 0x4f, 0x24, 0x53, 0x31, 0x6e, - 0x4a, 0x68, 0x2f, 0x28, 0x2e, 0x27, 0x49, 0x75, - 0x77, 0x75, 0x26, 0x47, 0x7c, 0x5d, 0x72, 0x5a, - 0x77, 0x50, 0x2e, 0x6c, 0x27, 0x68, 0x6b, 0x7b, - 0x27, 0x63, 0x21, 0x3d, 0x30, 0x2d, 0x5c, 0x67, - 0x4d, 0x41, 0x79, 0x47, 0x42, 0x50, 0x6d, 0x32, - 0x74, 0x39, 0x62, 0x4d, 0x5f, 0x65, 0x78, 0x4f, - 0x67, 0x3a, 0x60, 0x26, 0x45, 0x61, 0x7c, 0x61, - 0x63, 0x40, 0x46, 0x79, 0x52, 0x47, 0x57, 0x49, - 0x53, 0x4c, 0x48, 0x36, 0x67, 0x47, 0x5c, 0x71, - 0x50, 0x4d, 0x4f, 0x58, 0x26, 0x40, 0x6d, 0x54, - 0x55, 0x67, 0x66, 0x23, 0x70, 0x23, 0x68, 0x70, - 0x4d, 0x2c, 0x7a, 0x3d, 0x60, 0x51, 0x35, 0x64, - 0x56, 0x2f, 0x26, 0x6d, 0x72, 0x6a, 0x59, 0x34, - 0x3a, 0x73, 0x4b, 0x27, 0x33, 0x61, 0x26, 0x45, - 0x61, 0x28, 0x74, 0x22, 0x54, 0x50, 0x2e, 0x39, - 0x6a, 0x2c, 0x27, 0x59, 0x26, 0x73, 0x44, 0x71, - 0x67, 0x4c, 0x37, 0x74, 0x2c, 0x63, 0x52, 0x2a, - 0x60, 0x4f, 0x7b, 0x32, 0x39, 0x21, 0x79, 0x54, - 0x79, 0x6d, 0x28, 0x27, 0x3a, 0x6a, 0x7d, 0x40, - 0x6a, 0x4f, 0x4b, 0x46, 0x61, 0x36, 0x6a, 0x22, - 0x3f, 0x77, 0x2d, 0x6a, 0x3b, 0x73, 0x71, 0x72, - 0x3c, 0x21, 0x2e, 0x3f, 0x33, 0x25, 0x76, 0x64, - 0x64, 0x70, 0x43, 0x32, 0x44, 0x73, 0x61, 0x51, - 0x3c, 0x3b, 0x45, 0x3a, 0x68, 0x46, 0x5b, 0x6e, - 0x36, 0x47, 0x4d, 0x38, 0x26, 0x4f, 0x5c, 0x7d, - 0x73, 0x29, 0x24, 0x78, 0x44, 0x75, 0x40, 0x42, - 0x41, 0x2a, 0x73, 0x2b, 0x24, 0x38, 0x51, 0x67, - 0x36, 0x67, 0x2f, 0x70, 0x58, 0x54, 0x6e, 0x5d, - 0x3b, 0x41, 0x59, 0x76, 0x7d, 0x2d, 0x40, 0x70, - 0x29, 0x4a, 0x4a, 0x31, 0x79, 0x2c, 0x4e, 0x22, - 0x31, 0x59, 0x31, 0x3c, 0x2f, 0x21, 0x29, 0x3f, - 0x65, 0x6c, 0x38, 0x55, 0x4f, 0x27, 0x66, 0x66, - 0x34, 0x45, 0x49, 0x41, 0x56, 0x24, 0x2e, 0x40, - 0x36, 0x23, 0x5a, 0x46, 0x40, 0x23, 0x7b, 0x2d, - 0x69, 0x54, 0x6c, 0x51, 0x58, 0x73, 0x56, 0x60, - 0x5f, 0x60, 0x63, 0x5f, 0x77, 0x6a, 0x4c, 0x2c, - 0x35, 0x39, 0x60, 0x73, 0x63, 0x3e, 0x2d, 0x55, - 0x5a, 0x26, 0x4b, 0x43, 0x3b, 0x56, 0x33, 0x58, - 0x74, 0x51, 0x4f, 0x5c, 0x2a, 0x44, 0x78, 0x66, - 0x78, 0x71, 0x40, 0x29, 0x5e, 0x26, 0x57, 0x51, - 0x49, 0x30, 0x29, 0x73, 0x38, 0x56, 0x6c, 0x41, - 0x78, 0x3d, 0x61, 0x3d, 0x2c, 0x33, 0x46, 0x57, - 0x54, 0x63, 0x3e, 0x79, 0x55, 0x4a, 0x7d, 0x2e, - 0x2a, 0x3c, 0x77, 0x47, 0x35, 0x29, 0x5a, 0x6d, - 0x69, 0x48, 0x6b, 0x73, 0x7d, 0x4f, 0x5f, 0x6f, - 0x3a, 0x7a, 0x4e, 0x54, 0x59, 0x38, 0x62, 0x44, - 0x72, 0x51, 0x57, 0x6a, 0x74, 0x54, 0x4f, 0x77, - 0x6b, 0x66, 0x4a, 0x6b, 0x39, 0x29, 0x69, 0x60, - 0x71, 0x52, 0x6a, 0x32, 0x66, 0x6c, 0x25, 0x76, - 0x27, 0x7a, 0x2c, 0x38, 0x72, 0x4e, 0x5f, 0x40, - 0x26, 0x74, 0x6a, 0x5e, 0x42, 0x38, 0x78, 0x34, - 0x4f, 0x4f, 0x35, 0x27, 0x39, 0x62, 0x52, 0x61, - 0x37, 0x54, 0x47, 0x38, 0x70, 0x31, 0x7a, 0x66, - 0x69, 0x72, 0x24, 0x52, 0x2a, 0x2a, 0x78, 0x72, - 0x2b, 0x2e, 0x2a, 0x57, 0x4a, 0x21, 0x52, 0x3c, - 0x2a, 0x2f, 0x24, 0x58, 0x34, 0x3c, 0x42, 0x5c, - 0x5b, 0x78, 0x27, 0x55, 0x63, 0x58, 0x3e, 0x26, - 0x50, 0x2c, 0x72, 0x60, 0x36, 0x6c, 0x46, 0x58, - 0x63, 0x59, 0x23, 0x2a, 0x2d, 0x63, 0x6a, 0x68, - 0x69, 0x74, 0x3f, 0x49, 0x4f, 0x48, 0x4a, 0x3b, - 0x59, 0x56, 0x77, 0x43, 0x6d, 0x57, 0x28, 0x5f, - 0x39, 0x73, 0x28, 0x74, 0x3c, 0x4f, 0x43, 0x48, - 0x6a, 0x57, 0x5d, 0x41, 0x73, 0x3f, 0x41, 0x7c, - 0x65, 0x5e, 0x2d, 0x38, 0x72, 0x3a, 0x53, 0x3e, - 0x33, 0x47, 0x69, 0x6a, 0x6e, 0x78, 0x67, 0x5d, - 0x35, 0x3b, 0x3f, 0x23, 0x7c, 0x71, 0x3d, 0x7c, - 0x3a, 0x3c, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, - 0x50, 0x6a, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x50, 0x6a, 0x40, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x50, 0x6a, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x50, 0x6a, 0x40, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x50, 0x80, 0x23, 0x00, 0xdf, 0xaf, 0xff, 0x33, - 0x9b, 0x78, 0x70, 0x43, 0xc5, 0x0a, 0x4d, 0x98, - 0x96, 0x02, 0x64, 0x92, 0xc1, 0xee, 0x70, 0x32 - }; - uint32_t request7_len = sizeof(request7); - - uint8_t request8[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x65, 0xc1, 0xef, 0x7b, 0xd6, 0xaa, 0xd6, 0x09, - 0x21, 0xf6, 0xe7, 0xd1, 0x4c, 0xdf, 0x6a, 0x2d, - 0x0a, 0xfb, 0x43, 0xea, 0xda, 0x07, 0x24, 0x84, - 0x88, 0x52, 0x9e, 0xa8, 0xa1, 0x7f, 0x4b, 0x60, - 0xec, 0x94, 0x57, 0x33, 0x06, 0x93, 0x92, 0x25, - 0xd6, 0xac, 0xdc, 0x89, 0x68, 0x5e, 0xbb, 0x32, - 0x2b, 0x17, 0x68, 0xf2, 0x06, 0xb7, 0x86, 0xac, - 0x81, 0xfe, 0x52, 0x27, 0xf5, 0x80, 0x11, 0x0d, - 0x4e, 0x2e, 0x1b, 0xa3, 0x44, 0x8a, 0x58, 0xed, - 0xf3, 0x9c, 0xe9, 0x31, 0x01, 0x72, 0xa6, 0xab, - 0xfa, 0xa8, 0x05, 0x00, 0x37, 0x60, 0x6b, 0x81, - 0xef, 0xf4, 0x96, 0x9a, 0xf7, 0x67, 0x95, 0x27, - 0x7a, 0x25, 0xef, 0x6f, 0x0e, 0xff, 0x2d, 0x15, - 0x7f, 0x23, 0x1c, 0xa7, 0x56, 0x94, 0x4a, 0x18, - 0x98, 0xc6, 0xd8, 0xd2, 0x29, 0x5b, 0x57, 0xb8, - 0x5d, 0x3a, 0x93, 0x58, 0x45, 0x77, 0x36, 0xe3, - 0xd1, 0x36, 0x87, 0xff, 0xe3, 0x94, 0x0f, 0x00, - 0xe6, 0x7c, 0x1a, 0x92, 0xc1, 0x5f, 0x40, 0xc3, - 0xa3, 0x25, 0xce, 0xd4, 0xaf, 0x39, 0xeb, 0x17, - 0xcf, 0x22, 0x43, 0xd9, 0x0c, 0xce, 0x37, 0x86, - 0x46, 0x54, 0xd6, 0xce, 0x00, 0x30, 0x36, 0xae, - 0xf9, 0xb5, 0x2b, 0x11, 0xa0, 0xfe, 0xa3, 0x4b, - 0x2e, 0x05, 0xbe, 0x54, 0xa9, 0xd8, 0xa5, 0x76, - 0x83, 0x5b, 0x63, 0x01, 0x1c, 0xd4, 0x56, 0x72, - 0xcd, 0xdc, 0x4a, 0x1d, 0x77, 0xda, 0x8a, 0x9e, - 0xba, 0xcb, 0x6c, 0xe8, 0x19, 0x5d, 0x68, 0xef, - 0x8e, 0xbc, 0x6a, 0x05, 0x53, 0x0b, 0xc7, 0xc5, - 0x96, 0x84, 0x04, 0xd9, 0xda, 0x4c, 0x42, 0x31, - 0xd9, 0xbd, 0x99, 0x06, 0xf7, 0xa3, 0x0a, 0x19, - 0x49, 0x07, 0x77, 0xf0, 0xdb, 0x7c, 0x43, 0xfa, - 0xb2, 0xad, 0xb0, 0xfa, 0x87, 0x52, 0xba, 0xc9, - 0x94, 0x61, 0xdc, 0xcf, 0x16, 0xac, 0x0f, 0x4a, - 0xa3, 0x6b, 0x5b, 0x6e, 0x27, 0x86, 0x1f, 0xfe, - 0x4d, 0x28, 0x3a, 0xa5, 0x10, 0x54, 0x6d, 0xed, - 0x53, 0xf9, 0x73, 0xc6, 0x6e, 0xa8, 0xc0, 0x97, - 0xcf, 0x56, 0x3b, 0x61, 0xdf, 0xab, 0x83, 0x18, - 0xe8, 0x09, 0xee, 0x6a, 0xb7, 0xf5, 0xc9, 0x62, - 0x55, 0x2d, 0xc7, 0x0c, 0x0d, 0xa0, 0x22, 0xd8, - 0xd4, 0xd6, 0xb2, 0x12, 0x21, 0xd7, 0x73, 0x3e, - 0x41, 0xb0, 0x5c, 0xd4, 0xcf, 0x98, 0xf3, 0x70, - 0xe6, 0x08, 0xe6, 0x2a, 0x4f, 0x24, 0x85, 0xe8, - 0x74, 0xa8, 0x41, 0x5f, 0x0e, 0xfd, 0xf1, 0xf3, - 0xbe, 0x9b, 0x14, 0xfd, 0xc0, 0x73, 0x11, 0xff, - 0xa5, 0x5b, 0x06, 0x34, 0xc3, 0x6c, 0x28, 0x42, - 0x07, 0xfe, 0x8a, 0xa5, 0xbe, 0x72, 0x7a, 0xf7, - 0xfa, 0x25, 0xec, 0x35, 0x5e, 0x98, 0x71, 0x50, - 0x60, 0x35, 0x76, 0x53, 0x40, 0x1a, 0x34, 0xa5, - 0x99, 0x09, 0xa2, 0xc6, 0xca, 0xa5, 0xce, 0x08, - 0x50, 0x45, 0xab, 0x8d, 0xfb, 0xe3, 0xb8, 0xe4, - 0x8a, 0x61, 0x48, 0x14, 0x6e, 0xf7, 0x58, 0x71, - 0xe5, 0x2e, 0xbc, 0x12, 0xd1, 0x25, 0xe9, 0x65, - 0x7a, 0xa1, 0x27, 0xbe, 0x3b, 0x8b, 0xe8, 0xe7, - 0xbc, 0xe1, 0x05, 0xe7, 0x92, 0xeb, 0xb9, 0xdf, - 0x5d, 0x53, 0x74, 0xc0, 0x63, 0x97, 0x80, 0xb8, - 0x3c, 0xae, 0xf3, 0xf2, 0x09, 0x12, 0x81, 0x6c, - 0x69, 0x10, 0x6f, 0xf6, 0xbe, 0x03, 0x7b, 0x88, - 0xcf, 0x26, 0x6b, 0x51, 0x06, 0x23, 0x68, 0x03, - 0xa1, 0xb7, 0xd3, 0x0c, 0xca, 0xbf, 0x29, 0x01, - 0xa9, 0x61, 0x34, 0x75, 0x98, 0x1e, 0x05, 0x59, - 0xb3, 0x46, 0x44, 0xff, 0x2b, 0x98, 0x04, 0x88, - 0x89, 0xfd, 0x7f, 0xd5, 0x19, 0x8a, 0xa6, 0xf3, - 0xd9, 0x44, 0xd5, 0xf9, 0x3a, 0x3c, 0xec, 0xd9, - 0x9b, 0x8c, 0x93, 0x93, 0x2b, 0x44, 0x86, 0x8b, - 0x80, 0x83, 0x23, 0x00, 0xdf, 0xaf, 0xff, 0x33, - 0x9b, 0x78, 0x70, 0x43, 0xf1, 0x55, 0x87, 0xb1, - 0xa1, 0xb3, 0x8e, 0x79, 0x02, 0x70, 0x82, 0x6c, - 0x0b, 0xc1, 0xef, 0x96, 0xf1, 0xef, 0xdd, 0xa2, - 0x69, 0x86, 0xc7, 0x85, 0x09, 0x7e, 0xf0, 0x2f, - 0x8e, 0xa0, 0x5f, 0xea, 0x39, 0x2e, 0x24, 0xf0, - 0x82, 0x30, 0x26, 0xa8, 0xa1, 0x4f, 0xc6, 0x5c, - 0xec, 0x94, 0x87, 0x52, 0x9b, 0x93, 0x92, 0xf3, - 0xa3, 0x1b, 0xc7, 0x8f, 0x9e, 0xb3, 0xbb, 0x32, - 0x2b, 0x17, 0x54, 0xf2, 0x06, 0x0c, 0x86, 0x92, - 0x0f, 0xb8, 0xe0, 0x27, 0x50, 0xaa, 0xeb, 0xf5, - 0x4e, 0x2b, 0x1b, 0xb2, 0x44, 0xe6, 0x58, 0x02, - 0xd7, 0x65, 0xdc, 0x31, 0x01, 0xec, 0xa6, 0xab, - 0xfa, 0xa8, 0x05, 0x00, 0x37, 0x60, 0x4f, 0xa1, - 0x3c, 0x4f, 0x7a, 0x9a, 0x10, 0x67, 0x95, 0xc2, - 0x5b, 0x25, 0xef, 0x76, 0x0e, 0xff, 0x2d, 0x15, - 0x7f, 0x23, 0x1c, 0x77, 0x56, 0x94, 0x4a, 0x18, - 0x98, 0xc6, 0xd8, 0xd2, 0x29, 0x44, 0x57, 0xb8, - 0x40, 0x3a, 0x93, 0x58, 0x45, 0x77, 0x36, 0x36, - 0x07, 0x35, 0x2a, 0xff, 0x00, 0x94, 0x5c, 0x80, - 0xe6, 0x7c, 0x1a, 0x92, 0xc1, 0x5f, 0x40, 0xc3, - 0xbc, 0xf8, 0xce, 0x05, 0x77, 0x39, 0x40, 0x17, - 0xcf, 0x63, 0x43, 0x77, 0x27, 0xce, 0x37, 0x86, - 0x46, 0x54, 0xd6, 0xce, 0x00, 0x30, 0x36, 0xae, - 0x9f, 0x24, 0x2b, 0x5a, 0xa0, 0xfe, 0xa3, 0x4b, - 0x2e, 0x7e, 0xf7, 0x54, 0xa9, 0xd8, 0xa5, 0x76, - 0x83, 0x7b, 0x63, 0x01, 0x1c, 0xd4, 0x56, 0x17, - 0x02, 0xdc, 0x4a, 0x89, 0x77, 0xda, 0x8f, 0x9e, - 0xba, 0xcb, 0x37, 0xe8, 0x19, 0x5d, 0x68, 0x38, - 0x8e, 0xbc, 0x6a, 0x05, 0x53, 0x0b, 0xc7, 0xc5, - 0x96, 0x84, 0x5a, 0xd9, 0x6d, 0x4c, 0x42, 0x31, - 0xd9, 0xf2, 0x99, 0x06, 0xf7, 0x0c, 0x99, 0xbe, - 0x49, 0x07, 0x77, 0xf0, 0x8b, 0x7c, 0x43, 0xfa, - 0xb2, 0xad, 0xb0, 0xfa, 0x87, 0x52, 0xba, 0xc9, - 0x94, 0x61, 0xdc, 0xcf, 0x16, 0xac, 0x0f, 0x4a, - 0xa3, 0x6b, 0x5b, 0x6e, 0x27, 0x86, 0x1f, 0xfe, - 0x4d, 0x28, 0x3a, 0xa5, 0x10, 0x98, 0x6d, 0xed, - 0x53, 0xf9, 0x73, 0xc6, 0xa5, 0xa8, 0xf7, 0x66, - 0xcf, 0x56, 0x3b, 0x61, 0xdf, 0xab, 0x83, 0x18, - 0xe8, 0x09, 0xee, 0x6a, 0xb7, 0xf5, 0xc9, 0x62, - 0x55, 0x2d, 0xc7, 0x0c, 0x0d, 0xa0, 0x22, 0xd8, - 0xd4, 0xd6, 0xb2, 0x12, 0x21, 0xd7, 0x73, 0x3e, - 0x41, 0xb0, 0x5c, 0xd4, 0xcf, 0x98, 0xf3, 0x70, - 0xe6, 0x08, 0xe6, 0x2a, 0x4f, 0x92, 0x85, 0xe8, - 0x74, 0xa8, 0x41, 0x5f, 0x0e, 0xfd, 0xf1, 0xf3, - 0xbe, 0x9b, 0x14, 0xfd, 0xc0, 0x73, 0x11, 0xff, - 0xa5, 0x5b, 0x06, 0x34, 0xc3, 0x5d, 0x28, 0x42, - 0x34, 0xfe, 0x8a, 0xa5, 0xbe, 0x72, 0x7a, 0xf7, - 0xfa, 0x25, 0x2b, 0x35, 0x5e, 0x98, 0x71, 0x50, - 0x2c, 0x35, 0x76, 0x53, 0x4e, 0x1a, 0x34, 0xa5, - 0x99, 0x09, 0xa2, 0xc6, 0xca, 0xa5, 0xce, 0x08, - 0x50, 0x45, 0xab, 0x8d, 0xfb, 0xe3, 0xb8, 0xe4, - 0x8a, 0x61, 0x48, 0x14, 0x6e, 0xf7, 0x58, 0x71, - 0xe5, 0x2e, 0xbc, 0x12, 0xd1, 0x25, 0xe9, 0x65, - 0x7a, 0xa1, 0x27, 0xbe, 0x3b, 0x8b, 0xe8, 0xe7, - 0xbc, 0x77, 0x05, 0xe7, 0x92, 0xeb, 0xb9, 0xdf, - 0x5d, 0x53, 0x74, 0xc0, 0x63, 0x97, 0x80, 0xb8, - 0x3c, 0xae, 0xf3, 0xf2, 0x09, 0x12, 0x81, 0x6c, - 0x69, 0x10, 0x6f, 0xf6, 0xbe, 0x03, 0x7b, 0x88, - 0xcf, 0x26, 0x6b, 0x51, 0x06, 0x23, 0x68, 0x03, - 0xa1, 0xb7, 0xd3, 0x0c, 0xca, 0xbf, 0x29, 0x01, - 0xa9, 0x61, 0x34, 0x75, 0x98, 0x1e, 0x6f, 0x59, - 0xb3, 0x46, 0x44, 0xff, 0x2b, 0x98, 0x04, 0x88, - 0x89, 0xfd, 0x1c, 0xd5, 0x19, 0x8a, 0xa6, 0xf3, - 0xd9, 0x44, 0xd5, 0xf9, 0x79, 0x26, 0x46, 0xf7 - }; - uint32_t request8_len = sizeof(request8); - - uint8_t request9[] = { - 0x05, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xbf, 0xa1, 0x12, 0x73, 0x23, 0x44, 0x86, 0x8b, - 0x50, 0x6a, 0x40, 0x00 - }; - uint32_t request9_len = sizeof(request9); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - /* bind */ - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_START, - bind, bind_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 0) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - - /* bind_ack */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - bind_ack, bind_ack_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 0) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - - /* request1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 1024 && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 1) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh = 0; - - /* request2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 2048 && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 1) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh = 0; - - /* request3 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request3, request3_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 3072 && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 1) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh = 0; - - /* request4 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request4, request4_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 4096 && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 1) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh = 0; - - /* request5 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request5, request5_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 5120) && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL); - if (result == 0) - goto end; - - /* request6 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request6, request6_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 6144 && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 1) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh = 0; - - /* request7 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request7, request7_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 7168 && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 1) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh = 0; - - /* request8 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request8, request8_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 8192 && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 1) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh = 0; - - /* request9 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request9, request9_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 8204 && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 1) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh = 0; - - /* request1 again */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - result &= ( (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 1024 && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh == 1) && - (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) ); - if (result == 0) - goto end; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -#endif - return 1; -} - -/** - * \test General test. - */ -int DCERPCParserTest05(void) -{ - int result = 1; - Flow f; - int r = 0; - uint8_t bind1[] = { - 0x05, 0x00, 0x0b, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11, - 0x86, 0x1e, 0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x57, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind1_len = sizeof(bind1); - - uint8_t bind2[] = { - 0x05, 0x00, 0x0b, 0x02, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, - 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11, - 0x86, 0x1e, 0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x67, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind2_len = sizeof(bind2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - bind1, bind1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - DCERPCUuidEntry *item = NULL; - int m = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.uuid_list, next) { - printf("%d ", m); - printUUID("BIND",item); - m++; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - bind2, bind2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - item = NULL; - m = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.uuid_list, next) { - printf("%d ", m); - printUUID("BIND",item); - m++; - } - - /* we will need this test later for fragged bind pdus. keep it */ - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test DCERPC fragmented bind PDU(one PDU which is frag'ed) - */ -int DCERPCParserTest06(void) -{ - int result = 1; - Flow f; - int r = 0; - uint8_t bind1[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xdc, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0xc7, 0x70, 0x0d, 0x3e, 0x71, 0x37, 0x39, 0x0d, - 0x3a, 0x4f, 0xd3, 0xdc, 0xca, 0x49, 0xe8, 0xa3, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x84, 0xb6, 0x55, 0x75, - 0xdb, 0x9e, 0xba, 0x54, 0x56, 0xd3, 0x45, 0x10, - 0xb7, 0x7a, 0x2a, 0xe2, 0x04, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x6e, 0x39, 0x21, 0x24, 0x70, 0x6f, 0x41, 0x57, - 0x54, 0x70, 0xb8, 0xc3, 0x5e, 0x89, 0x3b, 0x43, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x01, 0x00, 0x39, 0x6a, 0x86, 0x5d, - 0x24, 0x0f, 0xd2, 0xf7, 0xb6, 0xce, 0x95, 0x9c, - 0x54, 0x1d, 0x3a, 0xdb, 0x02, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x12, 0xa5, 0xdd, 0xc5, 0x55, 0xce, 0xc3, 0x46, - 0xbd, 0xa0, 0x94, 0x39, 0x3c, 0x0d, 0x9b, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x01, 0x00, 0x87, 0x1c, 0x8b, 0x6e, - 0x11, 0xa8, 0x67, 0x98, 0xd4, 0x5d, 0xf6, 0x8a, - 0x2f, 0x33, 0x24, 0x7b, 0x05, 0x00, 0x03, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, - 0x9b, 0x82, 0x13, 0xd1, 0x28, 0xe0, 0x63, 0xf3, - 0x62, 0xee, 0x76, 0x73, 0xf9, 0xac, 0x3d, 0x2e, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x01, 0x00, 0xa9, 0xd4, 0x73, 0xf2, - 0xed, 0xad, 0xe8, 0x82, 0xf8, 0xcf, 0x9d, 0x9f, - 0x66, 0xe6, 0x43, 0x37, 0x02, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x06, 0x2b, 0x85, 0x38, 0x4f, 0x73, 0x96, 0xb1, - 0x73, 0xe1, 0x59, 0xbe, 0x9d, 0xe2, 0x6c, 0x07, - 0x05, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60}; - uint32_t bind1_len = sizeof(bind1); - - uint8_t bind2[] = { - 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, - 0xbf, 0xfa, 0xbb, 0xa4, 0x9e, 0x5c, 0x80, 0x61, - 0xb5, 0x8b, 0x79, 0x69, 0xa6, 0x32, 0x88, 0x77, - 0x01, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x01, 0x00, 0x39, 0xa8, 0x2c, 0x39, - 0x73, 0x50, 0x06, 0x8d, 0xf2, 0x37, 0x1e, 0x1e, - 0xa8, 0x8f, 0x46, 0x98, 0x02, 0x00, 0x02, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, - 0x91, 0x13, 0xd0, 0xa7, 0xef, 0xc4, 0xa7, 0x96, - 0x0c, 0x4a, 0x0d, 0x29, 0x80, 0xd3, 0xfe, 0xbf, - 0x00, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x01, 0x00, 0xcc, 0x2b, 0x55, 0x1d, - 0xd4, 0xa4, 0x0d, 0xfb, 0xcb, 0x6f, 0x86, 0x36, - 0xa6, 0x57, 0xc3, 0x21, 0x02, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x01, 0x00, - 0x43, 0x7b, 0x07, 0xee, 0x85, 0xa8, 0xb9, 0x3a, - 0x0f, 0xf9, 0x83, 0x70, 0xe6, 0x0b, 0x4f, 0x33, - 0x02, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x01, 0x00, 0x9c, 0x6a, 0x15, 0x8c, - 0xd6, 0x9c, 0xa6, 0xc3, 0xb2, 0x9e, 0x62, 0x9f, - 0x3d, 0x8e, 0x47, 0x73, 0x02, 0x00, 0x02, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, - 0xc8, 0x4f, 0x32, 0x4b, 0x70, 0x16, 0xd3, 0x01, - 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind2_len = sizeof(bind2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_START, - bind1, bind1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - result &= (dcerpc_state->dcerpc.bytesprocessed == 420); - result &= (dcerpc_state->dcerpc.dcerpcbindbindack.ctxbytesprocessed == 40); - result &= (dcerpc_state->dcerpc.dcerpcbindbindack.numctxitems == 16); - result &= (dcerpc_state->dcerpc.dcerpcbindbindack.numctxitemsleft == 8); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - bind2, bind2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result &= (dcerpc_state->dcerpc.bytesprocessed == 0); - result &= (dcerpc_state->dcerpc.dcerpcbindbindack.ctxbytesprocessed == 0); - result &= (dcerpc_state->dcerpc.dcerpcbindbindack.numctxitems == 16); - result &= (dcerpc_state->dcerpc.dcerpcbindbindack.numctxitemsleft == 0); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test DCERPC fragmented bind PDU(one PDU which is frag'ed). - */ -int DCERPCParserTest07(void) -{ - int result = 1; - Flow f; - int r = 0; - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x0D, 0x0E - }; - uint32_t request2_len = sizeof(request2); - - uint8_t request3[] = { - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14 - }; - uint32_t request3_len = sizeof(request3); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_START, - request1, request1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - result &= (dcerpc_state->dcerpc.bytesprocessed == 36); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 12); - result &= (dcerpc_state->dcerpc.pdu_fragged = 1); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result &= (dcerpc_state->dcerpc.bytesprocessed == 38); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 14); - result &= (dcerpc_state->dcerpc.pdu_fragged = 1); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request3, request3_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result &= (dcerpc_state->dcerpc.bytesprocessed == 0); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 20); - result &= (dcerpc_state->dcerpc.pdu_fragged == 0); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test DCERPC fragmented bind PDU(one PDU which is frag'ed). - */ -int DCERPCParserTest08(void) -{ - int result = 1; - Flow f; - int r = 0; - uint8_t request[] = { - 0x05, 0x02, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, - }; - uint32_t request_len = sizeof(request); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - request, request_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - result &= (dcerpc_state->dcerpc.bytesprocessed == 0); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer == NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 0); - result &= (dcerpc_state->dcerpc.pdu_fragged == 0); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test DCERPC fragmented bind PDU(one PDU which is frag'ed). - */ -int DCERPCParserTest09(void) -{ - int result = 1; - Flow f; - int r = 0; - uint8_t request[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C, - }; - uint32_t request_len = sizeof(request); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - request, request_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - result &= (dcerpc_state->dcerpc.bytesprocessed == 36); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 12); - result &= (dcerpc_state->dcerpc.pdu_fragged == 1); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test DCERPC fragmented PDU. - */ -int DCERPCParserTest10(void) -{ - int result = 1; - Flow f; - int r = 0; - - uint8_t fault[] = { - 0x05, 0x00, 0x03, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0xf7, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t fault_len = sizeof(fault); - - uint8_t request1[] = { - 0x05, 0x00 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x24, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, - 0x0B, 0x0C - }; - uint32_t request2_len = sizeof(request2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER|STREAM_START, - fault, fault_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result &= (dcerpc_state->dcerpc.bytesprocessed == 2); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer == NULL); - result &= (dcerpc_state->dcerpc.pdu_fragged == 1); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result &= (dcerpc_state->dcerpc.bytesprocessed == 0); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 12); - result &= (dcerpc_state->dcerpc.pdu_fragged == 0); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test DCERPC fragmented PDU. - */ -int DCERPCParserTest11(void) -{ - int result = 1; - Flow f; - int r = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0A, 0x0B, 0x0C - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00 - }; - uint32_t request2_len = sizeof(request2); - - uint8_t request3[] = { - 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x26, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, - 0x0B, 0x0C, 0xFF, 0xFF - }; - uint32_t request3_len = sizeof(request3); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - result &= (dcerpc_state->dcerpc.bytesprocessed == 0); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 12); - result &= (dcerpc_state->dcerpc.pdu_fragged == 0); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result &= (dcerpc_state->dcerpc.bytesprocessed == 2); - result &= (dcerpc_state->dcerpc.pdu_fragged == 1); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request3, request3_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result &= (dcerpc_state->dcerpc.bytesprocessed == 0); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 14); - result &= (dcerpc_state->dcerpc.pdu_fragged == 0); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test DCERPC fragmented PDU. - */ -int DCERPCParserTest12(void) -{ - int result = 1; - Flow f; - int r = 0; - - uint8_t bind_ack1[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x48, 0x1a, 0x00, 0x00, - }; - uint32_t bind_ack1_len = sizeof(bind_ack1); - - uint8_t bind_ack2[] = { - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack2_len = sizeof(bind_ack2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - bind_ack1, bind_ack1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - result &= (dcerpc_state->dcerpc.bytesprocessed == 24); - result &= (dcerpc_state->dcerpc.pdu_fragged == 1); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - bind_ack2, bind_ack2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result &= (dcerpc_state->dcerpc.bytesprocessed == 0); - result &= (dcerpc_state->dcerpc.pdu_fragged == 0); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Check if the parser accepts bind pdus that have context ids starting - * from a non-zero value. - */ -int DCERPCParserTest13(void) -{ - int result = 1; - Flow f; - int r = 0; - - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, - 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - bind, bind_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - result &= (dcerpc_state->dcerpc.bytesprocessed == 0); - result &= (dcerpc_state->dcerpc.pdu_fragged == 0); - result &= (dcerpc_state->dcerpc.dcerpcbindbindack.numctxitems == 1); - if (result == 0) - goto end; - - result = 0; - uint8_t ctx_uuid_from_pcap[16] = { - 0x00, 0x00, 0x01, 0xa0, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}; - DCERPCUuidEntry *item = NULL; - int internal_id = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.uuid_list, next) { - int i = 0; - /* check the interface uuid */ - for (i = 0; i < 16; i++) { - if (ctx_uuid_from_pcap[i] != item->uuid[i]) { - result = 0; - goto end; - } - } - result = 1; - result &= (item->internal_id == internal_id++); - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Check for another endless loop with bind pdus. - */ -int DCERPCParserTest14(void) -{ - int result = 1; - Flow f; - int r = 0; - - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x4A, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, - 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x01, 0x02, 0x03, 0x04, 0xFF /* ka boom - endless loop */ - }; - uint32_t bind_len = sizeof(bind); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - bind, bind_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Check for another endless loop for bind_ack pdus. - */ -int DCERPCParserTest15(void) -{ - int result = 1; - Flow f; - int r = 0; - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x3e, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0xfd, 0x04, 0x01, 0x00, - 0x04, 0x00, 0x31, 0x33, 0x35, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x01, 0x02, 0x03, 0x04, 0xFF - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - bind_ack, bind_ack_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Check for correct internal ids for bind_acks. - */ -int DCERPCParserTest16(void) -{ - int result = 1; - Flow f; - int r = 0; - - uint8_t bind1[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x50, 0x08, 0x43, 0x95, 0x43, 0x5a, 0x8b, 0xb2, - 0xf4, 0xc5, 0xb9, 0xee, 0x67, 0x55, 0x7c, 0x19, - 0x00, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00, 0xda, 0xc2, 0xbc, 0x9b, - 0x35, 0x2e, 0xd4, 0xc9, 0x1f, 0x85, 0x01, 0xe6, - 0x4e, 0x5a, 0x5e, 0xd4, 0x04, 0x00, 0x03, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0xb2, 0x97, 0xcc, 0x14, 0x6f, 0x70, 0x0d, 0xa5, - 0x33, 0xd7, 0xf4, 0xe3, 0x8e, 0xb2, 0x2a, 0x1e, - 0x05, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x01, 0x00, 0x96, 0x4e, 0xa6, 0xf6, - 0xb2, 0x4b, 0xae, 0xb3, 0x21, 0xf4, 0x97, 0x7c, - 0xcd, 0xa7, 0x08, 0xb0, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, - 0xbc, 0xc0, 0xf7, 0x71, 0x3f, 0x71, 0x54, 0x44, - 0x22, 0xa8, 0x55, 0x0f, 0x98, 0x83, 0x1f, 0xfe, - 0x04, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x01, 0x00, 0xbe, 0x52, 0xf2, 0x58, - 0x4a, 0xc3, 0xb5, 0xd0, 0xba, 0xac, 0xda, 0xf0, - 0x12, 0x99, 0x38, 0x6e, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, - 0xdb, 0xfa, 0x73, 0x01, 0xb3, 0x81, 0x01, 0xd4, - 0x7f, 0xa0, 0x36, 0xb1, 0x97, 0xae, 0x29, 0x7f, - 0x01, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x01, 0x00, 0x89, 0xbe, 0x41, 0x1d, - 0x38, 0x75, 0xf5, 0xb5, 0xad, 0x27, 0x73, 0xf1, - 0xb0, 0x7a, 0x28, 0x82, 0x05, 0x00, 0x02, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, - 0xf6, 0x87, 0x09, 0x93, 0xb8, 0xa8, 0x20, 0xc4, - 0xb8, 0x63, 0xe6, 0x95, 0xed, 0x59, 0xee, 0x3f, - 0x05, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x01, 0x00, 0x92, 0x77, 0x92, 0x68, - 0x3e, 0xa4, 0xbc, 0x3f, 0x44, 0x33, 0x0e, 0xb8, - 0x33, 0x0a, 0x2f, 0xdf, 0x01, 0x00, 0x02, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, - 0xa1, 0x03, 0xd2, 0xa9, 0xd2, 0x16, 0xc9, 0x89, - 0x67, 0x18, 0x3e, 0xb1, 0xee, 0x6b, 0xf9, 0x18, - 0x02, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x01, 0x00, 0x2f, 0x09, 0x5e, 0x74, - 0xec, 0xa0, 0xbb, 0xc1, 0x60, 0x18, 0xf1, 0x93, - 0x04, 0x17, 0x11, 0xf9, 0x01, 0x00, 0x03, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, - 0xc8, 0x4f, 0x32, 0x4b, 0x70, 0x16, 0xd3, 0x01, - 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind1_len = sizeof(bind1); - - uint8_t bind_ack1[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0xc1, 0x2b, 0x00, 0x00, - 0x0e, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack1_len = sizeof(bind_ack1); - - uint8_t bind2[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xdc, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0xc7, 0x70, 0x0d, 0x3e, 0x71, 0x37, 0x39, 0x0d, - 0x3a, 0x4f, 0xd3, 0xdc, 0xca, 0x49, 0xe8, 0xa3, - 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x84, 0xb6, 0x55, 0x75, - 0xdb, 0x9e, 0xba, 0x54, 0x56, 0xd3, 0x45, 0x10, - 0xb7, 0x7a, 0x2a, 0xe2, 0x04, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x6e, 0x39, 0x21, 0x24, 0x70, 0x6f, 0x41, 0x57, - 0x54, 0x70, 0xb8, 0xc3, 0x5e, 0x89, 0x3b, 0x43, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x01, 0x00, 0x39, 0x6a, 0x86, 0x5d, - 0x24, 0x0f, 0xd2, 0xf7, 0xb6, 0xce, 0x95, 0x9c, - 0x54, 0x1d, 0x3a, 0xdb, 0x02, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x12, 0xa5, 0xdd, 0xc5, 0x55, 0xce, 0xc3, 0x46, - 0xbd, 0xa0, 0x94, 0x39, 0x3c, 0x0d, 0x9b, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x01, 0x00, 0x87, 0x1c, 0x8b, 0x6e, - 0x11, 0xa8, 0x67, 0x98, 0xd4, 0x5d, 0xf6, 0x8a, - 0x2f, 0x33, 0x24, 0x7b, 0x05, 0x00, 0x03, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, - 0x9b, 0x82, 0x13, 0xd1, 0x28, 0xe0, 0x63, 0xf3, - 0x62, 0xee, 0x76, 0x73, 0xf9, 0xac, 0x3d, 0x2e, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x01, 0x00, 0xa9, 0xd4, 0x73, 0xf2, - 0xed, 0xad, 0xe8, 0x82, 0xf8, 0xcf, 0x9d, 0x9f, - 0x66, 0xe6, 0x43, 0x37, 0x02, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x06, 0x2b, 0x85, 0x38, 0x4f, 0x73, 0x96, 0xb1, - 0x73, 0xe1, 0x59, 0xbe, 0x9d, 0xe2, 0x6c, 0x07, - 0x05, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x01, 0x00, 0xbf, 0xfa, 0xbb, 0xa4, - 0x9e, 0x5c, 0x80, 0x61, 0xb5, 0x8b, 0x79, 0x69, - 0xa6, 0x32, 0x88, 0x77, 0x01, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, - 0x39, 0xa8, 0x2c, 0x39, 0x73, 0x50, 0x06, 0x8d, - 0xf2, 0x37, 0x1e, 0x1e, 0xa8, 0x8f, 0x46, 0x98, - 0x02, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x01, 0x00, 0x91, 0x13, 0xd0, 0xa7, - 0xef, 0xc4, 0xa7, 0x96, 0x0c, 0x4a, 0x0d, 0x29, - 0x80, 0xd3, 0xfe, 0xbf, 0x00, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, - 0xcc, 0x2b, 0x55, 0x1d, 0xd4, 0xa4, 0x0d, 0xfb, - 0xcb, 0x6f, 0x86, 0x36, 0xa6, 0x57, 0xc3, 0x21, - 0x02, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x01, 0x00, 0x43, 0x7b, 0x07, 0xee, - 0x85, 0xa8, 0xb9, 0x3a, 0x0f, 0xf9, 0x83, 0x70, - 0xe6, 0x0b, 0x4f, 0x33, 0x02, 0x00, 0x02, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x00, - 0x9c, 0x6a, 0x15, 0x8c, 0xd6, 0x9c, 0xa6, 0xc3, - 0xb2, 0x9e, 0x62, 0x9f, 0x3d, 0x8e, 0x47, 0x73, - 0x02, 0x00, 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x0f, 0x00, 0x01, 0x00, 0xc8, 0x4f, 0x32, 0x4b, - 0x70, 0x16, 0xd3, 0x01, 0x12, 0x78, 0x5a, 0x47, - 0xbf, 0x6e, 0xe1, 0x88, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind2_len = sizeof(bind2); - - uint8_t bind_ack2[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xac, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0xc2, 0x2b, 0x00, 0x00, - 0x0e, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack2_len = sizeof(bind_ack2); - - uint8_t bind3[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x2c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0xa4, 0x7f, 0x8e, 0xc6, 0xef, 0x56, 0x9b, 0x63, - 0x92, 0xfa, 0x08, 0xb3, 0x35, 0xe2, 0xa5, 0x81, - 0x00, 0x00, 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x9f, 0xfc, 0x78, 0xd2, - 0x5f, 0x16, 0x0b, 0xbc, 0xc6, 0xdb, 0x5d, 0xef, - 0xde, 0x54, 0xa2, 0x6f, 0x04, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x78, 0xb8, 0x96, 0xc7, 0x2f, 0xda, 0x11, 0x6b, - 0xd1, 0x28, 0x68, 0xe1, 0xd6, 0x71, 0xac, 0x9d, - 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x01, 0x00, 0xcf, 0xf4, 0xd7, 0x37, - 0x03, 0xda, 0xcc, 0xe3, 0x3e, 0x34, 0x7f, 0x67, - 0x99, 0x91, 0x41, 0x3d, 0x01, 0x00, 0x02, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, - 0x48, 0xeb, 0x32, 0xf0, 0x27, 0xd5, 0x9d, 0xd0, - 0x1e, 0xc6, 0x48, 0x46, 0x97, 0xe9, 0xdb, 0x09, - 0x05, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x01, 0x00, 0x82, 0xec, 0x0d, 0x08, - 0xf2, 0x8f, 0x22, 0x57, 0x42, 0x9b, 0xce, 0xa8, - 0x74, 0x16, 0xc6, 0xec, 0x00, 0x00, 0x01, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, - 0x2e, 0x00, 0x70, 0x44, 0xee, 0xc9, 0x30, 0x6b, - 0xf4, 0x34, 0x1e, 0x3d, 0x35, 0x0f, 0xf7, 0xf7, - 0x00, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x01, 0x00, 0x59, 0x04, 0x39, 0x3f, - 0x59, 0x87, 0x14, 0x0e, 0x76, 0x8d, 0x17, 0xc2, - 0x47, 0xfa, 0x67, 0x7f, 0x04, 0x00, 0x02, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, - 0x30, 0xd6, 0xed, 0x2e, 0x57, 0xfa, 0xf4, 0x72, - 0x6c, 0x10, 0x0d, 0xe5, 0x51, 0x7f, 0xd0, 0x39, - 0x02, 0x00, 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x01, 0x00, 0xea, 0x8b, 0x84, 0x4d, - 0x44, 0x43, 0xc1, 0x94, 0x75, 0xe2, 0x81, 0x48, - 0xd8, 0x77, 0xd9, 0xce, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, - 0x89, 0x4f, 0xe7, 0x95, 0xa3, 0xc1, 0x62, 0x36, - 0x26, 0x9e, 0x67, 0xdb, 0x2c, 0x52, 0x89, 0xd3, - 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x01, 0x00, 0x78, 0x56, 0x34, 0x12, - 0x34, 0x12, 0xcd, 0xab, 0xef, 0x00, 0x01, 0x23, - 0x45, 0x67, 0x89, 0xab, 0x01, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind3_len = sizeof(bind3); - - uint8_t bind_ack3[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x4c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x1a, 0x33, 0x00, 0x00, - 0x0e, 0x00, 0x5c, 0x70, 0x69, 0x70, 0x65, 0x5c, - 0x73, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x73, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack3_len = sizeof(bind_ack3); - - TcpSession ssn; - DCERPCUuidEntry *item = NULL; - int count = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - uint8_t accepted_uuids[3][16] = { - {0x4b, 0x32, 0x4f, 0xc8, 0x16, 0x70, 0x01, 0xd3, - 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88}, - {0x4b, 0x32, 0x4f, 0xc8, 0x16, 0x70, 0x01, 0xd3, - 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88}, - {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0xab, 0xcd, - 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab} - }; - - uint16_t accepted_ctxids[3] = {12, 15, 11}; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - bind1, bind1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - bind_ack1, bind_ack1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - count = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { - int i = 0; - /* check the interface uuid */ - for (i = 0; i < 16; i++) { - if (accepted_uuids[0][i] != item->uuid[i]) { - result = 0; - goto end; - } - } - if (accepted_ctxids[0] != item->ctxid) { - result = 0; - goto end; - } - count++; - } - if (count != 1) { - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - bind2, bind2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - count = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { - count++; - } - if (count != 0) { - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - bind_ack2, bind_ack2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - count = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { - int i = 0; - /* check the interface uuid */ - for (i = 0; i < 16; i++) { - if (accepted_uuids[1][i] != item->uuid[i]) { - result = 0; - goto end; - } - } - if (accepted_ctxids[1] != item->ctxid) { - result = 0; - goto end; - } - count++; - } - if (count != 1) { - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - bind3, bind3_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - count = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { - count++; - } - if (count != 0) { - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - bind_ack3, bind_ack3_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - count = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { - int i = 0; - /* check the interface uuid */ - for (i = 0; i < 16; i++) { - if (accepted_uuids[2][i] != item->uuid[i]) { - result = 0; - goto end; - } - } - if (accepted_ctxids[2] != item->ctxid) { - result = 0; - goto end; - } - count++; - } - if (count != 1) { - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - - -/** - * \test Check for correct internal ids for bind_acks + alter_contexts - */ -int DCERPCParserTest17(void) -{ - int result = 1; - Flow f; - int r = 0; - - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x40, 0xfd, 0x2c, 0x34, 0x6c, 0x3c, 0xce, 0x11, - 0xa8, 0x93, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, - 0x0d, 0x00, 0x5c, 0x70, 0x69, 0x70, 0x65, 0x5c, - 0x6c, 0x6c, 0x73, 0x72, 0x70, 0x63, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t alter_context[] = { - 0x05, 0x00, 0x0e, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, - 0xd0, 0x4c, 0x67, 0x57, 0x00, 0x52, 0xce, 0x11, - 0xa8, 0x97, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, - 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t alter_context_len = sizeof(alter_context); - - uint8_t alter_context_resp[] = { - 0x05, 0x00, 0x0f, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t alter_context_resp_len = sizeof(alter_context_resp); - - - TcpSession ssn; - DCERPCUuidEntry *item = NULL; - int count = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - uint8_t accepted_uuids[2][16] = { - {0x57, 0x67, 0x4c, 0xd0, 0x52, 0x00, 0x11, 0xce, - 0xa8, 0x97, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d}, - {0x34, 0x2c, 0xfd, 0x40, 0x3c, 0x6c, 0x11, 0xce, - 0xa8, 0x93, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d}, - }; - - uint16_t accepted_ctxids[2] = {1, 0}; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - bind, bind_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - bind_ack, bind_ack_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - count = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { - int i = 0; - /* check the interface uuid */ - for (i = 0; i < 16; i++) { - if (accepted_uuids[1][i] != item->uuid[i]) { - result = 0; - goto end; - } - } - if (accepted_ctxids[1] != item->ctxid) { - result = 0; - goto end; - } - count++; - } - if (count != 1) { - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - alter_context, alter_context_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - count = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { - count++; - } - if (count != 1) { - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - alter_context_resp, alter_context_resp_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - count = 0; - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { - int i = 0; - /* check the interface uuid */ - for (i = 0; i < 16; i++) { - if (accepted_uuids[count][i] != item->uuid[i]) { - result = 0; - goto end; - } - } - if (accepted_ctxids[count] != item->ctxid) { - result = 0; - goto end; - } - count++; - } - if (count != 2) { - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test DCERPC fragmented PDU. - */ -int DCERPCParserTest18(void) -{ - int result = 1; - Flow f; - int r = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x26, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x02, - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, - 0x0B, 0x0C, 0xFF, 0xFF - }; - uint32_t request2_len = sizeof(request2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - result = 0; - goto end; - } - - result &= (dcerpc_state->dcerpc.bytesprocessed == 18); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer == NULL); - result &= (dcerpc_state->dcerpc.pdu_fragged == 1); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result &= (dcerpc_state->dcerpc.bytesprocessed == 0); - result &= (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len == 14); - result &= (dcerpc_state->dcerpc.pdu_fragged == 0); - result &= (dcerpc_state->dcerpc.dcerpcrequest.opnum == 2); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -int DCERPCParserTest19(void) -{ - int result = 0; - Flow f; - uint8_t dcerpcbind[] = { - 0x05, 0x00, - 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x3c, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x16, - 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2c, 0xd0, - 0x28, 0xda, 0x76, 0x91, 0xf6, 0x6e, 0xcb, 0x0f, - 0xbf, 0x85, 0xcd, 0x9b, 0xf6, 0x39, 0x01, 0x00, - 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x2c, 0x75, 0xce, 0x7e, 0x82, 0x3b, - 0x06, 0xac, 0x1b, 0xf0, 0xf5, 0xb7, 0xa7, 0xf7, - 0x28, 0xaf, 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0xe3, 0xb2, - 0x10, 0xd1, 0xd0, 0x0c, 0xcc, 0x3d, 0x2f, 0x80, - 0x20, 0x7c, 0xef, 0xe7, 0x09, 0xe0, 0x04, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, - 0x01, 0x00, 0xde, 0x85, 0x70, 0xc4, 0x02, 0x7c, - 0x60, 0x23, 0x67, 0x0c, 0x22, 0xbf, 0x18, 0x36, - 0x79, 0x17, 0x01, 0x00, 0x02, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x41, 0x65, - 0x29, 0x51, 0xaa, 0xe7, 0x7b, 0xa8, 0xf2, 0x37, - 0x0b, 0xd0, 0x3f, 0xb3, 0x36, 0xed, 0x05, 0x00, - 0x01, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, - 0x01, 0x00, 0x14, 0x96, 0x80, 0x01, 0x2e, 0x78, - 0xfb, 0x5d, 0xb4, 0x3c, 0x14, 0xb3, 0x3d, 0xaa, - 0x02, 0xfb, 0x06, 0x00, 0x00, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x3b, 0x04, - 0x68, 0x3e, 0x63, 0xfe, 0x9f, 0xd8, 0x64, 0x55, - 0xcd, 0xe7, 0x39, 0xaf, 0x98, 0x9f, 0x03, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, - 0x01, 0x00, 0x16, 0x7a, 0x4f, 0x1b, 0xdb, 0x25, - 0x92, 0x55, 0xdd, 0xae, 0x9e, 0x5b, 0x3e, 0x93, - 0x66, 0x93, 0x04, 0x00, 0x01, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0xe8, 0xa4, - 0x8a, 0xcf, 0x95, 0x6c, 0xc7, 0x8f, 0x14, 0xcc, - 0x56, 0xfc, 0x7b, 0x5f, 0x4f, 0xe8, 0x04, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x01, 0x00, 0xd8, 0xda, 0xfb, 0xbc, 0xa2, 0x55, - 0x6f, 0x5d, 0xc0, 0x2d, 0x88, 0x6f, 0x00, 0x17, - 0x52, 0x8d, 0x06, 0x00, 0x03, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x3f, 0x17, - 0x55, 0x0c, 0xf4, 0x23, 0x3c, 0xca, 0xe6, 0xa0, - 0xaa, 0xcc, 0xb5, 0xe3, 0xf9, 0xce, 0x04, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, - 0x01, 0x00, 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, - 0xd0, 0x11, 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, - 0x2e, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0xc9, 0x9f, - 0x3e, 0x6e, 0x82, 0x0a, 0x2b, 0x28, 0x37, 0x78, - 0xe1, 0x13, 0x70, 0x05, 0x38, 0x4d, 0x01, 0x00, - 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0x01, 0x00, 0x11, 0xaa, 0x4b, 0x15, 0xdf, 0xa6, - 0x86, 0x3f, 0xfb, 0xe0, 0x09, 0xb7, 0xf8, 0x56, - 0xd2, 0x3f, 0x05, 0x00, 0x00, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x0e, 0x00, 0x01, 0x00, 0xee, 0x99, - 0xc4, 0x25, 0x11, 0xe4, 0x95, 0x62, 0x29, 0xfa, - 0xfd, 0x26, 0x57, 0x02, 0xf1, 0xce, 0x03, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x01, 0x00, 0xba, 0x81, 0x9e, 0x1a, 0xdf, 0x2b, - 0xba, 0xe4, 0xd3, 0x17, 0x41, 0x60, 0x6d, 0x2d, - 0x9e, 0x28, 0x03, 0x00, 0x03, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0xa0, 0x24, - 0x03, 0x9a, 0xa9, 0x99, 0xfb, 0xbe, 0x49, 0x11, - 0xad, 0x77, 0x30, 0xaa, 0xbc, 0xb6, 0x02, 0x00, - 0x03, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, - 0x01, 0x00, 0x32, 0x04, 0x7e, 0xae, 0xec, 0x28, - 0xd1, 0x55, 0x83, 0x4e, 0xc3, 0x47, 0x5d, 0x1d, - 0xc6, 0x65, 0x02, 0x00, 0x03, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x12, 0x00, 0x01, 0x00, 0xc6, 0xa4, - 0x81, 0x48, 0x66, 0x2a, 0x74, 0x7d, 0x56, 0x6e, - 0xc5, 0x1d, 0x19, 0xf2, 0xb5, 0xb6, 0x03, 0x00, - 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, - 0x01, 0x00, 0xcb, 0xae, 0xb3, 0xc0, 0x0c, 0xf4, - 0xa4, 0x5e, 0x91, 0x72, 0xdd, 0x53, 0x24, 0x70, - 0x89, 0x02, 0x05, 0x00, 0x03, 0x00, 0x04, 0x5d, - 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, - 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x01, 0x00, 0xb8, 0xd0, - 0xa0, 0x1a, 0x5e, 0x7a, 0x2d, 0xfe, 0x35, 0xc6, - 0x7d, 0x08, 0x0d, 0x33, 0x73, 0x18, 0x02, 0x00, - 0x02, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - }; - - uint8_t dcerpcbindack[] = { - 0x05, 0x00, 0x0c, 0x03, - 0x10, 0x00, 0x00, 0x00, 0x6c, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xb8, 0x10, 0xb8, 0x10, - 0xce, 0x47, 0x00, 0x00, 0x0c, 0x00, 0x5c, 0x50, - 0x49, 0x50, 0x45, 0x5c, 0x6c, 0x73, 0x61, 0x73, - 0x73, 0x00, 0xf6, 0x6e, 0x18, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - uint32_t bindlen = sizeof(dcerpcbind); - uint32_t bindacklen = sizeof(dcerpcbindack); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, dcerpcbind, bindlen); - if (r != 0) { - printf("dcerpc header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - DCERPCState *dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - if (dcerpc_state->dcerpc.bytesprocessed == 0) { - printf("request - dce parser bytesprocessed should not be 0.\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpcbindack, bindacklen); - if (r == 0) { - printf("dce parser didn't return fail\n"); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -#endif /* UNITTESTS */ - -void DCERPCParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DCERPCParserTest01", DCERPCParserTest01, 1); - UtRegisterTest("DCERPCParserTest02", DCERPCParserTest02, 1); - UtRegisterTest("DCERPCParserTest03", DCERPCParserTest03, 1); - UtRegisterTest("DCERPCParserTest04", DCERPCParserTest04, 1); - UtRegisterTest("DCERPCParserTest05", DCERPCParserTest05, 1); - UtRegisterTest("DCERPCParserTest06", DCERPCParserTest06, 1); - UtRegisterTest("DCERPCParserTest07", DCERPCParserTest07, 1); - UtRegisterTest("DCERPCParserTest08", DCERPCParserTest08, 1); - UtRegisterTest("DCERPCParserTest09", DCERPCParserTest09, 1); - UtRegisterTest("DCERPCParserTest10", DCERPCParserTest10, 1); - UtRegisterTest("DCERPCParserTest11", DCERPCParserTest11, 1); - UtRegisterTest("DCERPCParserTest12", DCERPCParserTest12, 1); - UtRegisterTest("DCERPCParserTest13", DCERPCParserTest13, 1); - UtRegisterTest("DCERPCParserTest14", DCERPCParserTest14, 1); - UtRegisterTest("DCERPCParserTest15", DCERPCParserTest15, 1); - UtRegisterTest("DCERPCParserTest16", DCERPCParserTest16, 1); - UtRegisterTest("DCERPCParserTest17", DCERPCParserTest17, 1); - UtRegisterTest("DCERPCParserTest18", DCERPCParserTest18, 1); - UtRegisterTest("DCERPCParserTest19", DCERPCParserTest19, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/app-layer-dcerpc.h b/framework/src/suricata/src/app-layer-dcerpc.h deleted file mode 100644 index 4781f0d1..00000000 --- a/framework/src/suricata/src/app-layer-dcerpc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Kirby Kuehl - */ - -#ifndef __APP_LAYER_DCERPC_H__ -#define __APP_LAYER_DCERPC_H__ - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-dcerpc-common.h" -#include "flow.h" -#include "queue.h" -#include "util-byte.h" - -typedef struct DCERPCState_ { - DCERPC dcerpc; - uint8_t data_needed_for_dir; -} DCERPCState; - -void RegisterDCERPCParsers(void); -void DCERPCParserTests(void); -void DCERPCParserRegisterTests(void); - -#endif /* __APP_LAYER_DCERPC_H__ */ - diff --git a/framework/src/suricata/src/app-layer-detect-proto.c b/framework/src/suricata/src/app-layer-detect-proto.c deleted file mode 100644 index 221b50ff..00000000 --- a/framework/src/suricata/src/app-layer-detect-proto.c +++ /dev/null @@ -1,3780 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "detect.h" -#include "detect-engine-port.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-content.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "flow.h" -#include "flow-util.h" -#include "flow-private.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-detect-proto.h" - -#include "conf.h" -#include "util-memcmp.h" -#include "util-spm.h" -#include "util-cuda.h" -#include "util-debug.h" - -#include "runmodes.h" - -typedef struct AppLayerProtoDetectProbingParserElement_ { - AppProto alproto; - /* \todo don't really need it. See if you can get rid of it */ - uint16_t port; - /* \todo calculate at runtime and get rid of this var */ - uint32_t alproto_mask; - /* \todo check if we can reduce the bottom 2 vars to uint16_t */ - /* the min length of data that has to be supplied to invoke the parser */ - uint32_t min_depth; - /* the max length of data after which this parser won't be invoked */ - uint32_t max_depth; - /* the probing parser function */ - ProbingParserFPtr ProbingParser; - - struct AppLayerProtoDetectProbingParserElement_ *next; -} AppLayerProtoDetectProbingParserElement; - -typedef struct AppLayerProtoDetectProbingParserPort_ { - /* the port no for which probing parser(s) are invoked */ - uint16_t port; - - uint32_t alproto_mask; - - /* the max depth for all the probing parsers registered for this port */ - uint16_t dp_max_depth; - uint16_t sp_max_depth; - - AppLayerProtoDetectProbingParserElement *dp; - AppLayerProtoDetectProbingParserElement *sp; - - struct AppLayerProtoDetectProbingParserPort_ *next; -} AppLayerProtoDetectProbingParserPort; - -typedef struct AppLayerProtoDetectProbingParser_ { - uint8_t ipproto; - AppLayerProtoDetectProbingParserPort *port; - - struct AppLayerProtoDetectProbingParser_ *next; -} AppLayerProtoDetectProbingParser; - -typedef struct AppLayerProtoDetectPMSignature_ { - AppProto alproto; - /* \todo Change this into a non-pointer */ - DetectContentData *cd; - struct AppLayerProtoDetectPMSignature_ *next; -} AppLayerProtoDetectPMSignature; - -typedef struct AppLayerProtoDetectPMCtx_ { - uint16_t max_len; - uint16_t min_len; - MpmCtx mpm_ctx; - - /** Mapping between pattern id and signature. As each signature has a - * unique pattern with a unique id, we can lookup the signature by - * the pattern id. */ - AppLayerProtoDetectPMSignature **map; - AppLayerProtoDetectPMSignature *head; - - /* \todo we don't need this except at setup time. Get rid of it. */ - PatIntId max_pat_id; -} AppLayerProtoDetectPMCtx; - -typedef struct AppLayerProtoDetectCtxIpproto_ { - /* 0 - toserver, 1 - toclient */ - AppLayerProtoDetectPMCtx ctx_pm[2]; -} AppLayerProtoDetectCtxIpproto; - -/** - * \brief The app layer protocol detection context. - */ -typedef struct AppLayerProtoDetectCtx_ { - /* Context per ip_proto. - * \todo Modify ctx_ipp to hold for only tcp and udp. The rest can be - * implemented if needed. Waste of space otherwise. */ - AppLayerProtoDetectCtxIpproto ctx_ipp[FLOW_PROTO_DEFAULT]; - - AppLayerProtoDetectProbingParser *ctx_pp; - - /* Indicates the protocols that have registered themselves - * for protocol detection. This table is independent of the - * ipproto. */ - char *alproto_names[ALPROTO_MAX]; -} AppLayerProtoDetectCtx; - -/** - * \brief The app layer protocol detection thread context. - */ -struct AppLayerProtoDetectThreadCtx_ { - PatternMatcherQueue pmq; - /* The value 2 is for direction(0 - toserver, 1 - toclient). */ - MpmThreadCtx mpm_tctx[FLOW_PROTO_DEFAULT][2]; -}; - -/* The global app layer proto detection context. */ -static AppLayerProtoDetectCtx alpd_ctx; - -/***** Static Internal Calls: Protocol Retrieval *****/ - -/** \internal - * \brief Handle SPM search for Signature */ -static AppProto AppLayerProtoDetectPMMatchSignature(const AppLayerProtoDetectPMSignature *s, - uint8_t *buf, uint16_t buflen, - uint8_t ipproto) -{ - SCEnter(); - AppProto proto = ALPROTO_UNKNOWN; - uint8_t *found = NULL; - - if (s->cd->offset > buflen) { - SCLogDebug("s->co->offset (%"PRIu16") > buflen (%"PRIu16")", - s->cd->offset, buflen); - goto end; - } - - if (s->cd->depth > buflen) { - SCLogDebug("s->co->depth (%"PRIu16") > buflen (%"PRIu16")", - s->cd->depth, buflen); - goto end; - } - - uint8_t *sbuf = buf + s->cd->offset; - uint16_t sbuflen = s->cd->depth - s->cd->offset; - SCLogDebug("s->co->offset (%"PRIu16") s->cd->depth (%"PRIu16")", - s->cd->offset, s->cd->depth); - - if (s->cd->flags & DETECT_CONTENT_NOCASE) - found = BoyerMooreNocase(s->cd->content, s->cd->content_len, sbuf, sbuflen, s->cd->bm_ctx); - else - found = BoyerMoore(s->cd->content, s->cd->content_len, sbuf, sbuflen, s->cd->bm_ctx); - if (found != NULL) - proto = s->alproto; - - end: - SCReturnUInt(proto); -} - -/** \internal - * \brief Run Pattern Sigs against buffer - * \param pm_results[out] AppProto array of size ALPROTO_MAX */ -static AppProto AppLayerProtoDetectPMGetProto(AppLayerProtoDetectThreadCtx *tctx, - Flow *f, - uint8_t *buf, uint16_t buflen, - uint8_t direction, - uint8_t ipproto, - AppProto *pm_results) -{ - SCEnter(); - - pm_results[0] = ALPROTO_UNKNOWN; - - AppLayerProtoDetectPMCtx *pm_ctx; - MpmThreadCtx *mpm_tctx; - uint16_t pm_matches = 0; - uint8_t cnt; - uint16_t searchlen; - - if (f->protomap >= FLOW_PROTO_DEFAULT) - return ALPROTO_UNKNOWN; - - if (direction & STREAM_TOSERVER) { - pm_ctx = &alpd_ctx.ctx_ipp[f->protomap].ctx_pm[0]; - mpm_tctx = &tctx->mpm_tctx[f->protomap][0]; - } else { - pm_ctx = &alpd_ctx.ctx_ipp[f->protomap].ctx_pm[1]; - mpm_tctx = &tctx->mpm_tctx[f->protomap][1]; - } - if (pm_ctx->mpm_ctx.pattern_cnt == 0) - goto end; - - searchlen = buflen; - if (searchlen > pm_ctx->max_len) - searchlen = pm_ctx->max_len; - - uint32_t search_cnt = 0; - - /* do the mpm search */ - search_cnt = mpm_table[pm_ctx->mpm_ctx.mpm_type].Search(&pm_ctx->mpm_ctx, - mpm_tctx, - &tctx->pmq, - buf, searchlen); - if (search_cnt == 0) - goto end; - - /* alproto bit field */ - uint8_t pm_results_bf[(ALPROTO_MAX / 8) + 1]; - memset(pm_results_bf, 0, sizeof(pm_results_bf)); - - /* loop through unique pattern id's. Can't use search_cnt here, - * as that contains all matches, tctx->pmq.pattern_id_array_cnt - * contains only *unique* matches. */ - for (cnt = 0; cnt < tctx->pmq.pattern_id_array_cnt; cnt++) { - const AppLayerProtoDetectPMSignature *s = pm_ctx->map[tctx->pmq.pattern_id_array[cnt]]; - while (s != NULL) { - AppProto proto = AppLayerProtoDetectPMMatchSignature(s, - buf, searchlen, ipproto); - - /* store each unique proto once */ - if (proto != ALPROTO_UNKNOWN && - !(pm_results_bf[proto / 8] & (1 << (proto % 8))) ) - { - pm_results[pm_matches++] = proto; - pm_results_bf[proto / 8] |= 1 << (proto % 8); - } - s = s->next; - } - } - - end: - PmqReset(&tctx->pmq); - if (buflen >= pm_ctx->max_len) - FLOW_SET_PM_DONE(f, direction); - SCReturnUInt(pm_matches); -} - -static AppLayerProtoDetectProbingParserPort *AppLayerProtoDetectGetProbingParsers(AppLayerProtoDetectProbingParser *pp, - uint8_t ipproto, - uint16_t port) -{ - AppLayerProtoDetectProbingParserPort *pp_port = NULL; - - while (pp != NULL) { - if (pp->ipproto == ipproto) - break; - - pp = pp->next; - } - - if (pp == NULL) - goto end; - - pp_port = pp->port; - while (pp_port != NULL) { - if (pp_port->port == port || pp_port->port == 0) { - break; - } - pp_port = pp_port->next; - } - - end: - SCReturnPtr(pp_port, "AppLayerProtoDetectProbingParserPort *"); -} - -/** - * \brief Call the probing parser if it exists for this flow. - * - * First we check the flow's dp as it's most likely to match. If that didn't - * lead to a PP, we try the sp. - * - */ -static AppProto AppLayerProtoDetectPPGetProto(Flow *f, - uint8_t *buf, uint32_t buflen, - uint8_t ipproto, uint8_t direction) -{ - const AppLayerProtoDetectProbingParserPort *pp_port_dp = NULL; - const AppLayerProtoDetectProbingParserPort *pp_port_sp = NULL; - const AppLayerProtoDetectProbingParserElement *pe = NULL; - const AppLayerProtoDetectProbingParserElement *pe1 = NULL; - const AppLayerProtoDetectProbingParserElement *pe2 = NULL; - AppProto alproto = ALPROTO_UNKNOWN; - uint32_t *alproto_masks; - uint32_t mask = 0; - - if (direction & STREAM_TOSERVER) { - /* first try the destination port */ - pp_port_dp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->dp); - alproto_masks = &f->probing_parser_toserver_alproto_masks; - if (pp_port_dp != NULL) { - SCLogDebug("toserver - Probing parser found for destination port %"PRIu16, f->dp); - - /* found based on destination port, so use dp registration */ - pe1 = pp_port_dp->dp; - } else { - SCLogDebug("toserver - No probing parser registered for dest port %"PRIu16, - f->dp); - } - - pp_port_sp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->sp); - if (pp_port_sp != NULL) { - SCLogDebug("toserver - Probing parser found for source port %"PRIu16, f->sp); - - /* found based on source port, so use sp registration */ - pe2 = pp_port_sp->sp; - } else { - SCLogDebug("toserver - No probing parser registered for source port %"PRIu16, - f->sp); - } - } else { - /* first try the destination port */ - pp_port_dp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->dp); - alproto_masks = &f->probing_parser_toclient_alproto_masks; - if (pp_port_dp != NULL) { - SCLogDebug("toclient - Probing parser found for destination port %"PRIu16, f->dp); - - /* found based on destination port, so use dp registration */ - pe1 = pp_port_dp->dp; - } else { - SCLogDebug("toclient - No probing parser registered for dest port %"PRIu16, - f->dp); - } - - pp_port_sp = AppLayerProtoDetectGetProbingParsers(alpd_ctx.ctx_pp, ipproto, f->sp); - if (pp_port_sp != NULL) { - SCLogDebug("toclient - Probing parser found for source port %"PRIu16, f->sp); - - pe2 = pp_port_sp->sp; - } else { - SCLogDebug("toclient - No probing parser registered for source port %"PRIu16, - f->sp); - } - } - - if (pe1 == NULL && pe2 == NULL) { - SCLogDebug("%s - No probing parsers found for either port", - (direction & STREAM_TOSERVER) ? "toserver":"toclient"); - FLOW_SET_PP_DONE(f, direction); - goto end; - } - - /* run the parser(s) */ - pe = pe1; - while (pe != NULL) { - if ((buflen < pe->min_depth) || - (alproto_masks[0] & pe->alproto_mask)) { - pe = pe->next; - continue; - } - - alproto = pe->ProbingParser(buf, buflen, NULL); - if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED) - goto end; - if (alproto == ALPROTO_FAILED || - (pe->max_depth != 0 && buflen > pe->max_depth)) { - alproto_masks[0] |= pe->alproto_mask; - } - pe = pe->next; - } - pe = pe2; - while (pe != NULL) { - if ((buflen < pe->min_depth) || - (alproto_masks[0] & pe->alproto_mask)) { - pe = pe->next; - continue; - } - - alproto = pe->ProbingParser(buf, buflen, NULL); - if (alproto != ALPROTO_UNKNOWN && alproto != ALPROTO_FAILED) - goto end; - if (alproto == ALPROTO_FAILED || - (pe->max_depth != 0 && buflen > pe->max_depth)) { - alproto_masks[0] |= pe->alproto_mask; - } - pe = pe->next; - } - - /* get the mask we need for this direction */ - if (pp_port_dp && pp_port_sp) - mask = pp_port_dp->alproto_mask|pp_port_sp->alproto_mask; - else if (pp_port_dp) - mask = pp_port_dp->alproto_mask; - else if (pp_port_sp) - mask = pp_port_sp->alproto_mask; - else - mask = 0; - - if (alproto_masks[0] == mask) { - FLOW_SET_PP_DONE(f, direction); - SCLogDebug("%s, mask is now %08x, needed %08x, so done", - (direction & STREAM_TOSERVER) ? "toserver":"toclient", alproto_masks[0], mask); - } else { - SCLogDebug("%s, mask is now %08x, need %08x", - (direction & STREAM_TOSERVER) ? "toserver":"toclient", alproto_masks[0], mask); - } - - end: - SCLogDebug("%s, mask is now %08x", - (direction & STREAM_TOSERVER) ? "toserver":"toclient", alproto_masks[0]); - SCReturnUInt(alproto); -} - -/***** Static Internal Calls: PP registration *****/ - -static void AppLayerProtoDetectPPGetIpprotos(AppProto alproto, - uint8_t *ipprotos) -{ - SCEnter(); - - const AppLayerProtoDetectProbingParser *pp; - const AppLayerProtoDetectProbingParserPort *pp_port; - const AppLayerProtoDetectProbingParserElement *pp_pe; - - for (pp = alpd_ctx.ctx_pp; pp != NULL; pp = pp->next) { - for (pp_port = pp->port; pp_port != NULL; pp_port = pp_port->next) { - for (pp_pe = pp_port->dp; pp_pe != NULL; pp_pe = pp_pe->next) { - if (alproto == pp_pe->alproto) - ipprotos[pp->ipproto / 8] |= 1 << (pp->ipproto % 8); - } - for (pp_pe = pp_port->sp; pp_pe != NULL; pp_pe = pp_pe->next) { - if (alproto == pp_pe->alproto) - ipprotos[pp->ipproto / 8] |= 1 << (pp->ipproto % 8); - } - } - } - - SCReturn; -} - -static uint32_t AppLayerProtoDetectProbingParserGetMask(AppProto alproto) -{ - SCEnter(); - - if (!(alproto > ALPROTO_UNKNOWN && alproto < ALPROTO_FAILED)) { - SCLogError(SC_ERR_ALPARSER, "Unknown protocol detected - %"PRIu16, - alproto); - exit(EXIT_FAILURE); - } - - SCReturnUInt(1 << alproto); -} - -static AppLayerProtoDetectProbingParserElement *AppLayerProtoDetectProbingParserElementAlloc(void) -{ - SCEnter(); - - AppLayerProtoDetectProbingParserElement *p = SCMalloc(sizeof(AppLayerProtoDetectProbingParserElement)); - if (unlikely(p == NULL)) { - exit(EXIT_FAILURE); - } - memset(p, 0, sizeof(AppLayerProtoDetectProbingParserElement)); - - SCReturnPtr(p, "AppLayerProtoDetectProbingParserElement"); -} - - -static void AppLayerProtoDetectProbingParserElementFree(AppLayerProtoDetectProbingParserElement *p) -{ - SCEnter(); - SCFree(p); - SCReturn; -} - -static AppLayerProtoDetectProbingParserPort *AppLayerProtoDetectProbingParserPortAlloc(void) -{ - SCEnter(); - - AppLayerProtoDetectProbingParserPort *p = SCMalloc(sizeof(AppLayerProtoDetectProbingParserPort)); - if (unlikely(p == NULL)) { - exit(EXIT_FAILURE); - } - memset(p, 0, sizeof(AppLayerProtoDetectProbingParserPort)); - - SCReturnPtr(p, "AppLayerProtoDetectProbingParserPort"); -} - -static void AppLayerProtoDetectProbingParserPortFree(AppLayerProtoDetectProbingParserPort *p) -{ - SCEnter(); - - AppLayerProtoDetectProbingParserElement *e; - - e = p->dp; - while (e != NULL) { - AppLayerProtoDetectProbingParserElement *e_next = e->next; - AppLayerProtoDetectProbingParserElementFree(e); - e = e_next; - } - - e = p->sp; - while (e != NULL) { - AppLayerProtoDetectProbingParserElement *e_next = e->next; - AppLayerProtoDetectProbingParserElementFree(e); - e = e_next; - } - - SCFree(p); - - SCReturn; -} - -static AppLayerProtoDetectProbingParser *AppLayerProtoDetectProbingParserAlloc(void) -{ - SCEnter(); - - AppLayerProtoDetectProbingParser *p = SCMalloc(sizeof(AppLayerProtoDetectProbingParser)); - if (unlikely(p == NULL)) { - exit(EXIT_FAILURE); - } - memset(p, 0, sizeof(AppLayerProtoDetectProbingParser)); - - SCReturnPtr(p, "AppLayerProtoDetectProbingParser"); -} - -static void AppLayerProtoDetectProbingParserFree(AppLayerProtoDetectProbingParser *p) -{ - SCEnter(); - - AppLayerProtoDetectProbingParserPort *pt = p->port; - while (pt != NULL) { - AppLayerProtoDetectProbingParserPort *pt_next = pt->next; - AppLayerProtoDetectProbingParserPortFree(pt); - pt = pt_next; - } - - SCFree(p); - - SCReturn; -} - -static AppLayerProtoDetectProbingParserElement * -AppLayerProtoDetectProbingParserElementCreate(AppProto alproto, - uint16_t port, - uint16_t min_depth, - uint16_t max_depth, - uint16_t (*AppLayerProtoDetectProbingParser) - (uint8_t *input, uint32_t input_len, uint32_t *offset)) -{ - AppLayerProtoDetectProbingParserElement *pe = AppLayerProtoDetectProbingParserElementAlloc(); - - pe->alproto = alproto; - pe->port = port; - pe->alproto_mask = AppLayerProtoDetectProbingParserGetMask(alproto); - pe->min_depth = min_depth; - pe->max_depth = max_depth; - pe->ProbingParser = AppLayerProtoDetectProbingParser; - pe->next = NULL; - - if (max_depth != 0 && min_depth >= max_depth) { - SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to " - "register the probing parser. min_depth >= max_depth"); - goto error; - } - if (alproto <= ALPROTO_UNKNOWN || alproto >= ALPROTO_MAX) { - SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to register " - "the probing parser. Invalid alproto - %d", alproto); - goto error; - } - if (AppLayerProtoDetectProbingParser == NULL) { - SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to " - "register the probing parser. Probing parser func NULL"); - goto error; - } - - SCReturnPtr(pe, "AppLayerProtoDetectProbingParserElement"); - error: - AppLayerProtoDetectProbingParserElementFree(pe); - SCReturnPtr(NULL, "AppLayerProtoDetectProbingParserElement"); -} - -static AppLayerProtoDetectProbingParserElement * -AppLayerProtoDetectProbingParserElementDuplicate(AppLayerProtoDetectProbingParserElement *pe) -{ - SCEnter(); - - AppLayerProtoDetectProbingParserElement *new_pe = AppLayerProtoDetectProbingParserElementAlloc(); - - new_pe->alproto = pe->alproto; - new_pe->port = pe->port; - new_pe->alproto_mask = pe->alproto_mask; - new_pe->min_depth = pe->min_depth; - new_pe->max_depth = pe->max_depth; - new_pe->ProbingParser = pe->ProbingParser; - new_pe->next = NULL; - - SCReturnPtr(new_pe, "AppLayerProtoDetectProbingParserElement"); -} - -void AppLayerProtoDetectPrintProbingParsers(AppLayerProtoDetectProbingParser *pp) -{ - SCEnter(); - - AppLayerProtoDetectProbingParserPort *pp_port = NULL; - AppLayerProtoDetectProbingParserElement *pp_pe = NULL; - - printf("\nProtocol Detection Configuration\n"); - - for ( ; pp != NULL; pp = pp->next) { - /* print ip protocol */ - if (pp->ipproto == IPPROTO_TCP) - printf("IPProto: TCP\n"); - else if (pp->ipproto == IPPROTO_UDP) - printf("IPProto: UDP\n"); - else - printf("IPProto: %"PRIu8"\n", pp->ipproto); - - pp_port = pp->port; - for ( ; pp_port != NULL; pp_port = pp_port->next) { - if (pp_port->dp != NULL) { - printf(" Port: %"PRIu16 "\n", pp_port->port); - - printf(" Destination port: (max-depth: %"PRIu16 ", " - "mask - %"PRIu32")\n", - pp_port->dp_max_depth, - pp_port->alproto_mask); - pp_pe = pp_port->dp; - for ( ; pp_pe != NULL; pp_pe = pp_pe->next) { - - if (pp_pe->alproto == ALPROTO_HTTP) - printf(" alproto: ALPROTO_HTTP\n"); - else if (pp_pe->alproto == ALPROTO_FTP) - printf(" alproto: ALPROTO_FTP\n"); - else if (pp_pe->alproto == ALPROTO_SMTP) - printf(" alproto: ALPROTO_SMTP\n"); - else if (pp_pe->alproto == ALPROTO_TLS) - printf(" alproto: ALPROTO_TLS\n"); - else if (pp_pe->alproto == ALPROTO_SSH) - printf(" alproto: ALPROTO_SSH\n"); - else if (pp_pe->alproto == ALPROTO_IMAP) - printf(" alproto: ALPROTO_IMAP\n"); - else if (pp_pe->alproto == ALPROTO_MSN) - printf(" alproto: ALPROTO_MSN\n"); - else if (pp_pe->alproto == ALPROTO_JABBER) - printf(" alproto: ALPROTO_JABBER\n"); - else if (pp_pe->alproto == ALPROTO_SMB) - printf(" alproto: ALPROTO_SMB\n"); - else if (pp_pe->alproto == ALPROTO_SMB2) - printf(" alproto: ALPROTO_SMB2\n"); - else if (pp_pe->alproto == ALPROTO_DCERPC) - printf(" alproto: ALPROTO_DCERPC\n"); - else if (pp_pe->alproto == ALPROTO_IRC) - printf(" alproto: ALPROTO_IRC\n"); - else if (pp_pe->alproto == ALPROTO_DNS) - printf(" alproto: ALPROTO_DNS\n"); - else if (pp_pe->alproto == ALPROTO_MODBUS) - printf(" alproto: ALPROTO_MODBUS\n"); - else if (pp_pe->alproto == ALPROTO_TEMPLATE) - printf(" alproto: ALPROTO_TEMPLATE\n"); - else - printf("impossible\n"); - - printf(" port: %"PRIu16 "\n", pp_pe->port); - printf(" mask: %"PRIu32 "\n", pp_pe->alproto_mask); - printf(" min_depth: %"PRIu32 "\n", pp_pe->min_depth); - printf(" max_depth: %"PRIu32 "\n", pp_pe->max_depth); - - printf("\n"); - } - } - - if (pp_port->sp == NULL) { - continue; - } - - printf(" Source port: (max-depth: %"PRIu16 ", " - "mask - %"PRIu32")\n", - pp_port->sp_max_depth, - pp_port->alproto_mask); - pp_pe = pp_port->sp; - for ( ; pp_pe != NULL; pp_pe = pp_pe->next) { - - if (pp_pe->alproto == ALPROTO_HTTP) - printf(" alproto: ALPROTO_HTTP\n"); - else if (pp_pe->alproto == ALPROTO_FTP) - printf(" alproto: ALPROTO_FTP\n"); - else if (pp_pe->alproto == ALPROTO_SMTP) - printf(" alproto: ALPROTO_SMTP\n"); - else if (pp_pe->alproto == ALPROTO_TLS) - printf(" alproto: ALPROTO_TLS\n"); - else if (pp_pe->alproto == ALPROTO_SSH) - printf(" alproto: ALPROTO_SSH\n"); - else if (pp_pe->alproto == ALPROTO_IMAP) - printf(" alproto: ALPROTO_IMAP\n"); - else if (pp_pe->alproto == ALPROTO_MSN) - printf(" alproto: ALPROTO_MSN\n"); - else if (pp_pe->alproto == ALPROTO_JABBER) - printf(" alproto: ALPROTO_JABBER\n"); - else if (pp_pe->alproto == ALPROTO_SMB) - printf(" alproto: ALPROTO_SMB\n"); - else if (pp_pe->alproto == ALPROTO_SMB2) - printf(" alproto: ALPROTO_SMB2\n"); - else if (pp_pe->alproto == ALPROTO_DCERPC) - printf(" alproto: ALPROTO_DCERPC\n"); - else if (pp_pe->alproto == ALPROTO_IRC) - printf(" alproto: ALPROTO_IRC\n"); - else if (pp_pe->alproto == ALPROTO_DNS) - printf(" alproto: ALPROTO_DNS\n"); - else if (pp_pe->alproto == ALPROTO_MODBUS) - printf(" alproto: ALPROTO_MODBUS\n"); - else if (pp_pe->alproto == ALPROTO_TEMPLATE) - printf(" alproto: ALPROTO_TEMPLATE\n"); - else - printf("impossible\n"); - - printf(" port: %"PRIu16 "\n", pp_pe->port); - printf(" mask: %"PRIu32 "\n", pp_pe->alproto_mask); - printf(" min_depth: %"PRIu32 "\n", pp_pe->min_depth); - printf(" max_depth: %"PRIu32 "\n", pp_pe->max_depth); - - printf("\n"); - } - } - } - - SCReturn; -} - -static void AppLayerProtoDetectProbingParserElementAppend(AppLayerProtoDetectProbingParserElement **head_pe, - AppLayerProtoDetectProbingParserElement *new_pe) -{ - SCEnter(); - - if (*head_pe == NULL) { - *head_pe = new_pe; - goto end; - } - - if ((*head_pe)->port == 0) { - if (new_pe->port != 0) { - new_pe->next = *head_pe; - *head_pe = new_pe; - } else { - AppLayerProtoDetectProbingParserElement *temp_pe = *head_pe; - while (temp_pe->next != NULL) - temp_pe = temp_pe->next; - temp_pe->next = new_pe; - } - } else { - AppLayerProtoDetectProbingParserElement *temp_pe = *head_pe; - if (new_pe->port == 0) { - while (temp_pe->next != NULL) - temp_pe = temp_pe->next; - temp_pe->next = new_pe; - } else { - while (temp_pe->next != NULL && temp_pe->next->port != 0) - temp_pe = temp_pe->next; - new_pe->next = temp_pe->next; - temp_pe->next = new_pe; - - } - } - - end: - SCReturn; -} - -static void AppLayerProtoDetectProbingParserAppend(AppLayerProtoDetectProbingParser **head_pp, - AppLayerProtoDetectProbingParser *new_pp) -{ - SCEnter(); - - if (*head_pp == NULL) { - *head_pp = new_pp; - goto end; - } - - AppLayerProtoDetectProbingParser *temp_pp = *head_pp; - while (temp_pp->next != NULL) - temp_pp = temp_pp->next; - temp_pp->next = new_pp; - - end: - SCReturn; -} - -static void AppLayerProtoDetectProbingParserPortAppend(AppLayerProtoDetectProbingParserPort **head_port, - AppLayerProtoDetectProbingParserPort *new_port) -{ - SCEnter(); - - if (*head_port == NULL) { - *head_port = new_port; - goto end; - } - - if ((*head_port)->port == 0) { - new_port->next = *head_port; - *head_port = new_port; - } else { - AppLayerProtoDetectProbingParserPort *temp_port = *head_port; - while (temp_port->next != NULL && temp_port->next->port != 0) { - temp_port = temp_port->next; - } - new_port->next = temp_port->next; - temp_port->next = new_port; - } - - end: - SCReturn; -} - -static void AppLayerProtoDetectInsertNewProbingParser(AppLayerProtoDetectProbingParser **pp, - uint8_t ipproto, - uint16_t port, - AppProto alproto, - uint16_t min_depth, uint16_t max_depth, - uint8_t direction, - ProbingParserFPtr ProbingParser) -{ - SCEnter(); - - /* get the top level ipproto pp */ - AppLayerProtoDetectProbingParser *curr_pp = *pp; - while (curr_pp != NULL) { - if (curr_pp->ipproto == ipproto) - break; - curr_pp = curr_pp->next; - } - if (curr_pp == NULL) { - AppLayerProtoDetectProbingParser *new_pp = AppLayerProtoDetectProbingParserAlloc(); - new_pp->ipproto = ipproto; - AppLayerProtoDetectProbingParserAppend(pp, new_pp); - curr_pp = new_pp; - } - - /* get the top level port pp */ - AppLayerProtoDetectProbingParserPort *curr_port = curr_pp->port; - while (curr_port != NULL) { - if (curr_port->port == port) - break; - curr_port = curr_port->next; - } - if (curr_port == NULL) { - AppLayerProtoDetectProbingParserPort *new_port = AppLayerProtoDetectProbingParserPortAlloc(); - new_port->port = port; - AppLayerProtoDetectProbingParserPortAppend(&curr_pp->port, new_port); - curr_port = new_port; - if (direction & STREAM_TOSERVER) { - curr_port->dp_max_depth = max_depth; - } else { - curr_port->sp_max_depth = max_depth; - } - - AppLayerProtoDetectProbingParserPort *zero_port; - - zero_port = curr_pp->port; - while (zero_port != NULL && zero_port->port != 0) { - zero_port = zero_port->next; - } - if (zero_port != NULL) { - AppLayerProtoDetectProbingParserElement *zero_pe; - - zero_pe = zero_port->dp; - for ( ; zero_pe != NULL; zero_pe = zero_pe->next) { - if (curr_port->dp == NULL) - curr_port->dp_max_depth = zero_pe->max_depth; - if (zero_pe->max_depth == 0) - curr_port->dp_max_depth = zero_pe->max_depth; - if (curr_port->dp_max_depth != 0 && - curr_port->dp_max_depth < zero_pe->max_depth) { - curr_port->dp_max_depth = zero_pe->max_depth; - } - - AppLayerProtoDetectProbingParserElement *dup_pe = - AppLayerProtoDetectProbingParserElementDuplicate(zero_pe); - AppLayerProtoDetectProbingParserElementAppend(&curr_port->dp, dup_pe); - curr_port->alproto_mask |= dup_pe->alproto_mask; - } - - zero_pe = zero_port->sp; - for ( ; zero_pe != NULL; zero_pe = zero_pe->next) { - if (curr_port->sp == NULL) - curr_port->sp_max_depth = zero_pe->max_depth; - if (zero_pe->max_depth == 0) - curr_port->sp_max_depth = zero_pe->max_depth; - if (curr_port->sp_max_depth != 0 && - curr_port->sp_max_depth < zero_pe->max_depth) { - curr_port->sp_max_depth = zero_pe->max_depth; - } - - AppLayerProtoDetectProbingParserElement *dup_pe = - AppLayerProtoDetectProbingParserElementDuplicate(zero_pe); - AppLayerProtoDetectProbingParserElementAppend(&curr_port->sp, dup_pe); - curr_port->alproto_mask |= dup_pe->alproto_mask; - } - } /* if (zero_port != NULL) */ - } /* if (curr_port == NULL) */ - - /* insert the pe_pp */ - AppLayerProtoDetectProbingParserElement *curr_pe; - if (direction & STREAM_TOSERVER) - curr_pe = curr_port->dp; - else - curr_pe = curr_port->sp; - while (curr_pe != NULL) { - if (curr_pe->alproto == alproto) { - SCLogError(SC_ERR_ALPARSER, "Duplicate pp registered - " - "ipproto - %"PRIu8" Port - %"PRIu16" " - "App Protocol - NULL, App Protocol(ID) - " - "%"PRIu16" min_depth - %"PRIu16" " - "max_dept - %"PRIu16".", - ipproto, port, alproto, - min_depth, max_depth); - goto error; - } - curr_pe = curr_pe->next; - } - /* Get a new parser element */ - AppLayerProtoDetectProbingParserElement *new_pe = - AppLayerProtoDetectProbingParserElementCreate(alproto, - curr_port->port, - min_depth, max_depth, - ProbingParser); - if (new_pe == NULL) - goto error; - curr_pe = new_pe; - AppLayerProtoDetectProbingParserElement **head_pe; - if (direction & STREAM_TOSERVER) { - if (curr_port->dp == NULL) - curr_port->dp_max_depth = new_pe->max_depth; - if (new_pe->max_depth == 0) - curr_port->dp_max_depth = new_pe->max_depth; - if (curr_port->dp_max_depth != 0 && - curr_port->dp_max_depth < new_pe->max_depth) { - curr_port->dp_max_depth = new_pe->max_depth; - } - curr_port->alproto_mask |= new_pe->alproto_mask; - head_pe = &curr_port->dp; - } else { - if (curr_port->sp == NULL) - curr_port->sp_max_depth = new_pe->max_depth; - if (new_pe->max_depth == 0) - curr_port->sp_max_depth = new_pe->max_depth; - if (curr_port->sp_max_depth != 0 && - curr_port->sp_max_depth < new_pe->max_depth) { - curr_port->sp_max_depth = new_pe->max_depth; - } - curr_port->alproto_mask |= new_pe->alproto_mask; - head_pe = &curr_port->sp; - } - AppLayerProtoDetectProbingParserElementAppend(head_pe, new_pe); - - if (curr_port->port == 0) { - AppLayerProtoDetectProbingParserPort *temp_port = curr_pp->port; - while (temp_port != NULL && temp_port->port != 0) { - if (direction & STREAM_TOSERVER) { - if (temp_port->dp == NULL) - temp_port->dp_max_depth = curr_pe->max_depth; - if (curr_pe->max_depth == 0) - temp_port->dp_max_depth = curr_pe->max_depth; - if (temp_port->dp_max_depth != 0 && - temp_port->dp_max_depth < curr_pe->max_depth) { - temp_port->dp_max_depth = curr_pe->max_depth; - } - AppLayerProtoDetectProbingParserElementAppend(&temp_port->dp, - AppLayerProtoDetectProbingParserElementDuplicate(curr_pe)); - temp_port->alproto_mask |= curr_pe->alproto_mask; - } else { - if (temp_port->sp == NULL) - temp_port->sp_max_depth = curr_pe->max_depth; - if (curr_pe->max_depth == 0) - temp_port->sp_max_depth = curr_pe->max_depth; - if (temp_port->sp_max_depth != 0 && - temp_port->sp_max_depth < curr_pe->max_depth) { - temp_port->sp_max_depth = curr_pe->max_depth; - } - AppLayerProtoDetectProbingParserElementAppend(&temp_port->sp, - AppLayerProtoDetectProbingParserElementDuplicate(curr_pe)); - temp_port->alproto_mask |= curr_pe->alproto_mask; - } - temp_port = temp_port->next; - } /* while */ - } /* if */ - - error: - SCReturn; -} - -/***** Static Internal Calls: PM registration *****/ - -static void AppLayerProtoDetectPMGetIpprotos(AppProto alproto, - uint8_t *ipprotos) -{ - SCEnter(); - - const AppLayerProtoDetectPMSignature *s = NULL; - int pat_id, max_pat_id; - - int i, j; - uint8_t ipproto; - - for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { - ipproto = FlowGetReverseProtoMapping(i); - for (j = 0; j < 2; j++) { - AppLayerProtoDetectPMCtx *pm_ctx = &alpd_ctx.ctx_ipp[i].ctx_pm[j]; - max_pat_id = pm_ctx->max_pat_id; - - for (pat_id = 0; pat_id < max_pat_id; pat_id++) { - s = pm_ctx->map[pat_id]; - while (s != NULL) { - if (s->alproto == alproto) - ipprotos[ipproto / 8] |= 1 << (ipproto % 8); - s = s->next; - } - } - } - } - - SCReturn; -} - -static int AppLayerProtoDetectPMSetContentIDs(AppLayerProtoDetectPMCtx *ctx) -{ - SCEnter(); - - typedef struct TempContainer_ { - PatIntId id; - uint16_t content_len; - uint8_t *content; - } TempContainer; - - AppLayerProtoDetectPMSignature *s = NULL; - uint32_t struct_total_size = 0; - uint32_t content_total_size = 0; - /* array hash buffer */ - uint8_t *ahb = NULL; - uint8_t *content = NULL; - uint8_t content_len = 0; - PatIntId max_id = 0; - TempContainer *struct_offset = NULL; - uint8_t *content_offset = NULL; - TempContainer *dup = NULL; - int ret = 0; - - if (ctx->head == NULL) - goto end; - - for (s = ctx->head; s != NULL; s = s->next) { - struct_total_size += sizeof(TempContainer); - content_total_size += s->cd->content_len; - } - - ahb = SCMalloc(sizeof(uint8_t) * (struct_total_size + content_total_size)); - if (unlikely(ahb == NULL)) - goto error; - - struct_offset = (TempContainer *)ahb; - content_offset = ahb + struct_total_size; - for (s = ctx->head; s != NULL; s = s->next) { - dup = (TempContainer *)ahb; - content = s->cd->content; - content_len = s->cd->content_len; - - for (; dup != struct_offset; dup++) { - if (dup->content_len != content_len || - SCMemcmp(dup->content, content, dup->content_len) != 0) - { - continue; - } - break; - } - - if (dup != struct_offset) { - s->cd->id = dup->id; - continue; - } - - struct_offset->content_len = content_len; - struct_offset->content = content_offset; - content_offset += content_len; - memcpy(struct_offset->content, content, content_len); - struct_offset->id = max_id++; - s->cd->id = struct_offset->id; - - struct_offset++; - } - - ctx->max_pat_id = max_id; - - goto end; - error: - ret = -1; - end: - if (ahb != NULL) - SCFree(ahb); - SCReturnInt(ret); -} - -static int AppLayerProtoDetectPMMapSignatures(AppLayerProtoDetectPMCtx *ctx) -{ - SCEnter(); - - int ret = 0; - PatIntId max_pat_id = 0, tmp_pat_id; - AppLayerProtoDetectPMSignature *s, *next_s; - int mpm_ret; - - max_pat_id = ctx->max_pat_id; - - ctx->map = SCMalloc((max_pat_id) * sizeof(AppLayerProtoDetectPMSignature *)); - if (ctx->map == NULL) - goto error; - memset(ctx->map, 0, (max_pat_id) * sizeof(AppLayerProtoDetectPMSignature *)); - - /* add an array indexed by pattern id to look up the sig */ - for (s = ctx->head; s != NULL;) { - next_s = s->next; - s->next = ctx->map[s->cd->id]; - ctx->map[s->cd->id] = s; - s = next_s; - } - ctx->head = NULL; - - - for (tmp_pat_id = 0; tmp_pat_id < max_pat_id; tmp_pat_id++) { - s = NULL; - for (s = ctx->map[tmp_pat_id]; s != NULL; s = s->next) { - if (s->cd->flags & DETECT_CONTENT_NOCASE) { - break; - } - } - /* if s != NULL now, it's CI. If NULL, CS */ - - if (s != NULL) { - mpm_ret = MpmAddPatternCI(&ctx->mpm_ctx, - s->cd->content, s->cd->content_len, - 0, 0, tmp_pat_id, 0, 0); - if (mpm_ret < 0) - goto error; - } else { - s = ctx->map[tmp_pat_id]; - if (s == NULL) - goto error; - - mpm_ret = MpmAddPatternCS(&ctx->mpm_ctx, - s->cd->content, s->cd->content_len, - 0, 0, tmp_pat_id, 0, 0); - if (mpm_ret < 0) - goto error; - } - } - - goto end; - error: - ret = -1; - end: - SCReturnInt(ret); -} - -static int AppLayerProtoDetectPMPrepareMpm(AppLayerProtoDetectPMCtx *ctx) -{ - SCEnter(); - - int ret = 0; - MpmCtx *mpm_ctx = &ctx->mpm_ctx; - - if (mpm_table[mpm_ctx->mpm_type].Prepare(mpm_ctx) < 0) - goto error; - - goto end; - error: - ret = -1; - end: - SCReturnInt(ret); -} - -static void AppLayerProtoDetectPMFreeSignature(AppLayerProtoDetectPMSignature *sig) -{ - SCEnter(); - if (sig == NULL) - SCReturn; - if (sig->cd) - DetectContentFree(sig->cd); - SCFree(sig); - SCReturn; -} - -static int AppLayerProtoDetectPMAddSignature(AppLayerProtoDetectPMCtx *ctx, DetectContentData *cd, - AppProto alproto) -{ - SCEnter(); - - int ret = 0; - AppLayerProtoDetectPMSignature *s = SCMalloc(sizeof(*s)); - if (unlikely(s == NULL)) - goto error; - memset(s, 0, sizeof(*s)); - - s->alproto = alproto; - s->cd = cd; - - /* prepend to the list */ - s->next = ctx->head; - ctx->head = s; - - goto end; - error: - ret = -1; - end: - SCReturnInt(ret); -} - -static int AppLayerProtoDetectPMRegisterPattern(uint8_t ipproto, AppProto alproto, - char *pattern, - uint16_t depth, uint16_t offset, - uint8_t direction, - uint8_t is_cs) -{ - SCEnter(); - - AppLayerProtoDetectCtxIpproto *ctx_ipp = &alpd_ctx.ctx_ipp[FlowGetProtoMapping(ipproto)]; - AppLayerProtoDetectPMCtx *ctx_pm = NULL; - DetectContentData *cd; - int ret = 0; - - cd = DetectContentParseEncloseQuotes(pattern); - if (cd == NULL) - goto error; - cd->depth = depth; - cd->offset = offset; - if (!is_cs) { - BoyerMooreCtxToNocase(cd->bm_ctx, cd->content, cd->content_len); - cd->flags |= DETECT_CONTENT_NOCASE; - } - if (depth < cd->content_len) - goto error; - - if (direction & STREAM_TOSERVER) - ctx_pm = (AppLayerProtoDetectPMCtx *)&ctx_ipp->ctx_pm[0]; - else - ctx_pm = (AppLayerProtoDetectPMCtx *)&ctx_ipp->ctx_pm[1]; - - if (depth > ctx_pm->max_len) - ctx_pm->max_len = depth; - if (depth < ctx_pm->min_len) - ctx_pm->min_len = depth; - - /* Finally turn it into a signature and add to the ctx. */ - AppLayerProtoDetectPMAddSignature(ctx_pm, cd, alproto); - - goto end; - error: - ret = -1; - end: - SCReturnInt(ret); -} - -/***** Protocol Retrieval *****/ - -AppProto AppLayerProtoDetectGetProto(AppLayerProtoDetectThreadCtx *tctx, - Flow *f, - uint8_t *buf, uint32_t buflen, - uint8_t ipproto, uint8_t direction) -{ - SCEnter(); - - AppProto alproto = ALPROTO_UNKNOWN; - AppProto pm_results[ALPROTO_MAX]; - uint16_t pm_matches; - - if (!FLOW_IS_PM_DONE(f, direction)) { - pm_matches = AppLayerProtoDetectPMGetProto(tctx, f, - buf, buflen, - direction, - ipproto, - pm_results); - if (pm_matches > 0) { - alproto = pm_results[0]; - goto end; - } - } - - if (!FLOW_IS_PP_DONE(f, direction)) - alproto = AppLayerProtoDetectPPGetProto(f, buf, buflen, ipproto, direction); - - end: - SCReturnCT(alproto, "AppProto"); -} - -static void AppLayerProtoDetectFreeProbingParsers(AppLayerProtoDetectProbingParser *pp) -{ - SCEnter(); - - AppLayerProtoDetectProbingParser *tmp_pp = NULL; - - if (pp == NULL) - goto end; - - while (pp != NULL) { - tmp_pp = pp->next; - AppLayerProtoDetectProbingParserFree(pp); - pp = tmp_pp; - } - - end: - SCReturn; -} - -/***** State Preparation *****/ - -int AppLayerProtoDetectPrepareState(void) -{ - SCEnter(); - - AppLayerProtoDetectPMCtx *ctx_pm; - int i, j; - int ret = 0; - - for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { - for (j = 0; j < 2; j++) { - ctx_pm = &alpd_ctx.ctx_ipp[i].ctx_pm[j]; - - if (AppLayerProtoDetectPMSetContentIDs(ctx_pm) < 0) - goto error; - - if (ctx_pm->max_pat_id == 0) - continue; - - if (AppLayerProtoDetectPMMapSignatures(ctx_pm) < 0) - goto error; - if (AppLayerProtoDetectPMPrepareMpm(ctx_pm) < 0) - goto error; - } - } - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - AppLayerProtoDetectPrintProbingParsers(alpd_ctx.ctx_pp); - } -#endif - - goto end; - error: - ret = -1; - end: - SCReturnInt(ret); -} - -/***** PP registration *****/ - -/** \brief register parser at a port - * - * \param direction STREAM_TOSERVER or STREAM_TOCLIENT for dp or sp - */ -void AppLayerProtoDetectPPRegister(uint8_t ipproto, - char *portstr, - AppProto alproto, - uint16_t min_depth, uint16_t max_depth, - uint8_t direction, - ProbingParserFPtr ProbingParser) -{ - SCEnter(); - - DetectPort *head = NULL; - DetectPortParse(NULL,&head, portstr); - DetectPort *temp_dp = head; - while (temp_dp != NULL) { - uint32_t port = temp_dp->port; - if (port == 0 && temp_dp->port2 != 0) - port++; - for ( ; port <= temp_dp->port2; port++) { - AppLayerProtoDetectInsertNewProbingParser(&alpd_ctx.ctx_pp, - ipproto, - port, - alproto, - min_depth, max_depth, - direction, - ProbingParser); - } - temp_dp = temp_dp->next; - } - DetectPortCleanupList(head); - - SCReturn; -} - -int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name, - uint8_t ipproto, - const char *alproto_name, - AppProto alproto, - uint16_t min_depth, uint16_t max_depth, - ProbingParserFPtr ProbingParser) -{ - SCEnter(); - - char param[100]; - int r; - ConfNode *node; - ConfNode *port_node = NULL; - int config = 0; - - r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.", - alproto_name, ".detection-ports"); - if (r < 0) { - SCLogError(SC_ERR_FATAL, "snprintf failure."); - exit(EXIT_FAILURE); - } else if (r > (int)sizeof(param)) { - SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); - exit(EXIT_FAILURE); - } - node = ConfGetNode(param); - if (node == NULL) { - SCLogDebug("Entry for %s not found.", param); - r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.", - alproto_name, ".", ipproto_name, ".detection-ports"); - if (r < 0) { - SCLogError(SC_ERR_FATAL, "snprintf failure."); - exit(EXIT_FAILURE); - } else if (r > (int)sizeof(param)) { - SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); - exit(EXIT_FAILURE); - } - node = ConfGetNode(param); - if (node == NULL) - goto end; - } - - /* detect by destination port of the flow (e.g. port 53 for DNS) */ - port_node = ConfNodeLookupChild(node, "dp"); - if (port_node == NULL) - port_node = ConfNodeLookupChild(node, "toserver"); - - if (port_node != NULL && port_node->val != NULL) { - AppLayerProtoDetectPPRegister(ipproto, - port_node->val, - alproto, - min_depth, max_depth, - STREAM_TOSERVER, /* to indicate dp */ - ProbingParser); - } - - /* detect by source port of flow */ - port_node = ConfNodeLookupChild(node, "sp"); - if (port_node == NULL) - port_node = ConfNodeLookupChild(node, "toclient"); - - if (port_node != NULL && port_node->val != NULL) { - AppLayerProtoDetectPPRegister(ipproto, - port_node->val, - alproto, - min_depth, max_depth, - STREAM_TOCLIENT, /* to indicate sp */ - ProbingParser); - - } - - config = 1; - end: - SCReturnInt(config); -} - -/***** PM registration *****/ - -int AppLayerProtoDetectPMRegisterPatternCS(uint8_t ipproto, AppProto alproto, - char *pattern, - uint16_t depth, uint16_t offset, - uint8_t direction) -{ - SCEnter(); - int r = 0; - r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto, - pattern, - depth, offset, - direction, - 1 /* case-sensitive */); - SCReturnInt(r); -} - -int AppLayerProtoDetectPMRegisterPatternCI(uint8_t ipproto, AppProto alproto, - char *pattern, - uint16_t depth, uint16_t offset, - uint8_t direction) -{ - SCEnter(); - int r = 0; - r = AppLayerProtoDetectPMRegisterPattern(ipproto, alproto, - pattern, - depth, offset, - direction, - 0 /* !case-sensitive */); - SCReturnInt(r); -} - -/***** Setup/General Registration *****/ - -int AppLayerProtoDetectSetup(void) -{ - SCEnter(); - - int i, j; - - memset(&alpd_ctx, 0, sizeof(alpd_ctx)); - - for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { - for (j = 0; j < 2; j++) { - MpmInitCtx(&alpd_ctx.ctx_ipp[i].ctx_pm[j].mpm_ctx, MPM_AC); - } - } - SCReturnInt(0); -} - -/** - * \todo incomplete. Need more work. - */ -int AppLayerProtoDetectDeSetup(void) -{ - SCEnter(); - - int ipproto_map = 0; - int dir = 0; - PatIntId id = 0; - AppLayerProtoDetectPMCtx *pm_ctx = NULL; - AppLayerProtoDetectPMSignature *sig = NULL, *next_sig = NULL; - - for (ipproto_map = 0; ipproto_map < FLOW_PROTO_DEFAULT; ipproto_map++) { - for (dir = 0; dir < 2; dir++) { - pm_ctx = &alpd_ctx.ctx_ipp[ipproto_map].ctx_pm[dir]; - mpm_table[pm_ctx->mpm_ctx.mpm_type].DestroyCtx(pm_ctx->mpm_ctx.ctx); - for (id = 0; id < pm_ctx->max_pat_id; id++) { - sig = pm_ctx->map[id]; - while (sig != NULL) { - next_sig = sig->next; - AppLayerProtoDetectPMFreeSignature(sig); - sig = next_sig; - } - } - } - } - - AppLayerProtoDetectFreeProbingParsers(alpd_ctx.ctx_pp); - - SCReturnInt(0); -} - -void AppLayerProtoDetectRegisterProtocol(AppProto alproto, char *alproto_name) -{ - SCEnter(); - - if (alpd_ctx.alproto_names[alproto] != NULL) - goto end; - - alpd_ctx.alproto_names[alproto] = alproto_name; - - goto end; - end: - SCReturn; -} - -int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, - const char *alproto) -{ - SCEnter(); - - BUG_ON(ipproto == NULL || alproto == NULL); - - int enabled = 1; - char param[100]; - ConfNode *node; - int r; - - if (RunmodeIsUnittests()) - goto enabled; - - r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.", - alproto, ".enabled"); - if (r < 0) { - SCLogError(SC_ERR_FATAL, "snprintf failure."); - exit(EXIT_FAILURE); - } else if (r > (int)sizeof(param)) { - SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); - exit(EXIT_FAILURE); - } - - node = ConfGetNode(param); - if (node == NULL) { - SCLogDebug("Entry for %s not found.", param); - r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.", - alproto, ".", ipproto, ".enabled"); - if (r < 0) { - SCLogError(SC_ERR_FATAL, "snprintf failure."); - exit(EXIT_FAILURE); - } else if (r > (int)sizeof(param)) { - SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); - exit(EXIT_FAILURE); - } - - node = ConfGetNode(param); - if (node == NULL) { - SCLogDebug("Entry for %s not found.", param); - goto enabled; - } - } - - if (node->val) { - if (ConfValIsTrue(node->val)) { - goto enabled; - } else if (ConfValIsFalse(node->val)) { - goto disabled; - } else if (strcasecmp(node->val, "detection-only") == 0) { - goto enabled; - } - } - - /* Invalid or null value. */ - SCLogError(SC_ERR_FATAL, "Invalid value found for %s.", param); - exit(EXIT_FAILURE); - - disabled: - enabled = 0; - enabled: - SCReturnInt(enabled); -} - -AppLayerProtoDetectThreadCtx *AppLayerProtoDetectGetCtxThread(void) -{ - SCEnter(); - - AppLayerProtoDetectThreadCtx *alpd_tctx = NULL; - MpmCtx *mpm_ctx; - MpmThreadCtx *mpm_tctx; - int i, j; - PatIntId max_pat_id = 0; - - for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { - for (j = 0; j < 2; j++) { - if (max_pat_id == 0) { - max_pat_id = alpd_ctx.ctx_ipp[i].ctx_pm[j].max_pat_id; - - } else if (alpd_ctx.ctx_ipp[i].ctx_pm[j].max_pat_id && - max_pat_id < alpd_ctx.ctx_ipp[i].ctx_pm[j].max_pat_id) - { - max_pat_id = alpd_ctx.ctx_ipp[i].ctx_pm[j].max_pat_id; - } - } - } - - alpd_tctx = SCMalloc(sizeof(*alpd_tctx)); - if (alpd_tctx == NULL) - goto error; - memset(alpd_tctx, 0, sizeof(*alpd_tctx)); - - /* Get the max pat id for all the mpm ctxs. */ - if (PmqSetup(&alpd_tctx->pmq, max_pat_id) < 0) - goto error; - - for (i = 0; i < FLOW_PROTO_DEFAULT; i++) { - for (j = 0; j < 2; j++) { - mpm_ctx = &alpd_ctx.ctx_ipp[i].ctx_pm[j].mpm_ctx; - mpm_tctx = &alpd_tctx->mpm_tctx[i][j]; - mpm_table[mpm_ctx->mpm_type].InitThreadCtx(mpm_ctx, mpm_tctx, 0); - } - } - - goto end; - error: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - alpd_tctx = NULL; - end: - SCReturnPtr(alpd_tctx, "AppLayerProtoDetectThreadCtx"); -} - -void AppLayerProtoDetectDestroyCtxThread(AppLayerProtoDetectThreadCtx *alpd_tctx) -{ - SCEnter(); - - MpmCtx *mpm_ctx; - MpmThreadCtx *mpm_tctx; - int ipproto_map, dir; - - for (ipproto_map = 0; ipproto_map < FLOW_PROTO_DEFAULT; ipproto_map++) { - for (dir = 0; dir < 2; dir++) { - mpm_ctx = &alpd_ctx.ctx_ipp[ipproto_map].ctx_pm[dir].mpm_ctx; - mpm_tctx = &alpd_tctx->mpm_tctx[ipproto_map][dir]; - mpm_table[mpm_ctx->mpm_type].DestroyThreadCtx(mpm_ctx, mpm_tctx); - } - } - PmqFree(&alpd_tctx->pmq); - SCFree(alpd_tctx); - - SCReturn; -} - -/***** Utility *****/ - -void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos) -{ - SCEnter(); - - AppLayerProtoDetectPMGetIpprotos(alproto, ipprotos); - AppLayerProtoDetectPPGetIpprotos(alproto, ipprotos); - - SCReturn; -} - -AppProto AppLayerProtoDetectGetProtoByName(char *alproto_name) -{ - SCEnter(); - - AppProto a; - for (a = 0; a < ALPROTO_MAX; a++) { - if (alpd_ctx.alproto_names[a] != NULL && - strlen(alpd_ctx.alproto_names[a]) == strlen(alproto_name) && - (SCMemcmp(alpd_ctx.alproto_names[a], alproto_name, strlen(alproto_name)) == 0)) - { - SCReturnCT(a, "AppProto"); - } - } - - SCReturnCT(ALPROTO_UNKNOWN, "AppProto"); -} - -char *AppLayerProtoDetectGetProtoName(AppProto alproto) -{ - return alpd_ctx.alproto_names[alproto]; -} - -void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos) -{ - SCEnter(); - - memset(alprotos, 0, ALPROTO_MAX * sizeof(AppProto)); - - int alproto; - - for (alproto = 0; alproto != ALPROTO_MAX; alproto++) { - if (alpd_ctx.alproto_names[alproto] != NULL) - alprotos[alproto] = 1; - } - - SCReturn; -} - -/***** Unittests *****/ - -#ifdef UNITTESTS - -static AppLayerProtoDetectCtx alpd_ctx_ut; - -void AppLayerProtoDetectUnittestCtxBackup(void) -{ - SCEnter(); - alpd_ctx_ut = alpd_ctx; - memset(&alpd_ctx, 0, sizeof(alpd_ctx)); - SCReturn; -} - -void AppLayerProtoDetectUnittestCtxRestore(void) -{ - SCEnter(); - alpd_ctx = alpd_ctx_ut; - memset(&alpd_ctx_ut, 0, sizeof(alpd_ctx_ut)); - SCReturn; -} - -int AppLayerProtoDetectTest01(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - char *buf; - int r = 0; - - buf = "HTTP"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); - buf = "GET"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOSERVER); - - AppLayerProtoDetectPrepareState(); - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 1) { - printf("Failure - " - "alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 1\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { - printf("Failure - " - "alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1\n"); - goto end; - } - - r = 1; - - end: - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -int AppLayerProtoDetectTest02(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - char *buf; - int r = 0; - - buf = "HTTP"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); - buf = "ftp"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_FTP, buf, 4, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_FTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_FTP\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1]->alproto != ALPROTO_HTTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1].alproto != ALPROTO_HTTP\n"); - goto end; - } - - r = 1; - - end: - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -int AppLayerProtoDetectTest03(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = "HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n"; - char *buf; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - memset(pm_results, 0, sizeof(pm_results)); - - buf = "HTTP"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); - buf = "220 "; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_FTP, buf, 4, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_FTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_FTP\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1]->alproto != ALPROTO_HTTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1].alproto != ALPROTO_HTTP\n"); - goto end; - } - - uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { - printf("cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -int AppLayerProtoDetectTest04(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = "HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\n"; - char *buf; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - memset(pm_results, 0, sizeof(pm_results)); - - buf = "200 "; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 13, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_HTTP\n"); - goto end; - } - - uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { - printf("cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -int AppLayerProtoDetectTest05(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = "HTTP/1.1 200 OK\r\nServer: Apache/1.0\r\n\r\nBlahblah"; - char *buf; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - memset(pm_results, 0, sizeof(pm_results)); - - buf = "HTTP"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); - buf = "220 "; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_FTP, buf, 4, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_FTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_FTP\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1]->alproto != ALPROTO_HTTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1].alproto != ALPROTO_HTTP\n"); - goto end; - } - - uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { - printf("cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -int AppLayerProtoDetectTest06(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = "220 Welcome to the OISF FTP server\r\n"; - char *buf; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - buf = "HTTP"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); - buf = "220 "; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_FTP, buf, 4, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_FTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_FTP\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1]->alproto != ALPROTO_HTTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[1].alproto != ALPROTO_HTTP\n"); - goto end; - } - - uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_FTP) { - printf("cnt != 1 && pm_results[0] != AlPROTO_FTP\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -int AppLayerProtoDetectTest07(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = "220 Welcome to the OISF HTTP/FTP server\r\n"; - char *buf; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - memset(pm_results, 0, sizeof(pm_results)); - - buf = "HTTP"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, buf, 4, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_HTTP\n"); - goto end; - } - - uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 0) { - printf("cnt != 0\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -int AppLayerProtoDetectTest08(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = { - 0x00, 0x00, 0x00, 0x85, 0xff, 0x53, 0x4d, 0x42, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02, - 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, - 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, - 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, - 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, - 0x30, 0x00, 0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x57, - 0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61, 0x00, 0x02, - 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, - 0x32, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, - 0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54, - 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, - 0x00 - }; - char *buf; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - memset(pm_results, 0, sizeof(pm_results)); - - buf = "|ff|SMB"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB, buf, 8, 4, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_SMB) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_SMB\n"); - goto end; - } - - uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_SMB) { - printf("cnt != 1 && pm_results[0] != AlPROTO_SMB\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -int AppLayerProtoDetectTest09(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = { - 0x00, 0x00, 0x00, 0x66, 0xfe, 0x53, 0x4d, 0x42, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x02 - }; - char *buf; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - memset(pm_results, 0, sizeof(pm_results)); - - buf = "|fe|SMB"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2, buf, 8, 4, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_SMB2) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_SMB2\n"); - goto end; - } - - uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_SMB2) { - printf("cnt != 1 && pm_results[0] != AlPROTO_SMB2\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -int AppLayerProtoDetectTest10(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0xb8, 0x4a, 0x9f, 0x4d, 0x1c, 0x7d, 0xcf, 0x11, - 0x86, 0x1e, 0x00, 0x20, 0xaf, 0x6e, 0x7c, 0x57, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - char *buf; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - memset(pm_results, 0, sizeof(pm_results)); - - buf = "|05 00|"; - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_DCERPC, buf, 4, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 0\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 2\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_DCERPC) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0].alproto != ALPROTO_DCERPC\n"); - goto end; - } - - uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_DCERPC) { - printf("cnt != 1 && pm_results[0] != AlPROTO_DCERPC\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -/** - * \test Why we still get http for connect... obviously because - * we also match on the reply, duh - */ -int AppLayerProtoDetectTest11(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = "CONNECT www.ssllabs.com:443 HTTP/1.0\r\n"; - uint8_t l7data_resp[] = "HTTP/1.1 405 Method Not Allowed\r\n"; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - memset(pm_results, 0, sizeof(pm_results)); - - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "GET", 3, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "PUT", 3, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "POST", 4, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "TRACE", 5, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "OPTIONS", 7, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "CONNECT", 7, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 7) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 7\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].max_pat_id != 1\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map == NULL) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map != NULL\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[0]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[1]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[2]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[3]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[4]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[5]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[6]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) - { - printf("failure 1\n"); - goto end; - } - - memset(pm_results, 0, sizeof(pm_results)); - uint32_t cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOSERVER, - IPPROTO_TCP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { - printf("l7data - cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); - goto end; - } - - memset(pm_results, 0, sizeof(pm_results)); - cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data_resp, sizeof(l7data_resp), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { - printf("l7data_resp - cnt != 1 && pm_results[0] != AlPROTO_HTTP\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -/** - * \test AlpProtoSignature test - */ -int AppLayerProtoDetectTest12(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - int r = 0; - - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOSERVER); - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].head == NULL || - alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map != NULL) - { - printf("failure 1\n"); - goto end; - } - - AppLayerProtoDetectPrepareState(); - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].max_pat_id != 1) { - printf("failure 2\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].head != NULL || - alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map == NULL) - { - printf("failure 3\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[0]->alproto != ALPROTO_HTTP) { - printf("failure 4\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[0]->cd->id != 0) { - printf("failure 5\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_TCP].ctx_pm[0].map[0]->next != NULL) { - printf("failure 6\n"); - goto end; - } - - r = 1; - - end: - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -/** - * \test What about if we add some sigs only for udp but call for tcp? - * It should not detect any proto - */ -int AppLayerProtoDetectTest13(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = "CONNECT www.ssllabs.com:443 HTTP/1.0\r\n"; - uint8_t l7data_resp[] = "HTTP/1.1 405 Method Not Allowed\r\n"; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - uint32_t cnt; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_TCP); - - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "GET", 3, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "PUT", 3, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "POST", 4, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "TRACE", 5, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "OPTIONS", 7, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "CONNECT", 7, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].max_pat_id != 7) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].max_pat_id != 7\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].max_pat_id != 1) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].max_pat_id != 1\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[0]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[1]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[2]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[3]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[4]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[5]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[6]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) - { - printf("failure 1\n"); - goto end; - } - - memset(pm_results, 0, sizeof(pm_results)); - cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOSERVER, - IPPROTO_TCP, - pm_results); - if (cnt != 0) { - printf("l7data - cnt != 0\n"); - goto end; - } - - memset(pm_results, 0, sizeof(pm_results)); - cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data_resp, sizeof(l7data_resp), - STREAM_TOCLIENT, - IPPROTO_TCP, - pm_results); - if (cnt != 0) { - printf("l7data_resp - cnt != 0\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -/** - * \test What about if we add some sigs only for udp calling it for UDP? - * It should detect ALPROTO_HTTP (over udp). This is just a check - * to ensure that TCP/UDP differences work correctly. - */ -int AppLayerProtoDetectTest14(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t l7data[] = "CONNECT www.ssllabs.com:443 HTTP/1.0\r\n"; - uint8_t l7data_resp[] = "HTTP/1.1 405 Method Not Allowed\r\n"; - int r = 0; - Flow f; - AppProto pm_results[ALPROTO_MAX]; - AppLayerProtoDetectThreadCtx *alpd_tctx; - uint32_t cnt; - - memset(&f, 0x00, sizeof(f)); - f.protomap = FlowGetProtoMapping(IPPROTO_UDP); - - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "GET", 3, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "PUT", 3, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "POST", 4, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "TRACE", 5, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "OPTIONS", 7, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "CONNECT", 7, 0, STREAM_TOSERVER); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_UDP, ALPROTO_HTTP, "HTTP", 4, 0, STREAM_TOCLIENT); - - AppLayerProtoDetectPrepareState(); - /* AppLayerProtoDetectGetCtxThread() should be called post AppLayerProtoDetectPrepareState(), since - * it sets internal structures which depends on the above function. */ - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].max_pat_id != 7) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].max_pat_id != 7\n"); - goto end; - } - if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].max_pat_id != 1) { - printf("alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].max_pat_id != 1\n"); - goto end; - } - - if (alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[0]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[1]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[2]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[3]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[4]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[5]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[0].map[6]->alproto != ALPROTO_HTTP || - alpd_ctx.ctx_ipp[FLOW_PROTO_UDP].ctx_pm[1].map[0]->alproto != ALPROTO_HTTP) - { - printf("failure 1\n"); - goto end; - } - - memset(pm_results, 0, sizeof(pm_results)); - cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data, sizeof(l7data), - STREAM_TOSERVER, - IPPROTO_UDP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { - printf("l7data - cnt != 0\n"); - goto end; - } - - memset(pm_results, 0, sizeof(pm_results)); - cnt = AppLayerProtoDetectPMGetProto(alpd_tctx, - &f, - l7data_resp, sizeof(l7data_resp), - STREAM_TOCLIENT, - IPPROTO_UDP, - pm_results); - if (cnt != 1 && pm_results[0] != ALPROTO_HTTP) { - printf("l7data_resp - cnt != 0\n"); - goto end; - } - - r = 1; - - end: - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return r; -} - -typedef struct AppLayerProtoDetectPPTestDataElement_ { - char *alproto_name; - AppProto alproto; - uint16_t port; - uint32_t alproto_mask; - uint32_t min_depth; - uint32_t max_depth; -} AppLayerProtoDetectPPTestDataElement; - -typedef struct AppLayerProtoDetectPPTestDataPort_ { - uint16_t port; - uint32_t alproto_mask; - uint16_t dp_max_depth; - uint16_t sp_max_depth; - - AppLayerProtoDetectPPTestDataElement *toserver_element; - AppLayerProtoDetectPPTestDataElement *toclient_element; - int ts_no_of_element; - int tc_no_of_element; -} AppLayerProtoDetectPPTestDataPort; - - -typedef struct AppLayerProtoDetectPPTestDataIPProto_ { - uint8_t ipproto; - - AppLayerProtoDetectPPTestDataPort *port; - int no_of_port; -} AppLayerProtoDetectPPTestDataIPProto; - -static int AppLayerProtoDetectPPTestData(AppLayerProtoDetectProbingParser *pp, - AppLayerProtoDetectPPTestDataIPProto *ip_proto, - int no_of_ip_proto) -{ - int result = 0; - int i = -1, j = -1 , k = -1; -#ifdef DEBUG - int dir = 0; -#endif - for (i = 0; i < no_of_ip_proto; i++, pp = pp->next) { - if (pp->ipproto != ip_proto[i].ipproto) - goto end; - - AppLayerProtoDetectProbingParserPort *pp_port = pp->port; - for (k = 0; k < ip_proto[i].no_of_port; k++, pp_port = pp_port->next) { - if (pp_port->port != ip_proto[i].port[k].port) - goto end; - if (pp_port->alproto_mask != ip_proto[i].port[k].alproto_mask) - goto end; - if (pp_port->alproto_mask != ip_proto[i].port[k].alproto_mask) - goto end; - if (pp_port->dp_max_depth != ip_proto[i].port[k].dp_max_depth) - goto end; - if (pp_port->sp_max_depth != ip_proto[i].port[k].sp_max_depth) - goto end; - - AppLayerProtoDetectProbingParserElement *pp_element = pp_port->dp; -#ifdef DEBUG - dir = 0; -#endif - for (j = 0 ; j < ip_proto[i].port[k].ts_no_of_element; - j++, pp_element = pp_element->next) { - - if (pp_element->alproto != ip_proto[i].port[k].toserver_element[j].alproto) { - goto end; - } - if (pp_element->port != ip_proto[i].port[k].toserver_element[j].port) { - goto end; - } - if (pp_element->alproto_mask != ip_proto[i].port[k].toserver_element[j].alproto_mask) { - goto end; - } - if (pp_element->min_depth != ip_proto[i].port[k].toserver_element[j].min_depth) { - goto end; - } - if (pp_element->max_depth != ip_proto[i].port[k].toserver_element[j].max_depth) { - goto end; - } - } /* for */ - if (pp_element != NULL) - goto end; - - pp_element = pp_port->sp; -#ifdef DEBUG - dir = 1; -#endif - for (j = 0 ; j < ip_proto[i].port[k].tc_no_of_element; j++, pp_element = pp_element->next) { - if (pp_element->alproto != ip_proto[i].port[k].toclient_element[j].alproto) { - goto end; - } - if (pp_element->port != ip_proto[i].port[k].toclient_element[j].port) { - goto end; - } - if (pp_element->alproto_mask != ip_proto[i].port[k].toclient_element[j].alproto_mask) { - goto end; - } - if (pp_element->min_depth != ip_proto[i].port[k].toclient_element[j].min_depth) { - goto end; - } - if (pp_element->max_depth != ip_proto[i].port[k].toclient_element[j].max_depth) { - goto end; - } - } /* for */ - if (pp_element != NULL) - goto end; - } - if (pp_port != NULL) - goto end; - } - if (pp != NULL) - goto end; - - result = 1; - end: -#ifdef DEBUG - printf("i = %d, k = %d, j = %d(%s)\n", i, k, j, (dir == 0) ? "ts" : "tc"); -#endif - return result; -} - -static uint16_t ProbingParserDummyForTesting(uint8_t *input, - uint32_t input_len, - uint32_t *offset) -{ - return 0; -} - -static int AppLayerProtoDetectTest15(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - int result = 0; - - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "80", - ALPROTO_HTTP, - 5, 8, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "80", - ALPROTO_SMB, - 5, 6, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "80", - ALPROTO_FTP, - 7, 10, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "81", - ALPROTO_DCERPC, - 9, 10, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "81", - ALPROTO_FTP, - 7, 15, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "0", - ALPROTO_SMTP, - 12, 0, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "0", - ALPROTO_TLS, - 12, 18, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "85", - ALPROTO_DCERPC, - 9, 10, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "85", - ALPROTO_FTP, - 7, 15, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - result = 1; - - AppLayerProtoDetectPPRegister(IPPROTO_UDP, - "85", - ALPROTO_IMAP, - 12, 23, - STREAM_TOSERVER, - ProbingParserDummyForTesting); - - /* toclient */ - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "0", - ALPROTO_JABBER, - 12, 23, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "0", - ALPROTO_IRC, - 12, 14, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "85", - ALPROTO_DCERPC, - 9, 10, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "81", - ALPROTO_FTP, - 7, 15, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "0", - ALPROTO_TLS, - 12, 18, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "80", - ALPROTO_HTTP, - 5, 8, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "81", - ALPROTO_DCERPC, - 9, 10, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "90", - ALPROTO_FTP, - 7, 15, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "80", - ALPROTO_SMB, - 5, 6, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_UDP, - "85", - ALPROTO_IMAP, - 12, 23, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "0", - ALPROTO_SMTP, - 12, 17, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "80", - ALPROTO_FTP, - 7, 10, - STREAM_TOCLIENT, - ProbingParserDummyForTesting); - - AppLayerProtoDetectPPTestDataElement element_ts_80[] = { - { "http", ALPROTO_HTTP, 80, 1 << ALPROTO_HTTP, 5, 8 }, - { "smb", ALPROTO_SMB, 80, 1 << ALPROTO_SMB, 5, 6 }, - { "ftp", ALPROTO_FTP, 80, 1 << ALPROTO_FTP, 7, 10 }, - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - }; - AppLayerProtoDetectPPTestDataElement element_tc_80[] = { - { "http", ALPROTO_HTTP, 80, 1 << ALPROTO_HTTP, 5, 8 }, - { "smb", ALPROTO_SMB, 80, 1 << ALPROTO_SMB, 5, 6 }, - { "ftp", ALPROTO_FTP, 80, 1 << ALPROTO_FTP, 7, 10 }, - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } - }; - - AppLayerProtoDetectPPTestDataElement element_ts_81[] = { - { "dcerpc", ALPROTO_DCERPC, 81, 1 << ALPROTO_DCERPC, 9, 10 }, - { "ftp", ALPROTO_FTP, 81, 1 << ALPROTO_FTP, 7, 15 }, - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - }; - AppLayerProtoDetectPPTestDataElement element_tc_81[] = { - { "ftp", ALPROTO_FTP, 81, 1 << ALPROTO_FTP, 7, 15 }, - { "dcerpc", ALPROTO_DCERPC, 81, 1 << ALPROTO_DCERPC, 9, 10 }, - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } - }; - - AppLayerProtoDetectPPTestDataElement element_ts_85[] = { - { "dcerpc", ALPROTO_DCERPC, 85, 1 << ALPROTO_DCERPC, 9, 10 }, - { "ftp", ALPROTO_FTP, 85, 1 << ALPROTO_FTP, 7, 15 }, - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - }; - AppLayerProtoDetectPPTestDataElement element_tc_85[] = { - { "dcerpc", ALPROTO_DCERPC, 85, 1 << ALPROTO_DCERPC, 9, 10 }, - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } - }; - - AppLayerProtoDetectPPTestDataElement element_ts_90[] = { - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - }; - AppLayerProtoDetectPPTestDataElement element_tc_90[] = { - { "ftp", ALPROTO_FTP, 90, 1 << ALPROTO_FTP, 7, 15 }, - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } - }; - - AppLayerProtoDetectPPTestDataElement element_ts_0[] = { - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 0 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 25 }, - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - }; - AppLayerProtoDetectPPTestDataElement element_tc_0[] = { - { "jabber", ALPROTO_JABBER, 0, 1 << ALPROTO_JABBER, 12, 23 }, - { "irc", ALPROTO_IRC, 0, 1 << ALPROTO_IRC, 12, 14 }, - { "tls", ALPROTO_TLS, 0, 1 << ALPROTO_TLS, 12, 18 }, - { "smtp", ALPROTO_SMTP, 0, 1 << ALPROTO_SMTP, 12, 17 } - }; - - - AppLayerProtoDetectPPTestDataElement element_ts_85_udp[] = { - { "imap", ALPROTO_IMAP, 85, 1 << ALPROTO_IMAP, 12, 23 }, - }; - AppLayerProtoDetectPPTestDataElement element_tc_85_udp[] = { - { "imap", ALPROTO_IMAP, 85, 1 << ALPROTO_IMAP, 12, 23 }, - }; - - AppLayerProtoDetectPPTestDataPort ports_tcp[] = { - { 80, - ((1 << ALPROTO_HTTP) | (1 << ALPROTO_SMB) | (1 << ALPROTO_FTP) | - (1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), - ((1 << ALPROTO_HTTP) | (1 << ALPROTO_SMB) | (1 << ALPROTO_FTP) | - (1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), - 23, - element_ts_80, element_tc_80, - sizeof(element_ts_80) / sizeof(AppLayerProtoDetectPPTestDataElement), - sizeof(element_tc_80) / sizeof(AppLayerProtoDetectPPTestDataElement), - }, - { 81, - ((1 << ALPROTO_DCERPC) | (1 << ALPROTO_FTP) | - (1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), - ((1 << ALPROTO_FTP) | (1 << ALPROTO_DCERPC) | - (1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), - 23, - element_ts_81, element_tc_81, - sizeof(element_ts_81) / sizeof(AppLayerProtoDetectPPTestDataElement), - sizeof(element_tc_81) / sizeof(AppLayerProtoDetectPPTestDataElement), - }, - { 85, - ((1 << ALPROTO_DCERPC) | (1 << ALPROTO_FTP) | - (1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), - ((1 << ALPROTO_DCERPC) | - (1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), - 23, - element_ts_85, element_tc_85, - sizeof(element_ts_85) / sizeof(AppLayerProtoDetectPPTestDataElement), - sizeof(element_tc_85) / sizeof(AppLayerProtoDetectPPTestDataElement) - }, - { 90, - ((1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), - ((1 << ALPROTO_FTP) | - (1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), - 23, - element_ts_90, element_tc_90, - sizeof(element_ts_90) / sizeof(AppLayerProtoDetectPPTestDataElement), - sizeof(element_tc_90) / sizeof(AppLayerProtoDetectPPTestDataElement) - }, - { 0, - ((1 << ALPROTO_SMTP) | (1 << ALPROTO_TLS) | (1 << ALPROTO_IRC) | (1 << ALPROTO_JABBER)), - ((1 << ALPROTO_JABBER) | (1 << ALPROTO_IRC) | (1 << ALPROTO_TLS) | (1 << ALPROTO_SMTP)), - 23, - element_ts_0, element_tc_0, - sizeof(element_ts_0) / sizeof(AppLayerProtoDetectPPTestDataElement), - sizeof(element_tc_0) / sizeof(AppLayerProtoDetectPPTestDataElement) - } - }; - - AppLayerProtoDetectPPTestDataPort ports_udp[] = { - { 85, - (1 << ALPROTO_IMAP), - (1 << ALPROTO_IMAP), - 23, - element_ts_85_udp, element_tc_85_udp, - sizeof(element_ts_85_udp) / sizeof(AppLayerProtoDetectPPTestDataElement), - sizeof(element_tc_85_udp) / sizeof(AppLayerProtoDetectPPTestDataElement), - }, - }; - - AppLayerProtoDetectPPTestDataIPProto ip_proto[] = { - { IPPROTO_TCP, - ports_tcp, - sizeof(ports_tcp) / sizeof(AppLayerProtoDetectPPTestDataPort), - }, - { IPPROTO_UDP, - ports_udp, - sizeof(ports_udp) / sizeof(AppLayerProtoDetectPPTestDataPort), - }, - }; - - - if (AppLayerProtoDetectPPTestData(alpd_ctx.ctx_pp, ip_proto, - sizeof(ip_proto) / sizeof(AppLayerProtoDetectPPTestDataIPProto)) == 0) { - goto end; - } - result = 1; - - end: - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - return result; -} - - -/** \test test if the engine detect the proto and match with it */ -static int AppLayerProtoDetectTest16(void) -{ - int result = 0; - Flow *f = NULL; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - if (p == NULL) { - printf("packet setup failed: "); - goto end; - } - - f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); - if (f == NULL) { - printf("flow setup failed: "); - goto end; - } - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - p->flow = f; - - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - f->alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(msg:\"Test content option\"; " - "sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should: "); - goto end; - } - result = 1; - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - UTHFreeFlow(f); - return result; -} - -/** \test test if the engine detect the proto on a non standar port - * and match with it */ -static int AppLayerProtoDetectTest17(void) -{ - int result = 0; - Flow *f = NULL; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacketSrcDstPorts(http_buf1, http_buf1_len, IPPROTO_TCP, 12345, 88); - - f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - p->flow = f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f->alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert http any !80 -> any any " - "(msg:\"http over non standar port\"; " - "sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should: "); - goto end; - } - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - UTHFreeFlow(f); - return result; -} - -/** \test test if the engine detect the proto and doesn't match - * because the sig expects another proto (ex ftp)*/ -static int AppLayerProtoDetectTest18(void) -{ - int result = 0; - Flow *f = NULL; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - p->flow = f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f->alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert ftp any any -> any any " - "(msg:\"Test content option\"; " - "sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not (it's not ftp): "); - goto end; - } - - result = 1; - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - UTHFreeFlow(f); - return result; -} - -/** \test test if the engine detect the proto and doesn't match - * because the packet has another proto (ex ftp) */ -static int AppLayerProtoDetectTest19(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t http_buf1[] = "MPUT one\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacketSrcDstPorts(http_buf1, http_buf1_len, IPPROTO_TCP, 12345, 88); - - f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - p->flow = f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f->alproto = ALPROTO_FTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert http any !80 -> any any " - "(msg:\"http over non standar port\"; " - "sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_FTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not (it's ftp): "); - goto end; - } - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - UTHFreeFlow(f); - return result; -} - -/** \test test if the engine detect the proto and match with it - * and also against a content option */ -static int AppLayerProtoDetectTest20(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - p->flow = f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f->alproto = ALPROTO_HTTP; - f->proto = IPPROTO_TCP; - p->flags |= PKT_STREAM_ADD; - p->flags |= PKT_STREAM_EOF; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - StreamTcpInitConfig(TRUE); - - StreamMsg *stream_msg = StreamMsgGetFromPool(); - if (stream_msg == NULL) { - printf("no stream_msg: "); - goto end; - } - - memcpy(stream_msg->data, http_buf1, http_buf1_len); - stream_msg->data_len = http_buf1_len; - - ssn.toserver_smsg_head = stream_msg; - ssn.toserver_smsg_tail = stream_msg; - - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(msg:\"Test content option\"; " - "content:\"one\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should: "); - goto end; - } - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - UTHFreeFlow(f); - return result; -} - - -void AppLayerProtoDetectUnittestsRegister(void) -{ - SCEnter(); - - UtRegisterTest("AppLayerProtoDetectTest01", AppLayerProtoDetectTest01, 1); - UtRegisterTest("AppLayerProtoDetectTest02", AppLayerProtoDetectTest02, 1); - UtRegisterTest("AppLayerProtoDetectTest03", AppLayerProtoDetectTest03, 1); - UtRegisterTest("AppLayerProtoDetectTest04", AppLayerProtoDetectTest04, 1); - UtRegisterTest("AppLayerProtoDetectTest05", AppLayerProtoDetectTest05, 1); - UtRegisterTest("AppLayerProtoDetectTest06", AppLayerProtoDetectTest06, 1); - UtRegisterTest("AppLayerProtoDetectTest07", AppLayerProtoDetectTest07, 1); - UtRegisterTest("AppLayerProtoDetectTest08", AppLayerProtoDetectTest08, 1); - UtRegisterTest("AppLayerProtoDetectTest09", AppLayerProtoDetectTest09, 1); - UtRegisterTest("AppLayerProtoDetectTest10", AppLayerProtoDetectTest10, 1); - UtRegisterTest("AppLayerProtoDetectTest11", AppLayerProtoDetectTest11, 1); - UtRegisterTest("AppLayerProtoDetectTest12", AppLayerProtoDetectTest12, 1); - UtRegisterTest("AppLayerProtoDetectTest13", AppLayerProtoDetectTest13, 1); - UtRegisterTest("AppLayerProtoDetectTest14", AppLayerProtoDetectTest14, 1); - UtRegisterTest("AppLayerProtoDetectTest15", AppLayerProtoDetectTest15, 1); - UtRegisterTest("AppLayerProtoDetectTest16", AppLayerProtoDetectTest16, 1); - UtRegisterTest("AppLayerProtoDetectTest17", AppLayerProtoDetectTest17, 1); - UtRegisterTest("AppLayerProtoDetectTest18", AppLayerProtoDetectTest18, 1); - UtRegisterTest("AppLayerProtoDetectTest19", AppLayerProtoDetectTest19, 1); - UtRegisterTest("AppLayerProtoDetectTest20", AppLayerProtoDetectTest20, 1); - - SCReturn; -} - -#endif /* UNITTESTS */ diff --git a/framework/src/suricata/src/app-layer-detect-proto.h b/framework/src/suricata/src/app-layer-detect-proto.h deleted file mode 100644 index 81b75fe3..00000000 --- a/framework/src/suricata/src/app-layer-detect-proto.h +++ /dev/null @@ -1,197 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#ifndef __APP_LAYER_DETECT_PROTO__H__ -#define __APP_LAYER_DETECT_PROTO__H__ - -typedef struct AppLayerProtoDetectThreadCtx_ AppLayerProtoDetectThreadCtx; - -typedef AppProto (*ProbingParserFPtr)(uint8_t *input, uint32_t input_len, - uint32_t *offset); - -/***** Protocol Retrieval *****/ - -/** - * \brief Returns the app layer protocol given a buffer. - * - * \param tctx Pointer to the app layer protocol detection thread context. - * \param f Pointer to the flow. - * \param buf The buffer to be inspected. - * \param buflen The length of the above buffer. - * \param ipproto The ip protocol. - * \param direction The direction bitfield - STREAM_TOSERVER/STREAM_TOCLIENT. - * - * \retval The app layer protocol. - */ -AppProto AppLayerProtoDetectGetProto(AppLayerProtoDetectThreadCtx *tctx, - Flow *f, - uint8_t *buf, uint32_t buflen, - uint8_t ipproto, uint8_t direction); - -/***** State Preparation *****/ - -/** - * \brief Prepares the internal state for protocol detection. - * This needs to be called once all the patterns and probing parser - * ports have been registered. - */ -int AppLayerProtoDetectPrepareState(void); - -/***** PP registration *****/ - -void AppLayerProtoDetectPPRegister(uint8_t ipproto, - char *portstr, - AppProto alproto, - uint16_t min_depth, uint16_t max_depth, - uint8_t direction, - ProbingParserFPtr ProbingParser); -/** - * \retval bool 0 if no config was found, 1 if config was found - */ -int AppLayerProtoDetectPPParseConfPorts(const char *ipproto_name, - uint8_t ipproto, - const char *alproto_name, - AppProto alproto, - uint16_t min_depth, uint16_t max_depth, - ProbingParserFPtr ProbingParser); - -/***** PM registration *****/ - -/** - * \brief Registers a case-sensitive pattern for protocol detection. - */ -int AppLayerProtoDetectPMRegisterPatternCS(uint8_t ipproto, AppProto alproto, - char *pattern, - uint16_t depth, uint16_t offset, - uint8_t direction); -/** - * \brief Registers a case-insensitive pattern for protocol detection. - */ -int AppLayerProtoDetectPMRegisterPatternCI(uint8_t ipproto, AppProto alproto, - char *pattern, - uint16_t depth, uint16_t offset, - uint8_t direction); - -/***** Setup/General Registration *****/ - -/** - * \brief The first function to be called. This initializes a global - * protocol detection context. - * - * \retval 0 On succcess; - * \retval -1 On failure. - */ -int AppLayerProtoDetectSetup(void); - -/** - * \brief Cleans up the app layer protocol detection phase. - */ -int AppLayerProtoDetectDeSetup(void); - -/** - * \brief Registers a protocol for protocol detection phase. - * - * This is the first function to be called after calling the - * setup function, AppLayerProtoDetectSetup(), before calling any other - * app layer functions, AppLayerParser or AppLayerProtoDetect, alike. - * With this function you are associating/registering a string - * that can be used by users to write rules, i.e. - * you register the http protocol for protocol detection using - * AppLayerProtoDetectRegisterProtocol(ctx, ALPROTO_HTTP, "http"), - * following which you can write rules like - - * alert http any any -> any any (sid:1;) - * which basically matches on the HTTP protocol. - * - * \param alproto The protocol. - * \param alproto_str The string to associate with the above "alproto". - * Please send a static string that won't be destroyed - * post making this call, since this function won't - * create a copy of the received argument. - * - * \retval 0 On success; - * -1 On failure. - */ -void AppLayerProtoDetectRegisterProtocol(AppProto alproto, char *alproto_name); - -/** - * \brief Given a protocol name, checks if proto detection is enabled in - * the conf file. - * - * \param alproto Name of the app layer protocol. - * - * \retval 1 If enabled. - * \retval 0 If disabled. - */ -int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, - const char *alproto); - -/** - * \brief Inits and returns an app layer protocol detection thread context. - - * \param ctx Pointer to the app layer protocol detection context. - * - * \retval Pointer to the thread context, on success; - * NULL, on failure. - */ -AppLayerProtoDetectThreadCtx *AppLayerProtoDetectGetCtxThread(void); - -/** - * \brief Destroys the app layer protocol detection thread context. - * - * \param tctx Pointer to the app layer protocol detection thread context. - */ -void AppLayerProtoDetectDestroyCtxThread(AppLayerProtoDetectThreadCtx *tctx); - -/***** Utility *****/ - -void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos); -AppProto AppLayerProtoDetectGetProtoByName(char *alproto_name); -char *AppLayerProtoDetectGetProtoName(AppProto alproto); -void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos); - -/***** Unittests *****/ - -#ifdef UNITTESTS - -/** - * \brief Backs up the internal context used by the app layer proto detection - * module. - */ -void AppLayerProtoDetectUnittestCtxBackup(void); - -/** - * \brief Restores back the internal context used by the app layer proto - * detection module, that was previously backed up by calling - * AppLayerProtoDetectUnittestCtxBackup(). - */ -void AppLayerProtoDetectUnittestCtxRestore(void); - -/** - * \brief Register unittests for app layer proto detection module. - */ -void AppLayerProtoDetectUnittestsRegister(void); - -#endif /* UNITTESTS */ - -#endif /* __APP_LAYER_DETECT_PROTO__H__ */ diff --git a/framework/src/suricata/src/app-layer-dns-common.c b/framework/src/suricata/src/app-layer-dns-common.c deleted file mode 100644 index 3c67fe44..00000000 --- a/framework/src/suricata/src/app-layer-dns-common.c +++ /dev/null @@ -1,1141 +0,0 @@ -/* Copyright (C) 2013-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "stream.h" -#include "app-layer-parser.h" -#include "app-layer-dns-common.h" -#ifdef DEBUG -#include "util-print.h" -#endif -#include "util-memcmp.h" -#include "util-atomic.h" - -typedef struct DNSConfig_ { - uint32_t request_flood; - uint32_t state_memcap; /**< memcap in bytes per state */ - uint64_t global_memcap; /**< memcap in bytes globally for parser */ -} DNSConfig; -static DNSConfig dns_config; - -void DNSConfigInit(void) -{ - memset(&dns_config, 0x00, sizeof(dns_config)); -} - -void DNSConfigSetRequestFlood(uint32_t value) -{ - dns_config.request_flood = value; -} - -void DNSConfigSetStateMemcap(uint32_t value) -{ - dns_config.state_memcap = value; -} - -SC_ATOMIC_DECLARE(uint64_t, dns_memuse); /**< byte counter of current memuse */ -SC_ATOMIC_DECLARE(uint64_t, dns_memcap_state); /**< counts number of 'rejects' */ -SC_ATOMIC_DECLARE(uint64_t, dns_memcap_global); /**< counts number of 'rejects' */ - -void DNSConfigSetGlobalMemcap(uint64_t value) -{ - dns_config.global_memcap = value; - - SC_ATOMIC_INIT(dns_memuse); - SC_ATOMIC_INIT(dns_memcap_state); - SC_ATOMIC_INIT(dns_memcap_global); -} - -void DNSIncrMemcap(uint32_t size, DNSState *state) -{ - if (state != NULL) { - state->memuse += size; - } - SC_ATOMIC_ADD(dns_memuse, size); -} - -void DNSDecrMemcap(uint32_t size, DNSState *state) -{ - if (state != NULL) { - BUG_ON(size > state->memuse); /**< TODO remove later */ - state->memuse -= size; - } - - BUG_ON(size > SC_ATOMIC_GET(dns_memuse)); /**< TODO remove later */ - (void)SC_ATOMIC_SUB(dns_memuse, size); -} - -int DNSCheckMemcap(uint32_t want, DNSState *state) -{ - if (state != NULL) { - if (state->memuse + want > dns_config.state_memcap) { - SC_ATOMIC_ADD(dns_memcap_state, 1); - DNSSetEvent(state, DNS_DECODER_EVENT_STATE_MEMCAP_REACHED); - return -1; - } - } - - if (SC_ATOMIC_GET(dns_memuse) + (uint64_t)want > dns_config.global_memcap) { - SC_ATOMIC_ADD(dns_memcap_global, 1); - return -2; - } - - return 0; -} - -uint64_t DNSMemcapGetMemuseCounter(void) -{ - uint64_t x = SC_ATOMIC_GET(dns_memuse); - return x; -} - -uint64_t DNSMemcapGetMemcapStateCounter(void) -{ - uint64_t x = SC_ATOMIC_GET(dns_memcap_state); - return x; -} - -uint64_t DNSMemcapGetMemcapGlobalCounter(void) -{ - uint64_t x = SC_ATOMIC_GET(dns_memcap_global); - return x; -} - -SCEnumCharMap dns_decoder_event_table[ ] = { - { "UNSOLLICITED_RESPONSE", DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE, }, - { "MALFORMED_DATA", DNS_DECODER_EVENT_MALFORMED_DATA, }, - { "NOT_A_REQUEST", DNS_DECODER_EVENT_NOT_A_REQUEST, }, - { "NOT_A_RESPONSE", DNS_DECODER_EVENT_NOT_A_RESPONSE, }, - { "Z_FLAG_SET", DNS_DECODER_EVENT_Z_FLAG_SET, }, - { "FLOODED", DNS_DECODER_EVENT_FLOODED, }, - { "STATE_MEMCAP_REACHED", DNS_DECODER_EVENT_STATE_MEMCAP_REACHED, }, - - { NULL, -1 }, -}; - -int DNSStateGetEventInfo(const char *event_name, - int *event_id, AppLayerEventType *event_type) -{ - *event_id = SCMapEnumNameToValue(event_name, dns_decoder_event_table); - if (*event_id == -1) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " - "dns's enum map table.", event_name); - /* this should be treated as fatal */ - return -1; - } - - *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; - - return 0; -} - -void DNSAppLayerRegisterGetEventInfo(uint8_t ipproto, AppProto alproto) -{ - AppLayerParserRegisterGetEventInfo(ipproto, alproto, DNSStateGetEventInfo); - - return; -} - -AppLayerDecoderEvents *DNSGetEvents(void *state, uint64_t id) -{ - DNSState *dns_state = (DNSState *)state; - DNSTransaction *tx; - - if (dns_state->curr && dns_state->curr->tx_num == (id + 1)) { - return dns_state->curr->decoder_events; - } - - TAILQ_FOREACH(tx, &dns_state->tx_list, next) { - if (tx->tx_num == (id+1)) - return tx->decoder_events; - } - return NULL; -} - -int DNSHasEvents(void *state) -{ - DNSState *dns_state = (DNSState *)state; - return (dns_state->events > 0); -} - -void *DNSGetTx(void *alstate, uint64_t tx_id) -{ - DNSState *dns_state = (DNSState *)alstate; - DNSTransaction *tx = NULL; - - /* fast track: try the current tx */ - if (dns_state->curr && dns_state->curr->tx_num == tx_id + 1) - return dns_state->curr; - - /* fast track: - * if the prev tx_id is equal to the stored tx ptr, we can - * use this shortcut to get to the next. */ - if (dns_state->iter) { - if (tx_id == dns_state->iter->tx_num) { - tx = TAILQ_NEXT(dns_state->iter, next); - if (tx && tx->tx_num == tx_id + 1) { - dns_state->iter = tx; - return tx; - } - } - } - - /* no luck with the fast tracks, do the full list walk */ - TAILQ_FOREACH(tx, &dns_state->tx_list, next) { - SCLogDebug("tx->tx_num %u, tx_id %"PRIu64, tx->tx_num, (tx_id+1)); - if ((tx_id+1) != tx->tx_num) - continue; - - SCLogDebug("returning tx %p", tx); - dns_state->iter = tx; - return tx; - } - - return NULL; -} - -uint64_t DNSGetTxCnt(void *alstate) -{ - DNSState *dns_state = (DNSState *)alstate; - return (uint64_t)dns_state->transaction_max; -} - -int DNSGetAlstateProgress(void *tx, uint8_t direction) -{ - DNSTransaction *dns_tx = (DNSTransaction *)tx; - if (direction & STREAM_TOCLIENT) { - /* response side of the tx is done if we parsed a reply - * or if we tagged this tx as 'reply lost'. */ - return (dns_tx->replied|dns_tx->reply_lost) ? 1 : 0; - } - else { - /* tx is only created if we have a complete request, - * or if we lost the request. Either way, if we have - * a tx it we consider the request complete. */ - return 1; - } -} - -/** \brief get value for 'complete' status in DNS - * - * For DNS we use a simple bool. 1 means done. - */ -int DNSGetAlstateProgressCompletionStatus(uint8_t direction) -{ - return 1; -} - -void DNSSetEvent(DNSState *s, uint8_t e) -{ - if (s && s->curr) { - SCLogDebug("s->curr->decoder_events %p", s->curr->decoder_events); - AppLayerDecoderEventsSetEventRaw(&s->curr->decoder_events, e); - SCLogDebug("s->curr->decoder_events %p", s->curr->decoder_events); - s->events++; - } else { - SCLogDebug("couldn't set event %u", e); - } -} - -/** \internal - * \brief Allocate a DNS TX - * \retval tx or NULL */ -static DNSTransaction *DNSTransactionAlloc(DNSState *state, const uint16_t tx_id) -{ - if (DNSCheckMemcap(sizeof(DNSTransaction), state) < 0) - return NULL; - - DNSTransaction *tx = SCMalloc(sizeof(DNSTransaction)); - if (unlikely(tx == NULL)) - return NULL; - DNSIncrMemcap(sizeof(DNSTransaction), state); - - memset(tx, 0x00, sizeof(DNSTransaction)); - - TAILQ_INIT(&tx->query_list); - TAILQ_INIT(&tx->answer_list); - TAILQ_INIT(&tx->authority_list); - - tx->tx_id = tx_id; - return tx; -} - -/** \internal - * \brief Free a DNS TX - * \param tx DNS TX to free */ -static void DNSTransactionFree(DNSTransaction *tx, DNSState *state) -{ - SCEnter(); - - DNSQueryEntry *q = NULL; - while ((q = TAILQ_FIRST(&tx->query_list))) { - TAILQ_REMOVE(&tx->query_list, q, next); - DNSDecrMemcap((sizeof(DNSQueryEntry) + q->len), state); - SCFree(q); - } - - DNSAnswerEntry *a = NULL; - while ((a = TAILQ_FIRST(&tx->answer_list))) { - TAILQ_REMOVE(&tx->answer_list, a, next); - DNSDecrMemcap((sizeof(DNSAnswerEntry) + a->fqdn_len + a->data_len), state); - SCFree(a); - } - while ((a = TAILQ_FIRST(&tx->authority_list))) { - TAILQ_REMOVE(&tx->authority_list, a, next); - DNSDecrMemcap((sizeof(DNSAnswerEntry) + a->fqdn_len + a->data_len), state); - SCFree(a); - } - - AppLayerDecoderEventsFreeEvents(&tx->decoder_events); - - if (tx->de_state != NULL) { - DetectEngineStateFree(tx->de_state); - BUG_ON(state->tx_with_detect_state_cnt == 0); - state->tx_with_detect_state_cnt--; - } - - if (state->iter == tx) - state->iter = NULL; - - DNSDecrMemcap(sizeof(DNSTransaction), state); - SCFree(tx); - SCReturn; -} - -/** - * \brief dns transaction cleanup callback - */ -void DNSStateTransactionFree(void *state, uint64_t tx_id) -{ - SCEnter(); - - DNSState *dns_state = state; - DNSTransaction *tx = NULL; - - SCLogDebug("state %p, id %"PRIu64, dns_state, tx_id); - - TAILQ_FOREACH(tx, &dns_state->tx_list, next) { - SCLogDebug("tx %p tx->tx_num %u, tx_id %"PRIu64, tx, tx->tx_num, (tx_id+1)); - if ((tx_id+1) < tx->tx_num) - break; - else if ((tx_id+1) > tx->tx_num) - continue; - - if (tx == dns_state->curr) - dns_state->curr = NULL; - - if (tx->decoder_events != NULL) { - if (tx->decoder_events->cnt <= dns_state->events) - dns_state->events -= tx->decoder_events->cnt; - else - dns_state->events = 0; - } - - TAILQ_REMOVE(&dns_state->tx_list, tx, next); - DNSTransactionFree(tx, state); - break; - } - SCReturn; -} - -/** \internal - * \brief Find the DNS Tx in the state - * \param tx_id id of the tx - * \retval tx or NULL if not found */ -DNSTransaction *DNSTransactionFindByTxId(const DNSState *dns_state, const uint16_t tx_id) -{ - if (dns_state->curr == NULL) - return NULL; - - /* fast path */ - if (dns_state->curr->tx_id == tx_id) { - return dns_state->curr; - - /* slow path, iterate list */ - } else { - DNSTransaction *tx = NULL; - TAILQ_FOREACH(tx, &dns_state->tx_list, next) { - if (tx->tx_id == tx_id) { - return tx; - } - } - } - /* not found */ - return NULL; -} - -int DNSStateHasTxDetectState(void *alstate) -{ - DNSState *state = (DNSState *)alstate; - return (state->tx_with_detect_state_cnt > 0); -} - -DetectEngineState *DNSGetTxDetectState(void *vtx) -{ - DNSTransaction *tx = (DNSTransaction *)vtx; - return tx->de_state; -} - -int DNSSetTxDetectState(void *alstate, void *vtx, DetectEngineState *s) -{ - DNSState *state = (DNSState *)alstate; - DNSTransaction *tx = (DNSTransaction *)vtx; - state->tx_with_detect_state_cnt++; - tx->de_state = s; - return 0; -} - -void *DNSStateAlloc(void) -{ - void *s = SCMalloc(sizeof(DNSState)); - if (unlikely(s == NULL)) - return NULL; - - memset(s, 0, sizeof(DNSState)); - - DNSState *dns_state = (DNSState *)s; - - DNSIncrMemcap(sizeof(DNSState), dns_state); - - TAILQ_INIT(&dns_state->tx_list); - return s; -} - -void DNSStateFree(void *s) -{ - SCEnter(); - if (s) { - DNSState *dns_state = (DNSState *) s; - - DNSTransaction *tx = NULL; - while ((tx = TAILQ_FIRST(&dns_state->tx_list))) { - TAILQ_REMOVE(&dns_state->tx_list, tx, next); - DNSTransactionFree(tx, dns_state); - } - - if (dns_state->buffer != NULL) { - DNSDecrMemcap(0xffff, dns_state); /** TODO update if/once we alloc - * in a smarter way */ - SCFree(dns_state->buffer); - } - - BUG_ON(dns_state->tx_with_detect_state_cnt > 0); - - DNSDecrMemcap(sizeof(DNSState), dns_state); - BUG_ON(dns_state->memuse > 0); - SCFree(s); - } - SCReturn; -} - -/** \brief Validation checks for DNS request header - * - * Will set decoder events if anomalies are found. - * - * \retval 0 ok - * \retval -1 error - */ -int DNSValidateRequestHeader(DNSState *dns_state, const DNSHeader *dns_header) -{ - uint16_t flags = ntohs(dns_header->flags); - - if ((flags & 0x8000) != 0) { - SCLogDebug("not a request 0x%04x", flags); - DNSSetEvent(dns_state, DNS_DECODER_EVENT_NOT_A_REQUEST); - goto bad_data; - } - - if ((flags & 0x0040) != 0) { - SCLogDebug("Z flag not 0, 0x%04x", flags); - DNSSetEvent(dns_state, DNS_DECODER_EVENT_Z_FLAG_SET); - goto bad_data; - } - - return 0; -bad_data: - return -1; -} - -/** \brief Validation checks for DNS response header - * - * Will set decoder events if anomalies are found. - * - * \retval 0 ok - * \retval -1 error - */ -int DNSValidateResponseHeader(DNSState *dns_state, const DNSHeader *dns_header) -{ - uint16_t flags = ntohs(dns_header->flags); - - if ((flags & 0x8000) == 0) { - SCLogDebug("not a response 0x%04x", flags); - DNSSetEvent(dns_state, DNS_DECODER_EVENT_NOT_A_RESPONSE); - goto bad_data; - } - - if ((flags & 0x0040) != 0) { - SCLogDebug("Z flag not 0, 0x%04x", flags); - DNSSetEvent(dns_state, DNS_DECODER_EVENT_Z_FLAG_SET); - goto bad_data; - } - - return 0; -bad_data: - return -1; -} - -/** \internal - * \brief check the query list to see if we already have this exact query - * \retval bool true or false - */ -static int QueryIsDuplicate(DNSTransaction *tx, const uint8_t *fqdn, const uint16_t fqdn_len, - const uint16_t type, const uint16_t class) -{ - DNSQueryEntry *q = NULL; - - TAILQ_FOREACH(q, &tx->query_list, next) { - uint8_t *qfqdn = (uint8_t *)q + sizeof(DNSQueryEntry); - - if (q->len == fqdn_len && q->type == type && - q->class == class && - SCMemcmp(qfqdn, fqdn, fqdn_len) == 0) { - return TRUE; - } - } - return FALSE; -} - -void DNSStoreQueryInState(DNSState *dns_state, const uint8_t *fqdn, const uint16_t fqdn_len, - const uint16_t type, const uint16_t class, const uint16_t tx_id) -{ - /* flood protection */ - if (dns_state->givenup) - return; - - /* find the tx and see if this is an exact duplicate */ - DNSTransaction *tx = DNSTransactionFindByTxId(dns_state, tx_id); - if ((tx != NULL) && (QueryIsDuplicate(tx, fqdn, fqdn_len, type, class) == TRUE)) { - SCLogDebug("query is duplicate"); - return; - } - - /* see if the last tx is unreplied */ - if (dns_state->curr != tx && dns_state->curr != NULL && - dns_state->curr->replied == 0) - { - dns_state->curr->reply_lost = 1; - dns_state->unreplied_cnt++; - - /* check flood limit */ - if (dns_config.request_flood != 0 && - dns_state->unreplied_cnt > dns_config.request_flood) { - DNSSetEvent(dns_state, DNS_DECODER_EVENT_FLOODED); - dns_state->givenup = 1; - } - } - - if (tx == NULL) { - tx = DNSTransactionAlloc(dns_state, tx_id); - if (tx == NULL) - return; - dns_state->transaction_max++; - SCLogDebug("dns_state->transaction_max updated to %"PRIu64, dns_state->transaction_max); - TAILQ_INSERT_TAIL(&dns_state->tx_list, tx, next); - dns_state->curr = tx; - tx->tx_num = dns_state->transaction_max; - SCLogDebug("new tx %u with internal id %u", tx->tx_id, tx->tx_num); - } - - if (DNSCheckMemcap((sizeof(DNSQueryEntry) + fqdn_len), dns_state) < 0) - return; - DNSQueryEntry *q = SCMalloc(sizeof(DNSQueryEntry) + fqdn_len); - if (unlikely(q == NULL)) - return; - DNSIncrMemcap((sizeof(DNSQueryEntry) + fqdn_len), dns_state); - - q->type = type; - q->class = class; - q->len = fqdn_len; - memcpy((uint8_t *)q + sizeof(DNSQueryEntry), fqdn, fqdn_len); - - TAILQ_INSERT_TAIL(&tx->query_list, q, next); - - SCLogDebug("Query for TX %04x stored", tx_id); -} - -void DNSStoreAnswerInState(DNSState *dns_state, const int rtype, const uint8_t *fqdn, - const uint16_t fqdn_len, const uint16_t type, const uint16_t class, const uint16_t ttl, - const uint8_t *data, const uint16_t data_len, const uint16_t tx_id) -{ - DNSTransaction *tx = DNSTransactionFindByTxId(dns_state, tx_id); - if (tx == NULL) { - tx = DNSTransactionAlloc(dns_state, tx_id); - if (tx == NULL) - return; - TAILQ_INSERT_TAIL(&dns_state->tx_list, tx, next); - dns_state->curr = tx; - tx->tx_num = dns_state->transaction_max; - } - - if (DNSCheckMemcap((sizeof(DNSAnswerEntry) + fqdn_len + data_len), dns_state) < 0) - return; - DNSAnswerEntry *q = SCMalloc(sizeof(DNSAnswerEntry) + fqdn_len + data_len); - if (unlikely(q == NULL)) - return; - DNSIncrMemcap((sizeof(DNSAnswerEntry) + fqdn_len + data_len), dns_state); - - q->type = type; - q->class = class; - q->ttl = ttl; - q->fqdn_len = fqdn_len; - q->data_len = data_len; - - uint8_t *ptr = (uint8_t *)q + sizeof(DNSAnswerEntry); - if (fqdn != NULL && fqdn_len > 0) { - memcpy(ptr, fqdn, fqdn_len); - ptr += fqdn_len; - } - if (data != NULL && data_len > 0) { - memcpy(ptr, data, data_len); - } - - if (rtype == DNS_LIST_ANSWER) - TAILQ_INSERT_TAIL(&tx->answer_list, q, next); - else if (rtype == DNS_LIST_AUTHORITY) - TAILQ_INSERT_TAIL(&tx->authority_list, q, next); - else - BUG_ON(1); - - SCLogDebug("Answer for TX %04x stored", tx_id); - - /* mark tx is as replied so we can log it */ - tx->replied = 1; - - /* reset unreplied counter */ - dns_state->unreplied_cnt = 0; -} - -/** \internal - * \brief get domain name from dns packet - * - * In case of compressed name storage this function follows the ptrs to - * create the full domain name. - * - * The length bytes are converted into dots, e.g. |03|com|00| becomes - * .com - * The trailing . is not stored. - * - * \param input input buffer (complete dns record) - * \param input_len lenght of input buffer - * \param offset offset into @input where dns name starts - * \param fqdn buffer to store result - * \param fqdn_size size of @fqdn buffer - * \retval 0 on error/no buffer - * \retval size size of fqdn - */ -static uint16_t DNSResponseGetNameByOffset(const uint8_t * const input, const uint32_t input_len, - const uint16_t offset, uint8_t *fqdn, const size_t fqdn_size) -{ - if (input + input_len < input + offset + 1) { - SCLogDebug("input buffer too small for domain of len %u", offset); - goto insufficient_data; - } - - int steps = 0; - uint16_t fqdn_offset = 0; - uint8_t length = *(input + offset); - const uint8_t *qdata = input + offset; - SCLogDebug("qry length %u", length); - - if (length == 0) { - memcpy(fqdn, "", 6); - SCReturnUInt(6U); - } - - while (length != 0) { - int cnt = 0; - while (length & 0xc0) { - uint16_t offset = ((length & 0x3f) << 8) + *(qdata+1); - qdata = (const uint8_t *)input + offset; - - if (input + input_len < qdata + 1) { - SCLogDebug("input buffer too small"); - goto insufficient_data; - } - - length = *qdata; - SCLogDebug("qry length %u", length); - - if (cnt++ == 100) { - SCLogDebug("too many pointer iterations, loop?"); - goto bad_data; - } - } - qdata++; - - if (length == 0) { - break; - } - - if (input + input_len < qdata + length) { - SCLogDebug("input buffer too small for domain of len %u", length); - goto insufficient_data; - } - //PrintRawDataFp(stdout, qdata, length); - - if ((size_t)(fqdn_offset + length + 1) < fqdn_size) { - memcpy(fqdn + fqdn_offset, qdata, length); - fqdn_offset += length; - fqdn[fqdn_offset++] = '.'; - } - qdata += length; - - if (input + input_len < qdata + 1) { - SCLogDebug("input buffer too small for len field"); - goto insufficient_data; - } - - length = *qdata; - SCLogDebug("qry length %u", length); - steps++; - if (steps >= 255) - goto bad_data; - } - if (fqdn_offset) { - fqdn_offset--; - } - //PrintRawDataFp(stdout, fqdn, fqdn_offset); - SCReturnUInt(fqdn_offset); -bad_data: -insufficient_data: - SCReturnUInt(0U); -} - -/** \internal - * \brief skip past domain name field - * - * Skip the domain at position data. We don't care about following compressed names - * as we only want to know when the next part of the buffer starts - * - * \param input input buffer (complete dns record) - * \param input_len lenght of input buffer - * \param data current position - * - * \retval NULL on out of bounds data - * \retval sdata ptr to position in buffer past the name - */ -static const uint8_t *SkipDomain(const uint8_t * const input, - const uint32_t input_len, const uint8_t *data) -{ - const uint8_t *sdata = data; - while (*sdata != 0x00) { - if (*sdata & 0xc0) { - sdata++; - break; - } else { - sdata += ((*sdata) + 1); - } - if (input + input_len < sdata) { - SCLogDebug("input buffer too small for data of len"); - goto insufficient_data; - } - } - sdata++; - if (input + input_len < sdata) { - SCLogDebug("input buffer too small for data of len"); - goto insufficient_data; - } - return sdata; -insufficient_data: - return NULL; -} - -const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_header, - const uint16_t num, const DnsListEnum list, const uint8_t * const input, - const uint32_t input_len, const uint8_t *data) -{ - if (input + input_len < data + 2) { - SCLogDebug("input buffer too small for record 'name' field, record %u, " - "total answer_rr %u", num, ntohs(dns_header->answer_rr)); - goto insufficient_data; - } - - uint8_t fqdn[DNS_MAX_SIZE]; - uint16_t fqdn_len = 0; - - /* see if name is compressed */ - if (!(data[0] & 0xc0)) { - if ((fqdn_len = DNSResponseGetNameByOffset(input, input_len, - data - input, fqdn, sizeof(fqdn))) == 0) - { -#if DEBUG - PrintRawDataFp(stdout, (uint8_t *)input, input_len); - BUG_ON(1); -#endif - goto insufficient_data; - } - //PrintRawDataFp(stdout, fqdn, fqdn_len); - const uint8_t *tdata = SkipDomain(input, input_len, data); - if (tdata == NULL) { - goto insufficient_data; - } - data = tdata; - } else { - uint16_t offset = (data[0] & 0x3f) << 8 | data[1]; - - if ((fqdn_len = DNSResponseGetNameByOffset(input, input_len, - offset, fqdn, sizeof(fqdn))) == 0) - { -#if DEBUG - PrintRawDataFp(stdout, (uint8_t *)input, input_len); - BUG_ON(1); -#endif - goto insufficient_data; - } - //PrintRawDataFp(stdout, fqdn, fqdn_len); - data += 2; - } - - if (input + input_len < data + sizeof(DNSAnswerHeader)) { - SCLogDebug("input buffer too small for DNSAnswerHeader"); - goto insufficient_data; - } - - const DNSAnswerHeader *head = (DNSAnswerHeader *)data; - - data += sizeof(DNSAnswerHeader); - - SCLogDebug("head->len %u", ntohs(head->len)); - - if (input + input_len < data + ntohs(head->len)) { - SCLogDebug("input buffer too small for data of len %u", ntohs(head->len)); - goto insufficient_data; - } - - SCLogDebug("TTL %u", ntohl(head->ttl)); - - switch (ntohs(head->type)) { - case DNS_RECORD_TYPE_A: - { - if (ntohs(head->len) == 4) { - //PrintRawDataFp(stdout, data, ntohs(head->len)); - //char a[16]; - //PrintInet(AF_INET, (const void *)data, a, sizeof(a)); - //SCLogInfo("A %s TTL %u", a, ntohl(head->ttl)); - - DNSStoreAnswerInState(dns_state, list, fqdn, fqdn_len, - ntohs(head->type), ntohs(head->class), ntohl(head->ttl), - data, 4, ntohs(dns_header->tx_id)); - } else { - SCLogDebug("invalid length for A response data: %u", ntohs(head->len)); - goto bad_data; - } - - data += ntohs(head->len); - break; - } - case DNS_RECORD_TYPE_AAAA: - { - if (ntohs(head->len) == 16) { - //char a[46]; - //PrintInet(AF_INET6, (const void *)data, a, sizeof(a)); - //SCLogInfo("AAAA %s TTL %u", a, ntohl(head->ttl)); - - DNSStoreAnswerInState(dns_state, list, fqdn, fqdn_len, - ntohs(head->type), ntohs(head->class), ntohl(head->ttl), - data, 16, ntohs(dns_header->tx_id)); - } else { - SCLogDebug("invalid length for AAAA response data: %u", ntohs(head->len)); - goto bad_data; - } - - data += ntohs(head->len); - break; - } - case DNS_RECORD_TYPE_MX: - case DNS_RECORD_TYPE_CNAME: - case DNS_RECORD_TYPE_PTR: - { - uint8_t name[DNS_MAX_SIZE]; - uint16_t name_len = 0; - uint8_t skip = 0; - - if (ntohs(head->type) == DNS_RECORD_TYPE_MX) { - // Skip the preference header - skip = 2; - } - - if ((name_len = DNSResponseGetNameByOffset(input, input_len, - data - input + skip, name, sizeof(name))) == 0) { -#if DEBUG - PrintRawDataFp(stdout, (uint8_t *)input, input_len); - BUG_ON(1); -#endif - goto insufficient_data; - } - - DNSStoreAnswerInState(dns_state, list, fqdn, fqdn_len, - ntohs(head->type), ntohs(head->class), ntohl(head->ttl), - name, name_len, ntohs(dns_header->tx_id)); - - data += ntohs(head->len); - break; - } - case DNS_RECORD_TYPE_NS: - case DNS_RECORD_TYPE_SOA: - { - uint8_t pname[DNS_MAX_SIZE]; - uint16_t pname_len = 0; - - if ((pname_len = DNSResponseGetNameByOffset(input, input_len, - data - input, pname, sizeof(pname))) == 0) - { -#if DEBUG - PrintRawDataFp(stdout, (uint8_t *)input, input_len); - BUG_ON(1); -#endif - goto insufficient_data; - } - - if (ntohs(head->type) == DNS_RECORD_TYPE_SOA) { - const uint8_t *sdata = SkipDomain(input, input_len, data); - if (sdata == NULL) { - goto insufficient_data; - } - - uint8_t pmail[DNS_MAX_SIZE]; - uint16_t pmail_len = 0; - SCLogDebug("getting pmail"); - if ((pmail_len = DNSResponseGetNameByOffset(input, input_len, - sdata - input, pmail, sizeof(pmail))) == 0) - { -#if DEBUG - PrintRawDataFp(stdout, (uint8_t *)input, input_len); - BUG_ON(1); -#endif - goto insufficient_data; - } - SCLogDebug("pmail_len %u", pmail_len); - //PrintRawDataFp(stdout, (uint8_t *)pmail, pmail_len); - - const uint8_t *tdata = SkipDomain(input, input_len, sdata); - if (tdata == NULL) { - goto insufficient_data; - } -#if DEBUG - struct Trailer { - uint32_t serial; - uint32_t refresh; - uint32_t retry; - uint32_t experiation; - uint32_t minttl; - } *tail = (struct Trailer *)tdata; - - if (input + input_len < tdata + sizeof(struct Trailer)) { - SCLogDebug("input buffer too small for data of len"); - goto insufficient_data; - } - - SCLogDebug("serial %u refresh %u retry %u exp %u min ttl %u", - ntohl(tail->serial), ntohl(tail->refresh), - ntohl(tail->retry), ntohl(tail->experiation), - ntohl(tail->minttl)); -#endif - } - - DNSStoreAnswerInState(dns_state, list, fqdn, fqdn_len, - ntohs(head->type), ntohs(head->class), ntohl(head->ttl), - pname, pname_len, ntohs(dns_header->tx_id)); - - data += ntohs(head->len); - break; - } - case DNS_RECORD_TYPE_TXT: - { - uint16_t datalen = ntohs(head->len); - uint8_t txtlen = *data; - const uint8_t *tdata = data + 1; - - do { - //PrintRawDataFp(stdout, (uint8_t*)tdata, txtlen); - - if (txtlen >= datalen) - goto bad_data; - - DNSStoreAnswerInState(dns_state, list, fqdn, fqdn_len, - ntohs(head->type), ntohs(head->class), ntohl(head->ttl), - (uint8_t*)tdata, (uint16_t)txtlen, ntohs(dns_header->tx_id)); - - datalen -= txtlen; - tdata += txtlen; - txtlen = *tdata; - - tdata++; - datalen--; - - SCLogDebug("datalen %u, txtlen %u", datalen, txtlen); - } while (datalen > 1); - - data += ntohs(head->len); - break; - } - default: /* unsupported record */ - { - DNSStoreAnswerInState(dns_state, list, NULL, 0, - ntohs(head->type), ntohs(head->class), ntohl(head->ttl), - NULL, 0, ntohs(dns_header->tx_id)); - - //PrintRawDataFp(stdout, data, ntohs(head->len)); - data += ntohs(head->len); - break; - } - } - return data; -bad_data: -insufficient_data: - return NULL; -} - -void DNSCreateTypeString(uint16_t type, char *str, size_t str_size) -{ - switch (type) { - case DNS_RECORD_TYPE_A: - snprintf(str, str_size, "A"); - break; - case DNS_RECORD_TYPE_NS: - snprintf(str, str_size, "NS"); - break; - case DNS_RECORD_TYPE_AAAA: - snprintf(str, str_size, "AAAA"); - break; - case DNS_RECORD_TYPE_TXT: - snprintf(str, str_size, "TXT"); - break; - case DNS_RECORD_TYPE_CNAME: - snprintf(str, str_size, "CNAME"); - break; - case DNS_RECORD_TYPE_SOA: - snprintf(str, str_size, "SOA"); - break; - case DNS_RECORD_TYPE_MX: - snprintf(str, str_size, "MX"); - break; - case DNS_RECORD_TYPE_PTR: - snprintf(str, str_size, "PTR"); - break; - case DNS_RECORD_TYPE_ANY: - snprintf(str, str_size, "ANY"); - break; - case DNS_RECORD_TYPE_TKEY: - snprintf(str, str_size, "TKEY"); - break; - case DNS_RECORD_TYPE_TSIG: - snprintf(str, str_size, "TSIG"); - break; - case DNS_RECORD_TYPE_SRV: - snprintf(str, str_size, "SRV"); - break; - case DNS_RECORD_TYPE_NAPTR: - snprintf(str, str_size, "NAPTR"); - break; - case DNS_RECORD_TYPE_DS: - snprintf(str, str_size, "DS"); - break; - case DNS_RECORD_TYPE_RRSIG: - snprintf(str, str_size, "RRSIG"); - break; - case DNS_RECORD_TYPE_NSEC: - snprintf(str, str_size, "NSEC"); - break; - case DNS_RECORD_TYPE_NSEC3: - snprintf(str, str_size, "NSEC3"); - break; - default: - snprintf(str, str_size, "%04x/%u", type, type); - } -} - -void DNSCreateRcodeString(uint8_t rcode, char *str, size_t str_size) -{ - switch (rcode) { - case DNS_RCODE_NOERROR: - snprintf(str, str_size, "NOERROR"); - break; - case DNS_RCODE_FORMERR: - snprintf(str, str_size, "FORMERR"); - break; - case DNS_RCODE_SERVFAIL: - snprintf(str, str_size, "SERVFAIL"); - break; - case DNS_RCODE_NXDOMAIN: - snprintf(str, str_size, "NXDOMAIN"); - break; - case DNS_RCODE_NOTIMP: - snprintf(str, str_size, "NOTIMP"); - break; - case DNS_RCODE_REFUSED: - snprintf(str, str_size, "REFUSED"); - break; - case DNS_RCODE_YXDOMAIN: - snprintf(str, str_size, "YXDOMAIN"); - break; - case DNS_RCODE_YXRRSET: - snprintf(str, str_size, "YXRRSET"); - break; - case DNS_RCODE_NXRRSET: - snprintf(str, str_size, "NXRRSET"); - break; - case DNS_RCODE_NOTAUTH: - snprintf(str, str_size, "NOTAUTH"); - break; - case DNS_RCODE_NOTZONE: - snprintf(str, str_size, "NOTZONE"); - break; - /* these are the same, need more logic */ - case DNS_RCODE_BADVERS: - //case DNS_RCODE_BADSIG: - snprintf(str, str_size, "BADVERS/BADSIG"); - break; - case DNS_RCODE_BADKEY: - snprintf(str, str_size, "BADKEY"); - break; - case DNS_RCODE_BADTIME: - snprintf(str, str_size, "BADTIME"); - break; - case DNS_RCODE_BADMODE: - snprintf(str, str_size, "BADMODE"); - break; - case DNS_RCODE_BADNAME: - snprintf(str, str_size, "BADNAME"); - break; - case DNS_RCODE_BADALG: - snprintf(str, str_size, "BADALG"); - break; - case DNS_RCODE_BADTRUNC: - snprintf(str, str_size, "BADTRUNC"); - break; - default: - SCLogDebug("could not map DNS rcode to name, bug!"); - snprintf(str, str_size, "%04x/%u", rcode, rcode); - } -} diff --git a/framework/src/suricata/src/app-layer-dns-common.h b/framework/src/suricata/src/app-layer-dns-common.h deleted file mode 100644 index c1979526..00000000 --- a/framework/src/suricata/src/app-layer-dns-common.h +++ /dev/null @@ -1,259 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __APP_LAYER_DNS_COMMON_H__ -#define __APP_LAYER_DNS_COMMON_H__ - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "flow.h" -#include "queue.h" -#include "util-byte.h" - -#define DNS_MAX_SIZE 256 - -#define DNS_RECORD_TYPE_A 1 -#define DNS_RECORD_TYPE_NS 2 - -#define DNS_RECORD_TYPE_CNAME 5 -#define DNS_RECORD_TYPE_SOA 6 - -#define DNS_RECORD_TYPE_PTR 12 -#define DNS_RECORD_TYPE_MX 15 -#define DNS_RECORD_TYPE_TXT 16 - -#define DNS_RECORD_TYPE_AAAA 28 - -#define DNS_RECORD_TYPE_SRV 33 - -#define DNS_RECORD_TYPE_NAPTR 35 - -#define DNS_RECORD_TYPE_DS 43 - -#define DNS_RECORD_TYPE_RRSIG 46 -#define DNS_RECORD_TYPE_NSEC 47 - -#define DNS_RECORD_TYPE_NSEC3 50 - -#define DNS_RECORD_TYPE_TKEY 249 -#define DNS_RECORD_TYPE_TSIG 250 - -#define DNS_RECORD_TYPE_ANY 255 - -#define DNS_RCODE_NOERROR 0 -#define DNS_RCODE_FORMERR 1 -#define DNS_RCODE_SERVFAIL 2 -#define DNS_RCODE_NXDOMAIN 3 -#define DNS_RCODE_NOTIMP 4 -#define DNS_RCODE_REFUSED 5 -#define DNS_RCODE_YXDOMAIN 6 -#define DNS_RCODE_YXRRSET 7 -#define DNS_RCODE_NXRRSET 8 -#define DNS_RCODE_NOTAUTH 9 -#define DNS_RCODE_NOTZONE 10 -// Support for OPT RR from RFC6891 will be needed to -// parse RCODE values over 15 -#define DNS_RCODE_BADVERS 16 -#define DNS_RCODE_BADSIG 16 -#define DNS_RCODE_BADKEY 17 -#define DNS_RCODE_BADTIME 18 -#define DNS_RCODE_BADMODE 19 -#define DNS_RCODE_BADNAME 20 -#define DNS_RCODE_BADALG 21 -#define DNS_RCODE_BADTRUNC 22 - -enum { - DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE, - DNS_DECODER_EVENT_MALFORMED_DATA, - DNS_DECODER_EVENT_NOT_A_REQUEST, - DNS_DECODER_EVENT_NOT_A_RESPONSE, - DNS_DECODER_EVENT_Z_FLAG_SET, - DNS_DECODER_EVENT_FLOODED, - DNS_DECODER_EVENT_STATE_MEMCAP_REACHED, -}; - -/** \brief DNS packet header */ -typedef struct DNSHeader_ { - uint16_t tx_id; - uint16_t flags; - uint16_t questions; - uint16_t answer_rr; - uint16_t authority_rr; - uint16_t additional_rr; -} __attribute__((__packed__)) DNSHeader; - -typedef struct DNSQueryTrailer_ { - uint16_t type; - uint16_t class; -} __attribute__((__packed__)) DNSQueryTrailer; - -/** \brief DNS answer header - * packed as we don't want alignment to mess up sizeof() */ -struct DNSAnswerHeader_ { - uint16_t type; - uint16_t class; - uint32_t ttl; - uint16_t len; -} __attribute__((__packed__)); -typedef struct DNSAnswerHeader_ DNSAnswerHeader; - -/** \brief List types in the TX. - * Used when storing answers from "Answer" or "Authority" */ -typedef enum { - DNS_LIST_ANSWER = 0, - DNS_LIST_AUTHORITY, -} DnsListEnum; - -/** \brief DNS Query storage. Stored in TX list. - * - * Layout is: - * [list ptr][2 byte type][2 byte class][2 byte len][...data...] - */ -typedef struct DNSQueryEntry_ { - TAILQ_ENTRY(DNSQueryEntry_) next; - uint16_t type; - uint16_t class; - uint16_t len; -} DNSQueryEntry; - -/** \brief DNS Answer storage. Stored in TX list. - * - * Layout is: - * [list ptr][2 byte type][2 byte class][2 byte ttl] \ - * [2 byte fqdn len][2 byte data len][...fqdn...][...data...] - */ -typedef struct DNSAnswerEntry_ { - TAILQ_ENTRY(DNSAnswerEntry_) next; - - uint16_t type; - uint16_t class; - - uint32_t ttl; - - uint16_t fqdn_len; - uint16_t data_len; -} DNSAnswerEntry; - -/** \brief DNS Transaction, request/reply with same TX id. */ -typedef struct DNSTransaction_ { - uint16_t tx_num; /**< internal: id */ - uint16_t tx_id; /**< transaction id */ - uint8_t replied; /**< bool indicating request is - replied to. */ - uint8_t reply_lost; - uint8_t rcode; /**< response code (e.g. "no error" / "no such name") */ - uint8_t recursion_desired; /**< server said "recursion desired" */ - - TAILQ_HEAD(, DNSQueryEntry_) query_list; /**< list for query/queries */ - TAILQ_HEAD(, DNSAnswerEntry_) answer_list; /**< list for answers */ - TAILQ_HEAD(, DNSAnswerEntry_) authority_list; /**< list for authority records */ - - AppLayerDecoderEvents *decoder_events; /**< per tx events */ - - TAILQ_ENTRY(DNSTransaction_) next; - DetectEngineState *de_state; -} DNSTransaction; - -/** \brief Per flow DNS state container */ -typedef struct DNSState_ { - TAILQ_HEAD(, DNSTransaction_) tx_list; /**< transaction list */ - DNSTransaction *curr; /**< ptr to current tx */ - DNSTransaction *iter; - uint64_t transaction_max; - uint32_t unreplied_cnt; /**< number of unreplied requests in a row */ - uint32_t memuse; /**< state memuse, for comparing with - state-memcap settings */ - uint64_t tx_with_detect_state_cnt; - - uint16_t events; - uint16_t givenup; - - /* used by TCP only */ - uint16_t offset; - uint16_t record_len; - uint8_t *buffer; -} DNSState; - -#define DNS_CONFIG_DEFAULT_REQUEST_FLOOD 500 -#define DNS_CONFIG_DEFAULT_STATE_MEMCAP 512*1024 -#define DNS_CONFIG_DEFAULT_GLOBAL_MEMCAP 16*1024*1024 - -void DNSConfigInit(void); -void DNSConfigSetRequestFlood(uint32_t value); -void DNSConfigSetStateMemcap(uint32_t value); -void DNSConfigSetGlobalMemcap(uint64_t value); - -void DNSIncrMemcap(uint32_t size, DNSState *state); -void DNSDecrMemcap(uint32_t size, DNSState *state); -int DNSCheckMemcap(uint32_t want, DNSState *state); -uint64_t DNSMemcapGetMemuseCounter(void); -uint64_t DNSMemcapGetMemcapStateCounter(void); -uint64_t DNSMemcapGetMemcapGlobalCounter(void); - -void RegisterDNSParsers(void); -void DNSParserTests(void); -void DNSParserRegisterTests(void); -void DNSAppLayerDecoderEventsRegister(int alproto); -int DNSStateGetEventInfo(const char *event_name, - int *event_id, AppLayerEventType *event_type); -void DNSAppLayerRegisterGetEventInfo(uint8_t ipproto, AppProto alproto); - -void *DNSGetTx(void *alstate, uint64_t tx_id); -uint64_t DNSGetTxCnt(void *alstate); -int DNSGetAlstateProgress(void *tx, uint8_t direction); -int DNSGetAlstateProgressCompletionStatus(uint8_t direction); - -void DNSStateTransactionFree(void *state, uint64_t tx_id); -DNSTransaction *DNSTransactionFindByTxId(const DNSState *dns_state, const uint16_t tx_id); - -int DNSStateHasTxDetectState(void *alstate); -DetectEngineState *DNSGetTxDetectState(void *vtx); -int DNSSetTxDetectState(void *alstate, void *vtx, DetectEngineState *s); - -void DNSSetEvent(DNSState *s, uint8_t e); -void *DNSStateAlloc(void); -void DNSStateFree(void *s); -AppLayerDecoderEvents *DNSGetEvents(void *state, uint64_t id); -int DNSHasEvents(void *state); - -int DNSValidateRequestHeader(DNSState *, const DNSHeader *dns_header); -int DNSValidateResponseHeader(DNSState *, const DNSHeader *dns_header); - -void DNSStoreQueryInState(DNSState *dns_state, const uint8_t *fqdn, const uint16_t fqdn_len, - const uint16_t type, const uint16_t class, const uint16_t tx_id); - -void DNSStoreAnswerInState(DNSState *dns_state, const int rtype, const uint8_t *fqdn, - const uint16_t fqdn_len, const uint16_t type, const uint16_t class, const uint16_t ttl, - const uint8_t *data, const uint16_t data_len, const uint16_t tx_id); - -const uint8_t *DNSReponseParse(DNSState *dns_state, const DNSHeader * const dns_header, - const uint16_t num, const DnsListEnum list, const uint8_t * const input, - const uint32_t input_len, const uint8_t *data); - -uint16_t DNSUdpResponseGetNameByOffset(const uint8_t * const input, const uint32_t input_len, - const uint16_t offset, uint8_t *fqdn, const size_t fqdn_size); - -void DNSCreateTypeString(uint16_t type, char *str, size_t str_size); -void DNSCreateRcodeString(uint8_t rcode, char *str, size_t str_size); - -#endif /* __APP_LAYER_DNS_COMMON_H__ */ diff --git a/framework/src/suricata/src/app-layer-dns-tcp.c b/framework/src/suricata/src/app-layer-dns-tcp.c deleted file mode 100644 index f1cb597d..00000000 --- a/framework/src/suricata/src/app-layer-dns-tcp.c +++ /dev/null @@ -1,682 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "debug.h" -#include "decode.h" - -#include "flow-util.h" - -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-debug.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" - -#include "util-spm.h" -#include "util-unittest.h" - -#include "app-layer-dns-tcp.h" - -struct DNSTcpHeader_ { - uint16_t len; - uint16_t tx_id; - uint16_t flags; - uint16_t questions; - uint16_t answer_rr; - uint16_t authority_rr; - uint16_t additional_rr; -} __attribute__((__packed__)); -typedef struct DNSTcpHeader_ DNSTcpHeader; - -/** \internal - * \param input_len at least enough for the DNSTcpHeader - */ -static int DNSTCPRequestParseProbe(uint8_t *input, uint32_t input_len) -{ -#ifdef DEBUG - BUG_ON(input_len < sizeof(DNSTcpHeader)); -#endif - SCLogDebug("starting %u", input_len); - - DNSTcpHeader *dns_tcp_header = (DNSTcpHeader *)input; - if (ntohs(dns_tcp_header->len) < sizeof(DNSHeader)) { - goto bad_data; - } - if (ntohs(dns_tcp_header->len) >= input_len) { - goto insufficient_data; - } - - input += 2; - input_len -= 2; - DNSHeader *dns_header = (DNSHeader *)input; - - uint16_t q; - const uint8_t *data = input + sizeof(DNSHeader); - - for (q = 0; q < ntohs(dns_header->questions); q++) { - uint16_t fqdn_offset = 0; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for len field"); - goto insufficient_data; - } - SCLogDebug("query length %u", *data); - - while (*data != 0) { - if (*data > 63) { - /** \todo set event?*/ - goto bad_data; - } - uint8_t length = *data; - - data++; - - if (length > 0) { - if (input + input_len < data + length) { - SCLogDebug("input buffer too small for domain of len %u", length); - goto insufficient_data; - } - //PrintRawDataFp(stdout, data, qry->length); - - if ((fqdn_offset + length + 1) < DNS_MAX_SIZE) { - fqdn_offset += length; - } else { - /** \todo set event? */ - goto bad_data; - } - } - - data += length; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for new len"); - goto insufficient_data; - } - - SCLogDebug("qry length %u", *data); - } - if (fqdn_offset) { - fqdn_offset--; - } - - data++; - if (input + input_len < data + sizeof(DNSQueryTrailer)) { - SCLogDebug("input buffer too small for DNSQueryTrailer"); - goto insufficient_data; - } -#ifdef DEBUG - DNSQueryTrailer *trailer = (DNSQueryTrailer *)data; - SCLogDebug("trailer type %04x class %04x", ntohs(trailer->type), ntohs(trailer->class)); -#endif - data += sizeof(DNSQueryTrailer); - } - - SCReturnInt(1); -insufficient_data: - SCReturnInt(0); -bad_data: - SCReturnInt(-1); -} - -static int BufferData(DNSState *dns_state, uint8_t *data, uint16_t len) -{ - if (dns_state->buffer == NULL) { - if (DNSCheckMemcap(0xffff, dns_state) < 0) - return -1; - - /** \todo be smarter about this, like use a pool or several pools for - * chunks of various sizes */ - dns_state->buffer = SCMalloc(0xffff); - if (dns_state->buffer == NULL) { - return -1; - } - DNSIncrMemcap(0xffff, dns_state); - } - - if ((uint32_t)len + (uint32_t)dns_state->offset > (uint32_t)dns_state->record_len) { - SCLogDebug("oh my, we have more data than the max record size. What do we do. WHAT DO WE DOOOOO!"); -#ifdef DEBUG - BUG_ON(1); -#endif - len = dns_state->record_len - dns_state->offset; - } - - memcpy(dns_state->buffer + dns_state->offset, data, len); - dns_state->offset += len; - return 0; -} - -static void BufferReset(DNSState *dns_state) -{ - dns_state->record_len = 0; - dns_state->offset = 0; -} - -static int DNSRequestParseData(Flow *f, DNSState *dns_state, const uint8_t *input, const uint32_t input_len) -{ - DNSHeader *dns_header = (DNSHeader *)input; - - if (DNSValidateRequestHeader(dns_state, dns_header) < 0) - goto bad_data; - - //SCLogInfo("ID %04x", ntohs(dns_header->tx_id)); - - uint16_t q; - const uint8_t *data = input + sizeof(DNSHeader); - - //PrintRawDataFp(stdout, (uint8_t*)data, input_len - (data - input)); - - for (q = 0; q < ntohs(dns_header->questions); q++) { - uint8_t fqdn[DNS_MAX_SIZE]; - uint16_t fqdn_offset = 0; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for DNSTcpQuery"); - goto insufficient_data; - } - SCLogDebug("query length %u", *data); - - while (*data != 0) { - if (*data > 63) { - /** \todo set event?*/ - goto insufficient_data; - } - uint8_t length = *data; - - data++; - - if (length > 0) { - if (input + input_len < data + length) { - SCLogDebug("input buffer too small for domain of len %u", length); - goto insufficient_data; - } - //PrintRawDataFp(stdout, data, qry->length); - - if ((size_t)(fqdn_offset + length + 1) < sizeof(fqdn)) { - memcpy(fqdn + fqdn_offset, data, length); - fqdn_offset += length; - fqdn[fqdn_offset++] = '.'; - } else { - /** \todo set event? */ - goto insufficient_data; - } - } - - data += length; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for DNSTcpQuery(2)"); - goto insufficient_data; - } - - SCLogDebug("qry length %u", *data); - } - if (fqdn_offset) { - fqdn_offset--; - } - - data++; - if (input + input_len < data + sizeof(DNSQueryTrailer)) { - SCLogDebug("input buffer too small for DNSQueryTrailer"); - goto insufficient_data; - } - DNSQueryTrailer *trailer = (DNSQueryTrailer *)data; - SCLogDebug("trailer type %04x class %04x", ntohs(trailer->type), ntohs(trailer->class)); - data += sizeof(DNSQueryTrailer); - - /* store our data */ - if (dns_state != NULL) { - DNSStoreQueryInState(dns_state, fqdn, fqdn_offset, - ntohs(trailer->type), ntohs(trailer->class), - ntohs(dns_header->tx_id)); - } - } - - SCReturnInt(1); -bad_data: -insufficient_data: - SCReturnInt(-1); - -} - -/** \internal - * \brief Parse DNS request packet - */ -static int DNSTCPRequestParse(Flow *f, void *dstate, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - DNSState *dns_state = (DNSState *)dstate; - SCLogDebug("starting %u", input_len); - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } - - /** \todo remove this when PP is fixed to enforce ipproto */ - if (f != NULL && f->proto != IPPROTO_TCP) - SCReturnInt(-1); - - /* probably a rst/fin sending an eof */ - if (input == NULL || input_len == 0) { - goto insufficient_data; - } - -next_record: - /* if this is the beginning of a record, we need at least the header */ - if (dns_state->offset == 0 && input_len < sizeof(DNSTcpHeader)) { - SCLogDebug("ilen too small, hoped for at least %"PRIuMAX, (uintmax_t)sizeof(DNSTcpHeader)); - goto insufficient_data; - } - SCLogDebug("input_len %u offset %u record %u", - input_len, dns_state->offset, dns_state->record_len); - - /* this is the first data of this record */ - if (dns_state->offset == 0) { - DNSTcpHeader *dns_tcp_header = (DNSTcpHeader *)input; - SCLogDebug("DNS %p", dns_tcp_header); - - if (ntohs(dns_tcp_header->len) < sizeof(DNSHeader)) { - /* bogus len, doesn't fit even basic dns header */ - goto bad_data; - } else if (ntohs(dns_tcp_header->len) == (input_len-2)) { - /* we have all data, so process w/o buffering */ - if (DNSRequestParseData(f, dns_state, input+2, input_len-2) < 0) - goto bad_data; - - } else if ((input_len-2) > ntohs(dns_tcp_header->len)) { - /* we have all data, so process w/o buffering */ - if (DNSRequestParseData(f, dns_state, input+2, ntohs(dns_tcp_header->len)) < 0) - goto bad_data; - - /* treat the rest of the data as a (potential) new record */ - input += ntohs(dns_tcp_header->len); - input_len -= ntohs(dns_tcp_header->len); - goto next_record; - } else { - /* not enough data, store record length and buffer */ - dns_state->record_len = ntohs(dns_tcp_header->len); - BufferData(dns_state, input+2, input_len-2); - } - } else if (input_len + dns_state->offset < dns_state->record_len) { - /* we don't have the full record yet, buffer */ - BufferData(dns_state, input, input_len); - } else if (input_len > (uint32_t)(dns_state->record_len - dns_state->offset)) { - /* more data than expected, we may have another record coming up */ - uint16_t need = (dns_state->record_len - dns_state->offset); - BufferData(dns_state, input, need); - int r = DNSRequestParseData(f, dns_state, dns_state->buffer, dns_state->record_len); - BufferReset(dns_state); - if (r < 0) - goto bad_data; - - /* treat the rest of the data as a (potential) new record */ - input += need; - input_len -= need; - goto next_record; - } else { - /* implied exactly the amount of data we want - * add current to buffer, then inspect buffer */ - BufferData(dns_state, input, input_len); - int r = DNSRequestParseData(f, dns_state, dns_state->buffer, dns_state->record_len); - BufferReset(dns_state); - if (r < 0) - goto bad_data; - } - - SCReturnInt(1); -insufficient_data: - SCReturnInt(-1); -bad_data: - SCReturnInt(-1); -} - -static int DNSReponseParseData(Flow *f, DNSState *dns_state, const uint8_t *input, const uint32_t input_len) -{ - DNSHeader *dns_header = (DNSHeader *)input; - - if (DNSValidateResponseHeader(dns_state, dns_header) < 0) - goto bad_data; - - DNSTransaction *tx = NULL; - int found = 0; - if ((tx = DNSTransactionFindByTxId(dns_state, ntohs(dns_header->tx_id))) != NULL) - found = 1; - - if (!found) { - SCLogDebug("DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE"); - DNSSetEvent(dns_state, DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE); - } - - uint16_t q; - const uint8_t *data = input + sizeof(DNSHeader); - for (q = 0; q < ntohs(dns_header->questions); q++) { - uint8_t fqdn[DNS_MAX_SIZE]; - uint16_t fqdn_offset = 0; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for len field"); - goto insufficient_data; - } - SCLogDebug("qry length %u", *data); - - while (*data != 0) { - uint8_t length = *data; - data++; - - if (length > 0) { - if (input + input_len < data + length) { - SCLogDebug("input buffer too small for domain of len %u", length); - goto insufficient_data; - } - //PrintRawDataFp(stdout, data, length); - - if ((size_t)(fqdn_offset + length + 1) < sizeof(fqdn)) { - memcpy(fqdn + fqdn_offset, data, length); - fqdn_offset += length; - fqdn[fqdn_offset++] = '.'; - } - } - - data += length; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for len field"); - goto insufficient_data; - } - - SCLogDebug("length %u", *data); - } - if (fqdn_offset) { - fqdn_offset--; - } - - data++; - if (input + input_len < data + sizeof(DNSQueryTrailer)) { - SCLogDebug("input buffer too small for DNSQueryTrailer"); - goto insufficient_data; - } -#if DEBUG - DNSQueryTrailer *trailer = (DNSQueryTrailer *)data; - SCLogDebug("trailer type %04x class %04x", ntohs(trailer->type), ntohs(trailer->class)); -#endif - data += sizeof(DNSQueryTrailer); - } - - for (q = 0; q < ntohs(dns_header->answer_rr); q++) { - data = DNSReponseParse(dns_state, dns_header, q, DNS_LIST_ANSWER, - input, input_len, data); - if (data == NULL) { - goto insufficient_data; - } - } - - //PrintRawDataFp(stdout, (uint8_t *)data, input_len - (data - input)); - for (q = 0; q < ntohs(dns_header->authority_rr); q++) { - data = DNSReponseParse(dns_state, dns_header, q, DNS_LIST_AUTHORITY, - input, input_len, data); - if (data == NULL) { - goto insufficient_data; - } - } - - /* parse rcode, e.g. "noerror" or "nxdomain" */ - uint8_t rcode = ntohs(dns_header->flags) & 0x0F; - if (rcode <= DNS_RCODE_NOTZONE) { - SCLogDebug("rcode %u", rcode); - if (tx != NULL) - tx->rcode = rcode; - } else { - /* this is not invalid, rcodes can be user defined */ - SCLogDebug("unexpected DNS rcode %u", rcode); - } - - if (ntohs(dns_header->flags) & 0x0080) { - SCLogDebug("recursion desired"); - if (tx != NULL) - tx->recursion_desired = 1; - } - - if (tx != NULL) { - tx->replied = 1; - } - - SCReturnInt(1); -bad_data: -insufficient_data: - SCReturnInt(-1); -} - -/** \internal - * \brief DNS TCP record parser, entry function - * - * Parses a DNS TCP record and fills the DNS state - * - * As TCP records can be 64k we'll have to buffer the data. Streaming parsing - * would have been _very_ tricky due to the way names are compressed in DNS - * - */ -static int DNSTCPResponseParse(Flow *f, void *dstate, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - DNSState *dns_state = (DNSState *)dstate; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } - - /** \todo remove this when PP is fixed to enforce ipproto */ - if (f != NULL && f->proto != IPPROTO_TCP) - SCReturnInt(-1); - - /* probably a rst/fin sending an eof */ - if (input == NULL || input_len == 0) { - goto insufficient_data; - } - -next_record: - /* if this is the beginning of a record, we need at least the header */ - if (dns_state->offset == 0 && input_len < sizeof(DNSTcpHeader)) { - SCLogDebug("ilen too small, hoped for at least %"PRIuMAX, (uintmax_t)sizeof(DNSTcpHeader)); - goto insufficient_data; - } - SCLogDebug("input_len %u offset %u record %u", - input_len, dns_state->offset, dns_state->record_len); - - /* this is the first data of this record */ - if (dns_state->offset == 0) { - DNSTcpHeader *dns_tcp_header = (DNSTcpHeader *)input; - SCLogDebug("DNS %p", dns_tcp_header); - - if (ntohs(dns_tcp_header->len) == (input_len-2)) { - /* we have all data, so process w/o buffering */ - if (DNSReponseParseData(f, dns_state, input+2, input_len-2) < 0) - goto bad_data; - - } else if ((input_len-2) > ntohs(dns_tcp_header->len)) { - /* we have all data, so process w/o buffering */ - if (DNSReponseParseData(f, dns_state, input+2, ntohs(dns_tcp_header->len)) < 0) - goto bad_data; - - /* treat the rest of the data as a (potential) new record */ - input += ntohs(dns_tcp_header->len); - input_len -= ntohs(dns_tcp_header->len); - goto next_record; - } else { - /* not enough data, store record length and buffer */ - dns_state->record_len = ntohs(dns_tcp_header->len); - BufferData(dns_state, input+2, input_len-2); - } - } else if (input_len + dns_state->offset < dns_state->record_len) { - /* we don't have the full record yet, buffer */ - BufferData(dns_state, input, input_len); - } else if (input_len > (uint32_t)(dns_state->record_len - dns_state->offset)) { - /* more data than expected, we may have another record coming up */ - uint16_t need = (dns_state->record_len - dns_state->offset); - BufferData(dns_state, input, need); - int r = DNSReponseParseData(f, dns_state, dns_state->buffer, dns_state->record_len); - BufferReset(dns_state); - if (r < 0) - goto bad_data; - - /* treat the rest of the data as a (potential) new record */ - input += need; - input_len -= need; - goto next_record; - } else { - /* implied exactly the amount of data we want - * add current to buffer, then inspect buffer */ - BufferData(dns_state, input, input_len); - int r = DNSReponseParseData(f, dns_state, dns_state->buffer, dns_state->record_len); - BufferReset(dns_state); - if (r < 0) - goto bad_data; - } - SCReturnInt(1); -insufficient_data: - SCReturnInt(-1); -bad_data: - SCReturnInt(-1); -} - -static uint16_t DNSTcpProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset) -{ - if (ilen == 0 || ilen < sizeof(DNSTcpHeader)) { - SCLogDebug("ilen too small, hoped for at least %"PRIuMAX, (uintmax_t)sizeof(DNSTcpHeader)); - return ALPROTO_UNKNOWN; - } - - DNSTcpHeader *dns_header = (DNSTcpHeader *)input; - if (ntohs(dns_header->len) < sizeof(DNSHeader)) { - /* length field bogus, won't even fit a minimal DNS header. */ - return ALPROTO_FAILED; - } else if (ntohs(dns_header->len) > ilen) { - int r = DNSTCPRequestParseProbe(input, ilen); - if (r == -1) { - /* probing parser told us "bad data", so it's not - * DNS */ - return ALPROTO_FAILED; - } else if (ilen > 512) { - SCLogDebug("all the parser told us was not enough data, which is expected. Lets assume it's DNS"); - return ALPROTO_DNS; - } - - SCLogDebug("not yet enough info %u > %u", ntohs(dns_header->len), ilen); - return ALPROTO_UNKNOWN; - } - - int r = DNSTCPRequestParseProbe(input, ilen); - if (r != 1) - return ALPROTO_FAILED; - - SCLogDebug("ALPROTO_DNS"); - return ALPROTO_DNS; -} - -void RegisterDNSTCPParsers(void) -{ - char *proto_name = "dns"; - - /** DNS */ - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_DNS, proto_name); - - if (RunmodeIsUnittests()) { - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "53", - ALPROTO_DNS, - 0, sizeof(DNSTcpHeader), - STREAM_TOSERVER, - DNSTcpProbingParser); - } else { - int have_cfg = AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP, - proto_name, ALPROTO_DNS, - 0, sizeof(DNSTcpHeader), - DNSTcpProbingParser); - /* if we have no config, we enable the default port 53 */ - if (!have_cfg) { - SCLogWarning(SC_ERR_DNS_CONFIG, "no DNS TCP config found, " - "enabling DNS detection on " - "port 53."); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, "53", - ALPROTO_DNS, 0, sizeof(DNSTcpHeader), - STREAM_TOSERVER, DNSTcpProbingParser); - } - } - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - proto_name); - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_DNS, STREAM_TOSERVER, - DNSTCPRequestParse); - AppLayerParserRegisterParser(IPPROTO_TCP , ALPROTO_DNS, STREAM_TOCLIENT, - DNSTCPResponseParse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_DNS, DNSStateAlloc, - DNSStateFree); - AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_DNS, - DNSStateTransactionFree); - - AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_DNS, DNSGetEvents); - AppLayerParserRegisterHasEventsFunc(IPPROTO_TCP, ALPROTO_DNS, DNSHasEvents); - AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_DNS, - DNSStateHasTxDetectState, - DNSGetTxDetectState, DNSSetTxDetectState); - - AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DNS, DNSGetTx); - AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DNS, DNSGetTxCnt); - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_DNS, - DNSGetAlstateProgress); - AppLayerParserRegisterGetStateProgressCompletionStatus(IPPROTO_TCP, ALPROTO_DNS, - DNSGetAlstateProgressCompletionStatus); - DNSAppLayerRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_DNS); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } - - return; -} - -/* UNITTESTS */ -#ifdef UNITTESTS -void DNSTCPParserRegisterTests(void) -{ -// UtRegisterTest("DNSTCPParserTest01", DNSTCPParserTest01, 1); -} -#endif diff --git a/framework/src/suricata/src/app-layer-dns-tcp.h b/framework/src/suricata/src/app-layer-dns-tcp.h deleted file mode 100644 index 2f3b4ffc..00000000 --- a/framework/src/suricata/src/app-layer-dns-tcp.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * \author Victor Julien - */ - - -#ifndef __APP_LAYER_DNS_TCP_H__ -#define __APP_LAYER_DNS_TCP_H__ - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-dns-common.h" -#include "flow.h" -#include "queue.h" -#include "util-byte.h" - -void RegisterDNSTCPParsers(void); -void DNSTCPParserTests(void); -void DNSTCPParserRegisterTests(void); - -#endif /* __APP_LAYER_DNS_TCP_H__ */ diff --git a/framework/src/suricata/src/app-layer-dns-udp.c b/framework/src/suricata/src/app-layer-dns-udp.c deleted file mode 100644 index e3ee01ff..00000000 --- a/framework/src/suricata/src/app-layer-dns-udp.c +++ /dev/null @@ -1,635 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "conf.h" -#include "util-misc.h" - -#include "debug.h" -#include "decode.h" - -#include "flow-util.h" - -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-debug.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" - -#include "util-spm.h" -#include "util-unittest.h" - -#include "app-layer-dns-udp.h" - -/** \internal - * \brief Parse DNS request packet - */ -static int DNSUDPRequestParse(Flow *f, void *dstate, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - DNSState *dns_state = (DNSState *)dstate; - - SCLogDebug("starting %u", input_len); - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } - - /** \todo remove this when PP is fixed to enforce ipproto */ - if (f != NULL && f->proto != IPPROTO_UDP) - SCReturnInt(-1); - - if (input == NULL || input_len == 0 || input_len < sizeof(DNSHeader)) { - SCLogDebug("ilen too small, hoped for at least %"PRIuMAX, (uintmax_t)sizeof(DNSHeader)); - goto insufficient_data; - } - - DNSHeader *dns_header = (DNSHeader *)input; - SCLogDebug("DNS %p", dns_header); - - if (DNSValidateRequestHeader(dns_state, dns_header) < 0) - goto bad_data; - - uint16_t q; - const uint8_t *data = input + sizeof(DNSHeader); - for (q = 0; q < ntohs(dns_header->questions); q++) { - uint8_t fqdn[DNS_MAX_SIZE]; - uint16_t fqdn_offset = 0; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for len"); - goto insufficient_data; - } - SCLogDebug("query length %u", *data); - - while (*data != 0) { - if (*data > 63) { - /** \todo set event?*/ - goto insufficient_data; - } - uint8_t length = *data; - - data++; - - if (length == 0) { - break; - } - - if (input + input_len < data + length) { - SCLogDebug("input buffer too small for domain of len %u", length); - goto insufficient_data; - } - //PrintRawDataFp(stdout, data, qry->length); - - if ((size_t)(fqdn_offset + length + 1) < sizeof(fqdn)) { - memcpy(fqdn + fqdn_offset, data, length); - fqdn_offset += length; - fqdn[fqdn_offset++] = '.'; - } else { - /** \todo set event? */ - goto insufficient_data; - } - - data += length; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for len(2)"); - goto insufficient_data; - } - - SCLogDebug("qry length %u", *data); - } - if (fqdn_offset) { - fqdn_offset--; - } - - data++; - if (input + input_len < data + sizeof(DNSQueryTrailer)) { - SCLogDebug("input buffer too small for DNSQueryTrailer"); - goto insufficient_data; - } - DNSQueryTrailer *trailer = (DNSQueryTrailer *)data; - SCLogDebug("trailer type %04x class %04x", ntohs(trailer->type), ntohs(trailer->class)); - data += sizeof(DNSQueryTrailer); - - /* store our data */ - if (dns_state != NULL) { - DNSStoreQueryInState(dns_state, fqdn, fqdn_offset, - ntohs(trailer->type), ntohs(trailer->class), - ntohs(dns_header->tx_id)); - } - } - - SCReturnInt(1); -bad_data: -insufficient_data: - SCReturnInt(-1); -} - -/** \internal - * \brief DNS UDP record parser, entry function - * - * Parses a DNS UDP record and fills the DNS state - * - */ -static int DNSUDPResponseParse(Flow *f, void *dstate, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - DNSState *dns_state = (DNSState *)dstate; - - SCLogDebug("starting %u", input_len); - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } - - /** \todo remove this when PP is fixed to enforce ipproto */ - if (f != NULL && f->proto != IPPROTO_UDP) - SCReturnInt(-1); - - if (input == NULL || input_len == 0 || input_len < sizeof(DNSHeader)) { - SCLogDebug("ilen too small, hoped for at least %"PRIuMAX, (uintmax_t)sizeof(DNSHeader)); - goto insufficient_data; - } - - DNSHeader *dns_header = (DNSHeader *)input; - SCLogDebug("DNS %p %04x %04x", dns_header, ntohs(dns_header->tx_id), dns_header->flags); - - DNSTransaction *tx = NULL; - int found = 0; - if ((tx = DNSTransactionFindByTxId(dns_state, ntohs(dns_header->tx_id))) != NULL) - found = 1; - - if (!found) { - SCLogDebug("DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE"); - DNSSetEvent(dns_state, DNS_DECODER_EVENT_UNSOLLICITED_RESPONSE); - } - - if (DNSValidateResponseHeader(dns_state, dns_header) < 0) - goto bad_data; - - SCLogDebug("queries %04x", ntohs(dns_header->questions)); - - uint16_t q; - const uint8_t *data = input + sizeof(DNSHeader); - for (q = 0; q < ntohs(dns_header->questions); q++) { - uint8_t fqdn[DNS_MAX_SIZE]; - uint16_t fqdn_offset = 0; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for len"); - goto insufficient_data; - } - SCLogDebug("qry length %u", *data); - - while (*data != 0) { - uint8_t length = *data; - data++; - - if (length == 0) - break; - - if (input + input_len < data + length) { - SCLogDebug("input buffer too small for domain of len %u", length); - goto insufficient_data; - } - //PrintRawDataFp(stdout, data, length); - - if ((size_t)(fqdn_offset + length + 1) < sizeof(fqdn)) { - memcpy(fqdn + fqdn_offset, data, length); - fqdn_offset += length; - fqdn[fqdn_offset++] = '.'; - } - - data += length; - - if (input + input_len < data + 1) { - SCLogDebug("input buffer too small for len"); - goto insufficient_data; - } - - SCLogDebug("length %u", *data); - } - if (fqdn_offset) { - fqdn_offset--; - } - - data++; - if (input + input_len < data + sizeof(DNSQueryTrailer)) { - SCLogDebug("input buffer too small for DNSQueryTrailer"); - goto insufficient_data; - } -#if DEBUG - DNSQueryTrailer *trailer = (DNSQueryTrailer *)data; - SCLogDebug("trailer type %04x class %04x", ntohs(trailer->type), ntohs(trailer->class)); -#endif - data += sizeof(DNSQueryTrailer); - } - - SCLogDebug("answer_rr %04x", ntohs(dns_header->answer_rr)); - for (q = 0; q < ntohs(dns_header->answer_rr); q++) { - data = DNSReponseParse(dns_state, dns_header, q, DNS_LIST_ANSWER, - input, input_len, data); - if (data == NULL) { - goto insufficient_data; - } - } - - SCLogDebug("authority_rr %04x", ntohs(dns_header->authority_rr)); - for (q = 0; q < ntohs(dns_header->authority_rr); q++) { - data = DNSReponseParse(dns_state, dns_header, q, DNS_LIST_AUTHORITY, - input, input_len, data); - if (data == NULL) { - goto insufficient_data; - } - } - - /* parse rcode, e.g. "noerror" or "nxdomain" */ - uint8_t rcode = ntohs(dns_header->flags) & 0x0F; - if (rcode <= DNS_RCODE_NOTZONE) { - SCLogDebug("rcode %u", rcode); - if (tx != NULL) - tx->rcode = rcode; - } else { - /* this is not invalid, rcodes can be user defined */ - SCLogDebug("unexpected DNS rcode %u", rcode); - } - - if (ntohs(dns_header->flags) & 0x0080) { - SCLogDebug("recursion desired"); - if (tx != NULL) - tx->recursion_desired = 1; - } - - if (tx != NULL) { - tx->replied = 1; - } - - SCReturnInt(1); - -bad_data: -insufficient_data: - DNSSetEvent(dns_state, DNS_DECODER_EVENT_MALFORMED_DATA); - SCReturnInt(-1); -} - -static uint16_t DNSUdpProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset) -{ - if (ilen == 0 || ilen < sizeof(DNSHeader)) { - SCLogDebug("ilen too small, hoped for at least %"PRIuMAX, (uintmax_t)sizeof(DNSHeader)); - return ALPROTO_UNKNOWN; - } - - if (DNSUDPRequestParse(NULL, NULL, NULL, input, ilen, NULL) == -1) - return ALPROTO_FAILED; - - return ALPROTO_DNS; -} - -static void DNSUDPConfigure(void) -{ - uint32_t request_flood = DNS_CONFIG_DEFAULT_REQUEST_FLOOD; - uint32_t state_memcap = DNS_CONFIG_DEFAULT_STATE_MEMCAP; - uint64_t global_memcap = DNS_CONFIG_DEFAULT_GLOBAL_MEMCAP; - - ConfNode *p = ConfGetNode("app-layer.protocols.dns.request-flood"); - if (p != NULL) { - uint32_t value; - if (ParseSizeStringU32(p->val, &value) < 0) { - SCLogError(SC_ERR_DNS_CONFIG, "invalid value for request-flood %s", p->val); - } else { - request_flood = value; - } - } - SCLogInfo("DNS request flood protection level: %u", request_flood); - DNSConfigSetRequestFlood(request_flood); - - p = ConfGetNode("app-layer.protocols.dns.state-memcap"); - if (p != NULL) { - uint32_t value; - if (ParseSizeStringU32(p->val, &value) < 0) { - SCLogError(SC_ERR_DNS_CONFIG, "invalid value for state-memcap %s", p->val); - } else { - state_memcap = value; - } - } - SCLogInfo("DNS per flow memcap (state-memcap): %u", state_memcap); - DNSConfigSetStateMemcap(state_memcap); - - p = ConfGetNode("app-layer.protocols.dns.global-memcap"); - if (p != NULL) { - uint64_t value; - if (ParseSizeStringU64(p->val, &value) < 0) { - SCLogError(SC_ERR_DNS_CONFIG, "invalid value for global-memcap %s", p->val); - } else { - global_memcap = value; - } - } - SCLogInfo("DNS global memcap: %"PRIu64, global_memcap); - DNSConfigSetGlobalMemcap(global_memcap); -} - -void RegisterDNSUDPParsers(void) -{ - char *proto_name = "dns"; - - /** DNS */ - if (AppLayerProtoDetectConfProtoDetectionEnabled("udp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_DNS, proto_name); - - if (RunmodeIsUnittests()) { - AppLayerProtoDetectPPRegister(IPPROTO_UDP, - "53", - ALPROTO_DNS, - 0, sizeof(DNSHeader), - STREAM_TOSERVER, - DNSUdpProbingParser); - } else { - int have_cfg = AppLayerProtoDetectPPParseConfPorts("udp", IPPROTO_UDP, - proto_name, ALPROTO_DNS, - 0, sizeof(DNSHeader), - DNSUdpProbingParser); - /* if we have no config, we enable the default port 53 */ - if (!have_cfg) { - SCLogWarning(SC_ERR_DNS_CONFIG, "no DNS UDP config found, " - "enabling DNS detection on " - "port 53."); - AppLayerProtoDetectPPRegister(IPPROTO_UDP, "53", - ALPROTO_DNS, 0, sizeof(DNSHeader), - STREAM_TOSERVER, DNSUdpProbingParser); - } - } - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - proto_name); - return; - } - - if (AppLayerParserConfParserEnabled("udp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DNS, STREAM_TOSERVER, - DNSUDPRequestParse); - AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_DNS, STREAM_TOCLIENT, - DNSUDPResponseParse); - AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_DNS, DNSStateAlloc, - DNSStateFree); - AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_DNS, - DNSStateTransactionFree); - - AppLayerParserRegisterGetEventsFunc(IPPROTO_UDP, ALPROTO_DNS, DNSGetEvents); - AppLayerParserRegisterHasEventsFunc(IPPROTO_UDP, ALPROTO_DNS, DNSHasEvents); - AppLayerParserRegisterDetectStateFuncs(IPPROTO_UDP, ALPROTO_DNS, - DNSStateHasTxDetectState, - DNSGetTxDetectState, DNSSetTxDetectState); - - AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_DNS, - DNSGetTx); - AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_DNS, - DNSGetTxCnt); - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_UDP, ALPROTO_DNS, - DNSGetAlstateProgress); - AppLayerParserRegisterGetStateProgressCompletionStatus(IPPROTO_UDP, ALPROTO_DNS, - DNSGetAlstateProgressCompletionStatus); - - DNSAppLayerRegisterGetEventInfo(IPPROTO_UDP, ALPROTO_DNS); - - DNSUDPConfigure(); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_UDP, ALPROTO_DNS, DNSUDPParserRegisterTests); -#endif -} - -/* UNITTESTS */ -#ifdef UNITTESTS -#include "util-unittest-helper.h" - -static int DNSUDPParserTest01 (void) -{ - int result = 0; - /* query: abcdefghijk.com - * TTL: 86400 - * serial 20130422 refresh 28800 retry 7200 exp 604800 min ttl 86400 - * ns, hostmaster */ - uint8_t buf[] = { 0x00, 0x3c, 0x85, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x0b, 0x61, 0x62, 0x63, - 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, - 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x0f, 0x00, - 0x01, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, - 0x51, 0x80, 0x00, 0x25, 0x02, 0x6e, 0x73, 0x00, - 0x0a, 0x68, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0xc0, 0x2f, 0x01, 0x33, 0x2a, - 0x76, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x1c, - 0x20, 0x00, 0x09, 0x3a, 0x80, 0x00, 0x01, 0x51, - 0x80}; - size_t buflen = sizeof(buf); - Flow *f = NULL; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53); - if (f == NULL) - goto end; - f->proto = IPPROTO_UDP; - f->alproto = ALPROTO_DNS; - f->alstate = DNSStateAlloc(); - - int r = DNSUDPResponseParse(f, f->alstate, NULL, buf, buflen, NULL); - if (r != 1) - goto end; - - result = 1; -end: - UTHFreeFlow(f); - return (result); -} - -static int DNSUDPParserTest02 (void) -{ - int result = 0; - uint8_t buf[] = { - 0x6D,0x08,0x84,0x80,0x00,0x01,0x00,0x08,0x00,0x00,0x00,0x01,0x03,0x57,0x57,0x57, - 0x04,0x54,0x54,0x54,0x54,0x03,0x56,0x56,0x56,0x03,0x63,0x6F,0x6D,0x02,0x79,0x79, - 0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00, - 0x02,0xC0,0x0C,0xC0,0x31,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0, - 0x31,0xC0,0x3F,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x3F,0xC0, - 0x4D,0x00,0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x4D,0xC0,0x5B,0x00, - 0x05,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x5B,0xC0,0x69,0x00,0x05,0x00, - 0x01,0x00,0x00,0x0E,0x10,0x00,0x02,0xC0,0x69,0xC0,0x77,0x00,0x05,0x00,0x01,0x00, - 0x00,0x0E,0x10,0x00,0x02,0xC0,0x77,0xC0,0x85,0x00,0x05,0x00,0x01,0x00,0x00,0x0E, - 0x10,0x00,0x02,0xC0,0x85,0x00,0x00,0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - }; - size_t buflen = sizeof(buf); - Flow *f = NULL; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53); - if (f == NULL) - goto end; - f->proto = IPPROTO_UDP; - f->alproto = ALPROTO_DNS; - f->alstate = DNSStateAlloc(); - - int r = DNSUDPResponseParse(f, f->alstate, NULL, buf, buflen, NULL); - if (r != 1) - goto end; - - result = 1; -end: - UTHFreeFlow(f); - return (result); -} - -static int DNSUDPParserTest03 (void) -{ - int result = 0; - uint8_t buf[] = { - 0x6F,0xB4,0x84,0x80,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x03,0x03,0x57,0x57,0x77, - 0x0B,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x56,0x03,0x55,0x55,0x55, - 0x02,0x79,0x79,0x00,0x00,0x01,0x00,0x01,0xC0,0x0C,0x00,0x05,0x00,0x01,0x00,0x00, - 0x0E,0x10,0x00,0x02,0xC0,0x10,0xC0,0x34,0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10, - 0x00,0x04,0xC3,0xEA,0x04,0x19,0xC0,0x34,0x00,0x02,0x00,0x01,0x00,0x00,0x0E,0x10, - 0x00,0x0A,0x03,0x6E,0x73,0x31,0x03,0x61,0x67,0x62,0xC0,0x20,0xC0,0x46,0x00,0x02, - 0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x06,0x03,0x6E,0x73,0x32,0xC0,0x56,0xC0,0x52, - 0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x04,0x0A,0xC0,0x68, - 0x00,0x01,0x00,0x01,0x00,0x00,0x0E,0x10,0x00,0x04,0xC3,0xEA,0x05,0x14,0x00,0x00, - 0x29,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - }; - size_t buflen = sizeof(buf); - Flow *f = NULL; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 53); - if (f == NULL) - goto end; - f->proto = IPPROTO_UDP; - f->alproto = ALPROTO_DNS; - f->alstate = DNSStateAlloc(); - - int r = DNSUDPResponseParse(f, f->alstate, NULL, buf, buflen, NULL); - if (r != 1) - goto end; - - result = 1; -end: - UTHFreeFlow(f); - return (result); -} - -/** \test TXT records in answer */ -static int DNSUDPParserTest04 (void) -{ - int result = 0; - uint8_t buf[] = { - 0xc2,0x2f,0x81,0x80,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x0a,0x41,0x41,0x41, - 0x41,0x41,0x4f,0x31,0x6b,0x51,0x41,0x05,0x3d,0x61,0x75,0x74,0x68,0x03,0x73,0x72, - 0x76,0x06,0x74,0x75,0x6e,0x6e,0x65,0x6c,0x03,0x63,0x6f,0x6d,0x00,0x00,0x10,0x00, - 0x01, - /* answer record start */ - 0xc0,0x0c,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x22, - /* txt record starts: */ - 0x20, /* proto = IPPROTO_UDP; - f->alproto = ALPROTO_DNS; - f->alstate = DNSStateAlloc(); - - int r = DNSUDPResponseParse(f, f->alstate, NULL, buf, buflen, NULL); - if (r != 1) - goto end; - - result = 1; -end: - UTHFreeFlow(f); - return (result); -} - -/** \test TXT records in answer, bad txtlen */ -static int DNSUDPParserTest05 (void) -{ - int result = 0; - uint8_t buf[] = { - 0xc2,0x2f,0x81,0x80,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x0a,0x41,0x41,0x41, - 0x41,0x41,0x4f,0x31,0x6b,0x51,0x41,0x05,0x3d,0x61,0x75,0x74,0x68,0x03,0x73,0x72, - 0x76,0x06,0x74,0x75,0x6e,0x6e,0x65,0x6c,0x03,0x63,0x6f,0x6d,0x00,0x00,0x10,0x00, - 0x01, - /* answer record start */ - 0xc0,0x0c,0x00,0x10,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x22, - /* txt record starts: */ - 0x40, /* proto = IPPROTO_UDP; - f->alproto = ALPROTO_DNS; - f->alstate = DNSStateAlloc(); - - int r = DNSUDPResponseParse(f, f->alstate, NULL, buf, buflen, NULL); - if (r != -1) - goto end; - - result = 1; -end: - UTHFreeFlow(f); - return (result); -} - - -void DNSUDPParserRegisterTests(void) -{ - UtRegisterTest("DNSUDPParserTest01", DNSUDPParserTest01, 1); - UtRegisterTest("DNSUDPParserTest02", DNSUDPParserTest02, 1); - UtRegisterTest("DNSUDPParserTest03", DNSUDPParserTest03, 1); - UtRegisterTest("DNSUDPParserTest04", DNSUDPParserTest04, 1); - UtRegisterTest("DNSUDPParserTest05", DNSUDPParserTest05, 1); -} -#endif diff --git a/framework/src/suricata/src/app-layer-dns-udp.h b/framework/src/suricata/src/app-layer-dns-udp.h deleted file mode 100644 index a6ee12a8..00000000 --- a/framework/src/suricata/src/app-layer-dns-udp.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * \author Victor Julien - */ - -#ifndef __APP_LAYER_DNS_UDP_H__ -#define __APP_LAYER_DNS_UDP_H__ - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-dns-common.h" -#include "flow.h" -#include "queue.h" -#include "util-byte.h" - -void RegisterDNSUDPParsers(void); -void DNSUDPParserTests(void); -void DNSUDPParserRegisterTests(void); - -#endif /* __APP_LAYER_DNS_UDP_H__ */ diff --git a/framework/src/suricata/src/app-layer-events.c b/framework/src/suricata/src/app-layer-events.c deleted file mode 100644 index cd00a4ee..00000000 --- a/framework/src/suricata/src/app-layer-events.c +++ /dev/null @@ -1,137 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "decode.h" -#include "flow.h" -#include "app-layer-events.h" -#include "app-layer-parser.h" -#include "util-enum.h" - -/* events raised during protocol detection are stored in the - * packets storage, not in the flow. */ -SCEnumCharMap app_layer_event_pkt_table[ ] = { - { "APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS", - APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS }, - { "APPLAYER_WRONG_DIRECTION_FIRST_DATA", - APPLAYER_WRONG_DIRECTION_FIRST_DATA }, - { "APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION", - APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION }, - { "APPLAYER_PROTO_DETECTION_SKIPPED", - APPLAYER_PROTO_DETECTION_SKIPPED }, - { NULL, - -1 }, -}; - -int AppLayerGetPktEventInfo(const char *event_name, int *event_id) -{ - *event_id = SCMapEnumNameToValue(event_name, app_layer_event_pkt_table); - if (*event_id == -1) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " - "app-layer-event's packet event table.", event_name); - /* this should be treated as fatal */ - return -1; - } - - return 0; -} - -#define DECODER_EVENTS_BUFFER_STEPS 8 - -/** - * \brief Set an app layer decoder event. - * - * \param sevents Pointer to a AppLayerDecoderEvents pointer. If *sevents is NULL - * memory will be allocated. - * \param event The event to be stored. - */ -void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event) -{ - if (*sevents == NULL) { - AppLayerDecoderEvents *new_devents = SCMalloc(sizeof(AppLayerDecoderEvents)); - if (new_devents == NULL) - return; - - memset(new_devents, 0, sizeof(AppLayerDecoderEvents)); - *sevents = new_devents; - - } - if ((*sevents)->cnt == UCHAR_MAX) { - /* we're full */ - return; - } - if ((*sevents)->cnt == (*sevents)->events_buffer_size) { - int steps = DECODER_EVENTS_BUFFER_STEPS; - if (UCHAR_MAX - (*sevents)->cnt < steps) - steps = UCHAR_MAX - (*sevents)->cnt < steps; - - void *ptr = SCRealloc((*sevents)->events, - ((*sevents)->cnt + steps) * sizeof(uint8_t)); - if (ptr == NULL) { - /* couldn't grow buffer, but no reason to free old - * so we keep the events that may already be here */ - return; - } - (*sevents)->events = ptr; - (*sevents)->events_buffer_size += steps; - } - - (*sevents)->events[(*sevents)->cnt++] = event; -} - -/** - * \brief Set an app layer decoder event. - * - * \param f Pointer to a flow containing DecoderEvents pointer head. If - * the head points to a DecoderEvents instance, a - * new instance would be created and the pointer head would - * would be updated with this new instance - * \param event The event to be stored. - */ -void AppLayerDecoderEventsSetEvent(Flow *f, uint8_t event) -{ - AppLayerDecoderEvents *events = AppLayerParserGetDecoderEvents(f->alparser); - AppLayerDecoderEvents *new = events; - AppLayerDecoderEventsSetEventRaw(&events, event); - if (events != new) - AppLayerParserSetDecoderEvents(f->alparser, events); -} - -void AppLayerDecoderEventsResetEvents(AppLayerDecoderEvents *events) -{ - if (events != NULL) - events->cnt = 0; -} - - -void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events) -{ - if (events && *events != NULL) { - if ((*events)->events != NULL) - SCFree((*events)->events); - SCFree(*events); - *events = NULL; - } -} - diff --git a/framework/src/suricata/src/app-layer-events.h b/framework/src/suricata/src/app-layer-events.h deleted file mode 100644 index 11dfb9e6..00000000 --- a/framework/src/suricata/src/app-layer-events.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#ifndef __APP_LAYER_EVENTS_H__ -#define __APP_LAYER_EVENTS_H__ - -/* contains fwd declaration of AppLayerDecoderEvents_ */ -#include "decode.h" - -/** - * \brief Data structure to store app layer decoder events. - */ -struct AppLayerDecoderEvents_ { - /* array of events */ - uint8_t *events; - /* number of events in the above buffer */ - uint8_t cnt; - /* current event buffer size */ - uint8_t events_buffer_size; -}; - -/* app layer pkt level events */ -enum { - APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS, - APPLAYER_WRONG_DIRECTION_FIRST_DATA, - APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION, - APPLAYER_PROTO_DETECTION_SKIPPED, -}; - -/* the event types for app events */ -typedef enum AppLayerEventType_ { - APP_LAYER_EVENT_TYPE_GENERAL = 1, - APP_LAYER_EVENT_TYPE_TRANSACTION, - APP_LAYER_EVENT_TYPE_PACKET, -} AppLayerEventType; - -int AppLayerGetPktEventInfo(const char *event_name, int *event_id); - -void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event); -void AppLayerDecoderEventsSetEvent(Flow *f, uint8_t event); - -static inline int AppLayerDecoderEventsIsEventSet(AppLayerDecoderEvents *devents, - uint8_t event) -{ - if (devents == NULL) - return 0; - - int i; - int cnt = devents->cnt; - for (i = 0; i < cnt; i++) { - if (devents->events[i] == event) - return 1; - } - - return 0; -} - -void AppLayerDecoderEventsResetEvents(AppLayerDecoderEvents *events); -void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events); - -#endif /* __APP_LAYER_EVENTS_H__ */ - diff --git a/framework/src/suricata/src/app-layer-ftp.c b/framework/src/suricata/src/app-layer-ftp.c deleted file mode 100644 index b5d4a03d..00000000 --- a/framework/src/suricata/src/app-layer-ftp.c +++ /dev/null @@ -1,681 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * App Layer Parser for FTP - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" - -#include "flow-util.h" - -#include "detect-engine-state.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-ftp.h" - -#include "util-spm.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "util-memcmp.h" - -static int FTPGetLineForDirection(FtpState *state, FtpLineState *line_state) -{ - void *ptmp; - if (line_state->current_line_lf_seen == 1) { - /* we have seen the lf for the previous line. Clear the parser - * details to parse new line */ - line_state->current_line_lf_seen = 0; - if (line_state->current_line_db == 1) { - line_state->current_line_db = 0; - SCFree(line_state->db); - line_state->db = NULL; - line_state->db_len = 0; - state->current_line = NULL; - state->current_line_len = 0; - } - } - - uint8_t *lf_idx = memchr(state->input, 0x0a, state->input_len); - - if (lf_idx == NULL) { - /* fragmented lines. Decoder event for special cases. Not all - * fragmented lines should be treated as a possible evasion - * attempt. With multi payload ftp chunks we can have valid - * cases of fragmentation. But within the same segment chunk - * if we see fragmentation then it's definitely something you - * should alert about */ - if (line_state->current_line_db == 0) { - line_state->db = SCMalloc(state->input_len); - if (line_state->db == NULL) { - return -1; - } - line_state->current_line_db = 1; - memcpy(line_state->db, state->input, state->input_len); - line_state->db_len = state->input_len; - } else { - ptmp = SCRealloc(line_state->db, - (line_state->db_len + state->input_len)); - if (ptmp == NULL) { - SCFree(line_state->db); - line_state->db = NULL; - line_state->db_len = 0; - return -1; - } - line_state->db = ptmp; - - memcpy(line_state->db + line_state->db_len, - state->input, state->input_len); - line_state->db_len += state->input_len; - } - state->input += state->input_len; - state->input_len = 0; - - return -1; - - } else { - line_state->current_line_lf_seen = 1; - - if (line_state->current_line_db == 1) { - ptmp = SCRealloc(line_state->db, - (line_state->db_len + (lf_idx + 1 - state->input))); - if (ptmp == NULL) { - SCFree(line_state->db); - line_state->db = NULL; - line_state->db_len = 0; - return -1; - } - line_state->db = ptmp; - - memcpy(line_state->db + line_state->db_len, - state->input, (lf_idx + 1 - state->input)); - line_state->db_len += (lf_idx + 1 - state->input); - - if (line_state->db_len > 1 && - line_state->db[line_state->db_len - 2] == 0x0D) { - line_state->db_len -= 2; - state->current_line_delimiter_len = 2; - } else { - line_state->db_len -= 1; - state->current_line_delimiter_len = 1; - } - - state->current_line = line_state->db; - state->current_line_len = line_state->db_len; - - } else { - state->current_line = state->input; - state->current_line_len = lf_idx - state->input; - - if (state->input != lf_idx && - *(lf_idx - 1) == 0x0D) { - state->current_line_len--; - state->current_line_delimiter_len = 2; - } else { - state->current_line_delimiter_len = 1; - } - } - - state->input_len -= (lf_idx - state->input) + 1; - state->input = (lf_idx + 1); - - return 0; - } - -} - -static int FTPGetLine(FtpState *state) -{ - SCEnter(); - - /* we have run out of input */ - if (state->input_len <= 0) - return -1; - - /* toserver */ - if (state->direction == 0) - return FTPGetLineForDirection(state, &state->line_state[0]); - else - return FTPGetLineForDirection(state, &state->line_state[1]); -} - -/** - * \brief This function is called to determine and set which command is being - * transfered to the ftp server - * \param ftp_state the ftp state structure for the parser - * \param input input line of the command - * \param len of the command - * - * \retval 1 when the command is parsed, 0 otherwise - */ -static int FTPParseRequestCommand(void *ftp_state, uint8_t *input, - uint32_t input_len) -{ - SCEnter(); - FtpState *fstate = (FtpState *)ftp_state; - fstate->command = FTP_COMMAND_UNKNOWN; - - if (input_len >= 4) { - if (SCMemcmpLowercase("port", input, 4) == 0) { - fstate->command = FTP_COMMAND_PORT; - } - - /* else { - * Add the ftp commands you need here - * } - */ - } - return 1; -} - -/** - * \brief This function is called to retrieve a ftp request - * \param ftp_state the ftp state structure for the parser - * \param input input line of the command - * \param input_len length of the request - * \param output the resulting output - * - * \retval 1 when the command is parsed, 0 otherwise - */ -static int FTPParseRequest(Flow *f, void *ftp_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SCEnter(); - /* PrintRawDataFp(stdout, input,input_len); */ - - FtpState *state = (FtpState *)ftp_state; - void *ptmp; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - state->input = input; - state->input_len = input_len; - /* toserver stream */ - state->direction = 0; - - while (FTPGetLine(state) >= 0) { - FTPParseRequestCommand(state, - state->current_line, state->current_line_len); - if (state->command == FTP_COMMAND_PORT) { - if (state->current_line_len > state->port_line_size) { - ptmp = SCRealloc(state->port_line, state->current_line_len); - if (ptmp == NULL) { - SCFree(state->port_line); - state->port_line = NULL; - state->port_line_size = 0; - return 0; - } - state->port_line = ptmp; - - state->port_line_size = state->current_line_len; - } - memcpy(state->port_line, state->current_line, - state->current_line_len); - state->port_line_len = state->current_line_len; - } - } - - return 1; -} - -/** - * \brief This function is called to retrieve a ftp response - * \param ftp_state the ftp state structure for the parser - * \param input input line of the command - * \param input_len length of the request - * \param output the resulting output - * - * \retval 1 when the command is parsed, 0 otherwise - */ -static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - return 1; -} - -#ifdef DEBUG -static SCMutex ftp_state_mem_lock = SCMUTEX_INITIALIZER; -static uint64_t ftp_state_memuse = 0; -static uint64_t ftp_state_memcnt = 0; -#endif - -static void *FTPStateAlloc(void) -{ - void *s = SCMalloc(sizeof(FtpState)); - if (unlikely(s == NULL)) - return NULL; - - memset(s, 0, sizeof(FtpState)); - -#ifdef DEBUG - SCMutexLock(&ftp_state_mem_lock); - ftp_state_memcnt++; - ftp_state_memuse+=sizeof(FtpState); - SCMutexUnlock(&ftp_state_mem_lock); -#endif - return s; -} - -static void FTPStateFree(void *s) -{ - FtpState *fstate = (FtpState *) s; - if (fstate->port_line != NULL) - SCFree(fstate->port_line); - if (fstate->line_state[0].db) - SCFree(fstate->line_state[0].db); - if (fstate->line_state[1].db) - SCFree(fstate->line_state[1].db); - SCFree(s); -#ifdef DEBUG - SCMutexLock(&ftp_state_mem_lock); - ftp_state_memcnt--; - ftp_state_memuse-=sizeof(FtpState); - SCMutexUnlock(&ftp_state_mem_lock); -#endif -} - -static int FTPRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_FTP, - "USER ", 5, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_FTP, - "PASS ", 5, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_FTP, - "PORT ", 5, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - - return 0; -} - -void RegisterFTPParsers(void) -{ - char *proto_name = "ftp"; - - /** FTP */ - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_FTP, proto_name); - if (FTPRegisterPatternsForProtocolDetection() < 0 ) - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_FTP, STREAM_TOSERVER, - FTPParseRequest); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_FTP, STREAM_TOCLIENT, - FTPParseResponse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_FTP, FTPStateAlloc, FTPStateFree); - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_FTP, STREAM_TOSERVER | STREAM_TOCLIENT); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_FTP, FTPParserRegisterTests); -#endif -} - -void FTPAtExitPrintStats(void) -{ -#ifdef DEBUG - SCMutexLock(&ftp_state_mem_lock); - SCLogDebug("ftp_state_memcnt %"PRIu64", ftp_state_memuse %"PRIu64"", - ftp_state_memcnt, ftp_state_memuse); - SCMutexUnlock(&ftp_state_mem_lock); -#endif -} - -/* UNITTESTS */ -#ifdef UNITTESTS - -/** \test Send a get request in one chunk. */ -int FTPParserTest01(void) -{ - int result = 1; - Flow f; - uint8_t ftpbuf[] = "PORT 192,168,1,1,0,80\r\n"; - uint32_t ftplen = sizeof(ftpbuf) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER|STREAM_EOF, ftpbuf, ftplen); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - FtpState *ftp_state = f.alstate; - if (ftp_state == NULL) { - SCLogDebug("no ftp state: "); - result = 0; - goto end; - } - - if (ftp_state->command != FTP_COMMAND_PORT) { - SCLogDebug("expected command %" PRIu32 ", got %" PRIu32 ": ", FTP_COMMAND_PORT, ftp_state->command); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test Send a splitted get request. */ -int FTPParserTest03(void) -{ - int result = 1; - Flow f; - uint8_t ftpbuf1[] = "POR"; - uint32_t ftplen1 = sizeof(ftpbuf1) - 1; /* minus the \0 */ - uint8_t ftpbuf2[] = "T 192,168,1"; - uint32_t ftplen2 = sizeof(ftpbuf2) - 1; /* minus the \0 */ - uint8_t ftpbuf3[] = "1,1,10,20\r\n"; - uint32_t ftplen3 = sizeof(ftpbuf3) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER|STREAM_START, ftpbuf1, ftplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER, ftpbuf2, ftplen2); - if (r != 0) { - SCLogDebug("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER|STREAM_EOF, ftpbuf3, ftplen3); - if (r != 0) { - SCLogDebug("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - FtpState *ftp_state = f.alstate; - if (ftp_state == NULL) { - SCLogDebug("no ftp state: "); - result = 0; - goto end; - } - - if (ftp_state->command != FTP_COMMAND_PORT) { - SCLogDebug("expected command %" PRIu32 ", got %" PRIu32 ": ", FTP_COMMAND_PORT, ftp_state->command); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test See how it deals with an incomplete request. */ -int FTPParserTest06(void) -{ - int result = 1; - Flow f; - uint8_t ftpbuf1[] = "PORT"; - uint32_t ftplen1 = sizeof(ftpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, ftpbuf1, ftplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - FtpState *ftp_state = f.alstate; - if (ftp_state == NULL) { - SCLogDebug("no ftp state: "); - result = 0; - goto end; - } - - if (ftp_state->command != FTP_COMMAND_UNKNOWN) { - SCLogDebug("expected command %" PRIu32 ", got %" PRIu32 ": ", FTP_COMMAND_UNKNOWN, ftp_state->command); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test See how it deals with an incomplete request in multiple chunks. */ -int FTPParserTest07(void) -{ - int result = 1; - Flow f; - uint8_t ftpbuf1[] = "PO"; - uint32_t ftplen1 = sizeof(ftpbuf1) - 1; /* minus the \0 */ - uint8_t ftpbuf2[] = "RT\r\n"; - uint32_t ftplen2 = sizeof(ftpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER|STREAM_START, ftpbuf1, ftplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER|STREAM_EOF, ftpbuf2, ftplen2); - if (r != 0) { - SCLogDebug("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - FtpState *ftp_state = f.alstate; - if (ftp_state == NULL) { - SCLogDebug("no ftp state: "); - result = 0; - goto end; - } - - if (ftp_state->command != FTP_COMMAND_PORT) { - SCLogDebug("expected command %" PRIu32 ", got %" PRIu32 ": ", - FTP_COMMAND_PORT, ftp_state->command); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test Test case where chunks are smaller than the delim length and the - * last chunk is supposed to match the delim. */ -int FTPParserTest10(void) -{ - int result = 1; - Flow f; - uint8_t ftpbuf1[] = "PORT 1,2,3,4,5,6\r\n"; - uint32_t ftplen1 = sizeof(ftpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - int r = 0; - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < ftplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (ftplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, flags, &ftpbuf1[u], 1); - if (r != 0) { - SCLogDebug("toserver chunk %" PRIu32 " returned %" PRId32 ", expected 0: ", u, r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - } - - FtpState *ftp_state = f.alstate; - if (ftp_state == NULL) { - SCLogDebug("no ftp state: "); - result = 0; - goto end; - } - - if (ftp_state->command != FTP_COMMAND_PORT) { - SCLogDebug("expected command %" PRIu32 ", got %" PRIu32 ": ", FTP_COMMAND_PORT, ftp_state->command); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} -#endif /* UNITTESTS */ - -void FTPParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("FTPParserTest01", FTPParserTest01, 1); - UtRegisterTest("FTPParserTest03", FTPParserTest03, 1); - UtRegisterTest("FTPParserTest06", FTPParserTest06, 1); - UtRegisterTest("FTPParserTest07", FTPParserTest07, 1); - UtRegisterTest("FTPParserTest10", FTPParserTest10, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/app-layer-ftp.h b/framework/src/suricata/src/app-layer-ftp.h deleted file mode 100644 index 4a001290..00000000 --- a/framework/src/suricata/src/app-layer-ftp.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - */ - -#ifndef __APP_LAYER_FTP_H__ -#define __APP_LAYER_FTP_H__ - -typedef enum { - FTP_COMMAND_UNKNOWN = 0, - FTP_COMMAND_ABOR, - FTP_COMMAND_ACCT, - FTP_COMMAND_ALLO, - FTP_COMMAND_APPE, - FTP_COMMAND_CDUP, - FTP_COMMAND_CHMOD, - FTP_COMMAND_CWD, - FTP_COMMAND_DELE, - FTP_COMMAND_HELP, - FTP_COMMAND_IDLE, - FTP_COMMAND_LIST, - FTP_COMMAND_MAIL, - FTP_COMMAND_MDTM, - FTP_COMMAND_MKD, - FTP_COMMAND_MLFL, - FTP_COMMAND_MODE, - FTP_COMMAND_MRCP, - FTP_COMMAND_MRSQ, - FTP_COMMAND_MSAM, - FTP_COMMAND_MSND, - FTP_COMMAND_MSOM, - FTP_COMMAND_NLST, - FTP_COMMAND_NOOP, - FTP_COMMAND_PASS, - FTP_COMMAND_PASV, - FTP_COMMAND_PORT, - FTP_COMMAND_PWD, - FTP_COMMAND_QUIT, - FTP_COMMAND_REIN, - FTP_COMMAND_REST, - FTP_COMMAND_RETR, - FTP_COMMAND_RMD, - FTP_COMMAND_RNFR, - FTP_COMMAND_RNTO, - FTP_COMMAND_SITE, - FTP_COMMAND_SIZE, - FTP_COMMAND_SMNT, - FTP_COMMAND_STAT, - FTP_COMMAND_STOR, - FTP_COMMAND_STOU, - FTP_COMMAND_STRU, - FTP_COMMAND_SYST, - FTP_COMMAND_TYPE, - FTP_COMMAND_UMASK, - FTP_COMMAND_USER - /** \todo more if missing.. */ -} FtpRequestCommand; -typedef uint32_t FtpRequestCommandArgOfs; - -typedef uint16_t FtpResponseCode; - -enum { - FTP_FIELD_NONE = 0, - - FTP_FIELD_REQUEST_LINE, - FTP_FIELD_REQUEST_COMMAND, - FTP_FIELD_REQUEST_ARGS, - - FTP_FIELD_RESPONSE_LINE, - FTP_FIELD_REPONSE_CODE, - - /* must be last */ - FTP_FIELD_MAX, -}; - -/** used to hold the line state when we have fragmentation. */ -typedef struct FtpLineState_ { - /** used to indicate if the current_line buffer is a malloced buffer. We - * use a malloced buffer, if a line is fragmented */ - uint8_t *db; - uint32_t db_len; - uint8_t current_line_db; - /** we have see LF for the currently parsed line */ - uint8_t current_line_lf_seen; -} FtpLineState; - -/** FTP State for app layer parser */ -typedef struct FtpState_ { - uint8_t *input; - int32_t input_len; - uint8_t direction; - - /* --parser details-- */ - /** current line extracted by the parser from the call to FTPGetline() */ - uint8_t *current_line; - /** length of the line in current_line. Doesn't include the delimiter */ - uint32_t current_line_len; - uint8_t current_line_delimiter_len; - - /* 0 for toserver, 1 for toclient */ - FtpLineState line_state[2]; - - FtpRequestCommand command; - FtpRequestCommandArgOfs arg_offset; - uint32_t port_line_len; - uint32_t port_line_size; - uint8_t *port_line; -} FtpState; - -void RegisterFTPParsers(void); -void FTPParserRegisterTests(void); -void FTPAtExitPrintStats(void); - -#endif /* __APP_LAYER_FTP_H__ */ - diff --git a/framework/src/suricata/src/app-layer-htp-body.c b/framework/src/suricata/src/app-layer-htp-body.c deleted file mode 100644 index 6454fe1c..00000000 --- a/framework/src/suricata/src/app-layer-htp-body.c +++ /dev/null @@ -1,264 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Gurvinder Singh - * \author Pablo Rincon - * \author Brian Rectanus - * - * This file provides a HTTP protocol support for the engine using HTP library. - */ - -#include "suricata.h" -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-radix-tree.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-htp.h" - -#include "util-spm.h" -#include "util-debug.h" -#include "app-layer-htp.h" -#include "app-layer-htp-file.h" -#include "util-time.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "flow-util.h" - -#include "detect-engine.h" -#include "detect-engine-state.h" -#include "detect-parse.h" - -#include "conf.h" - -#include "util-memcmp.h" - -/** - * \brief Append a chunk of body to the HtpBody struct - * - * \param body pointer to the HtpBody holding the list - * \param data pointer to the data of the chunk - * \param len length of the chunk pointed by data - * - * \retval 0 ok - * \retval -1 error - */ -int HtpBodyAppendChunk(HtpTxUserData *htud, HtpBody *body, uint8_t *data, uint32_t len) -{ - SCEnter(); - - HtpBodyChunk *bd = NULL; - - if (len == 0 || data == NULL) { - SCReturnInt(0); - } - - if (body->first == NULL) { - /* New chunk */ - bd = (HtpBodyChunk *)HTPMalloc(sizeof(HtpBodyChunk)); - if (bd == NULL) - goto error; - - bd->len = len; - bd->stream_offset = 0; - bd->next = NULL; - bd->logged = 0; - - bd->data = HTPMalloc(len); - if (bd->data == NULL) { - goto error; - } - memcpy(bd->data, data, len); - - body->first = body->last = bd; - - body->content_len_so_far = len; - } else { - bd = (HtpBodyChunk *)HTPMalloc(sizeof(HtpBodyChunk)); - if (bd == NULL) - goto error; - - bd->len = len; - bd->stream_offset = body->content_len_so_far; - bd->next = NULL; - bd->logged = 0; - - bd->data = HTPMalloc(len); - if (bd->data == NULL) { - goto error; - } - memcpy(bd->data, data, len); - - body->last->next = bd; - body->last = bd; - - body->content_len_so_far += len; - } - SCLogDebug("Body %p; data %p, len %"PRIu32, body, bd->data, (uint32_t)bd->len); - - SCReturnInt(0); - -error: - if (bd != NULL) { - if (bd->data != NULL) { - HTPFree(bd->data, bd->len); - } - HTPFree(bd, sizeof(HtpBodyChunk)); - } - SCReturnInt(-1); -} - -/** - * \brief Print the information and chunks of a Body - * \param body pointer to the HtpBody holding the list - * \retval none - */ -void HtpBodyPrint(HtpBody *body) -{ - if (SCLogDebugEnabled()||1) { - SCEnter(); - - if (body->first == NULL) - return; - - HtpBodyChunk *cur = NULL; - SCLogDebug("--- Start body chunks at %p ---", body); - printf("--- Start body chunks at %p ---\n", body); - for (cur = body->first; cur != NULL; cur = cur->next) { - SCLogDebug("Body %p; data %p, len %"PRIu32, body, cur->data, (uint32_t)cur->len); - printf("Body %p; data %p, len %"PRIu32"\n", body, cur->data, (uint32_t)cur->len); - PrintRawDataFp(stdout, (uint8_t*)cur->data, cur->len); - } - SCLogDebug("--- End body chunks at %p ---", body); - } -} - -/** - * \brief Free the information held in the request body - * \param body pointer to the HtpBody holding the list - * \retval none - */ -void HtpBodyFree(HtpBody *body) -{ - SCEnter(); - - if (body->first == NULL) - return; - - SCLogDebug("Removing chunks of Body %p; data %p, len %"PRIu32, body, - body->last->data, (uint32_t)body->last->len); - - HtpBodyChunk *cur = NULL; - HtpBodyChunk *prev = NULL; - - prev = body->first; - while (prev != NULL) { - cur = prev->next; - if (prev->data != NULL) - HTPFree(prev->data, prev->len); - HTPFree(prev, sizeof(HtpBodyChunk)); - prev = cur; - } - body->first = body->last = NULL; -} - -/** - * \brief Free request body chunks that are already fully parsed. - * - * \param state htp_state, with reference to our config - * \param body the body to prune - * \param direction STREAM_TOSERVER (request), STREAM_TOCLIENT (response) - * - * \retval none - */ -void HtpBodyPrune(HtpState *state, HtpBody *body, int direction) -{ - SCEnter(); - - if (body == NULL || body->first == NULL) { - SCReturn; - } - - if (body->body_parsed == 0) { - SCReturn; - } - - /* get the configured inspect sizes. Default to response values */ - uint32_t min_size = state->cfg->response_inspect_min_size; - uint32_t window = state->cfg->response_inspect_window; - - if (direction == STREAM_TOSERVER) { - min_size = state->cfg->request_inspect_min_size; - window = state->cfg->request_inspect_window; - } - - if (body->body_inspected < (min_size > window) ? min_size : window) { - SCReturn; - } - - SCLogDebug("Pruning chunks of Body %p; data %p, len %"PRIu32, body, - body->last->data, (uint32_t)body->last->len); - - HtpBodyChunk *cur = body->first; - while (cur != NULL) { - HtpBodyChunk *next = cur->next; - - SCLogDebug("cur->stream_offset %"PRIu64" + cur->len %u = %"PRIu64", " - "body->body_parsed %"PRIu64, cur->stream_offset, cur->len, - cur->stream_offset + cur->len, body->body_parsed); - - uint64_t left_edge = body->body_inspected; - if (left_edge <= min_size || left_edge <= window) - left_edge = 0; - if (left_edge) - left_edge -= window; - - if (cur->stream_offset + cur->len > left_edge) { - break; - } - - body->first = next; - if (body->last == cur) { - body->last = next; - } - - if (cur->data != NULL) { - HTPFree(cur->data, cur->len); - } - HTPFree(cur, sizeof(HtpBodyChunk)); - - cur = next; - } - - SCReturn; -} diff --git a/framework/src/suricata/src/app-layer-htp-body.h b/framework/src/suricata/src/app-layer-htp-body.h deleted file mode 100644 index 6d54f0d5..00000000 --- a/framework/src/suricata/src/app-layer-htp-body.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Gurvinder Singh - * \author Pablo Rincon - * - * This file provides a HTTP protocol support for the engine using HTP library. - */ - -#ifndef __APP_LAYER_HTP_BODY_H__ -#define __APP_LAYER_HTP_BODY_H__ - -int HtpBodyAppendChunk(HtpTxUserData *, HtpBody *, uint8_t *, uint32_t); -void HtpBodyPrint(HtpBody *); -void HtpBodyFree(HtpBody *); -void HtpBodyPrune(HtpState *, HtpBody *, int); - -#endif /* __APP_LAYER_HTP_BODY_H__ */ diff --git a/framework/src/suricata/src/app-layer-htp-file.c b/framework/src/suricata/src/app-layer-htp-file.c deleted file mode 100644 index d8659f33..00000000 --- a/framework/src/suricata/src/app-layer-htp-file.c +++ /dev/null @@ -1,1635 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * This file provides HTTP protocol file handling support for the engine - * using HTP library. - */ - -#include "suricata.h" -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-radix-tree.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-htp.h" - -#include "util-spm.h" -#include "util-debug.h" -#include "app-layer-htp.h" -#include "util-time.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "flow-util.h" - -#include "detect-engine.h" -#include "detect-engine-state.h" -#include "detect-parse.h" - -#include "conf.h" - -#include "util-memcmp.h" - -/** - * \brief Open the file with "filename" and pass the first chunk - * of data if any. - * - * \param s http state - * \param filename name of the file - * \param filename_len length of the name - * \param data data chunk (if any) - * \param data_len length of the data portion - * \param direction flow direction - * - * \retval 0 ok - * \retval -1 error - * \retval -2 not handling files on this flow - */ -int HTPFileOpen(HtpState *s, uint8_t *filename, uint16_t filename_len, - uint8_t *data, uint32_t data_len, uint16_t txid, uint8_t direction) -{ - int retval = 0; - uint8_t flags = 0; - FileContainer *files = NULL; - FileContainer *files_opposite = NULL; - - SCLogDebug("data %p data_len %"PRIu32, data, data_len); - - if (s == NULL) { - SCReturnInt(-1); - } - - if (direction & STREAM_TOCLIENT) { - if (s->files_tc == NULL) { - s->files_tc = FileContainerAlloc(); - if (s->files_tc == NULL) { - retval = -1; - goto end; - } - } - - files = s->files_tc; - files_opposite = s->files_ts; - - if ((s->flags & HTP_FLAG_STORE_FILES_TS) || - ((s->flags & HTP_FLAG_STORE_FILES_TX_TS) && txid == s->store_tx_id)) { - flags |= FILE_STORE; - } - - if (s->f->flags & FLOW_FILE_NO_MAGIC_TC) { - SCLogDebug("no magic for this flow in toclient direction, so none for this file"); - flags |= FILE_NOMAGIC; - } - - if (s->f->flags & FLOW_FILE_NO_MD5_TC) { - SCLogDebug("no md5 for this flow in toclient direction, so none for this file"); - flags |= FILE_NOMD5; - } - - if (!(flags & FILE_STORE) && (s->f->flags & FLOW_FILE_NO_STORE_TC)) { - flags |= FILE_NOSTORE; - } - } else { - if (s->files_ts == NULL) { - s->files_ts = FileContainerAlloc(); - if (s->files_ts == NULL) { - retval = -1; - goto end; - } - } - - files = s->files_ts; - files_opposite = s->files_tc; - - if ((s->flags & HTP_FLAG_STORE_FILES_TC) || - ((s->flags & HTP_FLAG_STORE_FILES_TX_TC) && txid == s->store_tx_id)) { - flags |= FILE_STORE; - } - if (s->f->flags & FLOW_FILE_NO_MAGIC_TS) { - SCLogDebug("no magic for this flow in toserver direction, so none for this file"); - flags |= FILE_NOMAGIC; - } - - if (s->f->flags & FLOW_FILE_NO_MD5_TS) { - SCLogDebug("no md5 for this flow in toserver direction, so none for this file"); - flags |= FILE_NOMD5; - } - - if (!(flags & FILE_STORE) && (s->f->flags & FLOW_FILE_NO_STORE_TS)) { - flags |= FILE_NOSTORE; - } - } - - /* if the previous file is in the same txid, we reset the file part of the - * stateful detection engine. We cannot do that here directly, because of - * locking order. Flow is locked at this point and we can't lock flow - * before de_state */ - if (files != NULL && files->tail != NULL && files->tail->txid == txid) { - SCLogDebug("new file in same tx, flagging http state for de_state reset"); - - if (direction & STREAM_TOCLIENT) { - s->flags |= HTP_FLAG_NEW_FILE_TX_TC; - } else { - s->flags |= HTP_FLAG_NEW_FILE_TX_TS; - } - } - if (files_opposite != NULL && files_opposite->tail != NULL && files_opposite->tail->txid == txid) { - SCLogDebug("new file in same tx, flagging http state for de_state reset"); - - if (direction & STREAM_TOCLIENT) { - SCLogDebug("flagging TC"); - s->flags |= HTP_FLAG_NEW_FILE_TX_TC; - } else { - SCLogDebug("flagging TS"); - s->flags |= HTP_FLAG_NEW_FILE_TX_TS; - } - } - - if (FileOpenFile(files, filename, filename_len, - data, data_len, flags) == NULL) - { - retval = -1; - } - - FileSetTx(files->tail, txid); - - FilePrune(files); -end: - SCReturnInt(retval); -} - -/** - * \brief Store a chunk of data in the flow - * - * \param s http state - * \param data data chunk (if any) - * \param data_len length of the data portion - * \param direction flow direction - * - * \retval 0 ok - * \retval -1 error - * \retval -2 file doesn't need storing - */ -int HTPFileStoreChunk(HtpState *s, uint8_t *data, uint32_t data_len, - uint8_t direction) -{ - SCEnter(); - - int retval = 0; - int result = 0; - FileContainer *files = NULL; - - if (s == NULL) { - SCReturnInt(-1); - } - - if (direction & STREAM_TOCLIENT) { - files = s->files_tc; - } else { - files = s->files_ts; - } - - if (files == NULL) { - SCLogDebug("no files in state"); - retval = -1; - goto end; - } - - result = FileAppendData(files, data, data_len); - if (result == -1) { - SCLogDebug("appending data failed"); - retval = -1; - } else if (result == -2) { - retval = -2; - } - - FilePrune(files); -end: - SCReturnInt(retval); -} - -/** - * \brief Close the file in the flow - * - * \param s http state - * \param data data chunk if any - * \param data_len length of the data portion - * \param flags flags to indicate events - * \param direction flow direction - * - * Currently on the FLOW_FILE_TRUNCATED flag is implemented, indicating - * that the file isn't complete but we're stopping storing it. - * - * \retval 0 ok - * \retval -1 error - * \retval -2 not storing files on this flow/tx - */ -int HTPFileClose(HtpState *s, uint8_t *data, uint32_t data_len, - uint8_t flags, uint8_t direction) -{ - SCEnter(); - - int retval = 0; - int result = 0; - FileContainer *files = NULL; - - if (s == NULL) { - SCReturnInt(-1); - } - - if (direction & STREAM_TOCLIENT) { - files = s->files_tc; - } else { - files = s->files_ts; - } - - if (files == NULL) { - retval = -1; - goto end; - } - - result = FileCloseFile(files, data, data_len, flags); - if (result == -1) { - retval = -1; - } else if (result == -2) { - retval = -2; - } - - FilePrune(files); -end: - SCReturnInt(retval); -} - -#ifdef UNITTESTS -static int HTPFileParserTest01(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 215\r\n" - "\r\n" - "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n"; - - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "filecontent\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - HtpState *http_state = NULL; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, http_state, 0); - if (tx == NULL) { - goto end; - } - - if (tx->request_method == NULL || memcmp(bstr_util_strdup_to_c(tx->request_method), "POST", 4) != 0) - { - printf("expected method POST, got %s \n", bstr_util_strdup_to_c(tx->request_method)); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -static int HTPFileParserTest02(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 337\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - uint8_t httpbuf2[] = "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"email\"\r\n" - "\r\n" - "someaddress@somedomain.lan\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - uint8_t httpbuf3[] = "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - - uint8_t httpbuf4[] = "filecontent\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 3 size %u <<<<\n", httplen3); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 4 size %u <<<<\n", httplen4); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, http_state, 0); - if (tx == NULL) { - goto end; - } - - if (tx->request_method == NULL || memcmp(bstr_util_strdup_to_c(tx->request_method), "POST", 4) != 0) - { - printf("expected method POST, got %s \n", bstr_util_strdup_to_c(tx->request_method)); - goto end; - } - - if (http_state->files_ts == NULL || http_state->files_ts->tail == NULL || - http_state->files_ts->tail->state != FILE_STATE_CLOSED) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -static int HTPFileParserTest03(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 337\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - uint8_t httpbuf2[] = "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"email\"\r\n" - "\r\n" - "someaddress@somedomain.lan\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - uint8_t httpbuf3[] = "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - - uint8_t httpbuf4[] = "file"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - - uint8_t httpbuf5[] = "content\r\n"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - - uint8_t httpbuf6[] = "-----------------------------277531038314945--"; - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 3 size %u <<<<\n", httplen3); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 4 size %u <<<<\n", httplen4); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 5 size %u <<<<\n", httplen5); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 6 size %u <<<<\n", httplen6); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, http_state, 0); - if (tx == NULL) { - goto end; - } - - if (tx->request_method == NULL || memcmp(bstr_util_strdup_to_c(tx->request_method), "POST", 4) != 0) - { - printf("expected method POST, got %s \n", bstr_util_strdup_to_c(tx->request_method)); - goto end; - } - - if (http_state->files_ts == NULL || http_state->files_ts->tail == NULL || - http_state->files_ts->tail->state != FILE_STATE_CLOSED) { - goto end; - } - - if (http_state->files_ts->head->chunks_head->len != 11) { - printf("filedata len not 11 but %u: ", http_state->files_ts->head->chunks_head->len); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -static int HTPFileParserTest04(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 373\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - uint8_t httpbuf2[] = "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"email\"\r\n" - "\r\n" - "someaddress@somedomain.lan\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - uint8_t httpbuf3[] = "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - - uint8_t httpbuf4[] = "file0123456789abcdefghijklmnopqrstuvwxyz"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - - uint8_t httpbuf5[] = "content\r\n"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - - uint8_t httpbuf6[] = "-----------------------------277531038314945--"; - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 3 size %u <<<<\n", httplen3); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 4 size %u <<<<\n", httplen4); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 5 size %u <<<<\n", httplen5); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 6 size %u <<<<\n", httplen6); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, http_state, 0); - if (tx == NULL) { - goto end; - } - - if (tx->request_method == NULL || memcmp(bstr_util_strdup_to_c(tx->request_method), "POST", 4) != 0) - { - printf("expected method POST, got %s: ", bstr_util_strdup_to_c(tx->request_method)); - goto end; - } - - if (http_state->files_ts == NULL || http_state->files_ts->tail == NULL || - http_state->files_ts->tail->state != FILE_STATE_CLOSED) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -static int HTPFileParserTest05(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 544\r\n" - "\r\n" - "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n" - "filecontent\r\n" - "-----------------------------277531038314945\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n" - "FILECONTENT\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 size %u <<<<\n", httplen1); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, http_state, 0); - if (tx == NULL) { - goto end; - } - - if (tx->request_method == NULL || memcmp(bstr_util_strdup_to_c(tx->request_method), "POST", 4) != 0) - { - printf("expected method POST, got %s \n", bstr_util_strdup_to_c(tx->request_method)); - goto end; - } - - if (http_state->files_ts == NULL || http_state->files_ts->tail == NULL || - http_state->files_ts->tail->state != FILE_STATE_CLOSED) { - goto end; - } - - if (http_state->files_ts->head == http_state->files_ts->tail) - goto end; - - if (http_state->files_ts->head->next != http_state->files_ts->tail) - goto end; - - if (http_state->files_ts->head->chunks_head->len != 11) { - printf("expected 11 but file is %u bytes instead: ", - http_state->files_ts->head->chunks_head->len); - PrintRawDataFp(stdout, http_state->files_ts->head->chunks_head->data, - http_state->files_ts->head->chunks_head->len); - goto end; - } - - if (memcmp("filecontent", http_state->files_ts->head->chunks_head->data, - http_state->files_ts->head->chunks_head->len) != 0) { - goto end; - } - - if (http_state->files_ts->tail->chunks_head->len != 11) { - printf("expected 11 but file is %u bytes instead: ", - http_state->files_ts->tail->chunks_head->len); - PrintRawDataFp(stdout, http_state->files_ts->tail->chunks_head->data, - http_state->files_ts->tail->chunks_head->len); - goto end; - } - - if (memcmp("FILECONTENT", http_state->files_ts->tail->chunks_head->data, - http_state->files_ts->tail->chunks_head->len) != 0) { - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test first multipart part contains file but doesn't end in first chunk */ -static int HTPFileParserTest06(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 544\r\n" - "\r\n" - "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n" - "filecontent\r\n" - "-----------------------------27753103831494"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "5\r\nContent-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n" - "FILECONTENT\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 size %u <<<<\n", httplen1); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, http_state, 0); - if (tx == NULL) { - goto end; - } - - if (tx->request_method == NULL || memcmp(bstr_util_strdup_to_c(tx->request_method), "POST", 4) != 0) - { - printf("expected method POST, got %s \n", bstr_util_strdup_to_c(tx->request_method)); - goto end; - } - - if (http_state->files_ts == NULL || http_state->files_ts->tail == NULL || - http_state->files_ts->tail->state != FILE_STATE_CLOSED) { - goto end; - } - - if (http_state->files_ts->head == http_state->files_ts->tail) - goto end; - - if (http_state->files_ts->head->next != http_state->files_ts->tail) - goto end; - - if (http_state->files_ts->head->chunks_head->len != 11) { - printf("expected 11 but file is %u bytes instead: ", - http_state->files_ts->head->chunks_head->len); - PrintRawDataFp(stdout, http_state->files_ts->head->chunks_head->data, - http_state->files_ts->head->chunks_head->len); - goto end; - } - - if (memcmp("filecontent", http_state->files_ts->head->chunks_head->data, - http_state->files_ts->head->chunks_head->len) != 0) { - goto end; - } - - if (http_state->files_ts->tail->chunks_head->len != 11) { - printf("expected 11 but file is %u bytes instead: ", - http_state->files_ts->tail->chunks_head->len); - PrintRawDataFp(stdout, http_state->files_ts->tail->chunks_head->data, - http_state->files_ts->tail->chunks_head->len); - goto end; - } - - if (memcmp("FILECONTENT", http_state->files_ts->tail->chunks_head->data, - http_state->files_ts->tail->chunks_head->len) != 0) { - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test POST, but not multipart */ -static int HTPFileParserTest07(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /filename HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Length: 11\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "FILECONTENT"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 size %u <<<<\n", httplen1); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, http_state, 0); - if (tx == NULL) { - goto end; - } - - if (tx->request_method == NULL || memcmp(bstr_util_strdup_to_c(tx->request_method), "POST", 4) != 0) - { - printf("expected method POST, got %s \n", bstr_util_strdup_to_c(tx->request_method)); - goto end; - } - - if (http_state->files_ts == NULL || http_state->files_ts->tail == NULL || - http_state->files_ts->tail->state != FILE_STATE_CLOSED) { - printf("state != FILE_STATE_CLOSED"); - goto end; - } - - if (http_state->files_ts->head->chunks_head->len != 11) { - printf("expected 11 but file is %u bytes instead: ", - http_state->files_ts->head->chunks_head->len); - PrintRawDataFp(stdout, http_state->files_ts->head->chunks_head->data, - http_state->files_ts->head->chunks_head->len); - goto end; - } - - if (memcmp("FILECONTENT", http_state->files_ts->head->chunks_head->data, - http_state->files_ts->head->chunks_head->len) != 0) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -static int HTPFileParserTest08(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 215\r\n" - "\r\n" - "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n"; - - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "filecontent\r\n\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - HtpState *http_state = NULL; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f->m); - AppLayerDecoderEvents *decoder_events = AppLayerParserGetEventsByTx(IPPROTO_TCP, ALPROTO_HTTP,f->alstate, 0); - if (decoder_events == NULL) { - printf("no app events: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - if (decoder_events->cnt != 2) { - printf("expected 2 events: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test invalid header: Somereallylongheaderstr: has no value */ -static int HTPFileParserTest09(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 337\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - uint8_t httpbuf2[] = "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"email\"\r\n" - "\r\n" - "someaddress@somedomain.lan\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - uint8_t httpbuf3[] = "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Somereallylongheaderstr:\r\n" - "\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - - uint8_t httpbuf4[] = "filecontent\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 3 size %u <<<<\n", httplen3); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 4 size %u <<<<\n", httplen4); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f->m); - AppLayerDecoderEvents *decoder_events = AppLayerParserGetEventsByTx(IPPROTO_TCP, ALPROTO_HTTP,f->alstate, 0); - if (decoder_events == NULL) { - printf("no app events: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - if (decoder_events->cnt != 1) { - printf("expected 1 event: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test empty entries */ -static int HTPFileParserTest10(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 337\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - uint8_t httpbuf2[] = "-----------------------------277531038314945\r\n" - "\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - uint8_t httpbuf3[] = "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Somereallylongheaderstr: with a good value\r\n" - "\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - - uint8_t httpbuf4[] = "filecontent\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 3 size %u <<<<\n", httplen3); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 4 size %u <<<<\n", httplen4); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f->m); - AppLayerDecoderEvents *decoder_events = AppLayerParserGetEventsByTx(IPPROTO_TCP, ALPROTO_HTTP,f->alstate, 0); - if (decoder_events != NULL) { - printf("app events: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test filedata cut in two pieces */ -static int HTPFileParserTest11(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n" - "Content-Length: 1102\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - uint8_t httpbuf2[] = "------WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - uint8_t httpbuf3[] = "Content-Disposition: form-data; name=\"PROGRESS_URL\"\r\n" - "\r\n" - "http://somserver.com/progress.php?UPLOAD_IDENTIFIER=XXXXXXXXX.XXXXXXXXXX.XXXXXXXX.XX.X\r\n" - "------WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n" - "Content-Disposition: form-data; name=\"DESTINATION_DIR\"\r\n" - "\r\n" - "10\r\n" - "------WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n" - "Content-Disposition: form-data; name=\"js_enabled\"\r\n" - "\r\n" - "1" - "------WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n" - "Content-Disposition: form-data; name=\"signature\"\r\n" - "\r\n" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n" - "------WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n" - "Content-Disposition: form-data; name=\"upload_files\"\r\n" - "\r\n" - "------WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n" - "Content-Disposition: form-data; name=\"terms\"\r\n" - "\r\n" - "1" - "------WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n" - "Content-Disposition: form-data; name=\"file[]\"\r\n" - "\r\n" - "------WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n" - "Content-Disposition: form-data; name=\"description[]\"\r\n" - "\r\n" - "------WebKitFormBoundaryBRDbP74mBhBxsIdo\r\n" - "Content-Disposition: form-data; name=\"upload_file[]\"; filename=\"filename.doc\"\r\n" - "Content-Type: application/msword\r\n" - "\r\n" - "FILE"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - - uint8_t httpbuf4[] = "CONTENT\r\n" - "------WebKitFormBoundaryBRDbP74mBhBxsIdo--"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 3 size %u <<<<\n", httplen3); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SCLogDebug("\n>>>> processing chunk 4 size %u <<<<\n", httplen4); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - SCMutexLock(&f->m); - AppLayerDecoderEvents *decoder_events = AppLayerParserGetEventsByTx(IPPROTO_TCP, ALPROTO_HTTP,f->alstate, 0); - if (decoder_events != NULL) { - printf("app events: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, http_state, 0); - if (tx == NULL) { - goto end; - } - - if (tx->request_method == NULL || memcmp(bstr_util_strdup_to_c(tx->request_method), "POST", 4) != 0) - { - printf("expected method POST, got %s \n", bstr_util_strdup_to_c(tx->request_method)); - goto end; - } - - if (http_state->files_ts == NULL || http_state->files_ts->tail == NULL || - http_state->files_ts->tail->state != FILE_STATE_CLOSED) { - printf("state != FILE_STATE_CLOSED: "); - goto end; - } - - if (http_state->files_ts->head->chunks_head->len != 11) { - printf("expected 11 but file is %u bytes instead: ", - http_state->files_ts->head->chunks_head->len); - PrintRawDataFp(stdout, http_state->files_ts->head->chunks_head->data, - http_state->files_ts->head->chunks_head->len); - goto end; - } - - if (memcmp("FILECONTENT", http_state->files_ts->head->chunks_head->data, - http_state->files_ts->head->chunks_head->len) != 0) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -#endif /* UNITTESTS */ - -void HTPFileParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("HTPFileParserTest01", HTPFileParserTest01, 1); - UtRegisterTest("HTPFileParserTest02", HTPFileParserTest02, 1); - UtRegisterTest("HTPFileParserTest03", HTPFileParserTest03, 1); - UtRegisterTest("HTPFileParserTest04", HTPFileParserTest04, 1); - UtRegisterTest("HTPFileParserTest05", HTPFileParserTest05, 1); - UtRegisterTest("HTPFileParserTest06", HTPFileParserTest06, 1); - UtRegisterTest("HTPFileParserTest07", HTPFileParserTest07, 1); - UtRegisterTest("HTPFileParserTest08", HTPFileParserTest08, 1); - UtRegisterTest("HTPFileParserTest09", HTPFileParserTest09, 1); - UtRegisterTest("HTPFileParserTest10", HTPFileParserTest10, 1); - UtRegisterTest("HTPFileParserTest11", HTPFileParserTest11, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/app-layer-htp-file.h b/framework/src/suricata/src/app-layer-htp-file.h deleted file mode 100644 index d70794ea..00000000 --- a/framework/src/suricata/src/app-layer-htp-file.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#ifndef __APP_LAYER_HTP_FILE_H__ -#define __APP_LAYER_HTP_FILE_H__ - -int HTPFileOpen(HtpState *, uint8_t *, uint16_t, uint8_t *, uint32_t, uint16_t, uint8_t); -int HTPFileStoreChunk(HtpState *, uint8_t *, uint32_t, uint8_t); -int HTPFileClose(HtpState *, uint8_t *, uint32_t, uint8_t, uint8_t); - -void HTPFileParserRegisterTests(void); - -#endif /* __APP_LAYER_HTP_FILE_H__ */ diff --git a/framework/src/suricata/src/app-layer-htp-libhtp.c b/framework/src/suricata/src/app-layer-htp-libhtp.c deleted file mode 100644 index 69d86220..00000000 --- a/framework/src/suricata/src/app-layer-htp-libhtp.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * We are using this file to hold APIs copied from libhtp 0.5.x. - */ - -/*************************************************************************** - * Copyright (c) 2009-2010 Open Information Security Foundation - * Copyright (c) 2010-2013 Qualys, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Qualys, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ***************************************************************************/ - -/** - * Anoop Saldanha - */ - -#include "suricata.h" -#include "suricata-common.h" - - -/** - * \brief A direct flick off libhtp-0.5.x htp_is_lws(). - */ -static int SC_htp_is_lws(int c) -{ - if ((c == ' ') || (c == '\t')) return 1; - else return 0; -} - -/** - * \brief A direct flick off libhtp-0.5.x htp_parse_positive_integer_whitespace(). - */ -static int64_t SC_htp_parse_positive_integer_whitespace(unsigned char *data, size_t len, int base) -{ - if (len == 0) return -1003; - - size_t last_pos; - size_t pos = 0; - - // Ignore LWS before - while ((pos < len) && (SC_htp_is_lws(data[pos]))) pos++; - if (pos == len) return -1001; - - int64_t r = bstr_util_mem_to_pint(data + pos, len - pos, base, &last_pos); - if (r < 0) return r; - - // Move after the last digit - pos += last_pos; - - // Ignore LWS after - while (pos < len) { - if (!SC_htp_is_lws(data[pos])) { - return -1002; - } - - pos++; - } - - return r; -} - -/** - * \brief A direct flick off libhtp-0.5.x htp_parse_content_length() - */ -int64_t SC_htp_parse_content_length(bstr *b) -{ - return SC_htp_parse_positive_integer_whitespace((unsigned char *) bstr_ptr(b), bstr_len(b), 10); -} - -/** - * \brief Generates the normalized uri. - * - * Libhtp doesn't recreate the whole normalized uri and save it. - * That duty has now been passed to us. A lot of this code has been - * copied from libhtp. - * - * Keep an eye out on the tx->parsed_uri struct and how the parameters - * in it are generated, just in case some modifications are made to - * them in the future. - * - * \param uri_include_all boolean to indicate if scheme, username/password, - hostname and port should be part of the buffer - */ -bstr *SCHTPGenerateNormalizedUri(htp_tx_t *tx, htp_uri_t *uri, int uri_include_all) -{ - if (uri == NULL) - return NULL; - - // On the first pass determine the length of the final string - size_t len = 0; - - if (uri_include_all) { - if (uri->scheme != NULL) { - len += bstr_len(uri->scheme); - len += 3; // "://" - } - - if ((uri->username != NULL) || (uri->password != NULL)) { - if (uri->username != NULL) { - len += bstr_len(uri->username); - } - - len += 1; // ":" - - if (uri->password != NULL) { - len += bstr_len(uri->password); - } - - len += 1; // "@" - } - - if (uri->hostname != NULL) { - len += bstr_len(uri->hostname); - } - - if (uri->port != NULL) { - len += 1; // ":" - len += bstr_len(uri->port); - } - } - - if (uri->path != NULL) { - len += bstr_len(uri->path); - } - - if (uri->query != NULL) { - len += 1; // "?" - len += bstr_len(uri->query); - } - - if (uri->fragment != NULL) { - len += 1; // "#" - len += bstr_len(uri->fragment); - } - - // On the second pass construct the string - /* FIXME in memcap */ - bstr *r = bstr_alloc(len); - if (r == NULL) { - return NULL; - } - - if (uri_include_all) { - if (uri->scheme != NULL) { - bstr_add_noex(r, uri->scheme); - bstr_add_c_noex(r, "://"); - } - - if ((uri->username != NULL) || (uri->password != NULL)) { - if (uri->username != NULL) { - bstr_add_noex(r, uri->username); - } - - bstr_add_c(r, ":"); - - if (uri->password != NULL) { - bstr_add_noex(r, uri->password); - } - - bstr_add_c_noex(r, "@"); - } - - if (uri->hostname != NULL) { - bstr_add_noex(r, uri->hostname); - } - - if (uri->port != NULL) { - bstr_add_c(r, ":"); - bstr_add_noex(r, uri->port); - } - } - - if (uri->path != NULL) { - bstr_add_noex(r, uri->path); - } - - if (uri->query != NULL) { - bstr *query = bstr_dup(uri->query); - if (query) { - uint64_t flags = 0; - htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, query, &flags); - bstr_add_c_noex(r, "?"); - bstr_add_noex(r, query); - bstr_free(query); - } - } - - if (uri->fragment != NULL) { - bstr_add_c_noex(r, "#"); - bstr_add_noex(r, uri->fragment); - } - - return r; -} diff --git a/framework/src/suricata/src/app-layer-htp-libhtp.h b/framework/src/suricata/src/app-layer-htp-libhtp.h deleted file mode 100644 index 4c4eb3cd..00000000 --- a/framework/src/suricata/src/app-layer-htp-libhtp.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * We are using this file to hold APIs copied from libhtp 0.5.x. - */ - -/*************************************************************************** - * Copyright (c) 2009-2010 Open Information Security Foundation - * Copyright (c) 2010-2013 Qualys, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Qualys, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ***************************************************************************/ - -/** - * Anoop Saldanha - */ - -#ifndef __APP_LAYER_HTP_LIBHTP__H__ -#define __APP_LAYER_HTP_LIBHTP__H__ - -#include "suricata.h" -#include "suricata-common.h" - -bstr *SCHTPGenerateNormalizedUri(htp_tx_t *tx, htp_uri_t *uri, int uri_include_all); -int64_t SC_htp_parse_content_length(bstr *b); - -#endif /* __APP_LAYER_HTP_LIBHTP__H__ */ diff --git a/framework/src/suricata/src/app-layer-htp-mem.c b/framework/src/suricata/src/app-layer-htp-mem.c deleted file mode 100644 index c4f94e82..00000000 --- a/framework/src/suricata/src/app-layer-htp-mem.c +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - -/** - * \file - * - * \author Eric Leblond - * - * This file provides a memory handling for the HTTP protocol support. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "conf.h" -#include "util-mem.h" -#include "util-misc.h" - -#include "app-layer-htp-mem.h" - -uint64_t htp_config_memcap = 0; - -SC_ATOMIC_DECLARE(uint64_t, htp_memuse); -SC_ATOMIC_DECLARE(uint64_t, htp_memcap); - -void HTPParseMemcap() -{ - char *conf_val; - - /** set config values for memcap, prealloc and hash_size */ - if ((ConfGet("app-layer.protocols.http.memcap", &conf_val)) == 1) - { - if (ParseSizeStringU64(conf_val, &htp_config_memcap) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing http.memcap " - "from conf file - %s. Killing engine", - conf_val); - exit(EXIT_FAILURE); - } - SCLogInfo("HTTP memcap: %"PRIu64, htp_config_memcap); - } else { - /* default to unlimited */ - htp_config_memcap = 0; - } - - SC_ATOMIC_INIT(htp_memuse); - SC_ATOMIC_INIT(htp_memcap); -} - -void HTPIncrMemuse(uint64_t size) -{ - (void) SC_ATOMIC_ADD(htp_memuse, size); - return; -} - -void HTPDecrMemuse(uint64_t size) -{ - (void) SC_ATOMIC_SUB(htp_memuse, size); - return; -} - -uint64_t HTPMemuseGlobalCounter(void) -{ - uint64_t tmpval = SC_ATOMIC_GET(htp_memuse); - return tmpval; -} - -uint64_t HTPMemcapGlobalCounter(void) -{ - uint64_t tmpval = SC_ATOMIC_GET(htp_memcap); - return tmpval; -} - -/** - * \brief Check if alloc'ing "size" would mean we're over memcap - * - * \retval 1 if in bounds - * \retval 0 if not in bounds - */ -int HTPCheckMemcap(uint64_t size) -{ - if (htp_config_memcap == 0 || size + SC_ATOMIC_GET(htp_memuse) <= htp_config_memcap) - return 1; - (void) SC_ATOMIC_ADD(htp_memcap, 1); - return 0; -} - -void *HTPMalloc(size_t size) -{ - void *ptr = NULL; - - if (HTPCheckMemcap((uint32_t)size) == 0) - return NULL; - - ptr = SCMalloc(size); - - if (unlikely(ptr == NULL)) - return NULL; - - HTPIncrMemuse((uint64_t)size); - - return ptr; -} - -void *HTPRealloc(void *ptr, size_t orig_size, size_t size) -{ - void *rptr = NULL; - - if (HTPCheckMemcap((uint32_t)(size - orig_size)) == 0) - return NULL; - - rptr = SCRealloc(ptr, size); - if (rptr == NULL) - return NULL; - - HTPIncrMemuse((uint64_t)(size - orig_size)); - - return rptr; -} - -void HTPFree(void *ptr, size_t size) -{ - SCFree(ptr); - - HTPDecrMemuse((uint64_t)size); -} - - -/** - * @} - */ diff --git a/framework/src/suricata/src/app-layer-htp-mem.h b/framework/src/suricata/src/app-layer-htp-mem.h deleted file mode 100644 index 44b50f5c..00000000 --- a/framework/src/suricata/src/app-layer-htp-mem.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "stream-tcp-reassemble.h" - -void HTPParseMemcap(); -void *HTPMalloc(size_t size); -void *HTPRealloc(void *ptr, size_t orig_size, size_t size); -void HTPFree(void *ptr, size_t size); - -uint64_t HTPMemuseGlobalCounter(void); -uint64_t HTPMemcapGlobalCounter(void); diff --git a/framework/src/suricata/src/app-layer-htp-xff.c b/framework/src/suricata/src/app-layer-htp-xff.c deleted file mode 100644 index 96c6de48..00000000 --- a/framework/src/suricata/src/app-layer-htp-xff.c +++ /dev/null @@ -1,364 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ignacio Sanchez - * \author Duarte Silva - */ - -#include "suricata-common.h" -#include "conf.h" - -#include "app-layer-parser.h" -#include "app-layer-htp.h" -#include "app-layer-htp-xff.h" - -#include "util-misc.h" -#include "util-memrchr.h" -#include "util-unittest.h" - -/** XFF header value minimal length */ -#define XFF_CHAIN_MINLEN 7 -/** XFF header value maximum length */ -#define XFF_CHAIN_MAXLEN 256 -/** Default XFF header name */ -#define XFF_DEFAULT "X-Forwarded-For" - -/** \internal - * \brief parse XFF string - * \param input input string, might be modified - * \param output output buffer - * \param output_size size of output buffer - * \retval bool 1 ok, 0 fail - */ -static int ParseXFFString(char *input, char *output, int output_size) -{ - size_t len = strlen(input); - if (len == 0) - return 0; - - if (input[0] == '[') { - char *end = strchr(input, ']'); - if (end == NULL) // malformed, not closed - return 0; - - if (end != input+(len - 1)) { - SCLogDebug("data after closing bracket"); - // if we ever want to parse the port, we can do it here - } - - /* done, lets wrap up */ - input++; // skip past [ - *end = '\0'; // overwrite ], ignore anything after - - } else { - /* lets see if the xff string ends in a port */ - int c = 0; - int d = 0; - char *p = input; - while (*p != '\0') { - if (*p == ':') - c++; - if (*p == '.') - d++; - p++; - } - /* 3 dots: ipv4, one ':' port */ - if (d == 3 && c == 1) { - SCLogDebug("XFF w port %s", input); - char *x = strchr(input, ':'); - if (x) { - *x = '\0'; - SCLogDebug("XFF w/o port %s", input); - // if we ever want to parse the port, we can do it here - } - } - } - - SCLogDebug("XFF %s", input); - - /** Sanity check on extracted IP for IPv4 and IPv6 */ - uint32_t ip[4]; - if (inet_pton(AF_INET, input, ip) == 1 || - inet_pton(AF_INET6, input, ip) == 1) - { - strlcpy(output, input, output_size); - return 1; // OK - } - return 0; -} - -/** - * \brief Function to return XFF IP if any in the selected transaction. The - * caller needs to lock the flow. - * \retval 1 if the IP has been found and returned in dstbuf - * \retval 0 if the IP has not being found or error - */ -int HttpXFFGetIPFromTx(const Packet *p, uint64_t tx_id, HttpXFFCfg *xff_cfg, - char *dstbuf, int dstbuflen) -{ - uint8_t xff_chain[XFF_CHAIN_MAXLEN]; - HtpState *htp_state = NULL; - htp_tx_t *tx = NULL; - uint64_t total_txs = 0; - uint8_t *p_xff = NULL; - - htp_state = (HtpState *)FlowGetAppState(p->flow); - - if (htp_state == NULL) { - SCLogDebug("no http state, XFF IP cannot be retrieved"); - return 0; - } - - total_txs = AppLayerParserGetTxCnt(p->flow->proto, ALPROTO_HTTP, htp_state); - if (tx_id >= total_txs) - return 0; - - tx = AppLayerParserGetTx(p->flow->proto, ALPROTO_HTTP, htp_state, tx_id); - if (tx == NULL) { - SCLogDebug("tx is NULL, XFF cannot be retrieved"); - return 0; - } - - htp_header_t *h_xff = NULL; - if (tx->request_headers != NULL) { - h_xff = htp_table_get_c(tx->request_headers, xff_cfg->header); - } - - if (h_xff != NULL && bstr_len(h_xff->value) >= XFF_CHAIN_MINLEN && - bstr_len(h_xff->value) < XFF_CHAIN_MAXLEN) { - - memcpy(xff_chain, bstr_ptr(h_xff->value), bstr_len(h_xff->value)); - xff_chain[bstr_len(h_xff->value)]=0; - - if (xff_cfg->flags & XFF_REVERSE) { - /** Get the last IP address from the chain */ - p_xff = memrchr(xff_chain, ' ', bstr_len(h_xff->value)); - if (p_xff == NULL) { - p_xff = xff_chain; - } else { - p_xff++; - } - } - else { - /** Get the first IP address from the chain */ - p_xff = memchr(xff_chain, ',', bstr_len(h_xff->value)); - if (p_xff != NULL) { - xff_chain[bstr_len(h_xff->value) - (p_xff - xff_chain)]=0; - } - p_xff = xff_chain; - } - return ParseXFFString((char *)p_xff, dstbuf, dstbuflen); - } - return 0; -} - -/** - * \brief Function to return XFF IP if any. The caller needs to lock the flow. - * \retval 1 if the IP has been found and returned in dstbuf - * \retval 0 if the IP has not being found or error - */ -int HttpXFFGetIP(const Packet *p, HttpXFFCfg *xff_cfg, char *dstbuf, int dstbuflen) -{ - HtpState *htp_state = NULL; - uint64_t tx_id = 0; - uint64_t total_txs = 0; - - htp_state = (HtpState *)FlowGetAppState(p->flow); - if (htp_state == NULL) { - SCLogDebug("no http state, XFF IP cannot be retrieved"); - goto end; - } - - total_txs = AppLayerParserGetTxCnt(p->flow->proto, ALPROTO_HTTP, htp_state); - for (; tx_id < total_txs; tx_id++) { - if (HttpXFFGetIPFromTx(p, tx_id, xff_cfg, dstbuf, dstbuflen) == 1) - return 1; - } - -end: - return 0; // Not found -} - -/** - * \brief Function to return XFF configuration from a configuration node. - */ -void HttpXFFGetCfg(ConfNode *conf, HttpXFFCfg *result) -{ - BUG_ON(conf == NULL || result == NULL); - - ConfNode *xff_node = NULL; - - if (conf != NULL) - xff_node = ConfNodeLookupChild(conf, "xff"); - - if (xff_node != NULL && ConfNodeChildValueIsTrue(xff_node, "enabled")) { - const char *xff_mode = ConfNodeLookupChildValue(xff_node, "mode"); - - if (xff_mode != NULL && strcasecmp(xff_mode, "overwrite") == 0) { - result->flags |= XFF_OVERWRITE; - } else { - if (xff_mode == NULL) { - SCLogWarning(SC_WARN_XFF_INVALID_MODE, "The XFF mode hasn't been defined, falling back to extra-data mode"); - } - else if (strcasecmp(xff_mode, "extra-data") != 0) { - SCLogWarning(SC_WARN_XFF_INVALID_MODE, "The XFF mode %s is invalid, falling back to extra-data mode", - xff_mode); - } - result->flags |= XFF_EXTRADATA; - } - - const char *xff_deployment = ConfNodeLookupChildValue(xff_node, "deployment"); - - if (xff_deployment != NULL && strcasecmp(xff_deployment, "forward") == 0) { - result->flags |= XFF_FORWARD; - } else { - if (xff_deployment == NULL) { - SCLogWarning(SC_WARN_XFF_INVALID_DEPLOYMENT, "The XFF deployment hasn't been defined, falling back to reverse proxy deployment"); - } - else if (strcasecmp(xff_deployment, "reverse") != 0) { - SCLogWarning(SC_WARN_XFF_INVALID_DEPLOYMENT, "The XFF mode %s is invalid, falling back to reverse proxy deployment", - xff_deployment); - } - result->flags |= XFF_REVERSE; - } - - const char *xff_header = ConfNodeLookupChildValue(xff_node, "header"); - - if (xff_header != NULL) { - result->header = (char *) xff_header; - } else { - SCLogWarning(SC_WARN_XFF_INVALID_HEADER, "The XFF header hasn't been defined, using the default %s", - XFF_DEFAULT); - result->header = XFF_DEFAULT; - } - } - else { - result->flags = XFF_DISABLED; - } -} - - -#ifdef UNITTESTS -static int XFFTest01(void) { - char input[] = "1.2.3.4:5678"; - char output[16]; - int r = ParseXFFString(input, output, sizeof(output)); - if (r == 1 && strcmp(output, "1.2.3.4") == 0) { - return 1; - } - return 0; -} - -static int XFFTest02(void) { - char input[] = "[12::34]:1234"; // thanks chort! - char output[16]; - int r = ParseXFFString(input, output, sizeof(output)); - if (r == 1 && strcmp(output, "12::34") == 0) { - return 1; - } - return 0; -} - -static int XFFTest03(void) { - char input[] = "[2a03:2880:1010:3f02:face:b00c:0:2]:80"; // thanks chort! - char output[46]; - int r = ParseXFFString(input, output, sizeof(output)); - if (r == 1 && strcmp(output, "2a03:2880:1010:3f02:face:b00c:0:2") == 0) { - return 1; - } - return 0; -} - -static int XFFTest04(void) { - char input[] = "[2a03:2880:1010:3f02:face:b00c:0:2]"; // thanks chort! - char output[46]; - int r = ParseXFFString(input, output, sizeof(output)); - if (r == 1 && strcmp(output, "2a03:2880:1010:3f02:face:b00c:0:2") == 0) { - return 1; - } - return 0; -} - -static int XFFTest05(void) { - char input[] = "[::ffff:1.2.3.4]:1234"; // thanks double-p - char output[46]; - int r = ParseXFFString(input, output, sizeof(output)); - if (r == 1 && strcmp(output, "::ffff:1.2.3.4") == 0) { - return 1; - } - return 0; -} - -static int XFFTest06(void) { - char input[] = "12::34"; - char output[46]; - int r = ParseXFFString(input, output, sizeof(output)); - if (r == 1 && strcmp(output, "12::34") == 0) { - return 1; - } - return 0; -} - -static int XFFTest07(void) { - char input[] = "1.2.3.4"; - char output[46]; - int r = ParseXFFString(input, output, sizeof(output)); - if (r == 1 && strcmp(output, "1.2.3.4") == 0) { - return 1; - } - return 0; -} - -static int XFFTest08(void) { - char input[] = "[1.2.3.4:1234"; - char output[46]; - int r = ParseXFFString(input, output, sizeof(output)); - if (r == 0) { - return 1; - } - return 0; -} - -static int XFFTest09(void) { - char input[] = "999.999.999.999:1234"; - char output[46]; - int r = ParseXFFString(input, output, sizeof(output)); - if (r == 0) { - return 1; - } - return 0; -} - -#endif - -void HTPXFFParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("XFFTest01", XFFTest01, 1); - UtRegisterTest("XFFTest02", XFFTest02, 1); - UtRegisterTest("XFFTest03", XFFTest03, 1); - UtRegisterTest("XFFTest04", XFFTest04, 1); - UtRegisterTest("XFFTest05", XFFTest05, 1); - UtRegisterTest("XFFTest06", XFFTest06, 1); - UtRegisterTest("XFFTest07", XFFTest07, 1); - UtRegisterTest("XFFTest08", XFFTest08, 1); - UtRegisterTest("XFFTest09", XFFTest09, 1); -#endif -} diff --git a/framework/src/suricata/src/app-layer-htp-xff.h b/framework/src/suricata/src/app-layer-htp-xff.h deleted file mode 100644 index 1a3b67e1..00000000 --- a/framework/src/suricata/src/app-layer-htp-xff.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ignacio Sanchez - * \author Duarte Silva - */ - -#ifndef __APP_LAYER_HTP_XFF_H__ -#define __APP_LAYER_HTP_XFF_H__ - -/** XFF is disabled */ -#define XFF_DISABLED 1 -/** XFF extra data mode */ -#define XFF_EXTRADATA 2 -/** XFF overwrite mode */ -#define XFF_OVERWRITE 4 -/** XFF is to be used in a reverse proxy deployment */ -#define XFF_REVERSE 8 -/** XFF is to be used in a forward proxy deployment */ -#define XFF_FORWARD 16 -/** Single XFF IP maximum length (default value based on IPv6 address length) */ -#define XFF_MAXLEN 46 - -typedef struct HttpXFFCfg_ { - uint8_t flags; /**< XFF operation mode and deployment */ - char *header; /**< XFF header name */ -} HttpXFFCfg; - -void HttpXFFGetCfg(ConfNode *conf, HttpXFFCfg *result); - -int HttpXFFGetIPFromTx(const Packet *p, uint64_t tx_id, HttpXFFCfg *xff_cfg, char *dstbuf, int dstbuflen); - -int HttpXFFGetIP(const Packet *p, HttpXFFCfg *xff_cfg, char *dstbuf, int dstbuflen); - -void HTPXFFParserRegisterTests(void); - -#endif /* __APP_LAYER_HTP_XFF_H__ */ diff --git a/framework/src/suricata/src/app-layer-htp.c b/framework/src/suricata/src/app-layer-htp.c deleted file mode 100644 index e8da88eb..00000000 --- a/framework/src/suricata/src/app-layer-htp.c +++ /dev/null @@ -1,6525 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - -/** - * \file - * - * \author Victor Julien - * \author Gurvinder Singh - * \author Pablo Rincon - * \author Brian Rectanus - * \author Anoop Saldanha - * - * This file provides a HTTP protocol support for the engine using HTP library. - */ - -#include "suricata.h" -#include "suricata-common.h" -#include "conf.h" -#include "debug.h" -#include "decode.h" -#include "threads.h" -#include "counters.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-radix-tree.h" -#include "util-file.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" - -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-htp-body.h" -#include "app-layer-htp-file.h" -#include "app-layer-htp-libhtp.h" -#include "app-layer-htp-xff.h" - -#include "util-spm.h" -#include "util-debug.h" -#include "util-time.h" -#include "util-misc.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "flow-util.h" - -#include "detect-engine.h" -#include "detect-engine-state.h" -#include "detect-parse.h" - -#include "decode-events.h" - -#include "util-memcmp.h" - -//#define PRINT - -/** Fast lookup tree (radix) for the various HTP configurations */ -static SCRadixTree *cfgtree; -/** List of HTP configurations. */ -static HTPCfgRec cfglist; - -#ifdef DEBUG -static SCMutex htp_state_mem_lock = SCMUTEX_INITIALIZER; -static uint64_t htp_state_memuse = 0; -static uint64_t htp_state_memcnt = 0; -#endif - -SCEnumCharMap http_decoder_event_table[ ] = { - { "UNKNOWN_ERROR", - HTTP_DECODER_EVENT_UNKNOWN_ERROR}, - { "GZIP_DECOMPRESSION_FAILED", - HTTP_DECODER_EVENT_GZIP_DECOMPRESSION_FAILED}, - { "REQUEST_FIELD_MISSING_COLON", - HTTP_DECODER_EVENT_REQUEST_FIELD_MISSING_COLON}, - { "RESPONSE_FIELD_MISSING_COLON", - HTTP_DECODER_EVENT_RESPONSE_FIELD_MISSING_COLON}, - { "INVALID_REQUEST_CHUNK_LEN", - HTTP_DECODER_EVENT_INVALID_REQUEST_CHUNK_LEN}, - { "INVALID_RESPONSE_CHUNK_LEN", - HTTP_DECODER_EVENT_INVALID_RESPONSE_CHUNK_LEN}, - { "INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST", - HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST}, - { "INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE", - HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE}, - { "INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST", - HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST}, - { "INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE", - HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE}, - { "100_CONTINUE_ALREADY_SEEN", - HTTP_DECODER_EVENT_100_CONTINUE_ALREADY_SEEN}, - { "UNABLE_TO_MATCH_RESPONSE_TO_REQUEST", - HTTP_DECODER_EVENT_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST}, - { "INVALID_SERVER_PORT_IN_REQUEST", - HTTP_DECODER_EVENT_INVALID_SERVER_PORT_IN_REQUEST}, - { "INVALID_AUTHORITY_PORT", - HTTP_DECODER_EVENT_INVALID_AUTHORITY_PORT}, - { "REQUEST_HEADER_INVALID", - HTTP_DECODER_EVENT_REQUEST_HEADER_INVALID}, - { "RESPONSE_HEADER_INVALID", - HTTP_DECODER_EVENT_RESPONSE_HEADER_INVALID}, - { "MISSING_HOST_HEADER", - HTTP_DECODER_EVENT_MISSING_HOST_HEADER}, - { "HOST_HEADER_AMBIGUOUS", - HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS}, - { "INVALID_REQUEST_FIELD_FOLDING", - HTTP_DECODER_EVENT_INVALID_REQUEST_FIELD_FOLDING}, - { "INVALID_RESPONSE_FIELD_FOLDING", - HTTP_DECODER_EVENT_INVALID_RESPONSE_FIELD_FOLDING}, - { "REQUEST_FIELD_TOO_LONG", - HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG}, - { "RESPONSE_FIELD_TOO_LONG", - HTTP_DECODER_EVENT_RESPONSE_FIELD_TOO_LONG}, - { "REQUEST_SERVER_PORT_TCP_PORT_MISMATCH", - HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH}, - { "REQUEST_URI_HOST_INVALID", - HTTP_DECODER_EVENT_URI_HOST_INVALID}, - { "REQUEST_HEADER_HOST_INVALID", - HTTP_DECODER_EVENT_HEADER_HOST_INVALID}, - { "URI_DELIM_NON_COMPLIANT", - HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT}, - { "METHOD_DELIM_NON_COMPLIANT", - HTTP_DECODER_EVENT_METHOD_DELIM_NON_COMPLIANT}, - { "REQUEST_LINE_LEADING_WHITESPACE", - HTTP_DECODER_EVENT_REQUEST_LINE_LEADING_WHITESPACE}, - - /* suricata warnings/errors */ - { "MULTIPART_GENERIC_ERROR", - HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR}, - { "MULTIPART_NO_FILEDATA", - HTTP_DECODER_EVENT_MULTIPART_NO_FILEDATA}, - { "MULTIPART_INVALID_HEADER", - HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER}, - - { NULL, -1 }, -}; - -static void *HTPStateGetTx(void *alstate, uint64_t tx_id); -static int HTPStateGetAlstateProgress(void *tx, uint8_t direction); -static uint64_t HTPStateGetTxCnt(void *alstate); -static int HTPStateGetAlstateProgressCompletionStatus(uint8_t direction); - -#ifdef DEBUG -/** - * \internal - * - * \brief Lookup the HTP personality string from the numeric personality. - * - * \todo This needs to be a libhtp function. - */ -static const char *HTPLookupPersonalityString(int p) -{ -#define CASE_HTP_PERSONALITY_STRING(p) \ - case HTP_SERVER_ ## p: return #p - - switch (p) { - CASE_HTP_PERSONALITY_STRING(MINIMAL); - CASE_HTP_PERSONALITY_STRING(GENERIC); - CASE_HTP_PERSONALITY_STRING(IDS); - CASE_HTP_PERSONALITY_STRING(IIS_4_0); - CASE_HTP_PERSONALITY_STRING(IIS_5_0); - CASE_HTP_PERSONALITY_STRING(IIS_5_1); - CASE_HTP_PERSONALITY_STRING(IIS_6_0); - CASE_HTP_PERSONALITY_STRING(IIS_7_0); - CASE_HTP_PERSONALITY_STRING(IIS_7_5); - CASE_HTP_PERSONALITY_STRING(APACHE_2); - } - - return NULL; -} -#endif /* DEBUG */ - -/** - * \internal - * - * \brief Lookup the numeric HTP personality from a string. - * - * \todo This needs to be a libhtp function. - */ -static int HTPLookupPersonality(const char *str) -{ -#define IF_HTP_PERSONALITY_NUM(p) \ - if (strcasecmp(#p, str) == 0) return HTP_SERVER_ ## p - - IF_HTP_PERSONALITY_NUM(MINIMAL); - IF_HTP_PERSONALITY_NUM(GENERIC); - IF_HTP_PERSONALITY_NUM(IDS); - IF_HTP_PERSONALITY_NUM(IIS_4_0); - IF_HTP_PERSONALITY_NUM(IIS_5_0); - IF_HTP_PERSONALITY_NUM(IIS_5_1); - IF_HTP_PERSONALITY_NUM(IIS_6_0); - IF_HTP_PERSONALITY_NUM(IIS_7_0); - IF_HTP_PERSONALITY_NUM(IIS_7_5); - IF_HTP_PERSONALITY_NUM(APACHE_2); - if (strcasecmp("TOMCAT_6_0", str) == 0) { - SCLogError(SC_WARN_OPTION_OBSOLETE, "Personality %s no " - "longer supported by libhtp.", str); - return -1; - } else if ((strcasecmp("APACHE", str) == 0) || - (strcasecmp("APACHE_2_2", str) == 0)) - { - SCLogWarning(SC_WARN_OPTION_OBSOLETE, "Personality %s no " - "longer supported by libhtp, failing back to " - "Apache2 personality.", str); - return HTP_SERVER_APACHE_2; - } - - return -1; -} - -void HTPSetEvent(HtpState *s, HtpTxUserData *htud, uint8_t e) -{ - SCLogDebug("setting event %u", e); - - if (htud) { - AppLayerDecoderEventsSetEventRaw(&htud->decoder_events, e); - s->events++; - return; - } - - htp_tx_t *tx = HTPStateGetTx(s, s->transaction_cnt); - if (tx != NULL) { - htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (htud != NULL) { - AppLayerDecoderEventsSetEventRaw(&htud->decoder_events, e); - s->events++; - return; - } - } - SCLogDebug("couldn't set event %u", e); -} - -static int HTPHasEvents(void *state) -{ - HtpState *htp_state = (HtpState *)state; - return (htp_state->events > 0); -} - -static AppLayerDecoderEvents *HTPGetEvents(void *state, uint64_t tx_id) -{ - SCLogDebug("get HTTP events for TX %"PRIu64, tx_id); - - HtpState *s = (HtpState *)state; - htp_tx_t *tx = HTPStateGetTx(s, tx_id); - if (tx != NULL) { - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (htud != NULL) { - SCLogDebug("has htud, htud->decoder_events %p", htud->decoder_events); - return htud->decoder_events; - } - } - return NULL; -} - -/** \brief Function to allocates the HTTP state memory and also creates the HTTP - * connection parser to be used by the HTP library - */ -static void *HTPStateAlloc(void) -{ - SCEnter(); - - HtpState *s = HTPMalloc(sizeof(HtpState)); - if (unlikely(s == NULL)) - goto error; - - memset(s, 0x00, sizeof(HtpState)); - -#ifdef DEBUG - SCMutexLock(&htp_state_mem_lock); - htp_state_memcnt++; - htp_state_memuse += sizeof(HtpState); - SCLogDebug("htp memory %"PRIu64" (%"PRIu64")", htp_state_memuse, htp_state_memcnt); - SCMutexUnlock(&htp_state_mem_lock); -#endif - - SCReturnPtr((void *)s, "void"); - -error: - if (s != NULL) { - HTPFree(s, sizeof(HtpState)); - } - - SCReturnPtr(NULL, "void"); -} - -static void HtpTxUserDataFree(HtpState *state, HtpTxUserData *htud) -{ - if (likely(htud)) { - HtpBodyFree(&htud->request_body); - HtpBodyFree(&htud->response_body); - bstr_free(htud->request_uri_normalized); - if (htud->request_headers_raw) - HTPFree(htud->request_headers_raw, htud->request_headers_raw_len); - if (htud->response_headers_raw) - HTPFree(htud->response_headers_raw, htud->response_headers_raw_len); - AppLayerDecoderEventsFreeEvents(&htud->decoder_events); - if (htud->boundary) - HTPFree(htud->boundary, htud->boundary_len); - if (htud->de_state != NULL) { - if (likely(state != NULL)) { // should be impossible that it's null - BUG_ON(state->tx_with_detect_state_cnt == 0); - state->tx_with_detect_state_cnt--; - } - - DetectEngineStateFree(htud->de_state); - } - HTPFree(htud, sizeof(HtpTxUserData)); - } -} - -/** \brief Function to frees the HTTP state memory and also frees the HTTP - * connection parser memory which was used by the HTP library - */ -void HTPStateFree(void *state) -{ - SCEnter(); - - HtpState *s = (HtpState *)state; - if (s == NULL) { - SCReturn; - } - - /* Unset the body inspection */ - s->flags &=~ HTP_FLAG_NEW_BODY_SET; - - /* free the connection parser memory used by HTP library */ - if (s->connp != NULL) { - SCLogDebug("freeing HTP state"); - - uint64_t tx_id; - uint64_t total_txs = HTPStateGetTxCnt(state); - /* free the list of body chunks */ - if (s->conn != NULL) { - for (tx_id = 0; tx_id < total_txs; tx_id++) { - htp_tx_t *tx = HTPStateGetTx(s, tx_id); - if (tx != NULL) { - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - HtpTxUserDataFree(s, htud); - htp_tx_set_user_data(tx, NULL); - } - } - } - htp_connp_destroy_all(s->connp); - } - BUG_ON(s->tx_with_detect_state_cnt > 0); - - FileContainerFree(s->files_ts); - FileContainerFree(s->files_tc); - HTPFree(s, sizeof(HtpState)); - -#ifdef DEBUG - SCMutexLock(&htp_state_mem_lock); - htp_state_memcnt--; - htp_state_memuse -= sizeof(HtpState); - SCLogDebug("htp memory %"PRIu64" (%"PRIu64")", htp_state_memuse, htp_state_memcnt); - SCMutexUnlock(&htp_state_mem_lock); -#endif - - SCReturn; -} - -/** - * \brief HTP transaction cleanup callback - * - * \warning We cannot actually free the transactions here. It seems that - * HTP only accepts freeing of transactions in the response callback. - */ -static void HTPStateTransactionFree(void *state, uint64_t id) -{ - SCEnter(); - - HtpState *s = (HtpState *)state; - - SCLogDebug("state %p, id %"PRIu64, s, id); - - htp_tx_t *tx = HTPStateGetTx(s, id); - if (tx != NULL) { - /* This will remove obsolete body chunks */ - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - HtpTxUserDataFree(s, htud); - htp_tx_set_user_data(tx, NULL); - - /* hack: even if libhtp considers the tx incomplete, we want to - * free it here. htp_tx_destroy however, will refuse to do this. - * As htp_tx_destroy_incomplete isn't available in the public API, - * we hack around it here. */ - if (unlikely(!( - tx->request_progress == HTP_REQUEST_COMPLETE && - tx->response_progress == HTP_RESPONSE_COMPLETE))) - { - tx->request_progress = HTP_REQUEST_COMPLETE; - tx->response_progress = HTP_RESPONSE_COMPLETE; - } - htp_tx_destroy(tx); - } -} - -/** - * \brief Sets a flag that informs the HTP app layer that some module in the - * engine needs the http request body data. - * \initonly - */ -void AppLayerHtpEnableRequestBodyCallback(void) -{ - SCEnter(); - - SC_ATOMIC_OR(htp_config_flags, HTP_REQUIRE_REQUEST_BODY); - SCReturn; -} - -/** - * \brief Sets a flag that informs the HTP app layer that some module in the - * engine needs the http request body data. - * \initonly - */ -void AppLayerHtpEnableResponseBodyCallback(void) -{ - SCEnter(); - - SC_ATOMIC_OR(htp_config_flags, HTP_REQUIRE_RESPONSE_BODY); - SCReturn; -} - -/** - * \brief Sets a flag that informs the HTP app layer that some module in the - * engine needs the http request multi part header. - * - * \initonly - */ -void AppLayerHtpNeedMultipartHeader(void) -{ - SCEnter(); - AppLayerHtpEnableRequestBodyCallback(); - - SC_ATOMIC_OR(htp_config_flags, HTP_REQUIRE_REQUEST_MULTIPART); - SCReturn; -} - -/** - * \brief Sets a flag that informs the HTP app layer that some module in the - * engine needs the http request file. - * - * \initonly - */ -void AppLayerHtpNeedFileInspection(void) -{ - SCEnter(); - AppLayerHtpNeedMultipartHeader(); - AppLayerHtpEnableRequestBodyCallback(); - AppLayerHtpEnableResponseBodyCallback(); - - SC_ATOMIC_OR(htp_config_flags, HTP_REQUIRE_REQUEST_FILE); - SCReturn; -} - -/* below error messages updated up to libhtp 0.5.7 (git 379632278b38b9a792183694a4febb9e0dbd1e7a) */ -struct { - char *msg; - int de; -} htp_errors[] = { - { "GZip decompressor: inflateInit2 failed", HTTP_DECODER_EVENT_GZIP_DECOMPRESSION_FAILED}, - { "Request field invalid: colon missing", HTTP_DECODER_EVENT_REQUEST_FIELD_MISSING_COLON}, - { "Response field invalid: missing colon", HTTP_DECODER_EVENT_RESPONSE_FIELD_MISSING_COLON}, - { "Request chunk encoding: Invalid chunk length", HTTP_DECODER_EVENT_INVALID_REQUEST_CHUNK_LEN}, - { "Response chunk encoding: Invalid chunk length", HTTP_DECODER_EVENT_INVALID_RESPONSE_CHUNK_LEN}, -/* { "Invalid T-E value in request", HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST}, <- tx flag HTP_REQUEST_INVALID_T_E - { "Invalid T-E value in response", HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE}, <- nothing to replace it */ -/* { "Invalid C-L field in request", HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST}, <- tx flag HTP_REQUEST_INVALID_C_L */ - { "Invalid C-L field in response", HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE}, - { "Already seen 100-Continue", HTTP_DECODER_EVENT_100_CONTINUE_ALREADY_SEEN}, - { "Unable to match response to request", HTTP_DECODER_EVENT_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST}, - { "Invalid server port information in request", HTTP_DECODER_EVENT_INVALID_SERVER_PORT_IN_REQUEST}, -/* { "Invalid authority port", HTTP_DECODER_EVENT_INVALID_AUTHORITY_PORT}, htp no longer returns this error */ - { "Request buffer over", HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG}, - { "Response buffer over", HTTP_DECODER_EVENT_RESPONSE_FIELD_TOO_LONG}, -}; - -struct { - char *msg; - int de; -} htp_warnings[] = { - { "GZip decompressor:", HTTP_DECODER_EVENT_GZIP_DECOMPRESSION_FAILED}, - { "Request field invalid", HTTP_DECODER_EVENT_REQUEST_HEADER_INVALID}, - { "Response field invalid", HTTP_DECODER_EVENT_RESPONSE_HEADER_INVALID}, - { "Request header name is not a token", HTTP_DECODER_EVENT_REQUEST_HEADER_INVALID}, - { "Response header name is not a token", HTTP_DECODER_EVENT_RESPONSE_HEADER_INVALID}, -/* { "Host information in request headers required by HTTP/1.1", HTTP_DECODER_EVENT_MISSING_HOST_HEADER}, <- tx flag HTP_HOST_MISSING - { "Host information ambiguous", HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS}, <- tx flag HTP_HOST_AMBIGUOUS */ - { "Invalid request field folding", HTTP_DECODER_EVENT_INVALID_REQUEST_FIELD_FOLDING}, - { "Invalid response field folding", HTTP_DECODER_EVENT_INVALID_RESPONSE_FIELD_FOLDING}, - /* line is now: htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Request server port=%d number differs from the actual TCP port=%d", port, connp->conn->server_port); - * luckily, "Request server port=" is unique */ -/* { "Request server port number differs from the actual TCP port", HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH}, */ - { "Request server port=", HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH}, - { "Request line: URI contains non-compliant delimiter", HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT}, - { "Request line: non-compliant delimiter between Method and URI", HTTP_DECODER_EVENT_METHOD_DELIM_NON_COMPLIANT}, - { "Request line: leading whitespace", HTTP_DECODER_EVENT_REQUEST_LINE_LEADING_WHITESPACE}, -}; - -#define HTP_ERROR_MAX (sizeof(htp_errors) / sizeof(htp_errors[0])) -#define HTP_WARNING_MAX (sizeof(htp_warnings) / sizeof(htp_warnings[0])) - -/** - * \internal - * - * \brief Get the warning id for the warning msg. - * - * \param msg warning message - * - * \retval id the id or 0 in case of not found - */ -static int HTPHandleWarningGetId(const char *msg) -{ - SCLogDebug("received warning \"%s\"", msg); - size_t idx; - for (idx = 0; idx < HTP_WARNING_MAX; idx++) { - if (strncmp(htp_warnings[idx].msg, msg, - strlen(htp_warnings[idx].msg)) == 0) - { - return htp_warnings[idx].de; - } - } - - return 0; -} - -/** - * \internal - * - * \brief Get the error id for the error msg. - * - * \param msg error message - * - * \retval id the id or 0 in case of not found - */ -static int HTPHandleErrorGetId(const char *msg) -{ - SCLogDebug("received error \"%s\"", msg); - - size_t idx; - for (idx = 0; idx < HTP_ERROR_MAX; idx++) { - if (strncmp(htp_errors[idx].msg, msg, - strlen(htp_errors[idx].msg)) == 0) - { - return htp_errors[idx].de; - } - } - - return 0; -} - -/** - * \internal - * - * \brief Check state for errors, warnings and add any as events - * - * \param s state - */ -static void HTPHandleError(HtpState *s) -{ - if (s == NULL || s->conn == NULL || - s->conn->messages == NULL) { - return; - } - - size_t size = htp_list_size(s->conn->messages); - size_t msg; - - for (msg = s->htp_messages_offset; msg < size; msg++) { - htp_log_t *log = htp_list_get(s->conn->messages, msg); - if (log == NULL) - continue; - - HtpTxUserData *htud = NULL; - htp_tx_t *tx = log->tx; // will be NULL in <=0.5.9 - if (tx != NULL) - htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - - SCLogDebug("message %s", log->msg); - - int id = HTPHandleErrorGetId(log->msg); - if (id == 0) { - id = HTPHandleWarningGetId(log->msg); - if (id == 0) - id = HTTP_DECODER_EVENT_UNKNOWN_ERROR; - } - - if (id > 0) { - HTPSetEvent(s, htud, id); - } - } - s->htp_messages_offset = (uint16_t)msg; - SCLogDebug("s->htp_messages_offset %u", s->htp_messages_offset); -} - -static inline void HTPErrorCheckTxRequestFlags(HtpState *s, htp_tx_t *tx) -{ -#ifdef DEBUG - BUG_ON(s == NULL || tx == NULL); -#endif - if (tx->flags & ( HTP_REQUEST_INVALID_T_E|HTP_REQUEST_INVALID_C_L| - HTP_HOST_MISSING|HTP_HOST_AMBIGUOUS|HTP_HOSTU_INVALID| - HTP_HOSTH_INVALID)) - { - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (htud == NULL) - return; - - if (tx->flags & HTP_REQUEST_INVALID_T_E) - HTPSetEvent(s, htud, - HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST); - if (tx->flags & HTP_REQUEST_INVALID_C_L) - HTPSetEvent(s, htud, - HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST); - if (tx->flags & HTP_HOST_MISSING) - HTPSetEvent(s, htud, - HTTP_DECODER_EVENT_MISSING_HOST_HEADER); - if (tx->flags & HTP_HOST_AMBIGUOUS) - HTPSetEvent(s, htud, - HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS); - if (tx->flags & HTP_HOSTU_INVALID) - HTPSetEvent(s, htud, - HTTP_DECODER_EVENT_URI_HOST_INVALID); - if (tx->flags & HTP_HOSTH_INVALID) - HTPSetEvent(s, htud, - HTTP_DECODER_EVENT_HEADER_HOST_INVALID); - } -} - -/** - * \brief Function to handle the reassembled data from client and feed it to - * the HTP library to process it. - * - * \param flow Pointer to the flow the data belong to - * \param htp_state Pointer the state in which the parsed value to be stored - * \param pstate Application layer parser state for this session - * \param input Pointer the received HTTP client data - * \param input_len Length in bytes of the received data - * \param output Pointer to the output (not used in this function) - * - * \retval On success returns 1 or on failure returns -1. - */ -static int HTPHandleRequestData(Flow *f, void *htp_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SCEnter(); - int r = -1; - int ret = 1; - - //PrintRawDataFp(stdout, input, input_len); - - HtpState *hstate = (HtpState *)htp_state; - hstate->f = f; - - /* On the first invocation, create the connection parser structure to - * be used by HTP library. This is looked up via IP in the radix - * tree. Failing that, the default HTP config is used. - */ - if (NULL == hstate->conn) { - HTPCfgRec *htp_cfg_rec = &cfglist; - htp_cfg_t *htp = cfglist.cfg; /* Default to the global HTP config */ - void *user_data = NULL; - - if (FLOW_IS_IPV4(f)) { - SCLogDebug("Looking up HTP config for ipv4 %08x", *GET_IPV4_DST_ADDR_PTR(f)); - (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)GET_IPV4_DST_ADDR_PTR(f), cfgtree, &user_data); - } - else if (FLOW_IS_IPV6(f)) { - SCLogDebug("Looking up HTP config for ipv6"); - (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)GET_IPV6_DST_ADDR(f), cfgtree, &user_data); - } - else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "unknown address family, bug!"); - goto error; - } - - if (user_data != NULL) { - htp_cfg_rec = user_data; - htp = htp_cfg_rec->cfg; - SCLogDebug("LIBHTP using config: %p", htp); - } else { - SCLogDebug("Using default HTP config: %p", htp); - } - - if (NULL == htp) { -#ifdef DEBUG_VALIDATION - BUG_ON(htp == NULL); -#endif - /* should never happen if HTPConfigure is properly invoked */ - goto error; - } - - hstate->connp = htp_connp_create(htp); - if (hstate->connp == NULL) { - goto error; - } - - hstate->conn = htp_connp_get_connection(hstate->connp); - - htp_connp_set_user_data(hstate->connp, (void *)hstate); - hstate->cfg = htp_cfg_rec; - - SCLogDebug("New hstate->connp %p", hstate->connp); - } - - /* the code block above should make sure connp is never NULL here */ -#ifdef DEBUG_VALIDATION - BUG_ON(hstate->connp == NULL); -#endif - - /* Unset the body inspection (the callback should - * reactivate it if necessary) */ - hstate->flags &=~ HTP_FLAG_NEW_BODY_SET; - - /* Open the HTTP connection on receiving the first request */ - if (!(hstate->flags & HTP_FLAG_STATE_OPEN)) { - SCLogDebug("opening htp handle at %p", hstate->connp); - - htp_connp_open(hstate->connp, NULL, f->sp, NULL, f->dp, &f->startts); - hstate->flags |= HTP_FLAG_STATE_OPEN; - } else { - SCLogDebug("using existing htp handle at %p", hstate->connp); - } - - htp_time_t ts = { f->lastts.tv_sec, f->lastts.tv_usec }; - /* pass the new data to the htp parser */ - if (input_len > 0) { - r = htp_connp_req_data(hstate->connp, &ts, input, input_len); - - switch(r) { - case HTP_STREAM_ERROR: - - hstate->flags |= HTP_FLAG_STATE_ERROR; - hstate->flags &= ~HTP_FLAG_STATE_DATA; - hstate->flags &= ~HTP_FLAG_NEW_BODY_SET; - ret = -1; - break; - case HTP_STREAM_DATA: - case HTP_STREAM_DATA_OTHER: - - hstate->flags |= HTP_FLAG_STATE_DATA; - break; - case HTP_STREAM_TUNNEL: - break; - default: - hstate->flags &= ~HTP_FLAG_STATE_DATA; - hstate->flags &= ~HTP_FLAG_NEW_BODY_SET; - } - HTPHandleError(hstate); - } - - /* if the TCP connection is closed, then close the HTTP connection */ - if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF) && - !(hstate->flags & HTP_FLAG_STATE_CLOSED_TS)) - { - htp_connp_close(hstate->connp, &ts); - hstate->flags |= HTP_FLAG_STATE_CLOSED_TS; - SCLogDebug("stream eof encountered, closing htp handle for ts"); - } - - SCLogDebug("hstate->connp %p", hstate->connp); - SCReturnInt(ret); - -error: - SCReturnInt(-1); -} - -/** - * \brief Function to handle the reassembled data from server and feed it to - * the HTP library to process it. - * - * \param flow Pointer to the flow the data belong to - * \param htp_state Pointer the state in which the parsed value to be stored - * \param pstate Application layer parser state for this session - * \param input Pointer the received HTTP server data - * \param input_len Length in bytes of the received data - * \param output Pointer to the output (not used in this function) - * - * \retval On success returns 1 or on failure returns -1 - */ -static int HTPHandleResponseData(Flow *f, void *htp_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SCEnter(); - int r = -1; - int ret = 1; - - HtpState *hstate = (HtpState *)htp_state; - hstate->f = f; - if (hstate->connp == NULL) { - SCLogDebug("HTP state has no connp"); - /* till we have the new libhtp changes that allow response first, - * let's take response in first. */ - //BUG_ON(1); - SCReturnInt(-1); - } - - /* Unset the body inspection (the callback should - * reactivate it if necessary) */ - hstate->flags &=~ HTP_FLAG_NEW_BODY_SET; - - htp_time_t ts = { f->lastts.tv_sec, f->lastts.tv_usec }; - if (input_len > 0) { - r = htp_connp_res_data(hstate->connp, &ts, input, input_len); - switch(r) { - case HTP_STREAM_ERROR: - hstate->flags = HTP_FLAG_STATE_ERROR; - hstate->flags &= ~HTP_FLAG_STATE_DATA; - hstate->flags &= ~HTP_FLAG_NEW_BODY_SET; - ret = -1; - break; - case HTP_STREAM_DATA: - case HTP_STREAM_DATA_OTHER: - hstate->flags |= HTP_FLAG_STATE_DATA; - break; - case HTP_STREAM_TUNNEL: - break; - default: - hstate->flags &= ~HTP_FLAG_STATE_DATA; - hstate->flags &= ~HTP_FLAG_NEW_BODY_SET; - } - HTPHandleError(hstate); - } - - /* if we the TCP connection is closed, then close the HTTP connection */ - if (AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF) && - !(hstate->flags & HTP_FLAG_STATE_CLOSED_TC)) - { - htp_connp_close(hstate->connp, &ts); - hstate->flags |= HTP_FLAG_STATE_CLOSED_TC; - } - - SCLogDebug("hstate->connp %p", hstate->connp); - SCReturnInt(ret); -} - -/** - * \param name /Lowercase/ version of the variable name - */ -static int HTTPParseContentDispositionHeader(uint8_t *name, size_t name_len, - uint8_t *data, size_t len, uint8_t **retptr, size_t *retlen) -{ -#ifdef PRINT - printf("DATA START: \n"); - PrintRawDataFp(stdout, data, len); - printf("DATA END: \n"); -#endif - size_t x; - int quote = 0; - - for (x = 0; x < len; x++) { - if (!(isspace(data[x]))) - break; - } - - if (x >= len) - return 0; - - uint8_t *line = data+x; - size_t line_len = len-x; - size_t offset = 0; -#ifdef PRINT - printf("LINE START: \n"); - PrintRawDataFp(stdout, line, line_len); - printf("LINE END: \n"); -#endif - for (x = 0 ; x < line_len; x++) { - if (x > 0) { - if (line[x - 1] != '\\' && line[x] == '\"') { - quote++; - } - - if (((line[x - 1] != '\\' && line[x] == ';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) { - uint8_t *token = line + offset; - size_t token_len = x - offset; - - if ((x + 1) == line_len) { - token_len++; - } - - offset = x + 1; - - while (offset < line_len && isspace(line[offset])) { - x++; - offset++; - } -#ifdef PRINT - printf("TOKEN START: \n"); - PrintRawDataFp(stdout, token, token_len); - printf("TOKEN END: \n"); -#endif - if (token_len > name_len) { - if (name == NULL || SCMemcmpLowercase(name, token, name_len) == 0) { - uint8_t *value = token + name_len; - size_t value_len = token_len - name_len; - - if (value[0] == '\"') { - value++; - value_len--; - } - if (value[value_len-1] == '\"') { - value_len--; - } -#ifdef PRINT - printf("VALUE START: \n"); - PrintRawDataFp(stdout, value, value_len); - printf("VALUE END: \n"); -#endif - *retptr = value; - *retlen = value_len; - return 1; - } - } - } - } - } - - return 0; -} - -/** - * \param name /Lowercase/ version of the variable name - */ -static int HTTPParseContentTypeHeader(uint8_t *name, size_t name_len, - uint8_t *data, size_t len, uint8_t **retptr, size_t *retlen) -{ - SCEnter(); -#ifdef PRINT - printf("DATA START: \n"); - PrintRawDataFp(stdout, data, len); - printf("DATA END: \n"); -#endif - size_t x; - int quote = 0; - - for (x = 0; x < len; x++) { - if (!(isspace(data[x]))) - break; - } - - if (x >= len) { - SCReturnInt(0); - } - - uint8_t *line = data+x; - size_t line_len = len-x; - size_t offset = 0; -#ifdef PRINT - printf("LINE START: \n"); - PrintRawDataFp(stdout, line, line_len); - printf("LINE END: \n"); -#endif - for (x = 0 ; x < line_len; x++) { - if (x > 0) { - if (line[x - 1] != '\\' && line[x] == '\"') { - quote++; - } - - if (((line[x - 1] != '\\' && line[x] == ';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) { - uint8_t *token = line + offset; - size_t token_len = x - offset; - - if ((x + 1) == line_len) { - token_len++; - } - - offset = x + 1; - - while (offset < line_len && isspace(line[offset])) { - x++; - offset++; - } -#ifdef PRINT - printf("TOKEN START: \n"); - PrintRawDataFp(stdout, token, token_len); - printf("TOKEN END: \n"); -#endif - if (token_len > name_len) { - if (name == NULL || SCMemcmpLowercase(name, token, name_len) == 0) { - uint8_t *value = token + name_len; - size_t value_len = token_len - name_len; - - if (value[0] == '\"') { - value++; - value_len--; - } - if (value[value_len-1] == '\"') { - value_len--; - } -#ifdef PRINT - printf("VALUE START: \n"); - PrintRawDataFp(stdout, value, value_len); - printf("VALUE END: \n"); -#endif - *retptr = value; - *retlen = value_len; - SCReturnInt(1); - } - } - } - } - } - - SCReturnInt(0); -} - -/** - * \brief setup multipart parsing: extract boundary and store it - * - * \param d HTTP transaction - * \param htud transaction userdata - * - * \retval 1 ok, multipart set up - * \retval 0 ok, not multipart though - * \retval -1 error: problem with the boundary - * - * If the request contains a multipart message, this function will - * set the HTP_BOUNDARY_SET in the transaction. - */ -static int HtpRequestBodySetupMultipart(htp_tx_data_t *d, HtpTxUserData *htud) -{ - htp_header_t *h = (htp_header_t *)htp_table_get_c(d->tx->request_headers, - "Content-Type"); - if (h != NULL && bstr_len(h->value) > 0) { - uint8_t *boundary = NULL; - size_t boundary_len = 0; - - int r = HTTPParseContentTypeHeader((uint8_t *)"boundary=", 9, - (uint8_t *) bstr_ptr(h->value), bstr_len(h->value), - &boundary, &boundary_len); - if (r == 1) { -#ifdef PRINT - printf("BOUNDARY START: \n"); - PrintRawDataFp(stdout, boundary, boundary_len); - printf("BOUNDARY END: \n"); -#endif - if (boundary_len < HTP_BOUNDARY_MAX) { - htud->boundary = HTPMalloc(boundary_len); - if (htud->boundary == NULL) { - return -1; - } - htud->boundary_len = (uint8_t)boundary_len; - memcpy(htud->boundary, boundary, boundary_len); - - htud->tsflags |= HTP_BOUNDARY_SET; - } else { - SCLogDebug("invalid boundary"); - return -1; - } - SCReturnInt(1); - } - //SCReturnInt(1); - } - SCReturnInt(0); -} - -/** - * \brief Setup boundary buffers - */ -static int HtpRequestBodySetupBoundary(HtpTxUserData *htud, - uint8_t **expected_boundary, uint8_t *expected_boundary_len, - uint8_t **expected_boundary_end, uint8_t *expected_boundary_end_len) -{ - uint8_t *eb = NULL; - uint8_t *ebe = NULL; - - uint8_t eb_len = htud->boundary_len + 2; - eb = (uint8_t *)HTPMalloc(eb_len); - if (eb == NULL) { - goto error; - } - memset(eb, '-', eb_len); - memcpy(eb + 2, htud->boundary, htud->boundary_len); - - uint8_t ebe_len = htud->boundary_len + 4; - ebe = (uint8_t *)HTPMalloc(ebe_len); - if (ebe == NULL) { - goto error; - } - memset(ebe, '-', ebe_len); - memcpy(ebe + 2, htud->boundary, htud->boundary_len); - - *expected_boundary = eb; - *expected_boundary_len = eb_len; - *expected_boundary_end = ebe; - *expected_boundary_end_len = ebe_len; - - SCReturnInt(0); - -error: - if (eb != NULL) { - HTPFree(eb, eb_len); - } - if (ebe != NULL) { - HTPFree(ebe, ebe_len); - } - SCReturnInt(-1); -} - -#define C_D_HDR "content-disposition:" -#define C_D_HDR_LEN 20 -#define C_T_HDR "content-type:" -#define C_T_HDR_LEN 13 - -static void HtpRequestBodyMultipartParseHeader(HtpState *hstate, - HtpTxUserData *htud, - uint8_t *header, uint32_t header_len, - uint8_t **filename, uint16_t *filename_len, - uint8_t **filetype, uint16_t *filetype_len) -{ - uint8_t *fn = NULL; - size_t fn_len = 0; - uint8_t *ft = NULL; - size_t ft_len = 0; - -#ifdef PRINT - printf("HEADER START: \n"); - PrintRawDataFp(stdout, header, header_len); - printf("HEADER END: \n"); -#endif - - while (header_len > 0) { - uint8_t *next_line = Bs2bmSearch(header, header_len, (uint8_t *)"\r\n", 2); - uint8_t *line = header; - uint32_t line_len; - - if (next_line == NULL) { - line_len = header_len; - } else { - line_len = next_line - header; - } - uint8_t *sc = (uint8_t *)memchr(line, ':', line_len); - if (sc == NULL) { - HTPSetEvent(hstate, htud, - HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER); - /* if the : we found is the final char, it means we have - * no value */ - } else if (line_len > 0 && sc == &line[line_len - 1]) { - HTPSetEvent(hstate, htud, - HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER); - } else { -#ifdef PRINT - printf("LINE START: \n"); - PrintRawDataFp(stdout, line, line_len); - printf("LINE END: \n"); -#endif - if (line_len >= C_D_HDR_LEN && - SCMemcmpLowercase(C_D_HDR, line, C_D_HDR_LEN) == 0) { - uint8_t *value = line + C_D_HDR_LEN; - uint32_t value_len = line_len - C_D_HDR_LEN; - - /* parse content-disposition */ - (void)HTTPParseContentDispositionHeader((uint8_t *)"filename=", 9, - value, value_len, &fn, &fn_len); - } else if (line_len >= C_T_HDR_LEN && - SCMemcmpLowercase(C_T_HDR, line, C_T_HDR_LEN) == 0) { - SCLogDebug("content-type line"); - uint8_t *value = line + C_T_HDR_LEN; - uint32_t value_len = line_len - C_T_HDR_LEN; - - (void)HTTPParseContentTypeHeader(NULL, 0, - value, value_len, &ft, &ft_len); - } - } - - if (next_line == NULL) { - SCLogDebug("no next_line"); - break; - } - header_len -= ((next_line + 2) - header); - header = next_line + 2; - } /* while (header_len > 0) */ - - if (fn_len > USHRT_MAX) - fn_len = USHRT_MAX; - if (ft_len > USHRT_MAX) - ft_len = USHRT_MAX; - - *filename = fn; - *filename_len = fn_len; - *filetype = ft; - *filetype_len = ft_len; -} - -/** - * \brief Create a single buffer from the HtpBodyChunks in our list - * - * \param htud transaction user data - * \param chunks_buffers pointer to pass back the buffer to the caller - * \param chunks_buffer_len pointer to pass back the buffer length to the caller - */ -static void HtpRequestBodyReassemble(HtpTxUserData *htud, - uint8_t **chunks_buffer, uint32_t *chunks_buffer_len) -{ - uint8_t *buf = NULL; - uint8_t *pbuf = NULL; - uint32_t buf_len = 0; - HtpBodyChunk *cur = htud->request_body.first; - - for ( ; cur != NULL; cur = cur->next) { - SCLogDebug("chunk %p", cur); - - /* skip body chunks entirely before what we parsed already */ - if ((uint64_t )cur->stream_offset + cur->len <= htud->request_body.body_parsed) { - SCLogDebug("skipping chunk"); - continue; - } - - SCLogDebug("cur->stream_offset %"PRIu64", cur->len %"PRIu32", body_parsed %"PRIu64, - cur->stream_offset, cur->len, htud->request_body.body_parsed); - - if (cur->stream_offset < htud->request_body.body_parsed && - cur->stream_offset + cur->len >= htud->request_body.body_parsed) { - SCLogDebug("use part"); - - uint32_t toff = htud->request_body.body_parsed - cur->stream_offset; - uint32_t tlen = (cur->stream_offset + cur->len) - htud->request_body.body_parsed; - uint8_t *pbuf = NULL; - - buf_len += tlen; - if ((pbuf = HTPRealloc(buf, buf_len - tlen, buf_len)) == NULL) { - HTPFree(buf, buf_len - tlen); - buf = NULL; - buf_len = 0; - break; - } - buf = pbuf; - memcpy(buf + buf_len - tlen, cur->data + toff, tlen); - - } else { - SCLogDebug("use entire chunk"); - - buf_len += cur->len; - if ((pbuf = HTPRealloc(buf, buf_len - cur->len, buf_len)) == NULL) { - HTPFree(buf, buf_len - cur->len); - buf = NULL; - buf_len = 0; - break; - } - buf = pbuf; - memcpy(buf + buf_len - cur->len, cur->data, cur->len); - } - } - - *chunks_buffer = buf; - *chunks_buffer_len = buf_len; -} - -int HtpRequestBodyHandleMultipart(HtpState *hstate, HtpTxUserData *htud, - void *tx, uint8_t *chunks_buffer, uint32_t chunks_buffer_len) -{ - int result = 0; - uint8_t *expected_boundary = NULL; - uint8_t *expected_boundary_end = NULL; - uint8_t expected_boundary_len = 0; - uint8_t expected_boundary_end_len = 0; - int tx_progress = 0; - -#ifdef PRINT - printf("CHUNK START: \n"); - PrintRawDataFp(stdout, chunks_buffer, chunks_buffer_len); - printf("CHUNK END: \n"); -#endif - - if (HtpRequestBodySetupBoundary(htud, &expected_boundary, &expected_boundary_len, - &expected_boundary_end, &expected_boundary_end_len) < 0) { - goto end; - } - - /* search for the header start, header end and form end */ - uint8_t *header_start = Bs2bmSearch(chunks_buffer, chunks_buffer_len, - expected_boundary, expected_boundary_len); - uint8_t *header_end = NULL; - if (header_start != NULL) { - header_end = Bs2bmSearch(header_start, chunks_buffer_len - (header_start - chunks_buffer), - (uint8_t *)"\r\n\r\n", 4); - } - uint8_t *form_end = Bs2bmSearch(chunks_buffer, chunks_buffer_len, - expected_boundary_end, expected_boundary_end_len); - - SCLogDebug("header_start %p, header_end %p, form_end %p", header_start, - header_end, form_end); - - /* we currently only handle multipart for ts. When we support it for tc, - * we will need to supply right direction */ - tx_progress = AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOSERVER); - /* if we're in the file storage process, deal with that now */ - if (htud->tsflags & HTP_FILENAME_SET) { - if (header_start != NULL || form_end != NULL || (tx_progress > HTP_REQUEST_BODY)) { - SCLogDebug("reached the end of the file"); - - uint8_t *filedata = chunks_buffer; - uint32_t filedata_len = 0; - uint8_t flags = 0; - - if (header_start < form_end || (header_start != NULL && form_end == NULL)) { - filedata_len = header_start - filedata - 2; /* 0d 0a */ - } else if (form_end != NULL && form_end < header_start) { - filedata_len = form_end - filedata; - } else if (form_end != NULL && form_end == header_start) { - filedata_len = form_end - filedata - 2; /* 0d 0a */ - } else if (tx_progress > HTP_RESPONSE_BODY) { - filedata_len = chunks_buffer_len; - flags = FILE_TRUNCATED; - } - - if (filedata_len > chunks_buffer_len) { - HTPSetEvent(hstate, htud, - HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR); - goto end; - } -#ifdef PRINT - printf("FILEDATA (final chunk) START: \n"); - PrintRawDataFp(stdout, filedata, filedata_len); - printf("FILEDATA (final chunk) END: \n"); -#endif - if (!(htud->tsflags & HTP_DONTSTORE)) { - if (HTPFileClose(hstate, filedata, filedata_len, flags, - STREAM_TOSERVER) == -1) - { - goto end; - } - } - - htud->tsflags &=~ HTP_FILENAME_SET; - - /* fall through */ - } else { - SCLogDebug("not yet at the end of the file"); - - if (chunks_buffer_len > expected_boundary_end_len) { - uint8_t *filedata = chunks_buffer; - uint32_t filedata_len = chunks_buffer_len - expected_boundary_len; -#ifdef PRINT - printf("FILEDATA (part) START: \n"); - PrintRawDataFp(stdout, filedata, filedata_len); - printf("FILEDATA (part) END: \n"); -#endif - - if (!(htud->tsflags & HTP_DONTSTORE)) { - result = HTPFileStoreChunk(hstate, filedata, - filedata_len, STREAM_TOSERVER); - if (result == -1) { - goto end; - } else if (result == -2) { - /* we know for sure we're not storing the file */ - htud->tsflags |= HTP_DONTSTORE; - } - } - - htud->request_body.body_parsed += filedata_len; - } else { - SCLogDebug("chunk too small to already process in part"); - } - - goto end; - } - } - - while (header_start != NULL && header_end != NULL && - header_end != form_end && - header_start < (chunks_buffer + chunks_buffer_len) && - header_end < (chunks_buffer + chunks_buffer_len) && - header_start < header_end) - { - uint8_t *filename = NULL; - uint16_t filename_len = 0; - uint8_t *filetype = NULL; - uint16_t filetype_len = 0; - - uint32_t header_len = header_end - header_start; - SCLogDebug("header_len %u", header_len); - uint8_t *header = header_start; - - /* skip empty records */ - if (expected_boundary_len == header_len) { - goto next; - } else if ((uint32_t)(expected_boundary_len + 2) <= header_len) { - header_len -= (expected_boundary_len + 2); - header = header_start + (expected_boundary_len + 2); // + for 0d 0a - } - - HtpRequestBodyMultipartParseHeader(hstate, htud, header, header_len, - &filename, &filename_len, &filetype, &filetype_len); - - if (filename != NULL) { - uint8_t *filedata = NULL; - uint32_t filedata_len = 0; - - SCLogDebug("we have a filename"); - - htud->tsflags |= HTP_FILENAME_SET; - htud->tsflags &= ~HTP_DONTSTORE; - - SCLogDebug("header_end %p", header_end); - SCLogDebug("form_end %p", form_end); - - /* everything until the final boundary is the file */ - if (form_end != NULL) { - filedata = header_end + 4; - if (form_end == filedata) { - HTPSetEvent(hstate, htud, - HTTP_DECODER_EVENT_MULTIPART_NO_FILEDATA); - goto end; - } else if (form_end < filedata) { - HTPSetEvent(hstate, htud, - HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR); - goto end; - } - - filedata_len = form_end - (header_end + 4 + 2); - SCLogDebug("filedata_len %"PRIuMAX, (uintmax_t)filedata_len); - - /* or is it? */ - uint8_t *header_next = Bs2bmSearch(filedata, filedata_len, - expected_boundary, expected_boundary_len); - if (header_next != NULL) { - filedata_len -= (form_end - header_next); - } - - if (filedata_len > chunks_buffer_len) { - HTPSetEvent(hstate, htud, - HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR); - goto end; - } - SCLogDebug("filedata_len %"PRIuMAX, (uintmax_t)filedata_len); -#ifdef PRINT - printf("FILEDATA START: \n"); - PrintRawDataFp(stdout, filedata, filedata_len); - printf("FILEDATA END: \n"); -#endif - - result = HTPFileOpen(hstate, filename, filename_len, - filedata, filedata_len, hstate->transaction_cnt, - STREAM_TOSERVER); - if (result == -1) { - goto end; - } else if (result == -2) { - htud->tsflags |= HTP_DONTSTORE; - } else { - if (HTPFileClose(hstate, NULL, 0, 0, STREAM_TOSERVER) == -1) { - goto end; - } - } - - htud->request_body.body_parsed += (header_end - chunks_buffer); - htud->tsflags &= ~HTP_FILENAME_SET; - } else { - SCLogDebug("chunk doesn't contain form end"); - - filedata = header_end + 4; - filedata_len = chunks_buffer_len - (filedata - chunks_buffer); - SCLogDebug("filedata_len %u (chunks_buffer_len %u)", filedata_len, chunks_buffer_len); - - if (filedata_len > chunks_buffer_len) { - HTPSetEvent(hstate, htud, - HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR); - goto end; - } - -#ifdef PRINT - printf("FILEDATA START: \n"); - PrintRawDataFp(stdout, filedata, filedata_len); - printf("FILEDATA END: \n"); -#endif - /* form doesn't end in this chunk, but part might. Lets - * see if have another coming up */ - uint8_t *header_next = Bs2bmSearch(filedata, filedata_len, - expected_boundary, expected_boundary_len); - SCLogDebug("header_next %p", header_next); - if (header_next == NULL) { - /* no, but we'll handle the file data when we see the - * form_end */ - - SCLogDebug("more file data to come"); - - uint32_t offset = (header_end + 4) - chunks_buffer; - SCLogDebug("offset %u", offset); - htud->request_body.body_parsed += offset; - - result = HTPFileOpen(hstate, filename, filename_len, - NULL, 0, hstate->transaction_cnt, - STREAM_TOSERVER); - if (result == -1) { - goto end; - } else if (result == -2) { - htud->tsflags |= HTP_DONTSTORE; - } - } else if (header_next - filedata > 2) { - filedata_len = header_next - filedata - 2; - SCLogDebug("filedata_len %u", filedata_len); - - result = HTPFileOpen(hstate, filename, filename_len, - filedata, filedata_len, hstate->transaction_cnt, - STREAM_TOSERVER); - if (result == -1) { - goto end; - } else if (result == -2) { - htud->tsflags |= HTP_DONTSTORE; - } else { - if (HTPFileClose(hstate, NULL, 0, 0, STREAM_TOSERVER) == -1) { - goto end; - } - } - - htud->tsflags &= ~HTP_FILENAME_SET; - htud->request_body.body_parsed += (header_end - chunks_buffer); - } - } - } -next: - SCLogDebug("header_start %p, header_end %p, form_end %p", - header_start, header_end, form_end); - - /* Search next boundary entry after the start of body */ - uint32_t cursizeread = header_end - chunks_buffer; - header_start = Bs2bmSearch(header_end + 4, - chunks_buffer_len - (cursizeread + 4), - expected_boundary, expected_boundary_len); - if (header_start != NULL) { - header_end = Bs2bmSearch(header_end + 4, - chunks_buffer_len - (cursizeread + 4), - (uint8_t *) "\r\n\r\n", 4); - } - } -end: - if (expected_boundary != NULL) { - HTPFree(expected_boundary, expected_boundary_len); - } - if (expected_boundary_end != NULL) { - HTPFree(expected_boundary_end, expected_boundary_end_len); - } - - SCLogDebug("htud->request_body.body_parsed %"PRIu64, htud->request_body.body_parsed); - return 0; -} - -/** \brief setup things for put request - * \todo really needed? */ -int HtpRequestBodySetupPUT(htp_tx_data_t *d, HtpTxUserData *htud) -{ -// if (d->tx->parsed_uri == NULL || d->tx->parsed_uri->path == NULL) { -// return -1; -// } - - /* filename is d->tx->parsed_uri->path */ - - return 0; -} - -/** \internal - * \brief Handle POST, no multipart body data - */ -static int HtpRequestBodyHandlePOST(HtpState *hstate, HtpTxUserData *htud, - htp_tx_t *tx, uint8_t *data, uint32_t data_len) -{ - int result = 0; - - /* see if we need to open the file */ - if (!(htud->tsflags & HTP_FILENAME_SET)) - { - uint8_t *filename = NULL; - size_t filename_len = 0; - - /* get the name */ - if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) { - filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path); - filename_len = bstr_len(tx->parsed_uri->path); - } - - if (filename != NULL) { - result = HTPFileOpen(hstate, filename, (uint32_t)filename_len, data, data_len, - hstate->transaction_cnt, STREAM_TOSERVER); - if (result == -1) { - goto end; - } else if (result == -2) { - htud->tsflags |= HTP_DONTSTORE; - } else { - htud->tsflags |= HTP_FILENAME_SET; - htud->tsflags &= ~HTP_DONTSTORE; - } - } - } - else - { - /* otherwise, just store the data */ - - if (!(htud->tsflags & HTP_DONTSTORE)) { - result = HTPFileStoreChunk(hstate, data, data_len, STREAM_TOSERVER); - if (result == -1) { - goto end; - } else if (result == -2) { - /* we know for sure we're not storing the file */ - htud->tsflags |= HTP_DONTSTORE; - } - } - } - - return 0; -end: - return -1; -} - -/** \internal - * \brief Handle PUT body data - */ -static int HtpRequestBodyHandlePUT(HtpState *hstate, HtpTxUserData *htud, - htp_tx_t *tx, uint8_t *data, uint32_t data_len) -{ - int result = 0; - - /* see if we need to open the file */ - if (!(htud->tsflags & HTP_FILENAME_SET)) - { - uint8_t *filename = NULL; - size_t filename_len = 0; - - /* get the name */ - if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) { - filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path); - filename_len = bstr_len(tx->parsed_uri->path); - } - - if (filename != NULL) { - result = HTPFileOpen(hstate, filename, (uint32_t)filename_len, data, data_len, - hstate->transaction_cnt, STREAM_TOSERVER); - if (result == -1) { - goto end; - } else if (result == -2) { - htud->tsflags |= HTP_DONTSTORE; - } else { - htud->tsflags |= HTP_FILENAME_SET; - htud->tsflags &= ~HTP_DONTSTORE; - } - } - } - else - { - /* otherwise, just store the data */ - - if (!(htud->tsflags & HTP_DONTSTORE)) { - result = HTPFileStoreChunk(hstate, data, data_len, STREAM_TOSERVER); - if (result == -1) { - goto end; - } else if (result == -2) { - /* we know for sure we're not storing the file */ - htud->tsflags |= HTP_DONTSTORE; - } - } - } - - return 0; -end: - return -1; -} - -int HtpResponseBodyHandle(HtpState *hstate, HtpTxUserData *htud, - htp_tx_t *tx, uint8_t *data, uint32_t data_len) -{ - SCEnter(); - - int result = 0; - - /* see if we need to open the file */ - if (!(htud->tcflags & HTP_FILENAME_SET)) - { - SCLogDebug("setting up file name"); - - uint8_t *filename = NULL; - size_t filename_len = 0; - - /* try Content-Disposition header first */ - htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->response_headers, - "Content-Disposition"); - if (h != NULL && bstr_len(h->value) > 0) { - /* parse content-disposition */ - (void)HTTPParseContentDispositionHeader((uint8_t *)"filename=", 9, - (uint8_t *) bstr_ptr(h->value), bstr_len(h->value), &filename, &filename_len); - } - - /* fall back to name from the uri */ - if (filename == NULL) { - /* get the name */ - if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) { - filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path); - filename_len = bstr_len(tx->parsed_uri->path); - } - } - - if (filename != NULL) { - result = HTPFileOpen(hstate, filename, (uint32_t)filename_len, - data, data_len, hstate->transaction_cnt, STREAM_TOCLIENT); - SCLogDebug("result %d", result); - if (result == -1) { - goto end; - } else if (result == -2) { - htud->tcflags |= HTP_DONTSTORE; - } else { - htud->tcflags |= HTP_FILENAME_SET; - htud->tcflags &= ~HTP_DONTSTORE; - } - } - } - else - { - /* otherwise, just store the data */ - - if (!(htud->tcflags & HTP_DONTSTORE)) { - result = HTPFileStoreChunk(hstate, data, data_len, STREAM_TOCLIENT); - SCLogDebug("result %d", result); - if (result == -1) { - goto end; - } else if (result == -2) { - /* we know for sure we're not storing the file */ - htud->tcflags |= HTP_DONTSTORE; - } - } - } - - htud->response_body.body_parsed += data_len; - return 0; -end: - return -1; -} - -/** - * \brief Function callback to append chunks for Requests - * \param d pointer to the htp_tx_data_t structure (a chunk from htp lib) - * \retval int HTP_OK if all goes well - */ -int HTPCallbackRequestBodyData(htp_tx_data_t *d) -{ - SCEnter(); - - if (!(SC_ATOMIC_GET(htp_config_flags) & HTP_REQUIRE_REQUEST_BODY)) - SCReturnInt(HTP_OK); - - if (d->data == NULL || d->len == 0) - SCReturnInt(HTP_OK); - -#ifdef PRINT - printf("HTPBODY START: \n"); - PrintRawDataFp(stdout, (uint8_t *)d->data, d->len); - printf("HTPBODY END: \n"); -#endif - - HtpState *hstate = htp_connp_get_user_data(d->tx->connp); - if (hstate == NULL) { - SCReturnInt(HTP_ERROR); - } - - SCLogDebug("New request body data available at %p -> %p -> %p, bodylen " - "%"PRIu32"", hstate, d, d->data, (uint32_t)d->len); - - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(d->tx); - if (tx_ud == NULL) { - tx_ud = HTPMalloc(sizeof(HtpTxUserData)); - if (unlikely(tx_ud == NULL)) { - SCReturnInt(HTP_OK); - } - memset(tx_ud, 0, sizeof(HtpTxUserData)); - - /* Set the user data for handling body chunks on this transaction */ - htp_tx_set_user_data(d->tx, tx_ud); - } - if (!tx_ud->response_body_init) { - tx_ud->response_body_init = 1; - tx_ud->operation = HTP_BODY_REQUEST; - - if (d->tx->request_method_number == HTP_M_POST) { - SCLogDebug("POST"); - int r = HtpRequestBodySetupMultipart(d, tx_ud); - if (r == 1) { - tx_ud->request_body_type = HTP_BODY_REQUEST_MULTIPART; - } else if (r == 0) { - tx_ud->request_body_type = HTP_BODY_REQUEST_POST; - SCLogDebug("not multipart"); - } - } else if (d->tx->request_method_number == HTP_M_PUT) { - if (HtpRequestBodySetupPUT(d, tx_ud) == 0) { - tx_ud->request_body_type = HTP_BODY_REQUEST_PUT; - } - } - } - - SCLogDebug("tx_ud->request_body.content_len_so_far %"PRIu64, tx_ud->request_body.content_len_so_far); - SCLogDebug("hstate->cfg->request_body_limit %u", hstate->cfg->request_body_limit); - - /* within limits, add the body chunk to the state. */ - if (hstate->cfg->request_body_limit == 0 || tx_ud->request_body.content_len_so_far < hstate->cfg->request_body_limit) - { - uint32_t len = (uint32_t)d->len; - - if (hstate->cfg->request_body_limit > 0 && - (tx_ud->request_body.content_len_so_far + len) > hstate->cfg->request_body_limit) - { - len = hstate->cfg->request_body_limit - tx_ud->request_body.content_len_so_far; - BUG_ON(len > (uint32_t)d->len); - } - SCLogDebug("len %u", len); - - HtpBodyAppendChunk(tx_ud, &tx_ud->request_body, (uint8_t *)d->data, len); - - uint8_t *chunks_buffer = NULL; - uint32_t chunks_buffer_len = 0; - - if (tx_ud->request_body_type == HTP_BODY_REQUEST_MULTIPART) { - /* multi-part body handling starts here */ - if (!(tx_ud->tsflags & HTP_BOUNDARY_SET)) { - goto end; - } - - HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len); - if (chunks_buffer == NULL) { - goto end; - } -#ifdef PRINT - printf("REASSCHUNK START: \n"); - PrintRawDataFp(stdout, chunks_buffer, chunks_buffer_len); - printf("REASSCHUNK END: \n"); -#endif - - HtpRequestBodyHandleMultipart(hstate, tx_ud, d->tx, chunks_buffer, chunks_buffer_len); - - if (chunks_buffer != NULL) { - HTPFree(chunks_buffer, chunks_buffer_len); - } - } else if (tx_ud->request_body_type == HTP_BODY_REQUEST_POST) { - HtpRequestBodyHandlePOST(hstate, tx_ud, d->tx, (uint8_t *)d->data, (uint32_t)d->len); - } else if (tx_ud->request_body_type == HTP_BODY_REQUEST_PUT) { - HtpRequestBodyHandlePUT(hstate, tx_ud, d->tx, (uint8_t *)d->data, (uint32_t)d->len); - } - - } - -end: - /* see if we can get rid of htp body chunks */ - HtpBodyPrune(hstate, &tx_ud->request_body, STREAM_TOSERVER); - - /* set the new chunk flag */ - hstate->flags |= HTP_FLAG_NEW_BODY_SET; - - SCReturnInt(HTP_OK); -} - -/** - * \brief Function callback to append chunks for Responses - * \param d pointer to the htp_tx_data_t structure (a chunk from htp lib) - * \retval int HTP_OK if all goes well - */ -int HTPCallbackResponseBodyData(htp_tx_data_t *d) -{ - SCEnter(); - - if (!(SC_ATOMIC_GET(htp_config_flags) & HTP_REQUIRE_RESPONSE_BODY)) - SCReturnInt(HTP_OK); - - if (d->data == NULL || d->len == 0) - SCReturnInt(HTP_OK); - - HtpState *hstate = htp_connp_get_user_data(d->tx->connp); - if (hstate == NULL) { - SCReturnInt(HTP_ERROR); - } - - SCLogDebug("New response body data available at %p -> %p -> %p, bodylen " - "%"PRIu32"", hstate, d, d->data, (uint32_t)d->len); - - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(d->tx); - if (tx_ud == NULL) { - tx_ud = HTPMalloc(sizeof(HtpTxUserData)); - if (unlikely(tx_ud == NULL)) { - SCReturnInt(HTP_OK); - } - memset(tx_ud, 0, sizeof(HtpTxUserData)); - - /* Set the user data for handling body chunks on this transaction */ - htp_tx_set_user_data(d->tx, tx_ud); - } - if (!tx_ud->request_body_init) { - tx_ud->request_body_init = 1; - tx_ud->operation = HTP_BODY_RESPONSE; - } - - SCLogDebug("tx_ud->response_body.content_len_so_far %"PRIu64, tx_ud->response_body.content_len_so_far); - SCLogDebug("hstate->cfg->response_body_limit %u", hstate->cfg->response_body_limit); - - /* within limits, add the body chunk to the state. */ - if (hstate->cfg->response_body_limit == 0 || tx_ud->response_body.content_len_so_far < hstate->cfg->response_body_limit) - { - uint32_t len = (uint32_t)d->len; - - if (hstate->cfg->response_body_limit > 0 && - (tx_ud->response_body.content_len_so_far + len) > hstate->cfg->response_body_limit) - { - len = hstate->cfg->response_body_limit - tx_ud->response_body.content_len_so_far; - BUG_ON(len > (uint32_t)d->len); - } - SCLogDebug("len %u", len); - - HtpBodyAppendChunk(tx_ud, &tx_ud->response_body, (uint8_t *)d->data, len); - - HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data, (uint32_t)d->len); - } - - /* see if we can get rid of htp body chunks */ - HtpBodyPrune(hstate, &tx_ud->response_body, STREAM_TOCLIENT); - - /* set the new chunk flag */ - hstate->flags |= HTP_FLAG_NEW_BODY_SET; - - SCReturnInt(HTP_OK); -} - -/** - * \brief Print the stats of the HTTP requests - */ -void HTPAtExitPrintStats(void) -{ -#ifdef DEBUG - SCEnter(); - SCMutexLock(&htp_state_mem_lock); - SCLogDebug("http_state_memcnt %"PRIu64", http_state_memuse %"PRIu64"", - htp_state_memcnt, htp_state_memuse); - SCMutexUnlock(&htp_state_mem_lock); - SCReturn; -#endif -} - -/** \brief Clears the HTTP server configuration memory used by HTP library */ -void HTPFreeConfig(void) -{ - SCEnter(); - - if (!AppLayerProtoDetectConfProtoDetectionEnabled("tcp", "http") || - !AppLayerParserConfParserEnabled("tcp", "http")) - { - SCReturn; - } - - HTPCfgRec *nextrec = cfglist.next; - SCRadixReleaseRadixTree(cfgtree); - cfgtree = NULL; - htp_config_destroy(cfglist.cfg); - while (nextrec != NULL) { - HTPCfgRec *htprec = nextrec; - nextrec = nextrec->next; - - htp_config_destroy(htprec->cfg); - SCFree(htprec); - } - SCReturn; -} - -/** - * \brief callback for request to store the recent incoming request - in to the recent_in_tx for the given htp state - * \param connp pointer to the current connection parser which has the htp - * state in it as user data - */ -static int HTPCallbackRequest(htp_tx_t *tx) -{ - SCEnter(); - - if (tx == NULL) { - SCReturnInt(HTP_ERROR); - } - - HtpState *hstate = htp_connp_get_user_data(tx->connp); - if (hstate == NULL) { - SCReturnInt(HTP_ERROR); - } - - SCLogDebug("transaction_cnt %"PRIu64", list_size %"PRIu64, - hstate->transaction_cnt, HTPStateGetTxCnt(hstate)); - - SCLogDebug("HTTP request completed"); - - HTPErrorCheckTxRequestFlags(hstate, tx); - - HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud != NULL) { - if (htud->tsflags & HTP_FILENAME_SET) { - SCLogDebug("closing file that was being stored"); - (void)HTPFileClose(hstate, NULL, 0, 0, STREAM_TOSERVER); - htud->tsflags &= ~HTP_FILENAME_SET; - } - } - - /* request done, do raw reassembly now to inspect state and stream - * at the same time. */ - AppLayerParserTriggerRawStreamReassembly(hstate->f); - SCReturnInt(HTP_OK); -} - -/** - * \brief callback for response to remove the recent received requests - from the recent_in_tx for the given htp state - * \param connp pointer to the current connection parser which has the htp - * state in it as user data - */ -static int HTPCallbackResponse(htp_tx_t *tx) -{ - SCEnter(); - - HtpState *hstate = htp_connp_get_user_data(tx->connp); - if (hstate == NULL) { - SCReturnInt(HTP_ERROR); - } - - /* we have one whole transaction now */ - hstate->transaction_cnt++; - - /* Unset the body inspection (if any) */ - hstate->flags &=~ HTP_FLAG_NEW_BODY_SET; - - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (htud != NULL) { - if (htud->tcflags & HTP_FILENAME_SET) { - SCLogDebug("closing file that was being stored"); - (void)HTPFileClose(hstate, NULL, 0, 0, STREAM_TOCLIENT); - htud->tcflags &= ~HTP_FILENAME_SET; - } - } - - /* response done, do raw reassembly now to inspect state and stream - * at the same time. */ - AppLayerParserTriggerRawStreamReassembly(hstate->f); - SCReturnInt(HTP_OK); -} - -static int HTPCallbackRequestLine(htp_tx_t *tx) -{ - HtpTxUserData *tx_ud; - bstr *request_uri_normalized; - HtpState *hstate = htp_connp_get_user_data(tx->connp); - HTPCfgRec *cfg = hstate->cfg; - - request_uri_normalized = SCHTPGenerateNormalizedUri(tx, tx->parsed_uri, cfg->uri_include_all); - if (request_uri_normalized == NULL) - return HTP_OK; - - tx_ud = htp_tx_get_user_data(tx); - if (likely(tx_ud == NULL)) { - tx_ud = HTPMalloc(sizeof(*tx_ud)); - if (unlikely(tx_ud == NULL)) { - bstr_free(request_uri_normalized); - return HTP_OK; - } - memset(tx_ud, 0, sizeof(*tx_ud)); - htp_tx_set_user_data(tx, tx_ud); - } - if (unlikely(tx_ud->request_uri_normalized != NULL)) - bstr_free(tx_ud->request_uri_normalized); - tx_ud->request_uri_normalized = request_uri_normalized; - - if (tx->flags) { - HTPErrorCheckTxRequestFlags(hstate, tx); - } - return HTP_OK; -} - -static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx) -{ - if (tx->parsed_uri == NULL || tx->parsed_uri->query == NULL) - return HTP_OK; - - uint64_t flags = 0; - htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, tx->parsed_uri->query, &flags); - - return HTP_OK; -} - -static int HTPCallbackDoubleDecodePath(htp_tx_t *tx) -{ - if (tx->parsed_uri == NULL || tx->parsed_uri->path == NULL) - return HTP_OK; - - uint64_t flags = 0; - htp_urldecode_inplace(tx->cfg, HTP_DECODER_URL_PATH, tx->parsed_uri->path, &flags); - - return HTP_OK; -} - -static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data) -{ - void *ptmp; - if (tx_data->len == 0) - return HTP_OK; - - HtpTxUserData *tx_ud = htp_tx_get_user_data(tx_data->tx); - if (tx_ud == NULL) { - tx_ud = HTPMalloc(sizeof(*tx_ud)); - if (unlikely(tx_ud == NULL)) - return HTP_OK; - memset(tx_ud, 0, sizeof(*tx_ud)); - htp_tx_set_user_data(tx_data->tx, tx_ud); - } - ptmp = HTPRealloc(tx_ud->request_headers_raw, - tx_ud->request_headers_raw_len, - tx_ud->request_headers_raw_len + tx_data->len); - if (ptmp == NULL) { - /* error: we're freeing the entire user data */ - HtpState *hstate = htp_connp_get_user_data(tx_data->tx->connp); - HtpTxUserDataFree(hstate, tx_ud); - htp_tx_set_user_data(tx_data->tx, NULL); - return HTP_OK; - } - tx_ud->request_headers_raw = ptmp; - - memcpy(tx_ud->request_headers_raw + tx_ud->request_headers_raw_len, - tx_data->data, tx_data->len); - tx_ud->request_headers_raw_len += tx_data->len; - - if (tx_data->tx && tx_data->tx->flags) { - HtpState *hstate = htp_connp_get_user_data(tx_data->tx->connp); - HTPErrorCheckTxRequestFlags(hstate, tx_data->tx); - } - return HTP_OK; -} - -static int HTPCallbackResponseHeaderData(htp_tx_data_t *tx_data) -{ - void *ptmp; - if (tx_data->len == 0) - return HTP_OK; - - HtpTxUserData *tx_ud = htp_tx_get_user_data(tx_data->tx); - if (tx_ud == NULL) { - tx_ud = HTPMalloc(sizeof(*tx_ud)); - if (unlikely(tx_ud == NULL)) - return HTP_OK; - memset(tx_ud, 0, sizeof(*tx_ud)); - htp_tx_set_user_data(tx_data->tx, tx_ud); - } - ptmp = HTPRealloc(tx_ud->response_headers_raw, - tx_ud->response_headers_raw_len, - tx_ud->response_headers_raw_len + tx_data->len); - if (ptmp == NULL) { - /* error: we're freeing the entire user data */ - HtpState *hstate = htp_connp_get_user_data(tx_data->tx->connp); - HtpTxUserDataFree(hstate, tx_ud); - htp_tx_set_user_data(tx_data->tx, NULL); - return HTP_OK; - } - tx_ud->response_headers_raw = ptmp; - - memcpy(tx_ud->response_headers_raw + tx_ud->response_headers_raw_len, - tx_data->data, tx_data->len); - tx_ud->response_headers_raw_len += tx_data->len; - - return HTP_OK; -} - -/* - * We have a similar set function called HTPConfigSetDefaultsPhase1. - */ -static void HTPConfigSetDefaultsPhase1(HTPCfgRec *cfg_prec) -{ - cfg_prec->uri_include_all = FALSE; - cfg_prec->request_body_limit = HTP_CONFIG_DEFAULT_REQUEST_BODY_LIMIT; - cfg_prec->response_body_limit = HTP_CONFIG_DEFAULT_RESPONSE_BODY_LIMIT; - cfg_prec->request_inspect_min_size = HTP_CONFIG_DEFAULT_REQUEST_INSPECT_MIN_SIZE; - cfg_prec->request_inspect_window = HTP_CONFIG_DEFAULT_REQUEST_INSPECT_WINDOW; - cfg_prec->response_inspect_min_size = HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_MIN_SIZE; - cfg_prec->response_inspect_window = HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_WINDOW; - cfg_prec->randomize = HTP_CONFIG_DEFAULT_RANDOMIZE; - cfg_prec->randomize_range = HTP_CONFIG_DEFAULT_RANDOMIZE_RANGE; - - htp_config_register_request_header_data(cfg_prec->cfg, HTPCallbackRequestHeaderData); - htp_config_register_request_trailer_data(cfg_prec->cfg, HTPCallbackRequestHeaderData); - htp_config_register_response_header_data(cfg_prec->cfg, HTPCallbackResponseHeaderData); - htp_config_register_response_trailer_data(cfg_prec->cfg, HTPCallbackResponseHeaderData); - - htp_config_register_request_body_data(cfg_prec->cfg, HTPCallbackRequestBodyData); - htp_config_register_response_body_data(cfg_prec->cfg, HTPCallbackResponseBodyData); - - htp_config_register_request_complete(cfg_prec->cfg, HTPCallbackRequest); - htp_config_register_response_complete(cfg_prec->cfg, HTPCallbackResponse); - - htp_config_set_parse_request_cookies(cfg_prec->cfg, 0); - htp_config_set_parse_request_auth(cfg_prec->cfg, 0); - - /* don't convert + to space by default */ - htp_config_set_plusspace_decode(cfg_prec->cfg, HTP_DECODER_URLENCODED, 0); - - /* libhtp <= 0.5.9 doesn't use soft limit, but it's impossible to set - * only the hard limit. So we set both here to the (current) htp defaults. - * The reason we do this is that if the user sets the hard limit in the - * config, we have to set the soft limit as well. If libhtp starts using - * the soft limit in the future, we at least make sure we control what - * it's value is. */ - htp_config_set_field_limits(cfg_prec->cfg, - (size_t)HTP_CONFIG_DEFAULT_FIELD_LIMIT_SOFT, - (size_t)HTP_CONFIG_DEFAULT_FIELD_LIMIT_HARD); - return; -} - -/* - * We have this splitup so that in case double decoding has been enabled - * for query and path, they would be called first on the callback queue, - * before the callback set by Phase2() is called. We need this, since - * the callback in Phase2() generates the normalized uri which utilizes - * the query and path. */ -static void HTPConfigSetDefaultsPhase2(char *name, HTPCfgRec *cfg_prec) -{ - /* randomize inspection size if needed */ - if (cfg_prec->randomize) { - int rdrange = cfg_prec->randomize_range; - - cfg_prec->request_inspect_min_size += - (int) (cfg_prec->request_inspect_min_size * - (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); - cfg_prec->request_inspect_window += - (int) (cfg_prec->request_inspect_window * - (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); - SCLogInfo("'%s' server has 'request-body-minimal-inspect-size' set to" - " %d and 'request-body-inspect-window' set to %d after" - " randomization.", - name, - cfg_prec->request_inspect_min_size, - cfg_prec->request_inspect_window); - - - cfg_prec->response_inspect_min_size += - (int) (cfg_prec->response_inspect_min_size * - (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); - cfg_prec->response_inspect_window += - (int) (cfg_prec->response_inspect_window * - (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); - - SCLogInfo("'%s' server has 'response-body-minimal-inspect-size' set to" - " %d and 'response-body-inspect-window' set to %d after" - " randomization.", - name, - cfg_prec->response_inspect_min_size, - cfg_prec->response_inspect_window); - } - - htp_config_register_request_line(cfg_prec->cfg, HTPCallbackRequestLine); - - return; -} - -static void HTPConfigParseParameters(HTPCfgRec *cfg_prec, ConfNode *s, - SCRadixTree *tree) -{ - if (cfg_prec == NULL || s == NULL || tree == NULL) - return; - - ConfNode *p = NULL; - - /* Default Parameters */ - TAILQ_FOREACH(p, &s->head, next) { - - if (strcasecmp("address", p->name) == 0) { - ConfNode *pval; - /* Addresses */ - TAILQ_FOREACH(pval, &p->head, next) { - SCLogDebug("LIBHTP server %s: %s=%s", s->name, p->name, - pval->val); - - /* IPV6 or IPV4? */ - if (strchr(pval->val, ':') != NULL) { - SCLogDebug("LIBHTP adding ipv6 server %s at %s: %p", - s->name, pval->val, cfg_prec->cfg); - if (SCRadixAddKeyIPV6String(pval->val, tree, cfg_prec) == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, "LIBHTP failed to " - "add ipv6 server %s, ignoring", pval->val); - } - } else { - SCLogDebug("LIBHTP adding ipv4 server %s at %s: %p", - s->name, pval->val, cfg_prec->cfg); - if (SCRadixAddKeyIPV4String(pval->val, tree, cfg_prec) == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, "LIBHTP failed " - "to add ipv4 server %s, ignoring", - pval->val); - } - } /* else - if (strchr(pval->val, ':') != NULL) */ - } /* TAILQ_FOREACH(pval, &p->head, next) */ - - } else if (strcasecmp("personality", p->name) == 0) { - /* Personalities */ - int personality = HTPLookupPersonality(p->val); - SCLogDebug("LIBHTP default: %s = %s", p->name, p->val); - SCLogDebug("LIBHTP default: %s = %s", p->name, p->val); - - if (personality >= 0) { - SCLogDebug("LIBHTP default: %s=%s (%d)", p->name, p->val, - personality); - if (htp_config_set_server_personality(cfg_prec->cfg, personality) == HTP_ERROR){ - SCLogWarning(SC_ERR_INVALID_VALUE, "LIBHTP Failed adding " - "personality \"%s\", ignoring", p->val); - } else { - SCLogDebug("LIBHTP personality set to %s", - HTPLookupPersonalityString(personality)); - } - - /* The IDS personality by default converts the path (and due to - * our query string callback also the query string) to lowercase. - * Signatures do not expect this, so override it. */ - htp_config_set_convert_lowercase(cfg_prec->cfg, HTP_DECODER_URL_PATH, 0); - } else { - SCLogWarning(SC_ERR_UNKNOWN_VALUE, "LIBHTP Unknown personality " - "\"%s\", ignoring", p->val); - continue; - } - - } else if (strcasecmp("request-body-limit", p->name) == 0 || - strcasecmp("request_body_limit", p->name) == 0) { - if (ParseSizeStringU32(p->val, &cfg_prec->request_body_limit) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing request-body-limit " - "from conf file - %s. Killing engine", p->val); - exit(EXIT_FAILURE); - } - - } else if (strcasecmp("response-body-limit", p->name) == 0) { - if (ParseSizeStringU32(p->val, &cfg_prec->response_body_limit) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing response-body-limit " - "from conf file - %s. Killing engine", p->val); - exit(EXIT_FAILURE); - } - - } else if (strcasecmp("request-body-minimal-inspect-size", p->name) == 0) { - if (ParseSizeStringU32(p->val, &cfg_prec->request_inspect_min_size) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing request-body-minimal-inspect-size " - "from conf file - %s. Killing engine", p->val); - exit(EXIT_FAILURE); - } - - } else if (strcasecmp("request-body-inspect-window", p->name) == 0) { - if (ParseSizeStringU32(p->val, &cfg_prec->request_inspect_window) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing request-body-inspect-window " - "from conf file - %s. Killing engine", p->val); - exit(EXIT_FAILURE); - } - - } else if (strcasecmp("double-decode-path", p->name) == 0) { - if (ConfValIsTrue(p->val)) { - htp_config_register_request_line(cfg_prec->cfg, - HTPCallbackDoubleDecodeQuery); - } - - } else if (strcasecmp("double-decode-query", p->name) == 0) { - if (ConfValIsTrue(p->val)) { - htp_config_register_request_line(cfg_prec->cfg, - HTPCallbackDoubleDecodePath); - } - - } else if (strcasecmp("response-body-minimal-inspect-size", p->name) == 0) { - if (ParseSizeStringU32(p->val, &cfg_prec->response_inspect_min_size) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing response-body-minimal-inspect-size " - "from conf file - %s. Killing engine", p->val); - exit(EXIT_FAILURE); - } - - } else if (strcasecmp("response-body-inspect-window", p->name) == 0) { - if (ParseSizeStringU32(p->val, &cfg_prec->response_inspect_window) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing response-body-inspect-window " - "from conf file - %s. Killing engine", p->val); - exit(EXIT_FAILURE); - } - - } else if (strcasecmp("path-convert-backslash-separators", p->name) == 0) { - htp_config_set_backslash_convert_slashes(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - ConfValIsTrue(p->val)); - } else if (strcasecmp("path-bestfit-replacement-char", p->name) == 0) { - if (strlen(p->val) == 1) { - htp_config_set_bestfit_replacement_byte(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - p->val[0]); - } else { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry " - "for libhtp param path-bestfit-replacement-char"); - } - } else if (strcasecmp("path-convert-lowercase", p->name) == 0) { - htp_config_set_convert_lowercase(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - ConfValIsTrue(p->val)); - } else if (strcasecmp("path-nul-encoded-terminates", p->name) == 0) { - htp_config_set_nul_encoded_terminates(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - ConfValIsTrue(p->val)); - } else if (strcasecmp("path-nul-raw-terminates", p->name) == 0) { - htp_config_set_nul_raw_terminates(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - ConfValIsTrue(p->val)); - } else if (strcasecmp("path-separators-compress", p->name) == 0) { - htp_config_set_path_separators_compress(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - ConfValIsTrue(p->val)); - } else if (strcasecmp("path-separators-decode", p->name) == 0) { - htp_config_set_path_separators_decode(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - ConfValIsTrue(p->val)); - } else if (strcasecmp("path-u-encoding-decode", p->name) == 0) { - htp_config_set_u_encoding_decode(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - ConfValIsTrue(p->val)); - } else if (strcasecmp("path-url-encoding-invalid-handling", p->name) == 0) { - enum htp_url_encoding_handling_t handling; - if (strcasecmp(p->val, "preserve_percent") == 0) { - handling = HTP_URL_DECODE_PRESERVE_PERCENT; - } else if (strcasecmp(p->val, "remove_percent") == 0) { - handling = HTP_URL_DECODE_REMOVE_PERCENT; - } else if (strcasecmp(p->val, "decode_invalid") == 0) { - handling = HTP_URL_DECODE_PROCESS_INVALID; - } else { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry " - "for libhtp param path-url-encoding-invalid-handling"); - return; - } - htp_config_set_url_encoding_invalid_handling(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - handling); - } else if (strcasecmp("path-utf8-convert-bestfit", p->name) == 0) { - htp_config_set_utf8_convert_bestfit(cfg_prec->cfg, - HTP_DECODER_URL_PATH, - ConfValIsTrue(p->val)); - } else if (strcasecmp("uri-include-all", p->name) == 0) { - cfg_prec->uri_include_all = ConfValIsTrue(p->val); - SCLogDebug("uri-include-all %s", - cfg_prec->uri_include_all ? "enabled" : "disabled"); - } else if (strcasecmp("query-plusspace-decode", p->name) == 0) { - htp_config_set_plusspace_decode(cfg_prec->cfg, - HTP_DECODER_URLENCODED, - ConfValIsTrue(p->val)); - } else if (strcasecmp("meta-field-limit", p->name) == 0) { - uint32_t limit = 0; - if (ParseSizeStringU32(p->val, &limit) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error meta-field-limit " - "from conf file - %s. Killing engine", p->val); - exit(EXIT_FAILURE); - } - if (limit == 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error meta-field-limit " - "from conf file cannot be 0. Killing engine"); - exit(EXIT_FAILURE); - } - /* set default soft-limit with our new hard limit */ - htp_config_set_field_limits(cfg_prec->cfg, - (size_t)HTP_CONFIG_DEFAULT_FIELD_LIMIT_SOFT, - (size_t)limit); - } else if (strcasecmp("randomize-inspection-sizes", p->name) == 0) { - cfg_prec->randomize = ConfValIsTrue(p->val); - } else if (strcasecmp("randomize-inspection-range", p->name) == 0) { - uint32_t range = atoi(p->val); - if (range > 100) { - SCLogError(SC_ERR_SIZE_PARSE, "Invalid value for randomize" - " inspection range setting from conf file - %s." - " It should be inferior to 100." - " Killing engine", - p->val); - exit(EXIT_FAILURE); - } - cfg_prec->randomize_range = range; - } else if (strcasecmp("http-body-inline", p->name) == 0) { - if (ConfValIsTrue(p->val)) { - cfg_prec->http_body_inline = 1; - } else if (ConfValIsFalse(p->val)) { - cfg_prec->http_body_inline = 0; - } else { - if (strcmp("auto", p->val) != 0) { - WarnInvalidConfEntry("http_body_inline", "%s", "auto"); - } - if (EngineModeIsIPS()) { - cfg_prec->http_body_inline = 1; - } else { - cfg_prec->http_body_inline = 0; - } - } - } else { - SCLogWarning(SC_ERR_UNKNOWN_VALUE, "LIBHTP Ignoring unknown " - "default config: %s", p->name); - } - } /* TAILQ_FOREACH(p, &default_config->head, next) */ - - return; -} - -void HTPConfigure(void) -{ - SCEnter(); - - cfglist.next = NULL; - - cfgtree = SCRadixCreateRadixTree(NULL, NULL); - if (NULL == cfgtree) - exit(EXIT_FAILURE); - - /* Default Config */ - cfglist.cfg = htp_config_create(); - if (NULL == cfglist.cfg) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to create HTP default config"); - exit(EXIT_FAILURE); - } - SCLogDebug("LIBHTP default config: %p", cfglist.cfg); - HTPConfigSetDefaultsPhase1(&cfglist); - if (ConfGetNode("app-layer.protocols.http.libhtp") == NULL) { - HTPConfigParseParameters(&cfglist, ConfGetNode("libhtp.default-config"), - cfgtree); - } else { - HTPConfigParseParameters(&cfglist, ConfGetNode("app-layer.protocols.http.libhtp.default-config"), cfgtree); - } - HTPConfigSetDefaultsPhase2("default", &cfglist); - - HTPParseMemcap(); - - /* Read server config and create a parser for each IP in radix tree */ - ConfNode *server_config = ConfGetNode("app-layer.protocols.http.libhtp.server-config"); - if (server_config == NULL) { - server_config = ConfGetNode("libhtp.server-config"); - if (server_config == NULL) { - SCLogDebug("LIBHTP Configuring %p", server_config); - SCReturn; - } - } - SCLogDebug("LIBHTP Configuring %p", server_config); - - ConfNode *si; - /* Server Nodes */ - TAILQ_FOREACH(si, &server_config->head, next) { - /* Need the named node, not the index */ - ConfNode *s = TAILQ_FIRST(&si->head); - if (NULL == s) { - SCLogDebug("LIBHTP s NULL"); - continue; - } - - SCLogDebug("LIBHTP server %s", s->name); - - HTPCfgRec *nextrec = cfglist.next; - HTPCfgRec *htprec = SCMalloc(sizeof(HTPCfgRec)); - if (NULL == htprec) - exit(EXIT_FAILURE); - memset(htprec, 0x00, sizeof(*htprec)); - - cfglist.next = htprec; - - cfglist.next->next = nextrec; - cfglist.next->cfg = htp_config_create(); - if (NULL == cfglist.next->cfg) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to create HTP server config"); - exit(EXIT_FAILURE); - } - - HTPConfigSetDefaultsPhase1(htprec); - HTPConfigParseParameters(htprec, s, cfgtree); - HTPConfigSetDefaultsPhase2(s->name, htprec); - } - - SCReturn; -} - -void AppLayerHtpPrintStats(void) -{ -#ifdef DEBUG - SCMutexLock(&htp_state_mem_lock); - SCLogInfo("htp memory %"PRIu64" (%"PRIu64")", htp_state_memuse, htp_state_memcnt); - SCMutexUnlock(&htp_state_mem_lock); -#endif -} - -/** \internal - * \brief get files callback - * \param state state ptr - * \param direction flow direction - * \retval files files ptr - */ -static FileContainer *HTPStateGetFiles(void *state, uint8_t direction) -{ - if (state == NULL) - return NULL; - - HtpState *http_state = (HtpState *)state; - - if (direction & STREAM_TOCLIENT) { - SCReturnPtr(http_state->files_tc, "FileContainer"); - } else { - SCReturnPtr(http_state->files_ts, "FileContainer"); - } -} - -static int HTPStateGetAlstateProgress(void *tx, uint8_t direction) -{ - if (direction & STREAM_TOSERVER) - return ((htp_tx_t *)tx)->request_progress; - else - return ((htp_tx_t *)tx)->response_progress; -} - -static uint64_t HTPStateGetTxCnt(void *alstate) -{ - HtpState *http_state = (HtpState *)alstate; - - if (http_state != NULL && http_state->conn != NULL) - return (uint64_t)htp_list_size(http_state->conn->transactions); - else - return 0ULL; -} - -static void *HTPStateGetTx(void *alstate, uint64_t tx_id) -{ - HtpState *http_state = (HtpState *)alstate; - - if (http_state != NULL && http_state->conn != NULL) - return htp_list_get(http_state->conn->transactions, tx_id); - else - return NULL; -} - -static int HTPStateGetAlstateProgressCompletionStatus(uint8_t direction) -{ - return (direction & STREAM_TOSERVER) ? HTP_REQUEST_COMPLETE : HTP_RESPONSE_COMPLETE; -} - -int HTPStateGetEventInfo(const char *event_name, - int *event_id, AppLayerEventType *event_type) -{ - *event_id = SCMapEnumNameToValue(event_name, http_decoder_event_table); - if (*event_id == -1) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " - "http's enum map table.", event_name); - /* this should be treated as fatal */ - return -1; - } - - *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; - - return 0; -} - -static void HTPStateTruncate(void *state, uint8_t direction) -{ - FileContainer *fc = HTPStateGetFiles(state, direction); - if (fc != NULL) { - FileTruncateAllOpenFiles(fc); - } -} - -static int HTPStateHasTxDetectState(void *alstate) -{ - HtpState *htp_state = (HtpState *)alstate; - return (htp_state->tx_with_detect_state_cnt > 0); -} - -static DetectEngineState *HTPGetTxDetectState(void *vtx) -{ - htp_tx_t *tx = (htp_tx_t *)vtx; - HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - return tx_ud ? tx_ud->de_state : NULL; -} - -static int HTPSetTxDetectState(void *alstate, void *vtx, DetectEngineState *s) -{ - HtpState *htp_state = (HtpState *)alstate; - htp_tx_t *tx = (htp_tx_t *)vtx; - HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud == NULL) { - tx_ud = HTPMalloc(sizeof(*tx_ud)); - if (unlikely(tx_ud == NULL)) - return -ENOMEM; - memset(tx_ud, 0, sizeof(*tx_ud)); - htp_tx_set_user_data(tx, tx_ud); - } - htp_state->tx_with_detect_state_cnt++; - tx_ud->de_state = s; - return 0; -} - -static int HTPRegisterPatternsForProtocolDetection(void) -{ - char *methods[] = { "GET", "PUT", "POST", "HEAD", "TRACE", "OPTIONS", - "CONNECT", "DELETE", "PATCH", "PROPFIND", "PROPPATCH", "MKCOL", - "COPY", "MOVE", "LOCK", "UNLOCK", "CHECKOUT", "UNCHECKOUT", "CHECKIN", - "UPDATE", "LABEL", "REPORT", "MKWORKSPACE", "MKACTIVITY", "MERGE", - "INVALID", "VERSION-CONTROL", "BASELINE-CONTROL", NULL}; - char *spacings[] = { "|20|", "|09|", NULL }; - char *versions[] = { "HTTP/0.9", "HTTP/1.0", "HTTP/1.1", NULL }; - - uint methods_pos; - uint spacings_pos; - uint versions_pos; - int register_result; - char method_buffer[32] = ""; - - /* Loop through all the methods ands spacings and register the patterns */ - for (methods_pos = 0; methods[methods_pos]; methods_pos++) { - for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) { - - /* Combine the method name and the spacing */ - snprintf(method_buffer, sizeof(method_buffer), "%s%s", methods[methods_pos], spacings[spacings_pos]); - - /* Register the new method+spacing pattern - * 3 is subtracted from the length since the spacing is hex typed as |xx| - * but the pattern matching should only be one char - */ - register_result = AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, - ALPROTO_HTTP, method_buffer, strlen(method_buffer)-3, 0, STREAM_TOSERVER); - if (register_result < 0) { - return -1; - } - } - } - - /* Loop through all the http verions patterns that are TO_CLIENT */ - for (versions_pos = 0; versions[versions_pos]; versions_pos++) { - register_result = AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, - ALPROTO_HTTP, versions[versions_pos], strlen(versions[versions_pos]), - 0, STREAM_TOCLIENT); - if (register_result < 0) { - return -1; - } - } - - return 0; -} - -/** - * \brief Register the HTTP protocol and state handling functions to APP layer - * of the engine. - */ -void RegisterHTPParsers(void) -{ - SCEnter(); - - char *proto_name = "http"; - - /** HTTP */ - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_HTTP, proto_name); - if (HTPRegisterPatternsForProtocolDetection() < 0) - return; - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol", - proto_name); - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_HTTP, HTPStateAlloc, HTPStateFree); - AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_HTTP, HTPStateTransactionFree); - AppLayerParserRegisterGetFilesFunc(IPPROTO_TCP, ALPROTO_HTTP, HTPStateGetFiles); - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_HTTP, HTPStateGetAlstateProgress); - AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, HTPStateGetTxCnt); - AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_HTTP, HTPStateGetTx); - AppLayerParserRegisterGetStateProgressCompletionStatus(IPPROTO_TCP, ALPROTO_HTTP, - HTPStateGetAlstateProgressCompletionStatus); - AppLayerParserRegisterHasEventsFunc(IPPROTO_TCP, ALPROTO_HTTP, HTPHasEvents); - AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_HTTP, HTPGetEvents); - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_HTTP, HTPStateGetEventInfo); - - AppLayerParserRegisterTruncateFunc(IPPROTO_TCP, ALPROTO_HTTP, HTPStateTruncate); - AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_HTTP, - HTPStateHasTxDetectState, - HTPGetTxDetectState, HTPSetTxDetectState); - - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_HTTP, STREAM_TOSERVER, - HTPHandleRequestData); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_HTTP, STREAM_TOCLIENT, - HTPHandleResponseData); - SC_ATOMIC_INIT(htp_config_flags); - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_HTTP, STREAM_TOSERVER); - HTPConfigure(); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_HTTP, HTPParserRegisterTests); -#endif - - SCReturn; -} - -#ifdef UNITTESTS -static HTPCfgRec cfglist_backup; - -void HtpConfigCreateBackup(void) -{ - cfglist_backup = cfglist; - - return; -} - -void HtpConfigRestoreBackup(void) -{ - cfglist = cfglist_backup; - - return; -} - -/** \test Test case where chunks are sent in smaller chunks and check the - * response of the parser from HTP library. */ -int HTPParserTest01(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost" - " Data is c0oL!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) - flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) - flags = STREAM_TOSERVER|STREAM_EOF; - else - flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (strcmp(bstr_util_strdup_to_c(h->value), "Victor/1.0") - || tx->request_method_number != HTP_M_POST || - tx->request_protocol_number != HTP_PROTOCOL_1_0) - { - printf("expected header value: Victor/1.0 and got %s: and expected" - " method: POST and got %s, expected protocol number HTTP/1.0" - " and got: %s \n", bstr_util_strdup_to_c(h->value), - bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test case where chunks are sent in smaller chunks and check the - * response of the parser from HTP library. */ -static int HTPParserTest01a(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = " POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost" - " Data is c0oL!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) - flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) - flags = STREAM_TOSERVER|STREAM_EOF; - else - flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (strcmp(bstr_util_strdup_to_c(h->value), "Victor/1.0") - || tx->request_method_number != HTP_M_POST || - tx->request_protocol_number != HTP_PROTOCOL_1_0) - { - printf("expected header value: Victor/1.0 and got %s: and expected" - " method: POST and got %s, expected protocol number HTTP/1.0" - " and got: %s \n", bstr_util_strdup_to_c(h->value), - bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test See how it deals with an incomplete request. */ -int HTPParserTest02(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START| - STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(http_state, 0); - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if ((tx->request_method) != NULL || h != NULL) - { - printf("expected method NULL, got %s \n", bstr_util_strdup_to_c(tx->request_method)); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test case where method is invalid and data is sent in smaller chunks - * and check the response of the parser from HTP library. */ -int HTPParserTest03(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "HELLO / HTTP/1.0\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (tx->request_method_number != HTP_M_UNKNOWN || - h != NULL || tx->request_protocol_number != HTP_PROTOCOL_1_0) - { - printf("expected method M_UNKNOWN and got %s: , expected protocol " - "HTTP/1.0 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test case where invalid data is sent and check the response of the - * parser from HTP library. */ -int HTPParserTest04(void) -{ - int result = 0; - Flow *f = NULL; - HtpState *htp_state = NULL; - uint8_t httpbuf1[] = "World!\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START| - STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (tx->request_method_number != HTP_M_UNKNOWN || - h != NULL || tx->request_protocol_number != HTP_PROTOCOL_0_9) - { - printf("expected method M_UNKNOWN and got %s: , expected protocol " - "NULL and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test both sides of a http stream mixed up to see if the HTP parser - * properly parsed them and also keeps them separated. */ -int HTPParserTest05(void) -{ - int result = 0; - Flow *f = NULL; - HtpState *http_state = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "Post D"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint8_t httpbuf3[] = "ata is c0oL!"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - - uint8_t httpbuf4[] = "HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "post R"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint8_t httpbuf6[] = "esults are tha bomb!"; - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, - httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, httpbuf4, - httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf3, - httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, httpbuf6, - httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(http_state, 0); - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (tx->request_method_number != HTP_M_POST || - h == NULL || tx->request_protocol_number != HTP_PROTOCOL_1_0) - { - printf("expected method M_POST and got %s: , expected protocol " - "HTTP/1.0 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - if (tx->response_status_number != 200) { - printf("expected response 200 OK and got %"PRId32" %s: , expected protocol " - "HTTP/1.0 and got %s \n", tx->response_status_number, - bstr_util_strdup_to_c(tx->response_message), - bstr_util_strdup_to_c(tx->response_protocol)); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test proper chunked encoded response body - */ -int HTPParserTest06(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "GET /ld/index.php?id=412784631&cid=0064&version=4&" - "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: " - "LD-agent\r\nHost: 209.205.196.16\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 " - "GMT\r\n" - "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 " - "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 " - "FrontPage/5.0.2.2510\r\n" - "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: " - "chunked\r\n" - "Content-Type: text/html\r\n\r\n" - "580\r\n" - "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu" - "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN" - "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N" - "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk" - "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l" - "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN" - "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt" - "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz" - "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw" - "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps" - "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw" - "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9" - "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N" - "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu" - "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3" - "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo" - "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv" - "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh" - "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5" - "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx" - "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y" - "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv" - "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv" - "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n" - "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt" - "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N" - "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w" - "aHA=\r\n0\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, - httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, httpbuf2, - httplen2); - if (r != 0) { - printf("toclient chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(http_state, 0); - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (tx->request_method_number != HTP_M_GET || - h == NULL || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected method M_GET and got %s: , expected protocol " - "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - if (tx->response_status_number != 200 || - h == NULL || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected response 200 OK and got %"PRId32" %s: , expected proto" - "col HTTP/1.1 and got %s \n", tx->response_status_number, - bstr_util_strdup_to_c(tx->response_message), - bstr_util_strdup_to_c(tx->response_protocol)); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test - */ -int HTPParserTest07(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) - flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) - flags = STREAM_TOSERVER|STREAM_EOF; - else - flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref[] = "/awstats.pl?/migratemigrate = |"; - size_t reflen = sizeof(ref) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref, reflen); - printf("\": "); - goto end; - } - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -#include "conf-yaml-loader.h" - -/** \test Abort - */ -int HTPParserTest08(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - - HtpState *htp_state = NULL; - int r = 0; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint8_t flags = 0; - flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk returned %" PRId32 ", expected" - " 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - //printf("uri %s\n", bstr_util_strdup_to_c(tx->request_uri_normalized)); - PrintRawDataFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), - bstr_len(tx_ud->request_uri_normalized)); - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - UTHFreeFlow(f); - return result; -} - -/** \test Abort - */ -int HTPParserTest09(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: Apache_2_2\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - - HtpState *htp_state = NULL; - int r = 0; - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint8_t flags = 0; - flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk returned %" PRId32 ", expected" - " 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - //printf("uri %s\n", bstr_util_strdup_to_c(tx->request_uri_normalized)); - PrintRawDataFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), - bstr_len(tx_ud->request_uri_normalized)); - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - UTHFreeFlow(f); - return result; -} - -/** \test Host:www.google.com <- missing space between name:value (rfc violation) - */ -int HTPParserTest10(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) - flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) - flags = STREAM_TOSERVER|STREAM_EOF; - else - flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (h == NULL) { - goto end; - } - - char *name = bstr_util_strdup_to_c(h->name); - if (name == NULL) { - goto end; - } - - if (strcmp(name, "Host") != 0) { - printf("header name not \"Host\", instead \"%s\": ", name); - free(name); - goto end; - } - free(name); - - char *value = bstr_util_strdup_to_c(h->value); - if (value == NULL) { - goto end; - } - - if (strcmp(value, "www.google.com") != 0) { - printf("header value not \"www.google.com\", instead \"%s\": ", value); - free(value); - goto end; - } - free(value); - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test double encoding in path - */ -static int HTPParserTest11(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "GET /%2500 HTTP/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) - flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) - flags = STREAM_TOSERVER|STREAM_EOF; - else - flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (tx != NULL && tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (4 != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be 2, is %"PRIuMAX, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (bstr_ptr(tx_ud->request_uri_normalized)[0] != '/' || - bstr_ptr(tx_ud->request_uri_normalized)[1] != '%' || - bstr_ptr(tx_ud->request_uri_normalized)[2] != '0' || - bstr_ptr(tx_ud->request_uri_normalized)[3] != '0') - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\": "); - goto end; - } - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test double encoding in query - */ -static int HTPParserTest12(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "GET /?a=%2500 HTTP/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) - flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) - flags = STREAM_TOSERVER|STREAM_EOF; - else - flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (7 != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be 5, is %"PRIuMAX, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (bstr_ptr(tx_ud->request_uri_normalized)[0] != '/' || - bstr_ptr(tx_ud->request_uri_normalized)[1] != '?' || - bstr_ptr(tx_ud->request_uri_normalized)[2] != 'a' || - bstr_ptr(tx_ud->request_uri_normalized)[3] != '=' || - bstr_ptr(tx_ud->request_uri_normalized)[4] != '%' || - bstr_ptr(tx_ud->request_uri_normalized)[5] != '0' || - bstr_ptr(tx_ud->request_uri_normalized)[6] != '0') - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\": "); - goto end; - } - } - - result = 1; - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Host:www.google.com0dName: Value0d0a <- missing space between name:value (rfc violation) - */ -int HTPParserTest13(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) - flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) - flags = STREAM_TOSERVER|STREAM_EOF; - else - flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (h == NULL) { - goto end; - } - - char *name = bstr_util_strdup_to_c(h->name); - if (name == NULL) { - goto end; - } - - if (strcmp(name, "Host") != 0) { - printf("header name not \"Host\", instead \"%s\": ", name); - free(name); - goto end; - } - free(name); - - char *value = bstr_util_strdup_to_c(h->value); - if (value == NULL) { - goto end; - } - - if (strcmp(value, "www.google.com\rName: Value") != 0) { - printf("header value not \"www.google.com\", instead \""); - PrintRawUriFp(stdout, (uint8_t *)value, strlen(value)); - printf("\": "); - free(value); - goto end; - } - free(value); - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test basic config */ -int HTPParserConfigTest01(void) -{ - int ret = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ -\n\ - server-config:\n\ -\n\ - - apache-tomcat:\n\ - address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\ - personality: Tomcat_6_0\n\ -\n\ - - iis7:\n\ - address: \n\ - - 192.168.0.0/24\n\ - - 192.168.10.0/24\n\ - personality: IIS_7_0\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - - ConfYamlLoadString(input, strlen(input)); - - ConfNode *outputs; - outputs = ConfGetNode("libhtp.default-config.personality"); - if (outputs == NULL) { - goto end; - } - - outputs = ConfGetNode("libhtp.server-config"); - if (outputs == NULL) { - goto end; - } - - ConfNode *node = TAILQ_FIRST(&outputs->head); - if (node == NULL) { - goto end; - } - if (strcmp(node->name, "0") != 0) { - goto end; - } - node = TAILQ_FIRST(&node->head); - if (node == NULL) { - goto end; - } - if (strcmp(node->name, "apache-tomcat") != 0) { - goto end; - } - - int i = 0; - ConfNode *n; - - ConfNode *node2 = ConfNodeLookupChild(node, "personality"); - if (node2 == NULL) { - goto end; - } - if (strcmp(node2->val, "Tomcat_6_0") != 0) { - goto end; - } - - node = ConfNodeLookupChild(node, "address"); - if (node == NULL) { - goto end; - } - TAILQ_FOREACH(n, &node->head, next) { - if (n == NULL) { - goto end; - } - - switch(i) { - case 0: - if (strcmp(n->name, "0") != 0) { - goto end; - } - if (strcmp(n->val, "192.168.1.0/24") != 0) { - goto end; - } - break; - case 1: - if (strcmp(n->name, "1") != 0) { - goto end; - } - if (strcmp(n->val, "127.0.0.0/8") != 0) { - goto end; - } - break; - case 2: - if (strcmp(n->name, "2") != 0) { - goto end; - } - if (strcmp(n->val, "::1") != 0) { - goto end; - } - break; - default: - goto end; - } - i++; - } - - outputs = ConfGetNode("libhtp.server-config"); - if (outputs == NULL) { - goto end; - } - - node = TAILQ_FIRST(&outputs->head); - node = TAILQ_NEXT(node, next); - if (node == NULL) { - goto end; - } - if (strcmp(node->name, "1") != 0) { - goto end; - } - node = TAILQ_FIRST(&node->head); - if (node == NULL) { - goto end; - } - if (strcmp(node->name, "iis7") != 0) { - goto end; - } - - node2 = ConfNodeLookupChild(node, "personality"); - if (node2 == NULL) { - goto end; - } - if (strcmp(node2->val, "IIS_7_0") != 0) { - goto end; - } - - node = ConfNodeLookupChild(node, "address"); - if (node == NULL) { - goto end; - } - - i = 0; - TAILQ_FOREACH(n, &node->head, next) { - if (n == NULL) { - goto end; - } - - switch(i) { - case 0: - if (strcmp(n->name, "0") != 0) { - goto end; - } - if (strcmp(n->val, "192.168.0.0/24") != 0) { - goto end; - } - break; - case 1: - if (strcmp(n->name, "1") != 0) { - goto end; - } - if (strcmp(n->val, "192.168.10.0/24") != 0) { - goto end; - } - break; - default: - goto end; - } - i++; - } - - ret = 1; - -end: - ConfDeInit(); - ConfRestoreContextBackup(); - - return ret; -} - -/** \test Test config builds radix correctly */ -int HTPParserConfigTest02(void) -{ - int ret = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ -\n\ - server-config:\n\ -\n\ - - apache-tomcat:\n\ - address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\ - personality: Tomcat_6_0\n\ -\n\ - - iis7:\n\ - address: \n\ - - 192.168.0.0/24\n\ - - 192.168.10.0/24\n\ - personality: IIS_7_0\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - - ConfYamlLoadString(input, strlen(input)); - - HTPConfigure(); - - if (cfglist.cfg == NULL) { - printf("No default config created.\n"); - goto end; - } - - if (cfgtree == NULL) { - printf("No config tree created.\n"); - goto end; - } - - htp_cfg_t *htp = cfglist.cfg; - uint8_t buf[128]; - const char *addr; - void *user_data = NULL; - - addr = "192.168.10.42"; - if (inet_pton(AF_INET, addr, buf) == 1) { - (void)SCRadixFindKeyIPV4BestMatch(buf, cfgtree, &user_data); - if (user_data != NULL) { - HTPCfgRec *htp_cfg_rec = user_data; - htp = htp_cfg_rec->cfg; - SCLogDebug("LIBHTP using config: %p", htp); - } - if (htp == NULL) { - printf("Could not get config for: %s\n", addr); - goto end; - } - } - else { - printf("Failed to parse address: %s\n", addr); - goto end; - } - - user_data = NULL; - addr = "::1"; - if (inet_pton(AF_INET6, addr, buf) == 1) { - (void)SCRadixFindKeyIPV6BestMatch(buf, cfgtree, &user_data); - if (user_data != NULL) { - HTPCfgRec *htp_cfg_rec = user_data; - htp = htp_cfg_rec->cfg; - SCLogDebug("LIBHTP using config: %p", htp); - } - if (htp == NULL) { - printf("Could not get config for: %s\n", addr); - goto end; - } - } - else { - printf("Failed to parse address: %s\n", addr); - goto end; - } - - ret = 1; - -end: - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - return ret; -} - -/** \test Test traffic is handled by the correct htp config */ -int HTPParserConfigTest03(void) -{ - int result = 1; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost" - " Data is c0oL!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ -\n\ - server-config:\n\ -\n\ - - apache-tomcat:\n\ - address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\ - personality: Tomcat_6_0\n\ -\n\ - - iis7:\n\ - address: \n\ - - 192.168.0.0/24\n\ - - 192.168.10.0/24\n\ - personality: IIS_7_0\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - - ConfYamlLoadString(input, strlen(input)); - - HTPConfigure(); - - char *addr = "192.168.10.42"; - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - htp_cfg_t *htp = cfglist.cfg; - - void *user_data = NULL; - (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)f->dst.addr_data32, cfgtree, &user_data); - if (user_data != NULL) { - HTPCfgRec *htp_cfg_rec = user_data; - htp = htp_cfg_rec->cfg; - SCLogDebug("LIBHTP using config: %p", htp); - } - if (htp == NULL) { - printf("Could not get config for: %s\n", addr); - goto end; - } - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (HTPStateGetTxCnt(htp_state) != 2) { - printf("HTPStateGetTxCnt(htp_state) failure\n"); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - if (tx->cfg != htp) { - printf("wrong HTP config (%p instead of %p - default=%p): ", - tx->cfg, htp, cfglist.cfg); - goto end; - } - tx = HTPStateGetTx(htp_state, 1); - if (tx == NULL) - goto end; - if (tx->cfg != htp) { - printf("wrong HTP config (%p instead of %p - default=%p): ", - tx->cfg, htp, cfglist.cfg); - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/* disabled when we upgraded to libhtp 0.5.x */ -#if 0 -int HTPParserConfigTest04(void) -{ - int result = 0; - - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - path-control-char-handling: status_400\n\ - path-convert-utf8: yes\n\ - path-invalid-encoding-handling: remove_percent\n\ -\n\ - server-config:\n\ -\n\ - - apache-tomcat:\n\ - personality: Tomcat_6_0\n\ - path-invalid-utf8-handling: none\n\ - path-nul-encoded-handling: status_404\n\ - path-nul-raw-handling: status_400\n\ -\n\ - - iis7:\n\ - personality: IIS_7_0\n\ - path-replacement-char: o\n\ - path-unicode-mapping: status_400\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - - ConfYamlLoadString(input, strlen(input)); - - HTPConfigure(); - - HTPCfgRec *cfg_rec = &cfglist; - if (cfg_rec->cfg->path_control_char_handling != STATUS_400 || - cfg_rec->cfg->path_convert_utf8 != 1 || - cfg_rec->cfg->path_invalid_encoding_handling != URL_DECODER_REMOVE_PERCENT) { - printf("failed 1\n"); - goto end; - } - - cfg_rec = cfg_rec->next; - if (cfg_rec->cfg->bestfit_replacement_char != 'o' || - cfg_rec->cfg->path_unicode_mapping != STATUS_400) { - printf("failed 2\n"); - goto end; - } - - cfg_rec = cfg_rec->next; - if (cfg_rec->cfg->path_invalid_utf8_handling != NONE || - cfg_rec->cfg->path_nul_encoded_handling != STATUS_404 || - cfg_rec->cfg->path_nul_raw_handling != STATUS_400) { - printf("failed 3\n"); - goto end; - } - - result = 1; - -end: - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - return result; -} -#endif - -/** \test Test %2f decoding in profile Apache_2_2 - * - * %2f in path is left untouched - * %2f in query string is normalized to %2F - * %252f in query string is decoded/normalized to %2F - */ -static int HTPParserDecodingTest01(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = - "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n" - "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n" - "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: Apache_2\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - char *addr = "4.3.2.1"; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref1[] = "/abc%2fdef"; - size_t reflen = sizeof(ref1) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref1, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref1, reflen); - printf("\": "); - goto end; - } - } - - uint8_t ref2[] = "/abc/def?ghi/jkl"; - reflen = sizeof(ref2) - 1; - - tx = HTPStateGetTx(htp_state, 1); - if (tx == NULL) - goto end; - tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref2, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref2, reflen); - printf("\": "); - goto end; - } - } - - uint8_t ref3[] = "/abc/def?ghi%2fjkl"; - reflen = sizeof(ref3) - 1; - tx = HTPStateGetTx(htp_state, 2); - if (tx == NULL) - goto end; - tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref3, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref3, reflen); - printf("\": "); - goto end; - } - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test %2f decoding in profile IDS - * - * %2f in path decoded to / - * %2f in query string is decoded to / - * %252f in query string is decoded to %2F - */ -static int HTPParserDecodingTest02(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = - "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n" - "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n" - "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - double-decode-path: no\n\ - double-decode-query: no\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - char *addr = "4.3.2.1"; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref1[] = "/abc/def"; - size_t reflen = sizeof(ref1) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref1, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref1, reflen); - printf("\": "); - goto end; - } - } - - uint8_t ref2[] = "/abc/def?ghi/jkl"; - reflen = sizeof(ref2) - 1; - - tx = HTPStateGetTx(htp_state, 1); - if (tx == NULL) - goto end; - tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref2, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref2, reflen); - printf("\": "); - goto end; - } - } - - uint8_t ref3[] = "/abc/def?ghi%2fjkl"; - reflen = sizeof(ref3) - 1; - tx = HTPStateGetTx(htp_state, 2); - if (tx == NULL) - goto end; - tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX" (3): ", - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref3, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref3, reflen); - printf("\": "); - goto end; - } - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test %2f decoding in profile IDS with double-decode-* options - * - * %252f in path decoded to / - * %252f in query string is decoded to / - */ -static int HTPParserDecodingTest03(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = - "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n" - "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - double-decode-path: yes\n\ - double-decode-query: yes\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - char *addr = "4.3.2.1"; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref1[] = "/abc/def"; - size_t reflen = sizeof(ref1) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref1, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref1, reflen); - printf("\": "); - goto end; - } - } - - uint8_t ref2[] = "/abc/def?ghi/jkl"; - reflen = sizeof(ref2) - 1; - - tx = HTPStateGetTx(htp_state, 1); - if (tx == NULL) - goto end; - tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref2, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref2, reflen); - printf("\": "); - goto end; - } - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test http:// in query profile IDS - */ -static int HTPParserDecodingTest04(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = - "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - double-decode-path: yes\n\ - double-decode-query: yes\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - char *addr = "4.3.2.1"; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref1[] = "/abc/def?a=http://www.abc.com/"; - size_t reflen = sizeof(ref1) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref1, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref1, reflen); - printf("\": "); - goto end; - } - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test \ char in query profile IDS. Bug 739 - */ -static int HTPParserDecodingTest05(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = - "GET /index?id=\\\" HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - double-decode-path: yes\n\ - double-decode-query: yes\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - char *addr = "4.3.2.1"; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref1[] = "/index?id=\\\""; - size_t reflen = sizeof(ref1) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref1, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref1, reflen); - printf("\": "); - goto end; - } - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test + char in query. Bug 1035 - */ -static int HTPParserDecodingTest06(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = - "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - double-decode-path: yes\n\ - double-decode-query: yes\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - char *addr = "4.3.2.1"; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref1[] = "/put.php?ip=1.2.3.4&port=+6000"; - size_t reflen = sizeof(ref1) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref1, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref1, reflen); - printf("\": "); - goto end; - } - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test + char in query. Bug 1035 - */ -static int HTPParserDecodingTest07(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = - "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - double-decode-path: yes\n\ - double-decode-query: yes\n\ - query-plusspace-decode: yes\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - char *addr = "4.3.2.1"; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref1[] = "/put.php?ip=1.2.3.4&port= 6000"; - size_t reflen = sizeof(ref1) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref1, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref1, reflen); - printf("\": "); - goto end; - } - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test 'proxy' URI normalization. Ticket 1008 - */ -static int HTPParserDecodingTest08(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = - "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - char *addr = "4.3.2.1"; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref1[] = "/blah/"; - size_t reflen = sizeof(ref1) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref1, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref1, reflen); - printf("\": "); - goto end; - } - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test 'proxy' URI normalization. Ticket 1008 - */ -static int HTPParserDecodingTest09(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = - "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - uri-include-all: true\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - char *addr = "4.3.2.1"; - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < httplen1; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - uint8_t ref1[] = "http://suricata-ids.org/blah/"; - size_t reflen = sizeof(ref1) - 1; - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL) - goto end; - HtpTxUserData *tx_ud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (tx_ud != NULL && tx_ud->request_uri_normalized != NULL) { - if (reflen != bstr_len(tx_ud->request_uri_normalized)) { - printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, - (uintmax_t)reflen, - (uintmax_t)bstr_len(tx_ud->request_uri_normalized)); - goto end; - } - - if (memcmp(bstr_ptr(tx_ud->request_uri_normalized), ref1, - bstr_len(tx_ud->request_uri_normalized)) != 0) - { - printf("normalized uri \""); - PrintRawUriFp(stdout, bstr_ptr(tx_ud->request_uri_normalized), bstr_len(tx_ud->request_uri_normalized)); - printf("\" != \""); - PrintRawUriFp(stdout, ref1, reflen); - printf("\": "); - goto end; - } - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test BG box crash -- chunks are messed up. Observed for real. */ -static int HTPBodyReassemblyTest01(void) -{ - int result = 0; - HtpTxUserData htud; - memset(&htud, 0x00, sizeof(htud)); - HtpState hstate; - memset(&hstate, 0x00, sizeof(hstate)); - Flow flow; - memset(&flow, 0x00, sizeof(flow)); - AppLayerParserState *parser = AppLayerParserStateAlloc(); - htp_tx_t tx; - memset(&tx, 0, sizeof(tx)); - - hstate.f = &flow; - flow.alparser = parser; - - uint8_t chunk1[] = "--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r"; - uint8_t chunk2[] = "POST /uri HTTP/1.1\r\nHost: hostname.com\r\nKeep-Alive: 115\r\nAccept-Charset: utf-8\r\nUser-Agent: Mozilla/5.0 (X11; Linux i686; rv:9.0.1) Gecko/20100101 Firefox/9.0.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nConnection: keep-alive\r\nContent-length: 68102\r\nReferer: http://otherhost.com\r\nAccept-Encoding: gzip\r\nContent-Type: multipart/form-data; boundary=e5a320f21416a02493a0a6f561b1c494\r\nCookie: blah\r\nAccept-Language: us\r\n\r\n--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r"; - - int r = HtpBodyAppendChunk(&htud, &htud.request_body, (uint8_t *)chunk1, sizeof(chunk1)-1); - BUG_ON(r != 0); - r = HtpBodyAppendChunk(&htud, &htud.request_body, (uint8_t *)chunk2, sizeof(chunk2)-1); - BUG_ON(r != 0); - - uint8_t *chunks_buffer = NULL; - uint32_t chunks_buffer_len = 0; - - HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len); - if (chunks_buffer == NULL) { - goto end; - } -#ifdef PRINT - printf("REASSCHUNK START: \n"); - PrintRawDataFp(stdout, chunks_buffer, chunks_buffer_len); - printf("REASSCHUNK END: \n"); -#endif - - HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len); - - if (htud.request_body.content_len_so_far != 669) { - printf("htud.request_body.content_len_so_far %"PRIu64": ", htud.request_body.content_len_so_far); - goto end; - } - - if (hstate.files_ts != NULL) - goto end; - - result = 1; -end: - return result; -} - -/** \test BG crash */ -static int HTPSegvTest01(void) -{ - int result = 0; - Flow *f = NULL; - uint8_t httpbuf1[] = "POST /uri HTTP/1.1\r\nHost: hostname.com\r\nKeep-Alive: 115\r\nAccept-Charset: utf-8\r\nUser-Agent: Mozilla/5.0 (X11; Linux i686; rv:9.0.1) Gecko/20100101 Firefox/9.0.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nConnection: keep-alive\r\nContent-length: 68102\r\nReferer: http://otherhost.com\r\nAccept-Encoding: gzip\r\nContent-Type: multipart/form-data; boundary=e5a320f21416a02493a0a6f561b1c494\r\nCookie: blah\r\nAccept-Language: us\r\n\r\n--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - double-decode-path: no\n\ - double-decode-query: no\n\ - request-body-limit: 0\n\ - response-body-limit: 0\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - - TcpSession ssn; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - SCLogDebug("\n>>>> processing chunk 1 again <<<<\n"); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - SCMutexLock(&f->m); - AppLayerDecoderEvents *decoder_events = AppLayerParserGetDecoderEvents(f->alparser); - if (decoder_events != NULL) { - printf("app events: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test Test really long request, this should result in HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG */ -int HTPParserTest14(void) -{ - int result = 0; - Flow *f = NULL; - char *httpbuf = NULL; - size_t len = 18887; - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - double-decode-path: no\n\ - double-decode-query: no\n\ - request-body-limit: 0\n\ - response-body-limit: 0\n\ -"; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - - httpbuf = SCMalloc(len); - if (unlikely(httpbuf == NULL)) - goto end; - memset(httpbuf, 0x00, len); - - /* create the request with a longer than 18k cookie */ - strlcpy(httpbuf, "GET /blah/ HTTP/1.1\r\n" - "Host: myhost.lan\r\n" - "Connection: keep-alive\r\n" - "Accept: */*\r\n" - "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36\r\n" - "Referer: http://blah.lan/\r\n" - "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n" - "Cookie: ", len); - size_t o = strlen(httpbuf); - for ( ; o < len - 4; o++) { - httpbuf[o] = 'A'; - } - httpbuf[len - 4] = '\r'; - httpbuf[len - 3] = '\n'; - httpbuf[len - 2] = '\r'; - httpbuf[len - 1] = '\n'; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < len; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (len - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, (uint8_t *)&httpbuf[u], 1); - if (u < 18294) { /* first 18294 bytes should result in 0 */ - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - } else if (u == 18294UL) { /* byte 18294 should result in error */ - if (r != -1) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " -1: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - - /* break out, htp state is in error state now */ - SCMutexUnlock(&f->m); - break; - } - SCMutexUnlock(&f->m); - } - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL || tx->request_method_number != HTP_M_GET || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected method M_GET and got %s: , expected protocol " - "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - SCMutexLock(&f->m); - AppLayerDecoderEvents *decoder_events = AppLayerParserGetEventsByTx(IPPROTO_TCP, ALPROTO_HTTP,f->alstate, 0); - if (decoder_events == NULL) { - printf("no app events: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - if (decoder_events->events[0] != HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG) { - printf("HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG not set: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - if (httpbuf != NULL) - SCFree(httpbuf); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - return result; -} - -/** \test Test really long request (same as HTPParserTest14), now with config - * update to allow it */ -int HTPParserTest15(void) -{ - int result = 0; - Flow *f = NULL; - char *httpbuf = NULL; - size_t len = 18887; - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - double-decode-path: no\n\ - double-decode-query: no\n\ - request-body-limit: 0\n\ - response-body-limit: 0\n\ - meta-field-limit: 20000\n\ -"; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - - httpbuf = SCMalloc(len); - if (unlikely(httpbuf == NULL)) - goto end; - memset(httpbuf, 0x00, len); - - /* create the request with a longer than 18k cookie */ - strlcpy(httpbuf, "GET /blah/ HTTP/1.1\r\n" - "Host: myhost.lan\r\n" - "Connection: keep-alive\r\n" - "Accept: */*\r\n" - "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36\r\n" - "Referer: http://blah.lan/\r\n" - "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n" - "Cookie: ", len); - size_t o = strlen(httpbuf); - for ( ; o < len - 4; o++) { - httpbuf[o] = 'A'; - } - httpbuf[len - 4] = '\r'; - httpbuf[len - 3] = '\n'; - httpbuf[len - 2] = '\r'; - httpbuf[len - 1] = '\n'; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint32_t u; - for (u = 0; u < len; u++) { - uint8_t flags = 0; - - if (u == 0) flags = STREAM_TOSERVER|STREAM_START; - else if (u == (len - 1)) flags = STREAM_TOSERVER|STREAM_EOF; - else flags = STREAM_TOSERVER; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, (uint8_t *)&httpbuf[u], 1); - if (r != 0) { - printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" - " 0: ", u, r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - } - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL || tx->request_method_number != HTP_M_GET || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected method M_GET and got %s: , expected protocol " - "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - SCMutexLock(&f->m); - AppLayerDecoderEvents *decoder_events = AppLayerParserGetEventsByTx(IPPROTO_TCP, ALPROTO_HTTP,f->alstate, 0); - if (decoder_events != NULL) { - printf("app events: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - if (httpbuf != NULL) - SCFree(httpbuf); - HTPFreeConfig(); - ConfDeInit(); - ConfRestoreContextBackup(); - HtpConfigRestoreBackup(); - return result; -} - -/** \test Test unusual delims in request line HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG */ -int HTPParserTest16(void) -{ - int result = 0; - Flow *f = NULL; - TcpSession ssn; - HtpState *htp_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - uint8_t httpbuf[] = "GET\f/blah/\fHTTP/1.1\r\n" - "Host: myhost.lan\r\n" - "Connection: keep-alive\r\n" - "Accept: */*\r\n" - "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36\r\n" - "Referer: http://blah.lan/\r\n" - "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n" - "Cookie: blah\r\n\r\n"; - size_t len = sizeof(httpbuf) - 1; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - uint8_t flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF; - - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, flags, (uint8_t *)httpbuf, len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - htp_state = f->alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(htp_state, 0); - if (tx == NULL || tx->request_method_number != HTP_M_GET || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected method M_GET and got %s: , expected protocol " - "HTTP/1.1 and got %s \n", tx ? bstr_util_strdup_to_c(tx->request_method) : "tx null", - tx ? bstr_util_strdup_to_c(tx->request_protocol) : "tx null"); - goto end; - } - - SCMutexLock(&f->m); - AppLayerDecoderEvents *decoder_events = AppLayerParserGetEventsByTx(IPPROTO_TCP, ALPROTO_HTTP,f->alstate, 0); - if (decoder_events == NULL) { - printf("no app events: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - if (decoder_events->events[0] != HTTP_DECODER_EVENT_METHOD_DELIM_NON_COMPLIANT) { - printf("HTTP_DECODER_EVENT_METHOD_DELIM_NON_COMPLIANT not set: "); - goto end; - } - - if (decoder_events->events[1] != HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT) { - printf("HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT not set: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - UTHFreeFlow(f); - return result; -} - -/** \test CONNECT with plain text HTTP being tunneled */ -int HTPParserTest17(void) -{ - int result = 0; - Flow *f = NULL; - HtpState *http_state = NULL; - /* CONNECT setup */ - uint8_t httpbuf1[] = "CONNECT abc:443 HTTP/1.1\r\nUser-Agent: Victor/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.1 200 OK\r\nServer: VictorServer/1.0\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - /* plain text HTTP */ - uint8_t httpbuf3[] = "GET / HTTP/1.1\r\nUser-Agent: Victor/1.0\r\n\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "HTTP/1.1 200 OK\r\nServer: VictorServer/1.0\r\n\r\n"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, - httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, httpbuf2, - httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, - httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf4, - httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(http_state, 0); - if (tx == NULL) - goto end; - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (tx->request_method_number != HTP_M_CONNECT || - h == NULL || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected method M_POST and got %s: , expected protocol " - "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - if (tx->response_status_number != 200) { - printf("expected response 200 OK and got %"PRId32" %s: , expected protocol " - "HTTP/1.1 and got %s \n", tx->response_status_number, - bstr_util_strdup_to_c(tx->response_message), - bstr_util_strdup_to_c(tx->response_protocol)); - goto end; - } - - tx = HTPStateGetTx(http_state, 1); - if (tx == NULL) - goto end; - h = htp_table_get_index(tx->request_headers, 0, NULL); - if (tx->request_method_number != HTP_M_GET || - h == NULL || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected method M_GET and got %s: , expected protocol " - "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - if (tx->response_status_number != 200) { - printf("expected response 200 OK and got %"PRId32" %s: , expected protocol " - "HTTP/1.1 and got %s \n", tx->response_status_number, - bstr_util_strdup_to_c(tx->response_message), - bstr_util_strdup_to_c(tx->response_protocol)); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test CONNECT with plain text HTTP being tunneled */ -int HTPParserTest18(void) -{ - int result = 0; - Flow *f = NULL; - HtpState *http_state = NULL; - /* CONNECT setup */ - uint8_t httpbuf1[] = "CONNECT abc:443 HTTP/1.1\r\nUser-Agent: Victor/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.1 200 OK\r\nServer: VictorServer/1.0\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - /* plain text HTTP */ - uint8_t httpbuf3[] = "GE"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "T / HTTP/1.1\r\nUser-Agent: Victor/1.0\r\n\r\n"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "HTTP/1.1 200 OK\r\nServer: VictorServer/1.0\r\n\r\n"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, - httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, httpbuf2, - httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, - httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, - httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf5, - httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(http_state, 0); - if (tx == NULL) - goto end; - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (tx->request_method_number != HTP_M_CONNECT || - h == NULL || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected method M_POST and got %s: , expected protocol " - "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - if (tx->response_status_number != 200) { - printf("expected response 200 OK and got %"PRId32" %s: , expected protocol " - "HTTP/1.1 and got %s \n", tx->response_status_number, - bstr_util_strdup_to_c(tx->response_message), - bstr_util_strdup_to_c(tx->response_protocol)); - goto end; - } - - tx = HTPStateGetTx(http_state, 1); - if (tx == NULL) - goto end; - h = htp_table_get_index(tx->request_headers, 0, NULL); - if (tx->request_method_number != HTP_M_GET || - h == NULL || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected method M_GET and got %s: , expected protocol " - "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - if (tx->response_status_number != 200) { - printf("expected response 200 OK and got %"PRId32" %s: , expected protocol " - "HTTP/1.1 and got %s \n", tx->response_status_number, - bstr_util_strdup_to_c(tx->response_message), - bstr_util_strdup_to_c(tx->response_protocol)); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -/** \test CONNECT with TLS content (start of it at least) */ -int HTPParserTest19(void) -{ - int result = 0; - Flow *f = NULL; - HtpState *http_state = NULL; - /* CONNECT setup */ - uint8_t httpbuf1[] = "CONNECT abc:443 HTTP/1.1\r\nUser-Agent: Victor/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.1 200 OK\r\nServer: VictorServer/1.0\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - /* start of TLS/SSL */ - uint8_t httpbuf3[] = "\x16\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, - httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, httpbuf2, - httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER, - httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f->m); - goto end; - } - - SCMutexUnlock(&f->m); - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = HTPStateGetTx(http_state, 0); - if (tx == NULL) - goto end; - htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL); - if (tx->request_method_number != HTP_M_CONNECT || - h == NULL || tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - printf("expected method M_POST and got %s: , expected protocol " - "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method), - bstr_util_strdup_to_c(tx->request_protocol)); - goto end; - } - - if (tx->response_status_number != 200) { - printf("expected response 200 OK and got %"PRId32" %s: , expected protocol " - "HTTP/1.1 and got %s \n", tx->response_status_number, - bstr_util_strdup_to_c(tx->response_message), - bstr_util_strdup_to_c(tx->response_protocol)); - goto end; - } - - /* no new tx should have been set up for the tunneled data */ - tx = HTPStateGetTx(http_state, 1); - if (tx != NULL) - goto end; - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (http_state != NULL) - HTPStateFree(http_state); - UTHFreeFlow(f); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief Register the Unit tests for the HTTP protocol - */ -void HTPParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("HTPParserTest01", HTPParserTest01, 1); - UtRegisterTest("HTPParserTest01a", HTPParserTest01a, 1); - UtRegisterTest("HTPParserTest02", HTPParserTest02, 1); - UtRegisterTest("HTPParserTest03", HTPParserTest03, 1); - UtRegisterTest("HTPParserTest04", HTPParserTest04, 1); - UtRegisterTest("HTPParserTest05", HTPParserTest05, 1); - UtRegisterTest("HTPParserTest06", HTPParserTest06, 1); - UtRegisterTest("HTPParserTest07", HTPParserTest07, 1); - UtRegisterTest("HTPParserTest08", HTPParserTest08, 1); - UtRegisterTest("HTPParserTest09", HTPParserTest09, 1); - UtRegisterTest("HTPParserTest10", HTPParserTest10, 1); - UtRegisterTest("HTPParserTest11", HTPParserTest11, 1); - UtRegisterTest("HTPParserTest12", HTPParserTest12, 1); - UtRegisterTest("HTPParserTest13", HTPParserTest13, 1); - UtRegisterTest("HTPParserConfigTest01", HTPParserConfigTest01, 1); - UtRegisterTest("HTPParserConfigTest02", HTPParserConfigTest02, 1); - UtRegisterTest("HTPParserConfigTest03", HTPParserConfigTest03, 1); -#if 0 /* disabled when we upgraded to libhtp 0.5.x */ - UtRegisterTest("HTPParserConfigTest04", HTPParserConfigTest04, 1); -#endif - - UtRegisterTest("HTPParserDecodingTest01", HTPParserDecodingTest01, 1); - UtRegisterTest("HTPParserDecodingTest02", HTPParserDecodingTest02, 1); - UtRegisterTest("HTPParserDecodingTest03", HTPParserDecodingTest03, 1); - UtRegisterTest("HTPParserDecodingTest04", HTPParserDecodingTest04, 1); - UtRegisterTest("HTPParserDecodingTest05", HTPParserDecodingTest05, 1); - UtRegisterTest("HTPParserDecodingTest06", HTPParserDecodingTest06, 1); - UtRegisterTest("HTPParserDecodingTest07", HTPParserDecodingTest07, 1); - UtRegisterTest("HTPParserDecodingTest08", HTPParserDecodingTest08, 1); - UtRegisterTest("HTPParserDecodingTest09", HTPParserDecodingTest09, 1); - - UtRegisterTest("HTPBodyReassemblyTest01", HTPBodyReassemblyTest01, 1); - - UtRegisterTest("HTPSegvTest01", HTPSegvTest01, 1); - - UtRegisterTest("HTPParserTest14", HTPParserTest14, 1); - UtRegisterTest("HTPParserTest15", HTPParserTest15, 1); - UtRegisterTest("HTPParserTest16", HTPParserTest16, 1); - UtRegisterTest("HTPParserTest17", HTPParserTest17, 1); - UtRegisterTest("HTPParserTest18", HTPParserTest18, 1); - UtRegisterTest("HTPParserTest19", HTPParserTest19, 1); - - HTPFileParserRegisterTests(); - HTPXFFParserRegisterTests(); -#endif /* UNITTESTS */ -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/app-layer-htp.h b/framework/src/suricata/src/app-layer-htp.h deleted file mode 100644 index 275bc4b7..00000000 --- a/framework/src/suricata/src/app-layer-htp.h +++ /dev/null @@ -1,294 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \defgroup httplayer HTTP layer support - * - * @{ - */ - -/** - * \file - * - * \author Gurvinder Singh - * \author Pablo Rincon - * - * This file provides a HTTP protocol support for the engine using HTP library. - */ - -#ifndef __APP_LAYER_HTP_H__ -#define __APP_LAYER_HTP_H__ - -#include "util-radix-tree.h" -#include "util-file.h" -#include "app-layer-htp-mem.h" -#include "detect-engine-state.h" - -#include - -/* default request body limit */ -#define HTP_CONFIG_DEFAULT_REQUEST_BODY_LIMIT 4096U -#define HTP_CONFIG_DEFAULT_RESPONSE_BODY_LIMIT 4096U -#define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_MIN_SIZE 32768U -#define HTP_CONFIG_DEFAULT_REQUEST_INSPECT_WINDOW 4096U -#define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_MIN_SIZE 32768U -#define HTP_CONFIG_DEFAULT_RESPONSE_INSPECT_WINDOW 4096U -#define HTP_CONFIG_DEFAULT_FIELD_LIMIT_SOFT 9000U -#define HTP_CONFIG_DEFAULT_FIELD_LIMIT_HARD 18000U - -#define HTP_CONFIG_DEFAULT_RANDOMIZE 1 -#define HTP_CONFIG_DEFAULT_RANDOMIZE_RANGE 10 - -/** a boundary should be smaller in size */ -#define HTP_BOUNDARY_MAX 200U - -#define HTP_FLAG_STATE_OPEN 0x0001 /**< Flag to indicate that HTTP - connection is open */ -#define HTP_FLAG_STATE_CLOSED_TS 0x0002 /**< Flag to indicate that HTTP - connection is closed */ -#define HTP_FLAG_STATE_CLOSED_TC 0x0004 /**< Flag to indicate that HTTP - connection is closed */ -#define HTP_FLAG_STATE_DATA 0x0008 /**< Flag to indicate that HTTP - connection needs more data */ -#define HTP_FLAG_STATE_ERROR 0x0010 /**< Flag to indicate that an error - has been occured on HTTP - connection */ -#define HTP_FLAG_NEW_BODY_SET 0x0020 /**< Flag to indicate that HTTP - has parsed a new body (for - pcre) */ -#define HTP_FLAG_STORE_FILES_TS 0x0040 -#define HTP_FLAG_STORE_FILES_TC 0x0080 -#define HTP_FLAG_STORE_FILES_TX_TS 0x0100 -#define HTP_FLAG_STORE_FILES_TX_TC 0x0200 -/** flag the state that a new file has been set in this tx */ -#define HTP_FLAG_NEW_FILE_TX_TS 0x0400 -/** flag the state that a new file has been set in this tx */ -#define HTP_FLAG_NEW_FILE_TX_TC 0x0800 - -enum { - HTP_BODY_NONE = 0, /**< Flag to indicate the current - operation */ - HTP_BODY_REQUEST, /**< Flag to indicate that the - current operation is a request */ - HTP_BODY_RESPONSE /**< Flag to indicate that the current - * operation is a response */ -}; - -enum { - HTP_BODY_REQUEST_NONE = 0, - HTP_BODY_REQUEST_MULTIPART, /* POST, MP */ - HTP_BODY_REQUEST_POST, /* POST, no MP */ - HTP_BODY_REQUEST_PUT, -}; - -enum { - /* libhtp errors/warnings */ - HTTP_DECODER_EVENT_UNKNOWN_ERROR, - HTTP_DECODER_EVENT_GZIP_DECOMPRESSION_FAILED, - HTTP_DECODER_EVENT_REQUEST_FIELD_MISSING_COLON, - HTTP_DECODER_EVENT_RESPONSE_FIELD_MISSING_COLON, - HTTP_DECODER_EVENT_INVALID_REQUEST_CHUNK_LEN, - HTTP_DECODER_EVENT_INVALID_RESPONSE_CHUNK_LEN, - HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST, - HTTP_DECODER_EVENT_INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE, - HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST, - HTTP_DECODER_EVENT_INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE, - HTTP_DECODER_EVENT_100_CONTINUE_ALREADY_SEEN, - HTTP_DECODER_EVENT_UNABLE_TO_MATCH_RESPONSE_TO_REQUEST, - HTTP_DECODER_EVENT_INVALID_SERVER_PORT_IN_REQUEST, - HTTP_DECODER_EVENT_INVALID_AUTHORITY_PORT, - HTTP_DECODER_EVENT_REQUEST_HEADER_INVALID, - HTTP_DECODER_EVENT_RESPONSE_HEADER_INVALID, - HTTP_DECODER_EVENT_MISSING_HOST_HEADER, - HTTP_DECODER_EVENT_HOST_HEADER_AMBIGUOUS, - HTTP_DECODER_EVENT_INVALID_REQUEST_FIELD_FOLDING, - HTTP_DECODER_EVENT_INVALID_RESPONSE_FIELD_FOLDING, - HTTP_DECODER_EVENT_REQUEST_FIELD_TOO_LONG, - HTTP_DECODER_EVENT_RESPONSE_FIELD_TOO_LONG, - HTTP_DECODER_EVENT_REQUEST_SERVER_PORT_TCP_PORT_MISMATCH, - HTTP_DECODER_EVENT_URI_HOST_INVALID, - HTTP_DECODER_EVENT_HEADER_HOST_INVALID, - HTTP_DECODER_EVENT_METHOD_DELIM_NON_COMPLIANT, - HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT, - HTTP_DECODER_EVENT_REQUEST_LINE_LEADING_WHITESPACE, - - /* suricata errors/warnings */ - HTTP_DECODER_EVENT_MULTIPART_GENERIC_ERROR, - HTTP_DECODER_EVENT_MULTIPART_NO_FILEDATA, - HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER, -}; - -#define HTP_PCRE_NONE 0x00 /**< No pcre executed yet */ -#define HTP_PCRE_DONE 0x01 /**< Flag to indicate that pcre has - done some inspection in the - chunks */ -#define HTP_PCRE_HAS_MATCH 0x02 /**< Flag to indicate that the chunks - matched on some rule */ - -/** Need a linked list in order to keep track of these */ -typedef struct HTPCfgRec_ { - htp_cfg_t *cfg; - struct HTPCfgRec_ *next; - - int uri_include_all; /**< use all info in uri (bool) */ - - /** max size of the client body we inspect */ - uint32_t request_body_limit; - uint32_t response_body_limit; - - uint32_t request_inspect_min_size; - uint32_t request_inspect_window; - - uint32_t response_inspect_min_size; - uint32_t response_inspect_window; - int randomize; - int randomize_range; - int http_body_inline; -} HTPCfgRec; - -/** Struct used to hold chunks of a body on a request */ -struct HtpBodyChunk_ { - uint8_t *data; /**< Pointer to the data of the chunk */ - struct HtpBodyChunk_ *next; /**< Pointer to the next chunk */ - uint64_t stream_offset; - uint32_t len; /**< Length of the chunk */ - int logged; -} __attribute__((__packed__)); -typedef struct HtpBodyChunk_ HtpBodyChunk; - -/** Struct used to hold all the chunks of a body on a request */ -typedef struct HtpBody_ { - HtpBodyChunk *first; /**< Pointer to the first chunk */ - HtpBodyChunk *last; /**< Pointer to the last chunk */ - - /* Holds the length of the htp request body seen so far */ - uint64_t content_len_so_far; - /* parser tracker */ - uint64_t body_parsed; - /* inspection tracker */ - uint64_t body_inspected; -} HtpBody; - -#define HTP_CONTENTTYPE_SET 0x01 /**< We have the content type */ -#define HTP_BOUNDARY_SET 0x02 /**< We have a boundary string */ -#define HTP_BOUNDARY_OPEN 0x04 /**< We have a boundary string */ -#define HTP_FILENAME_SET 0x08 /**< filename is registered in the flow */ -#define HTP_DONTSTORE 0x10 /**< not storing this file */ - -#define HTP_TX_HAS_FILE 0x01 -#define HTP_TX_HAS_FILENAME 0x02 /**< filename is known at this time */ -#define HTP_TX_HAS_TYPE 0x04 -#define HTP_TX_HAS_FILECONTENT 0x08 /**< file has content so we can do type detect */ - -#define HTP_RULE_NEED_FILE HTP_TX_HAS_FILE -#define HTP_RULE_NEED_FILENAME HTP_TX_HAS_FILENAME -#define HTP_RULE_NEED_TYPE HTP_TX_HAS_TYPE -#define HTP_RULE_NEED_FILECONTENT HTP_TX_HAS_FILECONTENT - -/** Now the Body Chunks will be stored per transaction, at - * the tx user data */ -typedef struct HtpTxUserData_ { - /* Body of the request (if any) */ - uint8_t request_body_init; - uint8_t response_body_init; - HtpBody request_body; - HtpBody response_body; - - bstr *request_uri_normalized; - - uint8_t *request_headers_raw; - uint8_t *response_headers_raw; - uint32_t request_headers_raw_len; - uint32_t response_headers_raw_len; - - AppLayerDecoderEvents *decoder_events; /**< per tx events */ - - /** Holds the boundary identificator string if any (used on - * multipart/form-data only) - */ - uint8_t *boundary; - uint8_t boundary_len; - - uint8_t tsflags; - uint8_t tcflags; - - int16_t operation; - - uint8_t request_body_type; - uint8_t response_body_type; - - DetectEngineState *de_state; -} HtpTxUserData; - -typedef struct HtpState_ { - - /* Connection parser structure for each connection */ - htp_connp_t *connp; - /* Connection structure for each connection */ - htp_conn_t *conn; - Flow *f; /**< Needed to retrieve the original flow when usin HTPLib callbacks */ - uint64_t transaction_cnt; - uint64_t store_tx_id; - FileContainer *files_ts; - FileContainer *files_tc; - struct HTPCfgRec_ *cfg; - uint16_t flags; - uint16_t events; - uint16_t htp_messages_offset; /**< offset into conn->messages list */ - uint64_t tx_with_detect_state_cnt; -} HtpState; - -/** part of the engine needs the request body (e.g. http_client_body keyword) */ -#define HTP_REQUIRE_REQUEST_BODY (1 << 0) -/** part of the engine needs the request body multipart header (e.g. filename - * and / or fileext keywords) */ -#define HTP_REQUIRE_REQUEST_MULTIPART (1 << 1) -/** part of the engine needs the request file (e.g. log-file module) */ -#define HTP_REQUIRE_REQUEST_FILE (1 << 2) -/** part of the engine needs the request body (e.g. file_data keyword) */ -#define HTP_REQUIRE_RESPONSE_BODY (1 << 3) - -SC_ATOMIC_DECLARE(uint32_t, htp_config_flags); - -void RegisterHTPParsers(void); -void HTPParserRegisterTests(void); -void HTPAtExitPrintStats(void); -void HTPFreeConfig(void); - -htp_tx_t *HTPTransactionMain(const HtpState *); - -int HTPCallbackRequestBodyData(htp_tx_data_t *); -int HtpTransactionGetLoggableId(Flow *); -void HtpBodyPrint(HtpBody *); -void HtpBodyFree(HtpBody *); -/* To free the state from unittests using app-layer-htp */ -void HTPStateFree(void *); -void AppLayerHtpEnableRequestBodyCallback(void); -void AppLayerHtpEnableResponseBodyCallback(void); -void AppLayerHtpNeedFileInspection(void); -void AppLayerHtpPrintStats(void); - -void HTPConfigure(void); - -void HtpConfigCreateBackup(void); -void HtpConfigRestoreBackup(void); - -#endif /* __APP_LAYER_HTP_H__ */ - -/** - * @} - */ diff --git a/framework/src/suricata/src/app-layer-modbus.c b/framework/src/suricata/src/app-layer-modbus.c deleted file mode 100644 index fa965135..00000000 --- a/framework/src/suricata/src/app-layer-modbus.c +++ /dev/null @@ -1,2671 +0,0 @@ -/* - * Copyright (C) 2014 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author David DIALLO - * - * App-layer parser for Modbus protocol - * - */ - -#include "suricata-common.h" - -#include "util-debug.h" -#include "util-byte.h" -#include "util-enum.h" -#include "util-mem.h" -#include "util-misc.h" - -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-modbus.h" - -#include "app-layer-detect-proto.h" - -#include "conf.h" -#include "decode.h" - -SCEnumCharMap modbus_decoder_event_table[ ] = { - /* Modbus Application Data Unit messages - ADU Modbus */ - { "INVALID_PROTOCOL_ID", MODBUS_DECODER_EVENT_INVALID_PROTOCOL_ID }, - { "UNSOLICITED_RESPONSE", MODBUS_DECODER_EVENT_UNSOLICITED_RESPONSE }, - { "INVALID_LENGTH", MODBUS_DECODER_EVENT_INVALID_LENGTH }, - { "INVALID_UNIT_IDENTIFIER", MODBUS_DECODER_EVENT_INVALID_UNIT_IDENTIFIER}, - - /* Modbus Protocol Data Unit messages - PDU Modbus */ - { "INVALID_FUNCTION_CODE", MODBUS_DECODER_EVENT_INVALID_FUNCTION_CODE }, - { "INVALID_VALUE", MODBUS_DECODER_EVENT_INVALID_VALUE }, - { "INVALID_EXCEPTION_CODE", MODBUS_DECODER_EVENT_INVALID_EXCEPTION_CODE }, - { "VALUE_MISMATCH", MODBUS_DECODER_EVENT_VALUE_MISMATCH }, - - /* Modbus Decoder event */ - { "FLOODED", MODBUS_DECODER_EVENT_FLOODED}, - { NULL, -1 }, -}; - -/* Modbus Application Data Unit (ADU) length range. */ -#define MODBUS_MIN_ADU_LEN 2 -#define MODBUS_MAX_ADU_LEN 254 - -/* Modbus Protocol version. */ -#define MODBUS_PROTOCOL_VER 0 - -/* Modbus Unit Identifier range. */ -#define MODBUS_MIN_INVALID_UNIT_ID 247 -#define MODBUS_MAX_INVALID_UNIT_ID 255 - -/* Modbus Quantity range. */ -#define MODBUS_MIN_QUANTITY 0 -#define MODBUS_MAX_QUANTITY_IN_BIT_ACCESS 2000 -#define MODBUS_MAX_QUANTITY_IN_WORD_ACCESS 125 - -/* Modbus Count range. */ -#define MODBUS_MIN_COUNT 1 -#define MODBUS_MAX_COUNT 250 - -/* Modbus Function Code. */ -#define MODBUS_FUNC_NONE 0x00 -#define MODBUS_FUNC_READCOILS 0x01 -#define MODBUS_FUNC_READDISCINPUTS 0x02 -#define MODBUS_FUNC_READHOLDREGS 0x03 -#define MODBUS_FUNC_READINPUTREGS 0x04 -#define MODBUS_FUNC_WRITESINGLECOIL 0x05 -#define MODBUS_FUNC_WRITESINGLEREG 0x06 -#define MODBUS_FUNC_READEXCSTATUS 0x07 -#define MODBUS_FUNC_DIAGNOSTIC 0x08 -#define MODBUS_FUNC_GETCOMEVTCOUNTER 0x0b -#define MODBUS_FUNC_GETCOMEVTLOG 0x0c -#define MODBUS_FUNC_WRITEMULTCOILS 0x0f -#define MODBUS_FUNC_WRITEMULTREGS 0x10 -#define MODBUS_FUNC_REPORTSERVERID 0x11 -#define MODBUS_FUNC_READFILERECORD 0x14 -#define MODBUS_FUNC_WRITEFILERECORD 0x15 -#define MODBUS_FUNC_MASKWRITEREG 0x16 -#define MODBUS_FUNC_READWRITEMULTREGS 0x17 -#define MODBUS_FUNC_READFIFOQUEUE 0x18 -#define MODBUS_FUNC_ENCAPINTTRANS 0x2b -#define MODBUS_FUNC_MASK 0x7f -#define MODBUS_FUNC_ERRORMASK 0x80 - -/* Modbus Diagnostic functions: Subfunction Code. */ -#define MODBUS_SUBFUNC_QUERY_DATA 0x00 -#define MODBUS_SUBFUNC_RESTART_COM 0x01 -#define MODBUS_SUBFUNC_DIAG_REGS 0x02 -#define MODBUS_SUBFUNC_CHANGE_DELIMITER 0x03 -#define MODBUS_SUBFUNC_LISTEN_MODE 0x04 -#define MODBUS_SUBFUNC_CLEAR_REGS 0x0a -#define MODBUS_SUBFUNC_BUS_MSG_COUNT 0x0b -#define MODBUS_SUBFUNC_COM_ERR_COUNT 0x0c -#define MODBUS_SUBFUNC_EXCEPT_ERR_COUNT 0x0d -#define MODBUS_SUBFUNC_SERVER_MSG_COUNT 0x0e -#define MODBUS_SUBFUNC_SERVER_NO_RSP_COUNT 0x0f -#define MODBUS_SUBFUNC_SERVER_NAK_COUNT 0x10 -#define MODBUS_SUBFUNC_SERVER_BUSY_COUNT 0x11 -#define MODBUS_SUBFUNC_SERVER_CHAR_COUNT 0x12 -#define MODBUS_SUBFUNC_CLEAR_COUNT 0x14 - -/* Modbus Encapsulated Interface Transport function: MEI type. */ -#define MODBUS_MEI_ENCAPINTTRANS_CAN 0x0d -#define MODBUS_MEI_ENCAPINTTRANS_READ 0x0e - -/* Modbus Exception Codes. */ -#define MODBUS_ERROR_CODE_ILLEGAL_FUNCTION 0x01 -#define MODBUS_ERROR_CODE_ILLEGAL_DATA_ADDRESS 0x02 -#define MODBUS_ERROR_CODE_ILLEGAL_DATA_VALUE 0x03 -#define MODBUS_ERROR_CODE_SERVER_DEVICE_FAILURE 0x04 -#define MODBUS_ERROR_CODE_MEMORY_PARITY_ERROR 0x08 - -/* Modbus Application Protocol (MBAP) header. */ -struct ModbusHeader_ { - uint16_t transactionId; - uint16_t protocolId; - uint16_t length; - uint8_t unitId; -} __attribute__((__packed__)); -typedef struct ModbusHeader_ ModbusHeader; - -/* Modbus Read/Write function and Access Types. */ -#define MODBUS_TYP_WRITE_SINGLE (MODBUS_TYP_WRITE | MODBUS_TYP_SINGLE) -#define MODBUS_TYP_WRITE_MULTIPLE (MODBUS_TYP_WRITE | MODBUS_TYP_MULTIPLE) -#define MODBUS_TYP_READ_WRITE_MULTIPLE (MODBUS_TYP_READ | MODBUS_TYP_WRITE | MODBUS_TYP_MULTIPLE) - -/* Macro to convert quantity value (in bit) into count value (in word): count = Ceil(quantity/8) */ -#define CEIL(quantity) (((quantity) + 7)>>3) - -/* Modbus Default unreplied Modbus requests are considered a flood */ -#define MODBUS_CONFIG_DEFAULT_REQUEST_FLOOD 500 - -static uint32_t request_flood = MODBUS_CONFIG_DEFAULT_REQUEST_FLOOD; - -int ModbusStateGetEventInfo(const char *event_name, int *event_id, AppLayerEventType *event_type) { - *event_id = SCMapEnumNameToValue(event_name, modbus_decoder_event_table); - - if (*event_id == -1) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " - "modbus's enum map table.", event_name); - /* yes this is fatal */ - return -1; - } - - *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; - - return 0; -} - -void ModbusSetEvent(ModbusState *modbus, uint8_t e) { - if (modbus && modbus->curr) { - SCLogDebug("modbus->curr->decoder_events %p", modbus->curr->decoder_events); - AppLayerDecoderEventsSetEventRaw(&modbus->curr->decoder_events, e); - SCLogDebug("modbus->curr->decoder_events %p", modbus->curr->decoder_events); - modbus->events++; - } else - SCLogDebug("couldn't set event %u", e); -} - -AppLayerDecoderEvents *ModbusGetEvents(void *state, uint64_t id) { - ModbusState *modbus = (ModbusState *) state; - ModbusTransaction *tx; - - if (modbus->curr && modbus->curr->tx_num == (id + 1)) - return modbus->curr->decoder_events; - - TAILQ_FOREACH(tx, &modbus->tx_list, next) { - if (tx->tx_num == (id+1)) - return tx->decoder_events; - } - - return NULL; -} - -int ModbusHasEvents(void *state) { - return (((ModbusState *) state)->events > 0); -} - -int ModbusGetAlstateProgress(void *modbus_tx, uint8_t direction) { - ModbusTransaction *tx = (ModbusTransaction *) modbus_tx; - ModbusState *modbus = tx->modbus; - - if (tx->replied == 1) - return 1; - - /* Check flood limit */ - if ((modbus->givenup == 1) && - ((modbus->transaction_max - tx->tx_num) > request_flood)) - return 1; - - return 0; -} - -/** \brief Get value for 'complete' status in Modbus - */ -int ModbusGetAlstateProgressCompletionStatus(uint8_t direction) { - return 1; -} - -void *ModbusGetTx(void *alstate, uint64_t tx_id) { - ModbusState *modbus = (ModbusState *) alstate; - ModbusTransaction *tx = NULL; - - if (modbus->curr && modbus->curr->tx_num == tx_id + 1) - return modbus->curr; - - TAILQ_FOREACH(tx, &modbus->tx_list, next) { - SCLogDebug("tx->tx_num %"PRIu64", tx_id %"PRIu64, tx->tx_num, (tx_id+1)); - if (tx->tx_num != (tx_id+1)) - continue; - - SCLogDebug("returning tx %p", tx); - return tx; - } - - return NULL; -} - -uint64_t ModbusGetTxCnt(void *alstate) { - return ((uint64_t) ((ModbusState *) alstate)->transaction_max); -} - -/** \internal - * \brief Find the Modbus Transaction in the state based on Transaction ID. - * - * \param modbus Pointer to Modbus state structure - * \param transactionId Transaction ID of the transaction - * - * \retval tx or NULL if not found - */ -static ModbusTransaction *ModbusTxFindByTransaction(const ModbusState *modbus, - const uint16_t transactionId) { - ModbusTransaction *tx = NULL; - - if (modbus->curr == NULL) - return NULL; - - /* fast path */ - if ((modbus->curr->transactionId == transactionId) && - !(modbus->curr->replied)) { - return modbus->curr; - /* slow path, iterate list */ - } else { - TAILQ_FOREACH(tx, &modbus->tx_list, next) { - if ((tx->transactionId == transactionId) && - !(modbus->curr->replied)) - return tx; - } - } - /* not found */ - return NULL; -} - -/** \internal - * \brief Allocate a Modbus Transaction and - * add it into Transaction list of Modbus State - * - * \param modbus Pointer to Modbus state structure - * - * \retval Pointer to Transaction or NULL pointer - */ -static ModbusTransaction *ModbusTxAlloc(ModbusState *modbus) { - ModbusTransaction *tx; - - tx = (ModbusTransaction *) SCCalloc(1, sizeof(ModbusTransaction)); - if (unlikely(tx == NULL)) - return NULL; - - modbus->transaction_max++; - modbus->unreplied_cnt++; - - /* Check flood limit */ - if ((request_flood != 0) && (modbus->unreplied_cnt > request_flood)) { - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_FLOODED); - modbus->givenup = 1; - } - - modbus->curr = tx; - - SCLogDebug("modbus->transaction_max updated to %"PRIu64, modbus->transaction_max); - - TAILQ_INSERT_TAIL(&modbus->tx_list, tx, next); - - tx->modbus = modbus; - tx->tx_num = modbus->transaction_max; - - return tx; -} - -/** \internal - * \brief Free a Modbus Transaction - * - * \retval Pointer to Transaction or NULL pointer - */ -static void ModbusTxFree(ModbusTransaction *tx) { - SCEnter(); - if (tx->data != NULL) - SCFree(tx->data); - - AppLayerDecoderEventsFreeEvents(&tx->decoder_events); - - if (tx->de_state != NULL) - DetectEngineStateFree(tx->de_state); - - SCFree(tx); - SCReturn; -} - -/** - * \brief Modbus transaction cleanup callback - */ -void ModbusStateTxFree(void *state, uint64_t tx_id) { - SCEnter(); - ModbusState *modbus = (ModbusState *) state; - ModbusTransaction *tx = NULL, *ttx; - - SCLogDebug("state %p, id %"PRIu64, modbus, tx_id); - - TAILQ_FOREACH_SAFE(tx, &modbus->tx_list, next, ttx) { - SCLogDebug("tx %p tx->tx_num %"PRIu64", tx_id %"PRIu64, tx, tx->tx_num, (tx_id+1)); - - if (tx->tx_num != (tx_id+1)) - continue; - - if (tx == modbus->curr) - modbus->curr = NULL; - - if (tx->decoder_events != NULL) { - if (tx->decoder_events->cnt <= modbus->events) - modbus->events -= tx->decoder_events->cnt; - else - modbus->events = 0; - } - - modbus->unreplied_cnt--; - - /* Check flood limit */ - if ((modbus->givenup == 1) && - (request_flood != 0) && - (modbus->unreplied_cnt < request_flood) ) - modbus->givenup = 0; - - TAILQ_REMOVE(&modbus->tx_list, tx, next); - ModbusTxFree(tx); - break; - } - SCReturn; -} - -/** \internal - * \brief Extract 8bits data from pointer the received input data - * - * \param res Pointer to the result - * \param input Pointer the received input data - * \param input_len Length of the received input data - * \param offset Offset of the received input data pointer - */ -static int ModbusExtractUint8(ModbusState *modbus, - uint8_t *res, - uint8_t *input, - uint32_t input_len, - uint16_t *offset) { - SCEnter(); - if (input_len < (uint32_t) (*offset + sizeof(uint8_t))) { - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_LENGTH); - SCReturnInt(-1); - } - - *res = *(input + *offset); - *offset += sizeof(uint8_t); - SCReturnInt(0); -} - -/** \internal - * \brief Extract 16bits data from pointer the received input data - * - * \param res Pointer to the result - * \param input Pointer the received input data - * \param input_len Length of the received input data - * \param offset Offset of the received input data pointer - */ -static int ModbusExtractUint16(ModbusState *modbus, - uint16_t *res, - uint8_t *input, - uint32_t input_len, - uint16_t *offset) { - SCEnter(); - if (input_len < (uint32_t) (*offset + sizeof(uint16_t))) { - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_LENGTH); - SCReturnInt(-1); - } - - ByteExtractUint16(res, BYTE_BIG_ENDIAN, sizeof(uint16_t), (const uint8_t *) (input + *offset)); - *offset += sizeof(uint16_t); - SCReturnInt(0); -} - -/** \internal - * \brief Check length field in Modbus header according to code function - * - * \param modbus Pointer to Modbus state structure - * \param length Length field in Modbus Header - * \param len Length according to code functio - */ -static int ModbusCheckHeaderLength(ModbusState *modbus, - uint16_t length, - uint16_t len) { - SCEnter(); - if (length != len) { - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_LENGTH); - SCReturnInt(-1); - } - SCReturnInt(0); -} - -/** \internal - * \brief Check Modbus header - * - * \param tx Pointer to Modbus Transaction structure - * \param modbus Pointer to Modbus state structure - * \param header Pointer to Modbus header state in which the value to be stored - */ -static void ModbusCheckHeader(ModbusState *modbus, - ModbusHeader *header) -{ - SCEnter(); - /* MODBUS protocol is identified by the value 0. */ - if (header->protocolId != MODBUS_PROTOCOL_VER) - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_PROTOCOL_ID); - - /* Check Length field that is a byte count of the following fields */ - if ((header->length < MODBUS_MIN_ADU_LEN) || - (header->length > MODBUS_MAX_ADU_LEN) ) - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_LENGTH); - - /* Check Unit Identifier field that is not in invalid range */ - if ((header->unitId > MODBUS_MIN_INVALID_UNIT_ID) && - (header->unitId < MODBUS_MAX_INVALID_UNIT_ID) ) - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_UNIT_IDENTIFIER); - - SCReturn; -} - -/** \internal - * \brief Parse Exception Response and verify protocol compliance. - * - * \param tx Pointer to Modbus Transaction structure - * \param modbus Pointer to Modbus state structure - * \param input Pointer the received input data - * \param input_len Length of the received input data - * \param offset Offset of the received input data pointer - */ -static void ModbusExceptionResponse(ModbusTransaction *tx, - ModbusState *modbus, - uint8_t *input, - uint32_t input_len, - uint16_t *offset) -{ - SCEnter(); - uint8_t exception; - - /* Exception code (1 byte) */ - if (ModbusExtractUint8(modbus, &exception, input, input_len, offset)) - SCReturn; - - switch (exception) { - case MODBUS_ERROR_CODE_ILLEGAL_FUNCTION: - case MODBUS_ERROR_CODE_SERVER_DEVICE_FAILURE: - break; - case MODBUS_ERROR_CODE_ILLEGAL_DATA_VALUE: - if (tx->function == MODBUS_FUNC_DIAGNOSTIC) { - break; - } - /* Fallthrough */ - case MODBUS_ERROR_CODE_ILLEGAL_DATA_ADDRESS: - if ( (tx->type & MODBUS_TYP_ACCESS_FUNCTION_MASK) || - (tx->function == MODBUS_FUNC_READFIFOQUEUE) || - (tx->function == MODBUS_FUNC_ENCAPINTTRANS)) { - break; - } - /* Fallthrough */ - case MODBUS_ERROR_CODE_MEMORY_PARITY_ERROR: - if ( (tx->function == MODBUS_FUNC_READFILERECORD) || - (tx->function == MODBUS_FUNC_WRITEFILERECORD) ) { - break; - } - /* Fallthrough */ - default: - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_EXCEPTION_CODE); - break; - } - - SCReturn; -} - -/** \internal - * \brief Parse Read data Request, complete Transaction structure - * and verify protocol compliance. - * - * \param tx Pointer to Modbus Transaction structure - * \param modbus Pointer to Modbus state structure - * \param input Pointer the received input data - * \param input_len Length of the received input data - * \param offset Offset of the received input data pointer - */ -static void ModbusParseReadRequest(ModbusTransaction *tx, - ModbusState *modbus, - uint8_t *input, - uint32_t input_len, - uint16_t *offset) -{ - SCEnter(); - uint16_t quantity; - uint8_t type = tx->type; - - /* Starting Address (2 bytes) */ - if (ModbusExtractUint16(modbus, &(tx->read.address), input, input_len, offset)) - goto end; - - /* Quantity (2 bytes) */ - if (ModbusExtractUint16(modbus, &(tx->read.quantity), input, input_len, offset)) - goto end; - quantity = tx->read.quantity; - - /* Check Quantity range */ - if (type & MODBUS_TYP_BIT_ACCESS_MASK) { - if ((quantity == MODBUS_MIN_QUANTITY) || - (quantity > MODBUS_MAX_QUANTITY_IN_BIT_ACCESS)) - goto error; - } else { - if ((quantity == MODBUS_MIN_QUANTITY) || - (quantity > MODBUS_MAX_QUANTITY_IN_WORD_ACCESS)) - goto error; - } - - if (~type & MODBUS_TYP_WRITE) - /* Except from Read/Write Multiple Registers function (code 23) */ - /* The length of all Read Data function requests is 6 bytes */ - /* Modbus Application Protocol Specification V1.1b3 from 6.1 to 6.4 */ - ModbusCheckHeaderLength(modbus, tx->length, 6); - - goto end; - -error: - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_VALUE); -end: - SCReturn; -} - -/** \internal - * \brief Parse Read data Response and verify protocol compliance - * - * \param tx Pointer to Modbus Transaction structure - * \param modbus Pointer to Modbus state structure - * \param input Pointer the received input data - * \param input_len Length of the received input data - * \param offset Offset of the received input data pointer - */ -static void ModbusParseReadResponse(ModbusTransaction *tx, - ModbusState *modbus, - uint8_t *input, - uint32_t input_len, - uint16_t *offset) -{ - SCEnter(); - uint8_t count; - - /* Count (1 bytes) */ - if (ModbusExtractUint8(modbus, &count, input, input_len, offset)) - goto end; - - /* Check Count range and value according to the request */ - if ((tx->type) & MODBUS_TYP_BIT_ACCESS_MASK) { - if ( (count < MODBUS_MIN_COUNT) || - (count > MODBUS_MAX_COUNT) || - (count != CEIL(tx->read.quantity))) - goto error; - } else { - if ( (count == MODBUS_MIN_COUNT) || - (count > MODBUS_MAX_COUNT) || - (count != (2 * (tx->read.quantity)))) - goto error; - } - - /* Except from Read/Write Multiple Registers function (code 23) */ - /* The length of all Read Data function responses is (3 bytes + count) */ - /* Modbus Application Protocol Specification V1.1b3 from 6.1 to 6.4 */ - ModbusCheckHeaderLength(modbus, tx->length, 3 + count); - goto end; - -error: - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_VALUE_MISMATCH); -end: - SCReturn; -} - -/** \internal - * \brief Parse Write data Request, complete Transaction structure - * and verify protocol compliance. - * - * \param tx Pointer to Modbus Transaction structure - * \param modbus Pointer to Modbus state structure - * \param input Pointer the received input data - * \param input_len Length of the received input data - * \param offset Offset of the received input data pointer - * - * \retval On success returns 0 or on failure returns -1. - */ -static int ModbusParseWriteRequest(ModbusTransaction *tx, - ModbusState *modbus, - uint8_t *input, - uint32_t input_len, - uint16_t *offset) -{ - SCEnter(); - uint16_t quantity = 1, word; - uint8_t byte, count = 1, type = tx->type; - - int i = 0; - - /* Starting/Output/Register Address (2 bytes) */ - if (ModbusExtractUint16(modbus, &(tx->write.address), input, input_len, offset)) - goto end; - - if (type & MODBUS_TYP_SINGLE) { - /* The length of Write Single Coil (code 5) and */ - /* Write Single Register (code 6) requests is 6 bytes */ - /* Modbus Application Protocol Specification V1.1b3 6.5 and 6.6 */ - if (ModbusCheckHeaderLength(modbus, tx->length, 6)) - goto end; - } else if (type & MODBUS_TYP_MULTIPLE) { - /* Quantity (2 bytes) */ - if (ModbusExtractUint16(modbus, &quantity, input, input_len, offset)) - goto end; - tx->write.quantity = quantity; - - /* Count (1 bytes) */ - if (ModbusExtractUint8(modbus, &count, input, input_len, offset)) - goto end; - tx->write.count = count; - - if (type & MODBUS_TYP_BIT_ACCESS_MASK) { - /* Check Quantity range and conversion in byte (count) */ - if ((quantity == MODBUS_MIN_QUANTITY) || - (quantity > MODBUS_MAX_QUANTITY_IN_BIT_ACCESS) || - (quantity != CEIL(count))) - goto error; - - /* The length of Write Multiple Coils (code 15) request is (7 + count) */ - /* Modbus Application Protocol Specification V1.1b3 6.11 */ - if (ModbusCheckHeaderLength(modbus, tx->length, 7 + count)) - goto end; - } else { - /* Check Quantity range and conversion in byte (count) */ - if ((quantity == MODBUS_MIN_QUANTITY) || - (quantity > MODBUS_MAX_QUANTITY_IN_WORD_ACCESS) || - (count != (2 * quantity))) - goto error; - - if (type & MODBUS_TYP_READ) { - /* The length of Read/Write Multiple Registers function (code 23) */ - /* request is (11 bytes + count) */ - /* Modbus Application Protocol Specification V1.1b3 6.17 */ - if (ModbusCheckHeaderLength(modbus, tx->length, 11 + count)) - goto end; - } else { - /* The length of Write Multiple Coils (code 15) and */ - /* Write Multiple Registers (code 16) functions requests is (7 bytes + count) */ - /* Modbus Application Protocol Specification V1.1b3 from 6.11 and 6.12 */ - if (ModbusCheckHeaderLength(modbus, tx->length, 7 + count)) - goto end; - } - } - } else { - /* Mask Write Register function (And_Mask and Or_Mask) */ - quantity = 2; - - /* The length of Mask Write Register (code 22) function request is 8 */ - /* Modbus Application Protocol Specification V1.1b3 6.16 */ - if (ModbusCheckHeaderLength(modbus, tx->length, 8)) - goto end; - } - - if (type & MODBUS_TYP_COILS) { - /* Output value (data block) unit is count */ - tx->data = (uint16_t *) SCCalloc(1, count * sizeof(uint16_t)); - if (unlikely(tx->data == NULL)) - SCReturnInt(-1); - - if (type & MODBUS_TYP_SINGLE) { - /* Outputs value (2 bytes) */ - if (ModbusExtractUint16(modbus, &word, input, input_len, offset)) - goto end; - tx->data[i] = word; - - if ((word != 0x00) && (word != 0xFF00)) - goto error; - } else { - for (i = 0; i < count; i++) { - /* Outputs value (1 byte) */ - if (ModbusExtractUint8(modbus, &byte, input, input_len, offset)) - goto end; - tx->data[i] = (uint16_t) byte; - } - } - } else { - /* Registers value (data block) unit is quantity */ - tx->data = (uint16_t *) SCCalloc(1, quantity * sizeof(uint16_t)); - if (unlikely(tx->data == NULL)) - SCReturnInt(-1); - - for (i = 0; i < quantity; i++) { - /* Outputs/Registers value (2 bytes) */ - if (ModbusExtractUint16(modbus, &word, input, input_len, offset)) - goto end; - tx->data[i] = word; - } - } - goto end; - -error: - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_VALUE); -end: - SCReturnInt(0); -} - -/** \internal - * \brief Parse Write data Response and verify protocol compliance - * - * \param tx Pointer to Modbus Transaction structure - * \param modbus Pointer to Modbus state structure - * \param input Pointer the received input data - * \param input_len Length of the received input data - * \param offset Offset of the received input data pointer - */ -static void ModbusParseWriteResponse(ModbusTransaction *tx, - ModbusState *modbus, - uint8_t *input, - uint32_t input_len, - uint16_t *offset) -{ - SCEnter(); - uint16_t address, quantity, word; - uint8_t type = tx->type; - - /* Starting Address (2 bytes) */ - if (ModbusExtractUint16(modbus, &address, input, input_len, offset)) - goto end; - - if (address != tx->write.address) - goto error; - - if (type & MODBUS_TYP_SINGLE) { - /* Outputs/Registers value (2 bytes) */ - if (ModbusExtractUint16(modbus, &word, input, input_len, offset)) - goto end; - - /* Check with Outputs/Registers from request */ - if (word != tx->data[0]) - goto error; - } else if (type & MODBUS_TYP_MULTIPLE) { - /* Quantity (2 bytes) */ - if (ModbusExtractUint16(modbus, &quantity, input, input_len, offset)) - goto end; - - /* Check Quantity range */ - if (type & MODBUS_TYP_BIT_ACCESS_MASK) { - if ((quantity == MODBUS_MIN_QUANTITY) || - (quantity > MODBUS_MAX_QUANTITY_IN_WORD_ACCESS)) - goto error; - } else { - if ((quantity == MODBUS_MIN_QUANTITY) || - (quantity > MODBUS_MAX_QUANTITY_IN_BIT_ACCESS)) - goto error; - } - - /* Check Quantity value according to the request */ - if (quantity != tx->write.quantity) - goto error; - } else { - /* And_Mask value (2 bytes) */ - if (ModbusExtractUint16(modbus, &word, input, input_len, offset)) - goto end; - - /* Check And_Mask value according to the request */ - if (word != tx->data[0]) - goto error; - - /* And_Or_Mask value (2 bytes) */ - if (ModbusExtractUint16(modbus, &word, input, input_len, offset)) - - /* Check Or_Mask value according to the request */ - if (word != tx->data[1]) - goto error; - - /* The length of Mask Write Register (code 22) function response is 8 */ - /* Modbus Application Protocol Specification V1.1b3 6.16 */ - ModbusCheckHeaderLength(modbus, tx->length, 8); - goto end; - } - - /* Except from Mask Write Register (code 22) */ - /* The length of all Write Data function responses is 6 */ - /* Modbus Application Protocol Specification V1.1b3 6.5, 6.6, 6.11, 6.12 and 6.17 */ - ModbusCheckHeaderLength(modbus, tx->length, 6); - goto end; - -error: - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_VALUE_MISMATCH); -end: - SCReturn; -} - -/** \internal - * \brief Parse Diagnostic Request, complete Transaction - * structure (Category) and verify protocol compliance. - * - * \param tx Pointer to Modbus Transaction structure - * \param modbus Pointer to Modbus state structure - * \param input Pointer the received input data - * \param input_len Length of the received input data - * \param offset Offset of the received input data pointer - * - * \retval Reserved category function returns 1 otherwise returns 0. - */ -static int ModbusParseDiagnosticRequest(ModbusTransaction *tx, - ModbusState *modbus, - uint8_t *input, - uint32_t input_len, - uint16_t *offset) -{ - SCEnter(); - uint16_t data; - - /* Sub-function (2 bytes) */ - if (ModbusExtractUint16(modbus, &(tx->subFunction), input, input_len, offset)) - goto end; - - /* Data (2 bytes) */ - if (ModbusExtractUint16(modbus, &data, input, input_len, offset)) - goto end; - - if (tx->subFunction != MODBUS_SUBFUNC_QUERY_DATA) { - switch (tx->subFunction) { - case MODBUS_SUBFUNC_RESTART_COM: - if ((data != 0x00) && (data != 0xFF00)) - goto error; - break; - - case MODBUS_SUBFUNC_CHANGE_DELIMITER: - if ((data & 0xFF) != 0x00) - goto error; - break; - - case MODBUS_SUBFUNC_LISTEN_MODE: - /* No answer is expected then mark tx as completed. */ - tx->replied = 1; - /* Fallthrough */ - case MODBUS_SUBFUNC_DIAG_REGS: - case MODBUS_SUBFUNC_CLEAR_REGS: - case MODBUS_SUBFUNC_BUS_MSG_COUNT: - case MODBUS_SUBFUNC_COM_ERR_COUNT: - case MODBUS_SUBFUNC_EXCEPT_ERR_COUNT: - case MODBUS_SUBFUNC_SERVER_MSG_COUNT: - case MODBUS_SUBFUNC_SERVER_NO_RSP_COUNT: - case MODBUS_SUBFUNC_SERVER_NAK_COUNT: - case MODBUS_SUBFUNC_SERVER_BUSY_COUNT: - case MODBUS_SUBFUNC_SERVER_CHAR_COUNT: - case MODBUS_SUBFUNC_CLEAR_COUNT: - if (data != 0x00) - goto error; - break; - - default: - /* Set function code category */ - tx->category = MODBUS_CAT_RESERVED; - SCReturnInt(1); - } - - /* The length of all Diagnostic Requests is 6 */ - /* Modbus Application Protocol Specification V1.1b3 6.8 */ - ModbusCheckHeaderLength(modbus, tx->length, 6); - } - - goto end; - -error: - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_VALUE); -end: - SCReturnInt(0); -} - -/* Modbus Function Code Categories structure. */ -typedef struct ModbusFunctionCodeRange_ { - uint8_t function; - uint8_t category; -} ModbusFunctionCodeRange; - -/* Modbus Function Code Categories table. */ -static ModbusFunctionCodeRange modbusFunctionCodeRanges[] = { - { 0, MODBUS_CAT_PUBLIC_UNASSIGNED}, - { 9, MODBUS_CAT_RESERVED }, - { 15, MODBUS_CAT_PUBLIC_UNASSIGNED}, - { 41, MODBUS_CAT_RESERVED }, - { 43, MODBUS_CAT_PUBLIC_UNASSIGNED}, - { 65, MODBUS_CAT_USER_DEFINED }, - { 73, MODBUS_CAT_PUBLIC_UNASSIGNED}, - { 90, MODBUS_CAT_RESERVED }, - { 92, MODBUS_CAT_PUBLIC_UNASSIGNED}, - { 100, MODBUS_CAT_USER_DEFINED }, - { 111, MODBUS_CAT_PUBLIC_UNASSIGNED}, - { 125, MODBUS_CAT_RESERVED }, - { 128, MODBUS_CAT_NONE } -}; - -/** \internal - * \brief Parse the Modbus Protocol Data Unit (PDU) Request - * - * \param tx Pointer to Modbus Transaction structure - * \param ModbusPdu Pointer the Modbus PDU state in which the value to be stored - * \param input Pointer the received input data - * \param input_len Length of the received input data - */ -static void ModbusParseRequestPDU(ModbusTransaction *tx, - ModbusState *modbus, - uint8_t *input, - uint32_t input_len) -{ - SCEnter(); - uint16_t offset = (uint16_t) sizeof(ModbusHeader); - uint8_t count; - - int i = 0; - - /* Standard function codes used on MODBUS application layer protocol (1 byte) */ - if (ModbusExtractUint8(modbus, &(tx->function), input, input_len, &offset)) - goto end; - - /* Set default function code category */ - tx->category = MODBUS_CAT_NONE; - - /* Set default function primary table */ - tx->type = MODBUS_TYP_NONE; - - switch (tx->function) { - case MODBUS_FUNC_NONE: - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_FUNCTION_CODE); - break; - - case MODBUS_FUNC_READCOILS: - /* Set function type */ - tx->type = (MODBUS_TYP_COILS | MODBUS_TYP_READ); - break; - - case MODBUS_FUNC_READDISCINPUTS: - /* Set function type */ - tx->type = (MODBUS_TYP_DISCRETES | MODBUS_TYP_READ); - break; - - case MODBUS_FUNC_READHOLDREGS: - /* Set function type */ - tx->type = (MODBUS_TYP_HOLDING | MODBUS_TYP_READ); - break; - - case MODBUS_FUNC_READINPUTREGS: - /* Set function type */ - tx->type = (MODBUS_TYP_INPUT | MODBUS_TYP_READ); - break; - - case MODBUS_FUNC_WRITESINGLECOIL: - /* Set function type */ - tx->type = (MODBUS_TYP_COILS | MODBUS_TYP_WRITE_SINGLE); - break; - - case MODBUS_FUNC_WRITESINGLEREG: - /* Set function type */ - tx->type = (MODBUS_TYP_HOLDING | MODBUS_TYP_WRITE_SINGLE); - break; - - case MODBUS_FUNC_WRITEMULTCOILS: - /* Set function type */ - tx->type = (MODBUS_TYP_COILS | MODBUS_TYP_WRITE_MULTIPLE); - break; - - case MODBUS_FUNC_WRITEMULTREGS: - /* Set function type */ - tx->type = (MODBUS_TYP_HOLDING | MODBUS_TYP_WRITE_MULTIPLE); - break; - - case MODBUS_FUNC_MASKWRITEREG: - /* Set function type */ - tx->type = (MODBUS_TYP_HOLDING | MODBUS_TYP_WRITE); - break; - - case MODBUS_FUNC_READWRITEMULTREGS: - /* Set function type */ - tx->type = (MODBUS_TYP_HOLDING | MODBUS_TYP_READ_WRITE_MULTIPLE); - break; - - case MODBUS_FUNC_READFILERECORD: - case MODBUS_FUNC_WRITEFILERECORD: - /* Count/length (1 bytes) */ - if (ModbusExtractUint8(modbus, &count, input, input_len, &offset)) - goto end; - - /* Modbus Application Protocol Specification V1.1b3 6.14 and 6.15 */ - ModbusCheckHeaderLength(modbus, tx->length, 2 + count); - break; - - case MODBUS_FUNC_DIAGNOSTIC: - if(ModbusParseDiagnosticRequest(tx, modbus, input, input_len, &offset)) - goto end; - break; - - case MODBUS_FUNC_READEXCSTATUS: - case MODBUS_FUNC_GETCOMEVTCOUNTER: - case MODBUS_FUNC_GETCOMEVTLOG: - case MODBUS_FUNC_REPORTSERVERID: - /* Modbus Application Protocol Specification V1.1b3 6.7, 6.9, 6.10 and 6.13 */ - ModbusCheckHeaderLength(modbus, tx->length, 2); - break; - - case MODBUS_FUNC_READFIFOQUEUE: - /* Modbus Application Protocol Specification V1.1b3 6.18 */ - ModbusCheckHeaderLength(modbus, tx->length, 4); - break; - - case MODBUS_FUNC_ENCAPINTTRANS: - /* MEI type (1 byte) */ - if (ModbusExtractUint8(modbus, &(tx->mei), input, input_len, &offset)) - goto end; - - if (tx->mei == MODBUS_MEI_ENCAPINTTRANS_READ) { - /* Modbus Application Protocol Specification V1.1b3 6.21 */ - ModbusCheckHeaderLength(modbus, tx->length, 5); - } else if (tx->mei != MODBUS_MEI_ENCAPINTTRANS_CAN) { - /* Set function code category */ - tx->category = MODBUS_CAT_RESERVED; - goto end; - } - break; - - default: - /* Check if request is error. */ - if (tx->function & MODBUS_FUNC_ERRORMASK) { - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_INVALID_FUNCTION_CODE); - goto end; - } - - /* Get and store function code category */ - for (i = 0; modbusFunctionCodeRanges[i].category != MODBUS_CAT_NONE; i++) { - if (tx->function <= modbusFunctionCodeRanges[i].function) - break; - tx->category = modbusFunctionCodeRanges[i].category; - } - goto end; - } - - /* Set function code category */ - tx->category = MODBUS_CAT_PUBLIC_ASSIGNED; - - if (tx->type & MODBUS_TYP_READ) - ModbusParseReadRequest(tx, modbus, input, input_len, &offset); - - if (tx->type & MODBUS_TYP_WRITE) - ModbusParseWriteRequest(tx, modbus, input, input_len, &offset); - -end: - SCReturn; -} - -/** \internal - * \brief Parse the Modbus Protocol Data Unit (PDU) Response - * - * \param tx Pointer to Modbus Transaction structure - * \param modbus Pointer the Modbus PDU state in which the value to be stored - * \param input Pointer the received input data - * \param input_len Length of the received input data - * \param offset Offset of the received input data pointer - */ -static void ModbusParseResponsePDU(ModbusTransaction *tx, - ModbusState *modbus, - uint8_t *input, - uint32_t input_len) -{ - SCEnter(); - uint16_t offset = (uint16_t) sizeof(ModbusHeader); - uint8_t count, error = FALSE, function, mei; - - /* Standard function codes used on MODBUS application layer protocol (1 byte) */ - if (ModbusExtractUint8(modbus, &function, input, input_len, &offset)) - goto end; - - /* Check if response is error */ - if(function & MODBUS_FUNC_ERRORMASK) { - function &= MODBUS_FUNC_MASK; - error = TRUE; - } - - if (tx->category == MODBUS_CAT_PUBLIC_ASSIGNED) { - /* Check if response is error. */ - if (error) { - ModbusExceptionResponse(tx, modbus, input, input_len, &offset); - } else { - switch(function) { - case MODBUS_FUNC_READEXCSTATUS: - /* Modbus Application Protocol Specification V1.1b3 6.7 */ - ModbusCheckHeaderLength(modbus, tx->length, 3); - goto end; - - case MODBUS_FUNC_GETCOMEVTCOUNTER: - /* Modbus Application Protocol Specification V1.1b3 6.9 */ - ModbusCheckHeaderLength(modbus, tx->length, 6); - goto end; - - case MODBUS_FUNC_READFILERECORD: - case MODBUS_FUNC_WRITEFILERECORD: - /* Count/length (1 bytes) */ - if (ModbusExtractUint8(modbus, &count, input, input_len, &offset)) - goto end; - - /* Modbus Application Protocol Specification V1.1b3 6.14 and 6.15 */ - ModbusCheckHeaderLength(modbus, tx->length, 2 + count); - goto end; - - case MODBUS_FUNC_ENCAPINTTRANS: - /* MEI type (1 byte) */ - if (ModbusExtractUint8(modbus, &mei, input, input_len, &offset)) - goto end; - - if (mei != tx->mei) - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_VALUE_MISMATCH); - goto end; - } - - if (tx->type & MODBUS_TYP_READ) - ModbusParseReadResponse(tx, modbus, input, input_len, &offset); - /* Read/Write response contents none write response part */ - else if (tx->type & MODBUS_TYP_WRITE) - ModbusParseWriteResponse(tx, modbus, input, input_len, &offset); - } - } - -end: - SCReturn; -} - -/** \internal - * \brief Parse the Modbus Application Protocol (MBAP) header - * - * \param header Pointer the Modbus header state in which the value to be stored - * \param input Pointer the received input data - */ -static int ModbusParseHeader(ModbusState *modbus, - ModbusHeader *header, - uint8_t *input, - uint32_t input_len) -{ - SCEnter(); - uint16_t offset = 0; - - /* Transaction Identifier (2 bytes) */ - if (ModbusExtractUint16(modbus, &(header->transactionId), input, input_len, &offset) || - /* Protocol Identifier (2 bytes) */ - ModbusExtractUint16(modbus, &(header->protocolId), input, input_len, &offset) || - /* Length (2 bytes) */ - ModbusExtractUint16(modbus, &(header->length), input, input_len, &offset) || - /* Unit Identifier (1 byte) */ - ModbusExtractUint8(modbus, &(header->unitId), input, input_len, &offset)) - SCReturnInt(-1); - - SCReturnInt(0); -} - -/** \internal - * - * \brief This function is called to retrieve a Modbus Request - * - * \param state Modbus state structure for the parser - * \param input Input line of the command - * \param input_len Length of the request - * - * \retval 1 when the command is parsed, 0 otherwise - */ -static int ModbusParseRequest(Flow *f, - void *state, - AppLayerParserState *pstate, - uint8_t *input, - uint32_t input_len, - void *local_data) -{ - SCEnter(); - ModbusState *modbus = (ModbusState *) state; - ModbusTransaction *tx; - ModbusHeader header; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - while (input_len > 0) { - uint32_t adu_len = input_len; - uint8_t *adu = input; - - /* Extract MODBUS Header */ - if (ModbusParseHeader(modbus, &header, adu, adu_len)) - SCReturnInt(0); - - /* Update ADU length with length in Modbus header. */ - adu_len = (uint32_t) sizeof(ModbusHeader) + (uint32_t) header.length - 1; - if (adu_len > input_len) - SCReturnInt(0); - - /* Allocate a Transaction Context and add it to Transaction list */ - tx = ModbusTxAlloc(modbus); - if (tx == NULL) - SCReturnInt(0); - - /* Check MODBUS Header */ - ModbusCheckHeader(modbus, &header); - - /* Store Transaction ID & PDU length */ - tx->transactionId = header.transactionId; - tx->length = header.length; - - /* Extract MODBUS PDU and fill Transaction Context */ - ModbusParseRequestPDU(tx, modbus, adu, adu_len); - - /* Update input line and remaining input length of the command */ - input += adu_len; - input_len -= adu_len; - } - - SCReturnInt(1); -} - -/** \internal - * \brief This function is called to retrieve a Modbus response - * - * \param state Pointer to Modbus state structure for the parser - * \param input Input line of the command - * \param input_len Length of the request - * - * \retval 1 when the command is parsed, 0 otherwise - */ -static int ModbusParseResponse(Flow *f, - void *state, - AppLayerParserState *pstate, - uint8_t *input, - uint32_t input_len, - void *local_data) -{ - SCEnter(); - ModbusHeader header; - ModbusState *modbus = (ModbusState *) state; - ModbusTransaction *tx; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - while (input_len > 0) { - uint32_t adu_len = input_len; - uint8_t *adu = input; - - /* Extract MODBUS Header */ - if (ModbusParseHeader(modbus, &header, adu, adu_len)) - SCReturnInt(0); - - /* Update ADU length with length in Modbus header. */ - adu_len = (uint32_t) sizeof(ModbusHeader) + (uint32_t) header.length - 1; - if (adu_len > input_len) - SCReturnInt(0); - - /* Find the transaction context thanks to transaction ID (and function code) */ - tx = ModbusTxFindByTransaction(modbus, header.transactionId); - if (tx == NULL) { - /* Allocate a Transaction Context if not previous request */ - /* and add it to Transaction list */ - tx = ModbusTxAlloc(modbus); - if (tx == NULL) - SCReturnInt(0); - - SCLogDebug("MODBUS_DECODER_EVENT_UNSOLICITED_RESPONSE"); - ModbusSetEvent(modbus, MODBUS_DECODER_EVENT_UNSOLICITED_RESPONSE); - } else { - /* Store PDU length */ - tx->length = header.length; - - /* Extract MODBUS PDU and fill Transaction Context */ - ModbusParseResponsePDU(tx, modbus, adu, adu_len); - } - - /* Check and store MODBUS Header */ - ModbusCheckHeader(modbus, &header); - - /* Mark as completed */ - tx->replied = 1; - - /* Update input line and remaining input length of the command */ - input += adu_len; - input_len -= adu_len; - } - - SCReturnInt(1); -} - -/** \internal - * \brief Function to allocate the Modbus state memory - */ -static void *ModbusStateAlloc(void) -{ - ModbusState *modbus; - - modbus = (ModbusState *) SCCalloc(1, sizeof(ModbusState)); - if (unlikely(modbus == NULL)) - return NULL; - - TAILQ_INIT(&modbus->tx_list); - - return (void *) modbus; -} - -/** \internal - * \brief Function to free the Modbus state memory - */ -static void ModbusStateFree(void *state) -{ - SCEnter(); - ModbusState *modbus = (ModbusState *) state; - ModbusTransaction *tx = NULL, *ttx; - - if (state) { - TAILQ_FOREACH_SAFE(tx, &modbus->tx_list, next, ttx) { - ModbusTxFree(tx); - } - - SCFree(state); - } - SCReturn; -} - -static uint16_t ModbusProbingParser(uint8_t *input, - uint32_t input_len, - uint32_t *offset) -{ - ModbusHeader *header = (ModbusHeader *) input; - - /* Modbus header is 7 bytes long */ - if (input_len < sizeof(ModbusHeader)) - return ALPROTO_UNKNOWN; - - /* MODBUS protocol is identified by the value 0. */ - if (header->protocolId != 0) - return ALPROTO_FAILED; - - return ALPROTO_MODBUS; -} - -DetectEngineState *ModbusGetTxDetectState(void *vtx) -{ - ModbusTransaction *tx = (ModbusTransaction *)vtx; - return tx->de_state; -} - -int ModbusSetTxDetectState(void *state, void *vtx, DetectEngineState *s) -{ - ModbusTransaction *tx = (ModbusTransaction *)vtx; - tx->de_state = s; - return 0; -} - -/** - * \brief Function to register the Modbus protocol parsers and other functions - */ -void RegisterModbusParsers(void) -{ - SCEnter(); - char *proto_name = "modbus"; - - /* Modbus application protocol V1.1b3 */ - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_MODBUS, proto_name); - - if (RunmodeIsUnittests()) { - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "502", - ALPROTO_MODBUS, - 0, sizeof(ModbusHeader), - STREAM_TOSERVER, - ModbusProbingParser); - } else { - /* if we have no config, we enable the default port 502 */ - if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP, - proto_name, ALPROTO_MODBUS, - 0, sizeof(ModbusHeader), - ModbusProbingParser)) { - SCLogWarning(SC_ERR_MODBUS_CONFIG, "no Modbus TCP config found, " - "enabling Modbus detection on " - "port 502."); - - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "502", - ALPROTO_MODBUS, - 0, sizeof(ModbusHeader), - STREAM_TOSERVER, - ModbusProbingParser); - } - } - - ConfNode *p = ConfGetNode("app-layer.protocols.modbus.request-flood"); - if (p != NULL) { - uint32_t value; - if (ParseSizeStringU32(p->val, &value) < 0) { - SCLogError(SC_ERR_MODBUS_CONFIG, "invalid value for request-flood %s", p->val); - } else { - request_flood = value; - } - } - SCLogInfo("Modbus request flood protection level: %u", request_flood); - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", proto_name); - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_MODBUS, STREAM_TOSERVER, ModbusParseRequest); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_MODBUS, STREAM_TOCLIENT, ModbusParseResponse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_MODBUS, ModbusStateAlloc, ModbusStateFree); - - AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_MODBUS, ModbusGetEvents); - AppLayerParserRegisterHasEventsFunc(IPPROTO_TCP, ALPROTO_MODBUS, ModbusHasEvents); - AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_MODBUS, NULL, - ModbusGetTxDetectState, ModbusSetTxDetectState); - - AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_MODBUS, ModbusGetTx); - AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_MODBUS, ModbusGetTxCnt); - AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_MODBUS, ModbusStateTxFree); - - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_MODBUS, ModbusGetAlstateProgress); - AppLayerParserRegisterGetStateProgressCompletionStatus(IPPROTO_TCP, ALPROTO_MODBUS, - ModbusGetAlstateProgressCompletionStatus); - - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_MODBUS, ModbusStateGetEventInfo); - - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_MODBUS, STREAM_TOSERVER); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" "still on.", proto_name); - } -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_MODBUS, ModbusParserRegisterTests); -#endif - - SCReturn; -} - -/* UNITTESTS */ -#ifdef UNITTESTS -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" - -#include "flow-util.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "stream-tcp.h" -#include "stream-tcp-private.h" - -/* Modbus Application Protocol Specification V1.1b3 6.1: Read Coils */ -/* Example of a request to read discrete outputs 20-38 */ -static uint8_t readCoilsReq[] = {/* Transaction ID */ 0x00, 0x00, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x06, - /* Unit ID */ 0x00, - /* Function code */ 0x01, - /* Starting Address */ 0x78, 0x90, - /* Quantity of coils */ 0x00, 0x13 }; - -static uint8_t readCoilsRsp[] = {/* Transaction ID */ 0x00, 0x00, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x06, - /* Unit ID */ 0x00, - /* Function code */ 0x01, - /* Byte count */ 0x03, - /* Coil Status */ 0xCD, 0x6B, 0x05 }; - -static uint8_t readCoilsErrorRsp[] = {/* Transaction ID */ 0x00, 0x00, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x03, - /* Unit ID */ 0x00, - /* Function code */ 0x81, - /* Exception code */ 0x05}; - -/* Modbus Application Protocol Specification V1.1b3 6.12: Write Multiple registers */ -/* Example of a request to write two registers starting at 2 to 00 0A and 01 02 hex */ -static uint8_t writeMultipleRegistersReq[] = {/* Transaction ID */ 0x00, 0x0A, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x0B, - /* Unit ID */ 0x00, - /* Function code */ 0x10, - /* Starting Address */ 0x00, 0x01, - /* Quantity of Registers */ 0x00, 0x02, - /* Byte count */ 0x04, - /* Registers Value */ 0x00, 0x0A, - 0x01, 0x02}; - -static uint8_t writeMultipleRegistersRsp[] = {/* Transaction ID */ 0x00, 0x0A, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x06, - /* Unit ID */ 0x00, - /* Function code */ 0x10, - /* Starting Address */ 0x00, 0x01, - /* Quantity of Registers */ 0x00, 0x02}; - -/* Modbus Application Protocol Specification V1.1b3 6.17: Read/Write Multiple registers */ -/* Example of a request to read six registers starting at register 4, */ -/* and to write three registers starting at register 15 */ -static uint8_t readWriteMultipleRegistersReq[] = {/* Transaction ID */ 0x12, 0x34, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x11, - /* Unit ID */ 0x00, - /* Function code */ 0x17, - /* Read Starting Address */ 0x00, 0x03, - /* Quantity to Read */ 0x00, 0x06, - /* Write Starting Address */ 0x00, 0x0E, - /* Quantity to Write */ 0x00, 0x03, - /* Write Byte count */ 0x06, - /* Write Registers Value */ 0x12, 0x34, - 0x56, 0x78, - 0x9A, 0xBC}; - -/* Mismatch value in Byte count 0x0B instead of 0x0C */ -static uint8_t readWriteMultipleRegistersRsp[] = {/* Transaction ID */ 0x12, 0x34, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x0E, - /* Unit ID */ 0x00, - /* Function code */ 0x17, - /* Byte count */ 0x0B, - /* Read Registers Value */ 0x00, 0xFE, - 0x0A, 0xCD, - 0x00, 0x01, - 0x00, 0x03, - 0x00, 0x0D, - 0x00}; - -/* Modbus Application Protocol Specification V1.1b3 6.8.1: 04 Force Listen Only Mode */ -/* Example of a request to to remote device to its Listen Only MOde for Modbus Communications. */ -static uint8_t forceListenOnlyMode[] = {/* Transaction ID */ 0x0A, 0x00, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x06, - /* Unit ID */ 0x00, - /* Function code */ 0x08, - /* Sub-function code */ 0x00, 0x04, - /* Data */ 0x00, 0x00}; - -static uint8_t invalidProtocolIdReq[] = {/* Transaction ID */ 0x00, 0x00, - /* Protocol ID */ 0x00, 0x01, - /* Length */ 0x00, 0x06, - /* Unit ID */ 0x00, - /* Function code */ 0x01, - /* Starting Address */ 0x78, 0x90, - /* Quantity of coils */ 0x00, 0x13 }; - -static uint8_t invalidLengthWriteMultipleRegistersReq[] = { - /* Transaction ID */ 0x00, 0x0A, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x09, - /* Unit ID */ 0x00, - /* Function code */ 0x10, - /* Starting Address */ 0x00, 0x01, - /* Quantity of Registers */ 0x00, 0x02, - /* Byte count */ 0x04, - /* Registers Value */ 0x00, 0x0A, - 0x01, 0x02}; - -static uint8_t exceededLengthWriteMultipleRegistersReq[] = { - /* Transaction ID */ 0x00, 0x0A, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0xff, 0xfa, - /* Unit ID */ 0x00, - /* Function code */ 0x10, - /* Starting Address */ 0x00, 0x01, - /* Quantity of Registers */ 0x7f, 0xf9, - /* Byte count */ 0xff}; - -static uint8_t invalidLengthPDUWriteMultipleRegistersReq[] = { - /* Transaction ID */ 0x00, 0x0A, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x02, - /* Unit ID */ 0x00, - /* Function code */ 0x10}; - -/** \test Send Modbus Read Coils request/response. */ -static int ModbusParserTest01(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - Flow f; - TcpSession ssn; - - int result = 0; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - readCoilsReq, sizeof(readCoilsReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - ModbusTransaction *tx = ModbusGetTx(modbus_state, 0); - - if ((tx->function != 1) || (tx->read.address != 0x7890) || (tx->read.quantity != 19)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 1, tx->function); - printf("expected address %" PRIu8 ", got %" PRIu8 ": ", 0x7890, tx->read.address); - printf("expected quantity %" PRIu8 ", got %" PRIu8 ": ", 19, tx->read.quantity); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOCLIENT, - readCoilsRsp, sizeof(readCoilsRsp)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (modbus_state->transaction_max !=1) { - printf("expected transaction_max %" PRIu8 ", got %" PRIu64 ": ", 1, modbus_state->transaction_max); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test Send Modbus Write Multiple registers request/response. */ -static int ModbusParserTest02(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - Flow f; - TcpSession ssn; - - int result = 0; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - writeMultipleRegistersReq, sizeof(writeMultipleRegistersReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - ModbusTransaction *tx = ModbusGetTx(modbus_state, 0); - - if ((tx->function != 16) || (tx->write.address != 0x01) || (tx->write.quantity != 2) || - (tx->write.count != 4) || (tx->data[0] != 0x000A) || (tx->data[1] != 0x0102)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 16, tx->function); - printf("expected write address %" PRIu8 ", got %" PRIu8 ": ", 0x01, tx->write.address); - printf("expected write quantity %" PRIu8 ", got %" PRIu8 ": ", 2, tx->write.quantity); - printf("expected write count %" PRIu8 ", got %" PRIu8 ": ", 4, tx->write.count); - printf("expected data %" PRIu8 ", got %" PRIu8 ": ", 0x000A, tx->data[0]); - printf("expected data %" PRIu8 ", got %" PRIu8 ": ", 0x0102, tx->data[1]); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOCLIENT, - writeMultipleRegistersRsp, sizeof(writeMultipleRegistersRsp)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (modbus_state->transaction_max !=1) { - printf("expected transaction_max %" PRIu8 ", got %" PRIu64 ": ", 1, modbus_state->transaction_max); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test Send Modbus Read/Write Multiple registers request/response with mismatch value. */ -static int ModbusParserTest03(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Modbus Data mismatch\"; " - "app-layer-event: " - "modbus.value_mismatch; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - readWriteMultipleRegistersReq, sizeof(readWriteMultipleRegistersReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - ModbusTransaction *tx = ModbusGetTx(modbus_state, 0); - - if ((tx->function != 23) || (tx->read.address != 0x03) || (tx->read.quantity != 6) || - (tx->write.address != 0x0E) || (tx->write.quantity != 3) || (tx->write.count != 6) || - (tx->data[0] != 0x1234) || (tx->data[1] != 0x5678) || (tx->data[2] != 0x9ABC)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 23, tx->function); - printf("expected read address %" PRIu8 ", got %" PRIu8 ": ", 0x03, tx->read.address); - printf("expected read quantity %" PRIu8 ", got %" PRIu8 ": ", 6, tx->read.quantity); - printf("expected write address %" PRIu8 ", got %" PRIu8 ": ", 0x0E, tx->write.address); - printf("expected write quantity %" PRIu8 ", got %" PRIu8 ": ", 3, tx->write.quantity); - printf("expected write count %" PRIu8 ", got %" PRIu8 ": ", 6, tx->write.count); - printf("expected data %" PRIu8 ", got %" PRIu8 ": ", 0x1234, tx->data[0]); - printf("expected data %" PRIu8 ", got %" PRIu8 ": ", 0x5678, tx->data[1]); - printf("expected data %" PRIu8 ", got %" PRIu8 ": ", 0x9ABC, tx->data[2]); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOCLIENT, - readWriteMultipleRegistersRsp, sizeof(readWriteMultipleRegistersRsp)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (modbus_state->transaction_max !=1) { - printf("expected transaction_max %" PRIu8 ", got %" PRIu64 ": ", 1, modbus_state->transaction_max); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match. Should have matched: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Send Modbus Force Listen Only Mode request. */ -static int ModbusParserTest04(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - Flow f; - TcpSession ssn; - - int result = 0; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - forceListenOnlyMode, sizeof(forceListenOnlyMode)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - ModbusTransaction *tx = ModbusGetTx(modbus_state, 0); - - if ((tx->function != 8) || (tx->subFunction != 4)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 8, tx->function); - printf("expected sub-function %" PRIu8 ", got %" PRIu8 ": ", 0x04, tx->subFunction); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test Send Modbus invalid Protocol version in request. */ -static int ModbusParserTest05(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Modbus invalid Protocol version\"; " - "app-layer-event: " - "modbus.invalid_protocol_id; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - invalidProtocolIdReq, sizeof(invalidProtocolIdReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match. Should have matched: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Send Modbus unsolicited response. */ -static int ModbusParserTest06(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Modbus unsolicited response\"; " - "app-layer-event: " - "modbus.unsolicited_response; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOCLIENT, - readCoilsRsp, sizeof(readCoilsRsp)); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match. Should have matched: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Send Modbus invalid Length request. */ -static int ModbusParserTest07(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Modbus invalid Length\"; " - "app-layer-event: " - "modbus.invalid_length; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - invalidLengthWriteMultipleRegistersReq, - sizeof(invalidLengthWriteMultipleRegistersReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match. Should have matched: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Send Modbus Read Coils request and error response with Exception code invalid. */ -static int ModbusParserTest08(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Modbus Exception code invalid\"; " - "app-layer-event: " - "modbus.invalid_exception_code; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - readCoilsReq, sizeof(readCoilsReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - ModbusTransaction *tx = ModbusGetTx(modbus_state, 0); - - if ((tx->function != 1) || (tx->read.address != 0x7890) || (tx->read.quantity != 19)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 1, tx->function); - printf("expected address %" PRIu8 ", got %" PRIu8 ": ", 0x7890, tx->read.address); - printf("expected quantity %" PRIu8 ", got %" PRIu8 ": ", 19, tx->read.quantity); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOCLIENT, - readCoilsErrorRsp, sizeof(readCoilsErrorRsp)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (modbus_state->transaction_max !=1) { - printf("expected transaction_max %" PRIu8 ", got %" PRIu64 ": ", 1, modbus_state->transaction_max); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match. Should have matched: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Modbus fragmentation - 1 ADU over 2 TCP packets. */ -static int ModbusParserTest09(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - Flow f; - TcpSession ssn; - - uint32_t input_len = sizeof(readCoilsReq), part2_len = 3; - uint8_t *input = readCoilsReq; - - int result = 0; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - input, input_len - part2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - input, input_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - ModbusTransaction *tx = ModbusGetTx(modbus_state, 0); - - if ((tx->function != 1) || (tx->read.address != 0x7890) || (tx->read.quantity != 19)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 1, tx->function); - printf("expected address %" PRIu8 ", got %" PRIu8 ": ", 0x7890, tx->read.address); - printf("expected quantity %" PRIu8 ", got %" PRIu8 ": ", 19, tx->read.quantity); - goto end; - } - - input_len = sizeof(readCoilsRsp); - part2_len = 10; - input = readCoilsRsp; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOCLIENT, - input, input_len - part2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOCLIENT, - input, input_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (modbus_state->transaction_max !=1) { - printf("expected transaction_max %" PRIu8 ", got %" PRIu64 ": ", 1, modbus_state->transaction_max); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test Modbus fragmentation - 2 ADU in 1 TCP packet. */ -static int ModbusParserTest10(void) { - uint32_t input_len = sizeof(readCoilsReq) + sizeof(writeMultipleRegistersReq); - uint8_t *input, *ptr; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - Flow f; - TcpSession ssn; - - int result = 0; - - input = (uint8_t *) SCMalloc (input_len * sizeof(uint8_t)); - if (unlikely(input == NULL)) - goto end; - - memcpy(input, readCoilsReq, sizeof(readCoilsReq)); - memcpy(input + sizeof(readCoilsReq), writeMultipleRegistersReq, sizeof(writeMultipleRegistersReq)); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - input, input_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - if (modbus_state->transaction_max !=2) { - printf("expected transaction_max %" PRIu8 ", got %" PRIu64 ": ", 2, modbus_state->transaction_max); - goto end; - } - - ModbusTransaction *tx = ModbusGetTx(modbus_state, 1); - - if ((tx->function != 16) || (tx->write.address != 0x01) || (tx->write.quantity != 2) || - (tx->write.count != 4) || (tx->data[0] != 0x000A) || (tx->data[1] != 0x0102)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 16, tx->function); - printf("expected write address %" PRIu8 ", got %" PRIu8 ": ", 0x01, tx->write.address); - printf("expected write quantity %" PRIu8 ", got %" PRIu8 ": ", 2, tx->write.quantity); - printf("expected write count %" PRIu8 ", got %" PRIu8 ": ", 4, tx->write.count); - printf("expected data %" PRIu8 ", got %" PRIu8 ": ", 0x000A, tx->data[0]); - printf("expected data %" PRIu8 ", got %" PRIu8 ": ", 0x0102, tx->data[1]); - goto end; - } - - input_len = sizeof(readCoilsRsp) + sizeof(writeMultipleRegistersRsp); - - ptr = (uint8_t *) SCRealloc (input, input_len * sizeof(uint8_t)); - if (unlikely(ptr == NULL)) - goto end; - input = ptr; - - memcpy(input, readCoilsRsp, sizeof(readCoilsRsp)); - memcpy(input + sizeof(readCoilsRsp), writeMultipleRegistersRsp, sizeof(writeMultipleRegistersRsp)); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOCLIENT, - input, sizeof(input_len)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result = 1; -end: - if (input != NULL) - SCFree(input); - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** \test Send Modbus exceed Length request. */ -static int ModbusParserTest11(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Modbus invalid Length\"; " - "app-layer-event: " - "modbus.invalid_length; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - exceededLengthWriteMultipleRegistersReq, - sizeof(exceededLengthWriteMultipleRegistersReq) + 65523 /* header.length - 7 */ * sizeof(uint8_t)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match. Should have matched: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Send Modbus invalid PDU Length. */ -static int ModbusParserTest12(void) { - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Modbus invalid Length\"; " - "app-layer-event: " - "modbus.invalid_length; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - invalidLengthPDUWriteMultipleRegistersReq, - sizeof(invalidLengthPDUWriteMultipleRegistersReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match. Should have matched: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} -#endif /* UNITTESTS */ - -void ModbusParserRegisterTests(void) { -#ifdef UNITTESTS - UtRegisterTest("ModbusParserTest01 - Modbus Read Coils request", ModbusParserTest01, 1); - UtRegisterTest("ModbusParserTest02 - Modbus Write Multiple registers request", ModbusParserTest02, 1); - UtRegisterTest("ModbusParserTest03 - Modbus Read/Write Multiple registers request", ModbusParserTest03, 1); - UtRegisterTest("ModbusParserTest04 - Modbus Force Listen Only Mode request", ModbusParserTest04, 1); - UtRegisterTest("ModbusParserTest05 - Modbus invalid Protocol version", ModbusParserTest05, 1); - UtRegisterTest("ModbusParserTest06 - Modbus unsolicited response", ModbusParserTest06, 1); - UtRegisterTest("ModbusParserTest07 - Modbus invalid Length request", ModbusParserTest07, 1); - UtRegisterTest("ModbusParserTest08 - Modbus Exception code invalid", ModbusParserTest08, 1); - UtRegisterTest("ModbusParserTest09 - Modbus fragmentation - 1 ADU in 2 TCP packets", ModbusParserTest09, 1); - UtRegisterTest("ModbusParserTest10 - Modbus fragmentation - 2 ADU in 1 TCP packet", ModbusParserTest10, 1); - UtRegisterTest("ModbusParserTest11 - Modbus exceeded Length request", ModbusParserTest11, 1); - UtRegisterTest("ModbusParserTest12 - Modbus invalid PDU Length", ModbusParserTest12, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/app-layer-modbus.h b/framework/src/suricata/src/app-layer-modbus.h deleted file mode 100644 index 25ac519a..00000000 --- a/framework/src/suricata/src/app-layer-modbus.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2014 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author David DIALLO - */ - -#ifndef __APP_LAYER_MODBUS_H__ -#define __APP_LAYER_MODBUS_H__ - -#include "decode.h" -#include "detect-engine-state.h" -#include "queue.h" - -/* Modbus Application Data Unit (ADU) - * and Protocol Data Unit (PDU) messages */ -enum { - MODBUS_DECODER_EVENT_INVALID_PROTOCOL_ID, - MODBUS_DECODER_EVENT_UNSOLICITED_RESPONSE, - MODBUS_DECODER_EVENT_INVALID_LENGTH, - MODBUS_DECODER_EVENT_INVALID_UNIT_IDENTIFIER, - MODBUS_DECODER_EVENT_INVALID_FUNCTION_CODE, - MODBUS_DECODER_EVENT_INVALID_VALUE, - MODBUS_DECODER_EVENT_INVALID_EXCEPTION_CODE, - MODBUS_DECODER_EVENT_VALUE_MISMATCH, - MODBUS_DECODER_EVENT_FLOODED, -}; - -/* Modbus Function Code Categories. */ -#define MODBUS_CAT_NONE 0x0 -#define MODBUS_CAT_PUBLIC_ASSIGNED (1<<0) -#define MODBUS_CAT_PUBLIC_UNASSIGNED (1<<1) -#define MODBUS_CAT_USER_DEFINED (1<<2) -#define MODBUS_CAT_RESERVED (1<<3) -#define MODBUS_CAT_ALL 0xFF - -/* Modbus Read/Write function and Access Types. */ -#define MODBUS_TYP_NONE 0x0 -#define MODBUS_TYP_ACCESS_MASK 0x03 -#define MODBUS_TYP_READ (1<<0) -#define MODBUS_TYP_WRITE (1<<1) -#define MODBUS_TYP_ACCESS_FUNCTION_MASK 0x3C -#define MODBUS_TYP_BIT_ACCESS_MASK 0x0C -#define MODBUS_TYP_DISCRETES (1<<2) -#define MODBUS_TYP_COILS (1<<3) -#define MODBUS_TYP_WORD_ACCESS_MASK 0x30 -#define MODBUS_TYP_INPUT (1<<4) -#define MODBUS_TYP_HOLDING (1<<5) -#define MODBUS_TYP_SINGLE (1<<6) -#define MODBUS_TYP_MULTIPLE (1<<7) -#define MODBUS_TYP_WRITE_SINGLE (MODBUS_TYP_WRITE | MODBUS_TYP_SINGLE) -#define MODBUS_TYP_WRITE_MULTIPLE (MODBUS_TYP_WRITE | MODBUS_TYP_MULTIPLE) -#define MODBUS_TYP_READ_WRITE_MULTIPLE (MODBUS_TYP_READ | MODBUS_TYP_WRITE | MODBUS_TYP_MULTIPLE) - -/* Modbus Transaction Structure, request/response. */ -typedef struct ModbusTransaction_ { - struct ModbusState_ *modbus; - - uint64_t tx_num; /**< internal: id */ - uint16_t transactionId; - uint16_t length; - uint8_t function; - uint8_t category; - uint8_t type; - uint8_t replied; /**< bool indicating request is replied to. */ - - union { - uint16_t subFunction; - uint8_t mei; - struct { - struct { - uint16_t address; - uint16_t quantity; - } read; - struct { - uint16_t address; - uint16_t quantity; - uint8_t count; - } write; - }; - }; - uint16_t *data; /**< to store data to write, bit is converted in 16bits. */ - - AppLayerDecoderEvents *decoder_events; /**< per tx events */ - DetectEngineState *de_state; - - TAILQ_ENTRY(ModbusTransaction_) next; -} ModbusTransaction; - -/* Modbus State Structure. */ -typedef struct ModbusState_ { - TAILQ_HEAD(, ModbusTransaction_) tx_list; /**< transaction list */ - ModbusTransaction *curr; /**< ptr to current tx */ - uint64_t transaction_max; - uint32_t unreplied_cnt; /**< number of unreplied requests */ - uint16_t events; - uint8_t givenup; /**< bool indicating flood. */ -} ModbusState; - -void RegisterModbusParsers(void); -void ModbusParserRegisterTests(void); - -#endif /* __APP_LAYER_MODBUS_H__ */ diff --git a/framework/src/suricata/src/app-layer-nbss.h b/framework/src/suricata/src/app-layer-nbss.h deleted file mode 100644 index 7ae8f2b4..00000000 --- a/framework/src/suricata/src/app-layer-nbss.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Kirby Kuehl - */ - -#ifndef __APP_LAYER_NBSS_H__ -#define __APP_LAYER_NBSS_H__ - -#include "suricata-common.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "flow.h" -#include "stream.h" - -/* - http://ubiqx.org/cifs/rfc-draft/rfc1002.html#s4.3 - All session packets are of the following general structure: - - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | TYPE | FLAGS | LENGTH | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - / TRAILER (Packet Type Dependent) / - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - The TYPE, FLAGS, and LENGTH fields are present in every session - packet. -*/ - -#define NBSS_SESSION_MESSAGE 0x00 -#define NBSS_SESSION_REQUEST 0x81 -#define NBSS_POSITIVE_SESSION_RESPONSE 0x82 -#define NBSS_NEGATIVE_SESSION_RESPONSE 0x83 -#define NBSS_RETARGET_SESSION_RESPONSE 0x84 -#define NBSS_SESSION_KEEP_ALIVE 0x85 - -typedef struct NBSSHdr_ { - uint8_t type; - uint8_t flags; - uint32_t length; -} NBSSHdr; - -#define NBSS_HDR_LEN 4 - -#endif /* __APP_LAYER_NBSS_H__ */ diff --git a/framework/src/suricata/src/app-layer-parser.c b/framework/src/suricata/src/app-layer-parser.c deleted file mode 100644 index 2650863e..00000000 --- a/framework/src/suricata/src/app-layer-parser.c +++ /dev/null @@ -1,1387 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Generic App-layer parsing functions. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "util-unittest.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" - -#include "flow-util.h" -#include "flow-private.h" - -#include "detect-engine-state.h" -#include "detect-engine-port.h" - -#include "stream-tcp.h" -#include "stream-tcp-private.h" -#include "stream.h" -#include "stream-tcp-reassemble.h" - -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-smb.h" -#include "app-layer-smb2.h" -#include "app-layer-dcerpc.h" -#include "app-layer-dcerpc-udp.h" -#include "app-layer-htp.h" -#include "app-layer-ftp.h" -#include "app-layer-ssl.h" -#include "app-layer-ssh.h" -#include "app-layer-smtp.h" -#include "app-layer-dns-udp.h" -#include "app-layer-dns-tcp.h" -#include "app-layer-modbus.h" -#include "app-layer-template.h" - -#include "conf.h" -#include "util-spm.h" - -#include "util-debug.h" -#include "decode-events.h" -#include "util-unittest-helper.h" -#include "util-validate.h" - -#include "runmodes.h" - -static GetActiveTxIdFunc AppLayerGetActiveTxIdFuncPtr = NULL; - -struct AppLayerParserThreadCtx_ { - void *alproto_local_storage[FLOW_PROTO_MAX][ALPROTO_MAX]; -}; - - -/** - * \brief App layer protocol parser context. - */ -typedef struct AppLayerParserProtoCtx_ -{ - /* 0 - to_server, 1 - to_client. */ - int (*Parser[2])(Flow *f, void *protocol_state, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_storage); - char logger; - - void *(*StateAlloc)(void); - void (*StateFree)(void *); - void (*StateTransactionFree)(void *, uint64_t); - void *(*LocalStorageAlloc)(void); - void (*LocalStorageFree)(void *); - - void (*Truncate)(void *, uint8_t); - FileContainer *(*StateGetFiles)(void *, uint8_t); - AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t); - int (*StateHasEvents)(void *); - - int (*StateGetProgress)(void *alstate, uint8_t direction); - uint64_t (*StateGetTxCnt)(void *alstate); - void *(*StateGetTx)(void *alstate, uint64_t tx_id); - int (*StateGetProgressCompletionStatus)(uint8_t direction); - int (*StateGetEventInfo)(const char *event_name, - int *event_id, AppLayerEventType *event_type); - - int (*StateHasTxDetectState)(void *alstate); - DetectEngineState *(*GetTxDetectState)(void *tx); - int (*SetTxDetectState)(void *alstate, void *tx, DetectEngineState *); - - /* Indicates the direction the parser is ready to see the data - * the first time for a flow. Values accepted - - * STREAM_TOSERVER, STREAM_TOCLIENT */ - uint8_t first_data_dir; - -#ifdef UNITTESTS - void (*RegisterUnittests)(void); -#endif -} AppLayerParserProtoCtx; - -typedef struct AppLayerParserCtx_ { - AppLayerParserProtoCtx ctxs[FLOW_PROTO_MAX][ALPROTO_MAX]; -} AppLayerParserCtx; - -struct AppLayerParserState_ { - uint8_t flags; - - /* State version, incremented for each update. Can wrap around. */ - uint8_t version; - /* Indicates the current transaction that is being inspected. - * We have a var per direction. */ - uint64_t inspect_id[2]; - /* Indicates the current transaction being logged. Unlike inspect_id, - * we don't need a var per direction since we don't log a transaction - * unless we have the entire transaction. */ - uint64_t log_id; - - /* Used to store decoder events. */ - AppLayerDecoderEvents *decoder_events; -}; - -/* Static global version of the parser context. - * Post 2.0 let's look at changing this to move it out to app-layer.c. */ -static AppLayerParserCtx alp_ctx; - -AppLayerParserState *AppLayerParserStateAlloc(void) -{ - SCEnter(); - - AppLayerParserState *pstate = (AppLayerParserState *)SCMalloc(sizeof(*pstate)); - if (pstate == NULL) - goto end; - memset(pstate, 0, sizeof(*pstate)); - - end: - SCReturnPtr(pstate, "AppLayerParserState"); -} - -void AppLayerParserStateFree(AppLayerParserState *pstate) -{ - SCEnter(); - - if (pstate->decoder_events != NULL) - AppLayerDecoderEventsFreeEvents(&pstate->decoder_events); - SCFree(pstate); - - SCReturn; -} - -int AppLayerParserSetup(void) -{ - SCEnter(); - - memset(&alp_ctx, 0, sizeof(alp_ctx)); - - /* set the default tx handler if none was set explicitly */ - if (AppLayerGetActiveTxIdFuncPtr == NULL) { - RegisterAppLayerGetActiveTxIdFunc(AppLayerTransactionGetActiveDetectLog); - } - - SCReturnInt(0); -} - -int AppLayerParserDeSetup(void) -{ - SCEnter(); - - SCReturnInt(0); -} - -AppLayerParserThreadCtx *AppLayerParserThreadCtxAlloc(void) -{ - SCEnter(); - - AppProto alproto = 0; - int flow_proto = 0; - AppLayerParserThreadCtx *tctx; - - tctx = SCMalloc(sizeof(*tctx)); - if (tctx == NULL) - goto end; - memset(tctx, 0, sizeof(*tctx)); - - for (flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) { - for (alproto = 0; alproto < ALPROTO_MAX; alproto++) { - uint8_t ipproto = FlowGetReverseProtoMapping(flow_proto); - - tctx->alproto_local_storage[flow_proto][alproto] = - AppLayerParserGetProtocolParserLocalStorage(ipproto, alproto); - } - } - - end: - SCReturnPtr(tctx, "void *"); -} - -void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx) -{ - SCEnter(); - - AppProto alproto = 0; - int flow_proto = 0; - - for (flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) { - for (alproto = 0; alproto < ALPROTO_MAX; alproto++) { - uint8_t ipproto = FlowGetReverseProtoMapping(flow_proto); - - AppLayerParserDestroyProtocolParserLocalStorage(ipproto, alproto, - tctx->alproto_local_storage[flow_proto][alproto]); - } - } - - SCFree(tctx); - SCReturn; -} - -int AppLayerParserConfParserEnabled(const char *ipproto, - const char *alproto_name) -{ - SCEnter(); - - int enabled = 1; - char param[100]; - ConfNode *node; - int r; - - if (RunmodeIsUnittests()) - goto enabled; - - r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.", - alproto_name, ".enabled"); - if (r < 0) { - SCLogError(SC_ERR_FATAL, "snprintf failure."); - exit(EXIT_FAILURE); - } else if (r > (int)sizeof(param)) { - SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); - exit(EXIT_FAILURE); - } - - node = ConfGetNode(param); - if (node == NULL) { - SCLogDebug("Entry for %s not found.", param); - r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.", - alproto_name, ".", ipproto, ".enabled"); - if (r < 0) { - SCLogError(SC_ERR_FATAL, "snprintf failure."); - exit(EXIT_FAILURE); - } else if (r > (int)sizeof(param)) { - SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); - exit(EXIT_FAILURE); - } - - node = ConfGetNode(param); - if (node == NULL) { - SCLogDebug("Entry for %s not found.", param); - goto enabled; - } - } - - if (strcasecmp(node->val, "yes") == 0) { - goto enabled; - } else if (strcasecmp(node->val, "no") == 0) { - goto disabled; - } else if (strcasecmp(node->val, "detection-only") == 0) { - goto disabled; - } else { - SCLogError(SC_ERR_FATAL, "Invalid value found for %s.", param); - exit(EXIT_FAILURE); - } - - disabled: - enabled = 0; - enabled: - SCReturnInt(enabled); -} - -/***** Parser related registration *****/ - -int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto, - uint8_t direction, - int (*Parser)(Flow *f, void *protocol_state, - AppLayerParserState *pstate, - uint8_t *buf, uint32_t buf_len, - void *local_storage)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - Parser[(direction & STREAM_TOSERVER) ? 0 : 1] = Parser; - - SCReturnInt(0); -} - -void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, AppProto alproto, - uint8_t direction) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].first_data_dir |= - (direction & (STREAM_TOSERVER | STREAM_TOCLIENT)); - - SCReturn; -} - -void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, - void *(*StateAlloc)(void), - void (*StateFree)(void *)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateAlloc = - StateAlloc; - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateFree = - StateFree; - - SCReturn; -} - -void AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto, AppProto alproto, - void *(*LocalStorageAlloc)(void), - void (*LocalStorageFree)(void *)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].LocalStorageAlloc = - LocalStorageAlloc; - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].LocalStorageFree = - LocalStorageFree; - - SCReturn; -} - -void AppLayerParserRegisterGetFilesFunc(uint8_t ipproto, AppProto alproto, - FileContainer *(*StateGetFiles)(void *, uint8_t)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetFiles = - StateGetFiles; - - SCReturn; -} - -void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto alproto, - AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetEvents = - StateGetEvents; - - SCReturn; -} - -void AppLayerParserRegisterHasEventsFunc(uint8_t ipproto, AppProto alproto, - int (*StateHasEvents)(void *)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateHasEvents = - StateHasEvents; - - SCReturn; -} - -void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].logger = TRUE; - - SCReturn; -} - -void AppLayerParserRegisterTruncateFunc(uint8_t ipproto, AppProto alproto, - void (*Truncate)(void *, uint8_t)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate = Truncate; - - SCReturn; -} - -void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, - int (*StateGetProgress)(void *alstate, uint8_t direction)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetProgress = StateGetProgress; - - SCReturn; -} - -void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, - void (*StateTransactionFree)(void *, uint64_t)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateTransactionFree = StateTransactionFree; - - SCReturn; -} - -void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, - uint64_t (*StateGetTxCnt)(void *alstate)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetTxCnt = StateGetTxCnt; - - SCReturn; -} - -void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, - void *(StateGetTx)(void *alstate, uint64_t tx_id)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetTx = StateGetTx; - - SCReturn; -} - -void AppLayerParserRegisterGetStateProgressCompletionStatus(uint8_t ipproto, - AppProto alproto, - int (*StateGetProgressCompletionStatus)(uint8_t direction)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetProgressCompletionStatus = StateGetProgressCompletionStatus; - - SCReturn; -} - -void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, - int (*StateGetEventInfo)(const char *event_name, int *event_id, - AppLayerEventType *event_type)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetEventInfo = StateGetEventInfo; - - SCReturn; -} - -void AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto, AppProto alproto, - int (*StateHasTxDetectState)(void *alstate), - DetectEngineState *(*GetTxDetectState)(void *tx), - int (*SetTxDetectState)(void *alstate, void *tx, DetectEngineState *)) -{ - SCEnter(); - - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateHasTxDetectState = StateHasTxDetectState; - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState = GetTxDetectState; - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxDetectState = SetTxDetectState; - - SCReturn; -} - -/***** Get and transaction functions *****/ - -void *AppLayerParserGetProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto) -{ - SCEnter(); - void * r = NULL; - - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - LocalStorageAlloc != NULL) - { - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - LocalStorageAlloc(); - } - - SCReturnPtr(r, "void *"); -} - -void AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto, - void *local_data) -{ - SCEnter(); - - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - LocalStorageFree != NULL) - { - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - LocalStorageFree(local_data); - } - - SCReturn; -} - -uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate) -{ - SCEnter(); - - SCReturnCT((pstate == NULL) ? 0 : pstate->log_id, "uint64_t"); -} - -void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate) -{ - SCEnter(); - - if (pstate != NULL) - pstate->log_id++; - - SCReturn; -} - -uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction) -{ - SCEnter(); - - if (pstate == NULL) - SCReturnCT(0ULL, "uint64_t"); - - SCReturnCT(pstate->inspect_id[direction & STREAM_TOSERVER ? 0 : 1], "uint64_t"); -} - -void AppLayerParserSetTransactionInspectId(AppLayerParserState *pstate, - const uint8_t ipproto, const AppProto alproto, - void *alstate, const uint8_t flags) -{ - SCEnter(); - - int direction = (flags & STREAM_TOSERVER) ? 0 : 1; - uint64_t total_txs = AppLayerParserGetTxCnt(ipproto, alproto, alstate); - uint64_t idx = AppLayerParserGetTransactionInspectId(pstate, flags); - int state_done_progress = AppLayerParserGetStateProgressCompletionStatus(ipproto, alproto, flags); - void *tx; - int state_progress; - - for (; idx < total_txs; idx++) { - tx = AppLayerParserGetTx(ipproto, alproto, alstate, idx); - if (tx == NULL) - continue; - state_progress = AppLayerParserGetStateProgress(ipproto, alproto, tx, flags); - if (state_progress >= state_done_progress) - continue; - else - break; - } - pstate->inspect_id[direction] = idx; - - SCReturn; -} - -AppLayerDecoderEvents *AppLayerParserGetDecoderEvents(AppLayerParserState *pstate) -{ - SCEnter(); - - SCReturnPtr(pstate->decoder_events, - "AppLayerDecoderEvents *"); -} - -void AppLayerParserSetDecoderEvents(AppLayerParserState *pstate, AppLayerDecoderEvents *devents) -{ - pstate->decoder_events = devents; -} - -AppLayerDecoderEvents *AppLayerParserGetEventsByTx(uint8_t ipproto, AppProto alproto, - void *alstate, uint64_t tx_id) -{ - SCEnter(); - - AppLayerDecoderEvents *ptr = NULL; - - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetEvents != NULL) - { - ptr = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetEvents(alstate, tx_id); - } - - SCReturnPtr(ptr, "AppLayerDecoderEvents *"); -} - -uint16_t AppLayerParserGetStateVersion(AppLayerParserState *pstate) -{ - SCEnter(); - SCReturnCT((pstate == NULL) ? 0 : pstate->version, "uint8_t"); -} - -FileContainer *AppLayerParserGetFiles(uint8_t ipproto, AppProto alproto, - void *alstate, uint8_t direction) -{ - SCEnter(); - - FileContainer *ptr = NULL; - - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetFiles != NULL) - { - ptr = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetFiles(alstate, direction); - } - - SCReturnPtr(ptr, "FileContainer *"); -} - -/** \brief active TX retrieval for normal ops: so with detection and logging - * - * \retval tx_id lowest tx_id that still needs work */ -uint64_t AppLayerTransactionGetActiveDetectLog(Flow *f, uint8_t flags) -{ - AppLayerParserProtoCtx *p = &alp_ctx.ctxs[FlowGetProtoMapping(f->proto)][f->alproto]; - uint64_t log_id = f->alparser->log_id; - uint64_t inspect_id = f->alparser->inspect_id[flags & STREAM_TOSERVER ? 0 : 1]; - if (p->logger == TRUE) { - return (log_id < inspect_id) ? log_id : inspect_id; - } else { - return inspect_id; - } -} - -/** \brief active TX retrieval for logging only: so NO detection - * - * If the logger is enabled, we simply return the log_id here. - * - * Otherwise, we go look for the tx id. There probably is no point - * in running this function in that case though. With no detection - * and no logging, why run a parser in the first place? - **/ -uint64_t AppLayerTransactionGetActiveLogOnly(Flow *f, uint8_t flags) -{ - AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][f->alproto]; - - if (p->logger == TRUE) { - uint64_t log_id = f->alparser->log_id; - SCLogDebug("returning %"PRIu64, log_id); - return log_id; - } - - /* logger is disabled, return highest 'complete' tx id */ - uint64_t total_txs = AppLayerParserGetTxCnt(f->proto, f->alproto, f->alstate); - uint64_t idx = AppLayerParserGetTransactionInspectId(f->alparser, flags); - int state_done_progress = AppLayerParserGetStateProgressCompletionStatus(f->proto, f->alproto, flags); - void *tx; - int state_progress; - - for (; idx < total_txs; idx++) { - tx = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, idx); - if (tx == NULL) - continue; - state_progress = AppLayerParserGetStateProgress(f->proto, f->alproto, tx, flags); - if (state_progress >= state_done_progress) - continue; - else - break; - } - SCLogDebug("returning %"PRIu64, idx); - return idx; -} - -void RegisterAppLayerGetActiveTxIdFunc(GetActiveTxIdFunc FuncPtr) -{ - //BUG_ON(AppLayerGetActiveTxIdFuncPtr != NULL); - AppLayerGetActiveTxIdFuncPtr = FuncPtr; - SCLogDebug("AppLayerGetActiveTxIdFuncPtr is now %p", AppLayerGetActiveTxIdFuncPtr); -} - -/** - * \brief Get 'active' tx id, meaning the lowest id that still need work. - * - * \retval id tx id - */ -static uint64_t AppLayerTransactionGetActive(Flow *f, uint8_t flags) -{ - BUG_ON(AppLayerGetActiveTxIdFuncPtr == NULL); - - return AppLayerGetActiveTxIdFuncPtr(f, flags); -} - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -/** - * \brief remove obsolete (inspected and logged) transactions - */ -static void AppLayerParserTransactionsCleanup(Flow *f) -{ - DEBUG_ASSERT_FLOW_LOCKED(f); - - AppLayerParserProtoCtx *p = &alp_ctx.ctxs[FlowGetProtoMapping(f->proto)][f->alproto]; - if (p->StateTransactionFree == NULL) - return; - - uint64_t tx_id_ts = AppLayerTransactionGetActive(f, STREAM_TOSERVER); - uint64_t tx_id_tc = AppLayerTransactionGetActive(f, STREAM_TOCLIENT); - - uint64_t min = MIN(tx_id_ts, tx_id_tc); - if (min > 0) { - SCLogDebug("freeing %"PRIu64" %p", min - 1, p->StateTransactionFree); - p->StateTransactionFree(f->alstate, min - 1); - } -} - -#define IS_DISRUPTED(flags) \ - ((flags) & (STREAM_DEPTH|STREAM_GAP)) - -/** - * \brief get the progress value for a tx/protocol - * - * If the stream is disrupted, we return the 'completion' value. - */ -int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto, - void *alstate, uint8_t flags) -{ - SCEnter(); - int r = 0; - if (unlikely(IS_DISRUPTED(flags))) { - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetProgressCompletionStatus(flags); - } else { - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetProgress(alstate, flags); - } - SCReturnInt(r); -} - -uint64_t AppLayerParserGetTxCnt(uint8_t ipproto, AppProto alproto, void *alstate) -{ - SCEnter(); - uint64_t r = 0; - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetTxCnt(alstate); - SCReturnCT(r, "uint64_t"); -} - -void *AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id) -{ - SCEnter(); - void * r = NULL; - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetTx(alstate, tx_id); - SCReturnPtr(r, "void *"); -} - -int AppLayerParserGetStateProgressCompletionStatus(uint8_t ipproto, AppProto alproto, - uint8_t direction) -{ - SCEnter(); - int r = 0; - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateGetProgressCompletionStatus(direction); - SCReturnInt(r); -} - -int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name, - int *event_id, AppLayerEventType *event_type) -{ - SCEnter(); - int ipproto_map = FlowGetProtoMapping(ipproto); - int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfo == NULL) ? - -1 : alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfo(event_name, event_id, event_type); - SCReturnInt(r); -} - -uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto) -{ - SCEnter(); - uint8_t r = 0; - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - first_data_dir; - SCReturnCT(r, "uint8_t"); -} - -uint64_t AppLayerParserGetTransactionActive(uint8_t ipproto, AppProto alproto, - AppLayerParserState *pstate, uint8_t direction) -{ - SCEnter(); - - uint64_t active_id; - - uint64_t log_id = pstate->log_id; - uint64_t inspect_id = pstate->inspect_id[direction & STREAM_TOSERVER ? 0 : 1]; - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].logger == TRUE) { - active_id = (log_id < inspect_id) ? log_id : inspect_id; - } else { - active_id = inspect_id; - } - - SCReturnCT(active_id, "uint64_t"); -} - -int AppLayerParserSupportsTxDetectState(uint8_t ipproto, AppProto alproto) -{ - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState != NULL) - return TRUE; - return FALSE; -} - -int AppLayerParserHasTxDetectState(uint8_t ipproto, AppProto alproto, void *alstate) -{ - int r; - SCEnter(); - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateHasTxDetectState == NULL) - return -ENOSYS; - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateHasTxDetectState(alstate); - SCReturnInt(r); -} - -DetectEngineState *AppLayerParserGetTxDetectState(uint8_t ipproto, AppProto alproto, void *tx) -{ - SCEnter(); - DetectEngineState *s; - s = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState(tx); - SCReturnPtr(s, "DetectEngineState"); -} - -int AppLayerParserSetTxDetectState(uint8_t ipproto, AppProto alproto, - void *alstate, void *tx, DetectEngineState *s) -{ - int r; - SCEnter(); - if ((alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState(tx) != NULL)) - SCReturnInt(-EBUSY); - r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxDetectState(alstate, tx, s); - SCReturnInt(r); -} - -/***** General *****/ - -int AppLayerParserParse(AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, - uint8_t flags, uint8_t *input, uint32_t input_len) -{ - SCEnter(); -#ifdef DEBUG_VALIDATION - BUG_ON(f->protomap != FlowGetProtoMapping(f->proto)); -#endif - AppLayerParserState *pstate = NULL; - AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][alproto]; - void *alstate = NULL; - - /* we don't have the parser registered for this protocol */ - if (p->StateAlloc == NULL) - goto end; - - /* Do this check before calling AppLayerParse */ - if (flags & STREAM_GAP) { - SCLogDebug("stream gap detected (missing packets), " - "this is not yet supported."); - - if (f->alstate != NULL) - AppLayerParserStreamTruncated(f->proto, alproto, f->alstate, flags); - goto error; - } - - /* Get the parser state (if any) */ - pstate = f->alparser; - if (pstate == NULL) { - f->alparser = pstate = AppLayerParserStateAlloc(); - if (pstate == NULL) - goto error; - } - pstate->version++; - SCLogDebug("app layer parser state version incremented to %"PRIu8, - pstate->version); - - if (flags & STREAM_EOF) - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF); - - alstate = f->alstate; - if (alstate == NULL) { - f->alstate = alstate = p->StateAlloc(); - if (alstate == NULL) - goto error; - SCLogDebug("alloced new app layer state %p (name %s)", - alstate, AppLayerGetProtoName(f->alproto)); - } else { - SCLogDebug("using existing app layer state %p (name %s))", - alstate, AppLayerGetProtoName(f->alproto)); - } - - /* invoke the recursive parser, but only on data. We may get empty msgs on EOF */ - if (input_len > 0 || (flags & STREAM_EOF)) { - /* invoke the parser */ - if (p->Parser[(flags & STREAM_TOSERVER) ? 0 : 1](f, alstate, pstate, - input, input_len, - alp_tctx->alproto_local_storage[f->protomap][alproto]) < 0) - { - goto error; - } - } - - /* set the packets to no inspection and reassembly if required */ - if (pstate->flags & APP_LAYER_PARSER_NO_INSPECTION) { - AppLayerParserSetEOF(pstate); - FlowSetNoPayloadInspectionFlag(f); - - if (f->proto == IPPROTO_TCP) { - StreamTcpDisableAppLayer(f); - - /* Set the no reassembly flag for both the stream in this TcpSession */ - if (pstate->flags & APP_LAYER_PARSER_NO_REASSEMBLY) { - /* Used only if it's TCP */ - TcpSession *ssn = f->protoctx; - if (ssn != NULL) { - StreamTcpSetSessionNoReassemblyFlag(ssn, - flags & STREAM_TOCLIENT ? 1 : 0); - StreamTcpSetSessionNoReassemblyFlag(ssn, - flags & STREAM_TOSERVER ? 1 : 0); - } - } - } - } - - /* In cases like HeartBleed for TLS we need to inspect AppLayer but not Payload */ - if (!(f->flags & FLOW_NOPAYLOAD_INSPECTION) && pstate->flags & APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD) { - FlowSetNoPayloadInspectionFlag(f); - /* Set the no reassembly flag for both the stream in this TcpSession */ - if (f->proto == IPPROTO_TCP) { - /* Used only if it's TCP */ - TcpSession *ssn = f->protoctx; - if (ssn != NULL) { - StreamTcpSetDisableRawReassemblyFlag(ssn, 0); - StreamTcpSetDisableRawReassemblyFlag(ssn, 1); - } - } - } - - /* next, see if we can get rid of transactions now */ - AppLayerParserTransactionsCleanup(f); - - /* stream truncated, inform app layer */ - if (flags & STREAM_DEPTH) - AppLayerParserStreamTruncated(f->proto, alproto, alstate, flags); - - end: - SCReturnInt(0); - error: - /* Set the no app layer inspection flag for both - * the stream in this Flow */ - if (f->proto == IPPROTO_TCP) { - StreamTcpDisableAppLayer(f); - } - AppLayerParserSetEOF(pstate); - SCReturnInt(-1); -} - -void AppLayerParserSetEOF(AppLayerParserState *pstate) -{ - SCEnter(); - - if (pstate == NULL) - goto end; - - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF); - /* increase version so we will inspect it one more time - * with the EOF flags now set */ - pstate->version++; - - end: - SCReturn; -} - -int AppLayerParserHasDecoderEvents(uint8_t ipproto, AppProto alproto, - void *alstate, AppLayerParserState *pstate, - uint8_t flags) -{ - SCEnter(); - - if (alstate == NULL || pstate == NULL) - goto not_present; - - AppLayerDecoderEvents *decoder_events; - uint64_t tx_id; - uint64_t max_id; - - if (AppLayerParserProtocolIsTxEventAware(ipproto, alproto)) { - /* fast path if supported by alproto */ - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateHasEvents != NULL) { - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - StateHasEvents(alstate) == 1) - { - goto present; - } - } else { - /* check each tx */ - tx_id = AppLayerParserGetTransactionInspectId(pstate, flags); - max_id = AppLayerParserGetTxCnt(ipproto, alproto, alstate); - for ( ; tx_id < max_id; tx_id++) { - decoder_events = AppLayerParserGetEventsByTx(ipproto, alproto, alstate, tx_id); - if (decoder_events && decoder_events->cnt) - goto present; - } - } - } - - decoder_events = AppLayerParserGetDecoderEvents(pstate); - if (decoder_events && decoder_events->cnt) - goto present; - - /* if we have reached here, we don't have events */ - not_present: - SCReturnInt(0); - present: - SCReturnInt(1); -} - -int AppLayerParserProtocolIsTxAware(uint8_t ipproto, AppProto alproto) -{ - SCEnter(); - int ipproto_map = FlowGetProtoMapping(ipproto); - int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetTx == NULL) ? 0 : 1; - SCReturnInt(r); -} - -int AppLayerParserProtocolIsTxEventAware(uint8_t ipproto, AppProto alproto) -{ - SCEnter(); - int ipproto_map = FlowGetProtoMapping(ipproto); - int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetEvents == NULL) ? 0 : 1; - SCReturnInt(r); -} - -int AppLayerParserProtocolSupportsTxs(uint8_t ipproto, AppProto alproto) -{ - SCEnter(); - int ipproto_map = FlowGetProtoMapping(ipproto); - int r = (alp_ctx.ctxs[ipproto_map][alproto].StateTransactionFree == NULL) ? 0 : 1; - SCReturnInt(r); -} - -int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto) -{ - SCEnter(); - int ipproto_map = FlowGetProtoMapping(ipproto); - int r = (alp_ctx.ctxs[ipproto_map][alproto].logger == 0) ? 0 : 1; - SCReturnInt(r); -} - -void AppLayerParserTriggerRawStreamReassembly(Flow *f) -{ - SCEnter(); - - if (f != NULL && f->protoctx != NULL) - StreamTcpReassembleTriggerRawReassembly(f->protoctx); - - SCReturn; -} - -/***** Cleanup *****/ - -void AppLayerParserStateCleanup(uint8_t ipproto, AppProto alproto, void *alstate, - AppLayerParserState *pstate) -{ - SCEnter(); - - AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]; - - if (ctx->StateFree != NULL && alstate != NULL) - ctx->StateFree(alstate); - - /* free the app layer parser api state */ - if (pstate != NULL) - AppLayerParserStateFree(pstate); - - SCReturn; -} - - -void AppLayerParserRegisterProtocolParsers(void) -{ - SCEnter(); - - RegisterHTPParsers(); - RegisterSSLParsers(); - RegisterSMBParsers(); - /** \todo bug 719 */ - //RegisterSMB2Parsers(); - RegisterDCERPCParsers(); - RegisterDCERPCUDPParsers(); - RegisterFTPParsers(); - RegisterSSHParsers(); - RegisterSMTPParsers(); - RegisterDNSUDPParsers(); - RegisterDNSTCPParsers(); - RegisterModbusParsers(); - RegisterTemplateParsers(); - - /** IMAP */ - AppLayerProtoDetectRegisterProtocol(ALPROTO_IMAP, "imap"); - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", "imap")) { - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_IMAP, - "1|20|capability", 12, 0, STREAM_TOSERVER) < 0) - { - SCLogInfo("imap proto registration failure\n"); - exit(EXIT_FAILURE); - } - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - "imap"); - } - - /** MSN Messenger */ - AppLayerProtoDetectRegisterProtocol(ALPROTO_MSN, "msn"); - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", "msn")) { - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_MSN, - "msn", 10, 6, STREAM_TOSERVER) < 0) - { - SCLogInfo("msn proto registration failure\n"); - exit(EXIT_FAILURE); - } - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - "msn"); - } - - return; -} - - -void AppLayerParserStateSetFlag(AppLayerParserState *pstate, uint8_t flag) -{ - SCEnter(); - pstate->flags |= flag; - SCReturn; -} - -int AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint8_t flag) -{ - SCEnter(); - SCReturnInt(pstate->flags & flag); -} - - -void AppLayerParserStreamTruncated(uint8_t ipproto, AppProto alproto, void *alstate, - uint8_t direction) -{ - SCEnter(); - - - if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate != NULL) - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate(alstate, direction); - - SCReturn; -} - -#ifdef DEBUG -void AppLayerParserStatePrintDetails(AppLayerParserState *pstate) -{ - SCEnter(); - - if (pstate == NULL) - SCReturn; - - AppLayerParserState *p = pstate; - SCLogDebug("AppLayerParser parser state information for parser state p(%p). " - "p->inspect_id[0](%"PRIu64"), " - "p->inspect_id[1](%"PRIu64"), " - "p->log_id(%"PRIu64"), " - "p->version(%"PRIu8"), " - "p->decoder_events(%p).", - pstate, p->inspect_id[0], p->inspect_id[1], p->log_id, - p->version, p->decoder_events); - - SCReturn; -} -#endif - - -/***** Unittests *****/ - -#ifdef UNITTESTS - -static AppLayerParserCtx alp_ctx_backup_unittest; - -typedef struct TestState_ { - uint8_t test; -} TestState; - -/** - * \brief Test parser function to test the memory deallocation of app layer - * parser of occurence of an error. - */ -static int TestProtocolParser(Flow *f, void *test_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SCEnter(); - SCReturnInt(-1); -} - -/** \brief Function to allocates the Test protocol state memory - */ -static void *TestProtocolStateAlloc(void) -{ - SCEnter(); - void *s = SCMalloc(sizeof(TestState)); - if (unlikely(s == NULL)) - goto end; - memset(s, 0, sizeof(TestState)); - end: - SCReturnPtr(s, "TestState"); -} - -/** \brief Function to free the Test Protocol state memory - */ -static void TestProtocolStateFree(void *s) -{ - SCFree(s); -} - -void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, - void (*RegisterUnittests)(void)) -{ - SCEnter(); - alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto]. - RegisterUnittests = RegisterUnittests; - SCReturn; -} - -void AppLayerParserBackupParserTable(void) -{ - SCEnter(); - alp_ctx_backup_unittest = alp_ctx; - memset(&alp_ctx, 0, sizeof(alp_ctx)); - SCReturn; -} - -void AppLayerParserRestoreParserTable(void) -{ - SCEnter(); - alp_ctx = alp_ctx_backup_unittest; - memset(&alp_ctx_backup_unittest, 0, sizeof(alp_ctx_backup_unittest)); - SCReturn; -} - -/** - * \test Test the deallocation of app layer parser memory on occurance of - * error in the parsing process. - */ -static int AppLayerParserTest01(void) -{ - AppLayerParserBackupParserTable(); - - int result = 0; - Flow *f = NULL; - uint8_t testbuf[] = { 0x11 }; - uint32_t testlen = sizeof(testbuf); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&ssn, 0, sizeof(ssn)); - - /* Register the Test protocol state and parser functions */ - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEST, STREAM_TOSERVER, - TestProtocolParser); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_TEST, - TestProtocolStateAlloc, TestProtocolStateFree); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->alproto = ALPROTO_TEST; - f->proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, - testbuf, testlen); - if (r != -1) { - printf("returned %" PRId32 ", expected -1: ", r); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - if (!(ssn.flags & STREAMTCP_FLAG_APP_LAYER_DISABLED)) { - printf("flag should have been set, but is not: "); - goto end; - } - - result = 1; - end: - AppLayerParserRestoreParserTable(); - StreamTcpFreeConfig(TRUE); - - UTHFreeFlow(f); - return result; -} - -/** - * \test Test the deallocation of app layer parser memory on occurance of - * error in the parsing process for UDP. - */ -static int AppLayerParserTest02(void) -{ - AppLayerParserBackupParserTable(); - - int result = 1; - Flow *f = NULL; - uint8_t testbuf[] = { 0x11 }; - uint32_t testlen = sizeof(testbuf); - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - /* Register the Test protocol state and parser functions */ - AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_TEST, STREAM_TOSERVER, - TestProtocolParser); - AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_TEST, - TestProtocolStateAlloc, TestProtocolStateFree); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40); - if (f == NULL) - goto end; - f->alproto = ALPROTO_TEST; - f->proto = IPPROTO_UDP; - f->protomap = FlowGetProtoMapping(f->proto); - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, testbuf, - testlen); - if (r != -1) { - printf("returned %" PRId32 ", expected -1: \n", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - end: - AppLayerParserRestoreParserTable(); - StreamTcpFreeConfig(TRUE); - UTHFreeFlow(f); - return result; -} - - -void AppLayerParserRegisterUnittests(void) -{ - SCEnter(); - - int ip; - AppProto alproto; - AppLayerParserProtoCtx *ctx; - - for (ip = 0; ip < FLOW_PROTO_DEFAULT; ip++) { - for (alproto = 0; alproto < ALPROTO_MAX; alproto++) { - ctx = &alp_ctx.ctxs[ip][alproto]; - if (ctx->RegisterUnittests == NULL) - continue; - ctx->RegisterUnittests(); - } - } - - UtRegisterTest("AppLayerParserTest01", AppLayerParserTest01, 1); - UtRegisterTest("AppLayerParserTest02", AppLayerParserTest02, 1); - - SCReturn; -} - -#endif diff --git a/framework/src/suricata/src/app-layer-parser.h b/framework/src/suricata/src/app-layer-parser.h deleted file mode 100644 index 62cb8f68..00000000 --- a/framework/src/suricata/src/app-layer-parser.h +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#ifndef __APP_LAYER_PARSER_H__ -#define __APP_LAYER_PARSER_H__ - -#include "app-layer-events.h" -#include "detect-engine-state.h" -#include "util-file.h" - -#define APP_LAYER_PARSER_EOF 0x01 -#define APP_LAYER_PARSER_NO_INSPECTION 0x02 -#define APP_LAYER_PARSER_NO_REASSEMBLY 0x04 -#define APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD 0x08 - - -/***** transaction handling *****/ - -/** \brief Function ptr type for getting active TxId from a flow - * Used by AppLayerTransactionGetActive. - */ -typedef uint64_t (*GetActiveTxIdFunc)(Flow *f, uint8_t flags); - -/** \brief Register GetActiveTxId Function - * - */ -void RegisterAppLayerGetActiveTxIdFunc(GetActiveTxIdFunc FuncPtr); - -/** \brief active TX retrieval for normal ops: so with detection and logging - * - * \retval tx_id lowest tx_id that still needs work - * - * This is the default function. - */ -uint64_t AppLayerTransactionGetActiveDetectLog(Flow *f, uint8_t flags); - -/** \brief active TX retrieval for logging only ops - * - * \retval tx_id lowest tx_id that still needs work - */ -uint64_t AppLayerTransactionGetActiveLogOnly(Flow *f, uint8_t flags); - - -int AppLayerParserSetup(void); - -int AppLayerParserDeSetup(void); - -typedef struct AppLayerParserThreadCtx_ AppLayerParserThreadCtx; - -/** - * \brief Gets a new app layer protocol's parser thread context. - * - * \retval Non-NULL pointer on success. - * NULL pointer on failure. - */ -AppLayerParserThreadCtx *AppLayerParserThreadCtxAlloc(void); - -/** - * \brief Destroys the app layer parser thread context obtained - * using AppLayerParserThreadCtxAlloc(). - * - * \param tctx Pointer to the thread context to be destroyed. - */ -void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx); - -/** - * \brief Given a protocol name, checks if the parser is enabled in - * the conf file. - * - * \param alproto_name Name of the app layer protocol. - * - * \retval 1 If enabled. - * \retval 0 If disabled. - */ -int AppLayerParserConfParserEnabled(const char *ipproto, - const char *alproto_name); - -/***** Parser related registration *****/ - -/** - * \brief Register app layer parser for the protocol. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto, - uint8_t direction, - int (*Parser)(Flow *f, void *protocol_state, - AppLayerParserState *pstate, - uint8_t *buf, uint32_t buf_len, - void *local_storage)); -void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, - AppProto alproto, - uint8_t direction); -void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, - void *(*StateAlloc)(void), - void (*StateFree)(void *)); -void AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto, AppProto proto, - void *(*LocalStorageAlloc)(void), - void (*LocalStorageFree)(void *)); -void AppLayerParserRegisterGetFilesFunc(uint8_t ipproto, AppProto alproto, - FileContainer *(*StateGetFiles)(void *, uint8_t)); -void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto proto, - AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t)); -void AppLayerParserRegisterHasEventsFunc(uint8_t ipproto, AppProto alproto, - int (*StateHasEvents)(void *)); -void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto); -void AppLayerParserRegisterTruncateFunc(uint8_t ipproto, AppProto alproto, - void (*Truncate)(void *, uint8_t)); -void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, - int (*StateGetStateProgress)(void *alstate, uint8_t direction)); -void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, - void (*StateTransactionFree)(void *, uint64_t)); -void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, - uint64_t (*StateGetTxCnt)(void *alstate)); -void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, - void *(StateGetTx)(void *alstate, uint64_t tx_id)); -void AppLayerParserRegisterGetStateProgressCompletionStatus(uint8_t ipproto, - AppProto alproto, - int (*StateGetStateProgressCompletionStatus)(uint8_t direction)); -void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, - int (*StateGetEventInfo)(const char *event_name, int *event_id, - AppLayerEventType *event_type)); -void AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto, AppProto alproto, - int (*StateHasTxDetectState)(void *alstate), - DetectEngineState *(*GetTxDetectState)(void *tx), - int (*SetTxDetectState)(void *alstate, void *tx, DetectEngineState *)); - -/***** Get and transaction functions *****/ - -void *AppLayerParserGetProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto); -void AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto, - void *local_data); - - -uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate); -void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate); -uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction); -void AppLayerParserSetTransactionInspectId(AppLayerParserState *pstate, - const uint8_t ipproto, const AppProto alproto, void *alstate, - const uint8_t flags); -AppLayerDecoderEvents *AppLayerParserGetDecoderEvents(AppLayerParserState *pstate); -void AppLayerParserSetDecoderEvents(AppLayerParserState *pstate, AppLayerDecoderEvents *devents); -AppLayerDecoderEvents *AppLayerParserGetEventsByTx(uint8_t ipproto, AppProto alproto, void *alstate, - uint64_t tx_id); -uint16_t AppLayerParserGetStateVersion(AppLayerParserState *pstate); -FileContainer *AppLayerParserGetFiles(uint8_t ipproto, AppProto alproto, - void *alstate, uint8_t direction); -int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto, - void *alstate, uint8_t direction); -uint64_t AppLayerParserGetTxCnt(uint8_t ipproto, AppProto alproto, void *alstate); -void *AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id); -int AppLayerParserGetStateProgressCompletionStatus(uint8_t ipproto, AppProto alproto, - uint8_t direction); -int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name, - int *event_id, AppLayerEventType *event_type); - -uint64_t AppLayerParserGetTransactionActive(uint8_t ipproto, AppProto alproto, AppLayerParserState *pstate, uint8_t direction); - -uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto); - -int AppLayerParserSupportsTxDetectState(uint8_t ipproto, AppProto alproto); -int AppLayerParserHasTxDetectState(uint8_t ipproto, AppProto alproto, void *alstate); -DetectEngineState *AppLayerParserGetTxDetectState(uint8_t ipproto, AppProto alproto, void *tx); -int AppLayerParserSetTxDetectState(uint8_t ipproto, AppProto alproto, void *alstate, void *tx, DetectEngineState *s); - -/***** General *****/ - -int AppLayerParserParse(AppLayerParserThreadCtx *tctx, Flow *f, AppProto alproto, - uint8_t flags, uint8_t *input, uint32_t input_len); -void AppLayerParserSetEOF(AppLayerParserState *pstate); -int AppLayerParserHasDecoderEvents(uint8_t ipproto, AppProto alproto, void *alstate, AppLayerParserState *pstate, - uint8_t flags); -int AppLayerParserProtocolIsTxAware(uint8_t ipproto, AppProto alproto); -int AppLayerParserProtocolIsTxEventAware(uint8_t ipproto, AppProto alproto); -int AppLayerParserProtocolSupportsTxs(uint8_t ipproto, AppProto alproto); -int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto); -void AppLayerParserTriggerRawStreamReassembly(Flow *f); - -/***** Cleanup *****/ - -void AppLayerParserStateCleanup(uint8_t ipproto, AppProto alproto, void *alstate, AppLayerParserState *pstate); - -void AppLayerParserRegisterProtocolParsers(void); - - -void AppLayerParserStateSetFlag(AppLayerParserState *pstate, uint8_t flag); -int AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint8_t flag); - -void AppLayerParserStreamTruncated(uint8_t ipproto, AppProto alproto, void *alstate, - uint8_t direction); - - - -AppLayerParserState *AppLayerParserStateAlloc(void); -void AppLayerParserStateFree(AppLayerParserState *pstate); - - - -#ifdef DEBUG -void AppLayerParserStatePrintDetails(AppLayerParserState *pstate); -#endif - -/***** Unittests *****/ - -#ifdef UNITTESTS -void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, - void (*RegisterUnittests)(void)); -void AppLayerParserRegisterUnittests(void); -void AppLayerParserBackupParserTable(void); -void AppLayerParserRestoreParserTable(void); -#endif - -#endif /* __APP_LAYER_PARSER_H__ */ diff --git a/framework/src/suricata/src/app-layer-protos.c b/framework/src/suricata/src/app-layer-protos.c deleted file mode 100644 index e8875643..00000000 --- a/framework/src/suricata/src/app-layer-protos.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "app-layer-protos.h" - -#define CASE_CODE(E) case E: return #E - -const char *AppProtoToString(AppProto alproto) -{ - const char *proto_name = NULL; - enum AppProtoEnum proto = alproto; - - switch (proto) { - case ALPROTO_HTTP: - proto_name = "http"; - break; - case ALPROTO_FTP: - proto_name = "ftp"; - break; - case ALPROTO_SMTP: - proto_name = "smtp"; - break; - case ALPROTO_TLS: - proto_name = "tls"; - break; - case ALPROTO_SSH: - proto_name = "ssh"; - break; - case ALPROTO_IMAP: - proto_name = "imap"; - break; - case ALPROTO_MSN: - proto_name = "msn"; - break; - case ALPROTO_JABBER: - proto_name = "jabber"; - break; - case ALPROTO_SMB: - proto_name = "smb"; - break; - case ALPROTO_SMB2: - proto_name = "smb2"; - break; - case ALPROTO_DCERPC: - proto_name = "dcerpc"; - break; - case ALPROTO_IRC: - proto_name = "irc"; - break; - case ALPROTO_DNS: - proto_name = "dns"; - break; - case ALPROTO_MODBUS: - proto_name = "modbus"; - break; - case ALPROTO_TEMPLATE: - proto_name = "template"; - break; - case ALPROTO_FAILED: -#ifdef UNITTESTS - case ALPROTO_TEST: -#endif - case ALPROTO_MAX: - case ALPROTO_UNKNOWN: - break; - } - - return proto_name; -} diff --git a/framework/src/suricata/src/app-layer-protos.h b/framework/src/suricata/src/app-layer-protos.h deleted file mode 100644 index aff90e9b..00000000 --- a/framework/src/suricata/src/app-layer-protos.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#ifndef __APP_LAYER_PROTOS_H__ -#define __APP_LAYER_PROTOS_H__ - -enum AppProtoEnum { - ALPROTO_UNKNOWN = 0, - ALPROTO_HTTP, - ALPROTO_FTP, - ALPROTO_SMTP, - ALPROTO_TLS, /* SSLv2, SSLv3 & TLSv1 */ - ALPROTO_SSH, - ALPROTO_IMAP, - ALPROTO_MSN, - ALPROTO_JABBER, - ALPROTO_SMB, - ALPROTO_SMB2, - ALPROTO_DCERPC, - ALPROTO_IRC, - - ALPROTO_DNS, - ALPROTO_MODBUS, - ALPROTO_TEMPLATE, - - /* used by the probing parser when alproto detection fails - * permanently for that particular stream */ - ALPROTO_FAILED, -#ifdef UNITTESTS - ALPROTO_TEST, -#endif /* UNITESTS */ - /* keep last */ - ALPROTO_MAX, -}; - -/* not using the enum as that is a unsigned int, so 4 bytes */ -typedef uint16_t AppProto; - -/** - * \brief Maps the ALPROTO_*, to its string equivalent. - * - * \param alproto App layer protocol id. - * - * \retval String equivalent for the alproto. - */ -const char *AppProtoToString(AppProto alproto); - -#endif /* __APP_LAYER_PROTOS_H__ */ diff --git a/framework/src/suricata/src/app-layer-smb.c b/framework/src/suricata/src/app-layer-smb.c deleted file mode 100644 index 4d7aa845..00000000 --- a/framework/src/suricata/src/app-layer-smb.c +++ /dev/null @@ -1,2717 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Kirby Kuehl - * - * \brief SMBv1 parser/decoder - */ - -#include "suricata-common.h" - -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" -#include "util-debug.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer.h" -#include "app-layer-detect-proto.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" - -#include "util-spm.h" -#include "util-unittest.h" -#include "util-memcmp.h" - -#include "app-layer-smb.h" - -enum { - SMB_FIELD_NONE = 0, - SMB_PARSE_NBSS_HEADER, - SMB_PARSE_SMB_HEADER, - SMB_PARSE_GET_WORDCOUNT, - SMB_PARSE_WORDCOUNT, - SMB_PARSE_GET_BYTECOUNT, - SMB_PARSE_BYTECOUNT, - /* must be last */ - SMB_FIELD_MAX, -}; - -/** - * \brief SMB Write AndX Request Parsing - */ -/* For WriteAndX we need to get writeandxdataoffset */ -static uint32_t SMBParseWriteAndX(Flow *f, void *smb_state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint8_t *p = input; - - switch (sstate->andx.andxbytesprocessed) { - case 0: - sstate->andx.paddingparsed = 0; - if (input_len >= 28) { - sstate->andx.andxcommand = *p; - sstate->andx.andxoffset = *(p + 2); - sstate->andx.andxoffset |= *(p + 3) << 8; - sstate->andx.datalengthhigh = *(p + 18); - sstate->andx.datalengthhigh |= *(p + 19) << 8; - sstate->andx.datalength = *(p + 20); - sstate->andx.datalength |= *(p + 21) << 8; - sstate->andx.dataoffset = *(p + 22); - sstate->andx.dataoffset |= *(p + 23) << 8; - sstate->andx.dataoffset |= (uint64_t) *(p + 24) << 56; - sstate->andx.dataoffset |= (uint64_t) *(p + 25) << 48; - sstate->andx.dataoffset |= (uint64_t) *(p + 26) << 40; - sstate->andx.dataoffset |= (uint64_t) *(p + 27) << 32; - sstate->bytesprocessed += 28; - SCReturnUInt(28U); - } else { - sstate->andx.andxcommand = *(p++); - if (!(--input_len)) - break; - } - /* fall through */ - case 1: - p++; // Reserved - if (!(--input_len)) - break; - /* fall through */ - case 2: - sstate->andx.andxoffset = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 3: - sstate->andx.andxoffset |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 4: - // SMB_COM_WRITE_ANDX Fid 1 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 5: - // SMB_COM_WRITE_ANDX Fid 2 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 6: - // SMB_COM_WRITE_ANDX Offset 1 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 7: - // SMB_COM_WRITE_ANDX Offset 2 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 8: - // SMB_COM_WRITE_ANDX Offset 3 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 9: - // SMB_COM_WRITE_ANDX Offset 4 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 10: - // SMB_COM_WRITE_ANDX Reserved 1 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 11: - // SMB_COM_WRITE_ANDX Reserved 2 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 12: - // SMB_COM_WRITE_ANDX Reserved 3 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 13: - // SMB_COM_WRITE_ANDX Reserved 4 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 14: - // SMB_COM_WRITE_ANDX WriteMode 1 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 15: - // SMB_COM_WRITE_ANDX WriteMode 2 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 16: - // SMB_COM_WRITE_ANDX BytesRemaining 1 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 17: - // SMB_COM_WRITE_ANDX BytesRemaining 2 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 18: - // DataLengthHigh 1 - sstate->andx.datalengthhigh = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 19: - // DataLengthHigh 2 - sstate->andx.datalengthhigh |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 20: - // DataLength 1 - sstate->andx.datalength = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 21: - // DataLength 2 - sstate->andx.datalength |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 22: - sstate->andx.dataoffset = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 23: - sstate->andx.dataoffset |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 24: - sstate->andx.dataoffset |= (uint64_t) *(p++) << 56; - if (!(--input_len)) - break; - /* fall through */ - case 25: - sstate->andx.dataoffset |= (uint64_t) *(p++) << 48; - if (!(--input_len)) - break; - /* fall through */ - case 26: - sstate->andx.dataoffset |= (uint64_t) *(p++) << 40; - if (!(--input_len)) - break; - /* fall through */ - case 27: - sstate->andx.dataoffset |= (uint64_t) *(p++) << 32; - --input_len; - break; - /* fall through */ - default: - sstate->bytesprocessed++; - SCReturnUInt(1); - break; - } - sstate->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -/** - * \brief SMB Read AndX Response Parsing - */ -static uint32_t SMBParseReadAndX(Flow *f, void *smb_state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint8_t *p = input; - - switch (sstate->andx.andxbytesprocessed) { - case 0: - sstate->andx.paddingparsed = 0; - if (input_len >= 24) { - sstate->andx.andxcommand = *p; - sstate->andx.andxoffset = *(p + 2); - sstate->andx.andxoffset |= *(p + 3) << 8; - sstate->andx.datalength = *(p + 10); - sstate->andx.datalength |= *(p + 11) << 8; - sstate->andx.dataoffset = *(p + 12); - sstate->andx.dataoffset |= *(p + 13) << 8; - sstate->andx.datalength |= (uint64_t) *(p + 14) << 32; - sstate->andx.datalength |= (uint64_t) *(p + 15) << 40; - sstate->andx.datalength |= (uint64_t) *(p + 16) << 48; - sstate->andx.datalength |= (uint64_t) *(p + 17) << 56; - sstate->bytesprocessed += 24; - SCReturnUInt(24U); - } else { - sstate->andx.andxcommand = *(p++); - if (!(--input_len)) - break; - } - /* fall through */ - case 1: - p++; // Reserved - if (!(--input_len)) - break; - /* fall through */ - case 2: - sstate->andx.andxoffset |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 3: - sstate->andx.andxoffset |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 4: - // SMB_COM_READ_ANDX Remaining Reserved must be 0xff - p++; - if (!(--input_len)) - break; - /* fall through */ - case 5: - // SMB_COM_READ_ANDX Remaining Reserved must be 0xff - p++; - if (!(--input_len)) - break; - /* fall through */ - case 6: - // SMB_COM_READ_ANDX DataCompactionMode 1 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 7: - // SMB_COM_READ_ANDX DataCompactionMode 1 - p++; - if (!(--input_len)) - break; - /* fall through */ - case 8: - // SMB_COM_READ_ANDX Reserved - p++; - if (!(--input_len)) - break; - /* fall through */ - case 9: - // SMB_COM_READ_ANDX Reserved - p++; - if (!(--input_len)) - break; - /* fall through */ - case 10: - sstate->andx.datalength = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 11: - sstate->andx.datalength |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 12: - sstate->andx.dataoffset = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 13: - sstate->andx.dataoffset |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 14: - sstate->andx.datalength |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 15: - sstate->andx.datalength |= *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 16: - // SMB_COM_READ_ANDX Reserved - p++; - if (!(--input_len)) - break; - /* fall through */ - case 17: - // SMB_COM_READ_ANDX Reserved - p++; - if (!(--input_len)) - break; - /* fall through */ - case 18: - // SMB_COM_READ_ANDX Reserved - p++; - --input_len; - break; - default: - sstate->bytesprocessed++; - SCReturnUInt(1); - break; - - } - sstate->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -static uint32_t SMBParseTransact(Flow *f, void *smb_state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint8_t *p = input; - - switch (sstate->andx.andxbytesprocessed) { - case 0: - sstate->andx.paddingparsed = 0; - if (input_len >= sstate->wordcount.wordcount) { - sstate->andx.datalength = *(p + 22); - sstate->andx.datalength |= *(p + 23) << 8; - sstate->andx.dataoffset = *(p + 24); - sstate->andx.dataoffset |= *(p + 25) << 8; - sstate->andx.datalength |= (uint64_t) *(p + 14) << 56; - sstate->andx.datalength |= (uint64_t) *(p + 15) << 48; - sstate->andx.datalength |= (uint64_t) *(p + 16) << 40; - sstate->andx.datalength |= (uint64_t) *(p + 17) << 32; - sstate->bytesprocessed += sstate->wordcount.wordcount; - sstate->andx.andxbytesprocessed += sstate->wordcount.wordcount; - SCReturnUInt(sstate->wordcount.wordcount); - } else { - /* total parameter count 1 */ - p++; - if (!(--input_len)) - break; - } - /* fall through */ - case 1: - /* total parameter count 2 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 2: - /* total data count 1 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 3: - /* total data count 2 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 4: - /* max parameter count 1 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 5: - /* max parameter count 2 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 6: - /* max data count 1 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 7: - /* max data count 2 */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 8: - /* max setup count */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 9: - /* Reserved */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 10: - /* Flags */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 11: - /* Flags */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 12: - /* Timeout */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 13: - /* Timeout */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 14: - /* Timeout */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 15: - /* Timeout */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 16: - /* Reserved */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 17: - /* Reserved */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 18: - /* Parameter Count */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 19: - /* Parameter Count */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 20: - /* Parameter Offset */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 21: - /* Parameter Offset */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 22: - /* Data Count */ - sstate->andx.datalength = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 23: - /* Data Count */ - sstate->andx.datalength |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 24: - /* Data Offset */ - sstate->andx.dataoffset = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 25: - /* Data Offset */ - sstate->andx.dataoffset |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 26: - /* Setup Count */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 27: - /* Reserved */ - p++; - if (!(--input_len)) - break; - /* fall through */ - case 28: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 29: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 30: - p++; - if (!(--input_len)) - break; - /* fall through */ - case 31: - p++; - --input_len; - break; - default: - SCLogDebug("SMB_COM_TRANSACTION AndX bytes processed is greater than 31 %u", sstate->andx.andxbytesprocessed); - sstate->bytesprocessed++; - sstate->andx.andxbytesprocessed++; - SCReturnUInt(1); - break; - } - sstate->bytesprocessed += (p - input); - sstate->andx.andxbytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -/** - * Handle variable length padding for WriteAndX and ReadAndX - */ -static uint32_t PaddingParser(void *smb_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint8_t *p = input; - - /* Check for validity of dataoffset */ - if ((uint64_t)(sstate->bytesprocessed - NBSS_HDR_LEN) > sstate->andx.dataoffset) { - sstate->andx.paddingparsed = 1; - SCReturnUInt((uint32_t)(p - input)); - } - while (((uint64_t)(sstate->bytesprocessed - NBSS_HDR_LEN) + (p - input)) - < sstate->andx.dataoffset && sstate->bytecount.bytecountleft-- - && input_len--) { - SCLogDebug("0x%02x ", *p); - p++; - } - if (((uint64_t)(sstate->bytesprocessed - NBSS_HDR_LEN) + (p - input)) - == sstate->andx.dataoffset) { - sstate->andx.paddingparsed = 1; - } - sstate->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -/** - * \brief Parse WriteAndX and ReadAndX Data - * \retval -1 f DCERPCParser does not validate - * \retval Number of bytes processed - */ -static int32_t DataParser(void *smb_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - int32_t parsed = 0; - - if (sstate->andx.paddingparsed) { - parsed = DCERPCParser(&sstate->dcerpc, input, input_len); - if (parsed == -1 || parsed > sstate->bytecount.bytecountleft || parsed > (int32_t)input_len) { - SCReturnInt(-1); - } else { - sstate->dcerpc_present = 1; - sstate->bytesprocessed += parsed; - sstate->bytecount.bytecountleft -= parsed; - input_len -= parsed; - } - } - SCReturnInt(parsed); -} - -/** - * \brief Obtain SMB WordCount which is 2 times the value. - * Reset bytecount.bytecountbytes to 0. - * Determine if this is an SMB AndX Command - */ -static uint32_t SMBGetWordCount(Flow *f, void *smb_state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - if (input_len > 0) { - SMBState *sstate = (SMBState *) smb_state; - sstate->wordcount.wordcount = *(input) * 2; - sstate->wordcount.wordcountleft = sstate->wordcount.wordcount; - sstate->bytesprocessed++; - sstate->bytecount.bytecountbytes = 0; - sstate->andx.isandx = isAndX(sstate); - SCLogDebug("Wordcount (%u):", sstate->wordcount.wordcount); - SCReturnUInt(1U); - } - - SCReturnUInt(0); -} - -/* - * Obtain SMB Bytecount. Handle the corner obfuscation case where a packet boundary - * is after the first bytecount byte. - */ - -static uint32_t SMBGetByteCount(Flow *f, void *smb_state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint8_t *p = input; - - if (input_len && sstate->bytesprocessed == NBSS_HDR_LEN + SMB_HDR_LEN + 1 - + sstate->wordcount.wordcount) { - sstate->bytecount.bytecount = *(p++); - sstate->bytesprocessed++; - --input_len; - } - - if (input_len && sstate->bytesprocessed == NBSS_HDR_LEN + SMB_HDR_LEN + 2 - + sstate->wordcount.wordcount) { - sstate->bytecount.bytecount |= *(p++) << 8; - sstate->bytecount.bytecountleft = sstate->bytecount.bytecount; - sstate->bytesprocessed++; - SCLogDebug("Bytecount %u", sstate->bytecount.bytecount); - --input_len; - } - - SCReturnUInt((uint32_t)(p - input)); -} - -/** - * \brief SMBParseWordCount parses the SMB Wordcount portion of the SMB Transaction. - * until sstate->wordcount.wordcount bytes are parsed. - */ -static uint32_t SMBParseWordCount(Flow *f, void *smb_state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint8_t *p = input; - uint32_t retval = 0; - - if ((sstate->smb.flags & SMB_FLAGS_SERVER_TO_REDIR) && sstate->smb.command - == SMB_COM_READ_ANDX) { - retval = SMBParseReadAndX(f, sstate, pstate, input, input_len); - if (retval <= sstate->wordcount.wordcountleft) { - sstate->wordcount.wordcountleft -= retval; - SCLogDebug("SMB_COM_READ_ANDX returned %d - %u bytes at offset %"PRIu64"", retval, sstate->andx.datalength, sstate->andx.dataoffset); - SCReturnUInt(retval); - } else { - SCReturnUInt(0U); - } - - } else if (((sstate->smb.flags & SMB_FLAGS_SERVER_TO_REDIR) == 0) - && sstate->smb.command == SMB_COM_WRITE_ANDX) { - retval = SMBParseWriteAndX(f, sstate, pstate, input, input_len); - if (retval <= sstate->wordcount.wordcountleft) { - sstate->wordcount.wordcountleft -= retval; - SCLogDebug("SMB_COM_WRITE_ANDX returned %d - %u bytes at offset %"PRIu64"", retval, sstate->andx.datalength, sstate->andx.dataoffset); - SCReturnUInt(retval); - } else { - SCReturnUInt(0U); - } - - } else if (sstate->smb.command == SMB_COM_TRANSACTION) { - retval = SMBParseTransact(f, sstate, pstate, input, input_len); - if (retval <= sstate->wordcount.wordcountleft) { - sstate->wordcount.wordcountleft -= retval; - SCLogDebug("SMB_COM_TRANSACTION returned %d - %u bytes at offset %"PRIu64"", retval, sstate->andx.datalength, sstate->andx.dataoffset); - SCReturnUInt(retval); - } else { - SCReturnUInt(0U); - } - - } else { /* Generic WordCount Handler */ - while (sstate->wordcount.wordcountleft-- && input_len--) { - SCLogDebug("0x%02x wordcount %u/%u input_len %u", *p, - sstate->wordcount.wordcountleft, - sstate->wordcount.wordcount, input_len); - p++; - } - sstate->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); - } -} - -/** - * \brief SMBParseByteCount parses the SMB ByteCount portion of the SMB Transaction. - * until sstate->bytecount.bytecount bytes are parsed. - */ -static uint32_t SMBParseByteCount(Flow *f, void *smb_state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint8_t *p = input; - uint32_t ures = 0; /* unsigned */ - int32_t sres = 0; /* signed */ - uint32_t parsed = 0; - - if (((sstate->smb.flags & SMB_FLAGS_SERVER_TO_REDIR) && - sstate->smb.command == SMB_COM_READ_ANDX) || - (((sstate->smb.flags & SMB_FLAGS_SERVER_TO_REDIR) == 0) - && sstate->smb.command == SMB_COM_WRITE_ANDX) || - (sstate->smb.command == SMB_COM_TRANSACTION)) - { - if (sstate->andx.paddingparsed == 0) { - ures = PaddingParser(sstate, pstate, input + parsed, input_len); - if (ures <= input_len) { - parsed += ures; - input_len -= ures; - } else { - SCReturnUInt(0U); - } - } - - if (sstate->andx.datalength && input_len) { - /* Uncomment the next line to help debug DCERPC over SMB */ - //hexdump(f, input + parsed, input_len); - sres = DataParser(sstate, pstate, input + parsed, input_len); - if (sres != -1 && sres <= (int32_t)input_len) { - parsed += (uint32_t)sres; - input_len -= (uint32_t)sres; - } else { /* Did not Validate as DCERPC over SMB */ - while (sstate->bytecount.bytecountleft-- && input_len--) { - SCLogDebug("0x%02x bytecount %"PRIu16"/%"PRIu16" input_len %"PRIu32, *p, - sstate->bytecount.bytecountleft, - sstate->bytecount.bytecount, input_len); - p++; - } - sstate->bytesprocessed += (p - input); - SCReturnUInt((p - input)); - } - } - SCReturnUInt(ures); - } - - while (sstate->bytecount.bytecountleft-- && input_len--) { - SCLogDebug("0x%02x bytecount %u/%u input_len %u", *p, - sstate->bytecount.bytecountleft, - sstate->bytecount.bytecount, input_len); - p++; - } - sstate->bytesprocessed += (p - input); - - SCReturnUInt((p - input)); -} - -/** - * \brief Parse a NBSS header. - * - * \retval 4 parsing of the header is done - * \retval 3 parsing partially done - * \retval 2 parsing partially done - * \retval 1 parsing partially done - * \retval 0 no input or already done - */ -static uint32_t NBSSParseHeader(Flow *f, void *smb_state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint8_t *p = input; - - if (input_len > 0 && sstate->bytesprocessed < (NBSS_HDR_LEN - 1)) { - switch (sstate->bytesprocessed) { - case 0: - /* Initialize */ - sstate->andx.andxcommand = SMB_NO_SECONDARY_ANDX_COMMAND; - sstate->andx.maxchainedandx = 5; - - /* fast track for having all bytes (common case) */ - if (input_len >= NBSS_HDR_LEN) { - sstate->nbss.type = *p; - sstate->nbss.length = (*(p + 1) & 0x01) << 16; - sstate->nbss.length |= *(p + 2) << 8; - sstate->nbss.length |= *(p + 3); - sstate->bytesprocessed += NBSS_HDR_LEN; - SCReturnUInt(4U); - } else { - sstate->nbss.type = *(p++); - if (!(--input_len)) - break; - } - /* fall through */ - case 1: - sstate->nbss.length = (*(p++) & 0x01) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 2: - sstate->nbss.length |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 3: - sstate->nbss.length |= *(p++); - --input_len; - break; - } - sstate->bytesprocessed += (p - input); - } - - SCReturnUInt((uint32_t)(p - input)); -} - -/** - * \brief parse and validate the 32 byte SMB Header - * - * \retval 32 parsing done - * \retval >0<32 parsing in progress - * \retval 0 no input or already fully parsed - * \retval -1 error - */ -static int SMBParseHeader(Flow *f, void *smb_state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint8_t *p = input; - - if (input_len > 0) { - switch (sstate->bytesprocessed) { - case 4: - // fallthrough - /* above statement to prevent coverity FPs from the switch - * fall through */ - if (input_len >= SMB_HDR_LEN) { - if (SCMemcmp(p, "\xff\x53\x4d\x42", 4) != 0) { - SCLogDebug("SMB Header did not validate"); - SCReturnInt(-1); - } - sstate->smb.command = *(p + 4); - sstate->smb.status = *(p + 5) << 24; - sstate->smb.status |= *(p + 6) << 16; - sstate->smb.status |= *(p + 7) << 8; - sstate->smb.status |= *(p + 8); - sstate->smb.flags = *(p + 9); - sstate->smb.flags2 = *(p + 10) << 8; - sstate->smb.flags2 |= *(p + 11); - sstate->smb.pidhigh = *(p + 12) << 8; - sstate->smb.pidhigh |= *(p + 13); - sstate->smb.securitysignature = (uint64_t) *(p + 14) << 56; - sstate->smb.securitysignature |= (uint64_t) *(p + 15) << 48; - sstate->smb.securitysignature |= (uint64_t) *(p + 16) << 40; - sstate->smb.securitysignature |= (uint64_t) *(p + 17) << 32; - sstate->smb.securitysignature |= (uint64_t) *(p + 18) << 24; - sstate->smb.securitysignature |= (uint64_t) *(p + 19) << 16; - sstate->smb.securitysignature |= (uint64_t) *(p + 20) << 8; - sstate->smb.securitysignature |= (uint64_t) *(p + 21); - sstate->smb.tid = *(p + 24) << 8; - sstate->smb.tid |= *(p + 25); - sstate->smb.pid = *(p + 26) << 8; - sstate->smb.pid |= *(p + 27); - sstate->smb.uid = *(p + 28) << 8; - sstate->smb.uid |= *(p + 29); - sstate->smb.mid = *(p + 30) << 8; - sstate->smb.mid |= *(p + 31); - sstate->bytesprocessed += SMB_HDR_LEN; - SCReturnInt(32); - break; - } else { - if (*(p++) != 0xff) { - SCLogDebug("SMB Header did not validate"); - SCReturnInt(-1); - } - if (!(--input_len)) - break; - /* We fall through to the next case if we still have input. - * Same applies for other cases as well */ - } - /* fall through */ - case 5: - if (*(p++) != 'S') { - SCLogDebug("SMB Header did not validate"); - SCReturnInt(-1); - } - if (!(--input_len)) - break; - /* fall through */ - case 6: - if (*(p++) != 'M') { - SCLogDebug("SMB Header did not validate"); - SCReturnInt(-1); - } - if (!(--input_len)) - break; - /* fall through */ - case 7: - if (*(p++) != 'B') { - SCLogDebug("SMB Header did not validate"); - SCReturnInt(-1); - } - if (!(--input_len)) - break; - /* fall through */ - case 8: - sstate->smb.command = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 9: - sstate->smb.status = *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 10: - sstate->smb.status |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 11: - sstate->smb.status |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 12: - sstate->smb.status |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 13: - sstate->smb.flags = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 14: - sstate->smb.flags2 = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 15: - sstate->smb.flags2 |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 16: - sstate->smb.pidhigh = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 17: - sstate->smb.pidhigh |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 18: - sstate->smb.securitysignature = (uint64_t) *(p++) << 56; - if (!(--input_len)) - break; - /* fall through */ - case 19: - sstate->smb.securitysignature |= (uint64_t) *(p++) << 48; - if (!(--input_len)) - break; - /* fall through */ - case 20: - sstate->smb.securitysignature |= (uint64_t) *(p++) << 40; - if (!(--input_len)) - break; - /* fall through */ - case 21: - sstate->smb.securitysignature |= (uint64_t) *(p++) << 32; - if (!(--input_len)) - break; - /* fall through */ - case 22: - sstate->smb.securitysignature |= (uint64_t) *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 23: - sstate->smb.securitysignature |= (uint64_t) *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 24: - sstate->smb.securitysignature |= (uint64_t) *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 25: - sstate->smb.securitysignature |= (uint64_t) *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 26: - p++; // UNUSED - if (!(--input_len)) - break; - /* fall through */ - case 27: - p++; // UNUSED - if (!(--input_len)) - break; - /* fall through */ - case 28: - sstate->smb.tid = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 29: - sstate->smb.tid |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 30: - sstate->smb.pid = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 31: - sstate->smb.pid |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 32: - sstate->smb.uid = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 33: - sstate->smb.uid |= *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 34: - sstate->smb.mid = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 35: - sstate->smb.mid |= *(p++); - --input_len; - break; - /* fall through */ - } - } - sstate->bytesprocessed += (p - input); - - SCReturnInt((p - input)); -} - -static int SMBParse(Flow *f, void *smb_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data, uint8_t dir) -{ - SCEnter(); - - SMBState *sstate = (SMBState *) smb_state; - uint64_t retval = 0; - uint64_t parsed = 0; - int hdrretval = 0; - int counter = 0; - - if (pstate == NULL) { - SCLogDebug("pstate == NULL"); - SCReturnInt(0); - } - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } - - if (sstate->bytesprocessed != 0 && sstate->data_needed_for_dir != dir) { - SCReturnInt(-1); - } - - while (input_len) { - /* till we clear corner cases */ - if (counter++ == 30) { - SCLogDebug("Somehow seem to be stuck inside the smb " - "parser for quite sometime. Let's get out of here."); - sstate->bytesprocessed = 0; - SCReturnInt(0); - } - - while (input_len && sstate->bytesprocessed < NBSS_HDR_LEN) { - retval = NBSSParseHeader(f, smb_state, pstate, input + parsed, - input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - SCLogDebug("[1] NBSS Header (%u/%u) Type 0x%02x Length 0x%04x " - "parsed %"PRIu64" input_len %u", - sstate->bytesprocessed, NBSS_HDR_LEN, sstate->nbss.type, - sstate->nbss.length, parsed, input_len); - } else if (input_len) { - SCLogDebug("Error parsing NBSS Header"); - sstate->bytesprocessed = 0; - SCReturnInt(0); - } - } - - switch (sstate->nbss.type) { - case NBSS_SESSION_MESSAGE: - while (input_len && - (sstate->bytesprocessed >= NBSS_HDR_LEN && - sstate->bytesprocessed < NBSS_HDR_LEN + SMB_HDR_LEN)) { - /* inside while */ - hdrretval = SMBParseHeader(f, smb_state, pstate, input + parsed, - input_len); - if (hdrretval == -1 || hdrretval > (int32_t)input_len) { - SCLogDebug("Error parsing SMB Header"); - sstate->bytesprocessed = 0; - SCReturnInt(0); - } else { - parsed += hdrretval; - input_len -= hdrretval; - SCLogDebug("[2] SMB Header (%u/%u) Command 0x%02x " - "parsed %"PRIu64" input_len %u", - sstate->bytesprocessed, NBSS_HDR_LEN + SMB_HDR_LEN, - sstate->smb.command, parsed, input_len); - } - } /* while */ - - do { - if (input_len && - (sstate->bytesprocessed == NBSS_HDR_LEN + SMB_HDR_LEN)) { - /* inside if */ - retval = SMBGetWordCount(f, smb_state, pstate, input + parsed, - input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - } else if (input_len) { - SCLogDebug("Error parsing SMB Word Count"); - sstate->bytesprocessed = 0; - SCReturnInt(0); - } - SCLogDebug("[3] WordCount (%u/%u) WordCount %u parsed " - "%"PRIu64" input_len %u", - sstate->bytesprocessed, - NBSS_HDR_LEN + SMB_HDR_LEN + 1, - sstate->wordcount.wordcount, - parsed, input_len); - } /* if (input_len && ..) */ - - while (input_len && - (sstate->bytesprocessed >= NBSS_HDR_LEN + SMB_HDR_LEN + 1 && - sstate->bytesprocessed < (NBSS_HDR_LEN + SMB_HDR_LEN + 1 + - sstate->wordcount.wordcount))) { - /* inside while */ - retval = SMBParseWordCount(f, smb_state, pstate, - input + parsed, input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - } else if (input_len) { - SCLogDebug("Error parsing SMB Word Count Data retval " - "%"PRIu64" input_len %u", retval, input_len); - sstate->bytesprocessed = 0; - SCReturnInt(0); - } - SCLogDebug("[4] Parsing WordCount (%u/%u) WordCount %u " - "parsed %"PRIu64" input_len %u", - sstate->bytesprocessed, - NBSS_HDR_LEN + SMB_HDR_LEN + 1 + - sstate->wordcount.wordcount, - sstate->wordcount.wordcount, - parsed, input_len); - } /* while (input_len && ..) */ - - while (input_len && - (sstate->bytesprocessed >= (NBSS_HDR_LEN + SMB_HDR_LEN + - 1 + sstate->wordcount.wordcount) && - sstate->bytesprocessed < (NBSS_HDR_LEN + SMB_HDR_LEN + 3 - + sstate->wordcount.wordcount))) { - /* inside while */ - retval = SMBGetByteCount(f, smb_state, pstate, input + parsed, - input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - } else if (input_len) { - SCLogDebug("Error parsing SMB Byte Count"); - sstate->bytesprocessed = 0; - SCReturnInt(0); - } - SCLogDebug("[5] ByteCount (%u/%u) ByteCount %u parsed " - "%"PRIu64" input_len %u", - sstate->bytesprocessed, - NBSS_HDR_LEN + SMB_HDR_LEN + 3, - sstate->bytecount.bytecount, - parsed, input_len); - - if (sstate->bytecount.bytecount == 0) { - sstate->bytesprocessed = 0; - input_len = 0; - } - } /* while (input_len && ..) */ - - while (input_len && - (sstate->bytesprocessed >= (NBSS_HDR_LEN + SMB_HDR_LEN + - 3 + sstate->wordcount.wordcount)) && - (sstate->bytesprocessed < (NBSS_HDR_LEN + SMB_HDR_LEN + 3 - + sstate->wordcount.wordcount - + sstate->bytecount.bytecount))) { - /* inside while */ - retval = SMBParseByteCount(f, smb_state, pstate, - input + parsed, input_len); - if (retval && retval <= input_len) { - parsed += retval; - input_len -= retval; - } else if (input_len) { - SCLogDebug("Error parsing SMB Byte Count Data"); - sstate->bytesprocessed = 0; - SCReturnInt(0); - } - SCLogDebug("[6] Parsing ByteCount (%u/%u) ByteCount %u " - "parsed %"PRIu64" input_len %u", - sstate->bytesprocessed, - NBSS_HDR_LEN + SMB_HDR_LEN + 1 + - sstate->wordcount.wordcount + 2 + - sstate->bytecount.bytecount, - sstate->bytecount.bytecount, parsed, input_len); - } /* while (input_len && ..) */ - - } while (sstate->andx.andxcommand != SMB_NO_SECONDARY_ANDX_COMMAND && - input_len && sstate->andx.maxchainedandx--); - - if (sstate->bytesprocessed >= sstate->nbss.length + NBSS_HDR_LEN || - sstate->andx.maxchainedandx == 0) { - /* inside if */ - sstate->bytesprocessed = 0; - sstate->transaction_id++; - input_len = 0; - } - break; - - case NBSS_SESSION_REQUEST: - case NBSS_POSITIVE_SESSION_RESPONSE: - case NBSS_NEGATIVE_SESSION_RESPONSE: - case NBSS_RETARGET_SESSION_RESPONSE: - case NBSS_SESSION_KEEP_ALIVE: - if (sstate->bytesprocessed < (sstate->nbss.length + NBSS_HDR_LEN)) { - if (input_len >= (sstate->nbss.length + NBSS_HDR_LEN - - sstate->bytesprocessed)) { - /* inside if */ - input_len -= (sstate->nbss.length + NBSS_HDR_LEN - - sstate->bytesprocessed); - parsed += (sstate->nbss.length + NBSS_HDR_LEN - - sstate->bytesprocessed); - sstate->bytesprocessed = 0; - } else { - sstate->bytesprocessed += input_len; - input_len = 0; - } - } else { - sstate->bytesprocessed = 0; - } - break; - - default: - sstate->bytesprocessed = 0; - break; - } /* switch */ - - } /* while (input_len) */ - - sstate->data_needed_for_dir = dir; - SCReturnInt(1); -} - -static int SMBParseRequest(Flow *f, void *smb_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - return SMBParse(f, smb_state, pstate, input, input_len, local_data, 0); -} - -static int SMBParseResponse(Flow *f, void *smb_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - return SMBParse(f, smb_state, pstate, input, input_len, local_data, 1); -} - - -/** - * \brief determines if the SMB command is an ANDX command - * \retval 1 if smb command is an AndX command - * \retval 0 if smb command is not an AndX command - */ - -int isAndX(SMBState *smb_state) -{ - SCEnter(); - - switch (smb_state->smb.command) { - case SMB_NO_SECONDARY_ANDX_COMMAND: - case SMB_COM_LOCKING_ANDX: - case SMB_COM_OPEN_ANDX: - case SMB_COM_READ_ANDX: - case SMB_COM_WRITE_ANDX: - case SMB_COM_SESSION_SETUP_ANDX: - case SMB_COM_LOGOFF_ANDX: - case SMB_COM_TREE_CONNECT_ANDX: - case SMB_COM_NT_CREATE_ANDX: - smb_state->andx.andxbytesprocessed = 0; - SCReturnInt(1); - default: - SCReturnInt(0); - } -} - -/** \internal - * \brief Allocate a SMBState - * \retval s State, or NULL in case of error - */ -static void *SMBStateAlloc(void) -{ - SCEnter(); - - void *s = SCMalloc(sizeof(SMBState)); - if (unlikely(s == NULL)) { - SCReturnPtr(NULL, "void"); - } - - memset(s, 0, sizeof(SMBState)); - - SCReturnPtr(s, "void"); -} - -/** \internal - * \brief Free a SMBState - */ -static void SMBStateFree(void *s) -{ - SCEnter(); - SMBState *sstate = (SMBState *) s; - - DCERPCUuidEntry *item; - - while ((item = TAILQ_FIRST(&sstate->dcerpc.dcerpcbindbindack.uuid_list))) { - //printUUID("Free", item); - TAILQ_REMOVE(&sstate->dcerpc.dcerpcbindbindack.uuid_list, item, next); - SCFree(item); - } - if (sstate->dcerpc.dcerpcrequest.stub_data_buffer != NULL) { - SCFree(sstate->dcerpc.dcerpcrequest.stub_data_buffer); - sstate->dcerpc.dcerpcrequest.stub_data_buffer = NULL; - sstate->dcerpc.dcerpcrequest.stub_data_buffer_len = 0; - } - if (sstate->dcerpc.dcerpcresponse.stub_data_buffer != NULL) { - SCFree(sstate->dcerpc.dcerpcresponse.stub_data_buffer); - sstate->dcerpc.dcerpcresponse.stub_data_buffer = NULL; - sstate->dcerpc.dcerpcresponse.stub_data_buffer_len = 0; - } - - SCFree(s); - SCReturn; -} - -#define SMB_PROBING_PARSER_MIN_DEPTH 8 - -static uint16_t SMBProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset) -{ - int32_t len; - int32_t input_len = ilen; - - while (input_len >= SMB_PROBING_PARSER_MIN_DEPTH) { - switch (input[0]) { - case NBSS_SESSION_MESSAGE: - if (input[4] == 0xFF && input[5] == 'S' && input[6] == 'M' && - input[7] == 'B') { - return ALPROTO_SMB; - } - - /* fall through */ - case NBSS_SESSION_REQUEST: - case NBSS_POSITIVE_SESSION_RESPONSE: - case NBSS_NEGATIVE_SESSION_RESPONSE: - case NBSS_RETARGET_SESSION_RESPONSE: - case NBSS_SESSION_KEEP_ALIVE: - len = (input[1] & 0x01) << 16; - len |= input[2] << 8; - len |= input[3]; - break; - default: - /* -1 indicates a stream where the probing parser would be - * unable to find nbss, even if it exists. This should - * prevent the probing parser from beig invoked henceforth */ - return ALPROTO_FAILED; - } - - input_len -= 4; - if (len >= input_len) { - return ALPROTO_UNKNOWN; - } - - input_len -= len; - input += 4 + len; - } - - return ALPROTO_UNKNOWN; -} - -static int SMBRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB, - "|ff|SMB", 8, 4, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2, - "|fe|SMB", 8, 4, STREAM_TOSERVER) < 0) - { - return -1; - } - - return 0; -} - -void RegisterSMBParsers(void) -{ - char *proto_name = "smb"; - - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_SMB, proto_name); - if (SMBRegisterPatternsForProtocolDetection() < 0) - return; - - if (RunmodeIsUnittests()) { - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "139", - ALPROTO_SMB, - SMB_PROBING_PARSER_MIN_DEPTH, 0, - STREAM_TOSERVER, - SMBProbingParser); - } else { - AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP, - proto_name, ALPROTO_SMB, - SMB_PROBING_PARSER_MIN_DEPTH, 0, - SMBProbingParser); - } - - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_SMB, STREAM_TOSERVER); - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - proto_name); - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMB, STREAM_TOSERVER, SMBParseRequest); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMB, STREAM_TOCLIENT, SMBParseResponse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_SMB, SMBStateAlloc, SMBStateFree); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } - -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_SMB, SMBParserRegisterTests); -#endif - return; -} - -/* UNITTESTS */ -#ifdef UNITTESTS - -/** - * \test SMBParserTest01 tests the NBSS and SMB header decoding - */ -int SMBParserTest01(void) -{ - int result = 0; - Flow f; - uint8_t smbbuf[] = "\x00\x00\x00\x85" // NBSS - "\xff\x53\x4d\x42\x72\x00\x00\x00" // SMB - "\x00\x18\x53\xc8\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\xff\xfe\x00\x00\x00\x00" - "\x00" // WordCount - "\x62\x00" // ByteCount - "\x02\x50\x43\x20\x4e\x45\x54\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20" - "\x31\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00\x02\x57\x69\x6e\x64\x6f\x77\x73" - "\x20\x66\x6f\x72\x20\x57\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61\x00\x02\x4c" - "\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54" - "\x20\x4c\x4d\x20\x30\x2e\x31\x32\x00"; - - uint32_t smblen = sizeof(smbbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER|STREAM_EOF, smbbuf, smblen); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SMBState *smb_state = f.alstate; - if (smb_state == NULL) { - printf("no smb state: "); - goto end; - } - - if (smb_state->nbss.type != NBSS_SESSION_MESSAGE) { - printf("expected nbss type 0x%02x , got 0x%02x : ", NBSS_SESSION_MESSAGE, smb_state->nbss.type); - goto end; - } - - if (smb_state->nbss.length != 133) { - printf("expected nbss length 0x%02x , got 0x%02x : ", 133, smb_state->nbss.length); - goto end; - } - - if (smb_state->smb.command != SMB_COM_NEGOTIATE) { - printf("expected SMB command 0x%02x , got 0x%02x : ", SMB_COM_NEGOTIATE, smb_state->smb.command); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test SMBParserTest02 tests the NBSS, SMB, and DCERPC over SMB header decoding - */ -int SMBParserTest02(void) -{ - int result = 0; - Flow f; - uint8_t smbbuf[] = { - 0x00, 0x00, 0x00, 0x92, 0xff, 0x53, 0x4d, 0x42, - 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x64, 0x05, - 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x00, 0x48, - 0x00, 0x00, 0x04, 0xe0, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x4a, 0x00, 0x48, 0x00, 0x4a, 0x00, 0x02, - 0x00, 0x26, 0x00, 0x00, 0x40, 0x4f, 0x00, 0x5c, - 0x50, 0x49, 0x50, 0x45, 0x5c, 0x00, 0x05, 0x00, - 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd0, 0x16, - 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0xfd, - 0x2c, 0x34, 0x6c, 0x3c, 0xce, 0x11, 0xa8, 0x93, - 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, - 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, - 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 }; - - uint32_t smblen = sizeof(smbbuf); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER|STREAM_EOF, smbbuf, smblen); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SMBState *smb_state = f.alstate; - if (smb_state == NULL) { - printf("no smb state: "); - goto end; - } - - if (smb_state->nbss.type != NBSS_SESSION_MESSAGE) { - printf("expected nbss type 0x%02x , got 0x%02x : ", NBSS_SESSION_MESSAGE, smb_state->nbss.type); - goto end; - } - - if (smb_state->nbss.length != 146) { - printf("expected nbss length 0x%02x , got 0x%02x : ", 146, smb_state->nbss.length); - goto end; - } - - if (smb_state->smb.command != SMB_COM_TRANSACTION) { - printf("expected SMB command 0x%02x , got 0x%02x : ", SMB_COM_TRANSACTION, smb_state->smb.command); - goto end; - } - - printUUID("BIND", smb_state->dcerpc.dcerpcbindbindack.uuid_entry); - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -int SMBParserTest03(void) -{ - int result = 0; - Flow f; - uint8_t smbbuf1[] = { - 0x00, 0x00, 0x07, 0x57, 0xff, 0x53, 0x4d, 0x42, - 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7f, 0x13, - 0x01, 0x08, 0xc9, 0x29, 0x0e, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x40, 0x55, 0x01, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0x08, 0x00, 0x0e, 0x00, 0x00, - 0x00, 0x0e, 0x00, 0x49, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x07, 0xcc, 0x1b, 0x19, 0xb8, 0x75, - 0x2c, 0x85, 0x52, 0x39, 0x72, 0xfa, 0x9c, 0x5f, - 0x5a, 0xb7, 0x59, 0xa1, 0x83, 0xba, 0x87, 0xd3, - 0xc3, 0xbf, 0xf4, 0x5d, 0x08, 0x32, 0x22, 0x33, - 0x2e, 0x62, 0x46, 0x4d, 0x03, 0x48, 0x1f, 0xea, - 0x7c, 0x65, 0x3e, 0x71, 0xf8, 0xea, 0x20, 0x85, - 0x29, 0x6f, 0x3c, 0xf2, 0x19, 0xb5, 0x65, 0xb0, - 0xce, 0x06, 0xcc, 0x90, 0x86, 0x20, 0x77, 0xf5, - 0xa0, 0xbc, 0x45, 0x9d, 0x4e, 0x92, 0xb4, 0x24, - 0xc8, 0x58, 0x4a, 0xc3, 0x4e, 0xb8, 0x95, 0x8d, - 0x93, 0x0c, 0xce, 0xe0, 0xf9, 0x7d, 0x7e, 0xd3, - 0x46, 0x53, 0x32, 0x95, 0x7d, 0x22, 0x76, 0x0e, - 0x95, 0x23, 0x2e, 0xa6, 0x58, 0x1a, 0xb6, 0x74, - 0x54, 0x4f, 0x37, 0x5c, 0x60, 0x00, 0xb4, 0x55, - 0x5b, 0xda, 0xea, 0x2c, 0xf3, 0x9b, 0x91, 0x6f, - 0xa8, 0x20, 0xd3, 0x40, 0x0c, 0x7c, 0xc7, 0x85, - 0x8c, 0x44, 0x76, 0xbc, 0x22, 0x9d, 0xfd, 0x8e, - 0x21, 0x46, 0x05, 0x41, 0x73, 0x0c, 0x88, 0x62, - 0xdc, 0x62, 0xc1, 0xc8, 0x14, 0xbb, 0x96, 0x60, - 0x77, 0x6c, 0x5c, 0x31, 0x2a, 0xaa, 0x87, 0x69, - 0x99, 0xaa, 0x83, 0x5e, 0x71, 0x11, 0x2a, 0x85, - 0xca, 0x5d, 0xe1, 0x67, 0x4f, 0xa2, 0x3e, 0x4e, - 0x94, 0xe7, 0xa3, 0xe6, 0xa0, 0xdb, 0xc2, 0x05, - 0x01, 0x4f, 0xf5, 0xe9, 0xfc, 0xa2, 0x2a, 0x1c, - 0x63, 0x21, 0xd5, 0x27, 0x98, 0x86, 0x9c, 0x66, - 0x5e, 0xf1, 0x97, 0xb0, 0x86, 0x58, 0x5b, 0x94, - 0x51, 0xfd, 0xb9, 0x83, 0x4c, 0xc4, 0x0f, 0x5f, - 0xdd, 0xc8, 0xce, 0x43, 0xed, 0xe8, 0xae, 0xbc, - 0x52, 0x73, 0xf6, 0x0f, 0x0d, 0xb4, 0xd6, 0xa7, - 0xcf, 0xef, 0x0e, 0x72, 0x34, 0xff, 0x2b, 0x50, - 0x71, 0x2a, 0x98, 0xf0, 0x60, 0x58, 0xde, 0x1d, - 0x96, 0x50, 0xd8, 0xec, 0xeb, 0x40, 0xcb, 0x4c, - 0x3b, 0x2c, 0xee, 0x76, 0xd6, 0x97, 0x1c, 0x69, - 0x61, 0x89, 0xc1, 0x9b, 0x03, 0xda, 0x08, 0x0b, - 0x15, 0xba, 0xd3, 0x3d, 0x8c, 0xea, 0xf7, 0x17, - 0xc3, 0x77, 0xf8, 0x04, 0xca, 0x72, 0xed, 0xfe, - 0xd0, 0x02, 0x73, 0x1b, 0x71, 0x72, 0x17, 0x9f, - 0x14, 0x96, 0xe2, 0x5f, 0xae, 0x5b, 0x7d, 0x7f, - 0xc9, 0x72, 0x9f, 0xd5, 0x32, 0xf4, 0xf3, 0x39, - 0x89, 0x36, 0x00, 0x44, 0xa9, 0x18, 0x21, 0x4b, - 0x26, 0xf2, 0x5a, 0x2a, 0x80, 0xea, 0x6b, 0x3e, - 0x68, 0x27, 0xd0, 0xa0, 0x84, 0x81, 0xb5, 0xa6, - 0x3b, 0xd5, 0xdc, 0xdd, 0xd1, 0xd4, 0x5b, 0xad, - 0x80, 0x91, 0xf2, 0x30, 0x5e, 0x90, 0x17, 0x35, - 0x59, 0xad, 0x34, 0x65, 0x54, 0x04, 0x5a, 0x3c, - 0xe4, 0x68, 0xa7, 0x30, 0x06, 0x7a, 0x85, 0xe7, - 0xf4, 0x20, 0xe3, 0xd7, 0xa5, 0x8b, 0x60, 0xfe, - 0x51, 0xad, 0xda, 0xe2, 0xd1, 0x4f, 0xfb, 0x94, - 0xc9, 0xba, 0xa4, 0x09, 0x5c, 0xde, 0x78, 0xdc, - 0x78, 0x36, 0x96, 0x8b, 0xd6, 0x72, 0xc4, 0xa7, - 0x1c, 0xde, 0x45, 0x85, 0xdf, 0x84, 0xb1, 0x3f, - 0x2b, 0x3f, 0xfe, 0x56, 0x80, 0x8d, 0x26, 0x4a, - 0x39, 0x22, 0x1f, 0x10, 0x89, 0x2e, 0x4e, 0x87, - 0xf5, 0x9c, 0x0e, 0xd9, 0xdd, 0xb2, 0xc9, 0x9c, - 0x3f, 0xc5, 0xe3, 0xab, 0xdc, 0x85, 0x1c, 0xf9, - 0xda, 0xbb, 0x36, 0x9b, 0xe7, 0x21, 0x58, 0x44, - 0xee, 0xb3, 0xe7, 0x37, 0xd3, 0xc3, 0x76, 0x09, - 0x79, 0xe2, 0xf4, 0xf1, 0x27, 0x6b, 0x74, 0xc4, - 0x5f, 0x06, 0x76, 0x78, 0x56, 0xb9, 0x80, 0x7f, - 0x63, 0x53, 0xa2, 0xd1, 0xfc, 0xfb, 0x69, 0x38, - 0x0c, 0x13, 0x6e, 0x9e, 0xea, 0x79, 0xc9, 0x6d, - 0x45, 0x6b, 0xa3, 0xa8, 0x20, 0x21, 0x24, 0xff, - 0x0d, 0x8d, 0xd9, 0x0a, 0x9e, 0xf4, 0x3f, 0xf5, - 0x18, 0x39, 0xdd, 0x9f, 0xed, 0xd6, 0x2b, 0xb1, - 0x4b, 0x3f, 0x24, 0x7e, 0x11, 0x79, 0x37, 0x01, - 0x10, 0xe7, 0x34, 0x1d, 0x36, 0x5f, 0x26, 0x99, - 0x5a, 0x4d, 0xe9, 0x1a, 0x89, 0x24, 0xf8, 0xea, - 0xca, 0x16, 0x19, 0x6c, 0x3b, 0x8e, 0x44, 0x70, - 0x20, 0x5f, 0x46, 0x3c, 0x60, 0xbe, 0x03, 0xfc, - 0x99, 0x29, 0xd7, 0x30, 0x5e, 0xbe, 0x5b, 0x17, - 0x4f, 0xfe, 0x3f, 0xe0, 0x50, 0xa0, 0x1b, 0x1a, - 0x6b, 0x17, 0xf3, 0xf9, 0x01, 0xe8, 0xc6, 0xc8, - 0x0f, 0x81, 0xbd, 0x2d, 0xc5, 0x8c, 0xa1, 0xab, - 0x9d, 0x13, 0xce, 0x73, 0x14, 0x56, 0x56, 0xb4, - 0x68, 0xac, 0x35, 0xf8, 0x6a, 0x55, 0x3e, 0x50, - 0x34, 0x5a, 0x66, 0x17, 0x98, 0x4d, 0xd1, 0xa7, - 0xdf, 0x57, 0xd6, 0xd4, 0x44, 0x64, 0xa7, 0x74, - 0x18, 0x0a, 0x4f, 0xa9, 0xe4, 0xb4, 0x0f, 0x89, - 0xa2, 0xc5, 0xb8, 0xa7, 0x20, 0xa2, 0xb1, 0xf8, - 0x70, 0xaf, 0xee, 0x6e, 0x62, 0xa5, 0x89, 0x5d, - 0xc9, 0x8a, 0xb9, 0x87, 0xac, 0x4d, 0x4d, 0x81, - 0x1c, 0x62, 0xd3, 0xbf, 0x83, 0x79, 0x98, 0x81, - 0xbd, 0xcc, 0x1f, 0x76, 0xc8, 0x7e, 0x2c, 0xec, - 0xdb, 0xa7, 0xa5, 0xea, 0x05, 0x94, 0x3f, 0xef, - 0x66, 0x1c, 0x5d, 0xc4, 0xbd, 0x73, 0x53, 0x1f, - 0xf3, 0xac, 0x1f, 0xa4, 0xb9, 0x78, 0x1b, 0x93, - 0xcb, 0x17, 0xb6, 0xda, 0xbb, 0x45, 0x21, 0xfa, - 0x52, 0xc7, 0x71, 0x05, 0xb3, 0xeb, 0x82, 0x09, - 0x99, 0x90, 0x5d, 0xa9, 0x76, 0xd1, 0x63, 0x6a, - 0x14, 0x99, 0xe9, 0xa5, 0x98, 0x5d, 0xe0, 0xb5, - 0x2a, 0xd1, 0xf1, 0x2e, 0xe7, 0x85, 0xdb, 0x42, - 0xfc, 0x61, 0x09, 0x14, 0xe5, 0x8e, 0x92, 0x70, - 0x91, 0x15, 0x74, 0x2c, 0x16, 0x30, 0xc4, 0xb0, - 0xf1, 0x61, 0xd5, 0x55, 0xa8, 0xa3, 0xca, 0x88, - 0xe6, 0xb1, 0x58, 0x76, 0xa5, 0x4c, 0x48, 0xe3, - 0xdd, 0x7a, 0x5e, 0x0a, 0x86, 0xfd, 0xd6, 0xe8, - 0xc0, 0x47, 0x27, 0x1a, 0x58, 0x92, 0xad, 0xa6, - 0x51, 0x32, 0x4d, 0x0d, 0x29, 0xd3, 0xcf, 0xf1, - 0xcc, 0x29, 0x1a, 0xfe, 0xf6, 0xa0, 0xf3, 0xdd, - 0x98, 0x73, 0xcb, 0xbb, 0x8a, 0xe9, 0x55, 0xba, - 0x89, 0x2d, 0x31, 0x9b, 0x3d, 0x04, 0x1f, 0xb5, - 0x1c, 0x84, 0x63, 0xca, 0xde, 0x75, 0xac, 0x91, - 0x78, 0x1f, 0x8b, 0x37, 0x8d, 0x46, 0xaa, 0x79, - 0x51, 0xbf, 0x30, 0xfa, 0x3d, 0x9b, 0xd9, 0x20, - 0x25, 0x18, 0x46, 0xb6, 0xe7, 0x8e, 0xf7, 0x5e, - 0x7d, 0xf8, 0xd3, 0x01, 0x39, 0xe5, 0x9d, 0x46, - 0x6b, 0x8c, 0xcf, 0x9d, 0xc6, 0xb9, 0xe8, 0xd8, - 0x25, 0x2d, 0x96, 0x07, 0xc7, 0x4e, 0xa3, 0x3a, - 0x9a, 0xbc, 0x9d, 0x80, 0xa6, 0x5d, 0xb1, 0xc0, - 0x3e, 0x81, 0xe0, 0x52, 0x8f, 0x9a, 0x1a, 0xc2, - 0xdb, 0x9f, 0x91, 0x85, 0x56, 0xdb, 0xb8, 0x69, - 0x10, 0x35, 0xe4, 0xc4, 0xaf, 0xb6, 0x13, 0xf8, - 0x86, 0xe1, 0x2d, 0x3c, 0xf8, 0x94, 0x60, 0xb7, - 0xa1, 0xde, 0x25, 0x51, 0x7d, 0xff, 0xff, 0xa6, - 0x23, 0x68, 0x28, 0x1f, 0x79, 0x33, 0x60, 0x86, - 0xe9, 0x2c, 0x3a, 0xb9, 0x3c, 0x70, 0xb3, 0xe0, - 0x4c, 0x8c, 0x7e, 0x06, 0xdf, 0x4d, 0xf6, 0x88, - 0xda, 0x9e, 0x4f, 0x5b, 0xd2, 0x2e, 0x28, 0xb8, - 0xe0, 0x27, 0x7a, 0x43, 0xfb, 0x23, 0x4b, 0x8a, - 0xd9, 0x4f, 0x29, 0x53, 0x5d, 0x75, 0xc6, 0xfc }; - uint8_t smbbuf2[] = { - 0x0a, 0x30, 0xe0, 0x74, 0x3c, 0x23, 0xc3, 0x11, - 0x95, 0x25, 0x04, 0xe4, 0x2d, 0x7b, 0x29, 0xa1, - 0x75, 0x69, 0x3f, 0x49, 0x9c, 0xfa, 0x66, 0x78, - 0x3c, 0xf1, 0xab, 0xee, 0xab, 0x9a, 0x75, 0x63, - 0x54, 0x80, 0x2b, 0x5c, 0x07, 0xf7, 0xec, 0x72, - 0xfb, 0xd0, 0x52, 0x5e, 0x7e, 0x99, 0xf5, 0x3b, - 0xc4, 0x77, 0x96, 0x12, 0xb8, 0x36, 0xb2, 0xcf, - 0xab, 0xf5, 0xd3, 0xf3, 0x19, 0x77, 0xbb, 0x03, - 0xdb, 0xf7, 0x4d, 0x81, 0xe3, 0xe8, 0x6c, 0x23, - 0x02, 0xe0, 0xcf, 0x24, 0xc1, 0xd5, 0x3d, 0x42, - 0xa4, 0xbc, 0x97, 0xf4, 0x83, 0xee, 0xff, 0x85, - 0x2c, 0xfd, 0xdd, 0xdc, 0x23, 0x1c, 0x87, 0x0c, - 0xe4, 0xd5, 0xfc, 0xc3, 0x8b, 0x10, 0xa5, 0x42, - 0x0f, 0x14, 0xd1, 0x89, 0xa6, 0xaf, 0xaa, 0x77, - 0xfc, 0x3b, 0xce, 0x6c, 0xbe, 0x62, 0xc9, 0xdd, - 0x16, 0xc6, 0x14, 0xc2, 0xa6, 0x13, 0x12, 0xfa, - 0x5a, 0x8b, 0x05, 0x88, 0x06, 0xf9, 0xef, 0x9c, - 0xce, 0xf7, 0x27, 0x46, 0x1d, 0x50, 0xe2, 0xeb, - 0x49, 0xb2, 0xb1, 0x7c, 0x6b, 0xaf, 0xe9, 0xc7, - 0xdd, 0x59, 0x8c, 0xda, 0x32, 0x55, 0xb5, 0xfe, - 0xdc, 0xe0, 0x47, 0xf4, 0xa0, 0xe7, 0xaa, 0x47, - 0x49, 0xdf, 0xcf, 0x9c, 0xd6, 0xfa, 0xd2, 0xca, - 0x55, 0xa7, 0x3f, 0x62, 0x14, 0x6c, 0xc8, 0x7f, - 0xad, 0x7c, 0xb1, 0x70, 0x88, 0xb3, 0x51, 0x13, - 0x2c, 0x3b, 0x78, 0x1d, 0xa2, 0x5e, 0xf7, 0x83, - 0x62, 0x6a, 0x51, 0xbd, 0xe9, 0x77, 0x62, 0xc6, - 0x06, 0x06, 0x51, 0x9d, 0x03, 0x95, 0x51, 0x7c, - 0xd3, 0x73, 0x50, 0x9b, 0x36, 0x5a, 0x28, 0x52, - 0xc0, 0x05, 0xee, 0xd5, 0x2d, 0xd5, 0x77, 0x52, - 0xab, 0x7c, 0x4a, 0x4c, 0x7e, 0xf6, 0xba, 0x52, - 0xc5, 0x4d, 0xb5, 0x74, 0x83, 0x77, 0x5f, 0xaa, - 0xba, 0x86, 0x94, 0xd2, 0x19, 0xca, 0xef, 0xc9, - 0x6e, 0x5b, 0x50, 0xee, 0x2c, 0xdd, 0x67, 0xc8, - 0xfd, 0xc3, 0xa4, 0x80, 0x63, 0x1d, 0xa2, 0x07, - 0x1e, 0x1a, 0x9d, 0x70, 0xe4, 0xab, 0x34, 0x7a, - 0xfb, 0x08, 0x82, 0x85, 0xec, 0x2d, 0x25, 0x3e, - 0x70, 0x22, 0x6e, 0x9d, 0x0f, 0xed, 0x60, 0x8f, - 0xc5, 0x06, 0x66, 0x42, 0x95, 0xcc, 0x77, 0xbe, - 0x4d, 0x19, 0x7c, 0xd1, 0x31, 0x26, 0xfb, 0x52, - 0xad, 0xbd, 0x19, 0x1d, 0x68, 0x56, 0x2c, 0xb9, - 0x5b, 0xaa, 0x92, 0x48, 0xcf, 0xdf, 0x65, 0x2d, - 0xdb, 0x87, 0x06, 0xbe, 0x51, 0x61, 0x6b, 0xf6, - 0x87, 0xdc, 0xbb, 0xa5, 0x48, 0x81, 0xaf, 0xd7, - 0xfc, 0x15, 0xf7, 0x41, 0xde, 0xe3, 0xe9, 0xd4, - 0xad, 0x5d, 0x64, 0x8f, 0x13, 0x68, 0xe5, 0x2b, - 0x4d, 0x87, 0x59, 0x7e, 0xcb, 0x2b, 0xbf, 0xbc, - 0xaa, 0xd2, 0xc7, 0x60, 0xef, 0xe1, 0x25, 0xe2, - 0x89, 0xb4, 0x78, 0x24, 0x52, 0xb4, 0x54, 0xe3, - 0xf0, 0xe5, 0x81, 0xba, 0xe3, 0x00, 0x62, 0x09, - 0x8a, 0x19, 0x7b, 0x9b, 0x0f, 0x50, 0x91, 0xa7, - 0x80, 0xdb, 0x0e, 0x68, 0xe1, 0x22, 0x54, 0x89, - 0x07, 0xc7, 0x39, 0x38, 0xca, 0xae, 0xbf, 0x5b, - 0xbb, 0xe4, 0x70, 0x28, 0xc5, 0x18, 0x98, 0xea }; - uint8_t smbbuf3[] = { - 0x39, 0x99, 0x97, 0x1f, 0xf1, 0x6a, 0x72, 0x0d, - 0x35, 0xd5, 0x33, 0x42, 0x5a, 0x9f, 0xea, 0x0f, - 0x6f, 0x3b, 0xc7, 0xb9, 0xd3, 0x04, 0xdf, 0x44, - 0x45, 0xc7, 0xc6, 0x06, 0x0b, 0x77, 0x8e, 0x8e, - 0x9a, 0x3c, 0xa4, 0x15, 0x85, 0x80, 0xce, 0xd0, - 0x8c, 0x54, 0x60, 0xf9, 0x1f, 0xb3, 0x3e, 0xed, - 0x21, 0x3e, 0xfa, 0x30, 0xf4, 0x50, 0x2b, 0x00, - 0x00, 0xea, 0xd1, 0xb3, 0xd2, 0x7e, 0x6c, 0x14, - 0xe5, 0xf0, 0xf4, 0x9c, 0xb4, 0x2e, 0x32, 0x41, - 0x20, 0x2a, 0x18, 0x78, 0x1a, 0xed, 0x04, 0x94, - 0x83, 0xd1, 0x87, 0x39, 0xf6, 0xcb, 0xf4, 0xc1, - 0xc7, 0xe0, 0x50, 0x87, 0x65, 0x4f, 0x36, 0x73, - 0x70, 0xf5, 0x0a, 0xaa, 0x2b, 0x28, 0xad, 0x05, - 0x28, 0x8d, 0x3b, 0x42, 0xfb, 0xe2, 0xd3, 0xb8, - 0x82, 0x71, 0x25, 0xcd, 0xa2, 0xf2, 0x4b, 0x62, - 0xeb, 0x14, 0x3b, 0x81, 0xaf, 0xd4, 0x68, 0x5a, - 0xae, 0x8e, 0x10, 0x9a, 0x17, 0x4c, 0xf1, 0x3d, - 0x43, 0xb9, 0xd2, 0xd5, 0x86, 0xee, 0x3a, 0xf3, - 0xe5, 0x41, 0xe5, 0x52, 0xda, 0x61, 0xf3, 0x20, - 0x30, 0x5b, 0xe5, 0x1f, 0xe2, 0x4e, 0x9d, 0xd6, - 0xd6, 0x2e, 0x2a, 0x63, 0xbc, 0xf6, 0xb9, 0xc2, - 0xec, 0xd0, 0xe9, 0xfd, 0x07, 0xfb, 0x2d, 0x8e, - 0xbc, 0x43, 0xcb, 0x7e, 0x55, 0x63, 0x9f, 0xb6, - 0xf8, 0x8b, 0x4c, 0xcd, 0x4b, 0x28, 0x47, 0x56, - 0xc9, 0xd2, 0xfe, 0x0e, 0x63, 0x11, 0x09, 0xd9, - 0xd9, 0x97, 0x0a, 0x5a, 0x21, 0xad, 0xdb, 0x53, - 0x24, 0xee, 0x62, 0x4a, 0xaa, 0x49, 0x14, 0xdf, - 0xc0, 0x61, 0x85, 0x11, 0x57, 0x6e, 0x3b, 0x8c, - 0x37, 0x24, 0x13, 0xde, 0xc7, 0xf3, 0x44, 0x54, - 0x8a, 0x69, 0x78, 0x0c, 0xf3, 0xd1, 0xcd, 0xc5, - 0xad, 0x45, 0xc6, 0x06, 0x56, 0x0b, 0x53, 0x40, - 0x79, 0x12, 0x90, 0x6b, 0xdf, 0xc5, 0x80, 0xde, - 0x9c, 0x8e, 0xe1, 0x73, 0xdc, 0x92, 0xc2, 0xf1, - 0xeb, 0xd9, 0x66, 0x0a, 0x12, 0xd2, 0x3f, 0x04, - 0x03, 0xaa, 0x6f, 0xd0, 0x90, 0xfa, 0xb0, 0x6b, - 0x7d, 0xfc, 0x76, 0xf9, 0xe3, 0xa2, 0x17, 0x28, - 0x4e, 0x9d, 0x2d, 0xa6, 0x7e, 0xfa, 0x19, 0x91, - 0xeb, 0xe5, 0xe4, 0xca, 0x09, 0x77, 0xfe, 0xc0, - 0x1c, 0xaa, 0xc4, 0x7c, 0xc2, 0x6a, 0x0e, 0xf3, - 0x4e, 0x79, 0x9b, 0x82, 0x2a, 0x4b, 0xd3, 0x35, - 0x1d, 0x92, 0x6c, 0x3f, 0x85, 0x57, 0x5a, 0x16, - 0xa1, 0x0d, 0xc7, 0x64, 0xb8, 0x46, 0x73, 0xbf, - 0x91, 0x5f, 0x10, 0x2a, 0x2b, 0x51, 0x49, 0xe1, - 0xea, 0xda, 0x2f, 0x41, 0x7b, 0x96, 0xa3, 0xd2, - 0x7b, 0x72, 0xc0, 0x88, 0x84, 0xcb, 0xe0, 0xb7, - 0xae, 0x74, 0xc9, 0x78, 0x82, 0x47, 0xf3, 0x19, - 0x21, 0x53, 0xe6, 0xe1, 0x67, 0xbb, 0x39, 0x05, - 0x6e, 0x1c, 0x38, 0x33, 0x10, 0x60, 0x24, 0x48, - 0xb2, 0x7a, 0xb9, 0x4e, 0x8d, 0x36, 0xcf, 0xce, - 0xf6, 0x31, 0x3b, 0xa3, 0x18, 0x78, 0x49, 0x91, - 0xef, 0xed, 0x86, 0x2c, 0x98, 0x00, 0x18, 0x49, - 0x73, 0xb8, 0xe5, 0x2f, 0xc1, 0x58, 0xe0, 0x47, - 0x2b, 0x16, 0x41, 0xc3, 0x41, 0x05, 0x00, 0x0b, - 0x03, 0x10, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, - 0x00, 0x00, 0x00 }; - - uint32_t smblen1 = sizeof(smbbuf1); - uint32_t smblen2 = sizeof(smbbuf2); - uint32_t smblen3 = sizeof(smbbuf3); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - int r = 0; - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER|STREAM_START, smbbuf1, smblen1); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SMBState *smb_state = f.alstate; - if (smb_state == NULL) { - printf("no smb state: "); - goto end; - } - - if (smb_state->smb.command != SMB_COM_WRITE_ANDX) { - printf("expected SMB command 0x%02x , got 0x%02x : ", SMB_COM_WRITE_ANDX, smb_state->smb.command); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER, smbbuf2, smblen2); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER, smbbuf3, smblen3); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - printUUID("BIND", smb_state->dcerpc.dcerpcbindbindack.uuid_entry); - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -int SMBParserTest04(void) -{ - int result = 0; - Flow f; - uint8_t smbbuf1[] = { - 0x00, 0x00, 0x00, 0x88, 0xff, 0x53, 0x4d, 0x42, - 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0x05, - 0x00, 0x08, 0x00, 0x00, 0x0e, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x00, 0x00, - 0x00, 0x48, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x00, 0xab, 0x05, 0x00, 0x0b, 0x03, - 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0xd0, 0x16, 0xd0, 0x16, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x78, 0x56, 0x34, 0x12, - 0x34, 0x12, 0xcd, 0xab, 0xef, 0x00, 0x01, 0x23, - 0x45, 0x67, 0x89, 0xab, 0x01, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 }; - uint8_t smbbuf2[] = { - 0x00, 0x00, 0x00, 0x2f, 0xff, 0x53, 0x4d, 0x42, - 0x2f, 0x00, 0x00, 0x00, 0x00, 0x98, 0x07, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0x05, - 0x00, 0x08, 0x00, 0x00, 0x06, 0xff, 0x00, 0x2f, - 0x00, 0x48, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; - uint8_t smbbuf3[] = { - 0x00, 0x00, 0x00, 0x3b, 0xff, 0x53, 0x4d, 0x42, - 0x2e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0x05, - 0x00, 0x08, 0x00, 0x00, 0x0c, 0xff, 0x00, 0xde, - 0xde, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint8_t smbbuf4[] = { - 0x00, 0x00, 0x00, 0x80, 0xff, 0x53, 0x4d, 0x42, - 0x2e, 0x00, 0x00, 0x00, 0x00, 0x98, 0x03, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0x05, - 0x00, 0x08, 0x00, 0x00, 0x0c, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, - 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x5d, 0xe0, 0x00, 0x00, - 0x0e, 0x00, 0x5c, 0x70, 0x69, 0x70, 0x65, 0x5c, - 0x73, 0x70, 0x6f, 0x6f, 0x6c, 0x73, 0x73, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 }; - uint32_t smblen1 = sizeof(smbbuf1); - uint32_t smblen2 = sizeof(smbbuf2); - uint32_t smblen3 = sizeof(smbbuf3); - uint32_t smblen4 = sizeof(smbbuf4); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - int r = 0; - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER|STREAM_START, smbbuf1, smblen1); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SMBState *smb_state = f.alstate; - if (smb_state == NULL) { - printf("no smb state: "); - goto end; - } - - if (smb_state->smb.command != SMB_COM_WRITE_ANDX) { - printf("expected SMB command 0x%02x , got 0x%02x : ", SMB_COM_WRITE_ANDX, smb_state->smb.command); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER, smbbuf2, smblen2); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER, smbbuf3, smblen3); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER, smbbuf4, smblen4); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -int SMBParserTest05(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t smbbuf1[] = { - /* session request */ - 0x81, 0x00, 0x00, 0x44, 0x20, 0x43, 0x4b, 0x46, - 0x44, 0x45, 0x4e, 0x45, 0x43, 0x46, 0x44, 0x45, - 0x46, 0x46, 0x43, 0x46, 0x47, 0x45, 0x46, 0x46, - 0x43, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x00, 0x20, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x41, 0x41, 0x00 - }; - uint32_t smblen1 = sizeof(smbbuf1); - uint8_t smbbuf2[] = { - /* session request */ - 0x81, 0x00, 0x00, 0x44, 0x20, 0x43, 0x4b, 0x46, - 0x44, 0x45, 0x4e, 0x45, 0x43, 0x46, 0x44, 0x45, - 0x46, 0x46, 0x43, 0x46, 0x47, 0x45, 0x46, 0x46, - 0x43, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x00, 0x20, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x41, 0x41, 0x00, - /* session message */ - 0x00, 0x00, 0x00, 0x60, 0xff, 0x53, 0x4d, 0x42, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x2d, - 0x00, 0x00, 0xdd, 0xca, 0x00, 0x3d, 0x00, 0x02, - 0x4d, 0x45, 0x54, 0x41, 0x53, 0x50, 0x4c, 0x4f, - 0x49, 0x54, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, - 0x41, 0x4e, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4c, - 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, 0x32, - 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x41, 0x4e, - 0x4d, 0x41, 0x4e, 0x20, 0x31, 0x2e, 0x30, 0x00, - 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x4d, 0x20, 0x30, - 0x2e, 0x31, 0x32, 0x00 - }; - uint32_t smblen2 = sizeof(smbbuf2); - - int result = 0; - AppProto alproto; - Flow f; - AppLayerProtoDetectThreadCtx *alpd_tctx; - memset(&f, 0, sizeof(f)); - f.dp = 139; - - /** SMB */ - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB, "|ff|SMB", 8, 4, STREAM_TOCLIENT); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB, "|ff|SMB", 8, 4, STREAM_TOSERVER); - - /** SMB2 */ - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2, "|fe|SMB", 8, 4, STREAM_TOCLIENT); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2, "|fe|SMB", 8, 4, STREAM_TOSERVER); - - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "139", - ALPROTO_SMB, - SMB_PROBING_PARSER_MIN_DEPTH, 0, - STREAM_TOSERVER, - SMBProbingParser); - - AppLayerProtoDetectPrepareState(); - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - alproto = AppLayerProtoDetectGetProto(alpd_tctx, - &f, - smbbuf1, smblen1, - IPPROTO_TCP, STREAM_TOSERVER); - if (alproto != ALPROTO_UNKNOWN) { - printf("alproto is %"PRIu16 ". Should be ALPROTO_UNKNOWN\n", - alproto); - goto end; - } - - alproto = AppLayerProtoDetectGetProto(alpd_tctx, - &f, - smbbuf2, smblen2, - IPPROTO_TCP, STREAM_TOSERVER); - if (alproto != ALPROTO_SMB) { - printf("alproto is %"PRIu16 ". Should be ALPROTO_SMB\n", - alproto); - goto end; - } - - result = 1; - end: - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - return result; -} - -int SMBParserTest06(void) -{ - AppLayerProtoDetectUnittestCtxBackup(); - AppLayerProtoDetectSetup(); - - uint8_t smbbuf1[] = { - /* session request */ - 0x83, 0x00, 0x00, 0x01, 0x82 - }; - uint32_t smblen1 = sizeof(smbbuf1); - uint8_t smbbuf2[] = { - /* session request */ - 0x83, 0x00, 0x00, 0x01, 0x82, - /* session message */ - 0x00, 0x00, 0x00, 0x55, 0xff, 0x53, 0x4d, 0x42, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x98, 0x53, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x05, 0x00, 0x03, - 0x0a, 0x00, 0x01, 0x00, 0x04, 0x11, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfd, 0xe3, 0x00, 0x80, 0xb8, 0xcb, 0x22, 0x5f, - 0xfd, 0xeb, 0xc3, 0x01, 0x68, 0x01, 0x00, 0x10, - 0x00, 0x50, 0xb5, 0xc3, 0x62, 0x59, 0x02, 0xd1, - 0x4d, 0x99, 0x6d, 0x85, 0x7d, 0xfa, 0x93, 0x2d, - 0xbb - }; - uint32_t smblen2 = sizeof(smbbuf2); - - int result = 0; - AppProto alproto; - Flow f; - AppLayerProtoDetectThreadCtx *alpd_tctx; - memset(&f, 0, sizeof(f)); - f.dp = 139; - - /** SMB */ - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB, "|ff|SMB", 8, 4, STREAM_TOCLIENT); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB, "|ff|SMB", 8, 4, STREAM_TOSERVER); - - /** SMB2 */ - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2, "|fe|SMB", 8, 4, STREAM_TOCLIENT); - AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMB2, "|fe|SMB", 8, 4, STREAM_TOSERVER); - - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "139", - ALPROTO_SMB, - SMB_PROBING_PARSER_MIN_DEPTH, 0, - STREAM_TOSERVER, - SMBProbingParser); - - AppLayerProtoDetectPrepareState(); - alpd_tctx = AppLayerProtoDetectGetCtxThread(); - - alproto = AppLayerProtoDetectGetProto(alpd_tctx, - &f, - smbbuf1, smblen1, - IPPROTO_TCP, STREAM_TOSERVER); - if (alproto != ALPROTO_UNKNOWN) { - printf("alproto is %"PRIu16 ". Should be ALPROTO_UNKNOWN\n", - alproto); - goto end; - } - - alproto = AppLayerProtoDetectGetProto(alpd_tctx, - &f, - smbbuf2, smblen2, - IPPROTO_TCP, STREAM_TOSERVER); - if (alproto != ALPROTO_SMB) { - printf("alproto is %"PRIu16 ". Should be ALPROTO_SMB\n", - alproto); - goto end; - } - - result = 1; - end: - AppLayerProtoDetectDeSetup(); - AppLayerProtoDetectUnittestCtxRestore(); - if (alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(alpd_tctx); - return result; -} - -int SMBParserTest07(void) -{ - int result = 0; - Flow f; - uint8_t smbbuf1[] = { - /* negative session response */ - 0x83, 0x00, 0x00, 0x01, 0x82 - }; - uint32_t smblen1 = sizeof(smbbuf1); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - int r = 0; - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOCLIENT | STREAM_START, smbbuf1, smblen1); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SMBState *smb_state = f.alstate; - if (smb_state == NULL) { - printf("no smb state: "); - goto end; - } - - if (smb_state->smb.command != 0) { - printf("we shouldn't have any smb state as yet\n"); - goto end; - } - - if (smb_state->nbss.length != 1 || - smb_state->nbss.type != NBSS_NEGATIVE_SESSION_RESPONSE) { - printf("something wrong with nbss parsing\n"); - goto end; - } - - if (smb_state->bytesprocessed != 0) { - printf("smb parser bytesprocessed should be 0, but it is not\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -int SMBParserTest08(void) -{ - int result = 0; - Flow f; - uint8_t smbbuf1[] = { - /* positive session response */ - 0x82, 0x00, 0x00, 0x00 - }; - uint8_t smbbuf2[] = { - /* negotiate protocol */ - 0x00, 0x00, 0x00, 0x55, 0xff, 0x53, 0x4d, 0x42, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x98, 0x53, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x05, 0x00, 0x03, - 0x0a, 0x00, 0x01, 0x00, 0x04, 0x11, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfd, 0xe3, 0x00, 0x80, 0x40, 0x8a, 0x57, 0x5c, - 0xfd, 0xeb, 0xc3, 0x01, 0x68, 0x01, 0x00, 0x10, - 0x00, 0x50, 0xb5, 0xc3, 0x62, 0x59, 0x02, 0xd1, - 0x4d, 0x99, 0x6d, 0x85, 0x7d, 0xfa, 0x93, 0x2d, - 0xbb - }; - uint32_t smblen1 = sizeof(smbbuf1); - uint32_t smblen2 = sizeof(smbbuf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - int r = 0; - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOCLIENT | STREAM_START, smbbuf1, smblen1); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SMBState *smb_state = f.alstate; - if (smb_state == NULL) { - printf("no smb state: "); - goto end; - } - - if (smb_state->smb.command != 0) { - printf("we shouldn't have any smb state as yet\n"); - goto end; - } - - if (smb_state->nbss.length != 0 || - smb_state->nbss.type != NBSS_POSITIVE_SESSION_RESPONSE) { - printf("something wrong with nbss parsing\n"); - goto end; - } - - if (smb_state->bytesprocessed != 0) { - printf("smb parser bytesprocessed should be 0, but it is not\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOCLIENT, smbbuf2, smblen2); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (smb_state->smb.command != SMB_COM_NEGOTIATE) { - printf("we should expect SMB command 0x%02x , got 0x%02x : ", - SMB_COM_NEGOTIATE, smb_state->smb.command); - goto end; - } - - if (smb_state->nbss.length != 85 || - smb_state->nbss.type != NBSS_SESSION_MESSAGE) { - printf("something wrong with nbss parsing\n"); - goto end; - } - - if (smb_state->bytesprocessed != 0) { - printf("smb parser bytesprocessed should be 0, but it is not\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -int SMBParserTest09(void) -{ - int result = 0; - Flow f; - uint8_t smbbuf1[] = { - /* session request */ - 0x81, 0x00, 0x00, 0x44, 0x20, 0x45, 0x44, 0x45, - 0x4a, 0x46, 0x44, 0x45, 0x44, 0x45, 0x50, 0x43, - 0x4e, 0x46, 0x48, 0x44, 0x43, 0x45, 0x4c, 0x43, - 0x4e, 0x46, 0x43, 0x46, 0x45, 0x45, 0x4e, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x00, 0x20, 0x45, - 0x44, 0x45, 0x4a, 0x46, 0x44, 0x45, 0x44, 0x45, - 0x50, 0x43, 0x4e, 0x46, 0x49, 0x46, 0x41, 0x43, - 0x4e, 0x46, 0x43, 0x46, 0x45, 0x45, 0x4e, 0x43, - 0x41, 0x43, 0x41, 0x43, 0x41, 0x41, 0x41, 0x00 - }; - uint8_t smbbuf2[] = { - /* session service - negotiate protocol */ - 0x00, 0x00, 0x00, 0x85, 0xff, 0x53, 0x4d, 0x42, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02, - 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, - 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, - 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, - 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, - 0x30, 0x00, 0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x57, - 0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61, 0x00, 0x02, - 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, - 0x32, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, - 0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54, - 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, - 0x00 - }; - uint32_t smblen1 = sizeof(smbbuf1); - uint32_t smblen2 = sizeof(smbbuf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - int r = 0; - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER | STREAM_START, smbbuf1, smblen1); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SMBState *smb_state = f.alstate; - if (smb_state == NULL) { - printf("no smb state: "); - goto end; - } - - if (smb_state->smb.command != 0) { - printf("we shouldn't have any smb state as yet\n"); - goto end; - } - - if (smb_state->nbss.length != 68 || - smb_state->nbss.type != NBSS_SESSION_REQUEST) { - printf("something wrong with nbss parsing\n"); - goto end; - } - - if (smb_state->bytesprocessed != 0) { - printf("smb parser bytesprocessed should be 0, but it is not\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER, smbbuf2, smblen2); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (smb_state->smb.command != SMB_COM_NEGOTIATE) { - printf("we should expect SMB command 0x%02x , got 0x%02x : ", - SMB_COM_NEGOTIATE, smb_state->smb.command); - goto end; - } - - if (smb_state->nbss.length != 133 || - smb_state->nbss.type != NBSS_SESSION_MESSAGE) { - printf("something wrong with nbss parsing\n"); - goto end; - } - - if (smb_state->bytesprocessed != 0) { - printf("smb parser bytesprocessed should be 0, but it is not\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Test to temporarily to show the direction demaraction issue in the - * smb parser. - */ -int SMBParserTest10(void) -{ - int result = 0; - Flow f; - uint8_t smbbuf1[] = { - /* partial request */ - 0x00, 0x00, 0x00, 0x85, 0xff, 0x53, 0x4d, 0x42, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02, - 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, - 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, - 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, - 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, - 0x30, 0x00, 0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x57, - 0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61, 0x00, 0x02, - 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, - 0x32, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, - }; - //0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54, - //0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, - //0x00 - - uint8_t smbbuf2[] = { - /* response */ - 0x00, 0x00, 0x00, 0x55, 0xff, 0x53, 0x4d, 0x42, - 0x72, 0x00, 0x00, 0x00, 0x00, 0x98, 0x53, 0xc8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x05, 0x00, 0x03, - 0x32, 0x00, 0x01, 0x00, 0x04, 0x41, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfd, 0xf3, 0x00, 0x80, 0x20, 0x03, 0x1a, 0x2d, - 0x77, 0x98, 0xc5, 0x01, 0xa4, 0x01, 0x00, 0x10, - 0x00, 0xb7, 0xeb, 0x0b, 0x05, 0x21, 0x22, 0x50, - 0x42, 0x8c, 0x38, 0x2a, 0x7f, 0xc5, 0x6a, 0x7c, - 0x0c - }; - uint32_t smblen1 = sizeof(smbbuf1); - uint32_t smblen2 = sizeof(smbbuf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - int r = 0; - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOSERVER | STREAM_START, smbbuf1, smblen1); - if (r != 0) { - printf("smb header check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SMBState *smb_state = f.alstate; - if (smb_state == NULL) { - printf("no smb state: "); - goto end; - } - - if (smb_state->bytesprocessed == 0) { - printf("request - smb parser bytesprocessed should not be 0.\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB, STREAM_TOCLIENT, smbbuf2, smblen2); - if (r == 0) { - printf("smb parser didn't return fail\n"); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -#endif - -void SMBParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SMBParserTest01", SMBParserTest01, 1); - UtRegisterTest("SMBParserTest02", SMBParserTest02, 1); - UtRegisterTest("SMBParserTest03", SMBParserTest03, 1); - UtRegisterTest("SMBParserTest04", SMBParserTest04, 1); - UtRegisterTest("SMBParserTest05", SMBParserTest05, 1); - UtRegisterTest("SMBParserTest06", SMBParserTest06, 1); - UtRegisterTest("SMBParserTest07", SMBParserTest07, 1); - UtRegisterTest("SMBParserTest08", SMBParserTest08, 1); - UtRegisterTest("SMBParserTest09", SMBParserTest09, 1); - UtRegisterTest("SMBParserTest10", SMBParserTest10, 1); -#endif -} - diff --git a/framework/src/suricata/src/app-layer-smb.h b/framework/src/suricata/src/app-layer-smb.h deleted file mode 100644 index 48d4fa84..00000000 --- a/framework/src/suricata/src/app-layer-smb.h +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Kirby Kuehl - */ -#ifndef __APP_LAYER_SMB_H__ -#define __APP_LAYER_SMB_H__ - -#include "suricata-common.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "flow.h" -#include "stream.h" -#include "app-layer-nbss.h" -#include "app-layer-dcerpc-common.h" - -typedef struct SMBHdr_ { - uint8_t protocol[4]; - uint8_t command; - uint32_t status; - uint8_t flags; - uint16_t flags2; - uint16_t pidhigh; - uint64_t securitysignature; - uint16_t unused; - uint16_t tid; - uint16_t pid; - uint16_t uid; - uint16_t mid; -} SMBHdr; - -#define SMB_HDR_LEN 32 -#define MINIMUM_SMB_LEN 35 -#define NBSS_SMB_HDRS_LEN 36 - -typedef struct SMBWordCount_ { - uint8_t wordcount; - uint8_t wordcountleft; - uint8_t *words; -} SMBWordCount; - -typedef struct SMBByteCount_ { - uint8_t bytecountbytes; - uint16_t bytecount; - uint16_t bytecountleft; - uint8_t *bytes; -} SMBByteCount; - -typedef struct SMBAndX_ { - uint8_t isandx; - uint8_t paddingparsed; - uint8_t andxcommand; - uint8_t maxchainedandx; - uint16_t andxoffset; - uint16_t andxbytesprocessed; - uint16_t datalength; - uint16_t datalengthhigh; - uint64_t dataoffset; -} SMBAndX; - -typedef struct SMBState_ { - NBSSHdr nbss; - uint16_t transaction_id; - uint16_t bytesprocessed; - SMBHdr smb; - SMBWordCount wordcount; - SMBByteCount bytecount; - SMBAndX andx; - DCERPC dcerpc; - uint8_t dcerpc_present; - uint8_t data_needed_for_dir; -} SMBState; - -#define SMB_FLAGS_SERVER_TO_REDIR 0x80 -#define SMB_NO_SECONDARY_ANDX_COMMAND 0xff - -/* http://msdn.microsoft.com/en-us/library/dd327674.aspx */ -#define SMB_COM_CREATE_DIRECTORY 0x00 -#define SMB_COM_DELETE_DIRECTORY 0x01 -#define SMB_COM_OPEN 0x02 -#define SMB_COM_CREATE 0x03 -#define SMB_COM_CLOSE 0x04 -#define SMB_COM_FLUSH 0x05 -#define SMB_COM_DELETE 0x06 -#define SMB_COM_RENAME 0x07 -#define SMB_COM_QUERY_INFORMATION 0x08 -#define SMB_COM_SET_INFORMATION 0x09 -#define SMB_COM_READ 0x0A -#define SMB_COM_WRITE 0x0B -#define SMB_COM_LOCK_BYTE_RANGE 0x0C -#define SMB_COM_UNLOCK_BYTE_RANGE 0x0D -#define SMB_COM_CREATE_TEMPORARY 0x0E -#define SMB_COM_CREATE_NEW 0x0F -#define SMB_COM_CHECK_DIRECTORY 0x10 -#define SMB_COM_PROCESS_EXIT 0x11 -#define SMB_COM_SEEK 0x12 -#define SMB_COM_LOCK_AND_READ 0x13 -#define SMB_COM_WRITE_AND_UNLOCK 0x14 -#define SMB_COM_READ_RAW 0x1A -#define SMB_COM_READ_MPX 0x1B -#define SMB_COM_READ_MPX_SECONDARY 0x1C -#define SMB_COM_WRITE_RAW 0x1D -#define SMB_COM_WRITE_MPX 0x1E -#define SMB_COM_WRITE_COMPLETE 0x20 -#define SMB_COM_SET_INFORMATION2 0x22 -#define SMB_COM_QUERY_INFORMATION2 0x23 -#define SMB_COM_LOCKING_ANDX 0x24 -#define SMB_COM_TRANSACTION 0x25 -#define SMB_COM_TRANSACTION_SECONDARY 0x26 -#define SMB_COM_IOCTL 0x27 -#define SMB_COM_IOCTL_SECONDARY 0x28 -#define SMB_COM_COPY 0x29 -#define SMB_COM_MOVE 0x2A -#define SMB_COM_ECHO 0x2B -#define SMB_COM_WRITE_AND_CLOSE 0x2C -#define SMB_COM_OPEN_ANDX 0x2D -#define SMB_COM_READ_ANDX 0x2E -#define SMB_COM_WRITE_ANDX 0x2F -#define SMB_COM_CLOSE_AND_TREE_DISC 0x31 -#define SMB_COM_TRANSACTION2 0x32 -#define SMB_COM_TRANSACTION2_SECONDARY 0x33 -#define SMB_COM_FIND_CLOSE2 0x34 -#define SMB_COM_FIND_NOTIFY_CLOSE 0x35 -#define SMB_COM_TREE_CONNECT 0x70 -#define SMB_COM_TREE_DISCONNECT 0x71 -#define SMB_COM_NEGOTIATE 0x72 -#define SMB_COM_SESSION_SETUP_ANDX 0x73 -#define SMB_COM_LOGOFF_ANDX 0x74 -#define SMB_COM_TREE_CONNECT_ANDX 0x75 -#define SMB_COM_QUERY_INFORMATION_DISK 0x80 -#define SMB_COM_SEARCH 0x81 -#define SMB_COM_FIND 0x82 -#define SMB_COM_FIND_UNIQUE 0x83 -#define SMB_COM_NT_TRANSACT 0xA0 -#define SMB_COM_NT_TRANSACT_SECONDARY 0xA1 -#define SMB_COM_NT_CREATE_ANDX 0xA2 -#define SMB_COM_NT_CANCEL 0xA4 -#define SMB_COM_NT_RENAME 0xA5 -#define SMB_COM_OPEN_PRINT_FILE 0xC0 -#define SMB_COM_WRITE_PRINT_FILE 0xC1 -#define SMB_COM_CLOSE_PRINT_FILE 0xC2 -#define SMB_COM_GET_PRINT_QUEUE 0xC3 - -void RegisterSMBParsers(void); -void SMBParserRegisterTests(void); -int isAndX(SMBState *smb_state); - -#endif /* __APP_LAYER_SMB_H__ */ - diff --git a/framework/src/suricata/src/app-layer-smb2.c b/framework/src/suricata/src/app-layer-smb2.c deleted file mode 100644 index f412e1df..00000000 --- a/framework/src/suricata/src/app-layer-smb2.c +++ /dev/null @@ -1,690 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Kirby Kuehl - * - * SMBv2 parser/decoder - */ - -#include "suricata-common.h" - -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" - -#include "util-spm.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "util-memcmp.h" - -#include "app-layer-smb2.h" - -enum { - SMB2_FIELD_NONE = 0, - SMB2_PARSE_NBSS_HEADER, - SMB2_PARSE_SMB_HEADER, - - /* must be last */ - SMB_FIELD_MAX, -}; - -static uint32_t NBSSParseHeader(void *smb2_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len) -{ - SCEnter(); - SMB2State *sstate = (SMB2State *) smb2_state; - uint8_t *p = input; - - if (input_len && sstate->bytesprocessed < NBSS_HDR_LEN - 1) { - switch (sstate->bytesprocessed) { - case 0: - /* Initialize */ - if (input_len >= NBSS_HDR_LEN) { - sstate->nbss.type = *p; - sstate->nbss.length = (*(p + 1) & 0x01) << 16; - sstate->nbss.length |= *(p + 2) << 8; - sstate->nbss.length |= *(p + 3); - sstate->bytesprocessed += NBSS_HDR_LEN; - SCReturnUInt(4U); - } else { - sstate->nbss.type = *(p++); - if (!(--input_len)) - break; - } - /* fall through */ - case 1: - sstate->nbss.length = (*(p++) & 0x01) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 2: - sstate->nbss.length |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 3: - sstate->nbss.length |= *(p++); - --input_len; - break; - } - sstate->bytesprocessed += (p - input); - } - SCReturnUInt((uint32_t)(p - input)); -} - -static uint32_t SMB2ParseHeader(void *smb2_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len) -{ - SCEnter(); - - SMB2State *sstate = (SMB2State *) smb2_state; - uint8_t *p = input; - - if (input_len) { - switch (sstate->bytesprocessed) { - case 4: - // fallthrough - /* above statement to prevent coverity FPs from the switch - * fall through */ - if (input_len >= SMB2_HDR_LEN) { - if (SCMemcmp(p, "\xfe\x53\x4d\x42", 4) != 0) { - //printf("SMB2 Header did not validate\n"); - return 0; - } - sstate->smb2.StructureSize = *(p + 4); - sstate->smb2.StructureSize |= *(p + 5) << 8; - sstate->smb2.CreditCharge = *(p + 6); - sstate->smb2.CreditCharge |= *(p + 7) << 8; - sstate->smb2.Status = *(p + 8); - sstate->smb2.Status |= *(p + 9) << 8; - sstate->smb2.Status |= *(p + 10) << 16; - sstate->smb2.Status |= *(p + 11) << 24; - sstate->smb2.Command = *(p + 12); - sstate->smb2.Command |= *(p + 13) << 8; - sstate->smb2.CreditRequestResponse = *(p + 14); - sstate->smb2.CreditRequestResponse |= *(p + 15) << 8; - sstate->smb2.Flags = *(p + 16); - sstate->smb2.Flags |= *(p + 17) << 8; - sstate->smb2.Flags |= *(p + 18) << 16; - sstate->smb2.Flags |= *(p + 19) << 24; - sstate->smb2.NextCommand = *(p + 20); - sstate->smb2.NextCommand |= *(p + 21) << 8; - sstate->smb2.NextCommand |= *(p + 22) << 16; - sstate->smb2.NextCommand |= *(p + 23) << 24; - sstate->smb2.MessageId = *(p + 24); - sstate->smb2.MessageId |= *(p + 25) << 8; - sstate->smb2.MessageId |= *(p + 26) << 16; - sstate->smb2.MessageId |= (uint64_t) *(p + 27) << 24; - sstate->smb2.MessageId |= (uint64_t) *(p + 28) << 32; - sstate->smb2.MessageId |= (uint64_t) *(p + 29) << 40; - sstate->smb2.MessageId |= (uint64_t) *(p + 30) << 48; - sstate->smb2.MessageId |= (uint64_t) *(p + 31) << 56; - sstate->smb2.ProcessId = *(p + 32); - sstate->smb2.ProcessId |= *(p + 33) << 8; - sstate->smb2.ProcessId |= *(p + 34) << 16; - sstate->smb2.ProcessId |= *(p + 35) << 24; - sstate->smb2.TreeId = *(p + 36); - sstate->smb2.TreeId |= *(p + 37) << 8; - sstate->smb2.TreeId |= *(p + 38) << 16; - sstate->smb2.TreeId |= *(p + 39) << 24; - sstate->smb2.SessionId = *(p + 40); - sstate->smb2.SessionId |= *(p + 41) << 8; - sstate->smb2.SessionId |= *(p + 42) << 16; - sstate->smb2.SessionId |= (uint64_t) *(p + 43) << 24; - sstate->smb2.SessionId |= (uint64_t) *(p + 44) << 32; - sstate->smb2.SessionId |= (uint64_t) *(p + 45) << 40; - sstate->smb2.SessionId |= (uint64_t) *(p + 46) << 48; - sstate->smb2.SessionId |= (uint64_t) *(p + 47) << 56; - sstate->smb2.Signature[0] = *(p + 48); - sstate->smb2.Signature[1] = *(p + 49); - sstate->smb2.Signature[2] = *(p + 50); - sstate->smb2.Signature[3] = *(p + 51); - sstate->smb2.Signature[4] = *(p + 52); - sstate->smb2.Signature[5] = *(p + 53); - sstate->smb2.Signature[6] = *(p + 54); - sstate->smb2.Signature[7] = *(p + 55); - sstate->smb2.Signature[8] = *(p + 56); - sstate->smb2.Signature[9] = *(p + 57); - sstate->smb2.Signature[10] = *(p + 58); - sstate->smb2.Signature[11] = *(p + 59); - sstate->smb2.Signature[12] = *(p + 60); - sstate->smb2.Signature[13] = *(p + 61); - sstate->smb2.Signature[14] = *(p + 62); - sstate->smb2.Signature[15] = *(p + 63); - sstate->bytesprocessed += SMB2_HDR_LEN; - SCReturnUInt(64U); - break; - } else { - //sstate->smb2.protocol[0] = *(p++); - if (*(p++) != 0xfe) - return 0; - if (!(--input_len)) - break; - /* We fall through to the next case if we still have input. - * Same applies for other cases as well */ - } - /* fall through */ - case 5: - //sstate->smb2.protocol[1] = *(p++); - if (*(p++) != 'S') - return 0; - if (!(--input_len)) - break; - /* fall through */ - case 6: - //sstate->smb2.protocol[2] = *(p++); - if (*(p++) != 'M') - return 0; - if (!(--input_len)) - break; - /* fall through */ - case 7: - //sstate->smb2.protocol[3] = *(p++); - if (*(p++) != 'B') - return 0; - if (!(--input_len)) - break; - /* fall through */ - case 8: - sstate->smb2.StructureSize = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 9: - sstate->smb2.StructureSize |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 10: - sstate->smb2.CreditCharge = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 11: - sstate->smb2.CreditCharge |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 12: - sstate->smb2.Status = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 13: - sstate->smb2.Status |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 14: - sstate->smb2.Status |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 15: - sstate->smb2.Status |= *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 16: - sstate->smb2.Command = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 17: - sstate->smb2.Command |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 18: - sstate->smb2.CreditRequestResponse = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 19: - sstate->smb2.CreditRequestResponse |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 20: - sstate->smb2.Flags = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 21: - sstate->smb2.Flags |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 22: - sstate->smb2.Flags |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 23: - sstate->smb2.Flags |= *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 24: - sstate->smb2.NextCommand = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 25: - sstate->smb2.NextCommand |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 26: - sstate->smb2.NextCommand |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 27: - sstate->smb2.NextCommand |= *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 28: - sstate->smb2.MessageId = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 29: - sstate->smb2.MessageId = *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 30: - sstate->smb2.MessageId = *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 31: - sstate->smb2.MessageId = (uint64_t) *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 32: - sstate->smb2.MessageId = (uint64_t) *(p++) << 32; - if (!(--input_len)) - break; - /* fall through */ - case 33: - sstate->smb2.MessageId = (uint64_t) *(p++) << 40; - if (!(--input_len)) - break; - /* fall through */ - case 34: - sstate->smb2.MessageId = (uint64_t) *(p++) << 48; - if (!(--input_len)) - break; - /* fall through */ - case 35: - sstate->smb2.MessageId = (uint64_t) *(p++) << 56; - if (!(--input_len)) - break; - /* fall through */ - case 36: - sstate->smb2.ProcessId = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 37: - sstate->smb2.ProcessId |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 38: - sstate->smb2.ProcessId |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 39: - sstate->smb2.ProcessId |= *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 40: - sstate->smb2.TreeId = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 41: - sstate->smb2.TreeId |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 42: - sstate->smb2.TreeId |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 43: - sstate->smb2.TreeId |= *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 44: - sstate->smb2.SessionId = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 45: - sstate->smb2.SessionId |= *(p++) << 8; - if (!(--input_len)) - break; - /* fall through */ - case 46: - sstate->smb2.SessionId |= *(p++) << 16; - if (!(--input_len)) - break; - /* fall through */ - case 47: - sstate->smb2.SessionId |= (uint64_t) *(p++) << 24; - if (!(--input_len)) - break; - /* fall through */ - case 48: - sstate->smb2.SessionId |= (uint64_t) *(p++) << 32; - if (!(--input_len)) - break; - /* fall through */ - case 49: - sstate->smb2.SessionId |= (uint64_t) *(p++) << 40; - if (!(--input_len)) - break; - /* fall through */ - case 50: - sstate->smb2.SessionId |= (uint64_t) *(p++) << 48; - if (!(--input_len)) - break; - /* fall through */ - case 51: - sstate->smb2.SessionId |= (uint64_t) *(p++) << 56; - if (!(--input_len)) - break; - /* fall through */ - case 52: - sstate->smb2.Signature[0] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 53: - sstate->smb2.Signature[1] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 54: - sstate->smb2.Signature[2] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 55: - sstate->smb2.Signature[3] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 56: - sstate->smb2.Signature[4] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 57: - sstate->smb2.Signature[5] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 58: - sstate->smb2.Signature[6] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 59: - sstate->smb2.Signature[7] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 60: - sstate->smb2.Signature[8] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 61: - sstate->smb2.Signature[9] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 62: - sstate->smb2.Signature[10] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 63: - sstate->smb2.Signature[11] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 64: - sstate->smb2.Signature[12] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 65: - sstate->smb2.Signature[13] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 66: - sstate->smb2.Signature[14] = *(p++); - if (!(--input_len)) - break; - /* fall through */ - case 67: - sstate->smb2.Signature[15] = *(p++); - --input_len; - break; - /* fall through */ - } - } - sstate->bytesprocessed += (p - input); - SCReturnUInt((uint32_t)(p - input)); -} - -static int SMB2Parse(Flow *f, void *smb2_state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SCEnter(); - SMB2State *sstate = (SMB2State *) smb2_state; - uint32_t retval = 0; - uint32_t parsed = 0; - - if (pstate == NULL) - return -1; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - while (sstate->bytesprocessed < NBSS_HDR_LEN && input_len) { - retval = NBSSParseHeader(smb2_state, pstate, input, input_len); - if (retval <= input_len) { - parsed += retval; - input_len -= retval; - } else { - return -1; - } - - SCLogDebug("NBSS Header (%u/%u) Type 0x%02x Length 0x%04x parsed %u input_len %u", - sstate->bytesprocessed, NBSS_HDR_LEN, sstate->nbss.type, - sstate->nbss.length, parsed, input_len); - } - - switch(sstate->nbss.type) { - case NBSS_SESSION_MESSAGE: - while (input_len && (sstate->bytesprocessed >= NBSS_HDR_LEN && - sstate->bytesprocessed < NBSS_HDR_LEN + SMB2_HDR_LEN)) { - retval = SMB2ParseHeader(smb2_state, pstate, input + parsed, input_len); - if (retval <= input_len) { - parsed += retval; - input_len -= retval; - } else { - return -1; - } - - SCLogDebug("SMB2 Header (%u/%u) Command 0x%04x parsed %u input_len %u", - sstate->bytesprocessed, NBSS_HDR_LEN + SMB2_HDR_LEN, - sstate->smb2.Command, parsed, input_len); - } - break; - default: - break; - } - SCReturnInt(1); -} - - -static void *SMB2StateAlloc(void) -{ - void *s = SCMalloc(sizeof(SMB2State)); - if (unlikely(s == NULL)) - return NULL; - - memset(s, 0, sizeof(SMB2State)); - return s; -} - -static void SMB2StateFree(void *s) -{ - if (s) { - SCFree(s); - s = NULL; - } -} - -void RegisterSMB2Parsers(void) -{ - /** SMB2 */ - char *proto_name = "smb2"; - - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMB2, STREAM_TOSERVER, SMB2Parse); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMB2, STREAM_TOCLIENT, SMB2Parse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_SMB2, SMB2StateAlloc, SMB2StateFree); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } - -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_SMB2, SMB2ParserRegisterTests); -#endif - return; -} - -/* UNITTESTS */ -#ifdef UNITTESTS - -int SMB2ParserTest01(void) -{ - int result = 1; - Flow f; - uint8_t smb2buf[] = - "\x00\x00\x00\x66" // NBSS - "\xfe\x53\x4d\x42\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00" // SMB2 - "\x3f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x24\x00\x01\x00x00\x00\x00\x00\x00\x00\x0\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02"; - - uint32_t smb2len = sizeof(smb2buf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMB2, STREAM_TOSERVER|STREAM_EOF, smb2buf, smb2len); - if (r != 0) { - printf("smb2 header check returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SMB2State *smb2_state = f.alstate; - if (smb2_state == NULL) { - printf("no smb2 state: "); - result = 0; - goto end; - } - - if (smb2_state->nbss.type != NBSS_SESSION_MESSAGE) { - printf("expected nbss type 0x%02x , got 0x%02x : ", NBSS_SESSION_MESSAGE, smb2_state->nbss.type); - result = 0; - goto end; - } - - if (smb2_state->nbss.length != 102) { - printf("expected nbss length 0x%02x , got 0x%02x : ", 102, smb2_state->nbss.length); - result = 0; - goto end; - } - - if (smb2_state->smb2.Command != SMB2_NEGOTIATE) { - printf("expected SMB2 command 0x%04x , got 0x%04x : ", SMB2_NEGOTIATE, smb2_state->smb2.Command); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -void SMB2ParserRegisterTests(void) -{ - UtRegisterTest("SMB2ParserTest01", SMB2ParserTest01, 1); -} -#endif - diff --git a/framework/src/suricata/src/app-layer-smb2.h b/framework/src/suricata/src/app-layer-smb2.h deleted file mode 100644 index 2eb86ca6..00000000 --- a/framework/src/suricata/src/app-layer-smb2.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Kirby Kuehl - */ - -#ifndef __APP_LAYER_SMB2_H__ -#define __APP_LAYER_SMB2_H__ - -#include "suricata-common.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-nbss.h" -#include "flow.h" -#include "stream.h" - -typedef struct SMB2Hdr { - uint32_t Protocol; /**< Contains 0xFE,'SMB' */ - uint16_t StructureSize; - uint16_t CreditCharge; - uint32_t Status; - uint16_t Command; - uint16_t CreditRequestResponse; - uint32_t Flags; - uint32_t NextCommand; - uint64_t MessageId; - uint32_t ProcessId; - uint32_t TreeId; - uint64_t SessionId; - uint8_t Signature[16]; -} SMB2Hdr; - -#define SMB2_HDR_LEN 64 - -typedef struct SMB2State_ { - NBSSHdr nbss; - SMB2Hdr smb2; - uint16_t bytesprocessed; -} SMB2State; - -/** from http://msdn.microsoft.com/en-us/library/cc246528(PROT.13).aspx */ -#define SMB2_NEGOTIATE 0x0000 -#define SMB2_SESSION_SETUP 0x0001 -#define SMB2_LOGOFF 0x0002 -#define SMB2_TREE_CONNECT 0x0003 -#define SMB2_TREE_DISCONNECT 0x0004 -#define SMB2_CREATE 0x0005 -#define SMB2_CLOSE 0x0006 -#define SMB2_FLUSH 0x0007 -#define SMB2_READ 0x0008 -#define SMB2_WRITE 0x0009 -#define SMB2_LOCK 0x000A -#define SMB2_IOCTL 0x000B -#define SMB2_CANCEL 0x000C -#define SMB2_ECHO 0x000D -#define SMB2_QUERY_DIRECTORY 0x000E -#define SMB2_CHANGE_NOTIFY 0x000F -#define SMB2_QUERY_INFO 0x0010 -#define SMB2_SET_INFO 0x0011 -#define SMB2_OPLOCK_BREAK 0x0012 - -void RegisterSMB2Parsers(void); -void SMB2ParserRegisterTests(void); - -#endif /* __APP_LAYER_SMB2_H__ */ - diff --git a/framework/src/suricata/src/app-layer-smtp.c b/framework/src/suricata/src/app-layer-smtp.c deleted file mode 100644 index cd0a732e..00000000 --- a/framework/src/suricata/src/app-layer-smtp.c +++ /dev/null @@ -1,5025 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata.h" -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer.h" -#include "app-layer-detect-proto.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-smtp.h" - -#include "util-mpm.h" -#include "util-debug.h" -#include "util-byte.h" -#include "util-unittest.h" -#include "util-byte.h" -#include "util-unittest-helper.h" -#include "util-memcmp.h" -#include "flow-util.h" - -#include "detect-engine.h" -#include "detect-engine-state.h" -#include "detect-parse.h" - -#include "decode-events.h" -#include "conf.h" - -#include "util-mem.h" -#include "util-misc.h" - -/* content-limit default value */ -#define FILEDATA_CONTENT_LIMIT 1000 -/* content-inspect-min-size default value */ -#define FILEDATA_CONTENT_INSPECT_MIN_SIZE 1000 -/* content-inspect-window default value */ -#define FILEDATA_CONTENT_INSPECT_WINDOW 1000 - -#define SMTP_MAX_REQUEST_AND_REPLY_LINE_LENGTH 510 - -#define SMTP_COMMAND_BUFFER_STEPS 5 - -/* we are in process of parsing a fresh command. Just a placeholder. If we - * are not in STATE_COMMAND_DATA_MODE, we have to be in this mode */ -#define SMTP_PARSER_STATE_COMMAND_MODE 0x00 -/* we are in mode of parsing a command's data. Used when we are parsing tls - * or accepting the rfc 2822 mail after DATA command */ -#define SMTP_PARSER_STATE_COMMAND_DATA_MODE 0x01 -/* Used when we are still in the process of parsing a server command. Used - * with multi-line replies and the stream is fragmented before all the lines - * for a response is seen */ -#define SMTP_PARSER_STATE_PARSING_SERVER_RESPONSE 0x02 -/* Used to indicate that the parser has seen the first reply */ -#define SMTP_PARSER_STATE_FIRST_REPLY_SEEN 0x04 -/* Used to indicate that the parser is parsing a multiline reply */ -#define SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY 0x08 - -/* Various SMTP commands - * We currently have var-ified just STARTTLS and DATA, since we need to them - * for state transitions. The rest are just indicate as OTHER_CMD. Other - * commands would be introduced as and when needed */ -#define SMTP_COMMAND_STARTTLS 1 -#define SMTP_COMMAND_DATA 2 -#define SMTP_COMMAND_BDAT 3 -/* not an actual command per se, but the mode where we accept the mail after - * DATA has it's own reply code for completion, from the server. We give this - * stage a pseudo command of it's own, so that we can add this to the command - * buffer to match with the reply */ -#define SMTP_COMMAND_DATA_MODE 4 -/* All other commands are represented by this var */ -#define SMTP_COMMAND_OTHER_CMD 5 - -/* Different EHLO extensions. Not used now. */ -#define SMTP_EHLO_EXTENSION_PIPELINING -#define SMTP_EHLO_EXTENSION_SIZE -#define SMTP_EHLO_EXTENSION_DSN -#define SMTP_EHLO_EXTENSION_STARTTLS -#define SMTP_EHLO_EXTENSION_8BITMIME - -SCEnumCharMap smtp_decoder_event_table[ ] = { - { "INVALID_REPLY", SMTP_DECODER_EVENT_INVALID_REPLY }, - { "UNABLE_TO_MATCH_REPLY_WITH_REQUEST", - SMTP_DECODER_EVENT_UNABLE_TO_MATCH_REPLY_WITH_REQUEST }, - { "MAX_COMMAND_LINE_LEN_EXCEEDED", - SMTP_DECODER_EVENT_MAX_COMMAND_LINE_LEN_EXCEEDED }, - { "MAX_REPLY_LINE_LEN_EXCEEDED", - SMTP_DECODER_EVENT_MAX_REPLY_LINE_LEN_EXCEEDED }, - { "INVALID_PIPELINED_SEQUENCE", - SMTP_DECODER_EVENT_INVALID_PIPELINED_SEQUENCE }, - { "BDAT_CHUNK_LEN_EXCEEDED", - SMTP_DECODER_EVENT_BDAT_CHUNK_LEN_EXCEEDED }, - { "NO_SERVER_WELCOME_MESSAGE", - SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE }, - { "TLS_REJECTED", - SMTP_DECODER_EVENT_TLS_REJECTED }, - { "DATA_COMMAND_REJECTED", - SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED }, - - /* MIME Events */ - { "MIME_PARSE_FAILED", - SMTP_DECODER_EVENT_MIME_PARSE_FAILED }, - { "MIME_MALFORMED_MSG", - SMTP_DECODER_EVENT_MIME_MALFORMED_MSG }, - { "MIME_INVALID_BASE64", - SMTP_DECODER_EVENT_MIME_INVALID_BASE64 }, - { "MIME_INVALID_QP", - SMTP_DECODER_EVENT_MIME_INVALID_QP }, - { "MIME_LONG_LINE", - SMTP_DECODER_EVENT_MIME_LONG_LINE }, - { "MIME_LONG_ENC_LINE", - SMTP_DECODER_EVENT_MIME_LONG_ENC_LINE }, - { "MIME_LONG_HEADER_NAME", - SMTP_DECODER_EVENT_MIME_LONG_HEADER_NAME }, - { "MIME_LONG_HEADER_VALUE", - SMTP_DECODER_EVENT_MIME_LONG_HEADER_VALUE }, - { "MIME_LONG_BOUNDARY", - SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG }, - - { NULL, -1 }, -}; - -#define SMTP_MPM DEFAULT_MPM - -static MpmCtx *smtp_mpm_ctx = NULL; -MpmThreadCtx *smtp_mpm_thread_ctx; - -/* smtp reply codes. If an entry is made here, please make a simultaneous - * entry in smtp_reply_map */ -enum { - SMTP_REPLY_211, - SMTP_REPLY_214, - SMTP_REPLY_220, - SMTP_REPLY_221, - SMTP_REPLY_235, - SMTP_REPLY_250, - SMTP_REPLY_251, - SMTP_REPLY_252, - - SMTP_REPLY_334, - SMTP_REPLY_354, - - SMTP_REPLY_421, - SMTP_REPLY_450, - SMTP_REPLY_451, - SMTP_REPLY_452, - SMTP_REPLY_455, - - SMTP_REPLY_500, - SMTP_REPLY_501, - SMTP_REPLY_502, - SMTP_REPLY_503, - SMTP_REPLY_504, - SMTP_REPLY_550, - SMTP_REPLY_551, - SMTP_REPLY_552, - SMTP_REPLY_553, - SMTP_REPLY_554, - SMTP_REPLY_555, -}; - -SCEnumCharMap smtp_reply_map[ ] = { - { "211", SMTP_REPLY_211 }, - { "214", SMTP_REPLY_214 }, - { "220", SMTP_REPLY_220 }, - { "221", SMTP_REPLY_221 }, - { "235", SMTP_REPLY_235 }, - { "250", SMTP_REPLY_250 }, - { "251", SMTP_REPLY_251 }, - { "252", SMTP_REPLY_252 }, - - { "334", SMTP_REPLY_334 }, - { "354", SMTP_REPLY_354 }, - - { "421", SMTP_REPLY_421 }, - { "450", SMTP_REPLY_450 }, - { "451", SMTP_REPLY_451 }, - { "452", SMTP_REPLY_452 }, - { "455", SMTP_REPLY_455 }, - - { "500", SMTP_REPLY_500 }, - { "501", SMTP_REPLY_501 }, - { "502", SMTP_REPLY_502 }, - { "503", SMTP_REPLY_503 }, - { "504", SMTP_REPLY_504 }, - { "550", SMTP_REPLY_550 }, - { "551", SMTP_REPLY_551 }, - { "552", SMTP_REPLY_552 }, - { "553", SMTP_REPLY_553 }, - { "554", SMTP_REPLY_554 }, - { "555", SMTP_REPLY_555 }, - { NULL, -1 }, -}; - -/* Create SMTP config structure */ -SMTPConfig smtp_config = { 0, { 0, 0, 0, 0, 0 }, 0, 0, 0}; - -static SMTPString *SMTPStringAlloc(void); - -/** - * \brief Configure SMTP Mime Decoder by parsing out mime section of YAML - * config file - * - * \return none - */ -static void SMTPConfigure(void) { - - SCEnter(); - int ret = 0, val; - intmax_t imval; - uint32_t content_limit = 0; - uint32_t content_inspect_min_size = 0; - uint32_t content_inspect_window = 0; - - ConfNode *config = ConfGetNode("app-layer.protocols.smtp.mime"); - if (config != NULL) { - - ret = ConfGetChildValueBool(config, "decode-mime", &val); - if (ret) { - smtp_config.decode_mime = val; - } - - ret = ConfGetChildValueBool(config, "decode-base64", &val); - if (ret) { - smtp_config.mime_config.decode_base64 = val; - } - - ret = ConfGetChildValueBool(config, "decode-quoted-printable", &val); - if (ret) { - smtp_config.mime_config.decode_quoted_printable = val; - } - - ret = ConfGetChildValueInt(config, "header-value-depth", &imval); - if (ret) { - smtp_config.mime_config.header_value_depth = (uint32_t) imval; - } - - ret = ConfGetChildValueBool(config, "extract-urls", &val); - if (ret) { - smtp_config.mime_config.extract_urls = val; - } - - ret = ConfGetChildValueBool(config, "body-md5", &val); - if (ret) { - smtp_config.mime_config.body_md5 = val; - } - } - - /* Pass mime config data to MimeDec API */ - MimeDecSetConfig(&smtp_config.mime_config); - - ConfNode *t = ConfGetNode("app-layer.protocols.smtp.inspected-tracker"); - ConfNode *p = NULL; - - if (t == NULL) - return; - - TAILQ_FOREACH(p, &t->head, next) { - if (strcasecmp("content-limit", p->name) == 0) { - if (ParseSizeStringU32(p->val, &content_limit) < 0) { - SCLogWarning(SC_ERR_SIZE_PARSE, "Error parsing content-limit " - "from conf file - %s. Killing engine", p->val); - content_limit = FILEDATA_CONTENT_LIMIT; - } - } - - if (strcasecmp("content-inspect-min-size", p->name) == 0) { - if (ParseSizeStringU32(p->val, &content_inspect_min_size) < 0) { - SCLogWarning(SC_ERR_SIZE_PARSE, "Error parsing content-inspect-min-size-limit " - "from conf file - %s. Killing engine", p->val); - content_inspect_min_size = FILEDATA_CONTENT_INSPECT_MIN_SIZE; - } - } - - if (strcasecmp("content-inspect-window", p->name) == 0) { - if (ParseSizeStringU32(p->val, &content_inspect_window) < 0) { - SCLogWarning(SC_ERR_SIZE_PARSE, "Error parsing content-inspect-window " - "from conf file - %s. Killing engine", p->val); - content_inspect_window = FILEDATA_CONTENT_INSPECT_WINDOW; - } - } - } - - SCReturn; -} - -void SMTPSetEvent(SMTPState *s, uint8_t e) -{ - SCLogDebug("setting event %u", e); - - if (s->curr_tx != NULL) { - AppLayerDecoderEventsSetEventRaw(&s->curr_tx->decoder_events, e); -// s->events++; - return; - } - SCLogDebug("couldn't set event %u", e); -} - -static SMTPTransaction *SMTPTransactionCreate(void) -{ - SMTPTransaction *tx = SCCalloc(1, sizeof(*tx)); - if (tx == NULL) { - return NULL; - } - - TAILQ_INIT(&tx->rcpt_to_list); - tx->mime_state = NULL; - return tx; -} - -int SMTPProcessDataChunk(const uint8_t *chunk, uint32_t len, - MimeDecParseState *state) { - - int ret = MIME_DEC_OK; - Flow *flow = (Flow *) state->data; - SMTPState *smtp_state = (SMTPState *) flow->alstate; - MimeDecEntity *entity = (MimeDecEntity *) state->stack->top->data; - FileContainer *files = NULL; - uint16_t flags = 0; - - /* Set flags */ - if (flow->flags & FLOW_FILE_NO_STORE_TS) { - flags |= FILE_NOSTORE; - } - - if (flow->flags & FLOW_FILE_NO_MAGIC_TS) { - flags |= FILE_NOMAGIC; - } - - if (flow->flags & FLOW_FILE_NO_MD5_TS) { - flags |= FILE_NOMD5; - } - - /* Determine whether to process files */ - if ((flags & (FILE_NOSTORE | FILE_NOMAGIC | FILE_NOMD5)) == - (FILE_NOSTORE | FILE_NOMAGIC | FILE_NOMD5)) { - SCLogDebug("File content ignored"); - return 0; - } - - /* Find file */ - if (entity->ctnt_flags & CTNT_IS_ATTACHMENT) { - - /* Make sure file container allocated */ - if (smtp_state->files_ts == NULL) { - smtp_state->files_ts = FileContainerAlloc(); - if (smtp_state->files_ts == NULL) { - ret = MIME_DEC_ERR_MEM; - SCLogError(SC_ERR_MEM_ALLOC, "Could not create file container"); - SCReturnInt(ret); - } - } - files = smtp_state->files_ts; - - /* Open file if necessary */ - if (state->body_begin) { - - if (SCLogDebugEnabled()) { - SCLogDebug("Opening file...%u bytes", len); - printf("File - "); - for (uint32_t i = 0; i < entity->filename_len; i++) { - printf("%c", entity->filename[i]); - } - printf("\n"); - } - - /* Set storage flag if applicable since only the first file in the - * flow seems to be processed by the 'filestore' detector */ - if (files->head != NULL && (files->head->flags & FILE_STORE)) { - flags |= FILE_STORE; - } - - if (FileOpenFile(files, (uint8_t *) entity->filename, entity->filename_len, - (uint8_t *) chunk, len, flags) == NULL) { - ret = MIME_DEC_ERR_DATA; - SCLogDebug("FileOpenFile() failed"); - } - - /* If close in the same chunk, then pass in empty bytes */ - if (state->body_end) { - - SCLogDebug("Closing file...%u bytes", len); - - if (files->tail->state == FILE_STATE_OPENED) { - ret = FileCloseFile(files, (uint8_t *) NULL, 0, flags); - if (ret != 0) { - SCLogDebug("FileCloseFile() failed: %d", ret); - ret = MIME_DEC_ERR_DATA; - } - } else { - SCLogDebug("File already closed"); - } - } - } else if (state->body_end) { - /* Close file */ - SCLogDebug("Closing file...%u bytes", len); - - if (files && files->tail && files->tail->state == FILE_STATE_OPENED) { - ret = FileCloseFile(files, (uint8_t *) chunk, len, flags); - if (ret != 0) { - SCLogDebug("FileCloseFile() failed: %d", ret); - ret = MIME_DEC_ERR_DATA; - } - } else { - SCLogDebug("File already closed"); - } - } else { - /* Append data chunk to file */ - SCLogDebug("Appending file...%u bytes", len); - - /* 0 is ok, -2 is not stored, -1 is error */ - ret = FileAppendData(files, (uint8_t *) chunk, len); - if (ret == -2) { - ret = 0; - SCLogDebug("FileAppendData() - file no longer being extracted"); - } else if (ret < 0) { - SCLogDebug("FileAppendData() failed: %d", ret); - ret = MIME_DEC_ERR_DATA; - } - } - - if (ret == 0) { - SCLogDebug("Successfully processed file data!"); - } - } else { - SCLogDebug("Body not a Ctnt_attachment"); - } - - if (files != NULL) { - FilePrune(files); - } - - SCReturnInt(ret); -} - -/** - * \internal - * \brief Get the next line from input. It doesn't do any length validation. - * - * \param state The smtp state. - * - * \retval 0 On suceess. - * \retval -1 Either when we don't have any new lines to supply anymore or - * on failure. - */ -static int SMTPGetLine(SMTPState *state) -{ - SCEnter(); - void *ptmp; - - /* we have run out of input */ - if (state->input_len <= 0) - return -1; - - /* toserver */ - if (state->direction == 0) { - if (state->ts_current_line_lf_seen == 1) { - /* we have seen the lf for the previous line. Clear the parser - * details to parse new line */ - state->ts_current_line_lf_seen = 0; - if (state->ts_current_line_db == 1) { - state->ts_current_line_db = 0; - SCFree(state->ts_db); - state->ts_db = NULL; - state->ts_db_len = 0; - state->current_line = NULL; - state->current_line_len = 0; - } - } - - uint8_t *lf_idx = memchr(state->input, 0x0a, state->input_len); - - if (lf_idx == NULL) { - /* fragmented lines. Decoder event for special cases. Not all - * fragmented lines should be treated as a possible evasion - * attempt. With multi payload smtp chunks we can have valid - * cases of fragmentation. But within the same segment chunk - * if we see fragmentation then it's definitely something you - * should alert about */ - if (state->ts_current_line_db == 0) { - state->ts_db = SCMalloc(state->input_len); - if (state->ts_db == NULL) { - return -1; - } - state->ts_current_line_db = 1; - memcpy(state->ts_db, state->input, state->input_len); - state->ts_db_len = state->input_len; - } else { - ptmp = SCRealloc(state->ts_db, - (state->ts_db_len + state->input_len)); - if (ptmp == NULL) { - SCFree(state->ts_db); - state->ts_db = NULL; - state->ts_db_len = 0; - return -1; - } - state->ts_db = ptmp; - - memcpy(state->ts_db + state->ts_db_len, - state->input, state->input_len); - state->ts_db_len += state->input_len; - } /* else */ - state->input += state->input_len; - state->input_len = 0; - - return -1; - - } else { - state->ts_current_line_lf_seen = 1; - - if (state->ts_current_line_db == 1) { - ptmp = SCRealloc(state->ts_db, - (state->ts_db_len + (lf_idx + 1 - state->input))); - if (ptmp == NULL) { - SCFree(state->ts_db); - state->ts_db = NULL; - state->ts_db_len = 0; - return -1; - } - state->ts_db = ptmp; - - memcpy(state->ts_db + state->ts_db_len, - state->input, (lf_idx + 1 - state->input)); - state->ts_db_len += (lf_idx + 1 - state->input); - - if (state->ts_db_len > 1 && - state->ts_db[state->ts_db_len - 2] == 0x0D) { - state->ts_db_len -= 2; - state->current_line_delimiter_len = 2; - } else { - state->ts_db_len -= 1; - state->current_line_delimiter_len = 1; - } - - state->current_line = state->ts_db; - state->current_line_len = state->ts_db_len; - - } else { - state->current_line = state->input; - state->current_line_len = lf_idx - state->input; - - if (state->input != lf_idx && - *(lf_idx - 1) == 0x0D) { - state->current_line_len--; - state->current_line_delimiter_len = 2; - } else { - state->current_line_delimiter_len = 1; - } - } - - state->input_len -= (lf_idx - state->input) + 1; - state->input = (lf_idx + 1); - - return 0; - } - - /* toclient */ - } else { - if (state->tc_current_line_lf_seen == 1) { - /* we have seen the lf for the previous line. Clear the parser - * details to parse new line */ - state->tc_current_line_lf_seen = 0; - if (state->tc_current_line_db == 1) { - state->tc_current_line_db = 0; - SCFree(state->tc_db); - state->tc_db = NULL; - state->tc_db_len = 0; - state->current_line = NULL; - state->current_line_len = 0; - } - } - - uint8_t *lf_idx = memchr(state->input, 0x0a, state->input_len); - - if (lf_idx == NULL) { - /* fragmented lines. Decoder event for special cases. Not all - * fragmented lines should be treated as a possible evasion - * attempt. With multi payload smtp chunks we can have valid - * cases of fragmentation. But within the same segment chunk - * if we see fragmentation then it's definitely something you - * should alert about */ - if (state->tc_current_line_db == 0) { - state->tc_db = SCMalloc(state->input_len); - if (state->tc_db == NULL) { - return -1; - } - state->tc_current_line_db = 1; - memcpy(state->tc_db, state->input, state->input_len); - state->tc_db_len = state->input_len; - } else { - ptmp = SCRealloc(state->tc_db, - (state->tc_db_len + state->input_len)); - if (ptmp == NULL) { - SCFree(state->tc_db); - state->tc_db = NULL; - state->tc_db_len = 0; - return -1; - } - state->tc_db = ptmp; - - memcpy(state->tc_db + state->tc_db_len, - state->input, state->input_len); - state->tc_db_len += state->input_len; - } /* else */ - state->input += state->input_len; - state->input_len = 0; - - return -1; - - } else { - state->tc_current_line_lf_seen = 1; - - if (state->tc_current_line_db == 1) { - ptmp = SCRealloc(state->tc_db, - (state->tc_db_len + (lf_idx + 1 - state->input))); - if (ptmp == NULL) { - SCFree(state->tc_db); - state->tc_db = NULL; - state->tc_db_len = 0; - return -1; - } - state->tc_db = ptmp; - - memcpy(state->tc_db + state->tc_db_len, - state->input, (lf_idx + 1 - state->input)); - state->tc_db_len += (lf_idx + 1 - state->input); - - if (state->tc_db_len > 1 && - state->tc_db[state->tc_db_len - 2] == 0x0D) { - state->tc_db_len -= 2; - state->current_line_delimiter_len = 2; - } else { - state->tc_db_len -= 1; - state->current_line_delimiter_len = 1; - } - - state->current_line = state->tc_db; - state->current_line_len = state->tc_db_len; - - } else { - state->current_line = state->input; - state->current_line_len = lf_idx - state->input; - - if (state->input != lf_idx && - *(lf_idx - 1) == 0x0D) { - state->current_line_len--; - state->current_line_delimiter_len = 2; - } else { - state->current_line_delimiter_len = 1; - } - } - - state->input_len -= (lf_idx - state->input) + 1; - state->input = (lf_idx + 1); - - return 0; - } /* else - if (lf_idx == NULL) */ - } - -} - -static int SMTPInsertCommandIntoCommandBuffer(uint8_t command, SMTPState *state, Flow *f) -{ - SCEnter(); - void *ptmp; - - if (state->cmds_cnt >= state->cmds_buffer_len) { - int increment = SMTP_COMMAND_BUFFER_STEPS; - if ((int)(state->cmds_buffer_len + SMTP_COMMAND_BUFFER_STEPS) > (int)USHRT_MAX) { - increment = USHRT_MAX - state->cmds_buffer_len; - } - - ptmp = SCRealloc(state->cmds, - sizeof(uint8_t) * (state->cmds_buffer_len + increment)); - if (ptmp == NULL) { - SCFree(state->cmds); - state->cmds = NULL; - SCLogDebug("SCRealloc failure"); - return -1; - } - state->cmds = ptmp; - - state->cmds_buffer_len += increment; - } - if (state->cmds_cnt >= 1 && - ((state->cmds[state->cmds_cnt - 1] == SMTP_COMMAND_STARTTLS) || - (state->cmds[state->cmds_cnt - 1] == SMTP_COMMAND_DATA))) { - /* decoder event */ - SMTPSetEvent(state, SMTP_DECODER_EVENT_INVALID_PIPELINED_SEQUENCE); - /* we have to have EHLO, DATA, VRFY, EXPN, TURN, QUIT, NOOP, - * STARTTLS as the last command in pipelined mode */ - } - - /** \todo decoder event */ - if ((int)(state->cmds_cnt + 1) > (int)USHRT_MAX) { - SCLogDebug("command buffer overflow"); - return -1; - } - - state->cmds[state->cmds_cnt] = command; - state->cmds_cnt++; - - return 0; -} - -static int SMTPProcessCommandBDAT(SMTPState *state, Flow *f, - AppLayerParserState *pstate) -{ - SCEnter(); - - state->bdat_chunk_idx += (state->current_line_len + - state->current_line_delimiter_len); - if (state->bdat_chunk_idx > state->bdat_chunk_len) { - state->parser_state &= ~SMTP_PARSER_STATE_COMMAND_DATA_MODE; - /* decoder event */ - SMTPSetEvent(state, SMTP_DECODER_EVENT_BDAT_CHUNK_LEN_EXCEEDED); - SCReturnInt(-1); - } else if (state->bdat_chunk_idx == state->bdat_chunk_len) { - state->parser_state &= ~SMTP_PARSER_STATE_COMMAND_DATA_MODE; - } - - SCReturnInt(0); -} - -static int SMTPProcessCommandDATA(SMTPState *state, Flow *f, - AppLayerParserState *pstate) -{ - SCEnter(); - - if (!(state->parser_state & SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - /* looks like are still waiting for a confirmination from the server */ - return 0; - } - - if (state->current_line_len == 1 && state->current_line[0] == '.') { - state->parser_state &= ~SMTP_PARSER_STATE_COMMAND_DATA_MODE; - /* kinda like a hack. The mail sent in DATA mode, would be - * acknowledged with a reply. We insert a dummy command to - * the command buffer to be used by the reply handler to match - * the reply received */ - SMTPInsertCommandIntoCommandBuffer(SMTP_COMMAND_DATA_MODE, state, f); - - if (smtp_config.decode_mime) { - /* Complete parsing task */ - int ret = MimeDecParseComplete(state->curr_tx->mime_state); - if (ret != MIME_DEC_OK) { - - SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_PARSE_FAILED); - SCLogDebug("MimeDecParseComplete() function failed"); - } - - /* Generate decoder events */ - MimeDecEntity *msg = state->curr_tx->mime_state->msg; - if (msg->anomaly_flags & ANOM_INVALID_BASE64) { - SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_INVALID_BASE64); - } - if (msg->anomaly_flags & ANOM_INVALID_QP) { - SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_INVALID_QP); - } - if (msg->anomaly_flags & ANOM_LONG_LINE) { - SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_LONG_LINE); - } - if (msg->anomaly_flags & ANOM_LONG_ENC_LINE) { - SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_LONG_ENC_LINE); - } - if (msg->anomaly_flags & ANOM_LONG_HEADER_NAME) { - SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_LONG_HEADER_NAME); - } - if (msg->anomaly_flags & ANOM_LONG_HEADER_VALUE) { - SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_LONG_HEADER_VALUE); - } - if (msg->anomaly_flags & ANOM_MALFORMED_MSG) { - SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_MALFORMED_MSG); - } - if (msg->anomaly_flags & ANOM_LONG_BOUNDARY) { - SMTPSetEvent(state, SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG); - } - } - state->curr_tx->done = 1; - SCLogDebug("marked tx as done"); - } - - /* If DATA, then parse out a MIME message */ - if (state->current_command == SMTP_COMMAND_DATA && - (state->parser_state & SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - - if (smtp_config.decode_mime && state->curr_tx->mime_state) { - int ret = MimeDecParseLine((const uint8_t *) state->current_line, - state->current_line_len, state->current_line_delimiter_len, - state->curr_tx->mime_state); - if (ret != MIME_DEC_OK) { - SCLogDebug("MimeDecParseLine() function returned an error code: %d", ret); - } - } - } - - return 0; -} - -static int SMTPProcessCommandSTARTTLS(SMTPState *state, Flow *f, - AppLayerParserState *pstate) -{ - return 0; -} - -static int SMTPProcessReply(SMTPState *state, Flow *f, - AppLayerParserState *pstate) -{ - SCEnter(); - - uint64_t reply_code = 0; - PatternMatcherQueue *pmq = state->thread_local_data; - - /* the reply code has to contain at least 3 bytes, to hold the 3 digit - * reply code */ - if (state->current_line_len < 3) { - /* decoder event */ - SMTPSetEvent(state, SMTP_DECODER_EVENT_INVALID_REPLY); - return -1; - } - - if (state->current_line_len >= 4) { - if (state->parser_state & SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY) { - if (state->current_line[3] != '-') { - state->parser_state &= ~SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY; - } - } else { - if (state->current_line[3] == '-') { - state->parser_state |= SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY; - } - } - } else { - if (state->parser_state & SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY) { - state->parser_state &= ~SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY; - } - } - - /* I don't like this pmq reset here. We'll devise a method later, that - * should make the use of the mpm very efficient */ - PmqReset(pmq); - int mpm_cnt = mpm_table[SMTP_MPM].Search(smtp_mpm_ctx, smtp_mpm_thread_ctx, - pmq, state->current_line, - 3); - if (mpm_cnt == 0) { - /* set decoder event - reply code invalid */ - SMTPSetEvent(state, SMTP_DECODER_EVENT_INVALID_REPLY); - SCLogDebug("invalid reply code %02x %02x %02x", - state->current_line[0], state->current_line[1], state->current_line[2]); - SCReturnInt(-1); - } - reply_code = smtp_reply_map[pmq->pattern_id_array[0]].enum_value; - - if (state->cmds_idx == state->cmds_cnt) { - if (!(state->parser_state & SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - /* the first server reply can be a multiline message. Let's - * flag the fact that we have seen the first reply only at the end - * of a multiline reply - */ - if (!(state->parser_state & SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY)) - state->parser_state |= SMTP_PARSER_STATE_FIRST_REPLY_SEEN; - if (reply_code == SMTP_REPLY_220) - SCReturnInt(0); - else - SMTPSetEvent(state, SMTP_DECODER_EVENT_INVALID_REPLY); - } else { - /* decoder event - unable to match reply with request */ - SCLogDebug("unable to match reply with request"); - SCReturnInt(-1); - } - } - - if (state->cmds_cnt == 0) { - /* reply but not a command we have stored, fall through */ - } else if (state->cmds[state->cmds_idx] == SMTP_COMMAND_STARTTLS) { - if (reply_code == SMTP_REPLY_220) { - /* we are entering STARRTTLS data mode */ - state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE; - AppLayerParserStateSetFlag(pstate, - APP_LAYER_PARSER_NO_INSPECTION | - APP_LAYER_PARSER_NO_REASSEMBLY); - } else { - /* decoder event */ - SMTPSetEvent(state, SMTP_DECODER_EVENT_TLS_REJECTED); - } - } else if (state->cmds[state->cmds_idx] == SMTP_COMMAND_DATA) { - if (reply_code == SMTP_REPLY_354) { - /* Next comes the mail for the DATA command in toserver direction */ - state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE; - } else { - /* decoder event */ - SMTPSetEvent(state, SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED); - } - } else { - /* we don't care for any other command for now */ - /* check if reply falls in the valid list of replies for SMTP. If not - * decoder event */ - } - - /* if it is a multi-line reply, we need to move the index only once for all - * the line of the reply. We unset the multiline flag on the last - * line of the multiline reply, following which we increment the index */ - if (!(state->parser_state & SMTP_PARSER_STATE_PARSING_MULTILINE_REPLY)) { - state->cmds_idx++; - } - - /* if we have matched all the buffered commands, reset the cnt and index */ - if (state->cmds_idx == state->cmds_cnt) { - state->cmds_cnt = 0; - state->cmds_idx = 0; - } - - return 0; -} - -static int SMTPParseCommandBDAT(SMTPState *state) -{ - SCEnter(); - - int i = 4; - while (i < state->current_line_len) { - if (state->current_line[i] != ' ') { - break; - } - i++; - } - if (i == 4) { - /* decoder event */ - return -1; - } - if (i == state->current_line_len) { - /* decoder event */ - return -1; - } - char *endptr = NULL; - state->bdat_chunk_len = strtoul((const char *)state->current_line + i, - (char **)&endptr, 10); - if ((uint8_t *)endptr == state->current_line + i) { - /* decoder event */ - return -1; - } - - return 0; -} - -static int SMTPParseCommandWithParam(SMTPState *state, uint8_t prefix_len, uint8_t **target, uint16_t *target_len) -{ - int i = prefix_len + 1; - int spc_i = 0; - - while (i < state->current_line_len) { - if (state->current_line[i] != ' ') { - break; - } - i++; - } - - /* rfc1870: with the size extension the mail from can be followed by an option. - We use the space separator to detect it. */ - spc_i = i; - while (spc_i < state->current_line_len) { - if (state->current_line[spc_i] == ' ') { - break; - } - spc_i++; - } - - *target = SCMalloc(spc_i - i + 1); - if (*target == NULL) - return -1; - memcpy(*target, state->current_line + i, spc_i - i); - (*target)[spc_i - i] = '\0'; - *target_len = spc_i - i; - - return 0; -} - -static int SMTPParseCommandHELO(SMTPState *state) -{ - return SMTPParseCommandWithParam(state, 4, &state->helo, &state->helo_len); -} - -static int SMTPParseCommandMAILFROM(SMTPState *state) -{ - return SMTPParseCommandWithParam(state, 9, - &state->curr_tx->mail_from, - &state->curr_tx->mail_from_len); -} - -static int SMTPParseCommandRCPTTO(SMTPState *state) -{ - uint8_t *rcptto; - uint16_t rcptto_len; - - if (SMTPParseCommandWithParam(state, 7, &rcptto, &rcptto_len) == 0) { - SMTPString *rcptto_str = SMTPStringAlloc(); - if (rcptto_str) { - rcptto_str->str = rcptto; - rcptto_str->len = rcptto_len; - TAILQ_INSERT_TAIL(&state->curr_tx->rcpt_to_list, rcptto_str, next); - } else { - SCFree(rcptto); - return -1; - } - } else { - return -1; - } - return 0; -} - -/* consider 'rset' and 'quit' to be part of the existing state */ -static int NoNewTx(SMTPState *state) -{ - if (!(state->parser_state & SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - if (state->current_line_len >= 4 && - SCMemcmpLowercase("rset", state->current_line, 4) == 0) { - return 1; - } else if (state->current_line_len >= 4 && - SCMemcmpLowercase("quit", state->current_line, 4) == 0) { - return 1; - } - } - return 0; -} - -static int SMTPProcessRequest(SMTPState *state, Flow *f, - AppLayerParserState *pstate) -{ - SCEnter(); - SMTPTransaction *tx = state->curr_tx; - - if (state->curr_tx == NULL || (state->curr_tx->done && !NoNewTx(state))) { - tx = SMTPTransactionCreate(); - if (tx == NULL) - return -1; - state->curr_tx = tx; - TAILQ_INSERT_TAIL(&state->tx_list, tx, next); - tx->tx_id = state->tx_cnt++; - } - - if (!(state->parser_state & SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - SMTPSetEvent(state, SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE); - } - - /* there are 2 commands that can push it into this COMMAND_DATA mode - - * STARTTLS and DATA */ - if (!(state->parser_state & SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - int r = 0; - - if (state->current_line_len >= 8 && - SCMemcmpLowercase("starttls", state->current_line, 8) == 0) { - state->current_command = SMTP_COMMAND_STARTTLS; - } else if (state->current_line_len >= 4 && - SCMemcmpLowercase("data", state->current_line, 4) == 0) { - state->current_command = SMTP_COMMAND_DATA; - if (smtp_config.decode_mime) { - tx->mime_state = MimeDecInitParser(f, SMTPProcessDataChunk); - if (tx->mime_state == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "MimeDecInitParser() failed to " - "allocate data"); - return MIME_DEC_ERR_MEM; - } - - /* Add new MIME message to end of list */ - if (tx->msg_head == NULL) { - tx->msg_head = tx->mime_state->msg; - tx->msg_tail = tx->mime_state->msg; - } - else { - tx->msg_tail->next = tx->mime_state->msg; - tx->msg_tail = tx->mime_state->msg; - } - } - - } else if (state->current_line_len >= 4 && - SCMemcmpLowercase("bdat", state->current_line, 4) == 0) { - r = SMTPParseCommandBDAT(state); - if (r == -1) { - SCReturnInt(-1); - } - state->current_command = SMTP_COMMAND_BDAT; - state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE; - } else if (state->current_line_len >= 4 && - ((SCMemcmpLowercase("helo", state->current_line, 4) == 0) || - SCMemcmpLowercase("ehlo", state->current_line, 4) == 0)) { - r = SMTPParseCommandHELO(state); - if (r == -1) { - SCReturnInt(-1); - } - state->current_command = SMTP_COMMAND_OTHER_CMD; - } else if (state->current_line_len >= 9 && - SCMemcmpLowercase("mail from", state->current_line, 9) == 0) { - r = SMTPParseCommandMAILFROM(state); - if (r == -1) { - SCReturnInt(-1); - } - state->current_command = SMTP_COMMAND_OTHER_CMD; - } else if (state->current_line_len >= 7 && - SCMemcmpLowercase("rcpt to", state->current_line, 7) == 0) { - r = SMTPParseCommandRCPTTO(state); - if (r == -1) { - SCReturnInt(-1); - } - state->current_command = SMTP_COMMAND_OTHER_CMD; - } else { - state->current_command = SMTP_COMMAND_OTHER_CMD; - } - - /* Every command is inserted into a command buffer, to be matched - * against reply(ies) sent by the server */ - if (SMTPInsertCommandIntoCommandBuffer(state->current_command, - state, f) == -1) { - SCReturnInt(-1); - } - - SCReturnInt(r); - } - - switch (state->current_command) { - case SMTP_COMMAND_STARTTLS: - return SMTPProcessCommandSTARTTLS(state, f, pstate); - - case SMTP_COMMAND_DATA: - return SMTPProcessCommandDATA(state, f, pstate); - - case SMTP_COMMAND_BDAT: - return SMTPProcessCommandBDAT(state, f, pstate); - - default: - /* we have nothing to do with any other command at this instant. - * Just let it go through */ - SCReturnInt(0); - } -} - -static int SMTPParse(int direction, Flow *f, SMTPState *state, - AppLayerParserState *pstate, uint8_t *input, - uint32_t input_len, - PatternMatcherQueue *local_data) -{ - SCEnter(); - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - state->input = input; - state->input_len = input_len; - state->direction = direction; - state->thread_local_data = local_data; - - /* toserver */ - if (direction == 0) { - while (SMTPGetLine(state) >= 0) { - if (SMTPProcessRequest(state, f, pstate) == -1) - SCReturnInt(-1); - } - - /* toclient */ - } else { - while (SMTPGetLine(state) >= 0) { - if (SMTPProcessReply(state, f, pstate) == -1) - SCReturnInt(-1); - } - } - - SCReturnInt(0); -} - -static int SMTPParseClientRecord(Flow *f, void *alstate, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SCEnter(); - - /* first arg 0 is toserver */ - return SMTPParse(0, f, alstate, pstate, input, input_len, local_data); -} - -static int SMTPParseServerRecord(Flow *f, void *alstate, - AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SCEnter(); - - /* first arg 1 is toclient */ - return SMTPParse(1, f, alstate, pstate, input, input_len, local_data); - - return 0; -} - -/** - * \internal - * \brief Function to allocate SMTP state memory. - */ -void *SMTPStateAlloc(void) -{ - SMTPState *smtp_state = SCMalloc(sizeof(SMTPState)); - if (unlikely(smtp_state == NULL)) - return NULL; - memset(smtp_state, 0, sizeof(SMTPState)); - - smtp_state->cmds = SCMalloc(sizeof(uint8_t) * - SMTP_COMMAND_BUFFER_STEPS); - if (smtp_state->cmds == NULL) { - SCFree(smtp_state); - return NULL; - } - smtp_state->cmds_buffer_len = SMTP_COMMAND_BUFFER_STEPS; - - TAILQ_INIT(&smtp_state->tx_list); - - return smtp_state; -} - -static SMTPString *SMTPStringAlloc(void) -{ - SMTPString *smtp_string = SCMalloc(sizeof(SMTPString)); - if (unlikely(smtp_string == NULL)) - return NULL; - memset(smtp_string, 0, sizeof(SMTPString)); - - return smtp_string; -} - - -static void SMTPStringFree(SMTPString *str) -{ - if (str->str) { - SCFree(str->str); - } - SCFree(str); -} - -static void *SMTPLocalStorageAlloc(void) -{ - /* needed by the mpm */ - PatternMatcherQueue *pmq = SCMalloc(sizeof(PatternMatcherQueue)); - if (unlikely(pmq == NULL)) { - exit(EXIT_FAILURE); - } - PmqSetup(pmq, - sizeof(smtp_reply_map)/sizeof(SCEnumCharMap) - 2); - - return pmq; -} - -static void SMTPLocalStorageFree(void *pmq) -{ - if (pmq != NULL) { - PmqFree(pmq); - SCFree(pmq); - } - - return; -} - -static void SMTPTransactionFree(SMTPTransaction *tx, SMTPState *state) -{ - if (tx->mime_state != NULL) { - MimeDecDeInitParser(tx->mime_state); - } - /* Free list of MIME message recursively */ - MimeDecFreeEntity(tx->msg_head); - - if (tx->decoder_events != NULL) - AppLayerDecoderEventsFreeEvents(&tx->decoder_events); - - if (tx->de_state != NULL) - DetectEngineStateFree(tx->de_state); - - if (tx->mail_from) - SCFree(tx->mail_from); - - SMTPString *str = NULL; - while ((str = TAILQ_FIRST(&tx->rcpt_to_list))) { - TAILQ_REMOVE(&tx->rcpt_to_list, str, next); - SMTPStringFree(str); - } -#if 0 - if (tx->decoder_events->cnt <= smtp_state->events) - smtp_state->events -= tx->decoder_events->cnt; - else - smtp_state->events = 0; -#endif - SCFree(tx); -} - -/** - * \internal - * \brief Function to free SMTP state memory. - */ -static void SMTPStateFree(void *p) -{ - SMTPState *smtp_state = (SMTPState *)p; - - if (smtp_state->cmds != NULL) { - SCFree(smtp_state->cmds); - } - if (smtp_state->ts_current_line_db) { - SCFree(smtp_state->ts_db); - } - if (smtp_state->tc_current_line_db) { - SCFree(smtp_state->tc_db); - } - - if (smtp_state->helo) { - SCFree(smtp_state->helo); - } - - FileContainerFree(smtp_state->files_ts); - - SMTPTransaction *tx = NULL; - while ((tx = TAILQ_FIRST(&smtp_state->tx_list))) { - TAILQ_REMOVE(&smtp_state->tx_list, tx, next); - SMTPTransactionFree(tx, smtp_state); - } - - SCFree(smtp_state); - - return; -} - -static void SMTPSetMpmState(void) -{ - smtp_mpm_ctx = SCMalloc(sizeof(MpmCtx)); - if (unlikely(smtp_mpm_ctx == NULL)) { - exit(EXIT_FAILURE); - } - memset(smtp_mpm_ctx, 0, sizeof(MpmCtx)); - MpmInitCtx(smtp_mpm_ctx, SMTP_MPM); - - smtp_mpm_thread_ctx = SCMalloc(sizeof(MpmThreadCtx)); - if (unlikely(smtp_mpm_thread_ctx == NULL)) { - exit(EXIT_FAILURE); - } - memset(smtp_mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitThreadCtx(smtp_mpm_thread_ctx, SMTP_MPM, 0); - - uint32_t i = 0; - for (i = 0; i < sizeof(smtp_reply_map)/sizeof(SCEnumCharMap) - 1; i++) { - SCEnumCharMap *map = &smtp_reply_map[i]; - /* The third argument is 3, because reply code is always 3 bytes. */ - MpmAddPatternCI(smtp_mpm_ctx, (uint8_t *)map->enum_name, 3, - 0 /* defunct */, 0 /* defunct */, - i /* pattern id */, 0, 0 /* no flags */); - } - - mpm_table[SMTP_MPM].Prepare(smtp_mpm_ctx); -} - -int SMTPStateGetEventInfo(const char *event_name, - int *event_id, AppLayerEventType *event_type) -{ - *event_id = SCMapEnumNameToValue(event_name, smtp_decoder_event_table); - if (*event_id == -1) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " - "smtp's enum map table.", event_name); - /* yes this is fatal */ - return -1; - } - - *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; - - return 0; -} - -static int SMTPRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMTP, - "EHLO", 4, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMTP, - "HELO", 4, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_SMTP, - "QUIT", 4, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - - return 0; -} - -static void SMTPStateTransactionFree (void *state, uint64_t tx_id) -{ - SMTPState *smtp_state = state; - SMTPTransaction *tx = NULL; - TAILQ_FOREACH(tx, &smtp_state->tx_list, next) { - if (tx_id < tx->tx_id) - break; - else if (tx_id > tx->tx_id) - continue; - - if (tx == smtp_state->curr_tx) - smtp_state->curr_tx = NULL; - TAILQ_REMOVE(&smtp_state->tx_list, tx, next); - SMTPTransactionFree(tx, state); - break; - } - - -} - -/** \retval cnt highest tx id */ -static uint64_t SMTPStateGetTxCnt(void *state) -{ - uint64_t cnt = 0; - SMTPState *smtp_state = state; - if (smtp_state) { - cnt = smtp_state->tx_cnt; - } - SCLogDebug("returning %"PRIu64, cnt); - return cnt; -} - -static void *SMTPStateGetTx(void *state, uint64_t id) -{ - SMTPState *smtp_state = state; - if (smtp_state) { - SMTPTransaction *tx = NULL; - - if (smtp_state->curr_tx == NULL) - return NULL; - if (smtp_state->curr_tx->tx_id == id) - return smtp_state->curr_tx; - - TAILQ_FOREACH(tx, &smtp_state->tx_list, next) { - if (tx->tx_id == id) - return tx; - } - } - return NULL; - -} - -static int SMTPStateGetAlstateProgressCompletionStatus(uint8_t direction) { - return 1; -} - -static int SMTPStateGetAlstateProgress(void *vtx, uint8_t direction) -{ - SMTPTransaction *tx = vtx; - return tx->done; -} - -static FileContainer *SMTPStateGetFiles(void *state, uint8_t direction) -{ - if (state == NULL) - return NULL; - - SMTPState *smtp_state = (SMTPState *)state; - - if (direction & STREAM_TOCLIENT) { - SCReturnPtr(NULL, "FileContainer"); - } else { - SCLogDebug("smtp_state->files_ts %p", smtp_state->files_ts); - SCReturnPtr(smtp_state->files_ts, "FileContainer"); - } -} - -static void SMTPStateTruncate(void *state, uint8_t direction) -{ - FileContainer *fc = SMTPStateGetFiles(state, direction); - if (fc != NULL) { - SCLogDebug("truncating stream, closing files in %s direction (container %p)", - direction & STREAM_TOCLIENT ? "STREAM_TOCLIENT" : "STREAM_TOSERVER", fc); - FileTruncateAllOpenFiles(fc); - } -} - -static AppLayerDecoderEvents *SMTPGetEvents(void *state, uint64_t tx_id) -{ - SCLogDebug("get SMTP events for TX %"PRIu64, tx_id); - - SMTPTransaction *tx = SMTPStateGetTx(state, tx_id); - if (tx != NULL) { - return tx->decoder_events; - } - return NULL; -} - -static DetectEngineState *SMTPGetTxDetectState(void *vtx) -{ - SMTPTransaction *tx = (SMTPTransaction *)vtx; - return tx->de_state; -} - -static int SMTPSetTxDetectState(void *state, void *vtx, DetectEngineState *s) -{ - SMTPTransaction *tx = (SMTPTransaction *)vtx; - tx->de_state = s; - return 0; -} - -/** - * \brief Register the SMTP Protocol parser. - */ -void RegisterSMTPParsers(void) -{ - char *proto_name = "smtp"; - - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_SMTP, proto_name); - if (SMTPRegisterPatternsForProtocolDetection() < 0 ) - return; - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol.", - proto_name); - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateAlloc, SMTPStateFree); - - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMTP, STREAM_TOSERVER, - SMTPParseClientRecord); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SMTP, STREAM_TOCLIENT, - SMTPParseServerRecord); - - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetEventInfo); - AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPGetEvents); - AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_SMTP, NULL, - SMTPGetTxDetectState, SMTPSetTxDetectState); - - AppLayerParserRegisterLocalStorageFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPLocalStorageAlloc, - SMTPLocalStorageFree); - - AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateTransactionFree); - AppLayerParserRegisterGetFilesFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetFiles); - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetAlstateProgress); - AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetTxCnt); - AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateGetTx); - AppLayerParserRegisterGetStateProgressCompletionStatus(IPPROTO_TCP, ALPROTO_SMTP, - SMTPStateGetAlstateProgressCompletionStatus); - AppLayerParserRegisterTruncateFunc(IPPROTO_TCP, ALPROTO_SMTP, SMTPStateTruncate); - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } - - SMTPSetMpmState(); - - SMTPConfigure(); - -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_SMTP, SMTPParserRegisterTests); -#endif - return; -} - -/***************************************Unittests******************************/ - -#ifdef UNITTESTS - -/* - * \test Test STARTTLS. - */ -int SMTPParserTest01(void) -{ - int result = 0; - Flow f; - int r = 0; - - /* 220 mx.google.com ESMTP d15sm986283wfl.6 */ - uint8_t welcome_reply[] = { - 0x32, 0x32, 0x30, 0x20, 0x6d, 0x78, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x20, 0x45, 0x53, 0x4d, 0x54, 0x50, 0x20, - 0x64, 0x31, 0x35, 0x73, 0x6d, 0x39, 0x38, 0x36, - 0x32, 0x38, 0x33, 0x77, 0x66, 0x6c, 0x2e, 0x36, - 0x0d, 0x0a - }; - uint32_t welcome_reply_len = sizeof(welcome_reply); - - /* EHLO [192.168.0.158] */ - uint8_t request1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x5b, 0x31, 0x39, - 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, - 0x31, 0x35, 0x38, 0x5d, 0x0d, 0x0a - }; - uint32_t request1_len = sizeof(request1); - /* 250-mx.google.com at your service, [117.198.115.50] - * 250-SIZE 35882577 - * 250-8BITMIME - * 250-STARTTLS - * 250 ENHANCEDSTATUSCODES - */ - uint8_t reply1[] = { - 0x32, 0x35, 0x30, 0x2d, 0x6d, 0x78, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x20, 0x61, 0x74, 0x20, 0x79, 0x6f, 0x75, - 0x72, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2c, 0x20, 0x5b, 0x31, 0x31, 0x37, 0x2e, - 0x31, 0x39, 0x38, 0x2e, 0x31, 0x31, 0x35, 0x2e, - 0x35, 0x30, 0x5d, 0x0d, 0x0a, 0x32, 0x35, 0x30, - 0x2d, 0x53, 0x49, 0x5a, 0x45, 0x20, 0x33, 0x35, - 0x38, 0x38, 0x32, 0x35, 0x37, 0x37, 0x0d, 0x0a, - 0x32, 0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, 0x54, - 0x4d, 0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, 0x35, - 0x30, 0x2d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x54, - 0x4c, 0x53, 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x20, - 0x45, 0x4e, 0x48, 0x41, 0x4e, 0x43, 0x45, 0x44, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x43, 0x4f, - 0x44, 0x45, 0x53, 0x0d, 0x0a - }; - uint32_t reply1_len = sizeof(reply1); - - /* STARTTLS */ - uint8_t request2[] = { - 0x53, 0x54, 0x41, 0x52, 0x54, 0x54, 0x4c, 0x53, - 0x0d, 0x0a - }; - uint32_t request2_len = sizeof(request2); - /* 220 2.0.0 Ready to start TLS */ - uint8_t reply2[] = { - 0x32, 0x32, 0x30, 0x20, 0x32, 0x2e, 0x30, 0x2e, - 0x30, 0x20, 0x52, 0x65, 0x61, 0x64, 0x79, 0x20, - 0x74, 0x6f, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x20, 0x54, 0x4c, 0x53, 0x0d, 0x0a - }; - uint32_t reply2_len = sizeof(reply2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - welcome_reply, welcome_reply_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply1, reply1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_STARTTLS || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply2, reply2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - if (!(f.flags & FLOW_NOPAYLOAD_INSPECTION) || - !(ssn.flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) || - !(((TcpSession *)f.protoctx)->server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) || - !(((TcpSession *)f.protoctx)->client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Test multiple DATA commands(full mail transactions). - */ -int SMTPParserTest02(void) -{ - int result = 0; - Flow f; - int r = 0; - - /* 220 mx.google.com ESMTP d15sm986283wfl.6 */ - uint8_t welcome_reply[] = { - 0x32, 0x32, 0x30, 0x20, 0x6d, 0x78, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x20, 0x45, 0x53, 0x4d, 0x54, 0x50, 0x20, - 0x64, 0x31, 0x35, 0x73, 0x6d, 0x39, 0x38, 0x36, - 0x32, 0x38, 0x33, 0x77, 0x66, 0x6c, 0x2e, 0x36, - 0x0d, 0x0a - }; - uint32_t welcome_reply_len = sizeof(welcome_reply); - - /* EHLO boo.com */ - uint8_t request1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a - }; - uint32_t request1_len = sizeof(request1); - /* 250-mx.google.com at your service, [117.198.115.50] - * 250-SIZE 35882577 - * 250-8BITMIME - * 250-STARTTLS - * 250 ENHANCEDSTATUSCODES - */ - uint8_t reply1[] = { - 0x32, 0x35, 0x30, 0x2d, 0x70, 0x6f, 0x6f, 0x6e, - 0x61, 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x5f, - 0x76, 0x6d, 0x31, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x50, 0x49, 0x50, - 0x45, 0x4c, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x53, 0x49, 0x5a, - 0x45, 0x20, 0x31, 0x30, 0x32, 0x34, 0x30, 0x30, - 0x30, 0x30, 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x2d, - 0x56, 0x52, 0x46, 0x59, 0x0d, 0x0a, 0x32, 0x35, - 0x30, 0x2d, 0x45, 0x54, 0x52, 0x4e, 0x0d, 0x0a, - 0x32, 0x35, 0x30, 0x2d, 0x45, 0x4e, 0x48, 0x41, - 0x4e, 0x43, 0x45, 0x44, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x43, 0x4f, 0x44, 0x45, 0x53, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, - 0x54, 0x4d, 0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, - 0x35, 0x30, 0x20, 0x44, 0x53, 0x4e, 0x0d, 0x0a - }; - uint32_t reply1_len = sizeof(reply1); - - /* MAIL FROM:asdff@asdf.com */ - uint8_t request2[] = { - 0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, - 0x4d, 0x3a, 0x61, 0x73, 0x64, 0x66, 0x66, 0x40, - 0x61, 0x73, 0x64, 0x66, 0x2e, 0x63, 0x6f, 0x6d, - 0x0d, 0x0a - }; - uint32_t request2_len = sizeof(request2); - /* 250 2.1.0 Ok */ - uint8_t reply2[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, - 0x30, 0x20, 0x4f, 0x6b, 0x0d, 0x0a - }; - uint32_t reply2_len = sizeof(reply2); - - /* RCPT TO:bimbs@gmail.com */ - uint8_t request3[] = { - 0x52, 0x43, 0x50, 0x54, 0x20, 0x54, 0x4f, 0x3a, - 0x62, 0x69, 0x6d, 0x62, 0x73, 0x40, 0x67, 0x6d, - 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x0d, - 0x0a - }; - uint32_t request3_len = sizeof(request3); - /* 250 2.1.5 Ok */ - uint8_t reply3[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, - 0x35, 0x20, 0x4f, 0x6b, 0x0d, 0x0a - }; - uint32_t reply3_len = sizeof(reply3); - - /* DATA */ - uint8_t request4[] = { - 0x44, 0x41, 0x54, 0x41, 0x0d, 0x0a - }; - uint32_t request4_len = sizeof(request4); - /* 354 End data with .|| */ - uint8_t reply4[] = { - 0x33, 0x35, 0x34, 0x20, 0x45, 0x6e, 0x64, 0x20, - 0x64, 0x61, 0x74, 0x61, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x20, 0x3c, 0x43, 0x52, 0x3e, 0x3c, 0x4c, - 0x46, 0x3e, 0x2e, 0x3c, 0x43, 0x52, 0x3e, 0x3c, - 0x4c, 0x46, 0x3e, 0x0d, 0x0a - }; - uint32_t reply4_len = sizeof(reply4); - - /* FROM:asdff@asdf.com */ - uint8_t request5_1[] = { - 0x46, 0x52, 0x4f, 0x4d, 0x3a, 0x61, 0x73, 0x64, - 0x66, 0x66, 0x40, 0x61, 0x73, 0x64, 0x66, 0x2e, - 0x63, 0x6f, 0x6d, 0x0d, 0x0a - }; - uint32_t request5_1_len = sizeof(request5_1); - /* TO:bimbs@gmail.com */ - uint8_t request5_2[] = { - 0x54, 0x4f, 0x3a, 0x62, 0x69, 0x6d, 0x62, 0x73, - 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, - 0x6f, 0x6d, 0x0d, 0x0a - }; - uint32_t request5_2_len = sizeof(request5_2); - /* */ - uint8_t request5_3[] = { - 0x0d, 0x0a - }; - uint32_t request5_3_len = sizeof(request5_3); - /* this is test mail1 */ - uint8_t request5_4[] = { - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, - 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x69, - 0x6c, 0x31, 0x0d, 0x0a - }; - uint32_t request5_4_len = sizeof(request5_4); - /* . */ - uint8_t request5_5[] = { - 0x2e, 0x0d, 0x0a - }; - uint32_t request5_5_len = sizeof(request5_5); - /* 250 2.0.0 Ok: queued as 6A1AF20BF2 */ - uint8_t reply5[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x30, 0x2e, - 0x30, 0x20, 0x4f, 0x6b, 0x3a, 0x20, 0x71, 0x75, - 0x65, 0x75, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, - 0x36, 0x41, 0x31, 0x41, 0x46, 0x32, 0x30, 0x42, - 0x46, 0x32, 0x0d, 0x0a - }; - uint32_t reply5_len = sizeof(reply5); - - /* MAIL FROM:asdfg@asdf.com */ - uint8_t request6[] = { - 0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, - 0x4d, 0x3a, 0x61, 0x73, 0x64, 0x66, 0x67, 0x40, - 0x61, 0x73, 0x64, 0x66, 0x2e, 0x63, 0x6f, 0x6d, - 0x0d, 0x0a - }; - uint32_t request6_len = sizeof(request6); - /* 250 2.1.0 Ok */ - uint8_t reply6[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, - 0x30, 0x20, 0x4f, 0x6b, 0x0d, 0x0a - }; - uint32_t reply6_len = sizeof(reply6); - - /* RCPT TO:bimbs@gmail.com */ - uint8_t request7[] = { - 0x52, 0x43, 0x50, 0x54, 0x20, 0x54, 0x4f, 0x3a, - 0x62, 0x69, 0x6d, 0x62, 0x73, 0x40, 0x67, 0x6d, - 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x0d, - 0x0a - }; - uint32_t request7_len = sizeof(request7); - /* 250 2.1.5 Ok */ - uint8_t reply7[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, - 0x35, 0x20, 0x4f, 0x6b, 0x0d, 0x0a - }; - uint32_t reply7_len = sizeof(reply7); - - /* DATA */ - uint8_t request8[] = { - 0x44, 0x41, 0x54, 0x41, 0x0d, 0x0a - }; - uint32_t request8_len = sizeof(request8); - /* 354 End data with .|| */ - uint8_t reply8[] = { - 0x33, 0x35, 0x34, 0x20, 0x45, 0x6e, 0x64, 0x20, - 0x64, 0x61, 0x74, 0x61, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x20, 0x3c, 0x43, 0x52, 0x3e, 0x3c, 0x4c, - 0x46, 0x3e, 0x2e, 0x3c, 0x43, 0x52, 0x3e, 0x3c, - 0x4c, 0x46, 0x3e, 0x0d, 0x0a - }; - uint32_t reply8_len = sizeof(reply8); - - /* FROM:asdfg@gmail.com */ - uint8_t request9_1[] = { - 0x46, 0x52, 0x4f, 0x4d, 0x3a, 0x61, 0x73, 0x64, - 0x66, 0x67, 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a - }; - uint32_t request9_1_len = sizeof(request9_1); - /* TO:bimbs@gmail.com */ - uint8_t request9_2[] = { - 0x54, 0x4f, 0x3a, 0x62, 0x69, 0x6d, 0x62, 0x73, - 0x40, 0x67, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, - 0x6f, 0x6d, 0x0d, 0x0a - }; - uint32_t request9_2_len = sizeof(request9_2); - /* */ - uint8_t request9_3[] = { - 0x0d, 0x0a - }; - uint32_t request9_3_len = sizeof(request9_3); - /* this is test mail2 */ - uint8_t request9_4[] = { - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, - 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x61, 0x69, - 0x6c, 0x32, 0x0d, 0x0a - }; - uint32_t request9_4_len = sizeof(request9_4); - /* . */ - uint8_t request9_5[] = { - 0x2e, 0x0d, 0x0a - }; - uint32_t request9_5_len = sizeof(request9_5); - /* 250 2.0.0 Ok: queued as 28CFF20BF2 */ - uint8_t reply9[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x30, 0x2e, - 0x30, 0x20, 0x4f, 0x6b, 0x3a, 0x20, 0x71, 0x75, - 0x65, 0x75, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, - 0x32, 0x38, 0x43, 0x46, 0x46, 0x32, 0x30, 0x42, - 0x46, 0x32, 0x0d, 0x0a - }; - uint32_t reply9_len = sizeof(reply9); - - /* QUIT */ - uint8_t request10[] = { - 0x51, 0x55, 0x49, 0x54, 0x0d, 0x0a - }; - uint32_t request10_len = sizeof(request10); - /* 221 2.0.0 Bye */ - uint8_t reply10[] = { - 0x32, 0x32, 0x31, 0x20, 0x32, 0x2e, 0x30, 0x2e, - 0x30, 0x20, 0x42, 0x79, 0x65, 0x0d, 0x0a - }; - uint32_t reply10_len = sizeof(reply10); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - welcome_reply, welcome_reply_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply1, reply1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply2, reply2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request3, request3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply3, reply3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request4, request4_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_DATA || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply4, reply4_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request5_1, request5_1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request5_2, request5_2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request5_3, request5_3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request5_4, request5_4_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request5_5, request5_5_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_DATA_MODE || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply5, reply5_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request6, request6_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply6, reply6_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request7, request7_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply7, reply7_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request8, request8_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_DATA || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply8, reply8_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request9_1, request9_1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request9_2, request9_2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request9_3, request9_3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request9_4, request9_4_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request9_5, request9_5_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_DATA_MODE || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply9, reply9_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request10, request10_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply10, reply10_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Testing parsing pipelined commands. - */ -int SMTPParserTest03(void) -{ - int result = 0; - Flow f; - int r = 0; - - /* 220 poona_slack_vm1.localdomain ESMTP Postfix */ - uint8_t welcome_reply[] = { - 0x32, 0x32, 0x30, 0x20, 0x70, 0x6f, 0x6f, 0x6e, - 0x61, 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x5f, - 0x76, 0x6d, 0x31, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, - 0x45, 0x53, 0x4d, 0x54, 0x50, 0x20, 0x50, 0x6f, - 0x73, 0x74, 0x66, 0x69, 0x78, 0x0d, 0x0a - }; - uint32_t welcome_reply_len = sizeof(welcome_reply); - - /* EHLO boo.com */ - uint8_t request1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0a - }; - uint32_t request1_len = sizeof(request1); - /* 250-poona_slack_vm1.localdomain - * 250-PIPELINING - * 250-SIZE 10240000 - * 250-VRFY - * 250-ETRN - * 250-ENHANCEDSTATUSCODES - * 250-8BITMIME - * 250 DSN - */ - uint8_t reply1[] = { - 0x32, 0x35, 0x30, 0x2d, 0x70, 0x6f, 0x6f, 0x6e, - 0x61, 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x5f, - 0x76, 0x6d, 0x31, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x50, 0x49, 0x50, - 0x45, 0x4c, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x53, 0x49, 0x5a, - 0x45, 0x20, 0x31, 0x30, 0x32, 0x34, 0x30, 0x30, - 0x30, 0x30, 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x2d, - 0x56, 0x52, 0x46, 0x59, 0x0d, 0x0a, 0x32, 0x35, - 0x30, 0x2d, 0x45, 0x54, 0x52, 0x4e, 0x0d, 0x0a, - 0x32, 0x35, 0x30, 0x2d, 0x45, 0x4e, 0x48, 0x41, - 0x4e, 0x43, 0x45, 0x44, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x43, 0x4f, 0x44, 0x45, 0x53, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, - 0x54, 0x4d, 0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, - 0x35, 0x30, 0x20, 0x44, 0x53, 0x4e, 0x0d, 0x0a - }; - uint32_t reply1_len = sizeof(reply1); - - /* MAIL FROM:pbsf@asdfs.com - * RCPT TO:pbsf@asdfs.com - * DATA - */ - uint8_t request2[] = { - 0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, - 0x4d, 0x3a, 0x70, 0x62, 0x73, 0x66, 0x40, 0x61, - 0x73, 0x64, 0x66, 0x73, 0x2e, 0x63, 0x6f, 0x6d, - 0x0d, 0x0a, 0x52, 0x43, 0x50, 0x54, 0x20, 0x54, - 0x4f, 0x3a, 0x70, 0x62, 0x73, 0x66, 0x40, 0x61, - 0x73, 0x64, 0x66, 0x73, 0x2e, 0x63, 0x6f, 0x6d, - 0x0d, 0x0a, 0x44, 0x41, 0x54, 0x41, 0x0d, 0x0a - }; - uint32_t request2_len = sizeof(request2); - /* 250 2.1.0 Ok - * 250 2.1.5 Ok - * 354 End data with .|| - */ - uint8_t reply2[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, - 0x30, 0x20, 0x4f, 0x6b, 0x0d, 0x0a, 0x32, 0x35, - 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, 0x35, 0x20, - 0x4f, 0x6b, 0x0d, 0x0a, 0x33, 0x35, 0x34, 0x20, - 0x45, 0x6e, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x3c, 0x43, - 0x52, 0x3e, 0x3c, 0x4c, 0x46, 0x3e, 0x2e, 0x3c, - 0x43, 0x52, 0x3e, 0x3c, 0x4c, 0x46, 0x3e, 0x0d, - 0x0a - }; - uint32_t reply2_len = sizeof(reply2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - welcome_reply, welcome_reply_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply1, reply1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 3 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->cmds[1] != SMTP_COMMAND_OTHER_CMD || - smtp_state->cmds[2] != SMTP_COMMAND_DATA || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply2, reply2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/* - * \test Test smtp with just delimter instead of . - */ -int SMTPParserTest04(void) -{ - int result = 0; - Flow f; - int r = 0; - - /* 220 poona_slack_vm1.localdomain ESMTP Postfix */ - uint8_t welcome_reply[] = { - 0x32, 0x32, 0x30, 0x20, 0x70, 0x6f, 0x6f, 0x6e, - 0x61, 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x5f, - 0x76, 0x6d, 0x31, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, - 0x45, 0x53, 0x4d, 0x54, 0x50, 0x20, 0x50, 0x6f, - 0x73, 0x74, 0x66, 0x69, 0x78, 0x0d, 0x0a - }; - uint32_t welcome_reply_len = sizeof(welcome_reply); - - /* EHLO boo.com */ - uint8_t request1[] = { - 0x32, 0x32, 0x30, 0x20, 0x70, 0x6f, 0x6f, 0x6e, - 0x61, 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x5f, - 0x76, 0x6d, 0x31, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, - 0x45, 0x53, 0x4d, 0x54, 0x50, 0x20, 0x50, 0x6f, - 0x73, 0x74, 0x66, 0x69, 0x78, 0x0d, 0x0a - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - welcome_reply, welcome_reply_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/* - * \test Test STARTTLS fail. - */ -int SMTPParserTest05(void) -{ - int result = 0; - Flow f; - int r = 0; - - /* 220 poona_slack_vm1.localdomain ESMTP Postfix */ - uint8_t welcome_reply[] = { - 0x32, 0x32, 0x30, 0x20, 0x70, 0x6f, 0x6f, 0x6e, - 0x61, 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x5f, - 0x76, 0x6d, 0x31, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, - 0x45, 0x53, 0x4d, 0x54, 0x50, 0x20, 0x50, 0x6f, - 0x73, 0x74, 0x66, 0x69, 0x78, 0x0d, 0x0a - }; - uint32_t welcome_reply_len = sizeof(welcome_reply); - - /* EHLO boo.com */ - uint8_t request1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a - }; - uint32_t request1_len = sizeof(request1); - /* 250-poona_slack_vm1.localdomain - * 250-PIPELINING - * 250-SIZE 10240000 - * 250-VRFY - * 250-ETRN - * 250-ENHANCEDSTATUSCODES - * 250-8BITMIME - * 250 DSN - */ - uint8_t reply1[] = { - 0x32, 0x35, 0x30, 0x2d, 0x70, 0x6f, 0x6f, 0x6e, - 0x61, 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x5f, - 0x76, 0x6d, 0x31, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x50, 0x49, 0x50, - 0x45, 0x4c, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x53, 0x49, 0x5a, - 0x45, 0x20, 0x31, 0x30, 0x32, 0x34, 0x30, 0x30, - 0x30, 0x30, 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x2d, - 0x56, 0x52, 0x46, 0x59, 0x0d, 0x0a, 0x32, 0x35, - 0x30, 0x2d, 0x45, 0x54, 0x52, 0x4e, 0x0d, 0x0a, - 0x32, 0x35, 0x30, 0x2d, 0x45, 0x4e, 0x48, 0x41, - 0x4e, 0x43, 0x45, 0x44, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x43, 0x4f, 0x44, 0x45, 0x53, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, - 0x54, 0x4d, 0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, - 0x35, 0x30, 0x20, 0x44, 0x53, 0x4e, 0x0d, 0x0a - }; - uint32_t reply1_len = sizeof(reply1); - - /* STARTTLS */ - uint8_t request2[] = { - 0x53, 0x54, 0x41, 0x52, 0x54, 0x54, 0x4c, 0x53, - 0x0d, 0x0a - }; - uint32_t request2_len = sizeof(request2); - /* 502 5.5.2 Error: command not recognized */ - uint8_t reply2[] = { - 0x35, 0x30, 0x32, 0x20, 0x35, 0x2e, 0x35, 0x2e, - 0x32, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, - 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x63, - 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x0d, - 0x0a - }; - uint32_t reply2_len = sizeof(reply2); - - /* QUIT */ - uint8_t request3[] = { - 0x51, 0x55, 0x49, 0x54, 0x0d, 0x0a - - }; - uint32_t request3_len = sizeof(request3); - /* 221 2.0.0 Bye */ - uint8_t reply3[] = { - 0x32, 0x32, 0x31, 0x20, 0x32, 0x2e, 0x30, 0x2e, - 0x30, 0x20, 0x42, 0x79, 0x65, 0x0d, 0x0a - }; - uint32_t reply3_len = sizeof(reply3); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - welcome_reply, welcome_reply_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply1, reply1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_STARTTLS || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply2, reply2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - if ((f.flags & FLOW_NOPAYLOAD_INSPECTION) || - (ssn.flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) || - (((TcpSession *)f.protoctx)->server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) || - (((TcpSession *)f.protoctx)->client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request3, request3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply3, reply3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Test multiple DATA commands(full mail transactions). - */ -int SMTPParserTest06(void) -{ - int result = 0; - Flow f; - int r = 0; - - uint8_t welcome_reply[] = { - 0x32, 0x32, 0x30, 0x20, 0x62, 0x61, 0x79, 0x30, - 0x2d, 0x6d, 0x63, 0x36, 0x2d, 0x66, 0x31, 0x30, - 0x2e, 0x62, 0x61, 0x79, 0x30, 0x2e, 0x68, 0x6f, - 0x74, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, - 0x6d, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x20, 0x75, 0x6e, 0x73, 0x6f, 0x6c, 0x69, - 0x63, 0x69, 0x74, 0x65, 0x64, 0x20, 0x63, 0x6f, - 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x69, 0x61, 0x6c, - 0x20, 0x6f, 0x72, 0x20, 0x62, 0x75, 0x6c, 0x6b, - 0x20, 0x65, 0x2d, 0x6d, 0x61, 0x69, 0x6c, 0x20, - 0x74, 0x6f, 0x20, 0x4d, 0x69, 0x63, 0x72, 0x6f, - 0x73, 0x6f, 0x66, 0x74, 0x27, 0x73, 0x20, 0x63, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x20, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, - 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x68, 0x69, - 0x62, 0x69, 0x74, 0x65, 0x64, 0x2e, 0x20, 0x4f, - 0x74, 0x68, 0x65, 0x72, 0x20, 0x72, 0x65, 0x73, - 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x66, 0x6f, - 0x75, 0x6e, 0x64, 0x20, 0x61, 0x74, 0x20, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x72, - 0x69, 0x76, 0x61, 0x63, 0x79, 0x2e, 0x6d, 0x73, - 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x6e, - 0x74, 0x69, 0x2d, 0x73, 0x70, 0x61, 0x6d, 0x2f, - 0x2e, 0x20, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x77, 0x69, 0x6c, - 0x6c, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x20, 0x69, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x20, - 0x6f, 0x66, 0x20, 0x65, 0x71, 0x75, 0x69, 0x70, - 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, - 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, - 0x69, 0x61, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6f, - 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x73, 0x2e, 0x20, 0x46, 0x72, 0x69, - 0x2c, 0x20, 0x31, 0x36, 0x20, 0x46, 0x65, 0x62, - 0x20, 0x32, 0x30, 0x30, 0x37, 0x20, 0x30, 0x35, - 0x3a, 0x30, 0x33, 0x3a, 0x32, 0x33, 0x20, 0x2d, - 0x30, 0x38, 0x30, 0x30, 0x20, 0x0d, 0x0a - }; - uint32_t welcome_reply_len = sizeof(welcome_reply); - - uint8_t request1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x45, 0x58, 0x43, - 0x48, 0x41, 0x4e, 0x47, 0x45, 0x32, 0x2e, 0x63, - 0x67, 0x63, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x69, - 0x61, 0x6d, 0x69, 0x2e, 0x65, 0x64, 0x75, 0x0d, - 0x0a - }; - uint32_t request1_len = sizeof(request1); - - uint8_t reply1[] = { - 0x32, 0x35, 0x30, 0x2d, 0x62, 0x61, 0x79, 0x30, - 0x2d, 0x6d, 0x63, 0x36, 0x2d, 0x66, 0x31, 0x30, - 0x2e, 0x62, 0x61, 0x79, 0x30, 0x2e, 0x68, 0x6f, - 0x74, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, - 0x6d, 0x20, 0x28, 0x33, 0x2e, 0x33, 0x2e, 0x31, - 0x2e, 0x34, 0x29, 0x20, 0x48, 0x65, 0x6c, 0x6c, - 0x6f, 0x20, 0x5b, 0x31, 0x32, 0x39, 0x2e, 0x31, - 0x37, 0x31, 0x2e, 0x33, 0x32, 0x2e, 0x35, 0x39, - 0x5d, 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x53, - 0x49, 0x5a, 0x45, 0x20, 0x32, 0x39, 0x36, 0x39, - 0x36, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x32, 0x35, - 0x30, 0x2d, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, - 0x4e, 0x49, 0x4e, 0x47, 0x0d, 0x0a, 0x32, 0x35, - 0x30, 0x2d, 0x38, 0x62, 0x69, 0x74, 0x6d, 0x69, - 0x6d, 0x65, 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x2d, - 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x4d, 0x49, - 0x4d, 0x45, 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x2d, - 0x43, 0x48, 0x55, 0x4e, 0x4b, 0x49, 0x4e, 0x47, - 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x41, 0x55, - 0x54, 0x48, 0x20, 0x4c, 0x4f, 0x47, 0x49, 0x4e, - 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x41, 0x55, - 0x54, 0x48, 0x3d, 0x4c, 0x4f, 0x47, 0x49, 0x4e, - 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x20, 0x4f, 0x4b, - 0x0d, 0x0a - }; - uint32_t reply1_len = sizeof(reply1); - - /* MAIL FROM:asdff@asdf.com */ - uint8_t request2[] = { - 0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, - 0x4d, 0x3a, 0x61, 0x73, 0x64, 0x66, 0x66, 0x40, - 0x61, 0x73, 0x64, 0x66, 0x2e, 0x63, 0x6f, 0x6d, - 0x0d, 0x0a - }; - uint32_t request2_len = sizeof(request2); - /* 250 2.1.0 Ok */ - uint8_t reply2[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, - 0x30, 0x20, 0x4f, 0x6b, 0x0d, 0x0a - }; - uint32_t reply2_len = sizeof(reply2); - - /* RCPT TO:bimbs@gmail.com */ - uint8_t request3[] = { - 0x52, 0x43, 0x50, 0x54, 0x20, 0x54, 0x4f, 0x3a, - 0x62, 0x69, 0x6d, 0x62, 0x73, 0x40, 0x67, 0x6d, - 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x0d, - 0x0a - }; - uint32_t request3_len = sizeof(request3); - /* 250 2.1.5 Ok */ - uint8_t reply3[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, - 0x35, 0x20, 0x4f, 0x6b, 0x0d, 0x0a - }; - uint32_t reply3_len = sizeof(reply3); - - /* BDAT 51 */ - uint8_t request4[] = { - 0x42, 0x44, 0x41, 0x54, 0x20, 0x35, 0x31, 0x0d, - 0x0a, - }; - uint32_t request4_len = sizeof(request4); - - uint8_t request5[] = { - 0x46, 0x52, 0x4f, 0x4d, 0x3a, 0x61, 0x73, 0x64, - 0x66, 0x66, 0x40, 0x61, 0x73, 0x64, 0x66, 0x2e, - 0x66, 0x66, 0x40, 0x61, 0x73, 0x64, 0x66, 0x2e, - 0x66, 0x66, 0x40, 0x61, 0x73, 0x64, 0x0d, 0x0a, - }; - uint32_t request5_len = sizeof(request5); - - uint8_t request6[] = { - 0x46, 0x52, 0x4f, 0x4d, 0x3a, 0x61, 0x73, 0x64, - 0x66, 0x66, 0x40, 0x61, 0x73, 0x64, 0x66, 0x2e, - 0x66, 0x0d, 0x0a, - }; - uint32_t request6_len = sizeof(request6); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - welcome_reply, welcome_reply_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply1, reply1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply2, reply2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request3, request3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply3, reply3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request4, request4_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_BDAT || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE) || - smtp_state->bdat_chunk_len != 51 || - smtp_state->bdat_chunk_idx != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request5, request5_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE) || - smtp_state->bdat_chunk_len != 51 || - smtp_state->bdat_chunk_idx != 32) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request6, request6_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN || - smtp_state->bdat_chunk_len != 51 || - smtp_state->bdat_chunk_idx != 51) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/* - * \test Test retrieving lines when frag'ed. - */ -int SMTPParserTest07(void) -{ - int result = 0; - Flow f; - int r = 0; - - const char *request1_str = "EHLO boo.com"; - /* EHLO boo.com */ - uint8_t request1_1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, - }; - int32_t request1_1_len = sizeof(request1_1); - - /* */ - uint8_t request1_2[] = { - 0x0a - }; - int32_t request1_2_len = sizeof(request1_2); - - /* EHLO boo.com */ - uint8_t request2[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, - }; - int32_t request2_len = sizeof(request2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1_1, request1_1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->current_line != NULL || - smtp_state->current_line_len != 0 || - smtp_state->ts_current_line_db != 1 || - smtp_state->ts_db == NULL || - smtp_state->ts_db_len != request1_1_len || - memcmp(smtp_state->ts_db, request1_1, request1_1_len) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1_2, request1_2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->ts_current_line_db != 1 || - smtp_state->ts_db == NULL || - smtp_state->ts_db_len != (int32_t)strlen(request1_str) || - memcmp(smtp_state->ts_db, request1_str, strlen(request1_str)) != 0 || - smtp_state->current_line != smtp_state->ts_db || - smtp_state->current_line_len != smtp_state->ts_db_len) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->ts_current_line_db != 0 || - smtp_state->ts_db != NULL || - smtp_state->ts_db_len != 0 || - smtp_state->current_line == NULL || - smtp_state->current_line_len != (int32_t)strlen(request1_str) || - memcmp(smtp_state->current_line, request1_str, strlen(request1_str)) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/* - * \test Test retrieving lines when frag'ed. - */ -int SMTPParserTest08(void) -{ - int result = 0; - Flow f; - int r = 0; - - const char *request1_str = "EHLO boo.com"; - /* EHLO boo.com */ - uint8_t request1_1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, - }; - int32_t request1_1_len = sizeof(request1_1); - - /* */ - uint8_t request1_2[] = { - 0x0d, 0x0a - }; - int32_t request1_2_len = sizeof(request1_2); - - /* EHLO boo.com */ - uint8_t request2[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, - }; - int32_t request2_len = sizeof(request2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1_1, request1_1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->current_line != NULL || - smtp_state->current_line_len != 0 || - smtp_state->ts_current_line_db != 1 || - smtp_state->ts_db == NULL || - smtp_state->ts_db_len != request1_1_len || - memcmp(smtp_state->ts_db, request1_1, request1_1_len) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1_2, request1_2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->ts_current_line_db != 1 || - smtp_state->ts_db == NULL || - smtp_state->ts_db_len != (int32_t)strlen(request1_str) || - memcmp(smtp_state->ts_db, request1_str, strlen(request1_str)) != 0 || - smtp_state->current_line != smtp_state->ts_db || - smtp_state->current_line_len != smtp_state->ts_db_len) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->ts_current_line_db != 0 || - smtp_state->ts_db != NULL || - smtp_state->ts_db_len != 0 || - smtp_state->current_line == NULL || - smtp_state->current_line_len != (int32_t)strlen(request1_str) || - memcmp(smtp_state->current_line, request1_str, strlen(request1_str)) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/* - * \test Test retrieving lines when frag'ed. - */ -int SMTPParserTest09(void) -{ - int result = 0; - Flow f; - int r = 0; - - const char *request1_str = "EHLO boo.com"; - /* EHLO boo. */ - uint8_t request1_1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, - }; - int32_t request1_1_len = sizeof(request1_1); - - /* com */ - uint8_t request1_2[] = { - 0x63, 0x6f, 0x6d, 0x0d, 0x0a - }; - int32_t request1_2_len = sizeof(request1_2); - - /* EHLO boo.com */ - uint8_t request2[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, - }; - int32_t request2_len = sizeof(request2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1_1, request1_1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->current_line != NULL || - smtp_state->current_line_len != 0 || - smtp_state->ts_current_line_db != 1 || - smtp_state->ts_db == NULL || - smtp_state->ts_db_len != request1_1_len || - memcmp(smtp_state->ts_db, request1_1, request1_1_len) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1_2, request1_2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->ts_current_line_db != 1 || - smtp_state->ts_db == NULL || - smtp_state->ts_db_len != (int32_t)strlen(request1_str) || - memcmp(smtp_state->ts_db, request1_str, strlen(request1_str)) != 0 || - smtp_state->current_line != smtp_state->ts_db || - smtp_state->current_line_len != smtp_state->ts_db_len) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->ts_current_line_db != 0 || - smtp_state->ts_db != NULL || - smtp_state->ts_db_len != 0 || - smtp_state->current_line == NULL || - smtp_state->current_line_len != (int32_t)strlen(request1_str) || - memcmp(smtp_state->current_line, request1_str, strlen(request1_str)) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/* - * \test Test retrieving lines when frag'ed. - */ -int SMTPParserTest10(void) -{ - int result = 0; - Flow f; - int r = 0; - - const char *request1_str = ""; - /* EHLO boo. */ - uint8_t request1_1[] = { - 0x0d, - }; - int32_t request1_1_len = sizeof(request1_1); - - /* com */ - uint8_t request1_2[] = { - 0x0a, - }; - int32_t request1_2_len = sizeof(request1_2); - - const char *request2_str = "EHLO boo.com"; - /* EHLO boo.com */ - uint8_t request2[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, - }; - int32_t request2_len = sizeof(request2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1_1, request1_1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->current_line != NULL || - smtp_state->current_line_len != 0 || - smtp_state->ts_current_line_db != 1 || - smtp_state->ts_db == NULL || - smtp_state->ts_db_len != request1_1_len || - memcmp(smtp_state->ts_db, request1_1, request1_1_len) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1_2, request1_2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->ts_current_line_db != 1 || - smtp_state->ts_db == NULL || - smtp_state->ts_db_len != (int32_t)strlen(request1_str) || - memcmp(smtp_state->ts_db, request1_str, strlen(request1_str)) != 0 || - smtp_state->current_line != smtp_state->ts_db || - smtp_state->current_line_len != smtp_state->ts_db_len) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->ts_current_line_db != 0 || - smtp_state->ts_db != NULL || - smtp_state->ts_db_len != 0 || - smtp_state->current_line == NULL || - smtp_state->current_line_len != (int32_t)strlen(request2_str) || - memcmp(smtp_state->current_line, request2_str, strlen(request2_str)) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/* - * \test Test retrieving lines when frag'ed. - */ -int SMTPParserTest11(void) -{ - int result = 0; - Flow f; - int r = 0; - - const char *request1_str = ""; - /* EHLO boo. */ - uint8_t request1[] = { - 0x0a, - }; - int32_t request1_len = sizeof(request1); - - const char *request2_str = "EHLO boo.com"; - /* EHLO boo.com */ - uint8_t request2[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, - }; - int32_t request2_len = sizeof(request2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->current_line == NULL || - smtp_state->current_line_len != 0 || - smtp_state->ts_current_line_db == 1 || - smtp_state->ts_db != NULL || - smtp_state->ts_db_len != 0 || - memcmp(smtp_state->current_line, request1_str, strlen(request1_str)) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->ts_current_line_db != 0 || - smtp_state->ts_db != NULL || - smtp_state->ts_db_len != 0 || - smtp_state->current_line == NULL || - smtp_state->current_line_len != (int32_t)strlen(request2_str) || - memcmp(smtp_state->current_line, request2_str, strlen(request2_str)) != 0) { - printf("smtp parser in inconsistent state\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -int SMTPParserTest12(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - SMTPState *smtp_state = NULL; - int r = 0; - - /* EHLO boo.com */ - uint8_t request1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, - }; - int32_t request1_len = sizeof(request1); - - /* 388 - */ - uint8_t reply1[] = { - 0x31, 0x38, 0x38, 0x0d, 0x0a, - }; - uint32_t reply1_len = sizeof(reply1); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SMTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx,"alert tcp any any -> any any " - "(msg:\"SMTP event handling\"; " - "app-layer-event: smtp.invalid_reply; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER | STREAM_START, - request1, request1_len); - if (r != 0) { - printf("AppLayerParse for smtp failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched. It shouldn't match: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT | STREAM_TOCLIENT, - reply1, reply1_len); - if (r == 0) { - printf("AppLayerParse for smtp failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match. Should have matched: "); - goto end; - } - - result = 1; - -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -int SMTPParserTest13(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - SMTPState *smtp_state = NULL; - int r = 0; - - /* EHLO boo.com */ - uint8_t request1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a, - }; - int32_t request1_len = sizeof(request1); - - /* 250 - */ - uint8_t reply1[] = { - 0x32, 0x35, 0x30, 0x0d, 0x0a, - }; - uint32_t reply1_len = sizeof(reply1); - - /* MAIL FROM:pbsf@asdfs.com - * RCPT TO:pbsf@asdfs.com - * DATA - * STARTTLS - */ - uint8_t request2[] = { - 0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, - 0x4d, 0x3a, 0x70, 0x62, 0x73, 0x66, 0x40, 0x61, - 0x73, 0x64, 0x66, 0x73, 0x2e, 0x63, 0x6f, 0x6d, - 0x0d, 0x0a, 0x52, 0x43, 0x50, 0x54, 0x20, 0x54, - 0x4f, 0x3a, 0x70, 0x62, 0x73, 0x66, 0x40, 0x61, - 0x73, 0x64, 0x66, 0x73, 0x2e, 0x63, 0x6f, 0x6d, - 0x0d, 0x0a, 0x44, 0x41, 0x54, 0x41, 0x0d, 0x0a, - 0x53, 0x54, 0x41, 0x52, 0x54, 0x54, 0x4c, 0x53, - 0x0d, 0x0a - }; - uint32_t request2_len = sizeof(request2); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SMTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"SMTP event handling\"; " - "app-layer-event: " - "smtp.invalid_pipelined_sequence; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER | STREAM_START, - request1, request1_len); - if (r != 0) { - printf("AppLayerParse for smtp failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched. It shouldn't match: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply1, reply1_len); - if (r != 0) { - printf("AppLayerParse for smtp failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched. It shouldn't match: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("AppLayerParse for smtp failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match. Should have matched: "); - goto end; - } - - result = 1; - -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test DATA command w/MIME message. - */ -int SMTPParserTest14(void) -{ - int result = 0; - Flow f; - int r = 0; - - /* 220 mx.google.com ESMTP d15sm986283wfl.6 */ - static uint8_t welcome_reply[] = { - 0x32, 0x32, 0x30, 0x20, 0x6d, 0x78, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x20, 0x45, 0x53, 0x4d, 0x54, 0x50, 0x20, - 0x64, 0x31, 0x35, 0x73, 0x6d, 0x39, 0x38, 0x36, - 0x32, 0x38, 0x33, 0x77, 0x66, 0x6c, 0x2e, 0x36, - 0x0d, 0x0a - }; - static uint32_t welcome_reply_len = sizeof(welcome_reply); - - /* EHLO boo.com */ - static uint8_t request1[] = { - 0x45, 0x48, 0x4c, 0x4f, 0x20, 0x62, 0x6f, 0x6f, - 0x2e, 0x63, 0x6f, 0x6d, 0x0d, 0x0a - }; - static uint32_t request1_len = sizeof(request1); - /* 250-mx.google.com at your service, [117.198.115.50] - * 250-SIZE 35882577 - * 250-8BITMIME - * 250-STARTTLS - * 250 ENHANCEDSTATUSCODES - */ - static uint8_t reply1[] = { - 0x32, 0x35, 0x30, 0x2d, 0x70, 0x6f, 0x6f, 0x6e, - 0x61, 0x5f, 0x73, 0x6c, 0x61, 0x63, 0x6b, 0x5f, - 0x76, 0x6d, 0x31, 0x2e, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x50, 0x49, 0x50, - 0x45, 0x4c, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x53, 0x49, 0x5a, - 0x45, 0x20, 0x31, 0x30, 0x32, 0x34, 0x30, 0x30, - 0x30, 0x30, 0x0d, 0x0a, 0x32, 0x35, 0x30, 0x2d, - 0x56, 0x52, 0x46, 0x59, 0x0d, 0x0a, 0x32, 0x35, - 0x30, 0x2d, 0x45, 0x54, 0x52, 0x4e, 0x0d, 0x0a, - 0x32, 0x35, 0x30, 0x2d, 0x45, 0x4e, 0x48, 0x41, - 0x4e, 0x43, 0x45, 0x44, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x43, 0x4f, 0x44, 0x45, 0x53, 0x0d, - 0x0a, 0x32, 0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, - 0x54, 0x4d, 0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, - 0x35, 0x30, 0x20, 0x44, 0x53, 0x4e, 0x0d, 0x0a - }; - static uint32_t reply1_len = sizeof(reply1); - - /* MAIL FROM:asdff@asdf.com */ - static uint8_t request2[] = { - 0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, - 0x4d, 0x3a, 0x61, 0x73, 0x64, 0x66, 0x66, 0x40, - 0x61, 0x73, 0x64, 0x66, 0x2e, 0x63, 0x6f, 0x6d, - 0x0d, 0x0a - }; - static uint32_t request2_len = sizeof(request2); - /* 250 2.1.0 Ok */ - static uint8_t reply2[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, - 0x30, 0x20, 0x4f, 0x6b, 0x0d, 0x0a - }; - static uint32_t reply2_len = sizeof(reply2); - - /* RCPT TO:bimbs@gmail.com */ - static uint8_t request3[] = { - 0x52, 0x43, 0x50, 0x54, 0x20, 0x54, 0x4f, 0x3a, - 0x62, 0x69, 0x6d, 0x62, 0x73, 0x40, 0x67, 0x6d, - 0x61, 0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x0d, - 0x0a - }; - static uint32_t request3_len = sizeof(request3); - /* 250 2.1.5 Ok */ - static uint8_t reply3[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x31, 0x2e, - 0x35, 0x20, 0x4f, 0x6b, 0x0d, 0x0a - }; - static uint32_t reply3_len = sizeof(reply3); - - /* DATA */ - static uint8_t request4[] = { - 0x44, 0x41, 0x54, 0x41, 0x0d, 0x0a - }; - static uint32_t request4_len = sizeof(request4); - /* 354 End data with .|| */ - static uint8_t reply4[] = { - 0x33, 0x35, 0x34, 0x20, 0x45, 0x6e, 0x64, 0x20, - 0x64, 0x61, 0x74, 0x61, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x20, 0x3c, 0x43, 0x52, 0x3e, 0x3c, 0x4c, - 0x46, 0x3e, 0x2e, 0x3c, 0x43, 0x52, 0x3e, 0x3c, - 0x4c, 0x46, 0x3e, 0x0d, 0x0a - }; - static uint32_t reply4_len = sizeof(reply4); - - /* MIME_MSG */ - static uint64_t filesize = 133; - static uint8_t request4_msg[] = { - 0x4D, 0x49, 0x4D, 0x45, 0x2D, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x31, 0x2E, - 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, - 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x3A, - 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6F, 0x63, 0x74, - 0x65, 0x74, 0x2D, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6D, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, - 0x6E, 0x74, 0x2D, 0x54, 0x72, 0x61, 0x6E, 0x73, - 0x66, 0x65, 0x72, 0x2D, 0x45, 0x6E, 0x63, 0x6F, - 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x62, 0x61, - 0x73, 0x65, 0x36, 0x34, 0x0D, 0x0A, 0x43, 0x6F, - 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x44, 0x69, - 0x73, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, - 0x6E, 0x3A, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, - 0x68, 0x6D, 0x65, 0x6E, 0x74, 0x3B, 0x20, 0x66, - 0x69, 0x6C, 0x65, 0x6E, 0x61, 0x6D, 0x65, 0x3D, - 0x22, 0x74, 0x65, 0x73, 0x74, 0x2E, 0x65, 0x78, - 0x65, 0x22, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x54, - 0x56, 0x6F, 0x41, 0x41, 0x46, 0x42, 0x46, 0x41, - 0x41, 0x42, 0x4D, 0x41, 0x51, 0x45, 0x41, 0x61, - 0x69, 0x70, 0x59, 0x77, 0x77, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, - 0x41, 0x41, 0x44, 0x41, 0x51, 0x73, 0x42, 0x43, - 0x41, 0x41, 0x42, 0x41, 0x41, 0x43, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x48, 0x6B, 0x41, 0x41, - 0x41, 0x41, 0x4D, 0x41, 0x41, 0x41, 0x41, 0x65, - 0x51, 0x41, 0x41, 0x41, 0x41, 0x77, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x42, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, - 0x41, 0x42, 0x30, 0x41, 0x41, 0x41, 0x41, 0x49, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, - 0x41, 0x45, 0x41, 0x41, 0x49, 0x67, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x67, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x42, 0x63, 0x58, 0x44, 0x59, 0x32, 0x4C, - 0x6A, 0x6B, 0x7A, 0x4C, 0x6A, 0x59, 0x34, 0x4C, - 0x6A, 0x5A, 0x63, 0x65, 0x67, 0x41, 0x41, 0x4F, - 0x41, 0x3D, 0x3D, 0x0D,0x0A }; - static uint32_t request4_msg_len = sizeof(request4_msg); - - /* DATA COMPLETED */ - static uint8_t request4_end[] = { - 0x0d, 0x0a, 0x2e, 0x0d, 0x0a - }; - static uint32_t request4_end_len = sizeof(request4_end); - /* 250 2.0.0 Ok: queued as 6A1AF20BF2 */ - static uint8_t reply4_end[] = { - 0x32, 0x35, 0x30, 0x20, 0x32, 0x2e, 0x30, 0x2e, - 0x30, 0x20, 0x4f, 0x6b, 0x3a, 0x20, 0x71, 0x75, - 0x65, 0x75, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, - 0x36, 0x41, 0x31, 0x41, 0x46, 0x32, 0x30, 0x42, - 0x46, 0x32, 0x0d, 0x0a - }; - static uint32_t reply4_end_len = sizeof(reply4_end); - - /* QUIT */ - static uint8_t request5[] = { - 0x51, 0x55, 0x49, 0x54, 0x0d, 0x0a - }; - static uint32_t request5_len = sizeof(request5); - /* 221 2.0.0 Bye */ - static uint8_t reply5[] = { - 0x32, 0x32, 0x31, 0x20, 0x32, 0x2e, 0x30, 0x2e, - 0x30, 0x20, 0x42, 0x79, 0x65, 0x0d, 0x0a - }; - static uint32_t reply5_len = sizeof(reply5); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - /* Welcome reply */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - welcome_reply, welcome_reply_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SMTPState *smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request1, request1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* EHLO Reply */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply1, reply1_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - if ((smtp_state->helo_len != 7) || strncmp("boo.com", (char *)smtp_state->helo, 7)) { - printf("incorrect parsing of HELO field '%s' (%d)\n", smtp_state->helo, smtp_state->helo_len); - SCMutexUnlock(&f.m); - goto end; - } - - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* MAIL FROM Request */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request2, request2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* MAIL FROM Reply */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply2, reply2_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - if ((smtp_state->curr_tx->mail_from_len != 14) || - strncmp("asdff@asdf.com", (char *)smtp_state->curr_tx->mail_from, 14)) { - printf("incorrect parsing of MAIL FROM field '%s' (%d)\n", - smtp_state->curr_tx->mail_from, - smtp_state->curr_tx->mail_from_len); - SCMutexUnlock(&f.m); - goto end; - } - - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* RCPT TO Request */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request3, request3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* RCPT TO Reply */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply3, reply3_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - /* Enable mime decoding */ - smtp_config.decode_mime = 1; - smtp_config.mime_config.decode_base64 = 1; - smtp_config.mime_config.decode_quoted_printable = 1; - MimeDecSetConfig(&smtp_config.mime_config); - - SCMutexLock(&f.m); - /* DATA request */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request4, request4_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_DATA || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* Data reply */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply4, reply4_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* DATA message */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request4_msg, request4_msg_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->curr_tx->mime_state == NULL || smtp_state->curr_tx->msg_head == NULL || /* MIME data structures */ - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN | - SMTP_PARSER_STATE_COMMAND_DATA_MODE)) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* DATA . request */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request4_end, request4_end_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_DATA_MODE || - smtp_state->curr_tx->mime_state == NULL || smtp_state->curr_tx->msg_head == NULL || /* MIME data structures */ - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SMTPState *state = (SMTPState *) f.alstate; - FileContainer *files = state->files_ts; - if (files != NULL && files->head != NULL) { - File *file = files->head; - - if(strncmp((const char *)file->name, "test.exe", 8) != 0){ - printf("smtp-mime file name is incorrect"); - goto end; - } - if(file->size != filesize){ - printf("smtp-mime file size %"PRIu64" is incorrect", file->size); - goto end; - } - static uint8_t org_binary[] = { - 0x4D, 0x5A, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, - 0x4C, 0x01, 0x01, 0x00, 0x6A, 0x2A, 0x58, 0xC3, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x03, 0x01, 0x0B, 0x01, 0x08, 0x00, - 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x79, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x79, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, - 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x5C, 0x5C, 0x36, 0x36, - 0x2E, 0x39, 0x33, 0x2E, 0x36, 0x38, 0x2E, 0x36, - 0x5C, 0x7A, 0x00, 0x00, 0x38,}; - uint64_t z; - for (z=0; z < filesize; z++){ - if(org_binary[z] != file->chunks_head->data[z]){ - printf("smtp-mime file data incorrect\n"); - goto end; - } - } - } - - SCMutexLock(&f.m); - /* DATA . reply */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply4_end, reply4_end_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* QUIT Request */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, - request5, request5_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 1 || - smtp_state->cmds_idx != 0 || - smtp_state->cmds[0] != SMTP_COMMAND_OTHER_CMD || - smtp_state->parser_state != SMTP_PARSER_STATE_FIRST_REPLY_SEEN) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - SCMutexLock(&f.m); - /* QUIT Reply */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOCLIENT, - reply5, reply5_len); - if (r != 0) { - printf("smtp check returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - if (smtp_state->input_len != 0 || - smtp_state->cmds_cnt != 0 || - smtp_state->cmds_idx != 0 || - smtp_state->parser_state != (SMTP_PARSER_STATE_FIRST_REPLY_SEEN)) { - printf("smtp parser in inconsistent state l.%d\n", __LINE__); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -int SMTPProcessDataChunkTest01(void){ - Flow f; - FLOW_INITIALIZE(&f); - f.flags = FLOW_FILE_NO_STORE_TS; - MimeDecParseState *state = MimeDecInitParser(&f, NULL); - int ret; - ret = SMTPProcessDataChunk(NULL, 0, state); - - return ret; -} - - -int SMTPProcessDataChunkTest02(void){ - char mimemsg[] = {0x4D, 0x49, 0x4D, 0x45, 0x2D, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x31, 0x2E, - 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, - 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x3A, - 0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6F, 0x63, 0x74, - 0x65, 0x74, 0x2D, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6D, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, - 0x6E, 0x74, 0x2D, 0x54, 0x72, 0x61, 0x6E, 0x73, - 0x66, 0x65, 0x72, 0x2D, 0x45, 0x6E, 0x63, 0x6F, - 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x62, 0x61, - 0x73, 0x65, 0x36, 0x34, 0x0D, 0x0A, 0x43, 0x6F, - 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x44, 0x69, - 0x73, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, - 0x6E, 0x3A, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, - 0x68, 0x6D, 0x65, 0x6E, 0x74, 0x3B, 0x20, 0x66, - 0x69, 0x6C, 0x65, 0x6E, 0x61, 0x6D, 0x65, 0x3D, - 0x22, 0x74, 0x65, 0x73, 0x74, 0x2E, 0x65, 0x78, - 0x65, 0x22, 0x3B, 0x0D, 0x0A, 0x0D, 0x0A, 0x54, - 0x56, 0x6F, 0x41, 0x41, 0x46, 0x42, 0x46, 0x41, - 0x41, 0x42, 0x4D, 0x41, 0x51, 0x45, 0x41, 0x61, - 0x69, 0x70, 0x59, 0x77, 0x77, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, - 0x41, 0x41, 0x44, 0x41, 0x51, 0x73, 0x42, 0x43, - 0x41, 0x41, 0x42, 0x41, 0x41, 0x43, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x48, 0x6B, 0x41, 0x41, - 0x41, 0x41, 0x4D, 0x41, 0x41, 0x41, 0x41, 0x65, - 0x51, 0x41, 0x41, 0x41, 0x41, 0x77, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x42, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, - 0x41, 0x42, 0x30, 0x41, 0x41, 0x41, 0x41, 0x49, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, - 0x41, 0x45, 0x41, 0x41, 0x49, 0x67, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x67, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x42, 0x63, 0x58, 0x44, 0x59, 0x32, 0x4C, - 0x6A, 0x6B, 0x7A, 0x4C, 0x6A, 0x59, 0x34, 0x4C, - 0x6A, 0x5A, 0x63, 0x65, 0x67, 0x41, 0x41, 0x4F, - 0x41, 0x3D, 0x3D, 0x0D, 0x0A,}; - - Flow f; - FLOW_INITIALIZE(&f); - f.alstate = SMTPStateAlloc(); - MimeDecParseState *state = MimeDecInitParser(&f, NULL); - ((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT; - state->body_begin = 1; - int ret; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg, sizeof(mimemsg), state); - - - return ret; -} - - - -int SMTPProcessDataChunkTest03(void){ - char mimemsg[] = {0x4D, 0x49, 0x4D, 0x45, 0x2D, 0x56, 0x65, 0x72, }; - char mimemsg2[] = {0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x31, 0x2E, }; - char mimemsg3[] = {0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, }; - char mimemsg4[] = {0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x3A, }; - char mimemsg5[] = {0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, }; - char mimemsg6[] = {0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6F, 0x63, 0x74, }; - char mimemsg7[] = {0x65, 0x74, 0x2D, 0x73, 0x74, 0x72, 0x65, 0x61, }; - char mimemsg8[] = {0x6D, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, }; - char mimemsg9[] = {0x6E, 0x74, 0x2D, 0x54, 0x72, 0x61, 0x6E, 0x73, }; - char mimemsg10[] = {0x66, 0x65, 0x72, 0x2D, 0x45, 0x6E, 0x63, 0x6F, }; - char mimemsg11[] = {0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x62, 0x61, }; - char mimemsg12[] = {0x73, 0x65, 0x36, 0x34, 0x0D, 0x0A, 0x43, 0x6F, }; - - Flow f; - FLOW_INITIALIZE(&f); - f.alstate = SMTPStateAlloc(); - MimeDecParseState *state = MimeDecInitParser(&f, NULL); - ((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT; - int ret; - - state->body_begin = 1; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg, sizeof(mimemsg), state); - if(ret) goto end; - state->body_begin = 0; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg2, sizeof(mimemsg2), state); - if(ret) goto end; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg3, sizeof(mimemsg3), state); - if(ret) goto end; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg4, sizeof(mimemsg4), state); - if(ret) goto end; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg5, sizeof(mimemsg5), state); - if(ret) goto end; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg6, sizeof(mimemsg6), state); - if(ret) goto end; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg7, sizeof(mimemsg7), state); - if(ret) goto end; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg8, sizeof(mimemsg8), state); - if(ret) goto end; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg9, sizeof(mimemsg9), state); - if(ret) goto end; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg10, sizeof(mimemsg10), state); - if(ret) goto end; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg11, sizeof(mimemsg11), state); - if(ret) goto end; - state->body_end = 1; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg12, sizeof(mimemsg12), state); - if(ret) goto end; - - end: - return ret; -} - - -int SMTPProcessDataChunkTest04(void){ - char mimemsg[] = {0x4D, 0x49, 0x4D, 0x45, 0x2D, 0x56, 0x65, 0x72, }; - char mimemsg2[] = {0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x31, 0x2E, }; - char mimemsg3[] = {0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, }; - char mimemsg4[] = {0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x3A, }; - char mimemsg5[] = {0x20, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, }; - char mimemsg6[] = {0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x6F, 0x63, 0x74, }; - char mimemsg7[] = {0x65, 0x74, 0x2D, 0x73, 0x74, 0x72, 0x65, 0x61, }; - char mimemsg8[] = {0x6D, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, }; - char mimemsg9[] = {0x6E, 0x74, 0x2D, 0x54, 0x72, 0x61, 0x6E, 0x73, }; - char mimemsg10[] = {0x66, 0x65, 0x72, 0x2D, 0x45, 0x6E, 0x63, 0x6F, }; - char mimemsg11[] = {0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x62, 0x61, }; - - Flow f; - FLOW_INITIALIZE(&f); - f.alstate = SMTPStateAlloc(); - MimeDecParseState *state = MimeDecInitParser(&f, NULL); - ((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT; - int ret = MIME_DEC_OK; - - state->body_begin = 1; - if(SMTPProcessDataChunk((uint8_t *)mimemsg, sizeof(mimemsg), state) != 0) goto end; - if(SMTPProcessDataChunk((uint8_t *)mimemsg2, sizeof(mimemsg2), state) != 0) goto end; - if(SMTPProcessDataChunk((uint8_t *)mimemsg3, sizeof(mimemsg3), state) != 0) goto end; - if(SMTPProcessDataChunk((uint8_t *)mimemsg4, sizeof(mimemsg4), state) != 0) goto end; - if(SMTPProcessDataChunk((uint8_t *)mimemsg5, sizeof(mimemsg5), state) != 0) goto end; - if(SMTPProcessDataChunk((uint8_t *)mimemsg6, sizeof(mimemsg6), state) != 0) goto end; - if(SMTPProcessDataChunk((uint8_t *)mimemsg7, sizeof(mimemsg7), state) != 0) goto end; - state->body_begin = 0; - state->body_end = 1; - if(SMTPProcessDataChunk((uint8_t *)mimemsg8, sizeof(mimemsg8), state) != 0) goto end; - state->body_end = 0; - if(SMTPProcessDataChunk((uint8_t *)mimemsg9, sizeof(mimemsg9), state) != 0) goto end; - if(SMTPProcessDataChunk((uint8_t *)mimemsg10, sizeof(mimemsg10), state) != 0) goto end; - if(SMTPProcessDataChunk((uint8_t *)mimemsg11, sizeof(mimemsg11), state) != 0) goto end; - - end: - return ret; -} - -int SMTPProcessDataChunkTest05(void){ - char mimemsg[] = {0x4D, 0x49, 0x4D, 0x45, 0x2D, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x31, 0x2E, - 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, - 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x3A, - 0x6A, 0x6B, 0x7A, 0x4C, 0x6A, 0x59, 0x34, 0x4C, - 0x6A, 0x5A, 0x63, 0x65, 0x67, 0x41, 0x41, 0x4F, - 0x41, 0x3D, 0x3D, 0x0D, 0x0A,}; - - Flow f; - FLOW_INITIALIZE(&f); - f.alstate = SMTPStateAlloc(); - MimeDecParseState *state = MimeDecInitParser(&f, NULL); - ((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT; - state->body_begin = 1; - int ret; - uint64_t file_size = 0; - ret = SMTPProcessDataChunk((uint8_t *)mimemsg, sizeof(mimemsg), state); - state->body_begin = 0; - if(ret){goto end;} - SMTPState *smtp_state = (SMTPState *)((Flow *)state->data)->alstate; - FileContainer *files = smtp_state->files_ts; - File *file = files->head; - file_size = file->size; - - FileDisableStoring(&f, STREAM_TOSERVER); - FileDisableMagic(&f, STREAM_TOSERVER); - FileDisableMd5(&f, STREAM_TOSERVER); - ret = SMTPProcessDataChunk((uint8_t *)mimemsg, sizeof(mimemsg), state); - if(ret){goto end;} - printf("%u\t%u\n", (uint32_t) file->size, (uint32_t) file_size); - if(file->size == file_size){ - return 0; - }else{ - return 1; - } - - end: - return ret; -} - -#endif /* UNITTESTS */ - -void SMTPParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SMTPParserTest01", SMTPParserTest01, 1); - UtRegisterTest("SMTPParserTest02", SMTPParserTest02, 1); - UtRegisterTest("SMTPParserTest03", SMTPParserTest03, 1); - UtRegisterTest("SMTPParserTest04", SMTPParserTest04, 1); - UtRegisterTest("SMTPParserTest05", SMTPParserTest05, 1); - UtRegisterTest("SMTPParserTest06", SMTPParserTest06, 1); - UtRegisterTest("SMTPParserTest07", SMTPParserTest07, 1); - UtRegisterTest("SMTPParserTest08", SMTPParserTest08, 1); - UtRegisterTest("SMTPParserTest09", SMTPParserTest09, 1); - UtRegisterTest("SMTPParserTest10", SMTPParserTest10, 1); - UtRegisterTest("SMTPParserTest11", SMTPParserTest11, 1); - UtRegisterTest("SMTPParserTest12", SMTPParserTest12, 1); - UtRegisterTest("SMTPParserTest13", SMTPParserTest13, 1); - UtRegisterTest("SMTPParserTest14", SMTPParserTest14, 1); - UtRegisterTest("SMTPProcessDataChunkTest01", SMTPProcessDataChunkTest01, 0); - UtRegisterTest("SMTPProcessDataChunkTest02", SMTPProcessDataChunkTest02, 0); - UtRegisterTest("SMTPProcessDataChunkTest03", SMTPProcessDataChunkTest03, 0); - UtRegisterTest("SMTPProcessDataChunkTest04", SMTPProcessDataChunkTest04, 0); - UtRegisterTest("SMTPProcessDataChunkTest05", SMTPProcessDataChunkTest05, 0); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/app-layer-smtp.h b/framework/src/suricata/src/app-layer-smtp.h deleted file mode 100644 index c5868414..00000000 --- a/framework/src/suricata/src/app-layer-smtp.h +++ /dev/null @@ -1,165 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __APP_LAYER_SMTP_H__ -#define __APP_LAYER_SMTP_H__ - -#include "decode-events.h" -#include "util-decode-mime.h" -#include "queue.h" - -enum { - SMTP_DECODER_EVENT_INVALID_REPLY, - SMTP_DECODER_EVENT_UNABLE_TO_MATCH_REPLY_WITH_REQUEST, - SMTP_DECODER_EVENT_MAX_COMMAND_LINE_LEN_EXCEEDED, - SMTP_DECODER_EVENT_MAX_REPLY_LINE_LEN_EXCEEDED, - SMTP_DECODER_EVENT_INVALID_PIPELINED_SEQUENCE, - SMTP_DECODER_EVENT_BDAT_CHUNK_LEN_EXCEEDED, - SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE, - SMTP_DECODER_EVENT_TLS_REJECTED, - SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED, - - /* MIME Events */ - SMTP_DECODER_EVENT_MIME_PARSE_FAILED, - SMTP_DECODER_EVENT_MIME_MALFORMED_MSG, - SMTP_DECODER_EVENT_MIME_INVALID_BASE64, - SMTP_DECODER_EVENT_MIME_INVALID_QP, - SMTP_DECODER_EVENT_MIME_LONG_LINE, - SMTP_DECODER_EVENT_MIME_LONG_ENC_LINE, - SMTP_DECODER_EVENT_MIME_LONG_HEADER_NAME, - SMTP_DECODER_EVENT_MIME_LONG_HEADER_VALUE, - SMTP_DECODER_EVENT_MIME_BOUNDARY_TOO_LONG, -}; - -typedef struct SMTPString_ { - uint8_t *str; - uint16_t len; - - TAILQ_ENTRY(SMTPString_) next; -} SMTPString; - -typedef struct SMTPTransaction_ { - /** id of this tx, starting at 0 */ - uint64_t tx_id; - int done; - /** the first message contained in the session */ - MimeDecEntity *msg_head; - /** the last message contained in the session */ - MimeDecEntity *msg_tail; - /** the mime decoding parser state */ - MimeDecParseState *mime_state; - - AppLayerDecoderEvents *decoder_events; /**< per tx events */ - DetectEngineState *de_state; - - /* MAIL FROM parameters */ - uint8_t *mail_from; - uint16_t mail_from_len; - - TAILQ_HEAD(, SMTPString_) rcpt_to_list; /**< rcpt to string list */ - - TAILQ_ENTRY(SMTPTransaction_) next; -} SMTPTransaction; - -typedef struct SMTPConfig { - - int decode_mime; - MimeDecConfig mime_config; - uint32_t content_limit; - uint32_t content_inspect_min_size; - uint32_t content_inspect_window; -} SMTPConfig; - -typedef struct SMTPState_ { - SMTPTransaction *curr_tx; - TAILQ_HEAD(, SMTPTransaction_) tx_list; /**< transaction list */ - uint64_t tx_cnt; - - /* current input that is being parsed */ - uint8_t *input; - int32_t input_len; - uint8_t direction; - - /* --parser details-- */ - /** current line extracted by the parser from the call to SMTPGetline() */ - uint8_t *current_line; - /** length of the line in current_line. Doesn't include the delimiter */ - int32_t current_line_len; - uint8_t current_line_delimiter_len; - PatternMatcherQueue *thread_local_data; - - /** used to indicate if the current_line buffer is a malloced buffer. We - * use a malloced buffer, if a line is fragmented */ - uint8_t *tc_db; - int32_t tc_db_len; - uint8_t tc_current_line_db; - /** we have see LF for the currently parsed line */ - uint8_t tc_current_line_lf_seen; - - /** used to indicate if the current_line buffer is a malloced buffer. We - * use a malloced buffer, if a line is fragmented */ - uint8_t *ts_db; - int32_t ts_db_len; - uint8_t ts_current_line_db; - /** we have see LF for the currently parsed line */ - uint8_t ts_current_line_lf_seen; - - /** var to indicate parser state */ - uint8_t parser_state; - /** current command in progress */ - uint8_t current_command; - /** bdat chunk len */ - uint32_t bdat_chunk_len; - /** bdat chunk idx */ - uint32_t bdat_chunk_idx; - - /* the request commands are store here and the reply handler uses these - * stored command in the buffer to match the reply(ies) with the command */ - /** the command buffer */ - uint8_t *cmds; - /** the buffer length */ - uint16_t cmds_buffer_len; - /** no of commands stored in the above buffer */ - uint16_t cmds_cnt; - /** index of the command in the buffer, currently in inspection by reply - * handler */ - uint16_t cmds_idx; - - /* SMTP Mime decoding and file extraction */ - /** the list of files sent to the server */ - FileContainer *files_ts; - - /* HELO of HELO message content */ - uint8_t *helo; - uint16_t helo_len; -} SMTPState; - -/* Create SMTP config structure */ -extern SMTPConfig smtp_config; - -int SMTPProcessDataChunk(const uint8_t *chunk, uint32_t len, MimeDecParseState *state); -void *SMTPStateAlloc(void); -void RegisterSMTPParsers(void); -void SMTPParserRegisterTests(void); - -#endif /* __APP_LAYER_SMTP_H__ */ diff --git a/framework/src/suricata/src/app-layer-ssh.c b/framework/src/suricata/src/app-layer-ssh.c deleted file mode 100644 index 879c7746..00000000 --- a/framework/src/suricata/src/app-layer-ssh.c +++ /dev/null @@ -1,2607 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * \author Victor Julien - * - * App-layer parser for SSH protocol - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-ssh.h" - -#include "conf.h" - -#include "util-spm.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "flow-private.h" - -#include "util-byte.h" -#include "util-memcmp.h" - -/** \internal - * \brief Function to parse the SSH version string of the client - * - * The input to this function is a byte buffer starting with SSH- - * - * \param ssh_state Pointer the state in which the value to be stored - * \param input Pointer the received input data - * \param input_len Length in bytes of the received data - * - * \retval len remaining length in input - */ -static int SSHParseBanner(SshState *state, SshHeader *header, const uint8_t *input, uint32_t input_len) -{ - const uint8_t *line_ptr = input; - uint32_t line_len = input_len; - - /* is it the version line? */ - if (SCMemcmp("SSH-", line_ptr, 4) != 0) { - SCReturnInt(-1); - } - - const uint8_t *banner_end = BasicSearch(line_ptr, line_len, (uint8_t*)"\r", 1); - if (banner_end == NULL) { - banner_end = BasicSearch(line_ptr, line_len, (uint8_t*)"\n", 1); - if (banner_end == NULL) { - SCLogDebug("No EOL at the end of banner buffer"); - SCReturnInt(-1); - } - } - - if ((banner_end - line_ptr) > 255) { - SCLogDebug("Invalid version string, it should be less than 255 " - "characters including , input value is %"PRIuMAX, - (banner_end - line_ptr)); - SCReturnInt(-1); - } - - /* don't search things behind the end of banner */ - line_len = banner_end - line_ptr; - - /* ok, we have found the version line/string, skip it and parse proto version */ - line_ptr += 4; - line_len -= 4; - - uint8_t *proto_end = BasicSearch(line_ptr, line_len, (uint8_t*)"-", 1); - if (proto_end == NULL) { - /* Strings starting with SSH- are not allowed - * if they are not the real version string */ - SCLogDebug("Info Version String for SSH (invalid usage of SSH- prefix)"); - SCReturnInt(-1); - } - uint64_t proto_ver_len = (uint64_t)(proto_end - line_ptr); - header->proto_version = SCMalloc(proto_ver_len + 1); - if (header->proto_version == NULL) { - SCReturnInt(-1); - } - memcpy(header->proto_version, line_ptr, proto_ver_len); - header->proto_version[proto_ver_len] = '\0'; - - /* Now lets parse the software & version */ - line_ptr += proto_ver_len + 1; - line_len -= proto_ver_len + 1; - if (line_len < 1) { - SCLogDebug("No software version specified (weird)"); - header->flags |= SSH_FLAG_VERSION_PARSED; - /* Return the remaining length */ - SCReturnInt(0); - } - - uint64_t sw_ver_len = (uint64_t)(banner_end - line_ptr); - /* sanity check on this arithmetic */ - if ((sw_ver_len <= 1) || (sw_ver_len >= input_len)) { - SCLogDebug("Should not have sw version length '%" PRIu64 "'", sw_ver_len); - SCReturnInt(-1); - } - - header->software_version = SCMalloc(sw_ver_len + 1); - if (header->software_version == NULL) { - SCReturnInt(-1); - } - memcpy(header->software_version, line_ptr, sw_ver_len); - header->software_version[sw_ver_len] = '\0'; - if (header->software_version[sw_ver_len - 1] == 0x0d) - header->software_version[sw_ver_len - 1] = '\0'; - - header->flags |= SSH_FLAG_VERSION_PARSED; - - /* Return the remaining length */ - int len = input_len - (banner_end - input); - SCReturnInt(len); -} - -static int SSHParseRecordHeader(SshState *state, SshHeader *header, - const uint8_t *input, uint32_t input_len) -{ -#ifdef DEBUG - BUG_ON(input_len != 6); -#else - if (input_len < 6) - SCReturnInt(-1); -#endif - /* input and input_len now point past initial line */ - uint32_t pkt_len = 0; - int r = ByteExtractUint32(&pkt_len, BYTE_BIG_ENDIAN, - 4, input); - if (r != 4) { - SCLogDebug("xtract 4 bytes failed %d", r); - SCReturnInt(-1); - } - if (pkt_len < 2) { - SCReturnInt(-1); - } - - header->pkt_len = pkt_len; - SCLogDebug("pkt len: %"PRIu32, pkt_len); - - input += 4; - //input_len -= 4; - - header->padding_len = *input; - - input += 1; - //input_len -= 1; - - SCLogDebug("padding: %u", header->padding_len); - - header->msg_code = *input; - - SCLogDebug("msg code: %u", header->msg_code); - - if (header->msg_code == SSH_MSG_NEWKEYS) { - /* done */ - SCLogDebug("done"); - header->flags |= SSH_FLAG_PARSER_DONE; - } else { - /* not yet done */ - SCLogDebug("not done"); - } - SCReturnInt(0); -} - -/** \internal - * \brief Function to parse the SSH field in packet received from the client - * - * Input to this function is a byte buffer starting with SSH- up to at least - * a \r or \n character. - * - * \param ssh_state Pointer the state in which the value to be stored - * \param input Pointer the received input data - * \param input_len Length in bytes of the received data - */ -static int SSHParseRecord(SshState *state, SshHeader *header, uint8_t *input, uint32_t input_len) -{ - SCEnter(); - int ret = 0; - - if (header->flags & SSH_FLAG_PARSER_DONE) { - SCReturnInt(0); - } - - SCLogDebug("state %p, input %p,input_len %" PRIu32, - state, input, input_len); - //PrintRawDataFp(stdout, input, input_len); - - if (!(header->flags & SSH_FLAG_VERSION_PARSED)) { - ret = SSHParseBanner(state, header, input, input_len); - if (ret < 0) { - SCLogDebug("Invalid version string"); - SCReturnInt(-1); - } else if (header->flags & SSH_FLAG_VERSION_PARSED) { - SCLogDebug("Version string parsed, remaining length %d", ret); - input += input_len - ret; - input_len -= (input_len - ret); - - uint32_t u = 0; - while (u < input_len && (input[u] == '\r' || input[u] == '\n')) { - u++; - } - SCLogDebug("skipping %u EOL bytes", u); - input += u; - input_len -= u; - - if (input_len == 0) - SCReturnInt(0); - - } else { - BUG_ON(1);// we only call this when we have enough data - SCLogDebug("Version string not parsed yet"); - //pstate->parse_field = 0; - SCReturnInt(0); - } - } else { - SCLogDebug("Version string already parsed"); - } - - /* skip bytes from the current record if we have to */ - if (header->record_left > 0) { - SCLogDebug("skipping bytes part of the current record"); - if (header->record_left > input_len) { - header->record_left -= input_len; - SCLogDebug("all input skipped, %u left in record", header->record_left); - SCReturnInt(0); - } else { - input_len -= header->record_left; - input += header->record_left; - header->record_left = 0; - - if (input_len == 0) { - SCLogDebug("all input skipped"); - SCReturnInt(0); - } - } - } - -again: - /* input is too small, even when combined with stored bytes */ - if (header->buf_offset + input_len < 6) { - memcpy(header->buf + header->buf_offset, input, input_len); - header->buf_offset += input_len; - SCReturnInt(0); - - /* we have enough bytes to parse 6 bytes, lets see if we have - * previously stored some */ - } else if (header->buf_offset > 0) { - uint8_t needed = 6 - header->buf_offset; - - SCLogDebug("parse stored"); - memcpy(header->buf + header->buf_offset, input, needed); - header->buf_offset = 6; - - // parse the 6 - if (SSHParseRecordHeader(state, header, header->buf, 6) < 0) - SCReturnInt(-1); - header->buf_offset = 0; - - uint32_t record_left = header->pkt_len - 2; - input_len -= needed; - input += needed; - - if (record_left > input_len) { - header->record_left = record_left - input_len; - } else { - input_len -= record_left; - if (input_len == 0) - SCReturnInt(0); - - input += record_left; - - SCLogDebug("we have %u left to parse", input_len); - goto again; - - } - - /* nothing stored, lets parse this directly */ - } else { - SCLogDebug("parse direct"); - //PrintRawDataFp(stdout, input, input_len); - if (SSHParseRecordHeader(state, header, input, 6) < 0) - SCReturnInt(-1); - - uint32_t record_left = header->pkt_len - 2; - SCLogDebug("record left %u", record_left); - input_len -= 6; - input += 6; - - if (record_left > input_len) { - header->record_left = record_left - input_len; - } else { - input_len -= record_left; - if (input_len == 0) - SCReturnInt(0); - input += record_left; - //PrintRawDataFp(stdout, input, input_len); - - SCLogDebug("we have %u left to parse", input_len); - goto again; - } - } - - SCReturnInt(0); -} - -static int EnoughData(uint8_t *input, uint32_t input_len) -{ - uint32_t u; - for (u = 0; u < input_len; u++) { - if (input[u] == '\r' || input[u] == '\n') - return TRUE; - } - return FALSE; -} - -#define MAX_BANNER_LEN 256 - -static int SSHParseData(SshState *state, SshHeader *header, - uint8_t *input, uint32_t input_len) -{ - /* we're looking for the banner */ - if (!(header->flags & SSH_FLAG_VERSION_PARSED)) - { - int banner_eol = EnoughData(input, input_len); - - /* fast track normal case: no buffering */ - if (header->banner_buffer == NULL && banner_eol) - { - SCLogDebug("enough data, parse now"); - // parse now - int r = SSHParseRecord(state, header, input, input_len); - SCReturnInt(r); - - /* banner EOL with existing buffer present. Time for magic. */ - } else if (banner_eol) { - SCLogDebug("banner EOL with existing buffer"); - - uint32_t tocopy = MAX_BANNER_LEN - header->banner_len; - if (tocopy > input_len) - tocopy = input_len; - - SCLogDebug("tocopy %u input_len %u", tocopy, input_len); - memcpy(header->banner_buffer + header->banner_len, input, tocopy); - header->banner_len += tocopy; - - SCLogDebug("header->banner_len %u", header->banner_len); - int r = SSHParseRecord(state, header, - header->banner_buffer, header->banner_len); - if (r == 0) { - input += tocopy; - input_len -= tocopy; - if (input_len > 0) { - SCLogDebug("handling remaining data %u", input_len); - r = SSHParseRecord(state, header, input, input_len); - } - } - SCReturnInt(r); - - /* no banner EOL, so we need to buffer */ - } else if (!banner_eol) { - if (header->banner_buffer == NULL) { - header->banner_buffer = SCMalloc(MAX_BANNER_LEN); - if (header->banner_buffer == NULL) - SCReturnInt(-1); - } - - uint32_t tocopy = MAX_BANNER_LEN - header->banner_len; - if (tocopy > input_len) - tocopy = input_len; - SCLogDebug("tocopy %u", tocopy); - - memcpy(header->banner_buffer + header->banner_len, input, tocopy); - header->banner_len += tocopy; - SCLogDebug("header->banner_len %u", header->banner_len); - } - - /* we have a banner, the rest is just records */ - } else { - int r = SSHParseRecord(state, header, input, input_len); - SCReturnInt(r); - } - - //PrintRawDataFp(stdout, input, input_len); - return 0; -} - -static int SSHParseRequest(Flow *f, void *state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SshState *ssh_state = (SshState *)state; - SshHeader *ssh_header = &ssh_state->cli_hdr; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - int r = SSHParseData(ssh_state, ssh_header, input, input_len); - - if (ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE && - ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE) { - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_INSPECTION); - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY); - } - - SCReturnInt(r); -} - -static int SSHParseResponse(Flow *f, void *state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - SshState *ssh_state = (SshState *)state; - SshHeader *ssh_header = &ssh_state->srv_hdr; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - int r = SSHParseData(ssh_state, ssh_header, input, input_len); - - if (ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE && - ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE) { - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_INSPECTION); - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY); - } - - SCReturnInt(r); -} - -/** \brief Function to allocates the SSH state memory - */ -static void *SSHStateAlloc(void) -{ - void *s = SCMalloc(sizeof(SshState)); - if (unlikely(s == NULL)) - return NULL; - - memset(s, 0, sizeof(SshState)); - return s; -} - -/** \brief Function to free the SSH state memory - */ -static void SSHStateFree(void *state) -{ - SshState *s = (SshState *)state; - if (s->cli_hdr.proto_version != NULL) - SCFree(s->cli_hdr.proto_version); - if (s->cli_hdr.software_version != NULL) - SCFree(s->cli_hdr.software_version); - if (s->cli_hdr.banner_buffer != NULL) - SCFree(s->cli_hdr.banner_buffer); - - if (s->srv_hdr.proto_version != NULL) - SCFree(s->srv_hdr.proto_version); - if (s->srv_hdr.software_version != NULL) - SCFree(s->srv_hdr.software_version); - if (s->srv_hdr.banner_buffer != NULL) - SCFree(s->srv_hdr.banner_buffer); - - SCFree(s); -} - -static int SSHRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_SSH, - "SSH-", 4, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_SSH, - "SSH-", 4, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - return 0; -} - -/** \brief Function to register the SSH protocol parsers and other functions - */ -void RegisterSSHParsers(void) -{ - char *proto_name = "ssh"; - - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_SSH, proto_name); - if (SSHRegisterPatternsForProtocolDetection() < 0) - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SSH, STREAM_TOSERVER, - SSHParseRequest); - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_SSH, STREAM_TOCLIENT, - SSHParseResponse); - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_SSH, SSHStateAlloc, SSHStateFree); - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, - ALPROTO_SSH, STREAM_TOSERVER|STREAM_TOCLIENT); - } else { -// SCLogInfo("Parsed disabled for %s protocol. Protocol detection" -// "still on.", proto_name); - } - -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_SSH, SSHParserRegisterTests); -#endif -} - -/* UNITTESTS */ -#ifdef UNITTESTS - -/** \test Send a version string in one chunk (client version str). */ -static int SSHParserTest01(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk but multiple lines and comments. - * (client version str) - */ -static int SSHParserTest02(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1 some comments...\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a invalid version string in one chunk but multiple lines and comments. - * (client version str) - */ -static int SSHParserTest03(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0 some comments...\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r == 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected != 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED) { - printf("Client version string parsed? It's not a valid string: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version != NULL) { - goto end; - } - - if (ssh_state->cli_hdr.software_version != NULL) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk (server version str). */ -static int SSHParserTest04(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk (server version str) - */ -static int SSHParserTest05(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-MySSHClient-0.5.1 some comments...\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a invalid version string in one chunk (server version str) - */ -static int SSHParserTest06(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0 some comments...\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT|STREAM_EOF, sshbuf, sshlen); - if (r == 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected != 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* Ok, it returned an error. Let's make sure we didn't parse the string at all */ - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED) { - printf("Client version string parsed? It's not a valid string: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version != NULL) { - goto end; - } - - if (ssh_state->srv_hdr.software_version != NULL) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -static int SSHParserTest07(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2."; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { "0-MySSHClient-0.5.1\r\n"}; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version banner in three chunks. */ -static int SSHParserTest08(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2."; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = { "0-MySSHClient-0.5.1\r\n"}; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -static int SSHParserTest09(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2."; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { "0-MySSHClient-0.5.1\r\n"}; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version banner in three chunks. */ -static int SSHParserTest10(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2."; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = { "0-MySSHClient-0.5.1\r\n"}; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and record in three chunks. */ -static int SSHParserTest11(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00}; - uint32_t sshlen2 = sizeof(sshbuf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and 2 records record in four chunks. */ -static int SSHParserTest12(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x03,0x01, 17, 0x00}; - uint32_t sshlen2 = sizeof(sshbuf2); - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03,0x01, 21, 0x00}; - uint32_t sshlen3 = sizeof(sshbuf3); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and 2 records record in four chunks. */ -static int SSHParserTest13(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 17}; - uint32_t sshlen2 = sizeof(sshbuf2); - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x02, 0x01, 21}; - uint32_t sshlen3 = sizeof(sshbuf3); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - uint32_t u; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - for (u = 0; u < sshlen2; u++) { - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, &sshbuf2[u], 1); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - } - for (u = 0; u < sshlen3; u++) { - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, &sshbuf3[u], 1); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - } - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and 2 records record in four chunks. */ -static int SSHParserTest14(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x10, 0x01, 17, 0x00}; - uint32_t sshlen2 = sizeof(sshbuf2); - - uint8_t sshbuf3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - uint32_t sshlen3 = sizeof(sshbuf3); - uint8_t sshbuf4[] = { 0x09, 0x10, 0x11, 0x12, 0x13, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4); - - /* first byte of this record in sshbuf4 */ - uint8_t sshbuf5[] = { 0x00, 0x00, 0x02, 0x01, 21}; - uint32_t sshlen5 = sizeof(sshbuf5); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf5, sshlen5); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a banner and 2 records record in four chunks. */ -static int SSHParserTest15(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = { 0x00, 0x00, 0x00, 0x10, 0x01, 17, 0x00}; - uint32_t sshlen2 = sizeof(sshbuf2); - - uint8_t sshbuf3[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; - uint32_t sshlen3 = sizeof(sshbuf3); - uint8_t sshbuf4[] = { 0x09, 0x10, 0x11, 0x12, 0x13, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4); - - /* first byte of this record in sshbuf4 */ - uint8_t sshbuf5[] = { 0x00, 0x00, 0x02, 0x01, 20, 0x00, 0x00, 0x00, 0x02, 0x01, 21}; - uint32_t sshlen5 = sizeof(sshbuf5); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf5, sshlen5); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->cli_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send toserver a banner and record in three chunks. */ -static int SSHParserTest16(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03,0x01, 21, 0x00}; - uint32_t sshlen3 = sizeof(sshbuf3); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send toserver a banner and 2 records record in four chunks. */ -static int SSHParserTest17(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 17, 0x00}; - uint32_t sshlen3 = sizeof(sshbuf3); - uint8_t sshbuf4[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.software_version, "MySSHClient-0.5.1", strlen("MySSHClient-0.5.1")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test 2 directional test */ -static int SSHParserTest18(void) -{ - int result = 0; - Flow f; - - uint8_t server1[] = "SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu3\r\n"; - uint32_t serverlen1 = sizeof(server1) - 1; - - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-MySSHClient-0.5.1\r\n"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - - uint8_t server2[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00 }; - uint32_t serverlen2 = sizeof(server2) - 1; - - uint8_t sshbuf3[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00 }; - uint32_t sshlen3 = sizeof(sshbuf3); - - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, server1, serverlen1); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, server2, serverlen2); - if (r != 0) { - printf("toclient chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - if (!(AppLayerParserStateIssetFlag(f.alparser, APP_LAYER_PARSER_NO_INSPECTION))) { - printf("detection not disabled: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Really long banner handling: bannel exactly 255 */ -static int SSHParserTest19(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; // 8 - uint8_t sshbuf3[] = "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//60 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//112 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//164 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//216 - "abcdefghijklmnopqrstuvwxyz"//242 - "abcdefghijkl\r";//255 - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - - uint8_t sshbuf4[] = { 0x00, 0x00, 0x00, 0x03, 0x01, 21, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - char *name = SCMalloc(256); - if (name == NULL) - goto end; - memset(name, 0x00, 256); - strlcpy(name, (char *)sshbuf3, strlen((char *)sshbuf3) - 1); - - if (strncmp((char*)ssh_state->srv_hdr.software_version, name, strlen(name)) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Really long banner handling: banner exactly 255, - * followed by malformed record */ -static int SSHParserTest20(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; // 8 - uint8_t sshbuf3[] = "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//60 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//112 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//164 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//216 - "abcdefghijklmnopqrstuvwxyz"//242 - "abcdefghijklm\r";//256 - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = {'a','b','c','d','e','f', '\r', - 0x00, 0x00, 0x00, 0x06, 0x01, 21, 0x00, 0x00, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCLogDebug("chunk 4:"); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ((ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("detected the msg code of new keys (ciphered data starts): "); - goto end; - } - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Fragmented banner handling: chunk has final part of bannel plus - * a record. */ -static int SSHParserTest21(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; // 8 - uint8_t sshbuf3[] = "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//60 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//112 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//164 - "abcdefghijklmnopqrstuvwxyz" - "abcdefghijklmnopqrstuvwxyz"//216 - "abcdefghijklmnopqrstuvwxy";//241 - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = {'l','i','b','s','s','h', '\r', - 0x00, 0x00, 0x00, 0x06, 0x01, 21, 0x00, 0x00, 0x00}; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCLogDebug("chunk 4:"); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Fragmented banner handling: chunk has final part of bannel plus - * a record. */ -static int SSHParserTest22(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "2.0-"; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; // 8 - uint8_t sshbuf3[] = { - 'l', 'i', 'b', 's', 's', 'h', '\r', //7 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //50 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //100 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //150 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //200 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, //250 - - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 17, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x01, 21, 0x00, 0x00, 0x00, 0x00, //300 - }; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); -#if 0 - SCLogDebug("chunk 4:"); - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOCLIENT, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); -#endif - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if (!(ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.software_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->srv_hdr.proto_version == NULL) { - printf("Client version string not parsed: "); - goto end; - } - - if (strncmp((char*)ssh_state->srv_hdr.proto_version, "2.0", strlen("2.0")) != 0) { - printf("Client version string not parsed correctly: "); - goto end; - } - - if ( !(ssh_state->srv_hdr.flags & SSH_FLAG_PARSER_DONE)) { - printf("Didn't detect the msg code of new keys (ciphered data starts): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk (client version str). */ -static int SSHParserTest23(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0\r-MySSHClient-0.5.1\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r == 0) { - printf("toclient chunk 1 returned 0 expected non null: "); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a version string in one chunk (client version str). */ -static int SSHParserTest24(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf[] = "SSH-2.0-\rMySSHClient-0.5.1\n"; - uint32_t sshlen = sizeof(sshbuf) - 1; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER|STREAM_EOF, sshbuf, sshlen); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - if ( !(ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - printf("Client version string not parsed: "); - goto end; - } - - if (ssh_state->cli_hdr.software_version) { - printf("Client version string should not be parsed: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - - -#endif /* UNITTESTS */ - -void SSHParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SSHParserTest01 - ToServer", SSHParserTest01, 1); - UtRegisterTest("SSHParserTest02 - ToServer", SSHParserTest02, 1); - UtRegisterTest("SSHParserTest03 - ToServer", SSHParserTest03, 1); - UtRegisterTest("SSHParserTest04 - ToClient", SSHParserTest04, 1); - UtRegisterTest("SSHParserTest05 - ToClient", SSHParserTest05, 1); - UtRegisterTest("SSHParserTest06 - ToClient", SSHParserTest06, 1); - UtRegisterTest("SSHParserTest07 - ToServer 2 chunks", SSHParserTest07, 1); - UtRegisterTest("SSHParserTest08 - ToServer 3 chunks", SSHParserTest08, 1); - UtRegisterTest("SSHParserTest09 - ToClient 2 chunks", SSHParserTest09, 1); - UtRegisterTest("SSHParserTest10 - ToClient 3 chunks", SSHParserTest10, 1); - UtRegisterTest("SSHParserTest11 - ToClient 4 chunks", SSHParserTest11, 1); - UtRegisterTest("SSHParserTest12 - ToClient 4 chunks", SSHParserTest12, 1); - UtRegisterTest("SSHParserTest13 - ToClient 4 chunks", SSHParserTest13, 1); - UtRegisterTest("SSHParserTest14 - ToClient 4 chunks", SSHParserTest14, 1); - UtRegisterTest("SSHParserTest15", SSHParserTest15, 1); - UtRegisterTest("SSHParserTest16", SSHParserTest16, 1); - UtRegisterTest("SSHParserTest17", SSHParserTest17, 1); - UtRegisterTest("SSHParserTest18", SSHParserTest18, 1); - UtRegisterTest("SSHParserTest19", SSHParserTest19, 1); - UtRegisterTest("SSHParserTest20", SSHParserTest20, 1); - UtRegisterTest("SSHParserTest21", SSHParserTest21, 1); - UtRegisterTest("SSHParserTest22", SSHParserTest22, 1); - UtRegisterTest("SSHParserTest23", SSHParserTest23, 1); - UtRegisterTest("SSHParserTest24", SSHParserTest24, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/app-layer-ssh.h b/framework/src/suricata/src/app-layer-ssh.h deleted file mode 100644 index 4fd59aa9..00000000 --- a/framework/src/suricata/src/app-layer-ssh.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * \author Victor Julien - */ - -#ifndef __APP_LAYER_SSH_H__ -#define __APP_LAYER_SSH_H__ - -/* header flag */ -#define SSH_FLAG_VERSION_PARSED 0x01 - -/* This flags indicate that the rest of the communication - * must be ciphered, so the parsing finish here */ -#define SSH_FLAG_PARSER_DONE 0x02 - -#define SSH_FLAG_STATE_LOGGED 0x04 - -#define SSH_FLAG_STATE_LOGGED_LUA 0x08 - -/* MSG_CODE */ -#define SSH_MSG_NEWKEYS 21 - -/** From SSH-TRANSP rfc - - SSH Bunary packet structure: - uint32 packet_length - byte padding_length - byte[n1] payload; n1 = packet_length - padding_length - 1 - byte[n2] random padding; n2 = padding_length - byte[m] mac (Message Authentication Code - MAC); m = mac_length - - So we are going to do a header struct to store - the lenghts and msg_code (inside payload, if any) -*/ - -typedef struct SshHeader_ { - uint32_t pkt_len; - uint8_t padding_len; - uint8_t msg_code; - uint8_t buf[6]; - uint8_t buf_offset; - uint8_t flags; - uint32_t record_left; - uint8_t *proto_version; - uint8_t *software_version; - uint8_t *banner_buffer; - uint16_t banner_len; -} SshHeader; - -/** structure to store the SSH state values */ -typedef struct SshState_ { - SshHeader srv_hdr; - SshHeader cli_hdr; -} SshState; - -void RegisterSSHParsers(void); -void SSHParserRegisterTests(void); - -#endif /* __APP_LAYER_SSH_H__ */ - diff --git a/framework/src/suricata/src/app-layer-ssl.c b/framework/src/suricata/src/app-layer-ssl.c deleted file mode 100644 index 3d4605af..00000000 --- a/framework/src/suricata/src/app-layer-ssl.c +++ /dev/null @@ -1,4319 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Pierre Chifflier - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "threads.h" - -#include "util-print.h" -#include "util-pool.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream.h" - -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-ssl.h" - -#include "app-layer-tls-handshake.h" - -#include "decode-events.h" -#include "conf.h" - -#include "util-spm.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "flow-util.h" -#include "flow-private.h" - -#include "util-byte.h" - -SCEnumCharMap tls_decoder_event_table[ ] = { - /* TLS protocol messages */ - { "INVALID_SSLV2_HEADER", TLS_DECODER_EVENT_INVALID_SSLV2_HEADER }, - { "INVALID_TLS_HEADER", TLS_DECODER_EVENT_INVALID_TLS_HEADER }, - { "INVALID_RECORD_VERSION", TLS_DECODER_EVENT_INVALID_RECORD_VERSION }, - { "INVALID_RECORD_TYPE", TLS_DECODER_EVENT_INVALID_RECORD_TYPE }, - { "INVALID_HANDSHAKE_MESSAGE", TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE }, - { "HEARTBEAT_MESSAGE", TLS_DECODER_EVENT_HEARTBEAT }, - { "INVALID_HEARTBEAT_MESSAGE", TLS_DECODER_EVENT_INVALID_HEARTBEAT }, - { "OVERFLOW_HEARTBEAT_MESSAGE", TLS_DECODER_EVENT_OVERFLOW_HEARTBEAT }, - { "DATALEAK_HEARTBEAT_MISMATCH", TLS_DECODER_EVENT_DATALEAK_HEARTBEAT_MISMATCH }, - /* Certificates decoding messages */ - { "INVALID_CERTIFICATE", TLS_DECODER_EVENT_INVALID_CERTIFICATE }, - { "CERTIFICATE_MISSING_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT }, - { "CERTIFICATE_UNKNOWN_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT }, - { "CERTIFICATE_INVALID_LENGTH", TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH }, - { "CERTIFICATE_INVALID_STRING", TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING }, - { "ERROR_MESSAGE_ENCOUNTERED", TLS_DECODER_EVENT_ERROR_MSG_ENCOUNTERED }, - /* used as a generic error event */ - { "INVALID_SSL_RECORD", TLS_DECODER_EVENT_INVALID_SSL_RECORD }, - { NULL, -1 }, -}; - -typedef struct SslConfig_ { - int no_reassemble; -} SslConfig; - -SslConfig ssl_config; - -/* SSLv3 record types */ -#define SSLV3_CHANGE_CIPHER_SPEC 20 -#define SSLV3_ALERT_PROTOCOL 21 -#define SSLV3_HANDSHAKE_PROTOCOL 22 -#define SSLV3_APPLICATION_PROTOCOL 23 -#define SSLV3_HEARTBEAT_PROTOCOL 24 - -/* SSLv3 handshake protocol types */ -#define SSLV3_HS_HELLO_REQUEST 0 -#define SSLV3_HS_CLIENT_HELLO 1 -#define SSLV3_HS_SERVER_HELLO 2 -#define SSLV3_HS_NEW_SESSION_TICKET 4 -#define SSLV3_HS_CERTIFICATE 11 -#define SSLV3_HS_SERVER_KEY_EXCHANGE 12 -#define SSLV3_HS_CERTIFICATE_REQUEST 13 -#define SSLV3_HS_SERVER_HELLO_DONE 14 -#define SSLV3_HS_CERTIFICATE_VERIFY 15 -#define SSLV3_HS_CLIENT_KEY_EXCHANGE 16 -#define SSLV3_HS_FINISHED 20 -#define SSLV3_HS_CERTIFICATE_URL 21 -#define SSLV3_HS_CERTIFICATE_STATUS 22 - -/* SSLv2 protocol message types */ -#define SSLV2_MT_ERROR 0 -#define SSLV2_MT_CLIENT_HELLO 1 -#define SSLV2_MT_CLIENT_MASTER_KEY 2 -#define SSLV2_MT_CLIENT_FINISHED 3 -#define SSLV2_MT_SERVER_HELLO 4 -#define SSLV2_MT_SERVER_VERIFY 5 -#define SSLV2_MT_SERVER_FINISHED 6 -#define SSLV2_MT_REQUEST_CERTIFICATE 7 -#define SSLV2_MT_CLIENT_CERTIFICATE 8 - -#define SSLV3_RECORD_HDR_LEN 5 -#define SSLV3_MESSAGE_HDR_LEN 4 - -#define SSLV3_CLIENT_HELLO_VERSION_LEN 2 -#define SSLV3_CLIENT_HELLO_RANDOM_LEN 32 - -/* TLS heartbeat protocol types */ -#define TLS_HB_REQUEST 1 -#define TLS_HB_RESPONSE 2 - -#define HAS_SPACE(n) ((uint32_t)((input) + (n) - (initial_input)) > (uint32_t)(input_len)) ? 0 : 1 - -static void SSLParserReset(SSLState *ssl_state) -{ - ssl_state->curr_connp->bytes_processed = 0; -} - -static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input, - uint32_t input_len) -{ - void *ptmp; - uint8_t *initial_input = input; - uint32_t parsed = 0; - int rc; - - if (input_len == 0) { - return 0; - } - - switch (ssl_state->curr_connp->handshake_type) { - case SSLV3_HS_CLIENT_HELLO: - ssl_state->flags |= SSL_AL_FLAG_STATE_CLIENT_HELLO; - - /* skip version */ - input += SSLV3_CLIENT_HELLO_VERSION_LEN; - - /* skip random */ - input += SSLV3_CLIENT_HELLO_RANDOM_LEN; - - if (!(HAS_SPACE(1))) - goto end; - - /* skip session id */ - uint8_t session_id_length = *(input++); - - input += session_id_length; - - if (!(HAS_SPACE(2))) - goto end; - - /* skip cipher suites */ - uint16_t cipher_suites_length = ntohs(*(uint16_t *)input); - input += 2; - - input += cipher_suites_length; - - if (!(HAS_SPACE(1))) - goto end; - - /* skip compression methods */ - uint8_t compression_methods_length = *(input++); - - input += compression_methods_length; - - if (!(HAS_SPACE(2))) - goto end; - - uint16_t extensions_len = ntohs(*(uint16_t *)input); - input += 2; - - uint16_t processed_len = 0; - while (processed_len < extensions_len) - { - if (!(HAS_SPACE(2))) - goto end; - - uint16_t ext_type = ntohs(*(uint16_t *)input); - input += 2; - - if (!(HAS_SPACE(2))) - goto end; - - uint16_t ext_len = ntohs(*(uint16_t *)input); - input += 2; - - - switch (ext_type) { - case SSL_EXTENSION_SNI: - { - /* skip sni_list_length and sni_type */ - input += 3; - - if (!(HAS_SPACE(2))) - goto end; - - uint16_t sni_len = ntohs(*(uint16_t *)input); - input += 2; - - size_t sni_strlen = sni_len + 1; - ssl_state->curr_connp->sni = SCMalloc(sni_strlen); - - if (unlikely(ssl_state->curr_connp->sni == NULL)) - goto end; - - if (!(HAS_SPACE(sni_len))) - goto end; - - memcpy(ssl_state->curr_connp->sni, input, - sni_strlen - 1); - ssl_state->curr_connp->sni[sni_strlen-1] = 0; - - input += sni_len; - break; - } - default: - { - input += ext_len; - break; - } - } - processed_len += ext_len + 4; - } -end: - break; - - case SSLV3_HS_SERVER_HELLO: - ssl_state->flags |= SSL_AL_FLAG_STATE_SERVER_HELLO; - break; - - case SSLV3_HS_SERVER_KEY_EXCHANGE: - ssl_state->flags |= SSL_AL_FLAG_STATE_SERVER_KEYX; - break; - - case SSLV3_HS_CLIENT_KEY_EXCHANGE: - ssl_state->flags |= SSL_AL_FLAG_STATE_CLIENT_KEYX; - break; - - case SSLV3_HS_CERTIFICATE: - if (ssl_state->curr_connp->trec == NULL) { - ssl_state->curr_connp->trec_len = 2 * ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN + 1; - ssl_state->curr_connp->trec = SCMalloc( ssl_state->curr_connp->trec_len ); - } - if (ssl_state->curr_connp->trec_pos + input_len >= ssl_state->curr_connp->trec_len) { - ssl_state->curr_connp->trec_len = ssl_state->curr_connp->trec_len + 2 * input_len + 1; - ptmp = SCRealloc(ssl_state->curr_connp->trec, - ssl_state->curr_connp->trec_len); - if (unlikely(ptmp == NULL)) { - SCFree(ssl_state->curr_connp->trec); - } - ssl_state->curr_connp->trec = ptmp; - } - if (unlikely(ssl_state->curr_connp->trec == NULL)) { - ssl_state->curr_connp->trec_len = 0; - /* error, skip packet */ - parsed += input_len; - ssl_state->curr_connp->bytes_processed += input_len; - return -1; - } - - uint32_t write_len = 0; - if ((ssl_state->curr_connp->bytes_processed + input_len) > ssl_state->curr_connp->record_length + (SSLV3_RECORD_HDR_LEN)) { - if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < ssl_state->curr_connp->bytes_processed) { - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - write_len = (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) - ssl_state->curr_connp->bytes_processed; - } else { - write_len = input_len; - } - memcpy(ssl_state->curr_connp->trec + ssl_state->curr_connp->trec_pos, initial_input, write_len); - ssl_state->curr_connp->trec_pos += write_len; - - rc = DecodeTLSHandshakeServerCertificate(ssl_state, ssl_state->curr_connp->trec, ssl_state->curr_connp->trec_pos); - if (rc > 0) { - /* do not return normally if the packet was fragmented: - * we would return the size of the *entire* message, - * while we expect only the number of bytes parsed bytes - * from the *current* fragment - */ - if (write_len < (ssl_state->curr_connp->trec_pos - rc)) { - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - uint32_t diff = write_len - (ssl_state->curr_connp->trec_pos - rc); - ssl_state->curr_connp->bytes_processed += diff; - - ssl_state->curr_connp->trec_pos = 0; - ssl_state->curr_connp->handshake_type = 0; - ssl_state->curr_connp->hs_bytes_processed = 0; - ssl_state->curr_connp->message_length = 0; - - return diff; - } else { - ssl_state->curr_connp->bytes_processed += write_len; - parsed += write_len; - return parsed; - } - - break; - case SSLV3_HS_HELLO_REQUEST: - case SSLV3_HS_CERTIFICATE_REQUEST: - case SSLV3_HS_CERTIFICATE_VERIFY: - case SSLV3_HS_FINISHED: - case SSLV3_HS_CERTIFICATE_URL: - case SSLV3_HS_CERTIFICATE_STATUS: - break; - case SSLV3_HS_NEW_SESSION_TICKET: - SCLogDebug("new session ticket"); - break; - default: - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - - uint32_t write_len = 0; - if ((ssl_state->curr_connp->bytes_processed + input_len) >= ssl_state->curr_connp->record_length + (SSLV3_RECORD_HDR_LEN)) { - if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < ssl_state->curr_connp->bytes_processed) { - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - write_len = (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) - ssl_state->curr_connp->bytes_processed; - } else { - write_len = input_len; - } - if ((ssl_state->curr_connp->trec_pos + write_len) >= ssl_state->curr_connp->message_length) { - if (ssl_state->curr_connp->message_length < ssl_state->curr_connp->trec_pos) { - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - parsed += ssl_state->curr_connp->message_length - ssl_state->curr_connp->trec_pos; - - ssl_state->curr_connp->bytes_processed += ssl_state->curr_connp->message_length - ssl_state->curr_connp->trec_pos; - - ssl_state->curr_connp->handshake_type = 0; - ssl_state->curr_connp->hs_bytes_processed = 0; - ssl_state->curr_connp->message_length = 0; - ssl_state->curr_connp->trec_pos = 0; - - return parsed; - } else { - ssl_state->curr_connp->trec_pos += write_len; - ssl_state->curr_connp->bytes_processed += write_len; - parsed += write_len; - return parsed; - } -} - -static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, uint8_t *input, - uint32_t input_len) -{ - uint8_t *initial_input = input; - int retval; - - if (input_len == 0 || - ssl_state->curr_connp->bytes_processed == - (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) - { - return 0; - } - - switch (ssl_state->curr_connp->hs_bytes_processed) { - case 0: - ssl_state->curr_connp->handshake_type = *(input++); - ssl_state->curr_connp->bytes_processed++; - ssl_state->curr_connp->hs_bytes_processed++; - if (--input_len == 0 || - ssl_state->curr_connp->bytes_processed == - (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) - { - return (input - initial_input); - } - /* fall through */ - case 1: - ssl_state->curr_connp->message_length = *(input++) << 16; - ssl_state->curr_connp->bytes_processed++; - ssl_state->curr_connp->hs_bytes_processed++; - if (--input_len == 0 || - ssl_state->curr_connp->bytes_processed == - (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) - { - return (input - initial_input); - } - /* fall through */ - case 2: - ssl_state->curr_connp->message_length |= *(input++) << 8; - ssl_state->curr_connp->bytes_processed++; - ssl_state->curr_connp->hs_bytes_processed++; - if (--input_len == 0 || - ssl_state->curr_connp->bytes_processed == - (ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN)) - { - return (input - initial_input); - } - /* fall through */ - case 3: - ssl_state->curr_connp->message_length |= *(input++); - ssl_state->curr_connp->bytes_processed++; - ssl_state->curr_connp->hs_bytes_processed++; - --input_len; - /* fall through */ - } - - retval = SSLv3ParseHandshakeType(ssl_state, input, input_len); - if (retval < 0) { - return retval; - } - input += retval; - - return (input - initial_input); -} - -/** - * \internal - * \brief TLS Heartbeat parser (see RFC 6520) - * - * \param sslstate Pointer to the SSL state. - * \param input Pointer the received input data. - * \param input_len Length in bytes of the received data. - * \param direction 1 toclient, 0 toserver - * - * \retval The number of bytes parsed on success, 0 if nothing parsed, -1 on failure. - */ -static int SSLv3ParseHeartbeatProtocol(SSLState *ssl_state, uint8_t *input, - uint32_t input_len, uint8_t direction) -{ - uint8_t hb_type; - uint16_t payload_len; - uint16_t padding_len; - - // expect at least 3 bytes, heartbeat type (1) + length (2) - if (input_len < 3) { - return 0; - } - hb_type = *input++; - - if (!(ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC)) { - if (!(hb_type == TLS_HB_REQUEST || hb_type == TLS_HB_RESPONSE)) { - AppLayerDecoderEventsSetEvent(ssl_state->f, - TLS_DECODER_EVENT_INVALID_HEARTBEAT); - return -1; - } - } - - if ((ssl_state->flags & SSL_AL_FLAG_HB_INFLIGHT) == 0) { - ssl_state->flags |= SSL_AL_FLAG_HB_INFLIGHT; - - if (direction) { - ssl_state->flags |= SSL_AL_FLAG_HB_SERVER_INIT; - SCLogDebug("HeartBeat Record type sent in the toclient " - "direction!"); - } else { - ssl_state->flags |= SSL_AL_FLAG_HB_CLIENT_INIT; - SCLogDebug("HeartBeat Record type sent in the toserver " - "direction!"); - } - /* if we reach this poin then can we assume that the HB request - * is encrypted if so lets set the heartbeat record len */ - if (ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC) { - ssl_state->hb_record_len = ssl_state->curr_connp->record_length; - SCLogDebug("Encrypted HeartBeat Request In-flight. Storing len %u", ssl_state->hb_record_len); - return (ssl_state->curr_connp->record_length - 3); - } - - payload_len = (*input++) << 8; - payload_len |= (*input++); - - // check that the requested payload length is really present in record (CVE-2014-0160) - if ((uint32_t)(payload_len+3) > ssl_state->curr_connp->record_length) { - SCLogDebug("We have a short record in HeartBeat Request"); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_OVERFLOW_HEARTBEAT); - return -1; - } - - // check the padding length - // it must be at least 16 bytes (RFC 6520, section 4) - padding_len = ssl_state->curr_connp->record_length - payload_len - 3; - if (padding_len < 16) { - SCLogDebug("We have a short record in HeartBeat Request"); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HEARTBEAT); - return -1; - } - - if (input_len < payload_len+padding_len) { // we don't have the payload - return 0; - } - - /* OpenSSL still seems to discard multiple in-flight - * heartbeats although some tools send multiple at once */ - } else if (direction == 1 && (ssl_state->flags & SSL_AL_FLAG_HB_INFLIGHT) && - (ssl_state->flags & SSL_AL_FLAG_HB_SERVER_INIT)) { - SCLogDebug("Multiple In-Flight Server Intiated HeartBeats"); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HEARTBEAT); - return -1; - } else if (direction == 0 && (ssl_state->flags & SSL_AL_FLAG_HB_INFLIGHT) && - (ssl_state->flags & SSL_AL_FLAG_HB_CLIENT_INIT)) { - SCLogDebug("Multiple In-Flight Client Intiated HeartBeats"); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HEARTBEAT); - return -1; - } else { - /* we have a HB record in the opposite direction of the request - * lets reset our flags */ - ssl_state->flags &= ~SSL_AL_FLAG_HB_INFLIGHT; - ssl_state->flags &= ~SSL_AL_FLAG_HB_SERVER_INIT; - ssl_state->flags &= ~SSL_AL_FLAG_HB_CLIENT_INIT; - - /* if we reach this poin then can we assume that the HB request is - *encrypted if so lets set the heartbeat record len */ - if (ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC) { - /* check to see if the encrypted response is longer than the - * encrypted request */ - if (ssl_state->hb_record_len > 0 && - ssl_state->hb_record_len < ssl_state->curr_connp->record_length) - { - SCLogDebug("My Heart It's Bleeding.. OpenSSL HeartBleed Response (%u)", - ssl_state->hb_record_len); - AppLayerDecoderEventsSetEvent(ssl_state->f, - TLS_DECODER_EVENT_DATALEAK_HEARTBEAT_MISMATCH); - ssl_state->hb_record_len = 0; - return -1; - } - } - /* reset the hb record len in-case we have legit hb's followed by a bad one */ - ssl_state->hb_record_len = 0; - } - - /* skip the heartbeat, 3 bytes were already parsed, e.g |18 03 02| for TLS 1.2 */ - return (ssl_state->curr_connp->record_length - 3); -} - -static int SSLv3ParseRecord(uint8_t direction, SSLState *ssl_state, - uint8_t *input, uint32_t input_len) -{ - uint8_t *initial_input = input; - - if (input_len == 0) { - return 0; - } - - switch (ssl_state->curr_connp->bytes_processed) { - case 0: - if (input_len >= 5) { - ssl_state->curr_connp->content_type = input[0]; - ssl_state->curr_connp->version = input[1] << 8; - ssl_state->curr_connp->version |= input[2]; - ssl_state->curr_connp->record_length = input[3] << 8; - ssl_state->curr_connp->record_length |= input[4]; - ssl_state->curr_connp->bytes_processed += SSLV3_RECORD_HDR_LEN; - return SSLV3_RECORD_HDR_LEN; - } else { - ssl_state->curr_connp->content_type = *(input++); - if (--input_len == 0) - break; - } - /* fall through */ - case 1: - ssl_state->curr_connp->version = *(input++) << 8; - if (--input_len == 0) - break; - /* fall through */ - case 2: - ssl_state->curr_connp->version |= *(input++); - if (--input_len == 0) - break; - /* fall through */ - case 3: - ssl_state->curr_connp->record_length = *(input++) << 8; - if (--input_len == 0) - break; - /* fall through */ - case 4: - ssl_state->curr_connp->record_length |= *(input++); - if (--input_len == 0) - break; - /* fall through */ - } /* switch (ssl_state->curr_connp->bytes_processed) */ - - ssl_state->curr_connp->bytes_processed += (input - initial_input); - - return (input - initial_input); -} - -static int SSLv2ParseRecord(uint8_t direction, SSLState *ssl_state, - uint8_t *input, uint32_t input_len) -{ - uint8_t *initial_input = input; - - if (input_len == 0) { - return 0; - } - - if (ssl_state->curr_connp->record_lengths_length == 2) { - switch (ssl_state->curr_connp->bytes_processed) { - case 0: - if (input_len >= ssl_state->curr_connp->record_lengths_length + 1) { - ssl_state->curr_connp->record_length = (0x7f & input[0]) << 8 | input[1]; - ssl_state->curr_connp->content_type = input[2]; - ssl_state->curr_connp->version = SSL_VERSION_2; - ssl_state->curr_connp->bytes_processed += 3; - return 3; - } else { - ssl_state->curr_connp->record_length = (0x7f & *(input++)) << 8; - if (--input_len == 0) - break; - } - - /* fall through */ - case 1: - ssl_state->curr_connp->record_length |= *(input++); - if (--input_len == 0) - break; - /* fall through */ - case 2: - ssl_state->curr_connp->content_type = *(input++); - ssl_state->curr_connp->version = SSL_VERSION_2; - if (--input_len == 0) - break; - /* fall through */ - } /* switch (ssl_state->curr_connp->bytes_processed) */ - - } else { - switch (ssl_state->curr_connp->bytes_processed) { - case 0: - if (input_len >= ssl_state->curr_connp->record_lengths_length + 1) { - ssl_state->curr_connp->record_length = (0x3f & input[0]) << 8 | input[1]; - ssl_state->curr_connp->content_type = input[3]; - ssl_state->curr_connp->version = SSL_VERSION_2; - ssl_state->curr_connp->bytes_processed += 4; - return 4; - } else { - ssl_state->curr_connp->record_length = (0x3f & *(input++)) << 8; - if (--input_len == 0) - break; - } - /* fall through */ - case 1: - ssl_state->curr_connp->record_length |= *(input++); - if (--input_len == 0) - break; - - /* fall through */ - case 2: - /* padding */ - input++; - if (--input_len == 0) - break; - - /* fall through */ - case 3: - ssl_state->curr_connp->content_type = *(input++); - ssl_state->curr_connp->version = SSL_VERSION_2; - if (--input_len == 0) - break; - /* fall through */ - } /* switch (ssl_state->curr_connp->bytes_processed) */ - } - - ssl_state->curr_connp->bytes_processed += (input - initial_input); - - return (input - initial_input); -} - -static int SSLv2Decode(uint8_t direction, SSLState *ssl_state, - AppLayerParserState *pstate, uint8_t *input, - uint32_t input_len) -{ - int retval = 0; - uint8_t *initial_input = input; - - if (ssl_state->curr_connp->bytes_processed == 0) { - if (input[0] & 0x80) { - ssl_state->curr_connp->record_lengths_length = 2; - } else { - ssl_state->curr_connp->record_lengths_length = 3; - } - } - - /* the + 1 because, we also read one extra byte inside SSLv2ParseRecord - * to read the msg_type */ - if (ssl_state->curr_connp->bytes_processed < (ssl_state->curr_connp->record_lengths_length + 1)) { - retval = SSLv2ParseRecord(direction, ssl_state, input, input_len); - if (retval == -1) { - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSLV2_HEADER); - return -1; - } else { - input += retval; - input_len -= retval; - } - } - - if (input_len == 0) { - return (input - initial_input); - } - - switch (ssl_state->curr_connp->content_type) { - case SSLV2_MT_ERROR: - SCLogDebug("SSLV2_MT_ERROR msg_type received. " - "Error encountered in establishing the sslv2 " - "session, may be version"); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_ERROR_MSG_ENCOUNTERED); - - break; - - case SSLV2_MT_CLIENT_HELLO: - ssl_state->flags |= SSL_AL_FLAG_STATE_CLIENT_HELLO; - ssl_state->flags |= SSL_AL_FLAG_SSL_CLIENT_HS; - - if (ssl_state->curr_connp->record_lengths_length == 3) { - switch (ssl_state->curr_connp->bytes_processed) { - case 4: - if (input_len >= 6) { - ssl_state->curr_connp->session_id_length = input[4] << 8; - ssl_state->curr_connp->session_id_length |= input[5]; - input += 6; - input_len -= 6; - ssl_state->curr_connp->bytes_processed += 6; - if (ssl_state->curr_connp->session_id_length == 0) { - ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID; - } - break; - } else { - input++; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - } - /* fall through */ - case 5: - input++; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - /* fall through */ - case 6: - input++; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - /* fall through */ - case 7: - input++; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - /* fall through */ - case 8: - ssl_state->curr_connp->session_id_length = *(input++) << 8; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - /* fall through */ - case 9: - ssl_state->curr_connp->session_id_length |= *(input++); - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - /* fall through */ - } /* switch (ssl_state->curr_connp->bytes_processed) */ - - /* ssl_state->curr_connp->record_lengths_length is 3 */ - } else { - switch (ssl_state->curr_connp->bytes_processed) { - case 3: - if (input_len >= 6) { - ssl_state->curr_connp->session_id_length = input[4] << 8; - ssl_state->curr_connp->session_id_length |= input[5]; - input += 6; - input_len -= 6; - ssl_state->curr_connp->bytes_processed += 6; - if (ssl_state->curr_connp->session_id_length == 0) { - ssl_state->flags |= SSL_AL_FLAG_SSL_NO_SESSION_ID; - } - break; - } else { - input++; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - } - case 4: - input++; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - case 5: - input++; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - case 6: - input++; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - case 7: - ssl_state->curr_connp->session_id_length = *(input++) << 8; - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - case 8: - ssl_state->curr_connp->session_id_length |= *(input++); - ssl_state->curr_connp->bytes_processed++; - if (--input_len == 0) - break; - } /* switch (ssl_state->curr_connp->bytes_processed) */ - } /* else - if (ssl_state->curr_connp->record_lengths_length == 3) */ - - break; - - case SSLV2_MT_CLIENT_MASTER_KEY: - if ( !(ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_HS)) { - SCLogDebug("Client hello is not seen before master key " - "message!!"); - } - ssl_state->flags |= SSL_AL_FLAG_SSL_CLIENT_MASTER_KEY; - - break; - - case SSLV2_MT_CLIENT_CERTIFICATE: - if (direction == 1) { - SCLogDebug("Incorrect SSL Record type sent in the toclient " - "direction!"); - } else { - ssl_state->flags |= SSL_AL_FLAG_STATE_CLIENT_KEYX; - } - /* fall through */ - case SSLV2_MT_SERVER_VERIFY: - case SSLV2_MT_SERVER_FINISHED: - if (direction == 0 && - !(ssl_state->curr_connp->content_type & SSLV2_MT_CLIENT_CERTIFICATE)) { - SCLogDebug("Incorrect SSL Record type sent in the toserver " - "direction!"); - } - /* fall through */ - case SSLV2_MT_CLIENT_FINISHED: - case SSLV2_MT_REQUEST_CERTIFICATE: - /* both ways hello seen */ - if ((ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_HS) && - (ssl_state->flags & SSL_AL_FLAG_SSL_SERVER_HS)) { - - if (direction == 0) { - if (ssl_state->flags & SSL_AL_FLAG_SSL_NO_SESSION_ID) { - ssl_state->flags |= SSL_AL_FLAG_SSL_CLIENT_SSN_ENCRYPTED; - SCLogDebug("SSLv2 client side has started the encryption"); - } else if (ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_MASTER_KEY) { - ssl_state->flags |= SSL_AL_FLAG_SSL_CLIENT_SSN_ENCRYPTED; - SCLogDebug("SSLv2 client side has started the encryption"); - } - } else { - ssl_state->flags |= SSL_AL_FLAG_SSL_SERVER_SSN_ENCRYPTED; - SCLogDebug("SSLv2 Server side has started the encryption"); - } - - if ((ssl_state->flags & SSL_AL_FLAG_SSL_CLIENT_SSN_ENCRYPTED) && - (ssl_state->flags & SSL_AL_FLAG_SSL_SERVER_SSN_ENCRYPTED)) { - AppLayerParserStateSetFlag(pstate, - APP_LAYER_PARSER_NO_INSPECTION); - if (ssl_config.no_reassemble == 1) - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY); - SCLogDebug("SSLv2 No reassembly & inspection has been set"); - } - } - - break; - - case SSLV2_MT_SERVER_HELLO: - ssl_state->flags |= SSL_AL_FLAG_STATE_SERVER_HELLO; - ssl_state->flags |= SSL_AL_FLAG_SSL_SERVER_HS; - - break; - } - - if (input_len + ssl_state->curr_connp->bytes_processed >= - (ssl_state->curr_connp->record_length + ssl_state->curr_connp->record_lengths_length)) { - /* looks like we have another record after this*/ - uint32_t diff = ssl_state->curr_connp->record_length + - ssl_state->curr_connp->record_lengths_length + - ssl_state->curr_connp->bytes_processed; - input += diff; - SSLParserReset(ssl_state); - return (input - initial_input); - - /* we still don't have the entire record for the one we are - * currently parsing */ - } else { - input += input_len; - ssl_state->curr_connp->bytes_processed += input_len; - return (input - initial_input); - } -} - -static int SSLv3Decode(uint8_t direction, SSLState *ssl_state, - AppLayerParserState *pstate, uint8_t *input, - uint32_t input_len) -{ - int retval = 0; - uint32_t parsed = 0; - - if (ssl_state->curr_connp->bytes_processed < SSLV3_RECORD_HDR_LEN) { - retval = SSLv3ParseRecord(direction, ssl_state, input, input_len); - if (retval < 0) { - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_TLS_HEADER); - return -1; - } else { - parsed += retval; - input_len -= retval; - } - } - - if (input_len == 0) { - return parsed; - } - - /* check record version */ - if (ssl_state->curr_connp->version < SSL_VERSION_3 || - ssl_state->curr_connp->version > TLS_VERSION_12) { - - AppLayerDecoderEventsSetEvent(ssl_state->f, - TLS_DECODER_EVENT_INVALID_RECORD_VERSION); - return -1; - } - - switch (ssl_state->curr_connp->content_type) { - - /* we don't need any data from these types */ - case SSLV3_CHANGE_CIPHER_SPEC: - ssl_state->flags |= SSL_AL_FLAG_CHANGE_CIPHER_SPEC; - - if (direction) - ssl_state->flags |= SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC; - else - ssl_state->flags |= SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC; - - break; - - case SSLV3_ALERT_PROTOCOL: - break; - case SSLV3_APPLICATION_PROTOCOL: - if ((ssl_state->flags & SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC) && - (ssl_state->flags & SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC)) { - /* - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_INSPECTION); - if (ssl_config.no_reassemble == 1) - AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_NO_REASSEMBLY); - */ - AppLayerParserStateSetFlag(pstate,APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD); - } - - break; - - case SSLV3_HANDSHAKE_PROTOCOL: - if (ssl_state->flags & SSL_AL_FLAG_CHANGE_CIPHER_SPEC) - break; - - if (ssl_state->curr_connp->record_length < 4) { - SSLParserReset(ssl_state); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - - retval = SSLv3ParseHandshakeProtocol(ssl_state, input + parsed, input_len); - if (retval < 0) { - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } else { - if ((uint32_t)retval > input_len) { - SCLogDebug("Error parsing SSLv3.x. Reseting parser " - "state. Let's get outta here"); - SSLParserReset(ssl_state); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - parsed += retval; - input_len -= retval; - if (ssl_state->curr_connp->bytes_processed == ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) { - SSLParserReset(ssl_state); - } - - SCLogDebug("trigger RAW! (post HS)"); - AppLayerParserTriggerRawStreamReassembly(ssl_state->f); - return parsed; - } - - break; - case SSLV3_HEARTBEAT_PROTOCOL: - retval = SSLv3ParseHeartbeatProtocol(ssl_state, input + parsed, input_len, direction); - if (retval < 0) - return -1; - break; - - default: - /* \todo fix the event from invalid rule to unknown rule */ - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_RECORD_TYPE); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - - if (input_len + ssl_state->curr_connp->bytes_processed >= ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) { - if ((ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN) < ssl_state->curr_connp->bytes_processed) { - /* defensive checks. Something's wrong. */ - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - - SCLogDebug("record complete, trigger RAW"); - AppLayerParserTriggerRawStreamReassembly(ssl_state->f); - - /* looks like we have another record */ - uint32_t diff = ssl_state->curr_connp->record_length + SSLV3_RECORD_HDR_LEN - ssl_state->curr_connp->bytes_processed; - parsed += diff; - SSLParserReset(ssl_state); - return parsed; - - /* we still don't have the entire record for the one we are - * currently parsing */ - } else { - parsed += input_len; - ssl_state->curr_connp->bytes_processed += input_len; - return parsed; - } - -} - -/** - * \internal - * \brief SSLv2, SSLv23, SSLv3, TLSv1.1, TLSv1.2, TLSv1.3 parser. - * - * On parsing error, this should be the only function that should reset - * the parser state, to avoid multiple functions in the chain reseting - * the parser state. - * - * \param direction 0 for toserver, 1 for toclient. - * \param alstate Pointer to the state. - * \param pstate Application layer parser state for this session. - * \param input Pointer the received input data. - * \param input_len Length in bytes of the received data. - * \param output Pointer to the list of parsed output elements. - * - * \todo On reaching an inconsistent state, check if the input has - * another new record, instead of just returning after the reset - * - * \retval >=0 On success. - */ -static int SSLDecode(Flow *f, uint8_t direction, void *alstate, AppLayerParserState *pstate, - uint8_t *input, uint32_t ilen) -{ - SSLState *ssl_state = (SSLState *)alstate; - int retval = 0; - uint8_t counter = 0; - - int32_t input_len = (int32_t)ilen; - - ssl_state->f = f; - - if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCReturnInt(1); - } else if (input == NULL || input_len == 0) { - SCReturnInt(-1); - } - - if (direction == 0) - ssl_state->curr_connp = &ssl_state->client_connp; - else - ssl_state->curr_connp = &ssl_state->server_connp; - - /* if we have more than one record */ - while (input_len > 0) { - if (counter++ == 30) { - SCLogDebug("Looks like we have looped quite a bit. Reset state " - "and get out of here"); - SSLParserReset(ssl_state); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } - - /* ssl_state->bytes_processed is 0 for a - * fresh record or positive to indicate a record currently being - * parsed */ - switch (ssl_state->curr_connp->bytes_processed) { - /* fresh record */ - case 0: - /* only SSLv2, has one of the top 2 bits set */ - if ((input[0] & 0x80) || (input[0] & 0x40)) { - SCLogDebug("SSLv2 detected"); - ssl_state->curr_connp->version = SSL_VERSION_2; - retval = SSLv2Decode(direction, ssl_state, pstate, input, - input_len); - if (retval < 0) { - SCLogDebug("Error parsing SSLv2.x. Reseting parser " - "state. Let's get outta here"); - SSLParserReset(ssl_state); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } else { - input_len -= retval; - input += retval; - } - } else { - SCLogDebug("SSLv3.x detected"); - /* we will keep it this way till our record parser tells - * us what exact version it is */ - ssl_state->curr_connp->version = TLS_VERSION_UNKNOWN; - retval = SSLv3Decode(direction, ssl_state, pstate, input, - input_len); - if (retval < 0) { - SCLogDebug("Error parsing SSLv3.x. Reseting parser " - "state. Let's get outta here"); - SSLParserReset(ssl_state); - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_SSL_RECORD); - return -1; - } else { - input_len -= retval; - input += retval; - if (ssl_state->curr_connp->bytes_processed == SSLV3_RECORD_HDR_LEN - && ssl_state->curr_connp->record_length == 0) { - /* empty record */ - SSLParserReset(ssl_state); - } - } - } - - break; - - default: - /* we would have established by now if we are dealing with - * SSLv2 or above */ - if (ssl_state->curr_connp->version == SSL_VERSION_2) { - SCLogDebug("Continuing parsing SSLv2 record from where we " - "previously left off"); - retval = SSLv2Decode(direction, ssl_state, pstate, input, - input_len); - if (retval == -1) { - SCLogDebug("Error parsing SSLv2.x. Reseting parser " - "state. Let's get outta here"); - SSLParserReset(ssl_state); - return 0; - } else { - input_len -= retval; - input += retval; - } - } else { - SCLogDebug("Continuing parsing SSLv3.x record from where we " - "previously left off"); - retval = SSLv3Decode(direction, ssl_state, pstate, input, - input_len); - if (retval < 0) { - SCLogDebug("Error parsing SSLv3.x. Reseting parser " - "state. Let's get outta here"); - SSLParserReset(ssl_state); - return 0; - } else { - if (retval > input_len) { - SCLogDebug("Error parsing SSLv3.x. Reseting parser " - "state. Let's get outta here"); - SSLParserReset(ssl_state); - } - input_len -= retval; - input += retval; - if (ssl_state->curr_connp->bytes_processed == SSLV3_RECORD_HDR_LEN - && ssl_state->curr_connp->record_length == 0) { - /* empty record */ - SSLParserReset(ssl_state); - } - } - } - - break; - } /* switch (ssl_state->curr_connp->bytes_processed) */ - } /* while (input_len) */ - - return 1; -} - -int SSLParseClientRecord(Flow *f, void *alstate, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - return SSLDecode(f, 0 /* toserver */, alstate, pstate, input, input_len); -} - -int SSLParseServerRecord(Flow *f, void *alstate, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, - void *local_data) -{ - return SSLDecode(f, 1 /* toclient */, alstate, pstate, input, input_len); -} - -/** - * \internal - * \brief Function to allocate the SSL state memory. - */ -void *SSLStateAlloc(void) -{ - SSLState *ssl_state = SCMalloc(sizeof(SSLState)); - if (unlikely(ssl_state == NULL)) - return NULL; - memset(ssl_state, 0, sizeof(SSLState)); - ssl_state->client_connp.cert_log_flag = 0; - ssl_state->server_connp.cert_log_flag = 0; - TAILQ_INIT(&ssl_state->server_connp.certs); - - return (void *)ssl_state; -} - -/** - * \internal - * \brief Function to free the SSL state memory. - */ -void SSLStateFree(void *p) -{ - SSLState *ssl_state = (SSLState *)p; - SSLCertsChain *item; - - if (ssl_state->client_connp.trec) - SCFree(ssl_state->client_connp.trec); - if (ssl_state->client_connp.cert0_subject) - SCFree(ssl_state->client_connp.cert0_subject); - if (ssl_state->client_connp.cert0_issuerdn) - SCFree(ssl_state->client_connp.cert0_issuerdn); - if (ssl_state->client_connp.cert0_fingerprint) - SCFree(ssl_state->client_connp.cert0_fingerprint); - if (ssl_state->client_connp.sni) - SCFree(ssl_state->client_connp.sni); - - if (ssl_state->server_connp.trec) - SCFree(ssl_state->server_connp.trec); - if (ssl_state->server_connp.cert0_subject) - SCFree(ssl_state->server_connp.cert0_subject); - if (ssl_state->server_connp.cert0_issuerdn) - SCFree(ssl_state->server_connp.cert0_issuerdn); - if (ssl_state->server_connp.cert0_fingerprint) - SCFree(ssl_state->server_connp.cert0_fingerprint); - if (ssl_state->server_connp.sni) - SCFree(ssl_state->server_connp.sni); - - /* Free certificate chain */ - while ((item = TAILQ_FIRST(&ssl_state->server_connp.certs))) { - TAILQ_REMOVE(&ssl_state->server_connp.certs, item, next); - SCFree(item); - } - TAILQ_INIT(&ssl_state->server_connp.certs); - - SCFree(ssl_state); - - return; -} - -static uint16_t SSLProbingParser(uint8_t *input, uint32_t ilen, uint32_t *offset) -{ - /* probably a rst/fin sending an eof */ - if (ilen == 0) - return ALPROTO_UNKNOWN; - - /* for now just the 3 byte header ones */ - /* \todo Detect the 2 byte ones */ - if ((input[0] & 0x80) && (input[2] == 0x01)) { - return ALPROTO_TLS; - } - - return ALPROTO_FAILED; -} - -int SSLStateGetEventInfo(const char *event_name, - int *event_id, AppLayerEventType *event_type) -{ - *event_id = SCMapEnumNameToValue(event_name, tls_decoder_event_table); - if (*event_id == -1) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " - "ssl's enum map table.", event_name); - /* yes this is fatal */ - return -1; - } - - *event_type = APP_LAYER_EVENT_TYPE_GENERAL; - - return 0; -} - -static int SSLRegisterPatternsForProtocolDetection(void) -{ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|01 00 02|", 5, 2, STREAM_TOSERVER) < 0) - { - return -1; - } - - /** SSLv3 */ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|01 03 00|", 3, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|16 03 00|", 3, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - - /** TLSv1 */ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|01 03 01|", 3, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|16 03 01|", 3, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - - /** TLSv1.1 */ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|01 03 02|", 3, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|16 03 02|", 3, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - - /** TLSv1.2 */ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|01 03 03|", 3, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|16 03 03|", 3, 0, STREAM_TOSERVER) < 0) - { - return -1; - } - - /***** toclient direction *****/ - - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|15 03 00|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|16 03 00|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|17 03 00|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - - /** TLSv1 */ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|15 03 01|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|16 03 01|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|17 03 01|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - - /** TLSv1.1 */ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|15 03 02|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|16 03 02|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|17 03 02|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - - /** TLSv1.2 */ - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|15 03 03|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|16 03 03|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|17 03 03|", 3, 0, STREAM_TOCLIENT) < 0) - { - return -1; - } - - /* Subsection - SSLv2 style record by client, but informing the server - * the max version it supports. - * Updated by Anoop Saldanha. Disabled it for now. We'll get back to - * it after some tests */ -#if 0 - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|01 03 00|", 5, 2, STREAM_TOSERVER) < 0) - { - return -1; - } - if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_TLS, - "|00 02|", 7, 5, STREAM_TOCLIENT) < 0) - { - return -1; - } -#endif - - return 0; -} - -/** - * \brief Function to register the SSL protocol parser and other functions - */ -void RegisterSSLParsers(void) -{ - char *proto_name = "tls"; - - /** SSLv2 and SSLv23*/ - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - AppLayerProtoDetectRegisterProtocol(ALPROTO_TLS, proto_name); - - if (SSLRegisterPatternsForProtocolDetection() < 0) - return; - - if (RunmodeIsUnittests()) { - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - "443", - ALPROTO_TLS, - 0, 3, - STREAM_TOSERVER, - SSLProbingParser); - } else { - AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP, - proto_name, ALPROTO_TLS, - 0, 3, - SSLProbingParser); - } - } else { - SCLogInfo("Protocol detection and parser disabled for %s protocol", - proto_name); - return; - } - - if (AppLayerParserConfParserEnabled("tcp", proto_name)) { - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TLS, STREAM_TOSERVER, - SSLParseClientRecord); - - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TLS, STREAM_TOCLIENT, - SSLParseServerRecord); - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_TLS, SSLStateGetEventInfo); - - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_TLS, SSLStateAlloc, SSLStateFree); - AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_TLS, STREAM_TOSERVER); - - /* Get the value of no reassembly option from the config file */ - if (ConfGetNode("app-layer.protocols.tls.no-reassemble") == NULL) { - if (ConfGetBool("tls.no-reassemble", &ssl_config.no_reassemble) != 1) - ssl_config.no_reassemble = 1; - } else { - if (ConfGetBool("app-layer.protocols.tls.no-reassemble", &ssl_config.no_reassemble) != 1) - ssl_config.no_reassemble = 1; - } - } else { - SCLogInfo("Parsed disabled for %s protocol. Protocol detection" - "still on.", proto_name); - } - -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_TLS, SSLParserRegisterTests); -#endif - - /* Get the value of no reassembly option from the config file */ - if (ConfGetBool("tls.no-reassemble", &ssl_config.no_reassemble) != 1) - ssl_config.no_reassemble = 1; - - return; -} - -/***************************************Unittests******************************/ - -#ifdef UNITTESTS - -/** - *\test Send a get request in one chunk. - */ -static int SSLParserTest01(void) -{ - int result = 1; - Flow f; - uint8_t tlsbuf[] = { 0x16, 0x03, 0x01 }; - uint32_t tlslen = sizeof(tlsbuf); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER | STREAM_EOF, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.version); - result = 0; - goto end; - } -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a get request in two chunks. */ -static int SSLParserTest02(void) -{ - int result = 1; - Flow f; - uint8_t tlsbuf1[] = { 0x16 }; - uint32_t tlslen1 = sizeof(tlsbuf1); - uint8_t tlsbuf2[] = { 0x03, 0x01 }; - uint32_t tlslen2 = sizeof(tlsbuf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.version); - result = 0; - goto end; - } -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a get request in three chunks. */ -static int SSLParserTest03(void) -{ - int result = 1; - Flow f; - uint8_t tlsbuf1[] = { 0x16 }; - uint32_t tlslen1 = sizeof(tlsbuf1); - uint8_t tlsbuf2[] = { 0x03 }; - uint32_t tlslen2 = sizeof(tlsbuf2); - uint8_t tlsbuf3[] = { 0x01 }; - uint32_t tlslen3 = sizeof(tlsbuf3); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.version); - result = 0; - goto end; - } -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test Send a get request in three chunks + more data. */ -static int SSLParserTest04(void) -{ - int result = 1; - Flow f; - uint8_t tlsbuf1[] = { 0x16 }; - uint32_t tlslen1 = sizeof(tlsbuf1); - uint8_t tlsbuf2[] = { 0x03 }; - uint32_t tlslen2 = sizeof(tlsbuf2); - uint8_t tlsbuf3[] = { 0x01 }; - uint32_t tlslen3 = sizeof(tlsbuf3); - uint8_t tlsbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x01 }; - uint32_t tlslen4 = sizeof(tlsbuf4); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.version); - result = 0; - goto end; - } -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -#if 0 -/** \test Test the setting up of no reassembly and no payload inspection flag - * after detection of the TLS handshake completion */ -static int SSLParserTest05(void) -{ - int result = 1; - Flow f; - uint8_t tlsbuf[] = { 0x16, 0x03, 0x01, 0x00, 0x01 }; - uint32_t tlslen = sizeof(tlsbuf); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - tlsbuf[0] = 0x14; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - tlsbuf[0] = 0x14; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - tlsbuf[0] = 0x17; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x17) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.client_version); - result = 0; - goto end; - } - - AppLayerParserStateStore *parser_state_store = (AppLayerParserStateStore *) - ssn.alparser; - AppLayerParserState *parser_state = &parser_state_store->to_server; - - if (!(parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) && - !(ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) && - !(ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) - { - printf("The flags should be set\n"); - result = 0; - goto end; - } - - if (!(f.flags & FLOW_NOPAYLOAD_INSPECTION)) { - printf("The flags should be set\n"); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} -#endif - -#if 0 -/** \test Test the setting up of no reassembly and no payload inspection flag - * after detection of the valid TLS handshake completion, the rouge - * 0x17 packet will not be considered in the detection process */ -static int SSLParserTest06(void) -{ - int result = 1; - Flow f; - uint8_t tlsbuf[] = { 0x16, 0x03, 0x01, 0x00, 0x01 }; - uint32_t tlslen = sizeof(tlsbuf); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - tlsbuf[0] = 0x14; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - tlsbuf[0] = 0x17; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x17) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_connp._content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.version); - result = 0; - goto end; - } - - AppLayerParserStateStore *parser_state_store = (AppLayerParserStateStore *) - ssn.alparser; - AppLayerParserState *parser_state = &parser_state_store->to_server; - - if ((parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) || - (ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) || - (ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - printf("The flags should not be set\n"); - result = 0; - goto end; - } - - tlsbuf[0] = 0x14; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - tlsbuf[0] = 0x17; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - if (!(parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) && - !(ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) && - !(ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - printf("The flags should be set\n"); - result = 0; - goto end; - } - - if (!(f.flags & FLOW_NOPAYLOAD_INSPECTION)) { - printf("The flags should be set\n"); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} -#endif - -/** \test multimsg test */ -static int SSLParserMultimsgTest01(void) -{ - int result = 1; - Flow f; - /* 3 msgs */ - uint8_t tlsbuf1[] = { - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0xd3, 0x6f, 0x1f, 0x63, 0x82, - 0x8d, 0x75, 0x77, 0x8c, 0x91, 0xbc, 0xa1, 0x3d, - 0xbb, 0xe1, 0xb5, 0xd3, 0x31, 0x92, 0x59, 0x2b, - 0x2c, 0x43, 0x96, 0xa3, 0xaa, 0x23, 0x92, 0xd0, - 0x91, 0x2a, 0x5e, 0x10, 0x5b, 0xc8, 0xc1, 0xe2, - 0xd3, 0x5c, 0x8b, 0x8c, 0x91, 0x9e, 0xc2, 0xf2, - 0x9c, 0x3c, 0x4f, 0x37, 0x1e, 0x20, 0x5e, 0x33, - 0xd5, 0xf0, 0xd6, 0xaf, 0x89, 0xf5, 0xcc, 0xb2, - 0xcf, 0xc1, 0x60, 0x3a, 0x46, 0xd5, 0x4e, 0x2a, - 0xb6, 0x6a, 0xb9, 0xfc, 0x32, 0x8b, 0xe0, 0x6e, - 0xa0, 0xed, 0x25, 0xa0, 0xa4, 0x82, 0x81, 0x73, - 0x90, 0xbf, 0xb5, 0xde, 0xeb, 0x51, 0x8d, 0xde, - 0x5b, 0x6f, 0x94, 0xee, 0xba, 0xe5, 0x69, 0xfa, - 0x1a, 0x80, 0x30, 0x54, 0xeb, 0x12, 0x01, 0xb9, - 0xfe, 0xbf, 0x82, 0x95, 0x01, 0x7b, 0xb0, 0x97, - 0x14, 0xc2, 0x06, 0x3c, 0x69, 0xfb, 0x1c, 0x66, - 0x47, 0x17, 0xd9, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0xf6, 0xbc, - 0x0d, 0x6f, 0xe8, 0xbb, 0xaa, 0xbf, 0x14, 0xeb, - 0x7b, 0xcc, 0x6c, 0x28, 0xb0, 0xfc, 0xa6, 0x01, - 0x2a, 0x97, 0x96, 0x17, 0x5e, 0xe8, 0xb4, 0x4e, - 0x78, 0xc9, 0x04, 0x65, 0x53, 0xb6, 0x93, 0x3d, - 0xeb, 0x44, 0xee, 0x86, 0xf9, 0x80, 0x49, 0x45, - 0x21, 0x34, 0xd1, 0xee, 0xc8, 0x9c - }; - uint32_t tlslen1 = sizeof(tlsbuf1); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.version); - result = 0; - goto end; - } -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** \test multimsg test server */ -static int SSLParserMultimsgTest02(void) -{ - int result = 1; - Flow f; - /* 3 msgs */ - uint8_t tlsbuf1[] = { - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0xd3, 0x6f, 0x1f, 0x63, 0x82, - 0x8d, 0x75, 0x77, 0x8c, 0x91, 0xbc, 0xa1, 0x3d, - 0xbb, 0xe1, 0xb5, 0xd3, 0x31, 0x92, 0x59, 0x2b, - 0x2c, 0x43, 0x96, 0xa3, 0xaa, 0x23, 0x92, 0xd0, - 0x91, 0x2a, 0x5e, 0x10, 0x5b, 0xc8, 0xc1, 0xe2, - 0xd3, 0x5c, 0x8b, 0x8c, 0x91, 0x9e, 0xc2, 0xf2, - 0x9c, 0x3c, 0x4f, 0x37, 0x1e, 0x20, 0x5e, 0x33, - 0xd5, 0xf0, 0xd6, 0xaf, 0x89, 0xf5, 0xcc, 0xb2, - 0xcf, 0xc1, 0x60, 0x3a, 0x46, 0xd5, 0x4e, 0x2a, - 0xb6, 0x6a, 0xb9, 0xfc, 0x32, 0x8b, 0xe0, 0x6e, - 0xa0, 0xed, 0x25, 0xa0, 0xa4, 0x82, 0x81, 0x73, - 0x90, 0xbf, 0xb5, 0xde, 0xeb, 0x51, 0x8d, 0xde, - 0x5b, 0x6f, 0x94, 0xee, 0xba, 0xe5, 0x69, 0xfa, - 0x1a, 0x80, 0x30, 0x54, 0xeb, 0x12, 0x01, 0xb9, - 0xfe, 0xbf, 0x82, 0x95, 0x01, 0x7b, 0xb0, 0x97, - 0x14, 0xc2, 0x06, 0x3c, 0x69, 0xfb, 0x1c, 0x66, - 0x47, 0x17, 0xd9, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0xf6, 0xbc, - 0x0d, 0x6f, 0xe8, 0xbb, 0xaa, 0xbf, 0x14, 0xeb, - 0x7b, 0xcc, 0x6c, 0x28, 0xb0, 0xfc, 0xa6, 0x01, - 0x2a, 0x97, 0x96, 0x17, 0x5e, 0xe8, 0xb4, 0x4e, - 0x78, 0xc9, 0x04, 0x65, 0x53, 0xb6, 0x93, 0x3d, - 0xeb, 0x44, 0xee, 0x86, 0xf9, 0x80, 0x49, 0x45, - 0x21, 0x34, 0xd1, 0xee, 0xc8, 0x9c - }; - uint32_t tlslen1 = sizeof(tlsbuf1); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, tlsbuf1, tlslen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->server_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->server_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->server_connp.version != 0x0301) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", 0x0301, - ssl_state->server_connp.version); - result = 0; - goto end; - } -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Test the detection of SSLv3 protocol from the given packet - */ -static int SSLParserTest07(void) -{ - int result = 1; - Flow f; - uint8_t tlsbuf[] = { 0x16, 0x03, 0x00, 0x00, 0x6f, 0x01, - 0x00, 0x00, 0x6b, 0x03, 0x00, 0x4b, 0x2f, 0xdc, - 0x4e, 0xe6, 0x95, 0xf1, 0xa0, 0xc7, 0xcf, 0x8e, - 0xf6, 0xeb, 0x22, 0x6d, 0xce, 0x9c, 0x44, 0xfb, - 0xc8, 0xa0, 0x44, 0x31, 0x15, 0x4c, 0xe9, 0x97, - 0xa7, 0xa1, 0xfe, 0xea, 0xcc, 0x20, 0x4b, 0x5d, - 0xfb, 0xa5, 0x63, 0x7a, 0x73, 0x95, 0xf7, 0xff, - 0x42, 0xac, 0x8f, 0x46, 0xed, 0xe4, 0xb1, 0x35, - 0x35, 0x78, 0x1a, 0x9d, 0xaf, 0x10, 0xc5, 0x52, - 0xf3, 0x7b, 0xfb, 0xb5, 0xe9, 0xa8, 0x00, 0x24, - 0x00, 0x88, 0x00, 0x87, 0x00, 0x39, 0x00, 0x38, - 0x00, 0x84, 0x00, 0x35, 0x00, 0x45, 0x00, 0x44, - 0x00, 0x33, 0x00, 0x32, 0x00, 0x96, 0x00, 0x41, - 0x00, 0x2f, 0x00, 0x16, 0x00, 0x13, 0xfe, 0xff, - 0x00, 0x0a, 0x00, 0x02, 0x01, 0x00 }; - uint32_t tlslen = sizeof(tlsbuf); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_connp.version); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -#if 0 -/** \test Test the setting up of no reassembly and no payload inspection flag - * after detection of the SSLv3 handshake completion */ -static int SSLParserTest08(void) -{ - int result = 1; - Flow f; - uint8_t tlsbuf[] = { 0x16, 0x03, 0x00, 0x00, 0x01 }; - uint32_t tlslen = sizeof(tlsbuf); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - tlsbuf[0] = 0x14; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - tlsbuf[0] = 0x14; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - tlsbuf[0] = 0x17; - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf, tlslen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x17) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_connp.version); - result = 0; - goto end; - } - - AppLayerParserStateStore *parser_state_store = (AppLayerParserStateStore *) - ssn.alparser; - AppLayerParserState *parser_state = &parser_state_store->to_server; - - if (!(parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) && - !(ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) && - !(ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - printf("The flags should be set\n"); - result = 0; - goto end; - } - - if (!(f.flags & FLOW_NOPAYLOAD_INSPECTION)) { - printf("The flags should be set\n"); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -#endif - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest09(void) -{ - int result = 1; - Flow f; - uint8_t buf1[] = { - 0x16, - }; - uint32_t buf1_len = sizeof(buf1); - - uint8_t buf2[] = { - 0x03, 0x00, 0x00, 0x6f, 0x01, - 0x00, 0x00, 0x6b, 0x03, 0x00, 0x4b, 0x2f, 0xdc, - 0x4e, 0xe6, 0x95, 0xf1, 0xa0, 0xc7, 0xcf, 0x8e, - 0xf6, 0xeb, 0x22, 0x6d, 0xce, 0x9c, 0x44, 0xfb, - 0xc8, 0xa0, 0x44, 0x31, 0x15, 0x4c, 0xe9, 0x97, - 0xa7, 0xa1, 0xfe, 0xea, 0xcc, 0x20, 0x4b, 0x5d, - 0xfb, 0xa5, 0x63, 0x7a, 0x73, 0x95, 0xf7, 0xff, - 0x42, 0xac, 0x8f, 0x46, 0xed, 0xe4, 0xb1, 0x35, - 0x35, 0x78, 0x1a, 0x9d, 0xaf, 0x10, 0xc5, 0x52, - 0xf3, 0x7b, 0xfb, 0xb5, 0xe9, 0xa8, 0x00, 0x24, - 0x00, 0x88, 0x00, 0x87, 0x00, 0x39, 0x00, 0x38, - 0x00, 0x84, 0x00, 0x35, 0x00, 0x45, 0x00, 0x44, - 0x00, 0x33, 0x00, 0x32, 0x00, 0x96, 0x00, 0x41, - 0x00, 0x2f, 0x00, 0x16, 0x00, 0x13, 0xfe, 0xff, - 0x00, 0x0a, 0x00, 0x02, 0x01, 0x00 - }; - uint32_t buf2_len = sizeof(buf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf2, buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_connp.version); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest10(void) -{ - int result = 1; - Flow f; - uint8_t buf1[] = { - 0x16, 0x03, - }; - uint32_t buf1_len = sizeof(buf1); - - uint8_t buf2[] = { - 0x00, 0x00, 0x6f, 0x01, - 0x00, 0x00, 0x6b, 0x03, 0x00, 0x4b, 0x2f, 0xdc, - 0x4e, 0xe6, 0x95, 0xf1, 0xa0, 0xc7, 0xcf, 0x8e, - 0xf6, 0xeb, 0x22, 0x6d, 0xce, 0x9c, 0x44, 0xfb, - 0xc8, 0xa0, 0x44, 0x31, 0x15, 0x4c, 0xe9, 0x97, - 0xa7, 0xa1, 0xfe, 0xea, 0xcc, 0x20, 0x4b, 0x5d, - 0xfb, 0xa5, 0x63, 0x7a, 0x73, 0x95, 0xf7, 0xff, - 0x42, 0xac, 0x8f, 0x46, 0xed, 0xe4, 0xb1, 0x35, - 0x35, 0x78, 0x1a, 0x9d, 0xaf, 0x10, 0xc5, 0x52, - 0xf3, 0x7b, 0xfb, 0xb5, 0xe9, 0xa8, 0x00, 0x24, - 0x00, 0x88, 0x00, 0x87, 0x00, 0x39, 0x00, 0x38, - 0x00, 0x84, 0x00, 0x35, 0x00, 0x45, 0x00, 0x44, - 0x00, 0x33, 0x00, 0x32, 0x00, 0x96, 0x00, 0x41, - 0x00, 0x2f, 0x00, 0x16, 0x00, 0x13, 0xfe, 0xff, - 0x00, 0x0a, 0x00, 0x02, 0x01, 0x00 - }; - uint32_t buf2_len = sizeof(buf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf2, buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_connp.version); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest11(void) -{ - int result = 1; - Flow f; - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x6f, 0x01, - }; - uint32_t buf1_len = sizeof(buf1); - - uint8_t buf2[] = { - 0x00, 0x00, 0x6b, 0x03, 0x00, 0x4b, 0x2f, 0xdc, - 0x4e, 0xe6, 0x95, 0xf1, 0xa0, 0xc7, 0xcf, 0x8e, - 0xf6, 0xeb, 0x22, 0x6d, 0xce, 0x9c, 0x44, 0xfb, - 0xc8, 0xa0, 0x44, 0x31, 0x15, 0x4c, 0xe9, 0x97, - 0xa7, 0xa1, 0xfe, 0xea, 0xcc, 0x20, 0x4b, 0x5d, - 0xfb, 0xa5, 0x63, 0x7a, 0x73, 0x95, 0xf7, 0xff, - 0x42, 0xac, 0x8f, 0x46, 0xed, 0xe4, 0xb1, 0x35, - 0x35, 0x78, 0x1a, 0x9d, 0xaf, 0x10, 0xc5, 0x52, - 0xf3, 0x7b, 0xfb, 0xb5, 0xe9, 0xa8, 0x00, 0x24, - 0x00, 0x88, 0x00, 0x87, 0x00, 0x39, 0x00, 0x38, - 0x00, 0x84, 0x00, 0x35, 0x00, 0x45, 0x00, 0x44, - 0x00, 0x33, 0x00, 0x32, 0x00, 0x96, 0x00, 0x41, - 0x00, 0x2f, 0x00, 0x16, 0x00, 0x13, 0xfe, 0xff, - 0x00, 0x0a, 0x00, 0x02, 0x01, 0x00 - }; - uint32_t buf2_len = sizeof(buf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf2, buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_connp.version); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest12(void) -{ - int result = 1; - Flow f; - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x6f, 0x01, - }; - uint32_t buf1_len = sizeof(buf1); - - uint8_t buf2[] = { - 0x00, 0x00, 0x6b, - }; - uint32_t buf2_len = sizeof(buf2); - - uint8_t buf3[] = { - 0x03, 0x00, 0x4b, 0x2f, 0xdc, - 0x4e, 0xe6, 0x95, 0xf1, 0xa0, 0xc7, 0xcf, 0x8e, - 0xf6, 0xeb, 0x22, 0x6d, 0xce, 0x9c, 0x44, 0xfb, - 0xc8, 0xa0, 0x44, 0x31, 0x15, 0x4c, 0xe9, 0x97, - 0xa7, 0xa1, 0xfe, 0xea, 0xcc, 0x20, 0x4b, 0x5d, - 0xfb, 0xa5, 0x63, 0x7a, 0x73, 0x95, 0xf7, 0xff, - 0x42, 0xac, 0x8f, 0x46, 0xed, 0xe4, 0xb1, 0x35, - 0x35, 0x78, 0x1a, 0x9d, 0xaf, 0x10, 0xc5, 0x52, - 0xf3, 0x7b, 0xfb, 0xb5, 0xe9, 0xa8, 0x00, 0x24, - 0x00, 0x88, 0x00, 0x87, 0x00, 0x39, 0x00, 0x38, - 0x00, 0x84, 0x00, 0x35, 0x00, 0x45, 0x00, 0x44, - 0x00, 0x33, 0x00, 0x32, 0x00, 0x96, 0x00, 0x41, - 0x00, 0x2f, 0x00, 0x16, 0x00, 0x13, 0xfe, 0xff, - 0x00, 0x0a, 0x00, 0x02, 0x01, 0x00 - }; - uint32_t buf3_len = sizeof(buf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf2, buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf3, buf3_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_connp.version); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest13(void) -{ - int result = 1; - Flow f; - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x6f, 0x01, - }; - uint32_t buf1_len = sizeof(buf1); - - uint8_t buf2[] = { - 0x00, 0x00, 0x6b, - }; - uint32_t buf2_len = sizeof(buf2); - - uint8_t buf3[] = { - 0x03, 0x00, 0x4b, 0x2f, 0xdc, - 0x4e, 0xe6, 0x95, 0xf1, 0xa0, 0xc7, - }; - uint32_t buf3_len = sizeof(buf3); - - uint8_t buf4[] = { - 0xcf, 0x8e, - 0xf6, 0xeb, 0x22, 0x6d, 0xce, 0x9c, 0x44, 0xfb, - 0xc8, 0xa0, 0x44, 0x31, 0x15, 0x4c, 0xe9, 0x97, - 0xa7, 0xa1, 0xfe, 0xea, 0xcc, 0x20, 0x4b, 0x5d, - 0xfb, 0xa5, 0x63, 0x7a, 0x73, 0x95, 0xf7, 0xff, - 0x42, 0xac, 0x8f, 0x46, 0xed, 0xe4, 0xb1, 0x35, - 0x35, 0x78, 0x1a, 0x9d, 0xaf, 0x10, 0xc5, 0x52, - 0xf3, 0x7b, 0xfb, 0xb5, 0xe9, 0xa8, 0x00, 0x24, - 0x00, 0x88, 0x00, 0x87, 0x00, 0x39, 0x00, 0x38, - 0x00, 0x84, 0x00, 0x35, 0x00, 0x45, 0x00, 0x44, - 0x00, 0x33, 0x00, 0x32, 0x00, 0x96, 0x00, 0x41, - 0x00, 0x2f, 0x00, 0x16, 0x00, 0x13, 0xfe, 0xff, - 0x00, 0x0a, 0x00, 0x02, 0x01, 0x00 - }; - uint32_t buf4_len = sizeof(buf4); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf2, buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf3, buf3_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf4, buf4_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x17, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_connp.version); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest14(void) -{ - int result = 1; - Flow f; - - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x00, - }; - uint32_t buf1_len = sizeof(buf1); - - uint8_t buf2[] = { - 0x16, 0x03, 0x00, 0x00, 0x00, - }; - uint32_t buf2_len = sizeof(buf2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf2, buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest15(void) -{ - int result = 1; - Flow f; - - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x01, 0x01, - }; - uint32_t buf1_len = sizeof(buf1); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r == 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest16(void) -{ - int result = 1; - Flow f; - - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x02, 0x01, 0x00 - }; - uint32_t buf1_len = sizeof(buf1); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r == 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest17(void) -{ - int result = 1; - Flow f; - - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00 - }; - uint32_t buf1_len = sizeof(buf1); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r == 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest18(void) -{ - int result = 1; - Flow f; - - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, - 0x6b, - }; - uint32_t buf1_len = sizeof(buf1); - - uint8_t buf2[] = { - 0x16, 0x03, 0x00, 0x00, 0x00, - }; - uint32_t buf2_len = sizeof(buf2); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf2, buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest19(void) -{ - int result = 1; - Flow f; - - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, - 0x6b, 0x16, 0x03, 0x00, 0x00, 0x00, - }; - uint32_t buf1_len = sizeof(buf1); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest20(void) -{ - int result = 1; - Flow f; - - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, - 0x16, 0x03, 0x00, 0x00, 0x00, - }; - uint32_t buf1_len = sizeof(buf1); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r == 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test SSLv2 Record parsing. - */ -static int SSLParserTest21(void) -{ - int result = 0; - Flow f; - uint8_t buf[] = { - 0x80, 0x31, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x01, - }; - uint32_t buf_len = sizeof(buf); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER | STREAM_EOF, buf, - buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *app_state = f.alstate; - if (app_state == NULL) { - printf("no ssl state: "); - goto end; - } - - if (app_state->client_connp.content_type != SSLV2_MT_CLIENT_HELLO) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV2_MT_SERVER_HELLO, app_state->client_connp.content_type); - goto end; - } - - if (app_state->client_connp.version != SSL_VERSION_2) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_2, app_state->client_connp.version); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test SSLv2 Record parsing. - */ -static int SSLParserTest22(void) -{ - int result = 1; - Flow f; - uint8_t buf[] = { - 0x80, 0x31, 0x04, 0x00, 0x01, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x10, 0x07, 0x00, 0xc0, - 0x05, 0x00, 0x80, 0x03, 0x00, 0x80, 0x01, 0x00, - 0x80, 0x08, 0x00, 0x80, 0x06, 0x00, 0x40, 0x04, - 0x00, 0x80, 0x02, 0x00, 0x80, 0x76, 0x64, 0x75, - 0x2d, 0xa7, 0x98, 0xfe, 0xc9, 0x12, 0x92, 0xc1, - 0x2f, 0x34, 0x84, 0x20, 0xc5}; - uint32_t buf_len = sizeof(buf); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - //AppLayerDetectProtoThreadInit(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT | STREAM_EOF, buf, - buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *app_state = f.alstate; - if (app_state == NULL) { - printf("no ssl state: "); - result = 0; - goto end; - } - - if (app_state->server_connp.content_type != SSLV2_MT_SERVER_HELLO) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV2_MT_SERVER_HELLO, app_state->server_connp.content_type); - result = 0; - goto end; - } - - if (app_state->server_connp.version != SSL_VERSION_2) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_2, app_state->server_connp.version); - result = 0; - goto end; - } -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test SSLv2 Record parsing. - */ -static int SSLParserTest23(void) -{ - int result = 1; - Flow f; - uint8_t chello_buf[] = { - 0x80, 0x67, 0x01, 0x03, 0x00, 0x00, 0x4e, 0x00, - 0x00, 0x00, 0x10, 0x01, 0x00, 0x80, 0x03, 0x00, - 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x40, 0x02, - 0x00, 0x80, 0x04, 0x00, 0x80, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x38, 0x00, 0x00, 0x35, 0x00, 0x00, - 0x33, 0x00, 0x00, 0x32, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x05, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x16, - 0x00, 0x00, 0x13, 0x00, 0xfe, 0xff, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x15, 0x00, 0x00, 0x12, 0x00, - 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, - 0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x06, 0xa8, 0xb8, 0x93, 0xbb, 0x90, 0xe9, 0x2a, - 0xa2, 0x4d, 0x6d, 0xcc, 0x1c, 0xe7, 0x2a, 0x80, - 0x21 - }; - uint32_t chello_buf_len = sizeof(chello_buf); - - uint8_t shello_buf[] = { - 0x16, 0x03, 0x00, 0x00, 0x4a, 0x02, - 0x00, 0x00, 0x46, 0x03, 0x00, 0x44, 0x4c, 0x94, - 0x8f, 0xfe, 0x81, 0xed, 0x93, 0x65, 0x02, 0x88, - 0xa3, 0xf8, 0xeb, 0x63, 0x86, 0x0e, 0x2c, 0xf6, - 0x8d, 0xd0, 0x0f, 0x2c, 0x2a, 0xd6, 0x4f, 0xcd, - 0x2d, 0x3c, 0x16, 0xd7, 0xd6, 0x20, 0xa0, 0xfb, - 0x60, 0x86, 0x3d, 0x1e, 0x76, 0xf3, 0x30, 0xfe, - 0x0b, 0x01, 0xfd, 0x1a, 0x01, 0xed, 0x95, 0xf6, - 0x7b, 0x8e, 0xc0, 0xd4, 0x27, 0xbf, 0xf0, 0x6e, - 0xc7, 0x56, 0xb1, 0x47, 0xce, 0x98, 0x00, 0x35, - 0x00, 0x16, 0x03, 0x00, 0x03, 0x44, 0x0b, 0x00, - 0x03, 0x40, 0x00, 0x03, 0x3d, 0x00, 0x03, 0x3a, - 0x30, 0x82, 0x03, 0x36, 0x30, 0x82, 0x02, 0x9f, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, - 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x58, 0x59, 0x31, - 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x0c, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, - 0x44, 0x65, 0x73, 0x65, 0x72, 0x74, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, - 0x0a, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x54, - 0x6f, 0x77, 0x6e, 0x31, 0x17, 0x30, 0x15, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x53, 0x6e, - 0x61, 0x6b, 0x65, 0x20, 0x4f, 0x69, 0x6c, 0x2c, - 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1e, 0x30, 0x1c, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0c, 0x53, - 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x4f, 0x69, 0x6c, - 0x20, 0x43, 0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x01, 0x16, 0x0f, 0x63, 0x61, 0x40, 0x73, - 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, 0x6c, 0x2e, - 0x64, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, - 0x33, 0x30, 0x33, 0x30, 0x35, 0x31, 0x36, 0x34, - 0x37, 0x34, 0x35, 0x5a, 0x17, 0x0d, 0x30, 0x38, - 0x30, 0x33, 0x30, 0x33, 0x31, 0x36, 0x34, 0x37, - 0x34, 0x35, 0x5a, 0x30, 0x81, 0xa7, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x58, 0x59, 0x31, 0x15, 0x30, 0x13, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x0c, 0x53, 0x6e, - 0x61, 0x6b, 0x65, 0x20, 0x44, 0x65, 0x73, 0x65, - 0x72, 0x74, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x6e, 0x61, - 0x6b, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0e, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, - 0x4f, 0x69, 0x6c, 0x2c, 0x20, 0x4c, 0x74, 0x64, - 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x0e, 0x57, 0x65, 0x62, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x61, - 0x6d, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x10, 0x77, 0x77, 0x77, 0x2e, - 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, 0x6c, - 0x2e, 0x64, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x09, 0x01, 0x16, 0x10, 0x77, 0x77, 0x77, - 0x40, 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, - 0x6c, 0x2e, 0x64, 0x6f, 0x6d, 0x30, 0x81, 0x9f, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, - 0x81, 0x00, 0xa4, 0x6e, 0x53, 0x14, 0x0a, 0xde, - 0x2c, 0xe3, 0x60, 0x55, 0x9a, 0xf2, 0x42, 0xa6, - 0xaf, 0x47, 0x12, 0x2f, 0x17, 0xce, 0xfa, 0xba, - 0xdc, 0x4e, 0x63, 0x56, 0x34, 0xb9, 0xba, 0x73, - 0x4b, 0x78, 0x44, 0x3d, 0xc6, 0x6c, 0x69, 0xa4, - 0x25, 0xb3, 0x61, 0x02, 0x9d, 0x09, 0x04, 0x3f, - 0x72, 0x3d, 0xd8, 0x27, 0xd3, 0xb0, 0x5a, 0x45, - 0x77, 0xb7, 0x36, 0xe4, 0x26, 0x23, 0xcc, 0x12, - 0xb8, 0xae, 0xde, 0xa7, 0xb6, 0x3a, 0x82, 0x3c, - 0x7c, 0x24, 0x59, 0x0a, 0xf8, 0x96, 0x43, 0x8b, - 0xa3, 0x29, 0x36, 0x3f, 0x91, 0x7f, 0x5d, 0xc7, - 0x23, 0x94, 0x29, 0x7f, 0x0a, 0xce, 0x0a, 0xbd, - 0x8d, 0x9b, 0x2f, 0x19, 0x17, 0xaa, 0xd5, 0x8e, - 0xec, 0x66, 0xa2, 0x37, 0xeb, 0x3f, 0x57, 0x53, - 0x3c, 0xf2, 0xaa, 0xbb, 0x79, 0x19, 0x4b, 0x90, - 0x7e, 0xa7, 0xa3, 0x99, 0xfe, 0x84, 0x4c, 0x89, - 0xf0, 0x3d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x6e, 0x30, 0x6c, 0x30, 0x1b, 0x06, 0x03, 0x55, - 0x1d, 0x11, 0x04, 0x14, 0x30, 0x12, 0x81, 0x10, - 0x77, 0x77, 0x77, 0x40, 0x73, 0x6e, 0x61, 0x6b, - 0x65, 0x6f, 0x69, 0x6c, 0x2e, 0x64, 0x6f, 0x6d, - 0x30, 0x3a, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x2d, 0x16, - 0x2b, 0x6d, 0x6f, 0x64, 0x5f, 0x73, 0x73, 0x6c, - 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, - 0x6d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x30, 0x11, 0x06, 0x09, - 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, - 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0xae, 0x79, 0x79, 0x22, 0x90, 0x75, - 0xfd, 0xa6, 0xd5, 0xc4, 0xb8, 0xc4, 0x99, 0x4e, - 0x1c, 0x05, 0x7c, 0x91, 0x59, 0xbe, 0x89, 0x0d, - 0x3d, 0xc6, 0x8c, 0xa3, 0xcf, 0xf6, 0xba, 0x23, - 0xdf, 0xb8, 0xae, 0x44, 0x68, 0x8a, 0x8f, 0xb9, - 0x8b, 0xcb, 0x12, 0xda, 0xe6, 0xa2, 0xca, 0xa5, - 0xa6, 0x55, 0xd9, 0xd2, 0xa1, 0xad, 0xba, 0x9b, - 0x2c, 0x44, 0x95, 0x1d, 0x4a, 0x90, 0x59, 0x7f, - 0x83, 0xae, 0x81, 0x5e, 0x3f, 0x92, 0xe0, 0x14, - 0x41, 0x82, 0x4e, 0x7f, 0x53, 0xfd, 0x10, 0x23, - 0xeb, 0x8a, 0xeb, 0xe9, 0x92, 0xea, 0x61, 0xf2, - 0x8e, 0x19, 0xa1, 0xd3, 0x49, 0xc0, 0x84, 0x34, - 0x1e, 0x2e, 0x6e, 0xf6, 0x98, 0xe2, 0x87, 0x53, - 0xd6, 0x55, 0xd9, 0x1a, 0x8a, 0x92, 0x5c, 0xad, - 0xdc, 0x1e, 0x1c, 0x30, 0xa7, 0x65, 0x9d, 0xc2, - 0x4f, 0x60, 0xd2, 0x6f, 0xdb, 0xe0, 0x9f, 0x9e, - 0xbc, 0x41, 0x16, 0x03, 0x00, 0x00, 0x04, 0x0e, - 0x00, 0x00, 0x00 - }; - uint32_t shello_buf_len = sizeof(shello_buf); - - uint8_t client_change_cipher_spec_buf[] = { - 0x16, 0x03, 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, - 0x80, 0x65, 0x51, 0x2d, 0xa6, 0xd4, 0xa7, 0x38, - 0xdf, 0xac, 0x79, 0x1f, 0x0b, 0xd9, 0xb2, 0x61, - 0x7d, 0x73, 0x88, 0x32, 0xd9, 0xf2, 0x62, 0x3a, - 0x8b, 0x11, 0x04, 0x75, 0xca, 0x42, 0xff, 0x4e, - 0xd9, 0xcc, 0xb9, 0xfa, 0x86, 0xf3, 0x16, 0x2f, - 0x09, 0x73, 0x51, 0x66, 0xaa, 0x29, 0xcd, 0x80, - 0x61, 0x0f, 0xe8, 0x13, 0xce, 0x5b, 0x8e, 0x0a, - 0x23, 0xf8, 0x91, 0x5e, 0x5f, 0x54, 0x70, 0x80, - 0x8e, 0x7b, 0x28, 0xef, 0xb6, 0x69, 0xb2, 0x59, - 0x85, 0x74, 0x98, 0xe2, 0x7e, 0xd8, 0xcc, 0x76, - 0x80, 0xe1, 0xb6, 0x45, 0x4d, 0xc7, 0xcd, 0x84, - 0xce, 0xb4, 0x52, 0x79, 0x74, 0xcd, 0xe6, 0xd7, - 0xd1, 0x9c, 0xad, 0xef, 0x63, 0x6c, 0x0f, 0xf7, - 0x05, 0xe4, 0x4d, 0x1a, 0xd3, 0xcb, 0x9c, 0xd2, - 0x51, 0xb5, 0x61, 0xcb, 0xff, 0x7c, 0xee, 0xc7, - 0xbc, 0x5e, 0x15, 0xa3, 0xf2, 0x52, 0x0f, 0xbb, - 0x32, 0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16, - 0x03, 0x00, 0x00, 0x40, 0xa9, 0xd8, 0xd7, 0x35, - 0xbc, 0x39, 0x56, 0x98, 0xad, 0x87, 0x61, 0x2a, - 0xc4, 0x8f, 0xcc, 0x03, 0xcb, 0x93, 0x80, 0x81, - 0xb0, 0x4a, 0xc4, 0xd2, 0x09, 0x71, 0x3e, 0x90, - 0x3c, 0x8d, 0xe0, 0x95, 0x44, 0xfe, 0x56, 0xd1, - 0x7e, 0x88, 0xe2, 0x48, 0xfd, 0x76, 0x70, 0x76, - 0xe2, 0xcd, 0x06, 0xd0, 0xf3, 0x9d, 0x13, 0x79, - 0x67, 0x1e, 0x37, 0xf6, 0x98, 0xbe, 0x59, 0x18, - 0x4c, 0xfc, 0x75, 0x56 - }; - uint32_t client_change_cipher_spec_buf_len = - sizeof(client_change_cipher_spec_buf); - - uint8_t server_change_cipher_spec_buf[] = { - 0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x00, 0x00, 0x40, 0xce, 0x7c, 0x92, 0x43, 0x59, - 0xcc, 0x3d, 0x90, 0x91, 0x9c, 0x58, 0xf0, 0x7a, - 0xce, 0xae, 0x0d, 0x08, 0xe0, 0x76, 0xb4, 0x86, - 0xb1, 0x15, 0x5b, 0x32, 0xb8, 0x77, 0x53, 0xe7, - 0xa6, 0xf9, 0xd0, 0x95, 0x5f, 0xaa, 0x07, 0xc3, - 0x96, 0x7c, 0xc9, 0x88, 0xc2, 0x7a, 0x20, 0x89, - 0x4f, 0xeb, 0xeb, 0xb6, 0x19, 0xef, 0xaa, 0x27, - 0x73, 0x9d, 0xa6, 0xb4, 0x9f, 0xeb, 0x34, 0xe2, - 0x4d, 0x9f, 0x6b - }; - uint32_t server_change_cipher_spec_buf_len = - sizeof(server_change_cipher_spec_buf); - - uint8_t toserver_app_data_buf[] = { - 0x17, 0x03, 0x00, 0x01, 0xb0, 0x4a, 0xc3, 0x3e, - 0x9d, 0x77, 0x78, 0x01, 0x2c, 0xb4, 0xbc, 0x4c, - 0x9a, 0x84, 0xd7, 0xb9, 0x90, 0x0c, 0x21, 0x10, - 0xf0, 0xfa, 0x00, 0x7c, 0x16, 0xbb, 0x77, 0xfb, - 0x72, 0x42, 0x4f, 0xad, 0x50, 0x4a, 0xd0, 0xaa, - 0x6f, 0xaa, 0x44, 0x6c, 0x62, 0x94, 0x1b, 0xc5, - 0xfe, 0xe9, 0x1c, 0x5e, 0xde, 0x85, 0x0b, 0x0e, - 0x05, 0xe4, 0x18, 0x6e, 0xd2, 0xd3, 0xb5, 0x20, - 0xab, 0x81, 0xfd, 0x18, 0x9a, 0x73, 0xb8, 0xd7, - 0xef, 0xc3, 0xdd, 0x74, 0xd7, 0x9c, 0x1e, 0x6f, - 0x21, 0x6d, 0xf8, 0x24, 0xca, 0x3c, 0x70, 0x78, - 0x36, 0x12, 0x7a, 0x8a, 0x9c, 0xac, 0x4e, 0x1c, - 0xa8, 0xfb, 0x27, 0x30, 0xba, 0x9a, 0xf4, 0x2f, - 0x0a, 0xab, 0x80, 0x6a, 0xa1, 0x60, 0x74, 0xf0, - 0xe3, 0x91, 0x84, 0xe7, 0x90, 0x88, 0xcc, 0xf0, - 0x95, 0x7b, 0x0a, 0x22, 0xf2, 0xf9, 0x27, 0xe0, - 0xdd, 0x38, 0x0c, 0xfd, 0xe9, 0x03, 0x71, 0xdc, - 0x70, 0xa4, 0x6e, 0xdf, 0xe3, 0x72, 0x9e, 0xa1, - 0xf0, 0xc9, 0x00, 0xd6, 0x03, 0x55, 0x6a, 0x67, - 0x5d, 0x9c, 0xb8, 0x75, 0x01, 0xb0, 0x01, 0x9f, - 0xe6, 0xd2, 0x44, 0x18, 0xbc, 0xca, 0x7a, 0x10, - 0x39, 0xa6, 0xcf, 0x15, 0xc7, 0xf5, 0x35, 0xd4, - 0xb3, 0x6d, 0x91, 0x23, 0x84, 0x99, 0xba, 0xb0, - 0x7e, 0xd0, 0xc9, 0x4c, 0xbf, 0x3f, 0x33, 0x68, - 0x37, 0xb7, 0x7d, 0x44, 0xb0, 0x0b, 0x2c, 0x0f, - 0xd0, 0x75, 0xa2, 0x6b, 0x5b, 0xe1, 0x9f, 0xd4, - 0x69, 0x9a, 0x14, 0xc8, 0x29, 0xb7, 0xd9, 0x10, - 0xbb, 0x99, 0x30, 0x9a, 0xfb, 0xcc, 0x13, 0x1f, - 0x76, 0x4e, 0xe6, 0xdf, 0x14, 0xaa, 0xd5, 0x60, - 0xbf, 0x91, 0x49, 0x0d, 0x64, 0x42, 0x29, 0xa8, - 0x64, 0x27, 0xd4, 0x5e, 0x1b, 0x18, 0x03, 0xa8, - 0x73, 0xd6, 0x05, 0x6e, 0xf7, 0x50, 0xb0, 0x09, - 0x6b, 0x69, 0x7a, 0x12, 0x28, 0x58, 0xef, 0x5a, - 0x86, 0x11, 0xde, 0x71, 0x71, 0x9f, 0xca, 0xbd, - 0x79, 0x2a, 0xc2, 0xe5, 0x9b, 0x5e, 0x32, 0xe7, - 0xcb, 0x97, 0x6e, 0xa0, 0xea, 0xa4, 0xa4, 0x6a, - 0x32, 0xf9, 0x37, 0x39, 0xd8, 0x37, 0x6d, 0x63, - 0xf3, 0x08, 0x1c, 0xdd, 0x06, 0xdd, 0x2c, 0x2b, - 0x9f, 0x04, 0x88, 0x5f, 0x36, 0x42, 0xc1, 0xb1, - 0xc7, 0xe8, 0x2d, 0x5d, 0xa4, 0x6c, 0xe5, 0x60, - 0x94, 0xae, 0xd0, 0x90, 0x1e, 0x88, 0xa0, 0x87, - 0x52, 0xfb, 0xed, 0x97, 0xa5, 0x25, 0x5a, 0xb7, - 0x55, 0xc5, 0x13, 0x07, 0x85, 0x27, 0x40, 0xed, - 0xb8, 0xa0, 0x26, 0x13, 0x44, 0x0c, 0xfc, 0xcc, - 0x5a, 0x09, 0xe5, 0x44, 0xb5, 0x63, 0xa1, 0x43, - 0x51, 0x23, 0x4f, 0x17, 0x21, 0x89, 0x2e, 0x58, - 0xfd, 0xf9, 0x63, 0x74, 0x04, 0x70, 0x1e, 0x7d, - 0xd0, 0x66, 0xba, 0x40, 0x5e, 0x45, 0xdc, 0x39, - 0x7c, 0x53, 0x0f, 0xa8, 0x38, 0xb2, 0x13, 0x99, - 0x27, 0xd9, 0x4a, 0x51, 0xe9, 0x9f, 0x2a, 0x92, - 0xbb, 0x9c, 0x90, 0xab, 0xfd, 0xf1, 0xb7, 0x40, - 0x05, 0xa9, 0x7a, 0x20, 0x63, 0x36, 0xc1, 0xef, - 0xb9, 0xad, 0xa2, 0xe0, 0x1d, 0x20, 0x4f, 0xb2, - 0x34, 0xbd, 0xea, 0x07, 0xac, 0x21, 0xce, 0xf6, - 0x8a, 0xa2, 0x9e, 0xcd, 0xfa - }; - uint32_t toserver_app_data_buf_len = sizeof(toserver_app_data_buf); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - //AppLayerDetectProtoThreadInit(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER | STREAM_START, chello_buf, - chello_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *app_state = f.alstate; - if (app_state == NULL) { - printf("no ssl state: "); - result = 0; - goto end; - } - - if (app_state->client_connp.content_type != SSLV2_MT_CLIENT_HELLO) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV2_MT_CLIENT_HELLO, app_state->client_connp.content_type); - result = 0; - goto end; - } - - if (app_state->client_connp.version != SSL_VERSION_2) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_2, app_state->client_connp.version); - result = 0; - goto end; - } - - if (app_state->flags != - (SSL_AL_FLAG_STATE_CLIENT_HELLO | SSL_AL_FLAG_SSL_CLIENT_HS | - SSL_AL_FLAG_SSL_NO_SESSION_ID)) { - printf("flags not set\n"); - result = 0; - goto end; - } - - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, shello_buf, - shello_buf_len); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (app_state->server_connp.content_type != SSLV3_HANDSHAKE_PROTOCOL) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV3_HANDSHAKE_PROTOCOL, app_state->server_connp.content_type); - result = 0; - goto end; - } - - if (app_state->server_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, app_state->server_connp.version); - result = 0; - goto end; - } - - if (app_state->flags != - (SSL_AL_FLAG_STATE_CLIENT_HELLO | SSL_AL_FLAG_SSL_CLIENT_HS | - SSL_AL_FLAG_SSL_NO_SESSION_ID | SSL_AL_FLAG_STATE_SERVER_HELLO)) { - printf("flags not set\n"); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, client_change_cipher_spec_buf, - client_change_cipher_spec_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* with multiple records the client content type hold the type from the last - * record */ - if (app_state->client_connp.content_type != SSLV3_HANDSHAKE_PROTOCOL) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV3_HANDSHAKE_PROTOCOL, app_state->client_connp.content_type); - result = 0; - goto end; - } - - if (app_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, app_state->client_connp.version); - result = 0; - goto end; - } - - if (app_state->flags != - (SSL_AL_FLAG_STATE_CLIENT_HELLO | SSL_AL_FLAG_SSL_CLIENT_HS | - SSL_AL_FLAG_SSL_NO_SESSION_ID | SSL_AL_FLAG_STATE_SERVER_HELLO | - SSL_AL_FLAG_STATE_CLIENT_KEYX | SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC | - SSL_AL_FLAG_CHANGE_CIPHER_SPEC)) { - printf("flags not set\n"); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, server_change_cipher_spec_buf, - server_change_cipher_spec_buf_len); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* with multiple records the serve content type hold the type from the last - * record */ - if (app_state->server_connp.content_type != SSLV3_HANDSHAKE_PROTOCOL) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV3_HANDSHAKE_PROTOCOL, app_state->server_connp.content_type); - result = 0; - goto end; - } - - if (app_state->server_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, app_state->server_connp.version); - result = 0; - goto end; - } - - if (app_state->flags != - (SSL_AL_FLAG_STATE_CLIENT_HELLO | SSL_AL_FLAG_SSL_CLIENT_HS | - SSL_AL_FLAG_SSL_NO_SESSION_ID | SSL_AL_FLAG_STATE_SERVER_HELLO | - SSL_AL_FLAG_STATE_CLIENT_KEYX | SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC | - SSL_AL_FLAG_CHANGE_CIPHER_SPEC | SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC | - SSL_AL_FLAG_CHANGE_CIPHER_SPEC)) { - printf("flags not set\n"); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, toserver_app_data_buf, - toserver_app_data_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (app_state->client_connp.content_type != SSLV3_APPLICATION_PROTOCOL) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - SSLV3_APPLICATION_PROTOCOL, app_state->client_connp.content_type); - result = 0; - goto end; - } - - if (app_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, app_state->client_connp.version); - result = 0; - goto end; - } - - if (app_state->flags != - (SSL_AL_FLAG_STATE_CLIENT_HELLO | SSL_AL_FLAG_SSL_CLIENT_HS | - SSL_AL_FLAG_SSL_NO_SESSION_ID | SSL_AL_FLAG_STATE_SERVER_HELLO | - SSL_AL_FLAG_STATE_CLIENT_KEYX | SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC | - SSL_AL_FLAG_CHANGE_CIPHER_SPEC | SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC | - SSL_AL_FLAG_CHANGE_CIPHER_SPEC)) { - printf("flags not set\n"); - result = 0; - goto end; - } - - if (!(f.flags & FLOW_NOPAYLOAD_INSPECTION)) { - printf("The flags should be set\n"); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Tests the parser for handling fragmented records. - */ -static int SSLParserTest24(void) -{ - int result = 1; - Flow f; - uint8_t buf1[] = { - 0x16, 0x03, 0x00, 0x00, 0x6f, 0x01, 0x00, 0x00, - 0x6b, 0x03, - }; - uint32_t buf1_len = sizeof(buf1); - - uint8_t buf2[] = { - 0x00, 0x4b, 0x2f, 0xdc, - 0x4e, 0xe6, 0x95, 0xf1, 0xa0, 0xc7, 0xcf, 0x8e, - 0xf6, 0xeb, 0x22, 0x6d, 0xce, 0x9c, 0x44, 0xfb, - 0xc8, 0xa0, 0x44, 0x31, 0x15, 0x4c, 0xe9, 0x97, - 0xa7, 0xa1, 0xfe, 0xea, 0xcc, 0x20, 0x4b, 0x5d, - 0xfb, 0xa5, 0x63, 0x7a, 0x73, 0x95, 0xf7, 0xff, - 0x42, 0xac, 0x8f, 0x46, 0xed, 0xe4, 0xb1, 0x35, - 0x35, 0x78, 0x1a, 0x9d, 0xaf, 0x10, 0xc5, 0x52, - 0xf3, 0x7b, 0xfb, 0xb5, 0xe9, 0xa8, 0x00, 0x24, - 0x00, 0x88, 0x00, 0x87, 0x00, 0x39, 0x00, 0x38, - 0x00, 0x84, 0x00, 0x35, 0x00, 0x45, 0x00, 0x44, - 0x00, 0x33, 0x00, 0x32, 0x00, 0x96, 0x00, 0x41, - 0x00, 0x2f, 0x00, 0x16, 0x00, 0x13, 0xfe, 0xff, - 0x00, 0x0a, 0x00, 0x02, 0x01, 0x00 - }; - uint32_t buf2_len = sizeof(buf2); - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf1, buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, buf2, buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - result = 0; - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, - ssl_state->client_connp.content_type); - result = 0; - goto end; - } - - if (ssl_state->client_connp.version != SSL_VERSION_3) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - SSL_VERSION_3, ssl_state->client_connp.version); - result = 0; - goto end; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Test for bug #955 and CVE-2013-5919. The data is from the - * pcap that was used to report this issue. - */ -static int SSLParserTest25(void) -{ - int result = 0; - Flow f; - uint8_t client_hello[] = { - 0x16, 0x03, 0x01, 0x00, 0xd3, 0x01, 0x00, 0x00, - 0xcf, 0x03, 0x01, 0x51, 0x60, 0xc2, 0x15, 0x36, - 0x73, 0xf5, 0xb8, 0x58, 0x55, 0x3b, 0x68, 0x12, - 0x7d, 0xe3, 0x28, 0xa3, 0xe1, 0x02, 0x79, 0x2d, - 0x12, 0xe1, 0xf4, 0x24, 0x12, 0xa2, 0x9e, 0xf1, - 0x08, 0x49, 0x68, 0x20, 0x0e, 0x96, 0x46, 0x3d, - 0x84, 0x5a, 0xc6, 0x55, 0xeb, 0x3b, 0x53, 0x77, - 0xf4, 0x8e, 0xf4, 0xd2, 0x8b, 0xec, 0xd6, 0x99, - 0x63, 0x64, 0x62, 0xf8, 0x3f, 0x3b, 0xd5, 0x35, - 0x45, 0x1b, 0x16, 0xac, 0x00, 0x46, 0x00, 0x04, - 0x00, 0x05, 0x00, 0x2f, 0x00, 0x35, 0xc0, 0x02, - 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x0c, 0xc0, 0x0e, - 0xc0, 0x0f, 0xc0, 0x07, 0xc0, 0x09, 0xc0, 0x0a, - 0xc0, 0x11, 0xc0, 0x13, 0xc0, 0x14, 0x00, 0x33, - 0x00, 0x39, 0x00, 0x32, 0x00, 0x38, 0x00, 0x0a, - 0xc0, 0x03, 0xc0, 0x0d, 0xc0, 0x08, 0xc0, 0x12, - 0x00, 0x16, 0x00, 0x13, 0x00, 0x09, 0x00, 0x15, - 0x00, 0x12, 0x00, 0x03, 0x00, 0x08, 0x00, 0x14, - 0x00, 0x11, 0x00, 0xff, 0x01, 0x00, 0x00, 0x40, - 0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, - 0x00, 0x0a, 0x00, 0x34, 0x00, 0x32, 0x00, 0x0e, - 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x0c, - 0x00, 0x18, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x16, - 0x00, 0x17, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, - 0x00, 0x14, 0x00, 0x15, 0x00, 0x04, 0x00, 0x05, - 0x00, 0x12, 0x00, 0x13, 0x00, 0x01, 0x00, 0x02, - 0x00, 0x03, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11 - }; - uint32_t client_hello_len = sizeof(client_hello); - - uint8_t server_hello_certificate_done[] = { - 0x16, 0x03, 0x01, 0x00, 0x51, 0x02, 0x00, 0x00, - 0x4d, 0x03, 0x01, 0x51, 0x60, 0xc2, 0x17, 0xb7, - 0x81, 0xaa, 0x27, 0xa1, 0xd5, 0xfa, 0x14, 0xc1, - 0xe0, 0x05, 0xab, 0x75, 0xf2, 0x51, 0xe7, 0x6e, - 0xe6, 0xf9, 0xc4, 0x8f, 0x16, 0x08, 0x26, 0x6c, - 0x1b, 0x86, 0x90, 0x20, 0x0a, 0x38, 0x90, 0x2d, - 0x17, 0x7d, 0xb7, 0x6b, 0x6b, 0xe5, 0xeb, 0x61, - 0x90, 0x35, 0xf8, 0xcd, 0xb1, 0x2a, 0x69, 0x6e, - 0x0e, 0x3e, 0x5f, 0x90, 0xdc, 0x2f, 0x51, 0x45, - 0x68, 0x63, 0xe3, 0xb3, 0x00, 0x05, 0x00, 0x00, - 0x05, 0xff, 0x01, 0x00, 0x01, 0x00, 0x16, 0x03, - 0x01, 0x07, 0x60, 0x0b, 0x00, 0x07, 0x5c, 0x00, - 0x07, 0x59, 0x00, 0x03, 0xcc, 0x30, 0x82, 0x03, - 0xc8, 0x30, 0x82, 0x03, 0x31, 0xa0, 0x03, 0x02, - 0x01, 0x02, 0x02, 0x10, 0x01, 0x7f, 0x77, 0xde, - 0xb3, 0xbc, 0xbb, 0x23, 0x5d, 0x44, 0xcc, 0xc7, - 0xdb, 0xa6, 0x2e, 0x72, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x30, 0x81, 0xba, 0x31, 0x1f, - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, - 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, - 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x2a, 0x56, 0x65, 0x72, 0x69, 0x53, - 0x69, 0x67, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, - 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x20, 0x33, 0x31, 0x49, 0x30, - 0x47, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x40, - 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, - 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x43, 0x50, 0x53, 0x20, 0x49, 0x6e, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x62, 0x79, 0x20, 0x52, - 0x65, 0x66, 0x2e, 0x20, 0x4c, 0x49, 0x41, 0x42, - 0x49, 0x4c, 0x49, 0x54, 0x59, 0x20, 0x4c, 0x54, - 0x44, 0x2e, 0x28, 0x63, 0x29, 0x39, 0x37, 0x20, - 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, - 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x36, - 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x32, 0x33, - 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, - 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, - 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, - 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x50, - 0x61, 0x6c, 0x6f, 0x20, 0x41, 0x6c, 0x74, 0x6f, - 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0e, 0x46, 0x61, 0x63, 0x65, 0x62, - 0x6f, 0x6f, 0x6b, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, - 0x04, 0x02, 0x14, 0x0e, 0x2a, 0x2e, 0x66, 0x61, - 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x63, - 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, - 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xae, - 0x94, 0xb1, 0x71, 0xe2, 0xde, 0xcc, 0xc1, 0x69, - 0x3e, 0x05, 0x10, 0x63, 0x24, 0x01, 0x02, 0xe0, - 0x68, 0x9a, 0xe8, 0x3c, 0x39, 0xb6, 0xb3, 0xe7, - 0x4b, 0x97, 0xd4, 0x8d, 0x7b, 0x23, 0x68, 0x91, - 0x00, 0xb0, 0xb4, 0x96, 0xee, 0x62, 0xf0, 0xe6, - 0xd3, 0x56, 0xbc, 0xf4, 0xaa, 0x0f, 0x50, 0x64, - 0x34, 0x02, 0xf5, 0xd1, 0x76, 0x6a, 0xa9, 0x72, - 0x83, 0x5a, 0x75, 0x64, 0x72, 0x3f, 0x39, 0xbb, - 0xef, 0x52, 0x90, 0xde, 0xd9, 0xbc, 0xdb, 0xf9, - 0xd3, 0xd5, 0x5d, 0xfa, 0xd2, 0x3a, 0xa0, 0x3d, - 0xc6, 0x04, 0xc5, 0x4d, 0x29, 0xcf, 0x1d, 0x4b, - 0x3b, 0xdb, 0xd1, 0xa8, 0x09, 0xcf, 0xae, 0x47, - 0xb4, 0x4c, 0x7e, 0xae, 0x17, 0xc5, 0x10, 0x9b, - 0xee, 0x24, 0xa9, 0xcf, 0x4a, 0x8d, 0x91, 0x1b, - 0xb0, 0xfd, 0x04, 0x15, 0xae, 0x4c, 0x3f, 0x43, - 0x0a, 0xa1, 0x2a, 0x55, 0x7e, 0x2a, 0xe1, 0x02, - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1e, - 0x30, 0x82, 0x01, 0x1a, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, - 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, - 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, - 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x17, - 0x03, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x01, 0x16, - 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, - 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x3c, 0x06, - 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x35, 0x30, 0x33, - 0x30, 0x31, 0xa0, 0x2f, 0xa0, 0x2d, 0x86, 0x2b, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x53, - 0x56, 0x52, 0x49, 0x6e, 0x74, 0x6c, 0x2d, 0x63, - 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, - 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x53, 0x56, 0x52, 0x49, 0x6e, 0x74, 0x6c, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x03, 0x02, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, - 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, - 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, - 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, - 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x27, 0x06, - 0x03, 0x55, 0x1d, 0x11, 0x04, 0x20, 0x30, 0x1e, - 0x82, 0x0e, 0x2a, 0x2e, 0x66, 0x61, 0x63, 0x65, - 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, - 0x82, 0x0c, 0x66, 0x61, 0x63, 0x65, 0x62, 0x6f, - 0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, - 0x00, 0x5b, 0x6c, 0x2b, 0x75, 0xf8, 0xed, 0x30, - 0xaa, 0x51, 0xaa, 0xd3, 0x6a, 0xba, 0x59, 0x5e, - 0x55, 0x51, 0x41, 0x95, 0x1f, 0x81, 0xa5, 0x3b, - 0x44, 0x79, 0x10, 0xac, 0x1f, 0x76, 0xff, 0x78, - 0xfc, 0x27, 0x81, 0x61, 0x6b, 0x58, 0xf3, 0x12, - 0x2a, 0xfc, 0x1c, 0x87, 0x01, 0x04, 0x25, 0xe9, - 0xed, 0x43, 0xdf, 0x1a, 0x7b, 0xa6, 0x49, 0x80, - 0x60, 0x67, 0xe2, 0x68, 0x8a, 0xf0, 0x3d, 0xb5, - 0x8c, 0x7d, 0xf4, 0xee, 0x03, 0x30, 0x9a, 0x6a, - 0xfc, 0x24, 0x7c, 0xcb, 0x13, 0x4d, 0xc3, 0x3e, - 0x54, 0xc6, 0xbc, 0x1d, 0x51, 0x33, 0xa5, 0x32, - 0xa7, 0x32, 0x73, 0xb1, 0xd7, 0x9c, 0xad, 0xc0, - 0x8e, 0x7e, 0x1a, 0x83, 0x11, 0x6d, 0x34, 0x52, - 0x33, 0x40, 0xb0, 0x30, 0x54, 0x27, 0xa2, 0x17, - 0x42, 0x82, 0x7c, 0x98, 0x91, 0x66, 0x98, 0xee, - 0x7e, 0xaf, 0x8c, 0x3b, 0xdd, 0x71, 0x70, 0x08, - 0x17, 0x00, 0x03, 0x87, 0x30, 0x82, 0x03, 0x83, - 0x30, 0x82, 0x02, 0xec, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x46, 0xfc, 0xeb, 0xba, 0xb4, - 0xd0, 0x2f, 0x0f, 0x92, 0x60, 0x98, 0x23, 0x3f, - 0x93, 0x07, 0x8f, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x13, 0x2e, 0x43, 0x6c, 0x61, - 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x41, 0x75, 0x64, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x39, - 0x37, 0x30, 0x34, 0x31, 0x37, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x36, - 0x31, 0x30, 0x32, 0x34, 0x32, 0x33, 0x35, 0x39, - 0x35, 0x39, 0x5a, 0x30, 0x81, 0xba, 0x31, 0x1f, - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, - 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, - 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x2a, 0x56, 0x65, 0x72, 0x69, 0x53, - 0x69, 0x67, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, - 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x20, 0x33, 0x31, 0x49, 0x30, - 0x47, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x40, - 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, - 0x73, 0x69, - 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, - 0x50, 0x53, 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, - 0x70, 0x2e, 0x62, 0x79, 0x20, 0x52, 0x65, 0x66, - 0x2e, 0x20, 0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c, - 0x49, 0x54, 0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, - 0x28, 0x63, 0x29, 0x39, 0x37, 0x20, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x30, 0x81, - 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, - 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, - 0x81, 0x81, 0x00, 0xd8, 0x82, 0x80, 0xe8, 0xd6, - 0x19, 0x02, 0x7d, 0x1f, 0x85, 0x18, 0x39, 0x25, - 0xa2, 0x65, 0x2b, 0xe1, 0xbf, 0xd4, 0x05, 0xd3, - 0xbc, 0xe6, 0x36, 0x3b, 0xaa, 0xf0, 0x4c, 0x6c, - 0x5b, 0xb6, 0xe7, 0xaa, 0x3c, 0x73, 0x45, 0x55, - 0xb2, 0xf1, 0xbd, 0xea, 0x97, 0x42, 0xed, 0x9a, - 0x34, 0x0a, 0x15, 0xd4, 0xa9, 0x5c, 0xf5, 0x40, - 0x25, 0xdd, 0xd9, 0x07, 0xc1, 0x32, 0xb2, 0x75, - 0x6c, 0xc4, 0xca, 0xbb, 0xa3, 0xfe, 0x56, 0x27, - 0x71, 0x43, 0xaa, 0x63, 0xf5, 0x30, 0x3e, 0x93, - 0x28, 0xe5, 0xfa, 0xf1, 0x09, 0x3b, 0xf3, 0xb7, - 0x4d, 0x4e, 0x39, 0xf7, 0x5c, 0x49, 0x5a, 0xb8, - 0xc1, 0x1d, 0xd3, 0xb2, 0x8a, 0xfe, 0x70, 0x30, - 0x95, 0x42, 0xcb, 0xfe, 0x2b, 0x51, 0x8b, 0x5a, - 0x3c, 0x3a, 0xf9, 0x22, 0x4f, 0x90, 0xb2, 0x02, - 0xa7, 0x53, 0x9c, 0x4f, 0x34, 0xe7, 0xab, 0x04, - 0xb2, 0x7b, 0x6f, 0x02, 0x03, 0x01, 0x00, 0x01, - 0xa3, 0x81, 0xe3, 0x30, 0x81, 0xe0, 0x30, 0x0f, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, - 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, - 0x44, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, - 0x30, 0x3b, 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, - 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x01, - 0x01, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, - 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, - 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x34, 0x06, - 0x03, 0x55, 0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, - 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, - 0x01, 0x08, 0x01, 0x30, 0x0b, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, - 0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, - 0x02, 0x01, 0x06, 0x30, 0x31, 0x06, 0x03, 0x55, - 0x1d, 0x1f, 0x04, 0x2a, 0x30, 0x28, 0x30, 0x26, - 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, - 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, - 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, - 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, - 0x00, 0x40, 0x8e, 0x49, 0x97, 0x96, 0x8a, 0x73, - 0xdd, 0x8e, 0x4d, 0xef, 0x3e, 0x61, 0xb7, 0xca, - 0xa0, 0x62, 0xad, 0xf4, 0x0e, 0x0a, 0xbb, 0x75, - 0x3d, 0xe2, 0x6e, 0xd8, 0x2c, 0xc7, 0xbf, 0xf4, - 0xb9, 0x8c, 0x36, 0x9b, 0xca, 0xa2, 0xd0, 0x9c, - 0x72, 0x46, 0x39, 0xf6, 0xa6, 0x82, 0x03, 0x65, - 0x11, 0xc4, 0xbc, 0xbf, 0x2d, 0xa6, 0xf5, 0xd9, - 0x3b, 0x0a, 0xb5, 0x98, 0xfa, 0xb3, 0x78, 0xb9, - 0x1e, 0xf2, 0x2b, 0x4c, 0x62, 0xd5, 0xfd, 0xb2, - 0x7a, 0x1d, 0xdf, 0x33, 0xfd, 0x73, 0xf9, 0xa5, - 0xd8, 0x2d, 0x8c, 0x2a, 0xea, 0xd1, 0xfc, 0xb0, - 0x28, 0xb6, 0xe9, 0x49, 0x48, 0x13, 0x4b, 0x83, - 0x8a, 0x1b, 0x48, 0x7b, 0x24, 0xf7, 0x38, 0xde, - 0x6f, 0x41, 0x54, 0xb8, 0xab, 0x57, 0x6b, 0x06, - 0xdf, 0xc7, 0xa2, 0xd4, 0xa9, 0xf6, 0xf1, 0x36, - 0x62, 0x80, 0x88, 0xf2, 0x8b, 0x75, 0xd6, 0x80, - 0x75, 0x16, 0x03, 0x01, 0x00, 0x04, 0x0e, 0x00, - 0x00, 0x00 - }; - uint32_t server_hello_certificate_done_len = sizeof(server_hello_certificate_done); - - uint8_t client_key_exchange_cipher_enc_hs[] = { - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x80, 0x00, 0x80, 0x14, 0x2b, 0x2f, 0x9f, 0x02, - 0x1d, 0x4e, 0x0d, 0xa7, 0x41, 0x0f, 0x99, 0xc5, - 0xe9, 0x49, 0x22, 0x14, 0xa0, 0x42, 0x7b, 0xb4, - 0x6d, 0x4f, 0x82, 0x3c, 0x3a, 0x6e, 0xed, 0xd5, - 0x6e, 0x72, 0x71, 0xae, 0x00, 0x4a, 0x9a, 0xc9, - 0x0e, 0x2d, 0x08, 0xa2, 0xd3, 0x3a, 0xb0, 0xb2, - 0x1a, 0x56, 0x01, 0x7c, 0x9a, 0xfa, 0xfb, 0x1a, - 0xd7, 0x7e, 0x20, 0x68, 0x51, 0xd0, 0xfe, 0xd9, - 0xdc, 0xa7, 0x0b, 0xeb, 0x1a, 0xb6, 0xd3, 0xc7, - 0x17, 0x1f, 0xf3, 0x6e, 0x91, 0xdd, 0x06, 0x0d, - 0x48, 0xde, 0xcd, 0x0c, 0x36, 0x8c, 0x83, 0x29, - 0x9a, 0x40, 0x03, 0xcd, 0xf3, 0x1b, 0xdb, 0xd8, - 0x44, 0x6b, 0x75, 0xf3, 0x5a, 0x9f, 0x26, 0x1a, - 0xc4, 0x16, 0x35, 0x8f, 0xc1, 0x15, 0x19, 0xa9, - 0xdf, 0x07, 0xa9, 0xe5, 0x56, 0x45, 0x6d, 0xca, - 0x20, 0x3c, 0xcf, 0x8e, 0xbe, 0x44, 0x68, 0x73, - 0xc8, 0x0b, 0xc7, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x24, 0xf9, 0x7e, - 0x28, 0x77, 0xa9, 0x9a, 0x08, 0x0c, 0x2e, 0xa9, - 0x09, 0x15, 0x27, 0xcd, 0x93, 0x5f, 0xc0, 0x32, - 0x0a, 0x8d, 0x62, 0xd3, 0x54, 0x79, 0x6b, 0x51, - 0xd7, 0xba, 0x02, 0xd6, 0xdb, 0x66, 0xe8, 0x97, - 0x5d, 0x7a - }; - uint32_t client_key_exchange_cipher_enc_hs_len = sizeof(client_key_exchange_cipher_enc_hs); - - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, client_hello, client_hello_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - goto end; - } - - if (ssl_state->client_connp.bytes_processed != 0 || - ssl_state->client_connp.hs_bytes_processed != 0) - { - printf("client_hello error\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, - server_hello_certificate_done, - server_hello_certificate_done_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - if (ssl_state->client_connp.bytes_processed != 0 || - ssl_state->client_connp.hs_bytes_processed != 0) - { - printf("server_hello_certificate_done error\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, - client_key_exchange_cipher_enc_hs, - client_key_exchange_cipher_enc_hs_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* The reason hs_bytes_processed is 2 is because, the record - * immediately after the client key exchange is 2 bytes long, - * and next time we see a new handshake, it is after we have - * seen a change cipher spec. Hence when we process the - * handshake, we immediately break and don't parse the pdu from - * where we left off, and leave the hs_bytes_processed var - * isn't reset. */ - if (ssl_state->client_connp.bytes_processed != 0 || - ssl_state->client_connp.hs_bytes_processed != 2) - { - printf("client_key_exchange_cipher_enc_hs error\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - return result; -} - -#endif /* UNITTESTS */ - -void SSLParserRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SSLParserTest01", SSLParserTest01, 1); - UtRegisterTest("SSLParserTest02", SSLParserTest02, 1); - UtRegisterTest("SSLParserTest03", SSLParserTest03, 1); - UtRegisterTest("SSLParserTest04", SSLParserTest04, 1); - /* Updated by Anoop Saldanha. Faulty tests. Disable it for now */ - //UtRegisterTest("SSLParserTest05", SSLParserTest05, 1); - //UtRegisterTest("SSLParserTest06", SSLParserTest06, 1); - UtRegisterTest("SSLParserTest07", SSLParserTest07, 1); - //UtRegisterTest("SSLParserTest08", SSLParserTest08, 1); - UtRegisterTest("SSLParserTest09", SSLParserTest09, 1); - UtRegisterTest("SSLParserTest10", SSLParserTest10, 1); - UtRegisterTest("SSLParserTest11", SSLParserTest11, 1); - UtRegisterTest("SSLParserTest12", SSLParserTest12, 1); - UtRegisterTest("SSLParserTest13", SSLParserTest13, 1); - - UtRegisterTest("SSLParserTest14", SSLParserTest14, 1); - UtRegisterTest("SSLParserTest15", SSLParserTest15, 1); - UtRegisterTest("SSLParserTest16", SSLParserTest16, 1); - UtRegisterTest("SSLParserTest17", SSLParserTest17, 1); - UtRegisterTest("SSLParserTest18", SSLParserTest18, 1); - UtRegisterTest("SSLParserTest19", SSLParserTest19, 1); - UtRegisterTest("SSLParserTest20", SSLParserTest20, 1); - UtRegisterTest("SSLParserTest21", SSLParserTest21, 1); - UtRegisterTest("SSLParserTest22", SSLParserTest22, 1); - UtRegisterTest("SSLParserTest23", SSLParserTest23, 1); - UtRegisterTest("SSLParserTest24", SSLParserTest24, 1); - UtRegisterTest("SSLParserTest25", SSLParserTest25, 1); - - UtRegisterTest("SSLParserMultimsgTest01", SSLParserMultimsgTest01, 1); - UtRegisterTest("SSLParserMultimsgTest02", SSLParserMultimsgTest02, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/app-layer-ssl.h b/framework/src/suricata/src/app-layer-ssl.h deleted file mode 100644 index e6274249..00000000 --- a/framework/src/suricata/src/app-layer-ssl.h +++ /dev/null @@ -1,178 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Pierre Chifflier - * - */ - -#ifndef __APP_LAYER_SSL_H__ -#define __APP_LAYER_SSL_H__ - -#include "decode-events.h" -#include "queue.h" - -enum { - /* TLS protocol messages */ - TLS_DECODER_EVENT_INVALID_SSLV2_HEADER, - TLS_DECODER_EVENT_INVALID_TLS_HEADER, - TLS_DECODER_EVENT_INVALID_RECORD_VERSION, - TLS_DECODER_EVENT_INVALID_RECORD_TYPE, - TLS_DECODER_EVENT_INVALID_HANDSHAKE_MESSAGE, - TLS_DECODER_EVENT_HEARTBEAT, - TLS_DECODER_EVENT_INVALID_HEARTBEAT, - TLS_DECODER_EVENT_OVERFLOW_HEARTBEAT, - TLS_DECODER_EVENT_DATALEAK_HEARTBEAT_MISMATCH, - /* Certificates decoding messages */ - TLS_DECODER_EVENT_INVALID_CERTIFICATE, - TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT, - TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT, - TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH, - TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING, - TLS_DECODER_EVENT_ERROR_MSG_ENCOUNTERED, - TLS_DECODER_EVENT_INVALID_SSL_RECORD, -}; - -/* Flag to indicate that server will now on send encrypted msgs */ -#define SSL_AL_FLAG_SERVER_CHANGE_CIPHER_SPEC 0x0001 -/* Flag to indicate that client will now on send encrypted msgs */ -#define SSL_AL_FLAG_CLIENT_CHANGE_CIPHER_SPEC 0x0002 -#define SSL_AL_FLAG_CHANGE_CIPHER_SPEC 0x0004 - -/* SSL related flags */ -#define SSL_AL_FLAG_SSL_CLIENT_HS 0x0008 -#define SSL_AL_FLAG_SSL_SERVER_HS 0x0010 -#define SSL_AL_FLAG_SSL_CLIENT_MASTER_KEY 0x0020 -#define SSL_AL_FLAG_SSL_CLIENT_SSN_ENCRYPTED 0x0040 -#define SSL_AL_FLAG_SSL_SERVER_SSN_ENCRYPTED 0x0080 -#define SSL_AL_FLAG_SSL_NO_SESSION_ID 0x0100 - -/* flags specific to detect-ssl-state keyword */ -#define SSL_AL_FLAG_STATE_CLIENT_HELLO 0x0200 -#define SSL_AL_FLAG_STATE_SERVER_HELLO 0x0400 -#define SSL_AL_FLAG_STATE_CLIENT_KEYX 0x0800 -#define SSL_AL_FLAG_STATE_SERVER_KEYX 0x1000 -#define SSL_AL_FLAG_STATE_UNKNOWN 0x2000 - -#define SSL_AL_FLAG_STATE_LOGGED 0x4000 - -/* flags specific to HeartBeat state */ -#define SSL_AL_FLAG_HB_INFLIGHT 0x8000 -#define SSL_AL_FLAG_HB_CLIENT_INIT 0x10000 -#define SSL_AL_FLAG_HB_SERVER_INIT 0x20000 - -/* flags for file storage */ -#define SSL_AL_FLAG_STATE_STORED 0x40000 - -#define SSL_AL_FLAG_STATE_LOGGED_LUA 0x80000 - -/* config flags */ -#define SSL_TLS_LOG_PEM (1 << 0) - -/* extensions */ -#define SSL_EXTENSION_SNI 0x0000 - -/* SSL versions. We'll use a unified format for all, with the top byte - * holding the major version and the lower byte the minor version */ -enum { - TLS_VERSION_UNKNOWN = 0x0000, - SSL_VERSION_2 = 0x0200, - SSL_VERSION_3 = 0x0300, - TLS_VERSION_10 = 0x0301, - TLS_VERSION_11 = 0x0302, - TLS_VERSION_12 = 0x0303, -}; - -typedef struct SSLCertsChain_ { - uint8_t *cert_data; - uint32_t cert_len; - TAILQ_ENTRY(SSLCertsChain_) next; -} SSLCertsChain; - - -typedef struct SSLStateConnp_ { - /* record length */ - uint32_t record_length; - /* record length's length for SSLv2 */ - uint32_t record_lengths_length; - - /* offset of the beginning of the current message (including header) */ - uint32_t message_start; - uint32_t message_length; - - uint16_t version; - uint8_t content_type; - - uint8_t handshake_type; - uint32_t handshake_length; - - /* the no of bytes processed in the currently parsed record */ - uint16_t bytes_processed; - /* the no of bytes processed in the currently parsed handshake */ - uint16_t hs_bytes_processed; - - /* sslv2 client hello session id length */ - uint16_t session_id_length; - - char *cert0_subject; - char *cert0_issuerdn; - char *cert0_fingerprint; - - /* ssl server name indication extension */ - char *sni; - - uint8_t *cert_input; - uint32_t cert_input_len; - - TAILQ_HEAD(, SSLCertsChain_) certs; - - uint32_t cert_log_flag; - - /* buffer for the tls record. - * We use a malloced buffer, if the record is fragmented */ - uint8_t *trec; - uint32_t trec_len; - uint32_t trec_pos; -} SSLStateConnp; - -/** - * \brief SSLv[2.0|3.[0|1|2|3]] state structure. - * - * Structure to store the SSL state values. - */ -typedef struct SSLState_ { - Flow *f; - - /* holds some state flags we need */ - uint32_t flags; - - SSLStateConnp *curr_connp; - - SSLStateConnp client_connp; - SSLStateConnp server_connp; - - /* there might be a better place to store this*/ - uint16_t hb_record_len; -} SSLState; - -void RegisterSSLParsers(void); -void SSLParserRegisterTests(void); - -#endif /* __APP_LAYER_SSL_H__ */ diff --git a/framework/src/suricata/src/app-layer-template.c b/framework/src/suricata/src/app-layer-template.c deleted file mode 100644 index 5eafa67e..00000000 --- a/framework/src/suricata/src/app-layer-template.c +++ /dev/null @@ -1,541 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file Template application layer detector and parser for learning and - * template pruposes. - * - * This template implements a simple application layer for something - * like the echo protocol running on port 7. - */ - -#include "suricata-common.h" -#include "stream.h" -#include "conf.h" - -#include "util-unittest.h" - -#include "app-layer-detect-proto.h" -#include "app-layer-parser.h" - -#include "app-layer-template.h" - -/* The default port to probe for echo traffic if not provided in the - * configuration file. */ -#define TEMPLATE_DEFAULT_PORT "7" - -/* The minimum size for an echo message. For some protocols this might - * be the size of a header. */ -#define TEMPLATE_MIN_FRAME_LEN 1 - -/* Enum of app-layer events for an echo protocol. Normally you might - * have events for errors in parsing data, like unexpected data being - * received. For echo we'll make something up, and log an app-layer - * level alert if an empty message is received. - * - * Example rule: - * - * alert template any any -> any any (msg:"SURCATA Template empty message"; \ - * app-layer-event:template.empty_message; sid:X; rev:Y;) - */ -enum { - TEMPLATE_DECODER_EVENT_EMPTY_MESSAGE, -}; - -SCEnumCharMap template_decoder_event_table[] = { - {"EMPTY_MESSAGE", TEMPLATE_DECODER_EVENT_EMPTY_MESSAGE}, -}; - -static TemplateTransaction *TemplateTxAlloc(TemplateState *echo) -{ - TemplateTransaction *tx = SCCalloc(1, sizeof(TemplateTransaction)); - if (unlikely(tx == NULL)) { - return NULL; - } - - /* Increment the transaction ID on the state each time one is - * allocated. */ - tx->tx_id = echo->transaction_max++; - - TAILQ_INSERT_TAIL(&echo->tx_list, tx, next); - - return tx; -} - -static void TemplateTxFree(void *tx) -{ - TemplateTransaction *templatetx = tx; - - if (templatetx->request_buffer != NULL) { - SCFree(templatetx->request_buffer); - } - - if (templatetx->response_buffer != NULL) { - SCFree(templatetx->response_buffer); - } - - AppLayerDecoderEventsFreeEvents(&templatetx->decoder_events); - - SCFree(tx); -} - -static void *TemplateStateAlloc(void) -{ - SCLogNotice("Allocating template state."); - TemplateState *state = SCCalloc(1, sizeof(TemplateState)); - if (unlikely(state == NULL)) { - return NULL; - } - TAILQ_INIT(&state->tx_list); - return state; -} - -static void TemplateStateFree(void *state) -{ - TemplateState *template_state = state; - TemplateTransaction *tx; - SCLogNotice("Freeing template state."); - while ((tx = TAILQ_FIRST(&template_state->tx_list)) != NULL) { - TAILQ_REMOVE(&template_state->tx_list, tx, next); - TemplateTxFree(tx); - } - SCFree(template_state); -} - -/** - * \brief Callback from the application layer to have a transaction freed. - * - * \param state a void pointer to the TemplateState object. - * \param tx_id the transaction ID to free. - */ -static void TemplateStateTxFree(void *state, uint64_t tx_id) -{ - TemplateState *echo = state; - TemplateTransaction *tx = NULL, *ttx; - - SCLogNotice("Freeing transaction %"PRIu64, tx_id); - - TAILQ_FOREACH_SAFE(tx, &echo->tx_list, next, ttx) { - - /* Continue if this is not the transaction we are looking - * for. */ - if (tx->tx_id != tx_id) { - continue; - } - - /* Remove and free the transaction. */ - TAILQ_REMOVE(&echo->tx_list, tx, next); - TemplateTxFree(tx); - return; - } - - SCLogNotice("Transaction %"PRIu64" not found.", tx_id); -} - -static int TemplateStateGetEventInfo(const char *event_name, int *event_id, - AppLayerEventType *event_type) -{ - *event_id = SCMapEnumNameToValue(event_name, template_decoder_event_table); - if (*event_id == -1) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " - "template enum map table.", event_name); - /* This should be treated as fatal. */ - return -1; - } - - *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION; - - return 0; -} - -static AppLayerDecoderEvents *TemplateGetEvents(void *state, uint64_t tx_id) -{ - TemplateState *template_state = state; - TemplateTransaction *tx; - - TAILQ_FOREACH(tx, &template_state->tx_list, next) { - if (tx->tx_id == tx_id) { - return tx->decoder_events; - } - } - - return NULL; -} - -static int TemplateHasEvents(void *state) -{ - TemplateState *echo = state; - return echo->events; -} - -/** - * \brief Probe the input to see if it looks like echo. - * - * \retval ALPROTO_TEMPLATE if it looks like echo, otherwise - * ALPROTO_UNKNOWN. - */ -static AppProto TemplateProbingParser(uint8_t *input, uint32_t input_len, - uint32_t *offset) -{ - /* Very simple test - if there is input, this is echo. */ - if (input_len >= TEMPLATE_MIN_FRAME_LEN) { - SCLogNotice("Detected as ALPROTO_TEMPLATE."); - return ALPROTO_TEMPLATE; - } - - SCLogNotice("Protocol not detected as ALPROTO_TEMPLATE."); - return ALPROTO_UNKNOWN; -} - -static int TemplateParseRequest(Flow *f, void *state, - AppLayerParserState *pstate, uint8_t *input, uint32_t input_len, - void *local_data) -{ - TemplateState *echo = state; - - SCLogNotice("Parsing echo request: len=%"PRIu32, input_len); - - /* Likely connection closed, we can just return here. */ - if ((input == NULL || input_len == 0) && - AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - return 0; - } - - /* Probably don't want to create a transaction in this case - * either. */ - if (input == NULL || input_len == 0) { - return 0; - } - - /* Normally you would parse out data here and store it in the - * transaction object, but as this is echo, we'll just record the - * request data. */ - - /* Also, if this protocol may have a "protocol data unit" span - * multiple chunks of data, which is always a possibility with - * TCP, you may need to do some buffering here. - * - * For the sake of simplicity, buffering is left out here, but - * even for an echo protocol we may want to buffer until a new - * line is seen, assuming its text based. - */ - - /* Allocate a transaction. - * - * But note that if a "protocol data unit" is not received in one - * chunk of data, and the buffering is done on the transaction, we - * may need to look for the transaction that this newly recieved - * data belongs to. - */ - TemplateTransaction *tx = TemplateTxAlloc(echo); - if (unlikely(tx == NULL)) { - SCLogNotice("Failed to allocate new Template tx."); - goto end; - } - SCLogNotice("Allocated Template tx %"PRIu64".", tx->tx_id); - - /* Make a copy of the request. */ - tx->request_buffer = SCCalloc(1, input_len); - if (unlikely(tx->request_buffer == NULL)) { - goto end; - } - memcpy(tx->request_buffer, input, input_len); - tx->request_buffer_len = input_len; - - /* Here we check for an empty message and create an app-layer - * event. */ - if ((input_len == 1 && tx->request_buffer[0] == '\n') || - (input_len == 2 && tx->request_buffer[0] == '\r')) { - SCLogNotice("Creating event for empty message."); - AppLayerDecoderEventsSetEventRaw(&tx->decoder_events, - TEMPLATE_DECODER_EVENT_EMPTY_MESSAGE); - echo->events++; - } - -end: - return 0; -} - -static int TemplateParseResponse(Flow *f, void *state, AppLayerParserState *pstate, - uint8_t *input, uint32_t input_len, void *local_data) -{ - TemplateState *echo = state; - TemplateTransaction *tx = NULL, *ttx;; - - SCLogNotice("Parsing Template response."); - - /* Likely connection closed, we can just return here. */ - if ((input == NULL || input_len == 0) && - AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - return 0; - } - - /* Probably don't want to create a transaction in this case - * either. */ - if (input == NULL || input_len == 0) { - return 0; - } - - /* Look up the existing transaction for this response. In the case - * of echo, it will be the most recent transaction on the - * TemplateState object. */ - - /* We should just grab the last transaction, but this is to - * illustrate how you might traverse the transaction list to find - * the transaction associated with this response. */ - TAILQ_FOREACH(ttx, &echo->tx_list, next) { - tx = ttx; - } - - if (tx == NULL) { - SCLogNotice("Failed to find transaction for response on echo state %p.", - echo); - goto end; - } - - SCLogNotice("Found transaction %"PRIu64" for response on echo state %p.", - tx->tx_id, echo); - - /* If the protocol requires multiple chunks of data to complete, you may - * run into the case where you have existing response data. - * - * In this case, we just log that there is existing data and free it. But - * you might want to realloc the buffer and append the data. - */ - if (tx->response_buffer != NULL) { - SCLogNotice("WARNING: Transaction already has response data, " - "existing data will be overwritten."); - SCFree(tx->response_buffer); - } - - /* Make a copy of the response. */ - tx->response_buffer = SCCalloc(1, input_len); - if (unlikely(tx->response_buffer == NULL)) { - goto end; - } - memcpy(tx->response_buffer, input, input_len); - tx->response_buffer_len = input_len; - - /* Set the response_done flag for transaction state checking in - * TemplateGetStateProgress(). */ - tx->response_done = 1; - -end: - return 0; -} - -static uint64_t TemplateGetTxCnt(void *state) -{ - TemplateState *echo = state; - SCLogNotice("Current tx count is %"PRIu64".", echo->transaction_max); - return echo->transaction_max; -} - -static void *TemplateGetTx(void *state, uint64_t tx_id) -{ - TemplateState *echo = state; - TemplateTransaction *tx; - - SCLogNotice("Requested tx ID %"PRIu64".", tx_id); - - TAILQ_FOREACH(tx, &echo->tx_list, next) { - if (tx->tx_id == tx_id) { - SCLogNotice("Transaction %"PRIu64" found, returning tx object %p.", - tx_id, tx); - return tx; - } - } - - SCLogNotice("Transaction ID %"PRIu64" not found.", tx_id); - return NULL; -} - -/** - * \brief Called by the application layer. - * - * In most cases 1 can be returned here. - */ -static int TemplateGetAlstateProgressCompletionStatus(uint8_t direction) { - return 1; -} - -/** - * \brief Return the state of a transaction in a given direction. - * - * In the case of the echo protocol, the existence of a transaction - * means that the request is done. However, some protocols that may - * need multiple chunks of data to complete the request may need more - * than just the existence of a transaction for the request to be - * considered complete. - * - * For the response to be considered done, the response for a request - * needs to be seen. The response_done flag is set on response for - * checking here. - */ -static int TemplateGetStateProgress(void *tx, uint8_t direction) -{ - TemplateTransaction *echotx = tx; - - SCLogNotice("Transaction progress requested for tx ID %"PRIu64 - ", direction=0x%02x", echotx->tx_id, direction); - - if (direction & STREAM_TOCLIENT && echotx->response_done) { - return 1; - } - else if (direction & STREAM_TOSERVER) { - /* For echo, just the existence of the transaction means the - * request is done. */ - return 1; - } - - return 0; -} - -/** - * \brief ??? - */ -static DetectEngineState *TemplateGetTxDetectState(void *vtx) -{ - TemplateTransaction *tx = vtx; - return tx->de_state; -} - -/** - * \brief ??? - */ -static int TemplateSetTxDetectState(void *state, void *vtx, - DetectEngineState *s) -{ - TemplateTransaction *tx = vtx; - tx->de_state = s; - return 0; -} - -void RegisterTemplateParsers(void) -{ - char *proto_name = "template"; - - /* TEMPLATE_START_REMOVE */ - if (ConfGetNode("app-layer.protocols.template") == NULL) { - return; - } - /* TEMPLATE_END_REMOVE */ - - /* Check if Template TCP detection is enabled. If it does not exist in - * the configuration file then it will be enabled by default. */ - if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", proto_name)) { - - SCLogNotice("Template TCP protocol detection enabled."); - - AppLayerProtoDetectRegisterProtocol(ALPROTO_TEMPLATE, proto_name); - - if (RunmodeIsUnittests()) { - - SCLogNotice("Unittest mode, registeringd default configuration."); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, TEMPLATE_DEFAULT_PORT, - ALPROTO_TEMPLATE, 0, TEMPLATE_MIN_FRAME_LEN, STREAM_TOSERVER, - TemplateProbingParser); - - } - else { - - if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP, - proto_name, ALPROTO_TEMPLATE, 0, TEMPLATE_MIN_FRAME_LEN, - TemplateProbingParser)) { - SCLogNotice("No echo app-layer configuration, enabling echo" - " detection TCP detection on port %s.", - TEMPLATE_DEFAULT_PORT); - AppLayerProtoDetectPPRegister(IPPROTO_TCP, - TEMPLATE_DEFAULT_PORT, ALPROTO_TEMPLATE, 0, - TEMPLATE_MIN_FRAME_LEN, STREAM_TOSERVER, - TemplateProbingParser); - } - - } - - } - - else { - SCLogNotice("Protocol detecter and parser disabled for Template."); - return; - } - - if (AppLayerParserConfParserEnabled("udp", proto_name)) { - - SCLogNotice("Registering Template protocol parser."); - - /* Register functions for state allocation and freeing. A - * state is allocated for every new Template flow. */ - AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_TEMPLATE, - TemplateStateAlloc, TemplateStateFree); - - /* Register request parser for parsing frame from server to client. */ - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEMPLATE, - STREAM_TOSERVER, TemplateParseRequest); - - /* Register response parser for parsing frames from server to client. */ - AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEMPLATE, - STREAM_TOCLIENT, TemplateParseResponse); - - /* Register a function to be called by the application layer - * when a transaction is to be freed. */ - AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_TEMPLATE, - TemplateStateTxFree); - - /* Register a function to return the current transaction count. */ - AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_TEMPLATE, - TemplateGetTxCnt); - - /* Transaction handling. */ - AppLayerParserRegisterGetStateProgressCompletionStatus(IPPROTO_TCP, - ALPROTO_TEMPLATE, TemplateGetAlstateProgressCompletionStatus); - AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, - ALPROTO_TEMPLATE, TemplateGetStateProgress); - AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_TEMPLATE, - TemplateGetTx); - - /* Application layer event handling. */ - AppLayerParserRegisterHasEventsFunc(IPPROTO_TCP, ALPROTO_TEMPLATE, - TemplateHasEvents); - - /* What is this being registered for? */ - AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_TEMPLATE, - NULL, TemplateGetTxDetectState, TemplateSetTxDetectState); - - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_TEMPLATE, - TemplateStateGetEventInfo); - AppLayerParserRegisterGetEventsFunc(IPPROTO_TCP, ALPROTO_TEMPLATE, - TemplateGetEvents); - } - else { - SCLogNotice("Template protocol parsing disabled."); - } - -#ifdef UNITTESTS - AppLayerParserRegisterProtocolUnittests(IPPROTO_TCP, ALPROTO_TEMPLATE, - TemplateParserRegisterTests); -#endif -} - -#ifdef UNITTESTS -#endif - -void TemplateParserRegisterTests(void) -{ -#ifdef UNITTESTS -#endif -} diff --git a/framework/src/suricata/src/app-layer-template.h b/framework/src/suricata/src/app-layer-template.h deleted file mode 100644 index 4e58fa89..00000000 --- a/framework/src/suricata/src/app-layer-template.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __APP_LAYER_TEMPLATE_H__ -#define __APP_LAYER_TEMPLATE_H__ - -#include "detect-engine-state.h" - -#include "queue.h" - -void RegisterTemplateParsers(void); -void TemplateParserRegisterTests(void); - -typedef struct TemplateTransaction_ { - - uint64_t tx_id; /*<< Internal transaction ID. */ - - AppLayerDecoderEvents *decoder_events; /*<< Application layer - * events that occurred - * while parsing this - * transaction. */ - - uint8_t *request_buffer; - uint32_t request_buffer_len; - - uint8_t *response_buffer; - uint32_t response_buffer_len; - - uint8_t response_done; /*<< Flag to be set when the response is - * seen. */ - - DetectEngineState *de_state; - - TAILQ_ENTRY(TemplateTransaction_) next; - -} TemplateTransaction; - -typedef struct TemplateState_ { - - TAILQ_HEAD(, TemplateTransaction_) tx_list; /**< List of Template transactions - * associated with this - * state. */ - - uint64_t transaction_max; /**< A count of the number of - * transactions created. The - * transaction ID for each transaction - * is allocted by incrementing this - * value. */ - - uint16_t events; /**< Number of application layer events created - * for this state. */ - -} TemplateState; - -#endif /* __APP_LAYER_TEMPLATE_H__ */ diff --git a/framework/src/suricata/src/app-layer-tls-handshake.c b/framework/src/suricata/src/app-layer-tls-handshake.c deleted file mode 100644 index ca2e7f49..00000000 --- a/framework/src/suricata/src/app-layer-tls-handshake.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2011-2012 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - * \brief Decode TLS Handshake messages, as described in RFC2246 - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "app-layer-parser.h" -#include "decode-events.h" - -#include "app-layer-ssl.h" - -#include "app-layer-tls-handshake.h" - -#include - -#include "util-decode-der.h" -#include "util-decode-der-get.h" - -#include "util-crypt.h" - -#define SSLV3_RECORD_LEN 5 - -static void TLSCertificateErrCodeToWarning(SSLState *ssl_state, uint32_t errcode) -{ - if (errcode == 0) - return; - - switch (errcode) { - case ERR_DER_ELEMENT_SIZE_TOO_BIG: - case ERR_DER_INVALID_SIZE: - AppLayerDecoderEventsSetEvent(ssl_state->f, - TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH); - break; - case ERR_DER_UNSUPPORTED_STRING: - AppLayerDecoderEventsSetEvent(ssl_state->f, - TLS_DECODER_EVENT_CERTIFICATE_INVALID_STRING); - break; - case ERR_DER_UNKNOWN_ELEMENT: - AppLayerDecoderEventsSetEvent(ssl_state->f, - TLS_DECODER_EVENT_CERTIFICATE_UNKNOWN_ELEMENT); - break; - case ERR_DER_MISSING_ELEMENT: - AppLayerDecoderEventsSetEvent(ssl_state->f, - TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT); - break; - case ERR_DER_GENERIC: - default: - AppLayerDecoderEventsSetEvent(ssl_state->f, - TLS_DECODER_EVENT_INVALID_CERTIFICATE); - break; - }; -} - -int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uint32_t input_len) -{ - uint32_t certificates_length, cur_cert_length; - int i; - Asn1Generic *cert; - char buffer[256]; - int rc; - int parsed; - uint8_t *start_data; - uint32_t errcode = 0; - - if (input_len < 3) - return 1; - - certificates_length = input[0]<<16 | input[1]<<8 | input[2]; - /* check if the message is complete */ - if (input_len < certificates_length + 3) - return 0; - - start_data = input; - input += 3; - parsed = 3; - - i = 0; - while (certificates_length > 0) { - cur_cert_length = input[0]<<16 | input[1]<<8 | input[2]; - input += 3; - parsed += 3; - - if (input - start_data + cur_cert_length > input_len) { - AppLayerDecoderEventsSetEvent(ssl_state->f, TLS_DECODER_EVENT_INVALID_CERTIFICATE); - return -1; - } - cert = DecodeDer(input, cur_cert_length, &errcode); - if (cert == NULL) { - TLSCertificateErrCodeToWarning(ssl_state, errcode); - } - if (cert != NULL) { - rc = Asn1DerGetSubjectDN(cert, buffer, sizeof(buffer), &errcode); - if (rc != 0) { - TLSCertificateErrCodeToWarning(ssl_state, errcode); - } else { - SSLCertsChain *ncert; - //SCLogInfo("TLS Cert %d: %s\n", i, buffer); - if (i == 0) { - if (ssl_state->server_connp.cert0_subject == NULL) - ssl_state->server_connp.cert0_subject = SCStrdup(buffer); - if (ssl_state->server_connp.cert0_subject == NULL) { - DerFree(cert); - return -1; - } - } - ncert = (SSLCertsChain *)SCMalloc(sizeof(SSLCertsChain)); - if (ncert == NULL) { - DerFree(cert); - return -1; - } - memset(ncert, 0, sizeof(*ncert)); - ncert->cert_data = input; - ncert->cert_len = cur_cert_length; - TAILQ_INSERT_TAIL(&ssl_state->server_connp.certs, ncert, next); - } - rc = Asn1DerGetIssuerDN(cert, buffer, sizeof(buffer), &errcode); - if (rc != 0) { - TLSCertificateErrCodeToWarning(ssl_state, errcode); - } else { - //SCLogInfo("TLS IssuerDN %d: %s\n", i, buffer); - if (i == 0) { - if (ssl_state->server_connp.cert0_issuerdn == NULL) - ssl_state->server_connp.cert0_issuerdn = SCStrdup(buffer); - if (ssl_state->server_connp.cert0_issuerdn == NULL) { - DerFree(cert); - return -1; - } - } - } - DerFree(cert); - - if (i == 0 && ssl_state->server_connp.cert0_fingerprint == NULL) { - int msg_len = cur_cert_length; - int hash_len = 20; - int out_len = 60; - char out[out_len]; - unsigned char *hash; - hash = ComputeSHA1((unsigned char *) input, (int) msg_len); - char *p = out; - int j = 0; - - if (hash == NULL) { - SCLogWarning(SC_ERR_MEM_ALLOC, "Can not allocate fingerprint string"); - } else { - for (j = 0; j < hash_len; j++, p += 3) { - snprintf(p, 4, j == hash_len - 1 ? "%02x" : "%02x:", hash[j]); - } - SCFree(hash); - ssl_state->server_connp.cert0_fingerprint = SCStrdup(out); - if (ssl_state->server_connp.cert0_fingerprint == NULL) { - SCLogWarning(SC_ERR_MEM_ALLOC, "Can not allocate fingerprint string"); - } - } - - ssl_state->server_connp.cert_input = input; - ssl_state->server_connp.cert_input_len = cur_cert_length; - } - - } - - i++; - certificates_length -= (cur_cert_length + 3); - parsed += cur_cert_length; - input += cur_cert_length; - } - - return parsed; - -} - diff --git a/framework/src/suricata/src/app-layer-tls-handshake.h b/framework/src/suricata/src/app-layer-tls-handshake.h deleted file mode 100644 index 6041f7fb..00000000 --- a/framework/src/suricata/src/app-layer-tls-handshake.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2011-2012 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - */ - -#ifndef __APP_LAYER_TLS_HANDSHAKE_H__ -#define __APP_LAYER_TLS_HANDSHAKE_H__ - -int DecodeTLSHandshakeServerCertificate(SSLState *ssl_state, uint8_t *input, uint32_t input_len); - -#endif /* __APP_LAYER_TLS_HANDSHAKE_H__ */ diff --git a/framework/src/suricata/src/app-layer.c b/framework/src/suricata/src/app-layer.c deleted file mode 100644 index 96fa252c..00000000 --- a/framework/src/suricata/src/app-layer.c +++ /dev/null @@ -1,3521 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * Generic App-layer functions - */ - -#include "suricata-common.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-protos.h" -#include "app-layer-detect-proto.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp-private.h" -#include "stream-tcp-inline.h" -#include "flow.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-print.h" -#include "util-profiling.h" -#include "util-validate.h" -#include "decode-events.h" - -#include "app-layer-htp-mem.h" -#include "app-layer-dns-common.h" - -/** - * \brief This is for the app layer in general and it contains per thread - * context relevant to both the alpd and alp. - */ -struct AppLayerThreadCtx_ { - /* App layer protocol detection thread context, from AppLayerProtoDetectGetCtxThread(). */ - AppLayerProtoDetectThreadCtx *alpd_tctx; - /* App layer parser thread context, from AppLayerParserThreadCtxAlloc(). */ - AppLayerParserThreadCtx *alp_tctx; - -#ifdef PROFILING - uint64_t ticks_start; - uint64_t ticks_end; - uint64_t ticks_spent; - AppProto alproto; - uint64_t proto_detect_ticks_start; - uint64_t proto_detect_ticks_end; - uint64_t proto_detect_ticks_spent; -#endif -}; - -/***** L7 layer dispatchers *****/ - -static void DisableAppLayer(Flow *f) -{ - SCLogDebug("disable app layer for flow %p", f); - StreamTcpDisableAppLayer(f); -} - -static inline int ProtoDetectDone(const Flow *f, const TcpSession *ssn, uint8_t direction) { - const TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server; - return ((stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) || - (FLOW_IS_PM_DONE(f, direction) && FLOW_IS_PP_DONE(f, direction))); -} - -int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - Packet *p, Flow *f, - TcpSession *ssn, TcpStream *stream, - uint8_t *data, uint32_t data_len, - uint8_t flags) -{ - SCEnter(); - - DEBUG_ASSERT_FLOW_LOCKED(f); - - AppLayerThreadCtx *app_tctx = ra_ctx->app_tctx; - AppProto *alproto; - AppProto *alproto_otherdir; - uint8_t dir; - uint32_t data_al_so_far; - int r = 0; - uint8_t first_data_dir; - - SCLogDebug("data_len %u flags %02X", data_len, flags); - if (ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) { - SCLogDebug("STREAMTCP_FLAG_APP_LAYER_DISABLED is set"); - goto end; - } - - if (flags & STREAM_TOSERVER) { - alproto = &f->alproto_ts; - alproto_otherdir = &f->alproto_tc; - dir = 0; - } else { - alproto = &f->alproto_tc; - alproto_otherdir = &f->alproto_ts; - dir = 1; - } - - /* if we don't know the proto yet and we have received a stream - * initializer message, we run proto detection. - * We receive 2 stream init msgs (one for each direction) but we - * only run the proto detection once. */ - if (*alproto == ALPROTO_UNKNOWN && (flags & STREAM_GAP)) { - StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream); - StreamTcpSetSessionNoReassemblyFlag(ssn, dir); - SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f); - } else if (*alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) { - if (data_len == 0) - data_al_so_far = 0; - else - data_al_so_far = f->data_al_so_far[dir]; - - SCLogDebug("Stream initializer (len %" PRIu32 ")", data_len); -#ifdef PRINT - if (data_len > 0) { - printf("=> Init Stream Data (app layer) -- start %s%s\n", - flags & STREAM_TOCLIENT ? "toclient" : "", - flags & STREAM_TOSERVER ? "toserver" : ""); - PrintRawDataFp(stdout, data, data_len); - printf("=> Init Stream Data -- end\n"); - } -#endif - - PACKET_PROFILING_APP_PD_START(app_tctx); - *alproto = AppLayerProtoDetectGetProto(app_tctx->alpd_tctx, - f, - data, data_len, - IPPROTO_TCP, flags); - PACKET_PROFILING_APP_PD_END(app_tctx); - - if (*alproto != ALPROTO_UNKNOWN) { - if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) { - AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, - APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS); - /* it indicates some data has already been sent to the parser */ - if (ssn->data_first_seen_dir == APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - f->alproto = *alproto = *alproto_otherdir; - } else { - if (flags & STREAM_TOCLIENT) - f->alproto = *alproto_otherdir = *alproto; - else - f->alproto = *alproto = *alproto_otherdir; - } - } - - f->alproto = *alproto; - StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream); - - /* if we have seen data from the other direction first, send - * data for that direction first to the parser. This shouldn't - * be an issue, since each stream processing happens - * independently of the other stream direction. At this point of - * call, you need to know that this function's already being - * called by the very same StreamReassembly() function that we - * will now call shortly for the opposing direction. */ - if ((ssn->data_first_seen_dir & (STREAM_TOSERVER | STREAM_TOCLIENT)) && - !(flags & ssn->data_first_seen_dir)) { - TcpStream *opposing_stream = NULL; - if (stream == &ssn->client) { - opposing_stream = &ssn->server; - if (StreamTcpInlineMode()) { - p->flowflags &= ~FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - } else { - p->flowflags &= ~FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - } - } else { - opposing_stream = &ssn->client; - if (StreamTcpInlineMode()) { - p->flowflags &= ~FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - } else { - p->flowflags &= ~FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - } - } - - int ret = 0; - /* if the opposing side is not going to work, then - * we just have to give up. */ - if (opposing_stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) - ret = -1; - else - ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn, - opposing_stream, p); - if (stream == &ssn->client) { - if (StreamTcpInlineMode()) { - p->flowflags &= ~FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - } else { - p->flowflags &= ~FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - } - } else { - if (StreamTcpInlineMode()) { - p->flowflags &= ~FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - } else { - p->flowflags &= ~FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - } - } - if (ret < 0) { - DisableAppLayer(f); - goto failure; - } - } - - /* if the parser operates such that it needs to see data from - * a particular direction first, we check if we have seen - * data from that direction first for the flow. IF it is not - * the same, we set an event and exit. - * - * \todo We need to figure out a more robust solution for this, - * as this can lead to easy evasion tactics, where the - * attackeer can first send some dummy data in the wrong - * direction first to mislead our proto detection process. - * While doing this we need to update the parsers as well, - * since the parsers must be robust to see such wrong - * direction data. - * Either ways the moment we see the - * APPLAYER_WRONG_DIRECTION_FIRST_DATA event set for the - * flow, it shows something's fishy. - */ - if (ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto); - - if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) { - AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, - APPLAYER_WRONG_DIRECTION_FIRST_DATA); - DisableAppLayer(f); - /* Set a value that is neither STREAM_TOSERVER, nor STREAM_TOCLIENT */ - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - goto failure; - } - /* This can happen if the current direction is not the - * right direction, and the data from the other(also - * the right direction) direction is available to be sent - * to the app layer, but it is not ack'ed yet and hence - * the forced call to STreamTcpAppLayerReassemble still - * hasn't managed to send data from the other direction - * to the app layer. */ - if (first_data_dir && !(first_data_dir & flags)) { - BUG_ON(*alproto_otherdir != ALPROTO_UNKNOWN); - FlowCleanupAppLayer(f); - f->alproto = *alproto = ALPROTO_UNKNOWN; - StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream); - FLOW_RESET_PP_DONE(f, flags); - FLOW_RESET_PM_DONE(f, flags); - goto failure; - } - } - - /* Set a value that is neither STREAM_TOSERVER, nor STREAM_TOCLIENT */ - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - - PACKET_PROFILING_APP_START(app_tctx, *alproto); - r = AppLayerParserParse(app_tctx->alp_tctx, f, *alproto, flags, data + data_al_so_far, data_len - data_al_so_far); - PACKET_PROFILING_APP_END(app_tctx, *alproto); - f->data_al_so_far[dir] = 0; - } else { - /* if the ssn is midstream, we may end up with a case where the - * start of an HTTP request is missing. We won't detect HTTP based - * on the request. However, the reply is fine, so we detect - * HTTP anyway. This leads to passing the incomplete request to - * the htp parser. - * - * This has been observed, where the http parser then saw many - * bogus requests in the incomplete data. - * - * To counter this case, a midstream session MUST find it's - * protocol in the toserver direction. If not, we assume the - * start of the request/toserver is incomplete and no reliable - * detection and parsing is possible. So we give up. - */ - if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) && !(ssn->flags & STREAMTCP_FLAG_MIDSTREAM_SYNACK)) { - if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) { - SCLogDebug("midstream end pd %p", ssn); - /* midstream and toserver detection failed: give up */ - DisableAppLayer(f); - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - goto end; - } - } - - if (*alproto_otherdir != ALPROTO_UNKNOWN) { - first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto_otherdir); - - /* this would handle this test case - - * http parser which says it wants to see toserver data first only. - * tcp handshake - * toclient data first received. - RUBBISH DATA which - * we don't detect as http - * toserver data next sent - we detect this as http. - * at this stage we see that toclient is the first data seen - * for this session and we try and redetect the app protocol, - * but we are unable to detect the app protocol like before. - * But since we have managed to detect the protocol for the - * other direction as http, we try to use that. At this - * stage we check if the direction of this stream matches - * to that acceptable by the app parser. If it is not the - * acceptable direction we error out. - */ - if ((ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) && - (first_data_dir) && !(first_data_dir & flags)) - { - DisableAppLayer(f); - goto failure; - } - - if (data_len > 0) - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - - PACKET_PROFILING_APP_START(app_tctx, *alproto_otherdir); - r = AppLayerParserParse(app_tctx->alp_tctx, f, *alproto_otherdir, flags, - data + data_al_so_far, data_len - data_al_so_far); - PACKET_PROFILING_APP_END(app_tctx, *alproto_otherdir); - if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) { - AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, - APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION); - StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream); - f->data_al_so_far[dir] = 0; - } else { - f->data_al_so_far[dir] = data_len; - } - } else { - /* See if we're going to have to give up: - * - * If we're getting a lot of data in one direction and the - * proto for this direction is unknown, proto detect will - * hold up segments in the segment list in the stream. - * They are held so that if we detect the protocol on the - * opposing stream, we can still parse this side of the stream - * as well. However, some sessions are very unbalanced. FTP - * data channels, large PUT/POST request and many others, can - * lead to cases where we would have to store many megabytes - * worth of segments before we see the opposing stream. This - * leads to risks of resource starvation. - * - * Here a cutoff point is enforced. If we've stored 100k in - * one direction and we've seen no data in the other direction, - * we give up. */ - uint32_t size_ts = ssn->client.last_ack - ssn->client.isn - 1; - uint32_t size_tc = ssn->server.last_ack - ssn->server.isn - 1; - SCLogDebug("size_ts %u, size_tc %u", size_ts, size_tc); -#ifdef DEBUG_VALIDATION - if (!(ssn->client.flags & STREAMTCP_STREAM_FLAG_GAP)) - BUG_ON(size_ts > 1000000UL); - if (!(ssn->server.flags & STREAMTCP_STREAM_FLAG_GAP)) - BUG_ON(size_tc > 1000000UL); -#endif /* DEBUG_VALIDATION */ - - if (ProtoDetectDone(f, ssn, STREAM_TOSERVER) && - ProtoDetectDone(f, ssn, STREAM_TOCLIENT)) - { - DisableAppLayer(f); - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - - } else if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) && - size_ts > 100000 && size_tc == 0) - { - DisableAppLayer(f); - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, - APPLAYER_PROTO_DETECTION_SKIPPED); - } else if (FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) && - size_tc > 100000 && size_ts == 0) - { - DisableAppLayer(f); - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, - APPLAYER_PROTO_DETECTION_SKIPPED); - /* little data in ts direction, pp done, pm not done (max - * depth not reached), ts direction done, lots of data in - * tc direction. */ - } else if (size_tc > 100000 && - FLOW_IS_PP_DONE(f, STREAM_TOSERVER) && !(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && - FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT)) - { - DisableAppLayer(f); - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, - APPLAYER_PROTO_DETECTION_SKIPPED); - /* little data in tc direction, pp done, pm not done (max - * depth not reached), tc direction done, lots of data in - * ts direction. */ - } else if (size_ts > 100000 && - FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) && !(FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && - FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) - { - DisableAppLayer(f); - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, - APPLAYER_PROTO_DETECTION_SKIPPED); - /* in case of really low TS data (e.g. 4 bytes) we can have - * the PP complete, PM not complete (depth not reached) and - * the TC side also not recognized (proto unknown) */ - } else if (size_tc > 100000 && - FLOW_IS_PP_DONE(f, STREAM_TOSERVER) && !(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && - (!FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && !FLOW_IS_PP_DONE(f, STREAM_TOCLIENT))) - { - DisableAppLayer(f); - ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; - AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, - APPLAYER_PROTO_DETECTION_SKIPPED); - } - } - } - } else { - SCLogDebug("stream data (len %" PRIu32 " alproto " - "%"PRIu16" (flow %p)", data_len, f->alproto, f); -#ifdef PRINT - if (data_len > 0) { - printf("=> Stream Data (app layer) -- start %s%s\n", - flags & STREAM_TOCLIENT ? "toclient" : "", - flags & STREAM_TOSERVER ? "toserver" : ""); - PrintRawDataFp(stdout, data, data_len); - printf("=> Stream Data -- end\n"); - } -#endif - /* if we don't have a data object here we are not getting it - * a start msg should have gotten us one */ - if (f->alproto != ALPROTO_UNKNOWN) { - PACKET_PROFILING_APP_START(app_tctx, f->alproto); - r = AppLayerParserParse(app_tctx->alp_tctx, f, f->alproto, flags, data, data_len); - PACKET_PROFILING_APP_END(app_tctx, f->alproto); - } else { - SCLogDebug(" smsg not start, but no l7 data? Weird"); - } - } - - goto end; - failure: - r = -1; - end: - SCReturnInt(r); -} - -/** - * \brief Handle a app layer UDP message - * - * If the protocol is yet unknown, the proto detection code is run first. - * - * \param dp_ctx Thread app layer detect context - * \param f unlocked flow - * \param p UDP packet - * - * \retval 0 ok - * \retval -1 error - */ -int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f) -{ - SCEnter(); - - int r = 0; - - FLOWLOCK_WRLOCK(f); - - uint8_t flags = 0; - if (p->flowflags & FLOW_PKT_TOSERVER) { - flags |= STREAM_TOSERVER; - } else { - flags |= STREAM_TOCLIENT; - } - - /* if we don't know the proto yet and we have received a stream - * initializer message, we run proto detection. - * We receive 2 stream init msgs (one for each direction) but we - * only run the proto detection once. */ - if (f->alproto == ALPROTO_UNKNOWN && !(f->flags & FLOW_ALPROTO_DETECT_DONE)) { - SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")", - p->payload_len); - - PACKET_PROFILING_APP_PD_START(tctx); - f->alproto = AppLayerProtoDetectGetProto(tctx->alpd_tctx, - f, - p->payload, p->payload_len, - IPPROTO_UDP, flags); - PACKET_PROFILING_APP_PD_END(tctx); - - if (f->alproto != ALPROTO_UNKNOWN) { - f->flags |= FLOW_ALPROTO_DETECT_DONE; - - PACKET_PROFILING_APP_START(tctx, f->alproto); - r = AppLayerParserParse(tctx->alp_tctx, - f, f->alproto, flags, - p->payload, p->payload_len); - PACKET_PROFILING_APP_END(tctx, f->alproto); - } else { - f->flags |= FLOW_ALPROTO_DETECT_DONE; - SCLogDebug("ALPROTO_UNKNOWN flow %p", f); - } - } else { - SCLogDebug("stream data (len %" PRIu32 " ), alproto " - "%"PRIu16" (flow %p)", p->payload_len, f->alproto, f); - - /* if we don't have a data object here we are not getting it - * a start msg should have gotten us one */ - if (f->alproto != ALPROTO_UNKNOWN) { - PACKET_PROFILING_APP_START(tctx, f->alproto); - r = AppLayerParserParse(tctx->alp_tctx, - f, f->alproto, flags, - p->payload, p->payload_len); - PACKET_PROFILING_APP_END(tctx, f->alproto); - } else { - SCLogDebug("udp session has started, but failed to detect alproto " - "for l7"); - } - } - - FLOWLOCK_UNLOCK(f); - PACKET_PROFILING_APP_STORE(tctx, p); - - SCReturnInt(r); -} - -/***** Utility *****/ - -AppProto AppLayerGetProtoByName(char *alproto_name) -{ - SCEnter(); - AppProto r = AppLayerProtoDetectGetProtoByName(alproto_name); - SCReturnCT(r, "AppProto"); -} - -char *AppLayerGetProtoName(AppProto alproto) -{ - SCEnter(); - char * r = AppLayerProtoDetectGetProtoName(alproto); - SCReturnCT(r, "char *"); -} - -void AppLayerListSupportedProtocols(void) -{ - SCEnter(); - - AppProto alproto; - AppProto alprotos[ALPROTO_MAX]; - - AppLayerProtoDetectSupportedAppProtocols(alprotos); - - printf("=========Supported App Layer Protocols=========\n"); - for (alproto = 0; alproto < ALPROTO_MAX; alproto++) { - if (alprotos[alproto] == 1) - printf("%s\n", AppLayerGetProtoName(alproto)); - } - - SCReturn; -} - -/***** Setup/General Registration *****/ - -int AppLayerSetup(void) -{ - SCEnter(); - - AppLayerProtoDetectSetup(); - AppLayerParserSetup(); - - AppLayerParserRegisterProtocolParsers(); - AppLayerProtoDetectPrepareState(); - - SCReturnInt(0); -} - -int AppLayerDeSetup(void) -{ - SCEnter(); - - AppLayerProtoDetectDeSetup(); - AppLayerParserDeSetup(); - - SCReturnInt(0); -} - -AppLayerThreadCtx *AppLayerGetCtxThread(ThreadVars *tv) -{ - SCEnter(); - - AppLayerThreadCtx *app_tctx = SCMalloc(sizeof(*app_tctx)); - if (app_tctx == NULL) - goto error; - memset(app_tctx, 0, sizeof(*app_tctx)); - - if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL) - goto error; - if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL) - goto error; - - goto done; - error: - AppLayerDestroyCtxThread(app_tctx); - app_tctx = NULL; - done: - SCReturnPtr(app_tctx, "void *"); -} - -void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx) -{ - SCEnter(); - - if (app_tctx == NULL) - SCReturn; - - if (app_tctx->alpd_tctx != NULL) - AppLayerProtoDetectDestroyCtxThread(app_tctx->alpd_tctx); - if (app_tctx->alp_tctx != NULL) - AppLayerParserThreadCtxFree(app_tctx->alp_tctx); - SCFree(app_tctx); - - SCReturn; -} - -void AppLayerProfilingResetInternal(AppLayerThreadCtx *app_tctx) -{ - PACKET_PROFILING_APP_RESET(app_tctx); -} - -void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p) -{ - PACKET_PROFILING_APP_STORE(app_tctx, p); -} - -/** \brief HACK to work around our broken unix manager (re)init loop - */ -void AppLayerRegisterGlobalCounters(void) -{ - StatsRegisterGlobalCounter("dns.memuse", DNSMemcapGetMemuseCounter); - StatsRegisterGlobalCounter("dns.memcap_state", DNSMemcapGetMemcapStateCounter); - StatsRegisterGlobalCounter("dns.memcap_global", DNSMemcapGetMemcapGlobalCounter); - StatsRegisterGlobalCounter("http.memuse", HTPMemuseGlobalCounter); - StatsRegisterGlobalCounter("http.memcap", HTPMemcapGlobalCounter); -} - -/***** Unittests *****/ - -#ifdef UNITTESTS - -#include "stream-tcp.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp-inline.h" -#include "stream-tcp-util.h" -#include "stream.h" -#include "util-unittest.h" - -/** - * \test GET -> HTTP/1.1 - */ -static int AppLayerTest01(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - /* handshake */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* full request */ - uint8_t request[] = { - 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, - 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, - 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, - 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request); - p->payload = request; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* full response - request ack */ - uint8_t response[] = { - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 5\n"); - goto end; - } - - /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 6\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test GE -> T -> HTTP/1.1 - */ -static int AppLayerTest02(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - /* handshake */ - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* partial request */ - uint8_t request1[] = { 0x47, 0x45, }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request1); - p->payload = request1; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* response ack against partial request */ - p->tcph->th_ack = htonl(3); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 5\n"); - goto end; - } - - /* complete partial request */ - uint8_t request2[] = { - 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, - 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, - 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, - 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(3); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request2); - p->payload = request2; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 6\n"); - goto end; - } - - /* response - request ack */ - uint8_t response[] = { - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 7\n"); - goto end; - } - - /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 8\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test GET -> RUBBISH(PM AND PP DONE IN ONE GO) - */ -static int AppLayerTest03(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - /* handshake */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* request */ - uint8_t request[] = { - 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, - 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, - 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, - 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request); - p->payload = request; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* rubbish response */ - uint8_t response[] = { - 0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 5\n"); - goto end; - } - - /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 6\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE). - */ -static int AppLayerTest04(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - /* handshake */ - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* request */ - uint8_t request[] = { - 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, - 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, - 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, - 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request); - p->payload = request; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* partial response */ - uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response1); - p->payload = response1; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 5\n"); - goto end; - } - - /* partial response ack */ - p->tcph->th_ack = htonl(5); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 4 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 6\n"); - goto end; - } - - /* remaining response */ - uint8_t response2[] = { - 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(5); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response2); - p->payload = response2; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 4 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 7\n"); - goto end; - } - - /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 8\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test RUBBISH -> HTTP/1.1 - */ -static int AppLayerTest05(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - /* handshake */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* full request */ - uint8_t request[] = { - 0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, - 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, - 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, - 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request); - p->payload = request; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* full response - request ack */ - uint8_t response[] = { - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 5\n"); - goto end; - } - - /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 6\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test HTTP/1.1 -> GET - */ -static int AppLayerTest06(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - /* handshake */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* full response - request ack */ - uint8_t response[] = { - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOCLIENT) { - printf("failure 4\n"); - goto end; - } - - /* full request - response ack*/ - uint8_t request[] = { - 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, - 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, - 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, - 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request); - p->payload = request; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - !(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 5\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test GET -> DCERPC - */ -static int AppLayerTest07(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - /* handshake */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* full request */ - uint8_t request[] = { - 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, - 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, - 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, - 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request); - p->payload = request; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* full response - request ack */ - uint8_t response[] = { - 0x05, 0x00, 0x4d, 0x42, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 5\n"); - goto end; - } - - /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - (ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 6\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test SMB -> HTTP/1.1 - */ -static int AppLayerTest08(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - /* handshake */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* full request */ - uint8_t request[] = { - 0x05, 0x00, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, - 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, - 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, - 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request); - p->payload = request; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* full response - request ack */ - uint8_t response[] = { - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_DCERPC || - f.alproto_ts != ALPROTO_DCERPC || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 5\n"); - goto end; - } - - /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_DCERPC || - f.alproto_ts != ALPROTO_DCERPC || - f.alproto_tc != ALPROTO_DCERPC || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - !(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 6 %04x\n", ssn->flags); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test RUBBISH(TC - PM and PP NOT DONE) -> - * RUBBISH(TC - PM and PP DONE) -> - * RUBBISH(TS - PM and PP DONE) - */ -static int AppLayerTest09(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - /* handshake */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* full request */ - uint8_t request1[] = { - 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request1); - p->payload = request1; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* response - request ack */ - p->tcph->th_ack = htonl(9); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 5\n"); - goto end; - } - - /* full request */ - uint8_t request2[] = { - 0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(9); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request2); - p->payload = request2; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 6\n"); - goto end; - } - - /* full response - request ack */ - uint8_t response[] = { - 0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 7\n"); - goto end; - } - - /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(18); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - !(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 8\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test RUBBISH(TC - PM and PP DONE) -> - * RUBBISH(TS - PM and PP DONE) - */ -static int AppLayerTest10(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - /* handshake */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* full request */ - uint8_t request1[] = { - 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request1); - p->payload = request1; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* response - request ack */ - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 5\n"); - goto end; - } - - /* full response - request ack */ - uint8_t response[] = { - 0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 7\n"); - goto end; - } - - /* response ack */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(18); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - !(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 8\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test RUBBISH(TC - PM and PP DONE) -> - * RUBBISH(TS - PM and PP NOT DONE) -> - * RUBBISH(TS - PM and PP DONE) - */ -static int AppLayerTest11(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - /* handshake */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* full request */ - uint8_t request1[] = { - 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request1); - p->payload = request1; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - /* response - request ack */ - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 5\n"); - goto end; - } - - /* full response - request ack */ - uint8_t response1[] = { - 0x55, 0x74, 0x54, 0x50, }; - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response1); - p->payload = response1; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 6\n"); - goto end; - } - - /* response ack from request */ - p->tcph->th_ack = htonl(5); - p->tcph->th_seq = htonl(18); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 7\n"); - goto end; - } - - uint8_t response2[] = { - 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(18); - p->tcph->th_seq = htonl(5); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response2); - p->payload = response2; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 8\n"); - goto end; - } - - /* response ack from request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(18); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - !(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 9\n"); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; - end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -void AppLayerUnittestsRegister(void) -{ - SCEnter(); - - UtRegisterTest("AppLayerTest01", AppLayerTest01, 1); - UtRegisterTest("AppLayerTest02", AppLayerTest02, 1); - UtRegisterTest("AppLayerTest03", AppLayerTest03, 1); - UtRegisterTest("AppLayerTest04", AppLayerTest04, 1); - UtRegisterTest("AppLayerTest05", AppLayerTest05, 1); - UtRegisterTest("AppLayerTest06", AppLayerTest06, 1); - UtRegisterTest("AppLayerTest07", AppLayerTest07, 1); - UtRegisterTest("AppLayerTest08", AppLayerTest08, 1); - UtRegisterTest("AppLayerTest09", AppLayerTest09, 1); - UtRegisterTest("AppLayerTest10", AppLayerTest10, 1); - UtRegisterTest("AppLayerTest11", AppLayerTest11, 1); - - SCReturn; -} - -#endif /* UNITTESTS */ diff --git a/framework/src/suricata/src/app-layer.h b/framework/src/suricata/src/app-layer.h deleted file mode 100644 index f45afe67..00000000 --- a/framework/src/suricata/src/app-layer.h +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \author Victor Julien - * \author Anoop Saldanha - */ - -#ifndef __APP_LAYER_H__ -#define __APP_LAYER_H__ - -#include "threadvars.h" -#include "decode.h" -#include "flow.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream.h" - -#include "util-profiling.h" - -#define APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER \ - (~STREAM_TOSERVER & ~STREAM_TOCLIENT) - -/***** L7 layer dispatchers *****/ - -/** - * \brief Handles reassembled tcp stream. - */ -int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - Packet *p, Flow *f, - TcpSession *ssn, TcpStream *stream, - uint8_t *data, uint32_t data_len, - uint8_t flags); - -/** - * \brief Handles an udp chunk. - */ -int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *app_tctx, - Packet *p, Flow *f); - -/***** Utility *****/ - -/** - * \brief Given a protocol string, returns the corresponding internal - * protocol id. - * - * \param The internal protocol id. - */ -AppProto AppLayerGetProtoByName(char *alproto_name); - -/** - * \brief Given the internal protocol id, returns a string representation - * of the protocol. - * - * \param alproto The internal protocol id. - * - * \retval String representation of the protocol. - */ -char *AppLayerGetProtoName(AppProto alproto); - -void AppLayerListSupportedProtocols(void); - -/***** Setup/General Registration *****/ - -/** - * \brief Setup the app layer. - * - * Includes protocol detection setup and the protocol parser setup. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int AppLayerSetup(void); - -/** - * \brief De initializes the app layer. - * - * Includes de initializing protocol detection and the protocol parser. - */ -int AppLayerDeSetup(void); - -/** - * \brief Creates a new app layer thread context. - * - * \retval Pointer to the newly create thread context, on success; - * NULL, on failure. - */ -AppLayerThreadCtx *AppLayerGetCtxThread(ThreadVars *tv); - -/** - * \brief Destroys the context created by AppLayeGetCtxThread(). - * - * \param tctx Pointer to the thread context to destroy. - */ -void AppLayerDestroyCtxThread(AppLayerThreadCtx *tctx); - - -/***** Profiling *****/ - -void AppLayerProfilingResetInternal(AppLayerThreadCtx *app_tctx); - -static inline void AppLayerProfilingReset(AppLayerThreadCtx *app_tctx) -{ -#ifdef PROFILING - AppLayerProfilingResetInternal(app_tctx); -#endif -} - -void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p); - -static inline void AppLayerProfilingStore(AppLayerThreadCtx *app_tctx, Packet *p) -{ -#ifdef PROFILING - AppLayerProfilingStoreInternal(app_tctx, p); -#endif -} - -void AppLayerRegisterGlobalCounters(void); - -/***** Unittests *****/ - -#ifdef UNITTESTS -void AppLayerUnittestsRegister(void); -#endif - -#endif diff --git a/framework/src/suricata/src/conf-yaml-loader.c b/framework/src/suricata/src/conf-yaml-loader.c deleted file mode 100644 index 13ec0488..00000000 --- a/framework/src/suricata/src/conf-yaml-loader.c +++ /dev/null @@ -1,949 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited - Jason Ish - * - * YAML configuration loader. - */ - -#include -#include "suricata-common.h" -#include "conf.h" -#include "util-path.h" -#include "util-debug.h" -#include "util-unittest.h" - -#define YAML_VERSION_MAJOR 1 -#define YAML_VERSION_MINOR 1 - -/* Sometimes we'll have to create a node name on the fly (integer - * conversion, etc), so this is a default length to allocate that will - * work most of the time. */ -#define DEFAULT_NAME_LEN 16 - -#define MANGLE_ERRORS_MAX 10 -static int mangle_errors = 0; - -static char *conf_dirname = NULL; - -static int ConfYamlParse(yaml_parser_t *parser, ConfNode *parent, int inseq); - -/* Configuration processing states. */ -enum conf_state { - CONF_KEY = 0, - CONF_VAL, - CONF_INCLUDE, -}; - -/** - * \brief Mangle unsupported characters. - * - * \param string A pointer to an null terminated string. - * - * \retval none - */ -static void -Mangle(char *string) -{ - char *c; - - while ((c = strchr(string, '_'))) - *c = '-'; - - return; -} - -/** - * \brief Set the directory name of the configuration file. - * - * \param filename The configuration filename. - */ -static void -ConfYamlSetConfDirname(const char *filename) -{ - char *ep; - - ep = strrchr(filename, '\\'); - if (ep == NULL) - ep = strrchr(filename, '/'); - - if (ep == NULL) { - conf_dirname = SCStrdup("."); - if (conf_dirname == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, - "ERROR: Failed to allocate memory while loading configuration."); - exit(EXIT_FAILURE); - } - } - else { - conf_dirname = SCStrdup(filename); - if (conf_dirname == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, - "ERROR: Failed to allocate memory while loading configuration."); - exit(EXIT_FAILURE); - } - conf_dirname[ep - filename] = '\0'; - } -} - -/** - * \brief Include a file in the configuration. - * - * \param parent The configuration node the included configuration will be - * placed at. - * \param filename The filename to include. - * - * \retval 0 on success, -1 on failure. - */ -static int -ConfYamlHandleInclude(ConfNode *parent, const char *filename) -{ - yaml_parser_t parser; - char include_filename[PATH_MAX]; - FILE *file; - - if (yaml_parser_initialize(&parser) != 1) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "Failed to initialize YAML parser"); - return -1; - } - - if (PathIsAbsolute(filename)) { - strlcpy(include_filename, filename, sizeof(include_filename)); - } - else { - snprintf(include_filename, sizeof(include_filename), "%s/%s", - conf_dirname, filename); - } - - file = fopen(include_filename, "r"); - if (file == NULL) { - SCLogError(SC_ERR_FOPEN, - "Failed to open configuration include file %s: %s", - include_filename, strerror(errno)); - return -1; - } - - yaml_parser_set_input_file(&parser, file); - - if (ConfYamlParse(&parser, parent, 0) != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, - "Failed to include configuration file %s", filename); - return -1; - } - - yaml_parser_delete(&parser); - fclose(file); - - return 0; -} - -/** - * \brief Parse a YAML layer. - * - * \param parser A pointer to an active yaml_parser_t. - * \param parent The parent configuration node. - * - * \retval 0 on success, -1 on failure. - */ -static int -ConfYamlParse(yaml_parser_t *parser, ConfNode *parent, int inseq) -{ - ConfNode *node = parent; - yaml_event_t event; - int done = 0; - int state = 0; - int seq_idx = 0; - - while (!done) { - if (!yaml_parser_parse(parser, &event)) { - SCLogError(SC_ERR_CONF_YAML_ERROR, - "Failed to parse configuration file at line %" PRIuMAX ": %s\n", - (uintmax_t)parser->problem_mark.line, parser->problem); - return -1; - } - - if (event.type == YAML_DOCUMENT_START_EVENT) { - SCLogDebug("event.type=YAML_DOCUMENT_START_EVENT; state=%d", state); - /* Verify YAML version - its more likely to be a valid - * Suricata configuration file if the version is - * correct. */ - yaml_version_directive_t *ver = - event.data.document_start.version_directive; - if (ver == NULL) { - fprintf(stderr, "ERROR: Invalid configuration file.\n\n"); - fprintf(stderr, "The configuration file must begin with the following two lines:\n\n"); - fprintf(stderr, "%%YAML 1.1\n---\n\n"); - goto fail; - } - int major = event.data.document_start.version_directive->major; - int minor = event.data.document_start.version_directive->minor; - if (!(major == YAML_VERSION_MAJOR && minor == YAML_VERSION_MINOR)) { - fprintf(stderr, "ERROR: Invalid YAML version. Must be 1.1\n"); - goto fail; - } - } - else if (event.type == YAML_SCALAR_EVENT) { - char *value = (char *)event.data.scalar.value; - char *tag = (char *)event.data.scalar.tag; - SCLogDebug("event.type=YAML_SCALAR_EVENT; state=%d; value=%s; " - "tag=%s; inseq=%d", state, value, tag, inseq); - if (inseq) { - char sequence_node_name[DEFAULT_NAME_LEN]; - snprintf(sequence_node_name, DEFAULT_NAME_LEN, "%d", seq_idx++); - ConfNode *seq_node = ConfNodeLookupChild(parent, - sequence_node_name); - if (seq_node != NULL) { - /* The sequence node has already been set, probably - * from the command line. Remove it so it gets - * re-added in the expected order for iteration. - */ - TAILQ_REMOVE(&parent->head, seq_node, next); - } - else { - seq_node = ConfNodeNew(); - if (unlikely(seq_node == NULL)) { - return -1; - } - seq_node->name = SCStrdup(sequence_node_name); - if (unlikely(seq_node->name == NULL)) { - SCFree(seq_node); - return -1; - } - seq_node->val = SCStrdup(value); - if (unlikely(seq_node->val == NULL)) { - SCFree(seq_node->name); - return -1; - } - } - TAILQ_INSERT_TAIL(&parent->head, seq_node, next); - } - else { - if (state == CONF_INCLUDE) { - SCLogInfo("Including configuration file %s.", value); - if (ConfYamlHandleInclude(parent, value) != 0) { - goto fail; - } - state = CONF_KEY; - } - else if (state == CONF_KEY) { - - if (strcmp(value, "include") == 0) { - state = CONF_INCLUDE; - goto next; - } - - if (parent->is_seq) { - if (parent->val == NULL) { - parent->val = SCStrdup(value); - if (parent->val && strchr(parent->val, '_')) - Mangle(parent->val); - } - } - ConfNode *existing = ConfNodeLookupChild(parent, value); - if (existing != NULL) { - if (!existing->final) { - SCLogInfo("Configuration node '%s' redefined.", - existing->name); - ConfNodePrune(existing); - } - node = existing; - } - else { - node = ConfNodeNew(); - node->name = SCStrdup(value); - if (node->name && strchr(node->name, '_')) { - if (!(parent->name && - ((strcmp(parent->name, "address-groups") == 0) || - (strcmp(parent->name, "port-groups") == 0)))) { - Mangle(node->name); - if (mangle_errors < MANGLE_ERRORS_MAX) { - SCLogWarning(SC_WARN_DEPRECATED, - "%s is deprecated. Please use %s on line %"PRIuMAX".", - value, node->name, (uintmax_t)parser->mark.line+1); - mangle_errors++; - if (mangle_errors >= MANGLE_ERRORS_MAX) - SCLogWarning(SC_WARN_DEPRECATED, "not showing more " - "parameter name warnings."); - } - } - } - TAILQ_INSERT_TAIL(&parent->head, node, next); - } - state = CONF_VAL; - } - else { - if ((tag != NULL) && (strcmp(tag, "!include") == 0)) { - SCLogInfo("Including configuration file %s at " - "parent node %s.", value, node->name); - if (ConfYamlHandleInclude(node, value) != 0) - goto fail; - } - else if (!node->final) { - if (node->val != NULL) - SCFree(node->val); - node->val = SCStrdup(value); - } - state = CONF_KEY; - } - } - } - else if (event.type == YAML_SEQUENCE_START_EVENT) { - SCLogDebug("event.type=YAML_SEQUENCE_START_EVENT; state=%d", state); - if (ConfYamlParse(parser, node, 1) != 0) - goto fail; - node->is_seq = 1; - state = CONF_KEY; - } - else if (event.type == YAML_SEQUENCE_END_EVENT) { - SCLogDebug("event.type=YAML_SEQUENCE_END_EVENT; state=%d", state); - return 0; - } - else if (event.type == YAML_MAPPING_START_EVENT) { - SCLogDebug("event.type=YAML_MAPPING_START_EVENT; state=%d", state); - if (inseq) { - char sequence_node_name[DEFAULT_NAME_LEN]; - snprintf(sequence_node_name, DEFAULT_NAME_LEN, "%d", seq_idx++); - ConfNode *seq_node = ConfNodeLookupChild(node, - sequence_node_name); - if (seq_node != NULL) { - /* The sequence node has already been set, probably - * from the command line. Remove it so it gets - * re-added in the expected order for iteration. - */ - TAILQ_REMOVE(&node->head, seq_node, next); - } - else { - seq_node = ConfNodeNew(); - if (unlikely(seq_node == NULL)) { - return -1; - } - seq_node->name = SCStrdup(sequence_node_name); - if (unlikely(seq_node->name == NULL)) { - SCFree(seq_node); - return -1; - } - } - seq_node->is_seq = 1; - TAILQ_INSERT_TAIL(&node->head, seq_node, next); - if (ConfYamlParse(parser, seq_node, 0) != 0) - goto fail; - } - else { - if (ConfYamlParse(parser, node, inseq) != 0) - goto fail; - } - state = CONF_KEY; - } - else if (event.type == YAML_MAPPING_END_EVENT) { - SCLogDebug("event.type=YAML_MAPPING_END_EVENT; state=%d", state); - done = 1; - } - else if (event.type == YAML_STREAM_END_EVENT) { - SCLogDebug("event.type=YAML_STREAM_END_EVENT; state=%d", state); - done = 1; - } - - next: - yaml_event_delete(&event); - continue; - - fail: - yaml_event_delete(&event); - return -1; - } - - return 0; -} - -/** - * \brief Load configuration from a YAML file. - * - * This function will load a configuration file. On failure -1 will - * be returned and it is suggested that the program then exit. Any - * errors while loading the configuration file will have already been - * logged. - * - * \param filename Filename of configuration file to load. - * - * \retval 0 on success, -1 on failure. - */ -int -ConfYamlLoadFile(const char *filename) -{ - FILE *infile; - yaml_parser_t parser; - int ret; - ConfNode *root = ConfGetRootNode(); - - if (yaml_parser_initialize(&parser) != 1) { - SCLogError(SC_ERR_FATAL, "failed to initialize yaml parser."); - return -1; - } - - struct stat stat_buf; - if (stat(filename, &stat_buf) == 0) { - if (stat_buf.st_mode & S_IFDIR) { - SCLogError(SC_ERR_FATAL, "yaml argument is not a file but a directory: %s. " - "Please specify the yaml file in your -c option.", filename); - return -1; - } - } - - infile = fopen(filename, "r"); - if (infile == NULL) { - SCLogError(SC_ERR_FATAL, "failed to open file: %s: %s", filename, - strerror(errno)); - yaml_parser_delete(&parser); - return -1; - } - - if (conf_dirname == NULL) { - ConfYamlSetConfDirname(filename); - } - - yaml_parser_set_input_file(&parser, infile); - ret = ConfYamlParse(&parser, root, 0); - yaml_parser_delete(&parser); - fclose(infile); - - return ret; -} - -/** - * \brief Load configuration from a YAML string. - */ -int -ConfYamlLoadString(const char *string, size_t len) -{ - ConfNode *root = ConfGetRootNode(); - yaml_parser_t parser; - int ret; - - if (yaml_parser_initialize(&parser) != 1) { - fprintf(stderr, "Failed to initialize yaml parser.\n"); - exit(EXIT_FAILURE); - } - yaml_parser_set_input_string(&parser, (const unsigned char *)string, len); - ret = ConfYamlParse(&parser, root, 0); - yaml_parser_delete(&parser); - - return ret; -} - -/** - * \brief Load configuration from a YAML file, insert in tree at 'prefix' - * - * This function will load a configuration file and insert it into the - * config tree at 'prefix'. This means that if this is called with prefix - * "abc" and the file contains a parameter "def", it will be loaded as - * "abc.def". - * - * \param filename Filename of configuration file to load. - * \param prefix Name prefix to use. - * - * \retval 0 on success, -1 on failure. - */ -int -ConfYamlLoadFileWithPrefix(const char *filename, const char *prefix) -{ - FILE *infile; - yaml_parser_t parser; - int ret; - ConfNode *root = ConfGetNode(prefix); - - if (yaml_parser_initialize(&parser) != 1) { - SCLogError(SC_ERR_FATAL, "failed to initialize yaml parser."); - return -1; - } - - struct stat stat_buf; - if (stat(filename, &stat_buf) == 0) { - if (stat_buf.st_mode & S_IFDIR) { - SCLogError(SC_ERR_FATAL, "yaml argument is not a file but a directory: %s. " - "Please specify the yaml file in your -c option.", filename); - return -1; - } - } - - infile = fopen(filename, "r"); - if (infile == NULL) { - SCLogError(SC_ERR_FATAL, "failed to open file: %s: %s", filename, - strerror(errno)); - yaml_parser_delete(&parser); - return -1; - } - - if (conf_dirname == NULL) { - ConfYamlSetConfDirname(filename); - } - - if (root == NULL) { - /* if node at 'prefix' doesn't yet exist, add a place holder */ - ConfSet(prefix, ""); - root = ConfGetNode(prefix); - if (root == NULL) { - fclose(infile); - yaml_parser_delete(&parser); - return -1; - } - } - yaml_parser_set_input_file(&parser, infile); - ret = ConfYamlParse(&parser, root, 0); - yaml_parser_delete(&parser); - fclose(infile); - - return ret; -} - -#ifdef UNITTESTS - -static int -ConfYamlSequenceTest(void) -{ - char input[] = "\ -%YAML 1.1\n\ ----\n\ -rule-files:\n\ - - netbios.rules\n\ - - x11.rules\n\ -\n\ -default-log-dir: /tmp\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - - ConfYamlLoadString(input, strlen(input)); - - ConfNode *node; - node = ConfGetNode("rule-files"); - if (node == NULL) - return 0; - if (!ConfNodeIsSequence(node)) - return 0; - if (TAILQ_EMPTY(&node->head)) - return 0; - int i = 0; - ConfNode *filename; - TAILQ_FOREACH(filename, &node->head, next) { - if (i == 0) { - if (strcmp(filename->val, "netbios.rules") != 0) - return 0; - if (ConfNodeIsSequence(filename)) - return 0; - if (filename->is_seq != 0) - return 0; - } - else if (i == 1) { - if (strcmp(filename->val, "x11.rules") != 0) - return 0; - if (ConfNodeIsSequence(filename)) - return 0; - } - else { - return 0; - } - i++; - } - - ConfDeInit(); - ConfRestoreContextBackup(); - - return 1; -} - -static int -ConfYamlLoggingOutputTest(void) -{ - char input[] = "\ -%YAML 1.1\n\ ----\n\ -logging:\n\ - output:\n\ - - interface: console\n\ - log-level: error\n\ - - interface: syslog\n\ - facility: local4\n\ - log-level: info\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - - ConfYamlLoadString(input, strlen(input)); - - ConfNode *outputs; - outputs = ConfGetNode("logging.output"); - if (outputs == NULL) - return 0; - - ConfNode *output; - ConfNode *output_param; - - output = TAILQ_FIRST(&outputs->head); - if (output == NULL) - return 0; - if (strcmp(output->name, "0") != 0) - return 0; - output_param = TAILQ_FIRST(&output->head); - if (output_param == NULL) - return 0; - if (strcmp(output_param->name, "interface") != 0) - return 0; - if (strcmp(output_param->val, "console") != 0) - return 0; - output_param = TAILQ_NEXT(output_param, next); - if (strcmp(output_param->name, "log-level") != 0) - return 0; - if (strcmp(output_param->val, "error") != 0) - return 0; - - output = TAILQ_NEXT(output, next); - if (output == NULL) - return 0; - if (strcmp(output->name, "1") != 0) - return 0; - output_param = TAILQ_FIRST(&output->head); - if (output_param == NULL) - return 0; - if (strcmp(output_param->name, "interface") != 0) - return 0; - if (strcmp(output_param->val, "syslog") != 0) - return 0; - output_param = TAILQ_NEXT(output_param, next); - if (strcmp(output_param->name, "facility") != 0) - return 0; - if (strcmp(output_param->val, "local4") != 0) - return 0; - output_param = TAILQ_NEXT(output_param, next); - if (strcmp(output_param->name, "log-level") != 0) - return 0; - if (strcmp(output_param->val, "info") != 0) - return 0; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return 1; -} - -/** - * Try to load something that is not a valid YAML file. - */ -static int -ConfYamlNonYamlFileTest(void) -{ - ConfCreateContextBackup(); - ConfInit(); - - if (ConfYamlLoadFile("/etc/passwd") != -1) - return 0; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return 1; -} - -static int -ConfYamlBadYamlVersionTest(void) -{ - char input[] = "\ -%YAML 9.9\n\ ----\n\ -logging:\n\ - output:\n\ - - interface: console\n\ - log-level: error\n\ - - interface: syslog\n\ - facility: local4\n\ - log-level: info\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - - if (ConfYamlLoadString(input, strlen(input)) != -1) - return 0; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return 1; -} - -static int -ConfYamlSecondLevelSequenceTest(void) -{ - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ - server-config:\n\ - - apache-php:\n\ - address: [\"192.168.1.0/24\"]\n\ - personality: [\"Apache_2_2\", \"PHP_5_3\"]\n\ - path-parsing: [\"compress_separators\", \"lowercase\"]\n\ - - iis-php:\n\ - address:\n\ - - 192.168.0.0/24\n\ -\n\ - personality:\n\ - - IIS_7_0\n\ - - PHP_5_3\n\ -\n\ - path-parsing:\n\ - - compress_separators\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - - if (ConfYamlLoadString(input, strlen(input)) != 0) - return 0; - - ConfNode *outputs; - outputs = ConfGetNode("libhtp.server-config"); - if (outputs == NULL) - return 0; - - ConfNode *node; - - node = TAILQ_FIRST(&outputs->head); - if (node == NULL) - return 0; - if (strcmp(node->name, "0") != 0) - return 0; - node = TAILQ_FIRST(&node->head); - if (node == NULL) - return 0; - if (strcmp(node->name, "apache-php") != 0) - return 0; - - node = ConfNodeLookupChild(node, "address"); - if (node == NULL) - return 0; - node = TAILQ_FIRST(&node->head); - if (node == NULL) - return 0; - if (strcmp(node->name, "0") != 0) - return 0; - if (strcmp(node->val, "192.168.1.0/24") != 0) - return 0; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return 1; -} - -/** - * Test file inclusion support. - */ -static int -ConfYamlFileIncludeTest(void) -{ - int ret = 0; - FILE *config_file; - - const char config_filename[] = "ConfYamlFileIncludeTest-config.yaml"; - const char config_file_contents[] = - "%YAML 1.1\n" - "---\n" - "# Include something at the root level.\n" - "include: ConfYamlFileIncludeTest-include.yaml\n" - "# Test including under a mapping.\n" - "mapping: !include ConfYamlFileIncludeTest-include.yaml\n"; - - const char include_filename[] = "ConfYamlFileIncludeTest-include.yaml"; - const char include_file_contents[] = - "%YAML 1.1\n" - "---\n" - "host-mode: auto\n" - "unix-command:\n" - " enabled: no\n"; - - ConfCreateContextBackup(); - ConfInit(); - - /* Write out the test files. */ - if ((config_file = fopen(config_filename, "w")) == NULL) { - goto cleanup; - } - if (fwrite(config_file_contents, strlen(config_file_contents), 1, - config_file) != 1) { - goto cleanup; - } - fclose(config_file); - if ((config_file = fopen(include_filename, "w")) == NULL) { - goto cleanup; - } - if (fwrite(include_file_contents, strlen(include_file_contents), 1, - config_file) != 1) { - goto cleanup; - } - fclose(config_file); - - /* Reset conf_dirname. */ - if (conf_dirname != NULL) { - SCFree(conf_dirname); - conf_dirname = NULL; - } - - if (ConfYamlLoadFile("ConfYamlFileIncludeTest-config.yaml") != 0) - goto cleanup; - - /* Check values that should have been loaded into the root of the - * configuration. */ - ConfNode *node; - node = ConfGetNode("host-mode"); - if (node == NULL) - goto cleanup; - if (strcmp(node->val, "auto") != 0) - goto cleanup; - node = ConfGetNode("unix-command.enabled"); - if (node == NULL) - goto cleanup; - if (strcmp(node->val, "no") != 0) - goto cleanup; - - /* Check for values that were included under a mapping. */ - node = ConfGetNode("mapping.host-mode"); - if (node == NULL) - goto cleanup; - if (strcmp(node->val, "auto") != 0) - goto cleanup; - node = ConfGetNode("mapping.unix-command.enabled"); - if (node == NULL) - goto cleanup; - if (strcmp(node->val, "no") != 0) - goto cleanup; - - ConfDeInit(); - ConfRestoreContextBackup(); - - ret = 1; - -cleanup: - unlink(config_filename); - unlink(include_filename); - - return ret; -} - -/** - * Test that a configuration section is overridden but subsequent - * occurrences. - */ -static int -ConfYamlOverrideTest(void) -{ - char config[] = - "%YAML 1.1\n" - "---\n" - "some-log-dir: /var/log\n" - "some-log-dir: /tmp\n" - "\n" - "parent:\n" - " child0:\n" - " key: value\n" - "parent:\n" - " child1:\n" - " key: value\n" - ; - char *value; - - ConfCreateContextBackup(); - ConfInit(); - - if (ConfYamlLoadString(config, strlen(config)) != 0) - return 0; - if (!ConfGet("some-log-dir", &value)) - return 0; - if (strcmp(value, "/tmp") != 0) - return 0; - - /* Test that parent.child0 does not exist, but child1 does. */ - if (ConfGetNode("parent.child0") != NULL) - return 0; - if (!ConfGet("parent.child1.key", &value)) - return 0; - if (strcmp(value, "value") != 0) - return 0; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return 1; -} - -/** - * Test that a configuration parameter loaded from YAML doesn't - * override a 'final' value that may be set on the command line. - */ -static int -ConfYamlOverrideFinalTest(void) -{ - ConfCreateContextBackup(); - ConfInit(); - - char config[] = - "%YAML 1.1\n" - "---\n" - "default-log-dir: /var/log\n"; - - /* Set the log directory as if it was set on the command line. */ - if (!ConfSetFinal("default-log-dir", "/tmp")) - return 0; - if (ConfYamlLoadString(config, strlen(config)) != 0) - return 0; - - char *default_log_dir; - - if (!ConfGet("default-log-dir", &default_log_dir)) - return 0; - if (strcmp(default_log_dir, "/tmp") != 0) { - fprintf(stderr, "final value was reassigned\n"); - return 0; - } - - ConfDeInit(); - ConfRestoreContextBackup(); - - return 1; -} - -#endif /* UNITTESTS */ - -void -ConfYamlRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("ConfYamlSequenceTest", ConfYamlSequenceTest, 1); - UtRegisterTest("ConfYamlLoggingOutputTest", ConfYamlLoggingOutputTest, 1); - UtRegisterTest("ConfYamlNonYamlFileTest", ConfYamlNonYamlFileTest, 1); - UtRegisterTest("ConfYamlBadYamlVersionTest", ConfYamlBadYamlVersionTest, 1); - UtRegisterTest("ConfYamlSecondLevelSequenceTest", - ConfYamlSecondLevelSequenceTest, 1); - UtRegisterTest("ConfYamlFileIncludeTest", ConfYamlFileIncludeTest, 1); - UtRegisterTest("ConfYamlOverrideTest", ConfYamlOverrideTest, 1); - UtRegisterTest("ConfYamlOverrideFinalTest", ConfYamlOverrideFinalTest, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/conf-yaml-loader.h b/framework/src/suricata/src/conf-yaml-loader.h deleted file mode 100644 index 6c599d0a..00000000 --- a/framework/src/suricata/src/conf-yaml-loader.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited - Jason Ish - */ - -#ifndef __CONF_YAML_LOADER_H__ -#define __CONF_YAML_LOADER_H__ - -int ConfYamlLoadFile(const char *); -int ConfYamlLoadString(const char *, size_t); -int ConfYamlLoadFileWithPrefix(const char *filename, const char *prefix); - -void ConfYamlRegisterTests(void); - -#endif /* !__CONF_YAML_LOADER_H__ */ diff --git a/framework/src/suricata/src/conf.c b/framework/src/suricata/src/conf.c deleted file mode 100644 index 88b9389c..00000000 --- a/framework/src/suricata/src/conf.c +++ /dev/null @@ -1,1532 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited - Jason Ish - * - * This file provides a basic configuration system for the IDPS - * engine. - * - * NOTE: Setting values should only be done from one thread during - * engine initialization. Multiple threads should be able access read - * configuration data. Allowing run time changes to the configuration - * will require some locks. - * - * \todo Consider having the in-memory configuration database a direct - * reflection of the configuration file and moving command line - * parameters to a primary lookup table? - * - * \todo Get rid of allow override and go with a simpler first set, - * stays approach? - */ - -#include "suricata-common.h" -#include "conf.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "util-path.h" - -/** Maximum size of a complete domain name. */ -#define NODE_NAME_MAX 1024 - -static ConfNode *root = NULL; -static ConfNode *root_backup = NULL; - -/** - * \brief Helper function to get a node, creating it if it does not - * exist. - * - * This function exits on memory failure as creating configuration - * nodes is usually part of application initialization. - * - * \param name The name of the configuration node to get. - * \param final Flag to set created nodes as final or not. - * - * \retval The existing configuration node if it exists, or a newly - * created node for the provided name. On error, NULL will be returned. - */ -static ConfNode *ConfGetNodeOrCreate(const char *name, int final) -{ - ConfNode *parent = root; - ConfNode *node = NULL; - char node_name[NODE_NAME_MAX]; - char *key; - char *next; - - if (strlcpy(node_name, name, sizeof(node_name)) >= sizeof(node_name)) { - SCLogError(SC_ERR_CONF_NAME_TOO_LONG, - "Configuration name too long: %s", name); - return NULL; - } - - key = node_name; - - do { - if ((next = strchr(key, '.')) != NULL) - *next++ = '\0'; - if ((node = ConfNodeLookupChild(parent, key)) == NULL) { - node = ConfNodeNew(); - if (unlikely(node == NULL)) { - SCLogWarning(SC_ERR_MEM_ALLOC, - "Failed to allocate memory for configuration."); - goto end; - } - node->name = SCStrdup(key); - if (unlikely(node->name == NULL)) { - ConfNodeFree(node); - node = NULL; - SCLogWarning(SC_ERR_MEM_ALLOC, - "Failed to allocate memory for configuration."); - goto end; - } - node->parent = parent; - node->final = final; - TAILQ_INSERT_TAIL(&parent->head, node, next); - } - key = next; - parent = node; - } while (next != NULL); - -end: - return node; -} - -/** - * \brief Initialize the configuration system. - */ -void ConfInit(void) -{ - if (root != NULL) { - SCLogDebug("already initialized"); - return; - } - root = ConfNodeNew(); - if (root == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, - "ERROR: Failed to allocate memory for root configuration node, " - "aborting."); - exit(EXIT_FAILURE); - } - SCLogDebug("configuration module initialized"); -} - -/** - * \brief Allocate a new configuration node. - * - * \retval An allocated configuration node on success, NULL on failure. - */ -ConfNode *ConfNodeNew(void) -{ - ConfNode *new; - - new = SCCalloc(1, sizeof(*new)); - if (unlikely(new == NULL)) { - return NULL; - } - TAILQ_INIT(&new->head); - - return new; -} - -/** - * \brief Free a ConfNode and all of its children. - * - * \param node The configuration node to SCFree. - */ -void ConfNodeFree(ConfNode *node) -{ - ConfNode *tmp; - - while ((tmp = TAILQ_FIRST(&node->head))) { - TAILQ_REMOVE(&node->head, tmp, next); - ConfNodeFree(tmp); - } - - if (node->name != NULL) - SCFree(node->name); - if (node->val != NULL) - SCFree(node->val); - SCFree(node); -} - -/** - * \brief Get a ConfNode by name. - * - * \param name The full name of the configuration node to lookup. - * - * \retval A pointer to ConfNode is found or NULL if the configuration - * node does not exist. - */ -ConfNode *ConfGetNode(const char *name) -{ - ConfNode *node = root; - char node_name[NODE_NAME_MAX]; - char *key; - char *next; - - if (strlcpy(node_name, name, sizeof(node_name)) >= sizeof(node_name)) { - SCLogError(SC_ERR_CONF_NAME_TOO_LONG, - "Configuration name too long: %s", name); - return NULL; - } - - key = node_name; - do { - if ((next = strchr(key, '.')) != NULL) - *next++ = '\0'; - node = ConfNodeLookupChild(node, key); - key = next; - } while (next != NULL && node != NULL); - - return node; -} - -/** - * \brief Get the root configuration node. - */ -ConfNode *ConfGetRootNode(void) -{ - return root; -} - -/** - * \brief Set a configuration value. - * - * Configuration values set with this function may be overridden by - * subsequent calls, or if the value appears multiple times in a - * configuration file. - * - * \param name The name of the configuration parameter to set. - * \param val The value of the configuration parameter. - * - * \retval 1 if the value was set otherwise 0. - */ -int ConfSet(const char *name, char *val) -{ - ConfNode *node = ConfGetNodeOrCreate(name, 0); - if (node == NULL || node->final) { - return 0; - } - if (node->val != NULL) - SCFree(node->val); - node->val = SCStrdup(val); - if (unlikely(node->val == NULL)) { - return 0; - } - return 1; -} - -/** - * \brief Set a configuration parameter from a string. - * - * Where the input string is something like: - * stream.midstream=true - * - * \param input the input string to be parsed. - * - * \retval 1 if the value of set, otherwise 0. - */ -int ConfSetFromString(const char *input, int final) -{ - int retval = 0; - char *name = SCStrdup(input), *val = NULL; - if (unlikely(name == NULL)) { - goto done; - } - val = strchr(name, '='); - if (val == NULL) { - goto done; - } - *val++ = '\0'; - - while (isspace((int)name[strlen(name) - 1])) { - name[strlen(name) - 1] = '\0'; - } - - while (isspace((int)*val)) { - val++; - } - - if (final) { - if (!ConfSetFinal(name, val)) { - goto done; - } - } - else { - if (!ConfSet(name, val)) { - goto done; - } - } - - retval = 1; -done: - if (name != NULL) { - SCFree(name); - } - return retval; -} - -/** - * \brief Set a final configuration value. - * - * A final configuration value is a value that cannot be overridden by - * the configuration file. Its mainly useful for setting values that - * are supplied on the command line prior to the configuration file - * being loaded. However, a subsequent call to this function can - * override a previously set value. - * - * \param name The name of the configuration parameter to set. - * \param val The value of the configuration parameter. - * - * \retval 1 if the value was set otherwise 0. - */ -int ConfSetFinal(const char *name, char *val) -{ - ConfNode *node = ConfGetNodeOrCreate(name, 1); - if (node == NULL) { - return 0; - } - if (node->val != NULL) - SCFree(node->val); - node->val = SCStrdup(val); - if (unlikely(node->val == NULL)) { - return 0; - } - node->final = 1; - return 1; -} - -/** - * \brief Retrieve the value of a configuration node. - * - * This function will return the value for a configuration node based - * on the full name of the node. It is possible that the value - * returned could be NULL, this could happen if the requested node - * does exist but is not a node that contains a value, but contains - * children ConfNodes instead. - * - * \param name Name of configuration parameter to get. - * \param vptr Pointer that will be set to the configuration value parameter. - * Note that this is just a reference to the actual value, not a copy. - * - * \retval 1 will be returned if the name is found, otherwise 0 will - * be returned. - */ -int ConfGet(const char *name, char **vptr) -{ - ConfNode *node = ConfGetNode(name); - if (node == NULL) { - SCLogDebug("failed to lookup configuration parameter '%s'", name); - return 0; - } - else { - *vptr = node->val; - return 1; - } -} - -int ConfGetChildValue(const ConfNode *base, const char *name, char **vptr) -{ - ConfNode *node = ConfNodeLookupChild(base, name); - - if (node == NULL) { - SCLogDebug("failed to lookup configuration parameter '%s'", name); - return 0; - } - else { - *vptr = node->val; - return 1; - } -} - - -int ConfGetChildValueWithDefault(const ConfNode *base, const ConfNode *dflt, - const char *name, char **vptr) -{ - int ret = ConfGetChildValue(base, name, vptr); - /* Get 'default' value */ - if (ret == 0 && dflt) { - return ConfGetChildValue(dflt, name, vptr); - } - return ret; -} - -/** - * \brief Retrieve a configuration value as an integer. - * - * \param name Name of configuration parameter to get. - * \param val Pointer to an intmax_t that will be set the - * configuration value. - * - * \retval 1 will be returned if the name is found and was properly - * converted to an interger, otherwise 0 will be returned. - */ -int ConfGetInt(const char *name, intmax_t *val) -{ - char *strval; - intmax_t tmpint; - char *endptr; - - if (ConfGet(name, &strval) == 0) - return 0; - - errno = 0; - tmpint = strtoimax(strval, &endptr, 0); - if (strval[0] == '\0' || *endptr != '\0') - return 0; - if (errno == ERANGE && (tmpint == INTMAX_MAX || tmpint == INTMAX_MIN)) - return 0; - - *val = tmpint; - return 1; -} - -int ConfGetChildValueInt(const ConfNode *base, const char *name, intmax_t *val) -{ - char *strval; - intmax_t tmpint; - char *endptr; - - if (ConfGetChildValue(base, name, &strval) == 0) - return 0; - errno = 0; - tmpint = strtoimax(strval, &endptr, 0); - if (strval[0] == '\0' || *endptr != '\0') - return 0; - if (errno == ERANGE && (tmpint == INTMAX_MAX || tmpint == INTMAX_MIN)) - return 0; - - *val = tmpint; - return 1; - -} - -int ConfGetChildValueIntWithDefault(const ConfNode *base, const ConfNode *dflt, - const char *name, intmax_t *val) -{ - int ret = ConfGetChildValueInt(base, name, val); - /* Get 'default' value */ - if (ret == 0 && dflt) { - return ConfGetChildValueInt(dflt, name, val); - } - return ret; -} - - -/** - * \brief Retrieve a configuration value as an boolen. - * - * \param name Name of configuration parameter to get. - * \param val Pointer to an int that will be set to 1 for true, or 0 - * for false. - * - * \retval 1 will be returned if the name is found and was properly - * converted to a boolean, otherwise 0 will be returned. - */ -int ConfGetBool(const char *name, int *val) -{ - char *strval; - - *val = 0; - if (ConfGet(name, &strval) != 1) - return 0; - - *val = ConfValIsTrue(strval); - - return 1; -} - -int ConfGetChildValueBool(const ConfNode *base, const char *name, int *val) -{ - char *strval; - - *val = 0; - if (ConfGetChildValue(base, name, &strval) == 0) - return 0; - - *val = ConfValIsTrue(strval); - - return 1; -} - -int ConfGetChildValueBoolWithDefault(const ConfNode *base, const ConfNode *dflt, - const char *name, int *val) -{ - int ret = ConfGetChildValueBool(base, name, val); - /* Get 'default' value */ - if (ret == 0 && dflt) { - return ConfGetChildValueBool(dflt, name, val); - } - return ret; -} - - -/** - * \brief Check if a value is true. - * - * The value is considered true if it is a string with the value of 1, - * yes, true or on. The test is not case sensitive, any other value - * is false. - * - * \param val The string to test for a true value. - * - * \retval 1 If the value is true, 0 if not. - */ -int ConfValIsTrue(const char *val) -{ - char *trues[] = {"1", "yes", "true", "on"}; - size_t u; - - for (u = 0; u < sizeof(trues) / sizeof(trues[0]); u++) { - if (strcasecmp(val, trues[u]) == 0) { - return 1; - } - } - - return 0; -} - -/** - * \brief Check if a value is false. - * - * The value is considered false if it is a string with the value of 0, - * no, false or off. The test is not case sensitive, any other value - * is not false. - * - * \param val The string to test for a false value. - * - * \retval 1 If the value is false, 0 if not. - */ -int ConfValIsFalse(const char *val) -{ - char *falses[] = {"0", "no", "false", "off"}; - size_t u; - - for (u = 0; u < sizeof(falses) / sizeof(falses[0]); u++) { - if (strcasecmp(val, falses[u]) == 0) { - return 1; - } - } - - return 0; -} - -/** - * \brief Retrieve a configuration value as a double - * - * \param name Name of configuration parameter to get. - * \param val Pointer to an double that will be set the - * configuration value. - * - * \retval 1 will be returned if the name is found and was properly - * converted to a double, otherwise 0 will be returned. - */ -int ConfGetDouble(const char *name, double *val) -{ - char *strval; - double tmpdo; - char *endptr; - - if (ConfGet(name, &strval) == 0) - return 0; - - errno = 0; - tmpdo = strtod(strval, &endptr); - if (strval[0] == '\0' || *endptr != '\0') - return 0; - if (errno == ERANGE) - return 0; - - *val = tmpdo; - return 1; -} - -/** - * \brief Retrieve a configuration value as a float - * - * \param name Name of configuration parameter to get. - * \param val Pointer to an float that will be set the - * configuration value. - * - * \retval 1 will be returned if the name is found and was properly - * converted to a double, otherwise 0 will be returned. - */ -int ConfGetFloat(const char *name, float *val) -{ - char *strval; - double tmpfl; - char *endptr; - - if (ConfGet(name, &strval) == 0) - return 0; - - errno = 0; - tmpfl = strtof(strval, &endptr); - if (strval[0] == '\0' || *endptr != '\0') - return 0; - if (errno == ERANGE) - return 0; - - *val = tmpfl; - return 1; -} - -/** - * \brief Remove (and SCFree) the provided configuration node. - */ -void ConfNodeRemove(ConfNode *node) -{ - if (node->parent != NULL) - TAILQ_REMOVE(&node->parent->head, node, next); - ConfNodeFree(node); -} - -/** - * \brief Remove a configuration parameter from the configuration db. - * - * \param name The name of the configuration parameter to remove. - * - * \retval Returns 1 if the parameter was removed, otherwise 0 is returned - * most likely indicating the parameter was not set. - */ -int ConfRemove(const char *name) -{ - ConfNode *node; - - node = ConfGetNode(name); - if (node == NULL) - return 0; - else { - ConfNodeRemove(node); - return 1; - } -} - -/** - * \brief Creates a backup of the conf_hash hash_table used by the conf API. - */ -void ConfCreateContextBackup(void) -{ - root_backup = root; - root = NULL; - - return; -} - -/** - * \brief Restores the backup of the hash_table present in backup_conf_hash - * back to conf_hash. - */ -void ConfRestoreContextBackup(void) -{ - root = root_backup; - root_backup = NULL; - - return; -} - -/** - * \brief De-initializes the configuration system. - */ -void ConfDeInit(void) -{ - if (root != NULL) { - ConfNodeFree(root); - root = NULL; - } - - SCLogDebug("configuration module de-initialized"); -} - -static char *ConfPrintNameArray(char **name_arr, int level) -{ - static char name[128*128]; - int i; - - name[0] = '\0'; - for (i = 0; i <= level; i++) { - strlcat(name, name_arr[i], sizeof(name)); - if (i < level) - strlcat(name, ".", sizeof(name)); - } - - return name; -} - -/** - * \brief Dump a configuration node and all its children. - */ -void ConfNodeDump(const ConfNode *node, const char *prefix) -{ - ConfNode *child; - - static char *name[128]; - static int level = -1; - - level++; - TAILQ_FOREACH(child, &node->head, next) { - name[level] = SCStrdup(child->name); - if (unlikely(name[level] == NULL)) { - continue; - } - if (prefix == NULL) { - printf("%s = %s\n", ConfPrintNameArray(name, level), - child->val); - } - else { - printf("%s.%s = %s\n", prefix, - ConfPrintNameArray(name, level), child->val); - } - ConfNodeDump(child, prefix); - SCFree(name[level]); - } - level--; -} - -/** - * \brief Dump configuration to stdout. - */ -void ConfDump(void) -{ - ConfNodeDump(root, NULL); -} - -/** - * \brief Lookup a child configuration node by name. - * - * Given a ConfNode this function will lookup an immediate child - * ConfNode by name and return the child ConfNode. - * - * \param node The parent configuration node. - * \param name The name of the child node to lookup. - * - * \retval A pointer the child ConfNode if found otherwise NULL. - */ -ConfNode *ConfNodeLookupChild(const ConfNode *node, const char *name) -{ - ConfNode *child; - - TAILQ_FOREACH(child, &node->head, next) { - if (strcmp(child->name, name) == 0) - return child; - } - - return NULL; -} - -/** - * \brief Lookup the value of a child configuration node by name. - * - * Given a parent ConfNode this function will return the value of a - * child configuration node by name returning a reference to that - * value. - * - * \param node The parent configuration node. - * \param name The name of the child node to lookup. - * - * \retval A pointer the child ConfNodes value if found otherwise NULL. - */ -const char *ConfNodeLookupChildValue(const ConfNode *node, const char *name) -{ - ConfNode *child; - - child = ConfNodeLookupChild(node, name); - if (child != NULL) - return child->val; - - return NULL; -} - -/** - * \brief Lookup for a key value under a specific node - * - * \return the ConfNode matching or NULL - */ - -ConfNode *ConfNodeLookupKeyValue(const ConfNode *base, const char *key, - const char *value) -{ - ConfNode *child; - - TAILQ_FOREACH(child, &base->head, next) { - if (!strncmp(child->val, key, strlen(child->val))) { - ConfNode *subchild; - TAILQ_FOREACH(subchild, &child->head, next) { - if ((!strcmp(subchild->name, key)) && (!strcmp(subchild->val, value))) { - return child; - } - } - } - } - - return NULL; -} - -/** - * \brief Test if a configuration node has a true value. - * - * \param node The parent configuration node. - * \param name The name of the child node to test. - * - * \retval 1 if the child node has a true value, otherwise 0 is - * returned, even if the child node does not exist. - */ -int ConfNodeChildValueIsTrue(const ConfNode *node, const char *key) -{ - const char *val; - - val = ConfNodeLookupChildValue(node, key); - - return val != NULL ? ConfValIsTrue(val) : 0; -} - -/** - * \brief Create the path for an include entry - * \param file The name of the file - * \retval str Pointer to the string path + sig_file - */ -char *ConfLoadCompleteIncludePath(const char *file) -{ - char *defaultpath = NULL; - char *path = NULL; - - /* Path not specified */ - if (PathIsRelative(file)) { - if (ConfGet("include-path", &defaultpath) == 1) { - SCLogDebug("Default path: %s", defaultpath); - size_t path_len = sizeof(char) * (strlen(defaultpath) + - strlen(file) + 2); - path = SCMalloc(path_len); - if (unlikely(path == NULL)) - return NULL; - strlcpy(path, defaultpath, path_len); - if (path[strlen(path) - 1] != '/') - strlcat(path, "/", path_len); - strlcat(path, file, path_len); - } else { - path = SCStrdup(file); - if (unlikely(path == NULL)) - return NULL; - } - } else { - path = SCStrdup(file); - if (unlikely(path == NULL)) - return NULL; - } - return path; -} - -/** - * \brief Prune a configuration node. - * - * Pruning a configuration is similar to freeing, but only fields that - * may be overridden are, leaving final type parameters. Additional - * the value of the provided node is also free'd, but the node itself - * is left. - * - * \param node The configuration node to prune. - */ -void ConfNodePrune(ConfNode *node) -{ - ConfNode *item, *it; - - for (item = TAILQ_FIRST(&node->head); item != NULL; item = it) { - it = TAILQ_NEXT(item, next); - if (!item->final) { - ConfNodePrune(item); - if (TAILQ_EMPTY(&item->head)) { - TAILQ_REMOVE(&node->head, item, next); - if (item->name != NULL) - SCFree(item->name); - if (item->val != NULL) - SCFree(item->val); - SCFree(item); - } - } - } - - if (node->val != NULL) { - SCFree(node->val); - node->val = NULL; - } -} - -/** - * \brief Check if a node is a sequence or node. - * - * \param node the node to check. - * - * \return 1 if node is a seuence, otherwise 0. - */ -int ConfNodeIsSequence(const ConfNode *node) -{ - return node->is_seq == 0 ? 0 : 1; -} - -#ifdef UNITTESTS - -/** - * Lookup a non-existant value. - */ -static int ConfTestGetNonExistant(void) -{ - char name[] = "non-existant-value"; - char *value; - - return !ConfGet(name, &value); -} - -/** - * Set then lookup a value. - */ -static int ConfTestSetAndGet(void) -{ - char name[] = "some-name"; - char value[] = "some-value"; - char *value0; - - if (ConfSet(name, value) != 1) - return 0; - if (ConfGet(name, &value0) != 1) - return 0; - if (strcmp(value, value0) != 0) - return 0; - - /* Cleanup. */ - ConfRemove(name); - - return 1; -} - -/** - * Test that overriding a value is allowed provided allow_override is - * true and that the config parameter gets the new value. - */ -static int ConfTestOverrideValue1(void) -{ - char name[] = "some-name"; - char value0[] = "some-value"; - char value1[] = "new-value"; - char *val; - int rc; - - if (ConfSet(name, value0) != 1) - return 0; - if (ConfSet(name, value1) != 1) - return 0; - if (ConfGet(name, &val) != 1) - return 0; - - rc = !strcmp(val, value1); - - /* Cleanup. */ - ConfRemove(name); - - return rc; -} - -/** - * Test that a final value will not be overrided by a ConfSet. - */ -static int ConfTestOverrideValue2(void) -{ - char name[] = "some-name"; - char value0[] = "some-value"; - char value1[] = "new-value"; - char *val; - int rc; - - if (ConfSetFinal(name, value0) != 1) - return 0; - if (ConfSet(name, value1) != 0) - return 0; - if (ConfGet(name, &val) != 1) - return 0; - - rc = !strcmp(val, value0); - - /* Cleanup. */ - ConfRemove(name); - - return rc; -} - -/** - * Test retrieving an integer value from the configuration db. - */ -static int ConfTestGetInt(void) -{ - char name[] = "some-int.x"; - intmax_t val; - - if (ConfSet(name, "0") != 1) - return 0; - if (ConfGetInt(name, &val) != 1) - return 0; - - if (val != 0) - return 0; - - if (ConfSet(name, "-1") != 1) - return 0; - if (ConfGetInt(name, &val) != 1) - return 0; - if (val != -1) - return 0; - - if (ConfSet(name, "0xffff") != 1) - return 0; - if (ConfGetInt(name, &val) != 1) - return 0; - if (val != 0xffff) - return 0; - - if (ConfSet(name, "not-an-int") != 1) - return 0; - if (ConfGetInt(name, &val) != 0) - return 0; - - return 1; -} - -/** - * Test retrieving a boolean value from the configuration db. - */ -static int ConfTestGetBool(void) -{ - char name[] = "some-bool"; - char *trues[] = { - "1", - "on", "ON", - "yes", "YeS", - "true", "TRUE", - }; - char *falses[] = { - "0", - "something", - "off", "OFF", - "false", "FalSE", - "no", "NO", - }; - int val; - size_t u; - - for (u = 0; u < sizeof(trues) / sizeof(trues[0]); u++) { - if (ConfSet(name, trues[u]) != 1) - return 0; - if (ConfGetBool(name, &val) != 1) - return 0; - if (val != 1) - return 0; - } - - for (u = 0; u < sizeof(falses) / sizeof(falses[0]); u++) { - if (ConfSet(name, falses[u]) != 1) - return 0; - if (ConfGetBool(name, &val) != 1) - return 0; - if (val != 0) - return 0; - } - - return 1; -} - -static int ConfNodeLookupChildTest(void) -{ - char *test_vals[] = { "one", "two", "three" }; - size_t u; - - ConfNode *parent = ConfNodeNew(); - ConfNode *child; - - for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) { - child = ConfNodeNew(); - child->name = SCStrdup(test_vals[u]); - child->val = SCStrdup(test_vals[u]); - TAILQ_INSERT_TAIL(&parent->head, child, next); - } - - child = ConfNodeLookupChild(parent, "one"); - if (child == NULL) - return 0; - if (strcmp(child->name, "one") != 0) - return 0; - if (strcmp(child->val, "one") != 0) - return 0; - - child = ConfNodeLookupChild(parent, "two"); - if (child == NULL) - return 0; - if (strcmp(child->name, "two") != 0) - return 0; - if (strcmp(child->val, "two") != 0) - return 0; - - child = ConfNodeLookupChild(parent, "three"); - if (child == NULL) - return 0; - if (strcmp(child->name, "three") != 0) - return 0; - if (strcmp(child->val, "three") != 0) - return 0; - - child = ConfNodeLookupChild(parent, "four"); - if (child != NULL) - return 0; - - ConfNodeFree(parent); - - return 1; -} - -static int ConfNodeLookupChildValueTest(void) -{ - char *test_vals[] = { "one", "two", "three" }; - size_t u; - - ConfNode *parent = ConfNodeNew(); - ConfNode *child; - const char *value; - - for (u = 0; u < sizeof(test_vals)/sizeof(test_vals[0]); u++) { - child = ConfNodeNew(); - child->name = SCStrdup(test_vals[u]); - child->val = SCStrdup(test_vals[u]); - TAILQ_INSERT_TAIL(&parent->head, child, next); - } - - value = (char *)ConfNodeLookupChildValue(parent, "one"); - if (value == NULL) - return 0; - if (strcmp(value, "one") != 0) - return 0; - - value = (char *)ConfNodeLookupChildValue(parent, "two"); - if (value == NULL) - return 0; - if (strcmp(value, "two") != 0) - return 0; - - value = (char *)ConfNodeLookupChildValue(parent, "three"); - if (value == NULL) - return 0; - if (strcmp(value, "three") != 0) - return 0; - - value = (char *)ConfNodeLookupChildValue(parent, "four"); - if (value != NULL) - return 0; - - ConfNodeFree(parent); - - return 1; -} - -static int ConfGetChildValueWithDefaultTest(void) -{ - char *val = ""; - int ret = 1; - ConfCreateContextBackup(); - ConfInit(); - ConfSet("af-packet.0.interface", "eth0"); - ConfSet("af-packet.1.interface", "default"); - ConfSet("af-packet.1.cluster-type", "cluster_cpu"); - - ConfNode *root = ConfGetNode("af-packet.0"); - ConfNode *dflt = ConfGetNode("af-packet.1"); - ConfGetChildValueWithDefault(root, dflt, "cluster-type", &val); - if (strcmp(val, "cluster_cpu")) { - ConfDeInit(); - ConfRestoreContextBackup(); - return 0; - } - - ConfSet("af-packet.0.cluster-type", "cluster_flow"); - ConfGetChildValueWithDefault(root, dflt, "cluster-type", &val); - - if (strcmp(val, "cluster_flow")) { - ret = 0; - } - ConfDeInit(); - ConfRestoreContextBackup(); - return ret; -} - -static int ConfGetChildValueIntWithDefaultTest(void) -{ - intmax_t val = 0; - ConfCreateContextBackup(); - ConfInit(); - ConfSet("af-packet.0.interface", "eth0"); - ConfSet("af-packet.1.interface", "default"); - ConfSet("af-packet.1.threads", "2"); - - ConfNode *root = ConfGetNode("af-packet.0"); - ConfNode *dflt = ConfGetNode("af-packet.1"); - ConfGetChildValueIntWithDefault(root, dflt, "threads", &val); - if (val != 2) { - ConfDeInit(); - ConfRestoreContextBackup(); - return 0; - } - - ConfSet("af-packet.0.threads", "1"); - ConfGetChildValueIntWithDefault(root, dflt, "threads", &val); - - ConfDeInit(); - ConfRestoreContextBackup(); - if (val != 1) { - return 0; - } - return 1; -} - -static int ConfGetChildValueBoolWithDefaultTest(void) -{ - int val; - ConfCreateContextBackup(); - ConfInit(); - ConfSet("af-packet.0.interface", "eth0"); - ConfSet("af-packet.1.interface", "default"); - ConfSet("af-packet.1.use-mmap", "yes"); - - ConfNode *root = ConfGetNode("af-packet.0"); - ConfNode *dflt = ConfGetNode("af-packet.1"); - ConfGetChildValueBoolWithDefault(root, dflt, "use-mmap", &val); - if (val == 0) { - ConfDeInit(); - ConfRestoreContextBackup(); - return 0; - } - - ConfSet("af-packet.0.use-mmap", "no"); - ConfGetChildValueBoolWithDefault(root, dflt, "use-mmap", &val); - - ConfDeInit(); - ConfRestoreContextBackup(); - if (val) { - return 0; - } - return 1; -} - -/** - * Test the removal of a configuration node. - */ -static int ConfNodeRemoveTest(void) -{ - ConfCreateContextBackup(); - ConfInit(); - - if (ConfSet("some.nested.parameter", "blah") != 1) - return 0; - - ConfNode *node = ConfGetNode("some.nested.parameter"); - if (node == NULL) - return 0; - ConfNodeRemove(node); - - node = ConfGetNode("some.nested.parameter"); - if (node != NULL) - return 0; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return 1; -} - -static int ConfSetTest(void) -{ - ConfCreateContextBackup(); - ConfInit(); - - /* Set some value with 2 levels. */ - if (ConfSet("one.two", "three") != 1) - return 0; - ConfNode *n = ConfGetNode("one.two"); - if (n == NULL) - return 0; - - /* Set another 2 level parameter with the same first level, this - * used to trigger a bug that caused the second level of the name - * to become a first level node. */ - if (ConfSet("one.three", "four") != 1) - return 0; - - n = ConfGetNode("one.three"); - if (n == NULL) - return 0; - - /* A top level node of "three" should not exist. */ - n = ConfGetNode("three"); - if (n != NULL) - return 0; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return 1; -} - -static int ConfGetNodeOrCreateTest(void) -{ - ConfNode *node; - int ret = 0; - - ConfCreateContextBackup(); - ConfInit(); - - /* Get a node that should not exist, give it a value, re-get it - * and make sure the second time it returns the existing node. */ - node = ConfGetNodeOrCreate("node0", 0); - if (node == NULL) { - fprintf(stderr, "returned null\n"); - goto end; - } - if (node->parent == NULL || node->parent != root) { - fprintf(stderr, "unexpected parent node\n"); - goto end; - } - if (node->val != NULL) { - fprintf(stderr, "node already existed\n"); - goto end; - } - node->val = SCStrdup("node0"); - node = ConfGetNodeOrCreate("node0", 0); - if (node == NULL) { - fprintf(stderr, "returned null\n"); - goto end; - } - if (node->val == NULL) { - fprintf(stderr, "new node was allocated\n"); - goto end; - } - if (strcmp(node->val, "node0") != 0) { - fprintf(stderr, "node did not have expected value\n"); - goto end; - } - - /* Do the same, but for something deeply nested. */ - node = ConfGetNodeOrCreate("parent.child.grandchild", 0); - if (node == NULL) { - fprintf(stderr, "returned null\n"); - goto end; - } - if (node->parent == NULL || node->parent == root) { - fprintf(stderr, "unexpected parent node\n"); - goto end; - } - if (node->val != NULL) { - fprintf(stderr, "node already existed\n"); - goto end; - } - node->val = SCStrdup("parent.child.grandchild"); - node = ConfGetNodeOrCreate("parent.child.grandchild", 0); - if (node == NULL) { - fprintf(stderr, "returned null\n"); - goto end; - } - if (node->val == NULL) { - fprintf(stderr, "new node was allocated\n"); - goto end; - } - if (strcmp(node->val, "parent.child.grandchild") != 0) { - fprintf(stderr, "node did not have expected value\n"); - goto end; - } - - /* Test that 2 child nodes have the same root. */ - ConfNode *child1 = ConfGetNodeOrCreate("parent.kids.child1", 0); - ConfNode *child2 = ConfGetNodeOrCreate("parent.kids.child2", 0); - if (child1 == NULL || child2 == NULL) { - fprintf(stderr, "returned null\n"); - goto end; - } - if (child1->parent != child2->parent) { - fprintf(stderr, "child nodes have different parents\n"); - goto end; - } - if (strcmp(child1->parent->name, "kids") != 0) { - fprintf(stderr, "parent node had unexpected name\n"); - goto end; - } - - ret = 1; - -end: - ConfDeInit(); - ConfRestoreContextBackup(); - - return ret; -} - -static int ConfNodePruneTest(void) -{ - int ret = 0; - ConfNode *node; - - ConfCreateContextBackup(); - ConfInit(); - - /* Test that final nodes exist after a prune. */ - if (ConfSet("node.notfinal", "notfinal") != 1) - goto end; - if (ConfSetFinal("node.final", "final") != 1) - goto end; - if (ConfGetNode("node.notfinal") == NULL) - goto end; - if (ConfGetNode("node.final") == NULL) - goto end; - if ((node = ConfGetNode("node")) == NULL) - goto end; - ConfNodePrune(node); - if (ConfGetNode("node.notfinal") != NULL) - goto end; - if (ConfGetNode("node.final") == NULL) - goto end; - - /* Test that everything under a final node exists after a prune. */ - if (ConfSet("node.final.one", "one") != 1) - goto end; - if (ConfSet("node.final.two", "two") != 1) - goto end; - ConfNodePrune(node); - if (ConfNodeLookupChild(node, "final") == NULL) - goto end; - if (ConfGetNode("node.final.one") == NULL) - goto end; - if (ConfGetNode("node.final.two") == NULL) - goto end; - - ret = 1; - -end: - ConfDeInit(); - ConfRestoreContextBackup(); - - return ret; -} - -int ConfNodeIsSequenceTest(void) -{ - int retval = 0; - ConfNode *node = ConfNodeNew(); - if (node == NULL) { - goto end; - } - if (ConfNodeIsSequence(node)) { - goto end; - } - node->is_seq = 1; - if (!ConfNodeIsSequence(node)) { - goto end; - } - - retval = 1; - -end: - if (node != NULL) { - ConfNodeFree(node); - } - return retval; -} - -static int ConfSetFromStringTest(void) -{ - int retval = 0; - ConfNode *n; - - ConfCreateContextBackup(); - ConfInit(); - - if (!ConfSetFromString("stream.midstream=true", 0)) { - goto end; - } - n = ConfGetNode("stream.midstream"); - if (n == NULL) { - goto end; - } - if (n->val == NULL || strcmp("true", n->val)) { - goto end; - } - - if (!ConfSetFromString("stream.midstream =false", 0)) { - goto end; - } - n = ConfGetNode("stream.midstream"); - if (n == NULL) { - goto end; - } - if (n->val == NULL || strcmp("false", n->val)) { - goto end; - } - - if (!ConfSetFromString("stream.midstream= true", 0)) { - goto end; - } - n = ConfGetNode("stream.midstream"); - if (n == NULL) { - goto end; - } - if (n->val == NULL || strcmp("true", n->val)) { - goto end; - } - - if (!ConfSetFromString("stream.midstream = false", 0)) { - goto end; - } - n = ConfGetNode("stream.midstream"); - if (n == NULL) { - goto end; - } - if (n->val == NULL || strcmp("false", n->val)) { - goto end; - } - - retval = 1; -end: - ConfDeInit(); - ConfRestoreContextBackup(); - return retval; -} - -void ConfRegisterTests(void) -{ - UtRegisterTest("ConfTestGetNonExistant", ConfTestGetNonExistant, 1); - UtRegisterTest("ConfSetTest", ConfSetTest, 1); - UtRegisterTest("ConfTestSetAndGet", ConfTestSetAndGet, 1); - UtRegisterTest("ConfTestOverrideValue1", ConfTestOverrideValue1, 1); - UtRegisterTest("ConfTestOverrideValue2", ConfTestOverrideValue2, 1); - UtRegisterTest("ConfTestGetInt", ConfTestGetInt, 1); - UtRegisterTest("ConfTestGetBool", ConfTestGetBool, 1); - UtRegisterTest("ConfNodeLookupChildTest", ConfNodeLookupChildTest, 1); - UtRegisterTest("ConfNodeLookupChildValueTest", ConfNodeLookupChildValueTest, 1); - UtRegisterTest("ConfNodeRemoveTest", ConfNodeRemoveTest, 1); - UtRegisterTest("ConfGetChildValueWithDefaultTest", ConfGetChildValueWithDefaultTest, 1); - UtRegisterTest("ConfGetChildValueIntWithDefaultTest", ConfGetChildValueIntWithDefaultTest, 1); - UtRegisterTest("ConfGetChildValueBoolWithDefaultTest", ConfGetChildValueBoolWithDefaultTest, 1); - UtRegisterTest("ConfGetNodeOrCreateTest", ConfGetNodeOrCreateTest, 1); - UtRegisterTest("ConfNodePruneTest", ConfNodePruneTest, 1); - UtRegisterTest("ConfNodeIsSequenceTest", ConfNodeIsSequenceTest, 1); - UtRegisterTest("ConfSetFromStringTest", ConfSetFromStringTest, 1); -} - -#endif /* UNITTESTS */ diff --git a/framework/src/suricata/src/conf.h b/framework/src/suricata/src/conf.h deleted file mode 100644 index 2318580a..00000000 --- a/framework/src/suricata/src/conf.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited - Jason Ish - */ - -#ifndef __CONF_H__ -#define __CONF_H__ - -#include "queue.h" - -/** - * Structure of a configuration parameter. - */ -typedef struct ConfNode_ { - char *name; - char *val; - - int is_seq; - - /**< Flag that sets this nodes value as final. */ - int final; - - struct ConfNode_ *parent; - TAILQ_HEAD(, ConfNode_) head; - TAILQ_ENTRY(ConfNode_) next; -} ConfNode; - - -/** - * The default log directory. - */ -#ifdef OS_WIN32 -#define DEFAULT_LOG_DIR "C:\\WINDOWS\\Temp" -#else -#define DEFAULT_LOG_DIR "/var/log/suricata" -#endif /* OS_WIN32 */ - -void ConfInit(void); -void ConfDeInit(void); -ConfNode *ConfGetRootNode(void); -int ConfGet(const char *name, char **vptr); -int ConfGetInt(const char *name, intmax_t *val); -int ConfGetBool(const char *name, int *val); -int ConfGetDouble(const char *name, double *val); -int ConfGetFloat(const char *name, float *val); -int ConfSet(const char *name, char *val); -int ConfSetFromString(const char *input, int final); -int ConfSetFinal(const char *name, char *val); -void ConfDump(void); -void ConfNodeDump(const ConfNode *node, const char *prefix); -ConfNode *ConfNodeNew(void); -void ConfNodeFree(ConfNode *); -ConfNode *ConfGetNode(const char *key); -void ConfCreateContextBackup(void); -void ConfRestoreContextBackup(void); -ConfNode *ConfNodeLookupChild(const ConfNode *node, const char *key); -const char *ConfNodeLookupChildValue(const ConfNode *node, const char *key); -void ConfNodeRemove(ConfNode *); -void ConfRegisterTests(); -int ConfNodeChildValueIsTrue(const ConfNode *node, const char *key); -int ConfValIsTrue(const char *val); -int ConfValIsFalse(const char *val); -void ConfNodePrune(ConfNode *node); - -ConfNode *ConfNodeLookupKeyValue(const ConfNode *base, const char *key, const char *value); -int ConfGetChildValue(const ConfNode *base, const char *name, char **vptr); -int ConfGetChildValueInt(const ConfNode *base, const char *name, intmax_t *val); -int ConfGetChildValueBool(const ConfNode *base, const char *name, int *val); -int ConfGetChildValueWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, char **vptr); -int ConfGetChildValueIntWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, intmax_t *val); -int ConfGetChildValueBoolWithDefault(const ConfNode *base, const ConfNode *dflt, const char *name, int *val); -char *ConfLoadCompleteIncludePath(const char *); -int ConfNodeIsSequence(const ConfNode *node); - -#endif /* ! __CONF_H__ */ diff --git a/framework/src/suricata/src/counters.c b/framework/src/suricata/src/counters.c deleted file mode 100644 index 887fd7ca..00000000 --- a/framework/src/suricata/src/counters.c +++ /dev/null @@ -1,1500 +0,0 @@ -/* Copyright (C) 2007-2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Victor Julien - * - * Engine stats API - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "counters.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "conf.h" -#include "util-time.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "util-privs.h" -#include "util-signal.h" -#include "unix-manager.h" -#include "output.h" - -/* Time interval for syncing the local counters with the global ones */ -#define STATS_WUT_TTS 3 - -/* Time interval at which the mgmt thread o/p the stats */ -#define STATS_MGMTT_TTS 8 - -/** - * \brief Different kinds of qualifier that can be used to modify the behaviour - * of the counter to be registered - */ -enum { - STATS_TYPE_NORMAL = 1, - STATS_TYPE_AVERAGE = 2, - STATS_TYPE_MAXIMUM = 3, - STATS_TYPE_FUNC = 4, - - STATS_TYPE_MAX = 5, -}; - -/** - * \brief per thread store of counters - */ -typedef struct StatsThreadStore_ { - /** thread name used in output */ - const char *name; - - StatsPublicThreadContext *ctx; - - StatsPublicThreadContext **head; - uint32_t size; - - struct StatsThreadStore_ *next; -} StatsThreadStore; - -/** - * \brief Holds the output interface context for the counter api - */ -typedef struct StatsGlobalContext_ { - /** list of thread stores: one per thread plus one global */ - StatsThreadStore *sts; - SCMutex sts_lock; - int sts_cnt; - - HashTable *counters_id_hash; - - StatsPublicThreadContext global_counter_ctx; -} StatsGlobalContext; - -static void *stats_thread_data = NULL; -static StatsGlobalContext *stats_ctx = NULL; -static time_t stats_start_time; -/** refresh interval in seconds */ -static uint32_t stats_tts = STATS_MGMTT_TTS; -/** is the stats counter enabled? */ -static char stats_enabled = TRUE; - -static int StatsOutput(ThreadVars *tv); -static int StatsThreadRegister(const char *thread_name, StatsPublicThreadContext *); -void StatsReleaseCounters(StatsCounter *head); - -/** stats table is filled each interval and passed to the - * loggers. Initialized at first use. */ -static StatsTable stats_table = { NULL, NULL, 0, 0, 0, {0 , 0}}; - -static uint16_t counters_global_id = 0; - -static void StatsPublicThreadContextInit(StatsPublicThreadContext *t) -{ - SCMutexInit(&t->m, NULL); -} - -static void StatsPublicThreadContextCleanup(StatsPublicThreadContext *t) -{ - SCMutexLock(&t->m); - StatsReleaseCounters(t->head); - t->head = NULL; - t->perf_flag = 0; - t->curr_id = 0; - SCMutexUnlock(&t->m); - SCMutexDestroy(&t->m); -} - -/** - * \brief Adds a value of type uint64_t to the local counter. - * - * \param id ID of the counter as set by the API - * \param pca Counter array that holds the local counter for this TM - * \param x Value to add to this local counter - */ -void StatsAddUI64(ThreadVars *tv, uint16_t id, uint64_t x) -{ - StatsPrivateThreadContext *pca = &tv->perf_private_ctx; -#ifdef UNITTESTS - if (pca->initialized == 0) - return; -#endif -#ifdef DEBUG - BUG_ON ((id < 1) || (id > pca->size)); -#endif - pca->head[id].value += x; - pca->head[id].updates++; - return; -} - -/** - * \brief Increments the local counter - * - * \param id Index of the counter in the counter array - * \param pca Counter array that holds the local counters for this TM - */ -void StatsIncr(ThreadVars *tv, uint16_t id) -{ - StatsPrivateThreadContext *pca = &tv->perf_private_ctx; -#ifdef UNITTESTS - if (pca->initialized == 0) - return; -#endif -#ifdef DEBUG - BUG_ON ((id < 1) || (id > pca->size)); -#endif - pca->head[id].value++; - pca->head[id].updates++; - return; -} - -/** - * \brief Sets a value of type double to the local counter - * - * \param id Index of the local counter in the counter array - * \param pca Pointer to the StatsPrivateThreadContext - * \param x The value to set for the counter - */ -void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x) -{ - StatsPrivateThreadContext *pca = &tv->perf_private_ctx; -#ifdef UNITTESTS - if (pca->initialized == 0) - return; -#endif -#ifdef DEBUG - BUG_ON ((id < 1) || (id > pca->size)); -#endif - - if ((pca->head[id].pc->type == STATS_TYPE_MAXIMUM) && - (x > pca->head[id].value)) { - pca->head[id].value = x; - } else if (pca->head[id].pc->type == STATS_TYPE_NORMAL) { - pca->head[id].value = x; - } - - pca->head[id].updates++; - - return; -} - -static ConfNode *GetConfig(void) { - ConfNode *stats = ConfGetNode("stats"); - if (stats != NULL) - return stats; - - ConfNode *root = ConfGetNode("outputs"); - ConfNode *node = NULL; - if (root != NULL) { - TAILQ_FOREACH(node, &root->head, next) { - if (strcmp(node->val, "stats") == 0) { - return node->head.tqh_first; - } - } - } - return NULL; -} - -/** - * \brief Initializes stats context - */ -static void StatsInitCtx(void) -{ - SCEnter(); - ConfNode *stats = GetConfig(); - if (stats != NULL) { - const char *enabled = ConfNodeLookupChildValue(stats, "enabled"); - if (enabled != NULL && ConfValIsFalse(enabled)) { - stats_enabled = FALSE; - SCLogDebug("Stats module has been disabled"); - SCReturn; - } - const char *interval = ConfNodeLookupChildValue(stats, "interval"); - if (interval != NULL) - stats_tts = (uint32_t) atoi(interval); - } - - if (!OutputStatsLoggersRegistered()) { - SCLogWarning(SC_WARN_NO_STATS_LOGGERS, "stats are enabled but no loggers are active"); - stats_enabled = FALSE; - SCReturn; - } - - /* Store the engine start time */ - time(&stats_start_time); - - /* init the lock used by StatsThreadStore */ - if (SCMutexInit(&stats_ctx->sts_lock, NULL) != 0) { - SCLogError(SC_ERR_INITIALIZATION, "error initializing sts mutex"); - exit(EXIT_FAILURE); - } - - SCReturn; -} - -/** - * \brief Releases the resources alloted to the output context of the - * Stats API - */ -static void StatsReleaseCtx() -{ - if (stats_ctx == NULL) { - SCLogDebug("Counter module has been disabled"); - return; - } - - StatsThreadStore *sts = NULL; - StatsThreadStore *temp = NULL; - sts = stats_ctx->sts; - - while (sts != NULL) { - if (sts->head != NULL) - SCFree(sts->head); - - temp = sts->next; - SCFree(sts); - sts = temp; - } - - if (stats_ctx->counters_id_hash != NULL) { - HashTableFree(stats_ctx->counters_id_hash); - stats_ctx->counters_id_hash = NULL; - } - - StatsPublicThreadContextCleanup(&stats_ctx->global_counter_ctx); - SCFree(stats_ctx); - stats_ctx = NULL; - - /* free stats table */ - if (stats_table.tstats != NULL) { - SCFree(stats_table.tstats); - stats_table.tstats = NULL; - } - - if (stats_table.stats != NULL) { - SCFree(stats_table.stats); - stats_table.stats = NULL; - } - memset(&stats_table, 0, sizeof(stats_table)); - - return; -} - -/** - * \brief management thread. This thread is responsible for writing the stats - * - * \param arg thread var - * - * \retval NULL This is the value that is always returned - */ -static void *StatsMgmtThread(void *arg) -{ - /* block usr2. usr2 to be handled by the main thread only */ - UtilSignalBlock(SIGUSR2); - - ThreadVars *tv_local = (ThreadVars *)arg; - uint8_t run = 1; - struct timespec cond_time; - - /* Set the thread name */ - if (SCSetThreadName(tv_local->name) < 0) { - SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name"); - } - - if (tv_local->thread_setup_flags != 0) - TmThreadSetupOptions(tv_local); - - /* Set the threads capability */ - tv_local->cap_flags = 0; - - SCDropCaps(tv_local); - - if (stats_ctx == NULL) { - SCLogError(SC_ERR_STATS_NOT_INIT, "Stats API not init" - "StatsInitCounterApi() has to be called first"); - TmThreadsSetFlag(tv_local, THV_CLOSED | THV_RUNNING_DONE); - return NULL; - } - - TmModule *tm = &tmm_modules[TMM_STATSLOGGER]; - BUG_ON(tm->ThreadInit == NULL); - int r = tm->ThreadInit(tv_local, NULL, &stats_thread_data); - if (r != 0 || stats_thread_data == NULL) { - SCLogError(SC_ERR_THREAD_INIT, "Stats API " - "ThreadInit failed"); - TmThreadsSetFlag(tv_local, THV_CLOSED | THV_RUNNING_DONE); - return NULL; - } - SCLogDebug("stats_thread_data %p", &stats_thread_data); - - TmThreadsSetFlag(tv_local, THV_INIT_DONE); - while (run) { - if (TmThreadsCheckFlag(tv_local, THV_PAUSE)) { - TmThreadsSetFlag(tv_local, THV_PAUSED); - TmThreadTestThreadUnPaused(tv_local); - TmThreadsUnsetFlag(tv_local, THV_PAUSED); - } - - cond_time.tv_sec = time(NULL) + stats_tts; - cond_time.tv_nsec = 0; - - /* wait for the set time, or until we are woken up by - * the shutdown procedure */ - SCCtrlMutexLock(tv_local->ctrl_mutex); - SCCtrlCondTimedwait(tv_local->ctrl_cond, tv_local->ctrl_mutex, &cond_time); - SCCtrlMutexUnlock(tv_local->ctrl_mutex); - - StatsOutput(tv_local); - - if (TmThreadsCheckFlag(tv_local, THV_KILL)) { - run = 0; - } - } - - TmThreadsSetFlag(tv_local, THV_RUNNING_DONE); - TmThreadWaitForFlag(tv_local, THV_DEINIT); - - r = tm->ThreadDeinit(tv_local, stats_thread_data); - if (r != TM_ECODE_OK) { - SCLogError(SC_ERR_THREAD_DEINIT, "Stats Counter API " - "ThreadDeinit failed"); - } - - TmThreadsSetFlag(tv_local, THV_CLOSED); - return NULL; -} - -/** - * \brief Wake up thread. This thread wakes up every TTS(time to sleep) seconds - * and sets the flag for every ThreadVars' StatsPublicThreadContext - * - * \param arg is NULL always - * - * \retval NULL This is the value that is always returned - */ -static void *StatsWakeupThread(void *arg) -{ - /* block usr2. usr2 to be handled by the main thread only */ - UtilSignalBlock(SIGUSR2); - - ThreadVars *tv_local = (ThreadVars *)arg; - uint8_t run = 1; - ThreadVars *tv = NULL; - PacketQueue *q = NULL; - struct timespec cond_time; - - /* Set the thread name */ - if (SCSetThreadName(tv_local->name) < 0) { - SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name"); - } - - if (tv_local->thread_setup_flags != 0) - TmThreadSetupOptions(tv_local); - - /* Set the threads capability */ - tv_local->cap_flags = 0; - - SCDropCaps(tv_local); - - if (stats_ctx == NULL) { - SCLogError(SC_ERR_STATS_NOT_INIT, "Stats API not init" - "StatsInitCounterApi() has to be called first"); - TmThreadsSetFlag(tv_local, THV_CLOSED | THV_RUNNING_DONE); - return NULL; - } - - TmThreadsSetFlag(tv_local, THV_INIT_DONE); - while (run) { - if (TmThreadsCheckFlag(tv_local, THV_PAUSE)) { - TmThreadsSetFlag(tv_local, THV_PAUSED); - TmThreadTestThreadUnPaused(tv_local); - TmThreadsUnsetFlag(tv_local, THV_PAUSED); - } - - cond_time.tv_sec = time(NULL) + STATS_WUT_TTS; - cond_time.tv_nsec = 0; - - /* wait for the set time, or until we are woken up by - * the shutdown procedure */ - SCCtrlMutexLock(tv_local->ctrl_mutex); - SCCtrlCondTimedwait(tv_local->ctrl_cond, tv_local->ctrl_mutex, &cond_time); - SCCtrlMutexUnlock(tv_local->ctrl_mutex); - - tv = tv_root[TVT_PPT]; - while (tv != NULL) { - if (tv->perf_public_ctx.head == NULL) { - tv = tv->next; - continue; - } - - /* assuming the assignment of an int to be atomic, and even if it's - * not, it should be okay */ - tv->perf_public_ctx.perf_flag = 1; - - if (tv->inq != NULL) { - q = &trans_q[tv->inq->id]; - SCCondSignal(&q->cond_q); - } - - tv = tv->next; - } - - /* mgt threads for flow manager */ - tv = tv_root[TVT_MGMT]; - while (tv != NULL) { - if (tv->perf_public_ctx.head == NULL) { - tv = tv->next; - continue; - } - - /* assuming the assignment of an int to be atomic, and even if it's - * not, it should be okay */ - tv->perf_public_ctx.perf_flag = 1; - - tv = tv->next; - } - - if (TmThreadsCheckFlag(tv_local, THV_KILL)) { - run = 0; - } - } - - TmThreadsSetFlag(tv_local, THV_RUNNING_DONE); - TmThreadWaitForFlag(tv_local, THV_DEINIT); - - TmThreadsSetFlag(tv_local, THV_CLOSED); - return NULL; -} - -/** - * \brief Releases a counter - * - * \param pc Pointer to the StatsCounter to be freed - */ -static void StatsReleaseCounter(StatsCounter *pc) -{ - if (pc != NULL) { - SCFree(pc); - } - - return; -} - -/** - * \brief Registers a counter. - * - * \param name Name of the counter, to be registered - * \param tm_name Thread module to which this counter belongs - * \param pctx StatsPublicThreadContext for this tm-tv instance - * \param type_q Qualifier describing the type of counter to be registered - * - * \retval the counter id for the newly registered counter, or the already - * present counter on success - * \retval 0 on failure - */ -static uint16_t StatsRegisterQualifiedCounter(char *name, char *tm_name, - StatsPublicThreadContext *pctx, - int type_q, uint64_t (*Func)(void)) -{ - StatsCounter **head = &pctx->head; - StatsCounter *temp = NULL; - StatsCounter *prev = NULL; - StatsCounter *pc = NULL; - - if (name == NULL || pctx == NULL) { - SCLogDebug("Counter name, StatsPublicThreadContext NULL"); - return 0; - } - - temp = prev = *head; - while (temp != NULL) { - prev = temp; - - if (strcmp(name, temp->name) == 0) { - break; - } - - temp = temp->next; - } - - /* We already have a counter registered by this name */ - if (temp != NULL) - return(temp->id); - - /* if we reach this point we don't have a counter registered by this name */ - if ( (pc = SCMalloc(sizeof(StatsCounter))) == NULL) - return 0; - memset(pc, 0, sizeof(StatsCounter)); - - /* assign a unique id to this StatsCounter. The id is local to this - * thread context. Please note that the id start from 1, and not 0 */ - pc->id = ++(pctx->curr_id); - pc->name = name; - pc->type = type_q; - pc->Func = Func; - - /* we now add the counter to the list */ - if (prev == NULL) - *head = pc; - else - prev->next = pc; - - return pc->id; -} - -/** - * \brief Copies the StatsCounter value from the local counter present in the - * StatsPrivateThreadContext to its corresponding global counterpart. Used - * internally by StatsUpdateCounterArray() - * - * \param pcae Pointer to the StatsPrivateThreadContext which holds the local - * versions of the counters - */ -static void StatsCopyCounterValue(StatsLocalCounter *pcae) -{ - StatsCounter *pc = pcae->pc; - - pc->value = pcae->value; - pc->updates = pcae->updates; - return; -} - -/** - * \brief The output interface for the Stats API - */ -static int StatsOutput(ThreadVars *tv) -{ - const StatsThreadStore *sts = NULL; - const StatsCounter *pc = NULL; - void *td = stats_thread_data; - - if (counters_global_id == 0) - return -1; - - if (stats_table.nstats == 0) { - StatsThreadRegister("Global", &stats_ctx->global_counter_ctx); - - uint32_t nstats = counters_global_id; - - stats_table.nstats = nstats; - stats_table.stats = SCCalloc(stats_table.nstats, sizeof(StatsRecord)); - if (stats_table.stats == NULL) { - stats_table.nstats = 0; - SCLogError(SC_ERR_MEM_ALLOC, "could not alloc memory for stats"); - return -1; - } - - stats_table.ntstats = stats_ctx->sts_cnt; - uint32_t array_size = stats_table.nstats * sizeof(StatsRecord); - stats_table.tstats = SCCalloc(stats_table.ntstats, array_size); - if (stats_table.tstats == NULL) { - stats_table.ntstats = 0; - SCLogError(SC_ERR_MEM_ALLOC, "could not alloc memory for stats"); - return -1; - } - - stats_table.start_time = stats_start_time; - } - - const uint16_t max_id = counters_global_id; - if (max_id == 0) - return -1; - - /** temporary local table to merge the per thread counters, - * especially needed for the average counters */ - struct CountersMergeTable { - int type; - uint64_t value; - uint64_t updates; - } merge_table[max_id]; - memset(&merge_table, 0x00, - max_id * sizeof(struct CountersMergeTable)); - - int thread = stats_ctx->sts_cnt - 1; - StatsRecord *table = stats_table.stats; - - /* Loop through the thread counter stores. The global counters - * are in a separate store inside this list. */ - sts = stats_ctx->sts; - SCLogDebug("sts %p", sts); - while (sts != NULL) { - BUG_ON(thread < 0); - - SCLogDebug("Thread %d %s ctx %p", thread, sts->name, sts->ctx); - - /* temporay table for quickly storing the counters for this - * thread store, so that we can post process them outside - * of the thread store lock */ - struct CountersMergeTable thread_table[max_id]; - memset(&thread_table, 0x00, - max_id * sizeof(struct CountersMergeTable)); - - SCMutexLock(&sts->ctx->m); - pc = sts->ctx->head; - while (pc != NULL) { - SCLogDebug("Counter %s (%u:%u) value %"PRIu64, - pc->name, pc->id, pc->gid, pc->value); - - thread_table[pc->gid].type = pc->type; - switch (pc->type) { - case STATS_TYPE_FUNC: - if (pc->Func != NULL) - thread_table[pc->gid].value = pc->Func(); - break; - case STATS_TYPE_AVERAGE: - default: - thread_table[pc->gid].value = pc->value; - break; - } - thread_table[pc->gid].updates = pc->updates; - table[pc->gid].name = pc->name; - - pc = pc->next; - } - SCMutexUnlock(&sts->ctx->m); - - /* update merge table */ - uint16_t c; - for (c = 0; c < max_id; c++) { - struct CountersMergeTable *e = &thread_table[c]; - /* thread only sets type if it has a counter - * of this type. */ - if (e->type == 0) - continue; - - switch (e->type) { - case STATS_TYPE_MAXIMUM: - if (e->value > merge_table[c].value) - merge_table[c].value = e->value; - break; - case STATS_TYPE_FUNC: - merge_table[c].value = e->value; - break; - case STATS_TYPE_AVERAGE: - default: - merge_table[c].value += e->value; - break; - } - merge_table[c].updates += e->updates; - merge_table[c].type = e->type; - } - - /* update per thread stats table */ - for (c = 0; c < max_id; c++) { - struct CountersMergeTable *e = &thread_table[c]; - /* thread only sets type if it has a counter - * of this type. */ - if (e->type == 0) - continue; - - uint32_t offset = (thread * stats_table.nstats) + c; - StatsRecord *r = &stats_table.tstats[offset]; - r->name = table[c].name; - r->tm_name = sts->name; - - switch (e->type) { - case STATS_TYPE_AVERAGE: - if (e->value > 0 && e->updates > 0) { - r->value = (uint64_t)(e->value / e->updates); - } - break; - default: - r->value = e->value; - break; - } - } - - sts = sts->next; - thread--; - } - - /* transfer 'merge table' to final stats table */ - uint16_t x; - for (x = 0; x < max_id; x++) { - /* xfer previous value to pvalue and reset value */ - table[x].pvalue = table[x].value; - table[x].value = 0; - table[x].tm_name = "Total"; - - struct CountersMergeTable *m = &merge_table[x]; - switch (m->type) { - case STATS_TYPE_MAXIMUM: - if (m->value > table[x].value) - table[x].value = m->value; - break; - case STATS_TYPE_AVERAGE: - if (m->value > 0 && m->updates > 0) { - table[x].value = (uint64_t)(m->value / m->updates); - } - break; - default: - table[x].value += m->value; - break; - } - } - - /* invoke logger(s) */ - OutputStatsLog(tv, td, &stats_table); - return 1; -} - -#ifdef BUILD_UNIX_SOCKET -/** - * \todo reimplement this, probably based on stats-json - */ -TmEcode StatsOutputCounterSocket(json_t *cmd, - json_t *answer, void *data) -{ - json_object_set_new(answer, "message", - json_string("not implemented")); - return TM_ECODE_FAILED; -} -#endif /* BUILD_UNIX_SOCKET */ - -/** - * \brief Initializes the perf counter api. Things are hard coded currently. - * More work to be done when we implement multiple interfaces - */ -void StatsInit(void) -{ - BUG_ON(stats_ctx != NULL); - if ( (stats_ctx = SCMalloc(sizeof(StatsGlobalContext))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in StatsInitCtx. Exiting..."); - exit(EXIT_FAILURE); - } - memset(stats_ctx, 0, sizeof(StatsGlobalContext)); - - StatsPublicThreadContextInit(&stats_ctx->global_counter_ctx); -} - -void StatsSetupPostConfig(void) -{ - StatsInitCtx(); -} - -/** - * \brief Spawns the wakeup, and the management thread used by the stats api - * - * The threads use the condition variable in the thread vars to control - * their wait loops to make sure the main thread can quickly kill them. - */ -void StatsSpawnThreads(void) -{ - SCEnter(); - - if (!stats_enabled) { - SCReturn; - } - - ThreadVars *tv_wakeup = NULL; - ThreadVars *tv_mgmt = NULL; - - /* spawn the stats wakeup thread */ - tv_wakeup = TmThreadCreateMgmtThread("StatsWakeupThread", - StatsWakeupThread, 1); - if (tv_wakeup == NULL) { - SCLogError(SC_ERR_THREAD_CREATE, "TmThreadCreateMgmtThread " - "failed"); - exit(EXIT_FAILURE); - } - - if (TmThreadSpawn(tv_wakeup) != 0) { - SCLogError(SC_ERR_THREAD_SPAWN, "TmThreadSpawn failed for " - "StatsWakeupThread"); - exit(EXIT_FAILURE); - } - - /* spawn the stats mgmt thread */ - tv_mgmt = TmThreadCreateMgmtThread("StatsMgmtThread", - StatsMgmtThread, 1); - if (tv_mgmt == NULL) { - SCLogError(SC_ERR_THREAD_CREATE, - "TmThreadCreateMgmtThread failed"); - exit(EXIT_FAILURE); - } - - if (TmThreadSpawn(tv_mgmt) != 0) { - SCLogError(SC_ERR_THREAD_SPAWN, "TmThreadSpawn failed for " - "StatsWakeupThread"); - exit(EXIT_FAILURE); - } - - SCReturn; -} - -/** - * \brief Registers a normal, unqualified counter - * - * \param name Name of the counter, to be registered - * \param tv Pointer to the ThreadVars instance for which the counter would - * be registered - * - * \retval id Counter id for the newly registered counter, or the already - * present counter - */ -uint16_t StatsRegisterCounter(char *name, struct ThreadVars_ *tv) -{ - uint16_t id = StatsRegisterQualifiedCounter(name, - (tv->thread_group_name != NULL) ? tv->thread_group_name : tv->name, - &tv->perf_public_ctx, - STATS_TYPE_NORMAL, NULL); - - return id; -} - -/** - * \brief Registers a counter, whose value holds the average of all the values - * assigned to it. - * - * \param name Name of the counter, to be registered - * \param tv Pointer to the ThreadVars instance for which the counter would - * be registered - * - * \retval id Counter id for the newly registered counter, or the already - * present counter - */ -uint16_t StatsRegisterAvgCounter(char *name, struct ThreadVars_ *tv) -{ - uint16_t id = StatsRegisterQualifiedCounter(name, - (tv->thread_group_name != NULL) ? tv->thread_group_name : tv->name, - &tv->perf_public_ctx, - STATS_TYPE_AVERAGE, NULL); - - return id; -} - -/** - * \brief Registers a counter, whose value holds the maximum of all the values - * assigned to it. - * - * \param name Name of the counter, to be registered - * \param tv Pointer to the ThreadVars instance for which the counter would - * be registered - * - * \retval the counter id for the newly registered counter, or the already - * present counter - */ -uint16_t StatsRegisterMaxCounter(char *name, struct ThreadVars_ *tv) -{ - uint16_t id = StatsRegisterQualifiedCounter(name, - (tv->thread_group_name != NULL) ? tv->thread_group_name : tv->name, - &tv->perf_public_ctx, - STATS_TYPE_MAXIMUM, NULL); - - return id; -} - -/** - * \brief Registers a counter, which represents a global value - * - * \param name Name of the counter, to be registered - * \param Func Function Pointer returning a uint64_t - * - * \retval id Counter id for the newly registered counter, or the already - * present counter - */ -uint16_t StatsRegisterGlobalCounter(char *name, uint64_t (*Func)(void)) -{ -#ifdef UNITTESTS - if (stats_ctx == NULL) - return 0; -#else - BUG_ON(stats_ctx == NULL); -#endif - uint16_t id = StatsRegisterQualifiedCounter(name, NULL, - &(stats_ctx->global_counter_ctx), - STATS_TYPE_FUNC, - Func); - return id; -} - -typedef struct CountersIdType_ { - uint16_t id; - const char *string; -} CountersIdType; - -uint32_t CountersIdHashFunc(HashTable *ht, void *data, uint16_t datalen) -{ - CountersIdType *t = (CountersIdType *)data; - uint32_t hash = 0; - int i = 0; - - int len = strlen(t->string); - - for (i = 0; i < len; i++) - hash += tolower((unsigned char)t->string[i]); - - hash = hash % ht->array_size; - - return hash; -} - -char CountersIdHashCompareFunc(void *data1, uint16_t datalen1, - void *data2, uint16_t datalen2) -{ - CountersIdType *t1 = (CountersIdType *)data1; - CountersIdType *t2 = (CountersIdType *)data2; - int len1 = 0; - int len2 = 0; - - if (t1 == NULL || t2 == NULL) - return 0; - - if (t1->string == NULL || t2->string == NULL) - return 0; - - len1 = strlen(t1->string); - len2 = strlen(t2->string); - - if (len1 == len2 && memcmp(t1->string, t2->string, len1) == 0) { - return 1; - } - - return 0; -} - -void CountersIdHashFreeFunc(void *data) -{ - SCFree(data); -} - - -/** \internal - * \brief Adds a TM to the clubbed TM table. Multiple instances of the same TM - * are stacked together in a PCTMI container. - * - * \param tm_name Name of the tm to be added to the table - * \param pctx StatsPublicThreadContext associated with the TM tm_name - * - * \retval 1 on success, 0 on failure - */ -static int StatsThreadRegister(const char *thread_name, StatsPublicThreadContext *pctx) -{ - if (stats_ctx == NULL) { - SCLogDebug("Counter module has been disabled"); - return 0; - } - - StatsThreadStore *temp = NULL; - - if (thread_name == NULL || pctx == NULL) { - SCLogDebug("supplied argument(s) to StatsThreadRegister NULL"); - return 0; - } - - SCMutexLock(&stats_ctx->sts_lock); - if (stats_ctx->counters_id_hash == NULL) { - stats_ctx->counters_id_hash = HashTableInit(256, CountersIdHashFunc, - CountersIdHashCompareFunc, - CountersIdHashFreeFunc); - BUG_ON(stats_ctx->counters_id_hash == NULL); - } - StatsCounter *pc = pctx->head; - while (pc != NULL) { - CountersIdType t = { 0, pc->name }, *id = NULL; - id = HashTableLookup(stats_ctx->counters_id_hash, &t, sizeof(t)); - if (id == NULL) { - id = SCCalloc(1, sizeof(*id)); - BUG_ON(id == NULL); - id->id = counters_global_id++; - id->string = pc->name; - BUG_ON(HashTableAdd(stats_ctx->counters_id_hash, id, sizeof(*id)) < 0); - } - pc->gid = id->id; - pc = pc->next; - } - - - if ( (temp = SCMalloc(sizeof(StatsThreadStore))) == NULL) { - SCMutexUnlock(&stats_ctx->sts_lock); - return 0; - } - memset(temp, 0, sizeof(StatsThreadStore)); - - temp->ctx = pctx; - temp->name = thread_name; - - temp->next = stats_ctx->sts; - stats_ctx->sts = temp; - stats_ctx->sts_cnt++; - SCLogDebug("stats_ctx->sts %p", stats_ctx->sts); - - SCMutexUnlock(&stats_ctx->sts_lock); - return 1; -} - -/** \internal - * \brief Returns a counter array for counters in this id range(s_id - e_id) - * - * \param s_id Counter id of the first counter to be added to the array - * \param e_id Counter id of the last counter to be added to the array - * \param pctx Pointer to the tv's StatsPublicThreadContext - * - * \retval a counter-array in this(s_id-e_id) range for this TM instance - */ -static int StatsGetCounterArrayRange(uint16_t s_id, uint16_t e_id, - StatsPublicThreadContext *pctx, - StatsPrivateThreadContext *pca) -{ - StatsCounter *pc = NULL; - uint32_t i = 0; - - if (pctx == NULL || pca == NULL) { - SCLogDebug("pctx/pca is NULL"); - return -1; - } - - if (s_id < 1 || e_id < 1 || s_id > e_id) { - SCLogDebug("error with the counter ids"); - return -1; - } - - if (e_id > pctx->curr_id) { - SCLogDebug("end id is greater than the max id for this tv"); - return -1; - } - - if ( (pca->head = SCMalloc(sizeof(StatsLocalCounter) * (e_id - s_id + 2))) == NULL) { - return -1; - } - memset(pca->head, 0, sizeof(StatsLocalCounter) * (e_id - s_id + 2)); - - pc = pctx->head; - while (pc->id != s_id) - pc = pc->next; - - i = 1; - while ((pc != NULL) && (pc->id <= e_id)) { - pca->head[i].pc = pc; - pca->head[i].id = pc->id; - pc = pc->next; - i++; - } - pca->size = i - 1; - - pca->initialized = 1; - return 0; -} - -/** \internal - * \brief Returns a counter array for all counters registered for this tm - * instance - * - * \param pctx Pointer to the tv's StatsPublicThreadContext - * - * \retval pca Pointer to a counter-array for all counter of this tm instance - * on success; NULL on failure - */ -static int StatsGetAllCountersArray(StatsPublicThreadContext *pctx, StatsPrivateThreadContext *private) -{ - if (pctx == NULL || private == NULL) - return -1; - - return StatsGetCounterArrayRange(1, pctx->curr_id, pctx, private); -} - - -int StatsSetupPrivate(ThreadVars *tv) -{ - StatsGetAllCountersArray(&(tv)->perf_public_ctx, &(tv)->perf_private_ctx); - - StatsThreadRegister(tv->name, &(tv)->perf_public_ctx); - return 0; -} - -/** - * \brief Syncs the counter array with the global counter variables - * - * \param pca Pointer to the StatsPrivateThreadContext - * \param pctx Pointer the the tv's StatsPublicThreadContext - * - * \retval 0 on success - * \retval -1 on error - */ -int StatsUpdateCounterArray(StatsPrivateThreadContext *pca, StatsPublicThreadContext *pctx) -{ - StatsLocalCounter *pcae = NULL; - uint32_t i = 0; - - if (pca == NULL || pctx == NULL) { - SCLogDebug("pca or pctx is NULL inside StatsUpdateCounterArray"); - return -1; - } - - pcae = pca->head; - - SCMutexLock(&pctx->m); - for (i = 1; i <= pca->size; i++) { - StatsCopyCounterValue(&pcae[i]); - } - SCMutexUnlock(&pctx->m); - - pctx->perf_flag = 0; - - return 1; -} - -/** - * \brief Get the value of the local copy of the counter that hold this id. - * - * \param tv threadvars - * \param id The counter id. - * - * \retval 0 on success. - * \retval -1 on error. - */ -uint64_t StatsGetLocalCounterValue(ThreadVars *tv, uint16_t id) -{ - StatsPrivateThreadContext *pca = &tv->perf_private_ctx; -#ifdef DEBUG - BUG_ON ((id < 1) || (id > pca->size)); -#endif - return pca->head[id].value; -} - -/** - * \brief Releases the resources alloted by the Stats API - */ -void StatsReleaseResources() -{ - StatsReleaseCtx(); - - return; -} - -/** - * \brief Releases counters - * - * \param head Pointer to the head of the list of perf counters that have to - * be freed - */ -void StatsReleaseCounters(StatsCounter *head) -{ - StatsCounter *pc = NULL; - - while (head != NULL) { - pc = head; - head = head->next; - StatsReleaseCounter(pc); - } - - return; -} - -/** - * \brief Releases the StatsPrivateThreadContext allocated by the user, for storing and - * updating local counter values - * - * \param pca Pointer to the StatsPrivateThreadContext - */ -void StatsReleasePrivateThreadContext(StatsPrivateThreadContext *pca) -{ - if (pca != NULL) { - if (pca->head != NULL) { - SCFree(pca->head); - pca->head = NULL; - pca->size = 0; - } - pca->initialized = 0; - } - - return; -} - -void StatsThreadCleanup(ThreadVars *tv) -{ - StatsPublicThreadContextCleanup(&tv->perf_public_ctx); - StatsReleasePrivateThreadContext(&tv->perf_private_ctx); -} - -/*----------------------------------Unit_Tests--------------------------------*/ - -#ifdef UNITTESTS -/** \internal - * \brief Registers a normal, unqualified counter - * - * \param name Name of the counter, to be registered - * \param tm_name Name of the engine module under which the counter has to be - * registered - * \param type Datatype of this counter variable - * \param pctx StatsPublicThreadContext corresponding to the tm_name key under which the - * key has to be registered - * - * \retval id Counter id for the newly registered counter, or the already - * present counter - */ -static uint16_t RegisterCounter(char *name, char *tm_name, - StatsPublicThreadContext *pctx) -{ - uint16_t id = StatsRegisterQualifiedCounter(name, tm_name, pctx, - STATS_TYPE_NORMAL, NULL); - return id; -} - -static int StatsTestCounterReg02() -{ - StatsPublicThreadContext pctx; - - memset(&pctx, 0, sizeof(StatsPublicThreadContext)); - - return RegisterCounter(NULL, NULL, &pctx); -} - -static int StatsTestCounterReg03() -{ - StatsPublicThreadContext pctx; - int result; - - memset(&pctx, 0, sizeof(StatsPublicThreadContext)); - - result = RegisterCounter("t1", "c1", &pctx); - - StatsReleaseCounters(pctx.head); - - return result; -} - -static int StatsTestCounterReg04() -{ - StatsPublicThreadContext pctx; - int result; - - memset(&pctx, 0, sizeof(StatsPublicThreadContext)); - - RegisterCounter("t1", "c1", &pctx); - RegisterCounter("t2", "c2", &pctx); - RegisterCounter("t3", "c3", &pctx); - - result = RegisterCounter("t1", "c1", &pctx); - - StatsReleaseCounters(pctx.head); - - return result; -} - -static int StatsTestGetCntArray05() -{ - ThreadVars tv; - int id; - - memset(&tv, 0, sizeof(ThreadVars)); - - id = RegisterCounter("t1", "c1", &tv.perf_public_ctx); - if (id != 1) { - printf("id %d: ", id); - return 0; - } - - int r = StatsGetAllCountersArray(NULL, &tv.perf_private_ctx); - return (r == -1) ? 1 : 0; -} - -static int StatsTestGetCntArray06() -{ - ThreadVars tv; - int id; - int result; - - memset(&tv, 0, sizeof(ThreadVars)); - - id = RegisterCounter("t1", "c1", &tv.perf_public_ctx); - if (id != 1) - return 0; - - int r = StatsGetAllCountersArray(&tv.perf_public_ctx, &tv.perf_private_ctx); - - result = (r == 0) ? 1 : 0; - - StatsReleaseCounters(tv.perf_public_ctx.head); - StatsReleasePrivateThreadContext(&tv.perf_private_ctx); - - return result; -} - -static int StatsTestCntArraySize07() -{ - ThreadVars tv; - StatsPrivateThreadContext *pca = NULL; - int result; - - memset(&tv, 0, sizeof(ThreadVars)); - - //pca = (StatsPrivateThreadContext *)&tv.perf_private_ctx; - - RegisterCounter("t1", "c1", &tv.perf_public_ctx); - RegisterCounter("t2", "c2", &tv.perf_public_ctx); - - StatsGetAllCountersArray(&tv.perf_public_ctx, &tv.perf_private_ctx); - pca = &tv.perf_private_ctx; - - StatsIncr(&tv, 1); - StatsIncr(&tv, 2); - - result = pca->size; - - StatsReleaseCounters(tv.perf_public_ctx.head); - StatsReleasePrivateThreadContext(pca); - - return result; -} - -static int StatsTestUpdateCounter08() -{ - ThreadVars tv; - StatsPrivateThreadContext *pca = NULL; - int id; - int result; - - memset(&tv, 0, sizeof(ThreadVars)); - - id = RegisterCounter("t1", "c1", &tv.perf_public_ctx); - - StatsGetAllCountersArray(&tv.perf_public_ctx, &tv.perf_private_ctx); - pca = &tv.perf_private_ctx; - - StatsIncr(&tv, id); - StatsAddUI64(&tv, id, 100); - - result = pca->head[id].value; - - StatsReleaseCounters(tv.perf_public_ctx.head); - StatsReleasePrivateThreadContext(pca); - - return result; -} - -static int StatsTestUpdateCounter09() -{ - ThreadVars tv; - StatsPrivateThreadContext *pca = NULL; - uint16_t id1, id2; - int result; - - memset(&tv, 0, sizeof(ThreadVars)); - - id1 = RegisterCounter("t1", "c1", &tv.perf_public_ctx); - RegisterCounter("t2", "c2", &tv.perf_public_ctx); - RegisterCounter("t3", "c3", &tv.perf_public_ctx); - RegisterCounter("t4", "c4", &tv.perf_public_ctx); - id2 = RegisterCounter("t5", "c5", &tv.perf_public_ctx); - - StatsGetAllCountersArray(&tv.perf_public_ctx, &tv.perf_private_ctx); - pca = &tv.perf_private_ctx; - - StatsIncr(&tv, id2); - StatsAddUI64(&tv, id2, 100); - - result = (pca->head[id1].value == 0) && (pca->head[id2].value == 101); - - StatsReleaseCounters(tv.perf_public_ctx.head); - StatsReleasePrivateThreadContext(pca); - - return result; -} - -static int StatsTestUpdateGlobalCounter10() -{ - ThreadVars tv; - StatsPrivateThreadContext *pca = NULL; - - int result = 1; - uint16_t id1, id2, id3; - - memset(&tv, 0, sizeof(ThreadVars)); - - id1 = RegisterCounter("t1", "c1", &tv.perf_public_ctx); - id2 = RegisterCounter("t2", "c2", &tv.perf_public_ctx); - id3 = RegisterCounter("t3", "c3", &tv.perf_public_ctx); - - StatsGetAllCountersArray(&tv.perf_public_ctx, &tv.perf_private_ctx); - pca = &tv.perf_private_ctx; - - StatsIncr(&tv, id1); - StatsAddUI64(&tv, id2, 100); - StatsIncr(&tv, id3); - StatsAddUI64(&tv, id3, 100); - - StatsUpdateCounterArray(pca, &tv.perf_public_ctx); - - result = (1 == tv.perf_public_ctx.head->value); - result &= (100 == tv.perf_public_ctx.head->next->value); - result &= (101 == tv.perf_public_ctx.head->next->next->value); - - StatsReleaseCounters(tv.perf_public_ctx.head); - StatsReleasePrivateThreadContext(pca); - - return result; -} - -static int StatsTestCounterValues11() -{ - ThreadVars tv; - StatsPrivateThreadContext *pca = NULL; - - int result = 1; - uint16_t id1, id2, id3, id4; - - memset(&tv, 0, sizeof(ThreadVars)); - - id1 = RegisterCounter("t1", "c1", &tv.perf_public_ctx); - id2 = RegisterCounter("t2", "c2", &tv.perf_public_ctx); - id3 = RegisterCounter("t3", "c3", &tv.perf_public_ctx); - id4 = RegisterCounter("t4", "c4", &tv.perf_public_ctx); - - StatsGetAllCountersArray(&tv.perf_public_ctx, &tv.perf_private_ctx); - pca = &tv.perf_private_ctx; - - StatsIncr(&tv, id1); - StatsAddUI64(&tv, id2, 256); - StatsAddUI64(&tv, id3, 257); - StatsAddUI64(&tv, id4, 16843024); - - StatsUpdateCounterArray(pca, &tv.perf_public_ctx); - - result &= (1 == tv.perf_public_ctx.head->value); - - result &= (256 == tv.perf_public_ctx.head->next->value); - - result &= (257 == tv.perf_public_ctx.head->next->next->value); - - result &= (16843024 == tv.perf_public_ctx.head->next->next->next->value); - - StatsReleaseCounters(tv.perf_public_ctx.head); - StatsReleasePrivateThreadContext(pca); - - return result; -} - -#endif - -void StatsRegisterTests() -{ -#ifdef UNITTESTS - UtRegisterTest("StatsTestCounterReg02", StatsTestCounterReg02, 0); - UtRegisterTest("StatsTestCounterReg03", StatsTestCounterReg03, 1); - UtRegisterTest("StatsTestCounterReg04", StatsTestCounterReg04, 1); - UtRegisterTest("StatsTestGetCntArray05", StatsTestGetCntArray05, 1); - UtRegisterTest("StatsTestGetCntArray06", StatsTestGetCntArray06, 1); - UtRegisterTest("StatsTestCntArraySize07", StatsTestCntArraySize07, 2); - UtRegisterTest("StatsTestUpdateCounter08", StatsTestUpdateCounter08, 101); - UtRegisterTest("StatsTestUpdateCounter09", StatsTestUpdateCounter09, 1); - UtRegisterTest("StatsTestUpdateGlobalCounter10", - StatsTestUpdateGlobalCounter10, 1); - UtRegisterTest("StatsTestCounterValues11", StatsTestCounterValues11, 1); -#endif -} diff --git a/framework/src/suricata/src/counters.h b/framework/src/suricata/src/counters.h deleted file mode 100644 index 023d15aa..00000000 --- a/framework/src/suricata/src/counters.h +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright (C) 2007-2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Victor Julien - */ - -#ifndef __COUNTERS_H__ -#define __COUNTERS_H__ - -/* forward declaration of the ThreadVars structure */ -struct ThreadVars_; - -/** - * \brief Container to hold the counter variable - */ -typedef struct StatsCounter_ { - int type; - - /* local id for this counter in this thread */ - uint16_t id; - - /* global id, used in output */ - uint16_t gid; - - /* counter value(s): copies from the 'private' counter */ - uint64_t value; /**< sum of updates/increments, or 'set' value */ - uint64_t updates; /**< number of updates (for avg) */ - - /* when using type STATS_TYPE_Q_FUNC this function is called once - * to get the counter value, regardless of how many threads there are. */ - uint64_t (*Func)(void); - - /* name of the counter */ - const char *name; - - /* the next perfcounter for this tv's tm instance */ - struct StatsCounter_ *next; -} StatsCounter; - -/** - * \brief Stats Context for a ThreadVars instance - */ -typedef struct StatsPublicThreadContext_ { - /* flag set by the wakeup thread, to inform the client threads to sync */ - uint32_t perf_flag; - - /* pointer to the head of a list of counters assigned under this context */ - StatsCounter *head; - - /* holds the total no of counters already assigned for this perf context */ - uint16_t curr_id; - - /* mutex to prevent simultaneous access during update_counter/output_stat */ - SCMutex m; -} StatsPublicThreadContext; - -/** - * \brief Storage for local counters, with a link to the public counter used - * for syncs - */ -typedef struct StatsLocalCounter_ { - /* pointer to the counter that corresponds to this local counter */ - StatsCounter *pc; - - /* local counter id of the above counter */ - uint16_t id; - - /* total value of the adds/increments, or exact value in case of 'set' */ - uint64_t value; - - /* no of times the local counter has been updated */ - uint64_t updates; -} StatsLocalCounter; - -/** - * \brief used to hold the private version of the counters registered - */ -typedef struct StatsPrivateThreadContext_ { - /* points to the array holding local counters */ - StatsLocalCounter *head; - - /* size of head array in elements */ - uint32_t size; - - int initialized; -} StatsPrivateThreadContext; - -/* the initialization functions */ -void StatsInit(void); -void StatsSetupPostConfig(void); -void StatsSpawnThreads(void); -void StatsRegisterTests(void); - -/* functions used to free the resources alloted by the Stats API */ -void StatsReleaseResources(void); - -/* counter registration functions */ -uint16_t StatsRegisterCounter(char *, struct ThreadVars_ *); -uint16_t StatsRegisterAvgCounter(char *, struct ThreadVars_ *); -uint16_t StatsRegisterMaxCounter(char *, struct ThreadVars_ *); -uint16_t StatsRegisterGlobalCounter(char *cname, uint64_t (*Func)(void)); - -/* functions used to update local counter values */ -void StatsAddUI64(struct ThreadVars_ *, uint16_t, uint64_t); -void StatsSetUI64(struct ThreadVars_ *, uint16_t, uint64_t); -void StatsIncr(struct ThreadVars_ *, uint16_t); - -/* utility functions */ -int StatsUpdateCounterArray(StatsPrivateThreadContext *, StatsPublicThreadContext *); -uint64_t StatsGetLocalCounterValue(struct ThreadVars_ *, uint16_t); -int StatsSetupPrivate(struct ThreadVars_ *); -void StatsThreadCleanup(struct ThreadVars_ *); - -#define StatsSyncCounters(tv) \ - StatsUpdateCounterArray(&(tv)->perf_private_ctx, &(tv)->perf_public_ctx); \ - -#define StatsSyncCountersIfSignalled(tv) \ - do { \ - if ((tv)->perf_public_ctx.perf_flag == 1) { \ - StatsUpdateCounterArray(&(tv)->perf_private_ctx, \ - &(tv)->perf_public_ctx); \ - } \ - } while (0) - -#ifdef BUILD_UNIX_SOCKET -#include -TmEcode StatsOutputCounterSocket(json_t *cmd, - json_t *answer, void *data); -#endif - -#endif /* __COUNTERS_H__ */ - diff --git a/framework/src/suricata/src/data-queue.c b/framework/src/suricata/src/data-queue.c deleted file mode 100644 index a3afd4ac..00000000 --- a/framework/src/suricata/src/data-queue.c +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (c) 2009, 2010 Open Information Security Foundation. - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "data-queue.h" -#include "threads.h" - -/** - * \brief Enqueues data on the queue. - * - * \param q Pointer to the data queue. - * \param data Pointer to the data to be queued. It should be a pointer to a - * structure instance that implements the template structure - * struct SCDQGenericQData_ defined in data-queue.h. - */ -void SCDQDataEnqueue(SCDQDataQueue *q, SCDQGenericQData *data) -{ - /* we already have some data in queue */ - if (q->top != NULL) { - data->next = q->top; - q->top->prev = data; - q->top = data; - - /* the queue is empty */ - } else { - q->top = data; - q->bot = data; - } - - q->len++; - -#ifdef DBG_PERF - if (q->len > q->dbg_maxlen) - q->dbg_maxlen = q->len; -#endif /* DBG_PERF */ - - return; -} - -/** - * \brief Dequeues and returns an entry from the queue. - * - * \param q Pointer to the data queue. - * \param retval Pointer to the data that has been enqueued. The instance - * returned is/should be a pointer to a structure instance that - * implements the template structure struct SCDQGenericQData_ - * defined in data-queue.h. - */ -SCDQGenericQData *SCDQDataDequeue(SCDQDataQueue *q) -{ - SCDQGenericQData *data = NULL; - - /* if the queue is empty there are is no data left and we return NULL */ - if (q->len == 0) { - return NULL; - } - - /* If we are going to get the last packet, set len to 0 - * before doing anything else (to make the threads to follow - * the SCondWait as soon as possible) */ - q->len--; - - /* pull the bottom packet from the queue */ - data = q->bot; - -#ifdef OS_DARWIN - /* Weird issue in OS_DARWIN - * Sometimes it looks that two thread arrive here at the same time - * so the bot ptr is NULL */ - if (data == NULL) { - printf("No data to dequeue!\n"); - return NULL; - } -#endif /* OS_DARWIN */ - - /* more data in queue */ - if (q->bot->prev != NULL) { - q->bot = q->bot->prev; - q->bot->next = NULL; - /* just the one we remove, so now empty */ - } else { - q->top = NULL; - q->bot = NULL; - } - - data->next = NULL; - data->prev = NULL; - - return data; -} diff --git a/framework/src/suricata/src/data-queue.h b/framework/src/suricata/src/data-queue.h deleted file mode 100644 index f1f6bb38..00000000 --- a/framework/src/suricata/src/data-queue.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright (c) 2009, 2010 Open Information Security Foundation. - * - * \author Anoop Saldanha - * - * \file Generic queues. Any instance that wants to get itself on the generic - * queue, would have to implement the template struct SCDQGenericQData_ - * defined below. - */ - -#ifndef __DATA_QUEUE_H__ -#define __DATA_QUEUE_H__ - -#include "threads.h" - -/** - * \brief Generic template for any data structure that wants to be on the - * queue. Any other data structure that wants to be on the queue - * needs to use this template and define its own members from - * onwards. - */ -typedef struct SCDQGenericQData_ { - /* this is needed when we want to supply a list of data items */ - struct SCDQGenericQData_ *next; - struct SCDQGenericQData_ *prev; - /* if we want to consider this pointer as the head of a list, this var - * holds the no of elements in the list. Else it holds a . */ - //uint16_t len; - /* in case this data instance is the head of a list, we can refer the - * bottomost instance directly using this var */ - //struct SCDQGenericaQData *bot; - - - /* any other data structure that wants to be on the queue can implement - * its own memebers from here on, in its structure definition. Just note - * that the first 2 members should always be next and prev in the same - * order */ - // -} SCDQGenericQData; - -/** - * \brief The data queue to hold instances that implement the template - * SCDQGenericQData. - */ -typedef struct SCDQDataQueue_ { - /* holds the item at the top of the queue */ - SCDQGenericQData *top; - /* holds the item at the bottom of the queue */ - SCDQGenericQData *bot; - /* no of items currently in the queue */ - uint16_t len; -#ifdef DBG_PERF - uint16_t dbg_maxlen; -#endif /* DBG_PERF */ - - SCMutex mutex_q; - SCCondT cond_q; - -} __attribute__((aligned(CLS))) SCDQDataQueue; - -void SCDQDataEnqueue(SCDQDataQueue *, SCDQGenericQData *); -SCDQGenericQData *SCDQDataDequeue(SCDQDataQueue *); - -#endif /* __DATA_QUEUE_H__ */ diff --git a/framework/src/suricata/src/debug.h b/framework/src/suricata/src/debug.h deleted file mode 100644 index 839d48d3..00000000 --- a/framework/src/suricata/src/debug.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DEBUG_H__ -#define __DEBUG_H__ - -#ifdef DEBUG - -#endif /* DEBUG */ -#endif /* __DEBUG_H__ */ - diff --git a/framework/src/suricata/src/decode-erspan.c b/framework/src/suricata/src/decode-erspan.c deleted file mode 100644 index f2fb0eb1..00000000 --- a/framework/src/suricata/src/decode-erspan.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decodes ERSPAN - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "decode-events.h" -#include "decode-erspan.h" - -#include "util-unittest.h" -#include "util-debug.h" - -/** - * \brief Function to decode ERSPAN packets - */ - -int DecodeERSPAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_erspan); - - if (len < sizeof(ErspanHdr)) { - ENGINE_SET_EVENT(p,ERSPAN_HEADER_TOO_SMALL); - return TM_ECODE_FAILED; - } - - const ErspanHdr *ehdr = (const ErspanHdr *)pkt; - uint16_t version = ntohs(ehdr->ver_vlan) >> 12; - uint16_t vlan_id = ntohs(ehdr->ver_vlan) & 0x0fff; - - SCLogDebug("ERSPAN: version %u vlan %u", version, vlan_id); - - /* only v1 is tested at this time */ - if (version != 1) { - ENGINE_SET_EVENT(p,ERSPAN_UNSUPPORTED_VERSION); - return TM_ECODE_FAILED; - } - - if (vlan_id > 0 && dtv->vlan_disabled == 0) { - if (p->vlan_idx >= 2) { - ENGINE_SET_EVENT(p,ERSPAN_TOO_MANY_VLAN_LAYERS); - return TM_ECODE_FAILED; - } - p->vlan_id[p->vlan_idx] = vlan_id; - p->vlan_idx++; - } - - return DecodeEthernet(tv, dtv, p, pkt + sizeof(ErspanHdr), len - sizeof(ErspanHdr), pq); -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-erspan.h b/framework/src/suricata/src/decode-erspan.h deleted file mode 100644 index 2f81d1e4..00000000 --- a/framework/src/suricata/src/decode-erspan.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#ifndef __DECODE_ERSPAN_H__ -#define __DECODE_ERSPAN_H__ - -#include "decode.h" -#include "threadvars.h" - -typedef struct ErspanHdr_ { - uint16_t ver_vlan; - uint16_t flags_spanid; - uint32_t padding; -} __attribute__((__packed__)) ErspanHdr; - -#endif /* __DECODE_ERSPAN_H__ */ diff --git a/framework/src/suricata/src/decode-ethernet.c b/framework/src/suricata/src/decode-ethernet.c deleted file mode 100644 index ee415723..00000000 --- a/framework/src/suricata/src/decode-ethernet.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decode Ethernet - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-ethernet.h" -#include "decode-events.h" - -#include "util-unittest.h" -#include "util-debug.h" - -int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, - uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_eth); - - if (unlikely(len < ETHERNET_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, ETHERNET_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - p->ethh = (EthernetHdr *)pkt; - if (unlikely(p->ethh == NULL)) - return TM_ECODE_FAILED; - - SCLogDebug("p %p pkt %p ether type %04x", p, pkt, ntohs(p->ethh->eth_type)); - - switch (ntohs(p->ethh->eth_type)) { - case ETHERNET_TYPE_IP: - //printf("DecodeEthernet ip4\n"); - DecodeIPV4(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, - len - ETHERNET_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_IPV6: - //printf("DecodeEthernet ip6\n"); - DecodeIPV6(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, - len - ETHERNET_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_PPPOE_SESS: - //printf("DecodeEthernet PPPOE Session\n"); - DecodePPPOESession(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, - len - ETHERNET_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_PPPOE_DISC: - //printf("DecodeEthernet PPPOE Discovery\n"); - DecodePPPOEDiscovery(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, - len - ETHERNET_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_VLAN: - case ETHERNET_TYPE_8021QINQ: - DecodeVLAN(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, - len - ETHERNET_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_MPLS_UNICAST: - case ETHERNET_TYPE_MPLS_MULTICAST: - DecodeMPLS(tv, dtv, p, pkt + ETHERNET_HEADER_LEN, - len - ETHERNET_HEADER_LEN, pq); - break; - default: - SCLogDebug("p %p pkt %p ether type %04x not supported", p, - pkt, ntohs(p->ethh->eth_type)); - } - - return TM_ECODE_OK; -} - -#ifdef UNITTESTS -/** DecodeEthernettest01 - * \brief Valid Ethernet packet - * \retval 0 Expected test value - */ -static int DecodeEthernetTest01 (void) -{ - /* ICMP packet wrapped in PPPOE */ - uint8_t raw_eth[] = { - 0x00, 0x10, 0x94, 0x55, 0x00, 0x01, 0x00, 0x10, - 0x94, 0x56, 0x00, 0x01, 0x88, 0x64, 0x11, 0x00, - 0x00, 0x01, 0x00, 0x68, 0x00, 0x21, 0x45, 0xc0, - 0x00, 0x64, 0x00, 0x1e, 0x00, 0x00, 0xff, 0x01, - 0xa7, 0x78, 0x0a, 0x00, 0x00, 0x02, 0x0a, 0x00, - 0x00, 0x01, 0x08, 0x00, 0x4a, 0x61, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, - 0x3b, 0xd4, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - - DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth), NULL); - - SCFree(p); - return 0; -} -#endif /* UNITTESTS */ - - -/** - * \brief Registers Ethernet unit tests - * \todo More Ethernet tests - */ -void DecodeEthernetRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodeEthernetTest01", DecodeEthernetTest01, 0); -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-ethernet.h b/framework/src/suricata/src/decode-ethernet.h deleted file mode 100644 index f8ede880..00000000 --- a/framework/src/suricata/src/decode-ethernet.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DECODE_ETHERNET_H__ -#define __DECODE_ETHERNET_H__ - -#define ETHERNET_HEADER_LEN 14 - -/* Ethernet types -- taken from Snort and Libdnet */ -#define ETHERNET_TYPE_PUP 0x0200 /* PUP protocol */ -#define ETHERNET_TYPE_IP 0x0800 -#define ETHERNET_TYPE_ARP 0x0806 -#define ETHERNET_TYPE_REVARP 0x8035 -#define ETHERNET_TYPE_EAPOL 0x888e -#define ETHERNET_TYPE_IPV6 0x86dd -#define ETHERNET_TYPE_IPX 0x8137 -#define ETHERNET_TYPE_PPPOE_DISC 0x8863 /* discovery stage */ -#define ETHERNET_TYPE_PPPOE_SESS 0x8864 /* session stage */ -#define ETHERNET_TYPE_8021AD 0x88a8 -#define ETHERNET_TYPE_8021Q 0x8100 -#define ETHERNET_TYPE_LOOP 0x9000 -#define ETHERNET_TYPE_8021QINQ 0x9100 -#define ETHERNET_TYPE_ERSPAN 0x88BE - -typedef struct EthernetHdr_ { - uint8_t eth_dst[6]; - uint8_t eth_src[6]; - uint16_t eth_type; -} __attribute__((__packed__)) EthernetHdr; - -#endif /* __DECODE_ETHERNET_H__ */ - diff --git a/framework/src/suricata/src/decode-events.c b/framework/src/suricata/src/decode-events.c deleted file mode 100644 index cecf77c5..00000000 --- a/framework/src/suricata/src/decode-events.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" - -/* code moved to app-layer-events */ - diff --git a/framework/src/suricata/src/decode-events.h b/framework/src/suricata/src/decode-events.h deleted file mode 100644 index c16d0d92..00000000 --- a/framework/src/suricata/src/decode-events.h +++ /dev/null @@ -1,252 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#ifndef __DECODE_EVENTS_H__ -#define __DECODE_EVENTS_H__ - -/* packet decoder events */ -enum { - /* IPV4 EVENTS */ - IPV4_PKT_TOO_SMALL = 1, /**< ipv4 pkt smaller than minimum header size */ - IPV4_HLEN_TOO_SMALL, /**< ipv4 header smaller than minimum size */ - IPV4_IPLEN_SMALLER_THAN_HLEN, /**< ipv4 pkt len smaller than ip header size */ - IPV4_TRUNC_PKT, /**< truncated ipv4 packet */ - - /* IPV4 OPTIONS */ - IPV4_OPT_INVALID, /**< invalid ip options */ - IPV4_OPT_INVALID_LEN, /**< ip options with invalid len */ - IPV4_OPT_MALFORMED, /**< malformed ip options */ - IPV4_OPT_PAD_REQUIRED, /**< pad bytes are needed in ip options */ - IPV4_OPT_EOL_REQUIRED, /**< "end of list" needed in ip options */ - IPV4_OPT_DUPLICATE, /**< duplicated ip option */ - IPV4_OPT_UNKNOWN, /**< unknown ip option */ - IPV4_WRONG_IP_VER, /**< wrong ip version in ip options */ - IPV4_WITH_ICMPV6, /**< IPv4 packet with ICMPv6 header */ - - /* ICMP EVENTS */ - ICMPV4_PKT_TOO_SMALL, /**< icmpv4 packet smaller than minimum size */ - ICMPV4_UNKNOWN_TYPE, /**< icmpv4 unknown type */ - ICMPV4_UNKNOWN_CODE, /**< icmpv4 unknown code */ - ICMPV4_IPV4_TRUNC_PKT, /**< truncated icmpv4 packet */ - ICMPV4_IPV4_UNKNOWN_VER, /**< unknown version in icmpv4 packet*/ - - /* ICMPv6 EVENTS */ - ICMPV6_UNKNOWN_TYPE, /**< icmpv6 unknown type */ - ICMPV6_UNKNOWN_CODE, /**< icmpv6 unknown code */ - ICMPV6_PKT_TOO_SMALL, /**< icmpv6 smaller than minimum size */ - ICMPV6_IPV6_UNKNOWN_VER, /**< unknown version in icmpv6 packet */ - ICMPV6_IPV6_TRUNC_PKT, /**< truncated icmpv6 packet */ - ICMPV6_MLD_MESSAGE_WITH_INVALID_HL, /**< invalid MLD that doesn't have HL 1 */ - - /* IPV6 EVENTS */ - IPV6_PKT_TOO_SMALL, /**< ipv6 packet smaller than minimum size */ - IPV6_TRUNC_PKT, /**< truncated ipv6 packet */ - IPV6_TRUNC_EXTHDR, /**< truncated ipv6 extension header */ - IPV6_EXTHDR_DUPL_FH, /**< duplicated "fragment" header in ipv6 extension headers */ - IPV6_EXTHDR_USELESS_FH, /**< useless FH: offset 0 + no more fragments */ - IPV6_EXTHDR_DUPL_RH, /**< duplicated "routing" header in ipv6 extension headers */ - IPV6_EXTHDR_DUPL_HH, /**< duplicated "hop-by-hop" header in ipv6 extension headers */ - IPV6_EXTHDR_DUPL_DH, /**< duplicated "destination" header in ipv6 extension headers */ - IPV6_EXTHDR_DUPL_AH, /**< duplicated "authentication" header in ipv6 extension headers */ - IPV6_EXTHDR_DUPL_EH, /**< duplicated "ESP" header in ipv6 extension headers */ - - IPV6_EXTHDR_INVALID_OPTLEN, /**< the opt len in an hop or dst hdr is invalid. */ - IPV6_WRONG_IP_VER, /**< wrong version in ipv6 */ - IPV6_EXTHDR_AH_RES_NOT_NULL, /**< AH hdr reserved fields not null (rfc 4302) */ - - IPV6_HOPOPTS_UNKNOWN_OPT, /**< unknown HOP opt */ - IPV6_HOPOPTS_ONLY_PADDING, /**< all options in HOP opts are padding */ - IPV6_DSTOPTS_UNKNOWN_OPT, /**< unknown DST opt */ - IPV6_DSTOPTS_ONLY_PADDING, /**< all options in DST opts are padding */ - - IPV6_EXTHDR_RH_TYPE_0, /**< RH 0 is deprecated as per rfc5095 */ - IPV6_EXTHDR_ZERO_LEN_PADN, /**< padN w/o data (0 len) */ - IPV6_FH_NON_ZERO_RES_FIELD, /**< reserved field not zero */ - IPV6_DATA_AFTER_NONE_HEADER, /**< data after 'none' (59) header */ - - IPV6_UNKNOWN_NEXT_HEADER, /**< unknown/unsupported next header */ - IPV6_WITH_ICMPV4, /**< IPv6 packet with ICMPv4 header */ - - /* TCP EVENTS */ - TCP_PKT_TOO_SMALL, /**< tcp packet smaller than minimum size */ - TCP_HLEN_TOO_SMALL, /**< tcp header smaller than minimum size */ - TCP_INVALID_OPTLEN, /**< invalid len in tcp options */ - - /* TCP OPTIONS */ - TCP_OPT_INVALID_LEN, /**< tcp option with invalid len */ - TCP_OPT_DUPLICATE, /**< duplicated tcp option */ - - /* UDP EVENTS */ - UDP_PKT_TOO_SMALL, /**< udp packet smaller than minimum size */ - UDP_HLEN_TOO_SMALL, /**< udp header smaller than minimum size */ - UDP_HLEN_INVALID, /**< invalid len of upd header */ - - /* SLL EVENTS */ - SLL_PKT_TOO_SMALL, /**< sll packet smaller than minimum size */ - - /* ETHERNET EVENTS */ - ETHERNET_PKT_TOO_SMALL, /**< ethernet packet smaller than minimum size */ - - /* PPP EVENTS */ - PPP_PKT_TOO_SMALL, /**< ppp packet smaller than minimum size */ - PPPVJU_PKT_TOO_SMALL, /**< ppp vj uncompressed packet smaller than minimum size */ - PPPIPV4_PKT_TOO_SMALL, /**< ppp ipv4 packet smaller than minimum size */ - PPPIPV6_PKT_TOO_SMALL, /**< ppp ipv6 packet smaller than minimum size */ - PPP_WRONG_TYPE, /**< wrong type in ppp frame */ - PPP_UNSUP_PROTO, /**< protocol not supported for ppp */ - - /* PPPOE EVENTS */ - PPPOE_PKT_TOO_SMALL, /**< pppoe packet smaller than minimum size */ - PPPOE_WRONG_CODE, /**< wrong code for pppoe */ - PPPOE_MALFORMED_TAGS, /**< malformed tags in pppoe */ - - /* GRE EVENTS */ - GRE_PKT_TOO_SMALL, /**< gre packet smaller than minimum size */ - GRE_WRONG_VERSION, /**< wrong version in gre header */ - GRE_VERSION0_RECUR, /**< gre v0 recursion control */ - GRE_VERSION0_FLAGS, /**< gre v0 flags */ - GRE_VERSION0_HDR_TOO_BIG, /**< gre v0 header bigger than maximum size */ - GRE_VERSION0_MALFORMED_SRE_HDR, /**< gre v0 malformed source route entry header */ - GRE_VERSION1_CHKSUM, /**< gre v1 checksum */ - GRE_VERSION1_ROUTE, /**< gre v1 routing */ - GRE_VERSION1_SSR, /**< gre v1 strict source route */ - GRE_VERSION1_RECUR, /**< gre v1 recursion control */ - GRE_VERSION1_FLAGS, /**< gre v1 flags */ - GRE_VERSION1_NO_KEY, /**< gre v1 no key present in header */ - GRE_VERSION1_WRONG_PROTOCOL, /**< gre v1 wrong protocol */ - GRE_VERSION1_MALFORMED_SRE_HDR, /**< gre v1 malformed source route entry header */ - GRE_VERSION1_HDR_TOO_BIG, /**< gre v1 header too big */ - - /* VLAN EVENTS */ - VLAN_HEADER_TOO_SMALL, /**< vlan header smaller than minimum size */ - VLAN_UNKNOWN_TYPE, /**< vlan unknown type */ - VLAN_HEADER_TOO_MANY_LAYERS, - - /* RAW EVENTS */ - IPRAW_INVALID_IPV, /**< invalid ip version in ip raw */ - - /* LINKTYPE NULL EVENTS */ - LTNULL_PKT_TOO_SMALL, /**< pkt too small for lt:null */ - LTNULL_UNSUPPORTED_TYPE, /**< pkt has a type that the decoder doesn't support */ - - /* STREAM EVENTS */ - STREAM_3WHS_ACK_IN_WRONG_DIR, - STREAM_3WHS_ASYNC_WRONG_SEQ, - STREAM_3WHS_RIGHT_SEQ_WRONG_ACK_EVASION, - STREAM_3WHS_SYNACK_IN_WRONG_DIRECTION, - STREAM_3WHS_SYNACK_RESEND_WITH_DIFFERENT_ACK, - STREAM_3WHS_SYNACK_RESEND_WITH_DIFF_SEQ, - STREAM_3WHS_SYNACK_TOSERVER_ON_SYN_RECV, - STREAM_3WHS_SYNACK_WITH_WRONG_ACK, - STREAM_3WHS_SYNACK_FLOOD, - STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV, - STREAM_3WHS_SYN_TOCLIENT_ON_SYN_RECV, - STREAM_3WHS_WRONG_SEQ_WRONG_ACK, - STREAM_4WHS_SYNACK_WITH_WRONG_ACK, - STREAM_4WHS_SYNACK_WITH_WRONG_SYN, - STREAM_4WHS_WRONG_SEQ, - STREAM_4WHS_INVALID_ACK, - STREAM_CLOSEWAIT_ACK_OUT_OF_WINDOW, - STREAM_CLOSEWAIT_FIN_OUT_OF_WINDOW, - STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK, - STREAM_CLOSEWAIT_INVALID_ACK, - STREAM_CLOSING_ACK_WRONG_SEQ, - STREAM_CLOSING_INVALID_ACK, - STREAM_EST_PACKET_OUT_OF_WINDOW, - STREAM_EST_PKT_BEFORE_LAST_ACK, - STREAM_EST_SYNACK_RESEND, - STREAM_EST_SYNACK_RESEND_WITH_DIFFERENT_ACK, - STREAM_EST_SYNACK_RESEND_WITH_DIFF_SEQ, - STREAM_EST_SYNACK_TOSERVER, - STREAM_EST_SYN_RESEND, - STREAM_EST_SYN_RESEND_DIFF_SEQ, - STREAM_EST_SYN_TOCLIENT, - STREAM_EST_INVALID_ACK, - STREAM_FIN_INVALID_ACK, - STREAM_FIN1_ACK_WRONG_SEQ, - STREAM_FIN1_FIN_WRONG_SEQ, - STREAM_FIN1_INVALID_ACK, - STREAM_FIN2_ACK_WRONG_SEQ, - STREAM_FIN2_FIN_WRONG_SEQ, - STREAM_FIN2_INVALID_ACK, - STREAM_FIN_BUT_NO_SESSION, - STREAM_FIN_OUT_OF_WINDOW, - STREAM_LASTACK_ACK_WRONG_SEQ, - STREAM_LASTACK_INVALID_ACK, - STREAM_RST_BUT_NO_SESSION, - STREAM_TIMEWAIT_ACK_WRONG_SEQ, - STREAM_TIMEWAIT_INVALID_ACK, - STREAM_SHUTDOWN_SYN_RESEND, - STREAM_PKT_INVALID_TIMESTAMP, - STREAM_PKT_INVALID_ACK, - STREAM_PKT_BROKEN_ACK, - STREAM_RST_INVALID_ACK, - STREAM_PKT_RETRANSMISSION, - STREAM_PKT_BAD_WINDOW_UPDATE, - - STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ, - STREAM_REASSEMBLY_NO_SEGMENT, - - STREAM_REASSEMBLY_SEQ_GAP, - - STREAM_REASSEMBLY_OVERLAP_DIFFERENT_DATA, - - /* SCTP EVENTS */ - SCTP_PKT_TOO_SMALL, /**< sctp packet smaller than minimum size */ - - /* Fragmentation reasembly events. */ - IPV4_FRAG_PKT_TOO_LARGE, - IPV6_FRAG_PKT_TOO_LARGE, - IPV4_FRAG_OVERLAP, - IPV6_FRAG_OVERLAP, - IPV4_FRAG_TOO_LARGE, - IPV6_FRAG_TOO_LARGE, - /* Fragment ignored due to internal error */ - IPV4_FRAG_IGNORED, - IPV6_FRAG_IGNORED, - - /* IPv4 in IPv6 events */ - IPV4_IN_IPV6_PKT_TOO_SMALL, - IPV4_IN_IPV6_WRONG_IP_VER, - /* IPv6 in IPv6 events */ - IPV6_IN_IPV6_PKT_TOO_SMALL, - IPV6_IN_IPV6_WRONG_IP_VER, - - /* MPLS decode events. */ - MPLS_HEADER_TOO_SMALL, - MPLS_BAD_LABEL_ROUTER_ALERT, - MPLS_BAD_LABEL_IMPLICIT_NULL, - MPLS_BAD_LABEL_RESERVED, - MPLS_UNKNOWN_PAYLOAD_TYPE, - - /* ERSPAN events */ - ERSPAN_HEADER_TOO_SMALL, - ERSPAN_UNSUPPORTED_VERSION, - ERSPAN_TOO_MANY_VLAN_LAYERS, - - /* should always be last! */ - DECODE_EVENT_MAX, -}; - -#endif /* __DECODE_EVENTS_H__ */ diff --git a/framework/src/suricata/src/decode-gre.c b/framework/src/suricata/src/decode-gre.c deleted file mode 100644 index 6ad9e397..00000000 --- a/framework/src/suricata/src/decode-gre.c +++ /dev/null @@ -1,400 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Breno Silva - * - * Decodes GRE - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "decode-events.h" -#include "decode-gre.h" - -#include "util-unittest.h" -#include "util-debug.h" - -/** - * \brief Function to decode GRE packets - */ - -int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - uint16_t header_len = GRE_HDR_LEN; - GRESreHdr *gsre = NULL; - - StatsIncr(tv, dtv->counter_gre); - - if(len < GRE_HDR_LEN) { - ENGINE_SET_INVALID_EVENT(p, GRE_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - p->greh = (GREHdr *)pkt; - if(p->greh == NULL) - return TM_ECODE_FAILED; - - SCLogDebug("p %p pkt %p GRE protocol %04x Len: %d GRE version %x", - p, pkt, GRE_GET_PROTO(p->greh), len,GRE_GET_VERSION(p->greh)); - - switch (GRE_GET_VERSION(p->greh)) - { - case GRE_VERSION_0: - - /* GRE version 0 doenst support the fields below RFC 1701 */ - - /** - * \todo We need to make sure this does not allow bypassing - * inspection. A server may just ignore these and - * continue processing the packet, but we will not look - * further into it. - */ - - if (GRE_FLAG_ISSET_RECUR(p->greh)) { - ENGINE_SET_INVALID_EVENT(p, GRE_VERSION0_RECUR); - return TM_ECODE_OK; - } - - if (GREV1_FLAG_ISSET_FLAGS(p->greh)) { - ENGINE_SET_INVALID_EVENT(p, GRE_VERSION0_FLAGS); - return TM_ECODE_OK; - } - - /* Adjust header length based on content */ - - if (GRE_FLAG_ISSET_KY(p->greh)) - header_len += GRE_KEY_LEN; - - if (GRE_FLAG_ISSET_SQ(p->greh)) - header_len += GRE_SEQ_LEN; - - if (GRE_FLAG_ISSET_CHKSUM(p->greh) || GRE_FLAG_ISSET_ROUTE(p->greh)) - header_len += GRE_CHKSUM_LEN + GRE_OFFSET_LEN; - - if (header_len > len) { - ENGINE_SET_INVALID_EVENT(p, GRE_VERSION0_HDR_TOO_BIG); - return TM_ECODE_OK; - } - - if (GRE_FLAG_ISSET_ROUTE(p->greh)) - { - while (1) - { - if ((header_len + GRE_SRE_HDR_LEN) > len) { - ENGINE_SET_INVALID_EVENT(p, - GRE_VERSION0_MALFORMED_SRE_HDR); - return TM_ECODE_OK; - } - - gsre = (GRESreHdr *)(pkt + header_len); - - header_len += GRE_SRE_HDR_LEN; - - if ((ntohs(gsre->af) == 0) && (gsre->sre_length == 0)) - break; - - header_len += gsre->sre_length; - if (header_len > len) { - ENGINE_SET_INVALID_EVENT(p, - GRE_VERSION0_MALFORMED_SRE_HDR); - return TM_ECODE_OK; - } - } - } - break; - - case GRE_VERSION_1: - - /* GRE version 1 doenst support the fields below RFC 1701 */ - - /** - * \todo We need to make sure this does not allow bypassing - * inspection. A server may just ignore these and - * continue processing the packet, but we will not look - * further into it. - */ - - if (GRE_FLAG_ISSET_CHKSUM(p->greh)) { - ENGINE_SET_INVALID_EVENT(p,GRE_VERSION1_CHKSUM); - return TM_ECODE_OK; - } - - if (GRE_FLAG_ISSET_ROUTE(p->greh)) { - ENGINE_SET_INVALID_EVENT(p,GRE_VERSION1_ROUTE); - return TM_ECODE_OK; - } - - if (GRE_FLAG_ISSET_SSR(p->greh)) { - ENGINE_SET_INVALID_EVENT(p,GRE_VERSION1_SSR); - return TM_ECODE_OK; - } - - if (GRE_FLAG_ISSET_RECUR(p->greh)) { - ENGINE_SET_INVALID_EVENT(p,GRE_VERSION1_RECUR); - return TM_ECODE_OK; - } - - if (GREV1_FLAG_ISSET_FLAGS(p->greh)) { - ENGINE_SET_INVALID_EVENT(p,GRE_VERSION1_FLAGS); - return TM_ECODE_OK; - } - - if (GRE_GET_PROTO(p->greh) != GRE_PROTO_PPP) { - ENGINE_SET_INVALID_EVENT(p,GRE_VERSION1_WRONG_PROTOCOL); - return TM_ECODE_OK; - } - - if (!(GRE_FLAG_ISSET_KY(p->greh))) { - ENGINE_SET_INVALID_EVENT(p,GRE_VERSION1_NO_KEY); - return TM_ECODE_OK; - } - - header_len += GRE_KEY_LEN; - - /* Adjust header length based on content */ - - if (GRE_FLAG_ISSET_SQ(p->greh)) - header_len += GRE_SEQ_LEN; - - if (GREV1_FLAG_ISSET_ACK(p->greh)) - header_len += GREV1_ACK_LEN; - - if (header_len > len) { - ENGINE_SET_INVALID_EVENT(p, GRE_VERSION1_HDR_TOO_BIG); - return TM_ECODE_OK; - } - - break; - default: - ENGINE_SET_INVALID_EVENT(p, GRE_WRONG_VERSION); - return TM_ECODE_OK; - } - - switch (GRE_GET_PROTO(p->greh)) - { - case ETHERNET_TYPE_IP: - { - if (pq != NULL) { - Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len, - len - header_len, DECODE_TUNNEL_IPV4, pq); - if (tp != NULL) { - PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE); - PacketEnqueue(pq,tp); - } - } - break; - } - - case GRE_PROTO_PPP: - { - if (pq != NULL) { - Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len, - len - header_len, DECODE_TUNNEL_PPP, pq); - if (tp != NULL) { - PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE); - PacketEnqueue(pq,tp); - } - } - break; - } - - case ETHERNET_TYPE_IPV6: - { - if (pq != NULL) { - Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len, - len - header_len, DECODE_TUNNEL_IPV6, pq); - if (tp != NULL) { - PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE); - PacketEnqueue(pq,tp); - } - } - break; - } - - case ETHERNET_TYPE_VLAN: - { - if (pq != NULL) { - Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len, - len - header_len, DECODE_TUNNEL_VLAN, pq); - if (tp != NULL) { - PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE); - PacketEnqueue(pq,tp); - } - } - break; - } - - case ETHERNET_TYPE_ERSPAN: - { - if (pq != NULL) { - Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + header_len, - len - header_len, DECODE_TUNNEL_ERSPAN, pq); - if (tp != NULL) { - PKT_SET_SRC(tp, PKT_SRC_DECODER_GRE); - PacketEnqueue(pq,tp); - } - } - break; - } - - default: - return TM_ECODE_OK; - } - return TM_ECODE_OK; -} - - -#ifdef UNITTESTS -/** - * \test DecodeGRETest01 is a test for small gre packet - */ - -static int DecodeGREtest01 (void) -{ - - uint8_t raw_gre[] = { 0x00 ,0x6e ,0x62 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodeGRE(&tv, &dtv, p, raw_gre, sizeof(raw_gre), NULL); - - if(ENGINE_ISSET_EVENT(p,GRE_PKT_TOO_SMALL)) { - SCFree(p); - return 1; - } - - SCFree(p); - return 0; -} - -/** - * \test DecodeGRETest02 is a test for wrong gre version - */ - -static int DecodeGREtest02 (void) -{ - uint8_t raw_gre[] = { - 0x00, 0x6e, 0x62, 0xac, 0x40, 0x00, 0x40, 0x2f, - 0xc2, 0xc7, 0x0a, 0x00, 0x00, 0x64, 0x0a, 0x00, - 0x00, 0x8a, 0x30, 0x01, 0x0b, 0x00, 0x4e, 0x00, - 0x00, 0x00, 0x18, 0x4a, 0x50, 0xff, 0x03, 0x00, - 0x21, 0x45, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x40, - 0x00, 0x40, 0x11, 0x94, 0x22, 0x50, 0x7e, 0x2b, - 0x2d, 0xc2, 0x6d, 0x68, 0x68, 0x80, 0x0e, 0x00, - 0x35, 0x00, 0x36, 0x9f, 0x18, 0xdb, 0xc4, 0x01, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x03, 0x73, 0x31, 0x36, 0x09, 0x73, 0x69, - 0x74, 0x65, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x03, - 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodeGRE(&tv, &dtv, p, raw_gre, sizeof(raw_gre), NULL); - - if(ENGINE_ISSET_EVENT(p,GRE_WRONG_VERSION)) { - SCFree(p); - return 1; - } - - SCFree(p); - return 0; -} - - -/** - * \test DecodeGRETest03 is a test for valid gre packet - */ - -static int DecodeGREtest03 (void) -{ - uint8_t raw_gre[] = { - 0x00, 0x6e, 0x62, 0xac, 0x40, 0x00, 0x40, 0x2f, - 0xc2, 0xc7, 0x0a, 0x00, 0x00, 0x64, 0x0a, 0x00, - 0x00, 0x8a, 0x30, 0x01, 0x88, 0x0b, 0x00, 0x4e, - 0x00, 0x00, 0x00, 0x18, 0x4a, 0x50, 0xff, 0x03, - 0x00, 0x21, 0x45, 0x00, 0x00, 0x4a, 0x00, 0x00, - 0x40, 0x00, 0x40, 0x11, 0x94, 0x22, 0x50, 0x7e, - 0x2b, 0x2d, 0xc2, 0x6d, 0x68, 0x68, 0x80, 0x0e, - 0x00, 0x35, 0x00, 0x36, 0x9f, 0x18, 0xdb, 0xc4, - 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x03, 0x73, 0x31, 0x36, 0x09, 0x73, - 0x69, 0x74, 0x65, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x29, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodeGRE(&tv, &dtv, p, raw_gre, sizeof(raw_gre), NULL); - - if(p->greh == NULL) { - SCFree(p); - return 0; - } - - - SCFree(p); - return 1; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for GRE decoder - */ - -void DecodeGRERegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodeGREtest01", DecodeGREtest01, 1); - UtRegisterTest("DecodeGREtest02", DecodeGREtest02, 1); - UtRegisterTest("DecodeGREtest03", DecodeGREtest03, 1); -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-gre.h b/framework/src/suricata/src/decode-gre.h deleted file mode 100644 index 6f3db29d..00000000 --- a/framework/src/suricata/src/decode-gre.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file decode-gre.h - * - * \author Breno Silva - * - * Generic Route Encapsulation (GRE) from RFC 1701. - */ - -#ifndef __DECODE_GRE_H__ -#define __DECODE_GRE_H__ - -#ifndef IPPROTO_GRE -#define IPPROTO_GRE 47 -#endif - -#include "decode.h" -#include "threadvars.h" - -typedef struct GREHdr_ -{ - uint8_t flags; /**< GRE packet flags */ - uint8_t version; /**< GRE version */ - uint16_t ether_type; /**< ether type of the encapsulated traffic */ - -} __attribute__((__packed__)) GREHdr; - -/* Generic Routing Encapsulation Source Route Entries (SREs). - * The header is followed by a variable amount of Routing Information. - */ -typedef struct GRESreHdr_ -{ - uint16_t af; /**< Address family */ - uint8_t sre_offset; - uint8_t sre_length; -} __attribute__((__packed__)) GRESreHdr; - -#define GRE_VERSION_0 0x0000 -#define GRE_VERSION_1 0x0001 - -#define GRE_HDR_LEN 4 -#define GRE_CHKSUM_LEN 2 -#define GRE_OFFSET_LEN 2 -#define GRE_KEY_LEN 4 -#define GRE_SEQ_LEN 4 -#define GRE_SRE_HDR_LEN 4 -#define GRE_PROTO_PPP 0x880b - -#define GRE_FLAG_ISSET_CHKSUM(r) (r->flags & 0x80) -#define GRE_FLAG_ISSET_ROUTE(r) (r->flags & 0x40) -#define GRE_FLAG_ISSET_KY(r) (r->flags & 0x20) -#define GRE_FLAG_ISSET_SQ(r) (r->flags & 0x10) -#define GRE_FLAG_ISSET_SSR(r) (r->flags & 0x08) -#define GRE_FLAG_ISSET_RECUR(r) (r->flags & 0x07) -#define GRE_GET_VERSION(r) (r->version & 0x07) -#define GRE_GET_FLAGS(r) (r->version & 0xF8) -#define GRE_GET_PROTO(r) ntohs(r->ether_type) - -#define GREV1_HDR_LEN 8 -#define GREV1_ACK_LEN 4 -#define GREV1_FLAG_ISSET_FLAGS(r) (r->version & 0x78) -#define GREV1_FLAG_ISSET_ACK(r) (r->version & 0x80) - -void DecodeGRERegisterTests(void); - -#endif /* __DECODE_GRE_H__ */ - diff --git a/framework/src/suricata/src/decode-icmpv4.c b/framework/src/suricata/src/decode-icmpv4.c deleted file mode 100644 index 5af012ce..00000000 --- a/framework/src/suricata/src/decode-icmpv4.c +++ /dev/null @@ -1,784 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decode ICMPv4 - */ - -#include "suricata-common.h" - -#include "decode.h" -#include "decode-events.h" -#include "decode-ipv4.h" -#include "decode-icmpv4.h" - -#include "flow.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" -#include "util-print.h" - -/** - * Note, this is the IP header, plus a bit of the original packet, not the whole thing! - */ -void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) -{ - /** Check the sizes, the header must fit at least */ - if (len < IPV4_HEADER_LEN) { - SCLogDebug("DecodePartialIPV4: ICMPV4_IPV4_TRUNC_PKT"); - ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_TRUNC_PKT); - return; - } - - IPV4Hdr *icmp4_ip4h = (IPV4Hdr*)partial_packet; - - /** Check the embedded version */ - if (IPV4_GET_RAW_VER(icmp4_ip4h) != 4) { - /** Check the embedded version */ - SCLogDebug("DecodePartialIPV4: ICMPv4 contains Unknown IPV4 version " - "ICMPV4_IPV4_UNKNOWN_VER"); - ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_UNKNOWN_VER); - return; - } - - /** We need to fill icmpv4vars */ - p->icmpv4vars.emb_ipv4h = icmp4_ip4h; - - /** Get the IP address from the contained packet */ - p->icmpv4vars.emb_ip4_src = IPV4_GET_RAW_IPSRC(icmp4_ip4h); - p->icmpv4vars.emb_ip4_dst = IPV4_GET_RAW_IPDST(icmp4_ip4h); - - p->icmpv4vars.emb_ip4_hlen=IPV4_GET_RAW_HLEN(icmp4_ip4h) << 2; - - switch (IPV4_GET_RAW_IPPROTO(icmp4_ip4h)) { - case IPPROTO_TCP: - if (len >= IPV4_HEADER_LEN + TCP_HEADER_LEN ) { - p->icmpv4vars.emb_tcph = (TCPHdr*)(partial_packet + IPV4_HEADER_LEN); - p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_tcph->th_sport); - p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_tcph->th_dport); - p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP; - - SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP header sport: " - "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport, - p->icmpv4vars.emb_dport); - } else if (len >= IPV4_HEADER_LEN + 4) { - /* only access th_sport and th_dport */ - TCPHdr *emb_tcph = (TCPHdr*)(partial_packet + IPV4_HEADER_LEN); - - p->icmpv4vars.emb_tcph = NULL; - p->icmpv4vars.emb_sport = ntohs(emb_tcph->th_sport); - p->icmpv4vars.emb_dport = ntohs(emb_tcph->th_dport); - p->icmpv4vars.emb_ip4_proto = IPPROTO_TCP; - SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->TCP partial header sport: " - "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport, - p->icmpv4vars.emb_dport); - } else { - SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->TCP " - "header Didn't fit in the packet!"); - p->icmpv4vars.emb_sport = 0; - p->icmpv4vars.emb_dport = 0; - } - - break; - case IPPROTO_UDP: - if (len >= IPV4_HEADER_LEN + UDP_HEADER_LEN ) { - p->icmpv4vars.emb_udph = (UDPHdr*)(partial_packet + IPV4_HEADER_LEN); - p->icmpv4vars.emb_sport = ntohs(p->icmpv4vars.emb_udph->uh_sport); - p->icmpv4vars.emb_dport = ntohs(p->icmpv4vars.emb_udph->uh_dport); - p->icmpv4vars.emb_ip4_proto = IPPROTO_UDP; - - SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->UDP header sport: " - "%"PRIu8" dport %"PRIu8"", p->icmpv4vars.emb_sport, - p->icmpv4vars.emb_dport); - } else { - SCLogDebug("DecodePartialIPV4: Warning, ICMPV4->IPV4->UDP " - "header Didn't fit in the packet!"); - p->icmpv4vars.emb_sport = 0; - p->icmpv4vars.emb_dport = 0; - } - - break; - case IPPROTO_ICMP: - p->icmpv4vars.emb_icmpv4h = (ICMPV4Hdr*)(partial_packet + IPV4_HEADER_LEN); - p->icmpv4vars.emb_sport = 0; - p->icmpv4vars.emb_dport = 0; - p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP; - - SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header"); - - break; - } - - /* debug print */ -#ifdef DEBUG - char s[16], d[16]; - PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s)); - PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d)); - SCLogDebug("ICMPv4 embedding IPV4 %s->%s - PROTO: %" PRIu32 " ID: %" PRIu32 "", s,d, - IPV4_GET_RAW_IPPROTO(icmp4_ip4h), IPV4_GET_RAW_IPID(icmp4_ip4h)); -#endif - - return; - -} - -/** DecodeICMPV4 - * \brief Main ICMPv4 decoding function - */ -int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_icmpv4); - - if (len < ICMPV4_HEADER_LEN) { - ENGINE_SET_INVALID_EVENT(p, ICMPV4_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - p->icmpv4h = (ICMPV4Hdr *)pkt; - - SCLogDebug("ICMPV4 TYPE %" PRIu32 " CODE %" PRIu32 "", p->icmpv4h->type, p->icmpv4h->code); - - p->proto = IPPROTO_ICMP; - p->type = p->icmpv4h->type; - p->code = p->icmpv4h->code; - p->payload = pkt + ICMPV4_HEADER_LEN; - p->payload_len = len - ICMPV4_HEADER_LEN; - - ICMPV4ExtHdr* icmp4eh = (ICMPV4ExtHdr*) p->icmpv4h; - - switch (p->icmpv4h->type) - { - case ICMP_ECHOREPLY: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } - break; - - case ICMP_DEST_UNREACH: - if (p->icmpv4h->code > NR_ICMP_UNREACH) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } else { - /* parse IP header plus 64 bytes */ - if (len > ICMPV4_HEADER_PKT_OFFSET) { - DecodePartialIPV4( p, (uint8_t *)(pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET ); - - /* ICMP ICMP_DEST_UNREACH influence TCP/UDP flows */ - if (ICMPV4_DEST_UNREACH_IS_VALID(p)) { - FlowHandlePacket(tv, dtv, p); - } - } - } - - - break; - - case ICMP_SOURCE_QUENCH: - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } else { - // parse IP header plus 64 bytes - if (len >= ICMPV4_HEADER_PKT_OFFSET) - DecodePartialIPV4( p, (uint8_t*) (pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET ); - } - break; - - case ICMP_REDIRECT: - if (p->icmpv4h->code>ICMP_REDIR_HOSTTOS) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } else { - // parse IP header plus 64 bytes - if (len > ICMPV4_HEADER_PKT_OFFSET) - DecodePartialIPV4( p, (uint8_t*) (pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET ); - } - break; - - case ICMP_ECHO: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } - break; - - case ICMP_TIME_EXCEEDED: - if (p->icmpv4h->code>ICMP_EXC_FRAGTIME) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } else { - // parse IP header plus 64 bytes - if (len > ICMPV4_HEADER_PKT_OFFSET) - DecodePartialIPV4( p, (uint8_t*) (pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET ); - } - break; - - case ICMP_PARAMETERPROB: - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } else { - // parse IP header plus 64 bytes - if (len > ICMPV4_HEADER_PKT_OFFSET) - DecodePartialIPV4( p, (uint8_t*) (pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET ); - } - break; - - case ICMP_TIMESTAMP: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } - break; - - case ICMP_TIMESTAMPREPLY: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } - break; - - case ICMP_INFO_REQUEST: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } - break; - - case ICMP_INFO_REPLY: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } - break; - - case ICMP_ADDRESS: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } - break; - - case ICMP_ADDRESSREPLY: - p->icmpv4vars.id=icmp4eh->id; - p->icmpv4vars.seq=icmp4eh->seq; - if (p->icmpv4h->code!=0) { - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE); - } - break; - - default: - ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_TYPE); - - } - - return TM_ECODE_OK; -} - -#ifdef UNITTESTS - -/** DecodeICMPV4test01 - * \brief - * \retval 1 Expected test value - */ -static int DecodeICMPV4test01(void) -{ - uint8_t raw_icmpv4[] = { - 0x08, 0x00, 0x78, 0x47, 0xfc, 0x55, 0x00, 0x04, - 0x52, 0xab, 0x86, 0x4a, 0x84, 0x50, 0x0e, 0x00, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab }; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int ret = 0; - IPV4Hdr ip4h; - - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; - - ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; - ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; - p->ip4h = &ip4h; - - DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); - - if (NULL!=p->icmpv4h) { - if (p->icmpv4h->type==8 && p->icmpv4h->code==0) { - ret = 1; - } - } - - FlowShutdown(); - SCFree(p); - return ret; -} - -/** DecodeICMPV4test02 - * \brief - * \retval 1 Expected test value - */ -static int DecodeICMPV4test02(void) -{ - uint8_t raw_icmpv4[] = { - 0x00, 0x00, 0x57, 0x64, 0xfb, 0x55, 0x00, 0x03, - 0x43, 0xab, 0x86, 0x4a, 0xf6, 0x49, 0x02, 0x00, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f }; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int ret = 0; - IPV4Hdr ip4h; - - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; - - ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; - ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; - p->ip4h = &ip4h; - - DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); - - if (NULL!=p->icmpv4h) { - if (p->icmpv4h->type==0 && p->icmpv4h->code==0) { - ret = 1; - } - } - - FlowShutdown(); - SCFree(p); - return ret; -} - -/** DecodeICMPV4test03 - * \brief TTL exceeded - * \retval Expected test value: 1 - */ -static int DecodeICMPV4test03(void) -{ - uint8_t raw_icmpv4[] = { - 0x0b, 0x00, 0x6a, 0x3d, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x00, 0x00, 0x3c, 0x64, 0x15, 0x00, 0x00, - 0x01, 0x11, 0xde, 0xfd, 0xc0, 0xa8, 0x01, 0x0d, - 0xd1, 0x55, 0xe3, 0x93, 0x8b, 0x12, 0x82, 0xaa, - 0x00, 0x28, 0x7c, 0xdd }; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int ret = 0; - IPV4Hdr ip4h; - - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; - - ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; - ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; - p->ip4h = &ip4h; - - DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); - - if (NULL == p->icmpv4h) { - printf("NULL == p->icmpv4h: "); - goto end; - } - - /* check it's type 11 code 0 */ - if (p->icmpv4h->type != 11 || p->icmpv4h->code != 0) { - printf("p->icmpv4h->type %u, p->icmpv4h->code %u: ", - p->icmpv4h->type, p->icmpv4h->code); - goto end; - } - - /* check it's source port 35602 to port 33450 */ - if (p->icmpv4vars.emb_sport != 35602 || - p->icmpv4vars.emb_dport != 33450) { - printf("p->icmpv4vars.emb_sport %u, p->icmpv4vars.emb_dport %u: ", - p->icmpv4vars.emb_sport, p->icmpv4vars.emb_dport); - goto end; - } - - /* check the src,dst IPs contained inside */ - char s[16], d[16]; - - PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s)); - PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d)); - - /* ICMPv4 embedding IPV4 192.168.1.13->209.85.227.147 pass */ - if (strcmp(s, "192.168.1.13") == 0 && strcmp(d, "209.85.227.147") == 0) { - ret = 1; - } - else { - printf("s %s, d %s: ", s, d); - } - -end: - FlowShutdown(); - SCFree(p); - return ret; -} - -/** DecodeICMPV4test04 - * \brief dest. unreachable, administratively prohibited - * \retval 1 Expected test value - */ -static int DecodeICMPV4test04(void) -{ - uint8_t raw_icmpv4[] = { - 0x03, 0x0a, 0x36, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x00, 0x00, 0x3c, 0x62, 0xee, 0x40, 0x00, - 0x33, 0x06, 0xb4, 0x8f, 0xc0, 0xa8, 0x01, 0x0d, - 0x58, 0x60, 0x16, 0x29, 0xb1, 0x0a, 0x00, 0x32, - 0x3e, 0x36, 0x38, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0xa0, 0x02, 0x16, 0xd0, 0x72, 0x04, 0x00, 0x00, - 0x02, 0x04, 0x05, 0x8a, 0x04, 0x02, 0x08, 0x0a }; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int ret = 0; - IPV4Hdr ip4h; - - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; - - ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; - ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; - p->ip4h = &ip4h; - - DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); - - if (NULL == p->icmpv4h) { - goto end; - } - - /* check the type,code pair is correct - type 3, code 10 */ - if (p->icmpv4h->type != 3 || p->icmpv4h->code != 10) { - goto end; - } - - /* check it's src port 45322 to dst port 50 */ - if (p->icmpv4vars.emb_sport != 45322 || - p->icmpv4vars.emb_dport != 50) { - goto end; - } - - // check the src,dst IPs contained inside - char s[16], d[16]; - - PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s)); - PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d)); - - // ICMPv4 embedding IPV4 192.168.1.13->88.96.22.41 - if (strcmp(s, "192.168.1.13") == 0 && strcmp(d, "88.96.22.41") == 0) { - ret = 1; - } - -end: - FlowShutdown(); - SCFree(p); - return ret; -} - -/** DecodeICMPV4test05 - * \brief dest. unreachable, administratively prohibited - * \retval 1 Expected test value - */ -static int DecodeICMPV4test05(void) -{ - uint8_t raw_icmpv4[] = { - 0x0b, 0x00, 0x5c, 0x46, 0x00, 0x00, 0x00, 0x00, 0x45, - 0x00, 0x00, 0x30, 0x02, 0x17, 0x40, 0x00, 0x01, 0x06, - 0xd6, 0xbd, 0xc0, 0xa8, 0x02, 0x05, 0x3d, 0x23, 0xa1, - 0x23, 0x04, 0x18, 0x00, 0x50, 0xd2, 0x08, 0xc2, 0x48, - }; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int ret = 0; - IPV4Hdr ip4h; - - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; - - ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; - ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; - p->ip4h = &ip4h; - - DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); - - if (NULL == p->icmpv4h) { - goto end; - } - - /* check the type,code pair is correct - type 11, code 0 */ - if (p->icmpv4h->type != 11 || p->icmpv4h->code != 0) { - goto end; - } - - /* check it's src port 1048 to dst port 80 */ - if (p->icmpv4vars.emb_sport != 1048 || - p->icmpv4vars.emb_dport != 80) { - goto end; - } - - // check the src,dst IPs contained inside - char s[16], d[16]; - - PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_src), s, sizeof(s)); - PrintInet(AF_INET, &(p->icmpv4vars.emb_ip4_dst), d, sizeof(d)); - - // ICMPv4 embedding IPV4 192.168.2.5->61.35.161.35 - if (strcmp(s, "192.168.2.5") == 0 && strcmp(d, "61.35.161.35") == 0) { - ret = 1; - } - -end: - FlowShutdown(); - SCFree(p); - return ret; -} - -static int ICMPV4CalculateValidChecksumtest05(void) -{ - uint16_t csum = 0; - - uint8_t raw_icmpv4[] = { - 0x08, 0x00, 0xab, 0x9b, 0x7f, 0x2b, 0x05, 0x2c, - 0x3f, 0x72, 0x93, 0x4a, 0x00, 0x4d, 0x0a, 0x00, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37}; - - csum = *( ((uint16_t *)raw_icmpv4) + 1); - return (csum == ICMPV4CalculateChecksum((uint16_t *)raw_icmpv4, sizeof(raw_icmpv4))); -} - -static int ICMPV4CalculateInvalidChecksumtest06(void) -{ - uint16_t csum = 0; - - uint8_t raw_icmpv4[] = { - 0x08, 0x00, 0xab, 0x9b, 0x7f, 0x2b, 0x05, 0x2c, - 0x3f, 0x72, 0x93, 0x4a, 0x00, 0x4d, 0x0a, 0x00, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38}; - - csum = *( ((uint16_t *)raw_icmpv4) + 1); - return (csum == ICMPV4CalculateChecksum((uint16_t *)raw_icmpv4, sizeof(raw_icmpv4))); -} - -static int ICMPV4InvalidType07(void) -{ - - uint8_t raw_icmpv4[] = { - 0xff, 0x00, 0xab, 0x9b, 0x7f, 0x2b, 0x05, 0x2c, - 0x3f, 0x72, 0x93, 0x4a, 0x00, 0x4d, 0x0a, 0x00, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38}; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int ret = 0; - IPV4Hdr ip4h; - - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; - - ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; - ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; - p->ip4h = &ip4h; - - DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); - - if(ENGINE_ISSET_EVENT(p,ICMPV4_UNKNOWN_TYPE)) { - ret = 1; - } - - FlowShutdown(); - SCFree(p); - return ret; -} - -/** DecodeICMPV4test08 - * \brief - * \retval 1 Expected test value - what we really want is not to segfault - */ -static int DecodeICMPV4test08(void) -{ - uint8_t raw_icmpv4[] = { - 0x08, 0x00, 0x78, 0x47, 0xfc, 0x55, 0x00, 0x00 - }; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int ret = 0; - IPV4Hdr ip4h; - - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("4.3.2.1");; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4");; - - ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; - ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; - p->ip4h = &ip4h; - - DecodeICMPV4(&tv, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); - - if (NULL!=p->icmpv4h) { - if (p->icmpv4h->type==8 && p->icmpv4h->code==0) { - ret = 1; - } - } - - FlowShutdown(); - SCFree(p); - return ret; -} -#endif /* UNITTESTS */ - -/** - * \brief Registers ICMPV4 unit test - */ -void DecodeICMPV4RegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodeICMPV4test01", DecodeICMPV4test01, 1); - UtRegisterTest("DecodeICMPV4test02", DecodeICMPV4test02, 1); - UtRegisterTest("DecodeICMPV4test03", DecodeICMPV4test03, 1); - UtRegisterTest("DecodeICMPV4test04", DecodeICMPV4test04, 1); - UtRegisterTest("DecodeICMPV4test05", DecodeICMPV4test05, 1); - UtRegisterTest("ICMPV4CalculateValidChecksumtest05", - ICMPV4CalculateValidChecksumtest05, 1); - UtRegisterTest("ICMPV4CalculateInvalidChecksumtest06", - ICMPV4CalculateInvalidChecksumtest06, 0); - UtRegisterTest("DecodeICMPV4InvalidType", ICMPV4InvalidType07, 1); - UtRegisterTest("DecodeICMPV4test08", DecodeICMPV4test08, 1); -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-icmpv4.h b/framework/src/suricata/src/decode-icmpv4.h deleted file mode 100644 index f8cb97f4..00000000 --- a/framework/src/suricata/src/decode-icmpv4.h +++ /dev/null @@ -1,345 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DECODE_ICMPV4_H__ -#define __DECODE_ICMPV4_H__ - -#include "decode.h" -#include "decode-tcp.h" -#include "decode-sctp.h" -#include "decode-udp.h" - -#define ICMPV4_HEADER_LEN 8 - -#ifndef ICMP_ECHOREPLY -#define ICMP_ECHOREPLY 0 /* Echo Reply */ -#endif -#ifndef ICMP_DEST_UNREACH -#define ICMP_DEST_UNREACH 3 /* Destination Unreachable */ -#endif -#ifndef ICMP_SOURCE_QUENCH -#define ICMP_SOURCE_QUENCH 4 /* Source Quench */ -#endif -#ifndef ICMP_REDIRECT -#define ICMP_REDIRECT 5 /* Redirect (change route) */ -#endif -#ifndef ICMP_ECHO -#define ICMP_ECHO 8 /* Echo Request */ -#endif -#ifndef ICMP_TIME_EXCEEDED -#define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ -#endif -#ifndef ICMP_PARAMETERPROB -#define ICMP_PARAMETERPROB 12 /* Parameter Problem */ -#endif -#ifndef ICMP_TIMESTAMP -#define ICMP_TIMESTAMP 13 /* Timestamp Request */ -#endif -#ifndef ICMP_TIMESTAMPREPLY -#define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ -#endif -#ifndef ICMP_INFO_REQUEST -#define ICMP_INFO_REQUEST 15 /* Information Request */ -#endif -#ifndef ICMP_INFO_REPLY -#define ICMP_INFO_REPLY 16 /* Information Reply */ -#endif -#ifndef ICMP_ADDRESS -#define ICMP_ADDRESS 17 /* Address Mask Request */ -#endif -#ifndef ICMP_ADDRESSREPLY -#define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ -#endif -#ifndef NR_ICMP_TYPES -#define NR_ICMP_TYPES 18 -#endif - - -/* Codes for UNREACH. */ -#ifndef ICMP_NET_UNREACH -#define ICMP_NET_UNREACH 0 /* Network Unreachable */ -#endif -#ifndef ICMP_HOST_UNREACH -#define ICMP_HOST_UNREACH 1 /* Host Unreachable */ -#endif -#ifndef ICMP_PROT_UNREACH -#define ICMP_PROT_UNREACH 2 /* Protocol Unreachable */ -#endif -#ifndef ICMP_PORT_UNREACH -#define ICMP_PORT_UNREACH 3 /* Port Unreachable */ -#endif -#ifndef ICMP_FRAG_NEEDED -#define ICMP_FRAG_NEEDED 4 /* Fragmentation Needed/DF set */ -#endif -#ifndef ICMP_SR_FAILED -#define ICMP_SR_FAILED 5 /* Source Route failed */ -#endif -#ifndef ICMP_NET_UNKNOWN -#define ICMP_NET_UNKNOWN 6 -#endif -#ifndef ICMP_HOST_UNKNOWN -#define ICMP_HOST_UNKNOWN 7 -#endif -#ifndef ICMP_HOST_ISOLATED -#define ICMP_HOST_ISOLATED 8 -#endif -#ifndef ICMP_NET_ANO -#define ICMP_NET_ANO 9 -#endif -#ifndef ICMP_HOST_ANO -#define ICMP_HOST_ANO 10 -#endif -#ifndef ICMP_NET_UNR_TOS -#define ICMP_NET_UNR_TOS 11 -#endif -#ifndef ICMP_HOST_UNR_TOS -#define ICMP_HOST_UNR_TOS 12 -#endif -#ifndef ICMP_PKT_FILTERED -#define ICMP_PKT_FILTERED 13 /* Packet filtered */ -#endif -#ifndef ICMP_PREC_VIOLATION -#define ICMP_PREC_VIOLATION 14 /* Precedence violation */ - -#endif -#ifndef ICMP_PREC_CUTOFF -#define ICMP_PREC_CUTOFF 15 /* Precedence cut off */ -#endif -#ifndef NR_ICMP_UNREACH -#define NR_ICMP_UNREACH 15 /* instead of hardcoding immediate value */ -#endif - -/* Codes for REDIRECT. */ -#ifndef ICMP_REDIR_NET -#define ICMP_REDIR_NET 0 /* Redirect Net */ -#endif -#ifndef ICMP_REDIR_HOST -#define ICMP_REDIR_HOST 1 /* Redirect Host */ -#endif -#ifndef ICMP_REDIR_NETTOS -#define ICMP_REDIR_NETTOS 2 /* Redirect Net for TOS */ -#endif -#ifndef ICMP_REDIR_HOSTTOS -#define ICMP_REDIR_HOSTTOS 3 /* Redirect Host for TOS */ -#endif - -/* Codes for TIME_EXCEEDED. */ -#ifndef ICMP_EXC_TTL -#define ICMP_EXC_TTL 0 /* TTL count exceeded */ -#endif -#ifndef ICMP_EXC_FRAGTIME -#define ICMP_EXC_FRAGTIME 1 /* Fragment Reass time exceeded */ -#endif - -/** marco for icmpv4 type access */ -#define ICMPV4_GET_TYPE(p) (p)->icmpv4h->type -/** marco for icmpv4 code access */ -#define ICMPV4_GET_CODE(p) (p)->icmpv4h->code - -/* ICMPv4 header structure */ -typedef struct ICMPV4Hdr_ -{ - uint8_t type; - uint8_t code; - uint16_t checksum; -} __attribute__((__packed__)) ICMPV4Hdr; - -/* ICMPv4 header structure */ -typedef struct ICMPV4ExtHdr_ -{ - uint8_t type; - uint8_t code; - uint16_t checksum; - uint16_t id; - uint16_t seq; -} ICMPV4ExtHdr; - -/* ICMPv4 vars */ -typedef struct ICMPV4Vars_ -{ - uint16_t id; - uint16_t seq; - uint32_t mtu; - uint32_t error_ptr; - - /** Pointers to the embedded packet headers */ - IPV4Hdr *emb_ipv4h; - TCPHdr *emb_tcph; - UDPHdr *emb_udph; - ICMPV4Hdr *emb_icmpv4h; - - /** IPv4 src and dst address */ - struct in_addr emb_ip4_src; - struct in_addr emb_ip4_dst; - uint8_t emb_ip4_hlen; - uint8_t emb_ip4_proto; - - /** TCP/UDP ports */ - uint16_t emb_sport; - uint16_t emb_dport; -} ICMPV4Vars; - -#define CLEAR_ICMPV4_PACKET(p) do { \ - (p)->level4_comp_csum = -1; \ - (p)->icmpv4vars.id = 0; \ - (p)->icmpv4vars.seq = 0; \ - (p)->icmpv4vars.mtu = 0; \ - (p)->icmpv4vars.error_ptr = 0; \ - (p)->icmpv4vars.emb_ipv4h = NULL; \ - (p)->icmpv4vars.emb_tcph = NULL; \ - (p)->icmpv4vars.emb_udph = NULL; \ - (p)->icmpv4vars.emb_icmpv4h = NULL; \ - (p)->icmpv4vars.emb_ip4_src.s_addr = 0; \ - (p)->icmpv4vars.emb_ip4_dst.s_addr = 0; \ - (p)->icmpv4vars.emb_sport = 0; \ - (p)->icmpv4vars.emb_ip4_proto = 0; \ - (p)->icmpv4vars.emb_sport = 0; \ - (p)->icmpv4vars.emb_dport = 0; \ - (p)->icmpv4h = NULL; \ -} while(0) - -#define ICMPV4_HEADER_PKT_OFFSET 8 - -/** macro for icmpv4 "type" access */ -#define ICMPV4_GET_TYPE(p) (p)->icmpv4h->type -/** macro for icmpv4 "code" access */ -#define ICMPV4_GET_CODE(p) (p)->icmpv4h->code -/** macro for icmpv4 "csum" access */ -#define ICMPV4_GET_CSUM(p) (p)->icmpv4h->csum - -/* If message is informational */ - -/** macro for icmpv4 "id" access */ -#define ICMPV4_GET_ID(p) ((p)->icmpv4vars.id) -/** macro for icmpv4 "seq" access */ -#define ICMPV4_GET_SEQ(p) ((p)->icmpv4vars.seq) - -/* If message is Error */ - -/** macro for icmpv4 "unused" access */ -#define ICMPV4_GET_UNUSED(p) (p)->icmpv4h->icmpv4b.icmpv4e.unused -/** macro for icmpv4 "error_ptr" access */ -#define ICMPV4_GET_ERROR_PTR(p) (p)->icmpv4h->icmpv4b.icmpv4e.error_ptr -/** macro for icmpv4 "mtu" access */ -#define ICMPV4_GET_MTU(p) (p)->icmpv4h->icmpv4b.icmpv4e.mtu - -/** macro for icmpv4 embedded "protocol" access */ -#define ICMPV4_GET_EMB_PROTO(p) (p)->icmpv4vars.emb_ip4_proto -/** macro for icmpv4 embedded "ipv4h" header access */ -#define ICMPV4_GET_EMB_IPV4(p) (p)->icmpv4vars.emb_ipv4h -/** macro for icmpv4 embedded "tcph" header access */ -#define ICMPV4_GET_EMB_TCP(p) (p)->icmpv4vars.emb_tcph -/** macro for icmpv4 embedded "udph" header access */ -#define ICMPV4_GET_EMB_UDP(p) (p)->icmpv4vars.emb_udph -/** macro for icmpv4 embedded "icmpv4h" header access */ -#define ICMPV4_GET_EMB_ICMPV4H(p) (p)->icmpv4vars.emb_icmpv4h - -/** macro for checking if a ICMP DEST UNREACH packet is valid for use - * in other parts of the engine, such as the flow engine. - * - * \warning use only _after_ the decoder has processed the packet - */ -#define ICMPV4_DEST_UNREACH_IS_VALID(p) (((p)->icmpv4h != NULL) && \ - (ICMPV4_GET_TYPE((p)) == ICMP_DEST_UNREACH) && \ - (ICMPV4_GET_EMB_IPV4((p)) != NULL) && \ - ((ICMPV4_GET_EMB_TCP((p)) != NULL) || \ - (ICMPV4_GET_EMB_UDP((p)) != NULL))) - -/** - * marco for checking if a ICMP packet is an error message or an - * query message. - * - * \todo This check is used in the flow engine and needs to be as - * cheap as possible. Consider setting a bitflag at the decoder - * stage so we can to a bit check instead of the more expensive - * check below. - */ -#define ICMPV4_IS_ERROR_MSG(p) (ICMPV4_GET_TYPE((p)) == ICMP_DEST_UNREACH || \ - ICMPV4_GET_TYPE((p)) == ICMP_SOURCE_QUENCH || \ - ICMPV4_GET_TYPE((p)) == ICMP_REDIRECT || \ - ICMPV4_GET_TYPE((p)) == ICMP_TIME_EXCEEDED || \ - ICMPV4_GET_TYPE((p)) == ICMP_PARAMETERPROB) - -typedef struct ICMPV4Cache_ { -} ICMPV4Cache; - -void DecodeICMPV4RegisterTests(void); - -/** ------ Inline functions ------ */ -static inline uint16_t ICMPV4CalculateChecksum(uint16_t *, uint16_t); - -/** - * \brief Calculates the checksum for the ICMP packet - * - * \param pkt Pointer to the start of the ICMP packet - * \param hlen Total length of the ICMP packet(header + payload) - * - * \retval csum Checksum for the ICMP packet - */ -static inline uint16_t ICMPV4CalculateChecksum(uint16_t *pkt, uint16_t tlen) -{ - uint16_t pad = 0; - uint32_t csum = pkt[0]; - - tlen -= 4; - pkt += 2; - - while (tlen >= 32) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15]; - tlen -= 32; - pkt += 16; - } - - while(tlen >= 8) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3]; - tlen -= 8; - pkt += 4; - } - - while(tlen >= 4) { - csum += pkt[0] + pkt[1]; - tlen -= 4; - pkt += 2; - } - - while (tlen > 1) { - csum += pkt[0]; - tlen -= 2; - pkt += 1; - } - - if (tlen == 1) { - *(uint8_t *)(&pad) = (*(uint8_t *)pkt); - csum += pad; - } - - csum = (csum >> 16) + (csum & 0x0000FFFF); - csum += (csum >> 16); - - return (uint16_t) ~csum; -} - -#endif /* __DECODE_ICMPV4_H__ */ - diff --git a/framework/src/suricata/src/decode-icmpv6.c b/framework/src/suricata/src/decode-icmpv6.c deleted file mode 100644 index 7972ea79..00000000 --- a/framework/src/suricata/src/decode-icmpv6.c +++ /dev/null @@ -1,1642 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decode ICMPv6 - */ - -#include "suricata-common.h" -#include "decode-icmpv6.h" -#include "decode.h" -#include "decode-tcp.h" -#include "decode-sctp.h" -#include "decode-udp.h" -#include "decode-events.h" -#include "util-unittest.h" -#include "flow.h" -#include "util-debug.h" -#include "util-print.h" - -#include "pkt-var.h" -#include "util-profiling.h" -#include "host.h" - - -/** - * \brief Get variables and do some checks of the embedded IPV6 packet - * - * \param p Pointer to the packet we are filling - * \param partial_packet Pointer to the raw packet buffer - * \param len the len of the rest of the packet not processed yet - * - * \retval void No return value - */ -void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len ) -{ - /** Check the sizes, the header must fit at least */ - if (len < IPV6_HEADER_LEN) { - SCLogDebug("ICMPV6_IPV6_TRUNC_PKT"); - ENGINE_SET_INVALID_EVENT(p, ICMPV6_IPV6_TRUNC_PKT); - return; - } - - IPV6Hdr *icmp6_ip6h = (IPV6Hdr*)partial_packet; - - /** Check the embedded version */ - if(((icmp6_ip6h->s_ip6_vfc & 0xf0) >> 4) != 6) - { - SCLogDebug("ICMPv6 contains Unknown IPV6 version " - "ICMPV6_IPV6_UNKNOWN_VER"); - ENGINE_SET_INVALID_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER); - return; - } - - /** We need to fill icmpv6vars */ - p->icmpv6vars.emb_ipv6h = icmp6_ip6h; - - /** Get the IP6 address */ - p->icmpv6vars.emb_ip6_src[0] = icmp6_ip6h->s_ip6_src[0]; - p->icmpv6vars.emb_ip6_src[1] = icmp6_ip6h->s_ip6_src[1]; - p->icmpv6vars.emb_ip6_src[2] = icmp6_ip6h->s_ip6_src[2]; - p->icmpv6vars.emb_ip6_src[3] = icmp6_ip6h->s_ip6_src[3]; - - p->icmpv6vars.emb_ip6_dst[0] = icmp6_ip6h->s_ip6_dst[0]; - p->icmpv6vars.emb_ip6_dst[1] = icmp6_ip6h->s_ip6_dst[1]; - p->icmpv6vars.emb_ip6_dst[2] = icmp6_ip6h->s_ip6_dst[2]; - p->icmpv6vars.emb_ip6_dst[3] = icmp6_ip6h->s_ip6_dst[3]; - - /** Get protocol and ports inside the embedded ipv6 packet and set the pointers */ - p->icmpv6vars.emb_ip6_proto_next = icmp6_ip6h->s_ip6_nxt; - - switch (icmp6_ip6h->s_ip6_nxt) { - case IPPROTO_TCP: - if (len >= IPV6_HEADER_LEN + TCP_HEADER_LEN ) { - p->icmpv6vars.emb_tcph = (TCPHdr*)(partial_packet + IPV6_HEADER_LEN); - p->icmpv6vars.emb_sport = p->icmpv6vars.emb_tcph->th_sport; - p->icmpv6vars.emb_dport = p->icmpv6vars.emb_tcph->th_dport; - - SCLogDebug("ICMPV6->IPV6->TCP header sport: " - "%"PRIu8" dport %"PRIu8"", p->icmpv6vars.emb_sport, - p->icmpv6vars.emb_dport); - } else { - SCLogDebug("Warning, ICMPV6->IPV6->TCP " - "header Didn't fit in the packet!"); - p->icmpv6vars.emb_sport = 0; - p->icmpv6vars.emb_dport = 0; - } - - break; - case IPPROTO_UDP: - if (len >= IPV6_HEADER_LEN + UDP_HEADER_LEN ) { - p->icmpv6vars.emb_udph = (UDPHdr*)(partial_packet + IPV6_HEADER_LEN); - p->icmpv6vars.emb_sport = p->icmpv6vars.emb_udph->uh_sport; - p->icmpv6vars.emb_dport = p->icmpv6vars.emb_udph->uh_dport; - - SCLogDebug("ICMPV6->IPV6->UDP header sport: " - "%"PRIu8" dport %"PRIu8"", p->icmpv6vars.emb_sport, - p->icmpv6vars.emb_dport); - } else { - SCLogDebug("Warning, ICMPV6->IPV6->UDP " - "header Didn't fit in the packet!"); - p->icmpv6vars.emb_sport = 0; - p->icmpv6vars.emb_dport = 0; - } - - break; - case IPPROTO_ICMPV6: - p->icmpv6vars.emb_icmpv6h = (ICMPV6Hdr*)(partial_packet + IPV6_HEADER_LEN); - p->icmpv6vars.emb_sport = 0; - p->icmpv6vars.emb_dport = 0; - - SCLogDebug("ICMPV6->IPV6->ICMP header"); - - break; - } - - /* debug print */ -#ifdef DEBUG - char s[46], d[46]; - PrintInet(AF_INET6, (const void *)p->icmpv6vars.emb_ip6_src, s, sizeof(s)); - PrintInet(AF_INET6, (const void *)p->icmpv6vars.emb_ip6_dst, d, sizeof(d)); - SCLogDebug("ICMPv6 embedding IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: " - "%" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32, - s, d, IPV6_GET_RAW_CLASS(icmp6_ip6h), IPV6_GET_RAW_FLOW(icmp6_ip6h), - IPV6_GET_RAW_NH(icmp6_ip6h), IPV6_GET_RAW_PLEN(icmp6_ip6h), IPV6_GET_RAW_HLIM(icmp6_ip6h)); -#endif - - return; -} - -/** - * \brief Decode ICMPV6 packets and fill the Packet with the decoded info - * - * \param tv Pointer to the thread variables - * \param dtv Pointer to the decode thread variables - * \param p Pointer to the packet we are filling - * \param pkt Pointer to the raw packet buffer - * \param len the len of the rest of the packet not processed yet - * \param pq the packet queue were this packet go - * - * \retval void No return value - */ -int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, - uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - int full_hdr = 0; - StatsIncr(tv, dtv->counter_icmpv6); - - if (len < ICMPV6_HEADER_LEN) { - SCLogDebug("ICMPV6_PKT_TOO_SMALL"); - ENGINE_SET_INVALID_EVENT(p, ICMPV6_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - p->icmpv6h = (ICMPV6Hdr *)pkt; - p->proto = IPPROTO_ICMPV6; - p->type = p->icmpv6h->type; - p->code = p->icmpv6h->code; - p->payload_len = len - ICMPV6_HEADER_LEN; - p->payload = pkt + ICMPV6_HEADER_LEN; - - SCLogDebug("ICMPV6 TYPE %" PRIu32 " CODE %" PRIu32 "", p->icmpv6h->type, - p->icmpv6h->code); - - switch (ICMPV6_GET_TYPE(p)) { - case ICMP6_DST_UNREACH: - SCLogDebug("ICMP6_DST_UNREACH"); - - if (ICMPV6_GET_CODE(p) > ICMP6_DST_UNREACH_REJECTROUTE) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } else { - DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN), - len - ICMPV6_HEADER_LEN ); - full_hdr = 1; - } - - break; - case ICMP6_PACKET_TOO_BIG: - SCLogDebug("ICMP6_PACKET_TOO_BIG"); - - if (ICMPV6_GET_CODE(p) != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } else { - p->icmpv6vars.mtu = ICMPV6_GET_MTU(p); - DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN), - len - ICMPV6_HEADER_LEN ); - full_hdr = 1; - } - - break; - case ICMP6_TIME_EXCEEDED: - SCLogDebug("ICMP6_TIME_EXCEEDED"); - - if (ICMPV6_GET_CODE(p) > ICMP6_TIME_EXCEED_REASSEMBLY) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } else { - DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN), - len - ICMPV6_HEADER_LEN ); - full_hdr = 1; - } - - break; - case ICMP6_PARAM_PROB: - SCLogDebug("ICMP6_PARAM_PROB"); - - if (ICMPV6_GET_CODE(p) > ICMP6_PARAMPROB_OPTION) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } else { - p->icmpv6vars.error_ptr= ICMPV6_GET_ERROR_PTR(p); - DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN), - len - ICMPV6_HEADER_LEN ); - full_hdr = 1; - } - - break; - case ICMP6_ECHO_REQUEST: - SCLogDebug("ICMP6_ECHO_REQUEST id: %u seq: %u", - p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq); - - if (ICMPV6_GET_CODE(p) != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } else { - p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id; - p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq; - full_hdr = 1; - } - - break; - case ICMP6_ECHO_REPLY: - SCLogDebug("ICMP6_ECHO_REPLY id: %u seq: %u", - p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq); - - if (p->icmpv6h->code != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } else { - p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id; - p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq; - full_hdr = 1; - } - - break; - case ND_ROUTER_SOLICIT: - SCLogDebug("ND_ROUTER_SOLICIT"); - if (p->icmpv6h->code != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } - break; - case ND_ROUTER_ADVERT: - SCLogDebug("ND_ROUTER_ADVERT"); - if (p->icmpv6h->code != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } - break; - case ND_NEIGHBOR_SOLICIT: - SCLogDebug("ND_NEIGHBOR_SOLICIT"); - if (p->icmpv6h->code != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } - break; - case ND_NEIGHBOR_ADVERT: - SCLogDebug("ND_NEIGHBOR_ADVERT"); - if (p->icmpv6h->code != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } - break; - case ND_REDIRECT: - SCLogDebug("ND_REDIRECT"); - if (p->icmpv6h->code != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } - break; - case MLD_LISTENER_QUERY: - SCLogDebug("MLD_LISTENER_QUERY"); - if (p->icmpv6h->code != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } - if (IPV6_GET_HLIM(p) != 1) { - ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL); - } - break; - case MLD_LISTENER_REPORT: - SCLogDebug("MLD_LISTENER_REPORT"); - if (p->icmpv6h->code != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } - if (IPV6_GET_HLIM(p) != 1) { - ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL); - } - break; - case MLD_LISTENER_REDUCTION: - SCLogDebug("MLD_LISTENER_REDUCTION"); - if (p->icmpv6h->code != 0) { - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE); - } - if (IPV6_GET_HLIM(p) != 1) { - ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL); - } - break; - default: - SCLogDebug("ICMPV6 Message type %" PRIu8 " not " - "implemented yet", ICMPV6_GET_TYPE(p)); - ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_TYPE); - } - - /* for a info message the header is just 4 bytes */ - if (!full_hdr) { - if (p->payload_len >= 4) { - p->payload_len -= 4; - p->payload = pkt + 4; - } else { - p->payload_len = 0; - p->payload = NULL; - } - } - -#ifdef DEBUG - if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) - SCLogDebug("Unknown Code, ICMPV6_UNKNOWN_CODE"); - - if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_TYPE)) - SCLogDebug("Unknown Type, ICMPV6_UNKNOWN_TYPE"); -#endif - - /* Flow is an integral part of us */ - FlowHandlePacket(tv, dtv, p); - - return TM_ECODE_OK; -} - -#ifdef UNITTESTS - -static int ICMPV6CalculateValidChecksumtest01(void) -{ - uint16_t csum = 0; - - uint8_t raw_ipv6[] = { - 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60, - 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60, - 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00, - 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed, - 0x08, 0x00}; - - csum = *( ((uint16_t *)(raw_ipv6 + 56))); - - return (csum == ICMPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 68)); -} - -static int ICMPV6CalculateInvalidChecksumtest02(void) -{ - uint16_t csum = 0; - - uint8_t raw_ipv6[] = { - 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60, - 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60, - 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00, - 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed, - 0x08, 0x01}; - - csum = *( ((uint16_t *)(raw_ipv6 + 56))); - - return (csum == ICMPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 68)); -} - - -/** \test icmpv6 message type: parameter problem, valid packet - * - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6ParamProbTest01(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x00, 0xcc, 0x2a, 0x6d, 0x93, 0x0b, 0xdf, - 0x69, 0x70, 0x12, 0xb7, 0x00, 0x08, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x80, 0x00, 0x08, 0xb5, 0x99, 0xc3, 0xde, 0x40 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - uint32_t *ipv6src; - uint32_t *ipv6dst; - ipv6src = (uint32_t*) &raw_ipv6[8]; - ipv6dst = (uint32_t*) &raw_ipv6[24]; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (p->icmpv6h == NULL) { - SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); - retval = 0; - goto end; - } - - if (ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0 || - ICMPV6_GET_EMB_PROTO(p) != IPPROTO_ICMPV6) { - SCLogDebug("ICMPv6 not processed at all"); - retval = 0; - goto end; - } - - /* Let's check if we retrieved the embedded ipv6 addresses correctly */ - uint32_t i=0; - for (i = 0; i < 4; i++) { - if (p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] || - p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]) { - SCLogDebug("ICMPv6 DecodePartialICMPV6 (Embedded ip6h) didn't set " - "the src and dest ip addresses correctly"); - retval = 0; - goto end; - } - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/** \test icmpv6 message type: packet too big, valid packet - * - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6PktTooBigTest01(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x00, 0x5c, 0x7a, 0x00, 0x00, 0x05, 0x00, - 0x64, 0x14, 0xfd, 0xff, 0x00, 0x00, 0x3b, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - uint32_t *ipv6src; - uint32_t *ipv6dst; - ipv6src = (uint32_t*) &raw_ipv6[8]; - ipv6dst = (uint32_t*) &raw_ipv6[24]; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (p->icmpv6h == NULL) { - SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); - retval = 0; - goto end; - } - - /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */ - if (ICMPV6_GET_TYPE(p) != 2 || ICMPV6_GET_CODE(p) != 0 ) { - SCLogDebug("ICMPv6 Not processed at all"); - retval = 0; - goto end; - } - - /* Let's check if we retrieved the embedded ipv6 addresses correctly */ - uint32_t i=0; - for (i = 0; i < 4; i++) { - if (p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] || - p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]) { - SCLogDebug("ICMPv6 DecodePartialICMPV6 (Embedded ip6h) didn't set " - "the src and dest ip addresses correctly"); - retval = 0; - goto end; - } - } - - SCLogDebug("ICMPV6 IPV6 src and dst properly set"); - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/** \test icmpv6 message type: time exceed, valid packet - * - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6TimeExceedTest01(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x03, 0x00, 0x56, 0x2d, 0x00, 0x00, 0x00, 0x00, - 0x6d, 0x23, 0xff, 0x3d, 0x00, 0x00, 0x3b, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - uint32_t *ipv6src; - uint32_t *ipv6dst; - ipv6src = (uint32_t*) &raw_ipv6[8]; - ipv6dst = (uint32_t*) &raw_ipv6[24]; - - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (p->icmpv6h == NULL) { - SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); - retval = 0; - goto end; - } - - /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */ - if (ICMPV6_GET_TYPE(p) != 3 || ICMPV6_GET_CODE(p) != 0 || - ICMPV6_GET_EMB_IPV6(p)==NULL || ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE ) { - SCLogDebug("ICMPv6 Not processed at all"); - retval = 0; - goto end; - } - - /* Let's check if we retrieved the embedded ipv6 addresses correctly */ - uint32_t i=0; - for (i = 0; i < 4; i++) { - if (p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] || - p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]) { - SCLogDebug("ICMPv6 DecodePartialICMPV6 (Embedded ip6h) didn't set " - "the src and dest ip addresses correctly"); - retval = 0; - goto end; - } - } - - SCLogDebug("ICMPV6 IPV6 src and dst properly set"); - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/** \test icmpv6 message type: destination unreach, valid packet - * - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6DestUnreachTest01(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - uint32_t *ipv6src; - uint32_t *ipv6dst; - ipv6src = (uint32_t*) &raw_ipv6[8]; - ipv6dst = (uint32_t*) &raw_ipv6[24]; - - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (p->icmpv6h == NULL) { - SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); - retval = 0; - goto end; - } - - /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */ - if (ICMPV6_GET_TYPE(p) != 1 || ICMPV6_GET_CODE(p) != 0 || - ICMPV6_GET_EMB_IPV6(p) == NULL || ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE ) { - SCLogDebug("ICMPv6 Not processed at all"); - retval = 0; - goto end; - } - - /* Let's check if we retrieved the embedded ipv6 addresses correctly */ - uint32_t i=0; - for (i = 0; i < 4; i++) { - if (p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] || - p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]) { - SCLogDebug("ICMPv6 DecodePartialICMPV6 (Embedded ip6h) didn't set " - "the src and dest ip addresses correctly"); - retval = 0; - goto end; - } - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/**\test icmpv6 message type: echo request, valid packet - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6EchoReqTest01(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x80, 0x00, 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (p->icmpv6h == NULL) { - SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); - goto end; - } - - SCLogDebug("ID: %u seq: %u", ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); - - if (ICMPV6_GET_TYPE(p) != 128 || ICMPV6_GET_CODE(p) != 0 || - ntohs(ICMPV6_GET_ID(p)) != 9712 || ntohs(ICMPV6_GET_SEQ(p)) != 29987) { - printf("ICMPv6 Echo reply decode failed TYPE %u CODE %u ID %04x(%u) SEQ %04x(%u): ", - ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), ntohs(ICMPV6_GET_ID(p)), - ICMPV6_GET_SEQ(p), ntohs(ICMPV6_GET_SEQ(p))); - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/**\test icmpv6 message type: echo reply, valid packet - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6EchoRepTest01(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x00, - 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (p->icmpv6h == NULL) { - SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); - goto end; - } - - SCLogDebug("type: %u code %u ID: %u seq: %u", ICMPV6_GET_TYPE(p), - ICMPV6_GET_CODE(p),ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); - - if (ICMPV6_GET_TYPE(p) != 129 || ICMPV6_GET_CODE(p) != 0 || - ntohs(ICMPV6_GET_ID(p)) != 9712 || ntohs(ICMPV6_GET_SEQ(p)) != 29987) { - printf("ICMPv6 Echo reply decode failed TYPE %u CODE %u ID %04x(%u) SEQ %04x(%u): ", - ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), ntohs(ICMPV6_GET_ID(p)), - ICMPV6_GET_SEQ(p), ntohs(ICMPV6_GET_SEQ(p))); - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/** \test icmpv6 message type: parameter problem, invalid packet - * \brief set the event ICMPV6_IPV6_UNKNOWN_VER properly when the embedded packet has an unknown version - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6ParamProbTest02(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x00, 0xcc, 0x2a, 0x6d, 0x93, 0x0b, 0xdf, - 0x38, 0x70, 0x12, 0xb7, 0x00, 0x08, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x80, 0x00, 0x08, 0xb5, 0x99, 0xc3, 0xde, 0x40 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (p->icmpv6h == NULL) { - SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); - retval = 0; - goto end; - } - - if (ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0) { - SCLogDebug("ICMPv6 Not processed at all"); - retval = 0; - goto end; - } - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER)) { - SCLogDebug("ICMPv6 Error: Unknown embedded ipv6 version event not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/** \test icmpv6 message type: packet too big, invalid packet - * \brief Set the event ICMPV6_UNKNOWN_CODE if code is invalid for this type - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6PktTooBigTest02(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x10, 0x5c, 0x7a, 0x00, 0x00, 0x05, 0x00, - 0x64, 0x14, 0xfd, 0xff, 0x00, 0x00, 0x3b, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (p->icmpv6h == NULL) { - SCLogDebug("ICMPv6 Unable to detect icmpv6 layer from ipv6"); - retval = 0; - goto end; - } - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/** \test icmpv6 message type: time exceed, invalid packet - * \brief set the event ICMPV6_PKT_TOO_SMALL properly - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6TimeExceedTest02(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x10, 0x5c }; - - /* The icmpv6 header is broken in the checksum (so we dont have a complete header) */ - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_PKT_TOO_SMALL)) { - SCLogDebug("ICMPv6 Error: event packet too small not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/**\test icmpv6 message type: destination unreach, invalid packet - * \brief The embedded packet header (ipv6) is truncated - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6DestUnreachTest02(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_IPV6_TRUNC_PKT)) { - SCLogDebug("ICMPv6 Error: embedded ipv6 truncated packet event not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/**\test icmpv6 message type: echo request, invalid packet - * \brief unknown code - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6EchoReqTest02(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, - 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/**\test icmpv6 message type: echo reply, invalid packet - * \brief unknown code - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6EchoRepTest02(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x01, - 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/**\test icmpv6 packet decoding and setting up of payload_len and payload buufer - * \retval retval 0 = Error ; 1 = ok - */ -static int ICMPV6PayloadTest01(void) -{ - int retval = 0; - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (p->payload == NULL) { - printf("payload == NULL, expected non-NULL: "); - goto end; - } - - if (p->payload_len != 37) { - printf("payload_len %"PRIu16", expected 37: ", p->payload_len); - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6RouterSolicitTestKnownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x85, 0x00, 0xbe, 0xb0, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6RouterSolicitTestUnknownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x85, 0x01, 0xbe, 0xaf, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6RouterAdvertTestKnownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x86, 0x00, 0xbd, 0xb0, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6RouterAdvertTestUnknownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x86, 0x01, 0xbd, 0xaf, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6NeighbourSolicitTestKnownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x87, 0x00, 0xbc, 0xb0, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6NeighbourSolicitTestUnknownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x87, 0x01, 0xbc, 0xaf, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6NeighbourAdvertTestKnownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x88, 0x00, 0xbb, 0xb0, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6NeighbourAdvertTestUnknownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x88, 0x01, 0xbb, 0xaf, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6RedirectTestKnownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x89, 0x00, 0xba, 0xb0, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int ICMPV6RedirectTestUnknownCode(void) -{ - int retval = 0; - - static uint8_t raw_ipv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x89, 0x01, 0xba, 0xaf, 0x00, 0x00, 0x00, 0x00 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - - FlowInitConfig(FLOW_QUIET); - DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6), NULL); - - if (!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE)) { - SCLogDebug("ICMPv6 Error: Unknown code event is not set"); - retval = 0; - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -#endif /* UNITTESTS */ -/** - * \brief Registers ICMPV6 unit tests - * \todo More ICMPv6 tests - */ -void DecodeICMPV6RegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("ICMPV6CalculateValidChecksumtest01", ICMPV6CalculateValidChecksumtest01, 1); - UtRegisterTest("ICMPV6CalculateInValidChecksumtest02", ICMPV6CalculateInvalidChecksumtest02, 0); - - UtRegisterTest("ICMPV6ParamProbTest01 (Valid)", ICMPV6ParamProbTest01, 1); - UtRegisterTest("ICMPV6DestUnreachTest01 (Valid)", ICMPV6DestUnreachTest01, 1); - UtRegisterTest("ICMPV6PktTooBigTest01 (Valid)", ICMPV6PktTooBigTest01, 1); - UtRegisterTest("ICMPV6TimeExceedTest01 (Valid)", ICMPV6TimeExceedTest01, 1); - UtRegisterTest("ICMPV6EchoReqTest01 (Valid)", ICMPV6EchoReqTest01, 1); - UtRegisterTest("ICMPV6EchoRepTest01 (Valid)", ICMPV6EchoRepTest01, 1); - - UtRegisterTest("ICMPV6ParamProbTest02 (Invalid)", ICMPV6ParamProbTest02, 1); - UtRegisterTest("ICMPV6DestUnreachTest02 (Invalid)", ICMPV6DestUnreachTest02, 1); - UtRegisterTest("ICMPV6PktTooBigTest02 (Invalid)", ICMPV6PktTooBigTest02, 1); - UtRegisterTest("ICMPV6TimeExceedTest02 (Invalid)", ICMPV6TimeExceedTest02, 1); - UtRegisterTest("ICMPV6EchoReqTest02 (Invalid)", ICMPV6EchoReqTest02, 1); - UtRegisterTest("ICMPV6EchoRepTest02 (Invalid)", ICMPV6EchoRepTest02, 1); - - UtRegisterTest("ICMPV6PayloadTest01", ICMPV6PayloadTest01, 1); - - UtRegisterTest("ICMPV6RouterSolicitTestKnownCode", - ICMPV6RouterSolicitTestKnownCode, 1); - UtRegisterTest("ICMPV6RouterSolicitTestUnknownCode", - ICMPV6RouterSolicitTestUnknownCode, 1); - UtRegisterTest("ICMPV6RouterAdvertTestKnownCode", - ICMPV6RouterAdvertTestKnownCode, 1); - UtRegisterTest("ICMPV6RouterAdvertTestUnknownCode", - ICMPV6RouterAdvertTestUnknownCode, 1); - - UtRegisterTest("ICMPV6NeighbourSolicitTestKnownCode", - ICMPV6NeighbourSolicitTestKnownCode, 1); - UtRegisterTest("ICMPV6NeighbourSolicitTestUnknownCode", - ICMPV6NeighbourSolicitTestUnknownCode, 1); - UtRegisterTest("ICMPV6NeighbourAdvertTestKnownCode", - ICMPV6NeighbourAdvertTestKnownCode, 1); - UtRegisterTest("ICMPV6NeighbourAdvertTestUnknownCode", - ICMPV6NeighbourAdvertTestUnknownCode, 1); - - UtRegisterTest("ICMPV6RedirectTestKnownCode", ICMPV6RedirectTestKnownCode, 1); - UtRegisterTest("ICMPV6RedirectTestUnknownCode", - ICMPV6RedirectTestUnknownCode, 1); -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-icmpv6.h b/framework/src/suricata/src/decode-icmpv6.h deleted file mode 100644 index af975006..00000000 --- a/framework/src/suricata/src/decode-icmpv6.h +++ /dev/null @@ -1,259 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DECODE_ICMPV6_H__ -#define __DECODE_ICMPV6_H__ - -#include "decode-tcp.h" -#include "decode-sctp.h" -#include "decode-udp.h" -#include "decode-ipv6.h" - -#define ICMPV6_HEADER_LEN 8 -#define ICMPV6_HEADER_PKT_OFFSET 8 - -/** ICMPV6 Message Types: */ -/** Error Messages: (type <128) */ -#define ICMP6_DST_UNREACH 1 -#define ICMP6_PACKET_TOO_BIG 2 -#define ICMP6_TIME_EXCEEDED 3 -#define ICMP6_PARAM_PROB 4 - -/** Informational Messages (type>=128) */ -#define ICMP6_ECHO_REQUEST 128 -#define ICMP6_ECHO_REPLY 129 - -#define MLD_LISTENER_QUERY 130 -#define MLD_LISTENER_REPORT 131 -#define MLD_LISTENER_REDUCTION 132 - -#define ND_ROUTER_SOLICIT 133 -#define ND_ROUTER_ADVERT 134 -#define ND_NEIGHBOR_SOLICIT 135 -#define ND_NEIGHBOR_ADVERT 136 -#define ND_REDIRECT 137 - -/** Destination Unreachable Message (type=1) Code: */ - -#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ -#define ICMP6_DST_UNREACH_ADMIN 1 /* communication with destination */ - /* administratively prohibited */ -#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ -#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ -#define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */ -#define ICMP6_DST_UNREACH_FAILEDPOLICY 5 /* Source address failed ingress/egress policy */ -#define ICMP6_DST_UNREACH_REJECTROUTE 6 /* Reject route to destination */ - - -/** Time Exceeded Message (type=3) Code: */ -#define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */ -#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */ - -/** Parameter Problem Message (type=4) Code: */ -#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ -#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */ -#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */ - - -/** macro for icmpv6 "type" access */ -#define ICMPV6_GET_TYPE(p) (p)->icmpv6h->type -/** macro for icmpv6 "code" access */ -#define ICMPV6_GET_CODE(p) (p)->icmpv6h->code -/** macro for icmpv6 "csum" access */ -#define ICMPV6_GET_CSUM(p) (p)->icmpv6h->csum - -/** If message is informational */ -/** macro for icmpv6 "id" access */ -#define ICMPV6_GET_ID(p) (p)->icmpv6vars.id -/** macro for icmpv6 "seq" access */ -#define ICMPV6_GET_SEQ(p) (p)->icmpv6vars.seq - -/** If message is Error */ -/** macro for icmpv6 "unused" access */ -#define ICMPV6_GET_UNUSED(p) (p)->icmpv6h->icmpv6b.icmpv6e.unused -/** macro for icmpv6 "error_ptr" access */ -#define ICMPV6_GET_ERROR_PTR(p) (p)->icmpv6h->icmpv6b.icmpv6e.error_ptr -/** macro for icmpv6 "mtu" access */ -#define ICMPV6_GET_MTU(p) (p)->icmpv6h->icmpv6b.icmpv6e.mtu - -/** macro for icmpv6 embedded "protocol" access */ -#define ICMPV6_GET_EMB_PROTO(p) (p)->icmpv6vars.emb_ip6_proto_next -/** macro for icmpv6 embedded "ipv6h" header access */ -#define ICMPV6_GET_EMB_IPV6(p) (p)->icmpv6vars.emb_ipv6h -/** macro for icmpv6 embedded "tcph" header access */ -#define ICMPV6_GET_EMB_TCP(p) (p)->icmpv6vars.emb_tcph -/** macro for icmpv6 embedded "udph" header access */ -#define ICMPV6_GET_EMB_UDP(p) (p)->icmpv6vars.emb_udph -/** macro for icmpv6 embedded "icmpv6h" header access */ -#define ICMPV6_GET_EMB_icmpv6h(p) (p)->icmpv6vars.emb_icmpv6h - -typedef struct ICMPV6Info_ -{ - uint16_t id; - uint16_t seq; -} ICMPV6Info; - -/** ICMPv6 header structure */ -typedef struct ICMPV6Hdr_ -{ - uint8_t type; - uint8_t code; - uint16_t csum; - - union { - ICMPV6Info icmpv6i; /** Informational message */ - union - { - uint32_t unused; /** for types 1 and 3, should be zero */ - uint32_t error_ptr; /** for type 4, pointer to the octet that originate the error */ - uint32_t mtu; /** for type 2, the Maximum Transmission Unit of the next-hop link */ - } icmpv6e; /** Error Message */ - } icmpv6b; -} ICMPV6Hdr; - -/** Data available from the decoded packet */ -typedef struct ICMPV6Vars_ { - /* checksum of the icmpv6 packet */ - uint16_t id; - uint16_t seq; - uint32_t mtu; - uint32_t error_ptr; - - /** Pointers to the embedded packet headers */ - IPV6Hdr *emb_ipv6h; - TCPHdr *emb_tcph; - UDPHdr *emb_udph; - ICMPV6Hdr *emb_icmpv6h; - - /** IPv6 src and dst address */ - uint32_t emb_ip6_src[4]; - uint32_t emb_ip6_dst[4]; - uint8_t emb_ip6_proto_next; - - /** TCP/UDP ports */ - uint16_t emb_sport; - uint16_t emb_dport; - -} ICMPV6Vars; - - -#define CLEAR_ICMPV6_PACKET(p) do { \ - (p)->level4_comp_csum = -1; \ - (p)->icmpv6vars.id = 0; \ - (p)->icmpv6vars.seq = 0; \ - (p)->icmpv6vars.mtu = 0; \ - (p)->icmpv6vars.error_ptr = 0; \ - (p)->icmpv6vars.emb_ipv6h = NULL; \ - (p)->icmpv6vars.emb_tcph = NULL; \ - (p)->icmpv6vars.emb_udph = NULL; \ - (p)->icmpv6vars.emb_icmpv6h = NULL; \ - (p)->icmpv6vars.emb_ip6_src[0] = 0; \ - (p)->icmpv6vars.emb_ip6_src[1] = 0; \ - (p)->icmpv6vars.emb_ip6_src[2] = 0; \ - (p)->icmpv6vars.emb_ip6_src[3] = 0; \ - (p)->icmpv6vars.emb_ip6_proto_next = 0; \ - (p)->icmpv6vars.emb_sport = 0; \ - (p)->icmpv6vars.emb_dport = 0; \ - (p)->icmpv6h = NULL; \ -} while(0) - -void DecodeICMPV6RegisterTests(void); - -/** -------- Inline functions --------- */ -static inline uint16_t ICMPV6CalculateChecksum(uint16_t *, uint16_t *, uint16_t); - -/** - * \brief Calculates the checksum for the ICMPV6 packet - * - * \param shdr Pointer to source address field from the IPV6 packet. Used as a - * part of the psuedoheader for computing the checksum - * \param pkt Pointer to the start of the ICMPV6 packet - * \param tlen Total length of the ICMPV6 packet(header + payload) - * - * \retval csum Checksum for the ICMPV6 packet - */ -static inline uint16_t ICMPV6CalculateChecksum(uint16_t *shdr, uint16_t *pkt, - uint16_t tlen) -{ - uint16_t pad = 0; - uint32_t csum = shdr[0]; - - csum += shdr[1] + shdr[2] + shdr[3] + shdr[4] + shdr[5] + shdr[6] + - shdr[7] + shdr[8] + shdr[9] + shdr[10] + shdr[11] + shdr[12] + - shdr[13] + shdr[14] + shdr[15] + htons(58 + tlen); - - csum += pkt[0]; - - tlen -= 4; - pkt += 2; - - while (tlen >= 64) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15] + pkt[16] + pkt[17] + pkt[18] + pkt[19] + - pkt[20] + pkt[21] + pkt[22] + pkt[23] + pkt[24] + pkt[25] + - pkt[26] + pkt[27] + pkt[28] + pkt[29] + pkt[30] + pkt[31]; - tlen -= 64; - pkt += 32; - } - - while (tlen >= 32) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15]; - tlen -= 32; - pkt += 16; - } - - while(tlen >= 8) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3]; - tlen -= 8; - pkt += 4; - } - - while(tlen >= 4) { - csum += pkt[0] + pkt[1]; - tlen -= 4; - pkt += 2; - } - - while (tlen > 1) { - csum += pkt[0]; - tlen -= 2; - pkt += 1; - } - - if (tlen == 1) { - *(uint8_t *)(&pad) = (*(uint8_t *)pkt); - csum += pad; - } - - csum = (csum >> 16) + (csum & 0x0000FFFF); - csum += (csum >> 16); - - return (uint16_t) ~csum; -} - - -#endif /* __DECODE_ICMPV6_H__ */ - diff --git a/framework/src/suricata/src/decode-ipv4.c b/framework/src/suricata/src/decode-ipv4.c deleted file mode 100644 index 63aae4ed..00000000 --- a/framework/src/suricata/src/decode-ipv4.c +++ /dev/null @@ -1,1913 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * \author Brian Rectanus - * - * Decode IPv4 - */ - -#include "suricata-common.h" -#include "packet-queue.h" -#include "decode.h" -#include "decode-ipv4.h" -#include "decode-events.h" -#include "defrag.h" -#include "pkt-var.h" -#include "host.h" - -#include "util-unittest.h" -#include "util-debug.h" -#include "util-optimize.h" -#include "util-print.h" -#include "util-profiling.h" - -/* Generic validation - * - * [--type--][--len---] - * - * \todo This function needs removed in favor of specific validation. - * - * See: RFC 791 - */ -static int IPV4OptValidateGeneric(Packet *p, const IPV4Opt *o) -{ - switch (o->type) { - /* See: RFC 4782 */ - case IPV4_OPT_QS: - if (p->IPV4_OPTS[p->IPV4_OPTS_CNT].len < IPV4_OPT_QS_MIN) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); - return -1; - } - break; - /* See: RFC 1108 */ - case IPV4_OPT_SEC: - if (p->IPV4_OPTS[p->IPV4_OPTS_CNT].len != IPV4_OPT_SEC_LEN) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); - return -1; - } - break; - case IPV4_OPT_SID: - if (p->IPV4_OPTS[p->IPV4_OPTS_CNT].len != IPV4_OPT_SID_LEN) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); - return -1; - } - break; - /* See: RFC 2113 */ - case IPV4_OPT_RTRALT: - if (p->IPV4_OPTS[p->IPV4_OPTS_CNT].len != IPV4_OPT_RTRALT_LEN) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); - return -1; - } - break; - default: - /* Should never get here unless there is a coding error */ - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_UNKNOWN); - return -1; - } - - return 0; -} - -/* Validate route type options - * - * [--type--][--len---][--ptr---][address1]...[addressN] - * - * See: RFC 791 - */ -static int IPV4OptValidateRoute(Packet *p, const IPV4Opt *o) -{ - uint8_t ptr; - - /* Check length */ - if (unlikely(o->len < IPV4_OPT_ROUTE_MIN)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); - return -1; - } - - /* Data is required */ - if (unlikely(o->data == NULL)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } - ptr = *o->data; - - /* Address pointer is 1 based and points at least after type+len+ptr, - * must be a incremented by 4 bytes (address size) and cannot extend - * past option length. - */ - if (unlikely((ptr < 4) || (ptr % 4) || (ptr > o->len + 1))) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } - - return 0; -} - -/* Validate timestamp type options - * - * [--type--][--len---][--ptr---][ovfl][flag][rec1----...]...[recN----...] - * NOTE: rec could be 4 (ts only) or 8 (ip+ts) bytes in length. - * - * See: RFC 781 - */ -static int IPV4OptValidateTimestamp(Packet *p, const IPV4Opt *o) -{ - uint8_t ptr; - uint8_t flag; - uint8_t rec_size; - - /* Check length */ - if (unlikely(o->len < IPV4_OPT_TS_MIN)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); - return -1; - } - - /* Data is required */ - if (unlikely(o->data == NULL)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } - ptr = *o->data; - - /* We need the flag to determine what is in the option payload */ - if (unlikely(ptr < 5)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } - flag = *(o->data + 3) & 0x00ff; - - /* A flag of 1|3 means we have both the ip+ts in each record */ - rec_size = ((flag == 1) || (flag == 3)) ? 8 : 4; - - /* Address pointer is 1 based and points at least after - * type+len+ptr+ovfl+flag, must be incremented by by the rec_size - * and cannot extend past option length. - */ - if (unlikely(((ptr - 5) % rec_size) || (ptr > o->len + 1))) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } - - return 0; -} - -/* Validate CIPSO option - * - * [--type--][--len---][--doi---][tags--...] - * - * See: draft-ietf-cipso-ipsecurity-01.txt - * See: FIPS 188 (tags 6 & 7) - */ -static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o) -{ -// uint32_t doi; - uint8_t *tag; - uint16_t len; - - /* Check length */ - if (unlikely(o->len < IPV4_OPT_CIPSO_MIN)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); - return -1; - } - - /* Data is required */ - if (unlikely(o->data == NULL)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } -// doi = *o->data; - tag = o->data + 4; - len = o->len - 1 - 1 - 4; /* Length of tags after header */ - - -#if 0 - /* Domain of Interest (DOI) of 0 is reserved and thus invalid */ - /** \todo Aparently a DOI of zero is fine in practice - verify. */ - if (doi == 0) { - ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED); - return -1; - } -#endif - - /* NOTE: We know len has passed min tests prior to this call */ - - /* Check that tags are formatted correctly - * [-ttype--][--tlen--][-tagdata-...] - */ - while (len) { - uint8_t ttype; - uint8_t tlen; - - /* Tag header must fit within option length */ - if (unlikely(len < 2)) { - //printf("CIPSO tag header too large %" PRIu16 " < 2\n", len); - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } - - /* Tag header is type+len */ - ttype = *(tag++); - tlen = *(tag++); - - /* Tag length must fit within the option length */ - if (unlikely(tlen > len)) { - //printf("CIPSO tag len too large %" PRIu8 " > %" PRIu16 "\n", tlen, len); - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } - - switch(ttype) { - case 1: - case 2: - case 5: - case 6: - case 7: - /* Tag is at least 4 and at most the remainder of option len */ - if (unlikely((tlen < 4) || (tlen > len))) { - //printf("CIPSO tag %" PRIu8 " bad tlen=%" PRIu8 " len=%" PRIu8 "\n", ttype, tlen, len); - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } - - /* The alignment octet is always 0 except tag - * type 7, which has no such field. - */ - if (unlikely((ttype != 7) && (*tag != 0))) { - //printf("CIPSO tag %" PRIu8 " ao=%" PRIu8 "\n", ttype, tlen); - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - return -1; - } - - /* Skip the rest of the tag payload */ - tag += tlen - 2; - len -= tlen; - - continue; - case 0: - /* Tag type 0 is reserved and thus invalid */ - /** \todo Wireshark marks this a padding, but spec says reserved. */ - ENGINE_SET_INVALID_EVENT(p,IPV4_OPT_MALFORMED); - return -1; - default: - //printf("CIPSO tag %" PRIu8 " unknown tag\n", ttype); - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_MALFORMED); - /** \todo May not want to return error here on unknown tag type (at least not for 3|4) */ - return -1; - } - } - - return 0; -} - -/** - * Decode/Validate IPv4 Options. - */ -static int DecodeIPV4Options(Packet *p, uint8_t *pkt, uint16_t len) -{ - uint16_t plen = len; - - p->IPV4_OPTS_CNT = 0; - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - uint16_t i; - char buf[256] = ""; - int offset = 0; - - for (i = 0; i < len; i++) { - offset += snprintf(buf + offset, (sizeof(buf) - offset), "%02" PRIx8 " ", pkt[i]); - } - SCLogDebug("IPV4OPTS: { %s}", buf); - } -#endif - - /* Options length must be padded to 8byte boundary */ - if (plen % 8) { - ENGINE_SET_EVENT(p,IPV4_OPT_PAD_REQUIRED); - /* Warn - we can keep going */ - } - - while (plen) - { - /* single byte options */ - if (*pkt == IPV4_OPT_EOL) { - /** \todo What if more data exist after EOL (possible covert channel or data leakage)? */ - SCLogDebug("IPV4OPT %" PRIu16 " len 1 @ %" PRIu16 "/%" PRIu16 "", - *pkt, (len - plen), (len - 1)); - break; - } else if (*pkt == IPV4_OPT_NOP) { - SCLogDebug("IPV4OPT %" PRIu16 " len 1 @ %" PRIu16 "/%" PRIu16 "", - *pkt, (len - plen), (len - 1)); - pkt++; - plen--; - - /* multibyte options */ - } else { - if (unlikely(plen < 2)) { - /** \todo What if padding is non-zero (possible covert channel or data leakage)? */ - /** \todo Spec seems to indicate EOL required if there is padding */ - ENGINE_SET_EVENT(p,IPV4_OPT_EOL_REQUIRED); - break; - } - - /* Option length is too big for packet */ - if (unlikely(*(pkt+1) > plen)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); - return -1; - } - - p->IPV4_OPTS[p->IPV4_OPTS_CNT].type = *pkt; - p->IPV4_OPTS[p->IPV4_OPTS_CNT].len = *(pkt+1); - if (plen > 2) - p->IPV4_OPTS[p->IPV4_OPTS_CNT].data = (pkt+2); - else - p->IPV4_OPTS[p->IPV4_OPTS_CNT].data = NULL; - - SCLogDebug("IPV4OPT %" PRIu16 " len %" PRIu16 " @ %" PRIu16 "/%" PRIu16 "", - p->IPV4_OPTS[p->IPV4_OPTS_CNT].type, p->IPV4_OPTS[p->IPV4_OPTS_CNT].len, - (len - plen), (len - 1)); - - /* we already know that the total options len is valid, - * so here the len of the specific option must be bad. - * Also check for invalid lengths 0 and 1. */ - if (unlikely(p->IPV4_OPTS[p->IPV4_OPTS_CNT].len > plen || - p->IPV4_OPTS[p->IPV4_OPTS_CNT].len < 2)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_OPT_INVALID_LEN); - return -1; - } - - /* we are parsing the most commonly used opts to prevent - * us from having to walk the opts list for these all the - * time. */ - /** \todo Figure out which IP options are more common and list them first */ - switch (p->IPV4_OPTS[p->IPV4_OPTS_CNT].type) { - case IPV4_OPT_TS: - if (p->ip4vars.o_ts != NULL) { - ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); - /* Warn - we can keep going */ - break; - } else if (IPV4OptValidateTimestamp(p,&p->IPV4_OPTS[p->IPV4_OPTS_CNT])) { - return -1; - } - p->ip4vars.o_ts = &p->IPV4_OPTS[p->IPV4_OPTS_CNT]; - break; - case IPV4_OPT_RR: - if (p->ip4vars.o_rr != NULL) { - ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); - /* Warn - we can keep going */ - break; - } else if (IPV4OptValidateRoute(p,&p->IPV4_OPTS[p->IPV4_OPTS_CNT]) != 0) { - return -1; - } - p->ip4vars.o_rr = &p->IPV4_OPTS[p->IPV4_OPTS_CNT]; - break; - case IPV4_OPT_QS: - if (p->ip4vars.o_qs != NULL) { - ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); - /* Warn - we can keep going */ - break; - } else if (IPV4OptValidateGeneric(p, &p->IPV4_OPTS[p->IPV4_OPTS_CNT])) { - return -1; - } - p->ip4vars.o_qs = &p->IPV4_OPTS[p->IPV4_OPTS_CNT]; - break; - case IPV4_OPT_SEC: - if (p->ip4vars.o_sec != NULL) { - ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); - /* Warn - we can keep going */ - break; - } else if (IPV4OptValidateGeneric(p, &p->IPV4_OPTS[p->IPV4_OPTS_CNT])) { - return -1; - } - p->ip4vars.o_sec = &p->IPV4_OPTS[p->IPV4_OPTS_CNT]; - break; - case IPV4_OPT_LSRR: - if (p->ip4vars.o_lsrr != NULL) { - ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); - /* Warn - we can keep going */ - break; - } else if (IPV4OptValidateRoute(p,&p->IPV4_OPTS[p->IPV4_OPTS_CNT]) != 0) { - return -1; - } - p->ip4vars.o_lsrr = &p->IPV4_OPTS[p->IPV4_OPTS_CNT]; - break; - case IPV4_OPT_CIPSO: - if (p->ip4vars.o_cipso != NULL) { - ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); - /* Warn - we can keep going */ - break; - } else if (IPV4OptValidateCIPSO(p,&p->IPV4_OPTS[p->IPV4_OPTS_CNT]) != 0) { - return -1; - } - p->ip4vars.o_cipso = &p->IPV4_OPTS[p->IPV4_OPTS_CNT]; - break; - case IPV4_OPT_SID: - if (p->ip4vars.o_sid != NULL) { - ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); - /* Warn - we can keep going */ - break; - } else if (IPV4OptValidateGeneric(p, &p->IPV4_OPTS[p->IPV4_OPTS_CNT])) { - return -1; - } - p->ip4vars.o_sid = &p->IPV4_OPTS[p->IPV4_OPTS_CNT]; - break; - case IPV4_OPT_SSRR: - if (p->ip4vars.o_ssrr != NULL) { - ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); - /* Warn - we can keep going */ - break; - } else if (IPV4OptValidateRoute(p,&p->IPV4_OPTS[p->IPV4_OPTS_CNT]) != 0) { - return -1; - } - p->ip4vars.o_ssrr = &p->IPV4_OPTS[p->IPV4_OPTS_CNT]; - break; - case IPV4_OPT_RTRALT: - if (p->ip4vars.o_rtralt != NULL) { - ENGINE_SET_EVENT(p,IPV4_OPT_DUPLICATE); - /* Warn - we can keep going */ - break; - } else if (IPV4OptValidateGeneric(p, &p->IPV4_OPTS[p->IPV4_OPTS_CNT])) { - return -1; - } - p->ip4vars.o_rtralt = &p->IPV4_OPTS[p->IPV4_OPTS_CNT]; - break; - default: - SCLogDebug("IPV4OPT (%" PRIu8 ") len %" PRIu8 "", - p->IPV4_OPTS[p->IPV4_OPTS_CNT].type, - p->IPV4_OPTS[p->IPV4_OPTS_CNT].len); - ENGINE_SET_EVENT(p,IPV4_OPT_INVALID); - /* Warn - we can keep going */ - break; - } - - pkt += p->IPV4_OPTS[p->IPV4_OPTS_CNT].len; - plen -= (p->IPV4_OPTS[p->IPV4_OPTS_CNT].len); - p->IPV4_OPTS_CNT++; - } - } - - return 0; -} - -static int DecodeIPV4Packet(Packet *p, uint8_t *pkt, uint16_t len) -{ - if (unlikely(len < IPV4_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_PKT_TOO_SMALL); - return -1; - } - - if (unlikely(IP_GET_RAW_VER(pkt) != 4)) { - SCLogDebug("wrong ip version %" PRIu8 "",IP_GET_RAW_VER(pkt)); - ENGINE_SET_INVALID_EVENT(p, IPV4_WRONG_IP_VER); - return -1; - } - - p->ip4h = (IPV4Hdr *)pkt; - - if (unlikely(IPV4_GET_HLEN(p) < IPV4_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_HLEN_TOO_SMALL); - return -1; - } - - if (unlikely(IPV4_GET_IPLEN(p) < IPV4_GET_HLEN(p))) { - ENGINE_SET_INVALID_EVENT(p, IPV4_IPLEN_SMALLER_THAN_HLEN); - return -1; - } - - if (unlikely(len < IPV4_GET_IPLEN(p))) { - ENGINE_SET_INVALID_EVENT(p, IPV4_TRUNC_PKT); - return -1; - } - - /* set the address struct */ - SET_IPV4_SRC_ADDR(p,&p->src); - SET_IPV4_DST_ADDR(p,&p->dst); - - /* save the options len */ - uint8_t ip_opt_len = IPV4_GET_HLEN(p) - IPV4_HEADER_LEN; - if (ip_opt_len > 0) { - DecodeIPV4Options(p, pkt + IPV4_HEADER_LEN, ip_opt_len); - } - - return 0; -} - -int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_ipv4); - - SCLogDebug("pkt %p len %"PRIu16"", pkt, len); - - /* do the actual decoding */ - if (unlikely(DecodeIPV4Packet (p, pkt, len) < 0)) { - SCLogDebug("decoding IPv4 packet failed"); - p->ip4h = NULL; - return TM_ECODE_FAILED; - } - p->proto = IPV4_GET_IPPROTO(p); - - /* If a fragment, pass off for re-assembly. */ - if (unlikely(IPV4_GET_IPOFFSET(p) > 0 || IPV4_GET_MF(p) == 1)) { - Packet *rp = Defrag(tv, dtv, p, pq); - if (rp != NULL) { - PacketEnqueue(pq, rp); - } - p->flags |= PKT_IS_FRAGMENT; - return TM_ECODE_OK; - } - - /* do hdr test, process hdr rules */ - -#ifdef DEBUG - if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */ - /* debug print */ - char s[16], d[16]; - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), s, sizeof(s)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), d, sizeof(d)); - SCLogDebug("IPV4 %s->%s PROTO: %" PRIu32 " OFFSET: %" PRIu32 " RF: %" PRIu32 " DF: %" PRIu32 " MF: %" PRIu32 " ID: %" PRIu32 "", s,d, - IPV4_GET_IPPROTO(p), IPV4_GET_IPOFFSET(p), IPV4_GET_RF(p), - IPV4_GET_DF(p), IPV4_GET_MF(p), IPV4_GET_IPID(p)); - } -#endif /* DEBUG */ - - /* check what next decoder to invoke */ - switch (IPV4_GET_IPPROTO(p)) { - case IPPROTO_TCP: - DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), - IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); - break; - case IPPROTO_UDP: - DecodeUDP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), - IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); - break; - case IPPROTO_ICMP: - DecodeICMPV4(tv, dtv, p, pkt + IPV4_GET_HLEN(p), - IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); - break; - case IPPROTO_GRE: - DecodeGRE(tv, dtv, p, pkt + IPV4_GET_HLEN(p), - IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); - break; - case IPPROTO_SCTP: - DecodeSCTP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), - IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); - break; - case IPPROTO_IPV6: - { - if (pq != NULL) { - /* spawn off tunnel packet */ - Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + IPV4_GET_HLEN(p), - IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), - DECODE_TUNNEL_IPV6, pq); - if (tp != NULL) { - PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV4); - PacketEnqueue(pq,tp); - } - } - break; - } - case IPPROTO_IP: - /* check PPP VJ uncompressed packets and decode tcp dummy */ - if(p->ppph != NULL && ntohs(p->ppph->protocol) == PPP_VJ_UCOMP) { - DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), - IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq); - } - break; - case IPPROTO_ICMPV6: - ENGINE_SET_INVALID_EVENT(p, IPV4_WITH_ICMPV6); - break; - } - - return TM_ECODE_OK; -} - -/* UNITTESTS */ -#ifdef UNITTESTS - -void DecodeIPV4OptionsPrint(Packet *p) -{ - IPV4Vars *pv = &p->ip4vars; - - printf("DecodeIPV4Options: cnt=%" PRIu8 - ",rr={t=%" PRIu8 ",l=%" PRIu8 ",d=%p}" - ",qs={t=%" PRIu8 ",l=%" PRIu8 ",d=%p}" - ",ts={t=%" PRIu8 ",l=%" PRIu8 ",d=%p}" - ",sec={t=%" PRIu8 ",l=%" PRIu8 ",d=%p}" - ",lsrr={t=%" PRIu8 ",l=%" PRIu8 ",d=%p}" - ",cipso={t=%" PRIu8 ",l=%" PRIu8 ",d=%p}" - ",sid={t=%" PRIu8 ",l=%" PRIu8 ",d=%p}" - ",ssrr={t=%" PRIu8 ",l=%" PRIu8 ",d=%p}" - ",rtralt={t=%" PRIu8 ",l=%" PRIu8 ",d=%p}" - "}\n", - pv->ip_opt_cnt, - (pv->o_rr ? pv->o_rr->type : 0), (pv->o_rr ? pv->o_rr->len : 0), (pv->o_rr ? pv->o_rr->data : 0), - (pv->o_qs ? pv->o_qs->type : 0), (pv->o_qs ? pv->o_qs->len : 0), (pv->o_qs ? pv->o_qs->data : 0), - (pv->o_ts ? pv->o_ts->type : 0), (pv->o_ts ? pv->o_ts->len : 0), (pv->o_ts ? pv->o_ts->data : 0), - (pv->o_sec ? pv->o_sec->type : 0), (pv->o_sec ? pv->o_sec->len : 0), (pv->o_sec ? pv->o_sec->data : 0), - (pv->o_lsrr ? pv->o_lsrr->type : 0), (pv->o_lsrr ? pv->o_lsrr->len : 0), (pv->o_lsrr ? pv->o_lsrr->data : 0), - (pv->o_cipso ? pv->o_cipso->type : 0), (pv->o_cipso ? pv->o_cipso->len : 0), (pv->o_cipso ? pv->o_cipso->data : 0), - (pv->o_sid ? pv->o_sid->type : 0), (pv->o_sid ? pv->o_sid->len : 0), (pv->o_sid ? pv->o_sid->data : 0), - (pv->o_ssrr ? pv->o_ssrr->type : 0), (pv->o_ssrr ? pv->o_ssrr->len : 0), (pv->o_ssrr ? pv->o_ssrr->data : 0), - (pv->o_rtralt ? pv->o_rtralt->type : 0), (pv->o_rtralt ? pv->o_rtralt->len : 0), (pv->o_rtralt ? pv->o_rtralt->data : 0)); -} - -/** \test IPV4 with no options. */ -int DecodeIPV4OptionsNONETest01(void) -{ - uint8_t raw_opts[] = { }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - uint8_t *data = (uint8_t *)p; - uint16_t i; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - if (rc != 0) { - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; - } - - for (i = 0; i < (uint16_t)SIZE_OF_PACKET; i++) { - if (*data) { - /* Should not have modified packet data */ - //printf("Data modified at offset %" PRIu16 "\n", i); - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; - } - } - - SCFree(p); - return 1; -} - -/** \test IPV4 with EOL option. */ -int DecodeIPV4OptionsEOLTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_EOL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - uint8_t *data = (uint8_t *)p; - uint16_t i; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - if (rc != 0) { - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; - } - - for (i = 0; i < (uint16_t)SIZE_OF_PACKET; i++) { - if (*data) { - /* Should not have modified packet data */ - //printf("Data modified at offset %" PRIu16 "\n", i); - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; - } - } - - SCFree(p); - return 1; -} - -/** \test IPV4 with NOP option. */ -int DecodeIPV4OptionsNOPTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_NOP, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - uint8_t *data = (uint8_t *)p; - uint16_t i; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - if (rc != 0) { - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; - } - - for (i = 0; i < (uint16_t)SIZE_OF_PACKET; i++) { - if (*data) { - /* Should not have modified packet data */ - //printf("Data modified at offset %" PRIu16 "\n", i); - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; - } - } - - SCFree(p); - return 1; -} - -/** \test IPV4 with RR option. */ -int DecodeIPV4OptionsRRTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_RR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",rr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_rr, (uintmax_t)&p.IPV4_OPTS[0]); - if ( (rc == 0) - && (p->IPV4_OPTS_CNT == 1) - && (p->IPV4_OPTS[0].type == IPV4_OPT_RR) - && (p->IPV4_OPTS[0].len == 0x27) - && (p->ip4vars.o_rr == &p->IPV4_OPTS[0])) - { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with RR option (len too large). */ -int DecodeIPV4OptionsRRTest02(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_RR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",rr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_rr, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with RR option (ptr too large). */ -int DecodeIPV4OptionsRRTest03(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_RR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",rr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_rr, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with RR option (ptr not in 4 byte increment). */ -int DecodeIPV4OptionsRRTest04(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_RR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",rr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_rr, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with QS option. */ -int DecodeIPV4OptionsQSTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_QS, 0x08, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",qs=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_qs, (uintmax_t)&p.IPV4_OPTS[0]); - if ( (rc == 0) - && (p->IPV4_OPTS_CNT == 1) - && (p->IPV4_OPTS[0].type == IPV4_OPT_QS) - && (p->IPV4_OPTS[0].len == 0x08) - && (p->ip4vars.o_qs == &p->IPV4_OPTS[0])) - { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with QS option (len too small) */ -int DecodeIPV4OptionsQSTest02(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_QS, 0x07, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",qs=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_qs, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with TS option. */ -int DecodeIPV4OptionsTSTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_TS, 0x24, 0x0d, 0x01, 0x0a, 0x0a, 0x0a, 0x69, - 0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",ts=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_ts, (uintmax_t)&p.IPV4_OPTS[0]); - if ( (rc == 0) - && (p->IPV4_OPTS_CNT == 1) - && (p->IPV4_OPTS[0].type == IPV4_OPT_TS) - && (p->IPV4_OPTS[0].len == 0x24) - && (p->ip4vars.o_ts == &p->IPV4_OPTS[0])) - { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with TS option (ptr too small). */ -int DecodeIPV4OptionsTSTest02(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_TS, 0x24, 0x04, 0x01, 0x0a, 0x0a, 0x0a, 0x69, - 0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",ts=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_ts, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with TS option (ptr too large). */ -int DecodeIPV4OptionsTSTest03(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_TS, 0x24, 0xff, 0x01, 0x0a, 0x0a, 0x0a, 0x69, - 0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",ts=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_ts, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with TS option (ptr not valid). */ -int DecodeIPV4OptionsTSTest04(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_TS, 0x24, 0x0a, 0x01, 0x0a, 0x0a, 0x0a, 0x69, - 0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",ts=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_ts, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with SEC option. */ -int DecodeIPV4OptionsSECTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_SEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",sec=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_sec, (uintmax_t)&p.IPV4_OPTS[0]); - if ( (rc == 0) - && (p->IPV4_OPTS_CNT == 1) - && (p->IPV4_OPTS[0].type == IPV4_OPT_SEC) - && (p->IPV4_OPTS[0].len == 0x0b) - && (p->ip4vars.o_sec == &p->IPV4_OPTS[0])) - { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with SEC option (invalid length). */ -int DecodeIPV4OptionsSECTest02(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_SEC, 0x0a, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",sec=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_sec, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with LSRR option. */ -int DecodeIPV4OptionsLSRRTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_LSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",lsrr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_lsrr, (uintmax_t)&p.IPV4_OPTS[0]); - if ( (rc == 0) - && (p->IPV4_OPTS_CNT == 1) - && (p->IPV4_OPTS[0].type == IPV4_OPT_LSRR) - && (p->IPV4_OPTS[0].len == 0x27) - && (p->ip4vars.o_lsrr == &p->IPV4_OPTS[0])) - { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with LSRR option (len too large). */ -int DecodeIPV4OptionsLSRRTest02(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_LSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",lsrr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_lsrr, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with LSRR option (ptr too large). */ -int DecodeIPV4OptionsLSRRTest03(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_LSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",lsrr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_lsrr, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with LSRR option (ptr not in 4 byte increment). */ -int DecodeIPV4OptionsLSRRTest04(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_LSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",lsrr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_lsrr, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with CIPSO option. */ -int DecodeIPV4OptionsCIPSOTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_CIPSO, 0x18, 0x00, 0x00, 0x00, 0x05, 0x05, 0x12, - 0x00, 0x03, 0x00, 0xef, 0x00, 0xef, 0x00, 0x06, - 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",rr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_cipso, (uintmax_t)&p.IPV4_OPTS[0]); - if ( (rc == 0) - && (p->IPV4_OPTS_CNT == 1) - && (p->IPV4_OPTS[0].type == IPV4_OPT_CIPSO) - && (p->IPV4_OPTS[0].len == 0x18) - && (p->ip4vars.o_cipso == &p->IPV4_OPTS[0])) - { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with SID option. */ -int DecodeIPV4OptionsSIDTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_SID, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",sid=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_sid, (uintmax_t)&p.IPV4_OPTS[0]); - if ( (rc == 0) - && (p->IPV4_OPTS_CNT == 1) - && (p->IPV4_OPTS[0].type == IPV4_OPT_SID) - && (p->IPV4_OPTS[0].len == 0x04) - && (p->ip4vars.o_sid == &p->IPV4_OPTS[0])) - { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with SID option (len invalid. */ -int DecodeIPV4OptionsSIDTest02(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_SID, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",sid=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_sid, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with SSRR option. */ -int DecodeIPV4OptionsSSRRTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_SSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",ssrr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_ssrr, (uintmax_t)&p.IPV4_OPTS[0]); - if ( (rc == 0) - && (p->IPV4_OPTS_CNT == 1) - && (p->IPV4_OPTS[0].type == IPV4_OPT_SSRR) - && (p->IPV4_OPTS[0].len == 0x27) - && (p->ip4vars.o_ssrr == &p->IPV4_OPTS[0])) - { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with SSRR option (len too large). */ -int DecodeIPV4OptionsSSRRTest02(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_SSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",ssrr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_ssrr, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with SSRR option (ptr too large). */ -int DecodeIPV4OptionsSSRRTest03(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_SSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",ssrr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_ssrr, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with SSRR option (ptr not in 4 byte increment). */ -int DecodeIPV4OptionsSSRRTest04(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_SSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",ssrr=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_ssrr, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with RTRALT option. */ -int DecodeIPV4OptionsRTRALTTest01(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_RTRALT, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",rtralt=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_rtralt, (uintmax_t)&p.IPV4_OPTS[0]); - if ( (rc == 0) - && (p->IPV4_OPTS_CNT == 1) - && (p->IPV4_OPTS[0].type == IPV4_OPT_RTRALT) - && (p->IPV4_OPTS[0].len == 0x04) - && (p->ip4vars.o_rtralt == &p->IPV4_OPTS[0])) - { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -/** \test IPV4 with RTRALT option (len invalid. */ -int DecodeIPV4OptionsRTRALTTest02(void) -{ - uint8_t raw_opts[] = { - IPV4_OPT_RTRALT, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00 - }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - int rc; - - rc = DecodeIPV4Options(p, raw_opts, sizeof(raw_opts)); - //printf("rc=%d,cnt=%" PRIu16 ",type=%" PRIu8 ",len=%" PRIu8 ",rtralt=%" PRIuMAX "/%" PRIuMAX "\n", rc, p.IPV4_OPTS_CNT, p.IPV4_OPTS[0].type, p.IPV4_OPTS[0].len, (uintmax_t)p.ip4vars.o_rtralt, (uintmax_t)&p.IPV4_OPTS[0]); - if (rc != 0) { - SCFree(p); - return 1; - } - - DecodeIPV4OptionsPrint(p); - SCFree(p); - return 0; -} - -static int IPV4CalculateValidChecksumtest01(void) -{ - uint16_t csum = 0; - - uint8_t raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03, - 0xc0, 0xa8, 0x01, 0x03}; - - csum = *( ((uint16_t *)raw_ipv4) + 5); - - return (csum == IPV4CalculateChecksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4))); -} - -static int IPV4CalculateInvalidChecksumtest02(void) -{ - uint16_t csum = 0; - - uint8_t raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03, - 0xc0, 0xa8, 0x01, 0x07}; - - csum = *( ((uint16_t *)raw_ipv4) + 5); - - return (csum == IPV4CalculateChecksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4))); -} - -/** - * \test IPV4 defrag and packet recursion level test - */ -int DecodeIPV4DefragTest01(void) -{ - uint8_t pkt1[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06, - 0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, - 0x81, 0x5e - }; - uint8_t pkt2[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06, - 0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, - 0x80, 0x00 - }; - uint8_t pkt3[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06, - 0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00 - }; - uint8_t tunnel_pkt[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06, - 0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, - 0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, - 0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00 - }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - PacketQueue pq; - int result = 1; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&pq, 0, sizeof(PacketQueue)); - - FlowInitConfig(FLOW_QUIET); - DefragInit(); - - PacketCopyData(p, pkt1, sizeof(pkt1)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph != NULL) { - printf("tcp header should be NULL for ip fragment, but it isn't\n"); - result = 0; - goto end; - } - PACKET_RECYCLE(p); - - PacketCopyData(p, pkt2, sizeof(pkt2)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph != NULL) { - printf("tcp header should be NULL for ip fragment, but it isn't\n"); - result = 0; - goto end; - } - PACKET_RECYCLE(p); - - PacketCopyData(p, pkt3, sizeof(pkt3)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph != NULL) { - printf("tcp header should be NULL for ip fragment, but it isn't\n"); - result = 0; - goto end; - } - Packet *tp = PacketDequeue(&pq); - if (tp == NULL) { - printf("Failed to get defragged pseudo packet\n"); - result = 0; - goto end; - } - if (tp->recursion_level != p->recursion_level) { - printf("defragged pseudo packet's and parent packet's recursion " - "level don't match\n %d != %d", - tp->recursion_level, p->recursion_level); - result = 0; - goto end; - } - if (tp->ip4h == NULL || tp->tcph == NULL) { - printf("pseudo packet's ip header and tcp header shouldn't be NULL, " - "but it is\n"); - result = 0; - goto end; - } - if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) { - printf("defragged pseudo packet's and parent packet's pkt lens " - "don't match\n %u != %"PRIuMAX, - GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt)); - result = 0; - goto end; - } - if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) { - result = 0; - goto end; - } - - PACKET_RECYCLE(tp); - SCFree(tp); - -end: - DefragDestroy(); - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return result; -} - -/** - * \test Don't send IPv4 fragments to the upper layer decoder and - * and packet recursion level test. - */ -int DecodeIPV4DefragTest02(void) -{ - uint8_t pkt1[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x24, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06, - 0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, - /* first frag */ - 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, - 0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, - 0x80, 0x00, - }; - uint8_t pkt2[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x2c, 0xe9, 0xef, 0x20, 0x02, 0x40, 0x06, - 0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, - /* second frag */ - 0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e, - 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00, - 0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04 - }; - uint8_t pkt3[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x16, 0xe9, 0xef, 0x00, 0x05, 0x40, 0x06, - 0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, - /* final frag */ - 0xb1, 0xa3, - }; - - uint8_t tunnel_pkt[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3e, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06, - 0xba, 0xae, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, - 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, 0x81, 0x5e, - 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00, - 0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e, - 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00, - 0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04, - 0xb1, 0xa3, - }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - PacketQueue pq; - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&pq, 0, sizeof(PacketQueue)); - - FlowInitConfig(FLOW_QUIET); - DefragInit(); - - PacketCopyData(p, pkt1, sizeof(pkt1)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph != NULL) { - printf("tcp header should be NULL for ip fragment, but it isn't\n"); - goto end; - } - PACKET_RECYCLE(p); - - PacketCopyData(p, pkt2, sizeof(pkt2)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph != NULL) { - printf("tcp header should be NULL for ip fragment, but it isn't\n"); - goto end; - } - PACKET_RECYCLE(p); - - p->recursion_level = 3; - PacketCopyData(p, pkt3, sizeof(pkt3)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph != NULL) { - printf("tcp header should be NULL for ip fragment, but it isn't\n"); - goto end; - } - Packet *tp = PacketDequeue(&pq); - if (tp == NULL) { - printf("Failed to get defragged pseudo packet\n"); - goto end; - } - if (tp->recursion_level != p->recursion_level) { - printf("defragged pseudo packet's and parent packet's recursion " - "level don't match %d != %d: ", - tp->recursion_level, p->recursion_level); - goto end; - } - if (tp->ip4h == NULL || tp->tcph == NULL) { - printf("pseudo packet's ip header and tcp header shouldn't be NULL, " - "but it is\n"); - goto end; - } - if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) { - printf("defragged pseudo packet's and parent packet's pkt lens " - "don't match %u != %"PRIuMAX": ", - GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt)); - goto end; - } - - if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) { - goto end; - } - - result = 1; - PACKET_RECYCLE(tp); - SCFree(tp); - -end: - DefragDestroy(); - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return result; -} - -/** - * \test IPV4 defrag and flow retrieval test. - */ -int DecodeIPV4DefragTest03(void) -{ - uint8_t pkt[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x28, 0xe9, 0xee, 0x00, 0x00, 0x40, 0x06, - 0xba, 0xbd, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, - 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, - 0x80, 0x00, 0x0c, 0xee, 0x00, 0x00 - }; - uint8_t pkt1[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06, - 0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, - 0x81, 0x5e - }; - uint8_t pkt2[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06, - 0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, - 0x80, 0x00 - }; - uint8_t pkt3[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06, - 0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00 - }; - uint8_t tunnel_pkt[] = { - 0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad, - 0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06, - 0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00, - 0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, - 0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, - 0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00 - }; - - Flow *f = NULL; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - PacketQueue pq; - int result = 1; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&pq, 0, sizeof(PacketQueue)); - - FlowInitConfig(FLOW_QUIET); - DefragInit(); - - PacketCopyData(p, pkt, sizeof(pkt)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph == NULL) { - printf("tcp header shouldn't be NULL, but it is\n"); - result = 0; - goto end; - } - if (p->flow == NULL) { - printf("packet flow shouldn't be NULL\n"); - result = 0; - goto end; - } - f = p->flow; - PACKET_RECYCLE(p); - - PacketCopyData(p, pkt1, sizeof(pkt1)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph != NULL) { - printf("tcp header should be NULL for ip fragment, but it isn't\n"); - result = 0; - goto end; - } - PACKET_RECYCLE(p); - - PacketCopyData(p, pkt2, sizeof(pkt2)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph != NULL) { - printf("tcp header should be NULL for ip fragment, but it isn't\n"); - result = 0; - goto end; - } - PACKET_RECYCLE(p); - - PacketCopyData(p, pkt3, sizeof(pkt3)); - DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN, - GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq); - if (p->tcph != NULL) { - printf("tcp header should be NULL for ip fragment, but it isn't\n"); - result = 0; - goto end; - } - - Packet *tp = PacketDequeue(&pq); - if (tp == NULL) { - printf("Failed to get defragged pseudo packet\n"); - result = 0; - goto end; - } - if (tp->flow == NULL) { - result = 0; - goto end; - } - if (tp->flow != f) { - result = 0; - goto end; - } - if (tp->recursion_level != p->recursion_level) { - printf("defragged pseudo packet's and parent packet's recursion " - "level don't match\n %d != %d", - tp->recursion_level, p->recursion_level); - result = 0; - goto end; - } - if (tp->ip4h == NULL || tp->tcph == NULL) { - printf("pseudo packet's ip header and tcp header shouldn't be NULL, " - "but it is\n"); - result = 0; - goto end; - } - if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) { - printf("defragged pseudo packet's and parent packet's pkt lens " - "don't match\n %u != %"PRIuMAX, - GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt)); - result = 0; - goto end; - } - - if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) { - result = 0; - goto end; - } - - PACKET_RECYCLE(tp); - SCFree(tp); - -end: - DefragDestroy(); - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return result; -} - -#endif /* UNITTESTS */ - -void DecodeIPV4RegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodeIPV4OptionsNONETest01", DecodeIPV4OptionsNONETest01, 1); - UtRegisterTest("DecodeIPV4OptionsEOLTest01", DecodeIPV4OptionsEOLTest01, 1); - UtRegisterTest("DecodeIPV4OptionsNOPTest01", DecodeIPV4OptionsNOPTest01, 1); - UtRegisterTest("DecodeIPV4OptionsRRTest01", DecodeIPV4OptionsRRTest01, 1); - UtRegisterTest("DecodeIPV4OptionsRRTest02", DecodeIPV4OptionsRRTest02, 1); - UtRegisterTest("DecodeIPV4OptionsRRTest03", DecodeIPV4OptionsRRTest03, 1); - UtRegisterTest("DecodeIPV4OptionsRRTest04", DecodeIPV4OptionsRRTest04, 1); - UtRegisterTest("DecodeIPV4OptionsQSTest01", DecodeIPV4OptionsQSTest01, 1); - UtRegisterTest("DecodeIPV4OptionsQSTest02", DecodeIPV4OptionsQSTest02, 1); - UtRegisterTest("DecodeIPV4OptionsTSTest01", DecodeIPV4OptionsTSTest01, 1); - UtRegisterTest("DecodeIPV4OptionsTSTest02", DecodeIPV4OptionsTSTest02, 1); - UtRegisterTest("DecodeIPV4OptionsTSTest03", DecodeIPV4OptionsTSTest03, 1); - UtRegisterTest("DecodeIPV4OptionsTSTest04", DecodeIPV4OptionsTSTest04, 1); - UtRegisterTest("DecodeIPV4OptionsSECTest01", DecodeIPV4OptionsSECTest01, 1); - UtRegisterTest("DecodeIPV4OptionsSECTest02", DecodeIPV4OptionsSECTest02, 1); - UtRegisterTest("DecodeIPV4OptionsLSRRTest01", DecodeIPV4OptionsLSRRTest01, 1); - UtRegisterTest("DecodeIPV4OptionsLSRRTest02", DecodeIPV4OptionsLSRRTest02, 1); - UtRegisterTest("DecodeIPV4OptionsLSRRTest03", DecodeIPV4OptionsLSRRTest03, 1); - UtRegisterTest("DecodeIPV4OptionsLSRRTest04", DecodeIPV4OptionsLSRRTest04, 1); - UtRegisterTest("DecodeIPV4OptionsCIPSOTest01", DecodeIPV4OptionsCIPSOTest01, 1); - UtRegisterTest("DecodeIPV4OptionsSIDTest01", DecodeIPV4OptionsSIDTest01, 1); - UtRegisterTest("DecodeIPV4OptionsSIDTest02", DecodeIPV4OptionsSIDTest02, 1); - UtRegisterTest("DecodeIPV4OptionsSSRRTest01", DecodeIPV4OptionsSSRRTest01, 1); - UtRegisterTest("DecodeIPV4OptionsSSRRTest02", DecodeIPV4OptionsSSRRTest02, 1); - UtRegisterTest("DecodeIPV4OptionsSSRRTest03", DecodeIPV4OptionsSSRRTest03, 1); - UtRegisterTest("DecodeIPV4OptionsSSRRTest04", DecodeIPV4OptionsSSRRTest04, 1); - UtRegisterTest("DecodeIPV4OptionsRTRALTTest01", DecodeIPV4OptionsRTRALTTest01, 1); - UtRegisterTest("DecodeIPV4OptionsRTRALTTest02", DecodeIPV4OptionsRTRALTTest02, 1); - UtRegisterTest("IPV4CalculateValidChecksumtest01", - IPV4CalculateValidChecksumtest01, 1); - UtRegisterTest("IPV4CalculateInvalidChecksumtest02", - IPV4CalculateInvalidChecksumtest02, 0); - UtRegisterTest("DecodeIPV4DefragTest01", DecodeIPV4DefragTest01, 1); - UtRegisterTest("DecodeIPV4DefragTest02", DecodeIPV4DefragTest02, 1); - UtRegisterTest("DecodeIPV4DefragTest03", DecodeIPV4DefragTest03, 1); -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-ipv4.h b/framework/src/suricata/src/decode-ipv4.h deleted file mode 100644 index be212bf2..00000000 --- a/framework/src/suricata/src/decode-ipv4.h +++ /dev/null @@ -1,254 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Brian Rectanus - */ - -#ifndef __DECODE_IPV4_H__ -#define __DECODE_IPV4_H__ - -#define IPV4_HEADER_LEN 20 /**< Header length */ -#define IPV4_OPTMAX 40 /**< Max options length */ -#define IPV4_MAXPACKET_LEN 65535 /**< Maximum packet size */ - -/** IP Option Types */ -#define IPV4_OPT_EOL 0x00 /**< Option: End of List */ -#define IPV4_OPT_NOP 0x01 /**< Option: No op */ -#define IPV4_OPT_RR 0x07 /**< Option: Record Route */ -#define IPV4_OPT_QS 0x19 /**< Option: Quick Start */ -#define IPV4_OPT_TS 0x44 /**< Option: Timestamp */ -#define IPV4_OPT_SEC 0x82 /**< Option: Security */ -#define IPV4_OPT_LSRR 0x83 /**< Option: Loose Source Route */ -#define IPV4_OPT_CIPSO 0x86 /**< Option: Commercial IP Security */ -#define IPV4_OPT_SID 0x88 /**< Option: Stream Identifier */ -#define IPV4_OPT_SSRR 0x89 /**< Option: Strict Source Route */ -#define IPV4_OPT_RTRALT 0x94 /**< Option: Router Alert */ - -/** IP Option Lengths (fixed) */ -#define IPV4_OPT_SEC_LEN 11 /**< SEC Option Fixed Length */ -#define IPV4_OPT_SID_LEN 4 /**< SID Option Fixed Length */ -#define IPV4_OPT_RTRALT_LEN 4 /**< RTRALT Option Fixed Length */ - -/** IP Option Lengths (variable) */ -#define IPV4_OPT_ROUTE_MIN 3 /**< RR, SRR, LTRR Option Min Length */ -#define IPV4_OPT_QS_MIN 8 /**< QS Option Min Length */ -#define IPV4_OPT_TS_MIN 5 /**< TS Option Min Length */ -#define IPV4_OPT_CIPSO_MIN 10 /**< CIPSO Option Min Length */ - -/** IP Option fields */ -#define IPV4_OPTS ip4vars.ip_opts -#define IPV4_OPTS_CNT ip4vars.ip_opt_cnt - -typedef struct IPV4Opt_ { - /** \todo We may want to break type up into its 3 fields - * as the reassembler may want to know which options - * must be copied to each fragment. - */ - uint8_t type; /**< option type */ - uint8_t len; /**< option length (type+len+data) */ - uint8_t *data; /**< option data */ -} IPV4Opt; - -typedef struct IPV4Hdr_ -{ - uint8_t ip_verhl; /**< version & header length */ - uint8_t ip_tos; /**< type of service */ - uint16_t ip_len; /**< length */ - uint16_t ip_id; /**< id */ - uint16_t ip_off; /**< frag offset */ - uint8_t ip_ttl; /**< time to live */ - uint8_t ip_proto; /**< protocol (tcp, udp, etc) */ - uint16_t ip_csum; /**< checksum */ - union { - struct { - struct in_addr ip_src;/**< source address */ - struct in_addr ip_dst;/**< destination address */ - } ip4_un1; - uint16_t ip_addrs[4]; - } ip4_hdrun1; -} __attribute__((__packed__)) IPV4Hdr; - - -#define s_ip_src ip4_hdrun1.ip4_un1.ip_src -#define s_ip_dst ip4_hdrun1.ip4_un1.ip_dst -#define s_ip_addrs ip4_hdrun1.ip_addrs - -#define IPV4_GET_RAW_VER(ip4h) (((ip4h)->ip_verhl & 0xf0) >> 4) -#define IPV4_GET_RAW_HLEN(ip4h) ((ip4h)->ip_verhl & 0x0f) -#define IPV4_GET_RAW_IPTOS(ip4h) ((ip4h)->ip_tos) -#define IPV4_GET_RAW_IPLEN(ip4h) ((ip4h)->ip_len) -#define IPV4_GET_RAW_IPID(ip4h) ((ip4h)->ip_id) -#define IPV4_GET_RAW_IPOFFSET(ip4h) ((ip4h)->ip_off) -#define IPV4_GET_RAW_IPTTL(ip4h) ((ip4h)->ip_ttl) -#define IPV4_GET_RAW_IPPROTO(ip4h) ((ip4h)->ip_proto) -#define IPV4_GET_RAW_IPSRC(ip4h) ((ip4h)->s_ip_src) -#define IPV4_GET_RAW_IPDST(ip4h) ((ip4h)->s_ip_dst) - -/** return the raw (directly from the header) src ip as uint32_t */ -#define IPV4_GET_RAW_IPSRC_U32(ip4h) (uint32_t)((ip4h)->s_ip_src.s_addr) -/** return the raw (directly from the header) dst ip as uint32_t */ -#define IPV4_GET_RAW_IPDST_U32(ip4h) (uint32_t)((ip4h)->s_ip_dst.s_addr) - -/* we need to change them as well as get them */ -#define IPV4_SET_RAW_VER(ip4h, value) ((ip4h)->ip_verhl = (((ip4h)->ip_verhl & 0x0f) | (value << 4))) -#define IPV4_SET_RAW_HLEN(ip4h, value) ((ip4h)->ip_verhl = (((ip4h)->ip_verhl & 0xf0) | (value & 0x0f))) -#define IPV4_SET_RAW_IPTOS(ip4h, value) ((ip4h)->ip_tos = value) -#define IPV4_SET_RAW_IPLEN(ip4h, value) ((ip4h)->ip_len = value) -#define IPV4_SET_RAW_IPPROTO(ip4h, value) ((ip4h)->ip_proto = value) - -/* ONLY call these functions after making sure that: - * 1. p->ip4h is set - * 2. p->ip4h is valid (len is correct) - */ -#define IPV4_GET_VER(p) \ - IPV4_GET_RAW_VER((p)->ip4h) -#define IPV4_GET_HLEN(p) \ - (IPV4_GET_RAW_HLEN((p)->ip4h) << 2) -#define IPV4_GET_IPTOS(p) \ - IPV4_GET_RAW_IPTOS((p)->ip4h) -#define IPV4_GET_IPLEN(p) \ - (ntohs(IPV4_GET_RAW_IPLEN((p)->ip4h))) -#define IPV4_GET_IPID(p) \ - (ntohs(IPV4_GET_RAW_IPID((p)->ip4h))) -/* _IPV4_GET_IPOFFSET: get the content of the offset header field in host order */ -#define _IPV4_GET_IPOFFSET(p) \ - (ntohs(IPV4_GET_RAW_IPOFFSET((p)->ip4h))) -/* IPV4_GET_IPOFFSET: get the final offset */ -#define IPV4_GET_IPOFFSET(p) \ - (_IPV4_GET_IPOFFSET(p) & 0x1fff) -/* IPV4_GET_RF: get the RF flag. Use _IPV4_GET_IPOFFSET to save a ntohs call. */ -#define IPV4_GET_RF(p) \ - (uint8_t)((_IPV4_GET_IPOFFSET((p)) & 0x8000) >> 15) -/* IPV4_GET_DF: get the DF flag. Use _IPV4_GET_IPOFFSET to save a ntohs call. */ -#define IPV4_GET_DF(p) \ - (uint8_t)((_IPV4_GET_IPOFFSET((p)) & 0x4000) >> 14) -/* IPV4_GET_MF: get the MF flag. Use _IPV4_GET_IPOFFSET to save a ntohs call. */ -#define IPV4_GET_MF(p) \ - (uint8_t)((_IPV4_GET_IPOFFSET((p)) & 0x2000) >> 13) -#define IPV4_GET_IPTTL(p) \ - IPV4_GET_RAW_IPTTL(p->ip4h) -#define IPV4_GET_IPPROTO(p) \ - IPV4_GET_RAW_IPPROTO((p)->ip4h) - -#define CLEAR_IPV4_PACKET(p) do { \ - (p)->ip4h = NULL; \ - (p)->level3_comp_csum = -1; \ - (p)->ip4vars.ip_src_u32 = 0; \ - (p)->ip4vars.ip_dst_u32 = 0; \ - (p)->ip4vars.ip_opt_cnt = 0; \ - (p)->ip4vars.o_rr = NULL; \ - (p)->ip4vars.o_qs = NULL; \ - (p)->ip4vars.o_ts = NULL; \ - (p)->ip4vars.o_sec = NULL; \ - (p)->ip4vars.o_lsrr = NULL; \ - (p)->ip4vars.o_cipso = NULL; \ - (p)->ip4vars.o_sid = NULL; \ - (p)->ip4vars.o_ssrr = NULL; \ - (p)->ip4vars.o_rtralt = NULL; \ -} while (0) - -/* helper structure with parsed ipv4 info */ -typedef struct IPV4Vars_ -{ - int32_t comp_csum; /* checksum computed over the ipv4 packet */ - uint32_t ip_src_u32; /* source IP */ - uint32_t ip_dst_u32; /* dest IP */ - - IPV4Opt ip_opts[IPV4_OPTMAX]; - uint8_t ip_opt_cnt; - - /* These are here for direct access and dup tracking */ - IPV4Opt *o_rr; - IPV4Opt *o_qs; - IPV4Opt *o_ts; - IPV4Opt *o_sec; - IPV4Opt *o_lsrr; - IPV4Opt *o_cipso; - IPV4Opt *o_sid; - IPV4Opt *o_ssrr; - IPV4Opt *o_rtralt; -} IPV4Vars; - - -void DecodeIPV4RegisterTests(void); - -/** ----- Inline functions ----- */ -static inline uint16_t IPV4CalculateChecksum(uint16_t *, uint16_t); -/** - * \brief Calculates the checksum for the IP packet - * - * \param pkt Pointer to the start of the IP packet - * \param hlen Length of the IP header - * - * \retval csum Checksum for the IP packet - */ -static inline uint16_t IPV4CalculateChecksum(uint16_t *pkt, uint16_t hlen) -{ - uint32_t csum = pkt[0]; - - csum += pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[6] + pkt[7] + pkt[8] + - pkt[9]; - - hlen -= 20; - pkt += 10; - - if (hlen == 0) { - ; - } else if (hlen == 4) { - csum += pkt[0] + pkt[1]; - } else if (hlen == 8) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3]; - } else if (hlen == 12) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5]; - } else if (hlen == 16) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7]; - } else if (hlen == 20) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9]; - } else if (hlen == 24) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11]; - } else if (hlen == 28) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13]; - } else if (hlen == 32) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15]; - } else if (hlen == 36) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15] + pkt[16] + pkt[17]; - } else if (hlen == 40) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15] + pkt[16] + pkt[17] + pkt[18] + pkt[19]; - } - - csum = (csum >> 16) + (csum & 0x0000FFFF); - csum += (csum >> 16); - - return (uint16_t) ~csum; -} - -#endif /* __DECODE_IPV4_H__ */ - diff --git a/framework/src/suricata/src/decode-ipv6.c b/framework/src/suricata/src/decode-ipv6.c deleted file mode 100644 index 21ae5226..00000000 --- a/framework/src/suricata/src/decode-ipv6.c +++ /dev/null @@ -1,1001 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decode IPv6 - */ - -#include "suricata-common.h" -#include "packet-queue.h" -#include "decode.h" -#include "decode-ipv6.h" -#include "decode-icmpv6.h" -#include "decode-events.h" -#include "defrag.h" -#include "pkt-var.h" -#include "util-debug.h" -#include "util-print.h" -#include "util-unittest.h" -#include "util-profiling.h" -#include "host.h" - -#define IPV6_EXTHDRS ip6eh.ip6_exthdrs -#define IPV6_EH_CNT ip6eh.ip6_exthdrs_cnt - -/** - * \brief Function to decode IPv4 in IPv6 packets - * - */ -static void DecodeIPv4inIPv6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t plen, PacketQueue *pq) -{ - - if (unlikely(plen < IPV4_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_IN_IPV6_PKT_TOO_SMALL); - return; - } - if (IP_GET_RAW_VER(pkt) == 4) { - if (pq != NULL) { - Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt, plen, DECODE_TUNNEL_IPV4, pq); - if (tp != NULL) { - PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6); - /* add the tp to the packet queue. */ - PacketEnqueue(pq,tp); - StatsIncr(tv, dtv->counter_ipv4inipv6); - return; - } - } - } else { - ENGINE_SET_EVENT(p, IPV4_IN_IPV6_WRONG_IP_VER); - } - return; -} - -/** - * \brief Function to decode IPv6 in IPv6 packets - * - */ -static int DecodeIP6inIP6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t plen, PacketQueue *pq) -{ - - if (unlikely(plen < IPV6_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, IPV6_IN_IPV6_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - if (IP_GET_RAW_VER(pkt) == 6) { - if (unlikely(pq != NULL)) { - Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt, plen, DECODE_TUNNEL_IPV6, pq); - if (tp != NULL) { - PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6); - PacketEnqueue(pq,tp); - StatsIncr(tv, dtv->counter_ipv6inipv6); - } - } - } else { - ENGINE_SET_EVENT(p, IPV6_IN_IPV6_WRONG_IP_VER); - } - return TM_ECODE_OK; -} - -static void -DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - SCEnter(); - - uint8_t *orig_pkt = pkt; - uint8_t nh = 0; /* careful, 0 is actually a real type */ - uint16_t hdrextlen; - uint16_t plen; - char dstopts = 0; - char exthdr_fh_done = 0; - - nh = IPV6_GET_NH(p); - plen = len; - - while(1) - { - /* No upper layer, but we do have data. Suspicious. */ - if (nh == IPPROTO_NONE && plen > 0) { - ENGINE_SET_EVENT(p, IPV6_DATA_AFTER_NONE_HEADER); - SCReturn; - } - - if (plen < 2) { /* minimal needed in a hdr */ - SCReturn; - } - - switch(nh) - { - case IPPROTO_TCP: - IPV6_SET_L4PROTO(p,nh); - DecodeTCP(tv, dtv, p, pkt, plen, pq); - SCReturn; - - case IPPROTO_UDP: - IPV6_SET_L4PROTO(p,nh); - DecodeUDP(tv, dtv, p, pkt, plen, pq); - SCReturn; - - case IPPROTO_ICMPV6: - IPV6_SET_L4PROTO(p,nh); - DecodeICMPV6(tv, dtv, p, pkt, plen, pq); - SCReturn; - - case IPPROTO_SCTP: - IPV6_SET_L4PROTO(p,nh); - DecodeSCTP(tv, dtv, p, pkt, plen, pq); - SCReturn; - - case IPPROTO_ROUTING: - IPV6_SET_L4PROTO(p,nh); - hdrextlen = 8 + (*(pkt+1) * 8); /* 8 bytes + length in 8 octet units */ - - SCLogDebug("hdrextlen %"PRIu8, hdrextlen); - - if (hdrextlen > plen) { - ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR); - SCReturn; - } - - if (p->IPV6_EH_CNT < IPV6_MAX_OPT) - { - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2; - p->IPV6_EH_CNT++; - } - - if (IPV6_EXTHDR_ISSET_RH(p)) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_RH); - /* skip past this extension so we can continue parsing the rest - * of the packet */ - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } - - IPV6_EXTHDR_SET_RH(p, pkt); - - /** \todo move into own function and load on demand */ - if (IPV6_EXTHDR_RH(p)->ip6rh_type == 0) { -#if 0 // XXX usused and broken, original packet is modified in the memcpy - uint8_t i; - - uint8_t n = hdrextlen / 2; - /* because we devide the header len by 2 (as rfc 2460 tells us to) - * we devide the result by 8 and not 16 as the header fields are - * sized */ - for (i = 0; i < (n/8) && i < sizeof(IPV6_EXTHDR_RH(p)->ip6rh0_addr)/sizeof(struct in6_addr); ++i) { - /* the address header fields are 16 bytes in size */ - /** \todo do this without memcpy since it's expensive */ - memcpy(&IPV6_EXTHDR_RH(p)->ip6rh0_addr[i], pkt+(i*16)+8, sizeof(IPV6_EXTHDR_RH(p)->ip6rh0_addr[i])); - } - IPV6_EXTHDR_RH(p)->ip6rh0_num_addrs = i; -#endif - ENGINE_SET_EVENT(p, IPV6_EXTHDR_RH_TYPE_0); - } - - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - - case IPPROTO_HOPOPTS: - case IPPROTO_DSTOPTS: - { - IPV6OptHAO *hao = NULL; - IPV6OptRA *ra = NULL; - IPV6OptJumbo *jumbo = NULL; - uint16_t optslen = 0; - - IPV6_SET_L4PROTO(p,nh); - hdrextlen = (*(pkt+1) + 1) << 3; - if (hdrextlen > plen) { - ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR); - SCReturn; - } - - if (p->IPV6_EH_CNT < IPV6_MAX_OPT) - { - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2; - p->IPV6_EH_CNT++; - } - - uint8_t *ptr = pkt + 2; /* +2 to go past nxthdr and len */ - - /* point the pointers to right structures - * in Packet. */ - if (nh == IPPROTO_HOPOPTS) { - if (IPV6_EXTHDR_ISSET_HH(p)) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_HH); - /* skip past this extension so we can continue parsing the rest - * of the packet */ - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } - - IPV6_EXTHDR_SET_HH(p, pkt); - hao = &IPV6_EXTHDR_HH_HAO(p); - ra = &IPV6_EXTHDR_HH_RA(p); - jumbo = &IPV6_EXTHDR_HH_JUMBO(p); - - optslen = ((IPV6_EXTHDR_HH(p)->ip6hh_len+1)<<3)-2; - } - else if (nh == IPPROTO_DSTOPTS) - { - if (dstopts == 0) { - IPV6_EXTHDR_SET_DH1(p, pkt); - hao = &IPV6_EXTHDR_DH1_HAO(p); - ra = &IPV6_EXTHDR_DH1_RA(p); - jumbo = &IPV6_EXTHDR_DH2_JUMBO(p); - optslen = ((IPV6_EXTHDR_DH1(p)->ip6dh_len+1)<<3)-2; - dstopts = 1; - } else if (dstopts == 1) { - IPV6_EXTHDR_SET_DH2(p, pkt); - hao = &IPV6_EXTHDR_DH2_HAO(p); - ra = &IPV6_EXTHDR_DH2_RA(p); - jumbo = &IPV6_EXTHDR_DH2_JUMBO(p); - optslen = ((IPV6_EXTHDR_DH2(p)->ip6dh_len+1)<<3)-2; - dstopts = 2; - } else { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_DH); - /* skip past this extension so we can continue parsing the rest - * of the packet */ - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } - } - - if (optslen > plen) { - /* since the packet is long enough (we checked - * plen against hdrlen, the optlen must be malformed. */ - ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN); - /* skip past this extension so we can continue parsing the rest - * of the packet */ - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } -/** \todo move into own function to loaded on demand */ - uint16_t padn_cnt = 0; - uint16_t other_cnt = 0; - uint16_t offset = 0; - while(offset < optslen) - { - if (*ptr == IPV6OPT_PAD1) - { - padn_cnt++; - offset++; - ptr++; - continue; - } - - if (offset + 1 >= optslen) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN); - break; - } - - /* length field for each opt */ - uint8_t ip6_optlen = *(ptr + 1); - - /* see if the optlen from the packet fits the total optslen */ - if ((offset + 1 + ip6_optlen) > optslen) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN); - break; - } - - if (*ptr == IPV6OPT_PADN) /* PadN */ - { - //printf("PadN option\n"); - padn_cnt++; - - /* a zero padN len would be weird */ - if (ip6_optlen == 0) - ENGINE_SET_EVENT(p, IPV6_EXTHDR_ZERO_LEN_PADN); - } - else if (*ptr == IPV6OPT_RA) /* RA */ - { - ra->ip6ra_type = *(ptr); - ra->ip6ra_len = ip6_optlen; - - if (ip6_optlen < sizeof(ra->ip6ra_value)) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN); - break; - } - - memcpy(&ra->ip6ra_value, (ptr + 2), sizeof(ra->ip6ra_value)); - ra->ip6ra_value = ntohs(ra->ip6ra_value); - //printf("RA option: type %" PRIu32 " len %" PRIu32 " value %" PRIu32 "\n", - // ra->ip6ra_type, ra->ip6ra_len, ra->ip6ra_value); - other_cnt++; - } - else if (*ptr == IPV6OPT_JUMBO) /* Jumbo */ - { - jumbo->ip6j_type = *(ptr); - jumbo->ip6j_len = ip6_optlen; - - if (ip6_optlen < sizeof(jumbo->ip6j_payload_len)) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN); - break; - } - - memcpy(&jumbo->ip6j_payload_len, (ptr+2), sizeof(jumbo->ip6j_payload_len)); - jumbo->ip6j_payload_len = ntohl(jumbo->ip6j_payload_len); - //printf("Jumbo option: type %" PRIu32 " len %" PRIu32 " payload len %" PRIu32 "\n", - // jumbo->ip6j_type, jumbo->ip6j_len, jumbo->ip6j_payload_len); - } - else if (*ptr == IPV6OPT_HAO) /* HAO */ - { - hao->ip6hao_type = *(ptr); - hao->ip6hao_len = ip6_optlen; - - if (ip6_optlen < sizeof(hao->ip6hao_hoa)) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN); - break; - } - - memcpy(&hao->ip6hao_hoa, (ptr+2), sizeof(hao->ip6hao_hoa)); - //printf("HAO option: type %" PRIu32 " len %" PRIu32 " ", - // hao->ip6hao_type, hao->ip6hao_len); - //char addr_buf[46]; - //PrintInet(AF_INET6, (char *)&(hao->ip6hao_hoa), - // addr_buf,sizeof(addr_buf)); - //printf("home addr %s\n", addr_buf); - other_cnt++; - } else { - if (nh == IPPROTO_HOPOPTS) - ENGINE_SET_EVENT(p, IPV6_HOPOPTS_UNKNOWN_OPT); - else - ENGINE_SET_EVENT(p, IPV6_DSTOPTS_UNKNOWN_OPT); - - other_cnt++; - } - uint16_t optlen = (*(ptr + 1) + 2); - ptr += optlen; /* +2 for opt type and opt len fields */ - offset += optlen; - } - /* flag packets that have only padding */ - if (padn_cnt > 0 && other_cnt == 0) { - if (nh == IPPROTO_HOPOPTS) - ENGINE_SET_EVENT(p, IPV6_HOPOPTS_ONLY_PADDING); - else - ENGINE_SET_EVENT(p, IPV6_DSTOPTS_ONLY_PADDING); - } - - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } - - case IPPROTO_FRAGMENT: - IPV6_SET_L4PROTO(p,nh); - /* store the offset of this extension into the packet - * past the ipv6 header. We use it in defrag for creating - * a defragmented packet without the frag header */ - if (exthdr_fh_done == 0) { - p->ip6eh.fh_offset = pkt - orig_pkt; - exthdr_fh_done = 1; - } - - hdrextlen = sizeof(IPV6FragHdr); - if (hdrextlen > plen) { - ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR); - SCReturn; - } - - /* for the frag header, the length field is reserved */ - if (*(pkt + 1) != 0) { - ENGINE_SET_EVENT(p, IPV6_FH_NON_ZERO_RES_FIELD); - /* non fatal, lets try to continue */ - } - - if(p->IPV6_EH_CNTIPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2; - p->IPV6_EH_CNT++; - } - - if (IPV6_EXTHDR_ISSET_FH(p)) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_FH); - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } - - /* set the header ptr first */ - IPV6_EXTHDR_SET_FH(p, pkt); - - /* if FH has offset 0 and no more fragments are coming, we - * parse this packet further right away, no defrag will be - * needed. It is a useless FH then though, so we do set an - * decoder event. */ - if (IPV6_EXTHDR_GET_FH_FLAG(p) == 0 && IPV6_EXTHDR_GET_FH_OFFSET(p) == 0) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_USELESS_FH); - - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } - - /* the rest is parsed upon reassembly */ - p->flags |= PKT_IS_FRAGMENT; - SCReturn; - - case IPPROTO_ESP: - { - IPV6_SET_L4PROTO(p,nh); - hdrextlen = sizeof(IPV6EspHdr); - if (hdrextlen > plen) { - ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR); - SCReturn; - } - - if(p->IPV6_EH_CNTIPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = IPPROTO_NONE; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2; - p->IPV6_EH_CNT++; - } - - if (IPV6_EXTHDR_ISSET_EH(p)) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_EH); - SCReturn; - } - - IPV6_EXTHDR_SET_EH(p, pkt); - - nh = IPPROTO_NONE; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } - case IPPROTO_AH: - { - IPV6_SET_L4PROTO(p,nh); - /* we need the header as a minimum */ - hdrextlen = sizeof(IPV6AuthHdr); - /* the payload len field is the number of extra 4 byte fields, - * IPV6AuthHdr already contains the first */ - if (*(pkt+1) > 0) - hdrextlen += ((*(pkt+1) - 1) * 4); - - SCLogDebug("hdrextlen %"PRIu8, hdrextlen); - - if (hdrextlen > plen) { - ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR); - SCReturn; - } - - IPV6AuthHdr *ahhdr = (IPV6AuthHdr *)pkt; - if (ahhdr->ip6ah_reserved != 0x0000) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_AH_RES_NOT_NULL); - } - - if(p->IPV6_EH_CNT < IPV6_MAX_OPT) - { - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen; - p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2; - p->IPV6_EH_CNT++; - } - - if (IPV6_EXTHDR_ISSET_AH(p)) { - ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_AH); - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } - - IPV6_EXTHDR_SET_AH(p, pkt); - - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - } - case IPPROTO_IPIP: - IPV6_SET_L4PROTO(p,nh); - DecodeIPv4inIPv6(tv, dtv, p, pkt, plen, pq); - SCReturn; - /* none, last header */ - case IPPROTO_NONE: - IPV6_SET_L4PROTO(p,nh); - SCReturn; - case IPPROTO_ICMP: - ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4); - SCReturn; - /* no parsing yet, just skip it */ - case IPPROTO_MH: - case IPPROTO_HIP: - case IPPROTO_SHIM6: - hdrextlen = 8 + (*(pkt+1) * 8); /* 8 bytes + length in 8 octet units */ - if (hdrextlen > plen) { - ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR); - SCReturn; - } - nh = *pkt; - pkt += hdrextlen; - plen -= hdrextlen; - break; - default: - ENGINE_SET_EVENT(p, IPV6_UNKNOWN_NEXT_HEADER); - IPV6_SET_L4PROTO(p,nh); - SCReturn; - } - } - - SCReturn; -} - -static int DecodeIPV6Packet (ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len) -{ - if (unlikely(len < IPV6_HEADER_LEN)) { - return -1; - } - - if (unlikely(IP_GET_RAW_VER(pkt) != 6)) { - SCLogDebug("wrong ip version %" PRIu8 "",IP_GET_RAW_VER(pkt)); - ENGINE_SET_INVALID_EVENT(p, IPV6_WRONG_IP_VER); - return -1; - } - - p->ip6h = (IPV6Hdr *)pkt; - - if (unlikely(len < (IPV6_HEADER_LEN + IPV6_GET_PLEN(p)))) - { - ENGINE_SET_INVALID_EVENT(p, IPV6_TRUNC_PKT); - return -1; - } - - SET_IPV6_SRC_ADDR(p,&p->src); - SET_IPV6_DST_ADDR(p,&p->dst); - - return 0; -} - -int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - int ret; - - StatsIncr(tv, dtv->counter_ipv6); - - /* do the actual decoding */ - ret = DecodeIPV6Packet (tv, dtv, p, pkt, len); - if (unlikely(ret < 0)) { - p->ip6h = NULL; - return TM_ECODE_FAILED; - } - -#ifdef DEBUG - if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */ - /* debug print */ - char s[46], d[46]; - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), s, sizeof(s)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), d, sizeof(d)); - SCLogDebug("IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: %" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32 "", s,d, - IPV6_GET_CLASS(p), IPV6_GET_FLOW(p), IPV6_GET_NH(p), IPV6_GET_PLEN(p), - IPV6_GET_HLIM(p)); - } -#endif /* DEBUG */ - - /* now process the Ext headers and/or the L4 Layer */ - switch(IPV6_GET_NH(p)) { - case IPPROTO_TCP: - IPV6_SET_L4PROTO (p, IPPROTO_TCP); - DecodeTCP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); - return TM_ECODE_OK; - case IPPROTO_UDP: - IPV6_SET_L4PROTO (p, IPPROTO_UDP); - DecodeUDP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); - return TM_ECODE_OK; - case IPPROTO_ICMPV6: - IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6); - DecodeICMPV6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); - return TM_ECODE_OK; - case IPPROTO_SCTP: - IPV6_SET_L4PROTO (p, IPPROTO_SCTP); - DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); - return TM_ECODE_OK; - case IPPROTO_IPIP: - IPV6_SET_L4PROTO(p, IPPROTO_IPIP); - DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); - return TM_ECODE_OK; - case IPPROTO_IPV6: - DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); - return TM_ECODE_OK; - case IPPROTO_FRAGMENT: - case IPPROTO_HOPOPTS: - case IPPROTO_ROUTING: - case IPPROTO_NONE: - case IPPROTO_DSTOPTS: - case IPPROTO_AH: - case IPPROTO_ESP: - case IPPROTO_MH: - case IPPROTO_HIP: - case IPPROTO_SHIM6: - DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq); - break; - case IPPROTO_ICMP: - ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4); - break; - default: - ENGINE_SET_EVENT(p, IPV6_UNKNOWN_NEXT_HEADER); - IPV6_SET_L4PROTO (p, IPV6_GET_NH(p)); - break; - } - p->proto = IPV6_GET_L4PROTO (p); - - /* Pass to defragger if a fragment. */ - if (IPV6_EXTHDR_ISSET_FH(p)) { - Packet *rp = Defrag(tv, dtv, p, pq); - if (rp != NULL) { - PacketEnqueue(pq,rp); - } - } - -#ifdef DEBUG - if (IPV6_EXTHDR_ISSET_FH(p)) { - SCLogDebug("IPV6 FRAG - HDRLEN: %" PRIuMAX " NH: %" PRIu32 " OFFSET: %" PRIu32 " ID: %" PRIu32 "", - (uintmax_t)IPV6_EXTHDR_GET_FH_HDRLEN(p), IPV6_EXTHDR_GET_FH_NH(p), - IPV6_EXTHDR_GET_FH_OFFSET(p), IPV6_EXTHDR_GET_FH_ID(p)); - } - if (IPV6_EXTHDR_ISSET_RH(p)) { - SCLogDebug("IPV6 ROUTE - HDRLEN: %" PRIu32 " NH: %" PRIu32 " TYPE: %" PRIu32 "", - IPV6_EXTHDR_GET_RH_HDRLEN(p), IPV6_EXTHDR_GET_RH_NH(p), - IPV6_EXTHDR_GET_RH_TYPE(p)); - } - if (IPV6_EXTHDR_ISSET_HH(p)) { - SCLogDebug("IPV6 HOPOPT - HDRLEN: %" PRIu32 " NH: %" PRIu32 "", - IPV6_EXTHDR_GET_HH_HDRLEN(p), IPV6_EXTHDR_GET_HH_NH(p)); - } - if (IPV6_EXTHDR_ISSET_DH1(p)) { - SCLogDebug("IPV6 DSTOPT1 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "", - IPV6_EXTHDR_GET_DH1_HDRLEN(p), IPV6_EXTHDR_GET_DH1_NH(p)); - } - if (IPV6_EXTHDR_ISSET_DH2(p)) { - SCLogDebug("IPV6 DSTOPT2 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "", - IPV6_EXTHDR_GET_DH2_HDRLEN(p), IPV6_EXTHDR_GET_DH2_NH(p)); - } -#endif - return TM_ECODE_OK; -} - -#ifdef UNITTESTS - -/** - * \test fragment decoding - */ -static int DecodeIPV6FragTest01 (void) -{ - - uint8_t raw_frag1[] = { - 0x60, 0x0f, 0x1a, 0xcf, 0x05, 0xa8, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01, - 0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x00, 0x01, 0xdf, 0xf8, 0x11, 0xd7, - 0x00, 0x50, 0xa6, 0x5c, 0xcc, 0xd7, 0x28, 0x9f, 0xc3, 0x34, 0xc6, 0x58, 0x80, 0x10, 0x20, 0x13, - 0x18, 0x1f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xcd, 0xf9, 0x3a, 0x41, 0x00, 0x1a, 0x91, 0x8a, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x30, 0x32, 0x20, 0x44, - 0x65, 0x63, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x38, 0x3a, 0x33, 0x32, 0x3a, 0x35, 0x37, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x50, - 0x72, 0x61, 0x67, 0x6d, 0x61, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d, - 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, - 0x31, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x31, 0x39, 0x37, 0x31, 0x20, 0x30, 0x30, 0x3a, 0x30, 0x30, - 0x3a, 0x30, 0x30, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x35, 0x39, 0x39, 0x0d, 0x0a, 0x4b, - 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x3a, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x3d, 0x35, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x3d, 0x39, 0x39, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41, - 0x6c, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, - 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x73, - 0x65, 0x74, 0x3d, 0x61, 0x73, 0x63, 0x69, 0x69, 0x0d, 0x0a, 0x0d, 0x0a, 0x5f, 0x6a, 0x71, 0x6a, - 0x73, 0x70, 0x28, 0x7b, 0x22, 0x69, 0x70, 0x22, 0x3a, 0x22, 0x32, 0x30, 0x30, 0x31, 0x3a, 0x39, - 0x38, 0x30, 0x3a, 0x33, 0x32, 0x62, 0x32, 0x3a, 0x31, 0x3a, 0x32, 0x65, 0x34, 0x31, 0x3a, 0x33, - 0x38, 0x66, 0x66, 0x3a, 0x66, 0x65, 0x61, 0x37, 0x3a, 0x65, 0x61, 0x65, 0x62, 0x22, 0x2c, 0x22, - 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x69, 0x70, 0x76, 0x36, 0x22, 0x2c, 0x22, 0x73, 0x75, - 0x62, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x76, 0x69, 0x61, 0x22, 0x3a, - 0x22, 0x22, 0x2c, 0x22, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x22, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - }; - uint8_t raw_frag2[] = { - 0x60, 0x0f, 0x1a, 0xcf, 0x00, 0x1c, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01, - 0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x05, 0xa0, 0xdf, 0xf8, 0x11, 0xd7, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, - }; - Packet *pkt; - Packet *p1 = PacketGetFromAlloc(); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = PacketGetFromAlloc(); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars tv; - DecodeThreadVars dtv; - int result = 0; - PacketQueue pq; - - FlowInitConfig(FLOW_QUIET); - DefragInit(); - - memset(&pq, 0, sizeof(PacketQueue)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - PacketCopyData(p1, raw_frag1, sizeof(raw_frag1)); - PacketCopyData(p2, raw_frag2, sizeof(raw_frag2)); - - DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq); - - if (!(IPV6_EXTHDR_ISSET_FH(p1))) { - printf("ipv6 frag header not detected: "); - goto end; - } - - DecodeIPV6(&tv, &dtv, p2, GET_PKT_DATA(p2), GET_PKT_LEN(p2), &pq); - - if (!(IPV6_EXTHDR_ISSET_FH(p2))) { - printf("ipv6 frag header not detected: "); - goto end; - } - - if (pq.len != 1) { - printf("no reassembled packet: "); - goto end; - } - - result = 1; -end: - PACKET_RECYCLE(p1); - PACKET_RECYCLE(p2); - SCFree(p1); - SCFree(p2); - pkt = PacketDequeue(&pq); - while (pkt != NULL) { - PACKET_RECYCLE(pkt); - SCFree(pkt); - pkt = PacketDequeue(&pq); - } - DefragDestroy(); - FlowShutdown(); - return result; -} - -/** - * \test routing header decode - */ -static int DecodeIPV6RouteTest01 (void) -{ - - uint8_t raw_pkt1[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x2b, 0x40, - 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0xb2, 0xed, 0x00, 0x50, 0x1b, 0xc7, 0x6a, 0xdf, - 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x20, 0x00, - 0xfa, 0x87, 0x00, 0x00, - }; - Packet *p1 = PacketGetFromAlloc(); - if (unlikely(p1 == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int result = 0; - PacketQueue pq; - - FlowInitConfig(FLOW_QUIET); - - memset(&pq, 0, sizeof(PacketQueue)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1)); - - DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq); - - if (!(IPV6_EXTHDR_ISSET_RH(p1))) { - printf("ipv6 routing header not detected: "); - goto end; - } - - if (p1->ip6eh.ip6_exthdrs[0].len != 8) { - printf("ipv6 routing length incorrect: "); - goto end; - } - - result = 1; -end: - PACKET_RECYCLE(p1); - SCFree(p1); - FlowShutdown(); - return result; -} - -/** - * \test HOP header decode - */ -static int DecodeIPV6HopTest01 (void) -{ - uint8_t raw_pkt1[] = { - 0x60,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00, - 0x02,0x0f,0xfe,0xff,0xfe,0x98,0x3d,0x01,0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3a,0x00,0x05,0x02,0x00,0x00,0x00,0x00, - 0x82,0x00,0x1c,0x6f,0x27,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - }; - Packet *p1 = PacketGetFromAlloc(); - if (unlikely(p1 == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int result = 0; - PacketQueue pq; - - FlowInitConfig(FLOW_QUIET); - - memset(&pq, 0, sizeof(PacketQueue)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1)); - - DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq); - - if (!(IPV6_EXTHDR_ISSET_HH(p1))) { - printf("ipv6 routing header not detected: "); - goto end; - } - - if (p1->ip6eh.ip6_exthdrs[0].len != 8) { - printf("ipv6 routing length incorrect: "); - goto end; - } - - if (ENGINE_ISSET_EVENT(p1, IPV6_HOPOPTS_UNKNOWN_OPT)) { - printf("engine event IPV6_HOPOPTS_UNKNOWN_OPT set: "); - goto end; - } - - result = 1; -end: - PACKET_RECYCLE(p1); - SCFree(p1); - FlowShutdown(); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for IPV6 decoder - */ - -void DecodeIPV6RegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodeIPV6FragTest01", DecodeIPV6FragTest01, 1); - UtRegisterTest("DecodeIPV6RouteTest01", DecodeIPV6RouteTest01, 1); - UtRegisterTest("DecodeIPV6HopTest01", DecodeIPV6HopTest01, 1); -#endif /* UNITTESTS */ -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-ipv6.h b/framework/src/suricata/src/decode-ipv6.h deleted file mode 100644 index da58d9e2..00000000 --- a/framework/src/suricata/src/decode-ipv6.h +++ /dev/null @@ -1,334 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DECODE_IPV6_H__ -#define __DECODE_IPV6_H__ - -#define IPV6_HEADER_LEN 40 -#define IPV6_MAXPACKET 65535 /* maximum packet size */ -#define IPV6_MAX_OPT 40 - -typedef struct IPV6Hdr_ -{ - union { - struct ip6_un1_ { - uint32_t ip6_un1_flow; /* 20 bits of flow-ID */ - uint16_t ip6_un1_plen; /* payload length */ - uint8_t ip6_un1_nxt; /* next header */ - uint8_t ip6_un1_hlim; /* hop limit */ - } ip6_un1; - uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */ - } ip6_hdrun; - - union { - struct { - uint32_t ip6_src[4]; - uint32_t ip6_dst[4]; - } ip6_un2; - uint16_t ip6_addrs[16]; - } ip6_hdrun2; -} __attribute__((__packed__)) IPV6Hdr; - -#define s_ip6_src ip6_hdrun2.ip6_un2.ip6_src -#define s_ip6_dst ip6_hdrun2.ip6_un2.ip6_dst -#define s_ip6_addrs ip6_hdrun2.ip6_addrs - -#define s_ip6_vfc ip6_hdrun.ip6_un2_vfc -#define s_ip6_flow ip6_hdrun.ip6_un1.ip6_un1_flow -#define s_ip6_plen ip6_hdrun.ip6_un1.ip6_un1_plen -#define s_ip6_nxt ip6_hdrun.ip6_un1.ip6_un1_nxt -#define s_ip6_hlim ip6_hdrun.ip6_un1.ip6_un1_hlim - -#define IPV6_GET_RAW_VER(ip6h) (((ip6h)->s_ip6_vfc & 0xf0) >> 4) -#define IPV6_GET_RAW_CLASS(ip6h) ((ntohl((ip6h)->s_ip6_flow) & 0x0FF00000) >> 20) -#define IPV6_GET_RAW_FLOW(ip6h) (ntohl((ip6h)->s_ip6_flow) & 0x000FFFFF) -#define IPV6_GET_RAW_NH(ip6h) ((ip6h)->s_ip6_nxt) -#define IPV6_GET_RAW_PLEN(ip6h) (ntohs((ip6h)->s_ip6_plen)) -#define IPV6_GET_RAW_HLIM(ip6h) ((ip6h)->s_ip6_hlim) - -#define IPV6_SET_RAW_VER(ip6h, value) ((ip6h)->s_ip6_vfc = (((ip6h)->s_ip6_vfc & 0x0f) | (value << 4))) -#define IPV6_SET_RAW_NH(ip6h, value) ((ip6h)->s_ip6_nxt = (value)) - -#define IPV6_SET_L4PROTO(p,proto) (p)->ip6vars.l4proto = proto - - -/* ONLY call these functions after making sure that: - * 1. p->ip6h is set - * 2. p->ip6h is valid (len is correct) - */ -#define IPV6_GET_VER(p) \ - IPV6_GET_RAW_VER((p)->ip6h) -#define IPV6_GET_CLASS(p) \ - IPV6_GET_RAW_CLASS((p)->ip6h) -#define IPV6_GET_FLOW(p) \ - IPV6_GET_RAW_FLOW((p)->ip6h) -#define IPV6_GET_NH(p) \ - (IPV6_GET_RAW_NH((p)->ip6h)) -#define IPV6_GET_PLEN(p) \ - IPV6_GET_RAW_PLEN((p)->ip6h) -#define IPV6_GET_HLIM(p) \ - (IPV6_GET_RAW_HLIM((p)->ip6h)) -/* XXX */ -#define IPV6_GET_L4PROTO(p) \ - ((p)->ip6vars.l4proto) - -/** \brief get the highest proto/next header field we know */ -//#define IPV6_GET_UPPER_PROTO(p) (p)->ip6eh.ip6_exthdrs_cnt ? -// (p)->ip6eh.ip6_exthdrs[(p)->ip6eh.ip6_exthdrs_cnt - 1].next : IPV6_GET_NH((p)) - -/* helper structure with parsed ipv6 info */ -typedef struct IPV6Vars_ -{ - uint8_t ip_opts_len; - uint8_t l4proto; /* the proto after the extension headers - * store while decoding so we don't have - * to loop through the exthdrs all the time */ -} IPV6Vars; - -#define CLEAR_IPV6_PACKET(p) do { \ - (p)->ip6h = NULL; \ - (p)->ip6vars.ip_opts_len = 0; \ - (p)->ip6vars.l4proto = 0; \ - (p)->ip6eh.ip6fh = NULL; \ - (p)->ip6eh.fh_offset = 0; \ - (p)->ip6eh.ip6rh = NULL; \ - (p)->ip6eh.ip6eh = NULL; \ - (p)->ip6eh.ip6dh1 = NULL; \ - (p)->ip6eh.ip6dh2 = NULL; \ - (p)->ip6eh.ip6hh = NULL; \ - (p)->ip6eh.ip6_exthdrs_cnt = 0; \ -} while (0) - -/* Fragment header */ -typedef struct IPV6FragHdr_ -{ - uint8_t ip6fh_nxt; /* next header */ - uint8_t ip6fh_reserved; /* reserved field */ - uint16_t ip6fh_offlg; /* offset, reserved, and flag */ - uint32_t ip6fh_ident; /* identification */ -} __attribute__((__packed__)) IPV6FragHdr; - -#define IPV6_EXTHDR_GET_RAW_FH_NH(p) ((p)->ip6eh.ip6fh->ip6fh_nxt) -#define IPV6_EXTHDR_GET_RAW_FH_HDRLEN(p) sizeof(IPV6FragHdr) -#define IPV6_EXTHDR_GET_RAW_FH_OFFSET(p) (ntohs((p)->ip6eh.ip6fh->ip6fh_offlg) & 0xFFF8) -#define IPV6_EXTHDR_GET_RAW_FH_FLAG(p) (ntohs((p)->ip6eh.ip6fh->ip6fh_offlg) & 0x0001) -#define IPV6_EXTHDR_GET_RAW_FH_ID(p) (ntohl((p)->ip6eh.ip6fh->ip6fh_ident)) - -#define IPV6_EXTHDR_GET_FH_NH(p) IPV6_EXTHDR_GET_RAW_FH_NH((p)) -#define IPV6_EXTHDR_GET_FH_HDRLEN(p) IPV6_EXTHDR_GET_RAW_FH_HDRLEN((p)) -#define IPV6_EXTHDR_GET_FH_OFFSET(p) IPV6_EXTHDR_GET_RAW_FH_OFFSET((p)) -#define IPV6_EXTHDR_GET_FH_FLAG(p) IPV6_EXTHDR_GET_RAW_FH_FLAG((p)) -#define IPV6_EXTHDR_GET_FH_ID(p) IPV6_EXTHDR_GET_RAW_FH_ID((p)) - -/* rfc 1826 */ -typedef struct IPV6AuthHdr_ -{ - uint8_t ip6ah_nxt; /* next header */ - uint8_t ip6ah_len; /* header length in units of 8 bytes, not - including first 8 bytes. */ - uint16_t ip6ah_reserved; /* reserved for future use */ - uint32_t ip6ah_spi; /* SECURITY PARAMETERS INDEX (SPI) */ - uint32_t ip6ah_seq; /* sequence number */ -} __attribute__((__packed__)) IPV6AuthHdr; - -typedef struct IPV6EspHdr_ -{ - uint32_t ip6esph_spi; /* SECURITY PARAMETERS INDEX (SPI) */ - uint32_t ip6esph_seq; /* sequence number */ -} __attribute__((__packed__)) IPV6EspHdr; - -typedef struct IPV6RouteHdr_ -{ - uint8_t ip6rh_nxt; /* next header */ - uint8_t ip6rh_len; /* header length in units of 8 bytes, not - including first 8 bytes. */ - uint8_t ip6rh_type; /* routing type */ - uint8_t ip6rh_segsleft; /* segments left */ -#if 0 - struct in6_addr ip6rh0_addr[23]; /* type 0 addresses */ - uint8_t ip6rh0_num_addrs; /* number of actual addresses in the - array/packet. The array is guarranteed - to be filled up to this number. */ -#endif -} __attribute__((__packed__)) IPV6RouteHdr; - -#define IPV6_EXTHDR_GET_RAW_RH_NH(p) ((p)->ip6eh.ip6rh->ip6rh_nxt) -#define IPV6_EXTHDR_GET_RAW_RH_HDRLEN(p) ((p)->ip6eh.ip6rh->ip6rh_len) -#define IPV6_EXTHDR_GET_RAW_RH_TYPE(p) (ntohs((p)->ip6eh.ip6rh->ip6rh_type)) -/* XXX */ - -#define IPV6_EXTHDR_GET_RH_NH(p) IPV6_EXTHDR_GET_RAW_RH_NH((p)) -#define IPV6_EXTHDR_GET_RH_HDRLEN(p) IPV6_EXTHDR_GET_RAW_RH_HDRLEN((p)) -#define IPV6_EXTHDR_GET_RH_TYPE(p) IPV6_EXTHDR_GET_RAW_RH_TYPE((p)) -/* XXX */ - - -/* Hop-by-Hop header and Destination Options header use options that are - * defined here. */ - -#define IPV6OPT_PAD1 0x00 -#define IPV6OPT_PADN 0x01 -#define IPV6OPT_RA 0x05 -#define IPV6OPT_JUMBO 0xC2 -#define IPV6OPT_HAO 0xC9 - -/* Home Address Option */ -typedef struct IPV6OptHAO_ -{ - uint8_t ip6hao_type; /* Option type */ - uint8_t ip6hao_len; /* Option Data len (excludes type and len) */ - struct in6_addr ip6hao_hoa; /* Home address. */ -} IPV6OptHAO; - -/* Router Alert Option */ -typedef struct IPV6OptRA_ -{ - uint8_t ip6ra_type; /* Option type */ - uint8_t ip6ra_len; /* Option Data len (excludes type and len) */ - uint16_t ip6ra_value; /* Router Alert value */ -} IPV6OptRA; - -/* Jumbo Option */ -typedef struct IPV6OptJumbo_ -{ - uint8_t ip6j_type; /* Option type */ - uint8_t ip6j_len; /* Option Data len (excludes type and len) */ - uint32_t ip6j_payload_len; /* Jumbo Payload Length */ -} IPV6OptJumbo; - -typedef struct IPV6HopOptsHdr_ -{ - uint8_t ip6hh_nxt; /* next header */ - uint8_t ip6hh_len; /* header length in units of 8 bytes, not - including first 8 bytes. */ -} __attribute__((__packed__)) IPV6HopOptsHdr; - -#define IPV6_EXTHDR_GET_RAW_HH_NH(p) ((p)->ip6eh.ip6hh->ip6hh_nxt) -#define IPV6_EXTHDR_GET_RAW_HH_HDRLEN(p) ((p)->ip6eh.ip6hh->ip6hh_len) -/* XXX */ - -#define IPV6_EXTHDR_GET_HH_NH(p) IPV6_EXTHDR_GET_RAW_HH_NH((p)) -#define IPV6_EXTHDR_GET_HH_HDRLEN(p) IPV6_EXTHDR_GET_RAW_HH_HDRLEN((p)) -/* XXX */ - -typedef struct IPV6DstOptsHdr_ -{ - uint8_t ip6dh_nxt; /* next header */ - uint8_t ip6dh_len; /* header length in units of 8 bytes, not - including first 8 bytes. */ -} __attribute__((__packed__)) IPV6DstOptsHdr; - -#define IPV6_EXTHDR_GET_RAW_DH1_NH(p) ((p)->ip6eh.ip6dh1->ip6dh_nxt) -#define IPV6_EXTHDR_GET_RAW_DH1_HDRLEN(p) ((p)->ip6eh.ip6dh1->ip6dh_len) -/* XXX */ - -#define IPV6_EXTHDR_GET_DH1_NH(p) IPV6_EXTHDR_GET_RAW_DH1_NH((p)) -#define IPV6_EXTHDR_GET_DH1_HDRLEN(p) IPV6_EXTHDR_GET_RAW_DH1_HDRLEN((p)) -/* XXX */ - -#define IPV6_EXTHDR_GET_RAW_DH2_NH(p) ((p)->ip6eh.ip6dh2->ip6dh_nxt) -#define IPV6_EXTHDR_GET_RAW_DH2_HDRLEN(p) ((p)->ip6eh.ip6dh2->ip6dh_len) -/* XXX */ - -#define IPV6_EXTHDR_GET_DH2_NH(p) IPV6_EXTHDR_GET_RAW_DH2_NH((p)) -#define IPV6_EXTHDR_GET_DH2_HDRLEN(p) IPV6_EXTHDR_GET_RAW_DH2_HDRLEN((p)) -/* XXX */ - -typedef struct IPV6GenOptHdr_ -{ - uint8_t type; - uint8_t next; - uint8_t len; - uint8_t *data; -} IPV6GenOptHdr; - -typedef struct IPV6ExtHdrs_ -{ - const IPV6FragHdr *ip6fh; - /* In fh_offset we store the offset of this extension into the packet past - * the ipv6 header. We use it in defrag for creating a defragmented packet - * without the frag header */ - uint16_t fh_offset; - - const IPV6RouteHdr *ip6rh; - const IPV6AuthHdr *ip6ah; - const IPV6EspHdr *ip6eh; - const IPV6DstOptsHdr *ip6dh1; - const IPV6DstOptsHdr *ip6dh2; - const IPV6HopOptsHdr *ip6hh; - - /* Hop-By-Hop options */ - IPV6OptHAO ip6hh_opt_hao; - IPV6OptRA ip6hh_opt_ra; - IPV6OptJumbo ip6hh_opt_jumbo; - /* Dest Options 1 */ - IPV6OptHAO ip6dh1_opt_hao; - IPV6OptRA ip6dh1_opt_ra; - IPV6OptJumbo ip6dh1_opt_jumbo; - /* Dest Options 2 */ - IPV6OptHAO ip6dh2_opt_hao; - IPV6OptRA ip6dh2_opt_ra; - IPV6OptJumbo ip6dh2_opt_jumbo; - - IPV6GenOptHdr ip6_exthdrs[IPV6_MAX_OPT]; - uint8_t ip6_exthdrs_cnt; - -} IPV6ExtHdrs; - -#define IPV6_EXTHDR_FH(p) (p)->ip6eh.ip6fh -#define IPV6_EXTHDR_RH(p) (p)->ip6eh.ip6rh -#define IPV6_EXTHDR_AH(p) (p)->ip6eh.ip6ah -#define IPV6_EXTHDR_EH(p) (p)->ip6eh.ip6eh -#define IPV6_EXTHDR_DH1(p) (p)->ip6eh.ip6dh1 -#define IPV6_EXTHDR_DH2(p) (p)->ip6eh.ip6dh2 -#define IPV6_EXTHDR_HH(p) (p)->ip6eh.ip6hh - -#define IPV6_EXTHDR_HH_HAO(p) (p)->ip6eh.ip6hh_opt_hao -#define IPV6_EXTHDR_DH1_HAO(p) (p)->ip6eh.ip6dh1_opt_hao -#define IPV6_EXTHDR_DH2_HAO(p) (p)->ip6eh.ip6dh2_opt_hao -#define IPV6_EXTHDR_HH_RA(p) (p)->ip6eh.ip6hh_opt_ra -#define IPV6_EXTHDR_DH1_RA(p) (p)->ip6eh.ip6dh1_opt_ra -#define IPV6_EXTHDR_DH2_RA(p) (p)->ip6eh.ip6dh2_opt_ra -#define IPV6_EXTHDR_HH_JUMBO(p) (p)->ip6eh.ip6hh_opt_jumbo -#define IPV6_EXTHDR_DH1_JUMBO(p) (p)->ip6eh.ip6dh1_opt_jumbo -#define IPV6_EXTHDR_DH2_JUMBO(p) (p)->ip6eh.ip6dh2_opt_jumbo - -#define IPV6_EXTHDR_SET_FH(p,pkt) IPV6_EXTHDR_FH((p)) = (IPV6FragHdr *)pkt -#define IPV6_EXTHDR_ISSET_FH(p) (IPV6_EXTHDR_FH((p)) != NULL) -#define IPV6_EXTHDR_SET_RH(p,pkt) IPV6_EXTHDR_RH((p)) = (IPV6RouteHdr *)pkt -#define IPV6_EXTHDR_ISSET_RH(p) (IPV6_EXTHDR_RH((p)) != NULL) -#define IPV6_EXTHDR_SET_AH(p,pkt) IPV6_EXTHDR_AH((p)) = (IPV6AuthHdr *)pkt -#define IPV6_EXTHDR_ISSET_AH(p) (IPV6_EXTHDR_AH((p)) != NULL) -#define IPV6_EXTHDR_SET_EH(p,pkt) IPV6_EXTHDR_EH((p)) = (IPV6EspHdr *)pkt -#define IPV6_EXTHDR_ISSET_EH(p) (IPV6_EXTHDR_EH((p)) != NULL) -#define IPV6_EXTHDR_SET_DH1(p,pkt) IPV6_EXTHDR_DH1((p)) = (IPV6DstOptsHdr *)pkt -#define IPV6_EXTHDR_ISSET_DH1(p) (IPV6_EXTHDR_DH1((p)) != NULL) -#define IPV6_EXTHDR_SET_DH2(p,pkt) IPV6_EXTHDR_DH2((p)) = (IPV6DstOptsHdr *)pkt -#define IPV6_EXTHDR_ISSET_DH2(p) (IPV6_EXTHDR_DH2((p)) != NULL) -#define IPV6_EXTHDR_SET_HH(p,pkt) IPV6_EXTHDR_HH((p)) = (IPV6HopOptsHdr *)pkt -#define IPV6_EXTHDR_ISSET_HH(p) (IPV6_EXTHDR_HH((p)) != NULL) - -void DecodeIPV6RegisterTests(void); - -#endif /* __DECODE_IPV6_H__ */ - diff --git a/framework/src/suricata/src/decode-mpls.c b/framework/src/suricata/src/decode-mpls.c deleted file mode 100644 index 1569ebfb..00000000 --- a/framework/src/suricata/src/decode-mpls.c +++ /dev/null @@ -1,325 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Jason Ish - * - * MPLS decoder. - */ - -#include "suricata-common.h" -#include "decode.h" -#include "util-unittest.h" - -#define MPLS_HEADER_LEN 4 -#define MPLS_PW_LEN 4 -#define MPLS_MAX_RESERVED_LABEL 15 - -#define MPLS_LABEL_IPV4 0 -#define MPLS_LABEL_ROUTER_ALERT 1 -#define MPLS_LABEL_IPV6 2 -#define MPLS_LABEL_NULL 3 - -#define MPLS_LABEL(shim) ntohl(shim) >> 12 -#define MPLS_BOTTOM(shim) ((ntohl(shim) >> 8) & 0x1) - -/* Inner protocol guessing values. */ -#define MPLS_PROTO_ETHERNET_PW 0 -#define MPLS_PROTO_IPV4 4 -#define MPLS_PROTO_IPV6 6 - -int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, - uint16_t len, PacketQueue *pq) -{ - uint32_t shim; - int label; - int event = 0; - - StatsIncr(tv, dtv->counter_mpls); - - do { - if (len < MPLS_HEADER_LEN) { - ENGINE_SET_INVALID_EVENT(p, MPLS_HEADER_TOO_SMALL); - return TM_ECODE_FAILED; - } - shim = *(uint32_t *)pkt; - pkt += MPLS_HEADER_LEN; - len -= MPLS_HEADER_LEN; - } while (MPLS_BOTTOM(shim) == 0); - - label = MPLS_LABEL(shim); - if (label == MPLS_LABEL_IPV4) { - return DecodeIPV4(tv, dtv, p, pkt, len, pq); - } - else if (label == MPLS_LABEL_ROUTER_ALERT) { - /* Not valid at the bottom of the stack. */ - event = MPLS_BAD_LABEL_ROUTER_ALERT; - } - else if (label == MPLS_LABEL_IPV6) { - return DecodeIPV6(tv, dtv, p, pkt, len, pq); - } - else if (label == MPLS_LABEL_NULL) { - /* Shouldn't appear on the wire. */ - event = MPLS_BAD_LABEL_IMPLICIT_NULL; - } - else if (label < MPLS_MAX_RESERVED_LABEL) { - event = MPLS_BAD_LABEL_RESERVED; - } - - if (event) { - goto end; - } - - /* Best guess at inner packet. */ - switch (pkt[0] >> 4) { - case MPLS_PROTO_IPV4: - DecodeIPV4(tv, dtv, p, pkt, len, pq); - break; - case MPLS_PROTO_IPV6: - DecodeIPV6(tv, dtv, p, pkt, len, pq); - break; - case MPLS_PROTO_ETHERNET_PW: - DecodeEthernet(tv, dtv, p, pkt + MPLS_PW_LEN, len - MPLS_PW_LEN, - pq); - break; - default: - ENGINE_SET_INVALID_EVENT(p, MPLS_UNKNOWN_PAYLOAD_TYPE); - return TM_ECODE_OK; - } - -end: - if (event) { - ENGINE_SET_EVENT(p, event); - } - return TM_ECODE_OK; -} - -#ifdef UNITTESTS - -static int DecodeMPLSTestHeaderTooSmall(void) -{ - int ret = 1; - - /* A packet that is too small to have a complete MPLS header. */ - uint8_t pkt[] = { - 0x00, 0x00, 0x11 - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) { - return 0; - } - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - - DecodeMPLS(&tv, &dtv, p, pkt, sizeof(pkt), NULL); - - if (!ENGINE_ISSET_EVENT(p, MPLS_HEADER_TOO_SMALL)) { - ret = 0; - } - - SCFree(p); - return ret; -} - -static int DecodeMPLSTestBadLabelRouterAlert(void) -{ - int ret = 1; - uint8_t pkt[] = { - 0x00, 0x00, 0x11, 0xff, 0x45, 0x00, 0x00, 0x64, - 0x00, 0x0a, 0x00, 0x00, 0xff, 0x01, 0xa5, 0x6a, - 0x0a, 0x01, 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, - 0x08, 0x00, 0x3a, 0x77, 0x0a, 0x39, 0x06, 0x2b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x50, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) { - return 0; - } - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - - DecodeMPLS(&tv, &dtv, p, pkt, sizeof(pkt), NULL); - - if (!ENGINE_ISSET_EVENT(p, MPLS_BAD_LABEL_ROUTER_ALERT)) { - ret = 0; - } - - SCFree(p); - return ret; -} - -static int DecodeMPLSTestBadLabelImplicitNull(void) -{ - int ret = 1; - uint8_t pkt[] = { - 0x00, 0x00, 0x31, 0xff, 0x45, 0x00, 0x00, 0x64, - 0x00, 0x0a, 0x00, 0x00, 0xff, 0x01, 0xa5, 0x6a, - 0x0a, 0x01, 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, - 0x08, 0x00, 0x3a, 0x77, 0x0a, 0x39, 0x06, 0x2b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x50, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) { - return 0; - } - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - - DecodeMPLS(&tv, &dtv, p, pkt, sizeof(pkt), NULL); - - if (!ENGINE_ISSET_EVENT(p, MPLS_BAD_LABEL_IMPLICIT_NULL)) { - ret = 0; - } - - SCFree(p); - return ret; -} - -static int DecodeMPLSTestBadLabelReserved(void) -{ - int ret = 1; - uint8_t pkt[] = { - 0x00, 0x00, 0x51, 0xff, 0x45, 0x00, 0x00, 0x64, - 0x00, 0x0a, 0x00, 0x00, 0xff, 0x01, 0xa5, 0x6a, - 0x0a, 0x01, 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, - 0x08, 0x00, 0x3a, 0x77, 0x0a, 0x39, 0x06, 0x2b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x50, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) { - return 0; - } - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - - DecodeMPLS(&tv, &dtv, p, pkt, sizeof(pkt), NULL); - - if (!ENGINE_ISSET_EVENT(p, MPLS_BAD_LABEL_RESERVED)) { - ret = 0; - } - - SCFree(p); - return ret; -} - -static int DecodeMPLSTestUnknownPayloadType(void) -{ - int ret = 1; - - /* Valid label: 21. - * Unknown payload type: 1. - */ - uint8_t pkt[] = { - 0x00, 0x01, 0x51, 0xff, 0x15, 0x00, 0x00, 0x64, - 0x00, 0x0a, 0x00, 0x00, 0xff, 0x01, 0xa5, 0x6a, - 0x0a, 0x01, 0x02, 0x01, 0x0a, 0x22, 0x00, 0x01, - 0x08, 0x00, 0x3a, 0x77, 0x0a, 0x39, 0x06, 0x2b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x33, 0x50, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, - 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) { - return 0; - } - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - - DecodeMPLS(&tv, &dtv, p, pkt, sizeof(pkt), NULL); - - if (!ENGINE_ISSET_EVENT(p, MPLS_UNKNOWN_PAYLOAD_TYPE)) { - ret = 0; - } - - SCFree(p); - return ret; -} - -#endif /* UNITTESTS */ - -void DecodeMPLSRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodeMPLSTestHeaderTooSmall", - DecodeMPLSTestHeaderTooSmall, 1); - UtRegisterTest("DecodeMPLSTestBadLabelRouterAlert", - DecodeMPLSTestBadLabelRouterAlert, 1); - UtRegisterTest("DecodeMPLSTestBadLabelImplicitNull", - DecodeMPLSTestBadLabelImplicitNull, 1); - UtRegisterTest("DecodeMPLSTestBadLabelReserved", - DecodeMPLSTestBadLabelReserved, 1); - UtRegisterTest("DecodeMPLSTestUnknownPayloadType", - DecodeMPLSTestUnknownPayloadType, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/decode-mpls.h b/framework/src/suricata/src/decode-mpls.h deleted file mode 100644 index c701d3df..00000000 --- a/framework/src/suricata/src/decode-mpls.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Jason Ish - * - * MPLS decoder. - */ - -#ifndef __DECODE_MPLS_H__ -#define __DECODE_MPLS_H__ - -#define ETHERNET_TYPE_MPLS_UNICAST 0x8847 -#define ETHERNET_TYPE_MPLS_MULTICAST 0x8848 - -void DecodeMPLSRegisterTests(void); - -#endif /* !__DECODE_MPLS_H__ */ diff --git a/framework/src/suricata/src/decode-null.c b/framework/src/suricata/src/decode-null.c deleted file mode 100644 index b3bcb066..00000000 --- a/framework/src/suricata/src/decode-null.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decode linkype null: - * http://www.tcpdump.org/linktypes.html - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-raw.h" -#include "decode-events.h" - -#include "util-unittest.h" -#include "util-debug.h" - -#include "pkt-var.h" -#include "util-profiling.h" -#include "host.h" - -#define HDR_SIZE 4 - -int DecodeNull(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_null); - - if (unlikely(len < HDR_SIZE)) { - ENGINE_SET_INVALID_EVENT(p, LTNULL_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - uint32_t type = *((uint32_t *)pkt); - switch(type) { - case AF_INET: - SCLogDebug("IPV4 Packet"); - DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p)+HDR_SIZE, GET_PKT_LEN(p)-HDR_SIZE, pq); - break; - case AF_INET6: - SCLogDebug("IPV6 Packet"); - DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p)+HDR_SIZE, GET_PKT_LEN(p)-HDR_SIZE, pq); - break; - default: - SCLogDebug("Unknown Null packet type version %" PRIu32 "", type); - ENGINE_SET_EVENT(p, LTNULL_UNSUPPORTED_TYPE); - break; - } - return TM_ECODE_OK; -} - -#ifdef UNITTESTS - -#endif /* UNITTESTS */ - -/** - * \brief Registers Null unit tests - */ -void DecodeNullRegisterTests(void) -{ -#ifdef UNITTESTS -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-null.h b/framework/src/suricata/src/decode-null.h deleted file mode 100644 index 22d988c7..00000000 --- a/framework/src/suricata/src/decode-null.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DECODE_NULL_H__ -#define __DECODE_NULL_H__ -void DecodeNullRegisterTests(void); -#endif /* __DECODE_NULL_H__ */ diff --git a/framework/src/suricata/src/decode-ppp.c b/framework/src/suricata/src/decode-ppp.c deleted file mode 100644 index f4ea670c..00000000 --- a/framework/src/suricata/src/decode-ppp.c +++ /dev/null @@ -1,312 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Breno Silva Pinto - * - * Decode PPP - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-ppp.h" -#include "decode-events.h" - -#include "flow.h" - -#include "util-unittest.h" -#include "util-debug.h" - -int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_ppp); - - if (unlikely(len < PPP_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, PPP_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - p->ppph = (PPPHdr *)pkt; - if (unlikely(p->ppph == NULL)) - return TM_ECODE_FAILED; - - SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRId32 "", - p, pkt, ntohs(p->ppph->protocol), len); - - switch (ntohs(p->ppph->protocol)) - { - case PPP_VJ_UCOMP: - if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) { - ENGINE_SET_INVALID_EVENT(p,PPPVJU_PKT_TOO_SMALL); - p->ppph = NULL; - return TM_ECODE_FAILED; - } - - if (likely(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPP_HEADER_LEN)) == 4)) { - return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq); - } else - return TM_ECODE_FAILED; - break; - - case PPP_IP: - if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) { - ENGINE_SET_INVALID_EVENT(p,PPPIPV4_PKT_TOO_SMALL); - p->ppph = NULL; - return TM_ECODE_FAILED; - } - - return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq); - - /* PPP IPv6 was not tested */ - case PPP_IPV6: - if (unlikely(len < (PPP_HEADER_LEN + IPV6_HEADER_LEN))) { - ENGINE_SET_INVALID_EVENT(p,PPPIPV6_PKT_TOO_SMALL); - p->ppph = NULL; - return TM_ECODE_FAILED; - } - - return DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq); - - case PPP_VJ_COMP: - case PPP_IPX: - case PPP_OSI: - case PPP_NS: - case PPP_DECNET: - case PPP_APPLE: - case PPP_BRPDU: - case PPP_STII: - case PPP_VINES: - case PPP_HELLO: - case PPP_LUXCOM: - case PPP_SNS: - case PPP_MPLS_UCAST: - case PPP_MPLS_MCAST: - case PPP_IPCP: - case PPP_OSICP: - case PPP_NSCP: - case PPP_DECNETCP: - case PPP_APPLECP: - case PPP_IPXCP: - case PPP_STIICP: - case PPP_VINESCP: - case PPP_IPV6CP: - case PPP_MPLSCP: - case PPP_LCP: - case PPP_PAP: - case PPP_LQM: - case PPP_CHAP: - ENGINE_SET_EVENT(p,PPP_UNSUP_PROTO); - return TM_ECODE_OK; - - default: - SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol)); - ENGINE_SET_INVALID_EVENT(p, PPP_WRONG_TYPE); - return TM_ECODE_OK; - } - -} - -/* TESTS BELOW */ -#ifdef UNITTESTS - -/* DecodePPPtest01 - * Decode malformed ip layer PPP packet - * Expected test value: 1 - */ -static int DecodePPPtest01 (void) -{ - uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL); - - /* Function my returns here with expected value */ - - if(ENGINE_ISSET_EVENT(p,PPPIPV4_PKT_TOO_SMALL)) { - SCFree(p); - return 1; - } - - SCFree(p); - return 0; -} - -/* DecodePPPtest02 - * Decode malformed ppp layer packet - * Expected test value: 1 - */ -static int DecodePPPtest02 (void) -{ - uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0xff, 0x45, 0xc0, 0x00, 0x2c, 0x4d, - 0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01, - 0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00, - 0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL); - - /* Function must returns here */ - - if(ENGINE_ISSET_EVENT(p,PPP_WRONG_TYPE)) { - SCFree(p); - return 1; - } - - SCFree(p); - return 0; -} - -/** DecodePPPtest03 - * \brief Decode good PPP packet, additionally the IPv4 packet inside is - * 4 bytes short. - * \retval 0 Test failed - * \retval 1 Test succeeded - */ -static int DecodePPPtest03 (void) -{ - uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c, 0x4d, - 0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01, - 0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00, - 0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL); - - FlowShutdown(); - - if(p->ppph == NULL) { - SCFree(p); - return 0; - } - - if(ENGINE_ISSET_EVENT(p,PPP_PKT_TOO_SMALL)) { - SCFree(p); - return 0; - } - - if(ENGINE_ISSET_EVENT(p,PPPIPV4_PKT_TOO_SMALL)) { - SCFree(p); - return 0; - } - - if(ENGINE_ISSET_EVENT(p,PPP_WRONG_TYPE)) { - SCFree(p); - return 0; - } - - if (!(ENGINE_ISSET_EVENT(p,IPV4_TRUNC_PKT))) { - SCFree(p); - return 0; - } - /* Function must return here */ - - SCFree(p); - return 1; -} - - -/* DecodePPPtest04 - * Check if ppp header is null - * Expected test value: 1 - */ - -static int DecodePPPtest04 (void) -{ - uint8_t raw_ppp[] = { 0xff, 0x03, 0x00, 0x21, 0x45, 0xc0, 0x00, 0x2c, 0x4d, - 0xed, 0x00, 0x00, 0xff, 0x06, 0xd5, 0x17, 0xbf, 0x01, - 0x0d, 0x01, 0xbf, 0x01, 0x0d, 0x03, 0xea, 0x37, 0x00, - 0x17, 0x6d, 0x0b, 0xba, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x02, 0x10, 0x20, 0xdd, 0xe1, 0x00, 0x00 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - DecodePPP(&tv, &dtv, p, raw_ppp, sizeof(raw_ppp), NULL); - - FlowShutdown(); - - if(p->ppph == NULL) { - SCFree(p); - return 0; - } - - if (!(ENGINE_ISSET_EVENT(p,IPV4_TRUNC_PKT))) { - SCFree(p); - return 0; - } - - /* Function must returns here */ - - SCFree(p); - return 1; -} -#endif /* UNITTESTS */ - -void DecodePPPRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodePPPtest01", DecodePPPtest01, 1); - UtRegisterTest("DecodePPPtest02", DecodePPPtest02, 1); - UtRegisterTest("DecodePPPtest03", DecodePPPtest03, 1); - UtRegisterTest("DecodePPPtest04", DecodePPPtest04, 1); -#endif /* UNITTESTS */ -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-ppp.h b/framework/src/suricata/src/decode-ppp.h deleted file mode 100644 index 00e61de9..00000000 --- a/framework/src/suricata/src/decode-ppp.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva Pinto - */ - -#ifndef __DECODE_PPP_H__ -#define __DECODE_PPP_H__ - -/** Point to Point Protocol RFC1331 - Supported tyes */ -#define PPP_IP 0x0021 /* Internet Protocol */ -#define PPP_IPV6 0x0057 /* Internet Protocol version 6 */ -#define PPP_VJ_UCOMP 0x002f /* VJ uncompressed TCP/IP */ - -/** Unsupported PPP types (libpcap source reference) */ -#define PPP_IPX 0x002b /* Novell IPX Protocol */ -#define PPP_VJ_COMP 0x002d /* VJ compressed TCP/IP */ -#define PPP_IPX 0x002b /* Novell IPX Protocol */ -#define PPP_OSI 0x0023 /* OSI Network Layer */ -#define PPP_NS 0x0025 /* Xerox NS IDP */ -#define PPP_DECNET 0x0027 /* DECnet Phase IV */ -#define PPP_APPLE 0x0029 /* Appletalk */ -#define PPP_BRPDU 0x0031 /* Bridging PDU */ -#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */ -#define PPP_VINES 0x0035 /* Banyan Vines */ -#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */ -#define PPP_LUXCOM 0x0231 /* Luxcom */ -#define PPP_SNS 0x0233 /* Sigma Network Systems */ -#define PPP_MPLS_UCAST 0x0281 /* rfc 3032 */ -#define PPP_MPLS_MCAST 0x0283 /* rfc 3022 */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */ -#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */ -#define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */ -#define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */ -#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */ -#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */ -#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */ -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ -#define PPP_MPLSCP 0x8281 /* rfc 3022 */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_LQM 0xc025 /* Link Quality Monitoring */ -#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */ - -/** PPP Packet header */ -typedef struct PPPHdr_ { - uint8_t address; - uint8_t control; - uint16_t protocol; -} __attribute__((__packed__)) PPPHdr; - -/** PPP Packet header length */ -#define PPP_HEADER_LEN 4 - -void DecodePPPRegisterTests(void); - -#endif /* __DECODE_PPP_H__ */ - diff --git a/framework/src/suricata/src/decode-pppoe.c b/framework/src/suricata/src/decode-pppoe.c deleted file mode 100644 index b6f5031f..00000000 --- a/framework/src/suricata/src/decode-pppoe.c +++ /dev/null @@ -1,460 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author James Riden - * - * PPPOE Decoder - */ - -#include "suricata-common.h" - -#include "packet-queue.h" - -#include "decode.h" -#include "decode-ppp.h" -#include "decode-pppoe.h" -#include "decode-events.h" - -#include "flow.h" - -#include "util-unittest.h" -#include "util-debug.h" - -/** - * \brief Main decoding function for PPPOE Discovery packets - */ -int DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_pppoe); - - if (len < PPPOE_DISCOVERY_HEADER_MIN_LEN) { - ENGINE_SET_INVALID_EVENT(p, PPPOE_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - p->pppoedh = (PPPOEDiscoveryHdr *)pkt; - if (p->pppoedh == NULL) - return TM_ECODE_FAILED; - - /* parse the PPPOE code */ - switch (p->pppoedh->pppoe_code) - { - case PPPOE_CODE_PADI: - break; - case PPPOE_CODE_PADO: - break; - case PPPOE_CODE_PADR: - break; - case PPPOE_CODE_PADS: - break; - case PPPOE_CODE_PADT: - break; - default: - SCLogDebug("unknown PPPOE code: 0x%0"PRIX8"", p->pppoedh->pppoe_code); - ENGINE_SET_INVALID_EVENT(p, PPPOE_WRONG_CODE); - return TM_ECODE_OK; - } - - /* parse any tags we have in the packet */ - - uint16_t tag_length = 0; - PPPOEDiscoveryTag* pppoedt = (PPPOEDiscoveryTag*) (p->pppoedh + PPPOE_DISCOVERY_HEADER_MIN_LEN); - - uint16_t pppoe_length = ntohs(p->pppoedh->pppoe_length); - uint16_t packet_length = len - PPPOE_DISCOVERY_HEADER_MIN_LEN ; - - SCLogDebug("pppoe_length %"PRIu16", packet_length %"PRIu16"", - pppoe_length, packet_length); - - if (pppoe_length > packet_length) { - SCLogDebug("malformed PPPOE tags"); - ENGINE_SET_INVALID_EVENT(p, PPPOE_MALFORMED_TAGS); - return TM_ECODE_OK; - } - - while (pppoedt < (PPPOEDiscoveryTag*) (pkt + (len - sizeof(PPPOEDiscoveryTag))) && pppoe_length >=4 && packet_length >=4) - { -#ifdef DEBUG - uint16_t tag_type = ntohs(pppoedt->pppoe_tag_type); -#endif - tag_length = ntohs(pppoedt->pppoe_tag_length); - - SCLogDebug ("PPPoE Tag type %x, length %u", tag_type, tag_length); - - if (pppoe_length >= (4 + tag_length)) { - pppoe_length -= (4 + tag_length); - } else { - pppoe_length = 0; // don't want an underflow - } - - if (packet_length >= 4 + tag_length) { - packet_length -= (4 + tag_length); - } else { - packet_length = 0; // don't want an underflow - } - - pppoedt = pppoedt + (4 + tag_length); - } - - return TM_ECODE_OK; -} - -/** - * \brief Main decoding function for PPPOE Session packets - */ -int DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_pppoe); - - if (len < PPPOE_SESSION_HEADER_LEN) { - ENGINE_SET_INVALID_EVENT(p, PPPOE_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - p->pppoesh = (PPPOESessionHdr *)pkt; - if (p->pppoesh == NULL) - return TM_ECODE_FAILED; - - SCLogDebug("PPPOE VERSION %" PRIu32 " TYPE %" PRIu32 " CODE %" PRIu32 " SESSIONID %" PRIu32 " LENGTH %" PRIu32 "", - PPPOE_SESSION_GET_VERSION(p->pppoesh), PPPOE_SESSION_GET_TYPE(p->pppoesh), p->pppoesh->pppoe_code, ntohs(p->pppoesh->session_id), ntohs(p->pppoesh->pppoe_length)); - - /* can't use DecodePPP() here because we only get a single 2-byte word to indicate protocol instead of the full PPP header */ - - if (ntohs(p->pppoesh->pppoe_length) > 0) { - /* decode contained PPP packet */ - - switch (ntohs(p->pppoesh->protocol)) - { - case PPP_VJ_COMP: - case PPP_IPX: - case PPP_OSI: - case PPP_NS: - case PPP_DECNET: - case PPP_APPLE: - case PPP_BRPDU: - case PPP_STII: - case PPP_VINES: - case PPP_HELLO: - case PPP_LUXCOM: - case PPP_SNS: - case PPP_MPLS_UCAST: - case PPP_MPLS_MCAST: - case PPP_IPCP: - case PPP_OSICP: - case PPP_NSCP: - case PPP_DECNETCP: - case PPP_APPLECP: - case PPP_IPXCP: - case PPP_STIICP: - case PPP_VINESCP: - case PPP_IPV6CP: - case PPP_MPLSCP: - case PPP_LCP: - case PPP_PAP: - case PPP_LQM: - case PPP_CHAP: - ENGINE_SET_EVENT(p,PPP_UNSUP_PROTO); - break; - - case PPP_VJ_UCOMP: - - if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, PPPVJU_PKT_TOO_SMALL); - return TM_ECODE_OK; - } - - if(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPPOE_SESSION_HEADER_LEN)) == 4) { - DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq ); - } - break; - - case PPP_IP: - if(len < (PPPOE_SESSION_HEADER_LEN + IPV4_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, PPPIPV4_PKT_TOO_SMALL); - return TM_ECODE_OK; - } - - DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq ); - break; - - /* PPP IPv6 was not tested */ - case PPP_IPV6: - if(len < (PPPOE_SESSION_HEADER_LEN + IPV6_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, PPPIPV6_PKT_TOO_SMALL); - return TM_ECODE_OK; - } - - DecodeIPV6(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq ); - break; - - default: - SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol)); - ENGINE_SET_INVALID_EVENT(p, PPP_WRONG_TYPE); - return TM_ECODE_OK; - } - } - return TM_ECODE_OK; -} - -#ifdef UNITTESTS -/** DecodePPPOEtest01 - * \brief Decode malformed PPPOE packet (too short) - * \retval 1 Expected test value - */ -static int DecodePPPOEtest01 (void) -{ - - uint8_t raw_pppoe[] = { 0x11, 0x00, 0x00, 0x00, 0x00 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodePPPOESession(&tv, &dtv, p, raw_pppoe, sizeof(raw_pppoe), NULL); - - if (ENGINE_ISSET_EVENT(p,PPPOE_PKT_TOO_SMALL)) { - SCFree(p); - return 1; - } - - SCFree(p); - return 0; -} - -/** DecodePPPOEtest02 - * \brief Valid PPPOE packet - check the invalid ICMP type encapsulated is flagged - * \retval 0 Expected test value - */ -static int DecodePPPOEtest02 (void) -{ - - uint8_t raw_pppoe[] = { - 0x11, 0x00, 0x00, 0x01, 0x00, 0x40, 0x00, 0x21, - 0x45, 0x00, 0x00, 0x3c, 0x05, 0x5c, 0x00, 0x00, - 0x20, 0x01, 0xff, 0x30, 0xc0, 0xa8, 0x0a, 0x7f, - 0xc0, 0xa8, 0x0a, 0x65, 0xab, 0xcd, 0x16, 0x5e, - 0x02, 0x00, 0x37, 0x00, 0x41, 0x42, 0x43, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, - 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x41, 0x42, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49 }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - int ret = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - DecodePPPOESession(&tv, &dtv, p, raw_pppoe, sizeof(raw_pppoe), NULL); - - if(ENGINE_ISSET_EVENT(p,PPPOE_PKT_TOO_SMALL)) { - goto end; - } - - // and we insist that the invalid ICMP encapsulated (type 0xab, code 0xcd) is flagged - - if(! ENGINE_ISSET_EVENT(p,ICMPV4_UNKNOWN_TYPE)) { - goto end; - } - - ret = 1; -end: - FlowShutdown(); - SCFree(p); - return ret; -} - - -/** DecodePPPOEtest03 - * \brief Valid example PADO packet PPPOE packet taken from RFC2516 - * \retval 0 Expected test value - */ -static int DecodePPPOEtest03 (void) -{ - - /* example PADO packet taken from RFC2516 */ - uint8_t raw_pppoe[] = { - 0x11, 0x07, 0x00, 0x00, 0x00, 0x20, 0x01, 0x01, - 0x00, 0x00, 0x01, 0x02, 0x00, 0x18, 0x47, 0x6f, - 0x20, 0x52, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, - 0x20, 0x2d, 0x20, 0x65, 0x73, 0x68, 0x73, 0x68, - 0x65, 0x73, 0x68, 0x6f, 0x6f, 0x74 - }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodePPPOEDiscovery(&tv, &dtv, p, raw_pppoe, sizeof(raw_pppoe), NULL); - if (p->pppoedh == NULL) { - SCFree(p); - return 0; - } - - SCFree(p); - return 1; -} - -/** DecodePPPOEtest04 - * \brief Valid example PPPOE packet taken from RFC2516 - but with wrong PPPOE code - * \retval 1 Expected test value - */ -static int DecodePPPOEtest04 (void) -{ - - /* example PADI packet taken from RFC2516, but with wrong code */ - uint8_t raw_pppoe[] = { - 0x11, 0xbb, 0x00, 0x00, 0x00, 0x04, 0x01, 0x01, - 0x00, 0x00 - }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodePPPOEDiscovery(&tv, &dtv, p, raw_pppoe, sizeof(raw_pppoe), NULL); - - if(ENGINE_ISSET_EVENT(p,PPPOE_WRONG_CODE)) { - SCFree(p); - return 1; - } - - SCFree(p); - return 0; -} - -/** DecodePPPOEtest05 - * \brief Valid exaple PADO PPPOE packet taken from RFC2516, but too short for given length - * \retval 0 Expected test value - */ -static int DecodePPPOEtest05 (void) -{ - - /* example PADI packet taken from RFC2516 */ - uint8_t raw_pppoe[] = { - 0x11, 0x07, 0x00, 0x00, 0x00, 0x20, 0x01, 0x01, - 0x00, 0x00, 0x01, 0x02, 0x00, 0x18, 0x47, 0x6f, - 0x20, 0x52, 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, - 0x20, 0x2d, 0x20, 0x65, 0x73, 0x68, 0x73, 0x68 - }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodePPPOEDiscovery(&tv, &dtv, p, raw_pppoe, sizeof(raw_pppoe), NULL); - - if(ENGINE_ISSET_EVENT(p,PPPOE_MALFORMED_TAGS)) { - SCFree(p); - return 1; - } - - SCFree(p); - return 0; -} - -/** DecodePPPOEtest06 - * \brief Check that the macros work as expected. Type and version are - * fields of 4 bits length. So they are sharing the same var and the macros - * should extract the first 4 bits for version and the second 4 bits for type - * \retval 1 Expected test value - */ -static int DecodePPPOEtest06 (void) -{ - - PPPOESessionHdr pppoesh; - PPPOEDiscoveryHdr pppoedh; - pppoesh.pppoe_version_type = 0xAB; - pppoedh.pppoe_version_type = 0xCD; - - if (PPPOE_SESSION_GET_VERSION(&pppoesh) != 0x0A) { - printf("Error, PPPOE macro pppoe_session_get_version failed: "); - return 0; - } - if (PPPOE_SESSION_GET_TYPE(&pppoesh) != 0x0B) { - printf("Error, PPPOE macro pppoe_session_get_type failed: "); - return 0; - } - if (PPPOE_DISCOVERY_GET_VERSION(&pppoedh) != 0x0C) { - printf("Error, PPPOE macro pppoe_discovery_get_version failed: "); - return 0; - } - if (PPPOE_DISCOVERY_GET_TYPE(&pppoedh) != 0x0D) { - printf("Error, PPPOE macro pppoe_discovery_get_type failed: "); - return 0; - } - - return 1; -} -#endif /* UNITTESTS */ - - - -/** - * \brief Registers PPPOE unit tests - * \todo More PPPOE tests - */ -void DecodePPPOERegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodePPPOEtest01", DecodePPPOEtest01, 1); - UtRegisterTest("DecodePPPOEtest02", DecodePPPOEtest02, 1); - UtRegisterTest("DecodePPPOEtest03", DecodePPPOEtest03, 1); - UtRegisterTest("DecodePPPOEtest04", DecodePPPOEtest04, 1); - UtRegisterTest("DecodePPPOEtest05", DecodePPPOEtest05, 1); - UtRegisterTest("DecodePPPOEtest06", DecodePPPOEtest06, 1); -#endif /* UNITTESTS */ -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-pppoe.h b/framework/src/suricata/src/decode-pppoe.h deleted file mode 100644 index 6aecf741..00000000 --- a/framework/src/suricata/src/decode-pppoe.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author James Riden - */ - -#ifndef __DECODE_PPPOE_H__ -#define __DECODE_PPPOE_H__ - -#include "decode.h" -#include "threadvars.h" - -#define PPPOE_SESSION_HEADER_LEN 8 -#define PPPOE_DISCOVERY_HEADER_MIN_LEN 6 -#define PPPOE_SESSION_GET_VERSION(hdr) ((hdr)->pppoe_version_type & 0xF0) >> 4 -#define PPPOE_SESSION_GET_TYPE(hdr) ((hdr)->pppoe_version_type & 0x0F) -#define PPPOE_DISCOVERY_GET_VERSION(hdr) ((hdr)->pppoe_version_type & 0xF0) >> 4 -#define PPPOE_DISCOVERY_GET_TYPE(hdr) ((hdr)->pppoe_version_type & 0x0F) - -typedef struct PPPOESessionHdr_ -{ - uint8_t pppoe_version_type; - uint8_t pppoe_code; - uint16_t session_id; - uint16_t pppoe_length; - uint16_t protocol; -} PPPOESessionHdr; - -typedef struct PPPOEDiscoveryTag_ -{ - uint16_t pppoe_tag_type; - uint16_t pppoe_tag_length; -} __attribute__((__packed__)) PPPOEDiscoveryTag; - -typedef struct PPPOEDiscoveryHdr_ -{ - uint8_t pppoe_version_type; - uint8_t pppoe_code; - uint16_t discovery_id; - uint16_t pppoe_length; -} __attribute__((__packed__)) PPPOEDiscoveryHdr; - -/* see RFC 2516 - discovery codes */ -#define PPPOE_CODE_PADI 0x09 -#define PPPOE_CODE_PADO 0x07 -#define PPPOE_CODE_PADR 0x19 -#define PPPOE_CODE_PADS 0x65 -#define PPPOE_CODE_PADT 0xa7 - -/* see RFC 2516 Appendix A */ -#define PPPOE_TAG_END_OF_LIST 0x0000 /* End-Of-List */ -#define PPPOE_TAG_SERVICE_NAME 0x0101 /* Service-Name */ -#define PPPOE_TAG_AC_NAME 0x0102 /* AC-Name */ -#define PPPOE_TAG_HOST_UNIQ 0x0103 /* Host-Uniq */ -#define PPPOE_TAG_AC_COOKIE 0x0104 /* AC-Cookie */ -#define PPPOE_TAG_VENDOR_SPECIFIC 0x0105 /* Vendor-Specific */ -#define PPPOE_TAG_RELAY_SESSION_ID 0x0110 /* Relay-Session-Id */ -#define PPPOE_TAG_SERVICE_NAME_ERROR 0x0201 /* Service-Name-Error */ -#define PPPOE_TAG_AC_SYS_ERROR 0x0202 /* AC-System Error */ -#define PPPOE_TAG_GEN_ERROR 0x0203 /* Generic-Error */ - -void DecodePPPOERegisterTests(void); - -#endif /* __DECODE_PPPOE_H__ */ - diff --git a/framework/src/suricata/src/decode-raw.c b/framework/src/suricata/src/decode-raw.c deleted file mode 100644 index 22e1b9e1..00000000 --- a/framework/src/suricata/src/decode-raw.c +++ /dev/null @@ -1,232 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author William Metcalf - * - * Decode RAW - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-raw.h" -#include "decode-events.h" - -#include "util-unittest.h" -#include "util-debug.h" - -#include "pkt-var.h" -#include "util-profiling.h" -#include "host.h" - - -int DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_raw); - - /* If it is ipv4 or ipv6 it should at least be the size of ipv4 */ - if (unlikely(len < IPV4_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, IPV4_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - if (IP_GET_RAW_VER(pkt) == 4) { - SCLogDebug("IPV4 Packet"); - DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - } else if (IP_GET_RAW_VER(pkt) == 6) { - SCLogDebug("IPV6 Packet"); - DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - } else { - SCLogDebug("Unknown ip version %" PRIu8 "", IP_GET_RAW_VER(pkt)); - ENGINE_SET_EVENT(p,IPRAW_INVALID_IPV); - } - return TM_ECODE_OK; -} - -#ifdef UNITTESTS -#include "flow.h" -#include "flow-util.h" - -/** DecodeRawtest01 - * \brief Valid Raw packet - * \retval 0 Expected test value - */ -static int DecodeRawTest01 (void) -{ - - /* IPV6/TCP/no eth header */ - uint8_t raw_ip[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x40, - 0x20, 0x01, 0x06, 0x18, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x51, 0x99, 0xcc, 0x70, - 0x20, 0x01, 0x06, 0x18, 0x00, 0x01, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, - 0x8c, 0x9b, 0x00, 0x50, 0x6a, 0xe7, 0x07, 0x36, - 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0x30, - 0x29, 0x9c, 0x00, 0x00, 0x02, 0x04, 0x05, 0x8c, - 0x04, 0x02, 0x08, 0x0a, 0x00, 0xdd, 0x1a, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - - if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) { - SCFree(p); - return 1; - } - - FlowInitConfig(FLOW_QUIET); - - DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p), NULL); - if (p->ip6h == NULL) { - printf("expected a valid ipv6 header but it was NULL: "); - FlowShutdown(); - SCFree(p); - return 1; - } - - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return 0; - -} -/** DecodeRawtest02 - * \brief Valid Raw packet - * \retval 0 Expected test value - */ -static int DecodeRawTest02 (void) -{ - - /* IPV4/TCP/no eth header */ - uint8_t raw_ip[] = { - 0x45, 0x00, 0x00, 0x30, 0x00, 0xad, 0x40, 0x00, - 0x7f, 0x06, 0xac, 0xc5, 0xc0, 0xa8, 0x67, 0x02, - 0xc0, 0xa8, 0x66, 0x02, 0x0b, 0xc7, 0x00, 0x50, - 0x1d, 0xb3, 0x12, 0x37, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x02, 0x40, 0x00, 0xb8, 0xc8, 0x00, 0x00, - 0x02, 0x04, 0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - - if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) { - SCFree(p); - return 1; - } - - FlowInitConfig(FLOW_QUIET); - - DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p), NULL); - if (p->ip4h == NULL) { - printf("expected a valid ipv4 header but it was NULL: "); - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return 1; - } - - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return 0; -} -/** DecodeRawtest03 - * \brief Valid Raw packet - * \retval 0 Expected test value - */ -static int DecodeRawTest03 (void) -{ - - /* IPV13 */ - uint8_t raw_ip[] = { - 0xdf, 0x00, 0x00, 0x3d, 0x49, 0x42, 0x40, 0x00, - 0x40, 0x06, 0xcf, 0x8a, 0x0a, 0x1f, 0x03, 0xaf, - 0x0a, 0x1f, 0x0a, 0x02, 0xa5, 0xe7, 0xde, 0xad, - 0x00, 0x0c, 0xe2, 0x0e, 0x8b, 0xfe, 0x0c, 0xe7, - 0x80, 0x18, 0x00, 0xb7, 0xaf, 0xeb, 0x00, 0x00, - 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, 0xab, 0x4f, - 0x34, 0x40, 0x67, 0x31, 0x3b, 0x63, 0x61, 0x74, - 0x20, 0x6b, 0x65, 0x79, 0x3b }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - - if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) { - SCFree(p); - return 1; - } - - FlowInitConfig(FLOW_QUIET); - - DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p), NULL); - if (ENGINE_ISSET_EVENT(p,IPRAW_INVALID_IPV)) { - FlowShutdown(); - SCFree(p); - return 0; - } else { - printf("expected IPRAW_INVALID_IPV to be set but it wasn't: "); - } - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return 1; -} - -#endif /* UNITTESTS */ - -/** - * \brief Registers Raw unit tests - * \todo More Raw tests - */ -void DecodeRawRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodeRawTest01", DecodeRawTest01, 0); - UtRegisterTest("DecodeRawTest02", DecodeRawTest02, 0); - UtRegisterTest("DecodeRawTest03", DecodeRawTest03, 0); -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-raw.h b/framework/src/suricata/src/decode-raw.h deleted file mode 100644 index ff637870..00000000 --- a/framework/src/suricata/src/decode-raw.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author William Metcalf - */ - -#ifndef __DECODE_RAW_H__ -#define __DECODE_RAW_H__ -void DecodeRawRegisterTests(void); -#endif /* __DECODE_RAW_H__ */ - diff --git a/framework/src/suricata/src/decode-sctp.c b/framework/src/suricata/src/decode-sctp.c deleted file mode 100644 index 2d493c66..00000000 --- a/framework/src/suricata/src/decode-sctp.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (C) 2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Eric Leblond - * - * Decode SCTP - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-sctp.h" -#include "decode-events.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "util-optimize.h" -#include "flow.h" - -static int DecodeSCTPPacket(ThreadVars *tv, Packet *p, uint8_t *pkt, uint16_t len) -{ - if (unlikely(len < SCTP_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, SCTP_PKT_TOO_SMALL); - return -1; - } - - p->sctph = (SCTPHdr *)pkt; - - SET_SCTP_SRC_PORT(p,&p->sp); - SET_SCTP_DST_PORT(p,&p->dp); - - p->payload = pkt + sizeof(SCTPHdr); - p->payload_len = len - sizeof(SCTPHdr); - - p->proto = IPPROTO_SCTP; - - return 0; -} - -int DecodeSCTP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_sctp); - - if (unlikely(DecodeSCTPPacket(tv, p,pkt,len) < 0)) { - p->sctph = NULL; - return TM_ECODE_FAILED; - } - -#ifdef DEBUG - SCLogDebug("SCTP sp: %" PRIu32 " -> dp: %" PRIu32, - SCTP_GET_SRC_PORT(p), SCTP_GET_DST_PORT(p)); -#endif - - /* Flow is an integral part of us */ - FlowHandlePacket(tv, dtv, p); - - return TM_ECODE_OK; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-sctp.h b/framework/src/suricata/src/decode-sctp.h deleted file mode 100644 index 184a172e..00000000 --- a/framework/src/suricata/src/decode-sctp.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (C) 2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#ifndef __DECODE_SCTP_H__ -#define __DECODE_SCTP_H__ - -/** size of the packet header without any chunk headers */ -#define SCTP_HEADER_LEN 12 - -/* XXX RAW* needs to be really 'raw', so no ntohs there */ -#define SCTP_GET_RAW_SRC_PORT(sctph) ntohs((sctph)->sh_sport) -#define SCTP_GET_RAW_DST_PORT(sctph) ntohs((sctph)->sh_dport) - -#define SCTP_GET_SRC_PORT(p) SCTP_GET_RAW_SRC_PORT(p->sctph) -#define SCTP_GET_DST_PORT(p) SCTP_GET_RAW_DST_PORT(p->sctph) - -typedef struct SCTPHdr_ -{ - uint16_t sh_sport; /* source port */ - uint16_t sh_dport; /* destination port */ - uint32_t sh_vtag; /* verification tag, defined per flow */ - uint32_t sh_sum; /* checksum, computed via crc32 */ -} __attribute__((__packed__)) SCTPHdr; - -#define CLEAR_SCTP_PACKET(p) { \ - (p)->sctph = NULL; \ -} while (0) - -void DecodeSCTPRegisterTests(void); - -#endif /* __DECODE_SCTP_H__ */ diff --git a/framework/src/suricata/src/decode-sll.c b/framework/src/suricata/src/decode-sll.c deleted file mode 100644 index eed61a4c..00000000 --- a/framework/src/suricata/src/decode-sll.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decodes Sll - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-sll.h" -#include "decode-events.h" -#include "util-debug.h" - -int DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_sll); - - if (unlikely(len < SLL_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, SLL_PKT_TOO_SMALL); - return TM_ECODE_FAILED; - } - - SllHdr *sllh = (SllHdr *)pkt; - if (unlikely(sllh == NULL)) - return TM_ECODE_FAILED; - - SCLogDebug("p %p pkt %p sll_protocol %04x", p, pkt, ntohs(sllh->sll_protocol)); - - switch (ntohs(sllh->sll_protocol)) { - case ETHERNET_TYPE_IP: - DecodeIPV4(tv, dtv, p, pkt + SLL_HEADER_LEN, - len - SLL_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_IPV6: - DecodeIPV6(tv, dtv, p, pkt + SLL_HEADER_LEN, - len - SLL_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_VLAN: - DecodeVLAN(tv, dtv, p, pkt + SLL_HEADER_LEN, - len - SLL_HEADER_LEN, pq); - break; - default: - SCLogDebug("p %p pkt %p sll type %04x not supported", p, - pkt, ntohs(sllh->sll_protocol)); - } - - return TM_ECODE_OK; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-sll.h b/framework/src/suricata/src/decode-sll.h deleted file mode 100644 index babdd7ac..00000000 --- a/framework/src/suricata/src/decode-sll.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DECODE_SLL_H__ -#define __DECODE_SLL_H__ - -#define SLL_HEADER_LEN 16 - -typedef struct SllHdr_ { - uint16_t sll_pkttype; /* packet type */ - uint16_t sll_hatype; /* link-layer address type */ - uint16_t sll_halen; /* link-layer address length */ - uint8_t sll_addr[8]; /* link-layer address */ - uint16_t sll_protocol; /* protocol */ -} __attribute__((__packed__)) SllHdr; - -#endif /* __DECODE_SLL_H__ */ - diff --git a/framework/src/suricata/src/decode-tcp.c b/framework/src/suricata/src/decode-tcp.c deleted file mode 100644 index 428e7ae4..00000000 --- a/framework/src/suricata/src/decode-tcp.c +++ /dev/null @@ -1,521 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decode TCP - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-tcp.h" -#include "decode-events.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "util-optimize.h" -#include "flow.h" -#include "util-profiling.h" -#include "pkt-var.h" -#include "host.h" - -static int DecodeTCPOptions(Packet *p, uint8_t *pkt, uint16_t len) -{ - uint16_t plen = len; - while (plen) - { - /* single byte options */ - if (*pkt == TCP_OPT_EOL) { - break; - } else if (*pkt == TCP_OPT_NOP) { - pkt++; - plen--; - - /* multibyte options */ - } else { - if (plen < 2) { - break; - } - - /* we already know that the total options len is valid, - * so here the len of the specific option must be bad. - * Also check for invalid lengths 0 and 1. */ - if (unlikely(*(pkt+1) > plen || *(pkt+1) < 2)) { - ENGINE_SET_INVALID_EVENT(p, TCP_OPT_INVALID_LEN); - return -1; - } - - p->TCP_OPTS[p->TCP_OPTS_CNT].type = *pkt; - p->TCP_OPTS[p->TCP_OPTS_CNT].len = *(pkt+1); - if (plen > 2) - p->TCP_OPTS[p->TCP_OPTS_CNT].data = (pkt+2); - else - p->TCP_OPTS[p->TCP_OPTS_CNT].data = NULL; - - /* we are parsing the most commonly used opts to prevent - * us from having to walk the opts list for these all the - * time. */ - switch (p->TCP_OPTS[p->TCP_OPTS_CNT].type) { - case TCP_OPT_WS: - if (p->TCP_OPTS[p->TCP_OPTS_CNT].len != TCP_OPT_WS_LEN) { - ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); - } else { - if (p->tcpvars.ws != NULL) { - ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); - } else { - p->tcpvars.ws = &p->TCP_OPTS[p->TCP_OPTS_CNT]; - } - } - break; - case TCP_OPT_MSS: - if (p->TCP_OPTS[p->TCP_OPTS_CNT].len != TCP_OPT_MSS_LEN) { - ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); - } else { - if (p->tcpvars.mss != NULL) { - ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); - } else { - p->tcpvars.mss = &p->TCP_OPTS[p->TCP_OPTS_CNT]; - } - } - break; - case TCP_OPT_SACKOK: - if (p->TCP_OPTS[p->TCP_OPTS_CNT].len != TCP_OPT_SACKOK_LEN) { - ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); - } else { - if (p->tcpvars.sackok != NULL) { - ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); - } else { - p->tcpvars.sackok = &p->TCP_OPTS[p->TCP_OPTS_CNT]; - } - } - break; - case TCP_OPT_TS: - if (p->TCP_OPTS[p->TCP_OPTS_CNT].len != TCP_OPT_TS_LEN) { - ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); - } else { - if (p->tcpvars.ts != NULL) { - ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); - } else { - p->tcpvars.ts = &p->TCP_OPTS[p->TCP_OPTS_CNT]; - } - } - break; - case TCP_OPT_SACK: - SCLogDebug("SACK option, len %u", p->TCP_OPTS[p->TCP_OPTS_CNT].len); - if (p->TCP_OPTS[p->TCP_OPTS_CNT].len < TCP_OPT_SACK_MIN_LEN || - p->TCP_OPTS[p->TCP_OPTS_CNT].len > TCP_OPT_SACK_MAX_LEN || - !((p->TCP_OPTS[p->TCP_OPTS_CNT].len - 2) % 8 == 0)) - { - ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN); - } else { - if (p->tcpvars.sack != NULL) { - ENGINE_SET_EVENT(p,TCP_OPT_DUPLICATE); - } else { - p->tcpvars.sack = &p->TCP_OPTS[p->TCP_OPTS_CNT]; - } - } - break; - } - - pkt += p->TCP_OPTS[p->TCP_OPTS_CNT].len; - plen -= (p->TCP_OPTS[p->TCP_OPTS_CNT].len); - p->TCP_OPTS_CNT++; - } - } - return 0; -} - -static int DecodeTCPPacket(ThreadVars *tv, Packet *p, uint8_t *pkt, uint16_t len) -{ - if (unlikely(len < TCP_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, TCP_PKT_TOO_SMALL); - return -1; - } - - p->tcph = (TCPHdr *)pkt; - - uint8_t hlen = TCP_GET_HLEN(p); - if (unlikely(len < hlen)) { - ENGINE_SET_INVALID_EVENT(p, TCP_HLEN_TOO_SMALL); - return -1; - } - - uint8_t tcp_opt_len = hlen - TCP_HEADER_LEN; - if (unlikely(tcp_opt_len > TCP_OPTLENMAX)) { - ENGINE_SET_INVALID_EVENT(p, TCP_INVALID_OPTLEN); - return -1; - } - - if (likely(tcp_opt_len > 0)) { - DecodeTCPOptions(p, pkt + TCP_HEADER_LEN, tcp_opt_len); - } - - SET_TCP_SRC_PORT(p,&p->sp); - SET_TCP_DST_PORT(p,&p->dp); - - p->proto = IPPROTO_TCP; - - p->payload = pkt + hlen; - p->payload_len = len - hlen; - - return 0; -} - -int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_tcp); - - if (unlikely(DecodeTCPPacket(tv, p,pkt,len) < 0)) { - SCLogDebug("invalid TCP packet"); - p->tcph = NULL; - return TM_ECODE_FAILED; - } - -#ifdef DEBUG - SCLogDebug("TCP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 " %s%s%s%s%s", - GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_HLEN(p), len, - p->tcpvars.sackok ? "SACKOK " : "", p->tcpvars.sack ? "SACK " : "", - p->tcpvars.ws ? "WS " : "", p->tcpvars.ts ? "TS " : "", - p->tcpvars.mss ? "MSS " : ""); -#endif - - /* Flow is an integral part of us */ - FlowHandlePacket(tv, dtv, p); - - return TM_ECODE_OK; -} - -#ifdef UNITTESTS -static int TCPCalculateValidChecksumtest01(void) -{ - uint16_t csum = 0; - - uint8_t raw_ipshdr[] = { - 0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03}; - - uint8_t raw_tcp[] = { - 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, - 0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0, - 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, - 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 02}; - - csum = *( ((uint16_t *)raw_tcp) + 8); - - return (csum == TCPCalculateChecksum((uint16_t *) raw_ipshdr, - (uint16_t *)raw_tcp, sizeof(raw_tcp))); -} - -static int TCPCalculateInvalidChecksumtest02(void) -{ - uint16_t csum = 0; - - uint8_t raw_ipshdr[] = { - 0x40, 0x8e, 0x7e, 0xb2, 0xc0, 0xa8, 0x01, 0x03}; - - uint8_t raw_tcp[] = { - 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, - 0xcf, 0x0d, 0x21, 0x80, 0xa0, 0x12, 0x16, 0xa0, - 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, - 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 03}; - - csum = *( ((uint16_t *)raw_tcp) + 8); - - return (csum == TCPCalculateChecksum((uint16_t *) raw_ipshdr, - (uint16_t *)raw_tcp, sizeof(raw_tcp))); -} - -static int TCPV6CalculateValidChecksumtest03(void) -{ - uint16_t csum = 0; - - static uint8_t raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe, - 0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a, - 0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1, - 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, - 0xca, 0x5a, 0x00, 0x01, 0x69, 0x27}; - - csum = *( ((uint16_t *)(raw_ipv6 + 70))); - - return (csum == TCPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 32)); -} - -static int TCPV6CalculateInvalidChecksumtest04(void) -{ - uint16_t csum = 0; - - static uint8_t raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x20, 0x06, 0x40, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0x03, 0xfe, - 0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, 0x0c, 0x7a, - 0x08, 0x77, 0x80, 0x10, 0x21, 0x5c, 0xc2, 0xf1, - 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, - 0xca, 0x5a, 0x00, 0x01, 0x69, 0x28}; - - csum = *( ((uint16_t *)(raw_ipv6 + 70))); - - return (csum == TCPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 32)); -} - -/** \test Get the wscale of 2 */ -static int TCPGetWscaleTest01(void) -{ - int retval = 0; - static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58, - 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0, - 0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02}; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - IPV4Hdr ip4h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip4h, 0, sizeof(IPV4Hdr)); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->ip4h = &ip4h; - - - FlowInitConfig(FLOW_QUIET); - DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL); - - if (p->tcph == NULL) { - printf("tcp packet decode failed: "); - goto end; - } - - uint8_t wscale = TCP_GET_WSCALE(p); - if (wscale != 2) { - printf("wscale %"PRIu8", expected 2: ", wscale); - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/** \test Get the wscale of 15, so see if return 0 properly */ -static int TCPGetWscaleTest02(void) -{ - int retval = 0; - static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x58, - 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0xd0, - 0x8a, 0xaf, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x00, 0x62, 0x88, 0x28, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x0f}; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - IPV4Hdr ip4h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip4h, 0, sizeof(IPV4Hdr)); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->ip4h = &ip4h; - - FlowInitConfig(FLOW_QUIET); - DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL); - - if (p->tcph == NULL) { - printf("tcp packet decode failed: "); - goto end; - } - - uint8_t wscale = TCP_GET_WSCALE(p); - if (wscale != 0) { - printf("wscale %"PRIu8", expected 0: ", wscale); - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -/** \test Get the wscale, but it's missing, so see if return 0 properly */ -static int TCPGetWscaleTest03(void) -{ - int retval = 0; - static uint8_t raw_tcp[] = {0xda, 0xc1, 0x00, 0x50, 0xb6, 0x21, 0x7f, 0x59, - 0xdd, 0xa3, 0x6f, 0xf8, 0x80, 0x10, 0x05, 0xb4, - 0x7c, 0x70, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, - 0x00, 0x62, 0x88, 0x9e, 0x00, 0x00, 0x00, 0x00}; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - IPV4Hdr ip4h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip4h, 0, sizeof(IPV4Hdr)); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->ip4h = &ip4h; - - FlowInitConfig(FLOW_QUIET); - DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL); - - if (p->tcph == NULL) { - printf("tcp packet decode failed: "); - goto end; - } - - uint8_t wscale = TCP_GET_WSCALE(p); - if (wscale != 0) { - printf("wscale %"PRIu8", expected 0: ", wscale); - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} - -static int TCPGetSackTest01(void) -{ - int retval = 0; - static uint8_t raw_tcp[] = { - 0x00, 0x50, 0x06, 0xa6, 0xfa, 0x87, 0x0b, 0xf5, - 0xf1, 0x59, 0x02, 0xe0, 0xa0, 0x10, 0x3e, 0xbc, - 0x1d, 0xe7, 0x00, 0x00, 0x01, 0x01, 0x05, 0x12, - 0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64, - 0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 }; - static uint8_t raw_tcp_sack[] = { - 0xf1, 0x59, 0x13, 0xfc, 0xf1, 0x59, 0x1f, 0x64, - 0xf1, 0x59, 0x08, 0x94, 0xf1, 0x59, 0x0e, 0x48 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - IPV4Hdr ip4h; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip4h, 0, sizeof(IPV4Hdr)); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->ip4h = &ip4h; - - FlowInitConfig(FLOW_QUIET); - DecodeTCP(&tv, &dtv, p, raw_tcp, sizeof(raw_tcp), NULL); - - if (p->tcph == NULL) { - printf("tcp packet decode failed: "); - goto end; - } - - if (p->tcpvars.sack == NULL) { - printf("tcp packet sack not decoded: "); - goto end; - } - - int sack = TCP_GET_SACK_CNT(p); - if (sack != 2) { - printf("expected 2 sack records, got %u: ", TCP_GET_SACK_CNT(p)); - goto end; - } - - uint8_t *sackptr = TCP_GET_SACK_PTR(p); - if (sackptr == NULL) { - printf("no sack data: "); - goto end; - } - - if (memcmp(sackptr, raw_tcp_sack, 16) != 0) { - printf("malformed sack data: "); - goto end; - } - - retval = 1; -end: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return retval; -} -#endif /* UNITTESTS */ - -void DecodeTCPRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("TCPCalculateValidChecksumtest01", - TCPCalculateValidChecksumtest01, 1); - UtRegisterTest("TCPCalculateInvalidChecksumtest02", - TCPCalculateInvalidChecksumtest02, 0); - UtRegisterTest("TCPV6CalculateValidChecksumtest03", - TCPV6CalculateValidChecksumtest03, 1); - UtRegisterTest("TCPV6CalculateInvalidChecksumtest04", - TCPV6CalculateInvalidChecksumtest04, 0); - UtRegisterTest("TCPGetWscaleTest01", TCPGetWscaleTest01, 1); - UtRegisterTest("TCPGetWscaleTest02", TCPGetWscaleTest02, 1); - UtRegisterTest("TCPGetWscaleTest03", TCPGetWscaleTest03, 1); - UtRegisterTest("TCPGetSackTest01", TCPGetSackTest01, 1); -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-tcp.h b/framework/src/suricata/src/decode-tcp.h deleted file mode 100644 index 29c02dfb..00000000 --- a/framework/src/suricata/src/decode-tcp.h +++ /dev/null @@ -1,297 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \todo RAW* macro's should be returning the raw value, not the host order - */ - -#ifndef __DECODE_TCP_H__ -#define __DECODE_TCP_H__ - -#define TCP_HEADER_LEN 20 -#define TCP_OPTLENMAX 40 -#define TCP_OPTMAX 20 /* every opt is at least 2 bytes - * (type + len), except EOL and NOP */ - -/* TCP flags */ - -#define TH_FIN 0x01 -#define TH_SYN 0x02 -#define TH_RST 0x04 -#define TH_PUSH 0x08 -#define TH_ACK 0x10 -#define TH_URG 0x20 -/** Establish a new connection reducing window */ -#define TH_ECN 0x40 -/** Echo Congestion flag */ -#define TH_CWR 0x80 - -/* tcp option codes */ -#define TCP_OPT_EOL 0x00 -#define TCP_OPT_NOP 0x01 -#define TCP_OPT_MSS 0x02 -#define TCP_OPT_WS 0x03 -#define TCP_OPT_SACKOK 0x04 -#define TCP_OPT_SACK 0x05 -#define TCP_OPT_TS 0x08 - -#define TCP_OPT_SACKOK_LEN 2 -#define TCP_OPT_WS_LEN 3 -#define TCP_OPT_TS_LEN 10 -#define TCP_OPT_MSS_LEN 4 -#define TCP_OPT_SACK_MIN_LEN 10 /* hdr 2, 1 pair 8 = 10 */ -#define TCP_OPT_SACK_MAX_LEN 34 /* hdr 2, 4 pair 32= 34 */ - -/** Max valid wscale value. */ -#define TCP_WSCALE_MAX 14 - -#define TCP_OPTS tcpvars.tcp_opts -#define TCP_OPTS_CNT tcpvars.tcp_opt_cnt - -#define TCP_GET_RAW_OFFSET(tcph) (((tcph)->th_offx2 & 0xf0) >> 4) -#define TCP_GET_RAW_X2(tcph) (unsigned char)((tcph)->th_offx2 & 0x0f) -#define TCP_GET_RAW_SRC_PORT(tcph) ntohs((tcph)->th_sport) -#define TCP_GET_RAW_DST_PORT(tcph) ntohs((tcph)->th_dport) - -#define TCP_SET_RAW_TCP_OFFSET(tcph, value) ((tcph)->th_offx2 = (unsigned char)(((tcph)->th_offx2 & 0x0f) | (value << 4))) -#define TCP_SET_RAW_TCP_X2(tcph, value) ((tcph)->th_offx2 = (unsigned char)(((tcph)->th_offx2 & 0xf0) | (value & 0x0f))) - -#define TCP_GET_RAW_SEQ(tcph) ntohl((tcph)->th_seq) -#define TCP_GET_RAW_ACK(tcph) ntohl((tcph)->th_ack) - -#define TCP_GET_RAW_WINDOW(tcph) ntohs((tcph)->th_win) -#define TCP_GET_RAW_URG_POINTER(tcph) ntohs((tcph)->th_urp) - -/** macro for getting the first timestamp from the packet. Timestamp is in host - * order and either returned from the cache or from the packet directly. */ -#define TCP_GET_TSVAL(p) \ - (uint32_t)ntohl((*(uint32_t *)(p)->tcpvars.ts->data)) - -/** macro for getting the second timestamp from the packet. Timestamp is in - * host order and either returned from the cache or from the packet directly. */ -#define TCP_GET_TSECR(p) \ - (uint32_t)ntohl((*(uint32_t *)((p)->tcpvars.ts->data+4))) - -/** macro for getting the wscale from the packet. */ -#define TCP_GET_WSCALE(p) ((p)->tcpvars.ws ? (((*(uint8_t *)(p)->tcpvars.ws->data) <= TCP_WSCALE_MAX) ? (*(uint8_t *)((p)->tcpvars.ws->data)) : 0) : 0) - -#define TCP_GET_SACKOK(p) ((p)->tcpvars.sackok ? 1 : 0) -#define TCP_GET_SACK_PTR(p) (p)->tcpvars.sack ? (p)->tcpvars.sack->data : NULL -#define TCP_GET_SACK_CNT(p) ((p)->tcpvars.sack ? (((p)->tcpvars.sack->len - 2) / 8) : 0) - -#define TCP_GET_OFFSET(p) TCP_GET_RAW_OFFSET((p)->tcph) -#define TCP_GET_HLEN(p) (TCP_GET_OFFSET((p)) << 2) -#define TCP_GET_SRC_PORT(p) TCP_GET_RAW_SRC_PORT((p)->tcph) -#define TCP_GET_DST_PORT(p) TCP_GET_RAW_DST_PORT((p)->tcph) -#define TCP_GET_SEQ(p) TCP_GET_RAW_SEQ((p)->tcph) -#define TCP_GET_ACK(p) TCP_GET_RAW_ACK((p)->tcph) -#define TCP_GET_WINDOW(p) TCP_GET_RAW_WINDOW((p)->tcph) -#define TCP_GET_URG_POINTER(p) TCP_GET_RAW_URG_POINTER((p)->tcph) - -#define TCP_ISSET_FLAG_FIN(p) ((p)->tcph->th_flags & TH_FIN) -#define TCP_ISSET_FLAG_SYN(p) ((p)->tcph->th_flags & TH_SYN) -#define TCP_ISSET_FLAG_RST(p) ((p)->tcph->th_flags & TH_RST) -#define TCP_ISSET_FLAG_PUSH(p) ((p)->tcph->th_flags & TH_PUSH) -#define TCP_ISSET_FLAG_ACK(p) ((p)->tcph->th_flags & TH_ACK) -#define TCP_ISSET_FLAG_URG(p) ((p)->tcph->th_flags & TH_URG) -#define TCP_ISSET_FLAG_RES2(p) ((p)->tcph->th_flags & TH_RES2) -#define TCP_ISSET_FLAG_RES1(p) ((p)->tcph->th_flags & TH_RES1) - -typedef struct TCPOpt_ { - uint8_t type; - uint8_t len; - uint8_t *data; -} TCPOpt; - -typedef struct TCPOptSackRecord_ { - uint32_t le; /**< left edge, network order */ - uint32_t re; /**< right edge, network order */ -} TCPOptSackRecord; - -typedef struct TCPHdr_ -{ - uint16_t th_sport; /**< source port */ - uint16_t th_dport; /**< destination port */ - uint32_t th_seq; /**< sequence number */ - uint32_t th_ack; /**< acknowledgement number */ - uint8_t th_offx2; /**< offset and reserved */ - uint8_t th_flags; /**< pkt flags */ - uint16_t th_win; /**< pkt window */ - uint16_t th_sum; /**< checksum */ - uint16_t th_urp; /**< urgent pointer */ -} __attribute__((__packed__)) TCPHdr; - -typedef struct TCPVars_ -{ - uint8_t tcp_opt_cnt; - TCPOpt tcp_opts[TCP_OPTMAX]; - - /* ptrs to commonly used and needed opts */ - TCPOpt *ts; - TCPOpt *sack; - TCPOpt *sackok; - TCPOpt *ws; - TCPOpt *mss; -} TCPVars; - -#define CLEAR_TCP_PACKET(p) { \ - (p)->tcph = NULL; \ - (p)->level4_comp_csum = -1; \ - (p)->tcpvars.tcp_opt_cnt = 0; \ - (p)->tcpvars.ts = NULL; \ - (p)->tcpvars.sack = NULL; \ - (p)->tcpvars.sackok = NULL; \ - (p)->tcpvars.ws = NULL; \ - (p)->tcpvars.mss = NULL; \ -} - -void DecodeTCPRegisterTests(void); - -/** -------- Inline functions ------- */ -static inline uint16_t TCPCalculateChecksum(uint16_t *, uint16_t *, uint16_t); -static inline uint16_t TCPV6CalculateChecksum(uint16_t *, uint16_t *, uint16_t); - -/** - * \brief Calculates the checksum for the TCP packet - * - * \param shdr Pointer to source address field from the IP packet. Used as a - * part of the pseudoheader for computing the checksum - * \param pkt Pointer to the start of the TCP packet - * \param tlen Total length of the TCP packet(header + payload) - * - * \retval csum Checksum for the TCP packet - */ -static inline uint16_t TCPCalculateChecksum(uint16_t *shdr, uint16_t *pkt, - uint16_t tlen) -{ - uint16_t pad = 0; - uint32_t csum = shdr[0]; - - csum += shdr[1] + shdr[2] + shdr[3] + htons(6) + htons(tlen); - - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[9]; - - tlen -= 20; - pkt += 10; - - while (tlen >= 32) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15]; - tlen -= 32; - pkt += 16; - } - - while(tlen >= 8) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3]; - tlen -= 8; - pkt += 4; - } - - while(tlen >= 4) { - csum += pkt[0] + pkt[1]; - tlen -= 4; - pkt += 2; - } - - while (tlen > 1) { - csum += pkt[0]; - pkt += 1; - tlen -= 2; - } - - if (tlen == 1) { - *(uint8_t *)(&pad) = (*(uint8_t *)pkt); - csum += pad; - } - - csum = (csum >> 16) + (csum & 0x0000FFFF); - csum += (csum >> 16); - - return (uint16_t)~csum; -} - -/** - * \brief Calculates the checksum for the TCP packet - * - * \param shdr Pointer to source address field from the IPV6 packet. Used as a - * part of the psuedoheader for computing the checksum - * \param pkt Pointer to the start of the TCP packet - * \param tlen Total length of the TCP packet(header + payload) - * - * \retval csum Checksum for the TCP packet - */ -static inline uint16_t TCPV6CalculateChecksum(uint16_t *shdr, uint16_t *pkt, - uint16_t tlen) -{ - uint16_t pad = 0; - uint32_t csum = shdr[0]; - - csum += shdr[1] + shdr[2] + shdr[3] + shdr[4] + shdr[5] + shdr[6] + - shdr[7] + shdr[8] + shdr[9] + shdr[10] + shdr[11] + shdr[12] + - shdr[13] + shdr[14] + shdr[15] + htons(6) + htons(tlen); - - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[9]; - - tlen -= 20; - pkt += 10; - - while (tlen >= 32) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15]; - tlen -= 32; - pkt += 16; - } - - while(tlen >= 8) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3]; - tlen -= 8; - pkt += 4; - } - - while(tlen >= 4) { - csum += pkt[0] + pkt[1]; - tlen -= 4; - pkt += 2; - } - - while (tlen > 1) { - csum += pkt[0]; - pkt += 1; - tlen -= 2; - } - - if (tlen == 1) { - *(uint8_t *)(&pad) = (*(uint8_t *)pkt); - csum += pad; - } - - csum = (csum >> 16) + (csum & 0x0000FFFF); - csum += (csum >> 16); - - return (uint16_t)~csum; -} - - -#endif /* __DECODE_TCP_H__ */ - diff --git a/framework/src/suricata/src/decode-template.c b/framework/src/suricata/src/decode-template.c deleted file mode 100644 index 2673a2cd..00000000 --- a/framework/src/suricata/src/decode-template.c +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author XXX Your Name - * - * Decodes XXX describe the protocol - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "decode-events.h" -#include "decode-template.h" - -#include "util-unittest.h" -#include "util-debug.h" - -/** - * \brief Function to decode XXX packets - * \param tv thread vars - * \param dtv decoder thread vars - * \param p packet - * \param pkt raw packet data - * \param len length in bytes of pkt array - * \retval TM_ECODE_OK or TM_ECODE_FAILED on serious error - */ - -int DecodeTEMPLATE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, - const uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - /* TODO add counter for your type of packet to DecodeThreadVars, - * and register it in DecodeRegisterPerfCounters */ - //StatsIncr(tv, dtv->counter_template); - - /* Validation: make sure that the input data is big enough to hold - * the header */ - if (len < sizeof(TemplateHdr)) { - /* in case of errors, we set events. Events are defined in - * decode-events.h, and are then exposed to the detection - * engine through detect-engine-events.h */ - //ENGINE_SET_EVENT(p,TEMPLATE_HEADER_TOO_SMALL); - return TM_ECODE_FAILED; - } - - /* Now we can access the header */ - const TemplateHdr *hdr = (const TemplateHdr *)pkt; - - /* lets assume we have UDP encapsulated */ - if (hdr->proto == 17) { - /* we need to pass on the pkt and it's length minus the current - * header */ - size_t hdr_len = sizeof(TemplateHdr); - - /* in this example it's clear that hdr_len can't be bigger than - * 'len', but in more complex cases checking that we can't underflow - * len is very important - if (hdr_len < len) { - */ - - /* invoke the next decoder on the remainder of the data */ - return DecodeUDP(tv, dtv, p, (uint8_t *)pkt + hdr_len, len - hdr_len, pq); - //} - } else { - //ENGINE_SET_EVENT(p,TEMPLATE_UNSUPPORTED_PROTOCOL); - return TM_ECODE_FAILED; - } - - return TM_ECODE_OK; -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-template.h b/framework/src/suricata/src/decode-template.h deleted file mode 100644 index b6a976e0..00000000 --- a/framework/src/suricata/src/decode-template.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author XXX - * - */ - -#ifndef __DECODE_TEMPLATE_H__ -#define __DECODE_TEMPLATE_H__ - -#include "decode.h" -#include "threadvars.h" - -typedef struct TemplateHdr_ { - uint8_t proto; - uint8_t pad0; - uint16_t pad1; -} __attribute__((__packed__)) TemplateHdr; - -#endif /* __DECODE_TEMPLATE_H__ */ diff --git a/framework/src/suricata/src/decode-teredo.c b/framework/src/suricata/src/decode-teredo.c deleted file mode 100644 index 20876027..00000000 --- a/framework/src/suricata/src/decode-teredo.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Eric Leblond - * - * Decode Teredo Tunneling protocol. - * - * This implementation is based upon RFC 4380: http://www.ietf.org/rfc/rfc4380.txt - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-ipv6.h" -#include "util-debug.h" - -#define TEREDO_ORIG_INDICATION_LENGTH 8 - -/** - * \brief Function to decode Teredo packets - * - * \retval TM_ECODE_FAILED if packet is not a Teredo packet, TM_ECODE_OK if it is - */ -int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - - uint8_t *start = pkt; - - /* Is this packet to short to contain an IPv6 packet ? */ - if (len < IPV6_HEADER_LEN) - return TM_ECODE_FAILED; - - /* Teredo encapsulate IPv6 in UDP and can add some custom message - * part before the IPv6 packet. In our case, we just want to get - * over an ORIGIN indication. So we just make one offset if needed. */ - if (start[0] == 0x0) { - switch (start[1]) { - /* origin indication: compatible with tunnel */ - case 0x0: - /* offset is coherent with len and presence of an IPv6 header */ - if (len >= TEREDO_ORIG_INDICATION_LENGTH + IPV6_HEADER_LEN) - start += TEREDO_ORIG_INDICATION_LENGTH; - else - return TM_ECODE_FAILED; - break; - /* authentication: negotiation not real tunnel */ - case 0x1: - return TM_ECODE_FAILED; - /* this case is not possible in Teredo: not that protocol */ - default: - return TM_ECODE_FAILED; - } - } - - /* There is no specific field that we can check to prove that the packet - * is a Teredo packet. We've zapped here all the possible Teredo header - * and we should have an IPv6 packet at the start pointer. - * We then can only do two checks before sending the encapsulated packets - * to decoding: - * - The packet has a protocol version which is IPv6. - * - The IPv6 length of the packet matches what remains in buffer. - */ - if (IP_GET_RAW_VER(start) == 6) { - IPV6Hdr *thdr = (IPV6Hdr *)start; - if (len == IPV6_HEADER_LEN + - IPV6_GET_RAW_PLEN(thdr) + (start - pkt)) { - if (pq != NULL) { - int blen = len - (start - pkt); - /* spawn off tunnel packet */ - Packet *tp = PacketTunnelPktSetup(tv, dtv, p, start, blen, - DECODE_TUNNEL_IPV6, pq); - if (tp != NULL) { - PKT_SET_SRC(tp, PKT_SRC_DECODER_TEREDO); - /* add the tp to the packet queue. */ - PacketEnqueue(pq,tp); - StatsIncr(tv, dtv->counter_teredo); - return TM_ECODE_OK; - } - } - } - return TM_ECODE_FAILED; - } - - return TM_ECODE_FAILED; -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-teredo.h b/framework/src/suricata/src/decode-teredo.h deleted file mode 100644 index 142d13c2..00000000 --- a/framework/src/suricata/src/decode-teredo.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -int DecodeTeredo(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, - uint8_t *pkt, uint16_t len, PacketQueue *pq); diff --git a/framework/src/suricata/src/decode-udp.c b/framework/src/suricata/src/decode-udp.c deleted file mode 100644 index 14ba7887..00000000 --- a/framework/src/suricata/src/decode-udp.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decode UDP - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-udp.h" -#include "decode-teredo.h" -#include "decode-events.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "flow.h" -#include "app-layer.h" - -static int DecodeUDPPacket(ThreadVars *t, Packet *p, uint8_t *pkt, uint16_t len) -{ - if (unlikely(len < UDP_HEADER_LEN)) { - ENGINE_SET_INVALID_EVENT(p, UDP_HLEN_TOO_SMALL); - return -1; - } - - p->udph = (UDPHdr *)pkt; - - if (unlikely(len < UDP_GET_LEN(p))) { - ENGINE_SET_INVALID_EVENT(p, UDP_PKT_TOO_SMALL); - return -1; - } - - if (unlikely(len != UDP_GET_LEN(p))) { - ENGINE_SET_INVALID_EVENT(p, UDP_HLEN_INVALID); - return -1; - } - - SET_UDP_SRC_PORT(p,&p->sp); - SET_UDP_DST_PORT(p,&p->dp); - - p->payload = pkt + UDP_HEADER_LEN; - p->payload_len = len - UDP_HEADER_LEN; - - p->proto = IPPROTO_UDP; - - return 0; -} - -int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - StatsIncr(tv, dtv->counter_udp); - - if (unlikely(DecodeUDPPacket(tv, p,pkt,len) < 0)) { - p->udph = NULL; - return TM_ECODE_FAILED; - } - - SCLogDebug("UDP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 "", - UDP_GET_SRC_PORT(p), UDP_GET_DST_PORT(p), UDP_HEADER_LEN, p->payload_len); - - if (unlikely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len, pq) == TM_ECODE_OK)) { - /* Here we have a Teredo packet and don't need to handle app - * layer */ - FlowHandlePacket(tv, dtv, p); - return TM_ECODE_OK; - } - - /* Flow is an integral part of us */ - FlowHandlePacket(tv, dtv, p); - - /* handle the app layer part of the UDP packet payload */ - if (unlikely(p->flow != NULL)) { - AppLayerHandleUdp(tv, dtv->app_tctx, p, p->flow); - } - - return TM_ECODE_OK; -} - -#ifdef UNITTESTS -static int UDPV4CalculateValidChecksumtest01(void) -{ - uint16_t csum = 0; - - uint8_t raw_ipshdr[] = { - 0xd0, 0x43, 0xdc, 0xdc, 0xc0, 0xa8, 0x01, 0x3}; - - uint8_t raw_udp[] = { - 0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0, - 0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67, - 0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63, - 0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, - 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b, - 0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65, - 0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0xc0, 0x26}; - - csum = *( ((uint16_t *)raw_udp) + 3); - - return (csum == UDPV4CalculateChecksum((uint16_t *) raw_ipshdr, - (uint16_t *)raw_udp, - sizeof(raw_udp))); -} - -static int UDPV4CalculateInvalidChecksumtest02(void) -{ - uint16_t csum = 0; - - uint8_t raw_ipshdr[] = { - 0xd0, 0x43, 0xdc, 0xdc, 0xc0, 0xa8, 0x01, 0x3}; - - uint8_t raw_udp[] = { - 0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0, - 0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67, - 0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63, - 0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, - 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b, - 0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65, - 0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0xc0, 0x27}; - - csum = *( ((uint16_t *)raw_udp) + 3); - - return (csum == UDPV4CalculateChecksum((uint16_t *) raw_ipshdr, - (uint16_t *)raw_udp, - sizeof(raw_udp))); -} - -static int UDPV6CalculateValidChecksumtest03(void) -{ - uint16_t csum = 0; - - static uint8_t raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0, - 0x09, 0x00}; - - csum = *( ((uint16_t *)(raw_ipv6 + 60))); - - return (csum == UDPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 20)); -} - -static int UDPV6CalculateInvalidChecksumtest04(void) -{ - uint16_t csum = 0; - - static uint8_t raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0, - 0x09, 0x01}; - - csum = *( ((uint16_t *)(raw_ipv6 + 60))); - - return (csum == UDPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8), - (uint16_t *)(raw_ipv6 + 54), 20)); -} -#endif /* UNITTESTS */ - -void DecodeUDPV4RegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("UDPV4CalculateValidChecksumtest01", - UDPV4CalculateValidChecksumtest01, 1); - UtRegisterTest("UDPV4CalculateInvalidChecksumtest02", - UDPV4CalculateInvalidChecksumtest02, 0); - UtRegisterTest("UDPV6CalculateValidChecksumtest03", - UDPV6CalculateValidChecksumtest03, 1); - UtRegisterTest("UDPV6CalculateInvalidChecksumtest04", - UDPV6CalculateInvalidChecksumtest04, 0); -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-udp.h b/framework/src/suricata/src/decode-udp.h deleted file mode 100644 index 5636c32b..00000000 --- a/framework/src/suricata/src/decode-udp.h +++ /dev/null @@ -1,193 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DECODE_UDP_H__ -#define __DECODE_UDP_H__ - -#define UDP_HEADER_LEN 8 - -/* XXX RAW* needs to be really 'raw', so no ntohs there */ -#define UDP_GET_RAW_LEN(udph) ntohs((udph)->uh_len) -#define UDP_GET_RAW_SRC_PORT(udph) ntohs((udph)->uh_sport) -#define UDP_GET_RAW_DST_PORT(udph) ntohs((udph)->uh_dport) - -#define UDP_GET_LEN(p) UDP_GET_RAW_LEN(p->udph) -#define UDP_GET_SRC_PORT(p) UDP_GET_RAW_SRC_PORT(p->udph) -#define UDP_GET_DST_PORT(p) UDP_GET_RAW_DST_PORT(p->udph) - -/* UDP header structure */ -typedef struct UDPHdr_ -{ - uint16_t uh_sport; /* source port */ - uint16_t uh_dport; /* destination port */ - uint16_t uh_len; /* length */ - uint16_t uh_sum; /* checksum */ -} __attribute__((__packed__)) UDPHdr; - -typedef struct UDPVars_ -{ -} UDPVars; - -#define CLEAR_UDP_PACKET(p) do { \ - (p)->udph = NULL; \ - (p)->level4_comp_csum = -1; \ -} while (0) - -void DecodeUDPV4RegisterTests(void); - -/** ------ Inline function ------ */ -static inline uint16_t UDPV4CalculateChecksum(uint16_t *, uint16_t *, uint16_t); -static inline uint16_t UDPV6CalculateChecksum(uint16_t *, uint16_t *, uint16_t); - -/** - * \brief Calculates the checksum for the UDP packet - * - * \param shdr Pointer to source address field from the IP packet. Used as a - * part of the psuedoheader for computing the checksum - * \param pkt Pointer to the start of the UDP packet - * \param hlen Total length of the UDP packet(header + payload) - * - * \retval csum Checksum for the UDP packet - */ -static inline uint16_t UDPV4CalculateChecksum(uint16_t *shdr, uint16_t *pkt, - uint16_t tlen) -{ - uint16_t pad = 0; - uint32_t csum = shdr[0]; - - csum += shdr[1] + shdr[2] + shdr[3] + htons(17) + htons(tlen); - - csum += pkt[0] + pkt[1] + pkt[2]; - - tlen -= 8; - pkt += 4; - - while (tlen >= 32) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15]; - tlen -= 32; - pkt += 16; - } - - while(tlen >= 8) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3]; - tlen -= 8; - pkt += 4; - } - - while(tlen >= 4) { - csum += pkt[0] + pkt[1]; - tlen -= 4; - pkt += 2; - } - - while (tlen > 1) { - csum += pkt[0]; - pkt += 1; - tlen -= 2; - } - - if (tlen == 1) { - *(uint8_t *)(&pad) = (*(uint8_t *)pkt); - csum += pad; - } - - csum = (csum >> 16) + (csum & 0x0000FFFF); - csum += (csum >> 16); - - uint16_t csum_u16 = (uint16_t)~csum; - if (csum_u16 == 0) - return 0xFFFF; - else - return csum_u16; -} - -/** - * \brief Calculates the checksum for the UDP packet - * - * \param shdr Pointer to source address field from the IPV6 packet. Used as a - * part of the psuedoheader for computing the checksum - * \param pkt Pointer to the start of the UDP packet - * \param tlen Total length of the UDP packet(header + payload) - * - * \retval csum Checksum for the UDP packet - */ -static inline uint16_t UDPV6CalculateChecksum(uint16_t *shdr, uint16_t *pkt, - uint16_t tlen) -{ - uint16_t pad = 0; - uint32_t csum = shdr[0]; - - csum += shdr[1] + shdr[2] + shdr[3] + shdr[4] + shdr[5] + shdr[6] + - shdr[7] + shdr[8] + shdr[9] + shdr[10] + shdr[11] + shdr[12] + - shdr[13] + shdr[14] + shdr[15] + htons(17) + htons(tlen); - - csum += pkt[0] + pkt[1] + pkt[2]; - - tlen -= 8; - pkt += 4; - - while (tlen >= 32) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3] + pkt[4] + pkt[5] + pkt[6] + - pkt[7] + pkt[8] + pkt[9] + pkt[10] + pkt[11] + pkt[12] + pkt[13] + - pkt[14] + pkt[15]; - tlen -= 32; - pkt += 16; - } - - while(tlen >= 8) { - csum += pkt[0] + pkt[1] + pkt[2] + pkt[3]; - tlen -= 8; - pkt += 4; - } - - while(tlen >= 4) { - csum += pkt[0] + pkt[1]; - tlen -= 4; - pkt += 2; - } - - while (tlen > 1) { - csum += pkt[0]; - pkt += 1; - tlen -= 2; - } - - if (tlen == 1) { - *(uint8_t *)(&pad) = (*(uint8_t *)pkt); - csum += pad; - } - - csum = (csum >> 16) + (csum & 0x0000FFFF); - csum += (csum >> 16); - - uint16_t csum_u16 = (uint16_t)~csum; - if (csum_u16 == 0) - return 0xFFFF; - else - return csum_u16; -} - - -#endif /* __DECODE_UDP_H__ */ diff --git a/framework/src/suricata/src/decode-vlan.c b/framework/src/suricata/src/decode-vlan.c deleted file mode 100644 index 59495594..00000000 --- a/framework/src/suricata/src/decode-vlan.c +++ /dev/null @@ -1,279 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup decode - * - * @{ - */ - - -/** - * \file - * - * \author Breno Silva - * - * Decode 802.1q - */ - -#include "suricata-common.h" -#include "decode.h" -#include "decode-vlan.h" -#include "decode-events.h" - -#include "flow.h" - -#include "util-unittest.h" -#include "util-debug.h" - -#include "pkt-var.h" -#include "util-profiling.h" -#include "host.h" - -/** - * \internal - * \brief this function is used to decode IEEE802.1q packets - * - * \param tv pointer to the thread vars - * \param dtv pointer code thread vars - * \param p pointer to the packet struct - * \param pkt pointer to the raw packet - * \param len packet len - * \param pq pointer to the packet queue - * - */ -int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) -{ - uint32_t proto; - - if (p->vlan_idx == 0) - StatsIncr(tv, dtv->counter_vlan); - else if (p->vlan_idx == 1) - StatsIncr(tv, dtv->counter_vlan_qinq); - - if(len < VLAN_HEADER_LEN) { - ENGINE_SET_INVALID_EVENT(p, VLAN_HEADER_TOO_SMALL); - return TM_ECODE_FAILED; - } - if (p->vlan_idx >= 2) { - ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS); - return TM_ECODE_FAILED; - } - - p->vlanh[p->vlan_idx] = (VLANHdr *)pkt; - if(p->vlanh[p->vlan_idx] == NULL) - return TM_ECODE_FAILED; - - proto = GET_VLAN_PROTO(p->vlanh[p->vlan_idx]); - - SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRId32 "", - p, pkt, proto, GET_VLAN_PRIORITY(p->vlanh[p->vlan_idx]), - GET_VLAN_CFI(p->vlanh[p->vlan_idx]), GET_VLAN_ID(p->vlanh[p->vlan_idx]), len); - - /* only store the id for flow hashing if it's not disabled. */ - if (dtv->vlan_disabled == 0) - p->vlan_id[p->vlan_idx] = (uint16_t)GET_VLAN_ID(p->vlanh[p->vlan_idx]); - - p->vlan_idx++; - - switch (proto) { - case ETHERNET_TYPE_IP: - DecodeIPV4(tv, dtv, p, pkt + VLAN_HEADER_LEN, - len - VLAN_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_IPV6: - DecodeIPV6(tv, dtv, p, pkt + VLAN_HEADER_LEN, - len - VLAN_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_PPPOE_SESS: - DecodePPPOESession(tv, dtv, p, pkt + VLAN_HEADER_LEN, - len - VLAN_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_PPPOE_DISC: - DecodePPPOEDiscovery(tv, dtv, p, pkt + VLAN_HEADER_LEN, - len - VLAN_HEADER_LEN, pq); - break; - case ETHERNET_TYPE_VLAN: - case ETHERNET_TYPE_8021AD: - if (p->vlan_idx >= 2) { - ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS); - return TM_ECODE_OK; - } else { - DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN, - len - VLAN_HEADER_LEN, pq); - } - break; - default: - SCLogDebug("unknown VLAN type: %" PRIx32 "", proto); - ENGINE_SET_INVALID_EVENT(p, VLAN_UNKNOWN_TYPE); - return TM_ECODE_OK; - } - - return TM_ECODE_OK; -} - -uint16_t DecodeVLANGetId(const Packet *p, uint8_t layer) -{ - if (unlikely(layer > 1)) - return 0; - - if (p->vlanh[layer] == NULL && (p->vlan_idx >= (layer + 1))) { - return p->vlan_id[layer]; - } else { - return GET_VLAN_ID(p->vlanh[layer]); - } - return 0; -} - -#ifdef UNITTESTS -/** \todo Must GRE+VLAN and Multi-Vlan packets to - * create more tests - */ - -/** - * \test DecodeVLANTest01 test if vlan header is too small. - * - * \retval 1 on success - * \retval 0 on failure - */ -static int DecodeVLANtest01 (void) -{ - uint8_t raw_vlan[] = { 0x00, 0x20, 0x08 }; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan), NULL); - - if(ENGINE_ISSET_EVENT(p,VLAN_HEADER_TOO_SMALL)) { - SCFree(p); - return 1; - } - - SCFree(p); - return 0; -} - -/** - * \test DecodeVLANTest02 test if vlan header has unknown type. - * - * \retval 1 on success - * \retval 0 on failure - */ -static int DecodeVLANtest02 (void) -{ - uint8_t raw_vlan[] = { - 0x00, 0x20, 0x01, 0x00, 0x45, 0x00, 0x00, 0x34, - 0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9, - 0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15, - 0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55, - 0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50, - 0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, - 0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3}; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan), NULL); - - - if(ENGINE_ISSET_EVENT(p,VLAN_UNKNOWN_TYPE)) { - SCFree(p); - return 1; - } - - SCFree(p); - return 0; -} - -/** - * \test DecodeVLANTest02 test a good vlan header. - * - * \retval 1 on success - * \retval 0 on failure - */ -static int DecodeVLANtest03 (void) -{ - uint8_t raw_vlan[] = { - 0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34, - 0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9, - 0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15, - 0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55, - 0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50, - 0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, - 0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3}; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - DecodeVLAN(&tv, &dtv, p, raw_vlan, sizeof(raw_vlan), NULL); - - - if(p->vlanh == NULL) { - goto error; - } - - if(ENGINE_ISSET_EVENT(p,VLAN_HEADER_TOO_SMALL)) { - goto error; - } - - if(ENGINE_ISSET_EVENT(p,VLAN_UNKNOWN_TYPE)) { - goto error; - } - - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return 1; - -error: - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return 0; -} -#endif /* UNITTESTS */ - -void DecodeVLANRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodeVLANtest01", DecodeVLANtest01, 1); - UtRegisterTest("DecodeVLANtest02", DecodeVLANtest02, 1); - UtRegisterTest("DecodeVLANtest03", DecodeVLANtest03, 1); -#endif /* UNITTESTS */ -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/decode-vlan.h b/framework/src/suricata/src/decode-vlan.h deleted file mode 100644 index baa36472..00000000 --- a/framework/src/suricata/src/decode-vlan.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - */ - -#ifndef __DECODE_VLAN_H__ -#define __DECODE_VLAN_H__ - -/* return vlan id in host byte order */ -uint16_t DecodeVLANGetId(const struct Packet_ *, uint8_t layer); - -/** Vlan type */ -#define ETHERNET_TYPE_VLAN 0x8100 - -/** Vlan macros to access Vlan priority, Vlan CFI and VID */ -#define GET_VLAN_PRIORITY(vlanh) ((ntohs((vlanh)->vlan_cfi) & 0xe000) >> 13) -#define GET_VLAN_CFI(vlanh) ((ntohs((vlanh)->vlan_cfi) & 0x0100) >> 12) -#define GET_VLAN_ID(vlanh) ((uint16_t)(ntohs((vlanh)->vlan_cfi) & 0x0FFF)) -#define GET_VLAN_PROTO(vlanh) ((ntohs((vlanh)->protocol))) - -/* return vlan id in host byte order */ -#define VLAN_GET_ID1(p) DecodeVLANGetId((p), 0) -#define VLAN_GET_ID2(p) DecodeVLANGetId((p), 1) - -/** Vlan header struct */ -typedef struct VLANHdr_ { - uint16_t vlan_cfi; - uint16_t protocol; /**< protocol field */ -} __attribute__((__packed__)) VLANHdr; - -/** VLAN header length */ -#define VLAN_HEADER_LEN 4 - -void DecodeVLANRegisterTests(void); - -#endif /* __DECODE_VLAN_H__ */ - diff --git a/framework/src/suricata/src/decode.c b/framework/src/suricata/src/decode.c deleted file mode 100644 index 4be4b9e7..00000000 --- a/framework/src/suricata/src/decode.c +++ /dev/null @@ -1,573 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \defgroup decode Packet decoding - * - * \brief Code in charge of protocol decoding - * - * The task of decoding packets is made in different files and - * as Suricata is supporting encapsulation there is a potential - * recursivity in the call. - * - * For each protocol a DecodePROTO function is provided. For - * example we have DecodeIPV4() for IPv4 and DecodePPP() for - * PPP. - * - * These functions have all a pkt and and a len argument which - * are respectively a pointer to the protocol data and the length - * of this protocol data. - * - * \attention The pkt parameter must point to the effective data because - * it will be used later to set per protocol pointer like Packet::tcph - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - * - * Decode the raw packet - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "conf.h" -#include "decode.h" -#include "util-debug.h" -#include "util-mem.h" -#include "app-layer-detect-proto.h" -#include "app-layer.h" -#include "tm-threads.h" -#include "util-error.h" -#include "util-print.h" -#include "tmqh-packetpool.h" -#include "util-profiling.h" -#include "pkt-var.h" -#include "util-mpm-ac.h" - -#include "output.h" -#include "output-flow.h" - -int DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, - uint8_t *pkt, uint16_t len, PacketQueue *pq, enum DecodeTunnelProto proto) -{ - switch (proto) { - case DECODE_TUNNEL_PPP: - return DecodePPP(tv, dtv, p, pkt, len, pq); - case DECODE_TUNNEL_IPV4: - return DecodeIPV4(tv, dtv, p, pkt, len, pq); - case DECODE_TUNNEL_IPV6: - return DecodeIPV6(tv, dtv, p, pkt, len, pq); - case DECODE_TUNNEL_VLAN: - return DecodeVLAN(tv, dtv, p, pkt, len, pq); - case DECODE_TUNNEL_ETHERNET: - return DecodeEthernet(tv, dtv, p, pkt, len, pq); - case DECODE_TUNNEL_ERSPAN: - return DecodeERSPAN(tv, dtv, p, pkt, len, pq); - default: - SCLogInfo("FIXME: DecodeTunnel: protocol %" PRIu32 " not supported.", proto); - break; - } - return TM_ECODE_OK; -} - -/** - * \brief Return a malloced packet. - */ -void PacketFree(Packet *p) -{ - PACKET_DESTRUCTOR(p); - SCFree(p); -} - -/** - * \brief Finalize decoding of a packet - * - * This function needs to be call at the end of decode - * functions when decoding has been succesful. - * - */ - -void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p) -{ - - if (p->flags & PKT_IS_INVALID) - StatsIncr(tv, dtv->counter_invalid); - -#ifdef __SC_CUDA_SUPPORT__ - if (dtv->cuda_vars.mpm_is_cuda) - CudaBufferPacket(&dtv->cuda_vars, p); -#endif - -} - -/** - * \brief Get a malloced packet. - * - * \retval p packet, NULL on error - */ -Packet *PacketGetFromAlloc(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) { - return NULL; - } - - memset(p, 0, SIZE_OF_PACKET); - PACKET_INITIALIZE(p); - p->ReleasePacket = PacketFree; - p->flags |= PKT_ALLOC; - - SCLogDebug("allocated a new packet only using alloc..."); - - PACKET_PROFILING_START(p); - return p; -} - -/** - * \brief Return a packet to where it was allocated. - */ -void PacketFreeOrRelease(Packet *p) -{ - if (p->flags & PKT_ALLOC) - PacketFree(p); - else - PacketPoolReturnPacket(p); -} - -/** - * \brief Get a packet. We try to get a packet from the packetpool first, but - * if that is empty we alloc a packet that is free'd again after - * processing. - * - * \retval p packet, NULL on error - */ -Packet *PacketGetFromQueueOrAlloc(void) -{ - /* try the pool first */ - Packet *p = PacketPoolGetPacket(); - - if (p == NULL) { - /* non fatal, we're just not processing a packet then */ - p = PacketGetFromAlloc(); - } else { - PACKET_PROFILING_START(p); - } - - return p; -} - -inline int PacketCallocExtPkt(Packet *p, int datalen) -{ - if (! p->ext_pkt) { - p->ext_pkt = SCCalloc(1, datalen); - if (unlikely(p->ext_pkt == NULL)) { - SET_PKT_LEN(p, 0); - return -1; - } - } - return 0; -} - -/** - * \brief Copy data to Packet payload at given offset - * - * This function copies data/payload to a Packet. It uses the - * space allocated at Packet creation (pointed by Packet::pkt) - * or allocate some memory (pointed by Packet::ext_pkt) if the - * data size is to big to fit in initial space (of size - * default_packet_size). - * - * \param Pointer to the Packet to modify - * \param Offset of the copy relatively to payload of Packet - * \param Pointer to the data to copy - * \param Length of the data to copy - */ -inline int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datalen) -{ - if (unlikely(offset + datalen > MAX_PAYLOAD_SIZE)) { - /* too big */ - return -1; - } - - /* Do we have already an packet with allocated data */ - if (! p->ext_pkt) { - if (offset + datalen <= (int)default_packet_size) { - /* data will fit in memory allocated with packet */ - memcpy(GET_PKT_DIRECT_DATA(p) + offset, data, datalen); - } else { - /* here we need a dynamic allocation */ - p->ext_pkt = SCMalloc(MAX_PAYLOAD_SIZE); - if (unlikely(p->ext_pkt == NULL)) { - SET_PKT_LEN(p, 0); - return -1; - } - /* copy initial data */ - memcpy(p->ext_pkt, GET_PKT_DIRECT_DATA(p), GET_PKT_DIRECT_MAX_SIZE(p)); - /* copy data as asked */ - memcpy(p->ext_pkt + offset, data, datalen); - } - } else { - memcpy(p->ext_pkt + offset, data, datalen); - } - return 0; -} - -/** - * \brief Copy data to Packet payload and set packet length - * - * \param Pointer to the Packet to modify - * \param Pointer to the data to copy - * \param Length of the data to copy - */ -inline int PacketCopyData(Packet *p, uint8_t *pktdata, int pktlen) -{ - SET_PKT_LEN(p, (size_t)pktlen); - return PacketCopyDataOffset(p, 0, pktdata, pktlen); -} - -/** - * \brief Setup a pseudo packet (tunnel) - * - * \param parent parent packet for this pseudo pkt - * \param pkt raw packet data - * \param len packet data length - * \param proto protocol of the tunneled packet - * - * \retval p the pseudo packet or NULL if out of memory - */ -Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *parent, - uint8_t *pkt, uint16_t len, enum DecodeTunnelProto proto, - PacketQueue *pq) -{ - int ret; - - SCEnter(); - - /* get us a packet */ - Packet *p = PacketGetFromQueueOrAlloc(); - if (unlikely(p == NULL)) { - SCReturnPtr(NULL, "Packet"); - } - - /* copy packet and set lenght, proto */ - PacketCopyData(p, pkt, len); - p->recursion_level = parent->recursion_level + 1; - p->ts.tv_sec = parent->ts.tv_sec; - p->ts.tv_usec = parent->ts.tv_usec; - p->datalink = DLT_RAW; - p->tenant_id = parent->tenant_id; - - /* set the root ptr to the lowest layer */ - if (parent->root != NULL) - p->root = parent->root; - else - p->root = parent; - - /* tell new packet it's part of a tunnel */ - SET_TUNNEL_PKT(p); - - ret = DecodeTunnel(tv, dtv, p, GET_PKT_DATA(p), - GET_PKT_LEN(p), pq, proto); - - if (unlikely(ret != TM_ECODE_OK)) { - /* Not a tunnel packet, just a pseudo packet */ - p->root = NULL; - UNSET_TUNNEL_PKT(p); - TmqhOutputPacketpool(tv, p); - SCReturnPtr(NULL, "Packet"); - } - - - /* tell parent packet it's part of a tunnel */ - SET_TUNNEL_PKT(parent); - - /* increment tunnel packet refcnt in the root packet */ - TUNNEL_INCR_PKT_TPR(p); - - /* disable payload (not packet) inspection on the parent, as the payload - * is the packet we will now run through the system separately. We do - * check it against the ip/port/other header checks though */ - DecodeSetNoPayloadInspectionFlag(parent); - SCReturnPtr(p, "Packet"); -} - -/** - * \brief Setup a pseudo packet (reassembled frags) - * - * Difference with PacketPseudoPktSetup is that this func doesn't increment - * the recursion level. It needs to be on the same level as the frags because - * we run the flow engine against this and we need to get the same flow. - * - * \param parent parent packet for this pseudo pkt - * \param pkt raw packet data - * \param len packet data length - * \param proto protocol of the tunneled packet - * - * \retval p the pseudo packet or NULL if out of memory - */ -Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto) -{ - SCEnter(); - - /* get us a packet */ - Packet *p = PacketGetFromQueueOrAlloc(); - if (unlikely(p == NULL)) { - SCReturnPtr(NULL, "Packet"); - } - - /* set the root ptr to the lowest layer */ - if (parent->root != NULL) - p->root = parent->root; - else - p->root = parent; - - /* copy packet and set lenght, proto */ - PacketCopyData(p, pkt, len); - p->recursion_level = parent->recursion_level; /* NOT incremented */ - p->ts.tv_sec = parent->ts.tv_sec; - p->ts.tv_usec = parent->ts.tv_usec; - p->datalink = DLT_RAW; - p->tenant_id = parent->tenant_id; - /* tell new packet it's part of a tunnel */ - SET_TUNNEL_PKT(p); - p->vlan_id[0] = parent->vlan_id[0]; - p->vlan_id[1] = parent->vlan_id[1]; - p->vlan_idx = parent->vlan_idx; - - SCReturnPtr(p, "Packet"); -} - -/** - * \brief inform defrag "parent" that a pseudo packet is - * now assosiated to it. - */ -void PacketDefragPktSetupParent(Packet *parent) -{ - /* tell parent packet it's part of a tunnel */ - SET_TUNNEL_PKT(parent); - - /* increment tunnel packet refcnt in the root packet */ - TUNNEL_INCR_PKT_TPR(parent); - - /* disable payload (not packet) inspection on the parent, as the payload - * is the packet we will now run through the system separately. We do - * check it against the ip/port/other header checks though */ - DecodeSetNoPayloadInspectionFlag(parent); -} - -void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv) -{ - /* register counters */ - dtv->counter_pkts = StatsRegisterCounter("decoder.pkts", tv); - dtv->counter_bytes = StatsRegisterCounter("decoder.bytes", tv); - dtv->counter_invalid = StatsRegisterCounter("decoder.invalid", tv); - dtv->counter_ipv4 = StatsRegisterCounter("decoder.ipv4", tv); - dtv->counter_ipv6 = StatsRegisterCounter("decoder.ipv6", tv); - dtv->counter_eth = StatsRegisterCounter("decoder.ethernet", tv); - dtv->counter_raw = StatsRegisterCounter("decoder.raw", tv); - dtv->counter_null = StatsRegisterCounter("decoder.null", tv); - dtv->counter_sll = StatsRegisterCounter("decoder.sll", tv); - dtv->counter_tcp = StatsRegisterCounter("decoder.tcp", tv); - dtv->counter_udp = StatsRegisterCounter("decoder.udp", tv); - dtv->counter_sctp = StatsRegisterCounter("decoder.sctp", tv); - dtv->counter_icmpv4 = StatsRegisterCounter("decoder.icmpv4", tv); - dtv->counter_icmpv6 = StatsRegisterCounter("decoder.icmpv6", tv); - dtv->counter_ppp = StatsRegisterCounter("decoder.ppp", tv); - dtv->counter_pppoe = StatsRegisterCounter("decoder.pppoe", tv); - dtv->counter_gre = StatsRegisterCounter("decoder.gre", tv); - dtv->counter_vlan = StatsRegisterCounter("decoder.vlan", tv); - dtv->counter_vlan_qinq = StatsRegisterCounter("decoder.vlan_qinq", tv); - dtv->counter_teredo = StatsRegisterCounter("decoder.teredo", tv); - dtv->counter_ipv4inipv6 = StatsRegisterCounter("decoder.ipv4_in_ipv6", tv); - dtv->counter_ipv6inipv6 = StatsRegisterCounter("decoder.ipv6_in_ipv6", tv); - dtv->counter_mpls = StatsRegisterCounter("decoder.mpls", tv); - dtv->counter_avg_pkt_size = StatsRegisterAvgCounter("decoder.avg_pkt_size", tv); - dtv->counter_max_pkt_size = StatsRegisterMaxCounter("decoder.max_pkt_size", tv); - dtv->counter_erspan = StatsRegisterMaxCounter("decoder.erspan", tv); - dtv->counter_flow_memcap = StatsRegisterCounter("flow.memcap", tv); - - dtv->counter_defrag_ipv4_fragments = - StatsRegisterCounter("defrag.ipv4.fragments", tv); - dtv->counter_defrag_ipv4_reassembled = - StatsRegisterCounter("defrag.ipv4.reassembled", tv); - dtv->counter_defrag_ipv4_timeouts = - StatsRegisterCounter("defrag.ipv4.timeouts", tv); - dtv->counter_defrag_ipv6_fragments = - StatsRegisterCounter("defrag.ipv6.fragments", tv); - dtv->counter_defrag_ipv6_reassembled = - StatsRegisterCounter("defrag.ipv6.reassembled", tv); - dtv->counter_defrag_ipv6_timeouts = - StatsRegisterCounter("defrag.ipv6.timeouts", tv); - dtv->counter_defrag_max_hit = - StatsRegisterCounter("defrag.max_frag_hits", tv); - - return; -} - -void DecodeUpdatePacketCounters(ThreadVars *tv, - const DecodeThreadVars *dtv, const Packet *p) -{ - StatsIncr(tv, dtv->counter_pkts); - //StatsIncr(tv, dtv->counter_pkts_per_sec); - StatsAddUI64(tv, dtv->counter_bytes, GET_PKT_LEN(p)); - StatsAddUI64(tv, dtv->counter_avg_pkt_size, GET_PKT_LEN(p)); - StatsSetUI64(tv, dtv->counter_max_pkt_size, GET_PKT_LEN(p)); -} - -/** - * \brief Debug print function for printing addresses - * - * \param Address object - * - * \todo IPv6 - */ -void AddressDebugPrint(Address *a) -{ - if (a == NULL) - return; - - switch (a->family) { - case AF_INET: - { - char s[16]; - PrintInet(AF_INET, (const void *)&a->addr_data32[0], s, sizeof(s)); - SCLogDebug("%s", s); - break; - } - } -} - -/** \brief Alloc and setup DecodeThreadVars */ -DecodeThreadVars *DecodeThreadVarsAlloc(ThreadVars *tv) -{ - DecodeThreadVars *dtv = NULL; - - if ( (dtv = SCMalloc(sizeof(DecodeThreadVars))) == NULL) - return NULL; - memset(dtv, 0, sizeof(DecodeThreadVars)); - - dtv->app_tctx = AppLayerGetCtxThread(tv); - - if (OutputFlowLogThreadInit(tv, NULL, &dtv->output_flow_thread_data) != TM_ECODE_OK) { - SCLogError(SC_ERR_THREAD_INIT, "initializing flow log API for thread failed"); - DecodeThreadVarsFree(tv, dtv); - return NULL; - } - - /** set config defaults */ - int vlanbool = 0; - if ((ConfGetBool("vlan.use-for-tracking", &vlanbool)) == 1 && vlanbool == 0) { - dtv->vlan_disabled = 1; - } - SCLogDebug("vlan tracking is %s", dtv->vlan_disabled == 0 ? "enabled" : "disabled"); - - return dtv; -} - -void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv) -{ - if (dtv != NULL) { - if (dtv->app_tctx != NULL) - AppLayerDestroyCtxThread(dtv->app_tctx); - - if (dtv->output_flow_thread_data != NULL) - OutputFlowLogThreadDeinit(tv, dtv->output_flow_thread_data); - - SCFree(dtv); - } -} - -/** - * \brief Set data for Packet and set length when zeo copy is used - * - * \param Pointer to the Packet to modify - * \param Pointer to the data - * \param Length of the data - */ -inline int PacketSetData(Packet *p, uint8_t *pktdata, int pktlen) -{ - SET_PKT_LEN(p, (size_t)pktlen); - if (unlikely(!pktdata)) { - return -1; - } - p->ext_pkt = pktdata; - p->flags |= PKT_ZERO_COPY; - - return 0; -} - -const char *PktSrcToString(enum PktSrcEnum pkt_src) -{ - char *pkt_src_str = ""; - switch (pkt_src) { - case PKT_SRC_WIRE: - pkt_src_str = "wire/pcap"; - break; - case PKT_SRC_DECODER_GRE: - pkt_src_str = "gre tunnel"; - break; - case PKT_SRC_DECODER_IPV4: - pkt_src_str = "ipv4 tunnel"; - break; - case PKT_SRC_DECODER_IPV6: - pkt_src_str = "ipv6 tunnel"; - break; - case PKT_SRC_DECODER_TEREDO: - pkt_src_str = "teredo tunnel"; - break; - case PKT_SRC_DEFRAG: - pkt_src_str = "defrag"; - break; - case PKT_SRC_STREAM_TCP_STREAM_END_PSEUDO: - pkt_src_str = "stream"; - break; - case PKT_SRC_FFR: - pkt_src_str = "stream (flow timeout)"; - break; - } - return pkt_src_str; -} - -void CaptureStatsUpdate(ThreadVars *tv, CaptureStats *s, const Packet *p) -{ - if (unlikely(PACKET_TEST_ACTION(p, (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)))) { - StatsIncr(tv, s->counter_ips_rejected); - } else if (unlikely(PACKET_TEST_ACTION(p, ACTION_DROP))) { - StatsIncr(tv, s->counter_ips_blocked); - } else if (unlikely(p->flags & PKT_STREAM_MODIFIED)) { - StatsIncr(tv, s->counter_ips_replaced); - } else { - StatsIncr(tv, s->counter_ips_accepted); - } -} - -void CaptureStatsSetup(ThreadVars *tv, CaptureStats *s) -{ - s->counter_ips_accepted = StatsRegisterCounter("ips.accepted", tv); - s->counter_ips_blocked = StatsRegisterCounter("ips.blocked", tv); - s->counter_ips_rejected = StatsRegisterCounter("ips.rejected", tv); - s->counter_ips_replaced = StatsRegisterCounter("ips.replaced", tv); -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/decode.h b/framework/src/suricata/src/decode.h deleted file mode 100644 index f57dcea9..00000000 --- a/framework/src/suricata/src/decode.h +++ /dev/null @@ -1,1050 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DECODE_H__ -#define __DECODE_H__ - -//#define DBG_THREADS -#define COUNTERS - -#include "suricata-common.h" -#include "threadvars.h" -#include "decode-events.h" - -#ifdef __SC_CUDA_SUPPORT__ -#include "util-cuda-buffer.h" -#include "util-cuda-vars.h" -#endif /* __SC_CUDA_SUPPORT__ */ - -typedef enum { - CHECKSUM_VALIDATION_DISABLE, - CHECKSUM_VALIDATION_ENABLE, - CHECKSUM_VALIDATION_AUTO, - CHECKSUM_VALIDATION_RXONLY, - CHECKSUM_VALIDATION_KERNEL, -} ChecksumValidationMode; - -enum PktSrcEnum { - PKT_SRC_WIRE = 1, - PKT_SRC_DECODER_GRE, - PKT_SRC_DECODER_IPV4, - PKT_SRC_DECODER_IPV6, - PKT_SRC_DECODER_TEREDO, - PKT_SRC_DEFRAG, - PKT_SRC_STREAM_TCP_STREAM_END_PSEUDO, - PKT_SRC_FFR, -}; - -#include "source-nflog.h" -#include "source-nfq.h" -#include "source-ipfw.h" -#include "source-pcap.h" -#include "source-af-packet.h" -#include "source-mpipe.h" -#include "source-netmap.h" - -#include "action-globals.h" - -#include "decode-erspan.h" -#include "decode-ethernet.h" -#include "decode-gre.h" -#include "decode-ppp.h" -#include "decode-pppoe.h" -#include "decode-sll.h" -#include "decode-ipv4.h" -#include "decode-ipv6.h" -#include "decode-icmpv4.h" -#include "decode-icmpv6.h" -#include "decode-tcp.h" -#include "decode-udp.h" -#include "decode-sctp.h" -#include "decode-raw.h" -#include "decode-null.h" -#include "decode-vlan.h" -#include "decode-mpls.h" - -#include "detect-reference.h" - -#include "app-layer-protos.h" - -/* forward declarations */ -struct DetectionEngineThreadCtx_; -typedef struct AppLayerThreadCtx_ AppLayerThreadCtx; - -struct PktPool_; - -/* declare these here as they are called from the - * PACKET_RECYCLE and PACKET_CLEANUP macro's. */ -typedef struct AppLayerDecoderEvents_ AppLayerDecoderEvents; -void AppLayerDecoderEventsResetEvents(AppLayerDecoderEvents *events); -void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events); - -/* Address */ -typedef struct Address_ { - char family; - union { - uint32_t address_un_data32[4]; /* type-specific field */ - uint16_t address_un_data16[8]; /* type-specific field */ - uint8_t address_un_data8[16]; /* type-specific field */ - } address; -} Address; - -#define addr_data32 address.address_un_data32 -#define addr_data16 address.address_un_data16 -#define addr_data8 address.address_un_data8 - -#define COPY_ADDRESS(a, b) do { \ - (b)->family = (a)->family; \ - (b)->addr_data32[0] = (a)->addr_data32[0]; \ - (b)->addr_data32[1] = (a)->addr_data32[1]; \ - (b)->addr_data32[2] = (a)->addr_data32[2]; \ - (b)->addr_data32[3] = (a)->addr_data32[3]; \ - } while (0) - -/* Set the IPv4 addresses into the Addrs of the Packet. - * Make sure p->ip4h is initialized and validated. - * - * We set the rest of the struct to 0 so we can - * prevent using memset. */ -#define SET_IPV4_SRC_ADDR(p, a) do { \ - (a)->family = AF_INET; \ - (a)->addr_data32[0] = (uint32_t)(p)->ip4h->s_ip_src.s_addr; \ - (a)->addr_data32[1] = 0; \ - (a)->addr_data32[2] = 0; \ - (a)->addr_data32[3] = 0; \ - } while (0) - -#define SET_IPV4_DST_ADDR(p, a) do { \ - (a)->family = AF_INET; \ - (a)->addr_data32[0] = (uint32_t)(p)->ip4h->s_ip_dst.s_addr; \ - (a)->addr_data32[1] = 0; \ - (a)->addr_data32[2] = 0; \ - (a)->addr_data32[3] = 0; \ - } while (0) - -/* clear the address structure by setting all fields to 0 */ -#define CLEAR_ADDR(a) do { \ - (a)->family = 0; \ - (a)->addr_data32[0] = 0; \ - (a)->addr_data32[1] = 0; \ - (a)->addr_data32[2] = 0; \ - (a)->addr_data32[3] = 0; \ - } while (0) - -/* Set the IPv6 addressesinto the Addrs of the Packet. - * Make sure p->ip6h is initialized and validated. */ -#define SET_IPV6_SRC_ADDR(p, a) do { \ - (a)->family = AF_INET6; \ - (a)->addr_data32[0] = (p)->ip6h->s_ip6_src[0]; \ - (a)->addr_data32[1] = (p)->ip6h->s_ip6_src[1]; \ - (a)->addr_data32[2] = (p)->ip6h->s_ip6_src[2]; \ - (a)->addr_data32[3] = (p)->ip6h->s_ip6_src[3]; \ - } while (0) - -#define SET_IPV6_DST_ADDR(p, a) do { \ - (a)->family = AF_INET6; \ - (a)->addr_data32[0] = (p)->ip6h->s_ip6_dst[0]; \ - (a)->addr_data32[1] = (p)->ip6h->s_ip6_dst[1]; \ - (a)->addr_data32[2] = (p)->ip6h->s_ip6_dst[2]; \ - (a)->addr_data32[3] = (p)->ip6h->s_ip6_dst[3]; \ - } while (0) - -/* Set the TCP ports into the Ports of the Packet. - * Make sure p->tcph is initialized and validated. */ -#define SET_TCP_SRC_PORT(pkt, prt) do { \ - SET_PORT(TCP_GET_SRC_PORT((pkt)), *(prt)); \ - } while (0) - -#define SET_TCP_DST_PORT(pkt, prt) do { \ - SET_PORT(TCP_GET_DST_PORT((pkt)), *(prt)); \ - } while (0) - -/* Set the UDP ports into the Ports of the Packet. - * Make sure p->udph is initialized and validated. */ -#define SET_UDP_SRC_PORT(pkt, prt) do { \ - SET_PORT(UDP_GET_SRC_PORT((pkt)), *(prt)); \ - } while (0) -#define SET_UDP_DST_PORT(pkt, prt) do { \ - SET_PORT(UDP_GET_DST_PORT((pkt)), *(prt)); \ - } while (0) - -/* Set the SCTP ports into the Ports of the Packet. - * Make sure p->sctph is initialized and validated. */ -#define SET_SCTP_SRC_PORT(pkt, prt) do { \ - SET_PORT(SCTP_GET_SRC_PORT((pkt)), *(prt)); \ - } while (0) - -#define SET_SCTP_DST_PORT(pkt, prt) do { \ - SET_PORT(SCTP_GET_DST_PORT((pkt)), *(prt)); \ - } while (0) - - - -#define GET_IPV4_SRC_ADDR_U32(p) ((p)->src.addr_data32[0]) -#define GET_IPV4_DST_ADDR_U32(p) ((p)->dst.addr_data32[0]) -#define GET_IPV4_SRC_ADDR_PTR(p) ((p)->src.addr_data32) -#define GET_IPV4_DST_ADDR_PTR(p) ((p)->dst.addr_data32) - -#define GET_IPV6_SRC_ADDR(p) ((p)->src.addr_data32) -#define GET_IPV6_DST_ADDR(p) ((p)->dst.addr_data32) -#define GET_TCP_SRC_PORT(p) ((p)->sp) -#define GET_TCP_DST_PORT(p) ((p)->dp) - -#define GET_PKT_LEN(p) ((p)->pktlen) -#define GET_PKT_DATA(p) ((((p)->ext_pkt) == NULL ) ? (uint8_t *)((p) + 1) : (p)->ext_pkt) -#define GET_PKT_DIRECT_DATA(p) (uint8_t *)((p) + 1) -#define GET_PKT_DIRECT_MAX_SIZE(p) (default_packet_size) - -#define SET_PKT_LEN(p, len) do { \ - (p)->pktlen = (len); \ - } while (0) - - -/* Port is just a uint16_t */ -typedef uint16_t Port; -#define SET_PORT(v, p) ((p) = (v)) -#define COPY_PORT(a,b) ((b) = (a)) - -#define CMP_ADDR(a1, a2) \ - (((a1)->addr_data32[3] == (a2)->addr_data32[3] && \ - (a1)->addr_data32[2] == (a2)->addr_data32[2] && \ - (a1)->addr_data32[1] == (a2)->addr_data32[1] && \ - (a1)->addr_data32[0] == (a2)->addr_data32[0])) -#define CMP_PORT(p1, p2) \ - ((p1) == (p2)) - -/*Given a packet pkt offset to the start of the ip header in a packet - *We determine the ip version. */ -#define IP_GET_RAW_VER(pkt) ((((pkt)[0] & 0xf0) >> 4)) - -#define PKT_IS_IPV4(p) (((p)->ip4h != NULL)) -#define PKT_IS_IPV6(p) (((p)->ip6h != NULL)) -#define PKT_IS_TCP(p) (((p)->tcph != NULL)) -#define PKT_IS_UDP(p) (((p)->udph != NULL)) -#define PKT_IS_ICMPV4(p) (((p)->icmpv4h != NULL)) -#define PKT_IS_ICMPV6(p) (((p)->icmpv6h != NULL)) -#define PKT_IS_TOSERVER(p) (((p)->flowflags & FLOW_PKT_TOSERVER)) -#define PKT_IS_TOCLIENT(p) (((p)->flowflags & FLOW_PKT_TOCLIENT)) - -#define IPH_IS_VALID(p) (PKT_IS_IPV4((p)) || PKT_IS_IPV6((p))) - -/* Retrieve proto regardless of IP version */ -#define IP_GET_IPPROTO(p) \ - (p->proto ? p->proto : \ - (PKT_IS_IPV4((p))? IPV4_GET_IPPROTO((p)) : (PKT_IS_IPV6((p))? IPV6_GET_L4PROTO((p)) : 0))) - -/* structure to store the sids/gids/etc the detection engine - * found in this packet */ -typedef struct PacketAlert_ { - SigIntId num; /* Internal num, used for sorting */ - uint8_t action; /* Internal num, used for sorting */ - uint8_t flags; - struct Signature_ *s; - uint64_t tx_id; -} PacketAlert; - -/** After processing an alert by the thresholding module, if at - * last it gets triggered, we might want to stick the drop action to - * the flow on IPS mode */ -#define PACKET_ALERT_FLAG_DROP_FLOW 0x01 -/** alert was generated based on state */ -#define PACKET_ALERT_FLAG_STATE_MATCH 0x02 -/** alert was generated based on stream */ -#define PACKET_ALERT_FLAG_STREAM_MATCH 0x04 -/** alert is in a tx, tx_id set */ -#define PACKET_ALERT_FLAG_TX 0x08 - -#define PACKET_ALERT_MAX 15 - -typedef struct PacketAlerts_ { - uint16_t cnt; - PacketAlert alerts[PACKET_ALERT_MAX]; - /* single pa used when we're dropping, - * so we can log it out in the drop log. */ - PacketAlert drop; -} PacketAlerts; - -/** number of decoder events we support per packet. Power of 2 minus 1 - * for memory layout */ -#define PACKET_ENGINE_EVENT_MAX 15 - -/** data structure to store decoder, defrag and stream events */ -typedef struct PacketEngineEvents_ { - uint8_t cnt; /**< number of events */ - uint8_t events[PACKET_ENGINE_EVENT_MAX]; /**< array of events */ -} PacketEngineEvents; - -typedef struct PktVar_ { - char *name; - struct PktVar_ *next; /* right now just implement this as a list, - * in the long run we have thing of something - * faster. */ - uint8_t *value; - uint16_t value_len; -} PktVar; - -#ifdef PROFILING - -/** \brief Per TMM stats storage */ -typedef struct PktProfilingTmmData_ { - uint64_t ticks_start; - uint64_t ticks_end; -#ifdef PROFILE_LOCKING - uint64_t mutex_lock_cnt; - uint64_t mutex_lock_wait_ticks; - uint64_t mutex_lock_contention; - uint64_t spin_lock_cnt; - uint64_t spin_lock_wait_ticks; - uint64_t spin_lock_contention; - uint64_t rww_lock_cnt; - uint64_t rww_lock_wait_ticks; - uint64_t rww_lock_contention; - uint64_t rwr_lock_cnt; - uint64_t rwr_lock_wait_ticks; - uint64_t rwr_lock_contention; -#endif -} PktProfilingTmmData; - -typedef struct PktProfilingDetectData_ { - uint64_t ticks_start; - uint64_t ticks_end; - uint64_t ticks_spent; -} PktProfilingDetectData; - -typedef struct PktProfilingAppData_ { - uint64_t ticks_spent; -} PktProfilingAppData; - -/** \brief Per pkt stats storage */ -typedef struct PktProfiling_ { - uint64_t ticks_start; - uint64_t ticks_end; - - PktProfilingTmmData tmm[TMM_SIZE]; - PktProfilingAppData app[ALPROTO_MAX]; - PktProfilingDetectData detect[PROF_DETECT_SIZE]; - uint64_t proto_detect; -} PktProfiling; - -#endif /* PROFILING */ - -/* forward declartion since Packet struct definition requires this */ -struct PacketQueue_; - -/* sizes of the members: - * src: 17 bytes - * dst: 17 bytes - * sp/type: 1 byte - * dp/code: 1 byte - * proto: 1 byte - * recurs: 1 byte - * - * sum of above: 38 bytes - * - * flow ptr: 4/8 bytes - * flags: 1 byte - * flowflags: 1 byte - * - * sum of above 44/48 bytes - */ -typedef struct Packet_ -{ - /* Addresses, Ports and protocol - * these are on top so we can use - * the Packet as a hash key */ - Address src; - Address dst; - union { - Port sp; - uint8_t type; - }; - union { - Port dp; - uint8_t code; - }; - uint8_t proto; - /* make sure we can't be attacked on when the tunneled packet - * has the exact same tuple as the lower levels */ - uint8_t recursion_level; - - uint16_t vlan_id[2]; - uint8_t vlan_idx; - - /* flow */ - uint8_t flowflags; - /* coccinelle: Packet:flowflags:FLOW_PKT_ */ - - /* Pkt Flags */ - uint32_t flags; - - struct Flow_ *flow; - - struct timeval ts; - - union { - /* nfq stuff */ -#ifdef HAVE_NFLOG - NFLOGPacketVars nflog_v; -#endif /* HAVE_NFLOG */ -#ifdef NFQ - NFQPacketVars nfq_v; -#endif /* NFQ */ -#ifdef IPFW - IPFWPacketVars ipfw_v; -#endif /* IPFW */ -#ifdef AF_PACKET - AFPPacketVars afp_v; -#endif -#ifdef HAVE_MPIPE - /* tilegx mpipe stuff */ - MpipePacketVars mpipe_v; -#endif -#ifdef HAVE_NETMAP - NetmapPacketVars netmap_v; -#endif - - /** libpcap vars: shared by Pcap Live mode and Pcap File mode */ - PcapPacketVars pcap_v; - }; - - /** The release function for packet structure and data */ - void (*ReleasePacket)(struct Packet_ *); - - /* pkt vars */ - PktVar *pktvar; - - /* header pointers */ - EthernetHdr *ethh; - - /* Checksum for IP packets. */ - int32_t level3_comp_csum; - /* Check sum for TCP, UDP or ICMP packets */ - int32_t level4_comp_csum; - - IPV4Hdr *ip4h; - - IPV6Hdr *ip6h; - - /* IPv4 and IPv6 are mutually exclusive */ - union { - IPV4Vars ip4vars; - struct { - IPV6Vars ip6vars; - IPV6ExtHdrs ip6eh; - }; - }; - /* Can only be one of TCP, UDP, ICMP at any given time */ - union { - TCPVars tcpvars; - UDPVars udpvars; - ICMPV4Vars icmpv4vars; - ICMPV6Vars icmpv6vars; - }; - - TCPHdr *tcph; - - UDPHdr *udph; - - SCTPHdr *sctph; - - ICMPV4Hdr *icmpv4h; - - ICMPV6Hdr *icmpv6h; - - PPPHdr *ppph; - PPPOESessionHdr *pppoesh; - PPPOEDiscoveryHdr *pppoedh; - - GREHdr *greh; - - VLANHdr *vlanh[2]; - - /* ptr to the payload of the packet - * with it's length. */ - uint8_t *payload; - uint16_t payload_len; - - /* IPS action to take */ - uint8_t action; - - uint8_t pkt_src; - - /* storage: set to pointer to heap and extended via allocation if necessary */ - uint32_t pktlen; - uint8_t *ext_pkt; - - /* Incoming interface */ - struct LiveDevice_ *livedev; - - PacketAlerts alerts; - - struct Host_ *host_src; - struct Host_ *host_dst; - - /** packet number in the pcap file, matches wireshark */ - uint64_t pcap_cnt; - - - /* engine events */ - PacketEngineEvents events; - - AppLayerDecoderEvents *app_layer_events; - - /* double linked list ptrs */ - struct Packet_ *next; - struct Packet_ *prev; - - /** data linktype in host order */ - int datalink; - - /* used to hold flowbits only if debuglog is enabled */ - int debuglog_flowbits_names_len; - const char **debuglog_flowbits_names; - - /* tunnel/encapsulation handling */ - struct Packet_ *root; /* in case of tunnel this is a ptr - * to the 'real' packet, the one we - * need to set the verdict on -- - * It should always point to the lowest - * packet in a encapsulated packet */ - - /** mutex to protect access to: - * - tunnel_rtv_cnt - * - tunnel_tpr_cnt - */ - SCMutex tunnel_mutex; - /* ready to set verdict counter, only set in root */ - uint16_t tunnel_rtv_cnt; - /* tunnel packet ref count */ - uint16_t tunnel_tpr_cnt; - - /** tenant id for this packet, if any. If 0 then no tenant was assigned. */ - uint32_t tenant_id; - - /* The Packet pool from which this packet was allocated. Used when returning - * the packet to its owner's stack. If NULL, then allocated with malloc. - */ - struct PktPool_ *pool; - -#ifdef PROFILING - PktProfiling *profile; -#endif -#ifdef __SC_CUDA_SUPPORT__ - CudaPacketVars cuda_pkt_vars; -#endif -} -#ifdef HAVE_MPIPE - /* mPIPE requires packet buffers to be aligned to 128 byte boundaries. */ - __attribute__((aligned(128))) -#endif -Packet; - -#define DEFAULT_PACKET_SIZE (1500 + ETHERNET_HEADER_LEN) -/* storage: maximum ip packet size + link header */ -#define MAX_PAYLOAD_SIZE (IPV6_HEADER_LEN + 65536 + 28) -uint32_t default_packet_size; -#define SIZE_OF_PACKET (default_packet_size + sizeof(Packet)) - -typedef struct PacketQueue_ { - Packet *top; - Packet *bot; - uint32_t len; -#ifdef DBG_PERF - uint32_t dbg_maxlen; -#endif /* DBG_PERF */ - SCMutex mutex_q; - SCCondT cond_q; -} PacketQueue; - -/** \brief Structure to hold thread specific data for all decode modules */ -typedef struct DecodeThreadVars_ -{ - /** Specific context for udp protocol detection (here atm) */ - AppLayerThreadCtx *app_tctx; - - int vlan_disabled; - - /** stats/counters */ - uint16_t counter_pkts; - uint16_t counter_bytes; - uint16_t counter_avg_pkt_size; - uint16_t counter_max_pkt_size; - - uint16_t counter_invalid; - - uint16_t counter_eth; - uint16_t counter_ipv4; - uint16_t counter_ipv6; - uint16_t counter_tcp; - uint16_t counter_udp; - uint16_t counter_icmpv4; - uint16_t counter_icmpv6; - - uint16_t counter_sll; - uint16_t counter_raw; - uint16_t counter_null; - uint16_t counter_sctp; - uint16_t counter_ppp; - uint16_t counter_gre; - uint16_t counter_vlan; - uint16_t counter_vlan_qinq; - uint16_t counter_pppoe; - uint16_t counter_teredo; - uint16_t counter_mpls; - uint16_t counter_ipv4inipv6; - uint16_t counter_ipv6inipv6; - uint16_t counter_erspan; - - /** frag stats - defrag runs in the context of the decoder. */ - uint16_t counter_defrag_ipv4_fragments; - uint16_t counter_defrag_ipv4_reassembled; - uint16_t counter_defrag_ipv4_timeouts; - uint16_t counter_defrag_ipv6_fragments; - uint16_t counter_defrag_ipv6_reassembled; - uint16_t counter_defrag_ipv6_timeouts; - uint16_t counter_defrag_max_hit; - - uint16_t counter_flow_memcap; - - /* thread data for flow logging api: only used at forced - * flow recycle during lookups */ - void *output_flow_thread_data; - -#ifdef __SC_CUDA_SUPPORT__ - CudaThreadVars cuda_vars; -#endif -} DecodeThreadVars; - -typedef struct CaptureStats_ { - - uint16_t counter_ips_accepted; - uint16_t counter_ips_blocked; - uint16_t counter_ips_rejected; - uint16_t counter_ips_replaced; - -} CaptureStats; - -void CaptureStatsUpdate(ThreadVars *tv, CaptureStats *s, const Packet *p); -void CaptureStatsSetup(ThreadVars *tv, CaptureStats *s); - -/** - * \brief reset these to -1(indicates that the packet is fresh from the queue) - */ -#define PACKET_RESET_CHECKSUMS(p) do { \ - (p)->level3_comp_csum = -1; \ - (p)->level4_comp_csum = -1; \ - } while (0) - -/* if p uses extended data, free them */ -#define PACKET_FREE_EXTDATA(p) do { \ - if ((p)->ext_pkt) { \ - if (!((p)->flags & PKT_ZERO_COPY)) { \ - SCFree((p)->ext_pkt); \ - } \ - (p)->ext_pkt = NULL; \ - } \ - } while(0) - -/** - * \brief Initialize a packet structure for use. - */ -#ifdef __SC_CUDA_SUPPORT__ -#include "util-cuda-handlers.h" -#include "util-mpm.h" - -#define PACKET_INITIALIZE(p) do { \ - memset((p), 0x00, SIZE_OF_PACKET); \ - SCMutexInit(&(p)->tunnel_mutex, NULL); \ - PACKET_RESET_CHECKSUMS((p)); \ - (p)->livedev = NULL; \ - SCMutexInit(&(p)->cuda_pkt_vars.cuda_mutex, NULL); \ - SCCondInit(&(p)->cuda_pkt_vars.cuda_cond, NULL); \ - } while (0) -#else -#define PACKET_INITIALIZE(p) { \ - SCMutexInit(&(p)->tunnel_mutex, NULL); \ - PACKET_RESET_CHECKSUMS((p)); \ - (p)->livedev = NULL; \ -} -#endif - -#define PACKET_RELEASE_REFS(p) do { \ - FlowDeReference(&((p)->flow)); \ - HostDeReference(&((p)->host_src)); \ - HostDeReference(&((p)->host_dst)); \ - } while (0) - -/** - * \brief Recycle a packet structure for reuse. - */ -#define PACKET_REINIT(p) do { \ - CLEAR_ADDR(&(p)->src); \ - CLEAR_ADDR(&(p)->dst); \ - (p)->sp = 0; \ - (p)->dp = 0; \ - (p)->proto = 0; \ - (p)->recursion_level = 0; \ - PACKET_FREE_EXTDATA((p)); \ - (p)->flags = (p)->flags & PKT_ALLOC; \ - (p)->flowflags = 0; \ - (p)->pkt_src = 0; \ - (p)->vlan_id[0] = 0; \ - (p)->vlan_id[1] = 0; \ - (p)->vlan_idx = 0; \ - (p)->ts.tv_sec = 0; \ - (p)->ts.tv_usec = 0; \ - (p)->datalink = 0; \ - (p)->action = 0; \ - if ((p)->pktvar != NULL) { \ - PktVarFree((p)->pktvar); \ - (p)->pktvar = NULL; \ - } \ - (p)->ethh = NULL; \ - if ((p)->ip4h != NULL) { \ - CLEAR_IPV4_PACKET((p)); \ - } \ - if ((p)->ip6h != NULL) { \ - CLEAR_IPV6_PACKET((p)); \ - } \ - if ((p)->tcph != NULL) { \ - CLEAR_TCP_PACKET((p)); \ - } \ - if ((p)->udph != NULL) { \ - CLEAR_UDP_PACKET((p)); \ - } \ - if ((p)->sctph != NULL) { \ - CLEAR_SCTP_PACKET((p)); \ - } \ - if ((p)->icmpv4h != NULL) { \ - CLEAR_ICMPV4_PACKET((p)); \ - } \ - if ((p)->icmpv6h != NULL) { \ - CLEAR_ICMPV6_PACKET((p)); \ - } \ - (p)->ppph = NULL; \ - (p)->pppoesh = NULL; \ - (p)->pppoedh = NULL; \ - (p)->greh = NULL; \ - (p)->vlanh[0] = NULL; \ - (p)->vlanh[1] = NULL; \ - (p)->payload = NULL; \ - (p)->payload_len = 0; \ - (p)->pktlen = 0; \ - (p)->alerts.cnt = 0; \ - (p)->alerts.drop.action = 0; \ - (p)->pcap_cnt = 0; \ - (p)->tunnel_rtv_cnt = 0; \ - (p)->tunnel_tpr_cnt = 0; \ - (p)->events.cnt = 0; \ - AppLayerDecoderEventsResetEvents((p)->app_layer_events); \ - (p)->next = NULL; \ - (p)->prev = NULL; \ - (p)->root = NULL; \ - (p)->livedev = NULL; \ - PACKET_RESET_CHECKSUMS((p)); \ - PACKET_PROFILING_RESET((p)); \ - p->tenant_id = 0; \ - } while (0) - -#define PACKET_RECYCLE(p) do { \ - PACKET_RELEASE_REFS((p)); \ - PACKET_REINIT((p)); \ - } while (0) - -/** - * \brief Cleanup a packet so that we can free it. No memset needed.. - */ -#define PACKET_DESTRUCTOR(p) do { \ - if ((p)->pktvar != NULL) { \ - PktVarFree((p)->pktvar); \ - } \ - PACKET_FREE_EXTDATA((p)); \ - SCMutexDestroy(&(p)->tunnel_mutex); \ - AppLayerDecoderEventsFreeEvents(&(p)->app_layer_events); \ - PACKET_PROFILING_RESET((p)); \ - } while (0) - - -/* macro's for setting the action - * handle the case of a root packet - * for tunnels */ - -#define PACKET_SET_ACTION(p, a) do { \ - ((p)->root ? \ - ((p)->root->action = a) : \ - ((p)->action = a)); \ -} while (0) - -#define PACKET_ALERT(p) PACKET_SET_ACTION(p, ACTION_ALERT) - -#define PACKET_ACCEPT(p) PACKET_SET_ACTION(p, ACTION_ACCEPT) - -#define PACKET_DROP(p) PACKET_SET_ACTION(p, ACTION_DROP) - -#define PACKET_REJECT(p) PACKET_SET_ACTION(p, (ACTION_REJECT|ACTION_DROP)) - -#define PACKET_REJECT_DST(p) PACKET_SET_ACTION(p, (ACTION_REJECT_DST|ACTION_DROP)) - -#define PACKET_REJECT_BOTH(p) PACKET_SET_ACTION(p, (ACTION_REJECT_BOTH|ACTION_DROP)) - -#define PACKET_PASS(p) PACKET_SET_ACTION(p, ACTION_PASS) - -#define PACKET_TEST_ACTION(p, a) \ - ((p)->root ? \ - ((p)->root->action & a) : \ - ((p)->action & a)) - -#define PACKET_UPDATE_ACTION(p, a) do { \ - ((p)->root ? \ - ((p)->root->action |= a) : \ - ((p)->action |= a)); \ -} while (0) - -#define TUNNEL_INCR_PKT_RTV(p) do { \ - SCMutexLock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex); \ - ((p)->root ? (p)->root->tunnel_rtv_cnt++ : (p)->tunnel_rtv_cnt++); \ - SCMutexUnlock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex); \ - } while (0) - -#define TUNNEL_INCR_PKT_TPR(p) do { \ - SCMutexLock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex); \ - ((p)->root ? (p)->root->tunnel_tpr_cnt++ : (p)->tunnel_tpr_cnt++); \ - SCMutexUnlock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex); \ - } while (0) - -#define TUNNEL_DECR_PKT_TPR(p) do { \ - SCMutexLock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex); \ - ((p)->root ? (p)->root->tunnel_tpr_cnt-- : (p)->tunnel_tpr_cnt--); \ - SCMutexUnlock((p)->root ? &(p)->root->tunnel_mutex : &(p)->tunnel_mutex); \ - } while (0) - -#define TUNNEL_DECR_PKT_TPR_NOLOCK(p) do { \ - ((p)->root ? (p)->root->tunnel_tpr_cnt-- : (p)->tunnel_tpr_cnt--); \ - } while (0) - -#define TUNNEL_PKT_RTV(p) ((p)->root ? (p)->root->tunnel_rtv_cnt : (p)->tunnel_rtv_cnt) -#define TUNNEL_PKT_TPR(p) ((p)->root ? (p)->root->tunnel_tpr_cnt : (p)->tunnel_tpr_cnt) - -#define IS_TUNNEL_PKT(p) (((p)->flags & PKT_TUNNEL)) -#define SET_TUNNEL_PKT(p) ((p)->flags |= PKT_TUNNEL) -#define UNSET_TUNNEL_PKT(p) ((p)->flags &= ~PKT_TUNNEL) -#define IS_TUNNEL_ROOT_PKT(p) (IS_TUNNEL_PKT(p) && (p)->root == NULL) - -#define IS_TUNNEL_PKT_VERDICTED(p) (((p)->flags & PKT_TUNNEL_VERDICTED)) -#define SET_TUNNEL_PKT_VERDICTED(p) ((p)->flags |= PKT_TUNNEL_VERDICTED) - -enum DecodeTunnelProto { - DECODE_TUNNEL_ETHERNET, - DECODE_TUNNEL_ERSPAN, - DECODE_TUNNEL_VLAN, - DECODE_TUNNEL_IPV4, - DECODE_TUNNEL_IPV6, - DECODE_TUNNEL_PPP, -}; - -Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *parent, - uint8_t *pkt, uint16_t len, enum DecodeTunnelProto proto, PacketQueue *pq); -Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto); -void PacketDefragPktSetupParent(Packet *parent); -void DecodeRegisterPerfCounters(DecodeThreadVars *, ThreadVars *); -Packet *PacketGetFromQueueOrAlloc(void); -Packet *PacketGetFromAlloc(void); -void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p); -void PacketFree(Packet *p); -void PacketFreeOrRelease(Packet *p); -int PacketCallocExtPkt(Packet *p, int datalen); -int PacketCopyData(Packet *p, uint8_t *pktdata, int pktlen); -int PacketSetData(Packet *p, uint8_t *pktdata, int pktlen); -int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datalen); -const char *PktSrcToString(enum PktSrcEnum pkt_src); - -DecodeThreadVars *DecodeThreadVarsAlloc(ThreadVars *); -void DecodeThreadVarsFree(ThreadVars *, DecodeThreadVars *); -void DecodeUpdatePacketCounters(ThreadVars *tv, - const DecodeThreadVars *dtv, const Packet *p); - -/* decoder functions */ -int DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeSll(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodePPP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodePPPOESession(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodePPPOEDiscovery(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeTunnel(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *, enum DecodeTunnelProto) __attribute__ ((warn_unused_result)); -int DecodeNull(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeRaw(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeIPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeIPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeICMPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeICMPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeTCP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeUDP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeSCTP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeMPLS(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); -int DecodeERSPAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); - -void AddressDebugPrint(Address *); - -/** \brief Set the No payload inspection Flag for the packet. - * - * \param p Packet to set the flag in - */ -#define DecodeSetNoPayloadInspectionFlag(p) do { \ - (p)->flags |= PKT_NOPAYLOAD_INSPECTION; \ - } while (0) - -#define DecodeUnsetNoPayloadInspectionFlag(p) do { \ - (p)->flags &= ~PKT_NOPAYLOAD_INSPECTION; \ - } while (0) - -/** \brief Set the No packet inspection Flag for the packet. - * - * \param p Packet to set the flag in - */ -#define DecodeSetNoPacketInspectionFlag(p) do { \ - (p)->flags |= PKT_NOPACKET_INSPECTION; \ - } while (0) -#define DecodeUnsetNoPacketInspectionFlag(p) do { \ - (p)->flags &= ~PKT_NOPACKET_INSPECTION; \ - } while (0) - - -#define ENGINE_SET_EVENT(p, e) do { \ - SCLogDebug("p %p event %d", (p), e); \ - if ((p)->events.cnt < PACKET_ENGINE_EVENT_MAX) { \ - (p)->events.events[(p)->events.cnt] = e; \ - (p)->events.cnt++; \ - } \ -} while(0) - -#define ENGINE_SET_INVALID_EVENT(p, e) do { \ - p->flags |= PKT_IS_INVALID; \ - ENGINE_SET_EVENT(p, e); \ -} while(0) - - - -#define ENGINE_ISSET_EVENT(p, e) ({ \ - int r = 0; \ - uint8_t u; \ - for (u = 0; u < (p)->events.cnt; u++) { \ - if ((p)->events.events[u] == (e)) { \ - r = 1; \ - break; \ - } \ - } \ - r; \ -}) - -/* older libcs don't contain a def for IPPROTO_DCCP - * inside of - * if it isn't defined let's define it here. - */ -#ifndef IPPROTO_DCCP -#define IPPROTO_DCCP 33 -#endif - -/* older libcs don't contain a def for IPPROTO_SCTP - * inside of - * if it isn't defined let's define it here. - */ -#ifndef IPPROTO_SCTP -#define IPPROTO_SCTP 132 -#endif - -#ifndef IPPROTO_MH -#define IPPROTO_MH 135 -#endif - -/* Host Identity Protocol (rfc 5201) */ -#ifndef IPPROTO_HIP -#define IPPROTO_HIP 139 -#endif - -#ifndef IPPROTO_SHIM6 -#define IPPROTO_SHIM6 140 -#endif - -/* pcap provides this, but we don't want to depend on libpcap */ -#ifndef DLT_EN10MB -#define DLT_EN10MB 1 -#endif - -/* taken from pcap's bpf.h */ -#ifndef DLT_RAW -#ifdef __OpenBSD__ -#define DLT_RAW 14 /* raw IP */ -#else -#define DLT_RAW 12 /* raw IP */ -#endif -#endif - -#ifndef DLT_NULL -#define DLT_NULL 0 -#endif - -/** libpcap shows us the way to linktype codes - * \todo we need more & maybe put them in a separate file? */ -#define LINKTYPE_NULL DLT_NULL -#define LINKTYPE_ETHERNET DLT_EN10MB -#define LINKTYPE_LINUX_SLL 113 -#define LINKTYPE_PPP 9 -#define LINKTYPE_RAW DLT_RAW -#define PPP_OVER_GRE 11 -#define VLAN_OVER_GRE 13 - -/*Packet Flags*/ -#define PKT_NOPACKET_INSPECTION (1) /**< Flag to indicate that packet header or contents should not be inspected*/ -#define PKT_NOPAYLOAD_INSPECTION (1<<2) /**< Flag to indicate that packet contents should not be inspected*/ -#define PKT_ALLOC (1<<3) /**< Packet was alloc'd this run, needs to be freed */ -#define PKT_HAS_TAG (1<<4) /**< Packet has matched a tag */ -#define PKT_STREAM_ADD (1<<5) /**< Packet payload was added to reassembled stream */ -#define PKT_STREAM_EST (1<<6) /**< Packet is part of establised stream */ -#define PKT_STREAM_EOF (1<<7) /**< Stream is in eof state */ -#define PKT_HAS_FLOW (1<<8) -#define PKT_PSEUDO_STREAM_END (1<<9) /**< Pseudo packet to end the stream */ -#define PKT_STREAM_MODIFIED (1<<10) /**< Packet is modified by the stream engine, we need to recalc the csum and reinject/replace */ -#define PKT_MARK_MODIFIED (1<<11) /**< Packet mark is modified */ -#define PKT_STREAM_NOPCAPLOG (1<<12) /**< Exclude packet from pcap logging as it's part of a stream that has reassembly depth reached. */ - -#define PKT_TUNNEL (1<<13) -#define PKT_TUNNEL_VERDICTED (1<<14) - -#define PKT_IGNORE_CHECKSUM (1<<15) /**< Packet checksum is not computed (TX packet for example) */ -#define PKT_ZERO_COPY (1<<16) /**< Packet comes from zero copy (ext_pkt must not be freed) */ - -#define PKT_HOST_SRC_LOOKED_UP (1<<17) -#define PKT_HOST_DST_LOOKED_UP (1<<18) - -#define PKT_IS_FRAGMENT (1<<19) /**< Packet is a fragment */ -#define PKT_IS_INVALID (1<<20) -#define PKT_PROFILE (1<<21) - -/** \brief return 1 if the packet is a pseudo packet */ -#define PKT_IS_PSEUDOPKT(p) ((p)->flags & PKT_PSEUDO_STREAM_END) - -#define PKT_SET_SRC(p, src_val) ((p)->pkt_src = src_val) - -#endif /* __DECODE_H__ */ - diff --git a/framework/src/suricata/src/defrag-config.c b/framework/src/suricata/src/defrag-config.c deleted file mode 100644 index 5bc4be36..00000000 --- a/framework/src/suricata/src/defrag-config.c +++ /dev/null @@ -1,162 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Giuseppe Longo - * - */ - -#include "suricata-common.h" -#include "queue.h" -#include "suricata.h" -#include "conf.h" -#include "util-debug.h" -#include "util-misc.h" -#include "defrag-config.h" - -static SCRadixTree *defrag_tree = NULL; - -static int default_timeout = 0; - -static void DefragPolicyFreeUserData(void *data) -{ - if (data != NULL) - SCFree(data); - - return; -} - -static void DefragPolicyAddHostInfo(char *host_ip_range, uint64_t timeout) -{ - uint64_t *user_data = NULL; - - if ( (user_data = SCMalloc(sizeof(uint64_t))) == NULL) { - SCLogError(SC_ERR_FATAL, "Error allocating memory. Exiting"); - exit(EXIT_FAILURE); - } - - *user_data = timeout; - - if (strchr(host_ip_range, ':') != NULL) { - SCLogDebug("adding ipv6 host %s", host_ip_range); - if (SCRadixAddKeyIPV6String(host_ip_range, defrag_tree, (void *)user_data) == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, - "failed to add ipv6 host %s", host_ip_range); - } - } else { - SCLogDebug("adding ipv4 host %s", host_ip_range); - if (SCRadixAddKeyIPV4String(host_ip_range, defrag_tree, (void *)user_data) == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, - "failed to add ipv4 host %s", host_ip_range); - } - } -} - -static int DefragPolicyGetIPv4HostTimeout(uint8_t *ipv4_addr) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, defrag_tree, &user_data); - if (user_data == NULL) - return -1; - - return *((int *)user_data); -} - -static int DefragPolicyGetIPv6HostTimeout(uint8_t *ipv6_addr) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, defrag_tree, &user_data); - if (user_data == NULL) - return -1; - - return *((int *)user_data); -} - -int DefragPolicyGetHostTimeout(Packet *p) -{ - int timeout = 0; - - if (PKT_IS_IPV4(p)) - timeout = DefragPolicyGetIPv4HostTimeout((uint8_t *)GET_IPV4_DST_ADDR_PTR(p)); - else if (PKT_IS_IPV6(p)) - timeout = DefragPolicyGetIPv6HostTimeout((uint8_t *)GET_IPV6_DST_ADDR(p)); - - if (timeout <= 0) - timeout = default_timeout; - - return timeout; -} - -static void DefragParseParameters(ConfNode *n) -{ - ConfNode *si; - uint64_t timeout = 0; - - TAILQ_FOREACH(si, &n->head, next) { - if (strcasecmp("timeout", si->name) == 0) { - SCLogDebug("timeout value %s", si->val); - if (ParseSizeStringU64(si->val, &timeout) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing timeout " - "from conf file"); - } - } - if (strcasecmp("address", si->name) == 0) { - ConfNode *pval; - TAILQ_FOREACH(pval, &si->head, next) { - DefragPolicyAddHostInfo(pval->val, timeout); - } - } - } -} - -void DefragSetDefaultTimeout(intmax_t timeout) -{ - default_timeout = timeout; - SCLogDebug("default timeout %d", default_timeout); -} - -void DefragPolicyLoadFromConfig(void) -{ - SCEnter(); - - defrag_tree = SCRadixCreateRadixTree(DefragPolicyFreeUserData, NULL); - if (defrag_tree == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, - "Can't alloc memory for the defrag config tree."); - exit(EXIT_FAILURE); - } - - ConfNode *server_config = ConfGetNode("defrag.host-config"); - if (server_config == NULL) { - SCLogDebug("failed to read host config"); - SCReturn; - } - - SCLogDebug("configuring host config %p", server_config); - ConfNode *sc; - - TAILQ_FOREACH(sc, &server_config->head, next) { - ConfNode *p = NULL; - - TAILQ_FOREACH(p, &sc->head, next) { - SCLogDebug("parsing configuration for %s", p->name); - DefragParseParameters(p); - } - } -} diff --git a/framework/src/suricata/src/defrag-config.h b/framework/src/suricata/src/defrag-config.h deleted file mode 100644 index a6c086ff..00000000 --- a/framework/src/suricata/src/defrag-config.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Giuseppe Longo - * - */ - -#ifndef DEFRAG_CONFIG_H_ -#define DEFRAG_CONFIG_H_ - -void DefragSetDefaultTimeout(intmax_t timeout); -void DefragPolicyLoadFromConfig(void); -int DefragPolicyGetHostTimeout(Packet *p); - -#endif /* DEFRAG_CONFIG_H_ */ diff --git a/framework/src/suricata/src/defrag-hash.c b/framework/src/suricata/src/defrag-hash.c deleted file mode 100644 index e37a0873..00000000 --- a/framework/src/suricata/src/defrag-hash.c +++ /dev/null @@ -1,716 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "conf.h" -#include "defrag-hash.h" -#include "defrag-queue.h" -#include "defrag-config.h" -#include "util-random.h" -#include "util-byte.h" -#include "util-misc.h" -#include "util-hash-lookup3.h" - -static DefragTracker *DefragTrackerGetUsedDefragTracker(void); - -/** queue with spare tracker */ -static DefragTrackerQueue defragtracker_spare_q; - -uint32_t DefragTrackerSpareQueueGetSize(void) -{ - return DefragTrackerQueueLen(&defragtracker_spare_q); -} - -void DefragTrackerMoveToSpare(DefragTracker *h) -{ - DefragTrackerEnqueue(&defragtracker_spare_q, h); - (void) SC_ATOMIC_SUB(defragtracker_counter, 1); -} - -DefragTracker *DefragTrackerAlloc(void) -{ - if (!(DEFRAG_CHECK_MEMCAP(sizeof(DefragTracker)))) { - return NULL; - } - - (void) SC_ATOMIC_ADD(defrag_memuse, sizeof(DefragTracker)); - - DefragTracker *dt = SCMalloc(sizeof(DefragTracker)); - if (unlikely(dt == NULL)) - goto error; - - memset(dt, 0x00, sizeof(DefragTracker)); - - SCMutexInit(&dt->lock, NULL); - SC_ATOMIC_INIT(dt->use_cnt); - return dt; - -error: - return NULL; -} - -void DefragTrackerFree(DefragTracker *dt) -{ - if (dt != NULL) { - DefragTrackerClearMemory(dt); - - SCMutexDestroy(&dt->lock); - SCFree(dt); - (void) SC_ATOMIC_SUB(defrag_memuse, sizeof(DefragTracker)); - } -} - -#define DefragTrackerIncrUsecnt(dt) \ - SC_ATOMIC_ADD((dt)->use_cnt, 1) -#define DefragTrackerDecrUsecnt(dt) \ - SC_ATOMIC_SUB((dt)->use_cnt, 1) - -static void DefragTrackerInit(DefragTracker *dt, Packet *p) -{ - /* copy address */ - COPY_ADDRESS(&p->src, &dt->src_addr); - COPY_ADDRESS(&p->dst, &dt->dst_addr); - - if (PKT_IS_IPV4(p)) { - dt->id = (int32_t)IPV4_GET_IPID(p); - dt->af = AF_INET; - } else { - dt->id = (int32_t)IPV6_EXTHDR_GET_FH_ID(p); - dt->af = AF_INET6; - } - dt->vlan_id[0] = p->vlan_id[0]; - dt->vlan_id[1] = p->vlan_id[1]; - dt->policy = DefragGetOsPolicy(p); - dt->host_timeout = DefragPolicyGetHostTimeout(p); - dt->remove = 0; - dt->seen_last = 0; - - TAILQ_INIT(&dt->frags); - (void) DefragTrackerIncrUsecnt(dt); -} - -void DefragTrackerRelease(DefragTracker *t) -{ - (void) DefragTrackerDecrUsecnt(t); - SCMutexUnlock(&t->lock); -} - -void DefragTrackerClearMemory(DefragTracker *dt) -{ - DefragTrackerFreeFrags(dt); - SC_ATOMIC_DESTROY(dt->use_cnt); -} - -#define DEFRAG_DEFAULT_HASHSIZE 4096 -#define DEFRAG_DEFAULT_MEMCAP 16777216 -#define DEFRAG_DEFAULT_PREALLOC 1000 - -/** \brief initialize the configuration - * \warning Not thread safe */ -void DefragInitConfig(char quiet) -{ - SCLogDebug("initializing defrag engine..."); - - memset(&defrag_config, 0, sizeof(defrag_config)); - //SC_ATOMIC_INIT(flow_flags); - SC_ATOMIC_INIT(defragtracker_counter); - SC_ATOMIC_INIT(defrag_memuse); - SC_ATOMIC_INIT(defragtracker_prune_idx); - DefragTrackerQueueInit(&defragtracker_spare_q); - - unsigned int seed = RandomTimePreseed(); - /* set defaults */ - defrag_config.hash_rand = (int)(DEFRAG_DEFAULT_HASHSIZE * (rand_r(&seed) / RAND_MAX + 1.0)); - - defrag_config.hash_size = DEFRAG_DEFAULT_HASHSIZE; - defrag_config.memcap = DEFRAG_DEFAULT_MEMCAP; - defrag_config.prealloc = DEFRAG_DEFAULT_PREALLOC; - - /* Check if we have memcap and hash_size defined at config */ - char *conf_val; - uint32_t configval = 0; - - /** set config values for memcap, prealloc and hash_size */ - if ((ConfGet("defrag.memcap", &conf_val)) == 1) - { - if (ParseSizeStringU64(conf_val, &defrag_config.memcap) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing defrag.memcap " - "from conf file - %s. Killing engine", - conf_val); - exit(EXIT_FAILURE); - } - } - if ((ConfGet("defrag.hash-size", &conf_val)) == 1) - { - if (ByteExtractStringUint32(&configval, 10, strlen(conf_val), - conf_val) > 0) { - defrag_config.hash_size = configval; - } else { - WarnInvalidConfEntry("defrag.hash-size", "%"PRIu32, defrag_config.hash_size); - } - } - - - if ((ConfGet("defrag.trackers", &conf_val)) == 1) - { - if (ByteExtractStringUint32(&configval, 10, strlen(conf_val), - conf_val) > 0) { - defrag_config.prealloc = configval; - } else { - WarnInvalidConfEntry("defrag.trackers", "%"PRIu32, defrag_config.prealloc); - } - } - SCLogDebug("DefragTracker config from suricata.yaml: memcap: %"PRIu64", hash-size: " - "%"PRIu32", prealloc: %"PRIu32, defrag_config.memcap, - defrag_config.hash_size, defrag_config.prealloc); - - /* alloc hash memory */ - uint64_t hash_size = defrag_config.hash_size * sizeof(DefragTrackerHashRow); - if (!(DEFRAG_CHECK_MEMCAP(hash_size))) { - SCLogError(SC_ERR_DEFRAG_INIT, "allocating defrag hash failed: " - "max defrag memcap is smaller than projected hash size. " - "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate " - "total hash size by multiplying \"defrag.hash-size\" with %"PRIuMAX", " - "which is the hash bucket size.", defrag_config.memcap, hash_size, - (uintmax_t)sizeof(DefragTrackerHashRow)); - exit(EXIT_FAILURE); - } - defragtracker_hash = SCCalloc(defrag_config.hash_size, sizeof(DefragTrackerHashRow)); - if (unlikely(defragtracker_hash == NULL)) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in DefragTrackerInitConfig. Exiting..."); - exit(EXIT_FAILURE); - } - memset(defragtracker_hash, 0, defrag_config.hash_size * sizeof(DefragTrackerHashRow)); - - uint32_t i = 0; - for (i = 0; i < defrag_config.hash_size; i++) { - DRLOCK_INIT(&defragtracker_hash[i]); - } - (void) SC_ATOMIC_ADD(defrag_memuse, (defrag_config.hash_size * sizeof(DefragTrackerHashRow))); - - if (quiet == FALSE) { - SCLogInfo("allocated %llu bytes of memory for the defrag hash... " - "%" PRIu32 " buckets of size %" PRIuMAX "", - SC_ATOMIC_GET(defrag_memuse), defrag_config.hash_size, - (uintmax_t)sizeof(DefragTrackerHashRow)); - } - - if ((ConfGet("defrag.prealloc", &conf_val)) == 1) - { - if (ConfValIsTrue(conf_val)) { - /* pre allocate defrag trackers */ - for (i = 0; i < defrag_config.prealloc; i++) { - if (!(DEFRAG_CHECK_MEMCAP(sizeof(DefragTracker)))) { - SCLogError(SC_ERR_DEFRAG_INIT, "preallocating defrag trackers failed: " - "max defrag memcap reached. Memcap %"PRIu64", " - "Memuse %"PRIu64".", defrag_config.memcap, - ((uint64_t)SC_ATOMIC_GET(defrag_memuse) + (uint64_t)sizeof(DefragTracker))); - exit(EXIT_FAILURE); - } - - DefragTracker *h = DefragTrackerAlloc(); - if (h == NULL) { - SCLogError(SC_ERR_DEFRAG_INIT, "preallocating defrag failed: %s", strerror(errno)); - exit(EXIT_FAILURE); - } - DefragTrackerEnqueue(&defragtracker_spare_q,h); - } - if (quiet == FALSE) { - SCLogInfo("preallocated %" PRIu32 " defrag trackers of size %" PRIuMAX "", - defragtracker_spare_q.len, (uintmax_t)sizeof(DefragTracker)); - } - } - } - - if (quiet == FALSE) { - SCLogInfo("defrag memory usage: %llu bytes, maximum: %"PRIu64, - SC_ATOMIC_GET(defrag_memuse), defrag_config.memcap); - } - - return; -} - -/** \brief print some defrag stats - * \warning Not thread safe */ -static void DefragTrackerPrintStats (void) -{ -} - -/** \brief shutdown the flow engine - * \warning Not thread safe */ -void DefragHashShutdown(void) -{ - DefragTracker *dt; - uint32_t u; - - DefragTrackerPrintStats(); - - /* free spare queue */ - while((dt = DefragTrackerDequeue(&defragtracker_spare_q))) { - BUG_ON(SC_ATOMIC_GET(dt->use_cnt) > 0); - DefragTrackerFree(dt); - } - - /* clear and free the hash */ - if (defragtracker_hash != NULL) { - for (u = 0; u < defrag_config.hash_size; u++) { - dt = defragtracker_hash[u].head; - while (dt) { - DefragTracker *n = dt->hnext; - DefragTrackerClearMemory(dt); - DefragTrackerFree(dt); - dt = n; - } - - DRLOCK_DESTROY(&defragtracker_hash[u]); - } - SCFree(defragtracker_hash); - defragtracker_hash = NULL; - } - (void) SC_ATOMIC_SUB(defrag_memuse, defrag_config.hash_size * sizeof(DefragTrackerHashRow)); - DefragTrackerQueueDestroy(&defragtracker_spare_q); - - SC_ATOMIC_DESTROY(defragtracker_prune_idx); - SC_ATOMIC_DESTROY(defrag_memuse); - SC_ATOMIC_DESTROY(defragtracker_counter); - //SC_ATOMIC_DESTROY(flow_flags); - return; -} - -/** \brief compare two raw ipv6 addrs - * - * \note we don't care about the real ipv6 ip's, this is just - * to consistently fill the DefragHashKey6 struct, without all - * the ntohl calls. - * - * \warning do not use elsewhere unless you know what you're doing. - * detect-engine-address-ipv6.c's AddressIPv6GtU32 is likely - * what you are looking for. - */ -static inline int DefragHashRawAddressIPv6GtU32(uint32_t *a, uint32_t *b) -{ - int i; - - for (i = 0; i < 4; i++) { - if (a[i] > b[i]) - return 1; - if (a[i] < b[i]) - break; - } - - return 0; -} - -typedef struct DefragHashKey4_ { - union { - struct { - uint32_t src, dst; - uint32_t id; - uint16_t vlan_id[2]; - }; - uint32_t u32[4]; - }; -} DefragHashKey4; - -typedef struct DefragHashKey6_ { - union { - struct { - uint32_t src[4], dst[4]; - uint32_t id; - uint16_t vlan_id[2]; - }; - uint32_t u32[10]; - }; -} DefragHashKey6; - -/* calculate the hash key for this packet - * - * we're using: - * hash_rand -- set at init time - * source address - * destination address - * id - * vlan_id - */ -static inline uint32_t DefragHashGetKey(Packet *p) -{ - uint32_t key; - - if (p->ip4h != NULL) { - DefragHashKey4 dhk; - if (p->src.addr_data32[0] > p->dst.addr_data32[0]) { - dhk.src = p->src.addr_data32[0]; - dhk.dst = p->dst.addr_data32[0]; - } else { - dhk.src = p->dst.addr_data32[0]; - dhk.dst = p->src.addr_data32[0]; - } - dhk.id = (uint32_t)IPV4_GET_IPID(p); - dhk.vlan_id[0] = p->vlan_id[0]; - dhk.vlan_id[1] = p->vlan_id[1]; - - uint32_t hash = hashword(dhk.u32, 4, defrag_config.hash_rand); - key = hash % defrag_config.hash_size; - } else if (p->ip6h != NULL) { - DefragHashKey6 dhk; - if (DefragHashRawAddressIPv6GtU32(p->src.addr_data32, p->dst.addr_data32)) { - dhk.src[0] = p->src.addr_data32[0]; - dhk.src[1] = p->src.addr_data32[1]; - dhk.src[2] = p->src.addr_data32[2]; - dhk.src[3] = p->src.addr_data32[3]; - dhk.dst[0] = p->dst.addr_data32[0]; - dhk.dst[1] = p->dst.addr_data32[1]; - dhk.dst[2] = p->dst.addr_data32[2]; - dhk.dst[3] = p->dst.addr_data32[3]; - } else { - dhk.src[0] = p->dst.addr_data32[0]; - dhk.src[1] = p->dst.addr_data32[1]; - dhk.src[2] = p->dst.addr_data32[2]; - dhk.src[3] = p->dst.addr_data32[3]; - dhk.dst[0] = p->src.addr_data32[0]; - dhk.dst[1] = p->src.addr_data32[1]; - dhk.dst[2] = p->src.addr_data32[2]; - dhk.dst[3] = p->src.addr_data32[3]; - } - dhk.id = IPV6_EXTHDR_GET_FH_ID(p); - dhk.vlan_id[0] = p->vlan_id[0]; - dhk.vlan_id[1] = p->vlan_id[1]; - - uint32_t hash = hashword(dhk.u32, 10, defrag_config.hash_rand); - key = hash % defrag_config.hash_size; - } else - key = 0; - - return key; -} - -/* Since two or more trackers can have the same hash key, we need to compare - * the tracker with the current tracker key. */ -#define CMP_DEFRAGTRACKER(d1,d2,id) \ - (((CMP_ADDR(&(d1)->src_addr, &(d2)->src) && \ - CMP_ADDR(&(d1)->dst_addr, &(d2)->dst)) || \ - (CMP_ADDR(&(d1)->src_addr, &(d2)->dst) && \ - CMP_ADDR(&(d1)->dst_addr, &(d2)->src))) && \ - (d1)->id == (id) && \ - (d1)->vlan_id[0] == (d2)->vlan_id[0] && \ - (d1)->vlan_id[1] == (d2)->vlan_id[1]) - -static inline int DefragTrackerCompare(DefragTracker *t, Packet *p) -{ - uint32_t id; - if (PKT_IS_IPV4(p)) { - id = (uint32_t)IPV4_GET_IPID(p); - } else { - id = IPV6_EXTHDR_GET_FH_ID(p); - } - - return CMP_DEFRAGTRACKER(t, p, id); -} - -/** - * \brief Get a new defrag tracker - * - * Get a new defrag tracker. We're checking memcap first and will try to make room - * if the memcap is reached. - * - * \retval dt *LOCKED* tracker on succes, NULL on error. - */ -static DefragTracker *DefragTrackerGetNew(Packet *p) -{ - DefragTracker *dt = NULL; - - /* get a tracker from the spare queue */ - dt = DefragTrackerDequeue(&defragtracker_spare_q); - if (dt == NULL) { - /* If we reached the max memcap, we get a used tracker */ - if (!(DEFRAG_CHECK_MEMCAP(sizeof(DefragTracker)))) { - /* declare state of emergency */ - //if (!(SC_ATOMIC_GET(defragtracker_flags) & DEFRAG_EMERGENCY)) { - // SC_ATOMIC_OR(defragtracker_flags, DEFRAG_EMERGENCY); - - /* under high load, waking up the flow mgr each time leads - * to high cpu usage. Flows are not timed out much faster if - * we check a 1000 times a second. */ - // FlowWakeupFlowManagerThread(); - //} - - dt = DefragTrackerGetUsedDefragTracker(); - if (dt == NULL) { - return NULL; - } - - /* freed a tracker, but it's unlocked */ - } else { - /* now see if we can alloc a new tracker */ - dt = DefragTrackerAlloc(); - if (dt == NULL) { - return NULL; - } - - /* tracker is initialized but *unlocked* */ - } - } else { - /* tracker has been recycled before it went into the spare queue */ - - /* tracker is initialized (recylced) but *unlocked* */ - } - - (void) SC_ATOMIC_ADD(defragtracker_counter, 1); - SCMutexLock(&dt->lock); - return dt; -} - -/* DefragGetTrackerFromHash - * - * Hash retrieval function for trackers. Looks up the hash bucket containing the - * tracker pointer. Then compares the packet with the found tracker to see if it is - * the tracker we need. If it isn't, walk the list until the right tracker is found. - * - * returns a *LOCKED* tracker or NULL - */ -DefragTracker *DefragGetTrackerFromHash (Packet *p) -{ - DefragTracker *dt = NULL; - - /* get the key to our bucket */ - uint32_t key = DefragHashGetKey(p); - /* get our hash bucket and lock it */ - DefragTrackerHashRow *hb = &defragtracker_hash[key]; - DRLOCK_LOCK(hb); - - /* see if the bucket already has a tracker */ - if (hb->head == NULL) { - dt = DefragTrackerGetNew(p); - if (dt == NULL) { - DRLOCK_UNLOCK(hb); - return NULL; - } - - /* tracker is locked */ - hb->head = dt; - hb->tail = dt; - - /* got one, now lock, initialize and return */ - DefragTrackerInit(dt,p); - - DRLOCK_UNLOCK(hb); - return dt; - } - - /* ok, we have a tracker in the bucket. Let's find out if it is our tracker */ - dt = hb->head; - - /* see if this is the tracker we are looking for */ - if (dt->remove || DefragTrackerCompare(dt, p) == 0) { - DefragTracker *pdt = NULL; /* previous tracker */ - - while (dt) { - pdt = dt; - dt = dt->hnext; - - if (dt == NULL) { - dt = pdt->hnext = DefragTrackerGetNew(p); - if (dt == NULL) { - DRLOCK_UNLOCK(hb); - return NULL; - } - hb->tail = dt; - - /* tracker is locked */ - - dt->hprev = pdt; - - /* initialize and return */ - DefragTrackerInit(dt,p); - - DRLOCK_UNLOCK(hb); - return dt; - } - - if (DefragTrackerCompare(dt, p) != 0) { - /* we found our tracker, lets put it on top of the - * hash list -- this rewards active trackers */ - if (dt->hnext) { - dt->hnext->hprev = dt->hprev; - } - if (dt->hprev) { - dt->hprev->hnext = dt->hnext; - } - if (dt == hb->tail) { - hb->tail = dt->hprev; - } - - dt->hnext = hb->head; - dt->hprev = NULL; - hb->head->hprev = dt; - hb->head = dt; - - /* found our tracker, lock & return */ - SCMutexLock(&dt->lock); - (void) DefragTrackerIncrUsecnt(dt); - DRLOCK_UNLOCK(hb); - return dt; - } - } - } - - /* lock & return */ - SCMutexLock(&dt->lock); - (void) DefragTrackerIncrUsecnt(dt); - DRLOCK_UNLOCK(hb); - return dt; -} - -/** \brief look up a tracker in the hash - * - * \param a address to look up - * - * \retval h *LOCKED* tracker or NULL - */ -DefragTracker *DefragLookupTrackerFromHash (Packet *p) -{ - DefragTracker *dt = NULL; - - /* get the key to our bucket */ - uint32_t key = DefragHashGetKey(p); - /* get our hash bucket and lock it */ - DefragTrackerHashRow *hb = &defragtracker_hash[key]; - DRLOCK_LOCK(hb); - - /* see if the bucket already has a tracker */ - if (hb->head == NULL) { - DRLOCK_UNLOCK(hb); - return dt; - } - - /* ok, we have a tracker in the bucket. Let's find out if it is our tracker */ - dt = hb->head; - - /* see if this is the tracker we are looking for */ - if (DefragTrackerCompare(dt, p) == 0) { - while (dt) { - dt = dt->hnext; - - if (dt == NULL) { - DRLOCK_UNLOCK(hb); - return dt; - } - - if (DefragTrackerCompare(dt, p) != 0) { - /* we found our tracker, lets put it on top of the - * hash list -- this rewards active tracker */ - if (dt->hnext) { - dt->hnext->hprev = dt->hprev; - } - if (dt->hprev) { - dt->hprev->hnext = dt->hnext; - } - if (dt == hb->tail) { - hb->tail = dt->hprev; - } - - dt->hnext = hb->head; - dt->hprev = NULL; - hb->head->hprev = dt; - hb->head = dt; - - /* found our tracker, lock & return */ - SCMutexLock(&dt->lock); - (void) DefragTrackerIncrUsecnt(dt); - DRLOCK_UNLOCK(hb); - return dt; - } - } - } - - /* lock & return */ - SCMutexLock(&dt->lock); - (void) DefragTrackerIncrUsecnt(dt); - DRLOCK_UNLOCK(hb); - return dt; -} - -/** \internal - * \brief Get a tracker from the hash directly. - * - * Called in conditions where the spare queue is empty and memcap is reached. - * - * Walks the hash until a tracker can be freed. "defragtracker_prune_idx" atomic int makes - * sure we don't start at the top each time since that would clear the top of - * the hash leading to longer and longer search times under high pressure (observed). - * - * \retval dt tracker or NULL - */ -static DefragTracker *DefragTrackerGetUsedDefragTracker(void) -{ - uint32_t idx = SC_ATOMIC_GET(defragtracker_prune_idx) % defrag_config.hash_size; - uint32_t cnt = defrag_config.hash_size; - - while (cnt--) { - if (++idx >= defrag_config.hash_size) - idx = 0; - - DefragTrackerHashRow *hb = &defragtracker_hash[idx]; - - if (DRLOCK_TRYLOCK(hb) != 0) - continue; - - DefragTracker *dt = hb->tail; - if (dt == NULL) { - DRLOCK_UNLOCK(hb); - continue; - } - - if (SCMutexTrylock(&dt->lock) != 0) { - DRLOCK_UNLOCK(hb); - continue; - } - - /** never prune a tracker that is used by a packets - * we are currently processing in one of the threads */ - if (SC_ATOMIC_GET(dt->use_cnt) > 0) { - DRLOCK_UNLOCK(hb); - SCMutexUnlock(&dt->lock); - continue; - } - - /* remove from the hash */ - if (dt->hprev != NULL) - dt->hprev->hnext = dt->hnext; - if (dt->hnext != NULL) - dt->hnext->hprev = dt->hprev; - if (hb->head == dt) - hb->head = dt->hnext; - if (hb->tail == dt) - hb->tail = dt->hprev; - - dt->hnext = NULL; - dt->hprev = NULL; - DRLOCK_UNLOCK(hb); - - DefragTrackerClearMemory(dt); - - SCMutexUnlock(&dt->lock); - - (void) SC_ATOMIC_ADD(defragtracker_prune_idx, (defrag_config.hash_size - cnt)); - return dt; - } - - return NULL; -} - - diff --git a/framework/src/suricata/src/defrag-hash.h b/framework/src/suricata/src/defrag-hash.h deleted file mode 100644 index 2d48393a..00000000 --- a/framework/src/suricata/src/defrag-hash.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DEFRAG_HASH_H__ -#define __DEFRAG_HASH_H__ - -#include "decode.h" -#include "defrag.h" - -/** Spinlocks or Mutex for the flow buckets. */ -//#define DRLOCK_SPIN -#define DRLOCK_MUTEX - -#ifdef DRLOCK_SPIN - #ifdef DRLOCK_MUTEX - #error Cannot enable both DRLOCK_SPIN and DRLOCK_MUTEX - #endif -#endif - -#ifdef DRLOCK_SPIN - #define DRLOCK_TYPE SCSpinlock - #define DRLOCK_INIT(fb) SCSpinInit(&(fb)->lock, 0) - #define DRLOCK_DESTROY(fb) SCSpinDestroy(&(fb)->lock) - #define DRLOCK_LOCK(fb) SCSpinLock(&(fb)->lock) - #define DRLOCK_TRYLOCK(fb) SCSpinTrylock(&(fb)->lock) - #define DRLOCK_UNLOCK(fb) SCSpinUnlock(&(fb)->lock) -#elif defined DRLOCK_MUTEX - #define DRLOCK_TYPE SCMutex - #define DRLOCK_INIT(fb) SCMutexInit(&(fb)->lock, NULL) - #define DRLOCK_DESTROY(fb) SCMutexDestroy(&(fb)->lock) - #define DRLOCK_LOCK(fb) SCMutexLock(&(fb)->lock) - #define DRLOCK_TRYLOCK(fb) SCMutexTrylock(&(fb)->lock) - #define DRLOCK_UNLOCK(fb) SCMutexUnlock(&(fb)->lock) -#else - #error Enable DRLOCK_SPIN or DRLOCK_MUTEX -#endif - -typedef struct DefragTrackerHashRow_ { - DRLOCK_TYPE lock; - DefragTracker *head; - DefragTracker *tail; -} DefragTrackerHashRow; - -/** defrag tracker hash table */ -DefragTrackerHashRow *defragtracker_hash; - -#define DEFRAG_VERBOSE 0 -#define DEFRAG_QUIET 1 - -typedef struct DefragConfig_ { - uint64_t memcap; - uint32_t hash_rand; - uint32_t hash_size; - uint32_t prealloc; -} DefragConfig; - -/** \brief check if a memory alloc would fit in the memcap - * - * \param size memory allocation size to check - * - * \retval 1 it fits - * \retval 0 no fit - */ -#define DEFRAG_CHECK_MEMCAP(size) \ - ((((uint64_t)SC_ATOMIC_GET(defrag_memuse) + (uint64_t)(size)) <= defrag_config.memcap)) - -DefragConfig defrag_config; -SC_ATOMIC_DECLARE(unsigned long long int,defrag_memuse); -SC_ATOMIC_DECLARE(unsigned int,defragtracker_counter); -SC_ATOMIC_DECLARE(unsigned int,defragtracker_prune_idx); - -void DefragInitConfig(char quiet); -void DefragHashShutdown(void); - -DefragTracker *DefragLookupTrackerFromHash (Packet *); -DefragTracker *DefragGetTrackerFromHash (Packet *); -void DefragTrackerRelease(DefragTracker *); -void DefragTrackerClearMemory(DefragTracker *); -void DefragTrackerMoveToSpare(DefragTracker *); -uint32_t DefragTrackerSpareQueueGetSize(void); - -#endif /* __DEFRAG_HASH_H__ */ - diff --git a/framework/src/suricata/src/defrag-queue.c b/framework/src/suricata/src/defrag-queue.c deleted file mode 100644 index 71dcb932..00000000 --- a/framework/src/suricata/src/defrag-queue.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Defrag tracker queue handler functions - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "defrag-queue.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-print.h" - -DefragTrackerQueue *DefragTrackerQueueInit (DefragTrackerQueue *q) -{ - if (q != NULL) { - memset(q, 0, sizeof(DefragTrackerQueue)); - DQLOCK_INIT(q); - } - return q; -} - -DefragTrackerQueue *DefragTrackerQueueNew() -{ - DefragTrackerQueue *q = (DefragTrackerQueue *)SCMalloc(sizeof(DefragTrackerQueue)); - if (q == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in DefragTrackerQueueNew. Exiting..."); - exit(EXIT_SUCCESS); - } - q = DefragTrackerQueueInit(q); - return q; -} - -/** - * \brief Destroy a tracker queue - * - * \param q the tracker queue to destroy - */ -void DefragTrackerQueueDestroy (DefragTrackerQueue *q) -{ - DQLOCK_DESTROY(q); -} - -/** - * \brief add a tracker to a queue - * - * \param q queue - * \param dt tracker - */ -void DefragTrackerEnqueue (DefragTrackerQueue *q, DefragTracker *dt) -{ -#ifdef DEBUG - BUG_ON(q == NULL || dt == NULL); -#endif - - DQLOCK_LOCK(q); - - /* more trackers in queue */ - if (q->top != NULL) { - dt->lnext = q->top; - q->top->lprev = dt; - q->top = dt; - /* only tracker */ - } else { - q->top = dt; - q->bot = dt; - } - q->len++; -#ifdef DBG_PERF - if (q->len > q->dbg_maxlen) - q->dbg_maxlen = q->len; -#endif /* DBG_PERF */ - DQLOCK_UNLOCK(q); -} - -/** - * \brief remove a tracker from the queue - * - * \param q queue - * - * \retval dt tracker or NULL if empty list. - */ -DefragTracker *DefragTrackerDequeue (DefragTrackerQueue *q) -{ - DQLOCK_LOCK(q); - - DefragTracker *dt = q->bot; - if (dt == NULL) { - DQLOCK_UNLOCK(q); - return NULL; - } - - /* more packets in queue */ - if (q->bot->lprev != NULL) { - q->bot = q->bot->lprev; - q->bot->lnext = NULL; - /* just the one we remove, so now empty */ - } else { - q->top = NULL; - q->bot = NULL; - } - -#ifdef DEBUG - BUG_ON(q->len == 0); -#endif - if (q->len > 0) - q->len--; - - dt->lnext = NULL; - dt->lprev = NULL; - - DQLOCK_UNLOCK(q); - return dt; -} - -uint32_t DefragTrackerQueueLen(DefragTrackerQueue *q) -{ - uint32_t len; - DQLOCK_LOCK(q); - len = q->len; - DQLOCK_UNLOCK(q); - return len; -} - diff --git a/framework/src/suricata/src/defrag-queue.h b/framework/src/suricata/src/defrag-queue.h deleted file mode 100644 index 87b5f4d1..00000000 --- a/framework/src/suricata/src/defrag-queue.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DEFRAG_QUEUE_H__ -#define __DEFRAG_QUEUE_H__ - -#include "suricata-common.h" -#include "defrag.h" - -/** Spinlocks or Mutex for the defrag tracker queues. */ -//#define DQLOCK_SPIN -#define DQLOCK_MUTEX - -#ifdef DQLOCK_SPIN - #ifdef DQLOCK_MUTEX - #error Cannot enable both DQLOCK_SPIN and DQLOCK_MUTEX - #endif -#endif - -/* Define a queue for storing defrag trackers */ -typedef struct DefragTrackerQueue_ -{ - DefragTracker *top; - DefragTracker *bot; - uint32_t len; -#ifdef DBG_PERF - uint32_t dbg_maxlen; -#endif /* DBG_PERF */ -#ifdef DQLOCK_MUTEX - SCMutex m; -#elif defined DQLOCK_SPIN - SCSpinlock s; -#else - #error Enable DQLOCK_SPIN or DQLOCK_MUTEX -#endif -} DefragTrackerQueue; - -#ifdef DQLOCK_SPIN - #define DQLOCK_INIT(q) SCSpinInit(&(q)->s, 0) - #define DQLOCK_DESTROY(q) SCSpinDestroy(&(q)->s) - #define DQLOCK_LOCK(q) SCSpinLock(&(q)->s) - #define DQLOCK_TRYLOCK(q) SCSpinTrylock(&(q)->s) - #define DQLOCK_UNLOCK(q) SCSpinUnlock(&(q)->s) -#elif defined DQLOCK_MUTEX - #define DQLOCK_INIT(q) SCMutexInit(&(q)->m, NULL) - #define DQLOCK_DESTROY(q) SCMutexDestroy(&(q)->m) - #define DQLOCK_LOCK(q) SCMutexLock(&(q)->m) - #define DQLOCK_TRYLOCK(q) SCMutexTrylock(&(q)->m) - #define DQLOCK_UNLOCK(q) SCMutexUnlock(&(q)->m) -#else - #error Enable DQLOCK_SPIN or DQLOCK_MUTEX -#endif - -/* prototypes */ -DefragTrackerQueue *DefragTrackerQueueNew(); -DefragTrackerQueue *DefragTrackerQueueInit(DefragTrackerQueue *); -void DefragTrackerQueueDestroy (DefragTrackerQueue *); - -void DefragTrackerEnqueue (DefragTrackerQueue *, DefragTracker *); -DefragTracker *DefragTrackerDequeue (DefragTrackerQueue *); -uint32_t DefragTrackerQueueLen(DefragTrackerQueue *); - -#endif /* __DEFRAG_QUEUE_H__ */ - diff --git a/framework/src/suricata/src/defrag-timeout.c b/framework/src/suricata/src/defrag-timeout.c deleted file mode 100644 index 663ee3b5..00000000 --- a/framework/src/suricata/src/defrag-timeout.c +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "defrag.h" -#include "defrag-hash.h" - -uint32_t DefragTrackerGetSpareCount(void) -{ - return DefragTrackerSpareQueueGetSize(); -} - -uint32_t DefragTrackerGetActiveCount(void) -{ - return SC_ATOMIC_GET(defragtracker_counter); -} - -/** \internal - * \brief See if we can really discard this tracker. Check use_cnt reference. - * - * \param dt tracker - * \param ts timestamp - * - * \retval 0 not timed out just yet - * \retval 1 fully timed out, lets kill it - */ -static int DefragTrackerTimedOut(DefragTracker *dt, struct timeval *ts) -{ - /** never prune a trackers that is used by a packet - * we are currently processing in one of the threads */ - if (SC_ATOMIC_GET(dt->use_cnt) > 0) { - return 0; - } - - /* retain if remove is not set and not timed out */ - if (!dt->remove && timercmp(&dt->timeout, ts, >)) - return 0; - - return 1; -} - -/** - * \internal - * - * \brief check all trackers in a hash row for timing out - * - * \param hb tracker hash row *LOCKED* - * \param dt last tracker in the hash row - * \param ts timestamp - * - * \retval cnt timed out tracker - */ -static uint32_t DefragTrackerHashRowTimeout(DefragTrackerHashRow *hb, DefragTracker *dt, struct timeval *ts) -{ - uint32_t cnt = 0; - - do { - if (SCMutexTrylock(&dt->lock) != 0) { - dt = dt->hprev; - continue; - } - - DefragTracker *next_dt = dt->hprev; - - /* check if the tracker is fully timed out and - * ready to be discarded. */ - if (DefragTrackerTimedOut(dt, ts) == 1) { - /* remove from the hash */ - if (dt->hprev != NULL) - dt->hprev->hnext = dt->hnext; - if (dt->hnext != NULL) - dt->hnext->hprev = dt->hprev; - if (hb->head == dt) - hb->head = dt->hnext; - if (hb->tail == dt) - hb->tail = dt->hprev; - - dt->hnext = NULL; - dt->hprev = NULL; - - DefragTrackerClearMemory(dt); - - /* no one is referring to this tracker, use_cnt 0, removed from hash - * so we can unlock it and move it back to the spare queue. */ - SCMutexUnlock(&dt->lock); - - /* move to spare list */ - DefragTrackerMoveToSpare(dt); - - cnt++; - } else { - SCMutexUnlock(&dt->lock); - } - - dt = next_dt; - } while (dt != NULL); - - return cnt; -} - -/** - * \brief time out tracker from the hash - * - * \param ts timestamp - * - * \retval cnt number of timed out tracker - */ -uint32_t DefragTimeoutHash(struct timeval *ts) -{ - uint32_t idx = 0; - uint32_t cnt = 0; - - for (idx = 0; idx < defrag_config.hash_size; idx++) { - DefragTrackerHashRow *hb = &defragtracker_hash[idx]; - - if (DRLOCK_TRYLOCK(hb) != 0) - continue; - - /* defrag hash bucket is now locked */ - - if (hb->tail == NULL) { - DRLOCK_UNLOCK(hb); - continue; - } - - /* we have a tracker, or more than one */ - cnt += DefragTrackerHashRowTimeout(hb, hb->tail, ts); - DRLOCK_UNLOCK(hb); - } - - return cnt; -} - diff --git a/framework/src/suricata/src/defrag-timeout.h b/framework/src/suricata/src/defrag-timeout.h deleted file mode 100644 index 77de4572..00000000 --- a/framework/src/suricata/src/defrag-timeout.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DEFRAG_TIMEOUT_H__ -#define __DEFRAG_TIMEOUT_H__ - -uint32_t DefragTimeoutHash(struct timeval *ts); - -uint32_t DefragGetSpareCount(void); -uint32_t DefragGetActiveCount(void); - -#endif - diff --git a/framework/src/suricata/src/defrag.c b/framework/src/suricata/src/defrag.c deleted file mode 100644 index 1d86c448..00000000 --- a/framework/src/suricata/src/defrag.c +++ /dev/null @@ -1,2584 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited, Jason Ish - * - * Defragmentation module. - * References: - * - RFC 815 - * - OpenBSD PF's IP normalizaton (pf_norm.c) - * - * \todo pool for frag packet storage - * \todo policy bsd-right - * \todo profile hash function - * \todo log anomalies - */ - -#include "suricata-common.h" - -#include "queue.h" - -#include "suricata.h" -#include "threads.h" -#include "conf.h" -#include "decode-ipv6.h" -#include "util-hashlist.h" -#include "util-pool.h" -#include "util-time.h" -#include "util-print.h" -#include "util-debug.h" -#include "util-fix_checksum.h" -#include "util-random.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "util-host-os-info.h" - -#include "defrag.h" -#include "defrag-hash.h" -#include "defrag-queue.h" -#include "defrag-config.h" - -#include "tmqh-packetpool.h" -#include "decode.h" - -#ifdef UNITTESTS -#include "util-unittest.h" -#endif - -#define DEFAULT_DEFRAG_HASH_SIZE 0xffff -#define DEFAULT_DEFRAG_POOL_SIZE 0xffff - -/** - * Default timeout (in seconds) before a defragmentation tracker will - * be released. - */ -#define TIMEOUT_DEFAULT 60 - -/** - * Maximum allowed timeout, 24 hours. - */ -#define TIMEOUT_MAX (60 * 60 * 24) - -/** - * Minimum allowed timeout, 1 second. - */ -#define TIMEOUT_MIN 1 - -/** Fragment reassembly policies. */ -enum defrag_policies { - DEFRAG_POLICY_FIRST = 1, - DEFRAG_POLICY_LAST, - DEFRAG_POLICY_BSD, - DEFRAG_POLICY_BSD_RIGHT, - DEFRAG_POLICY_LINUX, - DEFRAG_POLICY_WINDOWS, - DEFRAG_POLICY_SOLARIS, - - DEFRAG_POLICY_DEFAULT = DEFRAG_POLICY_BSD, -}; - -static int default_policy = DEFRAG_POLICY_BSD; - -/** The global DefragContext so all threads operate from the same - * context. */ -static DefragContext *defrag_context; - -/** - * Utility/debugging function to dump the frags associated with a - * tracker. Only enable when unit tests are enabled. - */ -#if 0 -#ifdef UNITTESTS -static void -DumpFrags(DefragTracker *tracker) -{ - Frag *frag; - - printf("Dumping frags for packet: ID=%d\n", tracker->id); - TAILQ_FOREACH(frag, &tracker->frags, next) { - printf("-> Frag: frag_offset=%d, frag_len=%d, data_len=%d, ltrim=%d, skip=%d\n", frag->offset, frag->len, frag->data_len, frag->ltrim, frag->skip); - PrintRawDataFp(stdout, frag->pkt, frag->len); - } -} -#endif /* UNITTESTS */ -#endif - -/** - * \brief Reset a frag for reuse in a pool. - */ -static void -DefragFragReset(Frag *frag) -{ - if (frag->pkt != NULL) - SCFree(frag->pkt); - memset(frag, 0, sizeof(*frag)); -} - -/** - * \brief Allocate a new frag for use in a pool. - */ -static int -DefragFragInit(void *data, void *initdata) -{ - Frag *frag = data; - - memset(frag, 0, sizeof(*frag)); - return 1; -} - -/** - * \brief Free all frags associated with a tracker. - */ -void -DefragTrackerFreeFrags(DefragTracker *tracker) -{ - Frag *frag; - - /* Lock the frag pool as we'll be return items to it. */ - SCMutexLock(&defrag_context->frag_pool_lock); - - while ((frag = TAILQ_FIRST(&tracker->frags)) != NULL) { - TAILQ_REMOVE(&tracker->frags, frag, next); - - /* Don't SCFree the frag, just give it back to its pool. */ - DefragFragReset(frag); - PoolReturn(defrag_context->frag_pool, frag); - } - - SCMutexUnlock(&defrag_context->frag_pool_lock); -} - -/** - * \brief Create a new DefragContext. - * - * \retval On success a return an initialized DefragContext, otherwise - * NULL will be returned. - */ -static DefragContext * -DefragContextNew(void) -{ - DefragContext *dc; - - dc = SCCalloc(1, sizeof(*dc)); - if (unlikely(dc == NULL)) - return NULL; - - /* Initialize the pool of trackers. */ - intmax_t tracker_pool_size; - if (!ConfGetInt("defrag.trackers", &tracker_pool_size) || tracker_pool_size == 0) { - tracker_pool_size = DEFAULT_DEFRAG_HASH_SIZE; - } - - /* Initialize the pool of frags. */ - intmax_t frag_pool_size; - if (!ConfGetInt("defrag.max-frags", &frag_pool_size) || frag_pool_size == 0) { - frag_pool_size = DEFAULT_DEFRAG_POOL_SIZE; - } - intmax_t frag_pool_prealloc = frag_pool_size / 2; - dc->frag_pool = PoolInit(frag_pool_size, frag_pool_prealloc, - sizeof(Frag), - NULL, DefragFragInit, dc, NULL, NULL); - if (dc->frag_pool == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, - "Defrag: Failed to initialize fragment pool."); - exit(EXIT_FAILURE); - } - if (SCMutexInit(&dc->frag_pool_lock, NULL) != 0) { - SCLogError(SC_ERR_MUTEX, - "Defrag: Failed to initialize frag pool mutex."); - exit(EXIT_FAILURE); - } - - /* Set the default timeout. */ - intmax_t timeout; - if (!ConfGetInt("defrag.timeout", &timeout)) { - dc->timeout = TIMEOUT_DEFAULT; - } - else { - if (timeout < TIMEOUT_MIN) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "defrag: Timeout less than minimum allowed value."); - exit(EXIT_FAILURE); - } - else if (timeout > TIMEOUT_MAX) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "defrag: Tiemout greater than maximum allowed value."); - exit(EXIT_FAILURE); - } - dc->timeout = timeout; - } - - SCLogDebug("Defrag Initialized:"); - SCLogDebug("\tTimeout: %"PRIuMAX, (uintmax_t)dc->timeout); - SCLogDebug("\tMaximum defrag trackers: %"PRIuMAX, tracker_pool_size); - SCLogDebug("\tPreallocated defrag trackers: %"PRIuMAX, tracker_pool_size); - SCLogDebug("\tMaximum fragments: %"PRIuMAX, (uintmax_t)frag_pool_size); - SCLogDebug("\tPreallocated fragments: %"PRIuMAX, (uintmax_t)frag_pool_prealloc); - - return dc; -} - -static void -DefragContextDestroy(DefragContext *dc) -{ - if (dc == NULL) - return; - - PoolFree(dc->frag_pool); - SCFree(dc); -} - -/** - * Attempt to re-assemble a packet. - * - * \param tracker The defragmentation tracker to reassemble from. - */ -static Packet * -Defrag4Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p) -{ - Packet *rp = NULL; - - /* Should not be here unless we have seen the last fragment. */ - if (!tracker->seen_last) - return NULL; - - /* Check that we have all the data. Relies on the fact that - * fragments are inserted if frag_offset order. */ - Frag *frag; - int len = 0; - TAILQ_FOREACH(frag, &tracker->frags, next) { - if (frag->skip) - continue; - - if (frag == TAILQ_FIRST(&tracker->frags)) { - if (frag->offset != 0) { - goto done; - } - len = frag->data_len; - } - else { - if (frag->offset > len) { - /* This fragment starts after the end of the previous - * fragment. We have a hole. */ - goto done; - } - else { - len += frag->data_len; - } - } - } - - /* Allocate a Packet for the reassembled packet. On failure we - * SCFree all the resources held by this tracker. */ - rp = PacketDefragPktSetup(p, NULL, 0, IPV4_GET_IPPROTO(p)); - if (rp == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate packet for " - "fragmentation re-assembly, dumping fragments."); - goto error_remove_tracker; - } - PKT_SET_SRC(rp, PKT_SRC_DEFRAG); - rp->recursion_level = p->recursion_level; - - int fragmentable_offset = 0; - int fragmentable_len = 0; - int hlen = 0; - int ip_hdr_offset = 0; - TAILQ_FOREACH(frag, &tracker->frags, next) { - SCLogDebug("frag %p, data_len %u, offset %u, pcap_cnt %"PRIu64, - frag, frag->data_len, frag->offset, frag->pcap_cnt); - - if (frag->skip) - continue; - if (frag->data_len - frag->ltrim <= 0) - continue; - if (frag->offset == 0) { - - if (PacketCopyData(rp, frag->pkt, frag->len) == -1) - goto error_remove_tracker; - - hlen = frag->hlen; - ip_hdr_offset = frag->ip_hdr_offset; - - /* This is the start of the fragmentable portion of the - * first packet. All fragment offsets are relative to - * this. */ - fragmentable_offset = frag->ip_hdr_offset + frag->hlen; - fragmentable_len = frag->data_len; - } - else { - int pkt_end = fragmentable_offset + frag->offset + frag->data_len; - if (pkt_end > (int)MAX_PAYLOAD_SIZE) { - SCLogWarning(SC_ERR_REASSEMBLY, "Failed re-assemble " - "fragmented packet, exceeds size of packet buffer."); - goto error_remove_tracker; - } - if (PacketCopyDataOffset(rp, fragmentable_offset + frag->offset + frag->ltrim, - frag->pkt + frag->data_offset + frag->ltrim, - frag->data_len - frag->ltrim) == -1) { - goto error_remove_tracker; - } - if (frag->offset + frag->data_len > fragmentable_len) - fragmentable_len = frag->offset + frag->data_len; - } - - if (!frag->more_frags) { - break; - } - } - - SCLogDebug("ip_hdr_offset %u, hlen %u, fragmentable_len %u", - ip_hdr_offset, hlen, fragmentable_len); - - rp->ip4h = (IPV4Hdr *)(GET_PKT_DATA(rp) + ip_hdr_offset); - int old = rp->ip4h->ip_len + rp->ip4h->ip_off; - rp->ip4h->ip_len = htons(fragmentable_len + hlen); - rp->ip4h->ip_off = 0; - rp->ip4h->ip_csum = FixChecksum(rp->ip4h->ip_csum, - old, rp->ip4h->ip_len + rp->ip4h->ip_off); - SET_PKT_LEN(rp, ip_hdr_offset + hlen + fragmentable_len); - - tracker->remove = 1; - DefragTrackerFreeFrags(tracker); -done: - return rp; - -error_remove_tracker: - tracker->remove = 1; - DefragTrackerFreeFrags(tracker); - if (rp != NULL) - PacketFreeOrRelease(rp); - return NULL; -} - -/** - * Attempt to re-assemble a packet. - * - * \param tracker The defragmentation tracker to reassemble from. - */ -static Packet * -Defrag6Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p) -{ - Packet *rp = NULL; - - /* Should not be here unless we have seen the last fragment. */ - if (!tracker->seen_last) - return NULL; - - /* Check that we have all the data. Relies on the fact that - * fragments are inserted if frag_offset order. */ - Frag *frag; - int len = 0; - TAILQ_FOREACH(frag, &tracker->frags, next) { - if (frag->skip) - continue; - - if (frag == TAILQ_FIRST(&tracker->frags)) { - if (frag->offset != 0) { - goto done; - } - len = frag->data_len; - } - else { - if (frag->offset > len) { - /* This fragment starts after the end of the previous - * fragment. We have a hole. */ - goto done; - } - else { - len += frag->data_len; - } - } - } - - /* Allocate a Packet for the reassembled packet. On failure we - * SCFree all the resources held by this tracker. */ - rp = PacketDefragPktSetup(p, (uint8_t *)p->ip6h, - IPV6_GET_PLEN(p) + sizeof(IPV6Hdr), 0); - if (rp == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate packet for " - "fragmentation re-assembly, dumping fragments."); - goto error_remove_tracker; - } - PKT_SET_SRC(rp, PKT_SRC_DEFRAG); - - int unfragmentable_len = 0; - int fragmentable_offset = 0; - int fragmentable_len = 0; - int ip_hdr_offset = 0; - uint8_t next_hdr = 0; - TAILQ_FOREACH(frag, &tracker->frags, next) { - if (frag->skip) - continue; - if (frag->data_len - frag->ltrim <= 0) - continue; - if (frag->offset == 0) { - IPV6FragHdr *frag_hdr = (IPV6FragHdr *)(frag->pkt + - frag->frag_hdr_offset); - next_hdr = frag_hdr->ip6fh_nxt; - - /* This is the first packet, we use this packets link and - * IPv6 headers. We also copy in its data, but remove the - * fragmentation header. */ - if (PacketCopyData(rp, frag->pkt, frag->frag_hdr_offset) == -1) - goto error_remove_tracker; - if (PacketCopyDataOffset(rp, frag->frag_hdr_offset, - frag->pkt + frag->frag_hdr_offset + sizeof(IPV6FragHdr), - frag->data_len) == -1) - goto error_remove_tracker; - ip_hdr_offset = frag->ip_hdr_offset; - - /* This is the start of the fragmentable portion of the - * first packet. All fragment offsets are relative to - * this. */ - fragmentable_offset = frag->frag_hdr_offset; - fragmentable_len = frag->data_len; - - /* unfragmentable part is the part between the ipv6 header - * and the frag header. */ - unfragmentable_len = (fragmentable_offset - ip_hdr_offset) - IPV6_HEADER_LEN; - if (unfragmentable_len >= fragmentable_offset) - goto error_remove_tracker; - } - else { - if (PacketCopyDataOffset(rp, fragmentable_offset + frag->offset + frag->ltrim, - frag->pkt + frag->data_offset + frag->ltrim, - frag->data_len - frag->ltrim) == -1) - goto error_remove_tracker; - if (frag->offset + frag->data_len > fragmentable_len) - fragmentable_len = frag->offset + frag->data_len; - } - - if (!frag->more_frags) { - break; - } - } - - rp->ip6h = (IPV6Hdr *)(GET_PKT_DATA(rp) + ip_hdr_offset); - rp->ip6h->s_ip6_plen = htons(fragmentable_len + unfragmentable_len); - /* if we have no unfragmentable part, so no ext hdrs before the frag - * header, we need to update the ipv6 headers next header field. This - * points to the frag header, and we will make it point to the layer - * directly after the frag header. */ - if (unfragmentable_len == 0) - rp->ip6h->s_ip6_nxt = next_hdr; - SET_PKT_LEN(rp, ip_hdr_offset + sizeof(IPV6Hdr) + - unfragmentable_len + fragmentable_len); - - tracker->remove = 1; - DefragTrackerFreeFrags(tracker); -done: - return rp; - -error_remove_tracker: - tracker->remove = 1; - DefragTrackerFreeFrags(tracker); - if (rp != NULL) - PacketFreeOrRelease(rp); - return NULL; -} - -/** - * Insert a new IPv4/IPv6 fragment into a tracker. - * - * \todo Allocate packet buffers from a pool. - */ -static Packet * -DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker, Packet *p, PacketQueue *pq) -{ - Packet *r = NULL; - int ltrim = 0; - - uint8_t more_frags; - uint16_t frag_offset; - - /* IPv4 header length - IPv4 only. */ - uint16_t hlen = 0; - - /* This is the offset of the start of the data in the packet that - * falls after the IP header. */ - uint16_t data_offset; - - /* The length of the (fragmented) data. This is the length of the - * data that falls after the IP header. */ - uint16_t data_len; - - /* Where the fragment ends. */ - uint16_t frag_end; - - /* Offset in the packet to the IPv6 header. */ - uint16_t ip_hdr_offset; - - /* Offset in the packet to the IPv6 frag header. IPv6 only. */ - uint16_t frag_hdr_offset = 0; - - /* Address family */ - int af = tracker->af; - - /* settings for updating a payload when an ip6 fragment with - * unfragmentable exthdrs are encountered. */ - int ip6_nh_set_offset = 0; - uint8_t ip6_nh_set_value = 0; - -#ifdef DEBUG - uint64_t pcap_cnt = p->pcap_cnt; -#endif - - if (tracker->af == AF_INET) { - more_frags = IPV4_GET_MF(p); - frag_offset = IPV4_GET_IPOFFSET(p) << 3; - hlen = IPV4_GET_HLEN(p); - data_offset = (uint8_t *)p->ip4h + hlen - GET_PKT_DATA(p); - data_len = IPV4_GET_IPLEN(p) - hlen; - frag_end = frag_offset + data_len; - ip_hdr_offset = (uint8_t *)p->ip4h - GET_PKT_DATA(p); - - /* Ignore fragment if the end of packet extends past the - * maximum size of a packet. */ - if (IPV4_HEADER_LEN + frag_offset + data_len > IPV4_MAXPACKET_LEN) { - ENGINE_SET_EVENT(p, IPV4_FRAG_PKT_TOO_LARGE); - return NULL; - } - } - else if (tracker->af == AF_INET6) { - more_frags = IPV6_EXTHDR_GET_FH_FLAG(p); - frag_offset = IPV6_EXTHDR_GET_FH_OFFSET(p); - data_offset = (uint8_t *)p->ip6eh.ip6fh + sizeof(IPV6FragHdr) - GET_PKT_DATA(p); - data_len = IPV6_GET_PLEN(p) - ( - ((uint8_t *)p->ip6eh.ip6fh + sizeof(IPV6FragHdr)) - - ((uint8_t *)p->ip6h + sizeof(IPV6Hdr))); - frag_end = frag_offset + data_len; - ip_hdr_offset = (uint8_t *)p->ip6h - GET_PKT_DATA(p); - frag_hdr_offset = (uint8_t *)p->ip6eh.ip6fh - GET_PKT_DATA(p); - - /* handle unfragmentable exthdrs */ - if (ip_hdr_offset + IPV6_HEADER_LEN < frag_hdr_offset) { - SCLogDebug("we have exthdrs before fraghdr %u bytes (%u hdrs total)", - (uint32_t)(frag_hdr_offset - (ip_hdr_offset + IPV6_HEADER_LEN)), - p->ip6eh.ip6_exthdrs_cnt); - - /* get the offset of the 'next' field in exthdr before the FH, - * relative to the buffer start */ - int t_offset = (int)((p->ip6eh.ip6_exthdrs[p->ip6eh.ip6_exthdrs_cnt - 2].data - 2) - GET_PKT_DATA(p)); - - /* store offset and FH 'next' value for updating frag buffer below */ - ip6_nh_set_offset = (int)t_offset; - ip6_nh_set_value = IPV6_EXTHDR_GET_FH_NH(p); - SCLogDebug("offset %d, value %u", ip6_nh_set_offset, ip6_nh_set_value); - } - - /* Ignore fragment if the end of packet extends past the - * maximum size of a packet. */ - if (frag_offset + data_len > IPV6_MAXPACKET) { - ENGINE_SET_EVENT(p, IPV6_FRAG_PKT_TOO_LARGE); - return NULL; - } - } - else { - /* Abort - should not happen. */ - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid address family, aborting."); - return NULL; - } - - /* Update timeout. */ - tracker->timeout.tv_sec = p->ts.tv_sec + tracker->host_timeout; - tracker->timeout.tv_usec = p->ts.tv_usec; - - Frag *prev = NULL, *next; - int overlap = 0; - if (!TAILQ_EMPTY(&tracker->frags)) { - TAILQ_FOREACH(prev, &tracker->frags, next) { - ltrim = 0; - next = TAILQ_NEXT(prev, next); - - switch (tracker->policy) { - case DEFRAG_POLICY_BSD: - if (frag_offset < prev->offset + prev->data_len) { - if (frag_offset >= prev->offset) { - ltrim = prev->offset + prev->data_len - frag_offset; - overlap++; - } - if ((next != NULL) && (frag_end > next->offset)) { - next->ltrim = frag_end - next->offset; - overlap++; - } - if ((frag_offset < prev->offset) && - (frag_end >= prev->offset + prev->data_len)) { - prev->skip = 1; - overlap++; - } - goto insert; - } - break; - case DEFRAG_POLICY_LINUX: - if (frag_offset < prev->offset + prev->data_len) { - if (frag_offset > prev->offset) { - ltrim = prev->offset + prev->data_len - frag_offset; - overlap++; - } - if ((next != NULL) && (frag_end > next->offset)) { - next->ltrim = frag_end - next->offset; - overlap++; - } - if ((frag_offset < prev->offset) && - (frag_end >= prev->offset + prev->data_len)) { - prev->skip = 1; - overlap++; - } - goto insert; - } - break; - case DEFRAG_POLICY_WINDOWS: - if (frag_offset < prev->offset + prev->data_len) { - if (frag_offset >= prev->offset) { - ltrim = prev->offset + prev->data_len - frag_offset; - overlap++; - } - if ((frag_offset < prev->offset) && - (frag_end > prev->offset + prev->data_len)) { - prev->skip = 1; - overlap++; - } - goto insert; - } - break; - case DEFRAG_POLICY_SOLARIS: - if (frag_offset < prev->offset + prev->data_len) { - if (frag_offset >= prev->offset) { - ltrim = prev->offset + prev->data_len - frag_offset; - overlap++; - } - if ((frag_offset < prev->offset) && - (frag_end >= prev->offset + prev->data_len)) { - prev->skip = 1; - overlap++; - } - goto insert; - } - break; - case DEFRAG_POLICY_FIRST: - if ((frag_offset >= prev->offset) && - (frag_end <= prev->offset + prev->data_len)) { - overlap++; - goto done; - } - if (frag_offset < prev->offset) { - goto insert; - } - if (frag_offset < prev->offset + prev->data_len) { - ltrim = prev->offset + prev->data_len - frag_offset; - overlap++; - goto insert; - } - break; - case DEFRAG_POLICY_LAST: - if (frag_offset <= prev->offset) { - if (frag_end > prev->offset) { - prev->ltrim = frag_end - prev->offset; - overlap++; - } - goto insert; - } - break; - default: - break; - } - } - } - -insert: - if (data_len - ltrim <= 0) { - if (af == AF_INET) { - ENGINE_SET_EVENT(p, IPV4_FRAG_TOO_LARGE); - } else { - ENGINE_SET_EVENT(p, IPV6_FRAG_TOO_LARGE); - } - goto done; - } - - /* Allocate fragment and insert. */ - SCMutexLock(&defrag_context->frag_pool_lock); - Frag *new = PoolGet(defrag_context->frag_pool); - SCMutexUnlock(&defrag_context->frag_pool_lock); - if (new == NULL) { - if (af == AF_INET) { - ENGINE_SET_EVENT(p, IPV4_FRAG_IGNORED); - } else { - ENGINE_SET_EVENT(p, IPV6_FRAG_IGNORED); - } - goto done; - } - new->pkt = SCMalloc(GET_PKT_LEN(p)); - if (new->pkt == NULL) { - SCMutexLock(&defrag_context->frag_pool_lock); - PoolReturn(defrag_context->frag_pool, new); - SCMutexUnlock(&defrag_context->frag_pool_lock); - if (af == AF_INET) { - ENGINE_SET_EVENT(p, IPV4_FRAG_IGNORED); - } else { - ENGINE_SET_EVENT(p, IPV6_FRAG_IGNORED); - } - goto done; - } - memcpy(new->pkt, GET_PKT_DATA(p) + ltrim, GET_PKT_LEN(p) - ltrim); - new->len = GET_PKT_LEN(p) - ltrim; - /* in case of unfragmentable exthdrs, update the 'next hdr' field - * in the raw buffer so the reassembled packet will point to the - * correct next header after stripping the frag header */ - if (ip6_nh_set_offset > 0 && frag_offset == 0 && ltrim == 0) { - if (new->len > ip6_nh_set_offset) { - SCLogDebug("updating frag to have 'correct' nh value: %u -> %u", - new->pkt[ip6_nh_set_offset], ip6_nh_set_value); - new->pkt[ip6_nh_set_offset] = ip6_nh_set_value; - } - } - - new->hlen = hlen; - new->offset = frag_offset + ltrim; - new->data_offset = data_offset; - new->data_len = data_len - ltrim; - new->ip_hdr_offset = ip_hdr_offset; - new->frag_hdr_offset = frag_hdr_offset; - new->more_frags = more_frags; -#ifdef DEBUG - new->pcap_cnt = pcap_cnt; -#endif - - Frag *frag; - TAILQ_FOREACH(frag, &tracker->frags, next) { - if (new->offset < frag->offset) - break; - } - if (frag == NULL) { - TAILQ_INSERT_TAIL(&tracker->frags, new, next); - } - else { - TAILQ_INSERT_BEFORE(frag, new, next); - } - - if (!more_frags) { - tracker->seen_last = 1; - } - - if (tracker->seen_last) { - if (tracker->af == AF_INET) { - r = Defrag4Reassemble(tv, tracker, p); - if (r != NULL && tv != NULL && dtv != NULL) { - StatsIncr(tv, dtv->counter_defrag_ipv4_reassembled); - if (pq && DecodeIPV4(tv, dtv, r, (void *)r->ip4h, - IPV4_GET_IPLEN(r), pq) != TM_ECODE_OK) { - TmqhOutputPacketpool(tv, r); - } else { - PacketDefragPktSetupParent(p); - } - } - } - else if (tracker->af == AF_INET6) { - r = Defrag6Reassemble(tv, tracker, p); - if (r != NULL && tv != NULL && dtv != NULL) { - StatsIncr(tv, dtv->counter_defrag_ipv6_reassembled); - if (pq && DecodeIPV6(tv, dtv, r, (uint8_t *)r->ip6h, - IPV6_GET_PLEN(r) + IPV6_HEADER_LEN, - pq) != TM_ECODE_OK) { - TmqhOutputPacketpool(tv, r); - } else { - PacketDefragPktSetupParent(p); - } - } - } - } - - -done: - if (overlap) { - if (af == AF_INET) { - ENGINE_SET_EVENT(p, IPV4_FRAG_OVERLAP); - } - else { - ENGINE_SET_EVENT(p, IPV6_FRAG_OVERLAP); - } - } - return r; -} - -/** - * \brief Get the defrag policy based on the destination address of - * the packet. - * - * \param p The packet used to get the destination address. - * - * \retval The defrag policy to use. - */ -uint8_t -DefragGetOsPolicy(Packet *p) -{ - int policy = -1; - - if (PKT_IS_IPV4(p)) { - policy = SCHInfoGetIPv4HostOSFlavour((uint8_t *)GET_IPV4_DST_ADDR_PTR(p)); - } - else if (PKT_IS_IPV6(p)) { - policy = SCHInfoGetIPv6HostOSFlavour((uint8_t *)GET_IPV6_DST_ADDR(p)); - } - - if (policy == -1) { - return default_policy; - } - - /* Map the OS policies returned from the configured host info to - * defrag specific policies. */ - switch (policy) { - /* BSD. */ - case OS_POLICY_BSD: - case OS_POLICY_HPUX10: - case OS_POLICY_IRIX: - return DEFRAG_POLICY_BSD; - - /* BSD-Right. */ - case OS_POLICY_BSD_RIGHT: - return DEFRAG_POLICY_BSD_RIGHT; - - /* Linux. */ - case OS_POLICY_OLD_LINUX: - case OS_POLICY_LINUX: - return DEFRAG_POLICY_LINUX; - - /* First. */ - case OS_POLICY_OLD_SOLARIS: - case OS_POLICY_HPUX11: - case OS_POLICY_MACOS: - case OS_POLICY_FIRST: - return DEFRAG_POLICY_FIRST; - - /* Solaris. */ - case OS_POLICY_SOLARIS: - return DEFRAG_POLICY_SOLARIS; - - /* Windows. */ - case OS_POLICY_WINDOWS: - case OS_POLICY_VISTA: - case OS_POLICY_WINDOWS2K3: - return DEFRAG_POLICY_WINDOWS; - - /* Last. */ - case OS_POLICY_LAST: - return DEFRAG_POLICY_LAST; - - default: - return default_policy; - } -} - -/** \internal - * - * \retval NULL or a *LOCKED* tracker */ -static DefragTracker * -DefragGetTracker(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p) -{ - return DefragGetTrackerFromHash(p); -} - -/** - * \brief Entry point for IPv4 and IPv6 fragments. - * - * \param tv ThreadVars for the calling decoder. - * \param p The packet fragment. - * - * \retval A new Packet resembling the re-assembled packet if the most - * recent fragment allowed the packet to be re-assembled, otherwise - * NULL is returned. - */ -Packet * -Defrag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, PacketQueue *pq) -{ - uint16_t frag_offset; - uint8_t more_frags; - DefragTracker *tracker; - int af; - - if (PKT_IS_IPV4(p)) { - af = AF_INET; - more_frags = IPV4_GET_MF(p); - frag_offset = IPV4_GET_IPOFFSET(p); - } - else if (PKT_IS_IPV6(p)) { - af = AF_INET6; - frag_offset = IPV6_EXTHDR_GET_FH_OFFSET(p); - more_frags = IPV6_EXTHDR_GET_FH_FLAG(p); - } - else { - return NULL; - } - - if (frag_offset == 0 && more_frags == 0) { - return NULL; - } - - if (tv != NULL && dtv != NULL) { - if (af == AF_INET) { - StatsIncr(tv, dtv->counter_defrag_ipv4_fragments); - } - else if (af == AF_INET6) { - StatsIncr(tv, dtv->counter_defrag_ipv6_fragments); - } - } - - /* return a locked tracker or NULL */ - tracker = DefragGetTracker(tv, dtv, p); - if (tracker == NULL) - return NULL; - - Packet *rp = DefragInsertFrag(tv, dtv, tracker, p, pq); - DefragTrackerRelease(tracker); - - return rp; -} - -void -DefragInit(void) -{ - intmax_t tracker_pool_size; - if (!ConfGetInt("defrag.trackers", &tracker_pool_size)) { - tracker_pool_size = DEFAULT_DEFRAG_HASH_SIZE; - } - - /* Load the defrag-per-host lookup. */ - DefragPolicyLoadFromConfig(); - - /* Allocate the DefragContext. */ - defrag_context = DefragContextNew(); - if (defrag_context == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, - "Failed to allocate memory for the Defrag module."); - exit(EXIT_FAILURE); - } - - DefragSetDefaultTimeout(defrag_context->timeout); - DefragInitConfig(FALSE); -} - -void DefragDestroy(void) -{ - DefragHashShutdown(); - DefragContextDestroy(defrag_context); - defrag_context = NULL; -} - -#ifdef UNITTESTS -#define IP_MF 0x2000 - -/** - * Allocate a test packet. Nothing to fancy, just a simple IP packet - * with some payload of no particular protocol. - */ -static Packet * -BuildTestPacket(uint16_t id, uint16_t off, int mf, const char content, - int content_len) -{ - Packet *p = NULL; - int hlen = 20; - int ttl = 64; - uint8_t *pcontent; - IPV4Hdr ip4h; - - p = SCCalloc(1, sizeof(*p) + default_packet_size); - if (unlikely(p == NULL)) - return NULL; - - PACKET_INITIALIZE(p); - - gettimeofday(&p->ts, NULL); - //p->ip4h = (IPV4Hdr *)GET_PKT_DATA(p); - ip4h.ip_verhl = 4 << 4; - ip4h.ip_verhl |= hlen >> 2; - ip4h.ip_len = htons(hlen + content_len); - ip4h.ip_id = htons(id); - ip4h.ip_off = htons(off); - if (mf) - ip4h.ip_off = htons(IP_MF | off); - else - ip4h.ip_off = htons(off); - ip4h.ip_ttl = ttl; - ip4h.ip_proto = IPPROTO_ICMP; - - ip4h.s_ip_src.s_addr = 0x01010101; /* 1.1.1.1 */ - ip4h.s_ip_dst.s_addr = 0x02020202; /* 2.2.2.2 */ - - /* copy content_len crap, we need full length */ - PacketCopyData(p, (uint8_t *)&ip4h, sizeof(ip4h)); - p->ip4h = (IPV4Hdr *)GET_PKT_DATA(p); - SET_IPV4_SRC_ADDR(p, &p->src); - SET_IPV4_DST_ADDR(p, &p->dst); - - pcontent = SCCalloc(1, content_len); - if (unlikely(pcontent == NULL)) - return NULL; - memset(pcontent, content, content_len); - PacketCopyDataOffset(p, hlen, pcontent, content_len); - SET_PKT_LEN(p, hlen + content_len); - SCFree(pcontent); - - p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)GET_PKT_DATA(p), hlen); - - /* Self test. */ - if (IPV4_GET_VER(p) != 4) - goto error; - if (IPV4_GET_HLEN(p) != hlen) - goto error; - if (IPV4_GET_IPLEN(p) != hlen + content_len) - goto error; - if (IPV4_GET_IPID(p) != id) - goto error; - if (IPV4_GET_IPOFFSET(p) != off) - goto error; - if (IPV4_GET_MF(p) != mf) - goto error; - if (IPV4_GET_IPTTL(p) != ttl) - goto error; - if (IPV4_GET_IPPROTO(p) != IPPROTO_ICMP) - goto error; - - return p; -error: - if (p != NULL) - SCFree(p); - return NULL; -} - -static Packet * -IPV6BuildTestPacket(uint32_t id, uint16_t off, int mf, const char content, - int content_len) -{ - Packet *p = NULL; - uint8_t *pcontent; - IPV6Hdr ip6h; - - p = SCCalloc(1, sizeof(*p) + default_packet_size); - if (unlikely(p == NULL)) - return NULL; - - PACKET_INITIALIZE(p); - - gettimeofday(&p->ts, NULL); - - ip6h.s_ip6_nxt = 44; - ip6h.s_ip6_hlim = 2; - - /* Source and dest address - very bogus addresses. */ - ip6h.s_ip6_src[0] = 0x01010101; - ip6h.s_ip6_src[1] = 0x01010101; - ip6h.s_ip6_src[2] = 0x01010101; - ip6h.s_ip6_src[3] = 0x01010101; - ip6h.s_ip6_dst[0] = 0x02020202; - ip6h.s_ip6_dst[1] = 0x02020202; - ip6h.s_ip6_dst[2] = 0x02020202; - ip6h.s_ip6_dst[3] = 0x02020202; - - /* copy content_len crap, we need full length */ - PacketCopyData(p, (uint8_t *)&ip6h, sizeof(IPV6Hdr)); - - p->ip6h = (IPV6Hdr *)GET_PKT_DATA(p); - IPV6_SET_RAW_VER(p->ip6h, 6); - /* Fragmentation header. */ - IPV6FragHdr *fh = (IPV6FragHdr *)(GET_PKT_DATA(p) + sizeof(IPV6Hdr)); - fh->ip6fh_nxt = IPPROTO_ICMP; - fh->ip6fh_ident = htonl(id); - fh->ip6fh_offlg = htons((off << 3) | mf); - p->ip6eh.ip6fh = fh; - - pcontent = SCCalloc(1, content_len); - if (unlikely(pcontent == NULL)) - return NULL; - memset(pcontent, content, content_len); - PacketCopyDataOffset(p, sizeof(IPV6Hdr) + sizeof(IPV6FragHdr), pcontent, content_len); - SET_PKT_LEN(p, sizeof(IPV6Hdr) + sizeof(IPV6FragHdr) + content_len); - SCFree(pcontent); - - p->ip6h->s_ip6_plen = htons(sizeof(IPV6FragHdr) + content_len); - - SET_IPV6_SRC_ADDR(p, &p->src); - SET_IPV6_DST_ADDR(p, &p->dst); - - /* Self test. */ - if (IPV6_GET_VER(p) != 6) - goto error; - if (IPV6_GET_NH(p) != 44) - goto error; - if (IPV6_GET_PLEN(p) != sizeof(IPV6FragHdr) + content_len) - goto error; - - return p; -error: - fprintf(stderr, "Error building test packet.\n"); - if (p != NULL) - SCFree(p); - return NULL; -} - -/** - * Test the simplest possible re-assembly scenario. All packet in - * order and no overlaps. - */ -static int -DefragInOrderSimpleTest(void) -{ - Packet *p1 = NULL, *p2 = NULL, *p3 = NULL; - Packet *reassembled = NULL; - int id = 12; - int i; - int ret = 0; - - DefragInit(); - - p1 = BuildTestPacket(id, 0, 1, 'A', 8); - if (p1 == NULL) - goto end; - p2 = BuildTestPacket(id, 1, 1, 'B', 8); - if (p2 == NULL) - goto end; - p3 = BuildTestPacket(id, 2, 0, 'C', 3); - if (p3 == NULL) - goto end; - - if (Defrag(NULL, NULL, p1, NULL) != NULL) - goto end; - if (Defrag(NULL, NULL, p2, NULL) != NULL) - goto end; - - reassembled = Defrag(NULL, NULL, p3, NULL); - if (reassembled == NULL) { - goto end; - } - - if (IPV4_GET_HLEN(reassembled) != 20) { - goto end; - } - if (IPV4_GET_IPLEN(reassembled) != 39) { - goto end; - } - - /* 20 bytes in we should find 8 bytes of A. */ - for (i = 20; i < 20 + 8; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'A') { - goto end; - } - } - - /* 28 bytes in we should find 8 bytes of B. */ - for (i = 28; i < 28 + 8; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'B') { - goto end; - } - } - - /* And 36 bytes in we should find 3 bytes of C. */ - for (i = 36; i < 36 + 3; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'C') - goto end; - } - - ret = 1; - -end: - if (p1 != NULL) - SCFree(p1); - if (p2 != NULL) - SCFree(p2); - if (p3 != NULL) - SCFree(p3); - if (reassembled != NULL) - SCFree(reassembled); - - DefragDestroy(); - return ret; -} - -/** - * Simple fragmented packet in reverse order. - */ -static int -DefragReverseSimpleTest(void) -{ - Packet *p1 = NULL, *p2 = NULL, *p3 = NULL; - Packet *reassembled = NULL; - int id = 12; - int i; - int ret = 0; - - DefragInit(); - - p1 = BuildTestPacket(id, 0, 1, 'A', 8); - if (p1 == NULL) - goto end; - p2 = BuildTestPacket(id, 1, 1, 'B', 8); - if (p2 == NULL) - goto end; - p3 = BuildTestPacket(id, 2, 0, 'C', 3); - if (p3 == NULL) - goto end; - - if (Defrag(NULL, NULL, p3, NULL) != NULL) - goto end; - if (Defrag(NULL, NULL, p2, NULL) != NULL) - goto end; - - reassembled = Defrag(NULL, NULL, p1, NULL); - if (reassembled == NULL) - goto end; - - if (IPV4_GET_HLEN(reassembled) != 20) - goto end; - if (IPV4_GET_IPLEN(reassembled) != 39) - goto end; - - /* 20 bytes in we should find 8 bytes of A. */ - for (i = 20; i < 20 + 8; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'A') - goto end; - } - - /* 28 bytes in we should find 8 bytes of B. */ - for (i = 28; i < 28 + 8; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'B') - goto end; - } - - /* And 36 bytes in we should find 3 bytes of C. */ - for (i = 36; i < 36 + 3; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'C') - goto end; - } - - ret = 1; -end: - if (p1 != NULL) - SCFree(p1); - if (p2 != NULL) - SCFree(p2); - if (p3 != NULL) - SCFree(p3); - if (reassembled != NULL) - SCFree(reassembled); - - DefragDestroy(); - return ret; -} - -/** - * Test the simplest possible re-assembly scenario. All packet in - * order and no overlaps. - */ -static int -IPV6DefragInOrderSimpleTest(void) -{ - Packet *p1 = NULL, *p2 = NULL, *p3 = NULL; - Packet *reassembled = NULL; - int id = 12; - int i; - int ret = 0; - - DefragInit(); - - p1 = IPV6BuildTestPacket(id, 0, 1, 'A', 8); - if (p1 == NULL) - goto end; - p2 = IPV6BuildTestPacket(id, 1, 1, 'B', 8); - if (p2 == NULL) - goto end; - p3 = IPV6BuildTestPacket(id, 2, 0, 'C', 3); - if (p3 == NULL) - goto end; - - if (Defrag(NULL, NULL, p1, NULL) != NULL) - goto end; - if (Defrag(NULL, NULL, p2, NULL) != NULL) - goto end; - reassembled = Defrag(NULL, NULL, p3, NULL); - if (reassembled == NULL) - goto end; - - if (IPV6_GET_PLEN(reassembled) != 19) - goto end; - - /* 40 bytes in we should find 8 bytes of A. */ - for (i = 40; i < 40 + 8; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'A') - goto end; - } - - /* 28 bytes in we should find 8 bytes of B. */ - for (i = 48; i < 48 + 8; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'B') - goto end; - } - - /* And 36 bytes in we should find 3 bytes of C. */ - for (i = 56; i < 56 + 3; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'C') - goto end; - } - - ret = 1; -end: - if (p1 != NULL) - SCFree(p1); - if (p2 != NULL) - SCFree(p2); - if (p3 != NULL) - SCFree(p3); - if (reassembled != NULL) - SCFree(reassembled); - - DefragDestroy(); - return ret; -} - -static int -IPV6DefragReverseSimpleTest(void) -{ - DefragContext *dc = NULL; - Packet *p1 = NULL, *p2 = NULL, *p3 = NULL; - Packet *reassembled = NULL; - int id = 12; - int i; - int ret = 0; - - DefragInit(); - - dc = DefragContextNew(); - if (dc == NULL) - goto end; - - p1 = IPV6BuildTestPacket(id, 0, 1, 'A', 8); - if (p1 == NULL) - goto end; - p2 = IPV6BuildTestPacket(id, 1, 1, 'B', 8); - if (p2 == NULL) - goto end; - p3 = IPV6BuildTestPacket(id, 2, 0, 'C', 3); - if (p3 == NULL) - goto end; - - if (Defrag(NULL, NULL, p3, NULL) != NULL) - goto end; - if (Defrag(NULL, NULL, p2, NULL) != NULL) - goto end; - reassembled = Defrag(NULL, NULL, p1, NULL); - if (reassembled == NULL) - goto end; - - /* 40 bytes in we should find 8 bytes of A. */ - for (i = 40; i < 40 + 8; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'A') - goto end; - } - - /* 28 bytes in we should find 8 bytes of B. */ - for (i = 48; i < 48 + 8; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'B') - goto end; - } - - /* And 36 bytes in we should find 3 bytes of C. */ - for (i = 56; i < 56 + 3; i++) { - if (GET_PKT_DATA(reassembled)[i] != 'C') - goto end; - } - - ret = 1; -end: - if (dc != NULL) - DefragContextDestroy(dc); - if (p1 != NULL) - SCFree(p1); - if (p2 != NULL) - SCFree(p2); - if (p3 != NULL) - SCFree(p3); - if (reassembled != NULL) - SCFree(reassembled); - - DefragDestroy(); - return ret; -} - -static int -DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len) -{ - int i; - int ret = 0; - - DefragInit(); - - /* - * Build the packets. - */ - - int id = 1; - Packet *packets[17]; - memset(packets, 0x00, sizeof(packets)); - - /* - * Original fragments. - */ - - /* A*24 at 0. */ - packets[0] = BuildTestPacket(id, 0, 1, 'A', 24); - - /* B*15 at 32. */ - packets[1] = BuildTestPacket(id, 32 >> 3, 1, 'B', 16); - - /* C*24 at 48. */ - packets[2] = BuildTestPacket(id, 48 >> 3, 1, 'C', 24); - - /* D*8 at 80. */ - packets[3] = BuildTestPacket(id, 80 >> 3, 1, 'D', 8); - - /* E*16 at 104. */ - packets[4] = BuildTestPacket(id, 104 >> 3, 1, 'E', 16); - - /* F*24 at 120. */ - packets[5] = BuildTestPacket(id, 120 >> 3, 1, 'F', 24); - - /* G*16 at 144. */ - packets[6] = BuildTestPacket(id, 144 >> 3, 1, 'G', 16); - - /* H*16 at 160. */ - packets[7] = BuildTestPacket(id, 160 >> 3, 1, 'H', 16); - - /* I*8 at 176. */ - packets[8] = BuildTestPacket(id, 176 >> 3, 1, 'I', 8); - - /* - * Overlapping subsequent fragments. - */ - - /* J*32 at 8. */ - packets[9] = BuildTestPacket(id, 8 >> 3, 1, 'J', 32); - - /* K*24 at 48. */ - packets[10] = BuildTestPacket(id, 48 >> 3, 1, 'K', 24); - - /* L*24 at 72. */ - packets[11] = BuildTestPacket(id, 72 >> 3, 1, 'L', 24); - - /* M*24 at 96. */ - packets[12] = BuildTestPacket(id, 96 >> 3, 1, 'M', 24); - - /* N*8 at 128. */ - packets[13] = BuildTestPacket(id, 128 >> 3, 1, 'N', 8); - - /* O*8 at 152. */ - packets[14] = BuildTestPacket(id, 152 >> 3, 1, 'O', 8); - - /* P*8 at 160. */ - packets[15] = BuildTestPacket(id, 160 >> 3, 1, 'P', 8); - - /* Q*16 at 176. */ - packets[16] = BuildTestPacket(id, 176 >> 3, 0, 'Q', 16); - - default_policy = policy; - - /* Send all but the last. */ - for (i = 0; i < 9; i++) { - Packet *tp = Defrag(NULL, NULL, packets[i], NULL); - if (tp != NULL) { - SCFree(tp); - goto end; - } - if (ENGINE_ISSET_EVENT(packets[i], IPV4_FRAG_OVERLAP)) { - goto end; - } - } - int overlap = 0; - for (; i < 16; i++) { - Packet *tp = Defrag(NULL, NULL, packets[i], NULL); - if (tp != NULL) { - SCFree(tp); - goto end; - } - if (ENGINE_ISSET_EVENT(packets[i], IPV4_FRAG_OVERLAP)) { - overlap++; - } - } - if (!overlap) { - goto end; - } - - /* And now the last one. */ - Packet *reassembled = Defrag(NULL, NULL, packets[16], NULL); - if (reassembled == NULL) { - goto end; - } - - if (IPV4_GET_HLEN(reassembled) != 20) { - goto end; - } - if (IPV4_GET_IPLEN(reassembled) != 20 + 192) { - goto end; - } - - if (memcmp(GET_PKT_DATA(reassembled) + 20, expected, expected_len) != 0) { - goto end; - } - SCFree(reassembled); - - /* Make sure all frags were returned back to the pool. */ - if (defrag_context->frag_pool->outstanding != 0) { - goto end; - } - - ret = 1; -end: - for (i = 0; i < 17; i++) { - SCFree(packets[i]); - } - DefragDestroy(); - return ret; -} - -static int -IPV6DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len) -{ - int i; - int ret = 0; - - DefragInit(); - - /* - * Build the packets. - */ - - int id = 1; - Packet *packets[17]; - memset(packets, 0x00, sizeof(packets)); - - /* - * Original fragments. - */ - - /* A*24 at 0. */ - packets[0] = IPV6BuildTestPacket(id, 0, 1, 'A', 24); - - /* B*15 at 32. */ - packets[1] = IPV6BuildTestPacket(id, 32 >> 3, 1, 'B', 16); - - /* C*24 at 48. */ - packets[2] = IPV6BuildTestPacket(id, 48 >> 3, 1, 'C', 24); - - /* D*8 at 80. */ - packets[3] = IPV6BuildTestPacket(id, 80 >> 3, 1, 'D', 8); - - /* E*16 at 104. */ - packets[4] = IPV6BuildTestPacket(id, 104 >> 3, 1, 'E', 16); - - /* F*24 at 120. */ - packets[5] = IPV6BuildTestPacket(id, 120 >> 3, 1, 'F', 24); - - /* G*16 at 144. */ - packets[6] = IPV6BuildTestPacket(id, 144 >> 3, 1, 'G', 16); - - /* H*16 at 160. */ - packets[7] = IPV6BuildTestPacket(id, 160 >> 3, 1, 'H', 16); - - /* I*8 at 176. */ - packets[8] = IPV6BuildTestPacket(id, 176 >> 3, 1, 'I', 8); - - /* - * Overlapping subsequent fragments. - */ - - /* J*32 at 8. */ - packets[9] = IPV6BuildTestPacket(id, 8 >> 3, 1, 'J', 32); - - /* K*24 at 48. */ - packets[10] = IPV6BuildTestPacket(id, 48 >> 3, 1, 'K', 24); - - /* L*24 at 72. */ - packets[11] = IPV6BuildTestPacket(id, 72 >> 3, 1, 'L', 24); - - /* M*24 at 96. */ - packets[12] = IPV6BuildTestPacket(id, 96 >> 3, 1, 'M', 24); - - /* N*8 at 128. */ - packets[13] = IPV6BuildTestPacket(id, 128 >> 3, 1, 'N', 8); - - /* O*8 at 152. */ - packets[14] = IPV6BuildTestPacket(id, 152 >> 3, 1, 'O', 8); - - /* P*8 at 160. */ - packets[15] = IPV6BuildTestPacket(id, 160 >> 3, 1, 'P', 8); - - /* Q*16 at 176. */ - packets[16] = IPV6BuildTestPacket(id, 176 >> 3, 0, 'Q', 16); - - default_policy = policy; - - /* Send all but the last. */ - for (i = 0; i < 9; i++) { - Packet *tp = Defrag(NULL, NULL, packets[i], NULL); - if (tp != NULL) { - SCFree(tp); - goto end; - } - if (ENGINE_ISSET_EVENT(packets[i], IPV6_FRAG_OVERLAP)) { - goto end; - } - } - int overlap = 0; - for (; i < 16; i++) { - Packet *tp = Defrag(NULL, NULL, packets[i], NULL); - if (tp != NULL) { - SCFree(tp); - goto end; - } - if (ENGINE_ISSET_EVENT(packets[i], IPV6_FRAG_OVERLAP)) { - overlap++; - } - } - if (!overlap) - goto end; - - /* And now the last one. */ - Packet *reassembled = Defrag(NULL, NULL, packets[16], NULL); - if (reassembled == NULL) - goto end; - if (memcmp(GET_PKT_DATA(reassembled) + 40, expected, expected_len) != 0) - goto end; - - if (IPV6_GET_PLEN(reassembled) != 192) - goto end; - - SCFree(reassembled); - - /* Make sure all frags were returned to the pool. */ - if (defrag_context->frag_pool->outstanding != 0) { - printf("defrag_context->frag_pool->outstanding %u: ", defrag_context->frag_pool->outstanding); - goto end; - } - - ret = 1; - -end: - for (i = 0; i < 17; i++) { - SCFree(packets[i]); - } - DefragDestroy(); - return ret; -} - -static int -DefragSturgesNovakBsdTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "JJJJJJJJ" - "BBBBBBBB" - "CCCCCCCC" - "CCCCCCCC" - "CCCCCCCC" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "MMMMMMMM" - "MMMMMMMM" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "HHHHHHHH" - "HHHHHHHH" - "IIIIIIII" - "QQQQQQQQ" - }; - - return DefragDoSturgesNovakTest(DEFRAG_POLICY_BSD, expected, sizeof(expected)); -} - -static int -IPV6DefragSturgesNovakBsdTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "JJJJJJJJ" - "BBBBBBBB" - "CCCCCCCC" - "CCCCCCCC" - "CCCCCCCC" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "MMMMMMMM" - "MMMMMMMM" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "HHHHHHHH" - "HHHHHHHH" - "IIIIIIII" - "QQQQQQQQ" - }; - - return IPV6DefragDoSturgesNovakTest(DEFRAG_POLICY_BSD, expected, sizeof(expected)); -} - -static int -DefragSturgesNovakLinuxTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "JJJJJJJJ" - "BBBBBBBB" - "KKKKKKKK" - "KKKKKKKK" - "KKKKKKKK" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "MMMMMMMM" - "MMMMMMMM" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "PPPPPPPP" - "HHHHHHHH" - "QQQQQQQQ" - "QQQQQQQQ" - }; - - return DefragDoSturgesNovakTest(DEFRAG_POLICY_LINUX, expected, sizeof(expected)); -} - -static int -IPV6DefragSturgesNovakLinuxTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "JJJJJJJJ" - "BBBBBBBB" - "KKKKKKKK" - "KKKKKKKK" - "KKKKKKKK" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "MMMMMMMM" - "MMMMMMMM" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "PPPPPPPP" - "HHHHHHHH" - "QQQQQQQQ" - "QQQQQQQQ" - }; - - return IPV6DefragDoSturgesNovakTest(DEFRAG_POLICY_LINUX, expected, - sizeof(expected)); -} - -static int -DefragSturgesNovakWindowsTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "BBBBBBBB" - "BBBBBBBB" - "CCCCCCCC" - "CCCCCCCC" - "CCCCCCCC" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "EEEEEEEE" - "EEEEEEEE" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "HHHHHHHH" - "HHHHHHHH" - "IIIIIIII" - "QQQQQQQQ" - }; - - return DefragDoSturgesNovakTest(DEFRAG_POLICY_WINDOWS, expected, sizeof(expected)); -} - -static int -IPV6DefragSturgesNovakWindowsTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "BBBBBBBB" - "BBBBBBBB" - "CCCCCCCC" - "CCCCCCCC" - "CCCCCCCC" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "EEEEEEEE" - "EEEEEEEE" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "HHHHHHHH" - "HHHHHHHH" - "IIIIIIII" - "QQQQQQQQ" - }; - - return IPV6DefragDoSturgesNovakTest(DEFRAG_POLICY_WINDOWS, expected, - sizeof(expected)); -} - -static int -DefragSturgesNovakSolarisTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "BBBBBBBB" - "BBBBBBBB" - "CCCCCCCC" - "CCCCCCCC" - "CCCCCCCC" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "MMMMMMMM" - "MMMMMMMM" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "HHHHHHHH" - "HHHHHHHH" - "IIIIIIII" - "QQQQQQQQ" - }; - - return DefragDoSturgesNovakTest(DEFRAG_POLICY_SOLARIS, expected, sizeof(expected)); -} - -static int -IPV6DefragSturgesNovakSolarisTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "BBBBBBBB" - "BBBBBBBB" - "CCCCCCCC" - "CCCCCCCC" - "CCCCCCCC" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "MMMMMMMM" - "MMMMMMMM" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "HHHHHHHH" - "HHHHHHHH" - "IIIIIIII" - "QQQQQQQQ" - }; - - return IPV6DefragDoSturgesNovakTest(DEFRAG_POLICY_SOLARIS, expected, - sizeof(expected)); -} - -static int -DefragSturgesNovakFirstTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "BBBBBBBB" - "BBBBBBBB" - "CCCCCCCC" - "CCCCCCCC" - "CCCCCCCC" - "LLLLLLLL" - "DDDDDDDD" - "LLLLLLLL" - "MMMMMMMM" - "EEEEEEEE" - "EEEEEEEE" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "HHHHHHHH" - "HHHHHHHH" - "IIIIIIII" - "QQQQQQQQ" - }; - - return DefragDoSturgesNovakTest(DEFRAG_POLICY_FIRST, expected, sizeof(expected)); -} - -static int -IPV6DefragSturgesNovakFirstTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "AAAAAAAA" - "AAAAAAAA" - "JJJJJJJJ" - "BBBBBBBB" - "BBBBBBBB" - "CCCCCCCC" - "CCCCCCCC" - "CCCCCCCC" - "LLLLLLLL" - "DDDDDDDD" - "LLLLLLLL" - "MMMMMMMM" - "EEEEEEEE" - "EEEEEEEE" - "FFFFFFFF" - "FFFFFFFF" - "FFFFFFFF" - "GGGGGGGG" - "GGGGGGGG" - "HHHHHHHH" - "HHHHHHHH" - "IIIIIIII" - "QQQQQQQQ" - }; - - return IPV6DefragDoSturgesNovakTest(DEFRAG_POLICY_FIRST, expected, - sizeof(expected)); -} - -static int -DefragSturgesNovakLastTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "JJJJJJJJ" - "JJJJJJJJ" - "JJJJJJJJ" - "JJJJJJJJ" - "BBBBBBBB" - "KKKKKKKK" - "KKKKKKKK" - "KKKKKKKK" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "MMMMMMMM" - "MMMMMMMM" - "FFFFFFFF" - "NNNNNNNN" - "FFFFFFFF" - "GGGGGGGG" - "OOOOOOOO" - "PPPPPPPP" - "HHHHHHHH" - "QQQQQQQQ" - "QQQQQQQQ" - }; - - return DefragDoSturgesNovakTest(DEFRAG_POLICY_LAST, expected, sizeof(expected)); -} - -static int -IPV6DefragSturgesNovakLastTest(void) -{ - /* Expected data. */ - u_char expected[] = { - "AAAAAAAA" - "JJJJJJJJ" - "JJJJJJJJ" - "JJJJJJJJ" - "JJJJJJJJ" - "BBBBBBBB" - "KKKKKKKK" - "KKKKKKKK" - "KKKKKKKK" - "LLLLLLLL" - "LLLLLLLL" - "LLLLLLLL" - "MMMMMMMM" - "MMMMMMMM" - "MMMMMMMM" - "FFFFFFFF" - "NNNNNNNN" - "FFFFFFFF" - "GGGGGGGG" - "OOOOOOOO" - "PPPPPPPP" - "HHHHHHHH" - "QQQQQQQQ" - "QQQQQQQQ" - }; - - return IPV6DefragDoSturgesNovakTest(DEFRAG_POLICY_LAST, expected, - sizeof(expected)); -} - -static int -DefragTimeoutTest(void) -{ - int i; - int ret = 0; - - /* Setup a small numberr of trackers. */ - if (ConfSet("defrag.trackers", "16") != 1) { - printf("ConfSet failed: "); - goto end; - } - - DefragInit(); - - /* Load in 16 packets. */ - for (i = 0; i < 16; i++) { - Packet *p = BuildTestPacket(i, 0, 1, 'A' + i, 16); - if (p == NULL) - goto end; - - Packet *tp = Defrag(NULL, NULL, p, NULL); - - SCFree(p); - - if (tp != NULL) { - SCFree(tp); - goto end; - } - } - - /* Build a new packet but push the timestamp out by our timeout. - * This should force our previous fragments to be timed out. */ - Packet *p = BuildTestPacket(99, 0, 1, 'A' + i, 16); - if (p == NULL) - goto end; - - p->ts.tv_sec += (defrag_context->timeout + 1); - Packet *tp = Defrag(NULL, NULL, p, NULL); - - if (tp != NULL) { - SCFree(tp); - goto end; - } - - DefragTracker *tracker = DefragLookupTrackerFromHash(p); - if (tracker == NULL) - goto end; - - if (tracker->id != 99) - goto end; - - SCFree(p); - - ret = 1; -end: - DefragDestroy(); - return ret; -} - -/** - * QA found that if you send a packet where more frags is 0, offset is - * > 0 and there is no data in the packet that the re-assembler will - * fail. The fix was simple, but this unit test is just to make sure - * its not introduced. - */ -static int -DefragIPv4NoDataTest(void) -{ - DefragContext *dc = NULL; - Packet *p = NULL; - int id = 12; - int ret = 0; - - DefragInit(); - - dc = DefragContextNew(); - if (dc == NULL) - goto end; - - /* This packet has an offset > 0, more frags set to 0 and no data. */ - p = BuildTestPacket(id, 1, 0, 'A', 0); - if (p == NULL) - goto end; - - /* We do not expect a packet returned. */ - if (Defrag(NULL, NULL, p, NULL) != NULL) - goto end; - - /* The fragment should have been ignored so no fragments should - * have been allocated from the pool. */ - if (dc->frag_pool->outstanding != 0) - return 0; - - ret = 1; -end: - if (dc != NULL) - DefragContextDestroy(dc); - if (p != NULL) - SCFree(p); - - DefragDestroy(); - return ret; -} - -static int -DefragIPv4TooLargeTest(void) -{ - DefragContext *dc = NULL; - Packet *p = NULL; - int ret = 0; - - DefragInit(); - - dc = DefragContextNew(); - if (dc == NULL) - goto end; - - /* Create a fragment that would extend past the max allowable size - * for an IPv4 packet. */ - p = BuildTestPacket(1, 8183, 0, 'A', 71); - if (p == NULL) - goto end; - - /* We do not expect a packet returned. */ - if (Defrag(NULL, NULL, p, NULL) != NULL) - goto end; - if (!ENGINE_ISSET_EVENT(p, IPV4_FRAG_PKT_TOO_LARGE)) - goto end; - - /* The fragment should have been ignored so no fragments should have - * been allocated from the pool. */ - if (dc->frag_pool->outstanding != 0) - return 0; - - ret = 1; -end: - if (dc != NULL) - DefragContextDestroy(dc); - if (p != NULL) - SCFree(p); - - DefragDestroy(); - return ret; -} - -/** - * Test that fragments in different VLANs that would otherwise be - * re-assembled, are not re-assembled. Just use simple in-order - * fragments. - */ -static int -DefragVlanTest(void) -{ - Packet *p1 = NULL, *p2 = NULL, *r = NULL; - int ret = 0; - - DefragInit(); - - p1 = BuildTestPacket(1, 0, 1, 'A', 8); - if (p1 == NULL) - goto end; - p2 = BuildTestPacket(1, 1, 0, 'B', 8); - if (p2 == NULL) - goto end; - - /* With no VLAN IDs set, packets should re-assemble. */ - if ((r = Defrag(NULL, NULL, p1, NULL)) != NULL) - goto end; - if ((r = Defrag(NULL, NULL, p2, NULL)) == NULL) - goto end; - SCFree(r); - - /* With mismatched VLANs, packets should not re-assemble. */ - p1->vlan_id[0] = 1; - p2->vlan_id[0] = 2; - if ((r = Defrag(NULL, NULL, p1, NULL)) != NULL) - goto end; - if ((r = Defrag(NULL, NULL, p2, NULL)) != NULL) - goto end; - - /* Pass. */ - ret = 1; - -end: - if (p1 != NULL) - SCFree(p1); - if (p2 != NULL) - SCFree(p2); - DefragDestroy(); - - return ret; -} - -/** - * Like DefragVlanTest, but for QinQ, testing the second level VLAN ID. - */ -static int -DefragVlanQinQTest(void) -{ - Packet *p1 = NULL, *p2 = NULL, *r = NULL; - int ret = 0; - - DefragInit(); - - p1 = BuildTestPacket(1, 0, 1, 'A', 8); - if (p1 == NULL) - goto end; - p2 = BuildTestPacket(1, 1, 0, 'B', 8); - if (p2 == NULL) - goto end; - - /* With no VLAN IDs set, packets should re-assemble. */ - if ((r = Defrag(NULL, NULL, p1, NULL)) != NULL) - goto end; - if ((r = Defrag(NULL, NULL, p2, NULL)) == NULL) - goto end; - SCFree(r); - - /* With mismatched VLANs, packets should not re-assemble. */ - p1->vlan_id[0] = 1; - p2->vlan_id[0] = 1; - p1->vlan_id[1] = 1; - p2->vlan_id[1] = 2; - if ((r = Defrag(NULL, NULL, p1, NULL)) != NULL) - goto end; - if ((r = Defrag(NULL, NULL, p2, NULL)) != NULL) - goto end; - - /* Pass. */ - ret = 1; - -end: - if (p1 != NULL) - SCFree(p1); - if (p2 != NULL) - SCFree(p2); - DefragDestroy(); - - return ret; -} - -static int DefragTrackerReuseTest(void) -{ - int ret = 0; - int id = 1; - Packet *p1 = NULL; - DefragTracker *tracker1 = NULL, *tracker2 = NULL; - - DefragInit(); - - /* Build a packet, its not a fragment but shouldn't matter for - * this test. */ - p1 = BuildTestPacket(id, 0, 0, 'A', 8); - if (p1 == NULL) { - goto end; - } - - /* Get a tracker. It shouldn't look like its already in use. */ - tracker1 = DefragGetTracker(NULL, NULL, p1); - if (tracker1 == NULL) { - goto end; - } - if (tracker1->seen_last) { - goto end; - } - if (tracker1->remove) { - goto end; - } - DefragTrackerRelease(tracker1); - - /* Get a tracker again, it should be the same one. */ - tracker2 = DefragGetTracker(NULL, NULL, p1); - if (tracker2 == NULL) { - goto end; - } - if (tracker2 != tracker1) { - goto end; - } - DefragTrackerRelease(tracker1); - - /* Now mark the tracker for removal. It should not be returned - * when we get a tracker for a packet that may have the same - * attributes. */ - tracker1->remove = 1; - - tracker2 = DefragGetTracker(NULL, NULL, p1); - if (tracker2 == NULL) { - goto end; - } - if (tracker2 == tracker1) { - goto end; - } - if (tracker2->remove) { - goto end; - } - - ret = 1; -end: - if (p1 != NULL) { - SCFree(p1); - } - DefragDestroy(); - return ret; -} - -/** - * IPV4: Test the case where you have a packet fragmented in 3 parts - * and send like: - * - Offset: 2; MF: 1 - * - Offset: 0; MF: 1 - * - Offset: 1; MF: 0 - * - * Only the fragments with offset 0 and 1 should be reassembled. - */ -static int DefragMfIpv4Test(void) -{ - int retval = 0; - int ip_id = 9; - Packet *p = NULL; - - DefragInit(); - - Packet *p1 = BuildTestPacket(ip_id, 2, 1, 'C', 8); - Packet *p2 = BuildTestPacket(ip_id, 0, 1, 'A', 8); - Packet *p3 = BuildTestPacket(ip_id, 1, 0, 'B', 8); - if (p1 == NULL || p2 == NULL || p3 == NULL) { - goto end; - } - - p = Defrag(NULL, NULL, p1, NULL); - if (p != NULL) { - goto end; - } - - p = Defrag(NULL, NULL, p2, NULL); - if (p != NULL) { - goto end; - } - - /* This should return a packet as MF=0. */ - p = Defrag(NULL, NULL, p3, NULL); - if (p == NULL) { - goto end; - } - - /* Expected IP length is 20 + 8 + 8 = 36 as only 2 of the - * fragments should be in the re-assembled packet. */ - if (IPV4_GET_IPLEN(p) != 36) { - goto end; - } - - retval = 1; -end: - if (p1 != NULL) { - SCFree(p1); - } - if (p2 != NULL) { - SCFree(p2); - } - if (p3 != NULL) { - SCFree(p3); - } - if (p != NULL) { - SCFree(p); - } - DefragDestroy(); - return retval; -} - -/** - * IPV6: Test the case where you have a packet fragmented in 3 parts - * and send like: - * - Offset: 2; MF: 1 - * - Offset: 0; MF: 1 - * - Offset: 1; MF: 0 - * - * Only the fragments with offset 0 and 1 should be reassembled. - */ -static int DefragMfIpv6Test(void) -{ - int retval = 0; - int ip_id = 9; - Packet *p = NULL; - - DefragInit(); - - Packet *p1 = IPV6BuildTestPacket(ip_id, 2, 1, 'C', 8); - Packet *p2 = IPV6BuildTestPacket(ip_id, 0, 1, 'A', 8); - Packet *p3 = IPV6BuildTestPacket(ip_id, 1, 0, 'B', 8); - if (p1 == NULL || p2 == NULL || p3 == NULL) { - goto end; - } - - p = Defrag(NULL, NULL, p1, NULL); - if (p != NULL) { - goto end; - } - - p = Defrag(NULL, NULL, p2, NULL); - if (p != NULL) { - goto end; - } - - /* This should return a packet as MF=0. */ - p = Defrag(NULL, NULL, p3, NULL); - if (p == NULL) { - goto end; - } - - /* For IPv6 the expected length is just the length of the payload - * of 2 fragments, so 16. */ - if (IPV6_GET_PLEN(p) != 16) { - goto end; - } - - retval = 1; -end: - if (p1 != NULL) { - SCFree(p1); - } - if (p2 != NULL) { - SCFree(p2); - } - if (p3 != NULL) { - SCFree(p3); - } - if (p != NULL) { - SCFree(p); - } - DefragDestroy(); - return retval; -} - -#endif /* UNITTESTS */ - -void -DefragRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DefragInOrderSimpleTest", - DefragInOrderSimpleTest, 1); - UtRegisterTest("DefragReverseSimpleTest", - DefragReverseSimpleTest, 1); - UtRegisterTest("DefragSturgesNovakBsdTest", - DefragSturgesNovakBsdTest, 1); - UtRegisterTest("DefragSturgesNovakLinuxTest", - DefragSturgesNovakLinuxTest, 1); - UtRegisterTest("DefragSturgesNovakWindowsTest", - DefragSturgesNovakWindowsTest, 1); - UtRegisterTest("DefragSturgesNovakSolarisTest", - DefragSturgesNovakSolarisTest, 1); - UtRegisterTest("DefragSturgesNovakFirstTest", - DefragSturgesNovakFirstTest, 1); - UtRegisterTest("DefragSturgesNovakLastTest", - DefragSturgesNovakLastTest, 1); - - UtRegisterTest("DefragIPv4NoDataTest", DefragIPv4NoDataTest, 1); - UtRegisterTest("DefragIPv4TooLargeTest", DefragIPv4TooLargeTest, 1); - - UtRegisterTest("IPV6DefragInOrderSimpleTest", - IPV6DefragInOrderSimpleTest, 1); - UtRegisterTest("IPV6DefragReverseSimpleTest", - IPV6DefragReverseSimpleTest, 1); - UtRegisterTest("IPV6DefragSturgesNovakBsdTest", - IPV6DefragSturgesNovakBsdTest, 1); - UtRegisterTest("IPV6DefragSturgesNovakLinuxTest", - IPV6DefragSturgesNovakLinuxTest, 1); - UtRegisterTest("IPV6DefragSturgesNovakWindowsTest", - IPV6DefragSturgesNovakWindowsTest, 1); - UtRegisterTest("IPV6DefragSturgesNovakSolarisTest", - IPV6DefragSturgesNovakSolarisTest, 1); - UtRegisterTest("IPV6DefragSturgesNovakFirstTest", - IPV6DefragSturgesNovakFirstTest, 1); - UtRegisterTest("IPV6DefragSturgesNovakLastTest", - IPV6DefragSturgesNovakLastTest, 1); - - UtRegisterTest("DefragVlanTest", DefragVlanTest, 1); - UtRegisterTest("DefragVlanQinQTest", DefragVlanQinQTest, 1); - UtRegisterTest("DefragTrackerReuseTest", DefragTrackerReuseTest, 1); - UtRegisterTest("DefragTimeoutTest", - DefragTimeoutTest, 1); - UtRegisterTest("DefragMfIpv4Test", DefragMfIpv4Test, 1); - UtRegisterTest("DefragMfIpv6Test", DefragMfIpv6Test, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/defrag.h b/framework/src/suricata/src/defrag.h deleted file mode 100644 index 2dfaec60..00000000 --- a/framework/src/suricata/src/defrag.h +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited, Jason Ish - */ - -#ifndef __DEFRAG_H__ -#define __DEFRAG_H__ - -#include "util-pool.h" - -/** - * A context for an instance of a fragmentation re-assembler, in case - * we ever need more than one. - */ -typedef struct DefragContext_ { - Pool *frag_pool; /**< Pool of fragments. */ - SCMutex frag_pool_lock; - - time_t timeout; /**< Default timeout. */ -} DefragContext; - -/** - * Storage for an individual fragment. - */ -typedef struct Frag_ { - uint16_t offset; /**< The offset of this fragment, already - * multiplied by 8. */ - - uint16_t len; /**< The length of this fragment. */ - - uint8_t hlen; /**< The length of this fragments IP header. */ - - uint8_t more_frags:4; /**< More frags? */ - uint8_t skip:4; /**< Skip this fragment during re-assembly. */ - - uint16_t ip_hdr_offset; /**< Offset in the packet where the IP - * header starts. */ - uint16_t frag_hdr_offset; /**< Offset in the packet where the frag - * header starts. */ - - uint16_t data_offset; /**< Offset to the packet data. */ - uint16_t data_len; /**< Length of data. */ - - uint16_t ltrim; /**< Number of leading bytes to trim when - * re-assembling the packet. */ - - uint8_t *pkt; /**< The actual packet. */ - -#ifdef DEBUG - uint64_t pcap_cnt; /**< pcap_cnt of original packet */ -#endif - - TAILQ_ENTRY(Frag_) next; /**< Pointer to next fragment for tailq. */ -} Frag; - -/** - * A defragmentation tracker. Used to track fragments that make up a - * single packet. - */ -typedef struct DefragTracker_ { - SCMutex lock; /**< Mutex for locking list operations on - * this tracker. */ - - uint16_t vlan_id[2]; /**< VLAN ID tracker applies to. */ - - uint32_t id; /**< IP ID for this tracker. 32 bits for IPv6, 16 - * for IPv4. */ - - uint8_t policy; /**< Reassembly policy this tracker will use. */ - - uint8_t af; /**< Address family for this tracker, AF_INET or - * AF_INET6. */ - - uint8_t seen_last; /**< Has this tracker seen the last fragment? */ - - uint8_t remove; /**< remove */ - - Address src_addr; /**< Source address for this tracker. */ - Address dst_addr; /**< Destination address for this tracker. */ - - struct timeval timeout; /**< When this tracker will timeout. */ - uint32_t host_timeout; /**< Host timeout, statically assigned from the yaml */ - - /** use cnt, reference counter */ - SC_ATOMIC_DECLARE(unsigned int, use_cnt); - - TAILQ_HEAD(frag_tailq, Frag_) frags; /**< Head of list of fragments. */ - - /** hash pointers, protected by hash row mutex/spin */ - struct DefragTracker_ *hnext; - struct DefragTracker_ *hprev; - - /** list pointers, protected by tracker-queue mutex/spin */ - struct DefragTracker_ *lnext; - struct DefragTracker_ *lprev; -} DefragTracker; - -void DefragInit(void); -void DefragDestroy(void); -void DefragReload(void); /**< use only in unittests */ - -uint8_t DefragGetOsPolicy(Packet *); -void DefragTrackerFreeFrags(DefragTracker *); -Packet *Defrag(ThreadVars *, DecodeThreadVars *, Packet *, PacketQueue *); -void DefragRegisterTests(void); - -#endif /* __DEFRAG_H__ */ diff --git a/framework/src/suricata/src/detect-ack.c b/framework/src/suricata/src/detect-ack.c deleted file mode 100644 index 5a84c6f9..00000000 --- a/framework/src/suricata/src/detect-ack.c +++ /dev/null @@ -1,302 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - * - * Implements the "ack" keyword. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "detect-ack.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -/* prototypes */ -static int DetectAckSetup(DetectEngineCtx *, Signature *, char *); -static int DetectAckMatch(ThreadVars *, DetectEngineThreadCtx *, - Packet *, Signature *, const SigMatchCtx *); -static void DetectAckRegisterTests(void); -static void DetectAckFree(void *); - -void DetectAckRegister(void) -{ - sigmatch_table[DETECT_ACK].name = "ack"; - sigmatch_table[DETECT_ACK].desc = "check for a specific TCP acknowledgement number"; - sigmatch_table[DETECT_ACK].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#ack"; - sigmatch_table[DETECT_ACK].Match = DetectAckMatch; - sigmatch_table[DETECT_ACK].Setup = DetectAckSetup; - sigmatch_table[DETECT_ACK].Free = DetectAckFree; - sigmatch_table[DETECT_ACK].RegisterTests = DetectAckRegisterTests; -} - -/** - * \internal - * \brief This function is used to match packets with a given Ack number - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectAckData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectAckMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectAckData *data = (const DetectAckData *)ctx; - - /* This is only needed on TCP packets */ - if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) { - return 0; - } - - return (data->ack == TCP_GET_ACK(p)) ? 1 : 0; -} - -/** - * \internal - * \brief this function is used to add the ack option into the signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param m pointer to the Current SigMatch - * \param optstr pointer to the user provided options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectAckSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) -{ - DetectAckData *data = NULL; - SigMatch *sm = NULL; - - data = SCMalloc(sizeof(DetectAckData)); - if (unlikely(data == NULL)) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_ACK; - - if (-1 == ByteExtractStringUint32(&data->ack, 10, 0, optstr)) { - goto error; - } - sm->ctx = (SigMatchCtx*)data; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (data) - SCFree(data); - if (sm) - SigMatchFree(sm); - return -1; - -} - -/** - * \internal - * \brief this function will free memory associated with ack option - * - * \param data pointer to ack configuration data - */ -static void DetectAckFree(void *ptr) -{ - DetectAckData *data = (DetectAckData *)ptr; - SCFree(data); -} - - -#ifdef UNITTESTS -/** - * \internal - * \brief This test tests sameip success and failure. - */ -static int DetectAckSigTest01Real(int mpm_type) -{ - Packet *p1 = NULL; - Packet *p2 = NULL; - Packet *p3 = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - /* TCP w/ack=42 */ - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p1->tcph->th_ack = htonl(42); - - /* TCP w/ack=100 */ - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2->tcph->th_ack = htonl(100); - - /* ICMP */ - p3 = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - /* These three are crammed in here as there is no Parse */ - if (SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing ack\";ack:foo;sid:1;)") != NULL) - { - printf("invalid ack accepted: "); - goto cleanup_engine; - } - if (SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing ack\";ack:9999999999;sid:1;)") != NULL) - { - printf("overflowing ack accepted: "); - goto cleanup_engine; - } - if (SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing ack\";ack:-100;sid:1;)") != NULL) - { - printf("negative ack accepted: "); - goto cleanup_engine; - } - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing ack\";ack:41;sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto cleanup_engine; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing ack\";ack:42;sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - goto cleanup_engine; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1) != 0) { - printf("sid 1 alerted, but should not have: "); - goto cleanup; - } - if (PacketAlertCheck(p1, 2) == 0) { - printf("sid 2 did not alert, but should have: "); - goto cleanup; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 1) != 0) { - printf("sid 1 alerted, but should not have: "); - goto cleanup; - } - if (PacketAlertCheck(p2, 2) != 0) { - printf("sid 2 alerted, but should not have: "); - goto cleanup; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p3); - if (PacketAlertCheck(p3, 1) != 0) { - printf("sid 1 alerted, but should not have: "); - goto cleanup; - } - if (PacketAlertCheck(p3, 2) != 0) { - printf("sid 2 alerted, but should not have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -cleanup_engine: - DetectEngineCtxFree(de_ctx); - -end: - return result; -} - -/** - * \test DetectAckSigTest01B2g tests sameip under B2g MPM - */ -static int DetectAckSigTest01B2g(void) -{ - return DetectAckSigTest01Real(MPM_B2G); -} - -/** - * \test DetectAckSigTest01B2g tests sameip under B3g MPM - */ -static int DetectAckSigTest01B3g(void) -{ - return DetectAckSigTest01Real(MPM_B3G); -} - -/** - * \test DetectAckSigTest01B2g tests sameip under WuManber MPM - */ -static int DetectAckSigTest01Wm(void) -{ - return DetectAckSigTest01Real(MPM_WUMANBER); -} - -#endif /* UNITTESTS */ - -/** - * \internal - * \brief This function registers unit tests for DetectAck - */ -static void DetectAckRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectAckSigTest01B2g", DetectAckSigTest01B2g, 1); - UtRegisterTest("DetectAckSigTest01B3g", DetectAckSigTest01B3g, 1); - UtRegisterTest("DetectAckSigTest01Wm", DetectAckSigTest01Wm, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-ack.h b/framework/src/suricata/src/detect-ack.h deleted file mode 100644 index 6a8465b8..00000000 --- a/framework/src/suricata/src/detect-ack.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - */ - -#ifndef __DETECT_ACK_H__ -#define __DETECT_ACK_H__ - -/** - * \brief ack data - */ -typedef struct DetectAckData_ { - uint32_t ack; /**< ack to match */ -} DetectAckData; - -/** - * \brief Registration function for ack: keyword - */ -void DetectAckRegister(void); - -#endif /* __DETECT_ACK_H__ */ - diff --git a/framework/src/suricata/src/detect-app-layer-event.c b/framework/src/suricata/src/detect-app-layer-event.c deleted file mode 100644 index 63d40117..00000000 --- a/framework/src/suricata/src/detect-app-layer-event.c +++ /dev/null @@ -1,836 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-smtp.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-state.h" -#include "detect-app-layer-event.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "decode-events.h" -#include "util-byte.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - - -static int DetectAppLayerEventPktMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx); -static int DetectAppLayerEventAppMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t, void *, Signature *, SigMatch *); -static int DetectAppLayerEventSetupP1(DetectEngineCtx *, Signature *, char *); -static void DetectAppLayerEventRegisterTests(void); -static void DetectAppLayerEventFree(void *); - -/** - * \brief Registers the keyword handlers for the "app-layer-event" keyword. - */ -void DetectAppLayerEventRegister(void) -{ - sigmatch_table[DETECT_AL_APP_LAYER_EVENT].name = "app-layer-event"; - sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Match = - DetectAppLayerEventPktMatch; - sigmatch_table[DETECT_AL_APP_LAYER_EVENT].AppLayerMatch = - DetectAppLayerEventAppMatch; - sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Setup = DetectAppLayerEventSetupP1; - sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Free = DetectAppLayerEventFree; - sigmatch_table[DETECT_AL_APP_LAYER_EVENT].RegisterTests = - DetectAppLayerEventRegisterTests; - - return; -} - - -static int DetectAppLayerEventPktMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectAppLayerEventData *aled = (const DetectAppLayerEventData *)ctx; - - return AppLayerDecoderEventsIsEventSet(p->app_layer_events, - aled->event_id); -} - -static int DetectAppLayerEventAppMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, Signature *s, - SigMatch *m) -{ - SCEnter(); - AppLayerDecoderEvents *decoder_events = NULL; - int r = 0; - DetectAppLayerEventData *aled = (DetectAppLayerEventData *)m->ctx; - - if (r == 0) { - decoder_events = AppLayerParserGetDecoderEvents(f->alparser); - if (decoder_events != NULL && - AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) { - r = 1; - } - } - - SCReturnInt(r); -} - -static DetectAppLayerEventData *DetectAppLayerEventParsePkt(const char *arg, - AppLayerEventType *event_type) -{ - DetectAppLayerEventData *aled; - - int event_id = 0; - int r = 0; - - r = AppLayerGetPktEventInfo(arg, &event_id); - if (r < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword " - "supplied with packet based event - \"%s\" that isn't " - "supported yet.", arg); - return NULL; - } - - aled = SCMalloc(sizeof(DetectAppLayerEventData)); - if (unlikely(aled == NULL)) - return NULL; - memset(aled,0x00,sizeof(*aled)); - aled->event_id = event_id; - *event_type = APP_LAYER_EVENT_TYPE_PACKET; - - return aled; -} - -static int DetectAppLayerEventParseAppP2(DetectAppLayerEventData *data, - uint8_t *ipproto_bitarray, - AppLayerEventType *event_type) -{ - int event_id = 0; - const char *p_idx; - uint8_t ipproto; - char alproto_name[50]; - int r = 0; - - p_idx = strchr(data->arg, '.'); - strlcpy(alproto_name, data->arg, p_idx - data->arg + 1); - - if (ipproto_bitarray[IPPROTO_TCP / 8] & 1 << (IPPROTO_TCP % 8)) { - ipproto = IPPROTO_TCP; - } else if (ipproto_bitarray[IPPROTO_UDP / 8] & 1 << (IPPROTO_UDP % 8)) { - ipproto = IPPROTO_UDP; - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "protocol %s is disabled", alproto_name); - return -1; - } - - r = AppLayerParserGetEventInfo(ipproto, data->alproto, - p_idx + 1, &event_id, event_type); - if (r < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword's " - "protocol \"%s\" doesn't have event \"%s\" registered", - alproto_name, p_idx + 1); - return -1; - } - data->event_id = event_id; - - return 0; -} - -static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg) -{ - /* period index */ - DetectAppLayerEventData *aled; - AppProto alproto; - const char *p_idx; - char alproto_name[50]; - - p_idx = strchr(arg, '.'); - /* + 1 for trailing \0 */ - strlcpy(alproto_name, arg, p_idx - arg + 1); - - alproto = AppLayerGetProtoByName(alproto_name); - if (alproto == ALPROTO_UNKNOWN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword " - "supplied with unknown protocol \"%s\"", - alproto_name); - return NULL; - } - - aled = SCMalloc(sizeof(*aled)); - if (unlikely(aled == NULL)) - return NULL; - memset(aled, 0x00, sizeof(*aled)); - aled->alproto = alproto; - aled->arg = SCStrdup(arg); - if (aled->arg == NULL) { - SCFree(aled); - return NULL; - } - - return aled; -} - -static DetectAppLayerEventData *DetectAppLayerEventParse(const char *arg, - AppLayerEventType *event_type) -{ - *event_type = 0; - - if (arg == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword supplied " - "with no arguments. This keyword needs an argument."); - return NULL; - } - - while (*arg != '\0' && isspace((unsigned char)*arg)) - arg++; - - if (strchr(arg, '.') == NULL) { - return DetectAppLayerEventParsePkt(arg, event_type); - } else { - return DetectAppLayerEventParseAppP1(arg); - } -} - -static int DetectAppLayerEventSetupP2(Signature *s, - SigMatch *sm) -{ - AppLayerEventType event_type = 0; - - if (DetectAppLayerEventParseAppP2((DetectAppLayerEventData *)sm->ctx, s->proto.proto, - &event_type) < 0) { - /* DetectAppLayerEventParseAppP2 prints errors */ - return -1; - } - if (event_type == APP_LAYER_EVENT_TYPE_GENERAL) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - else - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_APP_EVENT); - /* We should have set this flag already in SetupP1 */ - s->flags |= SIG_FLAG_APPLAYER; - - return 0; -} - -static int DetectAppLayerEventSetupP1(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - DetectAppLayerEventData *data = NULL; - SigMatch *sm = NULL; - AppLayerEventType event_type; - - data = DetectAppLayerEventParse(arg, &event_type); - if (data == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_AL_APP_LAYER_EVENT; - sm->ctx = (SigMatchCtx *)data; - - if (s->alproto != ALPROTO_UNKNOWN) { - if (s->alproto != data->alproto) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains " - "conflicting keywords needing different alprotos"); - goto error; - } - } else { - s->alproto = data->alproto; - } - - if (event_type == APP_LAYER_EVENT_TYPE_PACKET) { - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - } else { - /* We push it to this list temporarily. We deal with - * these in DetectAppLayerEventPrepare(). */ - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_APP_EVENT); - s->flags |= SIG_FLAG_APPLAYER; - } - - return 0; - -error: - if (data) - SCFree(data); - if (sm) { - sm->ctx = NULL; - SigMatchFree(sm); - } - return -1; -} - -static void DetectAppLayerEventFree(void *ptr) -{ - DetectAppLayerEventData *data = (DetectAppLayerEventData *)ptr; - if (data->arg != NULL) - SCFree(data->arg); - - SCFree(ptr); - - return; -} - -int DetectAppLayerEventPrepare(Signature *s) -{ - SigMatch *sm = s->sm_lists[DETECT_SM_LIST_APP_EVENT]; - s->sm_lists[DETECT_SM_LIST_APP_EVENT] = NULL; - s->sm_lists_tail[DETECT_SM_LIST_APP_EVENT] = NULL; - - while (sm != NULL) { - sm->next = sm->prev = NULL; - if (DetectAppLayerEventSetupP2(s, sm) < 0) - return -1; - sm = sm->next; - } - - return 0; -} - -/**********************************Unittests***********************************/ - -#ifdef UNITTESTS /* UNITTESTS */ - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "app-layer.h" - -#define APP_LAYER_EVENT_TEST_MAP_EVENT1 0 -#define APP_LAYER_EVENT_TEST_MAP_EVENT2 1 -#define APP_LAYER_EVENT_TEST_MAP_EVENT3 2 -#define APP_LAYER_EVENT_TEST_MAP_EVENT4 3 -#define APP_LAYER_EVENT_TEST_MAP_EVENT5 4 -#define APP_LAYER_EVENT_TEST_MAP_EVENT6 5 - -SCEnumCharMap app_layer_event_test_map[ ] = { - { "event1", APP_LAYER_EVENT_TEST_MAP_EVENT1 }, - { "event2", APP_LAYER_EVENT_TEST_MAP_EVENT2 }, - { "event3", APP_LAYER_EVENT_TEST_MAP_EVENT3 }, - { "event4", APP_LAYER_EVENT_TEST_MAP_EVENT4 }, - { "event5", APP_LAYER_EVENT_TEST_MAP_EVENT5 }, - { "event6", APP_LAYER_EVENT_TEST_MAP_EVENT6 }, -}; - -static int DetectAppLayerEventTestGetEventInfo(const char *event_name, - int *event_id, - AppLayerEventType *event_type) -{ - *event_id = SCMapEnumNameToValue(event_name, app_layer_event_test_map); - if (*event_id == -1) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in " - "app-layer-event's test enum map table.", event_name); - /* this should be treated as fatal */ - return -1; - } - - *event_type = APP_LAYER_EVENT_TYPE_GENERAL; - - return 0; -} - - -int DetectAppLayerEventTest01(void) -{ - AppLayerParserBackupParserTable(); - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_SMTP, - DetectAppLayerEventTestGetEventInfo); - - AppLayerEventType event_type; - int result = 0; - uint8_t ipproto_bitarray[256 / 8]; - memset(ipproto_bitarray, 0, sizeof(ipproto_bitarray)); - ipproto_bitarray[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8); - - DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1", - &event_type); - if (aled == NULL) - goto end; - if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0) { - printf("failure 1\n"); - goto end; - } - if (aled->alproto != ALPROTO_SMTP || - aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT1) { - printf("test failure. Holding wrong state\n"); - goto end; - } - - result = 1; - - end: - AppLayerParserRestoreParserTable(); - if (aled != NULL) - DetectAppLayerEventFree(aled); - return result; -} - -int DetectAppLayerEventTest02(void) -{ - AppLayerParserBackupParserTable(); - - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_SMTP, - DetectAppLayerEventTestGetEventInfo); - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_HTTP, - DetectAppLayerEventTestGetEventInfo); - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_SMB, - DetectAppLayerEventTestGetEventInfo); - AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_FTP, - DetectAppLayerEventTestGetEventInfo); - - AppLayerEventType event_type; - int result = 0; - uint8_t ipproto_bitarray[256 / 8]; - memset(ipproto_bitarray, 0, sizeof(ipproto_bitarray)); - ipproto_bitarray[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8); - - DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1", - &event_type); - if (aled == NULL) - goto end; - if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0) { - printf("failure 1\n"); - goto end; - } - if (aled->alproto != ALPROTO_SMTP || - aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT1) { - printf("test failure. Holding wrong state\n"); - goto end; - } - - aled = DetectAppLayerEventParse("smtp.event4", - &event_type); - if (aled == NULL) - goto end; - if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0) { - printf("failure 1\n"); - goto end; - } - if (aled->alproto != ALPROTO_SMTP || - aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT4) { - printf("test failure. Holding wrong state\n"); - goto end; - } - - aled = DetectAppLayerEventParse("http.event2", - &event_type); - if (aled == NULL) - goto end; - if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0) { - printf("failure 1\n"); - goto end; - } - if (aled->alproto != ALPROTO_HTTP || - aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT2) { - printf("test failure. Holding wrong state\n"); - goto end; - } - - aled = DetectAppLayerEventParse("smb.event3", - &event_type); - if (aled == NULL) - goto end; - if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0) { - printf("failure 1\n"); - goto end; - } - if (aled->alproto != ALPROTO_SMB || - aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT3) { - printf("test failure. Holding wrong state\n"); - goto end; - } - - aled = DetectAppLayerEventParse("ftp.event5", - &event_type); - if (aled == NULL) - goto end; - if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0) { - printf("failure 1\n"); - goto end; - } - if (aled->alproto != ALPROTO_FTP || - aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT5) { - printf("test failure. Holding wrong state\n"); - goto end; - } - - result = 1; - - end: - AppLayerParserRestoreParserTable(); - if (aled != NULL) - DetectAppLayerEventFree(aled); - return result; -} - -int DetectAppLayerEventTest03(void) -{ - int result = 0; - ThreadVars tv; - TcpReassemblyThreadCtx *ra_ctx = NULL; - Packet *p = NULL; - Flow *f = NULL; - TcpSession ssn; - TcpStream stream_ts, stream_tc; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - - uint8_t buf_ts[] = "GET /index.html HTTP/1.1\r\n" - "Host: 127.0.0.1\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100402 Firefox/3.6.3\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" - "Accept-Language: en-us,en;q=0.5\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Keep-Alive: 115\r\n" - "Connection: keep-alive\r\n" - "\r\n"; - uint8_t buf_tc[] = "HTTP/1.1 200 OK\r\n" - "Date: Fri, 22 Oct 2010 12:31:08 GMT\r\n" - "Server: Apache/2.2.15 (Unix) DAV/2\r\n" - "Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT\r\n" - "ETag: \"ab8486-2c-3e9564c23b600\"\r\n" - "Accept-Ranges: bytes\r\n" - "Content-Length: 44\r\n" - "Keep-Alive: timeout=5, max=100\r\n" - "Connection: Keep-Alive\r\n" - "Content-Type: text/html\r\n" - "\r\n" - "

It works!

"; - - memset(&tv, 0, sizeof (ThreadVars)); - memset(&ssn, 0, sizeof(TcpSession)); - memset(&stream_ts, 0, sizeof(TcpStream)); - memset(&stream_tc, 0, sizeof(TcpStream)); - - ssn.data_first_seen_dir = STREAM_TOSERVER; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(app-layer-event: applayer_mismatch_protocol_both_directions; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220); - if (f == NULL) - goto end; - FLOW_INITIALIZE(f); - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - f->flags |= FLOW_IPV4; - - p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - goto end; - p->flow = f; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - - ra_ctx = StreamTcpReassembleInitThreadCtx(&tv); - if (ra_ctx == NULL) - goto end; - StreamTcpInitConfig(TRUE); - - p->flowflags = FLOW_PKT_TOSERVER; - if (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream_ts, buf_ts, - sizeof(buf_ts), STREAM_TOSERVER | STREAM_START) < 0) { - printf("AppLayerHandleTCPData failure\n"); - goto end; - } - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - if (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream_tc, buf_tc, - sizeof(buf_tc), STREAM_TOCLIENT | STREAM_START) < 0) { - printf("AppLayerHandleTCPData failure\n"); - goto end; - } - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - result = 1; - end: - return result; -} - -int DetectAppLayerEventTest04(void) -{ - int result = 0; - ThreadVars tv; - TcpReassemblyThreadCtx *ra_ctx = NULL; - Packet *p = NULL; - Flow *f = NULL; - TcpSession ssn; - TcpStream stream_ts, stream_tc; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - - uint8_t buf_ts[] = "GET /index.html HTTP/1.1\r\n" - "Host: 127.0.0.1\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100402 Firefox/3.6.3\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" - "Accept-Language: en-us,en;q=0.5\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Keep-Alive: 115\r\n" - "Connection: keep-alive\r\n" - "\r\n"; - uint8_t buf_tc[] = "XTTP/1.1 200 OK\r\n" - "Date: Fri, 22 Oct 2010 12:31:08 GMT\r\n" - "Server: Apache/2.2.15 (Unix) DAV/2\r\n" - "Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT\r\n" - "ETag: \"ab8486-2c-3e9564c23b600\"\r\n" - "Accept-Ranges: bytes\r\n" - "Content-Length: 44\r\n" - "Keep-Alive: timeout=5, max=100\r\n" - "Connection: Keep-Alive\r\n" - "Content-Type: text/html\r\n" - "\r\n" - "

It works!

"; - - memset(&tv, 0, sizeof (ThreadVars)); - memset(&ssn, 0, sizeof(TcpSession)); - memset(&stream_ts, 0, sizeof(TcpStream)); - memset(&stream_tc, 0, sizeof(TcpStream)); - - ssn.data_first_seen_dir = STREAM_TOSERVER; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(app-layer-event: applayer_detect_protocol_only_one_direction; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220); - if (f == NULL) - goto end; - FLOW_INITIALIZE(f); - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - f->flags |= FLOW_IPV4; - - p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - goto end; - p->flow = f; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - - ra_ctx = StreamTcpReassembleInitThreadCtx(&tv); - if (ra_ctx == NULL) - goto end; - StreamTcpInitConfig(TRUE); - - p->flowflags = FLOW_PKT_TOSERVER; - if (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream_ts, buf_ts, - sizeof(buf_ts), STREAM_TOSERVER | STREAM_START) < 0) { - printf("AppLayerHandleTCPData failure\n"); - goto end; - } - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - if (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream_tc, buf_tc, - sizeof(buf_tc), STREAM_TOCLIENT | STREAM_START) < 0) { - printf("AppLayerHandleTCPData failure\n"); - goto end; - } - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; - end: - return result; -} - -int DetectAppLayerEventTest05(void) -{ - int result = 0; - ThreadVars tv; - TcpReassemblyThreadCtx *ra_ctx = NULL; - Packet *p = NULL; - Flow *f = NULL; - TcpSession ssn; - TcpStream stream_ts, stream_tc; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - - uint8_t buf_ts[] = "GET /index.html HTTP/1.1\r\n" - "Host: 127.0.0.1\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100402 Firefox/3.6.3\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" - "Accept-Language: en-us,en;q=0.5\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Keep-Alive: 115\r\n" - "Connection: keep-alive\r\n" - "\r\n"; - /* tls */ - uint8_t buf_tc[] = { - 0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00, - 0x82, 0x00, 0x80, 0xd3, 0x6f, 0x1f, 0x63, 0x82, - 0x8d, 0x75, 0x77, 0x8c, 0x91, 0xbc, 0xa1, 0x3d, - 0xbb, 0xe1, 0xb5, 0xd3, 0x31, 0x92, 0x59, 0x2b, - 0x2c, 0x43, 0x96, 0xa3, 0xaa, 0x23, 0x92, 0xd0, - 0x91, 0x2a, 0x5e, 0x10, 0x5b, 0xc8, 0xc1, 0xe2, - 0xd3, 0x5c, 0x8b, 0x8c, 0x91, 0x9e, 0xc2, 0xf2, - 0x9c, 0x3c, 0x4f, 0x37, 0x1e, 0x20, 0x5e, 0x33, - 0xd5, 0xf0, 0xd6, 0xaf, 0x89, 0xf5, 0xcc, 0xb2, - 0xcf, 0xc1, 0x60, 0x3a, 0x46, 0xd5, 0x4e, 0x2a, - 0xb6, 0x6a, 0xb9, 0xfc, 0x32, 0x8b, 0xe0, 0x6e, - 0xa0, 0xed, 0x25, 0xa0, 0xa4, 0x82, 0x81, 0x73, - 0x90, 0xbf, 0xb5, 0xde, 0xeb, 0x51, 0x8d, 0xde, - 0x5b, 0x6f, 0x94, 0xee, 0xba, 0xe5, 0x69, 0xfa, - 0x1a, 0x80, 0x30, 0x54, 0xeb, 0x12, 0x01, 0xb9, - 0xfe, 0xbf, 0x82, 0x95, 0x01, 0x7b, 0xb0, 0x97, - 0x14, 0xc2, 0x06, 0x3c, 0x69, 0xfb, 0x1c, 0x66, - 0x47, 0x17, 0xd9, 0x14, 0x03, 0x01, 0x00, 0x01, - 0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0xf6, 0xbc, - 0x0d, 0x6f, 0xe8, 0xbb, 0xaa, 0xbf, 0x14, 0xeb, - 0x7b, 0xcc, 0x6c, 0x28, 0xb0, 0xfc, 0xa6, 0x01, - 0x2a, 0x97, 0x96, 0x17, 0x5e, 0xe8, 0xb4, 0x4e, - 0x78, 0xc9, 0x04, 0x65, 0x53, 0xb6, 0x93, 0x3d, - 0xeb, 0x44, 0xee, 0x86, 0xf9, 0x80, 0x49, 0x45, - 0x21, 0x34, 0xd1, 0xee, 0xc8, 0x9c, - }; - - memset(&tv, 0, sizeof (ThreadVars)); - memset(&ssn, 0, sizeof(TcpSession)); - memset(&stream_ts, 0, sizeof(TcpStream)); - memset(&stream_tc, 0, sizeof(TcpStream)); - - ssn.data_first_seen_dir = STREAM_TOSERVER; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(app-layer-event: applayer_mismatch_protocol_both_directions; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220); - if (f == NULL) - goto end; - FLOW_INITIALIZE(f); - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - f->flags |= FLOW_IPV4; - - p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - goto end; - p->flow = f; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - - ra_ctx = StreamTcpReassembleInitThreadCtx(&tv); - if (ra_ctx == NULL) - goto end; - StreamTcpInitConfig(TRUE); - - p->flowflags = FLOW_PKT_TOSERVER; - if (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream_ts, buf_ts, - sizeof(buf_ts), STREAM_TOSERVER | STREAM_START) < 0) { - printf("AppLayerHandleTCPData failure\n"); - goto end; - } - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - if (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream_tc, buf_tc, - sizeof(buf_tc), STREAM_TOCLIENT | STREAM_START) < 0) { - printf("AppLayerHandleTCPData failure\n"); - goto end; - } - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; - end: - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief This function registers unit tests for "app-layer-event" keyword. - */ -void DetectAppLayerEventRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectAppLayerEventTest01", DetectAppLayerEventTest01, 1); - UtRegisterTest("DetectAppLayerEventTest02", DetectAppLayerEventTest02, 1); - UtRegisterTest("DetectAppLayerEventTest03", DetectAppLayerEventTest03, 1); - UtRegisterTest("DetectAppLayerEventTest04", DetectAppLayerEventTest04, 1); - UtRegisterTest("DetectAppLayerEventTest05", DetectAppLayerEventTest05, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-app-layer-event.h b/framework/src/suricata/src/detect-app-layer-event.h deleted file mode 100644 index a3ed6088..00000000 --- a/framework/src/suricata/src/detect-app-layer-event.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_APP_LAYER_EVENT_H__ -#define __DETECT_APP_LAYER_EVENT_H__ - -typedef struct DetectAppLayerEventData_ { - AppProto alproto; - int event_id; - - char *arg; -} DetectAppLayerEventData; - -int DetectAppLayerEventPrepare(Signature *s); -void DetectAppLayerEventRegister(void); - -#endif /* __DETECT_APP_LAYER_EVENT_H__ */ diff --git a/framework/src/suricata/src/detect-app-layer-protocol.c b/framework/src/suricata/src/detect-app-layer-protocol.c deleted file mode 100644 index 65af621e..00000000 --- a/framework/src/suricata/src/detect-app-layer-protocol.c +++ /dev/null @@ -1,407 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-app-layer-protocol.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -void DetectAppLayerProtocolRegisterTests(void); - -int DetectAppLayerProtocolMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, - Signature *s, SigMatch *m) -{ - int r = 0; - DetectAppLayerProtocolData *data = (DetectAppLayerProtocolData *)m->ctx; - - r = (data->negated) ? (f->alproto != data->alproto) : - (f->alproto == data->alproto); - - return r; -} - -static DetectAppLayerProtocolData *DetectAppLayerProtocolParse(const char *arg) -{ - DetectAppLayerProtocolData *data; - AppProto alproto = ALPROTO_UNKNOWN; - uint8_t negated = 0; - - if (arg == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-protocol keyword " - "supplied with no arguments. This keyword needs " - "an argument."); - return NULL; - } - - while (*arg != '\0' && isspace((unsigned char)*arg)) - arg++; - - if (arg[0] == '!') { - negated = 1; - arg++; - } - - while (*arg != '\0' && isspace((unsigned char)*arg)) - arg++; - - alproto = AppLayerGetProtoByName((char *)arg); - if (alproto == ALPROTO_UNKNOWN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-protocol " - "keyword supplied with unknown protocol \"%s\"", arg); - return NULL; - } - - data = SCMalloc(sizeof(DetectAppLayerProtocolData)); - if (unlikely(data == NULL)) - return NULL; - data->alproto = alproto; - data->negated = negated; - - return data; -} - -int DetectAppLayerProtocolSetup(DetectEngineCtx *de_ctx, Signature *s, - char *arg) -{ - DetectAppLayerProtocolData *data = NULL; - SigMatch *sm = NULL; - - if (s->alproto != ALPROTO_UNKNOWN) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Either we already " - "have the rule match on an app layer protocol set through " - "other keywords that match on this protocol, or have " - "already seen a non-negated app-layer-protocol."); - goto error; - } - - data = DetectAppLayerProtocolParse(arg); - if (data == NULL) - goto error; - - if (!data->negated) - s->alproto = data->alproto; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_AL_APP_LAYER_PROTOCOL; - sm->ctx = (void *)data; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - s->flags |= SIG_FLAG_APPLAYER; - - return 0; - -error: - if (data != NULL) - SCFree(data); - return -1; -} - -void DetectAppLayerProtocolFree(void *ptr) -{ - SCFree(ptr); - - return; -} - -void DetectAppLayerProtocolRegister(void) -{ - sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].name = "app-layer-protocol"; - sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].Match = NULL; - sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].AppLayerMatch = - DetectAppLayerProtocolMatch; - sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].Setup = - DetectAppLayerProtocolSetup; - sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].Free = - DetectAppLayerProtocolFree; - sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].RegisterTests = - DetectAppLayerProtocolRegisterTests; - - return; -} - -/**********************************Unittests***********************************/ - -#ifdef UNITTESTS - -int DetectAppLayerProtocolTest01(void) -{ - int result = 0; - - DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http"); - if (data == NULL) - goto end; - if (data->alproto != ALPROTO_HTTP || data->negated) { - printf("test failure. Holding wrong state\n"); - goto end; - } - - result = 1; - - end: - if (data != NULL) - DetectAppLayerProtocolFree(data); - return result; -} - -int DetectAppLayerProtocolTest02(void) -{ - int result = 0; - - DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("!http"); - if (data == NULL) - goto end; - if (data->alproto != ALPROTO_HTTP || !data->negated) { - printf("test failure. Holding wrong state\n"); - goto end; - } - - result = 1; - - end: - if (data != NULL) - DetectAppLayerProtocolFree(data); - return result; -} - -int DetectAppLayerProtocolTest03(void) -{ - int result = 0; - Signature *s = NULL; - DetectAppLayerProtocolData *data = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(app-layer-protocol:http; sid:1;)"); - if (s->alproto != ALPROTO_HTTP) { - printf("signature alproto should be http\n"); - goto end; - } - data = (DetectAppLayerProtocolData *)s->sm_lists[DETECT_SM_LIST_AMATCH]->ctx; - if (data->alproto != ALPROTO_HTTP || data->negated) { - printf("if (data->alproto != ALPROTO_HTTP || data->negated)\n"); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectAppLayerProtocolTest04(void) -{ - int result = 0; - Signature *s = NULL; - DetectAppLayerProtocolData *data = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(app-layer-protocol:!http; sid:1;)"); - if (s->alproto != ALPROTO_UNKNOWN) { - printf("signature alproto should be unknown\n"); - goto end; - } - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - printf("if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL)\n"); - goto end; - } - data = (DetectAppLayerProtocolData*)s->sm_lists[DETECT_SM_LIST_AMATCH]->ctx; - if (data == NULL) { - printf("if (data == NULL)\n"); - goto end; - } - if (data->alproto != ALPROTO_HTTP || !data->negated) { - printf("if (data->alproto != ALPROTO_HTTP || !data->negated)\n"); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectAppLayerProtocolTest05(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(app-layer-protocol:!http; app-layer-protocol:!smtp; sid:1;)"); - if (s->alproto != ALPROTO_UNKNOWN) { - printf("signature alproto should be unknown\n"); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectAppLayerProtocolTest06(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx, "alert http any any -> any any " - "(app-layer-protocol:smtp; sid:1;)"); - if (s != NULL) { - printf("if (s != NULL)\n"); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectAppLayerProtocolTest07(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx, "alert http any any -> any any " - "(app-layer-protocol:!smtp; sid:1;)"); - if (s != NULL) { - printf("if (s != NULL)\n"); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectAppLayerProtocolTest08(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(app-layer-protocol:!smtp; app-layer-protocol:http; sid:1;)"); - if (s != NULL) { - printf("if (s != NULL)\n"); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectAppLayerProtocolTest09(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(app-layer-protocol:http; app-layer-protocol:!smtp; sid:1;)"); - if (s != NULL) { - printf("if (s != NULL)\n"); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -void DetectAppLayerProtocolRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectAppLayerProtocolTest01", DetectAppLayerProtocolTest01, 1); - UtRegisterTest("DetectAppLayerProtocolTest02", DetectAppLayerProtocolTest02, 1); - UtRegisterTest("DetectAppLayerProtocolTest03", DetectAppLayerProtocolTest03, 1); - UtRegisterTest("DetectAppLayerProtocolTest04", DetectAppLayerProtocolTest04, 1); - UtRegisterTest("DetectAppLayerProtocolTest05", DetectAppLayerProtocolTest05, 1); - UtRegisterTest("DetectAppLayerProtocolTest06", DetectAppLayerProtocolTest06, 1); - UtRegisterTest("DetectAppLayerProtocolTest07", DetectAppLayerProtocolTest07, 1); - UtRegisterTest("DetectAppLayerProtocolTest08", DetectAppLayerProtocolTest08, 1); - UtRegisterTest("DetectAppLayerProtocolTest09", DetectAppLayerProtocolTest09, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-app-layer-protocol.h b/framework/src/suricata/src/detect-app-layer-protocol.h deleted file mode 100644 index 616c4f2a..00000000 --- a/framework/src/suricata/src/detect-app-layer-protocol.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_APP_LAYER_PROTOCOL__H__ -#define __DETECT_APP_LAYER_PROTOCOL__H__ - -typedef struct DetectAppLayerProtocolData_ { - AppProto alproto; - uint8_t negated; -} DetectAppLayerProtocolData; - -void DetectAppLayerProtocolRegister(void); - -#endif /* __DETECT_APP_LAYER_PROTOCOL__H__ */ diff --git a/framework/src/suricata/src/detect-asn1.c b/framework/src/suricata/src/detect-asn1.c deleted file mode 100644 index 69d90829..00000000 --- a/framework/src/suricata/src/detect-asn1.c +++ /dev/null @@ -1,1366 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file detect-asn1.c - * - * \author Pablo Rincon Crespo - * - * Implements "asn1" keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "flow.h" -#include "detect-asn1.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-byte.h" -#include "util-debug.h" -#include "util-decode-asn1.h" - -/* delimiters for functions/arguments */ -const char *ASN_DELIM = " \t,\n"; - -int DetectAsn1Match(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectAsn1Setup (DetectEngineCtx *, Signature *, char *); -void DetectAsn1RegisterTests(void); -void DetectAsn1Free(void *); - -/** - * \brief Registration function for asn1 - */ -void DetectAsn1Register(void) -{ - sigmatch_table[DETECT_ASN1].name = "asn1"; - sigmatch_table[DETECT_ASN1].Match = DetectAsn1Match; - sigmatch_table[DETECT_ASN1].Setup = DetectAsn1Setup; - sigmatch_table[DETECT_ASN1].Free = DetectAsn1Free; - sigmatch_table[DETECT_ASN1].RegisterTests = DetectAsn1RegisterTests; - - return; -} - -/** - * \brief The main checks are done here - * This function implements the detection of the following options: - * - oversize_length - * - bitstring_overflow - * - double_overflow - * We can add more checks here easily since we have all the data of the - * node avaliable. If we need all the tree, we can just pass the - * ASN1 ctx as argument and perform the checks here - * \param node pointer to the Asn1Node to inspect - * \param ad pointer to the parsed options of the asn1 keyword (which hold the - * checks that we want to perform, and the lenght of oversize check - * \retval 1 if any of the options match, 0 if not - */ -static uint8_t DetectAsn1Checks(Asn1Node *node, const DetectAsn1Data *ad) -{ - - /* oversize_length will check if a node has a length greater than - * the user supplied length */ - if (ad->flags & ASN1_OVERSIZE_LEN) { - if (node->len.len > ad->oversize_length - || node->data.len > ad->oversize_length) - return 1; - } - - /* 8.6 */ - /* bitstring_overflow check a malformed option where the number of bits - * to ignore is greater than the length decoded (in bits) */ - if (ad->flags & ASN1_BITSTRING_OVF) { - if (node->id.class_tag == ASN1_BER_CLASS_UNIV && - node->id.tag_num == ASN1_UNITAG_BIT_STRING && - node->id.tag_type == ASN1_TAG_TYPE_PRIMITIVE) - { - if (node->len.len > 0 && node->data.ptr != NULL - && (node->len.len) * 8 < (uint8_t) *node->data.ptr) - { - return 1; - } - } - } - - /* double_overflow checks a known issue that affect the MSASN1 library - * when decoding double/real types. If the endoding is ASCII, - * and the buffer is greater than 256, the array is overflown - */ - if (ad->flags & ASN1_DOUBLE_OVF) { - if (node->id.class_tag == ASN1_BER_CLASS_UNIV && - node->id.tag_num == ASN1_UNITAG_REAL && - node->id.tag_type == ASN1_TAG_TYPE_PRIMITIVE) - { - if (node->len.len > 0 && node->data.ptr != NULL - && !((uint8_t) *node->data.ptr & 0xC0) - && (node->len.len > 256 || node->data.len > 256)) - { - return 1; - } - } - } - - /* Good to know :) */ - return 0; -} - -/** - * \brief This function will decode the asn1 data and inspect the resulting - * nodes to detect if any of the specified checks match this data - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectAsn1Data - * - * \retval 0 no match - * \retval 1 match - */ -int DetectAsn1Match(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, - Signature *s, const SigMatchCtx *ctx) -{ - uint8_t ret = 0; - - if (p->payload_len == 0) { - /* No error, parser done, no data in bounds to decode */ - return 0; - } - - const DetectAsn1Data *ad = (const DetectAsn1Data *)ctx; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - - if (ad->flags & ASN1_ABSOLUTE_OFFSET) { - SCAsn1CtxInit(ac, p->payload + ad->absolute_offset, - p->payload_len - ad->absolute_offset); - } else if (ad->flags & ASN1_RELATIVE_OFFSET) { - SCAsn1CtxInit(ac, p->payload + ad->relative_offset, - p->payload_len - ad->relative_offset); - } else { - SCAsn1CtxInit(ac, p->payload, p->payload_len); - } - - SCAsn1Decode(ac, ac->cur_frame); - - /* Ok, now we have all the data. Let's check the nodes */ - - if (ac->cur_frame > 0 || (ac->asn1_stack[0] != NULL && ac->asn1_stack[0]->id.ptr != NULL)) { - /* We spect at least one node */ - uint16_t n_iter = 0; - ret = 0; - - for (; n_iter <= ac->cur_frame; n_iter++) { - Asn1Node *node = ASN1CTX_GET_NODE(ac, n_iter); - - if (node == NULL || node->id.ptr == NULL) - continue; /* Should not happen */ - - ret = DetectAsn1Checks(node, ad); - /* Got a match? */ - if (ret == 1) - break; - } - } - - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \brief This function is used to parse asn1 options passed via asn1: keyword - * - * \param asn1str Pointer to the user provided asn1 options - * - * \retval fd pointer to DetectAsn1Data on success - * \retval NULL on failure - */ -DetectAsn1Data *DetectAsn1Parse(char *asn1str) -{ - DetectAsn1Data *fd = NULL; - char *tok = NULL; - uint32_t ov_len = 0; - uint32_t abs_off = 0; - int32_t rel_off = 0; - uint8_t flags = 0; - char *saveptr = NULL; - - tok = strtok_r(asn1str, ASN_DELIM, &saveptr); - if (tok == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed asn1 argument: %s", - asn1str); - return NULL; - } - - while (tok != NULL) { - if (strcasecmp("bitstring_overflow", tok) == 0) { - /* No arg here, just set the flag */ - flags |= ASN1_BITSTRING_OVF; - } else if (strcasecmp("double_overflow", tok) == 0) { - /* No arg here, just set the flag */ - flags |= ASN1_DOUBLE_OVF; - } else if (strcasecmp("oversize_length", tok) == 0) { - flags |= ASN1_OVERSIZE_LEN; - /* get the param */ - tok = strtok_r(NULL, ASN_DELIM, &saveptr); - if ( tok == NULL || - ByteExtractStringUint32(&ov_len, 10, 0, tok) <= 0) - { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed value for " - "oversize_length: %s", tok); - goto error; - } - } else if (strcasecmp("absolute_offset", tok) == 0) { - flags |= ASN1_ABSOLUTE_OFFSET; - /* get the param */ - tok = strtok_r(NULL, ASN_DELIM, &saveptr); - if (tok == NULL || - ByteExtractStringUint32(&abs_off, 10, 0, tok) <= 0) - { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed value for " - "absolute_offset: %s", tok); - goto error; - } - } else if (strcasecmp("relative_offset",tok) == 0) { - flags |= ASN1_RELATIVE_OFFSET; - /* get the param */ - tok = strtok_r(NULL, ASN_DELIM, &saveptr); - if (tok == NULL || - ByteExtractStringInt32(&rel_off, 10, 0, tok) <= 0) - { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed value for " - "relative_offset: %s", tok); - goto error; - } - } else { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed asn1 argument: %s", - asn1str); - return NULL; - } - tok = strtok_r(NULL, ASN_DELIM, &saveptr); - } - - fd = SCMalloc(sizeof(DetectAsn1Data)); - if (unlikely(fd == NULL)) { - exit(EXIT_FAILURE); - } - memset(fd, 0x00, sizeof(DetectAsn1Data)); - - fd->flags = flags; - fd->oversize_length = ov_len; /* Length argument if needed */ - fd->absolute_offset = abs_off; /* Length argument if needed */ - fd->relative_offset = rel_off; /* Length argument if needed */ - return fd; - -error: - return NULL; -} - -/** - * \brief this function is used to add the parsed asn1 data into - * the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param asn1str pointer to the user provided asn1 options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectAsn1Setup(DetectEngineCtx *de_ctx, Signature *s, char *asn1str) -{ - DetectAsn1Data *ad = NULL; - SigMatch *sm = NULL; - - ad = DetectAsn1Parse(asn1str); - if (ad == NULL) goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_ASN1; - sm->ctx = (SigMatchCtx *)ad; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (ad != NULL) DetectAsn1Free(ad); - if (sm != NULL) SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectAsn1Data - * - * \param ad pointer to DetectAsn1Data - */ -void DetectAsn1Free(void *ptr) -{ - DetectAsn1Data *ad = (DetectAsn1Data *)ptr; - SCFree(ad); -} - -#ifdef UNITTESTS - -/** - * \test DetectAsn1TestParse01 check that we parse oversize_length correctly - */ -int DetectAsn1TestParse01(void) -{ - int result = 0; - char str[] = "oversize_length 1024"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL) { - if (ad->oversize_length == 1024 && (ad->flags & ASN1_OVERSIZE_LEN)) { - result = 1; - } - DetectAsn1Free(ad); - } - - return result; -} - -/** - * \test DetectAsn1TestParse02 check that we parse absolute_offset correctly - */ -int DetectAsn1TestParse02(void) -{ - int result = 0; - DetectAsn1Data *ad = NULL; - char str[] = "absolute_offset 1024"; - - ad = DetectAsn1Parse(str); - if (ad != NULL && ad->absolute_offset == 1024 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) { - DetectAsn1Free(ad); - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1TestParse03 check that we parse relative_offset correctly - */ -int DetectAsn1TestParse03(void) -{ - int result = 0; - char str[] = "relative_offset 1024"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && ad->relative_offset == 1024 - && (ad->flags & ASN1_RELATIVE_OFFSET)) { - DetectAsn1Free(ad); - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1TestParse04 check that we parse bitstring_overflow correctly - */ -int DetectAsn1TestParse04(void) -{ - int result = 0; - char str[] = "bitstring_overflow"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && (ad->flags & ASN1_BITSTRING_OVF)) { - DetectAsn1Free(ad); - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1TestParse05 check that we parse double_overflow correctly - */ -int DetectAsn1TestParse05(void) -{ - int result = 0; - char str[] = "double_overflow"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && (ad->flags & ASN1_DOUBLE_OVF)) { - DetectAsn1Free(ad); - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1TestParse06 check that we fail if a needed arg is not given - */ -int DetectAsn1TestParse06(void) -{ - int result = 1; - char str[] = "absolute_offset"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL) { - DetectAsn1Free(ad); - result = 0; - } - - return result; -} - -/** - * \test DetectAsn1TestParse07 check that we fail if a needed arg is not given - */ -int DetectAsn1TestParse07(void) -{ - int result = 1; - char str[] = "relative_offset"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL) { - DetectAsn1Free(ad); - result = 0; - } - - return result; -} - -/** - * \test DetectAsn1TestParse08 check that we fail if a needed arg is not given - */ -int DetectAsn1TestParse08(void) -{ - int result = 1; - char str[] = "oversize_length"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL) { - DetectAsn1Free(ad); - result = 0; - } - - return result; -} - - - -/** - * \test DetectAsn1TestParse09 test that we break on invalid options - */ -int DetectAsn1TestParse09(void) -{ - int result = 1; - DetectAsn1Data *fd = NULL; - char str[] = "oversize_length 1024, lalala 360"; - - fd = DetectAsn1Parse(str); - if (fd != NULL) { - result = 0; - DetectAsn1Free(fd); - } - - return result; -} - -/** - * \test DetectAsn1TestParse10 test that we break with a empty string - */ -int DetectAsn1TestParse10(void) -{ - int result = 1; - DetectAsn1Data *fd = NULL; - char str[] = ""; - - fd = DetectAsn1Parse(str); - if (fd != NULL) { - result = 0; - DetectAsn1Free(fd); - } - - return result; -} - -/** - * \test DetectAsn1TestParse11 check for combinations of keywords - */ -int DetectAsn1TestParse11(void) -{ - int result = 0; - char str[] = "oversize_length 1024, relative_offset 10"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && ad->oversize_length == 1024 - && (ad->flags & ASN1_OVERSIZE_LEN) - && ad->relative_offset == 10 - && (ad->flags & ASN1_RELATIVE_OFFSET)) - { - DetectAsn1Free(ad); - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1TestParse12 check for combinations of keywords - */ -int DetectAsn1TestParse12(void) -{ - int result = 0; - char str[] = "oversize_length 1024 absolute_offset 10"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && ad->oversize_length == 1024 - && (ad->flags & ASN1_OVERSIZE_LEN) - && ad->absolute_offset == 10 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) - { - DetectAsn1Free(ad); - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1TestParse13 check for combinations of keywords - */ -int DetectAsn1TestParse13(void) -{ - int result = 0; - char str[] = "oversize_length 1024 absolute_offset 10, bitstring_overflow"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && ad->oversize_length == 1024 - && (ad->flags & ASN1_OVERSIZE_LEN) - && (ad->flags & ASN1_BITSTRING_OVF) - && ad->absolute_offset == 10 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) - { - DetectAsn1Free(ad); - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1TestParse14 check for combinations of keywords - */ -int DetectAsn1TestParse14(void) -{ - int result = 0; - char str[] = "double_overflow, oversize_length 1024 absolute_offset 10," - " bitstring_overflow"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && ad->oversize_length == 1024 - && (ad->flags & ASN1_OVERSIZE_LEN) - && (ad->flags & ASN1_BITSTRING_OVF) - && (ad->flags & ASN1_DOUBLE_OVF) - && ad->absolute_offset == 10 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) - { - DetectAsn1Free(ad); - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1TestParse15 check for combinations of keywords - */ -int DetectAsn1TestParse15(void) -{ - int result = 0; - char str[] = "double_overflow, oversize_length 1024 relative_offset 10," - " bitstring_overflow"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && ad->oversize_length == 1024 - && (ad->flags & ASN1_OVERSIZE_LEN) - && (ad->flags & ASN1_BITSTRING_OVF) - && (ad->flags & ASN1_DOUBLE_OVF) - && ad->relative_offset == 10 - && (ad->flags & ASN1_RELATIVE_OFFSET)) - { - DetectAsn1Free(ad); - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1Test01 Ensure that the checks work when they should - */ -int DetectAsn1Test01(void) -{ - int result = 0; - /* Match if any of the nodes after offset 0 has greater length than 10 */ - char str[] = "oversize_length 132 absolute_offset 0"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && ad->oversize_length == 132 - && (ad->flags & ASN1_OVERSIZE_LEN) - && ad->absolute_offset == 0 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) - { - // Example from the specification X.690-0207 Appendix A.3 - uint8_t *str = (uint8_t*) "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" - "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" - "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" - "Jones""\xA0\x0A\x43\x08""19590717"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - - uint16_t len = strlen((char *)str)-1; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - - /* The first node has length 133, so it should match the oversize */ - if (ac->cur_frame > 0) { - /* We spect at least one node */ - uint16_t n_iter = 0; - - for (; n_iter <= ac->cur_frame; n_iter++) { - Asn1Node *node = ASN1CTX_GET_NODE(ac, n_iter); - - if (node == NULL || node->id.ptr == NULL) - continue; /* Should not happen */ - - result = DetectAsn1Checks(node, ad); - /* Got a match? */ - if (result == 1) - break; - } - } - - SCAsn1CtxDestroy(ac); - DetectAsn1Free(ad); - - } - - if (result == 0) { - printf("Error, oversize_length should match the first node: "); - } - - return result; -} - -/** - * \test DetectAsn1Test02 Ensure that the checks work when they should - */ -int DetectAsn1Test02(void) -{ - int result = 0; - /* Match if any of the nodes has the bitstring overflow condition */ - char str[] = "oversize_length 133, absolute_offset 0"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && ad->oversize_length == 133 - && (ad->flags & ASN1_OVERSIZE_LEN) - && ad->absolute_offset == 0 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) - { - // Example from the specification X.690-0207 Appendix A.3 - uint8_t *str = (uint8_t*) "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" - "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" - "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" - "Jones""\xA0\x0A\x43\x08""19590717"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - - uint16_t len = strlen((char *)str)-1; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - - /* The first node has length 133, so it should match the oversize */ - if (ac->cur_frame > 0) { - /* We spect at least one node */ - uint16_t n_iter = 0; - - for (; n_iter <= ac->cur_frame; n_iter++) { - Asn1Node *node = ASN1CTX_GET_NODE(ac, n_iter); - - if (node == NULL || node->id.ptr == NULL) - continue; /* Should not happen */ - - result |= DetectAsn1Checks(node, ad); - } - } - - /* Got a match? We don't have nodes greater than 133, it should not */ - if (result == 1) { - printf("Error, oversize_length should not match" - " any of the nodes: "); - result = 0; - } else { - result = 1; - } - - SCAsn1CtxDestroy(ac); - DetectAsn1Free(ad); - - } - - return result; -} - -/** - * \test DetectAsn1Test03 Ensure that the checks work when they should - */ -int DetectAsn1Test03(void) -{ - int result = 0; - /* Match if any of the nodes after offset 0 has a bitstring overflow */ - char str[] = "bitstring_overflow, absolute_offset 0"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && (ad->flags & ASN1_BITSTRING_OVF) - && ad->absolute_offset == 0 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) - { - /* Let's say tagnum bitstring, primitive, and as universal tag, - * and then length = 1 octet, but the next octet specify to ignore - * the last 256 bits... (let's match!) */ - uint8_t *str = (uint8_t*) "\x03\x01\xFF"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - - uint16_t len = 3; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - - if (ac->cur_frame > 0 || ac->asn1_stack[0]->id.ptr != NULL) { - /* We spect at least one node */ - uint16_t n_iter = 0; - - for (; n_iter <= ac->cur_frame; n_iter++) { - Asn1Node *node = ASN1CTX_GET_NODE(ac, n_iter); - - if (node == NULL || node->id.ptr == NULL) - continue; /* Should not happen */ - - result = DetectAsn1Checks(node, ad); - /* Got a match? */ - if (result == 1) - break; - } - } - - SCAsn1CtxDestroy(ac); - DetectAsn1Free(ad); - - } - - if (result == 0) { - printf("Error, bitstring_overflow should match the first node: "); - } - - return result; -} - -/** - * \test DetectAsn1Test04 Ensure that the checks work when they should - */ -int DetectAsn1Test04(void) -{ - int result = 0; - /* Match if any of the nodes after offset 0 has a bitstring overflow */ - char str[] = "bitstring_overflow, absolute_offset 0"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && (ad->flags & ASN1_BITSTRING_OVF) - && ad->absolute_offset == 0 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) - { - /* Let's say tagnum bitstring, primitive, and as universal tag, - * and then length = 1 octet, but the next octet specify to ignore - * the last 7 bits... (should not match) */ - uint8_t *str = (uint8_t*) "\x03\x01\x07"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - - uint16_t len = 3; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - - if (ac->cur_frame > 0 || ac->asn1_stack[0]->id.ptr != NULL) { - /* We spect at least one node */ - uint16_t n_iter = 0; - - for (; n_iter <= ac->cur_frame; n_iter++) { - Asn1Node *node = ASN1CTX_GET_NODE(ac, n_iter); - - if (node == NULL || node->id.ptr == NULL) - continue; /* Should not happen */ - - result = DetectAsn1Checks(node, ad); - /* Got a match? */ - if (result == 1) - break; - } - } - - SCAsn1CtxDestroy(ac); - DetectAsn1Free(ad); - - } - - if (result == 1) { - printf("Error, bitstring_overflog should not match any node: "); - result = 0; - } else { - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1Test05 Ensure that the checks work when they should - */ -int DetectAsn1Test05(void) -{ - int result = 0; - /* Match if any of the nodes after offset 0 has a double overflow */ - char str[] = "double_overflow, absolute_offset 0"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && (ad->flags & ASN1_DOUBLE_OVF) - && ad->absolute_offset == 0 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) - { - /* Let's say tag num 9 (type Real), and encoded as ASCII, with length - * 257, then we must match */ - uint8_t str[261]; - /* universal class, primitive type, tag_num = 9 (Data type Real) */ - str[0] = '\x09'; - /* length, definite form, 2 octets */ - str[1] = '\x82'; - /* length is the sum of the following octets (257): */ - str[2] = '\xFE'; - str[3] = '\x03'; - - /* Fill the content of the number */ - uint16_t i = 4; - for (; i < 257;i++) - str[i] = '\x05'; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - - uint16_t len = 261; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - - if (ac->cur_frame > 0 || ac->asn1_stack[0]->id.ptr != NULL) { - /* We spect at least one node */ - uint16_t n_iter = 0; - - for (; n_iter <= ac->cur_frame; n_iter++) { - Asn1Node *node = ASN1CTX_GET_NODE(ac, n_iter); - - if (node == NULL || node->id.ptr == NULL) - continue; /* Should not happen */ - - result = DetectAsn1Checks(node, ad); - /* Got a match? */ - if (result == 1) - break; - } - } - - SCAsn1CtxDestroy(ac); - DetectAsn1Free(ad); - - } - - if (result == 0) { - printf("Error, double_overflow should match the first node: "); - } - - return result; -} - -/** - * \test DetectAsn1Test06 Ensure that the checks work when they should - */ -int DetectAsn1Test06(void) -{ - int result = 0; - /* Match if any of the nodes after offset 0 has a double overflow */ - char str[] = "double_overflow, absolute_offset 0"; - DetectAsn1Data *ad = NULL; - - ad = DetectAsn1Parse(str); - if (ad != NULL && (ad->flags & ASN1_DOUBLE_OVF) - && ad->absolute_offset == 0 - && (ad->flags & ASN1_ABSOLUTE_OFFSET)) - { - /* Let's say tag num 9 (type Real), and encoded as ASCII, with length - * 256, which fit in the buffer, so it should not match */ - uint8_t str[260]; - /* universal class, primitive type, tag_num = 9 (Data type Real) */ - str[0] = '\x09'; - /* length, definite form, 2 octets */ - str[1] = '\x82'; - /* length is the sum of the following octets (256): */ - str[2] = '\xFE'; - str[3] = '\x02'; - - /* Fill the content of the number */ - uint16_t i = 4; - for (; i < 256;i++) - str[i] = '\x05'; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - - uint16_t len = 260; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - - if (ac->cur_frame > 0 || ac->asn1_stack[0]->id.ptr != NULL) { - /* We spect at least one node */ - uint16_t n_iter = 0; - - for (; n_iter <= ac->cur_frame; n_iter++) { - Asn1Node *node = ASN1CTX_GET_NODE(ac, n_iter); - - if (node == NULL || node->id.ptr == NULL) - continue; /* Should not happen */ - - result = DetectAsn1Checks(node, ad); - /* Got a match? */ - if (result == 1) - break; - } - } - - SCAsn1CtxDestroy(ac); - DetectAsn1Free(ad); - - } - - if (result == 1) { - printf("Error, double_overflow should not match any node: "); - result = 0 ; - } else { - result = 1; - } - - return result; -} - -/** - * \test DetectAsn1TestReal01 Ensure that all works together - */ -int DetectAsn1TestReal01(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *) "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" - "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" - "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" - "Jones""\xA0\x0A\x43\x08""19590717" - "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01""P" - "\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111""\x31\x1F" - "\x61\x11\x1A\x05""Pablo""\x1A\x01""B""\x1A\x05""Jones" - "\xA0\x0A\x43\x08""19590717"; - - uint16_t buflen = strlen((char *)buf) - 1; - - /* Check the start with AA (this is to test the relative_offset keyword) */ - uint8_t *buf2 = (uint8_t *) "AA\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" - "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" - "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" - "Jones""\xA0\x0A\x43\x08""19590717" - "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01""P" - "\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111""\x31\x1F" - "\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05""Jones" - "\xA0\x0A\x43\x08""19590717"; - - uint16_t buflen2 = strlen((char *)buf2) - 1; - - Packet *p[2]; - - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[1] = UTHBuildPacket((uint8_t *)buf2, buflen2, IPPROTO_TCP); - - if (p[0] == NULL || p[1] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert ip any any -> any any (msg:\"Testing id 1\"; " - "content:\"Pablo\"; asn1:absolute_offset 0, " - "oversize_length 130; sid:1;)"; - sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; " - "content:\"AA\"; asn1:relative_offset 2, " - "oversize_length 130; sid:2;)"; - sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; " - "content:\"lalala\"; asn1: oversize_length 2000; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[2][3] = { - /* packet 0 match sid 1 */ - {1, 0, 0}, - /* packet 1 match sid 2 */ - {0, 1, 0}}; - /* None of the packets should match sid 3 */ - - result = UTHGenericTest(p, 2, sigs, sid, (uint32_t *) results, 3); - - UTHFreePackets(p, 2); -end: - return result; -} - -/** - * \test DetectAsn1TestReal02 Ensure that all works together - */ -int DetectAsn1TestReal02(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *) "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" - "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" - "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" - "Jones""\xA0\x0A\x43\x08""19590717" - "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01""P" - "\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111""\x31\x1F" - "\x61\x11\x1A\x05""Pablo""\x1A\x01""B""\x1A\x05""Jones" - "\xA0\x0A\x43\x08""19590717"; - - uint16_t buflen = strlen((char *)buf) - 1; - - /* Check the start with AA (this is to test the relative_offset keyword) */ - uint8_t *buf2 = (uint8_t *) "AA\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" - "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" - "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" - "Jones""\xA0\x0A\x43\x08""19590717" - "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01""P" - "\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111""\x31\x1F" - "\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05""Jones" - "\xA0\x0A\x43\x08""19590717"; - - uint16_t buflen2 = strlen((char *)buf2) - 1; - - Packet *p[2]; - - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[1] = UTHBuildPacket((uint8_t *)buf2, buflen2, IPPROTO_TCP); - - if (p[0] == NULL || p[1] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert ip any any -> any any (msg:\"Testing id 1\"; " - "content:\"Pablo\"; asn1:absolute_offset 0, " - "oversize_length 140; sid:1;)"; - sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; " - "content:\"AA\"; asn1:relative_offset 2, " - "oversize_length 140; sid:2;)"; - sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; " - "content:\"lalala\"; asn1: oversize_length 2000; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[2][3] = { - {0, 0, 0}, - {0, 0, 0}}; - /* None of the packets should match */ - - result = UTHGenericTest(p, 2, sigs, sid, (uint32_t *) results, 3); - - UTHFreePackets(p, 2); -end: - return result; -} - -/** - * \test DetectAsn1TestReal03 Ensure that all works together - */ -int DetectAsn1TestReal03(void) -{ - int result = 0; - uint8_t buf[261] = ""; - /* universal class, primitive type, tag_num = 9 (Data type Real) */ - buf[0] = '\x09'; - /* length, definite form, 2 octets */ - buf[1] = '\x82'; - /* length is the sum of the following octets (257): */ - buf[2] = '\xFE'; - buf[3] = '\x03'; - - /* Fill the content of the number */ - uint16_t i = 4; - for (; i < 257;i++) - buf[i] = '\x05'; - - uint16_t buflen = 261; - - /* Check the start with AA (this is to test the relative_offset keyword) */ - uint8_t *buf2 = (uint8_t *) "AA\x03\x01\xFF"; - - uint16_t buflen2 = 5; - - Packet *p[2] = { NULL, NULL }; - - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[1] = UTHBuildPacket((uint8_t *)buf2, buflen2, IPPROTO_TCP); - - if (p[0] == NULL || p[1] == NULL) - goto end; - - char *sigs[3]; - /* This should match the first packet */ - sigs[0]= "alert ip any any -> any any (msg:\"Testing id 1\"; " - "asn1:absolute_offset 0, double_overflow; sid:1;)"; - /* This should match the second packet */ - sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; " - "asn1:relative_offset 2, bitstring_overflow," - "oversize_length 140; sid:2;)"; - /* This should match no packet */ - sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; " - "asn1: oversize_length 2000; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[2][3] = {{1, 0, 0}, - {0, 1, 0}}; - - result = UTHGenericTest(p, 2, sigs, sid, (uint32_t *) results, 3); - - UTHFreePackets(p, 2); -end: - return result; -} - -/** - * \test DetectAsn1TestReal04 like the real test 02, but modified the - * relative offset to check negative offset values, in this case - * start decoding from -7 bytes respect the content match "John" - */ -int DetectAsn1TestReal04(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *) "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" - "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" - "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" - "Jones""\xA0\x0A\x43\x08""19590717" - "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01""P" - "\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111""\x31\x1F" - "\x61\x11\x1A\x05""Pablo""\x1A\x01""B""\x1A\x05""Jones" - "\xA0\x0A\x43\x08""19590717"; - - uint16_t buflen = strlen((char *)buf) - 1; - - /* Check the start with AA (this is to test the relative_offset keyword) */ - uint8_t *buf2 = (uint8_t *) "AA\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" - "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" - "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" - "Jones""\xA0\x0A\x43\x08""19590717" - "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01""P" - "\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111""\x31\x1F" - "\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05""Jones" - "\xA0\x0A\x43\x08""19590717"; - - uint16_t buflen2 = strlen((char *)buf2) - 1; - - Packet *p[2]; - - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[1] = UTHBuildPacket((uint8_t *)buf2, buflen2, IPPROTO_TCP); - - if (p[0] == NULL || p[1] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert ip any any -> any any (msg:\"Testing id 1\"; " - "content:\"Pablo\"; asn1:absolute_offset 0, " - "oversize_length 140; sid:1;)"; - sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; " - "content:\"John\"; asn1:relative_offset -7, " - "oversize_length 140; sid:2;)"; - sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; " - "content:\"lalala\"; asn1: oversize_length 2000; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[2][3] = { - {0, 0, 0}, - {0, 0, 0}}; - /* None of the packets should match */ - - result = UTHGenericTest(p, 2, sigs, sid, (uint32_t *) results, 3); - - UTHFreePackets(p, 2); -end: - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectAsn1 - */ -void DetectAsn1RegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectAsn1TestParse01", DetectAsn1TestParse01, 1); - UtRegisterTest("DetectAsn1TestParse02", DetectAsn1TestParse02, 1); - UtRegisterTest("DetectAsn1TestParse03", DetectAsn1TestParse03, 1); - - UtRegisterTest("DetectAsn1TestParse04", DetectAsn1TestParse04, 1); - UtRegisterTest("DetectAsn1TestParse05", DetectAsn1TestParse05, 1); - UtRegisterTest("DetectAsn1TestParse06", DetectAsn1TestParse06, 1); - - UtRegisterTest("DetectAsn1TestParse07", DetectAsn1TestParse07, 1); - UtRegisterTest("DetectAsn1TestParse08", DetectAsn1TestParse08, 1); - UtRegisterTest("DetectAsn1TestParse09", DetectAsn1TestParse09, 1); - - UtRegisterTest("DetectAsn1TestParse10", DetectAsn1TestParse10, 1); - UtRegisterTest("DetectAsn1TestParse11", DetectAsn1TestParse11, 1); - UtRegisterTest("DetectAsn1TestParse12", DetectAsn1TestParse12, 1); - UtRegisterTest("DetectAsn1TestParse13", DetectAsn1TestParse13, 1); - UtRegisterTest("DetectAsn1TestParse14", DetectAsn1TestParse14, 1); - UtRegisterTest("DetectAsn1TestParse15", DetectAsn1TestParse15, 1); - UtRegisterTest("DetectAsn1Test01 - oversize_len", DetectAsn1Test01, 1); - UtRegisterTest("DetectAsn1Test02 - oversize_len", DetectAsn1Test02, 1); - UtRegisterTest("DetectAsn1Test03 - bitstring_ovf", DetectAsn1Test03, 1); - UtRegisterTest("DetectAsn1Test04 - bitstring_ovf", DetectAsn1Test04, 1); - UtRegisterTest("DetectAsn1Test05 - double_ovf", DetectAsn1Test05, 1); - UtRegisterTest("DetectAsn1Test06 - double_ovf", DetectAsn1Test06, 1); - UtRegisterTest("DetectAsn1TestReal01", DetectAsn1TestReal01, 1); - UtRegisterTest("DetectAsn1TestReal02", DetectAsn1TestReal02, 1); - UtRegisterTest("DetectAsn1TestReal03", DetectAsn1TestReal03, 1); - UtRegisterTest("DetectAsn1TestReal04", DetectAsn1TestReal04, 1); - -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-asn1.h b/framework/src/suricata/src/detect-asn1.h deleted file mode 100644 index c38d6439..00000000 --- a/framework/src/suricata/src/detect-asn1.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file detect-asn1.h - * - * \author Pablo Rincon Crespo - * - * Implements "asn1" keyword - */ -#ifndef __DETECT_ASN1_H__ -#define __DETECT_ASN1_H__ - - -/* Function check flags */ -#define ASN1_BITSTRING_OVF 0x01 -#define ASN1_DOUBLE_OVF 0x02 -#define ASN1_OVERSIZE_LEN 0x04 -#define ASN1_ABSOLUTE_OFFSET 0x10 -#define ASN1_RELATIVE_OFFSET 0x20 - -typedef struct DetectAsn1Data_ { - uint8_t flags; /* flags indicating the checks loaded */ - uint32_t oversize_length; /* Length argument if needed */ - int32_t absolute_offset; /* Length argument if needed */ - int32_t relative_offset; /* Length argument if needed */ -} DetectAsn1Data; - -/* prototypes */ -void DetectAsn1Register (void); - -#endif /* __DETECT_ASN1_H__ */ - diff --git a/framework/src/suricata/src/detect-base64-data.c b/framework/src/suricata/src/detect-base64-data.c deleted file mode 100644 index b056b97a..00000000 --- a/framework/src/suricata/src/detect-base64-data.c +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-engine-content-inspection.h" -#include "detect-parse.h" - -#include "util-unittest.h" - -static int DetectBase64DataSetup(DetectEngineCtx *, Signature *, char *); -static void DetectBase64DataRegisterTests(void); - -void DetectBase64DataRegister(void) -{ - sigmatch_table[DETECT_BASE64_DATA].name = "base64_data"; - sigmatch_table[DETECT_BASE64_DATA].desc = - "Content match base64 decoded data."; - sigmatch_table[DETECT_BASE64_DATA].url = - "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#base64_data"; - sigmatch_table[DETECT_BASE64_DATA].Setup = DetectBase64DataSetup; - sigmatch_table[DETECT_BASE64_DATA].RegisterTests = - DetectBase64DataRegisterTests; - - sigmatch_table[DETECT_BASE64_DATA].flags |= SIGMATCH_NOOPT; -} - -static int DetectBase64DataSetup(DetectEngineCtx *de_ctx, Signature *s, - char *str) -{ - SigMatch *pm = NULL; - - /* Check for a preceding base64_decode. */ - pm = SigMatchGetLastSMFromLists(s, 28, - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BASE64_DECODE, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - if (pm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, - "\"base64_data\" keyword seen without preceding base64_decode."); - return -1; - } - - s->list = DETECT_SM_LIST_BASE64_DATA; - return 0; -} - -int DetectBase64DataDoMatch(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f) -{ - if (det_ctx->base64_decoded_len) { - return DetectEngineContentInspection(de_ctx, det_ctx, s, - s->sm_lists[DETECT_SM_LIST_BASE64_DATA], f, det_ctx->base64_decoded, - det_ctx->base64_decoded_len, 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_BASE64, NULL); - } - - return 0; -} - -#ifdef UNITTESTS - -#include "detect-engine.h" - -static int DetectBase64DataSetupTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - SigMatch *sm; - int retval = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert smtp any any -> any any (msg:\"DetectBase64DataSetupTest\"; " - "base64_decode; base64_data; content:\"content\"; sid:1; rev:1;)"); - if (de_ctx->sig_list == NULL) { - printf("SigInit failed: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm == NULL) { - printf("DETECT_SM_LIST_PMATCH should not be NULL: "); - goto end; - } - if (sm->type != DETECT_BASE64_DECODE) { - printf("sm->type should be DETECT_BASE64_DECODE: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_BASE64_DATA] == NULL) { - printf("DETECT_SM_LIST_BASE64_DATA should not be NULL: "); - goto end; - } - - retval = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - return retval; -} - -static int DetectBase64DataSetupTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - SigMatch *sm; - int retval = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert smtp any any -> any any ( " - "msg:\"DetectBase64DataSetupTest\"; " - "file_data; " - "content:\"SGV\"; " - "base64_decode: bytes 16; " - "base64_data; " - "content:\"content\"; " - "sid:1; rev:1;)"); - if (de_ctx->sig_list == NULL) { - printf("SigInit failed: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm != NULL) { - printf("DETECT_SM_LIST_PMATCH is not NULL: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm == NULL) { - printf("DETECT_SM_LIST_FILEDATA is NULL: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_BASE64_DATA]; - if (sm == NULL) { - printf("DETECT_SM_LIST_BASE64_DATA is NULL: "); - goto end; - } - - retval = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - return retval; -} - -static int DetectBase64DataSetupTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int retval = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert smtp any any -> any any ( " - "msg:\"DetectBase64DataSetupTest\"; " - "base64_decode: bytes 16; " - "base64_data; " - "content:\"content\"; " - "file_data; " - "content:\"SGV\"; " - "sid:1; rev:1;)"); - if (de_ctx->sig_list != NULL) { - printf("SigInit should have failed: "); - goto end; - } - - retval = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - return retval; -} - -#endif - -static void DetectBase64DataRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectBase64DataSetupTest01", DetectBase64DataSetupTest01, - 1); - UtRegisterTest("DetectBase64DataSetupTest02", DetectBase64DataSetupTest02, - 1); - UtRegisterTest("DetectBase64DataSetupTest03", DetectBase64DataSetupTest03, - 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-base64-data.h b/framework/src/suricata/src/detect-base64-data.h deleted file mode 100644 index 12fa60de..00000000 --- a/framework/src/suricata/src/detect-base64-data.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __DETECT_BASE64_DATA_H__ -#define __DETECT_BASE64_DATA_H__ - -void DetectBase64DataRegister(void); -int DetectBase64DataDoMatch(DetectEngineCtx *, DetectEngineThreadCtx *, - Signature *, Flow *); - -#endif /* __DETECT_BASE64_DATA_H__ */ diff --git a/framework/src/suricata/src/detect-base64-decode.c b/framework/src/suricata/src/detect-base64-decode.c deleted file mode 100644 index bd9baea5..00000000 --- a/framework/src/suricata/src/detect-base64-decode.c +++ /dev/null @@ -1,778 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-base64-decode.h" -#include "util-base64.h" -#include "util-byte.h" -#include "util-print.h" - -/* Arbitrary maximum buffer size for decoded base64 data. */ -#define BASE64_DECODE_MAX 65535 - -static const char decode_pattern[] = "\\s*(bytes\\s+(\\d+),?)?" - "\\s*(offset\\s+(\\d+),?)?" - "\\s*(\\w+)?"; -static pcre *decode_pcre = NULL; -static pcre_extra *decode_pcre_study = NULL; - -static int DetectBase64DecodeSetup(DetectEngineCtx *, Signature *, char *); -static void DetectBase64DecodeFree(void *); -static void DetectBase64DecodeRegisterTests(void); - -void DetectBase64DecodeRegister(void) -{ - const char *pcre_errptr; - int pcre_erroffset; - - sigmatch_table[DETECT_BASE64_DECODE].name = "base64_decode"; - sigmatch_table[DETECT_BASE64_DECODE].desc = - "Decodes base64 encoded data."; - sigmatch_table[DETECT_BASE64_DECODE].url = - "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#base64_decode"; - sigmatch_table[DETECT_BASE64_DECODE].Setup = DetectBase64DecodeSetup; - sigmatch_table[DETECT_BASE64_DECODE].Free = DetectBase64DecodeFree; - sigmatch_table[DETECT_BASE64_DECODE].RegisterTests = - DetectBase64DecodeRegisterTests; - - sigmatch_table[DETECT_BASE64_DECODE].flags |= SIGMATCH_PAYLOAD; - sigmatch_table[DETECT_BASE64_DECODE].flags |= SIGMATCH_OPTIONAL_OPT; - - decode_pcre = pcre_compile(decode_pattern, 0, &pcre_errptr, &pcre_erroffset, - NULL); - if (decode_pcre == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Failed to compile pattern \"%s\" at" - " offset %d: %s", decode_pattern, pcre_erroffset, pcre_errptr); - exit(EXIT_FAILURE); - } - - decode_pcre_study = pcre_study(decode_pcre, 0, &pcre_errptr); - if (pcre_errptr != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "Failed to study pattern \"%s\": %s", - decode_pattern, pcre_errptr); - exit(EXIT_FAILURE); - } -} - -int DetectBase64DecodeDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, - const SigMatch *sm, uint8_t *payload, uint32_t payload_len) -{ - DetectBase64Decode *data = (DetectBase64Decode *)sm->ctx; - int decode_len; - -#if 0 - printf("Input data:\n"); - PrintRawDataFp(stdout, payload, payload_len); -#endif - - if (data->relative) { - payload += det_ctx->buffer_offset; - payload_len -= det_ctx->buffer_offset; - } - - if (data->offset) { - if (data->offset >= payload_len) { - return 0; - } - payload = payload + data->offset; - payload_len -= data->offset; - } - - decode_len = MIN(payload_len, data->bytes); - -#if 0 - printf("Decoding:\n"); - PrintRawDataFp(stdout, payload, decode_len); -#endif - - det_ctx->base64_decoded_len = DecodeBase64(det_ctx->base64_decoded, - payload, decode_len, 0); - SCLogDebug("Decoded %d bytes from base64 data.", - det_ctx->base64_decoded_len); -#if 0 - if (det_ctx->base64_decoded_len) { - printf("Decoded data:\n"); - PrintRawDataFp(stdout, det_ctx->base64_decoded, - det_ctx->base64_decoded_len); - } -#endif - - return det_ctx->base64_decoded_len > 0; -} - -static int DetectBase64DecodeParse(const char *str, uint32_t *bytes, - uint32_t *offset, uint8_t *relative) -{ - static const int max = 30; - int ov[max]; - int pcre_rc; - const char *bytes_str = NULL; - const char *offset_str = NULL; - const char *relative_str = NULL; - int retval = 0; - - *bytes = 0; - *offset = 0; - *relative = 0; - - pcre_rc = pcre_exec(decode_pcre, decode_pcre_study, str, strlen(str), 0, 0, - ov, max); - if (pcre_rc < 3) { - goto error; - } - - if (pcre_rc >= 3) { - if (pcre_get_substring((char *)str, ov, max, 2, &bytes_str) > 0) { - if (ByteExtractStringUint32(bytes, 10, 0, bytes_str) <= 0) { - SCLogError(SC_ERR_INVALID_RULE_ARGUMENT, - "Bad value for bytes: \"%s\"", bytes_str); - goto error; - } - } - } - - if (pcre_rc >= 5) { - if (pcre_get_substring((char *)str, ov, max, 4, &offset_str)) { - if (ByteExtractStringUint32(offset, 10, 0, offset_str) <= 0) { - SCLogError(SC_ERR_INVALID_RULE_ARGUMENT, - "Bad value for offset: \"%s\"", offset_str); - goto error; - } - } - } - - if (pcre_rc >= 6) { - if (pcre_get_substring((char *)str, ov, max, 5, &relative_str)) { - if (strcmp(relative_str, "relative") == 0) { - *relative = 1; - } - else { - SCLogError(SC_ERR_INVALID_RULE_ARGUMENT, - "Invalid argument: \"%s\"", relative_str); - goto error; - } - } - } - - retval = 1; -error: - if (bytes_str != NULL) { - pcre_free_substring(bytes_str); - } - if (offset_str != NULL) { - pcre_free_substring(offset_str); - } - if (relative_str != NULL) { - pcre_free_substring(relative_str); - } - return retval; -} - -static int DetectBase64DecodeSetup(DetectEngineCtx *de_ctx, Signature *s, - char *str) -{ - uint32_t bytes = 0; - uint32_t offset = 0; - uint8_t relative = 0; - DetectBase64Decode *data = NULL; - int sm_list; - SigMatch *sm = NULL; - SigMatch *pm = NULL; - - if (str != NULL) { - if (!DetectBase64DecodeParse(str, &bytes, &offset, &relative)) { - goto error; - } - } - data = SCCalloc(1, sizeof(DetectBase64Decode)); - if (unlikely(data == NULL)) { - goto error; - } - data->bytes = bytes; - data->offset = offset; - data->relative = relative; - - if (s->list != DETECT_SM_LIST_NOTSET) { - sm_list = s->list; -#if 0 - if (data->relative) { - pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, s->sm_lists_tail[sm_list], - DETECT_PCRE, s->sm_lists_tail[sm_list]); - } -#endif - } - else { - /* Copied from detect-isdataat.c. */ - pm = SigMatchGetLastSMFromLists(s, 168, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - if (pm == NULL) { - sm_list = DETECT_SM_LIST_PMATCH; - } - else { - sm_list = SigMatchListSMBelongsTo(s, pm); - } - } - - sm = SigMatchAlloc(); - if (sm == NULL) { - goto error; - } - sm->type = DETECT_BASE64_DECODE; - sm->ctx = (SigMatchCtx *)data; - SigMatchAppendSMToList(s, sm, sm_list); - - if (!data->bytes) { - data->bytes = BASE64_DECODE_MAX; - } - if (data->bytes > de_ctx->base64_decode_max_len) { - de_ctx->base64_decode_max_len = data->bytes; - } - - return 0; -error: - if (data != NULL) { - SCFree(data); - } - return -1; -} - -static void DetectBase64DecodeFree(void *ptr) -{ - DetectBase64Decode *data = ptr; - SCFree(data); -} - - -#ifdef UNITTESTS - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer-parser.h" -#include "flow-util.h" -#include "stream-tcp.h" - -static int DetectBase64TestDecodeParse(void) -{ - int retval = 0; - uint32_t bytes = 0; - uint32_t offset = 0; - uint8_t relative = 0; - - if (!DetectBase64DecodeParse("bytes 1", &bytes, &offset, &relative)) { - goto end; - } - if (bytes != 1 || offset != 0 || relative != 0) { - goto end; - } - - if (!DetectBase64DecodeParse("offset 9", &bytes, &offset, &relative)) { - goto end; - } - if (bytes != 0 || offset != 9 || relative != 0) { - goto end; - } - - if (!DetectBase64DecodeParse("relative", &bytes, &offset, &relative)) { - goto end; - } - if (bytes != 0 || offset != 0 || relative != 1) { - goto end; - } - - if (!DetectBase64DecodeParse("bytes 1, offset 2", &bytes, &offset, - &relative)) { - goto end; - } - if (bytes != 1 || offset != 2 || relative != 0) { - goto end; - } - - if (!DetectBase64DecodeParse("bytes 1, offset 2, relative", &bytes, &offset, - &relative)) { - goto end; - } - if (bytes != 1 || offset != 2 || relative != 1) { - goto end; - } - - if (!DetectBase64DecodeParse("offset 2, relative", &bytes, &offset, - &relative)) { - goto end; - } - if (bytes != 0 || offset != 2 || relative != 1) { - goto end; - } - - /* Misspelled relative. */ - if (DetectBase64DecodeParse("bytes 1, offset 2, relatve", &bytes, &offset, - &relative)) { - goto end; - } - - /* Misspelled bytes. */ - if (DetectBase64DecodeParse("byts 1, offset 2, relatve", &bytes, &offset, - &relative)) { - goto end; - } - - /* Misspelled offset. */ - if (DetectBase64DecodeParse("bytes 1, offst 2, relatve", &bytes, &offset, - &relative)) { - goto end; - } - - /* Misspelled empty string. */ - if (DetectBase64DecodeParse("", &bytes, &offset, &relative)) { - goto end; - } - - retval = 1; -end: - return retval; -} - -/** - * Test keyword setup on basic content. - */ -static int DetectBase64DecodeTestSetup(void) -{ - DetectEngineCtx *de_ctx = NULL; - Signature *s; - int retval = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (" - "msg:\"DetectBase64DecodeTestSetup\"; " - "base64_decode; content:\"content\"; " - "sid:1; rev:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - s = de_ctx->sig_list; - if (s == NULL) { - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - goto end; - } - - retval = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - return retval; -} - -/** - * Test keyword setup when the prior rule has a content modifier on - * it. - */ -static int DetectBase64DecodeHttpHeaderTestSetup(void) -{ - DetectEngineCtx *de_ctx = NULL; - Signature *s; - int retval = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (" - "msg:\"DetectBase64DecodeTestSetup\"; " - "content:\"Authorization: basic \"; http_header; " - "base64_decode; content:\"content\"; " - "sid:1; rev:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - s = de_ctx->sig_list; - if (s == NULL) { - goto end; - } - - /* I'm not complete sure if this list should not be NULL. */ - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - goto end; - } - - /* Test that the http header list is not NULL. */ - if (s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] == NULL) { - goto end; - } - - retval = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - return retval; -} - -static int DetectBase64DecodeTestDecode(void) -{ - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Packet *p = NULL; - int retval = 0; - - uint8_t payload[] = { - 'S', 'G', 'V', 's', 'b', 'G', '8', 'g', - 'V', '2', '9', 'y', 'b', 'G', 'Q', '=', - }; - - memset(&tv, 0, sizeof(tv)); - - if ((de_ctx = DetectEngineCtxInit()) == NULL) { - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"base64 test\"; " - "base64_decode; " - "sid:1; rev:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_TCP); - if (p == NULL) { - goto end; - } - - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (det_ctx->base64_decoded_len == 0) { - goto end; - } - - retval = 1; -end: - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&tv, det_ctx); - } - if (de_ctx != NULL) { - SigCleanSignatures(de_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - if (p != NULL) { - UTHFreePacket(p); - } - return retval; -} - -static int DetectBase64DecodeTestDecodeWithOffset(void) -{ - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Packet *p = NULL; - int retval = 0; - - uint8_t payload[] = { - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'S', 'G', 'V', 's', 'b', 'G', '8', 'g', - 'V', '2', '9', 'y', 'b', 'G', 'Q', '=', - }; - char decoded[] = "Hello World"; - - memset(&tv, 0, sizeof(tv)); - - if ((de_ctx = DetectEngineCtxInit()) == NULL) { - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"base64 test\"; " - "base64_decode: offset 8; " - "sid:1; rev:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_TCP); - if (p == NULL) { - goto end; - } - - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (det_ctx->base64_decoded_len != (int)strlen(decoded)) { - goto end; - } - if (memcmp(det_ctx->base64_decoded, decoded, strlen(decoded))) { - goto end; - } - - retval = 1; -end: - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&tv, det_ctx); - } - if (de_ctx != NULL) { - SigCleanSignatures(de_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - if (p != NULL) { - UTHFreePacket(p); - } - return retval; -} - -static int DetectBase64DecodeTestDecodeLargeOffset(void) -{ - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Packet *p = NULL; - int retval = 0; - - uint8_t payload[] = { - 'S', 'G', 'V', 's', 'b', 'G', '8', 'g', - 'V', '2', '9', 'y', 'b', 'G', 'Q', '=', - }; - - memset(&tv, 0, sizeof(tv)); - - if ((de_ctx = DetectEngineCtxInit()) == NULL) { - goto end; - } - - /* Offset is out of range. */ - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"base64 test\"; " - "base64_decode: bytes 16, offset 32; " - "sid:1; rev:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_TCP); - if (p == NULL) { - goto end; - } - - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (det_ctx->base64_decoded_len != 0) { - goto end; - } - - retval = 1; -end: - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&tv, det_ctx); - } - if (de_ctx != NULL) { - SigCleanSignatures(de_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - if (p != NULL) { - UTHFreePacket(p); - } - return retval; -} - -static int DetectBase64DecodeTestDecodeRelative(void) -{ - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Packet *p = NULL; - int retval = 0; - - uint8_t payload[] = { - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'S', 'G', 'V', 's', 'b', 'G', '8', 'g', - 'V', '2', '9', 'y', 'b', 'G', 'Q', '=', - }; - char decoded[] = "Hello World"; - - memset(&tv, 0, sizeof(tv)); - - if ((de_ctx = DetectEngineCtxInit()) == NULL) { - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"base64 test\"; " - "content:\"aaaaaaaa\"; " - "base64_decode: relative; " - "sid:1; rev:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_TCP); - if (p == NULL) { - goto end; - } - - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (det_ctx->base64_decoded_len != (int)strlen(decoded)) { - goto end; - } - if (memcmp(det_ctx->base64_decoded, decoded, strlen(decoded))) { - goto end; - } - - retval = 1; -end: - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&tv, det_ctx); - } - if (de_ctx != NULL) { - SigCleanSignatures(de_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - if (p != NULL) { - UTHFreePacket(p); - } - return retval; -} - -#endif - -static void DetectBase64DecodeRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectBase64TestDecodeParse", DetectBase64TestDecodeParse, - 1); - UtRegisterTest("DetectBase64DecodeTestSetup", DetectBase64DecodeTestSetup, - 1); - UtRegisterTest("DetectBase64DecodeHttpHeaderTestSetup", - DetectBase64DecodeHttpHeaderTestSetup, 1); - UtRegisterTest("DetectBase64DecodeTestDecode", DetectBase64DecodeTestDecode, - 1); - UtRegisterTest("DetectBase64DecodeTestDecodeWithOffset", - DetectBase64DecodeTestDecodeWithOffset, 1); - UtRegisterTest("DetectBase64DecodeTestDecodeLargeOffset", - DetectBase64DecodeTestDecodeLargeOffset, 1); - UtRegisterTest("DetectBase64DecodeTestDecodeRelative", - DetectBase64DecodeTestDecodeRelative, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-base64-decode.h b/framework/src/suricata/src/detect-base64-decode.h deleted file mode 100644 index a1ce388f..00000000 --- a/framework/src/suricata/src/detect-base64-decode.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __DETECT_BASE64_DECODE_H__ -#define __DETECT_BASE64_DECODE_H__ - -#include "app-layer-template.h" - -typedef struct DetectBase64Decode_ { - uint32_t bytes; - uint32_t offset; - uint8_t relative; -} DetectBase64Decode; - -void DetectBase64DecodeRegister(void); -int DetectBase64DecodeDoMatch(DetectEngineThreadCtx *, Signature *, - const SigMatch *, uint8_t *, uint32_t); - -#endif /* __DETECT_BASE64_DECODE_H__ */ diff --git a/framework/src/suricata/src/detect-byte-extract.c b/framework/src/suricata/src/detect-byte-extract.c deleted file mode 100644 index bc8bdf2d..00000000 --- a/framework/src/suricata/src/detect-byte-extract.c +++ /dev/null @@ -1,4897 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" -#include "detect-pcre.h" -#include "detect-bytejump.h" -#include "detect-bytetest.h" -#include "detect-byte-extract.h" -#include "detect-isdataat.h" - -#include "app-layer-protos.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-byte.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" - -/* the default value of endianess to be used, if none's specified */ -#define DETECT_BYTE_EXTRACT_ENDIAN_DEFAULT DETECT_BYTE_EXTRACT_ENDIAN_BIG - -/* the base to be used if string mode is specified. These options would be - * specified in DetectByteParseData->base */ -#define DETECT_BYTE_EXTRACT_BASE_NONE 0 -#define DETECT_BYTE_EXTRACT_BASE_HEX 16 -#define DETECT_BYTE_EXTRACT_BASE_DEC 10 -#define DETECT_BYTE_EXTRACT_BASE_OCT 8 - -/* the default value for multiplier. Either ways we always store a - * multiplier, 1 or otherwise, so that we can always multiply the extracted - * value and store it, instead of checking if a multiplier is set or not */ -#define DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT 1 -/* the min/max limit for multiplier */ -#define DETECT_BYTE_EXTRACT_MULTIPLIER_MIN_LIMIT 1 -#define DETECT_BYTE_EXTRACT_MULTIPLIER_MAX_LIMIT 65535 - -/* the max no of bytes that can be extracted in string mode - (string, hex) - * (string, oct) or (string, dec) */ -#define STRING_MAX_BYTES_TO_EXTRACT_FOR_OCT 23 -#define STRING_MAX_BYTES_TO_EXTRACT_FOR_DEC 20 -#define STRING_MAX_BYTES_TO_EXTRACT_FOR_HEX 14 -/* the max no of bytes that can be extraced in non-string mode */ -#define NO_STRING_MAX_BYTES_TO_EXTRACT 8 - -#define PARSE_REGEX "^" \ - "\\s*([0-9]+)\\s*" \ - ",\\s*(-?[0-9]+)\\s*" \ - ",\\s*([^\\s,]+)\\s*" \ - "(?:(?:,\\s*([^\\s,]+)\\s*)|(?:,\\s*([^\\s,]+)\\s+([^\\s,]+)\\s*))?" \ - "(?:(?:,\\s*([^\\s,]+)\\s*)|(?:,\\s*([^\\s,]+)\\s+([^\\s,]+)\\s*))?" \ - "(?:(?:,\\s*([^\\s,]+)\\s*)|(?:,\\s*([^\\s,]+)\\s+([^\\s,]+)\\s*))?" \ - "(?:(?:,\\s*([^\\s,]+)\\s*)|(?:,\\s*([^\\s,]+)\\s+([^\\s,]+)\\s*))?" \ - "(?:(?:,\\s*([^\\s,]+)\\s*)|(?:,\\s*([^\\s,]+)\\s+([^\\s,]+)\\s*))?" \ - "$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectByteExtractMatch(ThreadVars *, DetectEngineThreadCtx *, - Packet *, Signature *, SigMatch *); -int DetectByteExtractSetup(DetectEngineCtx *, Signature *, char *); -void DetectByteExtractRegisterTests(void); -void DetectByteExtractFree(void *); - -/** - * \brief Registers the keyword handlers for the "byte_extract" keyword. - */ -void DetectByteExtractRegister(void) -{ - const char *eb; - int eo; - int opts = 0; - - sigmatch_table[DETECT_BYTE_EXTRACT].name = "byte_extract"; - sigmatch_table[DETECT_BYTE_EXTRACT].Match = NULL; - sigmatch_table[DETECT_BYTE_EXTRACT].AppLayerMatch = NULL; - sigmatch_table[DETECT_BYTE_EXTRACT].Setup = DetectByteExtractSetup; - sigmatch_table[DETECT_BYTE_EXTRACT].Free = DetectByteExtractFree; - sigmatch_table[DETECT_BYTE_EXTRACT].RegisterTests = DetectByteExtractRegisterTests; - - sigmatch_table[DETECT_BYTE_EXTRACT].flags |= SIGMATCH_PAYLOAD; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed " - "at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - error: - return; -} - -int DetectByteExtractDoMatch(DetectEngineThreadCtx *det_ctx, SigMatch *sm, - Signature *s, uint8_t *payload, - uint16_t payload_len, uint64_t *value, - uint8_t endian) -{ - DetectByteExtractData *data = (DetectByteExtractData *)sm->ctx; - uint8_t *ptr = NULL; - int32_t len = 0; - uint64_t val = 0; - int extbytes; - - if (payload_len == 0) { - return 0; - } - - /* Calculate the ptr value for the bytetest and length remaining in - * the packet from that point. - */ - if (data->flags & DETECT_BYTE_EXTRACT_FLAG_RELATIVE) { - SCLogDebug("relative, working with det_ctx->buffer_offset %"PRIu32", " - "data->offset %"PRIu32"", det_ctx->buffer_offset, data->offset); - - ptr = payload + det_ctx->buffer_offset; - len = payload_len - det_ctx->buffer_offset; - - ptr += data->offset; - len -= data->offset; - - /* No match if there is no relative base */ - if (len <= 0) { - return 0; - } - //PrintRawDataFp(stdout,ptr,len); - } else { - SCLogDebug("absolute, data->offset %"PRIu32"", data->offset); - - ptr = payload + data->offset; - len = payload_len - data->offset; - } - - /* Validate that the to-be-extracted is within the packet */ - if (ptr < payload || data->nbytes > len) { - SCLogDebug("Data not within payload pkt=%p, ptr=%p, len=%"PRIu32", nbytes=%d", - payload, ptr, len, data->nbytes); - return 0; - } - - /* Extract the byte data */ - if (data->flags & DETECT_BYTE_EXTRACT_FLAG_STRING) { - extbytes = ByteExtractStringUint64(&val, data->base, - data->nbytes, (const char *)ptr); - if (extbytes <= 0) { - /* strtoull() return 0 if there is no numeric value in data string */ - if (val == 0) { - SCLogDebug("No Numeric value"); - return 0; - } else { - SCLogError(SC_ERR_INVALID_NUM_BYTES, "Error extracting %d " - "bytes of string data: %d", data->nbytes, extbytes); - return -1; - } - } - } else { - int endianness = (endian == DETECT_BYTE_EXTRACT_ENDIAN_BIG) ? - BYTE_BIG_ENDIAN : BYTE_LITTLE_ENDIAN; - extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr); - if (extbytes != data->nbytes) { - SCLogError(SC_ERR_INVALID_NUM_BYTES, "Error extracting %d bytes " - "of numeric data: %d\n", data->nbytes, extbytes); - return 0; - } - } - - /* Adjust the jump value based on flags */ - val *= data->multiplier_value; - if (data->flags & DETECT_BYTE_EXTRACT_FLAG_ALIGN) { - if ((val % data->align_value) != 0) { - val += data->align_value - (val % data->align_value); - } - } - - ptr += extbytes; - - det_ctx->buffer_offset = ptr - payload; - - *value = val; - - return 1; -} - - -int DetectByteExtractMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, SigMatch *m) -{ - goto end; - end: - return 1; -} - -/** - * \internal - * \brief Used to parse byte_extract arg. - * - * \arg The argument to parse. - * - * \param bed On success an instance containing the parsed data. - * On failure, NULL. - */ -static inline DetectByteExtractData *DetectByteExtractParse(char *arg) -{ - DetectByteExtractData *bed = NULL; -#define MAX_SUBSTRINGS 100 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - int i = 0; - - ret = pcre_exec(parse_regex, parse_regex_study, arg, - strlen(arg), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 3 || ret > 19) { - SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32 - ", string \"%s\"", ret, arg); - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid arg to byte_extract : %s " - "for byte_extract", arg); - goto error; - } - - bed = SCMalloc(sizeof(DetectByteExtractData)); - if (unlikely(bed == NULL)) - goto error; - memset(bed, 0, sizeof(DetectByteExtractData)); - - /* no of bytes to extract */ - char nbytes_str[64] = ""; - res = pcre_copy_substring((char *)arg, ov, - MAX_SUBSTRINGS, 1, nbytes_str, sizeof(nbytes_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed " - "for arg 1 for byte_extract"); - goto error; - } - bed->nbytes = atoi(nbytes_str); - - /* offset */ - char offset_str[64] = ""; - res = pcre_copy_substring((char *)arg, ov, - MAX_SUBSTRINGS, 2, offset_str, sizeof(offset_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed " - "for arg 2 for byte_extract"); - goto error; - } - int offset = atoi(offset_str); - if (offset < -65535 || offset > 65535) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "byte_extract offset invalid - %d. " - "The right offset range is -65535 to 65535", offset); - goto error; - } - bed->offset = offset; - - /* var name */ - char varname_str[256] = ""; - res = pcre_copy_substring((char *)arg, ov, - MAX_SUBSTRINGS, 3, varname_str, sizeof(varname_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed " - "for arg 3 for byte_extract"); - goto error; - } - bed->name = SCStrdup(varname_str); - if (bed->name == NULL) - goto error; - - /* check out other optional args */ - for (i = 4; i < ret; i++) { - char opt_str[64] = ""; - res = pcre_copy_substring((char *)arg, ov, - MAX_SUBSTRINGS, i, opt_str, sizeof(opt_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed " - "for arg %d for byte_extract", i); - goto error; - } - - if (strcmp("relative", opt_str) == 0) { - if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_RELATIVE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "relative specified more " - "than once for byte_extract"); - goto error; - } - bed->flags |= DETECT_BYTE_EXTRACT_FLAG_RELATIVE; - } else if (strcmp("multiplier", opt_str) == 0) { - if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_MULTIPLIER) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "multiplier specified more " - "than once for byte_extract"); - goto error; - } - bed->flags |= DETECT_BYTE_EXTRACT_FLAG_MULTIPLIER; - i++; - - char multiplier_str[16] = ""; - res = pcre_copy_substring((char *)arg, ov, - MAX_SUBSTRINGS, i, multiplier_str, sizeof(multiplier_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed " - "for arg %d for byte_extract", i); - goto error; - } - int multiplier = atoi(multiplier_str); - if (multiplier < DETECT_BYTE_EXTRACT_MULTIPLIER_MIN_LIMIT || - multiplier > DETECT_BYTE_EXTRACT_MULTIPLIER_MAX_LIMIT) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "multipiler_value invalid " - "- %d. The range is %d-%d", - multiplier, - DETECT_BYTE_EXTRACT_MULTIPLIER_MIN_LIMIT, - DETECT_BYTE_EXTRACT_MULTIPLIER_MAX_LIMIT); - goto error; - } - bed->multiplier_value = multiplier; - } else if (strcmp("big", opt_str) == 0) { - if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "endian option specified " - "more than once for byte_extract"); - goto error; - } - bed->flags |= DETECT_BYTE_EXTRACT_FLAG_ENDIAN; - bed->endian = DETECT_BYTE_EXTRACT_ENDIAN_BIG; - } else if (strcmp("little", opt_str) == 0) { - if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "endian option specified " - "more than once for byte_extract"); - goto error; - } - bed->flags |= DETECT_BYTE_EXTRACT_FLAG_ENDIAN; - bed->endian = DETECT_BYTE_EXTRACT_ENDIAN_LITTLE; - } else if (strcmp("dce", opt_str) == 0) { - if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "endian option specified " - "more than once for byte_extract"); - goto error; - } - bed->flags |= DETECT_BYTE_EXTRACT_FLAG_ENDIAN; - bed->endian = DETECT_BYTE_EXTRACT_ENDIAN_DCE; - } else if (strcmp("string", opt_str) == 0) { - if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_STRING) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "string specified more " - "than once for byte_extract"); - goto error; - } - if (bed->base != DETECT_BYTE_EXTRACT_BASE_NONE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "The right way to specify " - "base is (string, base) and not (base, string) " - "for byte_extract"); - goto error; - } - bed->flags |= DETECT_BYTE_EXTRACT_FLAG_STRING; - } else if (strcmp("hex", opt_str) == 0) { - if (!(bed->flags & DETECT_BYTE_EXTRACT_FLAG_STRING)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Base(hex) specified " - "without specifying string. The right way is " - "(string, base) and not (base, string)"); - goto error; - } - if (bed->base != DETECT_BYTE_EXTRACT_BASE_NONE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "More than one base " - "specified for byte_extract"); - goto error; - } - bed->base = DETECT_BYTE_EXTRACT_BASE_HEX; - } else if (strcmp("oct", opt_str) == 0) { - if (!(bed->flags & DETECT_BYTE_EXTRACT_FLAG_STRING)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Base(oct) specified " - "without specifying string. The right way is " - "(string, base) and not (base, string)"); - goto error; - } - if (bed->base != DETECT_BYTE_EXTRACT_BASE_NONE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "More than one base " - "specified for byte_extract"); - goto error; - } - bed->base = DETECT_BYTE_EXTRACT_BASE_OCT; - } else if (strcmp("dec", opt_str) == 0) { - if (!(bed->flags & DETECT_BYTE_EXTRACT_FLAG_STRING)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Base(dec) specified " - "without specifying string. The right way is " - "(string, base) and not (base, string)"); - goto error; - } - if (bed->base != DETECT_BYTE_EXTRACT_BASE_NONE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "More than one base " - "specified for byte_extract"); - goto error; - } - bed->base = DETECT_BYTE_EXTRACT_BASE_DEC; - } else if (strcmp("align", opt_str) == 0) { - if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_ALIGN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Align specified more " - "than once for byte_extract"); - goto error; - } - bed->flags |= DETECT_BYTE_EXTRACT_FLAG_ALIGN; - i++; - - char align_str[16] = ""; - res = pcre_copy_substring((char *)arg, ov, - MAX_SUBSTRINGS, i, align_str, sizeof(align_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed " - "for arg %d in byte_extract", i); - goto error; - } - bed->align_value = atoi(align_str); - if (!(bed->align_value == 2 || bed->align_value == 4)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid align_value for " - "byte_extract - \"%d\"", bed->align_value); - goto error; - } - } else if (strcmp("", opt_str) == 0) { - ; - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid option - \"%s\" " - "specified in byte_extract", opt_str); - goto error; - } - } /* for (i = 4; i < ret; i++) */ - - /* validation */ - if (!(bed->flags & DETECT_BYTE_EXTRACT_FLAG_MULTIPLIER)) { - /* default value */ - bed->multiplier_value = DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT; - } - - if (bed->flags & DETECT_BYTE_EXTRACT_FLAG_STRING) { - if (bed->base == DETECT_BYTE_EXTRACT_BASE_NONE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Base not specified for " - "byte_extract, though string was specified. " - "The right options are (string, hex), (string, oct) " - "or (string, dec)"); - goto error; - } - if (bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "byte_extract can't have " - "endian \"big\" or \"little\" specified along with " - "\"string\""); - goto error; - } - if (bed->base == DETECT_BYTE_EXTRACT_BASE_OCT) { - /* if are dealing with octal nos, the max no that can fit in a 8 - * byte value is 01777777777777777777777 */ - if (bed->nbytes > STRING_MAX_BYTES_TO_EXTRACT_FOR_OCT) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "byte_extract can't process " - "more than %d bytes in \"string\" extraction", - STRING_MAX_BYTES_TO_EXTRACT_FOR_OCT); - goto error; - } - } else if (bed->base == DETECT_BYTE_EXTRACT_BASE_DEC) { - /* if are dealing with decimal nos, the max no that can fit in a 8 - * byte value is 18446744073709551615 */ - if (bed->nbytes > STRING_MAX_BYTES_TO_EXTRACT_FOR_DEC) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "byte_extract can't process " - "more than %d bytes in \"string\" extraction", - STRING_MAX_BYTES_TO_EXTRACT_FOR_DEC); - goto error; - } - } else if (bed->base == DETECT_BYTE_EXTRACT_BASE_HEX) { - /* if are dealing with hex nos, the max no that can fit in a 8 - * byte value is 0xFFFFFFFFFFFFFFFF */ - if (bed->nbytes > STRING_MAX_BYTES_TO_EXTRACT_FOR_HEX) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "byte_extract can't process " - "more than %d bytes in \"string\" extraction", - STRING_MAX_BYTES_TO_EXTRACT_FOR_HEX); - goto error; - } - } else { - ; // just a placeholder. we won't reach here. - } - } else { - if (bed->nbytes > NO_STRING_MAX_BYTES_TO_EXTRACT) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "byte_extract can't process " - "more than %d bytes in \"non-string\" extraction", - NO_STRING_MAX_BYTES_TO_EXTRACT); - goto error; - } - /* if string has not been specified and no endian option has been - * specified, then set the default endian level of BIG */ - if (!(bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN)) - bed->endian = DETECT_BYTE_EXTRACT_ENDIAN_DEFAULT; - } - - return bed; - error: - if (bed != NULL) - DetectByteExtractFree(bed); - return NULL; -} - -/** - * \brief The setup function for the byte_extract keyword for a signature. - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to signature for the current Signature being parsed - * from the rules. - * \param m Pointer to the head of the SigMatch for the current rule - * being parsed. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectByteExtractSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - SigMatch *sm = NULL; - SigMatch *prev_pm = NULL; - DetectByteExtractData *data = NULL; - int ret = -1; - - data = DetectByteExtractParse(arg); - if (data == NULL) - goto error; - - int sm_list; - if (s->list != DETECT_SM_LIST_NOTSET) { - if (s->list == DETECT_SM_LIST_FILEDATA) { - if (data->endian == DETECT_BYTE_EXTRACT_ENDIAN_DCE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "dce byte_extract specified " - "with file_data option set."); - goto error; - } - AppLayerHtpEnableResponseBodyCallback(); - } - sm_list = s->list; - s->flags |= SIG_FLAG_APPLAYER; - if (data->flags & DETECT_BYTE_EXTRACT_FLAG_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, s->sm_lists_tail[sm_list], - DETECT_PCRE, s->sm_lists_tail[sm_list]); - } - } else if (data->endian == DETECT_BYTE_EXTRACT_ENDIAN_DCE) { - if (data->flags & DETECT_BYTE_EXTRACT_FLAG_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 12, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); - if (prev_pm == NULL) { - sm_list = DETECT_SM_LIST_PMATCH; - } else { - sm_list = SigMatchListSMBelongsTo(s, prev_pm); - if (sm_list < 0) - goto error; - } - } else { - sm_list = DETECT_SM_LIST_PMATCH; - } - - s->alproto = ALPROTO_DCERPC; - s->flags |= SIG_FLAG_APPLAYER; - - } else if (data->flags & DETECT_BYTE_EXTRACT_FLAG_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 168, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - if (prev_pm == NULL) { - sm_list = DETECT_SM_LIST_PMATCH; - } else { - sm_list = SigMatchListSMBelongsTo(s, prev_pm); - if (sm_list < 0) - goto error; - if (sm_list != DETECT_SM_LIST_PMATCH) - s->flags |= SIG_FLAG_APPLAYER; - } - - } else { - sm_list = DETECT_SM_LIST_PMATCH; - } - - if (data->endian == DETECT_BYTE_EXTRACT_ENDIAN_DCE) { - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_DCERPC) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Non dce alproto sig has " - "byte_extract with dce enabled"); - goto error; - } - s->alproto = ALPROTO_DCERPC; - if ((data->flags & DETECT_BYTE_EXTRACT_FLAG_STRING) || - (data->base == DETECT_BYTE_EXTRACT_BASE_DEC) || - (data->base == DETECT_BYTE_EXTRACT_BASE_HEX) || - (data->base == DETECT_BYTE_EXTRACT_BASE_OCT) ) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. " - "A byte_jump keyword with dce holds other invalid modifiers."); - goto error; - } - } - - SigMatch *prev_bed_sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_BYTE_EXTRACT, s->sm_lists_tail[sm_list]); - if (prev_bed_sm == NULL) - data->local_id = 0; - else - data->local_id = ((DetectByteExtractData *)prev_bed_sm->ctx)->local_id + 1; - if (data->local_id > de_ctx->byte_extract_max_local_id) - de_ctx->byte_extract_max_local_id = data->local_id; - - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - sm->type = DETECT_BYTE_EXTRACT; - sm->ctx = (void *)data; - SigMatchAppendSMToList(s, sm, sm_list); - - - if (!(data->flags & DETECT_BYTE_EXTRACT_FLAG_RELATIVE)) - goto okay; - - if (prev_pm == NULL) - goto okay; - - if (prev_pm->type == DETECT_CONTENT) { - DetectContentData *cd = (DetectContentData *)prev_pm->ctx; - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - } else if (prev_pm->type == DETECT_PCRE) { - DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx; - pd->flags |= DETECT_PCRE_RELATIVE_NEXT; - } - - okay: - ret = 0; - return ret; - error: - DetectByteExtractFree(data); - return ret; -} - -/** - * \brief Used to free instances of DetectByteExtractData. - * - * \param ptr Instance of DetectByteExtractData to be freed. - */ -void DetectByteExtractFree(void *ptr) -{ - if (ptr != NULL) { - DetectByteExtractData *bed = ptr; - if (bed->name != NULL) - SCFree((void *)bed->name); - SCFree(bed); - } - - return; -} - -/** - * \brief Lookup the SigMatch for a named byte_extract variable. - * - * \param arg The name of the byte_extract variable to lookup. - * \param s Pointer the signature to look in. - * - * \retval A pointer to the SigMatch if found, otherwise NULL. - */ -SigMatch *DetectByteExtractRetrieveSMVar(const char *arg, Signature *s) -{ - DetectByteExtractData *bed = NULL; - int list; - - for (list = 0; list < DETECT_SM_LIST_MAX; list++) { - SigMatch *sm = s->sm_lists[list]; - while (sm != NULL) { - if (sm->type == DETECT_BYTE_EXTRACT) { - bed = (DetectByteExtractData *)sm->ctx; - if (strcmp(bed->name, arg) == 0) { - return sm; - } - } - sm = sm->next; - } - } - - return NULL; -} - -/*************************************Unittests********************************/ - -#ifdef UNITTESTS - -int DetectByteExtractTest01(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != 0 || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_DEFAULT || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest02(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, relative"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_RELATIVE || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_DEFAULT || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest03(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, multiplier 10"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_MULTIPLIER || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_DEFAULT || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 0 || - bed->multiplier_value != 10) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest04(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, relative, multiplier 10"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_RELATIVE | - DETECT_BYTE_EXTRACT_FLAG_MULTIPLIER) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_DEFAULT || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 0 || - bed->multiplier_value != 10) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest05(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, big"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_ENDIAN || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_BIG || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest06(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, little"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_ENDIAN || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_LITTLE || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest07(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, dce"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_ENDIAN || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_DCE || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest08(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, string, hex"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest09(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, string, oct"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_OCT || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest10(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, string, dec"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_DEC || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest11(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_ALIGN || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_DEFAULT || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 4 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest12(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, relative"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_ALIGN | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_DEFAULT || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 4 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest13(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, relative, big"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_ALIGN | - DETECT_BYTE_EXTRACT_FLAG_ENDIAN | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_BIG || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 4 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest14(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, relative, dce"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_ALIGN | - DETECT_BYTE_EXTRACT_FLAG_ENDIAN | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_DCE || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 4 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest15(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, relative, little"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_ALIGN | - DETECT_BYTE_EXTRACT_FLAG_ENDIAN | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_LITTLE || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 4 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest16(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, relative, little, multiplier 2"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != 2 || - strcmp(bed->name, "one") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_ALIGN | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE | - DETECT_BYTE_EXTRACT_FLAG_ENDIAN | - DETECT_BYTE_EXTRACT_FLAG_MULTIPLIER) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_LITTLE || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 4 || - bed->multiplier_value != 2) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest17(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, " - "relative, little, " - "multiplier 2, string hex"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest18(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, " - "relative, little, " - "multiplier 2, " - "relative"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest19(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, " - "relative, little, " - "multiplier 2, " - "little"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest20(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, " - "relative, " - "multiplier 2, " - "align 2"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest21(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, " - "multiplier 2, " - "relative, " - "multiplier 2"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest22(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, " - "string hex, " - "relative, " - "string hex"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest23(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, " - "string hex, " - "relative, " - "string oct"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest24(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("24, 2, one, align 4, " - "string hex, " - "relative"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest25(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("9, 2, one, align 4, " - "little, " - "relative"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest26(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, " - "little, " - "relative, " - "multiplier 65536"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest27(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, 2, one, align 4, " - "little, " - "relative, " - "multiplier 0"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest28(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("23, 2, one, string, oct"); - if (bed == NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest29(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("24, 2, one, string, oct"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest30(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("20, 2, one, string, dec"); - if (bed == NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest31(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("21, 2, one, string, dec"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest32(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("14, 2, one, string, hex"); - if (bed == NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest33(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("15, 2, one, string, hex"); - if (bed != NULL) - goto end; - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -int DetectByteExtractTest34(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,2,two,relative,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 2 || - strncmp(bed->name, "two", cd->content_len) != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_RELATIVE | - DETECT_BYTE_EXTRACT_FLAG_STRING) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest35(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectPcreData *pd = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; pcre:/asf/; " - "byte_extract:4,0,two,relative,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_PCRE) { - result = 0; - goto end; - } - pd = (DetectPcreData *)sm->ctx; - if (pd->flags != DETECT_PCRE_RELATIVE_NEXT) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_RELATIVE | - DETECT_BYTE_EXTRACT_FLAG_STRING) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest36(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectBytejumpData *bjd = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; byte_jump:1,13; " - "byte_extract:4,0,two,relative,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_RELATIVE | - DETECT_BYTE_EXTRACT_FLAG_STRING) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest37(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectContentData *ud = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; uricontent:\"two\"; " - "byte_extract:4,0,two,relative,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)ud->content, "two", cd->content_len) != 0 || - ud->flags & DETECT_CONTENT_NOCASE || - ud->flags & DETECT_CONTENT_WITHIN || - ud->flags & DETECT_CONTENT_DISTANCE || - ud->flags & DETECT_CONTENT_FAST_PATTERN || - !(ud->flags & DETECT_CONTENT_RELATIVE_NEXT) || - ud->flags & DETECT_CONTENT_NEGATED ) { - printf("two failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_RELATIVE | - DETECT_BYTE_EXTRACT_FLAG_STRING) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest38(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectContentData *ud = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; uricontent:\"two\"; " - "byte_extract:4,0,two,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags !=DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)ud->content, "two", cd->content_len) != 0 || - ud->flags & DETECT_CONTENT_NOCASE || - ud->flags & DETECT_CONTENT_WITHIN || - ud->flags & DETECT_CONTENT_DISTANCE || - ud->flags & DETECT_CONTENT_FAST_PATTERN || - ud->flags & DETECT_CONTENT_RELATIVE_NEXT || - ud->flags & DETECT_CONTENT_NEGATED ) { - printf("two failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) { - result = 0; - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest39(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectContentData *ud = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; content:\"two\"; http_uri; " - "byte_extract:4,0,two,relative,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)ud->content, "two", cd->content_len) != 0 || - ud->flags & DETECT_CONTENT_NOCASE || - ud->flags & DETECT_CONTENT_WITHIN || - ud->flags & DETECT_CONTENT_DISTANCE || - ud->flags & DETECT_CONTENT_FAST_PATTERN || - !(ud->flags & DETECT_CONTENT_RELATIVE_NEXT) || - ud->flags & DETECT_CONTENT_NEGATED ) { - printf("two failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_RELATIVE | - DETECT_BYTE_EXTRACT_FLAG_STRING) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest40(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectContentData *ud = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; content:\"two\"; http_uri; " - "byte_extract:4,0,two,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags !=DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)ud->content, "two", cd->content_len) != 0 || - ud->flags & DETECT_CONTENT_NOCASE || - ud->flags & DETECT_CONTENT_WITHIN || - ud->flags & DETECT_CONTENT_DISTANCE || - ud->flags & DETECT_CONTENT_FAST_PATTERN || - ud->flags & DETECT_CONTENT_RELATIVE_NEXT || - ud->flags & DETECT_CONTENT_NEGATED ) { - printf("two failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) { - result = 0; - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest41(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "three") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 1) { - result = 0; - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest42(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectContentData *ud = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "uricontent: \"three\"; " - "byte_extract:4,0,four,string,hex,relative; " - "byte_extract:4,0,five,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "five") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 1) { - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)ud->content, "three", cd->content_len) != 0 || - ud->flags & DETECT_CONTENT_NOCASE || - ud->flags & DETECT_CONTENT_WITHIN || - ud->flags & DETECT_CONTENT_DISTANCE || - ud->flags & DETECT_CONTENT_FAST_PATTERN || - !(ud->flags & DETECT_CONTENT_RELATIVE_NEXT) || - ud->flags & DETECT_CONTENT_NEGATED ) { - printf("two failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "four") != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_RELATIVE | - DETECT_BYTE_EXTRACT_FLAG_STRING) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 0) { - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest43(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "content: \"three\"; offset:two; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "three", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_OFFSET_BE | - DETECT_CONTENT_OFFSET) || - cd->offset != bed->local_id) { - printf("three failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest44(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectByteExtractData *bed2 = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "content: \"four\"; offset:two; " - "content: \"five\"; offset:three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed2 = (DetectByteExtractData *)sm->ctx; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "four", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_OFFSET_BE | - DETECT_CONTENT_OFFSET) || - cd->offset != bed1->local_id) { - printf("four failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "five", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_OFFSET_BE | - DETECT_CONTENT_OFFSET) || - cd->offset != bed2->local_id) { - printf("five failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest45(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "content: \"three\"; depth:two; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "three", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_DEPTH_BE | - DETECT_CONTENT_DEPTH) || - cd->depth != bed->local_id || - cd->offset != 0) { - printf("three failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest46(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectByteExtractData *bed2 = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "content: \"four\"; depth:two; " - "content: \"five\"; depth:three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed2 = (DetectByteExtractData *)sm->ctx; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "four", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_DEPTH_BE | - DETECT_CONTENT_DEPTH) || - cd->depth != bed1->local_id) { - printf("four failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "five", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_DEPTH_BE | - DETECT_CONTENT_DEPTH) || - cd->depth != bed2->local_id) { - printf("five failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest47(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "content: \"three\"; distance:two; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "three", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_DISTANCE_BE | - DETECT_CONTENT_DISTANCE) || - cd->distance != bed->local_id || - cd->offset != 0 || - cd->depth != 0) { - printf("three failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest48(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectByteExtractData *bed2 = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "content: \"four\"; distance:two; " - "content: \"five\"; distance:three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed2 = (DetectByteExtractData *)sm->ctx; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "four", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_DISTANCE_BE | - DETECT_CONTENT_DISTANCE | - DETECT_CONTENT_RELATIVE_NEXT) || - cd->distance != bed1->local_id || - cd->depth != 0 || - cd->offset != 0) { - printf("four failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "five", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_DISTANCE_BE | - DETECT_CONTENT_DISTANCE) || - cd->distance != bed2->local_id || - cd->depth != 0 || - cd->offset != 0) { - printf("five failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest49(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "content: \"three\"; within:two; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "three", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_WITHIN_BE | - DETECT_CONTENT_WITHIN) || - cd->within != bed->local_id || - cd->offset != 0 || - cd->depth != 0 || - cd->distance != 0) { - printf("three failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest50(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectByteExtractData *bed2 = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "content: \"four\"; within:two; " - "content: \"five\"; within:three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed2 = (DetectByteExtractData *)sm->ctx; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "four", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_WITHIN_BE | - DETECT_CONTENT_WITHIN| - DETECT_CONTENT_RELATIVE_NEXT) || - cd->within != bed1->local_id || - cd->depth != 0 || - cd->offset != 0 || - cd->distance != 0) { - printf("four failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "five", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_WITHIN_BE | - DETECT_CONTENT_WITHIN) || - cd->within != bed2->local_id || - cd->depth != 0 || - cd->offset != 0 || - cd->distance != 0) { - printf("five failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest51(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed = NULL; - DetectBytetestData *btd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_test: 2,=,10, two; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTETEST) { - result = 0; - goto end; - } - btd = (DetectBytetestData *)sm->ctx; - if (btd->flags != DETECT_BYTETEST_OFFSET_BE || - btd->value != 10 || - btd->offset != 0) { - printf("three failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest52(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectBytetestData *btd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "byte_test: 2,=,two,three; " - "byte_test: 3,=,10,three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTETEST) { - result = 0; - goto end; - } - btd = (DetectBytetestData *)sm->ctx; - if (btd->flags != (DETECT_BYTETEST_OFFSET_BE | - DETECT_BYTETEST_VALUE_BE) || - btd->value != 0 || - btd->offset != 1) { - printf("three failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTETEST) { - result = 0; - goto end; - } - btd = (DetectBytetestData *)sm->ctx; - if (btd->flags != DETECT_BYTETEST_OFFSET_BE || - btd->value != 10 || - btd->offset != 1) { - printf("four failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest53(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed = NULL; - DetectBytejumpData *bjd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_jump: 2,two; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 0 || - strcmp(bed->name, "two") != 0 || - bed->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || - bjd->offset != 0) { - printf("three failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest54(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectBytejumpData *bjd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "byte_jump: 2,two; " - "byte_jump: 3,three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || - bjd->offset != 0) { - printf("three failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || - bjd->offset != 1) { - printf("four failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest55(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectByteExtractData *bed2 = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing byte_extract\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "byte_extract:4,0,four,string,hex; " - "byte_extract:4,0,five,string,hex; " - "content: \"four\"; within:two; distance:three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed: "); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - goto end; - } - bed2 = (DetectByteExtractData *)sm->ctx; - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "four", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_DISTANCE_BE | - DETECT_CONTENT_WITHIN_BE | - DETECT_CONTENT_DISTANCE | - DETECT_CONTENT_WITHIN) || - cd->within != bed1->local_id || - cd->distance != bed2->local_id) { - printf("four failed: "); - goto end; - } - - if (sm->next != NULL) { - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest56(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectByteExtractData *bed2 = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "uricontent:\"urione\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "byte_extract:4,0,four,string,hex; " - "byte_extract:4,0,five,string,hex; " - "content: \"four\"; within:two; distance:three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "urione", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed2 = (DetectByteExtractData *)sm->ctx; - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "four", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_DISTANCE_BE | - DETECT_CONTENT_WITHIN_BE | - DETECT_CONTENT_DISTANCE | - DETECT_CONTENT_WITHIN) || - cd->within != bed1->local_id || - cd->distance != bed2->local_id ) { - printf("four failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) { - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest57(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectByteExtractData *bed2 = NULL; - DetectByteExtractData *bed3 = NULL; - DetectByteExtractData *bed4 = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "uricontent: \"urione\"; " - "byte_extract:4,0,two,string,hex,relative; " - "byte_extract:4,0,three,string,hex,relative; " - "byte_extract:4,0,four,string,hex,relative; " - "byte_extract:4,0,five,string,hex,relative; " - "uricontent: \"four\"; within:two; distance:three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "urione", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed2 = (DetectByteExtractData *)sm->ctx; - if (bed2->local_id != 1) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed3 = (DetectByteExtractData *)sm->ctx; - if (bed3->local_id != 2) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed4 = (DetectByteExtractData *)sm->ctx; - if (bed4->local_id != 3) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (strncmp((char *)cd->content, "four", cd->content_len) != 0 || - cd->flags != (DETECT_CONTENT_DISTANCE_BE | - DETECT_CONTENT_WITHIN_BE | - DETECT_CONTENT_DISTANCE | - DETECT_CONTENT_WITHIN) || - cd->within != bed1->local_id || - cd->distance != bed2->local_id) { - printf("four failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) { - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest58(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectBytejumpData *bjd = NULL; - DetectIsdataatData *isdd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "byte_jump: 2,two; " - "byte_jump: 3,three; " - "isdataat: three; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || - bjd->offset != 0) { - printf("three failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || - bjd->offset != 1) { - printf("four failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_ISDATAAT) { - result = 0; - goto end; - } - isdd = (DetectIsdataatData *)sm->ctx; - if (isdd->flags != ISDATAAT_OFFSET_BE || - isdd->dataat != 1) { - printf("isdataat failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest59(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectBytejumpData *bjd = NULL; - DetectIsdataatData *isdd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex; " - "byte_extract:4,0,three,string,hex; " - "byte_jump: 2,two; " - "byte_jump: 3,three; " - "isdataat: three,relative; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - cd->flags & DETECT_CONTENT_RELATIVE_NEXT || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != DETECT_BYTE_EXTRACT_FLAG_STRING || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || - bjd->offset != 0) { - printf("three failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags != DETECT_BYTEJUMP_OFFSET_BE || - bjd->offset != 1) { - printf("four failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_ISDATAAT) { - result = 0; - goto end; - } - isdd = (DetectIsdataatData *)sm->ctx; - if (isdd->flags != (ISDATAAT_OFFSET_BE | - ISDATAAT_RELATIVE) || - isdd->dataat != 1) { - printf("isdataat failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest60(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectIsdataatData *isdd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex,relative; " - "uricontent: \"three\"; " - "byte_extract:4,0,four,string,hex,relative; " - "isdataat: two; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_ISDATAAT) { - result = 0; - goto end; - } - isdd = (DetectIsdataatData *)sm->ctx; - if (isdd->flags != (ISDATAAT_OFFSET_BE) || - isdd->dataat != bed1->local_id) { - printf("isdataat failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags != DETECT_CONTENT_RELATIVE_NEXT || - strncmp((char *)cd->content, "three", cd->content_len) != 0) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "four") != 0 || - bed1->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest61(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *cd = NULL; - DetectByteExtractData *bed1 = NULL; - DetectIsdataatData *isdd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "byte_extract:4,0,two,string,hex,relative; " - "uricontent: \"three\"; " - "byte_extract:4,0,four,string,hex,relative; " - "isdataat: four, relative; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES || - strncmp((char *)cd->content, "one", cd->content_len) != 0 || - cd->flags & DETECT_CONTENT_NOCASE || - cd->flags & DETECT_CONTENT_WITHIN || - cd->flags & DETECT_CONTENT_DISTANCE || - cd->flags & DETECT_CONTENT_FAST_PATTERN || - !(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) || - cd->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "two") != 0 || - bed1->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - cd = (DetectContentData *)sm->ctx; - if (cd->flags != DETECT_CONTENT_RELATIVE_NEXT || - strncmp((char *)cd->content, "three", cd->content_len) != 0) { - printf("one failed\n"); - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed1 = (DetectByteExtractData *)sm->ctx; - if (bed1->nbytes != 4 || - bed1->offset != 0 || - strcmp(bed1->name, "four") != 0 || - bed1->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | - DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed1->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed1->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed1->align_value != 0 || - bed1->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - if (bed1->local_id != 0) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_ISDATAAT) { - result = 0; - goto end; - } - isdd = (DetectIsdataatData *)sm->ctx; - if (isdd->flags != (ISDATAAT_OFFSET_BE | - ISDATAAT_RELATIVE) || - isdd->dataat != bed1->local_id) { - printf("isdataat failed\n"); - result = 0; - goto end; - } - - if (sm->next != NULL) - goto end; - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -static int DetectByteExtractTest62(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectByteExtractData *bed = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; byte_extract:4,2,two,relative,string,hex; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm->type != DETECT_BYTE_EXTRACT) { - result = 0; - goto end; - } - bed = (DetectByteExtractData *)sm->ctx; - if (bed->nbytes != 4 || - bed->offset != 2 || - strncmp(bed->name, "two", 3) != 0 || - bed->flags != (DETECT_BYTE_EXTRACT_FLAG_STRING | DETECT_BYTE_EXTRACT_FLAG_RELATIVE) || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_NONE || - bed->base != DETECT_BYTE_EXTRACT_BASE_HEX || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectByteExtractTest63(void) -{ - int result = 0; - - DetectByteExtractData *bed = DetectByteExtractParse("4, -2, one"); - if (bed == NULL) - goto end; - - if (bed->nbytes != 4 || - bed->offset != -2 || - strcmp(bed->name, "one") != 0 || - bed->flags != 0 || - bed->endian != DETECT_BYTE_EXTRACT_ENDIAN_DEFAULT || - bed->base != DETECT_BYTE_EXTRACT_BASE_NONE || - bed->align_value != 0 || - bed->multiplier_value != DETECT_BYTE_EXTRACT_MULTIPLIER_DEFAULT) { - goto end; - } - - result = 1; - end: - if (bed != NULL) - DetectByteExtractFree(bed); - return result; -} - -#endif /* UNITTESTS */ - -void DetectByteExtractRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectByteExtractTest01", DetectByteExtractTest01, 1); - UtRegisterTest("DetectByteExtractTest02", DetectByteExtractTest02, 1); - UtRegisterTest("DetectByteExtractTest03", DetectByteExtractTest03, 1); - UtRegisterTest("DetectByteExtractTest04", DetectByteExtractTest04, 1); - UtRegisterTest("DetectByteExtractTest05", DetectByteExtractTest05, 1); - UtRegisterTest("DetectByteExtractTest06", DetectByteExtractTest06, 1); - UtRegisterTest("DetectByteExtractTest07", DetectByteExtractTest07, 1); - UtRegisterTest("DetectByteExtractTest08", DetectByteExtractTest08, 1); - UtRegisterTest("DetectByteExtractTest09", DetectByteExtractTest09, 1); - UtRegisterTest("DetectByteExtractTest10", DetectByteExtractTest10, 1); - UtRegisterTest("DetectByteExtractTest11", DetectByteExtractTest11, 1); - UtRegisterTest("DetectByteExtractTest12", DetectByteExtractTest12, 1); - UtRegisterTest("DetectByteExtractTest13", DetectByteExtractTest13, 1); - UtRegisterTest("DetectByteExtractTest14", DetectByteExtractTest14, 1); - UtRegisterTest("DetectByteExtractTest15", DetectByteExtractTest15, 1); - UtRegisterTest("DetectByteExtractTest16", DetectByteExtractTest16, 1); - UtRegisterTest("DetectByteExtractTest17", DetectByteExtractTest17, 1); - UtRegisterTest("DetectByteExtractTest18", DetectByteExtractTest18, 1); - UtRegisterTest("DetectByteExtractTest19", DetectByteExtractTest19, 1); - UtRegisterTest("DetectByteExtractTest20", DetectByteExtractTest20, 1); - UtRegisterTest("DetectByteExtractTest21", DetectByteExtractTest21, 1); - UtRegisterTest("DetectByteExtractTest22", DetectByteExtractTest22, 1); - UtRegisterTest("DetectByteExtractTest23", DetectByteExtractTest23, 1); - UtRegisterTest("DetectByteExtractTest24", DetectByteExtractTest24, 1); - UtRegisterTest("DetectByteExtractTest25", DetectByteExtractTest25, 1); - UtRegisterTest("DetectByteExtractTest26", DetectByteExtractTest26, 1); - UtRegisterTest("DetectByteExtractTest27", DetectByteExtractTest27, 1); - UtRegisterTest("DetectByteExtractTest28", DetectByteExtractTest28, 1); - UtRegisterTest("DetectByteExtractTest29", DetectByteExtractTest29, 1); - UtRegisterTest("DetectByteExtractTest30", DetectByteExtractTest30, 1); - UtRegisterTest("DetectByteExtractTest31", DetectByteExtractTest31, 1); - UtRegisterTest("DetectByteExtractTest32", DetectByteExtractTest32, 1); - UtRegisterTest("DetectByteExtractTest33", DetectByteExtractTest33, 1); - UtRegisterTest("DetectByteExtractTest34", DetectByteExtractTest34, 1); - UtRegisterTest("DetectByteExtractTest35", DetectByteExtractTest35, 1); - UtRegisterTest("DetectByteExtractTest36", DetectByteExtractTest36, 1); - UtRegisterTest("DetectByteExtractTest37", DetectByteExtractTest37, 1); - UtRegisterTest("DetectByteExtractTest38", DetectByteExtractTest38, 1); - UtRegisterTest("DetectByteExtractTest39", DetectByteExtractTest39, 1); - UtRegisterTest("DetectByteExtractTest40", DetectByteExtractTest40, 1); - UtRegisterTest("DetectByteExtractTest41", DetectByteExtractTest41, 1); - UtRegisterTest("DetectByteExtractTest42", DetectByteExtractTest42, 1); - - UtRegisterTest("DetectByteExtractTest43", DetectByteExtractTest43, 1); - UtRegisterTest("DetectByteExtractTest44", DetectByteExtractTest44, 1); - - UtRegisterTest("DetectByteExtractTest45", DetectByteExtractTest45, 1); - UtRegisterTest("DetectByteExtractTest46", DetectByteExtractTest46, 1); - - UtRegisterTest("DetectByteExtractTest47", DetectByteExtractTest47, 1); - UtRegisterTest("DetectByteExtractTest48", DetectByteExtractTest48, 1); - - UtRegisterTest("DetectByteExtractTest49", DetectByteExtractTest49, 1); - UtRegisterTest("DetectByteExtractTest50", DetectByteExtractTest50, 1); - - UtRegisterTest("DetectByteExtractTest51", DetectByteExtractTest51, 1); - UtRegisterTest("DetectByteExtractTest52", DetectByteExtractTest52, 1); - - UtRegisterTest("DetectByteExtractTest53", DetectByteExtractTest53, 1); - UtRegisterTest("DetectByteExtractTest54", DetectByteExtractTest54, 1); - - UtRegisterTest("DetectByteExtractTest55", DetectByteExtractTest55, 1); - UtRegisterTest("DetectByteExtractTest56", DetectByteExtractTest56, 1); - UtRegisterTest("DetectByteExtractTest57", DetectByteExtractTest57, 1); - - UtRegisterTest("DetectByteExtractTest58", DetectByteExtractTest58, 1); - UtRegisterTest("DetectByteExtractTest59", DetectByteExtractTest59, 1); - UtRegisterTest("DetectByteExtractTest60", DetectByteExtractTest60, 1); - UtRegisterTest("DetectByteExtractTest61", DetectByteExtractTest61, 1); - UtRegisterTest("DetectByteExtractTest62", DetectByteExtractTest62, 1); - UtRegisterTest("DetectByteExtractTest63", DetectByteExtractTest63, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-byte-extract.h b/framework/src/suricata/src/detect-byte-extract.h deleted file mode 100644 index 020494da..00000000 --- a/framework/src/suricata/src/detect-byte-extract.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_BYTEEXTRACT_H__ -#define __DETECT_BYTEEXTRACT_H__ - -/* flags */ -#define DETECT_BYTE_EXTRACT_FLAG_RELATIVE 0x01 -#define DETECT_BYTE_EXTRACT_FLAG_MULTIPLIER 0x02 -#define DETECT_BYTE_EXTRACT_FLAG_STRING 0x04 -#define DETECT_BYTE_EXTRACT_FLAG_ALIGN 0x08 -#define DETECT_BYTE_EXTRACT_FLAG_ENDIAN 0x10 - -/* endian value to be used. Would be stored in DetectByteParseData->endian */ -#define DETECT_BYTE_EXTRACT_ENDIAN_NONE 0 -#define DETECT_BYTE_EXTRACT_ENDIAN_BIG 1 -#define DETECT_BYTE_EXTRACT_ENDIAN_LITTLE 2 -#define DETECT_BYTE_EXTRACT_ENDIAN_DCE 3 - -/** - * \brief Holds data related to byte_extract keyword. - */ -typedef struct DetectByteExtractData_ { - /* local id used by other keywords in the sig to reference this */ - uint8_t local_id; - - uint8_t nbytes; - int16_t pad; - int32_t offset; - const char *name; - uint8_t flags; - uint8_t endian; - uint8_t base; - uint8_t align_value; - - uint16_t multiplier_value; - /* unique id used to reference this byte_extract keyword */ - uint16_t id; - -} DetectByteExtractData; - -void DetectByteExtractRegister(void); -int DetectByteExtractSetup(DetectEngineCtx *, Signature *, char *); -void DetectByteExtractFree(void *); -int DetectByteExtractMatch(ThreadVars *, DetectEngineThreadCtx *, - Packet *, Signature *, SigMatch *); -SigMatch *DetectByteExtractRetrieveSMVar(const char *, Signature *); -int DetectByteExtractDoMatch(DetectEngineThreadCtx *, SigMatch *, Signature *, - uint8_t *, uint16_t, uint64_t *, uint8_t); - -#endif /* __DETECT_BYTEEXTRACT_H__ */ diff --git a/framework/src/suricata/src/detect-bytejump.c b/framework/src/suricata/src/detect-bytejump.c deleted file mode 100644 index 46a2a3e4..00000000 --- a/framework/src/suricata/src/detect-bytejump.c +++ /dev/null @@ -1,1429 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - * - * Implements byte_jump keyword. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "app-layer.h" - -#include "detect-bytejump.h" -#include "detect-byte-extract.h" -#include "detect-content.h" -#include "detect-uricontent.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "detect-pcre.h" - -/** - * \brief Regex for parsing our options - */ -#define PARSE_REGEX "^\\s*" \ - "([^\\s,]+\\s*,\\s*[^\\s,]+)" \ - "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \ - "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \ - "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \ - "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \ - "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \ - "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \ - "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \ - "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \ - "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \ - "\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -void DetectBytejumpRegisterTests(void); - -void DetectBytejumpRegister (void) -{ - const char *eb; - int eo; - int opts = 0; - - sigmatch_table[DETECT_BYTEJUMP].name = "byte_jump"; - sigmatch_table[DETECT_BYTEJUMP].Match = DetectBytejumpMatch; - sigmatch_table[DETECT_BYTEJUMP].Setup = DetectBytejumpSetup; - sigmatch_table[DETECT_BYTEJUMP].Free = DetectBytejumpFree; - sigmatch_table[DETECT_BYTEJUMP].RegisterTests = DetectBytejumpRegisterTests; - - sigmatch_table[DETECT_BYTEJUMP].flags |= SIGMATCH_PAYLOAD; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE,"pcre compile of \"%s\" failed " - "at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY,"pcre study failed: %s", eb); - goto error; - } - return; - -error: - /* XXX */ - return; -} - -/** \brief Byte jump match function - * \param det_ctx thread detect engine ctx - * \param s signature - * \param m byte jump sigmatch - * \param payload ptr to the payload - * \param payload_len length of the payload - * \retval 1 match - * \retval 0 no match - */ -int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, - const SigMatchCtx *ctx, uint8_t *payload, uint32_t payload_len, - uint8_t flags, int32_t offset) -{ - SCEnter(); - - const DetectBytejumpData *data = (const DetectBytejumpData *)ctx; - uint8_t *ptr = NULL; - uint8_t *jumpptr = NULL; - int32_t len = 0; - uint64_t val = 0; - int extbytes; - - if (payload_len == 0) { - SCReturnInt(0); - } - - /* Calculate the ptr value for the bytejump and length remaining in - * the packet from that point. - */ - if (flags & DETECT_BYTEJUMP_RELATIVE) { - ptr = payload + det_ctx->buffer_offset; - len = payload_len - det_ctx->buffer_offset; - - ptr += offset; - len -= offset; - - /* No match if there is no relative base */ - if (ptr == NULL || len <= 0) { - SCReturnInt(0); - } - } - else { - ptr = payload + offset; - len = payload_len - offset; - } - - /* Verify the to-be-extracted data is within the packet */ - if (ptr < payload || data->nbytes > len) { - SCLogDebug("Data not within payload " - "pkt=%p, ptr=%p, len=%d, nbytes=%d", - payload, ptr, len, data->nbytes); - SCReturnInt(0); - } - - /* Extract the byte data */ - if (flags & DETECT_BYTEJUMP_STRING) { - extbytes = ByteExtractStringUint64(&val, data->base, - data->nbytes, (const char *)ptr); - if(extbytes <= 0) { - SCLogError(SC_ERR_BYTE_EXTRACT_FAILED,"Error extracting %d bytes " - "of string data: %d", data->nbytes, extbytes); - SCReturnInt(-1); - } - } - else { - int endianness = (flags & DETECT_BYTEJUMP_LITTLE) ? BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN; - extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr); - if (extbytes != data->nbytes) { - SCLogError(SC_ERR_BYTE_EXTRACT_FAILED,"Error extracting %d bytes " - "of numeric data: %d", data->nbytes, extbytes); - SCReturnInt(-1); - } - } - - //printf("VAL: (%" PRIu64 " x %" PRIu32 ") + %d + %" PRId32 "\n", val, data->multiplier, extbytes, data->post_offset); - - /* Adjust the jump value based on flags */ - val *= data->multiplier; - if (flags & DETECT_BYTEJUMP_ALIGN) { - if ((val % 4) != 0) { - val += 4 - (val % 4); - } - } - val += data->post_offset; - - /* Calculate the jump location */ - if (flags & DETECT_BYTEJUMP_BEGIN) { - jumpptr = payload + val; - //printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr); - } - else { - val += extbytes; - jumpptr = ptr + val; - //printf("NEWVAL: ptr %p + %ld = %p\n", ptr, val, jumpptr); - } - - - /* Validate that the jump location is still in the packet - * \todo Should this validate it is still in the *payload*? - */ - if ((jumpptr < payload) || (jumpptr >= payload + payload_len)) { - SCLogDebug("Jump location (%p) is not within " - "payload (%p-%p)", jumpptr, payload, payload + payload_len - 1); - SCReturnInt(0); - } - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - uint8_t *sptr = (flags & DETECT_BYTEJUMP_BEGIN) ? payload : ptr; - SCLogDebug("jumping %" PRId64 " bytes from %p (%08x) to %p (%08x)", - val, sptr, (int)(sptr - payload), - jumpptr, (int)(jumpptr - payload)); - } -#endif /* DEBUG */ - - /* Adjust the detection context to the jump location. */ - det_ctx->buffer_offset = jumpptr - payload; - - SCReturnInt(1); -} - -int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectBytejumpData *data = (const DetectBytejumpData *)ctx; - uint8_t *ptr = NULL; - uint8_t *jumpptr = NULL; - uint16_t len = 0; - uint64_t val = 0; - int extbytes; - - if (p->payload_len == 0) { - return 0; - } - - /* Calculate the ptr value for the bytejump and length remaining in - * the packet from that point. - */ - if (data->flags & DETECT_BYTEJUMP_RELATIVE) { - ptr = p->payload + det_ctx->buffer_offset; - len = p->payload_len - det_ctx->buffer_offset; - - /* No match if there is no relative base */ - if (ptr == NULL || len == 0) { - return 0; - } - - ptr += data->offset; - len -= data->offset; - } - else { - ptr = p->payload + data->offset; - len = p->payload_len - data->offset; - } - - /* Verify the to-be-extracted data is within the packet */ - if (ptr < p->payload || data->nbytes > len) { - SCLogDebug("Data not within packet " - "payload=%p, ptr=%p, len=%d, nbytes=%d", - p->payload, ptr, len, data->nbytes); - return 0; - } - - /* Extract the byte data */ - if (data->flags & DETECT_BYTEJUMP_STRING) { - extbytes = ByteExtractStringUint64(&val, data->base, - data->nbytes, (const char *)ptr); - if(extbytes <= 0) { - SCLogError(SC_ERR_BYTE_EXTRACT_FAILED,"Error extracting %d bytes " - "of string data: %d", data->nbytes, extbytes); - return -1; - } - } - else { - int endianness = (data->flags & DETECT_BYTEJUMP_LITTLE) ? BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN; - extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr); - if (extbytes != data->nbytes) { - SCLogError(SC_ERR_BYTE_EXTRACT_FAILED,"Error extracting %d bytes " - "of numeric data: %d", data->nbytes, extbytes); - return -1; - } - } - - //printf("VAL: (%" PRIu64 " x %" PRIu32 ") + %d + %" PRId32 "\n", val, data->multiplier, extbytes, data->post_offset); - - /* Adjust the jump value based on flags */ - val *= data->multiplier; - if (data->flags & DETECT_BYTEJUMP_ALIGN) { - if ((val % 4) != 0) { - val += 4 - (val % 4); - } - } - val += data->post_offset; - - /* Calculate the jump location */ - if (data->flags & DETECT_BYTEJUMP_BEGIN) { - jumpptr = p->payload + val; - //printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr); - } - else { - val += extbytes; - jumpptr = ptr + val; - //printf("NEWVAL: ptr %p + %ld = %p\n", ptr, val, jumpptr); - } - - - /* Validate that the jump location is still in the packet - * \todo Should this validate it is still in the *payload*? - */ - if ((jumpptr < p->payload) || (jumpptr >= p->payload + p->payload_len)) { - SCLogDebug("Jump location (%p) is not within " - "packet (%p-%p)", jumpptr, p->payload, p->payload + p->payload_len - 1); - return 0; - } - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - uint8_t *sptr = (data->flags & DETECT_BYTEJUMP_BEGIN) ? p->payload - : ptr; - SCLogDebug("jumping %" PRId64 " bytes from %p (%08x) to %p (%08x)", - val, sptr, (int)(sptr - p->payload), - jumpptr, (int)(jumpptr - p->payload)); - } -#endif /* DEBUG */ - - /* Adjust the detection context to the jump location. */ - det_ctx->buffer_offset = jumpptr - p->payload; - - return 1; -} - -DetectBytejumpData *DetectBytejumpParse(char *optstr, char **offset) -{ - DetectBytejumpData *data = NULL; - char args[10][64]; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - int numargs = 0; - int i = 0; - uint32_t nbytes; - char *str_ptr; - char *end_ptr; - - memset(args, 0x00, sizeof(args)); - - /* Execute the regex and populate args with captures. */ - ret = pcre_exec(parse_regex, parse_regex_study, optstr, - strlen(optstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 2 || ret > 10) { - SCLogError(SC_ERR_PCRE_PARSE,"parse error, ret %" PRId32 - ", string \"%s\"", ret, optstr); - goto error; - } - - /* The first two arguments are stashed in the first PCRE substring. - * This is because byte_jump can take 10 arguments, but PCRE only - * supports 9 substrings, sigh. - */ - char str[512] = ""; - res = pcre_copy_substring((char *)optstr, ov, - MAX_SUBSTRINGS, 1, str, sizeof(str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed " - "for arg 1"); - goto error; - } - - /* Break up first substring into two parameters - * - * NOTE: Because of this, we cannot free args[1] as it is part of args[0], - * and *yes* this *is* ugly. - */ - end_ptr = str; - while (!(isspace((unsigned char)*end_ptr) || (*end_ptr == ','))) end_ptr++; - *(end_ptr++) = '\0'; - strlcpy(args[0], str, sizeof(args[0])); - numargs++; - - str_ptr = end_ptr; - while (isspace((unsigned char)*str_ptr) || (*str_ptr == ',')) str_ptr++; - end_ptr = str_ptr; - while (!(isspace((unsigned char)*end_ptr) || (*end_ptr == ',')) && (*end_ptr != '\0')) - end_ptr++; - *(end_ptr++) = '\0'; - strlcpy(args[1], str_ptr, sizeof(args[1])); - numargs++; - - /* The remaining args are directly from PCRE substrings */ - for (i = 1; i < (ret - 1); i++) { - res = pcre_copy_substring((char *)optstr, ov, MAX_SUBSTRINGS, i + 1, args[i+1], sizeof(args[0])); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed for arg %d", i + 1); - goto error; - } - numargs++; - } - - /* Initialize the data */ - data = SCMalloc(sizeof(DetectBytejumpData)); - if (unlikely(data == NULL)) - goto error; - data->base = DETECT_BYTEJUMP_BASE_UNSET; - data->flags = 0; - data->multiplier = 1; - data->post_offset = 0; - - /* - * The first two options are required and positional. The - * remaining arguments are flags and are not positional. - */ - - /* Number of bytes */ - if (ByteExtractStringUint32(&nbytes, 10, strlen(args[0]), args[0]) <= 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed number of bytes: %s", optstr); - goto error; - } - - /* Offset */ - if (args[1][0] != '-' && isalpha((unsigned char)args[1][0])) { - if (offset == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_jump supplied with " - "var name for offset. \"value\" argument supplied to " - "this function has to be non-NULL"); - goto error; - } - *offset = SCStrdup(args[1]); - if (*offset == NULL) - goto error; - } else { - if (ByteExtractStringInt32(&data->offset, 0, strlen(args[1]), args[1]) <= 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed offset: %s", optstr); - goto error; - } - } - - /* The remaining options are flags. */ - /** \todo Error on dups? */ - for (i = 2; i < numargs; i++) { - if (strcmp("relative", args[i]) == 0) { - data->flags |= DETECT_BYTEJUMP_RELATIVE; - } else if (strcasecmp("string", args[i]) == 0) { - data->flags |= DETECT_BYTEJUMP_STRING; - } else if (strcasecmp("dec", args[i]) == 0) { - data->base |= DETECT_BYTEJUMP_BASE_DEC; - } else if (strcasecmp("hex", args[i]) == 0) { - data->base |= DETECT_BYTEJUMP_BASE_HEX; - } else if (strcasecmp("oct", args[i]) == 0) { - data->base |= DETECT_BYTEJUMP_BASE_OCT; - } else if (strcasecmp("big", args[i]) == 0) { - if (data->flags & DETECT_BYTEJUMP_LITTLE) { - data->flags ^= DETECT_BYTEJUMP_LITTLE; - } - data->flags |= DETECT_BYTEJUMP_BIG; - } else if (strcasecmp("little", args[i]) == 0) { - data->flags |= DETECT_BYTEJUMP_LITTLE; - } else if (strcasecmp("from_beginning", args[i]) == 0) { - data->flags |= DETECT_BYTEJUMP_BEGIN; - } else if (strcasecmp("align", args[i]) == 0) { - data->flags |= DETECT_BYTEJUMP_ALIGN; - } else if (strncasecmp("multiplier ", args[i], 11) == 0) { - if (ByteExtractStringUint32(&data->multiplier, 10, - strlen(args[i]) - 11, - args[i] + 11) <= 0) - { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed multiplier: %s", optstr); - goto error; - } - } else if (strncasecmp("post_offset ", args[i], 12) == 0) { - if (ByteExtractStringInt32(&data->post_offset, 10, - strlen(args[i]) - 12, - args[i] + 12) <= 0) - { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed post_offset: %s", optstr); - goto error; - } - } else if (strcasecmp("dce", args[i]) == 0) { - data->flags |= DETECT_BYTEJUMP_DCE; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "Unknown option: \"%s\"", args[i]); - goto error; - } - } - - if (data->flags & DETECT_BYTEJUMP_STRING) { - /* 23 - This is the largest string (octal, with a zero prefix) that - * will not overflow uint64_t. The only way this length - * could be over 23 and still not overflow is if it were zero - * prefixed and we only support 1 byte of zero prefix for octal. - * - * "01777777777777777777777" = 0xffffffffffffffff - */ - if (nbytes > 23) { - SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 23 bytes " - "with \"string\": %s", optstr); - goto error; - } - } else { - if (nbytes > 8) { - SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 8 bytes " - "without \"string\": %s\n", optstr); - goto error; - } - if (data->base != DETECT_BYTEJUMP_BASE_UNSET) { - SCLogError(SC_ERR_INVALID_VALUE, "Cannot use a base " - "without \"string\": %s", optstr); - goto error; - } - } - - /* This is max 23 so it will fit in a byte (see above) */ - data->nbytes = (uint8_t)nbytes; - - return data; - -error: - if (offset != NULL && *offset != NULL) { - SCFree(*offset); - *offset = NULL; - } - if (data != NULL) - DetectBytejumpFree(data); - return NULL; -} - -int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) -{ - SigMatch *sm = NULL; - SigMatch *prev_pm = NULL; - DetectBytejumpData *data = NULL; - char *offset = NULL; - int ret = -1; - - data = DetectBytejumpParse(optstr, &offset); - if (data == NULL) - goto error; - - int sm_list; - if (s->list != DETECT_SM_LIST_NOTSET) { - if (s->list == DETECT_SM_LIST_FILEDATA) { - if (data->flags & DETECT_BYTEJUMP_DCE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "dce bytejump specified " - "with file_data option set."); - goto error; - } - AppLayerHtpEnableResponseBodyCallback(); - } - sm_list = s->list; - s->flags |= SIG_FLAG_APPLAYER; - if (data->flags & DETECT_BYTEJUMP_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, s->sm_lists_tail[sm_list], - DETECT_PCRE, s->sm_lists_tail[sm_list]); - - } - } else if (data->flags & DETECT_BYTEJUMP_DCE) { - if (data->flags & DETECT_BYTEJUMP_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 12, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); - if (prev_pm == NULL) { - sm_list = DETECT_SM_LIST_PMATCH; - } else { - sm_list = SigMatchListSMBelongsTo(s, prev_pm); - if (sm_list < 0) - goto error; - } - } else { - sm_list = DETECT_SM_LIST_PMATCH; - } - - s->alproto = ALPROTO_DCERPC; - s->flags |= SIG_FLAG_APPLAYER; - - } else if (data->flags & DETECT_BYTEJUMP_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 168, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - if (prev_pm == NULL) { - sm_list = DETECT_SM_LIST_PMATCH; - } else { - sm_list = SigMatchListSMBelongsTo(s, prev_pm); - if (sm_list < 0) - goto error; - } - - } else { - sm_list = DETECT_SM_LIST_PMATCH; - } - - if (data->flags & DETECT_BYTEJUMP_DCE) { - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_DCERPC) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Non dce alproto sig has " - "bytejump with dce enabled"); - goto error; - } - if ((data->flags & DETECT_BYTEJUMP_STRING) || - (data->flags & DETECT_BYTEJUMP_LITTLE) || - (data->flags & DETECT_BYTEJUMP_BIG) || - (data->flags & DETECT_BYTEJUMP_BEGIN) || - (data->base == DETECT_BYTEJUMP_BASE_DEC) || - (data->base == DETECT_BYTEJUMP_BASE_HEX) || - (data->base == DETECT_BYTEJUMP_BASE_OCT) ) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. " - "A byte_jump keyword with dce holds other invalid modifiers."); - goto error; - } - } - - if (offset != NULL) { - SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s); - if (bed_sm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " - "seen in byte_jump - %s\n", offset); - goto error; - } - data->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id; - data->flags |= DETECT_BYTEJUMP_OFFSET_BE; - SCFree(offset); - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - sm->type = DETECT_BYTEJUMP; - sm->ctx = (SigMatchCtx *)data; - SigMatchAppendSMToList(s, sm, sm_list); - - if (!(data->flags & DETECT_BYTEJUMP_RELATIVE)) - goto okay; - - if (prev_pm == NULL) - goto okay; - - if (prev_pm->type == DETECT_CONTENT) { - DetectContentData *cd = (DetectContentData *)prev_pm->ctx; - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - } else if (prev_pm->type == DETECT_PCRE) { - DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx; - pd->flags |= DETECT_PCRE_RELATIVE_NEXT; - } - - okay: - ret = 0; - return ret; - error: - DetectBytejumpFree(data); - return ret; -} - -/** - * \brief this function will free memory associated with DetectBytejumpData - * - * \param data pointer to DetectBytejumpData - */ -void DetectBytejumpFree(void *ptr) -{ - if (ptr == NULL) - return; - - DetectBytejumpData *data = (DetectBytejumpData *)ptr; - SCFree(data); -} - - -/* UNITTESTS */ -#ifdef UNITTESTS -#include "util-unittest-helper.h" -/** - * \test DetectBytejumpTestParse01 is a test to make sure that we return - * "something" when given valid bytejump opt - */ -int DetectBytejumpTestParse01(void) -{ - int result = 0; - DetectBytejumpData *data = NULL; - data = DetectBytejumpParse("4,0", NULL); - if (data != NULL) { - DetectBytejumpFree(data); - result = 1; - } - - return result; -} - -/** - * \test DetectBytejumpTestParse02 is a test for setting the required opts - */ -int DetectBytejumpTestParse02(void) -{ - int result = 0; - DetectBytejumpData *data = NULL; - data = DetectBytejumpParse("4, 0", NULL); - if (data != NULL) { - if ( (data->nbytes == 4) - && (data->offset == 0) - && (data->multiplier == 1) - && (data->post_offset == 0) - && (data->flags == 0) - && (data->base == DETECT_BYTEJUMP_BASE_UNSET)) - { - result = 1; - } - DetectBytejumpFree(data); - } - - return result; -} - -/** - * \test DetectBytejumpTestParse03 is a test for setting the optional flags - */ -int DetectBytejumpTestParse03(void) -{ - int result = 0; - DetectBytejumpData *data = NULL; - data = DetectBytejumpParse(" 4,0 , relative , little, string, " - "dec, align, from_beginning", NULL); - if (data != NULL) { - if ( (data->nbytes == 4) - && (data->offset == 0) - && (data->multiplier == 1) - && (data->post_offset == 0) - && (data->flags == ( DETECT_BYTEJUMP_RELATIVE - |DETECT_BYTEJUMP_LITTLE - |DETECT_BYTEJUMP_STRING - |DETECT_BYTEJUMP_ALIGN - |DETECT_BYTEJUMP_BEGIN)) - && (data->base == DETECT_BYTEJUMP_BASE_DEC)) - { - result = 1; - } - DetectBytejumpFree(data); - } - - return result; -} - -/** - * \test DetectBytejumpTestParse04 is a test for setting the optional flags - * with parameters - * - * \todo This fails becuase we can only have 9 captures and there are 10. - */ -int DetectBytejumpTestParse04(void) -{ - int result = 0; - DetectBytejumpData *data = NULL; - data = DetectBytejumpParse(" 4,0 , relative , little, string, " - "dec, align, from_beginning , " - "multiplier 2 , post_offset -16 ", NULL); - if (data != NULL) { - if ( (data->nbytes == 4) - && (data->offset == 0) - && (data->multiplier == 2) - && (data->post_offset == -16) - && (data->flags == ( DETECT_BYTEJUMP_RELATIVE - |DETECT_BYTEJUMP_LITTLE - |DETECT_BYTEJUMP_ALIGN - |DETECT_BYTEJUMP_STRING - |DETECT_BYTEJUMP_BEGIN)) - && (data->base == DETECT_BYTEJUMP_BASE_DEC)) - { - result = 1; - } - DetectBytejumpFree(data); - } - - return result; -} - -/** - * \test DetectBytejumpTestParse05 is a test for setting base without string - */ -int DetectBytejumpTestParse05(void) -{ - int result = 0; - DetectBytejumpData *data = NULL; - data = DetectBytejumpParse(" 4,0 , relative , little, dec, " - "align, from_beginning", NULL); - if (data == NULL) { - result = 1; - } - - return result; -} - -/** - * \test DetectBytejumpTestParse06 is a test for too many bytes to extract - */ -int DetectBytejumpTestParse06(void) -{ - int result = 0; - DetectBytejumpData *data = NULL; - data = DetectBytejumpParse("9, 0", NULL); - if (data == NULL) { - result = 1; - } - - return result; -} - -/** - * \test DetectBytejumpTestParse07 is a test for too many string bytes to extract - */ -int DetectBytejumpTestParse07(void) -{ - int result = 0; - DetectBytejumpData *data = NULL; - data = DetectBytejumpParse("24, 0, string, dec", NULL); - if (data == NULL) { - result = 1; - } - - return result; -} - -/** - * \test DetectBytejumpTestParse08 is a test for offset too big - */ -int DetectBytejumpTestParse08(void) -{ - int result = 0; - DetectBytejumpData *data = NULL; - data = DetectBytejumpParse("4, 0xffffffffffffffff", NULL); - if (data == NULL) { - result = 1; - } - - return result; -} - -/** - * \test Test dce option. - */ -int DetectBytejumpTestParse09(void) -{ - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 1; - - s->alproto = ALPROTO_DCERPC; - - result &= (DetectBytejumpSetup(NULL, s, "4,0, align, multiplier 2, " - "post_offset -16,dce") == 0); - result &= (DetectBytejumpSetup(NULL, s, "4,0, multiplier 2, " - "post_offset -16,dce") == 0); - result &= (DetectBytejumpSetup(NULL, s, "4,0,post_offset -16,dce") == 0); - result &= (DetectBytejumpSetup(NULL, s, "4,0,dce") == 0); - result &= (DetectBytejumpSetup(NULL, s, "4,0,dce") == 0); - result &= (DetectBytejumpSetup(NULL, s, "4,0, string, dce") == -1); - result &= (DetectBytejumpSetup(NULL, s, "4,0, big, dce") == -1); - result &= (DetectBytejumpSetup(NULL, s, "4,0, little, dce") == -1); - result &= (DetectBytejumpSetup(NULL, s, "4,0, string, dec, dce") == -1); - result &= (DetectBytejumpSetup(NULL, s, "4,0, string, oct, dce") == -1); - result &= (DetectBytejumpSetup(NULL, s, "4,0, string, hex, dce") == -1); - result &= (DetectBytejumpSetup(NULL, s, "4,0, from_beginning, dce") == -1); - result &= (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - - SigFree(s); - return result; -} - -/** - * \test Test dce option. - */ -int DetectBytejumpTestParse10(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - DetectBytejumpData *bd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "byte_jump:4,0,align,multiplier 2, " - "post_offset -16,relative,dce; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_BYTEJUMP); - bd = (DetectBytejumpData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (!(bd->flags & DETECT_BYTEJUMP_DCE) && - !(bd->flags & DETECT_BYTEJUMP_RELATIVE) && - (bd->flags & DETECT_BYTEJUMP_STRING) && - (bd->flags & DETECT_BYTEJUMP_BIG) && - (bd->flags & DETECT_BYTEJUMP_LITTLE) ) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "byte_jump:4,0,align,multiplier 2, " - "post_offset -16,relative,dce; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_BYTEJUMP); - bd = (DetectBytejumpData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (!(bd->flags & DETECT_BYTEJUMP_DCE) && - !(bd->flags & DETECT_BYTEJUMP_RELATIVE) && - (bd->flags & DETECT_BYTEJUMP_STRING) && - (bd->flags & DETECT_BYTEJUMP_BIG) && - (bd->flags & DETECT_BYTEJUMP_LITTLE) ) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "byte_jump:4,0,align,multiplier 2, " - "post_offset -16,relative; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_BYTEJUMP); - bd = (DetectBytejumpData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if ((bd->flags & DETECT_BYTEJUMP_DCE) && - !(bd->flags & DETECT_BYTEJUMP_RELATIVE) && - (bd->flags & DETECT_BYTEJUMP_STRING) && - (bd->flags & DETECT_BYTEJUMP_BIG) && - (bd->flags & DETECT_BYTEJUMP_LITTLE) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test dce option. - */ -int DetectBytejumpTestParse11(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; byte_jump:4,0,align,multiplier 2, " - "post_offset -16,string,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_sub_data; " - "content:\"one\"; byte_jump:4,0,align,multiplier 2, " - "post_offset -16,big,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; byte_jump:4,0,align,multiplier 2, " - "post_offset -16,little,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; byte_jump:4,0,align,multiplier 2, " - "post_offset -16,string,hex,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; byte_jump:4,0,align,multiplier 2, " - "post_offset -16,string,dec,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; byte_jump:4,0,align,multiplier 2, " - "post_offset -16,string,oct,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; byte_jump:4,0,align,multiplier 2, " - "post_offset -16,from_beginning,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test file_data - */ -static int DetectBytejumpTestParse12(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectBytejumpData *bd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; byte_jump:4,0,align,multiplier 2, " - "post_offset -16,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_BYTEJUMP) { - goto end; - } - - bd = (DetectBytejumpData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if ((bd->flags & DETECT_BYTEJUMP_DCE) && - (bd->flags & DETECT_BYTEJUMP_RELATIVE) && - (bd->flags & DETECT_BYTEJUMP_STRING) && - (bd->flags & DETECT_BYTEJUMP_BIG) && - (bd->flags & DETECT_BYTEJUMP_LITTLE) ) { - result = 0; - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectByteJumpTestPacket01 is a test to check matches of - * byte_jump and byte_jump relative works if the previous keyword is pcre - * (bug 142) - */ -int DetectByteJumpTestPacket01 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0" - "User-Agent: Wget/1.11.4" - "Accept: */*" - "Host: www.google.com" - "Connection: Keep-Alive" - "Date: Mon, 04 Jan 2010 17:29:39 GMT"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre + byte_test + " - "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6," - "relative,string,dec; content:\"0\"; sid:134; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} - -/** - * \test DetectByteJumpTestPacket02 is a test to check matches of - * byte_jump and byte_jump relative works if the previous keyword is byte_jump - * (bug 165) - */ -int DetectByteJumpTestPacket02 (void) -{ - int result = 0; - uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53, - 0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff, - 0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00, - 0x00, 0xff }; - uint16_t buflen = sizeof(buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"byte_jump with byte_jump" - " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; " - "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} - -int DetectByteJumpTestPacket03(void) -{ - int result = 0; - uint8_t *buf = NULL; - uint16_t buflen = 0; - buf = SCMalloc(4); - if (unlikely(buf == NULL)) { - printf("malloc failed\n"); - exit(EXIT_FAILURE); - } - memcpy(buf, "boom", 4); - buflen = 4; - - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"byte_jump\"; " - "byte_jump:1,214748364; sid:1; rev:1;)"; - - result = !UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); - -end: - if (buf != NULL) - SCFree(buf); - return result; -} - -/** - * \test check matches of with from_beginning (bug 626/627) - */ -int DetectByteJumpTestPacket04 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"XYZ04abcdABCD"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (content:\"XYZ\"; byte_jump:2,0,relative,string,dec; content:\"ABCD\"; distance:0; within:4; sid:1; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} - -/** - * \test check matches of with from_beginning (bug 626/627) - */ -int DetectByteJumpTestPacket05 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"XYZ04abcdABCD"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (content:\"XYZ\"; byte_jump:2,0,relative,string,dec; content:\"cdABCD\"; within:6; sid:1; rev:1;)"; - - result = UTHPacketMatchSig(p, sig) ? 0 : 1; - - UTHFreePacket(p); -end: - return result; -} - -/** - * \test check matches of with from_beginning (bug 626/627) - */ -int DetectByteJumpTestPacket06 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"XX04abcdABCD"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,relative,string,dec,from_beginning; content:\"ABCD\"; distance:4; within:4; sid:1; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} - -/** - * \test check matches of with from_beginning (bug 626/627) - */ -int DetectByteJumpTestPacket07 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"XX04abcdABCD"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,relative,string,dec,from_beginning; content:\"abcdABCD\"; distance:0; within:8; sid:1; rev:1;)"; - - result = UTHPacketMatchSig(p, sig) ? 1 : 0; - - UTHFreePacket(p); -end: - return result; -} - -#endif /* UNITTESTS */ - - -/** - * \brief this function registers unit tests for DetectBytejump - */ -void DetectBytejumpRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectBytejumpTestParse01", DetectBytejumpTestParse01, 1); - UtRegisterTest("DetectBytejumpTestParse02", DetectBytejumpTestParse02, 1); - UtRegisterTest("DetectBytejumpTestParse03", DetectBytejumpTestParse03, 1); - UtRegisterTest("DetectBytejumpTestParse04", DetectBytejumpTestParse04, 1); - UtRegisterTest("DetectBytejumpTestParse05", DetectBytejumpTestParse05, 1); - UtRegisterTest("DetectBytejumpTestParse06", DetectBytejumpTestParse06, 1); - UtRegisterTest("DetectBytejumpTestParse07", DetectBytejumpTestParse07, 1); - UtRegisterTest("DetectBytejumpTestParse08", DetectBytejumpTestParse08, 1); - UtRegisterTest("DetectBytejumpTestParse09", DetectBytejumpTestParse09, 1); - UtRegisterTest("DetectBytejumpTestParse10", DetectBytejumpTestParse10, 1); - UtRegisterTest("DetectBytejumpTestParse11", DetectBytejumpTestParse11, 1); - UtRegisterTest("DetectBytejumpTestParse12", DetectBytejumpTestParse12, 1); - - UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01, 1); - UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02, 1); - UtRegisterTest("DetectByteJumpTestPacket03", DetectByteJumpTestPacket03, 1); - UtRegisterTest("DetectByteJumpTestPacket04", DetectByteJumpTestPacket04, 1); - UtRegisterTest("DetectByteJumpTestPacket05", DetectByteJumpTestPacket05, 1); - UtRegisterTest("DetectByteJumpTestPacket06", DetectByteJumpTestPacket06, 1); - UtRegisterTest("DetectByteJumpTestPacket07", DetectByteJumpTestPacket07, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-bytejump.h b/framework/src/suricata/src/detect-bytejump.h deleted file mode 100644 index 35051486..00000000 --- a/framework/src/suricata/src/detect-bytejump.h +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - */ - -#ifndef __DETECT_BYTEJUMP_H__ -#define __DETECT_BYTEJUMP_H__ - -/** Bytejump Base */ -#define DETECT_BYTEJUMP_BASE_UNSET 0 /**< Unset type value string (automatic)*/ -#define DETECT_BYTEJUMP_BASE_OCT 8 /**< "oct" type value string */ -#define DETECT_BYTEJUMP_BASE_DEC 10 /**< "dec" type value string */ -#define DETECT_BYTEJUMP_BASE_HEX 16 /**< "hex" type value string */ - -/** Bytejump Flags */ -#define DETECT_BYTEJUMP_BEGIN 0x01 /**< "from_beginning" jump */ -#define DETECT_BYTEJUMP_LITTLE 0x02 /**< "little" endian value */ -#define DETECT_BYTEJUMP_BIG 0x04 /**< "big" endian value */ -#define DETECT_BYTEJUMP_STRING 0x08 /**< "string" value */ -#define DETECT_BYTEJUMP_RELATIVE 0x10 /**< "relative" offset */ -#define DETECT_BYTEJUMP_ALIGN 0x20 /**< "align" offset */ -#define DETECT_BYTEJUMP_DCE 0x40 /**< "dce" enabled */ -#define DETECT_BYTEJUMP_OFFSET_BE 0x80 /**< "byte extract" enabled */ - -typedef struct DetectBytejumpData_ { - uint8_t nbytes; /**< Number of bytes to compare */ - uint8_t base; /**< String value base (oct|dec|hex) */ - uint8_t flags; /**< Flags (big|little|relative|string) */ - uint32_t multiplier; /**< Multiplier for nbytes (multiplier n)*/ - int32_t offset; /**< Offset in payload to extract value */ - int32_t post_offset; /**< Offset to adjust post-jump */ -} DetectBytejumpData; - -/* prototypes */ - -/** - * Registration function for byte_jump. - * - * \todo add support for no_stream and stream_only - */ -void DetectBytejumpRegister (void); - -/** - * This function is used to add the parsed byte_jump data - * into the current signature. - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param optstr pointer to the user provided options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectBytejumpSetup(DetectEngineCtx *, Signature *, char *); - -/** - * \brief this function will free memory associated with DetectBytejumpData - * - * \param data pointer to DetectBytejumpData - */ -void DetectBytejumpFree(void *ptr); - -/** - * This function is used to parse byte_jump options passed via - * - * byte_jump: bytes, offset [,flags [, ...]] - * - * flags: "big", "little", "relative", "string", "oct", "dec", "hex" - * "align", "from beginning", "multiplier N", "post_offset N" - * - * \param optstr Pointer to the user provided byte_jump options - * \param offset Used to pass the offset back, if byte_jump uses a byte_extract - * var. - * - * \retval data pointer to DetectBytejumpData on success - * \retval NULL on failure - */ -DetectBytejumpData *DetectBytejumpParse(char *optstr, char **offset); - -/** - * This function is used to match byte_jump - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectBytejumpData - * - * \retval -1 error - * \retval 0 no match - * \retval 1 match - * - * \todo The return seems backwards. We should return a non-zero error code. - * One of the error codes is "no match". As-is if someone accidentally - * does: if (DetectBytejumpMatch(...)) { match }, then they catch an - * error as a match. - */ -int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx); -int DetectBytejumpDoMatch(DetectEngineThreadCtx *, Signature *, const SigMatchCtx *, - uint8_t *, uint32_t, uint8_t, int32_t); - -#endif /* __DETECT_BYTEJUMP_H__ */ - diff --git a/framework/src/suricata/src/detect-bytetest.c b/framework/src/suricata/src/detect-bytetest.c deleted file mode 100644 index 365ad55c..00000000 --- a/framework/src/suricata/src/detect-bytetest.c +++ /dev/null @@ -1,1580 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - * - * Implements byte_test keyword. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" - -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" -#include "detect-byte-extract.h" -#include "app-layer.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "detect-pcre.h" - - -/** - * \brief Regex for parsing our options - */ -/** \todo We probably just need a simple tokenizer here */ -#define PARSE_REGEX "^\\s*" \ - "([^\\s,]+)" \ - "\\s*,\\s*(\\!?)\\s*([^\\s,]*)" \ - "\\s*,\\s*([^\\s,]+)" \ - "\\s*,\\s*([^\\s,]+)" \ - "(?:\\s*,\\s*([^\\s,]+))?" \ - "(?:\\s*,\\s*([^\\s,]+))?" \ - "(?:\\s*,\\s*([^\\s,]+))?" \ - "(?:\\s*,\\s*([^\\s,]+))?" \ - "(?:\\s*,\\s*([^\\s,]+))?" \ - "\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -void DetectBytetestRegisterTests(void); - -void DetectBytetestRegister (void) -{ - const char *eb; - int eo; - int opts = 0; - - sigmatch_table[DETECT_BYTETEST].name = "byte_test"; - sigmatch_table[DETECT_BYTETEST].Match = DetectBytetestMatch; - sigmatch_table[DETECT_BYTETEST].Setup = DetectBytetestSetup; - sigmatch_table[DETECT_BYTETEST].Free = DetectBytetestFree; - sigmatch_table[DETECT_BYTETEST].RegisterTests = DetectBytetestRegisterTests; - - sigmatch_table[DETECT_BYTETEST].flags |= SIGMATCH_PAYLOAD; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at " - "offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - /* XXX */ - return; -} - -/** \brief Bytetest detection code - * - * Byte test works on the packet payload. - * - * \param det_ctx thread de ctx - * \param s signature - * \param m sigmatch for this bytettest - * \param payload ptr to the start of the buffer to inspect - * \param payload_len length of the payload - * \retval 1 match - * \retval 0 no match - */ -int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, const SigMatchCtx *ctx, uint8_t *payload, uint32_t payload_len, - uint8_t flags, int32_t offset, uint64_t value) -{ - SCEnter(); - - const DetectBytetestData *data = (const DetectBytetestData *)ctx; - uint8_t *ptr = NULL; - int32_t len = 0; - uint64_t val = 0; - int extbytes; - int neg; - int match; - - if (payload_len == 0) { - SCReturnInt(0); - } - - /* Calculate the ptr value for the bytetest and length remaining in - * the packet from that point. - */ - if (flags & DETECT_BYTETEST_RELATIVE) { - SCLogDebug("relative, working with det_ctx->buffer_offset %"PRIu32", " - "data->offset %"PRIi32"", det_ctx->buffer_offset, data->offset); - - ptr = payload + det_ctx->buffer_offset; - len = payload_len - det_ctx->buffer_offset; - - ptr += offset; - len -= offset; - - /* No match if there is no relative base */ - if (ptr == NULL || len <= 0) { - SCReturnInt(0); - } - //PrintRawDataFp(stdout,ptr,len); - } - else { - SCLogDebug("absolute, data->offset %"PRIi32"", data->offset); - - ptr = payload + offset; - len = payload_len - offset; - } - - /* Validate that the to-be-extracted is within the packet - * \todo Should this validate it is in the *payload*? - */ - if (ptr < payload || data->nbytes > len) { - SCLogDebug("Data not within payload pkt=%p, ptr=%p, len=%"PRIu32", nbytes=%d", - payload, ptr, len, data->nbytes); - SCReturnInt(0); - } - - neg = flags & DETECT_BYTETEST_NEGOP; - - /* Extract the byte data */ - if (flags & DETECT_BYTETEST_STRING) { - extbytes = ByteExtractStringUint64(&val, data->base, - data->nbytes, (const char *)ptr); - if (extbytes <= 0) { - /* strtoull() return 0 if there is no numeric value in data string */ - if (val == 0) { - SCLogDebug("No Numeric value"); - SCReturnInt(0); - } else { - SCLogError(SC_ERR_INVALID_NUM_BYTES, "Error extracting %d " - "bytes of string data: %d", data->nbytes, extbytes); - SCReturnInt(-1); - } - } - - SCLogDebug("comparing base %d string 0x%" PRIx64 " %s%c 0x%" PRIx64 "", - data->base, val, (neg ? "!" : ""), data->op, data->value); - } - else { - int endianness = (flags & DETECT_BYTETEST_LITTLE) ? - BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN; - extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr); - if (extbytes != data->nbytes) { - SCLogError(SC_ERR_INVALID_NUM_BYTES, "Error extracting %d bytes " - "of numeric data: %d\n", data->nbytes, extbytes); - SCReturnInt(-1); - } - - SCLogDebug("comparing numeric 0x%" PRIx64 " %s%c 0x%" PRIx64 "", - val, (neg ? "!" : ""), data->op, data->value); - } - - /* Compare using the configured operator */ - match = 0; - switch (data->op) { - case DETECT_BYTETEST_OP_EQ: - if (val == value) { - match = 1; - } - break; - case DETECT_BYTETEST_OP_LT: - if (val < value) { - match = 1; - } - break; - case DETECT_BYTETEST_OP_GT: - if (val > value) { - match = 1; - } - break; - case DETECT_BYTETEST_OP_AND: - if (val & value) { - match = 1; - } - break; - case DETECT_BYTETEST_OP_OR: - if (val ^ value) { - match = 1; - } - break; - case DETECT_BYTETEST_OP_GE: - if (val >= value) { - match = 1; - } - break; - case DETECT_BYTETEST_OP_LE: - if (val <= value) { - match = 1; - } - break; - default: - /* Should never get here as we handle this in parsing. */ - SCReturnInt(-1); - } - - /* A successful match depends on negation */ - if ((!neg && match) || (neg && !match)) { - SCLogDebug("MATCH"); - SCReturnInt(1); - } - - SCLogDebug("NO MATCH"); - SCReturnInt(0); - -} - -int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - return DetectBytetestDoMatch(det_ctx, s, ctx, p->payload, p->payload_len, - ((DetectBytetestData *)ctx)->flags, 0, 0); -} - -DetectBytetestData *DetectBytetestParse(char *optstr, char **value, char **offset) -{ - DetectBytetestData *data = NULL; - char *args[9] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL - }; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - int i; - uint32_t nbytes; - const char *str_ptr = NULL; - - /* Execute the regex and populate args with captures. */ - ret = pcre_exec(parse_regex, parse_regex_study, optstr, - strlen(optstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 6 || ret > 10) { - SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32 - ", string %s", ret, optstr); - goto error; - } - for (i = 0; i < (ret - 1); i++) { - res = pcre_get_substring((char *)optstr, ov, MAX_SUBSTRINGS, - i + 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed " - "for arg %d", i + 1); - goto error; - } - args[i] = (char *)str_ptr; - } - - /* Initialize the data */ - data = SCMalloc(sizeof(DetectBytetestData)); - if (unlikely(data == NULL)) - goto error; - data->base = DETECT_BYTETEST_BASE_UNSET; - data->flags = 0; - - - /* - * The first four options are required and positional. The - * remaining arguments are flags and are not positional. - */ - - /* Number of bytes */ - if (ByteExtractStringUint32(&nbytes, 10, 0, args[0]) <= 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed number of bytes: %s", str_ptr); - goto error; - } - - /* Operator is next two args: neg + op */ - data->op = 0; - if (args[1] != NULL && *args[1] == '!') { - data->flags |= DETECT_BYTETEST_NEGOP; - } - - if (args[2] != NULL) { - if ((strcmp("=", args[2]) == 0) || ((data->flags & DETECT_BYTETEST_NEGOP) - && strcmp("", args[2]) == 0)) { - data->op |= DETECT_BYTETEST_OP_EQ; - } else if (strcmp("<", args[2]) == 0) { - data->op |= DETECT_BYTETEST_OP_LT; - } else if (strcmp(">", args[2]) == 0) { - data->op |= DETECT_BYTETEST_OP_GT; - } else if (strcmp("&", args[2]) == 0) { - data->op |= DETECT_BYTETEST_OP_AND; - } else if (strcmp("^", args[2]) == 0) { - data->op |= DETECT_BYTETEST_OP_OR; - } else if (strcmp(">=", args[2]) == 0) { - data->op |= DETECT_BYTETEST_OP_GE; - } else if (strcmp("<=", args[2]) == 0) { - data->op |= DETECT_BYTETEST_OP_LE; - } else { - SCLogError(SC_ERR_INVALID_OPERATOR, "Invalid operator"); - goto error; - } - } - - /* Value */ - if (args[3][0] != '-' && isalpha((unsigned char)args[3][0])) { - if (value == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with " - "var name for value. \"value\" argument supplied to " - "this function has to be non-NULL"); - goto error; - } - *value = SCStrdup(args[3]); - if (*value == NULL) - goto error; - } else { - if (ByteExtractStringUint64(&data->value, 0, 0, args[3]) <= 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed value: %s", str_ptr); - goto error; - } - } - - /* Offset */ - if (args[4][0] != '-' && isalpha((unsigned char)args[4][0])) { - if (offset == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with " - "var name for offset. \"offset\" argument supplied to " - "this function has to be non-NULL"); - goto error; - } - *offset = SCStrdup(args[4]); - if (*offset == NULL) - goto error; - } else { - if (ByteExtractStringInt32(&data->offset, 0, 0, args[4]) <= 0) { - SCLogError(SC_ERR_INVALID_VALUE, " Malformed offset: %s", str_ptr); - goto error; - } - } - - /* The remaining options are flags. */ - /** \todo Error on dups? */ - for (i = 5; i < (ret - 1); i++) { - if (args[i] != NULL) { - if (strcmp("relative", args[i]) == 0) { - data->flags |= DETECT_BYTETEST_RELATIVE; - } else if (strcasecmp("string", args[i]) == 0) { - data->flags |= DETECT_BYTETEST_STRING; - } else if (strcasecmp("dec", args[i]) == 0) { - data->base |= DETECT_BYTETEST_BASE_DEC; - } else if (strcasecmp("hex", args[i]) == 0) { - data->base |= DETECT_BYTETEST_BASE_HEX; - } else if (strcasecmp("oct", args[i]) == 0) { - data->base |= DETECT_BYTETEST_BASE_OCT; - } else if (strcasecmp("big", args[i]) == 0) { - if (data->flags & DETECT_BYTETEST_LITTLE) { - data->flags ^= DETECT_BYTETEST_LITTLE; - } - data->flags |= DETECT_BYTETEST_BIG; - } else if (strcasecmp("little", args[i]) == 0) { - data->flags |= DETECT_BYTETEST_LITTLE; - } else if (strcasecmp("dce", args[i]) == 0) { - data->flags |= DETECT_BYTETEST_DCE; - } else { - SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown value: \"%s\"", - args[i]); - goto error; - } - } - } - - if (data->flags & DETECT_BYTETEST_STRING) { - /* 23 - This is the largest string (octal, with a zero prefix) that - * will not overflow uint64_t. The only way this length - * could be over 23 and still not overflow is if it were zero - * prefixed and we only support 1 byte of zero prefix for octal. - * - * "01777777777777777777777" = 0xffffffffffffffff - */ - if (nbytes > 23) { - SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 23 bytes with \"string\": %s", - optstr); - goto error; - } - } else { - if (nbytes > 8) { - SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 8 bytes without \"string\": %s", - optstr); - goto error; - } - if (data->base != DETECT_BYTETEST_BASE_UNSET) { - SCLogError(SC_ERR_INVALID_VALUE, "Cannot use a base without \"string\": %s", optstr); - goto error; - } - } - - /* This is max 23 so it will fit in a byte (see above) */ - data->nbytes = (uint8_t)nbytes; - - for (i = 0; i < (ret - 1); i++){ - if (args[i] != NULL) SCFree(args[i]); - } - return data; - -error: - for (i = 0; i < (ret - 1); i++){ - if (args[i] != NULL) SCFree(args[i]); - } - if (data != NULL) DetectBytetestFree(data); - return NULL; -} - -int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) -{ - SigMatch *sm = NULL; - SigMatch *prev_pm = NULL; - DetectBytetestData *data = NULL; - char *value = NULL; - char *offset = NULL; - int ret = -1; - - data = DetectBytetestParse(optstr, &value, &offset); - if (data == NULL) - goto error; - - int sm_list; - if (s->list != DETECT_SM_LIST_NOTSET) { - if (s->list == DETECT_SM_LIST_FILEDATA) { - if (data->flags & DETECT_BYTETEST_DCE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "dce bytetest specified " - "with file_data option set."); - goto error; - } - AppLayerHtpEnableResponseBodyCallback(); - } - sm_list = s->list; - s->flags |= SIG_FLAG_APPLAYER; - if (data->flags & DETECT_BYTETEST_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, s->sm_lists_tail[sm_list], - DETECT_PCRE, s->sm_lists_tail[sm_list]); - } - - } else if (data->flags & DETECT_BYTETEST_DCE) { - if (data->flags & DETECT_BYTETEST_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 12, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); - if (prev_pm == NULL) { - sm_list = DETECT_SM_LIST_PMATCH; - } else { - sm_list = SigMatchListSMBelongsTo(s, prev_pm); - if (sm_list < 0) - goto error; - } - } else { - sm_list = DETECT_SM_LIST_PMATCH; - } - - s->alproto = ALPROTO_DCERPC; - s->flags |= SIG_FLAG_APPLAYER; - - } else if (data->flags & DETECT_BYTETEST_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 168, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - if (prev_pm == NULL) { - sm_list = DETECT_SM_LIST_PMATCH; - } else { - sm_list = SigMatchListSMBelongsTo(s, prev_pm); - if (sm_list < 0) - goto error; - } - - } else { - sm_list = DETECT_SM_LIST_PMATCH; - } - - if (data->flags & DETECT_BYTETEST_DCE) { - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_DCERPC) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Non dce alproto sig has " - "bytetest with dce enabled"); - goto error; - } - if ((data->flags & DETECT_BYTETEST_STRING) || - (data->flags & DETECT_BYTETEST_LITTLE) || - (data->flags & DETECT_BYTETEST_BIG) || - (data->base == DETECT_BYTETEST_BASE_DEC) || - (data->base == DETECT_BYTETEST_BASE_HEX) || - (data->base == DETECT_BYTETEST_BASE_OCT) ) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. " - "A byte_test keyword with dce holds other invalid modifiers."); - goto error; - } - } - - if (value != NULL) { - SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(value, s); - if (bed_sm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " - "seen in byte_test - %s\n", value); - goto error; - } - data->value = ((DetectByteExtractData *)bed_sm->ctx)->local_id; - data->flags |= DETECT_BYTETEST_VALUE_BE; - SCFree(value); - } - - if (offset != NULL) { - SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s); - if (bed_sm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " - "seen in byte_test - %s\n", offset); - goto error; - } - data->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id; - data->flags |= DETECT_BYTETEST_OFFSET_BE; - SCFree(offset); - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - sm->type = DETECT_BYTETEST; - sm->ctx = (SigMatchCtx *)data; - SigMatchAppendSMToList(s, sm, sm_list); - - if (!(data->flags & DETECT_BYTETEST_RELATIVE)) - goto okay; - - if (prev_pm == NULL) - goto okay; - if (prev_pm->type == DETECT_CONTENT) { - DetectContentData *cd = (DetectContentData *)prev_pm->ctx; - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - } else if (prev_pm->type == DETECT_PCRE) { - DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx; - pd->flags |= DETECT_PCRE_RELATIVE_NEXT; - } - - okay: - ret = 0; - return ret; - error: - DetectBytetestFree(data); - return ret; -} - -/** - * \brief this function will free memory associated with DetectBytetestData - * - * \param data pointer to DetectBytetestData - */ -void DetectBytetestFree(void *ptr) -{ - if (ptr == NULL) - return; - - DetectBytetestData *data = (DetectBytetestData *)ptr; - SCFree(data); -} - - -/* UNITTESTS */ -#ifdef UNITTESTS -#include "util-unittest-helper.h" -/** - * \test DetectBytetestTestParse01 is a test to make sure that we return "something" - * when given valid bytetest opt - */ -int DetectBytetestTestParse01(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, =, 1 , 0", NULL, NULL); - if (data != NULL) { - DetectBytetestFree(data); - result = 1; - } - - return result; -} - -/** - * \test DetectBytetestTestParse02 is a test for setting the required opts - */ -int DetectBytetestTestParse02(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, !=, 1, 0", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_EQ) - && (data->nbytes == 4) - && (data->value == 1) - && (data->offset == 0) - && (data->flags == DETECT_BYTETEST_NEGOP) - && (data->base == DETECT_BYTETEST_BASE_UNSET)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse03 is a test for setting the relative flag - */ -int DetectBytetestTestParse03(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, !=, 1, 0, relative", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_EQ) - && (data->nbytes == 4) - && (data->value == 1) - && (data->offset == 0) - && (data->flags == ( DETECT_BYTETEST_NEGOP - |DETECT_BYTETEST_RELATIVE)) - && (data->base == DETECT_BYTETEST_BASE_UNSET)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse04 is a test for setting the string/oct flags - */ -int DetectBytetestTestParse04(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, !=, 1, 0, string, oct", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_EQ) - && (data->nbytes == 4) - && (data->value == 1) - && (data->offset == 0) - && (data->flags == ( DETECT_BYTETEST_NEGOP - |DETECT_BYTETEST_STRING)) - && (data->base == DETECT_BYTETEST_BASE_OCT)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse05 is a test for setting the string/dec flags - */ -int DetectBytetestTestParse05(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, =, 1, 0, string, dec", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_EQ) - && (data->nbytes == 4) - && (data->value == 1) - && (data->offset == 0) - && (data->flags == DETECT_BYTETEST_STRING) - && (data->base == DETECT_BYTETEST_BASE_DEC)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse06 is a test for setting the string/hex flags - */ -int DetectBytetestTestParse06(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, >, 1, 0, string, hex", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_GT) - && (data->nbytes == 4) - && (data->value == 1) - && (data->offset == 0) - && (data->flags == DETECT_BYTETEST_STRING) - && (data->base == DETECT_BYTETEST_BASE_HEX)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse07 is a test for setting the big flag - */ -int DetectBytetestTestParse07(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, <, 5, 0, big", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_LT) - && (data->nbytes == 4) - && (data->value == 5) - && (data->offset == 0) - && (data->flags == 4) - && (data->base == DETECT_BYTETEST_BASE_UNSET)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse08 is a test for setting the little flag - */ -int DetectBytetestTestParse08(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, <, 5, 0, little", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_LT) - && (data->nbytes == 4) - && (data->value == 5) - && (data->offset == 0) - && (data->flags == DETECT_BYTETEST_LITTLE) - && (data->base == DETECT_BYTETEST_BASE_UNSET)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse09 is a test for neg operator only - */ -int DetectBytetestTestParse09(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, !, 5, 0", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_EQ) - && (data->nbytes == 4) - && (data->value == 5) - && (data->offset == 0) - && (data->flags == DETECT_BYTETEST_NEGOP) - && (data->base == DETECT_BYTETEST_BASE_UNSET)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse10 is a test for whitespace - */ -int DetectBytetestTestParse10(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse(" 4 , ! &, 5 , 0 , little ", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_AND) - && (data->nbytes == 4) - && (data->value == 5) - && (data->offset == 0) - && (data->flags == (DETECT_BYTETEST_NEGOP|DETECT_BYTETEST_LITTLE)) - && (data->base == DETECT_BYTETEST_BASE_UNSET)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse11 is a test for whitespace - */ -int DetectBytetestTestParse11(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4,!^,5,0,little,string,relative,hex", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_OR) - && (data->nbytes == 4) - && (data->value == 5) - && (data->offset == 0) - && (data->flags == ( DETECT_BYTETEST_NEGOP - |DETECT_BYTETEST_LITTLE - |DETECT_BYTETEST_STRING - |DETECT_BYTETEST_RELATIVE)) - && (data->base == DETECT_BYTETEST_BASE_HEX)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse12 is a test for hex w/o string - */ -int DetectBytetestTestParse12(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, =, 1, 0, hex", NULL, NULL); - if (data == NULL) { - result = 1; - } - - return result; -} - -/** - * \test DetectBytetestTestParse13 is a test for too many bytes to extract - */ -int DetectBytetestTestParse13(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("9, =, 1, 0", NULL, NULL); - if (data == NULL) { - result = 1; - } - - return result; -} - -/** - * \test DetectBytetestTestParse14 is a test for large string extraction - */ -int DetectBytetestTestParse14(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("23,=,0xffffffffffffffffULL,0,string,oct", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_EQ) - && (data->nbytes == 23) - && (data->value == 0xffffffffffffffffULL) - && (data->offset == 0) - && (data->flags == DETECT_BYTETEST_STRING) - && (data->base == DETECT_BYTETEST_BASE_OCT)) - { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test DetectBytetestTestParse15 is a test for too many bytes to extract (string) - */ -int DetectBytetestTestParse15(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("24, =, 0xffffffffffffffffULL, 0, string", NULL, NULL); - if (data == NULL) { - result = 1; - } - - return result; -} - -/** - * \test DetectBytetestTestParse16 is a test for offset too big - */ -int DetectBytetestTestParse16(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4,=,0,0xffffffffffffffffULL", NULL, NULL); - if (data == NULL) { - result = 1; - } - - return result; -} - -/** - * \test Test dce option. - */ -int DetectBytetestTestParse17(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, <, 5, 0, dce", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_LT) && - (data->nbytes == 4) && - (data->value == 5) && - (data->offset == 0) && - (data->flags & DETECT_BYTETEST_DCE) ) { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test Test dce option. - */ -int DetectBytetestTestParse18(void) -{ - int result = 0; - DetectBytetestData *data = NULL; - data = DetectBytetestParse("4, <, 5, 0", NULL, NULL); - if (data != NULL) { - if ( (data->op == DETECT_BYTETEST_OP_LT) && - (data->nbytes == 4) && - (data->value == 5) && - (data->offset == 0) && - !(data->flags & DETECT_BYTETEST_DCE) ) { - result = 1; - } - DetectBytetestFree(data); - } - - return result; -} - -/** - * \test Test dce option. - */ -int DetectBytetestTestParse19(void) -{ - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 1; - - s->alproto = ALPROTO_DCERPC; - - result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,dce") == 0); - result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,string,dce") == -1); - result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,big,dce") == -1); - result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,little,dce") == -1); - result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,hex,dce") == -1); - result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,oct,dce") == -1); - result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,dec,dce") == -1); - - SigFree(s); - return result; -} - -/** - * \test Test dce option. - */ -int DetectBytetestTestParse20(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - DetectBytetestData *bd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "byte_test:1,=,1,6,relative,dce; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_BYTETEST); - bd = (DetectBytetestData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (!(bd->flags & DETECT_BYTETEST_DCE) && - !(bd->flags & DETECT_BYTETEST_RELATIVE) && - (bd->flags & DETECT_BYTETEST_STRING) && - (bd->flags & DETECT_BYTETEST_BIG) && - (bd->flags & DETECT_BYTETEST_LITTLE) && - (bd->flags & DETECT_BYTETEST_NEGOP) ) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "byte_test:1,=,1,6,relative,dce; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_BYTETEST); - bd = (DetectBytetestData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (!(bd->flags & DETECT_BYTETEST_DCE) && - !(bd->flags & DETECT_BYTETEST_RELATIVE) && - (bd->flags & DETECT_BYTETEST_STRING) && - (bd->flags & DETECT_BYTETEST_BIG) && - (bd->flags & DETECT_BYTETEST_LITTLE) && - (bd->flags & DETECT_BYTETEST_NEGOP) ) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "byte_test:1,=,1,6,relative; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_BYTETEST); - bd = (DetectBytetestData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if ((bd->flags & DETECT_BYTETEST_DCE) && - !(bd->flags & DETECT_BYTETEST_RELATIVE) && - (bd->flags & DETECT_BYTETEST_STRING) && - (bd->flags & DETECT_BYTETEST_BIG) && - (bd->flags & DETECT_BYTETEST_LITTLE) && - (bd->flags & DETECT_BYTETEST_NEGOP) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test dce option. - */ -int DetectBytetestTestParse21(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,string,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,big,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,little,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,hex,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,dec,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,oct,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,string,hex,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,big,string,hex,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,big,string,oct,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,little,string,hex,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytetest_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "content:\"one\"; byte_test:1,=,1,6,big,string,dec,dce; sid:1;)"); - if (s != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test file_data - */ -static int DetectBytetestTestParse22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectBytetestData *bd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; byte_test:1,=,1,6,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("empty server body list: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_BYTETEST) { - printf("bytetest not last sm in server body list: "); - goto end; - } - - bd = (DetectBytetestData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (bd->flags & DETECT_BYTETEST_DCE && - bd->flags & DETECT_BYTETEST_RELATIVE && - (bd->flags & DETECT_BYTETEST_STRING) && - (bd->flags & DETECT_BYTETEST_BIG) && - (bd->flags & DETECT_BYTETEST_LITTLE) && - (bd->flags & DETECT_BYTETEST_NEGOP) ) { - printf("wrong flags: "); - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectByteTestTestPacket01 is a test to check matches of - * byte_test and byte_test relative works if the previous keyword is pcre - * (bug 142) - */ -int DetectByteTestTestPacket01 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0" - "User-Agent: Wget/1.11.4" - "Accept: */*" - "Host: www.google.com" - "Connection: Keep-Alive" - "Date: Mon, 04 Jan 2010 17:29:39 GMT"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre + byte_test + " - "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_test:1,=,1" - ",6,relative,string,dec; sid:126; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} - -/** - * \test DetectByteTestTestPacket02 is a test to check matches of - * byte_test and byte_test relative works if the previous keyword is byte_jump - * (bug 158) - */ -int DetectByteTestTestPacket02 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0" - "User-Agent: Wget/1.11.4" - "Accept: */*" - "Host: www.google.com" - "Connection: Keep-Alive" - "Date: Mon, 04 Jan 2010 17:29:39 GMT"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test + " - "relative\"; byte_jump:1,44,string,dec; byte_test:1,=,0,0,relative,string," - "dec; sid:777; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} - -int DetectByteTestTestPacket03(void) -{ - int result = 0; - uint8_t *buf = NULL; - uint16_t buflen = 0; - buf = SCMalloc(4); - if (unlikely(buf == NULL)) { - printf("malloc failed\n"); - exit(EXIT_FAILURE); - } - memcpy(buf, "boom", 4); - buflen = 4; - - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test\"; " - "byte_test:1,=,65,214748364; sid:1; rev:1;)"; - - result = !UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); - -end: - return result; -} - -/** \test Test the byte_test signature matching with operator <= */ -int DetectByteTestTestPacket04(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0" - "User-Agent: Wget/1.11.4" - "Accept: */*" - "Host: www.google.com" - "Connection: Keep-Alive" - "Date: Mon, 04 Jan 2010 17:29:39 GMT"; - uint16_t buflen = strlen((char *)buf); - - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test +" - "relative\"; content:\"GET \"; depth:4; content:\"HTTP/1.\"; " - "byte_test:1,<=,0,0,relative,string,dec; sid:124; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); - -end: - return result; -} - -/** \test Test the byte_test signature matching with operator >= */ -int DetectByteTestTestPacket05(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0" - "User-Agent: Wget/1.11.4" - "Accept: */*" - "Host: www.google.com" - "Connection: Keep-Alive" - "Date: Mon, 04 Jan 2010 17:29:39 GMT"; - uint16_t buflen = strlen((char *)buf); - - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test +" - "relative\"; content:\"GET \"; depth:4; content:\"HTTP/1.\"; " - "byte_test:1,>=,0,0,relative,string,dec; sid:125; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); - -end: - return result; -} - -#endif /* UNITTESTS */ - - -/** - * \brief this function registers unit tests for DetectBytetest - */ -void DetectBytetestRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectBytetestTestParse01", DetectBytetestTestParse01, 1); - UtRegisterTest("DetectBytetestTestParse02", DetectBytetestTestParse02, 1); - UtRegisterTest("DetectBytetestTestParse03", DetectBytetestTestParse03, 1); - UtRegisterTest("DetectBytetestTestParse04", DetectBytetestTestParse04, 1); - UtRegisterTest("DetectBytetestTestParse05", DetectBytetestTestParse05, 1); - UtRegisterTest("DetectBytetestTestParse06", DetectBytetestTestParse06, 1); - UtRegisterTest("DetectBytetestTestParse07", DetectBytetestTestParse07, 1); - UtRegisterTest("DetectBytetestTestParse08", DetectBytetestTestParse08, 1); - UtRegisterTest("DetectBytetestTestParse09", DetectBytetestTestParse09, 1); - UtRegisterTest("DetectBytetestTestParse10", DetectBytetestTestParse10, 1); - UtRegisterTest("DetectBytetestTestParse11", DetectBytetestTestParse11, 1); - UtRegisterTest("DetectBytetestTestParse12", DetectBytetestTestParse12, 1); - UtRegisterTest("DetectBytetestTestParse13", DetectBytetestTestParse13, 1); - UtRegisterTest("DetectBytetestTestParse14", DetectBytetestTestParse14, 1); - UtRegisterTest("DetectBytetestTestParse15", DetectBytetestTestParse15, 1); - UtRegisterTest("DetectBytetestTestParse17", DetectBytetestTestParse17, 1); - UtRegisterTest("DetectBytetestTestParse18", DetectBytetestTestParse18, 1); - UtRegisterTest("DetectBytetestTestParse19", DetectBytetestTestParse19, 1); - UtRegisterTest("DetectBytetestTestParse20", DetectBytetestTestParse20, 1); - UtRegisterTest("DetectBytetestTestParse21", DetectBytetestTestParse21, 1); - UtRegisterTest("DetectBytetestTestParse22", DetectBytetestTestParse22, 1); - - UtRegisterTest("DetectByteTestTestPacket01", DetectByteTestTestPacket01, 1); - UtRegisterTest("DetectByteTestTestPacket02", DetectByteTestTestPacket02, 1); - UtRegisterTest("DetectByteTestTestPacket03", DetectByteTestTestPacket03, 1); - UtRegisterTest("DetectByteTestTestPacket04", DetectByteTestTestPacket04, 1); - UtRegisterTest("DetectByteTestTestPacket05", DetectByteTestTestPacket05, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-bytetest.h b/framework/src/suricata/src/detect-bytetest.h deleted file mode 100644 index 09d453fa..00000000 --- a/framework/src/suricata/src/detect-bytetest.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - */ - -#ifndef __DETECT_BYTETEST_H__ -#define __DETECT_BYTETEST_H__ - -/** Bytetest Operators */ -#define DETECT_BYTETEST_OP_LT 1 /**< "less than" operator */ -#define DETECT_BYTETEST_OP_GT 2 /**< "greater than" operator */ -#define DETECT_BYTETEST_OP_EQ 3 /**< "equals" operator */ -#define DETECT_BYTETEST_OP_AND 4 /**< "bitwise and" operator */ -#define DETECT_BYTETEST_OP_OR 5 /**< "bitwise or" operator */ -#define DETECT_BYTETEST_OP_GE 6 /**< greater than equal operator */ -#define DETECT_BYTETEST_OP_LE 7 /**< less than equal operator */ - -/** Bytetest Base */ -#define DETECT_BYTETEST_BASE_UNSET 0 /**< Unset type value string (automatic)*/ -#define DETECT_BYTETEST_BASE_OCT 8 /**< "oct" type value string */ -#define DETECT_BYTETEST_BASE_DEC 10 /**< "dec" type value string */ -#define DETECT_BYTETEST_BASE_HEX 16 /**< "hex" type value string */ - -/** Bytetest Flags */ -#define DETECT_BYTETEST_NEGOP 0x01 /**< "!" negated operator */ -#define DETECT_BYTETEST_LITTLE 0x02 /**< "little" endian value */ -#define DETECT_BYTETEST_BIG 0x04 /**< "bi" endian value */ -#define DETECT_BYTETEST_STRING 0x08 /**< "string" value */ -#define DETECT_BYTETEST_RELATIVE 0x10 /**< "relative" offset */ -#define DETECT_BYTETEST_DCE 0x20 /**< dce enabled */ -#define DETECT_BYTETEST_VALUE_BE 0x40 /**< byte extract value enabled */ -#define DETECT_BYTETEST_OFFSET_BE 0x80 /**< byte extract value enabled */ - -typedef struct DetectBytetestData_ { - uint8_t nbytes; /**< Number of bytes to compare */ - uint8_t op; /**< Operator used to compare */ - uint8_t base; /**< String value base (oct|dec|hex) */ - uint8_t flags; /**< Flags (big|little|relative|string) */ - int32_t offset; /**< Offset in payload */ - uint64_t value; /**< Value to compare against */ -} DetectBytetestData; - -/* prototypes */ - -/** - * Registration function for byte_test. - * - * \todo add support for no_stream and stream_only - */ -void DetectBytetestRegister (void); - -/** - * This function is used to add the parsed byte_test data - * into the current signature. - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param optstr pointer to the user provided options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectBytetestSetup(DetectEngineCtx *, Signature *, char *); - -/** - * \brief this function will free memory associated with DetectBytetestData - * - * \param data pointer to DetectBytetestData - */ -void DetectBytetestFree(void *ptr); - -/** - * This function is used to parse byte_test options passed via - * - * byte_test: bytes, [!]op, value, offset [,flags [, ...]] - * - * flags: "big", "little", "relative", "string", "oct", "dec", "hex" - * - * \param optstr Pointer to the user provided byte_test options - * \param value Used to pass the value back, if byte_test uses a byte_extract - * var. - * \param offset Used to pass the offset back, if byte_test uses a byte_extract - * var. - * - * \retval data pointer to DetectBytetestData on success - * \retval NULL on failure - */ -DetectBytetestData *DetectBytetestParse(char *optstr, char **value, - char **offset); - -/** - * This function is used to match byte_test - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectBytetestData - * - * \retval -1 error - * \retval 0 no match - * \retval 1 match - * - * \todo The return seems backwards. We should return a non-zero error code. One of the error codes is "no match". As-is if someone accidentally does: if (DetectBytetestMatch(...)) { match }, then they catch an error as a match. - */ -int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx); -int DetectBytetestDoMatch(DetectEngineThreadCtx *, Signature *, - const SigMatchCtx *ctx, uint8_t *, uint32_t, - uint8_t, int32_t, uint64_t); - -#endif /* __DETECT_BYTETEST_H__ */ diff --git a/framework/src/suricata/src/detect-classtype.c b/framework/src/suricata/src/detect-classtype.c deleted file mode 100644 index bc773710..00000000 --- a/framework/src/suricata/src/detect-classtype.c +++ /dev/null @@ -1,342 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements classtype keyword. - */ - -#include "suricata-common.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-classtype.h" -#include "flow-var.h" -#include "util-classification-config.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-unittest.h" - -#define DETECT_CLASSTYPE_REGEX "^\\s*([a-zA-Z][a-zA-Z0-9-_]*)\\s*$" - -static pcre *regex = NULL; -static pcre_extra *regex_study = NULL; - -static int DetectClasstypeSetup(DetectEngineCtx *, Signature *, char *); -void DetectClasstypeRegisterTests(void); - -/** - * \brief Registers the handler functions for the "Classtype" keyword. - */ -void DetectClasstypeRegister(void) -{ - const char *eb = NULL; - int eo; - int opts = 0; - - SCLogDebug("Registering the Classtype keyword handler"); - - sigmatch_table[DETECT_CLASSTYPE].name = "classtype"; - sigmatch_table[DETECT_CLASSTYPE].desc = "information about the classification of rules and alerts"; - sigmatch_table[DETECT_CLASSTYPE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Meta-settings#Classtype"; - sigmatch_table[DETECT_CLASSTYPE].Match = NULL; - sigmatch_table[DETECT_CLASSTYPE].Setup = DetectClasstypeSetup; - sigmatch_table[DETECT_CLASSTYPE].Free = NULL; - sigmatch_table[DETECT_CLASSTYPE].RegisterTests = DetectClasstypeRegisterTests; - - regex = pcre_compile(DETECT_CLASSTYPE_REGEX, opts, &eb, &eo, NULL); - if (regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - DETECT_CLASSTYPE_REGEX, eo, eb); - goto end; - } - - regex_study = pcre_study(regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto end; - } - - end: - return; -} - -/** - * \brief Parses the raw string supplied with the "Classtype" keyword. - * - * \param Pointer to the string to be parsed. - * - * \retval bool success or failure. - */ -static int DetectClasstypeParseRawString(char *rawstr, char *out, size_t outsize) -{ -#define MAX_SUBSTRINGS 30 - int ret = 0; - int ov[MAX_SUBSTRINGS]; - size_t len = strlen(rawstr); - - /* get rid of the double quotes if present */ - if (rawstr[0] == '\"' && rawstr[strlen(rawstr) - 1] == '\"') { - rawstr++; - rawstr[strlen(rawstr) - 1] = '\0'; - len -= 2; - } - - ret = pcre_exec(regex, regex_study, rawstr, len, 0, 0, ov, 30); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_MATCH, "Invalid Classtype in Signature"); - goto end; - } - - ret = pcre_copy_substring((char *)rawstr, ov, 30, 1, out, outsize); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto end; - } - - return 0; - end: - return -1; -} - -/** - * \brief The setup function that would be called when the Signature parsing - * module encounters the "Classtype" keyword. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer the current Signature instance that is being parsed. - * \param rawstr Pointer to the argument supplied to the classtype keyword. - * - * \retval 0 On success - * \retval -1 On failure - */ -static int DetectClasstypeSetup(DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - char parsed_ct_name[1024] = ""; - SCClassConfClasstype *ct = NULL; - - if (DetectClasstypeParseRawString(rawstr, parsed_ct_name, sizeof(parsed_ct_name)) < -1) { - SCLogError(SC_ERR_PCRE_PARSE, "Error parsing classtype argument supplied with the " - "classtype keyword"); - goto error; - } - - ct = SCClassConfGetClasstype(parsed_ct_name, de_ctx); - if (ct == NULL) { - SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown Classtype: \"%s\". Invalidating the Signature", - parsed_ct_name); - goto error; - } - - /* if we have retrieved the classtype, assign the message to be displayed - * for this Signature by fast.log, if a Packet matches this Signature */ - s->class = ct->classtype_id; - s->class_msg = ct->classtype_desc; - - /* if a priority keyword has appeared before the classtype, s->prio would - * hold a value which is != -1, in which case we don't overwrite the value. - * Otherwise, overwrite the value */ - if (s->prio == -1) - s->prio = ct->priority; - - return 0; - - error: - return -1; -} - -/*------------------------------Unittests-------------------------------------*/ - -#ifdef UNITTESTS - -/** - * \test Check that supplying an invalid classtype in the rule, results in the - * rule being invalidated. - */ -int DetectClasstypeTest01() -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Classtype test\"; " - "Classtype:not_available; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - DetectEngineCtxFree(de_ctx); - -end: - return result; -} - -/** - * \test Check that both valid and invalid classtypes in a rule are handled - * properly, with rules containing invalid classtypes being rejected - * and the ones containing valid classtypes parsed and returned. - */ -int DetectClasstypeTest02() -{ - int result = 0; - Signature *last = NULL; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Classtype test\"; Classtype:bad-unknown; sid:1;)"); - if (sig == NULL) { - printf("first sig failed to parse: "); - result = 0; - goto end; - } - de_ctx->sig_list = last = sig; - result = (sig != NULL); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Classtype test\"; Classtype:not-there; sid:1;)"); - last->next = sig; - result &= (sig == NULL); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Classtype test\"; Classtype:Bad-UnkNown; sid:1;)"); - if (sig == NULL) { - printf("second sig failed to parse: "); - result = 0; - goto end; - } - last->next = sig; - last = sig; - result &= (sig != NULL); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Classtype test\"; Classtype:nothing-wrong; sid:1;)"); - if (sig == NULL) { - result = 0; - goto end; - } - last->next = sig; - last = sig; - result &= (sig != NULL); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Classtype test\"; Classtype:attempted_dos; sid:1;)"); - last->next = sig; - result &= (sig == NULL); - - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - -end: - return result; -} - -/** - * \test Check that the signatures are assigned priority based on classtype they - * are given. - */ -int DetectClasstypeTest03() -{ - int result = 0; - Signature *last = NULL; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Classtype test\"; Classtype:bad-unknown; priority:1; sid:1;)"); - if (sig == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list = last = sig; - result = (sig != NULL); - result &= (sig->prio == 1); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Classtype test\"; Classtype:unKnoWn; " - "priority:3; sid:1;)"); - if (sig == NULL) { - result = 0; - goto end; - } - last->next = sig; - last = sig; - result &= (sig != NULL); - result &= (sig->prio == 3); - - sig = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"Classtype test\"; " - "Classtype:nothing-wrong; priority:1; sid:1;)"); - if (sig == NULL) { - result = 0; - goto end; - } - last->next = sig; - last = sig; - result &= (sig != NULL); - result &= (sig->prio == 1); - - - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - -end: - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief This function registers unit tests for Classification Config API. - */ -void DetectClasstypeRegisterTests(void) -{ - -#ifdef UNITTESTS - - UtRegisterTest("DetectClasstypeTest01", DetectClasstypeTest01, 1); - UtRegisterTest("DetectClasstypeTest02", DetectClasstypeTest02, 1); - UtRegisterTest("DetectClasstypeTest03", DetectClasstypeTest03, 1); - -#endif /* UNITTESTS */ - -} diff --git a/framework/src/suricata/src/detect-classtype.h b/framework/src/suricata/src/detect-classtype.h deleted file mode 100644 index 6e0dd509..00000000 --- a/framework/src/suricata/src/detect-classtype.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_CLASSTYPE_H__ -#define __DETECT_CLASSTYPE_H__ - -/* prototypes */ -void DetectClasstypeRegister(void); - -#endif /* __DETECT_CLASSTYPE_H__ */ - diff --git a/framework/src/suricata/src/detect-content.c b/framework/src/suricata/src/detect-content.c deleted file mode 100644 index 5f315cc5..00000000 --- a/framework/src/suricata/src/detect-content.c +++ /dev/null @@ -1,2824 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Simple content match part of the detection engine. - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-engine-mpm.h" -#include "detect-engine.h" -#include "detect-engine-state.h" -#include "detect-parse.h" -#include "util-mpm.h" -#include "flow.h" -#include "flow-util.h" -#include "flow-var.h" -#include "detect-flow.h" -#include "app-layer.h" -#include "util-unittest.h" -#include "util-print.h" -#include "util-debug.h" -#include "util-spm-bm.h" -#include "threads.h" -#include "util-unittest-helper.h" -#include "pkt-var.h" -#include "host.h" -#include "util-profiling.h" - -int DetectContentMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, SigMatch *); -int DetectContentSetup(DetectEngineCtx *, Signature *, char *); -void DetectContentRegisterTests(void); - -void DetectContentRegister (void) -{ - sigmatch_table[DETECT_CONTENT].name = "content"; - sigmatch_table[DETECT_CONTENT].desc = "match on payload content"; - sigmatch_table[DETECT_CONTENT].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#Content"; - sigmatch_table[DETECT_CONTENT].Match = NULL; - sigmatch_table[DETECT_CONTENT].Setup = DetectContentSetup; - sigmatch_table[DETECT_CONTENT].Free = DetectContentFree; - sigmatch_table[DETECT_CONTENT].RegisterTests = DetectContentRegisterTests; - - sigmatch_table[DETECT_CONTENT].flags |= SIGMATCH_PAYLOAD; -} - -/* pass on the content_max_id */ -uint32_t DetectContentMaxId(DetectEngineCtx *de_ctx) -{ - return MpmPatternIdStoreGetMaxId(de_ctx->mpm_pattern_id_store); -} - -/** - * \brief Parse a content string, ie "abc|DE|fgh" - * - * \param content_str null terminated string containing the content - * \param result result pointer to pass the fully parsed byte array - * \param result_len size of the resulted data - * \param flags flags to be set by this parsing function - * - * \retval -1 error - * \retval 0 ok - */ -int DetectContentDataParse(const char *keyword, const char *contentstr, - uint8_t **pstr, uint16_t *plen, uint32_t *flags) -{ - char *str = NULL; - uint16_t len; - uint16_t pos = 0; - uint16_t slen = 0; - - slen = strlen(contentstr); - if (slen == 0) { - return -1; - } - - /* skip the first spaces */ - while (pos < slen && isspace((unsigned char)contentstr[pos])) - pos++; - - if (contentstr[pos] == '!') { - *flags = DETECT_CONTENT_NEGATED; - pos++; - } else - *flags = 0; - - if (contentstr[pos] == '\"' && ((slen - pos) <= 1)) - goto error; - - if (!(contentstr[pos] == '\"' && contentstr[slen - 1] == '\"')) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "%s keyword arguments " - "should be always enclosed in double quotes. Invalid " - "content keyword passed in this rule - \"%s\"", - keyword, contentstr); - goto error; - } - - if ((str = SCStrdup(contentstr + pos + 1)) == NULL) - goto error; - str[strlen(str) - 1] = '\0'; - - len = strlen(str); - if (len == 0) - goto error; - - SCLogDebug("\"%s\", len %" PRIu32 "", str, len); - - //SCLogDebug("DetectContentParse: \"%s\", len %" PRIu32 "", str, len); - char converted = 0; - - { - uint16_t i, x; - uint8_t bin = 0; - uint8_t escape = 0; - uint8_t binstr[3] = ""; - uint8_t binpos = 0; - uint16_t bin_count = 0; - - for (i = 0, x = 0; i < len; i++) { - // SCLogDebug("str[%02u]: %c", i, str[i]); - if (str[i] == '|') { - bin_count++; - if (bin) { - bin = 0; - } else { - bin = 1; - } - } else if(!escape && str[i] == '\\') { - escape = 1; - } else { - if (bin) { - if (isdigit((unsigned char)str[i]) || - str[i] == 'A' || str[i] == 'a' || - str[i] == 'B' || str[i] == 'b' || - str[i] == 'C' || str[i] == 'c' || - str[i] == 'D' || str[i] == 'd' || - str[i] == 'E' || str[i] == 'e' || - str[i] == 'F' || str[i] == 'f') - { - // SCLogDebug("part of binary: %c", str[i]); - - binstr[binpos] = (char)str[i]; - binpos++; - - if (binpos == 2) { - uint8_t c = strtol((char *)binstr, (char **) NULL, 16) & 0xFF; - binpos = 0; - str[x] = c; - x++; - converted = 1; - } - } else if (str[i] == ' ') { - // SCLogDebug("space as part of binary string"); - } - else if (str[i] != ',') { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid hex code in " - "content - %s, hex %c. Invalidating signature", str, str[i]); - goto error; - } - } else if (escape) { - if (str[i] == ':' || - str[i] == ';' || - str[i] == '\\' || - str[i] == '\"') - { - str[x] = str[i]; - x++; - } else { - //SCLogDebug("Can't escape %c", str[i]); - goto error; - } - escape = 0; - converted = 1; - } else { - str[x] = str[i]; - x++; - } - } - } - - if (bin_count % 2 != 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid hex code assembly in " - "%s - %s. Invalidating signature", keyword, contentstr); - goto error; - } - - if (converted) { - len = x; - } - } - - *plen = len; - *pstr = (uint8_t *)str; - return 0; - -error: - if (str != NULL) - SCFree(str); - return -1; -} -/** - * \brief DetectContentParse - * \initonly - */ -DetectContentData *DetectContentParse (char *contentstr) -{ - DetectContentData *cd = NULL; - uint8_t *content = NULL; - uint16_t len = 0; - uint32_t flags = 0; - int ret; - - ret = DetectContentDataParse("content", contentstr, &content, &len, &flags); - if (ret == -1) { - return NULL; - } - - cd = SCMalloc(sizeof(DetectContentData) + len); - if (unlikely(cd == NULL)) { - SCFree(content); - exit(EXIT_FAILURE); - } - - memset(cd, 0, sizeof(DetectContentData) + len); - - if (flags == DETECT_CONTENT_NEGATED) - cd->flags |= DETECT_CONTENT_NEGATED; - - cd->content = (uint8_t *)cd + sizeof(DetectContentData); - memcpy(cd->content, content, len); - cd->content_len = len; - - /* Prepare Boyer Moore context for searching faster */ - cd->bm_ctx = BoyerMooreCtxInit(cd->content, cd->content_len); - cd->depth = 0; - cd->offset = 0; - cd->within = 0; - cd->distance = 0; - - SCFree(content); - return cd; - -} - -DetectContentData *DetectContentParseEncloseQuotes(char *contentstr) -{ - char str[strlen(contentstr) + 3]; // 2 for quotes, 1 for \0 - - str[0] = '\"'; - memcpy(str + 1, contentstr, strlen(contentstr)); - str[strlen(contentstr) + 1] = '\"'; - str[strlen(contentstr) + 2] = '\0'; - - return DetectContentParse(str); -} - -/** - * \brief Helper function to print a DetectContentData - */ -void DetectContentPrint(DetectContentData *cd) -{ - int i = 0; - if (cd == NULL) { - SCLogDebug("DetectContentData \"cd\" is NULL"); - return; - } - char *tmpstr=SCMalloc(sizeof(char) * cd->content_len + 1); - - if (tmpstr != NULL) { - for (i = 0; i < cd->content_len; i++) { - if (isprint(cd->content[i])) - tmpstr[i] = cd->content[i]; - else - tmpstr[i] = '.'; - } - tmpstr[i] = '\0'; - SCLogDebug("Content: \"%s\"", tmpstr); - SCFree(tmpstr); - } else { - SCLogDebug("Content: "); - for (i = 0; i < cd->content_len; i++) - SCLogDebug("%c", cd->content[i]); - } - - SCLogDebug("Content_id: %"PRIu32, cd->id); - SCLogDebug("Content_len: %"PRIu16, cd->content_len); - SCLogDebug("Depth: %"PRIu16, cd->depth); - SCLogDebug("Offset: %"PRIu16, cd->offset); - SCLogDebug("Within: %"PRIi32, cd->within); - SCLogDebug("Distance: %"PRIi32, cd->distance); - SCLogDebug("flags: %u ", cd->flags); - SCLogDebug("negated: %s ", cd->flags & DETECT_CONTENT_NEGATED ? "true" : "false"); - SCLogDebug("relative match next: %s ", cd->flags & DETECT_CONTENT_RELATIVE_NEXT ? "true" : "false"); - if (cd->replace && cd->replace_len) { - char *tmpstr=SCMalloc(sizeof(char) * cd->replace_len + 1); - - if (tmpstr != NULL) { - for (i = 0; i < cd->replace_len; i++) { - if (isprint(cd->replace[i])) - tmpstr[i] = cd->replace[i]; - else - tmpstr[i] = '.'; - } - tmpstr[i] = '\0'; - SCLogDebug("Replace: \"%s\"", tmpstr); - SCFree(tmpstr); - } else { - SCLogDebug("Replace: "); - for (i = 0; i < cd->replace_len; i++) - SCLogDebug("%c", cd->replace[i]); - } - } - SCLogDebug("-----------"); -} - -/** - * \brief Print list of DETECT_CONTENT SigMatch's allocated in a - * SigMatch list, from the current sm to the end - * \param sm pointer to the current SigMatch to start printing from - */ -void DetectContentPrintAll(SigMatch *sm) -{ -#ifdef DEBUG - if (SCLogDebugEnabled()) { - int i = 0; - - if (sm == NULL) - return; - - SigMatch *first_sm = sm; - - /* Print all of them */ - for (; first_sm != NULL; first_sm = first_sm->next) { - if (first_sm->type == DETECT_CONTENT) { - SCLogDebug("Printing SigMatch DETECT_CONTENT %d", ++i); - DetectContentPrint((DetectContentData*)first_sm->ctx); - } - } - } -#endif /* DEBUG */ -} - -/** - * \brief Function to setup a content pattern. - * - * \param de_ctx pointer to the current detection_engine - * \param s pointer to the current Signature - * \param m pointer to the last parsed SigMatch - * \param contentstr pointer to the current keyword content string - * \retval -1 if error - * \retval 0 if all was ok - */ -int DetectContentSetup(DetectEngineCtx *de_ctx, Signature *s, char *contentstr) -{ - DetectContentData *cd = NULL; - SigMatch *sm = NULL; - - cd = DetectContentParse(contentstr); - if (cd == NULL) - goto error; - DetectContentPrint(cd); - - int sm_list; - if (s->list != DETECT_SM_LIST_NOTSET) { - if (s->list == DETECT_SM_LIST_FILEDATA && s->alproto == ALPROTO_HTTP) { - AppLayerHtpEnableResponseBodyCallback(); - s->alproto = ALPROTO_HTTP; - } - - s->flags |= SIG_FLAG_APPLAYER; - sm_list = s->list; - } else { - sm_list = DETECT_SM_LIST_PMATCH; - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - sm->ctx = (void *)cd; - sm->type = DETECT_CONTENT; - SigMatchAppendSMToList(s, sm, sm_list); - - return 0; - -error: - DetectContentFree(cd); - return -1; -} - -/** - * \brief this function will SCFree memory associated with DetectContentData - * - * \param cd pointer to DetectCotentData - */ -void DetectContentFree(void *ptr) -{ - SCEnter(); - DetectContentData *cd = (DetectContentData *)ptr; - - if (cd == NULL) - SCReturn; - - BoyerMooreCtxDeInit(cd->bm_ctx); - - SCFree(cd); - SCReturn; -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectCotentParseTest01 this is a test to make sure we can deal with escaped colons - */ -int DetectContentParseTest01 (void) -{ - int result = 1; - DetectContentData *cd = NULL; - char *teststring = "\"abc\\:def\""; - char *teststringparsed = "abc:def"; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (memcmp(cd->content, teststringparsed, strlen(teststringparsed)) != 0) { - SCLogDebug("expected %s got ", teststringparsed); - PrintRawUriFp(stdout,cd->content,cd->content_len); - SCLogDebug(": "); - result = 0; - DetectContentFree(cd); - } - } else { - SCLogDebug("expected %s got NULL: ", teststringparsed); - result = 0; - } - return result; -} - -/** - * \test DetectCotentParseTest02 this is a test to make sure we can deal with escaped semi-colons - */ -int DetectContentParseTest02 (void) -{ - int result = 1; - DetectContentData *cd = NULL; - char *teststring = "\"abc\\;def\""; - char *teststringparsed = "abc;def"; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (memcmp(cd->content, teststringparsed, strlen(teststringparsed)) != 0) { - SCLogDebug("expected %s got ", teststringparsed); - PrintRawUriFp(stdout,cd->content,cd->content_len); - SCLogDebug(": "); - result = 0; - DetectContentFree(cd); - } - } else { - SCLogDebug("expected %s got NULL: ", teststringparsed); - result = 0; - } - return result; -} - -/** - * \test DetectCotentParseTest03 this is a test to make sure we can deal with escaped double-quotes - */ -int DetectContentParseTest03 (void) -{ - int result = 1; - DetectContentData *cd = NULL; - char *teststring = "\"abc\\\"def\""; - char *teststringparsed = "abc\"def"; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (memcmp(cd->content, teststringparsed, strlen(teststringparsed)) != 0) { - SCLogDebug("expected %s got ", teststringparsed); - PrintRawUriFp(stdout,cd->content,cd->content_len); - SCLogDebug(": "); - result = 0; - DetectContentFree(cd); - } - } else { - SCLogDebug("expected %s got NULL: ", teststringparsed); - result = 0; - } - return result; -} - -/** - * \test DetectCotentParseTest04 this is a test to make sure we can deal with escaped backslashes - */ -int DetectContentParseTest04 (void) -{ - int result = 1; - DetectContentData *cd = NULL; - char *teststring = "\"abc\\\\def\""; - char *teststringparsed = "abc\\def"; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - uint16_t len = (cd->content_len > strlen(teststringparsed)); - if (memcmp(cd->content, teststringparsed, len) != 0) { - SCLogDebug("expected %s got ", teststringparsed); - PrintRawUriFp(stdout,cd->content,cd->content_len); - SCLogDebug(": "); - result = 0; - DetectContentFree(cd); - } - } else { - SCLogDebug("expected %s got NULL: ", teststringparsed); - result = 0; - } - return result; -} - -/** - * \test DetectCotentParseTest05 test illegal escape - */ -int DetectContentParseTest05 (void) -{ - int result = 1; - DetectContentData *cd = NULL; - char *teststring = "\"abc\\def\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - SCLogDebug("expected NULL got "); - PrintRawUriFp(stdout,cd->content,cd->content_len); - SCLogDebug(": "); - result = 0; - DetectContentFree(cd); - } - return result; -} - -/** - * \test DetectCotentParseTest06 test a binary content - */ -int DetectContentParseTest06 (void) -{ - int result = 1; - DetectContentData *cd = NULL; - char *teststring = "\"a|42|c|44|e|46|\""; - char *teststringparsed = "abcdef"; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - uint16_t len = (cd->content_len > strlen(teststringparsed)); - if (memcmp(cd->content, teststringparsed, len) != 0) { - SCLogDebug("expected %s got ", teststringparsed); - PrintRawUriFp(stdout,cd->content,cd->content_len); - SCLogDebug(": "); - result = 0; - DetectContentFree(cd); - } - } else { - SCLogDebug("expected %s got NULL: ", teststringparsed); - result = 0; - } - return result; -} - -/** - * \test DetectCotentParseTest07 test an empty content - */ -int DetectContentParseTest07 (void) -{ - int result = 1; - DetectContentData *cd = NULL; - char *teststring = "\"\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - SCLogDebug("expected NULL got %p: ", cd); - result = 0; - DetectContentFree(cd); - } - return result; -} - -/** - * \test DetectCotentParseTest08 test an empty content - */ -int DetectContentParseTest08 (void) -{ - int result = 1; - DetectContentData *cd = NULL; - char *teststring = "\"\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - SCLogDebug("expected NULL got %p: ", cd); - result = 0; - DetectContentFree(cd); - } - return result; -} - -/** - * \test Test packet Matches - * \param raw_eth_pkt pointer to the ethernet packet - * \param pktsize size of the packet - * \param sig pointer to the signature to test - * \param sid sid number of the signature - * \retval return 1 if match - * \retval return 0 if not - */ -int DetectContentLongPatternMatchTest(uint8_t *raw_eth_pkt, uint16_t pktsize, char *sig, - uint32_t sid) -{ - int result = 0; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - DecodeThreadVars dtv; - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - FlowInitConfig(FLOW_QUIET); - DecodeEthernet(&th_v, &dtv, p, raw_eth_pkt, pktsize, NULL); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig); - if (de_ctx->sig_list == NULL) { - goto end; - } - de_ctx->sig_list->next = NULL; - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->type == DETECT_CONTENT) { - DetectContentData *co = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (co->flags & DETECT_CONTENT_RELATIVE_NEXT) { - printf("relative next flag set on final match which is content: "); - goto end; - } - } - - SCLogDebug("---DetectContentLongPatternMatchTest---"); - DetectContentPrintAll(de_ctx->sig_list->sm_lists[DETECT_SM_LIST_MATCH]); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, sid) != 1) { - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - PACKET_RECYCLE(p); - FlowShutdown(); - - SCFree(p); - return result; -} - -/** - * \brief Wrapper for DetectContentLongPatternMatchTest - */ -int DetectContentLongPatternMatchTestWrp(char *sig, uint32_t sid) -{ - /** Real packet with the following tcp data: - * "Hi, this is a big test to check content matches of splitted" - * "patterns between multiple chunks!" - * (without quotes! :) ) - */ - uint8_t raw_eth_pkt[] = { - 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, - 0x00,0x00,0x00,0x00,0x08,0x00,0x45,0x00, - 0x00,0x85,0x00,0x01,0x00,0x00,0x40,0x06, - 0x7c,0x70,0x7f,0x00,0x00,0x01,0x7f,0x00, - 0x00,0x01,0x00,0x14,0x00,0x50,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x02, - 0x20,0x00,0xc9,0xad,0x00,0x00,0x48,0x69, - 0x2c,0x20,0x74,0x68,0x69,0x73,0x20,0x69, - 0x73,0x20,0x61,0x20,0x62,0x69,0x67,0x20, - 0x74,0x65,0x73,0x74,0x20,0x74,0x6f,0x20, - 0x63,0x68,0x65,0x63,0x6b,0x20,0x63,0x6f, - 0x6e,0x74,0x65,0x6e,0x74,0x20,0x6d,0x61, - 0x74,0x63,0x68,0x65,0x73,0x20,0x6f,0x66, - 0x20,0x73,0x70,0x6c,0x69,0x74,0x74,0x65, - 0x64,0x20,0x70,0x61,0x74,0x74,0x65,0x72, - 0x6e,0x73,0x20,0x62,0x65,0x74,0x77,0x65, - 0x65,0x6e,0x20,0x6d,0x75,0x6c,0x74,0x69, - 0x70,0x6c,0x65,0x20,0x63,0x68,0x75,0x6e, - 0x6b,0x73,0x21 }; /* end raw_eth_pkt */ - - return DetectContentLongPatternMatchTest(raw_eth_pkt, (uint16_t)sizeof(raw_eth_pkt), - sig, sid); -} - -/** - * \test Check if we match a normal pattern (not splitted) - */ -int DetectContentLongPatternMatchTest01() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"Hi, this is a big test\"; sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -/** - * \test Check if we match a splitted pattern - */ -int DetectContentLongPatternMatchTest02() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"Hi, this is a big test to check content matches of" - " splitted patterns between multiple chunks!\"; sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -/** - * \test Check that we don't match the signature if one of the splitted - * chunks doesn't match the packet - */ -int DetectContentLongPatternMatchTest03() -{ - /** The last chunk of the content should not match */ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"Hi, this is a big test to check content matches of" - " splitted patterns between multiple splitted chunks!\"; sid:1;)"; - return (DetectContentLongPatternMatchTestWrp(sig, 1) == 0) ? 1: 0; -} - -/** - * \test Check if we match multiple content (not splitted) - */ -int DetectContentLongPatternMatchTest04() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; " - " content:\"Hi, this is\"; depth:15 ;content:\"a big test\"; " - " within:15; content:\"to check content matches of\"; " - " within:30; content:\"splitted patterns\"; distance:1; " - " within:30; " - " sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -/** - * \test Check that we match packets with multiple chunks and not chunks - * Here we should specify only contents that fit in 32 bytes - * Each of them with their modifier values - */ -int DetectContentLongPatternMatchTest05() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; " - " content:\"Hi, this is a big\"; depth:17; " - " isdataat:30, relative; " - " content:\"test\"; within: 5; distance:1; " - " isdataat:15, relative; " - " content:\"of splitted\"; within:37; distance:15; " - " isdataat:20,relative; " - " content:\"patterns\"; within:9; distance:1; " - " isdataat:10, relative; " - " sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -/** - * \test Check that we match packets with multiple chunks and not chunks - * Here we should specify contents that fit and contents that must be splitted - * Each of them with their modifier values - */ -int DetectContentLongPatternMatchTest06() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; " - " content:\"Hi, this is a big test to check cont\"; depth:36;" - " content:\"ent matches\"; within:11; distance:0; " - " content:\"of splitted patterns between multiple\"; " - " within:38; distance:1; " - " content:\"chunks!\"; within: 8; distance:1; " - " sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -/** - * \test Check if we match contents that are in the payload - * but not in the same order as specified in the signature - */ -int DetectContentLongPatternMatchTest07() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; " - " content:\"chunks!\"; " - " content:\"content matches\"; offset:32; depth:47; " - " content:\"of splitted patterns between multiple\"; " - " content:\"Hi, this is a big\"; offset:0; depth:17; " - " sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -/** - * \test Check if we match contents that are in the payload - * but not in the same order as specified in the signature - */ -int DetectContentLongPatternMatchTest08() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; " - " content:\"ent matches\"; " - " content:\"of splitted patterns between multiple\"; " - " within:38; distance:1; " - " content:\"chunks!\"; within: 8; distance:1; " - " content:\"Hi, this is a big test to check cont\"; depth:36;" - " sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -/** - * \test Check if we match contents that are in the payload - * but not in the same order as specified in the signature - */ -int DetectContentLongPatternMatchTest09() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; " - " content:\"ent matches\"; " - " content:\"of splitted patterns between multiple\"; " - " offset:47; depth:85; " - " content:\"chunks!\"; within: 8; distance:1; " - " content:\"Hi, this is a big test to chec\"; depth:36;" - " content:\"k cont\"; distance:0; within:6;" - " sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -/** - * \test Check if we match two consecutive simple contents - */ -int DetectContentLongPatternMatchTest10() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; " - " content:\"Hi, this is a big test to check \"; " - " content:\"con\"; " - " sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -/** - * \test Check if we match two contents of length 1 - */ -int DetectContentLongPatternMatchTest11() -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; " - " content:\"H\"; " - " content:\"i\"; " - " sid:1;)"; - return DetectContentLongPatternMatchTestWrp(sig, 1); -} - -int DetectContentParseTest09(void) -{ - int result = 0; - DetectContentData *cd = NULL; - char *teststring = "!\"boo\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (cd->flags & DETECT_CONTENT_NEGATED) - result = 1; - - DetectContentFree(cd); - } - - return result; -} - -int DetectContentParseTest10(void) -{ - int result = 0; - DetectContentData *cd = NULL; - char *teststring = "!\"boo\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (cd->flags & DETECT_CONTENT_NEGATED) - result = 1; - - DetectContentFree(cd); - } - return result; -} - -int DetectContentParseNegTest11(void) -{ - int result = 0; - DetectContentData *cd = NULL; - char *teststring = "\"boo\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (!(cd->flags & DETECT_CONTENT_NEGATED)) - result = 1; - - DetectContentFree(cd); - } - return result; -} - -int DetectContentParseNegTest12(void) -{ - int result = 0; - DetectContentData *cd = NULL; - char *teststring = "\"boo\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (!(cd->flags & DETECT_CONTENT_NEGATED)) - result = 1; - - DetectContentFree(cd); - } - return result; -} - -int DetectContentParseNegTest13(void) -{ - int result = 0; - DetectContentData *cd = NULL; - char *teststring = "!\"boo\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (cd->flags & DETECT_CONTENT_NEGATED) - result = 1; - - DetectContentFree(cd); - } - return result; -} - -int DetectContentParseNegTest14(void) -{ - int result = 0; - DetectContentData *cd = NULL; - char *teststring = " \"!boo\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (!(cd->flags & DETECT_CONTENT_NEGATED)) - result = 1; - - DetectContentFree(cd); - } - return result; -} - -int DetectContentParseNegTest15(void) -{ - int result = 0; - DetectContentData *cd = NULL; - char *teststring = " !\"boo\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - if (cd->flags & DETECT_CONTENT_NEGATED) - result = 1; - - DetectContentFree(cd); - } - return result; -} - -int DetectContentParseNegTest16(void) -{ - int result = 0; - DetectContentData *cd = NULL; - char *teststring = " \"boo\""; - - cd = DetectContentParse(teststring); - if (cd != NULL) { - result = (cd->content_len == 3 && memcmp(cd->content,"boo",3) == 0); - DetectContentFree(cd); - } - return result; -} - -/** - * \test Test cases where if within specified is < content lenggth we invalidate - * the sig. - */ -int DetectContentParseTest17(void) -{ - int result = 0; - char *sigstr = "alert tcp any any -> any any (msg:\"Dummy\"; " - "content:\"one\"; content:\"two\"; within:2; sid:1;)"; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->sig_list = SigInit(de_ctx, sigstr); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - -end: - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Test content for dce sig. - */ -int DetectContentParseTest18(void) -{ - Signature *s = SigAlloc(); - int result = 1; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - result = 0; - goto end; - } - - s->alproto = ALPROTO_DCERPC; - - result &= (DetectContentSetup(de_ctx, s, "\"one\"") == 0); - result &= (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - - SigFree(s); - - s = SigAlloc(); - if (s == NULL) - return 0; - - result &= (DetectContentSetup(de_ctx, s, "\"one\"") == 0); - result &= (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - - end: - SigFree(s); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ - -int DetectContentParseTest19(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - DetectContentData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing dce iface, stub_data with content\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf ("failed dce iface, stub_data with content "); - result = 0; - goto end; - } - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_CONTENT); - result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL); - data = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED || - result == 0) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing dce iface, stub_data with contents & distance, within\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; content:\"two\"; within:10; sid:1;)"); - if (s->next == NULL) { - printf("failed dce iface, stub_data with content & distance, within"); - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_CONTENT); - result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL); - data = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED || - result == 0) { - result = 0; - goto end; - } - result &= (data->within == 10); -/* - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing dce iface, stub_data with contents & offset, depth\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; offset:5; depth:9; " - "content:\"two\"; within:10; sid:1;)"); - if (s->next == NULL) { - printf ("failed dce iface, stub_data with contents & offset, depth"); - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_CONTENT); - result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL); - data = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED || - result == 0) { - result = 0; - goto end; - } - result &= (data->offset == 5 && data->depth == 9); - data = (DetectContentData *)s->sm_lists[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED || - result == 0) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing dce iface, stub with contents, distance\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "content:\"two\"; distance:2; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_CONTENT); - result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL); - data = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED || - result == 0) { - result = 0; - goto end; - } - result &= (data->distance == 2); -*/ - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing dce iface, stub with contents, distance, within\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "content:\"two\"; within:10; distance:2; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_CONTENT); - result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL); - data = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED || - result == 0) { - result = 0; - goto end; - } - result &= (data->within == 10 && data->distance == 2); -/* - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing dce iface, stub_data with content, offset\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; offset:10; sid:1;)"); - if (s->next == NULL) { - printf ("Failed dce iface, stub_data with content, offset "); - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_CONTENT); - result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL); - data = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED || - result == 0) { - result = 0; - goto end; - } - result &= (data->offset == 10); - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing dce iface, stub_data with content, depth\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; depth:10; sid:1;)"); - if (s->next == NULL) { - printf ("failed dce iface, stub_data with content, depth"); - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_CONTENT); - result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL); - data = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED || - result == 0) { - result = 0; - goto end; - } - result &= (data->depth == 10); - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing dce iface, stub_data with content, offset, depth\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; offset:10; depth:3; sid:1;)"); - if (s->next == NULL) { - printf("failed dce iface, stub_data with content, offset, depth"); - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_CONTENT); - result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL); - data = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED || - result == 0) { - result = 0; - goto end; - } - result &= (data->offset == 10 && data->depth == 13); -*/ - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing content\"; " - "content:\"one\"; sid:1;)"); - if (s->next == NULL) { - printf ("failed testing content"); - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] != NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DetectContentParseTest20(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest21(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"boo; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:boo\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectContentData *cd = 0; - Signature *s = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content: !\"boo\"; sid:238012;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL: "); - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL || s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx == NULL) { - printf("de_ctx->pmatch_tail == NULL || de_ctx->pmatch_tail->ctx == NULL: "); - result = 0; - goto end; - } - - cd = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - result = (strncmp("boo", (char *)cd->content, cd->content_len) == 0); - -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"|\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"|af\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"af|\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest28(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"|af|\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest29(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"aast|\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest30(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"aast|af\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest31(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"aast|af|\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest32(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"|af|asdf\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest33(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"|af|af|\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest34(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"|af|af|af\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectContentParseTest35(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"|af|af|af|\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test: file_data - */ -static int DetectContentParseTest36(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; file_data; content:\"abc\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("content still in PMATCH list: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("content not in FILEDATA list: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test: file_data - */ -static int DetectContentParseTest37(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; file_data; content:\"abc\"; content:\"def\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("content still in PMATCH list: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("content not in FILEDATA list: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test: file_data - */ -static int DetectContentParseTest38(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; file_data; content:\"abc\"; content:\"def\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("content still in PMATCH list: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("content not in FILEDATA list: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -static int SigTestPositiveTestContent(char *rule, uint8_t *buf) -{ - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, rule); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) != 1) { - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Parsing test: file_data, within relative to file_data - */ -static int DetectContentParseTest39(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; file_data; content:\"abc\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("content still in PMATCH list: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("content not in FILEDATA list: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test: file_data, distance relative to file_data - */ -static int DetectContentParseTest40(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; file_data; content:\"abc\"; distance:3; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("content still in PMATCH list: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("content not in FILEDATA list: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectContentParseTest41(void) -{ - int result = 1; - DetectContentData *cd = NULL; - int patlen = 257; - char *teststring = SCMalloc(sizeof(char) * (patlen + 1)); - if (unlikely(teststring == NULL)) - return 0; - int idx = 0; - teststring[idx++] = '\"'; - for (int i = 0; i < (patlen - 2); idx++, i++) { - teststring[idx] = 'a'; - } - teststring[idx++] = '\"'; - teststring[idx++] = '\0'; - - cd = DetectContentParse(teststring); - if (cd == NULL) { - SCLogDebug("expected not NULL"); - result = 0; - } - - SCFree(teststring); - DetectContentFree(cd); - return result; -} - -/** - * Tests that content lengths > 255 are supported. - */ -int DetectContentParseTest42(void) -{ - int result = 1; - DetectContentData *cd = NULL; - int patlen = 258; - char *teststring = SCMalloc(sizeof(char) * (patlen + 1)); - if (unlikely(teststring == NULL)) - return 0; - int idx = 0; - teststring[idx++] = '\"'; - for (int i = 0; i < (patlen - 2); idx++, i++) { - teststring[idx] = 'a'; - } - teststring[idx++] = '\"'; - teststring[idx++] = '\0'; - - cd = DetectContentParse(teststring); - if (cd == NULL) { - SCLogDebug("expected not NULL"); - result = 0; - } - - SCFree(teststring); - DetectContentFree(cd); - return result; -} - -int DetectContentParseTest43(void) -{ - int result = 1; - DetectContentData *cd = NULL; - int patlen = 260; - char *teststring = SCMalloc(sizeof(char) * (patlen + 1)); - if (unlikely(teststring == NULL)) - return 0; - int idx = 0; - teststring[idx++] = '\"'; - teststring[idx++] = '|'; - teststring[idx++] = '4'; - teststring[idx++] = '6'; - teststring[idx++] = '|'; - for (int i = 0; i < (patlen - 6); idx++, i++) { - teststring[idx] = 'a'; - } - teststring[idx++] = '\"'; - teststring[idx++] = '\0'; - - cd = DetectContentParse(teststring); - if (cd == NULL) { - SCLogDebug("expected not NULL"); - result = 0; - } - - SCFree(teststring); - DetectContentFree(cd); - return result; -} - -/** - * Tests that content lengths > 255 are supported. - */ -int DetectContentParseTest44(void) -{ - int result = 1; - DetectContentData *cd = NULL; - int patlen = 261; - char *teststring = SCMalloc(sizeof(char) * (patlen + 1)); - if (unlikely(teststring == NULL)) - return 0; - int idx = 0; - teststring[idx++] = '\"'; - teststring[idx++] = '|'; - teststring[idx++] = '4'; - teststring[idx++] = '6'; - teststring[idx++] = '|'; - for (int i = 0; i < (patlen - 6); idx++, i++) { - teststring[idx] = 'a'; - } - teststring[idx++] = '\"'; - teststring[idx++] = '\0'; - - cd = DetectContentParse(teststring); - if (cd == NULL) { - SCLogDebug("expected not NULL"); - result = 0; - } - - SCFree(teststring); - DetectContentFree(cd); - return result; -} - -static int SigTestNegativeTestContent(char *rule, uint8_t *buf) -{ - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, rule); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) != 0) { - goto end; - } - - result = 1; -end: - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test A positive test that checks that the content string doesn't contain - * the negated content - */ -static int SigTest41TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!\"GES\"; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n"); -} - -/** - * \test A positive test that checks that the content string doesn't contain - * the negated content within the specified depth - */ -static int SigTest42TestNegatedContent(void) -{ // 01 5 10 15 20 24 - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!\"twentythree\"; depth:22; offset:35; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A negative test that checks that the content string doesn't contain - * the negated content within the specified depth, and also after the - * specified offset. Since the content is there, the match fails. - * - * Match is at offset:23, depth:34 - */ -static int SigTest43TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (content:!\"twentythree\"; depth:34; offset:23; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A negative test that checks that the content string doesn't contain - * the negated content after the specified offset and within the specified - * depth. - */ -static int SigTest44TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!\"twentythree\"; offset:40; depth:35; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A positive test that uses a combination of content string with negated - * content string - */ -static int SigTest45TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; depth:5; content:!\"twentythree\"; depth:23; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A negative test that uses a combination of content string with negated - * content string, with we receiving a failure for 'onee' itself. - */ -static int SigTest46TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"onee\"; content:!\"twentythree\"; depth:23; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A negative test that uses a combination of content string with negated - * content string, with we receiving a failure of first content's offset - * condition - */ -static int SigTest47TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; offset:5; content:!\"twentythree\"; depth:23; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A positive test that checks that we don't have a negated content within - * the specified length from the previous content match. - */ -static int SigTest48TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET\"; content:!\"GES\"; within:26; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n"); -} - -/** - * \test A negative test that checks the combined use of content and negated - * content with the use of within - */ -static int SigTest49TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET\"; content:!\"Host\"; within:26; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n"); -} - -/** - * \test A positive test that checks the combined use of content and negated - * content with the use of distance - */ -static int SigTest50TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET\"; content:!\"GES\"; distance:25; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n"); -} - -/** - * \test A negative test that checks the combined use of content and negated - * content with the use of distance - * - * First GET at offset 0 - * First Host at offset 21 - */ -static int SigTest51TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"GET\"; content:!\"Host\"; distance:17; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\nHost: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n"); -} - -/** - * \test A negative test that checks the combined use of content and negated - * content, with the content not being present - */ -static int SigTest52TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GES\"; content:!\"BOO\"; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n"); -} - -/** - * \test A negative test that checks the combined use of content and negated - * content, in the presence of within - */ -static int SigTest53TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A positive test that checks the combined use of content and negated - * content, in the presence of within - */ -static int SigTest54TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; within:20; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A negative test that checks the use of negated content along with - * the presence of depth - */ -static int SigTest55TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!\"one\"; depth:5; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A positive test that checks the combined use of 2 contents in the - * presence of within - */ -static int SigTest56TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:\"fourty\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A negative test that checks the combined use of content and negated - * content, in the presence of within - */ -static int SigTest57TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A positive test that checks the combined use of content and negated - * content, in the presence of distance - */ -static int SigTest58TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; distance:57; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** - * \test A negative test that checks the combined use of content and negated - * content, in the presence of distance - */ -static int SigTest59TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; distance:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest60TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!\"one\"; content:\"fourty\"; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest61TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; within:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** \test Test negation in combination with within and depth - * - * Match of "one" at offset:0, depth:3 - * Match of "fourty" at offset:46, depth:52 - * - * This signature should not match for the test to pass. - */ -static int SigTest62TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; within:49; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest63TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; depth:10; content:!\"fourty\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest64TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; within:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** \test Test negation in combination with within and depth - * - * Match of "one" at offset:0, depth:3 - * Match of "fourty" at offset:46, depth:52 - * - * This signature should not match for the test to pass. - */ -static int SigTest65TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; distance:0; within:49; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest66TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; within:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest67TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"four\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest68TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:\"nine\"; offset:8; content:!\"fourty\"; within:28; content:\"fiftysix\"; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest69TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:\"nine\"; offset:8; content:!\"fourty\"; within:48; content:\"fiftysix\"; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest70TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; content:!\"fourty\"; within:52; distance:45 sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -/** \test within and distance */ -static int SigTest71TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; content:!\"fourty\"; within:40; distance:43; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest72TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; content:!\"fourty\"; within:49; distance:43; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest73TestNegatedContent(void) -{ - return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; depth:5; content:!\"twentythree\"; depth:35; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix"); -} - -static int SigTest74TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"USER\"; content:!\"PASS\"; sid:1;)", (uint8_t *)"USER apple"); -} - -static int SigTest75TestNegatedContent(void) -{ - return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"USER\"; content:\"!PASS\"; sid:1;)", (uint8_t *)"USER !PASS"); -} - -static int SigTest76TestBug134(void) -{ - uint8_t *buf = (uint8_t *)"test detect ${IFS} in traffic"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - Flow f; - - memset(&f, 0, sizeof(Flow)); - FLOW_INITIALIZE(&f); - - p->dp = 515; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flow = &f; - p->flags |= PKT_HAS_FLOW; - - char sig[] = "alert tcp any any -> any 515 " - "(msg:\"detect IFS\"; flow:to_server,established; content:\"${IFS}\";" - " depth:50; offset:0; sid:900091; rev:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - - FLOW_DESTROY(&f); - return result; -} - -static int SigTest77TestBug139(void) -{ - uint8_t buf[] = { - 0x12, 0x23, 0x34, 0x35, 0x52, 0x52, 0x24, 0x42, 0x22, 0x24, - 0x52, 0x24, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x34 }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_UDP); - int result = 0; - - p->dp = 53; - char sig[] = "alert udp any any -> any 53 (msg:\"dns testing\";" - " content:\"|00 00|\"; depth:5; offset:13; sid:9436601;" - " rev:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int DetectLongContentTestCommon(char *sig, uint32_t sid) -{ - /* Packet with 512 A's in it for testing long content. */ - static uint8_t pkt[739] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, - 0x02, 0xd5, 0x4a, 0x18, 0x40, 0x00, 0x40, 0x06, - 0xd7, 0xd6, 0x0a, 0x10, 0x01, 0x0b, 0x0a, 0x10, - 0x01, 0x0a, 0xdb, 0x36, 0x00, 0x50, 0xca, 0xc5, - 0xcc, 0xd1, 0x95, 0x77, 0x0f, 0x7d, 0x80, 0x18, - 0x00, 0xe5, 0x77, 0x9d, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x1d, 0xe0, 0x86, 0xc6, 0xfc, 0x73, - 0x49, 0xf3, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x2f, - 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, - 0x31, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x63, - 0x75, 0x72, 0x6c, 0x2f, 0x37, 0x2e, 0x33, 0x37, - 0x2e, 0x30, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, - 0x3a, 0x20, 0x31, 0x30, 0x2e, 0x31, 0x36, 0x2e, - 0x31, 0x2e, 0x31, 0x30, 0x0d, 0x0a, 0x41, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, - 0x2a, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x3a, 0x20, 0x35, 0x32, 0x38, 0x0d, 0x0a, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, - 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2f, 0x78, 0x2d, 0x77, 0x77, 0x77, 0x2d, - 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x75, 0x72, 0x6c, - 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x0d, - 0x0a, 0x0d, 0x0a, 0x58, 0x58, 0x58, 0x58, 0x58, - 0x58, 0x58, 0x58, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x58, 0x58, 0x58, 0x58, 0x58, - 0x58, 0x58, 0x58 - }; - - return DetectContentLongPatternMatchTest(pkt, (uint16_t)sizeof(pkt), sig, - sid); -} - -static int DetectLongContentTest1(void) -{ - /* Signature with 256 A's. */ - char *sig = "alert tcp any any -> any any (msg:\"Test Rule\"; content:\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"; sid:1;)"; - - return DetectLongContentTestCommon(sig, 1); -} - -static int DetectLongContentTest2(void) -{ - /* Signature with 512 A's. */ - char *sig = "alert tcp any any -> any any (msg:\"Test Rule\"; content:\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"; sid:1;)"; - - return DetectLongContentTestCommon(sig, 1); -} - -static int DetectLongContentTest3(void) -{ - /* Signature with 513 A's. */ - char *sig = "alert tcp any any -> any any (msg:\"Test Rule\"; content:\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"; sid:1;)"; - - return !DetectLongContentTestCommon(sig, 1); -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectContent - */ -void DetectContentRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectContentParseTest01", DetectContentParseTest01, 1); - UtRegisterTest("DetectContentParseTest02", DetectContentParseTest02, 1); - UtRegisterTest("DetectContentParseTest03", DetectContentParseTest03, 1); - UtRegisterTest("DetectContentParseTest04", DetectContentParseTest04, 1); - UtRegisterTest("DetectContentParseTest05", DetectContentParseTest05, 1); - UtRegisterTest("DetectContentParseTest06", DetectContentParseTest06, 1); - UtRegisterTest("DetectContentParseTest07", DetectContentParseTest07, 1); - UtRegisterTest("DetectContentParseTest08", DetectContentParseTest08, 1); - UtRegisterTest("DetectContentParseTest09", DetectContentParseTest09, 1); - UtRegisterTest("DetectContentParseTest10", DetectContentParseTest10, 1); - UtRegisterTest("DetectContentParseNegTest11", DetectContentParseNegTest11, 1); - UtRegisterTest("DetectContentParseNegTest12", DetectContentParseNegTest12, 1); - UtRegisterTest("DetectContentParseNegTest13", DetectContentParseNegTest13, 1); - UtRegisterTest("DetectContentParseNegTest14", DetectContentParseNegTest14, 1); - UtRegisterTest("DetectContentParseNegTest15", DetectContentParseNegTest15, 1); - UtRegisterTest("DetectContentParseNegTest16", DetectContentParseNegTest16, 1); - UtRegisterTest("DetectContentParseTest17", DetectContentParseTest17, 1); - UtRegisterTest("DetectContentParseTest18", DetectContentParseTest18, 1); - UtRegisterTest("DetectContentParseTest19", DetectContentParseTest19, 1); - UtRegisterTest("DetectContentParseTest20", DetectContentParseTest20, 1); - UtRegisterTest("DetectContentParseTest21", DetectContentParseTest21, 1); - UtRegisterTest("DetectContentParseTest22", DetectContentParseTest22, 1); - UtRegisterTest("DetectContentParseTest23", DetectContentParseTest23, 1); - UtRegisterTest("DetectContentParseTest24", DetectContentParseTest24, 1); - UtRegisterTest("DetectContentParseTest25", DetectContentParseTest25, 1); - UtRegisterTest("DetectContentParseTest26", DetectContentParseTest26, 1); - UtRegisterTest("DetectContentParseTest27", DetectContentParseTest27, 1); - UtRegisterTest("DetectContentParseTest28", DetectContentParseTest28, 1); - UtRegisterTest("DetectContentParseTest29", DetectContentParseTest29, 1); - UtRegisterTest("DetectContentParseTest30", DetectContentParseTest30, 1); - UtRegisterTest("DetectContentParseTest31", DetectContentParseTest31, 1); - UtRegisterTest("DetectContentParseTest32", DetectContentParseTest32, 1); - UtRegisterTest("DetectContentParseTest33", DetectContentParseTest33, 1); - UtRegisterTest("DetectContentParseTest34", DetectContentParseTest34, 1); - UtRegisterTest("DetectContentParseTest35", DetectContentParseTest35, 1); - UtRegisterTest("DetectContentParseTest36", DetectContentParseTest36, 1); - UtRegisterTest("DetectContentParseTest37", DetectContentParseTest37, 1); - UtRegisterTest("DetectContentParseTest38", DetectContentParseTest38, 1); - UtRegisterTest("DetectContentParseTest39", DetectContentParseTest39, 1); - UtRegisterTest("DetectContentParseTest40", DetectContentParseTest40, 1); - UtRegisterTest("DetectContentParseTest41", DetectContentParseTest41, 1); - UtRegisterTest("DetectContentParseTest42", DetectContentParseTest42, 1); - UtRegisterTest("DetectContentParseTest43", DetectContentParseTest43, 1); - UtRegisterTest("DetectContentParseTest44", DetectContentParseTest44, 1); - - /* The reals */ - UtRegisterTest("DetectContentLongPatternMatchTest01", DetectContentLongPatternMatchTest01, 1); - UtRegisterTest("DetectContentLongPatternMatchTest02", DetectContentLongPatternMatchTest02, 1); - UtRegisterTest("DetectContentLongPatternMatchTest03", DetectContentLongPatternMatchTest03, 1); - UtRegisterTest("DetectContentLongPatternMatchTest04", DetectContentLongPatternMatchTest04, 1); - UtRegisterTest("DetectContentLongPatternMatchTest05", DetectContentLongPatternMatchTest05, 1); - UtRegisterTest("DetectContentLongPatternMatchTest06", DetectContentLongPatternMatchTest06, 1); - UtRegisterTest("DetectContentLongPatternMatchTest07", DetectContentLongPatternMatchTest07, 1); - UtRegisterTest("DetectContentLongPatternMatchTest08", DetectContentLongPatternMatchTest08, 1); - UtRegisterTest("DetectContentLongPatternMatchTest09", DetectContentLongPatternMatchTest09, 1); - UtRegisterTest("DetectContentLongPatternMatchTest10", DetectContentLongPatternMatchTest10, 1); - UtRegisterTest("DetectContentLongPatternMatchTest11", DetectContentLongPatternMatchTest11, 1); - - /* Negated content tests */ - UtRegisterTest("SigTest41TestNegatedContent", SigTest41TestNegatedContent, 1); - UtRegisterTest("SigTest42TestNegatedContent", SigTest42TestNegatedContent, 1); - UtRegisterTest("SigTest43TestNegatedContent", SigTest43TestNegatedContent, 1); - UtRegisterTest("SigTest44TestNegatedContent", SigTest44TestNegatedContent, 1); - UtRegisterTest("SigTest45TestNegatedContent", SigTest45TestNegatedContent, 1); - UtRegisterTest("SigTest46TestNegatedContent", SigTest46TestNegatedContent, 1); - UtRegisterTest("SigTest47TestNegatedContent", SigTest47TestNegatedContent, 1); - UtRegisterTest("SigTest48TestNegatedContent", SigTest48TestNegatedContent, 1); - UtRegisterTest("SigTest49TestNegatedContent", SigTest49TestNegatedContent, 1); - UtRegisterTest("SigTest50TestNegatedContent", SigTest50TestNegatedContent, 1); - UtRegisterTest("SigTest51TestNegatedContent", SigTest51TestNegatedContent, 1); - UtRegisterTest("SigTest52TestNegatedContent", SigTest52TestNegatedContent, 1); - UtRegisterTest("SigTest53TestNegatedContent", SigTest53TestNegatedContent, 1); - UtRegisterTest("SigTest54TestNegatedContent", SigTest54TestNegatedContent, 1); - UtRegisterTest("SigTest55TestNegatedContent", SigTest55TestNegatedContent, 1); - UtRegisterTest("SigTest56TestNegatedContent", SigTest56TestNegatedContent, 1); - UtRegisterTest("SigTest57TestNegatedContent", SigTest57TestNegatedContent, 1); - UtRegisterTest("SigTest58TestNegatedContent", SigTest58TestNegatedContent, 1); - UtRegisterTest("SigTest59TestNegatedContent", SigTest59TestNegatedContent, 1); - UtRegisterTest("SigTest60TestNegatedContent", SigTest60TestNegatedContent, 1); - UtRegisterTest("SigTest61TestNegatedContent", SigTest61TestNegatedContent, 1); - UtRegisterTest("SigTest62TestNegatedContent", SigTest62TestNegatedContent, 1); - UtRegisterTest("SigTest63TestNegatedContent", SigTest63TestNegatedContent, 1); - UtRegisterTest("SigTest64TestNegatedContent", SigTest64TestNegatedContent, 1); - UtRegisterTest("SigTest65TestNegatedContent", SigTest65TestNegatedContent, 1); - UtRegisterTest("SigTest66TestNegatedContent", SigTest66TestNegatedContent, 1); - UtRegisterTest("SigTest67TestNegatedContent", SigTest67TestNegatedContent, 1); - UtRegisterTest("SigTest68TestNegatedContent", SigTest68TestNegatedContent, 1); - UtRegisterTest("SigTest69TestNegatedContent", SigTest69TestNegatedContent, 1); - UtRegisterTest("SigTest70TestNegatedContent", SigTest70TestNegatedContent, 1); - UtRegisterTest("SigTest71TestNegatedContent", SigTest71TestNegatedContent, 1); - UtRegisterTest("SigTest72TestNegatedContent", SigTest72TestNegatedContent, 1); - UtRegisterTest("SigTest73TestNegatedContent", SigTest73TestNegatedContent, 1); - UtRegisterTest("SigTest74TestNegatedContent", SigTest74TestNegatedContent, 1); - UtRegisterTest("SigTest75TestNegatedContent", SigTest75TestNegatedContent, 1); - - UtRegisterTest("SigTest76TestBug134", SigTest76TestBug134, 1); - UtRegisterTest("SigTest77TestBug139", SigTest77TestBug139, 1); - - UtRegisterTest("DetectLongContentTest1", DetectLongContentTest1, 1); - UtRegisterTest("DetectLongContentTest2", DetectLongContentTest2, 1); - UtRegisterTest("DetectLongContentTest3", DetectLongContentTest3, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-content.h b/framework/src/suricata/src/detect-content.h deleted file mode 100644 index b2e0f969..00000000 --- a/framework/src/suricata/src/detect-content.h +++ /dev/null @@ -1,102 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_CONTENT_H__ -#define __DETECT_CONTENT_H__ - -/* Flags affecting this content */ - -#define DETECT_CONTENT_NOCASE (1) -#define DETECT_CONTENT_DISTANCE (1 << 1) -#define DETECT_CONTENT_WITHIN (1 << 2) -#define DETECT_CONTENT_OFFSET (1 << 3) -#define DETECT_CONTENT_DEPTH (1 << 4) -#define DETECT_CONTENT_FAST_PATTERN (1 << 5) -#define DETECT_CONTENT_FAST_PATTERN_ONLY (1 << 6) -#define DETECT_CONTENT_FAST_PATTERN_CHOP (1 << 7) -/** content applies to a "raw"/undecoded field if applicable */ -#define DETECT_CONTENT_RAWBYTES (1 << 8) -/** content is negated */ -#define DETECT_CONTENT_NEGATED (1 << 9) - -/** a relative match to this content is next, used in matching phase */ -#define DETECT_CONTENT_RELATIVE_NEXT (1 << 10) - -/* BE - byte extract */ -#define DETECT_CONTENT_OFFSET_BE (1 << 11) -#define DETECT_CONTENT_DEPTH_BE (1 << 12) -#define DETECT_CONTENT_DISTANCE_BE (1 << 13) -#define DETECT_CONTENT_WITHIN_BE (1 << 14) - -/* replace data */ -#define DETECT_CONTENT_REPLACE (1 << 15) -/* this flag is set during the staging phase. It indicates that a content - * has been added to the mpm phase and requires no further inspection inside - * the inspection phase */ -#define DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED (1 << 16) - -#define DETECT_CONTENT_IS_SINGLE(c) (!( ((c)->flags & DETECT_CONTENT_DISTANCE) || \ - ((c)->flags & DETECT_CONTENT_WITHIN) || \ - ((c)->flags & DETECT_CONTENT_RELATIVE_NEXT) || \ - ((c)->flags & DETECT_CONTENT_DEPTH) || \ - ((c)->flags & DETECT_CONTENT_OFFSET) )) - -#include "util-spm-bm.h" - -typedef struct DetectContentData_ { - uint8_t *content; - uint16_t content_len; - uint16_t replace_len; - /* for chopped fast pattern, the length */ - uint16_t fp_chop_len; - /* would want to move PatIntId here and flags down to remove the padding - * gap, but I think the first four members was used as a template for - * casting. \todo check this and fix it if posssible */ - uint32_t flags; - PatIntId id; - uint16_t depth; - uint16_t offset; - /* for chopped fast pattern, the offset */ - uint16_t fp_chop_offset; - int32_t distance; - int32_t within; - /* Boyer Moore context (for spm search) */ - BmCtx *bm_ctx; - /* pointer to replacement data */ - uint8_t *replace; -} DetectContentData; - -/* prototypes */ -void DetectContentRegister (void); -uint32_t DetectContentMaxId(DetectEngineCtx *); -DetectContentData *DetectContentParse (char *contentstr); -int DetectContentDataParse(const char *keyword, const char *contentstr, - uint8_t **pstr, uint16_t *plen, uint32_t *flags); -DetectContentData *DetectContentParseEncloseQuotes(char *); - -int DetectContentSetup(DetectEngineCtx *de_ctx, Signature *s, char *contentstr); -void DetectContentPrint(DetectContentData *); - -void DetectContentFree(void *); - -#endif /* __DETECT_CONTENT_H__ */ diff --git a/framework/src/suricata/src/detect-csum.c b/framework/src/suricata/src/detect-csum.c deleted file mode 100644 index 2cf5b4ce..00000000 --- a/framework/src/suricata/src/detect-csum.c +++ /dev/null @@ -1,1647 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements checksum keyword. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-csum.h" - -#include "util-unittest.h" -#include "util-debug.h" - -#include "pkt-var.h" -#include "host.h" -#include "util-profiling.h" - -/* prototypes for the "ipv4-csum" rule keyword */ -int DetectIPV4CsumMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectIPV4CsumSetup(DetectEngineCtx *, Signature *, char *); -void DetectIPV4CsumFree(void *); - -/* prototypes for the "tcpv4-csum" rule keyword */ -int DetectTCPV4CsumMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectTCPV4CsumSetup(DetectEngineCtx *, Signature *, char *); -void DetectTCPV4CsumFree(void *); - -/* prototypes for the "tcpv6-csum" rule keyword */ -int DetectTCPV6CsumMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectTCPV6CsumSetup(DetectEngineCtx *, Signature *, char *); -void DetectTCPV6CsumFree(void *); - -/* prototypes for the "udpv4-csum" rule keyword */ -int DetectUDPV4CsumMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectUDPV4CsumSetup(DetectEngineCtx *, Signature *, char *); -void DetectUDPV4CsumFree(void *); - -/* prototypes for the "udpv6-csum" rule keyword */ -int DetectUDPV6CsumMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectUDPV6CsumSetup(DetectEngineCtx *, Signature *, char *); -void DetectUDPV6CsumFree(void *); - -/* prototypes for the "icmpv4-csum" rule keyword */ -int DetectICMPV4CsumMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectICMPV4CsumSetup(DetectEngineCtx *, Signature *, char *); -void DetectICMPV4CsumFree(void *); - -/* prototypes for the "icmpv6-csum" rule keyword */ -int DetectICMPV6CsumMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectICMPV6CsumSetup(DetectEngineCtx *, Signature *, char *); -void DetectICMPV6CsumFree(void *); - -void DetectCsumRegisterTests(void); - -/** - * \brief Registers handlers for all the checksum keywords. The checksum - * keywords that are registered are ipv4-sum, tcpv4-csum, tcpv6-csum, - * udpv4-csum, udpv6-csum, icmpv4-csum and icmpv6-csum. - * - * Each of the checksum keywords implemented here takes 2 arguments - - * "valid" or "invalid". If the rule keyword in the signature is - * specified as "valid", the Match function would return TRUE if the - * checksum for that particular packet and protocol is valid. Similarly - * for "invalid". - * - * The Setup functions takes 4 arguments - - * - * DetectEngineCtx * (de_ctx) - A pointer to the detection engine context - * Signature *(s) - Pointer to signature for the current Signature being - * parsed from the rules - * SigMatchCtx * (m) - Pointer to the head of the SigMatchs added to the - * current Signature being parsed - * char * (csum_str) - Pointer to a string holding the keyword value - * - * The Setup function returns 0 if it successfully parses the keyword - * value, and -1 otherwise. - * - * The Match function takes 5 arguments - - * - * ThreadVars * (t) - Pointer to the tv for the detection module instance - * DetectEngineThreadCtx * (det_ctx) - Pointer to the detection engine - * thread context - * Packet * (p) - Pointer to the Packet currently being handled - * Signature * (s) - Pointer to the Signature, the packet is being - * currently matched with - * SigMatchCtx * (m) - Pointer to the keyword structure from the above - * Signature, the Packet is being currently matched - * with - * - * The Match function returns 1 if the Packet contents match the keyword, - * and 0 otherwise - * - * The Free function takes a single argument - - * - * void * (ptr) - Pointer to the DetectCsumData for a keyword - */ -void DetectCsumRegister (void) -{ - sigmatch_table[DETECT_IPV4_CSUM].name = "ipv4-csum"; - sigmatch_table[DETECT_IPV4_CSUM].Match = DetectIPV4CsumMatch; - sigmatch_table[DETECT_IPV4_CSUM].Setup = DetectIPV4CsumSetup; - sigmatch_table[DETECT_IPV4_CSUM].Free = DetectIPV4CsumFree; - sigmatch_table[DETECT_IPV4_CSUM].RegisterTests = DetectCsumRegisterTests; - - sigmatch_table[DETECT_TCPV4_CSUM].name = "tcpv4-csum"; - sigmatch_table[DETECT_TCPV4_CSUM].Match = DetectTCPV4CsumMatch; - sigmatch_table[DETECT_TCPV4_CSUM].Setup = DetectTCPV4CsumSetup; - sigmatch_table[DETECT_TCPV4_CSUM].Free = DetectTCPV4CsumFree; - sigmatch_table[DETECT_TCPV4_CSUM].RegisterTests = NULL; - - sigmatch_table[DETECT_TCPV6_CSUM].name = "tcpv6-csum"; - sigmatch_table[DETECT_TCPV6_CSUM].Match = DetectTCPV6CsumMatch; - sigmatch_table[DETECT_TCPV6_CSUM].Setup = DetectTCPV6CsumSetup; - sigmatch_table[DETECT_TCPV6_CSUM].Free = DetectTCPV6CsumFree; - sigmatch_table[DETECT_TCPV6_CSUM].RegisterTests = NULL; - - sigmatch_table[DETECT_UDPV4_CSUM].name = "udpv4-csum"; - sigmatch_table[DETECT_UDPV4_CSUM].Match = DetectUDPV4CsumMatch; - sigmatch_table[DETECT_UDPV4_CSUM].Setup = DetectUDPV4CsumSetup; - sigmatch_table[DETECT_UDPV4_CSUM].Free = DetectUDPV4CsumFree; - sigmatch_table[DETECT_UDPV4_CSUM].RegisterTests = NULL; - - sigmatch_table[DETECT_UDPV6_CSUM].name = "udpv6-csum"; - sigmatch_table[DETECT_UDPV6_CSUM].Match = DetectUDPV6CsumMatch; - sigmatch_table[DETECT_UDPV6_CSUM].Setup = DetectUDPV6CsumSetup; - sigmatch_table[DETECT_UDPV6_CSUM].Free = DetectUDPV6CsumFree; - sigmatch_table[DETECT_UDPV6_CSUM].RegisterTests = NULL; - - sigmatch_table[DETECT_ICMPV4_CSUM].name = "icmpv4-csum"; - sigmatch_table[DETECT_ICMPV4_CSUM].Match = DetectICMPV4CsumMatch; - sigmatch_table[DETECT_ICMPV4_CSUM].Setup = DetectICMPV4CsumSetup; - sigmatch_table[DETECT_ICMPV4_CSUM].Free = DetectICMPV4CsumFree; - sigmatch_table[DETECT_ICMPV4_CSUM].RegisterTests = NULL; - - sigmatch_table[DETECT_ICMPV6_CSUM].name = "icmpv6-csum"; - sigmatch_table[DETECT_ICMPV6_CSUM].Match = DetectICMPV6CsumMatch; - sigmatch_table[DETECT_ICMPV6_CSUM].Setup = DetectICMPV6CsumSetup; - sigmatch_table[DETECT_ICMPV6_CSUM].Free = DetectICMPV6CsumFree; - sigmatch_table[DETECT_ICMPV6_CSUM].RegisterTests = NULL; - - return; -} - -/** - * \brief Validates and parses the argument supplied with the checksum keyword. - * Accepts strings both with and without quotes, i.e. valid, \"valid\", - * invalid and \"invalid\" - * - * \param key Pointer to a const character string holding the csum keyword value - * \param cd Pointer to the DetectCsumData structure that holds the keyword - * value sent as argument - * - * \retval 1 the keyvalue has been parsed successfully - * \retval 0 error - */ -static int DetectCsumParseArg(const char *key, DetectCsumData *cd) -{ - char *str; - - if (key[0] == '\"' && key[strlen(key) - 1] == '\"') { - str = SCStrdup(key + 1); - if (unlikely(str == NULL)) { - goto error; - } - str[strlen(key) - 2] = '\0'; - } else { - str = SCStrdup(key); - if (unlikely(str == NULL)) { - goto error; - } - } - - if (strcasecmp(str, DETECT_CSUM_VALID) == 0 || - strcasecmp(str, DETECT_CSUM_INVALID) == 0) { - cd->valid = (strcasecmp(key, DETECT_CSUM_VALID) == 0); - SCFree(str); - return 1; - } - -error: - if (str != NULL) - SCFree(str); - return 0; -} - -/** - * \brief Checks if the packet sent as the argument, has a valid or invalid - * ipv4 checksum, based on whether ipv4-csum option for this rule - * has been supplied with "valid" or "invalid" argument - * - * \param t Pointer to the tv for this detection module instance - * \param det_ctx Pointer to the detection engine thread context - * \param p Pointer to the Packet currently being matched - * \param s Pointer to the Signature, the packet is being currently - * matched with - * \param m Pointer to the keyword_structure(SigMatch) from the above - * Signature, the Packet is being currently matched with - * - * \retval 1 if the Packet contents match the keyword option; 0 otherwise - */ -int DetectIPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectCsumData *cd = (const DetectCsumData *)ctx; - - if (p->ip4h == NULL || PKT_IS_PSEUDOPKT(p)) - return 0; - - if (p->flags & PKT_IGNORE_CHECKSUM) { - return cd->valid; - } - - if (p->level3_comp_csum == -1) - p->level3_comp_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h, - IPV4_GET_HLEN(p)); - - if (p->level3_comp_csum == p->ip4h->ip_csum && cd->valid == 1) - return 1; - else if (p->level3_comp_csum != p->ip4h->ip_csum && cd->valid == 0) - return 1; - else - return 0; -} - -/** - * \brief Creates a SigMatch for the ipv4-csum keyword being sent as argument, - * and appends it to the Signature(s). Accepts 2 values for the - * keyword - "valid" and "invalid", both with and without quotes - * - * \param de_ctx Pointer to the detection engine context - * \param s Pointer to signature for the current Signature being parsed - * from the rules - * \param csum_str Pointer to the string holding the keyword value - * - * \retval 0 on success, -1 on failure - */ -static int DetectIPV4CsumSetup(DetectEngineCtx *de_ctx, Signature *s, char *csum_str) -{ - DetectCsumData *cd = NULL; - SigMatch *sm = NULL; - - //printf("DetectCsumSetup: \'%s\'\n", csum_str); - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_IPV4_CSUM; - - if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL) - goto error; - memset(cd, 0, sizeof(DetectCsumData)); - - if (DetectCsumParseArg(csum_str, cd) == 0) - goto error; - - sm->ctx = (SigMatchCtx *)cd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (cd != NULL) DetectIPV4CsumFree(cd); - if (sm != NULL) SCFree(sm); - - return -1; -} - -void DetectIPV4CsumFree(void *ptr) -{ - DetectCsumData *cd = (DetectCsumData *)ptr; - - if (cd != NULL) - SCFree(cd); - - return; -} - -/** - * \brief Checks if the packet sent as the argument, has a valid or invalid - * tcpv4 checksum, based on whether tcpv4-csum option for this rule - * has been supplied with "valid" or "invalid" argument - * - * \param t Pointer to the tv for this detection module instance - * \param det_ctx Pointer to the detection engine thread context - * \param p Pointer to the Packet currently being matched - * \param s Pointer to the Signature, the packet is being currently - * matched with - * \param m Pointer to the keyword_structure(SigMatch) from the above - * Signature, the Packet is being currently matched with - * - * \retval 1 if the Packet contents match the keyword option; 0 otherwise - */ -int DetectTCPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectCsumData *cd = (const DetectCsumData *)ctx; - - if (p->ip4h == NULL || p->tcph == NULL || p->proto != IPPROTO_TCP || PKT_IS_PSEUDOPKT(p)) - return 0; - - if (p->flags & PKT_IGNORE_CHECKSUM) { - return cd->valid; - } - - if (p->level4_comp_csum == -1) - p->level4_comp_csum = TCPCalculateChecksum(p->ip4h->s_ip_addrs, - (uint16_t *)p->tcph, - (p->payload_len + TCP_GET_HLEN(p))); - - if (p->level4_comp_csum == p->tcph->th_sum && cd->valid == 1) - return 1; - else if (p->level4_comp_csum != p->tcph->th_sum && cd->valid == 0) - return 1; - else - return 0; -} - -/** - * \brief Creates a SigMatch for the tcpv4-csum keyword being sent as argument, - * and appends it to the Signature(s). Accepts 2 values for the - * keyword - "valid" and "invalid", both with and without quotes - * - * \param de_ctx Pointer to the detection engine context - * \param s Pointer to signature for the current Signature being parsed - * from the rules - * \param csum_str Pointer to the string holding the keyword value - * - * \retval 0 on success, -1 on failure - */ -static int DetectTCPV4CsumSetup(DetectEngineCtx *de_ctx, Signature *s, char *csum_str) -{ - DetectCsumData *cd = NULL; - SigMatch *sm = NULL; - - //printf("DetectCsumSetup: \'%s\'\n", csum_str); - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_TCPV4_CSUM; - - if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL) - goto error; - memset(cd, 0, sizeof(DetectCsumData)); - - if (DetectCsumParseArg(csum_str, cd) == 0) - goto error; - - sm->ctx = (SigMatchCtx *)cd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (cd != NULL) DetectTCPV4CsumFree(cd); - if (sm != NULL) SCFree(sm); - - return -1; -} - -void DetectTCPV4CsumFree(void *ptr) -{ - DetectCsumData *cd = (DetectCsumData *)ptr; - - if (cd != NULL) - SCFree(cd); - - return; -} - -/** - * \brief Checks if the packet sent as the argument, has a valid or invalid - * tcpv6 checksum, based on whether tcpv6-csum option for this rule - * has been supplied with "valid" or "invalid" argument - * - * \param t Pointer to the tv for this detection module instance - * \param det_ctx Pointer to the detection engine thread context - * \param p Pointer to the Packet currently being matched - * \param s Pointer to the Signature, the packet is being currently - * matched with - * \param m Pointer to the keyword_structure(SigMatch) from the above - * Signature, the Packet is being currently matched with - * - * \retval 1 if the Packet contents match the keyword option; 0 otherwise - */ -int DetectTCPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectCsumData *cd = (const DetectCsumData *)ctx; - - if (p->ip6h == NULL || p->tcph == NULL || p->proto != IPPROTO_TCP || PKT_IS_PSEUDOPKT(p)) - return 0; - - if (p->flags & PKT_IGNORE_CHECKSUM) { - return cd->valid; - } - - if (p->level4_comp_csum == -1) - p->level4_comp_csum = TCPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, - (p->payload_len + TCP_GET_HLEN(p))); - - if (p->level4_comp_csum == p->tcph->th_sum && cd->valid == 1) - return 1; - else if (p->level4_comp_csum != p->tcph->th_sum && cd->valid == 0) - return 1; - else - return 0; -} - -/** - * \brief Creates a SigMatch for the tcpv6-csum keyword being sent as argument, - * and appends it to the Signature(s). Accepts 2 values for the - * keyword - "valid" and "invalid", both with and without quotes - * - * \param de_ctx Pointer to the detection engine context - * \param s Pointer to signature for the current Signature being parsed - * from the rules - * \param csum_str Pointer to the string holding the keyword value - * - * \retval 0 on success, -1 on failure - */ -static int DetectTCPV6CsumSetup(DetectEngineCtx *de_ctx, Signature *s, char *csum_str) -{ - DetectCsumData *cd = NULL; - SigMatch *sm = NULL; - - //printf("DetectCsumSetup: \'%s\'\n", csum_str); - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_TCPV6_CSUM; - - if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL) - goto error; - memset(cd, 0, sizeof(DetectCsumData)); - - if (DetectCsumParseArg(csum_str, cd) == 0) - goto error; - - sm->ctx = (SigMatchCtx *)cd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (cd != NULL) DetectTCPV6CsumFree(cd); - if (sm != NULL) SCFree(sm); - - return -1; -} - -void DetectTCPV6CsumFree(void *ptr) -{ - DetectCsumData *cd = (DetectCsumData *)ptr; - - if (cd != NULL) - SCFree(cd); - - return; -} - -/** - * \brief Checks if the packet sent as the argument, has a valid or invalid - * udpv4 checksum, based on whether udpv4-csum option for this rule - * has been supplied with "valid" or "invalid" argument - * - * \param t Pointer to the tv for this detection module instance - * \param det_ctx Pointer to the detection engine thread context - * \param p Pointer to the Packet currently being matched - * \param s Pointer to the Signature, the packet is being currently - * matched with - * \param m Pointer to the keyword_structure(SigMatch) from the above - * Signature, the Packet is being currently matched with - * - * \retval 1 if the Packet contents match the keyword option; 0 otherwise - */ -int DetectUDPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectCsumData *cd = (const DetectCsumData *)ctx; - - if (p->ip4h == NULL || p->udph == NULL || p->proto != IPPROTO_UDP || PKT_IS_PSEUDOPKT(p) || p->udph->uh_sum == 0) - return 0; - - if (p->flags & PKT_IGNORE_CHECKSUM) { - return cd->valid; - } - - if (p->level4_comp_csum == -1) - p->level4_comp_csum = UDPV4CalculateChecksum(p->ip4h->s_ip_addrs, - (uint16_t *)p->udph, - (p->payload_len + - UDP_HEADER_LEN) ); - - if (p->level4_comp_csum == p->udph->uh_sum && cd->valid == 1) - return 1; - else if (p->level4_comp_csum != p->udph->uh_sum && cd->valid == 0) - return 1; - else - return 0; -} - -/** - * \brief Creates a SigMatch for the udpv4-csum keyword being sent as argument, - * and appends it to the Signature(s). Accepts 2 values for the - * keyword - "valid" and "invalid", both with and without quotes - * - * \param de_ctx Pointer to the detection engine context - * \param s Pointer to signature for the current Signature being parsed - * from the rules - * \param csum_str Pointer to the string holding the keyword value - * - * \retval 0 on success, -1 on failure - */ -static int DetectUDPV4CsumSetup(DetectEngineCtx *de_ctx, Signature *s, char *csum_str) -{ - DetectCsumData *cd = NULL; - SigMatch *sm = NULL; - - //printf("DetectCsumSetup: \'%s\'\n", csum_str); - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_UDPV4_CSUM; - - if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL) - goto error; - memset(cd, 0, sizeof(DetectCsumData)); - - if (DetectCsumParseArg(csum_str, cd) == 0) - goto error; - - sm->ctx = (SigMatchCtx *)cd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (cd != NULL) DetectUDPV4CsumFree(cd); - if (sm != NULL) SCFree(sm); - - return -1; -} - -void DetectUDPV4CsumFree(void *ptr) -{ - DetectCsumData *cd = (DetectCsumData *)ptr; - - if (cd != NULL) - SCFree(cd); - - return; -} - -/** - * \brief Checks if the packet sent as the argument, has a valid or invalid - * udpv6 checksum, based on whether udpv6-csum option for this rule - * has been supplied with "valid" or "invalid" argument - * - * \param t Pointer to the tv for this detection module instance - * \param det_ctx Pointer to the detection engine thread context - * \param p Pointer to the Packet currently being matched - * \param s Pointer to the Signature, the packet is being currently - * matched with - * \param m Pointer to the keyword_structure(SigMatch) from the above - * Signature, the Packet is being currently matched with - * - * \retval 1 if the Packet contents match the keyword option; 0 otherwise - */ -int DetectUDPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectCsumData *cd = (const DetectCsumData *)ctx; - - if (p->ip6h == NULL || p->udph == NULL || p->proto != IPPROTO_UDP || PKT_IS_PSEUDOPKT(p)) - return 0; - - if (p->flags & PKT_IGNORE_CHECKSUM) { - return cd->valid; - } - - if (p->level4_comp_csum == -1) - p->level4_comp_csum = UDPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->udph, - (p->payload_len + - UDP_HEADER_LEN) ); - - if (p->level4_comp_csum == p->udph->uh_sum && cd->valid == 1) - return 1; - else if (p->level4_comp_csum != p->udph->uh_sum && cd->valid == 0) - return 1; - else - return 0; -} - -/** - * \brief Creates a SigMatch for the udpv6-csum keyword being sent as argument, - * and appends it to the Signature(s). Accepts 2 values for the - * keyword - "valid" and "invalid", both with and without quotes - * - * \param de_ctx Pointer to the detection engine context - * \param s Pointer to signature for the current Signature being parsed - * from the rules - * \param csum_str Pointer to the string holding the keyword value - * - * \retval 0 on success, -1 on failure - */ -static int DetectUDPV6CsumSetup(DetectEngineCtx *de_ctx, Signature *s, char *csum_str) -{ - DetectCsumData *cd = NULL; - SigMatch *sm = NULL; - - //printf("DetectCsumSetup: \'%s\'\n", csum_str); - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_UDPV6_CSUM; - - if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL) - goto error; - memset(cd, 0, sizeof(DetectCsumData)); - - if (DetectCsumParseArg(csum_str, cd) == 0) - goto error; - - sm->ctx = (void *)cd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (cd != NULL) DetectUDPV6CsumFree(cd); - if (sm != NULL) SCFree(sm); - - return -1; -} - -void DetectUDPV6CsumFree(void *ptr) -{ - DetectCsumData *cd = (DetectCsumData *)ptr; - - if (cd != NULL) - SCFree(cd); - - return; -} - -/** - * \brief Checks if the packet sent as the argument, has a valid or invalid - * icmpv4 checksum, based on whether icmpv4-csum option for this rule - * has been supplied with "valid" or "invalid" argument - * - * \param t Pointer to the tv for this detection module instance - * \param det_ctx Pointer to the detection engine thread context - * \param p Pointer to the Packet currently being matched - * \param s Pointer to the Signature, the packet is being currently - * matched with - * \param m Pointer to the keyword_structure(SigMatch) from the above - * Signature, the Packet is being currently matched with - * - * \retval 1 if the Packet contents match the keyword option; 0 otherwise - */ -int DetectICMPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectCsumData *cd = (const DetectCsumData *)ctx; - - if (p->ip4h == NULL || p->icmpv4h == NULL || p->proto != IPPROTO_ICMP || PKT_IS_PSEUDOPKT(p)) - return 0; - - if (p->flags & PKT_IGNORE_CHECKSUM) { - return cd->valid; - } - - if (p->level4_comp_csum == -1) - p->level4_comp_csum = ICMPV4CalculateChecksum((uint16_t *)p->icmpv4h, - ntohs(IPV4_GET_RAW_IPLEN(p->ip4h)) - - IPV4_GET_RAW_HLEN(p->ip4h) * 4); - - if (p->level4_comp_csum == p->icmpv4h->checksum && cd->valid == 1) - return 1; - else if (p->level4_comp_csum != p->icmpv4h->checksum && cd->valid == 0) - return 1; - else - return 0; -} - -/** - * \brief Creates a SigMatch for the icmpv4-csum keyword being sent as argument, - * and appends it to the Signature(s). Accepts 2 values for the - * keyword - "valid" and "invalid", both with and without quotes - * - * \param de_ctx Pointer to the detection engine context - * \param s Pointer to signature for the current Signature being parsed - * from the rules - * \param csum_str Pointer to the string holding the keyword value - * - * \retval 0 on success, -1 on failure - */ -static int DetectICMPV4CsumSetup(DetectEngineCtx *de_ctx, Signature *s, char *csum_str) -{ - DetectCsumData *cd = NULL; - SigMatch *sm = NULL; - - //printf("DetectCsumSetup: \'%s\'\n", csum_str); - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_ICMPV4_CSUM; - - if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL) - goto error; - memset(cd, 0, sizeof(DetectCsumData)); - - if (DetectCsumParseArg(csum_str, cd) == 0) - goto error; - - sm->ctx = (SigMatchCtx *)cd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (cd != NULL) DetectICMPV4CsumFree(cd); - if (sm != NULL) SCFree(sm); - - return -1; -} - -void DetectICMPV4CsumFree(void *ptr) -{ - DetectCsumData *cd = (DetectCsumData *)ptr; - - if (cd != NULL) - SCFree(cd); - - return; -} - -/** - * \brief Checks if the packet sent as the argument, has a valid or invalid - * icmpv6 checksum, based on whether icmpv6-csum option for this rule - * has been supplied with "valid" or "invalid" argument - * - * \param t Pointer to the tv for this detection module instance - * \param det_ctx Pointer to the detection engine thread context - * \param p Pointer to the Packet currently being matched - * \param s Pointer to the Signature, the packet is being currently - * matched with - * \param m Pointer to the keyword_structure(SigMatch) from the above - * Signature, the Packet is being currently matched with - * - * \retval 1 if the Packet contents match the keyword option; 0 otherwise - */ -int DetectICMPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectCsumData *cd = (const DetectCsumData *)ctx; - - if (p->ip6h == NULL || p->icmpv6h == NULL || p->proto != IPPROTO_ICMPV6 || PKT_IS_PSEUDOPKT(p) || - (GET_PKT_LEN(p) - ((uint8_t *)p->icmpv6h - GET_PKT_DATA(p))) <= 0) { - return 0; - } - - if (p->flags & PKT_IGNORE_CHECKSUM) { - return cd->valid; - } - - if (p->level4_comp_csum == -1) - p->level4_comp_csum = ICMPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->icmpv6h, - GET_PKT_LEN(p) - ((uint8_t *)p->icmpv6h - GET_PKT_DATA(p))); - - if (p->level4_comp_csum == p->icmpv6h->csum && cd->valid == 1) - return 1; - else if (p->level4_comp_csum != p->icmpv6h->csum && cd->valid == 0) - return 1; - else - return 0; -} - -/** - * \brief Creates a SigMatch for the icmpv6-csum keyword being sent as argument, - * and appends it to the Signature(s). Accepts 2 values for the - * keyword - "valid" and "invalid", both with and without quotes - * - * \param de_ctx Pointer to the detection engine context - * \param s Pointer to signature for the current Signature being parsed - * from the rules - * \param csum_str Pointer to the string holding the keyword value - * - * \retval 0 on success, -1 on failure - */ -static int DetectICMPV6CsumSetup(DetectEngineCtx *de_ctx, Signature *s, char *csum_str) -{ - DetectCsumData *cd = NULL; - SigMatch *sm = NULL; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_ICMPV6_CSUM; - - if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL) - goto error; - memset(cd, 0, sizeof(DetectCsumData)); - - if (DetectCsumParseArg(csum_str, cd) == 0) - goto error; - - sm->ctx = (SigMatchCtx *)cd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (cd != NULL) DetectICMPV6CsumFree(cd); - if (sm != NULL) SCFree(sm); - - return -1; -} - -void DetectICMPV6CsumFree(void *ptr) -{ - DetectCsumData *cd = (DetectCsumData *)ptr; - - if (cd != NULL) - SCFree(cd); - - return; -} - -/* ---------------------------------- Unit Tests --------------------------- */ - -#ifdef UNITTESTS - -int DetectCsumIPV4ValidArgsTestParse01(void) -{ - Signature s; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectIPV4CsumSetup(NULL, &s, "\"valid\"") == 0); - result &= (DetectIPV4CsumSetup(NULL, &s, "\"invalid\"") == 0); - result &= (DetectIPV4CsumSetup(NULL, &s, "\"vaLid\"") == 0); - result &= (DetectIPV4CsumSetup(NULL, &s, "\"VALID\"") == 0); - result &= (DetectIPV4CsumSetup(NULL, &s, "\"iNvaLid\"") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectIPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumIPV4InValidArgsTestParse02(void) -{ - Signature s; - int result = -1; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectIPV4CsumSetup(NULL, &s, "vaid") == -1); - result &= (DetectIPV4CsumSetup(NULL, &s, "invaalid") == -1); - result &= (DetectIPV4CsumSetup(NULL, &s, "vaLiid") == -1); - result &= (DetectIPV4CsumSetup(NULL, &s, "VALieD") == -1); - result &= (DetectIPV4CsumSetup(NULL, &s, "iNvamid") == -1); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectIPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumIPV4ValidArgsTestParse03(void) -{ - Signature s; - DetectCsumData *cd = NULL; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectIPV4CsumSetup(NULL, &s, "valid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 1); - } - DetectIPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - s.sm_lists[DETECT_SM_LIST_MATCH] = NULL; - - result &= (DetectIPV4CsumSetup(NULL, &s, "INVALID") == 0); - - if (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 0); - } - DetectIPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumICMPV4ValidArgsTestParse01(void) -{ - Signature s; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectICMPV4CsumSetup(NULL, &s, "valid") == 0); - result &= (DetectICMPV4CsumSetup(NULL, &s, "invalid") == 0); - result &= (DetectICMPV4CsumSetup(NULL, &s, "vaLid") == 0); - result &= (DetectICMPV4CsumSetup(NULL, &s, "VALID") == 0); - result &= (DetectICMPV4CsumSetup(NULL, &s, "iNvaLid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectICMPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumICMPV4InValidArgsTestParse02(void) -{ - Signature s; - int result = -1; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectICMPV4CsumSetup(NULL, &s, "vaid") == -1); - result &= (DetectICMPV4CsumSetup(NULL, &s, "invaalid") == -1); - result &= (DetectICMPV4CsumSetup(NULL, &s, "vaLiid") == -1); - result &= (DetectICMPV4CsumSetup(NULL, &s, "VALieD") == -1); - result &= (DetectICMPV4CsumSetup(NULL, &s, "iNvamid") == -1); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectICMPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumICMPV4ValidArgsTestParse03(void) -{ - Signature s; - DetectCsumData *cd = NULL; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectICMPV4CsumSetup(NULL, &s, "valid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 1); - } - DetectICMPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - s.sm_lists[DETECT_SM_LIST_MATCH] = NULL; - - result &= (DetectICMPV4CsumSetup(NULL, &s, "INVALID") == 0); - - if (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 0); - } - DetectICMPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumTCPV4ValidArgsTestParse01(void) -{ - Signature s; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectTCPV4CsumSetup(NULL, &s, "valid") == 0); - result &= (DetectTCPV4CsumSetup(NULL, &s, "invalid") == 0); - result &= (DetectTCPV4CsumSetup(NULL, &s, "vaLid") == 0); - result &= (DetectTCPV4CsumSetup(NULL, &s, "VALID") == 0); - result &= (DetectTCPV4CsumSetup(NULL, &s, "iNvaLid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectTCPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumTCPV4InValidArgsTestParse02(void) -{ - Signature s; - int result = -1; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectTCPV4CsumSetup(NULL, &s, "vaid") == -1); - result &= (DetectTCPV4CsumSetup(NULL, &s, "invaalid") == -1); - result &= (DetectTCPV4CsumSetup(NULL, &s, "vaLiid") == -1); - result &= (DetectTCPV4CsumSetup(NULL, &s, "VALieD") == -1); - result &= (DetectTCPV4CsumSetup(NULL, &s, "iNvamid") == -1); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectTCPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumTCPV4ValidArgsTestParse03(void) -{ - Signature s; - DetectCsumData *cd = NULL; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectTCPV4CsumSetup(NULL, &s, "valid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 1); - } - DetectTCPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - s.sm_lists[DETECT_SM_LIST_MATCH] = NULL; - - result &= (DetectTCPV4CsumSetup(NULL, &s, "INVALID") == 0); - - if (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 0); - } - DetectTCPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumUDPV4ValidArgsTestParse01(void) -{ - Signature s; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectUDPV4CsumSetup(NULL, &s, "valid") == 0); - result &= (DetectUDPV4CsumSetup(NULL, &s, "invalid") == 0); - result &= (DetectUDPV4CsumSetup(NULL, &s, "vaLid") == 0); - result &= (DetectUDPV4CsumSetup(NULL, &s, "VALID") == 0); - result &= (DetectUDPV4CsumSetup(NULL, &s, "iNvaLid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectUDPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumUDPV4InValidArgsTestParse02(void) -{ - Signature s; - int result = -1; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectUDPV4CsumSetup(NULL, &s, "vaid") == -1); - result &= (DetectUDPV4CsumSetup(NULL, &s, "invaalid") == -1); - result &= (DetectUDPV4CsumSetup(NULL, &s, "vaLiid") == -1); - result &= (DetectUDPV4CsumSetup(NULL, &s, "VALieD") == -1); - result &= (DetectUDPV4CsumSetup(NULL, &s, "iNvamid") == -1); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectUDPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumUDPV4ValidArgsTestParse03(void) -{ - Signature s; - DetectCsumData *cd = NULL; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectUDPV4CsumSetup(NULL, &s, "valid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 1); - } - DetectUDPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - s.sm_lists[DETECT_SM_LIST_MATCH] = NULL; - - result &= (DetectUDPV4CsumSetup(NULL, &s, "INVALID") == 0); - - if (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 0); - } - DetectUDPV4CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumTCPV6ValidArgsTestParse01(void) -{ - Signature s; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectTCPV6CsumSetup(NULL, &s, "valid") == 0); - result &= (DetectTCPV6CsumSetup(NULL, &s, "invalid") == 0); - result &= (DetectTCPV6CsumSetup(NULL, &s, "vaLid") == 0); - result &= (DetectTCPV6CsumSetup(NULL, &s, "VALID") == 0); - result &= (DetectTCPV6CsumSetup(NULL, &s, "iNvaLid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectTCPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumTCPV6InValidArgsTestParse02(void) -{ - Signature s; - int result = -1; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectTCPV6CsumSetup(NULL, &s, "vaid") == -1); - result &= (DetectTCPV6CsumSetup(NULL, &s, "invaalid") == -1); - result &= (DetectTCPV6CsumSetup(NULL, &s, "vaLiid") == -1); - result &= (DetectTCPV6CsumSetup(NULL, &s, "VALieD") == -1); - result &= (DetectTCPV6CsumSetup(NULL, &s, "iNvamid") == -1); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectTCPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumTCPV6ValidArgsTestParse03(void) -{ - Signature s; - DetectCsumData *cd = NULL; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectTCPV6CsumSetup(NULL, &s, "valid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 1); - } - DetectTCPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - s.sm_lists[DETECT_SM_LIST_MATCH] = NULL; - - result &= (DetectTCPV6CsumSetup(NULL, &s, "INVALID") == 0); - - if (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 0); - } - DetectTCPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumUDPV6ValidArgsTestParse01(void) -{ - Signature s; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectUDPV6CsumSetup(NULL, &s, "valid") == 0); - result &= (DetectUDPV6CsumSetup(NULL, &s, "invalid") == 0); - result &= (DetectUDPV6CsumSetup(NULL, &s, "vaLid") == 0); - result &= (DetectUDPV6CsumSetup(NULL, &s, "VALID") == 0); - result &= (DetectUDPV6CsumSetup(NULL, &s, "iNvaLid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectUDPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumUDPV6InValidArgsTestParse02(void) -{ - Signature s; - int result = -1; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectUDPV6CsumSetup(NULL, &s, "vaid") == -1); - result &= (DetectUDPV6CsumSetup(NULL, &s, "invaalid") == -1); - result &= (DetectUDPV6CsumSetup(NULL, &s, "vaLiid") == -1); - result &= (DetectUDPV6CsumSetup(NULL, &s, "VALieD") == -1); - result &= (DetectUDPV6CsumSetup(NULL, &s, "iNvamid") == -1); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectUDPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumUDPV6ValidArgsTestParse03(void) -{ - Signature s; - DetectCsumData *cd = NULL; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectUDPV6CsumSetup(NULL, &s, "valid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 1); - } - DetectUDPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - s.sm_lists[DETECT_SM_LIST_MATCH] = NULL; - - result &= (DetectUDPV6CsumSetup(NULL, &s, "INVALID") == 0); - - if (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 0); - } - DetectUDPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumICMPV6ValidArgsTestParse01(void) -{ - Signature s; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectICMPV6CsumSetup(NULL, &s, "valid") == 0); - result &= (DetectICMPV6CsumSetup(NULL, &s, "invalid") == 0); - result &= (DetectICMPV6CsumSetup(NULL, &s, "vaLid") == 0); - result &= (DetectICMPV6CsumSetup(NULL, &s, "VALID") == 0); - result &= (DetectICMPV6CsumSetup(NULL, &s, "iNvaLid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectICMPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumICMPV6InValidArgsTestParse02(void) -{ - Signature s; - int result = -1; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectICMPV6CsumSetup(NULL, &s, "vaid") == -1); - result &= (DetectICMPV6CsumSetup(NULL, &s, "invaalid") == -1); - result &= (DetectICMPV6CsumSetup(NULL, &s, "vaLiid") == -1); - result &= (DetectICMPV6CsumSetup(NULL, &s, "VALieD") == -1); - result &= (DetectICMPV6CsumSetup(NULL, &s, "iNvamid") == -1); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - DetectICMPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -int DetectCsumICMPV6ValidArgsTestParse03(void) -{ - Signature s; - DetectCsumData *cd = NULL; - int result = 0; - SigMatch *temp = NULL; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectICMPV6CsumSetup(NULL, &s, "valid") == 0); - - while (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 1); - } - DetectICMPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - s.sm_lists[DETECT_SM_LIST_MATCH] = NULL; - - result &= (DetectICMPV6CsumSetup(NULL, &s, "INVALID") == 0); - - if (s.sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - if (s.sm_lists[DETECT_SM_LIST_MATCH]->ctx != NULL) { - cd = (DetectCsumData *)s.sm_lists[DETECT_SM_LIST_MATCH]->ctx; - result &= (cd->valid == 0); - } - DetectICMPV6CsumFree(s.sm_lists[DETECT_SM_LIST_MATCH]->ctx); - temp = s.sm_lists[DETECT_SM_LIST_MATCH]; - s.sm_lists[DETECT_SM_LIST_MATCH] = s.sm_lists[DETECT_SM_LIST_MATCH]->next; - SCFree(temp); - } - - return result; -} - -#include "detect-engine.h" -#include "stream-tcp.h" - -int DetectCsumICMPV6Test01(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - DecodeThreadVars dtv; - - Packet *p = PacketGetFromAlloc(); - if (p == NULL) { - printf("failure PacketGetFromAlloc\n"); - goto end; - } - - uint8_t pkt[] = { - 0x00, 0x30, 0x18, 0xa8, 0x7c, 0x23, 0x2c, 0x41, - 0x38, 0xa7, 0xea, 0xeb, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x3c, 0x40, 0xad, 0xa1, - 0x09, 0x80, 0x00, 0x01, 0xd6, 0xf3, 0x20, 0x01, - 0xf4, 0xbe, 0xea, 0x3c, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x32, 0xb2, 0x00, 0x01, 0x32, 0xb2, - 0x09, 0x80, 0x20, 0x01, 0x00, 0x00, 0x3c, 0x00, - 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, - 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, - 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, - 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x63, 0xc2, 0x00, 0x00, 0x00, 0x00 }; - - PacketCopyData(p, pkt, sizeof(pkt)); - - memset(&tv, 0, sizeof(tv)); - memset(&dtv, 0, sizeof(dtv)); - - StreamTcpInitConfig(TRUE); - FlowInitConfig(FLOW_QUIET); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("DetectEngineCtxInit failure\n"); - goto end; - } - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert ip any any -> any any " - "(icmpv6-csum:valid; sid:1;)"); - if (s == NULL) { - printf("SigInit failed\n"); - goto end; - } - SigGroupBuild(de_ctx); - - DecodeEthernet(&tv, &dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), NULL); - - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert on p, but it should: "); - goto end; - } - - result = 1; - - end: - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - PACKET_RECYCLE(p); - FlowShutdown(); - - SCFree(p); - - return result; -} - -#endif /* UNITTESTS */ - -void DetectCsumRegisterTests(void) -{ - -#ifdef UNITTESTS - - UtRegisterTest("DetectCsumIPV4ValidArgsTestParse01", - DetectCsumIPV4ValidArgsTestParse01, 1); - UtRegisterTest("DetectCsumIPV4InValidArgsTestParse02", - DetectCsumIPV4InValidArgsTestParse02, 1); - UtRegisterTest("DetectCsumIPV4ValidArgsTestParse03", - DetectCsumIPV4ValidArgsTestParse03, 1); - - UtRegisterTest("DetectCsumICMPV4ValidArgsTestParse01", - DetectCsumICMPV4ValidArgsTestParse01, 1); - UtRegisterTest("DetectCsumICMPV4InValidArgsTestParse02", - DetectCsumICMPV4InValidArgsTestParse02, 1); - UtRegisterTest("DetectCsumICMPV4ValidArgsTestParse03", - DetectCsumICMPV4ValidArgsTestParse03, 1); - - UtRegisterTest("DetectCsumTCPV4ValidArgsTestParse01", - DetectCsumTCPV4ValidArgsTestParse01, 1); - UtRegisterTest("DetectCsumTCPV4InValidArgsTestParse02", - DetectCsumTCPV4InValidArgsTestParse02, 1); - UtRegisterTest("DetectCsumTCPV4ValidArgsTestParse03", - DetectCsumTCPV4ValidArgsTestParse03, 1); - - UtRegisterTest("DetectCsumUDPV4ValidArgsTestParse01", - DetectCsumUDPV4ValidArgsTestParse01, 1); - UtRegisterTest("DetectCsumUDPV4InValidArgsTestParse02", - DetectCsumUDPV4InValidArgsTestParse02, 1); - UtRegisterTest("DetectCsumUDPV4ValidArgsTestParse03", - DetectCsumUDPV4ValidArgsTestParse03, 1); - - UtRegisterTest("DetectCsumUDPV6ValidArgsTestParse01", - DetectCsumUDPV6ValidArgsTestParse01, 1); - UtRegisterTest("DetectCsumUDPV6InValidArgsTestParse02", - DetectCsumUDPV6InValidArgsTestParse02, 1); - UtRegisterTest("DetectCsumUDPV6ValidArgsTestParse03", - DetectCsumUDPV6ValidArgsTestParse03, 1); - - UtRegisterTest("DetectCsumTCPV6ValidArgsTestParse01", - DetectCsumTCPV6ValidArgsTestParse01, 1); - UtRegisterTest("DetectCsumTCPV6InValidArgsTestParse02", - DetectCsumTCPV6InValidArgsTestParse02, 1); - UtRegisterTest("DetectCsumTCPV6ValidArgsTestParse03", - DetectCsumTCPV6ValidArgsTestParse03, 1); - - UtRegisterTest("DetectCsumICMPV6ValidArgsTestParse01", - DetectCsumICMPV6ValidArgsTestParse01, 1); - UtRegisterTest("DetectCsumICMPV6InValidArgsTestParse02", - DetectCsumICMPV6InValidArgsTestParse02, 1); - UtRegisterTest("DetectCsumICMPV6ValidArgsTestParse03", - DetectCsumICMPV6ValidArgsTestParse03, 1); - - UtRegisterTest("DetectCsumICMPV6Test01", - DetectCsumICMPV6Test01, 1); - - -#endif /* UNITTESTS */ - -} diff --git a/framework/src/suricata/src/detect-csum.h b/framework/src/suricata/src/detect-csum.h deleted file mode 100644 index 8a871745..00000000 --- a/framework/src/suricata/src/detect-csum.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_CSUM_H__ -#define __DETECT_CSUM_H__ - -#define DETECT_CSUM_VALID "valid" -#define DETECT_CSUM_INVALID "invalid" - -typedef struct DetectCsumData_ { - /* Indicates if the csum- keyword in a rule holds the - keyvalue "valid" or "invalid" */ - int16_t valid; -} DetectCsumData; - -void DetectCsumRegister(void); - -#endif /* __DETECT_CSUM_H__ */ - diff --git a/framework/src/suricata/src/detect-dce-iface.c b/framework/src/suricata/src/detect-dce-iface.c deleted file mode 100644 index 60da43ed..00000000 --- a/framework/src/suricata/src/detect-dce-iface.c +++ /dev/null @@ -1,1837 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements dce_iface keyword. - */ - -#include "suricata-common.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-dce-iface.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "app-layer.h" -#include "app-layer-dcerpc.h" -#include "queue.h" -#include "stream-tcp-reassemble.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "stream-tcp.h" - -#define DETECT_DCE_IFACE_PCRE_PARSE_ARGS "^\\s*([0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12})(?:\\s*,(<|>|=|!)([0-9]{1,5}))?(?:\\s*,(any_frag))?\\s*$" - -static pcre *parse_regex = NULL; -static pcre_extra *parse_regex_study = NULL; - -int DetectDceIfaceMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, - void *, Signature *, SigMatch *); -static int DetectDceIfaceSetup(DetectEngineCtx *, Signature *, char *); -void DetectDceIfaceFree(void *); - -/** - * \brief Registers the keyword handlers for the "dce_iface" keyword. - */ -void DetectDceIfaceRegister(void) -{ - const char *eb; - int eo; - int opts = 0; - - sigmatch_table[DETECT_DCE_IFACE].name = "dce_iface"; - sigmatch_table[DETECT_DCE_IFACE].alproto = ALPROTO_DCERPC; - sigmatch_table[DETECT_DCE_IFACE].Match = NULL; - sigmatch_table[DETECT_DCE_IFACE].AppLayerMatch = DetectDceIfaceMatch; - sigmatch_table[DETECT_DCE_IFACE].Setup = DetectDceIfaceSetup; - sigmatch_table[DETECT_DCE_IFACE].Free = DetectDceIfaceFree; - sigmatch_table[DETECT_DCE_IFACE].RegisterTests = DetectDceIfaceRegisterTests; - - sigmatch_table[DETECT_DCE_IFACE].flags |= SIGMATCH_PAYLOAD; - - parse_regex = pcre_compile(DETECT_DCE_IFACE_PCRE_PARSE_ARGS, opts, &eb, - &eo, NULL); - if (parse_regex == NULL) { - SCLogDebug("pcre compile of \"%s\" failed at offset %" PRId32 ": %s", - DETECT_DCE_IFACE_PCRE_PARSE_ARGS, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogDebug("pcre study failed: %s", eb); - goto error; - } - - return; - - error: - /* we need to handle error?! */ - return; -} - -/** - * \internal - * \brief Parses the argument sent along with the "dce_iface" keyword. - * - * \param arg Pointer to the string containing the argument to be parsed. - * - * \retval did Pointer to a DetectDceIfaceData instance that holds the data - * from the parsed arg. - */ -static inline DetectDceIfaceData *DetectDceIfaceArgParse(const char *arg) -{ - DetectDceIfaceData *did = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - uint8_t hex_value; - char copy_str[128] = ""; - int i = 0, j = 0; - int len = 0; - char temp_str[3] = ""; - int version; - - ret = pcre_exec(parse_regex, parse_regex_study, arg, strlen(arg), 0, 0, ov, - MAX_SUBSTRINGS); - if (ret < 2) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, arg); - goto error; - } - - if ( (did = SCMalloc(sizeof(DetectDceIfaceData))) == NULL) - goto error; - memset(did, 0, sizeof(DetectDceIfaceData)); - - /* retrieve the iface uuid string. iface uuid is a compulsion in the keyword */ - res = pcre_copy_substring(arg, ov, MAX_SUBSTRINGS, 1, copy_str, sizeof(copy_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - /* parse the iface uuid string */ - len = strlen(copy_str); - j = 0; - temp_str[2] = '\0'; - for (i = 0; i < len; ) { - if (copy_str[i] == '-') { - i++; - continue; - } - - temp_str[0] = copy_str[i]; - temp_str[1] = copy_str[i + 1]; - - hex_value = strtol(temp_str, NULL, 16); - did->uuid[j] = hex_value; - i += 2; - j++; - } - - /* if the regex has 3 or 5, any_frag option is present in the signature */ - if (ret == 3 || ret == 5) - did->any_frag = 1; - - /* if the regex has 4 or 5, version/operator is present in the signature */ - if (ret == 4 || ret == 5) { - /* first handle the version number, so that we can do some additional - * validations of the version number, wrt. the operator */ - res = pcre_copy_substring(arg, ov, MAX_SUBSTRINGS, 3, copy_str, sizeof(copy_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - version = atoi(copy_str); - if (version > UINT16_MAX) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "DCE_IFACE interface version " - "invalid: %d\n", version); - goto error; - } - did->version = version; - - /* now let us handle the operator supplied with the version number */ - res = pcre_copy_substring(arg, ov, MAX_SUBSTRINGS, 2, copy_str, sizeof(copy_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - switch (copy_str[0]) { - case '<': - if (version == 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "DCE_IFACE interface " - "version invalid: %d. Version can't be less" - "than 0, with \"<\" operator", version); - goto error; - } - - did->op = DETECT_DCE_IFACE_OP_LT; - break; - case '>': - if (version == UINT16_MAX) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "DCE_IFACE interface " - "version invalid: %d. Version can't be greater" - "than %d, with \">\" operator", version, - UINT16_MAX); - goto error; - } - - did->op = DETECT_DCE_IFACE_OP_GT; - break; - case '=': - did->op = DETECT_DCE_IFACE_OP_EQ; - break; - case '!': - did->op = DETECT_DCE_IFACE_OP_NE; - break; - } - } - - return did; - - error: - if (did != NULL) - SCFree(did); - return NULL; -} - -/** - * \internal - * \brief Internal function that compares the dce interface version for this - * flow, to the signature's interface version specified using the - * dce_iface keyword. - * - * \param version The dce interface version for this flow. - * \param dce_data Pointer to the Signature's dce_iface keyword - * state(DetectDceIfaceData *). - */ -static inline int DetectDceIfaceMatchIfaceVersion(uint16_t version, - DetectDceIfaceData *dce_data) -{ - switch (dce_data->op) { - case DETECT_DCE_IFACE_OP_LT: - return (version < dce_data->version); - case DETECT_DCE_IFACE_OP_GT: - return (version > dce_data->version); - case DETECT_DCE_IFACE_OP_EQ: - return (version == dce_data->version); - case DETECT_DCE_IFACE_OP_NE: - return (version != dce_data->version); - default: - return 1; - } -} - -/** - * \brief App layer match function for the "dce_iface" keyword. - * - * \param t Pointer to the ThreadVars instance. - * \param det_ctx Pointer to the DetectEngineThreadCtx. - * \param f Pointer to the flow. - * \param flags Pointer to the flags indicating the flow direction. - * \param state Pointer to the app layer state data. - * \param s Pointer to the Signature instance. - * \param m Pointer to the SigMatch. - * - * \retval 1 On Match. - * \retval 0 On no match. - */ -int DetectDceIfaceMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, - uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - - int ret = 0; - DCERPCUuidEntry *item = NULL; - int i = 0; - DetectDceIfaceData *dce_data = (DetectDceIfaceData *)m->ctx; - DCERPCState *dcerpc_state = (DCERPCState *)state; - if (dcerpc_state == NULL) { - SCLogDebug("No DCERPCState for the flow"); - SCReturnInt(0); - } - - /* we still haven't seen a request */ - if (!dcerpc_state->dcerpc.dcerpcrequest.first_request_seen) - goto end; - - if (!(dcerpc_state->dcerpc.dcerpchdr.type == REQUEST)) - goto end; - - TAILQ_FOREACH(item, &dcerpc_state->dcerpc.dcerpcbindbindack.accepted_uuid_list, next) { - SCLogDebug("item %p", item); - ret = 1; - - /* if any_frag is not enabled, we need to match only against the first - * fragment */ - if (!dce_data->any_frag && !(item->flags & DCERPC_UUID_ENTRY_FLAG_FF)) - continue; - - /* if the uuid has been rejected(item->result == 1), we skip to the - * next uuid */ - if (item->result != 0) - continue; - - /* check the interface uuid */ - for (i = 0; i < 16; i++) { - if (dce_data->uuid[i] != item->uuid[i]) { - ret = 0; - break; - } - } - ret &= (item->ctxid == dcerpc_state->dcerpc.dcerpcrequest.ctxid); - if (ret == 0) - continue; - - /* check the interface version */ - if (dce_data->op != DETECT_DCE_IFACE_OP_NONE && - !DetectDceIfaceMatchIfaceVersion(item->version, dce_data)) { - ret &= 0; - } - - /* we have a match. Time to leave with a match */ - if (ret == 1) - goto end; - } - -end: - SCReturnInt(ret); -} - -/** - * \brief Creates a SigMatch for the "dce_iface" keyword being sent as argument, - * and appends it to the Signature(s). - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to signature for the current Signature being parsed - * from the rules. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 on success, -1 on failure. - */ - -static int DetectDceIfaceSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - DetectDceIfaceData *did = NULL; - SigMatch *sm = NULL; - - did = DetectDceIfaceArgParse(arg); - if (did == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Error parsing dec_iface option in " - "signature"); - goto error; - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_DCE_IFACE; - sm->ctx = (void *)did; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_DCERPC) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - s->alproto = ALPROTO_DCERPC; - /* Flagged the signature as to inspect the app layer data */ - s->flags |= SIG_FLAG_APPLAYER; - return 0; - - error: - DetectDceIfaceFree(did); - if (sm != NULL) - SCFree(sm); - return -1; -} - -void DetectDceIfaceFree(void *ptr) -{ - SCFree(ptr); - - return; -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -static int DetectDceIfaceTestParse01(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - SCReturnInt(0); - } - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - if (did == NULL) { - SCReturnInt(0); - } - - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 0); - result &= (did->op == 0); - result &= (did->any_frag == 0); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse02(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,>1") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - SCReturnInt(0); - } - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - if (did == NULL) { - SCReturnInt(0); - } - - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 1); - result &= (did->op == DETECT_DCE_IFACE_OP_GT); - result &= (did->any_frag == 0); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse03(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,<10") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - SCReturnInt(0); - } - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 10); - result &= (did->op == DETECT_DCE_IFACE_OP_LT); - result &= (did->any_frag == 0); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse04(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,!10") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - SCReturnInt(0); - } - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - if (did == NULL) { - SCReturnInt(0); - } - - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 10); - result &= (did->op == DETECT_DCE_IFACE_OP_NE); - result &= (did->any_frag == 0); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse05(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,=10") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - SCReturnInt(0); - } - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - if (did == NULL) { - SCReturnInt(0); - } - - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 10); - result &= (did->op == DETECT_DCE_IFACE_OP_EQ); - result &= (did->any_frag == 0); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse06(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,any_frag") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - SCReturnInt(0); - } - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - if (did == NULL) { - SCReturnInt(0); - } - - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 0); - result &= (did->op == 0); - result &= (did->any_frag == 1); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse07(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,>1,any_frag") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - SCReturnInt(0); - } - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - if (did == NULL) { - SCReturnInt(0); - } - - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 1); - result &= (did->op == DETECT_DCE_IFACE_OP_GT); - result &= (did->any_frag == 1); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse08(void) -{ - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,<1,any_frag") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - SCReturnInt(0); - } - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - if (did == NULL) { - SCReturnInt(0); - } - - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 1); - result &= (did->op == DETECT_DCE_IFACE_OP_LT); - result &= (did->any_frag == 1); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse09(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,=1,any_frag") == 0); - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - if (did == NULL) { - SCReturnInt(0); - } - - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 1); - result &= (did->op == DETECT_DCE_IFACE_OP_EQ); - result &= (did->any_frag == 1); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse10(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 0; - DetectDceIfaceData *did = NULL; - uint8_t test_uuid[] = {0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x12, 0x34, 0x12, 0x34, - 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC}; - SigMatch *temp = NULL; - int i = 0; - - result = (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,!1,any_frag") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - SCReturnInt(0); - } - - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - did = (DetectDceIfaceData *)temp->ctx; - if (did == NULL) { - SCReturnInt(0); - } - - result &= 1; - for (i = 0; i < 16; i++) { - if (did->uuid[i] != test_uuid[i]) { - result = 0; - break; - } - } - - result &= (did->version == 1); - result &= (did->op == DETECT_DCE_IFACE_OP_NE); - result &= (did->any_frag == 1); - - SigFree(s); - SCReturnInt(result); -} - -static int DetectDceIfaceTestParse11(void) -{ - SCEnter(); - - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - int result = 1; - - result &= (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,>1,ay_frag") == -1); - result &= (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-12345679ABC,>1,any_frag") == -1); - result &= (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-134-123456789ABC,>1,any_frag") == -1); - result &= (DetectDceIfaceSetup(NULL, s, "12345678-123-124-1234-123456789ABC,>1,any_frag") == -1); - result &= (DetectDceIfaceSetup(NULL, s, "1234568-1234-1234-1234-123456789ABC,>1,any_frag") == -1); - result &= (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,>65536,any_frag") == -1); - result &= (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,>=1,any_frag") == -1); - result &= (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,<0,any_frag") == -1); - result &= (DetectDceIfaceSetup(NULL, s, "12345678-1234-1234-1234-123456789ABC,>65535,any_frag") == -1); - - SigFree(s); - return result; -} - -/** - * \test Test a valid dce_iface entry for a bind and bind_ack - */ -static int DetectDceIfaceTestParse12(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_bindack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x26, 0x3d, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - - uint8_t dcerpc_request[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - - uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); - uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); - uint32_t dcerpc_request_len = sizeof(dcerpc_request); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx,"alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5,=0,any_frag; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCLogDebug("handling to_server chunk"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_bind, dcerpc_bind_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match (1): "); - goto end; - } - - SCLogDebug("handling to_client chunk"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack, - dcerpc_bindack_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched, but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_request, - dcerpc_request_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 matched, but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/* Disabled because of bug_753. Would be enabled, once we rewrite - * dce parser */ -#if 0 - -/** - * \test Test a valid dce_iface entry with a bind, bind_ack and 3 request/responses. - */ -static int DetectDceIfaceTestParse13(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x01, 0xd0, 0x8c, 0x33, 0x44, 0x22, 0xf1, 0x31, - 0xaa, 0xaa, 0x90, 0x00, 0x38, 0x00, 0x10, 0x03, - 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_bindack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x65, 0x8e, 0x00, 0x00, - 0x0d, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x77, 0x69, 0x6e, 0x72, 0x65, 0x67, 0x00, 0x6d, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x02, - }; - - uint8_t dcerpc_response1[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00, - 0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00, - 0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00, - 0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, - 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, - 0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00, - 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00, - 0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00, - 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, - 0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00, - 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, - 0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response2[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request3[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00, - 0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00, - 0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00, - 0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response3[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); - uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); - - uint32_t dcerpc_request1_len = sizeof(dcerpc_request1); - uint32_t dcerpc_response1_len = sizeof(dcerpc_response1); - - uint32_t dcerpc_request2_len = sizeof(dcerpc_request2); - uint32_t dcerpc_response2_len = sizeof(dcerpc_response2); - - uint32_t dcerpc_request3_len = sizeof(dcerpc_request3); - uint32_t dcerpc_response3_len = sizeof(dcerpc_response3); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx,"alert tcp any any -> any any " - "(msg:\"DCERPC\"; dce_iface:338cd001-2244-31f1-aaaa-900038001003,=1,any_frag; sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCLogDebug("chunk 1, bind"); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_bind, dcerpc_bind_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 didn't match after bind request: "); - goto end; - } - - SCLogDebug("chunk 2, bind_ack"); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack, - dcerpc_bindack_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched again after bind ack: "); - goto end; - } - - SCLogDebug("chunk 3, request 1"); - - /* request1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1, - dcerpc_request1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't match after request1: "); - goto end; - } - - SCLogDebug("sending response1"); - - /* response1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1, - dcerpc_response1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched after response1, but shouldn't: "); - goto end; - } - - SCLogDebug("sending request2"); - - /* request2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2, - dcerpc_request2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't match after request2: "); - goto end; - } - - /* response2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response2, - dcerpc_response2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched after response2, but shouldn't have: "); - goto end; - } - - /* request3 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request3, - dcerpc_request3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't match after request3: "); - goto end; - } - - /* response3 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF, - dcerpc_response3, dcerpc_response3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched after response3, but shouldn't have: "); - goto end; - } - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -#endif - -/** - * \test Test a valid dce_iface entry for a bind and bind_ack - */ -static int DetectDceIfaceTestParse14(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_bindack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x26, 0x3d, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - - uint8_t dcerpc_request[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - - uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); - uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); - uint32_t dcerpc_request_len = sizeof(dcerpc_request); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5,=0; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_bind, dcerpc_bind_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack, - dcerpc_bindack_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_request, - dcerpc_request_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test a valid dce_iface entry for a bind and bind_ack - */ -static int DetectDceIfaceTestParse15(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x40, 0xfd, 0x2c, 0x34, 0x6c, 0x3c, 0xce, 0x11, - 0xa8, 0x93, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); - - uint8_t dcerpc_bindack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, - 0x0d, 0x00, 0x5c, 0x70, 0x69, 0x70, 0x65, 0x5c, - 0x6c, 0x6c, 0x73, 0x72, 0x70, 0x63, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); - - uint8_t dcerpc_alter_context[] = { - 0x05, 0x00, 0x0e, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, - 0xd0, 0x4c, 0x67, 0x57, 0x00, 0x52, 0xce, 0x11, - 0xa8, 0x97, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, - 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t dcerpc_alter_context_len = sizeof(dcerpc_alter_context); - - uint8_t dcerpc_alter_context_resp[] = { - 0x05, 0x00, 0x0f, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t dcerpc_alter_context_resp_len = sizeof(dcerpc_alter_context_resp); - - uint8_t dcerpc_request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x20, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xdd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - uint32_t dcerpc_request1_len = sizeof(dcerpc_request1); - - uint8_t dcerpc_response1[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf5, 0x66, 0xbf, 0x54, - 0xc4, 0xdb, 0xdb, 0x4f, 0xa0, 0x01, 0x6d, 0xf4, - 0xf6, 0xa8, 0x44, 0xb3, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t dcerpc_response1_len = sizeof(dcerpc_response1); - - uint8_t dcerpc_request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9, - }; - uint32_t dcerpc_request2_len = sizeof(dcerpc_request2); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_iface:57674cd0-5200-11ce-a897-08002b2e9c6d; " - "sid:1;)"); - if (s == NULL) - goto end; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_iface:342cfd40-3c6c-11ce-a893-08002b2e9c6d; " - "sid:2;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_bind, dcerpc_bind_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - if (PacketAlertCheck(p, 2)) - goto end; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack, - dcerpc_bindack_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_alter_context, - dcerpc_alter_context_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_alter_context_resp, - dcerpc_alter_context_resp_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1, - dcerpc_request1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1, - dcerpc_response1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2, - dcerpc_request2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - if (!PacketAlertCheck(p, 2)) { - printf("sig 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif - -void DetectDceIfaceRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectDceIfaceTestParse01", DetectDceIfaceTestParse01, 1); - UtRegisterTest("DetectDceIfaceTestParse02", DetectDceIfaceTestParse02, 1); - UtRegisterTest("DetectDceIfaceTestParse03", DetectDceIfaceTestParse03, 1); - UtRegisterTest("DetectDceIfaceTestParse04", DetectDceIfaceTestParse04, 1); - UtRegisterTest("DetectDceIfaceTestParse05", DetectDceIfaceTestParse05, 1); - UtRegisterTest("DetectDceIfaceTestParse06", DetectDceIfaceTestParse06, 1); - UtRegisterTest("DetectDceIfaceTestParse07", DetectDceIfaceTestParse07, 1); - UtRegisterTest("DetectDceIfaceTestParse08", DetectDceIfaceTestParse08, 1); - UtRegisterTest("DetectDceIfaceTestParse09", DetectDceIfaceTestParse09, 1); - UtRegisterTest("DetectDceIfaceTestParse10", DetectDceIfaceTestParse10, 1); - UtRegisterTest("DetectDceIfaceTestParse11", DetectDceIfaceTestParse11, 1); - UtRegisterTest("DetectDceIfaceTestParse12", DetectDceIfaceTestParse12, 1); - /* Disabled because of bug_753. Would be enabled, once we rewrite - * dce parser */ -#if 0 - UtRegisterTest("DetectDceIfaceTestParse13", DetectDceIfaceTestParse13, 1); -#endif - UtRegisterTest("DetectDceIfaceTestParse14", DetectDceIfaceTestParse14, 1); - UtRegisterTest("DetectDceIfaceTestParse15", DetectDceIfaceTestParse15, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/detect-dce-iface.h b/framework/src/suricata/src/detect-dce-iface.h deleted file mode 100644 index 6a051b0d..00000000 --- a/framework/src/suricata/src/detect-dce-iface.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_DCE_IFACE_H__ -#define __DETECT_DCE_IFACE_H__ - -typedef enum DetectDceIfaceOperators_ { - DETECT_DCE_IFACE_OP_NONE = 0, - DETECT_DCE_IFACE_OP_LT, - DETECT_DCE_IFACE_OP_GT, - DETECT_DCE_IFACE_OP_EQ, - DETECT_DCE_IFACE_OP_NE, -} DetectDceIfaceOperators; - -typedef struct DetectDceIfaceData_ { - uint8_t uuid[16]; - uint8_t op; - uint16_t version; - uint8_t any_frag; -} DetectDceIfaceData; - -void DetectDceIfaceRegister(void); -void DetectDceIfaceRegisterTests(void); - -#endif /* __DETECT_DCE_IFACE_H__ */ diff --git a/framework/src/suricata/src/detect-dce-opnum.c b/framework/src/suricata/src/detect-dce-opnum.c deleted file mode 100644 index 08856663..00000000 --- a/framework/src/suricata/src/detect-dce-opnum.c +++ /dev/null @@ -1,2950 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements dce_opnum keyword - */ - -#include "suricata-common.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "app-layer.h" -#include "app-layer-dcerpc.h" -#include "queue.h" -#include "stream-tcp-reassemble.h" -#include "detect-dce-opnum.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "stream-tcp.h" - -#define DETECT_DCE_OPNUM_PCRE_PARSE_ARGS "^\\s*([0-9]{1,5}(\\s*-\\s*[0-9]{1,5}\\s*)?)(,\\s*[0-9]{1,5}(\\s*-\\s*[0-9]{1,5})?\\s*)*$" - -static pcre *parse_regex = NULL; -static pcre_extra *parse_regex_study = NULL; - -int DetectDceOpnumMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, - void *, Signature *, SigMatch *); -static int DetectDceOpnumSetup(DetectEngineCtx *, Signature *, char *); -void DetectDceOpnumFree(void *); - -/** - * \brief Registers the keyword handlers for the "dce_opnum" keyword. - */ -void DetectDceOpnumRegister(void) -{ - const char *eb; - int eo; - int opts = 0; - - sigmatch_table[DETECT_DCE_OPNUM].name = "dce_opnum"; - sigmatch_table[DETECT_DCE_OPNUM].alproto = ALPROTO_DCERPC; - sigmatch_table[DETECT_DCE_OPNUM].Match = NULL; - sigmatch_table[DETECT_DCE_OPNUM].AppLayerMatch = DetectDceOpnumMatch; - sigmatch_table[DETECT_DCE_OPNUM].Setup = DetectDceOpnumSetup; - sigmatch_table[DETECT_DCE_OPNUM].Free = DetectDceOpnumFree; - sigmatch_table[DETECT_DCE_OPNUM].RegisterTests = DetectDceOpnumRegisterTests; - - sigmatch_table[DETECT_DCE_OPNUM].flags |= SIGMATCH_PAYLOAD; - - parse_regex = pcre_compile(DETECT_DCE_OPNUM_PCRE_PARSE_ARGS, opts, &eb, - &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", - DETECT_DCE_OPNUM_PCRE_PARSE_ARGS, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - - error: - /* we need to handle error?! */ - return; -} - -/** - * \internal - * \brief Creates and returns a new instance of DetectDceOpnumRange. - * - * \retval dor Pointer to the new instance DetectDceOpnumRange. - */ -static inline DetectDceOpnumRange *DetectDceOpnumAllocDetectDceOpnumRange(void) -{ - DetectDceOpnumRange *dor = NULL; - - if ( (dor = SCMalloc(sizeof(DetectDceOpnumRange))) == NULL) - return NULL; - memset(dor, 0, sizeof(DetectDceOpnumRange)); - dor->range1 = dor->range2 = DCE_OPNUM_RANGE_UNINITIALIZED; - - return dor; -} - -/** - * \internal - * \brief Parses the argument sent along with the "dce_opnum" keyword. - * - * \param arg Pointer to the string containing the argument to be parsed. - * - * \retval did Pointer to a DetectDceIfaceData instance that holds the data - * from the parsed arg. - */ -static inline DetectDceOpnumData *DetectDceOpnumArgParse(const char *arg) -{ - DetectDceOpnumData *dod = NULL; - - DetectDceOpnumRange *dor = NULL; - DetectDceOpnumRange *prev_dor = NULL; - -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *pcre_sub_str = NULL; - - char *dup_str = NULL; - char *dup_str_temp = NULL; - char *dup_str_head = NULL; - char *comma_token = NULL; - char *hyphen_token = NULL; - - if (arg == NULL) { - goto error; - } - - ret = pcre_exec(parse_regex, parse_regex_study, arg, strlen(arg), 0, 0, ov, - MAX_SUBSTRINGS); - if (ret < 2) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, arg); - goto error; - } - - res = pcre_get_substring(arg, ov, MAX_SUBSTRINGS, 0, &pcre_sub_str); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if ( (dod = SCMalloc(sizeof(DetectDceOpnumData))) == NULL) - goto error; - memset(dod, 0, sizeof(DetectDceOpnumData)); - - if ( (dup_str = SCStrdup(pcre_sub_str)) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - goto error; - } - - /* free the substring */ - pcre_free_substring(pcre_sub_str); - - /* keep a copy of the strdup string in dup_str_head so that we can free it - * once we are done using it */ - dup_str_head = dup_str; - dup_str_temp = dup_str; - while ( (comma_token = index(dup_str, ',')) != NULL) { - comma_token[0] = '\0'; - dup_str = comma_token + 1; - - dor = DetectDceOpnumAllocDetectDceOpnumRange(); - if (dor == NULL) - goto error; - if (prev_dor == NULL) { - prev_dor = dor; - dod->range = dor; - } else { - prev_dor->next = dor; - prev_dor = dor; - } - - if ((hyphen_token = index(dup_str_temp, '-')) != NULL) { - hyphen_token[0] = '\0'; - hyphen_token++; - dor->range1 = atoi(dup_str_temp); - if (dor->range1 > DCE_OPNUM_RANGE_MAX) - goto error; - dor->range2 = atoi(hyphen_token); - if (dor->range2 > DCE_OPNUM_RANGE_MAX) - goto error; - if (dor->range1 > dor->range2) - goto error; - } - dor->range1 = atoi(dup_str_temp); - if (dor->range1 > DCE_OPNUM_RANGE_MAX) - goto error; - - dup_str_temp = dup_str; - } - - dor = DetectDceOpnumAllocDetectDceOpnumRange(); - if (dor == NULL) - goto error; - if (prev_dor == NULL) { - dod->range = dor; - } else { - prev_dor->next = dor; - } - - if ( (hyphen_token = index(dup_str, '-')) != NULL) { - hyphen_token[0] = '\0'; - hyphen_token++; - dor->range1 = atoi(dup_str); - if (dor->range1 > DCE_OPNUM_RANGE_MAX) - goto error; - dor->range2 = atoi(hyphen_token); - if (dor->range2 > DCE_OPNUM_RANGE_MAX) - goto error; - if (dor->range1 > dor->range2) - goto error; - } - dor->range1 = atoi(dup_str); - if (dor->range1 > DCE_OPNUM_RANGE_MAX) - goto error; - - if (dup_str_head != NULL) - SCFree(dup_str_head); - - return dod; - - error: - if (dup_str_head != NULL) - SCFree(dup_str_head); - DetectDceOpnumFree(dod); - return NULL; -} - -/** - * \brief App layer match function for the "dce_opnum" keyword. - * - * \param t Pointer to the ThreadVars instance. - * \param det_ctx Pointer to the DetectEngineThreadCtx. - * \param f Pointer to the flow. - * \param flags Pointer to the flags indicating the flow direction. - * \param state Pointer to the app layer state data. - * \param s Pointer to the Signature instance. - * \param m Pointer to the SigMatch. - * - * \retval 1 On Match. - * \retval 0 On no match. - */ -int DetectDceOpnumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, - uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - - DetectDceOpnumData *dce_data = (DetectDceOpnumData *)m->ctx; - DetectDceOpnumRange *dor = dce_data->range; - - DCERPCState *dcerpc_state = (DCERPCState *)state; - if (dcerpc_state == NULL) { - SCLogDebug("No DCERPCState for the flow"); - SCReturnInt(0); - } - - for ( ; dor != NULL; dor = dor->next) { - if (dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED) { - if (dor->range1 == dcerpc_state->dcerpc.dcerpcrequest.opnum) { - SCReturnInt(1); - } - } else { - if (dor->range1 <= dcerpc_state->dcerpc.dcerpcrequest.opnum && - dor->range2 >= dcerpc_state->dcerpc.dcerpcrequest.opnum) - { - SCReturnInt(1); - } - } - } - - SCReturnInt(0); -} - -/** - * \brief Creates a SigMatch for the "dce_opnum" keyword being sent as argument, - * and appends it to the Signature(s). - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to signature for the current Signature being parsed - * from the rules. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 on success, -1 on failure - */ - -static int DetectDceOpnumSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - DetectDceOpnumData *dod = NULL; - SigMatch *sm = NULL; - - if (arg == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Error parsing dce_opnum option in " - "signature, option needs a value"); - goto error; - } - - dod = DetectDceOpnumArgParse(arg); - if (dod == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Error parsing dce_opnum option in " - "signature"); - goto error; - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_DCE_OPNUM; - sm->ctx = (void *)dod; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_DCERPC) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - s->alproto = ALPROTO_DCERPC; - /* Flagged the signature as to inspect the app layer data */ - s->flags |= SIG_FLAG_APPLAYER; - return 0; - - error: - DetectDceOpnumFree(dod); - if (sm != NULL) - SCFree(sm); - return -1; -} - -void DetectDceOpnumFree(void *ptr) -{ - DetectDceOpnumData *dod = ptr; - DetectDceOpnumRange *dor = NULL; - DetectDceOpnumRange *dor_temp = NULL; - - if (dod != NULL) { - dor = dod->range; - while (dor != NULL) { - dor_temp = dor; - dor = dor->next; - SCFree(dor_temp); - } - SCFree(dod); - } - - return; -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -static int DetectDceOpnumTestParse01(void) -{ - Signature *s = SigAlloc(); - int result = 0; - - memset(s, 0, sizeof(Signature)); - - result = (DetectDceOpnumSetup(NULL, s, "12") == 0); - result &= (DetectDceOpnumSetup(NULL, s, "12,24") == 0); - result &= (DetectDceOpnumSetup(NULL, s, "12,12-24") == 0); - result &= (DetectDceOpnumSetup(NULL, s, "12-14,12,121,62-78") == 0); - result &= (DetectDceOpnumSetup(NULL, s, "12,26,62,61,6513-6666") == 0); - result &= (DetectDceOpnumSetup(NULL, s, "12,26,62,61,6513--") == -1); - result &= (DetectDceOpnumSetup(NULL, s, "12-14,12,121,62-8") == -1); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { - SigFree(s); - result &= 1; - } - - return result; -} - -static int DetectDceOpnumTestParse02(void) -{ - Signature *s = SigAlloc(); - int result = 0; - DetectDceOpnumData *dod = NULL; - DetectDceOpnumRange *dor = NULL; - SigMatch *temp = NULL; - - memset(s, 0, sizeof(Signature)); - - result = (DetectDceOpnumSetup(NULL, s, "12") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - dod = (DetectDceOpnumData *)temp->ctx; - if (dod == NULL) - goto end; - dor = dod->range; - result &= (dor->range1 == 12 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next == NULL); - } else { - result = 0; - } - - end: - SigFree(s); - return result; -} - -static int DetectDceOpnumTestParse03(void) -{ - Signature *s = SigAlloc(); - int result = 0; - DetectDceOpnumData *dod = NULL; - DetectDceOpnumRange *dor = NULL; - SigMatch *temp = NULL; - - memset(s, 0, sizeof(Signature)); - - result = (DetectDceOpnumSetup(NULL, s, "12-24") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - dod = (DetectDceOpnumData *)temp->ctx; - if (dod == NULL) - goto end; - dor = dod->range; - result &= (dor->range1 == 12 && dor->range2 == 24); - result &= (dor->next == NULL); - } else { - result = 0; - } - - end: - SigFree(s); - return result; -} - -static int DetectDceOpnumTestParse04(void) -{ - Signature *s = SigAlloc(); - int result = 0; - DetectDceOpnumData *dod = NULL; - DetectDceOpnumRange *dor = NULL; - SigMatch *temp = NULL; - - memset(s, 0, sizeof(Signature)); - - result = (DetectDceOpnumSetup(NULL, s, "12-24,24,62-72,623-635,62,25,213-235") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - dod = (DetectDceOpnumData *)temp->ctx; - if (dod == NULL) - goto end; - dor = dod->range; - result &= (dor->range1 == 12 && dor->range2 == 24); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 24 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 62 && dor->range2 == 72); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 623 && dor->range2 == 635); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 62 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 25 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 213 && dor->range2 == 235); - if (result == 0) - goto end; - } else { - result = 0; - } - - end: - SigFree(s); - return result; -} - -static int DetectDceOpnumTestParse05(void) -{ - Signature *s = SigAlloc(); - int result = 0; - DetectDceOpnumData *dod = NULL; - DetectDceOpnumRange *dor = NULL; - SigMatch *temp = NULL; - - memset(s, 0, sizeof(Signature)); - - result = (DetectDceOpnumSetup(NULL, s, "1,2,3,4,5,6,7") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - dod = (DetectDceOpnumData *)temp->ctx; - if (dod == NULL) - goto end; - dor = dod->range; - result &= (dor->range1 == 1 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 2 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 3 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 4 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 5 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 6 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 7 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - if (result == 0) - goto end; - } else { - result = 0; - } - - end: - SigFree(s); - return result; -} - -static int DetectDceOpnumTestParse06(void) -{ - Signature *s = SigAlloc(); - int result = 0; - DetectDceOpnumData *dod = NULL; - DetectDceOpnumRange *dor = NULL; - SigMatch *temp = NULL; - - memset(s, 0, sizeof(Signature)); - - result = (DetectDceOpnumSetup(NULL, s, "1-2,3-4,5-6,7-8") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - dod = (DetectDceOpnumData *)temp->ctx; - if (dod == NULL) - goto end; - dor = dod->range; - result &= (dor->range1 == 1 && dor->range2 == 2); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 3 && dor->range2 == 4); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 5 && dor->range2 == 6); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 7 && dor->range2 == 8); - if (result == 0) - goto end; - } else { - result = 0; - } - - end: - SigFree(s); - return result; -} - -static int DetectDceOpnumTestParse07(void) -{ - Signature *s = SigAlloc(); - int result = 0; - DetectDceOpnumData *dod = NULL; - DetectDceOpnumRange *dor = NULL; - SigMatch *temp = NULL; - - memset(s, 0, sizeof(Signature)); - - result = (DetectDceOpnumSetup(NULL, s, "1-2,3-4,5-6,7-8,9") == 0); - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { - temp = s->sm_lists[DETECT_SM_LIST_AMATCH]; - dod = (DetectDceOpnumData *)temp->ctx; - if (dod == NULL) - goto end; - dor = dod->range; - result &= (dor->range1 == 1 && dor->range2 == 2); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 3 && dor->range2 == 4); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 5 && dor->range2 == 6); - result &= (dor->next != NULL); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 7 && dor->range2 == 8); - if (result == 0) - goto end; - - dor = dor->next; - result &= (dor->range1 == 9 && dor->range2 == DCE_OPNUM_RANGE_UNINITIALIZED); - if (result == 0) - goto end; - } else { - result = 0; - } - - end: - SigFree(s); - return result; -} - -/** - * \test Test a valid dce_opnum entry with a bind, bind_ack and a request. - */ -static int DetectDceOpnumTestParse08(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_bindack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x26, 0x3d, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - - /* todo chop the request frag length and change the - * length related parameters in the frag */ - uint8_t dcerpc_request[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xec, 0x0c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xd4, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xe1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe1, 0x03, 0x00, 0x00, 0x83, 0xc7, 0x0b, 0x47, - 0x47, 0x47, 0x47, 0x81, 0x37, 0x22, 0xa5, 0x9b, - 0x4a, 0x75, 0xf4, 0xa3, 0x61, 0xd3, 0xbe, 0xdd, - 0x5a, 0xfb, 0x20, 0x1e, 0xfc, 0x10, 0x8e, 0x0f, - 0xa5, 0x9f, 0x4a, 0x22, 0x20, 0x9b, 0xa8, 0xd5, - 0xc4, 0xff, 0xc1, 0x3f, 0xbd, 0x9b, 0x4a, 0x22, - 0x2e, 0xc0, 0x7a, 0xa9, 0xfe, 0x97, 0xc9, 0xe1, - 0xa9, 0xf3, 0x2f, 0x22, 0xc9, 0x9b, 0x22, 0x50, - 0xa5, 0xf5, 0x4a, 0x4a, 0xce, 0x9b, 0x2f, 0x22, - 0x2e, 0x6f, 0xc1, 0xe1, 0xf3, 0xa8, 0x83, 0xa2, - 0x64, 0x98, 0xc1, 0x62, 0xa1, 0xa0, 0x89, 0x56, - 0xa8, 0x1b, 0x8b, 0x2b, 0x2e, 0xe3, 0x7a, 0xd1, - 0x03, 0xef, 0x58, 0x7c, 0x4e, 0x7d, 0x14, 0x76, - 0xfa, 0xc3, 0x7f, 0x02, 0xa5, 0xbb, 0x4a, 0x89, - 0x47, 0x6c, 0x12, 0xc9, 0x70, 0x18, 0x8e, 0x3a, - 0x2e, 0xcb, 0x52, 0xa9, 0x67, 0x98, 0x0a, 0x1e, - 0x2e, 0xc3, 0x32, 0x21, 0x7f, 0x10, 0x31, 0x3e, - 0xa6, 0x61, 0xc1, 0x61, 0x85, 0x98, 0x88, 0xa9, - 0xee, 0x83, 0x22, 0x51, 0xd6, 0xda, 0x4a, 0x4a, - 0xc1, 0xff, 0x38, 0x47, 0xcd, 0xe9, 0x25, 0x41, - 0xe4, 0xf3, 0x0d, 0x47, 0xd1, 0xcb, 0xc1, 0xd6, - 0x1e, 0x95, 0x4a, 0x22, 0xa5, 0x73, 0x08, 0x22, - 0xa5, 0x9b, 0xc9, 0xe6, 0xb5, 0xcd, 0x22, 0x43, - 0xd7, 0xe2, 0x0b, 0x4a, 0xe9, 0xf2, 0x28, 0x50, - 0xcd, 0xd7, 0x25, 0x43, 0xc1, 0x10, 0xbe, 0x99, - 0xa9, 0x9b, 0x4a, 0x22, 0x4d, 0xb8, 0x4a, 0x22, - 0xa5, 0x18, 0x8e, 0x2e, 0xf3, 0xc9, 0x22, 0x4e, - 0xc9, 0x9b, 0x4a, 0x4a, 0x96, 0xa9, 0x64, 0x46, - 0xcd, 0xec, 0x39, 0x10, 0xfa, 0xcf, 0xb5, 0x76, - 0x81, 0x8f, 0xc9, 0xe6, 0xa9, 0x10, 0x82, 0x7c, - 0xff, 0xc4, 0xa1, 0x0a, 0xf5, 0xcc, 0x1b, 0x74, - 0xf4, 0x10, 0x81, 0xa9, 0x9d, 0x98, 0xb0, 0xa1, - 0x65, 0x9f, 0xb9, 0x84, 0xd1, 0x9f, 0x13, 0x7c, - 0x47, 0x76, 0x12, 0x7c, 0xfc, 0x10, 0xbb, 0x09, - 0x55, 0x5a, 0xac, 0x20, 0xfa, 0x10, 0x7e, 0x15, - 0xa6, 0x69, 0x12, 0xe1, 0xf7, 0xca, 0x22, 0x57, - 0xd5, 0x9b, 0x4a, 0x4a, 0xd1, 0xfa, 0x38, 0x56, - 0xcd, 0xcc, 0x19, 0x63, 0xf6, 0xf3, 0x2f, 0x56, - 0xa5, 0x9b, 0x22, 0x51, 0xca, 0xf8, 0x21, 0x48, - 0xa5, 0xf3, 0x28, 0x4b, 0xcb, 0xff, 0x22, 0x47, - 0xcb, 0x9b, 0x4a, 0x4a, 0xc9, 0xf2, 0x39, 0x56, - 0xcd, 0xeb, 0x3e, 0x22, 0xa5, 0xf3, 0x2b, 0x41, - 0xc6, 0xfe, 0xc1, 0xfe, 0xf6, 0xca, 0xc9, 0xe1, - 0xad, 0xc8, 0x1b, 0xa1, 0x66, 0x93, 0x19, 0x73, - 0x26, 0x58, 0x42, 0x71, 0xf4, 0x18, 0x89, 0x2a, - 0xf6, 0xca, 0xb5, 0xf5, 0x2c, 0xd8, 0x42, 0xdd, - 0x72, 0x12, 0x09, 0x26, 0x5a, 0x4c, 0xc3, 0x21, - 0x5a, 0x4c, 0xc3, 0x61, 0x59, 0x64, 0x9d, 0xab, - 0xe6, 0x63, 0xc9, 0xc9, 0xad, 0x10, 0xa9, 0xa3, - 0x49, 0x0b, 0x4b, 0x22, 0xa5, 0xcf, 0x22, 0x23, - 0xa4, 0x9b, 0x4a, 0xdd, 0x31, 0xbf, 0xe2, 0x23, - 0xa5, 0x9b, 0xcb, 0xe6, 0x35, 0x9a, 0x4a, 0x22, - 0xcf, 0x9d, 0x20, 0x23, 0xcf, 0x99, 0xb5, 0x76, - 0x81, 0x83, 0x20, 0x22, 0xcf, 0x9b, 0x20, 0x22, - 0xcd, 0x99, 0x4a, 0xe6, 0x96, 0x10, 0x96, 0x71, - 0xf6, 0xcb, 0x20, 0x23, 0xf5, 0xf1, 0x5a, 0x71, - 0xf5, 0x64, 0x1e, 0x06, 0x9d, 0x64, 0x1e, 0x06, - 0x8d, 0x5c, 0x49, 0x32, 0xa5, 0x9b, 0x4a, 0xdd, - 0xf1, 0xbf, 0x56, 0xa1, 0x61, 0xbf, 0x13, 0x78, - 0xf4, 0xc9, 0x1a, 0x11, 0x77, 0xc9, 0x22, 0x51, - 0xc0, 0xf5, 0x2e, 0xa9, 0x61, 0xc9, 0x22, 0x50, - 0xc0, 0xf8, 0x3c, 0xa9, 0x71, 0xc9, 0x1b, 0x72, - 0xf4, 0x64, 0x9d, 0xb1, 0x5a, 0x4c, 0xdf, 0xa1, - 0x61, 0x8b, 0x12, 0x78, 0xfc, 0xc8, 0x1f, 0x72, - 0x2e, 0x77, 0x1a, 0x42, 0xcf, 0x9f, 0x10, 0x72, - 0x2e, 0x47, 0xa2, 0x63, 0xa5, 0x9b, 0x4a, 0x48, - 0xa5, 0xf3, 0x26, 0x4e, 0xca, 0xf8, 0x22, 0x57, - 0xc4, 0xf7, 0x0b, 0x4a, 0xf3, 0xf2, 0x38, 0x56, - 0xf1, 0xcd, 0xb5, 0xf5, 0x26, 0x5f, 0x5a, 0x78, - 0xf7, 0xf1, 0x0a, 0x4a, 0xa5, 0x8b, 0x4a, 0x22, - 0xf7, 0xf1, 0x4a, 0xdd, 0x75, 0x12, 0x0e, 0x06, - 0x81, 0xc1, 0xd9, 0xca, 0xb5, 0x9b, 0x4a, 0x22, - 0xc4, 0xc0, 0xb5, 0xc1, 0xc5, 0xa8, 0x8a, 0x92, - 0xa1, 0x73, 0x5c, 0x22, 0xa5, 0x9b, 0x2b, 0xe1, - 0xc5, 0xc9, 0x19, 0x11, 0x65, 0x73, 0x40, 0x22, - 0xa5, 0x9b, 0x11, 0x78, 0xa6, 0x43, 0x61, 0xf2, - 0xd0, 0x74, 0x2b, 0xe1, 0x96, 0x52, 0x1b, 0x70, - 0xf6, 0x64, 0x3f, 0x22, 0x5a, 0xcf, 0x4f, 0x26, - 0x20, 0x5b, 0x34, 0x23, 0x66, 0x64, 0x1f, 0xd2, - 0xa5, 0x9b, 0x4a, 0x22, 0xa5, 0x9b, 0x4a, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x54, 0x58, - 0x2d, 0x6f, 0x41, 0x3f, 0x3f, 0x2d, 0x6f, 0x41, - 0x3f, 0x3f, 0x2d, 0x6f, 0x41, 0x3f, 0x3f, 0x2d, - 0x6f, 0x43, 0x42, 0x42, 0x50, 0x5f, 0x57, 0xc3, - 0x33, 0x5f, 0x37, 0x74, 0x78, 0x78, 0x78, 0x78, - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, - 0xeb, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x53, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x44, 0x73, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x44, 0x73, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x74, - 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x53, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, - 0x52, 0x6f, 0x6f, 0x74, 0x50, 0x61, 0x74, 0x68, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x44, 0x6e, 0x73, 0x44, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0x65, 0x66, 0x31, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x72, 0x65, 0x66, 0x32, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x01, 0x02, 0x03, 0x04 - }; - - uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); - uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); - uint32_t dcerpc_request_len = sizeof(dcerpc_request); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_opnum:9; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_bind, dcerpc_bind_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - dcerpc_bindack, dcerpc_bindack_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_EOF, - dcerpc_request, dcerpc_request_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) - goto end; - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test a valid dce_opnum entry with only a request frag. - */ -static int DetectDceOpnumTestParse09(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - /* todo chop the request frag length and change the - * length related parameters in the frag */ - uint8_t dcerpc_request[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xec, 0x0c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xd4, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xe1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe1, 0x03, 0x00, 0x00, 0x83, 0xc7, 0x0b, 0x47, - 0x47, 0x47, 0x47, 0x81, 0x37, 0x22, 0xa5, 0x9b, - 0x4a, 0x75, 0xf4, 0xa3, 0x61, 0xd3, 0xbe, 0xdd, - 0x5a, 0xfb, 0x20, 0x1e, 0xfc, 0x10, 0x8e, 0x0f, - 0xa5, 0x9f, 0x4a, 0x22, 0x20, 0x9b, 0xa8, 0xd5, - 0xc4, 0xff, 0xc1, 0x3f, 0xbd, 0x9b, 0x4a, 0x22, - 0x2e, 0xc0, 0x7a, 0xa9, 0xfe, 0x97, 0xc9, 0xe1, - 0xa9, 0xf3, 0x2f, 0x22, 0xc9, 0x9b, 0x22, 0x50, - 0xa5, 0xf5, 0x4a, 0x4a, 0xce, 0x9b, 0x2f, 0x22, - 0x2e, 0x6f, 0xc1, 0xe1, 0xf3, 0xa8, 0x83, 0xa2, - 0x64, 0x98, 0xc1, 0x62, 0xa1, 0xa0, 0x89, 0x56, - 0xa8, 0x1b, 0x8b, 0x2b, 0x2e, 0xe3, 0x7a, 0xd1, - 0x03, 0xef, 0x58, 0x7c, 0x4e, 0x7d, 0x14, 0x76, - 0xfa, 0xc3, 0x7f, 0x02, 0xa5, 0xbb, 0x4a, 0x89, - 0x47, 0x6c, 0x12, 0xc9, 0x70, 0x18, 0x8e, 0x3a, - 0x2e, 0xcb, 0x52, 0xa9, 0x67, 0x98, 0x0a, 0x1e, - 0x2e, 0xc3, 0x32, 0x21, 0x7f, 0x10, 0x31, 0x3e, - 0xa6, 0x61, 0xc1, 0x61, 0x85, 0x98, 0x88, 0xa9, - 0xee, 0x83, 0x22, 0x51, 0xd6, 0xda, 0x4a, 0x4a, - 0xc1, 0xff, 0x38, 0x47, 0xcd, 0xe9, 0x25, 0x41, - 0xe4, 0xf3, 0x0d, 0x47, 0xd1, 0xcb, 0xc1, 0xd6, - 0x1e, 0x95, 0x4a, 0x22, 0xa5, 0x73, 0x08, 0x22, - 0xa5, 0x9b, 0xc9, 0xe6, 0xb5, 0xcd, 0x22, 0x43, - 0xd7, 0xe2, 0x0b, 0x4a, 0xe9, 0xf2, 0x28, 0x50, - 0xcd, 0xd7, 0x25, 0x43, 0xc1, 0x10, 0xbe, 0x99, - 0xa9, 0x9b, 0x4a, 0x22, 0x4d, 0xb8, 0x4a, 0x22, - 0xa5, 0x18, 0x8e, 0x2e, 0xf3, 0xc9, 0x22, 0x4e, - 0xc9, 0x9b, 0x4a, 0x4a, 0x96, 0xa9, 0x64, 0x46, - 0xcd, 0xec, 0x39, 0x10, 0xfa, 0xcf, 0xb5, 0x76, - 0x81, 0x8f, 0xc9, 0xe6, 0xa9, 0x10, 0x82, 0x7c, - 0xff, 0xc4, 0xa1, 0x0a, 0xf5, 0xcc, 0x1b, 0x74, - 0xf4, 0x10, 0x81, 0xa9, 0x9d, 0x98, 0xb0, 0xa1, - 0x65, 0x9f, 0xb9, 0x84, 0xd1, 0x9f, 0x13, 0x7c, - 0x47, 0x76, 0x12, 0x7c, 0xfc, 0x10, 0xbb, 0x09, - 0x55, 0x5a, 0xac, 0x20, 0xfa, 0x10, 0x7e, 0x15, - 0xa6, 0x69, 0x12, 0xe1, 0xf7, 0xca, 0x22, 0x57, - 0xd5, 0x9b, 0x4a, 0x4a, 0xd1, 0xfa, 0x38, 0x56, - 0xcd, 0xcc, 0x19, 0x63, 0xf6, 0xf3, 0x2f, 0x56, - 0xa5, 0x9b, 0x22, 0x51, 0xca, 0xf8, 0x21, 0x48, - 0xa5, 0xf3, 0x28, 0x4b, 0xcb, 0xff, 0x22, 0x47, - 0xcb, 0x9b, 0x4a, 0x4a, 0xc9, 0xf2, 0x39, 0x56, - 0xcd, 0xeb, 0x3e, 0x22, 0xa5, 0xf3, 0x2b, 0x41, - 0xc6, 0xfe, 0xc1, 0xfe, 0xf6, 0xca, 0xc9, 0xe1, - 0xad, 0xc8, 0x1b, 0xa1, 0x66, 0x93, 0x19, 0x73, - 0x26, 0x58, 0x42, 0x71, 0xf4, 0x18, 0x89, 0x2a, - 0xf6, 0xca, 0xb5, 0xf5, 0x2c, 0xd8, 0x42, 0xdd, - 0x72, 0x12, 0x09, 0x26, 0x5a, 0x4c, 0xc3, 0x21, - 0x5a, 0x4c, 0xc3, 0x61, 0x59, 0x64, 0x9d, 0xab, - 0xe6, 0x63, 0xc9, 0xc9, 0xad, 0x10, 0xa9, 0xa3, - 0x49, 0x0b, 0x4b, 0x22, 0xa5, 0xcf, 0x22, 0x23, - 0xa4, 0x9b, 0x4a, 0xdd, 0x31, 0xbf, 0xe2, 0x23, - 0xa5, 0x9b, 0xcb, 0xe6, 0x35, 0x9a, 0x4a, 0x22, - 0xcf, 0x9d, 0x20, 0x23, 0xcf, 0x99, 0xb5, 0x76, - 0x81, 0x83, 0x20, 0x22, 0xcf, 0x9b, 0x20, 0x22, - 0xcd, 0x99, 0x4a, 0xe6, 0x96, 0x10, 0x96, 0x71, - 0xf6, 0xcb, 0x20, 0x23, 0xf5, 0xf1, 0x5a, 0x71, - 0xf5, 0x64, 0x1e, 0x06, 0x9d, 0x64, 0x1e, 0x06, - 0x8d, 0x5c, 0x49, 0x32, 0xa5, 0x9b, 0x4a, 0xdd, - 0xf1, 0xbf, 0x56, 0xa1, 0x61, 0xbf, 0x13, 0x78, - 0xf4, 0xc9, 0x1a, 0x11, 0x77, 0xc9, 0x22, 0x51, - 0xc0, 0xf5, 0x2e, 0xa9, 0x61, 0xc9, 0x22, 0x50, - 0xc0, 0xf8, 0x3c, 0xa9, 0x71, 0xc9, 0x1b, 0x72, - 0xf4, 0x64, 0x9d, 0xb1, 0x5a, 0x4c, 0xdf, 0xa1, - 0x61, 0x8b, 0x12, 0x78, 0xfc, 0xc8, 0x1f, 0x72, - 0x2e, 0x77, 0x1a, 0x42, 0xcf, 0x9f, 0x10, 0x72, - 0x2e, 0x47, 0xa2, 0x63, 0xa5, 0x9b, 0x4a, 0x48, - 0xa5, 0xf3, 0x26, 0x4e, 0xca, 0xf8, 0x22, 0x57, - 0xc4, 0xf7, 0x0b, 0x4a, 0xf3, 0xf2, 0x38, 0x56, - 0xf1, 0xcd, 0xb5, 0xf5, 0x26, 0x5f, 0x5a, 0x78, - 0xf7, 0xf1, 0x0a, 0x4a, 0xa5, 0x8b, 0x4a, 0x22, - 0xf7, 0xf1, 0x4a, 0xdd, 0x75, 0x12, 0x0e, 0x06, - 0x81, 0xc1, 0xd9, 0xca, 0xb5, 0x9b, 0x4a, 0x22, - 0xc4, 0xc0, 0xb5, 0xc1, 0xc5, 0xa8, 0x8a, 0x92, - 0xa1, 0x73, 0x5c, 0x22, 0xa5, 0x9b, 0x2b, 0xe1, - 0xc5, 0xc9, 0x19, 0x11, 0x65, 0x73, 0x40, 0x22, - 0xa5, 0x9b, 0x11, 0x78, 0xa6, 0x43, 0x61, 0xf2, - 0xd0, 0x74, 0x2b, 0xe1, 0x96, 0x52, 0x1b, 0x70, - 0xf6, 0x64, 0x3f, 0x22, 0x5a, 0xcf, 0x4f, 0x26, - 0x20, 0x5b, 0x34, 0x23, 0x66, 0x64, 0x1f, 0xd2, - 0xa5, 0x9b, 0x4a, 0x22, 0xa5, 0x9b, 0x4a, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x54, 0x58, - 0x2d, 0x6f, 0x41, 0x3f, 0x3f, 0x2d, 0x6f, 0x41, - 0x3f, 0x3f, 0x2d, 0x6f, 0x41, 0x3f, 0x3f, 0x2d, - 0x6f, 0x43, 0x42, 0x42, 0x50, 0x5f, 0x57, 0xc3, - 0x33, 0x5f, 0x37, 0x74, 0x78, 0x78, 0x78, 0x78, - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, - 0xeb, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x53, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x44, 0x73, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x44, 0x73, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x74, - 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x53, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, - 0x52, 0x6f, 0x6f, 0x74, 0x50, 0x61, 0x74, 0x68, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x44, 0x6e, 0x73, 0x44, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0x65, 0x66, 0x31, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x72, 0x65, 0x66, 0x32, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x01, 0x02, 0x03, 0x04 - }; - - uint32_t dcerpc_request_len = sizeof(dcerpc_request); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_opnum:9; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_request, dcerpc_request_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) - goto end; - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -/* Disabled because of bug_753. Would be enabled, once we rewrite - * dce parser */ -#if 0 - -/** - * \test Test a valid dce_opnum(with multiple values) with a bind, bind_ack, - * and multiple request/responses with a match test after each frag parsing. - */ -static int DetectDceOpnumTestParse10(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x01, 0xd0, 0x8c, 0x33, 0x44, 0x22, 0xf1, 0x31, - 0xaa, 0xaa, 0x90, 0x00, 0x38, 0x00, 0x10, 0x03, - 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_bindack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x65, 0x8e, 0x00, 0x00, - 0x0d, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x77, 0x69, 0x6e, 0x72, 0x65, 0x67, 0x00, 0x6d, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x02, - }; - - uint8_t dcerpc_response1[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00, - 0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00, - 0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00, - 0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, - 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, - 0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00, - 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00, - 0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00, - 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, - 0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00, - 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, - 0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response2[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request3[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00, - 0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00, - 0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00, - 0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response3[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); - uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); - - uint32_t dcerpc_request1_len = sizeof(dcerpc_request1); - uint32_t dcerpc_response1_len = sizeof(dcerpc_response1); - - uint32_t dcerpc_request2_len = sizeof(dcerpc_request2); - uint32_t dcerpc_response2_len = sizeof(dcerpc_response2); - - uint32_t dcerpc_request3_len = sizeof(dcerpc_request3); - uint32_t dcerpc_response3_len = sizeof(dcerpc_response3); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"DCERPC\"; dce_opnum:2,15,22; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCLogDebug("sending bind"); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_bind, dcerpc_bind_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc bind failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - SCLogDebug("sending bind_ack"); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - dcerpc_bindack, dcerpc_bindack_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - SCLogDebug("sending request1"); - - /* request1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - dcerpc_request1, dcerpc_request1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't match, but should have: "); - goto end; - } - - SCLogDebug("sending response1"); - - /* response1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - dcerpc_response1, dcerpc_response1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 did match, shouldn't have on response1: "); - goto end; - } - - /* request2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - dcerpc_request2, dcerpc_request2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't match, but should have on request2: "); - goto end; - } - - /* response2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - dcerpc_response2, dcerpc_response2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 did match, shouldn't have on response2: "); - goto end; - } - - /* request3 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - dcerpc_request3, dcerpc_request3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't match, but should have on request3: "); - goto end; - } - - /* response3 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF, - dcerpc_response3, dcerpc_response3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 did match, shouldn't have on response2: "); - goto end; - } - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerDestroyCtxThread(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test a valid dce_opnum entry(with multiple values) with multiple - * request/responses. - */ -static int DetectDceOpnumTestParse11(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x02, - }; - - uint8_t dcerpc_response1[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00, - 0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00, - 0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00, - 0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, - 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, - 0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00, - 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00, - 0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00, - 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, - 0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00, - 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, - 0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response2[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request3[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00, - 0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00, - 0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00, - 0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response3[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - uint32_t dcerpc_request1_len = sizeof(dcerpc_request1); - uint32_t dcerpc_response1_len = sizeof(dcerpc_response1); - - uint32_t dcerpc_request2_len = sizeof(dcerpc_request2); - uint32_t dcerpc_response2_len = sizeof(dcerpc_response2); - - uint32_t dcerpc_request3_len = sizeof(dcerpc_request3); - uint32_t dcerpc_response3_len = sizeof(dcerpc_response3); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_opnum:2-22; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* request1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_request1, dcerpc_request1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - printf("AppLayerParse for dcerpcrequest1 failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - printf("no dcerpc state: "); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) - goto end; - - /* response1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - dcerpc_response1, dcerpc_response1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - printf("AppLayerParse for dcerpcresponse1 failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - - /* request2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - dcerpc_request2, dcerpc_request2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - printf("AppLayerParse for dcerpcrequest2 failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) - goto end; - - /* response2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - dcerpc_response2, dcerpc_response2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - printf("AppLayerParse for dcerpcresponse2 failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - - /* request3 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - dcerpc_request3, dcerpc_request3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - printf("AppLayerParse for dcerpc request3 failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) - goto end; - - /* response3 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF, - dcerpc_response3, dcerpc_response3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - printf("AppLayerParse for dcerpc response3 failed. Returned %" PRId32, r); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerDestroyCtxThread(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test a valid dce_opnum(with multiple values) with a bind, bind_ack, - * and multiple request/responses with a match test after each frag parsing. - */ -static int DetectDceOpnumTestParse12(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x40, 0xfd, 0x2c, 0x34, 0x6c, 0x3c, 0xce, 0x11, - 0xa8, 0x93, 0x08, 0x00, 0x2b, 0x2e, 0x9c, 0x6d, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_bindack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x7d, 0xd8, 0x00, 0x00, - 0x0d, 0x00, 0x5c, 0x70, 0x69, 0x70, 0x65, 0x5c, - 0x6c, 0x6c, 0x73, 0x72, 0x70, 0x63, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, //opnum is 0x28 0x00 - 0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9, - 0x2d, 0x97, 0xf4, 0x4a, 0xac, 0xc2, 0xbc, 0x70, - 0xec, 0xaa, 0x9a, 0xd3, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x40, 0x80, 0x40, 0x00, - 0x44, 0x80, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x00, 0x4e, - 0x61, 0x6d, 0x65, 0x00, 0x35, 0x39, 0x31, 0x63, - 0x64, 0x30, 0x35, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0xd0, 0x2e, 0x08, 0x00, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x00, 0x00 - }; - - uint8_t dcerpc_response1[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9, - 0x2d, 0x97, 0xf4, 0x4a, 0xac, 0xc2, 0xbc, 0x70, - 0xec, 0xaa, 0x9a, 0xd3, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x4d, 0x6f, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, - 0x35, 0x39, 0x31, 0x63, 0x64, 0x30, 0x35, 0x38, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x4e, 0x6f, 0x6e, 0x65 - }; - - uint8_t dcerpc_response2[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd8, 0x17, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x58, 0x1d, 0x08, 0x00, 0xe8, 0x32, 0x08, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x4d, 0x6f, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, - 0x35, 0x39, 0x31, 0x63, 0x64, 0x30, 0x35, 0x38, - 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0xd0, 0x2e, 0x08, 0x00, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); - uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); - - uint32_t dcerpc_request1_len = sizeof(dcerpc_request1); - uint32_t dcerpc_response1_len = sizeof(dcerpc_response1); - - uint32_t dcerpc_request2_len = sizeof(dcerpc_request2); - uint32_t dcerpc_response2_len = sizeof(dcerpc_response2); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"DCERPC\"; dce_opnum:30, 40; sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_bind, dcerpc_bind_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack, - dcerpc_bindack_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* request1 */ - SCLogDebug("Sending request1"); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1, - dcerpc_request1_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 40) { - printf("dcerpc state holding invalid opnum. Holding %d, while we are " - "expecting 40: ", dcerpc_state->dcerpc.dcerpcrequest.opnum); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("signature 1 didn't match, should have: "); - goto end; - } - - /* response1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1, - dcerpc_response1_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 40) { - printf("dcerpc state holding invalid opnum. Holding %d, while we are " - "expecting 40\n", dcerpc_state->dcerpc.dcerpcrequest.opnum); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched on response 1, but shouldn't: "); - goto end; - } - - /* request2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2, - dcerpc_request2_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 30) { - printf("dcerpc state holding invalid opnum. Holding %d, while we are " - "expecting 30\n", dcerpc_state->dcerpc.dcerpcrequest.opnum); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't match on request 2: "); - goto end; - } - - /* response2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF, dcerpc_response2, - dcerpc_response2_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 30) { - printf("dcerpc state holding invalid opnum. Holding %d, while we are " - "expecting 30\n", dcerpc_state->dcerpc.dcerpcrequest.opnum); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched on response2, but shouldn't: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerDestroyCtxThread(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test a valid dce_opnum(with multiple values) with a bind, bind_ack, - * and multiple request/responses with a match test after each frag parsing. - */ -static int DetectDceOpnumTestParse13(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9, - 0x2d, 0x97, 0xf4, 0x4a, 0xac, 0xc2, 0xbc, 0x70, - 0xec, 0xaa, 0x9a, 0xd3, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x40, 0x80, 0x40, 0x00, - 0x44, 0x80, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x4d, 0x6f, 0x00, 0x4e, - 0x61, 0x6d, 0x65, 0x00, 0x35, 0x39, 0x31, 0x63, - 0x64, 0x30, 0x35, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x17, 0x00, 0x00, 0x00, 0xd0, 0x2e, 0x08, 0x00, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x00, 0x00 - }; - - uint8_t dcerpc_response1[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x9f, 0x13, 0xd9, - 0x2d, 0x97, 0xf4, 0x4a, 0xac, 0xc2, 0xbc, 0x70, - 0xec, 0xaa, 0x9a, 0xd3, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x4d, 0x6f, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, - 0x35, 0x39, 0x31, 0x63, 0x64, 0x30, 0x35, 0x38, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x4e, 0x6f, 0x6e, 0x65 - }; - - uint8_t dcerpc_response2[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x8c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd8, 0x17, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x58, 0x1d, 0x08, 0x00, 0xe8, 0x32, 0x08, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x4d, 0x6f, 0x00, 0x4e, 0x61, 0x6d, 0x65, 0x00, - 0x35, 0x39, 0x31, 0x63, 0x64, 0x30, 0x35, 0x38, - 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, - 0xd0, 0x2e, 0x08, 0x00, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - uint32_t dcerpc_request1_len = sizeof(dcerpc_request1); - uint32_t dcerpc_response1_len = sizeof(dcerpc_response1); - - uint32_t dcerpc_request2_len = sizeof(dcerpc_request2); - uint32_t dcerpc_response2_len = sizeof(dcerpc_response2); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_opnum:30, 40; " - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* request1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1, - dcerpc_request1_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 40) { - printf("dcerpc state holding invalid opnum after request1. Holding %d, while we are " - "expecting 40\n", dcerpc_state->dcerpc.dcerpcrequest.opnum); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) - goto end; - - /* response1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1, - dcerpc_response1_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 40) { - printf("dcerpc state holding invalid opnum after response1. Holding %d, while we are " - "expecting 40\n", dcerpc_state->dcerpc.dcerpcrequest.opnum); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - - /* request2 */ - printf("Sending Request2\n"); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2, - dcerpc_request2_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 30) { - printf("dcerpc state holding invalid opnum after request2. Holding %d, while we are " - "expecting 30\n", dcerpc_state->dcerpc.dcerpcrequest.opnum); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) - goto end; - - /* response2 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF, dcerpc_response2, - dcerpc_response2_len); - if (r != 0) { - printf("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - goto end; - } - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - printf("no dcerpc state: "); - goto end; - } - - if (dcerpc_state->dcerpc.dcerpcrequest.opnum != 30) { - printf("dcerpc state holding invalid opnum after response2. Holding %d, while we are " - "expecting 30\n", dcerpc_state->dcerpc.dcerpcrequest.opnum); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerDestroyCtxThread(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} -#endif - - -#endif -void DetectDceOpnumRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectDceOpnumTestParse01", DetectDceOpnumTestParse01, 1); - UtRegisterTest("DetectDceOpnumTestParse02", DetectDceOpnumTestParse02, 1); - UtRegisterTest("DetectDceOpnumTestParse03", DetectDceOpnumTestParse03, 1); - UtRegisterTest("DetectDceOpnumTestParse04", DetectDceOpnumTestParse04, 1); - UtRegisterTest("DetectDceOpnumTestParse05", DetectDceOpnumTestParse05, 1); - UtRegisterTest("DetectDceOpnumTestParse06", DetectDceOpnumTestParse06, 1); - UtRegisterTest("DetectDceOpnumTestParse07", DetectDceOpnumTestParse07, 1); - UtRegisterTest("DetectDceOpnumTestParse08", DetectDceOpnumTestParse08, 1); - UtRegisterTest("DetectDceOpnumTestParse09", DetectDceOpnumTestParse09, 1); - /* Disabled because of bug_753. Would be enabled, once we rewrite - * dce parser */ -#if 0 - UtRegisterTest("DetectDceOpnumTestParse10", DetectDceOpnumTestParse10, 1); - UtRegisterTest("DetectDceOpnumTestParse11", DetectDceOpnumTestParse11, 1); - UtRegisterTest("DetectDceOpnumTestParse12", DetectDceOpnumTestParse12, 1); - UtRegisterTest("DetectDceOpnumTestParse13", DetectDceOpnumTestParse13, 1); -#endif -#endif - - return; -} diff --git a/framework/src/suricata/src/detect-dce-opnum.h b/framework/src/suricata/src/detect-dce-opnum.h deleted file mode 100644 index a4c1a9b7..00000000 --- a/framework/src/suricata/src/detect-dce-opnum.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_DCE_OPNUM_H__ -#define __DETECT_DCE_OPNUM_H__ - -#define DCE_OPNUM_RANGE_MAX 65535 -#define DCE_OPNUM_RANGE_UNINITIALIZED 100000 - -typedef struct DetectDceOpnumRange_ { - uint32_t range1; - uint32_t range2; - struct DetectDceOpnumRange_ *next; -} DetectDceOpnumRange; - -typedef struct DetectDceOpnumData_ { - DetectDceOpnumRange *range; -} DetectDceOpnumData; - -void DetectDceOpnumRegister(void); -void DetectDceOpnumRegisterTests(void); - -#endif /* __DETECT_DCE_OPNUM_H__ */ diff --git a/framework/src/suricata/src/detect-dce-stub-data.c b/framework/src/suricata/src/detect-dce-stub-data.c deleted file mode 100644 index d5e660eb..00000000 --- a/framework/src/suricata/src/detect-dce-stub-data.c +++ /dev/null @@ -1,1848 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements dce_stub_data keyword - */ - -#include "suricata-common.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "app-layer.h" -#include "app-layer-dcerpc.h" -#include "queue.h" -#include "stream-tcp-reassemble.h" -#include "detect-dce-stub-data.h" - -#include "util-debug.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "stream-tcp.h" - -int DetectDceStubDataMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, - void *, Signature *, SigMatch *); -static int DetectDceStubDataSetup(DetectEngineCtx *, Signature *, char *); - -/** - * \brief Registers the keyword handlers for the "dce_stub_data" keyword. - */ -void DetectDceStubDataRegister(void) -{ - sigmatch_table[DETECT_DCE_STUB_DATA].name = "dce_stub_data"; - sigmatch_table[DETECT_DCE_STUB_DATA].alproto = ALPROTO_DCERPC; - sigmatch_table[DETECT_DCE_STUB_DATA].Match = NULL; - sigmatch_table[DETECT_DCE_STUB_DATA].AppLayerMatch = NULL; - sigmatch_table[DETECT_DCE_STUB_DATA].Setup = DetectDceStubDataSetup; - sigmatch_table[DETECT_DCE_STUB_DATA].Free = NULL; - sigmatch_table[DETECT_DCE_STUB_DATA].RegisterTests = DetectDceStubDataRegisterTests; - - sigmatch_table[DETECT_DCE_STUB_DATA].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_DCE_STUB_DATA].flags |= SIGMATCH_PAYLOAD; - - return; -} - -/** - * \brief Creates a SigMatch for the \"dce_stub_data\" keyword being sent as argument, - * and appends it to the Signature(s). - * - * \param de_ctx Pointer to the detection engine context - * \param s Pointer to signature for the current Signature being parsed - * from the rules - * \param arg Pointer to the string holding the keyword value - * - * \retval 0 on success, -1 on failure - */ - -static int DetectDceStubDataSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_DCERPC) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, - "rule contains conflicting keywords."); - goto error; - } - - s->list = DETECT_SM_LIST_DMATCH; - s->alproto = ALPROTO_DCERPC; - s->flags |= SIG_FLAG_APPLAYER; - return 0; - - error: - return -1; -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -static int DetectDceStubDataTestParse01(void) -{ - Signature s; - int result = 0; - - memset(&s, 0, sizeof(Signature)); - - result = (DetectDceStubDataSetup(NULL, &s, NULL) == 0); - - if (s.sm_lists[DETECT_SM_LIST_AMATCH] == NULL) { - result = 1; - } else { - result = 0; - } - - return result; -} - -/** - * \test Test a valid dce_stub_data entry with bind, bind_ack, request frags. - */ -static int DetectDceStubDataTestParse02(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_bindack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x26, 0x3d, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - - /* todo chop the request frag length and change the - * length related parameters in the frag */ - uint8_t dcerpc_request[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xec, 0x0c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xd4, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xe1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe1, 0x03, 0x00, 0x00, 0x83, 0xc7, 0x0b, 0x47, - 0x47, 0x47, 0x47, 0x81, 0x37, 0x22, 0xa5, 0x9b, - 0x4a, 0x75, 0xf4, 0xa3, 0x61, 0xd3, 0xbe, 0xdd, - 0x5a, 0xfb, 0x20, 0x1e, 0xfc, 0x10, 0x8e, 0x0f, - 0xa5, 0x9f, 0x4a, 0x22, 0x20, 0x9b, 0xa8, 0xd5, - 0xc4, 0xff, 0xc1, 0x3f, 0xbd, 0x9b, 0x4a, 0x22, - 0x2e, 0xc0, 0x7a, 0xa9, 0xfe, 0x97, 0xc9, 0xe1, - 0xa9, 0xf3, 0x2f, 0x22, 0xc9, 0x9b, 0x22, 0x50, - 0xa5, 0xf5, 0x4a, 0x4a, 0xce, 0x9b, 0x2f, 0x22, - 0x2e, 0x6f, 0xc1, 0xe1, 0xf3, 0xa8, 0x83, 0xa2, - 0x64, 0x98, 0xc1, 0x62, 0xa1, 0xa0, 0x89, 0x56, - 0xa8, 0x1b, 0x8b, 0x2b, 0x2e, 0xe3, 0x7a, 0xd1, - 0x03, 0xef, 0x58, 0x7c, 0x4e, 0x7d, 0x14, 0x76, - 0xfa, 0xc3, 0x7f, 0x02, 0xa5, 0xbb, 0x4a, 0x89, - 0x47, 0x6c, 0x12, 0xc9, 0x70, 0x18, 0x8e, 0x3a, - 0x2e, 0xcb, 0x52, 0xa9, 0x67, 0x98, 0x0a, 0x1e, - 0x2e, 0xc3, 0x32, 0x21, 0x7f, 0x10, 0x31, 0x3e, - 0xa6, 0x61, 0xc1, 0x61, 0x85, 0x98, 0x88, 0xa9, - 0xee, 0x83, 0x22, 0x51, 0xd6, 0xda, 0x4a, 0x4a, - 0xc1, 0xff, 0x38, 0x47, 0xcd, 0xe9, 0x25, 0x41, - 0xe4, 0xf3, 0x0d, 0x47, 0xd1, 0xcb, 0xc1, 0xd6, - 0x1e, 0x95, 0x4a, 0x22, 0xa5, 0x73, 0x08, 0x22, - 0xa5, 0x9b, 0xc9, 0xe6, 0xb5, 0xcd, 0x22, 0x43, - 0xd7, 0xe2, 0x0b, 0x4a, 0xe9, 0xf2, 0x28, 0x50, - 0xcd, 0xd7, 0x25, 0x43, 0xc1, 0x10, 0xbe, 0x99, - 0xa9, 0x9b, 0x4a, 0x22, 0x4d, 0xb8, 0x4a, 0x22, - 0xa5, 0x18, 0x8e, 0x2e, 0xf3, 0xc9, 0x22, 0x4e, - 0xc9, 0x9b, 0x4a, 0x4a, 0x96, 0xa9, 0x64, 0x46, - 0xcd, 0xec, 0x39, 0x10, 0xfa, 0xcf, 0xb5, 0x76, - 0x81, 0x8f, 0xc9, 0xe6, 0xa9, 0x10, 0x82, 0x7c, - 0xff, 0xc4, 0xa1, 0x0a, 0xf5, 0xcc, 0x1b, 0x74, - 0xf4, 0x10, 0x81, 0xa9, 0x9d, 0x98, 0xb0, 0xa1, - 0x65, 0x9f, 0xb9, 0x84, 0xd1, 0x9f, 0x13, 0x7c, - 0x47, 0x76, 0x12, 0x7c, 0xfc, 0x10, 0xbb, 0x09, - 0x55, 0x5a, 0xac, 0x20, 0xfa, 0x10, 0x7e, 0x15, - 0xa6, 0x69, 0x12, 0xe1, 0xf7, 0xca, 0x22, 0x57, - 0xd5, 0x9b, 0x4a, 0x4a, 0xd1, 0xfa, 0x38, 0x56, - 0xcd, 0xcc, 0x19, 0x63, 0xf6, 0xf3, 0x2f, 0x56, - 0xa5, 0x9b, 0x22, 0x51, 0xca, 0xf8, 0x21, 0x48, - 0xa5, 0xf3, 0x28, 0x4b, 0xcb, 0xff, 0x22, 0x47, - 0xcb, 0x9b, 0x4a, 0x4a, 0xc9, 0xf2, 0x39, 0x56, - 0xcd, 0xeb, 0x3e, 0x22, 0xa5, 0xf3, 0x2b, 0x41, - 0xc6, 0xfe, 0xc1, 0xfe, 0xf6, 0xca, 0xc9, 0xe1, - 0xad, 0xc8, 0x1b, 0xa1, 0x66, 0x93, 0x19, 0x73, - 0x26, 0x58, 0x42, 0x71, 0xf4, 0x18, 0x89, 0x2a, - 0xf6, 0xca, 0xb5, 0xf5, 0x2c, 0xd8, 0x42, 0xdd, - 0x72, 0x12, 0x09, 0x26, 0x5a, 0x4c, 0xc3, 0x21, - 0x5a, 0x4c, 0xc3, 0x61, 0x59, 0x64, 0x9d, 0xab, - 0xe6, 0x63, 0xc9, 0xc9, 0xad, 0x10, 0xa9, 0xa3, - 0x49, 0x0b, 0x4b, 0x22, 0xa5, 0xcf, 0x22, 0x23, - 0xa4, 0x9b, 0x4a, 0xdd, 0x31, 0xbf, 0xe2, 0x23, - 0xa5, 0x9b, 0xcb, 0xe6, 0x35, 0x9a, 0x4a, 0x22, - 0xcf, 0x9d, 0x20, 0x23, 0xcf, 0x99, 0xb5, 0x76, - 0x81, 0x83, 0x20, 0x22, 0xcf, 0x9b, 0x20, 0x22, - 0xcd, 0x99, 0x4a, 0xe6, 0x96, 0x10, 0x96, 0x71, - 0xf6, 0xcb, 0x20, 0x23, 0xf5, 0xf1, 0x5a, 0x71, - 0xf5, 0x64, 0x1e, 0x06, 0x9d, 0x64, 0x1e, 0x06, - 0x8d, 0x5c, 0x49, 0x32, 0xa5, 0x9b, 0x4a, 0xdd, - 0xf1, 0xbf, 0x56, 0xa1, 0x61, 0xbf, 0x13, 0x78, - 0xf4, 0xc9, 0x1a, 0x11, 0x77, 0xc9, 0x22, 0x51, - 0xc0, 0xf5, 0x2e, 0xa9, 0x61, 0xc9, 0x22, 0x50, - 0xc0, 0xf8, 0x3c, 0xa9, 0x71, 0xc9, 0x1b, 0x72, - 0xf4, 0x64, 0x9d, 0xb1, 0x5a, 0x4c, 0xdf, 0xa1, - 0x61, 0x8b, 0x12, 0x78, 0xfc, 0xc8, 0x1f, 0x72, - 0x2e, 0x77, 0x1a, 0x42, 0xcf, 0x9f, 0x10, 0x72, - 0x2e, 0x47, 0xa2, 0x63, 0xa5, 0x9b, 0x4a, 0x48, - 0xa5, 0xf3, 0x26, 0x4e, 0xca, 0xf8, 0x22, 0x57, - 0xc4, 0xf7, 0x0b, 0x4a, 0xf3, 0xf2, 0x38, 0x56, - 0xf1, 0xcd, 0xb5, 0xf5, 0x26, 0x5f, 0x5a, 0x78, - 0xf7, 0xf1, 0x0a, 0x4a, 0xa5, 0x8b, 0x4a, 0x22, - 0xf7, 0xf1, 0x4a, 0xdd, 0x75, 0x12, 0x0e, 0x06, - 0x81, 0xc1, 0xd9, 0xca, 0xb5, 0x9b, 0x4a, 0x22, - 0xc4, 0xc0, 0xb5, 0xc1, 0xc5, 0xa8, 0x8a, 0x92, - 0xa1, 0x73, 0x5c, 0x22, 0xa5, 0x9b, 0x2b, 0xe1, - 0xc5, 0xc9, 0x19, 0x11, 0x65, 0x73, 0x40, 0x22, - 0xa5, 0x9b, 0x11, 0x78, 0xa6, 0x43, 0x61, 0xf2, - 0xd0, 0x74, 0x2b, 0xe1, 0x96, 0x52, 0x1b, 0x70, - 0xf6, 0x64, 0x3f, 0x22, 0x5a, 0xcf, 0x4f, 0x26, - 0x20, 0x5b, 0x34, 0x23, 0x66, 0x64, 0x1f, 0xd2, - 0xa5, 0x9b, 0x4a, 0x22, 0xa5, 0x9b, 0x4a, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x54, 0x58, - 0x2d, 0x6f, 0x41, 0x3f, 0x3f, 0x2d, 0x6f, 0x41, - 0x3f, 0x3f, 0x2d, 0x6f, 0x41, 0x3f, 0x3f, 0x2d, - 0x6f, 0x43, 0x42, 0x42, 0x50, 0x5f, 0x57, 0xc3, - 0x33, 0x5f, 0x37, 0x74, 0x78, 0x78, 0x78, 0x78, - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, - 0xeb, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x53, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x44, 0x73, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x44, 0x73, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x74, - 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x53, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, - 0x52, 0x6f, 0x6f, 0x74, 0x50, 0x61, 0x74, 0x68, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x44, 0x6e, 0x73, 0x44, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0x65, 0x66, 0x31, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x72, 0x65, 0x66, 0x32, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x01, 0x02, 0x03, 0x04 - }; - - uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); - uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); - uint32_t dcerpc_request_len = sizeof(dcerpc_request); - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_stub_data; content:\"|42 42 42 42|\";" - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_bind, dcerpc_bind_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* we shouldn't have any stub data */ - if (PacketAlertCheck(p, 1)) - goto end; - - /* do detect */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack, - dcerpc_bindack_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* we shouldn't have any stub data */ - if (PacketAlertCheck(p, 1)) - goto end; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_EOF, - dcerpc_request, dcerpc_request_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* we should have the stub data since we previously parsed a request frag */ - if (!PacketAlertCheck(p, 1)) - goto end; - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test a valid dce_stub_data with just a request frag. - */ -static int DetectDceStubDataTestParse03(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - /* todo chop the request frag length and change the - * length related parameters in the frag */ - uint8_t dcerpc_request[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xec, 0x0c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xd4, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xe1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe1, 0x03, 0x00, 0x00, 0x83, 0xc7, 0x0b, 0x47, - 0x47, 0x47, 0x47, 0x81, 0x37, 0x22, 0xa5, 0x9b, - 0x4a, 0x75, 0xf4, 0xa3, 0x61, 0xd3, 0xbe, 0xdd, - 0x5a, 0xfb, 0x20, 0x1e, 0xfc, 0x10, 0x8e, 0x0f, - 0xa5, 0x9f, 0x4a, 0x22, 0x20, 0x9b, 0xa8, 0xd5, - 0xc4, 0xff, 0xc1, 0x3f, 0xbd, 0x9b, 0x4a, 0x22, - 0x2e, 0xc0, 0x7a, 0xa9, 0xfe, 0x97, 0xc9, 0xe1, - 0xa9, 0xf3, 0x2f, 0x22, 0xc9, 0x9b, 0x22, 0x50, - 0xa5, 0xf5, 0x4a, 0x4a, 0xce, 0x9b, 0x2f, 0x22, - 0x2e, 0x6f, 0xc1, 0xe1, 0xf3, 0xa8, 0x83, 0xa2, - 0x64, 0x98, 0xc1, 0x62, 0xa1, 0xa0, 0x89, 0x56, - 0xa8, 0x1b, 0x8b, 0x2b, 0x2e, 0xe3, 0x7a, 0xd1, - 0x03, 0xef, 0x58, 0x7c, 0x4e, 0x7d, 0x14, 0x76, - 0xfa, 0xc3, 0x7f, 0x02, 0xa5, 0xbb, 0x4a, 0x89, - 0x47, 0x6c, 0x12, 0xc9, 0x70, 0x18, 0x8e, 0x3a, - 0x2e, 0xcb, 0x52, 0xa9, 0x67, 0x98, 0x0a, 0x1e, - 0x2e, 0xc3, 0x32, 0x21, 0x7f, 0x10, 0x31, 0x3e, - 0xa6, 0x61, 0xc1, 0x61, 0x85, 0x98, 0x88, 0xa9, - 0xee, 0x83, 0x22, 0x51, 0xd6, 0xda, 0x4a, 0x4a, - 0xc1, 0xff, 0x38, 0x47, 0xcd, 0xe9, 0x25, 0x41, - 0xe4, 0xf3, 0x0d, 0x47, 0xd1, 0xcb, 0xc1, 0xd6, - 0x1e, 0x95, 0x4a, 0x22, 0xa5, 0x73, 0x08, 0x22, - 0xa5, 0x9b, 0xc9, 0xe6, 0xb5, 0xcd, 0x22, 0x43, - 0xd7, 0xe2, 0x0b, 0x4a, 0xe9, 0xf2, 0x28, 0x50, - 0xcd, 0xd7, 0x25, 0x43, 0xc1, 0x10, 0xbe, 0x99, - 0xa9, 0x9b, 0x4a, 0x22, 0x4d, 0xb8, 0x4a, 0x22, - 0xa5, 0x18, 0x8e, 0x2e, 0xf3, 0xc9, 0x22, 0x4e, - 0xc9, 0x9b, 0x4a, 0x4a, 0x96, 0xa9, 0x64, 0x46, - 0xcd, 0xec, 0x39, 0x10, 0xfa, 0xcf, 0xb5, 0x76, - 0x81, 0x8f, 0xc9, 0xe6, 0xa9, 0x10, 0x82, 0x7c, - 0xff, 0xc4, 0xa1, 0x0a, 0xf5, 0xcc, 0x1b, 0x74, - 0xf4, 0x10, 0x81, 0xa9, 0x9d, 0x98, 0xb0, 0xa1, - 0x65, 0x9f, 0xb9, 0x84, 0xd1, 0x9f, 0x13, 0x7c, - 0x47, 0x76, 0x12, 0x7c, 0xfc, 0x10, 0xbb, 0x09, - 0x55, 0x5a, 0xac, 0x20, 0xfa, 0x10, 0x7e, 0x15, - 0xa6, 0x69, 0x12, 0xe1, 0xf7, 0xca, 0x22, 0x57, - 0xd5, 0x9b, 0x4a, 0x4a, 0xd1, 0xfa, 0x38, 0x56, - 0xcd, 0xcc, 0x19, 0x63, 0xf6, 0xf3, 0x2f, 0x56, - 0xa5, 0x9b, 0x22, 0x51, 0xca, 0xf8, 0x21, 0x48, - 0xa5, 0xf3, 0x28, 0x4b, 0xcb, 0xff, 0x22, 0x47, - 0xcb, 0x9b, 0x4a, 0x4a, 0xc9, 0xf2, 0x39, 0x56, - 0xcd, 0xeb, 0x3e, 0x22, 0xa5, 0xf3, 0x2b, 0x41, - 0xc6, 0xfe, 0xc1, 0xfe, 0xf6, 0xca, 0xc9, 0xe1, - 0xad, 0xc8, 0x1b, 0xa1, 0x66, 0x93, 0x19, 0x73, - 0x26, 0x58, 0x42, 0x71, 0xf4, 0x18, 0x89, 0x2a, - 0xf6, 0xca, 0xb5, 0xf5, 0x2c, 0xd8, 0x42, 0xdd, - 0x72, 0x12, 0x09, 0x26, 0x5a, 0x4c, 0xc3, 0x21, - 0x5a, 0x4c, 0xc3, 0x61, 0x59, 0x64, 0x9d, 0xab, - 0xe6, 0x63, 0xc9, 0xc9, 0xad, 0x10, 0xa9, 0xa3, - 0x49, 0x0b, 0x4b, 0x22, 0xa5, 0xcf, 0x22, 0x23, - 0xa4, 0x9b, 0x4a, 0xdd, 0x31, 0xbf, 0xe2, 0x23, - 0xa5, 0x9b, 0xcb, 0xe6, 0x35, 0x9a, 0x4a, 0x22, - 0xcf, 0x9d, 0x20, 0x23, 0xcf, 0x99, 0xb5, 0x76, - 0x81, 0x83, 0x20, 0x22, 0xcf, 0x9b, 0x20, 0x22, - 0xcd, 0x99, 0x4a, 0xe6, 0x96, 0x10, 0x96, 0x71, - 0xf6, 0xcb, 0x20, 0x23, 0xf5, 0xf1, 0x5a, 0x71, - 0xf5, 0x64, 0x1e, 0x06, 0x9d, 0x64, 0x1e, 0x06, - 0x8d, 0x5c, 0x49, 0x32, 0xa5, 0x9b, 0x4a, 0xdd, - 0xf1, 0xbf, 0x56, 0xa1, 0x61, 0xbf, 0x13, 0x78, - 0xf4, 0xc9, 0x1a, 0x11, 0x77, 0xc9, 0x22, 0x51, - 0xc0, 0xf5, 0x2e, 0xa9, 0x61, 0xc9, 0x22, 0x50, - 0xc0, 0xf8, 0x3c, 0xa9, 0x71, 0xc9, 0x1b, 0x72, - 0xf4, 0x64, 0x9d, 0xb1, 0x5a, 0x4c, 0xdf, 0xa1, - 0x61, 0x8b, 0x12, 0x78, 0xfc, 0xc8, 0x1f, 0x72, - 0x2e, 0x77, 0x1a, 0x42, 0xcf, 0x9f, 0x10, 0x72, - 0x2e, 0x47, 0xa2, 0x63, 0xa5, 0x9b, 0x4a, 0x48, - 0xa5, 0xf3, 0x26, 0x4e, 0xca, 0xf8, 0x22, 0x57, - 0xc4, 0xf7, 0x0b, 0x4a, 0xf3, 0xf2, 0x38, 0x56, - 0xf1, 0xcd, 0xb5, 0xf5, 0x26, 0x5f, 0x5a, 0x78, - 0xf7, 0xf1, 0x0a, 0x4a, 0xa5, 0x8b, 0x4a, 0x22, - 0xf7, 0xf1, 0x4a, 0xdd, 0x75, 0x12, 0x0e, 0x06, - 0x81, 0xc1, 0xd9, 0xca, 0xb5, 0x9b, 0x4a, 0x22, - 0xc4, 0xc0, 0xb5, 0xc1, 0xc5, 0xa8, 0x8a, 0x92, - 0xa1, 0x73, 0x5c, 0x22, 0xa5, 0x9b, 0x2b, 0xe1, - 0xc5, 0xc9, 0x19, 0x11, 0x65, 0x73, 0x40, 0x22, - 0xa5, 0x9b, 0x11, 0x78, 0xa6, 0x43, 0x61, 0xf2, - 0xd0, 0x74, 0x2b, 0xe1, 0x96, 0x52, 0x1b, 0x70, - 0xf6, 0x64, 0x3f, 0x22, 0x5a, 0xcf, 0x4f, 0x26, - 0x20, 0x5b, 0x34, 0x23, 0x66, 0x64, 0x1f, 0xd2, - 0xa5, 0x9b, 0x4a, 0x22, 0xa5, 0x9b, 0x4a, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x54, 0x58, - 0x2d, 0x6f, 0x41, 0x3f, 0x3f, 0x2d, 0x6f, 0x41, - 0x3f, 0x3f, 0x2d, 0x6f, 0x41, 0x3f, 0x3f, 0x2d, - 0x6f, 0x43, 0x42, 0x42, 0x50, 0x5f, 0x57, 0xc3, - 0x33, 0x5f, 0x37, 0x74, 0x78, 0x78, 0x78, 0x78, - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, - 0xeb, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x53, 0x69, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x44, 0x73, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x44, 0x73, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x74, - 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x53, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x56, 0x6f, 0x6c, 0x75, 0x6d, 0x65, - 0x52, 0x6f, 0x6f, 0x74, 0x50, 0x61, 0x74, 0x68, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x44, 0x6e, 0x73, 0x44, 0x6f, 0x6d, - 0x61, 0x69, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x50, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0x65, 0x66, 0x31, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x72, 0x65, 0x66, 0x32, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, - 0x01, 0x02, 0x03, 0x04 - }; - - uint32_t dcerpc_request_len = sizeof(dcerpc_request); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_stub_data; content:\"|42 42 42 42|\";" - "sid:1;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_request, dcerpc_request_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) - goto end; - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -static int DetectDceStubDataTestParse04(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x01, 0xd0, 0x8c, 0x33, 0x44, 0x22, 0xf1, 0x31, - 0xaa, 0xaa, 0x90, 0x00, 0x38, 0x00, 0x10, 0x03, - 0x01, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_bindack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x65, 0x8e, 0x00, 0x00, - 0x0d, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x77, 0x69, 0x6e, 0x72, 0x65, 0x67, 0x00, 0x6d, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x02, - }; - - uint8_t dcerpc_response1[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00, - 0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00, - 0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00, - 0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, - 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, - 0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00, - 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00, - 0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00, - 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, - 0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00, - 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, - 0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response2[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request3[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00, - 0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00, - 0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00, - 0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response3[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - uint32_t dcerpc_bind_len = sizeof(dcerpc_bind); - uint32_t dcerpc_bindack_len = sizeof(dcerpc_bindack); - - uint32_t dcerpc_request1_len = sizeof(dcerpc_request1); - uint32_t dcerpc_response1_len = sizeof(dcerpc_response1); - - uint32_t dcerpc_request2_len = sizeof(dcerpc_request2); - uint32_t dcerpc_response2_len = sizeof(dcerpc_response2); - - uint32_t dcerpc_request3_len = sizeof(dcerpc_request3); - uint32_t dcerpc_response3_len = sizeof(dcerpc_response3); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"DCERPC\"; dce_stub_data; content:\"|00 02|\"; sid:1;)"); - if (s == NULL) - goto end; - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"DCERPC\"; dce_stub_data; content:\"|00 75|\"; sid:2;)"); - if (s == NULL) - goto end; - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"DCERPC\"; dce_stub_data; content:\"|00 18|\"; sid:3;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_bind, dcerpc_bind_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_bindack, - dcerpc_bindack_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* request1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request1, - dcerpc_request1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3)) - goto end; - - /* response1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response1, - dcerpc_response1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3)) - goto end; - - /* request2 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request2, - dcerpc_request2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1) || !PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3)) - goto end; - - /* response2 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, dcerpc_response2, - dcerpc_response2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3)) - goto end; - - /* request3 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, dcerpc_request3, - dcerpc_request3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || !PacketAlertCheck(p, 3)) - goto end; - - /* response3 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF, - dcerpc_response3, dcerpc_response3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3)) - goto end; - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -static int DetectDceStubDataTestParse05(void) -{ - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - DCERPCState *dcerpc_state = NULL; - int r = 0; - - uint8_t dcerpc_request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x02, - }; - - uint8_t dcerpc_response1[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00, - 0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00, - 0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00, - 0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, - 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, - 0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00, - 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00, - 0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00, - 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, - 0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00, - 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, - 0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response2[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_request3[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00, - 0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00, - 0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00, - 0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - }; - - uint8_t dcerpc_response3[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - uint32_t dcerpc_request1_len = sizeof(dcerpc_request1); - uint32_t dcerpc_response1_len = sizeof(dcerpc_response1); - - uint32_t dcerpc_request2_len = sizeof(dcerpc_request2); - uint32_t dcerpc_response2_len = sizeof(dcerpc_response2); - - uint32_t dcerpc_request3_len = sizeof(dcerpc_request3); - uint32_t dcerpc_response3_len = sizeof(dcerpc_response3); - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_stub_data; content:\"|00 02|\"; " - "sid:1;)"); - if (s == NULL) - goto end; - s = de_ctx->sig_list->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_stub_data; content:\"|00 75|\"; " - "sid:2;)"); - if (s == NULL) - goto end; - s = de_ctx->sig_list->next->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"DCERPC\"; " - "dce_stub_data; content:\"|00 18|\"; " - "sid:3;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* request1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER | STREAM_START, - dcerpc_request1, dcerpc_request1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dcerpc_state = f.alstate; - if (dcerpc_state == NULL) { - SCLogDebug("no dcerpc state: "); - goto end; - } - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3)) - goto end; - - /* response1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - dcerpc_response1, dcerpc_response1_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3)) - goto end; - - /* request2 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - dcerpc_request2, dcerpc_request2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1) || !PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3)) - goto end; - - /* response2 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, - dcerpc_response2, dcerpc_response2_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || PacketAlertCheck(p, 3)) - goto end; - - /* request3 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, - dcerpc_request3, dcerpc_request3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2) || !PacketAlertCheck(p, 3)) - goto end; - - /* response3 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT | STREAM_EOF, - dcerpc_response3, dcerpc_response3_len); - if (r != 0) { - SCLogDebug("AppLayerParse for dcerpc failed. Returned %" PRId32, r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - p->flowflags &=~ FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - - -#endif - -void DetectDceStubDataRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectDceStubDataTestParse01", DetectDceStubDataTestParse01, 1); - UtRegisterTest("DetectDceStubDataTestParse02", DetectDceStubDataTestParse02, 1); - UtRegisterTest("DetectDceStubDataTestParse03", DetectDceStubDataTestParse03, 1); - UtRegisterTest("DetectDceStubDataTestParse04", DetectDceStubDataTestParse04, 1); - UtRegisterTest("DetectDceStubDataTestParse05", DetectDceStubDataTestParse05, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/detect-dce-stub-data.h b/framework/src/suricata/src/detect-dce-stub-data.h deleted file mode 100644 index adc45388..00000000 --- a/framework/src/suricata/src/detect-dce-stub-data.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_DCE_STUB_DATA_H__ -#define __DETECT_DCE_STUB_DATA_H__ - -void DetectDceStubDataRegister(void); -void DetectDceStubDataRegisterTests(void); - -#endif /* __DETECT_DCE_STUB_DATA_H__ */ diff --git a/framework/src/suricata/src/detect-depth.c b/framework/src/suricata/src/detect-depth.c deleted file mode 100644 index f58438da..00000000 --- a/framework/src/suricata/src/detect-depth.c +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * Implements the depth keyword. - */ - -#include "suricata-common.h" - -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-byte-extract.h" -#include "detect-parse.h" - -#include "flow-var.h" -#include "app-layer.h" - -#include "util-debug.h" - -static int DetectDepthSetup (DetectEngineCtx *, Signature *, char *); - -void DetectDepthRegister (void) -{ - sigmatch_table[DETECT_DEPTH].name = "depth"; - sigmatch_table[DETECT_DEPTH].desc = "designate how many bytes from the beginning of the payload will be checked"; - sigmatch_table[DETECT_DEPTH].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#Depth"; - sigmatch_table[DETECT_DEPTH].Match = NULL; - sigmatch_table[DETECT_DEPTH].Setup = DetectDepthSetup; - sigmatch_table[DETECT_DEPTH].Free = NULL; - sigmatch_table[DETECT_DEPTH].RegisterTests = NULL; - - sigmatch_table[DETECT_DEPTH].flags |= SIGMATCH_PAYLOAD; -} - -static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depthstr) -{ - char *str = depthstr; - char dubbed = 0; - SigMatch *pm = NULL; - int ret = -1; - - /* strip "'s */ - if (depthstr[0] == '\"' && depthstr[strlen(depthstr) - 1] == '\"') { - str = SCStrdup(depthstr + 1); - if (unlikely(str == NULL)) - goto end; - str[strlen(depthstr) - 2] = '\0'; - dubbed = 1; - } - - /* retrive the sm to apply the depth against */ - if (s->list != DETECT_SM_LIST_NOTSET) { - pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[s->list]); - } else { - pm = SigMatchGetLastSMFromLists(s, 28, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - } - if (pm == NULL) { - SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs " - "preceding content, uricontent option, http_client_body, " - "http_server_body, http_header option, http_raw_header option, " - "http_method option, http_cookie, http_raw_uri, " - "http_stat_msg, http_stat_code, http_user_agent, " - "http_host, http_raw_host or " - "file_data/dce_stub_data sticky buffer options"); - goto end; - } - - /* verify other conditions. */ - DetectContentData *cd = (DetectContentData *)pm->ctx; - - if (cd->flags & DETECT_CONTENT_DEPTH) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple depths for the same content."); - goto end; - } - if ((cd->flags & DETECT_CONTENT_WITHIN) || (cd->flags & DETECT_CONTENT_DISTANCE)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a relative " - "keyword like within/distance with a absolute " - "relative keyword like depth/offset for the same " - "content." ); - goto end; - } - if (cd->flags & DETECT_CONTENT_NEGATED && cd->flags & DETECT_CONTENT_FAST_PATTERN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " - "negated keyword set along with a fast_pattern"); - goto end; - } - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " - "keyword set along with a fast_pattern:only;"); - goto end; - } - if (str[0] != '-' && isalpha((unsigned char)str[0])) { - SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(str, s); - if (bed_sm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "unknown byte_extract var " - "seen in depth - %s\n", str); - goto end; - } - cd->depth = ((DetectByteExtractData *)bed_sm->ctx)->local_id; - cd->flags |= DETECT_CONTENT_DEPTH_BE; - } else { - cd->depth = (uint32_t)atoi(str); - if (cd->depth < cd->content_len) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "depth - %"PRIu16 - " smaller than content length - %"PRIu32, - cd->depth, cd->content_len); - goto end; - } - /* Now update the real limit, as depth is relative to the offset */ - cd->depth += cd->offset; - } - cd->flags |= DETECT_CONTENT_DEPTH; - - ret = 0; - end: - if (dubbed) - SCFree(str); - return ret; -} diff --git a/framework/src/suricata/src/detect-depth.h b/framework/src/suricata/src/detect-depth.h deleted file mode 100644 index b864f621..00000000 --- a/framework/src/suricata/src/detect-depth.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_DEPTH_H__ -#define __DETECT_DEPTH_H__ - -/* prototypes */ -void DetectDepthRegister (void); - -#endif /* __DETECT_DEPTH_H__ */ - diff --git a/framework/src/suricata/src/detect-detection-filter.c b/framework/src/suricata/src/detect-detection-filter.c deleted file mode 100644 index 7e1ee8bc..00000000 --- a/framework/src/suricata/src/detect-detection-filter.c +++ /dev/null @@ -1,665 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias - * - * Implements the detection_filter keyword - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "host.h" - -#include "detect-detection-filter.h" -#include "detect-threshold.h" -#include "detect-parse.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -#define TRACK_DST 1 -#define TRACK_SRC 2 - -/** - *\brief Regex for parsing our detection_filter options - */ -#define PARSE_REGEX "^\\s*(track|count|seconds)\\s+(by_src|by_dst|\\d+)\\s*,\\s*(track|count|seconds)\\s+(by_src|by_dst|\\d+)\\s*,\\s*(track|count|seconds)\\s+(by_src|by_dst|\\d+)\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectDetectionFilterMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectDetectionFilterSetup(DetectEngineCtx *, Signature *, char *); -void DetectDetectionFilterRegisterTests(void); -void DetectDetectionFilterFree(void *); - -/** - * \brief Registration function for detection_filter: keyword - */ -void DetectDetectionFilterRegister (void) -{ - sigmatch_table[DETECT_DETECTION_FILTER].name = "detection_filter"; - sigmatch_table[DETECT_DETECTION_FILTER].desc = "alert on every match after a threshold has been reached"; - sigmatch_table[DETECT_DETECTION_FILTER].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Rule-Thresholding#detection_filter"; - sigmatch_table[DETECT_DETECTION_FILTER].Match = DetectDetectionFilterMatch; - sigmatch_table[DETECT_DETECTION_FILTER].Setup = DetectDetectionFilterSetup; - sigmatch_table[DETECT_DETECTION_FILTER].Free = DetectDetectionFilterFree; - sigmatch_table[DETECT_DETECTION_FILTER].RegisterTests = DetectDetectionFilterRegisterTests; - /* this is compatible to ip-only signatures */ - sigmatch_table[DETECT_DETECTION_FILTER].flags |= SIGMATCH_IPONLY_COMPAT; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -int DetectDetectionFilterMatch (ThreadVars *thv, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - return 1; -} - -/** - * \internal - * \brief This function is used to parse detection_filter options passed via detection_filter: keyword - * - * \param rawstr Pointer to the user provided detection_filter options - * - * \retval df pointer to DetectThresholdData on success - * \retval NULL on failure - */ -DetectThresholdData *DetectDetectionFilterParse (char *rawstr) -{ - DetectThresholdData *df = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *str_ptr = NULL; - char *args[6] = { NULL, NULL, NULL, NULL, NULL, NULL}; - char *copy_str = NULL, *df_opt = NULL; - int seconds_found = 0, count_found = 0, track_found = 0; - int seconds_pos = 0, count_pos = 0; - uint16_t pos = 0; - int i = 0; - char *saveptr = NULL; - - copy_str = SCStrdup(rawstr); - if (unlikely(copy_str == NULL)) { - goto error; - } - - for (pos = 0, df_opt = strtok_r(copy_str,",", &saveptr); - pos < strlen(copy_str) && df_opt != NULL; - pos++, df_opt = strtok_r(NULL,",", &saveptr)) - { - if(strstr(df_opt,"count")) - count_found++; - if(strstr(df_opt,"second")) - seconds_found++; - if(strstr(df_opt,"track")) - track_found++; - } - SCFree(copy_str); - copy_str = NULL; - - if (count_found != 1 || seconds_found != 1 || track_found != 1) - goto error; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 5) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr); - goto error; - } - - df = SCMalloc(sizeof(DetectThresholdData)); - if (unlikely(df == NULL)) - goto error; - - memset(df,0,sizeof(DetectThresholdData)); - - df->type = TYPE_DETECTION; - - for (i = 0; i < (ret - 1); i++) { - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, i + 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - args[i] = (char *)str_ptr; - - if (strncasecmp(args[i],"by_dst",strlen("by_dst")) == 0) - df->track = TRACK_DST; - if (strncasecmp(args[i],"by_src",strlen("by_src")) == 0) - df->track = TRACK_SRC; - if (strncasecmp(args[i],"count",strlen("count")) == 0) - count_pos = i+1; - if (strncasecmp(args[i],"seconds",strlen("seconds")) == 0) - seconds_pos = i+1; - } - - if (args[count_pos] == NULL || args[seconds_pos] == NULL) { - goto error; - } - - if (ByteExtractStringUint32(&df->count, 10, strlen(args[count_pos]), - args[count_pos]) <= 0) { - goto error; - } - - if (ByteExtractStringUint32(&df->seconds, 10, strlen(args[seconds_pos]), - args[seconds_pos]) <= 0) { - goto error; - } - - if (df->count == 0 || df->seconds == 0) { - SCLogError(SC_ERR_INVALID_VALUE, "found an invalid value"); - goto error; - } - - for (i = 0; i < 6; i++){ - if (args[i] != NULL) - SCFree(args[i]); - } - return df; - -error: - for (i = 0; i < 6; i++){ - if (args[i] != NULL) - SCFree(args[i]); - } - if (df != NULL) - SCFree(df); - return NULL; -} - -/** - * \internal - * \brief this function is used to add the parsed detection_filter into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param m pointer to the Current SigMatch - * \param rawstr pointer to the user provided detection_filter options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectDetectionFilterSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - SCEnter(); - DetectThresholdData *df = NULL; - SigMatch *sm = NULL; - SigMatch *tmpm = NULL; - - /* checks if there's a previous instance of threshold */ - tmpm = SigMatchGetLastSMFromLists(s, 2, - DETECT_THRESHOLD, s->sm_lists_tail[DETECT_SM_LIST_MATCH]); - if (tmpm != NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "\"detection_filter\" and \"threshold\" are not allowed in the same rule"); - SCReturnInt(-1); - } - /* checks there's no previous instance of detection_filter */ - tmpm = SigMatchGetLastSMFromLists(s, 2, - DETECT_DETECTION_FILTER, s->sm_lists_tail[DETECT_SM_LIST_MATCH]); - if (tmpm != NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "At most one \"detection_filter\" is allowed per rule"); - SCReturnInt(-1); - } - - df = DetectDetectionFilterParse(rawstr); - if (df == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_DETECTION_FILTER; - sm->ctx = (SigMatchCtx *)df; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD); - - return 0; - -error: - if (df) SCFree(df); - if (sm) SCFree(sm); - return -1; -} - -/** - * \internal - * \brief this function will free memory associated with DetectThresholdData - * - * \param df_ptr pointer to DetectDetectionFilterData - */ -void DetectDetectionFilterFree(void *df_ptr) -{ - DetectThresholdData *df = (DetectThresholdData *)df_ptr; - if (df) SCFree(df); -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-threshold.h" -#include "util-time.h" -#include "util-hashlist.h" - -/** - * \test DetectDetectionFilterTestParse01 is a test for a valid detection_filter options - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DetectDetectionFilterTestParse01 (void) -{ - DetectThresholdData *df = NULL; - df = DetectDetectionFilterParse("track by_dst,count 10,seconds 60"); - if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 60)) { - DetectDetectionFilterFree(df); - return 1; - } - - return 0; -} - -/** - * \test DetectDetectionFilterTestParse02 is a test for a invalid detection_filter options - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DetectDetectionFilterTestParse02 (void) -{ - DetectThresholdData *df = NULL; - df = DetectDetectionFilterParse("track both,count 10,seconds 60"); - if (df && (df->track == TRACK_DST || df->track == TRACK_SRC) && (df->count == 10) && (df->seconds == 60)) { - DetectDetectionFilterFree(df); - return 1; - } - - return 0; -} - -/** - * \test DetectDetectionfilterTestParse03 is a test for a valid detection_filter options in any order - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DetectDetectionFilterTestParse03 (void) -{ - DetectThresholdData *df = NULL; - df = DetectDetectionFilterParse("track by_dst, seconds 60, count 10"); - if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 60)) { - DetectDetectionFilterFree(df); - return 1; - } - - return 0; -} - - -/** - * \test DetectDetectionFilterTestParse04 is a test for an invalid detection_filter options in any order - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DetectDetectionFilterTestParse04 (void) -{ - DetectThresholdData *df = NULL; - df = DetectDetectionFilterParse("count 10, track by_dst, seconds 60, count 10"); - if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 60)) { - DetectDetectionFilterFree(df); - return 1; - } - - return 0; -} - -/** - * \test DetectDetectionFilterTestParse05 is a test for a valid detection_filter options in any order - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DetectDetectionFilterTestParse05 (void) -{ - DetectThresholdData *df = NULL; - df = DetectDetectionFilterParse("count 10, track by_dst, seconds 60"); - if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 60)) { - DetectDetectionFilterFree(df); - return 1; - } - - return 0; -} - -/** - * \test DetectDetectionFilterTestParse06 is a test for an invalid value in detection_filter - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DetectDetectionFilterTestParse06 (void) -{ - DetectThresholdData *df = NULL; - df = DetectDetectionFilterParse("count 10, track by_dst, seconds 0"); - if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 0)) { - DetectDetectionFilterFree(df); - return 1; - } - - return 0; -} - -/** - * \test DetectDetectionFilterTestSig1 is a test for checking the working of detection_filter keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int DetectDetectionFilterTestSig1(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - - HostInitConfig(HOST_QUIET); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"detection_filter Test\"; detection_filter: track by_dst, count 4, seconds 60; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - - if(alerts == 4) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test DetectDetectionFilterTestSig2 is a test for checking the working of detection_filter keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int DetectDetectionFilterTestSig2(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - struct timeval ts; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"detection_filter Test 2\"; detection_filter: track by_dst, count 4, seconds 60; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - - if (alerts == 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test drops - */ -static int DetectDetectionFilterTestSig3(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - int drops = 0; - struct timeval ts; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (msg:\"detection_filter Test 2\"; detection_filter: track by_dst, count 2, seconds 60; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - if (alerts == 3 && drops == 3) - result = 1; - else { - if (alerts != 3) - printf("alerts: %d != 3: ", alerts); - if (drops != 3) - printf("drops: %d != 3: ", drops); - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} -#endif /* UNITTESTS */ - -void DetectDetectionFilterRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectDetectionFilterTestParse01", DetectDetectionFilterTestParse01, 1); - UtRegisterTest("DetectDetectionFilterTestParse02", DetectDetectionFilterTestParse02, 0); - UtRegisterTest("DetectDetectionFilterTestParse03", DetectDetectionFilterTestParse03, 1); - UtRegisterTest("DetectDetectionFilterTestParse04", DetectDetectionFilterTestParse04, 0); - UtRegisterTest("DetectDetectionFilterTestParse05", DetectDetectionFilterTestParse05, 1); - UtRegisterTest("DetectDetectionFilterTestParse06", DetectDetectionFilterTestParse06, 0); - UtRegisterTest("DetectDetectionFilterTestSig1", DetectDetectionFilterTestSig1, 1); - UtRegisterTest("DetectDetectionFilterTestSig2", DetectDetectionFilterTestSig2, 1); - UtRegisterTest("DetectDetectionFilterTestSig3", DetectDetectionFilterTestSig3, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-detection-filter.h b/framework/src/suricata/src/detect-detection-filter.h deleted file mode 100644 index 2c74d4f4..00000000 --- a/framework/src/suricata/src/detect-detection-filter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias - */ - -#ifndef __DETECT_DETECTION_FILTER_H__ -#define __DETECT_DETECTION_FILTER_H__ - -#include "decode-events.h" -#include "decode-ipv4.h" -#include "decode-tcp.h" - -/** - * Registration function for detection_filter: keyword - */ - -void DetectDetectionFilterRegister (void); - -/** - * This function registers unit tests for detection_filter - */ - -void DetectDetectionFilterRegisterTests(void); - -#endif /*__DETECT_DETECTION_FILTER_H__ */ - diff --git a/framework/src/suricata/src/detect-distance.c b/framework/src/suricata/src/detect-distance.c deleted file mode 100644 index a8284dbe..00000000 --- a/framework/src/suricata/src/detect-distance.c +++ /dev/null @@ -1,270 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * Implements the distance keyword - */ - -#include "suricata-common.h" - -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "app-layer.h" -#include "detect-parse.h" - -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-pcre.h" -#include "detect-byte-extract.h" - -#include "flow-var.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "detect-bytejump.h" -#include "util-unittest-helper.h" - -static int DetectDistanceSetup(DetectEngineCtx *, Signature *, char *); -void DetectDistanceRegisterTests(void); - -void DetectDistanceRegister(void) -{ - sigmatch_table[DETECT_DISTANCE].name = "distance"; - sigmatch_table[DETECT_DISTANCE].desc = "indicates a relation between this content keyword and the content preceding it"; - sigmatch_table[DETECT_DISTANCE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#Distance"; - sigmatch_table[DETECT_DISTANCE].Match = NULL; - sigmatch_table[DETECT_DISTANCE].Setup = DetectDistanceSetup; - sigmatch_table[DETECT_DISTANCE].Free = NULL; - sigmatch_table[DETECT_DISTANCE].RegisterTests = DetectDistanceRegisterTests; - - sigmatch_table[DETECT_DISTANCE].flags |= SIGMATCH_PAYLOAD; -} - -static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, - char *distancestr) -{ - char *str = distancestr; - char dubbed = 0; - SigMatch *pm = NULL; - int ret = -1; - - /* strip "'s */ - if (distancestr[0] == '\"' && distancestr[strlen(distancestr) - 1] == '\"') { - str = SCStrdup(distancestr + 1); - if (unlikely(str == NULL)) - goto end; - str[strlen(distancestr) - 2] = '\0'; - dubbed = 1; - } - - /* retrive the sm to apply the depth against */ - if (s->list != DETECT_SM_LIST_NOTSET) { - pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[s->list]); - } else { - pm = SigMatchGetLastSMFromLists(s, 28, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - } - if (pm == NULL) { - SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "distance needs " - "preceding content, uricontent option, http_client_body, " - "http_server_body, http_header option, http_raw_header option, " - "http_method option, http_cookie, http_raw_uri, " - "http_stat_msg, http_stat_code, http_user_agent or " - "file_data/dce_stub_data sticky buffer option"); - goto end; - } - - /* verify other conditions */ - DetectContentData *cd = (DetectContentData *)pm->ctx; - if (cd->flags & DETECT_CONTENT_DISTANCE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple distances for the same content."); - goto end; - } - if ((cd->flags & DETECT_CONTENT_DEPTH) || (cd->flags & DETECT_CONTENT_OFFSET)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a relative " - "keyword like within/distance with a absolute " - "relative keyword like depth/offset for the same " - "content." ); - goto end; - } - if (cd->flags & DETECT_CONTENT_NEGATED && cd->flags & DETECT_CONTENT_FAST_PATTERN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " - "negated keyword set along with a fast_pattern"); - goto end; - } - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " - "keyword set along with a fast_pattern:only;"); - goto end; - } - if (str[0] != '-' && isalpha((unsigned char)str[0])) { - SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(str, s); - if (bed_sm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "unknown byte_extract var " - "seen in distance - %s\n", str); - goto end; - } - cd->distance = ((DetectByteExtractData *)bed_sm->ctx)->local_id; - cd->flags |= DETECT_CONTENT_DISTANCE_BE; - } else { - cd->distance = strtol(str, NULL, 10); - } - cd->flags |= DETECT_CONTENT_DISTANCE; - - SigMatch *prev_pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, pm->prev, - DETECT_PCRE, pm->prev); - if (prev_pm == NULL) { - ret = 0; - goto end; - } - if (prev_pm->type == DETECT_CONTENT) { - DetectContentData *cd = (DetectContentData *)prev_pm->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "previous keyword " - "has a fast_pattern:only; set. Can't " - "have relative keywords around a fast_pattern " - "only content"); - goto end; - } - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - } else if (prev_pm->type == DETECT_PCRE) { - DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx; - pd->flags |= DETECT_PCRE_RELATIVE_NEXT; - } - - ret = 0; - end: - if (dubbed) - SCFree(str); - return ret; -} - -#ifdef UNITTESTS - -static int DetectDistanceTest01(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("no de_ctx: "); - goto end; - } - - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (content:\"|AA BB|\"; content:\"|CC DD EE FF 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE|\"; distance: 4; within: 19; sid:1; rev:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigMatch *sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm == NULL) { - printf("sm NULL: "); - goto end; - } - - sm = sm->next; - if (sm == NULL) { - printf("sm2 NULL: "); - goto end; - } - - DetectContentData *co = (DetectContentData *)sm->ctx; - if (co == NULL) { - printf("co == NULL: "); - goto end; - } - - if (co->distance != 4) { - printf("distance %"PRIi32", expected 4: ", co->distance); - goto end; - } - - /* within needs to be 23: distance + content_len as Snort auto fixes this */ - if (co->within != 19) { - printf("within %"PRIi32", expected 23: ", co->within); - goto end; - } - - result = 1; -end: - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectDistanceTestPacket01 is a test to check matches of - * distance works, if the previous keyword is byte_jump and content - * (bug 163) - */ -int DetectDistanceTestPacket01 (void) -{ - int result = 0; - uint8_t buf[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; - uint16_t buflen = sizeof(buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"suricata test\"; " - "byte_jump:1,2; content:\"|00|\"; " - "within:1; distance:2; sid:98711212; rev:1;)"; - - p->flowflags = FLOW_PKT_ESTABLISHED | FLOW_PKT_TOCLIENT; - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} -#endif /* UNITTESTS */ - -void DetectDistanceRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectDistanceTest01 -- distance / within mix", DetectDistanceTest01, 1); - UtRegisterTest("DetectDistanceTestPacket01", DetectDistanceTestPacket01, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-distance.h b/framework/src/suricata/src/detect-distance.h deleted file mode 100644 index 80aebe4f..00000000 --- a/framework/src/suricata/src/detect-distance.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_DISTANCE_H__ -#define __DETECT_DISTANCE_H__ - -/* prototypes */ -void DetectDistanceRegister (void); - -#endif /* __DETECT_DISTANCE_H__ */ - diff --git a/framework/src/suricata/src/detect-dns-query.c b/framework/src/suricata/src/detect-dns-query.c deleted file mode 100644 index 55742f89..00000000 --- a/framework/src/suricata/src/detect-dns-query.c +++ /dev/null @@ -1,1180 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup dnslayer - * - * @{ - */ - - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-util.h" -#include "flow-var.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-spm.h" -#include "util-print.h" - -#include "stream-tcp.h" - -#include "app-layer.h" -#include "app-layer-dns-common.h" -#include "detect-dns-query.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -static int DetectDnsQuerySetup (DetectEngineCtx *, Signature *, char *); -static void DetectDnsQueryRegisterTests(void); - -/** - * \brief Registration function for keyword: http_uri - */ -void DetectDnsQueryRegister (void) -{ - sigmatch_table[DETECT_AL_DNS_QUERY].name = "dns_query"; - sigmatch_table[DETECT_AL_DNS_QUERY].desc = "content modifier to match specifically and only on the DNS query-buffer"; - sigmatch_table[DETECT_AL_DNS_QUERY].Match = NULL; - sigmatch_table[DETECT_AL_DNS_QUERY].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_DNS_QUERY].alproto = ALPROTO_DNS; - sigmatch_table[DETECT_AL_DNS_QUERY].Setup = DetectDnsQuerySetup; - sigmatch_table[DETECT_AL_DNS_QUERY].Free = NULL; - sigmatch_table[DETECT_AL_DNS_QUERY].RegisterTests = DetectDnsQueryRegisterTests; - - sigmatch_table[DETECT_AL_DNS_QUERY].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_DNS_QUERY].flags |= SIGMATCH_PAYLOAD; -} - - -/** - * \brief this function setups the dns_query modifier keyword used in the rule - * - * \param de_ctx Pointer to the Detection Engine Context - * \param s Pointer to the Signature to which the current keyword belongs - * \param str Should hold an empty string always - * - * \retval 0 On success - * \retval -1 On failure - */ - -static int DetectDnsQuerySetup(DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - s->list = DETECT_SM_LIST_DNSQUERYNAME_MATCH; - s->alproto = ALPROTO_DNS; - return 0; -} - -/** - * \brief Run the pattern matcher against the queries - * - * \param f locked flow - * \param dns_state initialized dns state - * - * \warning Make sure the flow/state is locked - * \todo what should we return? Just the fact that we matched? - */ -uint32_t DetectDnsQueryInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - DNSState *dns_state, uint8_t flags, void *txv, - uint64_t tx_id) -{ - SCEnter(); - - DNSTransaction *tx = (DNSTransaction *)txv; - DNSQueryEntry *query = NULL; - uint8_t *buffer; - uint16_t buffer_len; - uint32_t cnt = 0; - - TAILQ_FOREACH(query, &tx->query_list, next) { - SCLogDebug("tx %p query %p", tx, query); - - buffer = (uint8_t *)((uint8_t *)query + sizeof(DNSQueryEntry)); - buffer_len = query->len; - - cnt += DnsQueryPatternSearch(det_ctx, - buffer, buffer_len, - flags); - } - - SCReturnUInt(cnt); -} - -#ifdef UNITTESTS -/** \test simple google.com query matching */ -static int DetectDnsQueryTest01(void) -{ - /* google.com */ - uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, - 0x00, 0x10, 0x00, 0x01, }; - int result = 0; - Flow f; - DNSState *dns_state = NULL; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - - p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - - FLOW_INITIALIZE(&f); - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_UDP; - f.protomap = FlowGetProtoMapping(f.proto); - - p->flow = &f; - p->flags |= PKT_HAS_FLOW; - p->flowflags |= FLOW_PKT_TOSERVER; - f.alproto = ALPROTO_DNS; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google\"; nocase; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf, sizeof(buf)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dns_state = f.alstate; - if (dns_state == NULL) { - printf("no dns state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test multi tx google.(com|net) query matching */ -static int DetectDnsQueryTest02(void) -{ - /* google.com */ - uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, - 0x00, 0x01, 0x00, 0x01, }; - - uint8_t buf2[] = { 0x10, 0x32, /* tx id */ - 0x81, 0x80, /* flags: resp, recursion desired, recusion available */ - 0x00, 0x01, /* 1 query */ - 0x00, 0x01, /* 1 answer */ - 0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */ - /* query record */ - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */ - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */ - 0x00, 0x01, 0x00, 0x01, /* type a, class in */ - /* answer */ - 0xc0, 0x0c, /* ref to name in query above */ - 0x00, 0x01, 0x00, 0x01, /* type a, class in */ - 0x00, 0x01, 0x40, 0xef, /* ttl */ - 0x00, 0x04, /* data len */ - 0x01, 0x02, 0x03, 0x04 }; /* addr */ - - /* google.net */ - uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x6E, 0x65, 0x74, 0x00, - 0x00, 0x10, 0x00, 0x01, }; - int result = 0; - Flow f; - DNSState *dns_state = NULL; - Packet *p1 = NULL, *p2 = NULL, *p3 = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - - p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - p2 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - p3 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - - FLOW_INITIALIZE(&f); - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_UDP; - f.protomap = FlowGetProtoMapping(f.proto); - f.alproto = ALPROTO_DNS; - - p1->flow = &f; - p1->flags |= PKT_HAS_FLOW; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->pcap_cnt = 1; - - p2->flow = &f; - p2->flags |= PKT_HAS_FLOW; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->pcap_cnt = 2; - - p3->flow = &f; - p3->flags |= PKT_HAS_FLOW; - p3->flowflags |= FLOW_PKT_TOSERVER; - p3->pcap_cnt = 3; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google.com\"; nocase; sid:1;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google.net\"; nocase; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf1, sizeof(buf1)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dns_state = f.alstate; - if (dns_state == NULL) { - printf("no dns state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("(p1) sig 1 didn't alert, but it should have: "); - goto end; - } - if (PacketAlertCheck(p1, 2)) { - printf("(p1) sig 2 did alert, but it should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf2, sizeof(buf2)); - if (r != 0) { - printf("toserver client 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("(p2) sig 1 alerted, but it should not have: "); - goto end; - } - if (PacketAlertCheck(p2, 2)) { - printf("(p2) sig 2 alerted, but it should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf3, sizeof(buf3)); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p3); - - if (PacketAlertCheck(p3, 1)) { - printf("(p3) sig 1 alerted, but it should not have: "); - goto end; - } - if (!(PacketAlertCheck(p3, 2))) { - printf("(p3) sig 2 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - FLOW_DESTROY(&f); - UTHFreePacket(p1); - UTHFreePacket(p2); - UTHFreePacket(p3); - return result; -} - -/** \test simple google.com query matching (TCP) */ -static int DetectDnsQueryTest03(void) -{ - /* google.com */ - uint8_t buf[] = { 0x00, 28, - 0x10, 0x32, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, - 0x00, 0x10, 0x00, 0x01, }; - int result = 0; - Flow f; - DNSState *dns_state = NULL; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_TCP; - f.protomap = FlowGetProtoMapping(f.proto); - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_DNS; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "content:\"google\"; nocase; dns_query; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf, sizeof(buf)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dns_state = f.alstate; - if (dns_state == NULL) { - printf("no dns state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test simple google.com query matching (TCP splicing) */ -static int DetectDnsQueryTest04(void) -{ - /* google.com */ - uint8_t buf1[] = { 0x00, 28, - 0x10, 0x32, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; - uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, - 0x00, 0x10, 0x00, 0x01, }; - int result = 0; - Flow f; - DNSState *dns_state = NULL; - Packet *p1 = NULL, *p2 = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_TCP; - f.protomap = FlowGetProtoMapping(f.proto); - f.alproto = ALPROTO_DNS; - - p1->flow = &f; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p1->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED; - - p2->flow = &f; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google\"; nocase; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf1, sizeof(buf1)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dns_state = f.alstate; - if (dns_state == NULL) { - printf("no dns state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sig 1 alerted, but it should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf2, sizeof(buf2)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p1); - UTHFreePacket(p2); - return result; -} - -/** \test simple google.com query matching (TCP splicing) */ -static int DetectDnsQueryTest05(void) -{ - /* google.com in 2 chunks (buf1 and buf2) */ - uint8_t buf1[] = { 0x00, 28, /* len 28 */ - 0x10, 0x32, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; - - uint8_t buf2[] = { 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, - 0x00, 0x10, 0x00, 0x01, }; - - uint8_t buf3[] = { 0x00, 44, /* len 44 */ - 0x10, 0x32, /* tx id */ - 0x81, 0x80, /* flags: resp, recursion desired, recusion available */ - 0x00, 0x01, /* 1 query */ - 0x00, 0x01, /* 1 answer */ - 0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */ - /* query record */ - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */ - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */ - 0x00, 0x01, 0x00, 0x01, /* type a, class in */ - /* answer */ - 0xc0, 0x0c, /* ref to name in query above */ - 0x00, 0x01, 0x00, 0x01, /* type a, class in */ - 0x00, 0x01, 0x40, 0xef, /* ttl */ - 0x00, 0x04, /* data len */ - 0x01, 0x02, 0x03, 0x04 }; /* addr */ - - /* google.net */ - uint8_t buf4[] = { 0x00, 28, /* len 28 */ - 0x11, 0x33, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x6E, 0x65, 0x74, 0x00, - 0x00, 0x10, 0x00, 0x01, }; - int result = 0; - Flow f; - DNSState *dns_state = NULL; - Packet *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - p4 = UTHBuildPacketReal(buf4, sizeof(buf4), IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_TCP; - f.protomap = FlowGetProtoMapping(f.proto); - f.alproto = ALPROTO_DNS; - - p1->flow = &f; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p1->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED; - - p2->flow = &f; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED; - - p3->flow = &f; - p3->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p3->flowflags |= FLOW_PKT_TOCLIENT|FLOW_PKT_ESTABLISHED; - - p4->flow = &f; - p4->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p4->flowflags |= FLOW_PKT_TOSERVER|FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google.com\"; nocase; sid:1;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google.net\"; nocase; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf1, sizeof(buf1)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dns_state = f.alstate; - if (dns_state == NULL) { - printf("no dns state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("(p1) sig 1 alerted, but it should not have: "); - goto end; - } - if (PacketAlertCheck(p1, 2)) { - printf("(p1) sig 2 did alert, but it should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf2, sizeof(buf2)); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - if (PacketAlertCheck(p2, 2)) { - printf("(p2) sig 2 did alert, but it should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf3, sizeof(buf3)); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p3); - - if (PacketAlertCheck(p3, 1)) { - printf("sig 1 did alert, but it should not have: "); - goto end; - } - if (PacketAlertCheck(p3, 2)) { - printf("(p3) sig 2 did alert, but it should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf4, sizeof(buf4)); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p4); - - if (PacketAlertCheck(p4, 1)) { - printf("(p4) sig 1 did alert, but it should not have: "); - goto end; - } - if (!(PacketAlertCheck(p4, 2))) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p1); - UTHFreePacket(p2); - UTHFreePacket(p3); - UTHFreePacket(p4); - return result; -} - -/** \test simple google.com query matching, pcre */ -static int DetectDnsQueryTest06(void) -{ - /* google.com */ - uint8_t buf[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, - 0x00, 0x10, 0x00, 0x01, }; - int result = 0; - Flow f; - DNSState *dns_state = NULL; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - - p = UTHBuildPacketReal(buf, sizeof(buf), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - - FLOW_INITIALIZE(&f); - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_UDP; - f.protomap = FlowGetProtoMapping(f.proto); - - p->flow = &f; - p->flags |= PKT_HAS_FLOW; - p->flowflags |= FLOW_PKT_TOSERVER; - f.alproto = ALPROTO_DNS; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google\"; nocase; " - "pcre:\"/google\\.com$/i\"; sid:1;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google\"; nocase; " - "pcre:\"/^\\.[a-z]{2,3}$/iR\"; sid:2;)"); - if (s == NULL) { - goto end; - } - - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf, sizeof(buf)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dns_state = f.alstate; - if (dns_state == NULL) { - printf("no dns state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sig 2 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test multi tx google.(com|net) query matching + - * app layer event */ -static int DetectDnsQueryTest07(void) -{ - /* google.com */ - uint8_t buf1[] = { 0x10, 0x32, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, - 0x00, 0x01, 0x00, 0x01, }; - - uint8_t buf2[] = { 0x10, 0x32, /* tx id */ - 0x81, 0x80|0x40, /* flags: resp, recursion desired, recusion available */ - 0x00, 0x01, /* 1 query */ - 0x00, 0x01, /* 1 answer */ - 0x00, 0x00, 0x00, 0x00, /* no auth rr, additional rr */ - /* query record */ - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, /* name */ - 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, /* name cont */ - 0x00, 0x01, 0x00, 0x01, /* type a, class in */ - /* answer */ - 0xc0, 0x0c, /* ref to name in query above */ - 0x00, 0x01, 0x00, 0x01, /* type a, class in */ - 0x00, 0x01, 0x40, 0xef, /* ttl */ - 0x00, 0x04, /* data len */ - 0x01, 0x02, 0x03, 0x04 }; /* addr */ - - /* google.net */ - uint8_t buf3[] = { 0x11, 0x33, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6C, - 0x65, 0x03, 0x6E, 0x65, 0x74, 0x00, - 0x00, 0x10, 0x00, 0x01, }; - int result = 0; - Flow f; - DNSState *dns_state = NULL; - Packet *p1 = NULL, *p2 = NULL, *p3 = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - - p1 = UTHBuildPacketReal(buf1, sizeof(buf1), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - p2 = UTHBuildPacketReal(buf2, sizeof(buf2), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - p3 = UTHBuildPacketReal(buf3, sizeof(buf3), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1", - 41424, 53); - - FLOW_INITIALIZE(&f); - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_UDP; - f.protomap = FlowGetProtoMapping(f.proto); - f.alproto = ALPROTO_DNS; - - p1->flow = &f; - p1->flags |= PKT_HAS_FLOW; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->pcap_cnt = 1; - - p2->flow = &f; - p2->flags |= PKT_HAS_FLOW; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->pcap_cnt = 2; - - p3->flow = &f; - p3->flags |= PKT_HAS_FLOW; - p3->flowflags |= FLOW_PKT_TOSERVER; - p3->pcap_cnt = 3; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google.com\"; nocase; sid:1;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test dns_query option\"; " - "dns_query; content:\"google.net\"; nocase; sid:2;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert dns any any -> any any " - "(msg:\"Test Z flag event\"; " - "app-layer-event:dns.z_flag_set; sid:3;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf1, sizeof(buf1)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - dns_state = f.alstate; - if (dns_state == NULL) { - printf("no dns state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("(p1) sig 1 didn't alert, but it should have: "); - goto end; - } - if (PacketAlertCheck(p1, 2)) { - printf("(p1) sig 2 did alert, but it should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOCLIENT, buf2, sizeof(buf2)); - if (r != -1) { - printf("toserver client 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("(p2) sig 1 alerted, but it should not have: "); - goto end; - } - if (PacketAlertCheck(p2, 2)) { - printf("(p2) sig 2 alerted, but it should not have: "); - goto end; - } - if (!(PacketAlertCheck(p2, 3))) { - printf("(p2) sig 3 didn't alert, but it should have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DNS, STREAM_TOSERVER, buf3, sizeof(buf3)); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p3); - - if (PacketAlertCheck(p3, 1)) { - printf("(p3) sig 1 alerted, but it should not have: "); - goto end; - } - if (!(PacketAlertCheck(p3, 2))) { - printf("(p3) sig 2 didn't alert, but it should have: "); - goto end; - } - /** \todo should not alert, bug #839 - if (PacketAlertCheck(p3, 3)) { - printf("(p3) sig 3 did alert, but it should not have: "); - goto end; - } - */ - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - FLOW_DESTROY(&f); - UTHFreePacket(p1); - UTHFreePacket(p2); - UTHFreePacket(p3); - return result; -} - -#endif - -static void DetectDnsQueryRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectDnsQueryTest01", DetectDnsQueryTest01, 1); - UtRegisterTest("DetectDnsQueryTest02", DetectDnsQueryTest02, 1); - UtRegisterTest("DetectDnsQueryTest03 -- tcp", DetectDnsQueryTest03, 1); - UtRegisterTest("DetectDnsQueryTest04 -- tcp splicing", DetectDnsQueryTest04, 1); - UtRegisterTest("DetectDnsQueryTest05 -- tcp splicing/multi tx", DetectDnsQueryTest05, 1); - UtRegisterTest("DetectDnsQueryTest06 -- pcre", DetectDnsQueryTest06, 1); - UtRegisterTest("DetectDnsQueryTest07 -- app layer event", DetectDnsQueryTest07, 1); -#endif -} diff --git a/framework/src/suricata/src/detect-dns-query.h b/framework/src/suricata/src/detect-dns-query.h deleted file mode 100644 index 75605231..00000000 --- a/framework/src/suricata/src/detect-dns-query.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_DNS_QUERY_H__ -#define __DETECT_DNS_QUERY_H__ - -#include "app-layer-dns-common.h" - -void DetectDnsQueryRegister (void); -uint32_t DetectDnsQueryInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - DNSState *dns_state, uint8_t flags, void *txv, uint64_t tx_id); - -#endif /* __DETECT_DNS_QUERY_H__ */ diff --git a/framework/src/suricata/src/detect-dsize.c b/framework/src/suricata/src/detect-dsize.c deleted file mode 100644 index 9858a5f2..00000000 --- a/framework/src/suricata/src/detect-dsize.c +++ /dev/null @@ -1,838 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the dsize keyword - */ - -#include "suricata-common.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "flow-var.h" - -#include "detect-dsize.h" - -#include "util-unittest.h" -#include "util-debug.h" -#include "util-byte.h" - -#include "pkt-var.h" -#include "host.h" -#include "util-profiling.h" - -/** - * dsize:[<>]<0-65535>[<><0-65535>]; - */ -#define PARSE_REGEX "^\\s*(<|>)?\\s*([0-9]{1,5})\\s*(?:(<>)\\s*([0-9]{1,5}))?\\s*$" -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectDsizeMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectDsizeSetup (DetectEngineCtx *, Signature *s, char *str); -void DsizeRegisterTests(void); -static void DetectDsizeFree(void *); - -/** - * \brief Registration function for dsize: keyword - */ -void DetectDsizeRegister (void) -{ - sigmatch_table[DETECT_DSIZE].name = "dsize"; - sigmatch_table[DETECT_DSIZE].desc = "match on the size of the packet payload"; - sigmatch_table[DETECT_DSIZE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#Dsize"; - sigmatch_table[DETECT_DSIZE].Match = DetectDsizeMatch; - sigmatch_table[DETECT_DSIZE].Setup = DetectDsizeSetup; - sigmatch_table[DETECT_DSIZE].Free = DetectDsizeFree; - sigmatch_table[DETECT_DSIZE].RegisterTests = DsizeRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE,"pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY,"pcre study failed: %s", eb); - goto error; - } - return; - -error: - /* XXX */ - return; -} - -/** - * \internal - * \brief This function is used to match flags on a packet with those passed via dsize: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param s pointer to the Signature - * \param m pointer to the sigmatch - * - * \retval 0 no match - * \retval 1 match - */ -int DetectDsizeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - SCEnter(); - int ret = 0; - - if (PKT_IS_PSEUDOPKT(p)) { - SCReturnInt(0); - } - - const DetectDsizeData *dd = (const DetectDsizeData *)ctx; - - SCLogDebug("p->payload_len %"PRIu16"", p->payload_len); - - if (dd->mode == DETECTDSIZE_EQ && dd->dsize == p->payload_len) - ret = 1; - else if (dd->mode == DETECTDSIZE_LT && p->payload_len < dd->dsize) - ret = 1; - else if (dd->mode == DETECTDSIZE_GT && p->payload_len > dd->dsize) - ret = 1; - else if (dd->mode == DETECTDSIZE_RA && p->payload_len > dd->dsize && p->payload_len < dd->dsize2) - ret = 1; - - SCReturnInt(ret); -} - -/** - * \internal - * \brief This function is used to parse dsize options passed via dsize: keyword - * - * \param rawstr Pointer to the user provided dsize options - * - * \retval dd pointer to DetectDsizeData on success - * \retval NULL on failure - */ -DetectDsizeData *DetectDsizeParse (char *rawstr) -{ - DetectDsizeData *dd = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - char mode[2] = ""; - char value1[6] = ""; - char value2[6] = ""; - char range[3] = ""; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 3 || ret > 5) { - SCLogError(SC_ERR_PCRE_MATCH,"Parse error %s", rawstr); - goto error; - } - - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, mode, sizeof(mode)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed"); - goto error; - } - SCLogDebug("mode \"%s\"", mode); - - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, value1, sizeof(value1)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed"); - goto error; - } - SCLogDebug("value1 \"%s\"", value1); - - if (ret > 3) { - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, range, sizeof(range)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed"); - goto error; - } - SCLogDebug("range \"%s\"", range); - - if (ret > 4) { - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4, value2, sizeof(value2)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed"); - goto error; - } - SCLogDebug("value2 \"%s\"", value2); - } - } - - dd = SCMalloc(sizeof(DetectDsizeData)); - if (unlikely(dd == NULL)) - goto error; - dd->dsize = 0; - dd->dsize2 = 0; - dd->mode = DETECTDSIZE_EQ; // default - - if (strlen(mode) > 0) { - if (mode[0] == '<') - dd->mode = DETECTDSIZE_LT; - else if (mode[0] == '>') - dd->mode = DETECTDSIZE_GT; - else - dd->mode = DETECTDSIZE_EQ; - } - - if (strcmp("<>", range) == 0) { - if (strlen(mode) != 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Range specified but mode also set"); - goto error; - } - dd->mode = DETECTDSIZE_RA; - } - - /** set the first dsize value */ - if (ByteExtractStringUint16(&dd->dsize,10,strlen(value1),value1) <= 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid size value1:\"%s\"", value1); - goto error; - } - - /** set the second dsize value if specified */ - if (strlen(value2) > 0) { - if (dd->mode != DETECTDSIZE_RA) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Multiple dsize values specified but mode is not range"); - goto error; - } - - if (ByteExtractStringUint16(&dd->dsize2,10,strlen(value2),value2) <= 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size value2:\"%s\"",value2); - goto error; - } - - if (dd->dsize2 <= dd->dsize) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"dsize2:%"PRIu16" <= dsize:%"PRIu16"",dd->dsize2,dd->dsize); - goto error; - } - } - - SCLogDebug("dsize parsed successfully dsize: %"PRIu16" dsize2: %"PRIu16"",dd->dsize,dd->dsize2); - return dd; - -error: - if (dd) - SCFree(dd); - return NULL; -} - -/** - * \internal - * \brief this function is used to add the parsed dsize into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param rawstr pointer to the user provided flags options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectDsizeSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectDsizeData *dd = NULL; - SigMatch *sm = NULL; - - if (SigMatchGetLastSMFromLists(s, 2, - DETECT_DSIZE, - s->sm_lists_tail[DETECT_SM_LIST_MATCH]) != NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Can't use 2 or more dsizes in " - "the same sig. Invalidating signature."); - goto error; - } - - SCLogDebug("\'%s\'", rawstr); - - dd = DetectDsizeParse(rawstr); - if (dd == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Parsing \'%s\' failed", rawstr); - goto error; - } - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL){ - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for SigMatch"); - SCFree(dd); - goto error; - } - - sm->type = DETECT_DSIZE; - sm->ctx = (SigMatchCtx *)dd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - SCLogDebug("dd->dsize %"PRIu16", dd->dsize2 %"PRIu16", dd->mode %"PRIu8"", - dd->dsize, dd->dsize2, dd->mode); - /* tell the sig it has a dsize to speed up engine init */ - s->flags |= SIG_FLAG_REQUIRE_PACKET; - s->flags |= SIG_FLAG_DSIZE; - - if (s->dsize_sm == NULL) { - s->dsize_sm = sm; - } - - return 0; - -error: - return -1; -} - -/** - * \internal - * \brief this function will free memory associated with DetectDsizeData - * - * \param de pointer to DetectDsizeData - */ -void DetectDsizeFree(void *de_ptr) -{ - DetectDsizeData *dd = (DetectDsizeData *)de_ptr; - if(dd) SCFree(dd); -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -#include "detect.h" -#include "detect-engine.h" -/** - * \test this is a test for a valid dsize value 1 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse01 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("1"); - if (dd) { - DetectDsizeFree(dd); - return 1; - } - - return 0; -} - -/** - * \test this is a test for a valid dsize value >10 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse02 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse(">10"); - if (dd) { - DetectDsizeFree(dd); - return 1; - } - - return 0; -} - -/** - * \test this is a test for a valid dsize value <100 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse03 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("<100"); - if (dd) { - DetectDsizeFree(dd); - return 1; - } - - return 0; -} - -/** - * \test this is a test for a valid dsize value 1<>2 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse04 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("1<>2"); - if (dd) { - DetectDsizeFree(dd); - return 1; - } - - return 0; -} - -/** - * \test this is a test for a valid dsize value 1 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse05 (void) -{ - int result = 0; - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("1"); - if (dd) { - if (dd->dsize == 1) - result = 1; - - DetectDsizeFree(dd); - } - - return result; -} - -/** - * \test this is a test for a valid dsize value >10 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse06 (void) -{ - int result = 0; - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse(">10"); - if (dd) { - if (dd->dsize == 10 && dd->mode == DETECTDSIZE_GT) - result = 1; - - DetectDsizeFree(dd); - } - - return result; -} - -/** - * \test this is a test for a valid dsize value <100 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse07 (void) -{ - int result = 0; - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("<100"); - if (dd) { - if (dd->dsize == 100 && dd->mode == DETECTDSIZE_LT) - result = 1; - - DetectDsizeFree(dd); - } - - return result; -} - -/** - * \test this is a test for a valid dsize value 1<>2 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse08 (void) -{ - int result = 0; - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("1<>2"); - if (dd) { - if (dd->dsize == 1 && dd->dsize2 == 2 && dd->mode == DETECTDSIZE_RA) - result = 1; - - DetectDsizeFree(dd); - } - - return result; -} - -/** - * \test this is a test for a invalid dsize value A - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse09 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("A"); - if (dd) { - DetectDsizeFree(dd); - return 0; - } - - return 1; -} - -/** - * \test this is a test for a invalid dsize value >10<>10 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse10 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse(">10<>10"); - if (dd) { - DetectDsizeFree(dd); - return 0; - } - - return 1; -} - -/** - * \test this is a test for a invalid dsize value <>10 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse11 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("<>10"); - if (dd) { - DetectDsizeFree(dd); - return 0; - } - - return 1; -} - -/** - * \test this is a test for a invalid dsize value 1<> - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse12 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("1<>"); - if (dd) { - DetectDsizeFree(dd); - return 0; - } - - return 1; -} - -/** - * \test this is a test for a valid dsize value 1 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse13 (void) -{ - int result = 0; - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("1"); - if (dd) { - if (dd->dsize2 == 0) - result = 1; - - DetectDsizeFree(dd); - } - - return result; -} - -/** - * \test this is a test for a invalid dsize value "" - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse14 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse(""); - if (dd) { - DetectDsizeFree(dd); - return 0; - } - - return 1; -} - -/** - * \test this is a test for a invalid dsize value " " - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse15 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse(" "); - if (dd) { - DetectDsizeFree(dd); - return 0; - } - - return 1; -} - -/** - * \test this is a test for a invalid dsize value 2<>1 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse16 (void) -{ - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("2<>1"); - if (dd) { - DetectDsizeFree(dd); - return 0; - } - - return 1; -} - -/** - * \test this is a test for a valid dsize value 1 <> 2 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse17 (void) -{ - int result = 0; - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse(" 1 <> 2 "); - if (dd) { - if (dd->dsize == 1 && dd->dsize2 == 2 && dd->mode == DETECTDSIZE_RA) - result = 1; - - DetectDsizeFree(dd); - } - - return result; -} - -/** - * \test this is test for a valid dsize value > 2 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse18 (void) -{ - int result = 0; - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("> 2 "); - if (dd) { - if (dd->dsize == 2 && dd->mode == DETECTDSIZE_GT) - result = 1; - - DetectDsizeFree(dd); - } - - return result; -} - -/** - * \test test for a valid dsize value < 12 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse19 (void) -{ - int result = 0; - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse("< 12 "); - if (dd) { - if (dd->dsize == 12 && dd->mode == DETECTDSIZE_LT) - result = 1; - - DetectDsizeFree(dd); - } - - return result; -} - -/** - * \test test for a valid dsize value 12 - * - * \retval 1 on succces - * \retval 0 on failure - */ -int DsizeTestParse20 (void) -{ - int result = 0; - DetectDsizeData *dd = NULL; - dd = DetectDsizeParse(" 12 "); - if (dd) { - if (dd->dsize == 12 && dd->mode == DETECTDSIZE_EQ) - result = 1; - - DetectDsizeFree(dd); - } - - return result; -} - -/** - * \test DetectDsizeIcmpv6Test01 is a test for checking the working of - * dsize keyword by creating 2 rules and matching a crafted packet - * against them. Only the first one shall trigger. - */ -int DetectDsizeIcmpv6Test01 (void) -{ - int result = 0; - - static uint8_t raw_icmpv6[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00, - 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV6Hdr ip6h; - ThreadVars tv; - DecodeThreadVars dtv; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ip6h, 0, sizeof(IPV6Hdr)); - memset(&th_v, 0, sizeof(ThreadVars)); - - FlowInitConfig(FLOW_QUIET); - p->src.family = AF_INET6; - p->dst.family = AF_INET6; - p->ip6h = &ip6h; - - DecodeIPV6(&tv, &dtv, p, raw_icmpv6, sizeof(raw_icmpv6), NULL); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(msg:\"ICMP Large ICMP Packet\"; dsize:>8; sid:1; rev:4;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx, "alert icmp any any -> any any " - "(msg:\"ICMP Large ICMP Packet\"; dsize:>800; sid:2; rev:4;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 0) { - printf("sid 1 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2)) { - printf("sid 2 alerted, but should not have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - PACKET_RECYCLE(p); - FlowShutdown(); -end: - SCFree(p); - return result; - -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for dsize - */ -void DsizeRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DsizeTestParse01", DsizeTestParse01, 1); - UtRegisterTest("DsizeTestParse02", DsizeTestParse02, 1); - UtRegisterTest("DsizeTestParse03", DsizeTestParse03, 1); - UtRegisterTest("DsizeTestParse04", DsizeTestParse04, 1); - UtRegisterTest("DsizeTestParse05", DsizeTestParse05, 1); - UtRegisterTest("DsizeTestParse06", DsizeTestParse06, 1); - UtRegisterTest("DsizeTestParse07", DsizeTestParse07, 1); - UtRegisterTest("DsizeTestParse08", DsizeTestParse08, 1); - UtRegisterTest("DsizeTestParse09", DsizeTestParse09, 1); - UtRegisterTest("DsizeTestParse10", DsizeTestParse10, 1); - UtRegisterTest("DsizeTestParse11", DsizeTestParse11, 1); - UtRegisterTest("DsizeTestParse12", DsizeTestParse12, 1); - UtRegisterTest("DsizeTestParse13", DsizeTestParse13, 1); - UtRegisterTest("DsizeTestParse14", DsizeTestParse14, 1); - UtRegisterTest("DsizeTestParse15", DsizeTestParse15, 1); - UtRegisterTest("DsizeTestParse16", DsizeTestParse16, 1); - UtRegisterTest("DsizeTestParse17", DsizeTestParse17, 1); - UtRegisterTest("DsizeTestParse18", DsizeTestParse18, 1); - UtRegisterTest("DsizeTestParse19", DsizeTestParse19, 1); - UtRegisterTest("DsizeTestParse20", DsizeTestParse20, 1); - - UtRegisterTest("DetectDsizeIcmpv6Test01", DetectDsizeIcmpv6Test01, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-dsize.h b/framework/src/suricata/src/detect-dsize.h deleted file mode 100644 index c0385dbc..00000000 --- a/framework/src/suricata/src/detect-dsize.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_DSIZE_H__ -#define __DETECT_DSIZE_H__ - -#define DETECTDSIZE_LT 0 -#define DETECTDSIZE_EQ 1 -#define DETECTDSIZE_GT 2 -#define DETECTDSIZE_RA 3 - -typedef struct DetectDsizeData_ { - uint16_t dsize; - uint16_t dsize2; - uint8_t mode; -} DetectDsizeData; - -/* prototypes */ -void DetectDsizeRegister (void); - -#endif /* __DETECT_DSIZE_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-address-ipv4.c b/framework/src/suricata/src/detect-engine-address-ipv4.c deleted file mode 100644 index 20e9e57e..00000000 --- a/framework/src/suricata/src/detect-engine-address-ipv4.c +++ /dev/null @@ -1,1614 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * IPV4 Address part of the detection engine. - */ - -#include "suricata-common.h" - -#include "decode.h" -#include "detect.h" -#include "flow-var.h" - -#include "util-cidr.h" -#include "util-unittest.h" - -#include "detect-engine-address.h" -#include "detect-engine-siggroup.h" -#include "detect-engine-port.h" - -#include "util-error.h" -#include "util-debug.h" -#include "util-unittest.h" - -/** - * \brief Compares 2 addresses(address ranges) and returns the relationship - * between the 2 addresses. - * - * \param a Pointer to the first address instance to be compared. - * \param b Pointer to the second address instance to be compared. - * - * \retval ADDRESS_EQ If the 2 address ranges a and b, are equal. - * \retval ADDRESS_ES b encapsulates a. b_ip1[...a_ip1...a_ip2...]b_ip2. - * \retval ADDRESS_EB a encapsulates b. a_ip1[...b_ip1....b_ip2...]a_ip2. - * \retval ADDRESS_LE a_ip1(...b_ip1==a_ip2...)b_ip2 - * \retval ADDRESS_LT a_ip1(...b_ip1...a_ip2...)b_ip2 - * \retval ADDRESS_GE b_ip1(...a_ip1==b_ip2...)a_ip2 - * \retval ADDRESS_GT a_ip1 > b_ip2, i.e. the address range for 'a' starts only - * after the end of the address range for 'b' - */ -int DetectAddressCmpIPv4(DetectAddress *a, DetectAddress *b) -{ - uint32_t a_ip1 = ntohl(a->ip.addr_data32[0]); - uint32_t a_ip2 = ntohl(a->ip2.addr_data32[0]); - uint32_t b_ip1 = ntohl(b->ip.addr_data32[0]); - uint32_t b_ip2 = ntohl(b->ip2.addr_data32[0]); - - if (a_ip1 == b_ip1 && a_ip2 == b_ip2) { - SCLogDebug("ADDRESS_EQ"); - return ADDRESS_EQ; - } else if (a_ip1 >= b_ip1 && a_ip1 <= b_ip2 && a_ip2 <= b_ip2) { - SCLogDebug("ADDRESS_ES"); - return ADDRESS_ES; - } else if (a_ip1 <= b_ip1 && a_ip2 >= b_ip2) { - SCLogDebug("ADDRESS_EB"); - return ADDRESS_EB; - } else if (a_ip1 < b_ip1 && a_ip2 < b_ip2 && a_ip2 >= b_ip1) { - SCLogDebug("ADDRESS_LE"); - return ADDRESS_LE; - } else if (a_ip1 < b_ip1 && a_ip2 < b_ip2) { - SCLogDebug("ADDRESS_LT"); - return ADDRESS_LT; - } else if (a_ip1 > b_ip1 && a_ip1 <= b_ip2 && a_ip2 > b_ip2) { - SCLogDebug("ADDRESS_GE"); - return ADDRESS_GE; - } else if (a_ip1 > b_ip2) { - SCLogDebug("ADDRESS_GT"); - return ADDRESS_GT; - } else { - /* should be unreachable */ - SCLogDebug("Internal Error: should be unreachable"); - } - - return ADDRESS_ER; -} - -/** - * \brief Cut groups and merge sigs - * - * a = 1.2.3.4, b = 1.2.3.4-1.2.3.5 - * must result in: a == 1.2.3.4, b == 1.2.3.5, c == NULL - * - * a = 1.2.3.4, b = 1.2.3.3-1.2.3.5 - * must result in: a == 1.2.3.3, b == 1.2.3.4, c == 1.2.3.5 - * - * a = 1.2.3.0/24 b = 1.2.3.128-1.2.4.10 - * must result in: a == 1.2.3.0/24, b == 1.2.4.0-1.2.4.10, c == NULL - * - * a = 1.2.3.4, b = 1.2.3.0/24 - * must result in: a == 1.2.3.0-1.2.3.3, b == 1.2.3.4, c == 1.2.3.5-1.2.3.255 - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressCutIPv4(DetectEngineCtx *de_ctx, DetectAddress *a, - DetectAddress *b, DetectAddress **c) -{ - uint32_t a_ip1 = ntohl(a->ip.addr_data32[0]); - uint32_t a_ip2 = ntohl(a->ip2.addr_data32[0]); - uint32_t b_ip1 = ntohl(b->ip.addr_data32[0]); - uint32_t b_ip2 = ntohl(b->ip2.addr_data32[0]); - DetectPort *port = NULL; - DetectAddress *tmp = NULL; - DetectAddress *tmp_c = NULL; - int r = 0; - - /* default to NULL */ - *c = NULL; - - r = DetectAddressCmpIPv4(a, b); - if (r != ADDRESS_ES && r != ADDRESS_EB && r != ADDRESS_LE && r != ADDRESS_GE) { - SCLogDebug("we shouldn't be here"); - goto error; - } - - /* get a place to temporary put sigs lists */ - tmp = DetectAddressInit(); - if (tmp == NULL) - goto error; - - /* we have 3 parts: [aaa[abab)bbb] - * part a: a_ip1 <-> b_ip1 - 1 - * part b: b_ip1 <-> a_ip2 - * part c: a_ip2 + 1 <-> b_ip2 - */ - if (r == ADDRESS_LE) { - SCLogDebug("DetectAddressCutIPv4: r == ADDRESS_LE"); - - a->ip.addr_data32[0] = htonl(a_ip1); - a->ip2.addr_data32[0] = htonl(b_ip1 - 1); - - b->ip.addr_data32[0] = htonl(b_ip1); - b->ip2.addr_data32[0] = htonl(a_ip2); - - tmp_c = DetectAddressInit(); - if (tmp_c == NULL) - goto error; - - tmp_c->ip.family = AF_INET; - tmp_c->ip.addr_data32[0] = htonl(a_ip2 + 1); - tmp_c->ip2.addr_data32[0] = htonl(b_ip2); - *c = tmp_c; - - if (de_ctx != NULL) { - SigGroupHeadCopySigs(de_ctx, b->sh, &tmp_c->sh); - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &tmp_c->port, port); - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &b->port, port); - - tmp_c->cnt += b->cnt; - b->cnt += a->cnt; - } - - /* we have 3 parts: [bbb[baba]aaa] - * part a: b_ip1 <-> a_ip1 - 1 - * part b: a_ip1 <-> b_ip2 - * part c: b_ip2 + 1 <-> a_ip2 - */ - } else if (r == ADDRESS_GE) { - SCLogDebug("DetectAddressCutIPv4: r == ADDRESS_GE"); - - a->ip.addr_data32[0] = htonl(b_ip1); - a->ip2.addr_data32[0] = htonl(a_ip1 - 1); - - b->ip.addr_data32[0] = htonl(a_ip1); - b->ip2.addr_data32[0] = htonl(b_ip2); - - tmp_c = DetectAddressInit(); - if (tmp_c == NULL) - goto error; - - tmp_c->ip.family = AF_INET; - tmp_c->ip.addr_data32[0] = htonl(b_ip2 + 1); - tmp_c->ip2.addr_data32[0] = htonl(a_ip2); - *c = tmp_c; - - if (de_ctx != NULL) { - /* 'a' gets clean and then 'b' sigs - * 'b' gets clean, then 'a' then 'b' sigs - * 'c' gets 'a' sigs */ - /* store old a list */ - SigGroupHeadCopySigs(de_ctx, a->sh, &tmp->sh); - /* clean a list */ - SigGroupHeadClearSigs(a->sh); - /* copy old b to c */ - SigGroupHeadCopySigs(de_ctx, tmp->sh, &tmp_c->sh); - /* copy old b to a */ - SigGroupHeadCopySigs(de_ctx, b->sh, &a->sh); - /* prepend old a before b */ - SigGroupHeadCopySigs(de_ctx, tmp->sh, &b->sh); - /* clean tmp list */ - SigGroupHeadClearSigs(tmp->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &tmp->port, port); - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &a->port, port); - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &b->port, port); - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &tmp_c->port, port); - - tmp->cnt += a->cnt; - a->cnt = 0; - tmp_c->cnt += tmp->cnt; - a->cnt += b->cnt; - b->cnt += tmp->cnt; - tmp->cnt = 0; - } - - /* we have 2 or three parts: - * - * 2 part: [[abab]bbb] or [bbb[baba]] - * part a: a_ip1 <-> a_ip2 - * part b: a_ip2 + 1 <-> b_ip2 - * - * part a: b_ip1 <-> a_ip1 - 1 - * part b: a_ip1 <-> a_ip2 - * - * 3 part [bbb[aaa]bbb] - * becomes[aaa[bbb]ccc] - * - * part a: b_ip1 <-> a_ip1 - 1 - * part b: a_ip1 <-> a_ip2 - * part c: a_ip2 + 1 <-> b_ip2 - */ - } else if (r == ADDRESS_ES) { - SCLogDebug("DetectAddressCutIPv4: r == ADDRESS_ES"); - - if (a_ip1 == b_ip1) { - SCLogDebug("DetectAddressCutIPv4: 1"); - - a->ip.addr_data32[0] = htonl(a_ip1); - a->ip2.addr_data32[0] = htonl(a_ip2); - - b->ip.addr_data32[0] = htonl(a_ip2 + 1); - b->ip2.addr_data32[0] = htonl(b_ip2); - - if (de_ctx != NULL) { - /* 'b' overlaps 'a' so 'a' needs the 'b' sigs */ - SigGroupHeadCopySigs(de_ctx, b->sh, &a->sh); - - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &a->port, port); - a->cnt += b->cnt; - } - } else if (a_ip2 == b_ip2) { - SCLogDebug("DetectAddressCutIPv4: 2"); - - a->ip.addr_data32[0] = htonl(b_ip1); - a->ip2.addr_data32[0] = htonl(a_ip1 - 1); - - b->ip.addr_data32[0] = htonl(a_ip1); - b->ip2.addr_data32[0] = htonl(a_ip2); - - if (de_ctx != NULL) { - SigGroupHeadCopySigs(de_ctx, b->sh, &tmp->sh); - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - SigGroupHeadClearSigs(a->sh); - SigGroupHeadCopySigs(de_ctx, tmp->sh, &a->sh); - SigGroupHeadClearSigs(tmp->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &tmp->port, a->port); - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &a->port, port); - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &b->port, port); - - tmp->cnt += a->cnt; - a->cnt = 0; - a->cnt += b->cnt; - b->cnt += tmp->cnt; - tmp->cnt = 0; - } - } else { - SCLogDebug("3"); - - a->ip.addr_data32[0] = htonl(b_ip1); - a->ip2.addr_data32[0] = htonl(a_ip1 - 1); - - b->ip.addr_data32[0] = htonl(a_ip1); - b->ip2.addr_data32[0] = htonl(a_ip2); - - tmp_c = DetectAddressInit(); - if (tmp_c == NULL) - goto error; - - tmp_c->ip.family = AF_INET; - tmp_c->ip.addr_data32[0] = htonl(a_ip2 + 1); - tmp_c->ip2.addr_data32[0] = htonl(b_ip2); - *c = tmp_c; - - if (de_ctx != NULL) { - /* 'a' gets clean and then 'b' sigs - * 'b' gets clean, then 'a' then 'b' sigs - * 'c' gets 'b' sigs */ - /* store old a list */ - SigGroupHeadCopySigs(de_ctx, a->sh, &tmp->sh); - /* clean a list */ - SigGroupHeadClearSigs(a->sh); - /* copy old b to c */ - SigGroupHeadCopySigs(de_ctx, b->sh, &tmp_c->sh); - /* copy old b to a */ - SigGroupHeadCopySigs(de_ctx, b->sh, &a->sh); - /* prepend old a before b */ - SigGroupHeadCopySigs(de_ctx, tmp->sh, &b->sh); - /* clean tmp list */ - SigGroupHeadClearSigs(tmp->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &tmp->port, port); - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &tmp_c->port, port); - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &a->port, port); - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &b->port, port); - - tmp->cnt += a->cnt; - a->cnt = 0; - tmp_c->cnt += b->cnt; - a->cnt += b->cnt; - b->cnt += tmp->cnt; - tmp->cnt = 0; - } - } - /* we have 2 or three parts: - * - * 2 part: [[baba]aaa] or [aaa[abab]] - * part a: b_ip1 <-> b_ip2 - * part b: b_ip2 + 1 <-> a_ip2 - * - * part a: a_ip1 <-> b_ip1 - 1 - * part b: b_ip1 <-> b_ip2 - * - * 3 part [aaa[bbb]aaa] - * becomes[aaa[bbb]ccc] - * - * part a: a_ip1 <-> b_ip2 - 1 - * part b: b_ip1 <-> b_ip2 - * part c: b_ip2 + 1 <-> a_ip2 - */ - } else if (r == ADDRESS_EB) { - SCLogDebug("DetectAddressCutIPv4: r == ADDRESS_EB"); - - if (a_ip1 == b_ip1) { - SCLogDebug("DetectAddressCutIPv4: 1"); - - a->ip.addr_data32[0] = htonl(b_ip1); - a->ip2.addr_data32[0] = htonl(b_ip2); - - b->ip.addr_data32[0] = htonl(b_ip2 + 1); - b->ip2.addr_data32[0] = htonl(a_ip2); - - if (de_ctx != NULL) { - /* 'b' overlaps 'a' so a needs the 'b' sigs */ - SigGroupHeadCopySigs(de_ctx, b->sh, &tmp->sh); - SigGroupHeadClearSigs(b->sh); - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - SigGroupHeadCopySigs(de_ctx, tmp->sh, &a->sh); - SigGroupHeadClearSigs(tmp->sh); - - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &tmp->port, b->port); - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &b->port, port); - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &a->port, port); - - tmp->cnt += b->cnt; - b->cnt = 0; - b->cnt += a->cnt; - a->cnt += tmp->cnt; - tmp->cnt = 0; - } - } else if (a_ip2 == b_ip2) { - SCLogDebug("DetectAddressCutIPv4: 2"); - - a->ip.addr_data32[0] = htonl(a_ip1); - a->ip2.addr_data32[0] = htonl(b_ip1 - 1); - - b->ip.addr_data32[0] = htonl(b_ip1); - b->ip2.addr_data32[0] = htonl(b_ip2); - - if (de_ctx != NULL) { - /* 'a' overlaps 'b' so a needs the 'a' sigs */ - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &b->port, port); - - b->cnt += a->cnt; - } - } else { - SCLogDebug("DetectAddressCutIPv4: 3"); - - a->ip.addr_data32[0] = htonl(a_ip1); - a->ip2.addr_data32[0] = htonl(b_ip1 - 1); - - b->ip.addr_data32[0] = htonl(b_ip1); - b->ip2.addr_data32[0] = htonl(b_ip2); - - tmp_c = DetectAddressInit(); - if (tmp_c == NULL) - goto error; - - tmp_c->ip.family = AF_INET; - tmp_c->ip.addr_data32[0] = htonl(b_ip2 + 1); - tmp_c->ip2.addr_data32[0] = htonl(a_ip2); - *c = tmp_c; - - if (de_ctx != NULL) { - /* 'a' stays the same wrt sigs - * 'b' keeps it's own sigs and gets a's sigs prepended - * 'c' gets 'a' sigs */ - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - SigGroupHeadCopySigs(de_ctx, a->sh, &tmp_c->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &b->port, port); - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &tmp_c->port, port); - - b->cnt += a->cnt; - tmp_c->cnt += a->cnt; - } - } - } - - if (tmp != NULL) - DetectAddressFree(tmp); - - return 0; - -error: - if (tmp != NULL) - DetectAddressFree(tmp); - return -1; -} - -/** - * \brief Check if the address group list covers the complete IPv4 IP space. - * - * \param ag Pointer to a DetectAddress list head, which has to be checked to - * see if the address ranges in it, cover the entire IPv4 IP space. - * - * \retval 1 Yes, it covers the entire IPv4 address range. - * \retval 0 No, it doesn't cover the entire IPv4 address range. - */ -int DetectAddressIsCompleteIPSpaceIPv4(DetectAddress *ag) -{ - uint32_t next_ip = 0; - - if (ag == NULL) - return 0; - - /* if we don't start with 0.0.0.0 we know we're good */ - if (ntohl(ag->ip.addr_data32[0]) != 0x00000000) - return 0; - - /* if we're ending with 255.255.255.255 while we know we started with - * 0.0.0.0 it's the complete space */ - if (ntohl(ag->ip2.addr_data32[0]) == 0xFFFFFFFF) - return 1; - - next_ip = htonl(ntohl(ag->ip2.addr_data32[0]) + 1); - ag = ag->next; - - for ( ; ag != NULL; ag = ag->next) { - - if (ag->ip.addr_data32[0] != next_ip) - return 0; - - if (ntohl(ag->ip2.addr_data32[0]) == 0xFFFFFFFF) - return 1; - - next_ip = htonl(ntohl(ag->ip2.addr_data32[0]) + 1); - } - - return 0; -} - -/** - * \brief Cuts and returns an address range, which is the complement of the - * address range that is supplied as the argument. - * - * For example: - * - * If a = 0.0.0.0-1.2.3.4, - * then a = 1.2.3.4-255.255.255.255 and b = NULL - * If a = 1.2.3.4-255.255.255.255, - * then a = 0.0.0.0-1.2.3.4 and b = NULL - * If a = 1.2.3.4-192.168.1.1, - * then a = 0.0.0.0-1.2.3.3 and b = 192.168.1.2-255.255.255.255 - * - * \param a Pointer to an address range (DetectAddress) instance whose complement - * has to be returned in a and b. - * \param b Pointer to DetectAddress pointer, that will be supplied back with a - * new DetectAddress instance, if the complement demands so. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressCutNotIPv4(DetectAddress *a, DetectAddress **b) -{ - uint32_t a_ip1 = ntohl(a->ip.addr_data32[0]); - uint32_t a_ip2 = ntohl(a->ip2.addr_data32[0]); - DetectAddress *tmp_b = NULL; - - /* default to NULL */ - *b = NULL; - - if (a_ip1 != 0x00000000 && a_ip2 != 0xFFFFFFFF) { - a->ip.addr_data32[0] = htonl(0x00000000); - a->ip2.addr_data32[0] = htonl(a_ip1 - 1); - - tmp_b = DetectAddressInit(); - if (tmp_b == NULL) - goto error; - - tmp_b->ip.family = AF_INET; - tmp_b->ip.addr_data32[0] = htonl(a_ip2 + 1); - tmp_b->ip2.addr_data32[0] = htonl(0xFFFFFFFF); - *b = tmp_b; - } else if (a_ip1 == 0x00000000 && a_ip2 != 0xFFFFFFFF) { - a->ip.addr_data32[0] = htonl(a_ip2 + 1); - a->ip2.addr_data32[0] = htonl(0xFFFFFFFF); - } else if (a_ip1 != 0x00000000 && a_ip2 == 0xFFFFFFFF) { - a->ip.addr_data32[0] = htonl(0x00000000); - a->ip2.addr_data32[0] = htonl(a_ip1 - 1); - } else { - goto error; - } - - return 0; - -error: - return -1; -} - -/** - * \brief Extends a target address range if the the source address range is - * wider than the target address range on either sides. - * - * Every address is a range, i.e. address->ip1....address->ip2. For - * example 1.2.3.4 to 192.168.1.1. - * if source->ip1 is smaller than target->ip1, it indicates that the - * source's left address limit is greater(range wise) than the target's - * left address limit, and hence we reassign the target's left address - * limit to source's left address limit. - * Similary if source->ip2 is greater than target->ip2, it indicates that - * the source's right address limit is greater(range wise) than the - * target's right address limit, and hence we reassign the target's right - * address limit to source's right address limit. - * - * \param de_ctx Pointer to the detection engine context. - * \param target Pointer to the target DetectAddress instance that has to be - * updated. - * \param source Pointer to the source DetectAddress instance that is used - * to decided whether we extend the target's address range. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressJoinIPv4(DetectEngineCtx *de_ctx, DetectAddress *target, - DetectAddress *source) -{ - if (source == NULL || target == NULL) - return -1; - - if (ntohl(source->ip.addr_data32[0]) < ntohl(target->ip.addr_data32[0])) - target->ip.addr_data32[0] = source->ip.addr_data32[0]; - - if (ntohl(source->ip2.addr_data32[0]) > ntohl(target->ip2.addr_data32[0])) - target->ip2.addr_data32[0] = source->ip2.addr_data32[0]; - - return 0; -} - -/********************************Unittests*************************************/ - -#ifdef UNITTESTS - -static int DetectAddressIPv4TestAddressCmp01(void) -{ - struct in_addr in; - int result = 1; - - DetectAddress *a = DetectAddressInit(); - if (a == NULL) - return 0; - - DetectAddress *b = DetectAddressInit(); - if (b == NULL) { - DetectAddressFree(a); - return 0; - } - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_EQ); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_ES); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_ES); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_ES); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_ES); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_ES); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_EB); - - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_EB); - - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_EB); - - if (inet_pton(AF_INET, "1.2.3.5", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_EB); - - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "128.128.128.128", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "128.128.128.128", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_LE); - - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "128.128.128.128", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_LE); - - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_LE); - - if (inet_pton(AF_INET, "170.170.170.169", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_LE); - - if (inet_pton(AF_INET, "170.170.170.169", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_LE); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_LT); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "185.185.185.185", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - /* we could get a LE */ - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - /* we could get a LE */ - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET, "128.128.128.128", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "128.128.128.128", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_GE); - - if (inet_pton(AF_INET, "128.128.128.128", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_GE); - - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_GE); - - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.169", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "180.180.180.180", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_GE); - - if (inet_pton(AF_INET, "170.170.170.169", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_GE); - - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.169.170", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_GE); - - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "200.200.200.200", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "185.185.185.185", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) == ADDRESS_GT); - - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "200.200.200.200", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_GT); - - if (inet_pton(AF_INET, "182.168.1.2", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "200.200.200.200", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "170.170.170.170", &in) < 0) - goto error; - b->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - b->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCmpIPv4(a, b) != ADDRESS_GT); - - DetectAddressFree(a); - DetectAddressFree(b); - return result; - - error: - DetectAddressFree(a); - DetectAddressFree(b); - return 0; -} - -static int DetectAddressIPv4IsCompleteIPSpace02(void) -{ - DetectAddress *a = NULL; - struct in_addr in; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - goto error; - - if (inet_pton(AF_INET, "0.0.0.0", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 1); - - if (inet_pton(AF_INET, "0.0.0.1", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - DetectAddressFree(a); - - if ( (a = DetectAddressInit()) == NULL) - goto error; - - if (inet_pton(AF_INET, "0.0.0.0", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "255.255.255.254", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - DetectAddressFree(a); - - return result; - - error: - if (a != NULL) - DetectAddressFree(a); - return 0; -} - -static int DetectAddressIPv4IsCompleteIPSpace03(void) -{ - DetectAddress *a = NULL; - DetectAddress *temp = NULL; - struct in_addr in; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - goto error; - temp = a; - - if (inet_pton(AF_INET, "0.0.0.0", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - if ( (temp->next = DetectAddressInit()) == NULL) - goto error; - temp = temp->next; - - if (inet_pton(AF_INET, "1.2.3.5", &in) < 0) - goto error; - temp->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "126.36.62.61", &in) < 0) - goto error; - temp->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - if ( (temp->next = DetectAddressInit()) == NULL) - goto error; - temp = temp->next; - - if (inet_pton(AF_INET, "126.36.62.62", &in) < 0) - goto error; - temp->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "222.52.21.62", &in) < 0) - goto error; - temp->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - if ( (temp->next = DetectAddressInit()) == NULL) - goto error; - temp = temp->next; - - if (inet_pton(AF_INET, "222.52.21.63", &in) < 0) - goto error; - temp->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "255.255.255.254", &in) < 0) - goto error; - temp->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - if ( (temp->next = DetectAddressInit()) == NULL) - goto error; - temp = temp->next; - - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - temp->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - temp->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 1); - - DetectAddressFree(a); - - return result; - - error: - if (a != NULL) - DetectAddressFree(a); - return 0; -} - -static int DetectAddressIPv4IsCompleteIPSpace04(void) -{ - DetectAddress *a = NULL; - DetectAddress *temp = NULL; - struct in_addr in; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - goto error; - temp = a; - - if (inet_pton(AF_INET, "0.0.0.0", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - if ( (temp->next = DetectAddressInit()) == NULL) - goto error; - temp = temp->next; - - if (inet_pton(AF_INET, "1.2.3.5", &in) < 0) - goto error; - temp->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "126.36.62.61", &in) < 0) - goto error; - temp->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - if ( (temp->next = DetectAddressInit()) == NULL) - goto error; - temp = temp->next; - - if (inet_pton(AF_INET, "126.36.62.62", &in) < 0) - goto error; - temp->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "222.52.21.62", &in) < 0) - goto error; - temp->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - if ( (temp->next = DetectAddressInit()) == NULL) - goto error; - temp = temp->next; - - if (inet_pton(AF_INET, "222.52.21.64", &in) < 0) - goto error; - temp->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "255.255.255.254", &in) < 0) - goto error; - temp->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - if ( (temp->next = DetectAddressInit()) == NULL) - goto error; - temp = temp->next; - - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - temp->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - temp->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressIsCompleteIPSpaceIPv4(a) == 0); - - DetectAddressFree(a); - - return result; - - error: - if (a != NULL) - DetectAddressFree(a); - return 0; -} - -static int DetectAddressIPv4CutNot05(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - struct in_addr in; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - return 0; - - if (inet_pton(AF_INET, "0.0.0.0", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCutNotIPv4(a, &b) == -1); - - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return result; - - error: - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return 0; -} - -static int DetectAddressIPv4CutNot06(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - struct in_addr in; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - return 0; - - if (inet_pton(AF_INET, "0.0.0.0", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCutNotIPv4(a, &b) == 0); - - if (inet_pton(AF_INET, "1.2.3.5", &in) < 0) - goto error; - result = (a->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - result &= (a->ip2.addr_data32[0] = in.s_addr); - - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return result; - - error: - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return 0; -} - -static int DetectAddressIPv4CutNot07(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - struct in_addr in; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - return 0; - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCutNotIPv4(a, &b) == 0); - - if (inet_pton(AF_INET, "0.0.0.0", &in) < 0) - goto error; - result = (a->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - result &= (a->ip2.addr_data32[0] = in.s_addr); - - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return result; - - error: - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return 0; -} - -static int DetectAddressIPv4CutNot08(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - struct in_addr in; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - return 0; - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCutNotIPv4(a, &b) == 0); - - if (inet_pton(AF_INET, "0.0.0.0", &in) < 0) - goto error; - result &= (a->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - result &= (a->ip2.addr_data32[0] = in.s_addr); - - if (b == NULL) { - result = 0; - goto error; - } else { - result &= 1; - } - if (inet_pton(AF_INET, "1.2.3.5", &in) < 0) - goto error; - result &= (b->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - result &= (b->ip2.addr_data32[0] = in.s_addr); - - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return result; - - error: - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return 0; -} - -static int DetectAddressIPv4CutNot09(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - struct in_addr in; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - return 0; - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - a->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - a->ip2.addr_data32[0] = in.s_addr; - result &= (DetectAddressCutNotIPv4(a, &b) == 0); - - if (inet_pton(AF_INET, "0.0.0.0", &in) < 0) - goto error; - result &= (a->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "1.2.3.3", &in) < 0) - goto error; - result &= (a->ip2.addr_data32[0] = in.s_addr); - - if (b == NULL) { - result = 0; - goto error; - } else { - result &= 1; - } - if (inet_pton(AF_INET, "192.168.1.3", &in) < 0) - goto error; - result &= (b->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "255.255.255.255", &in) < 0) - goto error; - result &= (b->ip2.addr_data32[0] = in.s_addr); - - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return result; - - error: - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return 0; -} - -static int DetectAddressIPv4Join10(void) -{ - struct in_addr in; - int result = 1; - - DetectAddress *source = DetectAddressInit(); - if (source == NULL) - return 0; - - DetectAddress *target = DetectAddressInit(); - if (target == NULL) { - DetectAddressFree(source); - return 0; - } - - if (inet_pton(AF_INET, "128.51.61.124", &in) < 0) - goto error; - target->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - target->ip2.addr_data32[0] = in.s_addr; - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - source->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - source->ip2.addr_data32[0] = in.s_addr; - - result &= (DetectAddressJoinIPv4(NULL, target, source) == 0); - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - result &= (target->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - result &= (target->ip2.addr_data32[0] == in.s_addr); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - target->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - target->ip2.addr_data32[0] = in.s_addr; - - if (inet_pton(AF_INET, "1.2.3.5", &in) < 0) - goto error; - source->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.1", &in) < 0) - goto error; - source->ip2.addr_data32[0] = in.s_addr; - - result &= (DetectAddressJoinIPv4(NULL, target, source) == 0); - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - result &= (target->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - result &= (target->ip2.addr_data32[0] == in.s_addr); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - target->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - target->ip2.addr_data32[0] = in.s_addr; - - if (inet_pton(AF_INET, "128.1.5.15", &in) < 0) - goto error; - source->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "200.202.200.200", &in) < 0) - goto error; - source->ip2.addr_data32[0] = in.s_addr; - - result &= (DetectAddressJoinIPv4(NULL, target, source) == 0); - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - result &= (target->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "200.202.200.200", &in) < 0) - goto error; - result &= (target->ip2.addr_data32[0] == in.s_addr); - - if (inet_pton(AF_INET, "128.51.61.124", &in) < 0) - goto error; - target->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - target->ip2.addr_data32[0] = in.s_addr; - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - source->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - source->ip2.addr_data32[0] = in.s_addr; - - result &= (DetectAddressJoinIPv4(NULL, target, source) == 0); - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - result &= (target->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - result &= (target->ip2.addr_data32[0] == in.s_addr); - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - target->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - target->ip2.addr_data32[0] = in.s_addr; - - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - source->ip.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - source->ip2.addr_data32[0] = in.s_addr; - - result &= (DetectAddressJoinIPv4(NULL, target, source) == 0); - if (inet_pton(AF_INET, "1.2.3.4", &in) < 0) - goto error; - result &= (target->ip.addr_data32[0] == in.s_addr); - if (inet_pton(AF_INET, "192.168.1.2", &in) < 0) - goto error; - result &= (target->ip2.addr_data32[0] == in.s_addr); - - DetectAddressFree(source); - DetectAddressFree(target); - return result; - - error: - DetectAddressFree(source); - DetectAddressFree(target); - return 0; -} - -#endif - -void DetectAddressIPv4Tests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectAddressIPv4TestAddressCmp01", - DetectAddressIPv4TestAddressCmp01, 1); - UtRegisterTest("DetectAddressIPv4IsCompleteIPSpace02", - DetectAddressIPv4IsCompleteIPSpace02, 1); - UtRegisterTest("DetectAddressIPv4IsCompleteIPSpace03", - DetectAddressIPv4IsCompleteIPSpace03, 1); - UtRegisterTest("DetectAddressIPv4IsCompleteIPSpace04", - DetectAddressIPv4IsCompleteIPSpace04, 1); - UtRegisterTest("DetectAddressIPv4CutNot05", DetectAddressIPv4CutNot05, 1); - UtRegisterTest("DetectAddressIPv4CutNot06", DetectAddressIPv4CutNot06, 1); - UtRegisterTest("DetectAddressIPv4CutNot07", DetectAddressIPv4CutNot07, 1); - UtRegisterTest("DetectAddressIPv4CutNot08", DetectAddressIPv4CutNot08, 1); - UtRegisterTest("DetectAddressIPv4CutNot09", DetectAddressIPv4CutNot09, 1); - UtRegisterTest("DetectAddressIPv4Join10", DetectAddressIPv4Join10, 1); -#endif -} diff --git a/framework/src/suricata/src/detect-engine-address-ipv4.h b/framework/src/suricata/src/detect-engine-address-ipv4.h deleted file mode 100644 index b8b7b344..00000000 --- a/framework/src/suricata/src/detect-engine-address-ipv4.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_ADDRESS_IPV4_H__ -#define __DETECT_ENGINE_ADDRESS_IPV4_H__ - -int DetectAddressCutNotIPv4(DetectAddress *, DetectAddress **); -int DetectAddressCmpIPv4(DetectAddress *a, DetectAddress *b); - -int DetectAddressCutIPv4(DetectEngineCtx *, DetectAddress *, - DetectAddress *, DetectAddress **); -int DetectAddressJoinIPv4(DetectEngineCtx *, DetectAddress *target, - DetectAddress *source); -int DetectAddressIsCompleteIPSpaceIPv4(DetectAddress *); - -void DetectAddressIPv4Tests(void); - -#endif /* __DETECT_ENGINE_ADDRESS_IPV4_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-address-ipv6.c b/framework/src/suricata/src/detect-engine-address-ipv6.c deleted file mode 100644 index 84a04d59..00000000 --- a/framework/src/suricata/src/detect-engine-address-ipv6.c +++ /dev/null @@ -1,2279 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * IPV6 Address part of the detection engine. - */ - -#include "suricata-common.h" - -#include "decode.h" -#include "detect.h" -#include "flow-var.h" - -#include "util-cidr.h" -#include "util-unittest.h" - -#include "detect-engine-address.h" -#include "detect-engine-siggroup.h" -#include "detect-engine-port.h" - -#include "util-debug.h" - -/** - * \brief Compares 2 ipv6 addresses and returns if the first address(a) is less - * than the second address(b) or not. - * - * \param a The first ipv6 address to be compared. - * \param b The second ipv6 address to be compared. - * - * \retval 1 If a < b. - * \retval 0 Otherwise, i.e. a >= b. - */ -int AddressIPv6Lt(Address *a, Address *b) -{ - int i = 0; - - for (i = 0; i < 4; i++) { - if (ntohl(a->addr_data32[i]) < ntohl(b->addr_data32[i])) - return 1; - if (ntohl(a->addr_data32[i]) > ntohl(b->addr_data32[i])) - break; - } - - return 0; -} - -int AddressIPv6LtU32(uint32_t *a, uint32_t *b) -{ - int i = 0; - - for (i = 0; i < 4; i++) { - if (ntohl(a[i]) < ntohl(b[i])) - return 1; - if (ntohl(a[i]) > ntohl(b[i])) - break; - } - - return 0; -} - -/** - * \brief Compares 2 ipv6 addresses and returns if the first address(a) is - * greater than the second address(b) or not. - * - * \param a The first ipv6 address to be compared. - * \param b The second ipv6 address to be compared. - * - * \retval 1 If a > b. - * \retval 0 Otherwise, i.e. a <= b. - */ -int AddressIPv6Gt(Address *a, Address *b) -{ - int i = 0; - - for (i = 0; i < 4; i++) { - if (ntohl(a->addr_data32[i]) > ntohl(b->addr_data32[i])) - return 1; - if (ntohl(a->addr_data32[i]) < ntohl(b->addr_data32[i])) - break; - } - - return 0; -} - -int AddressIPv6GtU32(uint32_t *a, uint32_t *b) -{ - int i = 0; - - for (i = 0; i < 4; i++) { - if (ntohl(a[i]) > ntohl(b[i])) - return 1; - if (ntohl(a[i]) < ntohl(b[i])) - break; - } - - return 0; -} - -/** - * \brief Compares 2 ipv6 addresses and returns if the addresses are equal - * or not. - * - * \param a The first ipv6 address to be compared. - * \param b The second ipv6 address to be compared. - * - * \retval 1 If a == b. - * \retval 0 Otherwise. - */ -int AddressIPv6Eq(Address *a, Address *b) -{ - int i = 0; - - for (i = 0; i < 4; i++) { - if (a->addr_data32[i] != b->addr_data32[i]) - return 0; - } - - return 1; -} - -int AddressIPv6EqU32(uint32_t *a, uint32_t *b) -{ - int i = 0; - - for (i = 0; i < 4; i++) { - if (a[i] != b[i]) - return 0; - } - - return 1; -} - -/** - * \brief Compares 2 ipv6 addresses and returns if the first address(a) is less - * than or equal to the second address(b) or not. - * - * \param a The first ipv6 address to be compared. - * \param b The second ipv6 address to be compared. - * - * \retval 1 If a <= b. - * \retval 0 Otherwise, i.e. a > b. - */ -int AddressIPv6Le(Address *a, Address *b) -{ - - if (AddressIPv6Eq(a, b) == 1) - return 1; - if (AddressIPv6Lt(a, b) == 1) - return 1; - - return 0; -} - -int AddressIPv6LeU32(uint32_t *a, uint32_t *b) -{ - - if (AddressIPv6EqU32(a, b) == 1) - return 1; - if (AddressIPv6LtU32(a, b) == 1) - return 1; - - return 0; -} - -/** - * \brief Compares 2 ipv6 addresses and returns if the first address(a) is - * greater than or equal to the second address(b) or not. - * - * \param a The first ipv6 address to be compared. - * \param b The second ipv6 address to be compared. - * - * \retval 1 If a >= b. - * \retval 0 Otherwise, i.e. a < b. - */ -int AddressIPv6Ge(Address *a, Address *b) -{ - - if (AddressIPv6Eq(a, b) == 1) - return 1; - if (AddressIPv6Gt(a, b) == 1) - return 1; - - return 0; -} - -int AddressIPv6GeU32(uint32_t *a, uint32_t *b) -{ - - if (AddressIPv6EqU32(a, b) == 1) - return 1; - if (AddressIPv6GtU32(a, b) == 1) - return 1; - - return 0; -} - -/** - * \brief Compares 2 addresses(address ranges) and returns the relationship - * between the 2 addresses. - * - * \param a Pointer to the first address instance to be compared. - * \param b Pointer to the second address instance to be compared. - * - * \retval ADDRESS_EQ If the 2 address ranges a and b, are equal. - * \retval ADDRESS_ES b encapsulates a. b_ip1[...a_ip1...a_ip2...]b_ip2. - * \retval ADDRESS_EB a encapsulates b. a_ip1[...b_ip1....b_ip2...]a_ip2. - * \retval ADDRESS_LE a_ip1(...b_ip1==a_ip2...)b_ip2 - * \retval ADDRESS_LT a_ip1(...b_ip1...a_ip2...)b_ip2 - * \retval ADDRESS_GE b_ip1(...a_ip1==b_ip2...)a_ip2 - * \retval ADDRESS_GT a_ip1 > b_ip2, i.e. the address range for 'a' starts only - * after the end of the address range for 'b' - */ -int DetectAddressCmpIPv6(DetectAddress *a, DetectAddress *b) -{ - if (AddressIPv6Eq(&a->ip, &b->ip) == 1 && - AddressIPv6Eq(&a->ip2, &b->ip2) == 1) { - return ADDRESS_EQ; - } else if (AddressIPv6Ge(&a->ip, &b->ip) == 1 && - AddressIPv6Le(&a->ip, &b->ip2) == 1 && - AddressIPv6Le(&a->ip2, &b->ip2) == 1) { - return ADDRESS_ES; - } else if (AddressIPv6Le(&a->ip, &b->ip) == 1 && - AddressIPv6Ge(&a->ip2, &b->ip2) == 1) { - return ADDRESS_EB; - } else if (AddressIPv6Lt(&a->ip, &b->ip) == 1 && - AddressIPv6Lt(&a->ip2, &b->ip2) == 1 && - AddressIPv6Ge(&a->ip2, &b->ip) == 1) { - return ADDRESS_LE; - } else if (AddressIPv6Lt(&a->ip, &b->ip) == 1 && - AddressIPv6Lt(&a->ip2, &b->ip2) == 1) { - return ADDRESS_LT; - } else if (AddressIPv6Gt(&a->ip, &b->ip) == 1 && - AddressIPv6Le(&a->ip, &b->ip2) == 1 && - AddressIPv6Gt(&a->ip2, &b->ip2) == 1) { - return ADDRESS_GE; - } else if (AddressIPv6Gt(&a->ip, &b->ip2) == 1) { - return ADDRESS_GT; - } else { - /* should be unreachable */ - SCLogDebug("Internal Error: should be unreachable\n"); - } - - return ADDRESS_ER; -} - -/** - * \brief Takes an IPv6 address in a, and returns in b an IPv6 address which is - * one less than the IPv6 address in a. The address sent in a is in host - * order, and the address in b will be returned in network order! - * - * \param a Pointer to an IPv6 address in host order. - * \param b Pointer to an IPv6 address store in memory which has to be updated - * with the new address(a - 1). - */ -static void AddressCutIPv6CopySubOne(uint32_t *a, uint32_t *b) -{ - uint32_t t = a[3]; - - b[0] = a[0]; - b[1] = a[1]; - b[2] = a[2]; - b[3] = a[3]; - - b[3]--; - if (b[3] > t) { - t = b[2]; - b[2]--; - if (b[2] > t) { - t = b[1]; - b[1]--; - if (b[1] > t) - b[0]--; - } - } - - b[0] = htonl(b[0]); - b[1] = htonl(b[1]); - b[2] = htonl(b[2]); - b[3] = htonl(b[3]); - - return; -} - -/** - * \brief Takes an IPv6 address in a, and returns in b an IPv6 address which is - * one more than the IPv6 address in a. The address sent in a is in host - * order, and the address in b will be returned in network order! - * - * \param a Pointer to an IPv6 address in host order. - * \param b Pointer to an IPv6 address store in memory which has to be updated - * with the new address(a + 1). - */ -static void AddressCutIPv6CopyAddOne(uint32_t *a, uint32_t *b) -{ - uint32_t t = a[3]; - - b[0] = a[0]; - b[1] = a[1]; - b[2] = a[2]; - b[3] = a[3]; - - b[3]++; - if (b[3] < t) { - t = b[2]; - b[2]++; - if (b[2] < t) { - t = b[1]; - b[1]++; - if (b[1] < t) - b[0]++; - } - } - - b[0] = htonl(b[0]); - b[1] = htonl(b[1]); - b[2] = htonl(b[2]); - b[3] = htonl(b[3]); - - return; -} - -/** - * \brief Copies an IPv6 address in a to the b. The address in a is in host - * order and will be copied in network order to b! - * - * \param a Pointer to the IPv6 address to be copied. - * \param b Pointer to an IPv6 address in memory which will be updated with the - * address in a. - */ -static void AddressCutIPv6Copy(uint32_t *a, uint32_t *b) -{ - b[0] = htonl(a[0]); - b[1] = htonl(a[1]); - b[2] = htonl(a[2]); - b[3] = htonl(a[3]); - - return; -} - -int DetectAddressCutIPv6(DetectEngineCtx *de_ctx, DetectAddress *a, - DetectAddress *b, DetectAddress **c) -{ - uint32_t a_ip1[4] = { ntohl(a->ip.addr_data32[0]), ntohl(a->ip.addr_data32[1]), - ntohl(a->ip.addr_data32[2]), ntohl(a->ip.addr_data32[3]) }; - uint32_t a_ip2[4] = { ntohl(a->ip2.addr_data32[0]), ntohl(a->ip2.addr_data32[1]), - ntohl(a->ip2.addr_data32[2]), ntohl(a->ip2.addr_data32[3]) }; - uint32_t b_ip1[4] = { ntohl(b->ip.addr_data32[0]), ntohl(b->ip.addr_data32[1]), - ntohl(b->ip.addr_data32[2]), ntohl(b->ip.addr_data32[3]) }; - uint32_t b_ip2[4] = { ntohl(b->ip2.addr_data32[0]), ntohl(b->ip2.addr_data32[1]), - ntohl(b->ip2.addr_data32[2]), ntohl(b->ip2.addr_data32[3]) }; - - DetectPort *port = NULL; - DetectAddress *tmp = NULL; - - /* default to NULL */ - *c = NULL; - - int r = DetectAddressCmpIPv6(a, b); - if (r != ADDRESS_ES && r != ADDRESS_EB && r != ADDRESS_LE && r != ADDRESS_GE) { - goto error; - } - - /* get a place to temporary put sigs lists */ - tmp = DetectAddressInit(); - if (tmp == NULL) - goto error; - memset(tmp,0,sizeof(DetectAddress)); - - /* we have 3 parts: [aaa[abab]bbb] - * part a: a_ip1 <-> b_ip1 - 1 - * part b: b_ip1 <-> a_ip2 - * part c: a_ip2 + 1 <-> b_ip2 - */ - if (r == ADDRESS_LE) { - AddressCutIPv6Copy(a_ip1, a->ip.addr_data32); - AddressCutIPv6CopySubOne(b_ip1, a->ip2.addr_data32); - - AddressCutIPv6Copy(b_ip1, b->ip.addr_data32); - AddressCutIPv6Copy(a_ip2, b->ip2.addr_data32); - - DetectAddress *tmp_c; - tmp_c = DetectAddressInit(); - if (tmp_c == NULL) - goto error; - tmp_c->ip.family = AF_INET6; - - AddressCutIPv6CopyAddOne(a_ip2, tmp_c->ip.addr_data32); - AddressCutIPv6Copy(b_ip2, tmp_c->ip2.addr_data32); - - *c = tmp_c; - - /* copy old b to c */ - SigGroupHeadCopySigs(de_ctx, b->sh, &tmp_c->sh); - /* copy old b to a */ - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &tmp_c->port, port); - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &b->port, port); - - tmp_c->cnt += b->cnt; - b->cnt += a->cnt; - - /* we have 3 parts: [bbb[baba]aaa] - * part a: b_ip1 <-> a_ip1 - 1 - * part b: a_ip1 <-> b_ip2 - * part c: b_ip2 + 1 <-> a_ip2 - */ - } else if (r == ADDRESS_GE) { - AddressCutIPv6Copy(b_ip1, a->ip.addr_data32); - AddressCutIPv6CopySubOne(a_ip1, a->ip2.addr_data32); - - AddressCutIPv6Copy(a_ip1, b->ip.addr_data32); - AddressCutIPv6Copy(b_ip2, b->ip2.addr_data32); - - DetectAddress *tmp_c; - tmp_c = DetectAddressInit(); - if (tmp_c == NULL) - goto error; - tmp_c->ip.family = AF_INET6; - - AddressCutIPv6CopyAddOne(b_ip2, tmp_c->ip.addr_data32); - AddressCutIPv6Copy(a_ip2, tmp_c->ip2.addr_data32); - *c = tmp_c; - - /* 'a' gets clean and then 'b' sigs - * 'b' gets clean, then 'a' then 'b' sigs - * 'c' gets 'a' sigs */ - /* store old a list */ - SigGroupHeadCopySigs(de_ctx, a->sh, &tmp->sh); - /* clean a list */ - SigGroupHeadClearSigs(a->sh); - /* copy old b to c */ - SigGroupHeadCopySigs(de_ctx, tmp->sh, &tmp_c->sh); - /* copy old b to a */ - SigGroupHeadCopySigs(de_ctx, b->sh, &a->sh); - /* prepend old a before b */ - SigGroupHeadCopySigs(de_ctx, tmp->sh, &b->sh); - - /* clean tmp list */ - SigGroupHeadClearSigs(tmp->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&tmp->port, port); - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&a->port, port); - - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&b->port, port); - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&tmp_c->port, port); - - tmp->cnt += a->cnt; - a->cnt = 0; - tmp_c->cnt += tmp->cnt; - a->cnt += b->cnt; - b->cnt += tmp->cnt; - tmp->cnt = 0; - - /* we have 2 or three parts: - * - * 2 part: [[abab]bbb] or [bbb[baba]] - * part a: a_ip1 <-> a_ip2 - * part b: a_ip2 + 1 <-> b_ip2 - * - * part a: b_ip1 <-> a_ip1 - 1 - * part b: a_ip1 <-> a_ip2 - * - * 3 part [bbb[aaa]bbb] - * part a: b_ip1 <-> a_ip1 - 1 - * part b: a_ip1 <-> a_ip2 - * part c: a_ip2 + 1 <-> b_ip2 - */ - } else if (r == ADDRESS_ES) { - if (AddressIPv6EqU32(a_ip1, b_ip1) == 1) { - AddressCutIPv6Copy(a_ip1, a->ip.addr_data32); - AddressCutIPv6Copy(a_ip2, a->ip2.addr_data32); - - AddressCutIPv6CopyAddOne(a_ip2, b->ip.addr_data32); - AddressCutIPv6Copy(b_ip2, b->ip2.addr_data32); - - /* 'b' overlaps 'a' so 'a' needs the 'b' sigs */ - SigGroupHeadCopySigs(de_ctx, b->sh, &a->sh); - - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&a->port, port); - - a->cnt += b->cnt; - - } else if (AddressIPv6EqU32(a_ip2, b_ip2) == 1) { - AddressCutIPv6Copy(b_ip1, a->ip.addr_data32); - AddressCutIPv6CopySubOne(a_ip1, a->ip2.addr_data32); - - AddressCutIPv6Copy(a_ip1, b->ip.addr_data32); - AddressCutIPv6Copy(a_ip2, b->ip2.addr_data32); - - SigGroupHeadCopySigs(de_ctx, b->sh, &tmp->sh); - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - SigGroupHeadClearSigs(a->sh); - SigGroupHeadCopySigs(de_ctx, tmp->sh, &a->sh); - SigGroupHeadClearSigs(tmp->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&tmp->port, a->port); - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&a->port, port); - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&b->port, port); - - tmp->cnt += a->cnt; - a->cnt = 0; - a->cnt += b->cnt; - b->cnt += tmp->cnt; - tmp->cnt = 0; - } else { - AddressCutIPv6Copy(b_ip1, a->ip.addr_data32); - AddressCutIPv6CopySubOne(a_ip1, a->ip2.addr_data32); - - AddressCutIPv6Copy(a_ip1, b->ip.addr_data32); - AddressCutIPv6Copy(a_ip2, b->ip2.addr_data32); - - DetectAddress *tmp_c; - tmp_c = DetectAddressInit(); - if (tmp_c == NULL) { - goto error; - } - tmp_c->ip.family = AF_INET6; - AddressCutIPv6CopyAddOne(a_ip2, tmp_c->ip.addr_data32); - AddressCutIPv6Copy(b_ip2, tmp_c->ip2.addr_data32); - *c = tmp_c; - - /* 'a' gets clean and then 'b' sigs - * 'b' gets clean, then 'a' then 'b' sigs - * 'c' gets 'b' sigs */ - /* store old a list */ - SigGroupHeadCopySigs(de_ctx, a->sh, &tmp->sh); - /* clean a list */ - SigGroupHeadClearSigs(a->sh); - /* copy old b to c */ - SigGroupHeadCopySigs(de_ctx, b->sh, &tmp_c->sh); - /* copy old b to a */ - SigGroupHeadCopySigs(de_ctx, b->sh, &a->sh); - /* prepend old a before b */ - SigGroupHeadCopySigs(de_ctx, tmp->sh, &b->sh); - - /* clean tmp list */ - SigGroupHeadClearSigs(tmp->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&tmp->port, port); - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&tmp_c->port, port); - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&a->port, port); - - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&b->port, port); - - tmp->cnt += a->cnt; - a->cnt = 0; - tmp_c->cnt += b->cnt; - a->cnt += b->cnt; - b->cnt += tmp->cnt; - tmp->cnt = 0; - } - /* we have 2 or three parts: - * - * 2 part: [[baba]aaa] or [aaa[abab]] - * part a: b_ip1 <-> b_ip2 - * part b: b_ip2 + 1 <-> a_ip2 - * - * part a: a_ip1 <-> b_ip1 - 1 - * part b: b_ip1 <-> b_ip2 - * - * 3 part [aaa[bbb]aaa] - * part a: a_ip1 <-> b_ip2 - 1 - * part b: b_ip1 <-> b_ip2 - * part c: b_ip2 + 1 <-> a_ip2 - */ - } else if (r == ADDRESS_EB) { - if (AddressIPv6EqU32(a_ip1, b_ip1) == 1) { - AddressCutIPv6Copy(b_ip1, a->ip.addr_data32); - AddressCutIPv6Copy(b_ip2, a->ip2.addr_data32); - - AddressCutIPv6CopyAddOne(b_ip2, b->ip.addr_data32); - AddressCutIPv6Copy(a_ip2, b->ip2.addr_data32); - - /* 'b' overlaps 'a' so a needs the 'b' sigs */ - SigGroupHeadCopySigs(de_ctx, b->sh, &tmp->sh); - SigGroupHeadClearSigs(b->sh); - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - SigGroupHeadCopySigs(de_ctx, tmp->sh, &a->sh); - SigGroupHeadClearSigs(tmp->sh); - - for (port = b->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&tmp->port, b->port); - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&b->port, port); - for (port = tmp->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&a->port, port); - - tmp->cnt += b->cnt; - b->cnt = 0; - b->cnt += a->cnt; - a->cnt += tmp->cnt; - tmp->cnt = 0; - } else if (AddressIPv6EqU32(a_ip2, b_ip2) == 1) { - AddressCutIPv6Copy(a_ip1, a->ip.addr_data32); - AddressCutIPv6CopySubOne(b_ip1, a->ip2.addr_data32); - - AddressCutIPv6Copy(b_ip1, b->ip.addr_data32); - AddressCutIPv6Copy(b_ip2, b->ip2.addr_data32); - - /* 'a' overlaps 'b' so a needs the 'a' sigs */ - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&b->port, port); - - b->cnt += a->cnt; - } else { - AddressCutIPv6Copy(a_ip1, a->ip.addr_data32); - AddressCutIPv6CopySubOne(b_ip1, a->ip2.addr_data32); - - AddressCutIPv6Copy(b_ip1, b->ip.addr_data32); - AddressCutIPv6Copy(b_ip2, b->ip2.addr_data32); - - DetectAddress *tmp_c; - tmp_c = DetectAddressInit(); - if (tmp_c == NULL) - goto error; - - tmp_c->ip.family = AF_INET6; - AddressCutIPv6CopyAddOne(b_ip2, tmp_c->ip.addr_data32); - AddressCutIPv6Copy(a_ip2, tmp_c->ip2.addr_data32); - *c = tmp_c; - - /* 'a' stays the same wrt sigs - * 'b' keeps it's own sigs and gets a's sigs prepended - * 'c' gets 'a' sigs */ - SigGroupHeadCopySigs(de_ctx, a->sh, &b->sh); - SigGroupHeadCopySigs(de_ctx, a->sh, &tmp_c->sh); - - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&b->port, port); - for (port = a->port; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx,&tmp_c->port, port); - - b->cnt += a->cnt; - tmp_c->cnt += a->cnt; - } - } - - if (tmp != NULL) - DetectAddressFree(tmp); - - return 0; - -error: - if (tmp != NULL) - DetectAddressFree(tmp); - return -1; -} - -#if 0 -int DetectAddressCutIPv6(DetectAddressData *a, DetectAddressData *b, - DetectAddressData **c) -{ - uint32_t a_ip1[4] = { ntohl(a->ip[0]), ntohl(a->ip[1]), - ntohl(a->ip[2]), ntohl(a->ip[3]) }; - uint32_t a_ip2[4] = { ntohl(a->ip2[0]), ntohl(a->ip2[1]), - ntohl(a->ip2[2]), ntohl(a->ip2[3]) }; - uint32_t b_ip1[4] = { ntohl(b->ip[0]), ntohl(b->ip[1]), - ntohl(b->ip[2]), ntohl(b->ip[3]) }; - uint32_t b_ip2[4] = { ntohl(b->ip2[0]), ntohl(b->ip2[1]), - ntohl(b->ip2[2]), ntohl(b->ip2[3]) }; - - /* default to NULL */ - *c = NULL; - - int r = DetectAddressCmpIPv6(a, b); - if (r != ADDRESS_ES && r != ADDRESS_EB && r != ADDRESS_LE && r != ADDRESS_GE) { - goto error; - } - - /* we have 3 parts: [aaa[abab]bbb] - * part a: a_ip1 <-> b_ip1 - 1 - * part b: b_ip1 <-> a_ip2 - * part c: a_ip2 + 1 <-> b_ip2 - */ - if (r == ADDRESS_LE) { - AddressCutIPv6Copy(a_ip1, a->ip); - AddressCutIPv6CopySubOne(b_ip1, a->ip2); - - AddressCutIPv6Copy(b_ip1, b->ip); - AddressCutIPv6Copy(a_ip2, b->ip2); - - DetectAddressData *tmp_c; - tmp_c = DetectAddressDataInit(); - if (tmp_c == NULL) - goto error; - tmp_c->family = AF_INET6; - - AddressCutIPv6CopyAddOne(a_ip2, tmp_c->ip); - AddressCutIPv6Copy(b_ip2, tmp_c->ip2); - - *c = tmp_c; - - /* we have 3 parts: [bbb[baba]aaa] - * part a: b_ip1 <-> a_ip1 - 1 - * part b: a_ip1 <-> b_ip2 - * part c: b_ip2 + 1 <-> a_ip2 - */ - } else if (r == ADDRESS_GE) { - AddressCutIPv6Copy(b_ip1, a->ip); - AddressCutIPv6CopySubOne(a_ip1, a->ip2); - - AddressCutIPv6Copy(a_ip1, b->ip); - AddressCutIPv6Copy(b_ip2, b->ip2); - - DetectAddressData *tmp_c; - tmp_c = DetectAddressDataInit(); - if (tmp_c == NULL) - goto error; - tmp_c->family = AF_INET6; - - AddressCutIPv6CopyAddOne(b_ip2, tmp_c->ip); - AddressCutIPv6Copy(a_ip2, tmp_c->ip2); - - *c = tmp_c; - - /* we have 2 or three parts: - * - * 2 part: [[abab]bbb] or [bbb[baba]] - * part a: a_ip1 <-> a_ip2 - * part b: a_ip2 + 1 <-> b_ip2 - * - * part a: b_ip1 <-> a_ip1 - 1 - * part b: a_ip1 <-> a_ip2 - * - * 3 part [bbb[aaa]bbb] - * part a: b_ip1 <-> a_ip1 - 1 - * part b: a_ip1 <-> a_ip2 - * part c: a_ip2 + 1 <-> b_ip2 - */ - } else if (r == ADDRESS_ES) { - if (AddressIPv6Eq(a_ip1,b_ip1) == 1) { - AddressCutIPv6Copy(a_ip1, a->ip); - AddressCutIPv6Copy(a_ip2, a->ip2); - - AddressCutIPv6CopyAddOne(a_ip2, b->ip); - AddressCutIPv6Copy(b_ip2, b->ip2); - } else if (AddressIPv6Eq(a_ip2, b_ip2) == 1) { - AddressCutIPv6Copy(b_ip1, a->ip); - AddressCutIPv6CopySubOne(a_ip1, a->ip2); - - AddressCutIPv6Copy(a_ip1, b->ip); - AddressCutIPv6Copy(a_ip2, b->ip2); - } else { - AddressCutIPv6Copy(b_ip1, a->ip); - AddressCutIPv6CopySubOne(a_ip1, a->ip2); - - AddressCutIPv6Copy(a_ip1, b->ip); - AddressCutIPv6Copy(a_ip2, b->ip2); - - DetectAddressData *tmp_c; - tmp_c = DetectAddressDataInit(); - if (tmp_c == NULL) - goto error; - - tmp_c->family = AF_INET6; - - AddressCutIPv6CopyAddOne(a_ip2, tmp_c->ip); - AddressCutIPv6Copy(b_ip2, tmp_c->ip2); - *c = tmp_c; - } - /* we have 2 or three parts: - * - * 2 part: [[baba]aaa] or [aaa[abab]] - * part a: b_ip1 <-> b_ip2 - * part b: b_ip2 + 1 <-> a_ip2 - * - * part a: a_ip1 <-> b_ip1 - 1 - * part b: b_ip1 <-> b_ip2 - * - * 3 part [aaa[bbb]aaa] - * part a: a_ip1 <-> b_ip2 - 1 - * part b: b_ip1 <-> b_ip2 - * part c: b_ip2 + 1 <-> a_ip2 - */ - } else if (r == ADDRESS_EB) { - if (AddressIPv6Eq(a_ip1, b_ip1) == 1) { - AddressCutIPv6Copy(b_ip1, a->ip); - AddressCutIPv6Copy(b_ip2, a->ip2); - - AddressCutIPv6CopyAddOne(b_ip2, b->ip); - AddressCutIPv6Copy(a_ip2, b->ip2); - } else if (AddressIPv6Eq(a_ip2, b_ip2) == 1) { - AddressCutIPv6Copy(a_ip1, a->ip); - AddressCutIPv6CopySubOne(b_ip1, a->ip2); - - AddressCutIPv6Copy(b_ip1, b->ip); - AddressCutIPv6Copy(b_ip2, b->ip2); - } else { - AddressCutIPv6Copy(a_ip1, a->ip); - AddressCutIPv6CopySubOne(b_ip1, a->ip2); - - AddressCutIPv6Copy(b_ip1, b->ip); - AddressCutIPv6Copy(b_ip2, b->ip2); - - DetectAddressData *tmp_c; - tmp_c = DetectAddressDataInit(); - if (tmp_c == NULL) - goto error; - tmp_c->family = AF_INET6; - - AddressCutIPv6CopyAddOne(b_ip2, tmp_c->ip); - AddressCutIPv6Copy(a_ip2, tmp_c->ip2); - *c = tmp_c; - } - } - - return 0; - -error: - return -1; -} -#endif - -/** - * \brief Cuts and returns an address range, which is the complement of the - * address range that is supplied as the argument. - * - * For example: - * - * If a = ::-2000::, - * then a = 2000::1-FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF and b = NULL - * If a = 2000::1-FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF, - * then a = ::-2000:: and b = NULL - * If a = 2000::1-20FF::2, - * then a = ::-2000:: and - * b = 20FF::3-FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF - * - * \param a Pointer to an address range (DetectAddress) instance whose complement - * has to be returned in a and b. - * \param b Pointer to DetectAddress pointer, that will be supplied back with a - * new DetectAddress instance, if the complement demands so. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressCutNotIPv6(DetectAddress *a, DetectAddress **b) -{ - uint32_t a_ip1[4] = { ntohl(a->ip.addr_data32[0]), ntohl(a->ip.addr_data32[1]), - ntohl(a->ip.addr_data32[2]), ntohl(a->ip.addr_data32[3]) }; - uint32_t a_ip2[4] = { ntohl(a->ip2.addr_data32[0]), ntohl(a->ip2.addr_data32[1]), - ntohl(a->ip2.addr_data32[2]), ntohl(a->ip2.addr_data32[3]) }; - uint32_t ip_nul[4] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; - uint32_t ip_max[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - - /* default to NULL */ - *b = NULL; - - if (!(a_ip1[0] == 0x00000000 && a_ip1[1] == 0x00000000 && - a_ip1[2] == 0x00000000 && a_ip1[3] == 0x00000000) && - !(a_ip2[0] == 0xFFFFFFFF && a_ip2[1] == 0xFFFFFFFF && - a_ip2[2] == 0xFFFFFFFF && a_ip2[3] == 0xFFFFFFFF)) { - AddressCutIPv6Copy(ip_nul, a->ip.addr_data32); - AddressCutIPv6CopySubOne(a_ip1, a->ip2.addr_data32); - - DetectAddress *tmp_b = DetectAddressInit(); - if (tmp_b == NULL) - goto error; - - tmp_b->ip.family = AF_INET6; - AddressCutIPv6CopyAddOne(a_ip2, tmp_b->ip.addr_data32); - AddressCutIPv6Copy(ip_max, tmp_b->ip2.addr_data32); - *b = tmp_b; - } else if ((a_ip1[0] == 0x00000000 && a_ip1[1] == 0x00000000 && - a_ip1[2] == 0x00000000 && a_ip1[3] == 0x00000000) && - !(a_ip2[0] == 0xFFFFFFFF && a_ip2[1] == 0xFFFFFFFF && - a_ip2[2] == 0xFFFFFFFF && a_ip2[3] == 0xFFFFFFFF)) { - AddressCutIPv6CopyAddOne(a_ip2, a->ip.addr_data32); - AddressCutIPv6Copy(ip_max, a->ip2.addr_data32); - } else if (!(a_ip1[0] == 0x00000000 && a_ip1[1] == 0x00000000 && - a_ip1[2] == 0x00000000 && a_ip1[3] == 0x00000000) && - (a_ip2[0] == 0xFFFFFFFF && a_ip2[1] == 0xFFFFFFFF && - a_ip2[2] == 0xFFFFFFFF && a_ip2[3] == 0xFFFFFFFF)) { - AddressCutIPv6Copy(ip_nul, a->ip.addr_data32); - AddressCutIPv6CopySubOne(a_ip1, a->ip2.addr_data32); - } else { - goto error; - } - - return 0; - -error: - return -1; -} - -/** - * \brief Extends a target address range if the the source address range is - * wider than the target address range on either sides. - * - * Every address is a range, i.e. address->ip1....address->ip2. For - * example 2000::-2010:: - * if source->ip1 is smaller than target->ip1, it indicates that the - * source's left address limit is greater(range wise) than the target's - * left address limit, and hence we reassign the target's left address - * limit to source's left address limit. - * Similary if source->ip2 is greater than target->ip2, it indicates that - * the source's right address limit is greater(range wise) than the - * target's right address limit, and hence we reassign the target's right - * address limit to source's right address limit. - * - * \param de_ctx Pointer to the detection engine context. - * \param target Pointer to the target DetectAddress instance that has to be - * updated. - * \param source Pointer to the source DetectAddress instance that is used - * to decided whether we extend the target's address range. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressJoinIPv6(DetectEngineCtx *de_ctx, DetectAddress *target, - DetectAddress *source) -{ - if (AddressIPv6Lt(&source->ip, &target->ip)) { - COPY_ADDRESS(&source->ip, &target->ip); - } - - if (AddressIPv6Gt(&source->ip, &target->ip)) { - COPY_ADDRESS(&source->ip2, &target->ip2); - } - - return 0; -} - - -/***************************************Unittests******************************/ - -#ifdef UNITTESTS - -int AddressTestIPv6Gt01(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 0, 2, 3, 4 }; - - if (AddressIPv6GtU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Gt02(void) -{ - int result = 0; - - uint32_t a[4] = { 0, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6GtU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Gt03(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6GtU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Gt04(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 5 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6GtU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Lt01(void) -{ - int result = 0; - - uint32_t a[4] = { 0, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6LtU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Lt02(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 0, 2, 3, 4 }; - - if (AddressIPv6LtU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Lt03(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6LtU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Lt04(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 5 }; - - if (AddressIPv6LtU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Eq01(void) -{ - int result = 0; - - uint32_t a[4] = { 0, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6EqU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Eq02(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 0, 2, 3, 4 }; - - if (AddressIPv6EqU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Eq03(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6EqU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Eq04(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 5 }; - - if (AddressIPv6EqU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Le01(void) -{ - int result = 0; - - uint32_t a[4] = { 0, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6LeU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Le02(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 0, 2, 3, 4 }; - - if (AddressIPv6LeU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Le03(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6LeU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Le04(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 5 }; - - if (AddressIPv6LeU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Le05(void) -{ - int result = 0; - - uint32_t a[4]; - uint32_t b[4]; - struct in6_addr in6; - - if (inet_pton(AF_INET6, "1999:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &in6) != 1) - return 0; - memcpy(&a, &in6.s6_addr, sizeof(in6.s6_addr)); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - return 0; - memcpy(&b, &in6.s6_addr, sizeof(in6.s6_addr)); - - if (AddressIPv6LeU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Ge01(void) -{ - int result = 0; - - uint32_t a[4] = { 0, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6GeU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Ge02(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 0, 2, 3, 4 }; - - if (AddressIPv6GeU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Ge03(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 4 }; - - if (AddressIPv6GeU32(a, b) == 1) - result = 1; - - return result; -} - -int AddressTestIPv6Ge04(void) -{ - int result = 0; - - uint32_t a[4] = { 1, 2, 3, 4 }; - uint32_t b[4] = { 1, 2, 3, 5 }; - - if (AddressIPv6GeU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6Ge05(void) -{ - int result = 0; - - uint32_t a[4]; - uint32_t b[4]; - struct in6_addr in6; - - if (inet_pton(AF_INET6, "1999:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &in6) != 1) - return 0; - memcpy(&a, &in6.s6_addr, sizeof(in6.s6_addr)); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - return 0; - memcpy(&b, &in6.s6_addr, sizeof(in6.s6_addr)); - - if (AddressIPv6GeU32(a, b) == 0) - result = 1; - - return result; -} - -int AddressTestIPv6SubOne01(void) -{ - int result = 0; - - uint32_t a[4], b[4]; - struct in6_addr in6; - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - return 0; - memcpy(a, in6.s6_addr, sizeof(in6.s6_addr)); - - a[0] = ntohl(a[0]); - a[1] = ntohl(a[1]); - a[2] = ntohl(a[2]); - a[3] = ntohl(a[3]); - - AddressCutIPv6CopySubOne(a, b); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - return 0; - memcpy(a, in6.s6_addr, sizeof(in6.s6_addr)); - if (b[0] == a[0] && b[1] == a[1] && - b[2] == a[2] && b[3] == a[3]) { - result = 1; - } - - return result; -} - -int AddressTestIPv6SubOne02(void) -{ - int result = 0; - - uint32_t a[4], b[4]; - struct in6_addr in6; - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - return 0; - memcpy(a, in6.s6_addr, sizeof(in6.s6_addr)); - - a[0] = ntohl(a[0]); - a[1] = ntohl(a[1]); - a[2] = ntohl(a[2]); - a[3] = ntohl(a[3]); - - AddressCutIPv6CopySubOne(a, b); - - if (inet_pton(AF_INET6, "1FFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", &in6) != 1) - return 0; - memcpy(a, in6.s6_addr, sizeof(in6.s6_addr)); - if (b[0] == a[0] && b[1] == a[1] && - b[2] == a[2] && b[3] == a[3]) { - result = 1; - } - - return result; -} - -int AddressTestIPv6AddOne01(void) -{ - int result = 0; - - uint32_t a[4], b[4]; - struct in6_addr in6; - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - return 0; - memcpy(a, in6.s6_addr, sizeof(in6.s6_addr)); - - a[0] = ntohl(a[0]); - a[1] = ntohl(a[1]); - a[2] = ntohl(a[2]); - a[3] = ntohl(a[3]); - - AddressCutIPv6CopyAddOne(a, b); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - return 0; - memcpy(a, in6.s6_addr, sizeof(in6.s6_addr)); - if (b[0] == a[0] && b[1] == a[1] && - b[2] == a[2] && b[3] == a[3]) { - result = 1; - } - - return result; -} - -int AddressTestIPv6AddOne02(void) -{ - int result = 0; - - uint32_t a[4], b[4]; - struct in6_addr in6; - - if (inet_pton(AF_INET6, "1FFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", &in6) != 1) - return 0; - memcpy(a, in6.s6_addr, sizeof(in6.s6_addr)); - - a[0] = ntohl(a[0]); - a[1] = ntohl(a[1]); - a[2] = ntohl(a[2]); - a[3] = ntohl(a[3]); - - AddressCutIPv6CopyAddOne(a, b); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - return 0; - memcpy(a, in6.s6_addr, sizeof(in6.s6_addr)); - if (b[0] == a[0] && b[1] == a[1] && - b[2] == a[2] && b[3] == a[3]) { - result = 1; - } - - return result; -} - -static int AddressTestIPv6AddressCmp01(void) -{ - DetectAddress *a = DetectAddressInit(); - DetectAddress *b = DetectAddressInit(); - struct in6_addr in6; - int result = 1; - - if (a == NULL || b == NULL) - goto error; - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_EQ); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_ES); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::11", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_ES); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_ES); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::11", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_ES); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::11", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_ES); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::11", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_EB); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_EB); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::11", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_EB); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::11", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_EB); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_LE); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::15", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_LE); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_LE); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_LE); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_LE); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::15", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_LT); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::15", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - /* we could get a LE */ - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - /* we could get a LE */ - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::19", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_LT); - - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_GE); - - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::15", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_GE); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::15", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_GE); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_GE); - - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::19", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_GE); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_GE); - - if (inet_pton(AF_INET6, "2000::15", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) == ADDRESS_GT); - - if (inet_pton(AF_INET6, "2000::15", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::15", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_GT); - - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&b->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&b->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCmpIPv6(a, b) != ADDRESS_GT); - - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return result; - - error: - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return 0; -} - -static int AddressTestIPv6CutNot01(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - struct in6_addr in6; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - goto error; - - if (inet_pton(AF_INET6, "::", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCutNotIPv6(a, &b) == -1); - - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return result; - - error: - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - return 0; -} - -static int AddressTestIPv6CutNot02(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - DetectAddress *temp = NULL; - struct in6_addr in6; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - goto error; - if ( (temp = DetectAddressInit()) == NULL) - goto error; - - if (inet_pton(AF_INET6, "::", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCutNotIPv6(a, &b) == 0); - - result &= (b == NULL); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - result = (DetectAddressCmpIPv6(a, temp) == ADDRESS_EQ); - - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - if (temp != NULL) - DetectAddressFree(temp); - return result; - - error: - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - if (temp != NULL) - DetectAddressFree(temp); - return 0; -} - -static int AddressTestIPv6CutNot03(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - DetectAddress *temp = NULL; - struct in6_addr in6; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - goto error; - if ( (temp = DetectAddressInit()) == NULL) - goto error; - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCutNotIPv6(a, &b) == 0); - - result &= (b == NULL); - - if (inet_pton(AF_INET6, "::", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - result = (DetectAddressCmpIPv6(a, temp) == ADDRESS_EQ); - - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - if (temp != NULL) - DetectAddressFree(temp); - return result; - - error: - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - if (temp != NULL) - DetectAddressFree(temp); - return 0; -} - -static int AddressTestIPv6CutNot04(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - DetectAddress *temp = NULL; - struct in6_addr in6; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - goto error; - if ( (temp = DetectAddressInit()) == NULL) - goto error; - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCutNotIPv6(a, &b) == 0); - - if (inet_pton(AF_INET6, "::", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result = (DetectAddressCmpIPv6(a, temp) == ADDRESS_EQ); - - result &= (b != NULL); - if (result == 0) - goto error; - if (inet_pton(AF_INET6, "2000::2", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result = (DetectAddressCmpIPv6(b, temp) == ADDRESS_EQ); - - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - if (temp != NULL) - DetectAddressFree(temp); - return result; - - error: - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - if (temp != NULL) - DetectAddressFree(temp); - return 0; -} - -static int AddressTestIPv6CutNot05(void) -{ - DetectAddress *a = NULL; - DetectAddress *b = NULL; - DetectAddress *temp = NULL; - struct in6_addr in6; - int result = 1; - - if ( (a = DetectAddressInit()) == NULL) - goto error; - if ( (temp = DetectAddressInit()) == NULL) - goto error; - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&a->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&a->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result &= (DetectAddressCutNotIPv6(a, &b) == 0); - - if (inet_pton(AF_INET6, "::", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::0", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result = (DetectAddressCmpIPv6(a, temp) == ADDRESS_EQ); - - result &= (b != NULL); - if (result == 0) - goto error; - if (inet_pton(AF_INET6, "2000::21", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result = (DetectAddressCmpIPv6(b, temp) == ADDRESS_EQ); - - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - if (temp != NULL) - DetectAddressFree(temp); - return result; - - error: - if (a != NULL) - DetectAddressFree(a); - if (b != NULL) - DetectAddressFree(b); - if (temp != NULL) - DetectAddressFree(temp); - return 0; -} - -static int AddressTestIPv6Join01(void) -{ - DetectAddress *source = DetectAddressInit(); - DetectAddress *target = DetectAddressInit(); - DetectAddress *temp = DetectAddressInit(); - struct in6_addr in6; - int result = 1; - - if (source == NULL || target == NULL || temp == NULL) - goto error; - - /* case 1 */ - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&target->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&target->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&source->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&source->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - result &= (DetectAddressJoinIPv6(NULL, target, source) == 0); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result = (DetectAddressCmpIPv6(target, temp) == ADDRESS_EQ); - - /* case 2 */ - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&target->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&target->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - if (inet_pton(AF_INET6, "2000::2", &in6) != 1) - goto error; - memcpy(&source->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::19", &in6) != 1) - goto error; - memcpy(&source->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - result &= (DetectAddressJoinIPv6(NULL, target, source) == 0); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result = (DetectAddressCmpIPv6(target, temp) == ADDRESS_EQ); - - /* case 3 */ - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&target->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::15", &in6) != 1) - goto error; - memcpy(&target->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&source->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&source->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - result &= (DetectAddressJoinIPv6(NULL, target, source) == 0); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result = (DetectAddressCmpIPv6(target, temp) == ADDRESS_EQ); - - /* case 4 */ - if (inet_pton(AF_INET6, "2000::10", &in6) != 1) - goto error; - memcpy(&target->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&target->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&source->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&source->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - result &= (DetectAddressJoinIPv6(NULL, target, source) == 0); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result = (DetectAddressCmpIPv6(target, temp) == ADDRESS_EQ); - - /* case 5 */ - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&target->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&target->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&source->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&source->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - - result &= (DetectAddressJoinIPv6(NULL, target, source) == 0); - if (inet_pton(AF_INET6, "2000::1", &in6) != 1) - goto error; - memcpy(&temp->ip.address, in6.s6_addr, sizeof(in6.s6_addr)); - if (inet_pton(AF_INET6, "2000::20", &in6) != 1) - goto error; - memcpy(&temp->ip2.address, in6.s6_addr, sizeof(in6.s6_addr)); - result = (DetectAddressCmpIPv6(target, temp) == ADDRESS_EQ); - - if (source != NULL) - DetectAddressFree(source); - if (target != NULL) - DetectAddressFree(target); - if (temp != NULL) - DetectAddressFree(temp); - return result; - - error: - if (source != NULL) - DetectAddressFree(source); - if (target != NULL) - DetectAddressFree(target); - if (temp != NULL) - DetectAddressFree(temp); - - return 0; -} - -#endif /* UNITTESTS */ - -void DetectAddressIPv6Tests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("AddressTestIPv6Gt01", AddressTestIPv6Gt01, 1); - UtRegisterTest("AddressTestIPv6Gt02", AddressTestIPv6Gt02, 1); - UtRegisterTest("AddressTestIPv6Gt03", AddressTestIPv6Gt03, 1); - UtRegisterTest("AddressTestIPv6Gt04", AddressTestIPv6Gt04, 1); - - UtRegisterTest("AddressTestIPv6Lt01", AddressTestIPv6Lt01, 1); - UtRegisterTest("AddressTestIPv6Lt02", AddressTestIPv6Lt02, 1); - UtRegisterTest("AddressTestIPv6Lt03", AddressTestIPv6Lt03, 1); - UtRegisterTest("AddressTestIPv6Lt04", AddressTestIPv6Lt04, 1); - - UtRegisterTest("AddressTestIPv6Eq01", AddressTestIPv6Eq01, 1); - UtRegisterTest("AddressTestIPv6Eq02", AddressTestIPv6Eq02, 1); - UtRegisterTest("AddressTestIPv6Eq03", AddressTestIPv6Eq03, 1); - UtRegisterTest("AddressTestIPv6Eq04", AddressTestIPv6Eq04, 1); - - UtRegisterTest("AddressTestIPv6Le01", AddressTestIPv6Le01, 1); - UtRegisterTest("AddressTestIPv6Le02", AddressTestIPv6Le02, 1); - UtRegisterTest("AddressTestIPv6Le03", AddressTestIPv6Le03, 1); - UtRegisterTest("AddressTestIPv6Le04", AddressTestIPv6Le04, 1); - UtRegisterTest("AddressTestIPv6Le05", AddressTestIPv6Le05, 1); - - UtRegisterTest("AddressTestIPv6Ge01", AddressTestIPv6Ge01, 1); - UtRegisterTest("AddressTestIPv6Ge02", AddressTestIPv6Ge02, 1); - UtRegisterTest("AddressTestIPv6Ge03", AddressTestIPv6Ge03, 1); - UtRegisterTest("AddressTestIPv6Ge04", AddressTestIPv6Ge04, 1); - UtRegisterTest("AddressTestIPv6Ge05", AddressTestIPv6Ge05, 1); - - UtRegisterTest("AddressTestIPv6SubOne01", AddressTestIPv6SubOne01, 1); - UtRegisterTest("AddressTestIPv6SubOne02", AddressTestIPv6SubOne02, 1); - - UtRegisterTest("AddressTestIPv6AddOne01", AddressTestIPv6AddOne01, 1); - UtRegisterTest("AddressTestIPv6AddOne02", AddressTestIPv6AddOne02, 1); - - UtRegisterTest("AddressTestIPv6AddressCmp01", - AddressTestIPv6AddressCmp01, 1); - - UtRegisterTest("AddressTestIPv6CutNot01", AddressTestIPv6CutNot01, 1); - UtRegisterTest("AddressTestIPv6CutNot02", AddressTestIPv6CutNot02, 1); - UtRegisterTest("AddressTestIPv6CutNot03", AddressTestIPv6CutNot03, 1); - UtRegisterTest("AddressTestIPv6CutNot04", AddressTestIPv6CutNot04, 1); - UtRegisterTest("AddressTestIPv6CutNot05", AddressTestIPv6CutNot05, 1); - - UtRegisterTest("AddressTestIPv6Join01", AddressTestIPv6Join01, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-engine-address-ipv6.h b/framework/src/suricata/src/detect-engine-address-ipv6.h deleted file mode 100644 index dedf090b..00000000 --- a/framework/src/suricata/src/detect-engine-address-ipv6.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_ADDRESS_IPV6_H__ -#define __DETECT_ENGINE_ADDRESS_IPV6_H__ - -int AddressIPv6Lt(Address *, Address *); -int AddressIPv6Gt(Address *, Address *); -int AddressIPv6Eq(Address *, Address *); -int AddressIPv6Le(Address *, Address *); -int AddressIPv6Ge(Address *, Address *); - -int DetectAddressCutNotIPv6(DetectAddress *, DetectAddress **); -int DetectAddressCmpIPv6(DetectAddress *a, DetectAddress *b); - -int DetectAddressCutIPv6(DetectEngineCtx *, DetectAddress *, DetectAddress *, - DetectAddress **); -int DetectAddressJoinIPv6(DetectEngineCtx *, DetectAddress *, DetectAddress *); - -void DetectAddressIPv6Tests(void); - -#endif /* __DETECT_ENGINE_ADDRESS_IPV6_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-address.c b/framework/src/suricata/src/detect-engine-address.c deleted file mode 100644 index 31e6a7ab..00000000 --- a/framework/src/suricata/src/detect-engine-address.c +++ /dev/null @@ -1,5419 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Address part of the detection engine. - * - * \todo Move this out of the detection plugin structure - * rename to detect-engine-address.c - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "flow-var.h" - -#include "util-cidr.h" -#include "util-unittest.h" -#include "util-rule-vars.h" -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "detect-engine-siggroup.h" -#include "detect-engine-address.h" -#include "detect-engine-address-ipv4.h" -#include "detect-engine-address-ipv6.h" -#include "detect-engine-port.h" - -#include "util-debug.h" -#include "util-print.h" - -/* prototypes */ -void DetectAddressPrint(DetectAddress *); -static int DetectAddressCutNot(DetectAddress *, DetectAddress **); -static int DetectAddressCut(DetectEngineCtx *, DetectAddress *, DetectAddress *, - DetectAddress **); -int DetectAddressMergeNot(DetectAddressHead *gh, DetectAddressHead *ghn); - -/** memory usage counters - * \todo not MT safe */ -#ifdef DEBUG -static uint32_t detect_address_group_memory = 0; -static uint32_t detect_address_group_init_cnt = 0; -static uint32_t detect_address_group_free_cnt = 0; - -static uint32_t detect_address_group_head_memory = 0; -static uint32_t detect_address_group_head_init_cnt = 0; -static uint32_t detect_address_group_head_free_cnt = 0; -#endif - -/** - * \brief Creates and returns a new instance of a DetectAddress. - * - * \retval ag Pointer to the newly created DetectAddress on success; - * NULL on failure. - */ -DetectAddress *DetectAddressInit(void) -{ - DetectAddress *ag = SCMalloc(sizeof(DetectAddress)); - if (unlikely(ag == NULL)) - return NULL; - memset(ag, 0, sizeof(DetectAddress)); - -#ifdef DEBUG - detect_address_group_memory += sizeof(DetectAddress); - detect_address_group_init_cnt++; -#endif - - return ag; -} - -/** - * \brief Frees a DetectAddress instance. - * - * \param ag Pointer to the DetectAddress instance to be freed. - */ -void DetectAddressFree(DetectAddress *ag) -{ - if (ag == NULL) - return; - - SCLogDebug("ag %p, sh %p", ag, ag->sh); - - /* only free the head if we have the original */ - if (ag->sh != NULL && !(ag->flags & ADDRESS_SIGGROUPHEAD_COPY)) { - SCLogDebug("- ag %p, sh %p not a copy, so call SigGroupHeadFree", ag, - ag->sh); - SigGroupHeadFree(ag->sh); - } - ag->sh = NULL; - - if (!(ag->flags & ADDRESS_HAVEPORT)) { - SCLogDebug("- ag %p dst_gh %p", ag, ag->dst_gh); - - if (ag->dst_gh != NULL) - DetectAddressHeadFree(ag->dst_gh); - ag->dst_gh = NULL; - } else { - SCLogDebug("- ag %p port %p", ag, ag->port); - - if (ag->port != NULL && !(ag->flags & ADDRESS_PORTS_COPY)) { - SCLogDebug("- ag %p port %p, not a copy so call DetectPortCleanupList", - ag, ag->port); - DetectPortCleanupList(ag->port); - } - ag->port = NULL; - } -#ifdef DEBUG - detect_address_group_memory -= sizeof(DetectAddress); - detect_address_group_free_cnt++; -#endif - SCFree(ag); - - return; -} - -/** - * \brief Copies the contents of one Address group in DetectAddress and returns - * a new instance of the DetectAddress that contains the copied address. - * - * \param orig Pointer to the instance of DetectAddress that contains the - * address data to be copied to the new instance. - * - * \retval ag Pointer to the new instance of DetectAddress that contains the - * copied address. - */ -DetectAddress *DetectAddressCopy(DetectAddress *orig) -{ - DetectAddress *ag = DetectAddressInit(); - if (ag == NULL) - return NULL; - - ag->flags = orig->flags; - - COPY_ADDRESS(&orig->ip, &ag->ip); - COPY_ADDRESS(&orig->ip2, &ag->ip2); - - ag->cnt = 1; - - return ag; -} - -/** - * \brief Prints the memory statistics for the detection-engine-address section. - */ -void DetectAddressPrintMemory(void) -{ -#ifdef DEBUG - SCLogDebug(" * Address group memory stats (DetectAddress %" PRIuMAX "):", - (uintmax_t)sizeof(DetectAddress)); - SCLogDebug(" - detect_address_group_memory %" PRIu32, - detect_address_group_memory); - SCLogDebug(" - detect_address_group_init_cnt %" PRIu32, - detect_address_group_init_cnt); - SCLogDebug(" - detect_address_group_free_cnt %" PRIu32, - detect_address_group_free_cnt); - SCLogDebug(" - outstanding groups %" PRIu32, - detect_address_group_init_cnt - detect_address_group_free_cnt); - SCLogDebug(" * Address group memory stats done"); - SCLogDebug(" * Address group head memory stats (DetectAddressHead %" PRIuMAX "):", - (uintmax_t)sizeof(DetectAddressHead)); - SCLogDebug(" - detect_address_group_head_memory %" PRIu32, - detect_address_group_head_memory); - SCLogDebug(" - detect_address_group_head_init_cnt %" PRIu32, - detect_address_group_head_init_cnt); - SCLogDebug(" - detect_address_group_head_free_cnt %" PRIu32, - detect_address_group_head_free_cnt); - SCLogDebug(" - outstanding groups %" PRIu32, - (detect_address_group_head_init_cnt - - detect_address_group_head_free_cnt)); - SCLogDebug(" * Address group head memory stats done"); - SCLogDebug(" X Total %" PRIu32 "\n", (detect_address_group_memory + - detect_address_group_head_memory)); -#endif - - return; -} - -/** - * \brief Used to check if a DetectAddress list contains an instance with - * a similar DetectAddress. The comparison done is not the one that - * checks the memory for the same instance, but one that checks that the - * two instances hold the same content. - * - * \param head Pointer to the DetectAddress list. - * \param ad Pointer to the DetectAddress that has to be checked for in - * the DetectAddress list. - * - * \retval cur Returns a pointer to the DetectAddress on a match; NULL if - * no match. - */ -DetectAddress *DetectAddressLookupInList(DetectAddress *head, DetectAddress *gr) -{ - DetectAddress *cur; - - if (head != NULL) { - for (cur = head; cur != NULL; cur = cur->next) { - if (DetectAddressCmp(cur, gr) == ADDRESS_EQ) - return cur; - } - } - - return NULL; -} - -/** - * \brief Prints the address data information for all the DetectAddress - * instances in the DetectAddress list sent as the argument. - * - * \param head Pointer to a list of DetectAddress instances. - */ -void DetectAddressPrintList(DetectAddress *head) -{ - DetectAddress *cur; - - SCLogInfo("list:"); - if (head != NULL) { - for (cur = head; cur != NULL; cur = cur->next) { - SCLogInfo("SIGS %6u ", cur->sh ? cur->sh->sig_cnt : 0); - DetectAddressPrint(cur); - } - } - SCLogInfo("endlist"); - - return; -} - -/** - * \brief Frees a list of DetectAddress instances. - * - * \param head Pointer to a list of DetectAddress instances to be freed. - */ -void DetectAddressCleanupList(DetectAddress *head) -{ - DetectAddress *cur, *next; - - if (head == NULL) - return; - - for (cur = head; cur != NULL; ) { - next = cur->next; - cur->next = NULL; - DetectAddressFree(cur); - cur = next; - } - - return; -} - -/** - * \brief Do a sorted insert, where the top of the list should be the biggest - * network/range. - * - * XXX current sorting only works for overlapping nets - * - * \param head Pointer to the list of DetectAddress. - * \param ag Pointer to the DetectAddress that has to be added to the - * above list. - * - * \retval 0 On successfully inserting the DetectAddress. - * \retval -1 On failure. - */ - -int DetectAddressAdd(DetectAddress **head, DetectAddress *ag) -{ - DetectAddress *cur, *prev_cur = NULL; - int r = 0; - - if (*head != NULL) { - for (cur = *head; cur != NULL; cur = cur->next) { - prev_cur = cur; - r = DetectAddressCmp(ag, cur); - if (r == ADDRESS_EB) { - /* insert here */ - ag->prev = cur->prev; - ag->next = cur; - - cur->prev = ag; - if (*head == cur) - *head = ag; - else - ag->prev->next = ag; - - return 0; - } - } - ag->prev = prev_cur; - if (prev_cur != NULL) - prev_cur->next = ag; - } else { - *head = ag; - } - - return 0; -} - -/** - * \internal - * \brief Helper function for DetectAddressInsert. Sets one of the - * DetectAddressHead head pointers, to the DetectAddress argument - * based on its address family. - * - * \param gh Pointer to the DetectAddressHead. - * \param newhead Pointer to the DetectAddress. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int SetHeadPtr(DetectAddressHead *gh, DetectAddress *newhead) -{ - if (newhead->flags & ADDRESS_FLAG_ANY) { - gh->any_head = newhead; - } else if (newhead->ip.family == AF_INET) { - gh->ipv4_head = newhead; - } else if (newhead->ip.family == AF_INET6) { - gh->ipv6_head = newhead; - } else { - SCLogDebug("newhead->family %u not supported", newhead->ip.family); - return -1; - } - - return 0; -} - -/** - * \internal - * \brief Returns the DetectAddress head from the DetectAddressHeads, - * based on the address family of the incoming DetectAddress arg. - * - * \param gh Pointer to the DetectAddressHead. - * \param new Pointer to the DetectAddress. - * - * \retval head Pointer to the DetectAddress(the head from - * DetectAddressHead). - */ -static DetectAddress *GetHeadPtr(DetectAddressHead *gh, DetectAddress *new) -{ - DetectAddress *head = NULL; - - if (new->flags & ADDRESS_FLAG_ANY) - head = gh->any_head; - else if (new->ip.family == AF_INET) - head = gh->ipv4_head; - else if (new->ip.family == AF_INET6) - head = gh->ipv6_head; - - return head; -} - -/** - * \brief Same as DetectAddressInsert, but then for inserting a address group - * object. This also makes sure SigGroupContainer lists are handled - * correctly. - * - * \param de_ctx Pointer to the detection engine context. - * \param gh Pointer to the DetectAddressHead list to which it has to - * be inserted. - * \param new Pointer to the DetectAddress, that has to be inserted. - * - * \retval 1 On successfully inserting it. - * \retval -1 On error. - * \retval 0 Not inserted, memory of new is freed. - */ -int DetectAddressInsert(DetectEngineCtx *de_ctx, DetectAddressHead *gh, - DetectAddress *new) -{ - DetectAddress *head = NULL; - DetectAddress *cur = NULL; - DetectAddress *c = NULL; - int r = 0; - - if (new == NULL) - return 0; - - BUG_ON(new->ip.family == 0 && !(new->flags & ADDRESS_FLAG_ANY)); - - /* get our head ptr based on the address we want to insert */ - head = GetHeadPtr(gh, new); - - /* see if it already exists or overlaps with existing ag's */ - if (head != NULL) { - cur = NULL; - - for (cur = head; cur != NULL; cur = cur->next) { - r = DetectAddressCmp(new, cur); - BUG_ON(r == ADDRESS_ER); - - /* if so, handle that */ - if (r == ADDRESS_EQ) { - /* exact overlap/match */ - if (cur != new) { - DetectPort *port = new->port; - for ( ; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &cur->port, port); - SigGroupHeadCopySigs(de_ctx, new->sh, &cur->sh); - cur->cnt += new->cnt; - DetectAddressFree(new); - - return 0; - } - - return 1; - } else if (r == ADDRESS_GT) { - /* only add it now if we are bigger than the last group. - * Otherwise we'll handle it later. */ - if (cur->next == NULL) { - /* put in the list */ - new->prev = cur; - cur->next = new; - - return 1; - } - } else if (r == ADDRESS_LT) { - /* see if we need to insert the ag anywhere put in the list */ - if (cur->prev != NULL) - cur->prev->next = new; - new->prev = cur->prev; - new->next = cur; - cur->prev = new; - - /* update head if required */ - if (head == cur) { - head = new; - - if (SetHeadPtr(gh, head) < 0) - goto error; - } - - return 1; - /* alright, those were the simple cases, lets handle the more - * complex ones now */ - } else if (r == ADDRESS_ES) { - c = NULL; - r = DetectAddressCut(de_ctx, cur, new, &c); - if (r == -1) - goto error; - - DetectAddressInsert(de_ctx, gh, new); - if (c != NULL) - DetectAddressInsert(de_ctx, gh, c); - - return 1; - } else if (r == ADDRESS_EB) { - c = NULL; - r = DetectAddressCut(de_ctx, cur, new, &c); - if (r == -1) - goto error; - - DetectAddressInsert(de_ctx, gh, new); - if (c != NULL) - DetectAddressInsert(de_ctx, gh, c); - - return 1; - } else if (r == ADDRESS_LE) { - c = NULL; - r = DetectAddressCut(de_ctx, cur, new, &c); - if (r == -1) - goto error; - - DetectAddressInsert(de_ctx, gh, new); - if (c != NULL) - DetectAddressInsert(de_ctx, gh, c); - - return 1; - } else if (r == ADDRESS_GE) { - c = NULL; - r = DetectAddressCut(de_ctx, cur,new,&c); - if (r == -1) - goto error; - - DetectAddressInsert(de_ctx, gh, new); - if (c != NULL) - DetectAddressInsert(de_ctx, gh, c); - - return 1; - } - } - - /* head is NULL, so get a group and set head to it */ - } else { - head = new; - if (SetHeadPtr(gh, head) < 0) { - SCLogDebug("SetHeadPtr failed"); - goto error; - } - } - - return 1; - -error: - /* XXX */ - return -1; -} - -/** - * \brief Join two addresses groups together. - * - * \param de_ctx Pointer to the detection engine context. - * \param target Pointer to the target address group. - * \param source Pointer to the source address group. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressJoin(DetectEngineCtx *de_ctx, DetectAddress *target, - DetectAddress *source) -{ - DetectPort *port = NULL; - - if (target == NULL || source == NULL) - return -1; - - if (target->ip.family != source->ip.family) - return -1; - - target->cnt += source->cnt; - SigGroupHeadCopySigs(de_ctx, source->sh, &target->sh); - - port = source->port; - for ( ; port != NULL; port = port->next) - DetectPortInsertCopy(de_ctx, &target->port, port); - - if (target->ip.family == AF_INET) - return DetectAddressJoinIPv4(de_ctx, target, source); - else if (target->ip.family == AF_INET6) - return DetectAddressJoinIPv6(de_ctx, target, source); - - return -1; -} - -/** - * \internal - * \brief Creates a cidr ipv6 netblock, based on the cidr netblock value. - * - * For example if we send a cidr of 7 as argument, an ipv6 address - * mask of the value FE:00:00:00:00:00:00:00 is created and updated - * in the argument struct in6_addr *in6. - * - * \todo I think for the final section: while (cidr > 0), we can simply - * replace it with a - * if (cidr > 0) { - * in6->s6_addr[i] = -1 << (8 - cidr); - * - * \param cidr The value of the cidr. - * \param in6 Pointer to an ipv6 address structure(struct in6_addr) which will - * hold the cidr netblock result. - */ -static void DetectAddressParseIPv6CIDR(int cidr, struct in6_addr *in6) -{ - int i = 0; - - memset(in6, 0, sizeof(struct in6_addr)); - - while (cidr > 8) { - in6->s6_addr[i] = 0xff; - cidr -= 8; - i++; - } - - while (cidr > 0) { - in6->s6_addr[i] |= 0x80; - if (--cidr > 0) - in6->s6_addr[i] = in6->s6_addr[i] >> 1; - } - - return; -} - -/** - * \internal - * \brief Parses an ipv4/ipv6 address string and updates the result into the - * DetectAddress instance sent as the argument. - * - * \param dd Pointer to the DetectAddress instance which should be updated with - * the address range details from the parsed ip string. - * \param str Pointer to address string that has to be parsed. - * - * \retval 0 On successfully parsing the address string. - * \retval -1 On failure. - */ -int DetectAddressParseString(DetectAddress *dd, char *str) -{ - char *ip = NULL; - char *ip2 = NULL; - char *mask = NULL; - int r = 0; - char ipstr[256]; - - while (*str != '\0' && *str == ' ') - str++; - - /* first handle 'any' */ - if (strcasecmp(str, "any") == 0) { - dd->flags |= ADDRESS_FLAG_ANY; - SCLogDebug("address is \'any\'"); - return 0; - } - - strlcpy(ipstr, str, sizeof(ipstr)); - SCLogDebug("str %s", str); - - /* we work with a copy so that we can put a - * nul-termination in it later */ - ip = ipstr; - - /* handle the negation case */ - if (ip[0] == '!') { - dd->flags |= ADDRESS_FLAG_NOT; - ip++; - } - - /* see if the address is an ipv4 or ipv6 address */ - if ((strchr(str, ':')) == NULL) { - /* IPv4 Address */ - struct in_addr in; - - dd->ip.family = AF_INET; - - if ((mask = strchr(ip, '/')) != NULL) { - /* 1.2.3.4/xxx format (either dotted or cidr notation */ - ip[mask - ip] = '\0'; - mask++; - uint32_t ip4addr = 0; - uint32_t netmask = 0; - size_t u = 0; - - if ((strchr (mask, '.')) == NULL) { - /* 1.2.3.4/24 format */ - - for (u = 0; u < strlen(mask); u++) { - if(!isdigit((unsigned char)mask[u])) - goto error; - } - - int cidr = atoi(mask); - if (cidr < 0 || cidr > 32) - goto error; - - netmask = CIDRGet(cidr); - } else { - /* 1.2.3.4/255.255.255.0 format */ - r = inet_pton(AF_INET, mask, &in); - if (r <= 0) - goto error; - - netmask = in.s_addr; - } - - r = inet_pton(AF_INET, ip, &in); - if (r <= 0) - goto error; - - ip4addr = in.s_addr; - - dd->ip.addr_data32[0] = dd->ip2.addr_data32[0] = ip4addr & netmask; - dd->ip2.addr_data32[0] |=~ netmask; - } else if ((ip2 = strchr(ip, '-')) != NULL) { - /* 1.2.3.4-1.2.3.6 range format */ - ip[ip2 - ip] = '\0'; - ip2++; - - r = inet_pton(AF_INET, ip, &in); - if (r <= 0) - goto error; - dd->ip.addr_data32[0] = in.s_addr; - - r = inet_pton(AF_INET, ip2, &in); - if (r <= 0) - goto error; - dd->ip2.addr_data32[0] = in.s_addr; - - /* a > b is illegal, a = b is ok */ - if (ntohl(dd->ip.addr_data32[0]) > ntohl(dd->ip2.addr_data32[0])) - goto error; - } else { - /* 1.2.3.4 format */ - r = inet_pton(AF_INET, ip, &in); - if (r <= 0) - goto error; - /* single host */ - dd->ip.addr_data32[0] = in.s_addr; - dd->ip2.addr_data32[0] = in.s_addr; - } - } else { - /* IPv6 Address */ - struct in6_addr in6, mask6; - uint32_t ip6addr[4], netmask[4]; - - dd->ip.family = AF_INET6; - - if ((mask = strchr(ip, '/')) != NULL) { - ip[mask - ip] = '\0'; - mask++; - - int cidr = atoi(mask); - if (cidr < 0 || cidr > 128) - goto error; - - r = inet_pton(AF_INET6, ip, &in6); - if (r <= 0) - goto error; - memcpy(&ip6addr, &in6.s6_addr, sizeof(ip6addr)); - - DetectAddressParseIPv6CIDR(cidr, &mask6); - memcpy(&netmask, &mask6.s6_addr, sizeof(netmask)); - - dd->ip2.addr_data32[0] = dd->ip.addr_data32[0] = ip6addr[0] & netmask[0]; - dd->ip2.addr_data32[1] = dd->ip.addr_data32[1] = ip6addr[1] & netmask[1]; - dd->ip2.addr_data32[2] = dd->ip.addr_data32[2] = ip6addr[2] & netmask[2]; - dd->ip2.addr_data32[3] = dd->ip.addr_data32[3] = ip6addr[3] & netmask[3]; - - dd->ip2.addr_data32[0] |=~ netmask[0]; - dd->ip2.addr_data32[1] |=~ netmask[1]; - dd->ip2.addr_data32[2] |=~ netmask[2]; - dd->ip2.addr_data32[3] |=~ netmask[3]; - } else if ((ip2 = strchr(ip, '-')) != NULL) { - /* 2001::1-2001::4 range format */ - ip[ip2 - ip] = '\0'; - ip2++; - - r = inet_pton(AF_INET6, ip, &in6); - if (r <= 0) - goto error; - memcpy(&dd->ip.address, &in6.s6_addr, sizeof(ip6addr)); - - r = inet_pton(AF_INET6, ip2, &in6); - if (r <= 0) - goto error; - memcpy(&dd->ip2.address, &in6.s6_addr, sizeof(ip6addr)); - - /* a > b is illegal, a=b is ok */ - if (AddressIPv6Gt(&dd->ip, &dd->ip2)) - goto error; - } else { - r = inet_pton(AF_INET6, ip, &in6); - if (r <= 0) - goto error; - - memcpy(&dd->ip.address, &in6.s6_addr, sizeof(dd->ip.address)); - memcpy(&dd->ip2.address, &in6.s6_addr, sizeof(dd->ip2.address)); - } - - } - - BUG_ON(dd->ip.family == 0); - - return 0; - -error: - return -1; -} - -/** - * \internal - * \brief Simply parse an address and return a DetectAddress instance containing - * the address ranges of the parsed ip addressstring - * - * \param str Pointer to a character string containing the ip address - * - * \retval dd Pointer to the DetectAddress instance containing the address - * range details from the parsed ip string - */ -static DetectAddress *DetectAddressParseSingle(char *str) -{ - DetectAddress *dd; - - SCLogDebug("str %s", str); - - dd = DetectAddressInit(); - if (dd == NULL) - goto error; - - if (DetectAddressParseString(dd, str) < 0) { - SCLogDebug("AddressParse failed"); - goto error; - } - - return dd; - -error: - if (dd != NULL) - DetectAddressFree(dd); - return NULL; -} - -/** - * \brief Setup a single address string, parse it and add the resulting - * Address-Range(s) to the AddessHead(DetectAddressHead instance). - * - * \param gh Pointer to the Address-Head(DetectAddressHead) to which the - * resulting Address-Range(s) from the parsed ip string has to - * be added. - * \param s Pointer to the ip address string to be parsed. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressSetup(DetectAddressHead *gh, char *s) -{ - DetectAddress *ad = NULL; - DetectAddress *ad2 = NULL; - int r = 0; - char any = FALSE; - - SCLogDebug("gh %p, s %s", gh, s); - - /* parse the address */ - ad = DetectAddressParseSingle(s); - if (ad == NULL) { - SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC, - "failed to parse address \"%s\"", s); - return -1; - } - - if (ad->flags & ADDRESS_FLAG_ANY) - any = TRUE; - - /* handle the not case, we apply the negation then insert the part(s) */ - if (ad->flags & ADDRESS_FLAG_NOT) { - ad2 = NULL; - - if (DetectAddressCutNot(ad, &ad2) < 0) { - SCLogDebug("DetectAddressCutNot failed"); - goto error; - } - - /* normally a 'not' will result in two ad's unless the 'not' is on the start or end - * of the address space (e.g. 0.0.0.0 or 255.255.255.255). */ - if (ad2 != NULL) { - if (DetectAddressInsert(NULL, gh, ad2) < 0) { - SCLogDebug("DetectAddressInsert failed"); - goto error; - } - } - } - - r = DetectAddressInsert(NULL, gh, ad); - if (r < 0) { - SCLogDebug("DetectAddressInsert failed"); - goto error; - } - SCLogDebug("r %d",r); - - /* if any, insert 0.0.0.0/0 and ::/0 as well */ - if (r == 1 && any == TRUE) { - SCLogDebug("adding 0.0.0.0/0 and ::/0 as we\'re handling \'any\'"); - - ad = DetectAddressParseSingle("0.0.0.0/0"); - if (ad == NULL) - goto error; - - BUG_ON(ad->ip.family == 0); - - if (DetectAddressInsert(NULL, gh, ad) < 0) { - SCLogDebug("DetectAddressInsert failed"); - goto error; - } - ad = DetectAddressParseSingle("::/0"); - if (ad == NULL) - goto error; - - BUG_ON(ad->ip.family == 0); - - if (DetectAddressInsert(NULL, gh, ad) < 0) { - SCLogDebug("DetectAddressInsert failed"); - goto error; - } - } - return 0; - -error: - SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC, "DetectAddressSetup error"); - /* XXX cleanup */ - return -1; -} - -/** - * \brief Parses an address string and updates the 2 address heads with the - * address data. - * - * \todo We don't seem to be handling negated cases, like [addr,![!addr,addr]], - * since we pass around negate without keeping a count of ! with depth. - * Can solve this by keeping a count of the negations with depth, so that - * an even no of negations would count as no negation and an odd no of - * negations would count as a negation. - * - * \param gh Pointer to the address head that should hold address ranges - * that are not negated. - * \param ghn Pointer to the address head that should hold address ranges - * that are negated. - * \param s Pointer to the character string holding the address to be - * parsed. - * \param negate Flag that indicates if the receieved address string is negated - * or not. 0 if it is not, 1 it it is. - * - * \retval 0 On successfully parsing. - * \retval -1 On failure. - */ -static int DetectAddressParse2(const DetectEngineCtx *de_ctx, - DetectAddressHead *gh, DetectAddressHead *ghn, - char *s, int negate) -{ - size_t x = 0; - size_t u = 0; - int o_set = 0, n_set = 0, d_set = 0; - int depth = 0; - size_t size = strlen(s); - char address[8196] = ""; - char *rule_var_address = NULL; - char *temp_rule_var_address = NULL; - - SCLogDebug("s %s negate %s", s, negate ? "true" : "false"); - - for (u = 0, x = 0; u < size && x < sizeof(address); u++) { - if (x == (sizeof(address) - 1)) { - SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC, "Hit the address buffer" - " limit for the supplied address. Invalidating sig. " - "Please file a bug report on this."); - goto error; - } - address[x] = s[u]; - x++; - - if (!o_set && s[u] == '!') { - n_set = 1; - x--; - } else if (s[u] == '[') { - if (!o_set) { - o_set = 1; - x = 0; - } - depth++; - } else if (s[u] == ']') { - if (depth == 1) { - address[x - 1] = '\0'; - x = 0; - SCLogDebug("address %s negate %d, n_set %d", address, negate, n_set); - if (((negate + n_set) % 2) == 0) { - /* normal block */ - SCLogDebug("normal block"); - - if (DetectAddressParse2(de_ctx, gh, ghn, address, (negate + n_set) % 2) < 0) - goto error; - } else { - /* negated block - * - * Extra steps are necessary. First consider it as a normal - * (non-negated) range. Merge the + and - ranges if - * applicable. Then insert the result into the ghn list. */ - SCLogDebug("negated block"); - - DetectAddressHead tmp_gh = { NULL, NULL, NULL }; - DetectAddressHead tmp_ghn = { NULL, NULL, NULL }; - - if (DetectAddressParse2(de_ctx, &tmp_gh, &tmp_ghn, address, 0) < 0) - goto error; - - DetectAddress *tmp_ad; - DetectAddress *tmp_ad2; -#ifdef DEBUG - SCLogDebug("tmp_gh: IPv4"); - for (tmp_ad = tmp_gh.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) { - DetectAddressPrint(tmp_ad); - } - SCLogDebug("tmp_ghn: IPv4"); - for (tmp_ad = tmp_ghn.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) { - DetectAddressPrint(tmp_ad); - } - SCLogDebug("tmp_gh: IPv6"); - for (tmp_ad = tmp_gh.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) { - DetectAddressPrint(tmp_ad); - } - SCLogDebug("tmp_ghn: IPv6"); - for (tmp_ad = tmp_ghn.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) { - DetectAddressPrint(tmp_ad); - } -#endif - if (DetectAddressMergeNot(&tmp_gh, &tmp_ghn) < 0) - goto error; - - SCLogDebug("merged succesfully"); - - /* insert the IPv4 addresses into the negated list */ - for (tmp_ad = tmp_gh.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) { - /* work with a copy of the address group */ - tmp_ad2 = DetectAddressCopy(tmp_ad); - if (tmp_ad2 == NULL) { - SCLogDebug("DetectAddressCopy failed"); - goto error; - } - DetectAddressPrint(tmp_ad2); - DetectAddressInsert(NULL, ghn, tmp_ad2); - } - - /* insert the IPv6 addresses into the negated list */ - for (tmp_ad = tmp_gh.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) { - /* work with a copy of the address group */ - tmp_ad2 = DetectAddressCopy(tmp_ad); - if (tmp_ad2 == NULL) { - SCLogDebug("DetectAddressCopy failed"); - goto error; - } - DetectAddressPrint(tmp_ad2); - DetectAddressInsert(NULL, ghn, tmp_ad2); - } - - DetectAddressHeadCleanup(&tmp_gh); - DetectAddressHeadCleanup(&tmp_ghn); - } - n_set = 0; - } - depth--; - } else if (depth == 0 && s[u] == ',') { - if (o_set == 1) { - o_set = 0; - } else if (d_set == 1) { - address[x - 1] = '\0'; - - rule_var_address = SCRuleVarsGetConfVar(de_ctx, address, - SC_RULE_VARS_ADDRESS_GROUPS); - if (rule_var_address == NULL) - goto error; - if (strlen(rule_var_address) == 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "variable %s resolved " - "to nothing. This is likely a misconfiguration. " - "Note that a negated address needs to be quoted, " - "\"!$HOME_NET\" instead of !$HOME_NET. See issue #295.", s); - goto error; - } - SCLogDebug("rule_var_address %s", rule_var_address); - temp_rule_var_address = rule_var_address; - if ((negate + n_set) % 2) { - temp_rule_var_address = SCMalloc(strlen(rule_var_address) + 3); - if (unlikely(temp_rule_var_address == NULL)) - goto error; - snprintf(temp_rule_var_address, strlen(rule_var_address) + 3, - "[%s]", rule_var_address); - } - DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address, - (negate + n_set) % 2); - d_set = 0; - n_set = 0; - if (temp_rule_var_address != rule_var_address) - SCFree(temp_rule_var_address); - } else { - address[x - 1] = '\0'; - - if (!((negate + n_set) % 2)) { - SCLogDebug("DetectAddressSetup into gh, %s", address); - if (DetectAddressSetup(gh, address) < 0) - goto error; - } else { - SCLogDebug("DetectAddressSetup into ghn, %s", address); - if (DetectAddressSetup(ghn, address) < 0) - goto error; - } - n_set = 0; - } - x = 0; - } else if (depth == 0 && s[u] == '$') { - d_set = 1; - } else if (depth == 0 && u == size - 1) { - if (x == sizeof(address)) { - address[x - 1] = '\0'; - } else { - address[x] = '\0'; - } - x = 0; - - if (d_set == 1) { - rule_var_address = SCRuleVarsGetConfVar(de_ctx, address, - SC_RULE_VARS_ADDRESS_GROUPS); - if (rule_var_address == NULL) - goto error; - if (strlen(rule_var_address) == 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "variable %s resolved " - "to nothing. This is likely a misconfiguration. " - "Note that a negated address needs to be quoted, " - "\"!$HOME_NET\" instead of !$HOME_NET. See issue #295.", s); - goto error; - } - SCLogDebug("rule_var_address %s", rule_var_address); - temp_rule_var_address = rule_var_address; - if ((negate + n_set) % 2) { - temp_rule_var_address = SCMalloc(strlen(rule_var_address) + 3); - if (unlikely(temp_rule_var_address == NULL)) - goto error; - snprintf(temp_rule_var_address, strlen(rule_var_address) + 3, - "[%s]", rule_var_address); - } - if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address, - (negate + n_set) % 2) < 0) { - SCLogDebug("DetectAddressParse2 hates us"); - goto error; - } - d_set = 0; - if (temp_rule_var_address != rule_var_address) - SCFree(temp_rule_var_address); - } else { - if (!((negate + n_set) % 2)) { - SCLogDebug("DetectAddressSetup into gh, %s", address); - if (DetectAddressSetup(gh, address) < 0) { - SCLogDebug("DetectAddressSetup gh fail"); - goto error; - } - } else { - SCLogDebug("DetectAddressSetup into ghn, %s", address); - if (DetectAddressSetup(ghn, address) < 0) { - SCLogDebug("DetectAddressSetup ghn fail"); - goto error; - } - } - } - n_set = 0; - } - } - if (depth > 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "not every address block was " - "properly closed in \"%s\", %d missing closing brackets (]). " - "Note: problem might be in a variable.", s, depth); - goto error; - } else if (depth < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "not every address block was " - "properly opened in \"%s\", %d missing opening brackets ([). " - "Note: problem might be in a variable.", s, depth*-1); - goto error; - } - - return 0; - -error: - return -1; -} - -/** - * \internal - * \brief See if the addresses and ranges in an address head cover the - * entire ip space. - * - * \param gh Pointer to the DetectAddressHead to check. - * - * \retval 0 No. - * \retval 1 Yes. - * - * \todo do the same for IPv6 - */ -static int DetectAddressIsCompleteIPSpace(DetectAddressHead *gh) -{ - int r = DetectAddressIsCompleteIPSpaceIPv4(gh->ipv4_head); - if (r == 1) - return 1; - - return 0; -} - -/** - * \brief Merge the + and the - list (+ positive match, - 'not' match) - * - * \param gh Pointer to the address head containing the non-NOT groups. - * \param ghn Pointer to the address head containing the NOT groups. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressMergeNot(DetectAddressHead *gh, DetectAddressHead *ghn) -{ - DetectAddress *ad; - DetectAddress *ag, *ag2; - int r = 0; - - SCLogDebug("gh->ipv4_head %p, ghn->ipv4_head %p", gh->ipv4_head, - ghn->ipv4_head); - - /* check if the negated list covers the entire ip space. If so - * the user screwed up the rules/vars. */ - if (DetectAddressIsCompleteIPSpace(ghn) == 1) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Complete IP space negated. " - "Rule address range is NIL. Probably have a !any or " - "an address range that supplies a NULL address range"); - goto error; - } - - /* step 0: if the gh list is empty, but the ghn list isn't we have a pure - * not thingy. In that case we add a 0.0.0.0/0 first. */ - if (gh->ipv4_head == NULL && ghn->ipv4_head != NULL) { - r = DetectAddressSetup(gh, "0.0.0.0/0"); - if (r < 0) { - SCLogDebug("DetectAddressSetup for 0.0.0.0/0 failed"); - goto error; - } - } - /* ... or ::/0 for ipv6 */ - if (gh->ipv6_head == NULL && ghn->ipv6_head != NULL) { - r = DetectAddressSetup(gh, "::/0"); - if (r < 0) { - SCLogDebug("DetectAddressSetup for ::/0 failed"); - goto error; - } - } - - /* step 1: insert our ghn members into the gh list */ - for (ag = ghn->ipv4_head; ag != NULL; ag = ag->next) { - /* work with a copy of the ad so we can easily clean up the ghn group - * later. */ - ad = DetectAddressCopy(ag); - if (ad == NULL) { - SCLogDebug("DetectAddressCopy failed"); - goto error; - } - - r = DetectAddressInsert(NULL, gh, ad); - if (r < 0) { - SCLogDebug("DetectAddressInsert failed"); - goto error; - } - } - /* ... and the same for ipv6 */ - for (ag = ghn->ipv6_head; ag != NULL; ag = ag->next) { - /* work with a copy of the ad so we can easily clean up the ghn group - * later. */ - ad = DetectAddressCopy(ag); - if (ad == NULL) { - SCLogDebug("DetectAddressCopy failed"); - goto error; - } - - r = DetectAddressInsert(NULL, gh, ad); - if (r < 0) { - SCLogDebug("DetectAddressInsert failed"); - goto error; - } - } -#ifdef DEBUG - DetectAddress *tmp_ad; - for (tmp_ad = gh->ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) { - DetectAddressPrint(tmp_ad); - } -#endif - int ipv4_applied = 0; - int ipv6_applied = 0; - - /* step 2: pull the address blocks that match our 'not' blocks */ - for (ag = ghn->ipv4_head; ag != NULL; ag = ag->next) { - SCLogDebug("ag %p", ag); - DetectAddressPrint(ag); - - int applied = 0; - for (ag2 = gh->ipv4_head; ag2 != NULL; ) { - SCLogDebug("ag2 %p", ag2); - DetectAddressPrint(ag2); - - r = DetectAddressCmp(ag, ag2); - /* XXX more ??? */ - if (r == ADDRESS_EQ || r == ADDRESS_EB) { - if (ag2->prev == NULL) - gh->ipv4_head = ag2->next; - else - ag2->prev->next = ag2->next; - - if (ag2->next != NULL) - ag2->next->prev = ag2->prev; - - /* store the next ptr and remove the group */ - DetectAddress *next_ag2 = ag2->next; - DetectAddressFree(ag2); - ag2 = next_ag2; - applied = 1; - } else { - ag2 = ag2->next; - } - } - - if (applied) { - ipv4_applied++; - } - } - /* ... and the same for ipv6 */ - for (ag = ghn->ipv6_head; ag != NULL; ag = ag->next) { - int applied = 0; - for (ag2 = gh->ipv6_head; ag2 != NULL; ) { - r = DetectAddressCmp(ag, ag2); - if (r == ADDRESS_EQ || r == ADDRESS_EB) { /* XXX more ??? */ - if (ag2->prev == NULL) - gh->ipv6_head = ag2->next; - else - ag2->prev->next = ag2->next; - - if (ag2->next != NULL) - ag2->next->prev = ag2->prev; - - /* store the next ptr and remove the group */ - DetectAddress *next_ag2 = ag2->next; - DetectAddressFree(ag2); - ag2 = next_ag2; - - SCLogDebug("applied"); - applied = 1; - } else { - ag2 = ag2->next; - } - } - if (applied) { - ipv6_applied++; - } - } -#ifdef DEBUG - for (tmp_ad = gh->ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) { - DetectAddressPrint(tmp_ad); - } - for (tmp_ad = ghn->ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) { - DetectAddressPrint(tmp_ad); - } -#endif - if (ghn->ipv4_head != NULL || ghn->ipv6_head != NULL) { - int cnt = 0; - DetectAddress *ad; - for (ad = ghn->ipv4_head; ad; ad = ad->next) - cnt++; - - if (ipv4_applied != cnt) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "not all IPv4 negations " - "could be applied: %d != %d", cnt, ipv4_applied); - goto error; - } - - cnt = 0; - for (ad = ghn->ipv6_head; ad; ad = ad->next) - cnt++; - - if (ipv6_applied != cnt) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "not all IPv6 negations " - "could be applied: %d != %d", cnt, ipv6_applied); - goto error; - } - } - - /* if the result is that we have no addresses we return error */ - if (gh->ipv4_head == NULL && gh->ipv6_head == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "no addresses left after " - "merging addresses and negated addresses"); - goto error; - } - - return 0; - -error: - return -1; -} - -int DetectAddressTestConfVars(void) -{ - SCLogDebug("Testing address conf vars for any misconfigured values"); - - ConfNode *address_vars_node = ConfGetNode("vars.address-groups"); - if (address_vars_node == NULL) { - return 0; - } - - ConfNode *seq_node; - TAILQ_FOREACH(seq_node, &address_vars_node->head, next) { - SCLogDebug("Testing %s - %s", seq_node->name, seq_node->val); - - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh == NULL) { - goto error; - } - DetectAddressHead *ghn = DetectAddressHeadInit(); - if (ghn == NULL) { - goto error; - } - - if (seq_node->val == NULL) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "Address var \"%s\" probably has a sequence(something " - "in brackets) value set without any quotes. Please " - "quote it using \"..\".", seq_node->name); - goto error; - } - - int r = DetectAddressParse2(NULL, gh, ghn, seq_node->val, /* start with negate no */0); - if (r < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "failed to parse address var \"%s\" with value \"%s\". " - "Please check it's syntax", seq_node->name, seq_node->val); - goto error; - } - - if (DetectAddressIsCompleteIPSpace(ghn)) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "address var - \"%s\" has the complete IP space negated " - "with it's value \"%s\". Rule address range is NIL. " - "Probably have a !any or an address range that supplies " - "a NULL address range", seq_node->name, seq_node->val); - goto error; - } - - if (gh != NULL) - DetectAddressHeadFree(gh); - if (ghn != NULL) - DetectAddressHeadFree(ghn); - } - - return 0; - error: - return -1; -} - -/** - * \brief Parses an address group sent as a character string and updates the - * DetectAddressHead sent as the argument with the relevant address - * ranges from the parsed string. - * - * \param gh Pointer to the DetectAddressHead. - * \param str Pointer to the character string containing the address group - * that has to be parsed. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressParse(const DetectEngineCtx *de_ctx, - DetectAddressHead *gh, char *str) -{ - int r; - DetectAddressHead *ghn = NULL; - - SCLogDebug("gh %p, str %s", gh, str); - - if (str == NULL) { - SCLogDebug("DetectAddressParse can not be run with NULL address"); - goto error; - } - - ghn = DetectAddressHeadInit(); - if (ghn == NULL) { - SCLogDebug("DetectAddressHeadInit for ghn failed"); - goto error; - } - - r = DetectAddressParse2(de_ctx, gh, ghn, str, /* start with negate no */0); - if (r < 0) { - SCLogDebug("DetectAddressParse2 returned %d", r); - goto error; - } - - SCLogDebug("gh->ipv4_head %p, ghn->ipv4_head %p", gh->ipv4_head, - ghn->ipv4_head); - - /* merge the 'not' address groups */ - if (DetectAddressMergeNot(gh, ghn) < 0) { - SCLogDebug("DetectAddressMergeNot failed"); - goto error; - } - - /* free the temp negate head */ - DetectAddressHeadFree(ghn); - return 0; - -error: - if (ghn != NULL) - DetectAddressHeadFree(ghn); - return -1; -} - -/** - * \brief Returns a new instance of DetectAddressHead. - * - * \retval gh Pointer to the new instance of DetectAddressHead. - */ -DetectAddressHead *DetectAddressHeadInit(void) -{ - DetectAddressHead *gh = SCMalloc(sizeof(DetectAddressHead)); - if (unlikely(gh == NULL)) - return NULL; - memset(gh, 0, sizeof(DetectAddressHead)); - -#ifdef DEBUG - detect_address_group_head_init_cnt++; - detect_address_group_head_memory += sizeof(DetectAddressHead); -#endif - - return gh; -} - -/** - * \brief Cleans a DetectAddressHead. The functions frees the 3 address - * group heads(any, ipv4 and ipv6) inside the DetectAddressHead - * instance. - * - * \param gh Pointer to the DetectAddressHead instance that has to be - * cleaned. - */ -void DetectAddressHeadCleanup(DetectAddressHead *gh) -{ - if (gh != NULL) { - if (gh->any_head != NULL) { - DetectAddressCleanupList(gh->any_head); - gh->any_head = NULL; - } - if (gh->ipv4_head != NULL) { - DetectAddressCleanupList(gh->ipv4_head); - gh->ipv4_head = NULL; - } - if (gh->ipv6_head != NULL) { - DetectAddressCleanupList(gh->ipv6_head); - gh->ipv6_head = NULL; - } - } - - return; -} - -/** - * \brief Frees a DetectAddressHead instance. - * - * \param gh Pointer to the DetectAddressHead instance to be freed. - */ -void DetectAddressHeadFree(DetectAddressHead *gh) -{ - if (gh != NULL) { - DetectAddressHeadCleanup(gh); - SCFree(gh); -#ifdef DEBUG - detect_address_group_head_free_cnt++; - detect_address_group_head_memory -= sizeof(DetectAddressHead); -#endif - } - - return; -} - -/** - * \brief Dispatcher function that calls the ipv4 and ipv6 address cut functions. - * Have a look at DetectAddressCutIPv4() and DetectAddressCutIPv6() for - * explanations on what these functions do. - * - * \param de_ctx Pointer to the DetectEngineCtx. - * \param a Pointer the the first address to be cut. - * \param b Pointer to the second address to be cut. - * \param c Pointer to a pointer to a third DetectAddressData, in case the - * ranges from a and b, demand a third address range. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressCut(DetectEngineCtx *de_ctx, DetectAddress *a, - DetectAddress *b, DetectAddress **c) -{ - if (a->ip.family == AF_INET) - return DetectAddressCutIPv4(de_ctx, a, b, c); - else if (a->ip.family == AF_INET6) - return DetectAddressCutIPv6(de_ctx, a, b, c); - - return -1; -} - -/** - * \brief Cuts a negated address range with respect to the entire ip range, and - * supplies with the address range that doesn't belong to the negated - * address range. - * - * There are 2 cases here - - * - * The first case includes the address being located at the extreme ends - * of the ip space, in which we get a single range. - * For example: !0.0.0.0, in which case we get 0.0.0.1 to 255.255.255.255. - * - * The second case includes the address not present at either of the - * ip space extremes, in which case we get 2 ranges. The second range - * would be supplied back with the argument "b" supplied to this function. - * For example: !10.20.30.40, in which case we the 2 ranges, 0.0.0.0 - - * 10.20.30.39 and 10.20.30.41 - 255.255.255.255. - * - * The above negation cases can similarly be extended to ranges, i.e. - * ![0.0.0.0 - 10.20.30.40], ![255.255.240.240 - 255.255.255.255] and - * ![10.20.30.40 - 10.20.30.50]. - * - * - * \param a Pointer to the DetectAddressData instance, that contains the negated - * address range that has to be cut. - * \param b Pointer to a pointer to a DetectAddressData instance, that should be - * filled with the address range, if the argument "a", doesn't fall at - * the extreme ends of the ip address space. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectAddressCutNot(DetectAddress *a, DetectAddress **b) -{ - if (a->ip.family == AF_INET) - return DetectAddressCutNotIPv4(a, b); - else if (a->ip.family == AF_INET6) - return DetectAddressCutNotIPv6(a, b); - - return -1; -} - -/** - * \brief Used to compare 2 address ranges. - * - * \param a Pointer to the first DetectAddressData to be compared. - * \param b Pointer to the second DetectAddressData to be compared. - */ -int DetectAddressCmp(DetectAddress *a, DetectAddress *b) -{ - if (a->ip.family != b->ip.family) - return ADDRESS_ER; - - /* check any */ - if ((a->flags & ADDRESS_FLAG_ANY) && (b->flags & ADDRESS_FLAG_ANY)) - return ADDRESS_EQ; - else if (a->ip.family == AF_INET) - return DetectAddressCmpIPv4(a, b); - else if (a->ip.family == AF_INET6) - return DetectAddressCmpIPv6(a, b); - - return ADDRESS_ER; -} - -/** - * \brief Match a packets address against a signatures addrs array - * - * \param addrs array of DetectMatchAddressIPv4's - * \param addrs_cnt array size in members - * \param a packets address - * - * \retval 0 no match - * \retval 1 match - * - * \note addresses in addrs are in host order - * - * \todo array should be ordered, so we can break out of the loop - */ -int DetectAddressMatchIPv4(DetectMatchAddressIPv4 *addrs, uint16_t addrs_cnt, Address *a) -{ - SCEnter(); - - if (addrs == NULL || addrs_cnt == 0) { - SCReturnInt(0); - } - - uint16_t idx; - for (idx = 0; idx < addrs_cnt; idx++) { - if (ntohl(a->addr_data32[0]) >= addrs[idx].ip && - ntohl(a->addr_data32[0]) <= addrs[idx].ip2) - { - SCReturnInt(1); - } - } - - SCReturnInt(0); -} - -/** - * \brief Match a packets address against a signatures addrs array - * - * \param addrs array of DetectMatchAddressIPv6's - * \param addrs_cnt array size in members - * \param a packets address - * - * \retval 0 no match - * \retval 1 match - * - * \note addresses in addrs are in host order - * - * \todo array should be ordered, so we can break out of the loop - */ -int DetectAddressMatchIPv6(DetectMatchAddressIPv6 *addrs, uint16_t addrs_cnt, Address *a) -{ - SCEnter(); - - if (addrs == NULL || addrs_cnt == 0) { - SCReturnInt(0); - } - - uint16_t idx; - int i = 0; - uint16_t result1, result2; - - /* See if the packet address is within the range of any entry in the - * signature's address match array. - */ - for (idx = 0; idx < addrs_cnt; idx++) { - result1 = result2 = 0; - - /* See if packet address equals either limit. Return 1 if true. */ - if (ntohl(a->addr_data32[0]) == addrs[idx].ip[0] && - ntohl(a->addr_data32[1]) == addrs[idx].ip[1] && - ntohl(a->addr_data32[2]) == addrs[idx].ip[2] && - ntohl(a->addr_data32[3]) == addrs[idx].ip[3]) - { - SCReturnInt(1); - } - if (ntohl(a->addr_data32[0]) == addrs[idx].ip2[0] && - ntohl(a->addr_data32[1]) == addrs[idx].ip2[1] && - ntohl(a->addr_data32[2]) == addrs[idx].ip2[2] && - ntohl(a->addr_data32[3]) == addrs[idx].ip2[3]) - { - SCReturnInt(1); - } - - /* See if packet address is greater than lower limit - * of the current signature address match pair. - */ - for (i = 0; i < 4; i++) { - if (ntohl(a->addr_data32[i]) > addrs[idx].ip[i]) { - result1 = 1; - break; - } - if (ntohl(a->addr_data32[i]) < addrs[idx].ip[i]) { - result1 = 0; - break; - } - } - - /* If not greater than lower limit, try next address match entry */ - if (result1 == 0) - continue; - - /* See if packet address is less than upper limit - * of the current signature address match pair. - */ - for (i = 0; i < 4; i++) { - if (ntohl(a->addr_data32[i]) < addrs[idx].ip2[i]) { - result2 = 1; - break; - } - if (ntohl(a->addr_data32[i]) > addrs[idx].ip2[i]) { - result2 = 0; - break; - } - } - - /* Return a match if packet address is between the two - * signature address match limits. - */ - if (result1 == 1 && result2 == 1) - SCReturnInt(1); - } - - SCReturnInt(0); -} - -/** - * \brief Check if a particular address(ipv4 or ipv6) matches the address - * range in the DetectAddress instance. - * - * We basically check that the address falls inbetween the address - * range in DetectAddress. - * - * \param dd Pointer to the DetectAddress instance. - * \param a Pointer to an Address instance. - * - * \param 1 On a match. - * \param 0 On no match. - */ -int DetectAddressMatch(DetectAddress *dd, Address *a) -{ - SCEnter(); - - if (dd->ip.family != a->family) { - SCReturnInt(0); - } - - //DetectAddressPrint(dd); - //AddressDebugPrint(a); - - switch (a->family) { - case AF_INET: - - /* XXX figure out a way to not need to do this ntohl if we switch to - * Address inside DetectAddressData we can do uint8_t checks */ - if (ntohl(a->addr_data32[0]) >= ntohl(dd->ip.addr_data32[0]) && - ntohl(a->addr_data32[0]) <= ntohl(dd->ip2.addr_data32[0])) - { - SCReturnInt(1); - } else { - SCReturnInt(0); - } - - break; - case AF_INET6: - if (AddressIPv6Ge(a, &dd->ip) == 1 && - AddressIPv6Le(a, &dd->ip2) == 1) - { - SCReturnInt(1); - } else { - SCReturnInt(0); - } - - break; - default: - SCLogDebug("What other address type can we have :-/"); - break; - } - - SCReturnInt(0); -} - -/** - * \brief Prints the address data held by the DetectAddress. If the - * address data family is any, we print "ANY". If the address data - * family is IPv4, we print the the ipv4 address and mask, and if the - * address data family is IPv6, we print the ipv6 address and mask. - * - * \param ad Pointer to the DetectAddress instance to be printed. - */ -void DetectAddressPrint(DetectAddress *gr) -{ - if (gr == NULL) - return; - - if (gr->flags & ADDRESS_FLAG_ANY) { - SCLogDebug("ANY"); - } else if (gr->ip.family == AF_INET) { - struct in_addr in; - char ip[16], mask[16]; - - memcpy(&in, &gr->ip.addr_data32[0], sizeof(in)); - PrintInet(AF_INET, &in, ip, sizeof(ip)); - memcpy(&in, &gr->ip2.addr_data32[0], sizeof(in)); - PrintInet(AF_INET, &in, mask, sizeof(mask)); - - SCLogDebug("%s/%s", ip, mask); -// printf("%s/%s", ip, mask); - } else if (gr->ip.family == AF_INET6) { - struct in6_addr in6; - char ip[66], mask[66]; - - memcpy(&in6, &gr->ip.addr_data32, sizeof(in6)); - PrintInet(AF_INET6, &in6, ip, sizeof(ip)); - memcpy(&in6, &gr->ip2.addr_data32, sizeof(in6)); - PrintInet(AF_INET6, &in6, mask, sizeof(mask)); - - SCLogDebug("%s/%s", ip, mask); -// printf("%s/%s", ip, mask); - } - - return; -} - -/** - * \brief Find the group matching address in a group head. - * - * \param gh Pointer to the address group head(DetectAddressHead instance). - * \param a Pointer to an Address instance. - * - * \retval g On success pointer to an DetectAddress if we find a match - * for the Address "a", in the DetectAddressHead "gh". - */ -DetectAddress *DetectAddressLookupInHead(DetectAddressHead *gh, Address *a) -{ - SCEnter(); - - DetectAddress *g; - - if (gh == NULL) { - SCReturnPtr(NULL, "DetectAddress"); - } - - /* XXX should we really do this check every time we run this function? */ - if (a->family == AF_INET) { - SCLogDebug("IPv4"); - g = gh->ipv4_head; - } else if (a->family == AF_INET6) { - SCLogDebug("IPv6"); - g = gh->ipv6_head; - } else { - SCLogDebug("ANY"); - g = gh->any_head; - } - - for ( ; g != NULL; g = g->next) { - if (DetectAddressMatch(g,a) == 1) { - SCReturnPtr(g, "DetectAddress"); - } - } - - SCReturnPtr(NULL, "DetectAddress"); -} - -/********************************Unittests*************************************/ - -#ifdef UNITTESTS - -static int UTHValidateDetectAddress(DetectAddress *ad, const char *one, const char *two) -{ - char str1[46] = "", str2[46] = ""; - - if (ad == NULL) - return FALSE; - - switch(ad->ip.family) { - case AF_INET: - PrintInet(AF_INET, (const void *)&ad->ip.addr_data32[0], str1, sizeof(str1)); - SCLogDebug("%s", str1); - PrintInet(AF_INET, (const void *)&ad->ip2.addr_data32[0], str2, sizeof(str2)); - SCLogDebug("%s", str2); - - if (strcmp(str1, one) != 0) { - SCLogInfo("%s != %s", str1, one); - return FALSE; - } - - if (strcmp(str2, two) != 0) { - SCLogInfo("%s != %s", str2, two); - return FALSE; - } - - return TRUE; - break; - - case AF_INET6: - PrintInet(AF_INET6, (const void *)&ad->ip.addr_data32[0], str1, sizeof(str1)); - SCLogDebug("%s", str1); - PrintInet(AF_INET6, (const void *)&ad->ip2.addr_data32[0], str2, sizeof(str2)); - SCLogDebug("%s", str2); - - if (strcmp(str1, one) != 0) { - SCLogInfo("%s != %s", str1, one); - return FALSE; - } - - if (strcmp(str2, two) != 0) { - SCLogInfo("%s != %s", str2, two); - return FALSE; - } - - return TRUE; - break; - } - - return FALSE; -} - -typedef struct UTHValidateDetectAddressHeadRange_ { - const char *one; - const char *two; -} UTHValidateDetectAddressHeadRange; - -int UTHValidateDetectAddressHead(DetectAddressHead *gh, int nranges, UTHValidateDetectAddressHeadRange *expectations) -{ - int expect = nranges; - int have = 0; - - if (gh == NULL) - return FALSE; - - DetectAddress *ad = NULL; - ad = gh->ipv4_head; - if (ad == NULL) - ad = gh->ipv6_head; - while (have < expect) { - if (ad == NULL) { - printf("bad head: have %d ranges, expected %d: ", have, expect); - return FALSE; - } - - if (UTHValidateDetectAddress(ad, expectations[have].one, expectations[have].two) == FALSE) - return FALSE; - - ad = ad->next; - have++; - } - - return TRUE; -} - -int AddressTestParse01(void) -{ - DetectAddress *dd = DetectAddressParseSingle("1.2.3.4"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse02(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("1.2.3.4"); - - if (dd) { - if (dd->ip2.addr_data32[0] != ntohl(16909060) || - dd->ip.addr_data32[0] != ntohl(16909060)) { - result = 0; - } - - printf("ip %"PRIu32", ip2 %"PRIu32"\n", dd->ip.addr_data32[0], dd->ip2.addr_data32[0]); - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse03(void) -{ - DetectAddress *dd = DetectAddressParseSingle("1.2.3.4/255.255.255.0"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse04(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("1.2.3.4/255.255.255.0"); - - if (dd) { - if (dd->ip.addr_data32[0] != ntohl(16909056)|| - dd->ip2.addr_data32[0] != ntohl(16909311)) { - result = 0; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse05(void) -{ - DetectAddress *dd = DetectAddressParseSingle("1.2.3.4/24"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse06(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("1.2.3.4/24"); - - if (dd) { - if (dd->ip2.addr_data32[0] != ntohl(16909311) || - dd->ip.addr_data32[0] != ntohl(16909056)) { - result = 0; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse07(void) -{ - DetectAddress *dd = DetectAddressParseSingle("2001::/3"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse08(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("2001::/3"); - - if (dd) { - if (dd->ip.addr_data32[0] != ntohl(536870912) || dd->ip.addr_data32[1] != 0x00000000 || - dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 || - - dd->ip2.addr_data32[0] != ntohl(1073741823) || dd->ip2.addr_data32[1] != 0xFFFFFFFF || - dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) { - DetectAddressPrint(dd); - result = 0; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse09(void) -{ - DetectAddress *dd = DetectAddressParseSingle("2001::1/128"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse10(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("2001::/128"); - - if (dd) { - if (dd->ip.addr_data32[0] != ntohl(536936448) || dd->ip.addr_data32[1] != 0x00000000 || - dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 || - - dd->ip2.addr_data32[0] != ntohl(536936448) || dd->ip2.addr_data32[1] != 0x00000000 || - dd->ip2.addr_data32[2] != 0x00000000 || dd->ip2.addr_data32[3] != 0x00000000) { - DetectAddressPrint(dd); - result = 0; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse11(void) -{ - DetectAddress *dd = DetectAddressParseSingle("2001::/48"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse12(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("2001::/48"); - - if (dd) { - if (dd->ip.addr_data32[0] != ntohl(536936448) || dd->ip.addr_data32[1] != 0x00000000 || - dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 || - - dd->ip2.addr_data32[0] != ntohl(536936448) || dd->ip2.addr_data32[1] != ntohl(65535) || - dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) { - DetectAddressPrint(dd); - result = 0; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} -int AddressTestParse13(void) -{ - DetectAddress *dd = DetectAddressParseSingle("2001::/16"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse14(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("2001::/16"); - - if (dd) { - if (dd->ip.addr_data32[0] != ntohl(536936448) || dd->ip.addr_data32[1] != 0x00000000 || - dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 || - - dd->ip2.addr_data32[0] != ntohl(537001983) || dd->ip2.addr_data32[1] != 0xFFFFFFFF || - dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) { - result = 0; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse15(void) -{ - DetectAddress *dd = DetectAddressParseSingle("2001::/0"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse16(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("2001::/0"); - - if (dd) { - if (dd->ip.addr_data32[0] != 0x00000000 || dd->ip.addr_data32[1] != 0x00000000 || - dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 || - - dd->ip2.addr_data32[0] != 0xFFFFFFFF || dd->ip2.addr_data32[1] != 0xFFFFFFFF || - dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) { - result = 0; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse17(void) -{ - DetectAddress *dd = DetectAddressParseSingle("1.2.3.4-1.2.3.6"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse18(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("1.2.3.4-1.2.3.6"); - - if (dd) { - if (dd->ip2.addr_data32[0] != ntohl(16909062) || - dd->ip.addr_data32[0] != ntohl(16909060)) { - result = 0; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse19(void) -{ - DetectAddress *dd = DetectAddressParseSingle("1.2.3.6-1.2.3.4"); - - if (dd) { - DetectAddressFree(dd); - return 0; - } - - return 1; -} - -int AddressTestParse20(void) -{ - DetectAddress *dd = DetectAddressParseSingle("2001::1-2001::4"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse21(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("2001::1-2001::4"); - - if (dd) { - if (dd->ip.addr_data32[0] != ntohl(536936448) || dd->ip.addr_data32[1] != 0x00000000 || - dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != ntohl(1) || - - dd->ip2.addr_data32[0] != ntohl(536936448) || dd->ip2.addr_data32[1] != 0x00000000 || - dd->ip2.addr_data32[2] != 0x00000000 || dd->ip2.addr_data32[3] != ntohl(4)) { - result = 0; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse22(void) -{ - DetectAddress *dd = DetectAddressParseSingle("2001::4-2001::1"); - - if (dd) { - DetectAddressFree(dd); - return 0; - } - - return 1; -} - -int AddressTestParse23(void) -{ - DetectAddress *dd = DetectAddressParseSingle("any"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse24(void) -{ - DetectAddress *dd = DetectAddressParseSingle("Any"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse25(void) -{ - DetectAddress *dd = DetectAddressParseSingle("ANY"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse26(void) -{ - int result = 0; - DetectAddress *dd = DetectAddressParseSingle("any"); - - if (dd) { - if (dd->flags & ADDRESS_FLAG_ANY) - result = 1; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse27(void) -{ - DetectAddress *dd = DetectAddressParseSingle("!192.168.0.1"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse28(void) -{ - int result = 0; - DetectAddress *dd = DetectAddressParseSingle("!1.2.3.4"); - - if (dd) { - if (dd->flags & ADDRESS_FLAG_NOT && - dd->ip.addr_data32[0] == ntohl(16909060)) { - result = 1; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse29(void) -{ - DetectAddress *dd = DetectAddressParseSingle("!1.2.3.0/24"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse30(void) -{ - int result = 0; - DetectAddress *dd = DetectAddressParseSingle("!1.2.3.4/24"); - - if (dd) { - if (dd->flags & ADDRESS_FLAG_NOT && - dd->ip.addr_data32[0] == ntohl(16909056) && - dd->ip2.addr_data32[0] == ntohl(16909311)) { - result = 1; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -/** - * \test make sure !any is rejected - */ -int AddressTestParse31(void) -{ - DetectAddress *dd = DetectAddressParseSingle("!any"); - - if (dd) { - DetectAddressFree(dd); - return 0; - } - - return 1; -} - -int AddressTestParse32(void) -{ - DetectAddress *dd = DetectAddressParseSingle("!2001::1"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse33(void) -{ - int result = 0; - DetectAddress *dd = DetectAddressParseSingle("!2001::1"); - - if (dd) { - if (dd->flags & ADDRESS_FLAG_NOT && - dd->ip.addr_data32[0] == ntohl(536936448) && dd->ip.addr_data32[1] == 0x00000000 && - dd->ip.addr_data32[2] == 0x00000000 && dd->ip.addr_data32[3] == ntohl(1)) { - result = 1; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse34(void) -{ - DetectAddress *dd = DetectAddressParseSingle("!2001::/16"); - - if (dd) { - DetectAddressFree(dd); - return 1; - } - - return 0; -} - -int AddressTestParse35(void) -{ - int result = 0; - DetectAddress *dd = DetectAddressParseSingle("!2001::/16"); - - if (dd) { - if (dd->flags & ADDRESS_FLAG_NOT && - dd->ip.addr_data32[0] == ntohl(536936448) && dd->ip.addr_data32[1] == 0x00000000 && - dd->ip.addr_data32[2] == 0x00000000 && dd->ip.addr_data32[3] == 0x00000000 && - - dd->ip2.addr_data32[0] == ntohl(537001983) && dd->ip2.addr_data32[1] == 0xFFFFFFFF && - dd->ip2.addr_data32[2] == 0xFFFFFFFF && dd->ip2.addr_data32[3] == 0xFFFFFFFF) { - result = 1; - } - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse36(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("ffff::/16"); - - if (dd) { - if (dd->ip.addr_data32[0] != ntohl(0xFFFF0000) || dd->ip.addr_data32[1] != 0x00000000 || - dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 || - - dd->ip2.addr_data32[0] != 0xFFFFFFFF || dd->ip2.addr_data32[1] != 0xFFFFFFFF || - dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) { - - DetectAddressPrint(dd); - result = 0; - } - DetectAddressPrint(dd); - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestParse37(void) -{ - int result = 1; - DetectAddress *dd = DetectAddressParseSingle("::/0"); - - if (dd) { - if (dd->ip.addr_data32[0] != 0x00000000 || dd->ip.addr_data32[1] != 0x00000000 || - dd->ip.addr_data32[2] != 0x00000000 || dd->ip.addr_data32[3] != 0x00000000 || - - dd->ip2.addr_data32[0] != 0xFFFFFFFF || dd->ip2.addr_data32[1] != 0xFFFFFFFF || - dd->ip2.addr_data32[2] != 0xFFFFFFFF || dd->ip2.addr_data32[3] != 0xFFFFFFFF) { - DetectAddressPrint(dd); - result = 0; - } - DetectAddressPrint(dd); - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch01(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in_addr in; - Address a; - - if (inet_pton(AF_INET, "1.2.3.4", &in) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET; - a.addr_data32[0] = in.s_addr; - - dd = DetectAddressParseSingle("1.2.3.4/24"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 0) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch02(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in_addr in; - Address a; - - if (inet_pton(AF_INET, "1.2.3.127", &in) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET; - a.addr_data32[0] = in.s_addr; - - dd = DetectAddressParseSingle("1.2.3.4/25"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 0) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch03(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in_addr in; - Address a; - - if (inet_pton(AF_INET, "1.2.3.128", &in) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET; - a.addr_data32[0] = in.s_addr; - - dd = DetectAddressParseSingle("1.2.3.4/25"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 1) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch04(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in_addr in; - Address a; - - if (inet_pton(AF_INET, "1.2.2.255", &in) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET; - a.addr_data32[0] = in.s_addr; - - dd = DetectAddressParseSingle("1.2.3.4/25"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 1) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch05(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in_addr in; - Address a; - - if (inet_pton(AF_INET, "1.2.3.4", &in) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET; - a.addr_data32[0] = in.s_addr; - - dd = DetectAddressParseSingle("1.2.3.4/32"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 0) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch06(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in_addr in; - Address a; - - if (inet_pton(AF_INET, "1.2.3.4", &in) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET; - a.addr_data32[0] = in.s_addr; - - dd = DetectAddressParseSingle("0.0.0.0/0.0.0.0"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 0) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch07(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in6_addr in6; - Address a; - - if (inet_pton(AF_INET6, "2001::1", &in6) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET6; - memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr)); - - dd = DetectAddressParseSingle("2001::/3"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 0) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch08(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in6_addr in6; - Address a; - - if (inet_pton(AF_INET6, "1999:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &in6) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET6; - memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr)); - - dd = DetectAddressParseSingle("2001::/3"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 1) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch09(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in6_addr in6; - Address a; - - if (inet_pton(AF_INET6, "2001::2", &in6) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET6; - memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr)); - - dd = DetectAddressParseSingle("2001::1/128"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 1) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch10(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in6_addr in6; - Address a; - - if (inet_pton(AF_INET6, "2001::2", &in6) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET6; - memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr)); - - dd = DetectAddressParseSingle("2001::1/126"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 0) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestMatch11(void) -{ - DetectAddress *dd = NULL; - int result = 1; - struct in6_addr in6; - Address a; - - if (inet_pton(AF_INET6, "2001::3", &in6) != 1) - return 0; - memset(&a, 0, sizeof(Address)); - a.family = AF_INET6; - memcpy(&a.addr_data32, &in6.s6_addr, sizeof(in6.s6_addr)); - - dd = DetectAddressParseSingle("2001::1/127"); - if (dd) { - if (DetectAddressMatch(dd, &a) == 1) - result = 0; - - DetectAddressFree(dd); - return result; - } - - return 0; -} - -int AddressTestCmp01(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("192.168.0.0/255.255.255.0"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("192.168.0.0/255.255.255.0"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_EQ) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp02(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("192.168.0.0/255.255.0.0"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("192.168.0.0/255.255.255.0"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_EB) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp03(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("192.168.0.0/255.255.255.0"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("192.168.0.0/255.255.0.0"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_ES) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp04(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("192.168.0.0/255.255.255.0"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("192.168.1.0/255.255.255.0"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_LT) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp05(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("192.168.1.0/255.255.255.0"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("192.168.0.0/255.255.255.0"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_GT) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp06(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("192.168.1.0/255.255.0.0"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("192.168.0.0/255.255.0.0"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_EQ) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmpIPv407(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("192.168.1.0/255.255.255.0"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("192.168.1.128-192.168.2.128"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_LE) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmpIPv408(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("192.168.1.128-192.168.2.128"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("192.168.1.0/255.255.255.0"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_GE) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp07(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("2001::/3"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("2001::1/3"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_EQ) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp08(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("2001::/3"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("2001::/8"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_EB) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp09(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("2001::/8"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("2001::/3"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_ES) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp10(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("2001:1:2:3:0:0:0:0/64"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("2001:1:2:4:0:0:0:0/64"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_LT) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp11(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("2001:1:2:4:0:0:0:0/64"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("2001:1:2:3:0:0:0:0/64"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_GT) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestCmp12(void) -{ - DetectAddress *da = NULL, *db = NULL; - int result = 1; - - da = DetectAddressParseSingle("2001:1:2:3:1:0:0:0/64"); - if (da == NULL) goto error; - db = DetectAddressParseSingle("2001:1:2:3:2:0:0:0/64"); - if (db == NULL) goto error; - - if (DetectAddressCmp(da, db) != ADDRESS_EQ) - result = 0; - - DetectAddressFree(da); - DetectAddressFree(db); - return result; - -error: - if (da) DetectAddressFree(da); - if (db) DetectAddressFree(db); - return 0; -} - -int AddressTestAddressGroupSetup01(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "1.2.3.4"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup02(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "1.2.3.4"); - if (r == 0 && gh->ipv4_head != NULL) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup03(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "1.2.3.4"); - if (r == 0 && gh->ipv4_head != NULL) { - DetectAddress *prev_head = gh->ipv4_head; - - r = DetectAddressParse(NULL, gh, "1.2.3.3"); - if (r == 0 && gh->ipv4_head != prev_head && - gh->ipv4_head != NULL && gh->ipv4_head->next == prev_head) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup04(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "1.2.3.4"); - if (r == 0 && gh->ipv4_head != NULL) { - DetectAddress *prev_head = gh->ipv4_head; - - r = DetectAddressParse(NULL, gh, "1.2.3.3"); - if (r == 0 && gh->ipv4_head != prev_head && - gh->ipv4_head != NULL && gh->ipv4_head->next == prev_head) { - DetectAddress *prev_head = gh->ipv4_head; - - r = DetectAddressParse(NULL, gh, "1.2.3.2"); - if (r == 0 && gh->ipv4_head != prev_head && - gh->ipv4_head != NULL && gh->ipv4_head->next == prev_head) { - result = 1; - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup05(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "1.2.3.2"); - if (r == 0 && gh->ipv4_head != NULL) { - DetectAddress *prev_head = gh->ipv4_head; - - r = DetectAddressParse(NULL, gh, "1.2.3.3"); - if (r == 0 && gh->ipv4_head == prev_head && - gh->ipv4_head != NULL && gh->ipv4_head->next != prev_head) { - DetectAddress *prev_head = gh->ipv4_head; - - r = DetectAddressParse(NULL, gh, "1.2.3.4"); - if (r == 0 && gh->ipv4_head == prev_head && - gh->ipv4_head != NULL && gh->ipv4_head->next != prev_head) { - result = 1; - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup06(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "1.2.3.2"); - if (r == 0 && gh->ipv4_head != NULL) { - DetectAddress *prev_head = gh->ipv4_head; - - r = DetectAddressParse(NULL, gh, "1.2.3.2"); - if (r == 0 && gh->ipv4_head == prev_head && - gh->ipv4_head != NULL && gh->ipv4_head->next == NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup07(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "10.0.0.0/8"); - if (r == 0 && gh->ipv4_head != NULL) { - r = DetectAddressParse(NULL, gh, "10.10.10.10"); - if (r == 0 && gh->ipv4_head != NULL && - gh->ipv4_head->next != NULL && - gh->ipv4_head->next->next != NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup08(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "10.10.10.10"); - if (r == 0 && gh->ipv4_head != NULL) { - r = DetectAddressParse(NULL, gh, "10.0.0.0/8"); - if (r == 0 && gh->ipv4_head != NULL && - gh->ipv4_head->next != NULL && - gh->ipv4_head->next->next != NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup09(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "10.10.10.0/24"); - if (r == 0 && gh->ipv4_head != NULL) { - r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1"); - if (r == 0 && gh->ipv4_head != NULL && - gh->ipv4_head->next != NULL && - gh->ipv4_head->next->next != NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup10(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1"); - if (r == 0 && gh->ipv4_head != NULL) { - r = DetectAddressParse(NULL, gh, "10.10.10.0/24"); - if (r == 0 && gh->ipv4_head != NULL && - gh->ipv4_head->next != NULL && - gh->ipv4_head->next->next != NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup11(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "10.10.10.0/24"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "0.0.0.0/0"); - if (r == 0) { - DetectAddress *one = gh->ipv4_head, *two = one->next, - *three = two->next, *four = three->next, - *five = four->next; - - /* result should be: - * 0.0.0.0/10.10.9.255 - * 10.10.10.0/10.10.10.9 - * 10.10.10.10/10.10.10.255 - * 10.10.11.0/10.10.11.1 - * 10.10.11.2/255.255.255.255 - */ - if (one->ip.addr_data32[0] == 0x00000000 && one->ip2.addr_data32[0] == ntohl(168430079) && - two->ip.addr_data32[0] == ntohl(168430080) && two->ip2.addr_data32[0] == ntohl(168430089) && - three->ip.addr_data32[0] == ntohl(168430090) && three->ip2.addr_data32[0] == ntohl(168430335) && - four->ip.addr_data32[0] == ntohl(168430336) && four->ip2.addr_data32[0] == ntohl(168430337) && - five->ip.addr_data32[0] == ntohl(168430338) && five->ip2.addr_data32[0] == 0xFFFFFFFF) { - result = 1; - } - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup12 (void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "0.0.0.0/0"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "10.10.10.0/24"); - if (r == 0) { - DetectAddress *one = gh->ipv4_head, *two = one->next, - *three = two->next, *four = three->next, - *five = four->next; - - /* result should be: - * 0.0.0.0/10.10.9.255 - * 10.10.10.0/10.10.10.9 - * 10.10.10.10/10.10.10.255 - * 10.10.11.0/10.10.11.1 - * 10.10.11.2/255.255.255.255 - */ - if (one->ip.addr_data32[0] == 0x00000000 && one->ip2.addr_data32[0] == ntohl(168430079) && - two->ip.addr_data32[0] == ntohl(168430080) && two->ip2.addr_data32[0] == ntohl(168430089) && - three->ip.addr_data32[0] == ntohl(168430090) && three->ip2.addr_data32[0] == ntohl(168430335) && - four->ip.addr_data32[0] == ntohl(168430336) && four->ip2.addr_data32[0] == ntohl(168430337) && - five->ip.addr_data32[0] == ntohl(168430338) && five->ip2.addr_data32[0] == 0xFFFFFFFF) { - result = 1; - } - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup13(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "0.0.0.0/0"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "10.10.10.10-10.10.11.1"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "10.10.10.0/24"); - if (r == 0) { - DetectAddress *one = gh->ipv4_head, *two = one->next, - *three = two->next, *four = three->next, - *five = four->next; - - /* result should be: - * 0.0.0.0/10.10.9.255 - * 10.10.10.0/10.10.10.9 - * 10.10.10.10/10.10.10.255 - * 10.10.11.0/10.10.11.1 - * 10.10.11.2/255.255.255.255 - */ - if (one->ip.addr_data32[0] == 0x00000000 && one->ip2.addr_data32[0] == ntohl(168430079) && - two->ip.addr_data32[0] == ntohl(168430080) && two->ip2.addr_data32[0] == ntohl(168430089) && - three->ip.addr_data32[0] == ntohl(168430090) && three->ip2.addr_data32[0] == ntohl(168430335) && - four->ip.addr_data32[0] == ntohl(168430336) && four->ip2.addr_data32[0] == ntohl(168430337) && - five->ip.addr_data32[0] == ntohl(168430338) && five->ip2.addr_data32[0] == 0xFFFFFFFF) { - result = 1; - } - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetupIPv414(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "!1.2.3.4"); - if (r == 0) { - DetectAddress *one = gh->ipv4_head; - DetectAddress *two = one ? one->next : NULL; - - if (one && two) { - /* result should be: - * 0.0.0.0/1.2.3.3 - * 1.2.3.5/255.255.255.255 - */ - if (one->ip.addr_data32[0] == 0x00000000 && one->ip2.addr_data32[0] == ntohl(16909059) && - two->ip.addr_data32[0] == ntohl(16909061) && two->ip2.addr_data32[0] == 0xFFFFFFFF) { - result = 1; - } else { - printf("unexpected addresses: "); - } - } else { - printf("one %p two %p: ", one, two); - } - } else { - printf("DetectAddressParse returned %d, expected 0: ", r); - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetupIPv415(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "!0.0.0.0"); - if (r == 0) { - DetectAddress *one = gh->ipv4_head; - - if (one && one->next == NULL) { - /* result should be: - * 0.0.0.1/255.255.255.255 - */ - if (one->ip.addr_data32[0] == ntohl(1) && one->ip2.addr_data32[0] == 0xFFFFFFFF) - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetupIPv416(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "!255.255.255.255"); - if (r == 0) { - DetectAddress *one = gh->ipv4_head; - - if (one && one->next == NULL) { - /* result should be: - * 0.0.0.0/255.255.255.254 - */ - if (one->ip.addr_data32[0] == 0x00000000 && one->ip2.addr_data32[0] == ntohl(4294967294)) - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup14(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::1"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup15(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::1"); - if (r == 0 && gh->ipv6_head != NULL) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup16(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::4"); - if (r == 0 && gh->ipv6_head != NULL) { - DetectAddress *prev_head = gh->ipv6_head; - - r = DetectAddressParse(NULL, gh, "2001::3"); - if (r == 0 && gh->ipv6_head != prev_head && - gh->ipv6_head != NULL && gh->ipv6_head->next == prev_head) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup17(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::4"); - if (r == 0 && gh->ipv6_head != NULL) { - DetectAddress *prev_head = gh->ipv6_head; - - r = DetectAddressParse(NULL, gh, "2001::3"); - if (r == 0 && gh->ipv6_head != prev_head && - gh->ipv6_head != NULL && gh->ipv6_head->next == prev_head) { - DetectAddress *prev_head = gh->ipv6_head; - - r = DetectAddressParse(NULL, gh, "2001::2"); - if (r == 0 && gh->ipv6_head != prev_head && - gh->ipv6_head != NULL && gh->ipv6_head->next == prev_head) { - result = 1; - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup18(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::2"); - if (r == 0 && gh->ipv6_head != NULL) { - DetectAddress *prev_head = gh->ipv6_head; - - r = DetectAddressParse(NULL, gh, "2001::3"); - if (r == 0 && gh->ipv6_head == prev_head && - gh->ipv6_head != NULL && gh->ipv6_head->next != prev_head) { - DetectAddress *prev_head = gh->ipv6_head; - - r = DetectAddressParse(NULL, gh, "2001::4"); - if (r == 0 && gh->ipv6_head == prev_head && - gh->ipv6_head != NULL && gh->ipv6_head->next != prev_head) { - result = 1; - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup19(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::2"); - if (r == 0 && gh->ipv6_head != NULL) { - DetectAddress *prev_head = gh->ipv6_head; - - r = DetectAddressParse(NULL, gh, "2001::2"); - if (r == 0 && gh->ipv6_head == prev_head && - gh->ipv6_head != NULL && gh->ipv6_head->next == NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup20(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2000::/3"); - if (r == 0 && gh->ipv6_head != NULL) { - r = DetectAddressParse(NULL, gh, "2001::4"); - if (r == 0 && gh->ipv6_head != NULL && - gh->ipv6_head->next != NULL && - gh->ipv6_head->next->next != NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup21(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::4"); - if (r == 0 && gh->ipv6_head != NULL) { - r = DetectAddressParse(NULL, gh, "2000::/3"); - if (r == 0 && gh->ipv6_head != NULL && - gh->ipv6_head->next != NULL && - gh->ipv6_head->next->next != NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup22(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2000::/3"); - if (r == 0 && gh->ipv6_head != NULL) { - r = DetectAddressParse(NULL, gh, "2001::4-2001::6"); - if (r == 0 && gh->ipv6_head != NULL && - gh->ipv6_head->next != NULL && - gh->ipv6_head->next->next != NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup23(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::4-2001::6"); - if (r == 0 && gh->ipv6_head != NULL) { - r = DetectAddressParse(NULL, gh, "2000::/3"); - if (r == 0 && gh->ipv6_head != NULL && - gh->ipv6_head->next != NULL && - gh->ipv6_head->next->next != NULL) { - result = 1; - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup24(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::4-2001::6"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "2001::/3"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "::/0"); - if (r == 0) { - DetectAddress *one = gh->ipv6_head, *two = one->next, - *three = two->next, *four = three->next, - *five = four->next; - if (one->ip.addr_data32[0] == 0x00000000 && - one->ip.addr_data32[1] == 0x00000000 && - one->ip.addr_data32[2] == 0x00000000 && - one->ip.addr_data32[3] == 0x00000000 && - one->ip2.addr_data32[0] == ntohl(536870911) && - one->ip2.addr_data32[1] == 0xFFFFFFFF && - one->ip2.addr_data32[2] == 0xFFFFFFFF && - one->ip2.addr_data32[3] == 0xFFFFFFFF && - - two->ip.addr_data32[0] == ntohl(536870912) && - two->ip.addr_data32[1] == 0x00000000 && - two->ip.addr_data32[2] == 0x00000000 && - two->ip.addr_data32[3] == 0x00000000 && - two->ip2.addr_data32[0] == ntohl(536936448) && - two->ip2.addr_data32[1] == 0x00000000 && - two->ip2.addr_data32[2] == 0x00000000 && - two->ip2.addr_data32[3] == ntohl(3) && - - three->ip.addr_data32[0] == ntohl(536936448) && - three->ip.addr_data32[1] == 0x00000000 && - three->ip.addr_data32[2] == 0x00000000 && - three->ip.addr_data32[3] == ntohl(4) && - three->ip2.addr_data32[0] == ntohl(536936448) && - three->ip2.addr_data32[1] == 0x00000000 && - three->ip2.addr_data32[2] == 0x00000000 && - three->ip2.addr_data32[3] == ntohl(6) && - - four->ip.addr_data32[0] == ntohl(536936448) && - four->ip.addr_data32[1] == 0x00000000 && - four->ip.addr_data32[2] == 0x00000000 && - four->ip.addr_data32[3] == ntohl(7) && - four->ip2.addr_data32[0] == ntohl(1073741823) && - four->ip2.addr_data32[1] == 0xFFFFFFFF && - four->ip2.addr_data32[2] == 0xFFFFFFFF && - four->ip2.addr_data32[3] == 0xFFFFFFFF && - - five->ip.addr_data32[0] == ntohl(1073741824) && - five->ip.addr_data32[1] == 0x00000000 && - five->ip.addr_data32[2] == 0x00000000 && - five->ip.addr_data32[3] == 0x00000000 && - five->ip2.addr_data32[0] == 0xFFFFFFFF && - five->ip2.addr_data32[1] == 0xFFFFFFFF && - five->ip2.addr_data32[2] == 0xFFFFFFFF && - five->ip2.addr_data32[3] == 0xFFFFFFFF) { - result = 1; - } - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup25(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "2001::4-2001::6"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "::/0"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "2001::/3"); - if (r == 0) { - DetectAddress *one = gh->ipv6_head, *two = one->next, - *three = two->next, *four = three->next, - *five = four->next; - if (one->ip.addr_data32[0] == 0x00000000 && - one->ip.addr_data32[1] == 0x00000000 && - one->ip.addr_data32[2] == 0x00000000 && - one->ip.addr_data32[3] == 0x00000000 && - one->ip2.addr_data32[0] == ntohl(536870911) && - one->ip2.addr_data32[1] == 0xFFFFFFFF && - one->ip2.addr_data32[2] == 0xFFFFFFFF && - one->ip2.addr_data32[3] == 0xFFFFFFFF && - - two->ip.addr_data32[0] == ntohl(536870912) && - two->ip.addr_data32[1] == 0x00000000 && - two->ip.addr_data32[2] == 0x00000000 && - two->ip.addr_data32[3] == 0x00000000 && - two->ip2.addr_data32[0] == ntohl(536936448) && - two->ip2.addr_data32[1] == 0x00000000 && - two->ip2.addr_data32[2] == 0x00000000 && - two->ip2.addr_data32[3] == ntohl(3) && - - three->ip.addr_data32[0] == ntohl(536936448) && - three->ip.addr_data32[1] == 0x00000000 && - three->ip.addr_data32[2] == 0x00000000 && - three->ip.addr_data32[3] == ntohl(4) && - three->ip2.addr_data32[0] == ntohl(536936448) && - three->ip2.addr_data32[1] == 0x00000000 && - three->ip2.addr_data32[2] == 0x00000000 && - three->ip2.addr_data32[3] == ntohl(6) && - - four->ip.addr_data32[0] == ntohl(536936448) && - four->ip.addr_data32[1] == 0x00000000 && - four->ip.addr_data32[2] == 0x00000000 && - four->ip.addr_data32[3] == ntohl(7) && - four->ip2.addr_data32[0] == ntohl(1073741823) && - four->ip2.addr_data32[1] == 0xFFFFFFFF && - four->ip2.addr_data32[2] == 0xFFFFFFFF && - four->ip2.addr_data32[3] == 0xFFFFFFFF && - - five->ip.addr_data32[0] == ntohl(1073741824) && - five->ip.addr_data32[1] == 0x00000000 && - five->ip.addr_data32[2] == 0x00000000 && - five->ip.addr_data32[3] == 0x00000000 && - five->ip2.addr_data32[0] == 0xFFFFFFFF && - five->ip2.addr_data32[1] == 0xFFFFFFFF && - five->ip2.addr_data32[2] == 0xFFFFFFFF && - five->ip2.addr_data32[3] == 0xFFFFFFFF) { - result = 1; - } - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup26(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "::/0"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "2001::4-2001::6"); - if (r == 0) { - r = DetectAddressParse(NULL, gh, "2001::/3"); - if (r == 0) { - DetectAddress *one = gh->ipv6_head, *two = one->next, - *three = two->next, *four = three->next, - *five = four->next; - if (one->ip.addr_data32[0] == 0x00000000 && - one->ip.addr_data32[1] == 0x00000000 && - one->ip.addr_data32[2] == 0x00000000 && - one->ip.addr_data32[3] == 0x00000000 && - one->ip2.addr_data32[0] == ntohl(536870911) && - one->ip2.addr_data32[1] == 0xFFFFFFFF && - one->ip2.addr_data32[2] == 0xFFFFFFFF && - one->ip2.addr_data32[3] == 0xFFFFFFFF && - - two->ip.addr_data32[0] == ntohl(536870912) && - two->ip.addr_data32[1] == 0x00000000 && - two->ip.addr_data32[2] == 0x00000000 && - two->ip.addr_data32[3] == 0x00000000 && - two->ip2.addr_data32[0] == ntohl(536936448) && - two->ip2.addr_data32[1] == 0x00000000 && - two->ip2.addr_data32[2] == 0x00000000 && - two->ip2.addr_data32[3] == ntohl(3) && - - three->ip.addr_data32[0] == ntohl(536936448) && - three->ip.addr_data32[1] == 0x00000000 && - three->ip.addr_data32[2] == 0x00000000 && - three->ip.addr_data32[3] == ntohl(4) && - three->ip2.addr_data32[0] == ntohl(536936448) && - three->ip2.addr_data32[1] == 0x00000000 && - three->ip2.addr_data32[2] == 0x00000000 && - three->ip2.addr_data32[3] == ntohl(6) && - - four->ip.addr_data32[0] == ntohl(536936448) && - four->ip.addr_data32[1] == 0x00000000 && - four->ip.addr_data32[2] == 0x00000000 && - four->ip.addr_data32[3] == ntohl(7) && - four->ip2.addr_data32[0] == ntohl(1073741823) && - four->ip2.addr_data32[1] == 0xFFFFFFFF && - four->ip2.addr_data32[2] == 0xFFFFFFFF && - four->ip2.addr_data32[3] == 0xFFFFFFFF && - - five->ip.addr_data32[0] == ntohl(1073741824) && - five->ip.addr_data32[1] == 0x00000000 && - five->ip.addr_data32[2] == 0x00000000 && - five->ip.addr_data32[3] == 0x00000000 && - five->ip2.addr_data32[0] == 0xFFFFFFFF && - five->ip2.addr_data32[1] == 0xFFFFFFFF && - five->ip2.addr_data32[2] == 0xFFFFFFFF && - five->ip2.addr_data32[3] == 0xFFFFFFFF) { - result = 1; - } - } - } - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup27(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[1.2.3.4]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup28(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[1.2.3.4,4.3.2.1]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup29(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[1.2.3.4,4.3.2.1,10.10.10.10]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup30(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[[1.2.3.4,2.3.4.5],4.3.2.1,[10.10.10.10,11.11.11.11]]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup31(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[[1.2.3.4,[2.3.4.5,3.4.5.6]],4.3.2.1,[10.10.10.10,[11.11.11.11,12.12.12.12]]]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup32(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[[1.2.3.4,[2.3.4.5,[3.4.5.6,4.5.6.7]]],4.3.2.1,[10.10.10.10,[11.11.11.11,[12.12.12.12,13.13.13.13]]]]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup33(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "![1.1.1.1,[2.2.2.2,[3.3.3.3,4.4.4.4]]]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup34(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[1.0.0.0/8,![1.1.1.1,[1.2.1.1,1.3.1.1]]]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup35(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[1.0.0.0/8,[2.0.0.0/8,![1.1.1.1,2.2.2.2]]]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup36 (void) -{ - int result = 0; - - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[1.0.0.0/8,[2.0.0.0/8,[3.0.0.0/8,!1.1.1.1]]]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestAddressGroupSetup37(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[0.0.0.0/0,::/0]"); - if (r == 0) - result = 1; - - DetectAddressHeadFree(gh); - } - return result; -} - -static int AddressTestAddressGroupSetup38(void) -{ - UTHValidateDetectAddressHeadRange expectations[3] = { - { "0.0.0.0", "192.167.255.255" }, - { "192.168.14.0", "192.168.14.255" }, - { "192.169.0.0", "255.255.255.255" } }; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "![192.168.0.0/16,!192.168.14.0/24]"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 3, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -static int AddressTestAddressGroupSetup39(void) -{ - UTHValidateDetectAddressHeadRange expectations[3] = { - { "0.0.0.0", "192.167.255.255" }, - { "192.168.14.0", "192.168.14.255" }, - { "192.169.0.0", "255.255.255.255" } }; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,!192.168.14.0/24]]"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 3, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -static int AddressTestAddressGroupSetup40(void) -{ - UTHValidateDetectAddressHeadRange expectations[3] = { - { "0.0.0.0", "192.167.255.255" }, - { "192.168.14.0", "192.168.14.255" }, - { "192.169.0.0", "255.255.255.255" } }; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,[!192.168.14.0/24]]]"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 3, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -static int AddressTestAddressGroupSetup41(void) -{ - UTHValidateDetectAddressHeadRange expectations[3] = { - { "0.0.0.0", "192.167.255.255" }, - { "192.168.14.0", "192.168.14.255" }, - { "192.169.0.0", "255.255.255.255" } }; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,![192.168.14.0/24]]]"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 3, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -static int AddressTestAddressGroupSetup42(void) -{ - UTHValidateDetectAddressHeadRange expectations[1] = { - { "2000:0000:0000:0000:0000:0000:0000:0000", "3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" } }; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[2001::/3]"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 1, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -static int AddressTestAddressGroupSetup43(void) -{ - UTHValidateDetectAddressHeadRange expectations[2] = { - { "2000:0000:0000:0000:0000:0000:0000:0000", "2fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" }, - { "3800:0000:0000:0000:0000:0000:0000:0000", "3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" } }; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[2001::/3,!3000::/5]"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 2, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -static int AddressTestAddressGroupSetup44(void) -{ - UTHValidateDetectAddressHeadRange expectations[2] = { - { "3ffe:ffff:7654:feda:1245:ba98:0000:0000", "3ffe:ffff:7654:feda:1245:ba98:ffff:ffff" }}; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "3ffe:ffff:7654:feda:1245:ba98:3210:4562/96"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 1, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -static int AddressTestAddressGroupSetup45(void) -{ - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[192.168.1.3,!192.168.0.0/16]"); - if (r != 0) { - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -static int AddressTestAddressGroupSetup46(void) -{ - UTHValidateDetectAddressHeadRange expectations[4] = { - { "0.0.0.0", "192.167.255.255" }, - { "192.168.1.0", "192.168.1.255" }, - { "192.168.3.0", "192.168.3.255" }, - { "192.169.0.0", "255.255.255.255" } }; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,![192.168.1.0/24,192.168.3.0/24]]]"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 4, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -/** \test net with some negations, then all negated */ -static int AddressTestAddressGroupSetup47(void) -{ - UTHValidateDetectAddressHeadRange expectations[5] = { - { "0.0.0.0", "192.167.255.255" }, - { "192.168.1.0", "192.168.1.255" }, - { "192.168.3.0", "192.168.3.255" }, - { "192.168.5.0", "192.168.5.255" }, - { "192.169.0.0", "255.255.255.255" } }; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[![192.168.0.0/16,![192.168.1.0/24,192.168.3.0/24],!192.168.5.0/24]]"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 5, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -/** \test same as AddressTestAddressGroupSetup47, but not negated */ -static int AddressTestAddressGroupSetup48(void) -{ - UTHValidateDetectAddressHeadRange expectations[4] = { - { "192.168.0.0", "192.168.0.255" }, - { "192.168.2.0", "192.168.2.255" }, - { "192.168.4.0", "192.168.4.255" }, - { "192.168.6.0", "192.168.255.255" } }; - int result = 0; - DetectAddressHead *gh = DetectAddressHeadInit(); - if (gh != NULL) { - int r = DetectAddressParse(NULL, gh, "[192.168.0.0/16,![192.168.1.0/24,192.168.3.0/24],!192.168.5.0/24]"); - if (r == 0) { - if (UTHValidateDetectAddressHead(gh, 4, expectations) == TRUE) - result = 1; - } - - DetectAddressHeadFree(gh); - } - return result; -} - -int AddressTestCutIPv401(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.0/255.255.255.0"); - b = DetectAddressParseSingle("1.2.2.0-1.2.3.4"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestCutIPv402(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.0/255.255.255.0"); - b = DetectAddressParseSingle("1.2.2.0-1.2.3.4"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - if (c == NULL) - goto error; - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestCutIPv403(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.0/255.255.255.0"); - b = DetectAddressParseSingle("1.2.2.0-1.2.3.4"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - if (c == NULL) - goto error; - - if (a->ip.addr_data32[0] != ntohl(16908800) || a->ip2.addr_data32[0] != ntohl(16909055)) - goto error; - if (b->ip.addr_data32[0] != ntohl(16909056) || b->ip2.addr_data32[0] != ntohl(16909060)) - goto error; - if (c->ip.addr_data32[0] != ntohl(16909061) || c->ip2.addr_data32[0] != ntohl(16909311)) - goto error; - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestCutIPv404(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.3-1.2.3.6"); - b = DetectAddressParseSingle("1.2.3.0-1.2.3.5"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - if (c == NULL) - goto error; - - if (a->ip.addr_data32[0] != ntohl(16909056) || a->ip2.addr_data32[0] != ntohl(16909058)) - goto error; - if (b->ip.addr_data32[0] != ntohl(16909059) || b->ip2.addr_data32[0] != ntohl(16909061)) - goto error; - if (c->ip.addr_data32[0] != ntohl(16909062) || c->ip2.addr_data32[0] != ntohl(16909062)) - goto error; - - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestCutIPv405(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.3-1.2.3.6"); - b = DetectAddressParseSingle("1.2.3.0-1.2.3.9"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - if (c == NULL) - goto error; - - if (a->ip.addr_data32[0] != ntohl(16909056) || a->ip2.addr_data32[0] != ntohl(16909058)) - goto error; - if (b->ip.addr_data32[0] != ntohl(16909059) || b->ip2.addr_data32[0] != ntohl(16909062)) - goto error; - if (c->ip.addr_data32[0] != ntohl(16909063) || c->ip2.addr_data32[0] != ntohl(16909065)) - goto error; - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestCutIPv406(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.0-1.2.3.9"); - b = DetectAddressParseSingle("1.2.3.3-1.2.3.6"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - if (c == NULL) - goto error; - - if (a->ip.addr_data32[0] != ntohl(16909056) || a->ip2.addr_data32[0] != ntohl(16909058)) - goto error; - if (b->ip.addr_data32[0] != ntohl(16909059) || b->ip2.addr_data32[0] != ntohl(16909062)) - goto error; - if (c->ip.addr_data32[0] != ntohl(16909063) || c->ip2.addr_data32[0] != ntohl(16909065)) - goto error; - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestCutIPv407(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.0-1.2.3.6"); - b = DetectAddressParseSingle("1.2.3.0-1.2.3.9"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - if (c != NULL) - goto error; - - if (a->ip.addr_data32[0] != ntohl(16909056) || a->ip2.addr_data32[0] != ntohl(16909062)) - goto error; - if (b->ip.addr_data32[0] != ntohl(16909063) || b->ip2.addr_data32[0] != ntohl(16909065)) - goto error; - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestCutIPv408(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.3-1.2.3.9"); - b = DetectAddressParseSingle("1.2.3.0-1.2.3.9"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - if (c != NULL) - goto error; - - if (a->ip.addr_data32[0] != ntohl(16909056) || a->ip2.addr_data32[0] != ntohl(16909058)) - goto error; - if (b->ip.addr_data32[0] != ntohl(16909059) || b->ip2.addr_data32[0] != ntohl(16909065)) - goto error; - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestCutIPv409(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.0-1.2.3.9"); - b = DetectAddressParseSingle("1.2.3.0-1.2.3.6"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - if (c != NULL) - goto error; - - if (a->ip.addr_data32[0] != ntohl(16909056) || a->ip2.addr_data32[0] != ntohl(16909062)) - goto error; - if (b->ip.addr_data32[0] != ntohl(16909063) || b->ip2.addr_data32[0] != ntohl(16909065)) - goto error; - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestCutIPv410(void) -{ - DetectAddress *a, *b, *c; - a = DetectAddressParseSingle("1.2.3.0-1.2.3.9"); - b = DetectAddressParseSingle("1.2.3.3-1.2.3.9"); - - if (DetectAddressCut(NULL, a, b, &c) == -1) - goto error; - - if (c != NULL) - goto error; - - if (a->ip.addr_data32[0] != ntohl(16909056) || a->ip2.addr_data32[0] != ntohl(16909058)) - goto error; - if (b->ip.addr_data32[0] != ntohl(16909059) || b->ip2.addr_data32[0] != ntohl(16909065)) - goto error; - - printf("ip %u ip2 %u ", htonl(a->ip.addr_data32[0]), htonl(a->ip2.addr_data32[0])); - - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 1; - -error: - DetectAddressFree(a); - DetectAddressFree(b); - DetectAddressFree(c); - return 0; -} - -int AddressTestParseInvalidMask01(void) -{ - int result = 1; - DetectAddress *dd = NULL; - - dd = DetectAddressParseSingle("192.168.2.0/33"); - if (dd != NULL) { - DetectAddressFree(dd); - result = 0; - } - return result; -} - -int AddressTestParseInvalidMask02(void) -{ - int result = 1; - DetectAddress *dd = NULL; - - dd = DetectAddressParseSingle("192.168.2.0/255.255.257.0"); - if (dd != NULL) { - DetectAddressFree(dd); - result = 0; - } - return result; -} - -int AddressTestParseInvalidMask03(void) -{ - int result = 1; - DetectAddress *dd = NULL; - - dd = DetectAddressParseSingle("192.168.2.0/blue"); - if (dd != NULL) { - DetectAddressFree(dd); - result = 0; - } - return result; -} - -int AddressConfVarsTest01(void) -{ - static const char *dummy_conf_string = - "%YAML 1.1\n" - "---\n" - "\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"any\"\n" - "\n" - " EXTERNAL_NET: \"!any\"\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"any\"\n" - "\n" - " SHELLCODE_PORTS: \"!any\"\n" - "\n"; - - int result = 0; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - if (DetectAddressTestConfVars() < 0 && DetectPortTestConfVars() < 0) - result = 1; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return result; -} - -int AddressConfVarsTest02(void) -{ - static const char *dummy_conf_string = - "%YAML 1.1\n" - "---\n" - "\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"any\"\n" - "\n" - " EXTERNAL_NET: \"any\"\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"any\"\n" - "\n" - " SHELLCODE_PORTS: \"!any\"\n" - "\n"; - - int result = 0; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - if (DetectAddressTestConfVars() == 0 && DetectPortTestConfVars() < 0) - result = 1; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return result; -} - -int AddressConfVarsTest03(void) -{ - static const char *dummy_conf_string = - "%YAML 1.1\n" - "---\n" - "\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"any\"\n" - "\n" - " EXTERNAL_NET: \"!$HOME_NET\"\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"any\"\n" - "\n" - " SHELLCODE_PORTS: \"!$HTTP_PORTS\"\n" - "\n"; - - int result = 0; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - if (DetectAddressTestConfVars() < 0 && DetectPortTestConfVars() < 0) - result = 1; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return result; -} - -int AddressConfVarsTest04(void) -{ - static const char *dummy_conf_string = - "%YAML 1.1\n" - "---\n" - "\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"any\"\n" - "\n" - " EXTERNAL_NET: \"$HOME_NET\"\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"any\"\n" - "\n" - " SHELLCODE_PORTS: \"$HTTP_PORTS\"\n" - "\n"; - - int result = 0; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - if (DetectAddressTestConfVars() == 0 && DetectPortTestConfVars() == 0) - result = 1; - - ConfDeInit(); - ConfRestoreContextBackup(); - - return result; -} - -int AddressConfVarsTest05(void) -{ - static const char *dummy_conf_string = - "%YAML 1.1\n" - "---\n" - "\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"any\"\n" - "\n" - " EXTERNAL_NET: [192.168.0.1]\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"any\"\n" - "\n" - " SHELLCODE_PORTS: [80]\n" - "\n"; - - int result = 0; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - if (DetectAddressTestConfVars() != -1 && DetectPortTestConfVars() != -1) - goto end; - - result = 1; - - end: - ConfDeInit(); - ConfRestoreContextBackup(); - - return result; -} - -#include "detect-engine.h" - -/** - * \test Test sig distribution over address groups - */ -static int AddressTestFunctions01(void) -{ - DetectAddress *a1 = NULL; - DetectAddress *a2 = NULL; - DetectAddressHead *h = NULL; - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature s[2]; - memset(s,0x00,sizeof(s)); - - s[0].num = 0; - s[1].num = 1; - - a1 = DetectAddressParseSingle("255.0.0.0/8"); - if (a1 == NULL) { - printf("a1 == NULL: "); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &a1->sh, &s[0]); - - a2 = DetectAddressParseSingle("0.0.0.0/0"); - if (a2 == NULL) { - printf("a2 == NULL: "); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &a2->sh, &s[1]); - - SCLogDebug("a1"); - DetectAddressPrint(a1); - SCLogDebug("a2"); - DetectAddressPrint(a2); - - h = DetectAddressHeadInit(); - if (h == NULL) - goto end; - DetectAddressInsert(de_ctx, h, a1); - DetectAddressInsert(de_ctx, h, a2); - - if (h == NULL) - goto end; - - DetectAddress *x = h->ipv4_head; - for ( ; x != NULL; x = x->next) { - SCLogDebug("x %p next %p", x, x->next); - DetectAddressPrint(x); - //SigGroupHeadPrintSigs(de_ctx, x->sh); - } - - DetectAddress *one = h->ipv4_head; - DetectAddress *two = one->next; - - int sig = 0; - if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'two', but it shouldn't: ", sig); - goto end; - } - - result = 1; -end: - if (h != NULL) - DetectAddressHeadFree(h); - return result; -} - -/** - * \test Test sig distribution over address groups - */ -static int AddressTestFunctions02(void) -{ - DetectAddress *a1 = NULL; - DetectAddress *a2 = NULL; - DetectAddressHead *h = NULL; - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature s[2]; - memset(s,0x00,sizeof(s)); - - s[0].num = 0; - s[1].num = 1; - - a1 = DetectAddressParseSingle("255.0.0.0/8"); - if (a1 == NULL) { - printf("a1 == NULL: "); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &a1->sh, &s[0]); - - a2 = DetectAddressParseSingle("0.0.0.0/0"); - if (a2 == NULL) { - printf("a2 == NULL: "); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &a2->sh, &s[1]); - - SCLogDebug("a1"); - DetectAddressPrint(a1); - SCLogDebug("a2"); - DetectAddressPrint(a2); - - h = DetectAddressHeadInit(); - if (h == NULL) - goto end; - DetectAddressInsert(de_ctx, h, a2); - DetectAddressInsert(de_ctx, h, a1); - - BUG_ON(h == NULL); - - SCLogDebug("dp3"); - - DetectAddress *x = h->ipv4_head; - for ( ; x != NULL; x = x->next) { - DetectAddressPrint(x); - //SigGroupHeadPrintSigs(de_ctx, x->sh); - } - - DetectAddress *one = h->ipv4_head; - DetectAddress *two = one->next; - - int sig = 0; - if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'two', but it shouldn't: ", sig); - goto end; - } - - result = 1; -end: - if (h != NULL) - DetectAddressHeadFree(h); - return result; -} - -/** - * \test Test sig distribution over address groups - */ -static int AddressTestFunctions03(void) -{ - DetectAddress *a1 = NULL; - DetectAddress *a2 = NULL; - DetectAddressHead *h = NULL; - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature s[2]; - memset(s,0x00,sizeof(s)); - - s[0].num = 0; - s[1].num = 1; - - a1 = DetectAddressParseSingle("ffff::/16"); - if (a1 == NULL) { - printf("a1 == NULL: "); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &a1->sh, &s[0]); - - a2 = DetectAddressParseSingle("::/0"); - if (a2 == NULL) { - printf("a2 == NULL: "); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &a2->sh, &s[1]); - - SCLogDebug("a1"); - DetectAddressPrint(a1); - SCLogDebug("a2"); - DetectAddressPrint(a2); - - h = DetectAddressHeadInit(); - if (h == NULL) - goto end; - DetectAddressInsert(de_ctx, h, a1); - DetectAddressInsert(de_ctx, h, a2); - - if (h == NULL) - goto end; - - DetectAddress *x = h->ipv6_head; - for ( ; x != NULL; x = x->next) { - SCLogDebug("x %p next %p", x, x->next); - DetectAddressPrint(x); - //SigGroupHeadPrintSigs(de_ctx, x->sh); - } - - DetectAddress *one = h->ipv6_head; - DetectAddress *two = one->next; - - int sig = 0; - if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'two', but it shouldn't: ", sig); - goto end; - } - - result = 1; -end: - if (h != NULL) - DetectAddressHeadFree(h); - return result; -} - -/** - * \test Test sig distribution over address groups - */ -static int AddressTestFunctions04(void) -{ - DetectAddress *a1 = NULL; - DetectAddress *a2 = NULL; - DetectAddressHead *h = NULL; - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature s[2]; - memset(s,0x00,sizeof(s)); - - s[0].num = 0; - s[1].num = 1; - - a1 = DetectAddressParseSingle("ffff::/16"); - if (a1 == NULL) { - printf("a1 == NULL: "); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &a1->sh, &s[0]); - - a2 = DetectAddressParseSingle("::/0"); - if (a2 == NULL) { - printf("a2 == NULL: "); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &a2->sh, &s[1]); - - SCLogDebug("a1"); - DetectAddressPrint(a1); - SCLogDebug("a2"); - DetectAddressPrint(a2); - - h = DetectAddressHeadInit(); - if (h == NULL) - goto end; - DetectAddressInsert(de_ctx, h, a2); - DetectAddressInsert(de_ctx, h, a1); - - BUG_ON(h == NULL); - - SCLogDebug("dp3"); - - DetectAddress *x = h->ipv6_head; - for ( ; x != NULL; x = x->next) { - DetectAddressPrint(x); - //SigGroupHeadPrintSigs(de_ctx, x->sh); - } - - DetectAddress *one = h->ipv6_head; - DetectAddress *two = one->next; - - int sig = 0; - if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'two', but it shouldn't: ", sig); - goto end; - } - - result = 1; -end: - if (h != NULL) - DetectAddressHeadFree(h); - return result; -} - -#endif /* UNITTESTS */ - -void DetectAddressTests(void) -{ -#ifdef UNITTESTS - DetectAddressIPv4Tests(); - DetectAddressIPv6Tests(); - - UtRegisterTest("AddressTestParse01", AddressTestParse01, 1); - UtRegisterTest("AddressTestParse02", AddressTestParse02, 1); - UtRegisterTest("AddressTestParse03", AddressTestParse03, 1); - UtRegisterTest("AddressTestParse04", AddressTestParse04, 1); - UtRegisterTest("AddressTestParse05", AddressTestParse05, 1); - UtRegisterTest("AddressTestParse06", AddressTestParse06, 1); - UtRegisterTest("AddressTestParse07", AddressTestParse07, 1); - UtRegisterTest("AddressTestParse08", AddressTestParse08, 1); - UtRegisterTest("AddressTestParse09", AddressTestParse09, 1); - UtRegisterTest("AddressTestParse10", AddressTestParse10, 1); - UtRegisterTest("AddressTestParse11", AddressTestParse11, 1); - UtRegisterTest("AddressTestParse12", AddressTestParse12, 1); - UtRegisterTest("AddressTestParse13", AddressTestParse13, 1); - UtRegisterTest("AddressTestParse14", AddressTestParse14, 1); - UtRegisterTest("AddressTestParse15", AddressTestParse15, 1); - UtRegisterTest("AddressTestParse16", AddressTestParse16, 1); - UtRegisterTest("AddressTestParse17", AddressTestParse17, 1); - UtRegisterTest("AddressTestParse18", AddressTestParse18, 1); - UtRegisterTest("AddressTestParse19", AddressTestParse19, 1); - UtRegisterTest("AddressTestParse20", AddressTestParse20, 1); - UtRegisterTest("AddressTestParse21", AddressTestParse21, 1); - UtRegisterTest("AddressTestParse22", AddressTestParse22, 1); - UtRegisterTest("AddressTestParse23", AddressTestParse23, 1); - UtRegisterTest("AddressTestParse24", AddressTestParse24, 1); - UtRegisterTest("AddressTestParse25", AddressTestParse25, 1); - UtRegisterTest("AddressTestParse26", AddressTestParse26, 1); - UtRegisterTest("AddressTestParse27", AddressTestParse27, 1); - UtRegisterTest("AddressTestParse28", AddressTestParse28, 1); - UtRegisterTest("AddressTestParse29", AddressTestParse29, 1); - UtRegisterTest("AddressTestParse30", AddressTestParse30, 1); - UtRegisterTest("AddressTestParse31", AddressTestParse31, 1); - UtRegisterTest("AddressTestParse32", AddressTestParse32, 1); - UtRegisterTest("AddressTestParse33", AddressTestParse33, 1); - UtRegisterTest("AddressTestParse34", AddressTestParse34, 1); - UtRegisterTest("AddressTestParse35", AddressTestParse35, 1); - UtRegisterTest("AddressTestParse36", AddressTestParse36, 1); - UtRegisterTest("AddressTestParse37", AddressTestParse37, 1); - - UtRegisterTest("AddressTestMatch01", AddressTestMatch01, 1); - UtRegisterTest("AddressTestMatch02", AddressTestMatch02, 1); - UtRegisterTest("AddressTestMatch03", AddressTestMatch03, 1); - UtRegisterTest("AddressTestMatch04", AddressTestMatch04, 1); - UtRegisterTest("AddressTestMatch05", AddressTestMatch05, 1); - UtRegisterTest("AddressTestMatch06", AddressTestMatch06, 1); - UtRegisterTest("AddressTestMatch07", AddressTestMatch07, 1); - UtRegisterTest("AddressTestMatch08", AddressTestMatch08, 1); - UtRegisterTest("AddressTestMatch09", AddressTestMatch09, 1); - UtRegisterTest("AddressTestMatch10", AddressTestMatch10, 1); - UtRegisterTest("AddressTestMatch11", AddressTestMatch11, 1); - - UtRegisterTest("AddressTestCmp01", AddressTestCmp01, 1); - UtRegisterTest("AddressTestCmp02", AddressTestCmp02, 1); - UtRegisterTest("AddressTestCmp03", AddressTestCmp03, 1); - UtRegisterTest("AddressTestCmp04", AddressTestCmp04, 1); - UtRegisterTest("AddressTestCmp05", AddressTestCmp05, 1); - UtRegisterTest("AddressTestCmp06", AddressTestCmp06, 1); - UtRegisterTest("AddressTestCmpIPv407", AddressTestCmpIPv407, 1); - UtRegisterTest("AddressTestCmpIPv408", AddressTestCmpIPv408, 1); - - UtRegisterTest("AddressTestCmp07", AddressTestCmp07, 1); - UtRegisterTest("AddressTestCmp08", AddressTestCmp08, 1); - UtRegisterTest("AddressTestCmp09", AddressTestCmp09, 1); - UtRegisterTest("AddressTestCmp10", AddressTestCmp10, 1); - UtRegisterTest("AddressTestCmp11", AddressTestCmp11, 1); - UtRegisterTest("AddressTestCmp12", AddressTestCmp12, 1); - - UtRegisterTest("AddressTestAddressGroupSetup01", - AddressTestAddressGroupSetup01, 1); - UtRegisterTest("AddressTestAddressGroupSetup02", - AddressTestAddressGroupSetup02, 1); - UtRegisterTest("AddressTestAddressGroupSetup03", - AddressTestAddressGroupSetup03, 1); - UtRegisterTest("AddressTestAddressGroupSetup04", - AddressTestAddressGroupSetup04, 1); - UtRegisterTest("AddressTestAddressGroupSetup05", - AddressTestAddressGroupSetup05, 1); - UtRegisterTest("AddressTestAddressGroupSetup06", - AddressTestAddressGroupSetup06, 1); - UtRegisterTest("AddressTestAddressGroupSetup07", - AddressTestAddressGroupSetup07, 1); - UtRegisterTest("AddressTestAddressGroupSetup08", - AddressTestAddressGroupSetup08, 1); - UtRegisterTest("AddressTestAddressGroupSetup09", - AddressTestAddressGroupSetup09, 1); - UtRegisterTest("AddressTestAddressGroupSetup10", - AddressTestAddressGroupSetup10, 1); - UtRegisterTest("AddressTestAddressGroupSetup11", - AddressTestAddressGroupSetup11, 1); - UtRegisterTest("AddressTestAddressGroupSetup12", - AddressTestAddressGroupSetup12, 1); - UtRegisterTest("AddressTestAddressGroupSetup13", - AddressTestAddressGroupSetup13, 1); - UtRegisterTest("AddressTestAddressGroupSetupIPv414", - AddressTestAddressGroupSetupIPv414, 1); - UtRegisterTest("AddressTestAddressGroupSetupIPv415", - AddressTestAddressGroupSetupIPv415, 1); - UtRegisterTest("AddressTestAddressGroupSetupIPv416", - AddressTestAddressGroupSetupIPv416, 1); - - UtRegisterTest("AddressTestAddressGroupSetup14", - AddressTestAddressGroupSetup14, 1); - UtRegisterTest("AddressTestAddressGroupSetup15", - AddressTestAddressGroupSetup15, 1); - UtRegisterTest("AddressTestAddressGroupSetup16", - AddressTestAddressGroupSetup16, 1); - UtRegisterTest("AddressTestAddressGroupSetup17", - AddressTestAddressGroupSetup17, 1); - UtRegisterTest("AddressTestAddressGroupSetup18", - AddressTestAddressGroupSetup18, 1); - UtRegisterTest("AddressTestAddressGroupSetup19", - AddressTestAddressGroupSetup19, 1); - UtRegisterTest("AddressTestAddressGroupSetup20", - AddressTestAddressGroupSetup20, 1); - UtRegisterTest("AddressTestAddressGroupSetup21", - AddressTestAddressGroupSetup21, 1); - UtRegisterTest("AddressTestAddressGroupSetup22", - AddressTestAddressGroupSetup22, 1); - UtRegisterTest("AddressTestAddressGroupSetup23", - AddressTestAddressGroupSetup23, 1); - UtRegisterTest("AddressTestAddressGroupSetup24", - AddressTestAddressGroupSetup24, 1); - UtRegisterTest("AddressTestAddressGroupSetup25", - AddressTestAddressGroupSetup25, 1); - UtRegisterTest("AddressTestAddressGroupSetup26", - AddressTestAddressGroupSetup26, 1); - - UtRegisterTest("AddressTestAddressGroupSetup27", - AddressTestAddressGroupSetup27, 1); - UtRegisterTest("AddressTestAddressGroupSetup28", - AddressTestAddressGroupSetup28, 1); - UtRegisterTest("AddressTestAddressGroupSetup29", - AddressTestAddressGroupSetup29, 1); - UtRegisterTest("AddressTestAddressGroupSetup30", - AddressTestAddressGroupSetup30, 1); - UtRegisterTest("AddressTestAddressGroupSetup31", - AddressTestAddressGroupSetup31, 1); - UtRegisterTest("AddressTestAddressGroupSetup32", - AddressTestAddressGroupSetup32, 1); - UtRegisterTest("AddressTestAddressGroupSetup33", - AddressTestAddressGroupSetup33, 1); - UtRegisterTest("AddressTestAddressGroupSetup34", - AddressTestAddressGroupSetup34, 1); - UtRegisterTest("AddressTestAddressGroupSetup35", - AddressTestAddressGroupSetup35, 1); - UtRegisterTest("AddressTestAddressGroupSetup36", - AddressTestAddressGroupSetup36, 1); - UtRegisterTest("AddressTestAddressGroupSetup37", - AddressTestAddressGroupSetup37, 1); - UtRegisterTest("AddressTestAddressGroupSetup38", - AddressTestAddressGroupSetup38, 1); - UtRegisterTest("AddressTestAddressGroupSetup39", - AddressTestAddressGroupSetup39, 1); - UtRegisterTest("AddressTestAddressGroupSetup40", - AddressTestAddressGroupSetup40, 1); - UtRegisterTest("AddressTestAddressGroupSetup41", - AddressTestAddressGroupSetup41, 1); - UtRegisterTest("AddressTestAddressGroupSetup42", - AddressTestAddressGroupSetup42, 1); - UtRegisterTest("AddressTestAddressGroupSetup43", - AddressTestAddressGroupSetup43, 1); - UtRegisterTest("AddressTestAddressGroupSetup44", - AddressTestAddressGroupSetup44, 1); - UtRegisterTest("AddressTestAddressGroupSetup45", - AddressTestAddressGroupSetup45, 1); - UtRegisterTest("AddressTestAddressGroupSetup46", - AddressTestAddressGroupSetup46, 1); - UtRegisterTest("AddressTestAddressGroupSetup47", - AddressTestAddressGroupSetup47, 1); - UtRegisterTest("AddressTestAddressGroupSetup48", - AddressTestAddressGroupSetup48, 1); - - UtRegisterTest("AddressTestCutIPv401", AddressTestCutIPv401, 1); - UtRegisterTest("AddressTestCutIPv402", AddressTestCutIPv402, 1); - UtRegisterTest("AddressTestCutIPv403", AddressTestCutIPv403, 1); - UtRegisterTest("AddressTestCutIPv404", AddressTestCutIPv404, 1); - UtRegisterTest("AddressTestCutIPv405", AddressTestCutIPv405, 1); - UtRegisterTest("AddressTestCutIPv406", AddressTestCutIPv406, 1); - UtRegisterTest("AddressTestCutIPv407", AddressTestCutIPv407, 1); - UtRegisterTest("AddressTestCutIPv408", AddressTestCutIPv408, 1); - UtRegisterTest("AddressTestCutIPv409", AddressTestCutIPv409, 1); - UtRegisterTest("AddressTestCutIPv410", AddressTestCutIPv410, 1); - - UtRegisterTest("AddressTestParseInvalidMask01", - AddressTestParseInvalidMask01, 1); - UtRegisterTest("AddressTestParseInvalidMask02", - AddressTestParseInvalidMask02, 1); - UtRegisterTest("AddressTestParseInvalidMask03", - AddressTestParseInvalidMask03, 1); - - UtRegisterTest("AddressConfVarsTest01 ", AddressConfVarsTest01, 1); - UtRegisterTest("AddressConfVarsTest02 ", AddressConfVarsTest02, 1); - UtRegisterTest("AddressConfVarsTest03 ", AddressConfVarsTest03, 1); - UtRegisterTest("AddressConfVarsTest04 ", AddressConfVarsTest04, 1); - UtRegisterTest("AddressConfVarsTest05 ", AddressConfVarsTest05, 1); - - UtRegisterTest("AddressTestFunctions01", AddressTestFunctions01, 1); - UtRegisterTest("AddressTestFunctions02", AddressTestFunctions02, 1); - UtRegisterTest("AddressTestFunctions03", AddressTestFunctions03, 1); - UtRegisterTest("AddressTestFunctions04", AddressTestFunctions04, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-engine-address.h b/framework/src/suricata/src/detect-engine-address.h deleted file mode 100644 index b29cff1b..00000000 --- a/framework/src/suricata/src/detect-engine-address.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ADDRESS_H__ -#define __DETECT_ADDRESS_H__ - -/* prototypes */ -void DetectAddressRegister (void); -void DetectAddressPrintMemory(void); - -DetectAddressHead *DetectAddressHeadInit(void); -void DetectAddressHeadFree(DetectAddressHead *); -void DetectAddressHeadCleanup(DetectAddressHead *); - -int DetectAddressParseString(DetectAddress *, char *); -int DetectAddressParse(const DetectEngineCtx *, DetectAddressHead *, char *); - -DetectAddress *DetectAddressInit(void); -void DetectAddressFree(DetectAddress *); - -void DetectAddressCleanupList (DetectAddress *); -int DetectAddressAdd(DetectAddress **, DetectAddress *); -void DetectAddressPrintList(DetectAddress *); - -int DetectAddressInsert(DetectEngineCtx *, DetectAddressHead *, DetectAddress *); -int DetectAddressJoin(DetectEngineCtx *, DetectAddress *, DetectAddress *); - -DetectAddress *DetectAddressLookupInHead(DetectAddressHead *, Address *); -DetectAddress *DetectAddressLookupInList(DetectAddress *, DetectAddress *); -int DetectAddressMatch(DetectAddress *, Address *); - -DetectAddress *DetectAddressCopy(DetectAddress *); -void DetectAddressPrint(DetectAddress *); -int DetectAddressCmp(DetectAddress *, DetectAddress *); - -int DetectAddressMatchIPv4(DetectMatchAddressIPv4 *, uint16_t, Address *); -int DetectAddressMatchIPv6(DetectMatchAddressIPv6 *, uint16_t, Address *); - -int DetectAddressTestConfVars(void); - -void DetectAddressTests(void); - -#endif /* __DETECT_ADDRESS_H__ */ diff --git a/framework/src/suricata/src/detect-engine-alert.c b/framework/src/suricata/src/detect-engine-alert.c deleted file mode 100644 index c2d7e420..00000000 --- a/framework/src/suricata/src/detect-engine-alert.c +++ /dev/null @@ -1,337 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" - -#include "detect.h" -#include "detect-engine-alert.h" -#include "detect-engine-threshold.h" -#include "detect-engine-tag.h" - -#include "decode.h" - -#include "flow.h" -#include "flow-private.h" - -#include "util-profiling.h" - -/** tag signature we use for tag alerts */ -static Signature g_tag_signature; -/** tag packet alert structure for tag alerts */ -static PacketAlert g_tag_pa; - -void PacketAlertTagInit(void) -{ - memset(&g_tag_signature, 0x00, sizeof(g_tag_signature)); - - g_tag_signature.id = TAG_SIG_ID; - g_tag_signature.gid = TAG_SIG_GEN; - g_tag_signature.num = TAG_SIG_ID; - g_tag_signature.rev = 1; - g_tag_signature.prio = 2; - - memset(&g_tag_pa, 0x00, sizeof(g_tag_pa)); - - g_tag_pa.action = ACTION_ALERT; - g_tag_pa.s = &g_tag_signature; -} - -PacketAlert *PacketAlertGetTag(void) -{ - return &g_tag_pa; -} - -/** - * \brief Handle a packet and check if needs a threshold logic - * Also apply rule action if necessary. - * - * \param de_ctx Detection Context - * \param sig Signature pointer - * \param p Packet structure - * - * \retval 1 alert is not suppressed - * \retval 0 alert is suppressed - */ -static int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - Signature *s, Packet *p, uint16_t pos) -{ - SCEnter(); - int ret = 1; - DetectThresholdData *td = NULL; - SigMatch *sm; - - if (!(PKT_IS_IPV4(p) || PKT_IS_IPV6(p))) { - SCReturnInt(1); - } - - /* handle suppressions first */ - if (s->sm_lists[DETECT_SM_LIST_SUPPRESS] != NULL) { - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_SUPPRESS); - sm = NULL; - do { - td = SigGetThresholdTypeIter(s, p, &sm, DETECT_SM_LIST_SUPPRESS); - if (td != NULL) { - SCLogDebug("td %p", td); - - /* PacketAlertThreshold returns 2 if the alert is suppressed but - * we do need to apply rule actions to the packet. */ - KEYWORD_PROFILING_START; - ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s); - if (ret == 0 || ret == 2) { - KEYWORD_PROFILING_END(det_ctx, DETECT_THRESHOLD, 0); - /* It doesn't match threshold, remove it */ - SCReturnInt(ret); - } - KEYWORD_PROFILING_END(det_ctx, DETECT_THRESHOLD, 1); - } - } while (sm != NULL); - } - - /* if we're still here, consider thresholding */ - if (s->sm_lists[DETECT_SM_LIST_THRESHOLD] != NULL) { - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_THRESHOLD); - sm = NULL; - do { - td = SigGetThresholdTypeIter(s, p, &sm, DETECT_SM_LIST_THRESHOLD); - if (td != NULL) { - SCLogDebug("td %p", td); - - /* PacketAlertThreshold returns 2 if the alert is suppressed but - * we do need to apply rule actions to the packet. */ - KEYWORD_PROFILING_START; - ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s); - if (ret == 0 || ret == 2) { - KEYWORD_PROFILING_END(det_ctx, DETECT_THRESHOLD ,0); - /* It doesn't match threshold, remove it */ - SCReturnInt(ret); - } - KEYWORD_PROFILING_END(det_ctx, DETECT_THRESHOLD, 1); - } - } while (sm != NULL); - } - SCReturnInt(1); -} - - -/** - * \brief Check if a certain sid alerted, this is used in the test functions - * - * \param p Packet on which we want to check if the signature alerted or not - * \param sid Signature id of the signature that thas to be checked for a match - * - * \retval match A value > 0 on a match; 0 on no match - */ -int PacketAlertCheck(Packet *p, uint32_t sid) -{ - uint16_t i = 0; - int match = 0; - - for (i = 0; i < p->alerts.cnt; i++) { - if (p->alerts.alerts[i].s == NULL) - continue; - - if (p->alerts.alerts[i].s->id == sid) - match++; - } - - return match; -} - -/** - * \brief Remove alert from the p->alerts.alerts array at pos - * \param p Pointer to the Packet - * \param pos Position in the array - * \retval 0 if the number of alerts is less than pos - * 1 if all goes well - */ -int PacketAlertRemove(Packet *p, uint16_t pos) -{ - uint16_t i = 0; - int match = 0; - - if (pos > p->alerts.cnt) { - SCLogDebug("removing %u failed, pos > cnt %u", pos, p->alerts.cnt); - return 0; - } - - for (i = pos; i <= p->alerts.cnt - 1; i++) { - memcpy(&p->alerts.alerts[i], &p->alerts.alerts[i + 1], sizeof(PacketAlert)); - } - - // Update it, since we removed 1 - p->alerts.cnt--; - - return match; -} - -/** \brief append a signature match to a packet - * - * \param det_ctx thread detection engine ctx - * \param s the signature that matched - * \param p packet - * \param flags alert flags - * \param alert_msg ptr to StreamMsg object that the signature matched on - */ -int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, Signature *s, Packet *p, uint64_t tx_id, uint8_t flags) -{ - int i = 0; - - if (p->alerts.cnt == PACKET_ALERT_MAX) - return 0; - - SCLogDebug("sid %"PRIu32"", s->id); - - /* It should be usually the last, so check it before iterating */ - if (p->alerts.cnt == 0 || (p->alerts.cnt > 0 && - p->alerts.alerts[p->alerts.cnt - 1].num < s->num)) { - /* We just add it */ - p->alerts.alerts[p->alerts.cnt].num = s->num; - p->alerts.alerts[p->alerts.cnt].action = s->action; - p->alerts.alerts[p->alerts.cnt].flags = flags; - p->alerts.alerts[p->alerts.cnt].s = s; - p->alerts.alerts[p->alerts.cnt].tx_id = tx_id; - } else { - /* We need to make room for this s->num - (a bit ugly with memcpy but we are planning changes here)*/ - for (i = p->alerts.cnt - 1; i >= 0 && p->alerts.alerts[i].num > s->num; i--) { - memcpy(&p->alerts.alerts[i + 1], &p->alerts.alerts[i], sizeof(PacketAlert)); - } - - i++; /* The right place to store the alert */ - - p->alerts.alerts[i].num = s->num; - p->alerts.alerts[i].action = s->action; - p->alerts.alerts[i].flags = flags; - p->alerts.alerts[i].s = s; - p->alerts.alerts[i].tx_id = tx_id; - } - - /* Update the count */ - p->alerts.cnt++; - - return 0; -} - -/** - * \brief Check the threshold of the sigs that match, set actions, break on pass action - * This function iterate the packet alerts array, removing those that didn't match - * the threshold, and those that match after a signature with the action "pass". - * The array is sorted by action priority/order - * \param de_ctx detection engine context - * \param det_ctx detection engine thread context - * \param p pointer to the packet - */ -void PacketAlertFinalize(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p) -{ - SCEnter(); - int i = 0; - Signature *s = NULL; - SigMatch *sm = NULL; - - while (i < p->alerts.cnt) { - SCLogDebug("Sig->num: %"PRIu16, p->alerts.alerts[i].num); - s = de_ctx->sig_array[p->alerts.alerts[i].num]; - - int res = PacketAlertHandle(de_ctx, det_ctx, s, p, i); - if (res > 0) { - /* Now, if we have an alert, we have to check if we want - * to tag this session or src/dst host */ - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_TMATCH); - sm = s->sm_lists[DETECT_SM_LIST_TMATCH]; - while (sm) { - /* tags are set only for alerts */ - KEYWORD_PROFILING_START; - sigmatch_table[sm->type].Match(NULL, det_ctx, p, s, sm->ctx); - KEYWORD_PROFILING_END(det_ctx, sm->type, 1); - sm = sm->next; - } - - if (s->flags & SIG_FLAG_IPONLY) { - if (((p->flowflags & FLOW_PKT_TOSERVER) && !(p->flowflags & FLOW_PKT_TOSERVER_IPONLY_SET)) || - ((p->flowflags & FLOW_PKT_TOCLIENT) && !(p->flowflags & FLOW_PKT_TOCLIENT_IPONLY_SET))) { - SCLogDebug("testing against \"ip-only\" signatures"); - - if (p->flow != NULL) { - /* Update flow flags for iponly */ - FLOWLOCK_WRLOCK(p->flow); - FlowSetIPOnlyFlagNoLock(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0); - - if (s->action & ACTION_DROP) - p->flow->flags |= FLOW_ACTION_DROP; - if (s->action & ACTION_REJECT) - p->flow->flags |= FLOW_ACTION_DROP; - if (s->action & ACTION_REJECT_DST) - p->flow->flags |= FLOW_ACTION_DROP; - if (s->action & ACTION_REJECT_BOTH) - p->flow->flags |= FLOW_ACTION_DROP; - if (s->action & ACTION_PASS) { - FlowSetNoPacketInspectionFlag(p->flow); - } - FLOWLOCK_UNLOCK(p->flow); - } - } - } - - /* set actions on packet */ - DetectSignatureApplyActions(p, p->alerts.alerts[i].s); - - if (PACKET_TEST_ACTION(p, ACTION_PASS)) { - /* Ok, reset the alert cnt to end in the previous of pass - * so we ignore the rest with less prio */ - p->alerts.cnt = i; - - /* if an stream/app-layer match we enforce the pass for the flow */ - if ((p->flow != NULL) && - (p->alerts.alerts[i].flags & - (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_STREAM_MATCH))) - { - FlowLockSetNoPacketInspectionFlag(p->flow); - } - break; - - /* if the signature wants to drop, check if the - * PACKET_ALERT_FLAG_DROP_FLOW flag is set. */ - } else if ((PACKET_TEST_ACTION(p, ACTION_DROP)) && - ((p->alerts.alerts[i].flags & PACKET_ALERT_FLAG_DROP_FLOW) || - (s->flags & SIG_FLAG_APPLAYER)) - && p->flow != NULL) - { - FLOWLOCK_WRLOCK(p->flow); - /* This will apply only on IPS mode (check StreamTcpPacket) */ - p->flow->flags |= FLOW_ACTION_DROP; - FLOWLOCK_UNLOCK(p->flow); - } - } - - /* Thresholding removes this alert */ - if (res == 0 || res == 2) { - PacketAlertRemove(p, i); - - if (p->alerts.cnt == 0) - break; - } else { - i++; - } - } - - /* At this point, we should have all the new alerts. Now check the tag - * keyword context for sessions and hosts */ - if (!(p->flags & PKT_PSEUDO_STREAM_END)) - TagHandlePacket(de_ctx, det_ctx, p); -} - - diff --git a/framework/src/suricata/src/detect-engine-alert.h b/framework/src/suricata/src/detect-engine-alert.h deleted file mode 100644 index 6f200b26..00000000 --- a/framework/src/suricata/src/detect-engine-alert.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_ALERT_H__ -#define __DETECT_ENGINE_ALERT_H__ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" - -void PacketAlertFinalize(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *); -int PacketAlertAppend(DetectEngineThreadCtx *, Signature *, Packet *, uint64_t tx_id, uint8_t); -int PacketAlertCheck(Packet *, uint32_t); -int PacketAlertRemove(Packet *, uint16_t); -void PacketAlertTagInit(void); -PacketAlert *PacketAlertGetTag(void); - -#endif /* __DETECT_ENGINE_ALERT_H__ */ diff --git a/framework/src/suricata/src/detect-engine-analyzer.c b/framework/src/suricata/src/detect-engine-analyzer.c deleted file mode 100644 index 066d41c6..00000000 --- a/framework/src/suricata/src/detect-engine-analyzer.c +++ /dev/null @@ -1,926 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eileen Donlon - * - * Rule analyzer for the detection engine - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-analyzer.h" -#include "detect-engine-mpm.h" -#include "conf.h" -#include "detect-content.h" -#include "detect-flow.h" -#include "detect-flags.h" -#include "util-print.h" - -static int rule_warnings_only = 0; -static FILE *rule_engine_analysis_FD = NULL; -static FILE *fp_engine_analysis_FD = NULL; -static pcre *percent_re = NULL; -static pcre_extra *percent_re_study = NULL; -static char log_path[PATH_MAX]; - -typedef struct FpPatternStats_ { - uint16_t min; - uint16_t max; - uint32_t cnt; - uint64_t tot; -} FpPatternStats; - -static FpPatternStats fp_pattern_stats[DETECT_SM_LIST_MAX]; - -static void FpPatternStatsAdd(int list, uint16_t patlen) -{ - if (list < 0 || list >= DETECT_SM_LIST_MAX) - return; - - FpPatternStats *f = &fp_pattern_stats[list]; - - if (f->min == 0) - f->min = patlen; - else if (patlen < f->min) - f->min = patlen; - - if (patlen > f->max) - f->max = patlen; - - f->cnt++; - f->tot += patlen; -} - -void EngineAnalysisFP(Signature *s, char *line) -{ - int fast_pattern_set = 0; - int fast_pattern_only_set = 0; - int fast_pattern_chop_set = 0; - DetectContentData *fp_cd = NULL; - SigMatch *mpm_sm = s->mpm_sm; - - if (mpm_sm != NULL) { - fp_cd = (DetectContentData *)mpm_sm->ctx; - if (fp_cd->flags & DETECT_CONTENT_FAST_PATTERN) { - fast_pattern_set = 1; - if (fp_cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { - fast_pattern_only_set = 1; - } else if (fp_cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) { - fast_pattern_chop_set = 1; - } - } - } - - fprintf(fp_engine_analysis_FD, "== Sid: %u ==\n", s->id); - fprintf(fp_engine_analysis_FD, "%s\n", line); - - fprintf(fp_engine_analysis_FD, " Fast Pattern analysis:\n"); - if (fp_cd == NULL) { - fprintf(fp_engine_analysis_FD, " No content present\n"); - fprintf(fp_engine_analysis_FD, "\n"); - return; - } - - fprintf(fp_engine_analysis_FD, " Fast pattern matcher: "); - int list_type = SigMatchListSMBelongsTo(s, mpm_sm); - if (list_type == DETECT_SM_LIST_PMATCH) - fprintf(fp_engine_analysis_FD, "content\n"); - else if (list_type == DETECT_SM_LIST_UMATCH) - fprintf(fp_engine_analysis_FD, "http uri content\n"); - else if (list_type == DETECT_SM_LIST_HRUDMATCH) - fprintf(fp_engine_analysis_FD, "http raw uri content\n"); - else if (list_type == DETECT_SM_LIST_HHDMATCH) - fprintf(fp_engine_analysis_FD, "http header content\n"); - else if (list_type == DETECT_SM_LIST_HRHDMATCH) - fprintf(fp_engine_analysis_FD, "http raw header content\n"); - else if (list_type == DETECT_SM_LIST_HMDMATCH) - fprintf(fp_engine_analysis_FD, "http method content\n"); - else if (list_type == DETECT_SM_LIST_HCDMATCH) - fprintf(fp_engine_analysis_FD, "http cookie content\n"); - else if (list_type == DETECT_SM_LIST_HCBDMATCH) - fprintf(fp_engine_analysis_FD, "http client body content\n"); - else if (list_type == DETECT_SM_LIST_FILEDATA) - fprintf(fp_engine_analysis_FD, "http server body content\n"); - else if (list_type == DETECT_SM_LIST_HSCDMATCH) - fprintf(fp_engine_analysis_FD, "http stat code content\n"); - else if (list_type == DETECT_SM_LIST_HSMDMATCH) - fprintf(fp_engine_analysis_FD, "http stat msg content\n"); - else if (list_type == DETECT_SM_LIST_HUADMATCH) - fprintf(fp_engine_analysis_FD, "http user agent content\n"); - - int flags_set = 0; - fprintf(fp_engine_analysis_FD, " Flags:"); - if (fp_cd->flags & DETECT_CONTENT_OFFSET) { - fprintf(fp_engine_analysis_FD, " Offset"); - flags_set = 1; - } if (fp_cd->flags & DETECT_CONTENT_DEPTH) { - fprintf(fp_engine_analysis_FD, " Depth"); - flags_set = 1; - } - if (fp_cd->flags & DETECT_CONTENT_WITHIN) { - fprintf(fp_engine_analysis_FD, " Within"); - flags_set = 1; - } - if (fp_cd->flags & DETECT_CONTENT_DISTANCE) { - fprintf(fp_engine_analysis_FD, " Distance"); - flags_set = 1; - } - if (fp_cd->flags & DETECT_CONTENT_NOCASE) { - fprintf(fp_engine_analysis_FD, " Nocase"); - flags_set = 1; - } - if (fp_cd->flags & DETECT_CONTENT_NEGATED) { - fprintf(fp_engine_analysis_FD, " Negated"); - flags_set = 1; - } - if (flags_set == 0) - fprintf(fp_engine_analysis_FD, " None"); - fprintf(fp_engine_analysis_FD, "\n"); - - fprintf(fp_engine_analysis_FD, " Fast pattern set: %s\n", fast_pattern_set ? "yes" : "no"); - fprintf(fp_engine_analysis_FD, " Fast pattern only set: %s\n", - fast_pattern_only_set ? "yes" : "no"); - fprintf(fp_engine_analysis_FD, " Fast pattern chop set: %s\n", - fast_pattern_chop_set ? "yes" : "no"); - if (fast_pattern_chop_set) { - fprintf(fp_engine_analysis_FD, " Fast pattern offset, length: %u, %u\n", - fp_cd->fp_chop_offset, fp_cd->fp_chop_len); - } - - uint16_t patlen = fp_cd->content_len; - uint8_t *pat = SCMalloc(fp_cd->content_len + 1); - if (unlikely(pat == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memcpy(pat, fp_cd->content, fp_cd->content_len); - pat[fp_cd->content_len] = '\0'; - fprintf(fp_engine_analysis_FD, " Original content: "); - PrintRawUriFp(fp_engine_analysis_FD, pat, patlen); - fprintf(fp_engine_analysis_FD, "\n"); - - if (fast_pattern_chop_set) { - SCFree(pat); - patlen = fp_cd->fp_chop_len; - pat = SCMalloc(fp_cd->fp_chop_len + 1); - if (unlikely(pat == NULL)) { - exit(EXIT_FAILURE); - } - memcpy(pat, fp_cd->content + fp_cd->fp_chop_offset, fp_cd->fp_chop_len); - pat[fp_cd->fp_chop_len] = '\0'; - fprintf(fp_engine_analysis_FD, " Final content: "); - PrintRawUriFp(fp_engine_analysis_FD, pat, patlen); - fprintf(fp_engine_analysis_FD, "\n"); - - FpPatternStatsAdd(list_type, patlen); - } else { - fprintf(fp_engine_analysis_FD, " Final content: "); - PrintRawUriFp(fp_engine_analysis_FD, pat, patlen); - fprintf(fp_engine_analysis_FD, "\n"); - - FpPatternStatsAdd(list_type, patlen); - } - SCFree(pat); - - fprintf(fp_engine_analysis_FD, "\n"); - return; -} - -/** - * \brief Sets up the fast pattern analyzer according to the config. - * - * \retval 1 If rule analyzer successfully enabled. - * \retval 0 If not enabled. - */ -int SetupFPAnalyzer(void) -{ - int fp_engine_analysis_set = 0; - - if ((ConfGetBool("engine-analysis.rules-fast-pattern", - &fp_engine_analysis_set)) == 0) { - return 0; - } - - if (fp_engine_analysis_set == 0) - return 0; - - char *log_dir; - log_dir = ConfigGetLogDirectory(); - snprintf(log_path, sizeof(log_path), "%s/%s", log_dir, - "rules_fast_pattern.txt"); - - fp_engine_analysis_FD = fopen(log_path, "w"); - if (fp_engine_analysis_FD == NULL) { - SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path, - strerror(errno)); - return 0; - } - - SCLogInfo("Engine-Analysis for fast_pattern printed to file - %s", - log_path); - - struct timeval tval; - struct tm *tms; - gettimeofday(&tval, NULL); - struct tm local_tm; - tms = SCLocalTime(tval.tv_sec, &local_tm); - fprintf(fp_engine_analysis_FD, "----------------------------------------------" - "---------------------\n"); - fprintf(fp_engine_analysis_FD, "Date: %" PRId32 "/%" PRId32 "/%04d -- " - "%02d:%02d:%02d\n", - tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour, - tms->tm_min, tms->tm_sec); - fprintf(fp_engine_analysis_FD, "----------------------------------------------" - "---------------------\n"); - - memset(&fp_pattern_stats, 0, sizeof(fp_pattern_stats)); - return 1; -} - -/** - * \brief Sets up the rule analyzer according to the config - * \retval 1 if rule analyzer successfully enabled - * \retval 0 if not enabled - */ -int SetupRuleAnalyzer(void) -{ - ConfNode *conf = ConfGetNode("engine-analysis"); - int enabled = 0; - if (conf != NULL) { - const char *value = ConfNodeLookupChildValue(conf, "rules"); - if (value && ConfValIsTrue(value)) { - enabled = 1; - } else if (value && strcasecmp(value, "warnings-only") == 0) { - enabled = 1; - rule_warnings_only = 1; - } - if (enabled) { - char *log_dir; - log_dir = ConfigGetLogDirectory(); - snprintf(log_path, sizeof(log_path), "%s/%s", log_dir, "rules_analysis.txt"); - rule_engine_analysis_FD = fopen(log_path, "w"); - if (rule_engine_analysis_FD == NULL) { - SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", log_path, strerror(errno)); - return 0; - } - - SCLogInfo("Engine-Analysis for rules printed to file - %s", - log_path); - - struct timeval tval; - struct tm *tms; - gettimeofday(&tval, NULL); - struct tm local_tm; - tms = SCLocalTime(tval.tv_sec, &local_tm); - fprintf(rule_engine_analysis_FD, "----------------------------------------------" - "---------------------\n"); - fprintf(rule_engine_analysis_FD, "Date: %" PRId32 "/%" PRId32 "/%04d -- " - "%02d:%02d:%02d\n", - tms->tm_mday, tms->tm_mon + 1, tms->tm_year + 1900, tms->tm_hour, - tms->tm_min, tms->tm_sec); - fprintf(rule_engine_analysis_FD, "----------------------------------------------" - "---------------------\n"); - - /*compile regex's for rule analysis*/ - if (PerCentEncodingSetup()== 0) { - fprintf(rule_engine_analysis_FD, "Error compiling regex; can't check for percent encoding in normalized http content.\n"); - } - } - } - else { - SCLogInfo("Conf parameter \"engine-analysis.rules\" not found. " - "Defaulting to not printing the rules analysis report."); - } - if (!enabled) { - SCLogInfo("Engine-Analysis for rules disabled in conf file."); - return 0; - } - return 1; -} - -void CleanupFPAnalyzer(void) -{ - fprintf(fp_engine_analysis_FD, "============\n" - "Summary:\n============\n"); - int i; - for (i = 0; i < DETECT_SM_LIST_MAX; i++) { - FpPatternStats *f = &fp_pattern_stats[i]; - if (f->cnt == 0) - continue; - - fprintf(fp_engine_analysis_FD, - "%s, smallest pattern %u byte(s), longest pattern %u byte(s), number of patterns %u, avg pattern len %.2f byte(s)\n", - DetectSigmatchListEnumToString(i), f->min, f->max, f->cnt, (float)((double)f->tot/(float)f->cnt)); - } - - if (fp_engine_analysis_FD != NULL) { - fclose(fp_engine_analysis_FD); - fp_engine_analysis_FD = NULL; - } - - return; -} - - -void CleanupRuleAnalyzer(void) -{ - if (rule_engine_analysis_FD != NULL) { - SCLogInfo("Engine-Analyis for rules printed to file - %s", log_path); - fclose(rule_engine_analysis_FD); - rule_engine_analysis_FD = NULL; - } -} - -/** - * \brief Compiles regex for rule analysis - * \retval 1 if successful - * \retval 0 if on error - */ -int PerCentEncodingSetup () -{ -#define DETECT_PERCENT_ENCODING_REGEX "%[0-9|a-f|A-F]{2}" - const char *eb = NULL; - int eo = 0; - int opts = 0; //PCRE_NEWLINE_ANY?? - - percent_re = pcre_compile(DETECT_PERCENT_ENCODING_REGEX, opts, &eb, &eo, NULL); - if (percent_re == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - DETECT_PERCENT_ENCODING_REGEX, eo, eb); - return 0; - } - - percent_re_study = pcre_study(percent_re, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - return 0; - } - return 1; -} - -/** - * \brief Checks for % encoding in content. - * \param Pointer to content - * \retval number of matches if content has % encoding - * \retval 0 if it doesn't have % encoding - * \retval -1 on error - */ -int PerCentEncodingMatch (uint8_t *content, uint8_t content_len) -{ -#define MAX_ENCODED_CHARS 240 - int ret = 0; - int ov[MAX_ENCODED_CHARS]; - - ret = pcre_exec(percent_re, percent_re_study, (char *)content, content_len, 0, 0, ov, MAX_ENCODED_CHARS); - if (ret == -1) { - return 0; - } - else if (ret < -1) { - SCLogError(SC_ERR_PCRE_MATCH, "Error parsing content - %s; error code is %d", content, ret); - return -1; - } - return ret; -} - -static void EngineAnalysisRulesPrintFP(Signature *s) -{ - DetectContentData *fp_cd = NULL; - SigMatch *mpm_sm = s->mpm_sm; - - if (mpm_sm != NULL) { - fp_cd = (DetectContentData *)mpm_sm->ctx; - } - - if (fp_cd == NULL) { - return; - } - - uint16_t patlen = fp_cd->content_len; - uint8_t *pat = SCMalloc(fp_cd->content_len + 1); - if (unlikely(pat == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memcpy(pat, fp_cd->content, fp_cd->content_len); - pat[fp_cd->content_len] = '\0'; - - if (fp_cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) { - SCFree(pat); - patlen = fp_cd->fp_chop_len; - pat = SCMalloc(fp_cd->fp_chop_len + 1); - if (unlikely(pat == NULL)) { - exit(EXIT_FAILURE); - } - memcpy(pat, fp_cd->content + fp_cd->fp_chop_offset, fp_cd->fp_chop_len); - pat[fp_cd->fp_chop_len] = '\0'; - fprintf(rule_engine_analysis_FD, " Fast Pattern \""); - PrintRawUriFp(rule_engine_analysis_FD, pat, patlen); - } else { - fprintf(rule_engine_analysis_FD, " Fast Pattern \""); - PrintRawUriFp(rule_engine_analysis_FD, pat, patlen); - } - SCFree(pat); - - fprintf(rule_engine_analysis_FD, "\" on \""); - - int list_type = SigMatchListSMBelongsTo(s, mpm_sm); - if (list_type == DETECT_SM_LIST_PMATCH) { - int payload = 0; - int stream = 0; - if (SignatureHasPacketContent(s)) - payload = 1; - if (SignatureHasStreamContent(s)) - stream = 1; - fprintf(rule_engine_analysis_FD, "%s", - payload ? (stream ? "payload and reassembled stream" : "payload") : "reassembled stream"); - } - else if (list_type == DETECT_SM_LIST_UMATCH) - fprintf(rule_engine_analysis_FD, "http uri content"); - else if (list_type == DETECT_SM_LIST_HRUDMATCH) - fprintf(rule_engine_analysis_FD, "http raw uri content"); - else if (list_type == DETECT_SM_LIST_HHDMATCH) - fprintf(rule_engine_analysis_FD, "http header content"); - else if (list_type == DETECT_SM_LIST_HRHDMATCH) - fprintf(rule_engine_analysis_FD, "http raw header content"); - else if (list_type == DETECT_SM_LIST_HMDMATCH) - fprintf(rule_engine_analysis_FD, "http method content"); - else if (list_type == DETECT_SM_LIST_HCDMATCH) - fprintf(rule_engine_analysis_FD, "http cookie content"); - else if (list_type == DETECT_SM_LIST_HCBDMATCH) - fprintf(rule_engine_analysis_FD, "http client body content"); - else if (list_type == DETECT_SM_LIST_FILEDATA) - fprintf(rule_engine_analysis_FD, "http server body content"); - else if (list_type == DETECT_SM_LIST_HSCDMATCH) - fprintf(rule_engine_analysis_FD, "http stat code content"); - else if (list_type == DETECT_SM_LIST_HSMDMATCH) - fprintf(rule_engine_analysis_FD, "http stat msg content"); - else if (list_type == DETECT_SM_LIST_HUADMATCH) - fprintf(rule_engine_analysis_FD, "http user agent content"); - else if (list_type == DETECT_SM_LIST_DNSQUERYNAME_MATCH) - fprintf(rule_engine_analysis_FD, "dns query name content"); - - fprintf(rule_engine_analysis_FD, "\" buffer.\n"); - - return; -} - - -void EngineAnalysisRulesFailure(char *line, char *file, int lineno) -{ - fprintf(rule_engine_analysis_FD, "== Sid: UNKNOWN ==\n"); - fprintf(rule_engine_analysis_FD, "%s\n", line); - fprintf(rule_engine_analysis_FD, " FAILURE: invalid rule.\n"); - fprintf(rule_engine_analysis_FD, " File: %s.\n", file); - fprintf(rule_engine_analysis_FD, " Line: %d.\n", lineno); - fprintf(rule_engine_analysis_FD, "\n"); -} - -/** - * \brief Prints analysis of loaded rules. - * - * Warns if potential rule issues are detected. For example, - * warns if a rule uses a construct that may perform poorly, - * e.g. pcre without content or with http_method content only; - * warns if a rule uses a construct that may not be consistent with intent, - * e.g. client side ports only, http and content without any http_* modifiers, etc. - * - * \param s Pointer to the signature. - */ -void EngineAnalysisRules(Signature *s, char *line) -{ - uint32_t rule_bidirectional = 0; - uint32_t rule_pcre = 0; - uint32_t rule_pcre_http = 0; - uint32_t rule_content = 0; - uint32_t rule_flow = 0; - uint32_t rule_flags = 0; - uint32_t rule_flow_toserver = 0; - uint32_t rule_flow_toclient = 0; - uint32_t rule_flow_nostream = 0; - uint32_t rule_ipv4_only = 0; - uint32_t rule_ipv6_only = 0; - uint32_t rule_flowbits = 0; - uint32_t rule_flowint = 0; - //uint32_t rule_flowvar = 0; - uint32_t rule_content_http = 0; - uint32_t rule_content_offset_depth = 0; - uint32_t list_id = 0; - uint32_t rule_warning = 0; - uint32_t raw_http_buf = 0; - uint32_t norm_http_buf = 0; - uint32_t stream_buf = 0; - uint32_t packet_buf = 0; - uint32_t http_header_buf = 0; - uint32_t http_uri_buf = 0; - uint32_t http_method_buf = 0; - uint32_t http_cookie_buf = 0; - uint32_t http_client_body_buf = 0; - uint32_t http_server_body_buf = 0; - uint32_t http_stat_code_buf = 0; - uint32_t http_stat_msg_buf = 0; - uint32_t http_raw_header_buf = 0; - uint32_t http_raw_uri_buf = 0; - uint32_t http_ua_buf = 0; - uint32_t warn_pcre_no_content = 0; - uint32_t warn_pcre_http_content = 0; - uint32_t warn_pcre_http = 0; - uint32_t warn_content_http_content = 0; - uint32_t warn_content_http = 0; - uint32_t warn_tcp_no_flow = 0; - uint32_t warn_client_ports = 0; - uint32_t warn_direction = 0; - uint32_t warn_method_toclient = 0; - uint32_t warn_method_serverbody = 0; - uint32_t warn_pcre_method = 0; - uint32_t warn_encoding_norm_http_buf = 0; - uint32_t warn_offset_depth_pkt_stream = 0; - uint32_t warn_offset_depth_alproto = 0; - uint32_t warn_non_alproto_fp_for_alproto_sig = 0; - - if (s->init_flags & SIG_FLAG_INIT_BIDIREC) { - rule_bidirectional = 1; - } - - if (s->flags & SIG_FLAG_REQUIRE_PACKET) { - packet_buf += 1; - } - if (s->flags & SIG_FLAG_REQUIRE_STREAM) { - stream_buf += 1; - } - - if (s->proto.flags & DETECT_PROTO_IPV4) { - rule_ipv4_only += 1; - } - if (s->proto.flags & DETECT_PROTO_IPV6) { - rule_ipv6_only += 1; - } - - for (list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) { - - SigMatch *sm = NULL; - for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) { - if (sm->type == DETECT_PCRE) { - if (list_id == DETECT_SM_LIST_HCBDMATCH) { - rule_pcre_http += 1; - http_client_body_buf += 1; - raw_http_buf += 1; - } - else if (list_id == DETECT_SM_LIST_UMATCH) { - rule_pcre_http += 1; - norm_http_buf += 1; - http_uri_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HHDMATCH) { - rule_pcre_http += 1; - norm_http_buf += 1; - http_header_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HCDMATCH) { - rule_pcre_http += 1; - norm_http_buf += 1; - http_cookie_buf += 1; - } - else if (list_id == DETECT_SM_LIST_FILEDATA) { - rule_pcre_http += 1; - http_server_body_buf += 1; - raw_http_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HRHDMATCH) { - rule_pcre_http += 1; - raw_http_buf += 1; - http_raw_header_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HMDMATCH) { - rule_pcre_http += 1; - raw_http_buf += 1; - http_method_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HRUDMATCH) { - rule_pcre_http += 1; - raw_http_buf += 1; - http_raw_uri_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HSMDMATCH) { - rule_pcre_http += 1; - raw_http_buf += 1; - http_stat_msg_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HSCDMATCH) { - rule_pcre_http += 1; - raw_http_buf += 1; - http_stat_code_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HUADMATCH) { - rule_pcre_http += 1; - norm_http_buf += 1; - http_ua_buf += 1; - } - else { - rule_pcre += 1; - } - } - else if (sm->type == DETECT_CONTENT) { - - if (list_id == DETECT_SM_LIST_UMATCH - || list_id == DETECT_SM_LIST_HHDMATCH - || list_id == DETECT_SM_LIST_HCDMATCH) { - rule_content_http += 1; - norm_http_buf += 1; - DetectContentData *cd = (DetectContentData *)sm->ctx; - if (cd != NULL && PerCentEncodingMatch(cd->content, cd->content_len) > 0) { - warn_encoding_norm_http_buf += 1; - rule_warning += 1; - } - if (list_id == DETECT_SM_LIST_UMATCH) { - http_uri_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HHDMATCH) { - http_header_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HCDMATCH) { - http_cookie_buf += 1; - } - } - else if (list_id == DETECT_SM_LIST_HCBDMATCH) { - rule_content_http += 1; - raw_http_buf += 1; - http_client_body_buf += 1; - } - else if (list_id == DETECT_SM_LIST_FILEDATA) { - rule_content_http += 1; - raw_http_buf += 1; - http_server_body_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HRHDMATCH) { - rule_content_http += 1; - raw_http_buf += 1; - http_raw_header_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HRUDMATCH) { - rule_content_http += 1; - raw_http_buf += 1; - http_raw_uri_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HSMDMATCH) { - rule_content_http += 1; - raw_http_buf += 1; - http_stat_msg_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HSCDMATCH) { - rule_content_http += 1; - raw_http_buf += 1; - http_stat_code_buf += 1; - } - else if (list_id == DETECT_SM_LIST_HMDMATCH) { - rule_content_http += 1; - raw_http_buf += 1; - http_method_buf += 1; - } - else if (list_id == DETECT_SM_LIST_PMATCH) { - rule_content += 1; - DetectContentData *cd = (DetectContentData *)sm->ctx; - if (cd->flags & - (DETECT_CONTENT_OFFSET | DETECT_CONTENT_DEPTH)) { - rule_content_offset_depth++; - } - } - } - else if (sm->type == DETECT_FLOW) { - rule_flow += 1; - if ((s->flags & SIG_FLAG_TOSERVER) && !(s->flags & SIG_FLAG_TOCLIENT)) { - rule_flow_toserver = 1; - } - else if ((s->flags & SIG_FLAG_TOCLIENT) && !(s->flags & SIG_FLAG_TOSERVER)) { - rule_flow_toclient = 1; - } - DetectFlowData *fd = (DetectFlowData *)sm->ctx; - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_NOSTREAM) - rule_flow_nostream = 1; - } - } - else if (sm->type == DETECT_FLOWBITS) { - if (list_id == DETECT_SM_LIST_MATCH) { - rule_flowbits += 1; - } - } - else if (sm->type == DETECT_FLOWINT) { - if (list_id == DETECT_SM_LIST_MATCH) { - rule_flowint += 1; - } - } - else if (sm->type == DETECT_FLAGS) { - DetectFlagsData *fd = (DetectFlagsData *)sm->ctx; - if (fd != NULL) { - rule_flags = 1; - } - } - } /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */ - - } /* for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) */ - - - if (rule_pcre > 0 && rule_content == 0 && rule_content_http == 0) { - rule_warning += 1; - warn_pcre_no_content = 1; - } - - if (rule_content_http > 0 && rule_pcre > 0 && rule_pcre_http == 0) { - rule_warning += 1; - warn_pcre_http_content = 1; - } - else if (s->alproto == ALPROTO_HTTP && rule_pcre > 0 && rule_pcre_http == 0) { - rule_warning += 1; - warn_pcre_http = 1; - } - - if (rule_content > 0 && rule_content_http > 0) { - rule_warning += 1; - warn_content_http_content = 1; - } - if (s->alproto == ALPROTO_HTTP && rule_content > 0 && rule_content_http == 0) { - rule_warning += 1; - warn_content_http = 1; - } - if (rule_content == 1) { - //todo: warning if content is weak, separate warning for pcre + weak content - } - if (rule_flow == 0 && rule_flags == 0 - && !(s->proto.flags & DETECT_PROTO_ANY) && DetectProtoContainsProto(&s->proto, IPPROTO_TCP) - && (rule_content || rule_content_http || rule_pcre || rule_pcre_http || rule_flowbits)) { - rule_warning += 1; - warn_tcp_no_flow = 1; - } - if (rule_flow && !rule_bidirectional && (rule_flow_toserver || rule_flow_toclient) - && !((s->flags & SIG_FLAG_SP_ANY) && (s->flags & SIG_FLAG_DP_ANY))) { - if (((s->flags & SIG_FLAG_TOSERVER) && !(s->flags & SIG_FLAG_SP_ANY) && (s->flags & SIG_FLAG_DP_ANY)) - || ((s->flags & SIG_FLAG_TOCLIENT) && !(s->flags & SIG_FLAG_DP_ANY) && (s->flags & SIG_FLAG_SP_ANY))) { - rule_warning += 1; - warn_client_ports = 1; - } - } - if (rule_flow && rule_bidirectional && (rule_flow_toserver || rule_flow_toclient)) { - rule_warning += 1; - warn_direction = 1; - } - if (http_method_buf) { - if (rule_flow && rule_flow_toclient) { - rule_warning += 1; - warn_method_toclient = 1; - } - if (http_server_body_buf) { - rule_warning += 1; - warn_method_serverbody = 1; - } - if (rule_content == 0 && rule_content_http == 0 && (rule_pcre > 0 || rule_pcre_http > 0)) { - rule_warning += 1; - warn_pcre_method = 1; - } - } - if (rule_content_offset_depth > 0 && stream_buf && packet_buf) { - rule_warning += 1; - warn_offset_depth_pkt_stream = 1; - } - if (rule_content_offset_depth > 0 && !stream_buf && packet_buf && s->alproto != ALPROTO_UNKNOWN) { - rule_warning += 1; - warn_offset_depth_alproto = 1; - } - if (s->mpm_sm != NULL && s->alproto == ALPROTO_HTTP && - SigMatchListSMBelongsTo(s, s->mpm_sm) == DETECT_SM_LIST_PMATCH) { - rule_warning += 1; - warn_non_alproto_fp_for_alproto_sig = 1; - } - - if (!rule_warnings_only || (rule_warnings_only && rule_warning > 0)) { - fprintf(rule_engine_analysis_FD, "== Sid: %u ==\n", s->id); - fprintf(rule_engine_analysis_FD, "%s\n", line); - - if (s->flags & SIG_FLAG_IPONLY) fprintf(rule_engine_analysis_FD, " Rule is ip only.\n"); - if (rule_ipv6_only) fprintf(rule_engine_analysis_FD, " Rule is IPv6 only.\n"); - if (rule_ipv4_only) fprintf(rule_engine_analysis_FD, " Rule is IPv4 only.\n"); - if (packet_buf) fprintf(rule_engine_analysis_FD, " Rule matches on packets.\n"); - if (!rule_flow_nostream && stream_buf && (rule_flow || rule_flowbits || rule_content || rule_pcre)) { - fprintf(rule_engine_analysis_FD, " Rule matches on reassembled stream.\n"); - } - if (http_uri_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http uri buffer.\n"); - if (http_header_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http header buffer.\n"); - if (http_cookie_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http cookie buffer.\n"); - if (http_raw_uri_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http raw uri buffer.\n"); - if (http_raw_header_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http raw header buffer.\n"); - if (http_method_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http method buffer.\n"); - if (http_server_body_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http server body buffer.\n"); - if (http_client_body_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http client body buffer.\n"); - if (http_stat_msg_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http stat msg buffer.\n"); - if (http_stat_code_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http stat code buffer.\n"); - if (http_ua_buf) fprintf(rule_engine_analysis_FD, " Rule matches on http user agent buffer.\n"); - if (s->alproto != ALPROTO_UNKNOWN) { - fprintf(rule_engine_analysis_FD, " App layer protocol is %s.\n", AppProtoToString(s->alproto)); - } - if (rule_content || rule_content_http || rule_pcre || rule_pcre_http) { - fprintf(rule_engine_analysis_FD, " Rule contains %d content options, %d http content options, %d pcre options, and %d pcre options with http modifiers.\n", rule_content, rule_content_http, rule_pcre, rule_pcre_http); - } - - /* print fast pattern info */ - EngineAnalysisRulesPrintFP(s); - - /* this is where the warnings start */ - if (warn_pcre_no_content /*rule_pcre > 0 && rule_content == 0 && rule_content_http == 0*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule uses pcre without a content option present.\n" - " -Consider adding a content to improve performance of this rule.\n"); - } - if (warn_pcre_http_content /*rule_content_http > 0 && rule_pcre > 0 && rule_pcre_http == 0*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule uses content options with http_* and pcre options without http modifiers.\n" - " -Consider adding http pcre modifier.\n"); - } - else if (warn_pcre_http /*s->alproto == ALPROTO_HTTP && rule_pcre > 0 && rule_pcre_http == 0*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule app layer protocol is http, but pcre options do not have http modifiers.\n" - " -Consider adding http pcre modifiers.\n"); - } - if (warn_content_http_content /*rule_content > 0 && rule_content_http > 0*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule contains content with http_* and content without http_*.\n" - " -Consider adding http content modifiers.\n"); - } - if (warn_content_http /*s->alproto == ALPROTO_HTTP && rule_content > 0 && rule_content_http == 0*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule app layer protocol is http, but content options do not have http_* modifiers.\n" - " -Consider adding http content modifiers.\n"); - } - if (rule_content == 1) { - //todo: warning if content is weak, separate warning for pcre + weak content - } - if (warn_encoding_norm_http_buf) { - fprintf(rule_engine_analysis_FD, " Warning: Rule may contain percent encoded content for a normalized http buffer match.\n"); - } - if (warn_tcp_no_flow /*rule_flow == 0 && rule_flow == 0 - && !(s->proto.flags & DETECT_PROTO_ANY) && DetectProtoContainsProto(&s->proto, IPPROTO_TCP)*/) { - fprintf(rule_engine_analysis_FD, " Warning: TCP rule without a flow or flags option.\n" - " -Consider adding flow or flags to improve performance of this rule.\n"); - } - if (warn_client_ports /*rule_flow && !rule_bidirectional && (rule_flow_toserver || rule_flow_toclient) - && !((s->flags & SIG_FLAG_SP_ANY) && (s->flags & SIG_FLAG_DP_ANY))) - if (((s->flags & SIG_FLAG_TOSERVER) && !(s->flags & SIG_FLAG_SP_ANY) && (s->flags & SIG_FLAG_DP_ANY)) - || ((s->flags & SIG_FLAG_TOCLIENT) && !(s->flags & SIG_FLAG_DP_ANY) && (s->flags & SIG_FLAG_SP_ANY))*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule contains ports or port variables only on the client side.\n" - " -Flow direction possibly inconsistent with rule.\n"); - } - if (warn_direction /*rule_flow && rule_bidirectional && (rule_flow_toserver || rule_flow_toclient)*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule is bidirectional and has a flow option with a specific direction.\n"); - } - if (warn_method_toclient /*http_method_buf && rule_flow && rule_flow_toclient*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule uses content or pcre for http_method with flow:to_client or from_server\n"); - } - if (warn_method_serverbody /*http_method_buf && http_server_body_buf*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule uses content or pcre for http_method with content or pcre for http_server_body.\n"); - } - if (warn_pcre_method /*http_method_buf && rule_content == 0 && rule_content_http == 0 - && (rule_pcre > 0 || rule_pcre_http > 0)*/) { - fprintf(rule_engine_analysis_FD, " Warning: Rule uses pcre with only a http_method content; possible performance issue.\n"); - } - if (warn_offset_depth_pkt_stream) { - fprintf(rule_engine_analysis_FD, " Warning: Rule has depth" - "/offset with raw content keywords. Please note the " - "offset/depth will be checked against both packet " - "payloads and stream. If you meant to have the offset/" - "depth checked against just the payload, you can update " - "the signature as \"alert tcp-pkt...\"\n"); - } - if (warn_offset_depth_alproto) { - fprintf(rule_engine_analysis_FD, " Warning: Rule has " - "offset/depth set along with a match on a specific " - "app layer protocol - %d. This can lead to FNs if we " - "have a offset/depth content match on a packet payload " - "before we can detect the app layer protocol for the " - "flow.\n", s->alproto); - } - if (warn_non_alproto_fp_for_alproto_sig) { - fprintf(rule_engine_analysis_FD, " Warning: Rule app layer " - "protocol is http, but the fast_pattern is set on the raw " - "stream. Consider adding fast_pattern over a http " - "buffer for increased performance."); - } - if (rule_warning == 0) { - fprintf(rule_engine_analysis_FD, " No warnings for this rule.\n"); - } - fprintf(rule_engine_analysis_FD, "\n"); - } - return; -} diff --git a/framework/src/suricata/src/detect-engine-analyzer.h b/framework/src/suricata/src/detect-engine-analyzer.h deleted file mode 100644 index d92b2060..00000000 --- a/framework/src/suricata/src/detect-engine-analyzer.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eileen Donlon - */ - -#ifndef __DETECT_ENGINE_ANALYZER_H__ -#define __DETECT_ENGINE_ANALYZER_H__ - -#include - -int SetupFPAnalyzer(void); -void CleanupFPAnalyzer(void); - -int SetupRuleAnalyzer(void); -void CleanupRuleAnalyzer (void); - -int PerCentEncodingSetup (); -int PerCentEncodingMatch (uint8_t *content, uint8_t content_len); - -void EngineAnalysisFP(Signature *s, char *line); -void EngineAnalysisRules(Signature *s, char *line); -void EngineAnalysisRulesFailure(char *line, char *file, int lineno); - -#endif /* __DETECT_ENGINE_ANALYZER_H__ */ diff --git a/framework/src/suricata/src/detect-engine-apt-event.c b/framework/src/suricata/src/detect-engine-apt-event.c deleted file mode 100644 index 5ca41689..00000000 --- a/framework/src/suricata/src/detect-engine-apt-event.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "app-layer-parser.h" -#include "detect-app-layer-event.h" -#include "detect-engine-state.h" -#include "stream.h" -#include "detect-engine-apt-event.h" -#include "util-profiling.h" -#include "util-unittest.h" - -int DetectEngineAptEventInspect(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id) -{ - AppLayerDecoderEvents *decoder_events = NULL; - int r = 0; - AppProto alproto; - SigMatch *sm; - DetectAppLayerEventData *aled = NULL; - - alproto = f->alproto; - decoder_events = AppLayerParserGetEventsByTx(f->proto, alproto, alstate, tx_id); - if (decoder_events == NULL) - goto end; - - for (sm = s->sm_lists[DETECT_SM_LIST_APP_EVENT]; sm != NULL; sm = sm->next) { - aled = (DetectAppLayerEventData *)sm->ctx; - KEYWORD_PROFILING_START; - if (AppLayerDecoderEventsIsEventSet(decoder_events, aled->event_id)) { - KEYWORD_PROFILING_END(det_ctx, sm->type, 1); - continue; - } - - KEYWORD_PROFILING_END(det_ctx, sm->type, 0); - goto end; - } - - r = 1; - - end: - if (r == 1) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } else { - if (AppLayerParserGetStateProgress(f->proto, alproto, tx, flags) == - AppLayerParserGetStateProgressCompletionStatus(f->proto, alproto, flags)) - { - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } else { - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } - } -} - diff --git a/framework/src/suricata/src/detect-engine-apt-event.h b/framework/src/suricata/src/detect-engine-apt-event.h deleted file mode 100644 index c264efe9..00000000 --- a/framework/src/suricata/src/detect-engine-apt-event.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_APT_EVENT__H__ -#define __DETECT_ENGINE_APT_EVENT__H__ - -int DetectEngineAptEventInspect(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -void DetectEngineAptEventRegisterTests(void); - -#endif /* __DETECT_ENGINE_APT_EVENT__H__ */ diff --git a/framework/src/suricata/src/detect-engine-content-inspection.c b/framework/src/suricata/src/detect-engine-content-inspection.c deleted file mode 100644 index 17df02ce..00000000 --- a/framework/src/suricata/src/detect-engine-content-inspection.c +++ /dev/null @@ -1,588 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Performs content inspection on any buffer supplied. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-content.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" -#include "detect-byte-extract.h" -#include "detect-replace.h" -#include "detect-engine-content-inspection.h" -#include "detect-uricontent.h" -#include "detect-urilen.h" -#include "detect-lua.h" -#include "detect-base64-decode.h" -#include "detect-base64-data.h" - -#include "app-layer-dcerpc.h" - -#include "util-spm.h" -#include "util-spm-bm.h" -#include "util-debug.h" -#include "util-print.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-profiling.h" - -#ifdef HAVE_LUA -#include "util-lua.h" -#endif - -/** - * \brief Run the actual payload match functions - * - * The following keywords are inspected: - * - content, including all the http and dce modified contents - * - isdaatat - * - pcre - * - bytejump - * - bytetest - * - byte_extract - * - urilen - * - - * - * All keywords are evaluated against the buffer with buffer_len. - * - * For accounting the last match in relative matching the - * det_ctx->buffer_offset int is used. - * - * \param de_ctx Detection engine context - * \param det_ctx Detection engine thread context - * \param s Signature to inspect - * \param sm SigMatch to inspect - * \param f Flow (for pcre flowvar storage) - * \param buffer Ptr to the buffer to inspect - * \param buffer_len Length of the payload - * \param stream_start_offset Indicates the start of the current buffer in - * the whole buffer stream inspected. This - * applies if the current buffer is inspected - * in chunks. - * \param inspection_mode Refers to the engine inspection mode we are currently - * inspecting. Can be payload, stream, one of the http - * buffer inspection modes or dce inspection mode. - * \param data Used to send some custom data. For example in - * payload inspection mode, data contains packet ptr, - * and under dce inspection mode, contains dce state. - * - * \retval 0 no match - * \retval 1 match - */ -int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - Flow *f, - uint8_t *buffer, uint32_t buffer_len, - uint32_t stream_start_offset, - uint8_t inspection_mode, void *data) -{ - SCEnter(); - KEYWORD_PROFILING_START; - - det_ctx->inspection_recursion_counter++; - - if (det_ctx->inspection_recursion_counter == de_ctx->inspection_recursion_limit) { - det_ctx->discontinue_matching = 1; - KEYWORD_PROFILING_END(det_ctx, sm->type, 0); - SCReturnInt(0); - } - - if (sm == NULL || buffer_len == 0) { - KEYWORD_PROFILING_END(det_ctx, sm->type, 0); - SCReturnInt(0); - } - - /* \todo unify this which is phase 2 of payload inspection unification */ - if (sm->type == DETECT_CONTENT) { - - DetectContentData *cd = (DetectContentData *)sm->ctx; - SCLogDebug("inspecting content %"PRIu32" buffer_len %"PRIu32, cd->id, buffer_len); - - /* we might have already have this content matched by the mpm. - * (if there is any other reason why we'd want to avoid checking - * it here, please fill it in) */ - //if (cd->flags & DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED) { - // goto match; - //} - - /* rule parsers should take care of this */ -#ifdef DEBUG - BUG_ON(cd->depth != 0 && cd->depth <= cd->offset); -#endif - - /* search for our pattern, checking the matches recursively. - * if we match we look for the next SigMatch as well */ - uint8_t *found = NULL; - uint32_t offset = 0; - uint32_t depth = buffer_len; - uint32_t prev_offset = 0; /**< used in recursive searching */ - uint32_t prev_buffer_offset = det_ctx->buffer_offset; - - do { - if ((cd->flags & DETECT_CONTENT_DISTANCE) || - (cd->flags & DETECT_CONTENT_WITHIN)) { - SCLogDebug("det_ctx->buffer_offset %"PRIu32, det_ctx->buffer_offset); - - offset = prev_buffer_offset; - depth = buffer_len; - - int distance = cd->distance; - if (cd->flags & DETECT_CONTENT_DISTANCE) { - if (cd->flags & DETECT_CONTENT_DISTANCE_BE) { - distance = det_ctx->bj_values[cd->distance]; - } - if (distance < 0 && (uint32_t)(abs(distance)) > offset) - offset = 0; - else - offset += distance; - - SCLogDebug("cd->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32, - distance, offset, depth); - } - - if (cd->flags & DETECT_CONTENT_WITHIN) { - if (cd->flags & DETECT_CONTENT_WITHIN_BE) { - if ((int32_t)depth > (int32_t)(prev_buffer_offset + det_ctx->bj_values[cd->within] + distance)) { - depth = prev_buffer_offset + det_ctx->bj_values[cd->within] + distance; - } - } else { - if ((int32_t)depth > (int32_t)(prev_buffer_offset + cd->within + distance)) { - depth = prev_buffer_offset + cd->within + distance; - } - - SCLogDebug("cd->within %"PRIi32", det_ctx->buffer_offset %"PRIu32", depth %"PRIu32, - cd->within, prev_buffer_offset, depth); - } - - if (stream_start_offset != 0 && prev_buffer_offset == 0) { - if (depth <= stream_start_offset) { - goto no_match; - } else if (depth >= (stream_start_offset + buffer_len)) { - ; - } else { - depth = depth - stream_start_offset; - } - } - } - - if (cd->flags & DETECT_CONTENT_DEPTH_BE) { - if ((det_ctx->bj_values[cd->depth] + prev_buffer_offset) < depth) { - depth = prev_buffer_offset + det_ctx->bj_values[cd->depth]; - } - } else { - if (cd->depth != 0) { - if ((cd->depth + prev_buffer_offset) < depth) { - depth = prev_buffer_offset + cd->depth; - } - - SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32, cd->depth, depth); - } - } - - if (cd->flags & DETECT_CONTENT_OFFSET_BE) { - if (det_ctx->bj_values[cd->offset] > offset) - offset = det_ctx->bj_values[cd->offset]; - } else { - if (cd->offset > offset) { - offset = cd->offset; - SCLogDebug("setting offset %"PRIu32, offset); - } - } - } else { /* implied no relative matches */ - /* set depth */ - if (cd->flags & DETECT_CONTENT_DEPTH_BE) { - depth = det_ctx->bj_values[cd->depth]; - } else { - if (cd->depth != 0) { - depth = cd->depth; - } - } - - if (stream_start_offset != 0 && cd->flags & DETECT_CONTENT_DEPTH) { - if (depth <= stream_start_offset) { - goto no_match; - } else if (depth >= (stream_start_offset + buffer_len)) { - ; - } else { - depth = depth - stream_start_offset; - } - } - - /* set offset */ - if (cd->flags & DETECT_CONTENT_OFFSET_BE) - offset = det_ctx->bj_values[cd->offset]; - else - offset = cd->offset; - prev_buffer_offset = 0; - } - - /* update offset with prev_offset if we're searching for - * matches after the first occurence. */ - SCLogDebug("offset %"PRIu32", prev_offset %"PRIu32, offset, prev_offset); - if (prev_offset != 0) - offset = prev_offset; - - SCLogDebug("offset %"PRIu32", depth %"PRIu32, offset, depth); - - if (depth > buffer_len) - depth = buffer_len; - - /* if offset is bigger than depth we can never match on a pattern. - * We can however, "match" on a negated pattern. */ - if (offset > depth || depth == 0) { - if (cd->flags & DETECT_CONTENT_NEGATED) { - goto match; - } else { - goto no_match; - } - } - - uint8_t *sbuffer = buffer + offset; - uint32_t sbuffer_len = depth - offset; - uint32_t match_offset = 0; - SCLogDebug("sbuffer_len %"PRIu32, sbuffer_len); -#ifdef DEBUG - BUG_ON(sbuffer_len > buffer_len); -#endif - - /* \todo Add another optimization here. If cd->content_len is - * greater than sbuffer_len found is anyways NULL */ - - /* do the actual search */ - if (cd->flags & DETECT_CONTENT_NOCASE) - found = BoyerMooreNocase(cd->content, cd->content_len, sbuffer, sbuffer_len, cd->bm_ctx); - else - found = BoyerMoore(cd->content, cd->content_len, sbuffer, sbuffer_len, cd->bm_ctx); - - /* next we evaluate the result in combination with the - * negation flag. */ - SCLogDebug("found %p cd negated %s", found, cd->flags & DETECT_CONTENT_NEGATED ? "true" : "false"); - - if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { - goto no_match; - } else if (found == NULL && (cd->flags & DETECT_CONTENT_NEGATED)) { - goto match; - } else if (found != NULL && (cd->flags & DETECT_CONTENT_NEGATED)) { - SCLogDebug("content %"PRIu32" matched at offset %"PRIu32", but negated so no match", cd->id, match_offset); - /* don't bother carrying recursive matches now, for preceding - * relative keywords */ - if (DETECT_CONTENT_IS_SINGLE(cd)) - det_ctx->discontinue_matching = 1; - goto no_match; - } else { - match_offset = (uint32_t)((found - buffer) + cd->content_len); - SCLogDebug("content %"PRIu32" matched at offset %"PRIu32"", cd->id, match_offset); - det_ctx->buffer_offset = match_offset; - - /* Match branch, add replace to the list if needed */ - if (cd->flags & DETECT_CONTENT_REPLACE) { - if (inspection_mode == DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD) { - /* we will need to replace content if match is confirmed */ - det_ctx->replist = DetectReplaceAddToList(det_ctx->replist, found, cd); - } else { - SCLogWarning(SC_ERR_INVALID_VALUE, "Can't modify payload without packet"); - } - } - if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - - /* bail out if we have no next match. Technically this is an - * error, as the current cd has the DETECT_CONTENT_RELATIVE_NEXT - * flag set. */ - if (sm->next == NULL) { - goto no_match; - } - - SCLogDebug("content %"PRIu32, cd->id); - KEYWORD_PROFILING_END(det_ctx, sm->type, 1); - - /* see if the next buffer keywords match. If not, we will - * search for another occurence of this content and see - * if the others match then until we run out of matches */ - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, sm->next, f, buffer, buffer_len, stream_start_offset, inspection_mode, data); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - goto no_match; - - /* set the previous match offset to the start of this match + 1 */ - prev_offset = (match_offset - (cd->content_len - 1)); - SCLogDebug("trying to see if there is another match after prev_offset %"PRIu32, prev_offset); - } - - } while(1); - - } else if (sm->type == DETECT_ISDATAAT) { - SCLogDebug("inspecting isdataat"); - - DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx; - if (id->flags & ISDATAAT_RELATIVE) { - if (det_ctx->buffer_offset + id->dataat > buffer_len) { - SCLogDebug("det_ctx->buffer_offset + id->dataat %"PRIu32" > %"PRIu32, det_ctx->buffer_offset + id->dataat, buffer_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - goto no_match; - } else { - SCLogDebug("relative isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - goto no_match; - goto match; - } - } else { - if (id->dataat < buffer_len) { - SCLogDebug("absolute isdataat match"); - if (id->flags & ISDATAAT_NEGATED) - goto no_match; - goto match; - } else { - SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", buffer_len %"PRIu32"", id->dataat, buffer_len); - if (id->flags & ISDATAAT_NEGATED) - goto match; - goto no_match; - } - } - - } else if (sm->type == DETECT_PCRE) { - SCLogDebug("inspecting pcre"); - DetectPcreData *pe = (DetectPcreData *)sm->ctx; - uint32_t prev_buffer_offset = det_ctx->buffer_offset; - uint32_t prev_offset = 0; - int r = 0; - - det_ctx->pcre_match_start_offset = 0; - do { - Packet *p = NULL; - if (inspection_mode == DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD) - p = (Packet *)data; - r = DetectPcrePayloadMatch(det_ctx, s, sm, p, f, - buffer, buffer_len); - if (r == 0) { - goto no_match; - } - - if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) { - SCLogDebug("no relative match coming up, so this is a match"); - goto match; - } - KEYWORD_PROFILING_END(det_ctx, sm->type, 1); - - /* save it, in case we need to do a pcre match once again */ - prev_offset = det_ctx->pcre_match_start_offset; - - /* see if the next payload keywords match. If not, we will - * search for another occurence of this pcre and see - * if the others match, until we run out of matches */ - r = DetectEngineContentInspection(de_ctx, det_ctx, s, sm->next, - f, buffer, buffer_len, stream_start_offset, inspection_mode, data); - if (r == 1) { - SCReturnInt(1); - } - - if (det_ctx->discontinue_matching) - goto no_match; - - det_ctx->buffer_offset = prev_buffer_offset; - det_ctx->pcre_match_start_offset = prev_offset; - } while (1); - - } else if (sm->type == DETECT_BYTETEST) { - DetectBytetestData *btd = (DetectBytetestData *)sm->ctx; - uint8_t flags = btd->flags; - int32_t offset = btd->offset; - uint64_t value = btd->value; - if (flags & DETECT_BYTETEST_OFFSET_BE) { - offset = det_ctx->bj_values[offset]; - } - if (flags & DETECT_BYTETEST_VALUE_BE) { - value = det_ctx->bj_values[value]; - } - - /* if we have dce enabled we will have to use the endianness - * specified by the dce header */ - if (flags & DETECT_BYTETEST_DCE) { - DCERPCState *dcerpc_state = (DCERPCState *)data; - /* enable the endianness flag temporarily. once we are done - * processing we reset the flags to the original value*/ - flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ? - DETECT_BYTETEST_LITTLE: 0); - } - - if (DetectBytetestDoMatch(det_ctx, s, sm->ctx, buffer, buffer_len, flags, - offset, value) != 1) { - goto no_match; - } - - goto match; - - } else if (sm->type == DETECT_BYTEJUMP) { - DetectBytejumpData *bjd = (DetectBytejumpData *)sm->ctx; - uint8_t flags = bjd->flags; - int32_t offset = bjd->offset; - - if (flags & DETECT_BYTEJUMP_OFFSET_BE) { - offset = det_ctx->bj_values[offset]; - } - - /* if we have dce enabled we will have to use the endianness - * specified by the dce header */ - if (flags & DETECT_BYTEJUMP_DCE) { - DCERPCState *dcerpc_state = (DCERPCState *)data; - /* enable the endianness flag temporarily. once we are done - * processing we reset the flags to the original value*/ - flags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ? - DETECT_BYTEJUMP_LITTLE: 0); - } - - if (DetectBytejumpDoMatch(det_ctx, s, sm->ctx, buffer, buffer_len, - flags, offset) != 1) { - goto no_match; - } - - goto match; - - } else if (sm->type == DETECT_BYTE_EXTRACT) { - - DetectByteExtractData *bed = (DetectByteExtractData *)sm->ctx; - uint8_t endian = bed->endian; - - /* if we have dce enabled we will have to use the endianness - * specified by the dce header */ - if ((bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN) && - endian == DETECT_BYTE_EXTRACT_ENDIAN_DCE) { - - DCERPCState *dcerpc_state = (DCERPCState *)data; - /* enable the endianness flag temporarily. once we are done - * processing we reset the flags to the original value*/ - endian |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] == 0x10) ? - DETECT_BYTE_EXTRACT_ENDIAN_LITTLE : DETECT_BYTE_EXTRACT_ENDIAN_BIG); - } - - if (DetectByteExtractDoMatch(det_ctx, sm, s, buffer, - buffer_len, - &det_ctx->bj_values[bed->local_id], - endian) != 1) { - goto no_match; - } - - goto match; - - /* we should never get here, but bail out just in case */ - } else if (sm->type == DETECT_AL_URILEN) { - SCLogDebug("inspecting uri len"); - - int r = 0; - DetectUrilenData *urilend = (DetectUrilenData *) sm->ctx; - - switch (urilend->mode) { - case DETECT_URILEN_EQ: - if (buffer_len == urilend->urilen1) - r = 1; - break; - case DETECT_URILEN_LT: - if (buffer_len < urilend->urilen1) - r = 1; - break; - case DETECT_URILEN_GT: - if (buffer_len > urilend->urilen1) - r = 1; - break; - case DETECT_URILEN_RA: - if (buffer_len > urilend->urilen1 && - buffer_len < urilend->urilen2) { - r = 1; - } - break; - } - - if (r == 1) { - goto match; - } - - det_ctx->discontinue_matching = 0; - - goto no_match; -#ifdef HAVE_LUA - } - else if (sm->type == DETECT_LUA) { - SCLogDebug("lua starting"); - /* for flowvar gets and sets we need to know the flow's lock status */ - int flow_lock = LUA_FLOW_LOCKED_BY_PARENT; - if (inspection_mode <= DETECT_ENGINE_CONTENT_INSPECTION_MODE_STREAM) - flow_lock = LUA_FLOW_NOT_LOCKED_BY_PARENT; - - if (DetectLuaMatchBuffer(det_ctx, s, sm, buffer, buffer_len, - det_ctx->buffer_offset, f, flow_lock) != 1) - { - SCLogDebug("lua no_match"); - goto no_match; - } - SCLogDebug("lua match"); - goto match; -#endif /* HAVE_LUA */ - } else if (sm->type == DETECT_BASE64_DECODE) { - if (DetectBase64DecodeDoMatch(det_ctx, s, sm, buffer, buffer_len)) { - if (s->sm_arrays[DETECT_SM_LIST_BASE64_DATA] != NULL) { - KEYWORD_PROFILING_END(det_ctx, sm->type, 1); - if (DetectBase64DataDoMatch(de_ctx, det_ctx, s, f)) { - /* Base64 is a terminal list. */ - goto final_match; - } - } - } - } else { - SCLogDebug("sm->type %u", sm->type); -#ifdef DEBUG - BUG_ON(1); -#endif - } - -no_match: - KEYWORD_PROFILING_END(det_ctx, sm->type, 0); - SCReturnInt(0); - -match: - /* this sigmatch matched, inspect the next one. If it was the last, - * the buffer portion of the signature matched. */ - if (sm->next != NULL) { - KEYWORD_PROFILING_END(det_ctx, sm->type, 1); - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, sm->next, f, buffer, buffer_len, stream_start_offset, inspection_mode, data); - SCReturnInt(r); - } -final_match: - KEYWORD_PROFILING_END(det_ctx, sm->type, 1); - SCReturnInt(1); -} diff --git a/framework/src/suricata/src/detect-engine-content-inspection.h b/framework/src/suricata/src/detect-engine-content-inspection.h deleted file mode 100644 index 5e80b9b8..00000000 --- a/framework/src/suricata/src/detect-engine-content-inspection.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_CONTENT_INSPECTION_H__ -#define __DETECT_ENGINE_CONTENT_INSPECTION_H__ - -/** \warning make sure to add new entries to the proper position - * wrt flow lock status - */ -enum { - /* called with flow unlocked */ - DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD = 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_STREAM, - - /* called with flow locked */ - DETECT_ENGINE_CONTENT_INSPECTION_MODE_DCE, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_URI, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRL, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRUD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HHD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HCBD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSBD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HCD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HMD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSCD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSMD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HUAD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HHHD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHHD, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_DNSQUERY, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_FD_SMTP, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_BASE64, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_TEMPLATE_BUFFER, -}; - -int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - Signature *s, SigMatch *sm, - Flow *f, - uint8_t *buffer, uint32_t buffer_len, - uint32_t stream_start_offset, - uint8_t inspection_mode, void *data); - -#endif /* __DETECT_ENGINE_CONTENT_INSPECTION_H__ */ diff --git a/framework/src/suricata/src/detect-engine-dcepayload.c b/framework/src/suricata/src/detect-engine-dcepayload.c deleted file mode 100644 index c2f7610e..00000000 --- a/framework/src/suricata/src/detect-engine-dcepayload.c +++ /dev/null @@ -1,10192 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-pcre.h" -#include "detect-isdataat.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" -#include "detect-byte-extract.h" -#include "detect-content.h" -#include "detect-engine-content-inspection.h" - -#include "stream-tcp.h" - -#include "app-layer.h" -#include "app-layer-dcerpc.h" -#include "flow-util.h" -#include "util-debug.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -/** - * \brief Do the content inspection & validation for a signature against dce stub. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param sm SigMatch to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectDcePayload(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Signature *s, - Flow *f, uint8_t flags, void *alstate) -{ - SCEnter(); - DCERPCState *dcerpc_state = (DCERPCState *)alstate; - uint8_t *dce_stub_data = NULL; - uint16_t dce_stub_data_len; - int r = 0; - - if (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL || dcerpc_state == NULL) { - SCReturnInt(0); - } - - if (dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcrequest.stub_data_fresh != 0) { - /* the request stub and stub_len */ - dce_stub_data = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer; - dce_stub_data_len = dcerpc_state->dcerpc.dcerpcrequest.stub_data_buffer_len; - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - - r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_DMATCH], - f, - dce_stub_data, - dce_stub_data_len, - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_DCE, dcerpc_state); - //r = DoInspectDcePayload(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_DMATCH], f, - //dce_stub_data, dce_stub_data_len, dcerpc_state); - if (r == 1) { - SCReturnInt(1); - } - } - - if (dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer != NULL && - dcerpc_state->dcerpc.dcerpcresponse.stub_data_fresh == 0) { - /* the response stub and stub_len */ - dce_stub_data = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer; - dce_stub_data_len = dcerpc_state->dcerpc.dcerpcresponse.stub_data_buffer_len; - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - - r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_DMATCH], - f, - dce_stub_data, - dce_stub_data_len, - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_DCE, dcerpc_state); - //r = DoInspectDcePayload(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_DMATCH], f, - //dce_stub_data, dce_stub_data_len, dcerpc_state); - if (r == 1) { - SCReturnInt(1); - } - } - - SCReturnInt(0); -} - -/**************************************Unittests*******************************/ - -#ifdef UNITTESTS - -/** - * \test Test the working of detection engien with respect to dce keywords. - */ -int DcePayloadTest01(void) -{ -#if 0 - int result = 0; - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x48, 0x1a, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - uint8_t request3[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x26, 0x65, 0x3c, 0x6e, 0x6d, 0x64, 0x24, 0x39, - 0x56, 0x43, 0x3e, 0x61, 0x5c, 0x54, 0x42, 0x23, - 0x75, 0x6b, 0x71, 0x27, 0x66, 0x2e, 0x6e, 0x3d, - 0x58, 0x23, 0x54, 0x77, 0x3b, 0x52, 0x6b, 0x50, - 0x3b, 0x74, 0x2c, 0x54, 0x25, 0x5c, 0x51, 0x7c, - 0x29, 0x7c, 0x5f, 0x4a, 0x35, 0x5c, 0x3d, 0x3f, - 0x33, 0x55, 0x3b, 0x5a, 0x57, 0x31, 0x59, 0x4f, - 0x6d, 0x6d, 0x7b, 0x3e, 0x38, 0x4d, 0x68, 0x75, - 0x64, 0x21, 0x50, 0x63, 0x47, 0x42, 0x56, 0x39, - 0x6c, 0x6f, 0x61, 0x53, 0x32, 0x56, 0x43, 0x52, - 0x43, 0x67, 0x26, 0x45, 0x28, 0x6b, 0x77, 0x28, - 0x7c, 0x64, 0x61, 0x24, 0x38, 0x6b, 0x59, 0x2a, - 0x4f, 0x6e, 0x5b, 0x57, 0x24, 0x54, 0x33, 0x37, - 0x47, 0x58, 0x4b, 0x58, 0x3d, 0x21, 0x38, 0x7c, - 0x2c, 0x24, 0x5f, 0x67, 0x3a, 0x41, 0x3e, 0x2a, - 0x72, 0x66, 0x2d, 0x6b, 0x66, 0x7b, 0x2b, 0x75, - 0x78, 0x2f, 0x4d, 0x4c, 0x51, 0x70, 0x5d, 0x55, - 0x54, 0x3c, 0x63, 0x46, 0x6b, 0x64, 0x4d, 0x25, - 0x45, 0x21, 0x34, 0x65, 0x48, 0x32, 0x58, 0x4c, - 0x70, 0x4c, 0x4c, 0x75, 0x5c, 0x77, 0x68, 0x78, - 0x34, 0x5c, 0x2d, 0x39, 0x58, 0x3b, 0x40, 0x71, - 0x77, 0x47, 0x32, 0x2e, 0x3c, 0x61, 0x6f, 0x6d, - 0x5f, 0x43, 0x74, 0x36, 0x4f, 0x21, 0x44, 0x66, - 0x36, 0x62, 0x30, 0x29, 0x5a, 0x34, 0x66, 0x4e, - 0x51, 0x23, 0x4e, 0x38, 0x51, 0x78, 0x74, 0x58, - 0x2e, 0x6d, 0x51, 0x49, 0x55, 0x73, 0x2a, 0x71, - 0x3c, 0x74, 0x38, 0x6f, 0x5d, 0x4b, 0x74, 0x68, - 0x65, 0x4a, 0x58, 0x41, 0x55, 0x29, 0x42, 0x69, - 0x55, 0x3b, 0x2b, 0x47, 0x64, 0x3b, 0x77, 0x72, - 0x74, 0x38, 0x53, 0x5c, 0x69, 0x49, 0x49, 0x5b, - 0x31, 0x41, 0x6a, 0x4e, 0x2c, 0x6a, 0x63, 0x3f, - 0x58, 0x4e, 0x25, 0x3e, 0x57, 0x41, 0x61, 0x26, - 0x5e, 0x24, 0x69, 0x7a, 0x38, 0x60, 0x73, 0x70, - 0x7d, 0x63, 0x34, 0x78, 0x4d, 0x50, 0x35, 0x69, - 0x49, 0x22, 0x45, 0x44, 0x3f, 0x6e, 0x75, 0x64, - 0x57, 0x3a, 0x61, 0x60, 0x34, 0x21, 0x61, 0x21, - 0x2a, 0x78, 0x7b, 0x52, 0x43, 0x50, 0x5b, 0x76, - 0x5f, 0x4b, 0x6a, 0x5d, 0x23, 0x5b, 0x57, 0x40, - 0x53, 0x51, 0x33, 0x21, 0x35, 0x7d, 0x31, 0x46, - 0x65, 0x52, 0x28, 0x25, 0x30, 0x5a, 0x37, 0x7c, - 0x2c, 0x3d, 0x2a, 0x48, 0x24, 0x5a, 0x2f, 0x47, - 0x64, 0x73, 0x64, 0x3d, 0x7a, 0x5b, 0x34, 0x5e, - 0x42, 0x22, 0x32, 0x47, 0x6e, 0x58, 0x3b, 0x3e, - 0x25, 0x2f, 0x58, 0x78, 0x42, 0x66, 0x71, 0x56, - 0x2a, 0x66, 0x66, 0x5b, 0x55, 0x35, 0x7a, 0x41, - 0x7c, 0x7c, 0x6a, 0x2d, 0x59, 0x25, 0x22, 0x34, - 0x5a, 0x61, 0x37, 0x48, 0x39, 0x31, 0x4a, 0x55, - 0x6a, 0x68, 0x40, 0x2f, 0x45, 0x69, 0x46, 0x25, - 0x51, 0x7d, 0x4f, 0x71, 0x21, 0x33, 0x55, 0x50, - 0x56, 0x5f, 0x75, 0x27, 0x64, 0x36, 0x7a, 0x39, - 0x40, 0x6a, 0x77, 0x38, 0x5d, 0x39, 0x30, 0x5e, - 0x74, 0x54, 0x24, 0x3f, 0x3d, 0x79, 0x3b, 0x27, - 0x7d, 0x68, 0x7d, 0x40, 0x71, 0x7a, 0x65, 0x54, - 0x50, 0x66, 0x33, 0x3c, 0x42, 0x69, 0x6e, 0x3c, - 0x63, 0x63, 0x69, 0x7a, 0x5e, 0x7b, 0x76, 0x26, - 0x71, 0x6f, 0x4a, 0x6d, 0x70, 0x73, 0x66, 0x3b, - 0x26, 0x70, 0x43, 0x5b, 0x52, 0x4c, 0x6d, 0x51, - 0x2a, 0x66, 0x6c, 0x3e, 0x68, 0x6a, 0x31, 0x41, - 0x79, 0x72, 0x37, 0x47, 0x7d, 0x2b, 0x3c, 0x40, - 0x6b, 0x75, 0x56, 0x70, 0x7b, 0x2d, 0x5f, 0x33, - 0x30, 0x30, 0x21, 0x35, 0x7a, 0x7a, 0x67, 0x48, - 0x5e, 0x3b, 0x73, 0x50, 0x54, 0x47, 0x23, 0x2b, - 0x4c, 0x4e, 0x2f, 0x24, 0x44, 0x34, 0x23, 0x5d, - 0x76, 0x51, 0x5a, 0x73, 0x72, 0x3e, 0x47, 0x77, - 0x40, 0x28, 0x65, 0x2e, 0x2a, 0x75, 0x3c, 0x2a, - 0x27, 0x4a, 0x3f, 0x3c, 0x66, 0x2d, 0x21, 0x79, - 0x2d, 0x2b, 0x78, 0x7c, 0x5a, 0x73, 0x46, 0x6b, - 0x39, 0x65, 0x5e, 0x3d, 0x38, 0x40, 0x32, 0x3e, - 0x21, 0x62, 0x34, 0x41, 0x58, 0x53, 0x67, 0x34, - 0x58, 0x56, 0x61, 0x5b, 0x3e, 0x4e, 0x2c, 0x5b, - 0x73, 0x35, 0x34, 0x35, 0x21, 0x3a, 0x61, 0x5f, - 0x6e, 0x45, 0x78, 0x44, 0x28, 0x23, 0x48, 0x65, - 0x53, 0x47, 0x6e, 0x2c, 0x38, 0x5e, 0x2c, 0x57, - 0x58, 0x30, 0x7a, 0x3b, 0x4b, 0x4a, 0x74, 0x7d, - 0x3e, 0x4d, 0x30, 0x24, 0x76, 0x66, 0x6d, 0x2e, - 0x74, 0x75, 0x28, 0x48, 0x5c, 0x23, 0x6c, 0x46, - 0x27, 0x46, 0x6e, 0x34, 0x63, 0x21, 0x58, 0x54, - 0x50, 0x2f, 0x40, 0x47, 0x40, 0x32, 0x36, 0x48, - 0x5f, 0x7d, 0x4a, 0x41, 0x6e, 0x60, 0x2c, 0x4a, - 0x6a, 0x67, 0x6c, 0x41, 0x27, 0x23, 0x30, 0x48, - 0x6a, 0x49, 0x73, 0x26, 0x77, 0x75, 0x4d, 0x65, - 0x5b, 0x34, 0x79, 0x67, 0x61, 0x5b, 0x5c, 0x2b, - 0x71, 0x3f, 0x62, 0x51, 0x3a, 0x53, 0x42, 0x26, - 0x6f, 0x36, 0x57, 0x3f, 0x2b, 0x34, 0x24, 0x30, - 0x60, 0x55, 0x70, 0x65, 0x70, 0x57, 0x5d, 0x68, - 0x36, 0x52, 0x5d, 0x3f, 0x6a, 0x3a, 0x33, 0x31, - 0x6c, 0x4e, 0x57, 0x79, 0x49, 0x79, 0x69, 0x71, - 0x6f, 0x70, 0x6a, 0x76, 0x4b, 0x2f, 0x33, 0x51, - 0x68, 0x30, 0x2e, 0x77, 0x78, 0x55, 0x2f, 0x53, - 0x52, 0x5e, 0x57, 0x60, 0x3b, 0x6f, 0x69, 0x61, - 0x6c, 0x60, 0x5a, 0x34, 0x5a, 0x35, 0x4b, 0x28, - 0x54, 0x32, 0x6a, 0x35, 0x36, 0x6d, 0x68, 0x47, - 0x5c, 0x74, 0x2e, 0x5f, 0x6c, 0x6d, 0x55, 0x42, - 0x77, 0x64, 0x7d, 0x53, 0x4d, 0x39, 0x2c, 0x41, - 0x42, 0x23, 0x3a, 0x73, 0x40, 0x60, 0x5d, 0x38, - 0x6d, 0x36, 0x56, 0x57, 0x2a, 0x28, 0x3d, 0x3b, - 0x5c, 0x75, 0x35, 0x2d, 0x69, 0x2d, 0x44, 0x51, - 0x27, 0x63, 0x66, 0x33, 0x46, 0x42, 0x2e, 0x36, - 0x6b, 0x7b, 0x2c, 0x23, 0x3b, 0x5a, 0x50, 0x2a, - 0x65, 0x28, 0x3b, 0x3c, 0x51, 0x3f, 0x4d, 0x63, - 0x38, 0x25, 0x74, 0x2e, 0x51, 0x22, 0x31, 0x74, - 0x35, 0x33, 0x23, 0x2d, 0x3f, 0x77, 0x26, 0x2c, - 0x55, 0x6d, 0x27, 0x39, 0x79, 0x76, 0x63, 0x4b, - 0x43, 0x4a, 0x3a, 0x6b, 0x59, 0x55, 0x65, 0x26, - 0x2f, 0x3f, 0x56, 0x67, 0x5a, 0x77, 0x71, 0x22, - 0x51, 0x2b, 0x6d, 0x4c, 0x2c, 0x57, 0x66, 0x76, - 0x37, 0x70, 0x5f, 0x52, 0x29, 0x44, 0x52, 0x22, - 0x57, 0x37, 0x27, 0x79, 0x29, 0x5c, 0x57, 0x3b, - 0x54, 0x3c, 0x3f, 0x53, 0x35, 0x27, 0x5e, 0x7c, - 0x49, 0x77, 0x57, 0x5a, 0x22, 0x76, 0x7c, 0x5b, - 0x2f, 0x53, 0x5e, 0x55, 0x6d, 0x64, 0x67, 0x34, - 0x41, 0x23, 0x76, 0x67, 0x23, 0x78, 0x6a, 0x63, - 0x27, 0x68, 0x43, 0x7d, 0x58, 0x49, 0x2d, 0x79, - 0x2e, 0x75, 0x60, 0x6b, 0x34, 0x48, 0x6f, 0x4a, - 0x6c, 0x48, 0x40, 0x68, 0x5f, 0x35, 0x25, 0x6c, - 0x38, 0x5c, 0x30, 0x32, 0x4c, 0x36, 0x31, 0x29, - 0x74, 0x4a, 0x55, 0x56, 0x6d, 0x4e, 0x23, 0x54, - 0x2e, 0x69, 0x78, 0x61, 0x76, 0x66, 0x22, 0x44, - 0x73, 0x25, 0x44, 0x29, 0x2a, 0x28, 0x3b, 0x67, - 0x48, 0x58, 0x37, 0x4a, 0x76, 0x76, 0x51, 0x4a, - 0x61, 0x70, 0x51, 0x74, 0x40, 0x23, 0x29, 0x63, - 0x69, 0x4a, 0x29, 0x23, 0x34, 0x6a, 0x3b, 0x25, - 0x28, 0x54, 0x45, 0x33, 0x28, 0x44, 0x30, 0x61, - 0x5b, 0x60, 0x51, 0x3f, 0x68, 0x50, 0x70, 0x3d, - 0x58, 0x2e, 0x6e, 0x59, 0x5a, 0x62, 0x66, 0x4d, - 0x7a, 0x2e, 0x37, 0x37, 0x3d, 0x7b, 0x74, 0x79, - 0x48, 0x45, 0x77, 0x56, 0x33, 0x76, 0x71, 0x60, - 0x74, 0x3f, 0x61, 0x22, 0x52, 0x51, 0x71, 0x69 - }; - uint32_t request3_len = sizeof(request3); - - uint8_t request4[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x75, 0x3e, 0x76, 0x3e, 0x66, 0x6b, 0x6b, 0x3e, - 0x6d, 0x59, 0x38, 0x2b, 0x63, 0x4d, 0x2c, 0x73, - 0x54, 0x57, 0x34, 0x25, 0x5b, 0x42, 0x7d, 0x5d, - 0x37, 0x34, 0x2c, 0x79, 0x24, 0x4b, 0x74, 0x73, - 0x25, 0x36, 0x73, 0x3a, 0x2c, 0x55, 0x69, 0x3c, - 0x58, 0x67, 0x33, 0x53, 0x67, 0x5c, 0x61, 0x7b, - 0x44, 0x2e, 0x42, 0x2d, 0x6b, 0x50, 0x55, 0x24, - 0x70, 0x58, 0x60, 0x38, 0x42, 0x45, 0x70, 0x6d, - 0x2f, 0x27, 0x27, 0x2c, 0x21, 0x6d, 0x57, 0x6e, - 0x43, 0x3c, 0x5b, 0x27, 0x7a, 0x34, 0x49, 0x5a, - 0x69, 0x30, 0x3f, 0x6f, 0x77, 0x70, 0x39, 0x2d, - 0x51, 0x74, 0x4b, 0x25, 0x70, 0x51, 0x64, 0x4d, - 0x75, 0x52, 0x5e, 0x3e, 0x37, 0x30, 0x5d, 0x3b, - 0x2c, 0x72, 0x25, 0x6c, 0x6f, 0x79, 0x69, 0x3c, - 0x5b, 0x73, 0x3d, 0x41, 0x28, 0x28, 0x64, 0x60, - 0x4b, 0x7a, 0x2c, 0x4a, 0x6b, 0x3d, 0x2e, 0x6c, - 0x7a, 0x54, 0x70, 0x61, 0x6f, 0x4b, 0x40, 0x28, - 0x59, 0x31, 0x25, 0x21, 0x57, 0x79, 0x4b, 0x31, - 0x6f, 0x4e, 0x71, 0x2b, 0x3c, 0x24, 0x30, 0x28, - 0x3c, 0x61, 0x28, 0x4b, 0x35, 0x61, 0x4d, 0x55, - 0x5e, 0x66, 0x34, 0x5f, 0x61, 0x70, 0x7b, 0x67, - 0x51, 0x55, 0x68, 0x78, 0x26, 0x3a, 0x27, 0x4e, - 0x71, 0x79, 0x4f, 0x67, 0x2c, 0x5a, 0x79, 0x75, - 0x59, 0x3a, 0x33, 0x4a, 0x36, 0x71, 0x72, 0x6d, - 0x49, 0x3e, 0x53, 0x59, 0x2b, 0x2b, 0x27, 0x4e, - 0x50, 0x5d, 0x21, 0x55, 0x64, 0x4b, 0x72, 0x73, - 0x25, 0x55, 0x26, 0x4f, 0x3a, 0x21, 0x54, 0x29, - 0x4f, 0x64, 0x51, 0x59, 0x60, 0x7b, 0x7c, 0x6f, - 0x3e, 0x65, 0x74, 0x6a, 0x5b, 0x52, 0x2c, 0x56, - 0x4e, 0x45, 0x53, 0x4b, 0x7c, 0x38, 0x49, 0x4b, - 0x4e, 0x4f, 0x4a, 0x47, 0x5e, 0x7c, 0x46, 0x3b, - 0x67, 0x2e, 0x43, 0x79, 0x35, 0x55, 0x59, 0x6d, - 0x38, 0x70, 0x2f, 0x59, 0x4f, 0x27, 0x63, 0x40, - 0x66, 0x2d, 0x39, 0x4f, 0x3d, 0x2e, 0x4c, 0x67, - 0x71, 0x7d, 0x34, 0x22, 0x52, 0x4e, 0x36, 0x7b, - 0x2c, 0x39, 0x4d, 0x42, 0x60, 0x75, 0x74, 0x72, - 0x4f, 0x72, 0x68, 0x3a, 0x51, 0x31, 0x2d, 0x21, - 0x4a, 0x35, 0x47, 0x6d, 0x69, 0x3c, 0x50, 0x4c, - 0x59, 0x66, 0x4c, 0x71, 0x24, 0x3a, 0x36, 0x67, - 0x24, 0x5a, 0x59, 0x28, 0x7c, 0x21, 0x5e, 0x77, - 0x68, 0x5e, 0x7b, 0x6e, 0x56, 0x62, 0x36, 0x29, - 0x6f, 0x4f, 0x5d, 0x57, 0x56, 0x2b, 0x75, 0x2a, - 0x2c, 0x69, 0x63, 0x51, 0x74, 0x6e, 0x5e, 0x46, - 0x50, 0x28, 0x2c, 0x3b, 0x32, 0x53, 0x28, 0x78, - 0x59, 0x72, 0x39, 0x5e, 0x44, 0x5c, 0x77, 0x60, - 0x72, 0x44, 0x3b, 0x75, 0x68, 0x39, 0x55, 0x3e, - 0x44, 0x50, 0x76, 0x3c, 0x48, 0x46, 0x43, 0x22, - 0x56, 0x27, 0x21, 0x31, 0x33, 0x4a, 0x5a, 0x74, - 0x41, 0x58, 0x3f, 0x39, 0x29, 0x71, 0x73, 0x30, - 0x57, 0x70, 0x33, 0x62, 0x7b, 0x4a, 0x75, 0x3e, - 0x4d, 0x4c, 0x4e, 0x55, 0x63, 0x38, 0x66, 0x7d, - 0x68, 0x7d, 0x6f, 0x23, 0x55, 0x50, 0x3d, 0x34, - 0x46, 0x5e, 0x2f, 0x55, 0x27, 0x62, 0x68, 0x7c, - 0x6c, 0x21, 0x2b, 0x63, 0x4b, 0x47, 0x6b, 0x6a, - 0x5b, 0x7b, 0x5c, 0x71, 0x37, 0x7c, 0x52, 0x2b, - 0x2f, 0x4a, 0x47, 0x70, 0x78, 0x50, 0x2f, 0x75, - 0x28, 0x4c, 0x60, 0x4c, 0x4c, 0x54, 0x6b, 0x68, - 0x63, 0x4f, 0x47, 0x39, 0x2a, 0x70, 0x51, 0x7d, - 0x28, 0x59, 0x52, 0x46, 0x4b, 0x38, 0x27, 0x49, - 0x50, 0x5d, 0x25, 0x22, 0x5f, 0x48, 0x2c, 0x2f, - 0x67, 0x59, 0x5d, 0x7d, 0x21, 0x3d, 0x72, 0x4f, - 0x5c, 0x5b, 0x41, 0x47, 0x5f, 0x56, 0x69, 0x42, - 0x55, 0x60, 0x68, 0x4b, 0x77, 0x44, 0x4c, 0x3b, - 0x7d, 0x5a, 0x58, 0x43, 0x7a, 0x33, 0x22, 0x58, - 0x58, 0x6f, 0x74, 0x53, 0x57, 0x6d, 0x6e, 0x29, - 0x6b, 0x33, 0x71, 0x68, 0x29, 0x48, 0x67, 0x35, - 0x52, 0x41, 0x6b, 0x36, 0x4f, 0x46, 0x31, 0x24, - 0x73, 0x56, 0x40, 0x48, 0x37, 0x51, 0x24, 0x2a, - 0x59, 0x21, 0x74, 0x76, 0x25, 0x2e, 0x4a, 0x74, - 0x32, 0x29, 0x5f, 0x57, 0x7c, 0x58, 0x30, 0x2c, - 0x7b, 0x70, 0x5b, 0x51, 0x73, 0x27, 0x4a, 0x28, - 0x77, 0x2a, 0x43, 0x28, 0x2e, 0x32, 0x3d, 0x38, - 0x36, 0x2e, 0x6b, 0x40, 0x6c, 0x76, 0x54, 0x66, - 0x4a, 0x5c, 0x25, 0x62, 0x2e, 0x61, 0x48, 0x30, - 0x28, 0x41, 0x40, 0x69, 0x3c, 0x39, 0x36, 0x4b, - 0x64, 0x50, 0x76, 0x3d, 0x52, 0x50, 0x77, 0x33, - 0x3b, 0x65, 0x59, 0x31, 0x5c, 0x48, 0x6a, 0x74, - 0x78, 0x5b, 0x74, 0x60, 0x47, 0x27, 0x60, 0x22, - 0x4a, 0x72, 0x25, 0x34, 0x5d, 0x3a, 0x21, 0x66, - 0x61, 0x7b, 0x34, 0x41, 0x3b, 0x3a, 0x27, 0x44, - 0x48, 0x7c, 0x7a, 0x74, 0x3a, 0x68, 0x59, 0x48, - 0x61, 0x32, 0x49, 0x61, 0x40, 0x22, 0x33, 0x75, - 0x29, 0x76, 0x5b, 0x24, 0x5b, 0x5c, 0x76, 0x5c, - 0x28, 0x75, 0x36, 0x26, 0x2c, 0x65, 0x5e, 0x51, - 0x7b, 0x3a, 0x7d, 0x4f, 0x35, 0x73, 0x6b, 0x5b, - 0x5c, 0x37, 0x35, 0x6b, 0x41, 0x35, 0x40, 0x3a, - 0x22, 0x28, 0x6c, 0x71, 0x46, 0x68, 0x7b, 0x66, - 0x56, 0x24, 0x7c, 0x54, 0x28, 0x30, 0x22, 0x4e, - 0x3c, 0x65, 0x69, 0x36, 0x44, 0x53, 0x3d, 0x6c, - 0x5f, 0x73, 0x6c, 0x6f, 0x5e, 0x27, 0x23, 0x4e, - 0x60, 0x45, 0x2f, 0x3d, 0x37, 0x28, 0x51, 0x29, - 0x77, 0x6a, 0x6b, 0x2a, 0x2a, 0x51, 0x26, 0x4c, - 0x4e, 0x71, 0x77, 0x73, 0x71, 0x2d, 0x5a, 0x2c, - 0x23, 0x3d, 0x5f, 0x62, 0x63, 0x2e, 0x72, 0x2a, - 0x75, 0x66, 0x43, 0x56, 0x5f, 0x21, 0x64, 0x66, - 0x35, 0x3b, 0x7a, 0x45, 0x3f, 0x4f, 0x57, 0x22, - 0x5a, 0x45, 0x65, 0x37, 0x58, 0x5b, 0x43, 0x66, - 0x4f, 0x5d, 0x6e, 0x41, 0x41, 0x62, 0x5e, 0x39, - 0x65, 0x6f, 0x43, 0x4b, 0x5e, 0x51, 0x42, 0x3f, - 0x2d, 0x68, 0x4b, 0x6e, 0x46, 0x6f, 0x21, 0x44, - 0x3c, 0x22, 0x46, 0x31, 0x31, 0x2e, 0x56, 0x2e, - 0x77, 0x48, 0x68, 0x23, 0x4a, 0x36, 0x52, 0x5d, - 0x61, 0x47, 0x71, 0x2e, 0x3a, 0x4a, 0x5b, 0x56, - 0x6b, 0x52, 0x2a, 0x4c, 0x4f, 0x24, 0x34, 0x60, - 0x70, 0x58, 0x7a, 0x76, 0x4b, 0x68, 0x24, 0x5f, - 0x51, 0x6d, 0x75, 0x45, 0x48, 0x21, 0x53, 0x4d, - 0x27, 0x75, 0x5f, 0x50, 0x3e, 0x40, 0x3f, 0x5e, - 0x64, 0x41, 0x5f, 0x68, 0x48, 0x30, 0x71, 0x4b, - 0x66, 0x2c, 0x2f, 0x76, 0x4b, 0x23, 0x46, 0x34, - 0x50, 0x58, 0x52, 0x69, 0x2b, 0x6e, 0x7a, 0x33, - 0x53, 0x43, 0x43, 0x35, 0x54, 0x30, 0x73, 0x63, - 0x3b, 0x43, 0x52, 0x29, 0x45, 0x37, 0x71, 0x79, - 0x5a, 0x26, 0x24, 0x72, 0x73, 0x4e, 0x44, 0x38, - 0x5b, 0x71, 0x36, 0x3a, 0x4f, 0x5b, 0x71, 0x28, - 0x71, 0x79, 0x72, 0x40, 0x6e, 0x51, 0x72, 0x29, - 0x3d, 0x4f, 0x33, 0x22, 0x73, 0x5a, 0x30, 0x71, - 0x58, 0x54, 0x59, 0x48, 0x29, 0x2b, 0x5c, 0x73, - 0x6f, 0x4e, 0x60, 0x2a, 0x72, 0x39, 0x50, 0x59, - 0x6f, 0x48, 0x3e, 0x62, 0x6c, 0x62, 0x49, 0x6c, - 0x2c, 0x3f, 0x43, 0x3f, 0x32, 0x7c, 0x6f, 0x6c, - 0x39, 0x26, 0x26, 0x7b, 0x5d, 0x65, 0x6f, 0x41, - 0x7c, 0x42, 0x2b, 0x65, 0x6f, 0x3e, 0x7b, 0x69, - 0x46, 0x4d, 0x68, 0x68, 0x5a, 0x33, 0x25, 0x5d, - 0x6f, 0x48, 0x7c, 0x77, 0x7d, 0x3f, 0x4e, 0x30, - 0x69, 0x65, 0x28, 0x2e, 0x34, 0x34, 0x41, 0x43, - 0x5e, 0x30, 0x23, 0x3b, 0x60, 0x79, 0x5b, 0x26, - 0x7c, 0x77, 0x3e, 0x43, 0x24, 0x31, 0x3a, 0x56, - 0x24, 0x3c, 0x60, 0x3f, 0x60, 0x55, 0x6a, 0x68 - }; - uint32_t request4_len = sizeof(request4); - - uint8_t request5[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x69, 0x3e, 0x72, 0x44, 0x31, 0x6b, 0x28, 0x2f, - 0x79, 0x37, 0x58, 0x5d, 0x5f, 0x68, 0x71, 0x47, - 0x7a, 0x68, 0x7c, 0x6c, 0x65, 0x3c, 0x74, 0x67, - 0x59, 0x5c, 0x3d, 0x28, 0x65, 0x28, 0x58, 0x74, - 0x44, 0x62, 0x2e, 0x36, 0x54, 0x2f, 0x24, 0x34, - 0x4b, 0x6d, 0x3a, 0x7b, 0x60, 0x71, 0x5a, 0x77, - 0x4a, 0x27, 0x25, 0x70, 0x75, 0x56, 0x78, 0x73, - 0x2e, 0x38, 0x6c, 0x70, 0x66, 0x7b, 0x7b, 0x2d, - 0x78, 0x27, 0x65, 0x63, 0x58, 0x4f, 0x7d, 0x5c, - 0x31, 0x3e, 0x36, 0x6e, 0x65, 0x61, 0x2e, 0x4e, - 0x26, 0x68, 0x2b, 0x33, 0x7d, 0x54, 0x2c, 0x28, - 0x47, 0x3a, 0x31, 0x47, 0x56, 0x32, 0x74, 0x51, - 0x79, 0x65, 0x42, 0x45, 0x60, 0x55, 0x6f, 0x48, - 0x61, 0x23, 0x72, 0x62, 0x74, 0x3a, 0x5a, 0x26, - 0x2d, 0x41, 0x58, 0x62, 0x75, 0x4b, 0x37, 0x2e, - 0x3f, 0x2a, 0x6e, 0x2e, 0x2c, 0x43, 0x6f, 0x53, - 0x5f, 0x48, 0x7a, 0x53, 0x7b, 0x54, 0x28, 0x30, - 0x2b, 0x7a, 0x34, 0x33, 0x28, 0x2b, 0x23, 0x23, - 0x72, 0x38, 0x25, 0x30, 0x35, 0x66, 0x76, 0x46, - 0x2a, 0x57, 0x7a, 0x60, 0x38, 0x5a, 0x26, 0x4f, - 0x78, 0x43, 0x2c, 0x7d, 0x3d, 0x76, 0x7d, 0x66, - 0x48, 0x7d, 0x3e, 0x59, 0x31, 0x58, 0x6b, 0x30, - 0x76, 0x45, 0x6e, 0x70, 0x72, 0x5f, 0x3c, 0x70, - 0x6d, 0x77, 0x42, 0x75, 0x42, 0x73, 0x68, 0x5e, - 0x5f, 0x72, 0x2b, 0x2a, 0x70, 0x38, 0x7a, 0x4c, - 0x58, 0x2e, 0x5e, 0x2d, 0x2d, 0x78, 0x67, 0x5a, - 0x77, 0x34, 0x5a, 0x50, 0x76, 0x2d, 0x2b, 0x77, - 0x37, 0x6e, 0x38, 0x2d, 0x7b, 0x44, 0x78, 0x67, - 0x52, 0x57, 0x79, 0x43, 0x7d, 0x6d, 0x4d, 0x32, - 0x23, 0x37, 0x51, 0x4b, 0x41, 0x60, 0x6e, 0x53, - 0x4e, 0x78, 0x37, 0x37, 0x60, 0x56, 0x64, 0x52, - 0x25, 0x46, 0x53, 0x5f, 0x2b, 0x56, 0x2b, 0x3b, - 0x40, 0x37, 0x33, 0x37, 0x23, 0x43, 0x36, 0x6b, - 0x6b, 0x5d, 0x35, 0x28, 0x7d, 0x6a, 0x2c, 0x68, - 0x28, 0x4b, 0x4a, 0x6c, 0x27, 0x35, 0x51, 0x66, - 0x30, 0x39, 0x28, 0x4d, 0x61, 0x2f, 0x64, 0x36, - 0x59, 0x39, 0x68, 0x4b, 0x24, 0x51, 0x7b, 0x6e, - 0x38, 0x49, 0x55, 0x72, 0x5f, 0x33, 0x5c, 0x26, - 0x45, 0x2f, 0x71, 0x66, 0x33, 0x3d, 0x36, 0x68, - 0x65, 0x48, 0x42, 0x40, 0x58, 0x61, 0x4f, 0x50, - 0x70, 0x5e, 0x3c, 0x5d, 0x56, 0x43, 0x4c, 0x41, - 0x45, 0x54, 0x76, 0x4b, 0x21, 0x25, 0x45, 0x4c, - 0x5e, 0x58, 0x23, 0x7d, 0x34, 0x61, 0x5c, 0x53, - 0x2a, 0x47, 0x37, 0x22, 0x6d, 0x31, 0x42, 0x6e, - 0x22, 0x72, 0x62, 0x55, 0x59, 0x66, 0x28, 0x73, - 0x55, 0x50, 0x5c, 0x6f, 0x52, 0x40, 0x3e, 0x3b, - 0x44, 0x2a, 0x51, 0x3d, 0x4d, 0x47, 0x3a, 0x57, - 0x3e, 0x29, 0x29, 0x7d, 0x40, 0x36, 0x41, 0x3f, - 0x58, 0x77, 0x3b, 0x41, 0x2d, 0x64, 0x5a, 0x72, - 0x7c, 0x7d, 0x30, 0x68, 0x54, 0x34, 0x40, 0x21, - 0x7d, 0x2b, 0x2d, 0x2b, 0x6d, 0x5f, 0x49, 0x57, - 0x68, 0x65, 0x79, 0x2c, 0x21, 0x41, 0x31, 0x55, - 0x27, 0x4d, 0x78, 0x55, 0x2f, 0x61, 0x62, 0x78, - 0x58, 0x25, 0x3a, 0x4b, 0x3e, 0x67, 0x44, 0x7c, - 0x7d, 0x52, 0x3d, 0x3e, 0x3b, 0x62, 0x2d, 0x28, - 0x48, 0x70, 0x2c, 0x79, 0x31, 0x5a, 0x5e, 0x3f, - 0x6a, 0x30, 0x78, 0x41, 0x44, 0x60, 0x4e, 0x63, - 0x63, 0x2e, 0x31, 0x79, 0x2b, 0x47, 0x57, 0x26, - 0x22, 0x6a, 0x46, 0x43, 0x70, 0x30, 0x51, 0x7d, - 0x21, 0x3c, 0x68, 0x74, 0x40, 0x5a, 0x6e, 0x71, - 0x3f, 0x76, 0x73, 0x2e, 0x29, 0x3f, 0x6a, 0x55, - 0x21, 0x72, 0x65, 0x75, 0x5e, 0x6b, 0x39, 0x6e, - 0x3e, 0x76, 0x42, 0x41, 0x65, 0x3f, 0x2b, 0x37, - 0x70, 0x7a, 0x7a, 0x29, 0x50, 0x66, 0x21, 0x67, - 0x3f, 0x54, 0x32, 0x5f, 0x73, 0x27, 0x59, 0x6f, - 0x39, 0x4b, 0x4e, 0x23, 0x54, 0x3b, 0x39, 0x21, - 0x38, 0x41, 0x33, 0x44, 0x57, 0x6b, 0x51, 0x30, - 0x6a, 0x76, 0x62, 0x2c, 0x5c, 0x5e, 0x49, 0x3e, - 0x59, 0x38, 0x5e, 0x4a, 0x59, 0x77, 0x34, 0x25, - 0x4f, 0x76, 0x6a, 0x68, 0x6f, 0x73, 0x7c, 0x3d, - 0x2d, 0x64, 0x6c, 0x7a, 0x3d, 0x2c, 0x26, 0x28, - 0x58, 0x2b, 0x4b, 0x45, 0x68, 0x38, 0x74, 0x63, - 0x7b, 0x4a, 0x63, 0x52, 0x26, 0x54, 0x3c, 0x46, - 0x77, 0x2d, 0x6b, 0x78, 0x63, 0x7b, 0x6a, 0x50, - 0x26, 0x42, 0x62, 0x63, 0x65, 0x6b, 0x63, 0x54, - 0x4d, 0x47, 0x59, 0x48, 0x2e, 0x60, 0x7c, 0x4d, - 0x33, 0x4d, 0x61, 0x72, 0x76, 0x72, 0x21, 0x4d, - 0x2b, 0x43, 0x58, 0x47, 0x4a, 0x36, 0x2d, 0x7b, - 0x32, 0x72, 0x21, 0x78, 0x22, 0x38, 0x2c, 0x7a, - 0x34, 0x44, 0x45, 0x66, 0x31, 0x7b, 0x37, 0x68, - 0x62, 0x65, 0x62, 0x6d, 0x4e, 0x7c, 0x75, 0x38, - 0x2a, 0x73, 0x27, 0x64, 0x33, 0x4f, 0x21, 0x41, - 0x7c, 0x41, 0x3f, 0x60, 0x68, 0x34, 0x72, 0x5b, - 0x38, 0x33, 0x6f, 0x65, 0x3e, 0x5a, 0x7d, 0x25, - 0x49, 0x50, 0x60, 0x36, 0x59, 0x5e, 0x6b, 0x25, - 0x66, 0x7a, 0x7d, 0x71, 0x40, 0x6c, 0x2c, 0x6e, - 0x6a, 0x5a, 0x24, 0x5a, 0x76, 0x21, 0x67, 0x39, - 0x4b, 0x4a, 0x31, 0x24, 0x66, 0x66, 0x2e, 0x58, - 0x43, 0x46, 0x75, 0x6c, 0x47, 0x28, 0x4f, 0x21, - 0x75, 0x77, 0x6f, 0x71, 0x48, 0x3f, 0x4d, 0x4c, - 0x51, 0x37, 0x3b, 0x41, 0x4d, 0x41, 0x48, 0x28, - 0x71, 0x24, 0x2f, 0x7a, 0x22, 0x49, 0x4a, 0x39, - 0x44, 0x43, 0x68, 0x21, 0x3a, 0x34, 0x4e, 0x52, - 0x7a, 0x60, 0x71, 0x61, 0x6d, 0x51, 0x58, 0x2a, - 0x59, 0x4c, 0x4a, 0x59, 0x6b, 0x77, 0x78, 0x2e, - 0x27, 0x78, 0x76, 0x48, 0x4f, 0x46, 0x79, 0x2c, - 0x54, 0x42, 0x7b, 0x2c, 0x52, 0x41, 0x54, 0x2b, - 0x2c, 0x33, 0x6b, 0x70, 0x77, 0x2e, 0x2e, 0x41, - 0x25, 0x7a, 0x48, 0x6e, 0x71, 0x55, 0x6a, 0x43, - 0x5a, 0x2c, 0x6c, 0x76, 0x6d, 0x71, 0x72, 0x4d, - 0x76, 0x5b, 0x7b, 0x22, 0x4b, 0x45, 0x31, 0x30, - 0x26, 0x53, 0x75, 0x3f, 0x26, 0x59, 0x36, 0x2f, - 0x68, 0x4f, 0x34, 0x5e, 0x2b, 0x30, 0x63, 0x68, - 0x7b, 0x32, 0x5e, 0x77, 0x7d, 0x7b, 0x53, 0x5f, - 0x63, 0x53, 0x77, 0x7a, 0x7d, 0x35, 0x28, 0x3e, - 0x41, 0x6f, 0x5b, 0x31, 0x78, 0x7b, 0x2b, 0x51, - 0x23, 0x43, 0x46, 0x6a, 0x32, 0x32, 0x25, 0x45, - 0x57, 0x43, 0x22, 0x50, 0x60, 0x32, 0x70, 0x2e, - 0x79, 0x2e, 0x6b, 0x33, 0x67, 0x6c, 0x43, 0x5b, - 0x3b, 0x68, 0x53, 0x53, 0x6a, 0x48, 0x59, 0x5f, - 0x30, 0x72, 0x7d, 0x6b, 0x37, 0x24, 0x75, 0x52, - 0x50, 0x2b, 0x75, 0x35, 0x24, 0x3b, 0x6e, 0x53, - 0x56, 0x34, 0x23, 0x54, 0x65, 0x4f, 0x78, 0x3e, - 0x46, 0x7d, 0x25, 0x3f, 0x2f, 0x49, 0x6b, 0x49, - 0x47, 0x45, 0x24, 0x38, 0x3b, 0x68, 0x6c, 0x4f, - 0x29, 0x21, 0x50, 0x32, 0x67, 0x47, 0x5a, 0x72, - 0x76, 0x21, 0x39, 0x67, 0x3c, 0x72, 0x47, 0x43, - 0x4a, 0x2e, 0x31, 0x32, 0x34, 0x3c, 0x53, 0x2d, - 0x22, 0x5b, 0x5b, 0x6a, 0x77, 0x75, 0x31, 0x68, - 0x30, 0x45, 0x43, 0x5f, 0x60, 0x5d, 0x56, 0x67, - 0x66, 0x55, 0x6a, 0x72, 0x77, 0x7b, 0x44, 0x61, - 0x22, 0x64, 0x36, 0x39, 0x6e, 0x44, 0x37, 0x54, - 0x45, 0x46, 0x6f, 0x58, 0x35, 0x51, 0x3c, 0x62, - 0x49, 0x3a, 0x50, 0x58, 0x56, 0x5d, 0x77, 0x6f, - 0x56, 0x64, 0x7b, 0x49, 0x39, 0x21, 0x31, 0x2d, - 0x5f, 0x56, 0x56, 0x33, 0x31, 0x69, 0x4a, 0x52, - 0x62, 0x5b, 0x6e, 0x65, 0x7c, 0x3d, 0x31, 0x55, - 0x3d, 0x75, 0x25, 0x61, 0x50, 0x71, 0x45, 0x29 - }; - uint32_t request5_len = sizeof(request5); - - uint8_t request6[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x5b, 0x56, 0x3d, 0x5a, 0x6b, 0x43, 0x73, 0x26, - 0x65, 0x3b, 0x38, 0x79, 0x26, 0x5e, 0x60, 0x59, - 0x40, 0x71, 0x7c, 0x72, 0x28, 0x29, 0x69, 0x32, - 0x72, 0x5a, 0x6c, 0x55, 0x43, 0x65, 0x3f, 0x4a, - 0x21, 0x66, 0x59, 0x30, 0x76, 0x39, 0x21, 0x69, - 0x4b, 0x25, 0x5d, 0x6e, 0x5f, 0x24, 0x2b, 0x38, - 0x70, 0x78, 0x35, 0x7d, 0x39, 0x36, 0x31, 0x72, - 0x44, 0x49, 0x45, 0x3d, 0x25, 0x50, 0x24, 0x3b, - 0x52, 0x27, 0x66, 0x46, 0x5d, 0x4f, 0x34, 0x50, - 0x26, 0x5a, 0x25, 0x3e, 0x3f, 0x34, 0x4b, 0x35, - 0x77, 0x3a, 0x3f, 0x3e, 0x23, 0x4e, 0x30, 0x23, - 0x70, 0x72, 0x33, 0x34, 0x60, 0x2a, 0x4a, 0x32, - 0x6e, 0x29, 0x54, 0x73, 0x5f, 0x26, 0x71, 0x3a, - 0x78, 0x5d, 0x3f, 0x31, 0x48, 0x59, 0x61, 0x44, - 0x5c, 0x38, 0x4f, 0x41, 0x73, 0x67, 0x62, 0x73, - 0x33, 0x52, 0x77, 0x73, 0x57, 0x49, 0x7a, 0x59, - 0x26, 0x21, 0x34, 0x38, 0x2b, 0x5f, 0x5f, 0x37, - 0x74, 0x28, 0x46, 0x3d, 0x43, 0x42, 0x26, 0x66, - 0x63, 0x37, 0x6d, 0x2a, 0x65, 0x3f, 0x71, 0x2d, - 0x4c, 0x72, 0x29, 0x4b, 0x3a, 0x77, 0x64, 0x6a, - 0x6b, 0x42, 0x70, 0x5c, 0x51, 0x38, 0x71, 0x25, - 0x4c, 0x7c, 0x6f, 0x74, 0x71, 0x39, 0x71, 0x25, - 0x3f, 0x62, 0x23, 0x45, 0x5f, 0x77, 0x59, 0x56, - 0x56, 0x67, 0x78, 0x3a, 0x2e, 0x4e, 0x27, 0x59, - 0x65, 0x2f, 0x64, 0x3c, 0x62, 0x40, 0x69, 0x52, - 0x36, 0x49, 0x3e, 0x3b, 0x2c, 0x47, 0x4f, 0x3e, - 0x61, 0x78, 0x2d, 0x45, 0x71, 0x3f, 0x7b, 0x55, - 0x34, 0x36, 0x47, 0x5e, 0x36, 0x51, 0x3d, 0x5a, - 0x4b, 0x75, 0x44, 0x72, 0x61, 0x44, 0x71, 0x4e, - 0x42, 0x6a, 0x2c, 0x34, 0x40, 0x3b, 0x40, 0x31, - 0x31, 0x75, 0x4b, 0x32, 0x71, 0x69, 0x3a, 0x5d, - 0x31, 0x25, 0x53, 0x2a, 0x61, 0x54, 0x68, 0x2a, - 0x76, 0x71, 0x57, 0x67, 0x56, 0x23, 0x7d, 0x70, - 0x7d, 0x28, 0x57, 0x5f, 0x2f, 0x4c, 0x71, 0x2e, - 0x40, 0x63, 0x49, 0x5b, 0x7c, 0x7b, 0x56, 0x76, - 0x77, 0x46, 0x69, 0x56, 0x3d, 0x75, 0x31, 0x3b, - 0x35, 0x40, 0x37, 0x2c, 0x51, 0x37, 0x49, 0x6a, - 0x79, 0x68, 0x53, 0x31, 0x4c, 0x6f, 0x57, 0x4c, - 0x48, 0x31, 0x6a, 0x30, 0x2b, 0x69, 0x30, 0x56, - 0x58, 0x4b, 0x76, 0x3b, 0x60, 0x6d, 0x35, 0x4d, - 0x74, 0x2f, 0x74, 0x2c, 0x54, 0x4f, 0x6e, 0x3f, - 0x38, 0x56, 0x5c, 0x67, 0x2b, 0x4a, 0x35, 0x30, - 0x67, 0x7d, 0x58, 0x24, 0x59, 0x54, 0x48, 0x2e, - 0x28, 0x7d, 0x6e, 0x51, 0x55, 0x68, 0x56, 0x54, - 0x59, 0x31, 0x4a, 0x65, 0x5a, 0x5e, 0x27, 0x76, - 0x76, 0x65, 0x6d, 0x2f, 0x75, 0x63, 0x67, 0x52, - 0x5e, 0x29, 0x58, 0x3d, 0x5c, 0x3f, 0x54, 0x7c, - 0x67, 0x21, 0x6e, 0x75, 0x67, 0x35, 0x77, 0x31, - 0x3d, 0x26, 0x3f, 0x60, 0x45, 0x2d, 0x2b, 0x45, - 0x5d, 0x3f, 0x55, 0x73, 0x59, 0x4c, 0x5e, 0x6c, - 0x30, 0x4a, 0x4e, 0x47, 0x55, 0x42, 0x6a, 0x4b, - 0x32, 0x3c, 0x75, 0x6e, 0x36, 0x51, 0x5f, 0x4c, - 0x68, 0x72, 0x72, 0x27, 0x3b, 0x51, 0x59, 0x7b, - 0x68, 0x7b, 0x3b, 0x54, 0x35, 0x37, 0x7c, 0x44, - 0x43, 0x36, 0x4c, 0x4f, 0x67, 0x62, 0x4e, 0x39, - 0x4b, 0x7a, 0x49, 0x36, 0x68, 0x38, 0x4c, 0x4a, - 0x64, 0x33, 0x35, 0x2f, 0x3e, 0x5c, 0x58, 0x61, - 0x23, 0x5b, 0x50, 0x6e, 0x34, 0x44, 0x60, 0x28, - 0x54, 0x41, 0x5c, 0x31, 0x53, 0x2d, 0x58, 0x58, - 0x54, 0x28, 0x77, 0x51, 0x6f, 0x64, 0x4c, 0x68, - 0x34, 0x79, 0x45, 0x66, 0x2c, 0x26, 0x77, 0x64, - 0x5f, 0x6c, 0x3b, 0x71, 0x28, 0x4d, 0x68, 0x2a, - 0x6b, 0x37, 0x6a, 0x34, 0x51, 0x27, 0x2a, 0x46, - 0x3a, 0x2e, 0x35, 0x21, 0x21, 0x79, 0x51, 0x44, - 0x58, 0x5d, 0x6f, 0x65, 0x6b, 0x76, 0x68, 0x3a, - 0x43, 0x70, 0x36, 0x41, 0x6b, 0x56, 0x64, 0x75, - 0x5b, 0x37, 0x24, 0x56, 0x7c, 0x6e, 0x6c, 0x41, - 0x3a, 0x60, 0x56, 0x38, 0x55, 0x63, 0x77, 0x4d, - 0x6e, 0x50, 0x3c, 0x3d, 0x7a, 0x44, 0x71, 0x42, - 0x4b, 0x55, 0x75, 0x72, 0x61, 0x60, 0x65, 0x6f, - 0x7a, 0x26, 0x64, 0x46, 0x67, 0x74, 0x29, 0x2a, - 0x5b, 0x62, 0x41, 0x28, 0x62, 0x30, 0x34, 0x33, - 0x40, 0x79, 0x7a, 0x38, 0x56, 0x38, 0x73, 0x22, - 0x7a, 0x7d, 0x73, 0x2a, 0x2a, 0x28, 0x2b, 0x63, - 0x27, 0x6f, 0x3d, 0x3e, 0x2c, 0x56, 0x23, 0x32, - 0x4b, 0x3b, 0x58, 0x4d, 0x72, 0x4c, 0x49, 0x6f, - 0x30, 0x76, 0x23, 0x21, 0x21, 0x3c, 0x49, 0x56, - 0x7a, 0x56, 0x79, 0x2f, 0x50, 0x7a, 0x5b, 0x21, - 0x21, 0x4a, 0x48, 0x61, 0x33, 0x52, 0x49, 0x2e, - 0x30, 0x7d, 0x2c, 0x2d, 0x67, 0x23, 0x55, 0x62, - 0x66, 0x52, 0x5a, 0x61, 0x75, 0x63, 0x3c, 0x39, - 0x69, 0x41, 0x31, 0x6b, 0x4e, 0x6f, 0x25, 0x34, - 0x74, 0x30, 0x21, 0x3a, 0x40, 0x72, 0x44, 0x40, - 0x60, 0x4c, 0x53, 0x74, 0x42, 0x64, 0x44, 0x49, - 0x76, 0x67, 0x21, 0x79, 0x36, 0x3c, 0x37, 0x70, - 0x4f, 0x58, 0x29, 0x71, 0x2a, 0x3a, 0x4d, 0x5d, - 0x67, 0x68, 0x52, 0x63, 0x23, 0x24, 0x4b, 0x21, - 0x3f, 0x68, 0x69, 0x6c, 0x66, 0x66, 0x42, 0x28, - 0x59, 0x35, 0x34, 0x6f, 0x2d, 0x6a, 0x25, 0x66, - 0x34, 0x54, 0x5d, 0x50, 0x26, 0x41, 0x22, 0x4f, - 0x34, 0x79, 0x3c, 0x50, 0x68, 0x2d, 0x5f, 0x7b, - 0x63, 0x7d, 0x58, 0x2e, 0x73, 0x46, 0x2f, 0x54, - 0x61, 0x27, 0x74, 0x45, 0x23, 0x72, 0x31, 0x7d, - 0x63, 0x4b, 0x43, 0x5e, 0x44, 0x54, 0x2c, 0x38, - 0x58, 0x24, 0x75, 0x6c, 0x50, 0x3c, 0x23, 0x5f, - 0x35, 0x57, 0x4f, 0x7b, 0x2f, 0x57, 0x29, 0x73, - 0x58, 0x2a, 0x66, 0x3e, 0x49, 0x42, 0x5a, 0x6b, - 0x75, 0x6a, 0x38, 0x3f, 0x73, 0x44, 0x42, 0x46, - 0x2d, 0x39, 0x66, 0x5b, 0x28, 0x3e, 0x63, 0x62, - 0x53, 0x75, 0x65, 0x64, 0x79, 0x32, 0x35, 0x71, - 0x22, 0x6a, 0x7b, 0x41, 0x2b, 0x26, 0x43, 0x79, - 0x58, 0x6f, 0x71, 0x25, 0x24, 0x34, 0x72, 0x5b, - 0x4a, 0x2c, 0x5c, 0x77, 0x23, 0x42, 0x27, 0x6a, - 0x67, 0x51, 0x5f, 0x3c, 0x75, 0x2c, 0x3f, 0x43, - 0x45, 0x5b, 0x48, 0x65, 0x6f, 0x6c, 0x27, 0x65, - 0x21, 0x3e, 0x33, 0x37, 0x5f, 0x2b, 0x2e, 0x24, - 0x22, 0x47, 0x4e, 0x33, 0x5b, 0x7b, 0x21, 0x3c, - 0x53, 0x69, 0x2e, 0x31, 0x3d, 0x48, 0x57, 0x3a, - 0x56, 0x48, 0x6b, 0x47, 0x5d, 0x33, 0x41, 0x6c, - 0x66, 0x4c, 0x61, 0x67, 0x32, 0x69, 0x53, 0x2c, - 0x2f, 0x3e, 0x36, 0x68, 0x37, 0x28, 0x40, 0x21, - 0x76, 0x27, 0x44, 0x26, 0x24, 0x6a, 0x30, 0x75, - 0x2a, 0x73, 0x48, 0x36, 0x52, 0x4a, 0x3b, 0x51, - 0x4e, 0x2f, 0x23, 0x36, 0x4b, 0x49, 0x33, 0x5a, - 0x70, 0x2c, 0x54, 0x5b, 0x67, 0x48, 0x53, 0x5d, - 0x21, 0x3e, 0x6b, 0x52, 0x6a, 0x3c, 0x48, 0x29, - 0x68, 0x27, 0x32, 0x75, 0x61, 0x7c, 0x51, 0x2e, - 0x7b, 0x49, 0x2f, 0x5b, 0x3d, 0x74, 0x5a, 0x28, - 0x26, 0x29, 0x2c, 0x30, 0x54, 0x74, 0x45, 0x55, - 0x4a, 0x3d, 0x39, 0x35, 0x66, 0x56, 0x28, 0x6d, - 0x6e, 0x38, 0x7b, 0x2b, 0x40, 0x31, 0x56, 0x61, - 0x74, 0x2b, 0x79, 0x5f, 0x63, 0x51, 0x53, 0x52, - 0x7d, 0x73, 0x4e, 0x2e, 0x45, 0x3b, 0x22, 0x28, - 0x6c, 0x2b, 0x47, 0x21, 0x50, 0x2a, 0x7c, 0x45, - 0x48, 0x57, 0x3e, 0x2f, 0x6d, 0x66, 0x6c, 0x51, - 0x23, 0x6c, 0x37, 0x4d, 0x4b, 0x4b, 0x66, 0x55, - 0x69, 0x2e, 0x4a, 0x69, 0x71, 0x7c, 0x71, 0x30, - 0x5c, 0x43, 0x46, 0x63, 0x5a, 0x23, 0x75, 0x40 - }; - uint32_t request6_len = sizeof(request6); - - uint8_t request7[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x5d, 0x32, 0x55, 0x71, 0x51, 0x45, 0x4e, 0x54, - 0x34, 0x21, 0x46, 0x77, 0x5e, 0x5b, 0x75, 0x62, - 0x2b, 0x5c, 0x34, 0x26, 0x72, 0x2b, 0x2c, 0x64, - 0x4b, 0x65, 0x56, 0x72, 0x31, 0x7d, 0x6a, 0x5f, - 0x70, 0x26, 0x32, 0x29, 0x7d, 0x21, 0x5b, 0x3e, - 0x5e, 0x53, 0x3d, 0x48, 0x5e, 0x2a, 0x4c, 0x37, - 0x3d, 0x59, 0x79, 0x21, 0x4f, 0x56, 0x79, 0x2a, - 0x4e, 0x28, 0x61, 0x7d, 0x2c, 0x58, 0x2f, 0x78, - 0x5c, 0x3f, 0x5c, 0x42, 0x6d, 0x2f, 0x71, 0x54, - 0x25, 0x31, 0x73, 0x38, 0x6c, 0x31, 0x5a, 0x2e, - 0x42, 0x5b, 0x2d, 0x41, 0x24, 0x4c, 0x37, 0x40, - 0x39, 0x7d, 0x2a, 0x67, 0x60, 0x6a, 0x7a, 0x62, - 0x24, 0x4e, 0x3f, 0x2e, 0x69, 0x35, 0x28, 0x65, - 0x77, 0x53, 0x23, 0x44, 0x59, 0x71, 0x31, 0x5c, - 0x40, 0x5d, 0x3a, 0x27, 0x46, 0x55, 0x30, 0x56, - 0x21, 0x74, 0x3e, 0x73, 0x41, 0x22, 0x52, 0x68, - 0x40, 0x6c, 0x37, 0x3e, 0x62, 0x5a, 0x2e, 0x21, - 0x23, 0x33, 0x27, 0x73, 0x68, 0x26, 0x60, 0x67, - 0x70, 0x58, 0x50, 0x42, 0x58, 0x27, 0x3a, 0x35, - 0x6f, 0x51, 0x62, 0x78, 0x25, 0x2c, 0x7b, 0x66, - 0x34, 0x6a, 0x5a, 0x39, 0x60, 0x70, 0x41, 0x2d, - 0x65, 0x26, 0x5a, 0x67, 0x58, 0x2d, 0x3e, 0x56, - 0x6d, 0x30, 0x4b, 0x4d, 0x5d, 0x45, 0x41, 0x3d, - 0x6e, 0x27, 0x4e, 0x5a, 0x7d, 0x2e, 0x62, 0x4d, - 0x42, 0x70, 0x31, 0x24, 0x73, 0x5c, 0x78, 0x77, - 0x50, 0x73, 0x27, 0x48, 0x3d, 0x35, 0x2c, 0x4b, - 0x40, 0x2d, 0x25, 0x77, 0x5d, 0x3d, 0x6b, 0x50, - 0x6f, 0x57, 0x73, 0x2f, 0x4f, 0x6e, 0x4c, 0x6e, - 0x56, 0x7b, 0x55, 0x3c, 0x6d, 0x60, 0x47, 0x53, - 0x56, 0x39, 0x3b, 0x51, 0x61, 0x71, 0x75, 0x73, - 0x6b, 0x70, 0x58, 0x5f, 0x2c, 0x27, 0x74, 0x49, - 0x2c, 0x2b, 0x53, 0x2d, 0x5b, 0x79, 0x43, 0x34, - 0x39, 0x5a, 0x38, 0x3e, 0x2d, 0x66, 0x70, 0x3d, - 0x49, 0x51, 0x29, 0x4d, 0x5d, 0x4c, 0x57, 0x4a, - 0x2f, 0x41, 0x69, 0x56, 0x57, 0x77, 0x49, 0x58, - 0x75, 0x28, 0x29, 0x4a, 0x6d, 0x54, 0x4f, 0x4f, - 0x3f, 0x58, 0x5f, 0x58, 0x6f, 0x39, 0x22, 0x4d, - 0x5d, 0x31, 0x75, 0x43, 0x2f, 0x7d, 0x31, 0x3d, - 0x4c, 0x4d, 0x76, 0x74, 0x4d, 0x57, 0x3b, 0x56, - 0x57, 0x48, 0x2b, 0x5d, 0x32, 0x67, 0x51, 0x6e, - 0x60, 0x39, 0x6f, 0x64, 0x38, 0x37, 0x52, 0x4b, - 0x52, 0x42, 0x32, 0x4f, 0x24, 0x53, 0x31, 0x6e, - 0x4a, 0x68, 0x2f, 0x28, 0x2e, 0x27, 0x49, 0x75, - 0x77, 0x75, 0x26, 0x47, 0x7c, 0x5d, 0x72, 0x5a, - 0x77, 0x50, 0x2e, 0x6c, 0x27, 0x68, 0x6b, 0x7b, - 0x27, 0x63, 0x21, 0x3d, 0x30, 0x2d, 0x5c, 0x67, - 0x4d, 0x41, 0x79, 0x47, 0x42, 0x50, 0x6d, 0x32, - 0x74, 0x39, 0x62, 0x4d, 0x5f, 0x65, 0x78, 0x4f, - 0x67, 0x3a, 0x60, 0x26, 0x45, 0x61, 0x7c, 0x61, - 0x63, 0x40, 0x46, 0x79, 0x52, 0x47, 0x57, 0x49, - 0x53, 0x4c, 0x48, 0x36, 0x67, 0x47, 0x5c, 0x71, - 0x50, 0x4d, 0x4f, 0x58, 0x26, 0x40, 0x6d, 0x54, - 0x55, 0x67, 0x66, 0x23, 0x70, 0x23, 0x68, 0x70, - 0x4d, 0x2c, 0x7a, 0x3d, 0x60, 0x51, 0x35, 0x64, - 0x56, 0x2f, 0x26, 0x6d, 0x72, 0x6a, 0x59, 0x34, - 0x3a, 0x73, 0x4b, 0x27, 0x33, 0x61, 0x26, 0x45, - 0x61, 0x28, 0x74, 0x22, 0x54, 0x50, 0x2e, 0x39, - 0x6a, 0x2c, 0x27, 0x59, 0x26, 0x73, 0x44, 0x71, - 0x67, 0x4c, 0x37, 0x74, 0x2c, 0x63, 0x52, 0x2a, - 0x60, 0x4f, 0x7b, 0x32, 0x39, 0x21, 0x79, 0x54, - 0x79, 0x6d, 0x28, 0x27, 0x3a, 0x6a, 0x7d, 0x40, - 0x6a, 0x4f, 0x4b, 0x46, 0x61, 0x36, 0x6a, 0x22, - 0x3f, 0x77, 0x2d, 0x6a, 0x3b, 0x73, 0x71, 0x72, - 0x3c, 0x21, 0x2e, 0x3f, 0x33, 0x25, 0x76, 0x64, - 0x64, 0x70, 0x43, 0x32, 0x44, 0x73, 0x61, 0x51, - 0x3c, 0x3b, 0x45, 0x3a, 0x68, 0x46, 0x5b, 0x6e, - 0x36, 0x47, 0x4d, 0x38, 0x26, 0x4f, 0x5c, 0x7d, - 0x73, 0x29, 0x24, 0x78, 0x44, 0x75, 0x40, 0x42, - 0x41, 0x2a, 0x73, 0x2b, 0x24, 0x38, 0x51, 0x67, - 0x36, 0x67, 0x2f, 0x70, 0x58, 0x54, 0x6e, 0x5d, - 0x3b, 0x41, 0x59, 0x76, 0x7d, 0x2d, 0x40, 0x70, - 0x29, 0x4a, 0x4a, 0x31, 0x79, 0x2c, 0x4e, 0x22, - 0x31, 0x59, 0x31, 0x3c, 0x2f, 0x21, 0x29, 0x3f, - 0x65, 0x6c, 0x38, 0x55, 0x4f, 0x27, 0x66, 0x66, - 0x34, 0x45, 0x49, 0x41, 0x56, 0x24, 0x2e, 0x40, - 0x36, 0x23, 0x5a, 0x46, 0x40, 0x23, 0x7b, 0x2d, - 0x69, 0x54, 0x6c, 0x51, 0x58, 0x73, 0x56, 0x60, - 0x5f, 0x60, 0x63, 0x5f, 0x77, 0x6a, 0x4c, 0x2c, - 0x35, 0x39, 0x60, 0x73, 0x63, 0x3e, 0x2d, 0x55, - 0x5a, 0x26, 0x4b, 0x43, 0x3b, 0x56, 0x33, 0x58, - 0x74, 0x51, 0x4f, 0x5c, 0x2a, 0x44, 0x78, 0x66, - 0x78, 0x71, 0x40, 0x29, 0x5e, 0x26, 0x57, 0x51, - 0x49, 0x30, 0x29, 0x73, 0x38, 0x56, 0x6c, 0x41, - 0x78, 0x3d, 0x61, 0x3d, 0x2c, 0x33, 0x46, 0x57, - 0x54, 0x63, 0x3e, 0x79, 0x55, 0x4a, 0x7d, 0x2e, - 0x2a, 0x3c, 0x77, 0x47, 0x35, 0x29, 0x5a, 0x6d, - 0x69, 0x48, 0x6b, 0x73, 0x7d, 0x4f, 0x5f, 0x6f, - 0x3a, 0x7a, 0x4e, 0x54, 0x59, 0x38, 0x62, 0x44, - 0x72, 0x51, 0x57, 0x6a, 0x74, 0x54, 0x4f, 0x77, - 0x6b, 0x66, 0x4a, 0x6b, 0x39, 0x29, 0x69, 0x60, - 0x71, 0x52, 0x6a, 0x32, 0x66, 0x6c, 0x25, 0x76, - 0x27, 0x7a, 0x2c, 0x38, 0x72, 0x4e, 0x5f, 0x40, - 0x26, 0x74, 0x6a, 0x5e, 0x42, 0x38, 0x78, 0x34, - 0x4f, 0x4f, 0x35, 0x27, 0x39, 0x62, 0x52, 0x61, - 0x37, 0x54, 0x47, 0x38, 0x70, 0x31, 0x7a, 0x66, - 0x69, 0x72, 0x24, 0x52, 0x2a, 0x2a, 0x78, 0x72, - 0x2b, 0x2e, 0x2a, 0x57, 0x4a, 0x21, 0x52, 0x3c, - 0x2a, 0x2f, 0x24, 0x58, 0x34, 0x3c, 0x42, 0x5c, - 0x5b, 0x78, 0x27, 0x55, 0x63, 0x58, 0x3e, 0x26, - 0x50, 0x2c, 0x72, 0x60, 0x36, 0x6c, 0x46, 0x58, - 0x63, 0x59, 0x23, 0x2a, 0x2d, 0x63, 0x6a, 0x68, - 0x69, 0x74, 0x3f, 0x49, 0x4f, 0x48, 0x4a, 0x3b, - 0x59, 0x56, 0x77, 0x43, 0x6d, 0x57, 0x28, 0x5f, - 0x39, 0x73, 0x28, 0x74, 0x3c, 0x4f, 0x43, 0x48, - 0x6a, 0x57, 0x5d, 0x41, 0x73, 0x3f, 0x41, 0x7c, - 0x65, 0x5e, 0x2d, 0x38, 0x72, 0x3a, 0x53, 0x3e, - 0x33, 0x47, 0x69, 0x6a, 0x6e, 0x78, 0x67, 0x5d, - 0x35, 0x3b, 0x3f, 0x23, 0x7c, 0x71, 0x3d, 0x7c, - 0x3a, 0x3c, 0x75, 0x6e, 0x00, 0x00, 0x00, 0x00, - 0x50, 0x6a, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x50, 0x6a, 0x40, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x50, 0x6a, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x50, 0x6a, 0x40, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x50, 0x80, 0x23, 0x00, 0xdf, 0xaf, 0xff, 0x33, - 0x9b, 0x78, 0x70, 0x43, 0xc5, 0x0a, 0x4d, 0x98, - 0x96, 0x02, 0x64, 0x92, 0xc1, 0xee, 0x70, 0x32 - }; - uint32_t request7_len = sizeof(request7); - - uint8_t request8[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0x65, 0xc1, 0xef, 0x7b, 0xd6, 0xaa, 0xd6, 0x09, - 0x21, 0xf6, 0xe7, 0xd1, 0x4c, 0xdf, 0x6a, 0x2d, - 0x0a, 0xfb, 0x43, 0xea, 0xda, 0x07, 0x24, 0x84, - 0x88, 0x52, 0x9e, 0xa8, 0xa1, 0x7f, 0x4b, 0x60, - 0xec, 0x94, 0x57, 0x33, 0x06, 0x93, 0x92, 0x25, - 0xd6, 0xac, 0xdc, 0x89, 0x68, 0x5e, 0xbb, 0x32, - 0x2b, 0x17, 0x68, 0xf2, 0x06, 0xb7, 0x86, 0xac, - 0x81, 0xfe, 0x52, 0x27, 0xf5, 0x80, 0x11, 0x0d, - 0x4e, 0x2e, 0x1b, 0xa3, 0x44, 0x8a, 0x58, 0xed, - 0xf3, 0x9c, 0xe9, 0x31, 0x01, 0x72, 0xa6, 0xab, - 0xfa, 0xa8, 0x05, 0x00, 0x37, 0x60, 0x6b, 0x81, - 0xef, 0xf4, 0x96, 0x9a, 0xf7, 0x67, 0x95, 0x27, - 0x7a, 0x25, 0xef, 0x6f, 0x0e, 0xff, 0x2d, 0x15, - 0x7f, 0x23, 0x1c, 0xa7, 0x56, 0x94, 0x4a, 0x18, - 0x98, 0xc6, 0xd8, 0xd2, 0x29, 0x5b, 0x57, 0xb8, - 0x5d, 0x3a, 0x93, 0x58, 0x45, 0x77, 0x36, 0xe3, - 0xd1, 0x36, 0x87, 0xff, 0xe3, 0x94, 0x0f, 0x00, - 0xe6, 0x7c, 0x1a, 0x92, 0xc1, 0x5f, 0x40, 0xc3, - 0xa3, 0x25, 0xce, 0xd4, 0xaf, 0x39, 0xeb, 0x17, - 0xcf, 0x22, 0x43, 0xd9, 0x0c, 0xce, 0x37, 0x86, - 0x46, 0x54, 0xd6, 0xce, 0x00, 0x30, 0x36, 0xae, - 0xf9, 0xb5, 0x2b, 0x11, 0xa0, 0xfe, 0xa3, 0x4b, - 0x2e, 0x05, 0xbe, 0x54, 0xa9, 0xd8, 0xa5, 0x76, - 0x83, 0x5b, 0x63, 0x01, 0x1c, 0xd4, 0x56, 0x72, - 0xcd, 0xdc, 0x4a, 0x1d, 0x77, 0xda, 0x8a, 0x9e, - 0xba, 0xcb, 0x6c, 0xe8, 0x19, 0x5d, 0x68, 0xef, - 0x8e, 0xbc, 0x6a, 0x05, 0x53, 0x0b, 0xc7, 0xc5, - 0x96, 0x84, 0x04, 0xd9, 0xda, 0x4c, 0x42, 0x31, - 0xd9, 0xbd, 0x99, 0x06, 0xf7, 0xa3, 0x0a, 0x19, - 0x49, 0x07, 0x77, 0xf0, 0xdb, 0x7c, 0x43, 0xfa, - 0xb2, 0xad, 0xb0, 0xfa, 0x87, 0x52, 0xba, 0xc9, - 0x94, 0x61, 0xdc, 0xcf, 0x16, 0xac, 0x0f, 0x4a, - 0xa3, 0x6b, 0x5b, 0x6e, 0x27, 0x86, 0x1f, 0xfe, - 0x4d, 0x28, 0x3a, 0xa5, 0x10, 0x54, 0x6d, 0xed, - 0x53, 0xf9, 0x73, 0xc6, 0x6e, 0xa8, 0xc0, 0x97, - 0xcf, 0x56, 0x3b, 0x61, 0xdf, 0xab, 0x83, 0x18, - 0xe8, 0x09, 0xee, 0x6a, 0xb7, 0xf5, 0xc9, 0x62, - 0x55, 0x2d, 0xc7, 0x0c, 0x0d, 0xa0, 0x22, 0xd8, - 0xd4, 0xd6, 0xb2, 0x12, 0x21, 0xd7, 0x73, 0x3e, - 0x41, 0xb0, 0x5c, 0xd4, 0xcf, 0x98, 0xf3, 0x70, - 0xe6, 0x08, 0xe6, 0x2a, 0x4f, 0x24, 0x85, 0xe8, - 0x74, 0xa8, 0x41, 0x5f, 0x0e, 0xfd, 0xf1, 0xf3, - 0xbe, 0x9b, 0x14, 0xfd, 0xc0, 0x73, 0x11, 0xff, - 0xa5, 0x5b, 0x06, 0x34, 0xc3, 0x6c, 0x28, 0x42, - 0x07, 0xfe, 0x8a, 0xa5, 0xbe, 0x72, 0x7a, 0xf7, - 0xfa, 0x25, 0xec, 0x35, 0x5e, 0x98, 0x71, 0x50, - 0x60, 0x35, 0x76, 0x53, 0x40, 0x1a, 0x34, 0xa5, - 0x99, 0x09, 0xa2, 0xc6, 0xca, 0xa5, 0xce, 0x08, - 0x50, 0x45, 0xab, 0x8d, 0xfb, 0xe3, 0xb8, 0xe4, - 0x8a, 0x61, 0x48, 0x14, 0x6e, 0xf7, 0x58, 0x71, - 0xe5, 0x2e, 0xbc, 0x12, 0xd1, 0x25, 0xe9, 0x65, - 0x7a, 0xa1, 0x27, 0xbe, 0x3b, 0x8b, 0xe8, 0xe7, - 0xbc, 0xe1, 0x05, 0xe7, 0x92, 0xeb, 0xb9, 0xdf, - 0x5d, 0x53, 0x74, 0xc0, 0x63, 0x97, 0x80, 0xb8, - 0x3c, 0xae, 0xf3, 0xf2, 0x09, 0x12, 0x81, 0x6c, - 0x69, 0x10, 0x6f, 0xf6, 0xbe, 0x03, 0x7b, 0x88, - 0xcf, 0x26, 0x6b, 0x51, 0x06, 0x23, 0x68, 0x03, - 0xa1, 0xb7, 0xd3, 0x0c, 0xca, 0xbf, 0x29, 0x01, - 0xa9, 0x61, 0x34, 0x75, 0x98, 0x1e, 0x05, 0x59, - 0xb3, 0x46, 0x44, 0xff, 0x2b, 0x98, 0x04, 0x88, - 0x89, 0xfd, 0x7f, 0xd5, 0x19, 0x8a, 0xa6, 0xf3, - 0xd9, 0x44, 0xd5, 0xf9, 0x3a, 0x3c, 0xec, 0xd9, - 0x9b, 0x8c, 0x93, 0x93, 0x2b, 0x44, 0x86, 0x8b, - 0x80, 0x83, 0x23, 0x00, 0xdf, 0xaf, 0xff, 0x33, - 0x9b, 0x78, 0x70, 0x43, 0xf1, 0x55, 0x87, 0xb1, - 0xa1, 0xb3, 0x8e, 0x79, 0x02, 0x70, 0x82, 0x6c, - 0x0b, 0xc1, 0xef, 0x96, 0xf1, 0xef, 0xdd, 0xa2, - 0x69, 0x86, 0xc7, 0x85, 0x09, 0x7e, 0xf0, 0x2f, - 0x8e, 0xa0, 0x5f, 0xea, 0x39, 0x2e, 0x24, 0xf0, - 0x82, 0x30, 0x26, 0xa8, 0xa1, 0x4f, 0xc6, 0x5c, - 0xec, 0x94, 0x87, 0x52, 0x9b, 0x93, 0x92, 0xf3, - 0xa3, 0x1b, 0xc7, 0x8f, 0x9e, 0xb3, 0xbb, 0x32, - 0x2b, 0x17, 0x54, 0xf2, 0x06, 0x0c, 0x86, 0x92, - 0x0f, 0xb8, 0xe0, 0x27, 0x50, 0xaa, 0xeb, 0xf5, - 0x4e, 0x2b, 0x1b, 0xb2, 0x44, 0xe6, 0x58, 0x02, - 0xd7, 0x65, 0xdc, 0x31, 0x01, 0xec, 0xa6, 0xab, - 0xfa, 0xa8, 0x05, 0x00, 0x37, 0x60, 0x4f, 0xa1, - 0x3c, 0x4f, 0x7a, 0x9a, 0x10, 0x67, 0x95, 0xc2, - 0x5b, 0x25, 0xef, 0x76, 0x0e, 0xff, 0x2d, 0x15, - 0x7f, 0x23, 0x1c, 0x77, 0x56, 0x94, 0x4a, 0x18, - 0x98, 0xc6, 0xd8, 0xd2, 0x29, 0x44, 0x57, 0xb8, - 0x40, 0x3a, 0x93, 0x58, 0x45, 0x77, 0x36, 0x36, - 0x07, 0x35, 0x2a, 0xff, 0x00, 0x94, 0x5c, 0x80, - 0xe6, 0x7c, 0x1a, 0x92, 0xc1, 0x5f, 0x40, 0xc3, - 0xbc, 0xf8, 0xce, 0x05, 0x77, 0x39, 0x40, 0x17, - 0xcf, 0x63, 0x43, 0x77, 0x27, 0xce, 0x37, 0x86, - 0x46, 0x54, 0xd6, 0xce, 0x00, 0x30, 0x36, 0xae, - 0x9f, 0x24, 0x2b, 0x5a, 0xa0, 0xfe, 0xa3, 0x4b, - 0x2e, 0x7e, 0xf7, 0x54, 0xa9, 0xd8, 0xa5, 0x76, - 0x83, 0x7b, 0x63, 0x01, 0x1c, 0xd4, 0x56, 0x17, - 0x02, 0xdc, 0x4a, 0x89, 0x77, 0xda, 0x8f, 0x9e, - 0xba, 0xcb, 0x37, 0xe8, 0x19, 0x5d, 0x68, 0x38, - 0x8e, 0xbc, 0x6a, 0x05, 0x53, 0x0b, 0xc7, 0xc5, - 0x96, 0x84, 0x5a, 0xd9, 0x6d, 0x4c, 0x42, 0x31, - 0xd9, 0xf2, 0x99, 0x06, 0xf7, 0x0c, 0x99, 0xbe, - 0x49, 0x07, 0x77, 0xf0, 0x8b, 0x7c, 0x43, 0xfa, - 0xb2, 0xad, 0xb0, 0xfa, 0x87, 0x52, 0xba, 0xc9, - 0x94, 0x61, 0xdc, 0xcf, 0x16, 0xac, 0x0f, 0x4a, - 0xa3, 0x6b, 0x5b, 0x6e, 0x27, 0x86, 0x1f, 0xfe, - 0x4d, 0x28, 0x3a, 0xa5, 0x10, 0x98, 0x6d, 0xed, - 0x53, 0xf9, 0x73, 0xc6, 0xa5, 0xa8, 0xf7, 0x66, - 0xcf, 0x56, 0x3b, 0x61, 0xdf, 0xab, 0x83, 0x18, - 0xe8, 0x09, 0xee, 0x6a, 0xb7, 0xf5, 0xc9, 0x62, - 0x55, 0x2d, 0xc7, 0x0c, 0x0d, 0xa0, 0x22, 0xd8, - 0xd4, 0xd6, 0xb2, 0x12, 0x21, 0xd7, 0x73, 0x3e, - 0x41, 0xb0, 0x5c, 0xd4, 0xcf, 0x98, 0xf3, 0x70, - 0xe6, 0x08, 0xe6, 0x2a, 0x4f, 0x92, 0x85, 0xe8, - 0x74, 0xa8, 0x41, 0x5f, 0x0e, 0xfd, 0xf1, 0xf3, - 0xbe, 0x9b, 0x14, 0xfd, 0xc0, 0x73, 0x11, 0xff, - 0xa5, 0x5b, 0x06, 0x34, 0xc3, 0x5d, 0x28, 0x42, - 0x34, 0xfe, 0x8a, 0xa5, 0xbe, 0x72, 0x7a, 0xf7, - 0xfa, 0x25, 0x2b, 0x35, 0x5e, 0x98, 0x71, 0x50, - 0x2c, 0x35, 0x76, 0x53, 0x4e, 0x1a, 0x34, 0xa5, - 0x99, 0x09, 0xa2, 0xc6, 0xca, 0xa5, 0xce, 0x08, - 0x50, 0x45, 0xab, 0x8d, 0xfb, 0xe3, 0xb8, 0xe4, - 0x8a, 0x61, 0x48, 0x14, 0x6e, 0xf7, 0x58, 0x71, - 0xe5, 0x2e, 0xbc, 0x12, 0xd1, 0x25, 0xe9, 0x65, - 0x7a, 0xa1, 0x27, 0xbe, 0x3b, 0x8b, 0xe8, 0xe7, - 0xbc, 0x77, 0x05, 0xe7, 0x92, 0xeb, 0xb9, 0xdf, - 0x5d, 0x53, 0x74, 0xc0, 0x63, 0x97, 0x80, 0xb8, - 0x3c, 0xae, 0xf3, 0xf2, 0x09, 0x12, 0x81, 0x6c, - 0x69, 0x10, 0x6f, 0xf6, 0xbe, 0x03, 0x7b, 0x88, - 0xcf, 0x26, 0x6b, 0x51, 0x06, 0x23, 0x68, 0x03, - 0xa1, 0xb7, 0xd3, 0x0c, 0xca, 0xbf, 0x29, 0x01, - 0xa9, 0x61, 0x34, 0x75, 0x98, 0x1e, 0x6f, 0x59, - 0xb3, 0x46, 0x44, 0xff, 0x2b, 0x98, 0x04, 0x88, - 0x89, 0xfd, 0x1c, 0xd5, 0x19, 0x8a, 0xa6, 0xf3, - 0xd9, 0x44, 0xd5, 0xf9, 0x79, 0x26, 0x46, 0xf7 - }; - uint32_t request8_len = sizeof(request8); - - uint8_t request9[] = { - 0x05, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xbf, 0xa1, 0x12, 0x73, 0x23, 0x44, 0x86, 0x8b, - 0x50, 0x6a, 0x40, 0x00 - }; - uint32_t request9_len = sizeof(request9); - - TcpSession ssn; - Packet *p[11]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|26 d0 cf 80|\"; distance:0; sid:1;)"; - char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|43 5b 67 26 65|\"; distance:0; sid:2;)"; - char *sig3 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|71 69 75 3e|\"; distance:0; sid:3;)"; - char *sig4 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|6a 68 69 3e 72|\"; distance:0; sid:4;)"; - char *sig5 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|61 50 71 45 29 5b 56 3d 5a|\"; distance:0; sid:5;)"; - char *sig6 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|23 75 40 5d 32 55|\"; distance:0; sid:6;)"; - char *sig7 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|ee 70 32 65 c1|\"; distance:0; sid:7;)"; - char *sig8 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|79 26 46 f7 bf a1|\"; distance:0; sid:8;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 11; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - p[1]->flowflags |= FLOW_PKT_TOCLIENT; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig2); - s = s->next; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig3); - s = s->next; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig4); - s = s->next; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig5); - s = s->next; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig6); - s = s->next; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig7); - s = s->next; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig8); - s = s->next; - if (s == NULL) - goto end; - - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, bind, bind_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if ((PacketAlertCheck(p[0], 1))) { - printf("sid 1 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 2))) { - printf("sid 2 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 3))) { - printf("sid 3 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 4))) { - printf("sid 4 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 5))) { - printf("sid 5 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 6))) { - printf("sid 6 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 7))) { - printf("sid 7 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 8))) { - printf("sid 8 matched but shouldn't have for packet 0: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack, bind_ack_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if ((PacketAlertCheck(p[1], 1))) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 2))) { - printf("sid 2 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 3))) { - printf("sid 3 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 4))) { - printf("sid 4 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 5))) { - printf("sid 5 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 6))) { - printf("sid 6 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 7))) { - printf("sid 7 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 8))) { - printf("sid 8 matched but shouldn't have for packet 1: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[2]); - if ((PacketAlertCheck(p[2], 1))) { - printf("sid 1 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 2))) { - printf("sid 2 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 3))) { - printf("sid 3 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 4))) { - printf("sid 4 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 5))) { - printf("sid 5 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 6))) { - printf("sid 6 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 7))) { - printf("sid 7 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 8))) { - printf("sid 8 matched but shouldn't have for packet 2: "); - goto end; - } - - SCLogDebug("sending request 2"); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[3]); - if (!(PacketAlertCheck(p[3], 1))) { - printf("sid 1 didn't match but should have for packet 3: "); - goto end; - } - if ((PacketAlertCheck(p[3], 2))) { - printf("sid 2 matched but shouldn't have for packet 3: "); - goto end; - } - if ((PacketAlertCheck(p[3], 3))) { - printf("sid 3 matched but shouldn't have for packet 3: "); - goto end; - } - if ((PacketAlertCheck(p[3], 4))) { - printf("sid 4 matched but shouldn't have for packet 3: "); - goto end; - } - if ((PacketAlertCheck(p[3], 5))) { - printf("sid 5 matched but shouldn't have for packet 3: "); - goto end; - } - if ((PacketAlertCheck(p[3], 6))) { - printf("sid 6 matched but shouldn't have for packet 3: "); - goto end; - } - if ((PacketAlertCheck(p[3], 7))) { - printf("sid 7 matched but shouldn't have for packet 3: "); - goto end; - } - if ((PacketAlertCheck(p[3], 8))) { - printf("sid 8 matched but shouldn't have for packet 3: "); - goto end; - } - - SCLogDebug("sending request 3"); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request3, request3_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SCLogDebug("inspecting packet 4"); - SigMatchSignatures(&tv, de_ctx, det_ctx, p[4]); - if ((PacketAlertCheck(p[4], 1))) { - printf("sid 1 matched but shouldn't have for packet 4: "); - goto end; - } - if (!(PacketAlertCheck(p[4], 2))) { - printf("sid 2 didn't match but should have for packet 4: "); - goto end; - } - if ((PacketAlertCheck(p[4], 3))) { - printf("sid 3 matched but shouldn't have for packet 4: "); - goto end; - } - if ((PacketAlertCheck(p[4], 4))) { - printf("sid 4 matched but shouldn't have for packet 4: "); - goto end; - } - if ((PacketAlertCheck(p[4], 5))) { - printf("sid 5 matched but shouldn't have for packet 4: "); - goto end; - } - if ((PacketAlertCheck(p[4], 6))) { - printf("sid 6 matched but shouldn't have for packet 4: "); - goto end; - } - if ((PacketAlertCheck(p[4], 7))) { - printf("sid 7 matched but shouldn't have for packet 4: "); - goto end; - } - if ((PacketAlertCheck(p[4], 8))) { - printf("sid 8 matched but shouldn't have for packet 4: "); - goto end; - } - - SCLogDebug("sending request 4"); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request4, request4_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[5]); - if ((PacketAlertCheck(p[5], 1))) { - printf("sid 1 matched but shouldn't have for packet 5: "); - goto end; - } - if ((PacketAlertCheck(p[5], 2))) { - printf("sid 2 matched but shouldn't have for packet 5: "); - goto end; - } - if (!(PacketAlertCheck(p[5], 3))) { - printf("sid 3 didn't match but should have packet 5: "); - goto end; - } - if ((PacketAlertCheck(p[5], 4))) { - printf("sid 4 matched but shouldn't have for packet 5: "); - goto end; - } - if ((PacketAlertCheck(p[5], 5))) { - printf("sid 5 matched but shouldn't have for packet 5: "); - goto end; - } - if ((PacketAlertCheck(p[5], 6))) { - printf("sid 6 matched but shouldn't have for packet 5: "); - goto end; - } - if ((PacketAlertCheck(p[5], 7))) { - printf("sid 7 matched but shouldn't have for packet 5: "); - goto end; - } - if ((PacketAlertCheck(p[5], 8))) { - printf("sid 8 matched but shouldn't have for packet 5: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request5, request5_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[6]); - if ((PacketAlertCheck(p[6], 1))) { - printf("sid 1 matched but shouldn't have for packet 6: "); - goto end; - } - if ((PacketAlertCheck(p[6], 2))) { - printf("sid 2 matched but shouldn't have for packet 6: "); - goto end; - } - if ((PacketAlertCheck(p[6], 3))) { - printf("sid 3 matched but shouldn't have for packet 6: "); - goto end; - } - if (!(PacketAlertCheck(p[6], 4))) { - printf("sid 4 didn't match but should have packet 6: "); - goto end; - } - if ((PacketAlertCheck(p[6], 5))) { - printf("sid 5 matched but shouldn't have for packet 6: "); - goto end; - } - if ((PacketAlertCheck(p[6], 6))) { - printf("sid 6 matched but shouldn't have for packet 6: "); - goto end; - } - if ((PacketAlertCheck(p[6], 7))) { - printf("sid 7 matched but shouldn't have for packet 6: "); - goto end; - } - if ((PacketAlertCheck(p[6], 8))) { - printf("sid 8 matched but shouldn't have for packet 6: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request6, request6_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[7]); - if ((PacketAlertCheck(p[7], 1))) { - printf("sid 1 matched but shouldn't have for packet 7: "); - goto end; - } - if ((PacketAlertCheck(p[7], 2))) { - printf("sid 2 matched but shouldn't have for packet 7: "); - goto end; - } - if ((PacketAlertCheck(p[7], 3))) { - printf("sid 3 matched but shouldn't have for packet 7: "); - goto end; - } - if ((PacketAlertCheck(p[7], 4))) { - printf("sid 4 matched but shouldn't have for packet 7: "); - goto end; - } - if (!(PacketAlertCheck(p[7], 5))) { - printf("sid 5 didn't match but should have paket 7: "); - goto end; - } - if ((PacketAlertCheck(p[7], 6))) { - printf("sid 6 matched but shouldn't have for packet 7: "); - goto end; - } - if ((PacketAlertCheck(p[7], 7))) { - printf("sid 7 matched but shouldn't have for packet 7: "); - goto end; - } - if ((PacketAlertCheck(p[7], 8))) { - printf("sid 8 matched but shouldn't have for packet 7: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request7, request7_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[8]); - if ((PacketAlertCheck(p[8], 1))) { - printf("sid 1 matched but shouldn't have for packet 8: "); - goto end; - } - if ((PacketAlertCheck(p[8], 2))) { - printf("sid 2 matched but shouldn't have for packet 8: "); - goto end; - } - if ((PacketAlertCheck(p[8], 3))) { - printf("sid 3 matched but shouldn't have for packet 8: "); - goto end; - } - if ((PacketAlertCheck(p[8], 4))) { - printf("sid 4 matched but shouldn't have for packet 8: "); - goto end; - } - if ((PacketAlertCheck(p[8], 5))) { - printf("sid 5 matched but shouldn't have for packet 8: "); - goto end; - } - if (!(PacketAlertCheck(p[8], 6))) { - printf("sid 6 didn't match but should have paket 8: "); - goto end; - } - if ((PacketAlertCheck(p[8], 7))) { - printf("sid 7 matched but shouldn't have for packet 8: "); - goto end; - } - if ((PacketAlertCheck(p[8], 8))) { - printf("sid 8 matched but shouldn't have for packet 8: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request8, request8_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[9]); - if ((PacketAlertCheck(p[9], 1))) { - printf("sid 1 matched but shouldn't have for packet 9: "); - goto end; - } - if ((PacketAlertCheck(p[9], 2))) { - printf("sid 2 matched but shouldn't have for packet 9: "); - goto end; - } - if ((PacketAlertCheck(p[9], 3))) { - printf("sid 3 matched but shouldn't have for packet 9: "); - goto end; - } - if ((PacketAlertCheck(p[9], 4))) { - printf("sid 4 matched but shouldn't have for packet 9: "); - goto end; - } - if ((PacketAlertCheck(p[9], 5))) { - printf("sid 5 matched but shouldn't have for packet 9: "); - goto end; - } - if ((PacketAlertCheck(p[9], 6))) { - printf("sid 6 matched but shouldn't have for packet 9: "); - goto end; - } - if (!(PacketAlertCheck(p[9], 7))) { - printf("sid 7 didn't match but should have for packet 9: "); - goto end; - } - if ((PacketAlertCheck(p[9], 8))) { - printf("sid 8 matched but shouldn't have for packet 9: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request9, request9_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[10]); - if ((PacketAlertCheck(p[10], 1))) { - printf("sid 1 matched but shouldn't have for packet 10: "); - goto end; - } - if ((PacketAlertCheck(p[10], 2))) { - printf("sid 2 matched but shouldn't have for packet 10: "); - goto end; - } - if ((PacketAlertCheck(p[10], 3))) { - printf("sid 3 matched but shouldn't have for packet 10: "); - goto end; - } - if ((PacketAlertCheck(p[10], 4))) { - printf("sid 4 matched but shouldn't have for packet 10: "); - goto end; - } - if ((PacketAlertCheck(p[10], 5))) { - printf("sid 5 matched but shouldn't have for packet 10: "); - goto end; - } - if ((PacketAlertCheck(p[10], 6))) { - printf("sid 6 matched but shouldn't have for packet 10: "); - goto end; - } - if ((PacketAlertCheck(p[10], 7))) { - printf("sid 7 matched but shouldn't have for packet 10: "); - goto end; - } - if (!(PacketAlertCheck(p[10], 8))) { - printf("sid 8 didn't match but should have for paket 10: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 11); - return result; -#else - return 1; -#endif -} - -/** - * \test Test the working of detection engien with respect to dce keywords. - */ -int DcePayloadTest02(void) -{ -#if 0 - int result = 0; - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x48, 0x1a, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - - TcpSession ssn; - Packet *p[4]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "sid:1;)"; - char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "dce_stub_data; content:\"|2d 5e 63 2a 4c|\"; distance:0; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 4; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - p[1]->flowflags |= FLOW_PKT_TOCLIENT; - p[1]->flowflags &=~ FLOW_PKT_TOSERVER; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig2); - s = s->next; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, bind, bind_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if (PacketAlertCheck(p[0], 1)) { - printf("sid 1 didn't match but should have for packet 0: "); - goto end; - } - if (PacketAlertCheck(p[0], 2)) { - printf("sid 2 matched but shouldn't have for packet 0: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack, bind_ack_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if ((PacketAlertCheck(p[1], 1))) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 2))) { - printf("sid 2 matched but shouldn't have for packet 1: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[2]); - if (!(PacketAlertCheck(p[2], 1))) { - printf("sid 1 didn't match but should have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 2))) { - printf("sid 2 matched but shouldn't have for packet 2: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[3]); - if ((PacketAlertCheck(p[3], 1))) { - printf("sid 1 matched but shouldn't have for packet 3: "); - goto end; - } - if (!(PacketAlertCheck(p[3], 2))) { - printf("sid 2 didn't match but should have for packet 3: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 4); - return result; -#else - return 1; -#endif -} - -/** - * \test Test the working of detection engien with respect to dce keywords. - */ -int DcePayloadTest03(void) -{ -#if 0 - int result = 0; - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x48, 0x1a, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - - TcpSession ssn; - Packet *p[4]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef4; " - "dce_stub_data; sid:1;)"; - char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|2d 5e 63 2a 4c|\"; distance:0; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 4; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - p[1]->flowflags |= FLOW_PKT_TOCLIENT; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig2); - s = s->next; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, bind, bind_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if ((PacketAlertCheck(p[0], 1))) { - printf("sid 1 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 2))) { - printf("sid 2 matched but shouldn't have for packet 0: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack, bind_ack_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if ((PacketAlertCheck(p[1], 1))) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 2))) { - printf("sid 2 matched but shouldn't have for packet 1: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[2]); - if ((PacketAlertCheck(p[2], 1))) { - printf("sid 1 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 2))) { - printf("sid 2 matched but shouldn't have for packet 2: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[3]); - if ((PacketAlertCheck(p[3], 1))) { - printf("sid 1 matched but shouldn't have for packet 3: "); - goto end; - } - if (!(PacketAlertCheck(p[3], 2))) { - printf("sid 2 didn't match but should have for packet 3: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 4); - return result; -#else - return 1; -#endif -} - -/** - * \test Test the working of detection engien with respect to dce keywords. - */ -int DcePayloadTest04(void) -{ -#if 0 - int result = 0; - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x48, 0x1a, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - - TcpSession ssn; - Packet *p[4]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; content:\"|91 27 27 40|\"; distance:0; sid:1;)"; - char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|2d 5e 63 2a 4c|\"; distance:0; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 4; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - p[1]->flowflags |= FLOW_PKT_TOCLIENT; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig2); - s = s->next; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, bind, bind_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if ((PacketAlertCheck(p[0], 1))) { - printf("sid 1 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 2))) { - printf("sid 2 matched but shouldn't have for packet 0: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack, bind_ack_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if ((PacketAlertCheck(p[1], 1))) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 2))) { - printf("sid 2 matched but shouldn't have for packet 1: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[2]); - if (!(PacketAlertCheck(p[2], 1))) { - printf("sid 1 didn't match but should have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 2))) { - printf("sid 2 matched but shouldn't have for packet 2: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[3]); - if ((PacketAlertCheck(p[3], 1))) { - printf("sid 1 matched but shouldn't have for packet 3: "); - goto end; - } - if (!(PacketAlertCheck(p[3], 2))) { - printf("sid 2 didn't match but should have for packet 3: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 4); - return result; -#else - return 1; -#endif -} - -/** - * \test Test the working of detection engien with respect to dce keywords. - */ -int DcePayloadTest05(void) -{ -#if 0 - int result = 0; - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x48, 0x1a, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - TcpSession ssn; - Packet *p[4]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef4; " - "dce_stub_data; content:\"|91 27 27 40|\"; distance:0; sid:1;)"; - char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "dce_stub_data; content:\"|2d 5e 63 2a 4c|\"; distance:0; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 4; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - p[1]->flowflags |= FLOW_PKT_TOCLIENT; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig2); - s = s->next; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, bind, bind_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if ((PacketAlertCheck(p[0], 1))) { - printf("sid 1 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 2))) { - printf("sid 2 matched but shouldn't have for packet 0: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack, bind_ack_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if ((PacketAlertCheck(p[1], 1))) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 2))) { - printf("sid 2 matched but shouldn't have for packet 1: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[2]); - if ((PacketAlertCheck(p[2], 1))) { - printf("sid 1 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 2))) { - printf("sid 2 matched but shouldn't have for packet 2: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[3]); - if ((PacketAlertCheck(p[3], 1))) { - printf("sid 2 matched but shouldn't have for packet 3: "); - goto end; - } - if (!(PacketAlertCheck(p[3], 2))) { - printf("sid 2 didn't match but should have for packet 3: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 4); - return result; -#else - return 1; -#endif -} - -/** - * \test Test the working of detection engien with respect to dce keywords. - */ -int DcePayloadTest06(void) -{ -#if 0 - int result = 0; - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x48, 0x1a, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - - TcpSession ssn; - Packet *p[4]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; content:\"|91 27 27 30|\"; distance:0; sid:1;)"; - char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|2d 5e 63 2a 4c|\"; distance:0; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 4; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - p[1]->flowflags |= FLOW_PKT_TOCLIENT; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig2); - s = s->next; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, bind, bind_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if ((PacketAlertCheck(p[0], 1))) { - printf("sid 1 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 2))) { - printf("sid 2 matched but shouldn't have for packet 0: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack, bind_ack_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if ((PacketAlertCheck(p[1], 1))) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 2))) { - printf("sid 2 matched but shouldn't have for packet 1: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[2]); - if ((PacketAlertCheck(p[2], 1))) { - printf("sid 1 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 2))) { - printf("sid 2 matched but shouldn't have for packet 2: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[3]); - if ((PacketAlertCheck(p[3], 1))) { - printf("sid 1 matched but shouldn't have for packet 3: "); - goto end; - } - if (!(PacketAlertCheck(p[3], 2))) { - printf("sid 2 didn't match but should have for packet 3: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 4); - return result; -#else - return 1; -#endif -} - -/** - * \test Test the working of detection engien with respect to dce keywords. - */ -int DcePayloadTest07(void) -{ -#if 0 - int result = 0; - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x16, 0xd0, 0x16, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x6a, 0x28, 0x19, 0x39, 0x0c, 0xb1, 0xd0, 0x11, - 0x9b, 0xa8, 0x00, 0xc0, 0x4f, 0xd9, 0x2e, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x48, 0x1a, 0x00, 0x00, - 0x0c, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6c, 0x73, 0x61, 0x73, 0x73, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - TcpSession ssn; - Packet *p[4]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; content:\"|91 27 27 30|\"; distance:0; sid:1;)"; - char *sig2 = "alert tcp any any -> any any (dce_stub_data; " - "content:\"|2d 5e 63 35 25|\"; distance:0; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 4; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - p[1]->flowflags |= FLOW_PKT_TOCLIENT; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - s->next = SigInit(de_ctx, sig2); - s = s->next; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, bind, bind_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if ((PacketAlertCheck(p[0], 1))) { - printf("sid 1 matched but shouldn't have for packet 0: "); - goto end; - } - if ((PacketAlertCheck(p[0], 2))) { - printf("sid 2 matched but shouldn't have for packet 0: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack, bind_ack_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if ((PacketAlertCheck(p[1], 1))) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - if ((PacketAlertCheck(p[1], 2))) { - printf("sid 2 matched but shouldn't have for packet 1: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[2]); - if ((PacketAlertCheck(p[2], 1))) { - printf("sid 1 matched but shouldn't have for packet 2: "); - goto end; - } - if ((PacketAlertCheck(p[2], 2))) { - printf("sid 2 matched but shouldn't have for packet 2: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[3]); - if ((PacketAlertCheck(p[3], 1))) { - printf("sid 1 matched but shouldn't have for packet 3: "); - goto end; - } - if ((PacketAlertCheck(p[3], 2))) { - printf("sid 2 matched but shouldn't have for packet 3: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 4); - return result; -#else - return 1; -#endif -} - -/** - * \test Positive test, to test the working of distance and within. - */ -int DcePayloadTest08(void) -{ -#if 0 - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p[1]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5d 5b 35|\"; distance:0; content:\"|9e a3|\"; " - "distance:0; within:2; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 1; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if (!(PacketAlertCheck(p[0], 1))) { - printf("sid 1 didn't match but should have for packet 0: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 1); - return result; -#else - return 1; -#endif -} - -/** - * \test Positive test, to test the working of distance and within. - */ -int DcePayloadTest09(void) -{ -#if 0 - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x5d, 0x5b, 0x35, 0x46, 0x9e, 0xa3, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p[1]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5d 5b 35|\"; distance:0; content:\"|9e a3|\"; " - "distance:0; within:2; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 1; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if (!(PacketAlertCheck(p[0], 1))) { - printf("sid 1 didn't match but should have for packet 0: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 1); - return result; -#else - return 1; -#endif -} - -/** - * \test Positive test, to test the working of distance and within. - */ -int DcePayloadTest10(void) -{ -#if 0 - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x5d, 0x5b, 0x35, 0x46, 0x9e, 0xa3, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p[1]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|ad 0d|\"; distance:0; content:\"|ad 0d 00|\"; " - "distance:-10; within:3; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 1; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if (!(PacketAlertCheck(p[0], 1))) { - printf("sid 1 didn't match but should have for packet 0: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 1); - return result; -#else - return 1; -#endif -} - -/** - * \test Postive test to check the working of disance and within across frags. - */ -int DcePayloadTest11(void) -{ -#if 0 - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - TcpSession ssn; - Packet *p[2]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|af, 26, d0|\"; distance:0; content:\"|80 98 6d|\"; " - "distance:1; within:3; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 2; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if ((PacketAlertCheck(p[0], 1))) { - printf("sid 1 matched but shouldn't have for packet 0: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if (!(PacketAlertCheck(p[1], 1))) { - printf("sid 1 didn't match but should have for pacekt 1: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 2); - return result; -#else - return 1; -#endif -} - -/** - * \test Negative test the working of contents on stub data with invalid - * distance. - */ -int DcePayloadTest12(void) -{ -#if 0 /* payload ticks off clamav */ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xad, 0x0d, 0x00, 0x00, 0x91, 0xfc, 0x27, 0x40, - 0x4a, 0x97, 0x4a, 0x98, 0x4b, 0x41, 0x3f, 0x48, - 0x99, 0x90, 0xf8, 0x27, 0xfd, 0x3f, 0x27, 0x37, - 0x40, 0xd6, 0x27, 0xfc, 0x3f, 0x9f, 0x4f, 0xfd, - 0x42, 0x47, 0x47, 0x49, 0x3f, 0xf9, 0x9b, 0xd6, - 0x48, 0x37, 0x27, 0x46, 0x93, 0x49, 0xfd, 0x93, - 0x91, 0xfd, 0x93, 0x90, 0x92, 0x96, 0xf5, 0x92, - 0x4e, 0x91, 0x98, 0x46, 0x4f, 0x4b, 0x46, 0xf5, - 0xf5, 0xfd, 0x40, 0xf9, 0x9b, 0x40, 0x9f, 0x93, - 0x4e, 0xf8, 0x40, 0x40, 0x4e, 0xf5, 0x4b, 0x98, - 0xf5, 0x91, 0xd6, 0x42, 0x99, 0x96, 0x27, 0x49, - 0x48, 0x47, 0x4f, 0x46, 0x99, 0x4b, 0x92, 0x92, - 0x90, 0x47, 0x46, 0x4e, 0x43, 0x9b, 0x43, 0x42, - 0x3f, 0x4b, 0x27, 0x97, 0x93, 0xf9, 0x42, 0x9b, - 0x46, 0x9b, 0x4b, 0x98, 0x41, 0x98, 0x37, 0x41, - 0x9f, 0x98, 0x4e, 0x93, 0x48, 0x46, 0x46, 0x9f, - 0x97, 0x9b, 0x42, 0x37, 0x90, 0x46, 0xf9, 0x97, - 0x91, 0xf5, 0x4e, 0x97, 0x4e, 0x99, 0xf8, 0x99, - 0x41, 0xf5, 0x41, 0x9f, 0x49, 0xfd, 0x92, 0x96, - 0x3f, 0x3f, 0x42, 0x27, 0x27, 0x93, 0x47, 0x49, - 0x91, 0x27, 0x27, 0x40, 0x42, 0x99, 0x9f, 0xfc, - 0x97, 0x47, 0x99, 0x4a, 0xf9, 0x3f, 0x48, 0x91, - 0x47, 0x97, 0x91, 0x42, 0x4b, 0x9b, 0x4a, 0x48, - 0x9f, 0x43, 0x43, 0x40, 0x99, 0xf9, 0x48, 0x4e, - 0x92, 0x93, 0x92, 0x41, 0x46, 0x4b, 0x4a, 0x4a, - 0x49, 0x96, 0x4a, 0x4f, 0xf5, 0x42, 0x47, 0x98, - 0x9b, 0xf5, 0x91, 0xf9, 0xd6, 0x9b, 0x48, 0x4e, - 0x9f, 0x91, 0xd6, 0x93, 0x4b, 0x37, 0x3f, 0x43, - 0xf5, 0x41, 0x41, 0xf5, 0x37, 0x4f, 0x43, 0x92, - 0x97, 0x27, 0x93, 0x92, 0x46, 0x47, 0x4b, 0x96, - 0x41, 0x90, 0x90, 0x3f, 0x96, 0x27, 0x41, 0xd6, - 0xd6, 0xd6, 0xf9, 0xf8, 0x47, 0x27, 0x46, 0x37, - 0x41, 0x90, 0x91, 0xfc, 0x46, 0x41, 0x43, 0x97, - 0x9f, 0x4a, 0x49, 0x92, 0x41, 0x91, 0x41, 0x92, - 0x42, 0x4a, 0x3f, 0x93, 0x99, 0x9b, 0x9f, 0x4e, - 0x47, 0x93, 0xd6, 0x37, 0x37, 0x40, 0x98, 0xfd, - 0x41, 0x42, 0x97, 0x4e, 0x4e, 0x98, 0x9f, 0x4e, - 0x48, 0x3f, 0x48, 0x42, 0x96, 0x9f, 0x99, 0x4f, - 0x4e, 0x42, 0x97, 0xf9, 0x3f, 0x37, 0x27, 0x46, - 0x41, 0xf9, 0x92, 0x96, 0x41, 0x93, 0x91, 0x4b, - 0x96, 0x4f, 0x43, 0xfd, 0xf5, 0x9f, 0x43, 0x27, - 0x99, 0xd6, 0xf5, 0x4e, 0xfd, 0x97, 0x4b, 0x47, - 0x47, 0x92, 0x98, 0x4f, 0x47, 0x49, 0x37, 0x97, - 0x3f, 0x4e, 0x40, 0x46, 0x4e, 0x9f, 0x4e, 0x4e, - 0xfc, 0x41, 0x47, 0xf8, 0x37, 0x9b, 0x41, 0x4e, - 0x96, 0x99, 0x46, 0x99, 0x46, 0xf9, 0x4e, 0x4f, - 0x48, 0x97, 0x97, 0x93, 0xd6, 0x9b, 0x41, 0x40, - 0x97, 0x97, 0x4f, 0x92, 0x91, 0xd6, 0x96, 0x40, - 0x4f, 0x4b, 0x91, 0x46, 0x27, 0x92, 0x3f, 0xf5, - 0xfc, 0x3f, 0x91, 0x97, 0xf8, 0x43, 0x4e, 0xfd, - 0x9b, 0x27, 0xfd, 0x9b, 0xf5, 0x27, 0x47, 0x42, - 0x46, 0x93, 0x37, 0x93, 0x91, 0x91, 0x91, 0xf8, - 0x4f, 0x92, 0x4f, 0xf8, 0x93, 0xf5, 0x49, 0x91, - 0x4b, 0x3f, 0xfc, 0x37, 0x4f, 0x46, 0x98, 0x97, - 0x9f, 0x40, 0xfd, 0x9f, 0x98, 0xfd, 0x4e, 0x97, - 0x4f, 0x47, 0x91, 0x27, 0x4a, 0x90, 0x96, 0x40, - 0x98, 0x97, 0x41, 0x3f, 0xd6, 0xfd, 0x41, 0xfd, - 0x42, 0x97, 0x4b, 0x9b, 0x46, 0x4e, 0xfc, 0x96, - 0xf9, 0x37, 0x4b, 0x96, 0x9f, 0x9b, 0x42, 0x9f, - 0x93, 0x40, 0x42, 0x43, 0xf5, 0x93, 0x48, 0x3f, - 0x4b, 0xfd, 0x9f, 0x4b, 0x41, 0x4a, 0x90, 0x9b, - 0x46, 0x97, 0x98, 0x96, 0x9b, 0x98, 0x92, 0xd6, - 0x4e, 0x4a, 0x27, 0x90, 0x96, 0x99, 0x91, 0x46, - 0x49, 0x41, 0x4b, 0x90, 0x43, 0x91, 0xd6, 0x48, - 0x42, 0x90, 0x4f, 0x96, 0x43, 0x9b, 0xf9, 0x9b, - 0x9f, 0x9f, 0x27, 0x47, 0x4b, 0xf5, 0x43, 0x99, - 0x99, 0x91, 0x4e, 0x41, 0x42, 0x46, 0x97, 0x46, - 0x47, 0xf9, 0xf5, 0x48, 0x4a, 0xf8, 0x4e, 0xd6, - 0x43, 0x4a, 0x27, 0x9b, 0x42, 0x90, 0x46, 0x46, - 0x3f, 0x99, 0x96, 0x9b, 0x91, 0x9f, 0xf5, 0x48, - 0x43, 0x9f, 0x4a, 0x99, 0x96, 0xfd, 0x92, 0x49, - 0x46, 0x91, 0x40, 0xfd, 0x4a, 0x48, 0x4f, 0x90, - 0x91, 0x98, 0x48, 0x4b, 0x9f, 0x42, 0x27, 0x93, - 0x47, 0xf8, 0x4f, 0x48, 0x3f, 0x90, 0x47, 0x41, - 0xf5, 0xfc, 0x27, 0xf8, 0x97, 0x4a, 0x49, 0x37, - 0x40, 0x4f, 0x40, 0x37, 0x41, 0x27, 0x96, 0x37, - 0xfc, 0x42, 0xd6, 0x4b, 0x48, 0x37, 0x42, 0xf5, - 0x27, 0xf9, 0xd6, 0x48, 0x9b, 0xfd, 0x40, 0x96, - 0x4e, 0x43, 0xf8, 0x90, 0x40, 0x40, 0x49, 0x3f, - 0xfc, 0x4a, 0x42, 0x47, 0xf8, 0x49, 0x42, 0x97, - 0x4f, 0x91, 0xfd, 0x4b, 0x46, 0x4b, 0xfc, 0x48, - 0x49, 0x96, 0x4b, 0x96, 0x43, 0x9f, 0x90, 0x37, - 0xd6, 0x4a, 0xd6, 0x3f, 0xd6, 0x90, 0x49, 0x27, - 0x4e, 0x96, 0x96, 0xf8, 0x49, 0x96, 0xf8, 0x37, - 0x90, 0x4e, 0x4b, 0x4f, 0x99, 0xf8, 0x6a, 0x52, - 0x59, 0xd9, 0xee, 0xd9, 0x74, 0x24, 0xf4, 0x5b, - 0x81, 0x73, 0x13, 0x30, 0x50, 0xf0, 0x82, 0x83, - 0xeb, 0xfc, 0xe2, 0xf4, 0xb1, 0x94, 0x0f, 0x6d, - 0xcf, 0xaf, 0xb4, 0x7e, 0x5a, 0xbb, 0xbf, 0x6a, - 0xc9, 0xaf, 0x0f, 0x7d, 0x50, 0xdb, 0x9c, 0xa6, - 0x14, 0xdb, 0xb5, 0xbe, 0xbb, 0x2c, 0xf5, 0xfa, - 0x31, 0xbf, 0x7b, 0xcd, 0x28, 0xdb, 0xaf, 0xa2, - 0x31, 0xbb, 0x13, 0xb2, 0x79, 0xdb, 0xc4, 0x09, - 0x31, 0xbe, 0xc1, 0x42, 0xa9, 0xfc, 0x74, 0x42, - 0x44, 0x57, 0x31, 0x48, 0x3d, 0x51, 0x32, 0x69, - 0xc4, 0x6b, 0xa4, 0xa6, 0x18, 0x25, 0x13, 0x09, - 0x6f, 0x74, 0xf1, 0x69, 0x56, 0xdb, 0xfc, 0xc9, - 0xbb, 0x0f, 0xec, 0x83, 0xdb, 0x53, 0xdc, 0x09, - 0xb9, 0x3c, 0xd4, 0x9e, 0x51, 0x93, 0xc1, 0x42, - 0x54, 0xdb, 0xb0, 0xb2, 0xbb, 0x10, 0xfc, 0x09, - 0x40, 0x4c, 0x5d, 0x09, 0x70, 0x58, 0xae, 0xea, - 0xbe, 0x1e, 0xfe, 0x6e, 0x60, 0xaf, 0x26, 0xb3, - 0xeb, 0x36, 0xa3, 0xe4, 0x58, 0x63, 0xc2, 0xea, - 0x47, 0x23, 0xc2, 0xdd, 0x64, 0xaf, 0x20, 0xea, - 0xfb, 0xbd, 0x0c, 0xb9, 0x60, 0xaf, 0x26, 0xdd, - 0xb9, 0xb5, 0x96, 0x03, 0xdd, 0x58, 0xf2, 0xd7, - 0x5a, 0x52, 0x0f, 0x52, 0x58, 0x89, 0xf9, 0x77, - 0x9d, 0x07, 0x0f, 0x54, 0x63, 0x03, 0xa3, 0xd1, - 0x63, 0x13, 0xa3, 0xc1, 0x63, 0xaf, 0x20, 0xe4, - 0x58, 0x41, 0xac, 0xe4, 0x63, 0xd9, 0x11, 0x17, - 0x58, 0xf4, 0xea, 0xf2, 0xf7, 0x07, 0x0f, 0x54, - 0x5a, 0x40, 0xa1, 0xd7, 0xcf, 0x80, 0x98, 0x26, - 0x9d, 0x7e, 0x19, 0xd5, 0xcf, 0x86, 0xa3, 0xd7, - 0xcf, 0x80, 0x98, 0x67, 0x79, 0xd6, 0xb9, 0xd5, - 0xcf, 0x86, 0xa0, 0xd6, 0x64, 0x05, 0x0f, 0x52, - 0xa3, 0x38, 0x17, 0xfb, 0xf6, 0x29, 0xa7, 0x7d, - 0xe6, 0x05, 0x0f, 0x52, 0x56, 0x3a, 0x94, 0xe4, - 0x58, 0x33, 0x9d, 0x0b, 0xd5, 0x3a, 0xa0, 0xdb, - 0x19, 0x9c, 0x79, 0x65, 0x5a, 0x14, 0x79, 0x60, - 0x01, 0x90, 0x03, 0x28, 0xce, 0x12, 0xdd, 0x7c, - 0x72, 0x7c, 0x63, 0x0f, 0x4a, 0x68, 0x5b, 0x29, - 0x9b, 0x38, 0x82, 0x7c, 0x83, 0x46, 0x0f, 0xf7, - 0x74, 0xaf, 0x26, 0xd9, 0x67, 0x02, 0xa1, 0xd3, - 0x61, 0x3a, 0xf1, 0xd3, 0x61, 0x05, 0xa1, 0x7d, - 0xe0, 0x38, 0x5d, 0x5b, 0x35, 0x9e, 0xa3, 0x7d, - 0xe6, 0x3a, 0x0f, 0x7d, 0x07, 0xaf, 0x20, 0x09, - 0x67, 0xac, 0x73, 0x46, 0x54, 0xaf, 0x26, 0xd0 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, - 0xcf, 0x80, 0x98, 0x6d, 0xfe, 0xb0, 0x90, 0xd1, - 0xcf, 0x86, 0x0f, 0x52, 0x2c, 0x23, 0x66, 0x28, - 0x27, 0x30, 0x48, 0x55, 0x42, 0x6a, 0x48, 0x4b, - 0x68, 0x22, 0x2e, 0x23, 0x64, 0x33, 0x2c, 0x2d, - 0x5c, 0x51, 0x48, 0x55, 0x24, 0x67, 0x6c, 0x4c, - 0x45, 0x71, 0x35, 0x72, 0x5a, 0x48, 0x5e, 0x35, - 0x61, 0x78, 0x35, 0x42, 0x2c, 0x7a, 0x75, 0x61, - 0x5b, 0x4e, 0x76, 0x30, 0x26, 0x2f, 0x2a, 0x34, - 0x48, 0x29, 0x25, 0x6e, 0x5c, 0x3a, 0x6c, 0x3e, - 0x79, 0x4e, 0x2a, 0x21, 0x6f, 0x6f, 0x34, 0x46, - 0x43, 0x26, 0x5b, 0x35, 0x78, 0x27, 0x69, 0x23, - 0x72, 0x21, 0x69, 0x56, 0x6a, 0x7d, 0x4b, 0x5e, - 0x65, 0x37, 0x60, 0x44, 0x7c, 0x5d, 0x5b, 0x72, - 0x7d, 0x73, 0x7b, 0x47, 0x57, 0x21, 0x41, 0x38, - 0x76, 0x38, 0x76, 0x5c, 0x58, 0x32, 0x4a, 0x37, - 0x2f, 0x40, 0x4b, 0x4c, 0x3d, 0x41, 0x33, 0x56, - 0x73, 0x38, 0x61, 0x71, 0x24, 0x49, 0x4c, 0x4a, - 0x44, 0x2e, 0x3a, 0x3f, 0x74, 0x54, 0x4c, 0x65, - 0x54, 0x2d, 0x3b, 0x28, 0x41, 0x45, 0x49, 0x2c, - 0x6e, 0x48, 0x44, 0x43, 0x37, 0x3d, 0x7b, 0x6d, - 0x2b, 0x4b, 0x32, 0x5a, 0x31, 0x61, 0x6e, 0x2b, - 0x27, 0x50, 0x6b, 0x66, 0x76, 0x4e, 0x55, 0x35, - 0x2b, 0x72, 0x2d, 0x5e, 0x42, 0x3e, 0x5a, 0x5d, - 0x36, 0x45, 0x32, 0x3a, 0x58, 0x78, 0x78, 0x3e, - 0x60, 0x6c, 0x5d, 0x63, 0x41, 0x7c, 0x52, 0x21, - 0x75, 0x6a, 0x5a, 0x70, 0x55, 0x45, 0x76, 0x58, - 0x33, 0x40, 0x38, 0x39, 0x21, 0x37, 0x7d, 0x77, - 0x21, 0x70, 0x2b, 0x72, 0x29, 0x6a, 0x31, 0x5f, - 0x38, 0x4a, 0x66, 0x65, 0x62, 0x2c, 0x39, 0x52, - 0x5f, 0x2a, 0x2b, 0x63, 0x4f, 0x76, 0x43, 0x25, - 0x6a, 0x50, 0x37, 0x52, 0x5e, 0x23, 0x3c, 0x42, - 0x28, 0x75, 0x75, 0x42, 0x25, 0x23, 0x28, 0x56, - 0x6c, 0x46, 0x5c, 0x5e, 0x6b, 0x7d, 0x48, 0x24, - 0x77, 0x6c, 0x70, 0x62, 0x2e, 0x28, 0x7d, 0x6b, - 0x69, 0x4a, 0x75, 0x3d, 0x5d, 0x56, 0x21, 0x49, - 0x56, 0x47, 0x64, 0x2b, 0x4c, 0x52, 0x43, 0x60, - 0x77, 0x49, 0x46, 0x46, 0x33, 0x2c, 0x4b, 0x4b, - 0x3d, 0x63, 0x5d, 0x33, 0x78, 0x76, 0x51, 0x56, - 0x77, 0x3c, 0x72, 0x74, 0x52, 0x27, 0x40, 0x6c, - 0x42, 0x79, 0x49, 0x24, 0x62, 0x5e, 0x26, 0x31, - 0x5c, 0x22, 0x2b, 0x4c, 0x64, 0x49, 0x52, 0x45, - 0x47, 0x49, 0x3a, 0x2a, 0x51, 0x71, 0x22, 0x22, - 0x70, 0x24, 0x34, 0x67, 0x4b, 0x6d, 0x58, 0x29, - 0x63, 0x26, 0x7b, 0x6f, 0x38, 0x78, 0x25, 0x62, - 0x4d, 0x3a, 0x7d, 0x40, 0x23, 0x57, 0x67, 0x33, - 0x38, 0x31, 0x4e, 0x54, 0x3c, 0x4b, 0x48, 0x69, - 0x3c, 0x39, 0x31, 0x2b, 0x26, 0x70, 0x44, 0x66, - 0x4a, 0x37, 0x2b, 0x75, 0x36, 0x45, 0x59, 0x34, - 0x3e, 0x3e, 0x29, 0x70, 0x71, 0x5a, 0x55, 0x49, - 0x3e, 0x4b, 0x68, 0x4e, 0x75, 0x70, 0x3c, 0x5c, - 0x50, 0x58, 0x28, 0x75, 0x3c, 0x2a, 0x41, 0x70, - 0x2f, 0x2b, 0x37, 0x26, 0x75, 0x71, 0x55, 0x22, - 0x3a, 0x44, 0x30, 0x48, 0x5d, 0x2f, 0x6c, 0x44, - 0x28, 0x4b, 0x34, 0x45, 0x21, 0x60, 0x44, 0x36, - 0x7b, 0x32, 0x39, 0x5f, 0x6d, 0x3f, 0x68, 0x73, - 0x25, 0x45, 0x56, 0x7c, 0x78, 0x7a, 0x49, 0x6a, - 0x46, 0x3d, 0x2d, 0x33, 0x6c, 0x6f, 0x23, 0x77, - 0x38, 0x33, 0x36, 0x74, 0x7b, 0x57, 0x4b, 0x6d, - 0x27, 0x75, 0x24, 0x6e, 0x43, 0x61, 0x4d, 0x44, - 0x6d, 0x27, 0x48, 0x58, 0x5e, 0x7b, 0x26, 0x6a, - 0x50, 0x7c, 0x51, 0x23, 0x3c, 0x4f, 0x37, 0x4c, - 0x47, 0x3e, 0x45, 0x56, 0x22, 0x33, 0x7c, 0x66, - 0x35, 0x54, 0x7a, 0x6e, 0x5a, 0x24, 0x70, 0x62, - 0x29, 0x3f, 0x69, 0x79, 0x24, 0x43, 0x41, 0x24, - 0x65, 0x25, 0x62, 0x4f, 0x73, 0x3e, 0x2b, 0x36, - 0x46, 0x69, 0x27, 0x55, 0x2a, 0x6e, 0x24, 0x6c, - 0x7d, 0x64, 0x7c, 0x61, 0x26, 0x67, 0x2a, 0x53, - 0x73, 0x60, 0x28, 0x2d, 0x6b, 0x44, 0x54, 0x61, - 0x34, 0x53, 0x22, 0x59, 0x6d, 0x73, 0x56, 0x55, - 0x25, 0x2c, 0x38, 0x4a, 0x3b, 0x4e, 0x78, 0x46, - 0x54, 0x6e, 0x6d, 0x4f, 0x47, 0x4f, 0x4f, 0x5a, - 0x67, 0x77, 0x39, 0x66, 0x28, 0x29, 0x4e, 0x43, - 0x55, 0x6e, 0x60, 0x59, 0x28, 0x3b, 0x65, 0x62, - 0x61, 0x5a, 0x29, 0x6e, 0x79, 0x60, 0x41, 0x53, - 0x2f, 0x5d, 0x44, 0x36, 0x7b, 0x3e, 0x7c, 0x2b, - 0x77, 0x36, 0x70, 0x3f, 0x40, 0x55, 0x48, 0x67, - 0x4b, 0x4d, 0x5d, 0x51, 0x79, 0x76, 0x48, 0x4a, - 0x2d, 0x21, 0x60, 0x40, 0x46, 0x55, 0x7a, 0x60, - 0x22, 0x25, 0x3f, 0x4b, 0x54, 0x6a, 0x6a, 0x3c, - 0x77, 0x22, 0x5b, 0x43, 0x67, 0x58, 0x71, 0x22, - 0x79, 0x4b, 0x32, 0x61, 0x44, 0x4d, 0x6f, 0x42, - 0x33, 0x2d, 0x53, 0x35, 0x3d, 0x6f, 0x57, 0x48, - 0x33, 0x3b, 0x5a, 0x53, 0x3f, 0x4e, 0x3f, 0x6b, - 0x4c, 0x27, 0x26, 0x3b, 0x73, 0x49, 0x22, 0x55, - 0x79, 0x2f, 0x47, 0x2f, 0x55, 0x5a, 0x7a, 0x71, - 0x6c, 0x31, 0x43, 0x40, 0x56, 0x7b, 0x21, 0x7a, - 0x6d, 0x4c, 0x43, 0x5e, 0x38, 0x47, 0x29, 0x38, - 0x62, 0x49, 0x45, 0x78, 0x70, 0x2b, 0x2e, 0x65, - 0x47, 0x71, 0x58, 0x79, 0x39, 0x67, 0x7d, 0x6d, - 0x6a, 0x67, 0x4a, 0x71, 0x27, 0x35, 0x2a, 0x4c, - 0x3e, 0x58, 0x55, 0x30, 0x4d, 0x75, 0x77, 0x48, - 0x5f, 0x4b, 0x59, 0x34, 0x65, 0x68, 0x57, 0x59, - 0x63, 0x23, 0x47, 0x38, 0x47, 0x5e, 0x56, 0x28, - 0x79, 0x58, 0x3e, 0x39, 0x66, 0x77, 0x67, 0x33, - 0x29, 0x61, 0x24, 0x7d, 0x37, 0x44, 0x37, 0x67, - 0x3a, 0x58, 0x76, 0x21, 0x51, 0x59, 0x61, 0x73, - 0x66, 0x75, 0x71, 0x53, 0x4d, 0x24, 0x2d, 0x4b, - 0x29, 0x30, 0x32, 0x26, 0x59, 0x64, 0x27, 0x55, - 0x2c, 0x5a, 0x4c, 0x3c, 0x6c, 0x53, 0x56, 0x4b, - 0x3e, 0x55, 0x2e, 0x44, 0x38, 0x6b, 0x47, 0x76, - 0x2d, 0x2c, 0x3f, 0x4d, 0x22, 0x7b, 0x6d, 0x61, - 0x34, 0x6b, 0x50, 0x73, 0x28, 0x6d, 0x41, 0x71, - 0x21, 0x76, 0x52, 0x2a, 0x6d, 0x53, 0x2a, 0x74, - 0x28, 0x27, 0x62, 0x2a, 0x66, 0x25, 0x6e, 0x5e, - 0x37, 0x4f, 0x27, 0x72, 0x28, 0x47, 0x63, 0x6e, - 0x5a, 0x6a, 0x41, 0x35, 0x3a, 0x42, 0x3f, 0x27, - 0x75, 0x3e, 0x26, 0x3e, 0x6b, 0x55, 0x59, 0x60, - 0x24, 0x70, 0x49, 0x3c, 0x4e, 0x2c, 0x39, 0x7a, - 0x36, 0x6c, 0x27, 0x3e, 0x6a, 0x4a, 0x59, 0x5a, - 0x3e, 0x21, 0x73, 0x4e, 0x59, 0x6e, 0x3d, 0x32, - 0x27, 0x45, 0x49, 0x58, 0x7d, 0x37, 0x39, 0x77, - 0x28, 0x51, 0x79, 0x54, 0x2b, 0x78, 0x46, 0x5a, - 0x21, 0x75, 0x33, 0x21, 0x63, 0x5a, 0x7b, 0x3e, - 0x33, 0x4f, 0x67, 0x75, 0x3a, 0x50, 0x48, 0x60, - 0x26, 0x64, 0x76, 0x5c, 0x42, 0x5c, 0x72, 0x38, - 0x6c, 0x52, 0x21, 0x2b, 0x25, 0x6b, 0x7c, 0x6b, - 0x2d, 0x5e, 0x63, 0x2a, 0x4c, 0x26, 0x5b, 0x4c, - 0x58, 0x52, 0x51, 0x55, 0x31, 0x79, 0x6c, 0x53, - 0x62, 0x3a, 0x36, 0x46, 0x7a, 0x29, 0x27, 0x78, - 0x1a, 0xbf, 0x49, 0x74, 0x68, 0x24, 0x51, 0x44, - 0x5b, 0x3e, 0x34, 0x44, 0x29, 0x5e, 0x4f, 0x2a, - 0xe9, 0x3f, 0xf8, 0xff, 0xff, 0x52, 0x7d, 0x47, - 0x67, 0x40, 0x27, 0x5e, 0x47, 0x46, 0x6d, 0x72, - 0x5d, 0x49, 0x26, 0x45, 0x33, 0x6b, 0x4d, 0x4a, - 0x6f, 0x62, 0x60, 0x45, 0x62, 0x27, 0x27, 0x7d, - 0x6a, 0x41, 0x2c, 0x6c, 0x5b, 0x2a, 0x2b, 0x36, - 0x29, 0x58, 0x7a, 0x4c, 0x6e, 0x2d, 0x74, 0x5c, - 0x38, 0x22, 0x5f, 0x49, 0x63, 0x43, 0x5b, 0x67 - }; - uint32_t request2_len = sizeof(request2); - - TcpSession ssn; - Packet *p[2]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|af, 26, d0|\"; distance:0; content:\"|80 98 6d|\"; " - "distance:2; within:3; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 2; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if ((PacketAlertCheck(p[0], 1))) { - printf("sid 1 matched but shouldn't have for packet 0: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if ((PacketAlertCheck(p[1], 1))) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 2); - return result; -#else - return 1; -#endif -} - -/* Disabled because of bug_753. Would be enabled, once we rewrite - * dce parser */ -#if 0 - -/** - * \test Test the working of detection engien with respect to dce keywords. - */ -int DcePayloadTest13(void) -{ - int result = 0; - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x2c, 0xfd, 0xb5, 0x00, 0x40, 0xaa, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x02, - }; - uint32_t request1_len = sizeof(request1); - - uint8_t response1[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - uint32_t response1_len = sizeof(response1); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0xa4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf6, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x5c, 0x00, 0x5c, 0x00, - 0xa8, 0xb9, 0x14, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00, - 0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00, - 0x5c, 0x00, 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, - 0x72, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, - 0x66, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x57, 0x00, - 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x6f, 0x00, - 0x77, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x43, 0x00, - 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, - 0x6e, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00, - 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, - 0x6e, 0x00, 0x5c, 0x00, 0x52, 0x00, 0x75, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - }; - uint32_t request2_len = sizeof(request2); - - uint8_t response2[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x00, 0x00, 0x00, 0x00, - }; - uint32_t response2_len = sizeof(response2); - - uint8_t request3[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xf7, 0x72, 0x28, 0x9c, - 0xf0, 0x57, 0xd8, 0x11, 0xb0, 0x05, 0x00, 0x0c, - 0x29, 0x87, 0xea, 0xe9, 0x0c, 0x00, 0x0c, 0x00, - 0x98, 0xda, 0x14, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x4f, 0x00, 0x73, 0x00, 0x61, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x54, 0x00, - 0x4f, 0x00, 0x53, 0x00, 0x41, 0x00, 0x33, 0x00, - 0x32, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x58, 0x00, - 0x45, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - }; - uint32_t request3_len = sizeof(request3); - - uint8_t response3[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - uint32_t response3_len = sizeof(response3); - - TcpSession ssn; - Packet *p[8]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|00 02|\"; sid:1;)"; - char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|00 75|\"; sid:2;)"; - char *sig3 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|00 18|\"; sid:3;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - /* let the 7 and the 8th packet be dummy packets the client sends to the server */ - for (i = 0; i < 8; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - p[1]->flowflags |= FLOW_PKT_TOCLIENT; - p[1]->flowflags &=~ FLOW_PKT_TOSERVER; - p[3]->flowflags |= FLOW_PKT_TOCLIENT; - p[3]->flowflags &=~ FLOW_PKT_TOSERVER; - p[5]->flowflags |= FLOW_PKT_TOCLIENT; - p[5]->flowflags &=~ FLOW_PKT_TOSERVER; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, sig1); - if (s == NULL) - goto end; - s = de_ctx->sig_list->next = SigInit(de_ctx, sig2); - if (s == NULL) - goto end; - s = de_ctx->sig_list->next->next = SigInit(de_ctx, sig3); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if (!PacketAlertCheck(p[0], 1) || PacketAlertCheck(p[0], 2) || PacketAlertCheck(p[0], 3)) { - printf("sid 1 didn't match but should have for packet 0: "); - goto end; - } - - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[6]); - if (PacketAlertCheck(p[6], 1) || PacketAlertCheck(p[6], 2) || PacketAlertCheck(p[6], 3)) { - printf("sid 1 matched but shouldn't have for packet 6: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, response1, response1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if (PacketAlertCheck(p[1], 1) || PacketAlertCheck(p[1], 2) || PacketAlertCheck(p[1], 3)) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - /* we should have a match for the sig once again for the same flow, since - * the detection engine state for the flow has been reset because of a - * fresh transaction */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[2]); - if (PacketAlertCheck(p[2], 1) || !PacketAlertCheck(p[2], 2) || PacketAlertCheck(p[2], 3)) { - printf("sid 1 didn't match but should have for packet 2: "); - goto end; - } - - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[7]); - if (PacketAlertCheck(p[7], 1) || PacketAlertCheck(p[7], 2) || PacketAlertCheck(p[7], 3)) { - printf("sid 1 matched but shouldn't have for packet 7: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, response2, response2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[3]); - if (PacketAlertCheck(p[3], 1) || PacketAlertCheck(p[3], 2) || PacketAlertCheck(p[3], 3)) { - printf("sid 1 matched but shouldn't have for packet 3: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request3, request3_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - /* we should have a match for the sig once again for the same flow, since - * the detection engine state for the flow has been reset because of a - * fresh transaction */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[4]); - if (PacketAlertCheck(p[4], 1) || PacketAlertCheck(p[4], 2) || !PacketAlertCheck(p[4], 3)) { - printf("sid 1 didn't match but should have for packet 4: "); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, response3, response3_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[5]); - if (PacketAlertCheck(p[5], 1) || PacketAlertCheck(p[5], 2) || PacketAlertCheck(p[5], 3)) { - printf("sid 1 matched but shouldn't have for packet 5: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 8); - return result; -} - -/** - * \test Test the working of detection engien with respect to dce keywords. - */ -int DcePayloadTest14(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x76, 0x7e, 0x32, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x5c, 0x00, 0x5c, 0x00, 0x31, 0x00, 0x37, 0x00, - 0x31, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x31, 0x00, - 0x2e, 0x00, 0x38, 0x00, 0x34, 0x00, 0x2e, 0x00, - 0x36, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x84, 0xf9, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x14, 0xfa, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t request1_len = sizeof(request1); - - uint8_t bind[] = { - 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x81, 0xbb, 0x7a, 0x36, 0x44, 0x98, 0xf1, 0x35, - 0xad, 0x32, 0x98, 0xf0, 0x38, 0x00, 0x10, 0x03, - 0x02, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, - 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00, - 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_len = sizeof(bind); - - uint8_t bind_ack[] = { - 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xb8, 0x10, 0xb8, 0x10, 0x74, 0x73, 0x00, 0x00, - 0x0d, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, - 0x6e, 0x74, 0x73, 0x76, 0x63, 0x73, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, - 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, - 0x02, 0x00, 0x00, 0x00 - }; - uint32_t bind_ack_len = sizeof(bind_ack); - - uint8_t request2[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, - 0x64, 0x7e, 0x32, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x5c, 0x5c, 0x31, 0x37, 0x31, 0x2e, 0x37, 0x31, - 0x2e, 0x38, 0x34, 0x2e, 0x36, 0x37, 0x00, 0x8a, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x0f, 0x00 - }; - uint32_t request2_len = sizeof(request2); - - uint8_t response2[] = { - 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd2, 0xc4, 0x88, 0x14, - 0xef, 0x31, 0xbb, 0x4d, 0xa8, 0x13, 0xb7, 0x1b, - 0x47, 0x49, 0xb5, 0xd7, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t response2_len = sizeof(response2); - - TcpSession ssn; - Packet *p[6]; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - int i = 0; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|7f 01|\"; sid:1;)"; - char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|3f 00|\"; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - for (i = 0; i < 6; i++) { - p[i] = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p[i]->flow = &f; - p[i]->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p[i]->flowflags |= FLOW_PKT_TOSERVER; - p[i]->flowflags |= FLOW_PKT_ESTABLISHED; - } - p[3]->flowflags |= FLOW_PKT_TOCLIENT; - p[3]->flowflags &=~ FLOW_PKT_TOSERVER; - p[5]->flowflags |= FLOW_PKT_TOCLIENT; - p[5]->flowflags &=~ FLOW_PKT_TOSERVER; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, sig1); - if (s == NULL) - goto end; - s = de_ctx->sig_list->next = SigInit(de_ctx, sig2); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[0]); - if (!PacketAlertCheck(p[0], 1) || PacketAlertCheck(p[0], 2)) { - printf("sid 1 didn't match but should have for packet 0: "); - goto end; - } - - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[1]); - if (PacketAlertCheck(p[1], 1) || PacketAlertCheck(p[1], 2)) { - printf("sid 1 matched but shouldn't have for packet 1: "); - goto end; - } - - /* bind */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, bind, bind_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[2]); - if (PacketAlertCheck(p[2], 1) || PacketAlertCheck(p[2], 2)) { - printf("sid 1 matched but shouldn't have for packet 2: "); - goto end; - } - - /* bind_ack. A new transaction initiation */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, bind_ack, bind_ack_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[3]); - if (PacketAlertCheck(p[3], 1) || PacketAlertCheck(p[3], 2)) { - printf("sid 1 matched but shouldn't have for packet 3: "); - goto end; - } - - /* we should have a match for the sig once again for the same flow, since - * the detection engine state for the flow has been reset because of a - * fresh transaction */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request2, request2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[4]); - if (PacketAlertCheck(p[4], 1) || !PacketAlertCheck(p[4], 2)) { - printf("sid 1 didn't match but should have for packet 4: "); - goto end; - } - - /* response */ - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOCLIENT, response2, response2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p[5]); - if (PacketAlertCheck(p[5], 1) || PacketAlertCheck(p[5], 2)) { - printf("sid 1 matched but shouldn't have for packet 5: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(p, 6); - return result; -} - -#endif - -/** - * \test Test the working of byte_test endianness. - */ -int DcePayloadTest15(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x76, 0x7e, 0x32, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x5c, 0x00, 0x5c, 0x00, 0x31, 0x00, 0x37, 0x00, - 0x31, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x31, 0x00, - 0x2e, 0x00, 0x38, 0x00, 0x34, 0x00, 0x2e, 0x00, - 0x36, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x84, 0xf9, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x14, 0xfa, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_test:2,=,14080,0,relative,dce; sid:1;)"; - char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_test:2,=,46,5,relative,dce; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - s->next = SigInit(de_ctx, sig2); - if (s->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have for packet: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test the working of byte_test endianness. - */ -int DcePayloadTest16(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x76, 0x7e, 0x32, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x5c, 0x00, 0x5c, 0x00, 0x31, 0x00, 0x37, 0x00, - 0x31, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x31, 0x00, - 0x2e, 0x00, 0x38, 0x00, 0x34, 0x00, 0x2e, 0x00, - 0x36, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x84, 0xf9, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x14, 0xfa, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_test:2,=,55,0,relative; sid:1;)"; - char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_test:2,=,11776,5,relative; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - s->next = SigInit(de_ctx, sig2); - if (s->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have for packet: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test the working of byte_test endianness. - */ -int DcePayloadTest17(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x76, 0x7e, 0x32, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x5c, 0x00, 0x5c, 0x00, 0x31, 0x00, 0x37, 0x00, - 0x31, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x31, 0x00, - 0x2e, 0x00, 0x38, 0x00, 0x34, 0x00, 0x2e, 0x00, - 0x36, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x84, 0xf9, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x14, 0xfa, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_test:2,=,55,0,relative,big; sid:1;)"; - char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_test:2,=,46,5,relative,little; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - s->next = SigInit(de_ctx, sig2); - if (s->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have for packet: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test the working of byte_jump endianness. - */ -int DcePayloadTest18(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x76, 0x7e, 0x32, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x5c, 0x00, 0x5c, 0x00, 0x31, 0x03, 0x00, 0x03, - 0x00, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x31, 0x00, - 0x2e, 0x00, 0x38, 0x00, 0x34, 0x00, 0x2e, 0x00, - 0x36, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x84, 0xf9, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x14, 0xfa, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_jump:2,0,relative,dce; byte_test:2,=,46,0,relative,dce; sid:1;)"; - char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_jump:2,2,relative,dce; byte_test:2,=,14080,0,relative; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - s->next = SigInit(de_ctx, sig2); - if (s->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have for packet: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test the working of byte_jump endianness. - */ -int DcePayloadTest19(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x76, 0x7e, 0x32, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x5c, 0x00, 0x5c, 0x00, 0x31, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x31, 0x00, - 0x2e, 0x00, 0x38, 0x00, 0x34, 0x00, 0x2e, 0x00, - 0x36, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x84, 0xf9, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x14, 0xfa, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_jump:2,0,relative; byte_test:2,=,46,0,relative,dce; sid:1;)"; - char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_jump:2,2,relative; byte_test:2,=,14080,0,relative; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - s->next = SigInit(de_ctx, sig2); - if (s->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have for packet: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test the working of byte_jump endianness. - */ -int DcePayloadTest20(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x76, 0x7e, 0x32, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x5c, 0x00, 0x5c, 0x00, 0x31, 0x00, 0x03, 0x03, - 0x00, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x31, 0x00, - 0x2e, 0x00, 0x38, 0x00, 0x34, 0x00, 0x2e, 0x00, - 0x36, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x84, 0xf9, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x14, 0xfa, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_jump:2,0,relative,big; byte_test:2,=,46,0,relative,dce; sid:1;)"; - char *sig2 = "alert tcp any any -> any any " - "(dce_stub_data; content:\"|5c 00 5c 00 31|\"; distance:0; " - "byte_jump:2,2,little,relative; byte_test:2,=,14080,0,relative; sid:2;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - s->next = SigInit(de_ctx, sig2); - if (s->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have for packet: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test the working of consecutive relative matches. - */ -int DcePayloadTest21(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x69, 0x73, /* "now this" */ - 0x20, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x62, /* " is is b" */ - 0x69, 0x67, 0x20, 0x62, 0x69, 0x67, 0x20, 0x73, /* "ig big s" */ - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f, /* "tring no" */ - 0x77 }; /* "w" */ - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(msg:\"testing dce consecutive relative matches\"; dce_stub_data; " - "content:\"this\"; distance:0; content:\"is\"; within:6; content:\"big\"; within:8; " - "content:\"string\"; within:8; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test the working of consecutive relative matches. - */ -int DcePayloadTest22(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x69, 0x73, /* "now this" */ - 0x20, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x69, /* " is is i" */ - 0x73, 0x20, 0x62, 0x69, 0x67, 0x20, 0x62, 0x69, /* "s big bi" */ - 0x67, 0x20, 0x62, 0x69, 0x67, 0x20, 0x73, 0x74, /* "g big st" */ - 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6e, 0x6f, 0x77 }; /* "ring now" */ - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(msg:\"testing dce consecutive relative matches\"; dce_stub_data; " - "content:\"this\"; distance:0; content:\"is\"; within:9; content:\"big\"; within:12; " - "content:\"string\"; within:8; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test the working of consecutive relative matches. - */ -int DcePayloadTest23(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x74, 0x68, 0x69, /* "this thi" */ - 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x69, 0x73, /* "s now is" */ - 0x20, 0x69, 0x73, 0x20, 0x20, 0x20, 0x20, 0x20, /* " is " */ - 0x62, 0x69, 0x67, 0x20, 0x73, 0x74, 0x72, 0x69, /* "big stri" */ - 0x6e, 0x67, 0x20, 0x6e, 0x6f, 0x77 }; /* "ng now" */ - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(msg:\"testing dce consecutive relative matches\"; dce_stub_data; " - "content:\"now\"; distance:0; content:\"this\"; distance:-20; " - "content:\"is\"; within:12; content:\"big\"; within:8; " - "content:\"string\"; within:8; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; content:\"two\"; " - "content:\"three\"; within:10; " - "content:\"four\"; distance:4; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] != NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "four", 4) == 0); - if (result == 0) - goto end; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_stub_data; " - "pkt_data; " - "content:\"one\"; " - "content:\"two\"; " - "content:\"three\"; within:5; " - "content:\"four\"; distance:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] != NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("one failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("four failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "four", 4) == 0); - if (result == 0) - goto end; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_stub_data; " - "content:\"one\"; distance:10; within:5; " - "content:\"two\"; within:5;" - "content:\"three\"; within:5; " - "content:\"four\"; distance:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] != NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("one failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("four failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "four", 4) == 0); - if (result == 0) - goto end; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest28(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_stub_data; " - "content:\"one\"; distance:10; within:5; " - "content:\"two\"; within:5;" - "pkt_data; " - "content:\"three\";" - "content:\"four\";" - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("one failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("four failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "four", 4) == 0); - if (result == 0) - goto end; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest29(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectPcreData *pd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_stub_data; " - "pkt_data; " - "pcre:/boom/; " - "content:\"one\"; distance:10; within:5; " - "content:\"two\"; within:5;" - "content:\"three\";" - "content:\"four\";" - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] != NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_PCRE) { - result = 0; - goto end; - } - pd = (DetectPcreData *)sm->ctx; - if (pd->flags & DETECT_PCRE_RAWBYTES || - pd->flags & DETECT_PCRE_RELATIVE) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("one failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("four failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "four", 4) == 0); - if (result == 0) - goto end; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest30(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectBytejumpData *bd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_stub_data; " - "pkt_data; " - "byte_jump:2,5; " - "content:\"one\"; distance:10; within:5; " - "content:\"two\"; within:5;" - "content:\"three\";" - "content:\"four\";" - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] != NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bd = (DetectBytejumpData *)sm->ctx; - if (bd->flags & DETECT_BYTEJUMP_BEGIN || - bd->flags & DETECT_BYTEJUMP_LITTLE || - bd->flags & DETECT_BYTEJUMP_BIG || - bd->flags & DETECT_BYTEJUMP_STRING || - bd->flags & DETECT_BYTEJUMP_RELATIVE || - bd->flags & DETECT_BYTEJUMP_ALIGN || - bd->flags & DETECT_BYTEJUMP_DCE ) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("one failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("four failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "four", 4) == 0); - if (result == 0) - goto end; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest31(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectBytejumpData *bd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_stub_data; " - "byte_jump:2,5,relative; " - "content:\"one\"; distance:10; within:5; " - "content:\"two\"; within:5;" - "pkt_data; " - "content:\"three\";" - "content:\"four\";" - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bd = (DetectBytejumpData *)sm->ctx; - if (bd->flags & DETECT_BYTEJUMP_BEGIN || - bd->flags & DETECT_BYTEJUMP_LITTLE || - bd->flags & DETECT_BYTEJUMP_BIG || - bd->flags & DETECT_BYTEJUMP_STRING || - !(bd->flags & DETECT_BYTEJUMP_RELATIVE) || - bd->flags & DETECT_BYTEJUMP_ALIGN || - bd->flags & DETECT_BYTEJUMP_DCE ) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("one failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("four failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "four", 4) == 0); - if (result == 0) - goto end; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest32(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectBytejumpData *bd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_stub_data; " - "byte_jump:2,5,relative; " - "content:\"one\"; distance:10; within:5; " - "content:\"two\"; within:5;" - "pkt_data; " - "content:\"three\";" - "content:\"four\"; within:4; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bd = (DetectBytejumpData *)sm->ctx; - if (bd->flags & DETECT_BYTEJUMP_BEGIN || - bd->flags & DETECT_BYTEJUMP_LITTLE || - bd->flags & DETECT_BYTEJUMP_BIG || - bd->flags & DETECT_BYTEJUMP_STRING || - !(bd->flags & DETECT_BYTEJUMP_RELATIVE) || - bd->flags & DETECT_BYTEJUMP_ALIGN || - bd->flags & DETECT_BYTEJUMP_DCE ) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("one failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("four failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "four", 4) == 0); - if (result == 0) - goto end; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest33(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectPcreData *pd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_stub_data; " - "pcre:/boom/R; " - "content:\"one\"; distance:10; within:5; " - "content:\"two\"; within:5;" - "pkt_data; " - "content:\"three\";" - "content:\"four\"; distance:5;" - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_PCRE) { - result = 0; - goto end; - } - pd = (DetectPcreData *)sm->ctx; - if ( pd->flags & DETECT_PCRE_RAWBYTES || - !(pd->flags & DETECT_PCRE_RELATIVE)) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("one failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("four failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "four", 4) == 0); - if (result == 0) - goto end; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest34(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectPcreData *pd = NULL; - DetectBytejumpData *bd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "dce_opnum:10; dce_stub_data; " - "pcre:/boom/R; " - "byte_jump:1,2,relative,align,dce; " - "content:\"one\"; within:4; distance:8; " - "pkt_data; " - "content:\"two\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_PCRE) { - result = 0; - goto end; - } - pd = (DetectPcreData *)sm->ctx; - if ( pd->flags & DETECT_PCRE_RAWBYTES || - !(pd->flags & DETECT_PCRE_RELATIVE)) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bd = (DetectBytejumpData *)sm->ctx; - if (bd->flags & DETECT_BYTEJUMP_BEGIN || - bd->flags & DETECT_BYTEJUMP_LITTLE || - bd->flags & DETECT_BYTEJUMP_BIG || - bd->flags & DETECT_BYTEJUMP_STRING || - !(bd->flags & DETECT_BYTEJUMP_RELATIVE) || - !(bd->flags & DETECT_BYTEJUMP_ALIGN) || - !(bd->flags & DETECT_BYTEJUMP_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest35(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectBytetestData *bd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "dce_opnum:10; dce_stub_data; " - "byte_test:1,=,0,0,relative,dce; " - "pkt_data; " - "content:\"one\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_BYTETEST) { - result = 0; - goto end; - } - bd = (DetectBytetestData *)sm->ctx; - if (bd->flags & DETECT_BYTETEST_LITTLE || - bd->flags & DETECT_BYTETEST_BIG || - bd->flags & DETECT_BYTETEST_STRING || - !(bd->flags & DETECT_BYTEJUMP_RELATIVE) || - !(bd->flags & DETECT_BYTETEST_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest36(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectIsdataatData *isd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "dce_opnum:10; dce_stub_data; " - "isdataat:10,relative; " - "content:\"one\"; within:4; distance:8; " - "pkt_data; " - "content:\"two\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_ISDATAAT) { - result = 0; - goto end; - } - isd = (DetectIsdataatData *)sm->ctx; - if ( isd->flags & ISDATAAT_RAWBYTES || - !(isd->flags & ISDATAAT_RELATIVE)) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest37(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectBytejumpData *bjd = NULL; - DetectBytetestData *btd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "dce_opnum:10; dce_stub_data; " - "byte_jump:1,2,relative,align,dce; " - "byte_test:1,=,2,0,relative,dce; " - "pkt_data; " - "content:\"one\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags & DETECT_BYTEJUMP_BEGIN || - bjd->flags & DETECT_BYTEJUMP_LITTLE || - bjd->flags & DETECT_BYTEJUMP_BIG || - bjd->flags & DETECT_BYTEJUMP_STRING || - !(bjd->flags & DETECT_BYTEJUMP_RELATIVE) || - !(bjd->flags & DETECT_BYTEJUMP_ALIGN) || - !(bjd->flags & DETECT_BYTEJUMP_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTETEST) { - result = 0; - goto end; - } - btd = (DetectBytetestData *)sm->ctx; - if (btd->flags & DETECT_BYTETEST_LITTLE || - btd->flags & DETECT_BYTETEST_BIG || - btd->flags & DETECT_BYTETEST_STRING || - !(btd->flags & DETECT_BYTETEST_RELATIVE) || - !(btd->flags & DETECT_BYTETEST_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest38(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectPcreData *pd = NULL; - DetectBytejumpData *bjd = NULL; - DetectBytetestData *btd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "dce_opnum:10; dce_stub_data; " - "pcre:/boom/R; " - "byte_jump:1,2,relative,align,dce; " - "byte_test:1,=,2,0,relative,dce; " - "pkt_data; " - "content:\"one\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_PCRE) { - result = 0; - goto end; - } - pd = (DetectPcreData *)sm->ctx; - if ( pd->flags & DETECT_PCRE_RAWBYTES || - !(pd->flags & DETECT_PCRE_RELATIVE)) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags & DETECT_BYTEJUMP_BEGIN || - bjd->flags & DETECT_BYTEJUMP_LITTLE || - bjd->flags & DETECT_BYTEJUMP_BIG || - bjd->flags & DETECT_BYTEJUMP_STRING || - !(bjd->flags & DETECT_BYTEJUMP_RELATIVE) || - !(bjd->flags & DETECT_BYTEJUMP_ALIGN) || - !(bjd->flags & DETECT_BYTEJUMP_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_BYTETEST) { - result = 0; - goto end; - } - btd = (DetectBytetestData *)sm->ctx; - if (btd->flags & DETECT_BYTETEST_LITTLE || - btd->flags & DETECT_BYTETEST_BIG || - btd->flags & DETECT_BYTETEST_STRING || - !(btd->flags & DETECT_BYTETEST_RELATIVE) || - !(btd->flags & DETECT_BYTETEST_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest39(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "dce_opnum:10; dce_stub_data; " - "content:\"two\"; within:4; distance:8; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest40(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectBytetestData *btd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "dce_opnum:10; dce_stub_data; " - "content:\"one\"; within:10; " - "content:\"two\"; distance:20; within:30; " - "byte_test:1,=,2,0,relative,dce; " - "pkt_data; " - "content:\"three\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_BYTETEST) { - result = 0; - goto end; - } - btd = (DetectBytetestData *)sm->ctx; - if (btd->flags & DETECT_BYTETEST_LITTLE || - btd->flags & DETECT_BYTETEST_BIG || - btd->flags & DETECT_BYTETEST_STRING || - !(btd->flags & DETECT_BYTETEST_RELATIVE) || - !(btd->flags & DETECT_BYTETEST_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest41(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectBytetestData *btd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "dce_opnum:10; dce_stub_data; " - "content:\"one\"; within:10; " - "pkt_data; " - "content:\"two\"; " - "byte_test:1,=,2,0,relative,dce; " - "content:\"three\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_BYTETEST) { - result = 0; - goto end; - } - btd = (DetectBytetestData *)sm->ctx; - if (btd->flags & DETECT_BYTETEST_LITTLE || - btd->flags & DETECT_BYTETEST_BIG || - btd->flags & DETECT_BYTETEST_STRING || - !(btd->flags & DETECT_BYTETEST_RELATIVE) || - !(btd->flags & DETECT_BYTETEST_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "three", 5) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test the working of consecutive relative matches with a negated content. - */ -int DcePayloadTest42(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x77, 0x65, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, /* "we need " */ - 0x74, 0x6f, 0x20, 0x66, 0x69, 0x78, 0x20, 0x74, /* "to fix t" */ - 0x68, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, /* "his and " */ - 0x79, 0x65, 0x73, 0x20, 0x66, 0x69, 0x78, 0x20, /* "yes fix " */ - 0x74, 0x68, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x77 /* "this now" */ - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(msg:\"testing dce consecutive relative matches\"; dce_stub_data; " - "content:\"fix\"; distance:0; content:\"this\"; within:6; " - "content:!\"and\"; distance:0; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 matched but shouldn't have for packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test the working of consecutive relative pcres. - */ -int DcePayloadTest43(void) -{ - int result = 0; - - uint8_t request1[] = { - 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, - 0x61, 0x20, 0x73, 0x75, 0x70, 0x65, 0x72, 0x20, - 0x64, 0x75, 0x70, 0x65, 0x72, 0x20, 0x6e, 0x6f, - 0x76, 0x61, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x75, - 0x70, 0x65, 0x72, 0x20, 0x6e, 0x6f, 0x76, 0x61, - 0x20, 0x6e, 0x6f, 0x77 - }; - uint32_t request1_len = sizeof(request1); - - TcpSession ssn; - Packet *p = NULL; - ThreadVars tv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - int r; - - char *sig1 = "alert tcp any any -> any any " - "(msg:\"testing dce consecutive relative matches\"; dce_stub_data; " - "pcre:/super/R; content:\"nova\"; within:7; sid:1;)"; - - Signature *s; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_DCERPC; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - s = de_ctx->sig_list; - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* request 1 */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_DCERPC, STREAM_TOSERVER, request1, request1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* detection phase */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if ( !(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest44(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectIsdataatData *isd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "dce_opnum:10; dce_stub_data; " - "isdataat:10,relative; " - "content:\"one\"; within:4; distance:8; " - "pkt_data; " - "content:\"two\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_ISDATAAT) { - result = 0; - goto end; - } - isd = (DetectIsdataatData *)sm->ctx; - if ( isd->flags & ISDATAAT_RAWBYTES || - !(isd->flags & ISDATAAT_RELATIVE)) { - result = 0; - goto end; - } - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - !(data->flags & DETECT_CONTENT_WITHIN) || - !(data->flags & DETECT_CONTENT_DISTANCE) || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_RELATIVE_NEXT || - data->flags & DETECT_CONTENT_NEGATED ) { - result = 0; - printf("two failed\n"); - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_RELATIVE_NEXT || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("three failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("two failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest45(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectBytejumpData *bjd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "content:\"one\"; " - "dce_opnum:10; dce_stub_data; " - "byte_jump:1,2,relative,align,dce; " - "pkt_data; " - "content:\"two\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_BYTEJUMP) { - result = 0; - goto end; - } - bjd = (DetectBytejumpData *)sm->ctx; - if (bjd->flags & DETECT_BYTEJUMP_BEGIN || - bjd->flags & DETECT_BYTEJUMP_LITTLE || - bjd->flags & DETECT_BYTEJUMP_BIG || - bjd->flags & DETECT_BYTEJUMP_STRING || - !(bjd->flags & DETECT_BYTEJUMP_RELATIVE) || - !(bjd->flags & DETECT_BYTEJUMP_ALIGN) || - !(bjd->flags & DETECT_BYTEJUMP_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_RELATIVE_NEXT || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_RELATIVE_NEXT || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("two failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DcePayloadParseTest46(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - SigMatch *sm = NULL; - DetectContentData *data = NULL; - DetectBytetestData *btd = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:12345678-1234-1234-1234-123456789012; " - "content:\"one\"; " - "dce_opnum:10; dce_stub_data; " - "byte_test:1,=,2,0,relative,dce; " - "pkt_data; " - "content:\"two\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - result = 0; - goto end; - } - - sm = s->sm_lists[DETECT_SM_LIST_DMATCH]; - if (sm->type != DETECT_BYTETEST) { - result = 0; - goto end; - } - btd = (DetectBytetestData *)sm->ctx; - if (btd->flags & DETECT_BYTETEST_LITTLE || - btd->flags & DETECT_BYTETEST_BIG || - btd->flags & DETECT_BYTETEST_STRING || - !(btd->flags & DETECT_BYTETEST_RELATIVE) || - !(btd->flags & DETECT_BYTETEST_DCE) ) { - result = 0; - printf("one failed\n"); - goto end; - } - - result &= (sm->next == NULL); - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_RELATIVE_NEXT || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("one failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "one", 3) == 0); - if (result == 0) - goto end; - - sm = sm->next; - if (sm->type != DETECT_CONTENT) { - result = 0; - goto end; - } - data = (DetectContentData *)sm->ctx; - if (data->flags & DETECT_CONTENT_RAWBYTES || - data->flags & DETECT_CONTENT_NOCASE || - data->flags & DETECT_CONTENT_WITHIN || - data->flags & DETECT_CONTENT_DISTANCE || - data->flags & DETECT_CONTENT_FAST_PATTERN || - data->flags & DETECT_CONTENT_RELATIVE_NEXT || - data->flags & DETECT_CONTENT_NEGATED ) { - printf("two failed\n"); - result = 0; - goto end; - } - result &= (strncmp((char *)data->content, "two", 3) == 0); - if (result == 0) - goto end; - - result &= (sm->next == NULL); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -#endif /* UNITTESTS */ - -void DcePayloadRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DcePayloadTest01", DcePayloadTest01, 1); - UtRegisterTest("DcePayloadTest02", DcePayloadTest02, 1); - UtRegisterTest("DcePayloadTest03", DcePayloadTest03, 1); - UtRegisterTest("DcePayloadTest04", DcePayloadTest04, 1); - UtRegisterTest("DcePayloadTest05", DcePayloadTest05, 1); - UtRegisterTest("DcePayloadTest06", DcePayloadTest06, 1); - UtRegisterTest("DcePayloadTest07", DcePayloadTest07, 1); - UtRegisterTest("DcePayloadTest08", DcePayloadTest08, 1); - UtRegisterTest("DcePayloadTest09", DcePayloadTest09, 1); - UtRegisterTest("DcePayloadTest10", DcePayloadTest10, 1); - UtRegisterTest("DcePayloadTest11", DcePayloadTest11, 1); - UtRegisterTest("DcePayloadTest12", DcePayloadTest12, 1); - /* Disabled because of bug_753. Would be enabled, once we rewrite - * dce parser */ -#if 0 - UtRegisterTest("DcePayloadTest13", DcePayloadTest13, 1); - UtRegisterTest("DcePayloadTest14", DcePayloadTest14, 1); -#endif - UtRegisterTest("DcePayloadTest15", DcePayloadTest15, 1); - UtRegisterTest("DcePayloadTest16", DcePayloadTest16, 1); - UtRegisterTest("DcePayloadTest17", DcePayloadTest17, 1); - UtRegisterTest("DcePayloadTest18", DcePayloadTest18, 1); - UtRegisterTest("DcePayloadTest19", DcePayloadTest19, 1); - UtRegisterTest("DcePayloadTest20", DcePayloadTest20, 1); - UtRegisterTest("DcePayloadTest21", DcePayloadTest21, 1); - UtRegisterTest("DcePayloadTest22", DcePayloadTest22, 1); - UtRegisterTest("DcePayloadTest23", DcePayloadTest23, 1); - - UtRegisterTest("DcePayloadParseTest25", DcePayloadParseTest25, 1); - UtRegisterTest("DcePayloadParseTest26", DcePayloadParseTest26, 1); - UtRegisterTest("DcePayloadParseTest27", DcePayloadParseTest27, 1); - UtRegisterTest("DcePayloadParseTest28", DcePayloadParseTest28, 1); - UtRegisterTest("DcePayloadParseTest29", DcePayloadParseTest29, 1); - UtRegisterTest("DcePayloadParseTest30", DcePayloadParseTest30, 1); - UtRegisterTest("DcePayloadParseTest31", DcePayloadParseTest31, 1); - UtRegisterTest("DcePayloadParseTest32", DcePayloadParseTest32, 1); - UtRegisterTest("DcePayloadParseTest33", DcePayloadParseTest33, 1); - UtRegisterTest("DcePayloadParseTest34", DcePayloadParseTest34, 1); - UtRegisterTest("DcePayloadParseTest35", DcePayloadParseTest35, 1); - UtRegisterTest("DcePayloadParseTest36", DcePayloadParseTest36, 1); - UtRegisterTest("DcePayloadParseTest37", DcePayloadParseTest37, 1); - UtRegisterTest("DcePayloadParseTest38", DcePayloadParseTest38, 1); - UtRegisterTest("DcePayloadParseTest39", DcePayloadParseTest39, 1); - UtRegisterTest("DcePayloadParseTest40", DcePayloadParseTest40, 1); - UtRegisterTest("DcePayloadParseTest41", DcePayloadParseTest41, 1); - - UtRegisterTest("DcePayloadTest42", DcePayloadTest42, 1); - UtRegisterTest("DcePayloadTest43", DcePayloadTest43, 1); - - UtRegisterTest("DcePayloadParseTest44", DcePayloadParseTest44, 1); - UtRegisterTest("DcePayloadParseTest45", DcePayloadParseTest45, 1); - UtRegisterTest("DcePayloadParseTest46", DcePayloadParseTest46, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-engine-dcepayload.h b/framework/src/suricata/src/detect-engine-dcepayload.h deleted file mode 100644 index ccc4794b..00000000 --- a/framework/src/suricata/src/detect-engine-dcepayload.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_DCEPAYLOAD_H__ -#define __DETECT_ENGINE_DCEPAYLOAD_H__ - -int DetectEngineInspectDcePayload(DetectEngineCtx *, DetectEngineThreadCtx *, - Signature *, Flow *, uint8_t, void *); - -void DcePayloadRegisterTests(void); - -#endif /* __DETECT_ENGINE_DCEPAYLOAD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-dns.c b/framework/src/suricata/src/detect-engine-dns.c deleted file mode 100644 index b08681c0..00000000 --- a/framework/src/suricata/src/detect-engine-dns.c +++ /dev/null @@ -1,163 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - * - * Based on detect-engine-uri.c - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-protos.h" -#include "app-layer-dns-common.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -/** \brief Do the content inspection & validation for a signature - * - * \param de_ctx Detection engine context - * \param det_ctx Detection engine thread context - * \param s Signature to inspect - * \param sm SigMatch to inspect - * \param f Flow - * \param flags app layer flags - * \param state App layer state - * - * \retval 0 no match - * \retval 1 match - */ -int DetectEngineInspectDnsQueryName(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, void *txv, uint64_t tx_id) -{ - DNSTransaction *tx = (DNSTransaction *)txv; - DNSQueryEntry *query = NULL; - uint8_t *buffer; - uint16_t buffer_len; - int r = 0; - - SCLogDebug("start"); - - TAILQ_FOREACH(query, &tx->query_list, next) { - SCLogDebug("tx %p query %p", tx, query); - det_ctx->discontinue_matching = 0; - det_ctx->buffer_offset = 0; - det_ctx->inspection_recursion_counter = 0; - - buffer = (uint8_t *)((uint8_t *)query + sizeof(DNSQueryEntry)); - buffer_len = query->len; - - //PrintRawDataFp(stdout, buffer, buffer_len); - - r = DetectEngineContentInspection(de_ctx, det_ctx, - s, s->sm_lists[DETECT_SM_LIST_DNSQUERYNAME_MATCH], - f, buffer, buffer_len, 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_DNSQUERY, NULL); - if (r == 1) - break; - } - return r; -} - - -/** \brief Do the content inspection & validation for a signature - * - * \param de_ctx Detection engine context - * \param det_ctx Detection engine thread context - * \param s Signature to inspect - * \param sm SigMatch to inspect - * \param f Flow - * \param flags app layer flags - * \param state App layer state - * - * \retval 0 no match - * \retval 1 match - */ -int DetectEngineInspectGenericList(ThreadVars *tv, - const DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - const Signature *s, Flow *f, const uint8_t flags, - void *alstate, void *txv, uint64_t tx_id, const int list) -{ - KEYWORD_PROFILING_SET_LIST(det_ctx, list); - - SigMatchData *smd = s->sm_arrays[list]; - SCLogDebug("running match functions, sm %p", smd); - if (smd != NULL) { - while (1) { - int match = 0; - KEYWORD_PROFILING_START; - match = sigmatch_table[smd->type]. - AppLayerTxMatch(tv, det_ctx, f, flags, alstate, txv, s, smd->ctx); - KEYWORD_PROFILING_END(det_ctx, smd->type, (match == 1)); - - if (match == 0) - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - if (match == 2) { - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } - - if (smd->is_last) - break; - smd++; - } - } - - return DETECT_ENGINE_INSPECT_SIG_MATCH; -} - -int DetectEngineInspectDnsRequest(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, void *txv, uint64_t tx_id) -{ - return DetectEngineInspectGenericList(tv, de_ctx, det_ctx, s, f, flags, - alstate, txv, tx_id, - DETECT_SM_LIST_DNSREQUEST_MATCH); -} - -int DetectEngineInspectDnsResponse(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, void *txv, uint64_t tx_id) -{ - return DetectEngineInspectGenericList(tv, de_ctx, det_ctx, s, f, flags, - alstate, txv, tx_id, - DETECT_SM_LIST_DNSRESPONSE_MATCH); -} diff --git a/framework/src/suricata/src/detect-engine-dns.h b/framework/src/suricata/src/detect-engine-dns.h deleted file mode 100644 index 801a22d4..00000000 --- a/framework/src/suricata/src/detect-engine-dns.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_DNS_H__ -#define __DETECT_ENGINE_DNS_H__ - -int DetectEngineInspectDnsQueryName(ThreadVars *, DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *, Signature *, - Flow *, uint8_t, void *, void *, uint64_t); -int DetectEngineInspectDnsRequest(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, void *txv, uint64_t tx_id); -int DetectEngineInspectDnsResponse(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, void *txv, uint64_t tx_id); - -#endif /* __DETECT_ENGINE_DNS_H__ */ diff --git a/framework/src/suricata/src/detect-engine-event.c b/framework/src/suricata/src/detect-engine-event.c deleted file mode 100644 index 6b685d70..00000000 --- a/framework/src/suricata/src/detect-engine-event.c +++ /dev/null @@ -1,412 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * - * Implements the decode-event keyword - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "detect.h" -#include "detect-parse.h" - -#include "flow-var.h" -#include "decode-events.h" - -#include "util-debug.h" - -#include "stream-tcp.h" - - -/* Need to get the DEvents[] array */ -#define DETECT_EVENTS - -#include "detect-engine-event.h" -#include "util-unittest.h" - -#define PARSE_REGEX "\\S[0-9A-z_]+[.][A-z0-9_+]+$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectEngineEventMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectEngineEventSetup (DetectEngineCtx *, Signature *, char *); -static int DetectDecodeEventSetup (DetectEngineCtx *, Signature *, char *); -static int DetectStreamEventSetup (DetectEngineCtx *, Signature *, char *); -static void DetectEngineEventFree (void *); -void EngineEventRegisterTests(void); - - -/** - * \brief Registration function for decode-event: keyword - */ -void DetectEngineEventRegister (void) -{ - sigmatch_table[DETECT_ENGINE_EVENT].name = "engine-event"; - sigmatch_table[DETECT_ENGINE_EVENT].Match = DetectEngineEventMatch; - sigmatch_table[DETECT_ENGINE_EVENT].Setup = DetectEngineEventSetup; - sigmatch_table[DETECT_ENGINE_EVENT].Free = DetectEngineEventFree; - sigmatch_table[DETECT_ENGINE_EVENT].RegisterTests = EngineEventRegisterTests; - - sigmatch_table[DETECT_DECODE_EVENT].name = "decode-event"; - sigmatch_table[DETECT_DECODE_EVENT].Match = DetectEngineEventMatch; - sigmatch_table[DETECT_DECODE_EVENT].Setup = DetectDecodeEventSetup; - sigmatch_table[DETECT_DECODE_EVENT].Free = DetectEngineEventFree; - sigmatch_table[DETECT_DECODE_EVENT].flags |= SIGMATCH_DEONLY_COMPAT; - - sigmatch_table[DETECT_STREAM_EVENT].name = "stream-event"; - sigmatch_table[DETECT_STREAM_EVENT].Match = DetectEngineEventMatch; - sigmatch_table[DETECT_STREAM_EVENT].Setup = DetectStreamEventSetup; - sigmatch_table[DETECT_STREAM_EVENT].Free = DetectEngineEventFree; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s\n", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s\n", eb); - goto error; - } - return; - -error: - return; - -} - -/** - * \brief This function is used to match decoder event flags set on a packet with those passed via decode-event: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param s pointer to the Signature - * \param m pointer to the sigmatch - * - * \retval 0 no match - * \retval 1 match - */ -int DetectEngineEventMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - SCEnter(); - - const DetectEngineEventData *de = (const DetectEngineEventData *)ctx; - - if (ENGINE_ISSET_EVENT(p, de->event)) { - SCLogDebug("de->event matched %u", de->event); - SCReturnInt(1); - } - - SCReturnInt(0); -} - -/** - * \brief This function is used to parse decoder events options passed via decode-event: keyword - * - * \param rawstr Pointer to the user provided decode-event options - * - * \retval de pointer to DetectFlowData on success - * \retval NULL on failure - */ -DetectEngineEventData *DetectEngineEventParse (char *rawstr) -{ - int i; - DetectEngineEventData *de = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0, found = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 - ", string %s", ret, rawstr); - goto error; - } - - char copy_str[128] = ""; - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 0, - copy_str, sizeof(copy_str)); - - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - for (i = 0; DEvents[i].event_name != NULL; i++) { - if (strcasecmp(DEvents[i].event_name,copy_str) == 0) { - found = 1; - break; - } - } - - if (found == 0) { - SCLogError(SC_ERR_UNKNOWN_DECODE_EVENT, "unknown decode event \"%s\"", - copy_str); - goto error; - } - - de = SCMalloc(sizeof(DetectEngineEventData)); - if (unlikely(de == NULL)) - goto error; - - de->event = DEvents[i].code; - - if (de->event == STREAM_REASSEMBLY_OVERLAP_DIFFERENT_DATA) { - StreamTcpReassembleConfigEnableOverlapCheck(); - } - return de; - -error: - if (de) - SCFree(de); - return NULL; -} - -/** - * \brief this function is used to add the parsed decode-event into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param rawstr pointer to the user provided decode-event options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int _DetectEngineEventSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr, int smtype) -{ - DetectEngineEventData *de = NULL; - SigMatch *sm = NULL; - - de = DetectEngineEventParse(rawstr); - if (de == NULL) - goto error; - - SCLogDebug("rawstr %s %u", rawstr, de->event); - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = smtype; - sm->ctx = (SigMatchCtx *)de; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - return 0; - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - return -1; -} - - -static int DetectEngineEventSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - return _DetectEngineEventSetup (de_ctx, s, rawstr, DETECT_ENGINE_EVENT); -} - -/** - * \brief this function will free memory associated with DetectEngineEventData - * - * \param de pointer to DetectEngineEventData - */ -static void DetectEngineEventFree(void *ptr) -{ - DetectEngineEventData *de = (DetectEngineEventData *)ptr; - if (de) - SCFree(de); -} - - -/** - * \brief this function Setup the 'decode-event' keyword by setting the correct - * signature type -*/ -static int DetectDecodeEventSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - return _DetectEngineEventSetup(de_ctx, s, rawstr, DETECT_DECODE_EVENT); -} - -/** - * \brief this function Setup the 'stream-event' keyword by resolving the alias -*/ -static int DetectStreamEventSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - char srawstr[MAX_SUBSTRINGS * 2] = "stream."; - - /* stream:$EVENT alias command develop as decode-event:stream.$EVENT */ - strlcat(srawstr, rawstr, 2 * MAX_SUBSTRINGS - strlen("stream.") - 1); - - return DetectEngineEventSetup(de_ctx, s, srawstr); -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ -#ifdef UNITTESTS - -/** - * \test EngineEventTestParse01 is a test for a valid decode-event value - */ -int EngineEventTestParse01 (void) -{ - DetectEngineEventData *de = NULL; - de = DetectEngineEventParse("ipv4.pkt_too_small"); - if (de) { - DetectEngineEventFree(de); - return 1; - } - - return 0; -} - - -/** - * \test EngineEventTestParse02 is a test for a valid upper + lower case decode-event value - */ -int EngineEventTestParse02 (void) -{ - DetectEngineEventData *de = NULL; - de = DetectEngineEventParse("PPP.pkt_too_small"); - if (de) { - DetectEngineEventFree(de); - return 1; - } - - return 0; -} - -/** - * \test EngineEventTestParse03 is a test for a valid upper case decode-event value - */ -int EngineEventTestParse03 (void) -{ - DetectEngineEventData *de = NULL; - de = DetectEngineEventParse("IPV6.PKT_TOO_SMALL"); - if (de) { - DetectEngineEventFree(de); - return 1; - } - - return 0; -} - -/** - * \test EngineEventTestParse04 is a test for an invalid upper case decode-event value - */ -int EngineEventTestParse04 (void) -{ - DetectEngineEventData *de = NULL; - de = DetectEngineEventParse("IPV6.INVALID_EVENT"); - if (de) { - DetectEngineEventFree(de); - return 1; - } - - return 0; -} - -/** - * \test EngineEventTestParse05 is a test for an invalid char into the decode-event value - */ -int EngineEventTestParse05 (void) -{ - DetectEngineEventData *de = NULL; - de = DetectEngineEventParse("IPV-6,INVALID_CHAR"); - if (de) { - DetectEngineEventFree(de); - return 1; - } - - return 0; -} - -/** - * \test EngineEventTestParse06 is a test for match function with valid decode-event value - */ -int EngineEventTestParse06 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectEngineEventData *de = NULL; - SigMatch *sm = NULL; - - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - - ENGINE_SET_EVENT(p,PPP_PKT_TOO_SMALL); - - de = DetectEngineEventParse("ppp.pkt_too_small"); - if (de == NULL) - goto error; - - de->event = PPP_PKT_TOO_SMALL; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_DECODE_EVENT; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectEngineEventMatch(&tv,NULL,p,NULL,sm->ctx); - - if(ret) { - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for EngineEvent - */ -void EngineEventRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("EngineEventTestParse01", EngineEventTestParse01, 1); - UtRegisterTest("EngineEventTestParse02", EngineEventTestParse02, 1); - UtRegisterTest("EngineEventTestParse03", EngineEventTestParse03, 1); - UtRegisterTest("EngineEventTestParse04", EngineEventTestParse04, 0); - UtRegisterTest("EngineEventTestParse05", EngineEventTestParse05, 0); - UtRegisterTest("EngineEventTestParse06", EngineEventTestParse06, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-engine-event.h b/framework/src/suricata/src/detect-engine-event.h deleted file mode 100644 index 9d6424fb..00000000 --- a/framework/src/suricata/src/detect-engine-event.h +++ /dev/null @@ -1,256 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - */ - -#ifndef __DETECT_ENGINE_EVENT_H__ -#define __DETECT_ENGINE_EVENT_H__ - -#include "decode-events.h" - -typedef struct DetectEngineEventData_ { - uint8_t event; -} DetectEngineEventData; - -/* prototypes */ -void DetectEngineEventRegister (void); - -/* supported decoder events */ - -#ifdef DETECT_EVENTS -struct DetectEngineEvents_ { - char *event_name; - uint8_t code; -} DEvents[] = { - /* IPV4 EVENTS */ - { "ipv4.pkt_too_small", IPV4_PKT_TOO_SMALL, }, - { "ipv4.hlen_too_small", IPV4_HLEN_TOO_SMALL, }, - { "ipv4.iplen_smaller_than_hlen", IPV4_IPLEN_SMALLER_THAN_HLEN, }, - { "ipv4.trunc_pkt", IPV4_TRUNC_PKT, }, - - /* IPV4 OPTIONS */ - { "ipv4.opt_invalid", IPV4_OPT_INVALID, }, - { "ipv4.opt_invalid_len", IPV4_OPT_INVALID_LEN, }, - { "ipv4.opt_malformed", IPV4_OPT_MALFORMED, }, - { "ipv4.opt_pad_required", IPV4_OPT_PAD_REQUIRED, }, - { "ipv4.opt_eol_required", IPV4_OPT_EOL_REQUIRED, }, - { "ipv4.opt_duplicate", IPV4_OPT_DUPLICATE, }, - { "ipv4.opt_unknown", IPV4_OPT_UNKNOWN, }, - { "ipv4.wrong_ip_version", IPV4_WRONG_IP_VER, }, - { "ipv4.icmpv6", IPV4_WITH_ICMPV6, }, - - /* ICMP EVENTS */ - { "icmpv4.pkt_too_small", ICMPV4_PKT_TOO_SMALL, }, - { "icmpv4.unknown_type", ICMPV4_UNKNOWN_TYPE, }, - { "icmpv4.unknown_code", ICMPV4_UNKNOWN_CODE, }, - { "icmpv4.ipv4_trunc_pkt", ICMPV4_IPV4_TRUNC_PKT, }, - { "icmpv4.ipv4_unknown_ver", ICMPV4_IPV4_UNKNOWN_VER, }, - - /* ICMPv6 EVENTS */ - { "icmpv6.unknown_type", ICMPV6_UNKNOWN_TYPE,}, - { "icmpv6.unknown_code", ICMPV6_UNKNOWN_CODE,}, - { "icmpv6.pkt_too_small", ICMPV6_PKT_TOO_SMALL,}, - { "icmpv6.ipv6_unknown_version", ICMPV6_IPV6_UNKNOWN_VER,}, - { "icmpv6.ipv6_trunc_pkt", ICMPV6_IPV6_TRUNC_PKT,}, - { "icmpv6.mld_message_with_invalid_hl", ICMPV6_MLD_MESSAGE_WITH_INVALID_HL,}, - - /* IPV6 EVENTS */ - { "ipv6.pkt_too_small", IPV6_PKT_TOO_SMALL, }, - { "ipv6.trunc_pkt", IPV6_TRUNC_PKT, }, - { "ipv6.trunc_exthdr", IPV6_TRUNC_EXTHDR, }, - { "ipv6.exthdr_dupl_fh", IPV6_EXTHDR_DUPL_FH, }, - { "ipv6.exthdr_useless_fh", IPV6_EXTHDR_USELESS_FH, }, - { "ipv6.exthdr_dupl_rh", IPV6_EXTHDR_DUPL_RH, }, - { "ipv6.exthdr_dupl_hh", IPV6_EXTHDR_DUPL_HH, }, - { "ipv6.exthdr_dupl_dh", IPV6_EXTHDR_DUPL_DH, }, - { "ipv6.exthdr_dupl_ah", IPV6_EXTHDR_DUPL_AH, }, - { "ipv6.exthdr_dupl_eh", IPV6_EXTHDR_DUPL_EH, }, - { "ipv6.exthdr_invalid_optlen", IPV6_EXTHDR_INVALID_OPTLEN, }, - { "ipv6.wrong_ip_version", IPV6_WRONG_IP_VER, }, - { "ipv6.exthdr_ah_res_not_null", IPV6_EXTHDR_AH_RES_NOT_NULL, }, - { "ipv6.hopopts_unknown_opt", IPV6_HOPOPTS_UNKNOWN_OPT, }, - { "ipv6.hopopts_only_padding", IPV6_HOPOPTS_ONLY_PADDING, }, - { "ipv6.dstopts_unknown_opt", IPV6_DSTOPTS_UNKNOWN_OPT, }, - { "ipv6.dstopts_only_padding", IPV6_DSTOPTS_ONLY_PADDING, }, - { "ipv6.rh_type_0", IPV6_EXTHDR_RH_TYPE_0, }, - { "ipv6.zero_len_padn", IPV6_EXTHDR_ZERO_LEN_PADN, }, - { "ipv6.fh_non_zero_reserved_field", IPV6_FH_NON_ZERO_RES_FIELD, }, - { "ipv6.data_after_none_header", IPV6_DATA_AFTER_NONE_HEADER, }, - { "ipv6.unknown_next_header", IPV6_UNKNOWN_NEXT_HEADER, }, - { "ipv6.icmpv4", IPV6_WITH_ICMPV4, }, - - /* TCP EVENTS */ - { "tcp.pkt_too_small", TCP_PKT_TOO_SMALL, }, - { "tcp.hlen_too_small", TCP_HLEN_TOO_SMALL, }, - { "tcp.invalid_optlen", TCP_INVALID_OPTLEN, }, - - /* TCP OPTIONS */ - { "tcp.opt_invalid_len", TCP_OPT_INVALID_LEN, }, - { "tcp.opt_duplicate", TCP_OPT_DUPLICATE, }, - - /* UDP EVENTS */ - { "udp.pkt_too_small", UDP_PKT_TOO_SMALL, }, - { "udp.hlen_too_small", UDP_HLEN_TOO_SMALL, }, - { "udp.hlen_invalid", UDP_HLEN_INVALID, }, - - /* SLL EVENTS */ - { "sll.pkt_too_small", SLL_PKT_TOO_SMALL, }, - - /* ETHERNET EVENTS */ - { "ethernet.pkt_too_small", ETHERNET_PKT_TOO_SMALL, }, - - /* PPP EVENTS */ - { "ppp.pkt_too_small", PPP_PKT_TOO_SMALL, }, - { "ppp.vju_pkt_too_small", PPPVJU_PKT_TOO_SMALL, }, - { "ppp.ip4_pkt_too_small", PPPIPV4_PKT_TOO_SMALL, }, - { "ppp.ip6_pkt_too_small", PPPIPV6_PKT_TOO_SMALL, }, - { "ppp.wrong_type", PPP_WRONG_TYPE, }, /** unknown & invalid protocol */ - { "ppp.unsup_proto", PPP_UNSUP_PROTO, }, /** unsupported but valid protocol */ - - /* PPPOE EVENTS */ - { "pppoe.pkt_too_small", PPPOE_PKT_TOO_SMALL, }, - { "pppoe.wrong_code", PPPOE_WRONG_CODE, }, - { "pppoe.malformed_tags", PPPOE_MALFORMED_TAGS, }, - - /* GRE EVENTS */ - { "gre.pkt_too_small", GRE_PKT_TOO_SMALL, }, - { "gre.wrong_version", GRE_WRONG_VERSION, }, - { "gre.version0_recur", GRE_VERSION0_RECUR, }, - { "gre.version0_flags", GRE_VERSION0_FLAGS, }, - { "gre.version0_hdr_too_big", GRE_VERSION0_HDR_TOO_BIG, }, - { "gre.version0_malformed_sre_hdr", GRE_VERSION0_MALFORMED_SRE_HDR, }, - { "gre.version1_chksum", GRE_VERSION1_CHKSUM, }, - { "gre.version1_route", GRE_VERSION1_ROUTE, }, - { "gre.version1_ssr", GRE_VERSION1_SSR, }, - { "gre.version1_recur", GRE_VERSION1_RECUR, }, - { "gre.version1_flags", GRE_VERSION1_FLAGS, }, - { "gre.version1_no_key", GRE_VERSION1_NO_KEY, }, - { "gre.version1_wrong_protocol", GRE_VERSION1_WRONG_PROTOCOL, }, - { "gre.version1_malformed_sre_hdr", GRE_VERSION1_MALFORMED_SRE_HDR, }, - { "gre.version1_hdr_too_big", GRE_VERSION1_HDR_TOO_BIG, }, - - /* VLAN EVENTS */ - { "vlan.header_too_small",VLAN_HEADER_TOO_SMALL, }, - { "vlan.unknown_type",VLAN_UNKNOWN_TYPE, }, - { "vlan.too_many_layers", VLAN_HEADER_TOO_MANY_LAYERS, }, - - /* RAW EVENTS */ - { "ipraw.invalid_ip_version",IPRAW_INVALID_IPV, }, - - /* LINKTYPE NULL EVENTS */ - { "ltnull.pkt_too_small", LTNULL_PKT_TOO_SMALL, }, - { "ltnull.unsupported_type", LTNULL_UNSUPPORTED_TYPE, }, - - /* STREAM EVENTS */ - { "stream.3whs_ack_in_wrong_dir", STREAM_3WHS_ACK_IN_WRONG_DIR, }, - { "stream.3whs_async_wrong_seq", STREAM_3WHS_ASYNC_WRONG_SEQ, }, - { "stream.3whs_right_seq_wrong_ack_evasion", STREAM_3WHS_RIGHT_SEQ_WRONG_ACK_EVASION, }, - { "stream.3whs_synack_in_wrong_direction", STREAM_3WHS_SYNACK_IN_WRONG_DIRECTION, }, - { "stream.3whs_synack_resend_with_different_ack", STREAM_3WHS_SYNACK_RESEND_WITH_DIFFERENT_ACK, }, - { "stream.3whs_synack_resend_with_diff_seq", STREAM_3WHS_SYNACK_RESEND_WITH_DIFF_SEQ, }, - { "stream.3whs_synack_toserver_on_syn_recv", STREAM_3WHS_SYNACK_TOSERVER_ON_SYN_RECV, }, - { "stream.3whs_synack_with_wrong_ack", STREAM_3WHS_SYNACK_WITH_WRONG_ACK, }, - { "stream.3whs_synack_flood", STREAM_3WHS_SYNACK_FLOOD, }, - { "stream.3whs_syn_resend_diff_seq_on_syn_recv", STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV, }, - { "stream.3whs_syn_toclient_on_syn_recv", STREAM_3WHS_SYN_TOCLIENT_ON_SYN_RECV, }, - { "stream.3whs_wrong_seq_wrong_ack", STREAM_3WHS_WRONG_SEQ_WRONG_ACK, }, - { "stream.4whs_synack_with_wrong_ack", STREAM_4WHS_SYNACK_WITH_WRONG_ACK, }, - { "stream.4whs_synack_with_wrong_syn", STREAM_4WHS_SYNACK_WITH_WRONG_SYN, }, - { "stream.4whs_wrong_seq", STREAM_4WHS_WRONG_SEQ, }, - { "stream.4whs_invalid_ack", STREAM_4WHS_INVALID_ACK, }, - { "stream.closewait_ack_out_of_window", STREAM_CLOSEWAIT_ACK_OUT_OF_WINDOW, }, - { "stream.closewait_fin_out_of_window", STREAM_CLOSEWAIT_FIN_OUT_OF_WINDOW, }, - { "stream.closewait_pkt_before_last_ack", STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK, }, - { "stream.closewait_invalid_ack", STREAM_CLOSEWAIT_INVALID_ACK, }, - { "stream.closing_ack_wrong_seq", STREAM_CLOSING_ACK_WRONG_SEQ, }, - { "stream.closing_invalid_ack", STREAM_CLOSING_INVALID_ACK, }, - { "stream.est_packet_out_of_window", STREAM_EST_PACKET_OUT_OF_WINDOW, }, - { "stream.est_pkt_before_last_ack", STREAM_EST_PKT_BEFORE_LAST_ACK, }, - { "stream.est_synack_resend", STREAM_EST_SYNACK_RESEND, }, - { "stream.est_synack_resend_with_different_ack", STREAM_EST_SYNACK_RESEND_WITH_DIFFERENT_ACK, }, - { "stream.est_synack_resend_with_diff_seq", STREAM_EST_SYNACK_RESEND_WITH_DIFF_SEQ, }, - { "stream.est_synack_toserver", STREAM_EST_SYNACK_TOSERVER, }, - { "stream.est_syn_resend", STREAM_EST_SYN_RESEND, }, - { "stream.est_syn_resend_diff_seq", STREAM_EST_SYN_RESEND_DIFF_SEQ, }, - { "stream.est_syn_toclient", STREAM_EST_SYN_TOCLIENT, }, - { "stream.est_invalid_ack", STREAM_EST_INVALID_ACK, }, - { "stream.fin_invalid_ack", STREAM_FIN_INVALID_ACK, }, - { "stream.fin1_ack_wrong_seq", STREAM_FIN1_ACK_WRONG_SEQ, }, - { "stream.fin1_fin_wrong_seq", STREAM_FIN1_FIN_WRONG_SEQ, }, - { "stream.fin1_invalid_ack", STREAM_FIN1_INVALID_ACK, }, - { "stream.fin2_ack_wrong_seq", STREAM_FIN2_ACK_WRONG_SEQ, }, - { "stream.fin2_fin_wrong_seq", STREAM_FIN2_FIN_WRONG_SEQ, }, - { "stream.fin2_invalid_ack", STREAM_FIN2_INVALID_ACK, }, - { "stream.fin_but_no_session", STREAM_FIN_BUT_NO_SESSION, }, - { "stream.fin_out_of_window", STREAM_FIN_OUT_OF_WINDOW, }, - { "stream.lastack_ack_wrong_seq", STREAM_LASTACK_ACK_WRONG_SEQ, }, - { "stream.lastack_invalid_ack", STREAM_LASTACK_INVALID_ACK, }, - { "stream.rst_but_no_session", STREAM_RST_BUT_NO_SESSION, }, - { "stream.timewait_ack_wrong_seq", STREAM_TIMEWAIT_ACK_WRONG_SEQ, }, - { "stream.timewait_invalid_ack", STREAM_TIMEWAIT_INVALID_ACK, }, - { "stream.pkt_invalid_timestamp", STREAM_PKT_INVALID_TIMESTAMP, }, - { "stream.pkt_invalid_ack", STREAM_PKT_INVALID_ACK, }, - { "stream.pkt_broken_ack", STREAM_PKT_BROKEN_ACK, }, - { "stream.rst_invalid_ack", STREAM_RST_INVALID_ACK, }, - { "stream.shutdown_syn_resend", STREAM_SHUTDOWN_SYN_RESEND, }, - { "stream.pkt_retransmission", STREAM_PKT_RETRANSMISSION, }, - { "stream.reassembly_segment_before_base_seq", STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ, }, - { "stream.reassembly_no_segment", STREAM_REASSEMBLY_NO_SEGMENT, }, - { "stream.reassembly_seq_gap", STREAM_REASSEMBLY_SEQ_GAP, }, - { "stream.reassembly_overlap_different_data", STREAM_REASSEMBLY_OVERLAP_DIFFERENT_DATA, }, - { "stream.pkt_bad_window_update", STREAM_PKT_BAD_WINDOW_UPDATE, }, - - /* SCTP EVENTS */ - { "sctp.pkt_too_small", SCTP_PKT_TOO_SMALL, }, - - /* Fragmentation reasembly events. */ - { "ipv4.frag_too_large", IPV4_FRAG_PKT_TOO_LARGE, }, - { "ipv6.frag_too_large", IPV6_FRAG_PKT_TOO_LARGE, }, - { "ipv4.frag_overlap", IPV4_FRAG_OVERLAP, }, - { "ipv6.frag_overlap", IPV6_FRAG_OVERLAP, }, - /* Fragment ignored due to internal error */ - { "ipv4.frag_ignored", IPV4_FRAG_IGNORED, }, - { "ipv6.frag_ignored", IPV6_FRAG_IGNORED, }, - - /* IPv4 in IPv6 events */ - { "ipv6.ipv4_in_ipv6_too_small", IPV4_IN_IPV6_PKT_TOO_SMALL, }, - { "ipv6.ipv4_in_ipv6_wrong_version", IPV4_IN_IPV6_WRONG_IP_VER, }, - /* IPv6 in IPv6 events */ - { "ipv6.ipv6_in_ipv6_too_small", IPV6_IN_IPV6_PKT_TOO_SMALL, }, - { "ipv6.ipv6_in_ipv6_wrong_version", IPV6_IN_IPV6_WRONG_IP_VER, }, - - /* MPLS events */ - { "mpls.bad_label_router_alert", MPLS_BAD_LABEL_ROUTER_ALERT, }, - { "mpls.bad_label_implicit_null", MPLS_BAD_LABEL_IMPLICIT_NULL, }, - { "mpls.bad_label_reserved", MPLS_BAD_LABEL_RESERVED, }, - { "mpls.unknown_payload_type", MPLS_UNKNOWN_PAYLOAD_TYPE, }, - - /* ERSPAN events */ - { "erspan.header_too_small", ERSPAN_HEADER_TOO_SMALL, }, - { "erspan.unsupported_version", ERSPAN_UNSUPPORTED_VERSION, }, - { "erspan.too_many_vlan_layers", ERSPAN_TOO_MANY_VLAN_LAYERS, }, - - { NULL, 0 }, -}; -#endif /* DETECT_EVENTS */ - -#endif /*__DETECT_ENGINE_EVENT_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-file.c b/framework/src/suricata/src/detect-engine-file.c deleted file mode 100644 index 31993685..00000000 --- a/framework/src/suricata/src/detect-engine-file.c +++ /dev/null @@ -1,301 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" - -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-engine-state.h" - -#include "detect-filestore.h" - -#include "detect-engine-uri.h" -#include "detect-engine-hcbd.h" -#include "detect-engine-hhd.h" -#include "detect-engine-hrhd.h" -#include "detect-engine-hmd.h" -#include "detect-engine-hcd.h" -#include "detect-engine-hrud.h" -#include "detect-engine-dcepayload.h" - -#include "stream-tcp.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" - -#include "app-layer-parser.h" -#include "app-layer-protos.h" -#include "app-layer-htp.h" -#include "app-layer-smb.h" -#include "app-layer-dcerpc-common.h" -#include "app-layer-dcerpc.h" -#include "app-layer-smtp.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-profiling.h" - - -/** - * \brief Inspect the file inspecting keywords. - * - * \param tv thread vars - * \param det_ctx detection engine thread ctx - * \param f flow - * \param s signature to inspect - * - * \retval 0 no match - * \retval 1 match - * \retval 2 can't match - * \retval 3 can't match filestore signature - * - * \note flow is not locked at this time - */ -static int DetectFileInspect(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, - Flow *f, Signature *s, uint8_t flags, FileContainer *ffc) -{ - SigMatch *sm = NULL; - int r = 0; - int match = 0; - int store_r = 0; - - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_FILEMATCH); - SCLogDebug("file inspection... %p", ffc); - - if (ffc != NULL) { - File *file = ffc->head; - for (; file != NULL; file = file->next) { - SCLogDebug("file"); - - if (file->state == FILE_STATE_NONE) { - SCLogDebug("file state FILE_STATE_NONE"); - continue; - } - - if (file->txid < det_ctx->tx_id) { - SCLogDebug("file->txid < det_ctx->tx_id == %"PRIu64" < %"PRIu64, file->txid, det_ctx->tx_id); - continue; - } - - if (file->txid > det_ctx->tx_id) { - SCLogDebug("file->txid > det_ctx->tx_id == %"PRIu64" > %"PRIu64, file->txid, det_ctx->tx_id); - break; - } - - if ((s->file_flags & FILE_SIG_NEED_FILENAME) && file->name == NULL) { - SCLogDebug("sig needs filename, but we don't have any"); - r = 0; - break; - } - - if ((s->file_flags & FILE_SIG_NEED_MAGIC) && file->chunks_head == NULL) { - SCLogDebug("sig needs file content, but we don't have any"); - r = 0; - break; - } - - if ((s->file_flags & FILE_SIG_NEED_FILECONTENT) && file->chunks_head == NULL) { - SCLogDebug("sig needs file content, but we don't have any"); - r = 0; - break; - } - - if ((s->file_flags & FILE_SIG_NEED_MD5) && (!(file->flags & FILE_MD5))) { - SCLogDebug("sig needs file md5, but we don't have any"); - r = 0; - break; - } - - if ((s->file_flags & FILE_SIG_NEED_SIZE) && file->state < FILE_STATE_CLOSED) { - SCLogDebug("sig needs filesize, but state < FILE_STATE_CLOSED"); - r = 0; - break; - } - - /* run the file match functions. */ - for (sm = s->sm_lists[DETECT_SM_LIST_FILEMATCH]; sm != NULL; sm = sm->next) { - SCLogDebug("sm %p, sm->next %p", sm, sm->next); - - if (sigmatch_table[sm->type].FileMatch != NULL) { - KEYWORD_PROFILING_START; - match = sigmatch_table[sm->type]. - FileMatch(tv, det_ctx, f, flags, file, s, sm); - KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0)); - if (match == 0) { - r = 2; - break; - } else if (sm->next == NULL) { - r = 1; - break; - } - } - } - - /* continue inspection for other files as we may want to store - * those as well. We'll return 1 (match) regardless of their - * results though */ - if (r == 1) - store_r = 1; - - /* if this is a filestore sig, and the sig can't match - * return 3 so we can distinguish */ - if ((s->flags & SIG_FLAG_FILESTORE) && r == 2) - r = 3; - - /* continue, this file may (or may not) be unable to match - * maybe we have more that can :) */ - } - } else { - /* if we have a filestore sm with a scope > file (so tx, ssn) we - * run it here */ - sm = s->sm_lists[DETECT_SM_LIST_FILEMATCH]; - if (sm != NULL && sm->next == NULL && sm->type == DETECT_FILESTORE && - sm->ctx != NULL) - { - DetectFilestoreData *fd = (DetectFilestoreData *)sm->ctx; - if (fd->scope > FILESTORE_SCOPE_DEFAULT) { - KEYWORD_PROFILING_START; - match = sigmatch_table[sm->type]. - FileMatch(tv, det_ctx, f, flags, /* no file */NULL, s, sm); - KEYWORD_PROFILING_END(det_ctx, sm->type, (match > 0)); - - if (match == 1) { - r = 1; - } - } - } - } - - if (store_r == 1) - r = 1; - SCReturnInt(r); -} - -/** - * \brief Inspect the file inspecting keywords against the HTTP transactions. - * - * \param tv thread vars - * \param det_ctx detection engine thread ctx - * \param f flow - * \param s signature to inspect - * \param alstate state - * \param flags direction flag - * - * \retval 0 no match - * \retval 1 match - * \retval 2 can't match - * \retval 3 can't match filestore signature - * - * \note flow should be locked when this function's called. - */ -int DetectFileInspectHttp(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, void *alstate, - void *tx, uint64_t tx_id) -{ - int r = DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - FileContainer *ffc; - HtpState *htp_state = (HtpState *)alstate; - - if (flags & STREAM_TOCLIENT) - ffc = htp_state->files_tc; - else - ffc = htp_state->files_ts; - - int match = DetectFileInspect(tv, det_ctx, f, s, flags, ffc); - if (match == 1) { - r = DETECT_ENGINE_INSPECT_SIG_MATCH; - } else if (match == 2) { - if (r != 1) { - SCLogDebug("sid %u can't match on this transaction", s->id); - r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } - } else if (match == 3) { - if (r != 1) { - SCLogDebug("sid %u can't match on this transaction (filestore sig)", s->id); - r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE; - } - } - - return r; -} - -/** - * \brief Inspect the file inspecting keywords against the SMTP transactions. - * - * \param tv thread vars - * \param det_ctx detection engine thread ctx - * \param f flow - * \param s signature to inspect - * \param alstate state - * \param flags direction flag - * - * \retval 0 no match - * \retval 1 match - * \retval 2 can't match - * \retval 3 can't match filestore signature - * - * \note flow is not locked at this time - */ -int DetectFileInspectSmtp(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, void *alstate, - void *tx, uint64_t tx_id) -{ - SCEnter(); - int r = DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - SMTPState *smtp_state = NULL; - FileContainer *ffc; - - smtp_state = (SMTPState *)alstate; - if (smtp_state == NULL) { - SCLogDebug("no SMTP state"); - goto end; - } - - if (flags & STREAM_TOSERVER) - ffc = smtp_state->files_ts; - else - goto end; - - int match = DetectFileInspect(tv, det_ctx, f, s, flags, ffc); - if (match == 1) { - r = DETECT_ENGINE_INSPECT_SIG_MATCH; - } else if (match == 2) { - if (r != 1) { - SCLogDebug("sid %u can't match on this transaction", s->id); - r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } - } else if (match == 3) { - if (r != 1) { - SCLogDebug("sid %u can't match on this transaction (filestore sig)", s->id); - r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE; - } - } - - -end: - SCReturnInt(r); -} diff --git a/framework/src/suricata/src/detect-engine-file.h b/framework/src/suricata/src/detect-engine-file.h deleted file mode 100644 index 365ed8a9..00000000 --- a/framework/src/suricata/src/detect-engine-file.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_FILE_H__ -#define __DETECT_ENGINE_FILE_H__ - -int DetectFileInspectHttp(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, void *alstate, - void *tx, uint64_t tx_id); - -int DetectFileInspectSmtp(ThreadVars *tv, DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Signature *s, - Flow *f, uint8_t flags, void *alstate, - void *tx, uint64_t tx_id); - -#endif /* __DETECT_ENGINE_FILE_H__ */ diff --git a/framework/src/suricata/src/detect-engine-filedata-smtp.c b/framework/src/suricata/src/detect-engine-filedata-smtp.c deleted file mode 100644 index 829832f9..00000000 --- a/framework/src/suricata/src/detect-engine-filedata-smtp.c +++ /dev/null @@ -1,562 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - - -/** \file - * - * \author Giuseppe Longo - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-smtp.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" - -#include "conf.h" -#include "conf-yaml-loader.h" - -#define BUFFER_STEP 50 - -static inline int SMTPCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size) -{ - void *ptmp; - if (size > det_ctx->smtp_buffers_size) { - ptmp = SCRealloc(det_ctx->smtp, - (det_ctx->smtp_buffers_size + BUFFER_STEP) * sizeof(FiledataReassembledBody)); - if (ptmp == NULL) { - SCFree(det_ctx->smtp); - det_ctx->smtp = NULL; - det_ctx->smtp_buffers_size = 0; - det_ctx->smtp_buffers_list_len = 0; - return -1; - } - det_ctx->smtp = ptmp; - - memset(det_ctx->smtp + det_ctx->smtp_buffers_size, 0, BUFFER_STEP * sizeof(FiledataReassembledBody)); - det_ctx->smtp_buffers_size += BUFFER_STEP; - } - for (int i = det_ctx->smtp_buffers_list_len; i < (size); i++) { - det_ctx->smtp[i].buffer_len = 0; - det_ctx->smtp[i].offset = 0; - } - - return 0; -} - -static uint8_t *DetectEngineSMTPGetBufferForTX(uint64_t tx_id, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Flow *f, File *curr_file, - uint8_t flags, - uint32_t *buffer_len, - uint32_t *stream_start_offset) -{ - int index = 0; - uint8_t *buffer = NULL; - *buffer_len = 0; - *stream_start_offset = 0; - FileData *curr_chunk = NULL; - - if (det_ctx->smtp_buffers_list_len == 0) { - if (SMTPCreateSpace(det_ctx, 1) < 0) - goto end; - index = 0; - - if (det_ctx->smtp_buffers_list_len == 0) { - det_ctx->smtp_start_tx_id = tx_id; - } - det_ctx->smtp_buffers_list_len++; - } else { - if ((tx_id - det_ctx->smtp_start_tx_id) < det_ctx->smtp_buffers_list_len) { - if (det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len != 0) { - *buffer_len = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len; - *stream_start_offset = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].offset; - return det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer; - } - } else { - if (SMTPCreateSpace(det_ctx, (tx_id - det_ctx->smtp_start_tx_id) + 1) < 0) - goto end; - - if (det_ctx->smtp_buffers_list_len == 0) { - det_ctx->smtp_start_tx_id = tx_id; - } - det_ctx->smtp_buffers_list_len++; - } - index = (tx_id - det_ctx->smtp_start_tx_id); - } - - /* no new data */ - if (curr_file->content_inspected == curr_file->content_len_so_far) { - SCLogDebug("no new data"); - goto end; - } - - curr_chunk = curr_file->chunks_head; - if (curr_chunk == NULL) { - SCLogDebug("no data chunks to inspect for this transaction"); - goto end; - } - - if ((smtp_config.content_limit == 0 || - curr_file->content_len_so_far < smtp_config.content_limit) && - curr_file->content_len_so_far < smtp_config.content_inspect_min_size && - !(flags & STREAM_EOF)) { - SCLogDebug("we still haven't seen the entire content. " - "Let's defer content inspection till we see the " - "entire content."); - goto end; - } - - int first = 1; - curr_chunk = curr_file->chunks_head; - while (curr_chunk != NULL) { - /* see if we can filter out chunks */ - if (curr_file->content_inspected > 0) { - if (curr_chunk->stream_offset < curr_file->content_inspected) { - if ((curr_file->content_inspected - curr_chunk->stream_offset) > smtp_config.content_inspect_window) { - curr_chunk = curr_chunk->next; - continue; - } else { - /* include this one */ - } - } else { - /* include this one */ - } - } - - if (first) { - det_ctx->smtp[index].offset = curr_chunk->stream_offset; - first = 0; - } - - /* see if we need to grow the buffer */ - if (det_ctx->smtp[index].buffer == NULL || (det_ctx->smtp[index].buffer_len + curr_chunk->len) > det_ctx->smtp[index].buffer_size) { - void *ptmp; - det_ctx->smtp[index].buffer_size += curr_chunk->len * 2; - - if ((ptmp = SCRealloc(det_ctx->smtp[index].buffer, det_ctx->smtp[index].buffer_size)) == NULL) { - SCFree(det_ctx->smtp[index].buffer); - det_ctx->smtp[index].buffer = NULL; - det_ctx->smtp[index].buffer_size = 0; - det_ctx->smtp[index].buffer_len = 0; - goto end; - } - det_ctx->smtp[index].buffer = ptmp; - } - memcpy(det_ctx->smtp[index].buffer + det_ctx->smtp[index].buffer_len, curr_chunk->data, curr_chunk->len); - det_ctx->smtp[index].buffer_len += curr_chunk->len; - - curr_chunk = curr_chunk->next; - } - - /* updat inspected tracker */ - curr_file->content_inspected = curr_file->chunks_tail->stream_offset + curr_file->chunks_tail->len; - - buffer = det_ctx->smtp[index].buffer; - *buffer_len = det_ctx->smtp[index].buffer_len; - *stream_start_offset = det_ctx->smtp[index].offset; -end: - return buffer; -} - -int DetectEngineInspectSMTPFiledata(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id) -{ - SMTPState *smtp_state = (SMTPState *)alstate; - FileContainer *ffc = smtp_state->files_ts; - int r = 0; - int match = 0; - uint32_t buffer_len = 0; - uint32_t stream_start_offset = 0; - uint8_t *buffer = 0; - - if (ffc != NULL) { - File *file = ffc->head; - for (; file != NULL; file = file->next) { - buffer = DetectEngineSMTPGetBufferForTX(tx_id, - de_ctx, det_ctx, - f, file, - flags, - &buffer_len, - &stream_start_offset); - if (buffer_len == 0) - goto end; - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - match = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_FILEDATA], - f, - buffer, - buffer_len, - stream_start_offset, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_FD_SMTP, NULL); - if (match == 1) - r = 1; - } - } - -end: - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -void DetectEngineCleanSMTPBuffers(DetectEngineThreadCtx *det_ctx) -{ - if (det_ctx->smtp_buffers_list_len > 0) { - for (int i = 0; i < det_ctx->smtp_buffers_list_len; i++) { - det_ctx->smtp[i].buffer_len = 0; - det_ctx->smtp[i].offset = 0; - } - } - det_ctx->smtp_buffers_list_len = 0; - det_ctx->smtp_start_tx_id = 0; - - return; -} - -int DetectEngineRunSMTPMpm(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Flow *f, - SMTPState *smtp_state, uint8_t flags, - void *tx, uint64_t idx) -{ - FileContainer *ffc = smtp_state->files_ts; - uint32_t cnt = 0; - uint32_t buffer_len = 0; - uint32_t stream_start_offset = 0; - uint8_t *buffer = NULL; - - if (ffc != NULL) { - File *file = ffc->head; - for (; file != NULL; file = file->next) { - buffer = DetectEngineSMTPGetBufferForTX(idx, - de_ctx, det_ctx, - f, file, - flags, - &buffer_len, - &stream_start_offset); - if (buffer_len == 0) - goto end; - - cnt += SMTPFiledataPatternSearch(det_ctx, buffer, buffer_len, flags); - } - } -end: - return cnt; -} - -#ifdef UNITTESTS - -static int DetectEngineSMTPFiledataTest01(void) -{ - uint8_t mimemsg[] = {0x4D, 0x49, 0x4D, 0x45, 0x2D, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6F, 0x6E, 0x3A, 0x20, 0x31, 0x2E, - 0x30, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, 0x74, 0x65, - 0x6E, 0x74, 0x2D, 0x54, 0x79, 0x70, 0x65, 0x3A, - 0x20, 0x74, 0x65, 0x78, 0x74, 0x2F, 0x70, 0x6C, - 0x61, 0x69, 0x6E, 0x3B, 0x20, 0x63, 0x68, 0x61, - 0x72, 0x73, 0x65, 0x74, 0x3D, 0x55, 0x54, 0x46, - 0x2D, 0x38, 0x3B, 0x0D, 0x0A, 0x43, 0x6F, 0x6E, - 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x54, 0x72, 0x61, - 0x6E, 0x73, 0x66, 0x65, 0x72, 0x2D, 0x45, 0x6E, - 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, - 0x37, 0x62, 0x69, 0x74, 0x0D, 0x0A, 0x43, 0x6F, - 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x44, 0x69, - 0x73, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, - 0x6E, 0x3A, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, - 0x68, 0x6D, 0x65, 0x6E, 0x74, 0x3B, 0x20, 0x66, - 0x69, 0x6C, 0x65, 0x6E, 0x61, 0x6D, 0x65, 0x3D, - 0x22, 0x74, 0x65, 0x73, 0x74, 0x2E, 0x74, 0x78, - 0x74, 0x22, 0x0D, 0x0A, 0x0D, 0x0A, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65,}; - uint32_t mimemsg_len = sizeof(mimemsg) - 1; - TcpSession ssn; - Packet *p; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - SMTPState *smtp_state = NULL; - Flow f; - int result = 0; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alstate = SMTPStateAlloc(); - - MimeDecParseState *state = MimeDecInitParser(&f, NULL); - ((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT; - state->body_begin = 1; - - if (SMTPProcessDataChunk((uint8_t *)mimemsg, sizeof(mimemsg), state) != 0) - goto end; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SMTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert smtp any any -> any any " - "(msg:\"file_data smtp test\"; " - "file_data; content:\"message\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, mimemsg, mimemsg_len); - if (r != 0) { - printf("AppLayerParse for smtp failed. Returned %d", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineSMTPFiledataTest02(void) -{ - Signature *s = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert smtp any any -> any any " - "(msg:\"file_data smtp test\"; " - "file_data; content:\"message\"; sid:1;)"); - if (s == NULL) - goto end; - - if (s->flags & SIG_FLAG_TOSERVER) - result = 1; - else if (s->flags & SIG_FLAG_TOCLIENT) - printf("s->flags & SIG_FLAG_TOCLIENT"); - -end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; - -} - -static int DetectEngineSMTPFiledataTest03(void) -{ - uint8_t mimemsg1[] = {0x65, 0x76,}; - uint8_t mimemsg2[] = {0x69, 0x6C,}; - uint32_t mimemsg1_len = sizeof(mimemsg1) - 1; - uint32_t mimemsg2_len = sizeof(mimemsg2) - 1; - TcpSession ssn; - Packet *p; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - SMTPState *smtp_state = NULL; - Flow f; - int result = 1; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alstate = SMTPStateAlloc(); - - MimeDecParseState *state = MimeDecInitParser(&f, NULL); - ((MimeDecEntity *)state->stack->top->data)->ctnt_flags = CTNT_IS_ATTACHMENT; - state->body_begin = 1; - - if (SMTPProcessDataChunk((uint8_t *)mimemsg1, sizeof(mimemsg1), state) != 0) - goto end; - - if (SMTPProcessDataChunk((uint8_t *)mimemsg2, sizeof(mimemsg2), state) != 0) - goto end; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SMTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert smtp any any -> any any " - "(msg:\"file_data smtp test\"; " - "file_data; content:\"evil\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = 0; - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, mimemsg1, mimemsg1_len); - if (r != 0) { - printf("AppLayerParse for smtp failed. Returned %d", r); - SCMutexUnlock(&f.m); - goto end; - } - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SMTP, STREAM_TOSERVER, mimemsg2, mimemsg2_len); - if (r != 0) { - printf("AppLayerParse for smtp failed. Returned %d", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - smtp_state = f.alstate; - if (smtp_state == NULL) { - printf("no smtp state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - result = 0; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineSMTPFiledataRegisterTests(void) -{ - #ifdef UNITTESTS - UtRegisterTest("DetectEngineSMTPFiledataTest01", - DetectEngineSMTPFiledataTest01, 1); - UtRegisterTest("DetectEngineSMTPFiledataTest02", - DetectEngineSMTPFiledataTest02, 1); - UtRegisterTest("DetectEngineSMTPFiledataTest03", - DetectEngineSMTPFiledataTest03, 0); - #endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-engine-filedata-smtp.h b/framework/src/suricata/src/detect-engine-filedata-smtp.h deleted file mode 100644 index e04832b7..00000000 --- a/framework/src/suricata/src/detect-engine-filedata-smtp.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Giuseppe Longo - */ - -#ifndef __DETECT_ENGINE_FILEDATA_SMTP_H__ -#define __DETECT_ENGINE_FILEDATA_SMTP_H__ - -#include "app-layer-smtp.h" - -int DetectEngineInspectSMTPFiledata(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -void DetectEngineCleanSMTPBuffers(DetectEngineThreadCtx *det_ctx); - -int DetectEngineRunSMTPMpm(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Flow *f, - SMTPState *smtp_state, uint8_t flags, - void *tx, uint64_t idx); - -void DetectEngineSMTPFiledataRegisterTests(void); - -#endif /* __DETECT_ENGINE_FILEDATA_SMTP_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hcbd.c b/framework/src/suricata/src/detect-engine-hcbd.c deleted file mode 100644 index 09b7980a..00000000 --- a/framework/src/suricata/src/detect-engine-hcbd.c +++ /dev/null @@ -1,1116 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * - * \brief Handle HTTP request body match corresponding to http_client_body - * keyword. - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "app-layer-parser.h" - -#include "stream-tcp.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -#include "conf.h" -#include "conf-yaml-loader.h" - -#define BUFFER_STEP 50 - -static inline int HCBDCreateSpace(DetectEngineThreadCtx *det_ctx, uint64_t size) -{ - if (size >= (USHRT_MAX - BUFFER_STEP)) - return -1; - - void *ptmp; - if (size > det_ctx->hcbd_buffers_size) { - ptmp = SCRealloc(det_ctx->hcbd, - (det_ctx->hcbd_buffers_size + BUFFER_STEP) * sizeof(HttpReassembledBody)); - if (ptmp == NULL) { - SCFree(det_ctx->hcbd); - det_ctx->hcbd = NULL; - det_ctx->hcbd_buffers_size = 0; - det_ctx->hcbd_buffers_list_len = 0; - return -1; - } - det_ctx->hcbd = ptmp; - - memset(det_ctx->hcbd + det_ctx->hcbd_buffers_size, 0, BUFFER_STEP * sizeof(HttpReassembledBody)); - det_ctx->hcbd_buffers_size += BUFFER_STEP; - - uint16_t i; - for (i = det_ctx->hcbd_buffers_list_len; i < ((uint16_t)size); i++) { - det_ctx->hcbd[i].buffer_len = 0; - det_ctx->hcbd[i].offset = 0; - } - } - - return 0; -} - -/** - */ -static uint8_t *DetectEngineHCBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Flow *f, HtpState *htp_state, - uint8_t flags, - uint32_t *buffer_len, - uint32_t *stream_start_offset) -{ - int index = 0; - uint8_t *buffer = NULL; - *buffer_len = 0; - *stream_start_offset = 0; - - if (det_ctx->hcbd_buffers_list_len == 0) { - /* get the inspect id to use as a 'base id' */ - uint64_t base_inspect_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - BUG_ON(base_inspect_id > tx_id); - /* see how many space we need for the current tx_id */ - uint64_t txs = (tx_id - base_inspect_id) + 1; - if (HCBDCreateSpace(det_ctx, txs) < 0) - goto end; - - index = (tx_id - base_inspect_id); - det_ctx->hcbd_start_tx_id = base_inspect_id; - det_ctx->hcbd_buffers_list_len = txs; - } else { - if ((tx_id - det_ctx->hcbd_start_tx_id) < det_ctx->hcbd_buffers_list_len) { - if (det_ctx->hcbd[(tx_id - det_ctx->hcbd_start_tx_id)].buffer_len != 0) { - *buffer_len = det_ctx->hcbd[(tx_id - det_ctx->hcbd_start_tx_id)].buffer_len; - *stream_start_offset = det_ctx->hcbd[(tx_id - det_ctx->hcbd_start_tx_id)].offset; - return det_ctx->hcbd[(tx_id - det_ctx->hcbd_start_tx_id)].buffer; - } - } else { - uint64_t txs = (tx_id - det_ctx->hcbd_start_tx_id) + 1; - if (HCBDCreateSpace(det_ctx, txs) < 0) - goto end; /* let's consider it as stage not done for now */ - - det_ctx->hcbd_buffers_list_len = txs; - } - index = (tx_id - det_ctx->hcbd_start_tx_id); - } - - HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud == NULL) { - SCLogDebug("no htud"); - goto end; - } - - /* no new data */ - if (htud->request_body.body_inspected == htud->request_body.content_len_so_far) { - SCLogDebug("no new data"); - goto end; - } - - HtpBodyChunk *cur = htud->request_body.first; - if (cur == NULL) { - SCLogDebug("No http chunks to inspect for this transacation"); - goto end; - } - - /* inspect the body if the transfer is complete or we have hit - * our body size limit */ - if ((htp_state->cfg->request_body_limit == 0 || - htud->request_body.content_len_so_far < htp_state->cfg->request_body_limit) && - htud->request_body.content_len_so_far < htp_state->cfg->request_inspect_min_size && - !(AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_BODY) && - !(flags & STREAM_EOF)) { - SCLogDebug("we still haven't seen the entire request body. " - "Let's defer body inspection till we see the " - "entire body."); - goto end; - } - - int first = 1; - while (cur != NULL) { - /* see if we can filter out chunks */ - if (htud->request_body.body_inspected > 0) { - if (cur->stream_offset < htud->request_body.body_inspected) { - if ((htud->request_body.body_inspected - cur->stream_offset) > htp_state->cfg->request_inspect_min_size) { - cur = cur->next; - continue; - } else { - /* include this one */ - } - } else { - /* include this one */ - } - } - - if (first) { - det_ctx->hcbd[index].offset = cur->stream_offset; - first = 0; - } - - /* see if we need to grow the buffer */ - if (det_ctx->hcbd[index].buffer == NULL || (det_ctx->hcbd[index].buffer_len + cur->len) > det_ctx->hcbd[index].buffer_size) { - void *ptmp; - det_ctx->hcbd[index].buffer_size += cur->len * 2; - - if ((ptmp = SCRealloc(det_ctx->hcbd[index].buffer, det_ctx->hcbd[index].buffer_size)) == NULL) { - SCFree(det_ctx->hcbd[index].buffer); - det_ctx->hcbd[index].buffer = NULL; - det_ctx->hcbd[index].buffer_size = 0; - det_ctx->hcbd[index].buffer_len = 0; - goto end; - } - det_ctx->hcbd[index].buffer = ptmp; - } - memcpy(det_ctx->hcbd[index].buffer + det_ctx->hcbd[index].buffer_len, cur->data, cur->len); - det_ctx->hcbd[index].buffer_len += cur->len; - - cur = cur->next; - } - - /* update inspected tracker */ - htud->request_body.body_inspected = htud->request_body.last->stream_offset + htud->request_body.last->len; - - buffer = det_ctx->hcbd[index].buffer; - *buffer_len = det_ctx->hcbd[index].buffer_len; - *stream_start_offset = det_ctx->hcbd[index].offset; - end: - return buffer; -} - -int DetectEngineRunHttpClientBodyMpm(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx) -{ - uint32_t cnt = 0; - uint32_t buffer_len = 0; - uint32_t stream_start_offset = 0; - uint8_t *buffer = DetectEngineHCBDGetBufferForTX(tx, idx, - de_ctx, det_ctx, - f, htp_state, - flags, - &buffer_len, - &stream_start_offset); - if (buffer_len == 0) - goto end; - - cnt = HttpClientBodyPatternSearch(det_ctx, buffer, buffer_len, flags); - - end: - return cnt; -} - -int DetectEngineInspectHttpClientBody(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, void *tx, uint64_t tx_id) -{ - HtpState *htp_state = (HtpState *)alstate; - uint32_t buffer_len = 0; - uint32_t stream_start_offset = 0; - uint8_t *buffer = DetectEngineHCBDGetBufferForTX(tx, tx_id, - de_ctx, det_ctx, - f, htp_state, - flags, - &buffer_len, - &stream_start_offset); - if (buffer_len == 0) - goto end; - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HCBDMATCH], - f, - buffer, - buffer_len, - stream_start_offset, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HCBD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - - end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_BODY) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -void DetectEngineCleanHCBDBuffers(DetectEngineThreadCtx *det_ctx) -{ - if (det_ctx->hcbd_buffers_list_len > 0) { - for (int i = 0; i < det_ctx->hcbd_buffers_list_len; i++) { - det_ctx->hcbd[i].buffer_len = 0; - det_ctx->hcbd[i].offset = 0; - } - } - det_ctx->hcbd_buffers_list_len = 0; - det_ctx->hcbd_start_tx_id = 0; - - return; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -struct TestSteps { - const uint8_t *input; - size_t input_size; /**< if 0 strlen will be used */ - int direction; /**< STREAM_TOSERVER, STREAM_TOCLIENT */ - int expect; -}; - -static int RunTest (struct TestSteps *steps, const char *sig, const char *yaml) -{ - TcpSession ssn; - Flow f; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - if (yaml) { - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - - ConfYamlLoadString(yaml, strlen(yaml)); - HTPConfigure(); - } - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - SCLogDebug("sig %s", sig); - DetectEngineAppendSig(de_ctx, (char *)sig); - - de_ctx->flags |= DE_QUIET; - - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - struct TestSteps *b = steps; - int i = 0; - while (b->input != NULL) { - SCLogDebug("chunk %p %d", b, i); - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - if (p == NULL) - goto end; - p->flow = &f; - p->flowflags = (b->direction == STREAM_TOSERVER) ? FLOW_PKT_TOSERVER : FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, b->direction, - (uint8_t *)b->input, - b->input_size ? b->input_size : strlen((const char *)b->input)); - if (r != 0) { - printf("toserver chunk %d returned %" PRId32 ", expected 0: ", i+1, r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - int match = PacketAlertCheck(p, 1); - if (b->expect != match) { - printf("rule matching mismatch: "); - goto end; - } - - UTHFreePackets(&p, 1); - p = NULL; - b++; - i++; - } - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - - if (yaml) { - HtpConfigRestoreBackup(); - ConfRestoreContextBackup(); - } - return result; -} - -static int DetectEngineHttpClientBodyTest01(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1This\"; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest02(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 19\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; offset:5; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest03(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; offset:16; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest04(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; offset:16; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest05(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; depth:25; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest06(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; depth:25; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest07(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:!\"body1\"; http_client_body; depth:15; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest08(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"This is dummy body1This is dummy message body2\"; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest09(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"This\"; http_client_body; within:5; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest10(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"boom\"; http_client_body; within:5; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest11(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"boom\"; http_client_body; within:5; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest12(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"This\"; http_client_body; within:5; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest13(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"dummy\"; http_client_body; distance:5; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest14(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"dummy\"; http_client_body; distance:10; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest15(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"dummy\"; http_client_body; distance:10; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest16(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:!\"dummy\"; http_client_body; distance:5; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest17(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 19\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"bambu\"; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest18(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 19\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"body1\"; http_client_body; content:\"bambu\"; http_client_body; fast_pattern; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest19(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 19\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"bambu\"; http_client_body; content:\"is\"; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest20(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 19\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"is\"; http_client_body; fast_pattern; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest21(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; http_client_body; within:7; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest22(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; within:7; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest23(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; distance:3; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest24(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (pcre:/body1/P; content:!\"dummy\"; distance:13; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest25(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; within:15; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest26(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; within:10; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest27(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; distance:8; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest28(void) -{ - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (pcre:/body1/P; content:\"dummy\"; distance:14; http_client_body; sid:1;)"; - return RunTest(steps, sig, NULL); -} - -static int DetectEngineHttpClientBodyTest29(void) -{ - const char *request_buffer = "GET /one HTTP/1.0\r\n" - "Host: localhost\r\n\r\n"; -#define TOTAL_REQUESTS 45 - uint8_t *http_buf = SCMalloc(TOTAL_REQUESTS * strlen(request_buffer)); - if (unlikely(http_buf == NULL)) - return 0; - for (int i = 0; i < TOTAL_REQUESTS; i++) { - memcpy(http_buf + i * strlen(request_buffer), request_buffer, - strlen(request_buffer)); - } - uint32_t http_buf_len = TOTAL_REQUESTS * strlen(request_buffer); -#undef TOTAL_REQUESTS - - struct TestSteps steps[] = { - { (const uint8_t *)http_buf, - (size_t)http_buf_len, STREAM_TOSERVER, 0 }, - - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 5\r\n" - "\r\n" - "dummy", - 0, STREAM_TOCLIENT, 0 }, - - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"dummyone\"; fast_pattern:0,3; http_server_body; sid:1;)"; - int result = RunTest(steps, sig, NULL); - SCFree(http_buf); - return result; -} - -static int DetectEngineHttpClientBodyTest30(void) -{ - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - request-body-limit: 0\n\ - response-body-limit: 0\n\ -\n\ - request-body-inspect-window: 0\n\ - response-body-inspect-window: 0\n\ - request-body-minimal-inspect-size: 0\n\ - response-body-minimal-inspect-size: 0\n\ -"; - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"bags\"; within:4; http_client_body; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpClientBodyTest31(void) -{ - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - request-body-limit: 0\n\ - response-body-limit: 0\n\ -\n\ - request-body-inspect-window: 0\n\ - response-body-inspect-window: 0\n\ - request-body-minimal-inspect-size: 0\n\ - response-body-minimal-inspect-size: 0\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"This is dummy message body2", - 0, STREAM_TOSERVER, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (content:\"bags\"; depth:4; http_client_body; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpClientBodyRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpClientBodyTest01", - DetectEngineHttpClientBodyTest01, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest02", - DetectEngineHttpClientBodyTest02, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest03", - DetectEngineHttpClientBodyTest03, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest04", - DetectEngineHttpClientBodyTest04, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest05", - DetectEngineHttpClientBodyTest05, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest06", - DetectEngineHttpClientBodyTest06, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest07", - DetectEngineHttpClientBodyTest07, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest08", - DetectEngineHttpClientBodyTest08, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest09", - DetectEngineHttpClientBodyTest09, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest10", - DetectEngineHttpClientBodyTest10, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest11", - DetectEngineHttpClientBodyTest11, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest12", - DetectEngineHttpClientBodyTest12, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest13", - DetectEngineHttpClientBodyTest13, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest14", - DetectEngineHttpClientBodyTest14, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest15", - DetectEngineHttpClientBodyTest15, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest16", - DetectEngineHttpClientBodyTest16, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest17", - DetectEngineHttpClientBodyTest17, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest18", - DetectEngineHttpClientBodyTest18, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest19", - DetectEngineHttpClientBodyTest19, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest20", - DetectEngineHttpClientBodyTest20, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest21", - DetectEngineHttpClientBodyTest21, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest22", - DetectEngineHttpClientBodyTest22, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest23", - DetectEngineHttpClientBodyTest23, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest24", - DetectEngineHttpClientBodyTest24, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest25", - DetectEngineHttpClientBodyTest25, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest26", - DetectEngineHttpClientBodyTest26, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest27", - DetectEngineHttpClientBodyTest27, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest28", - DetectEngineHttpClientBodyTest28, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest29", - DetectEngineHttpClientBodyTest29, 1); - - UtRegisterTest("DetectEngineHttpClientBodyTest30", - DetectEngineHttpClientBodyTest30, 1); - UtRegisterTest("DetectEngineHttpClientBodyTest31", - DetectEngineHttpClientBodyTest31, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hcbd.h b/framework/src/suricata/src/detect-engine-hcbd.h deleted file mode 100644 index 6dce3230..00000000 --- a/framework/src/suricata/src/detect-engine-hcbd.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HCBD_H__ -#define __DETECT_ENGINE_HCBD_H__ - -#define ENGINE_HCBD_BUFFER_LIMIT 20000 - -#include "app-layer-htp.h" - -int DetectEngineRunHttpClientBodyMpm(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -int DetectEngineInspectHttpClientBody(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -void DetectEngineCleanHCBDBuffers(DetectEngineThreadCtx *); - -void DetectEngineHttpClientBodyRegisterTests(void); - -#endif /* __DETECT_ENGINE_HCBD_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-hcd.c b/framework/src/suricata/src/detect-engine-hcd.c deleted file mode 100644 index 5fcfa51f..00000000 --- a/framework/src/suricata/src/detect-engine-hcd.c +++ /dev/null @@ -1,1878 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * - * \brief Handle HTTP cookie match - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-hcd.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -int DetectEngineRunHttpCookieMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - uint32_t cnt = 0; - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->request_headers == NULL) - goto end; - - htp_header_t *h = NULL; - if (flags & STREAM_TOSERVER) { - h = (htp_header_t *)htp_table_get_c(tx->request_headers, - "Cookie"); - if (h == NULL) { - SCLogDebug("HTTP cookie header not present in this request"); - goto end; - } - } else { - h = (htp_header_t *)htp_table_get_c(tx->response_headers, - "Set-Cookie"); - if (h == NULL) { - SCLogDebug("HTTP Set-Cookie header not present in this request"); - goto end; - } - } - - cnt = HttpCookiePatternSearch(det_ctx, - (uint8_t *)bstr_ptr(h->value), - bstr_len(h->value), flags); - end: - return cnt; -} - -/** - * \brief Do the http_cookie content inspection for a signature. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectHttpCookie(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - htp_tx_t *tx = (htp_tx_t *)txv; - htp_header_t *h = NULL; - if (flags & STREAM_TOSERVER) { - h = (htp_header_t *)htp_table_get_c(tx->request_headers, - "Cookie"); - if (h == NULL) { - SCLogDebug("HTTP cookie header not present in this request"); - goto end; - } - } else { - h = (htp_header_t *)htp_table_get_c(tx->response_headers, - "Set-Cookie"); - if (h == NULL) { - SCLogDebug("HTTP Set-Cookie header not present in this request"); - goto end; - } - } - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HCDMATCH], - f, - (uint8_t *)bstr_ptr(h->value), - bstr_len(h->value), - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HCD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - end: - if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest01(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CONNECT\"; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest02(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; depth:4; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest03(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"ECT\"; depth:4; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest04(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"ECT\"; depth:4; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest05(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"CON\"; depth:4; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"ECT\"; offset:3; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest07(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"CO\"; offset:3; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest08(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"ECT\"; offset:3; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest09(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CON\"; offset:3; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest10(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_cookie; " - "content:\"EC\"; within:4; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_cookie; " - "content:!\"EC\"; within:3; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_cookie; " - "content:\"EC\"; within:3; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_cookie; " - "content:!\"EC\"; within:4; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest14(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_cookie; " - "content:\"EC\"; distance:2; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest15(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_cookie; " - "content:!\"EC\"; distance:3; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest16(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_cookie; " - "content:\"EC\"; distance:3; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_cookie content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpCookieTest17(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Cookie: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_cookie; " - "content:!\"EC\"; distance:2; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpCookieRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpCookieTest01", - DetectEngineHttpCookieTest01, 1); - UtRegisterTest("DetectEngineHttpCookieTest02", - DetectEngineHttpCookieTest02, 1); - UtRegisterTest("DetectEngineHttpCookieTest03", - DetectEngineHttpCookieTest03, 1); - UtRegisterTest("DetectEngineHttpCookieTest04", - DetectEngineHttpCookieTest04, 1); - UtRegisterTest("DetectEngineHttpCookieTest05", - DetectEngineHttpCookieTest05, 1); - UtRegisterTest("DetectEngineHttpCookieTest06", - DetectEngineHttpCookieTest06, 1); - UtRegisterTest("DetectEngineHttpCookieTest07", - DetectEngineHttpCookieTest07, 1); - UtRegisterTest("DetectEngineHttpCookieTest08", - DetectEngineHttpCookieTest08, 1); - UtRegisterTest("DetectEngineHttpCookieTest09", - DetectEngineHttpCookieTest09, 1); - UtRegisterTest("DetectEngineHttpCookieTest10", - DetectEngineHttpCookieTest10, 1); - UtRegisterTest("DetectEngineHttpCookieTest11", - DetectEngineHttpCookieTest11, 1); - UtRegisterTest("DetectEngineHttpCookieTest12", - DetectEngineHttpCookieTest12, 1); - UtRegisterTest("DetectEngineHttpCookieTest13", - DetectEngineHttpCookieTest13, 1); - UtRegisterTest("DetectEngineHttpCookieTest14", - DetectEngineHttpCookieTest14, 1); - UtRegisterTest("DetectEngineHttpCookieTest15", - DetectEngineHttpCookieTest15, 1); - UtRegisterTest("DetectEngineHttpCookieTest16", - DetectEngineHttpCookieTest16, 1); - UtRegisterTest("DetectEngineHttpCookieTest17", - DetectEngineHttpCookieTest17, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hcd.h b/framework/src/suricata/src/detect-engine-hcd.h deleted file mode 100644 index 78f92407..00000000 --- a/framework/src/suricata/src/detect-engine-hcd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HCD_H__ -#define __DETECT_ENGINE_HCD_H__ - -#include "app-layer-htp.h" - -int DetectEngineInspectHttpCookie(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -int DetectEngineRunHttpCookieMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -void DetectEngineHttpCookieRegisterTests(void); - -#endif /* __DETECT_ENGINE_HCD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hhd.c b/framework/src/suricata/src/detect-engine-hhd.c deleted file mode 100644 index 3bec4fd2..00000000 --- a/framework/src/suricata/src/detect-engine-hhd.c +++ /dev/null @@ -1,3905 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * - * \brief Handle HTTP header match - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-hhd.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "util-memcmp.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -#define BUFFER_STEP 50 - -static inline int HHDCreateSpace(DetectEngineThreadCtx *det_ctx, uint64_t size) -{ - if (size >= (USHRT_MAX - BUFFER_STEP)) - return -1; - - void *ptmp; - if (size > det_ctx->hhd_buffers_size) { - ptmp = SCRealloc(det_ctx->hhd_buffers, - (det_ctx->hhd_buffers_size + BUFFER_STEP) * sizeof(uint8_t *)); - if (ptmp == NULL) { - SCFree(det_ctx->hhd_buffers); - det_ctx->hhd_buffers = NULL; - det_ctx->hhd_buffers_size = 0; - det_ctx->hhd_buffers_list_len = 0; - return -1; - } - det_ctx->hhd_buffers = ptmp; - - memset(det_ctx->hhd_buffers + det_ctx->hhd_buffers_size, 0, BUFFER_STEP * sizeof(uint8_t *)); - ptmp = SCRealloc(det_ctx->hhd_buffers_len, - (det_ctx->hhd_buffers_size + BUFFER_STEP) * sizeof(uint32_t)); - if (ptmp == NULL) { - SCFree(det_ctx->hhd_buffers_len); - det_ctx->hhd_buffers_len = NULL; - det_ctx->hhd_buffers_size = 0; - det_ctx->hhd_buffers_list_len = 0; - return -1; - } - det_ctx->hhd_buffers_len = ptmp; - - memset(det_ctx->hhd_buffers_len + det_ctx->hhd_buffers_size, 0, BUFFER_STEP * sizeof(uint32_t)); - det_ctx->hhd_buffers_size += BUFFER_STEP; - } - memset(det_ctx->hhd_buffers_len + det_ctx->hhd_buffers_list_len, 0, (size - det_ctx->hhd_buffers_list_len) * sizeof(uint32_t)); - - return 0; -} - -static uint8_t *DetectEngineHHDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Flow *f, HtpState *htp_state, - uint8_t flags, - uint32_t *buffer_len) -{ - uint8_t *headers_buffer = NULL; - int index = 0; - *buffer_len = 0; - - if (det_ctx->hhd_buffers_list_len == 0) { - /* get the inspect id to use as a 'base id' */ - uint64_t base_inspect_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - BUG_ON(base_inspect_id > tx_id); - /* see how many space we need for the current tx_id */ - uint64_t txs = (tx_id - base_inspect_id) + 1; - if (HHDCreateSpace(det_ctx, txs) < 0) - goto end; - - index = (tx_id - base_inspect_id); - det_ctx->hhd_start_tx_id = base_inspect_id; - det_ctx->hhd_buffers_list_len = txs; - } else { - /* tx fits in our current buffers */ - if ((tx_id - det_ctx->hhd_start_tx_id) < det_ctx->hhd_buffers_list_len) { - /* if we previously reassembled, return that buffer */ - if (det_ctx->hhd_buffers_len[(tx_id - det_ctx->hhd_start_tx_id)] != 0) { - *buffer_len = det_ctx->hhd_buffers_len[(tx_id - det_ctx->hhd_start_tx_id)]; - return det_ctx->hhd_buffers[(tx_id - det_ctx->hhd_start_tx_id)]; - } - /* otherwise fall through */ - } else { - /* not enough space, lets expand */ - uint64_t txs = (tx_id - det_ctx->hhd_start_tx_id) + 1; - if (HHDCreateSpace(det_ctx, txs) < 0) - goto end; - - det_ctx->hhd_buffers_list_len = txs; - } - index = (tx_id - det_ctx->hhd_start_tx_id); - } - - htp_table_t *headers; - if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) <= HTP_REQUEST_HEADERS) - goto end; - headers = tx->request_headers; - } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) <= HTP_RESPONSE_HEADERS) - goto end; - headers = tx->response_headers; - } - if (headers == NULL) - goto end; - - htp_header_t *h = NULL; - headers_buffer = det_ctx->hhd_buffers[index]; - size_t headers_buffer_len = 0; - size_t i = 0; - - size_t no_of_headers = htp_table_size(headers); - for (; i < no_of_headers; i++) { - h = htp_table_get_index(headers, i, NULL); - size_t size1 = bstr_size(h->name); - size_t size2 = bstr_size(h->value); - - if (flags & STREAM_TOSERVER) { - if (size1 == 6 && - SCMemcmpLowercase("cookie", bstr_ptr(h->name), 6) == 0) { - continue; - } - } else { - if (size1 == 10 && - SCMemcmpLowercase("set-cookie", bstr_ptr(h->name), 10) == 0) { - continue; - } - } - - /* the extra 4 bytes if for ": " and "\r\n" */ - uint8_t *new_headers_buffer = SCRealloc(headers_buffer, headers_buffer_len + size1 + size2 + 4); - if (unlikely(new_headers_buffer == NULL)) { - if (headers_buffer != NULL) { - SCFree(headers_buffer); - headers_buffer = NULL; - } - det_ctx->hhd_buffers[index] = NULL; - det_ctx->hhd_buffers_len[index] = 0; - goto end; - } - headers_buffer = new_headers_buffer; - - memcpy(headers_buffer + headers_buffer_len, bstr_ptr(h->name), size1); - headers_buffer_len += size1; - headers_buffer[headers_buffer_len] = ':'; - headers_buffer[headers_buffer_len + 1] = ' '; - headers_buffer_len += 2; - memcpy(headers_buffer + headers_buffer_len, bstr_ptr(h->value), size2); - headers_buffer_len += size2 + 2; - /* \r */ - headers_buffer[headers_buffer_len - 2] = '\r'; - /* \n */ - headers_buffer[headers_buffer_len - 1] = '\n'; - } - - /* store the buffers. We will need it for further inspection */ - det_ctx->hhd_buffers[index] = headers_buffer; - det_ctx->hhd_buffers_len[index] = headers_buffer_len; - - *buffer_len = (uint32_t)headers_buffer_len; - end: - return headers_buffer; -} - -int DetectEngineRunHttpHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx) -{ - uint32_t cnt = 0; - uint32_t buffer_len = 0; - uint8_t *buffer = DetectEngineHHDGetBufferForTX(tx, idx, - NULL, det_ctx, - f, htp_state, - flags, - &buffer_len); - if (buffer_len == 0) - goto end; - - cnt = HttpHeaderPatternSearch(det_ctx, buffer, buffer_len, flags); - - end: - return cnt; -} - -int DetectEngineInspectHttpHeader(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id) -{ - HtpState *htp_state = (HtpState *)alstate; - uint32_t buffer_len = 0; - uint8_t *buffer = DetectEngineHHDGetBufferForTX(tx, tx_id, - de_ctx, det_ctx, - f, htp_state, - flags, - &buffer_len); - if (buffer_len == 0) - goto end; - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HHDMATCH], - f, - buffer, - buffer_len, - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HHD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - end: - if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -void DetectEngineCleanHHDBuffers(DetectEngineThreadCtx *det_ctx) -{ - if (det_ctx->hhd_buffers_list_len != 0) { - int i; - for (i = 0; i < det_ctx->hhd_buffers_list_len; i++) { - det_ctx->hhd_buffers_len[i] = 0; - } - det_ctx->hhd_buffers_list_len = 0; - } - det_ctx->hhd_start_tx_id = 0; - - return; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest01(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest02(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; depth:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest03(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"one\"; depth:5; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest04(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; depth:5; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest05(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"one\"; depth:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; offset:10; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest07(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"one\"; offset:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest08(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; offset:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest09(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"one\"; offset:10; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest10(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:\"three\"; http_header; within:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:!\"three\"; http_header; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:!\"three\"; http_header; within:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:\"three\"; http_header; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest14(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:\"five\"; http_header; distance:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest15(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:!\"five\"; http_header; distance:15; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest16(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:!\"five\"; http_header; distance:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest17(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:\"five\"; http_header; distance:15; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest18(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "Host: www.onetwothreefourfivesixsevenfive.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:\"five\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = HttpHeaderPatternSearch(det_ctx, http_buf, http_len, STREAM_TOSERVER); - if (r != 2) { - printf("expected result 2, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest19(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "Host: www.onetwothreefourfivesixsevenfive.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; fast_pattern; content:\"five\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = HttpHeaderPatternSearch(det_ctx, http_buf, http_len, STREAM_TOSERVER); - if (r != 1) { - printf("expected result 1, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHeaderTest20(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:!\"dummy\"; http_header; within:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpHeaderTest21(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:!\"dummy\"; within:7; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpHeaderTest22(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:!\"dummy\"; distance:3; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpHeaderTest23(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:!\"dummy\"; distance:13; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpHeaderTest24(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:\"dummy\"; within:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpHeaderTest25(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:\"dummy\"; within:10; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpHeaderTest26(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:\"dummy\"; distance:8; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpHeaderTest27(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:\"dummy\"; distance:14; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpHeaderTest28(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Content-Length: 6\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, - http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpHeaderTest29(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Content-Length: 7\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, - http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -#if 0 - -static int DetectEngineHttpHeaderTest30(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Content-Length: 6\"; http_header; " - "content:\"User-Agent: Mozilla\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list != NULL) { - goto end; - } - - result = 1; - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* #if 0 */ - -static int DetectEngineHttpHeaderTest30(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Set-Cookie: dummycookieset\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"dummycookieset\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, - http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** \test reassembly bug where headers with names of length 6 were - * skipped - */ -static int DetectEngineHttpHeaderTest31(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Accept: blah\r\n" - "Cookie: blah\r\n" - "Crazy6: blah\r\n" - "SixZix: blah\r\n\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(content:\"Accept|3a|\"; http_header; " - "content:!\"Cookie|3a|\"; http_header; " - "content:\"Crazy6|3a|\"; http_header; " - "content:\"SixZix|3a|\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -/** - * \test Trailing headers. - */ -static int DetectEngineHttpHeaderTest32(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "host: boom\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n" - "13\r\n" - "This is dummy body1\r\n" - "0\r\n" - "Dummy-Header: kaboom\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(content:\"Dummy\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -/** - * \test Trailing headers. - */ -static int DetectEngineHttpHeaderTest33(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "host: boom\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n" - "13\r\n" - "This is dummy body1\r\n" - "0\r\n"; - uint8_t http2_buf[] = - "Dummy-Header: kaboom\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(content:\"Dummy\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpHeaderRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpHeaderTest01", - DetectEngineHttpHeaderTest01, 1); - UtRegisterTest("DetectEngineHttpHeaderTest02", - DetectEngineHttpHeaderTest02, 1); - UtRegisterTest("DetectEngineHttpHeaderTest03", - DetectEngineHttpHeaderTest03, 1); - UtRegisterTest("DetectEngineHttpHeaderTest04", - DetectEngineHttpHeaderTest04, 1); - UtRegisterTest("DetectEngineHttpHeaderTest05", - DetectEngineHttpHeaderTest05, 1); - UtRegisterTest("DetectEngineHttpHeaderTest06", - DetectEngineHttpHeaderTest06, 1); - UtRegisterTest("DetectEngineHttpHeaderTest07", - DetectEngineHttpHeaderTest07, 1); - UtRegisterTest("DetectEngineHttpHeaderTest08", - DetectEngineHttpHeaderTest08, 1); - UtRegisterTest("DetectEngineHttpHeaderTest09", - DetectEngineHttpHeaderTest09, 1); - UtRegisterTest("DetectEngineHttpHeaderTest10", - DetectEngineHttpHeaderTest10, 1); - UtRegisterTest("DetectEngineHttpHeaderTest11", - DetectEngineHttpHeaderTest11, 1); - UtRegisterTest("DetectEngineHttpHeaderTest12", - DetectEngineHttpHeaderTest12, 1); - UtRegisterTest("DetectEngineHttpHeaderTest13", - DetectEngineHttpHeaderTest13, 1); - UtRegisterTest("DetectEngineHttpHeaderTest14", - DetectEngineHttpHeaderTest14, 1); - UtRegisterTest("DetectEngineHttpHeaderTest15", - DetectEngineHttpHeaderTest15, 1); - UtRegisterTest("DetectEngineHttpHeaderTest16", - DetectEngineHttpHeaderTest16, 1); - UtRegisterTest("DetectEngineHttpHeaderTest17", - DetectEngineHttpHeaderTest17, 1); - UtRegisterTest("DetectEngineHttpHeaderTest18", - DetectEngineHttpHeaderTest18, 1); - UtRegisterTest("DetectEngineHttpHeaderTest19", - DetectEngineHttpHeaderTest19, 1); - UtRegisterTest("DetectEngineHttpHeaderTest20", - DetectEngineHttpHeaderTest20, 1); - UtRegisterTest("DetectEngineHttpHeaderTest21", - DetectEngineHttpHeaderTest21, 1); - UtRegisterTest("DetectEngineHttpHeaderTest22", - DetectEngineHttpHeaderTest22, 1); - UtRegisterTest("DetectEngineHttpHeaderTest23", - DetectEngineHttpHeaderTest23, 1); - UtRegisterTest("DetectEngineHttpHeaderTest24", - DetectEngineHttpHeaderTest24, 1); - UtRegisterTest("DetectEngineHttpHeaderTest25", - DetectEngineHttpHeaderTest25, 1); - UtRegisterTest("DetectEngineHttpHeaderTest26", - DetectEngineHttpHeaderTest26, 1); - UtRegisterTest("DetectEngineHttpHeaderTest27", - DetectEngineHttpHeaderTest27, 1); - UtRegisterTest("DetectEngineHttpHeaderTest28", - DetectEngineHttpHeaderTest28, 1); - UtRegisterTest("DetectEngineHttpHeaderTest29", - DetectEngineHttpHeaderTest29, 1); - UtRegisterTest("DetectEngineHttpHeaderTest30", - DetectEngineHttpHeaderTest30, 1); - UtRegisterTest("DetectEngineHttpHeaderTest31", - DetectEngineHttpHeaderTest31, 1); -#if 0 - UtRegisterTest("DetectEngineHttpHeaderTest30", - DetectEngineHttpHeaderTest30, 1); -#endif - UtRegisterTest("DetectEngineHttpHeaderTest32", - DetectEngineHttpHeaderTest32, 1); - UtRegisterTest("DetectEngineHttpHeaderTest33", - DetectEngineHttpHeaderTest33, 1); - -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hhd.h b/framework/src/suricata/src/detect-engine-hhd.h deleted file mode 100644 index e163000c..00000000 --- a/framework/src/suricata/src/detect-engine-hhd.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HHD_H__ -#define __DETECT_ENGINE_HHD_H__ - -#include "app-layer-htp.h" - -int DetectEngineInspectHttpHeader(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -int DetectEngineRunHttpHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -void DetectEngineCleanHHDBuffers(DetectEngineThreadCtx *det_ctx); - -void DetectEngineHttpHeaderRegisterTests(void); - -#endif /* __DETECT_ENGINE_HHD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hhhd.c b/framework/src/suricata/src/detect-engine-hhhd.c deleted file mode 100644 index 65aebd07..00000000 --- a/framework/src/suricata/src/detect-engine-hhhd.c +++ /dev/null @@ -1,2616 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * - * \brief Handle HTTP host header. - * HHHD - Http Host Header Data - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -#include "detect-engine-hhhd.h" - -int DetectEngineRunHttpHHMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - uint32_t cnt = 0; - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->request_hostname == NULL) - goto end; - uint8_t *hname = (uint8_t *)bstr_ptr(tx->request_hostname); - if (hname == NULL) - goto end; - uint32_t hname_len = bstr_len(tx->request_hostname); - - cnt += HttpHHPatternSearch(det_ctx, hname, hname_len, flags); - - end: - return cnt; -} - -/** - * \brief Do the http_header content inspection for a signature. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectHttpHH(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->parsed_uri == NULL || tx->request_hostname == NULL) - goto end; - uint8_t *hname = (uint8_t *)bstr_ptr(tx->request_hostname); - if (hname == NULL) - goto end; - uint32_t hname_len = bstr_len(tx->request_hostname); - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HHHDMATCH], - f, - hname, hname_len, - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HHHD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -/** - * \test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest01(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"connect\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest02(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"co\"; depth:4; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest03(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:!\"ect\"; depth:4; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest04(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"ect\"; depth:4; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest05(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:!\"con\"; depth:4; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"ect\"; offset:3; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest07(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:!\"co\"; offset:3; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest08(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:!\"ect\"; offset:3; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest09(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"con\"; offset:3; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest10(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"co\"; http_host; " - "content:\"ec\"; within:4; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"co\"; http_host; " - "content:!\"ec\"; within:3; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"co\"; http_host; " - "content:\"ec\"; within:3; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"co\"; http_host; " - "content:!\"ec\"; within:4; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest14(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"co\"; http_host; " - "content:\"ec\"; distance:2; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest15(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"co\"; http_host; " - "content:!\"ec\"; distance:3; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest16(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"co\"; http_host; " - "content:\"ec\"; distance:3; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHHTest17(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"co\"; http_host; " - "content:!\"ec\"; distance:2; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHHTest18(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.kaboom.com\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"kaboom\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHHTest19(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.kaboom.com:8080\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"kaboom\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHHTest20(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.kaboom.com:8080\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"8080\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHHTest21(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com/index.html HTTP/1.0\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"kaboom\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHHTest22(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"kaboom\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHHTest23(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"8080\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHHTest24(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n" - "Host: www.rabbit.com\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"kaboom\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHHTest25(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n" - "Host: www.rabbit.com\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_host header test\"; " - "content:\"rabbit\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpHHRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpHHTest01", - DetectEngineHttpHHTest01, 1); - UtRegisterTest("DetectEngineHttpHHTest02", - DetectEngineHttpHHTest02, 1); - UtRegisterTest("DetectEngineHttpHHTest03", - DetectEngineHttpHHTest03, 1); - UtRegisterTest("DetectEngineHttpHHTest04", - DetectEngineHttpHHTest04, 1); - UtRegisterTest("DetectEngineHttpHHTest05", - DetectEngineHttpHHTest05, 1); - UtRegisterTest("DetectEngineHttpHHTest06", - DetectEngineHttpHHTest06, 1); - UtRegisterTest("DetectEngineHttpHHTest07", - DetectEngineHttpHHTest07, 1); - UtRegisterTest("DetectEngineHttpHHTest08", - DetectEngineHttpHHTest08, 1); - UtRegisterTest("DetectEngineHttpHHTest09", - DetectEngineHttpHHTest09, 1); - UtRegisterTest("DetectEngineHttpHHTest10", - DetectEngineHttpHHTest10, 1); - UtRegisterTest("DetectEngineHttpHHTest11", - DetectEngineHttpHHTest11, 1); - UtRegisterTest("DetectEngineHttpHHTest12", - DetectEngineHttpHHTest12, 1); - UtRegisterTest("DetectEngineHttpHHTest13", - DetectEngineHttpHHTest13, 1); - UtRegisterTest("DetectEngineHttpHHTest14", - DetectEngineHttpHHTest14, 1); - UtRegisterTest("DetectEngineHttpHHTest15", - DetectEngineHttpHHTest15, 1); - UtRegisterTest("DetectEngineHttpHHTest16", - DetectEngineHttpHHTest16, 1); - UtRegisterTest("DetectEngineHttpHHTest17", - DetectEngineHttpHHTest17, 1); - UtRegisterTest("DetectEngineHttpHHTest18", - DetectEngineHttpHHTest18, 1); - UtRegisterTest("DetectEngineHttpHHTest19", - DetectEngineHttpHHTest19, 1); - UtRegisterTest("DetectEngineHttpHHTest20", - DetectEngineHttpHHTest20, 1); - UtRegisterTest("DetectEngineHttpHHTest21", - DetectEngineHttpHHTest21, 1); - UtRegisterTest("DetectEngineHttpHHTest22", - DetectEngineHttpHHTest22, 1); - UtRegisterTest("DetectEngineHttpHHTest23", - DetectEngineHttpHHTest23, 1); - UtRegisterTest("DetectEngineHttpHHTest24", - DetectEngineHttpHHTest24, 1); - UtRegisterTest("DetectEngineHttpHHTest25", - DetectEngineHttpHHTest25, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hhhd.h b/framework/src/suricata/src/detect-engine-hhhd.h deleted file mode 100644 index e6cec907..00000000 --- a/framework/src/suricata/src/detect-engine-hhhd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HHHD_H__ -#define __DETECT_ENGINE_HHHD_H__ - -#include "app-layer-htp.h" - -int DetectEngineInspectHttpHH(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -int DetectEngineRunHttpHHMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -void DetectEngineHttpHHRegisterTests(void); - -#endif /* __DETECT_ENGINE_HHHD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hmd.c b/framework/src/suricata/src/detect-engine-hmd.c deleted file mode 100644 index 5a4b7d8a..00000000 --- a/framework/src/suricata/src/detect-engine-hmd.c +++ /dev/null @@ -1,1827 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * - * \brief Handle HTTP method match - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-hmd.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -int DetectEngineRunHttpMethodMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - uint32_t cnt = 0; - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->request_method == NULL) - goto end; - cnt = HttpMethodPatternSearch(det_ctx, - (uint8_t *)bstr_ptr(tx->request_method), - bstr_len(tx->request_method), - flags); - - end: - return cnt; -} - -/** - * \brief Do the http_method content inspection for a signature. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectHttpMethod(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->request_method == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_LINE) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HMDMATCH], - f, - (uint8_t *)bstr_ptr(tx->request_method), - bstr_len(tx->request_method), - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HMD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest01(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"GET\"; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest02(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; depth:4; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest03(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"ECT\"; depth:4; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest04(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"ECT\"; depth:4; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest05(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"CON\"; depth:4; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"ECT\"; offset:3; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest07(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"CO\"; offset:3; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest08(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"ECT\"; offset:3; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest09(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CON\"; offset:3; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest10(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_method; " - "content:\"EC\"; within:4; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_method; " - "content:!\"EC\"; within:3; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_method; " - "content:\"EC\"; within:3; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_method; " - "content:!\"EC\"; within:4; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest14(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_method; " - "content:\"EC\"; distance:2; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest15(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_method; " - "content:!\"EC\"; distance:3; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest16(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_method; " - "content:\"EC\"; distance:3; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_method content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpMethodTest17(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"CO\"; http_method; " - "content:!\"EC\"; distance:2; http_method; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpMethodRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpMethodTest01", - DetectEngineHttpMethodTest01, 1); - UtRegisterTest("DetectEngineHttpMethodTest02", - DetectEngineHttpMethodTest02, 1); - UtRegisterTest("DetectEngineHttpMethodTest03", - DetectEngineHttpMethodTest03, 1); - UtRegisterTest("DetectEngineHttpMethodTest04", - DetectEngineHttpMethodTest04, 1); - UtRegisterTest("DetectEngineHttpMethodTest05", - DetectEngineHttpMethodTest05, 1); - UtRegisterTest("DetectEngineHttpMethodTest06", - DetectEngineHttpMethodTest06, 1); - UtRegisterTest("DetectEngineHttpMethodTest07", - DetectEngineHttpMethodTest07, 1); - UtRegisterTest("DetectEngineHttpMethodTest08", - DetectEngineHttpMethodTest08, 1); - UtRegisterTest("DetectEngineHttpMethodTest09", - DetectEngineHttpMethodTest09, 1); - UtRegisterTest("DetectEngineHttpMethodTest10", - DetectEngineHttpMethodTest10, 1); - UtRegisterTest("DetectEngineHttpMethodTest11", - DetectEngineHttpMethodTest11, 1); - UtRegisterTest("DetectEngineHttpMethodTest12", - DetectEngineHttpMethodTest12, 1); - UtRegisterTest("DetectEngineHttpMethodTest13", - DetectEngineHttpMethodTest13, 1); - UtRegisterTest("DetectEngineHttpMethodTest14", - DetectEngineHttpMethodTest14, 1); - UtRegisterTest("DetectEngineHttpMethodTest15", - DetectEngineHttpMethodTest15, 1); - UtRegisterTest("DetectEngineHttpMethodTest16", - DetectEngineHttpMethodTest16, 1); - UtRegisterTest("DetectEngineHttpMethodTest17", - DetectEngineHttpMethodTest17, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hmd.h b/framework/src/suricata/src/detect-engine-hmd.h deleted file mode 100644 index faf26aa2..00000000 --- a/framework/src/suricata/src/detect-engine-hmd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HMD_H__ -#define __DETECT_ENGINE_HMD_H__ - -#include "app-layer-htp.h" - -int DetectEngineInspectHttpMethod(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -int DetectEngineRunHttpMethodMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -void DetectEngineHttpMethodRegisterTests(void); - -#endif /* __DETECT_ENGINE_HMD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hrhd.c b/framework/src/suricata/src/detect-engine-hrhd.c deleted file mode 100644 index 90cf1d5e..00000000 --- a/framework/src/suricata/src/detect-engine-hrhd.c +++ /dev/null @@ -1,3545 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * - * \brief Handle HTTP raw header match. - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-hrhd.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - - -int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - SCEnter(); - - uint32_t cnt = 0; - htp_tx_t *tx = (htp_tx_t *)txv; - HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud == NULL) - SCReturnInt(cnt); - - if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) <= HTP_REQUEST_HEADERS) - SCReturnInt(cnt); - - if (tx_ud->request_headers_raw != NULL) { - cnt = HttpRawHeaderPatternSearch(det_ctx, - tx_ud->request_headers_raw, - tx_ud->request_headers_raw_len, - flags); - } - } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) <= HTP_RESPONSE_HEADERS) - SCReturnInt(cnt); - - if (tx_ud->response_headers_raw != NULL) { - cnt += HttpRawHeaderPatternSearch(det_ctx, - tx_ud->response_headers_raw, - tx_ud->response_headers_raw_len, - flags); - } - } - - SCReturnInt(cnt); -} - -/** - * \brief Do the http_raw_header content inspection for a signature. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectHttpRawHeader(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - HtpTxUserData *tx_ud = NULL; - uint8_t *headers_raw = NULL; - uint32_t headers_raw_len = 0; - - if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) <= HTP_REQUEST_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) <= HTP_RESPONSE_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } - - tx_ud = htp_tx_get_user_data(txv); - if (tx_ud == NULL) - goto end; - if (flags & STREAM_TOSERVER) { - headers_raw = tx_ud->request_headers_raw; - headers_raw_len = tx_ud->request_headers_raw_len; - } else { - headers_raw = tx_ud->response_headers_raw; - headers_raw_len = tx_ud->response_headers_raw_len; - } - if (headers_raw == NULL) - goto end; - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRHDMATCH], - f, - headers_raw, - headers_raw_len, - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - end: - if (flags & STREAM_TOSERVER) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_REQUEST_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } else { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_RESPONSE_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest01(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest02(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; depth:15; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest03(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:!\"one\"; depth:5; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest04(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; depth:5; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest05(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:!\"one\"; depth:15; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; offset:10; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest07(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:!\"one\"; offset:15; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest08(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; offset:15; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest09(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:!\"one\"; offset:10; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest10(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:\"three\"; http_raw_header; within:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:!\"three\"; http_raw_header; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:!\"three\"; http_raw_header; within:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:\"three\"; http_raw_header; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest14(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:\"five\"; http_raw_header; distance:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest15(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:!\"five\"; http_raw_header; distance:15; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest16(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:!\"five\"; http_raw_header; distance:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest17(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:\"five\"; http_raw_header; distance:15; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest18(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "Host: www.onetwothreefourfivesixsevenfive.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; content:\"five\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = HttpRawHeaderPatternSearch(det_ctx, http_buf, http_len, STREAM_TOSERVER); - if (r != 2) { - printf("expected result 2, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpRawHeaderTest19(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "Host: www.onetwothreefourfivesixsevenfive.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"one\"; http_raw_header; fast_pattern; content:\"five\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = HttpRawHeaderPatternSearch(det_ctx, http_buf, http_len, STREAM_TOSERVER); - if (r != 1) { - printf("expected result 1, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest20(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; flow:to_server; " - "pcre:/body1/D; " - "content:!\"dummy\"; http_raw_header; within:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest21(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; flow:to_server; " - "pcre:/body1/D; " - "content:!\"dummy\"; within:7; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest22(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; flow:to_server; " - "pcre:/body1/D; " - "content:!\"dummy\"; distance:3; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest23(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; flow:to_server; " - "pcre:/body1/D; " - "content:!\"dummy\"; distance:13; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest24(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; flow:to_server; " - "pcre:/body1/D; " - "content:\"dummy\"; within:15; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest25(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; flow:to_server; " - "pcre:/body1/D; " - "content:\"dummy\"; within:10; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest26(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; flow:to_server; " - "pcre:/body1/D; " - "content:\"dummy\"; distance:8; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest27(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; flow:to_server; " - "pcre:/body1/D; " - "content:\"dummy\"; distance:14; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest28(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_client; " - "content:\"Content-Length: 6\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, - http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawHeaderTest29(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_client; " - "content:\"Content-Length: 7\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, - http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -#if 0 - -static int DetectEngineHttpRawHeaderTest30(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Content-Length: 6\"; http_raw_header; " - "content:\"User-Agent: Mozilla\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list != NULL) { - goto end; - } - - result = 1; - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* #if 0 */ - -/** - * \test Trailing headers. - */ -static int DetectEngineHttpRawHeaderTest31(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "host: boom\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n" - "13\r\n" - "This is dummy body1\r\n" - "0\r\n" - "Dummy-Header: kaboom\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(flow:to_server; " - "content:\"Dummy\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -/** - * \test Trailing headers. - */ -static int DetectEngineHttpRawHeaderTest32(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "host: boom\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n" - "13\r\n" - "This is dummy body1\r\n" - "0\r\n"; - uint8_t http2_buf[] = - "Dummy-Header: kaboom\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(flow:to_server; " - "content:\"Dummy\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpRawHeaderRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpRawHeaderTest01", - DetectEngineHttpRawHeaderTest01, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest02", - DetectEngineHttpRawHeaderTest02, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest03", - DetectEngineHttpRawHeaderTest03, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest04", - DetectEngineHttpRawHeaderTest04, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest05", - DetectEngineHttpRawHeaderTest05, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest06", - DetectEngineHttpRawHeaderTest06, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest07", - DetectEngineHttpRawHeaderTest07, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest08", - DetectEngineHttpRawHeaderTest08, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest09", - DetectEngineHttpRawHeaderTest09, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest10", - DetectEngineHttpRawHeaderTest10, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest11", - DetectEngineHttpRawHeaderTest11, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest12", - DetectEngineHttpRawHeaderTest12, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest13", - DetectEngineHttpRawHeaderTest13, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest14", - DetectEngineHttpRawHeaderTest14, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest15", - DetectEngineHttpRawHeaderTest15, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest16", - DetectEngineHttpRawHeaderTest16, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest17", - DetectEngineHttpRawHeaderTest17, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest18", - DetectEngineHttpRawHeaderTest18, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest19", - DetectEngineHttpRawHeaderTest19, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest20", - DetectEngineHttpRawHeaderTest20, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest21", - DetectEngineHttpRawHeaderTest21, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest22", - DetectEngineHttpRawHeaderTest22, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest23", - DetectEngineHttpRawHeaderTest23, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest24", - DetectEngineHttpRawHeaderTest24, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest25", - DetectEngineHttpRawHeaderTest25, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest26", - DetectEngineHttpRawHeaderTest26, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest27", - DetectEngineHttpRawHeaderTest27, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest28", - DetectEngineHttpRawHeaderTest28, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest29", - DetectEngineHttpRawHeaderTest29, 1); -#if 0 - UtRegisterTest("DetectEngineHttpRawHeaderTest30", - DetectEngineHttpRawHeaderTest30, 1); -#endif - UtRegisterTest("DetectEngineHttpRawHeaderTest31", - DetectEngineHttpRawHeaderTest31, 1); - UtRegisterTest("DetectEngineHttpRawHeaderTest32", - DetectEngineHttpRawHeaderTest32, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hrhd.h b/framework/src/suricata/src/detect-engine-hrhd.h deleted file mode 100644 index c33d57e7..00000000 --- a/framework/src/suricata/src/detect-engine-hrhd.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HRHD_H__ -#define __DETECT_ENGINE_HRHD_H__ - -#include "app-layer-htp.h" - -int DetectEngineInspectHttpRawHeader(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -void DetectEngineHttpRawHeaderRegisterTests(void); - -#endif /* __DETECT_ENGINE_HHD_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-hrhhd.c b/framework/src/suricata/src/detect-engine-hrhhd.c deleted file mode 100644 index f1acf100..00000000 --- a/framework/src/suricata/src/detect-engine-hrhhd.c +++ /dev/null @@ -1,2643 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * - * \brief Handle HTTP host header. - * HRHHD - Http Raw Host Header Data - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -#include "detect-engine-hrhhd.h" - -int DetectEngineRunHttpHRHMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - uint32_t cnt = 0; - htp_tx_t *tx = (htp_tx_t *)txv; - uint8_t *hname = NULL; - uint32_t hname_len = 0; - - if (tx->parsed_uri == NULL || tx->parsed_uri->hostname == NULL) { - if (tx->request_headers == NULL) - goto end; - htp_header_t *h = NULL; - h = (htp_header_t *)htp_table_get_c(tx->request_headers, "Host"); - if (h != NULL) { - SCLogDebug("HTTP host header not present in this request"); - hname = (uint8_t *)bstr_ptr(h->value); - hname_len = bstr_len(h->value); - } else { - goto end; - } - } else { - hname = (uint8_t *)bstr_ptr(tx->parsed_uri->hostname); - if (hname != NULL) - hname_len = bstr_len(tx->parsed_uri->hostname); - else - goto end; - } - - cnt = HttpHRHPatternSearch(det_ctx, hname, hname_len, flags); - - end: - return cnt; -} - -/** - * \brief Do the http_header content inspection for a signature. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectHttpHRH(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - uint8_t *hname; - uint32_t hname_len; - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->parsed_uri == NULL || tx->parsed_uri->hostname == NULL) { - htp_header_t *h = NULL; - h = (htp_header_t *)htp_table_get_c(tx->request_headers, "Host"); - if (h == NULL) { - SCLogDebug("HTTP host header not present in this request"); - goto end; - } - hname = (uint8_t *)bstr_ptr(h->value); - hname_len = bstr_len(h->value); - } else { - hname = (uint8_t *)bstr_ptr(tx->parsed_uri->hostname); - if (hname == NULL) - goto end; - hname_len = bstr_len(tx->parsed_uri->hostname); - } - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRHHDMATCH], - f, - hname, hname_len, - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHHD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -/** - * \test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest01(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"CONNECT\"; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest02(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"CO\"; depth:4; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest03(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:!\"ECT\"; depth:4; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest04(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"ECT\"; depth:4; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest05(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:!\"CON\"; depth:4; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"ECT\"; offset:3; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest07(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:!\"CO\"; offset:3; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest08(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:!\"ECT\"; offset:3; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest09(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host header test\"; " - "content:\"CON\"; offset:3; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest10(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"CO\"; http_raw_host; " - "content:\"EC\"; within:4; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"CO\"; http_raw_host; " - "content:!\"EC\"; within:3; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"CO\"; http_raw_host; " - "content:\"EC\"; within:3; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"CO\"; http_raw_host; " - "content:!\"EC\"; within:4; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest14(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"CO\"; http_raw_host; " - "content:\"EC\"; distance:2; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest15(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"CO\"; http_raw_host; " - "content:!\"EC\"; distance:3; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest16(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"CO\"; http_raw_host; " - "content:\"EC\"; distance:3; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHRHTest17(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: CONNECT\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"CO\"; http_raw_host; " - "content:!\"EC\"; distance:2; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHRHTest18(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.kaboom.com:8080\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"kaboom\"; http_raw_host; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHRHTest19(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.kaboom.com:8080\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"kaboom\"; http_raw_host; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHRHTest20(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.kaboom.com:8080\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"8080\"; http_raw_host; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHRHTest21(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com/index.html HTTP/1.0\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"kaboom\"; http_raw_host; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHRHTest22(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"kaboom\"; http_raw_host; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHRHTest23(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"8080\"; http_raw_host; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHRHTest24(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n" - "Host: www.rabbit.com\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"kaboom\"; http_raw_host; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectEngineHttpHRHTest25(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET http://www.kaboom.com:8080/index.html HTTP/1.0\r\n" - "Host: www.rabbit.com\r\n" - "User-Agent: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_raw_host header test\"; " - "content:\"rabbit\"; http_raw_host; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpHRHRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpHRHTest01", - DetectEngineHttpHRHTest01, 1); - UtRegisterTest("DetectEngineHttpHRHTest02", - DetectEngineHttpHRHTest02, 1); - UtRegisterTest("DetectEngineHttpHRHTest03", - DetectEngineHttpHRHTest03, 1); - UtRegisterTest("DetectEngineHttpHRHTest04", - DetectEngineHttpHRHTest04, 1); - UtRegisterTest("DetectEngineHttpHRHTest05", - DetectEngineHttpHRHTest05, 1); - UtRegisterTest("DetectEngineHttpHRHTest06", - DetectEngineHttpHRHTest06, 1); - UtRegisterTest("DetectEngineHttpHRHTest07", - DetectEngineHttpHRHTest07, 1); - UtRegisterTest("DetectEngineHttpHRHTest08", - DetectEngineHttpHRHTest08, 1); - UtRegisterTest("DetectEngineHttpHRHTest09", - DetectEngineHttpHRHTest09, 1); - UtRegisterTest("DetectEngineHttpHRHTest10", - DetectEngineHttpHRHTest10, 1); - UtRegisterTest("DetectEngineHttpHRHTest11", - DetectEngineHttpHRHTest11, 1); - UtRegisterTest("DetectEngineHttpHRHTest12", - DetectEngineHttpHRHTest12, 1); - UtRegisterTest("DetectEngineHttpHRHTest13", - DetectEngineHttpHRHTest13, 1); - UtRegisterTest("DetectEngineHttpHRHTest14", - DetectEngineHttpHRHTest14, 1); - UtRegisterTest("DetectEngineHttpHRHTest15", - DetectEngineHttpHRHTest15, 1); - UtRegisterTest("DetectEngineHttpHRHTest16", - DetectEngineHttpHRHTest16, 1); - UtRegisterTest("DetectEngineHttpHRHTest17", - DetectEngineHttpHRHTest17, 1); - UtRegisterTest("DetectEngineHttpHRHTest18", - DetectEngineHttpHRHTest18, 1); - UtRegisterTest("DetectEngineHttpHRHTest19", - DetectEngineHttpHRHTest19, 1); - UtRegisterTest("DetectEngineHttpHRHTest20", - DetectEngineHttpHRHTest20, 1); - UtRegisterTest("DetectEngineHttpHRHTest21", - DetectEngineHttpHRHTest21, 1); - UtRegisterTest("DetectEngineHttpHRHTest22", - DetectEngineHttpHRHTest22, 1); - UtRegisterTest("DetectEngineHttpHRHTest23", - DetectEngineHttpHRHTest23, 1); - UtRegisterTest("DetectEngineHttpHRHTest24", - DetectEngineHttpHRHTest24, 1); - UtRegisterTest("DetectEngineHttpHRHTest25", - DetectEngineHttpHRHTest25, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hrhhd.h b/framework/src/suricata/src/detect-engine-hrhhd.h deleted file mode 100644 index 24c3b43e..00000000 --- a/framework/src/suricata/src/detect-engine-hrhhd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HRHHD_H__ -#define __DETECT_ENGINE_HRHHD_H__ - -#include "app-layer-htp.h" - -int DetectEngineInspectHttpHRH(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -int DetectEngineRunHttpHRHMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -void DetectEngineHttpHRHRegisterTests(void); - -#endif /* __DETECT_ENGINE_HRHHD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hrl.c b/framework/src/suricata/src/detect-engine-hrl.c deleted file mode 100644 index 5e5c0cb6..00000000 --- a/framework/src/suricata/src/detect-engine-hrl.c +++ /dev/null @@ -1,4221 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - * - * Based on detect-engine-uri.c - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -/** - * \brief Do the content inspection & validation for a signature - * - * \param de_ctx Detection engine context - * \param det_ctx Detection engine thread context - * \param s Signature to inspect - * \param sm SigMatch to inspect - * \param f Flow - * \param flags app layer flags - * \param state App layer state - * - * \retval 0 no match. - * \retval 1 match. - * \retval 2 Sig can't match. - */ -int DetectEngineInspectHttpRequestLine(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - htp_tx_t *tx = (htp_tx_t *)txv; - - if (tx->request_line == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_REQUEST_LINE) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } - - det_ctx->discontinue_matching = 0; - det_ctx->buffer_offset = 0; - det_ctx->inspection_recursion_counter = 0; - -#if 0 - PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx_ud->request_uri_normalized), - bstr_len(tx_ud->request_uri_normalized)); -#endif - - /* Inspect all the uricontents fetched on each - * transaction at the app layer */ - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRLMATCH], - f, - bstr_ptr(tx->request_line), - bstr_len(tx->request_line), - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRL, NULL); - if (r == 1) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } else { - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS -/** \test Test a simple uricontent option */ -static int UriTestSig01(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent option\"; " - "uricontent:\"one\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option */ -static int UriTestSig02(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /on HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option\"; " - "pcre:/one/U; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted with payload2, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option */ -static int UriTestSig03(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option\"; " - "pcre:/blah/U; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the urilen option */ -static int UriTestSig04(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test urilen option\"; " - "urilen:>20; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the urilen option */ -static int UriTestSig05(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test urilen option\"; " - "urilen:>4; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option */ -static int UriTestSig06(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option\"; " - "pcre:/(oneself)+/U; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert on payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option in combination with urilen */ -static int UriTestSig07(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option with urilen \"; " - "pcre:/(one){2,}(self)?/U; urilen:3<>20; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option in combination with urilen */ -static int UriTestSig08(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option with urilen\"; " - "pcre:/(blabla){2,}(self)?/U; urilen:3<>20; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option in combination with urilen */ -static int UriTestSig09(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option with urilen \"; " - "pcre:/(one){2,}(self)?/U; urilen:<2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the uricontent option in combination with urilen */ -static int UriTestSig10(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent with urilen option\"; " - "uricontent:\"one\"; urilen:<2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test content, uricontent, urilen, pcre /U options */ -static int UriTestSig11(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test content, uricontent, pcre /U and urilen options\"; " - "content:\"one\"; uricontent:\"one\"; pcre:/(one){2,}(self)?/U;" - "urilen:<2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test uricontent, urilen, pcre /U options */ -static int UriTestSig12(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U, uricontent and urilen option\"; " - "uricontent:\"one\"; " - "pcre:/(one)+self/U; urilen:>2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test uricontent, urilen */ -static int UriTestSig13(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test urilen option\"; " - "urilen:>2; uricontent:\"one\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test uricontent, pcre /U */ -static int UriTestSig14(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent option\"; " - "uricontent:\"one\"; pcre:/one(self)?/U;sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test pcre /U with anchored regex (bug 155) */ -static int UriTestSig15(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent option\"; " - "uricontent:\"one\"; pcre:/^\\/one(self)?$/U;sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test pcre /U with anchored regex (bug 155) */ -static int UriTestSig16(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0/\r\n" - "Host: 1.2.3.4\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any any (msg:\"ET TROJAN Downadup/Conficker A or B Worm reporting\"; flow:to_server,established; uricontent:\"/search?q=\"; pcre:\"/^\\/search\\?q=[0-9]{1,3}(&aq=7(\\?[0-9a-f]{8})?)?/U\"; pcre:\"/\\x0d\\x0aHost\\: \\d+\\.\\d+\\.\\d+\\.\\d+\\x0d\\x0a/\"; sid:2009024; rev:9;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 2009024)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - p->alerts.cnt = 0; - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - p->payload = http_buf2; - p->payload_len = http_buf2_len; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 2009024)) { - printf("sig 1 alerted, but it should not (host should not match): "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents - */ -static int UriTestSig17(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_big_big_string_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"this\"; uricontent:\"is\"; within:6; " - "uricontent:\"big\"; within:8; " - "uricontent:\"string\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents - */ -static int UriTestSig18(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_is_big_big_big_string_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"this\"; uricontent:\"is\"; within:9; " - "uricontent:\"big\"; within:12; " - "uricontent:\"string\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents - */ -static int UriTestSig19(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_this_now_is_is_____big_string_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"now\"; uricontent:\"this\"; " - "uricontent:\"is\"; within:12; " - "uricontent:\"big\"; within:8; " - "uricontent:\"string\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with offset - */ -static int UriTestSig20(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /_________thus_thus_is_a_big HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"thus\"; offset:8; " - "uricontent:\"is\"; within:6; " - "uricontent:\"big\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig21(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"fix\"; uricontent:\"this\"; within:6; " - "uricontent:!\"and\"; distance:0; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test relative pcre. - */ -static int UriTestSig22(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_is_a_super_duper_" - "nova_in_super_nova_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "pcre:/super/U; uricontent:\"nova\"; within:7; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig23(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:!\"fix_this_now\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig24(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"we_need_to\"; uricontent:!\"fix_this_now\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test normalized uricontents. - */ -static int UriTestSig25(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "pcre:/normalized/U; uricontent:\"normalized uri\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig26(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"fix_this\"; isdataat:4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig27(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"fix_this\"; isdataat:!10,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -static int UriTestSig28(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"ring\"; distance:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig29(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"ring\"; distance:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig30(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"_b5ig\"; offset:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig31(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"his\"; depth:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig32(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"g_st\"; within:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig33(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:15; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig34(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:15, norm; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig35(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:16; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig36(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:16, norm; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig37(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:17, raw; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig38(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:18, raw; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -#endif /* UNITTESTS */ - -void HttpRequestLineRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("UriTestSig01", UriTestSig01, 1); - UtRegisterTest("UriTestSig02", UriTestSig02, 1); - UtRegisterTest("UriTestSig03", UriTestSig03, 1); - UtRegisterTest("UriTestSig04", UriTestSig04, 1); - UtRegisterTest("UriTestSig05", UriTestSig05, 1); - UtRegisterTest("UriTestSig06", UriTestSig06, 1); - UtRegisterTest("UriTestSig07", UriTestSig07, 1); - UtRegisterTest("UriTestSig08", UriTestSig08, 1); - UtRegisterTest("UriTestSig09", UriTestSig09, 1); - UtRegisterTest("UriTestSig10", UriTestSig10, 1); - UtRegisterTest("UriTestSig11", UriTestSig11, 1); - UtRegisterTest("UriTestSig12", UriTestSig12, 1); - UtRegisterTest("UriTestSig13", UriTestSig13, 1); - UtRegisterTest("UriTestSig14", UriTestSig14, 1); - UtRegisterTest("UriTestSig15", UriTestSig15, 1); - UtRegisterTest("UriTestSig16", UriTestSig16, 1); - UtRegisterTest("UriTestSig17", UriTestSig17, 1); - UtRegisterTest("UriTestSig18", UriTestSig18, 1); - UtRegisterTest("UriTestSig19", UriTestSig19, 1); - UtRegisterTest("UriTestSig20", UriTestSig20, 1); - UtRegisterTest("UriTestSig21", UriTestSig21, 1); - UtRegisterTest("UriTestSig22", UriTestSig22, 1); - UtRegisterTest("UriTestSig23", UriTestSig23, 1); - UtRegisterTest("UriTestSig24", UriTestSig24, 1); - UtRegisterTest("UriTestSig25", UriTestSig25, 1); - UtRegisterTest("UriTestSig26", UriTestSig26, 1); - UtRegisterTest("UriTestSig27", UriTestSig27, 1); - - UtRegisterTest("UriTestSig28", UriTestSig28, 1); - UtRegisterTest("UriTestSig29", UriTestSig29, 1); - UtRegisterTest("UriTestSig30", UriTestSig30, 1); - UtRegisterTest("UriTestSig31", UriTestSig31, 1); - UtRegisterTest("UriTestSig32", UriTestSig32, 1); - UtRegisterTest("UriTestSig33", UriTestSig33, 1); - UtRegisterTest("UriTestSig34", UriTestSig34, 1); - UtRegisterTest("UriTestSig35", UriTestSig35, 1); - UtRegisterTest("UriTestSig36", UriTestSig36, 1); - UtRegisterTest("UriTestSig37", UriTestSig37, 1); - UtRegisterTest("UriTestSig38", UriTestSig38, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-engine-hrl.h b/framework/src/suricata/src/detect-engine-hrl.h deleted file mode 100644 index cb5360d9..00000000 --- a/framework/src/suricata/src/detect-engine-hrl.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_HRL_H__ -#define __DETECT_ENGINE_HRL_H__ - -int DetectEngineInspectHttpRequestLine(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -void HttpRequestLineRegisterTests(void); - -#endif /* __DETECT_ENGINE_HRL_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hrud.c b/framework/src/suricata/src/detect-engine-hrud.c deleted file mode 100644 index c715c029..00000000 --- a/framework/src/suricata/src/detect-engine-hrud.c +++ /dev/null @@ -1,3726 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * - * \brief Handle HTTP raw uri match - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-hrud.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - - -/** - * \brief Run the mpm against raw http uris. - * - * \retval cnt Number of matches reported by the mpm algo. - */ -int DetectEngineRunHttpRawUriMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - SCEnter(); - - htp_tx_t *tx = (htp_tx_t *)txv; - uint32_t cnt = 0; - if (tx->request_uri == NULL) - goto end; - cnt = HttpRawUriPatternSearch(det_ctx, - (uint8_t *)bstr_ptr(tx->request_uri), - bstr_len(tx->request_uri), flags); - -end: - SCReturnInt(cnt); -} - -/** - * \brief Do the http_raw_uri content inspection for a signature. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectHttpRawUri(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->request_uri == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_LINE) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } - - det_ctx->discontinue_matching = 0; - det_ctx->buffer_offset = 0; - det_ctx->inspection_recursion_counter = 0; - /* Inspect all the uricontents fetched on each - * transaction at the app layer */ - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HRUDMATCH], - f, - (uint8_t *)bstr_ptr(tx->request_uri), - bstr_len(tx->request_uri), - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRUD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -static int DetectEngineHttpRawUriTest01(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a/b/../c"; - uint8_t http2_buf[] = - "/./d.html HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"../c/./d\"; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest02(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 19\r\n" - "\r\n" - "This is dummy body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"/c/./d\"; http_raw_uri; offset:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest03(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a/b/../"; - uint8_t http2_buf[] = - "c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"/a/b\"; http_raw_uri; offset:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest04(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a/b/../"; - uint8_t http2_buf[] = - "c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:!\"/a/b\"; http_raw_uri; offset:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest05(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a/b/"; - uint8_t http2_buf[] = - "../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"a/b\"; http_raw_uri; depth:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest06(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a/b/"; - uint8_t http2_buf[] = - "../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:!\"/a/b\"; http_raw_uri; depth:25; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a/b/"; - uint8_t http2_buf[] = - "../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:!\"/c/./d\"; http_raw_uri; depth:12; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a/"; - uint8_t http2_buf[] = - "b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:!\"/c/./d\"; http_raw_uri; depth:18; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"/a\"; http_raw_uri; " - "content:\"./c/.\"; http_raw_uri; within:9; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"/a\"; http_raw_uri; " - "content:!\"boom\"; http_raw_uri; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest11(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"./a\"; http_raw_uri; " - "content:\"boom\"; http_raw_uri; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest12(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"./a\"; http_raw_uri; " - "content:!\"/b/..\"; http_raw_uri; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest13(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"./a\"; http_raw_uri; " - "content:\"/c/.\"; http_raw_uri; distance:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest14(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"./a\"; http_raw_uri; " - "content:!\"b/..\"; http_raw_uri; distance:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest15(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"./a\"; http_raw_uri; " - "content:\"/c/\"; http_raw_uri; distance:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest16(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"./a\"; http_raw_uri; " - "content:!\"/c/\"; http_raw_uri; distance:4; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest17(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http1_buf[] = "This_is_dummy_body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"body1\"; http_raw_uri; " - "content:\"bambu\"; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p1); - uint32_t r = HttpRawUriPatternSearch(det_ctx, http1_buf, http1_len, STREAM_TOSERVER); - if (r != 1) { - printf("expected 1 result, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -static int DetectEngineHttpRawUriTest18(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http1_buf[] = "This_is_dummy_body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"body1\"; http_raw_uri; " - "content:\"bambu\"; http_raw_uri; fast_pattern; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p1); - uint32_t r = HttpRawUriPatternSearch(det_ctx, http1_buf, http1_len, STREAM_TOSERVER); - if (r != 0) { - printf("expected 0 result, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -static int DetectEngineHttpRawUriTest19(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http1_buf[] = "This_is_dummy_body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"bambu\"; http_raw_uri; " - "content:\"is\"; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p1); - uint32_t r = HttpRawUriPatternSearch(det_ctx, http1_buf, http1_len, STREAM_TOSERVER); - if (r != 0) { - printf("expected 0 result, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -static int DetectEngineHttpRawUriTest20(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http1_buf[] = "This_is_dummy_body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "content:\"bambu\"; http_raw_uri; " - "content:\"is\"; http_raw_uri; fast_pattern; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p1); - uint32_t r = HttpRawUriPatternSearch(det_ctx, http1_buf, http1_len, STREAM_TOSERVER); - if (r != 2) { - printf("expected 2 result, got %"PRIu32": ", r); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -static int DetectEngineHttpRawUriTest21(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "pcre:/\\.\\/a/I; " - "content:!\"/c/\"; http_raw_uri; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest22(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "pcre:/\\.\\/a/I; " - "content:!\"/c/\"; within:5; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest23(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "pcre:/\\.\\/a/I; " - "content:!\"/c/\"; distance:3; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest24(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "pcre:/\\.\\/a/I; " - "content:!\"/c/\"; distance:10; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest25(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "pcre:/\\.\\/a/I; " - "content:\"/c/\"; within:10; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest26(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "pcre:/\\.\\/a/I; " - "content:\"/c/\"; within:5; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest27(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "pcre:/\\.\\/a/I; " - "content:\"/c/\"; distance:5; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpRawUriTest28(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /../a"; - uint8_t http2_buf[] = - "/b/../c/./d.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1" - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http raw uri test\"; " - "pcre:/\\.\\/a/I; " - "content:\"/c/\"; distance:10; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int DetectEngineHttpRawUriTest29(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /../a/b/../c/./d.html HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative raw uri contents\"; " - "content:\"/c/\"; http_raw_uri; " - "isdataat:4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int DetectEngineHttpRawUriTest30(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /../a/b/../c/./d.html HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative raw uri contents\"; " - "uricontent:\"/c/\"; isdataat:!10,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpRawUriRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpRawUriTest01", - DetectEngineHttpRawUriTest01, 1); - UtRegisterTest("DetectEngineHttpRawUriTest02", - DetectEngineHttpRawUriTest02, 1); - UtRegisterTest("DetectEngineHttpRawUriTest03", - DetectEngineHttpRawUriTest03, 1); - UtRegisterTest("DetectEngineHttpRawUriTest04", - DetectEngineHttpRawUriTest04, 1); - UtRegisterTest("DetectEngineHttpRawUriTest05", - DetectEngineHttpRawUriTest05, 1); - UtRegisterTest("DetectEngineHttpRawUriTest06", - DetectEngineHttpRawUriTest06, 1); - UtRegisterTest("DetectEngineHttpRawUriTest07", - DetectEngineHttpRawUriTest07, 1); - UtRegisterTest("DetectEngineHttpRawUriTest08", - DetectEngineHttpRawUriTest08, 1); - UtRegisterTest("DetectEngineHttpRawUriTest09", - DetectEngineHttpRawUriTest09, 1); - UtRegisterTest("DetectEngineHttpRawUriTest10", - DetectEngineHttpRawUriTest10, 1); - UtRegisterTest("DetectEngineHttpRawUriTest11", - DetectEngineHttpRawUriTest11, 1); - UtRegisterTest("DetectEngineHttpRawUriTest12", - DetectEngineHttpRawUriTest12, 1); - UtRegisterTest("DetectEngineHttpRawUriTest13", - DetectEngineHttpRawUriTest13, 1); - UtRegisterTest("DetectEngineHttpRawUriTest14", - DetectEngineHttpRawUriTest14, 1); - UtRegisterTest("DetectEngineHttpRawUriTest15", - DetectEngineHttpRawUriTest15, 1); - UtRegisterTest("DetectEngineHttpRawUriTest16", - DetectEngineHttpRawUriTest16, 1); - UtRegisterTest("DetectEngineHttpRawUriTest17", - DetectEngineHttpRawUriTest17, 1); - UtRegisterTest("DetectEngineHttpRawUriTest18", - DetectEngineHttpRawUriTest18, 1); - UtRegisterTest("DetectEngineHttpRawUriTest19", - DetectEngineHttpRawUriTest19, 1); - UtRegisterTest("DetectEngineHttpRawUriTest20", - DetectEngineHttpRawUriTest20, 1); - UtRegisterTest("DetectEngineHttpRawUriTest21", - DetectEngineHttpRawUriTest21, 1); - UtRegisterTest("DetectEngineHttpRawUriTest22", - DetectEngineHttpRawUriTest22, 1); - UtRegisterTest("DetectEngineHttpRawUriTest23", - DetectEngineHttpRawUriTest23, 1); - UtRegisterTest("DetectEngineHttpRawUriTest24", - DetectEngineHttpRawUriTest24, 1); - UtRegisterTest("DetectEngineHttpRawUriTest25", - DetectEngineHttpRawUriTest25, 1); - UtRegisterTest("DetectEngineHttpRawUriTest26", - DetectEngineHttpRawUriTest26, 1); - UtRegisterTest("DetectEngineHttpRawUriTest27", - DetectEngineHttpRawUriTest27, 1); - UtRegisterTest("DetectEngineHttpRawUriTest28", - DetectEngineHttpRawUriTest28, 1); - UtRegisterTest("DetectEngineHttpRawUriTest29", - DetectEngineHttpRawUriTest29, 1); - UtRegisterTest("DetectEngineHttpRawUriTest30", - DetectEngineHttpRawUriTest30, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hrud.h b/framework/src/suricata/src/detect-engine-hrud.h deleted file mode 100644 index 85ad88e1..00000000 --- a/framework/src/suricata/src/detect-engine-hrud.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HRUD_H__ -#define __DETECT_ENGINE_HRUD_H__ - -#include "app-layer-htp.h" - -int DetectEngineRunHttpRawUriMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -int DetectEngineInspectHttpRawUri(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -void DetectEngineHttpRawUriRegisterTests(void); - -#endif /* __DETECT_ENGINE_HRUD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hsbd.c b/framework/src/suricata/src/detect-engine-hsbd.c deleted file mode 100644 index 7d52c7d8..00000000 --- a/framework/src/suricata/src/detect-engine-hsbd.c +++ /dev/null @@ -1,4515 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * \author Victor Julien - * - * \brief Handle HTTP response body match corresponding to http_server_body - * keyword. - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-htp-mem.h" -#include "app-layer-protos.h" - -#include "conf.h" -#include "conf-yaml-loader.h" - -#define BUFFER_STEP 50 - -static inline int HSBDCreateSpace(DetectEngineThreadCtx *det_ctx, uint64_t size) -{ - if (size >= (USHRT_MAX - BUFFER_STEP)) - return -1; - - void *ptmp; - if (size > det_ctx->hsbd_buffers_size) { - ptmp = SCRealloc(det_ctx->hsbd, - (det_ctx->hsbd_buffers_size + BUFFER_STEP) * sizeof(HttpReassembledBody)); - if (ptmp == NULL) { - SCFree(det_ctx->hsbd); - det_ctx->hsbd = NULL; - det_ctx->hsbd_buffers_size = 0; - det_ctx->hsbd_buffers_list_len = 0; - return -1; - } - det_ctx->hsbd = ptmp; - - memset(det_ctx->hsbd + det_ctx->hsbd_buffers_size, 0, BUFFER_STEP * sizeof(HttpReassembledBody)); - det_ctx->hsbd_buffers_size += BUFFER_STEP; - } - uint16_t i; - for (i = det_ctx->hsbd_buffers_list_len; i < ((uint16_t)size); i++) { - det_ctx->hsbd[i].buffer_len = 0; - det_ctx->hsbd[i].offset = 0; - } - - return 0; -} - -static void HSBDGetBufferForTXInIDSMode(DetectEngineThreadCtx *det_ctx, - HtpState *htp_state, HtpBodyChunk *cur, - HtpTxUserData *htud, int index) -{ - int first = 1; - while (cur != NULL) { - /* see if we can filter out chunks */ - if (htud->response_body.body_inspected > 0) { - if (cur->stream_offset < htud->response_body.body_inspected) { - if ((htud->response_body.body_inspected - cur->stream_offset) > htp_state->cfg->response_inspect_window) { - cur = cur->next; - continue; - } else { - /* include this one */ - } - } else { - /* include this one */ - } - } - - if (first) { - det_ctx->hsbd[index].offset = cur->stream_offset; - first = 0; - } - - /* see if we need to grow the buffer */ - if (det_ctx->hsbd[index].buffer == NULL || (det_ctx->hsbd[index].buffer_len + cur->len) > det_ctx->hsbd[index].buffer_size) { - void *ptmp; - uint32_t newsize = det_ctx->hsbd[index].buffer_size + (cur->len * 2); - - if ((ptmp = HTPRealloc(det_ctx->hsbd[index].buffer, det_ctx->hsbd[index].buffer_size, newsize)) == NULL) { - HTPFree(det_ctx->hsbd[index].buffer, det_ctx->hsbd[index].buffer_size); - det_ctx->hsbd[index].buffer = NULL; - det_ctx->hsbd[index].buffer_size = 0; - det_ctx->hsbd[index].buffer_len = 0; - return; - } - det_ctx->hsbd[index].buffer = ptmp; - det_ctx->hsbd[index].buffer_size = newsize; - } - memcpy(det_ctx->hsbd[index].buffer + det_ctx->hsbd[index].buffer_len, cur->data, cur->len); - det_ctx->hsbd[index].buffer_len += cur->len; - - cur = cur->next; - } - - /* update inspected tracker */ - htud->response_body.body_inspected = htud->response_body.last->stream_offset + htud->response_body.last->len; -} - -#define MAX_WINDOW 10*1024*1024 -static void HSBDGetBufferForTXInIPSMode(DetectEngineThreadCtx *det_ctx, - HtpState *htp_state, HtpBodyChunk *cur, - HtpTxUserData *htud, int index) -{ - uint32_t window_size = 0; - - /* how much from before body_inspected will we consider? */ - uint32_t cfg_win = - htud->response_body.body_inspected >= htp_state->cfg->response_inspect_min_size ? - htp_state->cfg->response_inspect_window : - htp_state->cfg->response_inspect_min_size; - - /* but less if we don't have that much before body_inspected */ - if ((htud->response_body.body_inspected - htud->response_body.first->stream_offset) < cfg_win) { - cfg_win = htud->response_body.body_inspected - htud->response_body.first->stream_offset; - } - window_size = (htud->response_body.content_len_so_far - htud->response_body.body_inspected) + cfg_win; - if (window_size > MAX_WINDOW) { - SCLogDebug("weird: body size is %uk", window_size/1024); - window_size = MAX_WINDOW; - } - - if (det_ctx->hsbd[index].buffer == NULL || window_size > det_ctx->hsbd[index].buffer_size) { - void *ptmp; - - if ((ptmp = HTPRealloc(det_ctx->hsbd[index].buffer, det_ctx->hsbd[index].buffer_size, window_size)) == NULL) { - HTPFree(det_ctx->hsbd[index].buffer, det_ctx->hsbd[index].buffer_size); - det_ctx->hsbd[index].buffer = NULL; - det_ctx->hsbd[index].buffer_size = 0; - det_ctx->hsbd[index].buffer_len = 0; - return; - } - det_ctx->hsbd[index].buffer = ptmp; - det_ctx->hsbd[index].buffer_size = window_size; - } - - uint32_t left_edge = htud->response_body.body_inspected - cfg_win; - - int first = 1; - while (cur != NULL) { - if (first) { - det_ctx->hsbd[index].offset = cur->stream_offset; - first = 0; - } - - /* entirely before our window */ - if ((cur->stream_offset + cur->len) <= left_edge) { - cur = cur->next; - continue; - } else { - uint32_t offset = 0; - if (cur->stream_offset < left_edge && (cur->stream_offset + cur->len) > left_edge) { - offset = left_edge - cur->stream_offset; - BUG_ON(offset > cur->len); - } - - /* unusual: if window isn't big enough, we just give up */ - if (det_ctx->hsbd[index].buffer_len + (cur->len - offset) > window_size) { - htud->response_body.body_inspected = cur->stream_offset; - SCReturn; - } - - BUG_ON(det_ctx->hsbd[index].buffer_len + (cur->len - offset) > window_size); - - memcpy(det_ctx->hsbd[index].buffer + det_ctx->hsbd[index].buffer_len, cur->data + offset, cur->len - offset); - det_ctx->hsbd[index].buffer_len += (cur->len - offset); - det_ctx->hsbd[index].offset -= offset; - } - - cur = cur->next; - } - - /* update inspected tracker to point before the current window */ - htud->response_body.body_inspected = htud->response_body.content_len_so_far; -} - -static uint8_t *DetectEngineHSBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Flow *f, HtpState *htp_state, - uint8_t flags, - uint32_t *buffer_len, - uint32_t *stream_start_offset) -{ - int index = 0; - uint8_t *buffer = NULL; - *buffer_len = 0; - *stream_start_offset = 0; - - if (det_ctx->hsbd_buffers_list_len == 0) { - /* get the inspect id to use as a 'base id' */ - uint64_t base_inspect_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - BUG_ON(base_inspect_id > tx_id); - /* see how many space we need for the current tx_id */ - uint64_t txs = (tx_id - base_inspect_id) + 1; - if (HSBDCreateSpace(det_ctx, txs) < 0) - goto end; - index = (tx_id - base_inspect_id); - det_ctx->hsbd_start_tx_id = base_inspect_id; - det_ctx->hsbd_buffers_list_len = txs; - } else { - if ((tx_id - det_ctx->hsbd_start_tx_id) < det_ctx->hsbd_buffers_list_len) { - if (det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer_len != 0) { - *buffer_len = det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer_len; - *stream_start_offset = det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].offset; - return det_ctx->hsbd[(tx_id - det_ctx->hsbd_start_tx_id)].buffer; - } - } else { - uint64_t txs = (tx_id - det_ctx->hsbd_start_tx_id) + 1; - if (HSBDCreateSpace(det_ctx, txs) < 0) - goto end; - - det_ctx->hsbd_buffers_list_len = txs; - } - index = (tx_id - det_ctx->hsbd_start_tx_id); - } - - HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud == NULL) { - SCLogDebug("no htud"); - goto end; - } - - /* no new data */ - if (htud->response_body.body_inspected == htud->response_body.content_len_so_far) { - SCLogDebug("no new data"); - goto end; - } - - HtpBodyChunk *cur = htud->response_body.first; - if (cur == NULL) { - SCLogDebug("No http chunks to inspect for this transacation"); - goto end; - } - - SCLogDebug("response_body_limit %u response_body.content_len_so_far %"PRIu64 - ", response_inspect_min_size %"PRIu32", EOF %s, progress > body? %s", - htp_state->cfg->response_body_limit, - htud->response_body.content_len_so_far, - htp_state->cfg->response_inspect_min_size, - flags & STREAM_EOF ? "true" : "false", - (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_BODY) ? "true" : "false"); - - if (!htp_state->cfg->http_body_inline) { - /* inspect the body if the transfer is complete or we have hit - * our body size limit */ - if ((htp_state->cfg->response_body_limit == 0 || - htud->response_body.content_len_so_far < htp_state->cfg->response_body_limit) && - htud->response_body.content_len_so_far < htp_state->cfg->response_inspect_min_size && - !(AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_BODY) && - !(flags & STREAM_EOF)) { - SCLogDebug("we still haven't seen the entire response body. " - "Let's defer body inspection till we see the " - "entire body."); - goto end; - } - HSBDGetBufferForTXInIDSMode(det_ctx, htp_state, cur, htud, index); - } else { - HSBDGetBufferForTXInIPSMode(det_ctx, htp_state, cur, htud, index); - } - - buffer = det_ctx->hsbd[index].buffer; - *buffer_len = det_ctx->hsbd[index].buffer_len; - *stream_start_offset = det_ctx->hsbd[index].offset; - end: - return buffer; -} - -int DetectEngineRunHttpServerBodyMpm(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx) -{ - uint32_t cnt = 0; - uint32_t buffer_len = 0; - uint32_t stream_start_offset = 0; - uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx, idx, - de_ctx, det_ctx, - f, htp_state, - flags, - &buffer_len, - &stream_start_offset); - if (buffer_len == 0) - goto end; - - cnt = HttpServerBodyPatternSearch(det_ctx, buffer, buffer_len, flags); - - end: - return cnt; -} - -int DetectEngineInspectHttpServerBody(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id) -{ - HtpState *htp_state = (HtpState *)alstate; - uint32_t buffer_len = 0; - uint32_t stream_start_offset = 0; - uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx, tx_id, - de_ctx, det_ctx, - f, htp_state, - flags, - &buffer_len, - &stream_start_offset); - if (buffer_len == 0) - goto end; - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_FILEDATA], - f, - buffer, - buffer_len, - stream_start_offset, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSBD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_BODY) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -void DetectEngineCleanHSBDBuffers(DetectEngineThreadCtx *det_ctx) -{ - if (det_ctx->hsbd_buffers_list_len > 0) { - for (int i = 0; i < det_ctx->hsbd_buffers_list_len; i++) { - det_ctx->hsbd[i].buffer_len = 0; - det_ctx->hsbd[i].offset = 0; - } - } - det_ctx->hsbd_buffers_list_len = 0; - det_ctx->hsbd_start_tx_id = 0; - - return; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -struct TestSteps { - const uint8_t *input; - size_t input_size; /**< if 0 strlen will be used */ - int direction; /**< STREAM_TOSERVER, STREAM_TOCLIENT */ - int expect; -}; - -static int RunTest(struct TestSteps *steps, const char *sig, const char *yaml) -{ - TcpSession ssn; - Flow f; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - int i = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - if (yaml) { - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - - ConfYamlLoadString(yaml, strlen(yaml)); - HTPConfigure(); - EngineModeSetIPS(); - } - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - SCLogDebug("sig %s", sig); - DetectEngineAppendSig(de_ctx, (char *)sig); - - de_ctx->flags |= DE_QUIET; - - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - struct TestSteps *b = steps; - i = 0; - while (b->input != NULL) { - SCLogDebug("chunk %p %d", b, i); - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - if (p == NULL) - goto end; - p->flow = &f; - p->flowflags = (b->direction == STREAM_TOSERVER) ? FLOW_PKT_TOSERVER : FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, b->direction, - (uint8_t *)b->input, - b->input_size ? b->input_size : strlen((const char *)b->input)); - if (r != 0) { - printf("toserver chunk %d returned %" PRId32 ", expected 0: ", i+1, r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - int match = PacketAlertCheck(p, 1); - if (b->expect != match) { - printf("rule matching mismatch: "); - goto end; - } - - UTHFreePackets(&p, 1); - p = NULL; - b++; - i++; - } - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - - if (yaml) { - HtpConfigRestoreBackup(); - ConfRestoreContextBackup(); - EngineModeSetIDS(); - } - return result; -} - -static int DetectEngineHttpServerBodyTest01(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 7\r\n" - "\r\n" - "message"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"message\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest02(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 7\r\n" - "\r\n" - "xxxxABC"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"ABC\"; http_server_body; offset:4; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest03(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - int result = 0; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 17\r\n" - "\r\n" - "1234567"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "8901234ABC"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"ABC\"; http_server_body; offset:14; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest04(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:!\"abc\"; http_server_body; offset:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest05(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"abc\"; http_server_body; depth:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest06(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:!\"def\"; http_server_body; depth:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:!\"def\"; http_server_body; offset:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:!\"abc\"; http_server_body; depth:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"abc\"; http_server_body; depth:3; " - "content:\"def\"; http_server_body; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"abc\"; http_server_body; depth:3; " - "content:!\"xyz\"; http_server_body; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest11(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"abc\"; http_server_body; depth:3; " - "content:\"xyz\"; http_server_body; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 did match but should not have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest12(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"ab\"; http_server_body; depth:2; " - "content:\"ef\"; http_server_body; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest13(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"ab\"; http_server_body; depth:3; " - "content:!\"yz\"; http_server_body; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest14(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "pcre:/ab/Q; " - "content:\"ef\"; http_server_body; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest15(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "pcre:/abc/Q; " - "content:!\"xyz\"; http_server_body; distance:0; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest16(void) -{ - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - request-body-limit: 0\n\ - response-body-limit: 0\n\ -\n\ - request-body-inspect-window: 0\n\ - response-body-inspect-window: 0\n\ - request-body-minimal-inspect-size: 0\n\ - response-body-minimal-inspect-size: 0\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - int result = 0; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 17\r\n" - "\r\n" - "1234567"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "8901234ABC"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"890\"; within:3; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - HtpConfigRestoreBackup(); - ConfRestoreContextBackup(); - - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyTest17(void) -{ - char input[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ - personality: IDS\n\ - request-body-limit: 0\n\ - response-body-limit: 0\n\ -\n\ - request-body-inspect-window: 0\n\ - response-body-inspect-window: 0\n\ - request-body-minimal-inspect-size: 0\n\ - response-body-minimal-inspect-size: 0\n\ -"; - - ConfCreateContextBackup(); - ConfInit(); - HtpConfigCreateBackup(); - - ConfYamlLoadString(input, strlen(input)); - HTPConfigure(); - - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - int result = 0; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 17\r\n" - "\r\n" - "1234567"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "8901234ABC"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"890\"; depth:3; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - HTPFreeConfig(); - HtpConfigRestoreBackup(); - ConfRestoreContextBackup(); - - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/* - * gzip stream - */ -static int DetectEngineHttpServerBodyTest18(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = { - 'H', 'T', 'T', 'P', '/', '1', '.', '1', ' ', '2', '0', '0', 'o', 'k', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'L', 'e', 'n', 'g', 't', 'h', ':', ' ', '5', '1', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', ':', ' ', 'g', 'z', 'i', 'p', 0x0d, 0x0a, - 0x0d, 0x0a, - 0x1f, 0x8b, 0x08, 0x08, 0x27, 0x1e, 0xe5, 0x51, - 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, - 0x78, 0x74, 0x00, 0x2b, 0xc9, 0xc8, 0x2c, 0x56, - 0x00, 0xa2, 0x44, 0x85, 0xb4, 0xcc, 0x9c, 0x54, - 0x85, 0xcc, 0x3c, 0x20, 0x2b, 0x29, 0xbf, 0x42, - 0x8f, 0x0b, 0x00, 0xb2, 0x7d, 0xac, 0x9b, 0x19, - 0x00, 0x00, 0x00, - }; - uint32_t http_len2 = sizeof(http_buf2); - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"file\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/* - * deflate stream - */ -static int DetectEngineHttpServerBodyTest19(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = { - 'H', 'T', 'T', 'P', '/', '1', '.', '1', ' ', '2', '0', '0', 'o', 'k', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'L', 'e', 'n', 'g', 't', 'h', ':', ' ', '2', '4', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', ':', ' ', 'd', 'e', 'f', 'l', 'a', 't', 'e', 0x0d, 0x0a, - 0x0d, 0x0a, - 0x2b, 0xc9, 0xc8, 0x2c, 0x56, - 0x00, 0xa2, 0x44, 0x85, 0xb4, 0xcc, 0x9c, 0x54, - 0x85, 0xcc, 0x3c, 0x20, 0x2b, 0x29, 0xbf, 0x42, - 0x8f, 0x0b, 0x00, - }; - // 0xb2, 0x7d, 0xac, 0x9b, 0x19, 0x00, 0x00, 0x00, - uint32_t http_len2 = sizeof(http_buf2); - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"file\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/* - * deflate stream with gzip set as content-encoding - */ -static int DetectEngineHttpServerBodyTest20(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = { - 'H', 'T', 'T', 'P', '/', '1', '.', '1', ' ', '2', '0', '0', 'o', 'k', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'L', 'e', 'n', 'g', 't', 'h', ':', ' ', '2', '4', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', ':', ' ', 'g', 'z', 'i', 'p', 0x0d, 0x0a, - 0x0d, 0x0a, - 0x2b, 0xc9, 0xc8, 0x2c, 0x56, - 0x00, 0xa2, 0x44, 0x85, 0xb4, 0xcc, 0x9c, 0x54, - 0x85, 0xcc, 0x3c, 0x20, 0x2b, 0x29, 0xbf, 0x42, - 0x8f, 0x0b, 0x00, - }; - // 0xb2, 0x7d, 0xac, 0x9b, 0x19, 0x00, 0x00, 0x00, - uint32_t http_len2 = sizeof(http_buf2); - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"file\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/* - * gzip stream with deflate set as content-encoding. - */ -static int DetectEngineHttpServerBodyTest21(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = { - 'H', 'T', 'T', 'P', '/', '1', '.', '1', ' ', '2', '0', '0', 'o', 'k', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'L', 'e', 'n', 'g', 't', 'h', ':', ' ', '5', '1', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', ':', ' ', 'd', 'e', 'f', 'l', 'a', 't', 'e', 0x0d, 0x0a, - 0x0d, 0x0a, - 0x1f, 0x8b, 0x08, 0x08, 0x27, 0x1e, 0xe5, 0x51, - 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, - 0x78, 0x74, 0x00, 0x2b, 0xc9, 0xc8, 0x2c, 0x56, - 0x00, 0xa2, 0x44, 0x85, 0xb4, 0xcc, 0x9c, 0x54, - 0x85, 0xcc, 0x3c, 0x20, 0x2b, 0x29, 0xbf, 0x42, - 0x8f, 0x0b, 0x00, 0xb2, 0x7d, 0xac, 0x9b, 0x19, - 0x00, 0x00, 0x00, - }; - uint32_t http_len2 = sizeof(http_buf2); - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"file\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/* - * gzip stream. - * We have 2 content-encoding headers. First gzip and second deflate. - */ -static int DetectEngineHttpServerBodyTest22(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = { - 'H', 'T', 'T', 'P', '/', '1', '.', '1', ' ', '2', '0', '0', 'o', 'k', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'L', 'e', 'n', 'g', 't', 'h', ':', ' ', '5', '1', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', ':', ' ', 'g', 'z', 'i', 'p', 0x0d, 0x0a, - 'C', 'o', 'n', 't', 'e', 'n', 't', '-', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', ':', ' ', 'd', 'e', 'f', 'l', 'a', 't', 'e', 0x0d, 0x0a, - 0x0d, 0x0a, - 0x1f, 0x8b, 0x08, 0x08, 0x27, 0x1e, 0xe5, 0x51, - 0x00, 0x03, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, - 0x78, 0x74, 0x00, 0x2b, 0xc9, 0xc8, 0x2c, 0x56, - 0x00, 0xa2, 0x44, 0x85, 0xb4, 0xcc, 0x9c, 0x54, - 0x85, 0xcc, 0x3c, 0x20, 0x2b, 0x29, 0xbf, 0x42, - 0x8f, 0x0b, 0x00, 0xb2, 0x7d, 0xac, 0x9b, 0x19, - 0x00, 0x00, 0x00, - }; - uint32_t http_len2 = sizeof(http_buf2); - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"file\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyFileDataTest01(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "file_data; pcre:/ab/; " - "content:\"ef\"; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyFileDataTest02(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "file_data; pcre:/abc/; " - "content:!\"xyz\"; distance:0; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/* \test recursive relative byte test */ -static int DetectEngineHttpServerBodyFileDataTest03(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 33\r\n" - "\r\n" - "XYZ_klm_1234abcd_XYZ_klm_5678abcd"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any " - "(msg:\"match on 1st\"; " - "file_data; content:\"XYZ\"; content:\"_klm_\"; distance:0; content:\"abcd\"; distance:4; byte_test:4,=,1234,-8,relative,string;" - "sid:1;)"))) - goto end; - if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any " - "(msg:\"match on 2nd\"; " - "file_data; content:\"XYZ\"; content:\"_klm_\"; distance:0; content:\"abcd\"; distance:4; byte_test:4,=,5678,-8,relative,string;" - "sid:2;)"))) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - if (!PacketAlertCheck(p2, 2)) { - printf("sid 2 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpServerBodyFileDataTest04(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "ab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"cd", - 0, STREAM_TOCLIENT, 1 }, - { (const uint8_t *)"ef", - 0, STREAM_TOCLIENT, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"abcd\"; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest05(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "ab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"cd", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"ef", - 0, STREAM_TOCLIENT, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"abcdef\"; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest06(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "ab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"cd", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"ef", - 0, STREAM_TOCLIENT, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"bcdef\"; offset:1; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest07(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 13\r\n" - "\r\n" - "ab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"cd", - 0, STREAM_TOCLIENT, 1 }, - { (const uint8_t *)"123456789", - 0, STREAM_TOCLIENT, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"bc\"; offset:1; depth:2; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest08(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n" - "ab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"cd", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"1234567890", - 0, STREAM_TOCLIENT, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"d123456789\"; offset:3; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest09(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 13\r\n" - "\r\n" - "ab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"cd", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"123456789", - 0, STREAM_TOCLIENT, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"abcd12\"; depth:6; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest10(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 5\r\n" - "\r\n" - "ab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"c", - 0, STREAM_TOCLIENT, 1 }, - { (const uint8_t *)"de", - 0, STREAM_TOCLIENT, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"abc\"; depth:3; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest11(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 5\r\n" - "\r\n" - "ab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"c", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"de", - 0, STREAM_TOCLIENT, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"bcde\"; offset:1; depth:4; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest12(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 13\r\n" - "\r\n" - "a", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"b", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"c", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"d", - 0, STREAM_TOCLIENT, 1 }, - { (const uint8_t *)"efghijklm", - 0, STREAM_TOCLIENT, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"abcd\"; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest13(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 13\r\n" - "\r\n" - "a", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"b", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"c", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"d", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"efghijklm", - 0, STREAM_TOCLIENT, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"abcdefghijklm\"; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest14(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 20\r\n" - "\r\n" - "1234567890", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"abcdefghi", - 0, STREAM_TOCLIENT, 1 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"890abcdefghi\"; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest15(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 20\r\n" - "\r\n" - "1234567890", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"abcdefghi", - 0, STREAM_TOCLIENT, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"7890ab\"; depth:6; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest16(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 20\r\n" - "\r\n" - "aaaab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"bbbbc", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"ccccd", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"dddde", - 0, STREAM_TOCLIENT, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"aabb\"; depth:4; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest17(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 20\r\n" - "\r\n" - "aaaab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"bbbbc", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"ccccd", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"dddde", - 0, STREAM_TOCLIENT, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"bbbc\"; depth:4; sid:1;)"; - return RunTest(steps, sig, yaml); -} - -static int DetectEngineHttpServerBodyFileDataTest18(void) -{ - - const char yaml[] = "\ -%YAML 1.1\n\ ----\n\ -libhtp:\n\ -\n\ - default-config:\n\ -\n\ - http-body-inline: yes\n\ - response-body-minimal-inspect-size: 6\n\ - response-body-inspect-window: 3\n\ -"; - - struct TestSteps steps[] = { - { (const uint8_t *)"GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n", - 0, STREAM_TOSERVER, 0 }, - { (const uint8_t *)"HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 20\r\n" - "\r\n" - "aaaab", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"bbbbc", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"ccccd", - 0, STREAM_TOCLIENT, 0 }, - { (const uint8_t *)"dddde", - 0, STREAM_TOCLIENT, 0 }, - { NULL, 0, 0, 0 }, - }; - - const char *sig = "alert http any any -> any any (file_data; content:\"bccd\"; depth:4; sid:1;)"; - return RunTest(steps, sig, yaml); -} -#endif /* UNITTESTS */ - -void DetectEngineHttpServerBodyRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpServerBodyTest01", - DetectEngineHttpServerBodyTest01, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest02", - DetectEngineHttpServerBodyTest02, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest03", - DetectEngineHttpServerBodyTest03, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest04", - DetectEngineHttpServerBodyTest04, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest05", - DetectEngineHttpServerBodyTest05, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest06", - DetectEngineHttpServerBodyTest06, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest07", - DetectEngineHttpServerBodyTest07, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest08", - DetectEngineHttpServerBodyTest08, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest09", - DetectEngineHttpServerBodyTest09, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest10", - DetectEngineHttpServerBodyTest10, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest11", - DetectEngineHttpServerBodyTest11, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest12", - DetectEngineHttpServerBodyTest12, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest13", - DetectEngineHttpServerBodyTest13, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest14", - DetectEngineHttpServerBodyTest14, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest15", - DetectEngineHttpServerBodyTest15, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest16", - DetectEngineHttpServerBodyTest16, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest17", - DetectEngineHttpServerBodyTest17, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest18", - DetectEngineHttpServerBodyTest18, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest19", - DetectEngineHttpServerBodyTest19, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest20", - DetectEngineHttpServerBodyTest20, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest21", - DetectEngineHttpServerBodyTest21, 1); - UtRegisterTest("DetectEngineHttpServerBodyTest22", - DetectEngineHttpServerBodyTest22, 1); - - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest01", - DetectEngineHttpServerBodyFileDataTest01, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest02", - DetectEngineHttpServerBodyFileDataTest02, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest03", - DetectEngineHttpServerBodyFileDataTest03, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest04", - DetectEngineHttpServerBodyFileDataTest04, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest05", - DetectEngineHttpServerBodyFileDataTest05, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest06", - DetectEngineHttpServerBodyFileDataTest06, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest07", - DetectEngineHttpServerBodyFileDataTest07, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest08", - DetectEngineHttpServerBodyFileDataTest08, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest09", - DetectEngineHttpServerBodyFileDataTest09, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest10", - DetectEngineHttpServerBodyFileDataTest10, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest11", - DetectEngineHttpServerBodyFileDataTest11, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest12", - DetectEngineHttpServerBodyFileDataTest12, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest13", - DetectEngineHttpServerBodyFileDataTest13, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest14", - DetectEngineHttpServerBodyFileDataTest14, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest15", - DetectEngineHttpServerBodyFileDataTest15, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest16", - DetectEngineHttpServerBodyFileDataTest16, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest17", - DetectEngineHttpServerBodyFileDataTest17, 1); - UtRegisterTest("DetectEngineHttpServerBodyFileDataTest18", - DetectEngineHttpServerBodyFileDataTest18, 1); - -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hsbd.h b/framework/src/suricata/src/detect-engine-hsbd.h deleted file mode 100644 index a4424824..00000000 --- a/framework/src/suricata/src/detect-engine-hsbd.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HSBD_H__ -#define __DETECT_ENGINE_HSBD_H__ - -#define ENGINE_HSBD_BUFFER_LIMIT 20000 - -#include "app-layer-htp.h" - -int DetectEngineRunHttpServerBodyMpm(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -int DetectEngineInspectHttpServerBody(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -void DetectEngineCleanHSBDBuffers(DetectEngineThreadCtx *det_ctx); - -void DetectEngineHttpServerBodyRegisterTests(void); - -#endif /* __DETECT_ENGINE_HSBD_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-hscd.c b/framework/src/suricata/src/detect-engine-hscd.c deleted file mode 100644 index a38562b1..00000000 --- a/framework/src/suricata/src/detect-engine-hscd.c +++ /dev/null @@ -1,2097 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-hscd.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -/** - * \brief Run the mpm against http stat code. - * - * \retval cnt Number of matches reported by the mpm algo. - */ -int DetectEngineRunHttpStatCodeMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - SCEnter(); - - uint32_t cnt = 0; - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->response_status == NULL) - goto end; - - cnt = HttpStatCodePatternSearch(det_ctx, - (uint8_t *)bstr_ptr(tx->response_status), - bstr_len(tx->response_status), flags); - -end: - SCReturnInt(cnt); -} - -/** - * \brief Do the http_stat_code content inspection for a signature. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectHttpStatCode(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->response_status == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_LINE) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } - - det_ctx->discontinue_matching = 0; - det_ctx->buffer_offset = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, - s->sm_lists[DETECT_SM_LIST_HSCDMATCH], - f, - (uint8_t *)bstr_ptr(tx->response_status), - bstr_len(tx->response_status), - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSCD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -static int DetectEngineHttpStatCodeTest01(void) - { - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 message\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 7\r\n" - "\r\n" - "message"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:\"200\"; http_stat_code; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest02(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 2000123 xxxxABC\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 7\r\n" - "\r\n" - "xxxxABC"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:\"123\"; http_stat_code; offset:4; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest03(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - int result = 0; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 123"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "456789\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 17\r\n" - "\r\n" - "12345678901234ABC"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:\"789\"; http_stat_code; offset:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest04(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:!\"200\"; http_stat_code; offset:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest05(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:\"200\"; http_stat_code; depth:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest06(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:!\"123\"; http_stat_code; depth:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:!\"123\"; http_stat_code; offset:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:!\"200\"; http_stat_code; depth:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:\"200\"; http_stat_code; depth:3; " - "content:\"123\"; http_stat_code; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:\"200\"; http_stat_code; depth:3; " - "content:!\"124\"; http_stat_code; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest11(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:\"200\"; http_stat_code; depth:3; " - "content:\"124\"; http_stat_code; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 did match but should not have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest12(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:\"20\"; http_stat_code; depth:2; " - "content:\"23\"; http_stat_code; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest13(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "content:\"20\"; http_stat_code; depth:3; " - "content:!\"25\"; http_stat_code; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest14(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "pcre:/20/S; " - "content:\"23\"; http_stat_code; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatCodeTest15(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200123 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat code test\"; " - "pcre:/200/S; " - "content:!\"124\"; http_stat_code; distance:0; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpStatCodeRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpStatCodeTest01", - DetectEngineHttpStatCodeTest01, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest02", - DetectEngineHttpStatCodeTest02, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest03", - DetectEngineHttpStatCodeTest03, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest04", - DetectEngineHttpStatCodeTest04, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest05", - DetectEngineHttpStatCodeTest05, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest06", - DetectEngineHttpStatCodeTest06, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest07", - DetectEngineHttpStatCodeTest07, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest08", - DetectEngineHttpStatCodeTest08, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest09", - DetectEngineHttpStatCodeTest09, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest10", - DetectEngineHttpStatCodeTest10, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest11", - DetectEngineHttpStatCodeTest11, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest12", - DetectEngineHttpStatCodeTest12, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest13", - DetectEngineHttpStatCodeTest13, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest14", - DetectEngineHttpStatCodeTest14, 1); - UtRegisterTest("DetectEngineHttpStatCodeTest15", - DetectEngineHttpStatCodeTest15, 1); -#endif /* UNITTESTS */ - - return; -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hscd.h b/framework/src/suricata/src/detect-engine-hscd.h deleted file mode 100644 index 2a97c2ff..00000000 --- a/framework/src/suricata/src/detect-engine-hscd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HSCD_H__ -#define __DETECT_ENGINE_HSCD_H__ - -#include "app-layer-htp.h" - -int DetectEngineRunHttpStatCodeMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -int DetectEngineInspectHttpStatCode(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -void DetectEngineHttpStatCodeRegisterTests(void); - -#endif /* __DETECT_ENGINE_HSCD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hsmd.c b/framework/src/suricata/src/detect-engine-hsmd.c deleted file mode 100644 index 61c8e2e9..00000000 --- a/framework/src/suricata/src/detect-engine-hsmd.c +++ /dev/null @@ -1,2097 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-hsmd.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -/** - * \brief Run the mpm against http stat msg. - * - * \retval cnt Number of matches reported by the mpm algo. - */ -int DetectEngineRunHttpStatMsgMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - SCEnter(); - - uint32_t cnt = 0; - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->response_message == NULL) - goto end; - - cnt = HttpStatMsgPatternSearch(det_ctx, - (uint8_t *)bstr_ptr(tx->response_message), - bstr_len(tx->response_message), flags); - -end: - SCReturnInt(cnt); -} - -/** - * \brief Do the http_stat_msg content inspection for a signature. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectHttpStatMsg(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->response_message == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_RESPONSE_LINE) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } - - det_ctx->discontinue_matching = 0; - det_ctx->buffer_offset = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, - s->sm_lists[DETECT_SM_LIST_HSMDMATCH], - f, - (uint8_t *)bstr_ptr(tx->response_message), - bstr_len(tx->response_message), - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSMD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -static int DetectEngineHttpStatMsgTest01(void) - { - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 message\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 7\r\n" - "\r\n" - "message"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:\"message\"; http_stat_msg; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest02(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 xxxxABC\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 7\r\n" - "\r\n" - "xxxxABC"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:\"ABC\"; http_stat_msg; offset:4; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest03(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - int result = 0; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 1234567"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "8901234ABC\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 17\r\n" - "\r\n" - "12345678901234ABC"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:\"ABC\"; http_stat_msg; offset:14; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest04(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:!\"abc\"; http_stat_msg; offset:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest05(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:\"abc\"; http_stat_msg; depth:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest06(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:!\"def\"; http_stat_msg; depth:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:!\"def\"; http_stat_msg; offset:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:!\"abc\"; http_stat_msg; depth:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:\"abc\"; http_stat_msg; depth:3; " - "content:\"def\"; http_stat_msg; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:\"abc\"; http_stat_msg; depth:3; " - "content:!\"xyz\"; http_stat_msg; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest11(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:\"abc\"; http_stat_msg; depth:3; " - "content:\"xyz\"; http_stat_msg; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 did match but should not have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest12(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:\"ab\"; http_stat_msg; depth:2; " - "content:\"ef\"; http_stat_msg; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest13(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "content:\"ab\"; http_stat_msg; depth:3; " - "content:!\"yz\"; http_stat_msg; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest14(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "pcre:/ab/Y; " - "content:\"ef\"; http_stat_msg; distance:2; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectEngineHttpStatMsgTest15(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 abcdef\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http stat msg test\"; " - "pcre:/abc/Y; " - "content:!\"xyz\"; http_stat_msg; distance:0; within:3; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 did not match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpStatMsgRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpStatMsgTest01", - DetectEngineHttpStatMsgTest01, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest02", - DetectEngineHttpStatMsgTest02, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest03", - DetectEngineHttpStatMsgTest03, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest04", - DetectEngineHttpStatMsgTest04, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest05", - DetectEngineHttpStatMsgTest05, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest06", - DetectEngineHttpStatMsgTest06, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest07", - DetectEngineHttpStatMsgTest07, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest08", - DetectEngineHttpStatMsgTest08, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest09", - DetectEngineHttpStatMsgTest09, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest10", - DetectEngineHttpStatMsgTest10, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest11", - DetectEngineHttpStatMsgTest11, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest12", - DetectEngineHttpStatMsgTest12, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest13", - DetectEngineHttpStatMsgTest13, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest14", - DetectEngineHttpStatMsgTest14, 1); - UtRegisterTest("DetectEngineHttpStatMsgTest15", - DetectEngineHttpStatMsgTest15, 1); -#endif /* UNITTESTS */ - - return; -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hsmd.h b/framework/src/suricata/src/detect-engine-hsmd.h deleted file mode 100644 index 01fc3612..00000000 --- a/framework/src/suricata/src/detect-engine-hsmd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HSMD_H__ -#define __DETECT_ENGINE_HSMD_H__ - -#include "app-layer-htp.h" - -int DetectEngineRunHttpStatMsgMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -int DetectEngineInspectHttpStatMsg(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -void DetectEngineHttpStatMsgRegisterTests(void); - -#endif /* __DETECT_ENGINE_HSMD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-hua.c b/framework/src/suricata/src/detect-engine-hua.c deleted file mode 100644 index 8cafa423..00000000 --- a/framework/src/suricata/src/detect-engine-hua.c +++ /dev/null @@ -1,1855 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** \file - * - * \author Anoop Saldanha - * - * \brief Handle HTTP user agent match - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -#include "detect-engine-hua.h" - -int DetectEngineRunHttpUAMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - uint32_t cnt = 0; - htp_tx_t *tx = (htp_tx_t *)txv; - if (tx->request_headers == NULL) - goto end; - - htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->request_headers, - "User-Agent"); - if (h == NULL) { - SCLogDebug("HTTP user agent header not present in this request"); - goto end; - } - cnt = HttpUAPatternSearch(det_ctx, - (uint8_t *)bstr_ptr(h->value), - bstr_len(h->value), flags); - - end: - return cnt; -} - -/** - * \brief Do the http_user_agent content inspection for a signature. - * - * \param de_ctx Detection engine context. - * \param det_ctx Detection engine thread context. - * \param s Signature to inspect. - * \param f Flow. - * \param flags App layer flags. - * \param state App layer state. - * - * \retval 0 No match. - * \retval 1 Match. - */ -int DetectEngineInspectHttpUA(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - htp_tx_t *tx = (htp_tx_t *)txv; - htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->request_headers, - "User-Agent"); - if (h == NULL) { - SCLogDebug("HTTP user agent header not present in this request"); - goto end; - } - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HUADMATCH], - f, - (uint8_t *)bstr_ptr(h->value), - bstr_len(h->value), - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_HUAD, NULL); - if (r == 1) - return DETECT_ENGINE_INSPECT_SIG_MATCH; - - end: - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_HEADERS) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest01(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"CONNECT\"; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest02(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"CO\"; depth:4; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest03(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_user_agent test\"; " - "content:!\"ECT\"; depth:4; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest04(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"ECT\"; depth:4; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest05(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:!\"CON\"; depth:4; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"ECT\"; offset:3; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest07(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:!\"CO\"; offset:3; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest08(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:!\"ECT\"; offset:3; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest09(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"CON\"; offset:3; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest10(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_user_agent test\"; " - "content:\"CO\"; http_user_agent; " - "content:\"EC\"; within:4; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"CO\"; http_user_agent; " - "content:!\"EC\"; within:3; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_user_agent test\"; " - "content:\"CO\"; http_user_agent; " - "content:\"EC\"; within:3; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"CO\"; http_user_agent; " - "content:!\"EC\"; within:4; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest14(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_user_agent test\"; " - "content:\"CO\"; http_user_agent; " - "content:\"EC\"; distance:2; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest15(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"CO\"; http_user_agent; " - "content:!\"EC\"; distance:3; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest16(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"CO\"; http_user_agent; " - "content:\"EC\"; distance:3; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpUATest17(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "CONNECT /index.html HTTP/1.0\r\n" - "User-Agent: CONNECT\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http_user_agent test\"; " - "content:\"CO\"; http_user_agent; " - "content:!\"EC\"; distance:2; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectEngineHttpUARegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpUATest01", - DetectEngineHttpUATest01, 1); - UtRegisterTest("DetectEngineHttpUATest02", - DetectEngineHttpUATest02, 1); - UtRegisterTest("DetectEngineHttpUATest03", - DetectEngineHttpUATest03, 1); - UtRegisterTest("DetectEngineHttpUATest04", - DetectEngineHttpUATest04, 1); - UtRegisterTest("DetectEngineHttpUATest05", - DetectEngineHttpUATest05, 1); - UtRegisterTest("DetectEngineHttpUATest06", - DetectEngineHttpUATest06, 1); - UtRegisterTest("DetectEngineHttpUATest07", - DetectEngineHttpUATest07, 1); - UtRegisterTest("DetectEngineHttpUATest08", - DetectEngineHttpUATest08, 1); - UtRegisterTest("DetectEngineHttpUATest09", - DetectEngineHttpUATest09, 1); - UtRegisterTest("DetectEngineHttpUATest10", - DetectEngineHttpUATest10, 1); - UtRegisterTest("DetectEngineHttpUATest11", - DetectEngineHttpUATest11, 1); - UtRegisterTest("DetectEngineHttpUATest12", - DetectEngineHttpUATest12, 1); - UtRegisterTest("DetectEngineHttpUATest13", - DetectEngineHttpUATest13, 1); - UtRegisterTest("DetectEngineHttpUATest14", - DetectEngineHttpUATest14, 1); - UtRegisterTest("DetectEngineHttpUATest15", - DetectEngineHttpUATest15, 1); - UtRegisterTest("DetectEngineHttpUATest16", - DetectEngineHttpUATest16, 1); - UtRegisterTest("DetectEngineHttpUATest17", - DetectEngineHttpUATest17, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-hua.h b/framework/src/suricata/src/detect-engine-hua.h deleted file mode 100644 index c18ac761..00000000 --- a/framework/src/suricata/src/detect-engine-hua.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HUA_H__ -#define __DETECT_ENGINE_HUA_H__ - -#include "app-layer-htp.h" - -int DetectEngineInspectHttpUA(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -int DetectEngineRunHttpUAMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); -void DetectEngineHttpUARegisterTests(void); - -#endif /* __DETECT_ENGINE_HUA_H__ */ diff --git a/framework/src/suricata/src/detect-engine-iponly.c b/framework/src/suricata/src/detect-engine-iponly.c deleted file mode 100644 index 06983fc0..00000000 --- a/framework/src/suricata/src/detect-engine-iponly.c +++ /dev/null @@ -1,2321 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon Crespo - * - * Signatures that only inspect IP addresses are processed here - * We use radix trees for src dst ipv4 and ipv6 adresses - * This radix trees hold information for subnets and hosts in a - * hierarchical distribution - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "decode.h" -#include "flow.h" - -#include "detect-parse.h" -#include "detect-engine.h" - -#include "detect-engine-siggroup.h" -#include "detect-engine-address.h" -#include "detect-engine-proto.h" -#include "detect-engine-port.h" -#include "detect-engine-mpm.h" - -#include "detect-engine-threshold.h" -#include "detect-engine-iponly.h" -#include "detect-threshold.h" -#include "util-classification-config.h" -#include "util-rule-vars.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-print.h" -#include "util-profiling.h" - -#ifdef OS_WIN32 -#include -#else -#include -#endif /* OS_WIN32 */ - -/** - * \brief This function creates a new IPOnlyCIDRItem - * - * \retval IPOnlyCIDRItem address of the new instance - */ -static IPOnlyCIDRItem *IPOnlyCIDRItemNew() -{ - SCEnter(); - IPOnlyCIDRItem *item = NULL; - - item = SCMalloc(sizeof(IPOnlyCIDRItem)); - if (unlikely(item == NULL)) - SCReturnPtr(NULL, "IPOnlyCIDRItem"); - memset(item, 0, sizeof(IPOnlyCIDRItem)); - - SCReturnPtr(item, "IPOnlyCIDRItem"); -} - -static uint8_t IPOnlyCIDRItemCompare(IPOnlyCIDRItem *head, - IPOnlyCIDRItem *item) -{ - uint8_t i = 0; - for (; i < head->netmask / 32 || i < 1; i++) { - if (item->ip[i] < head->ip[i]) - //if (*(uint8_t *)(item->ip + i) < *(uint8_t *)(head->ip + i)) - return 1; - } - return 0; -} - -/** - * \internal - * \brief Parses an ipv4/ipv6 address string and updates the result into the - * IPOnlyCIDRItem instance sent as the argument. - * - * \param dd Pointer to the IPOnlyCIDRItem instance which should be updated with - * the address (in cidr) details from the parsed ip string. - * \param str Pointer to address string that has to be parsed. - * - * \retval 0 On successfully parsing the address string. - * \retval -1 On failure. - */ -static int IPOnlyCIDRItemParseSingle(IPOnlyCIDRItem *dd, char *str) -{ - char buf[256] = ""; - char *ip = NULL, *ip2 = NULL; - char *mask = NULL; - int r = 0; - - while (*str != '\0' && *str == ' ') - str++; - - SCLogDebug("str %s", str); - strlcpy(buf, str, sizeof(buf)); - ip = buf; - - /* first handle 'any' */ - if (strcasecmp(str, "any") == 0) { - /* if any, insert 0.0.0.0/0 and ::/0 as well */ - SCLogDebug("adding 0.0.0.0/0 and ::/0 as we\'re handling \'any\'"); - - IPOnlyCIDRItemParseSingle(dd, "0.0.0.0/0"); - BUG_ON(dd->family == 0); - - dd->next = IPOnlyCIDRItemNew(); - if (dd->next == NULL) - goto error; - - IPOnlyCIDRItemParseSingle(dd->next, "::/0"); - BUG_ON(dd->family == 0); - - SCLogDebug("address is \'any\'"); - return 0; - } - - /* handle the negation case */ - if (ip[0] == '!') { - dd->negated = (dd->negated)? 0 : 1; - ip++; - } - - /* see if the address is an ipv4 or ipv6 address */ - if ((strchr(str, ':')) == NULL) { - /* IPv4 Address */ - struct in_addr in; - - dd->family = AF_INET; - - if ((mask = strchr(ip, '/')) != NULL) { - /* 1.2.3.4/xxx format (either dotted or cidr notation */ - ip[mask - ip] = '\0'; - mask++; - uint32_t netmask = 0; - size_t u = 0; - - if ((strchr (mask, '.')) == NULL) { - /* 1.2.3.4/24 format */ - - for (u = 0; u < strlen(mask); u++) { - if(!isdigit((unsigned char)mask[u])) - goto error; - } - - int cidr = atoi(mask); - if (cidr < 0 || cidr > 32) - goto error; - - dd->netmask = cidr; - } else { - /* 1.2.3.4/255.255.255.0 format */ - r = inet_pton(AF_INET, mask, &in); - if (r <= 0) - goto error; - - netmask = in.s_addr; - - /* Extract cidr netmask */ - while ((0x01 & netmask) == 0) { - dd->netmask++; - netmask = netmask >> 1; - } - dd->netmask = 32 - dd->netmask; - } - - r = inet_pton(AF_INET, ip, &in); - if (r <= 0) - goto error; - - dd->ip[0] = in.s_addr; - - } else if ((ip2 = strchr(ip, '-')) != NULL) { - /* 1.2.3.4-1.2.3.6 range format */ - ip[ip2 - ip] = '\0'; - ip2++; - - uint32_t tmp_ip[4]; - uint32_t tmp_ip2[4]; - uint32_t first, last; - - r = inet_pton(AF_INET, ip, &in); - if (r <= 0) - goto error; - tmp_ip[0] = in.s_addr; - - r = inet_pton(AF_INET, ip2, &in); - if (r <= 0) - goto error; - tmp_ip2[0] = in.s_addr; - - /* a > b is illegal, a = b is ok */ - if (ntohl(tmp_ip[0]) > ntohl(tmp_ip2[0])) - goto error; - - first = ntohl(tmp_ip[0]); - last = ntohl(tmp_ip2[0]); - - dd->netmask = 32; - dd->ip[0] =htonl(first); - - if (first < last) { - for (first++; first <= last; first++) { - IPOnlyCIDRItem *new = IPOnlyCIDRItemNew(); - if (new == NULL) - goto error; - dd->next = new; - new->negated = dd->negated; - new->family= dd->family; - new->netmask = dd->netmask; - new->ip[0] = htonl(first); - dd = dd->next; - } - } - - } else { - /* 1.2.3.4 format */ - r = inet_pton(AF_INET, ip, &in); - if (r <= 0) - goto error; - - /* single host */ - dd->ip[0] = in.s_addr; - dd->netmask = 32; - } - } else { - /* IPv6 Address */ - struct in6_addr in6; - uint32_t ip6addr[4]; - - dd->family = AF_INET6; - - if ((mask = strchr(ip, '/')) != NULL) { - mask[0] = '\0'; - mask++; - - r = inet_pton(AF_INET6, ip, &in6); - if (r <= 0) - goto error; - - /* Format is cidr val */ - dd->netmask = atoi(mask); - - memcpy(dd->ip, &in6.s6_addr, sizeof(ip6addr)); - } else { - r = inet_pton(AF_INET6, ip, &in6); - if (r <= 0) - goto error; - - memcpy(dd->ip, &in6.s6_addr, sizeof(dd->ip)); - dd->netmask = 128; - } - - } - - BUG_ON(dd->family == 0); - return 0; - -error: - return -1; -} - -/** - * \brief Setup a single address string, parse it and add the resulting - * Address items in cidr format to the list of gh - * - * \param gh Pointer to the IPOnlyCIDRItem list Head to which the - * resulting Address-Range(s) from the parsed ip string has to - * be added. - * \param s Pointer to the ip address string to be parsed. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int IPOnlyCIDRItemSetup(IPOnlyCIDRItem *gh, char *s) -{ - SCLogDebug("gh %p, s %s", gh, s); - - /* parse the address */ - if (IPOnlyCIDRItemParseSingle(gh, s) == -1) { - SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC, - "DetectAddressParse error \"%s\"", s); - goto error; - } - - return 0; - -error: - return -1; -} - - -/** - * \brief This function insert a IPOnlyCIDRItem - * to a list of IPOnlyCIDRItems sorted by netmask - * ascending - * \param head Pointer to the head of IPOnlyCIDRItems list - * \param item Pointer to the item to insert in the list - * - * \retval IPOnlyCIDRItem address of the new head if apply - */ -static IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head, - IPOnlyCIDRItem *item) -{ - IPOnlyCIDRItem *it, *prev = NULL; - - if (item == NULL) - return head; - - /* Compare with the head */ - if (item->netmask < head->netmask || (item->netmask == head->netmask && IPOnlyCIDRItemCompare(head, item))) { - item->next = head; - return item; - } - - if (item->netmask == head->netmask && !IPOnlyCIDRItemCompare(head, item)) { - item->next = head->next; - head->next = item; - return head; - } - - for (prev = it = head; - it != NULL && it->netmask < item->netmask; - it = it->next) - prev = it; - - if (it == NULL) { - prev->next = item; - item->next = NULL; - } else { - item->next = it; - prev->next = item; - } - - return head; -} - -/** - * \brief This function insert a IPOnlyCIDRItem list - * to a list of IPOnlyCIDRItems sorted by netmask - * ascending - * \param head Pointer to the head of IPOnlyCIDRItems list - * \param item Pointer to the list of items to insert in the list - * - * \retval IPOnlyCIDRItem address of the new head if apply - */ -static IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head, - IPOnlyCIDRItem *item) -{ - IPOnlyCIDRItem *it, *prev = NULL; - - /* The first element */ - if (head == NULL) { - SCLogDebug("Head is NULL to insert item (%p)",item); - return item; - } - - if (item == NULL) { - SCLogDebug("Item is NULL"); - return head; - } - - SCLogDebug("Inserting item(%p)->netmask %u head %p", item, item->netmask, head); - - prev = item; - while (prev != NULL) { - it = prev->next; - - /* Separate from the item list */ - prev->next = NULL; - - //SCLogDebug("Before:"); - //IPOnlyCIDRListPrint(head); - head = IPOnlyCIDRItemInsertReal(head, prev); - //SCLogDebug("After:"); - //IPOnlyCIDRListPrint(head); - prev = it; - } - - return head; -} - -/** - * \brief This function free a IPOnlyCIDRItem list - * \param tmphead Pointer to the list - */ -void IPOnlyCIDRListFree(IPOnlyCIDRItem *tmphead) -{ - SCEnter(); - uint32_t i = 0; - - IPOnlyCIDRItem *it, *next = NULL; - - if (tmphead == NULL) { - SCLogDebug("temphead is NULL"); - return; - } - - it = tmphead; - next = it->next; - - while (it != NULL) { - i++; - SCFree(it); - SCLogDebug("Item(%p) %"PRIu32" removed\n", it, i); - it = next; - - if (next != NULL) - next = next->next; - } - SCReturn; -} - -/** - * \brief This function update a list of IPOnlyCIDRItems - * setting the signature internal id (signum) to "i" - * - * \param tmphead Pointer to the list - * \param i number of signature internal id - */ -static void IPOnlyCIDRListSetSigNum(IPOnlyCIDRItem *tmphead, SigIntId i) -{ - while (tmphead != NULL) { - tmphead->signum = i; - tmphead = tmphead->next; - } -} - -#ifdef UNITTESTS -/** - * \brief This function print a IPOnlyCIDRItem list - * \param tmphead Pointer to the head of IPOnlyCIDRItems list - */ -static void IPOnlyCIDRListPrint(IPOnlyCIDRItem *tmphead) -{ - uint32_t i = 0; - - while (tmphead != NULL) { - i++; - SCLogDebug("Item %"PRIu32" has netmask %"PRIu16" negated:" - " %s; IP: %s; signum: %"PRIu16, i, tmphead->netmask, - (tmphead->negated) ? "yes":"no", - inet_ntoa(*(struct in_addr*)&tmphead->ip[0]), - tmphead->signum); - tmphead = tmphead->next; - } -} -#endif - -/** - * \brief This function print a SigNumArray, it's used with the - * radix tree print function to help debugging - * \param tmp Pointer to the head of SigNumArray - */ -static void SigNumArrayPrint(void *tmp) -{ - SigNumArray *sna = (SigNumArray *)tmp; - uint32_t u; - - for (u = 0; u < sna->size; u++) { - uint8_t bitarray = sna->array[u]; - uint8_t i = 0; - - for (; i < 8; i++) { - if (bitarray & 0x01) - printf(", %"PRIu32"", u * 8 + i); - else - printf(", "); - - bitarray = bitarray >> 1; - } - } -} - -/** - * \brief This function creates a new SigNumArray with the - * size fixed to the io_ctx->max_idx - * \param de_ctx Pointer to the current detection context - * \param io_ctx Pointer to the current ip only context - * - * \retval SigNumArray address of the new instance - */ -static SigNumArray *SigNumArrayNew(DetectEngineCtx *de_ctx, - DetectEngineIPOnlyCtx *io_ctx) -{ - SigNumArray *new = SCMalloc(sizeof(SigNumArray)); - - if (unlikely(new == NULL)) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigNumArrayNew. Exiting..."); - exit(EXIT_FAILURE); - } - memset(new, 0, sizeof(SigNumArray)); - - new->array = SCMalloc(io_ctx->max_idx / 8 + 1); - if (new->array == NULL) { - exit(EXIT_FAILURE); - } - - memset(new->array, 0, io_ctx->max_idx / 8 + 1); - new->size = io_ctx->max_idx / 8 + 1; - - SCLogDebug("max idx= %u", io_ctx->max_idx); - - return new; -} - -/** - * \brief This function creates a new SigNumArray with the - * same data as the argument - * - * \param orig Pointer to the original SigNumArray to copy - * - * \retval SigNumArray address of the new instance - */ -static SigNumArray *SigNumArrayCopy(SigNumArray *orig) -{ - SigNumArray *new = SCMalloc(sizeof(SigNumArray)); - - if (unlikely(new == NULL)) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SigNumArrayCopy. Exiting..."); - exit(EXIT_FAILURE); - } - - memset(new, 0, sizeof(SigNumArray)); - new->size = orig->size; - - new->array = SCMalloc(orig->size); - if (new->array == NULL) { - exit(EXIT_FAILURE); - } - - memcpy(new->array, orig->array, orig->size); - return new; -} - -/** - * \brief This function free() a SigNumArray - * \param orig Pointer to the original SigNumArray to copy - */ -static void SigNumArrayFree(void *tmp) -{ - SigNumArray *sna = (SigNumArray *)tmp; - - if (sna == NULL) - return; - - if (sna->array != NULL) - SCFree(sna->array); - - SCFree(sna); -} - -/** - * \brief This function parses and return a list of IPOnlyCIDRItem - * - * \param s Pointer to the string of the addresses - * (in the format of signatures) - * \param negate flag to indicate if all this string is negated or not - * - * \retval 0 if success - * \retval -1 if fails - */ -static IPOnlyCIDRItem *IPOnlyCIDRListParse2(const DetectEngineCtx *de_ctx, - char *s, int negate) -{ - size_t x = 0; - size_t u = 0; - int o_set = 0, n_set = 0, d_set = 0; - int depth = 0; - size_t size = strlen(s); - char address[8196] = ""; - char *rule_var_address = NULL; - char *temp_rule_var_address = NULL; - IPOnlyCIDRItem *head; - IPOnlyCIDRItem *subhead; - head = subhead = NULL; - - SCLogDebug("s %s negate %s", s, negate ? "true" : "false"); - - for (u = 0, x = 0; u < size && x < sizeof(address); u++) { - address[x] = s[u]; - x++; - - if (!o_set && s[u] == '!') { - n_set = 1; - x--; - } else if (s[u] == '[') { - if (!o_set) { - o_set = 1; - x = 0; - } - depth++; - } else if (s[u] == ']') { - if (depth == 1) { - address[x - 1] = '\0'; - x = 0; - - if ( (subhead = IPOnlyCIDRListParse2(de_ctx, address, - (negate + n_set) % 2)) == NULL) - goto error; - - head = IPOnlyCIDRItemInsert(head, subhead); - n_set = 0; - } - depth--; - } else if (depth == 0 && s[u] == ',') { - if (o_set == 1) { - o_set = 0; - } else if (d_set == 1) { - address[x - 1] = '\0'; - - rule_var_address = SCRuleVarsGetConfVar(de_ctx, address, - SC_RULE_VARS_ADDRESS_GROUPS); - if (rule_var_address == NULL) - goto error; - - temp_rule_var_address = rule_var_address; - if ((negate + n_set) % 2) { - temp_rule_var_address = SCMalloc(strlen(rule_var_address) + 3); - - if (unlikely(temp_rule_var_address == NULL)) { - goto error; - } - - snprintf(temp_rule_var_address, strlen(rule_var_address) + 3, - "[%s]", rule_var_address); - } - - subhead = IPOnlyCIDRListParse2(de_ctx, temp_rule_var_address, - (negate + n_set) % 2); - head = IPOnlyCIDRItemInsert(head, subhead); - - d_set = 0; - n_set = 0; - - if (temp_rule_var_address != rule_var_address) - SCFree(temp_rule_var_address); - - } else { - address[x - 1] = '\0'; - - subhead = IPOnlyCIDRItemNew(); - if (subhead == NULL) - goto error; - - if (!((negate + n_set) % 2)) - subhead->negated = 0; - else - subhead->negated = 1; - - if (IPOnlyCIDRItemSetup(subhead, address) < 0) { - IPOnlyCIDRListFree(subhead); - subhead = NULL; - goto error; - } - head = IPOnlyCIDRItemInsert(head, subhead); - - n_set = 0; - } - x = 0; - } else if (depth == 0 && s[u] == '$') { - d_set = 1; - } else if (depth == 0 && u == size - 1) { - if (x == sizeof(address)) { - address[x - 1] = '\0'; - } else { - address[x] = '\0'; - } - x = 0; - - if (d_set == 1) { - rule_var_address = SCRuleVarsGetConfVar(de_ctx, address, - SC_RULE_VARS_ADDRESS_GROUPS); - if (rule_var_address == NULL) - goto error; - - temp_rule_var_address = rule_var_address; - if ((negate + n_set) % 2) { - temp_rule_var_address = SCMalloc(strlen(rule_var_address) + 3); - if (unlikely(temp_rule_var_address == NULL)) { - goto error; - } - snprintf(temp_rule_var_address, strlen(rule_var_address) + 3, - "[%s]", rule_var_address); - } - subhead = IPOnlyCIDRListParse2(de_ctx, temp_rule_var_address, - (negate + n_set) % 2); - head = IPOnlyCIDRItemInsert(head, subhead); - - d_set = 0; - - if (temp_rule_var_address != rule_var_address) - SCFree(temp_rule_var_address); - } else { - subhead = IPOnlyCIDRItemNew(); - if (subhead == NULL) - goto error; - - if (!((negate + n_set) % 2)) - subhead->negated = 0; - else - subhead->negated = 1; - - if (IPOnlyCIDRItemSetup(subhead, address) < 0) { - IPOnlyCIDRListFree(subhead); - subhead = NULL; - goto error; - } - head = IPOnlyCIDRItemInsert(head, subhead); - } - n_set = 0; - } - } - - return head; - -error: - SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC,"Error parsing addresses"); - return head; -} - - -/** - * \brief Parses an address group sent as a character string and updates the - * IPOnlyCIDRItem list - * - * \param gh Pointer to the IPOnlyCIDRItem list - * \param str Pointer to the character string containing the address group - * that has to be parsed. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int IPOnlyCIDRListParse(const DetectEngineCtx *de_ctx, - IPOnlyCIDRItem **gh, char *str) -{ - SCLogDebug("gh %p, str %s", gh, str); - - if (gh == NULL) - goto error; - - *gh = IPOnlyCIDRListParse2(de_ctx, str, 0); - if (*gh == NULL) { - SCLogDebug("DetectAddressParse2 returned null"); - goto error; - } - - return 0; - -error: - return -1; -} - -/** - * \brief Parses an address group sent as a character string and updates the - * IPOnlyCIDRItem lists src and dst of the Signature *s - * - * \param s Pointer to the signature structure - * \param addrstr Pointer to the character string containing the address group - * that has to be parsed. - * \param flag to indicate if we are parsing the src string or the dst string - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int IPOnlySigParseAddress(const DetectEngineCtx *de_ctx, - Signature *s, const char *addrstr, char flag) -{ - SCLogDebug("Address Group \"%s\" to be parsed now", addrstr); - IPOnlyCIDRItem *tmp = NULL; - - /* pass on to the address(list) parser */ - if (flag == 0) { - if (strcasecmp(addrstr, "any") == 0) { - s->flags |= SIG_FLAG_SRC_ANY; - - if (IPOnlyCIDRListParse(de_ctx, &s->CidrSrc, (char *)"0.0.0.0/0") < 0) - goto error; - - if (IPOnlyCIDRListParse(de_ctx, &tmp, (char *)"::/0") < 0) - goto error; - - s->CidrSrc = IPOnlyCIDRItemInsert(s->CidrSrc, tmp); - - } else if (IPOnlyCIDRListParse(de_ctx, &s->CidrSrc, (char *)addrstr) < 0) { - goto error; - } - - /* IPOnlyCIDRListPrint(s->CidrSrc); */ - } else { - if (strcasecmp(addrstr, "any") == 0) { - s->flags |= SIG_FLAG_DST_ANY; - - if (IPOnlyCIDRListParse(de_ctx, &tmp, (char *)"0.0.0.0/0") < 0) - goto error; - - if (IPOnlyCIDRListParse(de_ctx, &s->CidrDst, (char *)"::/0") < 0) - goto error; - - s->CidrDst = IPOnlyCIDRItemInsert(s->CidrDst, tmp); - - } else if (IPOnlyCIDRListParse(de_ctx, &s->CidrDst, (char *)addrstr) < 0) { - goto error; - } - - /* IPOnlyCIDRListPrint(s->CidrDst); */ - } - - return 0; - -error: - SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC, "failed to parse addresses"); - return -1; -} - -/** - * \brief Setup the IP Only detection engine context - * - * \param de_ctx Pointer to the current detection engine - * \param io_ctx Pointer to the current ip only detection engine - */ -void IPOnlyInit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx) -{ - io_ctx->sig_init_size = DetectEngineGetMaxSigId(de_ctx) / 8 + 1; - - if ( (io_ctx->sig_init_array = SCMalloc(io_ctx->sig_init_size)) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in IPOnlyInit. Exiting..."); - exit(EXIT_FAILURE); - } - - memset(io_ctx->sig_init_array, 0, io_ctx->sig_init_size); - - io_ctx->tree_ipv4src = SCRadixCreateRadixTree(SigNumArrayFree, - SigNumArrayPrint); - io_ctx->tree_ipv4dst = SCRadixCreateRadixTree(SigNumArrayFree, - SigNumArrayPrint); - io_ctx->tree_ipv6src = SCRadixCreateRadixTree(SigNumArrayFree, - SigNumArrayPrint); - io_ctx->tree_ipv6dst = SCRadixCreateRadixTree(SigNumArrayFree, - SigNumArrayPrint); -} - -/** - * \brief Setup the IP Only thread detection engine context - * - * \param de_ctx Pointer to the current detection engine - * \param io_ctx Pointer to the current ip only thread detection engine - */ -void DetectEngineIPOnlyThreadInit(DetectEngineCtx *de_ctx, - DetectEngineIPOnlyThreadCtx *io_tctx) -{ - /* initialize the signature bitarray */ - io_tctx->sig_match_size = de_ctx->io_ctx.max_idx / 8 + 1; - io_tctx->sig_match_array = SCMalloc(io_tctx->sig_match_size); - if (io_tctx->sig_match_array == NULL) { - exit(EXIT_FAILURE); - } - - memset(io_tctx->sig_match_array, 0, io_tctx->sig_match_size); -} - -/** - * \brief Print stats of the IP Only engine - * - * \param de_ctx Pointer to the current detection engine - * \param io_ctx Pointer to the current ip only detection engine - */ -void IPOnlyPrint(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx) -{ - /* XXX: how are we going to print the stats now? */ -} - -/** - * \brief Deinitialize the IP Only detection engine context - * - * \param de_ctx Pointer to the current detection engine - * \param io_ctx Pointer to the current ip only detection engine - */ -void IPOnlyDeinit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx) -{ - - if (io_ctx == NULL) - return; - - if (io_ctx->tree_ipv4src != NULL) - SCRadixReleaseRadixTree(io_ctx->tree_ipv4src); - io_ctx->tree_ipv4src = NULL; - - if (io_ctx->tree_ipv4dst != NULL) - SCRadixReleaseRadixTree(io_ctx->tree_ipv4dst); - io_ctx->tree_ipv4dst = NULL; - - if (io_ctx->tree_ipv6src != NULL) - SCRadixReleaseRadixTree(io_ctx->tree_ipv6src); - io_ctx->tree_ipv6src = NULL; - - if (io_ctx->tree_ipv6dst != NULL) - SCRadixReleaseRadixTree(io_ctx->tree_ipv6dst); - io_ctx->tree_ipv6dst = NULL; - - if (io_ctx->sig_init_array) - SCFree(io_ctx->sig_init_array); - io_ctx->sig_init_array = NULL; -} - -/** - * \brief Deinitialize the IP Only thread detection engine context - * - * \param de_ctx Pointer to the current detection engine - * \param io_ctx Pointer to the current ip only detection engine - */ -void DetectEngineIPOnlyThreadDeinit(DetectEngineIPOnlyThreadCtx *io_tctx) -{ - SCFree(io_tctx->sig_match_array); -} - -static inline -int IPOnlyMatchCompatSMs(ThreadVars *tv, - DetectEngineThreadCtx *det_ctx, - Signature *s, Packet *p) -{ - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_MATCH); - SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - - while (sm != NULL) { - BUG_ON(!(sigmatch_table[sm->type].flags & SIGMATCH_IPONLY_COMPAT)); - KEYWORD_PROFILING_START; - if (sigmatch_table[sm->type].Match(tv, det_ctx, p, s, sm->ctx) > 0) { - KEYWORD_PROFILING_END(det_ctx, sm->type, 1); - sm = sm->next; - continue; - } - KEYWORD_PROFILING_END(det_ctx, sm->type, 0); - return 0; - } - - return 1; -} - -/** - * \brief Match a packet against the IP Only detection engine contexts - * - * \param de_ctx Pointer to the current detection engine - * \param io_ctx Pointer to the current ip only detection engine - * \param io_ctx Pointer to the current ip only thread detection engine - * \param p Pointer to the Packet to match against - */ -void IPOnlyMatchPacket(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - DetectEngineIPOnlyCtx *io_ctx, - DetectEngineIPOnlyThreadCtx *io_tctx, Packet *p) -{ - SigNumArray *src = NULL; - SigNumArray *dst = NULL; - void *user_data_src = NULL, *user_data_dst = NULL; - - if (p->src.family == AF_INET) { - (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)&GET_IPV4_SRC_ADDR_U32(p), - io_ctx->tree_ipv4src, &user_data_src); - } else if (p->src.family == AF_INET6) { - (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)&GET_IPV6_SRC_ADDR(p), - io_ctx->tree_ipv6src, &user_data_src); - } - - if (p->dst.family == AF_INET) { - (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)&GET_IPV4_DST_ADDR_U32(p), - io_ctx->tree_ipv4dst, &user_data_dst); - } else if (p->dst.family == AF_INET6) { - (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)&GET_IPV6_DST_ADDR(p), - io_ctx->tree_ipv6dst, &user_data_dst); - } - - src = user_data_src; - dst = user_data_dst; - - if (src == NULL || dst == NULL) - return; - - uint32_t u; - for (u = 0; u < src->size; u++) { - SCLogDebug("And %"PRIu8" & %"PRIu8, src->array[u], dst->array[u]); - - /* The final results will be at io_tctx */ - io_tctx->sig_match_array[u] = dst->array[u] & src->array[u]; - - /* We have to move the logic of the signature checking - * to the main detect loop, in order to apply the - * priority of actions (pass, drop, reject, alert) */ - if (io_tctx->sig_match_array[u] != 0) { - /* We have a match :) Let's see from which signum's */ - uint8_t bitarray = io_tctx->sig_match_array[u]; - uint8_t i = 0; - - for (; i < 8; i++, bitarray = bitarray >> 1) { - if (bitarray & 0x01) { - Signature *s = de_ctx->sig_array[u * 8 + i]; - - if ((s->proto.flags & DETECT_PROTO_IPV4) && !PKT_IS_IPV4(p)) { - SCLogDebug("ip version didn't match"); - continue; - } - if ((s->proto.flags & DETECT_PROTO_IPV6) && !PKT_IS_IPV6(p)) { - SCLogDebug("ip version didn't match"); - continue; - } - - if (DetectProtoContainsProto(&s->proto, IP_GET_IPPROTO(p)) == 0) { - SCLogDebug("proto didn't match"); - continue; - } - - /* check the source & dst port in the sig */ - if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) { - if (!(s->flags & SIG_FLAG_DP_ANY)) { - if (p->flags & PKT_IS_FRAGMENT) - continue; - - DetectPort *dport = DetectPortLookupGroup(s->dp,p->dp); - if (dport == NULL) { - SCLogDebug("dport didn't match."); - continue; - } - } - if (!(s->flags & SIG_FLAG_SP_ANY)) { - if (p->flags & PKT_IS_FRAGMENT) - continue; - - DetectPort *sport = DetectPortLookupGroup(s->sp,p->sp); - if (sport == NULL) { - SCLogDebug("sport didn't match."); - continue; - } - } - } else if ((s->flags & (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) != (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) { - SCLogDebug("port-less protocol and sig needs ports"); - continue; - } - - if (!IPOnlyMatchCompatSMs(tv, det_ctx, s, p)) { - continue; - } - - SCLogDebug("Signum %"PRIu16" match (sid: %"PRIu16", msg: %s)", - u * 8 + i, s->id, s->msg); - - if (s->sm_arrays[DETECT_SM_LIST_POSTMATCH] != NULL) { - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_POSTMATCH); - SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_POSTMATCH]; - - SCLogDebug("running match functions, sm %p", smd); - - if (smd != NULL) { - while (1) { - KEYWORD_PROFILING_START; - (void)sigmatch_table[smd->type].Match(tv, det_ctx, p, s, smd->ctx); - KEYWORD_PROFILING_END(det_ctx, smd->type, 1); - if (smd->is_last) - break; - smd++; - } - } - } - if (!(s->flags & SIG_FLAG_NOALERT)) { - if (s->action & ACTION_DROP) - PacketAlertAppend(det_ctx, s, p, 0, PACKET_ALERT_FLAG_DROP_FLOW); - else - PacketAlertAppend(det_ctx, s, p, 0, 0); - } else { - /* apply actions for noalert/rule suppressed as well */ - DetectSignatureApplyActions(p, s); - } - } - } - } - } -} - -/** - * \brief Build the radix trees from the lists of parsed adresses in CIDR format - * the result should be 4 radix trees: src/dst ipv4 and src/dst ipv6 - * holding SigNumArrays, each of them with a hierarchical relation - * of subnets and hosts - * - * \param de_ctx Pointer to the current detection engine - */ -void IPOnlyPrepare(DetectEngineCtx *de_ctx) -{ - SCLogDebug("Preparing Final Lists"); - - /* - IPOnlyCIDRListPrint((de_ctx->io_ctx).ip_src); - IPOnlyCIDRListPrint((de_ctx->io_ctx).ip_dst); - */ - - IPOnlyCIDRItem *src, *dst; - SCRadixNode *node = NULL; - - /* Prepare Src radix trees */ - for (src = (de_ctx->io_ctx).ip_src; src != NULL; ) { - if (src->family == AF_INET) { - /* - SCLogDebug("To IPv4"); - SCLogDebug("Item has netmask %"PRIu16" negated: %s; IP: %s; " - "signum: %"PRIu16, src->netmask, - (src->negated) ? "yes":"no", - inet_ntoa( *(struct in_addr*)&src->ip[0]), - src->signum); - */ - - void *user_data = NULL; - if (src->netmask == 32) - (void)SCRadixFindKeyIPV4ExactMatch((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv4src, - &user_data); - else - (void)SCRadixFindKeyIPV4Netblock((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv4src, - src->netmask, &user_data); - if (user_data == NULL) { - SCLogDebug("Exact match not found"); - - /** Not found, look if there's a subnet of this range with - * bigger netmask */ - (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv4src, - &user_data); - if (user_data == NULL) { - SCLogDebug("best match not found"); - - /* Not found, insert a new one */ - SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx); - - /* Update the sig */ - uint8_t tmp = 1 << (src->signum % 8); - - if (src->negated > 0) - /* Unset it */ - sna->array[src->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[src->signum / 8] |= tmp; - - if (src->netmask == 32) - node = SCRadixAddKeyIPV4((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv4src, sna); - else - node = SCRadixAddKeyIPV4Netblock((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv4src, - sna, src->netmask); - - if (node == NULL) - SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the " - "src ipv4 radix tree"); - } else { - SCLogDebug("Best match found"); - - /* Found, copy the sig num table, add this signum and insert */ - SigNumArray *sna = NULL; - sna = SigNumArrayCopy((SigNumArray *) user_data); - - /* Update the sig */ - uint8_t tmp = 1 << (src->signum % 8); - - if (src->negated > 0) - /* Unset it */ - sna->array[src->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[src->signum / 8] |= tmp; - - if (src->netmask == 32) - node = SCRadixAddKeyIPV4((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv4src, sna); - else - node = SCRadixAddKeyIPV4Netblock((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv4src, sna, - src->netmask); - - if (node == NULL) { - char tmpstr[64]; - PrintInet(src->family, &src->ip[0], tmpstr, sizeof(tmpstr)); - SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the" - " src ipv4 radix tree ip %s netmask %"PRIu8, tmpstr, src->netmask); - //SCRadixPrintTree((de_ctx->io_ctx).tree_ipv4src); - exit(-1); - } - } - } else { - SCLogDebug("Exact match found"); - - /* it's already inserted. Update it */ - SigNumArray *sna = (SigNumArray *)user_data; - - /* Update the sig */ - uint8_t tmp = 1 << (src->signum % 8); - - if (src->negated > 0) - /* Unset it */ - sna->array[src->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[src->signum / 8] |= tmp; - } - } else if (src->family == AF_INET6) { - SCLogDebug("To IPv6"); - - void *user_data = NULL; - if (src->netmask == 128) - (void)SCRadixFindKeyIPV6ExactMatch((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv6src, - &user_data); - else - (void)SCRadixFindKeyIPV6Netblock((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv6src, - src->netmask, &user_data); - - if (user_data == NULL) { - /* Not found, look if there's a subnet of this range with bigger netmask */ - (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv6src, - &user_data); - - if (user_data == NULL) { - /* Not found, insert a new one */ - SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx); - - /* Update the sig */ - uint8_t tmp = 1 << (src->signum % 8); - - if (src->negated > 0) - /* Unset it */ - sna->array[src->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[src->signum / 8] |= tmp; - - if (src->netmask == 128) - node = SCRadixAddKeyIPV6((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv6src, sna); - else - node = SCRadixAddKeyIPV6Netblock((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv6src, - sna, src->netmask); - if (node == NULL) - SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the src " - "ipv6 radix tree"); - } else { - /* Found, copy the sig num table, add this signum and insert */ - SigNumArray *sna = NULL; - sna = SigNumArrayCopy((SigNumArray *)user_data); - - /* Update the sig */ - uint8_t tmp = 1 << (src->signum % 8); - if (src->negated > 0) - /* Unset it */ - sna->array[src->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[src->signum / 8] |= tmp; - - if (src->netmask == 128) - node = SCRadixAddKeyIPV6((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv6src, sna); - else - node = SCRadixAddKeyIPV6Netblock((uint8_t *)&src->ip[0], - (de_ctx->io_ctx).tree_ipv6src, - sna, src->netmask); - if (node == NULL) - SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the src " - "ipv6 radix tree"); - } - } else { - /* it's already inserted. Update it */ - SigNumArray *sna = (SigNumArray *)user_data; - - /* Update the sig */ - uint8_t tmp = 1 << (src->signum % 8); - if (src->negated > 0) - /* Unset it */ - sna->array[src->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[src->signum / 8] |= tmp; - } - } - IPOnlyCIDRItem *tmpaux = src; - src = src->next; - SCFree(tmpaux); - } - - SCLogDebug("dsts:"); - - /* Prepare Dst radix trees */ - for (dst = (de_ctx->io_ctx).ip_dst; dst != NULL; ) { - if (dst->family == AF_INET) { - - SCLogDebug("To IPv4"); - SCLogDebug("Item has netmask %"PRIu16" negated: %s; IP: %s; signum:" - " %"PRIu16"", dst->netmask, (dst->negated)?"yes":"no", - inet_ntoa(*(struct in_addr*)&dst->ip[0]), dst->signum); - - void *user_data = NULL; - if (dst->netmask == 32) - (void) SCRadixFindKeyIPV4ExactMatch((uint8_t *) &dst->ip[0], - (de_ctx->io_ctx).tree_ipv4dst, - &user_data); - else - (void) SCRadixFindKeyIPV4Netblock((uint8_t *) &dst->ip[0], - (de_ctx->io_ctx).tree_ipv4dst, - dst->netmask, - &user_data); - - if (user_data == NULL) { - SCLogDebug("Exact match not found"); - - /** - * Not found, look if there's a subnet of this range - * with bigger netmask - */ - (void) SCRadixFindKeyIPV4BestMatch((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv4dst, - &user_data); - if (user_data == NULL) { - SCLogDebug("Best match not found"); - - /** Not found, insert a new one */ - SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx); - - /** Update the sig */ - uint8_t tmp = 1 << (dst->signum % 8); - if (dst->negated > 0) - /** Unset it */ - sna->array[dst->signum / 8] &= ~tmp; - else - /** Set it */ - sna->array[dst->signum / 8] |= tmp; - - if (dst->netmask == 32) - node = SCRadixAddKeyIPV4((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv4dst, sna); - else - node = SCRadixAddKeyIPV4Netblock((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv4dst, - sna, dst->netmask); - - if (node == NULL) - SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the dst " - "ipv4 radix tree"); - } else { - SCLogDebug("Best match found"); - - /* Found, copy the sig num table, add this signum and insert */ - SigNumArray *sna = NULL; - sna = SigNumArrayCopy((SigNumArray *) user_data); - - /* Update the sig */ - uint8_t tmp = 1 << (dst->signum % 8); - if (dst->negated > 0) - /* Unset it */ - sna->array[dst->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[dst->signum / 8] |= tmp; - - if (dst->netmask == 32) - node = SCRadixAddKeyIPV4((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv4dst, sna); - else - node = SCRadixAddKeyIPV4Netblock((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv4dst, - sna, dst->netmask); - - if (node == NULL) - SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the dst " - "ipv4 radix tree"); - } - } else { - SCLogDebug("Exact match found"); - - /* it's already inserted. Update it */ - SigNumArray *sna = (SigNumArray *)user_data; - - /* Update the sig */ - uint8_t tmp = 1 << (dst->signum % 8); - if (dst->negated > 0) - /* Unset it */ - sna->array[dst->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[dst->signum / 8] |= tmp; - } - } else if (dst->family == AF_INET6) { - SCLogDebug("To IPv6"); - - void *user_data = NULL; - if (dst->netmask == 128) - (void) SCRadixFindKeyIPV6ExactMatch((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv6dst, - &user_data); - else - (void) SCRadixFindKeyIPV6Netblock((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv6dst, - dst->netmask, &user_data); - - if (user_data == NULL) { - /** Not found, look if there's a subnet of this range with - * bigger netmask - */ - (void) SCRadixFindKeyIPV6BestMatch((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv6dst, - &user_data); - - if (user_data == NULL) { - /* Not found, insert a new one */ - SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx); - - /* Update the sig */ - uint8_t tmp = 1 << (dst->signum % 8); - if (dst->negated > 0) - /* Unset it */ - sna->array[dst->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[dst->signum / 8] |= tmp; - - if (dst->netmask == 128) - node = SCRadixAddKeyIPV6((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv6dst, sna); - else - node = SCRadixAddKeyIPV6Netblock((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv6dst, - sna, dst->netmask); - - if (node == NULL) - SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the dst " - "ipv6 radix tree"); - } else { - /* Found, copy the sig num table, add this signum and insert */ - SigNumArray *sna = NULL; - sna = SigNumArrayCopy((SigNumArray *)user_data); - - /* Update the sig */ - uint8_t tmp = 1 << (dst->signum % 8); - if (dst->negated > 0) - /* Unset it */ - sna->array[dst->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[dst->signum / 8] |= tmp; - - if (dst->netmask == 128) - node = SCRadixAddKeyIPV6((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv6dst, sna); - else - node = SCRadixAddKeyIPV6Netblock((uint8_t *)&dst->ip[0], - (de_ctx->io_ctx).tree_ipv6dst, - sna, dst->netmask); - - if (node == NULL) - SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the dst " - "ipv6 radix tree"); - } - } else { - /* it's already inserted. Update it */ - SigNumArray *sna = (SigNumArray *)user_data; - - /* Update the sig */ - uint8_t tmp = 1 << (dst->signum % 8); - if (dst->negated > 0) - /* Unset it */ - sna->array[dst->signum / 8] &= ~tmp; - else - /* Set it */ - sna->array[dst->signum / 8] |= tmp; - } - } - IPOnlyCIDRItem *tmpaux = dst; - dst = dst->next; - SCFree(tmpaux); - } - - /* print all the trees: for debuggin it might print too much info - SCLogDebug("Radix tree src ipv4:"); - SCRadixPrintTree((de_ctx->io_ctx).tree_ipv4src); - SCLogDebug("Radix tree src ipv6:"); - SCRadixPrintTree((de_ctx->io_ctx).tree_ipv6src); - SCLogDebug("__________________"); - - SCLogDebug("Radix tree dst ipv4:"); - SCRadixPrintTree((de_ctx->io_ctx).tree_ipv4dst); - SCLogDebug("Radix tree dst ipv6:"); - SCRadixPrintTree((de_ctx->io_ctx).tree_ipv6dst); - SCLogDebug("__________________"); - */ -} - -/** - * \brief Add a signature to the lists of Adrresses in CIDR format (sorted) - * this step is necesary to build the radix tree with a hierarchical - * relation between nodes - * \param de_ctx Pointer to the current detection engine context - * \param de_ctx Pointer to the current ip only detection engine contest - * \param s Pointer to the current signature - */ -void IPOnlyAddSignature(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx, - Signature *s) -{ - if (!(s->flags & SIG_FLAG_IPONLY)) - return; - - /* Set the internal signum to the list before merging */ - IPOnlyCIDRListSetSigNum(s->CidrSrc, s->num); - - IPOnlyCIDRListSetSigNum(s->CidrDst, s->num); - - /** - * ipv4 and ipv6 are mixed, but later we will separate them into - * different trees - */ - io_ctx->ip_src = IPOnlyCIDRItemInsert(io_ctx->ip_src, s->CidrSrc); - io_ctx->ip_dst = IPOnlyCIDRItemInsert(io_ctx->ip_dst, s->CidrDst); - - if (s->num > io_ctx->max_idx) - io_ctx->max_idx = s->num; - - /* enable the sig in the bitarray */ - io_ctx->sig_init_array[(s->num/8)] |= 1 << (s->num % 8); - - /** no longer ref to this, it's in the table now */ - s->CidrSrc = NULL; - s->CidrDst = NULL; -} - -#ifdef UNITTESTS -/** - * \test check that we set a Signature as IPOnly because it has no rule - * option appending a SigMatch and no port is fixed - */ - -static int IPOnlyTestSig01(void) -{ - int result = 0; - DetectEngineCtx de_ctx; - - memset(&de_ctx, 0, sizeof(DetectEngineCtx)); - - de_ctx.flags |= DE_QUIET; - - Signature *s = SigInit(&de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-01 sig is IPOnly \"; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(&de_ctx, s)) - result = 1; - else - printf("expected a IPOnly signature: "); - - SigFree(s); -end: - return result; -} - -/** - * \test check that we dont set a Signature as IPOnly because it has no rule - * option appending a SigMatch but a port is fixed - */ - -static int IPOnlyTestSig02 (void) -{ - int result = 0; - DetectEngineCtx de_ctx; - memset (&de_ctx, 0, sizeof(DetectEngineCtx)); - - memset(&de_ctx, 0, sizeof(DetectEngineCtx)); - - de_ctx.flags |= DE_QUIET; - - Signature *s = SigInit(&de_ctx,"alert tcp any any -> any 80 (msg:\"SigTest40-02 sig is not IPOnly \"; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if ((SignatureIsIPOnly(&de_ctx, s))) - result = 1; - else - printf("got a non-IPOnly signature: "); - - SigFree(s); - -end: - return result; -} - -/** - * \test check that we set dont set a Signature as IPOnly - * because it has rule options appending a SigMatch like content, and pcre - */ - -static int IPOnlyTestSig03 (void) -{ - int result = 1; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - /* combination of pcre and content */ - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (pcre and content) \"; content:\"php\"; pcre:\"/require(_once)?/i\"; classtype:misc-activity; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(de_ctx, s)) - { - printf("got a IPOnly signature (content): "); - result=0; - } - SigFree(s); - - /* content */ - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (content) \"; content:\"match something\"; classtype:misc-activity; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(de_ctx, s)) - { - printf("got a IPOnly signature (content): "); - result=0; - } - SigFree(s); - - /* uricontent */ - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (uricontent) \"; uricontent:\"match something\"; classtype:misc-activity; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(de_ctx, s)) - { - printf("got a IPOnly signature (uricontent): "); - result=0; - } - SigFree(s); - - /* pcre */ - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (pcre) \"; pcre:\"/e?idps rule[sz]/i\"; classtype:misc-activity; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(de_ctx, s)) - { - printf("got a IPOnly signature (pcre): "); - result=0; - } - SigFree(s); - - /* flow */ - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (flow) \"; flow:to_server; classtype:misc-activity; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(de_ctx, s)) - { - printf("got a IPOnly signature (flow): "); - result=0; - } - SigFree(s); - - /* dsize */ - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (dsize) \"; dsize:100; classtype:misc-activity; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(de_ctx, s)) - { - printf("got a IPOnly signature (dsize): "); - result=0; - } - SigFree(s); - - /* flowbits */ - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (flowbits) \"; flowbits:unset; classtype:misc-activity; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(de_ctx, s)) - { - printf("got a IPOnly signature (flowbits): "); - result=0; - } - SigFree(s); - - /* flowvar */ - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (flowvar) \"; pcre:\"/(?.*)/i\"; flowvar:var,\"str\"; classtype:misc-activity; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(de_ctx, s)) - { - printf("got a IPOnly signature (flowvar): "); - result=0; - } - SigFree(s); - - /* pktvar */ - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (pktvar) \"; pcre:\"/(?.*)/i\"; pktvar:var,\"str\"; classtype:misc-activity; sid:400001; rev:1;)"); - if (s == NULL) { - goto end; - } - if(SignatureIsIPOnly(de_ctx, s)) - { - printf("got a IPOnly signature (pktvar): "); - result=0; - } - SigFree(s); - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test - */ -static int IPOnlyTestSig04 (void) -{ - int result = 1; - - IPOnlyCIDRItem *head = NULL; - IPOnlyCIDRItem *new; - - new = IPOnlyCIDRItemNew(); - new->netmask= 10; - - head = IPOnlyCIDRItemInsert(head, new); - - new = IPOnlyCIDRItemNew(); - new->netmask= 11; - - head = IPOnlyCIDRItemInsert(head, new); - - new = IPOnlyCIDRItemNew(); - new->netmask= 9; - - head = IPOnlyCIDRItemInsert(head, new); - - new = IPOnlyCIDRItemNew(); - new->netmask= 10; - - head = IPOnlyCIDRItemInsert(head, new); - - new = IPOnlyCIDRItemNew(); - new->netmask= 10; - - head = IPOnlyCIDRItemInsert(head, new); - - IPOnlyCIDRListPrint(head); - new = head; - if (new->netmask != 9) { - result = 0; - goto end; - } - new = new->next; - if (new->netmask != 10) { - result = 0; - goto end; - } - new = new->next; - if (new->netmask != 10) { - result = 0; - goto end; - } - new = new->next; - if (new->netmask != 10) { - result = 0; - goto end; - } - new = new->next; - if (new->netmask != 11) { - result = 0; - goto end; - } - -end: - IPOnlyCIDRListFree(head); - return result; -} - -/** - * \test Test a set of ip only signatures making use a lot of - * addresses for src and dst (all should match) - */ -int IPOnlyTestSig05(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 1; - uint8_t numsigs = 7; - - Packet *p[1]; - - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - char *sigs[numsigs]; - sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)"; - sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)"; - sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)"; - sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)"; - sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)"; - sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)"; - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; - uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} - -/** - * \test Test a set of ip only signatures making use a lot of - * addresses for src and dst (none should match) - */ -int IPOnlyTestSig06(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 1; - uint8_t numsigs = 7; - - Packet *p[1]; - - p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "80.58.0.33", "195.235.113.3"); - - char *sigs[numsigs]; - sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)"; - sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)"; - sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)"; - sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)"; - sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)"; - sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)"; - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; - uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} - -/* \todo fix it. We have disabled this unittest because 599 exposes 608, - * which is why these unittests fail. When we fix 608, we need to renable - * these sigs */ -#if 0 -/** - * \test Test a set of ip only signatures making use a lot of - * addresses for src and dst (all should match) - */ -int IPOnlyTestSig07(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 1; - uint8_t numsigs = 7; - - Packet *p[1]; - - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - char *sigs[numsigs]; - sigs[0]= "alert tcp 192.168.1.5 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert tcp [192.168.1.2,192.168.1.5,192.168.1.4] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)"; - sigs[2]= "alert tcp [192.168.1.0/24,!192.168.1.1] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)"; - sigs[3]= "alert tcp [192.0.0.0/8,!192.168.0.0/16,192.168.1.0/24,!192.168.1.1] any -> [192.168.1.0/24,!192.168.1.5] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)"; - sigs[4]= "alert tcp any any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)"; - sigs[5]= "alert tcp any any -> [192.168.0.0/16,!192.168.1.0/24,192.168.1.1] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)"; - sigs[6]= "alert tcp [78.129.202.0/24,192.168.1.5,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> 192.168.1.1 any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */ - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; - uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} -#endif - -/** - * \test Test a set of ip only signatures making use a lot of - * addresses for src and dst (none should match) - */ -int IPOnlyTestSig08(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 1; - uint8_t numsigs = 7; - - Packet *p[1]; - - p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"192.168.1.1","192.168.1.5"); - - char *sigs[numsigs]; - sigs[0]= "alert tcp 192.168.1.5 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert tcp [192.168.1.2,192.168.1.5,192.168.1.4] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)"; - sigs[2]= "alert tcp [192.168.1.0/24,!192.168.1.1] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)"; - sigs[3]= "alert tcp [192.0.0.0/8,!192.168.0.0/16,192.168.1.0/24,!192.168.1.1] any -> [192.168.1.0/24,!192.168.1.5] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)"; - sigs[4]= "alert tcp any any -> !192.168.1.5 any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)"; - sigs[5]= "alert tcp any any -> [192.168.0.0/16,!192.168.1.0/24,192.168.1.1] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)"; - sigs[6]= "alert tcp [78.129.202.0/24,192.168.1.5,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> 192.168.1.1 any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */ - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; - uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} - -/** - * \test Test a set of ip only signatures making use a lot of - * addresses for src and dst (all should match) - */ -int IPOnlyTestSig09(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 1; - uint8_t numsigs = 7; - - Packet *p[1]; - - p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565", "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562"); - - char *sigs[numsigs]; - sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)"; - sigs[2]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)"; - sigs[3]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:0/96 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)"; - sigs[4]= "alert tcp 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)"; - sigs[5]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)"; - sigs[6]= "alert tcp 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)"; - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; - uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} - -/** - * \test Test a set of ip only signatures making use a lot of - * addresses for src and dst (none should match) - */ -int IPOnlyTestSig10(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 1; - uint8_t numsigs = 7; - - Packet *p[1]; - - p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562", "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565"); - - char *sigs[numsigs]; - sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)"; - sigs[2]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)"; - sigs[3]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> !3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562/96 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)"; - sigs[4]= "alert tcp !3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)"; - sigs[5]= "alert tcp any any -> !3FFE:FFFF:7654:FEDA:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)"; - sigs[6]= "alert tcp 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> 3FFE:FFFF:7654:FEDB:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)"; - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; - uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} - -/* \todo fix it. We have disabled this unittest because 599 exposes 608, - * which is why these unittests fail. When we fix 608, we need to renable - * these sigs */ -#if 0 -/** - * \test Test a set of ip only signatures making use a lot of - * addresses for src and dst (all should match) with ipv4 and ipv6 mixed - */ -int IPOnlyTestSig11(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 2; - uint8_t numsigs = 7; - - Packet *p[2]; - - p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565", "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562"); - p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"192.168.1.1","192.168.1.5"); - - char *sigs[numsigs]; - sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1 any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.5 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert tcp [192.168.1.1,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.4,192.168.1.5,!192.168.1.0/24] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.0/24] any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)"; - sigs[2]= "alert tcp [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)"; - sigs[3]= "alert tcp [3FFE:FFFF:0:0:0:0:0:0/32,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.0/24,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)"; - sigs[4]= "alert tcp any any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)"; - sigs[5]= "alert tcp any any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)"; - sigs[6]= "alert tcp [78.129.202.0/24,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.0.0.0/8] any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */ - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; - uint32_t results[2][7] = {{ 1, 1, 1, 1, 1, 1, 1}, { 1, 1, 1, 1, 1, 1, 1}}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} -#endif - -/** - * \test Test a set of ip only signatures making use a lot of - * addresses for src and dst (none should match) with ipv4 and ipv6 mixed - */ -int IPOnlyTestSig12(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 2; - uint8_t numsigs = 7; - - Packet *p[2]; - - p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"3FBE:FFFF:7654:FEDA:1245:BA98:3210:4562","3FBE:FFFF:7654:FEDA:1245:BA98:3210:4565"); - p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"195.85.1.1","80.198.1.5"); - - char *sigs[numsigs]; - sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1 any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.5 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert tcp [192.168.1.1,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.4,192.168.1.5,!192.168.1.0/24] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.0/24] any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)"; - sigs[2]= "alert tcp [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)"; - sigs[3]= "alert tcp [3FFE:FFFF:0:0:0:0:0:0/32,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.0/24,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)"; - sigs[4]= "alert tcp any any -> [!3FBE:FFFF:7654:FEDA:1245:BA98:3210:4565,!80.198.1.5] any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)"; - sigs[5]= "alert tcp any any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)"; - sigs[6]= "alert tcp [78.129.202.0/24,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.0.0.0/8] any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */ - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; - uint32_t results[2][7] = {{ 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} - -static int IPOnlyTestSig13(void) -{ - int result = 0; - DetectEngineCtx de_ctx; - - memset(&de_ctx, 0, sizeof(DetectEngineCtx)); - - de_ctx.flags |= DE_QUIET; - - Signature *s = SigInit(&de_ctx, - "alert tcp any any -> any any (msg:\"Test flowbits ip only\"; " - "flowbits:set,myflow1; sid:1; rev:1;)"); - if (s == NULL) { - goto end; - } - if (SignatureIsIPOnly(&de_ctx, s)) - result = 1; - else - printf("expected a IPOnly signature: "); - - SigFree(s); -end: - return result; -} - -static int IPOnlyTestSig14(void) -{ - int result = 0; - DetectEngineCtx de_ctx; - - memset(&de_ctx, 0, sizeof(DetectEngineCtx)); - - de_ctx.flags |= DE_QUIET; - - Signature *s = SigInit(&de_ctx, - "alert tcp any any -> any any (msg:\"Test flowbits ip only\"; " - "flowbits:set,myflow1; flowbits:isset,myflow2; sid:1; rev:1;)"); - if (s == NULL) { - goto end; - } - if (SignatureIsIPOnly(&de_ctx, s)) - printf("expected a IPOnly signature: "); - else - result = 1; - - SigFree(s); -end: - return result; -} - -int IPOnlyTestSig15(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 1; - uint8_t numsigs = 7; - - Packet *p[1]; - Flow f; - GenericVar flowvar; - memset(&f, 0, sizeof(Flow)); - memset(&flowvar, 0, sizeof(GenericVar)); - FLOW_INITIALIZE(&f); - - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - p[0]->flow = &f; - p[0]->flow->flowvar = &flowvar; - p[0]->flags |= PKT_HAS_FLOW; - p[0]->flowflags |= FLOW_PKT_TOSERVER; - - char *sigs[numsigs]; - sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; " - "flowbits:set,one; sid:1;)"; - sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; " - "flowbits:set,two; sid:2;)"; - sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; " - "flowbits:set,three; sid:3;)"; - sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; " - "flowbits:set,four; sid:4;)"; - sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; " - "flowbits:set,five; sid:5;)"; - sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; " - "flowbits:set,six; sid:6;)"; - sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; " - "flowbits:set,seven; content:\"Hi all\"; sid:7;)"; - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; - uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - FLOW_DESTROY(&f); - return result; -} - -/** - * \brief Unittest to show #599. We fail to match if we have negated addresses. - */ -int IPOnlyTestSig16(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 1; - uint8_t numsigs = 2; - - Packet *p[1]; - - p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "100.100.0.0", "50.0.0.0"); - - char *sigs[numsigs]; - sigs[0]= "alert tcp !100.100.0.1 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert tcp any any -> !50.0.0.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)"; - - /* Sid numbers (we could extract them from the sig) */ - uint32_t sid[2] = { 1, 2}; - uint32_t results[2] = { 1, 1}; - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} - -/** - * \brief Unittest to show #611. Ports on portless protocols. - */ -int IPOnlyTestSig17(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - uint8_t numpkts = 1; - uint8_t numsigs = 2; - - Packet *p[1]; - - p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_ICMP, "100.100.0.0", "50.0.0.0"); - - char *sigs[numsigs]; - sigs[0]= "alert ip 100.100.0.0 80 -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)"; - sigs[1]= "alert ip any any -> 50.0.0.0 123 (msg:\"Testing dst ip (sid 2)\"; sid:2;)"; - - uint32_t sid[2] = { 1, 2}; - uint32_t results[2] = { 0, 0}; /* neither should match */ - - result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); - - UTHFreePackets(p, numpkts); - - return result; -} - -#endif /* UNITTESTS */ - -void IPOnlyRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("IPOnlyTestSig01", IPOnlyTestSig01, 1); - UtRegisterTest("IPOnlyTestSig02", IPOnlyTestSig02, 1); - UtRegisterTest("IPOnlyTestSig03", IPOnlyTestSig03, 1); - UtRegisterTest("IPOnlyTestSig04", IPOnlyTestSig04, 1); - - UtRegisterTest("IPOnlyTestSig05", IPOnlyTestSig05, 1); - UtRegisterTest("IPOnlyTestSig06", IPOnlyTestSig06, 1); -/* \todo fix it. We have disabled this unittest because 599 exposes 608, - * which is why these unittests fail. When we fix 608, we need to renable - * these sigs */ -#if 0 - UtRegisterTest("IPOnlyTestSig07", IPOnlyTestSig07, 1); -#endif - UtRegisterTest("IPOnlyTestSig08", IPOnlyTestSig08, 1); - - UtRegisterTest("IPOnlyTestSig09", IPOnlyTestSig09, 1); - UtRegisterTest("IPOnlyTestSig10", IPOnlyTestSig10, 1); -/* \todo fix it. We have disabled this unittest because 599 exposes 608, - * which is why these unittests fail. When we fix 608, we need to renable - * these sigs */ -#if 0 - UtRegisterTest("IPOnlyTestSig11", IPOnlyTestSig11, 1); -#endif - UtRegisterTest("IPOnlyTestSig12", IPOnlyTestSig12, 1); - UtRegisterTest("IPOnlyTestSig13", IPOnlyTestSig13, 1); - UtRegisterTest("IPOnlyTestSig14", IPOnlyTestSig14, 1); - UtRegisterTest("IPOnlyTestSig15", IPOnlyTestSig15, 1); - UtRegisterTest("IPOnlyTestSig16", IPOnlyTestSig16, 1); - - UtRegisterTest("IPOnlyTestSig17", IPOnlyTestSig17, 1); -#endif - - return; -} - diff --git a/framework/src/suricata/src/detect-engine-iponly.h b/framework/src/suricata/src/detect-engine-iponly.h deleted file mode 100644 index b71a5933..00000000 --- a/framework/src/suricata/src/detect-engine-iponly.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_IPONLY_H__ -#define __DETECT_ENGINE_IPONLY_H__ - -/** - * SigNumArray is a bit array representing signatures - * it can be used linked to src/dst address to indicate - * which signatures apply to this addres - * at IP Only we store SigNumArrays at the radix trees - */ -typedef struct SigNumArray_ { - uint8_t *array; /* bit array of sig nums */ - uint32_t size; /* size in bytes of the array */ -} SigNumArray; - -void IPOnlyCIDRListFree(IPOnlyCIDRItem *tmphead); -int IPOnlySigParseAddress(const DetectEngineCtx *, Signature *, const char *, char); -void IPOnlyMatchPacket(ThreadVars *tv, DetectEngineCtx *, - DetectEngineThreadCtx *, DetectEngineIPOnlyCtx *, - DetectEngineIPOnlyThreadCtx *, Packet *); -void IPOnlyInit(DetectEngineCtx *, DetectEngineIPOnlyCtx *); -void IPOnlyPrint(DetectEngineCtx *, DetectEngineIPOnlyCtx *); -void IPOnlyDeinit(DetectEngineCtx *, DetectEngineIPOnlyCtx *); -void IPOnlyPrepare(DetectEngineCtx *); -void DetectEngineIPOnlyThreadInit(DetectEngineCtx *, DetectEngineIPOnlyThreadCtx *); -void DetectEngineIPOnlyThreadDeinit(DetectEngineIPOnlyThreadCtx *); -void IPOnlyAddSignature(DetectEngineCtx *, DetectEngineIPOnlyCtx *, Signature *); -void IPOnlyRegisterTests(void); - -#endif /* __DETECT_ENGINE_IPONLY_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-loader.c b/framework/src/suricata/src/detect-engine-loader.c deleted file mode 100644 index b360cd04..00000000 --- a/framework/src/suricata/src/detect-engine-loader.c +++ /dev/null @@ -1,300 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "conf.h" -#include "debug.h" -#include "detect.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "queue.h" -#include "util-signal.h" - -#include "detect-engine-loader.h" - -#define NLOADERS 4 -static DetectLoaderControl *loaders = NULL; -static int cur_loader = 0; -void TmThreadWakeupDetectLoaderThreads(void); -static int num_loaders = NLOADERS; - -/** \param loader -1 for auto select - * \retval loader_id or negative in case of error */ -int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx) -{ - if (loader_id == -1) { - loader_id = cur_loader; - cur_loader++; - if (cur_loader >= num_loaders) - cur_loader = 0; - } - if (loader_id >= num_loaders || loader_id < 0) { - return -ERANGE; - } - - DetectLoaderControl *loader = &loaders[loader_id]; - - DetectLoaderTask *t = SCCalloc(1, sizeof(*t)); - if (t == NULL) - return -ENOMEM; - - t->Func = Func; - t->ctx = func_ctx; - - SCMutexLock(&loader->m); - TAILQ_INSERT_TAIL(&loader->task_list, t, next); - SCMutexUnlock(&loader->m); - - TmThreadWakeupDetectLoaderThreads(); - - SCLogDebug("%d %p %p", loader_id, Func, func_ctx); - return loader_id; -} - -/** \brief wait for loader tasks to complete - * \retval result 0 for ok, -1 for errors */ -int DetectLoadersSync(void) -{ - SCLogDebug("waiting"); - int errors = 0; - int i; - for (i = 0; i < num_loaders; i++) { - int done = 0; - DetectLoaderControl *loader = &loaders[i]; - while (!done) { - SCMutexLock(&loader->m); - if (TAILQ_EMPTY(&loader->task_list)) { - done = 1; - } - SCMutexUnlock(&loader->m); - } - SCMutexLock(&loader->m); - if (loader->result != 0) { - errors++; - loader->result = 0; - } - SCMutexUnlock(&loader->m); - - } - if (errors) { - SCLogError(SC_ERR_INITIALIZATION, "%d loaders reported errors", errors); - return -1; - } - SCLogDebug("done"); - return 0; -} - -static void DetectLoaderInit(DetectLoaderControl *loader) -{ - memset(loader, 0x00, sizeof(*loader)); - SCMutexInit(&loader->m, NULL); - TAILQ_INIT(&loader->task_list); -} - -void DetectLoadersInit(void) -{ - intmax_t setting = NLOADERS; - (void)ConfGetInt("multi-detect.loaders", &setting); - - if (setting < 1 || setting > 1024) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, - "invalid multi-detect.loaders setting %"PRIdMAX, setting); - exit(EXIT_FAILURE); - } - num_loaders = (int32_t)setting; - - SCLogInfo("using %d detect loader threads", num_loaders); - - BUG_ON(loaders != NULL); - loaders = SCCalloc(num_loaders, sizeof(DetectLoaderControl)); - BUG_ON(loaders == NULL); - - int i; - for (i = 0; i < num_loaders; i++) { - DetectLoaderInit(&loaders[i]); - } -} - -/** - * \brief Unpauses all threads present in tv_root - */ -void TmThreadWakeupDetectLoaderThreads() -{ - ThreadVars *tv = NULL; - int i = 0; - - SCMutexLock(&tv_root_lock); - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - while (tv != NULL) { - if (strcmp(tv->name,"DetectLoader") == 0) { - BUG_ON(tv->ctrl_cond == NULL); - pthread_cond_broadcast(tv->ctrl_cond); - } - tv = tv->next; - } - } - SCMutexUnlock(&tv_root_lock); - - return; -} - -/** - * \brief Unpauses all threads present in tv_root - */ -void TmThreadContinueDetectLoaderThreads() -{ - ThreadVars *tv = NULL; - int i = 0; - - SCMutexLock(&tv_root_lock); - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - while (tv != NULL) { - if (strcmp(tv->name,"DetectLoader") == 0) - TmThreadContinue(tv); - - tv = tv->next; - } - } - SCMutexUnlock(&tv_root_lock); - - return; -} - - -SC_ATOMIC_DECLARE(int, detect_loader_cnt); - -typedef struct DetectLoaderThreadData_ { - uint32_t instance; -} DetectLoaderThreadData; - -static TmEcode DetectLoaderThreadInit(ThreadVars *t, void *initdata, void **data) -{ - DetectLoaderThreadData *ftd = SCCalloc(1, sizeof(DetectLoaderThreadData)); - if (ftd == NULL) - return TM_ECODE_FAILED; - - ftd->instance = SC_ATOMIC_ADD(detect_loader_cnt, 1) - 1; /* id's start at 0 */ - SCLogDebug("detect loader instance %u", ftd->instance); - - /* pass thread data back to caller */ - *data = ftd; - - return TM_ECODE_OK; -} - -static TmEcode DetectLoaderThreadDeinit(ThreadVars *t, void *data) -{ - SCFree(data); - return TM_ECODE_OK; -} - - -static TmEcode DetectLoader(ThreadVars *th_v, void *thread_data) -{ - /* block usr2. usr2 to be handled by the main thread only */ - UtilSignalBlock(SIGUSR2); - - DetectLoaderThreadData *ftd = (DetectLoaderThreadData *)thread_data; - BUG_ON(ftd == NULL); - - SCLogDebug("loader thread started"); - while (1) - { - if (TmThreadsCheckFlag(th_v, THV_PAUSE)) { - TmThreadsSetFlag(th_v, THV_PAUSED); - TmThreadTestThreadUnPaused(th_v); - TmThreadsUnsetFlag(th_v, THV_PAUSED); - } - - /* see if we have tasks */ - - DetectLoaderControl *loader = &loaders[ftd->instance]; - SCMutexLock(&loader->m); - - DetectLoaderTask *task = NULL, *tmptask = NULL; - TAILQ_FOREACH_SAFE(task, &loader->task_list, next, tmptask) { - int r = task->Func(task->ctx, ftd->instance); - loader->result |= r; - TAILQ_REMOVE(&loader->task_list, task, next); - SCFree(task); - } - - SCMutexUnlock(&loader->m); - - if (TmThreadsCheckFlag(th_v, THV_KILL)) { - break; - } - - /* just wait until someone wakes us up */ - SCCtrlMutexLock(th_v->ctrl_mutex); - SCCtrlCondWait(th_v->ctrl_cond, th_v->ctrl_mutex); - SCCtrlMutexUnlock(th_v->ctrl_mutex); - - SCLogDebug("woke up..."); - } - - return TM_ECODE_OK; -} - -/** \brief spawn the detect loader manager thread */ -void DetectLoaderThreadSpawn() -{ - int i; - for (i = 0; i < num_loaders; i++) { - ThreadVars *tv_loader = NULL; - - char name[32] = ""; - snprintf(name, sizeof(name), "DetectLoader%02d", i+1); - - tv_loader = TmThreadCreateCmdThreadByName("DetectLoader", - "DetectLoader", 1); - BUG_ON(tv_loader == NULL); - - if (tv_loader == NULL) { - printf("ERROR: TmThreadsCreate failed\n"); - exit(1); - } - if (TmThreadSpawn(tv_loader) != TM_ECODE_OK) { - printf("ERROR: TmThreadSpawn failed\n"); - exit(1); - } - } - return; -} - -void TmModuleDetectLoaderRegister (void) -{ - tmm_modules[TMM_DETECTLOADER].name = "DetectLoader"; - tmm_modules[TMM_DETECTLOADER].ThreadInit = DetectLoaderThreadInit; - tmm_modules[TMM_DETECTLOADER].ThreadDeinit = DetectLoaderThreadDeinit; - tmm_modules[TMM_DETECTLOADER].Management = DetectLoader; - tmm_modules[TMM_DETECTLOADER].cap_flags = 0; - tmm_modules[TMM_DETECTLOADER].flags = TM_FLAG_MANAGEMENT_TM; - SCLogDebug("%s registered", tmm_modules[TMM_DETECTLOADER].name); - - SC_ATOMIC_INIT(detect_loader_cnt); -} diff --git a/framework/src/suricata/src/detect-engine-loader.h b/framework/src/suricata/src/detect-engine-loader.h deleted file mode 100644 index de28bdaf..00000000 --- a/framework/src/suricata/src/detect-engine-loader.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Detect loader API, for using multiple 'loader' threads - * that can load multiple detection engines in parallel. - */ - -#ifndef __DETECT_ENGINE_LOADER_H__ -#define __DETECT_ENGINE_LOADER_H__ - -/** - * \param ctx function specific data - * \param loader_id id of the loader that executed the task - */ -typedef int (*LoaderFunc)(void *ctx, int loader_id); - -typedef struct DetectLoaderTask_ { - LoaderFunc Func; - void *ctx; - TAILQ_ENTRY(DetectLoaderTask_) next; -} DetectLoaderTask; - -typedef struct DetectLoaderControl_ { - int id; - int result; /* 0 for ok, error otherwise */ - SCMutex m; - TAILQ_HEAD(, DetectLoaderTask_) task_list; -} DetectLoaderControl; - -int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx); -int DetectLoadersSync(void); -void DetectLoadersInit(void); - -void TmThreadContinueDetectLoaderThreads(); -void DetectLoaderThreadSpawn(); -void TmModuleDetectLoaderRegister (void); - -#endif /* __DETECT_ENGINE_LOADER_H__ */ diff --git a/framework/src/suricata/src/detect-engine-modbus.c b/framework/src/suricata/src/detect-engine-modbus.c deleted file mode 100644 index 8bbe5828..00000000 --- a/framework/src/suricata/src/detect-engine-modbus.c +++ /dev/null @@ -1,1345 +0,0 @@ -/* - * Copyright (C) 2014 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** \file - * - * \author David DIALLO - * - * Based on detect-engine-dns.c - */ - -#include "suricata-common.h" - -#include "app-layer.h" -#include "app-layer-modbus.h" - -#include "detect.h" -#include "detect-modbus.h" - -#include "detect-engine-modbus.h" - -#include "flow.h" - -#include "util-debug.h" - -/** \internal - * - * \brief Value match detection code - * - * \param value Modbus value context (min, max and mode) - * \param min Minimum value to compare - * \param inter Interval or maximum (min + inter) value to compare - * - * \retval 1 match or 0 no match - */ -static int DetectEngineInspectModbusValueMatch(DetectModbusValue *value, - uint16_t min, - uint16_t inter) -{ - SCEnter(); - uint16_t max = min + inter; - - int ret = 0; - - switch (value->mode) { - case DETECT_MODBUS_EQ: - if ((value->min >= min) && (value->min <= max)) - ret = 1; - break; - - case DETECT_MODBUS_LT: - if (value->min > min) - ret = 1; - break; - - case DETECT_MODBUS_GT: - if (value->min < max) - ret = 1; - break; - - case DETECT_MODBUS_RA: - if ((value->max > min) && (value->min < max)) - ret = 1; - break; - } - - SCReturnInt(ret); -} - -/** \internal - * - * \brief Do data (and address) inspection & validation for a signature - * - * \param tx Pointer to Modbus Transaction - * \param address Address inspection - * \param data Pointer to data signature structure to match - * - * \retval 0 no match or 1 match - */ -static int DetectEngineInspectModbusData(ModbusTransaction *tx, - uint16_t address, - DetectModbusValue *data) -{ - SCEnter(); - uint16_t offset, value = 0, type = tx->type; - - if (type & MODBUS_TYP_SINGLE) { - /* Output/Register(s) Value */ - if (type & MODBUS_TYP_COILS) - value = (tx->data[0])? 1 : 0; - else - value = tx->data[0]; - } else if (type & MODBUS_TYP_MULTIPLE) { - int i, size = (int) sizeof(tx->data); - - offset = address - (tx->write.address + 1); - - /* In case of Coils, offset is in bit (convert in byte) */ - if (type & MODBUS_TYP_COILS) - offset >>= 3; - - for (i=0; i< size; i++) { - /* Select the correct register/coils amongst the output value */ - if (!(offset--)) { - value = tx->data[i]; - break; - } - } - - /* In case of Coils, offset is now in the bit is the rest of previous convert */ - if (type & MODBUS_TYP_COILS) { - offset = (address - (tx->write.address + 1)) & 0x7; - value = (value >> offset) & 0x1; - } - } else { - /* It is not possible to define the value that is writing for Mask */ - /* Write Register function because the current content is not available.*/ - SCReturnInt(0); - } - - SCReturnInt(DetectEngineInspectModbusValueMatch(data, value, 0)); -} - -/** \internal - * - * \brief Do address inspection & validation for a signature - * - * \param tx Pointer to Modbus Transaction - * \param address Pointer to address signature structure to match - * \param access Access mode (READ or WRITE) - * - * \retval 0 no match or 1 match - */ -static int DetectEngineInspectModbusAddress(ModbusTransaction *tx, - DetectModbusValue *address, - uint8_t access) -{ - SCEnter(); - int ret = 0; - - /* Check if read/write address of request is at/in the address range of signature */ - if (access == MODBUS_TYP_READ) { - /* In the PDU Coils are addresses starting at zero */ - /* therefore Coils numbered 1-16 are addressed as 0-15 */ - ret = DetectEngineInspectModbusValueMatch(address, - tx->read.address + 1, - tx->read.quantity - 1); - } else { - /* In the PDU Registers are addresses starting at zero */ - /* therefore Registers numbered 1-16 are addressed as 0-15 */ - if (tx->type & MODBUS_TYP_SINGLE) - ret = DetectEngineInspectModbusValueMatch(address, - tx->write.address + 1, - 0); - else - ret = DetectEngineInspectModbusValueMatch(address, - tx->write.address + 1, - tx->write.quantity - 1); - } - - SCReturnInt(ret); -} - -/** \brief Do the content inspection & validation for a signature - * - * \param de_ctx Detection engine context - * \param det_ctx Detection engine thread context - * \param s Signature to inspect ( and sm: SigMatch to inspect) - * \param f Flow - * \param flags App layer flags - * \param alstate App layer state - * \param txv Pointer to Modbus Transaction structure - * - * \retval 0 no match or 1 match - */ -int DetectEngineInspectModbus(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, - Flow *f, - uint8_t flags, - void *alstate, - void *txv, - uint64_t tx_id) -{ - SCEnter(); - ModbusTransaction *tx = (ModbusTransaction *)txv; - SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MODBUS_MATCH]; - DetectModbus *modbus = (DetectModbus *) sm->ctx; - - int ret = 0; - - if (modbus == NULL) { - SCLogDebug("no modbus state, no match"); - SCReturnInt(0); - } - - if (modbus->type == MODBUS_TYP_NONE) { - if (modbus->category == MODBUS_CAT_NONE) { - if (modbus->function == tx->function) { - if (modbus->subfunction != NULL) { - SCLogDebug("looking for Modbus server function %d and subfunction %d", - modbus->function, *(modbus->subfunction)); - ret = (*(modbus->subfunction) == (tx->subFunction))? 1 : 0; - } else { - SCLogDebug("looking for Modbus server function %d", modbus->function); - ret = 1; - } - } - } else { - SCLogDebug("looking for Modbus category function %d", modbus->category); - ret = (tx->category & modbus->category)? 1 : 0; - } - } else { - uint8_t access = modbus->type & MODBUS_TYP_ACCESS_MASK; - uint8_t function = modbus->type & MODBUS_TYP_ACCESS_FUNCTION_MASK; - - if ((access & tx->type) && ((function == MODBUS_TYP_NONE) || (function & tx->type))) { - if (modbus->address != NULL) { - ret = DetectEngineInspectModbusAddress(tx, modbus->address, access); - - if (ret && (modbus->data != NULL)) { - ret = DetectEngineInspectModbusData(tx, modbus->address->min, modbus->data); - } - } else { - SCLogDebug("looking for Modbus access type %d and function type %d", access, function); - ret = 1; - } - } - } - - SCReturnInt(ret); -} - -#ifdef UNITTESTS /* UNITTESTS */ -#include "app-layer-parser.h" - -#include "detect-parse.h" - -#include "detect-engine.h" - -#include "flow-util.h" - -#include "stream-tcp.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -/* Modbus Application Protocol Specification V1.1b3 6.1: Read Coils */ -/* Example of a request to read discrete outputs 20-38 */ -static uint8_t readCoilsReq[] = {/* Transaction ID */ 0x00, 0x00, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x06, - /* Unit ID */ 0x00, - /* Function code */ 0x01, - /* Starting Address */ 0x78, 0x90, - /* Quantity of coils */ 0x00, 0x13 }; - -/* Modbus Application Protocol Specification V1.1b3 6.4: Read Input Registers */ -/* Example of a request to read input register 9 */ -static uint8_t readInputsRegistersReq[] = {/* Transaction ID */ 0x00, 0x0A, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x06, - /* Unit ID */ 0x00, - /* Function code */ 0x04, - /* Starting Address */ 0x00, 0x08, - /* Quantity of Registers */ 0x00, 0x60}; - -/* Modbus Application Protocol Specification V1.1b3 6.17: Read/Write Multiple registers */ -/* Example of a request to read six registers starting at register 4, */ -/* and to write three registers starting at register 15 */ -static uint8_t readWriteMultipleRegistersReq[] = {/* Transaction ID */ 0x12, 0x34, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x11, - /* Unit ID */ 0x00, - /* Function code */ 0x17, - /* Read Starting Address */ 0x00, 0x03, - /* Quantity to Read */ 0x00, 0x06, - /* Write Starting Address */ 0x00, 0x0E, - /* Quantity to Write */ 0x00, 0x03, - /* Write Byte count */ 0x06, - /* Write Registers Value */ 0x12, 0x34, /* 15 */ - 0x56, 0x78, /* 16 */ - 0x9A, 0xBC};/* 17 */ - -/* Modbus Application Protocol Specification V1.1b3 6.8.1: 04 Force Listen Only Mode */ -/* Example of a request to to remote device to its Listen Only MOde for Modbus Communications. */ -static uint8_t forceListenOnlyMode[] = {/* Transaction ID */ 0x0A, 0x00, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x06, - /* Unit ID */ 0x00, - /* Function code */ 0x08, - /* Sub-function code */ 0x00, 0x04, - /* Data */ 0x00, 0x00}; - -/* Modbus Application Protocol Specification V1.1b3 Annex A */ -/* Modbus Reserved Function codes, Subcodes and MEI types */ -static uint8_t encapsulatedInterfaceTransport[] = { - /* Transaction ID */ 0x00, 0x10, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x05, - /* Unit ID */ 0x00, - /* Function code */ 0x2B, - /* MEI Type */ 0x0F, - /* Data */ 0x00, 0x00}; - -static uint8_t unassigned[] = {/* Transaction ID */ 0x00, 0x0A, - /* Protocol ID */ 0x00, 0x00, - /* Length */ 0x00, 0x02, - /* Unit ID */ 0x00, - /* Function code */ 0x12}; - -/** \test Test code function. */ -static int DetectEngineInspectModbusTest01(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(readCoilsReq, sizeof(readCoilsReq), IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus code function\"; " - "modbus: function 23; sid:1;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - readWriteMultipleRegistersReq, sizeof(readWriteMultipleRegistersReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test code function and code subfunction. */ -static int DetectEngineInspectModbusTest02(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(readCoilsReq, sizeof(readCoilsReq), IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus function and subfunction\"; " - "modbus: function 8, subfunction 4; sid:1;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, forceListenOnlyMode, sizeof(forceListenOnlyMode)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test function category. */ -static int DetectEngineInspectModbusTest03(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(readCoilsReq, sizeof(readCoilsReq), IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus category function\"; " - "modbus: function reserved; sid:1;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - encapsulatedInterfaceTransport, sizeof(encapsulatedInterfaceTransport)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test negative function category. */ -static int DetectEngineInspectModbusTest04(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(readCoilsReq, sizeof(readCoilsReq), IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus category function\"; " - "modbus: function !assigned; sid:1;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, unassigned, sizeof(unassigned)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test access type. */ -static int DetectEngineInspectModbusTest05(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(readCoilsReq, sizeof(readCoilsReq), IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access type\"; " - "modbus: access read; sid:1;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - readCoilsReq, sizeof(readCoilsReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test access function. */ -static int DetectEngineInspectModbusTest06(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(readCoilsReq, sizeof(readCoilsReq), IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access type\"; " - "modbus: access read input; sid:1;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - readInputsRegistersReq, sizeof(readInputsRegistersReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test read access at an address. */ -static int DetectEngineInspectModbusTest07(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(readCoilsReq, sizeof(readCoilsReq), IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus address access\"; " - "modbus: access read, address 30870; sid:1;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, readCoilsReq, sizeof(readCoilsReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test read access at a range of address. */ -static int DetectEngineInspectModbusTest08(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(readCoilsReq, sizeof(readCoilsReq), IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - /* readInputsRegistersReq, Starting Address = 0x08, Quantity of Registers = 0x60 */ - /* Read access address from 9 to 104 */ - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address <9; sid:1;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address 9; sid:2;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address 5<>9; sid:3;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address <10; sid:4;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address 5<>10; sid:5;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address >103; sid:6;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address 103<>110; sid:7;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address 104; sid:8;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address >104; sid:9;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus access\"; " - "modbus: access read input, " - "address 104<>110; sid:10;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - readInputsRegistersReq, sizeof(readInputsRegistersReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 did match but should not have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have: "); - goto end; - } - - if (PacketAlertCheck(p, 3)) { - printf("sid 3 did match but should not have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 4))) { - printf("sid 4 didn't match but should have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 5))) { - printf("sid 5 didn't match but should have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 6))) { - printf("sid 6 didn't match but should have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 7))) { - printf("sid 7 didn't match but should have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 8))) { - printf("sid 8 didn't match but should have: "); - goto end; - } - - if (PacketAlertCheck(p, 9)) { - printf("sid 9 did match but should not have: "); - goto end; - } - - if (PacketAlertCheck(p, 10)) { - printf("sid 10 did match but should not have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test write access at a address in a range of value. */ -static int DetectEngineInspectModbusTest09(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - TcpSession ssn; - ThreadVars tv; - - int result = 0; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(readCoilsReq, sizeof(readCoilsReq), IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_MODBUS; - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - /* readWriteMultipleRegistersReq, Write Starting Address = 0x0E, Quantity to Write = 0x03 */ - /* Write access register address 15 = 0x1234 (4660) */ - /* Write access register address 16 = 0x5678 (22136) */ - /* Write access register address 17 = 0x9ABC (39612) */ - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 15, value <4660; sid:1;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 16, value <22137; sid:2;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 17, value 39612; sid:3;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 15, value 4661; sid:4;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 16, value 20000<>22136; sid:5;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 17, value 30000<>39613; sid:6;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 15, value 4659<>5000; sid:7;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 16, value 22136<>30000; sid:8;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 17, value >39611; sid:9;)"); - - s = DetectEngineAppendSig(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus write access\"; " - "modbus: access write holding, " - "address 15, value >4660; sid:10;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER, - readWriteMultipleRegistersReq, sizeof(readWriteMultipleRegistersReq)); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ModbusState *modbus_state = f.alstate; - if (modbus_state == NULL) { - printf("no modbus state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 did match but should not have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 3))) { - printf("sid 3 didn't match but should have: "); - goto end; - } - - if (PacketAlertCheck(p, 4)) { - printf("sid 4 did match but should not have: "); - goto end; - } - - if (PacketAlertCheck(p, 5)) { - printf("sid 5 did match but should not have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 6))) { - printf("sid 6 didn't match but should have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 7))) { - printf("sid 7 didn't match but should have: "); - goto end; - } - - if (PacketAlertCheck(p, 8)) { - printf("sid 8 did match but should not have: "); - goto end; - } - - if (!(PacketAlertCheck(p, 9))) { - printf("sid 9 didn't match but should have: "); - goto end; - } - - if (PacketAlertCheck(p, 10)) { - printf("sid 10 did match but should not have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} -#endif /* UNITTESTS */ - -void DetectEngineInspectModbusRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectEngineInspectModbusTest01 - Code function", DetectEngineInspectModbusTest01, 1); - UtRegisterTest("DetectEngineInspectModbusTest02 - code function and code subfunction", DetectEngineInspectModbusTest02, 1); - UtRegisterTest("DetectEngineInspectModbusTest03 - Function category", DetectEngineInspectModbusTest03, 1); - UtRegisterTest("DetectEngineInspectModbusTest04 - Negative function category", DetectEngineInspectModbusTest04, 1); - UtRegisterTest("DetectEngineInspectModbusTest05 - Access type", DetectEngineInspectModbusTest05, 1); - UtRegisterTest("DetectEngineInspectModbusTest06 - Access function", DetectEngineInspectModbusTest06, 1); - UtRegisterTest("DetectEngineInspectModbusTest07 - Read access at an address", DetectEngineInspectModbusTest07, 1); - UtRegisterTest("DetectEngineInspectModbusTest08 - Read access at a range of address", DetectEngineInspectModbusTest08, 1); - UtRegisterTest("DetectEngineInspectModbusTest09 - Write access at an address a range of value", DetectEngineInspectModbusTest09, 1); -#endif /* UNITTESTS */ - return; -} diff --git a/framework/src/suricata/src/detect-engine-modbus.h b/framework/src/suricata/src/detect-engine-modbus.h deleted file mode 100644 index e140f975..00000000 --- a/framework/src/suricata/src/detect-engine-modbus.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2014 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** \file - * - * \author David DIALLO - */ - -#ifndef __DETECT_ENGINE_MODBUS_H__ -#define __DETECT_ENGINE_MODBUS_H__ - -int DetectEngineInspectModbus(ThreadVars *, DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *, Signature *, - Flow *, uint8_t, void *, void *, uint64_t); - -void DetectEngineInspectModbusRegisterTests(void); -#endif /* __DETECT_ENGINE_MODBUS_H__ */ diff --git a/framework/src/suricata/src/detect-engine-mpm.c b/framework/src/suricata/src/detect-engine-mpm.c deleted file mode 100644 index 7fd532e5..00000000 --- a/framework/src/suricata/src/detect-engine-mpm.c +++ /dev/null @@ -1,2990 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * Multi pattern matcher - */ - -#include "suricata.h" -#include "suricata-common.h" - -#include "app-layer-protos.h" - -#include "decode.h" -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-siggroup.h" -#include "detect-engine-mpm.h" -#include "detect-engine-iponly.h" -#include "detect-parse.h" -#include "util-mpm.h" -#include "util-memcmp.h" -#include "util-memcpy.h" -#include "conf.h" -#include "detect-fast-pattern.h" - -#include "flow.h" -#include "flow-var.h" -#include "detect-flow.h" - -#include "detect-content.h" -#include "detect-uricontent.h" - -#include "stream.h" - -#include "util-enum.h" -#include "util-debug.h" -#include "util-print.h" -#include "util-memcmp.h" -#ifdef __SC_CUDA_SUPPORT__ -#include "util-mpm-ac.h" -#endif -#include "util-validate.h" - -/** \todo make it possible to use multiple pattern matcher algorithms next to - each other. */ - -#define POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS 0x01 -#define POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS 0x02 -#define POPULATE_MPM_AVOID_URI_MPM_PATTERNS 0x04 - -/** - * \brief check if a signature has patterns that are to be inspected - * against a packets payload (as opposed to the stream payload) - * - * \param s signature - * - * \retval 1 true - * \retval 0 false - */ -int SignatureHasPacketContent(Signature *s) -{ - SCEnter(); - - if (s == NULL) { - SCReturnInt(0); - } - - if (!(s->proto.proto[IPPROTO_TCP / 8] & 1 << (IPPROTO_TCP % 8))) { - SCReturnInt(1); - } - - if (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - SCLogDebug("no mpm"); - SCReturnInt(0); - } - - if (!(s->flags & SIG_FLAG_REQUIRE_PACKET)) { - SCReturnInt(0); - } - - SCReturnInt(1); -} - -/** - * \brief check if a signature has patterns that are to be inspected - * against the stream payload (as opposed to the individual packets - * payload(s)) - * - * \param s signature - * - * \retval 1 true - * \retval 0 false - */ -int SignatureHasStreamContent(Signature *s) -{ - SCEnter(); - - if (s == NULL) { - SCReturnInt(0); - } - - if (!(s->proto.proto[IPPROTO_TCP / 8] & 1 << (IPPROTO_TCP % 8))) { - SCReturnInt(0); - } - - if (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - SCLogDebug("no mpm"); - SCReturnInt(0); - } - - if (!(s->flags & SIG_FLAG_REQUIRE_STREAM)) { - SCReturnInt(0); - } - - SCReturnInt(1); -} - - -/** - * \brief Function to return the multi pattern matcher algorithm to be - * used by the engine, based on the mpm-algo setting in yaml - * Use the default mpm if none is specified in the yaml file. - * - * \retval mpm algo value - */ -uint16_t PatternMatchDefaultMatcher(void) -{ - char *mpm_algo; - uint16_t mpm_algo_val = DEFAULT_MPM; - - /* Get the mpm algo defined in config file by the user */ - if ((ConfGet("mpm-algo", &mpm_algo)) == 1) { - uint16_t u; - - if (mpm_algo != NULL) { - for (u = 0; u < MPM_TABLE_SIZE; u++) { - if (mpm_table[u].name == NULL) - continue; - - if (strcmp(mpm_table[u].name, mpm_algo) == 0) { - mpm_algo_val = u; - goto done; - } - } - } - - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid mpm algo supplied " - "in the yaml conf file: \"%s\"", mpm_algo); - exit(EXIT_FAILURE); - } - - done: -#ifdef __tile__ - if (mpm_algo_val == MPM_AC) - mpm_algo_val = MPM_AC_TILE; -#endif - - return mpm_algo_val; -} - -uint32_t PacketPatternSearchWithStreamCtx(DetectEngineThreadCtx *det_ctx, - Packet *p) -{ - SCEnter(); - - uint32_t ret = 0; - - if (p->flowflags & FLOW_PKT_TOSERVER) { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_stream_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_stream_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_stream_ctx_ts, &det_ctx->mtc, &det_ctx->pmq, - p->payload, p->payload_len); - } else { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_stream_ctx_tc == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_stream_ctx_tc->mpm_type]. - Search(det_ctx->sgh->mpm_stream_ctx_tc, &det_ctx->mtc, &det_ctx->pmq, - p->payload, p->payload_len); - } - - SCReturnInt(ret); -} - -/** \brief Pattern match -- searches for only one pattern per signature. - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * - * \retval ret number of matches - */ -uint32_t PacketPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p) -{ - SCEnter(); - - uint32_t ret; - MpmCtx *mpm_ctx = NULL; - - if (p->proto == IPPROTO_TCP) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - mpm_ctx = det_ctx->sgh->mpm_proto_tcp_ctx_ts; - } else { - mpm_ctx = det_ctx->sgh->mpm_proto_tcp_ctx_tc; - } - } else if (p->proto == IPPROTO_UDP) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - mpm_ctx = det_ctx->sgh->mpm_proto_udp_ctx_ts; - } else { - mpm_ctx = det_ctx->sgh->mpm_proto_udp_ctx_tc; - } - } else { - mpm_ctx = det_ctx->sgh->mpm_proto_other_ctx; - } - if (unlikely(mpm_ctx == NULL)) - SCReturnInt(0); - -#ifdef __SC_CUDA_SUPPORT__ - if (p->cuda_pkt_vars.cuda_mpm_enabled && p->pkt_src == PKT_SRC_WIRE) { - ret = SCACCudaPacketResultsProcessing(p, mpm_ctx, &det_ctx->pmq); - } else { - ret = mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, - &det_ctx->mtc, - &det_ctx->pmq, - p->payload, - p->payload_len); - } -#else - ret = mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx, - &det_ctx->mtc, - &det_ctx->pmq, - p->payload, - p->payload_len); -#endif - - SCReturnInt(ret); -} - -/** \brief Uri Pattern match -- searches for one pattern per signature. - * - * \param det_ctx detection engine thread ctx - * \param p packet to inspect - * - * \retval ret number of matches - */ -uint32_t UriPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *uri, uint16_t uri_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(flags & STREAM_TOCLIENT); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_uri_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_uri_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_uri_ctx_ts, - &det_ctx->mtcu, &det_ctx->pmq, uri, uri_len); - - //PrintRawDataFp(stdout, uri, uri_len); - - SCReturnUInt(ret); -} - -/** \brief Http client body pattern match -- searches for one pattern per - * signature. - * - * \param det_ctx Detection engine thread ctx. - * \param body The request body to inspect. - * \param body_len Body length. - * - * \retval ret Number of matches. - */ -uint32_t HttpClientBodyPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *body, uint32_t body_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(flags & STREAM_TOCLIENT); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hcbd_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hcbd_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_hcbd_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, body, body_len); - - SCReturnUInt(ret); -} - -/** \brief Http server body pattern match -- searches for one pattern per - * signature. - * - * \param det_ctx Detection engine thread ctx. - * \param body The request body to inspect. - * \param body_len Body length. - * - * \retval ret Number of matches. - */ -uint32_t HttpServerBodyPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *body, uint32_t body_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(!(flags & STREAM_TOCLIENT)); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hsbd_ctx_tc == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hsbd_ctx_tc->mpm_type]. - Search(det_ctx->sgh->mpm_hsbd_ctx_tc, &det_ctx->mtcu, - &det_ctx->pmq, body, body_len); - - SCReturnUInt(ret); -} - -/** - * \brief Http header match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param headers Headers to inspect. - * \param headers_len Headers length. - * - * \retval ret Number of matches. - */ -uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *headers, uint32_t headers_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - if (flags & STREAM_TOSERVER) { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hhd_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hhd_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_hhd_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, headers, headers_len); - } else { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hhd_ctx_tc == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hhd_ctx_tc->mpm_type]. - Search(det_ctx->sgh->mpm_hhd_ctx_tc, &det_ctx->mtcu, - &det_ctx->pmq, headers, headers_len); - } - - SCReturnUInt(ret); -} - -/** - * \brief Http raw header match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param headers Raw headers to inspect. - * \param headers_len Raw headers length. - * - * \retval ret Number of matches. - */ -uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *raw_headers, uint32_t raw_headers_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - if (flags & STREAM_TOSERVER) { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hrhd_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hrhd_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_hrhd_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, raw_headers, raw_headers_len); - } else { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hrhd_ctx_tc == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hrhd_ctx_tc->mpm_type]. - Search(det_ctx->sgh->mpm_hrhd_ctx_tc, &det_ctx->mtcu, - &det_ctx->pmq, raw_headers, raw_headers_len); - } - - SCReturnUInt(ret); -} - -/** - * \brief Http method match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param method Method to inspect. - * \param method_len Method length. - * - * \retval ret Number of matches. - */ -uint32_t HttpMethodPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *raw_method, uint32_t raw_method_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(flags & STREAM_TOCLIENT); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hmd_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hmd_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_hmd_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, raw_method, raw_method_len); - - SCReturnUInt(ret); -} - -/** - * \brief Http cookie match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param cookie Cookie to inspect. - * \param cookie_len Cookie length. - * - * \retval ret Number of matches. - */ -uint32_t HttpCookiePatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *cookie, uint32_t cookie_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - if (flags & STREAM_TOSERVER) { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hcd_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hcd_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_hcd_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, cookie, cookie_len); - } else { - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hcd_ctx_tc == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hcd_ctx_tc->mpm_type]. - Search(det_ctx->sgh->mpm_hcd_ctx_tc, &det_ctx->mtcu, - &det_ctx->pmq, cookie, cookie_len); - } - - SCReturnUInt(ret); -} - -/** - * \brief Http raw uri match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param uri Raw uri to inspect. - * \param uri_len Raw uri length. - * - * \retval ret Number of matches. - */ -uint32_t HttpRawUriPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *uri, uint32_t uri_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(flags & STREAM_TOCLIENT); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hrud_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hrud_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_hrud_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, uri, uri_len); - - SCReturnUInt(ret); -} - -/** - * \brief Http stat msg match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param stat_msg Stat msg to inspect. - * \param stat_msg_len Stat msg length. - * - * \retval ret Number of matches. - */ -uint32_t HttpStatMsgPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *stat_msg, uint32_t stat_msg_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(!(flags & STREAM_TOCLIENT)); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hsmd_ctx_tc == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hsmd_ctx_tc->mpm_type]. - Search(det_ctx->sgh->mpm_hsmd_ctx_tc, &det_ctx->mtcu, - &det_ctx->pmq, stat_msg, stat_msg_len); - - SCReturnUInt(ret); -} - -/** - * \brief Http stat code match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param stat_code Stat code to inspect. - * \param stat_code_len Stat code length. - * - * \retval ret Number of matches. - */ -uint32_t HttpStatCodePatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *stat_code, uint32_t stat_code_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(!(flags & STREAM_TOCLIENT)); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hscd_ctx_tc == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hscd_ctx_tc->mpm_type]. - Search(det_ctx->sgh->mpm_hscd_ctx_tc, &det_ctx->mtcu, - &det_ctx->pmq, stat_code, stat_code_len); - - SCReturnUInt(ret); -} - -/** - * \brief Http user agent match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param cookie User-Agent to inspect. - * \param cookie_len User-Agent buffer length. - * - * \retval ret Number of matches. - */ -uint32_t HttpUAPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *ua, uint32_t ua_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(flags & STREAM_TOCLIENT); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_huad_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_huad_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_huad_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, ua, ua_len); - - SCReturnUInt(ret); -} - -/** - * \brief Http host header match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param hh Host header to inspect. - * \param hh_len Host header buffer length. - * \param flags Flags - * - * \retval ret Number of matches. - */ -uint32_t HttpHHPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *hh, uint32_t hh_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(flags & STREAM_TOCLIENT); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hhhd_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hhhd_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_hhhd_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, hh, hh_len); - - SCReturnUInt(ret); -} - -/** - * \brief Http raw host header match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param hrh Raw hostname to inspect. - * \param hrh_len Raw hostname buffer length. - * \param flags Flags - * - * \retval ret Number of matches. - */ -uint32_t HttpHRHPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *hrh, uint32_t hrh_len, uint8_t flags) -{ - SCEnter(); - - uint32_t ret; - - DEBUG_VALIDATE_BUG_ON(flags & STREAM_TOCLIENT); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_hrhhd_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_hrhhd_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_hrhhd_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, hrh, hrh_len); - - SCReturnUInt(ret); -} - -/** - * \brief DNS query match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param hrh Buffer to inspect. - * \param hrh_len buffer length. - * \param flags Flags - * - * \retval ret Number of matches. - */ -uint32_t DnsQueryPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *buffer, uint32_t buffer_len, - uint8_t flags) -{ - SCEnter(); - - uint32_t ret = 0; - - DEBUG_VALIDATE_BUG_ON(flags & STREAM_TOCLIENT); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_dnsquery_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_dnsquery_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_dnsquery_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, buffer, buffer_len); - - SCReturnUInt(ret); -} - -/** \brief Pattern match -- searches for only one pattern per signature. - * - * \param det_ctx detection engine thread ctx - * \param p packet - * \param smsg stream msg (reassembled stream data) - * \param flags stream flags - * - * \retval ret number of matches - */ -uint32_t StreamPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p, - StreamMsg *smsg, uint8_t flags) -{ - SCEnter(); - - uint32_t ret = 0; - uint8_t cnt = 0; - - //PrintRawDataFp(stdout, smsg->data.data, smsg->data.data_len); - - uint32_t r; - if (flags & STREAM_TOSERVER) { - for ( ; smsg != NULL; smsg = smsg->next) { - r = mpm_table[det_ctx->sgh->mpm_stream_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_stream_ctx_ts, &det_ctx->mtcs, - &det_ctx->smsg_pmq[cnt], smsg->data, smsg->data_len); - if (r > 0) { - ret += r; - - SCLogDebug("smsg match stored in det_ctx->smsg_pmq[%u]", cnt); - - /* merge results with overall pmq */ - PmqMerge(&det_ctx->smsg_pmq[cnt], &det_ctx->pmq); - } - - cnt++; - } - } else { - for ( ; smsg != NULL; smsg = smsg->next) { - r = mpm_table[det_ctx->sgh->mpm_stream_ctx_tc->mpm_type]. - Search(det_ctx->sgh->mpm_stream_ctx_tc, &det_ctx->mtcs, - &det_ctx->smsg_pmq[cnt], smsg->data, smsg->data_len); - if (r > 0) { - ret += r; - - SCLogDebug("smsg match stored in det_ctx->smsg_pmq[%u]", cnt); - - /* merge results with overall pmq */ - PmqMerge(&det_ctx->smsg_pmq[cnt], &det_ctx->pmq); - } - - cnt++; - } - } - - SCReturnInt(ret); -} - -/** - * \brief SMTP Filedata match -- searches for one pattern per signature. - * - * \param det_ctx Detection engine thread ctx. - * \param buffer Buffer to inspect. - * \param buffer_len buffer length. - * \param flags Flags - * - * \retval ret Number of matches. - */ -uint32_t SMTPFiledataPatternSearch(DetectEngineThreadCtx *det_ctx, - uint8_t *buffer, uint32_t buffer_len, - uint8_t flags) -{ - SCEnter(); - - uint32_t ret = 0; - - DEBUG_VALIDATE_BUG_ON(flags & STREAM_TOCLIENT); - DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_smtp_filedata_ctx_ts == NULL); - - ret = mpm_table[det_ctx->sgh->mpm_smtp_filedata_ctx_ts->mpm_type]. - Search(det_ctx->sgh->mpm_smtp_filedata_ctx_ts, &det_ctx->mtcu, - &det_ctx->pmq, buffer, buffer_len); - - SCReturnUInt(ret); -} - -/** \brief cleans up the mpm instance after a match */ -void PacketPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx) -{ - PmqReset(&det_ctx->pmq); - - if (det_ctx->sgh == NULL) - return; - - /* content */ - if (det_ctx->sgh->mpm_proto_tcp_ctx_ts != NULL && - mpm_table[det_ctx->sgh->mpm_proto_tcp_ctx_ts->mpm_type].Cleanup != NULL) { - mpm_table[det_ctx->sgh->mpm_proto_tcp_ctx_ts->mpm_type].Cleanup(&det_ctx->mtc); - } - if (det_ctx->sgh->mpm_proto_tcp_ctx_tc != NULL && - mpm_table[det_ctx->sgh->mpm_proto_tcp_ctx_tc->mpm_type].Cleanup != NULL) { - mpm_table[det_ctx->sgh->mpm_proto_tcp_ctx_tc->mpm_type].Cleanup(&det_ctx->mtc); - } - - if (det_ctx->sgh->mpm_proto_udp_ctx_ts != NULL && - mpm_table[det_ctx->sgh->mpm_proto_udp_ctx_ts->mpm_type].Cleanup != NULL) { - mpm_table[det_ctx->sgh->mpm_proto_udp_ctx_ts->mpm_type].Cleanup(&det_ctx->mtc); - } - if (det_ctx->sgh->mpm_proto_udp_ctx_tc != NULL && - mpm_table[det_ctx->sgh->mpm_proto_udp_ctx_tc->mpm_type].Cleanup != NULL) { - mpm_table[det_ctx->sgh->mpm_proto_udp_ctx_tc->mpm_type].Cleanup(&det_ctx->mtc); - } - - if (det_ctx->sgh->mpm_proto_other_ctx != NULL && - mpm_table[det_ctx->sgh->mpm_proto_other_ctx->mpm_type].Cleanup != NULL) { - mpm_table[det_ctx->sgh->mpm_proto_other_ctx->mpm_type].Cleanup(&det_ctx->mtc); - } - - /* uricontent */ - if (det_ctx->sgh->mpm_uri_ctx_ts != NULL && mpm_table[det_ctx->sgh->mpm_uri_ctx_ts->mpm_type].Cleanup != NULL) { - mpm_table[det_ctx->sgh->mpm_uri_ctx_ts->mpm_type].Cleanup(&det_ctx->mtcu); - } - - /* stream content */ - if (det_ctx->sgh->mpm_stream_ctx_ts != NULL && mpm_table[det_ctx->sgh->mpm_stream_ctx_ts->mpm_type].Cleanup != NULL) { - mpm_table[det_ctx->sgh->mpm_stream_ctx_ts->mpm_type].Cleanup(&det_ctx->mtcs); - } - if (det_ctx->sgh->mpm_stream_ctx_tc != NULL && mpm_table[det_ctx->sgh->mpm_stream_ctx_tc->mpm_type].Cleanup != NULL) { - mpm_table[det_ctx->sgh->mpm_stream_ctx_tc->mpm_type].Cleanup(&det_ctx->mtcs); - } - - return; -} - -void StreamPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx, StreamMsg *smsg) -{ - uint8_t cnt = 0; - - while (smsg != NULL) { - PmqReset(&det_ctx->smsg_pmq[cnt]); - - smsg = smsg->next; - cnt++; - } -} - -void PatternMatchDestroy(MpmCtx *mpm_ctx, uint16_t mpm_matcher) -{ - SCLogDebug("mpm_ctx %p, mpm_matcher %"PRIu16"", mpm_ctx, mpm_matcher); - mpm_table[mpm_matcher].DestroyCtx(mpm_ctx); -} - -void PatternMatchPrepare(MpmCtx *mpm_ctx, uint16_t mpm_matcher) -{ - SCLogDebug("mpm_ctx %p, mpm_matcher %"PRIu16"", mpm_ctx, mpm_matcher); - MpmInitCtx(mpm_ctx, mpm_matcher); -} - -void PatternMatchThreadPrint(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher) -{ - SCLogDebug("mpm_thread_ctx %p, mpm_matcher %"PRIu16" defunct", mpm_thread_ctx, mpm_matcher); - //mpm_table[mpm_matcher].PrintThreadCtx(mpm_thread_ctx); -} -void PatternMatchThreadDestroy(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher) -{ - SCLogDebug("mpm_thread_ctx %p, mpm_matcher %"PRIu16"", mpm_thread_ctx, mpm_matcher); - if (mpm_table[mpm_matcher].DestroyThreadCtx != NULL) - mpm_table[mpm_matcher].DestroyThreadCtx(NULL, mpm_thread_ctx); -} -void PatternMatchThreadPrepare(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher, uint32_t max_id) -{ - SCLogDebug("mpm_thread_ctx %p, type %"PRIu16", max_id %"PRIu32"", mpm_thread_ctx, mpm_matcher, max_id); - MpmInitThreadCtx(mpm_thread_ctx, mpm_matcher, max_id); -} - - -/* free the pattern matcher part of a SigGroupHead */ -void PatternMatchDestroyGroup(SigGroupHead *sh) -{ - /* content */ - if (!(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) { - if (sh->mpm_proto_tcp_ctx_ts != NULL && - !sh->mpm_proto_tcp_ctx_ts->global) - { - SCLogDebug("destroying mpm_ctx %p (sh %p)", - sh->mpm_proto_tcp_ctx_ts, sh); - mpm_table[sh->mpm_proto_tcp_ctx_ts->mpm_type]. - DestroyCtx(sh->mpm_proto_tcp_ctx_ts); - SCFree(sh->mpm_proto_tcp_ctx_ts); - } - /* ready for reuse */ - sh->mpm_proto_tcp_ctx_ts = NULL; - - if (sh->mpm_proto_tcp_ctx_tc != NULL && - !sh->mpm_proto_tcp_ctx_tc->global) - { - SCLogDebug("destroying mpm_ctx %p (sh %p)", - sh->mpm_proto_tcp_ctx_tc, sh); - mpm_table[sh->mpm_proto_tcp_ctx_tc->mpm_type]. - DestroyCtx(sh->mpm_proto_tcp_ctx_tc); - SCFree(sh->mpm_proto_tcp_ctx_tc); - } - /* ready for reuse */ - sh->mpm_proto_tcp_ctx_tc = NULL; - - if (sh->mpm_proto_udp_ctx_ts != NULL && - !sh->mpm_proto_udp_ctx_ts->global) - { - SCLogDebug("destroying mpm_ctx %p (sh %p)", - sh->mpm_proto_udp_ctx_ts, sh); - mpm_table[sh->mpm_proto_udp_ctx_ts->mpm_type]. - DestroyCtx(sh->mpm_proto_udp_ctx_ts); - SCFree(sh->mpm_proto_udp_ctx_ts); - } - /* ready for reuse */ - sh->mpm_proto_udp_ctx_ts = NULL; - - if (sh->mpm_proto_udp_ctx_tc != NULL && - !sh->mpm_proto_udp_ctx_tc->global) - { - SCLogDebug("destroying mpm_ctx %p (sh %p)", - sh->mpm_proto_udp_ctx_tc, sh); - mpm_table[sh->mpm_proto_udp_ctx_tc->mpm_type]. - DestroyCtx(sh->mpm_proto_udp_ctx_tc); - SCFree(sh->mpm_proto_udp_ctx_tc); - } - /* ready for reuse */ - sh->mpm_proto_udp_ctx_tc = NULL; - - if (sh->mpm_proto_other_ctx != NULL && - !sh->mpm_proto_other_ctx->global) - { - SCLogDebug("destroying mpm_ctx %p (sh %p)", - sh->mpm_proto_other_ctx, sh); - mpm_table[sh->mpm_proto_other_ctx->mpm_type]. - DestroyCtx(sh->mpm_proto_other_ctx); - SCFree(sh->mpm_proto_other_ctx); - } - /* ready for reuse */ - sh->mpm_proto_other_ctx = NULL; - } - - /* uricontent */ - if ((sh->mpm_uri_ctx_ts != NULL) && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) { - if (sh->mpm_uri_ctx_ts != NULL) { - if (!sh->mpm_uri_ctx_ts->global) { - SCLogDebug("destroying mpm_uri_ctx %p (sh %p)", sh->mpm_uri_ctx_ts, sh); - mpm_table[sh->mpm_uri_ctx_ts->mpm_type].DestroyCtx(sh->mpm_uri_ctx_ts); - SCFree(sh->mpm_uri_ctx_ts); - } - /* ready for reuse */ - sh->mpm_uri_ctx_ts = NULL; - } - } - - /* stream content */ - if ((sh->mpm_stream_ctx_ts != NULL || sh->mpm_stream_ctx_tc != NULL) && - !(sh->flags & SIG_GROUP_HEAD_MPM_STREAM_COPY)) { - if (sh->mpm_stream_ctx_ts != NULL) { - if (!sh->mpm_stream_ctx_ts->global) { - SCLogDebug("destroying mpm_stream_ctx %p (sh %p)", sh->mpm_stream_ctx_ts, sh); - mpm_table[sh->mpm_stream_ctx_ts->mpm_type].DestroyCtx(sh->mpm_stream_ctx_ts); - SCFree(sh->mpm_stream_ctx_ts); - } - /* ready for reuse */ - sh->mpm_stream_ctx_ts = NULL; - } - if (sh->mpm_stream_ctx_tc != NULL) { - if (!sh->mpm_stream_ctx_tc->global) { - SCLogDebug("destroying mpm_stream_ctx %p (sh %p)", sh->mpm_stream_ctx_tc, sh); - mpm_table[sh->mpm_stream_ctx_tc->mpm_type].DestroyCtx(sh->mpm_stream_ctx_tc); - SCFree(sh->mpm_stream_ctx_tc); - } - /* ready for reuse */ - sh->mpm_stream_ctx_tc = NULL; - } - } - - if (sh->mpm_hcbd_ctx_ts != NULL) { - if (sh->mpm_hcbd_ctx_ts != NULL) { - if (!sh->mpm_hcbd_ctx_ts->global) { - mpm_table[sh->mpm_hcbd_ctx_ts->mpm_type].DestroyCtx(sh->mpm_hcbd_ctx_ts); - SCFree(sh->mpm_hcbd_ctx_ts); - } - sh->mpm_hcbd_ctx_ts = NULL; - } - } - - if (sh->mpm_hsbd_ctx_tc != NULL) { - if (sh->mpm_hsbd_ctx_tc != NULL) { - if (!sh->mpm_hsbd_ctx_tc->global) { - mpm_table[sh->mpm_hsbd_ctx_tc->mpm_type].DestroyCtx(sh->mpm_hsbd_ctx_tc); - SCFree(sh->mpm_hsbd_ctx_tc); - } - sh->mpm_hsbd_ctx_tc = NULL; - } - } - - if (sh->mpm_smtp_filedata_ctx_ts != NULL) { - if (sh->mpm_smtp_filedata_ctx_ts != NULL) { - if (!sh->mpm_smtp_filedata_ctx_ts->global) { - mpm_table[sh->mpm_smtp_filedata_ctx_ts->mpm_type].DestroyCtx(sh->mpm_smtp_filedata_ctx_ts); - SCFree(sh->mpm_smtp_filedata_ctx_ts); - } - sh->mpm_smtp_filedata_ctx_ts = NULL; - } - } - - if (sh->mpm_hhd_ctx_ts != NULL || sh->mpm_hhd_ctx_tc != NULL) { - if (sh->mpm_hhd_ctx_ts != NULL) { - if (!sh->mpm_hhd_ctx_ts->global) { - mpm_table[sh->mpm_hhd_ctx_ts->mpm_type].DestroyCtx(sh->mpm_hhd_ctx_ts); - SCFree(sh->mpm_hhd_ctx_ts); - } - sh->mpm_hhd_ctx_ts = NULL; - } - if (sh->mpm_hhd_ctx_tc != NULL) { - if (!sh->mpm_hhd_ctx_tc->global) { - mpm_table[sh->mpm_hhd_ctx_tc->mpm_type].DestroyCtx(sh->mpm_hhd_ctx_tc); - SCFree(sh->mpm_hhd_ctx_tc); - } - sh->mpm_hhd_ctx_tc = NULL; - } - } - - if (sh->mpm_hrhd_ctx_ts != NULL || sh->mpm_hrhd_ctx_tc != NULL) { - if (sh->mpm_hrhd_ctx_ts != NULL) { - if (!sh->mpm_hrhd_ctx_ts->global) { - mpm_table[sh->mpm_hrhd_ctx_ts->mpm_type].DestroyCtx(sh->mpm_hrhd_ctx_ts); - SCFree(sh->mpm_hrhd_ctx_ts); - } - sh->mpm_hrhd_ctx_ts = NULL; - } - if (sh->mpm_hrhd_ctx_tc != NULL) { - if (!sh->mpm_hrhd_ctx_tc->global) { - mpm_table[sh->mpm_hrhd_ctx_tc->mpm_type].DestroyCtx(sh->mpm_hrhd_ctx_tc); - SCFree(sh->mpm_hrhd_ctx_tc); - } - sh->mpm_hrhd_ctx_tc = NULL; - } - } - - if (sh->mpm_hmd_ctx_ts != NULL) { - if (sh->mpm_hmd_ctx_ts != NULL) { - if (!sh->mpm_hmd_ctx_ts->global) { - mpm_table[sh->mpm_hmd_ctx_ts->mpm_type].DestroyCtx(sh->mpm_hmd_ctx_ts); - SCFree(sh->mpm_hmd_ctx_ts); - } - sh->mpm_hmd_ctx_ts = NULL; - } - } - - if (sh->mpm_hcd_ctx_ts != NULL || sh->mpm_hcd_ctx_tc != NULL) { - if (sh->mpm_hcd_ctx_ts != NULL) { - if (!sh->mpm_hcd_ctx_ts->global) { - mpm_table[sh->mpm_hcd_ctx_ts->mpm_type].DestroyCtx(sh->mpm_hcd_ctx_ts); - SCFree(sh->mpm_hcd_ctx_ts); - } - sh->mpm_hcd_ctx_ts = NULL; - } - if (sh->mpm_hcd_ctx_tc != NULL) { - if (!sh->mpm_hcd_ctx_tc->global) { - mpm_table[sh->mpm_hcd_ctx_tc->mpm_type].DestroyCtx(sh->mpm_hcd_ctx_tc); - SCFree(sh->mpm_hcd_ctx_tc); - } - sh->mpm_hcd_ctx_tc = NULL; - } - } - - if (sh->mpm_hrud_ctx_ts != NULL) { - if (sh->mpm_hrud_ctx_ts != NULL) { - if (!sh->mpm_hrud_ctx_ts->global) { - mpm_table[sh->mpm_hrud_ctx_ts->mpm_type].DestroyCtx(sh->mpm_hrud_ctx_ts); - SCFree(sh->mpm_hrud_ctx_ts); - } - sh->mpm_hrud_ctx_ts = NULL; - } - } - - if (sh->mpm_hsmd_ctx_tc != NULL) { - if (sh->mpm_hsmd_ctx_tc != NULL) { - if (!sh->mpm_hsmd_ctx_tc->global) { - mpm_table[sh->mpm_hsmd_ctx_tc->mpm_type].DestroyCtx(sh->mpm_hsmd_ctx_tc); - SCFree(sh->mpm_hsmd_ctx_tc); - } - sh->mpm_hsmd_ctx_tc = NULL; - } - } - - if (sh->mpm_hscd_ctx_tc != NULL) { - if (sh->mpm_hscd_ctx_tc != NULL) { - if (!sh->mpm_hscd_ctx_tc->global) { - mpm_table[sh->mpm_hscd_ctx_tc->mpm_type].DestroyCtx(sh->mpm_hscd_ctx_tc); - SCFree(sh->mpm_hscd_ctx_tc); - } - sh->mpm_hscd_ctx_tc = NULL; - } - } - - if (sh->mpm_huad_ctx_ts != NULL) { - if (sh->mpm_huad_ctx_ts != NULL) { - if (!sh->mpm_huad_ctx_ts->global) { - mpm_table[sh->mpm_huad_ctx_ts->mpm_type].DestroyCtx(sh->mpm_huad_ctx_ts); - SCFree(sh->mpm_huad_ctx_ts); - } - sh->mpm_huad_ctx_ts = NULL; - } - } - - /* dns query */ - if (sh->mpm_dnsquery_ctx_ts != NULL) { - if (!sh->mpm_dnsquery_ctx_ts->global) { - mpm_table[sh->mpm_dnsquery_ctx_ts->mpm_type].DestroyCtx(sh->mpm_dnsquery_ctx_ts); - SCFree(sh->mpm_dnsquery_ctx_ts); - } - sh->mpm_dnsquery_ctx_ts = NULL; - } - - return; -} - -/** \brief Hash for looking up contents that are most used, - * always used, etc. */ -typedef struct ContentHash_ { - DetectContentData *ptr; - uint16_t cnt; - uint8_t use; /* use no matter what */ -} ContentHash; - -typedef struct UricontentHash_ { - DetectContentData *ptr; - uint16_t cnt; - uint8_t use; /* use no matter what */ -} UricontentHash; - -uint32_t ContentHashFunc(HashTable *ht, void *data, uint16_t datalen) -{ - ContentHash *ch = (ContentHash *)data; - DetectContentData *co = ch->ptr; - uint32_t hash = 0; - int i; - for (i = 0; i < co->content_len; i++) { - hash += co->content[i]; - } - hash = hash % ht->array_size; - SCLogDebug("hash %" PRIu32 "", hash); - return hash; -} - -uint32_t UricontentHashFunc(HashTable *ht, void *data, uint16_t datalen) -{ - UricontentHash *ch = (UricontentHash *)data; - DetectContentData *ud = ch->ptr; - uint32_t hash = 0; - int i; - for (i = 0; i < ud->content_len; i++) { - hash += ud->content[i]; - } - hash = hash % ht->array_size; - SCLogDebug("hash %" PRIu32 "", hash); - return hash; -} - -char ContentHashCompareFunc(void *data1, uint16_t len1, void *data2, uint16_t len2) -{ - ContentHash *ch1 = (ContentHash *)data1; - ContentHash *ch2 = (ContentHash *)data2; - DetectContentData *co1 = ch1->ptr; - DetectContentData *co2 = ch2->ptr; - - if (co1->content_len == co2->content_len && - ((co1->flags & DETECT_CONTENT_NOCASE) == (co2->flags & DETECT_CONTENT_NOCASE)) && - SCMemcmp(co1->content, co2->content, co1->content_len) == 0) - return 1; - - return 0; -} - -char UricontentHashCompareFunc(void *data1, uint16_t len1, void *data2, uint16_t len2) -{ - UricontentHash *ch1 = (UricontentHash *)data1; - UricontentHash *ch2 = (UricontentHash *)data2; - DetectContentData *ud1 = ch1->ptr; - DetectContentData *ud2 = ch2->ptr; - - if (ud1->content_len == ud2->content_len && - ((ud1->flags & DETECT_CONTENT_NOCASE) == (ud2->flags & DETECT_CONTENT_NOCASE)) && - SCMemcmp(ud1->content, ud2->content, ud1->content_len) == 0) - return 1; - - return 0; -} - -ContentHash *ContentHashAlloc(DetectContentData *ptr) -{ - ContentHash *ch = SCMalloc(sizeof(ContentHash)); - if (unlikely(ch == NULL)) - return NULL; - - ch->ptr = ptr; - ch->cnt = 1; - ch->use = 0; - - return ch; -} - -UricontentHash *UricontentHashAlloc(DetectContentData *ptr) -{ - UricontentHash *ch = SCMalloc(sizeof(UricontentHash)); - if (unlikely(ch == NULL)) - return NULL; - - ch->ptr = ptr; - ch->cnt = 1; - ch->use = 0; - - return ch; -} - -void ContentHashFree(void *ch) -{ - SCFree(ch); -} - -void UricontentHashFree(void *ch) -{ - SCFree(ch); -} - -/** \brief Predict a strength value for patterns - * - * Patterns with high character diversity score higher. - * Alpha chars score not so high - * Other printable + a few common codes a little higher - * Everything else highest. - * Longer patterns score better than short patters. - * - * \param pat pattern - * \param patlen length of the patternn - * - * \retval s pattern score - */ -uint32_t PatternStrength(uint8_t *pat, uint16_t patlen) -{ - uint8_t a[256]; - memset(&a, 0 ,sizeof(a)); - - uint32_t s = 0; - uint16_t u = 0; - for (u = 0; u < patlen; u++) { - if (a[pat[u]] == 0) { - if (isalpha(pat[u])) - s += 3; - else if (isprint(pat[u]) || pat[u] == 0x00 || pat[u] == 0x01 || pat[u] == 0xFF) - s += 4; - else - s += 6; - - a[pat[u]] = 1; - } else { - s++; - } - } - - return s; -} - -static void PopulateMpmHelperAddPatternToPktCtx(MpmCtx *mpm_ctx, - DetectContentData *cd, - Signature *s, uint8_t flags, - int chop) -{ - if (cd->flags & DETECT_CONTENT_NOCASE) { - if (chop) { - MpmAddPatternCI(mpm_ctx, - cd->content + cd->fp_chop_offset, cd->fp_chop_len, - 0, 0, - cd->id, s->num, flags); - } else { - MpmAddPatternCI(mpm_ctx, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - } else { - if (chop) { - MpmAddPatternCS(mpm_ctx, - cd->content + cd->fp_chop_offset, cd->fp_chop_len, - 0, 0, - cd->id, s->num, flags); - } else { - MpmAddPatternCS(mpm_ctx, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - } - - return; -} - -static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx, - SigGroupHead *sgh, Signature *s, - SigMatch *mpm_sm) -{ - s->mpm_sm = mpm_sm; - - if (mpm_sm == NULL) { - SCLogDebug("%"PRIu32" no mpm pattern selected", s->id); - return; - } - - int sm_list = SigMatchListSMBelongsTo(s, mpm_sm); - if (sm_list == -1) - BUG_ON(SigMatchListSMBelongsTo(s, mpm_sm) == -1); - - uint8_t flags = 0; - - DetectContentData *cd = NULL; - - switch (sm_list) { - case DETECT_SM_LIST_PMATCH: - { - cd = (DetectContentData *)mpm_sm->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) { - if (DETECT_CONTENT_IS_SINGLE(cd) && - !(cd->flags & DETECT_CONTENT_NEGATED) && - !(cd->flags & DETECT_CONTENT_REPLACE) && - cd->content_len == cd->fp_chop_len) { - cd->flags |= DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED; - } - - /* add the content to the "packet" mpm */ - if (SignatureHasPacketContent(s)) { - if (s->proto.proto[6 / 8] & 1 << (6 % 8)) { - if (s->flags & SIG_FLAG_TOSERVER) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_ts, - cd, s, flags, 1); - } - if (s->flags & SIG_FLAG_TOCLIENT) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_tc, - cd, s, flags, 1); - } - } - if (s->proto.proto[17 / 8] & 1 << (17 % 8)) { - if (s->flags & SIG_FLAG_TOSERVER) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_ts, - cd, s, flags, 1); - } - if (s->flags & SIG_FLAG_TOCLIENT) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_tc, - cd, s, flags, 1); - } - } - int i; - for (i = 0; i < 256; i++) { - if (i == 6 || i == 17) - continue; - if (s->proto.proto[i / 8] & (1 << (i % 8))) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_other_ctx, - cd, s, flags, 1); - break; - } - } - /* tell matcher we are inspecting packet */ - s->flags |= SIG_FLAG_MPM_PACKET; - s->mpm_pattern_id_div_8 = cd->id / 8; - s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8); - if (cd->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id); - s->flags |= SIG_FLAG_MPM_PACKET_NEG; - } - } - if (SignatureHasStreamContent(s)) { - if (cd->flags & DETECT_CONTENT_NOCASE) { - if (s->flags & SIG_FLAG_TOSERVER) { - MpmAddPatternCI(sgh->mpm_stream_ctx_ts, - cd->content + cd->fp_chop_offset, cd->fp_chop_len, - 0, 0, - cd->id, s->num, flags); - } - if (s->flags & SIG_FLAG_TOCLIENT) { - MpmAddPatternCI(sgh->mpm_stream_ctx_tc, - cd->content + cd->fp_chop_offset, cd->fp_chop_len, - 0, 0, - cd->id, s->num, flags); - } - } else { - if (s->flags & SIG_FLAG_TOSERVER) { - MpmAddPatternCS(sgh->mpm_stream_ctx_ts, - cd->content + cd->fp_chop_offset, cd->fp_chop_len, - 0, 0, - cd->id, s->num, flags); - } - if (s->flags & SIG_FLAG_TOCLIENT) { - MpmAddPatternCS(sgh->mpm_stream_ctx_tc, - cd->content + cd->fp_chop_offset, cd->fp_chop_len, - 0, 0, - cd->id, s->num, flags); - } - } - /* tell matcher we are inspecting stream */ - s->flags |= SIG_FLAG_MPM_STREAM; - s->mpm_pattern_id_div_8 = cd->id / 8; - s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8); - if (cd->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id); - s->flags |= SIG_FLAG_MPM_STREAM_NEG; - } - } - } else { - if (DETECT_CONTENT_IS_SINGLE(cd) && - !(cd->flags & DETECT_CONTENT_NEGATED) && - !(cd->flags & DETECT_CONTENT_REPLACE)) { - cd->flags |= DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED; - } - - if (SignatureHasPacketContent(s)) { - /* add the content to the "packet" mpm */ - if (s->proto.proto[6 / 8] & 1 << (6 % 8)) { - if (s->flags & SIG_FLAG_TOSERVER) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_ts, - cd, s, flags, 0); - } - if (s->flags & SIG_FLAG_TOCLIENT) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_tc, - cd, s, flags, 0); - } - } - if (s->proto.proto[17 / 8] & 1 << (17 % 8)) { - if (s->flags & SIG_FLAG_TOSERVER) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_ts, - cd, s, flags, 0); - } - if (s->flags & SIG_FLAG_TOCLIENT) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_tc, - cd, s, flags, 0); - } - } - int i; - for (i = 0; i < 256; i++) { - if (i == 6 || i == 17) - continue; - if (s->proto.proto[i / 8] & (1 << (i % 8))) { - PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_other_ctx, - cd, s, flags, 0); - break; - } - } - /* tell matcher we are inspecting packet */ - s->flags |= SIG_FLAG_MPM_PACKET; - s->mpm_pattern_id_div_8 = cd->id / 8; - s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8); - if (cd->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id); - s->flags |= SIG_FLAG_MPM_PACKET_NEG; - } - } - if (SignatureHasStreamContent(s)) { - /* add the content to the "packet" mpm */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - if (s->flags & SIG_FLAG_TOSERVER) { - MpmAddPatternCI(sgh->mpm_stream_ctx_ts, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - if (s->flags & SIG_FLAG_TOCLIENT) { - MpmAddPatternCI(sgh->mpm_stream_ctx_tc, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - } else { - if (s->flags & SIG_FLAG_TOSERVER) { - MpmAddPatternCS(sgh->mpm_stream_ctx_ts, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - if (s->flags & SIG_FLAG_TOCLIENT) { - MpmAddPatternCS(sgh->mpm_stream_ctx_tc, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - } - /* tell matcher we are inspecting stream */ - s->flags |= SIG_FLAG_MPM_STREAM; - s->mpm_pattern_id_div_8 = cd->id / 8; - s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8); - if (cd->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id); - s->flags |= SIG_FLAG_MPM_STREAM_NEG; - } - } - } - if (SignatureHasPacketContent(s)) { - sgh->flags |= SIG_GROUP_HEAD_MPM_PACKET; - } - if (SignatureHasStreamContent(s)) { - sgh->flags |= SIG_GROUP_HEAD_MPM_STREAM; - } - - break; - } /* case DETECT_CONTENT */ - - case DETECT_SM_LIST_UMATCH: - case DETECT_SM_LIST_HRUDMATCH: - case DETECT_SM_LIST_HCBDMATCH: - case DETECT_SM_LIST_FILEDATA: - case DETECT_SM_LIST_HHDMATCH: - case DETECT_SM_LIST_HRHDMATCH: - case DETECT_SM_LIST_HMDMATCH: - case DETECT_SM_LIST_HCDMATCH: - case DETECT_SM_LIST_HSMDMATCH: - case DETECT_SM_LIST_HSCDMATCH: - case DETECT_SM_LIST_HUADMATCH: - case DETECT_SM_LIST_HHHDMATCH: - case DETECT_SM_LIST_HRHHDMATCH: - case DETECT_SM_LIST_DNSQUERYNAME_MATCH: - { - MpmCtx *mpm_ctx_ts = NULL; - MpmCtx *mpm_ctx_tc = NULL; - - cd = (DetectContentData *)mpm_sm->ctx; - - if (sm_list == DETECT_SM_LIST_UMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_uri_ctx_ts; - sgh->flags |= SIG_GROUP_HEAD_MPM_URI; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HCBDMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_hcbd_ctx_ts; - sgh->flags |= SIG_GROUP_HEAD_MPM_HCBD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_FILEDATA) { - if (s->flags & SIG_FLAG_TOCLIENT) { - mpm_ctx_tc = sgh->mpm_hsbd_ctx_tc; - sgh->flags |= SIG_GROUP_HEAD_MPM_HSBD; - } - if (s->flags & SIG_FLAG_TOSERVER) { - mpm_ctx_ts = sgh->mpm_smtp_filedata_ctx_ts; - sgh->flags |= SIG_GROUP_HEAD_MPM_FD_SMTP; - } - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HHDMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_hhd_ctx_ts; - if (s->flags & SIG_FLAG_TOCLIENT) - mpm_ctx_tc = sgh->mpm_hhd_ctx_tc; - sgh->flags |= SIG_GROUP_HEAD_MPM_HHD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HRHDMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_hrhd_ctx_ts; - if (s->flags & SIG_FLAG_TOCLIENT) - mpm_ctx_tc = sgh->mpm_hrhd_ctx_tc; - sgh->flags |= SIG_GROUP_HEAD_MPM_HRHD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HMDMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_hmd_ctx_ts; - sgh->flags |= SIG_GROUP_HEAD_MPM_HMD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HCDMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_hcd_ctx_ts; - if (s->flags & SIG_FLAG_TOCLIENT) - mpm_ctx_tc = sgh->mpm_hcd_ctx_tc; - sgh->flags |= SIG_GROUP_HEAD_MPM_HCD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HRUDMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_hrud_ctx_ts; - sgh->flags |= SIG_GROUP_HEAD_MPM_HRUD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HSMDMATCH) { - if (s->flags & SIG_FLAG_TOCLIENT) - mpm_ctx_tc = sgh->mpm_hsmd_ctx_tc; - sgh->flags |= SIG_GROUP_HEAD_MPM_HSMD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HSCDMATCH) { - if (s->flags & SIG_FLAG_TOCLIENT) - mpm_ctx_tc = sgh->mpm_hscd_ctx_tc; - sgh->flags |= SIG_GROUP_HEAD_MPM_HSCD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HUADMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_huad_ctx_ts; - sgh->flags |= SIG_GROUP_HEAD_MPM_HUAD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HHHDMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_hhhd_ctx_ts; - sgh->flags |= SIG_GROUP_HEAD_MPM_HHHD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_HRHHDMATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_hrhhd_ctx_ts; - sgh->flags |= SIG_GROUP_HEAD_MPM_HRHHD; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } else if (sm_list == DETECT_SM_LIST_DNSQUERYNAME_MATCH) { - if (s->flags & SIG_FLAG_TOSERVER) - mpm_ctx_ts = sgh->mpm_dnsquery_ctx_ts; - if (s->flags & SIG_FLAG_TOCLIENT) - mpm_ctx_tc = NULL; - sgh->flags |= SIG_GROUP_HEAD_MPM_DNSQUERY; - s->flags |= SIG_FLAG_MPM_APPLAYER; - if (cd->flags & DETECT_CONTENT_NEGATED) - s->flags |= SIG_FLAG_MPM_APPLAYER_NEG; - } - - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) { - if (DETECT_CONTENT_IS_SINGLE(cd) && - !(cd->flags & DETECT_CONTENT_NEGATED) && - !(cd->flags & DETECT_CONTENT_REPLACE) && - cd->content_len == cd->fp_chop_len) { - cd->flags |= DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED; - } - - /* add the content to the mpm */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - if (mpm_ctx_ts != NULL) { - MpmAddPatternCI(mpm_ctx_ts, - cd->content + cd->fp_chop_offset, cd->fp_chop_len, - 0, 0, - cd->id, s->num, flags); - } - if (mpm_ctx_tc != NULL) { - MpmAddPatternCI(mpm_ctx_tc, - cd->content + cd->fp_chop_offset, cd->fp_chop_len, - 0, 0, - cd->id, s->num, flags); - } - } else { - if (mpm_ctx_ts != NULL) { - MpmAddPatternCS(mpm_ctx_ts, - cd->content + cd->fp_chop_offset, - cd->fp_chop_len, - 0, 0, cd->id, s->num, flags); - } - if (mpm_ctx_tc != NULL) { - MpmAddPatternCS(mpm_ctx_tc, - cd->content + cd->fp_chop_offset, - cd->fp_chop_len, - 0, 0, cd->id, s->num, flags); - } - } - } else { - if (DETECT_CONTENT_IS_SINGLE(cd) && - !(cd->flags & DETECT_CONTENT_NEGATED) && - !(cd->flags & DETECT_CONTENT_REPLACE)) { - cd->flags |= DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED; - } - - /* add the content to the "uri" mpm */ - if (cd->flags & DETECT_CONTENT_NOCASE) { - if (mpm_ctx_ts != NULL) { - MpmAddPatternCI(mpm_ctx_ts, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - if (mpm_ctx_tc != NULL) { - MpmAddPatternCI(mpm_ctx_tc, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - } else { - if (mpm_ctx_ts != NULL) { - MpmAddPatternCS(mpm_ctx_ts, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - if (mpm_ctx_tc != NULL) { - MpmAddPatternCS(mpm_ctx_tc, - cd->content, cd->content_len, - 0, 0, - cd->id, s->num, flags); - } - } - } - /* tell matcher we are inspecting uri */ - s->mpm_pattern_id_div_8 = cd->id / 8; - s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8); - - break; - } - } /* switch (mpm_sm->type) */ - - SCLogDebug("%"PRIu32" adding cd->id %"PRIu32" to the mpm phase " - "(s->num %"PRIu32")", s->id, - ((DetectContentData *)mpm_sm->ctx)->id, s->num); - - return; -} - -SigMatch *RetrieveFPForSig(Signature *s) -{ - SigMatch *mpm_sm = NULL, *sm = NULL; - uint8_t has_non_negated_non_stream_pattern = 0; - - if (s->mpm_sm != NULL) - return s->mpm_sm; - - int list_id; - for (list_id = 0 ; list_id < DETECT_SM_LIST_MAX; list_id++) { - /* we have no keywords that support fp in this Signature sm list */ - if (!FastPatternSupportEnabledForSigMatchList(list_id)) - continue; - - for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) { - /* this keyword isn't registered for fp support */ - if (sm->type != DETECT_CONTENT) - continue; - - DetectContentData *cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN) - return sm; - if (!(cd->flags & DETECT_CONTENT_NEGATED) && - (list_id != DETECT_SM_LIST_PMATCH) && - (list_id != DETECT_SM_LIST_HMDMATCH) && - (list_id != DETECT_SM_LIST_HSMDMATCH) && - (list_id != DETECT_SM_LIST_HSCDMATCH)) { - has_non_negated_non_stream_pattern = 1; - } - } - } - - int max_len = 0; - int max_len_negated = 0; - int max_len_non_negated = 0; - for (list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) { - if (!FastPatternSupportEnabledForSigMatchList(list_id)) - continue; - - if (has_non_negated_non_stream_pattern && - ((list_id == DETECT_SM_LIST_PMATCH) || - (list_id == DETECT_SM_LIST_HMDMATCH) || - (list_id == DETECT_SM_LIST_HSMDMATCH) || - (list_id == DETECT_SM_LIST_HSCDMATCH))) { - continue; - } - - for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_CONTENT) - continue; - - DetectContentData *cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_NEGATED) { - if (max_len_negated < cd->content_len) - max_len_negated = cd->content_len; - } else { - if (max_len_non_negated < cd->content_len) - max_len_non_negated = cd->content_len; - } - } - } - - int skip_negated_content = 0; - if (max_len_non_negated == 0) { - max_len = max_len_negated; - skip_negated_content = 0; - } else { - max_len = max_len_non_negated; - skip_negated_content = 1; - } - - for (list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) { - if (!FastPatternSupportEnabledForSigMatchList(list_id)) - continue; - - if (has_non_negated_non_stream_pattern && - ((list_id == DETECT_SM_LIST_PMATCH) || - (list_id == DETECT_SM_LIST_HMDMATCH) || - (list_id == DETECT_SM_LIST_HSMDMATCH) || - (list_id == DETECT_SM_LIST_HSCDMATCH))) { - continue; - } - - for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_CONTENT) - continue; - - DetectContentData *cd = (DetectContentData *)sm->ctx; - if ((cd->flags & DETECT_CONTENT_NEGATED) && skip_negated_content) - continue; - if (cd->content_len < max_len) - continue; - - if (mpm_sm == NULL) { - mpm_sm = sm; - } else { - DetectContentData *data1 = (DetectContentData *)sm->ctx; - DetectContentData *data2 = (DetectContentData *)mpm_sm->ctx; - uint32_t ls = PatternStrength(data1->content, data1->content_len); - uint32_t ss = PatternStrength(data2->content, data2->content_len); - if (ls > ss) { - mpm_sm = sm; - } else if (ls == ss) { - /* if 2 patterns are of equal strength, we pick the longest */ - if (data1->content_len > data2->content_len) - mpm_sm = sm; - } else { - SCLogDebug("sticking with mpm_sm"); - } - } /* else - if (mpm == NULL) */ - } /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */ - } /* for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) */ - - return mpm_sm; -} - -SigMatch *RetrieveFPForSigV2(Signature *s) -{ - if (s->mpm_sm != NULL) - return s->mpm_sm; - - - SigMatch *mpm_sm = NULL, *sm = NULL; - int nn_sm_list[DETECT_SM_LIST_MAX]; - int n_sm_list[DETECT_SM_LIST_MAX]; - memset(nn_sm_list, 0, sizeof(nn_sm_list)); - memset(n_sm_list, 0, sizeof(n_sm_list)); - int count_nn_sm_list = 0; - int count_n_sm_list = 0; - int list_id; - - for (list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) { - if (!FastPatternSupportEnabledForSigMatchList(list_id)) - continue; - - for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_CONTENT) - continue; - - DetectContentData *cd = (DetectContentData *)sm->ctx; - if ((cd->flags & DETECT_CONTENT_FAST_PATTERN)) - return sm; - if (cd->flags & DETECT_CONTENT_NEGATED) { - n_sm_list[list_id] = 1; - count_n_sm_list++; - } else { - nn_sm_list[list_id] = 1; - count_nn_sm_list++; - } - } /* for */ - } /* for */ - - int *curr_sm_list = NULL; - int skip_negated_content = 1; - if (count_nn_sm_list > 0) { - curr_sm_list = nn_sm_list; - } else if (count_n_sm_list > 0) { - curr_sm_list = n_sm_list; - skip_negated_content = 0; - } else { - return NULL; - } - - int final_sm_list[DETECT_SM_LIST_MAX]; - int count_final_sm_list = 0; - int priority; - - SCFPSupportSMList *tmp = sm_fp_support_smlist_list; - while (tmp != NULL) { - for (priority = tmp->priority; - tmp != NULL && priority == tmp->priority; - tmp = tmp->next) { - - if (curr_sm_list[tmp->list_id] == 0) - continue; - final_sm_list[count_final_sm_list++] = tmp->list_id; - } - if (count_final_sm_list != 0) - break; - } - - BUG_ON(count_final_sm_list == 0); - - int max_len = 0; - int i; - for (i = 0; i < count_final_sm_list; i++) { - for (sm = s->sm_lists[final_sm_list[i]]; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_CONTENT) - continue; - - DetectContentData *cd = (DetectContentData *)sm->ctx; - /* skip_negated_content is only set if there's absolutely no - * non-negated content present in the sig */ - if ((cd->flags & DETECT_CONTENT_NEGATED) && skip_negated_content) - continue; - if (max_len < cd->content_len) - max_len = cd->content_len; - } - } - - for (i = 0; i < count_final_sm_list; i++) { - for (sm = s->sm_lists[final_sm_list[i]]; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_CONTENT) - continue; - - DetectContentData *cd = (DetectContentData *)sm->ctx; - /* skip_negated_content is only set if there's absolutely no - * non-negated content present in the sig */ - if ((cd->flags & DETECT_CONTENT_NEGATED) && skip_negated_content) - continue; - if (cd->content_len != max_len) - continue; - - if (mpm_sm == NULL) { - mpm_sm = sm; - } else { - DetectContentData *data1 = (DetectContentData *)sm->ctx; - DetectContentData *data2 = (DetectContentData *)mpm_sm->ctx; - uint32_t ls = PatternStrength(data1->content, data1->content_len); - uint32_t ss = PatternStrength(data2->content, data2->content_len); - if (ls > ss) { - mpm_sm = sm; - } else if (ls == ss) { - /* if 2 patterns are of equal strength, we pick the longest */ - if (data1->content_len > data2->content_len) - mpm_sm = sm; - } else { - SCLogDebug("sticking with mpm_sm"); - } - } /* else - if */ - } /* for */ - } /* for */ - - return mpm_sm; -} - -/** - * \internal - * \brief Setup the mpm content. - * - * \param de_ctx Pointer to the detect engine context. - * \param sgh Pointer to the signature group head against which we are - * adding patterns to the mpm ctx. - * - * \retval 0 Always. - */ -static int PatternMatchPreparePopulateMpm(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - uint32_t sig = 0; - for (sig = 0; sig < sgh->sig_cnt; sig++) { - Signature *s = sgh->match_array[sig]; - if (s == NULL) - continue; - PopulateMpmAddPatternToMpm(de_ctx, sgh, s, s->mpm_sm); - } /* for (sig = 0; sig < sgh->sig_cnt; sig++) */ - - return 0; -} - -/** \brief Prepare the pattern matcher ctx in a sig group head. - * - * \todo determine if a content match can set the 'single' flag - * \todo do error checking - * \todo rewrite the COPY stuff - */ -int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) -{ - Signature *s = NULL; - uint32_t has_co_packet = 0; /**< our sgh has packet payload inspecting content */ - uint32_t has_co_stream = 0; /**< our sgh has stream inspecting content */ - uint32_t has_co_uri = 0; /**< our sgh has uri inspecting content */ - /* used to indicate if sgh has atleast one sig with http_client_body */ - uint32_t has_co_hcbd = 0; - /* used to indicate if sgh has atleast one sig with http_server_body */ - uint32_t has_co_hsbd = 0; - /* used to indicate if sgh has smtp file_data inspecting content */ - uint32_t has_co_smtp = 0; - /* used to indicate if sgh has atleast one sig with http_header */ - uint32_t has_co_hhd = 0; - /* used to indicate if sgh has atleast one sig with http_raw_header */ - uint32_t has_co_hrhd = 0; - /* used to indicate if sgh has atleast one sig with http_method */ - uint32_t has_co_hmd = 0; - /* used to indicate if sgh has atleast one sig with http_cookie */ - uint32_t has_co_hcd = 0; - /* used to indicate if sgh has atleast one sig with http_raw_uri */ - uint32_t has_co_hrud = 0; - /* used to indicate if sgh has atleast one sig with http_stat_msg */ - uint32_t has_co_hsmd = 0; - /* used to indicate if sgh has atleast one sig with http_stat_code */ - uint32_t has_co_hscd = 0; - /* used to indicate if sgh has atleast one sig with http_user_agent */ - uint32_t has_co_huad = 0; - /* used to indicate if sgh has atleast one sig with http_host */ - uint32_t has_co_hhhd = 0; - /* used to indicate if sgh has atleast one sig with http_raw_host */ - uint32_t has_co_hrhhd = 0; - //uint32_t cnt = 0; - uint32_t sig = 0; - /* sgh has at least one sig with dns_query */ - int has_co_dnsquery = 0; - - /* see if this head has content and/or uricontent */ - for (sig = 0; sig < sh->sig_cnt; sig++) { - s = sh->match_array[sig]; - if (s == NULL) - continue; - - if (SignatureHasPacketContent(s) == 1) { - has_co_packet = 1; - } - if (SignatureHasStreamContent(s) == 1) { - has_co_stream = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) { - has_co_uri = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) { - has_co_hcbd = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_FILEDATA] != NULL) { - if (s->alproto == ALPROTO_SMTP) - has_co_smtp = 1; - else if (s->alproto == ALPROTO_HTTP) - has_co_hsbd = 1; - else if (s->alproto == ALPROTO_UNKNOWN) { - has_co_smtp = 1; - has_co_hsbd = 1; - } - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) { - has_co_hhd = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) { - has_co_hrhd = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) { - has_co_hmd = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) { - has_co_hcd = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) { - has_co_hrud = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) { - has_co_hsmd = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) { - has_co_hscd = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) { - has_co_huad = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HHHDMATCH] != NULL) { - has_co_hhhd = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_HRHHDMATCH] != NULL) { - has_co_hrhhd = 1; - } - - if (s->sm_lists[DETECT_SM_LIST_DNSQUERYNAME_MATCH] != NULL) { - has_co_dnsquery = 1; - } - } - - /* intialize contexes */ - if (has_co_packet) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_proto_tcp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 0); - sh->mpm_proto_tcp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 1); - } else { - sh->mpm_proto_tcp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - sh->mpm_proto_tcp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1); - } - if (sh->mpm_proto_tcp_ctx_ts == NULL || sh->mpm_proto_tcp_ctx_tc == NULL) { - SCLogDebug("sh->mpm_proto_tcp_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - MpmInitCtx(sh->mpm_proto_tcp_ctx_ts, de_ctx->mpm_matcher); - MpmInitCtx(sh->mpm_proto_tcp_ctx_tc, de_ctx->mpm_matcher); - - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_proto_udp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 0); - sh->mpm_proto_udp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 1); - } else { - sh->mpm_proto_udp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - sh->mpm_proto_udp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1); - } - if (sh->mpm_proto_udp_ctx_ts == NULL || sh->mpm_proto_udp_ctx_tc == NULL) { - SCLogDebug("sh->mpm_proto_udp_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - MpmInitCtx(sh->mpm_proto_udp_ctx_ts, de_ctx->mpm_matcher); - MpmInitCtx(sh->mpm_proto_udp_ctx_tc, de_ctx->mpm_matcher); - - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_proto_other_ctx = - MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_other_packet, 0); - } else { - sh->mpm_proto_other_ctx = - MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_proto_other_ctx == NULL) { - SCLogDebug("sh->mpm_proto_other_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - MpmInitCtx(sh->mpm_proto_other_ctx, de_ctx->mpm_matcher); - } /* if (has_co_packet) */ - - if (has_co_stream) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_stream_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 0); - sh->mpm_stream_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 1); - } else { - sh->mpm_stream_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - sh->mpm_stream_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1); - } - if (sh->mpm_stream_ctx_tc == NULL || sh->mpm_stream_ctx_ts == NULL) { - SCLogDebug("sh->mpm_stream_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - MpmInitCtx(sh->mpm_stream_ctx_ts, de_ctx->mpm_matcher); - MpmInitCtx(sh->mpm_stream_ctx_tc, de_ctx->mpm_matcher); - } - - if (has_co_uri) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_uri_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_uri, 0); - } else { - sh->mpm_uri_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_uri_ctx_ts == NULL) { - SCLogDebug("sh->mpm_uri_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_uri_ctx_ts, de_ctx->mpm_matcher); - } - - if (has_co_hcbd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hcbd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcbd, 0); - } else { - sh->mpm_hcbd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_hcbd_ctx_ts == NULL) { - SCLogDebug("sh->mpm_hcbd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hcbd_ctx_ts, de_ctx->mpm_matcher); - } - - if (has_co_hsbd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hsbd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsbd, 1); - } else { - sh->mpm_hsbd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1); - } - if (sh->mpm_hsbd_ctx_tc == NULL) { - SCLogDebug("sh->mpm_hsbd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hsbd_ctx_tc, de_ctx->mpm_matcher); - } - - if (has_co_smtp) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_smtp_filedata_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_smtp, 0); - } else { - sh->mpm_smtp_filedata_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_smtp_filedata_ctx_ts == NULL) { - SCLogDebug("sh->mpm_smtp_filedata_ctx_ts == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_smtp_filedata_ctx_ts, de_ctx->mpm_matcher); - } - - if (has_co_hhd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhd, 0); - sh->mpm_hhd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhd, 1); - } else { - sh->mpm_hhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - sh->mpm_hhd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1); - } - if (sh->mpm_hhd_ctx_ts == NULL || sh->mpm_hhd_ctx_tc == NULL) { - SCLogDebug("sh->mpm_hhd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hhd_ctx_ts, de_ctx->mpm_matcher); - MpmInitCtx(sh->mpm_hhd_ctx_tc, de_ctx->mpm_matcher); - } - - if (has_co_hrhd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hrhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhd, 0); - sh->mpm_hrhd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhd, 1); - } else { - sh->mpm_hrhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - sh->mpm_hrhd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1); - } - if (sh->mpm_hrhd_ctx_ts == NULL || sh->mpm_hrhd_ctx_tc == NULL) { - SCLogDebug("sh->mpm_hrhd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hrhd_ctx_ts, de_ctx->mpm_matcher); - MpmInitCtx(sh->mpm_hrhd_ctx_tc, de_ctx->mpm_matcher); - } - - if (has_co_hmd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hmd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hmd, 0); - } else { - sh->mpm_hmd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_hmd_ctx_ts == NULL) { - SCLogDebug("sh->mpm_hmd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hmd_ctx_ts, de_ctx->mpm_matcher); - } - - if (has_co_hcd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hcd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcd, 0); - sh->mpm_hcd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcd, 1); - } else { - sh->mpm_hcd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - sh->mpm_hcd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1); - } - if (sh->mpm_hcd_ctx_ts == NULL || sh->mpm_hcd_ctx_tc == NULL) { - SCLogDebug("sh->mpm_hcd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hcd_ctx_ts, de_ctx->mpm_matcher); - MpmInitCtx(sh->mpm_hcd_ctx_tc, de_ctx->mpm_matcher); - } - - if (has_co_hrud) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hrud_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrud, 0); - } else { - sh->mpm_hrud_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_hrud_ctx_ts == NULL) { - SCLogDebug("sh->mpm_hrud_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hrud_ctx_ts, de_ctx->mpm_matcher); - } - - if (has_co_hsmd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hsmd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsmd, 1); - } else { - sh->mpm_hsmd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1); - } - if (sh->mpm_hsmd_ctx_tc == NULL) { - SCLogDebug("sh->mpm_hsmd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hsmd_ctx_tc, de_ctx->mpm_matcher); - } - - if (has_co_hscd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hscd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hscd, 1); - } else { - sh->mpm_hscd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1); - } - if (sh->mpm_hscd_ctx_tc == NULL) { - SCLogDebug("sh->mpm_hscd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hscd_ctx_tc, de_ctx->mpm_matcher); - } - - if (has_co_huad) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_huad_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_huad, 0); - } else { - sh->mpm_huad_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_huad_ctx_ts == NULL) { - SCLogDebug("sh->mpm_huad_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_huad_ctx_ts, de_ctx->mpm_matcher); - } - - if (has_co_hhhd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hhhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhhd, 0); - } else { - sh->mpm_hhhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_hhhd_ctx_ts == NULL) { - SCLogDebug("sh->mpm_hhhd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hhhd_ctx_ts, de_ctx->mpm_matcher); - } - - if (has_co_hrhhd) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_hrhhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhhd, 0); - } else { - sh->mpm_hrhhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_hrhhd_ctx_ts == NULL) { - SCLogDebug("sh->mpm_hrhhd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_hrhhd_ctx_ts, de_ctx->mpm_matcher); - } - - if (has_co_dnsquery) { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - sh->mpm_dnsquery_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_dnsquery, 0); - } else { - sh->mpm_dnsquery_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0); - } - if (sh->mpm_dnsquery_ctx_ts == NULL) { - SCLogDebug("sh->mpm_hrhhd_ctx == NULL. This should never happen"); - exit(EXIT_FAILURE); - } - - MpmInitCtx(sh->mpm_dnsquery_ctx_ts, de_ctx->mpm_matcher); - } - - if (has_co_packet || - has_co_stream || - has_co_uri || - has_co_hcbd || - has_co_hsbd || - has_co_smtp || - has_co_hhd || - has_co_hrhd || - has_co_hmd || - has_co_hcd || - has_co_hsmd || - has_co_hscd || - has_co_hrud || - has_co_huad || - has_co_hhhd || - has_co_hrhhd || - has_co_dnsquery) - { - PatternMatchPreparePopulateMpm(de_ctx, sh); - - if (sh->mpm_proto_tcp_ctx_ts != NULL) { - if (sh->mpm_proto_tcp_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_ts); - sh->mpm_proto_tcp_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_proto_tcp_ctx_ts->mpm_type].Prepare != NULL) { - mpm_table[sh->mpm_proto_tcp_ctx_ts->mpm_type]. - Prepare(sh->mpm_proto_tcp_ctx_ts); - } - } - } - } - if (sh->mpm_proto_tcp_ctx_tc != NULL) { - if (sh->mpm_proto_tcp_ctx_tc->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_tc); - sh->mpm_proto_tcp_ctx_tc = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_proto_tcp_ctx_tc->mpm_type].Prepare != NULL) { - mpm_table[sh->mpm_proto_tcp_ctx_tc->mpm_type]. - Prepare(sh->mpm_proto_tcp_ctx_tc); - } - } - } - } - - if (sh->mpm_proto_udp_ctx_ts != NULL) { - if (sh->mpm_proto_udp_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_ts); - sh->mpm_proto_udp_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_proto_udp_ctx_ts->mpm_type].Prepare != NULL) { - mpm_table[sh->mpm_proto_udp_ctx_ts->mpm_type]. - Prepare(sh->mpm_proto_udp_ctx_ts); - } - } - } - } - if (sh->mpm_proto_udp_ctx_tc != NULL) { - if (sh->mpm_proto_udp_ctx_tc->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_tc); - sh->mpm_proto_udp_ctx_tc = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_proto_udp_ctx_tc->mpm_type].Prepare != NULL) { - mpm_table[sh->mpm_proto_udp_ctx_tc->mpm_type]. - Prepare(sh->mpm_proto_udp_ctx_tc); - } - } - } - } - - if (sh->mpm_proto_other_ctx != NULL) { - if (sh->mpm_proto_other_ctx->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_other_ctx); - sh->mpm_proto_other_ctx = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_proto_other_ctx->mpm_type].Prepare != NULL) { - mpm_table[sh->mpm_proto_other_ctx->mpm_type]. - Prepare(sh->mpm_proto_other_ctx); - } - } - } - } - - if (sh->mpm_stream_ctx_ts != NULL) { - if (sh->mpm_stream_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_ts); - sh->mpm_stream_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_stream_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_stream_ctx_ts->mpm_type].Prepare(sh->mpm_stream_ctx_ts); - } - } - } - if (sh->mpm_stream_ctx_tc != NULL) { - if (sh->mpm_stream_ctx_tc->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_tc); - sh->mpm_stream_ctx_tc = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_stream_ctx_tc->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_stream_ctx_tc->mpm_type].Prepare(sh->mpm_stream_ctx_tc); - } - } - } - - if (sh->mpm_uri_ctx_ts != NULL) { - if (sh->mpm_uri_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_uri_ctx_ts); - sh->mpm_uri_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_uri_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_uri_ctx_ts->mpm_type].Prepare(sh->mpm_uri_ctx_ts); - } - } - } - - if (sh->mpm_hcbd_ctx_ts != NULL) { - if (sh->mpm_hcbd_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcbd_ctx_ts); - sh->mpm_hcbd_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hcbd_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hcbd_ctx_ts->mpm_type].Prepare(sh->mpm_hcbd_ctx_ts); - } - } - } - - if (sh->mpm_hsbd_ctx_tc != NULL) { - if (sh->mpm_hsbd_ctx_tc->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hsbd_ctx_tc); - sh->mpm_hsbd_ctx_tc = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hsbd_ctx_tc->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hsbd_ctx_tc->mpm_type].Prepare(sh->mpm_hsbd_ctx_tc); - } - } - } - - if (sh->mpm_smtp_filedata_ctx_ts != NULL) { - if (sh->mpm_smtp_filedata_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_smtp_filedata_ctx_ts); - sh->mpm_smtp_filedata_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_smtp_filedata_ctx_ts->mpm_type].Prepare != NULL) { - mpm_table[sh->mpm_smtp_filedata_ctx_ts->mpm_type].Prepare(sh->mpm_smtp_filedata_ctx_ts); - } - } - } - } - - if (sh->mpm_hhd_ctx_ts != NULL) { - if (sh->mpm_hhd_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhd_ctx_ts); - sh->mpm_hhd_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hhd_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hhd_ctx_ts->mpm_type].Prepare(sh->mpm_hhd_ctx_ts); - } - } - } - if (sh->mpm_hhd_ctx_tc != NULL) { - if (sh->mpm_hhd_ctx_tc->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhd_ctx_tc); - sh->mpm_hhd_ctx_tc = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hhd_ctx_tc->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hhd_ctx_tc->mpm_type].Prepare(sh->mpm_hhd_ctx_tc); - } - } - } - - if (sh->mpm_hrhd_ctx_ts != NULL) { - if (sh->mpm_hrhd_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhd_ctx_ts); - sh->mpm_hrhd_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hrhd_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hrhd_ctx_ts->mpm_type].Prepare(sh->mpm_hrhd_ctx_ts); - } - } - } - if (sh->mpm_hrhd_ctx_tc != NULL) { - if (sh->mpm_hrhd_ctx_tc->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhd_ctx_tc); - sh->mpm_hrhd_ctx_tc = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hrhd_ctx_tc->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hrhd_ctx_tc->mpm_type].Prepare(sh->mpm_hrhd_ctx_tc); - } - } - } - - if (sh->mpm_hmd_ctx_ts != NULL) { - if (sh->mpm_hmd_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hmd_ctx_ts); - sh->mpm_hmd_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hmd_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hmd_ctx_ts->mpm_type].Prepare(sh->mpm_hmd_ctx_ts); - } - } - } - - if (sh->mpm_hcd_ctx_ts != NULL) { - if (sh->mpm_hcd_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcd_ctx_ts); - sh->mpm_hcd_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hcd_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hcd_ctx_ts->mpm_type].Prepare(sh->mpm_hcd_ctx_ts); - } - } - } - if (sh->mpm_hcd_ctx_tc != NULL) { - if (sh->mpm_hcd_ctx_tc->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcd_ctx_tc); - sh->mpm_hcd_ctx_tc = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hcd_ctx_tc->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hcd_ctx_tc->mpm_type].Prepare(sh->mpm_hcd_ctx_tc); - } - } - } - - if (sh->mpm_hrud_ctx_ts != NULL) { - if (sh->mpm_hrud_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrud_ctx_ts); - sh->mpm_hrud_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hrud_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hrud_ctx_ts->mpm_type].Prepare(sh->mpm_hrud_ctx_ts); - } - } - } - - if (sh->mpm_hsmd_ctx_tc != NULL) { - if (sh->mpm_hsmd_ctx_tc->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hsmd_ctx_tc); - sh->mpm_hsmd_ctx_tc = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hsmd_ctx_tc->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hsmd_ctx_tc->mpm_type].Prepare(sh->mpm_hsmd_ctx_tc); - } - } - } - - if (sh->mpm_hscd_ctx_tc != NULL) { - if (sh->mpm_hscd_ctx_tc->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hscd_ctx_tc); - sh->mpm_hscd_ctx_tc = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hscd_ctx_tc->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hscd_ctx_tc->mpm_type].Prepare(sh->mpm_hscd_ctx_tc); - } - } - } - - if (sh->mpm_huad_ctx_ts != NULL) { - if (sh->mpm_huad_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_huad_ctx_ts); - sh->mpm_huad_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_huad_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_huad_ctx_ts->mpm_type].Prepare(sh->mpm_huad_ctx_ts); - } - } - } - - if (sh->mpm_hhhd_ctx_ts != NULL) { - if (sh->mpm_hhhd_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhhd_ctx_ts); - sh->mpm_hhhd_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hhhd_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hhhd_ctx_ts->mpm_type].Prepare(sh->mpm_hhhd_ctx_ts); - } - } - } - - if (sh->mpm_hrhhd_ctx_ts != NULL) { - if (sh->mpm_hrhhd_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhhd_ctx_ts); - sh->mpm_hrhhd_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_hrhhd_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_hrhhd_ctx_ts->mpm_type].Prepare(sh->mpm_hrhhd_ctx_ts); - } - } - } - - if (sh->mpm_dnsquery_ctx_ts != NULL) { - if (sh->mpm_dnsquery_ctx_ts->pattern_cnt == 0) { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_dnsquery_ctx_ts); - sh->mpm_dnsquery_ctx_ts = NULL; - } else { - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) { - if (mpm_table[sh->mpm_dnsquery_ctx_ts->mpm_type].Prepare != NULL) - mpm_table[sh->mpm_dnsquery_ctx_ts->mpm_type].Prepare(sh->mpm_dnsquery_ctx_ts); - } - } - } - } else { - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_other_ctx); - sh->mpm_proto_other_ctx = NULL; - - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_ts); - sh->mpm_proto_tcp_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_ts); - sh->mpm_proto_udp_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_ts); - sh->mpm_stream_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_uri_ctx_ts); - sh->mpm_uri_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcbd_ctx_ts); - sh->mpm_hcbd_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhd_ctx_ts); - sh->mpm_hhd_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhd_ctx_ts); - sh->mpm_hrhd_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hmd_ctx_ts); - sh->mpm_hmd_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcd_ctx_ts); - sh->mpm_hcd_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrud_ctx_ts); - sh->mpm_hrud_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_huad_ctx_ts); - sh->mpm_huad_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhhd_ctx_ts); - sh->mpm_hhhd_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhhd_ctx_ts); - sh->mpm_hrhhd_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_dnsquery_ctx_ts); - sh->mpm_dnsquery_ctx_ts = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_smtp_filedata_ctx_ts); - sh->mpm_smtp_filedata_ctx_ts = NULL; - - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_tc); - sh->mpm_proto_tcp_ctx_tc = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_tc); - sh->mpm_proto_udp_ctx_tc = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_tc); - sh->mpm_stream_ctx_tc = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhd_ctx_tc); - sh->mpm_hhd_ctx_tc = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhd_ctx_tc); - sh->mpm_hrhd_ctx_tc = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcd_ctx_tc); - sh->mpm_hcd_ctx_tc = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hsmd_ctx_tc); - sh->mpm_hsmd_ctx_tc = NULL; - MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hscd_ctx_tc); - sh->mpm_hscd_ctx_tc = NULL; - } - - return 0; -} - -/** \brief Pattern ID Hash for sharing pattern id's - * - * A per detection engine hash to make sure each pattern has a unique - * global id but patterns that are the same share id's. - */ -typedef struct MpmPatternIdTableElmt_ { - uint8_t *pattern; /**< ptr to the pattern */ - uint16_t pattern_len; /**< pattern len */ - PatIntId id; /**< pattern id */ - uint16_t dup_count; /**< duplicate count */ - uint8_t sm_list; /**< SigMatch list */ -} MpmPatternIdTableElmt; - -/** \brief Hash compare func for MpmPatternId api - * \retval 1 patterns are the same - * \retval 0 patterns are not the same - **/ -static char MpmPatternIdCompare(void *p1, uint16_t len1, void *p2, uint16_t len2) -{ - SCEnter(); - BUG_ON(len1 < sizeof(MpmPatternIdTableElmt)); - BUG_ON(len2 < sizeof(MpmPatternIdTableElmt)); - - MpmPatternIdTableElmt *e1 = (MpmPatternIdTableElmt *)p1; - MpmPatternIdTableElmt *e2 = (MpmPatternIdTableElmt *)p2; - - if (e1->pattern_len != e2->pattern_len || - e1->sm_list != e2->sm_list) { - SCReturnInt(0); - } - - if (SCMemcmp(e1->pattern, e2->pattern, e1->pattern_len) != 0) { - SCReturnInt(0); - } - - SCReturnInt(1); -} - -/** \brief Hash func for MpmPatternId api - * \retval hash hash value - */ -static uint32_t MpmPatternIdHashFunc(HashTable *ht, void *p, uint16_t len) -{ - SCEnter(); - BUG_ON(len < sizeof(MpmPatternIdTableElmt)); - - MpmPatternIdTableElmt *e = (MpmPatternIdTableElmt *)p; - uint32_t hash = e->pattern_len; - uint16_t u = 0; - - for (u = 0; u < e->pattern_len; u++) { - hash += e->pattern[u]; - } - - SCReturnUInt(hash % ht->array_size); -} - -/** \brief free a MpmPatternIdTableElmt */ -static void MpmPatternIdTableElmtFree(void *e) -{ - SCEnter(); - MpmPatternIdTableElmt *c = (MpmPatternIdTableElmt *)e; - SCFree(c->pattern); - SCFree(c); - SCReturn; -} - -/** \brief alloc initialize the MpmPatternIdHash */ -MpmPatternIdStore *MpmPatternIdTableInitHash(void) -{ - SCEnter(); - - MpmPatternIdStore *ht = SCMalloc(sizeof(MpmPatternIdStore)); - BUG_ON(ht == NULL); - memset(ht, 0x00, sizeof(MpmPatternIdStore)); - - ht->hash = HashTableInit(65536, MpmPatternIdHashFunc, MpmPatternIdCompare, MpmPatternIdTableElmtFree); - BUG_ON(ht->hash == NULL); - - SCReturnPtr(ht, "MpmPatternIdStore"); -} - -void MpmPatternIdTableFreeHash(MpmPatternIdStore *ht) -{ - SCEnter(); - - if (ht == NULL) { - SCReturn; - } - - if (ht->hash != NULL) { - HashTableFree(ht->hash); - } - - SCFree(ht); - SCReturn; -} - -uint32_t MpmPatternIdStoreGetMaxId(MpmPatternIdStore *ht) -{ - if (ht == NULL) { - return 0; - } - - return ht->max_id; -} - -/** - * \brief Get the pattern id for a content pattern - * - * \param ht mpm pattern id hash table store - * \param co content pattern data - * - * \retval id pattern id - * \initonly - */ -uint32_t DetectContentGetId(MpmPatternIdStore *ht, DetectContentData *co) -{ - SCEnter(); - - BUG_ON(ht == NULL || ht->hash == NULL); - - MpmPatternIdTableElmt *e = NULL; - MpmPatternIdTableElmt *r = NULL; - uint32_t id = 0; - - e = SCMalloc(sizeof(MpmPatternIdTableElmt)); - BUG_ON(e == NULL); - memset(e, 0, sizeof(MpmPatternIdTableElmt)); - e->pattern = SCMalloc(co->content_len); - BUG_ON(e->pattern == NULL); - memcpy(e->pattern, co->content, co->content_len); - e->pattern_len = co->content_len; - e->id = 0; - - r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt)); - if (r == NULL) { - e->id = ht->max_id; - ht->max_id++; - id = e->id; - - int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt)); - BUG_ON(ret != 0); - - e = NULL; - - ht->unique_patterns++; - } else { - id = r->id; - - ht->shared_patterns++; - } - - if (e != NULL) - MpmPatternIdTableElmtFree(e); - - SCReturnUInt(id); -} - -typedef struct DetectFPAndItsId_ { - PatIntId id; - uint16_t content_len; - uint32_t flags; - int sm_list; - - uint8_t *content; -} DetectFPAndItsId; - -/** - * \brief Figured out the FP and their respective content ids for all the - * sigs in the engine. - * - * \param de_ctx Detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectSetFastPatternAndItsId(DetectEngineCtx *de_ctx) -{ - uint32_t struct_total_size = 0; - uint32_t content_total_size = 0; - Signature *s = NULL; - - /* Count the amount of memory needed to store all the structures - * and the content of those structures. This will over estimate the - * true size, since duplicates are removed below, but counted here. - */ - for (s = de_ctx->sig_list; s != NULL; s = s->next) { - s->mpm_sm = RetrieveFPForSigV2(s); - if (s->mpm_sm != NULL) { - DetectContentData *cd = (DetectContentData *)s->mpm_sm->ctx; - struct_total_size += sizeof(DetectFPAndItsId); - content_total_size += cd->content_len; - } - } - - /* array hash buffer - i've run out of ideas to name it */ - uint8_t *ahb = SCMalloc(sizeof(uint8_t) * (struct_total_size + content_total_size)); - if (unlikely(ahb == NULL)) - return -1; - - uint8_t *content = NULL; - uint8_t content_len = 0; - PatIntId max_id = 0; - DetectFPAndItsId *struct_offset = (DetectFPAndItsId *)ahb; - uint8_t *content_offset = ahb + struct_total_size; - for (s = de_ctx->sig_list; s != NULL; s = s->next) { - if (s->mpm_sm != NULL) { - int sm_list = SigMatchListSMBelongsTo(s, s->mpm_sm); - BUG_ON(sm_list == -1); - - DetectContentData *cd = (DetectContentData *)s->mpm_sm->ctx; - DetectFPAndItsId *dup = (DetectFPAndItsId *)ahb; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) { - content = cd->content + cd->fp_chop_offset; - content_len = cd->fp_chop_len; - } else { - content = cd->content; - content_len = cd->content_len; - } - uint32_t flags = cd->flags & DETECT_CONTENT_NOCASE; - /* Check for content already found on the same list */ - for (; dup != struct_offset; dup++) { - if (dup->content_len != content_len) - continue; - if (dup->sm_list != sm_list) - continue; - if (dup->flags != flags) - continue; - /* Check for pattern matching a duplicate. Use case insensitive matching - * for case insensitive patterns. */ - if (flags & DETECT_CONTENT_NOCASE) { - if (SCMemcmpLowercase(dup->content, content, content_len) != 0) - continue; - } else { - /* Case sensitive matching */ - if (SCMemcmp(dup->content, content, content_len) != 0) - continue; - } - /* Found a match with a previous pattern. */ - break; - } - if (dup != struct_offset) { - /* Exited for-loop before the end, so found an existing match. - * Use its ID. */ - cd->id = dup->id; - continue; - } - - /* Not found, so new content. Give it a new ID and add it - * to the array. Copy the content at the end of the - * content array. - */ - struct_offset->id = max_id++; - cd->id = struct_offset->id; - struct_offset->content_len = content_len; - struct_offset->sm_list = sm_list; - struct_offset->content = content_offset; - struct_offset->flags = flags; - - content_offset += content_len; - - if (flags & DETECT_CONTENT_NOCASE) { - /* Need to store case-insensitive patterns as lower case - * because SCMemcmpLowercase() above assumes that all - * patterns are stored lower case so that it doesn't - * need to relower its first argument. - */ - memcpy_tolower(struct_offset->content, content, content_len); - } else { - memcpy(struct_offset->content, content, content_len); - } - - struct_offset++; - } /* if (s->mpm_sm != NULL) */ - } /* for */ - - de_ctx->max_fp_id = max_id; - - SCFree(ahb); - - return 0; -} diff --git a/framework/src/suricata/src/detect-engine-mpm.h b/framework/src/suricata/src/detect-engine-mpm.h deleted file mode 100644 index 02df56f4..00000000 --- a/framework/src/suricata/src/detect-engine-mpm.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_MPM_H__ -#define __DETECT_ENGINE_MPM_H__ - -#include "tm-threads.h" - -#include "detect.h" -#include "detect-content.h" -#include "detect-uricontent.h" - -#include "stream.h" - -uint16_t PatternMatchDefaultMatcher(void); - -uint32_t PatternStrength(uint8_t *, uint16_t); -uint32_t PacketPatternSearchWithStreamCtx(DetectEngineThreadCtx *, Packet *); -uint32_t PacketPatternSearch(DetectEngineThreadCtx *, Packet *); -uint32_t UriPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint16_t, uint8_t); -uint32_t StreamPatternSearch(DetectEngineThreadCtx *, Packet *, StreamMsg *, uint8_t); -uint32_t HttpClientBodyPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpServerBodyPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpMethodPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpCookiePatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpRawUriPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpStatMsgPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpStatCodePatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpUAPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpHHPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t HttpHRHPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t, uint8_t); -uint32_t DnsQueryPatternSearch(DetectEngineThreadCtx *det_ctx, uint8_t *buffer, uint32_t buffer_len, uint8_t flags); -uint32_t SMTPFiledataPatternSearch(DetectEngineThreadCtx *det_ctx, uint8_t *buffer, uint32_t buffer_len, uint8_t flags); - -void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *); -void StreamPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx, StreamMsg *smsg); - -void PatternMatchPrepare(MpmCtx *, uint16_t); -void PatternMatchThreadPrepare(MpmThreadCtx *, uint16_t type, uint32_t max_id); - -void PatternMatchDestroy(MpmCtx *, uint16_t); -void PatternMatchThreadDestroy(MpmThreadCtx *mpm_thread_ctx, uint16_t); -void PatternMatchThreadPrint(MpmThreadCtx *, uint16_t); - -int PatternMatchPrepareGroup(DetectEngineCtx *, SigGroupHead *); -void DetectEngineThreadCtxInfo(ThreadVars *, DetectEngineThreadCtx *); -void PatternMatchDestroyGroup(SigGroupHead *); - -TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **); -TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *); - -void DbgPrintSearchStats(); - -MpmPatternIdStore *MpmPatternIdTableInitHash(void); -void MpmPatternIdTableFreeHash(MpmPatternIdStore *); -uint32_t MpmPatternIdStoreGetMaxId(MpmPatternIdStore *); -uint32_t DetectContentGetId(MpmPatternIdStore *, DetectContentData *); - -int SignatureHasPacketContent(Signature *); -int SignatureHasStreamContent(Signature *); - -SigMatch *RetrieveFPForSig(Signature *s); -SigMatch *RetrieveFPForSigV2(Signature *s); - -/** - * \brief Figured out the FP and their respective content ids for all the - * sigs in the engine. - * - * \param de_ctx Detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectSetFastPatternAndItsId(DetectEngineCtx *de_ctx); - -#endif /* __DETECT_ENGINE_MPM_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-payload.c b/framework/src/suricata/src/detect-engine-payload.c deleted file mode 100644 index af0d9c3e..00000000 --- a/framework/src/suricata/src/detect-engine-payload.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Performs payload matching functions - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-engine-content-inspection.h" - -#include "util-debug.h" -#include "util-print.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -/** - * \brief Do the content inspection & validation for a signature - * - * \param de_ctx Detection engine context - * \param det_ctx Detection engine thread context - * \param s Signature to inspect - * \param f flow (for pcre flowvar storage) - * \param p Packet - * - * \retval 0 no match - * \retval 1 match - */ -int DetectEngineInspectPacketPayload(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, Packet *p) -{ - SCEnter(); - int r = 0; - - if (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - SCReturnInt(0); - } - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - det_ctx->replist = NULL; - //det_ctx->flags |= DETECT_ENGINE_THREAD_CTX_INSPECTING_PACKET; - - r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_PMATCH], - f, p->payload, p->payload_len, 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD, p); - //r = DoInspectPacketPayload(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_PMATCH], p, f, p->payload, p->payload_len); - //det_ctx->flags &= ~DETECT_ENGINE_THREAD_CTX_INSPECTING_PACKET; - if (r == 1) { - SCReturnInt(1); - } - SCReturnInt(0); -} - -/** - * \brief Do the content inspection & validation for a signature for a stream chunk - * - * \param de_ctx Detection engine context - * \param det_ctx Detection engine thread context - * \param s Signature to inspect - * \param f flow (for pcre flowvar storage) - * \param payload ptr to the payload to inspect - * \param payload_len length of the payload - * - * \retval 0 no match - * \retval 1 match - * - * \todo we might also pass the packet to this function for the pktvar - * storage. Only, would that be right? We're not inspecting data - * from the current packet here. - */ -int DetectEngineInspectStreamPayload(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, - uint8_t *payload, uint32_t payload_len) -{ - SCEnter(); - int r = 0; - - if (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - SCReturnInt(0); - } - - det_ctx->buffer_offset = 0; - det_ctx->discontinue_matching = 0; - det_ctx->inspection_recursion_counter = 0; - //det_ctx->flags |= DETECT_ENGINE_THREAD_CTX_INSPECTING_STREAM; - - r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_PMATCH], - f, payload, payload_len, 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_STREAM, NULL); - - //r = DoInspectPacketPayload(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_PMATCH], NULL, f, payload, payload_len); - //det_ctx->flags &= ~DETECT_ENGINE_THREAD_CTX_INSPECTING_STREAM; - if (r == 1) { - SCReturnInt(1); - } - - SCReturnInt(0); -} - -#ifdef UNITTESTS - -/** \test Not the first but the second occurence of "abc" should be used - * for the 2nd match */ -static int PayloadTestSig01 (void) -{ - uint8_t *buf = (uint8_t *) - "abcabcd"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (content:\"abc\"; content:\"d\"; distance:0; within:1; sid:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** \test Nocase matching */ -static int PayloadTestSig02 (void) -{ - uint8_t *buf = (uint8_t *) - "abcaBcd"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (content:\"abc\"; nocase; content:\"d\"; distance:0; within:1; sid:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** \test Negative distance matching */ -static int PayloadTestSig03 (void) -{ - uint8_t *buf = (uint8_t *) - "abcaBcd"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (content:\"aBc\"; nocase; content:\"abca\"; distance:-10; within:4; sid:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative matches. - */ -static int PayloadTestSig04(void) -{ - uint8_t *buf = (uint8_t *)"now this is is big big string now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"this\"; content:\"is\"; within:6; content:\"big\"; within:8; " - "content:\"string\"; within:8; sid:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative matches. - */ -static int PayloadTestSig05(void) -{ - uint8_t *buf = (uint8_t *)"now this is is is big big big string now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"this\"; content:\"is\"; within:9; content:\"big\"; within:12; " - "content:\"string\"; within:8; sid:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative matches. - */ -static int PayloadTestSig06(void) -{ - uint8_t *buf = (uint8_t *)"this this now is is big string now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"now\"; content:\"this\"; content:\"is\"; within:12; content:\"big\"; within:8; " - "content:\"string\"; within:8; sid:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative matches. - */ -static int PayloadTestSig07(void) -{ - uint8_t *buf = (uint8_t *)" thus thus is a big"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"thus\"; offset:8; content:\"is\"; within:6; content:\"big\"; within:8; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative matches with negative matches - * and show the need for det_ctx->discontinue_matching. - */ -static int PayloadTestSig08(void) -{ - uint8_t *buf = (uint8_t *)"we need to fix this and yes fix this now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"fix\"; content:\"this\"; within:6; content:!\"and\"; distance:0; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) != 1) { - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test pcre recursive matching. - */ -static int PayloadTestSig09(void) -{ - uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "pcre:/super/; content:\"nova\"; within:7; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test invalid sig. - */ -static int PayloadTestSig10(void) -{ - uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert udp any any -> any any (msg:\"crash\"; " - "byte_test:4,>,2,0,relative; sid:11;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 1) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test invalid sig. - */ -static int PayloadTestSig11(void) -{ - uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert udp any any -> any any (msg:\"crash\"; " - "byte_jump:1,0,relative; sid:11;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 1) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test invalid sig. - */ -static int PayloadTestSig12(void) -{ - uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert udp any any -> any any (msg:\"crash\"; " - "isdataat:10,relative; sid:11;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 1) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Used to check the working of recursion_limit counter. - */ -static int PayloadTestSig13(void) -{ - uint8_t *buf = (uint8_t *)"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - uint16_t mpm_type = MPM_B2G; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"aa\"; content:\"aa\"; distance:0; content:\"aa\"; distance:0; " - "byte_test:1,>,200,0,relative; sid:1;)"; - - struct timeval tv_start, tv_end, tv_diff; - - gettimeofday(&tv_start, NULL); - - do { - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx == NULL: "); - goto end; - } - de_ctx->inspection_recursion_limit = 3000; - - de_ctx->flags |= DE_QUIET; - de_ctx->mpm_matcher = mpm_type; - - de_ctx->sig_list = SigInit(de_ctx, sig); - if (de_ctx->sig_list == NULL) { - printf("signature == NULL: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, de_ctx->sig_list->id) != 1) { - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - } while (0); - - gettimeofday(&tv_end, NULL); - - tv_diff.tv_sec = tv_end.tv_sec - tv_start.tv_sec; - tv_diff.tv_usec = tv_end.tv_usec - tv_start.tv_usec; - - printf("%ld.%06ld\n", (long int)tv_diff.tv_sec, (long int)tv_diff.tv_usec); - - result = 1; - - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test normal & negated matching, both absolute and relative - */ -static int PayloadTestSig14(void) -{ - uint8_t *buf = (uint8_t *)"User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.6 GTB5"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (content:\"User-Agent|3A| Mozilla/5.0 |28|Macintosh|3B| \"; content:\"Firefox/3.\"; distance:0; content:!\"Firefox/3.6.12\"; distance:-10; content:!\"Mozilla/5.0 |28|Macintosh|3B| U|3B| Intel Mac OS X 10.5|3B| en-US|3B| rv|3A|1.9.1b4|29| Gecko/20090423 Firefox/3.6 GTB5\"; sid:1; rev:1;)"; - - //char sig[] = "alert tcp any any -> any any (content:\"User-Agent: Mozilla/5.0 (Macintosh; \"; content:\"Firefox/3.\"; distance:0; content:!\"Firefox/3.6.12\"; distance:-10; content:!\"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b4) Gecko/20090423 Firefox/3.6 GTB5\"; sid:1; rev:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 1) { - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig15(void) -{ - uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"nova\"; isdataat:18,relative; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig16(void) -{ - uint8_t *buf = (uint8_t *)"this is a super duper nova in super nova now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"nova\"; isdataat:!20,relative; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig17(void) -{ - uint8_t buf[] = { 0xEB, 0x29, 0x25, 0x38, 0x78, 0x25, 0x38, 0x78, 0x25 }; - uint16_t buflen = 9; - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"%\"; depth:4; offset:0; " - "content:\"%\"; within:2; distance:1; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig18(void) -{ - uint8_t buf[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x35, /* the last byte is 2 */ - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, - }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"|01 02 03 04|\"; " - "byte_extract:1,2,one,string,dec,relative; " - "content:\"|0C 0D 0E 0F|\"; distance:one; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig19(void) -{ - uint8_t buf[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x35, /* the last byte is 2 */ - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, - }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"|01 02 03 04|\"; " - "byte_extract:1,2,one,string,hex,relative; " - "content:\"|0C 0D 0E 0F|\"; distance:one; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig20(void) -{ - uint8_t buf[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x35, /* the last byte is 2 */ - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, - }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"|01 02 03 04|\"; " - "byte_extract:1,2,one,string,dec,relative; " - "content:\"|06 35 07 08|\"; offset:one; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig21(void) -{ - uint8_t buf[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x36, /* the last byte is 2 */ - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, - }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"|01 02 03 04|\"; " - "byte_extract:1,2,one,string,dec,relative; " - "content:\"|03 04 05 06|\"; depth:one; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig22(void) -{ - uint8_t buf[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x36, /* the last byte is 2 */ - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, - }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"|01 02 03 04|\"; " - "byte_extract:1,2,one,string,dec,relative; " - "content:\"|09 0A 0B 0C|\"; within:one; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig23(void) -{ - uint8_t buf[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x32, /* the last byte is 2 */ - 0x07, 0x08, 0x09, 0x33, 0x0B, 0x0C, 0x0D, - 0x32, 0x0F, - }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"|01 02 03 04|\"; " - "byte_extract:1,2,one,string,dec,relative; " - "byte_extract:1,3,two,string,dec,relative; " - "byte_test:1,=,one,two,string,dec,relative; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig24(void) -{ - uint8_t buf[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x32, /* the last byte is 2 */ - 0x07, 0x08, 0x33, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, - }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"|01 02 03 04|\"; " - "byte_extract:1,2,one,string,dec,relative; " - "byte_jump:1,one,string,dec,relative; " - "content:\"|0D 0E 0F|\"; distance:0; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/* - * \test Test negative byte extract. - */ -static int PayloadTestSig25(void) -{ - uint8_t buf[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x35, /* the last byte is 2 */ - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, - }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"|35 07 08 09|\"; " - "byte_extract:1,-4,one,string,dec,relative; " - "content:\"|0C 0D 0E 0F|\"; distance:one; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/* - * \test Test negative byte extract. - */ -static int PayloadTestSig26(void) -{ - uint8_t buf[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x35, /* the last byte is 2 */ - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, - 0x0E, 0x0F, - }; - uint16_t buflen = sizeof(buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"|35 07 08 09|\"; " - "byte_extract:1,-3000,one,string,dec,relative; " - "content:\"|0C 0D 0E 0F|\"; distance:one; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) != 0) { - result = 0; - goto end; - } - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/* - * \test Test packet/stream sigs - */ -static int PayloadTestSig27(void) -{ - uint8_t buf[] = "dummypayload"; - uint16_t buflen = sizeof(buf) - 1; - int result = 0; - - Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - char sig[] = "alert tcp any any -> any any (content:\"dummy\"; " - "depth:5; sid:1;)"; - - p->flags |= PKT_STREAM_ADD; - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) != 1) - goto end; - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/* - * \test Test packet/stream sigs - */ -static int PayloadTestSig28(void) -{ - uint8_t buf[] = "dummypayload"; - uint16_t buflen = sizeof(buf) - 1; - int result = 0; - - Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - char sig[] = "alert tcp any any -> any any (content:\"payload\"; " - "offset:4; depth:12; sid:1;)"; - - p->flags |= PKT_STREAM_ADD; - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) != 1) - goto end; - - result = 1; - -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test pcre recursive matching - bug #529 - */ -static int PayloadTestSig29(void) -{ - uint8_t *buf = (uint8_t *)"this is a super dupernova in super nova now"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"dummy\"; " - "pcre:/^.{4}/; content:\"nova\"; within:4; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, DEFAULT_MPM) == 1) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig30(void) -{ - uint8_t *buf = (uint8_t *) - "xyonexxxxxxtwojunkonetwo"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (content:\"one\"; pcre:\"/^two/R\"; sid:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int PayloadTestSig31(void) -{ - uint8_t *buf = (uint8_t *) - "xyonexxxxxxtwojunkonetwo"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (content:\"one\"; pcre:\"/(fiv|^two)/R\"; sid:1;)"; - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) { - result = 0; - goto end; - } - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test byte_jump. - */ -static int PayloadTestSig32(void) -{ - uint8_t *buf = (uint8_t *)"dummy2xxcardmessage"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"crash\"; " - "content:\"message\"; byte_jump:2,-14,string,dec,relative; content:\"card\"; within:4; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) - goto end; - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test byte_test. - */ -static int PayloadTestSig33(void) -{ - uint8_t *buf = (uint8_t *)"dummy2xxcardmessage"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"crash\"; " - "content:\"message\"; byte_test:1,=,2,-14,string,dec,relative; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) - goto end; - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** - * \test Test byte_extract. - */ -static int PayloadTestSig34(void) -{ - uint8_t *buf = (uint8_t *)"dummy2xxcardmessage"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"crash\"; " - "content:\"message\"; byte_extract:1,-14,boom,string,dec,relative; sid:1;)"; - - if (UTHPacketMatchSigMpm(p, sig, MPM_B2G) == 0) - goto end; - - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -#endif /* UNITTESTS */ - -void PayloadRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("PayloadTestSig01", PayloadTestSig01, 1); - UtRegisterTest("PayloadTestSig02", PayloadTestSig02, 1); - UtRegisterTest("PayloadTestSig03", PayloadTestSig03, 1); - UtRegisterTest("PayloadTestSig04", PayloadTestSig04, 1); - UtRegisterTest("PayloadTestSig05", PayloadTestSig05, 1); - UtRegisterTest("PayloadTestSig06", PayloadTestSig06, 1); - UtRegisterTest("PayloadTestSig07", PayloadTestSig07, 1); - UtRegisterTest("PayloadTestSig08", PayloadTestSig08, 1); - UtRegisterTest("PayloadTestSig09", PayloadTestSig09, 1); - UtRegisterTest("PayloadTestSig10", PayloadTestSig10, 1); - UtRegisterTest("PayloadTestSig11", PayloadTestSig11, 1); - UtRegisterTest("PayloadTestSig12", PayloadTestSig12, 1); - UtRegisterTest("PayloadTestSig13", PayloadTestSig13, 1); - UtRegisterTest("PayloadTestSig14", PayloadTestSig14, 1); - UtRegisterTest("PayloadTestSig15", PayloadTestSig15, 1); - UtRegisterTest("PayloadTestSig16", PayloadTestSig16, 1); - UtRegisterTest("PayloadTestSig17", PayloadTestSig17, 1); - - UtRegisterTest("PayloadTestSig18", PayloadTestSig18, 1); - UtRegisterTest("PayloadTestSig19", PayloadTestSig19, 1); - UtRegisterTest("PayloadTestSig20", PayloadTestSig20, 1); - UtRegisterTest("PayloadTestSig21", PayloadTestSig21, 1); - UtRegisterTest("PayloadTestSig22", PayloadTestSig22, 1); - UtRegisterTest("PayloadTestSig23", PayloadTestSig23, 1); - UtRegisterTest("PayloadTestSig24", PayloadTestSig24, 1); - UtRegisterTest("PayloadTestSig25", PayloadTestSig25, 1); - UtRegisterTest("PayloadTestSig26", PayloadTestSig26, 1); - UtRegisterTest("PayloadTestSig27", PayloadTestSig27, 1); - UtRegisterTest("PayloadTestSig28", PayloadTestSig28, 1); - UtRegisterTest("PayloadTestSig29", PayloadTestSig29, 1); - - UtRegisterTest("PayloadTestSig30", PayloadTestSig30, 1); - UtRegisterTest("PayloadTestSig31", PayloadTestSig31, 1); - UtRegisterTest("PayloadTestSig32", PayloadTestSig32, 1); - UtRegisterTest("PayloadTestSig33", PayloadTestSig33, 1); - UtRegisterTest("PayloadTestSig34", PayloadTestSig34, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-engine-payload.h b/framework/src/suricata/src/detect-engine-payload.h deleted file mode 100644 index d6220b18..00000000 --- a/framework/src/suricata/src/detect-engine-payload.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_PAYLOAD_H__ -#define __DETECT_ENGINE_PAYLOAD_H__ - -int DetectEngineInspectPacketPayload(DetectEngineCtx *, - DetectEngineThreadCtx *, Signature *, Flow *, Packet *); -int DetectEngineInspectStreamPayload(DetectEngineCtx *, - DetectEngineThreadCtx *, Signature *, Flow *, - uint8_t *, uint32_t); - -void PayloadRegisterTests(void); - -#endif /* __DETECT_ENGINE_PAYLOAD_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-port.c b/framework/src/suricata/src/detect-engine-port.c deleted file mode 100644 index 6d3d5208..00000000 --- a/framework/src/suricata/src/detect-engine-port.c +++ /dev/null @@ -1,2850 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Ports part of the detection engine. - * - * \todo move this out of the detection plugin structure - * \todo more unittesting - * - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "flow-var.h" - -#include "util-cidr.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-rule-vars.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "detect-engine-siggroup.h" -#include "detect-engine-port.h" - -#include "conf.h" -#include "util-debug.h" -#include "util-error.h" - -#include "pkt-var.h" -#include "host.h" -#include "util-profiling.h" - -static int DetectPortCutNot(DetectPort *, DetectPort **); -static int DetectPortCut(DetectEngineCtx *, DetectPort *, DetectPort *, - DetectPort **); -DetectPort *PortParse(char *str); -int DetectPortIsValidRange(char *); - -/** Memory usage counters */ -static uint32_t detect_port_memory = 0; -static uint32_t detect_port_init_cnt = 0; -static uint32_t detect_port_free_cnt = 0; - -/** - * \brief Alloc a DetectPort structure and update counters - * - * \retval sgh Pointer to the newly created DetectPort on success; or NULL in - * case of error. - */ -DetectPort *DetectPortInit(void) -{ - DetectPort *dp = SCMalloc(sizeof(DetectPort)); - if (unlikely(dp == NULL)) - return NULL; - memset(dp, 0, sizeof(DetectPort)); - - detect_port_memory += sizeof(DetectPort); - detect_port_init_cnt++; - - return dp; -} - -/** - * \brief Free a DetectPort and its members - * - * \param dp Pointer to the DetectPort that has to be freed. - */ -void DetectPortFree(DetectPort *dp) -{ - if (dp == NULL) - return; - - /* only free the head if we have the original */ - if (dp->sh != NULL && !(dp->flags & PORT_SIGGROUPHEAD_COPY)) { - SigGroupHeadFree(dp->sh); - } - dp->sh = NULL; - - if (dp->dst_ph != NULL && !(dp->flags & PORT_GROUP_PORTS_COPY)) { - DetectPortCleanupList(dp->dst_ph); - } - dp->dst_ph = NULL; - - //BUG_ON(dp->next != NULL); - - detect_port_memory -= sizeof(DetectPort); - detect_port_free_cnt++; - SCFree(dp); -} - -/** - * \brief Prints Memory statistics of the counters at detect-engine-port.[c,h] - */ -void DetectPortPrintMemory(void) -{ - SCLogDebug(" * Port memory stats (DetectPort %" PRIuMAX "):", - (uintmax_t)sizeof(DetectPort)); - SCLogDebug(" - detect_port_memory %" PRIu32 "", detect_port_memory); - SCLogDebug(" - detect_port_init_cnt %" PRIu32 "", detect_port_init_cnt); - SCLogDebug(" - detect_port_free_cnt %" PRIu32 "", detect_port_free_cnt); - SCLogDebug(" - outstanding ports %" PRIu32 "", - detect_port_init_cnt - detect_port_free_cnt); - SCLogDebug(" * Port memory stats done"); -} - -/** - * \brief Used to see if the exact same portrange exists in the list - * - * \param head Pointer to the DetectPort list head - * \param dp DetectPort to search in the DetectPort list - * - * \retval returns a ptr to the match, or NULL if no match - */ -DetectPort *DetectPortLookup(DetectPort *head, DetectPort *dp) -{ - DetectPort *cur; - - if (head != NULL) { - for (cur = head; cur != NULL; cur = cur->next) { - if (DetectPortCmp(cur, dp) == PORT_EQ) - return cur; - } - } - - return NULL; -} - -/** - * \brief Helper function used to print the list of ports - * present in this DetectPort list. - * - * \param head Pointer to the DetectPort list head - */ -void DetectPortPrintList(DetectPort *head) -{ - DetectPort *cur; - uint16_t cnt = 0; - - SCLogDebug("= list start:"); - if (head != NULL) { - for (cur = head; cur != NULL; cur = cur->next) { - DetectPortPrint(cur); - cnt++; - } - SCLogDebug(" "); - } - SCLogDebug("= list end (cnt %" PRIu32 ")", cnt); -} - -/** - * \brief Free a DetectPort list and each of its members - * - * \param head Pointer to the DetectPort list head - */ -void DetectPortCleanupList (DetectPort *head) -{ - if (head == NULL) - return; - - DetectPort *cur, *next; - - for (cur = head; cur != NULL; ) { - next = cur->next; - cur->next = NULL; - DetectPortFree(cur); - cur = next; - } -} - -/** - * \brief Do a sorted insert, where the top of the list should be the biggest - * port range. - * - * \todo XXX current sorting only works for overlapping ranges - * - * \param head Pointer to the DetectPort list head - * \param dp Pointer to DetectPort to search in the DetectPort list - * \retval 0 if dp is added correctly - */ -int DetectPortAdd(DetectPort **head, DetectPort *dp) -{ - DetectPort *cur, *prev_cur = NULL; - - //SCLogDebug("DetectPortAdd: adding "); DetectPortPrint(ag); SCLogDebug(""); - - if (*head != NULL) { - for (cur = *head; cur != NULL; cur = cur->next) { - prev_cur = cur; - int r = DetectPortCmp(dp,cur); - if (r == PORT_EB) { - /* insert here */ - dp->prev = cur->prev; - dp->next = cur; - - cur->prev = dp; - if (*head == cur) { - *head = dp; - } else { - dp->prev->next = dp; - } - return 0; - } - } - dp->prev = prev_cur; - if (prev_cur != NULL) - prev_cur->next = dp; - } else { - *head = dp; - } - - return 0; -} - -/** - * \brief Copy and insert the new DetectPort, with a copy list of sigs - * - * \param de_ctx Pointer to the current detection engine context - * \param head Pointer to the DetectPort list head - * \param new Pointer to DetectPort to search in the DetectPort list - * - * \retval 0 if dp is added correctly - */ -int DetectPortInsertCopy(DetectEngineCtx *de_ctx, DetectPort **head, - DetectPort *new) -{ - DetectPort *copy = DetectPortCopySingle(de_ctx,new); - if (copy == NULL) - return -1; - - return DetectPortInsert(de_ctx, head, copy); -} - -/** - * \brief function for inserting a port group object. This also makes sure - * SigGroupContainer lists are handled correctly. - * - * \param de_ctx Pointer to the current detection engine context - * \param head Pointer to the DetectPort list head - * \param dp DetectPort to search in the DetectPort list - * - * \retval 1 inserted - * \retval 0 not inserted, memory of new is freed - * \retval -1 error - * */ -int DetectPortInsert(DetectEngineCtx *de_ctx, DetectPort **head, - DetectPort *new) -{ - if (new == NULL) - return 0; - - //BUG_ON(new->next != NULL); - //BUG_ON(new->prev != NULL); - - /* see if it already exists or overlaps with existing ag's */ - if (*head != NULL) { - DetectPort *cur = NULL; - int r = 0; - - for (cur = *head; cur != NULL; cur = cur->next) { - r = DetectPortCmp(new,cur); - BUG_ON(r == PORT_ER); - - /* if so, handle that */ - if (r == PORT_EQ) { - SCLogDebug("PORT_EQ %p %p", cur, new); - /* exact overlap/match */ - if (cur != new) { - SigGroupHeadCopySigs(de_ctx, new->sh, &cur->sh); - cur->cnt += new->cnt; - DetectPortFree(new); - return 0; - } - return 1; - } else if (r == PORT_GT) { - SCLogDebug("PORT_GT (cur->next %p)", cur->next); - /* only add it now if we are bigger than the last - * group. Otherwise we'll handle it later. */ - if (cur->next == NULL) { - SCLogDebug("adding GT"); - /* put in the list */ - new->prev = cur; - cur->next = new; - return 1; - } - } else if (r == PORT_LT) { - SCLogDebug("PORT_LT"); - - /* see if we need to insert the ag anywhere */ - /* put in the list */ - if (cur->prev != NULL) - cur->prev->next = new; - new->prev = cur->prev; - new->next = cur; - cur->prev = new; - - /* update head if required */ - if (*head == cur) { - *head = new; - } - return 1; - - /* alright, those were the simple cases, - * lets handle the more complex ones now */ - - } else { - DetectPort *c = NULL; - r = DetectPortCut(de_ctx, cur, new, &c); - if (r == -1) - goto error; - - r = DetectPortInsert(de_ctx, head, new); - if (r == -1) - goto error; - - if (c != NULL) { - SCLogDebug("inserting C (%p)", c); - if (SCLogDebugEnabled()) { - DetectPortPrint(c); - } - r = DetectPortInsert(de_ctx, head, c); - if (r == -1) - goto error; - } - return 1; - - } - } - - /* head is NULL, so get a group and set head to it */ - } else { - SCLogDebug("setting new head %p", new); - *head = new; - } - - return 1; -error: - /* XXX */ - return -1; -} - -/** - * \brief Function that cuts port groups and merge them - * - * \param de_ctx Pointer to the current detection engine context - * \param a pointer to DetectPort "a" - * \param b pointer to DetectPort "b" - * \param c pointer to DetectPort "c" - * - * \retval 0 ok - * \retval -1 error - * */ -static int DetectPortCut(DetectEngineCtx *de_ctx, DetectPort *a, - DetectPort *b, DetectPort **c) -{ - uint32_t a_port1 = a->port; - uint32_t a_port2 = a->port2; - uint32_t b_port1 = b->port; - uint32_t b_port2 = b->port2; - DetectPort *tmp = NULL; - - /* default to NULL */ - *c = NULL; - - int r = DetectPortCmp(a,b); - BUG_ON(r != PORT_ES && r != PORT_EB && r != PORT_LE && r != PORT_GE); - - /* get a place to temporary put sigs lists */ - tmp = DetectPortInit(); - if (tmp == NULL) { - goto error; - } - memset(tmp, 0, sizeof(DetectPort)); - - /** - * We have 3 parts: [aaa[abab]bbb] - * part a: a_port1 <-> b_port1 - 1 - * part b: b_port1 <-> a_port2 - * part c: a_port2 + 1 <-> b_port2 - */ - if (r == PORT_LE) { - SCLogDebug("cut r == PORT_LE"); - a->port = a_port1; - a->port2 = b_port1 - 1; - - b->port = b_port1; - b->port2 = a_port2; - - DetectPort *tmp_c; - tmp_c = DetectPortInit(); - if (tmp_c == NULL) { - goto error; - } - *c = tmp_c; - - tmp_c->port = a_port2 + 1; - tmp_c->port2 = b_port2; - - SigGroupHeadCopySigs(de_ctx,b->sh,&tmp_c->sh); /* copy old b to c */ - SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh); /* copy a to b */ - - tmp_c->cnt += b->cnt; - b->cnt += a->cnt; - - /** - * We have 3 parts: [bbb[baba]aaa] - * part a: b_port1 <-> a_port1 - 1 - * part b: a_port1 <-> b_port2 - * part c: b_port2 + 1 <-> a_port2 - */ - } else if (r == PORT_GE) { - SCLogDebug("cut r == PORT_GE"); - a->port = b_port1; - a->port2 = a_port1 - 1; - - b->port = a_port1; - b->port2 = b_port2; - - DetectPort *tmp_c; - tmp_c = DetectPortInit(); - if (tmp_c == NULL) { - goto error; - } - *c = tmp_c; - - tmp_c->port = b_port2 + 1; - tmp_c->port2 = a_port2; - - /** - * 'a' gets clean and then 'b' sigs - * 'b' gets clean, then 'a' then 'b' sigs - * 'c' gets 'a' sigs - */ - SigGroupHeadCopySigs(de_ctx,a->sh,&tmp->sh); /* store old a list */ - SigGroupHeadClearSigs(a->sh); /* clean a list */ - SigGroupHeadCopySigs(de_ctx,tmp->sh,&tmp_c->sh); /* copy old b to c */ - SigGroupHeadCopySigs(de_ctx,b->sh,&a->sh); /* copy old b to a */ - SigGroupHeadCopySigs(de_ctx,tmp->sh,&b->sh);/* prepend old a before b */ - - SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */ - - tmp->cnt += a->cnt; - a->cnt = 0; - tmp_c->cnt += tmp->cnt; - a->cnt += b->cnt; - b->cnt += tmp->cnt; - tmp->cnt = 0; - - /** - * We have 2 or three parts: - * - * 2 part: [[abab]bbb] or [bbb[baba]] - * part a: a_port1 <-> a_port2 - * part b: a_port2 + 1 <-> b_port2 - * - * part a: b_port1 <-> a_port1 - 1 - * part b: a_port1 <-> a_port2 - * - * 3 part [bbb[aaa]bbb] - * becomes[aaa[bbb]ccc] - * - * part a: b_port1 <-> a_port1 - 1 - * part b: a_port1 <-> a_port2 - * part c: a_port2 + 1 <-> b_port2 - */ - } else if (r == PORT_ES) { - SCLogDebug("cut r == PORT_ES"); - if (a_port1 == b_port1) { - SCLogDebug("1"); - a->port = a_port1; - a->port2 = a_port2; - - b->port = a_port2 + 1; - b->port2 = b_port2; - - /** 'b' overlaps 'a' so 'a' needs the 'b' sigs */ - SigGroupHeadCopySigs(de_ctx,b->sh,&a->sh); - a->cnt += b->cnt; - - } else if (a_port2 == b_port2) { - SCLogDebug("2"); - a->port = b_port1; - a->port2 = a_port1 - 1; - - b->port = a_port1; - b->port2 = a_port2; - - /* [bbb[baba]] will be transformed into - * [aaa][bbb] - * steps: copy b sigs to tmp - * a overlaps b, so copy a to b - * clear a - * copy tmp to a */ - SigGroupHeadCopySigs(de_ctx,b->sh,&tmp->sh); /* store old a list */ - tmp->cnt = b->cnt; - SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh); - b->cnt += a->cnt; - SigGroupHeadClearSigs(a->sh); /* clean a list */ - SigGroupHeadCopySigs(de_ctx,tmp->sh,&a->sh);/* merge old a with b */ - a->cnt = tmp->cnt; - SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */ - } else { - SCLogDebug("3"); - a->port = b_port1; - a->port2 = a_port1 - 1; - - b->port = a_port1; - b->port2 = a_port2; - - DetectPort *tmp_c; - tmp_c = DetectPortInit(); - if (tmp_c == NULL) { - goto error; - } - *c = tmp_c; - - tmp_c->port = a_port2 + 1; - tmp_c->port2 = b_port2; - - /** - * 'a' gets clean and then 'b' sigs - * 'b' gets clean, then 'a' then 'b' sigs - * 'c' gets 'b' sigs - */ - SigGroupHeadCopySigs(de_ctx,a->sh,&tmp->sh); /* store old a list */ - SigGroupHeadClearSigs(a->sh); /* clean a list */ - SigGroupHeadCopySigs(de_ctx,b->sh,&tmp_c->sh); /* copy old b to c */ - SigGroupHeadCopySigs(de_ctx,b->sh,&a->sh); /* copy old b to a */ - SigGroupHeadCopySigs(de_ctx,tmp->sh,&b->sh);/* merge old a with b */ - - SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */ - - tmp->cnt += a->cnt; - a->cnt = 0; - tmp_c->cnt += b->cnt; - a->cnt += b->cnt; - b->cnt += tmp->cnt; - tmp->cnt = 0; - } - /** - * We have 2 or three parts: - * - * 2 part: [[baba]aaa] or [aaa[abab]] - * part a: b_port1 <-> b_port2 - * part b: b_port2 + 1 <-> a_port2 - * - * part a: a_port1 <-> b_port1 - 1 - * part b: b_port1 <-> b_port2 - * - * 3 part [aaa[bbb]aaa] - * becomes[aaa[bbb]ccc] - * - * part a: a_port1 <-> b_port2 - 1 - * part b: b_port1 <-> b_port2 - * part c: b_port2 + 1 <-> a_port2 - */ - } else if (r == PORT_EB) { - SCLogDebug("cut r == PORT_EB"); - if (a_port1 == b_port1) { - SCLogDebug("1"); - a->port = b_port1; - a->port2 = b_port2; - - b->port = b_port2 + 1; - b->port2 = a_port2; - - /** 'b' overlaps 'a' so 'a' needs the 'b' sigs */ - SigGroupHeadCopySigs(de_ctx,b->sh,&tmp->sh); - SigGroupHeadClearSigs(b->sh); - SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh); - SigGroupHeadCopySigs(de_ctx,tmp->sh,&a->sh); - - SigGroupHeadClearSigs(tmp->sh); - - tmp->cnt += b->cnt; - b->cnt = 0; - b->cnt += a->cnt; - a->cnt += tmp->cnt; - tmp->cnt = 0; - - } else if (a_port2 == b_port2) { - SCLogDebug("2"); - - a->port = a_port1; - a->port2 = b_port1 - 1; - - b->port = b_port1; - b->port2 = b_port2; - - /** 'a' overlaps 'b' so 'b' needs the 'a' sigs */ - SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh); - - b->cnt += a->cnt; - - } else { - SCLogDebug("3"); - a->port = a_port1; - a->port2 = b_port1 - 1; - - b->port = b_port1; - b->port2 = b_port2; - - DetectPort *tmp_c; - tmp_c = DetectPortInit(); - if (tmp_c == NULL) { - goto error; - } - *c = tmp_c; - - tmp_c->port = b_port2 + 1; - tmp_c->port2 = a_port2; - - SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh); - SigGroupHeadCopySigs(de_ctx,a->sh,&tmp_c->sh); - - b->cnt += a->cnt; - tmp_c->cnt += a->cnt; - } - } - - if (tmp != NULL) { - DetectPortFree(tmp); - } - return 0; - -error: - if (tmp != NULL) - DetectPortFree(tmp); - return -1; -} - -/** - * \brief Function that cuts port groups implementing group negation - * - * \param a pointer to DetectPort "a" - * \param b pointer to DetectPort "b" - * - * \retval 0 ok - * \retval -1 error - * */ -static int DetectPortCutNot(DetectPort *a, DetectPort **b) -{ - uint16_t a_port1 = a->port; - uint16_t a_port2 = a->port2; - - /* default to NULL */ - *b = NULL; - - if (a_port1 != 0x0000 && a_port2 != 0xFFFF) { - a->port = 0x0000; - a->port2 = a_port1 - 1; - - DetectPort *tmp_b; - tmp_b = DetectPortInit(); - if (tmp_b == NULL) { - goto error; - } - - tmp_b->port = a_port2 + 1; - tmp_b->port2 = 0xFFFF; - *b = tmp_b; - - } else if (a_port1 == 0x0000 && a_port2 != 0xFFFF) { - a->port = a_port2 + 1; - a->port2 = 0xFFFF; - - } else if (a_port1 != 0x0000 && a_port2 == 0xFFFF) { - a->port = 0x0000; - a->port2 = a_port1 - 1; - } else { - goto error; - } - - return 0; - -error: - return -1; -} - -/** - * \brief Function that compare port groups - * - * \param a pointer to DetectPort "a" - * \param b pointer to DetectPort "b" - * - * \retval PORT_XX (Port enum value, XX is EQ, ES, EB, LE, etc) - * \retval PORT_ER on error - * */ -int DetectPortCmp(DetectPort *a, DetectPort *b) -{ - /* check any */ - if ((a->flags & PORT_FLAG_ANY) && (b->flags & PORT_FLAG_ANY)) - return PORT_EQ; - if ((a->flags & PORT_FLAG_ANY) && !(b->flags & PORT_FLAG_ANY)) - return PORT_LT; - if (!(a->flags & PORT_FLAG_ANY) && (b->flags & PORT_FLAG_ANY)) - return PORT_GT; - - uint16_t a_port1 = a->port; - uint16_t a_port2 = a->port2; - uint16_t b_port1 = b->port; - uint16_t b_port2 = b->port2; - - /* PORT_EQ */ - if (a_port1 == b_port1 && a_port2 == b_port2) { - //SCLogDebug("PORT_EQ"); - return PORT_EQ; - /* PORT_ES */ - } else if (a_port1 >= b_port1 && a_port1 <= b_port2 && a_port2 <= b_port2) { - //SCLogDebug("PORT_ES"); - return PORT_ES; - /* PORT_EB */ - } else if (a_port1 <= b_port1 && a_port2 >= b_port2) { - //SCLogDebug("PORT_EB"); - return PORT_EB; - } else if (a_port1 < b_port1 && a_port2 < b_port2 && a_port2 >= b_port1) { - //SCLogDebug("PORT_LE"); - return PORT_LE; - } else if (a_port1 < b_port1 && a_port2 < b_port2) { - //SCLogDebug("PORT_LT"); - return PORT_LT; - } else if (a_port1 > b_port1 && a_port1 <= b_port2 && a_port2 > b_port2) { - //SCLogDebug("PORT_GE"); - return PORT_GE; - } else if (a_port1 > b_port2) { - //SCLogDebug("PORT_GT"); - return PORT_GT; - } else { - /* should be unreachable */ - BUG_ON(1); - } - - return PORT_ER; -} - -/** - * \brief Function that return a copy of DetectPort src - * - * \param de_ctx Pointer to the current Detection Engine Context - * \param src Pointer to a DetectPort group to copy - * - * \retval Pointer to a DetectPort instance (copy of src) - * \retval NULL on error - * */ -DetectPort *DetectPortCopy(DetectEngineCtx *de_ctx, DetectPort *src) -{ - if (src == NULL) - return NULL; - - DetectPort *dst = DetectPortInit(); - if (dst == NULL) { - goto error; - } - - dst->port = src->port; - dst->port2 = src->port2; - - if (src->next != NULL) { - dst->next = DetectPortCopy(de_ctx, src->next); - if (dst->next != NULL) { - dst->next->prev = dst; - } - } - - return dst; -error: - return NULL; -} - -/** - * \brief Function that return a copy of DetectPort src sigs - * - * \param de_ctx Pointer to the current Detection Engine Context - * \param src Pointer to a DetectPort group to copy - * - * \retval Pointer to a DetectPort instance (copy of src) - * \retval NULL on error - * */ -DetectPort *DetectPortCopySingle(DetectEngineCtx *de_ctx,DetectPort *src) -{ - if (src == NULL) - return NULL; - - DetectPort *dst = DetectPortInit(); - if (dst == NULL) { - goto error; - } - - dst->port = src->port; - dst->port2 = src->port2; - - SigGroupHeadCopySigs(de_ctx,src->sh,&dst->sh); - - return dst; -error: - return NULL; -} - -/** - * \brief Function Match to Match a port against a DetectPort group - * - * \param dp Pointer to DetectPort group where we try to match the port - * \param port To compare/match - * - * \retval 1 if port is in the range (it match) - * \retval 0 if port is not in the range - * */ -int DetectPortMatch(DetectPort *dp, uint16_t port) -{ - if (port >= dp->port && - port <= dp->port2) { - return 1; - } - - return 0; -} - -/** - * \brief Helper function that print the DetectPort info - * \retval none - */ -void DetectPortPrint(DetectPort *dp) -{ - if (dp == NULL) - return; - - if (dp->flags & PORT_FLAG_ANY) { - SCLogDebug("=> port %p: ANY", dp); -// printf("ANY"); - } else { - SCLogDebug("=> port %p %" PRIu32 "-%" PRIu32 "", dp, dp->port, dp->port2); -// printf("%" PRIu32 "-%" PRIu32 "", dp->port, dp->port2); - } -} - -/** - * \brief Function that find the group matching address in a group head - * - * \param dp Pointer to DetectPort group where we try to find the group - * \param port port to search/lookup - * - * \retval Pointer to the DetectPort group of our port if it matched - * \retval NULL if port is not in the list - * */ -DetectPort * -DetectPortLookupGroup(DetectPort *dp, uint16_t port) -{ - DetectPort *p = dp; - - if (dp == NULL) - return NULL; - - for ( ; p != NULL; p = p->next) { - if (DetectPortMatch(p,port) == 1) { - //SCLogDebug("match, port %" PRIu32 ", dp ", port); - //DetectPortPrint(p); SCLogDebug(""); - return p; - } - } - - return NULL; -} - -/** - * \brief Function to join the source group to the target and its members - * - * \param de_ctx Pointer to the current Detection Engine Context - * \param target Pointer to DetectPort group where the source is joined - * \param source Pointer to DetectPort group that will join into the target - * - * \retval -1 on error - * \retval 0 on success - * */ -int DetectPortJoin(DetectEngineCtx *de_ctx, DetectPort *target, - DetectPort *source) -{ - if (target == NULL || source == NULL) - return -1; - - target->cnt += source->cnt; - SigGroupHeadCopySigs(de_ctx,source->sh,&target->sh); - - if (source->port < target->port) - target->port = source->port; - - if (source->port2 > target->port2) - target->port2 = source->port2; - - return 0; -} - -/******************* parsing routines ************************/ - -/** - * \brief Wrapper function that call the internal/real function - * to insert the new DetectPort - * \param head Pointer to the head of the DetectPort group list - * \param new Pointer to the new DetectPort group list - * - * \retval 1 inserted - * \retval 0 not inserted, memory of new is freed - * \retval -1 error - */ -static int DetectPortParseInsert(DetectPort **head, DetectPort *new) -{ - return DetectPortInsert(NULL, head, new); -} - -/** - * \brief Function to parse and insert the string in the DetectPort head list - * - * \param head Pointer to the head of the DetectPort group list - * \param s Pointer to the port string - * - * \retval 0 on success - * \retval -1 on error - */ -static int DetectPortParseInsertString(DetectPort **head, char *s) -{ - DetectPort *ad = NULL, *ad_any = NULL; - int r = 0; - char port_any = FALSE; - - SCLogDebug("head %p, *head %p, s %s", head, *head, s); - - /** parse the address */ - ad = PortParse(s); - if (ad == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT," failed to parse port \"%s\"",s); - return -1; - } - - if (ad->flags & PORT_FLAG_ANY) { - port_any = TRUE; - } - - /** handle the not case, we apply the negation then insert the part(s) */ - if (ad->flags & PORT_FLAG_NOT) { - DetectPort *ad2 = NULL; - - if (DetectPortCutNot(ad, &ad2) < 0) { - goto error; - } - - /** normally a 'not' will result in two ad's unless the 'not' is on the - * start or end of the address space(e.g. 0.0.0.0 or 255.255.255.255) - */ - if (ad2 != NULL) { - if (DetectPortParseInsert(head, ad2) < 0) { - if (ad2 != NULL) SCFree(ad2); - goto error; - } - } - } - - r = DetectPortParseInsert(head, ad); - if (r < 0) - goto error; - - /** if any, insert 0.0.0.0/0 and ::/0 as well */ - if (r == 1 && port_any == TRUE) { - SCLogDebug("inserting 0:65535 as port is \"any\""); - - ad_any = PortParse("0:65535"); - if (ad_any == NULL) - goto error; - - if (DetectPortParseInsert(head, ad_any) < 0) - goto error; - } - - return 0; - -error: - SCLogError(SC_ERR_PORT_PARSE_INSERT_STRING,"DetectPortParseInsertString error"); - if (ad != NULL) - DetectPortCleanupList(ad); - if (ad_any != NULL) - DetectPortCleanupList(ad_any); - return -1; -} - -/** - * \brief Parses a port string and updates the 2 port heads with the - * port groups. - * - * \todo We don't seem to be handling negated cases, like [port,![!port,port]], - * since we pass around negate without keeping a count of ! with depth. - * Can solve this by keeping a count of the negations with depth, so that - * an even no of negations would count as no negation and an odd no of - * negations would count as a negation. - * - * \param gh Pointer to the port group head that should hold port ranges - * that are not negated. - * \param ghn Pointer to the port group head that should hold port ranges - * that are negated. - * \param s Pointer to the character string holding the port to be - * parsed. - * \param negate Flag that indicates if the receieved address string is negated - * or not. 0 if it is not, 1 it it is. - * - * \retval 0 On successfully parsing. - * \retval -1 On failure. - */ -static int DetectPortParseDo(const DetectEngineCtx *de_ctx, - DetectPort **head, DetectPort **nhead, - char *s, int negate) -{ - size_t u = 0; - size_t x = 0; - int o_set = 0, n_set = 0, d_set = 0; - int range = 0; - int depth = 0; - size_t size = strlen(s); - char address[1024] = ""; - char *rule_var_port = NULL; - int r = 0; - - SCLogDebug("head %p, *head %p, negate %d", head, *head, negate); - - for (u = 0, x = 0; u < size && x < sizeof(address); u++) { - address[x] = s[u]; - x++; - - if (s[u] == ':') - range = 1; - - if (range == 1 && s[u] == '!') { - SCLogError(SC_ERR_NEGATED_VALUE_IN_PORT_RANGE,"Can't have a negated value in a range."); - return -1; - } else if (!o_set && s[u] == '!') { - SCLogDebug("negation encountered"); - n_set = 1; - x--; - } else if (s[u] == '[') { - if (!o_set) { - o_set = 1; - x = 0; - } - depth++; - } else if (s[u] == ']') { - if (depth == 1) { - address[x - 1] = '\0'; - SCLogDebug("Parsed port from DetectPortParseDo - %s", address); - x = 0; - - r = DetectPortParseDo(de_ctx, head, nhead, address, negate? negate: n_set); - if (r == -1) - goto error; - - n_set = 0; - } - depth--; - range = 0; - } else if (depth == 0 && s[u] == ',') { - if (o_set == 1) { - o_set = 0; - } else if (d_set == 1) { - char *temp_rule_var_port = NULL, - *alloc_rule_var_port = NULL; - - address[x - 1] = '\0'; - - rule_var_port = SCRuleVarsGetConfVar(de_ctx, address, - SC_RULE_VARS_PORT_GROUPS); - if (rule_var_port == NULL) - goto error; - if (strlen(rule_var_port) == 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "variable %s resolved " - "to nothing. This is likely a misconfiguration. " - "Note that a negated port needs to be quoted, " - "\"!$HTTP_PORTS\" instead of !$HTTP_PORTS. See issue #295.", s); - goto error; - } - temp_rule_var_port = rule_var_port; - if (negate == 1 || n_set == 1) { - alloc_rule_var_port = SCMalloc(strlen(rule_var_port) + 3); - if (unlikely(alloc_rule_var_port == NULL)) - goto error; - snprintf(alloc_rule_var_port, strlen(rule_var_port) + 3, - "[%s]", rule_var_port); - temp_rule_var_port = alloc_rule_var_port; - } - r = DetectPortParseDo(de_ctx, head, nhead, temp_rule_var_port, - (negate + n_set) % 2);//negate? negate: n_set); - if (r == -1) - goto error; - - d_set = 0; - n_set = 0; - if (alloc_rule_var_port != NULL) - SCFree(alloc_rule_var_port); - } else { - address[x - 1] = '\0'; - SCLogDebug("Parsed port from DetectPortParseDo - %s", address); - - if (negate == 0 && n_set == 0) { - r = DetectPortParseInsertString(head, address); - } else { - r = DetectPortParseInsertString(nhead, address); - } - if (r == -1) - goto error; - - n_set = 0; - } - x = 0; - range = 0; - } else if (depth == 0 && s[u] == '$') { - d_set = 1; - } else if (depth == 0 && u == size-1) { - range = 0; - if (x == 1024) { - address[x - 1] = '\0'; - } else { - address[x] = '\0'; - } - SCLogDebug("%s", address); - x = 0; - if (d_set == 1) { - char *temp_rule_var_port = NULL, - *alloc_rule_var_port = NULL; - - rule_var_port = SCRuleVarsGetConfVar(de_ctx, address, - SC_RULE_VARS_PORT_GROUPS); - if (rule_var_port == NULL) - goto error; - if (strlen(rule_var_port) == 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "variable %s resolved " - "to nothing. This is likely a misconfiguration. " - "Note that a negated port needs to be quoted, " - "\"!$HTTP_PORTS\" instead of !$HTTP_PORTS. See issue #295.", s); - goto error; - } - temp_rule_var_port = rule_var_port; - if ((negate + n_set) % 2) { - alloc_rule_var_port = SCMalloc(strlen(rule_var_port) + 3); - if (unlikely(alloc_rule_var_port == NULL)) - goto error; - snprintf(alloc_rule_var_port, strlen(rule_var_port) + 3, - "[%s]", rule_var_port); - temp_rule_var_port = alloc_rule_var_port; - } - r = DetectPortParseDo(de_ctx, head, nhead, temp_rule_var_port, - (negate + n_set) % 2); - if (r == -1) - goto error; - - d_set = 0; - if (alloc_rule_var_port != NULL) - SCFree(alloc_rule_var_port); - } else { - if (!((negate + n_set) % 2)) { - r = DetectPortParseInsertString(head,address); - } else { - r = DetectPortParseInsertString(nhead,address); - } - if (r == -1) - goto error; - } - n_set = 0; - } - } - - if (depth > 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "not every port block was " - "properly closed in \"%s\", %d missing closing brackets (]). " - "Note: problem might be in a variable.", s, depth); - goto error; - } else if (depth < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "not every port block was " - "properly opened in \"%s\", %d missing opening brackets ([). " - "Note: problem might be in a variable.", s, depth*-1); - goto error; - } - - return 0; -error: - return -1; -} - -/** - * \brief Check if the port group list covers the complete port space. - * \retval 0 no - * \retval 1 yes - */ -int DetectPortIsCompletePortSpace(DetectPort *p) -{ - uint16_t next_port = 0; - - if (p == NULL) - return 0; - - if (p->port != 0x0000) - return 0; - - /* if we're ending with 0xFFFF while we know - we started with 0x0000 it's the complete space */ - if (p->port2 == 0xFFFF) - return 1; - - next_port = p->port2 + 1; - p = p->next; - - for ( ; p != NULL; p = p->next) { - if (p->port != next_port) - return 0; - - if (p->port2 == 0xFFFF) - return 1; - - next_port = p->port2 + 1; - } - - return 0; -} - -/** - * \brief Helper function for the parsing process - * - * \param head Pointer to the head of the DetectPort group list - * \param nhead Pointer to the new head of the DetectPort group list - * - * \retval 0 on success - * \retval -1 on error - */ -int DetectPortParseMergeNotPorts(DetectPort **head, DetectPort **nhead) -{ - DetectPort *ad = NULL; - DetectPort *ag, *ag2; - int r = 0; - - /** check if the full port space is negated */ - if (DetectPortIsCompletePortSpace(*nhead) == 1) { - SCLogError(SC_ERR_COMPLETE_PORT_SPACE_NEGATED,"Complete port space is negated"); - goto error; - } - - /** - * step 0: if the head list is empty, but the nhead list isn't - * we have a pure not thingy. In that case we add a 0:65535 - * first. - */ - if (*head == NULL && *nhead != NULL) { - SCLogDebug("inserting 0:65535 into head"); - r = DetectPortParseInsertString(head,"0:65535"); - if (r < 0) { - goto error; - } - } - - /** step 1: insert our ghn members into the gh list */ - for (ag = *nhead; ag != NULL; ag = ag->next) { - /** work with a copy of the ad so we can easily clean up - * the ghn group later. - */ - ad = DetectPortCopy(NULL, ag); - if (ad == NULL) { - goto error; - } - r = DetectPortParseInsert(head, ad); - if (r < 0) { - goto error; - } - ad = NULL; - } - - /** step 2: pull the address blocks that match our 'not' blocks */ - for (ag = *nhead; ag != NULL; ag = ag->next) { - SCLogDebug("ag %p", ag); - DetectPortPrint(ag); - - for (ag2 = *head; ag2 != NULL; ) { - SCLogDebug("ag2 %p", ag2); - DetectPortPrint(ag2); - - r = DetectPortCmp(ag, ag2); - if (r == PORT_EQ || r == PORT_EB) { /* XXX more ??? */ - if (ag2->prev == NULL) { - *head = ag2->next; - } else { - ag2->prev->next = ag2->next; - } - - if (ag2->next != NULL) { - ag2->next->prev = ag2->prev; - } - /** store the next ptr and remove the group */ - DetectPort *next_ag2 = ag2->next; - DetectPortFree(ag2); - ag2 = next_ag2; - } else { - ag2 = ag2->next; - } - } - } - - for (ag2 = *head; ag2 != NULL; ag2 = ag2->next) { - SCLogDebug("ag2 %p", ag2); - DetectPortPrint(ag2); - } - - if (*head == NULL) { - SCLogError(SC_ERR_NO_PORTS_LEFT_AFTER_MERGE,"no ports left after merging ports with negated ports"); - goto error; - } - - return 0; -error: - if (ad != NULL) - DetectPortFree(ad); - return -1; -} - -int DetectPortTestConfVars(void) -{ - SCLogDebug("Testing port conf vars for any misconfigured values"); - - ConfNode *port_vars_node = ConfGetNode("vars.port-groups"); - if (port_vars_node == NULL) { - return 0; - } - - ConfNode *seq_node; - TAILQ_FOREACH(seq_node, &port_vars_node->head, next) { - SCLogDebug("Testing %s - %s\n", seq_node->name, seq_node->val); - - DetectPort *gh = DetectPortInit(); - if (gh == NULL) { - goto error; - } - DetectPort *ghn = NULL; - - if (seq_node->val == NULL) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "Port var \"%s\" probably has a sequence(something " - "in brackets) value set without any quotes. Please " - "quote it using \"..\".", seq_node->name); - DetectPortCleanupList(gh); - goto error; - } - - int r = DetectPortParseDo(NULL, &gh, &ghn, seq_node->val, /* start with negate no */0); - if (r < 0) { - DetectPortCleanupList(gh); - goto error; - } - - if (DetectPortIsCompletePortSpace(ghn)) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "Port var - \"%s\" has the complete Port range negated " - "with it's value \"%s\". Port space range is NIL. " - "Probably have a !any or a port range that supplies " - "a NULL address range", seq_node->name, seq_node->val); - DetectPortCleanupList(gh); - DetectPortCleanupList(ghn); - goto error; - } - - if (gh != NULL) - DetectPortCleanupList(gh); - if (ghn != NULL) - DetectPortCleanupList(ghn); - } - - return 0; - error: - return -1; -} - - -/** - * \brief Function for parsing port strings - * - * \param head Pointer to the head of the DetectPort group list - * \param str Pointer to the port string - * - * \retval 0 on success - * \retval -1 on error - */ -int DetectPortParse(const DetectEngineCtx *de_ctx, - DetectPort **head, char *str) -{ - int r; - - SCLogDebug("Port string to be parsed - str %s", str); - - /* negate port list */ - DetectPort *nhead = NULL; - - r = DetectPortParseDo(de_ctx, head, &nhead, str,/* start with negate no */0); - if (r < 0) - goto error; - - SCLogDebug("head %p %p, nhead %p", head, *head, nhead); - - /* merge the 'not' address groups */ - if (DetectPortParseMergeNotPorts(head, &nhead) < 0) - goto error; - - /* free the temp negate head */ - DetectPortCleanupList(nhead); - return 0; - -error: - DetectPortCleanupList(nhead); - return -1; -} - -/** - * \brief Helper function for parsing port strings - * - * \param str Pointer to the port string - * - * \retval DetectPort pointer of the parse string on success - * \retval NULL on error - */ -DetectPort *PortParse(char *str) -{ - char *port2 = NULL; - DetectPort *dp = NULL; - - char portstr[16]; - strlcpy(portstr, str, sizeof(portstr)); - - dp = DetectPortInit(); - if (dp == NULL) - goto error; - - /* XXX better input validation */ - - /* we dup so we can put a nul-termination in it later */ - char *port = portstr; - - /* handle the negation case */ - if (port[0] == '!') { - dp->flags |= PORT_FLAG_NOT; - port++; - } - - /* see if the address is an ipv4 or ipv6 address */ - if ((port2 = strchr(port, ':')) != NULL) { - /* 80:81 range format */ - port2[0] = '\0'; - port2++; - - if(DetectPortIsValidRange(port)) - dp->port = atoi(port); - else - goto error; - - if (strcmp(port2, "") != 0) { - if (DetectPortIsValidRange(port2)) - dp->port2 = atoi(port2); - else - goto error; - } else { - dp->port2 = 65535; - } - - /* a > b is illegal, a == b is ok */ - if (dp->port > dp->port2) - goto error; - } else { - if (strcasecmp(port,"any") == 0) { - dp->port = 0; - dp->port2 = 65535; - } else if(DetectPortIsValidRange(port)){ - dp->port = dp->port2 = atoi(port); - } else { - goto error; - } - } - - return dp; - -error: - if (dp != NULL) - DetectPortCleanupList(dp); - return NULL; -} - -/** - * \brief Helper function to check if a parsed port is in the valid range - * of available ports - * - * \param str Pointer to the port string - * - * \retval 1 if port is in the valid range - * \retval 0 if invalid - */ -int DetectPortIsValidRange(char *port) -{ - if(atoi(port) >= 0 && atoi(port) <= 65535) - return 1; - else - return 0; -} -/********************** End parsing routines ********************/ - - -/********************* Hash function routines *******************/ -#define PORT_HASH_SIZE 1024 - -/** - * \brief Generate a hash for a DetectPort group - * - * \param ht HashListTable - * \param data Pointer to the DetectPort - * \param datalen sizeof data (not used here atm) - * - * \retval uint32_t the value of the generated hash - */ -uint32_t DetectPortHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - DetectPort *p = (DetectPort *)data; - uint32_t hash = p->port * p->port2; - - return hash % ht->array_size; -} - -/** - * \brief Function that return if the two DetectPort groups are equal or not - * - * \param data1 Pointer to the DetectPort 1 - * \param len1 sizeof data 1 (not used here atm) - * \param data2 Pointer to the DetectPort 2 - * \param len2 sizeof data 2 (not used here atm) - * - * \retval 1 if the DetectPort groups are equal - * \retval 0 if not equal - */ -char DetectPortCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - DetectPort *p1 = (DetectPort *)data1; - DetectPort *p2 = (DetectPort *)data2; - - if (p1->port2 == p2->port2 && p1->port == p2->port && - p1->flags == p2->flags) - return 1; - - return 0; -} - -void DetectPortFreeFunc(void *p) -{ - DetectPort *dp = (DetectPort *)p; - DetectPortFree(dp); -} - -/** - * \brief Function that initialize the HashListTable of destination DetectPort - * - * \param de_ctx Pointer to the current DetectionEngineContext - * - * \retval 0 HashListTable initialization succes - * \retval -1 Error - */ -int DetectPortDpHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->dport_hash_table = HashListTableInit(PORT_HASH_SIZE, - DetectPortHashFunc, DetectPortCompareFunc, DetectPortFreeFunc); - if (de_ctx->dport_hash_table == NULL) - goto error; - - return 0; -error: - return -1; -} - -/** - * \brief Function that free the HashListTable of destination DetectPort - * - * \param de_ctx Pointer to the current DetectionEngineCtx - */ -void DetectPortDpHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->dport_hash_table == NULL) - return; - - HashListTableFree(de_ctx->dport_hash_table); - de_ctx->dport_hash_table = NULL; -} - -/** - * \brief Function that reset the HashListTable of destination DetectPort - * (Free and Initialize it) - * - * \param de_ctx Pointer to the current DetectionEngineCtx - */ -void DetectPortDpHashReset(DetectEngineCtx *de_ctx) -{ - DetectPortDpHashFree(de_ctx); - DetectPortDpHashInit(de_ctx); -} - -/** - * \brief Function that add a destination DetectPort into the hashtable - * - * \param de_ctx Pointer to the current DetectionEngineCtx - * \param p Pointer to the DetectPort to add - */ -int DetectPortDpHashAdd(DetectEngineCtx *de_ctx, DetectPort *p) -{ - return HashListTableAdd(de_ctx->dport_hash_table, (void *)p, 0); -} - -/** - * \brief Function that search a destination DetectPort in the hashtable - * - * \param de_ctx Pointer to the current DetectionEngineCtx - * \param p Pointer to the DetectPort to search - */ -DetectPort *DetectPortDpHashLookup(DetectEngineCtx *de_ctx, DetectPort *p) -{ - DetectPort *rp = HashListTableLookup(de_ctx->dport_hash_table, - (void *)p, 0); - return rp; -} - -/** - * \brief Function that initialize the HashListTable of source DetectPort - * - * \param de_ctx Pointer to the current DetectionEngineContext - * - * \retval 0 HashListTable initialization succes - * \retval -1 Error - */ -int DetectPortSpHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sport_hash_table = HashListTableInit(PORT_HASH_SIZE, - DetectPortHashFunc, DetectPortCompareFunc, DetectPortFreeFunc); - if (de_ctx->sport_hash_table == NULL) - goto error; - - return 0; -error: - return -1; -} - -/** - * \brief Function that free the HashListTable of source DetectPort - * - * \param de_ctx Pointer to the current DetectionEngineCtx - */ -void DetectPortSpHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sport_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sport_hash_table); - de_ctx->sport_hash_table = NULL; -} - -/** - * \brief Function that reset the HashListTable of source DetectPort - * (Free and Initialize it) - * - * \param de_ctx Pointer to the current DetectionEngineCtx - */ -void DetectPortSpHashReset(DetectEngineCtx *de_ctx) -{ - DetectPortSpHashFree(de_ctx); - DetectPortSpHashInit(de_ctx); -} - -/** - * \brief Function that add a source DetectPort into the hashtable - * - * \param de_ctx Pointer to the current DetectionEngineCtx - * \param p Pointer to the DetectPort to add - */ -int DetectPortSpHashAdd(DetectEngineCtx *de_ctx, DetectPort *p) -{ - return HashListTableAdd(de_ctx->sport_hash_table, (void *)p, 0); -} - -/** - * \brief Function that search a source DetectPort in the hashtable - * - * \param de_ctx Pointer to the current DetectionEngineCtx - * \param p Pointer to the DetectPort to search - */ -DetectPort *DetectPortSpHashLookup(DetectEngineCtx *de_ctx, DetectPort *p) -{ - DetectPort *rp = HashListTableLookup(de_ctx->sport_hash_table, - (void *)p, 0); - return rp; -} - -/*---------------------- Unittests -------------------------*/ - -#ifdef UNITTESTS - -/** - * \test Check if a DetectPort is properly allocated - */ -int PortTestParse01 (void) -{ - DetectPort *dd = NULL; - - int r = DetectPortParse(NULL,&dd,"80"); - if (r == 0) { - DetectPortFree(dd); - return 1; - } - - return 0; -} - -/** - * \test Check if two ports are properly allocated in the DetectPort group - */ -int PortTestParse02 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"80"); - if (r == 0) { - r = DetectPortParse(NULL,&dd,"22"); - if (r == 0) { - result = 1; - } - - DetectPortCleanupList(dd); - return result; - } - - return result; -} - -/** - * \test Check if two port ranges are properly allocated in the DetectPort group - */ -int PortTestParse03 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"80:88"); - if (r == 0) { - r = DetectPortParse(NULL,&dd,"85:100"); - if (r == 0) { - result = 1; - } - - DetectPortCleanupList(dd); - - return result; - } - - return result; -} - -/** - * \test Check if a negated port range is properly allocated in the DetectPort - */ -int PortTestParse04 (void) -{ - DetectPort *dd = NULL; - - int r = DetectPortParse(NULL,&dd,"!80:81"); - if (r == 0) { - DetectPortCleanupList(dd); - return 1; - } - - return 0; -} - -/** - * \test Check if a negated port range is properly fragmented in the allowed - * real groups, ex !80:81 should allow 0:79 and 82:65535 - */ -int PortTestParse05 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"!80:81"); - if (r != 0) - goto end; - - if (dd->next == NULL) - goto end; - - if (dd->port != 0 || dd->port2 != 79) - goto end; - - if (dd->next->port != 82 || dd->next->port2 != 65535) - goto end; - - DetectPortCleanupList(dd); - result = 1; -end: - return result; -} - -/** - * \test Check if we copy a DetectPort correctly - */ -int PortTestParse06 (void) -{ - DetectPort *dd = NULL, *copy = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"22"); - if (r != 0) - goto end; - - r = DetectPortParse(NULL,&dd,"80"); - if (r != 0) - goto end; - - r = DetectPortParse(NULL,&dd,"143"); - if (r != 0) - goto end; - - copy = DetectPortCopy(NULL,dd); - if (copy == NULL) - goto end; - - if (DetectPortCmp(dd,copy) != PORT_EQ) - goto end; - - if (copy->next == NULL) - goto end; - - if (DetectPortCmp(dd->next,copy->next) != PORT_EQ) - goto end; - - if (copy->next->next == NULL) - goto end; - - if (DetectPortCmp(dd->next->next,copy->next->next) != PORT_EQ) - goto end; - - if (copy->port != 22 || copy->next->port != 80 || - copy->next->next->port != 143) - goto end; - - result = 1; - -end: - if (copy != NULL) - DetectPortCleanupList(copy); - if (dd != NULL) - DetectPortCleanupList(dd); - return result; -} - -/** - * \test Check if a negated port range is properly fragmented in the allowed - * real groups - */ -int PortTestParse07 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"!21:902"); - if (r != 0) - goto end; - - if (dd->next == NULL) - goto end; - - if (dd->port != 0 || dd->port2 != 20) - goto end; - - if (dd->next->port != 903 || dd->next->port2 != 65535) - goto end; - - DetectPortCleanupList(dd); - result = 1; -end: - return result; -} - -/** - * \test Check if we dont allow invalid port range specification - */ -int PortTestParse08 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"[80:!80]"); - if (r == 0) - goto end; - - DetectPortCleanupList(dd); - result = 1; -end: - return result; -} - -/** - * \test Check if we autocomplete correctly an open range - */ -int PortTestParse09 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"1024:"); - if (r != 0) - goto end; - - if (dd == NULL) - goto end; - - if (dd->port != 1024 || dd->port2 != 0xffff) - goto end; - - DetectPortCleanupList(dd); - result = 1; -end: - return result; -} - -/** - * \test Test we don't allow a port that is too big - */ -int PortTestParse10 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"77777777777777777777777777777777777777777777"); - if (r != 0) { - result = 1 ; - goto end; - } - - DetectPortFree(dd); - -end: - return result; -} - -/** - * \test Test second port of range being too big - */ -int PortTestParse11 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"1024:65536"); - if (r != 0) { - result = 1 ; - goto end; - } - - DetectPortFree(dd); - -end: - return result; -} - -/** - * \test Test second port of range being just right - */ -int PortTestParse12 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"1024:65535"); - if (r != 0) { - goto end; - } - - DetectPortFree(dd); - - result = 1 ; -end: - return result; -} - -/** - * \test Test first port of range being too big - */ -int PortTestParse13 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"65536:65535"); - if (r != 0) { - result = 1 ; - goto end; - } - - DetectPortFree(dd); - -end: - return result; -} - -/** - * \test Test merging port groups - */ -int PortTestParse14 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParseInsertString(&dd, "0:100"); - if (r != 0) - goto end; - r = DetectPortParseInsertString(&dd, "1000:65535"); - if (r != 0 || dd->next == NULL) - goto end; - - result = 1; - result &= (dd->port == 0) ? 1 : 0; - result &= (dd->port2 == 100) ? 1 : 0; - result &= (dd->next->port == 1000) ? 1 : 0; - result &= (dd->next->port2 == 65535) ? 1 : 0; - - DetectPortFree(dd); - -end: - return result; -} - -/** - * \test Test merging negated port groups - */ -int PortTestParse15 (void) -{ - DetectPort *dd = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"![0:100,1000:3000]"); - if (r != 0 || dd->next == NULL) - goto end; - - result = 1; - result &= (dd->port == 101) ? 1 : 0; - result &= (dd->port2 == 999) ? 1 : 0; - result &= (dd->next->port == 3001) ? 1 : 0; - result &= (dd->next->port2 == 65535) ? 1 : 0; - - DetectPortFree(dd); - -end: - return result; -} - -/** - * \test Test parse, copy and cmp functions - */ -int PortTestParse16 (void) -{ - DetectPort *dd = NULL, *copy = NULL; - int result = 0; - - int r = DetectPortParse(NULL,&dd,"22"); - if (r != 0) - goto end; - - r = DetectPortParse(NULL,&dd,"80"); - if (r != 0) - goto end; - - r = DetectPortParse(NULL,&dd,"143"); - if (r != 0) - goto end; - - copy = DetectPortCopy(NULL,dd); - if (copy == NULL) - goto end; - - if (DetectPortCmp(dd,copy) != PORT_EQ) - goto end; - - if (copy->next == NULL) - goto end; - - if (DetectPortCmp(dd->next,copy->next) != PORT_EQ) - goto end; - - if (copy->next->next == NULL) - goto end; - - if (DetectPortCmp(dd->next->next,copy->next->next) != PORT_EQ) - goto end; - - if (copy->port != 22 || copy->next->port != 80 || copy->next->next->port != 143) - goto end; - - if (copy->next->prev != copy) - goto end; - - result = 1; - -end: - if (copy != NULL) - DetectPortCleanupList(copy); - if (dd != NULL) - DetectPortCleanupList(dd); - return result; -} -/** - * \test Test general functions - */ -int PortTestFunctions01(void) -{ - DetectPort *head = NULL; - DetectPort *dp1= NULL; - int result = 0; - - /* Parse */ - int r = DetectPortParse(NULL,&head,"![0:100,1000:65535]"); - if (r != 0 || head->next != NULL) - goto end; - - /* We should have only one DetectPort */ - if (!(head->port == 101)) - goto end; - if (!(head->port2 == 999)) - goto end; - if (!(head->next == NULL)) - goto end; - - r = DetectPortParse(NULL, &dp1,"2000:3000"); - if (r != 0 || dp1->next != NULL) - goto end; - if (!(dp1->port == 2000)) - goto end; - if (!(dp1->port2 == 3000)) - goto end; - - /* Add */ - r = DetectPortAdd(&head, dp1); - if (r != 0 || head->next == NULL) - goto end; - if (!(head->port == 101)) - goto end; - if (!(head->port2 == 999)) - goto end; - if (!(head->next->port == 2000)) - goto end; - if (!(head->next->port2 == 3000)) - goto end; - - /* Match */ - if (!DetectPortMatch(head, 150)) - goto end; - if (DetectPortMatch(head->next, 1500)) - goto end; - if ((DetectPortMatch(head, 3500))) - goto end; - if ((DetectPortMatch(head, 50))) - goto end; - - result = 1; -end: - if (dp1 != NULL) - DetectPortFree(dp1); - if (head != NULL) - DetectPortFree(head); - return result; -} - -/** - * \test Test general functions - */ -int PortTestFunctions02(void) -{ - DetectPort *head = NULL; - DetectPort *dp1= NULL; - DetectPort *dp2= NULL; - int result = 0; - - /* Parse */ - int r = DetectPortParse(NULL,&head, "![0:100,1000:65535]"); - if (r != 0 || head->next != NULL) - goto end; - - r = DetectPortParse(NULL, &dp1, "!200:300"); - if (r != 0 || dp1->next == NULL) - goto end; - - /* Merge Nots */ - r = DetectPortParseMergeNotPorts(&head, &dp1); - if (r != 0 || head->next != NULL) - goto end; - - r = DetectPortParse(NULL, &dp2, "!100:500"); - if (r != 0 || dp2->next == NULL) - goto end; - - /* Merge Nots */ - r = DetectPortParseMergeNotPorts(&head, &dp2); - if (r != 0 || head->next != NULL) - goto end; - - if (!(head->port == 200)) - goto end; - if (!(head->port2 == 300)) - goto end; - - result = 1; - -end: - if (dp1 != NULL) - DetectPortFree(dp1); - if (dp2 != NULL) - DetectPortFree(dp2); - if (head != NULL) - DetectPortFree(head); - return result; -} - -/** - * \test Test general functions - */ -int PortTestFunctions03(void) -{ - DetectPort *dp1= NULL; - DetectPort *dp2= NULL; - DetectPort *dp3= NULL; - int result = 0; - - int r = DetectPortParse(NULL, &dp1, "200:300"); - if (r != 0) - goto end; - - r = DetectPortParse(NULL, &dp2, "250:300"); - if (r != 0) - goto end; - - /* Cut */ - DetectPortCut(NULL, dp1, dp2, &dp3); - if (r != 0) - goto end; - - if (!(dp1->port == 200)) - goto end; - if (!(dp1->port2 == 249)) - goto end; - if (!(dp2->port == 250)) - goto end; - if (!(dp2->port2 == 300)) - goto end; - - dp1->port = 0; - dp1->port2 = 500; - dp2->port = 250; - dp2->port2 = 750; - - /* Cut */ - DetectPortCut(NULL, dp1, dp2, &dp3); - if (r != 0) - goto end; - if (!(dp1->port == 0)) - goto end; - if (!(dp1->port2 == 249)) - goto end; - if (!(dp2->port == 250)) - goto end; - if (!(dp2->port2 == 500)) - goto end; - if (!(dp3->port == 501)) - goto end; - if (!(dp3->port2 == 750)) - goto end; - - result = 1; - -end: - if (dp1 != NULL) - DetectPortFree(dp1); - if (dp2 != NULL) - DetectPortFree(dp2); - if (dp3 != NULL) - DetectPortFree(dp3); - return result; -} - -/** - * \test Test general functions - */ -int PortTestFunctions04(void) -{ - DetectPort *dp1= NULL; - DetectPort *dp2= NULL; - int result = 0; - - int r = DetectPortParse(NULL, &dp1, "200:300"); - if (r != 0) - goto end; - - dp2 = DetectPortInit(); - - /* Cut Not */ - DetectPortCutNot(dp1, &dp2); - if (r != 0) - goto end; - - if (!(dp1->port == 0)) - goto end; - if (!(dp1->port2 == 199)) - goto end; - if (!(dp2->port == 301)) - goto end; - if (!(dp2->port2 == 65535)) - goto end; - - result = 1; -end: - if (dp1 != NULL) - DetectPortFree(dp1); - if (dp2 != NULL) - DetectPortFree(dp2); - return result; -} - -/** - * \test Test general functions - */ -static int PortTestFunctions05(void) -{ - DetectPort *dp1 = NULL; - DetectPort *dp2 = NULL; - DetectPort *dp3 = NULL; - int result = 0; - int r = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature s[2]; - memset(s,0x00,sizeof(s)); - - s[0].num = 0; - s[1].num = 1; - - r = DetectPortParse(NULL, &dp1, "1024:65535"); - if (r != 0) { - printf("r != 0 but %d: ", r); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &dp1->sh, &s[0]); - - r = DetectPortParse(NULL, &dp2, "any"); - if (r != 0) { - printf("r != 0 but %d: ", r); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &dp2->sh, &s[1]); - - SCLogDebug("dp1"); - DetectPortPrint(dp1); - SCLogDebug("dp2"); - DetectPortPrint(dp2); - - DetectPortInsert(de_ctx, &dp3, dp1); - DetectPortInsert(de_ctx, &dp3, dp2); - - if (dp3 == NULL) - goto end; - - SCLogDebug("dp3"); - DetectPort *x = dp3; - for ( ; x != NULL; x = x->next) { - DetectPortPrint(x); - //SigGroupHeadPrintSigs(de_ctx, x->sh); - } - - DetectPort *one = dp3; - DetectPort *two = dp3->next; - - int sig = 0; - if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'two', but it shouldn't: ", sig); - goto end; - } - - result = 1; -end: - if (dp1 != NULL) - DetectPortFree(dp1); - if (dp2 != NULL) - DetectPortFree(dp2); - return result; -} - -/** - * \test Test general functions - */ -static int PortTestFunctions06(void) -{ - DetectPort *dp1 = NULL; - DetectPort *dp2 = NULL; - DetectPort *dp3 = NULL; - int result = 0; - int r = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature s[2]; - memset(s,0x00,sizeof(s)); - - s[0].num = 0; - s[1].num = 1; - - r = DetectPortParse(NULL, &dp1, "1024:65535"); - if (r != 0) { - printf("r != 0 but %d: ", r); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &dp1->sh, &s[0]); - - r = DetectPortParse(NULL, &dp2, "any"); - if (r != 0) { - printf("r != 0 but %d: ", r); - goto end; - } - SigGroupHeadAppendSig(de_ctx, &dp2->sh, &s[1]); - - SCLogDebug("dp1"); - DetectPortPrint(dp1); - SCLogDebug("dp2"); - DetectPortPrint(dp2); - - DetectPortInsert(de_ctx, &dp3, dp2); - DetectPortInsert(de_ctx, &dp3, dp1); - - if (dp3 == NULL) - goto end; - - SCLogDebug("dp3"); - DetectPort *x = dp3; - for ( ; x != NULL; x = x->next) { - DetectPortPrint(x); - //SigGroupHeadPrintSigs(de_ctx, x->sh); - } - - DetectPort *one = dp3; - DetectPort *two = dp3->next; - - int sig = 0; - if ((one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(one->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'one', but it shouldn't: ", sig); - goto end; - } - sig = 1; - if (!(two->sh->init->sig_array[sig / 8] & (1 << (sig % 8)))) { - printf("sig %d part of 'two', but it shouldn't: ", sig); - goto end; - } - - result = 1; -end: - if (dp1 != NULL) - DetectPortFree(dp1); - if (dp2 != NULL) - DetectPortFree(dp2); - return result; -} - -/** - * \test Test packet Matches - * \param raw_eth_pkt pointer to the ethernet packet - * \param pktsize size of the packet - * \param sig pointer to the signature to test - * \param sid sid number of the signature - * \retval return 1 if match - * \retval return 0 if not - */ -int PortTestMatchReal(uint8_t *raw_eth_pkt, uint16_t pktsize, char *sig, - uint32_t sid) -{ - int result = 0; - FlowInitConfig(FLOW_QUIET); - Packet *p = UTHBuildPacketFromEth(raw_eth_pkt, pktsize); - result = UTHPacketMatchSig(p, sig); - PACKET_RECYCLE(p); - FlowShutdown(); - return result; -} - -/** - * \brief Wrapper for PortTestMatchReal - */ -int PortTestMatchRealWrp(char *sig, uint32_t sid) -{ - /* Real HTTP packeth doing a GET method - * tcp.sport=47370 tcp.dport=80 - * ip.src=192.168.28.131 ip.dst=192.168.1.1 - */ - uint8_t raw_eth_pkt[] = { - 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c, - 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00, - 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06, - 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8, - 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2, - 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18, - 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45, - 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50, - 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f, - 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e, - 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d, - 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67, - 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a, - 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30, - 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55, - 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20, - 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20, - 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72, - 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e, - 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b, - 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39, - 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75, - 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34, - 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79, - 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f, - 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34, - 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74, - 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68, - 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c, - 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f, - 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d, - 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63, - 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d, - 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c, - 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e, - 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70, - 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61, - 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75, - 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30, - 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65, - 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64, - 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69, - 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74, - 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70, - 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65, - 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38, - 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74, - 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e, - 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e, - 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d, - 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33, - 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e, - 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20, - 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69, - 0x76,0x65,0x0d,0x0a,0x0d,0x0a }; - /* end raw_eth_pkt */ - - return PortTestMatchReal(raw_eth_pkt, (uint16_t)sizeof(raw_eth_pkt), - sig, sid); -} - -/** - * \test Check if we match a dest port - */ -int PortTestMatchReal01() -{ - /* tcp.sport=47370 tcp.dport=80 */ - char *sig = "alert tcp any any -> any 80 (msg:\"Nothing..\"; content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we match a source port - */ -int PortTestMatchReal02() -{ - char *sig = "alert tcp any 47370 -> any any (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we match both of them - */ -int PortTestMatchReal03() -{ - char *sig = "alert tcp any 47370 -> any 80 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we negate dest ports correctly - */ -int PortTestMatchReal04() -{ - char *sig = "alert tcp any any -> any !80 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0; -} - -/** - * \test Check if we negate source ports correctly - */ -int PortTestMatchReal05() -{ - char *sig = "alert tcp any !47370 -> any any (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0; -} - -/** - * \test Check if we negate both ports correctly - */ -int PortTestMatchReal06() -{ - char *sig = "alert tcp any !47370 -> any !80 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0; -} - -/** - * \test Check if we match a dest port range - */ -int PortTestMatchReal07() -{ - char *sig = "alert tcp any any -> any 70:100 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we match a source port range - */ -int PortTestMatchReal08() -{ - char *sig = "alert tcp any 47000:50000 -> any any (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we match both port ranges - */ -int PortTestMatchReal09() -{ - char *sig = "alert tcp any 47000:50000 -> any 70:100 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we negate a dest port range - */ -int PortTestMatchReal10() -{ - char *sig = "alert tcp any any -> any !70:100 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0; -} - -/** - * \test Check if we negate a source port range - */ -int PortTestMatchReal11() -{ - char *sig = "alert tcp any !47000:50000 -> any any (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0; -} - -/** - * \test Check if we negate both port ranges - */ -int PortTestMatchReal12() -{ - char *sig = "alert tcp any !47000:50000 -> any !70:100 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0; -} - -/** - * \test Check if we autocomplete ranges correctly - */ -int PortTestMatchReal13() -{ - char *sig = "alert tcp any 47000:50000 -> any !81: (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we autocomplete ranges correctly - */ -int PortTestMatchReal14() -{ - char *sig = "alert tcp any !48000:50000 -> any :100 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we autocomplete ranges correctly - */ -int PortTestMatchReal15() -{ - char *sig = "alert tcp any :50000 -> any 81:100 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0; -} - -/** - * \test Check if we separate ranges correctly - */ -int PortTestMatchReal16() -{ - char *sig = "alert tcp any 100: -> any ![0:79,81:65535] (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we separate ranges correctly - */ -int PortTestMatchReal17() -{ - char *sig = "alert tcp any ![0:39999,48000:50000] -> any ![0:80,82:65535] " - "(msg:\"Nothing..\"; content:\"GET\"; sid:1;)"; - return (PortTestMatchRealWrp(sig, 1) == 0)? 1 : 0; -} - -/** - * \test Check if we separate ranges correctly - */ -int PortTestMatchReal18() -{ - char *sig = "alert tcp any ![0:39999,48000:50000] -> any 80 (msg:\"Nothing" - " at all\"; content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -/** - * \test Check if we separate ranges correctly - */ -int PortTestMatchReal19() -{ - char *sig = "alert tcp any any -> any 80 (msg:\"Nothing..\";" - " content:\"GET\"; sid:1;)"; - return PortTestMatchRealWrp(sig, 1); -} - -static int PortTestMatchDoubleNegation(void) -{ - int result = 0; - DetectPort *head = NULL, *nhead = NULL; - - if (DetectPortParseDo(NULL, &head, &nhead, "![!80]", 0) == -1) - return result; - - result = (head != NULL); - result = (nhead == NULL); - - return result; -} - -#endif /* UNITTESTS */ - -void DetectPortTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("PortTestParse01", PortTestParse01, 1); - UtRegisterTest("PortTestParse02", PortTestParse02, 1); - UtRegisterTest("PortTestParse03", PortTestParse03, 1); - UtRegisterTest("PortTestParse04", PortTestParse04, 1); - UtRegisterTest("PortTestParse05", PortTestParse05, 1); - UtRegisterTest("PortTestParse06", PortTestParse06, 1); - UtRegisterTest("PortTestParse07", PortTestParse07, 1); - UtRegisterTest("PortTestParse08", PortTestParse08, 1); - UtRegisterTest("PortTestParse09", PortTestParse09, 1); - UtRegisterTest("PortTestParse10", PortTestParse10, 1); - UtRegisterTest("PortTestParse11", PortTestParse11, 1); - UtRegisterTest("PortTestParse12", PortTestParse12, 1); - UtRegisterTest("PortTestParse13", PortTestParse13, 1); - UtRegisterTest("PortTestParse14", PortTestParse14, 1); - UtRegisterTest("PortTestParse15", PortTestParse15, 1); - UtRegisterTest("PortTestParse16", PortTestParse16, 1); - UtRegisterTest("PortTestFunctions01", PortTestFunctions01, 1); - UtRegisterTest("PortTestFunctions02", PortTestFunctions02, 1); - UtRegisterTest("PortTestFunctions03", PortTestFunctions03, 1); - UtRegisterTest("PortTestFunctions04", PortTestFunctions04, 1); - UtRegisterTest("PortTestFunctions05", PortTestFunctions05, 1); - UtRegisterTest("PortTestFunctions06", PortTestFunctions06, 1); - UtRegisterTest("PortTestMatchReal01", PortTestMatchReal01, 1); - UtRegisterTest("PortTestMatchReal02", PortTestMatchReal02, 1); - UtRegisterTest("PortTestMatchReal03", PortTestMatchReal03, 1); - UtRegisterTest("PortTestMatchReal04", PortTestMatchReal04, 1); - UtRegisterTest("PortTestMatchReal05", PortTestMatchReal05, 1); - UtRegisterTest("PortTestMatchReal06", PortTestMatchReal06, 1); - UtRegisterTest("PortTestMatchReal07", PortTestMatchReal07, 1); - UtRegisterTest("PortTestMatchReal08", PortTestMatchReal08, 1); - UtRegisterTest("PortTestMatchReal09", PortTestMatchReal09, 1); - UtRegisterTest("PortTestMatchReal10", PortTestMatchReal10, 1); - UtRegisterTest("PortTestMatchReal11", PortTestMatchReal11, 1); - UtRegisterTest("PortTestMatchReal12", PortTestMatchReal12, 1); - UtRegisterTest("PortTestMatchReal13", PortTestMatchReal13, 1); - UtRegisterTest("PortTestMatchReal14", PortTestMatchReal14, 1); - UtRegisterTest("PortTestMatchReal15", PortTestMatchReal15, 1); - UtRegisterTest("PortTestMatchReal16", PortTestMatchReal16, 1); - UtRegisterTest("PortTestMatchReal17", PortTestMatchReal17, 1); - UtRegisterTest("PortTestMatchReal18", PortTestMatchReal18, 1); - UtRegisterTest("PortTestMatchReal19", - PortTestMatchReal19, 1); - UtRegisterTest("PortTestMatchDoubleNegation", PortTestMatchDoubleNegation, 1); - - -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-engine-port.h b/framework/src/suricata/src/detect-engine-port.h deleted file mode 100644 index e23c1e47..00000000 --- a/framework/src/suricata/src/detect-engine-port.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_PORT_H__ -#define __DETECT_PORT_H__ - -/* prototypes */ -int DetectPortParse(const DetectEngineCtx *, DetectPort **head, char *str); - -DetectPort *DetectPortCopy(DetectEngineCtx *, DetectPort *); -DetectPort *DetectPortCopySingle(DetectEngineCtx *, DetectPort *); -int DetectPortInsertCopy(DetectEngineCtx *,DetectPort **, DetectPort *); -int DetectPortInsert(DetectEngineCtx *,DetectPort **, DetectPort *); -void DetectPortCleanupList (DetectPort *head); - -DetectPort *DetectPortLookup(DetectPort *head, DetectPort *dp); -int DetectPortAdd(DetectPort **head, DetectPort *dp); - -DetectPort *DetectPortLookupGroup(DetectPort *dp, uint16_t port); - -void DetectPortPrintMemory(void); - -DetectPort *DetectPortDpHashLookup(DetectEngineCtx *, DetectPort *); -DetectPort *DetectPortDpHashGetListPtr(DetectEngineCtx *); -int DetectPortDpHashInit(DetectEngineCtx *); -void DetectPortDpHashFree(DetectEngineCtx *); -int DetectPortDpHashAdd(DetectEngineCtx *, DetectPort *); -void DetectPortDpHashReset(DetectEngineCtx *); - -DetectPort *DetectPortSpHashLookup(DetectEngineCtx *, DetectPort *); -int DetectPortSpHashInit(DetectEngineCtx *); -void DetectPortSpHashFree(DetectEngineCtx *); -int DetectPortSpHashAdd(DetectEngineCtx *, DetectPort *); -void DetectPortSpHashReset(DetectEngineCtx *); - -int DetectPortJoin(DetectEngineCtx *,DetectPort *target, DetectPort *source); - -void DetectPortPrint(DetectPort *); -void DetectPortPrintList(DetectPort *head); -int DetectPortCmp(DetectPort *, DetectPort *); -void DetectPortFree(DetectPort *); - -int DetectPortTestConfVars(void); - -void DetectPortTests(void); - -#endif /* __DETECT_PORT_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-proto.c b/framework/src/suricata/src/detect-engine-proto.c deleted file mode 100644 index cacaeee3..00000000 --- a/framework/src/suricata/src/detect-engine-proto.c +++ /dev/null @@ -1,627 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Proto part of the detection engine. - * - * \todo move this out of the detection plugin structure - */ - -#include "suricata-common.h" - -#include "decode.h" -#include "detect.h" - -#include "app-layer-parser.h" - -#include "flow-util.h" -#include "flow-var.h" - -#include "detect-engine-siggroup.h" -#include "detect-engine-state.h" - -#include "util-cidr.h" -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -/** - * \brief Function to initialize the protocol detection and - * allocate memory to the DetectProto structure. - * - * \retval DetectProto instance pointer if successful otherwise NULL - */ - -DetectProto *DetectProtoInit(void) -{ - DetectProto *dp = SCMalloc(sizeof(DetectProto)); - if (unlikely(dp == NULL)) - return NULL; - memset(dp,0,sizeof(DetectProto)); - - return dp; -} - -/** - * \brief Free a DetectProto object - * - * \param dp Pointer to the DetectProto instance to be freed - */ -void DetectProtoFree(DetectProto *dp) -{ - if (dp == NULL) - return; - - SCFree(dp); -} - -/** - * \brief Parses a protocol sent as a string. - * - * \param dp Pointer to the DetectProto instance which will be updated with the - * incoming protocol information. - * \param str Pointer to the string containing the protocol name. - * - * \retval >=0 If proto is detected, -1 otherwise. - */ -int DetectProtoParse(DetectProto *dp, char *str) -{ - if (strcasecmp(str, "tcp") == 0) { - dp->proto[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8); - SCLogDebug("TCP protocol detected"); - } else if (strcasecmp(str, "tcp-pkt") == 0) { - dp->proto[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8); - SCLogDebug("TCP protocol detected, packets only"); - dp->flags |= DETECT_PROTO_ONLY_PKT; - } else if (strcasecmp(str, "tcp-stream") == 0) { - dp->proto[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8); - SCLogDebug("TCP protocol detected, stream only"); - dp->flags |= DETECT_PROTO_ONLY_STREAM; - } else if (strcasecmp(str, "udp") == 0) { - dp->proto[IPPROTO_UDP / 8] |= 1 << (IPPROTO_UDP % 8); - SCLogDebug("UDP protocol detected"); - } else if (strcasecmp(str, "icmpv4") == 0) { - dp->proto[IPPROTO_ICMP / 8] |= 1 << (IPPROTO_ICMP % 8); - SCLogDebug("ICMPv4 protocol detected"); - } else if (strcasecmp(str, "icmpv6") == 0) { - dp->proto[IPPROTO_ICMPV6 / 8] |= 1 << (IPPROTO_ICMPV6 % 8); - SCLogDebug("ICMPv6 protocol detected"); - } else if (strcasecmp(str, "icmp") == 0) { - dp->proto[IPPROTO_ICMP / 8] |= 1 << (IPPROTO_ICMP % 8); - dp->proto[IPPROTO_ICMPV6 / 8] |= 1 << (IPPROTO_ICMPV6 % 8); - SCLogDebug("ICMP protocol detected, sig applies both to ICMPv4 and ICMPv6"); - } else if (strcasecmp(str, "sctp") == 0) { - dp->proto[IPPROTO_SCTP / 8] |= 1 << (IPPROTO_SCTP % 8); - SCLogDebug("SCTP protocol detected"); - } else if (strcasecmp(str,"ipv4") == 0 || - strcasecmp(str,"ip4") == 0 ) { - dp->flags |= (DETECT_PROTO_IPV4 | DETECT_PROTO_ANY); - memset(dp->proto, 0xff, sizeof(dp->proto)); - SCLogDebug("IPv4 protocol detected"); - } else if (strcasecmp(str,"ipv6") == 0 || - strcasecmp(str,"ip6") == 0 ) { - dp->flags |= (DETECT_PROTO_IPV6 | DETECT_PROTO_ANY); - memset(dp->proto, 0xff, sizeof(dp->proto)); - SCLogDebug("IPv6 protocol detected"); - } else if (strcasecmp(str,"ip") == 0 || - strcasecmp(str,"pkthdr") == 0) { - /* Proto "ip" is treated as an "any" */ - dp->flags |= DETECT_PROTO_ANY; - memset(dp->proto, 0xff, sizeof(dp->proto)); - SCLogDebug("IP protocol detected"); - } else { - goto error; - - /** \todo are numeric protocols even valid? */ -#if 0 - uint8_t proto_u8; /* Used to avoid sign extension */ - - /* Extract out a 0-256 value with validation checks */ - if (ByteExtractStringUint8(&proto_u8, 10, 0, str) == -1) { - // XXX - SCLogDebug("DetectProtoParse: Error in extracting byte string"); - goto error; - } - proto = (int)proto_u8; - - /* Proto 0 is the same as "ip" above */ - if (proto == IPPROTO_IP) { - dp->flags |= DETECT_PROTO_ANY; - } else { - dp->proto[proto / 8] |= 1<<(proto % 8); - } -#endif - } - - return 0; -error: - return -1; -} - -/** \brief see if a DetectProto contains a certain proto - * \param dp detect proto to inspect - * \param proto protocol (such as IPPROTO_TCP) to look for - * \retval 0 protocol not in the set - * \retval 1 protocol is in the set */ -int DetectProtoContainsProto(DetectProto *dp, int proto) -{ - if (dp->flags & DETECT_PROTO_ANY) - return 1; - - if (dp->proto[proto / 8] & (1<<(proto % 8))) - return 1; - - return 0; -} - -/* TESTS */ - -#ifdef UNITTESTS -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-engine-mpm.h" -/** - * \brief this function is used to initialize the detection engine context and - * setup the signature with passed values. - */ -static int DetectProtoInitTest(DetectEngineCtx **de_ctx, Signature **sig, - DetectProto *dp, char *str) -{ - char fullstr[1024]; - int result = 0; - - *de_ctx = NULL; - *sig = NULL; - - if (snprintf(fullstr, 1024, "alert %s any any -> any any (msg:\"DetectProto" - " test\"; sid:1;)", str) >= 1024) - { - goto end; - } - - *de_ctx = DetectEngineCtxInit(); - if (*de_ctx == NULL) { - goto end; - } - - (*de_ctx)->flags |= DE_QUIET; - - (*de_ctx)->sig_list = SigInit(*de_ctx, fullstr); - if ((*de_ctx)->sig_list == NULL) { - goto end; - } - - *sig = (*de_ctx)->sig_list; - - if (DetectProtoParse(dp, str) < 0) - goto end; - - result = 1; - -end: - return result; -} - -/** - * \test ProtoTestParse01 is a test to make sure that we parse the - * protocol correctly, when given valid proto option. - */ -static int ProtoTestParse01 (void) -{ - DetectProto dp; - memset(&dp,0,sizeof(DetectProto)); - - int r = DetectProtoParse(&dp, "6"); - if (r < 0) { - return 1; - } - - SCLogDebug("DetectProtoParse should have rejected the \"6\" string"); - return 0; -} -/** - * \test ProtoTestParse02 is a test to make sure that we parse the - * protocol correctly, when given "tcp" as proto option. - */ -static int ProtoTestParse02 (void) -{ - DetectProto dp; - memset(&dp,0,sizeof(DetectProto)); - - int r = DetectProtoParse(&dp, "tcp"); - if (r >= 0 && dp.proto[(IPPROTO_TCP/8)] & (1<<(IPPROTO_TCP%8))) { - return 1; - } - - SCLogDebug("ProtoTestParse02: Error in parsing the \"tcp\" string"); - return 0; -} -/** - * \test ProtoTestParse03 is a test to make sure that we parse the - * protocol correctly, when given "ip" as proto option. - */ -static int ProtoTestParse03 (void) -{ - DetectProto dp; - memset(&dp,0,sizeof(DetectProto)); - - int r = DetectProtoParse(&dp, "ip"); - if (r >= 0 && dp.flags & DETECT_PROTO_ANY) { - return 1; - } - - SCLogDebug("ProtoTestParse03: Error in parsing the \"ip\" string"); - return 0; -} - -/** - * \test ProtoTestParse04 is a test to make sure that we do not parse the - * protocol, when given an invalid proto option. - */ -static int ProtoTestParse04 (void) -{ - DetectProto dp; - memset(&dp,0,sizeof(DetectProto)); - - /* Check for a bad number */ - int r = DetectProtoParse(&dp, "4242"); - if (r < 0) { - return 1; - } - - SCLogDebug("ProtoTestParse04: it should not parsing the \"4242\" string"); - return 0; -} - -/** - * \test ProtoTestParse05 is a test to make sure that we do not parse the - * protocol, when given an invalid proto option. - */ -static int ProtoTestParse05 (void) -{ - DetectProto dp; - memset(&dp,0,sizeof(DetectProto)); - - /* Check for a bad string */ - int r = DetectProtoParse(&dp, "tcp/udp"); - if (r < 0) { - return 1; - } - - SCLogDebug("ProtoTestParse05: it should not parsing the \"tcp/udp\" string"); - return 0; -} - -/** - * \test make sure that we properly parse tcp-pkt - */ -static int ProtoTestParse06 (void) -{ - DetectProto dp; - memset(&dp,0,sizeof(DetectProto)); - - /* Check for a bad string */ - int r = DetectProtoParse(&dp, "tcp-pkt"); - if (r < 0) { - printf("parsing tcp-pkt failed: "); - return 0; - } - - if (!(dp.flags & DETECT_PROTO_ONLY_PKT)) { - printf("DETECT_PROTO_ONLY_PKT flag not set: "); - return 0; - } - - return 1; -} - -/** - * \test make sure that we properly parse tcp-stream - */ -static int ProtoTestParse07 (void) -{ - DetectProto dp; - memset(&dp,0,sizeof(DetectProto)); - - /* Check for a bad string */ - int r = DetectProtoParse(&dp, "tcp-stream"); - if (r < 0) { - printf("parsing tcp-stream failed: "); - return 0; - } - - if (!(dp.flags & DETECT_PROTO_ONLY_STREAM)) { - printf("DETECT_PROTO_ONLY_STREAM flag not set: "); - return 0; - } - - return 1; -} - -/** - * \test DetectIPProtoTestSetup01 is a test for a protocol setting up in - * signature. - */ -static int DetectProtoTestSetup01(void) -{ - DetectProto dp; - Signature *sig = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - int i; - - memset(&dp, 0, sizeof(dp)); - - result = DetectProtoInitTest(&de_ctx, &sig, &dp, "tcp"); - if (result == 0) { - goto end; - } - - result = 0; - - /* The signature proto should be TCP */ - if (!(sig->proto.proto[(IPPROTO_TCP/8)] & (1<<(IPPROTO_TCP%8)))) { - printf("failed in sig matching\n"); - goto cleanup; - } - for (i = 2; i < 256/8; i++) { - if (sig->proto.proto[i] != 0) { - printf("failed in sig clear\n"); - goto cleanup; - } - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); -end: - return result; -} - -/** - * \test DetectrotoTestSetup02 is a test for a icmpv4 and icmpv6 - * protocol setting up in signature. - */ -static int DetectProtoTestSetup02(void) -{ - DetectProto dp; - Signature *sig_icmpv4 = NULL; - Signature *sig_icmpv6 = NULL; - Signature *sig_icmp = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - int i; - - memset(&dp, 0, sizeof(dp)); - - if (DetectProtoInitTest(&de_ctx, &sig_icmpv4, &dp, "icmpv4") == 0) { - printf("failure - imcpv4.\n"); - goto end; - } - - if (DetectProtoInitTest(&de_ctx, &sig_icmpv6, &dp, "icmpv6") == 0) { - printf("failure - imcpv6.\n"); - goto end; - } - - if (DetectProtoInitTest(&de_ctx, &sig_icmp, &dp, "icmp") == 0) { - printf("failure - imcp.\n"); - goto end; - } - - for (i = 0; i < 256 / 8; i++) { - if (i == IPPROTO_ICMP) { - if (!(sig_icmpv4->proto.proto[i / 8] & (1 << (i % 8)))) { - printf("failed in sig matching - icmpv4 - icmpv4.\n"); - goto end; - } - continue; - } - if (sig_icmpv4->proto.proto[i / 8] & (1 << (i % 8))) { - printf("failed in sig matching - icmpv4 - others.\n"); - goto end; - } - } - - for (i = 0; i < 256 / 8; i++) { - if (i == IPPROTO_ICMPV6) { - if (!(sig_icmpv6->proto.proto[i / 8] & (1 << (i % 8)))) { - printf("failed in sig matching - icmpv6 - icmpv6.\n"); - goto end; - } - continue; - } - if (sig_icmpv6->proto.proto[i / 8] & (1 << (i % 8))) { - printf("failed in sig matching - icmpv6 - others.\n"); - goto end; - } - } - - for (i = 0; i < 256 / 8; i++) { - if (i == IPPROTO_ICMP || i == IPPROTO_ICMPV6) { - if (!(sig_icmp->proto.proto[i / 8] & (1 << (i % 8)))) { - printf("failed in sig matching - icmp - icmp.\n"); - goto end; - } - continue; - } - if (sig_icmpv6->proto.proto[i / 8] & (1 << (i % 8))) { - printf("failed in sig matching - icmp - others.\n"); - goto end; - } - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectProtoTestSig01 is a test for checking the working of protocol - * detection by setting up the signature and later testing its working - * by matching the received packet against the sig. - */ - -static int DetectProtoTestSig01(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - Flow f; - - memset(&f, 0, sizeof(Flow)); - memset(&th_v, 0, sizeof(th_v)); - - FLOW_INITIALIZE(&f); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flags |= PKT_HAS_FLOW; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert udp any any -> any any " - "(msg:\"Not tcp\"; flow:to_server; sid:1;)"); - - if (s == NULL) - goto end; - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any " - "(msg:\"IP\"; flow:to_server; sid:2;)"); - - if (s == NULL) - goto end; - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any " - "(msg:\"TCP\"; flow:to_server; sid:3;)"); - - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 alerted, but should not have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2) == 0) { - printf("sid 2 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 3) == 0) { - printf("sid 3 did not alert, but should have: "); - goto cleanup; - } - - result = 1; - -cleanup: - FLOW_DESTROY(&f); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); -end: - return result; -} - -/** - * \test signature parsing with tcp-pkt and tcp-stream - */ - -static int DetectProtoTestSig02(void) -{ - Signature *s = NULL; - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp-pkt any any -> any any " - "(msg:\"tcp-pkt\"; content:\"blah\"; sid:1;)"); - if (s == NULL) { - printf("tcp-pkt sig parsing failed: "); - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp-stream any any -> any any " - "(msg:\"tcp-stream\"; content:\"blah\"; sid:2;)"); - if (s == NULL) { - printf("tcp-pkt sig parsing failed: "); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectProto - */ -void DetectProtoTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("ProtoTestParse01", ProtoTestParse01, 1); - UtRegisterTest("ProtoTestParse02", ProtoTestParse02, 1); - UtRegisterTest("ProtoTestParse03", ProtoTestParse03, 1); - UtRegisterTest("ProtoTestParse04", ProtoTestParse04, 1); - UtRegisterTest("ProtoTestParse05", ProtoTestParse05, 1); - UtRegisterTest("ProtoTestParse06", ProtoTestParse06, 1); - UtRegisterTest("ProtoTestParse07", ProtoTestParse07, 1); - - UtRegisterTest("DetectProtoTestSetup01", DetectProtoTestSetup01, 1); - UtRegisterTest("DetectProtoTestSetup02", DetectProtoTestSetup02, 1); - - UtRegisterTest("DetectProtoTestSig01", DetectProtoTestSig01, 1); - UtRegisterTest("DetectProtoTestSig02", DetectProtoTestSig02, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-engine-proto.h b/framework/src/suricata/src/detect-engine-proto.h deleted file mode 100644 index 4edfe3b5..00000000 --- a/framework/src/suricata/src/detect-engine-proto.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_PROTO_H__ -#define __DETECT_PROTO_H__ - -#define DETECT_PROTO_ANY (1 << 0) /**< Indicate that given protocol - is considered as IP */ -#define DETECT_PROTO_ONLY_PKT (1 << 1) /**< Indicate that we only care - about packet payloads. */ -#define DETECT_PROTO_ONLY_STREAM (1 << 2) /**< Indicate that we only care - about stream payloads. */ -#define DETECT_PROTO_IPV4 (1 << 3) /**< IPv4 only */ -#define DETECT_PROTO_IPV6 (1 << 4) /**< IPv6 only */ - -typedef struct DetectProto_ { - uint8_t proto[256/8]; /**< bit array for 256 protocol bits */ - uint8_t flags; -} DetectProto; - -/* prototypes */ -int DetectProtoParse(DetectProto *dp, char *str); -int DetectProtoContainsProto(DetectProto *, int); - -void DetectProtoTests(void); - -#endif /* __DETECT_PROTO_H__ */ - diff --git a/framework/src/suricata/src/detect-engine-siggroup.c b/framework/src/suricata/src/detect-engine-siggroup.c deleted file mode 100644 index 89e0eb79..00000000 --- a/framework/src/suricata/src/detect-engine-siggroup.c +++ /dev/null @@ -1,2420 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Signature grouping part of the detection engine. - */ - -#include "suricata-common.h" -#include "decode.h" - -#include "flow-var.h" - -#include "app-layer-protos.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-address.h" -#include "detect-engine-mpm.h" -#include "detect-engine-siggroup.h" - -#include "detect-content.h" -#include "detect-uricontent.h" - -#include "util-hash.h" -#include "util-hashlist.h" - -#include "util-error.h" -#include "util-debug.h" -#include "util-cidr.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-memcmp.h" - -/* prototypes */ -int SigGroupHeadClearSigs(SigGroupHead *); - -static uint32_t detect_siggroup_head_memory = 0; -static uint32_t detect_siggroup_head_init_cnt = 0; -static uint32_t detect_siggroup_head_free_cnt = 0; -static uint32_t detect_siggroup_head_initdata_memory = 0; -static uint32_t detect_siggroup_head_initdata_init_cnt = 0; -static uint32_t detect_siggroup_head_initdata_free_cnt = 0; -static uint32_t detect_siggroup_sigarray_memory = 0; -static uint32_t detect_siggroup_sigarray_init_cnt = 0; -static uint32_t detect_siggroup_sigarray_free_cnt = 0; -static uint32_t detect_siggroup_matcharray_memory = 0; -static uint32_t detect_siggroup_matcharray_init_cnt = 0; -static uint32_t detect_siggroup_matcharray_free_cnt = 0; - -void SigGroupHeadInitDataFree(SigGroupHeadInitData *sghid) -{ - if (sghid->content_array != NULL) { - SCFree(sghid->content_array); - sghid->content_array = NULL; - sghid->content_size = 0; - } - if (sghid->uri_content_array != NULL) { - SCFree(sghid->uri_content_array); - sghid->uri_content_array = NULL; - sghid->uri_content_size = 0; - } - if (sghid->sig_array != NULL) { - SCFree(sghid->sig_array); - sghid->sig_array = NULL; - - detect_siggroup_sigarray_free_cnt++; - detect_siggroup_sigarray_memory -= sghid->sig_size; - } - SCFree(sghid); - - detect_siggroup_head_initdata_free_cnt++; - detect_siggroup_head_initdata_memory -= sizeof(SigGroupHeadInitData); -} - -static SigGroupHeadInitData *SigGroupHeadInitDataAlloc(uint32_t size) -{ - SigGroupHeadInitData *sghid = SCMalloc(sizeof(SigGroupHeadInitData)); - if (unlikely(sghid == NULL)) - return NULL; - - memset(sghid, 0x00, sizeof(SigGroupHeadInitData)); - - detect_siggroup_head_initdata_init_cnt++; - detect_siggroup_head_initdata_memory += sizeof(SigGroupHeadInitData); - - /* initialize the signature bitarray */ - sghid->sig_size = size; - if ( (sghid->sig_array = SCMalloc(sghid->sig_size)) == NULL) - goto error; - - memset(sghid->sig_array, 0, sghid->sig_size); - - detect_siggroup_sigarray_init_cnt++; - detect_siggroup_sigarray_memory += sghid->sig_size; - - return sghid; -error: - SigGroupHeadInitDataFree(sghid); - return NULL; -} - -void SigGroupHeadStore(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - void *ptmp; - //printf("de_ctx->sgh_array_cnt %u, de_ctx->sgh_array_size %u, de_ctx->sgh_array %p\n", de_ctx->sgh_array_cnt, de_ctx->sgh_array_size, de_ctx->sgh_array); - if (de_ctx->sgh_array_cnt < de_ctx->sgh_array_size) { - de_ctx->sgh_array[de_ctx->sgh_array_cnt] = sgh; - } else { - int increase = 16; - ptmp = SCRealloc(de_ctx->sgh_array, - sizeof(SigGroupHead *) * (increase + de_ctx->sgh_array_size)); - if (ptmp == NULL) { - SCFree(de_ctx->sgh_array); - de_ctx->sgh_array = NULL; - return; - } - de_ctx->sgh_array = ptmp; - - de_ctx->sgh_array_size += increase; - de_ctx->sgh_array[de_ctx->sgh_array_cnt] = sgh; - } - de_ctx->sgh_array_cnt++; -} - -/** - * \brief Alloc a SigGroupHead and its signature bit_array. - * - * \param size Size of the sig_array that has to be created for this - * SigGroupHead. - * - * \retval sgh Pointer to the newly init SigGroupHead on success; or NULL in - * case of error. - */ -static SigGroupHead *SigGroupHeadAlloc(DetectEngineCtx *de_ctx, uint32_t size) -{ - SigGroupHead *sgh = SCMalloc(sizeof(SigGroupHead)); - if (unlikely(sgh == NULL)) - return NULL; - memset(sgh, 0, sizeof(SigGroupHead)); - - sgh->init = SigGroupHeadInitDataAlloc(size); - if (sgh->init == NULL) - goto error; - - detect_siggroup_head_init_cnt++; - detect_siggroup_head_memory += sizeof(SigGroupHead); - - return sgh; - -error: - SigGroupHeadFree(sgh); - return NULL; -} - -/** - * \brief Free a SigGroupHead and its members. - * - * \param sgh Pointer to the SigGroupHead that has to be freed. - */ -void SigGroupHeadFree(SigGroupHead *sgh) -{ - if (sgh == NULL) - return; - - SCLogDebug("sgh %p", sgh); - - PatternMatchDestroyGroup(sgh); - - if (sgh->match_array != NULL) { - detect_siggroup_matcharray_free_cnt++; - detect_siggroup_matcharray_memory -= (sgh->sig_cnt * sizeof(Signature *)); - SCFree(sgh->match_array); - sgh->match_array = NULL; - } - - if (sgh->non_mpm_store_array != NULL) { - SCFree(sgh->non_mpm_store_array); - sgh->non_mpm_store_array = NULL; - sgh->non_mpm_store_cnt = 0; - } - - sgh->sig_cnt = 0; - - if (sgh->init != NULL) { - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - - SCFree(sgh); - - detect_siggroup_head_free_cnt++; - detect_siggroup_head_memory -= sizeof(SigGroupHead); - - return; -} - -/** - * \brief The hash function to be the used by the mpm SigGroupHead hash table - - * DetectEngineCtx->sgh_mpm_hash_table. - * - * \param ht Pointer to the hash table. - * \param data Pointer to the SigGroupHead. - * \param datalen Not used in our case. - * - * \retval hash The generated hash value. - */ -uint32_t SigGroupHeadMpmHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - SigGroupHead *sgh = (SigGroupHead *)data; - uint32_t hash = 0; - uint32_t b = 0; - - for (b = 0; b < sgh->init->content_size; b++) - hash += sgh->init->content_array[b]; - - return hash % ht->array_size; -} - -/** - * \brief The Compare function to be used by the mpm SigGroupHead hash table - - * DetectEngineCtx->sgh_mpm_hash_table. - * - * \param data1 Pointer to the first SigGroupHead. - * \param len1 Not used. - * \param data2 Pointer to the second SigGroupHead. - * \param len2 Not used. - * - * \retval 1 If the 2 SigGroupHeads sent as args match. - * \retval 0 If the 2 SigGroupHeads sent as args do not match. - */ -char SigGroupHeadMpmCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - SigGroupHead *sgh1 = (SigGroupHead *)data1; - SigGroupHead *sgh2 = (SigGroupHead *)data2; - - if (sgh1->init->content_size != sgh2->init->content_size) - return 0; - - if (SCMemcmp(sgh1->init->content_array, sgh2->init->content_array, - sgh1->init->content_size) != 0) { - return 0; - } - - return 1; -} - -/** - * \brief Initializes the SigGroupHead mpm hash table to be used by the detection - * engine context. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadMpmHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_mpm_hash_table = HashListTableInit(4096, SigGroupHeadMpmHashFunc, - SigGroupHeadMpmCompareFunc, - NULL); - - if (de_ctx->sgh_mpm_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context SigGroupHead - * mpm hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh; -1 on failure. - */ -int SigGroupHeadMpmHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_mpm_hash_table, (void *)sgh, 0); - - return ret; -} - -/** - * \brief Used to lookup a SigGroupHead from the detection engine context - * SigGroupHead mpm hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadMpmHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_mpm_hash_table, - (void *)sgh, 0); - - return rsgh; -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_mpm_hash_table, allocated by - * SigGroupHeadMpmHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadMpmHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_mpm_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_mpm_hash_table); - de_ctx->sgh_mpm_hash_table = NULL; - - return; -} - -/** - * \brief The hash function to be the used by the mpm uri SigGroupHead hash - * table - DetectEngineCtx->sgh_mpm_uri_hash_table. - * - * \param ht Pointer to the hash table. - * \param data Pointer to the SigGroupHead. - * \param datalen Not used in our case. - * - * \retval hash The generated hash value. - */ -uint32_t SigGroupHeadMpmUriHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - SigGroupHead *sgh = (SigGroupHead *)data; - uint32_t hash = 0; - uint32_t b = 0; - - for (b = 0; b < sgh->init->uri_content_size; b++) - hash += sgh->init->uri_content_array[b]; - - return hash % ht->array_size; -} - -/** - * \brief The Compare function to be used by the mpm uri SigGroupHead hash - * table - DetectEngineCtx->sgh_mpm_uri_hash_table. - * - * \param data1 Pointer to the first SigGroupHead. - * \param len1 Not used. - * \param data2 Pointer to the second SigGroupHead. - * \param len2 Not used. - * - * \retval 1 If the 2 SigGroupHeads sent as args match. - * \retval 0 If the 2 SigGroupHeads sent as args do not match. - */ -char SigGroupHeadMpmUriCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - SigGroupHead *sgh1 = (SigGroupHead *)data1; - SigGroupHead *sgh2 = (SigGroupHead *)data2; - - if (sgh1->init->uri_content_size != sgh2->init->uri_content_size) - return 0; - - if (SCMemcmp(sgh1->init->uri_content_array, sgh2->init->uri_content_array, - sgh1->init->uri_content_size) != 0) { - return 0; - } - - return 1; -} - -/** - * \brief Initializes the mpm uri hash table to be used by the detection engine - * context. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadMpmUriHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_mpm_uri_hash_table = HashListTableInit(4096, - SigGroupHeadMpmUriHashFunc, - SigGroupHeadMpmUriCompareFunc, - NULL); - if (de_ctx->sgh_mpm_uri_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context SigGroupHead - * mpm uri hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh and -1 on failure. - */ -int SigGroupHeadMpmUriHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_mpm_uri_hash_table, (void *)sgh, 0); - - return ret; -} - -/** - * \brief Used to lookup a SigGroupHead from the detection engine context - * SigGroupHead mpm uri hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadMpmUriHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_mpm_uri_hash_table, - (void *)sgh, 0); - - return rsgh; -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_mpm_uri_hash_table, - * allocated by SigGroupHeadMpmUriHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadMpmUriHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_mpm_uri_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_mpm_uri_hash_table); - de_ctx->sgh_mpm_uri_hash_table = NULL; - - return; -} - -/** - * \brief The hash function to be the used by the mpm uri SigGroupHead hash - * table - DetectEngineCtx->sgh_mpm_uri_hash_table. - * - * \param ht Pointer to the hash table. - * \param data Pointer to the SigGroupHead. - * \param datalen Not used in our case. - * - * \retval hash The generated hash value. - */ -uint32_t SigGroupHeadMpmStreamHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - SigGroupHead *sgh = (SigGroupHead *)data; - uint32_t hash = 0; - uint32_t b = 0; - - for (b = 0; b < sgh->init->stream_content_size; b++) - hash += sgh->init->stream_content_array[b]; - - return hash % ht->array_size; -} - -/** - * \brief The Compare function to be used by the mpm uri SigGroupHead hash - * table - DetectEngineCtx->sgh_mpm_uri_hash_table. - * - * \param data1 Pointer to the first SigGroupHead. - * \param len1 Not used. - * \param data2 Pointer to the second SigGroupHead. - * \param len2 Not used. - * - * \retval 1 If the 2 SigGroupHeads sent as args match. - * \retval 0 If the 2 SigGroupHeads sent as args do not match. - */ -char SigGroupHeadMpmStreamCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - SigGroupHead *sgh1 = (SigGroupHead *)data1; - SigGroupHead *sgh2 = (SigGroupHead *)data2; - - if (sgh1->init->stream_content_size != sgh2->init->stream_content_size) - return 0; - - if (SCMemcmp(sgh1->init->stream_content_array, sgh2->init->stream_content_array, - sgh1->init->stream_content_size) != 0) { - return 0; - } - - return 1; -} - -/** - * \brief Initializes the mpm uri hash table to be used by the detection engine - * context. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadMpmStreamHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_mpm_stream_hash_table = HashListTableInit(4096, - SigGroupHeadMpmStreamHashFunc, SigGroupHeadMpmStreamCompareFunc, NULL); - if (de_ctx->sgh_mpm_stream_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context SigGroupHead - * mpm uri hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh and -1 on failure. - */ -int SigGroupHeadMpmStreamHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_mpm_stream_hash_table, (void *)sgh, 0); - - return ret; -} - -/** - * \brief Used to lookup a SigGroupHead from the detection engine context - * SigGroupHead mpm uri hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadMpmStreamHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_mpm_stream_hash_table, - (void *)sgh, 0); - - return rsgh; -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_mpm_uri_hash_table, - * allocated by SigGroupHeadMpmUriHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadMpmStreamHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_mpm_stream_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_mpm_stream_hash_table); - de_ctx->sgh_mpm_stream_hash_table = NULL; - - return; -} - -/** - * \brief The hash function to be the used by the hash table - - * DetectEngineCtx->sgh_hash_table. - * - * \param ht Pointer to the hash table. - * \param data Pointer to the SigGroupHead. - * \param datalen Not used in our case. - * - * \retval hash The generated hash value. - */ -uint32_t SigGroupHeadHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - SigGroupHead *sgh = (SigGroupHead *)data; - uint32_t hash = 0; - uint32_t b = 0; - - SCLogDebug("hashing sgh %p (mpm_content_minlen %u)", sgh, sgh->mpm_content_minlen); - - for (b = 0; b < sgh->init->sig_size; b++) - hash += sgh->init->sig_array[b]; - - hash %= ht->array_size; - SCLogDebug("hash %"PRIu32" (sig_size %"PRIu32")", hash, sgh->init->sig_size); - return hash; -} - -/** - * \brief The Compare function to be used by the SigGroupHead hash table - - * DetectEngineCtx->sgh_hash_table. - * - * \param data1 Pointer to the first SigGroupHead. - * \param len1 Not used. - * \param data2 Pointer to the second SigGroupHead. - * \param len2 Not used. - * - * \retval 1 If the 2 SigGroupHeads sent as args match. - * \retval 0 If the 2 SigGroupHeads sent as args do not match. - */ -char SigGroupHeadCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - SigGroupHead *sgh1 = (SigGroupHead *)data1; - SigGroupHead *sgh2 = (SigGroupHead *)data2; - - if (data1 == NULL || data2 == NULL) - return 0; - - if (sgh1->init->sig_size != sgh2->init->sig_size) - return 0; - - if (SCMemcmp(sgh1->init->sig_array, sgh2->init->sig_array, sgh1->init->sig_size) != 0) - return 0; - - return 1; -} - -/** - * \brief Initializes the hash table in the detection engine context to hold the - * SigGroupHeads. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_hash_table = HashListTableInit(4096, SigGroupHeadHashFunc, - SigGroupHeadCompareFunc, NULL); - if (de_ctx->sgh_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context SigGroupHead - * hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the SigGroupHead; -1 on failure. - */ -int SigGroupHeadHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_hash_table, (void *)sgh, 0); - - return ret; -} - -int SigGroupHeadHashRemove(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - return HashListTableRemove(de_ctx->sgh_hash_table, (void *)sgh, 0); -} - -/** - * \brief Used to lookup a SigGroupHead hash from the detection engine context - * SigGroupHead hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadHashLookup(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_hash_table, - (void *)sgh, 0); - - SCReturnPtr(rsgh, "SigGroupHead"); -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_hash_table, allocated by - * SigGroupHeadHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_hash_table); - de_ctx->sgh_hash_table = NULL; - - return; -} - -/** - * \brief Initializes the dport based SigGroupHead hash table to hold the - * SigGroupHeads. The hash table that would be initialized is - * DetectEngineCtx->sgh_dport_hash_table. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadDPortHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_dport_hash_table = HashListTableInit(4096, SigGroupHeadHashFunc, - SigGroupHeadCompareFunc, - NULL); - if (de_ctx->sgh_dport_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context dport based - * SigGroupHead hash table(DetectEngineCtx->sgh_dport_hash_table). - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh and -1 on failure. - */ -int SigGroupHeadDPortHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_dport_hash_table, (void *)sgh, 0); - - return ret; -} - -/** - * \brief Used to lookup a SigGroupHead hash from the detection engine ctx dport - * based SigGroupHead hash table(DetectEngineCtx->sgh_dport_hash_table). - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadDPortHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SCEnter(); - - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_dport_hash_table, - (void *)sgh, 0); - - SCReturnPtr(rsgh,"SigGroupHead"); -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_dport_hash_table, - * allocated by the SigGroupHeadDPortHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadDPortHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_dport_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_dport_hash_table); - de_ctx->sgh_dport_hash_table = NULL; - - return; -} - -/** - * \brief Initializes the sport based SigGroupHead hash table to hold the - * SigGroupHeads. The hash table that would be initialized is - * DetectEngineCtx->sgh_sport_hash_table. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadSPortHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_sport_hash_table = HashListTableInit(4096, - SigGroupHeadHashFunc, - SigGroupHeadCompareFunc, - NULL); - if (de_ctx->sgh_sport_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context dport based - * SigGroupHead hash table(DetectEngineCtx->sgh_sport_hash_table). - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh and -1 on failure. - */ -int SigGroupHeadSPortHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_sport_hash_table, (void *)sgh, 0); - - return ret; -} - -int SigGroupHeadSPortHashRemove(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - return HashListTableRemove(de_ctx->sgh_sport_hash_table, (void *)sgh, 0); -} - -/** - * \brief Used to lookup a SigGroupHead hash from the detection engine ctx sport - * based SigGroupHead hash table(DetectEngineCtx->sgh_dport_hash_table). - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadSPortHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_sport_hash_table, - (void *)sgh, 0); - - return rsgh; -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_sport_hash_table, - * allocated by the SigGroupHeadSPortHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadSPortHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_sport_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_sport_hash_table); - de_ctx->sgh_sport_hash_table = NULL; - - return; -} - -/** - * \brief Used to free the signature array, content_array and uri_content_array - * members from the SigGroupHeads in the HashListTable. - * - * \param de_ctx Pointer to the detection engine context. - * \param ht Pointer to the HashListTable - */ -static void SigGroupHeadFreeSigArraysHash2(DetectEngineCtx *de_ctx, - HashListTable *ht) -{ - HashListTableBucket *htb = NULL; - SigGroupHead *sgh = NULL; - - for (htb = HashListTableGetListHead(ht); - htb != NULL; - htb = HashListTableGetListNext(htb)) - { - sgh = (SigGroupHead *)HashListTableGetListData(htb); - if (sgh == NULL) { - continue; - } - - if (sgh->init->sig_array != NULL) { - detect_siggroup_sigarray_free_cnt++; - detect_siggroup_sigarray_memory -= sgh->init->sig_size; - - SCFree(sgh->init->sig_array); - sgh->init->sig_array = NULL; - sgh->init->sig_size = 0; - } - - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - - return; -} - -/** - * \brief Used to free the sig_array member of the SigGroupHeads present - * in the HashListTable. - * - * \param de_ctx Pointer to the detection engine context. - * \param ht Pointer to the HashListTable - */ -static void SigGroupHeadFreeSigArraysHash(DetectEngineCtx *de_ctx, - HashListTable *ht) -{ - HashListTableBucket *htb = NULL; - SigGroupHead *sgh = NULL; - - for (htb = HashListTableGetListHead(ht); - htb != NULL; - htb = HashListTableGetListNext(htb)) { - sgh = (SigGroupHead *)HashListTableGetListData(htb); - - if (sgh->init != NULL) { - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - } - - return; -} - -/** - * \brief Free the sigarrays in the sgh's. Those are only used during the init - * stage. - * - * \param de_ctx Pointer to the detection engine context whose sigarrays have to - * be freed. - */ -void SigGroupHeadFreeSigArrays(DetectEngineCtx *de_ctx) -{ - SigGroupHeadFreeSigArraysHash2(de_ctx, de_ctx->sgh_hash_table); - SigGroupHeadFreeSigArraysHash(de_ctx, de_ctx->sgh_dport_hash_table); - SigGroupHeadFreeSigArraysHash(de_ctx, de_ctx->sgh_sport_hash_table); - - return; -} - -/** - * \brief Free the mpm arrays that are only used during the init stage. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadFreeMpmArrays(DetectEngineCtx *de_ctx) -{ - HashListTableBucket *htb = NULL; - SigGroupHead *sgh = NULL; - - for (htb = HashListTableGetListHead(de_ctx->sgh_dport_hash_table); htb != NULL; htb = HashListTableGetListNext(htb)) { - sgh = (SigGroupHead *)HashListTableGetListData(htb); - if (sgh->init != NULL) { - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - } - - for (htb = HashListTableGetListHead(de_ctx->sgh_sport_hash_table); htb != NULL; htb = HashListTableGetListNext(htb)) { - sgh = (SigGroupHead *)HashListTableGetListData(htb); - if (sgh->init != NULL) { - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - } - - return; -} - -static uint16_t SignatureGetMpmPatternLen(Signature *s, int list) -{ - if (s->sm_lists[list] != NULL && s->mpm_sm != NULL && - SigMatchListSMBelongsTo(s, s->mpm_sm) == list) - { - DetectContentData *cd = (DetectContentData *)s->mpm_sm->ctx; - return cd->content_len; - } - return 0; -} - -/** - * \brief Add a Signature to a SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to a SigGroupHead. Can be NULL also. - * \param s Pointer to the Signature that has to be added to the - * SigGroupHead. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadAppendSig(DetectEngineCtx *de_ctx, SigGroupHead **sgh, - Signature *s) -{ - if (de_ctx == NULL) - return 0; - - /* see if we have a head already */ - if (*sgh == NULL) { - *sgh = SigGroupHeadAlloc(de_ctx, DetectEngineGetMaxSigId(de_ctx) / 8 + 1); - if (*sgh == NULL) - goto error; - } - - /* enable the sig in the bitarray */ - (*sgh)->init->sig_array[s->num / 8] |= 1 << (s->num % 8); - - /* update minlen for mpm */ - if (s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - /* check with the precalculated values from the sig */ - uint16_t mpm_content_minlen = SignatureGetMpmPatternLen(s, DETECT_SM_LIST_PMATCH); - if (mpm_content_minlen > 0) { - if ((*sgh)->mpm_content_minlen == 0) - (*sgh)->mpm_content_minlen = mpm_content_minlen; - - if ((*sgh)->mpm_content_minlen > mpm_content_minlen) - (*sgh)->mpm_content_minlen = mpm_content_minlen; - - SCLogDebug("(%p)->mpm_content_minlen %u", *sgh, (*sgh)->mpm_content_minlen); - } - } - return 0; - -error: - return -1; -} - -/** - * \brief Clears the bitarray holding the sids for this SigGroupHead. - * - * \param sgh Pointer to the SigGroupHead. - * - * \retval 0 Always. - */ -int SigGroupHeadClearSigs(SigGroupHead *sgh) -{ - if (sgh == NULL) - return 0; - - if (sgh->init->sig_array != NULL) - memset(sgh->init->sig_array, 0, sgh->init->sig_size); - - sgh->sig_cnt = 0; - - return 0; -} - -/** - * \brief Copies the bitarray holding the sids from the source SigGroupHead to - * the destination SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param src Pointer to the source SigGroupHead. - * \param dst Pointer to the destination SigGroupHead. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadCopySigs(DetectEngineCtx *de_ctx, SigGroupHead *src, SigGroupHead **dst) -{ - uint32_t idx = 0; - - if (src == NULL || de_ctx == NULL) - return 0; - - if (*dst == NULL) { - *dst = SigGroupHeadAlloc(de_ctx, DetectEngineGetMaxSigId(de_ctx) / 8 + 1); - if (*dst == NULL) - goto error; - } - - /* do the copy */ - for (idx = 0; idx < src->init->sig_size; idx++) - (*dst)->init->sig_array[idx] = (*dst)->init->sig_array[idx] | src->init->sig_array[idx]; - - if (src->mpm_content_minlen != 0) { - if ((*dst)->mpm_content_minlen == 0) - (*dst)->mpm_content_minlen = src->mpm_content_minlen; - - if ((*dst)->mpm_content_minlen > src->mpm_content_minlen) - (*dst)->mpm_content_minlen = src->mpm_content_minlen; - - SCLogDebug("src (%p)->mpm_content_minlen %u", src, src->mpm_content_minlen); - SCLogDebug("dst (%p)->mpm_content_minlen %u", (*dst), (*dst)->mpm_content_minlen); - BUG_ON((*dst)->mpm_content_minlen == 0); - } - return 0; - -error: - return -1; -} - -/** - * \brief Updates the SigGroupHead->sig_cnt with the total count of all the - * Signatures present in this SigGroupHead. - * - * \param sgh Pointer to the SigGroupHead. - * \param max_idx Maximum sid of the all the Signatures present in this - * SigGroupHead. - */ -void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx) -{ - uint32_t sig; - - sgh->sig_cnt = 0; - for (sig = 0; sig < max_idx + 1; sig++) { - if (sgh->init->sig_array[sig / 8] & (1 << (sig % 8))) - sgh->sig_cnt++; - } - - return; -} - -/** - * \brief Prints the memory statistics for the detect-engine-siggroup.[ch] module. - */ -void DetectSigGroupPrintMemory(void) -{ - SCLogDebug(" * Sig group head memory stats (SigGroupHead %" PRIuMAX "):", - (uintmax_t)sizeof(SigGroupHead)); - SCLogDebug(" - detect_siggroup_head_memory %" PRIu32, - detect_siggroup_head_memory); - SCLogDebug(" - detect_siggroup_head_init_cnt %" PRIu32, - detect_siggroup_head_init_cnt); - SCLogDebug(" - detect_siggroup_head_free_cnt %" PRIu32, - detect_siggroup_head_free_cnt); - SCLogDebug(" - outstanding sig group heads %" PRIu32, - detect_siggroup_head_init_cnt - detect_siggroup_head_free_cnt); - SCLogDebug(" * Sig group head memory stats done"); - SCLogDebug(" * Sig group head initdata memory stats (SigGroupHeadInitData %" PRIuMAX "):", - (uintmax_t)sizeof(SigGroupHeadInitData)); - SCLogDebug(" - detect_siggroup_head_initdata_memory %" PRIu32, - detect_siggroup_head_initdata_memory); - SCLogDebug(" - detect_siggroup_head_initdata_init_cnt %" PRIu32, - detect_siggroup_head_initdata_init_cnt); - SCLogDebug(" - detect_siggroup_head_initdata_free_cnt %" PRIu32, - detect_siggroup_head_initdata_free_cnt); - SCLogDebug(" - outstanding sig group head initdatas %" PRIu32, - detect_siggroup_head_initdata_init_cnt - detect_siggroup_head_initdata_free_cnt); - SCLogDebug(" * Sig group head memory initdata stats done"); - SCLogDebug(" * Sig group sigarray memory stats:"); - SCLogDebug(" - detect_siggroup_sigarray_memory %" PRIu32, - detect_siggroup_sigarray_memory); - SCLogDebug(" - detect_siggroup_sigarray_init_cnt %" PRIu32, - detect_siggroup_sigarray_init_cnt); - SCLogDebug(" - detect_siggroup_sigarray_free_cnt %" PRIu32, - detect_siggroup_sigarray_free_cnt); - SCLogDebug(" - outstanding sig group sigarrays %" PRIu32, - (detect_siggroup_sigarray_init_cnt - - detect_siggroup_sigarray_free_cnt)); - SCLogDebug(" * Sig group sigarray memory stats done"); - SCLogDebug(" * Sig group matcharray memory stats:"); - SCLogDebug(" - detect_siggroup_matcharray_memory %" PRIu32, - detect_siggroup_matcharray_memory); - SCLogDebug(" - detect_siggroup_matcharray_init_cnt %" PRIu32, - detect_siggroup_matcharray_init_cnt); - SCLogDebug(" - detect_siggroup_matcharray_free_cnt %" PRIu32, - detect_siggroup_matcharray_free_cnt); - SCLogDebug(" - outstanding sig group matcharrays %" PRIu32, - (detect_siggroup_matcharray_init_cnt - - detect_siggroup_matcharray_free_cnt)); - SCLogDebug(" * Sig group sigarray memory stats done"); - SCLogDebug(" X Total %" PRIu32, - (detect_siggroup_head_memory + detect_siggroup_sigarray_memory + - detect_siggroup_matcharray_memory)); - - return; -} - -/** - * \brief Helper function used to print the list of sids for the Signatures - * present in this SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - */ -void SigGroupHeadPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - if (sgh == NULL) { - SCReturn; - } - - uint32_t u; - - SCLogDebug("The Signatures present in this SigGroupHead are: "); - for (u = 0; u < (sgh->init->sig_size * 8); u++) { - if (sgh->init->sig_array[u / 8] & (1 << (u % 8))) { - SCLogDebug("%" PRIu32, u); - printf("s->num %"PRIu32" ", u); - } - } - - SCReturn; -} - -/** - * \brief Helper function used to print the content ids of all the contents that - * have been added to the bitarray of this SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - */ -void SigGroupHeadPrintContent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - uint32_t i = 0; - - SCLogDebug("Contents with the following content ids are present in this " - "SigGroupHead - "); - for (i = 0; i < DetectContentMaxId(de_ctx); i++) { - if (sgh->init->content_array[i / 8] & (1 << (i % 8))) - SCLogDebug("%" PRIu32, i); - } - - SCReturn; -} - -/** - * \brief Helper function used to print the total no of contents that have - * been added to the bitarray for this SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - */ -void SigGroupHeadPrintContentCnt(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - uint32_t i = 0; - uint32_t cnt = 0; - - for (i = 0; i < DetectContentMaxId(de_ctx); i++) { - if (sgh->init->content_array[i / 8] & (1 << (i % 8))) - cnt++; - } - - SCLogDebug("Total contents added to the SigGroupHead content bitarray: " - "%" PRIu32, cnt); - - SCReturn; -} - -/** - * \brief Loads all the content ids from all the contents belonging to all the - * Signatures in this SigGroupHead, into a bitarray. A fast and an - * efficient way of comparing pattern sets. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval 0 On success, i.e. on either the detection engine context being NULL - * or on successfully allocating memory and updating it with relevant - * data. - * \retval -1 On failure. - */ -int SigGroupHeadLoadContent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - SigMatch *sm = NULL; - uint32_t sig = 0; - DetectContentData *co = NULL; - - if (sgh == NULL) - return 0; - - if (DetectContentMaxId(de_ctx) == 0) - return 0; - - BUG_ON(sgh->init == NULL); - - sgh->init->content_size = (DetectContentMaxId(de_ctx) / 8) + 1; - sgh->init->content_array = SCMalloc(sgh->init->content_size); - if (sgh->init->content_array == NULL) - return -1; - - memset(sgh->init->content_array,0, sgh->init->content_size); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (s->alproto != ALPROTO_UNKNOWN) - continue; - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm == NULL) - continue; - - for ( ;sm != NULL; sm = sm->next) { - if (sm->type == DETECT_CONTENT) { - co = (DetectContentData *)sm->ctx; - - sgh->init->content_array[co->id / 8] |= 1 << (co->id % 8); - } - } - } - - return 0; -} - -/** - * \brief Clears the memory allocated by SigGroupHeadLoadContent() for the - * bitarray to hold the content ids for a SigGroupHead. - * - * \param Pointer to the SigGroupHead whose content_array would to be cleared. - * - * \ret 0 Always. - */ -int SigGroupHeadClearContent(SigGroupHead *sh) -{ - if (sh == NULL) - return 0; - - if (sh->init->content_array != NULL) { - SCFree(sh->init->content_array); - sh->init->content_array = NULL; - sh->init->content_size = 0; - } - return 0; -} - -/** - * \brief Loads all the uri content ids from all the uri contents belonging to - * all the Signatures in this SigGroupHead, into a bitarray. A fast and - * an efficient way of comparing pattern sets. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval 0 On success, i.e. on either the detection engine context being NULL - * or on successfully allocating memory and updating it with relevant - * data. - * \retval -1 On failure. - */ -int SigGroupHeadLoadUricontent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - SigMatch *sm = NULL; - uint32_t sig = 0; - DetectContentData *co = NULL; - - if (sgh == NULL) - return 0; - - if (DetectUricontentMaxId(de_ctx) == 0) - return 0; - - BUG_ON(sgh->init == NULL); - - sgh->init->uri_content_size = (DetectUricontentMaxId(de_ctx) / 8) + 1; - sgh->init->uri_content_array = SCMalloc(sgh->init->uri_content_size); - if (sgh->init->uri_content_array == NULL) - return -1; - - memset(sgh->init->uri_content_array, 0, sgh->init->uri_content_size); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - - if (s == NULL) - continue; - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm == NULL) - continue; - - for ( ;sm != NULL; sm = sm->next) { - if (sm->type == DETECT_CONTENT) { - co = (DetectContentData *)sm->ctx; - - sgh->init->uri_content_array[co->id / 8] |= 1 << (co->id % 8); - } - } - } - - return 0; -} - -/** - * \brief Clears the memory allocated by SigGroupHeadLoadUriContent() for the - * bitarray to hold the uri content ids for a SigGroupHead. - * - * \param Pointer to the SigGroupHead whose uri_content_array would to be - * cleared. - * - * \retval 0 Always. - */ -int SigGroupHeadClearUricontent(SigGroupHead *sh) -{ - if (sh == NULL) - return 0; - - if (sh->init->uri_content_array != NULL) { - SCFree(sh->init->uri_content_array); - sh->init->uri_content_array = NULL; - sh->init->uri_content_size = 0; - } - - return 0; -} - -/** - * \brief Loads all the content ids from all the contents belonging to all the - * Signatures in this SigGroupHead, into a bitarray. A fast and an - * efficient way of comparing pattern sets. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval 0 On success, i.e. on either the detection engine context being NULL - * or on successfully allocating memory and updating it with relevant - * data. - * \retval -1 On failure. - */ -int SigGroupHeadLoadStreamContent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - Signature *s = NULL; - SigMatch *sm = NULL; - uint32_t sig = 0; - DetectContentData *co = NULL; - - if (sgh == NULL) { - SCReturnInt(0); - } - - if (DetectContentMaxId(de_ctx) == 0) { - SCReturnInt(0); - } - - BUG_ON(sgh->init == NULL); - - sgh->init->stream_content_size = (DetectContentMaxId(de_ctx) / 8) + 1; - sgh->init->stream_content_array = SCMalloc(sgh->init->stream_content_size); - if (sgh->init->stream_content_array == NULL) { - SCReturnInt(-1); - } - - memset(sgh->init->stream_content_array,0, sgh->init->stream_content_size); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - - SCLogDebug("s %"PRIu32, s->id); - - if (s == NULL) - continue; - - if (SignatureHasPacketContent(s)) { - SCLogDebug("Sig has packet content"); - continue; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm == NULL) - continue; - - for ( ;sm != NULL; sm = sm->next) { - if (sm->type == DETECT_CONTENT) { - co = (DetectContentData *)sm->ctx; - - sgh->init->stream_content_array[co->id / 8] |= 1 << (co->id % 8); - } - } - } - - SCReturnInt(0); -} - -/** - * \brief Clears the memory allocated by SigGroupHeadLoadContent() for the - * bitarray to hold the content ids for a SigGroupHead. - * - * \param Pointer to the SigGroupHead whose content_array would to be cleared. - * - * \ret 0 Always. - */ -int SigGroupHeadClearStreamContent(SigGroupHead *sh) -{ - if (sh == NULL) - return 0; - - if (sh->init->stream_content_array != NULL) { - SCFree(sh->init->stream_content_array); - sh->init->stream_content_array = NULL; - sh->init->stream_content_size = 0; - } - return 0; -} - -/** - * \brief Create an array with all the internal ids of the sigs that this - * sig group head will check for. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * \param max_idx The maximum value of the sid in the SigGroupHead arg. - * - * \retval 0 success - * \retval -1 error - */ -int SigGroupHeadBuildMatchArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - uint32_t max_idx) -{ - Signature *s = NULL; - uint32_t idx = 0; - uint32_t sig = 0; - - if (sgh == NULL) - return 0; - - BUG_ON(sgh->match_array != NULL); - - sgh->match_array = SCMalloc(sgh->sig_cnt * sizeof(Signature *)); - if (sgh->match_array == NULL) - return -1; - - memset(sgh->match_array,0, sgh->sig_cnt * sizeof(Signature *)); - - detect_siggroup_matcharray_init_cnt++; - detect_siggroup_matcharray_memory += (sgh->sig_cnt * sizeof(Signature *)); - - for (sig = 0; sig < max_idx + 1; sig++) { - if (!(sgh->init->sig_array[(sig / 8)] & (1 << (sig % 8))) ) - continue; - - s = de_ctx->sig_array[sig]; - if (s == NULL) - continue; - - sgh->match_array[idx] = s; - idx++; - } - - return 0; -} - -/** - * \brief Set the need md5 flag in the sgh. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the flag in - */ -void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - - if (sgh == NULL) - return; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (SignatureIsFilemagicInspecting(s)) { - sgh->flags |= SIG_GROUP_HEAD_HAVEFILEMAGIC; - break; - } - } - - return; -} - -/** - * \brief Get size of the shortest mpm pattern. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the flag in - * \param list sm_list to consider - */ -uint16_t SigGroupHeadGetMinMpmSize(DetectEngineCtx *de_ctx, - SigGroupHead *sgh, int list) -{ - Signature *s = NULL; - uint32_t sig = 0; - uint16_t min = USHRT_MAX; - - if (sgh == NULL) - return 0; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - uint16_t mpm_content_minlen = SignatureGetMpmPatternLen(s, DETECT_SM_LIST_PMATCH); - if (mpm_content_minlen > 0) { - if (mpm_content_minlen < min) - min = mpm_content_minlen; - SCLogDebug("mpm_content_minlen %u", mpm_content_minlen); - } - } - - if (min == USHRT_MAX) - min = 0; - SCLogDebug("min mpm size %u", min); - return min; -} - -/** - * \brief Set the need size flag in the sgh. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the flag in - */ -void SigGroupHeadSetFilesizeFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - - if (sgh == NULL) - return; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (SignatureIsFilesizeInspecting(s)) { - sgh->flags |= SIG_GROUP_HEAD_HAVEFILESIZE; - break; - } - } - - return; -} - -/** - * \brief Set the need magic flag in the sgh. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the flag in - */ -void SigGroupHeadSetFileMd5Flag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - - if (sgh == NULL) - return; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (SignatureIsFileMd5Inspecting(s)) { - sgh->flags |= SIG_GROUP_HEAD_HAVEFILEMD5; - SCLogDebug("sgh %p has filemd5", sgh); - break; - } - } - - return; -} - -/** - * \brief Set the filestore_cnt in the sgh. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the counter in - */ -void SigGroupHeadSetFilestoreCount(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - - if (sgh == NULL) - return; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (SignatureIsFilestoring(s)) { - sgh->filestore_cnt++; - } - } - - return; -} - -/** \brief build an array of rule id's for sigs with no mpm - * Also updated de_ctx::non_mpm_store_cnt_max to track the highest cnt - */ -int SigGroupHeadBuildNonMpmArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - uint32_t non_mpm = 0; - - if (sgh == NULL) - return 0; - - BUG_ON(sgh->non_mpm_store_array != NULL); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (s->mpm_sm == NULL) - non_mpm++; - else if (s->flags & (SIG_FLAG_MPM_PACKET_NEG|SIG_FLAG_MPM_STREAM_NEG|SIG_FLAG_MPM_APPLAYER_NEG)) - non_mpm++; - } - - if (non_mpm == 0) { - sgh->non_mpm_store_array = NULL; - return 0; - } - - sgh->non_mpm_store_array = SCMalloc(non_mpm * sizeof(SignatureNonMpmStore)); - BUG_ON(sgh->non_mpm_store_array == NULL); - memset(sgh->non_mpm_store_array, 0, non_mpm * sizeof(SignatureNonMpmStore)); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (s->mpm_sm == NULL) { - BUG_ON(sgh->non_mpm_store_cnt >= non_mpm); - sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].id = s->num; - sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].mask = s->mask; - sgh->non_mpm_store_cnt++; - } else if (s->flags & (SIG_FLAG_MPM_PACKET_NEG|SIG_FLAG_MPM_STREAM_NEG|SIG_FLAG_MPM_APPLAYER_NEG)) { - BUG_ON(sgh->non_mpm_store_cnt >= non_mpm); - sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].id = s->num; - sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].mask = s->mask; - sgh->non_mpm_store_cnt++; - } - } - - /* track highest cnt for any sgh in our de_ctx */ - if (sgh->non_mpm_store_cnt > de_ctx->non_mpm_store_cnt_max) - de_ctx->non_mpm_store_cnt_max = sgh->non_mpm_store_cnt; - - return 0; -} - -/** - * \brief Check if a SigGroupHead contains a Signature, whose sid is sent as an - * argument. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead that has to be checked for the - * presence of a Signature. - * \param sid The Signature id(sid) that has to be checked in the SigGroupHead. - * - * \retval 1 On successfully finding the sid in the SigGroupHead. - * \retval 0 If the sid is not found in the SigGroupHead - */ -int SigGroupHeadContainsSigId(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - uint32_t sid) -{ - SCEnter(); - - uint32_t sig = 0; - Signature *s = NULL; - uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx); - - if (sgh == NULL) { - SCReturnInt(0); - } - - for (sig = 0; sig < max_sid; sig++) { - if (sgh->init->sig_array == NULL) { - SCReturnInt(0); - } - - /* Check if the SigGroupHead has an entry for the sid */ - if ( !(sgh->init->sig_array[sig / 8] & (1 << (sig % 8))) ) - continue; - - /* If we have reached here, we have an entry for sid in the SigGrouHead. - * Retrieve the Signature from the detection engine context */ - s = de_ctx->sig_array[sig]; - if (s == NULL) - continue; - - /* If the retrieved Signature matches the sid arg, we have a match */ - if (s->id == sid) { - SCReturnInt(1); - } - } - - SCReturnInt(0); -} - -/*----------------------------------Unittests---------------------------------*/ - -#ifdef UNITTESTS - -int SigAddressPrepareStage1(DetectEngineCtx *); - -/** - * \test Check if a SigGroupHead mpm hash table is properly allocated and - * deallocated when calling SigGroupHeadMpmHashInit() and - * SigGroupHeadMpmHashFree() respectively. - */ -static int SigGroupHeadTest01(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadMpmHashInit(&de_ctx); - - result &= (de_ctx.sgh_mpm_hash_table != NULL); - - SigGroupHeadMpmHashFree(&de_ctx); - - result &= (de_ctx.sgh_mpm_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHead mpm uri hash table is properly allocated and - * deallocated when calling SigGroupHeadMpmUriHashInit() and - * SigGroupHeadMpmUriHashFree() respectively. - */ -static int SigGroupHeadTest02(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadMpmUriHashInit(&de_ctx); - - result &= (de_ctx.sgh_mpm_uri_hash_table != NULL); - - SigGroupHeadMpmUriHashFree(&de_ctx); - - result &= (de_ctx.sgh_mpm_uri_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHead hash table is properly allocated and - * deallocated when calling SigGroupHeadHashInit() and - * SigGroupHeadHashFree() respectively. - */ -static int SigGroupHeadTest03(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadHashInit(&de_ctx); - - result &= (de_ctx.sgh_hash_table != NULL); - - SigGroupHeadHashFree(&de_ctx); - - result &= (de_ctx.sgh_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHead dport hash table is properly allocated and - * deallocated when calling SigGroupHeadDPortHashInit() and - * SigGroupHeadDportHashFree() respectively. - */ -static int SigGroupHeadTest04(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadDPortHashInit(&de_ctx); - - result &= (de_ctx.sgh_dport_hash_table != NULL); - - SigGroupHeadDPortHashFree(&de_ctx); - - result &= (de_ctx.sgh_dport_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHead dport hash table is properly allocated and - * deallocated when calling SigGroupHeadSPortHashInit() and - * SigGroupHeadSportHashFree() respectively. - */ -static int SigGroupHeadTest05(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadSPortHashInit(&de_ctx); - - result &= (de_ctx.sgh_sport_hash_table != NULL); - - SigGroupHeadSPortHashFree(&de_ctx); - - result &= (de_ctx.sgh_sport_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHeadAppendSig() correctly appends a sid to a - * SigGroupHead() and SigGroupHeadContainsSigId() correctly indicates - * the presence of a sid. - */ -static int SigGroupHeadTest06(void) -{ - int result = 1; - SigGroupHead *sh = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *prev_sig = NULL; - - if (de_ctx == NULL) - return 0; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:0;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - prev_sig = de_ctx->sig_list; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:1;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:2;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:3;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:4;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - SigAddressPrepareStage1(de_ctx); - - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next->next->next); - - SigGroupHeadSetSigCnt(sh, 4); - - result &= (sh->sig_cnt == 3); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 0) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 2) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 4) == 1); - - SigGroupHeadFree(sh); - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if a SigGroupHeadAppendSig(), correctly appends a sid to a - * SigGroupHead() and SigGroupHeadContainsSigId(), correctly indicates - * the presence of a sid and SigGroupHeadClearSigs(), correctly clears - * the SigGroupHead->sig_array and SigGroupHead->sig_cnt. - */ -static int SigGroupHeadTest07(void) -{ - int result = 1; - SigGroupHead *sh = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *prev_sig = NULL; - - if (de_ctx == NULL) - return 0; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:0;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - prev_sig = de_ctx->sig_list; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:1;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:2;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:3;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:4;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - SigAddressPrepareStage1(de_ctx); - - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next->next->next); - - SigGroupHeadSetSigCnt(sh, 4); - - result &= (sh->sig_cnt == 3); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 0) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 2) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 4) == 1); - - SigGroupHeadClearSigs(sh); - - result &= (sh->sig_cnt == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 0) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 2) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 4) == 0); - - SigGroupHeadFree(sh); - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if SigGroupHeadCopySigs(), correctly copies the sig_array from - * the source to the destination SigGroupHead. - */ -static int SigGroupHeadTest08(void) -{ - int result = 1; - SigGroupHead *src_sh = NULL; - SigGroupHead *dst_sh = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *prev_sig = NULL; - - if (de_ctx == NULL) - return 0; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:0;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - prev_sig = de_ctx->sig_list; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:1;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:2;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:3;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:4;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - SigAddressPrepareStage1(de_ctx); - - SigGroupHeadAppendSig(de_ctx, &src_sh, de_ctx->sig_list); - SigGroupHeadAppendSig(de_ctx, &src_sh, de_ctx->sig_list->next->next); - SigGroupHeadAppendSig(de_ctx, &src_sh, de_ctx->sig_list->next->next->next->next); - - SigGroupHeadSetSigCnt(src_sh, 4); - - result &= (src_sh->sig_cnt == 3); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 0) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 2) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 4) == 1); - - SigGroupHeadCopySigs(de_ctx, src_sh, &dst_sh); - - SigGroupHeadSetSigCnt(dst_sh, 4); - - result &= (dst_sh->sig_cnt == 3); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 0) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 2) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 4) == 1); - - SigGroupHeadFree(src_sh); - SigGroupHeadFree(dst_sh); - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if SigGroupHeadBuildMatchArray(), correctly updates the - * match array with the sids. - */ -static int SigGroupHeadTest09(void) -{ - int result = 1; - SigGroupHead *sh = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *prev_sig = NULL; - - if (de_ctx == NULL) - return 0; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:0;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - prev_sig = de_ctx->sig_list; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:1;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:2;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:3;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:4;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - SigAddressPrepareStage1(de_ctx); - - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next->next->next); - - SigGroupHeadSetSigCnt(sh, 4); - SigGroupHeadBuildMatchArray(de_ctx, sh, 4); - - result &= (sh->match_array[0] == de_ctx->sig_list); - result &= (sh->match_array[1] == de_ctx->sig_list->next->next); - result &= (sh->match_array[2] == de_ctx->sig_list->next->next->next->next); - - SigGroupHeadFree(sh); - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test ICMP(?) sig grouping bug. - */ -static int SigGroupHeadTest10(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *s = NULL; - Packet *p = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - - memset(&th_v, 0, sizeof(ThreadVars)); - - p = UTHBuildPacketSrcDst(NULL, 0, IPPROTO_ICMP, "192.168.1.1", "1.2.3.4"); - p->icmpv4h->type = 5; - p->icmpv4h->code = 1; - - /* originally ip's were - p.src.addr_data32[0] = 0xe08102d3; - p.dst.addr_data32[0] = 0x3001a8c0; - */ - - if (de_ctx == NULL) - return 0; - - s = DetectEngineAppendSig(de_ctx, "alert icmp 192.168.0.0/16 any -> any any (icode:>1; itype:11; sid:1; rev:1;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> 192.168.0.0/16 any (icode:1; itype:5; sid:2; rev:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - AddressDebugPrint(&p->dst); - - SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - goto end; - } - - result = 1; -end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test sig grouping bug. - */ -static int SigGroupHeadTest11(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *s = NULL; - Packet *p = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - - memset(&th_v, 0, sizeof(ThreadVars)); - - p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "192.168.1.1", "1.2.3.4", 60000, 80); - - if (de_ctx == NULL || p == NULL) - return 0; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any 1024: -> any 1024: (content:\"abc\"; sid:1;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"def\"; http_client_body; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - AddressDebugPrint(&p->dst); - - SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - goto end; - } - - /* check if hcbd flag is set in sgh */ - if (!(sgh->flags & SIG_GROUP_HEAD_MPM_HCBD)) { - printf("sgh has not SIG_GROUP_HEAD_MPM_HCBD flag set: "); - goto end; - } - - /* check if sig 2 is part of the sgh */ - - result = 1; -end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - UTHFreePackets(&p, 1); - return result; -} -#endif - -void SigGroupHeadRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SigGroupHeadTest01", SigGroupHeadTest01, 1); - UtRegisterTest("SigGroupHeadTest02", SigGroupHeadTest02, 1); - UtRegisterTest("SigGroupHeadTest03", SigGroupHeadTest03, 1); - UtRegisterTest("SigGroupHeadTest04", SigGroupHeadTest04, 1); - UtRegisterTest("SigGroupHeadTest05", SigGroupHeadTest05, 1); - UtRegisterTest("SigGroupHeadTest06", SigGroupHeadTest06, 1); - UtRegisterTest("SigGroupHeadTest07", SigGroupHeadTest07, 1); - UtRegisterTest("SigGroupHeadTest08", SigGroupHeadTest08, 1); - UtRegisterTest("SigGroupHeadTest09", SigGroupHeadTest09, 1); - UtRegisterTest("SigGroupHeadTest10", SigGroupHeadTest10, 1); - UtRegisterTest("SigGroupHeadTest11", SigGroupHeadTest11, 1); -#endif -} diff --git a/framework/src/suricata/src/detect-engine-siggroup.h b/framework/src/suricata/src/detect-engine-siggroup.h deleted file mode 100644 index cd6810a1..00000000 --- a/framework/src/suricata/src/detect-engine-siggroup.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_SIGGROUP_H__ -#define __DETECT_ENGINE_SIGGROUP_H__ - -void DetectSigGroupPrintMemory(void); - -int SigGroupHeadAppendSig(DetectEngineCtx *, SigGroupHead **, Signature *); -int SigGroupHeadClearSigs(SigGroupHead *); -int SigGroupHeadCopySigs(DetectEngineCtx *, SigGroupHead *, SigGroupHead **); - -int SigGroupHeadLoadContent(DetectEngineCtx *, SigGroupHead *); -int SigGroupHeadLoadUricontent(DetectEngineCtx *, SigGroupHead *); -int SigGroupHeadLoadStreamContent(DetectEngineCtx *, SigGroupHead *); -int SigGroupHeadClearContent(SigGroupHead *); -int SigGroupHeadClearUricontent(SigGroupHead *); -int SigGroupHeadClearStreamContent(SigGroupHead *); - -void SigGroupHeadFree(SigGroupHead *); - -void SigGroupHeadFreeMpmArrays(DetectEngineCtx *); - -SigGroupHead *SigGroupHeadHashLookup(DetectEngineCtx *, SigGroupHead *); -SigGroupHead *SigGroupHeadMpmHashLookup(DetectEngineCtx *, SigGroupHead *); -SigGroupHead *SigGroupHeadMpmUriHashLookup(DetectEngineCtx *, SigGroupHead *); -SigGroupHead *SigGroupHeadMpmStreamHashLookup(DetectEngineCtx *, SigGroupHead *); -SigGroupHead *SigGroupHeadDPortHashLookup(DetectEngineCtx *, SigGroupHead *); -SigGroupHead *SigGroupHeadSPortHashLookup(DetectEngineCtx *, SigGroupHead *); - -int SigGroupHeadMpmHashAdd(DetectEngineCtx *, SigGroupHead *); -int SigGroupHeadMpmUriHashAdd(DetectEngineCtx *, SigGroupHead *); -int SigGroupHeadMpmStreamHashAdd(DetectEngineCtx *, SigGroupHead *); -int SigGroupHeadHashAdd(DetectEngineCtx *, SigGroupHead *); -int SigGroupHeadDPortHashAdd(DetectEngineCtx *, SigGroupHead *); -int SigGroupHeadSPortHashAdd(DetectEngineCtx *, SigGroupHead *); - -void SigGroupHeadHashFree(DetectEngineCtx *); -void SigGroupHeadMpmHashFree(DetectEngineCtx *); -void SigGroupHeadMpmUriHashFree(DetectEngineCtx *); -void SigGroupHeadMpmStreamHashFree(DetectEngineCtx *); -void SigGroupHeadDPortHashFree(DetectEngineCtx *); -void SigGroupHeadSPortHashFree(DetectEngineCtx *); - -int SigGroupHeadHashInit(DetectEngineCtx *); -int SigGroupHeadMpmHashInit(DetectEngineCtx *); -int SigGroupHeadMpmUriHashInit(DetectEngineCtx *); -int SigGroupHeadDPortHashInit(DetectEngineCtx *); -int SigGroupHeadSPortHashInit(DetectEngineCtx *); - -int SigGroupHeadHashRemove(DetectEngineCtx *, SigGroupHead *); -int SigGroupHeadSPortHashRemove(DetectEngineCtx *, SigGroupHead *); - -void SigGroupHeadInitDataFree(SigGroupHeadInitData *sghid); -void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx); -int SigGroupHeadBuildMatchArray (DetectEngineCtx *de_ctx, SigGroupHead *sgh, - uint32_t max_idx); -void SigGroupHeadFreeSigArrays(DetectEngineCtx *de_ctx); - -int SigGroupHeadContainsSigId (DetectEngineCtx *de_ctx, SigGroupHead *sgh, - uint32_t sid); - -void SigGroupHeadRegisterTests(void); -void SigGroupHeadPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh); - -void SigGroupHeadStore(DetectEngineCtx *, SigGroupHead *); -void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *, SigGroupHead *); -void SigGroupHeadSetFilestoreCount(DetectEngineCtx *, SigGroupHead *); -void SigGroupHeadSetFileMd5Flag(DetectEngineCtx *, SigGroupHead *); -void SigGroupHeadSetFilesizeFlag(DetectEngineCtx *, SigGroupHead *); -uint16_t SigGroupHeadGetMinMpmSize(DetectEngineCtx *de_ctx, - SigGroupHead *sgh, int list); - -int SigGroupHeadBuildNonMpmArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh); - -#endif /* __DETECT_ENGINE_SIGGROUP_H__ */ diff --git a/framework/src/suricata/src/detect-engine-sigorder.c b/framework/src/suricata/src/detect-engine-sigorder.c deleted file mode 100644 index 0baa87a2..00000000 --- a/framework/src/suricata/src/detect-engine-sigorder.c +++ /dev/null @@ -1,2201 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Signature ordering part of the detection engine. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-xbits.h" -#include "detect-flowbits.h" -#include "detect-flowint.h" -#include "detect-parse.h" -#include "detect-engine-sigorder.h" -#include "detect-pcre.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" -#include "util-action.h" -#include "action-globals.h" -#include "flow-util.h" - -#define DETECT_FLOWVAR_NOT_USED 1 -#define DETECT_FLOWVAR_TYPE_READ 2 -#define DETECT_FLOWVAR_TYPE_SET_READ 3 -#define DETECT_FLOWVAR_TYPE_SET 4 - -#define DETECT_PKTVAR_NOT_USED 1 -#define DETECT_PKTVAR_TYPE_READ 2 -#define DETECT_PKTVAR_TYPE_SET_READ 3 -#define DETECT_PKTVAR_TYPE_SET 4 - -#define DETECT_FLOWBITS_NOT_USED 1 -#define DETECT_FLOWBITS_TYPE_READ 2 -#define DETECT_FLOWBITS_TYPE_SET_READ 3 -#define DETECT_FLOWBITS_TYPE_SET 4 - -#define DETECT_FLOWINT_NOT_USED 1 -#define DETECT_FLOWINT_TYPE_READ 2 -#define DETECT_FLOWINT_TYPE_SET_READ 3 -#define DETECT_FLOWINT_TYPE_SET 4 - -#define DETECT_XBITS_NOT_USED 1 -#define DETECT_XBITS_TYPE_READ 2 -#define DETECT_XBITS_TYPE_SET_READ 3 -#define DETECT_XBITS_TYPE_SET 4 - - -/** - * \brief Registers a keyword-based, signature ordering function - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures have to be ordered. - * \param FuncPtr Pointer to the signature ordering function. The prototype of - * the signature ordering function should accept a pointer to a - * SCSigSignatureWrapper as its argument and shouldn't return - * anything - */ -static void SCSigRegisterSignatureOrderingFunc(DetectEngineCtx *de_ctx, - int (*SWCompare)(SCSigSignatureWrapper *sw1, SCSigSignatureWrapper *sw2)) -{ - SCSigOrderFunc *curr = NULL; - SCSigOrderFunc *prev = NULL; - SCSigOrderFunc *temp = NULL; - - curr = de_ctx->sc_sig_order_funcs; - - /* Walk to the end of the list, and leave prev pointing at the - last element. */ - prev = curr; - while (curr != NULL) { - if (curr->SWCompare == SWCompare) { - /* Already specified this compare */ - return; - } - prev = curr; - curr = curr->next; - } - - if ( (temp = SCMalloc(sizeof(SCSigOrderFunc))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCSigRegisterSignatureOrderingFunc. Exiting..."); - exit(EXIT_FAILURE); - } - memset(temp, 0, sizeof(SCSigOrderFunc)); - - temp->SWCompare = SWCompare; - - /* Append the new compare function at the end of the list. */ - if (prev == NULL) - de_ctx->sc_sig_order_funcs = temp; - else - prev->next = temp; - - return; -} - -/** - * \brief Returns the flowbit type set for this signature. If more than one - * flowbit has been set for the same rule, we return the flowbit type of - * the maximum priority/value, where priority/value is maximum for the - * ones that set the value and the lowest for ones that read the value. - * If no flowbit has been set for the rule, we return 0, which indicates - * the least value amongst flowbit types. - * - * \param sig Pointer to the Signature from which the flowbit value has to be - * returned. - * - * \retval flowbits The flowbits type for this signature if it is set; if it is - * not set, return 0 - */ -static inline int SCSigGetFlowbitsType(Signature *sig) -{ - DetectFlowbitsData *fb = NULL; - int flowbits_user_type = DETECT_FLOWBITS_NOT_USED; - int read = 0; - int write = 0; - SigMatch *sm = sig->sm_lists[DETECT_SM_LIST_MATCH]; - - while (sm != NULL) { - if (sm->type == DETECT_FLOWBITS) { - fb = (DetectFlowbitsData *)sm->ctx; - if (fb->cmd == DETECT_FLOWBITS_CMD_ISNOTSET || - fb->cmd == DETECT_FLOWBITS_CMD_ISSET) { - read++; - } else { -#ifdef DEBUG - BUG_ON(1); -#endif - } - } - - sm = sm->next; - } - - sm = sig->sm_lists[DETECT_SM_LIST_POSTMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_FLOWBITS) { - fb = (DetectFlowbitsData *)sm->ctx; - if (fb->cmd == DETECT_FLOWBITS_CMD_SET || - fb->cmd == DETECT_FLOWBITS_CMD_UNSET || - fb->cmd == DETECT_FLOWBITS_CMD_TOGGLE) { - write++; - } else { -#ifdef DEBUG - BUG_ON(1); -#endif - } - } - - sm = sm->next; - } - - if (read > 0 && write == 0) { - flowbits_user_type = DETECT_FLOWBITS_TYPE_READ; - } else if (read == 0 && write > 0) { - flowbits_user_type = DETECT_FLOWBITS_TYPE_SET; - } else if (read > 0 && write > 0) { - flowbits_user_type = DETECT_FLOWBITS_TYPE_SET_READ; - } - - SCLogDebug("Sig %s typeval %d", sig->msg, flowbits_user_type); - - return flowbits_user_type; -} - -static inline int SCSigGetFlowintType(Signature *sig) -{ - DetectFlowintData *fi = NULL; - int flowint_user_type = DETECT_FLOWINT_NOT_USED; - int read = 0; - int write = 0; - SigMatch *sm = sig->sm_lists[DETECT_SM_LIST_MATCH]; - - while (sm != NULL) { - if (sm->type == DETECT_FLOWINT) { - fi = (DetectFlowintData *)sm->ctx; - if (fi->modifier == FLOWINT_MODIFIER_LT || - fi->modifier == FLOWINT_MODIFIER_LE || - fi->modifier == FLOWINT_MODIFIER_EQ || - fi->modifier == FLOWINT_MODIFIER_NE || - fi->modifier == FLOWINT_MODIFIER_GE || - fi->modifier == FLOWINT_MODIFIER_GT || - fi->modifier == FLOWINT_MODIFIER_ISSET) { - read++; - } else { -#ifdef DEBUG - BUG_ON(1); -#endif - } - } - - sm = sm->next; - } - - sm = sig->sm_lists[DETECT_SM_LIST_POSTMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_FLOWINT) { - fi = (DetectFlowintData *)sm->ctx; - if (fi->modifier == FLOWINT_MODIFIER_SET || - fi->modifier == FLOWINT_MODIFIER_ADD || - fi->modifier == FLOWINT_MODIFIER_SUB) { - write++; - } else { -#ifdef DEBUG - BUG_ON(1); -#endif - } - } - - sm = sm->next; - } - - if (read > 0 && write == 0) { - flowint_user_type = DETECT_FLOWINT_TYPE_READ; - } else if (read == 0 && write > 0) { - flowint_user_type = DETECT_FLOWINT_TYPE_SET; - } else if (read > 0 && write > 0) { - flowint_user_type = DETECT_FLOWINT_TYPE_SET_READ; - } - - SCLogDebug("Sig %s typeval %d", sig->msg, flowint_user_type); - - return flowint_user_type; -} - -/** - * \brief Returns whether the flowvar set for this rule, sets the flowvar or - * reads the flowvar. If the rule sets the flowvar the function returns - * DETECT_FLOWVAR_TYPE_SET(3), if it reads the flowvar the function - * returns DETECT_FLOWVAR_TYPE_READ(2), and if flowvar is not used in this - * rule the function returns DETECT_FLOWVAR_NOT_USED(1) - * - * \param sig Pointer to the Signature from which the flowvar type has to be - * returned. - * - * \retval type DETECT_FLOWVAR_TYPE_SET(3) if the rule sets the flowvar, - * DETECT_FLOWVAR_TYPE_READ(2) if it reads, and - * DETECT_FLOWVAR_NOT_USED(1) if flowvar is not used. - */ -static inline int SCSigGetFlowvarType(Signature *sig) -{ - DetectPcreData *pd = NULL; - int type = DETECT_FLOWVAR_NOT_USED; - int read = 0; - int write = 0; - SigMatch *sm = sig->sm_lists[DETECT_SM_LIST_PMATCH]; - - while (sm != NULL) { - pd = (DetectPcreData *)sm->ctx; - if (sm->type == DETECT_PCRE && (pd->flags & DETECT_PCRE_CAPTURE_FLOW)) { - write++; - } - - sm = sm->next; - } - - sm = sig->sm_lists[DETECT_SM_LIST_MATCH]; - pd = NULL; - while (sm != NULL) { - if (sm->type == DETECT_FLOWVAR) { - read++; - } - - sm = sm->next; - } - - if (read > 0 && write == 0) { - type = DETECT_FLOWVAR_TYPE_READ; - } else if (read == 0 && write > 0) { - type = DETECT_FLOWVAR_TYPE_SET; - } else if (read > 0 && write > 0) { - type = DETECT_FLOWVAR_TYPE_SET_READ; - } - - return type; -} - -/** - * \brief Returns whether the pktvar set for this rule, sets the flowvar or - * reads the pktvar. If the rule sets the pktvar the function returns - * DETECT_PKTVAR_TYPE_SET(3), if it reads the pktvar the function - * returns DETECT_PKTVAR_TYPE_READ(2), and if pktvar is not used in this - * rule the function returns DETECT_PKTVAR_NOT_USED(1) - * - * \param sig Pointer to the Signature from which the pktvar type has to be - * returned. - * - * \retval type DETECT_PKTVAR_TYPE_SET(3) if the rule sets the flowvar, - * DETECT_PKTVAR_TYPE_READ(2) if it reads, and - * DETECT_PKTVAR_NOT_USED(1) if pktvar is not used. - */ -static inline int SCSigGetPktvarType(Signature *sig) -{ - DetectPcreData *pd = NULL; - int type = DETECT_PKTVAR_NOT_USED; - int read = 0; - int write = 0; - SigMatch *sm = sig->sm_lists[DETECT_SM_LIST_PMATCH]; - - while (sm != NULL) { - pd = (DetectPcreData *)sm->ctx; - if (sm->type == DETECT_PCRE && (pd->flags & DETECT_PCRE_CAPTURE_PKT)) { - write++; - } - - sm = sm->next; - } - - sm = sig->sm_lists[DETECT_SM_LIST_MATCH]; - pd = NULL; - while (sm != NULL) { - if (sm->type == DETECT_PKTVAR) { - read++; - } - - sm = sm->next; - } - - if (read > 0 && write == 0) { - type = DETECT_PKTVAR_TYPE_READ; - } else if (read == 0 && write > 0) { - type = DETECT_PKTVAR_TYPE_SET; - } else if (read > 0 && write > 0) { - type = DETECT_PKTVAR_TYPE_SET_READ; - } - - return type; -} - -/** - * \brief Returns the xbit type set for this signature. If more than one - * xbit has been set for the same rule, we return the xbit type of - * the maximum priority/value, where priority/value is maximum for the - * ones that set the value and the lowest for ones that read the value. - * If no xbit has been set for the rule, we return 0, which indicates - * the least value amongst xbit types. - * - * \param sig Pointer to the Signature from which the xbit value has to be - * returned. - * - * \retval xbits The xbits type for this signature if it is set; if it is - * not set, return 0 - */ -static inline int SCSigGetXbitsType(Signature *sig, enum VarTypes type) -{ - DetectXbitsData *fb = NULL; - int xbits_user_type = DETECT_XBITS_NOT_USED; - int read = 0; - int write = 0; - SigMatch *sm = sig->sm_lists[DETECT_SM_LIST_MATCH]; - - while (sm != NULL) { - if (sm->type == DETECT_XBITS) { - fb = (DetectXbitsData *)sm->ctx; - if (fb->type == type) { - if (fb->cmd == DETECT_XBITS_CMD_ISNOTSET || - fb->cmd == DETECT_XBITS_CMD_ISSET) { - read++; - } else { -#ifdef DEBUG - BUG_ON(1); -#endif - } - } - } - - sm = sm->next; - } - - sm = sig->sm_lists[DETECT_SM_LIST_POSTMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_HOSTBITS) { - fb = (DetectXbitsData *)sm->ctx; - if (fb->type == type) { - if (fb->cmd == DETECT_XBITS_CMD_SET || - fb->cmd == DETECT_XBITS_CMD_UNSET || - fb->cmd == DETECT_XBITS_CMD_TOGGLE) { - write++; - } else { -#ifdef DEBUG - BUG_ON(1); -#endif - } - } - } - - sm = sm->next; - } - - if (read > 0 && write == 0) { - xbits_user_type = DETECT_XBITS_TYPE_READ; - } else if (read == 0 && write > 0) { - xbits_user_type = DETECT_XBITS_TYPE_SET; - } else if (read > 0 && write > 0) { - xbits_user_type = DETECT_XBITS_TYPE_SET_READ; - } - - SCLogDebug("Sig %s typeval %d", sig->msg, xbits_user_type); - - return xbits_user_type; -} - -/** - * \brief Processes the flowbits data for this signature and caches it for - * future use. This is needed to optimize the sig_ordering module. - * - * \param sw The sigwrapper/signature for which the flowbits data has to be - * cached - */ -static inline void SCSigProcessUserDataForFlowbits(SCSigSignatureWrapper *sw) -{ - sw->user[SC_RADIX_USER_DATA_FLOWBITS] = SCSigGetFlowbitsType(sw->sig); -} - -/** - * \brief Processes the flowvar data for this signature and caches it for - * future use. This is needed to optimize the sig_ordering module. - * - * \param sw The sigwrapper/signature for which the flowvar data has to be - * cached - */ -static inline void SCSigProcessUserDataForFlowvar(SCSigSignatureWrapper *sw) -{ - sw->user[SC_RADIX_USER_DATA_FLOWVAR] = SCSigGetFlowvarType(sw->sig); -} - -static inline void SCSigProcessUserDataForFlowint(SCSigSignatureWrapper *sw) -{ - sw->user[SC_RADIX_USER_DATA_FLOWINT] = SCSigGetFlowintType(sw->sig); -} - -/** - * \brief Processes the pktvar data for this signature and caches it for - * future use. This is needed to optimize the sig_ordering module. - * - * \param sw The sigwrapper/signature for which the pktvar data has to be - * cached - */ -static inline void SCSigProcessUserDataForPktvar(SCSigSignatureWrapper *sw) -{ - sw->user[SC_RADIX_USER_DATA_PKTVAR] = SCSigGetPktvarType(sw->sig); -} - -/** - * \brief Processes the hostbits data for this signature and caches it for - * future use. This is needed to optimize the sig_ordering module. - * - * \param sw The sigwrapper/signature for which the hostbits data has to be - * cached - */ -static inline void SCSigProcessUserDataForHostbits(SCSigSignatureWrapper *sw) -{ - sw->user[SC_RADIX_USER_DATA_HOSTBITS] = SCSigGetXbitsType(sw->sig, VAR_TYPE_HOST_BIT); -} - -/** - * \brief Processes the hostbits data for this signature and caches it for - * future use. This is needed to optimize the sig_ordering module. - * - * \param sw The sigwrapper/signature for which the hostbits data has to be - * cached - */ -static inline void SCSigProcessUserDataForIPPairbits(SCSigSignatureWrapper *sw) -{ - sw->user[SC_RADIX_USER_DATA_IPPAIRBITS] = SCSigGetXbitsType(sw->sig, VAR_TYPE_IPPAIR_BIT); -} - -/* Return 1 if sw1 comes before sw2 in the final list. */ -static int SCSigLessThan(SCSigSignatureWrapper *sw1, - SCSigSignatureWrapper *sw2, - SCSigOrderFunc *cmp_func_list) -{ - SCSigOrderFunc *funcs = cmp_func_list; - - while (funcs != NULL) { - int delta = funcs->SWCompare(sw1, sw2); - if (delta > 0) - return 1; - else if (delta < 0) - return 0; - - funcs = funcs->next; - } - // They are equal, so use sid as the final decider. - return sw1->sig->id < sw2->sig->id; -} - -/* Merge sort based on a list of compare functions */ -static SCSigSignatureWrapper *SCSigOrder(SCSigSignatureWrapper *sw, - SCSigOrderFunc *cmp_func_list) -{ - SCSigSignatureWrapper *subA = NULL; - SCSigSignatureWrapper *subB = NULL; - SCSigSignatureWrapper *first; - SCSigSignatureWrapper *second; - SCSigSignatureWrapper *result = NULL; - SCSigSignatureWrapper *last = NULL; - SCSigSignatureWrapper *new = NULL; - - /* Divide input list into two sub-lists. */ - while (sw != NULL) { - first = sw; - sw = sw->next; - /* Push the first element onto sub-list A */ - first->next = subA; - subA = first; - - if (sw == NULL) - break; - second = sw; - sw = sw->next; - /* Push the second element onto sub-list B */ - second->next = subB; - subB = second; - } - if (subB == NULL) { - /* Only zero or one element on the list. */ - return subA; - } - - /* Now sort each list */ - subA = SCSigOrder(subA, cmp_func_list); - subB = SCSigOrder(subB, cmp_func_list); - - /* Merge the two sorted lists. */ - while (subA != NULL && subB != NULL) { - if (SCSigLessThan(subA, subB, cmp_func_list)) { - new = subA; - subA = subA->next; - } else { - new = subB; - subB = subB->next; - } - /* Push onto the end of the output list. */ - new->next = NULL; - if (result == NULL) { - result = new; - last = new; - } else { - last->next = new; - last = new; - } - } - /* Attach the rest of any remaining list. Only one can be non-NULL here. */ - if (subA == NULL) - last->next = subB; - else if (subB == NULL) - last->next = subA; - - return result; -} - -/** - * \brief Orders an incoming Signature based on its action - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures have to be ordered. - * \param sw The new signature that has to be ordered based on its action - */ -static int SCSigOrderByActionCompare(SCSigSignatureWrapper *sw1, - SCSigSignatureWrapper *sw2) -{ - return ActionOrderVal(sw2->sig->action) - ActionOrderVal(sw1->sig->action); -} - -/** - * \brief Orders an incoming Signature based on its flowbits type - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures have to be ordered. - * \param sw The new signature that has to be ordered based on its flowbits - */ -static int SCSigOrderByFlowbitsCompare(SCSigSignatureWrapper *sw1, - SCSigSignatureWrapper *sw2) -{ - return sw1->user[SC_RADIX_USER_DATA_FLOWBITS] - - sw2->user[SC_RADIX_USER_DATA_FLOWBITS]; -} - -/** - * \brief Orders an incoming Signature based on its flowvar type - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures have to be ordered. - * \param sw The new signature that has to be ordered based on its flowvar - */ -static int SCSigOrderByFlowvarCompare(SCSigSignatureWrapper *sw1, - SCSigSignatureWrapper *sw2) -{ - return sw1->user[SC_RADIX_USER_DATA_FLOWVAR] - - sw2->user[SC_RADIX_USER_DATA_FLOWVAR]; -} - -/** - * \brief Orders an incoming Signature based on its pktvar type - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures have to be ordered. - * \param sw The new signature that has to be ordered based on its pktvar - */ -static int SCSigOrderByPktvarCompare(SCSigSignatureWrapper *sw1, - SCSigSignatureWrapper *sw2) -{ - return sw1->user[SC_RADIX_USER_DATA_PKTVAR] - - sw2->user[SC_RADIX_USER_DATA_PKTVAR]; -} - -static int SCSigOrderByFlowintCompare(SCSigSignatureWrapper *sw1, - SCSigSignatureWrapper *sw2) -{ - return sw1->user[SC_RADIX_USER_DATA_FLOWINT] - - sw2->user[SC_RADIX_USER_DATA_FLOWINT]; -} - -/** - * \brief Orders an incoming Signature based on its hostbits type - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures have to be ordered. - * \param sw The new signature that has to be ordered based on its hostbits - */ -static int SCSigOrderByHostbitsCompare(SCSigSignatureWrapper *sw1, - SCSigSignatureWrapper *sw2) -{ - return sw1->user[SC_RADIX_USER_DATA_HOSTBITS] - - sw2->user[SC_RADIX_USER_DATA_HOSTBITS]; -} - -/** - * \brief Orders an incoming Signature based on its ippairbits (xbits) type - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures have to be ordered. - * \param sw The new signature that has to be ordered based on its bits - */ -static int SCSigOrderByIPPairbitsCompare(SCSigSignatureWrapper *sw1, - SCSigSignatureWrapper *sw2) -{ - return sw1->user[SC_RADIX_USER_DATA_IPPAIRBITS] - - sw2->user[SC_RADIX_USER_DATA_IPPAIRBITS]; -} - -/** - * \brief Orders an incoming Signature based on its priority type - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures have to be ordered. - * \param sw The new signature that has to be ordered based on its priority - */ -static int SCSigOrderByPriorityCompare(SCSigSignatureWrapper *sw1, - SCSigSignatureWrapper *sw2) -{ - return sw2->sig->prio - sw1->sig->prio; -} - -/** - * \brief Creates a Wrapper around the Signature - * - * \param Pointer to the Signature to be wrapped - * - * \retval sw Pointer to the wrapper that holds the signature - */ -static inline SCSigSignatureWrapper *SCSigAllocSignatureWrapper(Signature *sig) -{ - SCSigSignatureWrapper *sw = NULL; - - if ( (sw = SCMalloc(sizeof(SCSigSignatureWrapper))) == NULL) - return NULL; - memset(sw, 0, sizeof(SCSigSignatureWrapper)); - - sw->sig = sig; - - /* Process data from the signature into a cache for further use by the - * sig_ordering module */ - SCSigProcessUserDataForFlowbits(sw); - SCSigProcessUserDataForFlowvar(sw); - SCSigProcessUserDataForFlowint(sw); - SCSigProcessUserDataForPktvar(sw); - SCSigProcessUserDataForHostbits(sw); - SCSigProcessUserDataForIPPairbits(sw); - - return sw; -} - -/** - * \brief Orders the signatures - * - * \param de_ctx Pointer to the Detection Engine Context that holds the - * signatures to be ordered - */ -void SCSigOrderSignatures(DetectEngineCtx *de_ctx) -{ - Signature *sig = NULL; - SCSigSignatureWrapper *sigw = NULL; - SCSigSignatureWrapper *sigw_list = NULL; - - int i = 0; - SCLogDebug("ordering signatures in memory"); - - sig = de_ctx->sig_list; - while (sig != NULL) { - sigw = SCSigAllocSignatureWrapper(sig); - /* Push signature wrapper onto a list, order doesn't matter here. */ - sigw->next = sigw_list; - sigw_list = sigw; - - sig = sig->next; - i++; - } - - /* Sort the list */ - sigw_list = SCSigOrder(sigw_list, de_ctx->sc_sig_order_funcs); - - SCLogDebug("Total Signatures to be processed by the" - "sigordering module: %d", i); - - /* Recreate the sig list in order */ - de_ctx->sig_list = NULL; - sigw = sigw_list; - i = 0; - while (sigw != NULL) { - i++; - sigw->sig->next = NULL; - if (de_ctx->sig_list == NULL) { - /* First entry on the list */ - de_ctx->sig_list = sigw->sig; - sig = de_ctx->sig_list; - } else { - sig->next = sigw->sig; - sig = sig->next; - } - SCSigSignatureWrapper *sigw_to_free = sigw; - sigw = sigw->next; - SCFree(sigw_to_free); - } - - SCLogDebug("total signatures reordered by the sigordering module: %d", i); -} - -/** - * \brief Lets you register the Signature ordering functions. The order in - * which the functions are registered, show the priority. The first - * function registered provides more priority than the function - * registered after it. To add a new registration function, register - * it by listing it in the correct position in the below sequence, - * based on the priority you would want to offer to that keyword. - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures have to be ordered. - */ -void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx) -{ - SCLogDebug("registering signature ordering functions"); - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowintCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByHostbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByIPPairbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); -} - -/** - * \brief De-registers all the signature ordering functions registered - * - * \param de_ctx Pointer to the detection engine context from which the - * signatures were ordered. - */ -void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *de_ctx) -{ - SCSigOrderFunc *funcs; - void *temp; - - /* clean the memory alloted to the signature ordering funcs */ - funcs = de_ctx->sc_sig_order_funcs; - while (funcs != NULL) { - temp = funcs; - funcs = funcs->next; - SCFree(temp); - } - de_ctx->sc_sig_order_funcs = NULL; -} - -/**********Unittests**********/ - -DetectEngineCtx *DetectEngineCtxInit(void); -Signature *SigInit(DetectEngineCtx *, char *); -void SigFree(Signature *); -void DetectEngineCtxFree(DetectEngineCtx *); - -#ifdef UNITTESTS - -static int SCSigOrderingTest01(void) -{ - SCSigOrderFunc *temp = NULL; - int i = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - - temp = de_ctx->sc_sig_order_funcs; - while (temp != NULL) { - i++; - temp = temp->next; - } - - DetectEngineCtxFree(de_ctx); - - return (i == 5); - end: - return 0; -} - -static int SCSigOrderingTest02(void) -{ - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; flowvar:http_host,\"www.oisf.net\"; rev:4; priority:1; sid:4;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:5;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:6;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:7;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - - sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; rev:4; priority:3; flowbits:set,TEST.one; flowbits:noalert; sid:9;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; pktvar:http_host,\"www.oisf.net\"; priority:2; flowbits:isnotset,TEST.two; sid:13;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; flowbits:set,TEST.two; sid:14;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - - sig = de_ctx->sig_list; - -#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - /* pass */ - result &= (sig->id == 6); - sig = sig->next; - result &= (sig->id == 4); - sig = sig->next; - result &= (sig->id == 8); - sig = sig->next; - result &= (sig->id == 7); - sig = sig->next; - result &= (sig->id == 10); - sig = sig->next; - - /* drops */ - result &= (sig->id == 9); - sig = sig->next; - result &= (sig->id == 13); - sig = sig->next; - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 3); - sig = sig->next; - - /* alerts */ - result &= (sig->id == 14); - sig = sig->next; - result &= (sig->id == 5); - sig = sig->next; - result &= (sig->id == 1); - sig = sig->next; - result &= (sig->id == 11); - sig = sig->next; - result &= (sig->id == 12); - sig = sig->next; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SCSigOrderingTest03(void) -{ - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:1;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; flowbits:unset,TEST.one; rev:4; priority:2; sid:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; flowbits:isset,TEST.one; rev:4; priority:1; sid:4;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; priority:2; sid:5;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; flowbits:isnotset,TEST.one; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; rev:4; sid:6;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; flowbits:unset,TEST.one; rev:4; priority:3; sid:7;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/220[- ]/\"; flowbits:toggle,TEST.one; rev:4; priority:1; pktvar:http_host,\"www.oisf.net\"; sid:8;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; rev:4; flowbits:set,TEST.one; flowbits:noalert; pktvar:http_host,\"www.oisf.net\"; sid:9;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:10;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:11;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:12;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:isnotset,TEST.one; sid:13;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; flowbits:set,TEST.one; sid:14;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - - sig = de_ctx->sig_list; - -#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - result &= (sig->id == 3); - sig = sig->next; - result &= (sig->id == 8); - sig = sig->next; - result &= (sig->id == 9); - sig = sig->next; - result &= (sig->id == 7); - sig = sig->next; - result &= (sig->id == 14); - sig = sig->next; - result &= (sig->id == 6); - sig = sig->next; - result &= (sig->id == 4); - sig = sig->next; - result &= (sig->id == 13); - sig = sig->next; - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 5); - sig = sig->next; - result &= (sig->id == 1); - sig = sig->next; - result &= (sig->id == 10); - sig = sig->next; - result &= (sig->id == 11); - sig = sig->next; - result &= (sig->id == 12); - sig = sig->next; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SCSigOrderingTest04(void) -{ - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; content:\"220\"; offset:10; rev:4; priority:3; sid:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; rev:4; priority:3; flowvar:http_host,\"www.oisf.net\"; sid:4;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; pktvar:http_host,\"www.oisf.net\"; rev:4; priority:1; sid:6;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; flowvar:http_host,\"www.oisf.net\"; pktvar:http_host,\"www.oisf.net\"; priority:1; sid:7;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; flowvar:http_host,\"www.oisf.net\"; sid:8;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; flowvar:http_host,\"www.oisf.net\"; sid:9;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - - sig = de_ctx->sig_list; - -#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - /* flowvar set */ - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 3); - sig = sig->next; - result &= (sig->id == 4); - sig = sig->next; - result &= (sig->id == 7); - sig = sig->next; - result &= (sig->id == 8); - sig = sig->next; - result &= (sig->id == 9); - sig = sig->next; - - /* pktvar */ - result &= (sig->id == 5); - sig = sig->next; - result &= (sig->id == 6); - sig = sig->next; - - result &= (sig->id == 1); - sig = sig->next; - -end: - if (de_ctx) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SCSigOrderingTest05(void) -{ - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; content:\"220\"; offset:10; rev:4; priority:3; sid:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; rev:4; priority:3; sid:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; pcre:\"/^User-Agent: (?P.*)\\r\\n/m\"; rev:4; priority:3; pktvar:http_host,\"www.oisf.net\"; sid:4;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:3; sid:5;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:6;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; pktvar:http_host,\"www.oisf.net\"; sid:7;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; pktvar:http_host,\"www.oisf.net\"; sid:8;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - - sig = de_ctx->sig_list; - - //#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } - //#endif - - sig = de_ctx->sig_list; - - /* pktvar set */ - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 3); - sig = sig->next; - result &= (sig->id == 4); - sig = sig->next; - /* pktvar read */ - result &= (sig->id == 7); - sig = sig->next; - result &= (sig->id == 8); - sig = sig->next; - - result &= (sig->id == 1); - sig = sig->next; - result &= (sig->id == 5); - sig = sig->next; - result &= (sig->id == 6); - sig = sig->next; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SCSigOrderingTest06(void) -{ - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; rev:4; priority:2; sid:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - - result = 1; - - sig = de_ctx->sig_list; - -#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - result &= (sig->id == 6); - sig = sig->next; - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 4); - sig = sig->next; - result &= (sig->id == 5); - sig = sig->next; - result &= (sig->id == 7); - sig = sig->next; - result &= (sig->id == 8); - sig = sig->next; - result &= (sig->id == 1); - sig = sig->next; - result &= (sig->id == 3); - sig = sig->next; - - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SCSigOrderingTest07(void) -{ - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:10; sid:2; rev:4; priority:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4; priority:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - - sig = de_ctx->sig_list; - -#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 4); - sig = sig->next; - result &= (sig->id == 5); - sig = sig->next; - result &= (sig->id == 7); - sig = sig->next; - result &= (sig->id == 6); - sig = sig->next; - result &= (sig->id == 8); - sig = sig->next; - result &= (sig->id == 1); - sig = sig->next; - result &= (sig->id == 3); - sig = sig->next; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Order with a different Action priority - * (as specified from config) - */ -static int SCSigOrderingTest08(void) -{ -#ifdef HAVE_LIBNET11 - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - extern uint8_t action_order_sigs[4]; - - /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */ - action_order_sigs[0] = ACTION_REJECT; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_ALERT; - action_order_sigs[3] = ACTION_PASS; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1; rev:4;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:10; sid:2; rev:4; priority:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:10; depth:4; sid:3; rev:4; priority:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:10; depth:4; sid:4; rev:4; priority:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:5; rev:4; priority:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "reject tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:6; rev:4; priority:1;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; sid:7; rev:4;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; sid:8; rev:4; priority:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - - sig = de_ctx->sig_list; - -#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - result &= (sig->id == 6); - sig = sig->next; - result &= (sig->id == 8); - sig = sig->next; - result &= (sig->id == 1); - sig = sig->next; - result &= (sig->id == 3); - sig = sig->next; - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 4); - sig = sig->next; - result &= (sig->id == 5); - sig = sig->next; - result &= (sig->id == 7); - sig = sig->next; - -end: - /* Restore the default pre-order definition */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -#else - return 1; -#endif -} - -/** - * \test Order with a different Action priority - * (as specified from config) - */ -static int SCSigOrderingTest09(void) -{ - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - extern uint8_t action_order_sigs[4]; - - /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */ - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_REJECT; - action_order_sigs[2] = ACTION_ALERT; - action_order_sigs[3] = ACTION_PASS; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:1;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:10; priority:2; sid:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:10; depth:4; priority:3; sid:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - - sig = de_ctx->sig_list; - -#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - result &= (sig->id == 6); - sig = sig->next; - result &= (sig->id == 7); - sig = sig->next; - result &= (sig->id == 8); - sig = sig->next; - result &= (sig->id == 1); - sig = sig->next; - result &= (sig->id == 3); - sig = sig->next; - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 4); - sig = sig->next; - result &= (sig->id == 5); - sig = sig->next; - -end: - /* Restore the default pre-order definition */ - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_REJECT; - action_order_sigs[2] = ACTION_PASS; - action_order_sigs[3] = ACTION_ALERT; - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Order with a different Action priority - * (as specified from config) - */ -static int SCSigOrderingTest10(void) -{ - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - extern uint8_t action_order_sigs[4]; - - /* Let's change the order. Default is pass, drop, reject, alert (pass has highest prio) */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_ALERT; - action_order_sigs[2] = ACTION_DROP; - action_order_sigs[3] = ACTION_REJECT; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; rev:4; sid:1;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:10; rev:4; priority:2; sid:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:10; depth:4; rev:4; priority:3; sid:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:10; depth:4; rev:4; priority:2; sid:4;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "pass tcp any !21:902 -> any any (msg:\"Testing sigordering pass\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:5;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering drop\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:1; sid:6;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "drop tcp any !21:902 -> any any (msg:\"Testing sigordering reject\"; content:\"220\"; offset:11; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:7;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering alert\"; content:\"220\"; offset:12; depth:4; pcre:\"/220[- ]/\"; rev:4; priority:2; sid:8;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - - sig = de_ctx->sig_list; - -#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 4); - sig = sig->next; - result &= (sig->id == 5); - sig = sig->next; - result &= (sig->id == 8); - sig = sig->next; - result &= (sig->id == 1); - sig = sig->next; - result &= (sig->id == 3); - sig = sig->next; - result &= (sig->id == 6); - sig = sig->next; - result &= (sig->id == 7); - sig = sig->next; - -end: - /* Restore the default pre-order definition */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SCSigOrderingTest11(void) -{ - int result = 0; - Signature *prevsig = NULL, *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering set\"; flowbits:isnotset,myflow1; rev:4; sid:1;)"); - if (sig == NULL) { - goto end; - } - prevsig = sig; - de_ctx->sig_list = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering toggle\"; flowbits:toggle,myflow2; rev:4; sid:2;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - prevsig = sig; - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"Testing sigordering unset\"; flowbits:isset, myflow1; flowbits:unset,myflow2; rev:4; priority:3; sid:3;)"); - if (sig == NULL) { - goto end; - } - prevsig->next = sig; - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByActionCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPktvarCompare); - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByPriorityCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - - sig = de_ctx->sig_list; - -#ifdef DEBUG - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - result &= (sig->id == 2); - sig = sig->next; - result &= (sig->id == 3); - sig = sig->next; - result &= (sig->id == 1); - sig = sig->next; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SCSigOrderingTest12(void) -{ - Signature *sig = NULL; - Packet *p = NULL; - uint8_t buf[] = "test message"; - int result = 0; - Flow f; - - FLOW_INITIALIZE(&f); - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_UNKNOWN; - f.proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - char *sigs[2]; - sigs[0] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:isset,one; flowbits:set,two; sid:1;)"; - sigs[1] = "alert tcp any any -> any any (content:\"test\"; dsize:>0; flowbits:set,one; sid:2;)"; - UTHAppendSigs(de_ctx, sigs, 2); - - sig = de_ctx->sig_list; - if (sig == NULL) - goto end; - if (sig->next == NULL) - goto end; - if (sig->next->next != NULL) - goto end; - if (de_ctx->signum != 2) - goto end; - - FlowInitConfig(FLOW_QUIET); - p = UTHBuildPacket(buf, sizeof(buf), IPPROTO_TCP); - if (p == NULL) { - printf("Error building packet."); - goto end; - } - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - UTHMatchPackets(de_ctx, &p, 1); - - uint32_t sids[2] = {1, 2}; - uint32_t results[2] = {1, 1}; - result = UTHCheckPacketMatchResults(p, sids, results, 2); - -end: - if (p != NULL) - SCFree(p); - if (de_ctx != NULL) { - SigCleanSignatures(de_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - FlowShutdown(); - - return result; -} - -/** \test Bug 1061 */ -static int SCSigOrderingTest13(void) -{ - int result = 0; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:set,bit2; flowbits:set,bit3; sid:6;)"); - if (sig == NULL) { - goto end; - } - sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:set,bit1; flowbits:set,bit2; sid:7;)"); - if (sig == NULL) { - goto end; - } - sig = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flowbits:isset,bit1; flowbits:isset,bit2; flowbits:isset,bit3; sid:5;)"); - if (sig == NULL) { - goto end; - } - - SCSigRegisterSignatureOrderingFunc(de_ctx, SCSigOrderByFlowbitsCompare); - SCSigOrderSignatures(de_ctx); - - result = 1; - -#ifdef DEBUG - sig = de_ctx->sig_list; - while (sig != NULL) { - printf("sid: %d\n", sig->id); - sig = sig->next; - } -#endif - - sig = de_ctx->sig_list; - - result &= (sig->id == 7); - sig = sig->next; - result &= (sig->id == 6); - sig = sig->next; - result &= (sig->id == 5); - sig = sig->next; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif - -void SCSigRegisterSignatureOrderingTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("SCSigOrderingTest01", SCSigOrderingTest01, 1); - UtRegisterTest("SCSigOrderingTest02", SCSigOrderingTest02, 1); - UtRegisterTest("SCSigOrderingTest03", SCSigOrderingTest03, 1); - UtRegisterTest("SCSigOrderingTest04", SCSigOrderingTest04, 1); - UtRegisterTest("SCSigOrderingTest05", SCSigOrderingTest05, 1); - UtRegisterTest("SCSigOrderingTest06", SCSigOrderingTest06, 1); - UtRegisterTest("SCSigOrderingTest07", SCSigOrderingTest07, 1); - UtRegisterTest("SCSigOrderingTest08", SCSigOrderingTest08, 1); - UtRegisterTest("SCSigOrderingTest09", SCSigOrderingTest09, 1); - UtRegisterTest("SCSigOrderingTest10", SCSigOrderingTest10, 1); - UtRegisterTest("SCSigOrderingTest11", SCSigOrderingTest11, 1); - UtRegisterTest("SCSigOrderingTest12", SCSigOrderingTest12, 1); - UtRegisterTest("SCSigOrderingTest13", SCSigOrderingTest13, 1); -#endif -} diff --git a/framework/src/suricata/src/detect-engine-sigorder.h b/framework/src/suricata/src/detect-engine-sigorder.h deleted file mode 100644 index 686ce928..00000000 --- a/framework/src/suricata/src/detect-engine-sigorder.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_SIGORDER_H__ -#define __DETECT_ENGINE_SIGORDER_H__ - -/** - * \brief Different kinds of helper data that can be used by the signature - * ordering module. Used by the "user" field in SCSigSignatureWrapper - */ -typedef enum{ - SC_RADIX_USER_DATA_FLOWBITS, - SC_RADIX_USER_DATA_FLOWVAR, - SC_RADIX_USER_DATA_PKTVAR, - SC_RADIX_USER_DATA_FLOWINT, - SC_RADIX_USER_DATA_HOSTBITS, - SC_RADIX_USER_DATA_IPPAIRBITS, - SC_RADIX_USER_DATA_MAX -} SCRadixUserDataType; - -/** - * \brief Signature wrapper used by signature ordering module while ordering - * signatures - */ -typedef struct SCSigSignatureWrapper_ { - /* the wrapped signature */ - Signature *sig; - - /* used as the lower limit SCSigSignatureWrapper that is used by the next - * ordering function, which will order the incoming Sigwrapper after this - * (min) wrapper */ - struct SCSigSignatureWrapper_ *min; - /* used as the upper limit SCSigSignatureWrapper that is used by the next - * ordering function, which will order the incoming Sigwrapper below this - * (max) wrapper */ - struct SCSigSignatureWrapper_ *max; - - /* user data that is to be associated with this sigwrapper */ - int user[SC_RADIX_USER_DATA_MAX]; - - struct SCSigSignatureWrapper_ *next; - struct SCSigSignatureWrapper_ *prev; -} SCSigSignatureWrapper; - -/** - * \brief Structure holding the signature ordering function used by the - * signature ordering module - */ -typedef struct SCSigOrderFunc_ { - /* Pointer to the Signature Ordering function */ - int (*SWCompare)(SCSigSignatureWrapper *sw1, SCSigSignatureWrapper *sw2); - - struct SCSigOrderFunc_ *next; -} SCSigOrderFunc; - -void SCSigOrderSignatures(DetectEngineCtx *); -void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *); -void SCSigRegisterSignatureOrderingTests(void); -void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *); - -#endif /* __DETECT_ENGINE_SIGORDER_H__ */ diff --git a/framework/src/suricata/src/detect-engine-state.c b/framework/src/suricata/src/detect-engine-state.c deleted file mode 100644 index 05ca25d5..00000000 --- a/framework/src/suricata/src/detect-engine-state.c +++ /dev/null @@ -1,2346 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \defgroup sigstate State support - * - * It is possible to do matching on reconstructed applicative flow. - * This is done by this code. It uses the ::Flow structure to store - * the list of signatures to match on the reconstructed stream. - * - * The Flow::de_state is a ::DetectEngineState structure. This is - * basically a containter for storage item of type ::DeStateStore. - * They contains an array of ::DeStateStoreItem which store the - * state of match for an individual signature identified by - * DeStateStoreItem::sid. - * - * The state is constructed by DeStateDetectStartDetection() which - * also starts the matching. Work is continued by - * DeStateDetectContinueDetection(). - * - * Once a transaction has been analysed DeStateRestartDetection() - * is used to reset the structures. - * - * @{ - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * \brief State based signature handling. - */ - -#include "suricata-common.h" - -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-dcepayload.h" - -#include "detect-flowvar.h" - -#include "stream-tcp.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-protos.h" -#include "app-layer-htp.h" -#include "app-layer-smb.h" -#include "app-layer-dcerpc-common.h" -#include "app-layer-dcerpc.h" -#include "app-layer-dns-common.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-profiling.h" - -#include "flow-util.h" - -/** convert enum to string */ -#define CASE_CODE(E) case E: return #E - -/** The DetectEngineThreadCtx::de_state_sig_array contains 2 separate values: - * 1. the first bit tells the prefilter engine to bypass the rule (or not) - * 2. the other bits allow 'ContinueDetect' to specify an offset again the - * base tx id. This offset will then be used by 'StartDetect' to not - * inspect transactions again for the same signature. - * - * The offset in (2) has a max value due to the limited data type. If it is - * set to max the code will fall back to a slower path that validates that - * we're not adding duplicate rules to the detection state. - */ -#define MAX_STORED_TXID_OFFSET 127 - -/******** static internal helpers *********/ - -static inline int StateIsValid(uint16_t alproto, void *alstate) -{ - if (alstate != NULL) { - if (alproto == ALPROTO_HTTP) { - HtpState *htp_state = (HtpState *)alstate; - if (htp_state->conn != NULL) { - return 1; - } - } else { - return 1; - } - } - return 0; -} - -static inline int TxIsLast(uint64_t tx_id, uint64_t total_txs) -{ - if (total_txs - tx_id <= 1) - return 1; - return 0; -} - -static DeStateStore *DeStateStoreAlloc(void) -{ - DeStateStore *d = SCMalloc(sizeof(DeStateStore)); - if (unlikely(d == NULL)) - return NULL; - memset(d, 0, sizeof(DeStateStore)); - - return d; -} -static DeStateStoreFlowRules *DeStateStoreFlowRulesAlloc(void) -{ - DeStateStoreFlowRules *d = SCMalloc(sizeof(DeStateStoreFlowRules)); - if (unlikely(d == NULL)) - return NULL; - memset(d, 0, sizeof(DeStateStoreFlowRules)); - - return d; -} - -static int DeStateSearchState(DetectEngineState *state, uint8_t direction, SigIntId num) -{ - DetectEngineStateDirection *dir_state = &state->dir_state[direction & STREAM_TOSERVER ? 0 : 1]; - DeStateStore *tx_store = dir_state->head; - SigIntId store_cnt; - SigIntId state_cnt = 0; - - for (; tx_store != NULL; tx_store = tx_store->next) { - SCLogDebug("tx_store %p", tx_store); - for (store_cnt = 0; - store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < dir_state->cnt; - store_cnt++, state_cnt++) - { - DeStateStoreItem *item = &tx_store->store[store_cnt]; - if (item->sid == num) { - SCLogDebug("sid %u already in state: %p %p %p %u %u, direction %s", - num, state, dir_state, tx_store, state_cnt, - store_cnt, direction & STREAM_TOSERVER ? "toserver" : "toclient"); - return 1; - } - } - } - return 0; -} - -static void DeStateSignatureAppend(DetectEngineState *state, Signature *s, uint32_t inspect_flags, uint8_t direction) -{ - int jump = 0; - int i = 0; - DetectEngineStateDirection *dir_state = &state->dir_state[direction & STREAM_TOSERVER ? 0 : 1]; - -#ifdef DEBUG_VALIDATION - BUG_ON(DeStateSearchState(state, direction, s->num)); -#endif - DeStateStore *store = dir_state->head; - - if (store == NULL) { - store = DeStateStoreAlloc(); - if (store != NULL) { - dir_state->head = store; - dir_state->tail = store; - } - } else { - jump = dir_state->cnt / DE_STATE_CHUNK_SIZE; - for (i = 0; i < jump; i++) { - store = store->next; - } - if (store == NULL) { - store = DeStateStoreAlloc(); - if (store != NULL) { - dir_state->tail->next = store; - dir_state->tail = store; - } - } - } - - if (store == NULL) - return; - - SigIntId idx = dir_state->cnt++ % DE_STATE_CHUNK_SIZE; - store->store[idx].sid = s->num; - store->store[idx].flags = inspect_flags; - - return; -} - -static void DeStateFlowRuleAppend(DetectEngineStateFlow *state, Signature *s, - SigMatch *sm, uint32_t inspect_flags, - uint8_t direction) -{ - int jump = 0; - int i = 0; - DetectEngineStateDirectionFlow *dir_state = &state->dir_state[direction & STREAM_TOSERVER ? 0 : 1]; - DeStateStoreFlowRules *store = dir_state->head; - - if (store == NULL) { - store = DeStateStoreFlowRulesAlloc(); - if (store != NULL) { - dir_state->head = store; - dir_state->tail = store; - } - } else { - jump = dir_state->cnt / DE_STATE_CHUNK_SIZE; - for (i = 0; i < jump; i++) { - store = store->next; - } - if (store == NULL) { - store = DeStateStoreFlowRulesAlloc(); - if (store != NULL) { - dir_state->tail->next = store; - dir_state->tail = store; - } - } - } - - if (store == NULL) - return; - - SigIntId idx = dir_state->cnt++ % DE_STATE_CHUNK_SIZE; - store->store[idx].sid = s->num; - store->store[idx].flags = inspect_flags; - store->store[idx].nm = sm; - - return; -} - -static void DeStateStoreStateVersion(Flow *f, - const uint8_t alversion, uint8_t direction) -{ - f->detect_alversion[direction & STREAM_TOSERVER ? 0 : 1] = alversion; -} - -static void DeStateStoreFileNoMatchCnt(DetectEngineState *de_state, uint16_t file_no_match, uint8_t direction) -{ - de_state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].filestore_cnt += file_no_match; - - return; -} - -static int DeStateStoreFilestoreSigsCantMatch(SigGroupHead *sgh, DetectEngineState *de_state, uint8_t direction) -{ - if (de_state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].filestore_cnt == sgh->filestore_cnt) - return 1; - else - return 0; -} - -DetectEngineState *DetectEngineStateAlloc(void) -{ - DetectEngineState *d = SCMalloc(sizeof(DetectEngineState)); - if (unlikely(d == NULL)) - return NULL; - memset(d, 0, sizeof(DetectEngineState)); - - return d; -} - -DetectEngineStateFlow *DetectEngineStateFlowAlloc(void) -{ - DetectEngineStateFlow *d = SCMalloc(sizeof(DetectEngineStateFlow)); - if (unlikely(d == NULL)) - return NULL; - memset(d, 0, sizeof(DetectEngineStateFlow)); - - return d; -} - -void DetectEngineStateFree(DetectEngineState *state) -{ - DeStateStore *store; - DeStateStore *store_next; - int i = 0; - - for (i = 0; i < 2; i++) { - store = state->dir_state[i].head; - while (store != NULL) { - store_next = store->next; - SCFree(store); - store = store_next; - } - } - SCFree(state); - - return; -} - -void DetectEngineStateFlowFree(DetectEngineStateFlow *state) -{ - DeStateStoreFlowRules *store; - DeStateStoreFlowRules *store_next; - int i = 0; - - for (i = 0; i < 2; i++) { - store = state->dir_state[i].head; - while (store != NULL) { - store_next = store->next; - SCFree(store); - store = store_next; - } - } - SCFree(state); - - return; -} - -static int HasStoredSigs(Flow *f, uint8_t flags) -{ - if (f->de_state != NULL && f->de_state->dir_state[flags & STREAM_TOSERVER ? 0 : 1].cnt != 0) { - SCLogDebug("global sigs present"); - return 1; - } - - if (AppLayerParserProtocolSupportsTxs(f->proto, f->alproto)) { - AppProto alproto = f->alproto; - void *alstate = FlowGetAppState(f); - if (!StateIsValid(f->alproto, alstate)) { - return 0; - } - - int state = AppLayerParserHasTxDetectState(f->proto, alproto, f->alstate); - if (state == -ENOSYS) { /* proto doesn't support this API call */ - /* fall through */ - } else if (state == 0) { - return 0; - } - /* if state == 1 we also fall through */ - - uint64_t inspect_tx_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - uint64_t total_txs = AppLayerParserGetTxCnt(f->proto, alproto, alstate); - - for ( ; inspect_tx_id < total_txs; inspect_tx_id++) { - void *inspect_tx = AppLayerParserGetTx(f->proto, alproto, alstate, inspect_tx_id); - if (inspect_tx != NULL) { - DetectEngineState *tx_de_state = AppLayerParserGetTxDetectState(f->proto, alproto, inspect_tx); - if (tx_de_state == NULL) { - continue; - } - if (tx_de_state->dir_state[flags & STREAM_TOSERVER ? 0 : 1].cnt != 0) { - SCLogDebug("tx %u has sigs present", (uint)inspect_tx_id); - return 1; - } - } - } - } - return 0; -} - -/** \brief Check if we need to inspect this state - * - * State needs to be inspected if: - * 1. state has been updated - * 2. we already have de_state in progress - * - * \retval 0 no inspectable state - * \retval 1 inspectable state - * \retval 2 inspectable state, but no update - */ -int DeStateFlowHasInspectableState(Flow *f, AppProto alproto, - const uint8_t alversion, uint8_t flags) -{ - int r = 0; - - FLOWLOCK_WRLOCK(f); - - if (!(flags & STREAM_EOF) && f->de_state && - f->detect_alversion[flags & STREAM_TOSERVER ? 0 : 1] == alversion) { - SCLogDebug("unchanged state"); - r = 2; - } else if (HasStoredSigs(f, flags)) { - r = 1; - } else { - r = 0; - } - FLOWLOCK_UNLOCK(f); - - return r; -} - -static int StoreState(DetectEngineThreadCtx *det_ctx, - Flow *f, const uint8_t flags, const uint8_t alversion, - Signature *s, SigMatch *sm, const uint32_t inspect_flags, - const uint16_t file_no_match) -{ - if (f->de_state == NULL) { - f->de_state = DetectEngineStateFlowAlloc(); - if (f->de_state == NULL) { - return 0; - } - } - - DeStateFlowRuleAppend(f->de_state, s, sm, inspect_flags, flags); - DeStateStoreStateVersion(f, alversion, flags); - return 1; -} - -static void StoreStateTxHandleFiles(DetectEngineThreadCtx *det_ctx, Flow *f, - DetectEngineState *destate, const uint8_t flags, - const uint64_t tx_id, const uint16_t file_no_match) -{ - DeStateStoreFileNoMatchCnt(destate, file_no_match, flags); - if (DeStateStoreFilestoreSigsCantMatch(det_ctx->sgh, destate, flags) == 1) { - FileDisableStoringForTransaction(f, flags & (STREAM_TOCLIENT | STREAM_TOSERVER), tx_id); - destate->dir_state[flags & STREAM_TOSERVER ? 0 : 1].flags |= DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED; - } -} - -static void StoreStateTxFileOnly(DetectEngineThreadCtx *det_ctx, - Flow *f, const uint8_t flags, const uint64_t tx_id, void *tx, - const uint16_t file_no_match) -{ - if (AppLayerParserSupportsTxDetectState(f->proto, f->alproto)) { - DetectEngineState *destate = AppLayerParserGetTxDetectState(f->proto, f->alproto, tx); - if (destate == NULL) { - destate = DetectEngineStateAlloc(); - if (destate == NULL) - return; - if (AppLayerParserSetTxDetectState(f->proto, f->alproto, f->alstate, tx, destate) < 0) { - DetectEngineStateFree(destate); - return; - } - SCLogDebug("destate created for %"PRIu64, tx_id); - } - StoreStateTxHandleFiles(det_ctx, f, destate, flags, tx_id, file_no_match); - } -} - -/** - * \param check_before_add check for duplicates before adding the sig - */ -static void StoreStateTx(DetectEngineThreadCtx *det_ctx, - Flow *f, const uint8_t flags, const uint8_t alversion, - const uint64_t tx_id, void *tx, - Signature *s, SigMatch *sm, - const uint32_t inspect_flags, const uint16_t file_no_match, int check_before_add) -{ - if (AppLayerParserSupportsTxDetectState(f->proto, f->alproto)) { - DetectEngineState *destate = AppLayerParserGetTxDetectState(f->proto, f->alproto, tx); - if (destate == NULL) { - destate = DetectEngineStateAlloc(); - if (destate == NULL) - return; - if (AppLayerParserSetTxDetectState(f->proto, f->alproto, f->alstate, tx, destate) < 0) { - DetectEngineStateFree(destate); - return; - } - SCLogDebug("destate created for %"PRIu64, tx_id); - } - - if (check_before_add == 0 || DeStateSearchState(destate, flags, s->num) == 0) - DeStateSignatureAppend(destate, s, inspect_flags, flags); - DeStateStoreStateVersion(f, alversion, flags); - - StoreStateTxHandleFiles(det_ctx, f, destate, flags, tx_id, file_no_match); - } - SCLogDebug("Stored for TX %"PRIu64, tx_id); -} - -int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Packet *p, Flow *f, uint8_t flags, - AppProto alproto, const uint8_t alversion) -{ - SigMatch *sm = NULL; - uint16_t file_no_match = 0; - uint32_t inspect_flags = 0; - uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1; - int alert_cnt = 0; - int check_before_add = 0; - - FLOWLOCK_WRLOCK(f); - /* TX based matches (inspect engines) */ - if (AppLayerParserProtocolSupportsTxs(f->proto, alproto)) { - uint64_t tx_id = 0; - uint64_t total_txs = 0; - - void *alstate = FlowGetAppState(f); - if (!StateIsValid(alproto, alstate)) { - goto end; - } - - /* if continue detection already inspected this rule for this tx, - * continue with the first not-inspected tx */ - uint8_t offset = det_ctx->de_state_sig_array[s->num] & 0xef; - tx_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - if (offset > 0) { - SCLogDebug("using stored_tx_id %u instead of %u", (uint)tx_id+offset, (uint)tx_id); - tx_id += offset; - } - if (offset == MAX_STORED_TXID_OFFSET) { - check_before_add = 1; - } - - total_txs = AppLayerParserGetTxCnt(f->proto, alproto, alstate); - SCLogDebug("total_txs %"PRIu64, total_txs); - - SCLogDebug("starting: start tx %u, packet %u", (uint)tx_id, (uint)p->pcap_cnt); - - for (; tx_id < total_txs; tx_id++) { - int total_matches = 0; - void *tx = AppLayerParserGetTx(f->proto, alproto, alstate, tx_id); - if (tx == NULL) - continue; - det_ctx->tx_id = tx_id; - det_ctx->tx_id_set = 1; - DetectEngineAppInspectionEngine *engine = app_inspection_engine[f->protomap][alproto][direction]; - inspect_flags = 0; - while (engine != NULL) { - if (s->sm_lists[engine->sm_list] != NULL) { - KEYWORD_PROFILING_SET_LIST(det_ctx, engine->sm_list); - int match = engine->Callback(tv, de_ctx, det_ctx, s, f, - flags, alstate, - tx, tx_id); - if (match == DETECT_ENGINE_INSPECT_SIG_MATCH) { - inspect_flags |= engine->inspect_flags; - engine = engine->next; - total_matches++; - continue; - } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH) { - inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; - inspect_flags |= engine->inspect_flags; - } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE) { - inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; - inspect_flags |= engine->inspect_flags; - file_no_match++; - } - break; - } - engine = engine->next; - } - /* all the engines seem to be exhausted at this point. If we - * didn't have a match in one of the engines we would have - * broken off and engine wouldn't be NULL. Hence the alert. */ - if (engine == NULL && total_matches > 0) { - if (!(s->flags & SIG_FLAG_NOALERT)) { - PacketAlertAppend(det_ctx, s, p, tx_id, - PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX); - } else { - DetectSignatureApplyActions(p, s); - } - alert_cnt = 1; - SCLogDebug("MATCH: tx %u packet %u", (uint)tx_id, (uint)p->pcap_cnt); - } - - /* if this is the last tx in our list, and it's incomplete: then - * we store the state so that ContinueDetection knows about it */ - int tx_is_done = (AppLayerParserGetStateProgress(f->proto, alproto, tx, flags) >= - AppLayerParserGetStateProgressCompletionStatus(f->proto, alproto, flags)); - /* see if we need to consider the next tx in our decision to add - * a sig to the 'no inspect array'. */ - int next_tx_no_progress = 0; - if (!TxIsLast(tx_id, total_txs)) { - void *next_tx = AppLayerParserGetTx(f->proto, alproto, alstate, tx_id+1); - if (next_tx != NULL) { - int c = AppLayerParserGetStateProgress(f->proto, alproto, next_tx, flags); - if (c == 0) { - next_tx_no_progress = 1; - } - } - } - - SCLogDebug("tx %u, packet %u, rule %u, alert_cnt %u, last tx %d, tx_is_done %d, next_tx_no_progress %d", - (uint)tx_id, (uint)p->pcap_cnt, s->num, alert_cnt, - TxIsLast(tx_id, total_txs), tx_is_done, next_tx_no_progress); - - /* if we have something to store (partial match or file store info), - * then we do it now. */ - if (inspect_flags != 0) { - if (!(TxIsLast(tx_id, total_txs)) || !tx_is_done) { - if (engine == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) { - inspect_flags |= DE_STATE_FLAG_FULL_INSPECT; - } - - /* store */ - StoreStateTx(det_ctx, f, flags, alversion, tx_id, tx, - s, sm, inspect_flags, file_no_match, check_before_add); - } else { - StoreStateTxFileOnly(det_ctx, f, flags, tx_id, tx, file_no_match); - } - } else { - SCLogDebug("no state to store"); - } - if (next_tx_no_progress) - break; - } /* for */ - - /* DCERPC matches */ - } else if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL && - (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || - alproto == ALPROTO_SMB2)) - { - void *alstate = FlowGetAppState(f); - if (alstate == NULL) { - goto end; - } - - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_DMATCH); - if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { - SMBState *smb_state = (SMBState *)alstate; - if (smb_state->dcerpc_present && - DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, - flags, &smb_state->dcerpc) == 1) { - if (!(s->flags & SIG_FLAG_NOALERT)) { - PacketAlertAppend(det_ctx, s, p, 0, - PACKET_ALERT_FLAG_STATE_MATCH); - } else { - DetectSignatureApplyActions(p, s); - } - alert_cnt = 1; - } - } else { - if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f, - flags, alstate) == 1) { - if (!(s->flags & SIG_FLAG_NOALERT)) { - PacketAlertAppend(det_ctx, s, p, 0, - PACKET_ALERT_FLAG_STATE_MATCH); - } else { - DetectSignatureApplyActions(p, s); - } - alert_cnt = 1; - } - } - } - - /* flow based matches */ - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_AMATCH); - sm = s->sm_lists[DETECT_SM_LIST_AMATCH]; - if (sm != NULL) { - void *alstate = FlowGetAppState(f); - if (alstate == NULL) { - goto end; - } - - int match = 0; - for ( ; sm != NULL; sm = sm->next) { - if (sigmatch_table[sm->type].AppLayerMatch != NULL) { - match = 0; - if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { - SMBState *smb_state = (SMBState *)alstate; - if (smb_state->dcerpc_present) { - KEYWORD_PROFILING_START; - match = sigmatch_table[sm->type]. - AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm); - KEYWORD_PROFILING_END(det_ctx, sm->type, (match == 1)); - } - } else { - KEYWORD_PROFILING_START; - match = sigmatch_table[sm->type]. - AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm); - KEYWORD_PROFILING_END(det_ctx, sm->type, (match == 1)); - } - - if (match == 0) - break; - if (match == 2) { - inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; - break; - } - } - } - - if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) { - if (match == 1) { - if (!(s->flags & SIG_FLAG_NOALERT)) { - PacketAlertAppend(det_ctx, s, p, 0, - PACKET_ALERT_FLAG_STATE_MATCH); - } else { - DetectSignatureApplyActions(p, s); - } - alert_cnt = 1; - } - inspect_flags |= DE_STATE_FLAG_FULL_INSPECT; - } - - StoreState(det_ctx, f, flags, alversion, - s, sm, inspect_flags, file_no_match); - } - - end: - FLOWLOCK_UNLOCK(f); - - det_ctx->tx_id = 0; - det_ctx->tx_id_set = 0; - return alert_cnt ? 1:0; -} - -static int DoInspectItem(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - DeStateStoreItem *item, const uint8_t dir_state_flags, - Packet *p, Flow *f, AppProto alproto, uint8_t flags, - const uint64_t inspect_tx_id, const uint64_t total_txs, - - uint16_t *file_no_match, int inprogress, // is current tx in progress? - const int next_tx_no_progress) // tx after current is still dormant -{ - Signature *s = de_ctx->sig_array[item->sid]; - - /* check if a sig in state 'full inspect' needs to be reconsidered - * as the result of a new file in the existing tx */ - if (item->flags & DE_STATE_FLAG_FULL_INSPECT) { - if (item->flags & (DE_STATE_FLAG_FILE_TC_INSPECT|DE_STATE_FLAG_FILE_TS_INSPECT)) { - if ((flags & STREAM_TOCLIENT) && - (dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW)) - { - item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT; - item->flags &= ~DE_STATE_FLAG_FULL_INSPECT; - } - - if ((flags & STREAM_TOSERVER) && - (dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW)) - { - item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT; - item->flags &= ~DE_STATE_FLAG_FULL_INSPECT; - } - } - - if (item->flags & DE_STATE_FLAG_FULL_INSPECT) { - if (TxIsLast(inspect_tx_id, total_txs) || inprogress || next_tx_no_progress) { - det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE; - SCLogDebug("skip and bypass: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt); - } else { - SCLogDebug("just skip: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt); - - /* make sure that if we reinspect this right now from - * start detection, we skip this tx we just matched on */ - uint64_t base_tx_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - uint64_t offset = (inspect_tx_id + 1) - base_tx_id; - if (offset > MAX_STORED_TXID_OFFSET) - offset = MAX_STORED_TXID_OFFSET; - det_ctx->de_state_sig_array[item->sid] = (uint8_t)offset; -#ifdef DEBUG_VALIDATION - BUG_ON(det_ctx->de_state_sig_array[item->sid] & DE_STATE_MATCH_NO_NEW_STATE); // check that we don't set the bit -#endif - SCLogDebug("storing tx_id %u for this sid", (uint)inspect_tx_id + 1); - } - return 0; - } - } - - /* check if a sig in state 'cant match' needs to be reconsidered - * as the result of a new file in the existing tx */ - if (item->flags & DE_STATE_FLAG_SIG_CANT_MATCH) { - if ((flags & STREAM_TOSERVER) && - (item->flags & DE_STATE_FLAG_FILE_TS_INSPECT) && - (dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW)) - { - item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT; - item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH; - } else if ((flags & STREAM_TOCLIENT) && - (item->flags & DE_STATE_FLAG_FILE_TC_INSPECT) && - (dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW)) - { - item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT; - item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH; - } else { - if (TxIsLast(inspect_tx_id, total_txs) || inprogress || next_tx_no_progress) { - det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE; - SCLogDebug("skip and bypass: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt); - } else { - SCLogDebug("just skip: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt); - - /* make sure that if we reinspect this right now from - * start detection, we skip this tx we just matched on */ - uint64_t base_tx_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - uint64_t offset = (inspect_tx_id + 1) - base_tx_id; - if (offset > MAX_STORED_TXID_OFFSET) - offset = MAX_STORED_TXID_OFFSET; - det_ctx->de_state_sig_array[item->sid] = (uint8_t)offset; -#ifdef DEBUG_VALIDATION - BUG_ON(det_ctx->de_state_sig_array[item->sid] & DE_STATE_MATCH_NO_NEW_STATE); // check that we don't set the bit -#endif - SCLogDebug("storing tx_id %u for this sid", (uint)inspect_tx_id + 1); - } - return 0; - } - } - - uint8_t alert = 0; - uint32_t inspect_flags = 0; - int total_matches = 0; - - RULE_PROFILING_START(p); - - void *alstate = FlowGetAppState(f); - if (!StateIsValid(alproto, alstate)) { - RULE_PROFILING_END(det_ctx, s, 0, p); - return -1; - } - - det_ctx->tx_id = inspect_tx_id; - det_ctx->tx_id_set = 1; - SCLogDebug("inspecting: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt); - - DetectEngineAppInspectionEngine *engine = app_inspection_engine[f->protomap][alproto][(flags & STREAM_TOSERVER) ? 0 : 1]; - void *inspect_tx = AppLayerParserGetTx(f->proto, alproto, alstate, inspect_tx_id); - if (inspect_tx == NULL) { - RULE_PROFILING_END(det_ctx, s, 0, p); - return -1; - } - - while (engine != NULL) { - if (!(item->flags & engine->inspect_flags) && - s->sm_lists[engine->sm_list] != NULL) - { - KEYWORD_PROFILING_SET_LIST(det_ctx, engine->sm_list); - int match = engine->Callback(tv, de_ctx, det_ctx, s, f, - flags, alstate, inspect_tx, inspect_tx_id); - if (match == DETECT_ENGINE_INSPECT_SIG_MATCH) { - inspect_flags |= engine->inspect_flags; - engine = engine->next; - total_matches++; - continue; - } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH) { - inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; - inspect_flags |= engine->inspect_flags; - } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE) { - inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; - inspect_flags |= engine->inspect_flags; - (*file_no_match)++; - } - break; - } - engine = engine->next; - } - if (total_matches > 0 && (engine == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH)) { - if (engine == NULL) - alert = 1; - inspect_flags |= DE_STATE_FLAG_FULL_INSPECT; - } - - item->flags |= inspect_flags; - /* flag this sig to don't inspect again from the detection loop it if - * there is no need for it */ - if (TxIsLast(inspect_tx_id, total_txs) || inprogress || next_tx_no_progress) { - det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE; - SCLogDebug("inspected, now bypass: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt); - } else { - /* make sure that if we reinspect this right now from - * start detection, we skip this tx we just matched on */ - uint64_t base_tx_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - uint64_t offset = (inspect_tx_id + 1) - base_tx_id; - if (offset > MAX_STORED_TXID_OFFSET) - offset = MAX_STORED_TXID_OFFSET; - det_ctx->de_state_sig_array[item->sid] = (uint8_t)offset; -#ifdef DEBUG_VALIDATION - BUG_ON(det_ctx->de_state_sig_array[item->sid] & DE_STATE_MATCH_NO_NEW_STATE); // check that we don't set the bit -#endif - SCLogDebug("storing tx_id %u for this sid", (uint)inspect_tx_id + 1); - } - RULE_PROFILING_END(det_ctx, s, (alert == 1), p); - - if (alert) { - det_ctx->flow_locked = 1; - SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s); - det_ctx->flow_locked = 0; - - if (!(s->flags & SIG_FLAG_NOALERT)) { - PacketAlertAppend(det_ctx, s, p, inspect_tx_id, - PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX); - } else { - PACKET_UPDATE_ACTION(p, s->action); - } - SCLogDebug("MATCH: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt); - } - - DetectFlowvarProcessList(det_ctx, f); - return 1; -} - -/** \internal - * \brief Continue Detection for a single "flow" rule (AMATCH) - */ -static int DoInspectFlowRule(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - DeStateStoreFlowRule *item, const uint8_t dir_state_flags, - Packet *p, Flow *f, AppProto alproto, uint8_t flags) -{ - /* flag rules that are either full inspected or unable to match - * in the de_state_sig_array so that prefilter filters them out */ - if (item->flags & (DE_STATE_FLAG_FULL_INSPECT|DE_STATE_FLAG_SIG_CANT_MATCH)) { - det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE; - return 0; - } - - uint8_t alert = 0; - uint32_t inspect_flags = 0; - int total_matches = 0; - SigMatch *sm = NULL; - Signature *s = de_ctx->sig_array[item->sid]; - - RULE_PROFILING_START(p); - - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_AMATCH); - if (item->nm != NULL) { - void *alstate = FlowGetAppState(f); - if (alstate == NULL) { - RULE_PROFILING_END(det_ctx, s, 0 /* no match */, p); - return -1; - } - - for (sm = item->nm; sm != NULL; sm = sm->next) { - if (sigmatch_table[sm->type].AppLayerMatch != NULL) - { - int match = 0; - if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { - SMBState *smb_state = (SMBState *)alstate; - if (smb_state->dcerpc_present) { - KEYWORD_PROFILING_START; - match = sigmatch_table[sm->type]. - AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm); - KEYWORD_PROFILING_END(det_ctx, sm->type, (match == 1)); - } - } else { - KEYWORD_PROFILING_START; - match = sigmatch_table[sm->type]. - AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm); - KEYWORD_PROFILING_END(det_ctx, sm->type, (match == 1)); - } - - if (match == 0) - break; - else if (match == 2) - inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; - else if (match == 1) - total_matches++; - } - } - } - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { - if (total_matches > 0 && (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH)) { - if (sm == NULL) - alert = 1; - inspect_flags |= DE_STATE_FLAG_FULL_INSPECT; - } - /* prevent the rule loop from reinspecting this rule */ - det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE; - } - RULE_PROFILING_END(det_ctx, s, (alert == 1), p); - - /* store the progress in the state */ - item->flags |= inspect_flags; - item->nm = sm; - - if (alert) { - det_ctx->flow_locked = 1; - SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s); - det_ctx->flow_locked = 0; - - if (!(s->flags & SIG_FLAG_NOALERT)) { - PacketAlertAppend(det_ctx, s, p, 0, - PACKET_ALERT_FLAG_STATE_MATCH); - } else { - DetectSignatureApplyActions(p, s); - } - } - - DetectFlowvarProcessList(det_ctx, f); - return 1; -} - -void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Packet *p, Flow *f, uint8_t flags, - AppProto alproto, const uint8_t alversion) -{ - uint16_t file_no_match = 0; - SigIntId store_cnt = 0; - SigIntId state_cnt = 0; - uint64_t inspect_tx_id = 0; - uint64_t total_txs = 0; - uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1; - - FLOWLOCK_WRLOCK(f); - - SCLogDebug("starting continue detection for packet %"PRIu64, p->pcap_cnt); - - if (AppLayerParserProtocolSupportsTxs(f->proto, alproto)) { - void *alstate = FlowGetAppState(f); - if (!StateIsValid(alproto, alstate)) { - FLOWLOCK_UNLOCK(f); - return; - } - - inspect_tx_id = AppLayerParserGetTransactionInspectId(f->alparser, flags); - total_txs = AppLayerParserGetTxCnt(f->proto, alproto, alstate); - - for ( ; inspect_tx_id < total_txs; inspect_tx_id++) { - int inspect_tx_inprogress = 0; - int next_tx_no_progress = 0; - void *inspect_tx = AppLayerParserGetTx(f->proto, alproto, alstate, inspect_tx_id); - if (inspect_tx != NULL) { - int a = AppLayerParserGetStateProgress(f->proto, alproto, inspect_tx, flags); - int b = AppLayerParserGetStateProgressCompletionStatus(f->proto, alproto, flags); - if (a < b) { - inspect_tx_inprogress = 1; - } - SCLogDebug("tx %"PRIu64" (%"PRIu64") => %s", inspect_tx_id, total_txs, - inspect_tx_inprogress ? "in progress" : "done"); - - DetectEngineState *tx_de_state = AppLayerParserGetTxDetectState(f->proto, alproto, inspect_tx); - if (tx_de_state == NULL) { - SCLogDebug("NO STATE tx %"PRIu64" (%"PRIu64")", inspect_tx_id, total_txs); - continue; - } - DetectEngineStateDirection *tx_dir_state = &tx_de_state->dir_state[direction]; - DeStateStore *tx_store = tx_dir_state->head; - - /* see if we need to consider the next tx in our decision to add - * a sig to the 'no inspect array'. */ - if (!TxIsLast(inspect_tx_id, total_txs)) { - void *next_inspect_tx = AppLayerParserGetTx(f->proto, alproto, alstate, inspect_tx_id+1); - if (next_inspect_tx != NULL) { - int c = AppLayerParserGetStateProgress(f->proto, alproto, next_inspect_tx, flags); - if (c == 0) { - next_tx_no_progress = 1; - } - } - } - - /* Loop through stored 'items' (stateful rules) and inspect them */ - state_cnt = 0; - for (; tx_store != NULL; tx_store = tx_store->next) { - SCLogDebug("tx_store %p", tx_store); - for (store_cnt = 0; - store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < tx_dir_state->cnt; - store_cnt++, state_cnt++) - { - DeStateStoreItem *item = &tx_store->store[store_cnt]; - int r = DoInspectItem(tv, de_ctx, det_ctx, - item, tx_dir_state->flags, - p, f, alproto, flags, - inspect_tx_id, total_txs, - &file_no_match, inspect_tx_inprogress, next_tx_no_progress); - if (r < 0) { - SCLogDebug("failed"); - goto end; - } - } - } - } - /* if the current tx is in progress, we won't advance to any newer - * tx' just yet. */ - if (inspect_tx_inprogress) { - SCLogDebug("break out"); - break; - } - } - } - - /* continue on flow based state rules (AMATCH) */ - if (f->de_state != NULL) { - DetectEngineStateDirectionFlow *dir_state = &f->de_state->dir_state[direction]; - DeStateStoreFlowRules *store = dir_state->head; - /* Loop through stored 'items' (stateful rules) and inspect them */ - for (; store != NULL; store = store->next) { - for (store_cnt = 0; - store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < dir_state->cnt; - store_cnt++, state_cnt++) - { - DeStateStoreFlowRule *rule = &store->store[store_cnt]; - - int r = DoInspectFlowRule(tv, de_ctx, det_ctx, - rule, dir_state->flags, - p, f, alproto, flags); - if (r < 0) { - goto end; - } - } - } - DeStateStoreStateVersion(f, alversion, flags); - } - -end: - FLOWLOCK_UNLOCK(f); - det_ctx->tx_id = 0; - det_ctx->tx_id_set = 0; - return; -} -/** \brief update flow's inspection id's - * - * \param f unlocked flow - * \param flags direction and disruption flags - * - * \note it is possible that f->alstate, f->alparser are NULL */ -void DeStateUpdateInspectTransactionId(Flow *f, const uint8_t flags) -{ - FLOWLOCK_WRLOCK(f); - if (f->alparser && f->alstate) { - AppLayerParserSetTransactionInspectId(f->alparser, f->proto, - f->alproto, f->alstate, flags); - } - FLOWLOCK_UNLOCK(f); - - return; -} - -void DetectEngineStateReset(DetectEngineStateFlow *state, uint8_t direction) -{ - if (state != NULL) { - if (direction & STREAM_TOSERVER) { - state->dir_state[0].cnt = 0; - state->dir_state[0].flags = 0; - } - if (direction & STREAM_TOCLIENT) { - state->dir_state[1].cnt = 0; - state->dir_state[1].flags = 0; - } - } - - return; -} - -/** \brief Reset de state for active tx' - * To be used on detect engine reload. - * \param f write LOCKED flow - */ -void DetectEngineStateResetTxs(Flow *f) -{ - if (AppLayerParserProtocolSupportsTxs(f->proto, f->alproto)) { - void *alstate = FlowGetAppState(f); - if (!StateIsValid(f->alproto, alstate)) { - return; - } - - uint64_t inspect_ts = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOCLIENT); - uint64_t inspect_tc = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOSERVER); - - uint64_t inspect_tx_id = MIN(inspect_ts, inspect_tc); - - uint64_t total_txs = AppLayerParserGetTxCnt(f->proto, f->alproto, alstate); - - for ( ; inspect_tx_id < total_txs; inspect_tx_id++) { - void *inspect_tx = AppLayerParserGetTx(f->proto, f->alproto, alstate, inspect_tx_id); - if (inspect_tx != NULL) { - DetectEngineState *tx_de_state = AppLayerParserGetTxDetectState(f->proto, f->alproto, inspect_tx); - if (tx_de_state == NULL) { - continue; - } - - tx_de_state->dir_state[0].cnt = 0; - tx_de_state->dir_state[0].filestore_cnt = 0; - tx_de_state->dir_state[0].flags = 0; - - tx_de_state->dir_state[1].cnt = 0; - tx_de_state->dir_state[1].filestore_cnt = 0; - tx_de_state->dir_state[1].flags = 0; - } - } - } -} - -/*********Unittests*********/ - -#ifdef UNITTESTS -#include "flow-util.h" - -static int DeStateTest01(void) -{ - SCLogDebug("sizeof(DetectEngineState)\t\t%"PRIuMAX, - (uintmax_t)sizeof(DetectEngineState)); - SCLogDebug("sizeof(DeStateStore)\t\t\t%"PRIuMAX, - (uintmax_t)sizeof(DeStateStore)); - SCLogDebug("sizeof(DeStateStoreItem)\t\t%"PRIuMAX"", - (uintmax_t)sizeof(DeStateStoreItem)); - - return 1; -} - -static int DeStateTest02(void) -{ - int result = 0; - - DetectEngineState *state = DetectEngineStateAlloc(); - if (state == NULL) { - printf("d == NULL: "); - goto end; - } - - Signature s; - memset(&s, 0x00, sizeof(s)); - - uint8_t direction = STREAM_TOSERVER; - - s.num = 0; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 11; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 22; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 33; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 44; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 55; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 66; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 77; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 88; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 99; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 100; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 111; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 122; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 133; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 144; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 155; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 166; - DeStateSignatureAppend(state, &s, 0, direction); - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL) { - goto end; - } - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11) { - goto end; - } - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL) { - goto end; - } - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144) { - goto end; - } - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155) { - goto end; - } - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166) { - goto end; - } - - result = 1; -end: - if (state != NULL) { - DetectEngineStateFree(state); - } - return result; -} - -static int DeStateTest03(void) -{ - int result = 0; - - DetectEngineState *state = DetectEngineStateAlloc(); - if (state == NULL) { - printf("d == NULL: "); - goto end; - } - - Signature s; - memset(&s, 0x00, sizeof(s)); - - uint8_t direction = STREAM_TOSERVER; - - s.num = 11; - DeStateSignatureAppend(state, &s, 0, direction); - s.num = 22; - DeStateSignatureAppend(state, &s, DE_STATE_FLAG_URI_INSPECT, direction); - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL) { - goto end; - } - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].sid != 11) { - goto end; - } - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].flags & DE_STATE_FLAG_URI_INSPECT) { - goto end; - } - - if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 22) { - goto end; - } - - if (!(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].flags & DE_STATE_FLAG_URI_INSPECT)) { - goto end; - } - - result = 1; -end: - if (state != NULL) { - DetectEngineStateFree(state); - } - return result; -} - -static int DeStateSigTest01(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\nContent-Length: 10\r\n\r\n"; - uint8_t httpbuf4[] = "Http Body!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"dummy\"; http_cookie; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("signature matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (http_state != NULL) { - HTPStateFree(http_state); - } - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test multiple pipelined http transactions */ -static int DeStateSigTest02(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n"; - uint8_t httpbuf4[] = "Http Body!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n"; - uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nHttp Body!"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"/\"; http_uri; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"body\"; nocase; http_client_body; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted too early: "); - goto end; - } - p->alerts.cnt = 0; - - void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, f.alstate, 0); - if (tx == NULL) { - printf("no http tx: "); - goto end; - } - DetectEngineState *tx_de_state = AppLayerParserGetTxDetectState(IPPROTO_TCP, ALPROTO_HTTP, tx); - if (tx_de_state == NULL || tx_de_state->dir_state[0].cnt != 1 || - tx_de_state->dir_state[0].head->store[0].flags != 0x00000001) { - printf("de_state not present or has unexpected content: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't match: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (5): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf7, httplen7); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match, but should have: "); - goto end; - } - p->alerts.cnt = 0; - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int DeStateSigTest03(void) -{ - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 215\r\n" - "\r\n" - "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n" - "filecontent\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - ThreadVars th_v; - TcpSession ssn; - int result = 0; - Flow *f = NULL; - Packet *p = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&ssn, 0, sizeof(ssn)); - - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - f->alproto = ALPROTO_HTTP; - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - if (p == NULL) - goto end; - - p->flow = f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (http_state->files_ts == NULL) { - printf("no files in state: "); - goto end; - } - - SCMutexLock(&f->m); - FileContainer *files = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto, - p->flow->alstate, STREAM_TOSERVER); - if (files == NULL) { - printf("no stored files: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - File *file = files->head; - if (file == NULL) { - printf("no file: "); - goto end; - } - - if (!(file->flags & FILE_STORE)) { - printf("file is set to store, but sig didn't match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreeFlow(f); - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - StreamTcpFreeConfig(TRUE); - return result; -} - -static int DeStateSigTest04(void) -{ - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 215\r\n" - "\r\n" - "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n" - "filecontent\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - ThreadVars th_v; - TcpSession ssn; - int result = 0; - Flow *f = NULL; - Packet *p = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&ssn, 0, sizeof(ssn)); - - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - f->alproto = ALPROTO_HTTP; - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - if (p == NULL) - goto end; - - p->flow = f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (http_state->files_ts == NULL) { - printf("no files in state: "); - goto end; - } - - SCMutexLock(&f->m); - FileContainer *files = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto, - p->flow->alstate, STREAM_TOSERVER); - if (files == NULL) { - printf("no stored files: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - File *file = files->head; - if (file == NULL) { - printf("no file: "); - goto end; - } - - if (file->flags & FILE_STORE) { - printf("file is set to store, but sig didn't match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreeFlow(f); - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - StreamTcpFreeConfig(TRUE); - return result; -} - -static int DeStateSigTest05(void) -{ - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 215\r\n" - "\r\n" - "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n" - "filecontent\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - ThreadVars th_v; - TcpSession ssn; - int result = 0; - Flow *f = NULL; - Packet *p = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&ssn, 0, sizeof(ssn)); - - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"nomatch\"; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - f->alproto = ALPROTO_HTTP; - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - if (p == NULL) - goto end; - - p->flow = f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (http_state->files_ts == NULL) { - printf("no files in state: "); - goto end; - } - - SCMutexLock(&f->m); - FileContainer *files = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto, - p->flow->alstate, STREAM_TOSERVER); - if (files == NULL) { - printf("no stored files: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - File *file = files->head; - if (file == NULL) { - printf("no file: "); - goto end; - } - - if (!(file->flags & FILE_NOSTORE)) { - printf("file is not set to \"no store\": "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreeFlow(f); - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - StreamTcpFreeConfig(TRUE); - return result; -} - -static int DeStateSigTest06(void) -{ - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 215\r\n" - "\r\n" - "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n" - "filecontent\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - ThreadVars th_v; - TcpSession ssn; - int result = 0; - Flow *f = NULL; - Packet *p = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&ssn, 0, sizeof(ssn)); - - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"nomatch\"; filestore; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - f->alproto = ALPROTO_HTTP; - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - if (p == NULL) - goto end; - - p->flow = f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (http_state->files_ts == NULL) { - printf("no files in state: "); - goto end; - } - - SCMutexLock(&f->m); - FileContainer *files = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto, - p->flow->alstate, STREAM_TOSERVER); - if (files == NULL) { - printf("no stored files: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - File *file = files->head; - if (file == NULL) { - printf("no file: "); - goto end; - } - - if (!(file->flags & FILE_NOSTORE)) { - printf("file is not set to \"no store\": "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreeFlow(f); - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - StreamTcpFreeConfig(TRUE); - return result; -} - -static int DeStateSigTest07(void) -{ - uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n" - "Host: www.server.lan\r\n" - "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n" - "Content-Length: 215\r\n" - "\r\n" - "-----------------------------277531038314945\r\n" - "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n" - "Content-Type: image/jpeg\r\n" - "\r\n"; - - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "filecontent\r\n" - "-----------------------------277531038314945--"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - ThreadVars th_v; - TcpSession ssn; - int result = 0; - Flow *f = NULL; - Packet *p = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&ssn, 0, sizeof(ssn)); - - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - f->alproto = ALPROTO_HTTP; - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - if (p == NULL) - goto end; - - p->flow = f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - - StreamTcpInitConfig(TRUE); - - SCLogDebug("\n>>>> processing chunk 1 <<<<\n"); - SCMutexLock(&f->m); - int r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - - SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2); - SCMutexLock(&f->m); - r = AppLayerParserParse(alp_tctx, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - - http_state = f->alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (http_state->files_ts == NULL) { - printf("no files in state: "); - goto end; - } - - SCMutexLock(&f->m); - FileContainer *files = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto, - p->flow->alstate, STREAM_TOSERVER); - if (files == NULL) { - printf("no stored files: "); - SCMutexUnlock(&f->m); - goto end; - } - SCMutexUnlock(&f->m); - - File *file = files->head; - if (file == NULL) { - printf("no file: "); - goto end; - } - - if (file->flags & FILE_STORE) { - printf("file is set to store, but sig didn't match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreeFlow(f); - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - StreamTcpFreeConfig(TRUE); - return result; -} - -#endif - -void DeStateRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DeStateTest01", DeStateTest01, 1); - UtRegisterTest("DeStateTest02", DeStateTest02, 1); - UtRegisterTest("DeStateTest03", DeStateTest03, 1); - UtRegisterTest("DeStateSigTest01", DeStateSigTest01, 1); - UtRegisterTest("DeStateSigTest02", DeStateSigTest02, 1); - UtRegisterTest("DeStateSigTest03", DeStateSigTest03, 1); - UtRegisterTest("DeStateSigTest04", DeStateSigTest04, 1); - UtRegisterTest("DeStateSigTest05", DeStateSigTest05, 1); - UtRegisterTest("DeStateSigTest06", DeStateSigTest06, 1); - UtRegisterTest("DeStateSigTest07", DeStateSigTest07, 1); -#endif - - return; -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-state.h b/framework/src/suricata/src/detect-engine-state.h deleted file mode 100644 index c8944cff..00000000 --- a/framework/src/suricata/src/detect-engine-state.h +++ /dev/null @@ -1,244 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup sigstate - * - * @{ - */ - -/** - * \file - * - * \brief Data structures and function prototypes for keeping - * state for the detection engine. - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -/* On DeState and locking. - * - * The DeState is part of a flow, but it can't be protected by the flow lock. - * Reason is we need to lock the DeState data for an entire detection run, - * as we're looping through on "continued" detection and rely on only a single - * detection instance setting it up on first run. We can't keep the entire flow - * locked during detection for performance reasons, it would slow us down too - * much. - * - * So a new lock was introduced. The only part of the process where we need - * the flow lock is obviously when we're getting/setting the de_state ptr from - * to the flow. - */ - -#ifndef __DETECT_ENGINE_STATE_H__ -#define __DETECT_ENGINE_STATE_H__ - -#define DETECT_ENGINE_INSPECT_SIG_NO_MATCH 0 -#define DETECT_ENGINE_INSPECT_SIG_MATCH 1 -#define DETECT_ENGINE_INSPECT_SIG_CANT_MATCH 2 -#define DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE 3 - -/** number of DeStateStoreItem's in one DeStateStore object */ -#define DE_STATE_CHUNK_SIZE 15 - -/* per sig flags */ -#define DE_STATE_FLAG_URI_INSPECT (1) -#define DE_STATE_FLAG_HRUD_INSPECT (1 << 1) -#define DE_STATE_FLAG_HCBD_INSPECT (1 << 2) -#define DE_STATE_FLAG_HSBD_INSPECT (1 << 3) -#define DE_STATE_FLAG_HHD_INSPECT (1 << 4) -#define DE_STATE_FLAG_HRHD_INSPECT (1 << 5) -#define DE_STATE_FLAG_HHHD_INSPECT (1 << 6) -#define DE_STATE_FLAG_HRHHD_INSPECT (1 << 7) -#define DE_STATE_FLAG_HUAD_INSPECT (1 << 8) -#define DE_STATE_FLAG_HMD_INSPECT (1 << 9) -#define DE_STATE_FLAG_HCD_INSPECT (1 << 10) -#define DE_STATE_FLAG_HSMD_INSPECT (1 << 11) -#define DE_STATE_FLAG_HSCD_INSPECT (1 << 12) -#define DE_STATE_FLAG_FILE_TC_INSPECT (1 << 13) -#define DE_STATE_FLAG_FILE_TS_INSPECT (1 << 14) -#define DE_STATE_FLAG_FULL_INSPECT (1 << 15) -#define DE_STATE_FLAG_SIG_CANT_MATCH (1 << 16) -#define DE_STATE_FLAG_DNSQUERYNAME_INSPECT (1 << 17) -#define DE_STATE_FLAG_APP_EVENT_INSPECT (1 << 18) -#define DE_STATE_FLAG_MODBUS_INSPECT (1 << 19) -#define DE_STATE_FLAG_HRL_INSPECT (1 << 20) -#define DE_STATE_FLAG_FD_SMTP_INSPECT (1 << 21) -#define DE_STATE_FLAG_DNSREQUEST_INSPECT (1 << 22) -#define DE_STATE_FLAG_DNSRESPONSE_INSPECT (1 << 23) -#define DE_STATE_FLAG_TEMPLATE_BUFFER_INSPECT (1 << 24) - -/* state flags */ -#define DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED 0x0001 -#define DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW 0x0002 -#define DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW 0x0004 - -/* We have 2 possible state values to be used by ContinueDetection() while - * trying to figure if we have fresh state to install or not. - * - * For tx based alprotos, we don't need to indicate the below values on a - * per sig basis, but for non-tx based alprotos we do, since we might have - * new alstate coming in, and some sigs might have already matchced in - * de_state and ContinueDetection needs to inform the detection filter that - * it no longer needs to inspect this sig, since ContinueDetection would - * handle it. - * - * Wrt tx based alprotos, if we have a new tx available apart from the one - * currently being inspected(and also added to de_state), we continue with - * the HAS_NEW_STATE flag, while if we don't have a new tx, we set - * NO_NEW_STATE, to avoid getting the sig reinspected for the already - * inspected tx. */ -#define DE_STATE_MATCH_HAS_NEW_STATE 0x00 -#define DE_STATE_MATCH_NO_NEW_STATE 0x80 - -/* TX BASED (inspect engines) */ - -typedef struct DeStateStoreItem_ { - uint32_t flags; - SigIntId sid; -} DeStateStoreItem; - -typedef struct DeStateStore_ { - DeStateStoreItem store[DE_STATE_CHUNK_SIZE]; - struct DeStateStore_ *next; -} DeStateStore; - -typedef struct DetectEngineStateDirection_ { - DeStateStore *head; - DeStateStore *tail; - SigIntId cnt; - uint16_t filestore_cnt; - uint8_t flags; -} DetectEngineStateDirection; - -typedef struct DetectEngineState_ { - DetectEngineStateDirection dir_state[2]; -} DetectEngineState; - -/* FLOW BASED (AMATCH) */ - -typedef struct DeStateStoreFlowRule_ { - SigMatch *nm; - uint32_t flags; - SigIntId sid; -} DeStateStoreFlowRule; - -typedef struct DeStateStoreFlowRules_ { - DeStateStoreFlowRule store[DE_STATE_CHUNK_SIZE]; - struct DeStateStoreFlowRules_ *next; -} DeStateStoreFlowRules; - -typedef struct DetectEngineStateDirectionFlow_ { - DeStateStoreFlowRules *head; - DeStateStoreFlowRules *tail; - SigIntId cnt; - uint8_t flags; -} DetectEngineStateDirectionFlow; - -typedef struct DetectEngineStateFlow_ { - DetectEngineStateDirectionFlow dir_state[2]; -} DetectEngineStateFlow; - -/** - * \brief Alloc a DetectEngineState object. - * - * \retval Alloc'd instance of DetectEngineState. - */ -DetectEngineState *DetectEngineStateAlloc(void); - -/** - * \brief Frees a DetectEngineState object. - * - * \param state DetectEngineState instance to free. - */ -void DetectEngineStateFree(DetectEngineState *state); -void DetectEngineStateFlowFree(DetectEngineStateFlow *state); - -/** - * \brief Check if a flow already contains(newly updated as well) de state. - * - * \param f Pointer to the flow. - * \param alversino The alversion to check against de_state's. - * \param direction Direction to check. 0 - ts, 1 - tc. - * - * \retval 1 Has state. - * \retval 0 Has no state. - */ -int DeStateFlowHasInspectableState(Flow *f, AppProto alproto, uint8_t alversion, uint8_t flags); - -/** - * \brief Match app layer sig list against app state and store relevant match - * information. - * - * \param tv Pointer to the threadvars. - * \param de_ctx DetectEngineCtx instance. - * \param det_ctx DetectEngineThreadCtx instance. - * \param s Pointer to the signature. - * \param f Pointer to the flow. - * \param flags Flags. - * \param alproto App protocol. - * \param alversion Current app layer version. - * - * \retval >= 0 An integer value indicating the no of matches. - */ -int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Packet *p, Flow *f, uint8_t flags, - AppProto alproto, uint8_t alversion); - -/** - * \brief Continue DeState detection of the signatures stored in the state. - * - * \param tv Pointer to the threadvars. - * \param de_ctx DetectEngineCtx instance. - * \param det_ctx DetectEngineThreadCtx instance. - * \param f Pointer to the flow. - * \param flags Flags. - * \param alproto App protocol. - * \param alversion Current app layer version. - */ -void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Packet *p, Flow *f, uint8_t flags, - AppProto alproto, uint8_t alversion); - -/** - * \brief Update the inspect id. - * - * \param f unlocked flow - * \param flags direction and disruption flags - */ -void DeStateUpdateInspectTransactionId(Flow *f, const uint8_t flags); - -/** - * \brief Reset a DetectEngineState state. - * - * \param state Pointer to the state(LOCKED). - * \param direction Direction flags - STREAM_TOSERVER or STREAM_TOCLIENT. - */ -void DetectEngineStateReset(DetectEngineStateFlow *state, uint8_t direction); - -void DetectEngineStateResetTxs(Flow *f); - -void DeStateRegisterTests(void); - -#endif /* __DETECT_ENGINE_STATE_H__ */ - -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-tag.c b/framework/src/suricata/src/detect-engine-tag.c deleted file mode 100644 index 7c8caabb..00000000 --- a/framework/src/suricata/src/detect-engine-tag.c +++ /dev/null @@ -1,1519 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file detect-engine-tag.c - * - * \author Victor Julien - * \author Pablo Rincon Crespo - * - * Implements a global context to store data related to hosts flagged - * tag keyword - */ - -#include "suricata-common.h" -#include "detect-engine.h" -#include "util-hash.h" -#include "util-atomic.h" -#include "util-time.h" -#include "util-hashlist.h" -#include "detect-engine-tag.h" -#include "detect-tag.h" -#include "host.h" -#include "host-storage.h" -#include "flow-storage.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "flow-util.h" -#include "stream-tcp-private.h" - -SC_ATOMIC_DECLARE(unsigned int, num_tags); /**< Atomic counter, to know if we - have tagged hosts/sessions, - to avoid locking */ -static int host_tag_id = -1; /**< Host storage id for tags */ -static int flow_tag_id = -1; /**< Flow storage id for tags */ - -void TagInitCtx(void) -{ - SC_ATOMIC_INIT(num_tags); - - host_tag_id = HostStorageRegister("tag", sizeof(void *), NULL, DetectTagDataListFree); - if (host_tag_id == -1) { - SCLogError(SC_ERR_HOST_INIT, "Can't initiate host storage for tag"); - exit(EXIT_FAILURE); - } - flow_tag_id = FlowStorageRegister("tag", sizeof(void *), NULL, DetectTagDataListFree); - if (flow_tag_id == -1) { - SCLogError(SC_ERR_FLOW_INIT, "Can't initiate flow storage for tag"); - exit(EXIT_FAILURE); - } -} - -/** - * \brief Destroy tag context hash tables - * - * \param tag_ctx Tag Context - * - */ -void TagDestroyCtx(void) -{ -#ifdef DEBUG - BUG_ON(SC_ATOMIC_GET(num_tags) != 0); -#endif - SC_ATOMIC_DESTROY(num_tags); -} - -/** \brief Reset the tagging engine context - */ -void TagRestartCtx() -{ - TagDestroyCtx(); - TagInitCtx(); -} - -int TagHostHasTag(Host *host) -{ - return HostGetStorageById(host, host_tag_id) ? 1 : 0; -} - -static DetectTagDataEntry *DetectTagDataCopy(DetectTagDataEntry *dtd) -{ - DetectTagDataEntry *tde = SCMalloc(sizeof(DetectTagDataEntry)); - if (unlikely(tde == NULL)) { - return NULL; - } - memset(tde, 0, sizeof(DetectTagDataEntry)); - - tde->sid = dtd->sid; - tde->gid = dtd->gid; - tde->flags = dtd->flags; - tde->metric = dtd->metric; - tde->count = dtd->count; - - tde->first_ts = dtd->first_ts; - tde->last_ts = dtd->last_ts; - return tde; -} - -/** - * \brief This function is used to add a tag to a session (type session) - * or update it if it's already installed. The number of times to - * allow an update is limited by DETECT_TAG_MATCH_LIMIT. This way - * repetitive matches to the same rule are limited of setting tags, - * to avoid DOS attacks - * - * \param p pointer to the current packet - * \param tde pointer to the new DetectTagDataEntry - * - * \retval 0 if the tde was added succesfuly - * \retval 1 if an entry of this sid/gid already exist and was updated - */ -int TagFlowAdd(Packet *p, DetectTagDataEntry *tde) -{ - uint8_t updated = 0; - uint16_t tag_cnt = 0; - DetectTagDataEntry *iter = NULL; - - if (p->flow == NULL) - return 1; - - FLOWLOCK_WRLOCK(p->flow); - iter = FlowGetStorageById(p->flow, flow_tag_id); - if (iter != NULL) { - /* First iterate installed entries searching a duplicated sid/gid */ - for (; iter != NULL; iter = iter->next) { - tag_cnt++; - - if (iter->sid == tde->sid && iter->gid == tde->gid) { - iter->cnt_match++; - - /* If so, update data, unless the maximum MATCH limit is - * reached. This prevents possible DOS attacks */ - if (iter->cnt_match < DETECT_TAG_MATCH_LIMIT) { - /* Reset time and counters */ - iter->first_ts = iter->last_ts = tde->first_ts; - iter->packets = 0; - iter->bytes = 0; - } - updated = 1; - break; - } - } - } - - /* If there was no entry of this rule, prepend the new tde */ - if (updated == 0 && tag_cnt < DETECT_TAG_MAX_TAGS) { - DetectTagDataEntry *new_tde = DetectTagDataCopy(tde); - if (new_tde != NULL) { - new_tde->next = FlowGetStorageById(p->flow, flow_tag_id); - FlowSetStorageById(p->flow, flow_tag_id, new_tde); - SCLogDebug("adding tag with first_ts %u", new_tde->first_ts); - (void) SC_ATOMIC_ADD(num_tags, 1); - } - } else if (tag_cnt == DETECT_TAG_MAX_TAGS) { - SCLogDebug("Max tags for sessions reached (%"PRIu16")", tag_cnt); - } - - FLOWLOCK_UNLOCK(p->flow); - return updated; -} - -/** - * \brief Add a tag entry for a host. If it already exist, update it. - * - * \param tag_ctx Tag context for hosts - * \param tde Tag data - * \param p packet - * - * \retval 0 if it was added, 1 if it was updated - */ -int TagHashAddTag(DetectTagDataEntry *tde, Packet *p) -{ - SCEnter(); - - uint8_t updated = 0; - uint16_t num_tags = 0; - Host *host = NULL; - - /* Lookup host in the hash. If it doesn't exist yet it's - * created. */ - if (tde->flags & TAG_ENTRY_FLAG_DIR_SRC) { - host = HostGetHostFromHash(&p->src); - } else if (tde->flags & TAG_ENTRY_FLAG_DIR_DST) { - host = HostGetHostFromHash(&p->dst); - } - /* no host for us */ - if (host == NULL) { - SCLogDebug("host tag not added: no host"); - return -1; - } - - void *tag = HostGetStorageById(host, host_tag_id); - if (tag == NULL) { - /* get a new tde as the one we have is on the stack */ - DetectTagDataEntry *new_tde = DetectTagDataCopy(tde); - if (new_tde != NULL) { - HostSetStorageById(host, host_tag_id, new_tde); - (void) SC_ATOMIC_ADD(num_tags, 1); - SCLogDebug("host tag added"); - } - } else { - /* Append the tag to the list of this host */ - SCLogDebug("updating existing host"); - - /* First iterate installed entries searching a duplicated sid/gid */ - DetectTagDataEntry *iter = NULL; - - for (iter = tag; iter != NULL; iter = iter->next) { - num_tags++; - if (iter->sid == tde->sid && iter->gid == tde->gid) { - iter->cnt_match++; - /* If so, update data, unless the maximum MATCH limit is - * reached. This prevents possible DOS attacks */ - if (iter->cnt_match < DETECT_TAG_MATCH_LIMIT) { - /* Reset time and counters */ - iter->first_ts = iter->last_ts = tde->first_ts; - iter->packets = 0; - iter->bytes = 0; - } - updated = 1; - break; - } - } - - /* If there was no entry of this rule, append the new tde */ - if (updated == 0 && num_tags < DETECT_TAG_MAX_TAGS) { - /* get a new tde as the one we have is on the stack */ - DetectTagDataEntry *new_tde = DetectTagDataCopy(tde); - if (new_tde != NULL) { - (void) SC_ATOMIC_ADD(num_tags, 1); - - new_tde->next = tag; - HostSetStorageById(host, host_tag_id, new_tde); - } - } else if (num_tags == DETECT_TAG_MAX_TAGS) { - SCLogDebug("Max tags for sessions reached (%"PRIu16")", num_tags); - } - } - - HostRelease(host); - SCReturnInt(updated); -} - -static void TagHandlePacketFlow(Flow *f, Packet *p) -{ - if (FlowGetStorageById(f, flow_tag_id) == NULL) - return; - - DetectTagDataEntry *tde = NULL; - DetectTagDataEntry *prev = NULL; - DetectTagDataEntry *iter = FlowGetStorageById(f, flow_tag_id); - uint8_t flag_added = 0; - - while (iter != NULL) { - /* update counters */ - iter->last_ts = p->ts.tv_sec; - switch (iter->metric) { - case DETECT_TAG_METRIC_PACKET: - iter->packets++; - break; - case DETECT_TAG_METRIC_BYTES: - iter->bytes += GET_PKT_LEN(p); - break; - } - - /* If this packet triggered the rule with tag, we dont need - * to log it (the alert will log it) */ - if (!(iter->flags & TAG_ENTRY_FLAG_SKIPPED_FIRST)) { - iter->flags |= TAG_ENTRY_FLAG_SKIPPED_FIRST; - } else { - /* Update metrics; remove if tag expired; and set alerts */ - switch (iter->metric) { - case DETECT_TAG_METRIC_PACKET: - if (iter->packets > iter->count) { - SCLogDebug("flow tag expired: packets %u > %u", - iter->packets, iter->count); - /* tag expired */ - if (prev != NULL) { - tde = iter; - prev->next = iter->next; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - continue; - } else { - FlowSetStorageById(p->flow, flow_tag_id, iter->next); - tde = iter; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - continue; - } - } else if (flag_added == 0) { - /* It's matching the tag. Add it to be logged and - * update "flag_added" to add the packet once. */ - p->flags |= PKT_HAS_TAG; - flag_added++; - } - break; - case DETECT_TAG_METRIC_BYTES: - if (iter->bytes > iter->count) { - /* tag expired */ - SCLogDebug("flow tag expired: bytes %u > %u", - iter->bytes, iter->count); - if (prev != NULL) { - tde = iter; - prev->next = iter->next; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - continue; - } else { - FlowSetStorageById(p->flow, flow_tag_id, iter->next); - tde = iter; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - continue; - } - } else if (flag_added == 0) { - /* It's matching the tag. Add it to be logged and - * update "flag_added" to add the packet once. */ - p->flags |= PKT_HAS_TAG; - flag_added++; - } - break; - case DETECT_TAG_METRIC_SECONDS: - /* last_ts handles this metric, but also a generic time based - * expiration to prevent dead sessions/hosts */ - if (iter->last_ts - iter->first_ts > iter->count) { - SCLogDebug("flow tag expired: %u - %u = %u > %u", - iter->last_ts, iter->first_ts, - (iter->last_ts - iter->first_ts), iter->count); - /* tag expired */ - if (prev != NULL) { - tde = iter; - prev->next = iter->next; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - continue; - } else { - FlowSetStorageById(p->flow, flow_tag_id, iter->next); - tde = iter; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - continue; - } - } else if (flag_added == 0) { - /* It's matching the tag. Add it to be logged and - * update "flag_added" to add the packet once. */ - p->flags |= PKT_HAS_TAG; - flag_added++; - } - break; - } - - } - - prev = iter; - iter = iter->next; - } -} - -void TagHandlePacketHost(Host *host, Packet *p) -{ - DetectTagDataEntry *tde = NULL; - DetectTagDataEntry *prev = NULL; - DetectTagDataEntry *iter; - uint8_t flag_added = 0; - - iter = HostGetStorageById(host, host_tag_id); - prev = NULL; - while (iter != NULL) { - /* update counters */ - iter->last_ts = p->ts.tv_sec; - switch (iter->metric) { - case DETECT_TAG_METRIC_PACKET: - iter->packets++; - break; - case DETECT_TAG_METRIC_BYTES: - iter->bytes += GET_PKT_LEN(p); - break; - } - - /* If this packet triggered the rule with tag, we dont need - * to log it (the alert will log it) */ - if (!(iter->flags & TAG_ENTRY_FLAG_SKIPPED_FIRST)) { - iter->flags |= TAG_ENTRY_FLAG_SKIPPED_FIRST; - } else { - /* Update metrics; remove if tag expired; and set alerts */ - switch (iter->metric) { - case DETECT_TAG_METRIC_PACKET: - if (iter->packets > iter->count) { - SCLogDebug("host tag expired: packets %u > %u", iter->packets, iter->count); - /* tag expired */ - if (prev != NULL) { - tde = iter; - prev->next = iter->next; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - continue; - } else { - tde = iter; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - HostSetStorageById(host, host_tag_id, iter); - continue; - } - } else if (flag_added == 0) { - /* It's matching the tag. Add it to be logged and - * update "flag_added" to add the packet once. */ - p->flags |= PKT_HAS_TAG; - flag_added++; - } - break; - case DETECT_TAG_METRIC_BYTES: - if (iter->bytes > iter->count) { - SCLogDebug("host tag expired: bytes %u > %u", iter->bytes, iter->count); - /* tag expired */ - if (prev != NULL) { - tde = iter; - prev->next = iter->next; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - continue; - } else { - tde = iter; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - HostSetStorageById(host, host_tag_id, iter); - continue; - } - } else if (flag_added == 0) { - /* It's matching the tag. Add it to be logged and - * update "flag_added" to add the packet once. */ - p->flags |= PKT_HAS_TAG; - flag_added++; - } - break; - case DETECT_TAG_METRIC_SECONDS: - /* last_ts handles this metric, but also a generic time based - * expiration to prevent dead sessions/hosts */ - if (iter->last_ts - iter->first_ts > iter->count) { - SCLogDebug("host tag expired: %u - %u = %u > %u", - iter->last_ts, iter->first_ts, - (iter->last_ts - iter->first_ts), iter->count); - /* tag expired */ - if (prev != NULL) { - tde = iter; - prev->next = iter->next; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - continue; - } else { - tde = iter; - iter = iter->next; - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - HostSetStorageById(host, host_tag_id, iter); - continue; - } - } else if (flag_added == 0) { - /* It's matching the tag. Add it to be logged and - * update "flag_added" to add the packet once. */ - p->flags |= PKT_HAS_TAG; - flag_added++; - } - break; - } - - } - - prev = iter; - iter = iter->next; - } -} - -/** - * \brief Search tags for src and dst. Update entries of the tag, remove if necessary - * - * \param de_ctx Detect context - * \param det_ctx Detect thread context - * \param p packet - * - */ -void TagHandlePacket(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Packet *p) -{ - SCEnter(); - - /* If there's no tag, get out of here */ - unsigned int current_tags = SC_ATOMIC_GET(num_tags); - if (current_tags == 0) - SCReturn; - - /* First update and get session tags */ - if (p->flow != NULL) { - FLOWLOCK_WRLOCK(p->flow); - TagHandlePacketFlow(p->flow, p); - FLOWLOCK_UNLOCK(p->flow); - } - - Host *src = HostLookupHostFromHash(&p->src); - if (src) { - if (TagHostHasTag(src)) { - TagHandlePacketHost(src,p); - } - HostRelease(src); - } - Host *dst = HostLookupHostFromHash(&p->dst); - if (dst) { - if (TagHostHasTag(dst)) { - TagHandlePacketHost(dst,p); - } - HostRelease(dst); - } - SCReturn; -} - -/** - * \brief Removes the entries exceding the max timeout value - * - * \param tag_ctx Tag context - * \param ts the current time - * - * \retval 1 no tags or tags removed -- host is free to go (from tag perspective) - * \retval 0 still active tags - */ -int TagTimeoutCheck(Host *host, struct timeval *tv) -{ - DetectTagDataEntry *tde = NULL; - DetectTagDataEntry *tmp = NULL; - DetectTagDataEntry *prev = NULL; - int retval = 1; - - tmp = HostGetStorageById(host, host_tag_id); - if (tmp == NULL) - return 1; - - prev = NULL; - while (tmp != NULL) { - if ((tv->tv_sec - tmp->last_ts) <= TAG_MAX_LAST_TIME_SEEN) { - prev = tmp; - tmp = tmp->next; - retval = 0; - continue; - } - - /* timed out */ - - if (prev != NULL) { - prev->next = tmp->next; - - tde = tmp; - tmp = tde->next; - - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - } else { - HostSetStorageById(host, host_tag_id, tmp->next); - - tde = tmp; - tmp = tde->next; - - SCFree(tde); - (void) SC_ATOMIC_SUB(num_tags, 1); - } - } - return retval; -} - -#ifdef UNITTESTS - -/** - * \test host tagging: packets - */ -int DetectTagTestPacket01 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint8_t *buf2 = (uint8_t *)"lalala!"; - uint16_t buf_len = strlen((char *)buf); - uint16_t buf_len2 = strlen((char *)buf2); - - Packet *p[7]; - p[0] = UTHBuildPacketReal(buf, buf_len, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[2] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.9", - 41424, 80); - p[3] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.9", - 41424, 80); - p[4] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.9", - 41424, 80); - p[5] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.11", - 41424, 80); - p[6] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.11", - 41424, 80); - - char *sigs[5]; - sigs[0]= "alert tcp any any -> any any (msg:\"Testing tag 1\"; content:\"Hi all\"; tag:host,3,packets,src; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"Hi all\"; tag:host,4,packets,dst; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:3;)"; - sigs[3]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:4;)"; - sigs[4]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:5;)"; - - /* Please, Notice that tagged data goes with sig_id = 1 and tag sig generator = 2 */ - uint32_t sid[5] = {1,2,3,4,5}; - - int32_t results[7][5] = { - {1, 1, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0} - }; - StorageInit(); - TagInitCtx(); - StorageFinalize(); - HostInitConfig(1); - - SCLogDebug("running tests"); - result = UTHGenericTest(p, 7, sigs, sid, (uint32_t *) results, 5); - SCLogDebug("running tests done"); - - Host *src = HostLookupHostFromHash(&p[1]->src); - if (src) { - void *tag = HostGetStorageById(src, host_tag_id); - if (tag != NULL) { - printf("tag should have been expired: "); - result = 0; - } - - HostRelease(src); - } - Host *dst = HostLookupHostFromHash(&p[1]->dst); - if (dst) { - void *tag = HostGetStorageById(dst, host_tag_id); - BUG_ON(tag == NULL); - - DetectTagDataEntry *iter = tag; - - /* check internal state */ - if (!(iter->gid == 1 && iter->sid == 2 && iter->packets == 4 && iter->count == 4)) { - printf("gid %u sid %u packets %u count %u: ", iter->gid, iter->sid, iter->packets, iter->count); - result = 0; - } - - HostRelease(dst); - } - BUG_ON(src == NULL || dst == NULL); - - UTHFreePackets(p, 7); - - HostShutdown(); - TagDestroyCtx(); - StorageCleanup(); - return result; -} - -/** - * \test host tagging: seconds - */ -int DetectTagTestPacket02 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint8_t *buf2 = (uint8_t *)"lalala!"; - uint16_t buf_len = strlen((char *)buf); - uint16_t buf_len2 = strlen((char *)buf2); - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - StorageInit(); - TagInitCtx(); - StorageFinalize(); - HostInitConfig(1); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - Packet *p[7]; - p[0] = UTHBuildPacketReal(buf, buf_len, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[2] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.9", - 41424, 80); - p[3] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.9", - 41424, 80); - p[4] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.9", - 41424, 80); - p[5] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.11", - 41424, 80); - p[6] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.11", - 41424, 80); - - char *sigs[5]; - sigs[0]= "alert tcp any any -> any any (msg:\"Testing tag 1\"; content:\"Hi all\"; tag:host,3,seconds,src; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"Hi all\"; tag:host,8,seconds,dst; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:3;)"; - sigs[3]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:4;)"; - sigs[4]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:5;)"; - - /* Please, Notice that tagged data goes with sig_id = 1 and tag sig generator = 2 */ - uint32_t sid[5] = {1,2,3,4,5}; - int numsigs = 5; - - if (UTHAppendSigs(de_ctx, sigs, numsigs) == 0) - goto cleanup; - - //de_ctx->flags |= DE_QUIET; - - int32_t results[7][5] = { - {1, 1, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0} - }; - - int num_packets = 7; - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int i = 0; - for (; i < num_packets; i++) { - SCLogDebug("packet %d", i); - TimeGet(&p[i]->ts); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); - if (UTHCheckPacketMatchResults(p[i], sid, (uint32_t *)&results[i][0], numsigs) == 0) - goto cleanup; - - TimeSetIncrementTime(2); - SCLogDebug("packet %d flag %s", i, p[i]->flags & PKT_HAS_TAG ? "true" : "false"); - - /* see if the PKT_HAS_TAG is set on the packet if needed */ - int expect; - if (i == 0 || i == 2 || i == 3 || i == 5 || i == 6) - expect = FALSE; - else - expect = TRUE; - if (((p[i]->flags & PKT_HAS_TAG) ? TRUE : FALSE) != expect) - goto cleanup; - } - - result = 1; - -cleanup: - UTHFreePackets(p, 7); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } -end: - HostShutdown(); - TagDestroyCtx(); - StorageCleanup(); - return result; -} - -/** - * \test host tagging: bytes - */ -static int DetectTagTestPacket03 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint8_t *buf2 = (uint8_t *)"lalala!"; - uint16_t buf_len = strlen((char *)buf); - uint16_t buf_len2 = strlen((char *)buf2); - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - StorageInit(); - TagInitCtx(); - StorageFinalize(); - HostInitConfig(1); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - Packet *p[7]; - p[0] = UTHBuildPacketReal(buf, buf_len, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[2] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.9", - 41424, 80); - p[3] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.9", - 41424, 80); - p[4] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.9", - 41424, 80); - p[5] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.11", - 41424, 80); - p[6] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.11", - 41424, 80); - - char *sigs[5]; - sigs[0]= "alert tcp any any -> any any (msg:\"Testing tag 1\"; content:\"Hi all\"; tag:host, 150, bytes, src; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"Hi all\"; tag:host, 150, bytes, dst; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:3;)"; - sigs[3]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:4;)"; - sigs[4]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:5;)"; - - /* Please, Notice that tagged data goes with sig_id = 1 and tag sig generator = 2 */ - uint32_t sid[5] = {1,2,3,4,5}; - int numsigs = 5; - - if (UTHAppendSigs(de_ctx, sigs, numsigs) == 0) - goto cleanup; - - int32_t results[7][5] = { - {1, 1, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0} - }; - - int num_packets = 7; - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int i = 0; - for (; i < num_packets; i++) { - SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); - - if (UTHCheckPacketMatchResults(p[i], sid, (uint32_t *)&results[i][0], numsigs) == 0) - goto cleanup; - - SCLogDebug("packet %d flag %s", i, p[i]->flags & PKT_HAS_TAG ? "true" : "false"); - - /* see if the PKT_HAS_TAG is set on the packet if needed */ - int expect; - if (i == 0 || i == 3 || i == 5 || i == 6) - expect = FALSE; - else - expect = TRUE; - if (((p[i]->flags & PKT_HAS_TAG) ? TRUE : FALSE) != expect) - goto cleanup; - } - - result = 1; - -cleanup: - UTHFreePackets(p, 7); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } -end: - HostShutdown(); - TagDestroyCtx(); - StorageCleanup(); - return result; -} - -/** - * \test session tagging: packets - */ -static int DetectTagTestPacket04 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint8_t *buf2 = (uint8_t *)"lalala!"; - uint16_t buf_len = strlen((char *)buf); - uint16_t buf_len2 = strlen((char *)buf2); - - Flow *f = NULL; - TcpSession ssn; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - StorageInit(); - TagInitCtx(); - StorageFinalize(); - HostInitConfig(1); - FlowInitConfig(1); - - f = FlowAlloc(); - BUG_ON(f == NULL); - FLOW_INITIALIZE(f); - f->protoctx = (void *)&ssn; - f->flags |= FLOW_IPV4; - if (inet_pton(AF_INET, "192.168.1.5", f->src.addr_data32) != 1) - goto end; - if (inet_pton(AF_INET, "192.168.1.1", f->dst.addr_data32) != 1) - goto end; - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - Packet *p[7]; - p[0] = UTHBuildPacketReal(buf, buf_len, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[2] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[3] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[4] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[5] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[6] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 80, 41424); - - char *sigs[5]; - sigs[0]= "alert tcp any any -> any any (msg:\"Testing tag 1\"; content:\"Hi all\"; tag:session,4,packets; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"blahblah\"; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:3;)"; - sigs[3]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:4;)"; - sigs[4]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:5;)"; - - /* Please, Notice that tagged data goes with sig_id = 1 and tag sig generator = 2 */ - uint32_t sid[5] = {1,2,3,4,5}; - int numsigs = 5; - - if (UTHAppendSigs(de_ctx, sigs, numsigs) == 0) - goto cleanup; - - int32_t results[7][5] = { - {1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0} - }; - - int num_packets = 7; - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int i = 0; - for (; i < num_packets; i++) { - p[i]->flow = f; - p[i]->flow->protoctx = &ssn; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); - - if (UTHCheckPacketMatchResults(p[i], sid, (uint32_t *)&results[i][0], numsigs) == 0) - goto cleanup; - - SCLogDebug("packet %d flag %s", i, p[i]->flags & PKT_HAS_TAG ? "true" : "false"); - /* see if the PKT_HAS_TAG is set on the packet if needed */ - int expect; - if (i == 0 || i == 4 || i == 5 || i == 6) - expect = FALSE; - else - expect = TRUE; - if (((p[i]->flags & PKT_HAS_TAG) ? TRUE : FALSE) != expect) - goto cleanup; - } - - result = 1; - -cleanup: - UTHFreePackets(p, 7); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - /* clean up flow */ - uint8_t proto_map = FlowGetProtoMapping(f->proto); - FlowClearMemory(f, proto_map); - FLOW_DESTROY(f); -end: - FlowShutdown(); - HostShutdown(); - TagDestroyCtx(); - StorageCleanup(); - return result; -} - -/** - * \test session tagging: seconds - */ -static int DetectTagTestPacket05 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint8_t *buf2 = (uint8_t *)"lalala!"; - uint16_t buf_len = strlen((char *)buf); - uint16_t buf_len2 = strlen((char *)buf2); - - Flow *f = NULL; - TcpSession ssn; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - StorageInit(); - TagInitCtx(); - StorageFinalize(); - HostInitConfig(1); - FlowInitConfig(1); - - f = FlowAlloc(); - BUG_ON(f == NULL); - FLOW_INITIALIZE(f); - f->protoctx = (void *)&ssn; - f->flags |= FLOW_IPV4; - if (inet_pton(AF_INET, "192.168.1.5", f->src.addr_data32) != 1) - goto end; - if (inet_pton(AF_INET, "192.168.1.1", f->dst.addr_data32) != 1) - goto end; - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - Packet *p[7]; - p[0] = UTHBuildPacketReal(buf, buf_len, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[2] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[3] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[4] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[5] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[6] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 80, 41424); - - char *sigs[5]; - sigs[0]= "alert tcp any any -> any any (msg:\"Testing tag 1\"; content:\"Hi all\"; tag:session,8,seconds; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"blahblah\"; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:3;)"; - sigs[3]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:4;)"; - sigs[4]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:5;)"; - - /* Please, Notice that tagged data goes with sig_id = 1 and tag sig generator = 2 */ - uint32_t sid[5] = {1,2,3,4,5}; - int numsigs = 5; - - if (UTHAppendSigs(de_ctx, sigs, numsigs) == 0) - goto cleanup; - - int32_t results[7][5] = { - {1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0} - }; - - int num_packets = 7; - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int i = 0; - for (; i < num_packets; i++) { - p[i]->flow = f; - p[i]->flow->protoctx = &ssn; - - SCLogDebug("packet %d", i); - TimeGet(&p[i]->ts); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); - - if (UTHCheckPacketMatchResults(p[i], sid, (uint32_t *)&results[i][0], numsigs) == 0) - goto cleanup; - - TimeSetIncrementTime(2); - - SCLogDebug("packet %d flag %s", i, p[i]->flags & PKT_HAS_TAG ? "true" : "false"); - /* see if the PKT_HAS_TAG is set on the packet if needed */ - int expect; - if (i == 0 || i == 5 || i == 6) - expect = FALSE; - else - expect = TRUE; - if (((p[i]->flags & PKT_HAS_TAG) ? TRUE : FALSE) != expect) - goto cleanup; - } - - result = 1; - -cleanup: - UTHFreePackets(p, 7); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - /* clean up flow */ - uint8_t proto_map = FlowGetProtoMapping(f->proto); - FlowClearMemory(f, proto_map); - FLOW_DESTROY(f); -end: - FlowShutdown(); - HostShutdown(); - TagDestroyCtx(); - StorageCleanup(); - return result; -} - -/** - * \test session tagging: bytes - */ -static int DetectTagTestPacket06 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint8_t *buf2 = (uint8_t *)"lalala!"; - uint16_t buf_len = strlen((char *)buf); - uint16_t buf_len2 = strlen((char *)buf2); - - Flow *f = NULL; - TcpSession ssn; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - StorageInit(); - TagInitCtx(); - StorageFinalize(); - HostInitConfig(1); - FlowInitConfig(1); - - f = FlowAlloc(); - BUG_ON(f == NULL); - FLOW_INITIALIZE(f); - f->protoctx = (void *)&ssn; - f->flags |= FLOW_IPV4; - if (inet_pton(AF_INET, "192.168.1.5", f->src.addr_data32) != 1) - goto end; - if (inet_pton(AF_INET, "192.168.1.1", f->dst.addr_data32) != 1) - goto end; - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - Packet *p[7]; - p[0] = UTHBuildPacketReal(buf, buf_len, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[2] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[3] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[4] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[5] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[6] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 80, 41424); - - char *sigs[5]; - sigs[0]= "alert tcp any any -> any any (msg:\"Testing tag 1\"; content:\"Hi all\"; tag:session,150,bytes; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"blahblah\"; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:3;)"; - sigs[3]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:4;)"; - sigs[4]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:5;)"; - - /* Please, Notice that tagged data goes with sig_id = 1 and tag sig generator = 2 */ - uint32_t sid[5] = {1,2,3,4,5}; - int numsigs = 5; - - if (UTHAppendSigs(de_ctx, sigs, numsigs) == 0) - goto cleanup; - - int32_t results[7][5] = { - {1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0} - }; - - int num_packets = 7; - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int i = 0; - for (; i < num_packets; i++) { - p[i]->flow = f; - p[i]->flow->protoctx = &ssn; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); - - if (UTHCheckPacketMatchResults(p[i], sid, (uint32_t *)&results[i][0], numsigs) == 0) - goto cleanup; - - SCLogDebug("packet %d flag %s", i, p[i]->flags & PKT_HAS_TAG ? "true" : "false"); - - /* see if the PKT_HAS_TAG is set on the packet if needed */ - int expect; - if (i == 0 || i == 3 || i == 4 || i == 5 || i == 6) - expect = FALSE; - else - expect = TRUE; - if (((p[i]->flags & PKT_HAS_TAG) ? TRUE : FALSE) != expect) - goto cleanup; - } - - result = 1; - -cleanup: - UTHFreePackets(p, 7); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - /* clean up flow */ - uint8_t proto_map = FlowGetProtoMapping(f->proto); - FlowClearMemory(f, proto_map); - FLOW_DESTROY(f); -end: - FlowShutdown(); - HostShutdown(); - TagDestroyCtx(); - StorageCleanup(); - return result; -} - -/** - * \test session tagging: bytes, where a 2nd match makes us tag more - */ -static int DetectTagTestPacket07 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint8_t *buf2 = (uint8_t *)"lalala!"; - uint16_t buf_len = strlen((char *)buf); - uint16_t buf_len2 = strlen((char *)buf2); - - Flow *f = NULL; - TcpSession ssn; - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - StorageInit(); - TagInitCtx(); - StorageFinalize(); - HostInitConfig(1); - FlowInitConfig(1); - - f = FlowAlloc(); - BUG_ON(f == NULL); - FLOW_INITIALIZE(f); - f->protoctx = (void *)&ssn; - f->flags |= FLOW_IPV4; - if (inet_pton(AF_INET, "192.168.1.5", f->src.addr_data32) != 1) - goto end; - if (inet_pton(AF_INET, "192.168.1.1", f->dst.addr_data32) != 1) - goto end; - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - Packet *p[7]; - p[0] = UTHBuildPacketReal(buf, buf_len, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[2] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[3] = UTHBuildPacketReal(buf, buf_len, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[4] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[5] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[6] = UTHBuildPacketReal(buf2, buf_len2, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 80, 41424); - - char *sigs[5]; - sigs[0]= "alert tcp any any -> any any (msg:\"Testing tag 1\"; content:\"Hi all\"; tag:session,150,bytes; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"blahblah\"; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:3;)"; - sigs[3]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:4;)"; - sigs[4]= "alert tcp any any -> any any (msg:\"Testing tag 2\"; content:\"no match\"; sid:5;)"; - - /* Please, Notice that tagged data goes with sig_id = 1 and tag sig generator = 2 */ - uint32_t sid[5] = {1,2,3,4,5}; - int numsigs = 5; - - if (UTHAppendSigs(de_ctx, sigs, numsigs) == 0) - goto cleanup; - - int32_t results[7][5] = { - {1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {1, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0} - }; - - int num_packets = 7; - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int i = 0; - for (; i < num_packets; i++) { - p[i]->flow = f; - p[i]->flow->protoctx = &ssn; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); - - if (UTHCheckPacketMatchResults(p[i], sid, (uint32_t *)&results[i][0], numsigs) == 0) - goto cleanup; - - SCLogDebug("packet %d flag %s", i, p[i]->flags & PKT_HAS_TAG ? "true" : "false"); -#if 1 - /* see if the PKT_HAS_TAG is set on the packet if needed */ - int expect; - if (i == 0 || i == 6) - expect = FALSE; - else - expect = TRUE; - if (((p[i]->flags & PKT_HAS_TAG) ? TRUE : FALSE) != expect) - goto cleanup; -#endif - } - - result = 1; - -cleanup: - UTHFreePackets(p, 7); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - /* clean up flow */ - uint8_t proto_map = FlowGetProtoMapping(f->proto); - FlowClearMemory(f, proto_map); - FLOW_DESTROY(f); -end: - FlowShutdown(); - HostShutdown(); - TagDestroyCtx(); - StorageCleanup(); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectTag - */ -void DetectEngineTagRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectTagTestPacket01", DetectTagTestPacket01, 1); - UtRegisterTest("DetectTagTestPacket02", DetectTagTestPacket02, 1); - UtRegisterTest("DetectTagTestPacket03", DetectTagTestPacket03, 1); - UtRegisterTest("DetectTagTestPacket04", DetectTagTestPacket04, 1); - UtRegisterTest("DetectTagTestPacket05", DetectTagTestPacket05, 1); - UtRegisterTest("DetectTagTestPacket06", DetectTagTestPacket06, 1); - UtRegisterTest("DetectTagTestPacket07", DetectTagTestPacket07, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-engine-tag.h b/framework/src/suricata/src/detect-engine-tag.h deleted file mode 100644 index 93243cef..00000000 --- a/framework/src/suricata/src/detect-engine-tag.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file detect-engine-tag.h - * - * \author Pablo Rincon Crespo - * - * Implements a global context to store data related to hosts flagged - * tag keyword - */ - -#ifndef __DETECT_ENGINE_TAG_H__ -#define __DETECT_ENGINE_TAG_H__ - -#include "host.h" -#include "detect.h" - -/* This limit should be overwriten/predefined at the config file - * to limit the options to prevent possible DOS situations. We should also - * create a limit for bytes and a limit for number of packets */ -#define TAG_MAX_LAST_TIME_SEEN 600 - -#define TAG_TIMEOUT_CHECK_INTERVAL 60 - -/* Used for tagged data (sid and gid of the packets that - * follow the one that triggered the rule with tag option) */ -#define TAG_SIG_GEN 2 -#define TAG_SIG_ID 1 - -int TagHashAddTag(DetectTagDataEntry *, Packet *); -int TagFlowAdd(Packet *, DetectTagDataEntry *); - -void TagContextDestroy(void); -void TagHandlePacket(DetectEngineCtx *, DetectEngineThreadCtx *, Packet *); - -void TagInitCtx(void); -void TagDestroyCtx(void); -void TagRestartCtx(void); - -int TagTimeoutCheck(Host *, struct timeval *); - -int TagHostHasTag(Host *host); - -void DetectEngineTagRegisterTests(void); - -#endif /* __DETECT_ENGINE_TAG_H__ */ - - diff --git a/framework/src/suricata/src/detect-engine-template.c b/framework/src/suricata/src/detect-engine-template.c deleted file mode 100644 index 49c29c6a..00000000 --- a/framework/src/suricata/src/detect-engine-template.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "stream.h" -#include "detect-engine-content-inspection.h" - -#include "app-layer-template.h" - -int DetectEngineInspectTemplateBuffer(ThreadVars *tv, DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags, - void *alstate, void *txv, uint64_t tx_id) -{ - TemplateTransaction *tx = (TemplateTransaction *)txv; - int ret = 0; - - if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) { - ret = DetectEngineContentInspection(de_ctx, det_ctx, s, - s->sm_lists[DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH], f, - tx->request_buffer, tx->request_buffer_len, 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_TEMPLATE_BUFFER, NULL); - } - else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) { - ret = DetectEngineContentInspection(de_ctx, det_ctx, s, - s->sm_lists[DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH], f, - tx->response_buffer, tx->response_buffer_len, 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_TEMPLATE_BUFFER, NULL); - } - - SCLogNotice("Returning %d.", ret); - return ret; -} diff --git a/framework/src/suricata/src/detect-engine-template.h b/framework/src/suricata/src/detect-engine-template.h deleted file mode 100644 index 61eb8d01..00000000 --- a/framework/src/suricata/src/detect-engine-template.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __DETECT_TEMPLATE_ENGINE_H__ -#define __DETECT_TEMPLATE_ENGINE_H__ - -int DetectEngineInspectTemplateBuffer(ThreadVars *, DetectEngineCtx *, - DetectEngineThreadCtx *, Signature *, Flow *, uint8_t, void *, void *, - uint64_t); - -#endif /* __DETECT_TEMPLATE_ENGINE_H__ */ diff --git a/framework/src/suricata/src/detect-engine-threshold.c b/framework/src/suricata/src/detect-engine-threshold.c deleted file mode 100644 index 2d37e55e..00000000 --- a/framework/src/suricata/src/detect-engine-threshold.c +++ /dev/null @@ -1,689 +0,0 @@ -/* Copyright (C) 2007-2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \defgroup threshold Thresholding - * - * This feature is used to reduce the number of logged alerts for noisy rules. - * This can be tuned to significantly reduce false alarms, and it can also be - * used to write a newer breed of rules. Thresholding commands limit the number - * of times a particular event is logged during a specified time interval. - * - * @{ - */ - -/** - * \file - * - * \author Breno Silva - * \author Victor Julien - * - * Threshold part of the detection engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" - -#include "host.h" -#include "host-storage.h" - -#include "detect-parse.h" -#include "detect-engine-sigorder.h" - -#include "detect-engine-siggroup.h" -#include "detect-engine-address.h" -#include "detect-engine-port.h" -#include "detect-engine-mpm.h" -#include "detect-engine-iponly.h" - -#include "detect-engine.h" -#include "detect-engine-threshold.h" - -#include "detect-content.h" -#include "detect-uricontent.h" - -#include "util-hash.h" -#include "util-time.h" -#include "util-error.h" -#include "util-debug.h" - -#include "util-var-name.h" -#include "tm-threads.h" - -static int threshold_id = -1; /**< host storage id for thresholds */ - -int ThresholdHostStorageId(void) -{ - return threshold_id; -} - -void ThresholdInit(void) -{ - threshold_id = HostStorageRegister("threshold", sizeof(void *), NULL, ThresholdListFree); - if (threshold_id == -1) { - SCLogError(SC_ERR_HOST_INIT, "Can't initiate host storage for thresholding"); - exit(EXIT_FAILURE); - } -} - -int ThresholdHostHasThreshold(Host *host) -{ - return HostGetStorageById(host, threshold_id) ? 1 : 0; -} - -/** - * \brief Return next DetectThresholdData for signature - * - * \param sig Signature pointer - * \param p Packet structure - * \param sm Pointer to a Signature Match pointer - * - * \retval tsh Return the threshold data from signature or NULL if not found - * - * - */ -DetectThresholdData *SigGetThresholdTypeIter(Signature *sig, Packet *p, SigMatch **psm, int list) -{ - SigMatch *sm = NULL; - DetectThresholdData *tsh = NULL; - - if (sig == NULL) - return NULL; - - if (*psm == NULL) { - sm = sig->sm_lists_tail[list]; - } else { - /* Iteration in progress, using provided value */ - sm = *psm; - } - - if (p == NULL) - return NULL; - - while (sm != NULL) { - if (sm->type == DETECT_THRESHOLD || sm->type == DETECT_DETECTION_FILTER) { - tsh = (DetectThresholdData *)sm->ctx; - *psm = sm->prev; - return tsh; - } - - sm = sm->prev; - } - *psm = NULL; - - return NULL; -} - -/** - * \brief Remove timeout threshold hash elements - * - * \param de_ctx Dectection Context - * - */ - -int ThresholdTimeoutCheck(Host *host, struct timeval *tv) -{ - DetectThresholdEntry *tde = NULL; - DetectThresholdEntry *tmp = NULL; - DetectThresholdEntry *prev = NULL; - int retval = 1; - - tmp = HostGetStorageById(host, threshold_id); - if (tmp == NULL) - return 1; - - prev = NULL; - while (tmp != NULL) { - if ((tv->tv_sec - tmp->tv_sec1) <= tmp->seconds) { - prev = tmp; - tmp = tmp->next; - retval = 0; - continue; - } - - /* timed out */ - - if (prev != NULL) { - prev->next = tmp->next; - - tde = tmp; - tmp = tde->next; - - SCFree(tde); - } else { - HostSetStorageById(host, threshold_id, tmp->next); - tde = tmp; - tmp = tde->next; - - SCFree(tde); - } - } - - return retval; -} - -static inline DetectThresholdEntry *DetectThresholdEntryAlloc(DetectThresholdData *td, Packet *p, uint32_t sid, uint32_t gid) -{ - SCEnter(); - - DetectThresholdEntry *ste = SCMalloc(sizeof(DetectThresholdEntry)); - if (unlikely(ste == NULL)) { - SCReturnPtr(NULL, "DetectThresholdEntry"); - } - - ste->sid = sid; - ste->gid = gid; - - ste->track = td->track; - ste->seconds = td->seconds; - ste->tv_timeout = 0; - - SCReturnPtr(ste, "DetectThresholdEntry"); -} - -static DetectThresholdEntry *ThresholdHostLookupEntry(Host *h, uint32_t sid, uint32_t gid) -{ - DetectThresholdEntry *e; - - for (e = HostGetStorageById(h, threshold_id); e != NULL; e = e->next) { - if (e->sid == sid && e->gid == gid) - break; - } - - return e; -} - -int ThresholdHandlePacketSuppress(Packet *p, DetectThresholdData *td, uint32_t sid, uint32_t gid) -{ - int ret = 0; - DetectAddress *m = NULL; - switch (td->track) { - case TRACK_DST: - m = DetectAddressLookupInHead(&td->addrs, &p->dst); - SCLogDebug("TRACK_DST"); - break; - case TRACK_SRC: - m = DetectAddressLookupInHead(&td->addrs, &p->src); - SCLogDebug("TRACK_SRC"); - break; - /* suppress if either src or dst is a match on the suppress - * address list */ - case TRACK_EITHER: - m = DetectAddressLookupInHead(&td->addrs, &p->src); - if (m == NULL) { - m = DetectAddressLookupInHead(&td->addrs, &p->dst); - } - break; - case TRACK_RULE: - default: - SCLogError(SC_ERR_INVALID_VALUE, - "track mode %d is not supported", td->track); - break; - } - if (m == NULL) - ret = 1; - else - ret = 2; /* suppressed but still need actions */ - - return ret; -} - -/** - * \retval 2 silent match (no alert but apply actions) - * \retval 1 normal match - * \retval 0 no match - */ -int ThresholdHandlePacketHost(Host *h, Packet *p, DetectThresholdData *td, uint32_t sid, uint32_t gid) -{ - int ret = 0; - - DetectThresholdEntry *lookup_tsh = ThresholdHostLookupEntry(h, sid, gid); - SCLogDebug("lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid); - - switch(td->type) { - case TYPE_LIMIT: - { - SCLogDebug("limit"); - - if (lookup_tsh != NULL) { - if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) { - lookup_tsh->current_count++; - - if (lookup_tsh->current_count <= td->count) { - ret = 1; - } else { - ret = 2; - } - } else { - lookup_tsh->tv_sec1 = p->ts.tv_sec; - lookup_tsh->current_count = 1; - - ret = 1; - } - } else { - DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid); - if (e == NULL) { - break; - } - - e->tv_sec1 = p->ts.tv_sec; - e->current_count = 1; - - ret = 1; - - e->next = HostGetStorageById(h, threshold_id); - HostSetStorageById(h, threshold_id, e); - } - break; - } - case TYPE_THRESHOLD: - { - SCLogDebug("threshold"); - - if (lookup_tsh != NULL) { - if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) { - lookup_tsh->current_count++; - - if (lookup_tsh->current_count >= td->count) { - ret = 1; - lookup_tsh->current_count = 0; - } - } else { - lookup_tsh->tv_sec1 = p->ts.tv_sec; - lookup_tsh->current_count = 1; - } - } else { - if (td->count == 1) { - ret = 1; - } else { - DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid); - if (e == NULL) { - break; - } - - e->current_count = 1; - e->tv_sec1 = p->ts.tv_sec; - - e->next = HostGetStorageById(h, threshold_id); - HostSetStorageById(h, threshold_id, e); - } - } - break; - } - case TYPE_BOTH: - { - SCLogDebug("both"); - - if (lookup_tsh != NULL) { - if ((p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) { - /* within time limit */ - - lookup_tsh->current_count++; - if (lookup_tsh->current_count == td->count) { - ret = 1; - } else if (lookup_tsh->current_count > td->count) { - /* silent match */ - ret = 2; - } - } else { - /* expired, so reset */ - lookup_tsh->tv_sec1 = p->ts.tv_sec; - lookup_tsh->current_count = 1; - - /* if we have a limit of 1, this is a match */ - if (lookup_tsh->current_count == td->count) { - ret = 1; - } - } - } else { - DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid); - if (e == NULL) { - break; - } - - e->current_count = 1; - e->tv_sec1 = p->ts.tv_sec; - - e->next = HostGetStorageById(h, threshold_id); - HostSetStorageById(h, threshold_id, e); - - /* for the first match we return 1 to - * indicate we should alert */ - if (td->count == 1) { - ret = 1; - } - } - break; - } - /* detection_filter */ - case TYPE_DETECTION: - { - SCLogDebug("detection_filter"); - - if (lookup_tsh != NULL) { - long double time_diff = ((p->ts.tv_sec + p->ts.tv_usec/1000000.0) - - (lookup_tsh->tv_sec1 + lookup_tsh->tv_usec1/1000000.0)); - - if (time_diff < td->seconds) { - /* within timeout */ - - lookup_tsh->current_count++; - if (lookup_tsh->current_count > td->count) { - ret = 1; - } - } else { - /* expired, reset */ - - lookup_tsh->tv_sec1 = p->ts.tv_sec; - lookup_tsh->tv_usec1 = p->ts.tv_usec; - lookup_tsh->current_count = 1; - } - } else { - DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid); - if (e == NULL) { - break; - } - - e->current_count = 1; - e->tv_sec1 = p->ts.tv_sec; - e->tv_usec1 = p->ts.tv_usec; - - e->next = HostGetStorageById(h, threshold_id); - HostSetStorageById(h, threshold_id, e); - } - break; - } - /* rate_filter */ - case TYPE_RATE: - { - SCLogDebug("rate_filter"); - - ret = 1; - - if (lookup_tsh != NULL) { - /* Check if we have a timeout enabled, if so, - * we still matching (and enabling the new_action) */ - if (lookup_tsh->tv_timeout != 0) { - if ((p->ts.tv_sec - lookup_tsh->tv_timeout) > td->timeout) { - /* Ok, we are done, timeout reached */ - lookup_tsh->tv_timeout = 0; - } else { - /* Already matching */ - /* Take the action to perform */ - switch (td->new_action) { - case TH_ACTION_ALERT: - PACKET_ALERT(p); - break; - case TH_ACTION_DROP: - PACKET_DROP(p); - break; - case TH_ACTION_REJECT: - PACKET_REJECT(p); - break; - case TH_ACTION_PASS: - PACKET_PASS(p); - break; - default: - /* Weird, leave the default action */ - break; - } - ret = 1; - } /* else - if ((p->ts.tv_sec - lookup_tsh->tv_timeout) > td->timeout) */ - - } else { - /* Update the matching state with the timeout interval */ - if ( (p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) { - lookup_tsh->current_count++; - if (lookup_tsh->current_count > td->count) { - /* Then we must enable the new action by setting a - * timeout */ - lookup_tsh->tv_timeout = p->ts.tv_sec; - /* Take the action to perform */ - switch (td->new_action) { - case TH_ACTION_ALERT: - PACKET_ALERT(p); - break; - case TH_ACTION_DROP: - PACKET_DROP(p); - break; - case TH_ACTION_REJECT: - PACKET_REJECT(p); - break; - case TH_ACTION_PASS: - PACKET_PASS(p); - break; - default: - /* Weird, leave the default action */ - break; - } - ret = 1; - } - } else { - lookup_tsh->tv_sec1 = p->ts.tv_sec; - lookup_tsh->current_count = 1; - } - } /* else - if (lookup_tsh->tv_timeout != 0) */ - } else { - if (td->count == 1) { - ret = 1; - } - - DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, sid, gid); - if (e == NULL) { - break; - } - - e->current_count = 1; - e->tv_sec1 = p->ts.tv_sec; - e->tv_timeout = 0; - - e->next = HostGetStorageById(h, threshold_id); - HostSetStorageById(h, threshold_id, e); - } - break; - } - /* case TYPE_SUPPRESS: is not handled here */ - default: - SCLogError(SC_ERR_INVALID_VALUE, "type %d is not supported", td->type); - } - - return ret; -} - -static int ThresholdHandlePacketRule(DetectEngineCtx *de_ctx, Packet *p, DetectThresholdData *td, Signature *s) -{ - int ret = 0; - - if (td->type != TYPE_RATE) - return 1; - - DetectThresholdEntry* lookup_tsh = (DetectThresholdEntry *)de_ctx->ths_ctx.th_entry[s->num]; - if (lookup_tsh != NULL) { - /* Check if we have a timeout enabled, if so, - * we still matching (and enabling the new_action) */ - if ( (p->ts.tv_sec - lookup_tsh->tv_timeout) > td->timeout) { - /* Ok, we are done, timeout reached */ - td->timeout = 0; - } else { - /* Already matching */ - /* Take the action to perform */ - switch (td->new_action) { - case TH_ACTION_ALERT: - PACKET_ALERT(p); - break; - case TH_ACTION_DROP: - PACKET_DROP(p); - break; - case TH_ACTION_REJECT: - PACKET_REJECT(p); - break; - case TH_ACTION_PASS: - PACKET_PASS(p); - break; - default: - /* Weird, leave the default action */ - break; - } - ret = 1; - } - - /* Update the matching state with the timeout interval */ - if ( (p->ts.tv_sec - lookup_tsh->tv_sec1) < td->seconds) { - lookup_tsh->current_count++; - if (lookup_tsh->current_count >= td->count) { - /* Then we must enable the new action by setting a - * timeout */ - lookup_tsh->tv_timeout = p->ts.tv_sec; - /* Take the action to perform */ - switch (td->new_action) { - case TH_ACTION_ALERT: - PACKET_ALERT(p); - break; - case TH_ACTION_DROP: - PACKET_DROP(p); - break; - case TH_ACTION_REJECT: - PACKET_REJECT(p); - break; - case TH_ACTION_PASS: - PACKET_PASS(p); - break; - default: - /* Weird, leave the default action */ - break; - } - ret = 1; - } - } else { - lookup_tsh->tv_sec1 = p->ts.tv_sec; - lookup_tsh->current_count = 1; - } - } else { - if (td->count == 1) { - ret = 1; - } - - DetectThresholdEntry *e = DetectThresholdEntryAlloc(td, p, s->id, s->gid); - if (e != NULL) { - e->current_count = 1; - e->tv_sec1 = p->ts.tv_sec; - e->tv_timeout = 0; - - de_ctx->ths_ctx.th_entry[s->num] = e; - } - } - - return ret; -} - -/** - * \brief Make the threshold logic for signatures - * - * \param de_ctx Dectection Context - * \param tsh_ptr Threshold element - * \param p Packet structure - * \param s Signature structure - * - * \retval 2 silent match (no alert but apply actions) - * \retval 1 alert on this event - * \retval 0 do not alert on this event - */ -int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - DetectThresholdData *td, Packet *p, Signature *s) -{ - SCEnter(); - - int ret = 0; - if (td == NULL) { - SCReturnInt(0); - } - - if (td->type == TYPE_SUPPRESS) { - ret = ThresholdHandlePacketSuppress(p,td,s->id,s->gid); - } else if (td->track == TRACK_SRC) { - Host *src = HostGetHostFromHash(&p->src); - if (src) { - ret = ThresholdHandlePacketHost(src,p,td,s->id,s->gid); - HostRelease(src); - } - } else if (td->track == TRACK_DST) { - Host *dst = HostGetHostFromHash(&p->dst); - if (dst) { - ret = ThresholdHandlePacketHost(dst,p,td,s->id,s->gid); - HostRelease(dst); - } - } else if (td->track == TRACK_RULE) { - SCMutexLock(&de_ctx->ths_ctx.threshold_table_lock); - ret = ThresholdHandlePacketRule(de_ctx,p,td,s); - SCMutexUnlock(&de_ctx->ths_ctx.threshold_table_lock); - } - - SCReturnInt(ret); -} - -/** - * \brief Init threshold context hash tables - * - * \param de_ctx Dectection Context - * - */ -void ThresholdHashInit(DetectEngineCtx *de_ctx) -{ - if (SCMutexInit(&de_ctx->ths_ctx.threshold_table_lock, NULL) != 0) { - SCLogError(SC_ERR_MEM_ALLOC, - "Threshold: Failed to initialize hash table mutex."); - exit(EXIT_FAILURE); - } -} - -/** - * \brief Destroy threshold context hash tables - * - * \param de_ctx Dectection Context - * - */ -void ThresholdContextDestroy(DetectEngineCtx *de_ctx) -{ - if (de_ctx->ths_ctx.th_entry != NULL) - SCFree(de_ctx->ths_ctx.th_entry); - SCMutexDestroy(&de_ctx->ths_ctx.threshold_table_lock); -} - -/** - * \brief this function will free all the entries of a list - * DetectTagDataEntry - * - * \param td pointer to DetectTagDataEntryList - */ -void ThresholdListFree(void *ptr) -{ - if (ptr != NULL) { - DetectThresholdEntry *entry = ptr; - - while (entry != NULL) { - DetectThresholdEntry *next_entry = entry->next; - SCFree(entry); - entry = next_entry; - } - } -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-engine-threshold.h b/framework/src/suricata/src/detect-engine-threshold.h deleted file mode 100644 index b874ecb2..00000000 --- a/framework/src/suricata/src/detect-engine-threshold.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_THRESHOLD_H__ -#define __DETECT_ENGINE_THRESHOLD_H__ - -#include "detect.h" -#include "host.h" - -void ThresholdInit(void); - -int ThresholdHostStorageId(void); -int ThresholdHostHasThreshold(Host *); - -DetectThresholdData *SigGetThresholdTypeIter(Signature *, Packet *, SigMatch **, int list); -int PacketAlertThreshold(DetectEngineCtx *, DetectEngineThreadCtx *, - DetectThresholdData *, Packet *, Signature *); - -void ThresholdHashInit(DetectEngineCtx *); -void ThresholdContextDestroy(DetectEngineCtx *); - -int ThresholdTimeoutCheck(Host *, struct timeval *); -void ThresholdListFree(void *ptr); - -#endif /* __DETECT_ENGINE_THRESHOLD_H__ */ diff --git a/framework/src/suricata/src/detect-engine-uri.c b/framework/src/suricata/src/detect-engine-uri.c deleted file mode 100644 index cd737157..00000000 --- a/framework/src/suricata/src/detect-engine-uri.c +++ /dev/null @@ -1,4222 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - * \author Pablo Rincon Crespo - * - * Based on detect-engine-uri.c - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" - -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -/** - * \brief Do the content inspection & validation for a signature - * - * \param de_ctx Detection engine context - * \param det_ctx Detection engine thread context - * \param s Signature to inspect - * \param sm SigMatch to inspect - * \param f Flow - * \param flags app layer flags - * \param state App layer state - * - * \retval 0 no match. - * \retval 1 match. - * \retval 2 Sig can't match. - */ -int DetectEngineInspectPacketUris(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *txv, uint64_t tx_id) -{ - HtpTxUserData *tx_ud = htp_tx_get_user_data(txv); - - if (tx_ud == NULL || tx_ud->request_uri_normalized == NULL) { - if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, txv, flags) > HTP_REQUEST_LINE) - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - else - return DETECT_ENGINE_INSPECT_SIG_NO_MATCH; - } - - det_ctx->discontinue_matching = 0; - det_ctx->buffer_offset = 0; - det_ctx->inspection_recursion_counter = 0; - -#if 0 - PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx_ud->request_uri_normalized), - bstr_len(tx_ud->request_uri_normalized)); -#endif - - /* Inspect all the uricontents fetched on each - * transaction at the app layer */ - int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_UMATCH], - f, - bstr_ptr(tx_ud->request_uri_normalized), - bstr_len(tx_ud->request_uri_normalized), - 0, - DETECT_ENGINE_CONTENT_INSPECTION_MODE_URI, NULL); - if (r == 1) { - return DETECT_ENGINE_INSPECT_SIG_MATCH; - } else { - return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; - } -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS -/** \test Test a simple uricontent option */ -static int UriTestSig01(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent option\"; " - "uricontent:\"one\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option */ -static int UriTestSig02(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /on HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option\"; " - "pcre:/one/U; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted with payload2, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option */ -static int UriTestSig03(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option\"; " - "pcre:/blah/U; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the urilen option */ -static int UriTestSig04(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test urilen option\"; " - "urilen:>20; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the urilen option */ -static int UriTestSig05(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test urilen option\"; " - "urilen:>4; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option */ -static int UriTestSig06(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option\"; " - "pcre:/(oneself)+/U; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert on payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option in combination with urilen */ -static int UriTestSig07(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option with urilen \"; " - "pcre:/(one){2,}(self)?/U; urilen:3<>20; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option in combination with urilen */ -static int UriTestSig08(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option with urilen\"; " - "pcre:/(blabla){2,}(self)?/U; urilen:3<>20; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the pcre /U option in combination with urilen */ -static int UriTestSig09(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U option with urilen \"; " - "pcre:/(one){2,}(self)?/U; urilen:<2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test the uricontent option in combination with urilen */ -static int UriTestSig10(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent with urilen option\"; " - "uricontent:\"one\"; urilen:<2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test content, uricontent, urilen, pcre /U options */ -static int UriTestSig11(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test content, uricontent, pcre /U and urilen options\"; " - "content:\"one\"; uricontent:\"one\"; pcre:/(one){2,}(self)?/U;" - "urilen:<2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test uricontent, urilen, pcre /U options */ -static int UriTestSig12(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test pcre /U, uricontent and urilen option\"; " - "uricontent:\"one\"; " - "pcre:/(one)+self/U; urilen:>2; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test uricontent, urilen */ -static int UriTestSig13(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test urilen option\"; " - "urilen:>2; uricontent:\"one\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test uricontent, pcre /U */ -static int UriTestSig14(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent option\"; " - "uricontent:\"one\"; pcre:/one(self)?/U;sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test pcre /U with anchored regex (bug 155) */ -static int UriTestSig15(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Test uricontent option\"; " - "uricontent:\"one\"; pcre:/^\\/one(self)?$/U;sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didnt alert with payload2, but it should: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test Test pcre /U with anchored regex (bug 155) */ -static int UriTestSig16(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0/\r\n" - "Host: 1.2.3.4\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf2) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any any (msg:\"ET TROJAN Downadup/Conficker A or B Worm reporting\"; flow:to_server,established; uricontent:\"/search?q=\"; pcre:\"/^\\/search\\?q=[0-9]{1,3}(&aq=7(\\?[0-9a-f]{8})?)?/U\"; pcre:\"/\\x0d\\x0aHost\\: \\d+\\.\\d+\\.\\d+\\.\\d+\\x0d\\x0a/\"; sid:2009024; rev:9;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 2009024)) { - printf("sig 1 didnt alert with pkt, but it should: "); - goto end; - } - p->alerts.cnt = 0; - - DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT); - p->payload = http_buf2; - p->payload_len = http_buf2_len; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 2009024)) { - printf("sig 1 alerted, but it should not (host should not match): "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents - */ -static int UriTestSig17(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_big_big_string_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"this\"; uricontent:\"is\"; within:6; " - "uricontent:\"big\"; within:8; " - "uricontent:\"string\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents - */ -static int UriTestSig18(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_is_big_big_big_string_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"this\"; uricontent:\"is\"; within:9; " - "uricontent:\"big\"; within:12; " - "uricontent:\"string\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents - */ -static int UriTestSig19(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_this_now_is_is_____big_string_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"now\"; uricontent:\"this\"; " - "uricontent:\"is\"; within:12; " - "uricontent:\"big\"; within:8; " - "uricontent:\"string\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with offset - */ -static int UriTestSig20(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /_________thus_thus_is_a_big HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"thus\"; offset:8; " - "uricontent:\"is\"; within:6; " - "uricontent:\"big\"; within:8; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig21(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"fix\"; uricontent:\"this\"; within:6; " - "uricontent:!\"and\"; distance:0; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test relative pcre. - */ -static int UriTestSig22(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_is_a_super_duper_" - "nova_in_super_nova_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "pcre:/super/U; uricontent:\"nova\"; within:7; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig23(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:!\"fix_this_now\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig24(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"we_need_to\"; uricontent:!\"fix_this_now\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test normalized uricontents. - */ -static int UriTestSig25(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "pcre:/normalized/U; uricontent:\"normalized uri\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig26(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"fix_this\"; isdataat:4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test Test multiple relative contents with a negated content. - */ -static int UriTestSig27(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "uricontent:\"fix_this\"; isdataat:!10,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -static int UriTestSig28(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"ring\"; distance:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig29(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"ring\"; distance:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig30(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"_b5ig\"; offset:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig31(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"his\"; depth:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig32(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"dummy\"; " - "uricontent:\"this\"; " - "byte_extract:1,2,one,string,dec,relative; " - "uricontent:\"g_st\"; within:one; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig33(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:15; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig34(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:15, norm; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig35(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:16; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig36(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:16, norm; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig37(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:17, raw; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int UriTestSig38(void) -{ - int result = 0; - uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri " - "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n"; - uint32_t http_buf_len = strlen((char *)http_buf); - Flow f; - TcpSession ssn; - HtpState *http_state = NULL; - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_HTTP; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test multiple relative uricontents\"; " - "urilen:18, raw; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted, but it shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -#endif /* UNITTESTS */ - -void UriRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("UriTestSig01", UriTestSig01, 1); - UtRegisterTest("UriTestSig02", UriTestSig02, 1); - UtRegisterTest("UriTestSig03", UriTestSig03, 1); - UtRegisterTest("UriTestSig04", UriTestSig04, 1); - UtRegisterTest("UriTestSig05", UriTestSig05, 1); - UtRegisterTest("UriTestSig06", UriTestSig06, 1); - UtRegisterTest("UriTestSig07", UriTestSig07, 1); - UtRegisterTest("UriTestSig08", UriTestSig08, 1); - UtRegisterTest("UriTestSig09", UriTestSig09, 1); - UtRegisterTest("UriTestSig10", UriTestSig10, 1); - UtRegisterTest("UriTestSig11", UriTestSig11, 1); - UtRegisterTest("UriTestSig12", UriTestSig12, 1); - UtRegisterTest("UriTestSig13", UriTestSig13, 1); - UtRegisterTest("UriTestSig14", UriTestSig14, 1); - UtRegisterTest("UriTestSig15", UriTestSig15, 1); - UtRegisterTest("UriTestSig16", UriTestSig16, 1); - UtRegisterTest("UriTestSig17", UriTestSig17, 1); - UtRegisterTest("UriTestSig18", UriTestSig18, 1); - UtRegisterTest("UriTestSig19", UriTestSig19, 1); - UtRegisterTest("UriTestSig20", UriTestSig20, 1); - UtRegisterTest("UriTestSig21", UriTestSig21, 1); - UtRegisterTest("UriTestSig22", UriTestSig22, 1); - UtRegisterTest("UriTestSig23", UriTestSig23, 1); - UtRegisterTest("UriTestSig24", UriTestSig24, 1); - UtRegisterTest("UriTestSig25", UriTestSig25, 1); - UtRegisterTest("UriTestSig26", UriTestSig26, 1); - UtRegisterTest("UriTestSig27", UriTestSig27, 1); - - UtRegisterTest("UriTestSig28", UriTestSig28, 1); - UtRegisterTest("UriTestSig29", UriTestSig29, 1); - UtRegisterTest("UriTestSig30", UriTestSig30, 1); - UtRegisterTest("UriTestSig31", UriTestSig31, 1); - UtRegisterTest("UriTestSig32", UriTestSig32, 1); - UtRegisterTest("UriTestSig33", UriTestSig33, 1); - UtRegisterTest("UriTestSig34", UriTestSig34, 1); - UtRegisterTest("UriTestSig35", UriTestSig35, 1); - UtRegisterTest("UriTestSig36", UriTestSig36, 1); - UtRegisterTest("UriTestSig37", UriTestSig37, 1); - UtRegisterTest("UriTestSig38", UriTestSig38, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-engine-uri.h b/framework/src/suricata/src/detect-engine-uri.h deleted file mode 100644 index 92b22cd3..00000000 --- a/framework/src/suricata/src/detect-engine-uri.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - * \author Pablo Rincon Crespo - */ - -#ifndef __DETECT_ENGINE_URICONTENT_H__ -#define __DETECT_ENGINE_URICONTENT_H__ - -int DetectEngineInspectPacketUris(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *s, Flow *f, uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id); -void UriRegisterTests(void); - -#endif /* __DETECT_ENGINE_URICONTENT_H__ */ - diff --git a/framework/src/suricata/src/detect-engine.c b/framework/src/suricata/src/detect-engine.c deleted file mode 100644 index cba76ca3..00000000 --- a/framework/src/suricata/src/detect-engine.c +++ /dev/null @@ -1,3291 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "flow-private.h" -#include "flow-util.h" -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "app-layer-htp.h" - -#include "detect-parse.h" -#include "detect-engine-sigorder.h" - -#include "detect-engine-siggroup.h" -#include "detect-engine-address.h" -#include "detect-engine-port.h" -#include "detect-engine-mpm.h" -#include "detect-engine-hcbd.h" -#include "detect-engine-iponly.h" -#include "detect-engine-tag.h" - -#include "detect-engine-uri.h" -#include "detect-engine-hcbd.h" -#include "detect-engine-hsbd.h" -#include "detect-engine-hhd.h" -#include "detect-engine-hrhd.h" -#include "detect-engine-hmd.h" -#include "detect-engine-hcd.h" -#include "detect-engine-hrud.h" -#include "detect-engine-hrl.h" -#include "detect-engine-hsmd.h" -#include "detect-engine-hscd.h" -#include "detect-engine-hua.h" -#include "detect-engine-hhhd.h" -#include "detect-engine-hrhhd.h" -#include "detect-engine-file.h" -#include "detect-engine-dns.h" -#include "detect-engine-modbus.h" -#include "detect-engine-filedata-smtp.h" -#include "detect-engine-template.h" - -#include "detect-engine.h" -#include "detect-engine-state.h" - -#include "detect-byte-extract.h" -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-engine-threshold.h" - -#include "detect-engine-loader.h" - -#include "util-classification-config.h" -#include "util-reference-config.h" -#include "util-threshold-config.h" -#include "util-error.h" -#include "util-hash.h" -#include "util-byte.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-action.h" -#include "util-magic.h" -#include "util-signal.h" - -#include "util-var-name.h" - -#include "tm-threads.h" -#include "runmodes.h" - -#ifdef PROFILING -#include "util-profiling.h" -#endif - -#include "reputation.h" - -#define DETECT_ENGINE_DEFAULT_INSPECTION_RECURSION_LIMIT 3000 - -static uint32_t detect_engine_ctx_id = 1; - -static DetectEngineThreadCtx *DetectEngineThreadCtxInitForReload( - ThreadVars *tv, DetectEngineCtx *new_de_ctx, int mt); - -static uint8_t DetectEngineCtxLoadConf(DetectEngineCtx *); - -static DetectEngineMasterCtx g_master_de_ctx = { SCMUTEX_INITIALIZER, 0, NULL, NULL, TENANT_SELECTOR_UNKNOWN, NULL,}; - -static uint32_t TenantIdHash(HashTable *h, void *data, uint16_t data_len); -static char TenantIdCompare(void *d1, uint16_t d1_len, void *d2, uint16_t d2_len); -static void TenantIdFree(void *d); -static uint32_t DetectEngineTentantGetIdFromVlanId(const void *ctx, const Packet *p); -static uint32_t DetectEngineTentantGetIdFromPcap(const void *ctx, const Packet *p); - -/* 2 - for each direction */ -DetectEngineAppInspectionEngine *app_inspection_engine[FLOW_PROTO_DEFAULT][ALPROTO_MAX][2]; - -#if 0 - -static void DetectEnginePrintAppInspectionEngines(DetectEngineAppInspectionEngine *list[][ALPROTO_MAX][2]) -{ - printf("\n"); - - AppProto alproto = ALPROTO_UNKNOWN + 1; - for ( ; alproto < ALPROTO_MAX; alproto++) { - printf("alproto - %d\n", alproto); - int dir = 0; - for ( ; dir < 2; dir++) { - printf(" direction - %d\n", dir); - DetectEngineAppInspectionEngine *engine = list[alproto][dir]; - while (engine != NULL) { - printf(" engine->alproto - %"PRIu16"\n", engine->alproto); - printf(" engine->dir - %"PRIu16"\n", engine->dir); - printf(" engine->sm_list - %d\n", engine->sm_list); - printf(" engine->inspect_flags - %"PRIu32"\n", engine->inspect_flags); - printf(" engine->match_flags - %"PRIu32"\n", engine->match_flags); - printf("\n"); - - engine = engine->next; - } - } /* for ( ; dir < 2; dir++) */ - } /* for ( ; alproto < ALPROTO_MAX; alproto++) */ - - return; -} - -#endif - -void DetectEngineRegisterAppInspectionEngines(void) -{ - struct tmp_t { - uint8_t ipproto; - AppProto alproto; - int32_t sm_list; - uint32_t inspect_flags; - uint16_t dir; - int (*Callback)(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *sig, Flow *f, - uint8_t flags, void *alstate, - void *tx, uint64_t tx_id); - - }; - - struct tmp_t data_toserver[] = { - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_UMATCH, - DE_STATE_FLAG_URI_INSPECT, - 0, - DetectEngineInspectPacketUris }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HRLMATCH, - DE_STATE_FLAG_HRL_INSPECT, - 0, - DetectEngineInspectHttpRequestLine }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HCBDMATCH, - DE_STATE_FLAG_HCBD_INSPECT, - 0, - DetectEngineInspectHttpClientBody }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HHDMATCH, - DE_STATE_FLAG_HHD_INSPECT, - 0, - DetectEngineInspectHttpHeader }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HRHDMATCH, - DE_STATE_FLAG_HRHD_INSPECT, - 0, - DetectEngineInspectHttpRawHeader }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HMDMATCH, - DE_STATE_FLAG_HMD_INSPECT, - 0, - DetectEngineInspectHttpMethod }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HCDMATCH, - DE_STATE_FLAG_HCD_INSPECT, - 0, - DetectEngineInspectHttpCookie }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HRUDMATCH, - DE_STATE_FLAG_HRUD_INSPECT, - 0, - DetectEngineInspectHttpRawUri }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_FILEMATCH, - DE_STATE_FLAG_FILE_TS_INSPECT, - 0, - DetectFileInspectHttp }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HUADMATCH, - DE_STATE_FLAG_HUAD_INSPECT, - 0, - DetectEngineInspectHttpUA }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HHHDMATCH, - DE_STATE_FLAG_HHHD_INSPECT, - 0, - DetectEngineInspectHttpHH }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HRHHDMATCH, - DE_STATE_FLAG_HRHHD_INSPECT, - 0, - DetectEngineInspectHttpHRH }, - /* DNS */ - { IPPROTO_TCP, - ALPROTO_DNS, - DETECT_SM_LIST_DNSQUERYNAME_MATCH, - DE_STATE_FLAG_DNSQUERYNAME_INSPECT, - 0, - DetectEngineInspectDnsQueryName }, - /* specifically for UDP, register again - * allows us to use the alproto w/o translation - * in the detection engine */ - { IPPROTO_UDP, - ALPROTO_DNS, - DETECT_SM_LIST_DNSQUERYNAME_MATCH, - DE_STATE_FLAG_DNSQUERYNAME_INSPECT, - 0, - DetectEngineInspectDnsQueryName }, - { IPPROTO_TCP, - ALPROTO_DNS, - DETECT_SM_LIST_DNSREQUEST_MATCH, - DE_STATE_FLAG_DNSREQUEST_INSPECT, - 0, - DetectEngineInspectDnsRequest }, - /* specifically for UDP, register again - * allows us to use the alproto w/o translation - * in the detection engine */ - { IPPROTO_UDP, - ALPROTO_DNS, - DETECT_SM_LIST_DNSREQUEST_MATCH, - DE_STATE_FLAG_DNSREQUEST_INSPECT, - 0, - DetectEngineInspectDnsRequest }, - /* SMTP */ - { IPPROTO_TCP, - ALPROTO_SMTP, - DETECT_SM_LIST_FILEMATCH, - DE_STATE_FLAG_FILE_TS_INSPECT, - 0, - DetectFileInspectSmtp }, - /* Modbus */ - { IPPROTO_TCP, - ALPROTO_MODBUS, - DETECT_SM_LIST_MODBUS_MATCH, - DE_STATE_FLAG_MODBUS_INSPECT, - 0, - DetectEngineInspectModbus }, - /* file_data smtp */ - { IPPROTO_TCP, - ALPROTO_SMTP, - DETECT_SM_LIST_FILEDATA, - DE_STATE_FLAG_FD_SMTP_INSPECT, - 0, - DetectEngineInspectSMTPFiledata }, - /* Template. */ - { IPPROTO_TCP, - ALPROTO_TEMPLATE, - DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH, - DE_STATE_FLAG_TEMPLATE_BUFFER_INSPECT, - 0, - DetectEngineInspectTemplateBuffer }, - }; - - struct tmp_t data_toclient[] = { - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_FILEDATA, - DE_STATE_FLAG_HSBD_INSPECT, - 1, - DetectEngineInspectHttpServerBody }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HHDMATCH, - DE_STATE_FLAG_HHD_INSPECT, - 1, - DetectEngineInspectHttpHeader }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HRHDMATCH, - DE_STATE_FLAG_HRHD_INSPECT, - 1, - DetectEngineInspectHttpRawHeader }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HCDMATCH, - DE_STATE_FLAG_HCD_INSPECT, - 1, - DetectEngineInspectHttpCookie }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_FILEMATCH, - DE_STATE_FLAG_FILE_TC_INSPECT, - 1, - DetectFileInspectHttp }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HSMDMATCH, - DE_STATE_FLAG_HSMD_INSPECT, - 1, - DetectEngineInspectHttpStatMsg }, - { IPPROTO_TCP, - ALPROTO_HTTP, - DETECT_SM_LIST_HSCDMATCH, - DE_STATE_FLAG_HSCD_INSPECT, - 1, - DetectEngineInspectHttpStatCode }, - /* Modbus */ - { IPPROTO_TCP, - ALPROTO_MODBUS, - DETECT_SM_LIST_MODBUS_MATCH, - DE_STATE_FLAG_MODBUS_INSPECT, - 0, - DetectEngineInspectModbus }, - { IPPROTO_TCP, - ALPROTO_DNS, - DETECT_SM_LIST_DNSRESPONSE_MATCH, - DE_STATE_FLAG_DNSRESPONSE_INSPECT, - 1, - DetectEngineInspectDnsResponse }, - /* specifically for UDP, register again - * allows us to use the alproto w/o translation - * in the detection engine */ - { IPPROTO_UDP, - ALPROTO_DNS, - DETECT_SM_LIST_DNSRESPONSE_MATCH, - DE_STATE_FLAG_DNSRESPONSE_INSPECT, - 1, - DetectEngineInspectDnsResponse }, - /* Template. */ - { IPPROTO_TCP, - ALPROTO_TEMPLATE, - DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH, - DE_STATE_FLAG_TEMPLATE_BUFFER_INSPECT, - 1, - DetectEngineInspectTemplateBuffer }, - }; - - size_t i; - for (i = 0 ; i < sizeof(data_toserver) / sizeof(struct tmp_t); i++) { - DetectEngineRegisterAppInspectionEngine(data_toserver[i].ipproto, - data_toserver[i].alproto, - data_toserver[i].dir, - data_toserver[i].sm_list, - data_toserver[i].inspect_flags, - data_toserver[i].Callback, - app_inspection_engine); - } - - for (i = 0 ; i < sizeof(data_toclient) / sizeof(struct tmp_t); i++) { - DetectEngineRegisterAppInspectionEngine(data_toclient[i].ipproto, - data_toclient[i].alproto, - data_toclient[i].dir, - data_toclient[i].sm_list, - data_toclient[i].inspect_flags, - data_toclient[i].Callback, - app_inspection_engine); - } - -#if 0 - DetectEnginePrintAppInspectionEngines(app_inspection_engine); -#endif - - return; -} - -static void AppendAppInspectionEngine(DetectEngineAppInspectionEngine *engine, - DetectEngineAppInspectionEngine *list[][ALPROTO_MAX][2]) -{ - /* append to the list */ - DetectEngineAppInspectionEngine *tmp = list[FlowGetProtoMapping(engine->ipproto)][engine->alproto][engine->dir]; - DetectEngineAppInspectionEngine *insert = NULL; - while (tmp != NULL) { - if (tmp->dir == engine->dir && - (tmp->sm_list == engine->sm_list || - tmp->inspect_flags == engine->inspect_flags - )) { - SCLogError(SC_ERR_DETECT_PREPARE, "App Inspection Engine already " - "registered for this direction(%"PRIu16") ||" - "sm_list(%d) || " - "[inspect(%"PRIu32")]_flags", - tmp->dir, tmp->sm_list, tmp->inspect_flags); - exit(EXIT_FAILURE); - } - insert = tmp; - tmp = tmp->next; - } - if (insert == NULL) - list[FlowGetProtoMapping(engine->ipproto)][engine->alproto][engine->dir] = engine; - else - insert->next = engine; - - return; -} - -void DetectEngineRegisterAppInspectionEngine(uint8_t ipproto, - AppProto alproto, - uint16_t dir, - int32_t sm_list, - uint32_t inspect_flags, - int (*Callback)(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *sig, Flow *f, - uint8_t flags, void *alstate, - void *tx, uint64_t tx_id), - DetectEngineAppInspectionEngine *list[][ALPROTO_MAX][2]) -{ - if ((list == NULL) || - (alproto <= ALPROTO_UNKNOWN || alproto >= ALPROTO_FAILED) || - (dir > 1) || - (sm_list < DETECT_SM_LIST_MATCH || sm_list >= DETECT_SM_LIST_MAX) || - (Callback == NULL)) - { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid arguments"); - exit(EXIT_FAILURE); - } - - DetectEngineAppInspectionEngine *tmp = list[FlowGetProtoMapping(ipproto)][alproto][dir]; - while (tmp != NULL) { - if (tmp->sm_list == sm_list && tmp->Callback == Callback) { - return; - } - tmp = tmp->next; - } - - DetectEngineAppInspectionEngine *new_engine = SCMalloc(sizeof(DetectEngineAppInspectionEngine)); - if (unlikely(new_engine == NULL)) { - exit(EXIT_FAILURE); - } - memset(new_engine, 0, sizeof(*new_engine)); - new_engine->ipproto = ipproto; - new_engine->alproto = alproto; - new_engine->dir = dir; - new_engine->sm_list = sm_list; - new_engine->inspect_flags = inspect_flags; - new_engine->Callback = Callback; - - AppendAppInspectionEngine(new_engine, list); - - return; -} - -/* code to control the main thread to do a reload */ - -enum DetectEngineSyncState { - IDLE, /**< ready to start a reload */ - RELOAD, /**< command main thread to do the reload */ - DONE, /**< main thread telling us reload is done */ -}; - - -typedef struct DetectEngineSyncer_ { - SCMutex m; - enum DetectEngineSyncState state; -} DetectEngineSyncer; - -static DetectEngineSyncer detect_sync = { SCMUTEX_INITIALIZER, IDLE }; - -/* tell main to start reloading */ -int DetectEngineReloadStart(void) -{ - int r = 0; - SCMutexLock(&detect_sync.m); - if (detect_sync.state == IDLE) { - detect_sync.state = RELOAD; - } else { - r = -1; - } - SCMutexUnlock(&detect_sync.m); - return r; -} - -/* main thread checks this to see if it should start */ -int DetectEngineReloadIsStart(void) -{ - int r = 0; - SCMutexLock(&detect_sync.m); - if (detect_sync.state == RELOAD) { - r = 1; - } - SCMutexUnlock(&detect_sync.m); - return r; -} - -/* main thread sets done when it's done */ -void DetectEngineReloadSetDone(void) -{ - SCMutexLock(&detect_sync.m); - detect_sync.state = DONE; - SCMutexUnlock(&detect_sync.m); -} - -/* caller loops this until it returns 1 */ -int DetectEngineReloadIsDone(void) -{ - int r = 0; - SCMutexLock(&detect_sync.m); - if (detect_sync.state == DONE) { - r = 1; - detect_sync.state = IDLE; - } - SCMutexUnlock(&detect_sync.m); - return r; -} - -/** \internal - * \brief Update detect threads with new detect engine - * - * Atomically update each detect thread with a new thread context - * that is associated to the new detection engine(s). - * - * If called in unix socket mode, it's possible that we don't have - * detect threads yet. - * - * \retval -1 error - * \retval 0 no detection threads - * \retval 1 successful reload - */ -static int DetectEngineReloadThreads(DetectEngineCtx *new_de_ctx) -{ - SCEnter(); - int i = 0; - int no_of_detect_tvs = 0; - ThreadVars *tv = NULL; - - /* count detect threads in use */ - SCMutexLock(&tv_root_lock); - tv = tv_root[TVT_PPT]; - while (tv) { - /* obtain the slots for this TV */ - TmSlot *slots = tv->tm_slots; - while (slots != NULL) { - TmModule *tm = TmModuleGetById(slots->tm_id); - - if (suricata_ctl_flags != 0) { - SCLogInfo("rule reload interupted by engine shutdown"); - SCMutexUnlock(&tv_root_lock); - return -1; - } - - if (!(tm->flags & TM_FLAG_DETECT_TM)) { - slots = slots->slot_next; - continue; - } - no_of_detect_tvs++; - break; - } - - tv = tv->next; - } - SCMutexUnlock(&tv_root_lock); - - /* can be zero in unix socket mode */ - if (no_of_detect_tvs == 0) { - return 0; - } - - SCLogNotice("rule reload starting"); - - /* prepare swap structures */ - DetectEngineThreadCtx *old_det_ctx[no_of_detect_tvs]; - DetectEngineThreadCtx *new_det_ctx[no_of_detect_tvs]; - ThreadVars *detect_tvs[no_of_detect_tvs]; - memset(old_det_ctx, 0x00, (no_of_detect_tvs * sizeof(DetectEngineThreadCtx *))); - memset(new_det_ctx, 0x00, (no_of_detect_tvs * sizeof(DetectEngineThreadCtx *))); - memset(detect_tvs, 0x00, (no_of_detect_tvs * sizeof(ThreadVars *))); - - /* start the process of swapping detect threads ctxs */ - - /* get reference to tv's and setup new_det_ctx array */ - SCMutexLock(&tv_root_lock); - tv = tv_root[TVT_PPT]; - while (tv) { - /* obtain the slots for this TV */ - TmSlot *slots = tv->tm_slots; - while (slots != NULL) { - TmModule *tm = TmModuleGetById(slots->tm_id); - - if (suricata_ctl_flags != 0) { - SCMutexUnlock(&tv_root_lock); - goto error; - } - - if (!(tm->flags & TM_FLAG_DETECT_TM)) { - slots = slots->slot_next; - continue; - } - - old_det_ctx[i] = SC_ATOMIC_GET(slots->slot_data); - detect_tvs[i] = tv; - - new_det_ctx[i] = DetectEngineThreadCtxInitForReload(tv, new_de_ctx, 1); - if (new_det_ctx[i] == NULL) { - SCLogError(SC_ERR_LIVE_RULE_SWAP, "Detect engine thread init " - "failure in live rule swap. Let's get out of here"); - SCMutexUnlock(&tv_root_lock); - goto error; - } - SCLogDebug("live rule swap created new det_ctx - %p and de_ctx " - "- %p\n", new_det_ctx[i], new_de_ctx); - i++; - break; - } - - tv = tv->next; - } - BUG_ON(i != no_of_detect_tvs); - - /* atomicly replace the det_ctx data */ - i = 0; - tv = tv_root[TVT_PPT]; - while (tv) { - /* find the correct slot */ - TmSlot *slots = tv->tm_slots; - while (slots != NULL) { - if (suricata_ctl_flags != 0) { - return -1; - } - - TmModule *tm = TmModuleGetById(slots->tm_id); - if (!(tm->flags & TM_FLAG_DETECT_TM)) { - slots = slots->slot_next; - continue; - } - SCLogDebug("swapping new det_ctx - %p with older one - %p", - new_det_ctx[i], SC_ATOMIC_GET(slots->slot_data)); - (void)SC_ATOMIC_SET(slots->slot_data, new_det_ctx[i++]); - break; - } - tv = tv->next; - } - SCMutexUnlock(&tv_root_lock); - - /* threads now all have new data, however they may not have started using - * it and may still use the old data */ - - SCLogInfo("Live rule swap has swapped %d old det_ctx's with new ones, " - "along with the new de_ctx", no_of_detect_tvs); - - /* inject a fake packet if the detect thread isn't using the new ctx yet, - * this speeds up the process */ - for (i = 0; i < no_of_detect_tvs; i++) { - int break_out = 0; - int pseudo_pkt_inserted = 0; - usleep(1000); - while (SC_ATOMIC_GET(new_det_ctx[i]->so_far_used_by_detect) != 1) { - if (suricata_ctl_flags != 0) { - break_out = 1; - break; - } - - if (pseudo_pkt_inserted == 0) { - pseudo_pkt_inserted = 1; - if (detect_tvs[i]->inq != NULL) { - Packet *p = PacketGetFromAlloc(); - if (p != NULL) { - p->flags |= PKT_PSEUDO_STREAM_END; - PacketQueue *q = &trans_q[detect_tvs[i]->inq->id]; - SCMutexLock(&q->mutex_q); - PacketEnqueue(q, p); - SCCondSignal(&q->cond_q); - SCMutexUnlock(&q->mutex_q); - } - } - } - usleep(1000); - } - if (break_out) - break; - SCLogDebug("new_det_ctx - %p used by detect engine", new_det_ctx[i]); - } - - /* this is to make sure that if someone initiated shutdown during a live - * rule swap, the live rule swap won't clean up the old det_ctx and - * de_ctx, till all detect threads have stopped working and sitting - * silently after setting RUNNING_DONE flag and while waiting for - * THV_DEINIT flag */ - if (i != no_of_detect_tvs) { // not all threads we swapped - ThreadVars *tv = tv_root[TVT_PPT]; - while (tv) { - /* obtain the slots for this TV */ - TmSlot *slots = tv->tm_slots; - while (slots != NULL) { - TmModule *tm = TmModuleGetById(slots->tm_id); - if (!(tm->flags & TM_FLAG_DETECT_TM)) { - slots = slots->slot_next; - continue; - } - - while (!TmThreadsCheckFlag(tv, THV_RUNNING_DONE)) { - usleep(100); - } - - slots = slots->slot_next; - } - - tv = tv->next; - } - } - - /* free all the ctxs */ - for (i = 0; i < no_of_detect_tvs; i++) { - SCLogDebug("Freeing old_det_ctx - %p used by detect", - old_det_ctx[i]); - DetectEngineThreadCtxDeinit(NULL, old_det_ctx[i]); - } - - SRepReloadComplete(); - - SCLogNotice("rule reload complete"); - return 1; - - error: - for (i = 0; i < no_of_detect_tvs; i++) { - if (new_det_ctx[i] != NULL) - DetectEngineThreadCtxDeinit(NULL, new_det_ctx[i]); - } - return -1; -} - -static DetectEngineCtx *DetectEngineCtxInitReal(int minimal, const char *prefix) -{ - DetectEngineCtx *de_ctx; - - ConfNode *seq_node = NULL; - ConfNode *insp_recursion_limit_node = NULL; - ConfNode *de_engine_node = NULL; - char *insp_recursion_limit = NULL; - - de_ctx = SCMalloc(sizeof(DetectEngineCtx)); - if (unlikely(de_ctx == NULL)) - goto error; - - memset(de_ctx,0,sizeof(DetectEngineCtx)); - - if (minimal) { - de_ctx->minimal = 1; - de_ctx->id = detect_engine_ctx_id++; - return de_ctx; - } - - if (prefix != NULL) { - strlcpy(de_ctx->config_prefix, prefix, sizeof(de_ctx->config_prefix)); - } - - if (ConfGetBool("engine.init-failure-fatal", (int *)&(de_ctx->failure_fatal)) != 1) { - SCLogDebug("ConfGetBool could not load the value."); - } - - de_engine_node = ConfGetNode("detect-engine"); - if (de_engine_node != NULL) { - TAILQ_FOREACH(seq_node, &de_engine_node->head, next) { - if (strcmp(seq_node->val, "inspection-recursion-limit") != 0) - continue; - - insp_recursion_limit_node = ConfNodeLookupChild(seq_node, seq_node->val); - if (insp_recursion_limit_node == NULL) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Error retrieving conf " - "entry for detect-engine:inspection-recursion-limit"); - break; - } - insp_recursion_limit = insp_recursion_limit_node->val; - SCLogDebug("Found detect-engine:inspection-recursion-limit - %s:%s", - insp_recursion_limit_node->name, insp_recursion_limit_node->val); - - break; - } - } - - if (insp_recursion_limit != NULL) { - de_ctx->inspection_recursion_limit = atoi(insp_recursion_limit); - } else { - de_ctx->inspection_recursion_limit = - DETECT_ENGINE_DEFAULT_INSPECTION_RECURSION_LIMIT; - } - - if (de_ctx->inspection_recursion_limit == 0) - de_ctx->inspection_recursion_limit = -1; - - SCLogDebug("de_ctx->inspection_recursion_limit: %d", - de_ctx->inspection_recursion_limit); - - de_ctx->mpm_matcher = PatternMatchDefaultMatcher(); - DetectEngineCtxLoadConf(de_ctx); - - SigGroupHeadHashInit(de_ctx); - SigGroupHeadMpmHashInit(de_ctx); - SigGroupHeadMpmUriHashInit(de_ctx); - SigGroupHeadSPortHashInit(de_ctx); - SigGroupHeadDPortHashInit(de_ctx); - DetectPortSpHashInit(de_ctx); - DetectPortDpHashInit(de_ctx); - ThresholdHashInit(de_ctx); - VariableNameInitHash(de_ctx); - DetectParseDupSigHashInit(de_ctx); - - de_ctx->mpm_pattern_id_store = MpmPatternIdTableInitHash(); - if (de_ctx->mpm_pattern_id_store == NULL) { - goto error; - } - - /* init iprep... ignore errors for now */ - (void)SRepInit(de_ctx); - -#ifdef PROFILING - SCProfilingKeywordInitCounters(de_ctx); -#endif - - SCClassConfLoadClassficationConfigFile(de_ctx, NULL); - SCRConfLoadReferenceConfigFile(de_ctx, NULL); - - if (ActionInitConfig() < 0) { - goto error; - } - - de_ctx->id = detect_engine_ctx_id++; - return de_ctx; -error: - return NULL; - -} - -DetectEngineCtx *DetectEngineCtxInitMinimal(void) -{ - return DetectEngineCtxInitReal(1, NULL); -} - -DetectEngineCtx *DetectEngineCtxInit(void) -{ - return DetectEngineCtxInitReal(0, NULL); -} - -DetectEngineCtx *DetectEngineCtxInitWithPrefix(const char *prefix) -{ - if (prefix == NULL || strlen(prefix) == 0) - return DetectEngineCtxInit(); - else - return DetectEngineCtxInitReal(0, prefix); -} - -static void DetectEngineCtxFreeThreadKeywordData(DetectEngineCtx *de_ctx) -{ - DetectEngineThreadKeywordCtxItem *item = de_ctx->keyword_list; - while (item) { - DetectEngineThreadKeywordCtxItem *next = item->next; - SCFree(item); - item = next; - } - de_ctx->keyword_list = NULL; -} - -/** - * \brief Free a DetectEngineCtx:: - * - * \param de_ctx DetectEngineCtx:: to be freed - */ -void DetectEngineCtxFree(DetectEngineCtx *de_ctx) -{ - - if (de_ctx == NULL) - return; - -#ifdef PROFILING - if (de_ctx->profile_ctx != NULL) { - SCProfilingRuleDestroyCtx(de_ctx->profile_ctx); - de_ctx->profile_ctx = NULL; - } - if (de_ctx->profile_keyword_ctx != NULL) { - SCProfilingKeywordDestroyCtx(de_ctx);//->profile_keyword_ctx); -// de_ctx->profile_keyword_ctx = NULL; - } -#endif - - /* Normally the hashes are freed elsewhere, but - * to be sure look at them again here. - */ - MpmPatternIdTableFreeHash(de_ctx->mpm_pattern_id_store); /* normally cleaned up in SigGroupBuild */ - - SigGroupHeadHashFree(de_ctx); - SigGroupHeadMpmHashFree(de_ctx); - SigGroupHeadMpmUriHashFree(de_ctx); - SigGroupHeadSPortHashFree(de_ctx); - SigGroupHeadDPortHashFree(de_ctx); - DetectParseDupSigHashFree(de_ctx); - SCSigSignatureOrderingModuleCleanup(de_ctx); - DetectPortSpHashFree(de_ctx); - DetectPortDpHashFree(de_ctx); - ThresholdContextDestroy(de_ctx); - SigCleanSignatures(de_ctx); - - VariableNameFreeHash(de_ctx); - if (de_ctx->sig_array) - SCFree(de_ctx->sig_array); - - SCClassConfDeInitContext(de_ctx); - SCRConfDeInitContext(de_ctx); - - SigGroupCleanup(de_ctx); - - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - MpmFactoryDeRegisterAllMpmCtxProfiles(de_ctx); - } - - DetectEngineCtxFreeThreadKeywordData(de_ctx); - SRepDestroy(de_ctx); - - /* if we have a config prefix, remove the config from the tree */ - if (strlen(de_ctx->config_prefix) > 0) { - /* remove config */ - ConfNode *node = ConfGetNode(de_ctx->config_prefix); - if (node != NULL) { - ConfNodeRemove(node); /* frees node */ - } -#if 0 - ConfDump(); -#endif - } - - SCFree(de_ctx); - //DetectAddressGroupPrintMemory(); - //DetectSigGroupPrintMemory(); - //DetectPortPrintMemory(); -} - -/** \brief Function that load DetectEngineCtx config for grouping sigs - * used by the engine - * \retval 0 if no config provided, 1 if config was provided - * and loaded successfuly - */ -static uint8_t DetectEngineCtxLoadConf(DetectEngineCtx *de_ctx) -{ - uint8_t profile = ENGINE_PROFILE_UNKNOWN; - char *de_ctx_profile = NULL; - - const char *max_uniq_toclient_src_groups_str = NULL; - const char *max_uniq_toclient_dst_groups_str = NULL; - const char *max_uniq_toclient_sp_groups_str = NULL; - const char *max_uniq_toclient_dp_groups_str = NULL; - - const char *max_uniq_toserver_src_groups_str = NULL; - const char *max_uniq_toserver_dst_groups_str = NULL; - const char *max_uniq_toserver_sp_groups_str = NULL; - const char *max_uniq_toserver_dp_groups_str = NULL; - - char *sgh_mpm_context = NULL; - - ConfNode *de_ctx_custom = ConfGetNode("detect-engine"); - ConfNode *opt = NULL; - - if (de_ctx_custom != NULL) { - TAILQ_FOREACH(opt, &de_ctx_custom->head, next) { - if (strcmp(opt->val, "profile") == 0) { - de_ctx_profile = opt->head.tqh_first->val; - } else if (strcmp(opt->val, "sgh-mpm-context") == 0) { - sgh_mpm_context = opt->head.tqh_first->val; - } - } - } - - if (de_ctx_profile != NULL) { - if (strcmp(de_ctx_profile, "low") == 0) { - profile = ENGINE_PROFILE_LOW; - } else if (strcmp(de_ctx_profile, "medium") == 0) { - profile = ENGINE_PROFILE_MEDIUM; - } else if (strcmp(de_ctx_profile, "high") == 0) { - profile = ENGINE_PROFILE_HIGH; - } else if (strcmp(de_ctx_profile, "custom") == 0) { - profile = ENGINE_PROFILE_CUSTOM; - } - - SCLogDebug("Profile for detection engine groups is \"%s\"", de_ctx_profile); - } else { - SCLogDebug("Profile for detection engine groups not provided " - "at suricata.yaml. Using default (\"medium\")."); - } - - /* detect-engine.sgh-mpm-context option parsing */ - if (sgh_mpm_context == NULL || strcmp(sgh_mpm_context, "auto") == 0) { - /* for now, since we still haven't implemented any intelligence into - * understanding the patterns and distributing mpm_ctx across sgh */ - if (de_ctx->mpm_matcher == DEFAULT_MPM || de_ctx->mpm_matcher == MPM_AC_GFBS || -#ifdef __SC_CUDA_SUPPORT__ - de_ctx->mpm_matcher == MPM_AC_BS || de_ctx->mpm_matcher == MPM_AC_CUDA) { -#else - de_ctx->mpm_matcher == MPM_AC_BS) { -#endif - de_ctx->sgh_mpm_context = ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE; - } else { - de_ctx->sgh_mpm_context = ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL; - } - } else { - if (strcmp(sgh_mpm_context, "single") == 0) { - de_ctx->sgh_mpm_context = ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE; - } else if (strcmp(sgh_mpm_context, "full") == 0) { -#ifdef __SC_CUDA_SUPPORT__ - if (de_ctx->mpm_matcher == MPM_AC_CUDA) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "You can't use " - "the cuda version of our mpm ac, i.e. \"ac-cuda\" " - "along with \"full\" \"sgh-mpm-context\". " - "Allowed values are \"single\" and \"auto\"."); - exit(EXIT_FAILURE); - } -#endif - de_ctx->sgh_mpm_context = ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL; - } else { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "You have supplied an " - "invalid conf value for detect-engine.sgh-mpm-context-" - "%s", sgh_mpm_context); - exit(EXIT_FAILURE); - } - } - - if (run_mode == RUNMODE_UNITTEST) { - de_ctx->sgh_mpm_context = ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL; - } - - opt = NULL; - switch (profile) { - case ENGINE_PROFILE_LOW: - de_ctx->max_uniq_toclient_src_groups = 2; - de_ctx->max_uniq_toclient_dst_groups = 2; - de_ctx->max_uniq_toclient_sp_groups = 2; - de_ctx->max_uniq_toclient_dp_groups = 3; - de_ctx->max_uniq_toserver_src_groups = 2; - de_ctx->max_uniq_toserver_dst_groups = 2; - de_ctx->max_uniq_toserver_sp_groups = 2; - de_ctx->max_uniq_toserver_dp_groups = 3; - break; - - case ENGINE_PROFILE_HIGH: - de_ctx->max_uniq_toclient_src_groups = 15; - de_ctx->max_uniq_toclient_dst_groups = 15; - de_ctx->max_uniq_toclient_sp_groups = 15; - de_ctx->max_uniq_toclient_dp_groups = 20; - de_ctx->max_uniq_toserver_src_groups = 15; - de_ctx->max_uniq_toserver_dst_groups = 15; - de_ctx->max_uniq_toserver_sp_groups = 15; - de_ctx->max_uniq_toserver_dp_groups = 40; - break; - - case ENGINE_PROFILE_CUSTOM: - TAILQ_FOREACH(opt, &de_ctx_custom->head, next) { - if (strcmp(opt->val, "custom-values") == 0) { - max_uniq_toclient_src_groups_str = ConfNodeLookupChildValue - (opt->head.tqh_first, "toclient-src-groups"); - max_uniq_toclient_dst_groups_str = ConfNodeLookupChildValue - (opt->head.tqh_first, "toclient-dst-groups"); - max_uniq_toclient_sp_groups_str = ConfNodeLookupChildValue - (opt->head.tqh_first, "toclient-sp-groups"); - max_uniq_toclient_dp_groups_str = ConfNodeLookupChildValue - (opt->head.tqh_first, "toclient-dp-groups"); - max_uniq_toserver_src_groups_str = ConfNodeLookupChildValue - (opt->head.tqh_first, "toserver-src-groups"); - max_uniq_toserver_dst_groups_str = ConfNodeLookupChildValue - (opt->head.tqh_first, "toserver-dst-groups"); - max_uniq_toserver_sp_groups_str = ConfNodeLookupChildValue - (opt->head.tqh_first, "toserver-sp-groups"); - max_uniq_toserver_dp_groups_str = ConfNodeLookupChildValue - (opt->head.tqh_first, "toserver-dp-groups"); - } - } - if (max_uniq_toclient_src_groups_str != NULL) { - if (ByteExtractStringUint16(&de_ctx->max_uniq_toclient_src_groups, 10, - strlen(max_uniq_toclient_src_groups_str), - (const char *)max_uniq_toclient_src_groups_str) <= 0) { - de_ctx->max_uniq_toclient_src_groups = 4; - SCLogWarning(SC_ERR_SIZE_PARSE, "parsing '%s' for " - "toclient-src-groups failed, using %u", - max_uniq_toclient_src_groups_str, - de_ctx->max_uniq_toclient_src_groups); - } - } else { - de_ctx->max_uniq_toclient_src_groups = 4; - } - if (max_uniq_toclient_dst_groups_str != NULL) { - if (ByteExtractStringUint16(&de_ctx->max_uniq_toclient_dst_groups, 10, - strlen(max_uniq_toclient_dst_groups_str), - (const char *)max_uniq_toclient_dst_groups_str) <= 0) { - de_ctx->max_uniq_toclient_dst_groups = 4; - SCLogWarning(SC_ERR_SIZE_PARSE, "parsing '%s' for " - "toclient-dst-groups failed, using %u", - max_uniq_toclient_dst_groups_str, - de_ctx->max_uniq_toclient_dst_groups); - } - } else { - de_ctx->max_uniq_toclient_dst_groups = 4; - } - if (max_uniq_toclient_sp_groups_str != NULL) { - if (ByteExtractStringUint16(&de_ctx->max_uniq_toclient_sp_groups, 10, - strlen(max_uniq_toclient_sp_groups_str), - (const char *)max_uniq_toclient_sp_groups_str) <= 0) { - de_ctx->max_uniq_toclient_sp_groups = 4; - SCLogWarning(SC_ERR_SIZE_PARSE, "parsing '%s' for " - "toclient-sp-groups failed, using %u", - max_uniq_toclient_sp_groups_str, - de_ctx->max_uniq_toclient_sp_groups); - } - } else { - de_ctx->max_uniq_toclient_sp_groups = 4; - } - if (max_uniq_toclient_dp_groups_str != NULL) { - if (ByteExtractStringUint16(&de_ctx->max_uniq_toclient_dp_groups, 10, - strlen(max_uniq_toclient_dp_groups_str), - (const char *)max_uniq_toclient_dp_groups_str) <= 0) { - de_ctx->max_uniq_toclient_dp_groups = 6; - SCLogWarning(SC_ERR_SIZE_PARSE, "parsing '%s' for " - "toclient-dp-groups failed, using %u", - max_uniq_toclient_dp_groups_str, - de_ctx->max_uniq_toclient_dp_groups); - } - } else { - de_ctx->max_uniq_toclient_dp_groups = 6; - } - if (max_uniq_toserver_src_groups_str != NULL) { - if (ByteExtractStringUint16(&de_ctx->max_uniq_toserver_src_groups, 10, - strlen(max_uniq_toserver_src_groups_str), - (const char *)max_uniq_toserver_src_groups_str) <= 0) { - de_ctx->max_uniq_toserver_src_groups = 4; - SCLogWarning(SC_ERR_SIZE_PARSE, "parsing '%s' for " - "toserver-src-groups failed, using %u", - max_uniq_toserver_src_groups_str, - de_ctx->max_uniq_toserver_src_groups); - } - } else { - de_ctx->max_uniq_toserver_src_groups = 4; - } - if (max_uniq_toserver_dst_groups_str != NULL) { - if (ByteExtractStringUint16(&de_ctx->max_uniq_toserver_dst_groups, 10, - strlen(max_uniq_toserver_dst_groups_str), - (const char *)max_uniq_toserver_dst_groups_str) <= 0) { - de_ctx->max_uniq_toserver_dst_groups = 8; - SCLogWarning(SC_ERR_SIZE_PARSE, "parsing '%s' for " - "toserver-dst-groups failed, using %u", - max_uniq_toserver_dst_groups_str, - de_ctx->max_uniq_toserver_dst_groups); - } - } else { - de_ctx->max_uniq_toserver_dst_groups = 8; - } - if (max_uniq_toserver_sp_groups_str != NULL) { - if (ByteExtractStringUint16(&de_ctx->max_uniq_toserver_sp_groups, 10, - strlen(max_uniq_toserver_sp_groups_str), - (const char *)max_uniq_toserver_sp_groups_str) <= 0) { - de_ctx->max_uniq_toserver_sp_groups = 4; - SCLogWarning(SC_ERR_SIZE_PARSE, "parsing '%s' for " - "toserver-sp-groups failed, using %u", - max_uniq_toserver_sp_groups_str, - de_ctx->max_uniq_toserver_sp_groups); - } - } else { - de_ctx->max_uniq_toserver_sp_groups = 4; - } - if (max_uniq_toserver_dp_groups_str != NULL) { - if (ByteExtractStringUint16(&de_ctx->max_uniq_toserver_dp_groups, 10, - strlen(max_uniq_toserver_dp_groups_str), - (const char *)max_uniq_toserver_dp_groups_str) <= 0) { - de_ctx->max_uniq_toserver_dp_groups = 30; - SCLogWarning(SC_ERR_SIZE_PARSE, "parsing '%s' for " - "toserver-dp-groups failed, using %u", - max_uniq_toserver_dp_groups_str, - de_ctx->max_uniq_toserver_dp_groups); - } - } else { - de_ctx->max_uniq_toserver_dp_groups = 30; - } - break; - - /* Default (or no config provided) is profile medium */ - case ENGINE_PROFILE_MEDIUM: - case ENGINE_PROFILE_UNKNOWN: - default: - de_ctx->max_uniq_toclient_src_groups = 4; - de_ctx->max_uniq_toclient_dst_groups = 4; - de_ctx->max_uniq_toclient_sp_groups = 4; - de_ctx->max_uniq_toclient_dp_groups = 6; - - de_ctx->max_uniq_toserver_src_groups = 4; - de_ctx->max_uniq_toserver_dst_groups = 8; - de_ctx->max_uniq_toserver_sp_groups = 4; - de_ctx->max_uniq_toserver_dp_groups = 30; - break; - } - - if (profile == ENGINE_PROFILE_UNKNOWN) - return 0; - return 1; -} - -/* - * getting & (re)setting the internal sig i - */ - -//inline uint32_t DetectEngineGetMaxSigId(DetectEngineCtx *de_ctx) -//{ -// return de_ctx->signum; -//} - -void DetectEngineResetMaxSigId(DetectEngineCtx *de_ctx) -{ - de_ctx->signum = 0; -} - -static int DetectEngineThreadCtxInitKeywords(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx) -{ - if (de_ctx->keyword_id > 0) { - det_ctx->keyword_ctxs_array = SCMalloc(de_ctx->keyword_id * sizeof(void *)); - if (det_ctx->keyword_ctxs_array == NULL) { - SCLogError(SC_ERR_DETECT_PREPARE, "setting up thread local detect ctx"); - return TM_ECODE_FAILED; - } - - memset(det_ctx->keyword_ctxs_array, 0x00, de_ctx->keyword_id * sizeof(void *)); - - det_ctx->keyword_ctxs_size = de_ctx->keyword_id; - - DetectEngineThreadKeywordCtxItem *item = de_ctx->keyword_list; - while (item) { - det_ctx->keyword_ctxs_array[item->id] = item->InitFunc(item->data); - if (det_ctx->keyword_ctxs_array[item->id] == NULL) { - SCLogError(SC_ERR_DETECT_PREPARE, "setting up thread local detect ctx " - "for keyword \"%s\" failed", item->name); - return TM_ECODE_FAILED; - } - item = item->next; - } - } - return TM_ECODE_OK; -} - -static void DetectEngineThreadCtxDeinitKeywords(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx) -{ - if (de_ctx->keyword_id > 0) { - DetectEngineThreadKeywordCtxItem *item = de_ctx->keyword_list; - while (item) { - if (det_ctx->keyword_ctxs_array[item->id] != NULL) - item->FreeFunc(det_ctx->keyword_ctxs_array[item->id]); - - item = item->next; - } - det_ctx->keyword_ctxs_size = 0; - SCFree(det_ctx->keyword_ctxs_array); - det_ctx->keyword_ctxs_array = NULL; - } -} - -/** NOTE: master MUST be locked before calling this */ -static TmEcode DetectEngineThreadCtxInitForMT(ThreadVars *tv, DetectEngineThreadCtx *det_ctx) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - DetectEngineTenantMapping *map_array = NULL; - uint32_t map_array_size = 0; - uint32_t map_cnt = 0; - int max_tenant_id = 0; - DetectEngineCtx *list = master->list; - HashTable *mt_det_ctxs_hash = NULL; - - if (master->tenant_selector == TENANT_SELECTOR_UNKNOWN) { - SCLogError(SC_ERR_MT_NO_SELECTOR, "no tenant selector set: " - "set using multi-detect.selector"); - return TM_ECODE_FAILED; - } - - uint32_t tcnt = 0; - while (list) { - if (list->tenant_id > max_tenant_id) - max_tenant_id = list->tenant_id; - - list = list->next; - tcnt++; - } - - mt_det_ctxs_hash = HashTableInit(tcnt * 2, TenantIdHash, TenantIdCompare, TenantIdFree); - if (mt_det_ctxs_hash == NULL) { - goto error; - } - - if (max_tenant_id == 0) { - SCLogInfo("no tenants left, or none registered yet"); - } else { - max_tenant_id++; - - DetectEngineTenantMapping *map = master->tenant_mapping_list; - while (map) { - map_cnt++; - map = map->next; - } - - if (map_cnt > 0) { - map_array_size = map_cnt + 1; - - map_array = SCCalloc(map_array_size, sizeof(*map_array)); - if (map_array == NULL) - goto error; - - /* fill the array */ - map_cnt = 0; - map = master->tenant_mapping_list; - while (map) { - BUG_ON(map_cnt > map_array_size); - map_array[map_cnt].traffic_id = map->traffic_id; - map_array[map_cnt].tenant_id = map->tenant_id; - map_cnt++; - map = map->next; - } - - } - - /* set up hash for tenant lookup */ - list = master->list; - while (list) { - SCLogInfo("tenant-id %u", list->tenant_id); - if (list->tenant_id != 0) { - DetectEngineThreadCtx *mt_det_ctx = DetectEngineThreadCtxInitForReload(tv, list, 0); - if (mt_det_ctx == NULL) - goto error; - BUG_ON(HashTableAdd(mt_det_ctxs_hash, mt_det_ctx, 0) != 0); - } - list = list->next; - } - } - - det_ctx->mt_det_ctxs_hash = mt_det_ctxs_hash; - mt_det_ctxs_hash = NULL; - - det_ctx->mt_det_ctxs_cnt = max_tenant_id; - - det_ctx->tenant_array = map_array; - det_ctx->tenant_array_size = map_array_size; - - switch (master->tenant_selector) { - case TENANT_SELECTOR_UNKNOWN: - SCLogDebug("TENANT_SELECTOR_UNKNOWN"); - break; - case TENANT_SELECTOR_VLAN: - det_ctx->TenantGetId = DetectEngineTentantGetIdFromVlanId; - SCLogDebug("TENANT_SELECTOR_VLAN"); - break; - case TENANT_SELECTOR_DIRECT: - det_ctx->TenantGetId = DetectEngineTentantGetIdFromPcap; - SCLogDebug("TENANT_SELECTOR_DIRECT"); - break; - } - - return TM_ECODE_OK; -error: - if (map_array != NULL) - SCFree(map_array); - if (mt_det_ctxs_hash != NULL) - HashTableFree(mt_det_ctxs_hash); - - return TM_ECODE_FAILED; -} - -/** \internal - * \brief Helper for DetectThread setup functions - */ -static TmEcode ThreadCtxDoInit (DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx) -{ - int i; - - /** \todo we still depend on the global mpm_ctx here - * - * Initialize the thread pattern match ctx with the max size - * of the content and uricontent id's so our match lookup - * table is always big enough - */ - PatternMatchThreadPrepare(&det_ctx->mtc, de_ctx->mpm_matcher, DetectContentMaxId(de_ctx)); - PatternMatchThreadPrepare(&det_ctx->mtcs, de_ctx->mpm_matcher, DetectContentMaxId(de_ctx)); - PatternMatchThreadPrepare(&det_ctx->mtcu, de_ctx->mpm_matcher, DetectUricontentMaxId(de_ctx)); - - PmqSetup(&det_ctx->pmq, de_ctx->max_fp_id); - for (i = 0; i < DETECT_SMSG_PMQ_NUM; i++) { - PmqSetup(&det_ctx->smsg_pmq[i], de_ctx->max_fp_id); - } - - /* sized to the max of our sgh settings. A max setting of 0 implies that all - * sgh's have: sgh->non_mpm_store_cnt == 0 */ - if (de_ctx->non_mpm_store_cnt_max > 0) { - det_ctx->non_mpm_id_array = SCCalloc(de_ctx->non_mpm_store_cnt_max, sizeof(SigIntId)); - BUG_ON(det_ctx->non_mpm_id_array == NULL); - } - - /* IP-ONLY */ - DetectEngineIPOnlyThreadInit(de_ctx,&det_ctx->io_ctx); - - /* DeState */ - if (de_ctx->sig_array_len > 0) { - det_ctx->de_state_sig_array_len = de_ctx->sig_array_len; - det_ctx->de_state_sig_array = SCMalloc(det_ctx->de_state_sig_array_len * sizeof(uint8_t)); - if (det_ctx->de_state_sig_array == NULL) { - return TM_ECODE_FAILED; - } - memset(det_ctx->de_state_sig_array, 0, - det_ctx->de_state_sig_array_len * sizeof(uint8_t)); - - det_ctx->match_array_len = de_ctx->sig_array_len; - det_ctx->match_array = SCMalloc(det_ctx->match_array_len * sizeof(Signature *)); - if (det_ctx->match_array == NULL) { - return TM_ECODE_FAILED; - } - memset(det_ctx->match_array, 0, - det_ctx->match_array_len * sizeof(Signature *)); - } - - /* byte_extract storage */ - det_ctx->bj_values = SCMalloc(sizeof(*det_ctx->bj_values) * - (de_ctx->byte_extract_max_local_id + 1)); - if (det_ctx->bj_values == NULL) { - return TM_ECODE_FAILED; - } - - /* Allocate space for base64 decoded data. */ - if (de_ctx->base64_decode_max_len) { - det_ctx->base64_decoded = SCMalloc(de_ctx->base64_decode_max_len); - if (det_ctx->base64_decoded == NULL) { - return TM_ECODE_FAILED; - } - det_ctx->base64_decoded_len_max = de_ctx->base64_decode_max_len; - det_ctx->base64_decoded_len = 0; - } - - DetectEngineThreadCtxInitKeywords(de_ctx, det_ctx); -#ifdef PROFILING - SCProfilingRuleThreadSetup(de_ctx->profile_ctx, det_ctx); - SCProfilingKeywordThreadSetup(de_ctx->profile_keyword_ctx, det_ctx); -#endif - SC_ATOMIC_INIT(det_ctx->so_far_used_by_detect); - - return TM_ECODE_OK; -} - -/** \brief initialize thread specific detection engine context - * - * \note there is a special case when using delayed detect. In this case the - * function is called twice per thread. The first time the rules are not - * yet loaded. de_ctx->delayed_detect_initialized will be 0. The 2nd - * time they will be loaded. de_ctx->delayed_detect_initialized will be 1. - * This is needed to do the per thread counter registration before the - * packet runtime starts. In delayed detect mode, the first call will - * return a NULL ptr through the data ptr. - * - * \param tv ThreadVars for this thread - * \param initdata pointer to de_ctx - * \param data[out] pointer to store our thread detection ctx - * - * \retval TM_ECODE_OK if all went well - * \retval TM_ECODE_FAILED on serious erro - */ -TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data) -{ - /* first register the counter. In delayed detect mode we exit right after if the - * rules haven't been loaded yet. */ - uint16_t counter_alerts = StatsRegisterCounter("detect.alert", tv); -#ifdef PROFILING - uint16_t counter_mpm_list = StatsRegisterAvgCounter("detect.mpm_list", tv); - uint16_t counter_nonmpm_list = StatsRegisterAvgCounter("detect.nonmpm_list", tv); - uint16_t counter_fnonmpm_list = StatsRegisterAvgCounter("detect.fnonmpm_list", tv); - uint16_t counter_match_list = StatsRegisterAvgCounter("detect.match_list", tv); -#endif - DetectEngineThreadCtx *det_ctx = SCMalloc(sizeof(DetectEngineThreadCtx)); - if (unlikely(det_ctx == NULL)) - return TM_ECODE_FAILED; - memset(det_ctx, 0, sizeof(DetectEngineThreadCtx)); - - det_ctx->tv = tv; - det_ctx->de_ctx = DetectEngineGetCurrent(); - if (det_ctx->de_ctx == NULL) { -#ifdef UNITTESTS - if (RunmodeIsUnittests()) { - det_ctx->de_ctx = (DetectEngineCtx *)initdata; - } else { - DetectEngineThreadCtxDeinit(tv, det_ctx); - return TM_ECODE_FAILED; - } -#else - DetectEngineThreadCtxDeinit(tv, det_ctx); - return TM_ECODE_FAILED; -#endif - } - - if (det_ctx->de_ctx->minimal == 0) { - if (ThreadCtxDoInit(det_ctx->de_ctx, det_ctx) != TM_ECODE_OK) { - DetectEngineThreadCtxDeinit(tv, det_ctx); - return TM_ECODE_FAILED; - } - } - - /** alert counter setup */ - det_ctx->counter_alerts = counter_alerts; -#ifdef PROFILING - det_ctx->counter_mpm_list = counter_mpm_list; - det_ctx->counter_nonmpm_list = counter_nonmpm_list; - det_ctx->counter_fnonmpm_list = counter_fnonmpm_list; - det_ctx->counter_match_list = counter_match_list; -#endif - - /* pass thread data back to caller */ - *data = (void *)det_ctx; - - if (DetectEngineMultiTenantEnabled()) { - if (DetectEngineThreadCtxInitForMT(tv, det_ctx) != TM_ECODE_OK) - return TM_ECODE_FAILED; - } - - return TM_ECODE_OK; -} - -/** - * \internal - * \brief initialize a det_ctx for reload cases - * \param new_de_ctx the new detection engine - * \param mt flag to indicate if MT should be set up for this det_ctx - * this should only be done for the 'root' det_ctx - * - * \retval det_ctx detection engine thread ctx or NULL in case of error - */ -static DetectEngineThreadCtx *DetectEngineThreadCtxInitForReload( - ThreadVars *tv, DetectEngineCtx *new_de_ctx, int mt) -{ - DetectEngineThreadCtx *det_ctx = SCMalloc(sizeof(DetectEngineThreadCtx)); - if (unlikely(det_ctx == NULL)) - return NULL; - memset(det_ctx, 0, sizeof(DetectEngineThreadCtx)); - - det_ctx->tenant_id = new_de_ctx->tenant_id; - det_ctx->tv = tv; - det_ctx->de_ctx = DetectEngineReference(new_de_ctx); - if (det_ctx->de_ctx == NULL) { - SCFree(det_ctx); - return NULL; - } - - /* most of the init happens here */ - if (ThreadCtxDoInit(det_ctx->de_ctx, det_ctx) != TM_ECODE_OK) { - DetectEngineDeReference(&det_ctx->de_ctx); - SCFree(det_ctx); - return NULL; - } - - /** alert counter setup */ - det_ctx->counter_alerts = StatsRegisterCounter("detect.alert", tv); -#ifdef PROFILING - uint16_t counter_mpm_list = StatsRegisterAvgCounter("detect.mpm_list", tv); - uint16_t counter_nonmpm_list = StatsRegisterAvgCounter("detect.nonmpm_list", tv); - uint16_t counter_fnonmpm_list = StatsRegisterAvgCounter("detect.fnonmpm_list", tv); - uint16_t counter_match_list = StatsRegisterAvgCounter("detect.match_list", tv); - det_ctx->counter_mpm_list = counter_mpm_list; - det_ctx->counter_nonmpm_list = counter_nonmpm_list; - det_ctx->counter_fnonmpm_list = counter_fnonmpm_list; - det_ctx->counter_match_list = counter_match_list; -#endif - - if (mt && DetectEngineMultiTenantEnabled()) { - if (DetectEngineThreadCtxInitForMT(tv, det_ctx) != TM_ECODE_OK) { - DetectEngineDeReference(&det_ctx->de_ctx); - SCFree(det_ctx); - return NULL; - } - } - - return det_ctx; -} - -void DetectEngineThreadCtxFree(DetectEngineThreadCtx *det_ctx) -{ - if (det_ctx->tenant_array != NULL) { - SCFree(det_ctx->tenant_array); - det_ctx->tenant_array = NULL; - } - -#ifdef PROFILING - SCProfilingRuleThreadCleanup(det_ctx); - SCProfilingKeywordThreadCleanup(det_ctx); -#endif - - DetectEngineIPOnlyThreadDeinit(&det_ctx->io_ctx); - - /** \todo get rid of this static */ - if (det_ctx->de_ctx != NULL) { - PatternMatchThreadDestroy(&det_ctx->mtc, det_ctx->de_ctx->mpm_matcher); - PatternMatchThreadDestroy(&det_ctx->mtcs, det_ctx->de_ctx->mpm_matcher); - PatternMatchThreadDestroy(&det_ctx->mtcu, det_ctx->de_ctx->mpm_matcher); - } - - PmqFree(&det_ctx->pmq); - int i; - for (i = 0; i < DETECT_SMSG_PMQ_NUM; i++) { - PmqFree(&det_ctx->smsg_pmq[i]); - } - - if (det_ctx->non_mpm_id_array != NULL) - SCFree(det_ctx->non_mpm_id_array); - - if (det_ctx->de_state_sig_array != NULL) - SCFree(det_ctx->de_state_sig_array); - if (det_ctx->match_array != NULL) - SCFree(det_ctx->match_array); - - if (det_ctx->bj_values != NULL) - SCFree(det_ctx->bj_values); - - /* HHD temp storage */ - for (i = 0; i < det_ctx->hhd_buffers_size; i++) { - if (det_ctx->hhd_buffers[i] != NULL) - SCFree(det_ctx->hhd_buffers[i]); - } - if (det_ctx->hhd_buffers) - SCFree(det_ctx->hhd_buffers); - det_ctx->hhd_buffers = NULL; - if (det_ctx->hhd_buffers_len) - SCFree(det_ctx->hhd_buffers_len); - det_ctx->hhd_buffers_len = NULL; - - /* HSBD */ - if (det_ctx->hsbd != NULL) { - SCLogDebug("det_ctx hsbd %u", det_ctx->hsbd_buffers_size); - for (i = 0; i < det_ctx->hsbd_buffers_size; i++) { - if (det_ctx->hsbd[i].buffer != NULL) { - HTPFree(det_ctx->hsbd[i].buffer, det_ctx->hsbd[i].buffer_size); - } - } - SCFree(det_ctx->hsbd); - } - - /* HSCB */ - if (det_ctx->hcbd != NULL) { - SCLogDebug("det_ctx hcbd %u", det_ctx->hcbd_buffers_size); - for (i = 0; i < det_ctx->hcbd_buffers_size; i++) { - if (det_ctx->hcbd[i].buffer != NULL) - SCFree(det_ctx->hcbd[i].buffer); - SCLogDebug("det_ctx->hcbd[i].buffer_size %u", det_ctx->hcbd[i].buffer_size); - } - SCFree(det_ctx->hcbd); - } - - /* Decoded base64 data. */ - if (det_ctx->base64_decoded != NULL) { - SCFree(det_ctx->base64_decoded); - } - - if (det_ctx->de_ctx != NULL) { - DetectEngineThreadCtxDeinitKeywords(det_ctx->de_ctx, det_ctx); -#ifdef UNITTESTS - if (!RunmodeIsUnittests() || det_ctx->de_ctx->ref_cnt > 0) - DetectEngineDeReference(&det_ctx->de_ctx); -#else - DetectEngineDeReference(&det_ctx->de_ctx); -#endif - } - SCFree(det_ctx); -} - -TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data) -{ - DetectEngineThreadCtx *det_ctx = (DetectEngineThreadCtx *)data; - - if (det_ctx == NULL) { - SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "argument \"data\" NULL"); - return TM_ECODE_OK; - } - - if (det_ctx->mt_det_ctxs_hash != NULL) { - HashTableFree(det_ctx->mt_det_ctxs_hash); - det_ctx->mt_det_ctxs_hash = NULL; - } - DetectEngineThreadCtxFree(det_ctx); - - return TM_ECODE_OK; -} - -void DetectEngineThreadCtxInfo(ThreadVars *t, DetectEngineThreadCtx *det_ctx) -{ - /* XXX */ - PatternMatchThreadPrint(&det_ctx->mtc, det_ctx->de_ctx->mpm_matcher); - PatternMatchThreadPrint(&det_ctx->mtcu, det_ctx->de_ctx->mpm_matcher); -} - -/** \brief Register Thread keyword context Funcs - * - * \param de_ctx detection engine to register in - * \param name keyword name for error printing - * \param InitFunc function ptr - * \param data keyword init data to pass to Func - * \param FreeFunc function ptr - * \param mode 0 normal (ctx per keyword instance) 1 shared (one ctx per det_ct) - * - * \retval id for retrieval of ctx at runtime - * \retval -1 on error - * - * \note make sure "data" remains valid and it free'd elsewhere. It's - * recommended to store it in the keywords global ctx so that - * it's freed when the de_ctx is freed. - */ -int DetectRegisterThreadCtxFuncs(DetectEngineCtx *de_ctx, const char *name, void *(*InitFunc)(void *), void *data, void (*FreeFunc)(void *), int mode) -{ - BUG_ON(de_ctx == NULL || InitFunc == NULL || FreeFunc == NULL || data == NULL); - - if (mode) { - DetectEngineThreadKeywordCtxItem *item = de_ctx->keyword_list; - while (item != NULL) { - if (strcmp(name, item->name) == 0) { - return item->id; - } - - item = item->next; - } - } - - DetectEngineThreadKeywordCtxItem *item = SCMalloc(sizeof(DetectEngineThreadKeywordCtxItem)); - if (unlikely(item == NULL)) - return -1; - memset(item, 0x00, sizeof(DetectEngineThreadKeywordCtxItem)); - - item->InitFunc = InitFunc; - item->FreeFunc = FreeFunc; - item->data = data; - item->name = name; - - item->next = de_ctx->keyword_list; - de_ctx->keyword_list = item; - item->id = de_ctx->keyword_id++; - - return item->id; -} - -/** \brief Retrieve thread local keyword ctx by id - * - * \param det_ctx detection engine thread ctx to retrieve the ctx from - * \param id id of the ctx returned by DetectRegisterThreadCtxInitFunc at - * keyword init. - * - * \retval ctx or NULL on error - */ -void *DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *det_ctx, int id) -{ - if (id < 0 || id > det_ctx->keyword_ctxs_size || det_ctx->keyword_ctxs_array == NULL) - return NULL; - - return det_ctx->keyword_ctxs_array[id]; -} - -/** \brief Check if detection is enabled - * \retval bool true or false */ -int DetectEngineEnabled(void) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - SCMutexLock(&master->lock); - - if (master->list == NULL) { - SCMutexUnlock(&master->lock); - return 0; - } - - SCMutexUnlock(&master->lock); - return 1; -} - -DetectEngineCtx *DetectEngineGetCurrent(void) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - SCMutexLock(&master->lock); - - if (master->list == NULL) { - SCMutexUnlock(&master->lock); - return NULL; - } - - master->list->ref_cnt++; - SCLogDebug("master->list %p ref_cnt %u", master->list, master->list->ref_cnt); - SCMutexUnlock(&master->lock); - return master->list; -} - -DetectEngineCtx *DetectEngineReference(DetectEngineCtx *de_ctx) -{ - if (de_ctx == NULL) - return NULL; - de_ctx->ref_cnt++; - return de_ctx; -} - -/** TODO locking? Not needed if this is a one time setting at startup */ -int DetectEngineMultiTenantEnabled(void) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - return (master->multi_tenant_enabled); -} - -/** \internal - * \brief load a tenant from a yaml file - * - * \param tenant_id the tenant id by which the config is known - * \param filename full path of a yaml file - * \param loader_id id of loader thread or -1 - * - * \retval 0 ok - * \retval -1 failed - */ -static int DetectEngineMultiTenantLoadTenant(uint32_t tenant_id, const char *filename, int loader_id) -{ - DetectEngineCtx *de_ctx = NULL; - char prefix[64]; - - snprintf(prefix, sizeof(prefix), "multi-detect.%d", tenant_id); - -#ifdef OS_WIN32 - struct _stat st; - if(_stat(filename, &st) != 0) { -#else - struct stat st; - if(stat(filename, &st) != 0) { -#endif /* OS_WIN32 */ - SCLogError(SC_ERR_FOPEN, "failed to stat file %s", filename); - goto error; - } - - de_ctx = DetectEngineGetByTenantId(tenant_id); - if (de_ctx != NULL) { - SCLogError(SC_ERR_MT_DUPLICATE_TENANT, "tenant %u already registered", - tenant_id); - DetectEngineDeReference(&de_ctx); - goto error; - } - - ConfNode *node = ConfGetNode(prefix); - if (node == NULL) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "failed to properly setup yaml %s", filename); - goto error; - } - - de_ctx = DetectEngineCtxInitWithPrefix(prefix); - if (de_ctx == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "initializing detection engine " - "context failed."); - goto error; - } - SCLogDebug("de_ctx %p with prefix %s", de_ctx, de_ctx->config_prefix); - - de_ctx->tenant_id = tenant_id; - de_ctx->loader_id = loader_id; - - if (SigLoadSignatures(de_ctx, NULL, 0) < 0) { - SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed."); - goto error; - } - - DetectEngineAddToMaster(de_ctx); - - return 0; - -error: - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - return -1; -} - -static int DetectEngineMultiTenantReloadTenant(uint32_t tenant_id, const char *filename, int reload_cnt) -{ - DetectEngineCtx *old_de_ctx = DetectEngineGetByTenantId(tenant_id); - if (old_de_ctx == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "tenant detect engine not found"); - return -1; - } - - char prefix[64]; - snprintf(prefix, sizeof(prefix), "multi-detect.%d.reload.%d", tenant_id, reload_cnt); - reload_cnt++; - SCLogInfo("prefix %s", prefix); - - if (ConfYamlLoadFileWithPrefix(filename, prefix) != 0) { - SCLogError(SC_ERR_INITIALIZATION,"failed to load yaml"); - goto error; - } - - ConfNode *node = ConfGetNode(prefix); - if (node == NULL) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "failed to properly setup yaml %s", filename); - goto error; - } - - DetectEngineCtx *new_de_ctx = DetectEngineCtxInitWithPrefix(prefix); - if (new_de_ctx == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "initializing detection engine " - "context failed."); - goto error; - } - SCLogDebug("de_ctx %p with prefix %s", new_de_ctx, new_de_ctx->config_prefix); - - new_de_ctx->tenant_id = tenant_id; - new_de_ctx->loader_id = old_de_ctx->loader_id; - - if (SigLoadSignatures(new_de_ctx, NULL, 0) < 0) { - SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed."); - goto error; - } - - DetectEngineAddToMaster(new_de_ctx); - - /* move to free list */ - DetectEngineMoveToFreeList(old_de_ctx); - DetectEngineDeReference(&old_de_ctx); - return 0; - -error: - DetectEngineDeReference(&old_de_ctx); - return -1; -} - - -typedef struct TenantLoaderCtx_ { - uint32_t tenant_id; - int reload_cnt; /**< used by reload */ - const char *yaml; -} TenantLoaderCtx; - -static int DetectLoaderFuncLoadTenant(void *vctx, int loader_id) -{ - TenantLoaderCtx *ctx = (TenantLoaderCtx *)vctx; - - SCLogDebug("loader %d", loader_id); - if (DetectEngineMultiTenantLoadTenant(ctx->tenant_id, ctx->yaml, loader_id) != 0) { - return -1; - } - return 0; -} - -int DetectLoaderSetupLoadTenant(uint32_t tenant_id, const char *yaml) -{ - TenantLoaderCtx *t = SCCalloc(1, sizeof(*t)); - if (t == NULL) - return -ENOMEM; - - t->tenant_id = tenant_id; - t->yaml = yaml; - - return DetectLoaderQueueTask(-1, DetectLoaderFuncLoadTenant, t); -} - -static int DetectLoaderFuncReloadTenant(void *vctx, int loader_id) -{ - TenantLoaderCtx *ctx = (TenantLoaderCtx *)vctx; - - SCLogDebug("loader_id %d", loader_id); - - if (DetectEngineMultiTenantReloadTenant(ctx->tenant_id, ctx->yaml, ctx->reload_cnt) != 0) { - return -1; - } - return 0; -} - -int DetectLoaderSetupReloadTenant(uint32_t tenant_id, const char *yaml, int reload_cnt) -{ - DetectEngineCtx *old_de_ctx = DetectEngineGetByTenantId(tenant_id); - if (old_de_ctx == NULL) - return -ENOENT; - int loader_id = old_de_ctx->loader_id; - DetectEngineDeReference(&old_de_ctx); - - TenantLoaderCtx *t = SCCalloc(1, sizeof(*t)); - if (t == NULL) - return -ENOMEM; - - t->tenant_id = tenant_id; - t->yaml = yaml; - t->reload_cnt = reload_cnt; - - SCLogDebug("loader_id %d", loader_id); - - return DetectLoaderQueueTask(loader_id, DetectLoaderFuncReloadTenant, t); -} - -/** \brief Load a tenant and wait for loading to complete - */ -int DetectEngineLoadTenantBlocking(uint32_t tenant_id, const char *yaml) -{ - int r = DetectLoaderSetupLoadTenant(tenant_id, yaml); - if (r < 0) - return r; - - if (DetectLoadersSync() != 0) - return -1; - - return 0; -} - -/** \brief Reload a tenant and wait for loading to complete - */ -int DetectEngineReloadTenantBlocking(uint32_t tenant_id, const char *yaml, int reload_cnt) -{ - int r = DetectLoaderSetupReloadTenant(tenant_id, yaml, reload_cnt); - if (r < 0) - return r; - - if (DetectLoadersSync() != 0) - return -1; - - return 0; -} - -/** - * \brief setup multi-detect / multi-tenancy - * - * See if MT is enabled. If so, setup the selector, tenants and mappings. - * Tenants and mappings are optional, and can also dynamically be added - * and removed from the unix socket. - */ -int DetectEngineMultiTenantSetup(void) -{ - enum DetectEngineTenantSelectors tenant_selector = TENANT_SELECTOR_UNKNOWN; - DetectEngineMasterCtx *master = &g_master_de_ctx; - - int unix_socket = 0; - (void)ConfGetBool("unix-command.enabled", &unix_socket); - - int failure_fatal = 0; - (void)ConfGetBool("engine.init-failure-fatal", &failure_fatal); - - int enabled = 0; - (void)ConfGetBool("multi-detect.enabled", &enabled); - if (enabled == 1) { - DetectLoadersInit(); - TmModuleDetectLoaderRegister(); - DetectLoaderThreadSpawn(); - TmThreadContinueDetectLoaderThreads(); - - SCMutexLock(&master->lock); - master->multi_tenant_enabled = 1; - - char *handler = NULL; - if (ConfGet("multi-detect.selector", &handler) == 1) { - SCLogInfo("multi-tenant selector type %s", handler); - - if (strcmp(handler, "vlan") == 0) { - tenant_selector = master->tenant_selector = TENANT_SELECTOR_VLAN; - - int vlanbool = 0; - if ((ConfGetBool("vlan.use-for-tracking", &vlanbool)) == 1 && vlanbool == 0) { - SCLogError(SC_ERR_INVALID_VALUE, "vlan tracking is disabled, " - "can't use multi-detect selector 'vlan'"); - SCMutexUnlock(&master->lock); - goto error; - } - - } else if (strcmp(handler, "direct") == 0) { - tenant_selector = master->tenant_selector = TENANT_SELECTOR_DIRECT; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "unknown value %s " - "multi-detect.selector", handler); - SCMutexUnlock(&master->lock); - goto error; - } - } - SCMutexUnlock(&master->lock); - SCLogInfo("multi-detect is enabled (multi tenancy). Selector: %s", handler); - - /* traffic -- tenant mappings */ - ConfNode *mappings_root_node = ConfGetNode("multi-detect.mappings"); - ConfNode *mapping_node = NULL; - - int mapping_cnt = 0; - if (mappings_root_node != NULL) { - TAILQ_FOREACH(mapping_node, &mappings_root_node->head, next) { - ConfNode *tenant_id_node = ConfNodeLookupChild(mapping_node, "tenant-id"); - if (tenant_id_node == NULL) - goto bad_mapping; - ConfNode *vlan_id_node = ConfNodeLookupChild(mapping_node, "vlan-id"); - if (vlan_id_node == NULL) - goto bad_mapping; - - uint32_t tenant_id = 0; - if (ByteExtractStringUint32(&tenant_id, 10, strlen(tenant_id_node->val), - tenant_id_node->val) == -1) - { - SCLogError(SC_ERR_INVALID_ARGUMENT, "tenant-id " - "of %s is invalid", tenant_id_node->val); - goto bad_mapping; - } - - uint16_t vlan_id = 0; - if (ByteExtractStringUint16(&vlan_id, 10, strlen(vlan_id_node->val), - vlan_id_node->val) == -1) - { - SCLogError(SC_ERR_INVALID_ARGUMENT, "vlan-id " - "of %s is invalid", vlan_id_node->val); - goto bad_mapping; - } - if (vlan_id == 0 || vlan_id >= 4095) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "vlan-id " - "of %s is invalid. Valid range 1-4094.", vlan_id_node->val); - goto bad_mapping; - } - - if (DetectEngineTentantRegisterVlanId(tenant_id, (uint32_t)vlan_id) != 0) { - goto error; - } - SCLogInfo("vlan %u connected to tenant-id %u", vlan_id, tenant_id); - mapping_cnt++; - continue; - - bad_mapping: - if (failure_fatal) - goto error; - } - } - - if (tenant_selector == TENANT_SELECTOR_VLAN && mapping_cnt == 0) { - /* no mappings are valid when we're in unix socket mode, - * they can be added on the fly. Otherwise warn/error - * depending on failure_fatal */ - - if (unix_socket) { - SCLogNotice("no tenant traffic mappings defined, " - "tenants won't be used until mappings are added"); - } else { - if (failure_fatal) { - SCLogError(SC_ERR_MT_NO_MAPPING, "no multi-detect mappings defined"); - goto error; - } else { - SCLogWarning(SC_ERR_MT_NO_MAPPING, "no multi-detect mappings defined"); - } - } - } - - /* tenants */ - ConfNode *tenants_root_node = ConfGetNode("multi-detect.tenants"); - ConfNode *tenant_node = NULL; - - if (tenants_root_node != NULL) { - TAILQ_FOREACH(tenant_node, &tenants_root_node->head, next) { - ConfNode *id_node = ConfNodeLookupChild(tenant_node, "id"); - if (id_node == NULL) { - goto bad_tenant; - } - ConfNode *yaml_node = ConfNodeLookupChild(tenant_node, "yaml"); - if (yaml_node == NULL) { - goto bad_tenant; - } - - uint32_t tenant_id = 0; - if (ByteExtractStringUint32(&tenant_id, 10, strlen(id_node->val), - id_node->val) == -1) - { - SCLogError(SC_ERR_INVALID_ARGUMENT, "tenant_id " - "of %s is invalid", id_node->val); - goto bad_tenant; - } - SCLogInfo("tenant id: %u, %s", tenant_id, yaml_node->val); - - /* setup the yaml in this loop so that it's not done by the loader - * threads. ConfYamlLoadFileWithPrefix is not thread safe. */ - char prefix[64]; - snprintf(prefix, sizeof(prefix), "multi-detect.%d", tenant_id); - if (ConfYamlLoadFileWithPrefix(yaml_node->val, prefix) != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "failed to load yaml %s", yaml_node->val); - goto bad_tenant; - } - - int r = DetectLoaderSetupLoadTenant(tenant_id, yaml_node->val); - if (r < 0) { - /* error logged already */ - goto bad_tenant; - } - continue; - - bad_tenant: - if (failure_fatal) - goto error; - } - } - - /* wait for our loaders to complete their tasks */ - if (DetectLoadersSync() != 0) { - goto error; - } - } else { - SCLogDebug("multi-detect not enabled (multi tenancy)"); - } - return 0; -error: - return -1; -} - -static uint32_t DetectEngineTentantGetIdFromVlanId(const void *ctx, const Packet *p) -{ - const DetectEngineThreadCtx *det_ctx = ctx; - uint32_t x = 0; - uint32_t vlan_id = 0; - - if (p->vlan_idx == 0) - return 0; - - vlan_id = p->vlan_id[0]; - - if (det_ctx == NULL || det_ctx->tenant_array == NULL || det_ctx->tenant_array_size == 0) - return 0; - - /* not very efficient, but for now we're targeting only limited amounts. - * Can use hash/tree approach later. */ - for (x = 0; x < det_ctx->tenant_array_size; x++) { - if (det_ctx->tenant_array[x].traffic_id == vlan_id) - return det_ctx->tenant_array[x].tenant_id; - } - - return 0; -} - -static int DetectEngineTentantRegisterSelector(enum DetectEngineTenantSelectors selector, - uint32_t tenant_id, uint32_t traffic_id) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - SCMutexLock(&master->lock); - - if (!(master->tenant_selector == TENANT_SELECTOR_UNKNOWN || master->tenant_selector == selector)) { - SCLogInfo("conflicting selector already set"); - SCMutexUnlock(&master->lock); - return -1; - } - - DetectEngineTenantMapping *m = master->tenant_mapping_list; - while (m) { - if (m->traffic_id == traffic_id) { - SCLogInfo("traffic id already registered"); - SCMutexUnlock(&master->lock); - return -1; - } - m = m->next; - } - - DetectEngineTenantMapping *map = SCCalloc(1, sizeof(*map)); - if (map == NULL) { - SCLogInfo("memory fail"); - SCMutexUnlock(&master->lock); - return -1; - } - map->traffic_id = traffic_id; - map->tenant_id = tenant_id; - - map->next = master->tenant_mapping_list; - master->tenant_mapping_list = map; - - master->tenant_selector = selector; - - SCLogDebug("tenant handler %u %u %u registered", selector, tenant_id, traffic_id); - SCMutexUnlock(&master->lock); - return 0; -} - -static int DetectEngineTentantUnregisterSelector(enum DetectEngineTenantSelectors selector, - uint32_t tenant_id, uint32_t traffic_id) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - SCMutexLock(&master->lock); - - if (master->tenant_mapping_list == NULL) { - SCMutexUnlock(&master->lock); - return -1; - } - - DetectEngineTenantMapping *prev = NULL; - DetectEngineTenantMapping *map = master->tenant_mapping_list; - while (map) { - if (map->traffic_id == traffic_id && - map->tenant_id == tenant_id) - { - if (prev != NULL) - prev->next = map->next; - else - master->tenant_mapping_list = map->next; - - map->next = NULL; - SCFree(map); - SCLogInfo("tenant handler %u %u %u unregistered", selector, tenant_id, traffic_id); - SCMutexUnlock(&master->lock); - return 0; - } - prev = map; - map = map->next; - } - - SCMutexUnlock(&master->lock); - return -1; -} - -int DetectEngineTentantRegisterVlanId(uint32_t tenant_id, uint16_t vlan_id) -{ - return DetectEngineTentantRegisterSelector(TENANT_SELECTOR_VLAN, tenant_id, (uint32_t)vlan_id); -} - -int DetectEngineTentantUnregisterVlanId(uint32_t tenant_id, uint16_t vlan_id) -{ - return DetectEngineTentantUnregisterSelector(TENANT_SELECTOR_VLAN, tenant_id, (uint32_t)vlan_id); -} - -int DetectEngineTentantRegisterPcapFile(uint32_t tenant_id) -{ - SCLogInfo("registering %u %d 0", TENANT_SELECTOR_DIRECT, tenant_id); - return DetectEngineTentantRegisterSelector(TENANT_SELECTOR_DIRECT, tenant_id, 0); -} - -int DetectEngineTentantUnregisterPcapFile(uint32_t tenant_id) -{ - SCLogInfo("unregistering %u %d 0", TENANT_SELECTOR_DIRECT, tenant_id); - return DetectEngineTentantUnregisterSelector(TENANT_SELECTOR_DIRECT, tenant_id, 0); -} - -static uint32_t DetectEngineTentantGetIdFromPcap(const void *ctx, const Packet *p) -{ - return p->pcap_v.tenant_id; -} - -DetectEngineCtx *DetectEngineGetByTenantId(int tenant_id) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - SCMutexLock(&master->lock); - - if (master->list == NULL) { - SCMutexUnlock(&master->lock); - return NULL; - } - - DetectEngineCtx *de_ctx = master->list; - while (de_ctx) { - if (de_ctx->tenant_id == tenant_id) { - de_ctx->ref_cnt++; - break; - } - - de_ctx = de_ctx->next; - } - - SCMutexUnlock(&master->lock); - return de_ctx; -} - -void DetectEngineDeReference(DetectEngineCtx **de_ctx) -{ - BUG_ON((*de_ctx)->ref_cnt == 0); - (*de_ctx)->ref_cnt--; - *de_ctx = NULL; -} - -static int DetectEngineAddToList(DetectEngineCtx *instance) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - - if (instance == NULL) - return -1; - - if (master->list == NULL) { - master->list = instance; - } else { - instance->next = master->list; - master->list = instance; - } - - return 0; -} - -int DetectEngineAddToMaster(DetectEngineCtx *de_ctx) -{ - int r; - - if (de_ctx == NULL) - return -1; - - SCLogDebug("adding de_ctx %p to master", de_ctx); - - DetectEngineMasterCtx *master = &g_master_de_ctx; - SCMutexLock(&master->lock); - r = DetectEngineAddToList(de_ctx); - SCMutexUnlock(&master->lock); - return r; -} - -int DetectEngineMoveToFreeList(DetectEngineCtx *de_ctx) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - - SCMutexLock(&master->lock); - DetectEngineCtx *instance = master->list; - if (instance == NULL) { - SCMutexUnlock(&master->lock); - return -1; - } - - /* remove from active list */ - if (instance == de_ctx) { - master->list = instance->next; - } else { - DetectEngineCtx *prev = instance; - instance = instance->next; /* already checked first element */ - - while (instance) { - DetectEngineCtx *next = instance->next; - - if (instance == de_ctx) { - prev->next = instance->next; - break; - } - - prev = instance; - instance = next; - } - if (instance == NULL) { - SCMutexUnlock(&master->lock); - return -1; - } - } - - /* instance is now detached from list */ - instance->next = NULL; - - /* add to free list */ - if (master->free_list == NULL) { - master->free_list = instance; - } else { - instance->next = master->free_list; - master->free_list = instance; - } - SCLogDebug("detect engine %p moved to free list (%u refs)", de_ctx, de_ctx->ref_cnt); - - SCMutexUnlock(&master->lock); - return 0; -} - -void DetectEnginePruneFreeList(void) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - SCMutexLock(&master->lock); - - DetectEngineCtx *prev = NULL; - DetectEngineCtx *instance = master->free_list; - while (instance) { - DetectEngineCtx *next = instance->next; - - SCLogDebug("detect engine %p has %u ref(s)", instance, instance->ref_cnt); - - if (instance->ref_cnt == 0) { - if (prev == NULL) { - master->free_list = next; - } else { - prev->next = next; - } - - SCLogDebug("freeing detect engine %p", instance); - DetectEngineCtxFree(instance); - instance = NULL; - } - - prev = instance; - instance = next; - } - SCMutexUnlock(&master->lock); -} - -static int reloads = 0; - -/** \brief Reload the detection engine - * - * \param filename YAML file to load for the detect config - * - * \retval -1 error - * \retval 0 ok - */ -int DetectEngineReload(const char *filename, SCInstance *suri) -{ - DetectEngineCtx *new_de_ctx = NULL; - DetectEngineCtx *old_de_ctx = NULL; - - char prefix[128] = ""; - if (filename != NULL) { - snprintf(prefix, sizeof(prefix), "detect-engine-reloads.%d", reloads++); - if (ConfYamlLoadFileWithPrefix(filename, prefix) != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "failed to load yaml %s", filename); - return -1; - } - - ConfNode *node = ConfGetNode(prefix); - if (node == NULL) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "failed to properly setup yaml %s", filename); - return -1; - } -#if 0 - ConfDump(); -#endif - } - - /* get a reference to the current de_ctx */ - old_de_ctx = DetectEngineGetCurrent(); - if (old_de_ctx == NULL) - return -1; - SCLogDebug("get ref to old_de_ctx %p", old_de_ctx); - - /* get new detection engine */ - new_de_ctx = DetectEngineCtxInitWithPrefix(prefix); - if (new_de_ctx == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "initializing detection engine " - "context failed."); - DetectEngineDeReference(&old_de_ctx); - return -1; - } - if (SigLoadSignatures(new_de_ctx, - suri->sig_file, suri->sig_file_exclusive) != 0) { - DetectEngineCtxFree(new_de_ctx); - DetectEngineDeReference(&old_de_ctx); - return -1; - } - SCThresholdConfInitContext(new_de_ctx, NULL); - SCLogDebug("set up new_de_ctx %p", new_de_ctx); - - /* add to master */ - DetectEngineAddToMaster(new_de_ctx); - - /* move to old free list */ - DetectEngineMoveToFreeList(old_de_ctx); - DetectEngineDeReference(&old_de_ctx); - - SCLogDebug("going to reload the threads to use new_de_ctx %p", new_de_ctx); - /* update the threads */ - DetectEngineReloadThreads(new_de_ctx); - SCLogDebug("threads now run new_de_ctx %p", new_de_ctx); - - /* walk free list, freeing the old_de_ctx */ - DetectEnginePruneFreeList(); - - SCLogDebug("old_de_ctx should have been freed"); - return 0; -} - -static uint32_t TenantIdHash(HashTable *h, void *data, uint16_t data_len) -{ - DetectEngineThreadCtx *det_ctx = (DetectEngineThreadCtx *)data; - return det_ctx->tenant_id % h->array_size; -} - -static char TenantIdCompare(void *d1, uint16_t d1_len, void *d2, uint16_t d2_len) -{ - DetectEngineThreadCtx *det1 = (DetectEngineThreadCtx *)d1; - DetectEngineThreadCtx *det2 = (DetectEngineThreadCtx *)d2; - return (det1->tenant_id == det2->tenant_id); -} - -static void TenantIdFree(void *d) -{ - DetectEngineThreadCtxFree(d); -} - -int DetectEngineMTApply(void) -{ - DetectEngineMasterCtx *master = &g_master_de_ctx; - SCMutexLock(&master->lock); - - if (master->tenant_selector == TENANT_SELECTOR_UNKNOWN) { - SCLogInfo("error, no tenant selector"); - SCMutexUnlock(&master->lock); - return -1; - } - - DetectEngineCtx *minimal_de_ctx = NULL; - /* if we have no tenants, we need a minimal one */ - if (master->list == NULL) { - minimal_de_ctx = master->list = DetectEngineCtxInitMinimal(); - SCLogDebug("no tenants, using minimal %p", minimal_de_ctx); - } else if (master->list->next == NULL && master->list->tenant_id == 0) { - minimal_de_ctx = master->list; - SCLogDebug("no tenants, using original %p", minimal_de_ctx); - - /* the default de_ctx should be in the list with tenant_id 0 */ - } else { - DetectEngineCtx *list = master->list; - for ( ; list != NULL; list = list->next) { - SCLogInfo("list %p tenant %u", list, list->tenant_id); - - if (list->tenant_id == 0) { - minimal_de_ctx = list; - break; - } - } - } - - /* update the threads */ - SCLogDebug("MT reload starting"); - DetectEngineReloadThreads(minimal_de_ctx); - SCLogDebug("MT reload done"); - - SCMutexUnlock(&master->lock); - - /* walk free list, freeing the old_de_ctx */ - DetectEnginePruneFreeList(); - - SCLogDebug("old_de_ctx should have been freed"); - return 0; -} - -const char *DetectSigmatchListEnumToString(enum DetectSigmatchListEnum type) -{ - switch (type) { - case DETECT_SM_LIST_MATCH: - return "packet"; - case DETECT_SM_LIST_PMATCH: - return "packet/stream payload"; - - case DETECT_SM_LIST_UMATCH: - return "http uri"; - case DETECT_SM_LIST_HRUDMATCH: - return "http raw uri"; - case DETECT_SM_LIST_HCBDMATCH: - return "http client body"; - case DETECT_SM_LIST_FILEDATA: - return "http server body"; - case DETECT_SM_LIST_HHDMATCH: - return "http headers"; - case DETECT_SM_LIST_HRHDMATCH: - return "http raw headers"; - case DETECT_SM_LIST_HSMDMATCH: - return "http stat msg"; - case DETECT_SM_LIST_HSCDMATCH: - return "http stat code"; - case DETECT_SM_LIST_HHHDMATCH: - return "http host"; - case DETECT_SM_LIST_HRHHDMATCH: - return "http raw host header"; - case DETECT_SM_LIST_HMDMATCH: - return "http method"; - case DETECT_SM_LIST_HCDMATCH: - return "http cookie"; - case DETECT_SM_LIST_HUADMATCH: - return "http user-agent"; - case DETECT_SM_LIST_HRLMATCH: - return "http request line"; - case DETECT_SM_LIST_APP_EVENT: - return "app layer events"; - - case DETECT_SM_LIST_AMATCH: - return "generic app layer"; - case DETECT_SM_LIST_DMATCH: - return "dcerpc"; - case DETECT_SM_LIST_TMATCH: - return "tag"; - - case DETECT_SM_LIST_FILEMATCH: - return "file"; - - case DETECT_SM_LIST_DNSQUERYNAME_MATCH: - return "dns query name"; - case DETECT_SM_LIST_DNSREQUEST_MATCH: - return "dns request"; - case DETECT_SM_LIST_DNSRESPONSE_MATCH: - return "dns response"; - - case DETECT_SM_LIST_MODBUS_MATCH: - return "modbus"; - - case DETECT_SM_LIST_BASE64_DATA: - return "base64_data"; - - case DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH: - return "template_buffer"; - - case DETECT_SM_LIST_POSTMATCH: - return "post-match"; - - case DETECT_SM_LIST_SUPPRESS: - return "suppress"; - case DETECT_SM_LIST_THRESHOLD: - return "threshold"; - - case DETECT_SM_LIST_MAX: - return "max (internal)"; - case DETECT_SM_LIST_NOTSET: - return "not set (internal)"; - } - return "error"; -} - - -/*************************************Unittest*********************************/ - -#ifdef UNITTESTS - -static int DetectEngineInitYamlConf(char *conf) -{ - ConfCreateContextBackup(); - ConfInit(); - return ConfYamlLoadString(conf, strlen(conf)); -} - -static void DetectEngineDeInitYamlConf(void) -{ - ConfDeInit(); - ConfRestoreContextBackup(); - - return; -} - -static int DetectEngineTest01(void) -{ - char *conf = - "%YAML 1.1\n" - "---\n" - "detect-engine:\n" - " - profile: medium\n" - " - custom-values:\n" - " toclient_src_groups: 2\n" - " toclient_dst_groups: 2\n" - " toclient_sp_groups: 2\n" - " toclient_dp_groups: 3\n" - " toserver_src_groups: 2\n" - " toserver_dst_groups: 4\n" - " toserver_sp_groups: 2\n" - " toserver_dp_groups: 25\n" - " - inspection-recursion-limit: 0\n"; - - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if (DetectEngineInitYamlConf(conf) == -1) - return 0; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - result = (de_ctx->inspection_recursion_limit == -1); - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - DetectEngineDeInitYamlConf(); - - return result; -} - -static int DetectEngineTest02(void) -{ - char *conf = - "%YAML 1.1\n" - "---\n" - "detect-engine:\n" - " - profile: medium\n" - " - custom-values:\n" - " toclient_src_groups: 2\n" - " toclient_dst_groups: 2\n" - " toclient_sp_groups: 2\n" - " toclient_dp_groups: 3\n" - " toserver_src_groups: 2\n" - " toserver_dst_groups: 4\n" - " toserver_sp_groups: 2\n" - " toserver_dp_groups: 25\n" - " - inspection-recursion-limit:\n"; - - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if (DetectEngineInitYamlConf(conf) == -1) - return 0; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - result = (de_ctx->inspection_recursion_limit == -1); - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - DetectEngineDeInitYamlConf(); - - return result; -} - -static int DetectEngineTest03(void) -{ - char *conf = - "%YAML 1.1\n" - "---\n" - "detect-engine:\n" - " - profile: medium\n" - " - custom-values:\n" - " toclient_src_groups: 2\n" - " toclient_dst_groups: 2\n" - " toclient_sp_groups: 2\n" - " toclient_dp_groups: 3\n" - " toserver_src_groups: 2\n" - " toserver_dst_groups: 4\n" - " toserver_sp_groups: 2\n" - " toserver_dp_groups: 25\n"; - - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if (DetectEngineInitYamlConf(conf) == -1) - return 0; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - result = (de_ctx->inspection_recursion_limit == - DETECT_ENGINE_DEFAULT_INSPECTION_RECURSION_LIMIT); - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - DetectEngineDeInitYamlConf(); - - return result; -} - -static int DetectEngineTest04(void) -{ - char *conf = - "%YAML 1.1\n" - "---\n" - "detect-engine:\n" - " - profile: medium\n" - " - custom-values:\n" - " toclient_src_groups: 2\n" - " toclient_dst_groups: 2\n" - " toclient_sp_groups: 2\n" - " toclient_dp_groups: 3\n" - " toserver_src_groups: 2\n" - " toserver_dst_groups: 4\n" - " toserver_sp_groups: 2\n" - " toserver_dp_groups: 25\n" - " - inspection-recursion-limit: 10\n"; - - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if (DetectEngineInitYamlConf(conf) == -1) - return 0; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - result = (de_ctx->inspection_recursion_limit == 10); - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - DetectEngineDeInitYamlConf(); - - return result; -} - -int DummyTestAppInspectionEngine01(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *sig, - Flow *f, - uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id) -{ - return 0; -} - -int DummyTestAppInspectionEngine02(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *sig, - Flow *f, - uint8_t flags, - void *alstate, - void *tx, uint64_t tx_id) -{ - return 0; -} - -int DetectEngineTest05(void) -{ - int result = 0; - int ip = 0; - - DetectEngineAppInspectionEngine *engine_list[FLOW_PROTO_DEFAULT][ALPROTO_MAX][2]; - memset(engine_list, 0, sizeof(engine_list)); - - DetectEngineRegisterAppInspectionEngine(IPPROTO_TCP, - ALPROTO_HTTP, - 0 /* STREAM_TOSERVER */, - DETECT_SM_LIST_UMATCH, - DE_STATE_FLAG_URI_INSPECT, - DummyTestAppInspectionEngine01, - engine_list); - - int alproto = ALPROTO_UNKNOWN + 1; - for (ip = 0; ip < FLOW_PROTO_DEFAULT; ip++) { - for ( ; alproto < ALPROTO_FAILED; alproto++) { - int dir = 0; - for ( ; dir < 2; dir++) { - if (alproto == ALPROTO_HTTP && dir == 0) { - if (engine_list[ip][alproto][dir]->next != NULL) { - printf("more than one entry found\n"); - goto end; - } - - DetectEngineAppInspectionEngine *engine = engine_list[ip][alproto][dir]; - - if (engine->alproto != alproto || - engine->dir != dir || - engine->sm_list != DETECT_SM_LIST_UMATCH || - engine->inspect_flags != DE_STATE_FLAG_URI_INSPECT || - engine->Callback != DummyTestAppInspectionEngine01) { - printf("failed for http and dir(0-toserver)\n"); - goto end; - } - } /* if (alproto == ALPROTO_HTTP && dir == 0) */ - - if (alproto == ALPROTO_HTTP && dir == 1) { - if (engine_list[ip][alproto][dir] != NULL) { - printf("failed for http and dir(1-toclient)\n"); - goto end; - } - } - - if (alproto != ALPROTO_HTTP && - engine_list[ip][alproto][0] != NULL && - engine_list[ip][alproto][1] != NULL) { - printf("failed for protocol %d\n", alproto); - goto end; - } - } /* for ( ; dir < 2 ..)*/ - } /* for ( ; alproto < ALPROTO_FAILED; ..) */ - } - - result = 1; - end: - return result; -} - -int DetectEngineTest06(void) -{ - int result = 0; - int ip = 0; - - DetectEngineAppInspectionEngine *engine_list[FLOW_PROTO_DEFAULT][ALPROTO_MAX][2]; - memset(engine_list, 0, sizeof(engine_list)); - - DetectEngineRegisterAppInspectionEngine(IPPROTO_TCP, - ALPROTO_HTTP, - 0 /* STREAM_TOSERVER */, - DETECT_SM_LIST_UMATCH, - DE_STATE_FLAG_URI_INSPECT, - DummyTestAppInspectionEngine01, - engine_list); - DetectEngineRegisterAppInspectionEngine(IPPROTO_TCP, - ALPROTO_HTTP, - 1 /* STREAM_TOCLIENT */, - DETECT_SM_LIST_UMATCH, - DE_STATE_FLAG_URI_INSPECT, - DummyTestAppInspectionEngine02, - engine_list); - - int alproto = ALPROTO_UNKNOWN + 1; - for (ip = 0; ip < FLOW_PROTO_DEFAULT; ip++) { - for ( ; alproto < ALPROTO_FAILED; alproto++) { - int dir = 0; - for ( ; dir < 2; dir++) { - if (alproto == ALPROTO_HTTP && dir == 0) { - if (engine_list[ip][alproto][dir]->next != NULL) { - printf("more than one entry found\n"); - goto end; - } - - DetectEngineAppInspectionEngine *engine = engine_list[ip][alproto][dir]; - - if (engine->alproto != alproto || - engine->dir != dir || - engine->sm_list != DETECT_SM_LIST_UMATCH || - engine->inspect_flags != DE_STATE_FLAG_URI_INSPECT || - engine->Callback != DummyTestAppInspectionEngine01) { - printf("failed for http and dir(0-toserver)\n"); - goto end; - } - } /* if (alproto == ALPROTO_HTTP && dir == 0) */ - - if (alproto == ALPROTO_HTTP && dir == 1) { - if (engine_list[ip][alproto][dir]->next != NULL) { - printf("more than one entry found\n"); - goto end; - } - - DetectEngineAppInspectionEngine *engine = engine_list[ip][alproto][dir]; - - if (engine->alproto != alproto || - engine->dir != dir || - engine->sm_list != DETECT_SM_LIST_UMATCH || - engine->inspect_flags != DE_STATE_FLAG_URI_INSPECT || - engine->Callback != DummyTestAppInspectionEngine02) { - printf("failed for http and dir(0-toclient)\n"); - goto end; - } - } /* if (alproto == ALPROTO_HTTP && dir == 1) */ - - if (alproto != ALPROTO_HTTP && - engine_list[ip][alproto][0] != NULL && - engine_list[ip][alproto][1] != NULL) { - printf("failed for protocol %d\n", alproto); - goto end; - } - } /* for ( ; dir < 2 ..)*/ - } /* for ( ; alproto < ALPROTO_FAILED; ..) */ - } - - result = 1; - end: - return result; -} - -int DetectEngineTest07(void) -{ - int result = 0; - int ip = 0; - - DetectEngineAppInspectionEngine *engine_list[FLOW_PROTO_DEFAULT][ALPROTO_MAX][2]; - memset(engine_list, 0, sizeof(engine_list)); - - struct test_data_t { - int32_t sm_list; - uint32_t inspect_flags; - uint16_t dir; - int (*Callback)(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *sig, Flow *f, - uint8_t flags, void *alstate, - void *tx, uint64_t tx_id); - - }; - - struct test_data_t data[] = { - { DETECT_SM_LIST_UMATCH, - DE_STATE_FLAG_URI_INSPECT, - 0, - DummyTestAppInspectionEngine01 }, - { DETECT_SM_LIST_HCBDMATCH, - DE_STATE_FLAG_HCBD_INSPECT, - 0, - DummyTestAppInspectionEngine02 }, - { DETECT_SM_LIST_FILEDATA, - DE_STATE_FLAG_HSBD_INSPECT, - 1, - DummyTestAppInspectionEngine02 }, - { DETECT_SM_LIST_HHDMATCH, - DE_STATE_FLAG_HHD_INSPECT, - 0, - DummyTestAppInspectionEngine01 }, - { DETECT_SM_LIST_HRHDMATCH, - DE_STATE_FLAG_HRHD_INSPECT, - 0, - DummyTestAppInspectionEngine01 }, - { DETECT_SM_LIST_HMDMATCH, - DE_STATE_FLAG_HMD_INSPECT, - 0, - DummyTestAppInspectionEngine02 }, - { DETECT_SM_LIST_HCDMATCH, - DE_STATE_FLAG_HCD_INSPECT, - 0, - DummyTestAppInspectionEngine01 }, - { DETECT_SM_LIST_HRUDMATCH, - DE_STATE_FLAG_HRUD_INSPECT, - 0, - DummyTestAppInspectionEngine01 }, - { DETECT_SM_LIST_FILEMATCH, - DE_STATE_FLAG_FILE_TS_INSPECT, - 0, - DummyTestAppInspectionEngine02 }, - { DETECT_SM_LIST_FILEMATCH, - DE_STATE_FLAG_FILE_TC_INSPECT, - 1, - DummyTestAppInspectionEngine02 }, - { DETECT_SM_LIST_HSMDMATCH, - DE_STATE_FLAG_HSMD_INSPECT, - 0, - DummyTestAppInspectionEngine01 }, - { DETECT_SM_LIST_HSCDMATCH, - DE_STATE_FLAG_HSCD_INSPECT, - 0, - DummyTestAppInspectionEngine01 }, - { DETECT_SM_LIST_HUADMATCH, - DE_STATE_FLAG_HUAD_INSPECT, - 0, - DummyTestAppInspectionEngine02 }, - }; - - size_t i = 0; - for ( ; i < sizeof(data) / sizeof(struct test_data_t); i++) { - DetectEngineRegisterAppInspectionEngine(IPPROTO_TCP, - ALPROTO_HTTP, - data[i].dir /* STREAM_TOCLIENT */, - data[i].sm_list, - data[i].inspect_flags, - data[i].Callback, - engine_list); - } - -#if 0 - DetectEnginePrintAppInspectionEngines(engine_list); -#endif - - int alproto = ALPROTO_UNKNOWN + 1; - for (ip = 0; ip < FLOW_PROTO_DEFAULT; ip++) { - for ( ; alproto < ALPROTO_FAILED; alproto++) { - int dir = 0; - for ( ; dir < 2; dir++) { - if (alproto == ALPROTO_HTTP) { - DetectEngineAppInspectionEngine *engine = engine_list[ip][alproto][dir]; - - size_t i = 0; - for ( ; i < (sizeof(data) / sizeof(struct test_data_t)); i++) { - if (data[i].dir != dir) - continue; - - if (engine->alproto != ALPROTO_HTTP || - engine->dir != data[i].dir || - engine->sm_list != data[i].sm_list || - engine->inspect_flags != data[i].inspect_flags || - engine->Callback != data[i].Callback) { - printf("failed for http\n"); - goto end; - } - engine = engine->next; - } - } else { - if (engine_list[ip][alproto][0] != NULL && - engine_list[ip][alproto][1] != NULL) { - printf("failed for protocol %d\n", alproto); - goto end; - } - } /* else */ - } /* for ( ; dir < 2; dir++) */ - } /* for ( ; alproto < ALPROTO_FAILED; ..) */ - } - - result = 1; - end: - return result; -} - -static int DetectEngineTest08(void) -{ - char *conf = - "%YAML 1.1\n" - "---\n" - "detect-engine:\n" - " - profile: custom\n" - " - custom-values:\n" - " toclient-src-groups: 20\n" - " toclient-dst-groups: 21\n" - " toclient-sp-groups: 22\n" - " toclient-dp-groups: 23\n" - " toserver-src-groups: 24\n" - " toserver-dst-groups: 25\n" - " toserver-sp-groups: 26\n" - " toserver-dp-groups: 27\n"; - - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if (DetectEngineInitYamlConf(conf) == -1) - return 0; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (de_ctx->max_uniq_toclient_src_groups == 20 && - de_ctx->max_uniq_toclient_dst_groups == 21 && - de_ctx->max_uniq_toclient_sp_groups == 22 && - de_ctx->max_uniq_toclient_dp_groups == 23 && - de_ctx->max_uniq_toserver_src_groups == 24 && - de_ctx->max_uniq_toserver_dst_groups == 25 && - de_ctx->max_uniq_toserver_sp_groups == 26 && - de_ctx->max_uniq_toserver_dp_groups == 27) - result = 1; - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - DetectEngineDeInitYamlConf(); - - return result; -} - -/** \test bug 892 bad values */ -static int DetectEngineTest09(void) -{ - char *conf = - "%YAML 1.1\n" - "---\n" - "detect-engine:\n" - " - profile: custom\n" - " - custom-values:\n" - " toclient-src-groups: BA\n" - " toclient-dst-groups: BA\n" - " toclient-sp-groups: BA\n" - " toclient-dp-groups: BA\n" - " toserver-src-groups: BA\n" - " toserver-dst-groups: BA\n" - " toserver-sp-groups: BA\n" - " toserver-dp-groups: BA\n" - " - inspection-recursion-limit: 10\n"; - - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if (DetectEngineInitYamlConf(conf) == -1) - return 0; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (de_ctx->max_uniq_toclient_src_groups == 4 && - de_ctx->max_uniq_toclient_dst_groups == 4 && - de_ctx->max_uniq_toclient_sp_groups == 4 && - de_ctx->max_uniq_toclient_dp_groups == 6 && - de_ctx->max_uniq_toserver_src_groups == 4 && - de_ctx->max_uniq_toserver_dst_groups == 8 && - de_ctx->max_uniq_toserver_sp_groups == 4 && - de_ctx->max_uniq_toserver_dp_groups == 30) - result = 1; - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - DetectEngineDeInitYamlConf(); - - return result; -} - -#endif - -void DetectEngineRegisterTests() -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectEngineTest01", DetectEngineTest01, 1); - UtRegisterTest("DetectEngineTest02", DetectEngineTest02, 1); - UtRegisterTest("DetectEngineTest03", DetectEngineTest03, 1); - UtRegisterTest("DetectEngineTest04", DetectEngineTest04, 1); - UtRegisterTest("DetectEngineTest05", DetectEngineTest05, 1); - UtRegisterTest("DetectEngineTest06", DetectEngineTest06, 1); - UtRegisterTest("DetectEngineTest07", DetectEngineTest07, 1); - UtRegisterTest("DetectEngineTest08", DetectEngineTest08, 1); - UtRegisterTest("DetectEngineTest09", DetectEngineTest09, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/detect-engine.h b/framework/src/suricata/src/detect-engine.h deleted file mode 100644 index 70b18133..00000000 --- a/framework/src/suricata/src/detect-engine.h +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_ENGINE_H__ -#define __DETECT_ENGINE_H__ - -#include "detect.h" -#include "tm-threads.h" -#include "flow-private.h" - -typedef struct DetectEngineAppInspectionEngine_ { - uint8_t ipproto; - AppProto alproto; - uint16_t dir; - - int32_t sm_list; - uint32_t inspect_flags; - - /* \retval 0 No match. Don't discontinue matching yet. We need more data. - * 1 Match. - * 2 Sig can't match. - * 3 Special value used by filestore sigs to indicate disabling - * filestore for the tx. - */ - int (*Callback)(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, - Signature *sig, Flow *f, uint8_t flags, void *alstate, - void *tx, uint64_t tx_id); - - struct DetectEngineAppInspectionEngine_ *next; -} DetectEngineAppInspectionEngine; - -extern DetectEngineAppInspectionEngine *app_inspection_engine[FLOW_PROTO_DEFAULT][ALPROTO_MAX][2]; - -/* prototypes */ -void DetectEngineRegisterAppInspectionEngines(void); -DetectEngineCtx *DetectEngineCtxInitWithPrefix(const char *prefix); -DetectEngineCtx *DetectEngineCtxInit(void); -DetectEngineCtx *DetectEngineCtxInitMinimal(void); -void DetectEngineCtxFree(DetectEngineCtx *); - -TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **); -TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *); -//inline uint32_t DetectEngineGetMaxSigId(DetectEngineCtx *); -/* faster as a macro than a inline function on my box -- VJ */ -#define DetectEngineGetMaxSigId(de_ctx) ((de_ctx)->signum) -void DetectEngineResetMaxSigId(DetectEngineCtx *); -void DetectEngineRegisterTests(void); -const char *DetectSigmatchListEnumToString(enum DetectSigmatchListEnum type); - -int DetectEngineAddToMaster(DetectEngineCtx *de_ctx); -DetectEngineCtx *DetectEngineGetCurrent(void); -DetectEngineCtx *DetectEngineGetByTenantId(int tenant_id); -void DetectEnginePruneFreeList(void); -int DetectEngineMoveToFreeList(DetectEngineCtx *de_ctx); -DetectEngineCtx *DetectEngineReference(DetectEngineCtx *); -void DetectEngineDeReference(DetectEngineCtx **de_ctx); -int DetectEngineReload(const char *filename, SCInstance *suri); -int DetectEngineEnabled(void); -int DetectEngineMTApply(void); -int DetectEngineMultiTenantEnabled(void); -int DetectEngineMultiTenantSetup(void); - -int DetectEngineReloadStart(void); -int DetectEngineReloadIsStart(void); -void DetectEngineReloadSetDone(void); -int DetectEngineReloadIsDone(void); - -int DetectEngineLoadTenantBlocking(uint32_t tenant_id, const char *yaml); -int DetectEngineReloadTenantBlocking(uint32_t tenant_id, const char *yaml, int reload_cnt); - -int DetectEngineTentantRegisterVlanId(uint32_t tenant_id, uint16_t vlan_id); -int DetectEngineTentantUnregisterVlanId(uint32_t tenant_id, uint16_t vlan_id); -int DetectEngineTentantRegisterPcapFile(uint32_t tenant_id); -int DetectEngineTentantUnregisterPcapFile(uint32_t tenant_id); - -/** - * \brief Registers an app inspection engine. - * - * \param alproto App layer protocol for which we will register the engine. - * \param direction The direction for the engine. 0 - toserver; 1- toclient. - * \param sm_list The SigMatch list against which the engine works. - * \param inspect_flags The inspection flags to be used by de_state - * against the engine. - * \param match_flags The match flags to be used by de_state in tandem with - * the inpsect_flags. - * \param Callback The engine callback. - */ -void DetectEngineRegisterAppInspectionEngine(uint8_t ipproto, - AppProto alproto, - uint16_t direction, - int32_t sm_list, - uint32_t inspect_flags, - int (*Callback)(ThreadVars *tv, - DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, - Signature *sig, Flow *f, - uint8_t flags, void *alstate, - void *tx, uint64_t tx_id), - DetectEngineAppInspectionEngine *list[][ALPROTO_MAX][2]); -#endif /* __DETECT_ENGINE_H__ */ diff --git a/framework/src/suricata/src/detect-fast-pattern.c b/framework/src/suricata/src/detect-fast-pattern.c deleted file mode 100644 index 01b8f398..00000000 --- a/framework/src/suricata/src/detect-fast-pattern.c +++ /dev/null @@ -1,20156 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements the fast_pattern keyword - */ - -#include "suricata-common.h" -#include "detect.h" -#include "flow.h" -#include "detect-content.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-fast-pattern.h" - -#include "util-error.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#define DETECT_FAST_PATTERN_REGEX "^(\\s*only\\s*)|\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*$" - -static pcre *parse_regex = NULL; -static pcre_extra *parse_regex_study = NULL; - -static int DetectFastPatternSetup(DetectEngineCtx *, Signature *, char *); -void DetectFastPatternRegisterTests(void); - -/* holds the list of sm match lists that need to be searched for a keyword - * that has fp support */ -SCFPSupportSMList *sm_fp_support_smlist_list = NULL; - -/** - * \brief Lets one add a sm list id to be searched for potential fp supported - * keywords later. - * - * \param list_id SM list id. - * \param priority Priority for this list. - */ -static void SupportFastPatternForSigMatchList(int list_id, int priority) -{ - if (sm_fp_support_smlist_list == NULL) { - SCFPSupportSMList *new = SCMalloc(sizeof(SCFPSupportSMList)); - if (unlikely(new == NULL)) - exit(EXIT_FAILURE); - memset(new, 0, sizeof(SCFPSupportSMList)); - new->list_id = list_id; - new->priority = priority; - - sm_fp_support_smlist_list = new; - - return; - } - - /* insertion point - ip */ - SCFPSupportSMList *ip = NULL; - for (SCFPSupportSMList *tmp = sm_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) { - if (list_id == tmp->list_id) { - SCLogError(SC_ERR_FATAL, "SM list already registered."); - exit(EXIT_FAILURE); - } - - if (priority <= tmp->priority) - break; - - ip = tmp; - } - - SCFPSupportSMList *new = SCMalloc(sizeof(SCFPSupportSMList)); - if (unlikely(new == NULL)) - exit(EXIT_FAILURE); - memset(new, 0, sizeof(SCFPSupportSMList)); - new->list_id = list_id; - new->priority = priority; - if (ip == NULL) { - new->next = sm_fp_support_smlist_list; - sm_fp_support_smlist_list = new; - } else { - new->next = ip->next; - ip->next = new; - } - - for (SCFPSupportSMList *tmp = new->next; tmp != NULL; tmp = tmp->next) { - if (list_id == tmp->list_id) { - SCLogError(SC_ERR_FATAL, "SM list already registered."); - exit(EXIT_FAILURE); - } - } - - return; -} - -/** - * \brief Registers the keywords(SMs) that should be given fp support. - */ -void SupportFastPatternForSigMatchTypes(void) -{ - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HCBDMATCH, 2); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_FILEDATA, 2); - - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HHDMATCH, 2); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRHDMATCH, 2); - - SupportFastPatternForSigMatchList(DETECT_SM_LIST_UMATCH, 2); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRUDMATCH, 2); - - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HHHDMATCH, 2); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRHHDMATCH, 2); - - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HCDMATCH, 2); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HUADMATCH, 2); - - SupportFastPatternForSigMatchList(DETECT_SM_LIST_PMATCH, 3); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HMDMATCH, 3); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSCDMATCH, 3); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSMDMATCH, 3); - - SupportFastPatternForSigMatchList(DETECT_SM_LIST_DNSQUERYNAME_MATCH, 2); - -#if 0 - SCFPSupportSMList *tmp = sm_fp_support_smlist_list; - while (tmp != NULL) { - printf("%d - %d\n", tmp->list_id, tmp->priority); - - tmp = tmp->next; - } -#endif - - return; -} - -/** - * \brief Registration function for fast_pattern keyword - */ -void DetectFastPatternRegister(void) -{ - sigmatch_table[DETECT_FAST_PATTERN].name = "fast_pattern"; - sigmatch_table[DETECT_FAST_PATTERN].desc = "force using preceding content in the multi pattern matcher"; - sigmatch_table[DETECT_FAST_PATTERN].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#fast_pattern"; - sigmatch_table[DETECT_FAST_PATTERN].Match = NULL; - sigmatch_table[DETECT_FAST_PATTERN].Setup = DetectFastPatternSetup; - sigmatch_table[DETECT_FAST_PATTERN].Free = NULL; - sigmatch_table[DETECT_FAST_PATTERN].RegisterTests = DetectFastPatternRegisterTests; - - sigmatch_table[DETECT_FAST_PATTERN].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_FAST_PATTERN].flags |= SIGMATCH_PAYLOAD; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(DETECT_FAST_PATTERN_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at " - "offset %" PRId32 ": %s", DETECT_FAST_PATTERN_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - - error: - /* get some way to return an error code! */ - return; -} - -//static int DetectFastPatternParseArg( - -/** - * \brief Configures the previous content context for a fast_pattern modifier - * keyword used in the rule. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Signature to which the current keyword belongs. - * \param null_str Should hold an empty string always. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - char arg_substr[128] = ""; - DetectContentData *cd = NULL; - - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH] == NULL && - s->sm_lists_tail[DETECT_SM_LIST_DNSQUERYNAME_MATCH] == NULL) { - SCLogWarning(SC_WARN_COMPATIBILITY, "fast_pattern found inside the " - "rule, without a preceding content based keyword. " - "Currently we provide fast_pattern support for content, " - "uricontent, http_client_body, http_server_body, http_header, " - "http_raw_header, http_method, http_cookie, " - "http_raw_uri, http_stat_msg, http_stat_code, " - "http_user_agent, http_host, http_raw_host or " - "dns_query option"); - return -1; - } - - SigMatch *pm = SigMatchGetLastSMFromLists(s, 28, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_DNSQUERYNAME_MATCH]); - if (pm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside " - "the rule, without a content context. Please use a " - "content based keyword before using fast_pattern"); - return -1; - } - - cd = (DetectContentData *)pm->ctx; - if ((cd->flags & DETECT_CONTENT_NEGATED) && - ((cd->flags & DETECT_CONTENT_DISTANCE) || - (cd->flags & DETECT_CONTENT_WITHIN) || - (cd->flags & DETECT_CONTENT_OFFSET) || - (cd->flags & DETECT_CONTENT_DEPTH))) { - - /* we can't have any of these if we are having "only" */ - SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern; cannot be " - "used with negated content, along with relative modifiers"); - goto error; - } - - if (arg == NULL|| strcmp(arg, "") == 0) { - if (cd->flags & DETECT_CONTENT_FAST_PATTERN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple fast_pattern " - "options for the same content"); - goto error; - } - else { /*allow only one content to have fast_pattern modifier*/ - int list_id = 0; - for (list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) { - SigMatch *sm = NULL; - for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) { - if (sm->type == DETECT_CONTENT) { - DetectContentData *tmp_cd = (DetectContentData *)sm->ctx; - if (tmp_cd->flags & DETECT_CONTENT_FAST_PATTERN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern " - "can be used on only one content in a rule"); - goto error; - } - } - } /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */ - } - } - cd->flags |= DETECT_CONTENT_FAST_PATTERN; - return 0; - } - - /* Execute the regex and populate args with captures. */ - ret = pcre_exec(parse_regex, parse_regex_study, arg, - strlen(arg), 0, 0, ov, MAX_SUBSTRINGS); - /* fast pattern only */ - if (ret == 2) { - if ((cd->flags & DETECT_CONTENT_NEGATED) || - (cd->flags & DETECT_CONTENT_DISTANCE) || - (cd->flags & DETECT_CONTENT_WITHIN) || - (cd->flags & DETECT_CONTENT_OFFSET) || - (cd->flags & DETECT_CONTENT_DEPTH)) { - - /* we can't have any of these if we are having "only" */ - SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern: only; cannot be " - "used with negated content or with any of the relative " - "modifiers like distance, within, offset, depth"); - goto error; - } - cd->flags |= DETECT_CONTENT_FAST_PATTERN_ONLY; - - /* fast pattern chop */ - } else if (ret == 4) { - res = pcre_copy_substring((char *)arg, ov, MAX_SUBSTRINGS, - 2, arg_substr, sizeof(arg_substr)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed " - "for fast_pattern offset"); - goto error; - } - int offset = atoi(arg_substr); - if (offset > 65535) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Fast pattern offset exceeds " - "limit"); - goto error; - } - - res = pcre_copy_substring((char *)arg, ov, MAX_SUBSTRINGS, - 3, arg_substr, sizeof(arg_substr)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed " - "for fast_pattern offset"); - goto error; - } - int length = atoi(arg_substr); - if (length > 65535) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Fast pattern length exceeds " - "limit"); - goto error; - } - - if (offset + length > 65535) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Fast pattern (length + offset) " - "exceeds limit pattern length limit"); - goto error; - } - - if (offset + length > cd->content_len) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Fast pattern (length + " - "offset (%u)) exceeds pattern length (%u)", - offset + length, cd->content_len); - goto error; - } - - cd->fp_chop_offset = offset; - cd->fp_chop_len = length; - cd->flags |= DETECT_CONTENT_FAST_PATTERN_CHOP; - - } else { - SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32 - ", string %s", ret, arg); - goto error; - } - - //int args; - //args = 0; - //printf("ret-%d\n", ret); - //for (args = 0; args < ret; args++) { - // res = pcre_get_substring((char *)arg, ov, MAX_SUBSTRINGS, - // args, &arg_substr); - // if (res < 0) { - // SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed " - // "for arg 1"); - // goto error; - // } - // printf("%d-%s\n", args, arg_substr); - //} - - cd->flags |= DETECT_CONTENT_FAST_PATTERN; - - return 0; - - error: - return -1; -} - -/*----------------------------------Unittests---------------------------------*/ - -#ifdef UNITTESTS - -/** - * \test Checks if a fast_pattern is registered in a Signature - */ -int DetectFastPatternTest01(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; tcpv4-csum:valid; fast_pattern; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - break; - } else { - result = 0; - break; - } - } - sm = sm->next; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature - */ -int DetectFastPatternTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; fast_pattern; " - "content:\"boo\"; fast_pattern; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that we have no fast_pattern registerd for a Signature when the - * Signature doesn't contain a fast_pattern - */ -int DetectFastPatternTest03(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - if ( !(((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN)) { - result = 1; - } else { - result = 0; - break; - } - } - sm = sm->next; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a fast_pattern is not registered in a Signature, when we - * supply a fast_pattern with an argument - */ -int DetectFastPatternTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; fast_pattern:boo; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a fast_pattern is used in the mpm phase. - */ -int DetectFastPatternTest05(void) -{ - uint8_t *buf = (uint8_t *) "Oh strin1. But what " - "strin2. This is strings3. We strins_str4. we " - "have strins_string5"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; fast_pattern; " - "content:\"strings_str4\"; content:\"strings_string5\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) != 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a fast_pattern is used in the mpm phase. - */ -int DetectFastPatternTest06(void) -{ - uint8_t *buf = (uint8_t *) "Oh this is a string1. But what is this with " - "string2. This is strings3. We have strings_str4. We also have " - "strings_string5"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; fast_pattern; " - "content:\"strings_str4\"; content:\"strings_string5\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) != 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a fast_pattern is used in the mpm phase, when the payload - * doesn't contain the fast_pattern string within it. - */ -int DetectFastPatternTest07(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. now here comes our " - "dark knight strings_string5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; fast_pattern; " - "content:\"strings_str4\"; content:\"strings_string5\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a fast_pattern is used in the mpm phase and that we get - * exactly 1 match for the mpm phase. - */ -int DetectFastPatternTest08(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. now here comes our " - "dark knight strings3. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx init: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; fast_pattern; " - "content:\"strings_str4\"; content:\"strings_string5\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = PacketPatternSearchWithStreamCtx(det_ctx, p); - if (r != 1) { - printf("expected 1, got %"PRIu32": ", r); - goto end; - } - - result = 1; -end: - UTHFreePackets(&p, 1); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} -/** - * \test Checks that a fast_pattern is used in the mpm phase, when the payload - * doesn't contain the fast_pattern string within it. - */ -int DetectFastPatternTest09(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. no_strings4 _imp now here " - "comes our dark knight strings3. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; fast_pattern; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a the SigInit chooses the fast_pattern with better pattern - * strength, when we have multiple fast_patterns in the Signature. Also - * checks that we get a match for the fast_pattern from the mpm phase. - */ -int DetectFastPatternTest10(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. strings4_imp now here " - "comes our dark knight strings5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx init: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; fast_pattern; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = PacketPatternSearchWithStreamCtx(det_ctx, p); - if (r != 1) { - printf("expected 1, got %"PRIu32": ", r); - goto end; - } - - result = 1; -end: - UTHFreePackets(&p, 1); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a the SigInit chooses the fast_pattern with better pattern - * strength, when we have multiple fast_patterns in the Signature. Also - * checks that we get no matches for the fast_pattern from the mpm phase. - */ -int DetectFastPatternTest11(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. strings5_imp now here " - "comes our dark knight strings5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; fast_pattern; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0) - result = 1; - - -end: - UTHFreePackets(&p, 1); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - return result; -} - -/** - * \test Checks that we don't get a match for the mpm phase. - */ -int DetectFastPatternTest12(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. strings5_imp now here " - "comes our dark knight strings5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - UTHFreePackets(&p, 1); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks that a the SigInit chooses the fast_pattern with a better - * strength from the available patterns, when we don't specify a - * fast_pattern. We also check that we get a match from the mpm - * phase. - */ -int DetectFastPatternTest13(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. strings5_imp now here " - "comes our dark knight strings_string5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx init: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"string1\"; " - "content:\"string2\"; content:\"strings3\"; " - "content:\"strings4_imp\"; " - "content:\"strings_string5\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* start the search phase */ - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - uint32_t r = PacketPatternSearchWithStreamCtx(det_ctx, p); - if (r != 1) { - printf("expected 1 result, got %"PRIu32": ", r); - goto end; - } - - result = 1; -end: - UTHFreePackets(&p, 1); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the same payload - * - */ -int DetectFastPatternTest14(void) -{ - uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " - "right now, all the way to hangover. right. strings5_imp now here " - "comes our dark knight strings_string5. Yes here is our dark knight"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int alertcnt = 0; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf,buflen,IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - FlowInitConfig(FLOW_QUIET); - - de_ctx->mpm_matcher = MPM_B3G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; fast_pattern; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)){ - alertcnt++; - }else{ - SCLogInfo("could not match on sig 1 with when fast_pattern is inspecting payload"); - goto end; - } - if (PacketAlertCheck(p, 2)){ - result = 1; - }else{ - SCLogInfo("match on sig 1 fast_pattern no match sig 2 inspecting same payload"); - } -end: - UTHFreePackets(&p, 1); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - DetectEngineCtxFree(de_ctx); - FlowShutdown(); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature - */ -int DetectFastPatternTest15(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; fast_pattern:only; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - break; - } else { - result = 0; - break; - } - } - sm = sm->next; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature - */ -int DetectFastPatternTest16(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - break; - } else { - result = 0; - break; - } - } - sm = sm->next; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest17(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - DetectContentData *cd = (DetectContentData *)sm->ctx; - if (sm->type == DETECT_CONTENT) { - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - cd->fp_chop_offset == 0 && - cd->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest18(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - DetectContentData *cd = (DetectContentData *)sm->ctx; - if (sm->type == DETECT_CONTENT) { - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest19(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest20(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest21(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; fast_pattern:only; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; within:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; fast_pattern:only; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; offset:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; fast_pattern:only; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; depth:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:!\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest28(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content: \"one\"; content:\"two\"; distance:30; content:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - cd->fp_chop_offset == 0 && - cd->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest29(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; within:30; content:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - cd->fp_chop_offset == 0 && - cd->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest30(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; offset:30; content:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - cd->fp_chop_offset == 0 && - cd->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest31(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; depth:30; content:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - cd->fp_chop_offset == 0 && - cd->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest32(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; content:\"two\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - cd->flags & DETECT_CONTENT_NEGATED && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - cd->fp_chop_offset == 0 && - cd->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest33(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; content:!\"one\"; fast_pattern; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest34(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; content:!\"one\"; fast_pattern; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest35(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; content:!\"one\"; fast_pattern; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest36(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; content:!\"one\"; fast_pattern; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest37(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; content:\"oneonetwo\"; fast_pattern:3,4; content:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest38(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"twotwotwo\"; fast_pattern:3,4; content:\"three\"; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest39(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"twotwotwo\"; fast_pattern:3,4; content:\"three\"; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest40(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"twotwotwo\"; fast_pattern:3,4; content:\"three\"; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest41(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"twotwotwo\"; fast_pattern:3,4; content:\"three\"; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest42(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; distance:10; content:\"threethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest43(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; within:10; content:\"threethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest44(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; offset:10; content:\"threethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest45(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; depth:10; content:\"threethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest46(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; fast_pattern:65977,4; content:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest47(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"twooneone\"; fast_pattern:3,65977; content:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest48(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; fast_pattern:65534,4; content:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest49(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:!\"twooneone\"; fast_pattern:3,4; content:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN && - cd->flags & DETECT_CONTENT_NEGATED && - !(cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - cd->fp_chop_offset == 3 && - cd->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest50(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:!\"twooneone\"; fast_pattern:3,4; distance:10; content:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest51(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:!\"twooneone\"; fast_pattern:3,4; within:10; content:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest52(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:!\"twooneone\"; fast_pattern:3,4; offset:10; content:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest53(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:!\"twooneone\"; fast_pattern:3,4; depth:10; content:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* content fast_pattern tests ^ */ -/* uricontent fast_pattern tests v */ - - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest54(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"/one/\"; fast_pattern:only; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - break; - } else { - result = 0; - break; - } - } - sm = sm->next; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest55(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"oneoneone\"; fast_pattern:3,4; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - break; - } else { - result = 0; - break; - } - } - sm = sm->next; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest56(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (sm->type == DETECT_CONTENT) { - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest57(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"oneoneone\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (sm->type == DETECT_CONTENT) { - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest58(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; fast_pattern:only; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest59(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; distance:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest60(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; fast_pattern:only; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest61(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; within:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest62(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; fast_pattern:only; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest63(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; offset:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest64(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; fast_pattern:only; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest65(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; depth:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest66(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:!\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest67(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent: \"one\"; uricontent:\"two\"; distance:30; uricontent:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest68(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; within:30; uricontent:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest69(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; offset:30; uricontent:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest70(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; depth:30; uricontent:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest71(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:!\"one\"; fast_pattern; uricontent:\"two\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest72(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"two\"; uricontent:!\"one\"; fast_pattern; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest73(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"two\"; uricontent:!\"one\"; fast_pattern; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest74(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"two\"; uricontent:!\"one\"; fast_pattern; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest75(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"two\"; uricontent:!\"one\"; fast_pattern; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest76(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"oneonetwo\"; fast_pattern:3,4; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest77(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"oneonetwo\"; fast_pattern:3,4; uricontent:\"three\"; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest78(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"oneonetwo\"; fast_pattern:3,4; uricontent:\"three\"; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest79(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"oneonetwo\"; fast_pattern:3,4; uricontent:\"three\"; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest80(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"oneonetwo\"; fast_pattern:3,4; uricontent:\"three\"; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest81(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; distance:10; uricontent:\"oneonethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest82(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; within:10; uricontent:\"oneonethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest83(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; offset:10; uricontent:\"oneonethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest84(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; depth:10; uricontent:\"oneonethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest85(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; fast_pattern:65977,4; uricontent:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest86(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"oneonetwo\"; fast_pattern:3,65977; uricontent:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest87(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; fast_pattern:65534,4; uricontent:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest88(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:!\"oneonetwo\"; fast_pattern:3,4; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest89(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:!\"oneonetwo\"; fast_pattern:3,4; distance:10; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest90(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:!\"oneonetwo\"; fast_pattern:3,4; within:10; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest91(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:!\"oneonetwo\"; fast_pattern:3,4; offset:10; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest92(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:!\"oneonetwo\"; fast_pattern:3,4; depth:10; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* uricontent fast_pattern tests ^ */ -/* http_uri fast_pattern tests v */ - - -int DetectFastPatternTest93(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:!\"oneonetwo\"; fast_pattern:3,4; http_uri; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest94(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; fast_pattern:only; http_uri; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - break; - } else { - result = 0; - break; - } - } - sm = sm->next; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest95(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_uri; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - break; - } else { - result = 0; - break; - } - } - sm = sm->next; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest96(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (sm->type == DETECT_CONTENT) { - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest97(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (sm->type == DETECT_CONTENT) { - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest98(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; fast_pattern:only; http_uri; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest99(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest100(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; fast_pattern:only; http_uri; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest101(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; within:10; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest102(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; fast_pattern:only; http_uri; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest103(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; offset:10; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest104(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; fast_pattern:only; http_uri; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest105(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; depth:10; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest106(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:!\"two\"; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest107(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent: \"one\"; uricontent:\"two\"; distance:30; content:\"two\"; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest108(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; within:30; content:\"two\"; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest109(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; offset:30; content:\"two\"; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest110(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; depth:30; content:\"two\"; fast_pattern:only; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest111(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_uri; uricontent:\"two\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest112(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"two\"; content:!\"one\"; fast_pattern; http_uri; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest113(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"two\"; content:!\"one\"; fast_pattern; http_uri; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest114(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"two\"; content:!\"one\"; fast_pattern; http_uri; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest115(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"two\"; content:!\"one\"; fast_pattern; http_uri; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest116(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"oneonetwo\"; fast_pattern:3,4; http_uri; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest117(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"oneonetwo\"; fast_pattern:3,4; http_uri; uricontent:\"three\"; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest118(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"oneonetwo\"; fast_pattern:3,4; http_uri; uricontent:\"three\"; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest119(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"oneonetwo\"; fast_pattern:3,4; http_uri; uricontent:\"three\"; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest120(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"oneonetwo\"; fast_pattern:3,4; http_uri; uricontent:\"three\"; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest121(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; distance:10; content:\"oneonethree\"; fast_pattern:3,4; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest122(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; within:10; content:\"oneonethree\"; fast_pattern:3,4; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest123(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; offset:10; content:\"oneonethree\"; fast_pattern:3,4; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest124(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; uricontent:\"two\"; depth:10; content:\"oneonethree\"; fast_pattern:3,4; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest125(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; fast_pattern:65977,4; http_uri; uricontent:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest126(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"oneonetwo\"; fast_pattern:3,65977; http_uri; uricontent:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest127(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:\"two\"; fast_pattern:65534,4; http_uri; uricontent:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest128(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:!\"oneonetwo\"; fast_pattern:3,4; http_uri; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest129(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:!\"oneonetwo\"; fast_pattern:3,4; http_uri; distance:10; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest130(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:!\"oneonetwo\"; fast_pattern:3,4; http_uri; within:10; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest131(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:!\"twooneone\"; fast_pattern:3,4; http_uri; offset:10; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest132(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:!\"oneonetwo\"; fast_pattern:3,4; http_uri; depth:10; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest133(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; content:!\"oneonetwo\"; fast_pattern:3,4; http_uri; uricontent:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_uri fast_pattern tests ^ */ -/* http_client_body fast_pattern tests v */ - - -int DetectFastPatternTest134(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:!\"oneonetwo\"; fast_pattern:3,4; http_client_body; content:\"three\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest135(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; fast_pattern:only; http_client_body; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest136(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_client_body; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest137(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest138(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest139(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; fast_pattern:only; http_client_body; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest140(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; distance:10; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest141(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; fast_pattern:only; http_client_body; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest142(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; within:10; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest143(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; fast_pattern:only; http_client_body; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest144(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; offset:10; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest145(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; fast_pattern:only; http_client_body; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest146(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; depth:10; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest147(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:!\"two\"; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest148(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content: \"one\"; http_client_body; content:\"two\"; http_client_body; distance:30; content:\"two\"; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest149(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; http_client_body; within:30; content:\"two\"; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest150(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; http_client_body; offset:30; content:\"two\"; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest151(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; http_client_body; depth:30; content:\"two\"; fast_pattern:only; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest152(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_client_body; content:\"two\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest153(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_client_body; content:!\"one\"; fast_pattern; http_client_body; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest154(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_client_body; content:!\"one\"; fast_pattern; http_client_body; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest155(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_client_body; content:!\"one\"; fast_pattern; http_client_body; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest156(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_client_body; content:!\"one\"; fast_pattern; http_client_body; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest157(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"oneonetwo\"; fast_pattern:3,4; http_client_body; content:\"three\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest158(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"oneonetwo\"; fast_pattern:3,4; http_client_body; content:\"three\"; http_client_body; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest159(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"oneonetwo\"; fast_pattern:3,4; http_client_body; content:\"three\"; http_client_body; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest160(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"oneonetwo\"; fast_pattern:3,4; http_client_body; content:\"three\"; http_client_body; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest161(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"oneonetwo\"; fast_pattern:3,4; http_client_body; content:\"three\"; http_client_body; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest162(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; http_client_body; distance:10; content:\"oneonethree\"; fast_pattern:3,4; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest163(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; http_client_body; within:10; content:\"oneonethree\"; fast_pattern:3,4; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest164(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; http_client_body; offset:10; content:\"oneonethree\"; fast_pattern:3,4; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest165(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; http_client_body; depth:10; content:\"oneonethree\"; fast_pattern:3,4; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest166(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; fast_pattern:65977,4; http_client_body; content:\"three\"; http_client_body; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest167(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"oneonetwo\"; fast_pattern:3,65977; http_client_body; content:\"three\"; distance:10; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest168(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:\"two\"; fast_pattern:65534,4; http_client_body; content:\"three\"; http_client_body; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest169(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:!\"oneonetwo\"; fast_pattern:3,4; http_client_body; content:\"three\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest170(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:!\"oneonetwo\"; fast_pattern:3,4; http_client_body; distance:10; content:\"three\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest171(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:!\"oneonetwo\"; fast_pattern:3,4; http_client_body; within:10; content:\"three\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest172(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:!\"twooneone\"; fast_pattern:3,4; http_client_body; offset:10; content:\"three\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest173(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:!\"oneonetwo\"; fast_pattern:3,4; http_client_body; depth:10; content:\"three\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest174(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; content:!\"oneonetwo\"; fast_pattern:3,4; http_client_body; content:\"three\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_client_body fast_pattern tests ^ */ -/* content fast_pattern tests v */ - - -int DetectFastPatternTest175(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; content:!\"one\"; distance:20; fast_pattern; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest176(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; content:!\"one\"; within:20; fast_pattern; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest177(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; content:!\"one\"; offset:20; fast_pattern; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest178(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; content:!\"one\"; depth:20; fast_pattern; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/* content fast_pattern tests ^ */ -/* http_header fast_pattern tests v */ - - -int DetectFastPatternTest179(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_header; " - "content:\"three\"; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest180(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; fast_pattern:only; http_header; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest181(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_header; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest182(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest183(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest184(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; fast_pattern:only; http_header; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest185(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; distance:10; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest186(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; fast_pattern:only; http_header; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest187(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; within:10; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest188(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; fast_pattern:only; http_header; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest189(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; offset:10; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest190(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; fast_pattern:only; http_header; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest191(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; depth:10; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest192(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:!\"two\"; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest193(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content: \"one\"; http_header; content:\"two\"; http_header; distance:30; content:\"two\"; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest194(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; http_header; within:30; content:\"two\"; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest195(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; http_header; offset:30; content:\"two\"; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest196(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; http_header; depth:30; content:\"two\"; fast_pattern:only; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest197(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_header; content:\"two\"; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest198(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_header; content:!\"one\"; fast_pattern; http_header; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest199(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_header; content:!\"one\"; fast_pattern; http_header; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest200(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_header; content:!\"one\"; fast_pattern; http_header; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest201(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_header; content:!\"one\"; fast_pattern; http_header; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest202(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"oneonetwo\"; fast_pattern:3,4; http_header; content:\"three\"; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest203(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"oneonetwo\"; fast_pattern:3,4; http_header; content:\"three\"; http_header; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest204(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"oneonetwo\"; fast_pattern:3,4; http_header; content:\"three\"; http_header; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest205(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"oneonetwo\"; fast_pattern:3,4; http_header; content:\"three\"; http_header; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest206(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"oneonetwo\"; fast_pattern:3,4; http_header; content:\"three\"; http_header; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest207(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; http_header; distance:10; content:\"oneonethree\"; fast_pattern:3,4; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest208(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; http_header; within:10; content:\"oneonethree\"; fast_pattern:3,4; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest209(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; http_header; offset:10; content:\"oneonethree\"; fast_pattern:3,4; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest210(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; http_header; depth:10; content:\"oneonethree\"; fast_pattern:3,4; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest211(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; fast_pattern:65977,4; http_header; content:\"three\"; http_header; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest212(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"oneonetwo\"; fast_pattern:3,65977; http_header; content:\"three\"; distance:10; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest213(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:\"two\"; fast_pattern:65534,4; http_header; content:\"three\"; http_header; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest214(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_header; content:\"three\"; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest215(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_header; distance:10; content:\"three\"; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest216(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_header; within:10; content:\"three\"; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest217(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_header; offset:10; content:\"three\"; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest218(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_header; depth:10; content:\"three\"; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest219(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_header; content:\"three\"; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_header fast_pattern tests ^ */ -/* http_raw_header fast_pattern tests v */ - - -int DetectFastPatternTest220(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_header; " - "content:\"three\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest221(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"/one/\"; fast_pattern:only; http_raw_header; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest222(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"oneoneone\"; fast_pattern:3,4; http_raw_header; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest223(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest224(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"oneoneone\"; fast_pattern:3,4; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest225(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; fast_pattern:only; http_raw_header; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest226(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; distance:10; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest227(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; fast_pattern:only; http_raw_header; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest228(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; within:10; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest229(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; fast_pattern:only; http_raw_header; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest230(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; offset:10; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest231(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; fast_pattern:only; http_raw_header; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest232(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; depth:10; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest233(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:!\"two\"; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest234(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content: \"one\"; http_raw_header; content:\"two\"; http_raw_header; distance:30; content:\"two\"; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest235(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; http_raw_header; within:30; content:\"two\"; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest236(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; http_raw_header; offset:30; content:\"two\"; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest237(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; http_raw_header; depth:30; content:\"two\"; fast_pattern:only; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest238(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:!\"one\"; fast_pattern; http_raw_header; content:\"two\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest239(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"two\"; http_raw_header; content:!\"one\"; fast_pattern; http_raw_header; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest240(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"two\"; http_raw_header; content:!\"one\"; fast_pattern; http_raw_header; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest241(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"two\"; http_raw_header; content:!\"one\"; fast_pattern; http_raw_header; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest242(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"two\"; http_raw_header; content:!\"one\"; fast_pattern; http_raw_header; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest243(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"oneonetwo\"; fast_pattern:3,4; http_raw_header; content:\"three\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest244(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"oneonetwo\"; fast_pattern:3,4; http_raw_header; content:\"three\"; http_raw_header; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest245(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"oneonetwo\"; fast_pattern:3,4; http_raw_header; content:\"three\"; http_raw_header; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest246(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"oneonetwo\"; fast_pattern:3,4; http_raw_header; content:\"three\"; http_raw_header; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest247(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"oneonetwo\"; fast_pattern:3,4; http_raw_header; content:\"three\"; http_raw_header; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest248(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; http_raw_header; distance:10; content:\"oneonethree\"; fast_pattern:3,4; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest249(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; http_raw_header; within:10; content:\"oneonethree\"; fast_pattern:3,4; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest250(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; http_raw_header; offset:10; content:\"oneonethree\"; fast_pattern:3,4; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest251(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; http_raw_header; depth:10; content:\"oneonethree\"; fast_pattern:3,4; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest252(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; fast_pattern:65977,4; http_raw_header; content:\"three\"; http_raw_header; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest253(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"oneonetwo\"; fast_pattern:3,65977; http_raw_header; content:\"three\"; distance:10; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest254(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:\"two\"; fast_pattern:65534,4; http_raw_header; content:\"three\"; http_raw_header; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest255(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_header; content:\"three\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest256(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_header; distance:10; content:\"three\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest257(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_header; within:10; content:\"three\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest258(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_header; offset:10; content:\"three\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest259(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_header; depth:10; content:\"three\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest260(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_header; content:\"three\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_raw_header fast_pattern tests ^ */ -/* http_method fast_pattern tests v */ - - -int DetectFastPatternTest261(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_method; " - "content:\"three\"; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest262(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; fast_pattern:only; http_method; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HMDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest263(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_method; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HMDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest264(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HMDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest265(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HMDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest266(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; fast_pattern:only; http_method; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest267(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; distance:10; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest268(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; fast_pattern:only; http_method; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest269(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; within:10; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest270(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; fast_pattern:only; http_method; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest271(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; offset:10; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest272(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; fast_pattern:only; http_method; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest273(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; depth:10; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest274(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:!\"two\"; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest275(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content: \"one\"; http_method; content:\"two\"; http_method; distance:30; content:\"two\"; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest276(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; http_method; within:30; content:\"two\"; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest277(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; http_method; offset:30; content:\"two\"; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest278(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; http_method; depth:30; content:\"two\"; fast_pattern:only; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest279(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_method; content:\"two\"; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest280(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_method; content:!\"one\"; fast_pattern; http_method; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest281(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_method; content:!\"one\"; fast_pattern; http_method; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest282(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_method; content:!\"one\"; fast_pattern; http_method; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest283(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_method; content:!\"one\"; fast_pattern; http_method; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest284(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"oneonetwo\"; fast_pattern:3,4; http_method; content:\"three\"; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest285(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"oneonetwo\"; fast_pattern:3,4; http_method; content:\"three\"; http_method; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest286(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"oneonetwo\"; fast_pattern:3,4; http_method; content:\"three\"; http_method; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest287(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"oneonetwo\"; fast_pattern:3,4; http_method; content:\"three\"; http_method; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest288(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"oneonetwo\"; fast_pattern:3,4; http_method; content:\"three\"; http_method; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest289(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; http_method; distance:10; content:\"oneonethree\"; fast_pattern:3,4; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest290(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; http_method; within:10; content:\"oneonethree\"; fast_pattern:3,4; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest291(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; http_method; offset:10; content:\"oneonethree\"; fast_pattern:3,4; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest292(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; http_method; depth:10; content:\"oneonethree\"; fast_pattern:3,4; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest293(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; fast_pattern:65977,4; http_method; content:\"three\"; http_method; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest294(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"oneonetwo\"; fast_pattern:3,65977; http_method; content:\"three\"; distance:10; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest295(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:\"two\"; fast_pattern:65534,4; http_method; content:\"three\"; http_method; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest296(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:!\"oneonetwo\"; fast_pattern:3,4; http_method; content:\"three\"; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest297(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:!\"oneonetwo\"; fast_pattern:3,4; http_method; distance:10; content:\"three\"; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest298(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:!\"oneonetwo\"; fast_pattern:3,4; http_method; within:10; content:\"three\"; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest299(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:!\"oneonetwo\"; fast_pattern:3,4; http_method; offset:10; content:\"three\"; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest300(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:!\"oneonetwo\"; fast_pattern:3,4; http_method; depth:10; content:\"three\"; http_method; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest301(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_method; content:!\"oneonetwo\"; fast_pattern:3,4; http_method; content:\"three\"; http_method; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_method fast_pattern tests ^ */ -/* http_cookie fast_pattern tests v */ - - -int DetectFastPatternTest302(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_cookie; " - "content:\"three\"; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest303(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; fast_pattern:only; http_cookie; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest304(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_cookie; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest305(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest306(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest307(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; fast_pattern:only; http_cookie; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest308(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; distance:10; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest309(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; fast_pattern:only; http_cookie; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest310(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; within:10; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest311(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; fast_pattern:only; http_cookie; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest312(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; offset:10; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest313(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; fast_pattern:only; http_cookie; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest314(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; depth:10; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest315(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:!\"two\"; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest316(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content: \"one\"; http_cookie; content:\"two\"; http_cookie; distance:30; content:\"two\"; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest317(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; http_cookie; within:30; content:\"two\"; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest318(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; http_cookie; offset:30; content:\"two\"; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest319(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; http_cookie; depth:30; content:\"two\"; fast_pattern:only; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest320(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_cookie; content:\"two\"; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest321(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_cookie; content:!\"one\"; fast_pattern; http_cookie; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest322(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_cookie; content:!\"one\"; fast_pattern; http_cookie; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest323(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_cookie; content:!\"one\"; fast_pattern; http_cookie; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest324(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_cookie; content:!\"one\"; fast_pattern; http_cookie; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest325(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"oneonetwo\"; fast_pattern:3,4; http_cookie; content:\"three\"; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest326(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"oneonetwo\"; fast_pattern:3,4; http_cookie; content:\"three\"; http_cookie; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest327(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"oneonetwo\"; fast_pattern:3,4; http_cookie; content:\"three\"; http_cookie; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest328(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"oneonetwo\"; fast_pattern:3,4; http_cookie; content:\"three\"; http_cookie; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest329(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"oneonetwo\"; fast_pattern:3,4; http_cookie; content:\"three\"; http_cookie; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest330(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; http_cookie; distance:10; content:\"oneonethree\"; fast_pattern:3,4; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest331(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; http_cookie; within:10; content:\"oneonethree\"; fast_pattern:3,4; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest332(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; http_cookie; offset:10; content:\"oneonethree\"; fast_pattern:3,4; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest333(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; http_cookie; depth:10; content:\"oneonethree\"; fast_pattern:3,4; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest334(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; fast_pattern:65977,4; http_cookie; content:\"three\"; http_cookie; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest335(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"oneonetwo\"; fast_pattern:3,65977; http_cookie; content:\"three\"; distance:10; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest336(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:\"two\"; fast_pattern:65534,4; http_cookie; content:\"three\"; http_cookie; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest337(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:!\"oneonetwo\"; fast_pattern:3,4; http_cookie; content:\"three\"; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest338(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:!\"oneonetwo\"; fast_pattern:3,4; http_cookie; distance:10; content:\"three\"; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest339(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:!\"oneonetwo\"; fast_pattern:3,4; http_cookie; within:10; content:\"three\"; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest340(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:!\"oneonetwo\"; fast_pattern:3,4; http_cookie; offset:10; content:\"three\"; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest341(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:!\"oneonetwo\"; fast_pattern:3,4; http_cookie; depth:10; content:\"three2\"; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest342(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_cookie; content:!\"oneonetwo\"; fast_pattern:3,4; http_cookie; content:\"three\"; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_cookie fast_pattern tests ^ */ -/* http_raw_uri fast_pattern tests v */ - - -int DetectFastPatternTest343(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest344(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"/one/\"; fast_pattern:only; http_raw_uri; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest345(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_raw_uri; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest346(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest347(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest348(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; fast_pattern:only; http_raw_uri; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest349(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; distance:10; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest350(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; fast_pattern:only; http_raw_uri; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest351(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; within:10; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest352(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; fast_pattern:only; http_raw_uri; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest353(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; offset:10; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest354(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; fast_pattern:only; http_raw_uri; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest355(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; depth:10; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest356(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:!\"two\"; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest357(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content: \"one\"; http_raw_uri; " - "content:\"two\"; http_raw_uri; distance:30; " - "content:\"two\"; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest358(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; http_raw_uri; within:30; " - "content:\"two\"; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest359(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; http_raw_uri; offset:30; " - "content:\"two\"; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest360(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; http_raw_uri; depth:30; " - "content:\"two\"; fast_pattern:only; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest361(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_raw_uri; " - "content:\"two\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest362(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_raw_uri; " - "content:!\"one\"; fast_pattern; http_raw_uri; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest363(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_raw_uri; " - "content:!\"one\"; fast_pattern; http_raw_uri; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest364(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_raw_uri; " - "content:!\"one\"; fast_pattern; http_raw_uri; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest365(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_raw_uri; " - "content:!\"one\"; fast_pattern; http_raw_uri; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest366(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest367(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest368(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest369(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest370(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest371(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; http_raw_uri; distance:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest372(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; http_raw_uri; within:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest373(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; http_raw_uri; offset:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest374(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; http_raw_uri; depth:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest375(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; fast_pattern:65977,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest376(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"oneonetwo\"; fast_pattern:3,65977; http_raw_uri; " - "content:\"three\"; distance:10; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest377(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; fast_pattern:65534,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest378(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest379(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; distance:10; " - "content:\"three\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest380(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; within:10; " - "content:\"three\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest381(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; offset:10; " - "content:\"three\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest382(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; depth:10; " - "content:\"three\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest383(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_uri; " - "content:\"three\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_raw_uri fast_pattern tests ^ */ -/* http_stat_msg fast_pattern tests v */ - - -int DetectFastPatternTest384(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest385(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_stat_msg; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSMDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest386(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_stat_msg; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSMDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest387(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSMDMATCH]; - if (sm == NULL) { - goto end; - } - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest388(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSMDMATCH]; - if (sm == NULL) { - goto end; - } - - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest389(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; fast_pattern:only; http_stat_msg; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest390(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; distance:10; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest391(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; fast_pattern:only; http_stat_msg; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest392(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; within:10; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest393(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; fast_pattern:only; http_stat_msg; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest394(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; offset:10; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest395(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; fast_pattern:only; http_stat_msg; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest396(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; depth:10; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest397(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:!\"two\"; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest398(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\" one\"; http_stat_msg; " - "content:\"two\"; http_stat_msg; distance:30; " - "content:\"two\"; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest399(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; http_stat_msg; within:30; " - "content:\"two\"; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest400(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; http_stat_msg; offset:30; " - "content:\"two\"; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest401(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; http_stat_msg; depth:30; " - "content:\"two\"; fast_pattern:only; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest402(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_stat_msg; " - "content:\"two\"; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest403(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_stat_msg; " - "content:!\"one\"; fast_pattern; http_stat_msg; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest404(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_stat_msg; " - "content:!\"one\"; fast_pattern; http_stat_msg; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest405(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_stat_msg; " - "content:!\"one\"; fast_pattern; http_stat_msg; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest406(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_stat_msg; " - "content:!\"one\"; fast_pattern; http_stat_msg; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest407(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest408(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest409(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest410(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest411(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest412(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; http_stat_msg; distance:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest413(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; http_stat_msg; within:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest414(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; http_stat_msg; offset:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest415(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; http_stat_msg; depth:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest416(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; fast_pattern:65977,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest417(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"oneonetwo\"; fast_pattern:3,65977; http_stat_msg; " - "content:\"three\"; distance:10; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest418(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:\"two\"; fast_pattern:65534,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest419(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest420(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; distance:10; " - "content:\"three\"; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest421(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; within:10; " - "content:\"three\"; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest422(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; offset:10; " - "content:\"three\"; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest423(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; depth:10; " - "content:\"three\"; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest424(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_msg; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_msg; " - "content:\"three\"; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_stat_msg fast_pattern tests ^ */ -/* http_stat_code fast_pattern tests v */ - - -int DetectFastPatternTest425(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_code; " - "content:\"three\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest426(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_stat_code; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSCDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest427(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_stat_code; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSCDMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest428(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSCDMATCH]; - if (sm == NULL) { - goto end; - } - - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest429(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSCDMATCH]; - if (sm == NULL) { - goto end; - } - - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest430(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; fast_pattern:only; http_stat_code; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest431(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; distance:10; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest432(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; fast_pattern:only; http_stat_code; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest433(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; within:10; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest434(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; fast_pattern:only; http_stat_code; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest435(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; offset:10; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest436(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; fast_pattern:only; http_stat_code; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest437(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; depth:10; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest438(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:!\"two\"; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest439(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\" one\"; http_stat_code; " - "content:\"two\"; http_stat_code; distance:30; " - "content:\"two\"; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest440(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; http_stat_code; within:30; " - "content:\"two\"; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest441(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; http_stat_code; offset:30; " - "content:\"two\"; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest442(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; http_stat_code; depth:30; " - "content:\"two\"; fast_pattern:only; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest443(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_stat_code; " - "content:\"two\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest444(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_stat_code; " - "content:!\"one\"; fast_pattern; http_stat_code; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest445(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_stat_code; " - "content:!\"one\"; fast_pattern; http_stat_code; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest446(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_stat_code; " - "content:!\"one\"; fast_pattern; http_stat_code; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest447(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_stat_code; " - "content:!\"one\"; fast_pattern; http_stat_code; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest448(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_code; " - "content:\"three\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest449(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_code; " - "content:\"three\"; http_stat_code; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest450(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_code; " - "content:\"three\"; http_stat_code; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest451(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_code; " - "content:\"three\"; http_stat_code; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest452(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_stat_code; " - "content:\"three\"; http_stat_code; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest453(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; http_stat_code; distance:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest454(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; http_stat_code; within:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest455(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; http_stat_code; offset:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest456(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; http_stat_code; depth:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest457(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; fast_pattern:65977,4; http_stat_code; " - "content:\"three\"; http_stat_code; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest458(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"oneonetwo\"; fast_pattern:3,65977; http_stat_code; " - "content:\"three\"; distance:10; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest459(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:\"two\"; fast_pattern:65534,4; http_stat_code; " - "content:\"three\"; http_stat_code; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest460(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_code; " - "content:\"three\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest461(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_code; distance:10; " - "content:\"three\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest462(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_code; within:10; " - "content:\"three\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest463(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_code; offset:10; " - "content:\"three\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest464(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_code; depth:10; " - "content:\"three\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest465(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_stat_code; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_stat_code; " - "content:\"three\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_stat_code fast_pattern tests ^ */ -/* http_server_body fast_pattern tests v */ - - -int DetectFastPatternTest466(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_server_body; " - "content:\"three\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest467(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_server_body; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest468(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_server_body; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest469(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm == NULL) { - goto end; - } - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest470(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm == NULL) { - goto end; - } - - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest471(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; fast_pattern:only; http_server_body; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest472(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; distance:10; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest473(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; fast_pattern:only; http_server_body; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest474(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; within:10; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest475(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; fast_pattern:only; http_server_body; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest476(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; offset:10; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest477(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; fast_pattern:only; http_server_body; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest478(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; depth:10; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest479(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:!\"two\"; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest480(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\" one\"; http_server_body; " - "content:\"two\"; http_server_body; distance:30; " - "content:\"two\"; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest481(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; http_server_body; within:30; " - "content:\"two\"; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest482(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; http_server_body; offset:30; " - "content:\"two\"; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest483(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; http_server_body; depth:30; " - "content:\"two\"; fast_pattern:only; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest484(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_server_body; " - "content:\"two\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest485(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_server_body; " - "content:!\"one\"; fast_pattern; http_server_body; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest486(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_server_body; " - "content:!\"one\"; fast_pattern; http_server_body; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest487(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_server_body; " - "content:!\"one\"; fast_pattern; http_server_body; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest488(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_server_body; " - "content:!\"one\"; fast_pattern; http_server_body; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest489(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_server_body; " - "content:\"three\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest490(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_server_body; " - "content:\"three\"; http_server_body; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest491(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_server_body; " - "content:\"three\"; http_server_body; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest492(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_server_body; " - "content:\"three\"; http_server_body; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest493(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_server_body; " - "content:\"three\"; http_server_body; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest494(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; http_server_body; distance:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest495(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; http_server_body; within:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest496(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; http_server_body; offset:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest497(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; http_server_body; depth:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest498(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; fast_pattern:65977,4; http_server_body; " - "content:\"three\"; http_server_body; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest499(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"oneonetwo\"; fast_pattern:3,65977; http_server_body; " - "content:\"three\"; distance:10; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest500(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; fast_pattern:65534,4; http_server_body; " - "content:\"three\"; http_server_body; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest501(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_server_body; " - "content:\"three\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest502(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_server_body; distance:10; " - "content:\"three\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest503(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_server_body; within:10; " - "content:\"three\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest504(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_server_body; offset:10; " - "content:\"three\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest505(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_server_body; depth:10; " - "content:\"three\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest506(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_server_body; " - "content:\"three\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_server_body fast_pattern tests ^ */ -/* file_data fast_pattern tests v */ - - -int DetectFastPatternTest507(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:!\"oneonetwo\"; fast_pattern:3,4; " - "content:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest508(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; fast_pattern:only; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest509(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"oneoneone\"; fast_pattern:3,4; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest510(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm == NULL) { - goto end; - } - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest511(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"oneoneone\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm == NULL) { - goto end; - } - - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest512(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; fast_pattern:only; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest513(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; distance:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest514(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; fast_pattern:only; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest515(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; within:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest516(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; fast_pattern:only; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest517(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; offset:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest518(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; fast_pattern:only; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest519(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; depth:10; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest520(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:!\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest521(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\" one\"; " - "content:\"two\"; distance:30; " - "content:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest522(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; within:30; " - "content:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest523(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; offset:30; " - "content:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest524(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; depth:30; " - "content:\"two\"; fast_pattern:only; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest525(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:!\"one\"; fast_pattern; " - "content:\"two\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest526(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"two\"; " - "content:!\"one\"; fast_pattern; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest527(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"two\"; " - "content:!\"one\"; fast_pattern; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest528(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"two\"; " - "content:!\"one\"; fast_pattern; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest529(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"two\"; " - "content:!\"one\"; fast_pattern; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest530(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"oneonetwo\"; fast_pattern:3,4; " - "content:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest531(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"oneonetwo\"; fast_pattern:3,4; " - "content:\"three\"; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest532(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"oneonetwo\"; fast_pattern:3,4; " - "content:\"three\"; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest533(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"oneonetwo\"; fast_pattern:3,4; " - "content:\"three\"; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest534(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"oneonetwo\"; fast_pattern:3,4; " - "content:\"three\"; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest535(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; distance:10; " - "content:\"oneonethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest536(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; within:10; " - "content:\"oneonethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest537(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; offset:10; " - "content:\"oneonethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest538(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; depth:10; " - "content:\"oneonethree\"; fast_pattern:3,4; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest539(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; fast_pattern:65977,4; " - "content:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest540(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"oneonetwo\"; fast_pattern:3,65977; " - "content:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest541(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:\"two\"; fast_pattern:65534,4; " - "content:\"three\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest542(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:!\"oneonetwo\"; fast_pattern:3,4; " - "content:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest543(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:!\"oneonetwo\"; fast_pattern:3,4; distance:10; " - "content:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest544(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:!\"oneonetwo\"; fast_pattern:3,4; within:10; " - "content:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest545(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:!\"oneonetwo\"; fast_pattern:3,4; offset:10; " - "content:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest546(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:!\"oneonetwo\"; fast_pattern:3,4; depth:10; " - "content:\"three\"; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest547(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(file_data; content:\"one\"; " - "content:!\"oneonetwo\"; fast_pattern:3,4; " - "content:\"three\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* file_data fast_pattern tests ^ */ -/* http_user_agent fast_pattern tests v */ - - -int DetectFastPatternTest548(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_user_agent; " - "content:\"three\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest549(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_user_agent; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest550(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_user_agent; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH]; - if (sm != NULL) { - if ( ((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest551(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH]; - if (sm == NULL) { - goto end; - } - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest552(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH]; - if (sm == NULL) { - goto end; - } - - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest553(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; fast_pattern:only; http_user_agent; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest554(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; distance:10; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest555(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; fast_pattern:only; http_user_agent; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest556(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; within:10; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest557(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; fast_pattern:only; http_user_agent; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest558(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; offset:10; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest559(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; fast_pattern:only; http_user_agent; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest560(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; depth:10; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest561(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:!\"two\"; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest562(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\" one\"; http_user_agent; " - "content:\"two\"; http_user_agent; distance:30; " - "content:\"two\"; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest563(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; http_user_agent; within:30; " - "content:\"two\"; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest564(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; http_user_agent; offset:30; " - "content:\"two\"; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest565(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; http_user_agent; depth:30; " - "content:\"two\"; fast_pattern:only; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest566(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_user_agent; " - "content:\"two\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest567(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_user_agent; " - "content:!\"one\"; fast_pattern; http_user_agent; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest568(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_user_agent; " - "content:!\"one\"; fast_pattern; http_user_agent; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest569(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_user_agent; " - "content:!\"one\"; fast_pattern; http_user_agent; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest570(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_user_agent; " - "content:!\"one\"; fast_pattern; http_user_agent; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest571(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_user_agent; " - "content:\"three\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest572(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_user_agent; " - "content:\"three\"; http_user_agent; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest573(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_user_agent; " - "content:\"three\"; http_user_agent; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest574(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_user_agent; " - "content:\"three\"; http_user_agent; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest575(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_user_agent; " - "content:\"three\"; http_user_agent; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest576(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; http_user_agent; distance:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest577(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; http_user_agent; within:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest578(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; http_user_agent; offset:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest579(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; http_user_agent; depth:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest580(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; fast_pattern:65977,4; http_user_agent; " - "content:\"three\"; http_user_agent; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest581(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"oneonetwo\"; fast_pattern:3,65977; http_user_agent; " - "content:\"three\"; distance:10; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest582(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; fast_pattern:65534,4; http_user_agent; " - "content:\"three\"; http_user_agent; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest583(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_user_agent; " - "content:\"three\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest584(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_user_agent; distance:10; " - "content:\"three\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest585(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_user_agent; within:10; " - "content:\"three\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest586(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_user_agent; offset:10; " - "content:\"three\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest587(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_user_agent; depth:10; " - "content:\"three\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest588(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_user_agent; " - "content:\"three\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_user_agent fast_pattern tests ^ */ -/* http_host fast_pattern tests v */ - - -int DetectFastPatternTest589(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_host; " - "content:\"three\"; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest590(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_host; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH]; - if (sm != NULL) { - if ( (((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN)) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest591(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_host; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH]; - if (sm != NULL) { - if ( (((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN)) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest592(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH]; - if (sm == NULL) { - goto end; - } - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest593(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH]; - if (sm == NULL) { - goto end; - } - - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest594(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; fast_pattern:only; http_host; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest595(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; distance:10; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest596(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; fast_pattern:only; http_host; within:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest597(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; within:10; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest598(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; fast_pattern:only; http_host; offset:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest599(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; offset:10; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest600(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; fast_pattern:only; http_host; depth:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest601(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; depth:10; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest602(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:!\"two\"; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest603(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\" one\"; http_host; " - "content:\"two\"; http_host; distance:30; " - "content:\"two\"; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest604(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; http_host; within:30; " - "content:\"two\"; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest605(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; http_host; offset:30; " - "content:\"two\"; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest606(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; http_host; depth:30; " - "content:\"two\"; fast_pattern:only; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest607(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_host; " - "content:\"two\"; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest608(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_host; " - "content:!\"one\"; fast_pattern; http_host; distance:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest609(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_host; " - "content:!\"one\"; fast_pattern; http_host; within:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest610(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_host; " - "content:!\"one\"; fast_pattern; http_host; offset:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest611(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_host; " - "content:!\"one\"; fast_pattern; http_host; depth:20; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest612(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_host; " - "content:\"three\"; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest613(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_host; " - "content:\"three\"; http_host; distance:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest614(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_host; " - "content:\"three\"; http_host; within:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest615(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_host; " - "content:\"three\"; http_host; offset:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest616(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_host; " - "content:\"three\"; http_host; depth:30; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest617(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; http_host; distance:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest618(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; http_host; within:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest619(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; http_host; offset:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest620(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; http_host; depth:10; " - "content:\"oneonethree\"; fast_pattern:3,4; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest621(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; fast_pattern:65977,4; http_host; " - "content:\"three\"; http_host; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest622(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"oneonetwo\"; fast_pattern:3,65977; http_host; " - "content:\"three\"; distance:10; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest623(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; fast_pattern:65534,4; http_host; " - "content:\"three\"; http_host; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest624(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_host; " - "content:\"three\"; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest625(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_host; distance:10; " - "content:\"three\"; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest626(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_host; within:10; " - "content:\"three\"; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest627(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_host; offset:10; " - "content:\"three\"; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest628(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_host; depth:10; " - "content:\"three\"; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest629(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_host; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_host; " - "content:\"three\"; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/* http_host fast_pattern tests ^ */ -/* http_rawhost fast_pattern tests v */ - - -int DetectFastPatternTest630(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NEGATED && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest631(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_raw_host; nocase; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH]; - if (sm != NULL) { - if ( (((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) && - (((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_NOCASE)) { - result = 1; - } else { - result = 0; - } - } - - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a fast_pattern is registered in a Signature for uricontent. - */ -int DetectFastPatternTest632(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_raw_host; nocase; " - "msg:\"Testing fast_pattern\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH]; - if (sm != NULL) { - if ( (((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN) && - (((DetectContentData *)sm->ctx)->flags & - DETECT_CONTENT_NOCASE)) { - result = 1; - } else { - result = 0; - } - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest633(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH]; - if (sm == NULL) { - goto end; - } - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest634(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"oneoneone\"; fast_pattern:3,4; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH]; - if (sm == NULL) { - goto end; - } - - DetectContentData *ud = (DetectContentData *)sm->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest635(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; fast_pattern:only; http_raw_host; distance:10; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest636(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; distance:10; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest637(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; fast_pattern:only; http_raw_host; within:10; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest638(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; within:10; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest639(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; fast_pattern:only; http_raw_host; offset:10; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest640(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; offset:10; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest641(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; fast_pattern:only; http_raw_host; depth:10; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest642(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; depth:10; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest643(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:!\"two\"; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest644(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\" one\"; http_raw_host; nocase; " - "content:\"two\"; http_raw_host; distance:30; nocase; " - "content:\"two\"; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest645(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; http_raw_host; within:30; nocase; " - "content:\"two\"; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest646(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; http_raw_host; offset:30; nocase; " - "content:\"two\"; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest647(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; http_raw_host; depth:30; nocase; " - "content:\"two\"; fast_pattern:only; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest648(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:!\"one\"; fast_pattern; http_raw_host; nocase; " - "content:\"two\"; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) && - ud->fp_chop_offset == 0 && - ud->fp_chop_len == 0) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest649(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_raw_host; nocase; " - "content:!\"one\"; fast_pattern; http_raw_host; distance:20; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest650(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_raw_host; nocase; " - "content:!\"one\"; fast_pattern; http_raw_host; within:20; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest651(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_raw_host; nocase; " - "content:!\"one\"; fast_pattern; http_raw_host; offset:20; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest652(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_raw_host; nocase; " - "content:!\"one\"; fast_pattern; http_raw_host; depth:20; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest653(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest654(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; distance:30; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest655(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; within:30; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest656(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; offset:30; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest657(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"oneonetwo\"; fast_pattern:3,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; depth:30; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest658(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; http_raw_host; distance:10; nocase; " - "content:\"oneonethree\"; fast_pattern:3,4; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest659(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; http_raw_host; within:10; nocase; " - "content:\"oneonethree\"; fast_pattern:3,4; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest660(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; http_raw_host; offset:10; nocase; " - "content:\"oneonethree\"; fast_pattern:3,4; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest661(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; http_raw_host; depth:10; nocase; " - "content:\"oneonethree\"; fast_pattern:3,4; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest662(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; fast_pattern:65977,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; distance:10; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest663(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"oneonetwo\"; fast_pattern:3,65977; http_raw_host; nocase; " - "content:\"three\"; distance:10; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest664(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:\"two\"; fast_pattern:65534,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; distance:10; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest665(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest666(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_host; distance:10; nocase; " - "content:\"three\"; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest667(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_host; within:10; nocase; " - "content:\"three\"; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest668(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_host; offset:10; nocase; " - "content:\"three\"; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest669(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_host; depth:10; nocase; " - "content:\"three\"; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectFastPatternTest670(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; " - "content:!\"oneonetwo\"; fast_pattern:3,4; http_raw_host; nocase; " - "content:\"three\"; http_raw_host; nocase; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - DetectContentData *ud = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - if (ud->flags & DETECT_CONTENT_FAST_PATTERN && - ud->flags & DETECT_CONTENT_NOCASE && - ud->flags & DETECT_CONTENT_NEGATED && - !(ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) && - ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP && - ud->fp_chop_offset == 3 && - ud->fp_chop_len == 4) { - result = 1; - } else { - result = 0; - } - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - - -/** - * Unittest to check - * - if we assign different content_ids to duplicate patterns, but one of the - * patterns has a fast_pattern chop set. - * - if 2 unique patterns get unique ids. - * - if 2 duplicate patterns, with no chop set get unique ids. - */ -int DetectFastPatternTest671(void) -{ - int no_of_sigs = 6; - int result = 0; - char *sigs[no_of_sigs]; - Signature *s[no_of_sigs]; - Signature *sig = NULL; - DetectEngineCtx *de_ctx = NULL; - DetectContentData *cd = NULL; - SigMatch *sm = NULL; - int i = 0; - - sigs[0] = "alert tcp any any -> any any " - "(content:\"onetwothreefour\"; sid:1;)"; - sigs[1] = "alert tcp any any -> any any " - "(content:\"onetwothreefour\"; sid:2;)"; - sigs[2] = "alert tcp any any -> any any " - "(content:\"uniquepattern\"; sid:3;)"; - sigs[3] = "alert tcp any any -> any any " - "(content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)"; - sigs[4] = "alert tcp any any -> any any " - "(content:\"twoth\"; sid:5;)"; - sigs[5] = "alert tcp any any -> any any " - "(content:\"onetwothreefour\"; fast_pattern:0,15; sid:6;)"; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("DetectEngineCtxInit() failure\n"); - goto end; - } - de_ctx->flags |= DE_QUIET; - - i = 0; - s[i] = SigInit(de_ctx, sigs[i]); - de_ctx->sig_list = sig = s[i]; - if (sig == NULL) { - printf("SigInit(de_ctx, sig1) failure\n"); - goto end; - } - i++; - for ( ; i < no_of_sigs; i++) { - s[i] = SigInit(de_ctx, sigs[i]); - sig->next = s[i]; - sig = sig->next; - if (sig == NULL) { - printf("SigInit(de_ctx, sig[%d]) failure\n", i); - goto end; - } - } - - SigGroupBuild(de_ctx); - - sm = s[0]->sm_lists[DETECT_SM_LIST_PMATCH]; - cd = (DetectContentData *)sm->ctx; - if (cd->id != 0) { - printf("sm = s[0]->sm_lists[DETECT_SM_LIST_PMATCH] failure\n"); - goto end; - } - - sm = s[1]->sm_lists[DETECT_SM_LIST_PMATCH]; - cd = (DetectContentData *)sm->ctx; - if (cd->id != 0) { - printf("sm = s[1]->sm_lists[DETECT_SM_LIST_PMATCH] failure\n"); - goto end; - } - - sm = s[2]->sm_lists[DETECT_SM_LIST_PMATCH]; - cd = (DetectContentData *)sm->ctx; - if (cd->id != 1) { - printf("sm = s[2]->sm_lists[DETECT_SM_LIST_PMATCH] failure\n"); - goto end; - } - - sm = s[3]->sm_lists[DETECT_SM_LIST_PMATCH]; - cd = (DetectContentData *)sm->ctx; - if (cd->id != 2) { - printf("sm = s[3]->sm_lists[DETECT_SM_LIST_PMATCH] failure\n"); - goto end; - } - - sm = s[4]->sm_lists[DETECT_SM_LIST_PMATCH]; - cd = (DetectContentData *)sm->ctx; - if (cd->id != 2) { - printf("sm = s[4]->sm_lists[DETECT_SM_LIST_PMATCH] failure\n"); - goto end; - } - - sm = s[5]->sm_lists[DETECT_SM_LIST_PMATCH]; - cd = (DetectContentData *)sm->ctx; - if (cd->id != 0) { - printf("sm = s[5]->sm_lists[DETECT_SM_LIST_PMATCH] failure\n"); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - return result; -} - -#endif - -void DetectFastPatternRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("DetectFastPatternTest01", DetectFastPatternTest01, 1); - UtRegisterTest("DetectFastPatternTest02", DetectFastPatternTest02, 1); - UtRegisterTest("DetectFastPatternTest03", DetectFastPatternTest03, 1); - UtRegisterTest("DetectFastPatternTest04", DetectFastPatternTest04, 1); - UtRegisterTest("DetectFastPatternTest05", DetectFastPatternTest05, 1); - UtRegisterTest("DetectFastPatternTest06", DetectFastPatternTest06, 1); - UtRegisterTest("DetectFastPatternTest07", DetectFastPatternTest07, 1); - UtRegisterTest("DetectFastPatternTest08", DetectFastPatternTest08, 1); - UtRegisterTest("DetectFastPatternTest09", DetectFastPatternTest09, 1); - UtRegisterTest("DetectFastPatternTest10", DetectFastPatternTest10, 1); - UtRegisterTest("DetectFastPatternTest11", DetectFastPatternTest11, 1); - UtRegisterTest("DetectFastPatternTest12", DetectFastPatternTest12, 1); - UtRegisterTest("DetectFastPatternTest13", DetectFastPatternTest13, 1); - UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14, 1); - UtRegisterTest("DetectFastPatternTest15", DetectFastPatternTest15, 1); - UtRegisterTest("DetectFastPatternTest16", DetectFastPatternTest16, 1); - UtRegisterTest("DetectFastPatternTest17", DetectFastPatternTest17, 1); - UtRegisterTest("DetectFastPatternTest18", DetectFastPatternTest18, 1); - UtRegisterTest("DetectFastPatternTest19", DetectFastPatternTest19, 1); - UtRegisterTest("DetectFastPatternTest20", DetectFastPatternTest20, 1); - UtRegisterTest("DetectFastPatternTest21", DetectFastPatternTest21, 1); - UtRegisterTest("DetectFastPatternTest22", DetectFastPatternTest22, 1); - UtRegisterTest("DetectFastPatternTest23", DetectFastPatternTest23, 1); - UtRegisterTest("DetectFastPatternTest24", DetectFastPatternTest24, 1); - UtRegisterTest("DetectFastPatternTest25", DetectFastPatternTest25, 1); - UtRegisterTest("DetectFastPatternTest26", DetectFastPatternTest26, 1); - UtRegisterTest("DetectFastPatternTest27", DetectFastPatternTest27, 1); - UtRegisterTest("DetectFastPatternTest28", DetectFastPatternTest28, 1); - UtRegisterTest("DetectFastPatternTest29", DetectFastPatternTest29, 1); - UtRegisterTest("DetectFastPatternTest30", DetectFastPatternTest30, 1); - UtRegisterTest("DetectFastPatternTest31", DetectFastPatternTest31, 1); - UtRegisterTest("DetectFastPatternTest32", DetectFastPatternTest32, 1); - UtRegisterTest("DetectFastPatternTest33", DetectFastPatternTest33, 1); - UtRegisterTest("DetectFastPatternTest34", DetectFastPatternTest34, 1); - UtRegisterTest("DetectFastPatternTest35", DetectFastPatternTest35, 1); - UtRegisterTest("DetectFastPatternTest36", DetectFastPatternTest36, 1); - UtRegisterTest("DetectFastPatternTest37", DetectFastPatternTest37, 1); - UtRegisterTest("DetectFastPatternTest38", DetectFastPatternTest38, 1); - UtRegisterTest("DetectFastPatternTest39", DetectFastPatternTest39, 1); - UtRegisterTest("DetectFastPatternTest40", DetectFastPatternTest40, 1); - UtRegisterTest("DetectFastPatternTest41", DetectFastPatternTest41, 1); - UtRegisterTest("DetectFastPatternTest42", DetectFastPatternTest42, 1); - UtRegisterTest("DetectFastPatternTest43", DetectFastPatternTest43, 1); - UtRegisterTest("DetectFastPatternTest44", DetectFastPatternTest44, 1); - UtRegisterTest("DetectFastPatternTest45", DetectFastPatternTest45, 1); - UtRegisterTest("DetectFastPatternTest46", DetectFastPatternTest46, 1); - UtRegisterTest("DetectFastPatternTest47", DetectFastPatternTest47, 1); - UtRegisterTest("DetectFastPatternTest48", DetectFastPatternTest48, 1); - UtRegisterTest("DetectFastPatternTest49", DetectFastPatternTest49, 1); - UtRegisterTest("DetectFastPatternTest50", DetectFastPatternTest50, 1); - UtRegisterTest("DetectFastPatternTest51", DetectFastPatternTest51, 1); - UtRegisterTest("DetectFastPatternTest52", DetectFastPatternTest52, 1); - UtRegisterTest("DetectFastPatternTest53", DetectFastPatternTest53, 1); - /* content fast_pattern tests ^ */ - /* uricontent fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest54", DetectFastPatternTest54, 1); - UtRegisterTest("DetectFastPatternTest55", DetectFastPatternTest55, 1); - UtRegisterTest("DetectFastPatternTest56", DetectFastPatternTest56, 1); - UtRegisterTest("DetectFastPatternTest57", DetectFastPatternTest57, 1); - UtRegisterTest("DetectFastPatternTest58", DetectFastPatternTest58, 1); - UtRegisterTest("DetectFastPatternTest59", DetectFastPatternTest59, 1); - UtRegisterTest("DetectFastPatternTest60", DetectFastPatternTest60, 1); - UtRegisterTest("DetectFastPatternTest61", DetectFastPatternTest61, 1); - UtRegisterTest("DetectFastPatternTest62", DetectFastPatternTest62, 1); - UtRegisterTest("DetectFastPatternTest63", DetectFastPatternTest63, 1); - UtRegisterTest("DetectFastPatternTest64", DetectFastPatternTest64, 1); - UtRegisterTest("DetectFastPatternTest65", DetectFastPatternTest65, 1); - UtRegisterTest("DetectFastPatternTest66", DetectFastPatternTest66, 1); - UtRegisterTest("DetectFastPatternTest67", DetectFastPatternTest67, 1); - UtRegisterTest("DetectFastPatternTest68", DetectFastPatternTest68, 1); - UtRegisterTest("DetectFastPatternTest69", DetectFastPatternTest69, 1); - UtRegisterTest("DetectFastPatternTest70", DetectFastPatternTest70, 1); - UtRegisterTest("DetectFastPatternTest71", DetectFastPatternTest71, 1); - UtRegisterTest("DetectFastPatternTest72", DetectFastPatternTest72, 1); - UtRegisterTest("DetectFastPatternTest73", DetectFastPatternTest73, 1); - UtRegisterTest("DetectFastPatternTest74", DetectFastPatternTest74, 1); - UtRegisterTest("DetectFastPatternTest75", DetectFastPatternTest75, 1); - UtRegisterTest("DetectFastPatternTest76", DetectFastPatternTest76, 1); - UtRegisterTest("DetectFastPatternTest77", DetectFastPatternTest77, 1); - UtRegisterTest("DetectFastPatternTest78", DetectFastPatternTest78, 1); - UtRegisterTest("DetectFastPatternTest79", DetectFastPatternTest79, 1); - UtRegisterTest("DetectFastPatternTest80", DetectFastPatternTest80, 1); - UtRegisterTest("DetectFastPatternTest81", DetectFastPatternTest81, 1); - UtRegisterTest("DetectFastPatternTest82", DetectFastPatternTest82, 1); - UtRegisterTest("DetectFastPatternTest83", DetectFastPatternTest83, 1); - UtRegisterTest("DetectFastPatternTest84", DetectFastPatternTest84, 1); - UtRegisterTest("DetectFastPatternTest85", DetectFastPatternTest85, 1); - UtRegisterTest("DetectFastPatternTest86", DetectFastPatternTest86, 1); - UtRegisterTest("DetectFastPatternTest87", DetectFastPatternTest87, 1); - UtRegisterTest("DetectFastPatternTest88", DetectFastPatternTest88, 1); - UtRegisterTest("DetectFastPatternTest89", DetectFastPatternTest89, 1); - UtRegisterTest("DetectFastPatternTest90", DetectFastPatternTest90, 1); - UtRegisterTest("DetectFastPatternTest91", DetectFastPatternTest91, 1); - UtRegisterTest("DetectFastPatternTest92", DetectFastPatternTest92, 1); - /* uricontent fast_pattern tests ^ */ - /* http_uri fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest93", DetectFastPatternTest93, 1); - UtRegisterTest("DetectFastPatternTest94", DetectFastPatternTest94, 1); - UtRegisterTest("DetectFastPatternTest95", DetectFastPatternTest95, 1); - UtRegisterTest("DetectFastPatternTest96", DetectFastPatternTest96, 1); - UtRegisterTest("DetectFastPatternTest97", DetectFastPatternTest97, 1); - UtRegisterTest("DetectFastPatternTest98", DetectFastPatternTest98, 1); - UtRegisterTest("DetectFastPatternTest99", DetectFastPatternTest99, 1); - UtRegisterTest("DetectFastPatternTest100", DetectFastPatternTest100, 1); - UtRegisterTest("DetectFastPatternTest101", DetectFastPatternTest101, 1); - UtRegisterTest("DetectFastPatternTest102", DetectFastPatternTest102, 1); - UtRegisterTest("DetectFastPatternTest103", DetectFastPatternTest103, 1); - UtRegisterTest("DetectFastPatternTest104", DetectFastPatternTest104, 1); - UtRegisterTest("DetectFastPatternTest105", DetectFastPatternTest105, 1); - UtRegisterTest("DetectFastPatternTest106", DetectFastPatternTest106, 1); - UtRegisterTest("DetectFastPatternTest107", DetectFastPatternTest107, 1); - UtRegisterTest("DetectFastPatternTest108", DetectFastPatternTest108, 1); - UtRegisterTest("DetectFastPatternTest109", DetectFastPatternTest109, 1); - UtRegisterTest("DetectFastPatternTest110", DetectFastPatternTest110, 1); - UtRegisterTest("DetectFastPatternTest111", DetectFastPatternTest111, 1); - UtRegisterTest("DetectFastPatternTest112", DetectFastPatternTest112, 1); - UtRegisterTest("DetectFastPatternTest113", DetectFastPatternTest113, 1); - UtRegisterTest("DetectFastPatternTest114", DetectFastPatternTest114, 1); - UtRegisterTest("DetectFastPatternTest115", DetectFastPatternTest115, 1); - UtRegisterTest("DetectFastPatternTest116", DetectFastPatternTest116, 1); - UtRegisterTest("DetectFastPatternTest117", DetectFastPatternTest117, 1); - UtRegisterTest("DetectFastPatternTest118", DetectFastPatternTest118, 1); - UtRegisterTest("DetectFastPatternTest119", DetectFastPatternTest119, 1); - UtRegisterTest("DetectFastPatternTest120", DetectFastPatternTest120, 1); - UtRegisterTest("DetectFastPatternTest121", DetectFastPatternTest121, 1); - UtRegisterTest("DetectFastPatternTest122", DetectFastPatternTest122, 1); - UtRegisterTest("DetectFastPatternTest123", DetectFastPatternTest123, 1); - UtRegisterTest("DetectFastPatternTest124", DetectFastPatternTest124, 1); - UtRegisterTest("DetectFastPatternTest125", DetectFastPatternTest125, 1); - UtRegisterTest("DetectFastPatternTest126", DetectFastPatternTest126, 1); - UtRegisterTest("DetectFastPatternTest127", DetectFastPatternTest127, 1); - UtRegisterTest("DetectFastPatternTest128", DetectFastPatternTest128, 1); - UtRegisterTest("DetectFastPatternTest129", DetectFastPatternTest129, 1); - UtRegisterTest("DetectFastPatternTest130", DetectFastPatternTest130, 1); - UtRegisterTest("DetectFastPatternTest131", DetectFastPatternTest131, 1); - UtRegisterTest("DetectFastPatternTest132", DetectFastPatternTest132, 1); - UtRegisterTest("DetectFastPatternTest133", DetectFastPatternTest133, 1); - /* http_uri fast_pattern tests ^ */ - /* http_client_body fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest134", DetectFastPatternTest134, 1); - UtRegisterTest("DetectFastPatternTest135", DetectFastPatternTest135, 1); - UtRegisterTest("DetectFastPatternTest136", DetectFastPatternTest136, 1); - UtRegisterTest("DetectFastPatternTest137", DetectFastPatternTest137, 1); - UtRegisterTest("DetectFastPatternTest138", DetectFastPatternTest138, 1); - UtRegisterTest("DetectFastPatternTest139", DetectFastPatternTest139, 1); - UtRegisterTest("DetectFastPatternTest140", DetectFastPatternTest140, 1); - UtRegisterTest("DetectFastPatternTest141", DetectFastPatternTest141, 1); - UtRegisterTest("DetectFastPatternTest142", DetectFastPatternTest142, 1); - UtRegisterTest("DetectFastPatternTest143", DetectFastPatternTest143, 1); - UtRegisterTest("DetectFastPatternTest144", DetectFastPatternTest144, 1); - UtRegisterTest("DetectFastPatternTest145", DetectFastPatternTest145, 1); - UtRegisterTest("DetectFastPatternTest146", DetectFastPatternTest146, 1); - UtRegisterTest("DetectFastPatternTest147", DetectFastPatternTest147, 1); - UtRegisterTest("DetectFastPatternTest148", DetectFastPatternTest148, 1); - UtRegisterTest("DetectFastPatternTest149", DetectFastPatternTest149, 1); - UtRegisterTest("DetectFastPatternTest150", DetectFastPatternTest150, 1); - UtRegisterTest("DetectFastPatternTest151", DetectFastPatternTest151, 1); - UtRegisterTest("DetectFastPatternTest152", DetectFastPatternTest152, 1); - UtRegisterTest("DetectFastPatternTest153", DetectFastPatternTest153, 1); - UtRegisterTest("DetectFastPatternTest154", DetectFastPatternTest154, 1); - UtRegisterTest("DetectFastPatternTest155", DetectFastPatternTest155, 1); - UtRegisterTest("DetectFastPatternTest156", DetectFastPatternTest156, 1); - UtRegisterTest("DetectFastPatternTest157", DetectFastPatternTest157, 1); - UtRegisterTest("DetectFastPatternTest158", DetectFastPatternTest158, 1); - UtRegisterTest("DetectFastPatternTest159", DetectFastPatternTest159, 1); - UtRegisterTest("DetectFastPatternTest160", DetectFastPatternTest160, 1); - UtRegisterTest("DetectFastPatternTest161", DetectFastPatternTest161, 1); - UtRegisterTest("DetectFastPatternTest162", DetectFastPatternTest162, 1); - UtRegisterTest("DetectFastPatternTest163", DetectFastPatternTest163, 1); - UtRegisterTest("DetectFastPatternTest164", DetectFastPatternTest164, 1); - UtRegisterTest("DetectFastPatternTest165", DetectFastPatternTest165, 1); - UtRegisterTest("DetectFastPatternTest166", DetectFastPatternTest166, 1); - UtRegisterTest("DetectFastPatternTest167", DetectFastPatternTest167, 1); - UtRegisterTest("DetectFastPatternTest168", DetectFastPatternTest168, 1); - UtRegisterTest("DetectFastPatternTest169", DetectFastPatternTest169, 1); - UtRegisterTest("DetectFastPatternTest170", DetectFastPatternTest170, 1); - UtRegisterTest("DetectFastPatternTest171", DetectFastPatternTest171, 1); - UtRegisterTest("DetectFastPatternTest172", DetectFastPatternTest172, 1); - UtRegisterTest("DetectFastPatternTest173", DetectFastPatternTest173, 1); - UtRegisterTest("DetectFastPatternTest174", DetectFastPatternTest174, 1); - /* http_client_body fast_pattern tests ^ */ - /* content fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest175", DetectFastPatternTest175, 1); - UtRegisterTest("DetectFastPatternTest176", DetectFastPatternTest176, 1); - UtRegisterTest("DetectFastPatternTest177", DetectFastPatternTest177, 1); - UtRegisterTest("DetectFastPatternTest178", DetectFastPatternTest178, 1); - /* content fast_pattern tests ^ */ - /* http_header fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest179", DetectFastPatternTest179, 1); - UtRegisterTest("DetectFastPatternTest180", DetectFastPatternTest180, 1); - UtRegisterTest("DetectFastPatternTest181", DetectFastPatternTest181, 1); - UtRegisterTest("DetectFastPatternTest182", DetectFastPatternTest182, 1); - UtRegisterTest("DetectFastPatternTest183", DetectFastPatternTest183, 1); - UtRegisterTest("DetectFastPatternTest184", DetectFastPatternTest184, 1); - UtRegisterTest("DetectFastPatternTest185", DetectFastPatternTest185, 1); - UtRegisterTest("DetectFastPatternTest186", DetectFastPatternTest186, 1); - UtRegisterTest("DetectFastPatternTest187", DetectFastPatternTest187, 1); - UtRegisterTest("DetectFastPatternTest188", DetectFastPatternTest188, 1); - UtRegisterTest("DetectFastPatternTest189", DetectFastPatternTest189, 1); - UtRegisterTest("DetectFastPatternTest190", DetectFastPatternTest190, 1); - UtRegisterTest("DetectFastPatternTest191", DetectFastPatternTest191, 1); - UtRegisterTest("DetectFastPatternTest192", DetectFastPatternTest192, 1); - UtRegisterTest("DetectFastPatternTest193", DetectFastPatternTest193, 1); - UtRegisterTest("DetectFastPatternTest194", DetectFastPatternTest194, 1); - UtRegisterTest("DetectFastPatternTest195", DetectFastPatternTest195, 1); - UtRegisterTest("DetectFastPatternTest196", DetectFastPatternTest196, 1); - UtRegisterTest("DetectFastPatternTest197", DetectFastPatternTest197, 1); - UtRegisterTest("DetectFastPatternTest198", DetectFastPatternTest198, 1); - UtRegisterTest("DetectFastPatternTest199", DetectFastPatternTest199, 1); - UtRegisterTest("DetectFastPatternTest200", DetectFastPatternTest200, 1); - UtRegisterTest("DetectFastPatternTest201", DetectFastPatternTest201, 1); - UtRegisterTest("DetectFastPatternTest202", DetectFastPatternTest202, 1); - UtRegisterTest("DetectFastPatternTest203", DetectFastPatternTest203, 1); - UtRegisterTest("DetectFastPatternTest204", DetectFastPatternTest204, 1); - UtRegisterTest("DetectFastPatternTest205", DetectFastPatternTest205, 1); - UtRegisterTest("DetectFastPatternTest206", DetectFastPatternTest206, 1); - UtRegisterTest("DetectFastPatternTest207", DetectFastPatternTest207, 1); - UtRegisterTest("DetectFastPatternTest208", DetectFastPatternTest208, 1); - UtRegisterTest("DetectFastPatternTest209", DetectFastPatternTest209, 1); - UtRegisterTest("DetectFastPatternTest210", DetectFastPatternTest210, 1); - UtRegisterTest("DetectFastPatternTest211", DetectFastPatternTest211, 1); - UtRegisterTest("DetectFastPatternTest212", DetectFastPatternTest212, 1); - UtRegisterTest("DetectFastPatternTest213", DetectFastPatternTest213, 1); - UtRegisterTest("DetectFastPatternTest214", DetectFastPatternTest214, 1); - UtRegisterTest("DetectFastPatternTest215", DetectFastPatternTest215, 1); - UtRegisterTest("DetectFastPatternTest216", DetectFastPatternTest216, 1); - UtRegisterTest("DetectFastPatternTest217", DetectFastPatternTest217, 1); - UtRegisterTest("DetectFastPatternTest218", DetectFastPatternTest218, 1); - UtRegisterTest("DetectFastPatternTest219", DetectFastPatternTest219, 1); - /* http_header fast_pattern tests ^ */ - /* http_raw_header fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest220", DetectFastPatternTest220, 1); - UtRegisterTest("DetectFastPatternTest221", DetectFastPatternTest221, 1); - UtRegisterTest("DetectFastPatternTest222", DetectFastPatternTest222, 1); - UtRegisterTest("DetectFastPatternTest223", DetectFastPatternTest223, 1); - UtRegisterTest("DetectFastPatternTest224", DetectFastPatternTest224, 1); - UtRegisterTest("DetectFastPatternTest225", DetectFastPatternTest225, 1); - UtRegisterTest("DetectFastPatternTest226", DetectFastPatternTest226, 1); - UtRegisterTest("DetectFastPatternTest227", DetectFastPatternTest227, 1); - UtRegisterTest("DetectFastPatternTest228", DetectFastPatternTest228, 1); - UtRegisterTest("DetectFastPatternTest229", DetectFastPatternTest229, 1); - UtRegisterTest("DetectFastPatternTest230", DetectFastPatternTest230, 1); - UtRegisterTest("DetectFastPatternTest231", DetectFastPatternTest231, 1); - UtRegisterTest("DetectFastPatternTest232", DetectFastPatternTest232, 1); - UtRegisterTest("DetectFastPatternTest233", DetectFastPatternTest233, 1); - UtRegisterTest("DetectFastPatternTest234", DetectFastPatternTest234, 1); - UtRegisterTest("DetectFastPatternTest235", DetectFastPatternTest235, 1); - UtRegisterTest("DetectFastPatternTest236", DetectFastPatternTest236, 1); - UtRegisterTest("DetectFastPatternTest237", DetectFastPatternTest237, 1); - UtRegisterTest("DetectFastPatternTest238", DetectFastPatternTest238, 1); - UtRegisterTest("DetectFastPatternTest239", DetectFastPatternTest239, 1); - UtRegisterTest("DetectFastPatternTest240", DetectFastPatternTest240, 1); - UtRegisterTest("DetectFastPatternTest241", DetectFastPatternTest241, 1); - UtRegisterTest("DetectFastPatternTest242", DetectFastPatternTest242, 1); - UtRegisterTest("DetectFastPatternTest243", DetectFastPatternTest243, 1); - UtRegisterTest("DetectFastPatternTest244", DetectFastPatternTest244, 1); - UtRegisterTest("DetectFastPatternTest245", DetectFastPatternTest245, 1); - UtRegisterTest("DetectFastPatternTest246", DetectFastPatternTest246, 1); - UtRegisterTest("DetectFastPatternTest247", DetectFastPatternTest247, 1); - UtRegisterTest("DetectFastPatternTest248", DetectFastPatternTest248, 1); - UtRegisterTest("DetectFastPatternTest249", DetectFastPatternTest249, 1); - UtRegisterTest("DetectFastPatternTest250", DetectFastPatternTest250, 1); - UtRegisterTest("DetectFastPatternTest251", DetectFastPatternTest251, 1); - UtRegisterTest("DetectFastPatternTest252", DetectFastPatternTest252, 1); - UtRegisterTest("DetectFastPatternTest253", DetectFastPatternTest253, 1); - UtRegisterTest("DetectFastPatternTest254", DetectFastPatternTest254, 1); - UtRegisterTest("DetectFastPatternTest255", DetectFastPatternTest255, 1); - UtRegisterTest("DetectFastPatternTest256", DetectFastPatternTest256, 1); - UtRegisterTest("DetectFastPatternTest257", DetectFastPatternTest257, 1); - UtRegisterTest("DetectFastPatternTest258", DetectFastPatternTest258, 1); - UtRegisterTest("DetectFastPatternTest259", DetectFastPatternTest259, 1); - UtRegisterTest("DetectFastPatternTest260", DetectFastPatternTest260, 1); - /* http_raw_header fast_pattern tests ^ */ - /* http_method fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest261", DetectFastPatternTest261, 1); - UtRegisterTest("DetectFastPatternTest262", DetectFastPatternTest262, 1); - UtRegisterTest("DetectFastPatternTest263", DetectFastPatternTest263, 1); - UtRegisterTest("DetectFastPatternTest264", DetectFastPatternTest264, 1); - UtRegisterTest("DetectFastPatternTest265", DetectFastPatternTest265, 1); - UtRegisterTest("DetectFastPatternTest266", DetectFastPatternTest266, 1); - UtRegisterTest("DetectFastPatternTest267", DetectFastPatternTest267, 1); - UtRegisterTest("DetectFastPatternTest268", DetectFastPatternTest268, 1); - UtRegisterTest("DetectFastPatternTest269", DetectFastPatternTest269, 1); - UtRegisterTest("DetectFastPatternTest270", DetectFastPatternTest270, 1); - UtRegisterTest("DetectFastPatternTest271", DetectFastPatternTest271, 1); - UtRegisterTest("DetectFastPatternTest272", DetectFastPatternTest272, 1); - UtRegisterTest("DetectFastPatternTest273", DetectFastPatternTest273, 1); - UtRegisterTest("DetectFastPatternTest274", DetectFastPatternTest274, 1); - UtRegisterTest("DetectFastPatternTest275", DetectFastPatternTest275, 1); - UtRegisterTest("DetectFastPatternTest276", DetectFastPatternTest276, 1); - UtRegisterTest("DetectFastPatternTest277", DetectFastPatternTest277, 1); - UtRegisterTest("DetectFastPatternTest278", DetectFastPatternTest278, 1); - UtRegisterTest("DetectFastPatternTest279", DetectFastPatternTest279, 1); - UtRegisterTest("DetectFastPatternTest280", DetectFastPatternTest280, 1); - UtRegisterTest("DetectFastPatternTest281", DetectFastPatternTest281, 1); - UtRegisterTest("DetectFastPatternTest282", DetectFastPatternTest282, 1); - UtRegisterTest("DetectFastPatternTest283", DetectFastPatternTest283, 1); - UtRegisterTest("DetectFastPatternTest284", DetectFastPatternTest284, 1); - UtRegisterTest("DetectFastPatternTest285", DetectFastPatternTest285, 1); - UtRegisterTest("DetectFastPatternTest286", DetectFastPatternTest286, 1); - UtRegisterTest("DetectFastPatternTest287", DetectFastPatternTest287, 1); - UtRegisterTest("DetectFastPatternTest288", DetectFastPatternTest288, 1); - UtRegisterTest("DetectFastPatternTest289", DetectFastPatternTest289, 1); - UtRegisterTest("DetectFastPatternTest290", DetectFastPatternTest290, 1); - UtRegisterTest("DetectFastPatternTest291", DetectFastPatternTest291, 1); - UtRegisterTest("DetectFastPatternTest292", DetectFastPatternTest292, 1); - UtRegisterTest("DetectFastPatternTest293", DetectFastPatternTest293, 1); - UtRegisterTest("DetectFastPatternTest294", DetectFastPatternTest294, 1); - UtRegisterTest("DetectFastPatternTest295", DetectFastPatternTest295, 1); - UtRegisterTest("DetectFastPatternTest296", DetectFastPatternTest296, 1); - UtRegisterTest("DetectFastPatternTest297", DetectFastPatternTest297, 1); - UtRegisterTest("DetectFastPatternTest298", DetectFastPatternTest298, 1); - UtRegisterTest("DetectFastPatternTest299", DetectFastPatternTest299, 1); - UtRegisterTest("DetectFastPatternTest300", DetectFastPatternTest300, 1); - UtRegisterTest("DetectFastPatternTest301", DetectFastPatternTest301, 1); - /* http_method fast_pattern tests ^ */ - /* http_cookie fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest302", DetectFastPatternTest302, 1); - UtRegisterTest("DetectFastPatternTest303", DetectFastPatternTest303, 1); - UtRegisterTest("DetectFastPatternTest304", DetectFastPatternTest304, 1); - UtRegisterTest("DetectFastPatternTest305", DetectFastPatternTest305, 1); - UtRegisterTest("DetectFastPatternTest306", DetectFastPatternTest306, 1); - UtRegisterTest("DetectFastPatternTest307", DetectFastPatternTest307, 1); - UtRegisterTest("DetectFastPatternTest308", DetectFastPatternTest308, 1); - UtRegisterTest("DetectFastPatternTest309", DetectFastPatternTest309, 1); - UtRegisterTest("DetectFastPatternTest310", DetectFastPatternTest310, 1); - UtRegisterTest("DetectFastPatternTest311", DetectFastPatternTest311, 1); - UtRegisterTest("DetectFastPatternTest312", DetectFastPatternTest312, 1); - UtRegisterTest("DetectFastPatternTest313", DetectFastPatternTest313, 1); - UtRegisterTest("DetectFastPatternTest314", DetectFastPatternTest314, 1); - UtRegisterTest("DetectFastPatternTest315", DetectFastPatternTest315, 1); - UtRegisterTest("DetectFastPatternTest316", DetectFastPatternTest316, 1); - UtRegisterTest("DetectFastPatternTest317", DetectFastPatternTest317, 1); - UtRegisterTest("DetectFastPatternTest318", DetectFastPatternTest318, 1); - UtRegisterTest("DetectFastPatternTest319", DetectFastPatternTest319, 1); - UtRegisterTest("DetectFastPatternTest320", DetectFastPatternTest320, 1); - UtRegisterTest("DetectFastPatternTest321", DetectFastPatternTest321, 1); - UtRegisterTest("DetectFastPatternTest322", DetectFastPatternTest322, 1); - UtRegisterTest("DetectFastPatternTest323", DetectFastPatternTest323, 1); - UtRegisterTest("DetectFastPatternTest324", DetectFastPatternTest324, 1); - UtRegisterTest("DetectFastPatternTest325", DetectFastPatternTest325, 1); - UtRegisterTest("DetectFastPatternTest326", DetectFastPatternTest326, 1); - UtRegisterTest("DetectFastPatternTest327", DetectFastPatternTest327, 1); - UtRegisterTest("DetectFastPatternTest328", DetectFastPatternTest328, 1); - UtRegisterTest("DetectFastPatternTest329", DetectFastPatternTest329, 1); - UtRegisterTest("DetectFastPatternTest330", DetectFastPatternTest330, 1); - UtRegisterTest("DetectFastPatternTest331", DetectFastPatternTest331, 1); - UtRegisterTest("DetectFastPatternTest332", DetectFastPatternTest332, 1); - UtRegisterTest("DetectFastPatternTest333", DetectFastPatternTest333, 1); - UtRegisterTest("DetectFastPatternTest334", DetectFastPatternTest334, 1); - UtRegisterTest("DetectFastPatternTest335", DetectFastPatternTest335, 1); - UtRegisterTest("DetectFastPatternTest336", DetectFastPatternTest336, 1); - UtRegisterTest("DetectFastPatternTest337", DetectFastPatternTest337, 1); - UtRegisterTest("DetectFastPatternTest338", DetectFastPatternTest338, 1); - UtRegisterTest("DetectFastPatternTest339", DetectFastPatternTest339, 1); - UtRegisterTest("DetectFastPatternTest340", DetectFastPatternTest340, 1); - UtRegisterTest("DetectFastPatternTest341", DetectFastPatternTest341, 1); - UtRegisterTest("DetectFastPatternTest342", DetectFastPatternTest342, 1); - /* http_cookie fast_pattern tests ^ */ - /* http_raw_uri fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest343", DetectFastPatternTest343, 1); - UtRegisterTest("DetectFastPatternTest344", DetectFastPatternTest344, 1); - UtRegisterTest("DetectFastPatternTest345", DetectFastPatternTest345, 1); - UtRegisterTest("DetectFastPatternTest346", DetectFastPatternTest346, 1); - UtRegisterTest("DetectFastPatternTest347", DetectFastPatternTest347, 1); - UtRegisterTest("DetectFastPatternTest348", DetectFastPatternTest348, 1); - UtRegisterTest("DetectFastPatternTest349", DetectFastPatternTest349, 1); - UtRegisterTest("DetectFastPatternTest350", DetectFastPatternTest350, 1); - UtRegisterTest("DetectFastPatternTest351", DetectFastPatternTest351, 1); - UtRegisterTest("DetectFastPatternTest352", DetectFastPatternTest352, 1); - UtRegisterTest("DetectFastPatternTest353", DetectFastPatternTest353, 1); - UtRegisterTest("DetectFastPatternTest354", DetectFastPatternTest354, 1); - UtRegisterTest("DetectFastPatternTest355", DetectFastPatternTest355, 1); - UtRegisterTest("DetectFastPatternTest356", DetectFastPatternTest356, 1); - UtRegisterTest("DetectFastPatternTest357", DetectFastPatternTest357, 1); - UtRegisterTest("DetectFastPatternTest358", DetectFastPatternTest358, 1); - UtRegisterTest("DetectFastPatternTest359", DetectFastPatternTest359, 1); - UtRegisterTest("DetectFastPatternTest360", DetectFastPatternTest360, 1); - UtRegisterTest("DetectFastPatternTest361", DetectFastPatternTest361, 1); - UtRegisterTest("DetectFastPatternTest362", DetectFastPatternTest362, 1); - UtRegisterTest("DetectFastPatternTest363", DetectFastPatternTest363, 1); - UtRegisterTest("DetectFastPatternTest364", DetectFastPatternTest364, 1); - UtRegisterTest("DetectFastPatternTest365", DetectFastPatternTest365, 1); - UtRegisterTest("DetectFastPatternTest366", DetectFastPatternTest366, 1); - UtRegisterTest("DetectFastPatternTest367", DetectFastPatternTest367, 1); - UtRegisterTest("DetectFastPatternTest368", DetectFastPatternTest368, 1); - UtRegisterTest("DetectFastPatternTest369", DetectFastPatternTest369, 1); - UtRegisterTest("DetectFastPatternTest370", DetectFastPatternTest370, 1); - UtRegisterTest("DetectFastPatternTest371", DetectFastPatternTest371, 1); - UtRegisterTest("DetectFastPatternTest372", DetectFastPatternTest372, 1); - UtRegisterTest("DetectFastPatternTest373", DetectFastPatternTest373, 1); - UtRegisterTest("DetectFastPatternTest374", DetectFastPatternTest374, 1); - UtRegisterTest("DetectFastPatternTest375", DetectFastPatternTest375, 1); - UtRegisterTest("DetectFastPatternTest376", DetectFastPatternTest376, 1); - UtRegisterTest("DetectFastPatternTest377", DetectFastPatternTest377, 1); - UtRegisterTest("DetectFastPatternTest378", DetectFastPatternTest378, 1); - UtRegisterTest("DetectFastPatternTest379", DetectFastPatternTest379, 1); - UtRegisterTest("DetectFastPatternTest380", DetectFastPatternTest380, 1); - UtRegisterTest("DetectFastPatternTest381", DetectFastPatternTest381, 1); - UtRegisterTest("DetectFastPatternTest382", DetectFastPatternTest382, 1); - UtRegisterTest("DetectFastPatternTest383", DetectFastPatternTest383, 1); - /* http_raw_uri fast_pattern tests ^ */ - /* http_stat_msg fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest384", DetectFastPatternTest384, 1); - UtRegisterTest("DetectFastPatternTest385", DetectFastPatternTest385, 1); - UtRegisterTest("DetectFastPatternTest386", DetectFastPatternTest386, 1); - UtRegisterTest("DetectFastPatternTest387", DetectFastPatternTest387, 1); - UtRegisterTest("DetectFastPatternTest388", DetectFastPatternTest388, 1); - UtRegisterTest("DetectFastPatternTest389", DetectFastPatternTest389, 1); - UtRegisterTest("DetectFastPatternTest390", DetectFastPatternTest390, 1); - UtRegisterTest("DetectFastPatternTest391", DetectFastPatternTest391, 1); - UtRegisterTest("DetectFastPatternTest392", DetectFastPatternTest392, 1); - UtRegisterTest("DetectFastPatternTest393", DetectFastPatternTest393, 1); - UtRegisterTest("DetectFastPatternTest394", DetectFastPatternTest394, 1); - UtRegisterTest("DetectFastPatternTest395", DetectFastPatternTest395, 1); - UtRegisterTest("DetectFastPatternTest396", DetectFastPatternTest396, 1); - UtRegisterTest("DetectFastPatternTest397", DetectFastPatternTest397, 1); - UtRegisterTest("DetectFastPatternTest398", DetectFastPatternTest398, 1); - UtRegisterTest("DetectFastPatternTest399", DetectFastPatternTest399, 1); - UtRegisterTest("DetectFastPatternTest400", DetectFastPatternTest400, 1); - UtRegisterTest("DetectFastPatternTest401", DetectFastPatternTest401, 1); - UtRegisterTest("DetectFastPatternTest402", DetectFastPatternTest402, 1); - UtRegisterTest("DetectFastPatternTest403", DetectFastPatternTest403, 1); - UtRegisterTest("DetectFastPatternTest404", DetectFastPatternTest404, 1); - UtRegisterTest("DetectFastPatternTest405", DetectFastPatternTest405, 1); - UtRegisterTest("DetectFastPatternTest406", DetectFastPatternTest406, 1); - UtRegisterTest("DetectFastPatternTest407", DetectFastPatternTest407, 1); - UtRegisterTest("DetectFastPatternTest408", DetectFastPatternTest408, 1); - UtRegisterTest("DetectFastPatternTest409", DetectFastPatternTest409, 1); - UtRegisterTest("DetectFastPatternTest410", DetectFastPatternTest410, 1); - UtRegisterTest("DetectFastPatternTest411", DetectFastPatternTest411, 1); - UtRegisterTest("DetectFastPatternTest412", DetectFastPatternTest412, 1); - UtRegisterTest("DetectFastPatternTest413", DetectFastPatternTest413, 1); - UtRegisterTest("DetectFastPatternTest414", DetectFastPatternTest414, 1); - UtRegisterTest("DetectFastPatternTest415", DetectFastPatternTest415, 1); - UtRegisterTest("DetectFastPatternTest416", DetectFastPatternTest415, 1); - UtRegisterTest("DetectFastPatternTest417", DetectFastPatternTest417, 1); - UtRegisterTest("DetectFastPatternTest418", DetectFastPatternTest418, 1); - UtRegisterTest("DetectFastPatternTest419", DetectFastPatternTest419, 1); - UtRegisterTest("DetectFastPatternTest420", DetectFastPatternTest420, 1); - UtRegisterTest("DetectFastPatternTest421", DetectFastPatternTest421, 1); - UtRegisterTest("DetectFastPatternTest422", DetectFastPatternTest422, 1); - UtRegisterTest("DetectFastPatternTest423", DetectFastPatternTest423, 1); - UtRegisterTest("DetectFastPatternTest424", DetectFastPatternTest424, 1); - /* http_stat_msg fast_pattern tests ^ */ - /* http_stat_code fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest425", DetectFastPatternTest425, 1); - UtRegisterTest("DetectFastPatternTest426", DetectFastPatternTest426, 1); - UtRegisterTest("DetectFastPatternTest427", DetectFastPatternTest427, 1); - UtRegisterTest("DetectFastPatternTest428", DetectFastPatternTest428, 1); - UtRegisterTest("DetectFastPatternTest429", DetectFastPatternTest429, 1); - UtRegisterTest("DetectFastPatternTest430", DetectFastPatternTest430, 1); - UtRegisterTest("DetectFastPatternTest431", DetectFastPatternTest431, 1); - UtRegisterTest("DetectFastPatternTest432", DetectFastPatternTest432, 1); - UtRegisterTest("DetectFastPatternTest433", DetectFastPatternTest433, 1); - UtRegisterTest("DetectFastPatternTest434", DetectFastPatternTest434, 1); - UtRegisterTest("DetectFastPatternTest435", DetectFastPatternTest435, 1); - UtRegisterTest("DetectFastPatternTest436", DetectFastPatternTest436, 1); - UtRegisterTest("DetectFastPatternTest437", DetectFastPatternTest437, 1); - UtRegisterTest("DetectFastPatternTest438", DetectFastPatternTest438, 1); - UtRegisterTest("DetectFastPatternTest439", DetectFastPatternTest439, 1); - UtRegisterTest("DetectFastPatternTest440", DetectFastPatternTest440, 1); - UtRegisterTest("DetectFastPatternTest441", DetectFastPatternTest441, 1); - UtRegisterTest("DetectFastPatternTest442", DetectFastPatternTest442, 1); - UtRegisterTest("DetectFastPatternTest443", DetectFastPatternTest443, 1); - UtRegisterTest("DetectFastPatternTest444", DetectFastPatternTest444, 1); - UtRegisterTest("DetectFastPatternTest445", DetectFastPatternTest445, 1); - UtRegisterTest("DetectFastPatternTest446", DetectFastPatternTest446, 1); - UtRegisterTest("DetectFastPatternTest447", DetectFastPatternTest447, 1); - UtRegisterTest("DetectFastPatternTest448", DetectFastPatternTest448, 1); - UtRegisterTest("DetectFastPatternTest449", DetectFastPatternTest449, 1); - UtRegisterTest("DetectFastPatternTest450", DetectFastPatternTest450, 1); - UtRegisterTest("DetectFastPatternTest451", DetectFastPatternTest451, 1); - UtRegisterTest("DetectFastPatternTest452", DetectFastPatternTest452, 1); - UtRegisterTest("DetectFastPatternTest453", DetectFastPatternTest453, 1); - UtRegisterTest("DetectFastPatternTest454", DetectFastPatternTest454, 1); - UtRegisterTest("DetectFastPatternTest455", DetectFastPatternTest455, 1); - UtRegisterTest("DetectFastPatternTest456", DetectFastPatternTest456, 1); - UtRegisterTest("DetectFastPatternTest457", DetectFastPatternTest457, 1); - UtRegisterTest("DetectFastPatternTest458", DetectFastPatternTest458, 1); - UtRegisterTest("DetectFastPatternTest459", DetectFastPatternTest459, 1); - UtRegisterTest("DetectFastPatternTest460", DetectFastPatternTest460, 1); - UtRegisterTest("DetectFastPatternTest461", DetectFastPatternTest461, 1); - UtRegisterTest("DetectFastPatternTest462", DetectFastPatternTest462, 1); - UtRegisterTest("DetectFastPatternTest463", DetectFastPatternTest463, 1); - UtRegisterTest("DetectFastPatternTest464", DetectFastPatternTest464, 1); - UtRegisterTest("DetectFastPatternTest465", DetectFastPatternTest465, 1); - /* http_stat_code fast_pattern tests ^ */ - /* http_server_body fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest466", DetectFastPatternTest466, 1); - UtRegisterTest("DetectFastPatternTest467", DetectFastPatternTest467, 1); - UtRegisterTest("DetectFastPatternTest468", DetectFastPatternTest468, 1); - UtRegisterTest("DetectFastPatternTest469", DetectFastPatternTest469, 1); - UtRegisterTest("DetectFastPatternTest470", DetectFastPatternTest470, 1); - UtRegisterTest("DetectFastPatternTest471", DetectFastPatternTest471, 1); - UtRegisterTest("DetectFastPatternTest472", DetectFastPatternTest472, 1); - UtRegisterTest("DetectFastPatternTest473", DetectFastPatternTest473, 1); - UtRegisterTest("DetectFastPatternTest474", DetectFastPatternTest474, 1); - UtRegisterTest("DetectFastPatternTest475", DetectFastPatternTest475, 1); - UtRegisterTest("DetectFastPatternTest476", DetectFastPatternTest476, 1); - UtRegisterTest("DetectFastPatternTest477", DetectFastPatternTest477, 1); - UtRegisterTest("DetectFastPatternTest478", DetectFastPatternTest478, 1); - UtRegisterTest("DetectFastPatternTest479", DetectFastPatternTest479, 1); - UtRegisterTest("DetectFastPatternTest480", DetectFastPatternTest480, 1); - UtRegisterTest("DetectFastPatternTest481", DetectFastPatternTest481, 1); - UtRegisterTest("DetectFastPatternTest482", DetectFastPatternTest482, 1); - UtRegisterTest("DetectFastPatternTest483", DetectFastPatternTest483, 1); - UtRegisterTest("DetectFastPatternTest484", DetectFastPatternTest484, 1); - UtRegisterTest("DetectFastPatternTest485", DetectFastPatternTest485, 1); - UtRegisterTest("DetectFastPatternTest486", DetectFastPatternTest486, 1); - UtRegisterTest("DetectFastPatternTest487", DetectFastPatternTest487, 1); - UtRegisterTest("DetectFastPatternTest488", DetectFastPatternTest488, 1); - UtRegisterTest("DetectFastPatternTest489", DetectFastPatternTest489, 1); - UtRegisterTest("DetectFastPatternTest490", DetectFastPatternTest490, 1); - UtRegisterTest("DetectFastPatternTest491", DetectFastPatternTest491, 1); - UtRegisterTest("DetectFastPatternTest492", DetectFastPatternTest492, 1); - UtRegisterTest("DetectFastPatternTest493", DetectFastPatternTest493, 1); - UtRegisterTest("DetectFastPatternTest494", DetectFastPatternTest494, 1); - UtRegisterTest("DetectFastPatternTest495", DetectFastPatternTest495, 1); - UtRegisterTest("DetectFastPatternTest496", DetectFastPatternTest496, 1); - UtRegisterTest("DetectFastPatternTest497", DetectFastPatternTest497, 1); - UtRegisterTest("DetectFastPatternTest498", DetectFastPatternTest498, 1); - UtRegisterTest("DetectFastPatternTest499", DetectFastPatternTest499, 1); - UtRegisterTest("DetectFastPatternTest500", DetectFastPatternTest500, 1); - UtRegisterTest("DetectFastPatternTest501", DetectFastPatternTest501, 1); - UtRegisterTest("DetectFastPatternTest502", DetectFastPatternTest502, 1); - UtRegisterTest("DetectFastPatternTest503", DetectFastPatternTest503, 1); - UtRegisterTest("DetectFastPatternTest504", DetectFastPatternTest504, 1); - UtRegisterTest("DetectFastPatternTest505", DetectFastPatternTest505, 1); - UtRegisterTest("DetectFastPatternTest506", DetectFastPatternTest506, 1); - /* http_server_body fast_pattern tests ^ */ - /* file_data fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest507", DetectFastPatternTest507, 1); - UtRegisterTest("DetectFastPatternTest508", DetectFastPatternTest508, 1); - UtRegisterTest("DetectFastPatternTest509", DetectFastPatternTest509, 1); - UtRegisterTest("DetectFastPatternTest510", DetectFastPatternTest510, 1); - UtRegisterTest("DetectFastPatternTest511", DetectFastPatternTest511, 1); - UtRegisterTest("DetectFastPatternTest512", DetectFastPatternTest512, 1); - UtRegisterTest("DetectFastPatternTest513", DetectFastPatternTest513, 1); - UtRegisterTest("DetectFastPatternTest514", DetectFastPatternTest514, 1); - UtRegisterTest("DetectFastPatternTest515", DetectFastPatternTest515, 1); - UtRegisterTest("DetectFastPatternTest516", DetectFastPatternTest516, 1); - UtRegisterTest("DetectFastPatternTest517", DetectFastPatternTest517, 1); - UtRegisterTest("DetectFastPatternTest518", DetectFastPatternTest518, 1); - UtRegisterTest("DetectFastPatternTest519", DetectFastPatternTest519, 1); - UtRegisterTest("DetectFastPatternTest520", DetectFastPatternTest520, 1); - UtRegisterTest("DetectFastPatternTest521", DetectFastPatternTest521, 1); - UtRegisterTest("DetectFastPatternTest522", DetectFastPatternTest522, 1); - UtRegisterTest("DetectFastPatternTest523", DetectFastPatternTest523, 1); - UtRegisterTest("DetectFastPatternTest524", DetectFastPatternTest524, 1); - UtRegisterTest("DetectFastPatternTest525", DetectFastPatternTest525, 1); - UtRegisterTest("DetectFastPatternTest526", DetectFastPatternTest526, 1); - UtRegisterTest("DetectFastPatternTest527", DetectFastPatternTest527, 1); - UtRegisterTest("DetectFastPatternTest528", DetectFastPatternTest528, 1); - UtRegisterTest("DetectFastPatternTest529", DetectFastPatternTest529, 1); - UtRegisterTest("DetectFastPatternTest530", DetectFastPatternTest530, 1); - UtRegisterTest("DetectFastPatternTest531", DetectFastPatternTest531, 1); - UtRegisterTest("DetectFastPatternTest532", DetectFastPatternTest532, 1); - UtRegisterTest("DetectFastPatternTest533", DetectFastPatternTest533, 1); - UtRegisterTest("DetectFastPatternTest534", DetectFastPatternTest534, 1); - UtRegisterTest("DetectFastPatternTest535", DetectFastPatternTest535, 1); - UtRegisterTest("DetectFastPatternTest536", DetectFastPatternTest536, 1); - UtRegisterTest("DetectFastPatternTest537", DetectFastPatternTest537, 1); - UtRegisterTest("DetectFastPatternTest538", DetectFastPatternTest538, 1); - UtRegisterTest("DetectFastPatternTest539", DetectFastPatternTest539, 1); - UtRegisterTest("DetectFastPatternTest540", DetectFastPatternTest540, 1); - UtRegisterTest("DetectFastPatternTest541", DetectFastPatternTest541, 1); - UtRegisterTest("DetectFastPatternTest542", DetectFastPatternTest542, 1); - UtRegisterTest("DetectFastPatternTest543", DetectFastPatternTest543, 1); - UtRegisterTest("DetectFastPatternTest544", DetectFastPatternTest544, 1); - UtRegisterTest("DetectFastPatternTest545", DetectFastPatternTest545, 1); - UtRegisterTest("DetectFastPatternTest546", DetectFastPatternTest546, 1); - UtRegisterTest("DetectFastPatternTest547", DetectFastPatternTest547, 1); - /* file_data fast_pattern tests ^ */ - /* http_user_agent fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest548", DetectFastPatternTest548, 1); - UtRegisterTest("DetectFastPatternTest549", DetectFastPatternTest549, 1); - UtRegisterTest("DetectFastPatternTest550", DetectFastPatternTest550, 1); - UtRegisterTest("DetectFastPatternTest551", DetectFastPatternTest551, 1); - UtRegisterTest("DetectFastPatternTest552", DetectFastPatternTest552, 1); - UtRegisterTest("DetectFastPatternTest553", DetectFastPatternTest553, 1); - UtRegisterTest("DetectFastPatternTest554", DetectFastPatternTest554, 1); - UtRegisterTest("DetectFastPatternTest555", DetectFastPatternTest555, 1); - UtRegisterTest("DetectFastPatternTest556", DetectFastPatternTest556, 1); - UtRegisterTest("DetectFastPatternTest557", DetectFastPatternTest557, 1); - UtRegisterTest("DetectFastPatternTest558", DetectFastPatternTest558, 1); - UtRegisterTest("DetectFastPatternTest559", DetectFastPatternTest559, 1); - UtRegisterTest("DetectFastPatternTest560", DetectFastPatternTest560, 1); - UtRegisterTest("DetectFastPatternTest561", DetectFastPatternTest561, 1); - UtRegisterTest("DetectFastPatternTest562", DetectFastPatternTest562, 1); - UtRegisterTest("DetectFastPatternTest563", DetectFastPatternTest563, 1); - UtRegisterTest("DetectFastPatternTest564", DetectFastPatternTest564, 1); - UtRegisterTest("DetectFastPatternTest565", DetectFastPatternTest565, 1); - UtRegisterTest("DetectFastPatternTest566", DetectFastPatternTest566, 1); - UtRegisterTest("DetectFastPatternTest567", DetectFastPatternTest567, 1); - UtRegisterTest("DetectFastPatternTest568", DetectFastPatternTest568, 1); - UtRegisterTest("DetectFastPatternTest569", DetectFastPatternTest569, 1); - UtRegisterTest("DetectFastPatternTest570", DetectFastPatternTest570, 1); - UtRegisterTest("DetectFastPatternTest571", DetectFastPatternTest571, 1); - UtRegisterTest("DetectFastPatternTest572", DetectFastPatternTest572, 1); - UtRegisterTest("DetectFastPatternTest573", DetectFastPatternTest573, 1); - UtRegisterTest("DetectFastPatternTest574", DetectFastPatternTest574, 1); - UtRegisterTest("DetectFastPatternTest575", DetectFastPatternTest575, 1); - UtRegisterTest("DetectFastPatternTest576", DetectFastPatternTest576, 1); - UtRegisterTest("DetectFastPatternTest577", DetectFastPatternTest577, 1); - UtRegisterTest("DetectFastPatternTest578", DetectFastPatternTest578, 1); - UtRegisterTest("DetectFastPatternTest579", DetectFastPatternTest579, 1); - UtRegisterTest("DetectFastPatternTest580", DetectFastPatternTest580, 1); - UtRegisterTest("DetectFastPatternTest581", DetectFastPatternTest581, 1); - UtRegisterTest("DetectFastPatternTest582", DetectFastPatternTest582, 1); - UtRegisterTest("DetectFastPatternTest583", DetectFastPatternTest583, 1); - UtRegisterTest("DetectFastPatternTest584", DetectFastPatternTest584, 1); - UtRegisterTest("DetectFastPatternTest585", DetectFastPatternTest585, 1); - UtRegisterTest("DetectFastPatternTest586", DetectFastPatternTest586, 1); - UtRegisterTest("DetectFastPatternTest587", DetectFastPatternTest587, 1); - UtRegisterTest("DetectFastPatternTest588", DetectFastPatternTest588, 1); - /* http_user_agent fast_pattern tests ^ */ - /* http_host fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest589", DetectFastPatternTest589, 1); - UtRegisterTest("DetectFastPatternTest590", DetectFastPatternTest590, 1); - UtRegisterTest("DetectFastPatternTest591", DetectFastPatternTest591, 1); - UtRegisterTest("DetectFastPatternTest592", DetectFastPatternTest592, 1); - UtRegisterTest("DetectFastPatternTest593", DetectFastPatternTest593, 1); - UtRegisterTest("DetectFastPatternTest594", DetectFastPatternTest594, 1); - UtRegisterTest("DetectFastPatternTest595", DetectFastPatternTest595, 1); - UtRegisterTest("DetectFastPatternTest596", DetectFastPatternTest596, 1); - UtRegisterTest("DetectFastPatternTest597", DetectFastPatternTest597, 1); - UtRegisterTest("DetectFastPatternTest598", DetectFastPatternTest598, 1); - UtRegisterTest("DetectFastPatternTest599", DetectFastPatternTest599, 1); - UtRegisterTest("DetectFastPatternTest600", DetectFastPatternTest600, 1); - UtRegisterTest("DetectFastPatternTest601", DetectFastPatternTest601, 1); - UtRegisterTest("DetectFastPatternTest602", DetectFastPatternTest602, 1); - UtRegisterTest("DetectFastPatternTest603", DetectFastPatternTest603, 1); - UtRegisterTest("DetectFastPatternTest604", DetectFastPatternTest604, 1); - UtRegisterTest("DetectFastPatternTest605", DetectFastPatternTest605, 1); - UtRegisterTest("DetectFastPatternTest606", DetectFastPatternTest606, 1); - UtRegisterTest("DetectFastPatternTest607", DetectFastPatternTest607, 1); - UtRegisterTest("DetectFastPatternTest608", DetectFastPatternTest608, 1); - UtRegisterTest("DetectFastPatternTest609", DetectFastPatternTest609, 1); - UtRegisterTest("DetectFastPatternTest610", DetectFastPatternTest610, 1); - UtRegisterTest("DetectFastPatternTest611", DetectFastPatternTest611, 1); - UtRegisterTest("DetectFastPatternTest612", DetectFastPatternTest612, 1); - UtRegisterTest("DetectFastPatternTest613", DetectFastPatternTest613, 1); - UtRegisterTest("DetectFastPatternTest614", DetectFastPatternTest614, 1); - UtRegisterTest("DetectFastPatternTest615", DetectFastPatternTest615, 1); - UtRegisterTest("DetectFastPatternTest616", DetectFastPatternTest616, 1); - UtRegisterTest("DetectFastPatternTest617", DetectFastPatternTest617, 1); - UtRegisterTest("DetectFastPatternTest618", DetectFastPatternTest618, 1); - UtRegisterTest("DetectFastPatternTest619", DetectFastPatternTest619, 1); - UtRegisterTest("DetectFastPatternTest620", DetectFastPatternTest620, 1); - UtRegisterTest("DetectFastPatternTest621", DetectFastPatternTest621, 1); - UtRegisterTest("DetectFastPatternTest622", DetectFastPatternTest622, 1); - UtRegisterTest("DetectFastPatternTest623", DetectFastPatternTest623, 1); - UtRegisterTest("DetectFastPatternTest624", DetectFastPatternTest624, 1); - UtRegisterTest("DetectFastPatternTest625", DetectFastPatternTest625, 1); - UtRegisterTest("DetectFastPatternTest626", DetectFastPatternTest626, 1); - UtRegisterTest("DetectFastPatternTest627", DetectFastPatternTest627, 1); - UtRegisterTest("DetectFastPatternTest628", DetectFastPatternTest628, 1); - UtRegisterTest("DetectFastPatternTest629", DetectFastPatternTest629, 1); - /* http_host fast_pattern tests ^ */ - /* http_rawhost fast_pattern tests v */ - UtRegisterTest("DetectFastPatternTest630", DetectFastPatternTest630, 1); - UtRegisterTest("DetectFastPatternTest631", DetectFastPatternTest631, 1); - UtRegisterTest("DetectFastPatternTest632", DetectFastPatternTest632, 1); - UtRegisterTest("DetectFastPatternTest633", DetectFastPatternTest633, 1); - UtRegisterTest("DetectFastPatternTest634", DetectFastPatternTest634, 1); - UtRegisterTest("DetectFastPatternTest635", DetectFastPatternTest635, 1); - UtRegisterTest("DetectFastPatternTest636", DetectFastPatternTest636, 1); - UtRegisterTest("DetectFastPatternTest637", DetectFastPatternTest637, 1); - UtRegisterTest("DetectFastPatternTest638", DetectFastPatternTest638, 1); - UtRegisterTest("DetectFastPatternTest639", DetectFastPatternTest639, 1); - UtRegisterTest("DetectFastPatternTest640", DetectFastPatternTest640, 1); - UtRegisterTest("DetectFastPatternTest641", DetectFastPatternTest641, 1); - UtRegisterTest("DetectFastPatternTest642", DetectFastPatternTest642, 1); - UtRegisterTest("DetectFastPatternTest643", DetectFastPatternTest643, 1); - UtRegisterTest("DetectFastPatternTest644", DetectFastPatternTest644, 1); - UtRegisterTest("DetectFastPatternTest645", DetectFastPatternTest645, 1); - UtRegisterTest("DetectFastPatternTest646", DetectFastPatternTest646, 1); - UtRegisterTest("DetectFastPatternTest647", DetectFastPatternTest647, 1); - UtRegisterTest("DetectFastPatternTest648", DetectFastPatternTest648, 1); - UtRegisterTest("DetectFastPatternTest649", DetectFastPatternTest649, 1); - UtRegisterTest("DetectFastPatternTest650", DetectFastPatternTest650, 1); - UtRegisterTest("DetectFastPatternTest651", DetectFastPatternTest651, 1); - UtRegisterTest("DetectFastPatternTest652", DetectFastPatternTest652, 1); - UtRegisterTest("DetectFastPatternTest653", DetectFastPatternTest653, 1); - UtRegisterTest("DetectFastPatternTest654", DetectFastPatternTest654, 1); - UtRegisterTest("DetectFastPatternTest655", DetectFastPatternTest655, 1); - UtRegisterTest("DetectFastPatternTest656", DetectFastPatternTest656, 1); - UtRegisterTest("DetectFastPatternTest657", DetectFastPatternTest657, 1); - UtRegisterTest("DetectFastPatternTest658", DetectFastPatternTest658, 1); - UtRegisterTest("DetectFastPatternTest659", DetectFastPatternTest659, 1); - UtRegisterTest("DetectFastPatternTest660", DetectFastPatternTest660, 1); - UtRegisterTest("DetectFastPatternTest661", DetectFastPatternTest661, 1); - UtRegisterTest("DetectFastPatternTest662", DetectFastPatternTest662, 1); - UtRegisterTest("DetectFastPatternTest663", DetectFastPatternTest663, 1); - UtRegisterTest("DetectFastPatternTest664", DetectFastPatternTest664, 1); - UtRegisterTest("DetectFastPatternTest665", DetectFastPatternTest665, 1); - UtRegisterTest("DetectFastPatternTest666", DetectFastPatternTest666, 1); - UtRegisterTest("DetectFastPatternTest667", DetectFastPatternTest667, 1); - UtRegisterTest("DetectFastPatternTest668", DetectFastPatternTest668, 1); - UtRegisterTest("DetectFastPatternTest669", DetectFastPatternTest669, 1); - UtRegisterTest("DetectFastPatternTest670", DetectFastPatternTest670, 1); - - /* Unittest to check - * - if we assign different content_ids to duplicate patterns, but one of the - * patterns has a fast_pattern chop set. - * - if 2 unique patterns get unique ids. - * - if 2 duplicate patterns, with no chop set get unique ids. - */ - UtRegisterTest("DetectFastPatternTest671", DetectFastPatternTest671, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/detect-fast-pattern.h b/framework/src/suricata/src/detect-fast-pattern.h deleted file mode 100644 index 8298e7bb..00000000 --- a/framework/src/suricata/src/detect-fast-pattern.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_FAST_PATTERN_H__ -#define __DETECT_FAST_PATTERN_H__ - -typedef struct SCFPSupportSMList_ { - /* the list id. Have a look at Signature->sm_lists[] */ - int list_id; - int priority; - - struct SCFPSupportSMList_ *next; -} SCFPSupportSMList; - -extern SCFPSupportSMList *sm_fp_support_smlist_list; - -/** - * \brief Checks if a particular list(Signature->sm_lists[]) is in the list - * of lists that need to be searched for a keyword that has fp support. - * - * \param list_id The list id. - * - * \retval 1 If supported. - * \retval 0 If not. - */ -static inline int FastPatternSupportEnabledForSigMatchList(int list_id) -{ - if (sm_fp_support_smlist_list == NULL) - return 0; - - SCFPSupportSMList *tmp_smlist_fp = sm_fp_support_smlist_list; - while (tmp_smlist_fp != NULL) { - if (tmp_smlist_fp->list_id == list_id) - return 1; - - tmp_smlist_fp = tmp_smlist_fp->next; - } - - return 0; -} - -void SupportFastPatternForSigMatchTypes(void); - -void DetectFastPatternRegister(void); - -#endif /* __DETECT_FAST_PATTERN_H__ */ - diff --git a/framework/src/suricata/src/detect-file-data.c b/framework/src/suricata/src/detect-file-data.c deleted file mode 100644 index 258a135c..00000000 --- a/framework/src/suricata/src/detect-file-data.c +++ /dev/null @@ -1,280 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-spm-bm.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -static int DetectFiledataSetup (DetectEngineCtx *, Signature *, char *); -static void DetectFiledataRegisterTests(void); -/** - * \brief Registration function for keyword: file_data - */ -void DetectFiledataRegister(void) -{ - sigmatch_table[DETECT_FILE_DATA].name = "file_data"; - sigmatch_table[DETECT_FILE_DATA].desc = "make content keywords match on HTTP response body"; - sigmatch_table[DETECT_FILE_DATA].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#file_data"; - sigmatch_table[DETECT_FILE_DATA].Match = NULL; - sigmatch_table[DETECT_FILE_DATA].AppLayerMatch = NULL; - sigmatch_table[DETECT_FILE_DATA].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_FILE_DATA].Setup = DetectFiledataSetup; - sigmatch_table[DETECT_FILE_DATA].Free = NULL; - sigmatch_table[DETECT_FILE_DATA].RegisterTests = DetectFiledataRegisterTests; - sigmatch_table[DETECT_FILE_DATA].flags = SIGMATCH_NOOPT; -} - -/** - * \brief this function is used to parse filedata options - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param str pointer to the user provided "filestore" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFiledataSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - SCEnter(); - - if (!DetectProtoContainsProto(&s->proto, IPPROTO_TCP) && - s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP && - s->alproto != ALPROTO_SMTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - return -1; - } - - if (s->alproto == ALPROTO_HTTP && (s->init_flags & SIG_FLAG_INIT_FLOW) && - (s->flags & SIG_FLAG_TOSERVER) && !(s->flags & SIG_FLAG_TOCLIENT)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Can't use file_data with flow:to_server or from_client with http."); - return -1; - } - - if (s->alproto == ALPROTO_SMTP && (s->init_flags & SIG_FLAG_INIT_FLOW) && - !(s->flags & SIG_FLAG_TOSERVER) && (s->flags & SIG_FLAG_TOCLIENT)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Can't use file_data with flow:to_client or from_server with smtp."); - return -1; - } - - s->list = DETECT_SM_LIST_FILEDATA; - - return 0; -} - -#ifdef UNITTESTS -static int DetectFiledataParseTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert smtp any any -> any any " - "(msg:\"test\"; file_data; content:\"abc\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("content is still in FILEDATA list: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("content not in FILEDATA list: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -static int DetectFiledataParseTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; file_data; content:\"abc\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("content is still in PMATCH list: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("content not in FILEDATA list: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -static int DetectFiledataParseTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any 25 " - "(msg:\"test\"; flow:to_server,established; file_data; content:\"abc\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("content is still in PMATCH list: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("content not in FILEDATA list: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -static int DetectFiledataParseTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert smtp any any -> any any " - "(msg:\"test\"; flow:to_client,established; file_data; content:\"abc\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -static int DetectFiledataParseTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert http any any -> any any " - "(msg:\"test\"; flow:to_server,established; file_data; content:\"abc\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} -#endif - -void DetectFiledataRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectFiledataParseTest01", DetectFiledataParseTest01, 1); - UtRegisterTest("DetectFiledataParseTest02", DetectFiledataParseTest02, 1); - UtRegisterTest("DetectFiledataParseTest03", DetectFiledataParseTest03, 1); - UtRegisterTest("DetectFiledataParseTest04", DetectFiledataParseTest04, 0); - UtRegisterTest("DetectFiledataParseTest05", DetectFiledataParseTest05, 0); -#endif -} diff --git a/framework/src/suricata/src/detect-file-data.h b/framework/src/suricata/src/detect-file-data.h deleted file mode 100644 index 41cdd734..00000000 --- a/framework/src/suricata/src/detect-file-data.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_FILEDATA_H__ -#define __DETECT_FILEDATA_H__ - -/* prototypes */ -void DetectFiledataRegister (void); - -#endif /* __DETECT_FILEDATA_H__ */ diff --git a/framework/src/suricata/src/detect-fileext.c b/framework/src/suricata/src/detect-fileext.c deleted file mode 100644 index 7b5e9103..00000000 --- a/framework/src/suricata/src/detect-fileext.c +++ /dev/null @@ -1,315 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon - * - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm-bm.h" -#include "util-print.h" -#include "util-memcmp.h" - -#include "app-layer.h" - -#include "stream-tcp.h" -#include "detect-fileext.h" - -static int DetectFileextMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t, File *, Signature *, SigMatch *); -static int DetectFileextSetup (DetectEngineCtx *, Signature *, char *); -static void DetectFileextRegisterTests(void); -static void DetectFileextFree(void *); - -/** - * \brief Registration function for keyword: fileext - */ -void DetectFileextRegister(void) -{ - sigmatch_table[DETECT_FILEEXT].name = "fileext"; - sigmatch_table[DETECT_FILEEXT].desc = "match on the extension of a file name"; - sigmatch_table[DETECT_FILEEXT].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/File-keywords#fileext"; - sigmatch_table[DETECT_FILEEXT].FileMatch = DetectFileextMatch; - sigmatch_table[DETECT_FILEEXT].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_FILEEXT].Setup = DetectFileextSetup; - sigmatch_table[DETECT_FILEEXT].Free = DetectFileextFree; - sigmatch_table[DETECT_FILEEXT].RegisterTests = DetectFileextRegisterTests; - - SCLogDebug("registering fileext rule option"); - return; -} - -/** - * \brief match the specified file extension - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param f *LOCKED* flow - * \param flags direction flags - * \param file file being inspected - * \param s signature being inspected - * \param m sigmatch that we will cast into DetectFileextData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectFileextMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, File *file, Signature *s, SigMatch *m) -{ - SCEnter(); - int ret = 0; - - DetectFileextData *fileext = (DetectFileextData *)m->ctx; - - if (file->name == NULL) - SCReturnInt(0); - - if (file->txid < det_ctx->tx_id) - SCReturnInt(0); - - if (file->txid > det_ctx->tx_id) - SCReturnInt(0); - - if (file->name_len <= fileext->len) - SCReturnInt(0); - - int offset = file->name_len - fileext->len; - - /* fileext->ext is already in lowercase, as SCMemcmpLowercase requires */ - if (file->name[offset - 1] == '.' && - SCMemcmpLowercase(fileext->ext, file->name + offset, fileext->len) == 0) - { - if (!(fileext->flags & DETECT_CONTENT_NEGATED)) { - ret = 1; - SCLogDebug("File ext found"); - } - } - - if (ret == 0 && (fileext->flags & DETECT_CONTENT_NEGATED)) { - SCLogDebug("negated match"); - ret = 1; - } - - SCReturnInt(ret); -} - -/** - * \brief This function is used to parse fileet - * - * \param str Pointer to the fileext value string - * - * \retval pointer to DetectFileextData on success - * \retval NULL on failure - */ -static DetectFileextData *DetectFileextParse (char *str) -{ - DetectFileextData *fileext = NULL; - - /* We have a correct filename option */ - fileext = SCMalloc(sizeof(DetectFileextData)); - if (unlikely(fileext == NULL)) - goto error; - - memset(fileext, 0x00, sizeof(DetectFileextData)); - - if (DetectContentDataParse("fileext", str, &fileext->ext, &fileext->len, &fileext->flags) == -1) { - goto error; - } - uint16_t u; - for (u = 0; u < fileext->len; u++) - fileext->ext[u] = tolower(fileext->ext[u]); - - SCLogDebug("flags %02X", fileext->flags); - if (fileext->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("negated fileext"); - } - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - char *ext = SCMalloc(fileext->len + 1); - if (ext != NULL) { - memcpy(ext, fileext->ext, fileext->len); - ext[fileext->len] = '\0'; - SCLogDebug("will look for fileext %s", ext); - } - } -#endif - - return fileext; - -error: - if (fileext != NULL) - DetectFileextFree(fileext); - return NULL; - -} - -/** - * \brief this function is used to add the parsed "id" option - * into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param idstr pointer to the user provided "id" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFileextSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectFileextData *fileext= NULL; - SigMatch *sm = NULL; - - fileext = DetectFileextParse(str); - if (fileext == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FILEEXT; - sm->ctx = (void *)fileext; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEMATCH); - - if (s->alproto != ALPROTO_HTTP && s->alproto != ALPROTO_SMTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - if (s->alproto == ALPROTO_HTTP) { - AppLayerHtpNeedFileInspection(); - } - - s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_FILENAME); - return 0; - -error: - if (fileext != NULL) - DetectFileextFree(fileext); - if (sm != NULL) - SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectFileextData - * - * \param fileext pointer to DetectFileextData - */ -static void DetectFileextFree(void *ptr) -{ - if (ptr != NULL) { - DetectFileextData *fileext = (DetectFileextData *)ptr; - if (fileext->ext != NULL) - SCFree(fileext->ext); - SCFree(fileext); - } -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectFileextTestParse01 - */ -int DetectFileextTestParse01 (void) -{ - DetectFileextData *dfd = DetectFileextParse("\"doc\""); - if (dfd != NULL) { - DetectFileextFree(dfd); - return 1; - } - return 0; -} - -/** - * \test DetectFileextTestParse02 - */ -int DetectFileextTestParse02 (void) -{ - int result = 0; - - DetectFileextData *dfd = DetectFileextParse("\"tar.gz\""); - if (dfd != NULL) { - if (dfd->len == 6 && memcmp(dfd->ext, "tar.gz", 6) == 0) { - result = 1; - } - - DetectFileextFree(dfd); - return result; - } - return 0; -} - -/** - * \test DetectFileextTestParse03 - */ -int DetectFileextTestParse03 (void) -{ - int result = 0; - - DetectFileextData *dfd = DetectFileextParse("\"pdf\""); - if (dfd != NULL) { - if (dfd->len == 3 && memcmp(dfd->ext, "pdf", 3) == 0) { - result = 1; - } - - DetectFileextFree(dfd); - return result; - } - return 0; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectFileext - */ -void DetectFileextRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectFileextTestParse01", DetectFileextTestParse01, 1); - UtRegisterTest("DetectFileextTestParse02", DetectFileextTestParse02, 1); - UtRegisterTest("DetectFileextTestParse03", DetectFileextTestParse03, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-fileext.h b/framework/src/suricata/src/detect-fileext.h deleted file mode 100644 index 4981763b..00000000 --- a/framework/src/suricata/src/detect-fileext.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_FILEEXT_H__ -#define __DETECT_FILEEXT_H__ - -#include "util-spm-bm.h" - -typedef struct DetectFileextData_ { - uint8_t *ext; /** file extension to match */ - uint16_t len; /** length of the file */ - uint32_t flags; -} DetectFileextData; - -/* prototypes */ -void DetectFileextRegister (void); - -#endif /* __DETECT_FILEEXT_H__ */ diff --git a/framework/src/suricata/src/detect-filemagic.c b/framework/src/suricata/src/detect-filemagic.c deleted file mode 100644 index 5dd28ec8..00000000 --- a/framework/src/suricata/src/detect-filemagic.c +++ /dev/null @@ -1,498 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-spm-bm.h" -#include "util-magic.h" -#include "util-print.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" - -#include "stream-tcp.h" - -#include "detect-filemagic.h" - -#include "conf.h" -#include "util-magic.h" - -static int DetectFilemagicMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t, File *, Signature *, SigMatch *); -static int DetectFilemagicSetup (DetectEngineCtx *, Signature *, char *); -static void DetectFilemagicRegisterTests(void); -static void DetectFilemagicFree(void *); - -/** - * \brief Registration function for keyword: filemagic - */ -void DetectFilemagicRegister(void) -{ - sigmatch_table[DETECT_FILEMAGIC].name = "filemagic"; - sigmatch_table[DETECT_FILEMAGIC].desc = "match on the information libmagic returns about a file"; - sigmatch_table[DETECT_FILEMAGIC].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/File-keywords#filemagic"; - sigmatch_table[DETECT_FILEMAGIC].FileMatch = DetectFilemagicMatch; - sigmatch_table[DETECT_FILEMAGIC].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_FILEMAGIC].Setup = DetectFilemagicSetup; - sigmatch_table[DETECT_FILEMAGIC].Free = DetectFilemagicFree; - sigmatch_table[DETECT_FILEMAGIC].RegisterTests = DetectFilemagicRegisterTests; - - SCLogDebug("registering filemagic rule option"); - return; -} - -#define FILEMAGIC_MIN_SIZE 512 - -/** - * \brief run the magic check - * - * \param file the file - * - * \retval -1 error - * \retval 0 ok - */ -int FilemagicGlobalLookup(File *file) -{ - if (file == NULL || file->chunks_head == NULL) { - SCReturnInt(-1); - } - - /* initial chunk already matching our requirement */ - if (file->chunks_head->len >= FILEMAGIC_MIN_SIZE) { - file->magic = MagicGlobalLookup(file->chunks_head->data, FILEMAGIC_MIN_SIZE); - } else { - uint8_t *buf = SCMalloc(FILEMAGIC_MIN_SIZE); - uint32_t size = 0; - - if (likely(buf != NULL)) { - FileData *ffd = file->chunks_head; - - for ( ; ffd != NULL; ffd = ffd->next) { - uint32_t copy_len = ffd->len; - if (size + ffd->len > FILEMAGIC_MIN_SIZE) - copy_len = FILEMAGIC_MIN_SIZE - size; - - memcpy(buf + size, ffd->data, copy_len); - size += copy_len; - - if (size >= FILEMAGIC_MIN_SIZE) { - file->magic = MagicGlobalLookup(buf, size); - break; - } - /* file is done but smaller than FILEMAGIC_MIN_SIZE */ - if (ffd->next == NULL && file->state >= FILE_STATE_CLOSED) { - file->magic = MagicGlobalLookup(buf, size); - break; - } - } - - SCFree(buf); - } - } - - SCReturnInt(0); -} - -/** - * \brief run the magic check - * - * \param file the file - * - * \retval -1 error - * \retval 0 ok - */ -int FilemagicThreadLookup(magic_t *ctx, File *file) -{ - if (ctx == NULL || file == NULL || file->chunks_head == NULL) { - SCReturnInt(-1); - } - - /* initial chunk already matching our requirement */ - if (file->chunks_head->len >= FILEMAGIC_MIN_SIZE) { - file->magic = MagicThreadLookup(ctx, file->chunks_head->data, FILEMAGIC_MIN_SIZE); - } else { - uint8_t *buf = SCMalloc(FILEMAGIC_MIN_SIZE); - uint32_t size = 0; - - if (likely(buf != NULL)) { - FileData *ffd = file->chunks_head; - - for ( ; ffd != NULL; ffd = ffd->next) { - uint32_t copy_len = ffd->len; - if (size + ffd->len > FILEMAGIC_MIN_SIZE) - copy_len = FILEMAGIC_MIN_SIZE - size; - - memcpy(buf + size, ffd->data, copy_len); - size += copy_len; - - if (size >= FILEMAGIC_MIN_SIZE) { - file->magic = MagicThreadLookup(ctx, buf, size); - break; - } - /* file is done but smaller than FILEMAGIC_MIN_SIZE */ - if (ffd->next == NULL && file->state >= FILE_STATE_CLOSED) { - file->magic = MagicThreadLookup(ctx, buf, size); - break; - } - } - - SCFree(buf); - } - } - - SCReturnInt(0); -} - -/** - * \brief match the specified filemagic - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param f *LOCKED* flow - * \param flags direction flags - * \param file file being inspected - * \param s signature being inspected - * \param m sigmatch that we will cast into DetectFilemagicData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectFilemagicMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, File *file, Signature *s, SigMatch *m) -{ - SCEnter(); - int ret = 0; - DetectFilemagicData *filemagic = (DetectFilemagicData *)m->ctx; - - if (file->txid < det_ctx->tx_id) - SCReturnInt(0); - - if (file->txid > det_ctx->tx_id) - SCReturnInt(0); - - DetectFilemagicThreadData *tfilemagic = (DetectFilemagicThreadData *)DetectThreadCtxGetKeywordThreadCtx(det_ctx, filemagic->thread_ctx_id); - if (tfilemagic == NULL) { - SCReturnInt(0); - } - - if (file->magic == NULL) { - FilemagicThreadLookup(&tfilemagic->ctx, file); - } - - if (file->magic != NULL) { - SCLogDebug("magic %s", file->magic); - - /* we include the \0 in the inspection, so patterns can match on the - * end of the string. */ - if (BoyerMooreNocase(filemagic->name, filemagic->len, (uint8_t *)file->magic, - strlen(file->magic) + 1, filemagic->bm_ctx) != NULL) - { -#ifdef DEBUG - if (SCLogDebugEnabled()) { - char *name = SCMalloc(filemagic->len + 1); - if (name != NULL) { - memcpy(name, filemagic->name, filemagic->len); - name[filemagic->len] = '\0'; - SCLogDebug("will look for filemagic %s", name); - } - } -#endif - - if (!(filemagic->flags & DETECT_CONTENT_NEGATED)) { - ret = 1; - } - } else if (filemagic->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("negated match"); - ret = 1; - } - } - - SCReturnInt(ret); -} - -/** - * \brief Parse the filemagic keyword - * - * \param idstr Pointer to the user provided option - * - * \retval filemagic pointer to DetectFilemagicData on success - * \retval NULL on failure - */ -static DetectFilemagicData *DetectFilemagicParse (char *str) -{ - DetectFilemagicData *filemagic = NULL; - - /* We have a correct filemagic option */ - filemagic = SCMalloc(sizeof(DetectFilemagicData)); - if (unlikely(filemagic == NULL)) - goto error; - - memset(filemagic, 0x00, sizeof(DetectFilemagicData)); - - if (DetectContentDataParse ("filemagic", str, &filemagic->name, &filemagic->len, &filemagic->flags) == -1) { - goto error; - } - - filemagic->bm_ctx = BoyerMooreNocaseCtxInit(filemagic->name, filemagic->len); - if (filemagic->bm_ctx == NULL) { - goto error; - } - - SCLogDebug("flags %02X", filemagic->flags); - if (filemagic->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("negated filemagic"); - } - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - char *name = SCMalloc(filemagic->len + 1); - if (name != NULL) { - memcpy(name, filemagic->name, filemagic->len); - name[filemagic->len] = '\0'; - SCLogDebug("will look for filemagic %s", name); - } - } -#endif - - return filemagic; - -error: - if (filemagic != NULL) - DetectFilemagicFree(filemagic); - return NULL; -} - -static void *DetectFilemagicThreadInit(void *data) -{ - char *filename = NULL; - FILE *fd = NULL; - DetectFilemagicData *filemagic = (DetectFilemagicData *)data; - BUG_ON(filemagic == NULL); - - DetectFilemagicThreadData *t = SCMalloc(sizeof(DetectFilemagicThreadData)); - if (unlikely(t == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "couldn't alloc ctx memory"); - return NULL; - } - memset(t, 0x00, sizeof(DetectFilemagicThreadData)); - - t->ctx = magic_open(0); - if (t->ctx == NULL) { - SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s", magic_error(t->ctx)); - goto error; - } - - (void)ConfGet("magic-file", &filename); - if (filename != NULL) { - SCLogInfo("using magic-file %s", filename); - - if ( (fd = fopen(filename, "r")) == NULL) { - SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, strerror(errno)); - goto error; - } - fclose(fd); - } - - if (magic_load(t->ctx, filename) != 0) { - SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s", magic_error(t->ctx)); - goto error; - } - - return (void *)t; - -error: - if (t->ctx) - magic_close(t->ctx); - SCFree(t); - return NULL; -} - -static void DetectFilemagicThreadFree(void *ctx) -{ - if (ctx != NULL) { - DetectFilemagicThreadData *t = (DetectFilemagicThreadData *)ctx; - if (t->ctx) - magic_close(t->ctx); - SCFree(t); - } -} - -/** - * \brief this function is used to parse filemagic options - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param str pointer to the user provided "filemagic" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFilemagicSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectFilemagicData *filemagic = NULL; - SigMatch *sm = NULL; - - filemagic = DetectFilemagicParse(str); - if (filemagic == NULL) - goto error; - - filemagic->thread_ctx_id = DetectRegisterThreadCtxFuncs(de_ctx, "filemagic", - DetectFilemagicThreadInit, (void *)filemagic, - DetectFilemagicThreadFree, 1); - if (filemagic->thread_ctx_id == -1) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FILEMAGIC; - sm->ctx = (void *)filemagic; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEMATCH); - - if (s->alproto != ALPROTO_HTTP && s->alproto != ALPROTO_SMTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - if (s->alproto == ALPROTO_HTTP) { - AppLayerHtpNeedFileInspection(); - } - - s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_MAGIC); - return 0; - -error: - if (filemagic != NULL) - DetectFilemagicFree(filemagic); - if (sm != NULL) - SCFree(sm); - return -1; -} - -/** - * \brief this function will free memory associated with DetectFilemagicData - * - * \param filemagic pointer to DetectFilemagicData - */ -static void DetectFilemagicFree(void *ptr) -{ - if (ptr != NULL) { - DetectFilemagicData *filemagic = (DetectFilemagicData *)ptr; - if (filemagic->bm_ctx != NULL) { - BoyerMooreCtxDeInit(filemagic->bm_ctx); - } - if (filemagic->name != NULL) - SCFree(filemagic->name); - SCFree(filemagic); - } -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectFilemagicTestParse01 - */ -int DetectFilemagicTestParse01 (void) -{ - DetectFilemagicData *dnd = DetectFilemagicParse("\"secret.pdf\""); - if (dnd != NULL) { - DetectFilemagicFree(dnd); - return 1; - } - return 0; -} - -/** - * \test DetectFilemagicTestParse02 - */ -int DetectFilemagicTestParse02 (void) -{ - int result = 0; - - DetectFilemagicData *dnd = DetectFilemagicParse("\"backup.tar.gz\""); - if (dnd != NULL) { - if (dnd->len == 13 && memcmp(dnd->name, "backup.tar.gz", 13) == 0) { - result = 1; - } - - DetectFilemagicFree(dnd); - return result; - } - return 0; -} - -/** - * \test DetectFilemagicTestParse03 - */ -int DetectFilemagicTestParse03 (void) -{ - int result = 0; - - DetectFilemagicData *dnd = DetectFilemagicParse("\"cmd.exe\""); - if (dnd != NULL) { - if (dnd->len == 7 && memcmp(dnd->name, "cmd.exe", 7) == 0) { - result = 1; - } - - DetectFilemagicFree(dnd); - return result; - } - return 0; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectFilemagic - */ -void DetectFilemagicRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectFilemagicTestParse01", DetectFilemagicTestParse01, 1); - UtRegisterTest("DetectFilemagicTestParse02", DetectFilemagicTestParse02, 1); - UtRegisterTest("DetectFilemagicTestParse03", DetectFilemagicTestParse03, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-filemagic.h b/framework/src/suricata/src/detect-filemagic.h deleted file mode 100644 index 97cd7954..00000000 --- a/framework/src/suricata/src/detect-filemagic.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_FILEMAGIC_H__ -#define __DETECT_FILEMAGIC_H__ - -#include "util-spm-bm.h" -#include - -typedef struct DetectFilemagicThreadData { - magic_t ctx; -} DetectFilemagicThreadData; - -typedef struct DetectFilemagicData { - int thread_ctx_id; - uint8_t *name; /** name of the file to match */ - BmCtx *bm_ctx; /** BM context */ - uint16_t len; /** name length */ - uint32_t flags; -} DetectFilemagicData; - -/* prototypes */ -void DetectFilemagicRegister (void); -int FilemagicGlobalLookup(File *file); - -#endif /* __DETECT_FILEMAGIC_H__ */ diff --git a/framework/src/suricata/src/detect-filemd5.c b/framework/src/suricata/src/detect-filemd5.c deleted file mode 100644 index 87f3f35e..00000000 --- a/framework/src/suricata/src/detect-filemd5.c +++ /dev/null @@ -1,428 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-spm-bm.h" -#include "util-print.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" - -#include "stream-tcp.h" - -#include "detect-filemd5.h" - -#include "queue.h" -#include "util-rohash.h" - -#ifndef HAVE_NSS - -static int DetectFileMd5SetupNoSupport (DetectEngineCtx *a, Signature *b, char *c) -{ - SCLogError(SC_ERR_NO_MD5_SUPPORT, "no MD5 calculation support built in, needed for filemd5 keyword"); - return -1; -} - -/** - * \brief Registration function for keyword: filemd5 - */ -void DetectFileMd5Register(void) -{ - sigmatch_table[DETECT_FILEMD5].name = "filemd5"; - sigmatch_table[DETECT_FILEMD5].FileMatch = NULL; - sigmatch_table[DETECT_FILEMD5].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_FILEMD5].Setup = DetectFileMd5SetupNoSupport; - sigmatch_table[DETECT_FILEMD5].Free = NULL; - sigmatch_table[DETECT_FILEMD5].RegisterTests = NULL; - sigmatch_table[DETECT_FILEMD5].flags = SIGMATCH_NOT_BUILT; - - SCLogDebug("registering filemd5 rule option"); - return; -} - -#else /* HAVE_NSS */ - -static int DetectFileMd5Match (ThreadVars *, DetectEngineThreadCtx *, - Flow *, uint8_t, File *, Signature *, SigMatch *); -static int DetectFileMd5Setup (DetectEngineCtx *, Signature *, char *); -static void DetectFileMd5RegisterTests(void); -static void DetectFileMd5Free(void *); - -/** - * \brief Registration function for keyword: filemd5 - */ -void DetectFileMd5Register(void) -{ - sigmatch_table[DETECT_FILEMD5].name = "filemd5"; - sigmatch_table[DETECT_FILEMD5].desc = "match file MD5 against list of MD5 checksums"; - sigmatch_table[DETECT_FILEMD5].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/File-keywords#filemd5"; - sigmatch_table[DETECT_FILEMD5].FileMatch = DetectFileMd5Match; - sigmatch_table[DETECT_FILEMD5].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_FILEMD5].Setup = DetectFileMd5Setup; - sigmatch_table[DETECT_FILEMD5].Free = DetectFileMd5Free; - sigmatch_table[DETECT_FILEMD5].RegisterTests = DetectFileMd5RegisterTests; - - SCLogDebug("registering filemd5 rule option"); - return; -} - -static int Md5ReadString(uint8_t *md5, char *str, char *filename, int line_no) -{ - if (strlen(str) != 32) { - SCLogError(SC_ERR_INVALID_MD5, "%s:%d md5 string not 32 bytes", - filename, line_no); - return -1; - } - - int i, x; - for (x = 0, i = 0; i < 32; i+=2, x++) { - char buf[3] = { 0, 0, 0}; - buf[0] = str[i]; - buf[1] = str[i+1]; - - long value = strtol(buf, NULL, 16); - if (value >= 0 && value <= 255) - md5[x] = (uint8_t)value; - else { - SCLogError(SC_ERR_INVALID_MD5, "%s:%d md5 byte out of range %ld", - filename, line_no, value); - return -1; - } - } - - return 1; -} - -static int MD5LoadHash(ROHashTable *hash, char *string, char *filename, int line_no) -{ - uint8_t md5[16]; - - if (Md5ReadString(md5, string, filename, line_no) == 1) { - if (ROHashInitQueueValue(hash, &md5, (uint16_t)sizeof(md5)) != 1) - return -1; - } - - return 1; -} - -static int MD5MatchLookupBuffer(ROHashTable *hash, uint8_t *buf, size_t buflen) -{ - void *ptr = ROHashLookup(hash, buf, (uint16_t)buflen); - if (ptr == NULL) - return 0; - else - return 1; -} - -/** - * \brief match the specified filemd5 - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param f *LOCKED* flow - * \param flags direction flags - * \param file file being inspected - * \param s signature being inspected - * \param m sigmatch that we will cast into DetectFileMd5Data - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectFileMd5Match (ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, File *file, Signature *s, SigMatch *m) -{ - SCEnter(); - int ret = 0; - DetectFileMd5Data *filemd5 = (DetectFileMd5Data *)m->ctx; - - if (file->txid < det_ctx->tx_id) { - SCReturnInt(0); - } - - if (file->txid > det_ctx->tx_id) { - SCReturnInt(0); - } - - if (file->state != FILE_STATE_CLOSED) { - SCReturnInt(0); - } - - if (file->flags & FILE_MD5) { - if (MD5MatchLookupBuffer(filemd5->hash, file->md5, sizeof(file->md5)) == 1) { - if (filemd5->negated == 0) - ret = 1; - else - ret = 0; - } else { - if (filemd5->negated == 0) - ret = 0; - else - ret = 1; - } - } - - SCReturnInt(ret); -} - -/** - * \brief Parse the filemd5 keyword - * - * \param idstr Pointer to the user provided option - * - * \retval filemd5 pointer to DetectFileMd5Data on success - * \retval NULL on failure - */ -static DetectFileMd5Data *DetectFileMd5Parse (const DetectEngineCtx *de_ctx, char *str) -{ - DetectFileMd5Data *filemd5 = NULL; - FILE *fp = NULL; - char *filename = NULL; - - /* We have a correct filemd5 option */ - filemd5 = SCMalloc(sizeof(DetectFileMd5Data)); - if (unlikely(filemd5 == NULL)) - goto error; - - memset(filemd5, 0x00, sizeof(DetectFileMd5Data)); - - if (strlen(str) && str[0] == '!') { - filemd5->negated = 1; - str++; - } - - filemd5->hash = ROHashInit(18, 16); - if (filemd5->hash == NULL) { - goto error; - } - - /* get full filename */ - filename = DetectLoadCompleteSigPath(de_ctx, str); - if (filename == NULL) { - goto error; - } - - char line[8192] = ""; - fp = fopen(filename, "r"); - if (fp == NULL) { - SCLogError(SC_ERR_OPENING_RULE_FILE, "opening md5 file %s: %s", filename, strerror(errno)); - goto error; - } - - int line_no = 0; - while(fgets(line, (int)sizeof(line), fp) != NULL) { - size_t len = strlen(line); - line_no++; - - /* ignore comments and empty lines */ - if (line[0] == '\n' || line [0] == '\r' || line[0] == ' ' || line[0] == '#' || line[0] == '\t') - continue; - - while (isspace(line[--len])); - - /* Check if we have a trailing newline, and remove it */ - len = strlen(line); - if (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) { - line[len - 1] = '\0'; - } - - /* cut off longer lines */ - if (strlen(line) > 32) - line[32] = 0x00; - - if (MD5LoadHash(filemd5->hash, line, filename, line_no) != 1) { - goto error; - } - } - fclose(fp); - fp = NULL; - - if (ROHashInitFinalize(filemd5->hash) != 1) { - goto error; - } - SCLogInfo("MD5 hash size %u bytes%s", ROHashMemorySize(filemd5->hash), filemd5->negated ? ", negated match" : ""); - - SCFree(filename); - return filemd5; - -error: - if (filemd5 != NULL) - DetectFileMd5Free(filemd5); - if (fp != NULL) - fclose(fp); - if (filename != NULL) - SCFree(filename); - return NULL; -} - -/** - * \brief this function is used to parse filemd5 options - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param str pointer to the user provided "filemd5" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFileMd5Setup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectFileMd5Data *filemd5 = NULL; - SigMatch *sm = NULL; - - filemd5 = DetectFileMd5Parse(de_ctx, str); - if (filemd5 == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FILEMD5; - sm->ctx = (void *)filemd5; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEMATCH); - - if (s->alproto != ALPROTO_HTTP && s->alproto != ALPROTO_SMTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - if (s->alproto == ALPROTO_HTTP) { - AppLayerHtpNeedFileInspection(); - } - - s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_MD5); - return 0; - -error: - if (filemd5 != NULL) - DetectFileMd5Free(filemd5); - if (sm != NULL) - SCFree(sm); - return -1; -} - -/** - * \brief this function will free memory associated with DetectFileMd5Data - * - * \param filemd5 pointer to DetectFileMd5Data - */ -static void DetectFileMd5Free(void *ptr) -{ - if (ptr != NULL) { - DetectFileMd5Data *filemd5 = (DetectFileMd5Data *)ptr; - if (filemd5->hash != NULL) - ROHashFree(filemd5->hash); - SCFree(filemd5); - } -} - -#ifdef UNITTESTS -static int MD5MatchLookupString(ROHashTable *hash, char *string) -{ - uint8_t md5[16]; - if (Md5ReadString(md5, string, "file", 88) == 1) { - void *ptr = ROHashLookup(hash, &md5, (uint16_t)sizeof(md5)); - if (ptr == NULL) - return 0; - else - return 1; - } - return 0; -} - -static int MD5MatchTest01(void) -{ - ROHashTable *hash = ROHashInit(4, 16); - if (hash == NULL) { - return 0; - } - if (MD5LoadHash(hash, "d80f93a93dc5f3ee945704754d6e0a36", "file", 1) != 1) - return 0; - if (MD5LoadHash(hash, "92a49985b384f0d993a36e4c2d45e206", "file", 2) != 1) - return 0; - if (MD5LoadHash(hash, "11adeaacc8c309815f7bc3e33888f281", "file", 3) != 1) - return 0; - if (MD5LoadHash(hash, "22e10a8fe02344ade0bea8836a1714af", "file", 4) != 1) - return 0; - if (MD5LoadHash(hash, "c3db2cbf02c68f073afcaee5634677bc", "file", 5) != 1) - return 0; - if (MD5LoadHash(hash, "7ed095da259638f42402fb9e74287a17", "file", 6) != 1) - return 0; - - if (ROHashInitFinalize(hash) != 1) { - return 0; - } - - if (MD5MatchLookupString(hash, "d80f93a93dc5f3ee945704754d6e0a36") != 1) - return 0; - if (MD5MatchLookupString(hash, "92a49985b384f0d993a36e4c2d45e206") != 1) - return 0; - if (MD5MatchLookupString(hash, "11adeaacc8c309815f7bc3e33888f281") != 1) - return 0; - if (MD5MatchLookupString(hash, "22e10a8fe02344ade0bea8836a1714af") != 1) - return 0; - if (MD5MatchLookupString(hash, "c3db2cbf02c68f073afcaee5634677bc") != 1) - return 0; - if (MD5MatchLookupString(hash, "7ed095da259638f42402fb9e74287a17") != 1) - return 0; - /* shouldnt match */ - if (MD5MatchLookupString(hash, "33333333333333333333333333333333") == 1) - return 0; - - ROHashFree(hash); - return 1; -} -#endif - -void DetectFileMd5RegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("MD5MatchTest01", MD5MatchTest01, 1); -#endif -} - -#endif /* HAVE_NSS */ - diff --git a/framework/src/suricata/src/detect-filemd5.h b/framework/src/suricata/src/detect-filemd5.h deleted file mode 100644 index 486812f7..00000000 --- a/framework/src/suricata/src/detect-filemd5.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_FILEMD5_H__ -#define __DETECT_FILEMD5_H__ - -#include "util-rohash.h" - -typedef struct DetectFileMd5Data { - ROHashTable *hash; - int negated; -} DetectFileMd5Data; - -/* prototypes */ -void DetectFileMd5Register (void); - -#endif /* __DETECT_FILEMD5_H__ */ diff --git a/framework/src/suricata/src/detect-filename.c b/framework/src/suricata/src/detect-filename.c deleted file mode 100644 index 8e5ddc1c..00000000 --- a/framework/src/suricata/src/detect-filename.c +++ /dev/null @@ -1,321 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon - * - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-spm-bm.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" - -#include "stream-tcp.h" - -#include "detect-filename.h" - -static int DetectFilenameMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t, File *, Signature *, SigMatch *); -static int DetectFilenameSetup (DetectEngineCtx *, Signature *, char *); -static void DetectFilenameRegisterTests(void); -static void DetectFilenameFree(void *); - -/** - * \brief Registration function for keyword: filename - */ -void DetectFilenameRegister(void) -{ - sigmatch_table[DETECT_FILENAME].name = "filename"; - sigmatch_table[DETECT_FILENAME].desc = "match on the file name"; - sigmatch_table[DETECT_FILENAME].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/File-keywords#filename"; - sigmatch_table[DETECT_FILENAME].FileMatch = DetectFilenameMatch; - sigmatch_table[DETECT_FILENAME].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_FILENAME].Setup = DetectFilenameSetup; - sigmatch_table[DETECT_FILENAME].Free = DetectFilenameFree; - sigmatch_table[DETECT_FILENAME].RegisterTests = DetectFilenameRegisterTests; - - SCLogDebug("registering filename rule option"); - return; -} - -/** - * \brief match the specified filename - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param f *LOCKED* flow - * \param flags direction flags - * \param file file being inspected - * \param s signature being inspected - * \param m sigmatch that we will cast into DetectFilenameData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectFilenameMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, File *file, Signature *s, SigMatch *m) -{ - SCEnter(); - int ret = 0; - - DetectFilenameData *filename = (DetectFilenameData *)m->ctx; - - if (file->name == NULL) - SCReturnInt(0); - - if (file->txid < det_ctx->tx_id) - SCReturnInt(0); - - if (file->txid > det_ctx->tx_id) - SCReturnInt(0); - - if (BoyerMooreNocase(filename->name, filename->len, file->name, - file->name_len, filename->bm_ctx) != NULL) - { -#ifdef DEBUG - if (SCLogDebugEnabled()) { - char *name = SCMalloc(filename->len + 1); - if (name != NULL) { - memcpy(name, filename->name, filename->len); - name[filename->len] = '\0'; - SCLogDebug("will look for filename %s", name); - } - } -#endif - - if (!(filename->flags & DETECT_CONTENT_NEGATED)) { - ret = 1; - } - } - - if (ret == 0 && (filename->flags & DETECT_CONTENT_NEGATED)) { - SCLogDebug("negated match"); - ret = 1; - } - - SCReturnInt(ret); -} - -/** - * \brief Parse the filename keyword - * - * \param idstr Pointer to the user provided option - * - * \retval filename pointer to DetectFilenameData on success - * \retval NULL on failure - */ -static DetectFilenameData *DetectFilenameParse (char *str) -{ - DetectFilenameData *filename = NULL; - - /* We have a correct filename option */ - filename = SCMalloc(sizeof(DetectFilenameData)); - if (unlikely(filename == NULL)) - goto error; - - memset(filename, 0x00, sizeof(DetectFilenameData)); - - if (DetectContentDataParse ("filename", str, &filename->name, &filename->len, &filename->flags) == -1) { - goto error; - } - - filename->bm_ctx = BoyerMooreNocaseCtxInit(filename->name, filename->len); - if (filename->bm_ctx == NULL) { - goto error; - } - - SCLogDebug("flags %02X", filename->flags); - if (filename->flags & DETECT_CONTENT_NEGATED) { - SCLogDebug("negated filename"); - } - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - char *name = SCMalloc(filename->len + 1); - if (name != NULL) { - memcpy(name, filename->name, filename->len); - name[filename->len] = '\0'; - SCLogDebug("will look for filename %s", name); - } - } -#endif - - return filename; - -error: - if (filename != NULL) - DetectFilenameFree(filename); - return NULL; -} - -/** - * \brief this function is used to parse filename options - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param str pointer to the user provided "filename" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFilenameSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectFilenameData *filename = NULL; - SigMatch *sm = NULL; - - filename = DetectFilenameParse(str); - if (filename == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FILENAME; - sm->ctx = (void *)filename; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEMATCH); - - if (s->alproto != ALPROTO_HTTP && s->alproto != ALPROTO_SMTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - if (s->alproto == ALPROTO_HTTP) { - AppLayerHtpNeedFileInspection(); - } - - s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_FILENAME); - return 0; - -error: - if (filename != NULL) - DetectFilenameFree(filename); - if (sm != NULL) - SCFree(sm); - return -1; -} - -/** - * \brief this function will free memory associated with DetectFilenameData - * - * \param filename pointer to DetectFilenameData - */ -static void DetectFilenameFree(void *ptr) -{ - if (ptr != NULL) { - DetectFilenameData *filename = (DetectFilenameData *)ptr; - if (filename->bm_ctx != NULL) { - BoyerMooreCtxDeInit(filename->bm_ctx); - } - if (filename->name != NULL) - SCFree(filename->name); - SCFree(filename); - } -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectFilenameTestParse01 - */ -int DetectFilenameTestParse01 (void) -{ - DetectFilenameData *dnd = DetectFilenameParse("\"secret.pdf\""); - if (dnd != NULL) { - DetectFilenameFree(dnd); - return 1; - } - return 0; -} - -/** - * \test DetectFilenameTestParse02 - */ -int DetectFilenameTestParse02 (void) -{ - int result = 0; - - DetectFilenameData *dnd = DetectFilenameParse("\"backup.tar.gz\""); - if (dnd != NULL) { - if (dnd->len == 13 && memcmp(dnd->name, "backup.tar.gz", 13) == 0) { - result = 1; - } - - DetectFilenameFree(dnd); - return result; - } - return 0; -} - -/** - * \test DetectFilenameTestParse03 - */ -int DetectFilenameTestParse03 (void) -{ - int result = 0; - - DetectFilenameData *dnd = DetectFilenameParse("\"cmd.exe\""); - if (dnd != NULL) { - if (dnd->len == 7 && memcmp(dnd->name, "cmd.exe", 7) == 0) { - result = 1; - } - - DetectFilenameFree(dnd); - return result; - } - return 0; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectFilename - */ -void DetectFilenameRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectFilenameTestParse01", DetectFilenameTestParse01, 1); - UtRegisterTest("DetectFilenameTestParse02", DetectFilenameTestParse02, 1); - UtRegisterTest("DetectFilenameTestParse03", DetectFilenameTestParse03, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-filename.h b/framework/src/suricata/src/detect-filename.h deleted file mode 100644 index 7204f36d..00000000 --- a/framework/src/suricata/src/detect-filename.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_FILENAME_H__ -#define __DETECT_FILENAME_H__ - -#include "util-spm-bm.h" - -typedef struct DetectFilenameData { - uint8_t *name; /** name of the file to match */ - BmCtx *bm_ctx; /** BM context */ - uint16_t len; /** name length */ - uint32_t flags; -} DetectFilenameData; - -/* prototypes */ -void DetectFilenameRegister (void); - -#endif /* __DETECT_FILENAME_H__ */ diff --git a/framework/src/suricata/src/detect-filesize.c b/framework/src/suricata/src/detect-filesize.c deleted file mode 100644 index 17a01216..00000000 --- a/framework/src/suricata/src/detect-filesize.c +++ /dev/null @@ -1,532 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the filesize keyword - */ - -#include "suricata-common.h" -#include "app-layer-protos.h" -#include "app-layer-htp.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine-state.h" - -#include "detect-filesize.h" -#include "util-debug.h" -#include "util-byte.h" -#include "flow-util.h" -#include "stream-tcp.h" - -/** - * \brief Regex for parsing our filesize - */ -#define PARSE_REGEX "^(?:\\s*)(<|>)?(?:\\s*)([0-9]{1,23})(?:\\s*)(?:(<>)(?:\\s*)([0-9]{1,23}))?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -/*prototypes*/ -static int DetectFilesizeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, - uint8_t flags, File *file, Signature *s, SigMatch *m); -static int DetectFilesizeSetup (DetectEngineCtx *, Signature *, char *); -static void DetectFilesizeFree (void *); -static void DetectFilesizeRegisterTests (void); - -/** - * \brief Registration function for filesize: keyword - */ - -void DetectFilesizeRegister(void) -{ - sigmatch_table[DETECT_FILESIZE].name = "filesize"; - sigmatch_table[DETECT_FILESIZE].desc = "match on the size of the file as it is being transferred"; - sigmatch_table[DETECT_FILESIZE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/File-keywords#filesize"; - sigmatch_table[DETECT_FILESIZE].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_FILESIZE].FileMatch = DetectFilesizeMatch; - sigmatch_table[DETECT_FILESIZE].Setup = DetectFilesizeSetup; - sigmatch_table[DETECT_FILESIZE].Free = DetectFilesizeFree; - sigmatch_table[DETECT_FILESIZE].RegisterTests = DetectFilesizeRegisterTests; - sigmatch_table[DETECT_FILESIZE].flags |= SIGMATCH_PAYLOAD; /** XXX necessary? */ - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogDebug("pcre compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogDebug("pcre study failed: %s", eb); - goto error; - } - return; - -error: - if (parse_regex != NULL) - SCFree(parse_regex); - if (parse_regex_study != NULL) - SCFree(parse_regex_study); - return; -} - -/** - * \brief This function is used to match filesize rule option. - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param f *LOCKED* flow - * \param flags direction flags - * \param file file being inspected - * \param s signature being inspected - * \param m sigmatch that we will cast into DetectFilesizeData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectFilesizeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, - uint8_t flags, File *file, Signature *s, SigMatch *m) -{ - SCEnter(); - - DetectFilesizeData *fsd = (DetectFilesizeData *)m->ctx; - int ret = 0; - SCLogDebug("file size %"PRIu64", check %"PRIu64, file->size, fsd->size1); - - if (file->state == FILE_STATE_CLOSED) { - switch (fsd->mode) { - case DETECT_FILESIZE_EQ: - if (file->size == fsd->size1) - ret = 1; - break; - case DETECT_FILESIZE_LT: - if (file->size < fsd->size1) - ret = 1; - break; - case DETECT_FILESIZE_GT: - if (file->size > fsd->size1) - ret = 1; - break; - case DETECT_FILESIZE_RA: - if (file->size > fsd->size1 && file->size < fsd->size2) - ret = 1; - break; - } - /* truncated, error: only see if what we have meets the GT condition */ - } else if (file->state > FILE_STATE_CLOSED) { - if (fsd->mode == DETECT_FILESIZE_GT && file->size > fsd->size1) - ret = 1; - } - SCReturnInt(ret); -} - -/** - * \brief parse filesize options - * - * \param str pointer to the user provided filesize - * - * \retval fsd pointer to DetectFilesizeData on success - * \retval NULL on failure - */ -static DetectFilesizeData *DetectFilesizeParse (char *str) -{ - - DetectFilesizeData *fsd = NULL; - char *arg1 = NULL; - char *arg2 = NULL; - char *arg3 = NULL; - char *arg4 = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), - 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 3 || ret > 5) { - SCLogError(SC_ERR_PCRE_PARSE, "filesize option pcre parse error: \"%s\"", str); - goto error; - } - const char *str_ptr; - - SCLogDebug("ret %d", ret); - - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg1 = (char *) str_ptr; - SCLogDebug("Arg1 \"%s\"", arg1); - - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg2 = (char *) str_ptr; - SCLogDebug("Arg2 \"%s\"", arg2); - - if (ret > 3) { - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 3, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg3 = (char *) str_ptr; - SCLogDebug("Arg3 \"%s\"", arg3); - - if (ret > 4) { - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 4, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg4 = (char *) str_ptr; - SCLogDebug("Arg4 \"%s\"", arg4); - } - } - - fsd = SCMalloc(sizeof (DetectFilesizeData)); - if (unlikely(fsd == NULL)) - goto error; - memset(fsd, 0, sizeof(DetectFilesizeData)); - - if (arg1[0] == '<') - fsd->mode = DETECT_FILESIZE_LT; - else if (arg1[0] == '>') - fsd->mode = DETECT_FILESIZE_GT; - else - fsd->mode = DETECT_FILESIZE_EQ; - - if (arg3 != NULL && strcmp("<>", arg3) == 0) { - if (strlen(arg1) != 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Range specified but mode also set"); - goto error; - } - fsd->mode = DETECT_FILESIZE_RA; - } - - /** set the first value */ - if (ByteExtractStringUint64(&fsd->size1,10,strlen(arg2),arg2) <= 0){ - SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size :\"%s\"",arg2); - goto error; - } - - /** set the second value if specified */ - if (arg4 != NULL && strlen(arg4) > 0) { - if (fsd->mode != DETECT_FILESIZE_RA) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Multiple filesize values specified" - " but mode is not range"); - goto error; - } - - if(ByteExtractStringUint64(&fsd->size2,10,strlen(arg4),arg4) <= 0) - { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size :\"%s\"",arg4); - goto error; - } - - if (fsd->size2 <= fsd->size1){ - SCLogError(SC_ERR_INVALID_ARGUMENT,"filesize2:%"PRIu64" <= filesize:" - "%"PRIu64"",fsd->size2,fsd->size1); - goto error; - } - } - - pcre_free_substring(arg1); - pcre_free_substring(arg2); - if (arg3 != NULL) - pcre_free_substring(arg3); - if (arg4 != NULL) - pcre_free_substring(arg4); - return fsd; - -error: - if (fsd) - SCFree(fsd); - if (arg1 != NULL) - SCFree(arg1); - if (arg2 != NULL) - SCFree(arg2); - if (arg3 != NULL) - SCFree(arg3); - if (arg4 != NULL) - SCFree(arg4); - return NULL; -} - -/** - * \brief this function is used to parse filesize data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param str pointer to the user provided options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFilesizeSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - SCEnter(); - DetectFilesizeData *fsd = NULL; - SigMatch *sm = NULL; - - fsd = DetectFilesizeParse(str); - if (fsd == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FILESIZE; - sm->ctx = (SigMatchCtx *)fsd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEMATCH); - - if (s->alproto != ALPROTO_HTTP && s->alproto != ALPROTO_SMTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - if (s->alproto == ALPROTO_HTTP) { - AppLayerHtpNeedFileInspection(); - } - - s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_SIZE); - SCReturnInt(0); - -error: - if (fsd != NULL) - DetectFilesizeFree(fsd); - if (sm != NULL) - SCFree(sm); - SCReturnInt(-1); -} - -/** - * \brief this function will free memory associated with DetectFilesizeData - * - * \param ptr pointer to DetectFilesizeData - */ -static void DetectFilesizeFree(void *ptr) -{ - DetectFilesizeData *fsd = (DetectFilesizeData *)ptr; - SCFree(fsd); -} - -#ifdef UNITTESTS - -#include "stream.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "app-layer-parser.h" - -/** \test Test the Filesize keyword setup */ -static int DetectFilesizeParseTest01(void) -{ - int ret = 0; - DetectFilesizeData *fsd = NULL; - - fsd = DetectFilesizeParse("10"); - if (fsd != NULL) { - if (fsd->size1 == 10 && fsd->mode == DETECT_FILESIZE_EQ) - ret = 1; - - DetectFilesizeFree(fsd); - } - return ret; -} - -/** \test Test the Filesize keyword setup */ -static int DetectFilesizeParseTest02(void) -{ - int ret = 0; - DetectFilesizeData *fsd = NULL; - - fsd = DetectFilesizeParse(" < 10 "); - if (fsd != NULL) { - if (fsd->size1 == 10 && fsd->mode == DETECT_FILESIZE_LT) - ret = 1; - - DetectFilesizeFree(fsd); - } - return ret; -} - -/** \test Test the Filesize keyword setup */ -static int DetectFilesizeParseTest03(void) -{ - int ret = 0; - DetectFilesizeData *fsd = NULL; - - fsd = DetectFilesizeParse(" > 10 "); - if (fsd != NULL) { - if (fsd->size1 == 10 && fsd->mode == DETECT_FILESIZE_GT) - ret = 1; - - DetectFilesizeFree(fsd); - } - return ret; -} - -/** \test Test the Filesize keyword setup */ -static int DetectFilesizeParseTest04(void) -{ - int ret = 0; - DetectFilesizeData *fsd = NULL; - - fsd = DetectFilesizeParse(" 5 <> 10 "); - if (fsd != NULL) { - if (fsd->size1 == 5 && fsd->size2 == 10 && - fsd->mode == DETECT_FILESIZE_RA) - ret = 1; - - DetectFilesizeFree(fsd); - } - return ret; -} - -/** \test Test the Filesize keyword setup */ -static int DetectFilesizeParseTest05(void) -{ - int ret = 0; - DetectFilesizeData *fsd = NULL; - - fsd = DetectFilesizeParse("5<>10"); - if (fsd != NULL) { - if (fsd->size1 == 5 && fsd->size2 == 10 && - fsd->mode == DETECT_FILESIZE_RA) - ret = 1; - - DetectFilesizeFree(fsd); - } - return ret; -} - -/** - * \brief this function is used to initialize the detection engine context and - * setup the signature with passed values. - * - */ - -static int DetectFilesizeInitTest(DetectEngineCtx **de_ctx, Signature **sig, - DetectFilesizeData **fsd, char *str) -{ - char fullstr[1024]; - int result = 0; - - *de_ctx = NULL; - *sig = NULL; - - if (snprintf(fullstr, 1024, "alert http any any -> any any (msg:\"Filesize " - "test\"; filesize:%s; sid:1;)", str) >= 1024) { - goto end; - } - - *de_ctx = DetectEngineCtxInit(); - if (*de_ctx == NULL) { - goto end; - } - - (*de_ctx)->flags |= DE_QUIET; - - (*de_ctx)->sig_list = SigInit(*de_ctx, fullstr); - if ((*de_ctx)->sig_list == NULL) { - goto end; - } - - *sig = (*de_ctx)->sig_list; - - *fsd = DetectFilesizeParse(str); - - result = 1; - -end: - return result; -} - -/** - * \test DetectFilesizeSetpTest01 is a test for setting up an valid filesize values - * with valid "<>" operator and include spaces arround the given values. - * In the test the values are setup with initializing the detection engine - * context and setting up the signature itself. - */ - -static int DetectFilesizeSetpTest01(void) -{ - - DetectFilesizeData *fsd = NULL; - uint8_t res = 0; - Signature *sig = NULL; - DetectEngineCtx *de_ctx = NULL; - - res = DetectFilesizeInitTest(&de_ctx, &sig, &fsd, "1 <> 2 "); - if (res == 0) { - goto end; - } - - if(fsd == NULL) - goto cleanup; - - if (fsd != NULL) { - if (fsd->size1 == 1 && fsd->size2 == 2 && - fsd->mode == DETECT_FILESIZE_RA) - res = 1; - } - -cleanup: - if (fsd) - SCFree(fsd); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); -end: - return res; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectFilesize - */ -void DetectFilesizeRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectFilesizeParseTest01", DetectFilesizeParseTest01, 1); - UtRegisterTest("DetectFilesizeParseTest02", DetectFilesizeParseTest02, 1); - UtRegisterTest("DetectFilesizeParseTest03", DetectFilesizeParseTest03, 1); - UtRegisterTest("DetectFilesizeParseTest04", DetectFilesizeParseTest04, 1); - UtRegisterTest("DetectFilesizeParseTest05", DetectFilesizeParseTest05, 1); - UtRegisterTest("DetectFilesizeSetpTest01", DetectFilesizeSetpTest01, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-filesize.h b/framework/src/suricata/src/detect-filesize.h deleted file mode 100644 index cecb29f0..00000000 --- a/framework/src/suricata/src/detect-filesize.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_FILESIZE_H__ -#define __DETECT_FILESIZE_H__ - -#define DETECT_FILESIZE_LT 0 /**< "less than" operator */ -#define DETECT_FILESIZE_GT 1 /**< "greater than" operator */ -#define DETECT_FILESIZE_RA 2 /**< range operator */ -#define DETECT_FILESIZE_EQ 3 /**< equal operator */ - -typedef struct DetectFilesizeData_ { - uint64_t size1; /**< 1st value in the signature*/ - uint64_t size2; /**< 2nd value in the signature*/ - uint8_t mode; /**< operator used in the signature */ -} DetectFilesizeData; - -//int DetectFilesizeMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, -// uint8_t, void *, Signature *, SigMatch *); -void DetectFilesizeRegister(void); - -#endif /* _DETECT_URILEN_H */ diff --git a/framework/src/suricata/src/detect-filestore.c b/framework/src/suricata/src/detect-filestore.c deleted file mode 100644 index 00e8aacc..00000000 --- a/framework/src/suricata/src/detect-filestore.c +++ /dev/null @@ -1,443 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the filestore keyword - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-spm-bm.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "stream-tcp.h" - -#include "detect-filestore.h" - -/** - * \brief Regex for parsing our flow options - */ -#define PARSE_REGEX "^\\s*([A-z_]+)\\s*(?:,\\s*([A-z_]+))?\\s*(?:,\\s*([A-z_]+))?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -static int DetectFilestoreMatch (ThreadVars *, DetectEngineThreadCtx *, - Flow *, uint8_t, File *, Signature *, SigMatch *); -static int DetectFilestoreSetup (DetectEngineCtx *, Signature *, char *); -static void DetectFilestoreFree(void *); - -/** - * \brief Registration function for keyword: filestore - */ -void DetectFilestoreRegister(void) -{ - sigmatch_table[DETECT_FILESTORE].name = "filestore"; - sigmatch_table[DETECT_FILESTORE].desc = "stores files to disk if the rule matched"; - sigmatch_table[DETECT_FILESTORE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/File-keywords#filestore"; - sigmatch_table[DETECT_FILESTORE].FileMatch = DetectFilestoreMatch; - sigmatch_table[DETECT_FILESTORE].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_FILESTORE].Setup = DetectFilestoreSetup; - sigmatch_table[DETECT_FILESTORE].Free = DetectFilestoreFree; - sigmatch_table[DETECT_FILESTORE].RegisterTests = NULL; - sigmatch_table[DETECT_FILESTORE].flags = SIGMATCH_OPTIONAL_OPT; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - SCLogDebug("registering filestore rule option"); - return; -error: - /* XXX */ - return; -} - -/** - * \brief apply the post match filestore with options - */ -static int FilestorePostMatchWithOptions(Packet *p, Flow *f, DetectFilestoreData *filestore, FileContainer *fc, - uint16_t file_id, uint16_t tx_id) -{ - if (filestore == NULL) { - SCReturnInt(0); - } - - int this_file = 0; - int this_tx = 0; - int this_flow = 0; - int rule_dir = 0; - int toserver_dir = 0; - int toclient_dir = 0; - - switch (filestore->direction) { - case FILESTORE_DIR_DEFAULT: - rule_dir = 1; - break; - case FILESTORE_DIR_BOTH: - toserver_dir = 1; - toclient_dir = 1; - break; - case FILESTORE_DIR_TOSERVER: - toserver_dir = 1; - break; - case FILESTORE_DIR_TOCLIENT: - toclient_dir = 1; - break; - } - - switch (filestore->scope) { - case FILESTORE_SCOPE_DEFAULT: - if (rule_dir) { - this_file = 1; - } else if ((p->flowflags & FLOW_PKT_TOCLIENT) && toclient_dir) { - this_file = 1; - } else if ((p->flowflags & FLOW_PKT_TOSERVER) && toserver_dir) { - this_file = 1; - } - break; - case FILESTORE_SCOPE_TX: - this_tx = 1; - break; - case FILESTORE_SCOPE_SSN: - this_flow = 1; - break; - } - - if (this_file) { - FileStoreFileById(fc, file_id); - } else if (this_tx) { - /* flag tx all files will be stored */ - if (f->alproto == ALPROTO_HTTP && f->alstate != NULL) { - HtpState *htp_state = f->alstate; - if (toserver_dir) { - htp_state->flags |= HTP_FLAG_STORE_FILES_TX_TS; - FileStoreAllFilesForTx(htp_state->files_ts, tx_id); - } - if (toclient_dir) { - htp_state->flags |= HTP_FLAG_STORE_FILES_TX_TC; - FileStoreAllFilesForTx(htp_state->files_tc, tx_id); - } - htp_state->store_tx_id = tx_id; - } - } else if (this_flow) { - /* flag flow all files will be stored */ - if (f->alproto == ALPROTO_HTTP && f->alstate != NULL) { - HtpState *htp_state = f->alstate; - if (toserver_dir) { - htp_state->flags |= HTP_FLAG_STORE_FILES_TS; - FileStoreAllFiles(htp_state->files_ts); - } - if (toclient_dir) { - htp_state->flags |= HTP_FLAG_STORE_FILES_TC; - FileStoreAllFiles(htp_state->files_tc); - } - } - } else { - FileStoreFileById(fc, file_id); - } - - SCReturnInt(0); -} - -/** - * \brief post-match function for filestore - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param p packet - * - * The match function for filestore records store candidates in the det_ctx. - * When we are sure all parts of the signature matched, we run this function - * to finalize the filestore. - */ -int DetectFilestorePostMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s) -{ - uint8_t flags = 0; - - SCEnter(); - - if (det_ctx->filestore_cnt == 0) { - SCReturnInt(0); - } - - if (s->filestore_sm == NULL || p->flow == NULL) { -#ifndef DEBUG - SCReturnInt(0); -#else - BUG_ON(1); -#endif - } - - if (p->flowflags & FLOW_PKT_TOCLIENT) - flags |= STREAM_TOCLIENT; - else - flags |= STREAM_TOSERVER; - - if (det_ctx->flow_locked == 0) - FLOWLOCK_WRLOCK(p->flow); - - FileContainer *ffc = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto, - p->flow->alstate, flags); - - /* filestore for single files only */ - if (s->filestore_sm->ctx == NULL) { - uint16_t u; - for (u = 0; u < det_ctx->filestore_cnt; u++) { - FileStoreFileById(ffc, det_ctx->filestore[u].file_id); - } - } else { - DetectFilestoreData *filestore = (DetectFilestoreData *)s->filestore_sm->ctx; - uint16_t u; - - for (u = 0; u < det_ctx->filestore_cnt; u++) { - FilestorePostMatchWithOptions(p, p->flow, filestore, ffc, - det_ctx->filestore[u].file_id, det_ctx->filestore[u].tx_id); - } - } - - if (det_ctx->flow_locked == 0) - FLOWLOCK_UNLOCK(p->flow); - - SCReturnInt(0); -} - -/** - * \brief match the specified filestore - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param f *LOCKED* flow - * \param flags direction flags - * \param file file being inspected - * \param s signature being inspected - * \param m sigmatch that we will cast into DetectFilestoreData - * - * \retval 0 no match - * \retval 1 match - * - * \todo when we start supporting more protocols, the logic in this function - * needs to be put behind a api. - */ -static int DetectFilestoreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, - uint8_t flags, File *file, Signature *s, SigMatch *m) -{ - uint16_t file_id = 0; - - SCEnter(); - - if (det_ctx->filestore_cnt >= DETECT_FILESTORE_MAX) { - SCReturnInt(1); - } - - /* file can be NULL when a rule with filestore scope > file - * matches. */ - if (file != NULL) { - file_id = file->file_id; - } - - det_ctx->filestore[det_ctx->filestore_cnt].file_id = file_id; - det_ctx->filestore[det_ctx->filestore_cnt].tx_id = det_ctx->tx_id; - - SCLogDebug("%u, file %u, tx %"PRIu64, det_ctx->filestore_cnt, - det_ctx->filestore[det_ctx->filestore_cnt].file_id, - det_ctx->filestore[det_ctx->filestore_cnt].tx_id); - - det_ctx->filestore_cnt++; - SCReturnInt(1); -} - -/** - * \brief this function is used to parse filestore options - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param str pointer to the user provided "filestore" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFilestoreSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - SCEnter(); - - DetectFilestoreData *fd = NULL; - SigMatch *sm = NULL; - char *args[3] = {NULL,NULL,NULL}; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FILESTORE; - - if (str != NULL && strlen(str) > 0) { - SCLogDebug("str %s", str); - - ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 ", string %s", ret, str); - goto error; - } - - if (ret > 1) { - const char *str_ptr; - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[0] = (char *)str_ptr; - - if (ret > 2) { - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[1] = (char *)str_ptr; - } - if (ret > 3) { - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 3, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[2] = (char *)str_ptr; - } - } - - fd = SCMalloc(sizeof(DetectFilestoreData)); - if (unlikely(fd == NULL)) - goto error; - memset(fd, 0x00, sizeof(DetectFilestoreData)); - - if (args[0] != NULL) { - SCLogDebug("first arg %s", args[0]); - - if (strcasecmp(args[0], "request") == 0 || - strcasecmp(args[0], "to_server") == 0) - { - fd->direction = FILESTORE_DIR_TOSERVER; - fd->scope = FILESTORE_SCOPE_TX; - } - else if (strcasecmp(args[0], "response") == 0 || - strcasecmp(args[0], "to_client") == 0) - { - fd->direction = FILESTORE_DIR_TOCLIENT; - fd->scope = FILESTORE_SCOPE_TX; - } - else if (strcasecmp(args[0], "both") == 0) - { - fd->direction = FILESTORE_DIR_BOTH; - fd->scope = FILESTORE_SCOPE_TX; - } - } else { - fd->direction = FILESTORE_DIR_DEFAULT; - } - - if (args[1] != NULL) { - SCLogDebug("second arg %s", args[1]); - - if (strcasecmp(args[1], "file") == 0) - { - fd->scope = FILESTORE_SCOPE_DEFAULT; - } else if (strcasecmp(args[1], "tx") == 0) - { - fd->scope = FILESTORE_SCOPE_TX; - } else if (strcasecmp(args[1], "ssn") == 0 || - strcasecmp(args[1], "flow") == 0) - { - fd->scope = FILESTORE_SCOPE_SSN; - } - } else { - if (fd->scope == 0) - fd->scope = FILESTORE_SCOPE_DEFAULT; - } - - sm->ctx = (SigMatchCtx*)fd; - } else { - sm->ctx = (SigMatchCtx*)NULL; - } - - if (s->alproto != ALPROTO_HTTP && s->alproto != ALPROTO_SMTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - if (s->alproto == ALPROTO_HTTP) { - AppLayerHtpNeedFileInspection(); - } - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEMATCH); - s->filestore_sm = sm; - - s->flags |= SIG_FLAG_FILESTORE; - return 0; - -error: - if (sm != NULL) - SCFree(sm); - return -1; -} - -static void DetectFilestoreFree(void *ptr) -{ - if (ptr != NULL) { - SCFree(ptr); - } -} diff --git a/framework/src/suricata/src/detect-filestore.h b/framework/src/suricata/src/detect-filestore.h deleted file mode 100644 index 1879b875..00000000 --- a/framework/src/suricata/src/detect-filestore.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_FILESTORE_H__ -#define __DETECT_FILESTORE_H__ - -#define FILESTORE_DIR_DEFAULT 0 /* rule dir */ -#define FILESTORE_DIR_TOSERVER 1 -#define FILESTORE_DIR_TOCLIENT 2 -#define FILESTORE_DIR_BOTH 3 - -#define FILESTORE_SCOPE_DEFAULT 0 /* per file */ -#define FILESTORE_SCOPE_TX 1 /* per transaction */ -#define FILESTORE_SCOPE_SSN 2 /* per flow/ssn */ - -typedef struct DetectFilestoreData_ { - int16_t direction; - int16_t scope; -} DetectFilestoreData; - -/* prototypes */ -void DetectFilestoreRegister (void); - -int DetectFilestorePostMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *); -#endif /* __DETECT_FILESTORE_H__ */ diff --git a/framework/src/suricata/src/detect-flags.c b/framework/src/suricata/src/detect-flags.c deleted file mode 100644 index b5b1840a..00000000 --- a/framework/src/suricata/src/detect-flags.c +++ /dev/null @@ -1,1341 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * - * Implements the flags keyword - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "flow-var.h" -#include "decode-events.h" - -#include "detect-flags.h" -#include "util-unittest.h" - -#include "util-debug.h" - -/** - * Regex (by Brian Rectanus) - * flags: [!+*](SAPRFU120)[,SAPRFU12] - */ -#define PARSE_REGEX "^\\s*(?:([\\+\\*!]))?\\s*([SAPRFU120CE\\+\\*!]+)(?:\\s*,\\s*([SAPRFU12CE]+))?\\s*$" - -/** - * Flags args[0] *(3) +(2) !(1) - * - */ - -#define MODIFIER_NOT 1 -#define MODIFIER_PLUS 2 -#define MODIFIER_ANY 3 - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -static int DetectFlagsMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectFlagsSetup (DetectEngineCtx *, Signature *, char *); -static void DetectFlagsFree(void *); - -/** - * \brief Registration function for flags: keyword - */ - -void DetectFlagsRegister (void) -{ - sigmatch_table[DETECT_FLAGS].name = "flags"; - sigmatch_table[DETECT_FLAGS].Match = DetectFlagsMatch; - sigmatch_table[DETECT_FLAGS].Setup = DetectFlagsSetup; - sigmatch_table[DETECT_FLAGS].Free = DetectFlagsFree; - sigmatch_table[DETECT_FLAGS].RegisterTests = FlagsRegisterTests; - - const char *eb; - int opts = 0; - int eo; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - -error: - return; - -} - -/** - * \internal - * \brief This function is used to match flags on a packet with those passed via flags: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param s pointer to the Signature - * \param m pointer to the sigmatch - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectFlagsMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - SCEnter(); - - uint8_t flags = 0; - const DetectFlagsData *de = (const DetectFlagsData *)ctx; - - if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) { - SCReturnInt(0); - } - - flags = p->tcph->th_flags; - - if (!de->flags && flags) { - if(de->modifier == MODIFIER_NOT) { - SCReturnInt(1); - } - - SCReturnInt(0); - } - - flags &= de->ignored_flags; - - switch (de->modifier) { - case MODIFIER_ANY: - if ((flags & de->flags) > 0) { - SCReturnInt(1); - } - SCReturnInt(0); - - case MODIFIER_PLUS: - if (((flags & de->flags) == de->flags)) { - SCReturnInt(1); - } - SCReturnInt(0); - - case MODIFIER_NOT: - if ((flags & de->flags) != de->flags) { - SCReturnInt(1); - } - SCReturnInt(0); - - default: - SCLogDebug("flags %"PRIu8" and de->flags %"PRIu8"",flags,de->flags); - if (flags == de->flags) { - SCReturnInt(1); - } - } - - SCReturnInt(0); -} - -/** - * \internal - * \brief This function is used to parse flags options passed via flags: keyword - * - * \param rawstr Pointer to the user provided flags options - * - * \retval de pointer to DetectFlagsData on success - * \retval NULL on failure - */ -static DetectFlagsData *DetectFlagsParse (char *rawstr) -{ - SCEnter(); - - DetectFlagsData *de = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, found = 0, ignore = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *str_ptr = NULL; - char *args[3] = { NULL, NULL, NULL }; - char *ptr; - int i; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), - 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre match failed"); - goto error; - } - - for (i = 0; i < (ret - 1); i++) { - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS,i + 1, - &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - args[i] = (char *)str_ptr; - } - - if(args[1] == NULL) { - SCLogDebug("args[1] == NULL"); - goto error; - } - - de = SCMalloc(sizeof(DetectFlagsData)); - if (unlikely(de == NULL)) - goto error; - - memset(de,0,sizeof(DetectFlagsData)); - - de->ignored_flags = 0xff; - - /** First parse args[0] */ - - if(args[0]) { - - ptr = args[0]; - - while (*ptr != '\0') { - switch (*ptr) { - case 'S': - case 's': - de->flags |= TH_SYN; - found++; - break; - case 'A': - case 'a': - de->flags |= TH_ACK; - found++; - break; - case 'F': - case 'f': - de->flags |= TH_FIN; - found++; - break; - case 'R': - case 'r': - de->flags |= TH_RST; - found++; - break; - case 'P': - case 'p': - de->flags |= TH_PUSH; - found++; - break; - case 'U': - case 'u': - de->flags |= TH_URG; - found++; - break; - case '1': - de->flags |= TH_CWR; - found++; - break; - case '2': - de->flags |= TH_ECN; - found++; - break; - case 'C': - case 'c': - de->flags |= TH_CWR; - found++; - break; - case 'E': - case 'e': - de->flags |= TH_ECN; - found++; - break; - case '0': - de->flags = 0; - found++; - break; - - case '!': - de->modifier = MODIFIER_NOT; - break; - case '+': - de->modifier = MODIFIER_PLUS; - break; - case '*': - de->modifier = MODIFIER_ANY; - break; - } - ptr++; - } - - } - - /** Second parse first set of flags */ - - ptr = args[1]; - - while (*ptr != '\0') { - switch (*ptr) { - case 'S': - case 's': - de->flags |= TH_SYN; - found++; - break; - case 'A': - case 'a': - de->flags |= TH_ACK; - found++; - break; - case 'F': - case 'f': - de->flags |= TH_FIN; - found++; - break; - case 'R': - case 'r': - de->flags |= TH_RST; - found++; - break; - case 'P': - case 'p': - de->flags |= TH_PUSH; - found++; - break; - case 'U': - case 'u': - de->flags |= TH_URG; - found++; - break; - case '1': - de->flags |= TH_CWR; - found++; - break; - case '2': - de->flags |= TH_ECN; - found++; - break; - case 'C': - case 'c': - de->flags |= TH_CWR; - found++; - break; - case 'E': - case 'e': - de->flags |= TH_ECN; - found++; - break; - case '0': - de->flags = 0; - found++; - break; - - case '!': - if (de->modifier != 0) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "\"flags\" supports only" - " one modifier at a time"); - goto error; - } - de->modifier = MODIFIER_NOT; - SCLogDebug("NOT modifier is set"); - break; - case '+': - if (de->modifier != 0) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "\"flags\" supports only" - " one modifier at a time"); - goto error; - } - de->modifier = MODIFIER_PLUS; - SCLogDebug("PLUS modifier is set"); - break; - case '*': - if (de->modifier != 0) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "\"flags\" supports only" - " one modifier at a time"); - goto error; - } - de->modifier = MODIFIER_ANY; - SCLogDebug("ANY modifier is set"); - break; - default: - break; - } - ptr++; - } - - if(found == 0) - goto error; - - /** Finally parse ignored flags */ - - if(args[2]) { - - ptr = args[2]; - - while (*ptr != '\0') { - switch (*ptr) { - case 'S': - case 's': - de->ignored_flags &= ~TH_SYN; - ignore++; - break; - case 'A': - case 'a': - de->ignored_flags &= ~TH_ACK; - ignore++; - break; - case 'F': - case 'f': - de->ignored_flags &= ~TH_FIN; - ignore++; - break; - case 'R': - case 'r': - de->ignored_flags &= ~TH_RST; - ignore++; - break; - case 'P': - case 'p': - de->ignored_flags &= ~TH_PUSH; - ignore++; - break; - case 'U': - case 'u': - de->ignored_flags &= ~TH_URG; - ignore++; - break; - case '1': - de->ignored_flags &= ~TH_CWR; - ignore++; - break; - case '2': - de->ignored_flags &= ~TH_ECN; - ignore++; - break; - case 'C': - case 'c': - de->ignored_flags &= ~TH_CWR; - ignore++; - break; - case 'E': - case 'e': - de->ignored_flags &= ~TH_ECN; - ignore++; - break; - case '0': - break; - default: - break; - } - ptr++; - } - - if(ignore == 0) { - SCLogDebug("ignore == 0"); - goto error; - } - } - - for (i = 0; i < (ret - 1); i++){ - SCLogDebug("args[%"PRId32"] = %s",i, args[i]); - if (args[i] != NULL) SCFree(args[i]); - } - - SCLogDebug("found %"PRId32" ignore %"PRId32"", found, ignore); - SCReturnPtr(de, "DetectFlagsData"); - -error: - for (i = 0; i < (ret - 1); i++){ - if (args[i] != NULL) SCFree(args[i]); - } - if (de) SCFree(de); - SCReturnPtr(NULL, "DetectFlagsData"); -} - -/** - * \internal - * \brief this function is used to add the parsed flags into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param m pointer to the Current SigMatch - * \param rawstr pointer to the user provided flags options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFlagsSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - - de = DetectFlagsParse(rawstr); - if (de == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - return -1; -} - -/** - * \internal - * \brief this function will free memory associated with DetectFlagsData - * - * \param de pointer to DetectFlagsData - */ -static void DetectFlagsFree(void *de_ptr) -{ - DetectFlagsData *de = (DetectFlagsData *)de_ptr; - if(de) SCFree(de); -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -/** - * \test FlagsTestParse01 is a test for a valid flags value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int FlagsTestParse01 (void) -{ - DetectFlagsData *de = NULL; - de = DetectFlagsParse("S"); - if (de && (de->flags == TH_SYN) ) { - DetectFlagsFree(de); - return 1; - } - - return 0; -} - -/** - * \test FlagsTestParse02 is a test for an invalid flags value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int FlagsTestParse02 (void) -{ - DetectFlagsData *de = NULL; - de = DetectFlagsParse("G"); - if (de) { - DetectFlagsFree(de); - return 1; - } - - return 0; -} - -/** - * \test FlagsTestParse03 test if ACK and PUSH are set. Must return success - * - * \retval 1 on success - * \retval 0 on failure - */ -static int FlagsTestParse03 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST; - - de = DetectFlagsParse("AP+"); - - if (de == NULL || (de->flags != (TH_ACK|TH_PUSH)) ) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FlagsTestParse04 check if ACK bit is set. Must fails. - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int FlagsTestParse04 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN; - - de = DetectFlagsParse("A"); - - if (de == NULL || de->flags != TH_ACK) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FlagsTestParse05 test if ACK+PUSH and more flags are set. Ignore SYN and RST bits. - * Must fails. - * \retval 1 on success - * \retval 0 on failure - */ -static int FlagsTestParse05 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST; - - de = DetectFlagsParse("+AP,SR"); - - if (de == NULL || (de->modifier != MODIFIER_PLUS) || (de->flags != (TH_ACK|TH_PUSH)) || (de->ignored_flags != (TH_SYN|TH_RST))) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FlagsTestParse06 test if ACK+PUSH and more flags are set. Ignore URG and RST bits. - * Must return success. - * \retval 1 on success - * \retval 0 on failure - */ -static int FlagsTestParse06 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST; - - de = DetectFlagsParse("+AP,UR"); - - if (de == NULL || (de->modifier != MODIFIER_PLUS) || (de->flags != (TH_ACK|TH_PUSH)) || ((0xff - de->ignored_flags) != (TH_URG|TH_RST))) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FlagsTestParse07 test if SYN or RST are set. Must fails. - * - * \retval 1 on success - * \retval 0 on failure - */ -static int FlagsTestParse07 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST; - - de = DetectFlagsParse("*AP"); - - if (de == NULL || (de->modifier != MODIFIER_ANY) || (de->flags != (TH_ACK|TH_PUSH))) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FlagsTestParse08 test if SYN or RST are set. Must return success. - * - * \retval 1 on success - * \retval 0 on failure - */ -static int FlagsTestParse08 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST; - - de = DetectFlagsParse("*SA"); - - if (de == NULL || (de->modifier != MODIFIER_ANY) || (de->flags != (TH_ACK|TH_SYN))) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FlagsTestParse09 test if SYN and RST are not set. Must fails. - * - * \retval 1 on success - * \retval 0 on failure - */ -static int FlagsTestParse09 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST; - - de = DetectFlagsParse("!PA"); - - if (de == NULL || (de->modifier != MODIFIER_NOT) || (de->flags != (TH_ACK|TH_PUSH))) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FlagsTestParse10 test if ACK and PUSH are not set. Must return success. - * - * \retval 1 on success - * \retval 0 on failure - */ -static int FlagsTestParse10 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST; - - de = DetectFlagsParse("!AP"); - - if (de == NULL || (de->modifier != MODIFIER_NOT) || (de->flags != (TH_ACK|TH_PUSH))) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FlagsTestParse11 test if ACK or PUSH are set. Ignore SYN and RST. Must fails. - * - * \retval 1 on success - * \retval 0 on failure - */ -static int FlagsTestParse11 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN|TH_RST|TH_URG; - - de = DetectFlagsParse("*AP,SR"); - - if (de == NULL || (de->modifier != MODIFIER_ANY) || (de->flags != (TH_ACK|TH_PUSH)) || ((0xff - de->ignored_flags) != (TH_SYN|TH_RST))) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FlagsTestParse12 check if no flags are set. Must fails. - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int FlagsTestParse12 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_SYN; - - de = DetectFlagsParse("0"); - - if (de == NULL || de->flags != 0) { - printf("de setup: "); - goto error; - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test test for a valid flags value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int FlagsTestParse13 (void) -{ - DetectFlagsData *de = NULL; - de = DetectFlagsParse("+S*"); - if (de != NULL) { - DetectFlagsFree(de); - return 0; - } - - return 1; -} - -/** - * \test Parse 'C' and 'E' flags. - * - * \retval 1 on success. - * \retval 0 on failure. - */ -static int FlagsTestParse14(void) -{ - DetectFlagsData *de = DetectFlagsParse("CE"); - if (de != NULL && (de->flags == (TH_CWR | TH_ECN)) ) { - DetectFlagsFree(de); - return 1; - } - - return 0; -} - -static int FlagsTestParse15(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_ECN | TH_CWR | TH_SYN | TH_RST; - - de = DetectFlagsParse("EC+"); - - if (de == NULL || (de->flags != (TH_ECN | TH_CWR)) ) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if (ret) { - if (de) - SCFree(de); - if (sm) - SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) - SCFree(de); - if (sm) - SCFree(sm); - SCFree(p); - return 0; -} - -static int FlagsTestParse16(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_ECN | TH_SYN | TH_RST; - - de = DetectFlagsParse("EC*"); - - if (de == NULL || (de->flags != (TH_ECN | TH_CWR)) ) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if (ret) { - if (de) - SCFree(de); - if (sm) - SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) - SCFree(de); - if (sm) - SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test Negative test. - */ -static int FlagsTestParse17(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectFlagsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ipv4h; - TCPHdr tcph; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - memset(&tcph, 0, sizeof(TCPHdr)); - - p->ip4h = &ipv4h; - p->tcph = &tcph; - p->tcph->th_flags = TH_ECN | TH_SYN | TH_RST; - - de = DetectFlagsParse("EC+"); - - if (de == NULL || (de->flags != (TH_ECN | TH_CWR)) ) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLAGS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFlagsMatch(&tv, NULL, p, NULL, sm->ctx); - - if (ret == 0) { - if (de) - SCFree(de); - if (sm) - SCFree(sm); - SCFree(p); - return 1; - } - -error: - if (de) - SCFree(de); - if (sm) - SCFree(sm); - SCFree(p); - return 0; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for Flags - */ -void FlagsRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("FlagsTestParse01", FlagsTestParse01, 1); - UtRegisterTest("FlagsTestParse02", FlagsTestParse02, 0); - UtRegisterTest("FlagsTestParse03", FlagsTestParse03, 1); - UtRegisterTest("FlagsTestParse04", FlagsTestParse04, 0); - UtRegisterTest("FlagsTestParse05", FlagsTestParse05, 0); - UtRegisterTest("FlagsTestParse06", FlagsTestParse06, 1); - UtRegisterTest("FlagsTestParse07", FlagsTestParse07, 0); - UtRegisterTest("FlagsTestParse08", FlagsTestParse08, 1); - UtRegisterTest("FlagsTestParse09", FlagsTestParse09, 1); - UtRegisterTest("FlagsTestParse10", FlagsTestParse10, 1); - UtRegisterTest("FlagsTestParse11", FlagsTestParse11, 0); - UtRegisterTest("FlagsTestParse12", FlagsTestParse12, 0); - UtRegisterTest("FlagsTestParse13", FlagsTestParse13, 1); - UtRegisterTest("FlagsTestParse14", FlagsTestParse14, 1); - UtRegisterTest("FlagsTestParse15", FlagsTestParse15, 1); - UtRegisterTest("FlagsTestParse16", FlagsTestParse16, 1); - UtRegisterTest("FlagsTestParse17", FlagsTestParse17, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-flags.h b/framework/src/suricata/src/detect-flags.h deleted file mode 100644 index 0eaaa282..00000000 --- a/framework/src/suricata/src/detect-flags.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - */ - -#ifndef __DETECT_FLAGS_H__ -#define __DETECT_FLAGS_H__ - -#include "decode-events.h" -#include "decode-ipv4.h" -#include "decode-tcp.h" - -/** - * \struct DetectFlagsData_ - * DetectFlagsData_ is used to store flags: input value - */ - -/** - * \typedef DetectFlagsData - * A typedef for DetectFlagsData_ - */ - -typedef struct DetectFlagsData_ { - uint8_t flags; /**< TCP flags */ - uint8_t modifier; /**< !(1) +(2) *(3) modifiers */ - uint8_t ignored_flags; /**< Ignored TCP flags defined by modifer , */ -} DetectFlagsData; - -/** - * Registration function for flags: keyword - */ - -void DetectFlagsRegister (void); - -/** - * This function registers unit tests for Flags - */ - -void FlagsRegisterTests(void); - -#endif /*__DETECT_FLAGS_H__ */ diff --git a/framework/src/suricata/src/detect-flow.c b/framework/src/suricata/src/detect-flow.c deleted file mode 100644 index 9c2db944..00000000 --- a/framework/src/suricata/src/detect-flow.c +++ /dev/null @@ -1,1127 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * FLOW part of the detection engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" - -#include "flow.h" -#include "flow-var.h" - -#include "detect-flow.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -/** - * \brief Regex for parsing our flow options - */ -#define PARSE_REGEX "^\\s*([A-z_]+)\\s*(?:,\\s*([A-z_]+))?\\s*(?:,\\s*([A-z_]+))?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectFlowMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectFlowSetup (DetectEngineCtx *, Signature *, char *); -void DetectFlowRegisterTests(void); -void DetectFlowFree(void *); - -/** - * \brief Registration function for flow: keyword - */ -void DetectFlowRegister (void) -{ - sigmatch_table[DETECT_FLOW].name = "flow"; - sigmatch_table[DETECT_FLOW].desc = "match on direction and state of the flow"; - sigmatch_table[DETECT_FLOW].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Flow-keywords#Flow"; - sigmatch_table[DETECT_FLOW].Match = DetectFlowMatch; - sigmatch_table[DETECT_FLOW].Setup = DetectFlowSetup; - sigmatch_table[DETECT_FLOW].Free = DetectFlowFree; - sigmatch_table[DETECT_FLOW].RegisterTests = DetectFlowRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - /* XXX */ - return; -} - -/* - * returns 0: no match - * 1: match - * -1: error - */ - -/** - * \brief This function is used to match flow flags set on a packet with those passed via flow: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectFlowData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectFlowMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - SCEnter(); - - SCLogDebug("pkt %p", p); - - if (p->flowflags & FLOW_PKT_TOSERVER) { - SCLogDebug("FLOW_PKT_TOSERVER"); - } else if (p->flowflags & FLOW_PKT_TOCLIENT) { - SCLogDebug("FLOW_PKT_TOCLIENT"); - } - - if (p->flowflags & FLOW_PKT_ESTABLISHED) { - SCLogDebug("FLOW_PKT_ESTABLISHED"); - } - - uint8_t cnt = 0; - const DetectFlowData *fd = (const DetectFlowData *)ctx; - - if ((fd->flags & DETECT_FLOW_FLAG_TOSERVER) && (p->flowflags & FLOW_PKT_TOSERVER)) { - cnt++; - } else if ((fd->flags & DETECT_FLOW_FLAG_TOCLIENT) && (p->flowflags & FLOW_PKT_TOCLIENT)) { - cnt++; - } - - if ((fd->flags & DETECT_FLOW_FLAG_ESTABLISHED) && (p->flowflags & FLOW_PKT_ESTABLISHED)) { - cnt++; - } else if (fd->flags & DETECT_FLOW_FLAG_STATELESS) { - cnt++; - } - - if (det_ctx->flags & DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH) { - if (fd->flags & DETECT_FLOW_FLAG_ONLYSTREAM) - cnt++; - } else { - if (fd->flags & DETECT_FLOW_FLAG_NOSTREAM) - cnt++; - } - - int ret = (fd->match_cnt == cnt) ? 1 : 0; - SCLogDebug("returning %" PRId32 " cnt %" PRIu8 " fd->match_cnt %" PRId32 " fd->flags 0x%02X p->flowflags 0x%02X", - ret, cnt, fd->match_cnt, fd->flags, p->flowflags); - SCReturnInt(ret); -} - -/** - * \brief This function is used to parse flow options passed via flow: keyword - * - * \param flowstr Pointer to the user provided flow options - * - * \retval fd pointer to DetectFlowData on success - * \retval NULL on failure - */ -DetectFlowData *DetectFlowParse (char *flowstr) -{ - DetectFlowData *fd = NULL; - char *args[3] = {NULL,NULL,NULL}; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - char str1[16] = "", str2[16] = "", str3[16] = ""; - - ret = pcre_exec(parse_regex, parse_regex_study, flowstr, strlen(flowstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 ", string %s", ret, flowstr); - goto error; - } - - if (ret > 1) { - res = pcre_copy_substring((char *)flowstr, ov, MAX_SUBSTRINGS, 1, str1, sizeof(str1)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - args[0] = (char *)str1; - - if (ret > 2) { - res = pcre_copy_substring((char *)flowstr, ov, MAX_SUBSTRINGS, 2, str2, sizeof(str2)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - args[1] = (char *)str2; - } - if (ret > 3) { - res = pcre_copy_substring((char *)flowstr, ov, MAX_SUBSTRINGS, 3, str3, sizeof(str3)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - args[2] = (char *)str3; - } - } - - fd = SCMalloc(sizeof(DetectFlowData)); - if (unlikely(fd == NULL)) - goto error; - fd->flags = 0; - fd->match_cnt = 0; - - int i; - for (i = 0; i < (ret - 1); i++) { - if (args[i]) { - /* inspect our options and set the flags */ - if (strcasecmp(args[i], "established") == 0) { - if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "DETECT_FLOW_FLAG_ESTABLISHED flag is already set"); - goto error; - } else if (fd->flags & DETECT_FLOW_FLAG_STATELESS) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "DETECT_FLOW_FLAG_STATELESS already set"); - goto error; - } - fd->flags |= DETECT_FLOW_FLAG_ESTABLISHED; - } else if (strcasecmp(args[i], "stateless") == 0) { - if (fd->flags & DETECT_FLOW_FLAG_STATELESS) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "DETECT_FLOW_FLAG_STATELESS flag is already set"); - goto error; - } else if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set DETECT_FLOW_FLAG_STATELESS, DETECT_FLOW_FLAG_ESTABLISHED already set"); - goto error; - } - fd->flags |= DETECT_FLOW_FLAG_STATELESS; - } else if (strcasecmp(args[i], "to_client") == 0 || strcasecmp(args[i], "from_server") == 0) { - if (fd->flags & DETECT_FLOW_FLAG_TOCLIENT) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set DETECT_FLOW_FLAG_TOCLIENT flag is already set"); - goto error; - } else if (fd->flags & DETECT_FLOW_FLAG_TOSERVER) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set to_client, DETECT_FLOW_FLAG_TOSERVER already set"); - goto error; - } - fd->flags |= DETECT_FLOW_FLAG_TOCLIENT; - } else if (strcasecmp(args[i], "to_server") == 0 || strcasecmp(args[i], "from_client") == 0){ - if (fd->flags & DETECT_FLOW_FLAG_TOSERVER) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set DETECT_FLOW_FLAG_TOSERVER flag is already set"); - goto error; - } else if (fd->flags & DETECT_FLOW_FLAG_TOCLIENT) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set to_server, DETECT_FLOW_FLAG_TO_CLIENT flag already set"); - goto error; - } - fd->flags |= DETECT_FLOW_FLAG_TOSERVER; - } else if (strcasecmp(args[i], "only_stream") == 0) { - if (fd->flags & DETECT_FLOW_FLAG_ONLYSTREAM) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set only_stream flag is already set"); - goto error; - } else if (fd->flags & DETECT_FLOW_FLAG_NOSTREAM) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set only_stream flag, DETECT_FLOW_FLAG_NOSTREAM already set"); - goto error; - } - fd->flags |= DETECT_FLOW_FLAG_ONLYSTREAM; - } else if (strcasecmp(args[i], "no_stream") == 0) { - if (fd->flags & DETECT_FLOW_FLAG_NOSTREAM) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag is already set"); - goto error; - } else if (fd->flags & DETECT_FLOW_FLAG_ONLYSTREAM) { - SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag, DETECT_FLOW_FLAG_ONLYSTREAM already set"); - goto error; - } - fd->flags |= DETECT_FLOW_FLAG_NOSTREAM; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "invalid flow option \"%s\"", args[i]); - goto error; - } - - fd->match_cnt++; - //printf("args[%" PRId32 "]: %s match_cnt: %" PRId32 " flags: 0x%02X\n", i, args[i], fd->match_cnt, fd->flags); - } - } - return fd; - -error: - if (fd != NULL) - DetectFlowFree(fd); - return NULL; - -} - -/** - * \brief this function is used to add the parsed flowdata into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param flowstr pointer to the user provided flow options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectFlowSetup (DetectEngineCtx *de_ctx, Signature *s, char *flowstr) -{ - DetectFlowData *fd = NULL; - SigMatch *sm = NULL; - - fd = DetectFlowParse(flowstr); - if (fd == NULL) - goto error; - - /*ensure only one flow option*/ - if (s->init_flags & SIG_FLAG_INIT_FLOW) { - SCLogError (SC_ERR_INVALID_SIGNATURE, "A signature may have only one flow option."); - goto error; - } - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLOW; - sm->ctx = (SigMatchCtx *)fd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - /* set the signature direction flags */ - if (fd->flags & DETECT_FLOW_FLAG_TOSERVER) { - s->flags |= SIG_FLAG_TOSERVER; - } else if (fd->flags & DETECT_FLOW_FLAG_TOCLIENT) { - s->flags |= SIG_FLAG_TOCLIENT; - } else { - s->flags |= SIG_FLAG_TOSERVER; - s->flags |= SIG_FLAG_TOCLIENT; - } - if (fd->flags & DETECT_FLOW_FLAG_ONLYSTREAM) { - s->flags |= SIG_FLAG_REQUIRE_STREAM; - } - if (fd->flags & DETECT_FLOW_FLAG_NOSTREAM) { - s->flags |= SIG_FLAG_REQUIRE_PACKET; - } else { - s->init_flags |= SIG_FLAG_INIT_FLOW; - } - - return 0; - -error: - if (fd != NULL) - DetectFlowFree(fd); - if (sm != NULL) - SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectFlowData - * - * \param fd pointer to DetectFlowData - */ -void DetectFlowFree(void *ptr) -{ - DetectFlowData *fd = (DetectFlowData *)ptr; - SCFree(fd); -} - -#ifdef UNITTESTS - -/** - * \test DetectFlowTestParse01 is a test to make sure that we return "something" - * when given valid flow opt - */ -int DetectFlowTestParse01 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("established"); - if (fd != NULL) { - DetectFlowFree(fd); - result = 1; - } - - return result; -} - -/** - * \test DetectFlowTestParse02 is a test for setting the established flow opt - */ -int DetectFlowTestParse02 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("established"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_ESTABLISHED && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_ESTABLISHED, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse03 is a test for setting the stateless flow opt - */ -int DetectFlowTestParse03 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("stateless"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_STATELESS && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_STATELESS, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse04 is a test for setting the to_client flow opt - */ -int DetectFlowTestParse04 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("to_client"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_TOCLIENT, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse05 is a test for setting the to_server flow opt - */ -int DetectFlowTestParse05 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("to_server"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_TOSERVER && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_TOSERVER, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse06 is a test for setting the from_server flow opt - */ -int DetectFlowTestParse06 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_server"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_TOCLIENT, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse07 is a test for setting the from_client flow opt - */ -int DetectFlowTestParse07 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_client"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_TOSERVER && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_TOSERVER, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse08 is a test for setting the established,to_client flow opts - */ -int DetectFlowTestParse08 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("established,to_client"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 2) { - result = 1; - } else { - printf("expected: 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_ESTABLISHED + DETECT_FLOW_FLAG_TOCLIENT, 2, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse09 is a test for setting the to_client,stateless flow opts (order of state,dir reversed) - */ -int DetectFlowTestParse09 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("to_client,stateless"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_STATELESS && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 2) { - result = 1; - } else { - printf("expected: 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_STATELESS + DETECT_FLOW_FLAG_TOCLIENT, 2, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse10 is a test for setting the from_server,stateless flow opts (order of state,dir reversed) - */ -int DetectFlowTestParse10 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_server,stateless"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_STATELESS && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 2){ - result = 1; - } else { - printf("expected: 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_STATELESS + DETECT_FLOW_FLAG_TOCLIENT, 2, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse11 is a test for setting the from_server,stateless flow opts with spaces all around - */ -int DetectFlowTestParse11 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse(" from_server , stateless "); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_STATELESS && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 2){ - result = 1; - } else { - printf("expected: 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_STATELESS + DETECT_FLOW_FLAG_TOCLIENT, 2, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase01 is a test to make sure that we return "something" - * when given valid flow opt - */ -int DetectFlowTestParseNocase01 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("ESTABLISHED"); - if (fd != NULL) { - DetectFlowFree(fd); - result = 1; - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase02 is a test for setting the established flow opt - */ -int DetectFlowTestParseNocase02 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("ESTABLISHED"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_ESTABLISHED && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_ESTABLISHED, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase03 is a test for setting the stateless flow opt - */ -int DetectFlowTestParseNocase03 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("STATELESS"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_STATELESS && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_STATELESS, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase04 is a test for setting the to_client flow opt - */ -int DetectFlowTestParseNocase04 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("TO_CLIENT"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_TOCLIENT, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase05 is a test for setting the to_server flow opt - */ -int DetectFlowTestParseNocase05 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("TO_SERVER"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_TOSERVER && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_TOSERVER, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase06 is a test for setting the from_server flow opt - */ -int DetectFlowTestParseNocase06 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("FROM_SERVER"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_TOCLIENT, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase07 is a test for setting the from_client flow opt - */ -int DetectFlowTestParseNocase07 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("FROM_CLIENT"); - if (fd != NULL) { - if (fd->flags == DETECT_FLOW_FLAG_TOSERVER && fd->match_cnt == 1) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_TOSERVER, 1, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase08 is a test for setting the established,to_client flow opts - */ -int DetectFlowTestParseNocase08 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("ESTABLISHED,TO_CLIENT"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 2) { - result = 1; - } else { - printf("expected: 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_ESTABLISHED + DETECT_FLOW_FLAG_TOCLIENT, 2, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase09 is a test for setting the to_client,stateless flow opts (order of state,dir reversed) - */ -int DetectFlowTestParseNocase09 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("TO_CLIENT,STATELESS"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_STATELESS && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 2) { - result = 1; - } else { - printf("expected: 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_STATELESS + DETECT_FLOW_FLAG_TOCLIENT, 2, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase10 is a test for setting the from_server,stateless flow opts (order of state,dir reversed) - */ -int DetectFlowTestParseNocase10 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("FROM_SERVER,STATELESS"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_STATELESS && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 2){ - result = 1; - } else { - printf("expected: 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_STATELESS + DETECT_FLOW_FLAG_TOCLIENT, 2, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase11 is a test for setting the from_server,stateless flow opts with spaces all around - */ -int DetectFlowTestParseNocase11 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse(" FROM_SERVER , STATELESS "); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_STATELESS && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->match_cnt == 2){ - result = 1; - } else { - printf("expected: 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_STATELESS + DETECT_FLOW_FLAG_TOCLIENT, 2, fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - - -/** - * \test DetectFlowTestParse12 is a test for setting an invalid seperator : - */ -int DetectFlowTestParse12 (void) -{ - int result = 1; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_server:stateless"); - if (fd != NULL) { - printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); - result = 0; - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse13 is a test for an invalid option - */ -int DetectFlowTestParse13 (void) -{ - int result = 1; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("invalidoptiontest"); - if (fd != NULL) { - printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); - result = 0; - DetectFlowFree(fd); - } - - return result; -} -/** - * \test DetectFlowTestParse14 is a test for a empty option - */ -int DetectFlowTestParse14 (void) -{ - int result = 1; - DetectFlowData *fd = NULL; - fd = DetectFlowParse(""); - if (fd != NULL) { - printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); - result = 0; - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse15 is a test for an invalid combo of options established,stateless - */ -int DetectFlowTestParse15 (void) -{ - int result = 1; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("established,stateless"); - if (fd != NULL) { - printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); - result = 0; - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse16 is a test for an invalid combo of options to_client,to_server - */ -int DetectFlowTestParse16 (void) -{ - int result = 1; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("to_client,to_server"); - if (fd != NULL) { - printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); - result = 0; - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse16 is a test for an invalid combo of options to_client,from_server - * flowbit flags are the same - */ -int DetectFlowTestParse17 (void) -{ - int result = 1; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("to_client,from_server"); - if (fd != NULL) { - printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); - result = 0; - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse18 is a test for setting the from_server,stateless,only_stream flow opts (order of state,dir reversed) - */ -int DetectFlowTestParse18 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_server,established,only_stream"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->flags & DETECT_FLOW_FLAG_ONLYSTREAM && fd->match_cnt == 3) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_ESTABLISHED + DETECT_FLOW_FLAG_TOCLIENT + DETECT_FLOW_FLAG_ONLYSTREAM, 3, - fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParseNocase18 is a test for setting the from_server,stateless,only_stream flow opts (order of state,dir reversed) - */ -int DetectFlowTestParseNocase18 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("FROM_SERVER,ESTABLISHED,ONLY_STREAM"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->flags & DETECT_FLOW_FLAG_ONLYSTREAM && fd->match_cnt == 3) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_ESTABLISHED + DETECT_FLOW_FLAG_TOCLIENT + DETECT_FLOW_FLAG_ONLYSTREAM, 3, - fd->flags, fd->match_cnt); - } - DetectFlowFree(fd); - } - - return result; -} - - -/** - * \test DetectFlowTestParse19 is a test for one to many options passed to DetectFlowParse - */ -int DetectFlowTestParse19 (void) -{ - int result = 1; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_server,established,only_stream,a"); - if (fd != NULL) { - printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); - result = 0; - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse20 is a test for setting from_server, established, no_stream - */ -int DetectFlowTestParse20 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_server,established,no_stream"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->flags & DETECT_FLOW_FLAG_NOSTREAM && fd->match_cnt == 3) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_ESTABLISHED + DETECT_FLOW_FLAG_TOCLIENT + DETECT_FLOW_FLAG_NOSTREAM, 3, - fd->flags, fd->match_cnt); - } - - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse20 is a test for setting from_server, established, no_stream - */ -int DetectFlowTestParseNocase20 (void) -{ - int result = 0; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("FROM_SERVER,ESTABLISHED,NO_STREAM"); - if (fd != NULL) { - if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED && fd->flags & DETECT_FLOW_FLAG_TOCLIENT && fd->flags & DETECT_FLOW_FLAG_NOSTREAM && fd->match_cnt == 3) { - result = 1; - } else { - printf("expected 0x%02X cnt %" PRId32 " got 0x%02X cnt %" PRId32 ": ", DETECT_FLOW_FLAG_ESTABLISHED + DETECT_FLOW_FLAG_TOCLIENT + DETECT_FLOW_FLAG_NOSTREAM, 3, - fd->flags, fd->match_cnt); - } - - DetectFlowFree(fd); - } - - return result; -} - -/** - * \test DetectFlowTestParse21 is a test for an invalid opt between to valid opts - */ -int DetectFlowTestParse21 (void) -{ - int result = 1; - DetectFlowData *fd = NULL; - fd = DetectFlowParse("from_server,a,no_stream"); - if (fd != NULL) { - printf("expected: NULL got 0x%02X %" PRId32 ": ",fd->flags, fd->match_cnt); - result = 0; - DetectFlowFree(fd); - } - - return result; -} - -static int DetectFlowSigTest01(void) -{ - int result = 0; - ThreadVars th_v; - DecodeThreadVars dtv; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - uint8_t *buf = (uint8_t *)"supernovaduper"; - uint16_t buflen = strlen((char *)buf); - - Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - if (p->flow != NULL) { - printf("packet has flow set\n"); - goto end; - } - - char *sig1 = "alert tcp any any -> any any (msg:\"dummy\"; " - "content:\"nova\"; flow:no_stream; sid:1;)"; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx == NULL: "); - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig1); - if (de_ctx->sig_list == NULL) { - printf("signature == NULL: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) != 1) { - goto end; - } - - result = 1; - - end: - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - if (p != NULL) - UTHFreePacket(p); - - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectFlow - */ -void DetectFlowRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectFlowTestParse01", DetectFlowTestParse01, 1); - UtRegisterTest("DetectFlowTestParse02", DetectFlowTestParse02, 1); - UtRegisterTest("DetectFlowTestParse03", DetectFlowTestParse03, 1); - UtRegisterTest("DetectFlowTestParse04", DetectFlowTestParse04, 1); - UtRegisterTest("DetectFlowTestParse05", DetectFlowTestParse05, 1); - UtRegisterTest("DetectFlowTestParse06", DetectFlowTestParse06, 1); - UtRegisterTest("DetectFlowTestParse07", DetectFlowTestParse07, 1); - UtRegisterTest("DetectFlowTestParse08", DetectFlowTestParse08, 1); - UtRegisterTest("DetectFlowTestParse09", DetectFlowTestParse09, 1); - UtRegisterTest("DetectFlowTestParse10", DetectFlowTestParse10, 1); - UtRegisterTest("DetectFlowTestParse11", DetectFlowTestParse11, 1); - UtRegisterTest("DetectFlowTestParseNocase01", DetectFlowTestParseNocase01, 1); - UtRegisterTest("DetectFlowTestParseNocase02", DetectFlowTestParseNocase02, 1); - UtRegisterTest("DetectFlowTestParseNocase03", DetectFlowTestParseNocase03, 1); - UtRegisterTest("DetectFlowTestParseNocase04", DetectFlowTestParseNocase04, 1); - UtRegisterTest("DetectFlowTestParseNocase05", DetectFlowTestParseNocase05, 1); - UtRegisterTest("DetectFlowTestParseNocase06", DetectFlowTestParseNocase06, 1); - UtRegisterTest("DetectFlowTestParseNocase07", DetectFlowTestParseNocase07, 1); - UtRegisterTest("DetectFlowTestParseNocase08", DetectFlowTestParseNocase08, 1); - UtRegisterTest("DetectFlowTestParseNocase09", DetectFlowTestParseNocase09, 1); - UtRegisterTest("DetectFlowTestParseNocase10", DetectFlowTestParseNocase10, 1); - UtRegisterTest("DetectFlowTestParseNocase11", DetectFlowTestParseNocase11, 1); - UtRegisterTest("DetectFlowTestParse12", DetectFlowTestParse12, 1); - UtRegisterTest("DetectFlowTestParse13", DetectFlowTestParse13, 1); - UtRegisterTest("DetectFlowTestParse14", DetectFlowTestParse14, 1); - UtRegisterTest("DetectFlowTestParse15", DetectFlowTestParse15, 1); - UtRegisterTest("DetectFlowTestParse16", DetectFlowTestParse16, 1); - UtRegisterTest("DetectFlowTestParse17", DetectFlowTestParse17, 1); - UtRegisterTest("DetectFlowTestParse18", DetectFlowTestParse18, 1); - UtRegisterTest("DetectFlowTestParseNocase18", DetectFlowTestParseNocase18, 1); - UtRegisterTest("DetectFlowTestParse19", DetectFlowTestParse19, 1); - UtRegisterTest("DetectFlowTestParse20", DetectFlowTestParse20, 1); - UtRegisterTest("DetectFlowTestParseNocase20", DetectFlowTestParseNocase20, 1); - UtRegisterTest("DetectFlowTestParse21", DetectFlowTestParse21, 1); - - UtRegisterTest("DetectFlowSigTest01", DetectFlowSigTest01, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-flow.h b/framework/src/suricata/src/detect-flow.h deleted file mode 100644 index b3774c29..00000000 --- a/framework/src/suricata/src/detect-flow.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_FLOW_H__ -#define __DETECT_FLOW_H__ - -#define DETECT_FLOW_FLAG_TOSERVER 0x01 -#define DETECT_FLOW_FLAG_TOCLIENT 0x02 -#define DETECT_FLOW_FLAG_ESTABLISHED 0x04 -#define DETECT_FLOW_FLAG_STATELESS 0x08 -#define DETECT_FLOW_FLAG_ONLYSTREAM 0x10 -#define DETECT_FLOW_FLAG_NOSTREAM 0x20 - -typedef struct DetectFlowData_ { - uint8_t flags; /* flags to match */ - uint8_t match_cnt; /* number of matches we need */ -} DetectFlowData; - -/* prototypes */ -void DetectFlowRegister (void); - -#endif /* __DETECT_FLOW_H__ */ - diff --git a/framework/src/suricata/src/detect-flowbits.c b/framework/src/suricata/src/detect-flowbits.c deleted file mode 100644 index 2c10f499..00000000 --- a/framework/src/suricata/src/detect-flowbits.c +++ /dev/null @@ -1,1156 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Breno Silva - * - * Implements the flowbits keyword - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "threads.h" -#include "flow.h" -#include "flow-bit.h" -#include "flow-util.h" -#include "detect-flowbits.h" -#include "util-spm.h" - -#include "app-layer-parser.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow-bit.h" -#include "util-var-name.h" -#include "util-unittest.h" -#include "util-debug.h" - -#define PARSE_REGEX "([a-z]+)(?:,\\s*([^\\s]*))?" -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectFlowbitMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectFlowbitSetup (DetectEngineCtx *, Signature *, char *); -void DetectFlowbitFree (void *); -void FlowBitsRegisterTests(void); - -void DetectFlowbitsRegister (void) -{ - sigmatch_table[DETECT_FLOWBITS].name = "flowbits"; - sigmatch_table[DETECT_FLOWBITS].desc = "operate on flow flag"; - sigmatch_table[DETECT_FLOWBITS].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Flow-keywords#Flowbits"; - sigmatch_table[DETECT_FLOWBITS].Match = DetectFlowbitMatch; - sigmatch_table[DETECT_FLOWBITS].Setup = DetectFlowbitSetup; - sigmatch_table[DETECT_FLOWBITS].Free = DetectFlowbitFree; - sigmatch_table[DETECT_FLOWBITS].RegisterTests = FlowBitsRegisterTests; - /* this is compatible to ip-only signatures */ - sigmatch_table[DETECT_FLOWBITS].flags |= SIGMATCH_IPONLY_COMPAT; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - return; -} - - -static int DetectFlowbitMatchToggle (Packet *p, const DetectFlowbitsData *fd, const int flow_locked) -{ - if (p->flow == NULL) - return 0; - - if (flow_locked) - FlowBitToggleNoLock(p->flow,fd->idx); - else - FlowBitToggle(p->flow,fd->idx); - return 1; -} - -static int DetectFlowbitMatchUnset (Packet *p, const DetectFlowbitsData *fd, const int flow_locked) -{ - if (p->flow == NULL) - return 0; - - if (flow_locked) - FlowBitUnsetNoLock(p->flow,fd->idx); - else - FlowBitUnset(p->flow,fd->idx); - return 1; -} - -static int DetectFlowbitMatchSet (Packet *p, const DetectFlowbitsData *fd, const int flow_locked) -{ - if (p->flow == NULL) - return 0; - - if (flow_locked) - FlowBitSetNoLock(p->flow,fd->idx); - else - FlowBitSet(p->flow,fd->idx); - return 1; -} - -static int DetectFlowbitMatchIsset (Packet *p, const DetectFlowbitsData *fd) -{ - if (p->flow == NULL) - return 0; - - return FlowBitIsset(p->flow,fd->idx); -} - -static int DetectFlowbitMatchIsnotset (Packet *p, const DetectFlowbitsData *fd) -{ - if (p->flow == NULL) - return 0; - - return FlowBitIsnotset(p->flow,fd->idx); -} - -/* - * returns 0: no match - * 1: match - * -1: error - */ - -int DetectFlowbitMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectFlowbitsData *fd = (const DetectFlowbitsData *)ctx; - if (fd == NULL) - return 0; - const int flow_locked = det_ctx->flow_locked; - - switch (fd->cmd) { - case DETECT_FLOWBITS_CMD_ISSET: - return DetectFlowbitMatchIsset(p,fd); - case DETECT_FLOWBITS_CMD_ISNOTSET: - return DetectFlowbitMatchIsnotset(p,fd); - case DETECT_FLOWBITS_CMD_SET: - return DetectFlowbitMatchSet(p,fd,flow_locked); - case DETECT_FLOWBITS_CMD_UNSET: - return DetectFlowbitMatchUnset(p,fd,flow_locked); - case DETECT_FLOWBITS_CMD_TOGGLE: - return DetectFlowbitMatchToggle(p,fd,flow_locked); - default: - SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown cmd %" PRIu32 "", fd->cmd); - return 0; - } - - return 0; -} - -static int DetectFlowbitParse(char *str, char *cmd, int cmd_len, char *name, - int name_len) -{ - const int max_substrings = 30; - int count, rc; - int ov[max_substrings]; - - count = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, - ov, max_substrings); - if (count != 2 && count != 3) { - SCLogError(SC_ERR_PCRE_MATCH, - "\"%s\" is not a valid setting for flowbits.", str); - return 0; - } - - rc = pcre_copy_substring((char *)str, ov, max_substrings, 1, cmd, cmd_len); - if (rc < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return 0; - } - - if (count == 3) { - rc = pcre_copy_substring((char *)str, ov, max_substrings, 2, name, - name_len); - if (rc < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return 0; - } - } - - return 1; -} - -int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectFlowbitsData *cd = NULL; - SigMatch *sm = NULL; - uint8_t fb_cmd = 0; - char fb_cmd_str[16] = "", fb_name[256] = ""; - - if (!DetectFlowbitParse(rawstr, fb_cmd_str, sizeof(fb_cmd_str), fb_name, - sizeof(fb_name))) { - return -1; - } - - if (strcmp(fb_cmd_str,"noalert") == 0) { - fb_cmd = DETECT_FLOWBITS_CMD_NOALERT; - } else if (strcmp(fb_cmd_str,"isset") == 0) { - fb_cmd = DETECT_FLOWBITS_CMD_ISSET; - } else if (strcmp(fb_cmd_str,"isnotset") == 0) { - fb_cmd = DETECT_FLOWBITS_CMD_ISNOTSET; - } else if (strcmp(fb_cmd_str,"set") == 0) { - fb_cmd = DETECT_FLOWBITS_CMD_SET; - } else if (strcmp(fb_cmd_str,"unset") == 0) { - fb_cmd = DETECT_FLOWBITS_CMD_UNSET; - } else if (strcmp(fb_cmd_str,"toggle") == 0) { - fb_cmd = DETECT_FLOWBITS_CMD_TOGGLE; - } else { - SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: flowbits action \"%s\" is not supported.", fb_cmd_str); - goto error; - } - - switch (fb_cmd) { - case DETECT_FLOWBITS_CMD_NOALERT: - if (strlen(fb_name) != 0) - goto error; - s->flags |= SIG_FLAG_NOALERT; - return 0; - case DETECT_FLOWBITS_CMD_ISNOTSET: - case DETECT_FLOWBITS_CMD_ISSET: - case DETECT_FLOWBITS_CMD_SET: - case DETECT_FLOWBITS_CMD_UNSET: - case DETECT_FLOWBITS_CMD_TOGGLE: - default: - if (strlen(fb_name) == 0) - goto error; - break; - } - - cd = SCMalloc(sizeof(DetectFlowbitsData)); - if (unlikely(cd == NULL)) - goto error; - - cd->idx = VariableNameGetIdx(de_ctx, fb_name, VAR_TYPE_FLOW_BIT); - cd->cmd = fb_cmd; - - SCLogDebug("idx %" PRIu32 ", cmd %s, name %s", - cd->idx, fb_cmd_str, strlen(fb_name) ? fb_name : "(none)"); - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLOWBITS; - sm->ctx = (SigMatchCtx *)cd; - - switch (fb_cmd) { - /* case DETECT_FLOWBITS_CMD_NOALERT can't happen here */ - - case DETECT_FLOWBITS_CMD_ISNOTSET: - case DETECT_FLOWBITS_CMD_ISSET: - /* checks, so packet list */ - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - break; - - case DETECT_FLOWBITS_CMD_SET: - case DETECT_FLOWBITS_CMD_UNSET: - case DETECT_FLOWBITS_CMD_TOGGLE: - /* modifiers, only run when entire sig has matched */ - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_POSTMATCH); - break; - } - - return 0; - -error: - if (cd != NULL) - SCFree(cd); - if (sm != NULL) - SCFree(sm); - return -1; -} - -void DetectFlowbitFree (void *ptr) -{ - DetectFlowbitsData *fd = (DetectFlowbitsData *)ptr; - - if (fd == NULL) - return; - - SCFree(fd); -} - -#ifdef UNITTESTS - -static int FlowBitsTestParse01(void) -{ - int ret = 0; - char command[16] = "", name[16] = ""; - - /* Single argument version. */ - if (!DetectFlowbitParse("noalert", command, sizeof(command), name, - sizeof(name))) { - goto end; - } - if (strcmp(command, "noalert") != 0) { - goto end; - } - - /* No leading or trailing spaces. */ - if (!DetectFlowbitParse("set,flowbit", command, sizeof(command), name, - sizeof(name))) { - goto end; - } - if (strcmp(command, "set") != 0) { - goto end; - } - if (strcmp(name, "flowbit") != 0) { - goto end; - } - - /* Leading space. */ - if (!DetectFlowbitParse("set, flowbit", command, sizeof(command), name, - sizeof(name))) { - goto end; - } - if (strcmp(command, "set") != 0) { - goto end; - } - if (strcmp(name, "flowbit") != 0) { - goto end; - } - - /* Trailing space. */ - if (!DetectFlowbitParse("set,flowbit ", command, sizeof(command), name, - sizeof(name))) { - goto end; - } - if (strcmp(command, "set") != 0) { - goto end; - } - if (strcmp(name, "flowbit") != 0) { - goto end; - } - - /* Leading and trailing space. */ - if (!DetectFlowbitParse("set, flowbit ", command, sizeof(command), name, - sizeof(name))) { - goto end; - } - if (strcmp(command, "set") != 0) { - goto end; - } - if (strcmp(name, "flowbit") != 0) { - goto end; - } - - ret = 1; -end: - return ret; -} - -/** - * \test FlowBitsTestSig01 is a test for a valid noalert flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int FlowBitsTestSig01(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Noalert\"; flowbits:noalert,wrongusage; content:\"GET \"; sid:1;)"); - - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - SCFree(p); - return result; -} - -/** - * \test FlowBitsTestSig02 is a test for a valid isset,set,isnotset,unset,toggle flowbits options - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int FlowBitsTestSig02(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - int error_count = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"isset rule need an option\"; flowbits:isset; content:\"GET \"; sid:1;)"); - - if (s == NULL) { - error_count++; - } - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"isnotset rule need an option\"; flowbits:isnotset; content:\"GET \"; sid:2;)"); - - if (s == NULL) { - error_count++; - } - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"set rule need an option\"; flowbits:set; content:\"GET \"; sid:3;)"); - - if (s == NULL) { - error_count++; - } - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"unset rule need an option\"; flowbits:unset; content:\"GET \"; sid:4;)"); - - if (s == NULL) { - error_count++; - } - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"toggle rule need an option\"; flowbits:toggle; content:\"GET \"; sid:5;)"); - - if (s == NULL) { - error_count++; - } - - if(error_count == 5) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - goto cleanup; - } - if (PacketAlertCheck(p, 2)) { - goto cleanup; - } - if (PacketAlertCheck(p, 3)) { - goto cleanup; - } - if (PacketAlertCheck(p, 4)) { - goto cleanup; - } - if (PacketAlertCheck(p, 5)) { - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - SCFree(p); - return result; -} - -/** - * \test FlowBitsTestSig03 is a test for a invalid flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int FlowBitsTestSig03(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Unknown cmd\"; flowbits:wrongcmd; content:\"GET \"; sid:1;)"); - - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - - SCFree(p); - return result; -} - -/** - * \test FlowBitsTestSig04 is a test check idx value - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int FlowBitsTestSig04(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - int idx = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"isset option\"; flowbits:isset,fbt; content:\"GET \"; sid:1;)"); - - idx = VariableNameGetIdx(de_ctx, "fbt", VAR_TYPE_FLOW_BIT); - - if (s == NULL || idx != 1) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - SCFree(p); - return result; - -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - SCFree(p); - return result; -} - -/** - * \test FlowBitsTestSig05 is a test check noalert flag - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int FlowBitsTestSig05(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Noalert\"; flowbits:noalert; content:\"GET \"; sid:1;)"); - - if (s == NULL || ((s->flags & SIG_FLAG_NOALERT) != SIG_FLAG_NOALERT)) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - SCFree(p); - return result; -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - SCFree(p); - return result; -} - -/** - * \test FlowBitsTestSig06 is a test set flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int FlowBitsTestSig06(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - GenericVar flowvar, *gv = NULL; - int result = 0; - int idx = 0; - - memset(p, 0, SIZE_OF_PACKET); - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(Flow)); - memset(&flowvar, 0, sizeof(GenericVar)); - - FLOW_INITIALIZE(&f); - p->flow = &f; - p->flow->flowvar = &flowvar; - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - p->flags |= PKT_HAS_FLOW; - p->flowflags |= FLOW_PKT_TOSERVER; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit set\"; flowbits:set,myflow; sid:10;)"); - - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - idx = VariableNameGetIdx(de_ctx, "myflow", VAR_TYPE_FLOW_BIT); - - gv = p->flow->flowvar; - - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_FLOWBITS && gv->idx == idx) { - result = 1; - } - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - - SCFree(p); - return result; -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - SCFree(p); - return result; -} - -/** - * \test FlowBitsTestSig07 is a test unset flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int FlowBitsTestSig07(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - GenericVar flowvar, *gv = NULL; - int result = 0; - int idx = 0; - - memset(p, 0, SIZE_OF_PACKET); - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(Flow)); - memset(&flowvar, 0, sizeof(GenericVar)); - - FLOW_INITIALIZE(&f); - p->flow = &f; - p->flow->flowvar = &flowvar; - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit set\"; flowbits:set,myflow2; sid:10;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit unset\"; flowbits:unset,myflow2; sid:11;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - idx = VariableNameGetIdx(de_ctx, "myflow", VAR_TYPE_FLOW_BIT); - - gv = p->flow->flowvar; - - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_FLOWBITS && gv->idx == idx) { - result = 1; - } - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - - SCFree(p); - return result; -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - - SCFree(p); - return result; -} - -/** - * \test FlowBitsTestSig08 is a test toogle flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int FlowBitsTestSig08(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - GenericVar flowvar, *gv = NULL; - int result = 0; - int idx = 0; - - memset(p, 0, SIZE_OF_PACKET); - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(Flow)); - memset(&flowvar, 0, sizeof(GenericVar)); - - FLOW_INITIALIZE(&f); - p->flow = &f; - p->flow->flowvar = &flowvar; - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit set\"; flowbits:set,myflow2; sid:10;)"); - - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit unset\"; flowbits:toggle,myflow2; sid:11;)"); - - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - idx = VariableNameGetIdx(de_ctx, "myflow", VAR_TYPE_FLOW_BIT); - - gv = p->flow->flowvar; - - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_FLOWBITS && gv->idx == idx) { - result = 1; - } - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - - SCFree(p); - return result; -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - - SCFree(p); - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for FlowBits - */ -void FlowBitsRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("FlowBitsTestParse01", FlowBitsTestParse01, 1); - UtRegisterTest("FlowBitsTestSig01", FlowBitsTestSig01, 0); - UtRegisterTest("FlowBitsTestSig02", FlowBitsTestSig02, 0); - UtRegisterTest("FlowBitsTestSig03", FlowBitsTestSig03, 0); - UtRegisterTest("FlowBitsTestSig04", FlowBitsTestSig04, 1); - UtRegisterTest("FlowBitsTestSig05", FlowBitsTestSig05, 1); - UtRegisterTest("FlowBitsTestSig06", FlowBitsTestSig06, 1); - UtRegisterTest("FlowBitsTestSig07", FlowBitsTestSig07, 0); - UtRegisterTest("FlowBitsTestSig08", FlowBitsTestSig08, 0); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-flowbits.h b/framework/src/suricata/src/detect-flowbits.h deleted file mode 100644 index 8961da3f..00000000 --- a/framework/src/suricata/src/detect-flowbits.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Breno Silva - */ - -#ifndef __DETECT_FLOWBITS_H__ -#define __DETECT_FLOWBITS_H__ - -#define DETECT_FLOWBITS_CMD_SET 0 -#define DETECT_FLOWBITS_CMD_TOGGLE 1 -#define DETECT_FLOWBITS_CMD_UNSET 2 -#define DETECT_FLOWBITS_CMD_ISNOTSET 3 -#define DETECT_FLOWBITS_CMD_ISSET 4 -#define DETECT_FLOWBITS_CMD_NOALERT 5 -#define DETECT_FLOWBITS_CMD_MAX 6 - -typedef struct DetectFlowbitsData_ { - uint16_t idx; - uint8_t cmd; -} DetectFlowbitsData; - -/* prototypes */ -void DetectFlowbitsRegister (void); - -#endif /* __DETECT_FLOWBITS_H__ */ - diff --git a/framework/src/suricata/src/detect-flowint.c b/framework/src/suricata/src/detect-flowint.c deleted file mode 100644 index 54303cd3..00000000 --- a/framework/src/suricata/src/detect-flowint.c +++ /dev/null @@ -1,2178 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * - * Flowvar management for integer types, part of the detection engine - * Keyword: flowint - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "threads.h" -#include "flow.h" -#include "flow-var.h" -#include "detect-flowint.h" -#include "util-spm.h" -#include "util-var-name.h" -#include "util-debug.h" -#include "util-unittest.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "pkt-var.h" -#include "host.h" -#include "util-profiling.h" - -/* name modifiers value */ -#define PARSE_REGEX "^\\s*([a-zA-Z][\\w\\d_.]+)\\s*,\\s*([+=-]{1}|==|!=|<|<=|>|>=|isset|notset)\\s*,?\\s*([a-zA-Z][\\w\\d]+|[\\d]{1,10})?\\s*$" -/* Varnames must begin with a letter */ - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectFlowintMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectFlowintSetup(DetectEngineCtx *, Signature *, char *); -void DetectFlowintFree(void *); -void DetectFlowintRegisterTests(void); - -void DetectFlowintRegister(void) -{ - sigmatch_table[DETECT_FLOWINT].name = "flowint"; - sigmatch_table[DETECT_FLOWINT].desc = "operate on a per-flow integer"; - sigmatch_table[DETECT_FLOWINT].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Flowint"; - sigmatch_table[DETECT_FLOWINT].Match = DetectFlowintMatch; - sigmatch_table[DETECT_FLOWINT].Setup = DetectFlowintSetup; - sigmatch_table[DETECT_FLOWINT].Free = DetectFlowintFree; - sigmatch_table[DETECT_FLOWINT].RegisterTests = DetectFlowintRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; -error: - SCLogInfo("Error registering flowint detection plugin"); - return; -} - -/** - * \brief This function is used to create a flowint, add/substract values, - * compare it with other flowints, etc - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param s pointer to the current Signature - * \param m pointer to the sigmatch that we will cast into DetectFlowintData - * - * \retval 0 no match, when a var doesn't exist - * \retval 1 match, when a var is initialized well, add/substracted, or a true - * condition - */ -int DetectFlowintMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const int flow_locked = det_ctx->flow_locked; - const DetectFlowintData *sfd = (const DetectFlowintData *)ctx; - FlowVar *fv; - FlowVar *fvt; - uint32_t targetval; - int ret = 0; - - if (flow_locked == 0) - FLOWLOCK_WRLOCK(p->flow); - - /** ATM If we are going to compare the current var with another - * that doesn't exist, the default value will be zero; - * if you don't want this behaviour, you can use the keyword - * "isset" to make it match or not before using the default - * value of zero; - * But it is mandatory that the current var exist, otherwise, it will - * return zero(not match). - */ - if (sfd->targettype == FLOWINT_TARGET_VAR) { - uint16_t tvar_idx = VariableNameGetIdx(det_ctx->de_ctx, sfd->target.tvar.name, VAR_TYPE_FLOW_INT); - - fvt = FlowVarGet(p->flow, tvar_idx); - /* We don't have that variable initialized yet */ - if (fvt == NULL) - targetval = 0; - else - targetval = fvt->data.fv_int.value; - } else { - targetval = sfd->target.value; - } - - SCLogDebug("Our var %s is at idx: %"PRIu16"", sfd->name, sfd->idx); - - if (sfd->modifier == FLOWINT_MODIFIER_SET) { - FlowVarAddIntNoLock(p->flow, sfd->idx, targetval); - SCLogDebug("Setting %s = %u", sfd->name, targetval); - ret = 1; - goto end; - } - - fv = FlowVarGet(p->flow, sfd->idx); - - if (sfd->modifier == FLOWINT_MODIFIER_ISSET) { - SCLogDebug(" Isset %s? = %u", sfd->name,(fv) ? 1 : 0); - if (fv != NULL) - ret = 1; - goto end; - } - - if (sfd->modifier == FLOWINT_MODIFIER_NOTSET) { - SCLogDebug(" Not set %s? = %u", sfd->name,(fv) ? 0 : 1); - if (fv == NULL) - ret = 1; - goto end; - } - - if (fv != NULL && fv->datatype == FLOWVAR_TYPE_INT) { - if (sfd->modifier == FLOWINT_MODIFIER_ADD) { - SCLogDebug("Adding %u to %s", targetval, sfd->name); - FlowVarAddIntNoLock(p->flow, sfd->idx, fv->data.fv_int.value + - targetval); - ret = 1; - goto end; - } - - if (sfd->modifier == FLOWINT_MODIFIER_SUB) { - SCLogDebug("Substracting %u to %s", targetval, sfd->name); - FlowVarAddIntNoLock(p->flow, sfd->idx, fv->data.fv_int.value - - targetval); - ret = 1; - goto end; - } - - switch(sfd->modifier) { - case FLOWINT_MODIFIER_EQ: - SCLogDebug("( %u EQ %u )", fv->data.fv_int.value, targetval); - ret = (fv->data.fv_int.value == targetval); - break; - case FLOWINT_MODIFIER_NE: - SCLogDebug("( %u NE %u )", fv->data.fv_int.value, targetval); - ret = (fv->data.fv_int.value != targetval); - break; - case FLOWINT_MODIFIER_LT: - SCLogDebug("( %u LT %u )", fv->data.fv_int.value, targetval); - ret = (fv->data.fv_int.value < targetval); - break; - case FLOWINT_MODIFIER_LE: - SCLogDebug("( %u LE %u )", fv->data.fv_int.value, targetval); - ret = (fv->data.fv_int.value <= targetval); - break; - case FLOWINT_MODIFIER_GT: - SCLogDebug("( %u GT %u )", fv->data.fv_int.value, targetval); - ret = (fv->data.fv_int.value > targetval); - break; - case FLOWINT_MODIFIER_GE: - SCLogDebug("( %u GE %u )", fv->data.fv_int.value, targetval); - ret = (fv->data.fv_int.value >= targetval); - break; - default: - SCLogDebug("Unknown Modifier!"); -#ifdef DEBUG - BUG_ON(1); -#endif - } - } else { - /* allow a add on a non-existing var, it will init to the "add" value, - * so implying a 0 set. */ - if (sfd->modifier == FLOWINT_MODIFIER_ADD) { - SCLogDebug("Adding %u to %s (new var)", targetval, sfd->name); - FlowVarAddIntNoLock(p->flow, sfd->idx, targetval); - ret = 1; - } else { - SCLogDebug("Var not found!"); - /* It doesn't exist because it wasn't set - * or it is a string var, that we don't compare here - */ - ret = 0; - } - } - -end: - if (flow_locked == 0) - FLOWLOCK_UNLOCK(p->flow); - return ret; -} - -/** - * \brief This function is used to parse a flowint option - * - * \param de_ctx pointer to the engine context - * \param rawstr pointer to the string holding the options - * - * \retval NULL if invalid option - * \retval DetectFlowintData pointer with the flowint parsed - */ -DetectFlowintData *DetectFlowintParse(DetectEngineCtx *de_ctx, char *rawstr) -{ - DetectFlowintData *sfd = NULL; - char *varname = NULL; - char *varval = NULL; - char *modstr = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - uint8_t modifier = FLOWINT_MODIFIER_UNKNOWN; - unsigned long long value_long = 0; - const char *str_ptr; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), - 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 3 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for flowint(ret = %d).", rawstr, ret); - return NULL; - } - - /* Get our flowint varname */ - res = pcre_get_substring((char *) rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0 || str_ptr == NULL) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - varname = (char *)str_ptr; - - res = pcre_get_substring((char *) rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0 || str_ptr == NULL) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - modstr = (char *)str_ptr; - - /* Get the modifier */ - if (strcmp("=", modstr) == 0) - modifier = FLOWINT_MODIFIER_SET; - if (strcmp("+", modstr) == 0) - modifier = FLOWINT_MODIFIER_ADD; - if (strcmp("-", modstr) == 0) - modifier = FLOWINT_MODIFIER_SUB; - - if (strcmp("<", modstr) == 0) - modifier = FLOWINT_MODIFIER_LT; - if (strcmp("<=", modstr) == 0) - modifier = FLOWINT_MODIFIER_LE; - if (strcmp("!=", modstr) == 0) - modifier = FLOWINT_MODIFIER_NE; - if (strcmp("==", modstr) == 0) - modifier = FLOWINT_MODIFIER_EQ; - if (strcmp(">=", modstr) == 0) - modifier = FLOWINT_MODIFIER_GE; - if (strcmp(">", modstr) == 0) - modifier = FLOWINT_MODIFIER_GT; - if (strcmp("isset", modstr) == 0) - modifier = FLOWINT_MODIFIER_ISSET; - if (strcmp("notset", modstr) == 0) - modifier = FLOWINT_MODIFIER_NOTSET; - - if (modifier == FLOWINT_MODIFIER_UNKNOWN) { - SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown modifier"); - goto error; - } - - sfd = SCMalloc(sizeof(DetectFlowintData)); - if (unlikely(sfd == NULL)) - goto error; - - /* If we need another arg, check it out(isset doesn't need another arg) */ - if (modifier != FLOWINT_MODIFIER_ISSET && modifier != FLOWINT_MODIFIER_NOTSET) { - if (ret < 4) - goto error; - - res = pcre_get_substring((char *) rawstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); - varval = (char *)str_ptr; - if (res < 0 || varval == NULL || strcmp(varval, "") == 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (varval[0] >= '0' && varval[0] <= '9') { /* is digit, look at the regexp */ - sfd->targettype = FLOWINT_TARGET_VAL; - value_long = atoll(varval); - if (value_long > UINT32_MAX) { - SCLogDebug("DetectFlowintParse: Cannot load this value." - " Values should be between 0 and %"PRIu32, UINT32_MAX); - goto error; - } - sfd->target.value = (uint32_t) value_long; - } else { - sfd->targettype = FLOWINT_TARGET_VAR; - sfd->target.tvar.name = SCStrdup(varval); - if (unlikely(sfd->target.tvar.name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "malloc from strdup failed"); - goto error; - } - } - } else { - sfd->targettype = FLOWINT_TARGET_SELF; - } - - /* Set the name of the origin var to modify/compared with the target */ - sfd->name = SCStrdup(varname); - if (unlikely(sfd->name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "malloc from strdup failed"); - goto error; - } - if (de_ctx != NULL) - sfd->idx = VariableNameGetIdx(de_ctx, varname, VAR_TYPE_FLOW_INT); - sfd->modifier = modifier; - - pcre_free_substring(varname); - pcre_free_substring(modstr); - if (varval) - pcre_free_substring(varval); - return sfd; -error: - if (varname) - pcre_free_substring(varname); - if (varval) - pcre_free_substring(varval); - if (modstr) - pcre_free_substring(modstr); - if (sfd != NULL) - SCFree(sfd); - return NULL; -} - -/** - * \brief This function is used to set up the SigMatch holding the flowint opt - * - * \param de_ctx pointer to the engine context - * \param s pointer to the current Signature - * \param rawstr pointer to the string holding the options - * - * \retval 0 if all is ok - * \retval -1 if we find any problem - */ -static int DetectFlowintSetup(DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectFlowintData *sfd = NULL; - SigMatch *sm = NULL; - - sfd = DetectFlowintParse(de_ctx, rawstr); - if (sfd == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FLOWINT; - sm->ctx = (SigMatchCtx *)sfd; - - switch (sfd->modifier) { - case FLOWINT_MODIFIER_SET: - case FLOWINT_MODIFIER_ADD: - case FLOWINT_MODIFIER_SUB: - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_POSTMATCH); - break; - - case FLOWINT_MODIFIER_LT: - case FLOWINT_MODIFIER_LE: - case FLOWINT_MODIFIER_NE: - case FLOWINT_MODIFIER_EQ: - case FLOWINT_MODIFIER_GE: - case FLOWINT_MODIFIER_GT: - case FLOWINT_MODIFIER_ISSET: - case FLOWINT_MODIFIER_NOTSET: - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - break; - default: - goto error; - } - - return 0; - -error: - if (sfd) - DetectFlowintFree(sfd); - if (sm) - SCFree(sm); - return -1; -} - -/** - * \brief This function is used to free the data of DetectFlowintData - */ -void DetectFlowintFree(void *tmp) -{ - DetectFlowintData *sfd =(DetectFlowintData*) tmp; - if (sfd != NULL) { - if (sfd->name != NULL) - SCFree(sfd->name); - if (sfd->targettype == FLOWINT_TARGET_VAR) - if (sfd->target.tvar.name != NULL) - SCFree(sfd->target.tvar.name); - SCFree(sfd); - } -} - -/** - * \brief This is a helper funtion used for debugging purposes - */ -void DetectFlowintPrintData(DetectFlowintData *sfd) -{ - if (sfd == NULL) { - SCLogDebug("DetectFlowintPrintData: Error, DetectFlowintData == NULL!"); - return; - } - - SCLogDebug("Varname: %s, modifier: %"PRIu8", idx: %"PRIu16" Target: ", - sfd->name, sfd->modifier, sfd->idx); - switch(sfd->targettype) { - case FLOWINT_TARGET_VAR: - SCLogDebug("target_var: %s", - sfd->target.tvar.name); - break; - case FLOWINT_TARGET_VAL: - SCLogDebug("Value: %"PRIu32"; ", sfd->target.value); - break; - default : - SCLogDebug("DetectFlowintPrintData: Error, Targettype not known!"); - } -} - -#ifdef UNITTESTS -/** - * \test DetectFlowintTestParseVal01 is a test to make sure that we set the - * DetectFlowint correctly for setting a valid target value - */ -int DetectFlowintTestParseVal01(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,=,35"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar") - && sfd->modifier == FLOWINT_MODIFIER_SET) { - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar01 is a test to make sure that we set the - * DetectFlowint correctly for setting a valid target variable - */ -int DetectFlowintTestParseVar01(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,=,targetvar"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_VAR - && sfd->target.tvar.name != NULL - && !strcmp(sfd->target.tvar.name, "targetvar") - && sfd->modifier == FLOWINT_MODIFIER_SET) { - - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVal02 is a test to make sure that we set the - * DetectFlowint correctly for adding a valid target value - */ -int DetectFlowintTestParseVal02(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,+,35"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar") - && sfd->modifier == FLOWINT_MODIFIER_ADD) { - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar02 is a test to make sure that we set the - * DetectFlowint correctly for adding a valid target variable - */ -int DetectFlowintTestParseVar02(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,+,targetvar"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_VAR - && sfd->target.tvar.name != NULL - && !strcmp(sfd->target.tvar.name, "targetvar") - && sfd->modifier == FLOWINT_MODIFIER_ADD) { - - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVal03 is a test to make sure that we set the - * DetectFlowint correctly for substract a valid target value - */ -int DetectFlowintTestParseVal03(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,-,35"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar") - && sfd->modifier == FLOWINT_MODIFIER_SUB) { - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar03 is a test to make sure that we set the - * DetectFlowint correctly for substract a valid target variable - */ -int DetectFlowintTestParseVar03(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,-,targetvar"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_VAR - && sfd->target.tvar.name != NULL - && !strcmp(sfd->target.tvar.name, "targetvar") - && sfd->modifier == FLOWINT_MODIFIER_SUB) { - - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - - -/** - * \test DetectFlowintTestParseVal04 is a test to make sure that we set the - * DetectFlowint correctly for checking if equal to a valid target value - */ -int DetectFlowintTestParseVal04(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,==,35"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar") - && sfd->modifier == FLOWINT_MODIFIER_EQ) { - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar04 is a test to make sure that we set the - * DetectFlowint correctly for checking if equal to a valid target variable - */ -int DetectFlowintTestParseVar04(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,==,targetvar"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_VAR - && sfd->target.tvar.name != NULL - && !strcmp(sfd->target.tvar.name, "targetvar") - && sfd->modifier == FLOWINT_MODIFIER_EQ) { - - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVal05 is a test to make sure that we set the - * DetectFlowint correctly for cheking if not equal to a valid target value - */ -int DetectFlowintTestParseVal05(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,!=,35"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar") - && sfd->modifier == FLOWINT_MODIFIER_NE) { - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar05 is a test to make sure that we set the - * DetectFlowint correctly for checking if not equal to a valid target variable - */ -int DetectFlowintTestParseVar05(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,!=,targetvar"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_VAR - && sfd->target.tvar.name != NULL - && !strcmp(sfd->target.tvar.name, "targetvar") - && sfd->modifier == FLOWINT_MODIFIER_NE) { - - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVal06 is a test to make sure that we set the - * DetectFlowint correctly for cheking if greater than a valid target value - */ -int DetectFlowintTestParseVal06(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar, >,35"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar") - && sfd->modifier == FLOWINT_MODIFIER_GT) { - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar06 is a test to make sure that we set the - * DetectFlowint correctly for checking if greater than a valid target variable - */ -int DetectFlowintTestParseVar06(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar, >,targetvar"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_VAR - && sfd->target.tvar.name != NULL - && !strcmp(sfd->target.tvar.name, "targetvar") - && sfd->modifier == FLOWINT_MODIFIER_GT) { - - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVal07 is a test to make sure that we set the - * DetectFlowint correctly for cheking if greater or equal than a valid target value - */ -int DetectFlowintTestParseVal07(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar, >= ,35"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar") - && sfd->modifier == FLOWINT_MODIFIER_GE) { - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar07 is a test to make sure that we set the - * DetectFlowint correctly for checking if greater or equal than a valid target variable - */ -int DetectFlowintTestParseVar07(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar, >= ,targetvar"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_VAR - && sfd->target.tvar.name != NULL - && !strcmp(sfd->target.tvar.name, "targetvar") - && sfd->modifier == FLOWINT_MODIFIER_GE) { - - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVal08 is a test to make sure that we set the - * DetectFlowint correctly for cheking if lower or equal than a valid target value - */ -int DetectFlowintTestParseVal08(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar, <= ,35"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar") - && sfd->modifier == FLOWINT_MODIFIER_LE) { - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar08 is a test to make sure that we set the - * DetectFlowint correctly for checking if lower or equal than a valid target variable - */ -int DetectFlowintTestParseVar08(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar, <= ,targetvar"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_VAR - && sfd->target.tvar.name != NULL - && !strcmp(sfd->target.tvar.name, "targetvar") - && sfd->modifier == FLOWINT_MODIFIER_LE) { - - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVal09 is a test to make sure that we set the - * DetectFlowint correctly for cheking if lower than a valid target value - */ -int DetectFlowintTestParseVal09(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar, < ,35"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar") - && sfd->modifier == FLOWINT_MODIFIER_LT) { - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar09 is a test to make sure that we set the - * DetectFlowint correctly for checking if lower than a valid target variable - */ -int DetectFlowintTestParseVar09(void) -{ - int result = 0; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar, < ,targetvar"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_VAR - && sfd->target.tvar.name != NULL - && !strcmp(sfd->target.tvar.name, "targetvar") - && sfd->modifier == FLOWINT_MODIFIER_LT) { - - result = 1; - } - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseVar09 is a test to make sure that handle the - * isset keyword correctly - */ -int DetectFlowintTestParseIsset10(void) -{ - int result = 1; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar, isset"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_SELF - && sfd->modifier == FLOWINT_MODIFIER_ISSET) { - - result &= 1; - } else { - result = 0; - } - - if (sfd) DetectFlowintFree(sfd); - sfd = DetectFlowintParse(de_ctx, "myvar, notset"); - DetectFlowintPrintData(sfd); - if (sfd != NULL && !strcmp(sfd->name, "myvar") - && sfd->targettype == FLOWINT_TARGET_SELF - && sfd->modifier == FLOWINT_MODIFIER_NOTSET) { - - result &= 1; - } else { - result = 0; - } - - if (sfd) DetectFlowintFree(sfd); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectFlowintTestParseInvalidSyntaxis01 is a test to make sure that we dont set the - * DetectFlowint for a invalid input option - */ -int DetectFlowintTestParseInvalidSyntaxis01(void) -{ - int result = 1; - DetectFlowintData *sfd = NULL; - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto error; - de_ctx->flags |= DE_QUIET; - - sfd = DetectFlowintParse(de_ctx, "myvar,=,9999999999"); - if (sfd != NULL) { - SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,=,9532458716234857"); - result = 0; - } - if (sfd) DetectFlowintFree(sfd); - - sfd = DetectFlowintParse(de_ctx, "myvar,=,45targetvar"); - if (sfd != NULL) { - SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,=,45targetvar "); - result = 0; - } - if (sfd) DetectFlowintFree(sfd); - - sfd = DetectFlowintParse(de_ctx, "657myvar,=,targetvar"); - if (sfd != NULL) { - SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at 657myvar,=,targetvar "); - result = 0; - } - if (sfd) DetectFlowintFree(sfd); - - sfd = DetectFlowintParse(de_ctx, "myvar,=<,targetvar"); - if (sfd != NULL) { - SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,=<,targetvar "); - result = 0; - } - if (sfd) DetectFlowintFree(sfd); - - sfd = DetectFlowintParse(de_ctx, "myvar,===,targetvar"); - if (sfd != NULL) { - SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,===,targetvar "); - result = 0; - } - if (sfd) DetectFlowintFree(sfd); - - sfd = DetectFlowintParse(de_ctx, "myvar,=="); - if (sfd != NULL) { - SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,=="); - result = 0; - } - if (sfd) DetectFlowintFree(sfd); - - sfd = DetectFlowintParse(de_ctx, "myvar,"); - if (sfd != NULL) { - SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,"); - result = 0; - } - if (sfd) DetectFlowintFree(sfd); - - sfd = DetectFlowintParse(de_ctx, "myvar"); - if (sfd != NULL) { - SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar"); - result = 0; - } - if (sfd) DetectFlowintFree(sfd); - - DetectEngineCtxFree(de_ctx); - - return result; -error: - if (de_ctx) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test DetectFlowintTestPacket01Real - * \brief Set a counter when we see a content:"GET" - * and increment it by 2 if we match a "Unauthorized" - * When it reach 3(with the last +2), another counter starts - * and when that counter reach 6 packets. - * - * All the Signatures generate an alert(its for testing) - * but the ignature that increment the second counter +1, that has - * a "noalert", so we can do all increments - * silently until we reach 6 next packets counted - */ -int DetectFlowintTestPacket01Real() -{ - int result = 1; - - uint8_t pkt1[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3c, 0xc2, 0x26, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x67, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x82, 0xb5, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, - 0x16, 0xd0, 0xe8, 0xb0, 0x00, 0x00, 0x02, 0x04, - 0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a, 0x01, 0x72, - 0x40, 0x93, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, - 0x03, 0x07 - }; - - uint8_t pkt2[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06, - 0xb6, 0x8e, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8b, 0xdd, 0x17, 0x51, 0x82, 0xb6, 0xa0, 0x12, - 0x16, 0x80, 0x17, 0x8a, 0x00, 0x00, 0x02, 0x04, - 0x05, 0xac, 0x04, 0x02, 0x08, 0x0a, 0x01, 0x29, - 0x23, 0x63, 0x01, 0x72, 0x40, 0x93, 0x01, 0x03, - 0x03, 0x07 - }; - - uint8_t pkt3[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x27, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6e, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x82, 0xb6, 0x21, 0x04, 0x8b, 0xde, 0x80, 0x10, - 0x00, 0x2e, 0x5c, 0xa0, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0x93, 0x01, 0x29, - 0x23, 0x63 - }; - - uint8_t pkt4[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x01, 0x12, 0xc2, 0x28, 0x40, 0x00, 0x40, 0x06, - 0xf3, 0x8f, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x82, 0xb6, 0x21, 0x04, 0x8b, 0xde, 0x80, 0x18, - 0x00, 0x2e, 0x24, 0x39, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0x93, 0x01, 0x29, - 0x23, 0x63, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, - 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x3a, 0x20, 0x74, 0x65, 0x78, - 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x20, - 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x63, 0x73, 0x73, 0x2c, 0x20, 0x74, 0x65, - 0x78, 0x74, 0x2f, 0x73, 0x67, 0x6d, 0x6c, 0x2c, - 0x20, 0x2a, 0x2f, 0x2a, 0x3b, 0x71, 0x3d, 0x30, - 0x2e, 0x30, 0x31, 0x0d, 0x0a, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x2d, 0x45, 0x6e, 0x63, 0x6f, - 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x67, 0x7a, - 0x69, 0x70, 0x2c, 0x20, 0x62, 0x7a, 0x69, 0x70, - 0x32, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x2d, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, - 0x67, 0x65, 0x3a, 0x20, 0x65, 0x6e, 0x0d, 0x0a, - 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x3a, 0x20, 0x4c, 0x79, 0x6e, 0x78, - 0x2f, 0x32, 0x2e, 0x38, 0x2e, 0x36, 0x72, 0x65, - 0x6c, 0x2e, 0x34, 0x20, 0x6c, 0x69, 0x62, 0x77, - 0x77, 0x77, 0x2d, 0x46, 0x4d, 0x2f, 0x32, 0x2e, - 0x31, 0x34, 0x20, 0x53, 0x53, 0x4c, 0x2d, 0x4d, - 0x4d, 0x2f, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x20, - 0x47, 0x4e, 0x55, 0x54, 0x4c, 0x53, 0x2f, 0x32, - 0x2e, 0x30, 0x2e, 0x34, 0x0d, 0x0a, 0x0d, 0x0a - }; - - uint8_t pkt5[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xa8, 0xbd, 0x40, 0x00, 0x40, 0x06, - 0x0d, 0xd9, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8b, 0xde, 0x17, 0x51, 0x83, 0x94, 0x80, 0x10, - 0x00, 0x2d, 0x5b, 0xc3, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x23, 0x63, 0x01, 0x72, - 0x40, 0x93 - }; - - uint8_t pkt6[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x01, 0xe4, 0xa8, 0xbe, 0x40, 0x00, 0x40, 0x06, - 0x0c, 0x28, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8b, 0xde, 0x17, 0x51, 0x83, 0x94, 0x80, 0x18, - 0x00, 0x2d, 0x1b, 0x84, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x23, 0x6a, 0x01, 0x72, - 0x40, 0x93, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, - 0x2e, 0x31, 0x20, 0x34, 0x30, 0x31, 0x20, 0x55, - 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x65, 0x64, 0x0d, 0x0a, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x6d, 0x69, 0x63, - 0x72, 0x6f, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, - 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, - 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, - 0x65, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, - 0x20, 0x57, 0x65, 0x64, 0x2c, 0x20, 0x31, 0x34, - 0x20, 0x4f, 0x63, 0x74, 0x20, 0x32, 0x30, 0x30, - 0x39, 0x20, 0x31, 0x33, 0x3a, 0x34, 0x39, 0x3a, - 0x35, 0x33, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x57, 0x57, 0x57, 0x2d, 0x41, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, - 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x3d, 0x22, 0x44, - 0x53, 0x4c, 0x20, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x22, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, - 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, - 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, - 0x0d, 0x0a, 0x3c, 0x48, 0x54, 0x4d, 0x4c, 0x3e, - 0x3c, 0x48, 0x45, 0x41, 0x44, 0x3e, 0x3c, 0x54, - 0x49, 0x54, 0x4c, 0x45, 0x3e, 0x34, 0x30, 0x31, - 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x65, 0x64, 0x3c, 0x2f, 0x54, - 0x49, 0x54, 0x4c, 0x45, 0x3e, 0x3c, 0x2f, 0x48, - 0x45, 0x41, 0x44, 0x3e, 0x0a, 0x3c, 0x42, 0x4f, - 0x44, 0x59, 0x20, 0x42, 0x47, 0x43, 0x4f, 0x4c, - 0x4f, 0x52, 0x3d, 0x22, 0x23, 0x63, 0x63, 0x39, - 0x39, 0x39, 0x39, 0x22, 0x3e, 0x3c, 0x48, 0x34, - 0x3e, 0x34, 0x30, 0x31, 0x20, 0x55, 0x6e, 0x61, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, - 0x64, 0x3c, 0x2f, 0x48, 0x34, 0x3e, 0x0a, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x3c, - 0x48, 0x52, 0x3e, 0x0a, 0x3c, 0x41, 0x44, 0x44, - 0x52, 0x45, 0x53, 0x53, 0x3e, 0x3c, 0x41, 0x20, - 0x48, 0x52, 0x45, 0x46, 0x3d, 0x22, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, - 0x72, 0x65, 0x2f, 0x6d, 0x69, 0x63, 0x72, 0x6f, - 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x2f, 0x22, - 0x3e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x5f, 0x68, - 0x74, 0x74, 0x70, 0x64, 0x3c, 0x2f, 0x41, 0x3e, - 0x3c, 0x2f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, - 0x53, 0x3e, 0x0a, 0x3c, 0x2f, 0x42, 0x4f, 0x44, - 0x59, 0x3e, 0x3c, 0x2f, 0x48, 0x54, 0x4d, 0x4c, - 0x3e, 0x0a - }; - - uint8_t pkt7[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x29, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6c, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x83, 0x94, 0x21, 0x04, 0x8d, 0x8e, 0x80, 0x10, - 0x00, 0x36, 0x59, 0xfa, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0x9c, 0x01, 0x29, - 0x23, 0x6a - }; - - uint8_t pkt8[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xa8, 0xbf, 0x40, 0x00, 0x40, 0x06, - 0x0d, 0xd7, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8d, 0x8e, 0x17, 0x51, 0x83, 0x94, 0x80, 0x11, - 0x00, 0x2d, 0x5a, 0x0b, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x23, 0x6a, 0x01, 0x72, - 0x40, 0x93 - }; - - uint8_t pkt9[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x2a, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6b, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x83, 0x94, 0x21, 0x04, 0x8d, 0x8f, 0x80, 0x10, - 0x00, 0x36, 0x59, 0xef, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0xa6, 0x01, 0x29, - 0x23, 0x6a - }; - - uint8_t pkt10[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x2b, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6a, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x83, 0x94, 0x21, 0x04, 0x8d, 0x8f, 0x80, 0x11, - 0x00, 0x36, 0x57, 0x0a, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x43, 0x8a, 0x01, 0x29, - 0x23, 0x6a - }; - - uint8_t pkt11[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0x10, 0xaf, 0x40, 0x00, 0x40, 0x06, - 0xa5, 0xe7, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8d, 0x8f, 0x17, 0x51, 0x83, 0x95, 0x80, 0x10, - 0x00, 0x2d, 0x54, 0xbb, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x25, 0xc2, 0x01, 0x72, - 0x43, 0x8a - }; - - uint8_t *pkts[] = { - pkt1, pkt2, pkt3, pkt4, pkt5, pkt6, pkt7, pkt8, - pkt9, pkt10, pkt11 - }; - - uint16_t pktssizes[] = { - sizeof(pkt1), sizeof(pkt2), sizeof(pkt3), sizeof(pkt4), sizeof(pkt5), - sizeof(pkt6), sizeof(pkt7), sizeof(pkt8), sizeof(pkt9), sizeof(pkt10), - sizeof(pkt11) - }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - FlowInitConfig(FLOW_QUIET); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - /* Now that we have the array of packets for the flow, prepare the signatures */ - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"Setting a flowint counter\"; content:\"GET\"; flowint:myvar,=,1; flowint:maxvar,=,6; sid:101;)"); - - de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"Adding to flowint counter\"; content:\"Unauthorized\"; flowint: myvar,+,2; sid:102;)"); - - de_ctx->sig_list->next->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"if the flowint counter is 3 create a new counter\"; content:\"Unauthorized\"; flowint: myvar,==,3; flowint: cntpackets, =, 0; sid:103;)"); - - de_ctx->sig_list->next->next->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"and count the rest of the packets received without generating alerts!!!\"; flowint: myvar,==,3; flowint: cntpackets, +, 1; noalert;sid:104;)"); - - /* comparation of myvar with maxvar */ - de_ctx->sig_list->next->next->next->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\" and fire this when it reach 6\"; flowint: cntpackets, ==, maxvar; sid:105;)"); - - /* I know it's a bit ugly, */ - de_ctx->sig_list->next->next->next->next->next = NULL; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v,(void *) de_ctx,(void *) &det_ctx); - - /* Decode the packets, and test the matches*/ - int i; - for (i = 0;i < 11;i++) { - memset(p, 0, SIZE_OF_PACKET); - PACKET_INITIALIZE(p); - DecodeEthernet(&th_v, &dtv, p, pkts[i], pktssizes[i], NULL); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - switch(i) { - case 3: - if (PacketAlertCheck(p, 101) == 0) { - SCLogDebug("Not declared/initialized!"); - result = 0; - } - break; - case 5: - if (PacketAlertCheck(p, 102) == 0) { - SCLogDebug("Not incremented!"); - result = 0; - } - - if (PacketAlertCheck(p, 103) == 0) { - SCLogDebug("myvar is not 3 or bad cmp!!"); - result = 0; - } - break; - case 10: - if (PacketAlertCheck(p, 105) == 0) { - SCLogDebug("Not declared/initialized/or well incremented the" - " second var!"); - result = 0; - } - break; - } - SCLogDebug("Raw Packet %d has %u alerts ", i, p->alerts.cnt); - PACKET_RECYCLE(p); - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v,(void *) det_ctx); - DetectEngineCtxFree(de_ctx); - FlowShutdown(); - - SCFree(p); - return result; - -end: - if (de_ctx) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - if (det_ctx) - DetectEngineThreadCtxDeinit(&th_v,(void *) det_ctx); - if (de_ctx) - DetectEngineCtxFree(de_ctx); - - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return result; -} - -/** - * \test DetectFlowintTestPacket02Real - * \brief like DetectFlowintTestPacket01Real but using isset/notset keywords - */ -int DetectFlowintTestPacket02Real() -{ - int result = 1; - - uint8_t pkt1[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3c, 0xc2, 0x26, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x67, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x82, 0xb5, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, - 0x16, 0xd0, 0xe8, 0xb0, 0x00, 0x00, 0x02, 0x04, - 0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a, 0x01, 0x72, - 0x40, 0x93, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, - 0x03, 0x07 - }; - - uint8_t pkt2[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06, - 0xb6, 0x8e, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8b, 0xdd, 0x17, 0x51, 0x82, 0xb6, 0xa0, 0x12, - 0x16, 0x80, 0x17, 0x8a, 0x00, 0x00, 0x02, 0x04, - 0x05, 0xac, 0x04, 0x02, 0x08, 0x0a, 0x01, 0x29, - 0x23, 0x63, 0x01, 0x72, 0x40, 0x93, 0x01, 0x03, - 0x03, 0x07 - }; - - uint8_t pkt3[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x27, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6e, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x82, 0xb6, 0x21, 0x04, 0x8b, 0xde, 0x80, 0x10, - 0x00, 0x2e, 0x5c, 0xa0, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0x93, 0x01, 0x29, - 0x23, 0x63 - }; - - uint8_t pkt4[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x01, 0x12, 0xc2, 0x28, 0x40, 0x00, 0x40, 0x06, - 0xf3, 0x8f, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x82, 0xb6, 0x21, 0x04, 0x8b, 0xde, 0x80, 0x18, - 0x00, 0x2e, 0x24, 0x39, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0x93, 0x01, 0x29, - 0x23, 0x63, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, - 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x3a, 0x20, 0x74, 0x65, 0x78, - 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x20, - 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x63, 0x73, 0x73, 0x2c, 0x20, 0x74, 0x65, - 0x78, 0x74, 0x2f, 0x73, 0x67, 0x6d, 0x6c, 0x2c, - 0x20, 0x2a, 0x2f, 0x2a, 0x3b, 0x71, 0x3d, 0x30, - 0x2e, 0x30, 0x31, 0x0d, 0x0a, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x2d, 0x45, 0x6e, 0x63, 0x6f, - 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x67, 0x7a, - 0x69, 0x70, 0x2c, 0x20, 0x62, 0x7a, 0x69, 0x70, - 0x32, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x2d, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, - 0x67, 0x65, 0x3a, 0x20, 0x65, 0x6e, 0x0d, 0x0a, - 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x3a, 0x20, 0x4c, 0x79, 0x6e, 0x78, - 0x2f, 0x32, 0x2e, 0x38, 0x2e, 0x36, 0x72, 0x65, - 0x6c, 0x2e, 0x34, 0x20, 0x6c, 0x69, 0x62, 0x77, - 0x77, 0x77, 0x2d, 0x46, 0x4d, 0x2f, 0x32, 0x2e, - 0x31, 0x34, 0x20, 0x53, 0x53, 0x4c, 0x2d, 0x4d, - 0x4d, 0x2f, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x20, - 0x47, 0x4e, 0x55, 0x54, 0x4c, 0x53, 0x2f, 0x32, - 0x2e, 0x30, 0x2e, 0x34, 0x0d, 0x0a, 0x0d, 0x0a - }; - - uint8_t pkt5[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xa8, 0xbd, 0x40, 0x00, 0x40, 0x06, - 0x0d, 0xd9, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8b, 0xde, 0x17, 0x51, 0x83, 0x94, 0x80, 0x10, - 0x00, 0x2d, 0x5b, 0xc3, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x23, 0x63, 0x01, 0x72, - 0x40, 0x93 - }; - - uint8_t pkt6[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x01, 0xe4, 0xa8, 0xbe, 0x40, 0x00, 0x40, 0x06, - 0x0c, 0x28, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8b, 0xde, 0x17, 0x51, 0x83, 0x94, 0x80, 0x18, - 0x00, 0x2d, 0x1b, 0x84, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x23, 0x6a, 0x01, 0x72, - 0x40, 0x93, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, - 0x2e, 0x31, 0x20, 0x34, 0x30, 0x31, 0x20, 0x55, - 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x65, 0x64, 0x0d, 0x0a, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x6d, 0x69, 0x63, - 0x72, 0x6f, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, - 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, - 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, - 0x65, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, - 0x20, 0x57, 0x65, 0x64, 0x2c, 0x20, 0x31, 0x34, - 0x20, 0x4f, 0x63, 0x74, 0x20, 0x32, 0x30, 0x30, - 0x39, 0x20, 0x31, 0x33, 0x3a, 0x34, 0x39, 0x3a, - 0x35, 0x33, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x57, 0x57, 0x57, 0x2d, 0x41, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, - 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x3d, 0x22, 0x44, - 0x53, 0x4c, 0x20, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x22, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, - 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, - 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, - 0x0d, 0x0a, 0x3c, 0x48, 0x54, 0x4d, 0x4c, 0x3e, - 0x3c, 0x48, 0x45, 0x41, 0x44, 0x3e, 0x3c, 0x54, - 0x49, 0x54, 0x4c, 0x45, 0x3e, 0x34, 0x30, 0x31, - 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x65, 0x64, 0x3c, 0x2f, 0x54, - 0x49, 0x54, 0x4c, 0x45, 0x3e, 0x3c, 0x2f, 0x48, - 0x45, 0x41, 0x44, 0x3e, 0x0a, 0x3c, 0x42, 0x4f, - 0x44, 0x59, 0x20, 0x42, 0x47, 0x43, 0x4f, 0x4c, - 0x4f, 0x52, 0x3d, 0x22, 0x23, 0x63, 0x63, 0x39, - 0x39, 0x39, 0x39, 0x22, 0x3e, 0x3c, 0x48, 0x34, - 0x3e, 0x34, 0x30, 0x31, 0x20, 0x55, 0x6e, 0x61, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, - 0x64, 0x3c, 0x2f, 0x48, 0x34, 0x3e, 0x0a, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x3c, - 0x48, 0x52, 0x3e, 0x0a, 0x3c, 0x41, 0x44, 0x44, - 0x52, 0x45, 0x53, 0x53, 0x3e, 0x3c, 0x41, 0x20, - 0x48, 0x52, 0x45, 0x46, 0x3d, 0x22, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, - 0x72, 0x65, 0x2f, 0x6d, 0x69, 0x63, 0x72, 0x6f, - 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x2f, 0x22, - 0x3e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x5f, 0x68, - 0x74, 0x74, 0x70, 0x64, 0x3c, 0x2f, 0x41, 0x3e, - 0x3c, 0x2f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, - 0x53, 0x3e, 0x0a, 0x3c, 0x2f, 0x42, 0x4f, 0x44, - 0x59, 0x3e, 0x3c, 0x2f, 0x48, 0x54, 0x4d, 0x4c, - 0x3e, 0x0a - }; - - uint8_t pkt7[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x29, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6c, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x83, 0x94, 0x21, 0x04, 0x8d, 0x8e, 0x80, 0x10, - 0x00, 0x36, 0x59, 0xfa, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0x9c, 0x01, 0x29, - 0x23, 0x6a - }; - - uint8_t pkt8[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xa8, 0xbf, 0x40, 0x00, 0x40, 0x06, - 0x0d, 0xd7, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8d, 0x8e, 0x17, 0x51, 0x83, 0x94, 0x80, 0x11, - 0x00, 0x2d, 0x5a, 0x0b, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x23, 0x6a, 0x01, 0x72, - 0x40, 0x93 - }; - - uint8_t pkt9[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x2a, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6b, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x83, 0x94, 0x21, 0x04, 0x8d, 0x8f, 0x80, 0x10, - 0x00, 0x36, 0x59, 0xef, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0xa6, 0x01, 0x29, - 0x23, 0x6a - }; - - uint8_t pkt10[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x2b, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6a, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x83, 0x94, 0x21, 0x04, 0x8d, 0x8f, 0x80, 0x11, - 0x00, 0x36, 0x57, 0x0a, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x43, 0x8a, 0x01, 0x29, - 0x23, 0x6a - }; - - uint8_t pkt11[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0x10, 0xaf, 0x40, 0x00, 0x40, 0x06, - 0xa5, 0xe7, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8d, 0x8f, 0x17, 0x51, 0x83, 0x95, 0x80, 0x10, - 0x00, 0x2d, 0x54, 0xbb, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x25, 0xc2, 0x01, 0x72, - 0x43, 0x8a - }; - - uint8_t *pkts[] = { - pkt1, pkt2, pkt3, pkt4, pkt5, pkt6, pkt7, pkt8, - pkt9, pkt10, pkt11 - }; - - uint16_t pktssizes[] = { - sizeof(pkt1), sizeof(pkt2), sizeof(pkt3), sizeof(pkt4), sizeof(pkt5), - sizeof(pkt6), sizeof(pkt7), sizeof(pkt8), sizeof(pkt9), sizeof(pkt10), - sizeof(pkt11) - }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - DecodeThreadVars dtv; - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - FlowInitConfig(FLOW_QUIET); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - /* Now that we have the array of packets for the flow, prepare the signatures */ - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"Setting a flowint counter\"; content:\"GET\"; flowint: myvar, notset; flowint:maxvar,notset; flowint: myvar,=,1; flowint: maxvar,=,6; sid:101;)"); - - de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"Adding to flowint counter\"; content:\"Unauthorized\"; flowint:myvar,isset; flowint: myvar,+,2; sid:102;)"); - - de_ctx->sig_list->next->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"if the flowint counter is 3 create a new counter\"; content:\"Unauthorized\"; flowint: myvar, isset; flowint: myvar,==,3; flowint:cntpackets,notset; flowint: cntpackets, =, 0; sid:103;)"); - - de_ctx->sig_list->next->next->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"and count the rest of the packets received without generating alerts!!!\"; flowint: cntpackets,isset; flowint: cntpackets, +, 1; noalert;sid:104;)"); - - /* comparation of myvar with maxvar */ - de_ctx->sig_list->next->next->next->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\" and fire this when it reach 6\"; flowint: cntpackets, isset; flowint: maxvar,isset; flowint: cntpackets, ==, maxvar; sid:105;)"); - - /* I know it's a bit ugly, */ - de_ctx->sig_list->next->next->next->next->next = NULL; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v,(void *) de_ctx,(void *) &det_ctx); - - int i; - - /* Decode the packets, and test the matches*/ - for (i = 0;i < 11;i++) { - memset(p, 0, SIZE_OF_PACKET); - PACKET_INITIALIZE(p); - DecodeEthernet(&th_v, &dtv, p, pkts[i], pktssizes[i], NULL); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - switch(i) { - case 3: - if (PacketAlertCheck(p, 101) == 0) { - SCLogDebug("Not declared/initialized!"); - result = 0; - } - break; - case 5: - if (PacketAlertCheck(p, 102) == 0) { - SCLogDebug("Not incremented!"); - result = 0; - } - - if (PacketAlertCheck(p, 103) == 0) { - SCLogDebug("myvar is not 3 or bad cmp!!"); - result = 0; - } - break; - case 10: - if (PacketAlertCheck(p, 105) == 0) { - SCLogDebug("Not declared/initialized/or well incremented the" - " second var!"); - result = 0; - } - break; - } - SCLogDebug("Raw Packet %d has %u alerts ", i, p->alerts.cnt); - PACKET_RECYCLE(p); - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v,(void *) det_ctx); - //PatternMatchDestroy(mpm_ctx); - DetectEngineCtxFree(de_ctx); - FlowShutdown(); - - SCFree(p); - return result; - -end: - if (de_ctx) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - if (det_ctx) - DetectEngineThreadCtxDeinit(&th_v,(void *) det_ctx); - //PatternMatchDestroy(mpm_ctx); - if (de_ctx) - DetectEngineCtxFree(de_ctx); - - FlowShutdown(); - SCFree(p); - return result; -} - -/** - * \test DetectFlowintTestPacket03Real - * \brief Check the behaviour of isset/notset - */ -int DetectFlowintTestPacket03Real() -{ - int result = 1; - - uint8_t pkt1[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3c, 0xc2, 0x26, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x67, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x82, 0xb5, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, - 0x16, 0xd0, 0xe8, 0xb0, 0x00, 0x00, 0x02, 0x04, - 0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a, 0x01, 0x72, - 0x40, 0x93, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, - 0x03, 0x07 - }; - - uint8_t pkt2[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06, - 0xb6, 0x8e, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8b, 0xdd, 0x17, 0x51, 0x82, 0xb6, 0xa0, 0x12, - 0x16, 0x80, 0x17, 0x8a, 0x00, 0x00, 0x02, 0x04, - 0x05, 0xac, 0x04, 0x02, 0x08, 0x0a, 0x01, 0x29, - 0x23, 0x63, 0x01, 0x72, 0x40, 0x93, 0x01, 0x03, - 0x03, 0x07 - }; - - uint8_t pkt3[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x27, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6e, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x82, 0xb6, 0x21, 0x04, 0x8b, 0xde, 0x80, 0x10, - 0x00, 0x2e, 0x5c, 0xa0, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0x93, 0x01, 0x29, - 0x23, 0x63 - }; - - uint8_t pkt4[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x01, 0x12, 0xc2, 0x28, 0x40, 0x00, 0x40, 0x06, - 0xf3, 0x8f, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x82, 0xb6, 0x21, 0x04, 0x8b, 0xde, 0x80, 0x18, - 0x00, 0x2e, 0x24, 0x39, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0x93, 0x01, 0x29, - 0x23, 0x63, 0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, - 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x3a, 0x20, 0x74, 0x65, 0x78, - 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x20, - 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x63, 0x73, 0x73, 0x2c, 0x20, 0x74, 0x65, - 0x78, 0x74, 0x2f, 0x73, 0x67, 0x6d, 0x6c, 0x2c, - 0x20, 0x2a, 0x2f, 0x2a, 0x3b, 0x71, 0x3d, 0x30, - 0x2e, 0x30, 0x31, 0x0d, 0x0a, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x2d, 0x45, 0x6e, 0x63, 0x6f, - 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x67, 0x7a, - 0x69, 0x70, 0x2c, 0x20, 0x62, 0x7a, 0x69, 0x70, - 0x32, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x2d, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, - 0x67, 0x65, 0x3a, 0x20, 0x65, 0x6e, 0x0d, 0x0a, - 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x3a, 0x20, 0x4c, 0x79, 0x6e, 0x78, - 0x2f, 0x32, 0x2e, 0x38, 0x2e, 0x36, 0x72, 0x65, - 0x6c, 0x2e, 0x34, 0x20, 0x6c, 0x69, 0x62, 0x77, - 0x77, 0x77, 0x2d, 0x46, 0x4d, 0x2f, 0x32, 0x2e, - 0x31, 0x34, 0x20, 0x53, 0x53, 0x4c, 0x2d, 0x4d, - 0x4d, 0x2f, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x20, - 0x47, 0x4e, 0x55, 0x54, 0x4c, 0x53, 0x2f, 0x32, - 0x2e, 0x30, 0x2e, 0x34, 0x0d, 0x0a, 0x0d, 0x0a - }; - - uint8_t pkt5[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xa8, 0xbd, 0x40, 0x00, 0x40, 0x06, - 0x0d, 0xd9, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8b, 0xde, 0x17, 0x51, 0x83, 0x94, 0x80, 0x10, - 0x00, 0x2d, 0x5b, 0xc3, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x23, 0x63, 0x01, 0x72, - 0x40, 0x93 - }; - - uint8_t pkt6[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x01, 0xe4, 0xa8, 0xbe, 0x40, 0x00, 0x40, 0x06, - 0x0c, 0x28, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8b, 0xde, 0x17, 0x51, 0x83, 0x94, 0x80, 0x18, - 0x00, 0x2d, 0x1b, 0x84, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x23, 0x6a, 0x01, 0x72, - 0x40, 0x93, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, - 0x2e, 0x31, 0x20, 0x34, 0x30, 0x31, 0x20, 0x55, - 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x65, 0x64, 0x0d, 0x0a, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x3a, 0x20, 0x6d, 0x69, 0x63, - 0x72, 0x6f, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, - 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, - 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, - 0x65, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, - 0x20, 0x57, 0x65, 0x64, 0x2c, 0x20, 0x31, 0x34, - 0x20, 0x4f, 0x63, 0x74, 0x20, 0x32, 0x30, 0x30, - 0x39, 0x20, 0x31, 0x33, 0x3a, 0x34, 0x39, 0x3a, - 0x35, 0x33, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x57, 0x57, 0x57, 0x2d, 0x41, 0x75, 0x74, 0x68, - 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, - 0x72, 0x65, 0x61, 0x6c, 0x6d, 0x3d, 0x22, 0x44, - 0x53, 0x4c, 0x20, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x22, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, - 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, - 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, - 0x0d, 0x0a, 0x3c, 0x48, 0x54, 0x4d, 0x4c, 0x3e, - 0x3c, 0x48, 0x45, 0x41, 0x44, 0x3e, 0x3c, 0x54, - 0x49, 0x54, 0x4c, 0x45, 0x3e, 0x34, 0x30, 0x31, - 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x65, 0x64, 0x3c, 0x2f, 0x54, - 0x49, 0x54, 0x4c, 0x45, 0x3e, 0x3c, 0x2f, 0x48, - 0x45, 0x41, 0x44, 0x3e, 0x0a, 0x3c, 0x42, 0x4f, - 0x44, 0x59, 0x20, 0x42, 0x47, 0x43, 0x4f, 0x4c, - 0x4f, 0x52, 0x3d, 0x22, 0x23, 0x63, 0x63, 0x39, - 0x39, 0x39, 0x39, 0x22, 0x3e, 0x3c, 0x48, 0x34, - 0x3e, 0x34, 0x30, 0x31, 0x20, 0x55, 0x6e, 0x61, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, - 0x64, 0x3c, 0x2f, 0x48, 0x34, 0x3e, 0x0a, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x64, 0x2e, 0x0a, 0x3c, - 0x48, 0x52, 0x3e, 0x0a, 0x3c, 0x41, 0x44, 0x44, - 0x52, 0x45, 0x53, 0x53, 0x3e, 0x3c, 0x41, 0x20, - 0x48, 0x52, 0x45, 0x46, 0x3d, 0x22, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, - 0x72, 0x65, 0x2f, 0x6d, 0x69, 0x63, 0x72, 0x6f, - 0x5f, 0x68, 0x74, 0x74, 0x70, 0x64, 0x2f, 0x22, - 0x3e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x5f, 0x68, - 0x74, 0x74, 0x70, 0x64, 0x3c, 0x2f, 0x41, 0x3e, - 0x3c, 0x2f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, - 0x53, 0x3e, 0x0a, 0x3c, 0x2f, 0x42, 0x4f, 0x44, - 0x59, 0x3e, 0x3c, 0x2f, 0x48, 0x54, 0x4d, 0x4c, - 0x3e, 0x0a - }; - - uint8_t pkt7[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x29, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6c, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x83, 0x94, 0x21, 0x04, 0x8d, 0x8e, 0x80, 0x10, - 0x00, 0x36, 0x59, 0xfa, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0x9c, 0x01, 0x29, - 0x23, 0x6a - }; - - uint8_t pkt8[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xa8, 0xbf, 0x40, 0x00, 0x40, 0x06, - 0x0d, 0xd7, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8d, 0x8e, 0x17, 0x51, 0x83, 0x94, 0x80, 0x11, - 0x00, 0x2d, 0x5a, 0x0b, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x23, 0x6a, 0x01, 0x72, - 0x40, 0x93 - }; - - uint8_t pkt9[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x2a, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6b, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x83, 0x94, 0x21, 0x04, 0x8d, 0x8f, 0x80, 0x10, - 0x00, 0x36, 0x59, 0xef, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x40, 0xa6, 0x01, 0x29, - 0x23, 0x6a - }; - - uint8_t pkt10[] = { - 0x00, 0x1a, 0x2b, 0x19, 0x52, 0xa8, 0x00, 0x13, - 0x20, 0x65, 0x1a, 0x9e, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0xc2, 0x2b, 0x40, 0x00, 0x40, 0x06, - 0xf4, 0x6a, 0xc0, 0xa8, 0x01, 0xdc, 0xc0, 0xa8, - 0x01, 0x01, 0xe7, 0xf5, 0x00, 0x50, 0x17, 0x51, - 0x83, 0x94, 0x21, 0x04, 0x8d, 0x8f, 0x80, 0x11, - 0x00, 0x36, 0x57, 0x0a, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x72, 0x43, 0x8a, 0x01, 0x29, - 0x23, 0x6a - }; - - uint8_t pkt11[] = { - 0x00, 0x13, 0x20, 0x65, 0x1a, 0x9e, 0x00, 0x1a, - 0x2b, 0x19, 0x52, 0xa8, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x34, 0x10, 0xaf, 0x40, 0x00, 0x40, 0x06, - 0xa5, 0xe7, 0xc0, 0xa8, 0x01, 0x01, 0xc0, 0xa8, - 0x01, 0xdc, 0x00, 0x50, 0xe7, 0xf5, 0x21, 0x04, - 0x8d, 0x8f, 0x17, 0x51, 0x83, 0x95, 0x80, 0x10, - 0x00, 0x2d, 0x54, 0xbb, 0x00, 0x00, 0x01, 0x01, - 0x08, 0x0a, 0x01, 0x29, 0x25, 0xc2, 0x01, 0x72, - 0x43, 0x8a - }; - - uint8_t *pkts[] = { - pkt1, pkt2, pkt3, pkt4, pkt5, pkt6, pkt7, pkt8, - pkt9, pkt10, pkt11 - }; - - uint16_t pktssizes[] = { - sizeof(pkt1), sizeof(pkt2), sizeof(pkt3), sizeof(pkt4), sizeof(pkt5), - sizeof(pkt6), sizeof(pkt7), sizeof(pkt8), sizeof(pkt9), sizeof(pkt10), - sizeof(pkt11) - }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - DecodeThreadVars dtv; - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - FlowInitConfig(FLOW_QUIET); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - /* Now that we have the array of packets for the flow, prepare the signatures */ - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"check notset\"; content:\"GET\"; flowint: myvar, notset; flowint: myvar,=,0; flowint: other,=,10; sid:101;)"); - - de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"check isset\"; content:\"Unauthorized\"; flowint:myvar,isset; flowint: other,isset; sid:102;)"); - - de_ctx->sig_list->next->next = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"check notset\"; content:\"Unauthorized\"; flowint:lala,isset; sid:103;)"); - - de_ctx->sig_list->next->next->next = NULL; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v,(void *) de_ctx,(void *) &det_ctx); - - int i; - - /* Decode the packets, and test the matches*/ - for (i = 0;i < 11;i++) { - memset(p, 0, SIZE_OF_PACKET); - PACKET_INITIALIZE(p); - DecodeEthernet(&th_v, &dtv, p, pkts[i], pktssizes[i], NULL); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - switch(i) { - case 3: - if (PacketAlertCheck(p, 101) == 0) { - SCLogDebug("Not declared/initialized but match!"); - result = 0; - } - if (PacketAlertCheck(p, 103) != 0) { - SCLogDebug(" var lala is never set, it should NOT match!!"); - result = 0; - } - break; - case 5: - if (PacketAlertCheck(p, 102) == 0) { - SCLogDebug("Not incremented!"); - result = 0; - } - - if (PacketAlertCheck(p, 103) != 0) { - SCLogDebug(" var lala is never set, it should NOT match!!"); - result = 0; - } - break; - } - SCLogDebug("Raw Packet %d has %u alerts ", i, p->alerts.cnt); - PACKET_RECYCLE(p); - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v,(void *) det_ctx); - //PatternMatchDestroy(mpm_ctx); - DetectEngineCtxFree(de_ctx); - FlowShutdown(); - - SCFree(p); - return result; - -end: - if (de_ctx) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - if (det_ctx) - DetectEngineThreadCtxDeinit(&th_v,(void *) det_ctx); - //PatternMatchDestroy(mpm_ctx); - if (de_ctx) - DetectEngineCtxFree(de_ctx); - - FlowShutdown(); - SCFree(p); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectFlowint - */ -void DetectFlowintRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectFlowintTestParseVal01", - DetectFlowintTestParseVal01, 1); - UtRegisterTest("DetectFlowintTestParseVar01", - DetectFlowintTestParseVar01, 1); - UtRegisterTest("DetectFlowintTestParseVal02", - DetectFlowintTestParseVal02, 1); - UtRegisterTest("DetectFlowintTestParseVar02", - DetectFlowintTestParseVar02, 1); - UtRegisterTest("DetectFlowintTestParseVal03", - DetectFlowintTestParseVal03, 1); - UtRegisterTest("DetectFlowintTestParseVar03", - DetectFlowintTestParseVar03, 1); - UtRegisterTest("DetectFlowintTestParseVal04", - DetectFlowintTestParseVal04, 1); - UtRegisterTest("DetectFlowintTestParseVar04", - DetectFlowintTestParseVar04, 1); - UtRegisterTest("DetectFlowintTestParseVal05", - DetectFlowintTestParseVal05, 1); - UtRegisterTest("DetectFlowintTestParseVar05", - DetectFlowintTestParseVar05, 1); - UtRegisterTest("DetectFlowintTestParseVal06", - DetectFlowintTestParseVal06, 1); - UtRegisterTest("DetectFlowintTestParseVar06", - DetectFlowintTestParseVar06, 1); - UtRegisterTest("DetectFlowintTestParseVal07", - DetectFlowintTestParseVal07, 1); - UtRegisterTest("DetectFlowintTestParseVar07", - DetectFlowintTestParseVar07, 1); - UtRegisterTest("DetectFlowintTestParseVal08", - DetectFlowintTestParseVal08, 1); - UtRegisterTest("DetectFlowintTestParseVar08", - DetectFlowintTestParseVar08, 1); - UtRegisterTest("DetectFlowintTestParseVal09", - DetectFlowintTestParseVal09, 1); - UtRegisterTest("DetectFlowintTestParseVar09", - DetectFlowintTestParseVar09, 1); - UtRegisterTest("DetectFlowintTestParseIsset10", - DetectFlowintTestParseIsset10, 1); - UtRegisterTest("DetectFlowintTestParseInvalidSyntaxis01", - DetectFlowintTestParseInvalidSyntaxis01, 1); - UtRegisterTest("DetectFlowintTestPacket01Real", - DetectFlowintTestPacket01Real, 1); - UtRegisterTest("DetectFlowintTestPacket02Real", - DetectFlowintTestPacket02Real, 1); - UtRegisterTest("DetectFlowintTestPacket03Real", - DetectFlowintTestPacket03Real, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-flowint.h b/framework/src/suricata/src/detect-flowint.h deleted file mode 100644 index 9a18efd5..00000000 --- a/framework/src/suricata/src/detect-flowint.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_FLOWINT_H__ -#define __DETECT_FLOWINT_H__ - -/** Flowint operations allowed */ -enum { - /** Changing integer values */ - FLOWINT_MODIFIER_SET, - FLOWINT_MODIFIER_ADD, - FLOWINT_MODIFIER_SUB, - - /** Comparing integer values */ - FLOWINT_MODIFIER_LT, - FLOWINT_MODIFIER_LE, - FLOWINT_MODIFIER_EQ, - FLOWINT_MODIFIER_NE, - FLOWINT_MODIFIER_GE, - FLOWINT_MODIFIER_GT, - /** Checking if a var is set (keyword isset/notset)*/ - FLOWINT_MODIFIER_ISSET, - FLOWINT_MODIFIER_NOTSET, - - FLOWINT_MODIFIER_UNKNOWN -}; - -/** The target can be a value, or another variable arleady declared */ -enum { - FLOWINT_TARGET_VAL, - FLOWINT_TARGET_VAR, - FLOWINT_TARGET_SELF, - FLOWINT_TARGET_UNKNOWN -}; - -/** If the target is another var, get the name and the idx */ -typedef struct TargetVar_ { - char *name; -} TargetVar; - -/** Context data for flowint vars */ -typedef struct DetectFlowintData_ { - /* This is the main var we are going to use - * against the target */ - char *name; - /* Internal id of the var */ - uint16_t idx; - - /* The modifier/operation/condition we are - * going to execute */ - uint8_t modifier; - uint8_t targettype; - - union { - /* the target value */ - uint32_t value; - /* or the target var */ - TargetVar tvar; - } target; -} DetectFlowintData; - -/* prototypes */ -void DetectFlowintRegister (void); - -#endif /* __DETECT_FLOWINT_H__ */ - diff --git a/framework/src/suricata/src/detect-flowvar.c b/framework/src/suricata/src/detect-flowvar.c deleted file mode 100644 index f6ff82d6..00000000 --- a/framework/src/suricata/src/detect-flowvar.c +++ /dev/null @@ -1,357 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Simple flowvar content match part of the detection engine. - */ - -#include "suricata-common.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-content.h" -#include "threads.h" -#include "flow.h" -#include "flow-var.h" -#include "detect-flowvar.h" - -#include "util-spm.h" -#include "util-var-name.h" -#include "util-debug.h" -#include "util-print.h" - -#define PARSE_REGEX "(.*),(.*)" -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectFlowvarMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectFlowvarSetup (DetectEngineCtx *, Signature *, char *); -static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx); -static void DetectFlowvarDataFree(void *ptr); - -void DetectFlowvarRegister (void) -{ - sigmatch_table[DETECT_FLOWVAR].name = "flowvar"; - sigmatch_table[DETECT_FLOWVAR].Match = DetectFlowvarMatch; - sigmatch_table[DETECT_FLOWVAR].Setup = DetectFlowvarSetup; - sigmatch_table[DETECT_FLOWVAR].Free = DetectFlowvarDataFree; - sigmatch_table[DETECT_FLOWVAR].RegisterTests = NULL; - - /* post-match for flowvar storage */ - sigmatch_table[DETECT_FLOWVAR_POSTMATCH].name = "__flowvar__postmatch__"; - sigmatch_table[DETECT_FLOWVAR_POSTMATCH].Match = DetectFlowvarPostMatch; - sigmatch_table[DETECT_FLOWVAR_POSTMATCH].Setup = NULL; - sigmatch_table[DETECT_FLOWVAR_POSTMATCH].Free = DetectFlowvarDataFree; - sigmatch_table[DETECT_FLOWVAR_POSTMATCH].RegisterTests = NULL; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - return; -} - -/** - * \brief this function will SCFree memory associated with DetectFlowvarData - * - * \param cd pointer to DetectCotentData - */ -static void DetectFlowvarDataFree(void *ptr) -{ - if (ptr == NULL) - SCReturn; - - DetectFlowvarData *fd = (DetectFlowvarData *)ptr; - - if (fd->name) - SCFree(fd->name); - if (fd->content) - SCFree(fd->content); - - SCFree(fd); -} - -/* - * returns 0: no match - * 1: match - * -1: error - */ - -int DetectFlowvarMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - int ret = 0; - DetectFlowvarData *fd = (DetectFlowvarData *)ctx; - - /* we need a lock */ - FLOWLOCK_RDLOCK(p->flow); - - FlowVar *fv = FlowVarGet(p->flow, fd->idx); - if (fv != NULL) { - uint8_t *ptr = SpmSearch(fv->data.fv_str.value, - fv->data.fv_str.value_len, - fd->content, fd->content_len); - if (ptr != NULL) - ret = 1; - } - FLOWLOCK_UNLOCK(p->flow); - - return ret; -} - -static int DetectFlowvarSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectFlowvarData *fd = NULL; - SigMatch *sm = NULL; - char *varname = NULL, *varcontent = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *str_ptr; - uint8_t *content = NULL; - uint16_t contentlen = 0; - uint32_t contentflags = 0; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret != 3) { - SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for flowvar.", rawstr); - return -1; - } - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - return -1; - } - varname = (char *)str_ptr; - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - return -1; - } - varcontent = (char *)str_ptr; - - res = DetectContentDataParse("flowvar", varcontent, &content, &contentlen, &contentflags); - if (res == -1) - goto error; - - fd = SCMalloc(sizeof(DetectFlowvarData)); - if (unlikely(fd == NULL)) - goto error; - memset(fd, 0x00, sizeof(*fd)); - - fd->content = SCMalloc(contentlen); - if (unlikely(fd->content == NULL)) - goto error; - - memcpy(fd->content, content, contentlen); - fd->content_len = contentlen; - fd->flags = contentflags; - - fd->name = SCStrdup(varname); - if (unlikely(fd->name == NULL)) - goto error; - fd->idx = VariableNameGetIdx(de_ctx, varname, VAR_TYPE_FLOW_VAR); - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (unlikely(sm == NULL)) - goto error; - - sm->type = DETECT_FLOWVAR; - sm->ctx = (SigMatchCtx *)fd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - SCFree(content); - return 0; - -error: - if (fd != NULL) - DetectFlowvarDataFree(fd); - if (sm != NULL) - SCFree(sm); - if (content != NULL) - SCFree(content); - return -1; -} - - -/** \brief Store flowvar in det_ctx so we can exec it post-match */ -int DetectFlowvarStoreMatch(DetectEngineThreadCtx *det_ctx, uint16_t idx, - uint8_t *buffer, uint16_t len, int type) -{ - DetectFlowvarList *fs = det_ctx->flowvarlist; - - /* first check if we have had a previous match for this idx */ - for ( ; fs != NULL; fs = fs->next) { - if (fs->idx == idx) { - /* we're replacing the older store */ - SCFree(fs->buffer); - fs->buffer = NULL; - break; - } - } - - if (fs == NULL) { - fs = SCMalloc(sizeof(*fs)); - if (unlikely(fs == NULL)) - return -1; - - fs->idx = idx; - - fs->next = det_ctx->flowvarlist; - det_ctx->flowvarlist = fs; - } - - fs->len = len; - fs->type = type; - fs->buffer = buffer; - return 0; -} - -/** \brief Setup a post-match for flowvar storage - * We're piggyback riding the DetectFlowvarData struct - */ -int DetectFlowvarPostMatchSetup(Signature *s, uint16_t idx) -{ - SigMatch *sm = NULL; - DetectFlowvarData *fv = NULL; - - fv = SCMalloc(sizeof(DetectFlowvarData)); - if (unlikely(fv == NULL)) - goto error; - memset(fv, 0x00, sizeof(*fv)); - - /* we only need the idx */ - fv->idx = idx; - - sm = SigMatchAlloc(); - if (unlikely(sm == NULL)) - goto error; - - sm->type = DETECT_FLOWVAR_POSTMATCH; - sm->ctx = (SigMatchCtx *)fv; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_POSTMATCH); - return 0; -error: - if (fv != NULL) - DetectFlowvarDataFree(fv); - return -1; -} - -/** \internal - * \brief post-match func to store flowvars in the flow - * \param sm sigmatch containing the idx to store - * \retval 1 or -1 in case of error - */ -static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - DetectFlowvarList *fs, *prev; - const DetectFlowvarData *fd; - const int flow_locked = det_ctx->flow_locked; - - if (det_ctx->flowvarlist == NULL || p->flow == NULL) - return 1; - - fd = (const DetectFlowvarData *)ctx; - - prev = NULL; - fs = det_ctx->flowvarlist; - while (fs != NULL) { - if (fd->idx == fs->idx) { - SCLogDebug("adding to the flow %u:", fs->idx); - //PrintRawDataFp(stdout, fs->buffer, fs->len); - - if (flow_locked) - FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len); - else - FlowVarAddStr(p->flow, fs->idx, fs->buffer, fs->len); - /* memory at fs->buffer is now the responsibility of - * the flowvar code. */ - - if (fs == det_ctx->flowvarlist) { - det_ctx->flowvarlist = fs->next; - SCFree(fs); - fs = det_ctx->flowvarlist; - } else { - prev->next = fs->next; - SCFree(fs); - fs = prev->next; - } - } else { - prev = fs; - fs = fs->next; - } - } - return 1; -} - -/** \brief Handle flowvar candidate list in det_ctx: - * - clean up the list - * - enforce storage for type ALWAYS (luajit) - * Only called from DetectFlowvarProcessList() when flowvarlist is not NULL . - */ -void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f, const int flow_locked) -{ - DetectFlowvarList *next; - - do { - next = fs->next; - - if (fs->type == DETECT_FLOWVAR_TYPE_ALWAYS) { - BUG_ON(f == NULL); - SCLogDebug("adding to the flow %u:", fs->idx); - //PrintRawDataFp(stdout, fs->buffer, fs->len); - - if (flow_locked) - FlowVarAddStrNoLock(f, fs->idx, fs->buffer, fs->len); - else - FlowVarAddStr(f, fs->idx, fs->buffer, fs->len); - /* memory at fs->buffer is now the responsibility of - * the flowvar code. */ - } else - SCFree(fs->buffer); - SCFree(fs); - fs = next; - } while (fs != NULL); -} diff --git a/framework/src/suricata/src/detect-flowvar.h b/framework/src/suricata/src/detect-flowvar.h deleted file mode 100644 index 9e72a5bc..00000000 --- a/framework/src/suricata/src/detect-flowvar.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_FLOWVAR_H__ -#define __DETECT_FLOWVAR_H__ - -typedef struct DetectFlowvarData_ { - char *name; - uint16_t idx; - uint8_t *content; - uint8_t content_len; - uint8_t flags; -} DetectFlowvarData; - -/* prototypes */ -void DetectFlowvarRegister (void); - -int DetectFlowvarPostMatchSetup(Signature *s, uint16_t idx); -int DetectFlowvarStoreMatch(DetectEngineThreadCtx *, uint16_t, uint8_t *, uint16_t, int); - -/* For use only by DetectFlowvarProcessList() */ -void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f, const int flow_locked); -static inline void DetectFlowvarProcessList(DetectEngineThreadCtx *det_ctx, Flow *f) -{ - DetectFlowvarList *fs = det_ctx->flowvarlist; - const int flow_locked = det_ctx->flow_locked; - - SCLogDebug("det_ctx->flowvarlist %p", fs); - - if (fs != NULL) { - det_ctx->flowvarlist = NULL; - DetectFlowvarProcessListInternal(fs, f, flow_locked); - } -} - -#endif /* __DETECT_FLOWVAR_H__ */ diff --git a/framework/src/suricata/src/detect-fragbits.c b/framework/src/suricata/src/detect-fragbits.c deleted file mode 100644 index 7a564ba0..00000000 --- a/framework/src/suricata/src/detect-fragbits.c +++ /dev/null @@ -1,581 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * - * Implements fragbits keyword - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "flow-var.h" -#include "decode-events.h" -#include "app-layer.h" -#include "app-layer-detect-proto.h" - -#include "detect-fragbits.h" -#include "util-unittest.h" -#include "util-debug.h" - -#include "pkt-var.h" -#include "host.h" -#include "util-profiling.h" - -/** - * Regex - * fragbits: [!+*](MDR) - */ -#define PARSE_REGEX "^\\s*(?:([\\+\\*!]))?\\s*([MDR]+)" - -/** - * FragBits args[0] *(3) +(2) !(1) - * - */ - -#define MODIFIER_NOT 1 -#define MODIFIER_PLUS 2 -#define MODIFIER_ANY 3 - -#define FRAGBITS_HAVE_MF 0x01 -#define FRAGBITS_HAVE_DF 0x02 -#define FRAGBITS_HAVE_RF 0x04 - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -static int DetectFragBitsMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectFragBitsSetup (DetectEngineCtx *, Signature *, char *); -static void DetectFragBitsFree(void *); - -/** - * \brief Registration function for fragbits: keyword - */ - -void DetectFragBitsRegister (void) -{ - sigmatch_table[DETECT_FRAGBITS].name = "fragbits"; - sigmatch_table[DETECT_FRAGBITS].desc = "check if the fragmentation and reserved bits are set in the IP header"; - sigmatch_table[DETECT_FRAGBITS].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#Fragbits"; - sigmatch_table[DETECT_FRAGBITS].Match = DetectFragBitsMatch; - sigmatch_table[DETECT_FRAGBITS].Setup = DetectFragBitsSetup; - sigmatch_table[DETECT_FRAGBITS].Free = DetectFragBitsFree; - sigmatch_table[DETECT_FRAGBITS].RegisterTests = FragBitsRegisterTests; - - const char *eb; - int opts = 0; - int eo; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - -error: - return; - -} - -/** - * \internal - * \brief This function is used to match fragbits on a packet with those passed via fragbits: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param s pointer to the Signature - * \param m pointer to the sigmatch - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectFragBitsMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - int ret = 0; - uint16_t fragbits = 0; - const DetectFragBitsData *de = (const DetectFragBitsData *)ctx; - - if (!de || !PKT_IS_IPV4(p) || !p || PKT_IS_PSEUDOPKT(p)) - return ret; - - if(IPV4_GET_MF(p)) - fragbits |= FRAGBITS_HAVE_MF; - if(IPV4_GET_DF(p)) - fragbits |= FRAGBITS_HAVE_DF; - if(IPV4_GET_RF(p)) - fragbits |= FRAGBITS_HAVE_RF; - - switch(de->modifier) { - case MODIFIER_ANY: - if((fragbits & de->fragbits) > 0) - return 1; - return ret; - case MODIFIER_PLUS: - if(((fragbits & de->fragbits) == de->fragbits) && (((fragbits - de->fragbits) > 0))) - return 1; - return ret; - case MODIFIER_NOT: - if((fragbits & de->fragbits) != de->fragbits) - return 1; - return ret; - default: - if(fragbits == de->fragbits) - return 1; - } - - return ret; -} - -/** - * \internal - * \brief This function is used to parse fragbits options passed via fragbits: keyword - * - * \param rawstr Pointer to the user provided fragbits options - * - * \retval de pointer to DetectFragBitsData on success - * \retval NULL on failure - */ -static DetectFragBitsData *DetectFragBitsParse (char *rawstr) -{ - DetectFragBitsData *de = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, found = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *str_ptr = NULL; - char *args[2] = { NULL, NULL}; - char *ptr; - int i; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - - if (ret < 1) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr); - goto error; - } - - for (i = 0; i < (ret - 1); i++) { - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS,i + 1, &str_ptr); - - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - args[i] = (char *)str_ptr; - } - - if(args[1] == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "invalid value"); - goto error; - } - - de = SCMalloc(sizeof(DetectFragBitsData)); - if (unlikely(de == NULL)) - goto error; - - memset(de,0,sizeof(DetectFragBitsData)); - - /** First parse args[0] */ - - if(args[0]) { - - ptr = args[0]; - - while (*ptr != '\0') { - switch (*ptr) { - case '!': - de->modifier = MODIFIER_NOT; - break; - case '+': - de->modifier = MODIFIER_PLUS; - break; - case '*': - de->modifier = MODIFIER_ANY; - break; - } - ptr++; - } - - } - - /** Second parse first set of fragbits */ - - ptr = args[1]; - - while (*ptr != '\0') { - switch (*ptr) { - case 'M': - case 'm': - de->fragbits |= FRAGBITS_HAVE_MF; - found++; - break; - case 'D': - case 'd': - de->fragbits |= FRAGBITS_HAVE_DF; - found++; - break; - case 'R': - case 'r': - de->fragbits |= FRAGBITS_HAVE_RF; - found++; - break; - default: - found = 0; - break; - } - ptr++; - } - - if(found == 0) - goto error; - - for (i = 0; i < 2; i++) { - if (args[i] != NULL) - SCFree(args[i]); - } - return de; - -error: - for (i = 0; i < 2; i++) { - if (args[i] != NULL) - SCFree(args[i]); - } - if (de != NULL) - SCFree(de); - return NULL; -} - -/** - * \internal - * \brief this function is used to add the parsed fragbits into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param m pointer to the Current SigMatch - * \param rawstr pointer to the user provided fragbits options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFragBitsSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectFragBitsData *de = NULL; - SigMatch *sm = NULL; - - de = DetectFragBitsParse(rawstr); - if (de == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FRAGBITS; - sm->ctx = (SigMatchCtx *)de; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - return -1; -} - -/** - * \internal - * \brief this function will free memory associated with DetectFragBitsData - * - * \param de pointer to DetectFragBitsData - */ -static void DetectFragBitsFree(void *de_ptr) -{ - DetectFragBitsData *de = (DetectFragBitsData *)de_ptr; - if(de) SCFree(de); -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -/** - * \test FragBitsTestParse01 is a test for a valid fragbits value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int FragBitsTestParse01 (void) -{ - DetectFragBitsData *de = NULL; - de = DetectFragBitsParse("M"); - if (de && (de->fragbits == FRAGBITS_HAVE_MF) ) { - DetectFragBitsFree(de); - return 1; - } - - return 0; -} - -/** - * \test FragBitsTestParse02 is a test for an invalid fragbits value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int FragBitsTestParse02 (void) -{ - DetectFragBitsData *de = NULL; - de = DetectFragBitsParse("G"); - if (de) { - DetectFragBitsFree(de); - return 1; - } - - return 0; -} - -/** - * \test FragBitsTestParse03 test if DONT FRAG is set. Must return success - * - * \retval 1 on success - * \retval 0 on failure - */ -static int FragBitsTestParse03 (void) -{ - uint8_t raw_eth[] = { - 0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00, - 0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00, - 0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11, - 0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00, - 0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff, - 0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01, - 0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70, - 0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74, - 0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64, - 0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c, - 0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10, - 0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75, - 0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65, - 0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65, - 0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34, - 0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10, - 0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0, - 0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e, - 0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0, - 0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c, - 0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00, - 0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00, - 0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0, - 0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a, - 0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a, - 0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb, - 0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01, - 0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b, - 0x51}; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - IPV4Hdr ipv4h; - int ret = 0; - DetectFragBitsData *de = NULL; - SigMatch *sm = NULL; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - dtv.app_tctx = AppLayerGetCtxThread(&tv); - - p->ip4h = &ipv4h; - - FlowInitConfig(FLOW_QUIET); - - DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth), NULL); - - de = DetectFragBitsParse("D"); - - if (de == NULL || (de->fragbits != FRAGBITS_HAVE_DF)) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FRAGBITS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFragBitsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 1; - } - -error: - FlowShutdown(); - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test FragBitsTestParse04 test if DONT FRAG is not set. Must fails. - * - * \retval 1 on success - * \retval 0 on failure - */ -static int FragBitsTestParse04 (void) -{ - uint8_t raw_eth[] = { - 0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00, - 0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00, - 0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11, - 0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00, - 0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff, - 0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01, - 0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70, - 0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74, - 0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64, - 0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c, - 0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10, - 0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75, - 0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65, - 0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65, - 0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34, - 0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10, - 0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0, - 0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e, - 0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0, - 0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c, - 0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00, - 0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00, - 0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0, - 0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a, - 0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a, - 0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb, - 0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01, - 0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00, - 0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b, - 0x51}; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - IPV4Hdr ipv4h; - int ret = 0; - DetectFragBitsData *de = NULL; - SigMatch *sm = NULL; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&ipv4h, 0, sizeof(IPV4Hdr)); - dtv.app_tctx = AppLayerGetCtxThread(&tv); - - p->ip4h = &ipv4h; - - FlowInitConfig(FLOW_QUIET); - - DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth), NULL); - - - de = DetectFragBitsParse("!D"); - - if (de == NULL || (de->fragbits != FRAGBITS_HAVE_DF) || (de->modifier != MODIFIER_NOT)) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_FRAGBITS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectFragBitsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - if (de) SCFree(de); - if (sm) SCFree(sm); - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - return 0; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for FragBits - */ -void FragBitsRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("FragBitsTestParse01", FragBitsTestParse01, 1); - UtRegisterTest("FragBitsTestParse02", FragBitsTestParse02, 0); - UtRegisterTest("FragBitsTestParse03", FragBitsTestParse03, 1); - UtRegisterTest("FragBitsTestParse04", FragBitsTestParse04, 0); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-fragbits.h b/framework/src/suricata/src/detect-fragbits.h deleted file mode 100644 index 2fdf0323..00000000 --- a/framework/src/suricata/src/detect-fragbits.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - */ - -#ifndef __DETECT_FRAGBITS_H__ -#define __DETECT_FRAGBITS_H__ - -#include "decode-events.h" -#include "decode-ipv4.h" -#include "decode-tcp.h" - -/** - * \struct DetectFragBitsData_ - * DetectFragBitsData_ is used to store fragbits: input value - */ - -/** - * \typedef DetectFragBitsData - * A typedef for DetectFragBitsData_ - */ - -typedef struct DetectFragBitsData_ { - uint16_t fragbits; /**< TCP fragbits */ - uint8_t modifier; /**< !(1) +(2) *(3) modifiers */ -} DetectFragBitsData; - -/** - * Registration function for fragbits: keyword - */ - -void DetectFragBitsRegister (void); - -/** - * This function registers unit tests for FragBits - */ - -void FragBitsRegisterTests(void); - -#endif /*__DETECT_FRAGBITS_H__ */ diff --git a/framework/src/suricata/src/detect-fragoffset.c b/framework/src/suricata/src/detect-fragoffset.c deleted file mode 100644 index c887b7b9..00000000 --- a/framework/src/suricata/src/detect-fragoffset.c +++ /dev/null @@ -1,396 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * - * Implements fragoffset keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "decode-ipv4.h" -#include "decode-ipv6.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-fragoffset.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-debug.h" - -#define PARSE_REGEX "^\\s*(?:(<|>))?\\s*([0-9]+)" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectFragOffsetMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectFragOffsetSetup(DetectEngineCtx *, Signature *, char *); -void DetectFragOffsetRegisterTests(void); -void DetectFragOffsetFree(void *); - -/** - * \brief Registration function for fragoffset - */ -void DetectFragOffsetRegister (void) -{ - sigmatch_table[DETECT_FRAGOFFSET].name = "fragoffset"; - sigmatch_table[DETECT_FRAGOFFSET].desc = "match on specific decimal values of the IP fragment offset field"; - sigmatch_table[DETECT_FRAGOFFSET].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#Fragoffset"; - sigmatch_table[DETECT_FRAGOFFSET].Match = DetectFragOffsetMatch; - sigmatch_table[DETECT_FRAGOFFSET].Setup = DetectFragOffsetSetup; - sigmatch_table[DETECT_FRAGOFFSET].Free = DetectFragOffsetFree; - sigmatch_table[DETECT_FRAGOFFSET].RegisterTests = DetectFragOffsetRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE,"pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY,"pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -/** - * \brief This function is used to match fragoffset rule option set on a packet - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectFragOffsetData - * - * \retval 0 no match or frag is not set - * \retval 1 match - * - */ -int DetectFragOffsetMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - uint16_t frag = 0; - const DetectFragOffsetData *fragoff = (const DetectFragOffsetData *)ctx; - - if (PKT_IS_PSEUDOPKT(p)) - return 0; - - if (PKT_IS_IPV4(p)) { - frag = IPV4_GET_IPOFFSET(p); - } else if (PKT_IS_IPV6(p)) { - if(IPV6_EXTHDR_FH(p)) { - frag = IPV6_EXTHDR_GET_FH_OFFSET(p); - } else { - return 0; - } - } else { - SCLogDebug("No IPv4 or IPv6 packet"); - return 0; - } - - switch (fragoff->mode) { - case FRAG_LESS: - if (frag < fragoff->frag_off) return 1; - break; - case FRAG_MORE: - if (frag > fragoff->frag_off) return 1; - break; - default: - if (frag == fragoff->frag_off) return 1; - } - - return 0; -} - -/** - * \brief This function is used to parse fragoffset option passed via fragoffset: keyword - * - * \param fragoffsetstr Pointer to the user provided fragoffset options - * - * \retval fragoff pointer to DetectFragOffsetData on success - * \retval NULL on failure - */ -DetectFragOffsetData *DetectFragOffsetParse (char *fragoffsetstr) -{ - DetectFragOffsetData *fragoff = NULL; - char *substr[3] = {NULL, NULL, NULL}; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - int i; - const char *str_ptr; - char *mode = NULL; - - ret = pcre_exec(parse_regex, parse_regex_study, fragoffsetstr, strlen(fragoffsetstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH,"Parse error %s", fragoffsetstr); - goto error; - } - - for (i = 1; i < ret; i++) { - res = pcre_get_substring((char *)fragoffsetstr, ov, MAX_SUBSTRINGS, i, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_get_substring failed"); - goto error; - } - substr[i-1] = (char *)str_ptr; - } - - fragoff = SCMalloc(sizeof(DetectFragOffsetData)); - if (unlikely(fragoff == NULL)) - goto error; - - fragoff->frag_off = 0; - fragoff->mode = 0; - - mode = substr[0]; - - if(mode != NULL) { - - while(*mode != '\0') { - switch(*mode) { - case '>': - fragoff->mode = FRAG_MORE; - break; - case '<': - fragoff->mode = FRAG_LESS; - break; - } - mode++; - } - } - - if (ByteExtractStringUint16(&fragoff->frag_off, 10, 0, substr[1]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified frag offset %s is not " - "valid", substr[1]); - goto error; - } - - for (i = 0; i < 3; i++) { - if (substr[i] != NULL) SCFree(substr[i]); - } - - return fragoff; - -error: - for (i = 0; i < 3; i++) { - if (substr[i] != NULL) SCFree(substr[i]); - } - if (fragoff != NULL) DetectFragOffsetFree(fragoff); - return NULL; - -} - -/** - * \brief this function is used to add the parsed fragoffset data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param fragoffsetstr pointer to the user provided fragoffset option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectFragOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *fragoffsetstr) -{ - DetectFragOffsetData *fragoff = NULL; - SigMatch *sm = NULL; - - fragoff = DetectFragOffsetParse(fragoffsetstr); - if (fragoff == NULL) goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) goto error; - - sm->type = DETECT_FRAGOFFSET; - sm->ctx = (SigMatchCtx *)fragoff; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (fragoff != NULL) DetectFragOffsetFree(fragoff); - if (sm != NULL) SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectFragOffsetData - * - * \param ptr pointer to DetectFragOffsetData - */ -void DetectFragOffsetFree (void *ptr) -{ - DetectFragOffsetData *fragoff = (DetectFragOffsetData *)ptr; - SCFree(fragoff); -} - -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -/** - * \test DetectFragOffsetParseTest01 is a test for setting a valid fragoffset value - */ -int DetectFragOffsetParseTest01 (void) -{ - DetectFragOffsetData *fragoff = NULL; - fragoff = DetectFragOffsetParse("300"); - if (fragoff != NULL && fragoff->frag_off == 300) { - DetectFragOffsetFree(fragoff); - return 1; - } - return 0; -} - -/** - * \test DetectFragOffsetParseTest02 is a test for setting a valid fragoffset value - * with spaces all around - */ -int DetectFragOffsetParseTest02 (void) -{ - DetectFragOffsetData *fragoff = NULL; - fragoff = DetectFragOffsetParse(">300"); - if (fragoff != NULL && fragoff->frag_off == 300 && fragoff->mode == FRAG_MORE) { - DetectFragOffsetFree(fragoff); - return 1; - } - return 0; -} - -/** - * \test DetectFragOffsetParseTest03 is a test for setting an invalid fragoffset value - */ -int DetectFragOffsetParseTest03 (void) -{ - DetectFragOffsetData *fragoff = NULL; - fragoff = DetectFragOffsetParse("badc"); - if (fragoff != NULL) { - DetectFragOffsetFree(fragoff); - return 1; - } - return 0; -} - -/** - * \test DetectFragOffsetMatchTest01 is a test for checking the working of - * fragoffset keyword by creating 2 rules and matching a crafted packet - * against them. Only the first one shall trigger. - */ -int DetectFragOffsetMatchTest01 (void) -{ - int result = 0; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - IPV4Hdr ip4h; - - memset(p, 0, SIZE_OF_PACKET); - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(ThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->src.addr_data32[0] = 0x01020304; - p->dst.addr_data32[0] = 0x04030201; - - ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; - ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; - ip4h.ip_off = 0x2222; - p->ip4h = &ip4h; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert ip any any -> any any (fragoffset:546; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx, "alert ip any any -> any any (fragoffset:5000; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 0) { - printf("sid 1 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2)) { - printf("sid 2 alerted, but should not have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - FlowShutdown(); -end: - SCFree(p); - return result; - -} -#endif /* UNITTESTS */ - -void DetectFragOffsetRegisterTests (void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectFragOffsetParseTest01", DetectFragOffsetParseTest01, 1); - UtRegisterTest("DetectFragOffsetParseTest02", DetectFragOffsetParseTest02, 1); - UtRegisterTest("DetectFragOffsetParseTest03", DetectFragOffsetParseTest03, 0); - UtRegisterTest("DetectFragOffsetMatchTest01", DetectFragOffsetMatchTest01, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-fragoffset.h b/framework/src/suricata/src/detect-fragoffset.h deleted file mode 100644 index 5d22e920..00000000 --- a/framework/src/suricata/src/detect-fragoffset.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - */ - -#ifndef __DETECT_FRAGOFFSET_H__ -#define __DETECT_FRAGOFFSET_H__ - -#define FRAG_LESS 1 -#define FRAG_MORE 2 - -typedef struct DetectFragOffsetData_ { - uint16_t frag_off; - uint8_t mode; -} DetectFragOffsetData; - -/* prototypes */ -void DetectFragOffsetRegister(void); - -#endif /* __DETECT_FRAGOFFSET__ */ diff --git a/framework/src/suricata/src/detect-ftpbounce.c b/framework/src/suricata/src/detect-ftpbounce.c deleted file mode 100644 index 39e1c5a2..00000000 --- a/framework/src/suricata/src/detect-ftpbounce.c +++ /dev/null @@ -1,560 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * - * ftpbounce keyword, part of the detection engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-ftp.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" -#include "threads.h" -#include "detect-ftpbounce.h" -#include "stream-tcp.h" -#include "util-byte.h" - -int DetectFtpbounceMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, SigMatch *); -int DetectFtpbounceALMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t, void *, Signature *, SigMatch *); -static int DetectFtpbounceSetup(DetectEngineCtx *, Signature *, char *); -int DetectFtpbounceMatchArgs(uint8_t *payload, uint16_t payload_len, - uint32_t ip_orig, uint16_t offset); -void DetectFtpbounceRegisterTests(void); -void DetectFtpbounceFree(void *); - -/** - * \brief Registration function for ftpbounce: keyword - * \todo add support for no_stream and stream_only - */ -void DetectFtpbounceRegister(void) -{ - sigmatch_table[DETECT_FTPBOUNCE].name = "ftpbounce"; - sigmatch_table[DETECT_FTPBOUNCE].Setup = DetectFtpbounceSetup; - sigmatch_table[DETECT_FTPBOUNCE].Match = NULL; - sigmatch_table[DETECT_FTPBOUNCE].AppLayerMatch = DetectFtpbounceALMatch; - sigmatch_table[DETECT_FTPBOUNCE].alproto = ALPROTO_FTP; - sigmatch_table[DETECT_FTPBOUNCE].Free = NULL; - sigmatch_table[DETECT_FTPBOUNCE].RegisterTests = DetectFtpbounceRegisterTests; - sigmatch_table[DETECT_FTPBOUNCE].flags = SIGMATCH_NOOPT; - return; -} - -/** - * \brief This function is used to match ftpbounce attacks - * - * \param payload Payload of the PORT command - * \param payload_len Length of the payload - * \param ip_orig IP source to check the ftpbounce condition - * \param offset offset to the arguments of the PORT command - * - * \retval 1 if ftpbounce detected, 0 if not - */ -int DetectFtpbounceMatchArgs(uint8_t *payload, uint16_t payload_len, - uint32_t ip_orig, uint16_t offset) -{ - SCEnter(); - SCLogDebug("Checking ftpbounce condition"); - char *c = NULL; - uint16_t i = 0; - int octet = 0; - int octet_ascii_len = 0; - int noctet = 0; - uint32_t ip = 0; - /* PrintRawDataFp(stdout, payload, payload_len); */ - - if (payload_len < 7) { - /* we need at least a differet ip address - * in the format 1,2,3,4,x,y where x,y is the port - * in two byte representation so let's look at - * least for the IP octets in comma separated */ - return 0; - } - - if (offset + 7 >= payload_len) - return 0; - - c =(char*) payload; - if (c == NULL) { - SCLogDebug("No payload to check"); - return 0; - } - - i = offset; - /* Search for the first IP octect(Skips "PORT ") */ - while (i < payload_len && !isdigit((unsigned char)c[i])) i++; - - for (;i < payload_len && octet_ascii_len < 4 ;i++) { - if (isdigit((unsigned char)c[i])) { - octet =(c[i] - '0') + octet * 10; - octet_ascii_len++; - } else { - if (octet > 256) { - SCLogDebug("Octet not in ip format"); - return 0; - } - - if (isspace((unsigned char)c[i])) - while (i < payload_len && isspace((unsigned char)c[i]) ) i++; - - if (i < payload_len && c[i] == ',') { /* we have an octet */ - noctet++; - octet_ascii_len = 0; - ip =(ip << 8) + octet; - octet = 0; - } else { - SCLogDebug("Unrecognized character '%c'", c[i]); - return 0; - } - if (noctet == 4) { - /* Different IP than src, ftp bounce scan */ - ip = SCByteSwap32(ip); - - if (ip != ip_orig) { - SCLogDebug("Different ip, so Matched ip:%d <-> ip_orig:%d", - ip, ip_orig); - return 1; - } - SCLogDebug("Same ip, so no match here"); - return 0; - } - } - } - SCLogDebug("No match"); - return 0; -} - -/** - * \brief This function is used to check matches from the FTP App Layer Parser - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch but we don't use it since ftpbounce - * has no options - * \retval 0 no match - * \retval 1 match - */ -int DetectFtpbounceALMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, Signature *s, - SigMatch *m) -{ - SCEnter(); - FtpState *ftp_state =(FtpState *)state; - if (ftp_state == NULL) { - SCLogDebug("no ftp state, no match"); - SCReturnInt(0); - } - - int ret = 0; - - if (ftp_state->command == FTP_COMMAND_PORT) { - ret = DetectFtpbounceMatchArgs(ftp_state->port_line, - ftp_state->port_line_len, f->src.address.address_un_data32[0], - ftp_state->arg_offset); - } - - SCReturnInt(ret); -} - -/** - * \brief this function is used to add the parsed ftpbounce - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param m pointer to the Current SigMatch - * \param ftpbouncestr pointer to the user provided ftpbounce options - * currently there are no options. - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectFtpbounceSetup(DetectEngineCtx *de_ctx, Signature *s, char *ftpbouncestr) -{ - SCEnter(); - - SigMatch *sm = NULL; - - sm = SigMatchAlloc(); - if (sm == NULL) { - goto error;; - } - - sm->type = DETECT_FTPBOUNCE; - - /* We don't need to allocate any data for ftpbounce here. - * - * TODO: As a suggestion, maybe we can add a flag in the flow - * to set the stream as "bounce detected" for fast Match. - * When you do a ftp bounce attack you usually use the same - * communication control stream to "setup" various destinations - * whithout breaking the connection, so I guess we can make it a bit faster - * with a flow flag set lookup in the Match function. - */ - sm->ctx = NULL; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_FTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - s->alproto = ALPROTO_FTP; - s->flags |= SIG_FLAG_APPLAYER; - SCReturnInt(0); - -error: - if (sm != NULL) { - SigMatchFree(sm); - } - SCReturnInt(-1); -} - -#ifdef UNITTESTS - -/** - * \test DetectFtpbounceTestSetup01 is a test for the Setup ftpbounce - */ -int DetectFtpbounceTestSetup01(void) -{ - int res = 0; - DetectEngineCtx *de_ctx = NULL; - Signature *s = SigAlloc(); - if (s == NULL) - return 0; - - /* ftpbounce doesn't accept options so the str is NULL */ - res = !DetectFtpbounceSetup(de_ctx, s, NULL); - res &= s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL && s->sm_lists[DETECT_SM_LIST_AMATCH]->type & DETECT_FTPBOUNCE; - - SigFree(s); - return res; -} - -#include "stream-tcp-reassemble.h" - -/** - * \test Check the ftpbounce match, send a get request in three chunks - * + more data. - * \brief This test tests the ftpbounce condition match, based on the - * ftp layer parser - */ -static int DetectFtpbounceTestALMatch02(void) -{ - int result = 0; - - uint8_t ftpbuf1[] = { 'P','O' }; - uint32_t ftplen1 = sizeof(ftpbuf1); - uint8_t ftpbuf2[] = { 'R', 'T' }; - uint32_t ftplen2 = sizeof(ftpbuf2); - uint8_t ftpbuf3[] = { ' ', '8','0',',','5' }; - uint32_t ftplen3 = sizeof(ftpbuf3); - uint8_t ftpbuf4[] = "8,0,33,10,20\r\n"; - uint32_t ftplen4 = sizeof(ftpbuf4); - - TcpSession ssn; - Flow f; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacketSrcDst(NULL, 0, IPPROTO_TCP, "1.2.3.4", "5.6.7.8"); - - FLOW_INITIALIZE(&f); - f.src.address.address_un_data32[0]=0x01020304; - f.protoctx =(void *)&ssn; - f.proto = IPPROTO_TCP; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_FTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any " - "(msg:\"Ftp Bounce\"; ftpbounce; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v,(void *)de_ctx,(void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER, ftpbuf1, ftplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf2, ftplen2); - if (r != 0) { - SCLogDebug("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf3, ftplen3); - if (r != 0) { - SCLogDebug("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf4, ftplen4); - if (r != 0) { - SCLogDebug("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - SCMutexUnlock(&f.m); - - FtpState *ftp_state = f.alstate; - if (ftp_state == NULL) { - SCLogDebug("no ftp state: "); - result = 0; - goto end; - } - - if (ftp_state->command != FTP_COMMAND_PORT) { - SCLogDebug("expected command port not detected"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v,(void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Check the ftpbounce match - * \brief This test tests the ftpbounce condition match, based on - * the ftp layer parser - */ -static int DetectFtpbounceTestALMatch03(void) -{ - int result = 0; - - uint8_t ftpbuf1[] = { 'P','O' }; - uint32_t ftplen1 = sizeof(ftpbuf1); - uint8_t ftpbuf2[] = { 'R', 'T' }; - uint32_t ftplen2 = sizeof(ftpbuf2); - uint8_t ftpbuf3[] = { ' ', '1',',','2',',' }; - uint32_t ftplen3 = sizeof(ftpbuf3); - uint8_t ftpbuf4[] = "3,4,10,20\r\n"; - uint32_t ftplen4 = sizeof(ftpbuf4); - - TcpSession ssn; - Flow f; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->src.addr_data32[0] = 0x04030201; - p->payload = NULL; - p->payload_len = 0; - p->proto = IPPROTO_TCP; - - FLOW_INITIALIZE(&f); - f.src.address.address_un_data32[0]=0x04030201; - f.protoctx =(void *)&ssn; - f.proto = IPPROTO_TCP; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_FTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any " - "(msg:\"Ftp Bounce\"; ftpbounce; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v,(void *)de_ctx,(void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_FTP, STREAM_TOSERVER, ftpbuf1, ftplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf2, ftplen2); - if (r != 0) { - SCLogDebug("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf3, ftplen3); - if (r != 0) { - SCLogDebug("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f,ALPROTO_FTP, STREAM_TOSERVER, ftpbuf4, ftplen4); - if (r != 0) { - SCLogDebug("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - FtpState *ftp_state = f.alstate; - if (ftp_state == NULL) { - SCLogDebug("no ftp state: "); - result = 0; - goto end; - } - - if (ftp_state->command != FTP_COMMAND_PORT) { - SCLogDebug("expected command port not detected"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* It should not match */ - if (!(PacketAlertCheck(p, 1))) { - result = 1; - } else { - SCLogDebug("It should not match here!"); - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v,(void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - SCFree(p); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectFtpbounce - */ -void DetectFtpbounceRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectFtpbounceTestSetup01", DetectFtpbounceTestSetup01, 1); - UtRegisterTest("DetectFtpbounceTestALMatch02", - DetectFtpbounceTestALMatch02, 1); - UtRegisterTest("DetectFtpbounceTestALMatch03", - DetectFtpbounceTestALMatch03, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-ftpbounce.h b/framework/src/suricata/src/detect-ftpbounce.h deleted file mode 100644 index f9cdfe39..00000000 --- a/framework/src/suricata/src/detect-ftpbounce.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_FTPBOUNCE_H__ -#define __DETECT_FTPBOUNCE_H__ - -/* prototypes */ -void DetectFtpbounceRegister (void); - -#endif /* __DETECT_FTPBOUNCE_H__ */ - diff --git a/framework/src/suricata/src/detect-geoip.c b/framework/src/suricata/src/detect-geoip.c deleted file mode 100644 index 53c950f8..00000000 --- a/framework/src/suricata/src/detect-geoip.c +++ /dev/null @@ -1,618 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ignacio Sanchez - * - * Implements the geoip keyword. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "detect-geoip.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#ifndef HAVE_GEOIP - -static int DetectGeoipSetupNoSupport (DetectEngineCtx *a, Signature *b, char *c) -{ - SCLogError(SC_ERR_NO_GEOIP_SUPPORT, "no GeoIP support built in, needed for geoip keyword"); - return -1; -} - -/** - * \brief Registration function for geoip keyword (no libgeoip support) - * \todo add support for src_only and dst_only - */ -void DetectGeoipRegister(void) -{ - sigmatch_table[DETECT_GEOIP].name = "geoip"; - sigmatch_table[DETECT_GEOIP].Setup = DetectGeoipSetupNoSupport; - sigmatch_table[DETECT_GEOIP].Free = NULL; - sigmatch_table[DETECT_GEOIP].RegisterTests = NULL; -} - -#else /* HAVE_GEOIP */ - -#include - - -static int DetectGeoipMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectGeoipSetup(DetectEngineCtx *, Signature *, char *); -static void DetectGeoipRegisterTests(void); -static void DetectGeoipDataFree(void *); - -/** - * \brief Registration function for geoip keyword - * \todo add support for src_only and dst_only - */ -void DetectGeoipRegister(void) -{ - sigmatch_table[DETECT_GEOIP].name = "geoip"; - sigmatch_table[DETECT_GEOIP].Match = DetectGeoipMatch; - sigmatch_table[DETECT_GEOIP].Setup = DetectGeoipSetup; - sigmatch_table[DETECT_GEOIP].Free = DetectGeoipDataFree; - sigmatch_table[DETECT_GEOIP].RegisterTests = DetectGeoipRegisterTests; -} - -/** - * \internal - * \brief This function is used to initialize the geolocation MaxMind engine - * - * \retval NULL if the engine couldn't be initialized - * \retval (GeoIP *) to the geolocation engine - */ -static GeoIP *InitGeolocationEngine(void) -{ - return GeoIP_new(GEOIP_MEMORY_CACHE); -} - -/** - * \internal - * \brief This function is used to geolocate the IP using the MaxMind libraries - * - * \param ip IP to geolocate (uint32_t ip) - * - * \retval NULL if it couldn't be geolocated - * \retval ptr (const char *) to the country code string - */ -static const char *GeolocateIPv4(GeoIP *geoengine, uint32_t ip) -{ - if (geoengine != NULL) - return GeoIP_country_code_by_ipnum(geoengine, ntohl(ip)); - return NULL; -} - -/* Match-on conditions supported */ -#define GEOIP_MATCH_SRC_STR "src" -#define GEOIP_MATCH_DST_STR "dst" -#define GEOIP_MATCH_BOTH_STR "both" -#define GEOIP_MATCH_ANY_STR "any" - -#define GEOIP_MATCH_NO_FLAG 0 -#define GEOIP_MATCH_SRC_FLAG 1 -#define GEOIP_MATCH_DST_FLAG 2 -#define GEOIP_MATCH_ANY_FLAG 3 /* default src and dst*/ -#define GEOIP_MATCH_BOTH_FLAG 4 -#define GEOIP_MATCH_NEGATED 8 - -/** - * \internal - * \brief This function is used to geolocate the IP using the MaxMind libraries - * - * \param ip IP to geolocate (uint32_t ip) - * - * \retval 0 no match - * \retval 1 match - */ -static int CheckGeoMatchIPv4(const DetectGeoipData *geoipdata, uint32_t ip) -{ - const char *country; - int i; - country = GeolocateIPv4(geoipdata->geoengine, ip); - /* Check if NOT NEGATED match-on condition */ - if ((geoipdata->flags & GEOIP_MATCH_NEGATED) == 0) - { - for (i = 0; i < geoipdata->nlocations; i++) - if (country != NULL && strcmp(country, (char *)geoipdata->location[i])==0) - return 1; - } else { - /* Check if NEGATED match-on condition */ - for (i = 0; i < geoipdata->nlocations; i++) - if (country != NULL && strcmp(country, (char *)geoipdata->location[i])==0) - return 0; /* if one matches, rule does NOT match (negated) */ - return 1; /* returns 1 if no location matches (negated) */ - } - return 0; -} - -/** - * \internal - * \brief This function is used to match packets with a IPs in an specified country - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectGeoipData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectGeoipMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectGeoipData *geoipdata = (const DetectGeoipData *)ctx; - int matches = 0; - - if (PKT_IS_PSEUDOPKT(p)) - return 0; - - if (PKT_IS_IPV4(p)) - { - if (geoipdata->flags & ( GEOIP_MATCH_SRC_FLAG | GEOIP_MATCH_BOTH_FLAG )) - { - if (CheckGeoMatchIPv4(geoipdata, GET_IPV4_SRC_ADDR_U32(p))) - { - if (geoipdata->flags & GEOIP_MATCH_BOTH_FLAG) - matches++; - else - return 1; - } - } - if (geoipdata->flags & ( GEOIP_MATCH_DST_FLAG | GEOIP_MATCH_BOTH_FLAG )) - { - if (CheckGeoMatchIPv4(geoipdata, GET_IPV4_DST_ADDR_U32(p))) - { - if (geoipdata->flags & GEOIP_MATCH_BOTH_FLAG) - matches++; - else - return 1; - } - } - /* if matches == 2 is because match-on is "both" */ - if (matches == 2) - return 1; - } - - return 0; -} - -/** - * \brief This function is used to parse geoipdata - * - * \param str Pointer to the geoipdata value string - * - * \retval pointer to DetectGeoipData on success - * \retval NULL on failure - */ -static DetectGeoipData *DetectGeoipDataParse (char *str) -{ - DetectGeoipData *geoipdata = NULL; - uint16_t pos = 0; - uint16_t prevpos = 0; - uint16_t slen = 0; - int skiplocationparsing = 0; - - slen = strlen(str); - if (slen == 0) - goto error; - - /* We have a correct geoip options string */ - geoipdata = SCMalloc(sizeof(DetectGeoipData)); - if (unlikely(geoipdata == NULL)) - goto error; - - memset(geoipdata, 0x00, sizeof(DetectGeoipData)); - - /* Parse the geoip option string */ - while (pos <= slen) - { - /* search for ',' or end of string */ - if (str[pos] == ',' || pos == slen) - { - if (geoipdata->flags == GEOIP_MATCH_NO_FLAG) - { - /* Parse match-on condition */ - if (pos == slen) /* if end of option str then there are no match-on cond. */ - { - /* There was NO match-on condition! we default to ANY*/ - skiplocationparsing = 0; - geoipdata->flags |= GEOIP_MATCH_ANY_FLAG; - } else { - skiplocationparsing = 1; - if (strncmp(&str[prevpos], GEOIP_MATCH_SRC_STR, pos-prevpos) == 0) - geoipdata->flags |= GEOIP_MATCH_SRC_FLAG; - else if (strncmp(&str[prevpos], GEOIP_MATCH_DST_STR, pos-prevpos) == 0) - geoipdata->flags |= GEOIP_MATCH_DST_FLAG; - else if (strncmp(&str[prevpos], GEOIP_MATCH_BOTH_STR, pos-prevpos) == 0) - geoipdata->flags |= GEOIP_MATCH_BOTH_FLAG; - else if (strncmp(&str[prevpos], GEOIP_MATCH_ANY_STR, pos-prevpos) == 0) - geoipdata->flags |= GEOIP_MATCH_ANY_FLAG; - else { - /* There was NO match-on condition! we default to ANY*/ - skiplocationparsing = 0; - geoipdata->flags |= GEOIP_MATCH_ANY_FLAG; - } - } - } - if (geoipdata->flags != GEOIP_MATCH_NO_FLAG && skiplocationparsing == 0) - { - /* Parse location string: for now just the country code(s) */ - if (str[prevpos] == '!') - { - geoipdata->flags |= GEOIP_MATCH_NEGATED; - prevpos++; /* dot not copy the ! */ - } - - if (geoipdata->nlocations >= GEOOPTION_MAXLOCATIONS) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "too many arguements for geoip keyword"); - goto error; - } - - if (pos-prevpos > GEOOPTION_MAXSIZE) - strlcpy((char *)geoipdata->location[geoipdata->nlocations], &str[prevpos], - GEOOPTION_MAXSIZE); - else - strlcpy((char *)geoipdata->location[geoipdata->nlocations], &str[prevpos], - pos-prevpos+1); - - if (geoipdata->nlocations < GEOOPTION_MAXLOCATIONS) - geoipdata->nlocations++; - } - prevpos = pos+1; - skiplocationparsing = 0; /* match-on condition for sure has been parsed already */ - } - pos++; - } - - SCLogDebug("GeoIP: %"PRIu32" countries loaded", geoipdata->nlocations); - for (int i=0; inlocations; i++) - SCLogDebug("GeoIP country code: %s", geoipdata->location[i]); - - SCLogDebug("flags %02X", geoipdata->flags); - if (geoipdata->flags & GEOIP_MATCH_NEGATED) { - SCLogDebug("negated geoip"); - } - - /* Initialize the geolocation engine */ - geoipdata->geoengine = InitGeolocationEngine(); - if (geoipdata->geoengine == NULL) - goto error; - - return geoipdata; - -error: - if (geoipdata != NULL) - DetectGeoipDataFree(geoipdata); - return NULL; -} - -/** - * \internal - * \brief this function is used to add the geoip option into the signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param optstr pointer to the user provided options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectGeoipSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) -{ - DetectGeoipData *geoipdata = NULL; - SigMatch *sm = NULL; - - geoipdata = DetectGeoipDataParse(optstr); - if (geoipdata == NULL) - goto error; - - /* Get this into a SigMatch and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_GEOIP; - sm->ctx = (SigMatchCtx *)geoipdata; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (geoipdata != NULL) - DetectGeoipDataFree(geoipdata); - if (sm != NULL) - SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectGeoipData - * - * \param geoipdata pointer to DetectGeoipData - */ -static void DetectGeoipDataFree(void *ptr) -{ - if (ptr != NULL) { - DetectGeoipData *geoipdata = (DetectGeoipData *)ptr; - SCFree(geoipdata); - } -} - -#ifdef UNITTESTS - -static int GeoipParseTest(char *rule, int ncountries, char **countries, uint32_t flags) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectGeoipData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, rule); - - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_MATCH] == NULL) { - printf("empty server body list: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_MATCH]->type != DETECT_GEOIP) { - printf("last sm not geoip: "); - goto end; - } - - data = (DetectGeoipData *)s->sm_lists_tail[DETECT_SM_LIST_MATCH]->ctx; - if (data->flags != flags) { - printf("flags not right: (flags=%d)",data->flags); - goto end; - } - - if (data->nlocations!=ncountries) - { - printf("wrong number of parsed countries: "); - goto end; - } - - for (int i=0; ilocation[i],countries[i])!=0) - { - printf("wrong parsed country code: "); - goto end; - } - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -static int GeoipParseTest01(void) -{ - char *ccodes[1] = {"US"}; - return GeoipParseTest("alert tcp any any -> any any (geoip:US;sid:1;)", 1, ccodes, - GEOIP_MATCH_ANY_FLAG); -} - -static int GeoipParseTest02(void) -{ - char *ccodes[1] = {"US"}; - return GeoipParseTest("alert tcp any any -> any any (geoip:!US;sid:1;)", 1, ccodes, - GEOIP_MATCH_ANY_FLAG | GEOIP_MATCH_NEGATED); -} - -static int GeoipParseTest03(void) -{ - char *ccodes[1] = {"US"}; - return GeoipParseTest("alert tcp any any -> any any (geoip:!US;sid:1;)", 1, ccodes, - GEOIP_MATCH_ANY_FLAG | GEOIP_MATCH_NEGATED); -} - -static int GeoipParseTest04(void) -{ - char *ccodes[1] = {"US"}; - return GeoipParseTest("alert tcp any any -> any any (geoip:src,US;sid:1;)", 1, ccodes, - GEOIP_MATCH_SRC_FLAG); -} - -static int GeoipParseTest05(void) -{ - char *ccodes[1] = {"US"}; - return GeoipParseTest("alert tcp any any -> any any (geoip:dst,!US;sid:1;)", 1, ccodes, - GEOIP_MATCH_DST_FLAG | GEOIP_MATCH_NEGATED); -} - -static int GeoipParseTest06(void) -{ - char *ccodes[3] = {"US", "ES", "UK"}; - return GeoipParseTest("alert tcp any any -> any any (geoip:US,ES,UK;sid:1;)", 3, ccodes, - GEOIP_MATCH_ANY_FLAG); -} - -static int GeoipParseTest07(void) -{ - char *ccodes[3] = {"US", "ES", "UK"}; - return GeoipParseTest("alert tcp any any -> any any (geoip:both,!US,ES,UK;sid:1;)", 3, ccodes, - GEOIP_MATCH_BOTH_FLAG | GEOIP_MATCH_NEGATED); -} - -/** - * \internal - * \brief This test tests geoip success and failure. - */ -static int GeoipMatchTest(char *rule, char *srcip, char *dstip) -{ - uint8_t *buf = (uint8_t *) "GET / HTTP/1.0\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p1 = UTHBuildPacketSrcDst(buf, buflen, IPPROTO_TCP, srcip, dstip); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, rule); - - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - result = 2; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1) == 0) { - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - return result; -} - -static int GeoipMatchTest01(void) -{ - /* Tests with IP of google DNS as US for both src and dst IPs */ - return GeoipMatchTest("alert tcp any any -> any any (geoip:US;sid:1;)", "8.8.8.8", "8.8.8.8"); - /* Expected result 1 = match */ -} - -static int GeoipMatchTest02(void) -{ - /* Tests with IP of google DNS as US, and m.root-servers.net as japan */ - return GeoipMatchTest("alert tcp any any -> any any (geoip:JP;sid:1;)", "8.8.8.8", - "202.12.27.33"); - /* Expected result 1 = match */ -} - -static int GeoipMatchTest03(void) -{ - /* Tests with IP of google DNS as US, and m.root-servers.net as japan */ - return GeoipMatchTest("alert tcp any any -> any any (geoip:dst,JP;sid:1;)", - "8.8.8.8", "202.12.27.33"); - /* Expected result 1 = match */ -} - -static int GeoipMatchTest04(void) -{ - /* Tests with IP of google DNS as US, and m.root-servers.net as japan */ - return GeoipMatchTest("alert tcp any any -> any any (geoip:src,JP;sid:1;)", - "8.8.8.8", "202.12.27.33"); - /* Expected result 2 = NO match */ -} - -static int GeoipMatchTest05(void) -{ - /* Tests with IP of google DNS as US, and m.root-servers.net as japan */ - return GeoipMatchTest("alert tcp any any -> any any (geoip:src,JP,US;sid:1;)", - "8.8.8.8", "202.12.27.33"); - /* Expected result 1 = match */ -} - -static int GeoipMatchTest06(void) -{ - /* Tests with IP of google DNS as US, and m.root-servers.net as japan */ - return GeoipMatchTest("alert tcp any any -> any any (geoip:src,ES,JP,US,UK,PT;sid:1;)", - "8.8.8.8", "202.12.27.33"); - /* Expected result 1 = match */ -} - -static int GeoipMatchTest07(void) -{ - /* Tests with IP of google DNS as US, and m.root-servers.net as japan */ - return GeoipMatchTest("alert tcp any any -> any any (geoip:src,!ES,JP,US,UK,PT;sid:1;)", - "8.8.8.8", "202.12.27.33"); - /* Expected result 2 = NO match */ -} - - -#endif /* UNITTESTS */ - -/** - * \internal - * \brief This function registers unit tests for DetectGeoip - */ -static void DetectGeoipRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("GeoipParseTest01", GeoipParseTest01, 1); - UtRegisterTest("GeoipParseTest02", GeoipParseTest02, 1); - UtRegisterTest("GeoipParseTest03", GeoipParseTest03, 1); - UtRegisterTest("GeoipParseTest04", GeoipParseTest04, 1); - UtRegisterTest("GeoipParseTest05", GeoipParseTest05, 1); - UtRegisterTest("GeoipParseTest06", GeoipParseTest06, 1); - UtRegisterTest("GeoipParseTest07", GeoipParseTest07, 1); - - UtRegisterTest("GeoipMatchTest01", GeoipMatchTest01, 1); - UtRegisterTest("GeoipMatchTest02", GeoipMatchTest02, 1); - UtRegisterTest("GeoipMatchTest03", GeoipMatchTest03, 1); - UtRegisterTest("GeoipMatchTest04", GeoipMatchTest04, 2); - UtRegisterTest("GeoipMatchTest05", GeoipMatchTest05, 1); - UtRegisterTest("GeoipMatchTest06", GeoipMatchTest06, 1); - UtRegisterTest("GeoipMatchTest07", GeoipMatchTest07, 2); -#endif /* UNITTESTS */ -} - -#endif /* HAVE_GEOIP */ diff --git a/framework/src/suricata/src/detect-geoip.h b/framework/src/suricata/src/detect-geoip.h deleted file mode 100644 index 1bfc7aff..00000000 --- a/framework/src/suricata/src/detect-geoip.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ignacio Sanchez - */ - -#ifndef __DETECT_GEOIP_H__ -#define __DETECT_GEOIP_H__ - -#ifdef HAVE_GEOIP - -#include -#include "util-spm-bm.h" - -#define GEOOPTION_MAXSIZE 3 /* Country Code (2 chars) + NULL */ -#define GEOOPTION_MAXLOCATIONS 64 - -typedef struct DetectGeoipData_ { - uint8_t location[GEOOPTION_MAXLOCATIONS][GEOOPTION_MAXSIZE]; /** country code for now, null term.*/ - int nlocations; /** number of location strings parsed */ - uint32_t flags; - GeoIP *geoengine; -} DetectGeoipData; - -#endif - -void DetectGeoipRegister(void); - -#endif diff --git a/framework/src/suricata/src/detect-gid.c b/framework/src/suricata/src/detect-gid.c deleted file mode 100644 index f63ea28a..00000000 --- a/framework/src/suricata/src/detect-gid.c +++ /dev/null @@ -1,202 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * - * Implements the gid keyword - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "flow-var.h" -#include "decode-events.h" - -#include "detect-gid.h" -#include "util-unittest.h" -#include "util-debug.h" - -#define PARSE_REGEX "[0-9]+" - -static int DetectGidSetup (DetectEngineCtx *, Signature *, char *); - -/** - * \brief Registration function for gid: keyword - */ - -void DetectGidRegister (void) -{ - sigmatch_table[DETECT_GID].name = "gid"; - sigmatch_table[DETECT_GID].desc = "give different groups of signatures another id value"; - sigmatch_table[DETECT_GID].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Meta-settings#Gid-group-id"; - sigmatch_table[DETECT_GID].Match = NULL; - sigmatch_table[DETECT_GID].Setup = DetectGidSetup; - sigmatch_table[DETECT_GID].Free = NULL; - sigmatch_table[DETECT_GID].RegisterTests = GidRegisterTests; -} - -/** - * \internal - * \brief this function is used to add the parsed gid into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param rawstr pointer to the user provided gid options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectGidSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - char *str = rawstr; - char duped = 0; - - /* Strip leading and trailing "s. */ - if (rawstr[0] == '\"') { - str = SCStrdup(rawstr + 1); - if (unlikely(str == NULL)) { - return -1; - } - if (strlen(str) && str[strlen(str) - 1] == '\"') { - str[strlen(str) - 1] = '\"'; - } - duped = 1; - } - - unsigned long gid = 0; - char *endptr = NULL; - gid = strtoul(rawstr, &endptr, 10); - if (endptr == NULL || *endptr != '\0') { - SCLogError(SC_ERR_INVALID_SIGNATURE, "invalid character as arg " - "to gid keyword"); - goto error; - } - if (gid >= UINT_MAX) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "gid value to high, max %u", UINT_MAX); - goto error; - } - - s->gid = (uint32_t)gid; - - if (duped) - SCFree(str); - return 0; - - error: - if (duped) - SCFree(str); - return -1; -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -/** - * \test GidTestParse01 is a test for a valid gid value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int GidTestParse01 (void) -{ - int result = 0; - Signature *s = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - s = DetectEngineAppendSig(de_ctx, "alert tcp 1.2.3.4 any -> any any (sid:1; gid:1;)"); - if (s == NULL || s->gid != 1) - goto end; - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test GidTestParse02 is a test for an invalid gid value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int GidTestParse02 (void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (DetectEngineAppendSig(de_ctx, "alert tcp 1.2.3.4 any -> any any (sid:1; gid:a;)") != NULL) - goto end; - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Test a gid consisting of a single quote. - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int GidTestParse03 (void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (DetectEngineAppendSig(de_ctx, - "alert tcp any any -> any any (content:\"ABC\"; gid:\";)") != NULL) - goto end; - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for Gid - */ -void GidRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("GidTestParse01", GidTestParse01, 1); - UtRegisterTest("GidTestParse02", GidTestParse02, 1); - UtRegisterTest("GidTestParse03", GidTestParse03, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-gid.h b/framework/src/suricata/src/detect-gid.h deleted file mode 100644 index d98d6edc..00000000 --- a/framework/src/suricata/src/detect-gid.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * - * Implements the gid keyword - */ - -#ifndef __DETECT_GID_H__ -#define __DETECT_GID_H__ - -#include "decode-events.h" -#include "decode-ipv4.h" -#include "decode-tcp.h" - -/** - * Registration function for gid: keyword - */ - -void DetectGidRegister (void); - -/** - * This function registers unit tests for Gid - */ - -void GidRegisterTests(void); - -#endif /*__DETECT_GID_H__ */ diff --git a/framework/src/suricata/src/detect-hostbits.c b/framework/src/suricata/src/detect-hostbits.c deleted file mode 100644 index ad1fce57..00000000 --- a/framework/src/suricata/src/detect-hostbits.c +++ /dev/null @@ -1,1473 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the hostbits keyword - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "threads.h" -#include "flow.h" -#include "flow-util.h" -#include "detect-hostbits.h" -#include "util-spm.h" - -#include "detect-engine-sigorder.h" - -#include "app-layer-parser.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow-bit.h" -#include "host-bit.h" -#include "util-var-name.h" -#include "util-unittest.h" -#include "util-debug.h" - -/* - hostbits:isset,bitname; - hostbits:set,bitname; - - hostbits:set,bitname,src; - hostbits:set,bitname,dst; -TODO: - hostbits:set,bitname,both; - - hostbits:set,bitname,src,3600; - hostbits:set,bitname,dst,60; - hostbits:set,bitname,both,120; - */ - -#define PARSE_REGEX "([a-z]+)(?:\\s*,\\s*([^\\s,]+))?(?:\\s*,\\s*([^,\\s]+))?" -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectHostbitMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectHostbitSetup (DetectEngineCtx *, Signature *, char *); -void DetectHostbitFree (void *); -void HostBitsRegisterTests(void); - -void DetectHostbitsRegister (void) -{ - sigmatch_table[DETECT_HOSTBITS].name = "hostbits"; - sigmatch_table[DETECT_HOSTBITS].desc = "operate on host flag"; -// sigmatch_table[DETECT_HOSTBITS].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Flow-keywords#Flowbits"; - sigmatch_table[DETECT_HOSTBITS].Match = DetectHostbitMatch; - sigmatch_table[DETECT_HOSTBITS].Setup = DetectHostbitSetup; - sigmatch_table[DETECT_HOSTBITS].Free = DetectHostbitFree; - sigmatch_table[DETECT_HOSTBITS].RegisterTests = HostBitsRegisterTests; - /* this is compatible to ip-only signatures */ - sigmatch_table[DETECT_HOSTBITS].flags |= SIGMATCH_IPONLY_COMPAT; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - return; -} - -static int DetectHostbitMatchToggle (Packet *p, const DetectXbitsData *fd) -{ - switch (fd->tracker) { - case DETECT_XBITS_TRACK_IPSRC: - if (p->host_src == NULL) { - p->host_src = HostGetHostFromHash(&p->src); - if (p->host_src == NULL) - return 0; - } - else - HostLock(p->host_src); - - HostBitToggle(p->host_src,fd->idx,p->ts.tv_sec + fd->expire); - HostUnlock(p->host_src); - break; - case DETECT_XBITS_TRACK_IPDST: - if (p->host_dst == NULL) { - p->host_dst = HostGetHostFromHash(&p->dst); - if (p->host_dst == NULL) - return 0; - } - else - HostLock(p->host_dst); - - HostBitToggle(p->host_dst,fd->idx,p->ts.tv_sec + fd->expire); - HostUnlock(p->host_dst); - break; - } - return 1; -} - -/* return true even if bit not found */ -static int DetectHostbitMatchUnset (Packet *p, const DetectXbitsData *fd) -{ - switch (fd->tracker) { - case DETECT_XBITS_TRACK_IPSRC: - if (p->host_src == NULL) { - p->host_src = HostLookupHostFromHash(&p->src); - if (p->host_src == NULL) - return 1; - } else - HostLock(p->host_src); - - HostBitUnset(p->host_src,fd->idx); - HostUnlock(p->host_src); - break; - case DETECT_XBITS_TRACK_IPDST: - if (p->host_dst == NULL) { - p->host_dst = HostLookupHostFromHash(&p->dst); - if (p->host_dst == NULL) - return 1; - } else - HostLock(p->host_dst); - - HostBitUnset(p->host_dst,fd->idx); - HostUnlock(p->host_dst); - break; - } - return 1; -} - -static int DetectHostbitMatchSet (Packet *p, const DetectXbitsData *fd) -{ - switch (fd->tracker) { - case DETECT_XBITS_TRACK_IPSRC: - if (p->host_src == NULL) { - p->host_src = HostGetHostFromHash(&p->src); - if (p->host_src == NULL) - return 0; - } else - HostLock(p->host_src); - - HostBitSet(p->host_src,fd->idx,p->ts.tv_sec + fd->expire); - HostUnlock(p->host_src); - break; - case DETECT_XBITS_TRACK_IPDST: - if (p->host_dst == NULL) { - p->host_dst = HostGetHostFromHash(&p->dst); - if (p->host_dst == NULL) - return 0; - } else - HostLock(p->host_dst); - - HostBitSet(p->host_dst,fd->idx, p->ts.tv_sec + fd->expire); - HostUnlock(p->host_dst); - break; - } - return 1; -} - -static int DetectHostbitMatchIsset (Packet *p, const DetectXbitsData *fd) -{ - int r = 0; - switch (fd->tracker) { - case DETECT_XBITS_TRACK_IPSRC: - if (p->host_src == NULL) { - p->host_src = HostLookupHostFromHash(&p->src); - if (p->host_src == NULL) - return 0; - } else - HostLock(p->host_src); - - r = HostBitIsset(p->host_src,fd->idx, p->ts.tv_sec); - HostUnlock(p->host_src); - return r; - case DETECT_XBITS_TRACK_IPDST: - if (p->host_dst == NULL) { - p->host_dst = HostLookupHostFromHash(&p->dst); - if (p->host_dst == NULL) - return 0; - } else - HostLock(p->host_dst); - - r = HostBitIsset(p->host_dst,fd->idx, p->ts.tv_sec); - HostUnlock(p->host_dst); - return r; - } - return 0; -} - -static int DetectHostbitMatchIsnotset (Packet *p, const DetectXbitsData *fd) -{ - int r = 0; - switch (fd->tracker) { - case DETECT_XBITS_TRACK_IPSRC: - if (p->host_src == NULL) { - p->host_src = HostLookupHostFromHash(&p->src); - if (p->host_src == NULL) - return 1; - } else - HostLock(p->host_src); - - r = HostBitIsnotset(p->host_src,fd->idx, p->ts.tv_sec); - HostUnlock(p->host_src); - return r; - case DETECT_XBITS_TRACK_IPDST: - if (p->host_dst == NULL) { - p->host_dst = HostLookupHostFromHash(&p->dst); - if (p->host_dst == NULL) - return 1; - } else - HostLock(p->host_dst); - - r = HostBitIsnotset(p->host_dst,fd->idx, p->ts.tv_sec); - HostUnlock(p->host_dst); - return r; - } - return 0; -} - -int DetectXbitMatchHost(Packet *p, const DetectXbitsData *xd) -{ - switch (xd->cmd) { - case DETECT_XBITS_CMD_ISSET: - return DetectHostbitMatchIsset(p,xd); - case DETECT_XBITS_CMD_ISNOTSET: - return DetectHostbitMatchIsnotset(p,xd); - case DETECT_XBITS_CMD_SET: - return DetectHostbitMatchSet(p,xd); - case DETECT_XBITS_CMD_UNSET: - return DetectHostbitMatchUnset(p,xd); - case DETECT_XBITS_CMD_TOGGLE: - return DetectHostbitMatchToggle(p,xd); - default: - SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown cmd %" PRIu32 "", xd->cmd); - return 0; - } - - return 0; -} - -/* - * returns 0: no match - * 1: match - * -1: error - */ - -int DetectHostbitMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectXbitsData *xd = (const DetectXbitsData *)ctx; - if (xd == NULL) - return 0; - - return DetectXbitMatchHost(p, xd); -} - -static int DetectHostbitParse(const char *str, char *cmd, int cmd_len, - char *name, int name_len, char *dir, int dir_len) -{ - const int max_substrings = 30; - int count, rc; - int ov[max_substrings]; - - count = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, - ov, max_substrings); - if (count != 2 && count != 3 && count != 4) { - SCLogError(SC_ERR_PCRE_MATCH, - "\"%s\" is not a valid setting for hostbits.", str); - return 0; - } - - rc = pcre_copy_substring((char *)str, ov, max_substrings, 1, cmd, cmd_len); - if (rc < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return 0; - } - - if (count >= 3) { - rc = pcre_copy_substring((char *)str, ov, max_substrings, 2, name, - name_len); - if (rc < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return 0; - } - if (count >= 4) { - rc = pcre_copy_substring((char *)str, ov, max_substrings, 3, dir, - dir_len); - if (rc < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, - "pcre_copy_substring failed"); - return 0; - } - } - } - - return 1; -} - -int DetectHostbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectXbitsData *cd = NULL; - SigMatch *sm = NULL; - uint8_t fb_cmd = 0; - uint8_t hb_dir = 0; - char fb_cmd_str[16] = "", fb_name[256] = ""; - char hb_dir_str[16] = ""; - - if (!DetectHostbitParse(rawstr, fb_cmd_str, sizeof(fb_cmd_str), - fb_name, sizeof(fb_name), hb_dir_str, sizeof(hb_dir_str))) { - return -1; - } - - if (strlen(hb_dir_str) > 0) { - if (strcmp(hb_dir_str, "src") == 0) - hb_dir = DETECT_XBITS_TRACK_IPSRC; - else if (strcmp(hb_dir_str, "dst") == 0) - hb_dir = DETECT_XBITS_TRACK_IPDST; - else if (strcmp(hb_dir_str, "both") == 0) { - //hb_dir = DETECT_XBITS_TRACK_IPBOTH; - SCLogError(SC_ERR_UNIMPLEMENTED, "'both' not implemented"); - goto error; - } else { - // TODO - goto error; - } - } - - if (strcmp(fb_cmd_str,"noalert") == 0) { - fb_cmd = DETECT_XBITS_CMD_NOALERT; - } else if (strcmp(fb_cmd_str,"isset") == 0) { - fb_cmd = DETECT_XBITS_CMD_ISSET; - } else if (strcmp(fb_cmd_str,"isnotset") == 0) { - fb_cmd = DETECT_XBITS_CMD_ISNOTSET; - } else if (strcmp(fb_cmd_str,"set") == 0) { - fb_cmd = DETECT_XBITS_CMD_SET; - } else if (strcmp(fb_cmd_str,"unset") == 0) { - fb_cmd = DETECT_XBITS_CMD_UNSET; - } else if (strcmp(fb_cmd_str,"toggle") == 0) { - fb_cmd = DETECT_XBITS_CMD_TOGGLE; - } else { - SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: flowbits action \"%s\" is not supported.", fb_cmd_str); - goto error; - } - - switch (fb_cmd) { - case DETECT_XBITS_CMD_NOALERT: - if (strlen(fb_name) != 0) - goto error; - s->flags |= SIG_FLAG_NOALERT; - return 0; - case DETECT_XBITS_CMD_ISNOTSET: - case DETECT_XBITS_CMD_ISSET: - case DETECT_XBITS_CMD_SET: - case DETECT_XBITS_CMD_UNSET: - case DETECT_XBITS_CMD_TOGGLE: - default: - if (strlen(fb_name) == 0) - goto error; - break; - } - - cd = SCMalloc(sizeof(DetectXbitsData)); - if (unlikely(cd == NULL)) - goto error; - - cd->idx = VariableNameGetIdx(de_ctx, fb_name, VAR_TYPE_HOST_BIT); - cd->cmd = fb_cmd; - cd->tracker = hb_dir; - cd->type = VAR_TYPE_HOST_BIT; - cd->expire = 300; - - SCLogDebug("idx %" PRIu32 ", cmd %s, name %s", - cd->idx, fb_cmd_str, strlen(fb_name) ? fb_name : "(none)"); - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_HOSTBITS; - sm->ctx = (void *)cd; - - switch (fb_cmd) { - /* case DETECT_XBITS_CMD_NOALERT can't happen here */ - - case DETECT_XBITS_CMD_ISNOTSET: - case DETECT_XBITS_CMD_ISSET: - /* checks, so packet list */ - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - break; - - case DETECT_XBITS_CMD_SET: - case DETECT_XBITS_CMD_UNSET: - case DETECT_XBITS_CMD_TOGGLE: - /* modifiers, only run when entire sig has matched */ - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_POSTMATCH); - break; - } - - return 0; - -error: - if (cd != NULL) - SCFree(cd); - if (sm != NULL) - SCFree(sm); - return -1; -} - -void DetectHostbitFree (void *ptr) -{ - DetectXbitsData *fd = (DetectXbitsData *)ptr; - - if (fd == NULL) - return; - - SCFree(fd); -} - -#ifdef UNITTESTS - -static void HostBitsTestSetup(void) -{ - StorageInit(); - HostBitInitCtx(); - StorageFinalize(); - HostInitConfig(TRUE); -} - -static void HostBitsTestShutdown(void) -{ - HostCleanup(); - StorageCleanup(); -} - -static int HostBitsTestParse01(void) -{ - int ret = 0; - char cmd[16] = "", name[256] = "", dir[16] = ""; - - /* No direction. */ - if (!DetectHostbitParse("isset,name", cmd, sizeof(cmd), name, - sizeof(name), dir, sizeof(dir))) { - goto end; - } - if (strcmp(cmd, "isset") != 0) { - goto end; - } - if (strcmp(name, "name") != 0) { - goto end; - } - if (strlen(dir)) { - goto end; - } - - /* No direction, leading space. */ - *cmd = '\0'; - *name = '\0'; - *dir = '\0'; - if (!DetectHostbitParse("isset, name", cmd, sizeof(cmd), name, - sizeof(name), dir, sizeof(dir))) { - goto end; - } - if (strcmp(cmd, "isset") != 0) { - goto end; - } - if (strcmp(name, "name") != 0) { - goto end; - } - - /* No direction, trailing space. */ - *cmd = '\0'; - *name = '\0'; - *dir = '\0'; - if (!DetectHostbitParse("isset,name ", cmd, sizeof(cmd), name, - sizeof(name), dir, sizeof(dir))) { - goto end; - } - if (strcmp(cmd, "isset") != 0) { - goto end; - } - if (strcmp(name, "name") != 0) { - goto end; - } - - /* No direction, leading and trailing space. */ - *cmd = '\0'; - *name = '\0'; - *dir = '\0'; - if (!DetectHostbitParse("isset, name ", cmd, sizeof(cmd), name, - sizeof(name), dir, sizeof(dir))) { - goto end; - } - if (strcmp(cmd, "isset") != 0) { - goto end; - } - if (strcmp(name, "name") != 0) { - goto end; - } - - /* With direction. */ - *cmd = '\0'; - *name = '\0'; - *dir = '\0'; - if (!DetectHostbitParse("isset,name,src", cmd, sizeof(cmd), name, - sizeof(name), dir, sizeof(dir))) { - goto end; - } - if (strcmp(cmd, "isset") != 0) { - goto end; - } - if (strcmp(name, "name") != 0) { - goto end; - } - if (strcmp(dir, "src") != 0) { - goto end; - } - - /* With direction - leading and trailing spaces on name. */ - *cmd = '\0'; - *name = '\0'; - *dir = '\0'; - if (!DetectHostbitParse("isset, name ,src", cmd, sizeof(cmd), name, - sizeof(name), dir, sizeof(dir))) { - goto end; - } - if (strcmp(cmd, "isset") != 0) { - goto end; - } - if (strcmp(name, "name") != 0) { - goto end; - } - if (strcmp(dir, "src") != 0) { - goto end; - } - - /* With direction - space around direction. */ - *cmd = '\0'; - *name = '\0'; - *dir = '\0'; - if (!DetectHostbitParse("isset, name , src ", cmd, sizeof(cmd), name, - sizeof(name), dir, sizeof(dir))) { - goto end; - } - if (strcmp(cmd, "isset") != 0) { - goto end; - } - if (strcmp(name, "name") != 0) { - goto end; - } - if (strcmp(dir, "src") != 0) { - goto end; - } - - ret = 1; -end: - return ret; -} - -/** - * \test HostBitsTestSig01 is a test for a valid noalert flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int HostBitsTestSig01(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - HostBitsTestSetup(); - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - printf("bad de_ctx: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (hostbits:set,abc; content:\"GET \"; sid:1;)"); - - if (s == NULL) { - printf("bad sig: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - result = 1; - -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - HostBitsTestShutdown(); - - SCFree(p); - return result; -} - -/** - * \test various options - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int HostBitsTestSig02(void) -{ - Signature *s = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - int error_count = 0; - - memset(&th_v, 0, sizeof(th_v)); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (hostbits:isset,abc,src; content:\"GET \"; sid:1;)"); - if (s == NULL) { - error_count++; - } - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (hostbits:isnotset,abc,dst; content:\"GET \"; sid:2;)"); - if (s == NULL) { - error_count++; - } -/* TODO reenable after both is supported - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (hostbits:set,abc,both; content:\"GET \"; sid:3;)"); - if (s == NULL) { - error_count++; - } -*/ - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (hostbits:unset,abc,src; content:\"GET \"; sid:4;)"); - if (s == NULL) { - error_count++; - } - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (hostbits:toggle,abc,dst; content:\"GET \"; sid:5;)"); - if (s == NULL) { - error_count++; - } - - if (error_count != 0) - goto end; - - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - return result; -} - -#if 0 -/** - * \test HostBitsTestSig03 is a test for a invalid flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int HostBitsTestSig03(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Unknown cmd\"; flowbits:wrongcmd; content:\"GET \"; sid:1;)"); - - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - - SCFree(p); - return result; -} -#endif - -/** - * \test HostBitsTestSig04 is a test check idx value - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int HostBitsTestSig04(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - int idx = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - HostBitsTestSetup(); - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"isset option\"; hostbits:isset,fbt; content:\"GET \"; sid:1;)"); - - idx = VariableNameGetIdx(de_ctx, "fbt", VAR_TYPE_HOST_BIT); - - if (s == NULL || idx != 1) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - HostBitsTestShutdown(); - - SCFree(p); - return result; - -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - HostBitsTestShutdown(); - - SCFree(p); - return result; -} - -/** - * \test HostBitsTestSig05 is a test check noalert flag - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int HostBitsTestSig05(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - HostBitsTestSetup(); - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert ip any any -> any any (hostbits:noalert; content:\"GET \"; sid:1;)"); - - if (s == NULL || ((s->flags & SIG_FLAG_NOALERT) != SIG_FLAG_NOALERT)) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - result = 1; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostBitsTestShutdown(); - - SCFree(p); - return result; -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - HostBitsTestShutdown(); - - SCFree(p); - return result; -} - -#if 0 -/** - * \test HostBitsTestSig06 is a test set flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int HostBitsTestSig06(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - GenericVar flowvar, *gv = NULL; - int result = 0; - int idx = 0; - - memset(p, 0, SIZE_OF_PACKET); - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(Flow)); - memset(&flowvar, 0, sizeof(GenericVar)); - - FLOW_INITIALIZE(&f); - p->flow = &f; - p->flow->flowvar = &flowvar; - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - p->flags |= PKT_HAS_FLOW; - p->flowflags |= FLOW_PKT_TOSERVER; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit set\"; flowbits:set,myflow; sid:10;)"); - - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - idx = VariableNameGetIdx(de_ctx, "myflow", VAR_TYPE_HOST_BIT); - - gv = p->flow->flowvar; - - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_HOSTBITS && gv->idx == idx) { - result = 1; - } - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - - SCFree(p); - return result; -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - SCFree(p); - return result; -} - -/** - * \test HostBitsTestSig07 is a test unset flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int HostBitsTestSig07(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - GenericVar flowvar, *gv = NULL; - int result = 0; - int idx = 0; - - memset(p, 0, SIZE_OF_PACKET); - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(Flow)); - memset(&flowvar, 0, sizeof(GenericVar)); - - FLOW_INITIALIZE(&f); - p->flow = &f; - p->flow->flowvar = &flowvar; - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit set\"; flowbits:set,myflow2; sid:10;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit unset\"; flowbits:unset,myflow2; sid:11;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - idx = VariableNameGetIdx(de_ctx, "myflow", VAR_TYPE_HOST_BIT); - - gv = p->flow->flowvar; - - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_HOSTBITS && gv->idx == idx) { - result = 1; - } - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - - SCFree(p); - return result; -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - if(gv) GenericVarFree(gv); - FLOW_DESTROY(&f); - - SCFree(p); - return result; -} -#endif - -/** - * \test set / isset - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int HostBitsTestSig07(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - int result = 0; - - memset(p, 0, SIZE_OF_PACKET); - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(Flow)); - - HostBitsTestSetup(); - - FLOW_INITIALIZE(&f); - p->flow = &f; - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert ip any any -> any any (hostbits:set,myflow2; sid:10;)"); - - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx, - "alert ip any any -> any any (hostbits:isset,myflow2; sid:11;)"); - - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - SCLogInfo("p->host_src %p", p->host_src); - - if (HostHasHostBits(p->host_src) == 1) { - if (PacketAlertCheck(p, 11)) { - result = 1; - } - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - FLOW_DESTROY(&f); - - HostBitsTestShutdown(); - SCFree(p); - return result; -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - FLOW_DESTROY(&f); - - HostBitsTestShutdown(); - SCFree(p); - return result; -} - -/** - * \test set / toggle / toggle / isset - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int HostBitsTestSig08(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - int result = 0; - - memset(p, 0, SIZE_OF_PACKET); - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(Flow)); - - HostBitsTestSetup(); - - FLOW_INITIALIZE(&f); - p->flow = &f; - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (hostbits:set,myflow2; sid:10;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (hostbits:toggle,myflow2; sid:11;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (hostbits:toggle,myflow2; sid:12;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (hostbits:isset,myflow2; sid:13;)"); - if (s == NULL) { - goto end; - } - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - SCSigSignatureOrderingModuleCleanup(de_ctx); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - SCLogInfo("p->host_src %p", p->host_src); - - if (HostHasHostBits(p->host_src) == 1) { - if (PacketAlertCheck(p, 10)) { - SCLogInfo("sid 10 matched"); - } - if (PacketAlertCheck(p, 11)) { - SCLogInfo("sid 11 matched"); - } - if (PacketAlertCheck(p, 12)) { - SCLogInfo("sid 12 matched"); - } - if (PacketAlertCheck(p, 13)) { - SCLogInfo("sid 13 matched"); - result = 1; - } - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - FLOW_DESTROY(&f); - - HostBitsTestShutdown(); - - SCFree(p); - return result; -end: - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - FLOW_DESTROY(&f); - - HostBitsTestShutdown(); - - SCFree(p); - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for HostBits - */ -void HostBitsRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("HostBitsTestParse01", HostBitsTestParse01, 1); - UtRegisterTest("HostBitsTestSig01", HostBitsTestSig01, 1); - UtRegisterTest("HostBitsTestSig02", HostBitsTestSig02, 1); -#if 0 - UtRegisterTest("HostBitsTestSig03", HostBitsTestSig03, 0); -#endif - UtRegisterTest("HostBitsTestSig04", HostBitsTestSig04, 1); - UtRegisterTest("HostBitsTestSig05", HostBitsTestSig05, 1); -#if 0 - UtRegisterTest("HostBitsTestSig06", HostBitsTestSig06, 1); -#endif - UtRegisterTest("HostBitsTestSig07", HostBitsTestSig07, 1); - UtRegisterTest("HostBitsTestSig08", HostBitsTestSig08, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-hostbits.h b/framework/src/suricata/src/detect-hostbits.h deleted file mode 100644 index 6e9c7f5f..00000000 --- a/framework/src/suricata/src/detect-hostbits.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_HOSTBITS_H__ -#define __DETECT_HOSTBITS_H__ - -#include "detect-xbits.h" - -int DetectXbitMatchHost(Packet *p, const DetectXbitsData *xd); - -/* prototypes */ -void DetectHostbitsRegister (void); - -#endif /* __DETECT_HOSTBITS_H__ */ diff --git a/framework/src/suricata/src/detect-http-client-body.c b/framework/src/suricata/src/detect-http-client-body.c deleted file mode 100644 index e6c902aa..00000000 --- a/framework/src/suricata/src/detect-http-client-body.c +++ /dev/null @@ -1,2407 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements support for the http_client_body keyword - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-htp.h" -#include "detect-http-client-body.h" -#include "stream-tcp.h" - -int DetectHttpClientBodySetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpClientBodyRegisterTests(void); -void DetectHttpClientBodyFree(void *); - -/** - * \brief Registers the keyword handlers for the "http_client_body" keyword. - */ -void DetectHttpClientBodyRegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].name = "http_client_body"; - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].desc = "content modifier to match only on HTTP request-body"; - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_client_body"; - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].Setup = DetectHttpClientBodySetup; - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].Free = DetectHttpClientBodyFree; - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].RegisterTests = DetectHttpClientBodyRegisterTests; - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].alproto = ALPROTO_HTTP; - - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].flags |= SIGMATCH_NOOPT ; - sigmatch_table[DETECT_AL_HTTP_CLIENT_BODY].flags |= SIGMATCH_PAYLOAD ; -} - -static void DetectHttpClientBodySetupCallback(Signature *s) -{ - AppLayerHtpEnableRequestBodyCallback(); - return; -} - -/** - * \brief The setup function for the http_client_body keyword for a signature. - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to signature for the current Signature being parsed - * from the rules. - * \param m Pointer to the head of the SigMatchs for the current rule - * being parsed. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 On success - * \retval -1 On failure - */ -int DetectHttpClientBodySetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_CLIENT_BODY, - DETECT_SM_LIST_HCBDMATCH, - ALPROTO_HTTP, - DetectHttpClientBodySetupCallback); -} - -/** - * \brief The function to free the http_client_body data. - * - * \param ptr Pointer to the http_client_body. - */ -void DetectHttpClientBodyFree(void *ptr) -{ - SCEnter(); - DetectContentData *hcbd = (DetectContentData *)ptr; - if (hcbd == NULL) - SCReturn; - - if (hcbd->content != NULL) - SCFree(hcbd->content); - - BoyerMooreCtxDeInit(hcbd->bm_ctx); - SCFree(hcbd); - - SCReturn; -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Test that a signature containting a http_client_body is correctly parsed - * and the keyword is registered. - */ -static int DetectHttpClientBodyTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - SigMatch *sm = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_client_body\"; " - "content:\"one\"; http_client_body; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_MATCH]; - if (sm != NULL) { - result &= (sm->type == DETECT_CONTENT); - result &= (sm->next == NULL); - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a signature containing an valid http_client_body entry is - * parsed. - */ -static int DetectHttpClientBodyTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_client_body\"; " - "content:\"one\"; http_client_body:; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing no content but a http_client_body - * is invalidated. - */ -static int DetectHttpClientBodyTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_client_body\"; " - "http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_client_body is invalidated. - */ -static int DetectHttpClientBodyTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_client_body\"; " - "content:\"one\"; rawbytes; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_client_body is invalidated. - */ -static int DetectHttpClientBodyTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_client_body\"; " - "content:\"one\"; http_client_body; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - *\test Test that the http_client_body content matches against a http request - * which holds the content. - */ -static int DetectHttpClientBodyTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:\"message\"; http_client_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_client_body content matches against a http request - * which holds the content. - */ -static int DetectHttpClientBodyTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 54\r\n" - "\r\n" - "This is dummy message body1"; - uint8_t http2_buf[] = - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:\"message\"; http_client_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_client_body content matches against a http request - * which holds the content. - */ -static int DetectHttpClientBodyTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1"; - uint8_t http2_buf[] = - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:\"message\"; http_client_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_client_body content matches against a http request - * which holds the content, against a cross boundary present pattern. - */ -static int DetectHttpClientBodyTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1"; - uint8_t http2_buf[] = - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:\"body1This\"; http_client_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_client_body content matches against a http request - * against a case insensitive pattern. - */ -static int DetectHttpClientBodyTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy bodY1"; - uint8_t http2_buf[] = - "This is dummy message body2"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:\"body1This\"; http_client_body; nocase;" - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the negated http_client_body content matches against a - * http request which doesn't hold the content. - */ -static int DetectHttpClientBodyTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:!\"message1\"; http_client_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Negative test that the negated http_client_body content matches against a - * http request which holds hold the content. - */ -static int DetectHttpClientBodyTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:!\"message\"; http_client_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_client_body content matches against a http request - * which holds the content. - */ -static int DetectHttpClientBodyTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 55\r\n" - "\r\n" - "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_client_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test multiple http transactions and body chunks of request handling */ -static int DetectHttpClientBodyTest14(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n"; - uint8_t httpbuf4[] = "Body one!!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n"; - uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"one\"; http_client_body; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; content:\"two\"; http_client_body; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - SCMutexUnlock(&f.m); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("signature matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (5): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf7, httplen7); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match, but should have: "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test multiple http transactions and body chunks of request handling */ -static int DetectHttpClientBodyTest15(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n"; - uint8_t httpbuf4[] = "Body one!!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n"; - uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"one\"; http_client_body; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; content:\"two\"; http_client_body; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("signature matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (5): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf7, httplen7); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match, but should have: "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* hardcoded check of the transactions and it's client body chunks */ - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0); - htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 1); - - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1); - - HtpBodyChunk *cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body one!!", strlen("Body one!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - htud = (HtpTxUserData *) htp_tx_get_user_data(t2); - - cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body two!!", strlen("Body two!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - - - - - - - - - - - - - - - -int DetectHttpClientBodyTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; http_client_body; " - "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hcbd1->content, "two", hcbd1->content_len) != 0 || - hcbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd1) || - !DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hcbd1) || - DETECT_CONTENT_IS_SINGLE(hcbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; pcre:/two/; " - "content:\"three\"; distance:10; http_client_body; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 || - hcbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hcbd1) || - DETECT_CONTENT_IS_SINGLE(hcbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; pcre:/two/; " - "content:\"three\"; distance:10; within:15; http_client_body; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 || - hcbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hcbd1) || - DETECT_CONTENT_IS_SINGLE(hcbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; pcre:/two/; " - "content:\"three\"; distance:10; http_client_body; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 || - hcbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hcbd1) || - DETECT_CONTENT_IS_SINGLE(hcbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; offset:10; http_client_body; pcre:/two/; " - "content:\"three\"; distance:10; http_client_body; within:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hcbd1->flags != (DETECT_CONTENT_RELATIVE_NEXT | DETECT_CONTENT_OFFSET) || - memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 || - hcbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) { - printf ("failed: http_client_body incorrect flags"); - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hcbd1) || - DETECT_CONTENT_IS_SINGLE(hcbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; offset:10; http_client_body; pcre:/two/; " - "content:\"three\"; distance:10; http_client_body; within:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest28(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; pcre:/two/; " - "content:\"three\"; http_client_body; depth:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hcbd1->flags != 0 || - memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 || - hcbd2->flags != DETECT_CONTENT_DEPTH || - memcmp(hcbd2->content, "three", hcbd1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - !DETECT_CONTENT_IS_SINGLE(hcbd1) || - DETECT_CONTENT_IS_SINGLE(hcbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest29(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; " - "content:\"two\"; distance:0; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 || - hcbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest30(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; " - "content:\"two\"; within:5; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hcbd1->content, "one", hcbd1->content_len) != 0 || - hcbd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hcbd2->content, "two", hcbd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest31(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest32(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_client_body; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list != NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest33(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest34(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(pcre:/one/P; " - "content:\"two\"; within:5; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hcbd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest35(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_client_body; " - "pcre:/one/PR; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->type != DETECT_PCRE || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->type != DETECT_CONTENT) { - - goto end; - } - - DetectContentData *hcbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (pd2->flags != (DETECT_PCRE_RELATIVE) || - hcbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hcbd1->content, "two", hcbd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpClientBodyTest36(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(pcre:/one/P; " - "content:\"two\"; distance:5; http_client_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCBDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->prev->ctx; - DetectContentData *hcbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hcbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hcbd2->content, "two", hcbd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -void DetectHttpClientBodyRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectHttpClientBodyTest01", DetectHttpClientBodyTest01, 1); - UtRegisterTest("DetectHttpClientBodyTest02", DetectHttpClientBodyTest02, 1); - UtRegisterTest("DetectHttpClientBodyTest03", DetectHttpClientBodyTest03, 1); - UtRegisterTest("DetectHttpClientBodyTest04", DetectHttpClientBodyTest04, 1); - UtRegisterTest("DetectHttpClientBodyTest05", DetectHttpClientBodyTest05, 1); - UtRegisterTest("DetectHttpClientBodyTest06", DetectHttpClientBodyTest06, 1); - UtRegisterTest("DetectHttpClientBodyTest07", DetectHttpClientBodyTest07, 1); - UtRegisterTest("DetectHttpClientBodyTest08", DetectHttpClientBodyTest08, 1); - UtRegisterTest("DetectHttpClientBodyTest09", DetectHttpClientBodyTest09, 1); - UtRegisterTest("DetectHttpClientBodyTest10", DetectHttpClientBodyTest10, 1); - UtRegisterTest("DetectHttpClientBodyTest11", DetectHttpClientBodyTest11, 1); - UtRegisterTest("DetectHttpClientBodyTest12", DetectHttpClientBodyTest12, 1); - UtRegisterTest("DetectHttpClientBodyTest13", DetectHttpClientBodyTest13, 1); - UtRegisterTest("DetectHttpClientBodyTest14", DetectHttpClientBodyTest14, 1); - UtRegisterTest("DetectHttpClientBodyTest15", DetectHttpClientBodyTest15, 1); - - UtRegisterTest("DetectHttpClientBodyTest22", DetectHttpClientBodyTest22, 1); - UtRegisterTest("DetectHttpClientBodyTest23", DetectHttpClientBodyTest23, 1); - UtRegisterTest("DetectHttpClientBodyTest24", DetectHttpClientBodyTest24, 1); - UtRegisterTest("DetectHttpClientBodyTest25", DetectHttpClientBodyTest25, 1); - UtRegisterTest("DetectHttpClientBodyTest26", DetectHttpClientBodyTest26, 1); - UtRegisterTest("DetectHttpClientBodyTest27", DetectHttpClientBodyTest27, 1); - UtRegisterTest("DetectHttpClientBodyTest28", DetectHttpClientBodyTest28, 1); - UtRegisterTest("DetectHttpClientBodyTest29", DetectHttpClientBodyTest29, 1); - UtRegisterTest("DetectHttpClientBodyTest30", DetectHttpClientBodyTest30, 1); - UtRegisterTest("DetectHttpClientBodyTest31", DetectHttpClientBodyTest31, 1); - UtRegisterTest("DetectHttpClientBodyTest32", DetectHttpClientBodyTest32, 1); - UtRegisterTest("DetectHttpClientBodyTest33", DetectHttpClientBodyTest33, 1); - UtRegisterTest("DetectHttpClientBodyTest34", DetectHttpClientBodyTest34, 1); - UtRegisterTest("DetectHttpClientBodyTest35", DetectHttpClientBodyTest35, 1); - UtRegisterTest("DetectHttpClientBodyTest36", DetectHttpClientBodyTest36, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-client-body.h b/framework/src/suricata/src/detect-http-client-body.h deleted file mode 100644 index 7a2249c2..00000000 --- a/framework/src/suricata/src/detect-http-client-body.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_HTTP_CLIENT_BODY_H__ -#define __DETECT_HTTP_CLIENT_BODY_H__ - -void DetectHttpClientBodyRegister(void); - -#endif /* __DETECT_HTTP_CLIENT_BODY_H__ */ diff --git a/framework/src/suricata/src/detect-http-cookie.c b/framework/src/suricata/src/detect-http-cookie.c deleted file mode 100644 index 94f76765..00000000 --- a/framework/src/suricata/src/detect-http-cookie.c +++ /dev/null @@ -1,1277 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Gurvinder Singh - * - * Implements the http_cookie keyword - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-error.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" -#include "util-print.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "detect-http-cookie.h" -#include "stream-tcp.h" - -static int DetectHttpCookieSetup (DetectEngineCtx *, Signature *, char *); -void DetectHttpCookieRegisterTests(void); -void DetectHttpCookieFree(void *); - -/** - * \brief Registration function for keyword: http_cookie - */ -void DetectHttpCookieRegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_COOKIE].name = "http_cookie"; - sigmatch_table[DETECT_AL_HTTP_COOKIE].desc = "content modifier to match only on the HTTP cookie-buffer"; - sigmatch_table[DETECT_AL_HTTP_COOKIE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_cookie"; - sigmatch_table[DETECT_AL_HTTP_COOKIE].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_COOKIE].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_COOKIE].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_AL_HTTP_COOKIE].Setup = DetectHttpCookieSetup; - sigmatch_table[DETECT_AL_HTTP_COOKIE].Free = DetectHttpCookieFree; - sigmatch_table[DETECT_AL_HTTP_COOKIE].RegisterTests = DetectHttpCookieRegisterTests; - - sigmatch_table[DETECT_AL_HTTP_COOKIE].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_HTTP_COOKIE].flags |= SIGMATCH_PAYLOAD; -} - -/** - * \brief this function clears the memory of http_cookie modifier keyword - * - * \param ptr Pointer to the Detection Cookie data - */ -void DetectHttpCookieFree(void *ptr) -{ - DetectContentData *hcd = (DetectContentData *)ptr; - if (hcd == NULL) - return; - if (hcd->content != NULL) - SCFree(hcd->content); - SCFree(hcd); -} - -/** - * \brief this function setups the http_cookie modifier keyword used in the rule - * - * \param de_ctx Pointer to the Detection Engine Context - * \param s Pointer to the Signature to which the current keyword belongs - * \param str Should hold an empty string always - * - * \retval 0 On success - * \retval -1 On failure - */ - -static int DetectHttpCookieSetup(DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, str, - DETECT_AL_HTTP_COOKIE, - DETECT_SM_LIST_HCDMATCH, - ALPROTO_HTTP, - NULL); -} - -/******************************** UNITESTS **********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Checks if a http_cookie is registered in a Signature, if content is not - * specified in the signature - */ -int DetectHttpCookieTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_cookie\"; http_cookie;sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_cookie is registered in a Signature, if some parameter - * is specified with http_cookie in the signature - */ -int DetectHttpCookieTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_cookie\"; content:\"me\"; " - "http_cookie:woo; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_cookie is registered in a Signature - */ -int DetectHttpCookieTest03(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_cookie\"; content:\"one\"; " - "http_cookie; content:\"two\"; http_cookie; " - "content:\"two\"; http_cookie; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HCDMATCH]; - if (sm == NULL) { - printf("no sigmatch(es): "); - goto end; - } - - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - result = 1; - } else { - printf("expected DETECT_CONTENT for http_cookie, got %d: ", sm->type); - goto end; - } - sm = sm->next; - } - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_cookie is registered in a Signature, when fast_pattern - * is also specified in the signature (now it should) - */ -int DetectHttpCookieTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_cookie\"; content:\"one\"; " - "fast_pattern; http_cookie; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - -end: - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_cookie is registered in a Signature, when rawbytes is - * also specified in the signature - */ -int DetectHttpCookieTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_cookie\"; content:\"one\"; " - "rawbytes; http_cookie; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_cookie is registered in a Signature, when rawbytes is - * also specified in the signature - */ -int DetectHttpCookieTest06(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_cookie\"; content:\"one\"; " - "http_cookie; uricontent:\"abc\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - Signature *s = de_ctx->sig_list; - - BUG_ON(s->sm_lists[DETECT_SM_LIST_HCDMATCH] == NULL); - - if (s->sm_lists[DETECT_SM_LIST_HCDMATCH]->type != DETECT_CONTENT) - goto end; - - if (s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL) { - printf("expected another SigMatch, got NULL: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_UMATCH]->type != DETECT_CONTENT) { - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - return result; -} - -/** \test Check the signature working to alert when http_cookie is matched . */ -static int DetectHttpCookieSigTest01(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\nCookie:" - " hellocatchme\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; content:\"me\"; " - "http_cookie; sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " - "cookie\"; content:\"go\"; http_cookie; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sid 2 matched but shouldn't: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_cookie is not present */ -static int DetectHttpCookieSigTest02(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; content:\"me\"; " - "http_cookie; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_cookie is not present */ -static int DetectHttpCookieSigTest03(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; content:\"boo\"; " - "http_cookie; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_cookie is not present */ -static int DetectHttpCookieSigTest04(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; content:!\"boo\"; " - "http_cookie; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_cookie is not present */ -static int DetectHttpCookieSigTest05(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: DuMmY\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; content:\"dummy\"; nocase; " - "http_cookie; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_cookie is not present */ -static int DetectHttpCookieSigTest06(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: DuMmY\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; content:\"dummy\"; " - "http_cookie; nocase; sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_cookie is not present */ -static int DetectHttpCookieSigTest07(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; content:!\"dummy\"; " - "http_cookie; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Check the signature working to alert against set-cookie - */ -static int DetectHttpCookieSigTest08(void) -{ - int result = 0; - Flow f; - - uint8_t httpbuf_request[] = - "GET / HTTP/1.1\r\n" - "User-Agent: Mozilla/1.0\r\n" - "\r\n"; - uint32_t httpbuf_request_len = sizeof(httpbuf_request) - 1; /* minus the \0 */ - - uint8_t httpbuf_response[] = - "HTTP/1.1 200 OK\r\n" - "Set-Cookie: response_user_agent\r\n" - "\r\n"; - uint32_t httpbuf_response_len = sizeof(httpbuf_response) - 1; /* minus the \0 */ - - TcpSession ssn; - Packet *p1 = NULL, *p2 = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(flow:to_client; content:\"response_user_agent\"; " - "http_cookie; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* request */ - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, - httpbuf_request, httpbuf_request_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) { - goto end; - } - - /* response */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, - httpbuf_response, httpbuf_response_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!PacketAlertCheck(p2, 1)) { - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - * \test Check the signature working to alert against cookie/set-cookie - */ -static int DetectHttpCookieSigTest09(void) -{ - int result = 0; - Flow f; - - uint8_t httpbuf_request[] = - "GET / HTTP/1.1\r\n" - "Cookie: request_user_agent\r\n" - "User-Agent: Mozilla/1.0\r\n" - "\r\n"; - uint32_t httpbuf_request_len = sizeof(httpbuf_request) - 1; /* minus the \0 */ - - uint8_t httpbuf_response[] = - "HTTP/1.1 200 OK\r\n" - "Set-Cookie: response_user_agent\r\n" - "\r\n"; - uint32_t httpbuf_response_len = sizeof(httpbuf_response) - 1; /* minus the \0 */ - - TcpSession ssn; - Packet *p1 = NULL, *p2 = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(flow:to_server; content:\"request_user_agent\"; " - "http_cookie; sid:1;)"); - if (s == NULL) { - goto end; - } - s = de_ctx->sig_list->next = SigInit(de_ctx,"alert http any any -> any any " - "(flow:to_client; content:\"response_user_agent\"; " - "http_cookie; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* request */ - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, - httpbuf_request, httpbuf_request_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (!PacketAlertCheck(p1, 1) || PacketAlertCheck(p1, 2)) { - goto end; - } - - /* response */ - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, - httpbuf_response, httpbuf_response_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 1) || !PacketAlertCheck(p2, 2)) { - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief Register the UNITTESTS for the http_cookie keyword - */ -void DetectHttpCookieRegisterTests (void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectHttpCookieTest01", DetectHttpCookieTest01, 1); - UtRegisterTest("DetectHttpCookieTest02", DetectHttpCookieTest02, 1); - UtRegisterTest("DetectHttpCookieTest03", DetectHttpCookieTest03, 1); - UtRegisterTest("DetectHttpCookieTest04", DetectHttpCookieTest04, 1); - UtRegisterTest("DetectHttpCookieTest05", DetectHttpCookieTest05, 1); - UtRegisterTest("DetectHttpCookieTest06", DetectHttpCookieTest06, 1); - UtRegisterTest("DetectHttpCookieSigTest01", DetectHttpCookieSigTest01, 1); - UtRegisterTest("DetectHttpCookieSigTest02", DetectHttpCookieSigTest02, 1); - UtRegisterTest("DetectHttpCookieSigTest03", DetectHttpCookieSigTest03, 1); - UtRegisterTest("DetectHttpCookieSigTest04", DetectHttpCookieSigTest04, 1); - UtRegisterTest("DetectHttpCookieSigTest05", DetectHttpCookieSigTest05, 1); - UtRegisterTest("DetectHttpCookieSigTest06", DetectHttpCookieSigTest06, 1); - UtRegisterTest("DetectHttpCookieSigTest07", DetectHttpCookieSigTest07, 1); - UtRegisterTest("DetectHttpCookieSigTest08", DetectHttpCookieSigTest08, 1); - UtRegisterTest("DetectHttpCookieSigTest09", DetectHttpCookieSigTest09, 1); -#endif /* UNITTESTS */ - -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-cookie.h b/framework/src/suricata/src/detect-http-cookie.h deleted file mode 100644 index 63128e0c..00000000 --- a/framework/src/suricata/src/detect-http-cookie.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - */ - -#ifndef _DETECT_HTTP_COOKIE_H -#define _DETECT_HTTP_COOKIE_H - -/* prototypes */ -void DetectHttpCookieRegister (void); -int DetectHttpCookieDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, - Flow *, uint8_t, void *); - -#endif /* _DETECT_HTTP_COOKIE_H */ - diff --git a/framework/src/suricata/src/detect-http-header.c b/framework/src/suricata/src/detect-http-header.c deleted file mode 100644 index 6c9fea9a..00000000 --- a/framework/src/suricata/src/detect-http-header.c +++ /dev/null @@ -1,1822 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Pablo Rincon - * - * Implements support for http_header keyword. - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" -#include "util-print.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "detect-http-header.h" -#include "stream-tcp.h" - -int DetectHttpHeaderSetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpHeaderRegisterTests(void); -void DetectHttpHeaderFree(void *); - -/** - * \brief Registers the keyword handlers for the "http_header" keyword. - */ -void DetectHttpHeaderRegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_HEADER].name = "http_header"; - sigmatch_table[DETECT_AL_HTTP_HEADER].desc = "content modifier to match only on the HTTP header-buffer"; - sigmatch_table[DETECT_AL_HTTP_HEADER].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_header"; - sigmatch_table[DETECT_AL_HTTP_HEADER].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_HEADER].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_HEADER].Setup = DetectHttpHeaderSetup; - sigmatch_table[DETECT_AL_HTTP_HEADER].Free = DetectHttpHeaderFree; - sigmatch_table[DETECT_AL_HTTP_HEADER].RegisterTests = DetectHttpHeaderRegisterTests; - sigmatch_table[DETECT_AL_HTTP_HEADER].alproto = ALPROTO_HTTP; - - sigmatch_table[DETECT_AL_HTTP_HEADER].flags |= SIGMATCH_NOOPT ; - sigmatch_table[DETECT_AL_HTTP_HEADER].flags |= SIGMATCH_PAYLOAD ; - - return; -} - -/** - * \brief this function clears the memory of http_header modifier keyword - * - * \param ptr Pointer to the Detection Header Data - */ -void DetectHttpHeaderFree(void *ptr) -{ - DetectContentData *hhd = (DetectContentData *)ptr; - if (hhd == NULL) - return; - - if (hhd->content != NULL) - SCFree(hhd->content); - SCFree(hhd); - - return; -} - -/** - * \brief The setup function for the http_header keyword for a signature. - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to signature for the current Signature being parsed - * from the rules. - * \param m Pointer to the head of the SigMatchs for the current rule - * being parsed. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectHttpHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_HEADER, - DETECT_SM_LIST_HHDMATCH, - ALPROTO_HTTP, - NULL); -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Test that a signature containting a http_header is correctly parsed - * and the keyword is registered. - */ -static int DetectHttpHeaderTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - SigMatch *sm = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "content:\"one\"; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("Error parsing signature: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH]; - if (sm != NULL) { - result &= (sm->type == DETECT_CONTENT); - result &= (sm->next == NULL); - } else { - result = 0; - printf("Error updating content pattern to http_header pattern: "); - } - - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a signature containing an valid http_header entry is - * parsed. - */ -static int DetectHttpHeaderTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "content:\"one\"; http_header:; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing no content but a http_header - * is invalidated. - */ -static int DetectHttpHeaderTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_header is invalidated. - */ -static int DetectHttpHeaderTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "content:\"one\"; rawbytes; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_header is invalidated. - */ -static int DetectHttpHeaderTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "content:\"one\"; nocase; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpHeaderTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Content-Type: text/html\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpHeaderTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozi"; - uint8_t http2_buf[] = - "lla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\nContent-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n" - "This is dummy message body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Mozilla\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ( (PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpHeaderTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n"; - uint8_t http2_buf[] = - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Gecko/20091221 Firefox/3.5.7\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content, against a cross boundary present pattern. - */ -static int DetectHttpHeaderTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"; - uint8_t http2_buf[] = - "Content-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n" - "This is dummy body\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->mpm_matcher = DEFAULT_MPM; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Firefox/3.5.7|0D 0A|Content\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * against a case insensitive pattern. - */ -static int DetectHttpHeaderTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"; - uint8_t http2_buf[] = - "Content-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n" - "This is dummy body"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_header;" - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the negated http_header content matches against a - * http request which doesn't hold the content. - */ -static int DetectHttpHeaderTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"lalalalala\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Negative test that the negated http_header content matches against a - * http request which holds hold the content. - */ -static int DetectHttpHeaderTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"User-Agent: Mozilla/5.0 \"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpHeaderTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 100\r\n" - "\r\n" - "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Host: www.openinfosecfoundation.org\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -int DetectHttpHeaderTest20(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; " - "content:\"two\"; distance:0; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hhd1->content, "one", hhd1->content_len) != 0 || - hhd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hhd2->content, "two", hhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHeaderTest21(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; " - "content:\"two\"; within:5; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hhd1->content, "one", hhd1->content_len) != 0 || - hhd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hhd2->content, "two", hhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHeaderTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHeaderTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHeaderTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHeaderTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(pcre:/one/H; " - "content:\"two\"; within:5; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hhd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hhd2->content, "two", hhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHeaderTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_header; " - "pcre:/one/HR; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->type != DETECT_PCRE || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->type != DETECT_CONTENT) { - - goto end; - } - - DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (pd2->flags != (DETECT_PCRE_RELATIVE) || - hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hhd1->content, "two", hhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHeaderTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(pcre:/one/H; " - "content:\"two\"; distance:5; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hhd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hhd2->content, "two", hhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test app-layer-event:http.host_header_ambiguous should not be set - * \bug 640*/ -static int DetectHttpHeaderTest28(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n" - "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n" - "Host: xxx.intranet.local:8000\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(app-layer-event:http.host_header_ambiguous; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldnt have: "); - goto end; - } - - result = 1; - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test app-layer-event:http.host_header_ambiguous should be set - * \bug 640*/ -static int DetectHttpHeaderTest29(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "POST http://xxx.intranet.local:8001/xxx HTTP/1.1\r\n" - "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n" - "Host: xxx.intranet.local:8000\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(app-layer-event:http.host_header_ambiguous; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test app-layer-event:http.host_header_ambiguous should be set - * \bug 640*/ -static int DetectHttpHeaderTest30(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n" - "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n" - "Host: xyz.intranet.local:8000\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(app-layer-event:http.host_header_ambiguous; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectHttpHeaderRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectHttpHeaderTest01", DetectHttpHeaderTest01, 1); - UtRegisterTest("DetectHttpHeaderTest02", DetectHttpHeaderTest02, 1); - UtRegisterTest("DetectHttpHeaderTest03", DetectHttpHeaderTest03, 1); - UtRegisterTest("DetectHttpHeaderTest04", DetectHttpHeaderTest04, 1); - UtRegisterTest("DetectHttpHeaderTest05", DetectHttpHeaderTest05, 1); - UtRegisterTest("DetectHttpHeaderTest06", DetectHttpHeaderTest06, 1); - UtRegisterTest("DetectHttpHeaderTest07", DetectHttpHeaderTest07, 1); - UtRegisterTest("DetectHttpHeaderTest08", DetectHttpHeaderTest08, 1); - UtRegisterTest("DetectHttpHeaderTest09", DetectHttpHeaderTest09, 1); - UtRegisterTest("DetectHttpHeaderTest10", DetectHttpHeaderTest10, 1); - UtRegisterTest("DetectHttpHeaderTest11", DetectHttpHeaderTest11, 1); - UtRegisterTest("DetectHttpHeaderTest12", DetectHttpHeaderTest12, 1); - UtRegisterTest("DetectHttpHeaderTest13", DetectHttpHeaderTest13, 1); - UtRegisterTest("DetectHttpHeaderTest20", DetectHttpHeaderTest20, 1); - UtRegisterTest("DetectHttpHeaderTest21", DetectHttpHeaderTest21, 1); - UtRegisterTest("DetectHttpHeaderTest22", DetectHttpHeaderTest22, 1); - UtRegisterTest("DetectHttpHeaderTest23", DetectHttpHeaderTest23, 1); - UtRegisterTest("DetectHttpHeaderTest24", DetectHttpHeaderTest24, 1); - UtRegisterTest("DetectHttpHeaderTest25", DetectHttpHeaderTest25, 1); - UtRegisterTest("DetectHttpHeaderTest26", DetectHttpHeaderTest26, 1); - UtRegisterTest("DetectHttpHeaderTest27", DetectHttpHeaderTest27, 1); - UtRegisterTest("DetectHttpHeaderTest28", DetectHttpHeaderTest28, 1); - UtRegisterTest("DetectHttpHeaderTest29", DetectHttpHeaderTest29, 1); - UtRegisterTest("DetectHttpHeaderTest30", DetectHttpHeaderTest30, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-header.h b/framework/src/suricata/src/detect-http-header.h deleted file mode 100644 index 5327b5b8..00000000 --- a/framework/src/suricata/src/detect-http-header.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_HTTP_HEADER_H__ -#define __DETECT_HTTP_HEADER_H__ - -void DetectHttpHeaderRegister(void); -void DetectHttpRawHeaderRegister(void); - -#endif /* __DETECT_HTTP_HEADER_H__ */ diff --git a/framework/src/suricata/src/detect-http-hh.c b/framework/src/suricata/src/detect-http-hh.c deleted file mode 100644 index 19e87e16..00000000 --- a/framework/src/suricata/src/detect-http-hh.c +++ /dev/null @@ -1,2106 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements support for the http_host keyword. - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "stream-tcp.h" -#include "detect-http-hh.h" - -int DetectHttpHHSetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpHHRegisterTests(void); -void DetectHttpHHFree(void *); - -/** - * \brief Registers the keyword handlers for the "http_host" keyword. - */ -void DetectHttpHHRegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_HOST].name = "http_host"; - sigmatch_table[DETECT_AL_HTTP_HOST].desc = "content modifier to match only on the HTTP hostname"; - sigmatch_table[DETECT_AL_HTTP_HOST].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_HOST].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_HOST].Setup = DetectHttpHHSetup; - sigmatch_table[DETECT_AL_HTTP_HOST].Free = DetectHttpHHFree; - sigmatch_table[DETECT_AL_HTTP_HOST].RegisterTests = DetectHttpHHRegisterTests; - sigmatch_table[DETECT_AL_HTTP_HOST].alproto = ALPROTO_HTTP; - - sigmatch_table[DETECT_AL_HTTP_HOST].flags |= SIGMATCH_NOOPT ; - sigmatch_table[DETECT_AL_HTTP_HOST].flags |= SIGMATCH_PAYLOAD ; - - return; -} - -/** - * \brief The setup function for the http_host keyword for a signature. - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to the signature for the current Signature being - * parsed from the rules. - * \param m Pointer to the head of the SigMatch for the current rule - * being parsed. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 On success - * \retval -1 On failure - */ -int DetectHttpHHSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_HOST, - DETECT_SM_LIST_HHHDMATCH, - ALPROTO_HTTP, - NULL); -} - -/** - * \brief The function to free the http_host data. - * - * \param ptr Pointer to the http_host. - */ -void DetectHttpHHFree(void *ptr) -{ - DetectContentData *hhhd = (DetectContentData *)ptr; - if (hhhd == NULL) - return; - - if (hhhd->content != NULL) - SCFree(hhhd->content); - - BoyerMooreCtxDeInit(hhhd->bm_ctx); - SCFree(hhhd); - - return; -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Test that a signature containting a http_host is correctly parsed - * and the keyword is registered. - */ -static int DetectHttpHHTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_host\"; " - "content:\"one\"; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a signature containing an valid http_host entry is - * parsed. - */ -static int DetectHttpHHTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_host\"; " - "content:\"one\"; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing no content but a - * http_host is invalidated. - */ -static int DetectHttpHHTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_host\"; " - "http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_host is invalidated. - */ -static int DetectHttpHHTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_host\"; " - "content:\"one\"; rawbytes; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a http_host with nocase is parsed. - */ -static int DetectHttpHHTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_host\"; " - "content:\"one\"; http_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - *\test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectHttpHHTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy message body\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"message\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectHttpHHTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy message"; - uint8_t http2_buf[] = - "body1\r\n\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"message\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectHttpHHTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "host: This is dummy mess"; - uint8_t http2_buf[] = - "age body\r\n\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"message\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_host content matches against a http request - * which holds the content, against a cross boundary present pattern. - */ -static int DetectHttpHHTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy body1"; - uint8_t http2_buf[] = - "This is dummy message body2\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"body1this\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_host content matches against a http request - * against a case insensitive pattern. - */ -static int DetectHttpHHTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy bodY1"; - uint8_t http2_buf[] = - "This is dummy message body2\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy bodY1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"body1this\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the negated http_host content matches against a - * http request which doesn't hold the content. - */ -static int DetectHttpHHTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy message body\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:!\"message\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Negative test that the negated http_host content matches against a - * http request which holds hold the content. - */ -static int DetectHttpHHTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy body\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:!\"message\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_host content matches against a http request - * which holds the content. - */ -static int DetectHttpHHTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test multiple http transactions and body chunks of request handling - */ -static int DetectHttpHHTest14(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "Cookie: dummy1\r\n"; - uint8_t httpbuf3[] = "Host: Body one!!\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf5[] = "Cookie: dummy2\r\n"; - uint8_t httpbuf6[] = "Host: Body two\r\n\r\n"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"dummy1\"; http_cookie; content:\"body one\"; http_host; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"dummy2\"; http_cookie; content:\"body two\"; http_host; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2)) { - printf("sig 1 alerted (4): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) || !(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match or sig 1 matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - - - - - - - - - - - -int DetectHttpHHTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; content:\"two\"; http_host; " - "content:\"three\"; distance:10; http_host; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hhhd1->content, "two", hhhd1->content_len) != 0 || - hhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd1) || - !DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hhhd1) || - DETECT_CONTENT_IS_SINGLE(hhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_host; pcre:/two/; " - "content:\"three\"; distance:10; http_host; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 || - hhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hhhd1) || - DETECT_CONTENT_IS_SINGLE(hhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_host; pcre:/two/; " - "content:\"three\"; distance:10; within:15; http_host; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 || - hhhd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hhhd1) || - DETECT_CONTENT_IS_SINGLE(hhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_host; pcre:/two/; " - "content:\"three\"; distance:10; http_host; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 || - hhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hhhd1) || - DETECT_CONTENT_IS_SINGLE(hhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; offset:10; http_host; pcre:/two/; " - "content:\"three\"; distance:10; http_host; within:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT | DETECT_CONTENT_OFFSET) || - memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 || - hhhd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) { - printf ("failed: http_host incorrect flags"); - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hhhd1) || - DETECT_CONTENT_IS_SINGLE(hhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; offset:10; http_host; pcre:/two/; " - "content:\"three\"; distance:10; http_host; within:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest28(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_host; pcre:/two/; " - "content:\"three\"; http_host; depth:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hhhd1->flags != (0) || - memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 || - hhhd2->flags != (DETECT_CONTENT_DEPTH) || - memcmp(hhhd2->content, "three", hhhd1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - !DETECT_CONTENT_IS_SINGLE(hhhd1) || - DETECT_CONTENT_IS_SINGLE(hhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest29(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; distance:0; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 || - hhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hhhd2->content, "two", hhhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest30(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_host; " - "content:\"two\"; within:5; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hhhd1->content, "one", hhhd1->content_len) != 0 || - hhhd2->flags != (DETECT_CONTENT_WITHIN) || - memcmp(hhhd2->content, "two", hhhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest31(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; within:5; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest32(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_host; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list != NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest33(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest34(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(pcre:/one/W; " - "content:\"two\"; within:5; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hhhd2->flags != (DETECT_CONTENT_WITHIN) || - memcmp(hhhd2->content, "two", hhhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest35(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"two\"; http_host; " - "pcre:/one/WR; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->type != DETECT_PCRE || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->type != DETECT_CONTENT) { - - goto end; - } - - DetectContentData *hhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (pd2->flags != (DETECT_PCRE_RELATIVE) || - hhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hhhd1->content, "two", hhhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHHTest36(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(pcre:/one/W; " - "content:\"two\"; distance:5; http_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HHHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->prev->ctx; - DetectContentData *hhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hhhd2->content, "two", hhhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -void DetectHttpHHRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectHttpHHTest01", DetectHttpHHTest01, 1); - UtRegisterTest("DetectHttpHHTest02", DetectHttpHHTest02, 1); - UtRegisterTest("DetectHttpHHTest03", DetectHttpHHTest03, 1); - UtRegisterTest("DetectHttpHHTest04", DetectHttpHHTest04, 1); - UtRegisterTest("DetectHttpHHTest05", DetectHttpHHTest05, 1); - UtRegisterTest("DetectHttpHHTest06", DetectHttpHHTest06, 1); - UtRegisterTest("DetectHttpHHTest07", DetectHttpHHTest07, 1); - UtRegisterTest("DetectHttpHHTest08", DetectHttpHHTest08, 1); - UtRegisterTest("DetectHttpHHTest09", DetectHttpHHTest09, 1); - UtRegisterTest("DetectHttpHHTest10", DetectHttpHHTest10, 1); - UtRegisterTest("DetectHttpHHTest11", DetectHttpHHTest11, 1); - UtRegisterTest("DetectHttpHHTest12", DetectHttpHHTest12, 1); - UtRegisterTest("DetectHttpHHTest13", DetectHttpHHTest13, 1); - UtRegisterTest("DetectHttpHHTest14", DetectHttpHHTest14, 1); - - UtRegisterTest("DetectHttpHHTest22", DetectHttpHHTest22, 1); - UtRegisterTest("DetectHttpHHTest23", DetectHttpHHTest23, 1); - UtRegisterTest("DetectHttpHHTest24", DetectHttpHHTest24, 1); - UtRegisterTest("DetectHttpHHTest25", DetectHttpHHTest25, 1); - UtRegisterTest("DetectHttpHHTest26", DetectHttpHHTest26, 1); - UtRegisterTest("DetectHttpHHTest27", DetectHttpHHTest27, 1); - UtRegisterTest("DetectHttpHHTest28", DetectHttpHHTest28, 1); - UtRegisterTest("DetectHttpHHTest29", DetectHttpHHTest29, 1); - UtRegisterTest("DetectHttpHHTest30", DetectHttpHHTest30, 1); - UtRegisterTest("DetectHttpHHTest31", DetectHttpHHTest31, 1); - UtRegisterTest("DetectHttpHHTest32", DetectHttpHHTest32, 1); - UtRegisterTest("DetectHttpHHTest33", DetectHttpHHTest33, 1); - UtRegisterTest("DetectHttpHHTest34", DetectHttpHHTest34, 1); - UtRegisterTest("DetectHttpHHTest35", DetectHttpHHTest35, 1); - UtRegisterTest("DetectHttpHHTest36", DetectHttpHHTest36, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-hh.h b/framework/src/suricata/src/detect-http-hh.h deleted file mode 100644 index bb6fd3da..00000000 --- a/framework/src/suricata/src/detect-http-hh.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_HTTP_HH_H__ -#define __DETECT_HTTP_HH_H__ - -void DetectHttpHHRegister(void); - -#endif /* __DETECT_HTTP_HH_H__ */ diff --git a/framework/src/suricata/src/detect-http-hrh.c b/framework/src/suricata/src/detect-http-hrh.c deleted file mode 100644 index a6a56b10..00000000 --- a/framework/src/suricata/src/detect-http-hrh.c +++ /dev/null @@ -1,2233 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements support for the http_raw_host keyword. - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "stream-tcp.h" -#include "detect-http-hrh.h" - -int DetectHttpHRHSetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpHRHRegisterTests(void); -void DetectHttpHRHFree(void *); - -/** - * \brief Registers the keyword handlers for the "http_raw_host" keyword. - */ -void DetectHttpHRHRegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].name = "http_raw_host"; - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].desc = "content modifier to match only on the HTTP host header or the raw hostname from the HTTP uri"; - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].Setup = DetectHttpHRHSetup; - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].Free = DetectHttpHRHFree; - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].RegisterTests = DetectHttpHRHRegisterTests; - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].alproto = ALPROTO_HTTP; - - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].flags |= SIGMATCH_NOOPT ; - sigmatch_table[DETECT_AL_HTTP_RAW_HOST].flags |= SIGMATCH_PAYLOAD ; - - return; -} - -/** - * \brief The setup function for the http_raw_host keyword for a signature. - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to the signature for the current Signature being - * parsed from the rules. - * \param m Pointer to the head of the SigMatch for the current rule - * being parsed. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 On success - * \retval -1 On failure - */ -int DetectHttpHRHSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_RAW_HOST, - DETECT_SM_LIST_HRHHDMATCH, - ALPROTO_HTTP, - NULL); -} - -/** - * \brief The function to free the http_raw_host data. - * - * \param ptr Pointer to the http_raw_host. - */ -void DetectHttpHRHFree(void *ptr) -{ - DetectContentData *hrhhd = (DetectContentData *)ptr; - if (hrhhd == NULL) - return; - - if (hrhhd->content != NULL) - SCFree(hrhhd->content); - - BoyerMooreCtxDeInit(hrhhd->bm_ctx); - SCFree(hrhhd); - - return; -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Test that a signature containting a http_raw_host is correctly parsed - * and the keyword is registered. - */ -static int DetectHttpHRHTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_host\"; " - "content:\"one\"; http_raw_host; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a signature containing an valid http_raw_host entry is - * parsed. - */ -static int DetectHttpHRHTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_host\"; " - "content:\"one\"; http_raw_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing no content but a - * http_raw_host is invalidated. - */ -static int DetectHttpHRHTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_host\"; " - "http_raw_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_raw_host is invalidated. - */ -static int DetectHttpHRHTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_host\"; " - "content:\"one\"; rawbytes; http_raw_host; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a http_raw_host with nocase is parsed. - */ -static int DetectHttpHRHTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_host\"; " - "content:\"one\"; http_raw_host; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - *\test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectHttpHRHTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy message body\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"message\"; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectHttpHRHTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy message"; - uint8_t http2_buf[] = - "body1\r\n\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"message\"; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectHttpHRHTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "host: This is dummy mess"; - uint8_t http2_buf[] = - "age body\r\n\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"message\"; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_raw_host content matches against a http request - * which holds the content, against a cross boundary present pattern. - */ -static int DetectHttpHRHTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy body1"; - uint8_t http2_buf[] = - "This is dummy message body2\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"body1This\"; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_raw_host content matches against a http request - * against a case insensitive pattern. - */ -static int DetectHttpHRHTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy bodY1"; - uint8_t http2_buf[] = - "This is dummy message body2\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy bodY1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"bodY1This\"; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the negated http_raw_host content matches against a - * http request which doesn't hold the content. - */ -static int DetectHttpHRHTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy message body\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:!\"message\"; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Negative test that the negated http_raw_host content matches against a - * http request which holds hold the content. - */ -static int DetectHttpHRHTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy body\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:!\"message\"; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_raw_host content matches against a http request - * which holds the content. - */ -static int DetectHttpHRHTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_raw_host; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test multiple http transactions and body chunks of request handling - */ -static int DetectHttpHRHTest14(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "Cookie: dummy1\r\n"; - uint8_t httpbuf3[] = "Host: Body one!!\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf5[] = "Cookie: dummy2\r\n"; - uint8_t httpbuf6[] = "Host: Body two\r\n\r\n"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"dummy1\"; http_cookie; content:\"Body one\"; http_raw_host; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"dummy2\"; http_cookie; content:\"Body two\"; http_raw_host; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2)) { - printf("sig 1 alerted (4): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) || !(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match or sig 1 matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - - - - - - - - -int DetectHttpHRHTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; content:\"two\"; http_raw_host; " - "content:\"three\"; distance:10; http_raw_host; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hrhhd1->content, "two", hrhhd1->content_len) != 0 || - hrhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd1) || - !DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hrhhd1) || - DETECT_CONTENT_IS_SINGLE(hrhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_raw_host; pcre:/two/; " - "content:\"three\"; distance:10; http_raw_host; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 || - hrhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hrhhd1) || - DETECT_CONTENT_IS_SINGLE(hrhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_raw_host; pcre:/two/; " - "content:\"three\"; distance:10; within:15; http_raw_host; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 || - hrhhd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hrhhd1) || - DETECT_CONTENT_IS_SINGLE(hrhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_raw_host; pcre:/two/; " - "content:\"three\"; distance:10; http_raw_host; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 || - hrhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hrhhd1) || - DETECT_CONTENT_IS_SINGLE(hrhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; offset:10; http_raw_host; pcre:/two/; " - "content:\"three\"; distance:10; http_raw_host; within:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT | DETECT_CONTENT_OFFSET) || - memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 || - hrhhd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) { - printf ("failed: http_raw_host incorrect flags"); - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hrhhd1) || - DETECT_CONTENT_IS_SINGLE(hrhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; offset:10; http_raw_host; pcre:/two/; " - "content:\"three\"; distance:10; http_raw_host; within:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest28(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_raw_host; nocase; pcre:/two/; " - "content:\"three\"; http_raw_host; depth:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hrhhd1->flags != (DETECT_CONTENT_NOCASE) || - memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 || - hrhhd2->flags != (DETECT_CONTENT_DEPTH) || - memcmp(hrhhd2->content, "three", hrhhd1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - !DETECT_CONTENT_IS_SINGLE(hrhhd1) || - DETECT_CONTENT_IS_SINGLE(hrhhd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest29(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_raw_host; " - "content:\"two\"; distance:0; http_raw_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 || - hrhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hrhhd2->content, "two", hrhhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest30(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_raw_host; " - "content:\"two\"; within:5; http_raw_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hrhhd1->content, "one", hrhhd1->content_len) != 0 || - hrhhd2->flags != (DETECT_CONTENT_WITHIN) || - memcmp(hrhhd2->content, "two", hrhhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest31(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; within:5; http_raw_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest32(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_raw_host; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list != NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest33(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest34(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(pcre:/one/Zi; " - "content:\"two\"; within:5; http_raw_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT | DETECT_PCRE_CASELESS) || - hrhhd2->flags != (DETECT_CONTENT_WITHIN) || - memcmp(hrhhd2->content, "two", hrhhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest35(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"two\"; http_raw_host; " - "pcre:/one/ZRi; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->type != DETECT_PCRE || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->type != DETECT_CONTENT) { - - goto end; - } - - DetectContentData *hrhhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (pd2->flags != (DETECT_PCRE_RELATIVE | DETECT_PCRE_CASELESS) || - hrhhd1->flags != (DETECT_CONTENT_RELATIVE_NEXT) || - memcmp(hrhhd1->content, "two", hrhhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpHRHTest36(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(pcre:/one/Zi; " - "content:\"two\"; distance:5; http_raw_host; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->prev->ctx; - DetectContentData *hrhhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT | DETECT_PCRE_CASELESS) || - hrhhd2->flags != (DETECT_CONTENT_DISTANCE) || - memcmp(hrhhd2->content, "two", hrhhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - *\test Test that the http_raw_host content matches against a http request - * against a case insensitive pattern. - */ -static int DetectHttpHRHTest37(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "User-Agent: www.openinfosecfoundation.org\r\n" - "Host: This is dummy bodY1"; - uint8_t http2_buf[] = - "This is dummy message body2\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy bodY1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http host test\"; " - "content:\"body1this\"; http_raw_host; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectHttpHRHRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectHttpHRHTest01", DetectHttpHRHTest01, 1); - UtRegisterTest("DetectHttpHRHTest02", DetectHttpHRHTest02, 1); - UtRegisterTest("DetectHttpHRHTest03", DetectHttpHRHTest03, 1); - UtRegisterTest("DetectHttpHRHTest04", DetectHttpHRHTest04, 1); - UtRegisterTest("DetectHttpHRHTest05", DetectHttpHRHTest05, 1); - UtRegisterTest("DetectHttpHRHTest06", DetectHttpHRHTest06, 1); - UtRegisterTest("DetectHttpHRHTest07", DetectHttpHRHTest07, 1); - UtRegisterTest("DetectHttpHRHTest08", DetectHttpHRHTest08, 1); - UtRegisterTest("DetectHttpHRHTest09", DetectHttpHRHTest09, 1); - UtRegisterTest("DetectHttpHRHTest10", DetectHttpHRHTest10, 1); - UtRegisterTest("DetectHttpHRHTest11", DetectHttpHRHTest11, 1); - UtRegisterTest("DetectHttpHRHTest12", DetectHttpHRHTest12, 1); - UtRegisterTest("DetectHttpHRHTest13", DetectHttpHRHTest13, 1); - UtRegisterTest("DetectHttpHRHTest14", DetectHttpHRHTest14, 1); - - UtRegisterTest("DetectHttpHRHTest22", DetectHttpHRHTest22, 1); - UtRegisterTest("DetectHttpHRHTest23", DetectHttpHRHTest23, 1); - UtRegisterTest("DetectHttpHRHTest24", DetectHttpHRHTest24, 1); - UtRegisterTest("DetectHttpHRHTest25", DetectHttpHRHTest25, 1); - UtRegisterTest("DetectHttpHRHTest26", DetectHttpHRHTest26, 1); - UtRegisterTest("DetectHttpHRHTest27", DetectHttpHRHTest27, 1); - UtRegisterTest("DetectHttpHRHTest28", DetectHttpHRHTest28, 1); - UtRegisterTest("DetectHttpHRHTest29", DetectHttpHRHTest29, 1); - UtRegisterTest("DetectHttpHRHTest30", DetectHttpHRHTest30, 1); - UtRegisterTest("DetectHttpHRHTest31", DetectHttpHRHTest31, 1); - UtRegisterTest("DetectHttpHRHTest32", DetectHttpHRHTest32, 1); - UtRegisterTest("DetectHttpHRHTest33", DetectHttpHRHTest33, 1); - UtRegisterTest("DetectHttpHRHTest34", DetectHttpHRHTest34, 1); - UtRegisterTest("DetectHttpHRHTest35", DetectHttpHRHTest35, 1); - UtRegisterTest("DetectHttpHRHTest36", DetectHttpHRHTest36, 1); - UtRegisterTest("DetectHttpHRHTest37", DetectHttpHRHTest37, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-hrh.h b/framework/src/suricata/src/detect-http-hrh.h deleted file mode 100644 index 0255f167..00000000 --- a/framework/src/suricata/src/detect-http-hrh.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_HTTP_HRH_H__ -#define __DETECT_HTTP_HRH_H__ - -void DetectHttpHRHRegister(void); - -#endif /* __DETECT_HTTP_HRH_H__ */ diff --git a/framework/src/suricata/src/detect-http-method.c b/framework/src/suricata/src/detect-http-method.c deleted file mode 100644 index 4cc8a787..00000000 --- a/framework/src/suricata/src/detect-http-method.c +++ /dev/null @@ -1,833 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Brian Rectanus - * - * Implements the http_method keyword - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "detect-http-method.h" -#include "stream-tcp.h" - - -static int DetectHttpMethodSetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpMethodRegisterTests(void); -void DetectHttpMethodFree(void *); - -/** - * \brief Registration function for keyword: http_method - */ -void DetectHttpMethodRegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_METHOD].name = "http_method"; - sigmatch_table[DETECT_AL_HTTP_METHOD].desc = "content modifier to match only on the HTTP method-buffer"; - sigmatch_table[DETECT_AL_HTTP_METHOD].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_method"; - sigmatch_table[DETECT_AL_HTTP_METHOD].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_METHOD].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_METHOD].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_AL_HTTP_METHOD].Setup = DetectHttpMethodSetup; - sigmatch_table[DETECT_AL_HTTP_METHOD].Free = DetectHttpMethodFree; - sigmatch_table[DETECT_AL_HTTP_METHOD].RegisterTests = DetectHttpMethodRegisterTests; - sigmatch_table[DETECT_AL_HTTP_METHOD].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_HTTP_METHOD].flags |= SIGMATCH_PAYLOAD; - - SCLogDebug("registering http_method rule option"); -} - -/** - * \brief This function is used to add the parsed "http_method" option - * into the current signature. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Current Signature. - * \param str Pointer to the user provided option string. - * - * \retval 0 on Success. - * \retval -1 on Failure. - */ -static int DetectHttpMethodSetup(DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, str, - DETECT_AL_HTTP_METHOD, - DETECT_SM_LIST_HMDMATCH, - ALPROTO_HTTP, - NULL); -} - -/** - * \brief this function will free memory associated with DetectContentData - * - * \param id_d pointer to DetectContentData - */ -void DetectHttpMethodFree(void *ptr) -{ - DetectContentData *data = (DetectContentData *)ptr; - - if (data->content != NULL) - SCFree(data->content); - SCFree(data); -} - -#ifdef UNITTESTS /* UNITTESTS */ - -#include "stream-tcp-reassemble.h" - -/** \test Check a signature with content */ -int DetectHttpMethodTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "content:\"GET\"; " - "http_method; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature without content (fail) */ -int DetectHttpMethodTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "http_method; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with parameter (fail) */ -int DetectHttpMethodTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "content:\"foobar\"; " - "http_method:\"GET\"; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with fast_pattern (should work) */ -int DetectHttpMethodTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "content:\"GET\"; " - "fast_pattern; " - "http_method; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with rawbytes (fail) */ -int DetectHttpMethodTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "content:\"GET\"; " - "rawbytes; " - "http_method; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test setting the nocase flag */ -static int DetectHttpMethodTest12(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any " - "(content:\"one\"; http_method; nocase; sid:1;)") == NULL) { - printf("DetectEngineAppend == NULL: "); - goto end; - } - if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any " - "(content:\"one\"; nocase; http_method; sid:2;)") == NULL) { - printf("DetectEngineAppend == NULL: "); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HMDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HMDMATCH] == NULL: "); - goto end; - } - - DetectContentData *hmd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - DetectContentData *hmd2 = (DetectContentData *)de_ctx->sig_list->next->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - - if (!(hmd1->flags & DETECT_CONTENT_NOCASE)) { - printf("nocase flag not set on sig 1: "); - goto end; - } - - if (!(hmd2->flags & DETECT_CONTENT_NOCASE)) { - printf("nocase flag not set on sig 2: "); - goto end; - } - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with method + within and pcre with /M (should work) */ -int DetectHttpMethodTest13(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "pcre:\"/HE/M\"; " - "content:\"AD\"; " - "within:2; http_method; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with method + within and pcre without /M (should fail) */ -int DetectHttpMethodTest14(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "pcre:\"/HE/\"; " - "content:\"AD\"; " - "http_method; within:2; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with method + within and pcre with /M (should work) */ -int DetectHttpMethodTest15(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "pcre:\"/HE/M\"; " - "content:\"AD\"; " - "http_method; within:2; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} -/** \test Check a signature with an known request method */ -static int DetectHttpMethodSigTest01(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n" - "Host: foo.bar.tld\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "content:\"GET\"; " - "http_method; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "content:\"POST\"; " - "http_method; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - SCLogDebug("no http state: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - goto end; - } - if (PacketAlertCheck(p, 2)) { - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check a signature with an unknown request method */ -static int DetectHttpMethodSigTest02(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "FOO / HTTP/1.0\r\n" - "Host: foo.bar.tld\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "content:\"FOO\"; " - "http_method; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "content:\"BAR\"; " - "http_method; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - SCLogDebug("no http state: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - goto end; - } - if (PacketAlertCheck(p, 2)) { - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check a signature against an unparsable request */ -static int DetectHttpMethodSigTest03(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = " "; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "content:\" \"; " - "http_method; sid:1;)"); - if (s == NULL) { - SCLogDebug("Bad signature"); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - SCLogDebug("no http state: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check a signature with an request method and negation of the same */ -static int DetectHttpMethodSigTest04(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n" - "Host: foo.bar.tld\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"Testing http_method\"; " - "content:\"GET\"; http_method; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx, - "alert tcp any any -> any any (msg:\"Testing http_method\"; " - "content:!\"GET\"; http_method; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - SCLogDebug("no http state: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sid 2 matched but shouldn't have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx); - } - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectHttpMethod - */ -void DetectHttpMethodRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - SCLogDebug("Registering tests for DetectHttpMethod..."); - UtRegisterTest("DetectHttpMethodTest01", DetectHttpMethodTest01, 1); - UtRegisterTest("DetectHttpMethodTest02", DetectHttpMethodTest02, 1); - UtRegisterTest("DetectHttpMethodTest03", DetectHttpMethodTest03, 1); - UtRegisterTest("DetectHttpMethodTest04", DetectHttpMethodTest04, 1); - UtRegisterTest("DetectHttpMethodTest05", DetectHttpMethodTest05, 1); - UtRegisterTest("DetectHttpMethodTest12 -- nocase flag", DetectHttpMethodTest12, 1); - UtRegisterTest("DetectHttpMethodTest13", DetectHttpMethodTest13, 1); - UtRegisterTest("DetectHttpMethodTest14", DetectHttpMethodTest14, 1); - UtRegisterTest("DetectHttpMethodTest15", DetectHttpMethodTest15, 1); - UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01, 1); - UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02, 1); - UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03, 1); - UtRegisterTest("DetectHttpMethodSigTest04", DetectHttpMethodSigTest04, 1); -#endif /* UNITTESTS */ -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-method.h b/framework/src/suricata/src/detect-http-method.h deleted file mode 100644 index 9e6dc4dd..00000000 --- a/framework/src/suricata/src/detect-http-method.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - */ - -#ifndef __DETECT_HTTP_METHOD_H__ -#define __DETECT_HTTP_METHOD_H__ - -/* prototypes */ -void DetectHttpMethodRegister(void); -int DetectHttpMethodDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, - Flow *, uint8_t, void *); - -#endif /* __DETECT_HTTP_METHOD_H__ */ - diff --git a/framework/src/suricata/src/detect-http-raw-header.c b/framework/src/suricata/src/detect-http-raw-header.c deleted file mode 100644 index 1a5f0eb2..00000000 --- a/framework/src/suricata/src/detect-http-raw-header.c +++ /dev/null @@ -1,1557 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Pablo Rincon - * - * Implements support for http_raw_header keyword. - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" -#include "util-print.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "detect-http-raw-header.h" -#include "stream-tcp.h" - -int DetectHttpRawHeaderSetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpRawHeaderRegisterTests(void); -void DetectHttpRawHeaderFree(void *); - -/** - * \brief Registers the keyword handlers for the "http_raw_header" keyword. - */ -void DetectHttpRawHeaderRegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].name = "http_raw_header"; - sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Setup = DetectHttpRawHeaderSetup; - sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Free = DetectHttpRawHeaderFree; - sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].RegisterTests = DetectHttpRawHeaderRegisterTests; - sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].alproto = ALPROTO_HTTP; - - sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].flags |= SIGMATCH_PAYLOAD; - - return; -} - - -/** - * \brief this function clears the memory of http_raw_header modifier keyword - * - * \param ptr Pointer to the Detection Header Data - */ -void DetectHttpRawHeaderFree(void *ptr) -{ - DetectContentData *cd = (DetectContentData *)ptr; - if (cd == NULL) - return; - - if (cd->content != NULL) - SCFree(cd->content); - SCFree(cd); - - return; -} - -/** - * \brief The setup function for the http_raw_header keyword for a signature. - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to signature for the current Signature being parsed - * from the rules. - * \param m Pointer to the head of the SigMatchs for the current rule - * being parsed. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectHttpRawHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_RAW_HEADER, - DETECT_SM_LIST_HRHDMATCH, - ALPROTO_HTTP, - NULL); -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Test that a signature containting a http_header is correctly parsed - * and the keyword is registered. - */ -static int DetectHttpRawHeaderTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - SigMatch *sm = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; flow:to_server; " - "content:\"one\"; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("Error parsing signature: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH]; - if (sm != NULL) { - result &= (sm->type == DETECT_CONTENT); - result &= (sm->next == NULL); - } else { - result = 0; - printf("Error updating content pattern to http_header pattern: "); - } - - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a signature containing an valid http_header entry is - * parsed. - */ -static int DetectHttpRawHeaderTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; flow:to_server; " - "content:\"one\"; http_raw_header:; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing no content but a http_header - * is invalidated. - */ -static int DetectHttpRawHeaderTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; flow:to_server; " - "http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_header is invalidated. - */ -static int DetectHttpRawHeaderTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; flow:to_server; " - "content:\"one\"; rawbytes; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_header is invalidated. - */ -static int DetectHttpRawHeaderTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; flow:to_server; " - "content:\"one\"; nocase; http_raw_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpRawHeaderTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"Content-Type: text/html\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpRawHeaderTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozi"; - uint8_t http2_buf[] = - "lla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\nContent-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n" - "This is dummy message body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"Mozilla\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ( (PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpRawHeaderTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n"; - uint8_t http2_buf[] = - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"Gecko/20091221 Firefox/3.5.7\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content, against a cross boundary present pattern. - */ -static int DetectHttpRawHeaderTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"; - uint8_t http2_buf[] = - "Content-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n" - "This is dummy body\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"Firefox/3.5.7|0D 0A|Content\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * against a case insensitive pattern. - */ -static int DetectHttpRawHeaderTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"; - uint8_t http2_buf[] = - "Content-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n" - "This is dummy body"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_raw_header;" - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the negated http_header content matches against a - * http request which doesn't hold the content. - */ -static int DetectHttpRawHeaderTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:!\"lalalalala\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Negative test that the negated http_header content matches against a - * http request which holds hold the content. - */ -static int DetectHttpRawHeaderTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:!\"User-Agent: Mozilla/5.0 \"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpRawHeaderTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 100\r\n" - "\r\n" - "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"Host: www.openinfosecfoundation.org\"; http_raw_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -int DetectHttpRawHeaderTest20(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; " - "content:\"two\"; distance:0; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hrhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - DetectContentData *hrhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (hrhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hrhd1->content, "one", hrhd1->content_len) != 0 || - hrhd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hrhd2->content, "two", hrhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawHeaderTest21(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; " - "content:\"two\"; within:5; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *hrhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - DetectContentData *hrhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (hrhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hrhd1->content, "one", hrhd1->content_len) != 0 || - hrhd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hrhd2->content, "two", hrhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawHeaderTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; within:5; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawHeaderTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawHeaderTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawHeaderTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; pcre:/one/D; " - "content:\"two\"; within:5; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hhd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hhd2->content, "two", hhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawHeaderTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; content:\"two\"; http_raw_header; " - "pcre:/one/DR; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->type != DETECT_PCRE || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->type != DETECT_CONTENT) { - - goto end; - } - - DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (pd2->flags != (DETECT_PCRE_RELATIVE) || - hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hhd1->content, "two", hhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawHeaderTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(flow:to_server; pcre:/one/D; " - "content:\"two\"; distance:5; http_raw_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hhd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hhd2->content, "two", hhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -void DetectHttpRawHeaderRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectHttpRawHeaderTest01", DetectHttpRawHeaderTest01, 1); - UtRegisterTest("DetectHttpRawHeaderTest02", DetectHttpRawHeaderTest02, 1); - UtRegisterTest("DetectHttpRawHeaderTest03", DetectHttpRawHeaderTest03, 1); - UtRegisterTest("DetectHttpRawHeaderTest04", DetectHttpRawHeaderTest04, 1); - UtRegisterTest("DetectHttpRawHeaderTest05", DetectHttpRawHeaderTest05, 1); - UtRegisterTest("DetectHttpRawHeaderTest06", DetectHttpRawHeaderTest06, 1); - UtRegisterTest("DetectHttpRawHeaderTest07", DetectHttpRawHeaderTest07, 1); - UtRegisterTest("DetectHttpRawHeaderTest08", DetectHttpRawHeaderTest08, 1); - UtRegisterTest("DetectHttpRawHeaderTest09", DetectHttpRawHeaderTest09, 1); - UtRegisterTest("DetectHttpRawHeaderTest10", DetectHttpRawHeaderTest10, 1); - UtRegisterTest("DetectHttpRawHeaderTest11", DetectHttpRawHeaderTest11, 1); - UtRegisterTest("DetectHttpRawHeaderTest12", DetectHttpRawHeaderTest12, 1); - UtRegisterTest("DetectHttpRawHeaderTest13", DetectHttpRawHeaderTest13, 1); - UtRegisterTest("DetectHttpRawHeaderTest20", DetectHttpRawHeaderTest20, 1); - UtRegisterTest("DetectHttpRawHeaderTest21", DetectHttpRawHeaderTest21, 1); - UtRegisterTest("DetectHttpRawHeaderTest22", DetectHttpRawHeaderTest22, 1); - UtRegisterTest("DetectHttpRawHeaderTest23", DetectHttpRawHeaderTest23, 1); - UtRegisterTest("DetectHttpRawHeaderTest24", DetectHttpRawHeaderTest24, 1); - UtRegisterTest("DetectHttpRawHeaderTest25", DetectHttpRawHeaderTest25, 1); - UtRegisterTest("DetectHttpRawHeaderTest26", DetectHttpRawHeaderTest26, 1); - UtRegisterTest("DetectHttpRawHeaderTest27", DetectHttpRawHeaderTest27, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-raw-header.h b/framework/src/suricata/src/detect-http-raw-header.h deleted file mode 100644 index f6b480b2..00000000 --- a/framework/src/suricata/src/detect-http-raw-header.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_HTTP_RAW_HEADER_H__ -#define __DETECT_HTTP_RAW_HEADER_H__ - -void DetectHttpRawHeaderRegister(void); - -#endif /* __DETECT_HTTP_RAW_HEADER_H__ */ diff --git a/framework/src/suricata/src/detect-http-raw-uri.c b/framework/src/suricata/src/detect-http-raw-uri.c deleted file mode 100644 index e269686e..00000000 --- a/framework/src/suricata/src/detect-http-raw-uri.c +++ /dev/null @@ -1,566 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-spm.h" -#include "util-print.h" - -#include "app-layer.h" - -#include "app-layer-htp.h" -#include "detect-http-raw-uri.h" -#include "stream-tcp.h" - -static int DetectHttpRawUriSetup(DetectEngineCtx *, Signature *, char *); -static void DetectHttpRawUriRegisterTests(void); - -/** - * \brief Registration function for keyword http_raw_uri. - */ -void DetectHttpRawUriRegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_RAW_URI].name = "http_raw_uri"; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].desc = "content modifier to match on HTTP uri"; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_uri-and-http_raw_uri"; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].Setup = DetectHttpRawUriSetup; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].Free = NULL; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].RegisterTests = DetectHttpRawUriRegisterTests; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_HTTP_RAW_URI].flags |= SIGMATCH_PAYLOAD; - - return; -} - -/** - * \brief Sets up the http_raw_uri modifier keyword. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Signature to which the current keyword belongs. - * \param arg Should hold an empty string always. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int DetectHttpRawUriSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_RAW_URI, - DETECT_SM_LIST_HRUDMATCH, - ALPROTO_HTTP, - NULL); -} - - -/******************************** UNITESTS **********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Checks if a http_raw_uri is registered in a Signature, if content is not - * specified in the signature. - */ -int DetectHttpRawUriTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_uri\"; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_raw_uri is registered in a Signature, if some parameter - * is specified with http_raw_uri in the signature. - */ -int DetectHttpRawUriTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_uri\"; content:\"one\"; " - "http_raw_uri:wrong; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_raw_uri is registered in a Signature. - */ -int DetectHttpRawUriTest03(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_uri\"; " - "content:\"one\"; http_raw_uri; " - "content:\"two\"; http_raw_uri; " - "content:\"three\"; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH]; - if (sm == NULL) { - printf("no sigmatch(es): "); - goto end; - } - - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - result = 1; - } else { - printf("expected DETECT_CONTENT for http_raw_uri(%d), got %d: ", - DETECT_CONTENT, sm->type); - goto end; - } - sm = sm->next; - } - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_raw_uri is registered in a Signature, when rawbytes is - * also specified in the signature. - */ -int DetectHttpRawUriTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_uri\"; " - "content:\"one\"; rawbytes; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_raw_uri is successfully converted to a rawuricontent. - * - */ -int DetectHttpRawUriTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - Signature *s = NULL; - int result = 0; - - if ((de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_raw_uri\"; " - "content:\"we are testing http_raw_uri keyword\"; http_raw_uri; " - "sid:1;)"); - if (s == NULL) { - printf("sig failed to parse\n"); - goto end; - } - if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) - goto end; - if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH]->type != DETECT_CONTENT) { - printf("wrong type\n"); - goto end; - } - - char *str = "we are testing http_raw_uri keyword"; - int uricomp = memcmp((const char *) - ((DetectContentData*)s->sm_lists[DETECT_SM_LIST_HRUDMATCH]->ctx)->content, - str, - strlen(str) - 1); - int urilen = ((DetectContentData*)s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx)->content_len; - if (uricomp != 0 || - urilen != strlen("we are testing http_raw_uri keyword")) { - printf("sig failed to parse, content not setup properly\n"); - goto end; - } - result = 1; - -end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - return result; -} - -int DetectHttpRawUriTest12(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; distance:0; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *ud1 = - (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - DetectContentData *ud2 = - (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(ud1->content, "one", ud1->content_len) != 0 || - ud2->flags != DETECT_CONTENT_DISTANCE || - memcmp(ud2->content, "two", ud1->content_len) != 0) { - /* inside body */ - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawUriTest13(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; within:5; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *ud1 = - (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - DetectContentData *ud2 = - (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(ud1->content, "one", ud1->content_len) != 0 || - ud2->flags != DETECT_CONTENT_WITHIN || - memcmp(ud2->content, "two", ud1->content_len) != 0) { - /* inside the body */ - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawUriTest14(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawUriTest15(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawUriTest16(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawUriTest17(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; distance:0; http_raw_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *ud1 = - (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - DetectContentData *ud2 = - (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(ud1->content, "one", ud1->content_len) != 0 || - ud2->flags != DETECT_CONTENT_DISTANCE || - memcmp(ud2->content, "two", ud1->content_len) != 0) { - /* inside body */ - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpRawUriTest18(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_raw_uri; " - "content:\"two\"; within:5; http_raw_uri; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRUDMATCH] == NULL\n"); - goto end; - } - - DetectContentData *ud1 = - (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->prev->ctx; - DetectContentData *ud2 = - (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH]->ctx; - if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(ud1->content, "one", ud1->content_len) != 0 || - ud2->flags != DETECT_CONTENT_WITHIN || - memcmp(ud2->content, "two", ud1->content_len) != 0) { - /* inside body */ - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief Register the UNITTESTS for the http_uri keyword - */ -static void DetectHttpRawUriRegisterTests (void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectHttpRawUriTest01", DetectHttpRawUriTest01, 1); - UtRegisterTest("DetectHttpRawUriTest02", DetectHttpRawUriTest02, 1); - UtRegisterTest("DetectHttpRawUriTest03", DetectHttpRawUriTest03, 1); - UtRegisterTest("DetectHttpRawUriTest04", DetectHttpRawUriTest04, 1); - UtRegisterTest("DetectHttpRawUriTest05", DetectHttpRawUriTest05, 1); - UtRegisterTest("DetectHttpRawUriTest12", DetectHttpRawUriTest12, 1); - UtRegisterTest("DetectHttpRawUriTest13", DetectHttpRawUriTest13, 1); - UtRegisterTest("DetectHttpRawUriTest14", DetectHttpRawUriTest14, 1); - UtRegisterTest("DetectHttpRawUriTest15", DetectHttpRawUriTest15, 1); - UtRegisterTest("DetectHttpRawUriTest16", DetectHttpRawUriTest16, 1); - UtRegisterTest("DetectHttpRawUriTest17", DetectHttpRawUriTest17, 1); - UtRegisterTest("DetectHttpRawUriTest18", DetectHttpRawUriTest18, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-raw-uri.h b/framework/src/suricata/src/detect-http-raw-uri.h deleted file mode 100644 index 805adfbe..00000000 --- a/framework/src/suricata/src/detect-http-raw-uri.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - */ - -#ifndef __DETECT_HTTP_URI_H__ -#define __DETECT_HTTP_URI_H__ - -void DetectHttpRawUriRegister(void); - -#endif /* __DETECT_HTTP_URI_H__ */ diff --git a/framework/src/suricata/src/detect-http-server-body.c b/framework/src/suricata/src/detect-http-server-body.c deleted file mode 100644 index a5463b66..00000000 --- a/framework/src/suricata/src/detect-http-server-body.c +++ /dev/null @@ -1,3873 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Anoop Saldanha - * \author Victor Julien - * - * Implements support for the http_server_body keyword - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "detect-http-server-body.h" -#include "stream-tcp.h" - -int DetectHttpServerBodySetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpServerBodyRegisterTests(void); -void DetectHttpServerBodyFree(void *); - -/** - * \brief Registers the keyword handlers for the "http_server_body" keyword. - */ -void DetectHttpServerBodyRegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].name = "http_server_body"; - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].desc = "content modifier to match only on the HTTP response-body"; - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_server_body"; - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].Setup = DetectHttpServerBodySetup; - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].Free = DetectHttpServerBodyFree; - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].RegisterTests = DetectHttpServerBodyRegisterTests; - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].alproto = ALPROTO_HTTP; - - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_HTTP_SERVER_BODY].flags |= SIGMATCH_PAYLOAD ; -} - -static void DetectHttpServerBodySetupCallback(Signature *s) -{ - s->flags |= SIG_FLAG_APPLAYER; - AppLayerHtpEnableResponseBodyCallback(); - - return; -} - -/** - * \brief The setup function for the http_server_body keyword for a signature. - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to signature for the current Signature being parsed - * from the rules. - * \param m Pointer to the head of the SigMatchs for the current rule - * being parsed. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 On success - * \retval -1 On failure - */ -int DetectHttpServerBodySetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_SERVER_BODY, - DETECT_SM_LIST_FILEDATA, - ALPROTO_HTTP, - DetectHttpServerBodySetupCallback); -} - -/** - * \brief The function to free the http_server_body data. - * - * \param ptr Pointer to the http_server_body. - */ -void DetectHttpServerBodyFree(void *ptr) -{ - SCEnter(); - DetectContentData *hsbd = (DetectContentData *)ptr; - if (hsbd == NULL) - SCReturn; - - if (hsbd->content != NULL) - SCFree(hsbd->content); - - BoyerMooreCtxDeInit(hsbd->bm_ctx); - SCFree(hsbd); - - SCReturn; -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Test that a signature containting a http_server_body is correctly parsed - * and the keyword is registered. - */ -static int DetectHttpServerBodyTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - SigMatch *sm = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_server_body\"; " - "content:\"one\"; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - /* sm should not be in the MATCH list */ - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_MATCH]; - if (sm != NULL) { - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm == NULL) { - goto end; - } - - if (sm->type != DETECT_CONTENT) { - printf("sm type not DETECT_AL_HTTP_SERVER_BODY: "); - goto end; - } - - if (sm->next != NULL) { - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a signature containing an valid http_server_body entry is - * parsed. - */ -static int DetectHttpServerBodyTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_server_body\"; " - "content:\"one\"; http_server_body:; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing no content but a http_server_body - * is invalidated. - */ -static int DetectHttpServerBodyTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_server_body\"; " - "http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_server_body is invalidated. - */ -static int DetectHttpServerBodyTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_server_body\"; " - "content:\"one\"; rawbytes; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_server_body is invalidated. - */ -static int DetectHttpServerBodyTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_server_body\"; " - "content:\"one\"; http_server_body; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. - */ -static int DetectHttpServerBodyTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 7\r\n" - "\r\n" - "message"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"message\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START|STREAM_EOF, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. - */ -static int DetectHttpServerBodyTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n" - "message"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "message"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"message\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched on chunk2 but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 (chunk3) but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. - */ -static int DetectHttpServerBodyTest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n" - "bigmes"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "sage4u!!"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:\"message\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. - */ -static int DetectHttpServerBodyTest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n" - "bigmes"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "sag"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - uint8_t http_buf4[] = - "e4u!!"; - uint32_t http_len4 = sizeof(http_buf4) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:\"message\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf4, http_len4); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. Case insensitve. - */ -static int DetectHttpServerBodyTest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n" - "bigmes"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "sag"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - uint8_t http_buf4[] = - "e4u!!"; - uint32_t http_len4 = sizeof(http_buf4) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:\"MeSSaGE\"; http_server_body; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf4, http_len4); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. Negated match. - */ -static int DetectHttpServerBodyTest11(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "bigmessage4u!!"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:!\"MaSSaGE\"; http_server_body; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have (p1): "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have (p2): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. Negated match. - */ -static int DetectHttpServerBodyTest12(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "bigmessage4u!!"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "content:!\"MeSSaGE\"; http_server_body; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have (p1): "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have (p2): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectHttpServerBodyTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 55\r\n" - "\r\n" - "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "content:\"longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\"; http_server_body; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START|STREAM_EOF, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test multiple http transactions and body chunks of request handling */ -static int DetectHttpServerBodyTest14(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "GET /index1.html HTTP/1.1\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Connection: keep-alive\r\n" - "Cookie: dummy1\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.1 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 3\r\n" - "\r\n" - "one"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint8_t httpbuf3[] = "GET /index2.html HTTP/1.1\r\n" - "User-Agent: Firefox/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Connection: keep-alive\r\n" - "Cookie: dummy2\r\n\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "HTTP/1.1 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 3\r\n" - "\r\n" - "two"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:established,to_client; content:\"one\"; http_server_body; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:established,to_client; content:\"two\"; http_server_body; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCLogDebug("add chunk 1"); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - SCLogDebug("add chunk 2"); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCLogDebug("inspect chunk 1"); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert (tx 1): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("add chunk 3"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - SCLogDebug("add chunk 4"); - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SCLogDebug("inspect chunk 4"); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1))) { - printf("sig 1 alerted (tx 2): "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sig 2 didn't alert (tx 2): "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int DetectHttpServerBodyTest15(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "GET /index1.html HTTP/1.1\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Connection: keep-alive\r\n" - "Cookie: dummy1\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.1 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 3\r\n" - "\r\n" - "one"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint8_t httpbuf3[] = "GET /index2.html HTTP/1.1\r\n" - "User-Agent: Firefox/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Connection: keep-alive\r\n" - "Cookie: dummy2\r\n\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "HTTP/1.1 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 3\r\n" - "\r\n" - "two"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:established,to_client; content:\"one\"; http_server_body; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:established,to_client; content:\"two\"; http_server_body; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert (tx 1): "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sig 2 alerted (tx 1): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1))) { - printf("sig 1 alerted (tx 2): "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sig 2 didn't alert (tx 2): "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -int DetectHttpServerBodyTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; content:\"two\"; http_server_body; " - "content:\"three\"; distance:10; http_server_body; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hsbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hsbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hsbd1->content, "two", hsbd1->content_len) != 0 || - hsbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hsbd2->content, "three", hsbd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd1) || - !DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hsbd1) || - DETECT_CONTENT_IS_SINGLE(hsbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; pcre:/two/; " - "content:\"three\"; distance:10; http_server_body; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hsbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hsbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hsbd1->content, "one", hsbd1->content_len) != 0 || - hsbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hsbd2->content, "three", hsbd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hsbd1) || - DETECT_CONTENT_IS_SINGLE(hsbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; pcre:/two/; " - "content:\"three\"; distance:10; within:15; http_server_body; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hsbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - hsbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hsbd1->content, "one", hsbd1->content_len) != 0 || - hsbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(hsbd2->content, "three", hsbd1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hsbd1) || - DETECT_CONTENT_IS_SINGLE(hsbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; pcre:/two/; " - "content:\"three\"; distance:10; http_server_body; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hsbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hsbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hsbd1->content, "one", hsbd1->content_len) != 0 || - hsbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hsbd2->content, "three", hsbd1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hsbd1) || - DETECT_CONTENT_IS_SINGLE(hsbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; offset:10; http_server_body; pcre:/two/; " - "content:\"three\"; distance:10; http_server_body; within:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hsbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hsbd1->flags != (DETECT_CONTENT_RELATIVE_NEXT | DETECT_CONTENT_OFFSET) || - memcmp(hsbd1->content, "one", hsbd1->content_len) != 0 || - hsbd2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(hsbd2->content, "three", hsbd1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(hsbd1) || - DETECT_CONTENT_IS_SINGLE(hsbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test invalid combination for content: distance, depth, http_server_body */ -int DetectHttpServerBodyTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; offset:10; http_server_body; pcre:/two/; distance:10; " - "content:\"three\"; distance:10; http_server_body; depth:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list != NULL) { - printf("de_ctx->sig_list != NULL: "); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest28(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; pcre:/two/; " - "content:\"three\"; http_server_body; depth:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *hsbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - hsbd1->flags != 0 || - memcmp(hsbd1->content, "one", hsbd1->content_len) != 0 || - hsbd2->flags != DETECT_CONTENT_DEPTH || - memcmp(hsbd2->content, "three", hsbd1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - !DETECT_CONTENT_IS_SINGLE(hsbd1) || - DETECT_CONTENT_IS_SINGLE(hsbd2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest29(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; distance:0; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - DetectContentData *hsbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (hsbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hsbd1->content, "one", hsbd1->content_len) != 0 || - hsbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hsbd2->content, "two", hsbd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest30(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; " - "content:\"two\"; within:5; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - DetectContentData *hsbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (hsbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hsbd1->content, "one", hsbd1->content_len) != 0 || - hsbd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hsbd2->content, "two", hsbd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest31(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest32(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_server_body; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest33(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest34(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(pcre:/one/Q; " - "content:\"two\"; within:5; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hsbd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hsbd2->content, "two", hsbd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest35(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_server_body; " - "pcre:/one/QR; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_PCRE || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->type != DETECT_CONTENT) { - - goto end; - } - - DetectContentData *hsbd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (pd2->flags != (DETECT_PCRE_RELATIVE) || - hsbd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hsbd1->content, "two", hsbd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpServerBodyTest36(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(pcre:/one/Q; " - "content:\"two\"; distance:5; http_server_body; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->prev->ctx; - DetectContentData *hsbd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hsbd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hsbd2->content, "two", hsbd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. - */ -static int DetectHttpServerBodyFileDataTest01(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 7\r\n" - "\r\n" - "message"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "file_data; content:\"message\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START|STREAM_EOF, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. - */ -static int DetectHttpServerBodyFileDataTest02(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n" - "message"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "message"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "file_data; content:\"message\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but should have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. - */ -static int DetectHttpServerBodyFileDataTest03(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n" - "bigmes"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "sage4u!!"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "file_data; content:\"message\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. - */ -static int DetectHttpServerBodyFileDataTest04(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n" - "bigmes"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "sag"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - uint8_t http_buf4[] = - "e4u!!"; - uint32_t http_len4 = sizeof(http_buf4) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "file_data; content:\"message\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf4, http_len4); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. Case insensitve. - */ -static int DetectHttpServerBodyFileDataTest05(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n" - "bigmes"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "sag"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - uint8_t http_buf4[] = - "e4u!!"; - uint32_t http_len4 = sizeof(http_buf4) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "file_data; content:\"MeSSaGE\"; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 matched but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf4, http_len4); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. Negated match. - */ -static int DetectHttpServerBodyFileDataTest06(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "bigmessage4u!!"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http file_data test\"; " - "file_data; content:!\"MaSSaGE\"; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have (p1): "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have (p2): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_server_body content matches against a http request - * which holds the content. Negated match. - */ -static int DetectHttpServerBodyFileDataTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf1[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len1 = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 14\r\n" - "\r\n"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - uint8_t http_buf3[] = - "bigmessage4u!!"; - uint32_t http_len3 = sizeof(http_buf3) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOCLIENT; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOCLIENT; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http file_data test\"; " - "file_data; content:!\"MeSSaGE\"; nocase; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, http_buf1, http_len1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched but shouldn't have (p1): "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, http_buf3, http_len3); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have (p2): "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -static int DetectHttpServerBodyFileDataTest08(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 55\r\n" - "\r\n" - "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend"; - uint32_t http_len2 = sizeof(http_buf2) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http server body test\"; " - "file_data; content:\"longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_START|STREAM_EOF, http_buf2, http_len2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test multiple http transactions and body chunks of request handling */ -static int DetectHttpServerBodyFileDataTest09(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "GET /index1.html HTTP/1.1\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Connection: keep-alive\r\n" - "Cookie: dummy1\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.1 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 3\r\n" - "\r\n" - "one"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint8_t httpbuf3[] = "GET /index2.html HTTP/1.1\r\n" - "User-Agent: Firefox/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Connection: keep-alive\r\n" - "Cookie: dummy2\r\n\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "HTTP/1.1 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 3\r\n" - "\r\n" - "two"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:established,to_client; file_data; content:\"one\"; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:established,to_client; file_data; content:\"two\"; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert (tx 1): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1))) { - printf("sig 1 alerted (tx 2): "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sig 2 didn't alert (tx 2): "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -static int DetectHttpServerBodyFileDataTest10(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "GET /index1.html HTTP/1.1\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Connection: keep-alive\r\n" - "Cookie: dummy1\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.1 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 3\r\n" - "\r\n" - "one"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint8_t httpbuf3[] = "GET /index2.html HTTP/1.1\r\n" - "User-Agent: Firefox/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "Connection: keep-alive\r\n" - "Cookie: dummy2\r\n\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "HTTP/1.1 200 ok\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 3\r\n" - "\r\n" - "two"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:established,to_client; file_data; content:\"one\"; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:established,to_client; file_data; content:\"two\"; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert (tx 1): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT|STREAM_EOF, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1))) { - printf("sig 1 alerted (tx 2): "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sig 2 didn't alert (tx 2): "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -#endif /* UNITTESTS */ - -void DetectHttpServerBodyRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectHttpServerBodyTest01", DetectHttpServerBodyTest01, 1); - UtRegisterTest("DetectHttpServerBodyTest02", DetectHttpServerBodyTest02, 1); - UtRegisterTest("DetectHttpServerBodyTest03", DetectHttpServerBodyTest03, 1); - UtRegisterTest("DetectHttpServerBodyTest04", DetectHttpServerBodyTest04, 1); - UtRegisterTest("DetectHttpServerBodyTest05", DetectHttpServerBodyTest05, 1); - UtRegisterTest("DetectHttpServerBodyTest06", DetectHttpServerBodyTest06, 1); - UtRegisterTest("DetectHttpServerBodyTest07", DetectHttpServerBodyTest07, 1); - UtRegisterTest("DetectHttpServerBodyTest08", DetectHttpServerBodyTest08, 1); - UtRegisterTest("DetectHttpServerBodyTest09", DetectHttpServerBodyTest09, 1); - UtRegisterTest("DetectHttpServerBodyTest10", DetectHttpServerBodyTest10, 1); - UtRegisterTest("DetectHttpServerBodyTest11", DetectHttpServerBodyTest11, 1); - UtRegisterTest("DetectHttpServerBodyTest12", DetectHttpServerBodyTest12, 1); - UtRegisterTest("DetectHttpServerBodyTest13", DetectHttpServerBodyTest13, 1); - UtRegisterTest("DetectHttpServerBodyTest14", DetectHttpServerBodyTest14, 1); - UtRegisterTest("DetectHttpServerBodyTest15", DetectHttpServerBodyTest15, 1); - UtRegisterTest("DetectHttpServerBodyTest22", DetectHttpServerBodyTest22, 1); - UtRegisterTest("DetectHttpServerBodyTest23", DetectHttpServerBodyTest23, 1); - UtRegisterTest("DetectHttpServerBodyTest24", DetectHttpServerBodyTest24, 1); - UtRegisterTest("DetectHttpServerBodyTest25", DetectHttpServerBodyTest25, 1); - UtRegisterTest("DetectHttpServerBodyTest26", DetectHttpServerBodyTest26, 1); - UtRegisterTest("DetectHttpServerBodyTest27", DetectHttpServerBodyTest27, 1); - UtRegisterTest("DetectHttpServerBodyTest28", DetectHttpServerBodyTest28, 1); - UtRegisterTest("DetectHttpServerBodyTest29", DetectHttpServerBodyTest29, 1); - UtRegisterTest("DetectHttpServerBodyTest30", DetectHttpServerBodyTest30, 1); - UtRegisterTest("DetectHttpServerBodyTest31", DetectHttpServerBodyTest31, 1); - UtRegisterTest("DetectHttpServerBodyTest32", DetectHttpServerBodyTest32, 1); - UtRegisterTest("DetectHttpServerBodyTest33", DetectHttpServerBodyTest33, 1); - UtRegisterTest("DetectHttpServerBodyTest34", DetectHttpServerBodyTest34, 1); - UtRegisterTest("DetectHttpServerBodyTest35", DetectHttpServerBodyTest35, 1); - UtRegisterTest("DetectHttpServerBodyTest36", DetectHttpServerBodyTest36, 1); - - UtRegisterTest("DetectHttpServerBodyFileDataTest01", DetectHttpServerBodyFileDataTest01, 1); - UtRegisterTest("DetectHttpServerBodyFileDataTest02", DetectHttpServerBodyFileDataTest02, 1); - UtRegisterTest("DetectHttpServerBodyFileDataTest03", DetectHttpServerBodyFileDataTest03, 1); - UtRegisterTest("DetectHttpServerBodyFileDataTest04", DetectHttpServerBodyFileDataTest04, 1); - UtRegisterTest("DetectHttpServerBodyFileDataTest05", DetectHttpServerBodyFileDataTest05, 1); - UtRegisterTest("DetectHttpServerBodyFileDataTest06", DetectHttpServerBodyFileDataTest06, 1); - UtRegisterTest("DetectHttpServerBodyFileDataTest07", DetectHttpServerBodyFileDataTest07, 1); - UtRegisterTest("DetectHttpServerBodyFileDataTest08", DetectHttpServerBodyFileDataTest08, 1); - UtRegisterTest("DetectHttpServerBodyFileDataTest09", DetectHttpServerBodyFileDataTest09, 1); - UtRegisterTest("DetectHttpServerBodyFileDataTest10", DetectHttpServerBodyFileDataTest10, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-server-body.h b/framework/src/suricata/src/detect-http-server-body.h deleted file mode 100644 index 7f20dc54..00000000 --- a/framework/src/suricata/src/detect-http-server-body.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_HTTP_SERVER_BODY_H__ -#define __DETECT_HTTP_SERVER_BODY_H__ - -void DetectHttpServerBodyRegister(void); - -#endif /* __DETECT_HTTP_SERVER_BODY_H__ */ diff --git a/framework/src/suricata/src/detect-http-stat-code.c b/framework/src/suricata/src/detect-http-stat-code.c deleted file mode 100644 index 0237009f..00000000 --- a/framework/src/suricata/src/detect-http-stat-code.c +++ /dev/null @@ -1,688 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Gurvinder Singh - * \author Anoop Saldanha - * - * Implements the http_stat_code keyword - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-content.h" -#include "detect-pcre.h" -#include "detect-engine-mpm.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-error.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" -#include "util-print.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "detect-http-stat-code.h" -#include "stream-tcp-private.h" -#include "stream-tcp.h" - -int DetectHttpStatCodeMatch(ThreadVars *, DetectEngineThreadCtx *, - Flow *, uint8_t , void *, Signature *, - SigMatch *); -static int DetectHttpStatCodeSetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpStatCodeRegisterTests(void); -void DetectHttpStatCodeFree(void *); - -/** - * \brief Registration function for keyword: http_stat_code - */ -void DetectHttpStatCodeRegister (void) -{ - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].name = "http_stat_code"; - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].desc = "content modifier to match only on HTTP stat-code-buffer"; - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_stat_code"; - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].Setup = DetectHttpStatCodeSetup; - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].Free = NULL; - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].RegisterTests = DetectHttpStatCodeRegisterTests; - - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_HTTP_STAT_CODE].flags |= SIGMATCH_PAYLOAD; -} - -/** - * \brief this function setups the http_stat_code modifier keyword used in the rule - * - * \param de_ctx Pointer to the Detection Engine Context - * \param s Pointer to the Signature to which the current keyword belongs - * \param str Should hold an empty string always - * - * \retval 0 On success - * \retval -1 On failure - */ - -static int DetectHttpStatCodeSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_STAT_CODE, - DETECT_SM_LIST_HSCDMATCH, - ALPROTO_HTTP, - NULL); -} - -#ifdef UNITTESTS - -/** - * \test Checks if a http_stat_code is registered in a Signature, if content is not - * specified in the signature or rawbyes is specified or fast_pattern is - * provided in the signature. - */ -int DetectHttpStatCodeTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ((de_ctx = DetectEngineCtxInit()) == NULL) { - printf("DetectEngineCtxInit failed: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_code\"; http_stat_code; sid:1;)"); - if (de_ctx->sig_list != NULL) { - printf("sid 1 parse failed to error out: "); - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_code\"; content:\"|FF F1|\";" - " rawbytes; http_stat_code; sid:2;)"); - if (de_ctx->sig_list != NULL) { - printf("sid 2 parse failed to error out: "); - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_code\"; content:\"100\";" - "fast_pattern; http_stat_code; sid:3;)"); - if (de_ctx->sig_list == NULL) { - printf("sid 3 parse failed: "); - goto end; - } - if (!(((DetectContentData *)de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSCDMATCH]->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN)) - { - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_stat_code is registered in a Signature and also checks - * the nocase - */ -int DetectHttpStatCodeTest02(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_code\"; content:\"one\"; " - "http_stat_code; content:\"200\"; http_stat_code; " - "content:\"two hundred\"; nocase; http_stat_code; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSCDMATCH]; - if (sm == NULL) { - printf("no sigmatch(es): "); - goto end; - } - - SigMatch *prev = NULL; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - result = 1; - } else { - printf("expected DETECT_CONTENT for http_stat_code, got %d: ", sm->type); - goto end; - } - prev = sm; - sm = sm->next; - } - - if (! (((DetectContentData *)prev->ctx)->flags & - DETECT_CONTENT_NOCASE)) - { - result = 0; - } -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check the signature working to alert when http_stat_code is matched . */ -static int DetectHttpStatCodeSigTest01(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("DetectEngineCtxInit failed: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status code\"; content:\"200\"; http_stat_code; sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_stat_code is not matched . */ -static int DetectHttpStatCodeSigTest02(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status code\"; content:\"no\"; " - "http_stat_code; sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " - "Status code\"; content:\"100\";" - "http_stat_code; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't: "); - goto end; - } - if ((PacketAlertCheck(p, 2))) { - printf("sid 2 match but shouldn't have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_stat_code is matched for - * for nocase or not */ -static int DetectHttpStatCodeSigTest03(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 FAIL OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status code\"; content:\"FAIL\"; " - "http_stat_code; sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " - "Status code nocase\"; content:\"fail\"; nocase; " - "http_stat_code; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_stat_code is matched for - * for negatoin or not */ -static int DetectHttpStatCodeSigTest04(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status code\"; content:\"200\"; " - "http_stat_code; sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " - "Status code negation\"; content:!\"100\"; nocase; " - "http_stat_code; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief Register the UNITTESTS for the http_stat_code keyword - */ -void DetectHttpStatCodeRegisterTests (void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - - UtRegisterTest("DetectHttpStatCodeTest01", DetectHttpStatCodeTest01, 1); - UtRegisterTest("DetectHttpStatCodeTest02", DetectHttpStatCodeTest02, 1); - UtRegisterTest("DetectHttpStatCodeSigTest01", DetectHttpStatCodeSigTest01, 1); - UtRegisterTest("DetectHttpStatCodeSigTest02", DetectHttpStatCodeSigTest02, 1); - UtRegisterTest("DetectHttpStatCodeSigTest03", DetectHttpStatCodeSigTest03, 1); - UtRegisterTest("DetectHttpStatCodeSigTest04", DetectHttpStatCodeSigTest04, 1); - -#endif /* UNITTESTS */ -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-stat-code.h b/framework/src/suricata/src/detect-http-stat-code.h deleted file mode 100644 index 811c6951..00000000 --- a/framework/src/suricata/src/detect-http-stat-code.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - */ - -#ifndef _DETECT_HTTP_STAT_CODE_H -#define _DETECT_HTTP_STAT_CODE_H - -/* prototypes */ -int DetectHttpStatCodeMatch (ThreadVars *, DetectEngineThreadCtx *, - Flow *, uint8_t , void *, Signature *, - SigMatch *); -void DetectHttpStatCodeRegister(void); - -#endif /* _DETECT_HTTP_STAT_CODE_H */ - diff --git a/framework/src/suricata/src/detect-http-stat-msg.c b/framework/src/suricata/src/detect-http-stat-msg.c deleted file mode 100644 index d2d7685e..00000000 --- a/framework/src/suricata/src/detect-http-stat-msg.c +++ /dev/null @@ -1,564 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Gurvinder Singh - * \author Anoop Saldanha - * - * Implements the http_stat_msg keyword - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-content.h" -#include "detect-pcre.h" -#include "detect-engine-mpm.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-error.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" -#include "util-print.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "detect-http-stat-msg.h" -#include "stream-tcp-private.h" -#include "stream-tcp.h" - -int DetectHttpStatMsgMatch (ThreadVars *, DetectEngineThreadCtx *, - Flow *, uint8_t , void *, Signature *, - SigMatch *); -static int DetectHttpStatMsgSetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpStatMsgRegisterTests(void); -void DetectHttpStatMsgFree(void *); - -/** - * \brief Registration function for keyword: http_stat_msg - */ -void DetectHttpStatMsgRegister (void) -{ - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].name = "http_stat_msg"; - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].desc = "content modifier to match on HTTP stat-msg-buffer"; - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_stat_msg"; - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Setup = DetectHttpStatMsgSetup; - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].Free = NULL; - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].RegisterTests = DetectHttpStatMsgRegisterTests; - - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_HTTP_STAT_MSG].flags |= SIGMATCH_PAYLOAD; -} - -/** - * \brief this function setups the http_stat_msg modifier keyword used in the rule - * - * \param de_ctx Pointer to the Detection Engine Context - * \param s Pointer to the Signature to which the current keyword belongs - * \param str Should hold an empty string always - * - * \retval 0 On success - * \retval -1 On failure - */ - -static int DetectHttpStatMsgSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_STAT_MSG, - DETECT_SM_LIST_HSMDMATCH, - ALPROTO_HTTP, - NULL); -} - -#ifdef UNITTESTS - -/** - * \test Checks if a http_stat_msg is registered in a Signature, if content is not - * specified in the signature or rawbyes is specified or fast_pattern is - * provided in the signature. - */ -int DetectHttpStatMsgTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_msg\"; http_stat_msg;sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_msg\"; content:\"|FF F1|\";" - " rawbytes; http_stat_msg;sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_msg\"; content:\"one\";" - "fast_pattern; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - if (!(((DetectContentData *)de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSMDMATCH]->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN)) - { - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_stat_msg is registered in a Signature and also checks - * the nocase - */ -int DetectHttpStatMsgTest02(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_msg\"; content:\"one\"; " - "http_stat_msg; content:\"two\"; http_stat_msg; " - "content:\"two\"; nocase; http_stat_msg; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - result = 0; - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HSMDMATCH]; - if (sm == NULL) { - printf("no sigmatch(es): "); - goto end; - } - - SigMatch *prev = NULL; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - result = 1; - } else { - printf("expected DETECT_CONTENT for http_stat_msg, got %d: ", sm->type); - goto end; - } - prev = sm; - sm = sm->next; - } - - if (! (((DetectContentData *)prev->ctx)->flags & - DETECT_CONTENT_NOCASE)) - { - result = 0; - } -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check the signature working to alert when http_stat_msg is matched . */ -static int DetectHttpStatMsgSigTest01(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status message\"; content:\"OK\"; " - "http_stat_msg; sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " - "Status message nocase\"; content:\"ok\"; nocase; " - "http_stat_msg; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_stat_msg is not matched . */ -static int DetectHttpStatMsgSigTest02(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status message\"; content:\"no\"; " - "http_stat_msg; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_stat_msg is used with - * negated content . */ -static int DetectHttpStatMsgSigTest03(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status message\"; content:\"ok\"; " - "nocase; http_stat_msg; sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " - "Status message nocase\"; content:!\"Not\"; " - "http_stat_msg; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (! PacketAlertCheck(p, 1)) { - printf("sid 1 didn't matched but should have: "); - goto end; - } - if (! PacketAlertCheck(p, 2)) { - printf("sid 2 didn't matched but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief Register the UNITTESTS for the http_stat_msg keyword - */ -void DetectHttpStatMsgRegisterTests (void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - - UtRegisterTest("DetectHttpStatMsgTest01", DetectHttpStatMsgTest01, 1); - UtRegisterTest("DetectHttpStatMsgTest02", DetectHttpStatMsgTest02, 1); - UtRegisterTest("DetectHttpStatMsgSigTest01", DetectHttpStatMsgSigTest01, 1); - UtRegisterTest("DetectHttpStatMsgSigTest02", DetectHttpStatMsgSigTest02, 1); - UtRegisterTest("DetectHttpStatMsgSigTest03", DetectHttpStatMsgSigTest03, 1); - -#endif /* UNITTESTS */ -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-stat-msg.h b/framework/src/suricata/src/detect-http-stat-msg.h deleted file mode 100644 index baa05718..00000000 --- a/framework/src/suricata/src/detect-http-stat-msg.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - */ - -#ifndef _DETECT_HTTP_STAT_MSG_H -#define _DETECT_HTTP_STAT_MSG_H - -/* prototypes */ -int DetectHttpStatMsgMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t , void *, Signature *, SigMatch *); -void DetectHttpStatMsgRegister(void); - -#endif /* _DETECT_HTTP_STAT_MSG_H */ - diff --git a/framework/src/suricata/src/detect-http-ua.c b/framework/src/suricata/src/detect-http-ua.c deleted file mode 100644 index cae5e9fa..00000000 --- a/framework/src/suricata/src/detect-http-ua.c +++ /dev/null @@ -1,2110 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements support for the http_user_agent keyword. - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-htp.h" -#include "stream-tcp.h" -#include "detect-http-ua.h" - -int DetectHttpUASetup(DetectEngineCtx *, Signature *, char *); -void DetectHttpUARegisterTests(void); -void DetectHttpUAFree(void *); - -/** - * \brief Registers the keyword handlers for the "http_user_agent" keyword. - */ -void DetectHttpUARegister(void) -{ - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].name = "http_user_agent"; - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].desc = "content modifier to match only on the HTTP User-Agent header"; - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_user_agent"; - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].Setup = DetectHttpUASetup; - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].Free = DetectHttpUAFree; - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].RegisterTests = DetectHttpUARegisterTests; - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].alproto = ALPROTO_HTTP; - - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_HTTP_USER_AGENT].flags |= SIGMATCH_PAYLOAD ; - - return; -} - -/** - * \brief The setup function for the http_user_agent keyword for a signature. - * - * \param de_ctx Pointer to the detection engine context. - * \param s Pointer to the signature for the current Signature being - * parsed from the rules. - * \param m Pointer to the head of the SigMatch for the current rule - * being parsed. - * \param arg Pointer to the string holding the keyword value. - * - * \retval 0 On success - * \retval -1 On failure - */ -int DetectHttpUASetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, arg, - DETECT_AL_HTTP_USER_AGENT, - DETECT_SM_LIST_HUADMATCH, - ALPROTO_HTTP, - NULL); -} - -/** - * \brief The function to free the http_user_agent data. - * - * \param ptr Pointer to the http_user_agent. - */ -void DetectHttpUAFree(void *ptr) -{ - DetectContentData *huad = (DetectContentData *)ptr; - if (huad == NULL) - return; - - if (huad->content != NULL) - SCFree(huad->content); - - BoyerMooreCtxDeInit(huad->bm_ctx); - SCFree(huad); - - return; -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Test that a signature containting a http_user_agent is correctly parsed - * and the keyword is registered. - */ -static int DetectHttpUATest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_user_agent\"; " - "content:\"one\"; http_user_agent; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a signature containing an valid http_user_agent entry is - * parsed. - */ -static int DetectHttpUATest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_user_agent\"; " - "content:\"one\"; http_user_agent:; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing no content but a - * http_user_agent is invalidated. - */ -static int DetectHttpUATest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_user_agent\"; " - "http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_user_agent is invalidated. - */ -static int DetectHttpUATest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_user_agent\"; " - "content:\"one\"; rawbytes; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a http_user_agent with nocase is parsed. - */ -static int DetectHttpUATest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_user_agent\"; " - "content:\"one\"; http_user_agent; nocase; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - *\test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectHttpUATest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: This is dummy message body\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"message\"; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectHttpUATest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: This is dummy message"; - uint8_t http2_buf[] = - "body1\r\n\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"message\"; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but shouldn't have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectHttpUATest08(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: This is dummy mess"; - uint8_t http2_buf[] = - "age body\r\n\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"message\"; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_user_agent content matches against a http request - * which holds the content, against a cross boundary present pattern. - */ -static int DetectHttpUATest09(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: This is dummy body1"; - uint8_t http2_buf[] = - "This is dummy message body2\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"body1This\"; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the http_user_agent content matches against a http request - * against a case insensitive pattern. - */ -static int DetectHttpUATest10(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: This is dummy bodY1"; - uint8_t http2_buf[] = - "This is dummy message body2\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 46\r\n" - "\r\n" - "This is dummy bodY1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"body1this\"; http_user_agent; nocase;" - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: \n"); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have\n"); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** - *\test Test that the negated http_user_agent content matches against a - * http request which doesn't hold the content. - */ -static int DetectHttpUATest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: This is dummy message body\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:!\"message\"; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - *\test Negative test that the negated http_user_agent content matches against a - * http request which holds hold the content. - */ -static int DetectHttpUATest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: This is dummy body\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:!\"message\"; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test that the http_user_agent content matches against a http request - * which holds the content. - */ -static int DetectHttpUATest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n" - "Content-Type: text/html\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 1; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http user agent test\"; " - "content:\"abcdefghijklmnopqrstuvwxyz0123456789\"; http_user_agent; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test multiple http transactions and body chunks of request handling - */ -static int DetectHttpUATest14(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "Cookie: dummy1\r\n"; - uint8_t httpbuf3[] = "User-Agent: Body one!!\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf5[] = "Cookie: dummy2\r\n"; - uint8_t httpbuf6[] = "User-Agent: Body two\r\n\r\n"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"dummy1\"; http_cookie; content:\"Body one\"; http_user_agent; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"dummy2\"; http_cookie; content:\"Body two\"; http_user_agent; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) || PacketAlertCheck(p, 2)) { - printf("sig 1 alerted (4): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) || !(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match or sig 1 matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - - - - - - - - - - - - - - - -int DetectHttpUATest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; content:\"two\"; http_user_agent; " - "content:\"three\"; distance:10; http_user_agent; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - DetectContentData *cd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (cd1->flags != 0 || memcmp(cd1->content, "one", cd1->content_len) != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - huad1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(huad1->content, "two", huad1->content_len) != 0 || - huad2->flags != DETECT_CONTENT_DISTANCE || - memcmp(huad2->content, "three", huad1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd1) || - !DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(huad1) || - DETECT_CONTENT_IS_SINGLE(huad2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_user_agent; pcre:/two/; " - "content:\"three\"; distance:10; http_user_agent; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - huad1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(huad1->content, "one", huad1->content_len) != 0 || - huad2->flags != DETECT_CONTENT_DISTANCE || - memcmp(huad2->content, "three", huad1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(huad1) || - DETECT_CONTENT_IS_SINGLE(huad2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_user_agent; pcre:/two/; " - "content:\"three\"; distance:10; within:15; http_user_agent; content:\"four\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (pd1->flags != 0 || - cd2->flags != 0 || memcmp(cd2->content, "four", cd2->content_len) != 0 || - huad1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(huad1->content, "one", huad1->content_len) != 0 || - huad2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(huad2->content, "three", huad1->content_len) != 0) { - goto end; - } - - if (!DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(huad1) || - DETECT_CONTENT_IS_SINGLE(huad2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_user_agent; pcre:/two/; " - "content:\"three\"; distance:10; http_user_agent; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (pd1->flags != DETECT_PCRE_RELATIVE_NEXT || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - huad1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(huad1->content, "one", huad1->content_len) != 0 || - huad2->flags != DETECT_CONTENT_DISTANCE || - memcmp(huad2->content, "three", huad1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(huad1) || - DETECT_CONTENT_IS_SINGLE(huad2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; offset:10; http_user_agent; pcre:/two/; " - "content:\"three\"; distance:10; http_user_agent; within:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - huad1->flags != (DETECT_CONTENT_RELATIVE_NEXT | DETECT_CONTENT_OFFSET) || - memcmp(huad1->content, "one", huad1->content_len) != 0 || - huad2->flags != (DETECT_CONTENT_DISTANCE | DETECT_CONTENT_WITHIN) || - memcmp(huad2->content, "three", huad1->content_len) != 0) { - printf ("failed: http_user_agent incorrect flags"); - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - DETECT_CONTENT_IS_SINGLE(huad1) || - DETECT_CONTENT_IS_SINGLE(huad2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; offset:10; http_user_agent; pcre:/two/; " - "content:\"three\"; distance:10; http_user_agent; within:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest28(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_user_agent; pcre:/two/; " - "content:\"three\"; http_user_agent; depth:10; " - "content:\"four\"; distance:10; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->prev->ctx; - DetectContentData *cd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - cd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(cd2->content, "four", cd2->content_len) != 0 || - huad1->flags != 0 || - memcmp(huad1->content, "one", huad1->content_len) != 0 || - huad2->flags != DETECT_CONTENT_DEPTH || - memcmp(huad2->content, "three", huad1->content_len) != 0) { - goto end; - } - - if (DETECT_CONTENT_IS_SINGLE(cd2) || - !DETECT_CONTENT_IS_SINGLE(huad1) || - DETECT_CONTENT_IS_SINGLE(huad2)) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest29(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; distance:0; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (huad1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(huad1->content, "one", huad1->content_len) != 0 || - huad2->flags != DETECT_CONTENT_DISTANCE || - memcmp(huad2->content, "two", huad1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest30(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_user_agent; " - "content:\"two\"; within:5; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (huad1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(huad1->content, "one", huad1->content_len) != 0 || - huad2->flags != DETECT_CONTENT_WITHIN || - memcmp(huad2->content, "two", huad1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest31(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; within:5; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest32(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; http_user_agent; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list != NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest33(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest34(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(pcre:/one/V; " - "content:\"two\"; within:5; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - huad2->flags != DETECT_CONTENT_WITHIN || - memcmp(huad2->content, "two", huad2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest35(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"two\"; http_user_agent; " - "pcre:/one/VR; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->type != DETECT_PCRE || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->type != DETECT_CONTENT) { - - goto end; - } - - DetectContentData *huad1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (pd2->flags != (DETECT_PCRE_RELATIVE) || - huad1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(huad1->content, "two", huad1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUATest36(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(pcre:/one/V; " - "content:\"two\"; distance:5; http_user_agent; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HUADMATCH] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH] == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->prev->ctx; - DetectContentData *huad2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HUADMATCH]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - huad2->flags != DETECT_CONTENT_DISTANCE || - memcmp(huad2->content, "two", huad2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -void DetectHttpUARegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectHttpUATest01", DetectHttpUATest01, 1); - UtRegisterTest("DetectHttpUATest02", DetectHttpUATest02, 1); - UtRegisterTest("DetectHttpUATest03", DetectHttpUATest03, 1); - UtRegisterTest("DetectHttpUATest04", DetectHttpUATest04, 1); - UtRegisterTest("DetectHttpUATest05", DetectHttpUATest05, 1); - UtRegisterTest("DetectHttpUATest06", DetectHttpUATest06, 1); - UtRegisterTest("DetectHttpUATest07", DetectHttpUATest07, 1); - UtRegisterTest("DetectHttpUATest08", DetectHttpUATest08, 1); - UtRegisterTest("DetectHttpUATest09", DetectHttpUATest09, 1); - UtRegisterTest("DetectHttpUATest10", DetectHttpUATest10, 1); - UtRegisterTest("DetectHttpUATest11", DetectHttpUATest11, 1); - UtRegisterTest("DetectHttpUATest12", DetectHttpUATest12, 1); - UtRegisterTest("DetectHttpUATest13", DetectHttpUATest13, 1); - UtRegisterTest("DetectHttpUATest14", DetectHttpUATest14, 1); - - UtRegisterTest("DetectHttpUATest22", DetectHttpUATest22, 1); - UtRegisterTest("DetectHttpUATest23", DetectHttpUATest23, 1); - UtRegisterTest("DetectHttpUATest24", DetectHttpUATest24, 1); - UtRegisterTest("DetectHttpUATest25", DetectHttpUATest25, 1); - UtRegisterTest("DetectHttpUATest26", DetectHttpUATest26, 1); - UtRegisterTest("DetectHttpUATest27", DetectHttpUATest27, 1); - UtRegisterTest("DetectHttpUATest28", DetectHttpUATest28, 1); - UtRegisterTest("DetectHttpUATest29", DetectHttpUATest29, 1); - UtRegisterTest("DetectHttpUATest30", DetectHttpUATest30, 1); - UtRegisterTest("DetectHttpUATest31", DetectHttpUATest31, 1); - UtRegisterTest("DetectHttpUATest32", DetectHttpUATest32, 1); - UtRegisterTest("DetectHttpUATest33", DetectHttpUATest33, 1); - UtRegisterTest("DetectHttpUATest34", DetectHttpUATest34, 1); - UtRegisterTest("DetectHttpUATest35", DetectHttpUATest35, 1); - UtRegisterTest("DetectHttpUATest36", DetectHttpUATest36, 1); -#endif /* UNITTESTS */ - - return; -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-ua.h b/framework/src/suricata/src/detect-http-ua.h deleted file mode 100644 index 2b04245e..00000000 --- a/framework/src/suricata/src/detect-http-ua.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_HTTP_UA_H__ -#define __DETECT_HTTP_UA_H__ - -void DetectHttpUARegister(void); - -#endif /* __DETECT_HTTP_UA_H__ */ diff --git a/framework/src/suricata/src/detect-http-uri.c b/framework/src/suricata/src/detect-http-uri.c deleted file mode 100644 index 92c4803e..00000000 --- a/framework/src/suricata/src/detect-http-uri.c +++ /dev/null @@ -1,556 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup httplayer - * - * @{ - */ - - -/** - * \file - * - * \author Gerardo Iglesias - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-content.h" -#include "detect-pcre.h" - -#include "flow.h" -#include "flow-var.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-spm.h" -#include "util-print.h" - -#include "app-layer.h" - -#include "app-layer-htp.h" -#include "detect-http-uri.h" -#include "detect-uricontent.h" -#include "stream-tcp.h" - -int DetectHttpUriSetup (DetectEngineCtx *, Signature *, char *); -void DetectHttpUriRegisterTests(void); - -/** - * \brief Registration function for keyword: http_uri - */ -void DetectHttpUriRegister (void) -{ - sigmatch_table[DETECT_AL_HTTP_URI].name = "http_uri"; - sigmatch_table[DETECT_AL_HTTP_URI].desc = "content modifier to match specifically and only on the HTTP uri-buffer"; - sigmatch_table[DETECT_AL_HTTP_URI].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#http_uri-and-http_raw_uri"; - sigmatch_table[DETECT_AL_HTTP_URI].Match = NULL; - sigmatch_table[DETECT_AL_HTTP_URI].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_HTTP_URI].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_AL_HTTP_URI].Setup = DetectHttpUriSetup; - sigmatch_table[DETECT_AL_HTTP_URI].Free = NULL; - sigmatch_table[DETECT_AL_HTTP_URI].RegisterTests = DetectHttpUriRegisterTests; - - sigmatch_table[DETECT_AL_HTTP_URI].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_HTTP_URI].flags |= SIGMATCH_PAYLOAD; -} - - -/** - * \brief this function setups the http_uri modifier keyword used in the rule - * - * \param de_ctx Pointer to the Detection Engine Context - * \param s Pointer to the Signature to which the current keyword belongs - * \param str Should hold an empty string always - * - * \retval 0 On success - * \retval -1 On failure - */ - -int DetectHttpUriSetup(DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - return DetectEngineContentModifierBufferSetup(de_ctx, s, str, - DETECT_AL_HTTP_URI, - DETECT_SM_LIST_UMATCH, - ALPROTO_HTTP, - NULL); -} - - -/******************************** UNITESTS **********************************/ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** - * \test Checks if a http_uri is registered in a Signature, if content is not - * specified in the signature - */ -int DetectHttpUriTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_uri\"; http_uri;sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_uri is registered in a Signature, if some parameter - * is specified with http_uri in the signature - */ -int DetectHttpUriTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_uri\"; content:\"one\"; " - "http_cookie:wrong; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_uri is registered in a Signature - */ -int DetectHttpUriTest03(void) -{ - SigMatch *sm = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_uri\"; content:\"one\"; " - "http_uri; content:\"two\"; http_uri; " - "content:\"three\"; http_uri; " - "sid:1;)"); - - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm == NULL) { - printf("no sigmatch(es): "); - goto end; - } - - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - result = 1; - } else { - printf("expected DETECT_AL_HTTP_URI, got %d: ", sm->type); - goto end; - } - sm = sm->next; - } - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_uri is registered in a Signature, when rawbytes is - * also specified in the signature - */ -int DetectHttpUriTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_uri\"; content:\"one\"; " - "rawbytes; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - - end: - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_uri is successfully converted to a uricontent - * - */ -int DetectHttpUriTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - Signature *s = NULL; - int result = 0; - - if ((de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - s = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_uri\"; " - "content:\"we are testing http_uri keyword\"; " - "http_uri; sid:1;)"); - if (s == NULL) { - printf("sig failed to parse\n"); - goto end; - } - if (s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL) - goto end; - if (s->sm_lists[DETECT_SM_LIST_UMATCH]->type != DETECT_CONTENT) { - printf("wrong type\n"); - goto end; - } - - char *str = "we are testing http_uri keyword"; - int uricomp = memcmp((const char *)((DetectContentData*) s->sm_lists[DETECT_SM_LIST_UMATCH]->ctx)->content, str, strlen(str)-1); - int urilen = ((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx)->content_len; - if (uricomp != 0 || - urilen != strlen("we are testing http_uri keyword")) { - printf("sig failed to parse, content not setup properly\n"); - goto end; - } - result = 1; - -end: - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - return result; -} - -int DetectHttpUriTest12(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_uri; " - "content:\"two\"; distance:0; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL\n"); - goto end; - } - - DetectContentData *ud1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - DetectContentData *ud2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(ud1->content, "one", ud1->content_len) != 0 || - ud2->flags != DETECT_CONTENT_DISTANCE || - memcmp(ud2->content, "two", ud1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUriTest13(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_uri; " - "content:\"two\"; within:5; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL\n"); - goto end; - } - - DetectContentData *ud1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - DetectContentData *ud2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(ud1->content, "one", ud1->content_len) != 0 || - ud2->flags != DETECT_CONTENT_WITHIN || - memcmp(ud2->content, "two", ud1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUriTest14(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUriTest15(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_uri; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL\n"); - goto end; - } - - DetectContentData *cd = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (memcmp(cd->content, "one", cd->content_len) != 0 || - cd->flags != DETECT_CONTENT_WITHIN) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUriTest16(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUriTest17(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; " - "content:\"two\"; distance:0; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL\n"); - goto end; - } - - DetectContentData *ud1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - DetectContentData *ud2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(ud1->content, "one", ud1->content_len) != 0 || - ud2->flags != DETECT_CONTENT_DISTANCE || - memcmp(ud2->content, "two", ud1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -int DetectHttpUriTest18(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(uricontent:\"one\"; " - "content:\"two\"; within:5; http_uri; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL\n"); - goto end; - } - - DetectContentData *ud1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->prev->ctx; - DetectContentData *ud2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if (ud1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(ud1->content, "one", ud1->content_len) != 0 || - ud2->flags != DETECT_CONTENT_WITHIN || - memcmp(ud2->content, "two", ud1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief Register the UNITTESTS for the http_uri keyword - */ -void DetectHttpUriRegisterTests (void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectHttpUriTest01", DetectHttpUriTest01, 1); - UtRegisterTest("DetectHttpUriTest02", DetectHttpUriTest02, 1); - UtRegisterTest("DetectHttpUriTest03", DetectHttpUriTest03, 1); - UtRegisterTest("DetectHttpUriTest04", DetectHttpUriTest04, 1); - UtRegisterTest("DetectHttpUriTest05", DetectHttpUriTest05, 1); - UtRegisterTest("DetectHttpUriTest12", DetectHttpUriTest12, 1); - UtRegisterTest("DetectHttpUriTest13", DetectHttpUriTest13, 1); - UtRegisterTest("DetectHttpUriTest14", DetectHttpUriTest14, 1); - UtRegisterTest("DetectHttpUriTest15", DetectHttpUriTest15, 1); - UtRegisterTest("DetectHttpUriTest16", DetectHttpUriTest16, 1); - UtRegisterTest("DetectHttpUriTest17", DetectHttpUriTest17, 1); - UtRegisterTest("DetectHttpUriTest18", DetectHttpUriTest18, 1); -#endif /* UNITTESTS */ - -} -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-http-uri.h b/framework/src/suricata/src/detect-http-uri.h deleted file mode 100644 index cb327804..00000000 --- a/framework/src/suricata/src/detect-http-uri.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias Galvan - */ - -#ifndef _DETECT_HTTP_URI_H -#define _DETECT_HTTP_URI_H - -/* prototypes */ -void DetectHttpUriRegister (void); - -int DetectHttpUriSetup(DetectEngineCtx *de_ctx, Signature *s, char *str); -int DetectHttpUriDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, - SigMatch *sm, Flow *f, uint8_t flags, void *state); - -#endif /* _DETECT_HTTP_URI_H */ diff --git a/framework/src/suricata/src/detect-icmp-id.c b/framework/src/suricata/src/detect-icmp-id.c deleted file mode 100644 index 5d6f7f26..00000000 --- a/framework/src/suricata/src/detect-icmp-id.c +++ /dev/null @@ -1,500 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias Galvan - * - * Implements the icmp_id keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-icmp-id.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -#define PARSE_REGEX "^\\s*(\"\\s*)?([0-9]+)(\\s*\")?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectIcmpIdMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectIcmpIdSetup(DetectEngineCtx *, Signature *, char *); -void DetectIcmpIdRegisterTests(void); -void DetectIcmpIdFree(void *); - -/** - * \brief Registration function for icode: icmp_id - */ -void DetectIcmpIdRegister (void) -{ - sigmatch_table[DETECT_ICMP_ID].name = "icmp_id"; - sigmatch_table[DETECT_ICMP_ID].desc = "check for a ICMP id"; - sigmatch_table[DETECT_ICMP_ID].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#icmp_id"; - sigmatch_table[DETECT_ICMP_ID].Match = DetectIcmpIdMatch; - sigmatch_table[DETECT_ICMP_ID].Setup = DetectIcmpIdSetup; - sigmatch_table[DETECT_ICMP_ID].Free = DetectIcmpIdFree; - sigmatch_table[DETECT_ICMP_ID].RegisterTests = DetectIcmpIdRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -/** - * \brief This function is used to match icmp_id rule option set on a packet - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectIcmpIdData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectIcmpIdMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - uint16_t pid; - const DetectIcmpIdData *iid = (const DetectIcmpIdData *)ctx; - - if (PKT_IS_PSEUDOPKT(p)) - return 0; - - if (PKT_IS_ICMPV4(p)) { - switch (ICMPV4_GET_TYPE(p)){ - case ICMP_ECHOREPLY: - case ICMP_ECHO: - case ICMP_TIMESTAMP: - case ICMP_TIMESTAMPREPLY: - case ICMP_INFO_REQUEST: - case ICMP_INFO_REPLY: - case ICMP_ADDRESS: - case ICMP_ADDRESSREPLY: - SCLogDebug("ICMPV4_GET_ID(p) %"PRIu16" (network byte order), " - "%"PRIu16" (host byte order)", ICMPV4_GET_ID(p), - ntohs(ICMPV4_GET_ID(p))); - - pid = ICMPV4_GET_ID(p); - break; - default: - SCLogDebug("Packet has no id field"); - return 0; - } - } else if (PKT_IS_ICMPV6(p)) { - switch (ICMPV6_GET_TYPE(p)) { - case ICMP6_ECHO_REQUEST: - case ICMP6_ECHO_REPLY: - SCLogDebug("ICMPV6_GET_ID(p) %"PRIu16" (network byte order), " - "%"PRIu16" (host byte order)", ICMPV6_GET_ID(p), - ntohs(ICMPV6_GET_ID(p))); - - pid = ICMPV6_GET_ID(p); - break; - default: - SCLogDebug("Packet has no id field"); - return 0; - } - } else { - SCLogDebug("Packet not ICMPV4 nor ICMPV6"); - return 0; - } - - if (pid == iid->id) - return 1; - - return 0; -} - -/** - * \brief This function is used to parse icmp_id option passed via icmp_id: keyword - * - * \param icmpidstr Pointer to the user provided icmp_id options - * - * \retval iid pointer to DetectIcmpIdData on success - * \retval NULL on failure - */ -DetectIcmpIdData *DetectIcmpIdParse (char *icmpidstr) -{ - DetectIcmpIdData *iid = NULL; - char *substr[3] = {NULL, NULL, NULL}; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, icmpidstr, strlen(icmpidstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "Parse error %s", icmpidstr); - goto error; - } - - int i; - const char *str_ptr; - for (i = 1; i < ret; i++) { - res = pcre_get_substring((char *)icmpidstr, ov, MAX_SUBSTRINGS, i, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - substr[i-1] = (char *)str_ptr; - } - - iid = SCMalloc(sizeof(DetectIcmpIdData)); - if (unlikely(iid == NULL)) - goto error; - iid->id = 0; - - if (substr[0]!= NULL && strlen(substr[0]) != 0) { - if (substr[2] == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Missing close quote in input"); - goto error; - } - } else { - if (substr[2] != NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Missing open quote in input"); - goto error; - } - } - - /** \todo can ByteExtractStringUint16 do this? */ - uint16_t id = 0; - if (ByteExtractStringUint16(&id, 10, 0, substr[1]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp id %s is not " - "valid", substr[1]); - goto error; - } - iid->id = htons(id); - - for (i = 0; i < 3; i++) { - if (substr[i] != NULL) SCFree(substr[i]); - } - return iid; - -error: - for (i = 0; i < 3; i++) { - if (substr[i] != NULL) SCFree(substr[i]); - } - if (iid != NULL) DetectIcmpIdFree(iid); - return NULL; - -} - -/** - * \brief this function is used to add the parsed icmp_id data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param icmpidstr pointer to the user provided icmp_id option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectIcmpIdSetup (DetectEngineCtx *de_ctx, Signature *s, char *icmpidstr) -{ - DetectIcmpIdData *iid = NULL; - SigMatch *sm = NULL; - - iid = DetectIcmpIdParse(icmpidstr); - if (iid == NULL) goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) goto error; - - sm->type = DETECT_ICMP_ID; - sm->ctx = (SigMatchCtx *)iid; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (iid != NULL) DetectIcmpIdFree(iid); - if (sm != NULL) SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectIcmpIdData - * - * \param ptr pointer to DetectIcmpIdData - */ -void DetectIcmpIdFree (void *ptr) -{ - DetectIcmpIdData *iid = (DetectIcmpIdData *)ptr; - SCFree(iid); -} - -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -/** - * \test DetectIcmpIdParseTest01 is a test for setting a valid icmp_id value - */ -int DetectIcmpIdParseTest01 (void) -{ - DetectIcmpIdData *iid = NULL; - iid = DetectIcmpIdParse("300"); - if (iid != NULL && iid->id == htons(300)) { - DetectIcmpIdFree(iid); - return 1; - } - return 0; -} - -/** - * \test DetectIcmpIdParseTest02 is a test for setting a valid icmp_id value - * with spaces all around - */ -int DetectIcmpIdParseTest02 (void) -{ - DetectIcmpIdData *iid = NULL; - iid = DetectIcmpIdParse(" 300 "); - if (iid != NULL && iid->id == htons(300)) { - DetectIcmpIdFree(iid); - return 1; - } - return 0; -} - -/** - * \test DetectIcmpIdParseTest03 is a test for setting a valid icmp_id value - * with quotation marks - */ -int DetectIcmpIdParseTest03 (void) -{ - DetectIcmpIdData *iid = NULL; - iid = DetectIcmpIdParse("\"300\""); - if (iid != NULL && iid->id == htons(300)) { - DetectIcmpIdFree(iid); - return 1; - } - return 0; -} - -/** - * \test DetectIcmpIdParseTest04 is a test for setting a valid icmp_id value - * with quotation marks and spaces all around - */ -int DetectIcmpIdParseTest04 (void) -{ - DetectIcmpIdData *iid = NULL; - iid = DetectIcmpIdParse(" \" 300 \""); - if (iid != NULL && iid->id == htons(300)) { - DetectIcmpIdFree(iid); - return 1; - } - return 0; -} - -/** - * \test DetectIcmpIdParseTest05 is a test for setting an invalid icmp_id - * value with missing quotation marks - */ -int DetectIcmpIdParseTest05 (void) -{ - DetectIcmpIdData *iid = NULL; - iid = DetectIcmpIdParse("\"300"); - if (iid == NULL) { - DetectIcmpIdFree(iid); - return 1; - } - return 0; -} - -/** - * \test DetectIcmpIdMatchTest01 is a test for checking the working of - * icmp_id keyword by creating 2 rules and matching a crafted packet - * against them. Only the first one shall trigger. - */ -int DetectIcmpIdMatchTest01 (void) -{ - int result = 0; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(ThreadVars)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); - p->icmpv4vars.id = htons(21781); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any (icmp_id:21781; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx, "alert icmp any any -> any any (icmp_id:21782; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 0) { - printf("sid 1 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2)) { - printf("sid 2 alerted, but should not have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); -end: - return result; - -} - -/** - * \test DetectIcmpIdMatchTest02 is a test for checking the working of - * icmp_id keyword by creating 1 rule and matching a crafted packet - * against them. The packet is an ICMP packet with no "id" field, - * therefore the rule should not trigger. - */ -int DetectIcmpIdMatchTest02 (void) -{ - int result = 0; - - uint8_t raw_icmpv4[] = { - 0x0b, 0x00, 0x8a, 0xdf, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x00, 0x00, 0x14, 0x25, 0x0c, 0x00, 0x00, - 0xff, 0x11, 0x00, 0x00, 0x85, 0x64, 0xea, 0x5b, - 0x51, 0xa6, 0xbb, 0x35, 0x59, 0x8a, 0x5a, 0xe2, - 0x00, 0x14, 0x00, 0x00 }; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - IPV4Hdr ip4h; - - memset(&ip4h, 0, sizeof(IPV4Hdr)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(ThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - p->src.addr_data32[0] = 0x01020304; - p->dst.addr_data32[0] = 0x04030201; - - ip4h.s_ip_src.s_addr = p->src.addr_data32[0]; - ip4h.s_ip_dst.s_addr = p->dst.addr_data32[0]; - p->ip4h = &ip4h; - - DecodeICMPV4(&th_v, &dtv, p, raw_icmpv4, sizeof(raw_icmpv4), NULL); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any (icmp_id:0; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 alerted, but should not have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - FlowShutdown(); -end: - SCFree(p); - return result; -} -#endif /* UNITTESTS */ - -void DetectIcmpIdRegisterTests (void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectIcmpIdParseTest01", DetectIcmpIdParseTest01, 1); - UtRegisterTest("DetectIcmpIdParseTest02", DetectIcmpIdParseTest02, 1); - UtRegisterTest("DetectIcmpIdParseTest03", DetectIcmpIdParseTest03, 1); - UtRegisterTest("DetectIcmpIdParseTest04", DetectIcmpIdParseTest04, 1); - UtRegisterTest("DetectIcmpIdParseTest05", DetectIcmpIdParseTest05, 1); - UtRegisterTest("DetectIcmpIdMatchTest01", DetectIcmpIdMatchTest01, 1); - UtRegisterTest("DetectIcmpIdMatchTest02", DetectIcmpIdMatchTest02, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-icmp-id.h b/framework/src/suricata/src/detect-icmp-id.h deleted file mode 100644 index a3b20f3c..00000000 --- a/framework/src/suricata/src/detect-icmp-id.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias Galvan - */ - -#ifndef __DETECT_ICMP_ID_H__ -#define __DETECT_ICMP_ID_H__ - -typedef struct DetectIcmpIdData_ { - uint16_t id; /**< id in network byte error */ -} DetectIcmpIdData; - -/* prototypes */ -void DetectIcmpIdRegister(void); - -#endif /* __DETECT_ICMP_ID__ */ diff --git a/framework/src/suricata/src/detect-icmp-seq.c b/framework/src/suricata/src/detect-icmp-seq.c deleted file mode 100644 index 4e3fe1ac..00000000 --- a/framework/src/suricata/src/detect-icmp-seq.c +++ /dev/null @@ -1,390 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * - * Implements the icmp_seq keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-icmp-seq.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -#define PARSE_REGEX "^\\s*(\"\\s*)?([0-9]+)(\\s*\")?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectIcmpSeqMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectIcmpSeqSetup(DetectEngineCtx *, Signature *, char *); -void DetectIcmpSeqRegisterTests(void); -void DetectIcmpSeqFree(void *); - -/** - * \brief Registration function for icmp_seq - */ -void DetectIcmpSeqRegister (void) -{ - sigmatch_table[DETECT_ICMP_SEQ].name = "icmp_seq"; - sigmatch_table[DETECT_ICMP_SEQ].desc = "check for a ICMP sequence number"; - sigmatch_table[DETECT_ICMP_SEQ].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#icmp_seq"; - sigmatch_table[DETECT_ICMP_SEQ].Match = DetectIcmpSeqMatch; - sigmatch_table[DETECT_ICMP_SEQ].Setup = DetectIcmpSeqSetup; - sigmatch_table[DETECT_ICMP_SEQ].Free = DetectIcmpSeqFree; - sigmatch_table[DETECT_ICMP_SEQ].RegisterTests = DetectIcmpSeqRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE,"pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY,"pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -/** - * \brief This function is used to match icmp_seq rule option set on a packet - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectIcmpSeqData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectIcmpSeqMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - uint16_t seqn; - const DetectIcmpSeqData *iseq = (const DetectIcmpSeqData *)ctx; - - if (PKT_IS_PSEUDOPKT(p)) - return 0; - - if (PKT_IS_ICMPV4(p)) { - switch (ICMPV4_GET_TYPE(p)){ - case ICMP_ECHOREPLY: - case ICMP_ECHO: - case ICMP_TIMESTAMP: - case ICMP_TIMESTAMPREPLY: - case ICMP_INFO_REQUEST: - case ICMP_INFO_REPLY: - case ICMP_ADDRESS: - case ICMP_ADDRESSREPLY: - SCLogDebug("ICMPV4_GET_SEQ(p) %"PRIu16" (network byte order), " - "%"PRIu16" (host byte order)", ICMPV4_GET_SEQ(p), - ntohs(ICMPV4_GET_SEQ(p))); - - seqn = ICMPV4_GET_SEQ(p); - break; - default: - SCLogDebug("Packet has no seq field"); - return 0; - } - } else if (PKT_IS_ICMPV6(p)) { - - switch (ICMPV6_GET_TYPE(p)) { - case ICMP6_ECHO_REQUEST: - case ICMP6_ECHO_REPLY: - SCLogDebug("ICMPV6_GET_SEQ(p) %"PRIu16" (network byte order), " - "%"PRIu16" (host byte order)", ICMPV6_GET_SEQ(p), - ntohs(ICMPV6_GET_SEQ(p))); - - seqn = ICMPV6_GET_SEQ(p); - break; - default: - SCLogDebug("Packet has no seq field"); - return 0; - } - } else { - SCLogDebug("Packet not ICMPV4 nor ICMPV6"); - return 0; - } - - if (seqn == iseq->seq) - return 1; - - return 0; -} - -/** - * \brief This function is used to parse icmp_seq option passed via icmp_seq: keyword - * - * \param icmpseqstr Pointer to the user provided icmp_seq options - * - * \retval iseq pointer to DetectIcmpSeqData on success - * \retval NULL on failure - */ -DetectIcmpSeqData *DetectIcmpSeqParse (char *icmpseqstr) -{ - DetectIcmpSeqData *iseq = NULL; - char *substr[3] = {NULL, NULL, NULL}; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - int i; - const char *str_ptr; - - ret = pcre_exec(parse_regex, parse_regex_study, icmpseqstr, strlen(icmpseqstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH,"Parse error %s", icmpseqstr); - goto error; - } - - for (i = 1; i < ret; i++) { - res = pcre_get_substring((char *)icmpseqstr, ov, MAX_SUBSTRINGS, i, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_get_substring failed"); - goto error; - } - substr[i-1] = (char *)str_ptr; - } - - iseq = SCMalloc(sizeof(DetectIcmpSeqData)); - if (unlikely(iseq == NULL)) - goto error; - - iseq->seq = 0; - - if (substr[0] != NULL && strlen(substr[0]) != 0) { - if (substr[2] == NULL) { - SCLogError(SC_ERR_MISSING_QUOTE,"Missing quote in input"); - goto error; - } - } else { - if (substr[2] != NULL) { - SCLogError(SC_ERR_MISSING_QUOTE,"Missing quote in input"); - goto error; - } - } - - uint16_t seq = 0; - if (ByteExtractStringUint16(&seq, 10, 0, substr[1]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp seq %s is not " - "valid", substr[1]); - goto error; - } - iseq->seq = htons(seq); - - for (i = 0; i < 3; i++) { - if (substr[i] != NULL) SCFree(substr[i]); - } - - return iseq; - -error: - for (i = 0; i < 3; i++) { - if (substr[i] != NULL) SCFree(substr[i]); - } - if (iseq != NULL) DetectIcmpSeqFree(iseq); - return NULL; - -} - -/** - * \brief this function is used to add the parsed icmp_seq data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param icmpseqstr pointer to the user provided icmp_seq option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectIcmpSeqSetup (DetectEngineCtx *de_ctx, Signature *s, char *icmpseqstr) -{ - DetectIcmpSeqData *iseq = NULL; - SigMatch *sm = NULL; - - iseq = DetectIcmpSeqParse(icmpseqstr); - if (iseq == NULL) goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) goto error; - - sm->type = DETECT_ICMP_SEQ; - sm->ctx = (SigMatchCtx *)iseq; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (iseq != NULL) DetectIcmpSeqFree(iseq); - if (sm != NULL) SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectIcmpSeqData - * - * \param ptr pointer to DetectIcmpSeqData - */ -void DetectIcmpSeqFree (void *ptr) -{ - DetectIcmpSeqData *iseq = (DetectIcmpSeqData *)ptr; - SCFree(iseq); -} - -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -/** - * \test DetectIcmpSeqParseTest01 is a test for setting a valid icmp_seq value - */ -int DetectIcmpSeqParseTest01 (void) -{ - DetectIcmpSeqData *iseq = NULL; - iseq = DetectIcmpSeqParse("300"); - if (iseq != NULL && htons(iseq->seq) == 300) { - DetectIcmpSeqFree(iseq); - return 1; - } - return 0; -} - -/** - * \test DetectIcmpSeqParseTest02 is a test for setting a valid icmp_seq value - * with spaces all around - */ -int DetectIcmpSeqParseTest02 (void) -{ - DetectIcmpSeqData *iseq = NULL; - iseq = DetectIcmpSeqParse(" 300 "); - if (iseq != NULL && htons(iseq->seq) == 300) { - DetectIcmpSeqFree(iseq); - return 1; - } - return 0; -} - -/** - * \test DetectIcmpSeqParseTest03 is a test for setting an invalid icmp_seq value - */ -int DetectIcmpSeqParseTest03 (void) -{ - DetectIcmpSeqData *iseq = NULL; - iseq = DetectIcmpSeqParse("badc"); - if (iseq != NULL) { - DetectIcmpSeqFree(iseq); - return 1; - } - return 0; -} - -/** - * \test DetectIcmpSeqMatchTest01 is a test for checking the working of - * icmp_seq keyword by creating 2 rules and matching a crafted packet - * against them. Only the first one shall trigger. - */ -int DetectIcmpSeqMatchTest01 (void) -{ - int result = 0; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); - p->icmpv4vars.seq = htons(2216); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any (icmp_seq:2216; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx, "alert icmp any any -> any any (icmp_seq:5000; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 0) { - printf("sid 1 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2)) { - printf("sid 2 alerted, but should not have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); -end: - return result; - -} -#endif /* UNITTESTS */ - -void DetectIcmpSeqRegisterTests (void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectIcmpSeqParseTest01", DetectIcmpSeqParseTest01, 1); - UtRegisterTest("DetectIcmpSeqParseTest02", DetectIcmpSeqParseTest02, 1); - UtRegisterTest("DetectIcmpSeqParseTest03", DetectIcmpSeqParseTest03, 0); - UtRegisterTest("DetectIcmpSeqMatchTest01", DetectIcmpSeqMatchTest01, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-icmp-seq.h b/framework/src/suricata/src/detect-icmp-seq.h deleted file mode 100644 index 5c41f1d8..00000000 --- a/framework/src/suricata/src/detect-icmp-seq.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. -*/ - -/** - * \file - * - * \author Breno Silva - */ - -#ifndef __DETECT_ICMP_SEQ_H__ -#define __DETECT_ICMP_SEQ_H__ - -typedef struct DetectIcmpSeqData_ { - uint16_t seq; /**< sequence value in network byte order */ -} DetectIcmpSeqData; - -/* prototypes */ -void DetectIcmpSeqRegister(void); - -#endif /* __DETECT_ICMP_SEQ__ */ - diff --git a/framework/src/suricata/src/detect-icode.c b/framework/src/suricata/src/detect-icode.c deleted file mode 100644 index 05c35a72..00000000 --- a/framework/src/suricata/src/detect-icode.c +++ /dev/null @@ -1,528 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias - * - * Implements icode keyword support - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-icode.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -/** - *\brief Regex for parsing our icode options - */ -#define PARSE_REGEX "^\\s*(<|>)?\\s*([0-9]+)\\s*(?:<>\\s*([0-9]+))?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectICodeMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectICodeSetup(DetectEngineCtx *, Signature *, char *); -void DetectICodeRegisterTests(void); -void DetectICodeFree(void *); - - -/** - * \brief Registration function for icode: keyword - */ -void DetectICodeRegister (void) -{ - sigmatch_table[DETECT_ICODE].name = "icode"; - sigmatch_table[DETECT_ICODE].desc = "match on specific ICMP id-value"; - sigmatch_table[DETECT_ICODE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#icode"; - sigmatch_table[DETECT_ICODE].Match = DetectICodeMatch; - sigmatch_table[DETECT_ICODE].Setup = DetectICodeSetup; - sigmatch_table[DETECT_ICODE].Free = DetectICodeFree; - sigmatch_table[DETECT_ICODE].RegisterTests = DetectICodeRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -/** - * \brief This function is used to match icode rule option set on a packet with those passed via icode: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectICodeData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectICodeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - int ret = 0; - uint8_t picode; - const DetectICodeData *icd = (const DetectICodeData *)ctx; - - if (PKT_IS_PSEUDOPKT(p)) - return 0; - - if (PKT_IS_ICMPV4(p)) { - picode = ICMPV4_GET_CODE(p); - } else if (PKT_IS_ICMPV6(p)) { - picode = ICMPV6_GET_CODE(p); - } else { - /* Packet not ICMPv4 nor ICMPv6 */ - return ret; - } - - switch(icd->mode) { - case DETECT_ICODE_EQ: - ret = (picode == icd->code1) ? 1 : 0; - break; - case DETECT_ICODE_LT: - ret = (picode < icd->code1) ? 1 : 0; - break; - case DETECT_ICODE_GT: - ret = (picode > icd->code1) ? 1 : 0; - break; - case DETECT_ICODE_RN: - ret = (picode >= icd->code1 && picode <= icd->code2) ? 1 : 0; - break; - } - - return ret; -} - -/** - * \brief This function is used to parse icode options passed via icode: keyword - * - * \param icodestr Pointer to the user provided icode options - * - * \retval icd pointer to DetectICodeData on success - * \retval NULL on failure - */ -DetectICodeData *DetectICodeParse(char *icodestr) -{ - DetectICodeData *icd = NULL; - char *args[3] = {NULL, NULL, NULL}; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, icodestr, strlen(icodestr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, icodestr); - goto error; - } - - int i; - const char *str_ptr; - for (i = 1; i < ret; i++) { - res = pcre_get_substring((char *)icodestr, ov, MAX_SUBSTRINGS, i, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[i-1] = (char *)str_ptr; - } - - icd = SCMalloc(sizeof(DetectICodeData)); - if (unlikely(icd == NULL)) - goto error; - icd->code1 = 0; - icd->code2 = 0; - icd->mode = 0; - - /* we have either "<" or ">" */ - if (args[0] != NULL && strlen(args[0]) != 0) { - /* we have a third part ("<> y"), therefore it's invalid */ - if (args[2] != NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "icode: invalid value"); - goto error; - } - /* we have only a comparison ("<", ">") */ - if (ByteExtractStringUint8(&icd->code1, 10, 0, args[1]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not " - "valid", args[1]); - goto error; - } - if ((strcmp(args[0], ">")) == 0) icd->mode = DETECT_ICODE_GT; - else icd->mode = DETECT_ICODE_LT; - } else { /* no "<", ">" */ - /* we have a range ("<>") */ - if (args[2] != NULL) { - icd->mode = (uint8_t) DETECT_ICODE_RN; - if (ByteExtractStringUint8(&icd->code1, 10, 0, args[1]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not " - "valid", args[1]); - goto error; - } - if (ByteExtractStringUint8(&icd->code2, 10, 0, args[2]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not " - "valid", args[2]); - goto error; - } - /* we check that the first given value in the range is less than - the second, otherwise we swap them */ - if (icd->code1 > icd->code2) { - uint8_t temp = icd->code1; - icd->code1 = icd->code2; - icd->code2 = temp; - } - } else { /* we have an equality */ - icd->mode = DETECT_ICODE_EQ; - if (ByteExtractStringUint8(&icd->code1, 10, 0, args[1]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not " - "valid", args[1]); - goto error; - } - } - } - - for (i = 0; i < (ret-1); i++) { - if (args[i] != NULL) - SCFree(args[i]); - } - return icd; - -error: - for (i = 0; i < (ret-1) && i < 3; i++) { - if (args[i] != NULL) - SCFree(args[i]); - } - if (icd != NULL) - DetectICodeFree(icd); - return NULL; -} - -/** - * \brief this function is used to add the parsed icode data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param icodestr pointer to the user provided icode options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectICodeSetup(DetectEngineCtx *de_ctx, Signature *s, char *icodestr) -{ - - DetectICodeData *icd = NULL; - SigMatch *sm = NULL; - - icd = DetectICodeParse(icodestr); - if (icd == NULL) goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) goto error; - - sm->type = DETECT_ICODE; - sm->ctx = (SigMatchCtx *)icd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (icd != NULL) DetectICodeFree(icd); - if (sm != NULL) SCFree(sm); - return -1; -} - -/** - * \brief this function will free memory associated with DetectICodeData - * - * \param ptr pointer to DetectICodeData - */ -void DetectICodeFree(void *ptr) -{ - DetectICodeData *icd = (DetectICodeData *)ptr; - SCFree(icd); -} - -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -/** - * \test DetectICodeParseTest01 is a test for setting a valid icode value - */ -int DetectICodeParseTest01(void) -{ - DetectICodeData *icd = NULL; - int result = 0; - icd = DetectICodeParse("8"); - if (icd != NULL) { - if (icd->code1 == 8 && icd->mode == DETECT_ICODE_EQ) - result = 1; - DetectICodeFree(icd); - } - return result; -} - -/** - * \test DetectICodeParseTest02 is a test for setting a valid icode value - * with ">" operator - */ -int DetectICodeParseTest02(void) -{ - DetectICodeData *icd = NULL; - int result = 0; - icd = DetectICodeParse(">8"); - if (icd != NULL) { - if (icd->code1 == 8 && icd->mode == DETECT_ICODE_GT) - result = 1; - DetectICodeFree(icd); - } - return result; -} - -/** - * \test DetectICodeParseTest03 is a test for setting a valid icode value - * with "<" operator - */ -int DetectICodeParseTest03(void) -{ - DetectICodeData *icd = NULL; - int result = 0; - icd = DetectICodeParse("<8"); - if (icd != NULL) { - if (icd->code1 == 8 && icd->mode == DETECT_ICODE_LT) - result = 1; - DetectICodeFree(icd); - } - return result; -} - -/** - * \test DetectICodeParseTest04 is a test for setting a valid icode value - * with "<>" operator - */ -int DetectICodeParseTest04(void) -{ - DetectICodeData *icd = NULL; - int result = 0; - icd = DetectICodeParse("8<>20"); - if (icd != NULL) { - if (icd->code1 == 8 && icd->code2 == 20 && icd->mode == DETECT_ICODE_RN) - result = 1; - DetectICodeFree(icd); - } - return result; -} - -/** - * \test DetectICodeParseTest05 is a test for setting a valid icode value - * with spaces all around - */ -int DetectICodeParseTest05(void) -{ - DetectICodeData *icd = NULL; - int result = 0; - icd = DetectICodeParse(" 8 "); - if (icd != NULL) { - if (icd->code1 == 8 && icd->mode == DETECT_ICODE_EQ) - result = 1; - DetectICodeFree(icd); - } - return result; -} - -/** - * \test DetectICodeParseTest06 is a test for setting a valid icode value - * with ">" operator and spaces all around - */ -int DetectICodeParseTest06(void) -{ - DetectICodeData *icd = NULL; - int result = 0; - icd = DetectICodeParse(" > 8 "); - if (icd != NULL) { - if (icd->code1 == 8 && icd->mode == DETECT_ICODE_GT) - result = 1; - DetectICodeFree(icd); - } - return result; -} - -/** - * \test DetectICodeParseTest07 is a test for setting a valid icode value - * with "<>" operator and spaces all around - */ -int DetectICodeParseTest07(void) -{ - DetectICodeData *icd = NULL; - int result = 0; - icd = DetectICodeParse(" 8 <> 20 "); - if (icd != NULL) { - if (icd->code1 == 8 && icd->code2 == 20 && icd->mode == DETECT_ICODE_RN) - result = 1; - DetectICodeFree(icd); - } - return result; -} - -/** - * \test DetectICodeParseTest08 is a test for setting an invalid icode value - */ -int DetectICodeParseTest08(void) -{ - DetectICodeData *icd = NULL; - icd = DetectICodeParse("> 8 <> 20"); - if (icd == NULL) - return 1; - DetectICodeFree(icd); - return 0; -} - -/** - * \test DetectICodeMatchTest01 is a test for checking the working of icode - * keyword by creating 5 rules and matching a crafted packet against - * them. 4 out of 5 rules shall trigger. - */ -int DetectICodeMatchTest01(void) -{ - - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); - - p->icmpv4h->code = 10; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert icmp any any -> any any (icode:10; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:<15; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:>20; sid:3;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:8<>20; sid:4;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:20<>8; sid:5;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 0) { - SCLogDebug("sid 1 did not alert, but should have"); - goto cleanup; - } else if (PacketAlertCheck(p, 2) == 0) { - SCLogDebug("sid 2 did not alert, but should have"); - goto cleanup; - } else if (PacketAlertCheck(p, 3)) { - SCLogDebug("sid 3 alerted, but should not have"); - goto cleanup; - } else if (PacketAlertCheck(p, 4) == 0) { - SCLogDebug("sid 4 did not alert, but should have"); - goto cleanup; - } else if (PacketAlertCheck(p, 5) == 0) { - SCLogDebug("sid 5 did not alert, but should have"); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); -end: - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectICode - */ -void DetectICodeRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectICodeParseTest01", DetectICodeParseTest01, 1); - UtRegisterTest("DetectICodeParseTest02", DetectICodeParseTest02, 1); - UtRegisterTest("DetectICodeParseTest03", DetectICodeParseTest03, 1); - UtRegisterTest("DetectICodeParseTest04", DetectICodeParseTest04, 1); - UtRegisterTest("DetectICodeParseTest05", DetectICodeParseTest05, 1); - UtRegisterTest("DetectICodeParseTest06", DetectICodeParseTest06, 1); - UtRegisterTest("DetectICodeParseTest07", DetectICodeParseTest07, 1); - UtRegisterTest("DetectICodeParseTest08", DetectICodeParseTest08, 1); - UtRegisterTest("DetectICodeMatchTest01", DetectICodeMatchTest01, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-icode.h b/framework/src/suricata/src/detect-icode.h deleted file mode 100644 index 88a4d481..00000000 --- a/framework/src/suricata/src/detect-icode.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \file detect-icode.c - * - * \author Gerardo Iglesias - */ - -#ifndef __DETECT_ICODE_H__ -#define __DETECT_ICODE_H__ - -#define DETECT_ICODE_EQ 0 /**< "equal" operator */ -#define DETECT_ICODE_LT 1 /**< "less than" operator */ -#define DETECT_ICODE_GT 2 /**< "greater than" operator */ -#define DETECT_ICODE_RN 3 /**< "range" operator */ - -typedef struct DetectICodeData_ { - uint8_t code1; - uint8_t code2; - - uint8_t mode; -}DetectICodeData; - -/* prototypes */ -void DetectICodeRegister(void); - -#endif /* __DETECT_ICODE_H__ */ diff --git a/framework/src/suricata/src/detect-id.c b/framework/src/suricata/src/detect-id.c deleted file mode 100644 index 5df2a6d1..00000000 --- a/framework/src/suricata/src/detect-id.c +++ /dev/null @@ -1,384 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * Implements the id keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "detect-id.h" -#include "flow.h" -#include "flow-var.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -/** - * \brief Regex for parsing "id" option, matching number or "number" - */ -#define PARSE_REGEX "^\\s*([0-9]{1,5}|\"[0-9]{1,5}\")\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectIdMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectIdSetup (DetectEngineCtx *, Signature *, char *); -void DetectIdRegisterTests(void); -void DetectIdFree(void *); - -/** - * \brief Registration function for keyword: id - */ -void DetectIdRegister (void) -{ - sigmatch_table[DETECT_ID].name = "id"; - sigmatch_table[DETECT_ID].desc = "match on a specific IP ID value"; - sigmatch_table[DETECT_ID].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#Id"; - sigmatch_table[DETECT_ID].Match = DetectIdMatch; - sigmatch_table[DETECT_ID].Setup = DetectIdSetup; - sigmatch_table[DETECT_ID].Free = DetectIdFree; - sigmatch_table[DETECT_ID].RegisterTests = DetectIdRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - SCLogDebug("registering id rule option"); - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -/** - * \brief This function is used to match the specified id on a packet - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectIdData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectIdMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, - Signature *s, const SigMatchCtx *ctx) -{ - const DetectIdData *id_d = (const DetectIdData *)ctx; - - /** - * To match a ipv4 packet with a "id" rule - */ - if (!PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p)) { - return 0; - } - - if (id_d->id == IPV4_GET_IPID(p)) { - SCLogDebug("IPV4 Proto and matched with ip_id: %u.\n", - id_d->id); - return 1; - } - - return 0; -} - -/** - * \brief This function is used to parse IPV4 ip_id passed via keyword: "id" - * - * \param idstr Pointer to the user provided id option - * - * \retval id_d pointer to DetectIdData on success - * \retval NULL on failure - */ -DetectIdData *DetectIdParse (char *idstr) -{ - uint32_t temp; - DetectIdData *id_d = NULL; - #define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, idstr, strlen(idstr), 0, 0, - ov, MAX_SUBSTRINGS); - - if (ret < 1 || ret > 3) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid id option. The id option value must be" - " in the range %u - %u", - DETECT_IPID_MIN, DETECT_IPID_MAX); - goto error; - } - - - if (ret > 1) { - char copy_str[128] = ""; - char *tmp_str; - res = pcre_copy_substring((char *)idstr, ov, MAX_SUBSTRINGS, 1, - copy_str, sizeof(copy_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - tmp_str = copy_str; - - /* Let's see if we need to scape "'s */ - if (tmp_str[0] == '"') - { - tmp_str[strlen(tmp_str) - 1] = '\0'; - tmp_str += 1; - } - - /* ok, fill the id data */ - temp = atoi((char *)tmp_str); - - if (temp > DETECT_IPID_MAX) { - SCLogError(SC_ERR_INVALID_VALUE, "\"id\" option must be in " - "the range %u - %u", - DETECT_IPID_MIN, DETECT_IPID_MAX); - goto error; - } - - /* We have a correct id option */ - id_d = SCMalloc(sizeof(DetectIdData)); - if (unlikely(id_d == NULL)) - goto error; - - id_d->id = temp; - - SCLogDebug("detect-id: will look for ip_id: %u\n", id_d->id); - } - - return id_d; - -error: - if (id_d != NULL) - DetectIdFree(id_d); - return NULL; - -} - -/** - * \brief this function is used to add the parsed "id" option - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param idstr pointer to the user provided "id" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectIdSetup (DetectEngineCtx *de_ctx, Signature *s, char *idstr) -{ - DetectIdData *id_d = NULL; - SigMatch *sm = NULL; - - id_d = DetectIdParse(idstr); - if (id_d == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_ID; - sm->ctx = (SigMatchCtx *)id_d; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (id_d != NULL) DetectIdFree(id_d); - if (sm != NULL) SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectIdData - * - * \param id_d pointer to DetectIdData - */ -void DetectIdFree(void *ptr) -{ - DetectIdData *id_d = (DetectIdData *)ptr; - SCFree(id_d); -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectIdTestParse01 is a test to make sure that we parse the "id" - * option correctly when given valid id option - */ -int DetectIdTestParse01 (void) -{ - DetectIdData *id_d = NULL; - id_d = DetectIdParse(" 35402 "); - if (id_d != NULL &&id_d->id==35402) { - DetectIdFree(id_d); - return 1; - } - - return 0; -} - -/** - * \test DetectIdTestParse02 is a test to make sure that we parse the "id" - * option correctly when given an invalid id option - * it should return id_d = NULL - */ -int DetectIdTestParse02 (void) -{ - DetectIdData *id_d = NULL; - id_d = DetectIdParse("65537"); - if (id_d == NULL) { - DetectIdFree(id_d); - return 1; - } - - return 0; -} - -/** - * \test DetectIdTestParse03 is a test to make sure that we parse the "id" - * option correctly when given an invalid id option - * it should return id_d = NULL - */ -int DetectIdTestParse03 (void) -{ - DetectIdData *id_d = NULL; - id_d = DetectIdParse("12what?"); - if (id_d == NULL) { - DetectIdFree(id_d); - return 1; - } - - return 0; -} - -/** - * \test DetectIdTestParse04 is a test to make sure that we parse the "id" - * option correctly when given valid id option but wrapped with "'s - */ -int DetectIdTestParse04 (void) -{ - DetectIdData *id_d = NULL; - /* yep, look if we trim blank spaces correctly and ignore "'s */ - id_d = DetectIdParse(" \"35402\" "); - if (id_d != NULL &&id_d->id==35402) { - DetectIdFree(id_d); - return 1; - } - - return 0; -} - -/** - * \test DetectIdTestSig01 - * \brief Test to check "id" keyword with constructed packets - */ -int DetectIdTestMatch01(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[1] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_UDP); - p[2] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_ICMP); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - /* TCP IP id = 1234 */ - p[0]->ip4h->ip_id = htons(1234); - - /* UDP IP id = 5678 */ - p[1]->ip4h->ip_id = htons(5678); - - /* UDP IP id = 91011 */ - p[2]->ip4h->ip_id = htons(5101); - - char *sigs[3]; - sigs[0]= "alert ip any any -> any any (msg:\"Testing id 1\"; id:1234; sid:1;)"; - sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; id:5678; sid:2;)"; - sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; id:5101; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - /* packet 0 match sid 1 but should not match sid 2 */ - {1, 0, 0}, - /* packet 1 should not match */ - {0, 1, 0}, - /* packet 2 should not match */ - {0, 0, 1} }; - - result = UTHGenericTest(p, 3, sigs, sid, (uint32_t *) results, 3); - - UTHFreePackets(p, 3); -end: - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectId - */ -void DetectIdRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectIdTestParse01", DetectIdTestParse01, 1); - UtRegisterTest("DetectIdTestParse02", DetectIdTestParse02, 1); - UtRegisterTest("DetectIdTestParse03", DetectIdTestParse03, 1); - UtRegisterTest("DetectIdTestParse04", DetectIdTestParse04, 1); - UtRegisterTest("DetectIdTestMatch01", DetectIdTestMatch01, 1); - -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-id.h b/framework/src/suricata/src/detect-id.h deleted file mode 100644 index 3198c9c3..00000000 --- a/framework/src/suricata/src/detect-id.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - */ - -#ifndef __DETECT_ID_H__ -#define __DETECT_ID_H__ - - -#define DETECT_IPID_MIN 0 -#define DETECT_IPID_MAX 65536 - -typedef struct DetectIdData_ { - uint16_t id; /** ip->id to match */ -} DetectIdData; - -/* prototypes */ -void DetectIdRegister (void); - -#endif /* __DETECT_ID_H__ */ - diff --git a/framework/src/suricata/src/detect-ipopts.c b/framework/src/suricata/src/detect-ipopts.c deleted file mode 100644 index 159578ee..00000000 --- a/framework/src/suricata/src/detect-ipopts.c +++ /dev/null @@ -1,386 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * - * Implements the ipopts keyword - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "flow-var.h" -#include "decode-events.h" - -#include "util-debug.h" - -/* Need to get the DIpOpts[] array */ -#define DETECT_EVENTS - -#include "detect-ipopts.h" -#include "util-unittest.h" - -#define PARSE_REGEX "\\S[A-z]" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectIpOptsMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectIpOptsSetup (DetectEngineCtx *, Signature *, char *); -void IpOptsRegisterTests(void); -void DetectIpOptsFree(void *); - -/** - * \brief Registration function for ipopts: keyword - */ -void DetectIpOptsRegister (void) -{ - sigmatch_table[DETECT_IPOPTS].name = "ipopts"; - sigmatch_table[DETECT_IPOPTS].desc = "check if a specific IP option is set"; - sigmatch_table[DETECT_IPOPTS].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#Ipopts"; - sigmatch_table[DETECT_IPOPTS].Match = DetectIpOptsMatch; - sigmatch_table[DETECT_IPOPTS].Setup = DetectIpOptsSetup; - sigmatch_table[DETECT_IPOPTS].Free = DetectIpOptsFree; - sigmatch_table[DETECT_IPOPTS].RegisterTests = IpOptsRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; - -} - -/** - * \internal - * \brief This function is used to match ip option on a packet with those passed via ipopts: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param s pointer to the Signature - * \param m pointer to the sigmatch - * - * \retval 0 no match - * \retval 1 match - */ -int DetectIpOptsMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - int ret = 0; - int ipopt = 0; - const DetectIpOptsData *de = (const DetectIpOptsData *)ctx; - - if (!de || !PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p)) - return ret; - - /* IPV4_OPT_ANY matches on any options */ - - if (p->IPV4_OPTS_CNT && (de->ipopt == IPV4_OPT_ANY)) { - return 1; - } - - /* Loop through instead of using o_xxx direct access fields so that - * future options do not require any modification here. - */ - - while(ipopt < p->IPV4_OPTS_CNT) { - if (p->IPV4_OPTS[ipopt].type == de->ipopt) { - return 1; - } - ipopt++; - } - - return ret; -} - -/** - * \internal - * \brief This function is used to parse ipopts options passed via ipopts: keyword - * - * \param rawstr Pointer to the user provided ipopts options - * - * \retval de pointer to DetectIpOptsData on success - * \retval NULL on failure - */ -DetectIpOptsData *DetectIpOptsParse (char *rawstr) -{ - int i; - DetectIpOptsData *de = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, found = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr); - goto error; - } - - for(i = 0; DIpOpts[i].ipopt_name != NULL; i++) { - if((strcasecmp(DIpOpts[i].ipopt_name,rawstr)) == 0) { - found = 1; - break; - } - } - - if(found == 0) - goto error; - - de = SCMalloc(sizeof(DetectIpOptsData)); - if (unlikely(de == NULL)) - goto error; - - de->ipopt = DIpOpts[i].code; - - return de; - -error: - if (de) SCFree(de); - return NULL; -} - -/** - * \internal - * \brief this function is used to add the parsed ipopts into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param rawstr pointer to the user provided ipopts options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectIpOptsSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectIpOptsData *de = NULL; - SigMatch *sm = NULL; - - de = DetectIpOptsParse(rawstr); - if (de == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_IPOPTS; - sm->ctx = (SigMatchCtx *)de; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - return -1; -} - -/** - * \internal - * \brief this function will free memory associated with DetectIpOptsData - * - * \param de pointer to DetectIpOptsData - */ -void DetectIpOptsFree(void *de_ptr) -{ - DetectIpOptsData *de = (DetectIpOptsData *)de_ptr; - if(de) SCFree(de); -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -/** - * \test IpOptsTestParse01 is a test for a valid ipopts value - * - * \retval 1 on succces - * \retval 0 on failure - */ -int IpOptsTestParse01 (void) -{ - DetectIpOptsData *de = NULL; - de = DetectIpOptsParse("lsrr"); - if (de) { - DetectIpOptsFree(de); - return 1; - } - - return 0; -} - -/** - * \test IpOptsTestParse02 is a test for an invalid ipopts value - * - * \retval 1 on succces - * \retval 0 on failure - */ -int IpOptsTestParse02 (void) -{ - DetectIpOptsData *de = NULL; - de = DetectIpOptsParse("invalidopt"); - if (de) { - DetectIpOptsFree(de); - return 1; - } - - return 0; -} - -/** - * \test IpOptsTestParse03 test the match function on a packet that needs to match - * - * \retval 1 on succces - * \retval 0 on failure - */ -int IpOptsTestParse03 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectIpOptsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ip4h; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ip4h, 0, sizeof(IPV4Hdr)); - - p->ip4h = &ip4h; - p->IPV4_OPTS[0].type = IPV4_OPT_RR; - - p->IPV4_OPTS_CNT++; - - de = DetectIpOptsParse("rr"); - - if (de == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_IPOPTS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectIpOptsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} - -/** - * \test IpOptsTestParse04 test the match function on a packet that needs to not match - * - * \retval 1 on succces - * \retval 0 on failure - */ -int IpOptsTestParse04 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - int ret = 0; - DetectIpOptsData *de = NULL; - SigMatch *sm = NULL; - IPV4Hdr ip4h; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ip4h, 0, sizeof(IPV4Hdr)); - - p->ip4h = &ip4h; - p->IPV4_OPTS[0].type = IPV4_OPT_RR; - - p->IPV4_OPTS_CNT++; - - de = DetectIpOptsParse("lsrr"); - - if (de == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_IPOPTS; - sm->ctx = (SigMatchCtx *)de; - - ret = DetectIpOptsMatch(&tv, NULL, p, NULL, sm->ctx); - - if(ret) { - SCFree(p); - return 1; - } - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - SCFree(p); - return 0; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for IpOpts - */ -void IpOptsRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("IpOptsTestParse01", IpOptsTestParse01, 1); - UtRegisterTest("IpOptsTestParse02", IpOptsTestParse02, 0); - UtRegisterTest("IpOptsTestParse03", IpOptsTestParse03, 1); - UtRegisterTest("IpOptsTestParse04", IpOptsTestParse04, 0); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-ipopts.h b/framework/src/suricata/src/detect-ipopts.h deleted file mode 100644 index bd346256..00000000 --- a/framework/src/suricata/src/detect-ipopts.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - */ - -#ifndef __DETECT_IPOPTS_H__ -#define __DETECT_IPOPTS_H__ - -#include "decode-events.h" -#include "decode-ipv4.h" - -/** - * \struct DetectIpOptsData_ - * DetectIpOptsData_ is used to store ipopts: input value - */ - -/** - * \typedef DetectIpOptsData - * A typedef for DetectIpOptsData_ - */ - -typedef struct DetectIpOptsData_ { - uint8_t ipopt; /**< Ip option */ -} DetectIpOptsData; - -/** - * Registration function for ipopts: keyword - */ - -void DetectIpOptsRegister (void); - -#ifdef DETECT_EVENTS - -/** - * Used to check ipopts:any - */ - -#define IPV4_OPT_ANY 0xff - -/** - * \struct DetectIpOptss_ - * DetectIpOptss_ is used to store supported iptops values - */ - -struct DetectIpOptss_ { - char *ipopt_name; /**< Ip option name */ - uint8_t code; /**< Ip option value */ -} DIpOpts[] = { - { "rr", IPV4_OPT_RR, }, - { "lsrr", IPV4_OPT_LSRR, }, - { "eol", IPV4_OPT_EOL, }, - { "nop", IPV4_OPT_NOP, }, - { "ts", IPV4_OPT_TS, }, - { "sec", IPV4_OPT_SEC, }, - { "ssrr", IPV4_OPT_SSRR, }, - { "satid", IPV4_OPT_SID, }, - { "any", IPV4_OPT_ANY, }, - { NULL, 0 }, -}; -#endif /* DETECT_EVENTS */ -#endif /*__DETECT_IPOPTS_H__ */ - diff --git a/framework/src/suricata/src/detect-ipproto.c b/framework/src/suricata/src/detect-ipproto.c deleted file mode 100644 index d8ffc44b..00000000 --- a/framework/src/suricata/src/detect-ipproto.c +++ /dev/null @@ -1,9609 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - * - * Implements the ip_proto keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-ipproto.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "detect-engine-siggroup.h" -#include "detect-engine-address.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "util-debug.h" - -/** - * \brief Regex for parsing our options - */ -#define PARSE_REGEX "^\\s*" \ - "([!<>]?)" \ - "\\s*([^\\s]+)" \ - "\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -static int DetectIPProtoSetup(DetectEngineCtx *, Signature *, char *); -static DetectIPProtoData *DetectIPProtoParse(const char *); -static void DetectIPProtoRegisterTests(void); -static void DetectIPProtoFree(void *); - -void DetectIPProtoRegister(void) -{ - const char *eb; - int eo; - int opts = 0; - - sigmatch_table[DETECT_IPPROTO].name = "ip_proto"; - sigmatch_table[DETECT_IPPROTO].desc = "match on the IP protocol in the packet-header"; - sigmatch_table[DETECT_IPPROTO].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#ip_proto"; - sigmatch_table[DETECT_IPPROTO].Match = NULL; - sigmatch_table[DETECT_IPPROTO].Setup = DetectIPProtoSetup; - sigmatch_table[DETECT_IPPROTO].Free = DetectIPProtoFree; - sigmatch_table[DETECT_IPPROTO].RegisterTests = DetectIPProtoRegisterTests; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at " - "offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - if (parse_regex) - pcre_free(parse_regex); - if (parse_regex_study) - pcre_free_study(parse_regex_study); - return; -} - -/** - * \internal - * \brief Parse ip_proto options string. - * - * \param optstr Options string to parse - * - * \return New ip_proto data structure - */ -static DetectIPProtoData *DetectIPProtoParse(const char *optstr) -{ - DetectIPProtoData *data = NULL; - char *args[2] = { NULL, NULL }; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - int i; - const char *str_ptr; - - /* Execute the regex and populate args with captures. */ - ret = pcre_exec(parse_regex, parse_regex_study, optstr, - strlen(optstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret != 3) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret" - "%" PRId32 ", string %s", ret, optstr); - goto error; - } - - for (i = 0; i < (ret - 1); i++) { - res = pcre_get_substring((char *)optstr, ov, MAX_SUBSTRINGS, - i + 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[i] = (char *)str_ptr; - } - - /* Initialize the data */ - data = SCMalloc(sizeof(DetectIPProtoData)); - if (unlikely(data == NULL)) - goto error; - data->op = DETECT_IPPROTO_OP_EQ; - data->proto = 0; - - /* Operator */ - if (*(args[0]) != '\0') { - data->op = *(args[0]); - } - - /* Protocol name/number */ - if (!isdigit((unsigned char)*(args[1]))) { - struct protoent *pent = getprotobyname(args[1]); - if (pent == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed protocol name: %s", - str_ptr); - goto error; - } - data->proto = (uint8_t)pent->p_proto; - } - else { - if (ByteExtractStringUint8(&data->proto, 10, 0, args[1]) <= 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Malformed protocol number: %s", - str_ptr); - goto error; - } - } - - for (i = 0; i < (ret - 1); i++){ - if (args[i] != NULL) - SCFree(args[i]); - } - - return data; - -error: - for (i = 0; i < (ret - 1) && i < 2; i++){ - if (args[i] != NULL) - SCFree(args[i]); - } - if (data != NULL) - SCFree(data); - - return NULL; -} - -static int DetectIPProtoTypePresentForOP(Signature *s, uint8_t op) -{ - SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - DetectIPProtoData *data; - - while (sm != NULL) { - if (sm->type == DETECT_IPPROTO) { - data = (DetectIPProtoData *)sm->ctx; - if (data->op == op) - return 1; - } - sm = sm->next; - } - - return 0; -} - -/* Updated by AS. Please do not remove this unused code. - * Need it as we redo this code once we solve ipproto - * multiple uses */ -#if 0 -static int DetectIPProtoQSortCompare(const void *a, const void *b) -{ - const uint8_t *one = a; - const uint8_t *two = b; - - return ((int)*one - *two); -} -#endif - -/** - * \internal - * \brief Setup ip_proto keyword. - * - * \param de_ctx Detection engine context - * \param s Signature - * \param optstr Options string - * - * \return Non-zero on error - */ -static int DetectIPProtoSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) -{ - SigMatch *sm = NULL; - DetectIPProtoData *data = NULL; - int i; - - data = DetectIPProtoParse((const char *)optstr); - if (data == NULL) { - goto error; - } - - /* Reset our "any" (or "ip") state: for ipv4, ipv6 and ip cases, the bitfield - * s->proto.proto have all bit set to 1 to be able to match any protocols. ipproto - * will refined the protocol list and thus it needs to reset the bitfield to zero - * before setting the value specified by the ip_proto keyword. - */ - if (s->proto.flags & (DETECT_PROTO_ANY | DETECT_PROTO_IPV6 | DETECT_PROTO_IPV4)) { - s->proto.flags &= ~DETECT_PROTO_ANY; - memset(s->proto.proto, 0x00, sizeof(s->proto.proto)); - s->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - } else { - /* The ipproto engine has a relationship with the protocol that is - * set after the action and also the app protocol(that can also be - * set through the app-layer-protocol. - * An ip_proto keyword can be used only with alert ip, which if - * not true we error out on the sig. And hence the init_flag to - * indicate this. */ - if (!(s->init_flags & SIG_FLAG_INIT_FIRST_IPPROTO_SEEN)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Signature can use " - "ip_proto keyword only when we use alert ip, " - "in which case the _ANY flag is set on the sig " - "and the if condition should match."); - goto error; - } - } - - int eq_set = DetectIPProtoTypePresentForOP(s, DETECT_IPPROTO_OP_EQ); - int gt_set = DetectIPProtoTypePresentForOP(s, DETECT_IPPROTO_OP_GT); - int lt_set = DetectIPProtoTypePresentForOP(s, DETECT_IPPROTO_OP_LT); - int not_set = DetectIPProtoTypePresentForOP(s, DETECT_IPPROTO_OP_NOT); - - switch (data->op) { - case DETECT_IPPROTO_OP_EQ: - if (eq_set || gt_set || lt_set || not_set) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a eq " - "ipproto without any operators attached to " - "them in the same sig"); - goto error; - } - s->proto.proto[data->proto / 8] |= 1 << (data->proto % 8); - break; - - case DETECT_IPPROTO_OP_GT: - if (eq_set || gt_set) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a eq or gt " - "ipproto along with a greater than ipproto in the " - "same sig "); - goto error; - } - if (!lt_set && !not_set) { - s->proto.proto[data->proto / 8] = 0xfe << (data->proto % 8); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] = 0xff; - } - } else if (lt_set && !not_set) { - SigMatch *temp_sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - while (temp_sm != NULL) { - if (temp_sm->type == DETECT_IPPROTO) { - break; - } - temp_sm = temp_sm->next; - } - if (temp_sm != NULL) { - DetectIPProtoData *data_temp = (DetectIPProtoData *)temp_sm->ctx; - if (data_temp->proto <= data->proto) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have " - "both gt and lt ipprotos, with the lt being " - "lower than gt value"); - goto error; - /* Updated by AS. Please do not remove this unused code. Need it - * as we redo this code once we solve ipproto multiple uses */ -#if 0 - s->proto.proto[data->proto / 8] |= 0xfe << (data->proto % 8); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] = 0xff; - } -#endif - } else { - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] = 0; - } - s->proto.proto[data->proto / 8] &= 0xfe << (data->proto % 8); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] &= 0xff; - } - } - } - } else if (!lt_set && not_set) { - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] = 0; - } - s->proto.proto[data->proto / 8] &= 0xfe << (data->proto % 8); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] &= 0xff; - } - } else { - DetectIPProtoData *data_temp; - SigMatch *temp_sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - while (temp_sm != NULL) { - if (temp_sm->type == DETECT_IPPROTO && - ((DetectIPProtoData *)temp_sm->ctx)->op == DETECT_IPPROTO_OP_LT) { - break; - } - temp_sm = temp_sm->next; - } - if (temp_sm != NULL) { - data_temp = (DetectIPProtoData *)temp_sm->ctx; - if (data_temp->proto <= data->proto) { - /* Updated by AS. Please do not remove this unused code. - * Need it as we redo this code once we solve ipproto - * multiple uses */ - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have " - "both gt and lt ipprotos, with the lt being " - "lower than gt value"); - goto error; -#if 0 - s->proto.proto[data->proto / 8] |= 0xfe << (data->proto % 8); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] = 0xff; - } - temp_sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - uint8_t *not_protos = NULL; - int not_protos_len = 0; - while (temp_sm != NULL) { - if (temp_sm->type == DETECT_IPPROTO && - ((DetectIPProtoData *)temp_sm->ctx)->op == DETECT_IPPROTO_OP_NOT) { - DetectIPProtoData *data_temp = temp_sm->ctx; - not_protos = SCRealloc(not_protos, - (not_protos_len + 1) * sizeof(uint8_t)); - if (not_protos == NULL) - goto error; - not_protos[not_protos_len] = data_temp->proto; - not_protos_len++; - } - temp_sm = temp_sm->next; - } - qsort(not_protos, not_protos_len, sizeof(uint8_t), - DetectIPProtoQSortCompare); - int j = 0; - while (j < not_protos_len) { - if (not_protos[j] < data->proto) { - ; - } else { - s->proto.proto[not_protos[j] / 8] &= ~(1 << (not_protos[j] % 8)); - } - j++; - } -#endif - } else { - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] = 0; - } - s->proto.proto[data->proto / 8] &= 0xfe << (data->proto % 8); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] &= 0xff; - } - } - } - } - break; - - case DETECT_IPPROTO_OP_LT: - if (eq_set || lt_set) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a eq or lt " - "ipproto along with a less than ipproto in the " - "same sig "); - goto error; - } - if (!gt_set && !not_set) { - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] = 0xff; - } - s->proto.proto[data->proto / 8] = ~(0xff << (data->proto % 8)); - } else if (gt_set && !not_set) { - SigMatch *temp_sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - while (temp_sm != NULL) { - if (temp_sm->type == DETECT_IPPROTO) { - break; - } - temp_sm = temp_sm->next; - } - if (temp_sm != NULL) { - DetectIPProtoData *data_temp = (DetectIPProtoData *)temp_sm->ctx; - if (data_temp->proto >= data->proto) { - /* Updated by AS. Please do not remove this unused code. - * Need it as we redo this code once we solve ipproto - * multiple uses */ - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a have " - "both gt and lt ipprotos, with the lt being " - "lower than gt value"); - goto error; -#if 0 - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] = 0xff; - } - s->proto.proto[data->proto / 8] |= ~(0xff << (data->proto % 8));; -#endif - } else { - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] &= 0xff; - } - s->proto.proto[data->proto / 8] &= ~(0xff << (data->proto % 8)); - for (i = (data->proto / 8) + 1; i < 256 / 8; i++) { - s->proto.proto[i] = 0; - } - } - } - } else if (!gt_set && not_set) { - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] &= 0xFF; - } - s->proto.proto[data->proto / 8] &= ~(0xff << (data->proto % 8)); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] = 0; - } - } else { - DetectIPProtoData *data_temp; - SigMatch *temp_sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - while (temp_sm != NULL) { - if (temp_sm->type == DETECT_IPPROTO && - ((DetectIPProtoData *)temp_sm->ctx)->op == DETECT_IPPROTO_OP_GT) { - break; - } - temp_sm = temp_sm->next; - } - if (temp_sm != NULL) { - data_temp = (DetectIPProtoData *)temp_sm->ctx; - if (data_temp->proto >= data->proto) { - /* Updated by AS. Please do not remove this unused code. - * Need it as we redo this code once we solve ipproto - * multiple uses */ - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have " - "both gt and lt ipprotos, with the lt being " - "lower than gt value"); - goto error; -#if 0 - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] = 0xff; - } - s->proto.proto[data->proto / 8] |= ~(0xff << (data->proto % 8)); - temp_sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - uint8_t *not_protos = NULL; - int not_protos_len = 0; - while (temp_sm != NULL) { - if (temp_sm->type == DETECT_IPPROTO && - ((DetectIPProtoData *)temp_sm->ctx)->op == DETECT_IPPROTO_OP_NOT) { - DetectIPProtoData *data_temp = temp_sm->ctx; - not_protos = SCRealloc(not_protos, - (not_protos_len + 1) * sizeof(uint8_t)); - if (not_protos == NULL) - goto error; - not_protos[not_protos_len] = data_temp->proto; - not_protos_len++; - } - temp_sm = temp_sm->next; - } - qsort(not_protos, not_protos_len, sizeof(uint8_t), - DetectIPProtoQSortCompare); - int j = 0; - while (j < not_protos_len) { - if (not_protos[j] < data->proto) { - s->proto.proto[not_protos[j] / 8] &= ~(1 << (not_protos[j] % 8)); - } else { - ; - } - j++; - } -#endif - } else { - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] &= 0xFF; - } - s->proto.proto[data->proto / 8] &= ~(0xff << (data->proto % 8)); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] = 0; - } - } - } - } - break; - - case DETECT_IPPROTO_OP_NOT: - if (eq_set) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a eq " - "ipproto along with a not ipproto in the " - "same sig "); - goto error; - } - if (!gt_set && !lt_set && !not_set) { - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] = 0xff; - } - s->proto.proto[data->proto / 8] = ~(1 << (data->proto % 8)); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] = 0xff; - } - } else { - for (i = 0; i < (data->proto / 8); i++) { - s->proto.proto[i] &= 0xff; - } - s->proto.proto[data->proto / 8] &= ~(1 << (data->proto % 8)); - for (i = (data->proto / 8) + 1; i < (256 / 8); i++) { - s->proto.proto[i] &= 0xff; - } - } - break; - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - sm->type = DETECT_IPPROTO; - sm->ctx = (void *)data; - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - - error: - - return -1; -} - - -void DetectIPProtoRemoveAllSMs(Signature *s) -{ - SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - - while (sm != NULL) { - if (sm->type != DETECT_IPPROTO) { - sm = sm->next; - continue; - } - SigMatch *tmp_sm = sm->next; - SigMatchRemoveSMFromList(s, sm, DETECT_SM_LIST_MATCH); - SigMatchFree(sm); - sm = tmp_sm; - } - - return; -} - -static void DetectIPProtoFree(void *ptr) -{ - DetectIPProtoData *data = (DetectIPProtoData *)ptr; - if (data) { - SCFree(data); - } -} - -/* UNITTESTS */ -#ifdef UNITTESTS - -#include "detect-engine.h" -#include "detect-parse.h" - -/** - * \test DetectIPProtoTestParse01 is a test for an invalid proto number - */ -static int DetectIPProtoTestParse01(void) -{ - int result = 0; - DetectIPProtoData *data = NULL; - data = DetectIPProtoParse("999"); - if (data == NULL) { - result = 1; - } - - if (data) - SCFree(data); - - return result; -} - -/** - * \test DetectIPProtoTestParse02 is a test for an invalid proto name - */ -static int DetectIPProtoTestParse02(void) -{ - int result = 0; - DetectIPProtoData *data = NULL; - data = DetectIPProtoParse("foobarbooeek"); - if (data == NULL) { - result = 1; - } - - if (data) - SCFree(data); - - return result; -} - -/** - * \test DetectIPProtoTestSetup01 is a test for a protocol number - */ -static int DetectIPProtoTestSetup01(void) -{ - int result = 0; - Signature *sig; - char *value_str = "14"; - int value = atoi(value_str); - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - DetectIPProtoSetup(NULL, sig, value_str); - for (i = 0; i < (value / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value / 8] != 0x40) { - goto end; - } - for (i = (value / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - -end: - SigFree(sig); - return result; -} - -/** - * \test DetectIPProtoTestSetup02 is a test for a protocol name - */ -static int DetectIPProtoTestSetup02(void) -{ - int result = 0; - Signature *sig = NULL; - char *value_str = "tcp"; - struct protoent *pent = getprotobyname(value_str); - if (pent == NULL) { - goto end; - } - uint8_t value = (uint8_t)pent->p_proto; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - DetectIPProtoSetup(NULL, sig, value_str); - for (i = 0; i < (value / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value / 8] != 0x40) { - goto end; - } - for (i = (value / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - if (sig != NULL) - SigFree(sig); - return result; -} - -/** - * \test DetectIPProtoTestSetup03 is a test for a < operator - */ -static int DetectIPProtoTestSetup03(void) -{ - int result = 0; - Signature *sig; - char *value_str = "<14"; - int value = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - DetectIPProtoSetup(NULL, sig, value_str); - for (i = 0; i < (value / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value / 8] != 0x3F) { - goto end; - } - for (i = (value / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test DetectIPProtoTestSetup04 is a test for a > operator - */ -static int DetectIPProtoTestSetup04(void) -{ - int result = 0; - Signature *sig; - char *value_str = ">14"; - int value = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - DetectIPProtoSetup(NULL, sig, value_str); - for (i = 0; i < (value / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value / 8] != 0x80) { - goto end; - } - for (i = (value / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test DetectIPProtoTestSetup05 is a test for a ! operator - */ -static int DetectIPProtoTestSetup05(void) -{ - int result = 0; - Signature *sig; - char *value_str = "!14"; - int value = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - DetectIPProtoSetup(NULL, sig, value_str); - for (i = 0; i < (value / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value / 8] != 0xBF) { - goto end; - } - for (i = (value / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test Negative test. - */ -static int DetectIPProtoTestSetup06(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "14"; - char *value2_str = "15"; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != -1) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test Negative test. - */ -static int DetectIPProtoTestSetup07(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "14"; - char *value2_str = "<15"; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != -1) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test Negative test. - */ -static int DetectIPProtoTestSetup08(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "14"; - char *value2_str = ">15"; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != -1) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test Negative test. - */ -static int DetectIPProtoTestSetup09(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "14"; - char *value2_str = "!15"; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != -1) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test Negative test. - */ -static int DetectIPProtoTestSetup10(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">14"; - char *value2_str = "15"; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != -1) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test Negative test. - */ -static int DetectIPProtoTestSetup11(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<14"; - char *value2_str = "15"; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != -1) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test Negative test. - */ -static int DetectIPProtoTestSetup12(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!14"; - char *value2_str = "15"; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != -1) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -/** - * \test Negative test. - */ -static int DetectIPProtoTestSetup13(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">14"; - char *value2_str = ">15"; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != -1) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup14(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<14"; - char *value2_str = "<15"; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != -1) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup15(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<14"; - int value1 = 14; - char *value2_str = ">34"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x3F) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<14"; - int value1 = 14; - char *value2_str = ">34"; - int value2 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x3F) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup16(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<14"; - char *value2_str = ">34"; - int value2 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<14"; - int value1 = 14; - char *value2_str = ">34"; - int value2 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x3F) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup17(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = ">13"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = ">13"; - int value2 = 13; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xC7) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xC7) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup18(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - char *value2_str = ">13"; - int value2 = 13; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xC0) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = ">13"; - int value2 = 13; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xC7) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xC7) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup19(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!13"; - char *value3_str = ">36"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!13"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup20(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value3_str = ">36"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!13"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup21(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!13"; - char *value3_str = ">36"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!13"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup22(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - char *value2_str = "!13"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!13"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup23(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!13"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup24(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - char *value2_str = "!13"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!13"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup25(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!18"; - char *value3_str = ">36"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!18"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup26(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value3_str = ">36"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!18"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup27(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!18"; - char *value3_str = ">36"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!18"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup28(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - char *value2_str = "!18"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!18"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup29(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!18"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup30(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - char *value2_str = "!18"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!18"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup31(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!34"; - char *value3_str = ">36"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!34"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup32(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value3_str = ">36"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!34"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup33(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!34"; - char *value3_str = ">36"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!34"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup34(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!34"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!34"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup35(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!34"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup36(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<11"; - char *value2_str = "!34"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<11"; - int value1 = 11; - char *value2_str = "!34"; - char *value3_str = ">36"; - int value3 = 36; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x07) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xE0) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup37(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int value3 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x83) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup38(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value3_str = ">14"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int value3 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x83) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup39(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value1 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int value3 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x83) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup40(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int value3 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x80) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int value3 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x83) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup41(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value3_str = ">14"; - int value3 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x80) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int value3 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x83) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup42(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int value3 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x80) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!12"; - char *value3_str = ">14"; - int value3 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x83) { - goto end; - } - for (i = (value3 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup43(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup44(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = "<13"; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup45(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup46(void) -{ - int result = 0; - Signature *sig; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup47(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = "<13"; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup48(void) -{ - int result = 0; - Signature *sig; - char *value2_str = "<13"; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup49(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!11"; - int value1 = 11; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x17) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!11"; - int value1 = 11; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x17) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup50(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!11"; - char *value2_str = "<13"; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!11"; - int value1 = 11; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x17) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup51(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!11"; - int value1 = 11; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x17) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!11"; - int value1 = 11; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x17) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup52(void) -{ - int result = 0; - Signature *sig; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x1F) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value3_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!11"; - int value1 = 11; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x17) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup53(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!11"; - char *value2_str = "<13"; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!11"; - int value1 = 11; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x17) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup54(void) -{ - int result = 0; - Signature *sig; - char *value2_str = "<13"; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "!11"; - int value1 = 11; - char *value2_str = "<13"; - int value2 = 13; - char *value3_str = ">34"; - int value3 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x17) { - goto end; - } - for (i = (value2 / 8) + 1; i < value3 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xF8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup55(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!37"; - int value3 = 37; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xD8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup56(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - char *value3_str = "!37"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!37"; - int value3 = 37; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xD8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup57(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - char *value2_str = ">34"; - int value2 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!37"; - int value3 = 37; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xD8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup58(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!37"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xD8) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!37"; - int value3 = 37; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xD8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup59(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - char *value3_str = "!37"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!37"; - int value3 = 37; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xD8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup60(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!37"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xD8) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!37"; - int value3 = 37; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xD8) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup61(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!44"; - int value3 = 44; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xEF) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup62(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - char *value3_str = "!44"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!44"; - int value3 = 44; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xEF) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup63(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - char *value2_str = ">34"; - int value2 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!44"; - int value3 = 44; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xEF) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup64(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!44"; - int value3 = 44; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xEF) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!44"; - int value3 = 44; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xEF) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup65(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - char *value3_str = "!44"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!44"; - int value3 = 44; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xEF) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup66(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<13"; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!44"; - int value3 = 44; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xEF) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; - -#if 0 - int result = 0; - Signature *sig; - char *value1_str = "<13"; - int value1 = 13; - char *value2_str = ">34"; - int value2 = 34; - char *value3_str = "!44"; - int value3 = 44; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1F) { - goto end; - } - for (i = (value1 / 8) + 1; i < value2 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value3 / 8] != 0xEF) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -#endif -} - -static int DetectIPProtoTestSetup67(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">14"; - int value1 = 14; - char *value2_str = "<34"; - int value2 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x80) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup68(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">14"; - int value1 = 14; - char *value2_str = "<34"; - int value2 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x80) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup69(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<14"; - int value2 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x38) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup70(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<14"; - int value2 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x38) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup71(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!14"; - int value2 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xB8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup72(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!14"; - int value2 = 14; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xB8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup73(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!34"; - int value2 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xFB) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup74(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!34"; - int value2 = 34; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xFB) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup75(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!8"; - char *value2_str = ">10"; - int value2 = 10; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup76(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!8"; - char *value2_str = ">10"; - int value2 = 10; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup77(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">10"; - int value2 = 10; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup78(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">10"; - int value2 = 10; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup79(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<10"; - int value2 = 10; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup80(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - int value1 = 4; - char *value2_str = "<10"; - int value2 = 10; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (sig->proto.proto[value1 / 8] != 0xEF) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup81(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!9"; - int value1 = 9; - char *value2_str = "<13"; - int value2 = 13; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1D) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup82(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!9"; - int value1 = 9; - char *value2_str = "<13"; - int value2 = 13; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x1D) { - goto end; - } - for (i = (value2 / 8) + 1; i < (256 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup83(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!13"; - int value2 = 13; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup84(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!13"; - int value2 = 13; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup85(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!35"; - int value2 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup86(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!35"; - int value2 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup87(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">10"; - int value2 = 10; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x07) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup88(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">10"; - int value2 = 10; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x07) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup89(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">10"; - int value2 = 10; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x07) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup90(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">10"; - int value2 = 10; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x07) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup91(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">10"; - int value2 = 10; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x07) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup92(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">10"; - int value2 = 10; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x07) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup93(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!9"; - char *value2_str = ">12"; - int value2 = 12; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xE0) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup94(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!9"; - char *value2_str = ">12"; - int value2 = 12; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xE0) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup95(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!9"; - char *value2_str = ">12"; - int value2 = 12; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xE0) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup96(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!9"; - char *value2_str = ">12"; - int value2 = 12; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xE0) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup97(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!9"; - char *value2_str = ">12"; - int value2 = 12; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xE0) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup98(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!9"; - char *value2_str = ">12"; - int value2 = 12; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xE0) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup99(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!13"; - int value2 = 13; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xD8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup100(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!13"; - int value2 = 13; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xD8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup101(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!13"; - int value2 = 13; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xD8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup102(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!13"; - int value2 = 13; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xD8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup103(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!13"; - int value2 = 13; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xD8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup104(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!13"; - int value2 = 13; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xD8) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup105(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!18"; - int value2 = 18; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xFB) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup106(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!18"; - int value2 = 18; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xFB) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup107(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!18"; - int value2 = 18; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xFB) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup108(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!18"; - int value2 = 18; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xFB) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup109(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!18"; - int value2 = 18; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xFB) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup110(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!18"; - int value2 = 18; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xFB) { - goto end; - } - for (i = (value2 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup111(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!33"; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x05) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup112(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!33"; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x05) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup113(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!33"; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x05) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup114(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!33"; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x05) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup115(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!33"; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x05) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup116(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!33"; - char *value3_str = "<35"; - int value3 = 35; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value3 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value3 / 8] != 0x05) { - goto end; - } - for (i = (value3 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup117(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!38"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup118(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!38"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup119(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!38"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup120(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!38"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup121(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!38"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup122(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!38"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup123(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!45"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup124(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!45"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup125(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!45"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup126(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!45"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup127(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!45"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup128(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "<34"; - int value2 = 34; - char *value3_str = "!45"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0x03) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup129(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = ">10"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (DetectIPProtoSetup(NULL, sig, value2_str) == 0) - goto end; - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup130(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - char *value2_str = ">10"; - int value2 = 10; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) == 0) - goto end; - for (i = 0; i < (value2 / 8); i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - if (sig->proto.proto[value2 / 8] != 0xF8) { - goto end; - } - for (i = (value2 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup131(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!10"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup132(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "<10"; - int value1 = 10; - char *value2_str = "!10"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0x03) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup133(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!10"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - - -static int DetectIPProtoTestSetup134(void) -{ - int result = 0; - Signature *sig; - char *value1_str = ">10"; - int value1 = 10; - char *value2_str = "!10"; - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - for (i = 0; i < (value1 / 8); i++) { - if (sig->proto.proto[i] != 0x0) - goto end; - } - if (sig->proto.proto[value1 / 8] != 0xF8) { - goto end; - } - for (i = (value1 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0xFF) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup135(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!27"; - char *value4_str = "!29"; - char *value5_str = "!30"; - char *value6_str = "!34"; - char *value7_str = "<36"; - char *value8_str = "!38"; - int value8 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xFE) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value8 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup136(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!27"; - char *value4_str = "!29"; - char *value5_str = "!30"; - char *value6_str = "!34"; - char *value7_str = "<36"; - char *value8_str = "!38"; - int value8 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xFE) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value8 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup137(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!27"; - char *value4_str = "!29"; - char *value5_str = "!30"; - char *value6_str = "!34"; - char *value7_str = "<36"; - char *value8_str = "!38"; - int value8 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xFE) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value8 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup138(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!27"; - char *value4_str = "!29"; - char *value5_str = "!30"; - char *value6_str = "!34"; - char *value7_str = "<36"; - char *value8_str = "!38"; - int value8 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xFE) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value8 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup139(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!27"; - char *value4_str = "!29"; - char *value5_str = "!30"; - char *value6_str = "!34"; - char *value7_str = "<36"; - char *value8_str = "!38"; - int value8 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xFE) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value8 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup140(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!27"; - char *value4_str = "!29"; - char *value5_str = "!30"; - char *value6_str = "!34"; - char *value7_str = "<36"; - char *value8_str = "!38"; - int value8 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xFE) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value8 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup141(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!27"; - char *value4_str = "!29"; - char *value5_str = "!30"; - char *value6_str = "!34"; - char *value7_str = "<36"; - char *value8_str = "!38"; - int value8 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xFE) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value8 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup142(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!27"; - char *value4_str = "!29"; - char *value5_str = "!30"; - char *value6_str = "!34"; - char *value7_str = "<36"; - char *value8_str = "!38"; - int value8 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xFE) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value8 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup143(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!10"; - char *value4_str = "!14"; - char *value5_str = "!27"; - char *value6_str = "!29"; - char *value7_str = "!30"; - char *value8_str = "!34"; - char *value9_str = "<36"; - char *value10_str = "!38"; - int value10 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value9_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value10_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xBA) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value10 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup144(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!10"; - char *value4_str = "!14"; - char *value5_str = "!27"; - char *value6_str = "!29"; - char *value7_str = "!30"; - char *value8_str = "!34"; - char *value9_str = "<36"; - char *value10_str = "!38"; - int value10 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value10_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value9_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xBA) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value10 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSetup145(void) -{ - int result = 0; - Signature *sig; - char *value1_str = "!4"; - char *value2_str = ">8"; - char *value3_str = "!10"; - char *value4_str = "!14"; - char *value5_str = "!27"; - char *value6_str = "!29"; - char *value7_str = "!30"; - char *value8_str = "!34"; - char *value9_str = "<36"; - char *value10_str = "!38"; - int value10 = 38; - - int i; - - if ((sig = SigAlloc()) == NULL) - goto end; - - sig->init_flags |= SIG_FLAG_INIT_FIRST_IPPROTO_SEEN; - sig->proto.flags |= DETECT_PROTO_ANY; - if (DetectIPProtoSetup(NULL, sig, value5_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value8_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value2_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value10_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value1_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value6_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value9_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value4_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value3_str) != 0) - goto end; - if (DetectIPProtoSetup(NULL, sig, value7_str) != 0) - goto end; - if (sig->proto.proto[0] != 0) { - goto end; - } - if (sig->proto.proto[1] != 0xBA) { - goto end; - } - if (sig->proto.proto[2] != 0xFF) { - goto end; - } - if (sig->proto.proto[3] != 0x97) { - goto end; - } - if (sig->proto.proto[4] != 0x0B) { - goto end; - } - for (i = (value10 / 8) + 1; i < 256 / 8; i++) { - if (sig->proto.proto[i] != 0) - goto end; - } - - result = 1; - - end: - SigFree(sig); - return result; -} - -static int DetectIPProtoTestSig1(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - if (p == NULL) - goto end; - - char *sigs[4]; - sigs[0] = "alert ip any any -> any any " - "(msg:\"Not tcp\"; ip_proto:!tcp; content:\"GET \"; sid:1;)"; - sigs[1] = "alert ip any any -> any any " - "(msg:\"Less than 7\"; content:\"GET \"; ip_proto:<7; sid:2;)"; - sigs[2] = "alert ip any any -> any any " - "(msg:\"Greater than 5\"; content:\"GET \"; ip_proto:>5; sid:3;)"; - sigs[3] = "alert ip any any -> any any " - "(msg:\"Equals tcp\"; content:\"GET \"; ip_proto:tcp; sid:4;)"; - - /* sids to match */ - uint32_t sid[4] = {1, 2, 3, 4}; - /* expected matches for each sid within this packet we are testing */ - uint32_t results[4] = {0, 1, 1, 1}; - - /* remember that UTHGenericTest expect the first parameter - * as an array of packet pointers. And also a bidimensional array of results - * For example: - * results[numpacket][position] should hold the number of times - * that the sid at sid[position] matched that packet (should be always 1..) - * But here we built it as unidimensional array - */ - result = UTHGenericTest(&p, 1, sigs, sid, results, 4); - - UTHFreePacket(p); -end: - DetectSigGroupPrintMemory(); - DetectAddressPrintMemory(); - return result; -} - -static int DetectIPProtoTestSig2(void) -{ - int result = 0; - - uint8_t raw_eth[] = { - 0x01, 0x00, 0x5e, 0x00, 0x00, 0x0d, 0x00, 0x26, - 0x88, 0x61, 0x3a, 0x80, 0x08, 0x00, 0x45, 0xc0, - 0x00, 0x36, 0xe4, 0xcd, 0x00, 0x00, 0x01, 0x67, - 0xc7, 0xab, 0xac, 0x1c, 0x7f, 0xfe, 0xe0, 0x00, - 0x00, 0x0d, 0x20, 0x00, 0x90, 0x20, 0x00, 0x01, - 0x00, 0x02, 0x00, 0x69, 0x00, 0x02, 0x00, 0x04, - 0x81, 0xf4, 0x07, 0xd0, 0x00, 0x13, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x14, 0x00, 0x04, - 0x4a, 0xea, 0x7a, 0x8e, - }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - memset(p, 0, SIZE_OF_PACKET); - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - p->proto = 0; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - FlowInitConfig(FLOW_QUIET); - DecodeEthernet(&th_v, &dtv, p, raw_eth, sizeof(raw_eth), NULL); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert ip any any -> any any (msg:\"Check ipproto usage\"; " - "ip_proto:!103; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 0) { - result = 1; - goto end; - } else { - result = 0; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - FlowShutdown(); - - SCFree(p); - return result; - -end: - if (de_ctx) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - if (de_ctx) - DetectEngineCtxFree(de_ctx); - - FlowShutdown(); - SCFree(p); - - return result; -} - -static int DetectIPProtoTestSig3(void) -{ - int result = 0; - - uint8_t raw_eth[] = { - 0x01, 0x00, 0x5e, 0x00, 0x00, 0x0d, 0x00, 0x26, - 0x88, 0x61, 0x3a, 0x80, 0x08, 0x00, 0x45, 0xc0, - 0x00, 0x36, 0xe4, 0xcd, 0x00, 0x00, 0x01, 0x67, - 0xc7, 0xab, 0xac, 0x1c, 0x7f, 0xfe, 0xe0, 0x00, - 0x00, 0x0d, 0x20, 0x00, 0x90, 0x20, 0x00, 0x01, - 0x00, 0x02, 0x00, 0x69, 0x00, 0x02, 0x00, 0x04, - 0x81, 0xf4, 0x07, 0xd0, 0x00, 0x13, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x14, 0x00, 0x04, - 0x4a, 0xea, 0x7a, 0x8e, - }; - - Packet *p = UTHBuildPacket((uint8_t *)"boom", 4, IPPROTO_TCP); - if (p == NULL) - return 0; - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - p->proto = 0; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - FlowInitConfig(FLOW_QUIET); - DecodeEthernet(&th_v, &dtv, p, raw_eth, sizeof(raw_eth), NULL); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = DEFAULT_MPM; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert ip any any -> any any (msg:\"Check ipproto usage\"; " - "ip_proto:103; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!PacketAlertCheck(p, 1)) { - result = 0; - goto end; - } else { - result = 1; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - FlowShutdown(); - - SCFree(p); - return result; - -end: - if (de_ctx) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - if (de_ctx) - DetectEngineCtxFree(de_ctx); - - FlowShutdown(); - SCFree(p); - - return result; -} - -#endif /* UNITTESTS */ - -/** - * \internal - * \brief Register ip_proto tests. - */ -static void DetectIPProtoRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectIPProtoTestParse01", DetectIPProtoTestParse01, 1); - UtRegisterTest("DetectIPProtoTestParse02", DetectIPProtoTestParse02, 1); - UtRegisterTest("DetectIPProtoTestSetup01", DetectIPProtoTestSetup01, 1); - UtRegisterTest("DetectIPProtoTestSetup02", DetectIPProtoTestSetup02, 1); - UtRegisterTest("DetectIPProtoTestSetup03", DetectIPProtoTestSetup03, 1); - UtRegisterTest("DetectIPProtoTestSetup04", DetectIPProtoTestSetup04, 1); - UtRegisterTest("DetectIPProtoTestSetup05", DetectIPProtoTestSetup05, 1); - UtRegisterTest("DetectIPProtoTestSetup06", DetectIPProtoTestSetup06, 1); - UtRegisterTest("DetectIPProtoTestSetup07", DetectIPProtoTestSetup07, 1); - UtRegisterTest("DetectIPProtoTestSetup08", DetectIPProtoTestSetup08, 1); - UtRegisterTest("DetectIPProtoTestSetup09", DetectIPProtoTestSetup09, 1); - UtRegisterTest("DetectIPProtoTestSetup10", DetectIPProtoTestSetup10, 1); - UtRegisterTest("DetectIPProtoTestSetup11", DetectIPProtoTestSetup11, 1); - UtRegisterTest("DetectIPProtoTestSetup12", DetectIPProtoTestSetup12, 1); - UtRegisterTest("DetectIPProtoTestSetup13", DetectIPProtoTestSetup13, 1); - UtRegisterTest("DetectIPProtoTestSetup14", DetectIPProtoTestSetup14, 1); - UtRegisterTest("DetectIPProtoTestSetup15", DetectIPProtoTestSetup15, 1); - UtRegisterTest("DetectIPProtoTestSetup16", DetectIPProtoTestSetup16, 1); - UtRegisterTest("DetectIPProtoTestSetup17", DetectIPProtoTestSetup17, 1); - UtRegisterTest("DetectIPProtoTestSetup18", DetectIPProtoTestSetup18, 1); - UtRegisterTest("DetectIPProtoTestSetup19", DetectIPProtoTestSetup19, 1); - UtRegisterTest("DetectIPProtoTestSetup20", DetectIPProtoTestSetup20, 1); - UtRegisterTest("DetectIPProtoTestSetup21", DetectIPProtoTestSetup21, 1); - UtRegisterTest("DetectIPProtoTestSetup22", DetectIPProtoTestSetup22, 1); - UtRegisterTest("DetectIPProtoTestSetup23", DetectIPProtoTestSetup23, 1); - UtRegisterTest("DetectIPProtoTestSetup24", DetectIPProtoTestSetup24, 1); - UtRegisterTest("DetectIPProtoTestSetup25", DetectIPProtoTestSetup25, 1); - UtRegisterTest("DetectIPProtoTestSetup26", DetectIPProtoTestSetup26, 1); - UtRegisterTest("DetectIPProtoTestSetup27", DetectIPProtoTestSetup27, 1); - UtRegisterTest("DetectIPProtoTestSetup28", DetectIPProtoTestSetup28, 1); - UtRegisterTest("DetectIPProtoTestSetup29", DetectIPProtoTestSetup29, 1); - UtRegisterTest("DetectIPProtoTestSetup30", DetectIPProtoTestSetup30, 1); - UtRegisterTest("DetectIPProtoTestSetup31", DetectIPProtoTestSetup31, 1); - UtRegisterTest("DetectIPProtoTestSetup32", DetectIPProtoTestSetup32, 1); - UtRegisterTest("DetectIPProtoTestSetup33", DetectIPProtoTestSetup33, 1); - UtRegisterTest("DetectIPProtoTestSetup34", DetectIPProtoTestSetup34, 1); - UtRegisterTest("DetectIPProtoTestSetup35", DetectIPProtoTestSetup35, 1); - UtRegisterTest("DetectIPProtoTestSetup36", DetectIPProtoTestSetup36, 1); - UtRegisterTest("DetectIPProtoTestSetup37", DetectIPProtoTestSetup37, 1); - UtRegisterTest("DetectIPProtoTestSetup38", DetectIPProtoTestSetup38, 1); - UtRegisterTest("DetectIPProtoTestSetup39", DetectIPProtoTestSetup39, 1); - UtRegisterTest("DetectIPProtoTestSetup40", DetectIPProtoTestSetup40, 1); - UtRegisterTest("DetectIPProtoTestSetup41", DetectIPProtoTestSetup41, 1); - UtRegisterTest("DetectIPProtoTestSetup42", DetectIPProtoTestSetup42, 1); - UtRegisterTest("DetectIPProtoTestSetup43", DetectIPProtoTestSetup43, 1); - UtRegisterTest("DetectIPProtoTestSetup44", DetectIPProtoTestSetup44, 1); - UtRegisterTest("DetectIPProtoTestSetup45", DetectIPProtoTestSetup45, 1); - UtRegisterTest("DetectIPProtoTestSetup46", DetectIPProtoTestSetup46, 1); - UtRegisterTest("DetectIPProtoTestSetup47", DetectIPProtoTestSetup47, 1); - UtRegisterTest("DetectIPProtoTestSetup48", DetectIPProtoTestSetup48, 1); - UtRegisterTest("DetectIPProtoTestSetup49", DetectIPProtoTestSetup49, 1); - UtRegisterTest("DetectIPProtoTestSetup50", DetectIPProtoTestSetup50, 1); - UtRegisterTest("DetectIPProtoTestSetup51", DetectIPProtoTestSetup51, 1); - UtRegisterTest("DetectIPProtoTestSetup52", DetectIPProtoTestSetup52, 1); - UtRegisterTest("DetectIPProtoTestSetup53", DetectIPProtoTestSetup53, 1); - UtRegisterTest("DetectIPProtoTestSetup54", DetectIPProtoTestSetup54, 1); - UtRegisterTest("DetectIPProtoTestSetup55", DetectIPProtoTestSetup55, 1); - UtRegisterTest("DetectIPProtoTestSetup56", DetectIPProtoTestSetup56, 1); - UtRegisterTest("DetectIPProtoTestSetup57", DetectIPProtoTestSetup57, 1); - UtRegisterTest("DetectIPProtoTestSetup58", DetectIPProtoTestSetup58, 1); - UtRegisterTest("DetectIPProtoTestSetup59", DetectIPProtoTestSetup59, 1); - UtRegisterTest("DetectIPProtoTestSetup60", DetectIPProtoTestSetup60, 1); - UtRegisterTest("DetectIPProtoTestSetup61", DetectIPProtoTestSetup61, 1); - UtRegisterTest("DetectIPProtoTestSetup62", DetectIPProtoTestSetup62, 1); - UtRegisterTest("DetectIPProtoTestSetup63", DetectIPProtoTestSetup63, 1); - UtRegisterTest("DetectIPProtoTestSetup64", DetectIPProtoTestSetup64, 1); - UtRegisterTest("DetectIPProtoTestSetup65", DetectIPProtoTestSetup65, 1); - UtRegisterTest("DetectIPProtoTestSetup66", DetectIPProtoTestSetup66, 1); - UtRegisterTest("DetectIPProtoTestSetup67", DetectIPProtoTestSetup67, 1); - UtRegisterTest("DetectIPProtoTestSetup68", DetectIPProtoTestSetup68, 1); - UtRegisterTest("DetectIPProtoTestSetup69", DetectIPProtoTestSetup69, 1); - UtRegisterTest("DetectIPProtoTestSetup70", DetectIPProtoTestSetup70, 1); - UtRegisterTest("DetectIPProtoTestSetup71", DetectIPProtoTestSetup71, 1); - UtRegisterTest("DetectIPProtoTestSetup72", DetectIPProtoTestSetup72, 1); - UtRegisterTest("DetectIPProtoTestSetup73", DetectIPProtoTestSetup73, 1); - UtRegisterTest("DetectIPProtoTestSetup74", DetectIPProtoTestSetup74, 1); - UtRegisterTest("DetectIPProtoTestSetup75", DetectIPProtoTestSetup75, 1); - UtRegisterTest("DetectIPProtoTestSetup76", DetectIPProtoTestSetup76, 1); - UtRegisterTest("DetectIPProtoTestSetup77", DetectIPProtoTestSetup77, 1); - UtRegisterTest("DetectIPProtoTestSetup78", DetectIPProtoTestSetup78, 1); - UtRegisterTest("DetectIPProtoTestSetup79", DetectIPProtoTestSetup79, 1); - UtRegisterTest("DetectIPProtoTestSetup80", DetectIPProtoTestSetup80, 1); - UtRegisterTest("DetectIPProtoTestSetup81", DetectIPProtoTestSetup81, 1); - UtRegisterTest("DetectIPProtoTestSetup82", DetectIPProtoTestSetup82, 1); - UtRegisterTest("DetectIPProtoTestSetup83", DetectIPProtoTestSetup83, 1); - UtRegisterTest("DetectIPProtoTestSetup84", DetectIPProtoTestSetup84, 1); - UtRegisterTest("DetectIPProtoTestSetup85", DetectIPProtoTestSetup85, 1); - UtRegisterTest("DetectIPProtoTestSetup86", DetectIPProtoTestSetup86, 1); - UtRegisterTest("DetectIPProtoTestSetup87", DetectIPProtoTestSetup87, 1); - UtRegisterTest("DetectIPProtoTestSetup88", DetectIPProtoTestSetup88, 1); - UtRegisterTest("DetectIPProtoTestSetup89", DetectIPProtoTestSetup89, 1); - UtRegisterTest("DetectIPProtoTestSetup90", DetectIPProtoTestSetup90, 1); - UtRegisterTest("DetectIPProtoTestSetup91", DetectIPProtoTestSetup91, 1); - UtRegisterTest("DetectIPProtoTestSetup92", DetectIPProtoTestSetup92, 1); - UtRegisterTest("DetectIPProtoTestSetup93", DetectIPProtoTestSetup93, 1); - UtRegisterTest("DetectIPProtoTestSetup94", DetectIPProtoTestSetup94, 1); - UtRegisterTest("DetectIPProtoTestSetup95", DetectIPProtoTestSetup95, 1); - UtRegisterTest("DetectIPProtoTestSetup96", DetectIPProtoTestSetup96, 1); - UtRegisterTest("DetectIPProtoTestSetup97", DetectIPProtoTestSetup97, 1); - UtRegisterTest("DetectIPProtoTestSetup98", DetectIPProtoTestSetup98, 1); - UtRegisterTest("DetectIPProtoTestSetup99", DetectIPProtoTestSetup99, 1); - UtRegisterTest("DetectIPProtoTestSetup100", DetectIPProtoTestSetup100, 1); - UtRegisterTest("DetectIPProtoTestSetup101", DetectIPProtoTestSetup101, 1); - UtRegisterTest("DetectIPProtoTestSetup102", DetectIPProtoTestSetup102, 1); - UtRegisterTest("DetectIPProtoTestSetup103", DetectIPProtoTestSetup103, 1); - UtRegisterTest("DetectIPProtoTestSetup104", DetectIPProtoTestSetup104, 1); - UtRegisterTest("DetectIPProtoTestSetup105", DetectIPProtoTestSetup105, 1); - UtRegisterTest("DetectIPProtoTestSetup106", DetectIPProtoTestSetup106, 1); - UtRegisterTest("DetectIPProtoTestSetup107", DetectIPProtoTestSetup107, 1); - UtRegisterTest("DetectIPProtoTestSetup108", DetectIPProtoTestSetup108, 1); - UtRegisterTest("DetectIPProtoTestSetup109", DetectIPProtoTestSetup109, 1); - UtRegisterTest("DetectIPProtoTestSetup110", DetectIPProtoTestSetup110, 1); - UtRegisterTest("DetectIPProtoTestSetup111", DetectIPProtoTestSetup111, 1); - UtRegisterTest("DetectIPProtoTestSetup112", DetectIPProtoTestSetup112, 1); - UtRegisterTest("DetectIPProtoTestSetup113", DetectIPProtoTestSetup113, 1); - UtRegisterTest("DetectIPProtoTestSetup114", DetectIPProtoTestSetup114, 1); - UtRegisterTest("DetectIPProtoTestSetup115", DetectIPProtoTestSetup115, 1); - UtRegisterTest("DetectIPProtoTestSetup116", DetectIPProtoTestSetup116, 1); - UtRegisterTest("DetectIPProtoTestSetup117", DetectIPProtoTestSetup117, 1); - UtRegisterTest("DetectIPProtoTestSetup118", DetectIPProtoTestSetup118, 1); - UtRegisterTest("DetectIPProtoTestSetup119", DetectIPProtoTestSetup119, 1); - UtRegisterTest("DetectIPProtoTestSetup120", DetectIPProtoTestSetup120, 1); - UtRegisterTest("DetectIPProtoTestSetup121", DetectIPProtoTestSetup121, 1); - UtRegisterTest("DetectIPProtoTestSetup122", DetectIPProtoTestSetup122, 1); - UtRegisterTest("DetectIPProtoTestSetup123", DetectIPProtoTestSetup123, 1); - UtRegisterTest("DetectIPProtoTestSetup124", DetectIPProtoTestSetup124, 1); - UtRegisterTest("DetectIPProtoTestSetup125", DetectIPProtoTestSetup125, 1); - UtRegisterTest("DetectIPProtoTestSetup126", DetectIPProtoTestSetup126, 1); - UtRegisterTest("DetectIPProtoTestSetup127", DetectIPProtoTestSetup127, 1); - UtRegisterTest("DetectIPProtoTestSetup128", DetectIPProtoTestSetup128, 1); - UtRegisterTest("DetectIPProtoTestSetup129", DetectIPProtoTestSetup129, 1); - UtRegisterTest("DetectIPProtoTestSetup130", DetectIPProtoTestSetup130, 1); - UtRegisterTest("DetectIPProtoTestSetup131", DetectIPProtoTestSetup131, 1); - UtRegisterTest("DetectIPProtoTestSetup132", DetectIPProtoTestSetup132, 1); - UtRegisterTest("DetectIPProtoTestSetup133", DetectIPProtoTestSetup133, 1); - UtRegisterTest("DetectIPProtoTestSetup134", DetectIPProtoTestSetup134, 1); - UtRegisterTest("DetectIPProtoTestSetup135", DetectIPProtoTestSetup135, 1); - UtRegisterTest("DetectIPProtoTestSetup136", DetectIPProtoTestSetup136, 1); - UtRegisterTest("DetectIPProtoTestSetup137", DetectIPProtoTestSetup137, 1); - UtRegisterTest("DetectIPProtoTestSetup138", DetectIPProtoTestSetup138, 1); - UtRegisterTest("DetectIPProtoTestSetup139", DetectIPProtoTestSetup139, 1); - UtRegisterTest("DetectIPProtoTestSetup140", DetectIPProtoTestSetup140, 1); - UtRegisterTest("DetectIPProtoTestSetup141", DetectIPProtoTestSetup141, 1); - UtRegisterTest("DetectIPProtoTestSetup142", DetectIPProtoTestSetup142, 1); - UtRegisterTest("DetectIPProtoTestSetup143", DetectIPProtoTestSetup143, 1); - UtRegisterTest("DetectIPProtoTestSetup144", DetectIPProtoTestSetup144, 1); - UtRegisterTest("DetectIPProtoTestSetup145", DetectIPProtoTestSetup145, 1); - - UtRegisterTest("DetectIPProtoTestSig1", DetectIPProtoTestSig1, 1); - UtRegisterTest("DetectIPProtoTestSig2", DetectIPProtoTestSig2, 1); - UtRegisterTest("DetectIPProtoTestSig3", DetectIPProtoTestSig3, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-ipproto.h b/framework/src/suricata/src/detect-ipproto.h deleted file mode 100644 index e586f303..00000000 --- a/framework/src/suricata/src/detect-ipproto.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - */ - -#ifndef __DETECT_IPPROTO_H__ -#define __DETECT_IPPROTO_H__ - -/** IPProto Operators */ -#define DETECT_IPPROTO_OP_EQ '=' /**< "equals" operator (default) */ -#define DETECT_IPPROTO_OP_NOT '!' /**< "not" operator */ -#define DETECT_IPPROTO_OP_LT '<' /**< "less than" operator */ -#define DETECT_IPPROTO_OP_GT '>' /**< "greater than" operator */ - -/** ip_proto data */ -typedef struct DetectIPProtoData_ { - uint8_t op; /**< Operator used to compare */ - uint8_t proto; /**< Protocol used to compare */ -} DetectIPProtoData; - -/* prototypes */ - -/** - * \brief Registration function for ip_proto keyword. - */ -void DetectIPProtoRegister (void); -void DetectIPProtoRemoveAllSMs(Signature *); - -#endif /* __DETECT_IPPROTO_H__ */ - diff --git a/framework/src/suricata/src/detect-iprep.c b/framework/src/suricata/src/detect-iprep.c deleted file mode 100644 index 4e47acdc..00000000 --- a/framework/src/suricata/src/detect-iprep.c +++ /dev/null @@ -1,1030 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the iprep keyword - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "threads.h" -#include "flow.h" -#include "flow-bit.h" -#include "flow-util.h" -#include "detect-iprep.h" -#include "util-spm.h" - -#include "app-layer-parser.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-fmemopen.h" - -#include "reputation.h" -#include "host.h" - -#define PARSE_REGEX "\\s*(any|src|dst|both)\\s*,\\s*([A-Za-z0-9\\-\\_]+)\\s*,\\s*(\\<|\\>|\\=)\\s*,\\s*([0-9]+)\\s*" -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectIPRepMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectIPRepSetup (DetectEngineCtx *, Signature *, char *); -void DetectIPRepFree (void *); -void IPRepRegisterTests(void); - -void DetectIPRepRegister (void) -{ - sigmatch_table[DETECT_IPREP].name = "iprep"; - sigmatch_table[DETECT_IPREP].Match = DetectIPRepMatch; - sigmatch_table[DETECT_IPREP].Setup = DetectIPRepSetup; - sigmatch_table[DETECT_IPREP].Free = DetectIPRepFree; - sigmatch_table[DETECT_IPREP].RegisterTests = IPRepRegisterTests; - /* this is compatible to ip-only signatures */ - sigmatch_table[DETECT_IPREP].flags |= SIGMATCH_IPONLY_COMPAT; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - return; -} - -static uint8_t GetHostRepSrc(Packet *p, uint8_t cat, uint32_t version) -{ - uint8_t val = 0; - Host *h = NULL; - - if (p->flags & PKT_HOST_SRC_LOOKED_UP && p->host_src == NULL) { - return 0; - } else if (p->host_src != NULL) { - h = (Host *)p->host_src; - HostLock(h); - } else { - h = HostLookupHostFromHash(&(p->src)); - - p->flags |= PKT_HOST_SRC_LOOKED_UP; - - if (h == NULL) - return 0; - - HostReference(&p->host_src, h); - } - - if (h->iprep == NULL) { - HostRelease(h); - return 0; - } - - SReputation *r = (SReputation *)h->iprep; - - /* allow higher versions as this happens during - * rule reload */ - if (r->version >= version) - val = r->rep[cat]; - else - SCLogDebug("version mismatch %u != %u", r->version, version); - - HostRelease(h); - return val; -} - -static uint8_t GetHostRepDst(Packet *p, uint8_t cat, uint32_t version) -{ - uint8_t val = 0; - Host *h = NULL; - - if (p->flags & PKT_HOST_DST_LOOKED_UP && p->host_dst == NULL) { - return 0; - } else if (p->host_dst != NULL) { - h = (Host *)p->host_dst; - HostLock(h); - } else { - h = HostLookupHostFromHash(&(p->dst)); - - p->flags |= PKT_HOST_DST_LOOKED_UP; - - if (h == NULL) { - return 0; - } - - HostReference(&p->host_dst, h); - } - - if (h->iprep == NULL) { - HostRelease(h); - return 0; - } - - SReputation *r = (SReputation *)h->iprep; - - /* allow higher versions as this happens during - * rule reload */ - if (r->version >= version) - val = r->rep[cat]; - else - SCLogDebug("version mismatch %u != %u", r->version, version); - - HostRelease(h); - return val; -} - -static inline int RepMatch(uint8_t op, uint8_t val1, uint8_t val2) -{ - if (op == DETECT_IPREP_OP_GT && val1 > val2) { - return 1; - } else if (op == DETECT_IPREP_OP_LT && val1 < val2) { - return 1; - } else if (op == DETECT_IPREP_OP_EQ && val1 == val2) { - return 1; - } - return 0; -} - -/* - * returns 0: no match - * 1: match - * -1: error - */ -int DetectIPRepMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectIPRepData *rd = (const DetectIPRepData *)ctx; - if (rd == NULL) - return 0; - - uint32_t version = det_ctx->de_ctx->srep_version; - uint8_t val = 0; - - SCLogDebug("rd->cmd %u", rd->cmd); - switch(rd->cmd) { - case DETECT_IPREP_CMD_ANY: - val = GetHostRepSrc(p, rd->cat, version); - if (val == 0) - val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version); - if (val > 0) { - if (RepMatch(rd->op, val, rd->val) == 1) - return 1; - } - val = GetHostRepDst(p, rd->cat, version); - if (val == 0) - val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version); - if (val > 0) { - return RepMatch(rd->op, val, rd->val); - } - break; - - case DETECT_IPREP_CMD_SRC: - val = GetHostRepSrc(p, rd->cat, version); - SCLogDebug("checking src -- val %u (looking for cat %u, val %u)", val, rd->cat, rd->val); - if (val == 0) - val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version); - if (val > 0) { - return RepMatch(rd->op, val, rd->val); - } - break; - - case DETECT_IPREP_CMD_DST: - SCLogDebug("checking dst"); - val = GetHostRepDst(p, rd->cat, version); - if (val == 0) - val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version); - if (val > 0) { - return RepMatch(rd->op, val, rd->val); - } - break; - - case DETECT_IPREP_CMD_BOTH: - val = GetHostRepSrc(p, rd->cat, version); - if (val == 0) - val = SRepCIDRGetIPRepSrc(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version); - if (val == 0 || RepMatch(rd->op, val, rd->val) == 0) - return 0; - val = GetHostRepDst(p, rd->cat, version); - if (val == 0) - val = SRepCIDRGetIPRepDst(det_ctx->de_ctx->srepCIDR_ctx, p, rd->cat, version); - if (val > 0) { - return RepMatch(rd->op, val, rd->val); - } - break; - } - - return 0; -} - -int DetectIPRepSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectIPRepData *cd = NULL; - SigMatch *sm = NULL; - char *cmd_str = NULL, *name = NULL, *op_str = NULL, *value = NULL; - uint8_t cmd = 0; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret != 5) { - SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for iprep", rawstr); - return -1; - } - - const char *str_ptr; - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - return -1; - } - cmd_str = (char *)str_ptr; - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - name = (char *)str_ptr; - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - op_str = (char *)str_ptr; - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - value = (char *)str_ptr; - - if (strcmp(cmd_str,"any") == 0) { - cmd = DETECT_IPREP_CMD_ANY; - } else if (strcmp(cmd_str,"both") == 0) { - cmd = DETECT_IPREP_CMD_BOTH; - } else if (strcmp(cmd_str,"src") == 0) { - cmd = DETECT_IPREP_CMD_SRC; - } else if (strcmp(cmd_str,"dst") == 0) { - cmd = DETECT_IPREP_CMD_DST; - } else { - SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: iprep \"%s\" is not supported.", cmd_str); - goto error; - } - - //SCLogInfo("category %s", name); - uint8_t cat = SRepCatGetByShortname(name); - if (cat == 0) { - SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown iprep category \"%s\"", name); - goto error; - } - - uint8_t op = 0; - uint8_t val = 0; - - if (op_str == NULL || strlen(op_str) != 1) { - goto error; - } - - switch(op_str[0]) { - case '<': - op = DETECT_IPREP_OP_LT; - break; - case '>': - op = DETECT_IPREP_OP_GT; - break; - case '=': - op = DETECT_IPREP_OP_EQ; - break; - default: - goto error; - break; - } - - if (value != NULL && strlen(value) > 0) { - int ival = atoi(value); - if (ival < 0 || ival > 127) - goto error; - val = (uint8_t)ival; - } - - cd = SCMalloc(sizeof(DetectIPRepData)); - if (unlikely(cd == NULL)) - goto error; - - cd->cmd = cmd; - cd->cat = cat; - cd->op = op; - cd->val = val; - SCLogDebug("cmd %u, cat %u, op %u, val %u", cd->cmd, cd->cat, cd->op, cd->val); - - pcre_free_substring(name); - name = NULL; - pcre_free_substring(cmd_str); - cmd_str = NULL; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_IPREP; - sm->ctx = (SigMatchCtx *)cd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (name != NULL) - pcre_free_substring(name); - if (cmd_str != NULL) - pcre_free_substring(cmd_str); - if (cd != NULL) - SCFree(cd); - if (sm != NULL) - SCFree(sm); - return -1; -} - -void DetectIPRepFree (void *ptr) -{ - DetectIPRepData *fd = (DetectIPRepData *)ptr; - - if (fd == NULL) - return; - - SCFree(fd); -} - -#ifdef UNITTESTS -FILE *DetectIPRepGenerateCategoriesDummy() -{ - FILE *fd = NULL; - const char *buffer = "1,BadHosts,Know bad hosts"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen()"); - - return fd; -} - -FILE *DetectIPRepGenerateCategoriesDummy2() -{ - FILE *fd = NULL; - const char *buffer = - "1,BadHosts,Know bad hosts\n" - "2,GoodHosts,Know good hosts\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen()"); - - return fd; -} - -FILE *DetectIPRepGenerateNetworksDummy() -{ - FILE *fd = NULL; - const char *buffer = "10.0.0.0/24,1,20"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen()"); - - return fd; -} - -FILE *DetectIPRepGenerateNetworksDummy2() -{ - FILE *fd = NULL; - const char *buffer = - "0.0.0.0/0,1,10\n" - "192.168.0.0/16,2,127"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen()"); - - return fd; -} - -static int DetectIPRepTest01(void) -{ - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *sig = NULL; - FILE *fd = NULL; - int result = 0, r = 0; - Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - HostInitConfig(HOST_QUIET); - memset(&th_v, 0, sizeof(th_v)); - - if (de_ctx == NULL || p == NULL) - goto end; - - p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1"); - de_ctx->flags |= DE_QUIET; - - SRepInit(de_ctx); - SRepResetVersion(); - - fd = DetectIPRepGenerateCategoriesDummy(); - r = SRepLoadCatFileFromFD(fd); - if (r < 0) { - goto end; - } - - fd = DetectIPRepGenerateNetworksDummy(); - r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd); - if (r < 0) { - goto end; - } - - sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1;rev:1;)"); - if (sig == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -static int DetectIPRepTest02(void) -{ - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *sig = NULL; - FILE *fd = NULL; - int result = 0, r = 0; - Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - HostInitConfig(HOST_QUIET); - memset(&th_v, 0, sizeof(th_v)); - - if (de_ctx == NULL || p == NULL) - goto end; - - p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1"); - de_ctx->flags |= DE_QUIET; - - SRepInit(de_ctx); - SRepResetVersion(); - - fd = DetectIPRepGenerateCategoriesDummy(); - r = SRepLoadCatFileFromFD(fd); - if (r < 0) { - goto end; - } - - fd = DetectIPRepGenerateNetworksDummy(); - r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd); - if (r < 0) { - goto end; - } - - sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:src,BadHosts,>,1; sid:1; rev:1;)"); - if (sig == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -static int DetectIPRepTest03(void) -{ - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *sig = NULL; - FILE *fd = NULL; - int result = 0, r = 0; - Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - HostInitConfig(HOST_QUIET); - memset(&th_v, 0, sizeof(th_v)); - - if (de_ctx == NULL || p == NULL) - goto end; - - p->dst.addr_data32[0] = UTHSetIPv4Address("10.0.0.2"); - de_ctx->flags |= DE_QUIET; - - SRepInit(de_ctx); - SRepResetVersion(); - - fd = DetectIPRepGenerateCategoriesDummy(); - r = SRepLoadCatFileFromFD(fd); - if (r < 0) { - goto end; - } - - fd = DetectIPRepGenerateNetworksDummy(); - r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd); - if (r < 0) { - goto end; - } - - sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:dst,BadHosts,>,1; sid:1; rev:1;)"); - if (sig == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -static int DetectIPRepTest04(void) -{ - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *sig = NULL; - FILE *fd = NULL; - int result = 0, r = 0; - Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - HostInitConfig(HOST_QUIET); - memset(&th_v, 0, sizeof(th_v)); - - if (de_ctx == NULL || p == NULL) - goto end; - - p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1"); - p->dst.addr_data32[0] = UTHSetIPv4Address("10.0.0.2"); - de_ctx->flags |= DE_QUIET; - - SRepInit(de_ctx); - SRepResetVersion(); - - fd = DetectIPRepGenerateCategoriesDummy(); - r = SRepLoadCatFileFromFD(fd); - if (r < 0) { - goto end; - } - - fd = DetectIPRepGenerateNetworksDummy(); - r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd); - if (r < 0) { - goto end; - } - - sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:both,BadHosts,>,1; sid:1; rev:1;)"); - if (sig == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -static int DetectIPRepTest05(void) -{ - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *sig = NULL; - FILE *fd = NULL; - int result = 0, r = 0; - Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - HostInitConfig(HOST_QUIET); - memset(&th_v, 0, sizeof(th_v)); - - if (de_ctx == NULL || p == NULL) - goto end; - - p->src.addr_data32[0] = UTHSetIPv4Address("1.0.0.1"); - de_ctx->flags |= DE_QUIET; - - SRepInit(de_ctx); - SRepResetVersion(); - - fd = DetectIPRepGenerateCategoriesDummy(); - r = SRepLoadCatFileFromFD(fd); - if (r < 0) { - goto end; - } - - fd = DetectIPRepGenerateNetworksDummy(); - r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd); - if (r < 0) { - goto end; - } - - sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)"); - if (sig == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -static int DetectIPRepTest06(void) -{ - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *sig = NULL; - FILE *fd = NULL; - int result = 0, r = 0; - Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - HostInitConfig(HOST_QUIET); - memset(&th_v, 0, sizeof(th_v)); - - if (de_ctx == NULL || p == NULL) - goto end; - - p->src.addr_data32[0] = UTHSetIPv4Address("1.0.0.1"); - de_ctx->flags |= DE_QUIET; - - SRepInit(de_ctx); - SRepResetVersion(); - - fd = DetectIPRepGenerateCategoriesDummy(); - r = SRepLoadCatFileFromFD(fd); - if (r < 0) { - goto end; - } - - fd = DetectIPRepGenerateNetworksDummy(); - r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd); - if (r < 0) { - goto end; - } - - sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)"); - if (sig == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -static int DetectIPRepTest07(void) -{ - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *sig = NULL; - FILE *fd = NULL; - int result = 0, r = 0; - Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - HostInitConfig(HOST_QUIET); - memset(&th_v, 0, sizeof(th_v)); - - if (de_ctx == NULL || p == NULL) - goto end; - - p->dst.addr_data32[0] = UTHSetIPv4Address("1.0.0.2"); - de_ctx->flags |= DE_QUIET; - - SRepInit(de_ctx); - SRepResetVersion(); - - fd = DetectIPRepGenerateCategoriesDummy(); - r = SRepLoadCatFileFromFD(fd); - if (r < 0) { - goto end; - } - - fd = DetectIPRepGenerateNetworksDummy(); - r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd); - if (r < 0) { - goto end; - } - - sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)"); - if (sig == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -static int DetectIPRepTest08(void) -{ - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *sig = NULL; - FILE *fd = NULL; - int result = 0, r = 0; - Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - HostInitConfig(HOST_QUIET); - memset(&th_v, 0, sizeof(th_v)); - - if (de_ctx == NULL || p == NULL) - goto end; - - p->src.addr_data32[0] = UTHSetIPv4Address("1.0.0.1"); - p->dst.addr_data32[0] = UTHSetIPv4Address("1.0.0.2"); - de_ctx->flags |= DE_QUIET; - - SRepInit(de_ctx); - SRepResetVersion(); - - fd = DetectIPRepGenerateCategoriesDummy(); - r = SRepLoadCatFileFromFD(fd); - if (r < 0) { - goto end; - } - - fd = DetectIPRepGenerateNetworksDummy(); - r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd); - if (r < 0) { - goto end; - } - - sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"IPREP High value badhost\"; iprep:any,BadHosts,>,1; sid:1; rev:1;)"); - if (sig == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -static int DetectIPRepTest09(void) -{ - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *sig = NULL; - FILE *fd = NULL; - int result = 0, r = 0; - Packet *p = UTHBuildPacket((uint8_t *)"lalala", 6, IPPROTO_TCP); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - HostInitConfig(HOST_QUIET); - memset(&th_v, 0, sizeof(th_v)); - - if (de_ctx == NULL || p == NULL) - goto end; - - p->src.addr_data32[0] = UTHSetIPv4Address("192.168.0.1"); - p->dst.addr_data32[0] = UTHSetIPv4Address("192.168.0.2"); - de_ctx->flags |= DE_QUIET; - - SRepInit(de_ctx); - SRepResetVersion(); - - fd = DetectIPRepGenerateCategoriesDummy2(); - r = SRepLoadCatFileFromFD(fd); - if (r < 0) { - goto end; - } - - fd = DetectIPRepGenerateNetworksDummy2(); - r = SRepLoadFileFromFD(de_ctx->srepCIDR_ctx, fd); - if (r < 0) { - goto end; - } - - sig = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"test\"; iprep:src,BadHosts,>,9; sid:1; rev:1;)"); - if (sig == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for IPRep - */ -void IPRepRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectIPRepTest01", DetectIPRepTest01, 1); - UtRegisterTest("DetectIPRepTest02", DetectIPRepTest02, 1); - UtRegisterTest("DetectIPRepTest03", DetectIPRepTest03, 1); - UtRegisterTest("DetectIPRepTest04", DetectIPRepTest04, 1); - UtRegisterTest("DetectIPRepTest05", DetectIPRepTest05, 0); - UtRegisterTest("DetectIPRepTest06", DetectIPRepTest06, 0); - UtRegisterTest("DetectIPRepTest07", DetectIPRepTest07, 0); - UtRegisterTest("DetectIPRepTest08", DetectIPRepTest08, 0); - UtRegisterTest("DetectIPRepTest09", DetectIPRepTest09, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-iprep.h b/framework/src/suricata/src/detect-iprep.h deleted file mode 100644 index 129851b9..00000000 --- a/framework/src/suricata/src/detect-iprep.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_IPREP_H__ -#define __DETECT_IPREP_H__ - -#define DETECT_IPREP_CMD_ANY 0 -#define DETECT_IPREP_CMD_BOTH 1 -#define DETECT_IPREP_CMD_SRC 2 -#define DETECT_IPREP_CMD_DST 3 - -#define DETECT_IPREP_OP_LT 0 -#define DETECT_IPREP_OP_GT 1 -#define DETECT_IPREP_OP_EQ 2 - -typedef struct DetectIPRepData_ { - uint8_t cmd; - int8_t cat; - int8_t op; - uint8_t val; -} DetectIPRepData; - -/* prototypes */ -void DetectIPRepRegister (void); - -#endif /* __DETECT_IPREP_H__ */ diff --git a/framework/src/suricata/src/detect-isdataat.c b/framework/src/suricata/src/detect-isdataat.c deleted file mode 100644 index e6a16f40..00000000 --- a/framework/src/suricata/src/detect-isdataat.c +++ /dev/null @@ -1,1249 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * - * Implements isdataat keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "app-layer.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "detect-isdataat.h" -#include "detect-content.h" -#include "detect-uricontent.h" - -#include "flow.h" -#include "flow-var.h" - -#include "util-debug.h" -#include "util-byte.h" -#include "detect-pcre.h" -#include "detect-bytejump.h" -#include "detect-byte-extract.h" - -/** - * \brief Regex for parsing our isdataat options - */ -#define PARSE_REGEX "^\\s*!?([^\\s,]+)\\s*(,\\s*relative)?\\s*(,\\s*rawbytes\\s*)?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectIsdataatMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -int DetectIsdataatSetup (DetectEngineCtx *, Signature *, char *); -void DetectIsdataatRegisterTests(void); -void DetectIsdataatFree(void *); - -/** - * \brief Registration function for isdataat: keyword - */ -void DetectIsdataatRegister(void) -{ - sigmatch_table[DETECT_ISDATAAT].name = "isdataat"; - sigmatch_table[DETECT_ISDATAAT].desc = "check if there is still data at a specific part of the payload"; - sigmatch_table[DETECT_ISDATAAT].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#Isadataat"; - sigmatch_table[DETECT_ISDATAAT].Match = DetectIsdataatMatch; - sigmatch_table[DETECT_ISDATAAT].Setup = DetectIsdataatSetup; - sigmatch_table[DETECT_ISDATAAT].Free = DetectIsdataatFree; - sigmatch_table[DETECT_ISDATAAT].RegisterTests = DetectIsdataatRegisterTests; - - sigmatch_table[DETECT_ISDATAAT].flags |= SIGMATCH_PAYLOAD; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - /* XXX */ - return; -} - -/** - * \brief This function is used to match isdataat on a packet - * \todo We need to add support for rawbytes - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectIsdataatData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectIsdataatMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectIsdataatData *idad = (const DetectIsdataatData *)ctx; - - SCLogDebug("payload_len: %u , dataat? %u ; relative? %u...", p->payload_len,idad->dataat,idad->flags &ISDATAAT_RELATIVE); - - /* Relative to the last matched content is not performed here, returning match (content should take care of this)*/ - if (idad->flags & ISDATAAT_RELATIVE) - return 1; - - /* its not relative and we have more data in the packet than the offset of isdataat */ - if (p->payload_len >= idad->dataat) { - SCLogDebug("matched with payload_len: %u , dataat? %u ; relative? %u...", p->payload_len,idad->dataat,idad->flags &ISDATAAT_RELATIVE); - return 1; - } - - return 0; -} - -/** - * \brief This function is used to parse isdataat options passed via isdataat: keyword - * - * \param isdataatstr Pointer to the user provided isdataat options - * - * \retval idad pointer to DetectIsdataatData on success - * \retval NULL on failure - */ -DetectIsdataatData *DetectIsdataatParse (char *isdataatstr, char **offset) -{ - DetectIsdataatData *idad = NULL; - char *args[3] = {NULL,NULL,NULL}; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - int i=0; - - ret = pcre_exec(parse_regex, parse_regex_study, isdataatstr, strlen(isdataatstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, isdataatstr); - goto error; - } - - if (ret > 1) { - const char *str_ptr; - res = pcre_get_substring((char *)isdataatstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[0] = (char *)str_ptr; - - - if (ret > 2) { - res = pcre_get_substring((char *)isdataatstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[1] = (char *)str_ptr; - } - if (ret > 3) { - res = pcre_get_substring((char *)isdataatstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[2] = (char *)str_ptr; - } - - idad = SCMalloc(sizeof(DetectIsdataatData)); - if (unlikely(idad == NULL)) - goto error; - - idad->flags = 0; - idad->dataat = 0; - - if (args[0][0] != '-' && isalpha((unsigned char)args[0][0])) { - if (offset == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "isdataat supplied with " - "var name for offset. \"offset\" argument supplied to " - "this function has to be non-NULL"); - goto error; - } - *offset = SCStrdup(args[0]); - if (*offset == NULL) - goto error; - } else { - if (ByteExtractStringUint16(&idad->dataat, 10, - strlen(args[0]), args[0]) < 0 ) { - SCLogError(SC_ERR_INVALID_VALUE, "isdataat out of range"); - SCFree(idad); - idad = NULL; - goto error; - } - } - - if (args[1] !=NULL) { - idad->flags |= ISDATAAT_RELATIVE; - - if(args[2] !=NULL) - idad->flags |= ISDATAAT_RAWBYTES; - } - - if (isdataatstr[0] == '!') { - idad->flags |= ISDATAAT_NEGATED; - } - - for (i = 0; i < (ret -1); i++) { - if (args[i] != NULL) - SCFree(args[i]); - } - - return idad; - - } - -error: - for (i = 0; i < (ret -1) && i < 3; i++){ - if (args[i] != NULL) - SCFree(args[i]); - } - - if (idad != NULL) - DetectIsdataatFree(idad); - return NULL; - -} - -/** - * \brief This function is used to add the parsed isdataatdata into the current - * signature. - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param isdataatstr pointer to the user provided isdataat options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, char *isdataatstr) -{ - SigMatch *sm = NULL; - SigMatch *prev_pm = NULL; - DetectIsdataatData *idad = NULL; - char *offset = NULL; - int ret = -1; - - idad = DetectIsdataatParse(isdataatstr, &offset); - if (idad == NULL) - return -1; - - int sm_list; - if (s->list != DETECT_SM_LIST_NOTSET) { - if (s->list == DETECT_SM_LIST_FILEDATA) { - AppLayerHtpEnableResponseBodyCallback(); - s->alproto = ALPROTO_HTTP; - } - sm_list = s->list; - s->flags |= SIG_FLAG_APPLAYER; - if (idad->flags & ISDATAAT_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, s->sm_lists_tail[sm_list], - DETECT_PCRE, s->sm_lists_tail[sm_list]); - } - } else if (idad->flags & ISDATAAT_RELATIVE) { - prev_pm = SigMatchGetLastSMFromLists(s, 168, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_PCRE, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTETEST, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTEJUMP, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_BYTE_EXTRACT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH], - - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_ISDATAAT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - if (prev_pm == NULL) - sm_list = DETECT_SM_LIST_PMATCH; - else { - sm_list = SigMatchListSMBelongsTo(s, prev_pm); - if (sm_list < 0) - goto end; - } - } else { - sm_list = DETECT_SM_LIST_PMATCH; - } - - if (offset != NULL) { - SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s); - if (bed_sm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var " - "seen in isdataat - %s\n", offset); - goto end; - } - idad->dataat = ((DetectByteExtractData *)bed_sm->ctx)->local_id; - idad->flags |= ISDATAAT_OFFSET_BE; - SCFree(offset); - } - - sm = SigMatchAlloc(); - if (sm == NULL) - goto end; - sm->type = DETECT_ISDATAAT; - sm->ctx = (SigMatchCtx *)idad; - SigMatchAppendSMToList(s, sm, sm_list); - - if (!(idad->flags & ISDATAAT_RELATIVE)) { - ret = 0; - goto end; - } - - if (prev_pm == NULL) { - ret = 0; - goto end; - } - - if (prev_pm->type == DETECT_CONTENT) { - DetectContentData *cd = (DetectContentData *)prev_pm->ctx; - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - } else if (prev_pm->type == DETECT_PCRE) { - DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx; - pd->flags |= DETECT_PCRE_RELATIVE_NEXT; - } - - ret = 0; - -end: - if (ret != 0) - DetectIsdataatFree(idad); - return ret; -} - -/** - * \brief this function will free memory associated with DetectIsdataatData - * - * \param idad pointer to DetectIsdataatData - */ -void DetectIsdataatFree(void *ptr) -{ - DetectIsdataatData *idad = (DetectIsdataatData *)ptr; - SCFree(idad); -} - - -#ifdef UNITTESTS - -/** - * \test DetectIsdataatTestParse01 is a test to make sure that we return a correct IsdataatData structure - * when given valid isdataat opt - */ -int DetectIsdataatTestParse01 (void) -{ - int result = 0; - DetectIsdataatData *idad = NULL; - idad = DetectIsdataatParse("30 ", NULL); - if (idad != NULL) { - DetectIsdataatFree(idad); - result = 1; - } - - return result; -} - -/** - * \test DetectIsdataatTestParse02 is a test to make sure that we return a correct IsdataatData structure - * when given valid isdataat opt - */ -int DetectIsdataatTestParse02 (void) -{ - int result = 0; - DetectIsdataatData *idad = NULL; - idad = DetectIsdataatParse("30 , relative", NULL); - if (idad != NULL && idad->flags & ISDATAAT_RELATIVE && !(idad->flags & ISDATAAT_RAWBYTES)) { - DetectIsdataatFree(idad); - result = 1; - } - - return result; -} - -/** - * \test DetectIsdataatTestParse03 is a test to make sure that we return a correct IsdataatData structure - * when given valid isdataat opt - */ -int DetectIsdataatTestParse03 (void) -{ - int result = 0; - DetectIsdataatData *idad = NULL; - idad = DetectIsdataatParse("30,relative, rawbytes ", NULL); - if (idad != NULL && idad->flags & ISDATAAT_RELATIVE && idad->flags & ISDATAAT_RAWBYTES) { - DetectIsdataatFree(idad); - result = 1; - } - - return result; -} - -/** - * \test Test isdataat option for dce sig. - */ -int DetectIsdataatTestParse04(void) -{ - Signature *s = SigAlloc(); - int result = 1; - - s->alproto = ALPROTO_DCERPC; - - result &= (DetectIsdataatSetup(NULL, s, "30") == 0); - result &= (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - SigFree(s); - - s = SigAlloc(); - s->alproto = ALPROTO_DCERPC; - /* failure since we have no preceding content/pcre/bytejump */ - result &= (DetectIsdataatSetup(NULL, s, "30,relative") == 0); - result &= (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - - SigFree(s); - - return result; -} - -/** - * \test Test isdataat option for dce sig. - */ -int DetectIsdataatTestParse05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "isdataat:4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) ) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "isdataat:4,relative; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) ) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "content:\"one\"; distance:0; " - "isdataat:4,relative,rawbytes; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - !(data->flags & ISDATAAT_RAWBYTES) ) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; isdataat:4,relative,rawbytes; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectIsdataatTestParse06(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; " - "isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) { - goto end; - } - - result = 1; - - result &= (s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectIsdataatTestParse07(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "uricontent:\"one\"; " - "isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL) { - goto end; - } - - result = 1; - - result &= (s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectIsdataatTestParse08(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; http_uri; " - "isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL) { - goto end; - } - - result = 1; - - result &= (s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectIsdataatTestParse09(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; http_client_body; " - "isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH] == NULL) { - goto end; - } - - result = 1; - - result &= (s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectIsdataatTestParse10(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; http_header; " - "isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] == NULL) { - goto end; - } - - result = 1; - - result &= (s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectIsdataatTestParse11(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "flow:to_server; content:\"one\"; http_raw_header; " - "isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH] == NULL) { - goto end; - } - - result = 1; - - result &= (s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectIsdataatTestParse12(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; http_method; " - "isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH] == NULL) { - goto end; - } - - result = 1; - - result &= (s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -int DetectIsdataatTestParse13(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; http_cookie; " - "isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH] == NULL) { - goto end; - } - - result = 1; - - result &= (s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->type == DETECT_ISDATAAT); - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -static int DetectIsdataatTestParse14(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing file_data and isdataat\"; " - "file_data; content:\"one\"; " - "isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("server body list empty: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_ISDATAAT) { - printf("last server body sm not isdataat: "); - goto end; - } - - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test file_data with isdataat relative to it - */ -static int DetectIsdataatTestParse15(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing file_data and isdataat\"; " - "file_data; isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("server body list empty: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_ISDATAAT) { - printf("last server body sm not isdataat: "); - goto end; - } - - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test dns_query with isdataat relative to it - */ -static int DetectIsdataatTestParse16(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectIsdataatData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing dns_query and isdataat\"; " - "dns_query; isdataat:!4,relative; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_DNSQUERYNAME_MATCH] == NULL) { - printf("dns_query list empty: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_DNSQUERYNAME_MATCH]->type != DETECT_ISDATAAT) { - printf("last dns_query body sm not isdataat: "); - goto end; - } - - data = (DetectIsdataatData *)s->sm_lists_tail[DETECT_SM_LIST_DNSQUERYNAME_MATCH]->ctx; - if ( !(data->flags & ISDATAAT_RELATIVE) || - (data->flags & ISDATAAT_RAWBYTES) || - !(data->flags & ISDATAAT_NEGATED) ) { - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test DetectIsdataatTestPacket01 is a test to check matches of - * isdataat, and isdataat relative - */ -int DetectIsdataatTestPacket01 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[1] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_UDP); - p[2] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_ICMP); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[5]; - sigs[0]= "alert ip any any -> any any (msg:\"Testing window 1\"; isdataat:6; sid:1;)"; - sigs[1]= "alert ip any any -> any any (msg:\"Testing window 2\"; content:\"all\"; isdataat:1, relative; isdataat:6; sid:2;)"; - sigs[2]= "alert ip any any -> any any (msg:\"Testing window 3\"; isdataat:8; sid:3;)"; - sigs[3]= "alert ip any any -> any any (msg:\"Testing window 4\"; content:\"Hi\"; isdataat:5, relative; sid:4;)"; - sigs[4]= "alert ip any any -> any any (msg:\"Testing window 4\"; content:\"Hi\"; isdataat:6, relative; sid:5;)"; - - uint32_t sid[5] = {1, 2, 3, 4, 5}; - - uint32_t results[3][5] = { - /* packet 0 match sid 1 but should not match sid 2 */ - {1, 1, 0, 1, 0}, - /* packet 1 should not match */ - {1, 1, 0, 1, 0}, - /* packet 2 should not match */ - {1, 1, 0, 1, 0} }; - - result = UTHGenericTest(p, 3, sigs, sid, (uint32_t *) results, 5); - - UTHFreePackets(p, 3); -end: - return result; -} - -/** - * \test DetectIsdataatTestPacket02 is a test to check matches of - * isdataat, and isdataat relative works if the previous keyword is pcre - * (bug 144) - */ -int DetectIsdataatTestPacket02 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0" - "User-Agent: Wget/1.11.4" - "Accept: */*" - "Host: www.google.com" - "Connection: Keep-Alive" - "Date: Mon, 04 Jan 2010 17:29:39 GMT"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre with" - " isdataat + relative\"; pcre:\"/A(ll|pp)WorkAndNoPlayMakesWillA" - "DullBoy/\"; isdataat:96,relative; sid:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} - -/** - * \test DetectIsdataatTestPacket03 is a test to check matches of - * isdataat, and isdataat relative works if the previous keyword is byte_jump - * (bug 146) - */ -int DetectIsdataatTestPacket03 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0" - "User-Agent: Wget/1.11.4" - "Accept: */*" - "Host: www.google.com" - "Connection: Keep-Alive" - "Date: Mon, 04 Jan 2010 17:29:39 GMT"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"byte_jump match = 0 " - "with distance content HTTP/1. relative against HTTP/1.0\"; byte_jump:1," - "46,string,dec; isdataat:87,relative; sid:109; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} -#endif - -/** - * \brief this function registers unit tests for DetectIsdataat - */ -void DetectIsdataatRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectIsdataatTestParse01", DetectIsdataatTestParse01, 1); - UtRegisterTest("DetectIsdataatTestParse02", DetectIsdataatTestParse02, 1); - UtRegisterTest("DetectIsdataatTestParse03", DetectIsdataatTestParse03, 1); - UtRegisterTest("DetectIsdataatTestParse04", DetectIsdataatTestParse04, 1); - UtRegisterTest("DetectIsdataatTestParse05", DetectIsdataatTestParse05, 1); - UtRegisterTest("DetectIsdataatTestParse06", DetectIsdataatTestParse06, 1); - UtRegisterTest("DetectIsdataatTestParse07", DetectIsdataatTestParse07, 1); - UtRegisterTest("DetectIsdataatTestParse08", DetectIsdataatTestParse08, 1); - UtRegisterTest("DetectIsdataatTestParse09", DetectIsdataatTestParse09, 1); - UtRegisterTest("DetectIsdataatTestParse10", DetectIsdataatTestParse10, 1); - UtRegisterTest("DetectIsdataatTestParse11", DetectIsdataatTestParse11, 1); - UtRegisterTest("DetectIsdataatTestParse12", DetectIsdataatTestParse12, 1); - UtRegisterTest("DetectIsdataatTestParse13", DetectIsdataatTestParse13, 1); - UtRegisterTest("DetectIsdataatTestParse14", DetectIsdataatTestParse14, 1); - UtRegisterTest("DetectIsdataatTestParse15", DetectIsdataatTestParse15, 1); - UtRegisterTest("DetectIsdataatTestParse16", DetectIsdataatTestParse16, 1); - - UtRegisterTest("DetectIsdataatTestPacket01", DetectIsdataatTestPacket01, 1); - UtRegisterTest("DetectIsdataatTestPacket02", DetectIsdataatTestPacket02, 1); - UtRegisterTest("DetectIsdataatTestPacket03", DetectIsdataatTestPacket03, 1); -#endif -} diff --git a/framework/src/suricata/src/detect-isdataat.h b/framework/src/suricata/src/detect-isdataat.h deleted file mode 100644 index f264f36d..00000000 --- a/framework/src/suricata/src/detect-isdataat.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_ISDATAAT_H__ -#define __DETECT_ISDATAAT_H__ - -#define ISDATAAT_RELATIVE 0x01 -#define ISDATAAT_RAWBYTES 0x02 -#define ISDATAAT_NEGATED 0x04 -#define ISDATAAT_OFFSET_BE 0x08 - -#define ISDATAAT_MIN 0 -#define ISDATAAT_MAX 65535 - -typedef struct DetectIsdataatData_ { - uint16_t dataat; /* data offset to match */ - uint8_t flags; /* isdataat options*/ -} DetectIsdataatData; - -/* prototypes */ -void DetectIsdataatRegister (void); - -#endif /* __DETECT_ISDATAAT_H__ */ - diff --git a/framework/src/suricata/src/detect-itype.c b/framework/src/suricata/src/detect-itype.c deleted file mode 100644 index 1be07647..00000000 --- a/framework/src/suricata/src/detect-itype.c +++ /dev/null @@ -1,529 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias - * - * Implements itype keyword support - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-itype.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -/** - *\brief Regex for parsing our itype options - */ -#define PARSE_REGEX "^\\s*(<|>)?\\s*([0-9]+)\\s*(?:<>\\s*([0-9]+))?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectITypeMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectITypeSetup(DetectEngineCtx *, Signature *, char *); -void DetectITypeRegisterTests(void); -void DetectITypeFree(void *); - - -/** - * \brief Registration function for itype: keyword - */ -void DetectITypeRegister (void) -{ - sigmatch_table[DETECT_ITYPE].name = "itype"; - sigmatch_table[DETECT_ITYPE].desc = "matching on a specific ICMP type"; - sigmatch_table[DETECT_ITYPE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#itype"; - sigmatch_table[DETECT_ITYPE].Match = DetectITypeMatch; - sigmatch_table[DETECT_ITYPE].Setup = DetectITypeSetup; - sigmatch_table[DETECT_ITYPE].Free = DetectITypeFree; - sigmatch_table[DETECT_ITYPE].RegisterTests = DetectITypeRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -/** - * \brief This function is used to match itype rule option set on a packet with those passed via itype: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectITypeData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectITypeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - int ret = 0; - uint8_t pitype; - const DetectITypeData *itd = (const DetectITypeData *)ctx; - - if (PKT_IS_PSEUDOPKT(p)) - return 0; - - if (PKT_IS_ICMPV4(p)) { - pitype = ICMPV4_GET_TYPE(p); - } else if (PKT_IS_ICMPV6(p)) { - pitype = ICMPV6_GET_TYPE(p); - } else { - /* Packet not ICMPv4 nor ICMPv6 */ - return ret; - } - - switch(itd->mode) { - case DETECT_ITYPE_EQ: - ret = (pitype == itd->type1) ? 1 : 0; - break; - case DETECT_ITYPE_LT: - ret = (pitype < itd->type1) ? 1 : 0; - break; - case DETECT_ITYPE_GT: - ret = (pitype > itd->type1) ? 1 : 0; - break; - case DETECT_ITYPE_RN: - ret = (pitype > itd->type1 && pitype < itd->type2) ? 1 : 0; - break; - } - - return ret; -} - -/** - * \brief This function is used to parse itype options passed via itype: keyword - * - * \param itypestr Pointer to the user provided itype options - * - * \retval itd pointer to DetectITypeData on success - * \retval NULL on failure - */ -DetectITypeData *DetectITypeParse(char *itypestr) -{ - DetectITypeData *itd = NULL; - char *args[3] = {NULL, NULL, NULL}; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, itypestr, strlen(itypestr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, itypestr); - goto error; - } - - int i; - const char *str_ptr; - for (i = 1; i < ret; i++) { - res = pcre_get_substring((char *)itypestr, ov, MAX_SUBSTRINGS, i, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[i-1] = (char *)str_ptr; - } - - itd = SCMalloc(sizeof(DetectITypeData)); - if (unlikely(itd == NULL)) - goto error; - itd->type1 = 0; - itd->type2 = 0; - itd->mode = 0; - - /* we have either "<" or ">" */ - if (args[0] != NULL && strlen(args[0]) != 0) { - /* we have a third part ("<> y"), therefore it's invalid */ - if (args[2] != NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "itype: invalid value"); - goto error; - } - /* we have only a comparison ("<", ">") */ - if (ByteExtractStringUint8(&itd->type1, 10, 0, args[1]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp type %s is not " - "valid", args[1]); - goto error; - } - if ((strcmp(args[0], ">")) == 0) itd->mode = DETECT_ITYPE_GT; - else itd->mode = DETECT_ITYPE_LT; - } else { /* no "<", ">" */ - /* we have a range ("<>") */ - if (args[2] != NULL) { - itd->mode = (uint8_t) DETECT_ITYPE_RN; - if (ByteExtractStringUint8(&itd->type1, 10, 0, args[1]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp type %s is not " - "valid", args[1]); - goto error; - } - if (ByteExtractStringUint8(&itd->type2, 10, 0, args[2]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp type %s is not " - "valid", args[2]); - goto error; - } - /* we check that the first given value in the range is less than - the second, otherwise we swap them */ - if (itd->type1 > itd->type2) { - uint8_t temp = itd->type1; - itd->type1 = itd->type2; - itd->type2 = temp; - } - } else { /* we have an equality */ - itd->mode = DETECT_ITYPE_EQ; - if (ByteExtractStringUint8(&itd->type1, 10, 0, args[1]) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp type %s is not " - "valid", args[1]); - goto error; - } - } - } - - for (i = 0; i < (ret-1); i++) { - if (args[i] != NULL) - SCFree(args[i]); - } - return itd; - -error: - for (i = 0; i < (ret-1) && i < 3; i++) { - if (args[i] != NULL) - SCFree(args[i]); - } - if (itd != NULL) - DetectITypeFree(itd); - return NULL; -} - -/** - * \brief this function is used to add the parsed itype data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param itypestr pointer to the user provided itype options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectITypeSetup(DetectEngineCtx *de_ctx, Signature *s, char *itypestr) -{ - - DetectITypeData *itd = NULL; - SigMatch *sm = NULL; - - itd = DetectITypeParse(itypestr); - if (itd == NULL) goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) goto error; - - sm->type = DETECT_ITYPE; - sm->ctx = (SigMatchCtx *)itd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (itd != NULL) DetectITypeFree(itd); - if (sm != NULL) SCFree(sm); - return -1; -} - -/** - * \brief this function will free memory associated with DetectITypeData - * - * \param ptr pointer to DetectITypeData - */ -void DetectITypeFree(void *ptr) -{ - DetectITypeData *itd = (DetectITypeData *)ptr; - SCFree(itd); -} - -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -/** - * \test DetectITypeParseTest01 is a test for setting a valid itype value - */ -int DetectITypeParseTest01(void) -{ - DetectITypeData *itd = NULL; - int result = 0; - itd = DetectITypeParse("8"); - if (itd != NULL) { - if (itd->type1 == 8 && itd->mode == DETECT_ITYPE_EQ) - result = 1; - DetectITypeFree(itd); - } - return result; -} - -/** - * \test DetectITypeParseTest02 is a test for setting a valid itype value - * with ">" operator - */ -int DetectITypeParseTest02(void) -{ -DetectITypeData *itd = NULL; - int result = 0; - itd = DetectITypeParse(">8"); - if (itd != NULL) { - if (itd->type1 == 8 && itd->mode == DETECT_ITYPE_GT) - result = 1; - DetectITypeFree(itd); - } - return result; -} - -/** - * \test DetectITypeParseTest03 is a test for setting a valid itype value - * with "<" operator - */ -int DetectITypeParseTest03(void) -{ - DetectITypeData *itd = NULL; - int result = 0; - itd = DetectITypeParse("<8"); - if (itd != NULL) { - if (itd->type1 == 8 && itd->mode == DETECT_ITYPE_LT) - result = 1; - DetectITypeFree(itd); - } - return result; -} - -/** - * \test DetectITypeParseTest04 is a test for setting a valid itype value - * with "<>" operator - */ -int DetectITypeParseTest04(void) -{ -DetectITypeData *itd = NULL; - int result = 0; - itd = DetectITypeParse("8<>20"); - if (itd != NULL) { - if (itd->type1 == 8 && itd->type2 == 20 && itd->mode == DETECT_ITYPE_RN) - result = 1; - DetectITypeFree(itd); - } - return result; -} - -/** - * \test DetectITypeParseTest05 is a test for setting a valid itype value - * with spaces all around - */ -int DetectITypeParseTest05(void) -{ -DetectITypeData *itd = NULL; - int result = 0; - itd = DetectITypeParse(" 8 "); - if (itd != NULL) { - if (itd->type1 == 8 && itd->mode == DETECT_ITYPE_EQ) - result = 1; - DetectITypeFree(itd); - } - return result; -} - -/** - * \test DetectITypeParseTest06 is a test for setting a valid itype value - * with ">" operator and spaces all around - */ -int DetectITypeParseTest06(void) -{ -DetectITypeData *itd = NULL; - int result = 0; - itd = DetectITypeParse(" > 8 "); - if (itd != NULL) { - if (itd->type1 == 8 && itd->mode == DETECT_ITYPE_GT) - result = 1; - DetectITypeFree(itd); - } - return result; -} - -/** - * \test DetectITypeParseTest07 is a test for setting a valid itype value - * with "<>" operator and spaces all around - */ -int DetectITypeParseTest07(void) -{ -DetectITypeData *itd = NULL; - int result = 0; - itd = DetectITypeParse(" 8 <> 20 "); - if (itd != NULL) { - if (itd->type1 == 8 && itd->type2 == 20 && itd->mode == DETECT_ITYPE_RN) - result = 1; - DetectITypeFree(itd); - } - return result; -} - -/** - * \test DetectITypeParseTest08 is a test for setting an invalid itype value - */ -int DetectITypeParseTest08(void) -{ - DetectITypeData *itd = NULL; - itd = DetectITypeParse("> 8 <> 20"); - if (itd == NULL) - return 1; - DetectITypeFree(itd); - return 0; -} - -/** - * \test DetectITypeMatchTest01 is a test for checking the working of itype - * keyword by creating 5 rules and matching a crafted packet against - * them. 4 out of 5 rules shall trigger. - */ -int DetectITypeMatchTest01(void) -{ - - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP); - p->icmpv4h->type = 10; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert icmp any any -> any any (itype:10; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (itype:<15; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (itype:>20; sid:3;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (itype:8<>20; sid:4;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (itype:20<>8; sid:5;)"); - if (s == NULL) { - goto end; - } - - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 0) { - SCLogDebug("sid 1 did not alert, but should have"); - goto cleanup; - } else if (PacketAlertCheck(p, 2) == 0) { - SCLogDebug("sid 2 did not alert, but should have"); - goto cleanup; - } else if (PacketAlertCheck(p, 3)) { - SCLogDebug("sid 3 alerted, but should not have"); - goto cleanup; - } else if (PacketAlertCheck(p, 4) == 0) { - SCLogDebug("sid 4 did not alert, but should have"); - goto cleanup; - } else if (PacketAlertCheck(p, 5) == 0) { - SCLogDebug("sid 5 did not alert, but should have"); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); -end: - return result; -} - - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectIType - */ -void DetectITypeRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectITypeParseTest01", DetectITypeParseTest01, 1); - UtRegisterTest("DetectITypeParseTest02", DetectITypeParseTest02, 1); - UtRegisterTest("DetectITypeParseTest03", DetectITypeParseTest03, 1); - UtRegisterTest("DetectITypeParseTest04", DetectITypeParseTest04, 1); - UtRegisterTest("DetectITypeParseTest05", DetectITypeParseTest05, 1); - UtRegisterTest("DetectITypeParseTest06", DetectITypeParseTest06, 1); - UtRegisterTest("DetectITypeParseTest07", DetectITypeParseTest07, 1); - UtRegisterTest("DetectITypeParseTest08", DetectITypeParseTest08, 1); - UtRegisterTest("DetectITypeMatchTest01", DetectITypeMatchTest01, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-itype.h b/framework/src/suricata/src/detect-itype.h deleted file mode 100644 index 168e0e7b..00000000 --- a/framework/src/suricata/src/detect-itype.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias - */ - -#ifndef __DETECT_ITYPE_H__ -#define __DETECT_ITYPE_H__ - -#define DETECT_ITYPE_EQ 0 /**< "equal" operator */ -#define DETECT_ITYPE_LT 1 /**< "less than" operator */ -#define DETECT_ITYPE_GT 2 /**< "greater than" operator */ -#define DETECT_ITYPE_RN 3 /**< "range" operator */ - -typedef struct DetectITypeData_ { - uint8_t type1; - uint8_t type2; - - uint8_t mode; -} DetectITypeData; - -/* prototypes */ -void DetectITypeRegister(void); - -#endif /* __DETECT_ITYPE_H__ */ diff --git a/framework/src/suricata/src/detect-l3proto.c b/framework/src/suricata/src/detect-l3proto.c deleted file mode 100644 index c67b47c8..00000000 --- a/framework/src/suricata/src/detect-l3proto.c +++ /dev/null @@ -1,391 +0,0 @@ -/* Copyright (C) 2012-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - * - * Implements the l3_proto keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-ipproto.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "detect-engine-siggroup.h" -#include "detect-engine-address.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "util-debug.h" - -static int DetectL3ProtoSetup(DetectEngineCtx *, Signature *, char *); - -void DetectL3protoRegisterTests(void); - -void DetectL3ProtoRegister(void) -{ - sigmatch_table[DETECT_L3PROTO].name = "l3_proto"; - sigmatch_table[DETECT_L3PROTO].Match = NULL; - sigmatch_table[DETECT_L3PROTO].Setup = DetectL3ProtoSetup; - sigmatch_table[DETECT_L3PROTO].Free = NULL; - sigmatch_table[DETECT_L3PROTO].RegisterTests = DetectL3protoRegisterTests; - - return; -} -/** - * \internal - * \brief Setup l3_proto keyword. - * - * \param de_ctx Detection engine context - * \param s Signature - * \param optstr Options string - * - * \return Non-zero on error - */ -static int DetectL3ProtoSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) -{ - char *str = optstr; - char dubbed = 0; - - /* strip "'s */ - if (optstr[0] == '\"' && optstr[strlen(optstr) - 1] == '\"') { - str = SCStrdup(optstr + 1); - if (unlikely(str == NULL)) - goto error; - str[strlen(optstr) - 2] = '\0'; - dubbed = 1; - } - - /* reset possible any value */ - if (s->proto.flags & DETECT_PROTO_ANY) { - s->proto.flags &= ~DETECT_PROTO_ANY; - } - - /* authorized value, ip, any, ip4, ipv4, ip6, ipv6 */ - if (strcasecmp(str,"ipv4") == 0 || - strcasecmp(str,"ip4") == 0 ) { - if (s->proto.flags & DETECT_PROTO_IPV6) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Conflicting l3 proto specified"); - goto error; - } - s->proto.flags |= DETECT_PROTO_IPV4; - SCLogDebug("IPv4 protocol detected"); - } else if (strcasecmp(str,"ipv6") == 0 || - strcasecmp(str,"ip6") == 0 ) { - if (s->proto.flags & DETECT_PROTO_IPV6) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Conflicting l3 proto specified"); - goto error; - } - s->proto.flags |= DETECT_PROTO_IPV6; - SCLogDebug("IPv6 protocol detected"); - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid l3 proto: \"%s\"", str); - goto error; - } - - if (dubbed) - SCFree(str); - return 0; -error: - if (dubbed) - SCFree(str); - return -1; -} - -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -/** - * \test DetectL3protoTestSig01 is a test for checking the working of ttl keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - */ - -static int DetectL3protoTestSig1(void) -{ - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - IPV4Hdr ip4h; - - memset(&th_v, 0, sizeof(th_v)); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->ip4h = &ip4h; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ipv4\"; l3_proto:ipv4; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ipv6\"; l3_proto:ipv6; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ip4\"; l3_proto:ip4; sid:3;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ip6\"; l3_proto:ip6; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 0) { - printf("sid 1 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2)) { - printf("sid 2 alerted, but should not have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 3) == 0) { - printf("sid 3 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 4)) { - printf("sid 4 alerted, but should not have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - SCFree(p); - return result; -} - -/** - * \test DetectL3protoTestSig02 is a test for checking the working of l3proto keyword - * by setting up the signature and later testing its working by matching - * the received IPv6 packet against the sig. - */ - -static int DetectL3protoTestSig2(void) -{ - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - IPV6Hdr ip6h; - - memset(&th_v, 0, sizeof(th_v)); - - p->src.family = AF_INET6; - p->dst.family = AF_INET6; - p->proto = IPPROTO_TCP; - p->ip6h = &ip6h; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ipv4\"; l3_proto:ipv4; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ipv6\"; l3_proto:ipv6; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ip4\"; l3_proto:ip4; sid:3;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ip6\"; l3_proto:ip6; sid:4;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 alerted, but should not have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2) == 0) { - printf("sid 2 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 3)) { - printf("sid 3 alerted, but should not have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 4) == 0) { - printf("sid 4 did not alert, but should have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - SCFree(p); - return result; -} - -/** - * \test DetectL3protoTestSig03 is a test for checking the working of l3proto keyword - * in conjonction with ip_proto keyword. - */ - -static int DetectL3protoTestSig3(void) -{ - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - IPV6Hdr ip6h; - - memset(&th_v, 0, sizeof(th_v)); - - p->src.family = AF_INET6; - p->dst.family = AF_INET6; - p->proto = IPPROTO_TCP; - p->ip6h = &ip6h; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ipv4 and ip_proto udp\"; l3_proto:ipv4; ip_proto:17; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ipv6 and ip_proto udp\"; l3_proto:ipv6; ip_proto:17; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ip4 and ip_proto tcp\"; l3_proto:ipv4; ip_proto:6; sid:3;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"l3proto ipv6 and ip_proto tcp\"; l3_proto:ipv6; ip_proto:6; sid:4;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 alerted, but should not have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2)) { - printf("sid 2 alerted, but should not have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 3)) { - printf("sid 3 alerted, but should not have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 4) == 0) { - printf("sid 4 did not alert, but should have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - SCFree(p); - return result; -} - - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectL3proto - */ -void DetectL3protoRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectL3protoTestSig1", DetectL3protoTestSig1, 1); - UtRegisterTest("DetectL3protoTestSig2", DetectL3protoTestSig2, 1); - UtRegisterTest("DetectL3protoTestSig3", DetectL3protoTestSig3, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-l3proto.h b/framework/src/suricata/src/detect-l3proto.h deleted file mode 100644 index 447cd95d..00000000 --- a/framework/src/suricata/src/detect-l3proto.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - */ - -#ifndef __DETECT_L3PROTO_H__ -#define __DETECT_L3PROTO_H__ - -/** - * \brief Registration function for ip_proto keyword. - */ -void DetectL3ProtoRegister (void); - -#endif /* __DETECT_L3PROTO_H__ */ diff --git a/framework/src/suricata/src/detect-lua-extensions.c b/framework/src/suricata/src/detect-lua-extensions.c deleted file mode 100644 index ae9b4e14..00000000 --- a/framework/src/suricata/src/detect-lua-extensions.c +++ /dev/null @@ -1,627 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Functions to expose to the lua scripts. - */ - -#include "suricata-common.h" -#include "conf.h" - -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-flowvar.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-spm-bm.h" -#include "util-print.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" - -#include "stream-tcp.h" - -#include "detect-lua.h" - -#include "queue.h" -#include "util-cpu.h" - -#include "app-layer-parser.h" - -#ifdef HAVE_LUA - -#include "util-lua.h" -#include "util-lua-common.h" -#include "util-lua-http.h" -#include "util-lua-dns.h" -#include "util-lua-tls.h" -#include "util-lua-ssh.h" - -static const char luaext_key_ld[] = "suricata:luajitdata"; -static const char luaext_key_det_ctx[] = "suricata:det_ctx"; - -static int LuaGetFlowvar(lua_State *luastate) -{ - uint16_t idx; - int id; - Flow *f; - FlowVar *fv; - DetectLuaData *ld; - int flow_lock = 0; - - /* need luajit data for id -> idx conversion */ - lua_pushlightuserdata(luastate, (void *)&luaext_key_ld); - lua_gettable(luastate, LUA_REGISTRYINDEX); - ld = lua_touserdata(luastate, -1); - SCLogDebug("ld %p", ld); - if (ld == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "internal error: no ld"); - return 2; - } - - /* need flow and lock hint */ - f = LuaStateGetFlow(luastate, &flow_lock); - if (f == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "no flow"); - return 2; - } - - /* need flowvar idx */ - if (!lua_isnumber(luastate, 1)) { - lua_pushnil(luastate); - lua_pushstring(luastate, "1st arg not a number"); - return 2; - } - id = lua_tonumber(luastate, 1); - if (id < 0 || id >= DETECT_LUAJIT_MAX_FLOWVARS) { - lua_pushnil(luastate); - lua_pushstring(luastate, "flowvar id out of range"); - return 2; - } - idx = ld->flowvar[id]; - if (idx == 0) { - lua_pushnil(luastate); - lua_pushstring(luastate, "flowvar id uninitialized"); - return 2; - } - - /* lookup var */ - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_RDLOCK(f); - - fv = FlowVarGet(f, idx); - if (fv == NULL) { - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_UNLOCK(f); - - lua_pushnil(luastate); - lua_pushstring(luastate, "no flow var"); - return 2; - } - - LuaPushStringBuffer(luastate, (const uint8_t *)fv->data.fv_str.value, - (size_t)fv->data.fv_str.value_len); - - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_UNLOCK(f); - - return 1; - -} - -int LuaSetFlowvar(lua_State *luastate) -{ - uint16_t idx; - int id; - Flow *f; - const char *str; - int len; - uint8_t *buffer; - DetectEngineThreadCtx *det_ctx; - DetectLuaData *ld; - int flow_lock = 0; - - /* need luajit data for id -> idx conversion */ - lua_pushlightuserdata(luastate, (void *)&luaext_key_ld); - lua_gettable(luastate, LUA_REGISTRYINDEX); - ld = lua_touserdata(luastate, -1); - SCLogDebug("ld %p", ld); - if (ld == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "internal error: no ld"); - return 2; - } - - /* need det_ctx */ - lua_pushlightuserdata(luastate, (void *)&luaext_key_det_ctx); - lua_gettable(luastate, LUA_REGISTRYINDEX); - det_ctx = lua_touserdata(luastate, -1); - SCLogDebug("det_ctx %p", det_ctx); - if (det_ctx == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "internal error: no det_ctx"); - return 2; - } - - /* need flow and lock hint */ - f = LuaStateGetFlow(luastate, &flow_lock); - if (f == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "no flow"); - return 2; - } - - /* need flowvar idx */ - if (!lua_isnumber(luastate, 1)) { - lua_pushnil(luastate); - lua_pushstring(luastate, "1st arg not a number"); - return 2; - } - id = lua_tonumber(luastate, 1); - if (id < 0 || id >= DETECT_LUAJIT_MAX_FLOWVARS) { - lua_pushnil(luastate); - lua_pushstring(luastate, "flowvar id out of range"); - return 2; - } - - if (!lua_isstring(luastate, 2)) { - lua_pushnil(luastate); - lua_pushstring(luastate, "2nd arg not a string"); - return 2; - } - str = lua_tostring(luastate, 2); - if (str == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "null string"); - return 2; - } - - if (!lua_isnumber(luastate, 3)) { - lua_pushnil(luastate); - lua_pushstring(luastate, "3rd arg not a number"); - return 2; - } - len = lua_tonumber(luastate, 3); - if (len < 0 || len > 0xffff) { - lua_pushnil(luastate); - lua_pushstring(luastate, "len out of range: max 64k"); - return 2; - } - - idx = ld->flowvar[id]; - if (idx == 0) { - lua_pushnil(luastate); - lua_pushstring(luastate, "flowvar id uninitialized"); - return 2; - } - - buffer = SCMalloc(len+1); - if (unlikely(buffer == NULL)) { - lua_pushnil(luastate); - lua_pushstring(luastate, "out of memory"); - return 2; - } - memcpy(buffer, str, len); - buffer[len] = '\0'; - - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FlowVarAddStr(f, idx, buffer, len); - else - FlowVarAddStrNoLock(f, idx, buffer, len); - - //SCLogInfo("stored:"); - //PrintRawDataFp(stdout,buffer,len); - return 0; -} - -static int LuaGetFlowint(lua_State *luastate) -{ - uint16_t idx; - int id; - Flow *f; - FlowVar *fv; - DetectLuaData *ld; - int flow_lock = 0; - uint32_t number; - - /* need luajit data for id -> idx conversion */ - lua_pushlightuserdata(luastate, (void *)&luaext_key_ld); - lua_gettable(luastate, LUA_REGISTRYINDEX); - ld = lua_touserdata(luastate, -1); - SCLogDebug("ld %p", ld); - if (ld == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "internal error: no ld"); - return 2; - } - - /* need flow and lock hint */ - f = LuaStateGetFlow(luastate, &flow_lock); - if (f == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "no flow"); - return 2; - } - - /* need flowint idx */ - if (!lua_isnumber(luastate, 1)) { - SCLogDebug("1st arg not a number"); - lua_pushnil(luastate); - lua_pushstring(luastate, "1st arg not a number"); - return 2; - } - id = lua_tonumber(luastate, 1); - if (id < 0 || id >= DETECT_LUAJIT_MAX_FLOWINTS) { - SCLogDebug("id %d", id); - lua_pushnil(luastate); - lua_pushstring(luastate, "flowint id out of range"); - return 2; - } - idx = ld->flowint[id]; - if (idx == 0) { - SCLogDebug("idx %u", idx); - lua_pushnil(luastate); - lua_pushstring(luastate, "flowint id uninitialized"); - return 2; - } - - /* lookup var */ - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_RDLOCK(f); - - fv = FlowVarGet(f, idx); - if (fv == NULL) { - SCLogDebug("fv NULL"); - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_UNLOCK(f); - - lua_pushnil(luastate); - lua_pushstring(luastate, "no flow var"); - return 2; - } - number = fv->data.fv_int.value; - - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_UNLOCK(f); - - /* return value through luastate, as a luanumber */ - lua_pushnumber(luastate, (lua_Number)number); - SCLogDebug("retrieved flow:%p idx:%u value:%u", f, idx, number); - - return 1; - -} - -int LuaSetFlowint(lua_State *luastate) -{ - uint16_t idx; - int id; - Flow *f; - DetectEngineThreadCtx *det_ctx; - DetectLuaData *ld; - int flow_lock = 0; - uint32_t number; - lua_Number luanumber; - - /* need luajit data for id -> idx conversion */ - lua_pushlightuserdata(luastate, (void *)&luaext_key_ld); - lua_gettable(luastate, LUA_REGISTRYINDEX); - ld = lua_touserdata(luastate, -1); - SCLogDebug("ld %p", ld); - if (ld == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "internal error: no ld"); - return 2; - } - - /* need det_ctx */ - lua_pushlightuserdata(luastate, (void *)&luaext_key_det_ctx); - lua_gettable(luastate, LUA_REGISTRYINDEX); - det_ctx = lua_touserdata(luastate, -1); - SCLogDebug("det_ctx %p", det_ctx); - if (det_ctx == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "internal error: no det_ctx"); - return 2; - } - - /* need flow and lock hint */ - f = LuaStateGetFlow(luastate, &flow_lock); - if (f == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "no flow"); - return 2; - } - - /* need flowint idx */ - if (!lua_isnumber(luastate, 1)) { - lua_pushnil(luastate); - lua_pushstring(luastate, "1st arg not a number"); - return 2; - } - id = lua_tonumber(luastate, 1); - if (id < 0 || id >= DETECT_LUAJIT_MAX_FLOWVARS) { - lua_pushnil(luastate); - lua_pushstring(luastate, "flowint id out of range"); - return 2; - } - - if (!lua_isnumber(luastate, 2)) { - lua_pushnil(luastate); - lua_pushstring(luastate, "2nd arg not a number"); - return 2; - } - luanumber = lua_tonumber(luastate, 2); - if (luanumber < 0 || id > (double)UINT_MAX) { - lua_pushnil(luastate); - lua_pushstring(luastate, "value out of range, value must be unsigned 32bit int"); - return 2; - } - number = (uint32_t)luanumber; - - idx = ld->flowint[id]; - if (idx == 0) { - lua_pushnil(luastate); - lua_pushstring(luastate, "flowint id uninitialized"); - return 2; - } - - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FlowVarAddInt(f, idx, number); - else - FlowVarAddIntNoLock(f, idx, number); - - SCLogDebug("stored flow:%p idx:%u value:%u", f, idx, number); - return 0; -} - -static int LuaIncrFlowint(lua_State *luastate) -{ - uint16_t idx; - int id; - Flow *f; - FlowVar *fv; - DetectLuaData *ld; - int flow_lock = 0; - uint32_t number; - - /* need luajit data for id -> idx conversion */ - lua_pushlightuserdata(luastate, (void *)&luaext_key_ld); - lua_gettable(luastate, LUA_REGISTRYINDEX); - ld = lua_touserdata(luastate, -1); - SCLogDebug("ld %p", ld); - if (ld == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "internal error: no ld"); - return 2; - } - - /* need flow and lock hint */ - f = LuaStateGetFlow(luastate, &flow_lock); - if (f == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "no flow"); - return 2; - } - - /* need flowint idx */ - if (!lua_isnumber(luastate, 1)) { - SCLogDebug("1st arg not a number"); - lua_pushnil(luastate); - lua_pushstring(luastate, "1st arg not a number"); - return 2; - } - id = lua_tonumber(luastate, 1); - if (id < 0 || id >= DETECT_LUAJIT_MAX_FLOWINTS) { - SCLogDebug("id %d", id); - lua_pushnil(luastate); - lua_pushstring(luastate, "flowint id out of range"); - return 2; - } - idx = ld->flowint[id]; - if (idx == 0) { - SCLogDebug("idx %u", idx); - lua_pushnil(luastate); - lua_pushstring(luastate, "flowint id uninitialized"); - return 2; - } - - /* lookup var */ - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_RDLOCK(f); - - fv = FlowVarGet(f, idx); - if (fv == NULL) { - number = 1; - } else { - number = fv->data.fv_int.value; - if (number < UINT_MAX) - number++; - } - FlowVarAddIntNoLock(f, idx, number); - - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_UNLOCK(f); - - /* return value through luastate, as a luanumber */ - lua_pushnumber(luastate, (lua_Number)number); - SCLogDebug("incremented flow:%p idx:%u value:%u", f, idx, number); - - return 1; - -} - -static int LuaDecrFlowint(lua_State *luastate) -{ - uint16_t idx; - int id; - Flow *f; - FlowVar *fv; - DetectLuaData *ld; - int flow_lock = 0; - uint32_t number; - - /* need luajit data for id -> idx conversion */ - lua_pushlightuserdata(luastate, (void *)&luaext_key_ld); - lua_gettable(luastate, LUA_REGISTRYINDEX); - ld = lua_touserdata(luastate, -1); - SCLogDebug("ld %p", ld); - if (ld == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "internal error: no ld"); - return 2; - } - - /* need flow and lock hint */ - f = LuaStateGetFlow(luastate, &flow_lock); - if (f == NULL) { - lua_pushnil(luastate); - lua_pushstring(luastate, "no flow"); - return 2; - } - - /* need flowint idx */ - if (!lua_isnumber(luastate, 1)) { - SCLogDebug("1st arg not a number"); - lua_pushnil(luastate); - lua_pushstring(luastate, "1st arg not a number"); - return 2; - } - id = lua_tonumber(luastate, 1); - if (id < 0 || id >= DETECT_LUAJIT_MAX_FLOWINTS) { - SCLogDebug("id %d", id); - lua_pushnil(luastate); - lua_pushstring(luastate, "flowint id out of range"); - return 2; - } - idx = ld->flowint[id]; - if (idx == 0) { - SCLogDebug("idx %u", idx); - lua_pushnil(luastate); - lua_pushstring(luastate, "flowint id uninitialized"); - return 2; - } - - /* lookup var */ - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_RDLOCK(f); - - fv = FlowVarGet(f, idx); - if (fv == NULL) { - number = 0; - } else { - number = fv->data.fv_int.value; - if (number > 0) - number--; - } - FlowVarAddIntNoLock(f, idx, number); - - if (flow_lock == LUA_FLOW_NOT_LOCKED_BY_PARENT) - FLOWLOCK_UNLOCK(f); - - /* return value through luastate, as a luanumber */ - lua_pushnumber(luastate, (lua_Number)number); - SCLogDebug("decremented flow:%p idx:%u value:%u", f, idx, number); - - return 1; - -} - -void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, DetectEngineThreadCtx *det_ctx, - Flow *f, int flow_locked, Packet *p, uint8_t flags) -{ - SCLogDebug("det_ctx %p, f %p", det_ctx, f); - - /* luajit keyword data */ - lua_pushlightuserdata(lua_state, (void *)&luaext_key_ld); - lua_pushlightuserdata(lua_state, (void *)ld); - lua_settable(lua_state, LUA_REGISTRYINDEX); - - /* detection engine thread ctx */ - lua_pushlightuserdata(lua_state, (void *)&luaext_key_det_ctx); - lua_pushlightuserdata(lua_state, (void *)det_ctx); - lua_settable(lua_state, LUA_REGISTRYINDEX); - - LuaStateSetFlow(lua_state, f, flow_locked); - - if (det_ctx->tx_id_set && flow_locked == LUA_FLOW_LOCKED_BY_PARENT) { - if (f && f->alstate) { - void *txptr = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, det_ctx->tx_id); - if (txptr) { - LuaStateSetTX(lua_state, txptr); - } - } - } - - if (p != NULL) - LuaStateSetPacket(lua_state, p); - - LuaStateSetDirection(lua_state, (flags & STREAM_TOSERVER)); -} - -/** - * \brief Register Suricata Lua functions - */ -int LuaRegisterExtensions(lua_State *lua_state) -{ - lua_pushcfunction(lua_state, LuaGetFlowvar); - lua_setglobal(lua_state, "ScFlowvarGet"); - - lua_pushcfunction(lua_state, LuaSetFlowvar); - lua_setglobal(lua_state, "ScFlowvarSet"); - - lua_pushcfunction(lua_state, LuaGetFlowint); - lua_setglobal(lua_state, "ScFlowintGet"); - - lua_pushcfunction(lua_state, LuaSetFlowint); - lua_setglobal(lua_state, "ScFlowintSet"); - - lua_pushcfunction(lua_state, LuaIncrFlowint); - lua_setglobal(lua_state, "ScFlowintIncr"); - - lua_pushcfunction(lua_state, LuaDecrFlowint); - lua_setglobal(lua_state, "ScFlowintDecr"); - - LuaRegisterFunctions(lua_state); - LuaRegisterHttpFunctions(lua_state); - LuaRegisterDnsFunctions(lua_state); - LuaRegisterTlsFunctions(lua_state); - LuaRegisterSshFunctions(lua_state); - return 0; -} - -#endif /* HAVE_LUA */ diff --git a/framework/src/suricata/src/detect-lua-extensions.h b/framework/src/suricata/src/detect-lua-extensions.h deleted file mode 100644 index b8aa2736..00000000 --- a/framework/src/suricata/src/detect-lua-extensions.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_LUA_EXT_H__ -#define __DETECT_LUA_EXT_H__ - -#ifdef HAVE_LUA -int LuaRegisterExtensions(lua_State *); - -void LuaExtensionsMatchSetup(lua_State *lua_state, - DetectLuaData *, DetectEngineThreadCtx *det_ctx, - Flow *f, int flow_locked, Packet *p, uint8_t flags); - -#endif /* HAVE_LUA */ -#endif diff --git a/framework/src/suricata/src/detect-lua.c b/framework/src/suricata/src/detect-lua.c deleted file mode 100644 index a3eead4a..00000000 --- a/framework/src/suricata/src/detect-lua.c +++ /dev/null @@ -1,2088 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "conf.h" - -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-spm-bm.h" -#include "util-print.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "stream-tcp.h" - -#include "detect-lua.h" -#include "detect-lua-extensions.h" - -#include "queue.h" -#include "util-cpu.h" -#include "util-var-name.h" - -#ifndef HAVE_LUA - -static int DetectLuaSetupNoSupport (DetectEngineCtx *a, Signature *b, char *c) -{ - SCLogError(SC_ERR_NO_LUA_SUPPORT, "no Lua support built in, needed for lua/luajit keyword"); - return -1; -} - -/** - * \brief Registration function for keyword: luajit - */ -void DetectLuaRegister(void) -{ - sigmatch_table[DETECT_LUA].name = "lua"; - sigmatch_table[DETECT_LUA].alias = "luajit"; - sigmatch_table[DETECT_LUA].Setup = DetectLuaSetupNoSupport; - sigmatch_table[DETECT_LUA].Free = NULL; - sigmatch_table[DETECT_LUA].RegisterTests = NULL; - sigmatch_table[DETECT_LUA].flags = SIGMATCH_NOT_BUILT; - - SCLogDebug("registering lua rule option"); - return; -} - -#else /* HAVE_LUA */ - -#ifdef HAVE_LUAJIT -#include "util-pool.h" - -/** \brief lua_State pool - * - * Lua requires states to be alloc'd in memory <2GB. For this reason we - * prealloc the states early during engine startup so we have a better chance - * of getting the states. We protect the pool with a lock as the detect - * threads access it during their init and cleanup. - * - * Pool size is automagically determined based on number of keyword occurences, - * cpus/cores and rule reloads being enabled or not. - * - * Alternatively, the "detect-engine.luajit-states" var can be set. - */ -static Pool *luajit_states = NULL; -static pthread_mutex_t luajit_states_lock = SCMUTEX_INITIALIZER; - -#endif /* HAVE_LUAJIT */ - -#include "util-lua.h" - -static int DetectLuaMatch (ThreadVars *, DetectEngineThreadCtx *, - Packet *, Signature *, const SigMatchCtx *); -static int DetectLuaAppMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m); -static int DetectLuaAppTxMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, - void *state, void *txv, const Signature *s, - const SigMatchCtx *ctx); -static int DetectLuaSetup (DetectEngineCtx *, Signature *, char *); -static void DetectLuaRegisterTests(void); -static void DetectLuaFree(void *); - -/** - * \brief Registration function for keyword: luajit - */ -void DetectLuaRegister(void) -{ - sigmatch_table[DETECT_LUA].name = "lua"; - sigmatch_table[DETECT_LUA].alias = "luajit"; - sigmatch_table[DETECT_LUA].desc = "match via a luajit script"; - sigmatch_table[DETECT_LUA].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Lua_scripting"; - sigmatch_table[DETECT_LUA].Match = DetectLuaMatch; - sigmatch_table[DETECT_LUA].AppLayerMatch = DetectLuaAppMatch; - sigmatch_table[DETECT_LUA].AppLayerTxMatch = DetectLuaAppTxMatch; - sigmatch_table[DETECT_LUA].Setup = DetectLuaSetup; - sigmatch_table[DETECT_LUA].Free = DetectLuaFree; - sigmatch_table[DETECT_LUA].RegisterTests = DetectLuaRegisterTests; - - SCLogDebug("registering luajit rule option"); - return; -} - -#define DATATYPE_PACKET (1<<0) -#define DATATYPE_PAYLOAD (1<<1) -#define DATATYPE_STREAM (1<<2) - -#define DATATYPE_HTTP_URI (1<<3) -#define DATATYPE_HTTP_URI_RAW (1<<4) - -#define DATATYPE_HTTP_REQUEST_HEADERS (1<<5) -#define DATATYPE_HTTP_REQUEST_HEADERS_RAW (1<<6) -#define DATATYPE_HTTP_REQUEST_COOKIE (1<<7) -#define DATATYPE_HTTP_REQUEST_UA (1<<8) - -#define DATATYPE_HTTP_REQUEST_LINE (1<<9) -#define DATATYPE_HTTP_REQUEST_BODY (1<<10) - -#define DATATYPE_HTTP_RESPONSE_COOKIE (1<<11) -#define DATATYPE_HTTP_RESPONSE_BODY (1<<12) - -#define DATATYPE_HTTP_RESPONSE_HEADERS (1<<13) -#define DATATYPE_HTTP_RESPONSE_HEADERS_RAW (1<<14) - -#define DATATYPE_DNS_RRNAME (1<<15) -#define DATATYPE_DNS_REQUEST (1<<16) -#define DATATYPE_DNS_RESPONSE (1<<17) - -#define DATATYPE_TLS (1<<18) - -#define DATATYPE_SSH (1<<19) - -#ifdef HAVE_LUAJIT -static void *LuaStatePoolAlloc(void) -{ - return luaL_newstate(); -} - -static void LuaStatePoolFree(void *d) -{ - lua_State *s = (lua_State *)d; - if (s != NULL) - lua_close(s); -} - -/** \brief Populate lua states pool - * - * \param num keyword instances - * \param reloads bool indicating we have rule reloads enabled - */ -int DetectLuajitSetupStatesPool(int num, int reloads) -{ - int retval = 0; - pthread_mutex_lock(&luajit_states_lock); - - if (luajit_states == NULL) { - intmax_t cnt = 0; - ConfNode *denode = NULL; - ConfNode *decnf = ConfGetNode("detect-engine"); - if (decnf != NULL) { - TAILQ_FOREACH(denode, &decnf->head, next) { - if (strcmp(denode->val, "luajit-states") == 0) { - ConfGetChildValueInt(denode, "luajit-states", &cnt); - } - } - } - - if (cnt == 0) { - int cpus = UtilCpuGetNumProcessorsOnline(); - if (cpus == 0) { - cpus = 10; - } - cnt = num * cpus; - cnt *= 3; /* assume 3 threads per core */ - - /* alloc a bunch extra so reload can add new rules/instances */ - if (reloads) - cnt *= 5; - } - - luajit_states = PoolInit(0, cnt, 0, LuaStatePoolAlloc, NULL, NULL, NULL, LuaStatePoolFree); - if (luajit_states == NULL) { - SCLogError(SC_ERR_LUA_ERROR, "luastate pool init failed, lua/luajit keywords won't work"); - retval = -1; - } - } - - pthread_mutex_unlock(&luajit_states_lock); - return retval; -} -#endif /* HAVE_LUAJIT */ - -static lua_State *DetectLuaGetState(void) -{ - - lua_State *s = NULL; -#ifdef HAVE_LUAJIT - pthread_mutex_lock(&luajit_states_lock); - if (luajit_states != NULL) - s = (lua_State *)PoolGet(luajit_states); - pthread_mutex_unlock(&luajit_states_lock); -#else - s = luaL_newstate(); -#endif - return s; -} - -static void DetectLuaReturnState(lua_State *s) -{ - if (s != NULL) { -#ifdef HAVE_LUAJIT - pthread_mutex_lock(&luajit_states_lock); - PoolReturn(luajit_states, (void *)s); - pthread_mutex_unlock(&luajit_states_lock); -#else - lua_close(s); -#endif - } -} - -/** \brief dump stack from lua state to screen */ -void LuaDumpStack(lua_State *state) -{ - int size = lua_gettop(state); - int i; - - for (i = 1; i <= size; i++) { - int type = lua_type(state, i); - printf("Stack size=%d, level=%d, type=%d, ", size, i, type); - - switch (type) { - case LUA_TFUNCTION: - printf("function %s", lua_tostring(state, i) ? "true" : "false"); - break; - case LUA_TBOOLEAN: - printf("bool %s", lua_toboolean(state, i) ? "true" : "false"); - break; - case LUA_TNUMBER: - printf("number %g", lua_tonumber(state, i)); - break; - case LUA_TSTRING: - printf("string `%s'", lua_tostring(state, i)); - break; - case LUA_TTABLE: - printf("table `%s'", lua_tostring(state, i)); - break; - default: - printf("other %s", lua_typename(state, type)); - break; - - } - printf("\n"); - } -} - -int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, - uint8_t *buffer, uint32_t buffer_len, uint32_t offset, - Flow *f, int flow_lock) -{ - SCEnter(); - int ret = 0; - - if (buffer == NULL || buffer_len == 0) - SCReturnInt(0); - - DetectLuaData *luajit = (DetectLuaData *)sm->ctx; - if (luajit == NULL) - SCReturnInt(0); - - DetectLuaThreadData *tluajit = (DetectLuaThreadData *)DetectThreadCtxGetKeywordThreadCtx(det_ctx, luajit->thread_ctx_id); - if (tluajit == NULL) - SCReturnInt(0); - - /* setup extension data for use in lua c functions */ - LuaExtensionsMatchSetup(tluajit->luastate, luajit, det_ctx, - f, flow_lock, /* no packet in the ctx */NULL, 0); - - /* prepare data to pass to script */ - lua_getglobal(tluajit->luastate, "match"); - lua_newtable(tluajit->luastate); /* stack at -1 */ - - lua_pushliteral (tluajit->luastate, "offset"); /* stack at -2 */ - lua_pushnumber (tluajit->luastate, (int)(offset + 1)); - lua_settable(tluajit->luastate, -3); - - lua_pushstring (tluajit->luastate, luajit->buffername); /* stack at -2 */ - LuaPushStringBuffer(tluajit->luastate, (const uint8_t *)buffer, (size_t)buffer_len); - lua_settable(tluajit->luastate, -3); - - int retval = lua_pcall(tluajit->luastate, 1, 1, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(tluajit->luastate, -1)); - } - - /* process returns from script */ - if (lua_gettop(tluajit->luastate) > 0) { - /* script returns a number (return 1 or return 0) */ - if (lua_type(tluajit->luastate, 1) == LUA_TNUMBER) { - double script_ret = lua_tonumber(tluajit->luastate, 1); - SCLogDebug("script_ret %f", script_ret); - lua_pop(tluajit->luastate, 1); - - if (script_ret == 1.0) - ret = 1; - - /* script returns a table */ - } else if (lua_type(tluajit->luastate, 1) == LUA_TTABLE) { - lua_pushnil(tluajit->luastate); - const char *k, *v; - while (lua_next(tluajit->luastate, -2)) { - v = lua_tostring(tluajit->luastate, -1); - lua_pop(tluajit->luastate, 1); - k = lua_tostring(tluajit->luastate, -1); - - if (!k || !v) - continue; - - SCLogDebug("k='%s', v='%s'", k, v); - - if (strcmp(k, "retval") == 0) { - if (atoi(v) == 1) - ret = 1; - } else { - /* set flow var? */ - } - } - - /* pop the table */ - lua_pop(tluajit->luastate, 1); - } - } else { - SCLogDebug("no stack"); - } - - /* clear the stack */ - while (lua_gettop(tluajit->luastate) > 0) { - lua_pop(tluajit->luastate, 1); - } - - if (luajit->negated) { - if (ret == 1) - ret = 0; - else - ret = 1; - } - - SCReturnInt(ret); - -} - -/** - * \brief match the specified luajit - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param p packet - * \param s signature being inspected - * \param m sigmatch that we will cast into DetectLuaData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectLuaMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - SCEnter(); - int ret = 0; - DetectLuaData *luajit = (DetectLuaData *)ctx; - if (luajit == NULL) - SCReturnInt(0); - - DetectLuaThreadData *tluajit = (DetectLuaThreadData *)DetectThreadCtxGetKeywordThreadCtx(det_ctx, luajit->thread_ctx_id); - if (tluajit == NULL) - SCReturnInt(0); - - /* setup extension data for use in lua c functions */ - uint8_t flags = 0; - if (p->flowflags & FLOW_PKT_TOSERVER) - flags = STREAM_TOSERVER; - else if (p->flowflags & FLOW_PKT_TOCLIENT) - flags = STREAM_TOCLIENT; - - LuaExtensionsMatchSetup(tluajit->luastate, luajit, det_ctx, - p->flow, /* flow not locked */LUA_FLOW_NOT_LOCKED_BY_PARENT, p, flags); - - if ((tluajit->flags & DATATYPE_PAYLOAD) && p->payload_len == 0) - SCReturnInt(0); - if ((tluajit->flags & DATATYPE_PACKET) && GET_PKT_LEN(p) == 0) - SCReturnInt(0); - if (tluajit->alproto != ALPROTO_UNKNOWN) { - if (p->flow == NULL) - SCReturnInt(0); - - FLOWLOCK_RDLOCK(p->flow); - int alproto = p->flow->alproto; - FLOWLOCK_UNLOCK(p->flow); - - if (tluajit->alproto != alproto) - SCReturnInt(0); - } - - lua_getglobal(tluajit->luastate, "match"); - lua_newtable(tluajit->luastate); /* stack at -1 */ - - if ((tluajit->flags & DATATYPE_PAYLOAD) && p->payload_len) { - lua_pushliteral(tluajit->luastate, "payload"); /* stack at -2 */ - LuaPushStringBuffer (tluajit->luastate, (const uint8_t *)p->payload, (size_t)p->payload_len); /* stack at -3 */ - lua_settable(tluajit->luastate, -3); - } - if ((tluajit->flags & DATATYPE_PACKET) && GET_PKT_LEN(p)) { - lua_pushliteral(tluajit->luastate, "packet"); /* stack at -2 */ - LuaPushStringBuffer (tluajit->luastate, (const uint8_t *)GET_PKT_DATA(p), (size_t)GET_PKT_LEN(p)); /* stack at -3 */ - lua_settable(tluajit->luastate, -3); - } - if (tluajit->alproto == ALPROTO_HTTP) { - FLOWLOCK_RDLOCK(p->flow); - HtpState *htp_state = p->flow->alstate; - if (htp_state != NULL && htp_state->connp != NULL) { - htp_tx_t *tx = NULL; - uint64_t idx = AppLayerParserGetTransactionInspectId(p->flow->alparser, - STREAM_TOSERVER); - uint64_t total_txs= AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state); - for ( ; idx < total_txs; idx++) { - tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, idx); - if (tx == NULL) - continue; - - if ((tluajit->flags & DATATYPE_HTTP_REQUEST_LINE) && tx->request_line != NULL && - bstr_len(tx->request_line) > 0) { - lua_pushliteral(tluajit->luastate, "http.request_line"); /* stack at -2 */ - LuaPushStringBuffer(tluajit->luastate, - (const uint8_t *)bstr_ptr(tx->request_line), - bstr_len(tx->request_line)); - lua_settable(tluajit->luastate, -3); - } - } - } - FLOWLOCK_UNLOCK(p->flow); - } - - int retval = lua_pcall(tluajit->luastate, 1, 1, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(tluajit->luastate, -1)); - } - - /* process returns from script */ - if (lua_gettop(tluajit->luastate) > 0) { - - /* script returns a number (return 1 or return 0) */ - if (lua_type(tluajit->luastate, 1) == LUA_TNUMBER) { - double script_ret = lua_tonumber(tluajit->luastate, 1); - SCLogDebug("script_ret %f", script_ret); - lua_pop(tluajit->luastate, 1); - - if (script_ret == 1.0) - ret = 1; - - /* script returns a table */ - } else if (lua_type(tluajit->luastate, 1) == LUA_TTABLE) { - lua_pushnil(tluajit->luastate); - const char *k, *v; - while (lua_next(tluajit->luastate, -2)) { - v = lua_tostring(tluajit->luastate, -1); - lua_pop(tluajit->luastate, 1); - k = lua_tostring(tluajit->luastate, -1); - - if (!k || !v) - continue; - - SCLogDebug("k='%s', v='%s'", k, v); - - if (strcmp(k, "retval") == 0) { - if (atoi(v) == 1) - ret = 1; - } else { - /* set flow var? */ - } - } - - /* pop the table */ - lua_pop(tluajit->luastate, 1); - } - } - while (lua_gettop(tluajit->luastate) > 0) { - lua_pop(tluajit->luastate, 1); - } - - if (luajit->negated) { - if (ret == 1) - ret = 0; - else - ret = 1; - } - - SCReturnInt(ret); -} - -static int DetectLuaAppMatchCommon (ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, - const Signature *s, const SigMatchCtx *ctx) -{ - SCEnter(); - int ret = 0; - DetectLuaData *luajit = (DetectLuaData *)ctx; - if (luajit == NULL) - SCReturnInt(0); - - DetectLuaThreadData *tluajit = (DetectLuaThreadData *)DetectThreadCtxGetKeywordThreadCtx(det_ctx, luajit->thread_ctx_id); - if (tluajit == NULL) - SCReturnInt(0); - - /* setup extension data for use in lua c functions */ - LuaExtensionsMatchSetup(tluajit->luastate, luajit, det_ctx, - f, /* flow is locked */LUA_FLOW_LOCKED_BY_PARENT, - NULL, flags); - - if (tluajit->alproto != ALPROTO_UNKNOWN) { - int alproto = f->alproto; - if (tluajit->alproto != alproto) - SCReturnInt(0); - } - - lua_getglobal(tluajit->luastate, "match"); - lua_newtable(tluajit->luastate); /* stack at -1 */ - - if (tluajit->alproto == ALPROTO_HTTP) { - HtpState *htp_state = state; - if (htp_state != NULL && htp_state->connp != NULL) { - htp_tx_t *tx = NULL; - tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, det_ctx->tx_id); - if (tx != NULL) { - if ((tluajit->flags & DATATYPE_HTTP_REQUEST_LINE) && tx->request_line != NULL && - bstr_len(tx->request_line) > 0) { - lua_pushliteral(tluajit->luastate, "http.request_line"); /* stack at -2 */ - LuaPushStringBuffer(tluajit->luastate, - (const uint8_t *)bstr_ptr(tx->request_line), - bstr_len(tx->request_line)); - lua_settable(tluajit->luastate, -3); - } - } - } - } - - int retval = lua_pcall(tluajit->luastate, 1, 1, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(tluajit->luastate, -1)); - } - - /* process returns from script */ - if (lua_gettop(tluajit->luastate) > 0) { - - /* script returns a number (return 1 or return 0) */ - if (lua_type(tluajit->luastate, 1) == LUA_TNUMBER) { - double script_ret = lua_tonumber(tluajit->luastate, 1); - SCLogDebug("script_ret %f", script_ret); - lua_pop(tluajit->luastate, 1); - - if (script_ret == 1.0) - ret = 1; - - /* script returns a table */ - } else if (lua_type(tluajit->luastate, 1) == LUA_TTABLE) { - lua_pushnil(tluajit->luastate); - const char *k, *v; - while (lua_next(tluajit->luastate, -2)) { - v = lua_tostring(tluajit->luastate, -1); - lua_pop(tluajit->luastate, 1); - k = lua_tostring(tluajit->luastate, -1); - - if (!k || !v) - continue; - - SCLogDebug("k='%s', v='%s'", k, v); - - if (strcmp(k, "retval") == 0) { - if (atoi(v) == 1) - ret = 1; - } else { - /* set flow var? */ - } - } - - /* pop the table */ - lua_pop(tluajit->luastate, 1); - } - } - while (lua_gettop(tluajit->luastate) > 0) { - lua_pop(tluajit->luastate, 1); - } - - if (luajit->negated) { - if (ret == 1) - ret = 0; - else - ret = 1; - } - - SCReturnInt(ret); -} - -/** - * \brief match the specified lua script in AMATCH - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param s signature being inspected - * \param m sigmatch that we will cast into DetectLuaData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectLuaAppMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - return DetectLuaAppMatchCommon(t, det_ctx, f, flags, state, s, m->ctx); -} - -/** - * \brief match the specified lua script in a list with a tx - * - * \param t thread local vars - * \param det_ctx pattern matcher thread local data - * \param s signature being inspected - * \param m sigmatch that we will cast into DetectLuaData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectLuaAppTxMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, - void *state, void *txv, const Signature *s, - const SigMatchCtx *ctx) -{ - return DetectLuaAppMatchCommon(t, det_ctx, f, flags, state, s, ctx); -} - -#ifdef UNITTESTS -/* if this ptr is set the luajit setup functions will use this buffer as the - * lua script instead of calling luaL_loadfile on the filename supplied. */ -static const char *ut_script = NULL; -#endif - -static void *DetectLuaThreadInit(void *data) -{ - int status; - DetectLuaData *luajit = (DetectLuaData *)data; - BUG_ON(luajit == NULL); - - DetectLuaThreadData *t = SCMalloc(sizeof(DetectLuaThreadData)); - if (unlikely(t == NULL)) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't alloc ctx memory"); - return NULL; - } - memset(t, 0x00, sizeof(DetectLuaThreadData)); - - t->alproto = luajit->alproto; - t->flags = luajit->flags; - - t->luastate = DetectLuaGetState(); - if (t->luastate == NULL) { - SCLogError(SC_ERR_LUA_ERROR, "luastate pool depleted"); - goto error; - } - - luaL_openlibs(t->luastate); - - LuaRegisterExtensions(t->luastate); - - lua_pushinteger(t->luastate, (lua_Integer)(luajit->sid)); - lua_setglobal(t->luastate, "SCRuleSid"); - lua_pushinteger(t->luastate, (lua_Integer)(luajit->rev)); - lua_setglobal(t->luastate, "SCRuleRev"); - lua_pushinteger(t->luastate, (lua_Integer)(luajit->gid)); - lua_setglobal(t->luastate, "SCRuleGid"); - - /* hackish, needed to allow unittests to pass buffers as scripts instead of files */ -#ifdef UNITTESTS - if (ut_script != NULL) { - status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest"); - if (status) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't load file: %s", lua_tostring(t->luastate, -1)); - goto error; - } - } else { -#endif - status = luaL_loadfile(t->luastate, luajit->filename); - if (status) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't load file: %s", lua_tostring(t->luastate, -1)); - goto error; - } -#ifdef UNITTESTS - } -#endif - - /* prime the script (or something) */ - if (lua_pcall(t->luastate, 0, 0, 0) != 0) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't prime file: %s", lua_tostring(t->luastate, -1)); - goto error; - } - - return (void *)t; - -error: - if (t->luastate != NULL) - DetectLuaReturnState(t->luastate); - SCFree(t); - return NULL; -} - -static void DetectLuaThreadFree(void *ctx) -{ - if (ctx != NULL) { - DetectLuaThreadData *t = (DetectLuaThreadData *)ctx; - if (t->luastate != NULL) - DetectLuaReturnState(t->luastate); - SCFree(t); - } -} - -/** - * \brief Parse the luajit keyword - * - * \param str Pointer to the user provided option - * - * \retval luajit pointer to DetectLuaData on success - * \retval NULL on failure - */ -static DetectLuaData *DetectLuaParse (const DetectEngineCtx *de_ctx, char *str) -{ - DetectLuaData *luajit = NULL; - - /* We have a correct luajit option */ - luajit = SCMalloc(sizeof(DetectLuaData)); - if (unlikely(luajit == NULL)) - goto error; - - memset(luajit, 0x00, sizeof(DetectLuaData)); - - if (strlen(str) && str[0] == '!') { - luajit->negated = 1; - str++; - } - - /* get full filename */ - luajit->filename = DetectLoadCompleteSigPath(de_ctx, str); - if (luajit->filename == NULL) { - goto error; - } - - return luajit; - -error: - if (luajit != NULL) - DetectLuaFree(luajit); - return NULL; -} - -static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld) -{ - int status; - - lua_State *luastate = luaL_newstate(); - if (luastate == NULL) - return -1; - luaL_openlibs(luastate); - - /* hackish, needed to allow unittests to pass buffers as scripts instead of files */ -#ifdef UNITTESTS - if (ut_script != NULL) { - status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest"); - if (status) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't load file: %s", lua_tostring(luastate, -1)); - goto error; - } - } else { -#endif - status = luaL_loadfile(luastate, ld->filename); - if (status) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't load file: %s", lua_tostring(luastate, -1)); - goto error; - } -#ifdef UNITTESTS - } -#endif - - /* prime the script (or something) */ - if (lua_pcall(luastate, 0, 0, 0) != 0) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't prime file: %s", lua_tostring(luastate, -1)); - goto error; - } - - lua_getglobal(luastate, "init"); - if (lua_type(luastate, -1) != LUA_TFUNCTION) { - SCLogError(SC_ERR_LUA_ERROR, "no init function in script"); - goto error; - } - - lua_newtable(luastate); /* stack at -1 */ - if (lua_gettop(luastate) == 0 || lua_type(luastate, 2) != LUA_TTABLE) { - SCLogError(SC_ERR_LUA_ERROR, "no table setup"); - goto error; - } - - lua_pushliteral(luastate, "script_api_ver"); /* stack at -2 */ - lua_pushnumber (luastate, 1); /* stack at -3 */ - lua_settable(luastate, -3); - - if (lua_pcall(luastate, 1, 1, 0) != 0) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't run script 'init' function: %s", lua_tostring(luastate, -1)); - goto error; - } - - /* process returns from script */ - if (lua_gettop(luastate) == 0) { - SCLogError(SC_ERR_LUA_ERROR, "init function in script should return table, nothing returned"); - goto error; - } - if (lua_type(luastate, 1) != LUA_TTABLE) { - SCLogError(SC_ERR_LUA_ERROR, "init function in script should return table, returned is not table"); - goto error; - } - - lua_pushnil(luastate); - const char *k, *v; - while (lua_next(luastate, -2)) { - k = lua_tostring(luastate, -2); - if (k == NULL) - continue; - - /* handle flowvar separately as it has a table as value */ - if (strcmp(k, "flowvar") == 0) { - if (lua_istable(luastate, -1)) { - lua_pushnil(luastate); - while (lua_next(luastate, -2) != 0) { - /* value at -1, key is at -2 which we ignore */ - const char *value = lua_tostring(luastate, -1); - SCLogDebug("value %s", value); - /* removes 'value'; keeps 'key' for next iteration */ - lua_pop(luastate, 1); - - if (ld->flowvars == DETECT_LUAJIT_MAX_FLOWVARS) { - SCLogError(SC_ERR_LUA_ERROR, "too many flowvars registered"); - goto error; - } - - uint16_t idx = VariableNameGetIdx(de_ctx, (char *)value, VAR_TYPE_FLOW_VAR); - ld->flowvar[ld->flowvars++] = idx; - SCLogDebug("script uses flowvar %u with script id %u", idx, ld->flowvars - 1); - } - } - lua_pop(luastate, 1); - continue; - } else if (strcmp(k, "flowint") == 0) { - if (lua_istable(luastate, -1)) { - lua_pushnil(luastate); - while (lua_next(luastate, -2) != 0) { - /* value at -1, key is at -2 which we ignore */ - const char *value = lua_tostring(luastate, -1); - SCLogDebug("value %s", value); - /* removes 'value'; keeps 'key' for next iteration */ - lua_pop(luastate, 1); - - if (ld->flowints == DETECT_LUAJIT_MAX_FLOWINTS) { - SCLogError(SC_ERR_LUA_ERROR, "too many flowints registered"); - goto error; - } - - uint16_t idx = VariableNameGetIdx(de_ctx, (char *)value, VAR_TYPE_FLOW_INT); - ld->flowint[ld->flowints++] = idx; - SCLogDebug("script uses flowint %u with script id %u", idx, ld->flowints - 1); - } - } - lua_pop(luastate, 1); - continue; - } - - v = lua_tostring(luastate, -1); - lua_pop(luastate, 1); - if (v == NULL) - continue; - - SCLogDebug("k='%s', v='%s'", k, v); - if (strcmp(k, "packet") == 0 && strcmp(v, "true") == 0) { - ld->flags |= DATATYPE_PACKET; - } else if (strcmp(k, "payload") == 0 && strcmp(v, "true") == 0) { - ld->flags |= DATATYPE_PAYLOAD; - } else if (strcmp(k, "stream") == 0 && strcmp(v, "true") == 0) { - ld->flags |= DATATYPE_STREAM; - - ld->buffername = SCStrdup("stream"); - if (ld->buffername == NULL) { - SCLogError(SC_ERR_LUA_ERROR, "alloc error"); - goto error; - } - - } else if (strncmp(k, "http", 4) == 0 && strcmp(v, "true") == 0) { - if (ld->alproto != ALPROTO_UNKNOWN && ld->alproto != ALPROTO_HTTP) { - SCLogError(SC_ERR_LUA_ERROR, "can just inspect script against one app layer proto like HTTP at a time"); - goto error; - } - if (ld->flags != 0) { - SCLogError(SC_ERR_LUA_ERROR, "when inspecting HTTP buffers only a single buffer can be inspected"); - goto error; - } - - /* http types */ - ld->alproto = ALPROTO_HTTP; - - if (strcmp(k, "http.uri") == 0) - ld->flags |= DATATYPE_HTTP_URI; - - else if (strcmp(k, "http.uri.raw") == 0) - ld->flags |= DATATYPE_HTTP_URI_RAW; - - else if (strcmp(k, "http.request_line") == 0) - ld->flags |= DATATYPE_HTTP_REQUEST_LINE; - - else if (strcmp(k, "http.request_headers") == 0) - ld->flags |= DATATYPE_HTTP_REQUEST_HEADERS; - - else if (strcmp(k, "http.request_headers.raw") == 0) - ld->flags |= DATATYPE_HTTP_REQUEST_HEADERS_RAW; - - else if (strcmp(k, "http.request_cookie") == 0) - ld->flags |= DATATYPE_HTTP_REQUEST_COOKIE; - - else if (strcmp(k, "http.request_user_agent") == 0) - ld->flags |= DATATYPE_HTTP_REQUEST_UA; - - else if (strcmp(k, "http.request_body") == 0) - ld->flags |= DATATYPE_HTTP_REQUEST_BODY; - - else if (strcmp(k, "http.response_body") == 0) - ld->flags |= DATATYPE_HTTP_RESPONSE_BODY; - - else if (strcmp(k, "http.response_cookie") == 0) - ld->flags |= DATATYPE_HTTP_RESPONSE_COOKIE; - - else if (strcmp(k, "http.response_headers") == 0) - ld->flags |= DATATYPE_HTTP_RESPONSE_HEADERS; - - else if (strcmp(k, "http.response_headers.raw") == 0) - ld->flags |= DATATYPE_HTTP_RESPONSE_HEADERS_RAW; - - else { - SCLogError(SC_ERR_LUA_ERROR, "unsupported http data type %s", k); - goto error; - } - - ld->buffername = SCStrdup(k); - if (ld->buffername == NULL) { - SCLogError(SC_ERR_LUA_ERROR, "alloc error"); - goto error; - } - } else if (strncmp(k, "dns", 3) == 0 && strcmp(v, "true") == 0) { - - ld->alproto = ALPROTO_DNS; - - if (strcmp(k, "dns.rrname") == 0) - ld->flags |= DATATYPE_DNS_RRNAME; - else if (strcmp(k, "dns.request") == 0) - ld->flags |= DATATYPE_DNS_REQUEST; - else if (strcmp(k, "dns.response") == 0) - ld->flags |= DATATYPE_DNS_RESPONSE; - - else { - SCLogError(SC_ERR_LUA_ERROR, "unsupported dns data type %s", k); - goto error; - } - ld->buffername = SCStrdup(k); - if (ld->buffername == NULL) { - SCLogError(SC_ERR_LUA_ERROR, "alloc error"); - goto error; - } - } else if (strncmp(k, "tls", 3) == 0 && strcmp(v, "true") == 0) { - - ld->alproto = ALPROTO_TLS; - - ld->flags |= DATATYPE_TLS; - - } else if (strncmp(k, "ssh", 3) == 0 && strcmp(v, "true") == 0) { - - ld->alproto = ALPROTO_SSH; - - ld->flags |= DATATYPE_SSH; - - } else { - SCLogError(SC_ERR_LUA_ERROR, "unsupported data type %s", k); - goto error; - } - } - - /* pop the table */ - lua_pop(luastate, 1); - lua_close(luastate); - return 0; -error: - lua_close(luastate); - return -1; -} - -/** - * \brief this function is used to parse luajit options - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param str pointer to the user provided "luajit" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectLuaData *luajit = NULL; - SigMatch *sm = NULL; - - luajit = DetectLuaParse(de_ctx, str); - if (luajit == NULL) - goto error; - - if (DetectLuaSetupPrime(de_ctx, luajit) == -1) { - goto error; - } - - luajit->thread_ctx_id = DetectRegisterThreadCtxFuncs(de_ctx, "luajit", - DetectLuaThreadInit, (void *)luajit, - DetectLuaThreadFree, 0); - if (luajit->thread_ctx_id == -1) - goto error; - - if (luajit->alproto != ALPROTO_UNKNOWN) { - if (s->alproto != ALPROTO_UNKNOWN && luajit->alproto != s->alproto) { - goto error; - } - s->alproto = luajit->alproto; - } - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_LUA; - sm->ctx = (SigMatchCtx *)luajit; - - if (luajit->alproto == ALPROTO_UNKNOWN) { - if (luajit->flags & DATATYPE_STREAM) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_PMATCH); - else - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - } else if (luajit->alproto == ALPROTO_HTTP) { - if (luajit->flags & DATATYPE_HTTP_RESPONSE_BODY) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_FILEDATA); - else if (luajit->flags & DATATYPE_HTTP_REQUEST_BODY) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HCBDMATCH); - else if (luajit->flags & DATATYPE_HTTP_URI) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_UMATCH); - else if (luajit->flags & DATATYPE_HTTP_URI_RAW) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRUDMATCH); - else if (luajit->flags & DATATYPE_HTTP_REQUEST_COOKIE) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HCDMATCH); - else if (luajit->flags & DATATYPE_HTTP_REQUEST_UA) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HUADMATCH); - else if (luajit->flags & (DATATYPE_HTTP_REQUEST_HEADERS|DATATYPE_HTTP_RESPONSE_HEADERS)) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HHDMATCH); - else if (luajit->flags & (DATATYPE_HTTP_REQUEST_HEADERS_RAW|DATATYPE_HTTP_RESPONSE_HEADERS_RAW)) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRHDMATCH); - else if (luajit->flags & DATATYPE_HTTP_RESPONSE_COOKIE) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HCDMATCH); - else - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRLMATCH); - } else if (luajit->alproto == ALPROTO_DNS) { - if (luajit->flags & DATATYPE_DNS_RRNAME) { - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DNSQUERYNAME_MATCH); - } else if (luajit->flags & DATATYPE_DNS_REQUEST) { - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DNSREQUEST_MATCH); - } else if (luajit->flags & DATATYPE_DNS_RESPONSE) { - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_DNSRESPONSE_MATCH); - } - } else if (luajit->alproto == ALPROTO_TLS) { - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - } else if (luajit->alproto == ALPROTO_SSH) { - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - } else { - SCLogError(SC_ERR_LUA_ERROR, "luajit can't be used with protocol %s", - AppLayerGetProtoName(luajit->alproto)); - goto error; - } - - de_ctx->detect_luajit_instances++; - return 0; - -error: - if (luajit != NULL) - DetectLuaFree(luajit); - if (sm != NULL) - SCFree(sm); - return -1; -} - -/** \brief post-sig parse function to set the sid,rev,gid into the - * ctx, as this isn't available yet during parsing. - */ -void DetectLuaPostSetup(Signature *s) -{ - int i; - SigMatch *sm; - - for (i = 0; i < DETECT_SM_LIST_MAX; i++) { - for (sm = s->sm_lists[i]; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_LUA) - continue; - - DetectLuaData *ld = (DetectLuaData *)sm->ctx; - ld->sid = s->id; - ld->rev = s->rev; - ld->gid = s->gid; - } - } -} - -/** - * \brief this function will free memory associated with DetectLuaData - * - * \param luajit pointer to DetectLuaData - */ -static void DetectLuaFree(void *ptr) -{ - if (ptr != NULL) { - DetectLuaData *luajit = (DetectLuaData *)ptr; - - if (luajit->buffername) - SCFree(luajit->buffername); - if (luajit->filename) - SCFree(luajit->filename); - - SCFree(luajit); - } -} - -#ifdef UNITTESTS -/** \test http buffer */ -static int LuaMatchTest01(void) -{ - const char script[] = - "function init (args)\n" - " local needs = {}\n" - " needs[\"http.request_headers\"] = tostring(true)\n" - " needs[\"flowvar\"] = {\"cnt\"}\n" - " return needs\n" - "end\n" - "\n" - "function match(args)\n" - " a = ScFlowvarGet(0)\n" - " if a then\n" - " a = tostring(tonumber(a)+1)\n" - " print (a)\n" - " ScFlowvarSet(0, a, #a)\n" - " else\n" - " a = tostring(1)\n" - " print (a)\n" - " ScFlowvarSet(0, a, #a)\n" - " end\n" - " \n" - " print (\"pre check: \" .. (a))\n" - " if tonumber(a) == 2 then\n" - " print \"match\"\n" - " return 1\n" - " end\n" - " return 0\n" - "end\n" - "return 0\n"; - char sig[] = "alert http any any -> any any (flow:to_server; luajit:unittest; sid:1;)"; - int result = 0; - uint8_t httpbuf1[] = - "POST / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n\r\n"; - uint8_t httpbuf2[] = - "POST / HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - Flow f; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - ut_script = script; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, sig); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SCLogDebug("inspecting p1"); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match on p1 but should have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect for p2 */ - SCLogDebug("inspecting p2"); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, 1); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_str.value_len != 1) { - printf("%u != %u: ", fv->data.fv_str.value_len, 1); - goto end; - } - - if (memcmp(fv->data.fv_str.value, "2", 1) != 0) { - PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len); - - printf("buffer mismatch: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** \test payload buffer */ -static int LuaMatchTest02(void) -{ - const char script[] = - "function init (args)\n" - " local needs = {}\n" - " needs[\"payload\"] = tostring(true)\n" - " needs[\"flowvar\"] = {\"cnt\"}\n" - " return needs\n" - "end\n" - "\n" - "function match(args)\n" - " a = ScFlowvarGet(0)\n" - " if a then\n" - " a = tostring(tonumber(a)+1)\n" - " print (a)\n" - " ScFlowvarSet(0, a, #a)\n" - " else\n" - " a = tostring(1)\n" - " print (a)\n" - " ScFlowvarSet(0, a, #a)\n" - " end\n" - " \n" - " print (\"pre check: \" .. (a))\n" - " if tonumber(a) == 2 then\n" - " print \"match\"\n" - " return 1\n" - " end\n" - " return 0\n" - "end\n" - "return 0\n"; - char sig[] = "alert tcp any any -> any any (flow:to_server; luajit:unittest; sid:1;)"; - int result = 0; - uint8_t httpbuf1[] = - "POST / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n\r\n"; - uint8_t httpbuf2[] = - "POST / HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - Flow f; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - - ut_script = script; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP); - p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, sig); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match on p1 but should have: "); - goto end; - } - - /* do detect for p2 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, 1); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_str.value_len != 1) { - printf("%u != %u: ", fv->data.fv_str.value_len, 1); - goto end; - } - - if (memcmp(fv->data.fv_str.value, "2", 1) != 0) { - PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len); - - printf("buffer mismatch: "); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** \test packet buffer */ -static int LuaMatchTest03(void) -{ - const char script[] = - "function init (args)\n" - " local needs = {}\n" - " needs[\"packet\"] = tostring(true)\n" - " needs[\"flowvar\"] = {\"cnt\"}\n" - " return needs\n" - "end\n" - "\n" - "function match(args)\n" - " a = ScFlowvarGet(0)\n" - " if a then\n" - " a = tostring(tonumber(a)+1)\n" - " print (a)\n" - " ScFlowvarSet(0, a, #a)\n" - " else\n" - " a = tostring(1)\n" - " print (a)\n" - " ScFlowvarSet(0, a, #a)\n" - " end\n" - " \n" - " print (\"pre check: \" .. (a))\n" - " if tonumber(a) == 2 then\n" - " print \"match\"\n" - " return 1\n" - " end\n" - " return 0\n" - "end\n" - "return 0\n"; - char sig[] = "alert tcp any any -> any any (flow:to_server; luajit:unittest; sid:1;)"; - int result = 0; - uint8_t httpbuf1[] = - "POST / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n\r\n"; - uint8_t httpbuf2[] = - "POST / HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - Flow f; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - - ut_script = script; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP); - p2 = UTHBuildPacket(httpbuf2, httplen2, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, sig); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match on p1 but should have: "); - goto end; - } - - /* do detect for p2 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, 1); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_str.value_len != 1) { - printf("%u != %u: ", fv->data.fv_str.value_len, 1); - goto end; - } - - if (memcmp(fv->data.fv_str.value, "2", 1) != 0) { - PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len); - - printf("buffer mismatch: "); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** \test http buffer, flowints */ -static int LuaMatchTest04(void) -{ - const char script[] = - "function init (args)\n" - " local needs = {}\n" - " needs[\"http.request_headers\"] = tostring(true)\n" - " needs[\"flowint\"] = {\"cnt\"}\n" - " return needs\n" - "end\n" - "\n" - "function match(args)\n" - " print \"inspecting\"" - " a = ScFlowintGet(0)\n" - " if a then\n" - " ScFlowintSet(0, a + 1)\n" - " else\n" - " ScFlowintSet(0, 1)\n" - " end\n" - " \n" - " a = ScFlowintGet(0)\n" - " if a == 2 then\n" - " print \"match\"\n" - " return 1\n" - " end\n" - " return 0\n" - "end\n" - "return 0\n"; - char sig[] = "alert http any any -> any any (flow:to_server; luajit:unittest; sid:1;)"; - int result = 0; - uint8_t httpbuf1[] = - "POST / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n\r\n"; - uint8_t httpbuf2[] = - "POST / HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - Flow f; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - ut_script = script; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, sig); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SCLogInfo("p1"); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect for p2 */ - SCLogInfo("p2"); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, 1); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_int.value != 2) { - printf("%u != %u: ", fv->data.fv_int.value, 2); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** \test http buffer, flowints */ -static int LuaMatchTest05(void) -{ - const char script[] = - "function init (args)\n" - " local needs = {}\n" - " needs[\"http.request_headers\"] = tostring(true)\n" - " needs[\"flowint\"] = {\"cnt\"}\n" - " return needs\n" - "end\n" - "\n" - "function match(args)\n" - " print \"inspecting\"" - " a = ScFlowintIncr(0)\n" - " if a == 2 then\n" - " print \"match\"\n" - " return 1\n" - " end\n" - " return 0\n" - "end\n" - "return 0\n"; - char sig[] = "alert http any any -> any any (flow:to_server; luajit:unittest; sid:1;)"; - int result = 0; - uint8_t httpbuf1[] = - "POST / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n\r\n"; - uint8_t httpbuf2[] = - "POST / HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - Flow f; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - ut_script = script; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, sig); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SCLogInfo("p1"); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect for p2 */ - SCLogInfo("p2"); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, 1); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_int.value != 2) { - printf("%u != %u: ", fv->data.fv_int.value, 2); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -/** \test http buffer, flowints */ -static int LuaMatchTest06(void) -{ - const char script[] = - "function init (args)\n" - " local needs = {}\n" - " needs[\"http.request_headers\"] = tostring(true)\n" - " needs[\"flowint\"] = {\"cnt\"}\n" - " return needs\n" - "end\n" - "\n" - "function match(args)\n" - " print \"inspecting\"" - " a = ScFlowintGet(0)\n" - " if a == nil then\n" - " print \"new var set to 2\"" - " ScFlowintSet(0, 2)\n" - " end\n" - " a = ScFlowintDecr(0)\n" - " if a == 0 then\n" - " print \"match\"\n" - " return 1\n" - " end\n" - " return 0\n" - "end\n" - "return 0\n"; - char sig[] = "alert http any any -> any any (flow:to_server; luajit:unittest; sid:1;)"; - int result = 0; - uint8_t httpbuf1[] = - "POST / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n\r\n"; - uint8_t httpbuf2[] = - "POST / HTTP/1.1\r\n" - "Host: www.openinfosecfoundation.org\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - Flow f; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - ut_script = script; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, sig); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SCLogInfo("p1"); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but should not have: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - /* do detect for p2 */ - SCLogInfo("p2"); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't match on p2 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, 1); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_int.value != 0) { - printf("%u != %u: ", fv->data.fv_int.value, 0); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -#endif - -void DetectLuaRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("LuaMatchTest01", LuaMatchTest01, 1); - UtRegisterTest("LuaMatchTest02", LuaMatchTest02, 1); - UtRegisterTest("LuaMatchTest03", LuaMatchTest03, 1); - UtRegisterTest("LuaMatchTest04", LuaMatchTest04, 1); - UtRegisterTest("LuaMatchTest05", LuaMatchTest05, 1); - UtRegisterTest("LuaMatchTest06", LuaMatchTest06, 1); -#endif -} - -#endif /* HAVE_LUAJIT */ diff --git a/framework/src/suricata/src/detect-lua.h b/framework/src/suricata/src/detect-lua.h deleted file mode 100644 index f7dc5de4..00000000 --- a/framework/src/suricata/src/detect-lua.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_LUAJIT_H__ -#define __DETECT_LUAJIT_H__ - -#ifdef HAVE_LUA - -#include -#include -#include - -typedef struct DetectLuaThreadData { - lua_State *luastate; - uint32_t flags; - int alproto; -} DetectLuaThreadData; - -#define DETECT_LUAJIT_MAX_FLOWVARS 15 -#define DETECT_LUAJIT_MAX_FLOWINTS 15 - -typedef struct DetectLuaData { - int thread_ctx_id; - int negated; - char *filename; - uint32_t flags; - int alproto; - char *buffername; /* buffer name in case of a single buffer */ - uint16_t flowint[DETECT_LUAJIT_MAX_FLOWINTS]; - uint16_t flowints; - uint16_t flowvar[DETECT_LUAJIT_MAX_FLOWVARS]; - uint16_t flowvars; - uint32_t sid; - uint32_t rev; - uint32_t gid; -} DetectLuaData; - -#endif /* HAVE_LUA */ - -/* prototypes */ -void DetectLuaRegister (void); -int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, - uint8_t *buffer, uint32_t buffer_len, uint32_t offset, - Flow *f, int flow_lock); - -#ifdef HAVE_LUAJIT -int DetectLuajitSetupStatesPool(int num, int reloads); -#endif /* HAVE_LUAJIT */ - -void DetectLuaPostSetup(Signature *s); - -#endif /* __DETECT_FILELUAJIT_H__ */ diff --git a/framework/src/suricata/src/detect-mark.c b/framework/src/suricata/src/detect-mark.c deleted file mode 100644 index 695a7b41..00000000 --- a/framework/src/suricata/src/detect-mark.c +++ /dev/null @@ -1,353 +0,0 @@ -/* Copyright (C) 2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - * Implements the mark keyword. Based on detect-gid - * by Breno Silva - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "detect.h" -#include "flow-var.h" -#include "decode-events.h" - -#include "detect-mark.h" -#include "detect-parse.h" - -#include "util-unittest.h" -#include "util-debug.h" - -#define PARSE_REGEX "([0x]*[0-9a-f]+)/([0x]*[0-9a-f]+)" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -static int DetectMarkSetup (DetectEngineCtx *, Signature *, char *); -int DetectMarkPacket(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx); -void DetectMarkDataFree(void *ptr); - -/** - * \brief Registration function for nfq_set_mark: keyword - */ - -void DetectMarkRegister (void) -{ - sigmatch_table[DETECT_MARK].name = "nfq_set_mark"; - sigmatch_table[DETECT_MARK].Match = DetectMarkPacket; - sigmatch_table[DETECT_MARK].Setup = DetectMarkSetup; - sigmatch_table[DETECT_MARK].Free = DetectMarkDataFree; - sigmatch_table[DETECT_MARK].RegisterTests = MarkRegisterTests; - - const char *eb; - int opts = 0; - int eo; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - -error: - return; - -} - -#ifdef NFQ -/** - * \internal - * \brief This function is used to parse mark options passed via mark: keyword - * - * \param rawstr Pointer to the user provided mark options - * - * \retval 0 on success - * \retval < 0 on failure - */ -static void * DetectMarkParse (char *rawstr) -{ - int ret = 0, res = 0; -#define MAX_SUBSTRINGS 30 - int ov[MAX_SUBSTRINGS]; - const char *str_ptr = NULL; - char *ptr = NULL; - char *endptr = NULL; - uint32_t mark; - uint32_t mask; - DetectMarkData *data; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr); - return NULL; - } - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - return NULL; - } - - ptr = (char *)str_ptr; - - if (ptr == NULL) - return NULL; - - errno = 0; - mark = strtoul(ptr, &endptr, 0); - if (errno == ERANGE) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range"); - SCFree(ptr); - return NULL; - } /* If there is no numeric value in the given string then strtoull(), makes - endptr equals to ptr and return 0 as result */ - else if (endptr == ptr && mark == 0) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "No numeric value"); - SCFree(ptr); - return NULL; - } else if (endptr == ptr) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Invalid numeric value"); - SCFree(ptr); - return NULL; - } - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - return NULL; - } - - SCFree(ptr); - ptr = (char *)str_ptr; - - if (ptr == NULL) { - data = SCMalloc(sizeof(DetectMarkData)); - if (unlikely(data == NULL)) { - return NULL; - } - data->mark = mark; - data->mask = 0xffff; - return data; - } - - errno = 0; - mask = strtoul(ptr, &endptr, 0); - if (errno == ERANGE) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range"); - SCFree(ptr); - return NULL; - } /* If there is no numeric value in the given string then strtoull(), makes - endptr equals to ptr and return 0 as result */ - else if (endptr == ptr && mask == 0) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "No numeric value"); - SCFree(ptr); - return NULL; - } - else if (endptr == ptr) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Invalid numeric value"); - SCFree(ptr); - return NULL; - } - - SCLogDebug("Rule will set mark 0x%x with mask 0x%x", mark, mask); - SCFree(ptr); - - data = SCMalloc(sizeof(DetectMarkData)); - if (unlikely(data == NULL)) { - return NULL; - } - data->mark = mark; - data->mask = mask; - return data; -} - -#endif /* NFQ */ - -/** - * \internal - * \brief this function is used to add the parsed mark into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param rawstr pointer to the user provided mark options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectMarkSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ -#ifdef NFQ - DetectMarkData *data = NULL; - SigMatch *sm = NULL; - - data = DetectMarkParse(rawstr); - - if (data == NULL) { - return -1; - } else { - sm = SigMatchAlloc(); - if (sm == NULL) { - DetectMarkDataFree(data); - return -1; - } - - sm->type = DETECT_MARK; - sm->ctx = (SigMatchCtx *)data; - - /* Append it to the list of tags */ - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_TMATCH); - return 0; - } -#else - return 0; -#endif -} - -void DetectMarkDataFree(void *ptr) -{ - DetectMarkData *data = (DetectMarkData *)ptr; - SCFree(data); -} - - -int DetectMarkPacket(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ -#ifdef NFQ - const DetectMarkData *nf_data = (const DetectMarkData *)ctx; - if (nf_data->mask) { - p->nfq_v.mark = (nf_data->mark & nf_data->mask) - | (p->nfq_v.mark & ~(nf_data->mask)); - p->flags |= PKT_MARK_MODIFIED; - } -#endif - return 1; -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#if defined UNITTESTS && defined NFQ -/** - * \test MarkTestParse01 is a test for a valid mark value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int MarkTestParse01 (void) -{ - DetectMarkData *data; - - data = DetectMarkParse("1/1"); - - if (data == NULL) { - return 0; - } - - DetectMarkDataFree(data); - return 1; -} - -/** - * \test MarkTestParse02 is a test for an invalid mark value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int MarkTestParse02 (void) -{ - DetectMarkData *data; - - data = DetectMarkParse("4"); - - if (data == NULL) { - return 0; - } - - DetectMarkDataFree(data); - return 1; -} - -/** - * \test MarkTestParse03 is a test for a valid mark value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int MarkTestParse03 (void) -{ - DetectMarkData *data; - - data = DetectMarkParse("0x10/0xff"); - - if (data == NULL) { - return 0; - } - - DetectMarkDataFree(data); - return 1; -} - -/** - * \test MarkTestParse04 is a test for a invalid mark value - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int MarkTestParse04 (void) -{ - DetectMarkData *data; - - data = DetectMarkParse("0x1g/0xff"); - - if (data == NULL) { - return 0; - } - - DetectMarkDataFree(data); - return 1; -} - - - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for Mark - */ -void MarkRegisterTests(void) -{ -#if defined UNITTESTS && defined NFQ - UtRegisterTest("MarkTestParse01", MarkTestParse01, 1); - UtRegisterTest("MarkTestParse02", MarkTestParse02, 0); - UtRegisterTest("MarkTestParse03", MarkTestParse03, 1); - UtRegisterTest("MarkTestParse04", MarkTestParse04, 0); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-mark.h b/framework/src/suricata/src/detect-mark.h deleted file mode 100644 index 3c3b8593..00000000 --- a/framework/src/suricata/src/detect-mark.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - * Based on detect-mark.h by Breno Silva - * - * Implements the nfq_set_mark keyword - */ - -#ifndef __DETECT_MARK_H__ -#define __DETECT_MARK_H__ - -#include "decode.h" -#include "detect.h" - -/** - * \struct DetectMarkData_ - * DetectMarkData_ is used to store nfq_set_mark: input value - */ - -/** - * \typedef DetectMarkData - * A typedef for DetectMarkData_ - */ - -typedef struct DetectMarkData_ { - uint32_t mark; /**< Rule mark */ - uint32_t mask; /**< Rule mask */ -} DetectMarkData; - -/** - * Registration function for nfq_set_mark: keyword - */ - -void DetectMarkRegister (void); - -/** - * This function registers unit tests for Mark - */ - -void MarkRegisterTests(void); - -#endif /*__DETECT_MARK_H__ */ diff --git a/framework/src/suricata/src/detect-metadata.c b/framework/src/suricata/src/detect-metadata.c deleted file mode 100644 index 3055ec78..00000000 --- a/framework/src/suricata/src/detect-metadata.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements metadata keyword support - * - * \todo Do we need to do anything more this is used in snort host attribute table - * It is also used for rule managment. - */ - -#include "suricata-common.h" -#include "detect.h" - -static int DetectMetadataSetup (DetectEngineCtx *, Signature *, char *); - -void DetectMetadataRegister (void) -{ - sigmatch_table[DETECT_METADATA].name = "metadata"; - sigmatch_table[DETECT_METADATA].desc = "ignored by suricata"; - sigmatch_table[DETECT_METADATA].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Meta-settings#Metadata"; - sigmatch_table[DETECT_METADATA].Match = NULL; - sigmatch_table[DETECT_METADATA].Setup = DetectMetadataSetup; - sigmatch_table[DETECT_METADATA].Free = NULL; - sigmatch_table[DETECT_METADATA].RegisterTests = NULL; -} - -static int DetectMetadataSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - return 0; -} - diff --git a/framework/src/suricata/src/detect-metadata.h b/framework/src/suricata/src/detect-metadata.h deleted file mode 100644 index bcb4c01c..00000000 --- a/framework/src/suricata/src/detect-metadata.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_METADATA_H__ -#define __DETECT_METADATA_H__ - -/* prototypes */ -void DetectMetadataRegister (void); - -#endif /* __DETECT_METADATA_H__ */ - diff --git a/framework/src/suricata/src/detect-modbus.c b/framework/src/suricata/src/detect-modbus.c deleted file mode 100644 index d1e4ec50..00000000 --- a/framework/src/suricata/src/detect-modbus.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - * Copyright (C) 2014 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author David DIALLO - * - * Implements the Modbus function and access keywords - * You can specify a: - * - concrete function like Modbus: - * function 8, subfunction 4 (diagnostic: Force Listen Only Mode) - * - data (in primary table) register access (r/w) like Modbus: - * access read coils, address 1000 (.i.e Read coils: at address 1000) - * - write data value at specific address Modbus: - * access write, address 1500<>2000, value >2000 (Write multiple coils/register: - * at address between 1500 and 2000 value greater than 2000) - */ - -#include "suricata-common.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-modbus.h" - -#include "util-debug.h" - -#include "app-layer-modbus.h" - -#include "stream-tcp.h" - -/** - * \brief Regex for parsing the Modbus function string - */ -#define PARSE_REGEX_FUNCTION "^\\s*\"?\\s*function\\s*(!?[A-z0-9]+)(,\\s*subfunction\\s+(\\d+))?\\s*\"?\\s*$" -static pcre *function_parse_regex; -static pcre_extra *function_parse_regex_study; - -/** - * \brief Regex for parsing the Modbus access string - */ -#define PARSE_REGEX_ACCESS "^\\s*\"?\\s*access\\s*(read|write)\\s*(discretes|coils|input|holding)?(,\\s*address\\s+([<>]?\\d+)(<>\\d+)?(,\\s*value\\s+([<>]?\\d+)(<>\\d+)?)?)?\\s*\"?\\s*$" -static pcre *access_parse_regex; -static pcre_extra *access_parse_regex_study; - -#define MAX_SUBSTRINGS 30 - -void DetectModbusRegisterTests(void); - -/** \internal - * - * \brief this function will free memory associated with DetectModbus - * - * \param ptr pointer to DetectModbus - */ -static void DetectModbusFree(void *ptr) { - SCEnter(); - DetectModbus *modbus = (DetectModbus *) ptr; - - if(modbus) { - if (modbus->subfunction) - SCFree(modbus->subfunction); - - if (modbus->address) - SCFree(modbus->address); - - if (modbus->data) - SCFree(modbus->data); - - SCFree(modbus); - } -} - -/** \internal - * - * \brief This function is used to parse Modbus parameters in access mode - * - * \param str Pointer to the user provided id option - * - * \retval Pointer to DetectModbusData on success or NULL on failure - */ -static DetectModbus *DetectModbusAccessParse(char *str) -{ - SCEnter(); - DetectModbus *modbus = NULL; - - char arg[MAX_SUBSTRINGS]; - int ov[MAX_SUBSTRINGS], ret, res; - - ret = pcre_exec(access_parse_regex, access_parse_regex_study, str, strlen(str), 0, 0, ov, MAX_SUBSTRINGS); - - if (ret < 1) - goto error; - - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 1, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct Modbus option */ - modbus = (DetectModbus *) SCCalloc(1, sizeof(DetectModbus)); - if (unlikely(modbus == NULL)) - goto error; - - if (strcmp(arg, "read") == 0) - modbus->type = MODBUS_TYP_READ; - else if (strcmp(arg, "write") == 0) - modbus->type = MODBUS_TYP_WRITE; - else - goto error; - - if (ret > 2) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 2, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (*arg != '\0') { - if (strcmp(arg, "discretes") == 0) { - if (modbus->type == MODBUS_TYP_WRITE) - /* Discrete access is only read access. */ - goto error; - - modbus->type |= MODBUS_TYP_DISCRETES; - } - else if (strcmp(arg, "coils") == 0) { - modbus->type |= MODBUS_TYP_COILS; - } - else if (strcmp(arg, "input") == 0) { - if (modbus->type == MODBUS_TYP_WRITE) { - /* Input access is only read access. */ - goto error; - } - - modbus->type |= MODBUS_TYP_INPUT; - } - else if (strcmp(arg, "holding") == 0) { - modbus->type |= MODBUS_TYP_HOLDING; - } - else - goto error; - } - - if (ret > 4) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 4, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct address option */ - modbus->address = (DetectModbusValue *) SCCalloc(1, sizeof(DetectModbusValue)); - if (unlikely(modbus->address == NULL)) - goto error; - - if (arg[0] == '>') { - modbus->address->min = atoi((const char*) (arg+1)); - modbus->address->mode = DETECT_MODBUS_GT; - } else if (arg[0] == '<') { - modbus->address->min = atoi((const char*) (arg+1)); - modbus->address->mode = DETECT_MODBUS_LT; - } else { - modbus->address->min = atoi((const char*) arg); - } - SCLogDebug("and min/equal address %d", modbus->address->min); - - if (ret > 5) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 5, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (*arg != '\0') { - modbus->address->max = atoi((const char*) (arg+2)); - modbus->address->mode = DETECT_MODBUS_RA; - SCLogDebug("and max address %d", modbus->address->max); - } - - if (ret > 7) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 7, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (modbus->address->mode != DETECT_MODBUS_EQ) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords (address range and value)."); - goto error; - } - - /* We have a correct address option */ - modbus->data = (DetectModbusValue *) SCCalloc(1, sizeof(DetectModbusValue)); - if (unlikely(modbus->data == NULL)) - goto error; - - if (arg[0] == '>') { - modbus->data->min = atoi((const char*) (arg+1)); - modbus->data->mode = DETECT_MODBUS_GT; - } else if (arg[0] == '<') { - modbus->data->min = atoi((const char*) (arg+1)); - modbus->data->mode = DETECT_MODBUS_LT; - } else { - modbus->data->min = atoi((const char*) arg); - } - SCLogDebug("and min/equal value %d", modbus->data->min); - - if (ret > 8) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 8, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (*arg != '\0') { - modbus->data->max = atoi((const char*) (arg+2)); - modbus->data->mode = DETECT_MODBUS_RA; - SCLogDebug("and max value %d", modbus->data->max); - } - } - } - } - } - } - - SCReturnPtr(modbus, "DetectModbusAccess"); - -error: - if (modbus != NULL) - DetectModbusFree(modbus); - - SCReturnPtr(NULL, "DetectModbus"); -} - -/** \internal - * - * \brief This function is used to parse Modbus parameters in function mode - * - * \param str Pointer to the user provided id option - * - * \retval id_d pointer to DetectModbusData on success - * \retval NULL on failure - */ -static DetectModbus *DetectModbusFunctionParse(char *str) -{ - SCEnter(); - DetectModbus *modbus = NULL; - - char arg[MAX_SUBSTRINGS], *ptr = arg; - int ov[MAX_SUBSTRINGS], res, ret; - - ret = pcre_exec(function_parse_regex, function_parse_regex_study, str, strlen(str), 0, 0, ov, MAX_SUBSTRINGS); - - if (ret < 1) - goto error; - - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 1, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct Modbus function option */ - modbus = (DetectModbus *) SCCalloc(1, sizeof(DetectModbus)); - if (unlikely(modbus == NULL)) - goto error; - - if (isdigit((unsigned char)ptr[0])) { - modbus->function = atoi((const char*) ptr); - SCLogDebug("will look for modbus function %d", modbus->function); - - if (ret > 2) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 3, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct address option */ - modbus->subfunction =(uint16_t *) SCCalloc(1, sizeof(uint16_t)); - if (modbus->subfunction == NULL) - goto error; - - *(modbus->subfunction) = atoi((const char*) arg); - SCLogDebug("and subfunction %d", *(modbus->subfunction)); - } - } else { - uint8_t neg = 0; - - if (ptr[0] == '!') { - neg = 1; - ptr++; - } - - if (strcmp("assigned", ptr) == 0) - modbus->category = MODBUS_CAT_PUBLIC_ASSIGNED; - else if (strcmp("unassigned", ptr) == 0) - modbus->category = MODBUS_CAT_PUBLIC_UNASSIGNED; - else if (strcmp("public", ptr) == 0) - modbus->category = MODBUS_CAT_PUBLIC_ASSIGNED | MODBUS_CAT_PUBLIC_UNASSIGNED; - else if (strcmp("user", ptr) == 0) - modbus->category = MODBUS_CAT_USER_DEFINED; - else if (strcmp("reserved", ptr) == 0) - modbus->category = MODBUS_CAT_RESERVED; - else if (strcmp("all", ptr) == 0) - modbus->category = MODBUS_CAT_ALL; - - if (neg) - modbus->category = ~modbus->category; - SCLogDebug("will look for modbus category function %d", modbus->category); - } - - SCReturnPtr(modbus, "DetectModbusFunction"); - -error: - if (modbus != NULL) - DetectModbusFree(modbus); - - SCReturnPtr(NULL, "DetectModbus"); -} - -/** \internal - * - * \brief this function is used to add the parsed "id" option into the current signature - * - * \param de_ctx Pointer to the Detection Engine Context - * \param s Pointer to the Current Signature - * \param str Pointer to the user provided "id" option - * - * \retval 0 on Success or -1 on Failure - */ -static int DetectModbusSetup(DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - SCEnter(); - DetectModbus *modbus = NULL; - SigMatch *sm = NULL; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_MODBUS) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - if ((modbus = DetectModbusFunctionParse(str)) == NULL) { - if ((modbus = DetectModbusAccessParse(str)) == NULL) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid modbus option"); - goto error; - } - } - - /* Okay so far so good, lets get this into a SigMatch and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_AL_MODBUS; - sm->ctx = (void *) modbus; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MODBUS_MATCH); - s->alproto = ALPROTO_MODBUS; - - SCReturnInt(0); - -error: - if (modbus != NULL) - DetectModbusFree(modbus); - if (sm != NULL) - SCFree(sm); - SCReturnInt(-1); -} - -/** - * \brief Registration function for Modbus keyword - */ -void DetectModbusRegister(void) -{ - SCEnter(); - sigmatch_table[DETECT_AL_MODBUS].name = "modbus"; - sigmatch_table[DETECT_AL_MODBUS].Match = NULL; - sigmatch_table[DETECT_AL_MODBUS].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_MODBUS].alproto = ALPROTO_MODBUS; - sigmatch_table[DETECT_AL_MODBUS].Setup = DetectModbusSetup; - sigmatch_table[DETECT_AL_MODBUS].Free = DetectModbusFree; - sigmatch_table[DETECT_AL_MODBUS].RegisterTests = DetectModbusRegisterTests; - - const char *eb; - int eo, opts = 0; - - SCLogDebug("registering modbus rule option"); - - /* Function PARSE_REGEX */ - function_parse_regex = pcre_compile(PARSE_REGEX_FUNCTION, opts, &eb, &eo, NULL); - if (function_parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX_FUNCTION, eo, eb); - goto error; - } - - function_parse_regex_study = pcre_study(function_parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - /* Access PARSE_REGEX */ - access_parse_regex = pcre_compile(PARSE_REGEX_ACCESS, opts, &eb, &eo, NULL); - if (access_parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX_ACCESS, eo, eb); - goto error; - } - - access_parse_regex_study = pcre_study(access_parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - -error: - SCReturn; -} - -#ifdef UNITTESTS /* UNITTESTS */ -#include "detect-engine.h" - -#include "util-unittest.h" - -/** \test Signature containing a function. */ -static int DetectModbusTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus function\"; " - "modbus: function 1; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->function != 1) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 1, modbus->function); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a function and a subfunction. */ -static int DetectModbusTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus function and subfunction\"; " - "modbus: function 8, subfunction 4; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if ((modbus->function != 8) || (*modbus->subfunction != 4)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 1, modbus->function); - printf("expected subfunction %" PRIu8 ", got %" PRIu16 ": ", 4, *modbus->subfunction); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a function category. */ -static int DetectModbusTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.function\"; " - "modbus: function reserved; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->category != MODBUS_CAT_RESERVED) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", MODBUS_CAT_RESERVED, modbus->category); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a negative function category. */ -static int DetectModbusTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - uint8_t category = ~MODBUS_CAT_PUBLIC_ASSIGNED; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus function\"; " - "modbus: function !assigned; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->category != category) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", ~MODBUS_CAT_PUBLIC_ASSIGNED, modbus->category); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a access type. */ -static int DetectModbusTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access read; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->type != MODBUS_TYP_READ) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", MODBUS_TYP_READ, modbus->type); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a access function. */ -static int DetectModbusTest06(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - uint8_t type = (MODBUS_TYP_READ | MODBUS_TYP_DISCRETES); - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access read discretes; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->type != type) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", type, modbus->type); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a read access at an address. */ -static int DetectModbusTest07(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - DetectModbusMode mode = DETECT_MODBUS_EQ; - - uint8_t type = MODBUS_TYP_READ; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access read, address 1000; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if ((modbus->type != type) || - ((*modbus->address).mode != mode) || - ((*modbus->address).min != 1000)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", type, modbus->type); - printf("expected mode %" PRIu8 ", got %" PRIu16 ": ", mode, (*modbus->address).mode); - printf("expected address %" PRIu8 ", got %" PRIu16 ": ", 1000, (*modbus->address).min); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a write access at a range of address. */ -static int DetectModbusTest08(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - DetectModbusMode mode = DETECT_MODBUS_GT; - - uint8_t type = (MODBUS_TYP_WRITE | MODBUS_TYP_COILS); - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access write coils, address >500; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if ((modbus->type != type) || - ((*modbus->address).mode != mode) || - ((*modbus->address).min != 500)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", type, modbus->type); - printf("expected mode %" PRIu8 ", got %" PRIu16 ": ", mode, (*modbus->address).mode); - printf("expected address %" PRIu8 ", got %" PRIu16 ": ", 500, (*modbus->address).min); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a write access at a address a range of value. */ -static int DetectModbusTest09(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - DetectModbusMode addressMode = DETECT_MODBUS_EQ; - DetectModbusMode valueMode = DETECT_MODBUS_RA; - - uint8_t type = (MODBUS_TYP_WRITE | MODBUS_TYP_HOLDING); - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access write holding, address 100, value 500<>1000; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if ((modbus->type != type) || - ((*modbus->address).mode != addressMode) || - ((*modbus->address).min != 100) || - ((*modbus->data).mode != valueMode) || - ((*modbus->data).min != 500) || - ((*modbus->data).max != 1000)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", type, modbus->type); - printf("expected address mode %" PRIu8 ", got %" PRIu16 ": ", addressMode, (*modbus->address).mode); - printf("expected address %" PRIu8 ", got %" PRIu16 ": ", 500, (*modbus->address).min); - printf("expected value mode %" PRIu8 ", got %" PRIu16 ": ", valueMode, (*modbus->data).mode); - printf("expected min value %" PRIu8 ", got %" PRIu16 ": ", 500, (*modbus->data).min); - printf("expected max value %" PRIu8 ", got %" PRIu16 ": ", 1000, (*modbus->data).max); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectModbus - */ -void DetectModbusRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectModbusTest01 - Testing function", DetectModbusTest01, 1); - UtRegisterTest("DetectModbusTest02 - Testing function and subfunction", DetectModbusTest02, 1); - UtRegisterTest("DetectModbusTest03 - Testing category function", DetectModbusTest03, 1); - UtRegisterTest("DetectModbusTest04 - Testing category function in negative", DetectModbusTest04, 1); - UtRegisterTest("DetectModbusTest05 - Testing access type", DetectModbusTest05, 1); - UtRegisterTest("DetectModbusTest06 - Testing access function", DetectModbusTest06, 1); - UtRegisterTest("DetectModbusTest07 - Testing access at address", DetectModbusTest07, 1); - UtRegisterTest("DetectModbusTest08 - Testing a range of address", DetectModbusTest08, 1); - UtRegisterTest("DetectModbusTest09 - Testing write a range of value", DetectModbusTest09, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-modbus.h b/framework/src/suricata/src/detect-modbus.h deleted file mode 100644 index 408fb7af..00000000 --- a/framework/src/suricata/src/detect-modbus.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2014 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author David DIALLO - */ - -#ifndef __DETECT_MODBUS_H__ -#define __DETECT_MODBUS_H__ - -#include "app-layer-modbus.h" - -typedef enum { - DETECT_MODBUS_EQ = 0, /** < EQual operator */ - DETECT_MODBUS_LT, /** < "Less Than" operator */ - DETECT_MODBUS_GT, /** < "Greater Than" operator */ - DETECT_MODBUS_RA, /** < RAnge operator */ -} DetectModbusMode; - -typedef struct DetectModbusValue_ { - uint16_t min; /** < Modbus minimum [range] or equal value to match */ - uint16_t max; /** < Modbus maximum value [range] to match */ - DetectModbusMode mode; /** < Modbus operator used in the address/data signature */ -} DetectModbusValue; - -typedef struct DetectModbus_ { - uint8_t category; /** < Modbus function code category to match */ - uint8_t function; /** < Modbus function code to match */ - uint16_t *subfunction; /** < Modbus subfunction to match */ - uint8_t type; /** < Modbus access type to match */ - DetectModbusValue *address; /** < Modbus address to match */ - DetectModbusValue *data; /** < Modbus data to match */ -} DetectModbus; - -/* prototypes */ -void DetectModbusRegister(void); - -#endif /* __DETECT_MODBUS_H__ */ diff --git a/framework/src/suricata/src/detect-msg.c b/framework/src/suricata/src/detect-msg.c deleted file mode 100644 index e8b87529..00000000 --- a/framework/src/suricata/src/detect-msg.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the msg keyword - */ - -#include "suricata-common.h" -#include "detect.h" -#include "util-classification-config.h" -#include "util-debug.h" -#include "util-unittest.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -static int DetectMsgSetup (DetectEngineCtx *, Signature *, char *); -void DetectMsgRegisterTests(void); - -void DetectMsgRegister (void) -{ - sigmatch_table[DETECT_MSG].name = "msg"; - sigmatch_table[DETECT_MSG].desc = "information about the rule and the possible alert"; - sigmatch_table[DETECT_MSG].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Meta-settings#msg-message"; - sigmatch_table[DETECT_MSG].Match = NULL; - sigmatch_table[DETECT_MSG].Setup = DetectMsgSetup; - sigmatch_table[DETECT_MSG].Free = NULL; - sigmatch_table[DETECT_MSG].RegisterTests = DetectMsgRegisterTests; -} - -static int DetectMsgSetup (DetectEngineCtx *de_ctx, Signature *s, char *msgstr) -{ - char *str = NULL; - uint16_t len; - - if (strlen(msgstr) == 0) - goto error; - - /* strip "'s */ - if (msgstr[0] == '\"' && msgstr[strlen(msgstr)-1] == '\"') { - str = SCStrdup(msgstr+1); - if (unlikely(str == NULL)) - goto error; - str[strlen(msgstr)-2] = '\0'; - } else if (msgstr[1] == '\"' && msgstr[strlen(msgstr)-1] == '\"') { - /* XXX do this parsing in a better way */ - str = SCStrdup(msgstr+2); - if (unlikely(str == NULL)) - goto error; - str[strlen(msgstr)-3] = '\0'; - //printf("DetectMsgSetup: format hack applied: \'%s\'\n", str); - } else { - SCLogError(SC_ERR_INVALID_VALUE, "format error \'%s\'", msgstr); - goto error; - } - - len = strlen(str); - if (len == 0) - goto error; - - char converted = 0; - - { - uint16_t i, x; - uint8_t escape = 0; - - /* it doesn't matter if we need to escape or not we remove the extra "\" to mimic snort */ - for (i = 0, x = 0; i < len; i++) { - //printf("str[%02u]: %c\n", i, str[i]); - if(!escape && str[i] == '\\') { - escape = 1; - } else if (escape) { - if (str[i] != ':' && - str[i] != ';' && - str[i] != '\\' && - str[i] != '\"') - { - SCLogDebug("character \"%c\" does not need to be escaped but is" ,str[i]); - } - escape = 0; - converted = 1; - - str[x] = str[i]; - x++; - }else{ - str[x] = str[i]; - x++; - } - - } -#if 0 //def DEBUG - if (SCLogDebugEnabled()) { - for (i = 0; i < x; i++) { - printf("%c", str[i]); - } - printf("\n"); - } -#endif - - if (converted) { - len = x; - str[len] = '\0'; - } - } - - s->msg = SCMalloc(len + 1); - if (s->msg == NULL) - goto error; - - strlcpy(s->msg, str, len + 1); - - SCFree(str); - return 0; - -error: - SCFree(str); - return -1; -} - -/* -------------------------------------Unittests-----------------------------*/ - -#ifdef UNITTESTS -static int DetectMsgParseTest01(void) -{ - int result = 0; - Signature *sig = NULL; - char *teststringparsed = "flow stateless to_server"; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - sig = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"flow stateless to_server\"; flow:stateless,to_server; content:\"flowstatelesscheck\"; classtype:bad-unknown; sid: 40000002; rev: 1;)"); - if(sig == NULL) - goto end; - - if (strcmp(sig->msg, teststringparsed) != 0) { - printf("got \"%s\", expected: \"%s\": ", sig->msg, teststringparsed); - goto end; - } - - result = 1; -end: - if (sig != NULL) - SigFree(sig); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectMsgParseTest02(void) -{ - int result = 0; - Signature *sig = NULL; - char *teststringparsed = "msg escape tests wxy'\"\\;:"; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"msg escape tests \\w\\x\\y\\'\\\"\\\\;\\:\"; flow:to_server,established; content:\"blah\"; uricontent:\"/blah/\"; sid: 100;)"); - if(sig == NULL) - goto end; - - if (strcmp(sig->msg, teststringparsed) != 0) { - printf("got \"%s\", expected: \"%s\": ",sig->msg, teststringparsed); - goto end; - } - - result = 1; -end: - if (sig != NULL) - SigFree(sig); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectMsg - */ -void DetectMsgRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectMsgParseTest01", DetectMsgParseTest01, 1); - UtRegisterTest("DetectMsgParseTest02", DetectMsgParseTest02, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-msg.h b/framework/src/suricata/src/detect-msg.h deleted file mode 100644 index a21d5110..00000000 --- a/framework/src/suricata/src/detect-msg.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_MSG_H__ -#define __DETECT_MSG_H__ - -/* prototypes */ -void DetectMsgRegister (void); - -#endif /* __DETECT_MSG_H__ */ - diff --git a/framework/src/suricata/src/detect-noalert.c b/framework/src/suricata/src/detect-noalert.c deleted file mode 100644 index b4f69af4..00000000 --- a/framework/src/suricata/src/detect-noalert.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the noalert keyword - */ - -#include "suricata-common.h" -#include "detect.h" -#include "util-debug.h" - -static int DetectNoalertSetup (DetectEngineCtx *, Signature *, char *); - -void DetectNoalertRegister (void) -{ - sigmatch_table[DETECT_NOALERT].name = "noalert"; - sigmatch_table[DETECT_NOALERT].Match = NULL; - sigmatch_table[DETECT_NOALERT].Setup = DetectNoalertSetup; - sigmatch_table[DETECT_NOALERT].Free = NULL; - sigmatch_table[DETECT_NOALERT].RegisterTests = NULL; - - sigmatch_table[DETECT_NOALERT].flags |= SIGMATCH_NOOPT; -} - -static int DetectNoalertSetup (DetectEngineCtx *de_ctx, Signature *s, char *nullstr) -{ - if (nullstr != NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "nocase has no value"); - return -1; - } - - s->flags |= SIG_FLAG_NOALERT; - return 0; -} - diff --git a/framework/src/suricata/src/detect-noalert.h b/framework/src/suricata/src/detect-noalert.h deleted file mode 100644 index abe39efc..00000000 --- a/framework/src/suricata/src/detect-noalert.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_NOALERT_H__ -#define __DETECT_NOALERT_H__ - -/* prototypes */ -void DetectNoalertRegister (void); - -#endif /* __DETECT_NOALERT_H__ */ - diff --git a/framework/src/suricata/src/detect-nocase.c b/framework/src/suricata/src/detect-nocase.c deleted file mode 100644 index 9968e3c4..00000000 --- a/framework/src/suricata/src/detect-nocase.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the nocase keyword - */ - -#include "suricata-common.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "flow-var.h" - -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-pcre.h" -#include "detect-http-client-body.h" -#include "detect-http-cookie.h" -#include "detect-http-header.h" -#include "detect-http-method.h" -#include "detect-http-uri.h" - -#include "util-debug.h" - -static int DetectNocaseSetup (DetectEngineCtx *, Signature *, char *); - -void DetectNocaseRegister(void) -{ - sigmatch_table[DETECT_NOCASE].name = "nocase"; - sigmatch_table[DETECT_NOCASE].desc = "modify content match to be case insensitive"; - sigmatch_table[DETECT_NOCASE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#Nocase"; - sigmatch_table[DETECT_NOCASE].Match = NULL; - sigmatch_table[DETECT_NOCASE].Setup = DetectNocaseSetup; - sigmatch_table[DETECT_NOCASE].Free = NULL; - sigmatch_table[DETECT_NOCASE].RegisterTests = NULL; - - sigmatch_table[DETECT_NOCASE].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_NOCASE].flags |= SIGMATCH_PAYLOAD; -} - -/** - * \internal - * \brief Apply the nocase keyword to the last pattern match, either content or uricontent - * \param det_ctx detection engine ctx - * \param s signature - * \param nullstr should be null - * \retval 0 ok - * \retval -1 failure - */ -static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nullstr) -{ - SCEnter(); - - SigMatch *pm = NULL; - int ret = -1; - - if (nullstr != NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "nocase has value"); - goto end; - } - - /* retrive the sm to apply the depth against */ - if (s->list != DETECT_SM_LIST_NOTSET) { - pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[s->list]); - } else { - pm = SigMatchGetLastSMFromLists(s, 28, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - } - if (pm == NULL) { - SCLogError(SC_ERR_NOCASE_MISSING_PATTERN, "nocase needs " - "preceding content, uricontent option, http_client_body, " - "http_server_body, http_header option, http_raw_header option, " - "http_method option, http_cookie, http_raw_uri, " - "http_stat_msg, http_stat_code, http_user_agent or " - "file_data/dce_stub_data sticky buffer options"); - goto end; - } - - - /* verify other conditions. */ - DetectContentData *cd = (DetectContentData *)pm->ctx;; - - if (cd->flags & DETECT_CONTENT_NOCASE) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple nocase modifiers with the same content"); - goto end; - } - cd->flags |= DETECT_CONTENT_NOCASE; - /* Recreate the context with nocase chars */ - BoyerMooreCtxToNocase(cd->bm_ctx, cd->content, cd->content_len); - - ret = 0; - end: - SCReturnInt(ret); -} diff --git a/framework/src/suricata/src/detect-nocase.h b/framework/src/suricata/src/detect-nocase.h deleted file mode 100644 index 4ba6723e..00000000 --- a/framework/src/suricata/src/detect-nocase.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_NOCASE_H__ -#define __DETECT_NOCASE_H__ - -/* prototypes */ -void DetectNocaseRegister (void); - -#endif /* __DETECT_NOCASE_H__ */ - diff --git a/framework/src/suricata/src/detect-offset.c b/framework/src/suricata/src/detect-offset.c deleted file mode 100644 index 65372ec0..00000000 --- a/framework/src/suricata/src/detect-offset.c +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * Implements the offset keyword. - */ - -#include "suricata-common.h" - -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-byte-extract.h" -#include "app-layer.h" - -#include "flow-var.h" - -#include "util-debug.h" - -static int DetectOffsetSetup(DetectEngineCtx *, Signature *, char *); - -void DetectOffsetRegister (void) -{ - sigmatch_table[DETECT_OFFSET].name = "offset"; - sigmatch_table[DETECT_OFFSET].desc = "designate from which byte in the payload will be checked to find a match"; - sigmatch_table[DETECT_OFFSET].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#Offset"; - sigmatch_table[DETECT_OFFSET].Match = NULL; - sigmatch_table[DETECT_OFFSET].Setup = DetectOffsetSetup; - sigmatch_table[DETECT_OFFSET].Free = NULL; - sigmatch_table[DETECT_OFFSET].RegisterTests = NULL; - - sigmatch_table[DETECT_OFFSET].flags |= SIGMATCH_PAYLOAD; -} - -int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr) -{ - char *str = offsetstr; - char dubbed = 0; - SigMatch *pm = NULL; - int ret = -1; - - /* strip "'s */ - if (offsetstr[0] == '\"' && offsetstr[strlen(offsetstr)-1] == '\"') { - str = SCStrdup(offsetstr+1); - if (unlikely(str == NULL)) - goto end; - str[strlen(offsetstr) - 2] = '\0'; - dubbed = 1; - } - - /* retrive the sm to apply the depth against */ - if (s->list != DETECT_SM_LIST_NOTSET) { - pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[s->list]); - } else { - pm = SigMatchGetLastSMFromLists(s, 28, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - } - if (pm == NULL) { - SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs " - "preceding content, uricontent option, http_client_body, " - "http_server_body, http_header option, http_raw_header option, " - "http_method option, http_cookie, http_raw_uri, " - "http_stat_msg, http_stat_code, http_user_agent or " - "file_data/dce_stub_data sticky buffer options"); - goto end; - } - - - /* verify other conditions */ - DetectContentData *cd = (DetectContentData *)pm->ctx; - - if (cd->flags & DETECT_CONTENT_OFFSET) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple offsets for the same content. "); - goto end; - } - if ((cd->flags & DETECT_CONTENT_WITHIN) || (cd->flags & DETECT_CONTENT_DISTANCE)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a relative " - "keyword like within/distance with a absolute " - "relative keyword like depth/offset for the same " - "content." ); - goto end; - } - if (cd->flags & DETECT_CONTENT_NEGATED && cd->flags & DETECT_CONTENT_FAST_PATTERN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " - "negated keyword set along with a fast_pattern"); - goto end; - } - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " - "keyword set along with a fast_pattern:only;"); - goto end; - } - if (str[0] != '-' && isalpha((unsigned char)str[0])) { - SigMatch *bed_sm = - DetectByteExtractRetrieveSMVar(str, s); - if (bed_sm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "unknown byte_extract var " - "seen in offset - %s\n", str); - goto end; - } - cd->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id; - cd->flags |= DETECT_CONTENT_OFFSET_BE; - } else { - cd->offset = (uint32_t)atoi(str); - if (cd->depth != 0) { - if (cd->depth < cd->content_len) { - SCLogDebug("depth increased to %"PRIu32" to match pattern len", - cd->content_len); - cd->depth = cd->content_len; - } - /* Updating the depth as is relative to the offset */ - cd->depth += cd->offset; - } - } - cd->flags |= DETECT_CONTENT_OFFSET; - - ret = 0; - end: - if (dubbed) - SCFree(str); - return ret; -} - diff --git a/framework/src/suricata/src/detect-offset.h b/framework/src/suricata/src/detect-offset.h deleted file mode 100644 index 76befe17..00000000 --- a/framework/src/suricata/src/detect-offset.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_OFFSET_H__ -#define __DETECT_OFFSET_H__ - -/* prototypes */ -void DetectOffsetRegister (void); - -#endif /* __DETECT_OFFSET_H__ */ - diff --git a/framework/src/suricata/src/detect-parse.c b/framework/src/suricata/src/detect-parse.c deleted file mode 100644 index f91e7591..00000000 --- a/framework/src/suricata/src/detect-parse.c +++ /dev/null @@ -1,3439 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * signature parser - */ - -#include "suricata-common.h" -#include "debug.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-address.h" -#include "detect-engine-port.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "detect-content.h" -#include "detect-pcre.h" -#include "detect-uricontent.h" -#include "detect-reference.h" -#include "detect-ipproto.h" -#include "detect-flow.h" -#include "detect-app-layer-protocol.h" -#include "detect-engine-apt-event.h" -#include "detect-lua.h" -#include "detect-app-layer-event.h" - -#include "pkt-var.h" -#include "host.h" -#include "util-profiling.h" -#include "decode.h" - -#include "flow.h" - -#include "util-rule-vars.h" -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" - -#include "util-classification-config.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" -#include "string.h" -#include "detect-parse.h" -#include "detect-engine-iponly.h" -#include "app-layer-detect-proto.h" -#include "app-layer.h" - -extern int sc_set_caps; - -static pcre *config_pcre = NULL; -static pcre *option_pcre = NULL; -static pcre_extra *config_pcre_extra = NULL; -static pcre_extra *option_pcre_extra = NULL; - -static uint32_t dbg_srcportany_cnt = 0; -static uint32_t dbg_dstportany_cnt = 0; - -/** - * \brief We use this as data to the hash table DetectEngineCtx->dup_sig_hash_table. - */ -typedef struct SigDuplWrapper_ { - /* the signature we want to wrap */ - Signature *s; - /* the signature right before the above signatue in the det_ctx->sig_list */ - Signature *s_prev; -} SigDuplWrapper; - -#define CONFIG_PARTS 8 - -#define CONFIG_ACTION 0 -#define CONFIG_PROTO 1 -#define CONFIG_SRC 2 -#define CONFIG_SP 3 -#define CONFIG_DIREC 4 -#define CONFIG_DST 5 -#define CONFIG_DP 6 -#define CONFIG_OPTS 7 - -/* if enclosed in [], spaces are allowed */ -#define CONFIG_PCRE_SRCDST "(" \ - "[\\[\\]A-z0-9\\.\\:_\\$\\!\\-,\\/]+" \ - "|" \ - "\\[[\\[\\]A-z0-9\\.\\:_\\$\\!\\-,\\/\\s]+\\]"\ - ")" - -/* if enclosed in [], spaces are allowed */ -#define CONFIG_PCRE_PORT "(" \ - "[\\:A-z0-9_\\$\\!,]+"\ - "|"\ - "\\[[\\:A-z0-9_\\$\\!,\\s]+\\]"\ - ")" - -/* format: action space(s) protocol spaces(s) src space(s) sp spaces(s) dir spaces(s) dst spaces(s) dp spaces(s) options */ -#define CONFIG_PCRE "^([A-z]+)\\s+([A-z0-9\\-]+)\\s+" \ - CONFIG_PCRE_SRCDST \ - "\\s+"\ - CONFIG_PCRE_PORT \ - "\\s+(-\\>|\\<\\>|\\<\\-)\\s+" \ - CONFIG_PCRE_SRCDST \ - "\\s+" \ - CONFIG_PCRE_PORT \ - "(?:\\s+\\((.*)?(?:\\s*)\\))?(?:(?:\\s*)\\n)?\\s*$" -#define OPTION_PARTS 3 -#define OPTION_PCRE "^\\s*([A-z_0-9-\\.]+)(?:\\s*\\:\\s*(.*)(?list != DETECT_SM_LIST_NOTSET) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "\"%s\" keyword seen " - "with a sticky buffer still set. Reset sticky buffer " - "with pkt_data before using the modifier.", - sigmatch_table[sm_type].name); - goto end; - } - /* for now let's hardcode it as http */ - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != alproto) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting " - "alprotos set"); - goto end; - } - - sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); - if (sm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "\"%s\" keyword " - "found inside the rule without a content context. " - "Please use a \"content\" keyword before using the " - "\"%s\" keyword", sigmatch_table[sm_type].name, - sigmatch_table[sm_type].name); - goto end; - } - DetectContentData *cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "%s rule can not " - "be used with the rawbytes rule keyword", - sigmatch_table[sm_type].name); - goto end; - } - if (cd->flags & (DETECT_CONTENT_WITHIN | DETECT_CONTENT_DISTANCE)) { - SigMatch *pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, sm->prev, - DETECT_PCRE, sm->prev); - if (pm != NULL) { - if (pm->type == DETECT_CONTENT) { - DetectContentData *tmp_cd = (DetectContentData *)pm->ctx; - tmp_cd->flags &= ~DETECT_CONTENT_RELATIVE_NEXT; - } else { - DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; - tmp_pd->flags &= ~DETECT_PCRE_RELATIVE_NEXT; - } - } - - pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, s->sm_lists_tail[sm_list], - DETECT_PCRE, s->sm_lists_tail[sm_list]); - if (pm != NULL) { - if (pm->type == DETECT_CONTENT) { - DetectContentData *tmp_cd = (DetectContentData *)pm->ctx; - tmp_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - } else { - DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx; - tmp_pd->flags |= DETECT_PCRE_RELATIVE_NEXT; - } - } - } - if (CustomCallback != NULL) - CustomCallback(s); - s->alproto = alproto; - s->flags |= SIG_FLAG_APPLAYER; - - /* transfer the sm from the pmatch list to hcbdmatch list */ - SigMatchTransferSigMatchAcrossLists(sm, - &s->sm_lists[DETECT_SM_LIST_PMATCH], - &s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - &s->sm_lists[sm_list], - &s->sm_lists_tail[sm_list]); - - ret = 0; - end: - return ret; -} - -uint32_t DbgGetSrcPortAnyCnt(void) -{ - return dbg_srcportany_cnt; -} - -uint32_t DbgGetDstPortAnyCnt(void) -{ - return dbg_dstportany_cnt; -} - -SigMatch *SigMatchAlloc(void) -{ - SigMatch *sm = SCMalloc(sizeof(SigMatch)); - if (unlikely(sm == NULL)) - return NULL; - - memset(sm, 0, sizeof(SigMatch)); - sm->prev = NULL; - sm->next = NULL; - return sm; -} - -/** \brief free a SigMatch - * \param sm SigMatch to free. - */ -void SigMatchFree(SigMatch *sm) -{ - if (sm == NULL) - return; - - /** free the ctx, for that we call the Free func */ - if (sm->ctx != NULL) { - if (sigmatch_table[sm->type].Free != NULL) { - sigmatch_table[sm->type].Free(sm->ctx); - } - } - SCFree(sm); -} - -/* Get the detection module by name */ -SigTableElmt *SigTableGet(char *name) -{ - SigTableElmt *st = NULL; - int i = 0; - - for (i = 0; i < DETECT_TBLSIZE; i++) { - st = &sigmatch_table[i]; - - if (st->name != NULL) { - if (strcasecmp(name,st->name) == 0) - return st; - if (st->alias != NULL && strcasecmp(name,st->alias) == 0) - return st; - } - } - - return NULL; -} - -/** - * \brief Append a SigMatch to the list type. - * - * \param s Signature. - * \param new The sig match to append. - * \param list The list to append to. - */ -void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list) -{ - if (s->sm_lists[list] == NULL) { - s->sm_lists[list] = new; - s->sm_lists_tail[list] = new; - new->next = NULL; - new->prev = NULL; - } else { - SigMatch *cur = s->sm_lists_tail[list]; - cur->next = new; - new->prev = cur; - new->next = NULL; - s->sm_lists_tail[list] = new; - } - - new->idx = s->sm_cnt; - s->sm_cnt++; -} - -void SigMatchRemoveSMFromList(Signature *s, SigMatch *sm, int sm_list) -{ - if (sm == s->sm_lists[sm_list]) { - s->sm_lists[sm_list] = sm->next; - } - if (sm == s->sm_lists_tail[sm_list]) { - s->sm_lists_tail[sm_list] = sm->prev; - } - if (sm->prev != NULL) - sm->prev->next = sm->next; - if (sm->next != NULL) - sm->next->prev = sm->prev; - - return; -} - -/** - * \brief Returns a pointer to the last SigMatch instance of a particular type - * in a Signature of the payload list. - * - * \param s Pointer to the tail of the sigmatch list - * \param type SigMatch type which has to be searched for in the Signature. - * - * \retval match Pointer to the last SigMatch instance of type 'type'. - */ -static inline SigMatch *SigMatchGetLastSM(SigMatch *sm, uint8_t type) -{ - while (sm != NULL) { - if (sm->type == type) { - return sm; - } - sm = sm->prev; - } - - return NULL; -} - -/** - * \brief Returns the sm with the largest index (added latest) from all the lists. - * - * \retval Pointer to Last sm. - */ -SigMatch *SigMatchGetLastSMFromLists(Signature *s, int args, ...) -{ - if (args == 0 || args % 2 != 0) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "You need to send an even no of args " - "(non zero as well) to this function, since we need a " - "SigMatch list for every SigMatch type(send a map of sm_type " - "and sm_list) sent"); - /* as this is a bug we should abort to ease debugging */ - BUG_ON(1); - } - - SigMatch *sm_last = NULL; - SigMatch *sm_new; - int i; - - va_list ap; - va_start(ap, args); - - for (i = 0; i < args; i += 2) { - int sm_type = va_arg(ap, int); - SigMatch *sm_list = va_arg(ap, SigMatch *); - sm_new = SigMatchGetLastSM(sm_list, sm_type); - if (sm_new == NULL) - continue; - if (sm_last == NULL || sm_new->idx > sm_last->idx) - sm_last = sm_new; - } - - va_end(ap); - - return sm_last; -} - -void SigMatchTransferSigMatchAcrossLists(SigMatch *sm, - SigMatch **src_sm_list, SigMatch **src_sm_list_tail, - SigMatch **dst_sm_list, SigMatch **dst_sm_list_tail) -{ - /* we won't do any checks for args */ - - if (sm->prev != NULL) - sm->prev->next = sm->next; - if (sm->next != NULL) - sm->next->prev = sm->prev; - - if (sm == *src_sm_list) - *src_sm_list = sm->next; - if (sm == *src_sm_list_tail) - *src_sm_list_tail = sm->prev; - - if (*dst_sm_list == NULL) { - *dst_sm_list = sm; - *dst_sm_list_tail = sm; - sm->next = NULL; - sm->prev = NULL; - } else { - SigMatch *cur = *dst_sm_list_tail; - cur->next = sm; - sm->prev = cur; - sm->next = NULL; - *dst_sm_list_tail = sm; - } - - return; -} - -int SigMatchListSMBelongsTo(Signature *s, SigMatch *key_sm) -{ - int list = 0; - - for (list = 0; list < DETECT_SM_LIST_MAX; list++) { - SigMatch *sm = s->sm_lists[list]; - while (sm != NULL) { - if (sm == key_sm) - return list; - sm = sm->next; - } - } - - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unable to find the sm in any of the " - "sm lists"); - return -1; -} - -void SigParsePrepare(void) -{ - char *regexstr = CONFIG_PCRE; - const char *eb; - int eo; - int opts = 0; - - opts |= PCRE_UNGREEDY; - config_pcre = pcre_compile(regexstr, opts, &eb, &eo, NULL); - if(config_pcre == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", regexstr, eo, eb); - exit(1); - } - - config_pcre_extra = pcre_study(config_pcre, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - exit(1); - } - - regexstr = OPTION_PCRE; - opts |= PCRE_UNGREEDY; - - option_pcre = pcre_compile(regexstr, opts, &eb, &eo, NULL); - if(option_pcre == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", regexstr, eo, eb); - exit(1); - } - - option_pcre_extra = pcre_study(option_pcre, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - exit(1); - } -} - -static int SigParseOptions(DetectEngineCtx *de_ctx, Signature *s, char *optstr, char *output, size_t output_size) -{ -#define MAX_SUBSTRINGS 30 - int ov[MAX_SUBSTRINGS]; - int ret = 0; - SigTableElmt *st = NULL; - char optname[64]; - char optvalue[DETECT_MAX_RULE_SIZE] = ""; - - ret = pcre_exec(option_pcre, option_pcre_extra, optstr, strlen(optstr), 0, 0, ov, MAX_SUBSTRINGS); - /* if successful, we either have: - * 2: keyword w/o value - * 3: keyword w value, final opt OR keyword w/o value, more options coming - * 4: keyword w value, more options coming - */ - if (ret != 2 && ret != 3 && ret != 4) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec failed: ret %" PRId32 ", optstr \"%s\"", ret, optstr); - goto error; - } - - /* extract the substrings */ - if (pcre_copy_substring(optstr, ov, MAX_SUBSTRINGS, 1, optname, sizeof(optname)) < 0) { - goto error; - } - - /* Call option parsing */ - st = SigTableGet(optname); - if (st == NULL) { - SCLogError(SC_ERR_RULE_KEYWORD_UNKNOWN, "unknown rule keyword '%s'.", optname); - goto error; - } - - if (ret == 3) { - if (st->flags & SIGMATCH_NOOPT) { - if (pcre_copy_substring(optstr, ov, MAX_SUBSTRINGS, 2, output, output_size) < 0) { - goto error; - } - } else { - if (pcre_copy_substring(optstr, ov, MAX_SUBSTRINGS, 2, optvalue, sizeof(optvalue)) < 0) { - goto error; - } - } - } else if (ret == 4) { - if (pcre_copy_substring(optstr, ov, MAX_SUBSTRINGS, 2, optvalue, sizeof(optvalue)) < 0) { - goto error; - } - if (pcre_copy_substring(optstr, ov, MAX_SUBSTRINGS, 3, output, output_size) < 0) { - goto error; - } - } - - if (!(st->flags & (SIGMATCH_NOOPT|SIGMATCH_OPTIONAL_OPT))) { - if (strlen(optvalue) == 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "invalid formatting or malformed option to %s keyword: \'%s\'", - optname, optstr); - goto error; - } - } - - /* setup may or may not add a new SigMatch to the list */ - if (st->Setup(de_ctx, s, strlen(optvalue) ? optvalue : NULL) < 0) { - SCLogDebug("\"%s\" failed to setup", st->name); - goto error; - } - - if (ret == 4) { - return 1; - } - - return 0; - -error: - return -1; -} - -/** \brief Parse address string and update signature - * - * \retval 0 ok, -1 error - */ -int SigParseAddress(const DetectEngineCtx *de_ctx, - Signature *s, const char *addrstr, char flag) -{ - SCLogDebug("Address Group \"%s\" to be parsed now", addrstr); - - /* pass on to the address(list) parser */ - if (flag == 0) { - if (strcasecmp(addrstr, "any") == 0) - s->flags |= SIG_FLAG_SRC_ANY; - - if (DetectAddressParse(de_ctx, &s->src, (char *)addrstr) < 0) - goto error; - } else { - if (strcasecmp(addrstr, "any") == 0) - s->flags |= SIG_FLAG_DST_ANY; - - if (DetectAddressParse(de_ctx, &s->dst, (char *)addrstr) < 0) - goto error; - } - - return 0; - -error: - return -1; -} - -/** - * \brief Parses the protocol supplied by the Signature. - * - * http://www.iana.org/assignments/protocol-numbers - * - * \param s Pointer to the Signature instance to which the parsed - * protocol has to be added. - * \param protostr Pointer to the character string containing the protocol name. - * - * \retval 0 On successfully parsing the protocl sent as the argument. - * \retval -1 On failure - */ -int SigParseProto(Signature *s, const char *protostr) -{ - SCEnter(); - - int r = DetectProtoParse(&s->proto, (char *)protostr); - if (r < 0) { - s->alproto = AppLayerGetProtoByName((char *)protostr); - /* indicate that the signature is app-layer */ - if (s->alproto != ALPROTO_UNKNOWN) - s->flags |= SIG_FLAG_APPLAYER; - else { - SCLogError(SC_ERR_UNKNOWN_PROTOCOL, "protocol \"%s\" cannot be used " - "in a signature. Either detection for this protocol " - "supported yet OR detection has been disabled for " - "protocol through the yaml option " - "app-layer.protocols.%s.detection-enabled", protostr, - protostr); - SCReturnInt(-1); - } - } - - /* if any of these flags are set they are set in a mutually exclusive - * manner */ - if (s->proto.flags & DETECT_PROTO_ONLY_PKT) { - s->flags |= SIG_FLAG_REQUIRE_PACKET; - } else if (s->proto.flags & DETECT_PROTO_ONLY_STREAM) { - s->flags |= SIG_FLAG_REQUIRE_STREAM; - } - - SCReturnInt(0); -} - -/** - * \brief Parses the port(source or destination) field, from a Signature. - * - * \param s Pointer to the signature which has to be updated with the - * port information. - * \param portstr Pointer to the character string containing the port info. - * \param Flag which indicates if the portstr received is src or dst - * port. For src port: flag = 0, dst port: flag = 1. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int SigParsePort(const DetectEngineCtx *de_ctx, - Signature *s, const char *portstr, char flag) -{ - int r = 0; - - /* XXX VJ exclude handling this for none UDP/TCP proto's */ - - SCLogDebug("Port group \"%s\" to be parsed", portstr); - - if (flag == 0) { - if (strcasecmp(portstr, "any") == 0) - s->flags |= SIG_FLAG_SP_ANY; - - r = DetectPortParse(de_ctx, &s->sp, (char *)portstr); - } else if (flag == 1) { - if (strcasecmp(portstr, "any") == 0) - s->flags |= SIG_FLAG_DP_ANY; - - r = DetectPortParse(de_ctx, &s->dp, (char *)portstr); - } - - if (r < 0) - return -1; - - return 0; -} - -/** \retval 1 valid - * \retval 0 invalid - */ -static int SigParseActionRejectValidate(const char *action) -{ -#ifdef HAVE_LIBNET11 -#ifdef HAVE_LIBCAP_NG - if (sc_set_caps == TRUE) { - SCLogError(SC_ERR_LIBNET11_INCOMPATIBLE_WITH_LIBCAP_NG, "Libnet 1.1 is " - "incompatible with POSIX based capabilities with privs dropping. " - "For rejects to work, run as root/super user."); - return 0; - } -#endif -#else /* no libnet 1.1 */ - SCLogError(SC_ERR_LIBNET_REQUIRED_FOR_ACTION, "Libnet 1.1.x is " - "required for action \"%s\" but is not compiled into Suricata", - action); - return 0; -#endif - return 1; -} - -/** - * \brief Parses the action that has been used by the Signature and allots it - * to its Signature instance. - * - * \param s Pointer to the Signature instance to which the action belongs. - * \param action Pointer to the action string used by the Signature. - * - * \retval 0 On successfully parsing the action string and adding it to the - * Signature. - * \retval -1 On failure. - */ -int SigParseAction(Signature *s, const char *action) -{ - if (strcasecmp(action, "alert") == 0) { - s->action = ACTION_ALERT; - return 0; - } else if (strcasecmp(action, "drop") == 0) { - s->action = ACTION_DROP; - return 0; - } else if (strcasecmp(action, "pass") == 0) { - s->action = ACTION_PASS; - return 0; - } else if (strcasecmp(action, "reject") == 0) { - if (!(SigParseActionRejectValidate(action))) - return -1; - s->action = ACTION_REJECT|ACTION_DROP; - return 0; - } else if (strcasecmp(action, "rejectsrc") == 0) { - if (!(SigParseActionRejectValidate(action))) - return -1; - s->action = ACTION_REJECT|ACTION_DROP; - return 0; - } else if (strcasecmp(action, "rejectdst") == 0) { - if (!(SigParseActionRejectValidate(action))) - return -1; - s->action = ACTION_REJECT_DST|ACTION_DROP; - return 0; - } else if (strcasecmp(action, "rejectboth") == 0) { - if (!(SigParseActionRejectValidate(action))) - return -1; - s->action = ACTION_REJECT_BOTH|ACTION_DROP; - return 0; - } else { - SCLogError(SC_ERR_INVALID_ACTION,"An invalid action \"%s\" was given",action); - return -1; - } -} - -/** - * \internal - * \brief split a signature string into a few blocks for further parsing - */ -static int SigParseBasics(const DetectEngineCtx *de_ctx, - Signature *s, const char *sigstr, SignatureParser *parser, uint8_t addrs_direction) -{ -#define MAX_SUBSTRINGS 30 - int ov[MAX_SUBSTRINGS]; - int ret = 0; - - ret = pcre_exec(config_pcre, config_pcre_extra, sigstr, strlen(sigstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret != 8 && ret != 9) { - SCLogDebug("pcre_exec failed: ret %" PRId32 ", sigstr \"%s\"", ret, sigstr); - goto error; - } - - if (pcre_copy_substring(sigstr, ov, MAX_SUBSTRINGS, 1, parser->action, sizeof(parser->action)) < 0) - goto error; - if (pcre_copy_substring(sigstr, ov, MAX_SUBSTRINGS, 2, parser->protocol, sizeof(parser->protocol)) < 0) - goto error; - if (pcre_copy_substring(sigstr, ov, MAX_SUBSTRINGS, 3, parser->src, sizeof(parser->src)) < 0) - goto error; - if (pcre_copy_substring(sigstr, ov, MAX_SUBSTRINGS, 4, parser->sp, sizeof(parser->sp)) < 0) - goto error; - if (pcre_copy_substring(sigstr, ov, MAX_SUBSTRINGS, 5, parser->direction, sizeof(parser->direction)) < 0) - goto error; - if (pcre_copy_substring(sigstr, ov, MAX_SUBSTRINGS, 6, parser->dst, sizeof(parser->dst)) < 0) - goto error; - if (pcre_copy_substring(sigstr, ov, MAX_SUBSTRINGS, 7, parser->dp, sizeof(parser->dp)) < 0) - goto error; - if (ret == 9) { - if (pcre_copy_substring(sigstr, ov, MAX_SUBSTRINGS, 8, parser->opts, sizeof(parser->opts)) < 0) - goto error; - } - - /* Parse Action */ - if (SigParseAction(s, parser->action) < 0) - goto error; - - if (SigParseProto(s, parser->protocol) < 0) - goto error; - - if (strcmp(parser->direction, "<-") == 0) { - SCLogError(SC_ERR_INVALID_DIRECTION, "\"<-\" is not a valid direction modifier, \"->\" and \"<>\" are supported."); - goto error; - } - /* Check if it is bidirectional */ - if (strcmp(parser->direction, "<>") == 0) - s->init_flags |= SIG_FLAG_INIT_BIDIREC; - - /* Parse Address & Ports */ - if (SigParseAddress(de_ctx, s, parser->src, SIG_DIREC_SRC ^ addrs_direction) < 0) - goto error; - - if (SigParseAddress(de_ctx, s, parser->dst, SIG_DIREC_DST ^ addrs_direction) < 0) - goto error; - - /* For IPOnly */ - if (IPOnlySigParseAddress(de_ctx, s, parser->src, SIG_DIREC_SRC ^ addrs_direction) < 0) - goto error; - - if (IPOnlySigParseAddress(de_ctx, s, parser->dst, SIG_DIREC_DST ^ addrs_direction) < 0) - goto error; - - /* By AWS - Traditionally we should be doing this only for tcp/udp/sctp, - * but we do it for regardless of ip proto, since the dns/dnstcp/dnsudp - * changes that we made sees to it that at this point of time we don't - * set the ip proto for the sig. We do it a bit later. */ - if (SigParsePort(de_ctx, s, parser->sp, SIG_DIREC_SRC ^ addrs_direction) < 0) - goto error; - if (SigParsePort(de_ctx, s, parser->dp, SIG_DIREC_DST ^ addrs_direction) < 0) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief parse a signature - * - * \param de_ctx detection engine ctx to add it to - * \param s memory structure to store the signature in - * \param sigstr the raw signature as a null terminated string - * \param addrs_direction direction (for bi-directional sigs) - * - * \param -1 parse error - * \param 0 ok - */ -int SigParse(DetectEngineCtx *de_ctx, Signature *s, char *sigstr, uint8_t addrs_direction) -{ - SCEnter(); - - SignatureParser parser; - memset(&parser, 0x00, sizeof(parser)); - - s->sig_str = sigstr; - - int ret = SigParseBasics(de_ctx, s, sigstr, &parser, addrs_direction); - if (ret < 0) { - SCLogDebug("SigParseBasics failed"); - SCReturnInt(-1); - } - - /* we can have no options, so make sure we have them */ - if (strlen(parser.opts) > 0) { - size_t buffer_size = strlen(parser.opts) + 1; - char input[buffer_size]; - char output[buffer_size]; - memset(input, 0x00, buffer_size); - memcpy(input, parser.opts, strlen(parser.opts)+1); - - /* loop the option parsing. Each run processes one option - * and returns the rest of the option string through the - * output variable. */ - do { - memset(output, 0x00, buffer_size); - ret = SigParseOptions(de_ctx, s, input, output, buffer_size); - if (ret == 1) { - memcpy(input, output, buffer_size); - } - - } while (ret == 1); - } - - s->sig_str = NULL; - - DetectIPProtoRemoveAllSMs(s); - - SCReturnInt(ret); -} - -Signature *SigAlloc (void) -{ - Signature *sig = SCMalloc(sizeof(Signature)); - if (unlikely(sig == NULL)) - return NULL; - - memset(sig, 0, sizeof(Signature)); - - /* assign it to -1, so that we can later check if the value has been - * overwritten after the Signature has been parsed, and if it hasn't been - * overwritten, we can then assign the default value of 3 */ - sig->prio = -1; - - sig->list = DETECT_SM_LIST_NOTSET; - return sig; -} - -/** - * \internal - * \brief Free Reference list - * - * \param s Pointer to the signature - */ -static void SigRefFree (Signature *s) -{ - SCEnter(); - - DetectReference *ref = NULL; - DetectReference *next_ref = NULL; - - if (s == NULL) { - SCReturn; - } - - SCLogDebug("s %p, s->references %p", s, s->references); - - for (ref = s->references; ref != NULL;) { - next_ref = ref->next; - DetectReferenceFree(ref); - ref = next_ref; - } - - s->references = NULL; - - SCReturn; -} - -static void SigMatchFreeArrays(Signature *s) -{ - if (s != NULL) { - int type; - for (type = 0; type < DETECT_SM_LIST_MAX; type++) { - if (s->sm_arrays[type] != NULL) - SCFree(s->sm_arrays[type]); - } - } -} - -void SigFree(Signature *s) -{ - if (s == NULL) - return; - - if (s->CidrDst != NULL) - IPOnlyCIDRListFree(s->CidrDst); - - if (s->CidrSrc != NULL) - IPOnlyCIDRListFree(s->CidrSrc); - - int i; - for (i = 0; i < DETECT_SM_LIST_MAX; i++) { - SigMatch *sm = s->sm_lists[i], *nsm; - while (sm != NULL) { - nsm = sm->next; - SigMatchFree(sm); - sm = nsm; - } - } - SigMatchFreeArrays(s); - - DetectAddressHeadCleanup(&s->src); - DetectAddressHeadCleanup(&s->dst); - - if (s->sp != NULL) { - DetectPortCleanupList(s->sp); - } - if (s->dp != NULL) { - DetectPortCleanupList(s->dp); - } - - if (s->msg != NULL) - SCFree(s->msg); - - if (s->addr_src_match4 != NULL) { - SCFree(s->addr_src_match4); - } - if (s->addr_dst_match4 != NULL) { - SCFree(s->addr_dst_match4); - } - if (s->addr_src_match6 != NULL) { - SCFree(s->addr_src_match6); - } - if (s->addr_dst_match6 != NULL) { - SCFree(s->addr_dst_match6); - } - - SigRefFree(s); - - SCFree(s); -} - -/** - * \internal - * \brief build address match array for cache efficient matching - * - * \param s the signature - */ -static void SigBuildAddressMatchArray(Signature *s) -{ - /* source addresses */ - uint16_t cnt = 0; - uint16_t idx = 0; - DetectAddress *da = s->src.ipv4_head; - for ( ; da != NULL; da = da->next) { - cnt++; - } - if (cnt > 0) { - s->addr_src_match4 = SCMalloc(cnt * sizeof(DetectMatchAddressIPv4)); - if (s->addr_src_match4 == NULL) { - exit(EXIT_FAILURE); - } - - for (da = s->src.ipv4_head; da != NULL; da = da->next) { - s->addr_src_match4[idx].ip = ntohl(da->ip.addr_data32[0]); - s->addr_src_match4[idx].ip2 = ntohl(da->ip2.addr_data32[0]); - idx++; - } - s->addr_src_match4_cnt = cnt; - } - - /* destination addresses */ - cnt = 0; - idx = 0; - da = s->dst.ipv4_head; - for ( ; da != NULL; da = da->next) { - cnt++; - } - if (cnt > 0) { - s->addr_dst_match4 = SCMalloc(cnt * sizeof(DetectMatchAddressIPv4)); - if (s->addr_dst_match4 == NULL) { - exit(EXIT_FAILURE); - } - - for (da = s->dst.ipv4_head; da != NULL; da = da->next) { - s->addr_dst_match4[idx].ip = ntohl(da->ip.addr_data32[0]); - s->addr_dst_match4[idx].ip2 = ntohl(da->ip2.addr_data32[0]); - idx++; - } - s->addr_dst_match4_cnt = cnt; - } - - /* source addresses IPv6 */ - cnt = 0; - idx = 0; - da = s->src.ipv6_head; - for ( ; da != NULL; da = da->next) { - cnt++; - } - if (cnt > 0) { - s->addr_src_match6 = SCMalloc(cnt * sizeof(DetectMatchAddressIPv6)); - if (s->addr_src_match6 == NULL) { - exit(EXIT_FAILURE); - } - - for (da = s->src.ipv6_head; da != NULL; da = da->next) { - s->addr_src_match6[idx].ip[0] = ntohl(da->ip.addr_data32[0]); - s->addr_src_match6[idx].ip[1] = ntohl(da->ip.addr_data32[1]); - s->addr_src_match6[idx].ip[2] = ntohl(da->ip.addr_data32[2]); - s->addr_src_match6[idx].ip[3] = ntohl(da->ip.addr_data32[3]); - s->addr_src_match6[idx].ip2[0] = ntohl(da->ip2.addr_data32[0]); - s->addr_src_match6[idx].ip2[1] = ntohl(da->ip2.addr_data32[1]); - s->addr_src_match6[idx].ip2[2] = ntohl(da->ip2.addr_data32[2]); - s->addr_src_match6[idx].ip2[3] = ntohl(da->ip2.addr_data32[3]); - idx++; - } - s->addr_src_match6_cnt = cnt; - } - - /* destination addresses IPv6 */ - cnt = 0; - idx = 0; - da = s->dst.ipv6_head; - for ( ; da != NULL; da = da->next) { - cnt++; - } - if (cnt > 0) { - s->addr_dst_match6 = SCMalloc(cnt * sizeof(DetectMatchAddressIPv6)); - if (s->addr_dst_match6 == NULL) { - exit(EXIT_FAILURE); - } - - for (da = s->dst.ipv6_head; da != NULL; da = da->next) { - s->addr_dst_match6[idx].ip[0] = ntohl(da->ip.addr_data32[0]); - s->addr_dst_match6[idx].ip[1] = ntohl(da->ip.addr_data32[1]); - s->addr_dst_match6[idx].ip[2] = ntohl(da->ip.addr_data32[2]); - s->addr_dst_match6[idx].ip[3] = ntohl(da->ip.addr_data32[3]); - s->addr_dst_match6[idx].ip2[0] = ntohl(da->ip2.addr_data32[0]); - s->addr_dst_match6[idx].ip2[1] = ntohl(da->ip2.addr_data32[1]); - s->addr_dst_match6[idx].ip2[2] = ntohl(da->ip2.addr_data32[2]); - s->addr_dst_match6[idx].ip2[3] = ntohl(da->ip2.addr_data32[3]); - idx++; - } - s->addr_dst_match6_cnt = cnt; - } -} - -/** - * \internal - * \brief validate a just parsed signature for internal inconsistencies - * - * \param s just parsed signature - * - * \retval 0 invalid - * \retval 1 valid - */ -int SigValidate(DetectEngineCtx *de_ctx, Signature *s) -{ - uint32_t u = 0; - uint32_t sig_flags = 0; - SigMatch *sm, *pm; - - SCEnter(); - - if ((s->flags & SIG_FLAG_REQUIRE_PACKET) && - (s->flags & SIG_FLAG_REQUIRE_STREAM)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't mix packet keywords with " - "tcp-stream or flow:only_stream. Invalidating signature."); - SCReturnInt(0); - } - - for (sm = s->sm_lists[DETECT_SM_LIST_MATCH]; sm != NULL; sm = sm->next) { - if (sm->type == DETECT_FLOW) { - DetectFlowData *fd = (DetectFlowData *)sm->ctx; - if (fd == NULL) - continue; - - if (fd->flags & FLOW_PKT_TOCLIENT) { - /* check for uricontent + from_server/to_client */ - if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use uricontent " - "/http_uri , raw_uri, http_client_body, " - "http_method, http_user_agent keywords " - "with flow:to_client or flow:from_server"); - SCReturnInt(0); - } - } else if (fd->flags & FLOW_PKT_TOSERVER) { - /* check for uricontent + from_server/to_client */ - if (/*s->sm_lists[DETECT_SM_LIST_FILEDATA] != NULL ||*/ - s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use http_" - "server_body, http_stat_msg, http_stat_code " - "with flow:to_server or flow:from_client"); - SCReturnInt(0); - } - } - } - } - - if ((s->sm_lists[DETECT_SM_LIST_FILEDATA] != NULL && s->alproto == ALPROTO_SMTP) || - s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) { - sig_flags |= SIG_FLAG_TOSERVER; - s->flags |= SIG_FLAG_TOSERVER; - s->flags &= ~SIG_FLAG_TOCLIENT; - } - if ((s->sm_lists[DETECT_SM_LIST_FILEDATA] != NULL && s->alproto == ALPROTO_HTTP) || - s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) { - sig_flags |= SIG_FLAG_TOCLIENT; - s->flags |= SIG_FLAG_TOCLIENT; - s->flags &= ~SIG_FLAG_TOSERVER; - } - if ((sig_flags & (SIG_FLAG_TOCLIENT | SIG_FLAG_TOSERVER)) == (SIG_FLAG_TOCLIENT | SIG_FLAG_TOSERVER)) { - SCLogError(SC_ERR_INVALID_SIGNATURE,"You seem to have mixed keywords " - "that require inspection in both directions. Atm we only " - "support keywords in one direction within a rule."); - SCReturnInt(0); - } - - if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) { - if ((s->flags & (SIG_FLAG_TOCLIENT|SIG_FLAG_TOSERVER)) == (SIG_FLAG_TOCLIENT|SIG_FLAG_TOSERVER)) { - SCLogError(SC_ERR_INVALID_SIGNATURE,"http_raw_header signature " - "without a flow direction. Use flow:to_server for " - "inspecting request headers or flow:to_client for " - "inspecting response headers."); - SCReturnInt(0); - } - } - - if (s->sm_lists[DETECT_SM_LIST_HHHDMATCH] != NULL) { - for (sm = s->sm_lists[DETECT_SM_LIST_HHHDMATCH]; - sm != NULL; sm = sm->next) { - if (sm->type == DETECT_CONTENT) { - DetectContentData *cd = (DetectContentData *)sm->ctx; - if (cd->flags & DETECT_CONTENT_NOCASE) { - SCLogWarning(SC_ERR_INVALID_SIGNATURE, "http_host keyword " - "specified along with \"nocase\". " - "Since the hostname buffer we match against " - "is actually lowercase. So having a " - "nocase is redundant."); - } else { - for (u = 0; u < cd->content_len; u++) { - if (isupper(cd->content[u])) - break; - } - if (u != cd->content_len) { - SCLogWarning(SC_ERR_INVALID_SIGNATURE, "A pattern with " - "uppercase chars detected for http_host. " - "Since the hostname buffer we match against " - "is lowercase only, please specify a " - "lowercase pattern."); - SCReturnInt(0); - } - } - } - } - } - - //if (s->alproto != ALPROTO_UNKNOWN) { - // if (s->flags & SIG_FLAG_STATE_MATCH) { - // if (s->alproto == ALPROTO_DNS) { - // if (al_proto_table[ALPROTO_DNS_UDP].to_server == 0 || - // al_proto_table[ALPROTO_DNS_UDP].to_client == 0 || - // al_proto_table[ALPROTO_DNS_TCP].to_server == 0 || - // al_proto_table[ALPROTO_DNS_TCP].to_client == 0) { - // SCLogInfo("Signature uses options that need the app layer " - // "parser for dns, but the parser's disabled " - // "for the protocol. Please check if you have " - // "disabled it through the option " - // "\"app-layer.protocols.dcerpc[udp|tcp].enabled\"" - // "or internally the parser has been disabled in " - // "the code. Invalidating signature."); - // SCReturnInt(0); - // } - // } else { - // if (al_proto_table[s->alproto].to_server == 0 || - // al_proto_table[s->alproto].to_client == 0) { - // const char *proto_name = AppProtoToString(s->alproto); - // SCLogInfo("Signature uses options that need the app layer " - // "parser for \"%s\", but the parser's disabled " - // "for the protocol. Please check if you have " - // "disabled it through the option " - // "\"app-layer.protocols.%s.enabled\" or internally " - // "there the parser has been disabled in the code. " - // "Invalidating signature.", proto_name, proto_name); - // SCReturnInt(0); - // } - // } - // } - // - // - // - // - // - //} - - if (s->flags & SIG_FLAG_REQUIRE_PACKET) { - pm = SigMatchGetLastSMFromLists(s, 24, - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_REPLACE, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - if (pm != NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Signature has" - " replace keyword linked with a modified content" - " keyword (http_*, dce_*). It only supports content on" - " raw payload"); - SCReturnInt(0); - } - - if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] || - s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH] || - s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]) - { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Signature combines packet " - "specific matches (like dsize, flags, ttl) with stream / " - "state matching by matching on app layer proto (like using " - "http_* keywords)."); - SCReturnInt(0); - } - } - - for (sm = s->sm_lists[DETECT_SM_LIST_AMATCH]; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_AL_APP_LAYER_PROTOCOL) - continue; - if (((DetectAppLayerProtocolData *)sm->ctx)->negated) - break; - } - if (sm != NULL && s->alproto != ALPROTO_UNKNOWN) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "We can't have " - "the rule match on a fixed alproto and at the same time" - "have an app-layer-protocol keyword set."); - SCReturnInt(0); - } - - /* TCP: pkt vs stream vs depth/offset */ - if (s->proto.proto[IPPROTO_TCP / 8] & (1 << (IPPROTO_TCP % 8))) { - if (!(s->flags & (SIG_FLAG_REQUIRE_PACKET | SIG_FLAG_REQUIRE_STREAM))) { - s->flags |= SIG_FLAG_REQUIRE_STREAM; - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT && - (((DetectContentData *)(sm->ctx))->flags & - (DETECT_CONTENT_DEPTH | DETECT_CONTENT_OFFSET))) { - s->flags |= SIG_FLAG_REQUIRE_PACKET; - break; - } - sm = sm->next; - } - } - } - - if (s->sm_lists[DETECT_SM_LIST_BASE64_DATA] != NULL) { - int list; - uint16_t idx = s->sm_lists[DETECT_SM_LIST_BASE64_DATA]->idx; - for (list = 0; list < DETECT_SM_LIST_MAX; list++) { - if (list != DETECT_SM_LIST_BASE64_DATA && - s->sm_lists[list] != NULL) { - if (s->sm_lists[list]->idx > idx) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Rule buffer " - "cannot be reset after base64_data."); - SCReturnInt(0); - } - } - } - } - -#ifdef HAVE_LUA - DetectLuaPostSetup(s); -#endif - -#ifdef DEBUG - int i; - for (i = 0; i < DETECT_SM_LIST_MAX; i++) { - if (s->sm_lists[i] != NULL) { - for (sm = s->sm_lists[i]; sm != NULL; sm = sm->next) { - BUG_ON(sm == sm->prev); - BUG_ON(sm == sm->next); - } - } - } -#endif - - SCReturnInt(1); -} - -/** - * \internal - * \brief Helper function for SigInit(). - */ -static Signature *SigInitHelper(DetectEngineCtx *de_ctx, char *sigstr, - uint8_t dir) -{ - Signature *sig = SigAlloc(); - if (sig == NULL) - goto error; - - /* default gid to 1 */ - sig->gid = 1; - - if (SigParse(de_ctx, sig, sigstr, dir) < 0) - goto error; - - /* signature priority hasn't been overwritten. Using default priority */ - if (sig->prio == -1) - sig->prio = 3; - - sig->num = de_ctx->signum; - de_ctx->signum++; - - if (sig->alproto != ALPROTO_UNKNOWN) { - int override_needed = 0; - if (sig->proto.flags & DETECT_PROTO_ANY) { - sig->proto.flags &= ~DETECT_PROTO_ANY; - memset(sig->proto.proto, 0x00, sizeof(sig->proto.proto)); - override_needed = 1; - } else { - override_needed = 1; - size_t s = 0; - for (s = 0; s < sizeof(sig->proto.proto); s++) { - if (sig->proto.proto[s] != 0x00) { - override_needed = 0; - break; - } - } - } - - /* at this point if we had alert ip and the ip proto was not - * overridden, we use the ip proto that has been configured - * against the app proto in use. */ - if (override_needed) - AppLayerProtoDetectSupportedIpprotos(sig->alproto, sig->proto.proto); - } - - if (DetectAppLayerEventPrepare(sig) < 0) - goto error; - - /* set the packet and app layer flags, but only if the - * app layer flag wasn't already set in which case we - * only consider the app layer */ - if (!(sig->flags & SIG_FLAG_APPLAYER)) { - if (sig->sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - SigMatch *sm = sig->sm_lists[DETECT_SM_LIST_MATCH]; - for ( ; sm != NULL; sm = sm->next) { - if (sigmatch_table[sm->type].Match != NULL) - sig->init_flags |= SIG_FLAG_INIT_PACKET; - } - } else { - sig->init_flags |= SIG_FLAG_INIT_PACKET; - } - } - - if (sig->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) - sig->flags |= SIG_FLAG_APPLAYER; - - if (sig->sm_lists[DETECT_SM_LIST_UMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_DMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_AMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HRLMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HCBDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_FILEDATA]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HHDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HRHDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HMDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HCDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HRUDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_FILEMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HSMDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HSCDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HUADMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HHHDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_HRHHDMATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - - /* Template. */ - if (sig->sm_lists[DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH]) { - sig->flags |= SIG_FLAG_STATE_MATCH; - } - - /* DNS */ - if (sig->sm_lists[DETECT_SM_LIST_DNSQUERYNAME_MATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_DNSREQUEST_MATCH]) { - sig->flags |= SIG_FLAG_STATE_MATCH; - } - if (sig->sm_lists[DETECT_SM_LIST_DNSRESPONSE_MATCH]) { - sig->flags |= SIG_FLAG_STATE_MATCH; - } - - if (sig->sm_lists[DETECT_SM_LIST_MODBUS_MATCH]) - sig->flags |= SIG_FLAG_STATE_MATCH; - if (sig->sm_lists[DETECT_SM_LIST_APP_EVENT]) - sig->flags |= SIG_FLAG_STATE_MATCH; - - if (!(sig->init_flags & SIG_FLAG_INIT_FLOW)) { - sig->flags |= SIG_FLAG_TOSERVER; - sig->flags |= SIG_FLAG_TOCLIENT; - } - - SCLogDebug("sig %"PRIu32" SIG_FLAG_APPLAYER: %s, SIG_FLAG_PACKET: %s", - sig->id, sig->flags & SIG_FLAG_APPLAYER ? "set" : "not set", - sig->init_flags & SIG_FLAG_INIT_PACKET ? "set" : "not set"); - - SigBuildAddressMatchArray(sig); - - if (sig->sm_lists[DETECT_SM_LIST_APP_EVENT] != NULL) { - if (AppLayerParserProtocolIsTxEventAware(IPPROTO_TCP, sig->alproto)) { - if (sig->flags & SIG_FLAG_TOSERVER) { - DetectEngineRegisterAppInspectionEngine(IPPROTO_TCP, - sig->alproto, - 0, - DETECT_SM_LIST_APP_EVENT, - DE_STATE_FLAG_APP_EVENT_INSPECT, - DetectEngineAptEventInspect, - app_inspection_engine); - } - if (sig->flags & SIG_FLAG_TOCLIENT) { - DetectEngineRegisterAppInspectionEngine(IPPROTO_TCP, - sig->alproto, - 1, - DETECT_SM_LIST_APP_EVENT, - DE_STATE_FLAG_APP_EVENT_INSPECT, - DetectEngineAptEventInspect, - app_inspection_engine); - } - } - if (AppLayerParserProtocolIsTxEventAware(IPPROTO_UDP, sig->alproto)) { - if (sig->flags & SIG_FLAG_TOSERVER) { - DetectEngineRegisterAppInspectionEngine(IPPROTO_UDP, - sig->alproto, - 0, - DETECT_SM_LIST_APP_EVENT, - DE_STATE_FLAG_APP_EVENT_INSPECT, - DetectEngineAptEventInspect, - app_inspection_engine); - } - if (sig->flags & SIG_FLAG_TOCLIENT) { - DetectEngineRegisterAppInspectionEngine(IPPROTO_UDP, - sig->alproto, - 1, - DETECT_SM_LIST_APP_EVENT, - DE_STATE_FLAG_APP_EVENT_INSPECT, - DetectEngineAptEventInspect, - app_inspection_engine); - } - } - } - - /* validate signature, SigValidate will report the error reason */ - if (SigValidate(de_ctx, sig) == 0) { - goto error; - } - - return sig; - -error: - if (sig != NULL) { - SigFree(sig); - } - return NULL; -} - -/** - * \brief Parses a signature and adds it to the Detection Engine Context. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param sigstr Pointer to a character string containing the signature to be - * parsed. - * - * \retval Pointer to the Signature instance on success; NULL on failure. - */ -Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) -{ - SCEnter(); - - uint32_t oldsignum = de_ctx->signum; - - Signature *sig; - - if ((sig = SigInitHelper(de_ctx, sigstr, SIG_DIREC_NORMAL)) == NULL) { - goto error; - } - - if (sig->init_flags & SIG_FLAG_INIT_BIDIREC) { - sig->next = SigInitHelper(de_ctx, sigstr, SIG_DIREC_SWITCHED); - if (sig->next == NULL) { - goto error; - } - } - - SCReturnPtr(sig, "Signature"); - -error: - if (sig != NULL) { - SigFree(sig); - } - /* if something failed, restore the old signum count - * since we didn't install it */ - de_ctx->signum = oldsignum; - - SCReturnPtr(NULL, "Signature"); -} - -/** - * \brief The hash free function to be the used by the hash table - - * DetectEngineCtx->dup_sig_hash_table. - * - * \param data Pointer to the data, in our case SigDuplWrapper to be freed. - */ -void DetectParseDupSigFreeFunc(void *data) -{ - if (data != NULL) - SCFree(data); - - return; -} - -/** - * \brief The hash function to be the used by the hash table - - * DetectEngineCtx->dup_sig_hash_table. - * - * \param ht Pointer to the hash table. - * \param data Pointer to the data, in our case SigDuplWrapper. - * \param datalen Not used in our case. - * - * \retval sw->s->id The generated hash value. - */ -uint32_t DetectParseDupSigHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - SigDuplWrapper *sw = (SigDuplWrapper *)data; - - return (sw->s->id % ht->array_size); -} - -/** - * \brief The Compare function to be used by the hash table - - * DetectEngineCtx->dup_sig_hash_table. - * - * \param data1 Pointer to the first SigDuplWrapper. - * \param len1 Not used. - * \param data2 Pointer to the second SigDuplWrapper. - * \param len2 Not used. - * - * \retval 1 If the 2 SigDuplWrappers sent as args match. - * \retval 0 If the 2 SigDuplWrappers sent as args do not match. - */ -char DetectParseDupSigCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - SigDuplWrapper *sw1 = (SigDuplWrapper *)data1; - SigDuplWrapper *sw2 = (SigDuplWrapper *)data2; - - if (sw1 == NULL || sw2 == NULL || - sw1->s == NULL || sw2->s == NULL) - return 0; - - /* sid and gid match required */ - if (sw1->s->id == sw2->s->id && sw1->s->gid == sw2->s->gid) return 1; - - return 0; -} - -/** - * \brief Initializes the hash table that is used to cull duplicate sigs. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectParseDupSigHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->dup_sig_hash_table = HashListTableInit(15000, - DetectParseDupSigHashFunc, - DetectParseDupSigCompareFunc, - DetectParseDupSigFreeFunc); - if (de_ctx->dup_sig_hash_table == NULL) - return -1; - - return 0; -} - -/** - * \brief Frees the hash table that is used to cull duplicate sigs. - * - * \param de_ctx Pointer to the detection engine context that holds this table. - */ -void DetectParseDupSigHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->dup_sig_hash_table != NULL) - HashListTableFree(de_ctx->dup_sig_hash_table); - - de_ctx->dup_sig_hash_table = NULL; - - return; -} - -/** - * \brief Check if a signature is a duplicate. - * - * There are 3 types of return values for this function. - * - * - 0, which indicates that the Signature is not a duplicate - * and has to be added to the detection engine list. - * - 1, Signature is duplicate, and the existing signature in - * the list shouldn't be replaced with this duplicate. - * - 2, Signature is duplicate, and the existing signature in - * the list should be replaced with this duplicate. - * - * \param de_ctx Pointer to the detection engine context. - * \param sig Pointer to the Signature that has to be checked. - * - * \retval 2 If Signature is duplicate and the existing signature in - * the list should be chucked out and replaced with this. - * \retval 1 If Signature is duplicate, and should be chucked out. - * \retval 0 If Signature is not a duplicate. - */ -static inline int DetectEngineSignatureIsDuplicate(DetectEngineCtx *de_ctx, - Signature *sig) -{ - /* we won't do any NULL checks on the args */ - - /* return value */ - int ret = 0; - - SigDuplWrapper *sw_dup = NULL; - SigDuplWrapper *sw = NULL; - - /* used for making a duplicate_sig_hash_table entry */ - sw = SCMalloc(sizeof(SigDuplWrapper)); - if (unlikely(sw == NULL)) { - exit(EXIT_FAILURE); - } - memset(sw, 0, sizeof(SigDuplWrapper)); - sw->s = sig; - - /* check if we have a duplicate entry for this signature */ - sw_dup = HashListTableLookup(de_ctx->dup_sig_hash_table, (void *)sw, 0); - /* we don't have a duplicate entry for this sig */ - if (sw_dup == NULL) { - /* add it to the hash table */ - HashListTableAdd(de_ctx->dup_sig_hash_table, (void *)sw, 0); - - /* add the s_prev entry for the previously loaded sw in the hash_table */ - if (de_ctx->sig_list != NULL) { - SigDuplWrapper *sw_old = NULL; - SigDuplWrapper sw_tmp; - memset(&sw_tmp, 0, sizeof(SigDuplWrapper)); - - /* the topmost sig would be the last loaded sig */ - sw_tmp.s = de_ctx->sig_list; - sw_old = HashListTableLookup(de_ctx->dup_sig_hash_table, - (void *)&sw_tmp, 0); - /* sw_old == NULL case is impossible */ - sw_old->s_prev = sig; - } - - ret = 0; - goto end; - } - - /* if we have reached here we have a duplicate entry for this signature. - * Check the signature revision. Store the signature with the latest rev - * and discard the other one */ - if (sw->s->rev <= sw_dup->s->rev) { - ret = 1; - goto end; - } - - /* the new sig is of a newer revision than the one that is already in the - * list. Remove the old sig from the list */ - if (sw_dup->s_prev == NULL) { - SigDuplWrapper sw_temp; - memset(&sw_temp, 0, sizeof(SigDuplWrapper)); - if (sw_dup->s->init_flags & SIG_FLAG_INIT_BIDIREC) { - sw_temp.s = sw_dup->s->next->next; - de_ctx->sig_list = sw_dup->s->next->next; - SigFree(sw_dup->s->next); - } else { - sw_temp.s = sw_dup->s->next; - de_ctx->sig_list = sw_dup->s->next; - } - SigDuplWrapper *sw_next = NULL; - if (sw_temp.s != NULL) { - sw_next = HashListTableLookup(de_ctx->dup_sig_hash_table, - (void *)&sw_temp, 0); - sw_next->s_prev = sw_dup->s_prev; - } - SigFree(sw_dup->s); - } else { - SigDuplWrapper sw_temp; - memset(&sw_temp, 0, sizeof(SigDuplWrapper)); - if (sw_dup->s->init_flags & SIG_FLAG_INIT_BIDIREC) { - sw_temp.s = sw_dup->s->next->next; - sw_dup->s_prev->next = sw_dup->s->next->next; - SigFree(sw_dup->s->next); - } else { - sw_temp.s = sw_dup->s->next; - sw_dup->s_prev->next = sw_dup->s->next; - } - SigDuplWrapper *sw_next = NULL; - if (sw_temp.s != NULL) { - sw_next = HashListTableLookup(de_ctx->dup_sig_hash_table, - (void *)&sw_temp, 0); - sw_next->s_prev = sw_dup->s_prev;; - } - SigFree(sw_dup->s); - } - - /* make changes to the entry to reflect the presence of the new sig */ - sw_dup->s = sig; - sw_dup->s_prev = NULL; - - /* this is duplicate, but a duplicate that replaced the existing sig entry */ - ret = 2; - - SCFree(sw); - -end: - return ret; -} - -/** - * \brief Parse and append a Signature into the Detection Engine Context - * signature list. - * - * If the signature is bidirectional it should append two signatures - * (with the addresses switched) into the list. Also handle duplicate - * signatures. In case of duplicate sigs, use the ones that have the - * latest revision. We use the sid and the msg to identifiy duplicate - * sigs. If 2 sigs have the same sid and gid, they are duplicates. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param sigstr Pointer to a character string containing the signature to be - * parsed. - * \param sig_file Pointer to a character string containing the filename from - * which signature is read - * \param lineno Line number from where signature is read - * - * \retval Pointer to the head Signature in the detection engine ctx sig_list - * on success; NULL on failure. - */ -Signature *DetectEngineAppendSig(DetectEngineCtx *de_ctx, char *sigstr) -{ - Signature *sig = SigInit(de_ctx, sigstr); - if (sig == NULL) { - return NULL; - } - - /* checking for the status of duplicate signature */ - int dup_sig = DetectEngineSignatureIsDuplicate(de_ctx, sig); - /* a duplicate signature that should be chucked out. Check the previously - * called function details to understand the different return values */ - if (dup_sig == 1) { - SCLogError(SC_ERR_DUPLICATE_SIG, "Duplicate signature \"%s\"", sigstr); - goto error; - } else if (dup_sig == 2) { - SCLogWarning(SC_ERR_DUPLICATE_SIG, "Signature with newer revision," - " so the older sig replaced by this new signature \"%s\"", - sigstr); - } - - if (sig->init_flags & SIG_FLAG_INIT_BIDIREC) { - if (sig->next != NULL) { - sig->next->next = de_ctx->sig_list; - } else { - goto error; - } - } else { - /* if this sig is the first one, sig_list should be null */ - sig->next = de_ctx->sig_list; - } - - de_ctx->sig_list = sig; - - /** - * In DetectEngineAppendSig(), the signatures are prepended and we always return the first one - * so if the signature is bidirectional, the returned sig will point through "next" ptr - * to the cloned signatures with the switched addresses - */ - return (dup_sig == 0 || dup_sig == 2) ? sig : NULL; - -error: - if (sig != NULL) - SigFree(sig); - return NULL; -} - -/* - * TESTS - */ - -#ifdef UNITTESTS -int SigParseTest01 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)"); - if (sig == NULL) - result = 0; - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -int SigParseTest02 (void) -{ - int result = 0; - Signature *sig = NULL; - DetectPort *port = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) - goto end; - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - sig = SigInit(de_ctx, "alert tcp any !21:902 -> any any (msg:\"ET MALWARE Suspicious 220 Banner on Local Port\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:2003055; rev:4;)"); - if (sig == NULL) { - goto end; - } - - int r = DetectPortParse(de_ctx, &port, "0:20"); - if (r < 0) - goto end; - - if (DetectPortCmp(sig->sp, port) == PORT_EQ) { - result = 1; - } else { - DetectPortPrint(port); printf(" != "); DetectPortPrint(sig->sp); printf(": "); - } - -end: - if (port != NULL) DetectPortCleanupList(port); - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test SigParseTest03 test for invalid direction operator in rule - */ -int SigParseTest03 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp 1.2.3.4 any <- !1.2.3.4 any (msg:\"SigParseTest03\"; sid:1;)"); - if (sig != NULL) { - result = 0; - printf("expected NULL got sig ptr %p: ",sig); - } - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -int SigParseTest04 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp 1.2.3.4 1024: -> !1.2.3.4 1024: (msg:\"SigParseTest04\"; sid:1;)"); - if (sig == NULL) - result = 0; - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Port validation */ -int SigParseTest05 (void) -{ - int result = 0; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp 1.2.3.4 1024:65536 -> !1.2.3.4 any (msg:\"SigParseTest05\"; sid:1;)"); - if (sig == NULL) { - result = 1; - } else { - printf("signature didn't fail to parse as we expected: "); - } - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Parsing bug debugging at 2010-03-18 */ -int SigParseTest06 (void) -{ - int result = 0; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any any -> any any (flow:to_server; content:\"GET\"; nocase; http_method; uricontent:\"/uri/\"; nocase; content:\"Host|3A| abc\"; nocase; sid:1; rev:1;)"); - if (sig != NULL) { - result = 1; - } else { - printf("signature failed to parse: "); - } - -end: - if (sig != NULL) - SigFree(sig); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Parsing duplicate sigs. - */ -int SigParseTest07(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:1; rev:1;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:1; rev:1;)"); - - result = (de_ctx->sig_list != NULL && de_ctx->sig_list->next == NULL); - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Parsing duplicate sigs. - */ -int SigParseTest08(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:1; rev:1;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:1; rev:2;)"); - - result = (de_ctx->sig_list != NULL && de_ctx->sig_list->next == NULL && - de_ctx->sig_list->rev == 2); - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Parsing duplicate sigs. - */ -int SigParseTest09(void) -{ - int result = 1; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:1; rev:1;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:1; rev:2;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:1; rev:6;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:1; rev:4;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:2; rev:2;)"); - result &= (de_ctx->sig_list != NULL && de_ctx->sig_list->id == 2 && - de_ctx->sig_list->rev == 2); - if (result == 0) - goto end; - result &= (de_ctx->sig_list->next != NULL && de_ctx->sig_list->next->id == 1 && - de_ctx->sig_list->next->rev == 6); - if (result == 0) - goto end; - - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:2; rev:1;)"); - result &= (de_ctx->sig_list != NULL && de_ctx->sig_list->id == 2 && - de_ctx->sig_list->rev == 2); - if (result == 0) - goto end; - result &= (de_ctx->sig_list->next != NULL && de_ctx->sig_list->next->id == 1 && - de_ctx->sig_list->next->rev == 6); - if (result == 0) - goto end; - - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:2; rev:4;)"); - result &= (de_ctx->sig_list != NULL && de_ctx->sig_list->id == 2 && - de_ctx->sig_list->rev == 4); - if (result == 0) - goto end; - result &= (de_ctx->sig_list->next != NULL && de_ctx->sig_list->next->id == 1 && - de_ctx->sig_list->next->rev == 6); - if (result == 0) - goto end; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Parsing duplicate sigs. - */ -int SigParseTest10(void) -{ - int result = 1; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:1; rev:1;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:2; rev:1;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:3; rev:1;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:4; rev:1;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:5; rev:1;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:3; rev:2;)"); - DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (msg:\"boo\"; sid:2; rev:2;)"); - - result &= ((de_ctx->sig_list->id == 2) && - (de_ctx->sig_list->next->id == 3) && - (de_ctx->sig_list->next->next->id == 5) && - (de_ctx->sig_list->next->next->next->id == 4) && - (de_ctx->sig_list->next->next->next->next->id == 1)); - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Parsing sig with trailing space(s) as reported by - * Morgan Cox on oisf-users. - */ -int SigParseTest11(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - Signature *s = NULL; - - s = DetectEngineAppendSig(de_ctx, "drop tcp any any -> any 80 (msg:\"Snort_Inline is blocking the http link\";) "); - if (s == NULL) { - printf("sig 1 didn't parse: "); - goto end; - } - - s = DetectEngineAppendSig(de_ctx, "drop tcp any any -> any 80 (msg:\"Snort_Inline is blocking the http link\"; sid:1;) "); - if (s == NULL) { - printf("sig 2 didn't parse: "); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test file_data with rawbytes - */ -static int SigParseTest12(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - Signature *s = NULL; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (file_data; content:\"abc\"; rawbytes; sid:1;)"); - if (s != NULL) { - printf("sig 1 should have given an error: "); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test packet/stream sig - */ -static int SigParseTest13(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - Signature *s = NULL; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"abc\"; sid:1;)"); - if (s == NULL) { - printf("sig 1 invalidated: failure"); - goto end; - } - - if (!(s->flags & SIG_FLAG_REQUIRE_STREAM)) { - printf("sig doesn't have stream flag set\n"); - goto end; - } - - if (s->flags & SIG_FLAG_REQUIRE_PACKET) { - printf("sig has packet flag set\n"); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test packet/stream sig - */ -static int SigParseTest14(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - Signature *s = NULL; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"abc\"; dsize:>0; sid:1;)"); - if (s == NULL) { - printf("sig 1 invalidated: failure"); - goto end; - } - - if (!(s->flags & SIG_FLAG_REQUIRE_PACKET)) { - printf("sig doesn't have packet flag set\n"); - goto end; - } - - if (s->flags & SIG_FLAG_REQUIRE_STREAM) { - printf("sig has stream flag set\n"); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test packet/stream sig - */ -static int SigParseTest15(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - Signature *s = NULL; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"abc\"; offset:5; sid:1;)"); - if (s == NULL) { - printf("sig 1 invalidated: failure"); - goto end; - } - - if (!(s->flags & SIG_FLAG_REQUIRE_PACKET)) { - printf("sig doesn't have packet flag set\n"); - goto end; - } - - if (!(s->flags & SIG_FLAG_REQUIRE_STREAM)) { - printf("sig doesn't have stream flag set\n"); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test packet/stream sig - */ -static int SigParseTest16(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - Signature *s = NULL; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"abc\"; depth:5; sid:1;)"); - if (s == NULL) { - printf("sig 1 invalidated: failure"); - goto end; - } - - if (!(s->flags & SIG_FLAG_REQUIRE_PACKET)) { - printf("sig doesn't have packet flag set\n"); - goto end; - } - - if (!(s->flags & SIG_FLAG_REQUIRE_STREAM)) { - printf("sig doesn't have stream flag set\n"); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test packet/stream sig - */ -static int SigParseTest17(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - Signature *s = NULL; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"abc\"; offset:1; depth:5; sid:1;)"); - if (s == NULL) { - printf("sig 1 invalidated: failure"); - goto end; - } - - if (!(s->flags & SIG_FLAG_REQUIRE_PACKET)) { - printf("sig doesn't have packet flag set\n"); - goto end; - } - - if (!(s->flags & SIG_FLAG_REQUIRE_STREAM)) { - printf("sig doesn't have stream flag set\n"); - goto end; - } - - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test sid value too large. Bug #779 */ -static int SigParseTest18 (void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (DetectEngineAppendSig(de_ctx, "alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:99999999999999999999;)") != NULL) - goto end; - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test gid value too large. Related to bug #779 */ -static int SigParseTest19 (void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (DetectEngineAppendSig(de_ctx, "alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; gid:99999999999999999999;)") != NULL) - goto end; - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test rev value too large. Related to bug #779 */ -static int SigParseTest20 (void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (DetectEngineAppendSig(de_ctx, "alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1; rev:99999999999999999999;)") != NULL) - goto end; - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test address parsing */ -static int SigParseTest21 (void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (DetectEngineAppendSig(de_ctx, "alert tcp [1.2.3.4, 1.2.3.5] any -> !1.2.3.4 any (sid:1;)") == NULL) - goto end; - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test address parsing */ -static int SigParseTest22 (void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (DetectEngineAppendSig(de_ctx, "alert tcp [10.10.10.0/24, !10.10.10.247] any -> [10.10.10.0/24, !10.10.10.247] any (sid:1;)") == NULL) - goto end; - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Direction operator validation (invalid) */ -int SigParseBidirecTest06 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any - 192.168.1.5 any (msg:\"SigParseBidirecTest05\"; sid:1;)"); - if (sig == NULL) - result = 1; - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Direction operator validation (invalid) */ -int SigParseBidirecTest07 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any <- 192.168.1.5 any (msg:\"SigParseBidirecTest05\"; sid:1;)"); - if (sig == NULL) - result = 1; - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Direction operator validation (invalid) */ -int SigParseBidirecTest08 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any < 192.168.1.5 any (msg:\"SigParseBidirecTest05\"; sid:1;)"); - if (sig == NULL) - result = 1; - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Direction operator validation (invalid) */ -int SigParseBidirecTest09 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any > 192.168.1.5 any (msg:\"SigParseBidirecTest05\"; sid:1;)"); - if (sig == NULL) - result = 1; - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Direction operator validation (invalid) */ -int SigParseBidirecTest10 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any -< 192.168.1.5 any (msg:\"SigParseBidirecTest05\"; sid:1;)"); - if (sig == NULL) - result = 1; - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Direction operator validation (invalid) */ -int SigParseBidirecTest11 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any >- 192.168.1.5 any (msg:\"SigParseBidirecTest05\"; sid:1;)"); - if (sig == NULL) - result = 1; - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Direction operator validation (invalid) */ -int SigParseBidirecTest12 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any >< 192.168.1.5 any (msg:\"SigParseBidirecTest05\"; sid:1;)"); - if (sig == NULL) - result = 1; - -end: - if (sig != NULL) SigFree(sig); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Direction operator validation (valid) */ -int SigParseBidirecTest13 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any <> 192.168.1.5 any (msg:\"SigParseBidirecTest05\"; sid:1;)"); - if (sig != NULL) - result = 1; - -end: - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Direction operator validation (valid) */ -int SigParseBidirecTest14 (void) -{ - int result = 1; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any -> 192.168.1.5 any (msg:\"SigParseBidirecTest05\"; sid:1;)"); - if (sig != NULL) - result = 1; - -end: - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Ensure that we don't set bidirectional in a - * normal (one direction) Signature - */ -int SigTestBidirec01 (void) -{ - Signature *sig = NULL; - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 1.2.3.4 1024:65535 -> !1.2.3.4 any (msg:\"SigTestBidirec01\"; sid:1;)"); - if (sig == NULL) - goto end; - if (sig->next != NULL) - goto end; - if (sig->init_flags & SIG_FLAG_INIT_BIDIREC) - goto end; - if (de_ctx->signum != 1) - goto end; - - result = 1; - -end: - if (de_ctx != NULL) { - SigCleanSignatures(de_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - return result; -} - -/** \test Ensure that we set a bidirectional Signature correctly */ -int SigTestBidirec02 (void) -{ - int result = 0; - Signature *sig = NULL; - Signature *copy = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 1.2.3.4 1024:65535 <> !1.2.3.4 any (msg:\"SigTestBidirec02\"; sid:1;)"); - if (sig == NULL) - goto end; - if (de_ctx->sig_list != sig) - goto end; - if (!(sig->init_flags & SIG_FLAG_INIT_BIDIREC)) - goto end; - if (sig->next == NULL) - goto end; - if (de_ctx->signum != 2) - goto end; - copy = sig->next; - if (copy->next != NULL) - goto end; - if (!(copy->init_flags & SIG_FLAG_INIT_BIDIREC)) - goto end; - - result = 1; - -end: - if (de_ctx != NULL) { - SigCleanSignatures(de_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - return result; -} - -/** \test Ensure that we set a bidirectional Signature correctly -* and we install it with the rest of the signatures, checking -* also that it match with the correct addr directions -*/ -int SigTestBidirec03 (void) -{ - int result = 0; - Signature *sig = NULL; - Packet *p = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - char *sigs[3]; - sigs[0] = "alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 1\"; sid:1;)"; - sigs[1] = "alert tcp any any <> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)"; - sigs[2] = "alert tcp any any -> 192.168.1.1 any (msg:\"SigTestBidirec03 sid 3\"; sid:3;)"; - UTHAppendSigs(de_ctx, sigs, 3); - - /* Checking that bidirectional rules are set correctly */ - sig = de_ctx->sig_list; - if (sig == NULL) - goto end; - if (sig->next == NULL) - goto end; - if (sig->next->next == NULL) - goto end; - if (sig->next->next->next == NULL) - goto end; - if (sig->next->next->next->next != NULL) - goto end; - if (de_ctx->signum != 4) - goto end; - - uint8_t rawpkt1_ether[] = { - 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c, - 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00, - 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06, - 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8, - 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2, - 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18, - 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45, - 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50, - 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f, - 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e, - 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d, - 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67, - 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a, - 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30, - 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55, - 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20, - 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20, - 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72, - 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e, - 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b, - 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39, - 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75, - 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34, - 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79, - 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f, - 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34, - 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74, - 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68, - 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c, - 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f, - 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d, - 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63, - 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d, - 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c, - 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e, - 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70, - 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61, - 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75, - 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30, - 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65, - 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64, - 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69, - 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74, - 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70, - 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65, - 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38, - 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74, - 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e, - 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e, - 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d, - 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33, - 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e, - 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20, - 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69, - 0x76,0x65,0x0d,0x0a,0x0d,0x0a }; /* end rawpkt1_ether */ - - FlowInitConfig(FLOW_QUIET); - p = UTHBuildPacketFromEth(rawpkt1_ether, sizeof(rawpkt1_ether)); - if (p == NULL) { - SCLogDebug("Error building packet"); - goto end; - } - UTHMatchPackets(de_ctx, &p, 1); - - uint32_t sids[3] = {1, 2, 3}; - uint32_t results[3] = {1, 1, 1}; - result = UTHCheckPacketMatchResults(p, sids, results, 1); - -end: - if (p != NULL) { - PACKET_RECYCLE(p); - SCFree(p); - } - if (de_ctx != NULL) { - SigCleanSignatures(de_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - FlowShutdown(); - - return result; -} - -/** \test Ensure that we set a bidirectional Signature correctly -* and we install it with the rest of the signatures, checking -* also that it match with the correct addr directions -*/ -int SigTestBidirec04 (void) -{ - int result = 0; - Signature *sig = NULL; - Packet *p = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any -> any any (msg:\"SigTestBidirec03 sid 1\"; sid:1;)"); - if (sig == NULL) - goto end; - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any <> any any (msg:\"SigTestBidirec03 sid 2 bidirectional\"; sid:2;)"); - if (sig == NULL) - goto end; - if ( !(sig->init_flags & SIG_FLAG_INIT_BIDIREC)) - goto end; - if (sig->next == NULL) - goto end; - if (sig->next->next == NULL) - goto end; - if (sig->next->next->next != NULL) - goto end; - if (de_ctx->signum != 3) - goto end; - - sig = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.1.1 any -> any any (msg:\"SigTestBidirec03 sid 3\"; sid:3;)"); - if (sig == NULL) - goto end; - if (sig->next == NULL) - goto end; - if (sig->next->next == NULL) - goto end; - if (sig->next->next->next == NULL) - goto end; - if (sig->next->next->next->next != NULL) - goto end; - if (de_ctx->signum != 4) - goto end; - - uint8_t rawpkt1_ether[] = { - 0x00,0x50,0x56,0xea,0x00,0xbd,0x00,0x0c, - 0x29,0x40,0xc8,0xb5,0x08,0x00,0x45,0x00, - 0x01,0xa8,0xb9,0xbb,0x40,0x00,0x40,0x06, - 0xe0,0xbf,0xc0,0xa8,0x1c,0x83,0xc0,0xa8, - 0x01,0x01,0xb9,0x0a,0x00,0x50,0x6f,0xa2, - 0x92,0xed,0x7b,0xc1,0xd3,0x4d,0x50,0x18, - 0x16,0xd0,0xa0,0x6f,0x00,0x00,0x47,0x45, - 0x54,0x20,0x2f,0x20,0x48,0x54,0x54,0x50, - 0x2f,0x31,0x2e,0x31,0x0d,0x0a,0x48,0x6f, - 0x73,0x74,0x3a,0x20,0x31,0x39,0x32,0x2e, - 0x31,0x36,0x38,0x2e,0x31,0x2e,0x31,0x0d, - 0x0a,0x55,0x73,0x65,0x72,0x2d,0x41,0x67, - 0x65,0x6e,0x74,0x3a,0x20,0x4d,0x6f,0x7a, - 0x69,0x6c,0x6c,0x61,0x2f,0x35,0x2e,0x30, - 0x20,0x28,0x58,0x31,0x31,0x3b,0x20,0x55, - 0x3b,0x20,0x4c,0x69,0x6e,0x75,0x78,0x20, - 0x78,0x38,0x36,0x5f,0x36,0x34,0x3b,0x20, - 0x65,0x6e,0x2d,0x55,0x53,0x3b,0x20,0x72, - 0x76,0x3a,0x31,0x2e,0x39,0x2e,0x30,0x2e, - 0x31,0x34,0x29,0x20,0x47,0x65,0x63,0x6b, - 0x6f,0x2f,0x32,0x30,0x30,0x39,0x30,0x39, - 0x30,0x32,0x31,0x37,0x20,0x55,0x62,0x75, - 0x6e,0x74,0x75,0x2f,0x39,0x2e,0x30,0x34, - 0x20,0x28,0x6a,0x61,0x75,0x6e,0x74,0x79, - 0x29,0x20,0x46,0x69,0x72,0x65,0x66,0x6f, - 0x78,0x2f,0x33,0x2e,0x30,0x2e,0x31,0x34, - 0x0d,0x0a,0x41,0x63,0x63,0x65,0x70,0x74, - 0x3a,0x20,0x74,0x65,0x78,0x74,0x2f,0x68, - 0x74,0x6d,0x6c,0x2c,0x61,0x70,0x70,0x6c, - 0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f, - 0x78,0x68,0x74,0x6d,0x6c,0x2b,0x78,0x6d, - 0x6c,0x2c,0x61,0x70,0x70,0x6c,0x69,0x63, - 0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d, - 0x6c,0x3b,0x71,0x3d,0x30,0x2e,0x39,0x2c, - 0x2a,0x2f,0x2a,0x3b,0x71,0x3d,0x30,0x2e, - 0x38,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70, - 0x74,0x2d,0x4c,0x61,0x6e,0x67,0x75,0x61, - 0x67,0x65,0x3a,0x20,0x65,0x6e,0x2d,0x75, - 0x73,0x2c,0x65,0x6e,0x3b,0x71,0x3d,0x30, - 0x2e,0x35,0x0d,0x0a,0x41,0x63,0x63,0x65, - 0x70,0x74,0x2d,0x45,0x6e,0x63,0x6f,0x64, - 0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69, - 0x70,0x2c,0x64,0x65,0x66,0x6c,0x61,0x74, - 0x65,0x0d,0x0a,0x41,0x63,0x63,0x65,0x70, - 0x74,0x2d,0x43,0x68,0x61,0x72,0x73,0x65, - 0x74,0x3a,0x20,0x49,0x53,0x4f,0x2d,0x38, - 0x38,0x35,0x39,0x2d,0x31,0x2c,0x75,0x74, - 0x66,0x2d,0x38,0x3b,0x71,0x3d,0x30,0x2e, - 0x37,0x2c,0x2a,0x3b,0x71,0x3d,0x30,0x2e, - 0x37,0x0d,0x0a,0x4b,0x65,0x65,0x70,0x2d, - 0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x33, - 0x30,0x30,0x0d,0x0a,0x43,0x6f,0x6e,0x6e, - 0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20, - 0x6b,0x65,0x65,0x70,0x2d,0x61,0x6c,0x69, - 0x76,0x65,0x0d,0x0a,0x0d,0x0a }; /* end rawpkt1_ether */ - - p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - - FlowInitConfig(FLOW_QUIET); - DecodeEthernet(&th_v, &dtv, p, rawpkt1_ether, sizeof(rawpkt1_ether), NULL); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* At this point we have a list of 4 signatures. The last one - is a copy of the second one. If we receive a packet - with source 192.168.1.1 80, all the sids should match */ - - SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, MPM_B2G); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* only sid 2 should match with a packet going to 192.168.1.1 port 80 */ - if (PacketAlertCheck(p, 1) <= 0 && PacketAlertCheck(p, 3) <= 0 && - PacketAlertCheck(p, 2) == 1) { - result = 1; - } - - if (p != NULL) { - PACKET_RECYCLE(p); - } - FlowShutdown(); - //PatternMatchDestroy(mpm_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - -end: - if (de_ctx != NULL) { - SigCleanSignatures(de_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - if (p != NULL) - SCFree(p); - return result; -} - -/** - * \test check that we don't allow invalid negation options - */ -static int SigParseTestNegation01 (void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tcp !any any -> any any (msg:\"SigTest41-01 src address is !any \"; classtype:misc-activity; sid:410001; rev:1;)"); - if (s != NULL) { - SigFree(s); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test check that we don't allow invalid negation options - */ -static int SigParseTestNegation02 (void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tcp any !any -> any any (msg:\"SigTest41-02 src ip is !any \"; classtype:misc-activity; sid:410002; rev:1;)"); - if (s != NULL) { - SigFree(s); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} -/** - * \test check that we don't allow invalid negation options - */ -static int SigParseTestNegation03 (void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tcp any any -> any [80:!80] (msg:\"SigTest41-03 dst port [80:!80] \"; classtype:misc-activity; sid:410003; rev:1;)"); - if (s != NULL) { - SigFree(s); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} -/** - * \test check that we don't allow invalid negation options - */ -static int SigParseTestNegation04 (void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tcp any any -> any [80,!80] (msg:\"SigTest41-03 dst port [80:!80] \"; classtype:misc-activity; sid:410003; rev:1;)"); - if (s != NULL) { - SigFree(s); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} -/** - * \test check that we don't allow invalid negation options - */ -static int SigParseTestNegation05 (void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tcp any any -> [192.168.0.2,!192.168.0.2] any (msg:\"SigTest41-04 dst ip [192.168.0.2,!192.168.0.2] \"; classtype:misc-activity; sid:410004; rev:1;)"); - if (s != NULL) { - SigFree(s); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} -/** - * \test check that we don't allow invalid negation options - */ -static int SigParseTestNegation06 (void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tcp any any -> any [100:1000,!1:20000] (msg:\"SigTest41-05 dst port [100:1000,!1:20000] \"; classtype:misc-activity; sid:410005; rev:1;)"); - if (s != NULL) { - SigFree(s); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test check that we don't allow invalid negation options - */ -static int SigParseTestNegation07 (void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tcp any any -> [192.168.0.2,!192.168.0.0/24] any (msg:\"SigTest41-06 dst ip [192.168.0.2,!192.168.0.0/24] \"; classtype:misc-activity; sid:410006; rev:1;)"); - if (s != NULL) { - SigFree(s); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test check valid negation bug 1079 - */ -static int SigParseTestNegation08 (void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tcp any any -> [192.168.0.0/16,!192.168.0.0/24] any (sid:410006; rev:1;)"); - if (s == NULL) { - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test mpm - */ -int SigParseTestMpm01 (void) -{ - int result = 0; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; sid:1;)"); - if (sig == NULL) { - printf("sig failed to init: "); - goto end; - } - - if (sig->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("sig doesn't have content list: "); - goto end; - } - - result = 1; -end: - if (sig != NULL) - SigFree(sig); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test mpm - */ -int SigParseTestMpm02 (void) -{ - int result = 0; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - sig = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"mpm test\"; content:\"abcd\"; content:\"abcdef\"; sid:1;)"); - if (sig == NULL) { - printf("sig failed to init: "); - goto end; - } - - if (sig->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("sig doesn't have content list: "); - goto end; - } - - result = 1; -end: - if (sig != NULL) - SigFree(sig); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test test tls (app layer) rule - */ -static int SigParseTestAppLayerTLS01(void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS01 \"; sid:410006; rev:1;)"); - if (s == NULL) { - printf("parsing sig failed: "); - goto end; - } - - if (s->alproto == 0) { - printf("alproto not set: "); - goto end; - } - - result = 1; -end: - if (s != NULL) - SigFree(s); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test test tls (app layer) rule - */ -static int SigParseTestAppLayerTLS02(void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS02 \"; tls.version:1.0; sid:410006; rev:1;)"); - if (s == NULL) { - printf("parsing sig failed: "); - goto end; - } - - if (s->alproto == 0) { - printf("alproto not set: "); - goto end; - } - - result = 1; -end: - if (s != NULL) - SigFree(s); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test test tls (app layer) rule - */ -static int SigParseTestAppLayerTLS03(void) -{ - int result = 0; - DetectEngineCtx *de_ctx; - Signature *s=NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx,"alert tls any any -> any any (msg:\"SigParseTestAppLayerTLS03 \"; tls.version:2.5; sid:410006; rev:1;)"); - if (s != NULL) { - SigFree(s); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -void SigParseRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SigParseTest01", SigParseTest01, 1); - UtRegisterTest("SigParseTest02", SigParseTest02, 1); - UtRegisterTest("SigParseTest03", SigParseTest03, 1); - UtRegisterTest("SigParseTest04", SigParseTest04, 1); - UtRegisterTest("SigParseTest05", SigParseTest05, 1); - UtRegisterTest("SigParseTest06", SigParseTest06, 1); - UtRegisterTest("SigParseTest07", SigParseTest07, 1); - UtRegisterTest("SigParseTest08", SigParseTest08, 1); - UtRegisterTest("SigParseTest09", SigParseTest09, 1); - UtRegisterTest("SigParseTest10", SigParseTest10, 1); - UtRegisterTest("SigParseTest11", SigParseTest11, 1); - UtRegisterTest("SigParseTest12", SigParseTest12, 1); - UtRegisterTest("SigParseTest13", SigParseTest13, 1); - UtRegisterTest("SigParseTest14", SigParseTest14, 1); - UtRegisterTest("SigParseTest15", SigParseTest15, 1); - UtRegisterTest("SigParseTest16", SigParseTest16, 1); - UtRegisterTest("SigParseTest17", SigParseTest17, 1); - UtRegisterTest("SigParseTest18", SigParseTest18, 1); - UtRegisterTest("SigParseTest19", SigParseTest19, 1); - UtRegisterTest("SigParseTest20", SigParseTest20, 1); - UtRegisterTest("SigParseTest21 -- address with space", SigParseTest21, 1); - UtRegisterTest("SigParseTest22 -- address with space", SigParseTest22, 1); - - UtRegisterTest("SigParseBidirecTest06", SigParseBidirecTest06, 1); - UtRegisterTest("SigParseBidirecTest07", SigParseBidirecTest07, 1); - UtRegisterTest("SigParseBidirecTest08", SigParseBidirecTest08, 1); - UtRegisterTest("SigParseBidirecTest09", SigParseBidirecTest09, 1); - UtRegisterTest("SigParseBidirecTest10", SigParseBidirecTest10, 1); - UtRegisterTest("SigParseBidirecTest11", SigParseBidirecTest11, 1); - UtRegisterTest("SigParseBidirecTest12", SigParseBidirecTest12, 1); - UtRegisterTest("SigParseBidirecTest13", SigParseBidirecTest13, 1); - UtRegisterTest("SigParseBidirecTest14", SigParseBidirecTest14, 1); - UtRegisterTest("SigTestBidirec01", SigTestBidirec01, 1); - UtRegisterTest("SigTestBidirec02", SigTestBidirec02, 1); - UtRegisterTest("SigTestBidirec03", SigTestBidirec03, 1); - UtRegisterTest("SigTestBidirec04", SigTestBidirec04, 1); - UtRegisterTest("SigParseTestNegation01", SigParseTestNegation01, 1); - UtRegisterTest("SigParseTestNegation02", SigParseTestNegation02, 1); - UtRegisterTest("SigParseTestNegation03", SigParseTestNegation03, 1); - UtRegisterTest("SigParseTestNegation04", SigParseTestNegation04, 1); - UtRegisterTest("SigParseTestNegation05", SigParseTestNegation05, 1); - UtRegisterTest("SigParseTestNegation06", SigParseTestNegation06, 1); - UtRegisterTest("SigParseTestNegation07", SigParseTestNegation07, 1); - UtRegisterTest("SigParseTestNegation08", SigParseTestNegation08, 1); - UtRegisterTest("SigParseTestMpm01", SigParseTestMpm01, 1); - UtRegisterTest("SigParseTestMpm02", SigParseTestMpm02, 1); - UtRegisterTest("SigParseTestAppLayerTLS01", SigParseTestAppLayerTLS01, 1); - UtRegisterTest("SigParseTestAppLayerTLS02", SigParseTestAppLayerTLS02, 1); - UtRegisterTest("SigParseTestAppLayerTLS03", SigParseTestAppLayerTLS03, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-parse.h b/framework/src/suricata/src/detect-parse.h deleted file mode 100644 index c90560a9..00000000 --- a/framework/src/suricata/src/detect-parse.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_PARSE_H__ -#define __DETECT_PARSE_H__ - -/** Flags to indicate if the Signature parsing must be done -* switching the source and dest (for ip addresses and ports) -* or otherwise as normal */ -enum { - SIG_DIREC_NORMAL, - SIG_DIREC_SWITCHED -}; - -/** Flags to indicate if are referencing the source of the Signature -* or the destination (for ip addresses and ports)*/ -enum { - SIG_DIREC_SRC, - SIG_DIREC_DST -}; - -/* prototypes */ -int SigParse(DetectEngineCtx *,Signature *, char *, uint8_t); -Signature *SigAlloc(void); -void SigFree(Signature *s); -Signature *SigInit(DetectEngineCtx *,char *sigstr); -Signature *SigInitReal(DetectEngineCtx *, char *); -SigMatch *SigMatchGetLastSMFromLists(Signature *, int, ...); -void SigMatchTransferSigMatchAcrossLists(SigMatch *sm, - SigMatch **, SigMatch **s, - SigMatch **, SigMatch **); -void SigParsePrepare(void); -void SigParseRegisterTests(void); -Signature *DetectEngineAppendSig(DetectEngineCtx *, char *); - -void SigMatchAppendSMToList(Signature *, SigMatch *, int); -void SigMatchRemoveSMFromList(Signature *, SigMatch *, int); -int SigMatchListSMBelongsTo(Signature *, SigMatch *); - -int DetectParseDupSigHashInit(DetectEngineCtx *); -void DetectParseDupSigHashFree(DetectEngineCtx *); - -int DetectEngineContentModifierBufferSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg, - uint8_t sm_type, uint8_t sm_list, - AppProto alproto, void (*CustomCallback)(Signature *s)); - -#endif /* __DETECT_PARSE_H__ */ - diff --git a/framework/src/suricata/src/detect-pcre.c b/framework/src/suricata/src/detect-pcre.c deleted file mode 100644 index d69f1da6..00000000 --- a/framework/src/suricata/src/detect-pcre.c +++ /dev/null @@ -1,4193 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the pcre keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "pkt-var.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "detect-pcre.h" -#include "detect-flowvar.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-sigorder.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "util-var-name.h" -#include "util-unittest-helper.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-print.h" -#include "util-pool.h" - -#include "conf.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "stream.h" -#include "stream-tcp.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "app-layer-protos.h" -#include "app-layer-parser.h" -#include "app-layer-htp.h" - -#include "stream.h" - - -#define PARSE_CAPTURE_REGEX "\\(\\?P\\<([A-z]+)\\_([A-z0-9_]+)\\>" -#define PARSE_REGEX "(?ctx; - - if (pe->flags & DETECT_PCRE_RELATIVE) { - ptr = payload + det_ctx->buffer_offset; - len = payload_len - det_ctx->buffer_offset; - } else { - ptr = payload; - len = payload_len; - } - - int start_offset = 0; - if (det_ctx->pcre_match_start_offset != 0) { - start_offset = (payload + det_ctx->pcre_match_start_offset - ptr); - } - - /* run the actual pcre detection */ - ret = pcre_exec(pe->re, pe->sd, (char *)ptr, len, start_offset, 0, ov, MAX_SUBSTRINGS); - SCLogDebug("ret %d (negating %s)", ret, (pe->flags & DETECT_PCRE_NEGATE) ? "set" : "not set"); - - if (ret == PCRE_ERROR_NOMATCH) { - if (pe->flags & DETECT_PCRE_NEGATE) { - /* regex didn't match with negate option means we - * consider it a match */ - ret = 1; - } else { - ret = 0; - } - } else if (ret >= 0) { - if (pe->flags & DETECT_PCRE_NEGATE) { - /* regex matched but we're negated, so not - * considering it a match */ - ret = 0; - } else { - /* regex matched and we're not negated, - * considering it a match */ - - SCLogDebug("ret %d capidx %u", ret, pe->capidx); - - /* see if we need to do substring capturing. */ - if (ret > 1 && pe->capidx != 0) { - SCLogDebug("capturing"); - const char *str_ptr; - ret = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (ret) { - if (pe->flags & DETECT_PCRE_CAPTURE_PKT) { - if (p != NULL) { - PktVarAdd(p, pe->capname, (uint8_t *)str_ptr, ret); - } - } else if (pe->flags & DETECT_PCRE_CAPTURE_FLOW) { - if (f != NULL) { - /* store max 64k. Errors are ignored */ - capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff; - (void)DetectFlowvarStoreMatch(det_ctx, pe->capidx, - (uint8_t *)str_ptr, capture_len, - DETECT_FLOWVAR_TYPE_POSTMATCH); - } - } - } - } - - /* update offset for pcre RELATIVE */ - det_ctx->buffer_offset = (ptr + ov[1]) - payload; - det_ctx->pcre_match_start_offset = (ptr + ov[0] + 1) - payload; - - ret = 1; - } - - } else { - SCLogDebug("pcre had matching error"); - ret = 0; - } - SCReturnInt(ret); -} - -static int DetectPcreSetList(int list, int set) -{ - if (list != DETECT_SM_LIST_NOTSET) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "only one pcre option to specify a buffer type is allowed"); - return -1; - } - return set; -} - -static int DetectPcreHasUpperCase(const char *re) -{ - size_t len = strlen(re); - int is_meta = 0; - - for (size_t i = 0; i < len; i++) { - if (is_meta) { - is_meta = 0; - } - else if (re[i] == '\\') { - is_meta = 1; - } - else if (isupper((unsigned char)re[i])) { - return 1; - } - } - - return 0; -} - -static DetectPcreData *DetectPcreParse (DetectEngineCtx *de_ctx, char *regexstr, int *sm_list) -{ - int ec; - const char *eb; - int eo; - int opts = 0; - DetectPcreData *pd = NULL; - char *op = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - size_t slen = strlen(regexstr); - char re[slen], op_str[64] = ""; - uint16_t pos = 0; - uint8_t negate = 0; - - while (pos < slen && isspace((unsigned char)regexstr[pos])) { - pos++; - } - - if (regexstr[pos] == '!') { - negate = 1; - pos++; - } - - ret = pcre_exec(parse_regex, parse_regex_study, regexstr + pos, slen-pos, - 0, 0, ov, MAX_SUBSTRINGS); - if (ret <= 0) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre parse error: %s", regexstr); - goto error; - } - - res = pcre_copy_substring((char *)regexstr + pos, ov, MAX_SUBSTRINGS, - 1, re, slen); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return NULL; - } - - if (ret > 2) { - res = pcre_copy_substring((char *)regexstr + pos, ov, MAX_SUBSTRINGS, - 2, op_str, sizeof(op_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return NULL; - } - op = op_str; - } - //printf("ret %" PRId32 " re \'%s\', op \'%s\'\n", ret, re, op); - - pd = SCMalloc(sizeof(DetectPcreData)); - if (unlikely(pd == NULL)) - goto error; - memset(pd, 0, sizeof(DetectPcreData)); - - if (negate) - pd->flags |= DETECT_PCRE_NEGATE; - - if (op != NULL) { - while (*op) { - SCLogDebug("regex option %c", *op); - - switch (*op) { - case 'A': - opts |= PCRE_ANCHORED; - break; - case 'E': - opts |= PCRE_DOLLAR_ENDONLY; - break; - case 'G': - opts |= PCRE_UNGREEDY; - break; - - case 'i': - opts |= PCRE_CASELESS; - pd->flags |= DETECT_PCRE_CASELESS; - break; - case 'm': - opts |= PCRE_MULTILINE; - break; - case 's': - opts |= PCRE_DOTALL; - break; - case 'x': - opts |= PCRE_EXTENDED; - break; - - case 'O': - pd->flags |= DETECT_PCRE_MATCH_LIMIT; - break; - - case 'B': /* snort's option */ - if (*sm_list != DETECT_SM_LIST_NOTSET) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'B' inconsistent with chosen buffer"); - goto error; - } - pd->flags |= DETECT_PCRE_RAWBYTES; - break; - case 'R': /* snort's option */ - pd->flags |= DETECT_PCRE_RELATIVE; - break; - - /* buffer selection */ - - case 'U': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'U' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_UMATCH); - break; - case 'V': - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'V' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HUADMATCH); - break; - case 'W': - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'W' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HHHDMATCH); - break; - case 'Z': - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'Z' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HRHHDMATCH); - break; - case 'H': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'H' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HHDMATCH); - break; - case 'I': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'I' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HRUDMATCH); - break; - case 'D': /* snort's option */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HRHDMATCH); - break; - case 'M': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'M' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HMDMATCH); - break; - case 'C': /* snort's option */ - if (pd->flags & DETECT_PCRE_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "regex modifier 'C' inconsistent with 'B'"); - goto error; - } - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HCDMATCH); - break; - case 'P': - /* snort's option (http request body inspection) */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HCBDMATCH); - break; - case 'Q': - /* suricata extension (http response body inspection) */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_FILEDATA); - break; - case 'Y': - /* snort's option */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HSMDMATCH); - break; - case 'S': - /* snort's option */ - *sm_list = DetectPcreSetList(*sm_list, DETECT_SM_LIST_HSCDMATCH); - break; - default: - SCLogError(SC_ERR_UNKNOWN_REGEX_MOD, "unknown regex modifier '%c'", *op); - goto error; - } - op++; - } - } - if (*sm_list == -1) - goto error; - - SCLogDebug("DetectPcreParse: \"%s\"", re); - - /* host header */ - if (*sm_list == DETECT_SM_LIST_HHHDMATCH) { - if (pd->flags & DETECT_PCRE_CASELESS) { - SCLogWarning(SC_ERR_INVALID_SIGNATURE, "http host pcre(\"W\") " - "specified along with \"i(caseless)\" modifier. " - "Since the hostname buffer we match against " - "is actually lowercase, having a " - "nocase is redundant."); - } - else if (DetectPcreHasUpperCase(re)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre host(\"W\") " - "specified has an uppercase char. " - "Since the hostname buffer we match against " - "is actually lowercase, please specify an " - "all lowercase based pcre."); - goto error; - } - } - - /* Try to compile as if all (...) groups had been meant as (?:...), - * which is the common case in most rules. - * If we fail because a capture group is later referenced (e.g., \1), - * PCRE will let us know. - */ - pd->re = pcre_compile2(re, opts | PCRE_NO_AUTO_CAPTURE, &ec, &eb, &eo, NULL); - if (pd->re == NULL && ec == 15) { // reference to non-existent subpattern - pd->re = pcre_compile(re, opts, &eb, &eo, NULL); - } - - if(pd->re == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", regexstr, eo, eb); - goto error; - } -#ifdef PCRE_HAVE_JIT - pd->sd = pcre_study(pd->re, PCRE_STUDY_JIT_COMPILE, &eb); - if(eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed : %s", eb); - goto error; - } - - int jit = 0; - ret = pcre_fullinfo(pd->re, pd->sd, PCRE_INFO_JIT, &jit); - if (ret != 0 || jit != 1) { - /* warning, so we won't print the sig after this. Adding - * file and line to the message so the admin can figure - * out what sig this is about */ - SCLogDebug("PCRE JIT compiler does not support: %s. " - "Falling back to regular PCRE handling (%s:%d)", - regexstr, de_ctx->rule_file, de_ctx->rule_line); - } -#else - pd->sd = pcre_study(pd->re, 0, &eb); - if(eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed : %s", eb); - goto error; - } -#endif /*PCRE_HAVE_JIT*/ - - if (pd->sd == NULL) - pd->sd = (pcre_extra *) SCCalloc(1,sizeof(pcre_extra)); - - if (pd->sd) { - if(pd->flags & DETECT_PCRE_MATCH_LIMIT) { - if(pcre_match_limit >= -1) { - pd->sd->match_limit = pcre_match_limit; - pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT; - } -#ifndef NO_PCRE_MATCH_RLIMIT - if(pcre_match_limit_recursion >= -1) { - pd->sd->match_limit_recursion = pcre_match_limit_recursion; - pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; - } -#endif /* NO_PCRE_MATCH_RLIMIT */ - } else { - pd->sd->match_limit = SC_MATCH_LIMIT_DEFAULT; - pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT; -#ifndef NO_PCRE_MATCH_RLIMIT - pd->sd->match_limit_recursion = SC_MATCH_LIMIT_RECURSION_DEFAULT; - pd->sd->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; -#endif /* NO_PCRE_MATCH_RLIMIT */ - } - } else { - goto error; - } - - return pd; - -error: - if (pd != NULL && pd->re != NULL) - pcre_free(pd->re); - if (pd != NULL && pd->sd != NULL) - pcre_free(pd->sd); - if (pd) - SCFree(pd); - return NULL; -} - -/** \internal - * \brief check if we need to extract capture settings and set them up if needed - */ -static int DetectPcreParseCapture(char *regexstr, DetectEngineCtx *de_ctx, DetectPcreData *pd) -{ - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - char type_str[16] = ""; - size_t cap_buffer_len = strlen(regexstr); - char capture_str[cap_buffer_len]; - memset(capture_str, 0x00, cap_buffer_len); - - if (de_ctx == NULL) - goto error; - - SCLogDebug("\'%s\'", regexstr); - - ret = pcre_exec(parse_capture_regex, parse_capture_regex_study, regexstr, strlen(regexstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 3) { - return 0; - } - - res = pcre_copy_substring((char *)regexstr, ov, MAX_SUBSTRINGS, 1, type_str, sizeof(type_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - res = pcre_copy_substring((char *)regexstr, ov, MAX_SUBSTRINGS, 2, capture_str, cap_buffer_len); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - if (strlen(capture_str) == 0 || strlen(type_str) == 0) { - goto error; - } - - SCLogDebug("type \'%s\'", type_str); - SCLogDebug("capture \'%s\'", capture_str); - - pd->capname = SCStrdup(capture_str); - if (unlikely(pd->capname == NULL)) - goto error; - - if (strcmp(type_str, "pkt") == 0) { - pd->flags |= DETECT_PCRE_CAPTURE_PKT; - } else if (strcmp(type_str, "flow") == 0) { - pd->flags |= DETECT_PCRE_CAPTURE_FLOW; - SCLogDebug("flow capture"); - } - if (pd->capname != NULL) { - if (pd->flags & DETECT_PCRE_CAPTURE_PKT) - pd->capidx = VariableNameGetIdx(de_ctx, (char *)pd->capname, VAR_TYPE_PKT_VAR); - else if (pd->flags & DETECT_PCRE_CAPTURE_FLOW) - pd->capidx = VariableNameGetIdx(de_ctx, (char *)pd->capname, VAR_TYPE_FLOW_VAR); - } - - SCLogDebug("pd->capname %s", pd->capname); - return 0; - -error: - if (pd->capname != NULL) { - SCFree(pd->capname); - pd->capname = NULL; - } - return -1; -} - -static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexstr) -{ - SCEnter(); - DetectPcreData *pd = NULL; - SigMatch *sm = NULL; - int ret = -1; - int parsed_sm_list = DETECT_SM_LIST_NOTSET; - - pd = DetectPcreParse(de_ctx, regexstr, &parsed_sm_list); - if (pd == NULL) - goto error; - if (DetectPcreParseCapture(regexstr, de_ctx, pd) < 0) - goto error; - - if (parsed_sm_list == DETECT_SM_LIST_UMATCH || - parsed_sm_list == DETECT_SM_LIST_HRUDMATCH || - parsed_sm_list == DETECT_SM_LIST_HCBDMATCH || - parsed_sm_list == DETECT_SM_LIST_FILEDATA || - parsed_sm_list == DETECT_SM_LIST_HHDMATCH || - parsed_sm_list == DETECT_SM_LIST_HRHDMATCH || - parsed_sm_list == DETECT_SM_LIST_HSMDMATCH || - parsed_sm_list == DETECT_SM_LIST_HSCDMATCH || - parsed_sm_list == DETECT_SM_LIST_HHHDMATCH || - parsed_sm_list == DETECT_SM_LIST_HRHHDMATCH || - parsed_sm_list == DETECT_SM_LIST_HMDMATCH || - parsed_sm_list == DETECT_SM_LIST_HCDMATCH || - parsed_sm_list == DETECT_SM_LIST_HUADMATCH) - { - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. " - "Conflicting alprotos detected for this rule. Http " - "pcre modifier found along with a different protocol " - "for the rule."); - goto error; - } - if (s->list != DETECT_SM_LIST_NOTSET) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre found with http " - "modifier set, with file_data/dce_stub_data sticky " - "option set."); - goto error; - } - } - - int sm_list = -1; - if (s->list != DETECT_SM_LIST_NOTSET) { - if (s->list == DETECT_SM_LIST_FILEDATA) { - SCLogDebug("adding to http server body list because of file data"); - AppLayerHtpEnableResponseBodyCallback(); - } else if (s->list == DETECT_SM_LIST_DMATCH) { - SCLogDebug("adding to dmatch list because of dce_stub_data"); - } else if (s->list == DETECT_SM_LIST_DNSQUERYNAME_MATCH) { - SCLogDebug("adding to DETECT_SM_LIST_DNSQUERYNAME_MATCH list because of dns_query"); - } - s->flags |= SIG_FLAG_APPLAYER; - sm_list = s->list; - } else { - switch(parsed_sm_list) { - case DETECT_SM_LIST_HCBDMATCH: - AppLayerHtpEnableRequestBodyCallback(); - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_HTTP; - sm_list = parsed_sm_list; - break; - - case DETECT_SM_LIST_FILEDATA: - AppLayerHtpEnableResponseBodyCallback(); - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_HTTP; - sm_list = parsed_sm_list; - break; - - case DETECT_SM_LIST_UMATCH: - case DETECT_SM_LIST_HRUDMATCH: - case DETECT_SM_LIST_HHDMATCH: - case DETECT_SM_LIST_HRHDMATCH: - case DETECT_SM_LIST_HHHDMATCH: - case DETECT_SM_LIST_HRHHDMATCH: - case DETECT_SM_LIST_HSMDMATCH: - case DETECT_SM_LIST_HSCDMATCH: - case DETECT_SM_LIST_HCDMATCH: - case DETECT_SM_LIST_HMDMATCH: - case DETECT_SM_LIST_HUADMATCH: - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_HTTP; - sm_list = parsed_sm_list; - break; - case DETECT_SM_LIST_NOTSET: - sm_list = DETECT_SM_LIST_PMATCH; - break; - } - } - if (sm_list == -1) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - sm->type = DETECT_PCRE; - sm->ctx = (void *)pd; - SigMatchAppendSMToList(s, sm, sm_list); - - if (pd->capidx != 0) { - if (DetectFlowvarPostMatchSetup(s, pd->capidx) < 0) - goto error_nofree; - } - - if (!(pd->flags & DETECT_PCRE_RELATIVE)) - goto okay; - - /* errors below shouldn't free pd */ - - SigMatch *prev_pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, sm->prev, - DETECT_PCRE, sm->prev); - if (s->list == DETECT_SM_LIST_NOTSET && prev_pm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre with /R (relative) needs " - "preceeding match in the same buffer"); - goto error_nofree; - /* null is allowed when we use a sticky buffer */ - } else if (prev_pm == NULL) - goto okay; - if (prev_pm->type == DETECT_CONTENT) { - DetectContentData *cd = (DetectContentData *)prev_pm->ctx; - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - } else if (prev_pm->type == DETECT_PCRE) { - DetectPcreData *tmp = (DetectPcreData *)prev_pm->ctx; - tmp->flags |= DETECT_PCRE_RELATIVE_NEXT; - } - - okay: - ret = 0; - SCReturnInt(ret); - error: - DetectPcreFree(pd); - error_nofree: - SCReturnInt(ret); -} - -void DetectPcreFree(void *ptr) -{ - if (ptr == NULL) - return; - - DetectPcreData *pd = (DetectPcreData *)ptr; - - if (pd->capname != NULL) - SCFree(pd->capname); - if (pd->re != NULL) - pcre_free(pd->re); - if (pd->sd != NULL) - pcre_free(pd->sd); - - SCFree(pd); - return; -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectPcreParseTest01 make sure we don't allow invalid opts 7. - */ -static int DetectPcreParseTest01 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/blah/7"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd != NULL) { - printf("expected NULL: got %p", pd); - result = 0; - DetectPcreFree(pd); - } - - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest02 make sure we don't allow invalid opts Ui$. - */ -static int DetectPcreParseTest02 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/blah/Ui$"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd != NULL) { - printf("expected NULL: got %p", pd); - result = 0; - DetectPcreFree(pd); - } - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest03 make sure we don't allow invalid opts UZi. - */ -static int DetectPcreParseTest03 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/blah/UNi"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd != NULL) { - printf("expected NULL: got %p", pd); - result = 0; - DetectPcreFree(pd); - } - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest04 make sure we allow escaped " - */ -static int DetectPcreParseTest04 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/b\\\"lah/i"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest05 make sure we parse pcre with no opts - */ -static int DetectPcreParseTest05 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/b(l|a)h/"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest06 make sure we parse pcre with smi opts - */ -static int DetectPcreParseTest06 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/b(l|a)h/smi"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest07 make sure we parse pcre with /Ui opts - */ -static int DetectPcreParseTest07 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/blah/Ui"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest08 make sure we parse pcre with O opts - */ -static int DetectPcreParseTest08 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/b(l|a)h/O"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test DetectPcreParseTest09 make sure we parse pcre with a content - * that has slashes - */ -static int DetectPcreParseTest09 (void) -{ - int result = 1; - DetectPcreData *pd = NULL; - char *teststring = "/lala\\\\/"; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return 0; - - pd = DetectPcreParse(de_ctx, teststring, &list); - if (pd == NULL) { - printf("expected %p: got NULL", pd); - result = 0; - } - - DetectPcreFree(pd); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Test pcre option for dce sig(yeah I'm bored of writing test titles). - */ -int DetectPcreParseTest10(void) -{ - Signature *s = SigAlloc(); - int result = 1; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - result = 0; - goto end; - } - - s->alproto = ALPROTO_DCERPC; - - result &= (DetectPcreSetup(de_ctx, s, "/bamboo/") == 0); - result &= (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - - SigFree(s); - - s = SigAlloc(); - /* failure since we have no preceding content/pcre/bytejump */ - result &= (DetectPcreSetup(de_ctx, s, "/bamboo/") == 0); - result &= (s->sm_lists[DETECT_SM_LIST_DMATCH] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL); - - end: - SigFree(s); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test pcre option for dce sig. - */ -int DetectPcreParseTest11(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - Signature *s = NULL; - DetectPcreData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "pcre:/bamboo/R; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_PCRE); - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - !(data->flags & DETECT_PCRE_RELATIVE)) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "pcre:/bamboo/R; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_PCRE); - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - !(data->flags & DETECT_PCRE_RELATIVE)) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; " - "dce_stub_data; " - "pcre:/bamboo/RB; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] == NULL) { - result = 0; - goto end; - } - result &= (s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->type == DETECT_PCRE); - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_DMATCH]->ctx; - if (!(data->flags & DETECT_PCRE_RAWBYTES) || - !(data->flags & DETECT_PCRE_RELATIVE)) { - result = 0; - goto end; - } - - s->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing bytejump_body\"; " - "content:\"one\"; pcre:/bamboo/; sid:1;)"); - if (s->next == NULL) { - result = 0; - goto end; - } - s = s->next; - if (s->sm_lists_tail[DETECT_SM_LIST_DMATCH] != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test pcre option with file data. pcre is relative to file_data, - * so relative flag should be unset. - */ -static int DetectPcreParseTest12(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectPcreData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; pcre:/abc/R; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("empty server body list: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_PCRE) { - printf("last sm not pcre: "); - goto end; - } - - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - !(data->flags & DETECT_PCRE_RELATIVE)) { - printf("flags not right: "); - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test pcre option with file data. - */ -static int DetectPcreParseTest13(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectPcreData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; content:\"abc\"; pcre:/def/R; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("empty server body list: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_PCRE) { - printf("last sm not pcre: "); - goto end; - } - - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - !(data->flags & DETECT_PCRE_RELATIVE)) { - printf("flags not right: "); - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test pcre option with file data. - */ -static int DetectPcreParseTest14(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Signature *s = NULL; - DetectPcreData *data = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; pcre:/def/; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - s = de_ctx->sig_list; - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA] == NULL) { - printf("empty server body list: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->type != DETECT_PCRE) { - printf("last sm not pcre: "); - goto end; - } - - data = (DetectPcreData *)s->sm_lists_tail[DETECT_SM_LIST_FILEDATA]->ctx; - if (data->flags & DETECT_PCRE_RAWBYTES || - data->flags & DETECT_PCRE_RELATIVE) { - printf("flags not right: "); - goto end; - } - - result = 1; - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Check a signature with pcre relative method */ -int DetectPcreParseTest15(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing pcre relative http_method\"; " - "content:\"GET\"; " - "http_method; pcre:\"/abc/RM\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - - -/** \test Check a signature with pcre relative cookie */ -int DetectPcreParseTest16(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing pcre relative http_cookie\"; " - "content:\"test\"; " - "http_cookie; pcre:\"/abc/RC\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative raw header */ -int DetectPcreParseTest17(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing pcre relative http_raw_header\"; " - "flow:to_server; content:\"test\"; " - "http_raw_header; pcre:\"/abc/RD\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative header */ -int DetectPcreParseTest18(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing pcre relative http_header\"; " - "content:\"test\"; " - "http_header; pcre:\"/abc/RH\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative client-body */ -int DetectPcreParseTest19(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing pcre relativie http_client_body\"; " - "content:\"test\"; " - "http_client_body; pcre:\"/abc/RP\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative raw uri */ -int DetectPcreParseTest20(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_raw_uri\"; " - "content:\"test\"; " - "http_raw_uri; pcre:\"/abc/RI\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative uricontent */ -int DetectPcreParseTest21(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing pcre relative uricontent\"; " - "uricontent:\"test\"; " - "pcre:\"/abc/RU\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with pcre relative http_uri */ -int DetectPcreParseTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing pcre relative http_uri\"; " - "content:\"test\"; " - "http_uri; pcre:\"/abc/RU\"; sid:1;)"); - - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("sig parse failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with inconsistent pcre relative */ -int DetectPcreParseTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing inconsistent pcre relative\"; " - "content:\"GET\"; " - "http_cookie; pcre:\"/abc/RM\"; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse shouldn't have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with inconsistent pcre modifiers */ -int DetectPcreParseTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing inconsistent pcre modifiers\"; " - "pcre:\"/abc/UI\"; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse should have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with inconsistent pcre modifiers */ -int DetectPcreParseTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing inconsistent pcre modifiers\"; " - "pcre:\"/abc/DH\"; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse should have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check a signature with inconsistent pcre modifiers */ -static int DetectPcreParseTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert http any any -> any any " - "(msg:\"Testing inconsistent pcre modifiers\"; " - "pcre:\"/abc/F\"; sid:1;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse should have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Bug 1098 */ -static int DetectPcreParseTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any 80 " - "(content:\"baduricontent\"; http_raw_uri; " - "pcre:\"/^[a-z]{5}\\.html/R\"; sid:2; rev:2;)"); - - if (de_ctx->sig_list == NULL) { - result = 1; - } else { - printf("sig parse should have failed: "); - } - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectPcreTestSig01Real(int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - Flow f; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&th_v, 0, sizeof(th_v)); - memset(&ssn, 0, sizeof(TcpSession)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - f.alproto = ALPROTO_HTTP; - - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; pcre:\"/^gEt/i\"; pcre:\"/\\/two\\//U; pcre:\"/GET \\/two\\//\"; pcre:\"/\\s+HTTP/R\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, buf, buflen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 1) { - result = 1; - } - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} -static int DetectPcreTestSig01B2g (void) -{ - return DetectPcreTestSig01Real(MPM_B2G); -} -static int DetectPcreTestSig01B3g (void) -{ - return DetectPcreTestSig01Real(MPM_B3G); -} -static int DetectPcreTestSig01Wm (void) -{ - return DetectPcreTestSig01Real(MPM_WUMANBER); -} - -static int DetectPcreTestSig02Real(int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - Flow f; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - - FLOW_INITIALIZE(&f); - - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - pcre_match_limit = 100; - pcre_match_limit_recursion = 100; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; pcre:\"/two/O\"; sid:2;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 2) == 1) { - result = 1; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - FLOW_DESTROY(&f); -end: - UTHFreePackets(&p, 1); - return result; -} -static int DetectPcreTestSig02B2g (void) -{ - return DetectPcreTestSig02Real(MPM_B2G); -} -static int DetectPcreTestSig02B3g (void) -{ - return DetectPcreTestSig02Real(MPM_B3G); -} -static int DetectPcreTestSig02Wm (void) -{ - return DetectPcreTestSig02Real(MPM_WUMANBER); -} - -/** - * \test DetectPcreTestSig03Real negation test ! outside of "" this sig should not match - */ -static int DetectPcreTestSig03Real(int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 1; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - result = 0; - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; content:\"GET\"; pcre:!\"/two/\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)){ - printf("sid 1 matched even though it shouldn't have:"); - result = 0; - } - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} - -static int DetectPcreTestSig03B2g (void) -{ - return DetectPcreTestSig03Real(MPM_B2G); -} -static int DetectPcreTestSig03B3g (void) -{ - return DetectPcreTestSig03Real(MPM_B3G); -} -static int DetectPcreTestSig03Wm (void) -{ - return DetectPcreTestSig03Real(MPM_WUMANBER); -} - -/** - * \test Check the signature with pcre modifier P (match with L7 to http body data) - */ -static int DetectPcreModifPTest04(void) -{ - int result = 0; - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "X-Powered-By: PHP/5.2.5\r\n" - "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n" - "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n" - "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" - "Pragma: no-cache\r\n" - "Keep-Alive: timeout=15, max=100\r\n" - "Connection: Keep-Alive\r\n" - "Transfer-Encoding: chunked\r\n" - "Content-Type: text/html; charset=utf-8\r\n" - "\r\n" - "15" - "\r\n" - "flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"Pcre modifier P\"; pcre:\"/DOCTYPE/P\"; " - "sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"" - "Pcre modifier P (no match)\"; pcre:\"/blah/P\"; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - if (PacketAlertCheck(p, 2)) { - printf("sid 2 matched but shouldn't: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Check the signature with pcre modifier P (match with L7 to http body data) - * over fragmented chunks (DOCTYPE fragmented) - */ -static int DetectPcreModifPTest05(void) -{ - int result = 0; - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "X-Powered-By: PHP/5.2.5\r\n" - "P3P: CP=\"NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM\"\r\n" - "Expires: Mon, 1 Jan 2001 00:00:00 GMT\r\n" - "Last-Modified: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\n" - "Pragma: no-cache\r\n" - "Keep-Alive: timeout=15, max=100\r\n" - "Connection: Keep-Alive\r\n" - "Transfer-Encoding: chunked\r\n" - "Content-Type: text/html; charset=utf-8\r\n" - "\r\n" - "15" - "\r\n" - "flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"Pcre modifier P\"; pcre:\"/DOC/P\"; " - "sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"" - "Pcre modifier P (no match)\"; pcre:\"/DOCTYPE/P\"; sid:2;)"); - if (s->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 didn't match on p1 but should have: "); - goto end; - } - - if (PacketAlertCheck(p1, 2)) { - printf("sid 2 did match on p1 but shouldn't have: "); - /* It's a partial match over 2 chunks*/ - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect for p2 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 did match on p2 but should have: "); - goto end; - } - - if (!(PacketAlertCheck(p2, 2))) { - printf("sid 2 didn't match on p2 but should have: "); - /* It's a partial match over 2 chunks*/ - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - return result; -} - -int DetectPcreTestSig06() -{ - uint8_t *buf = (uint8_t *) - "lalala lalala\\ lala\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/ lalala\\\\/\"; sid:1;)"; - if (UTHPacketMatchSig(p, sig) == 0) { - result = 0; - goto end; - } - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** \test anchored pcre */ -int DetectPcreTestSig07() -{ - uint8_t *buf = (uint8_t *) - "lalala\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)"; - if (UTHPacketMatchSig(p, sig) == 0) { - result = 0; - goto end; - } - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** \test anchored pcre */ -int DetectPcreTestSig08() -{ - /* test it also without ending in a newline "\n" */ - uint8_t *buf = (uint8_t *) - "lalala"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre with an ending slash\"; pcre:\"/^(la)+$/\"; sid:1;)"; - if (UTHPacketMatchSig(p, sig) == 0) { - result = 0; - goto end; - } - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -/** \test Check the signature working to alert when cookie modifier is - * passed to pcre - */ -static int DetectPcreTestSig09(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; pcre:\"/dummy/C\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when cookie modifier is - * passed to a negated pcre - */ -static int DetectPcreTestSig10(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummoOOooooO\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP cookie\"; pcre:!\"/dummy/C\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 should match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when method modifier is - * passed to pcre - */ -static int DetectPcreTestSig11(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP method\"; pcre:\"/POST/M\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when method modifier is - * passed to a negated pcre - */ -static int DetectPcreTestSig12(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummoOOooooO\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP method\"; pcre:!\"/POST/M\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 should match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when header modifier is - * passed to pcre - */ -static int DetectPcreTestSig13(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP header\"; pcre:\"/User[-_]Agent[:]?\\sMozilla/H\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when header modifier is - * passed to a negated pcre - */ -static int DetectPcreTestSig14(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "GET / HTTP/1.0\r\nUser-Agent: IEXPLORER/1.0\r\n" - "Cookie: dummoOOooooO\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP header\"; pcre:!\"/User-Agent[:]?\\s+Mozilla/H\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 should match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when cookie and relative modifiers are - * passed to pcre - */ -static int DetectPcreTestSig15(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy 1234\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"pcre relative HTTP cookie\"; content:\"dummy\";" - " http_cookie; pcre:\"/1234/RC\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when method and relative modifiers are - * passed to pcre - */ -static int DetectPcreTestSig16(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n" - "Cookie: dummy 1234\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"pcre relative HTTP method\"; content:\"PO\";" - " http_method; pcre:\"/ST/RM\"; " - " sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 failed to match: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Test tracking of body chunks per transactions (on requests) - */ -static int DetectPcreTxBodyChunksTest01(void) -{ - int result = 0; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "GET / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n"; - uint8_t httpbuf4[] = "Body one!!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n"; - uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - AppLayerHtpEnableRequestBodyCallback(); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf7, httplen7); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - /* Now we should have 2 transactions, each with it's own list - * of request body chunks (let's test it) */ - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* hardcoded check of the transactions and it's client body chunks */ - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0); - htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 1); - - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1); - if (htud == NULL) { - printf("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - HtpBodyChunk *cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body one!!", strlen("Body one!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - htud = (HtpTxUserData *) htp_tx_get_user_data(t2); - - cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body two!!", strlen("Body two!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SCMutexUnlock(&f.m); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test test pcre P modifier with multiple pipelined http transactions */ -static int DetectPcreTxBodyChunksTest02(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n"; - uint8_t httpbuf4[] = "Body one!!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n"; - uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; pcre:\"/one/P\"; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; pcre:\"/two/P\"; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("signature matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (5): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf7, httplen7); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match, but should have: "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* hardcoded check of the transactions and it's client body chunks */ - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - htp_tx_t *t1 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0); - htp_tx_t *t2 = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 1); - - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1); - - HtpBodyChunk *cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body one!!", strlen("Body one!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - htud = (HtpTxUserData *) htp_tx_get_user_data(t2); - - cur = htud->request_body.first; - if (htud->request_body.first == NULL) { - SCLogDebug("No body data in t1 (it should be removed only when the tx is destroyed): "); - goto end; - } - - if (memcmp(cur->data, "Body two!!", strlen("Body two!!")) != 0) { - SCLogDebug("Body data in t1 is not correctly set: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** \test multiple http transactions and body chunks of request handling */ -static int DetectPcreTxBodyChunksTest03(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - Flow f; - TcpSession ssn; - Packet *p = NULL; - uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n"; - uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n"; - uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n"; - uint8_t httpbuf4[] = "Body one!!"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n"; - uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n"; - uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nBody two!!"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */ - uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; pcre:\"/one/P\"; sid:1; rev:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; pcre:\"/two/P\"; sid:2; rev:1;)"); - if (s == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (2): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf3, httplen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("signature matched, but shouldn't have: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf4, httplen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 1))) { - printf("sig 1 didn't alert: "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf5, httplen5); - if (r != 0) { - printf("toserver chunk 5 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sig 1 alerted (5): "); - goto end; - } - p->alerts.cnt = 0; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf6, httplen6); - if (r != 0) { - printf("toserver chunk 6 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if ((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2))) { - printf("sig 1 alerted (request 2, chunk 6): "); - goto end; - } - p->alerts.cnt = 0; - - SCLogDebug("sending data chunk 7"); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf7, httplen7); - if (r != 0) { - printf("toserver chunk 7 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!(PacketAlertCheck(p, 2))) { - printf("signature 2 didn't match, but should have: "); - goto end; - } - p->alerts.cnt = 0; - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - if (AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, htp_state) != 2) { - printf("The http app layer doesn't have 2 transactions, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - return result; -} - -/** - * \test flowvar capture on http buffer - */ -static int DetectPcreFlowvarCapture01(void) -{ - int result = 0; - uint8_t uabuf1[] = - "Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13"; - uint32_t ualen1 = sizeof(uabuf1) - 1; /* minus the \0 */ - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "\r\n" - "flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match on p1 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, pd->capidx); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_str.value_len != ualen1) { - printf("%u != %u: ", fv->data.fv_str.value_len, ualen1); - goto end; - } - - if (memcmp(fv->data.fv_str.value, uabuf1, ualen1) != 0) { - PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len); - PrintRawDataFp(stdout, uabuf1, ualen1); - - printf("buffer mismatch: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -/** - * \test flowvar capture on http buffer, capture overwrite - */ -static int DetectPcreFlowvarCapture02(void) -{ - int result = 0; - uint8_t uabuf1[] = - "Apache"; - uint32_t ualen1 = sizeof(uabuf1) - 1; /* minus the \0 */ - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "\r\n" - "flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; priority:1; sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd1 = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"Server: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; priority:3; sid:2;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd2 = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - if (pd1->capidx != pd2->capidx) { - printf("capidx mismatch, %u != %u: ", pd1->capidx, pd2->capidx); - goto end; - } - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - SCSigSignatureOrderingModuleCleanup(de_ctx); - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match on p1 but should have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, pd1->capidx); - if (fv == NULL) { - printf("no flowvar: "); - goto end; - } - - if (fv->data.fv_str.value_len != ualen1) { - PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len); - PrintRawDataFp(stdout, uabuf1, ualen1); - printf("%u != %u: ", fv->data.fv_str.value_len, ualen1); - goto end; - } - - if (memcmp(fv->data.fv_str.value, uabuf1, ualen1) != 0) { - PrintRawDataFp(stdout, fv->data.fv_str.value, fv->data.fv_str.value_len); - PrintRawDataFp(stdout, uabuf1, ualen1); - - printf("buffer mismatch: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -/** - * \test flowvar capture on http buffer, capture overwrite + no matching sigs, so flowvars should not be set. - */ -static int DetectPcreFlowvarCapture03(void) -{ - int result = 0; - uint8_t httpbuf1[] = - "GET / HTTP/1.1\r\n" - "Host: www.emergingthreats.net\r\n" - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.0.13) Gecko/2009080315 Ubuntu/8.10 (intrepid) Firefox/3.0.13\r\n" - "Accept: text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8\r\n" - "Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3\r\n" - "Accept-Encoding: gzip,deflate\r\n" - "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" - "Date: Tue, 22 Sep 2009 19:24:48 GMT\r\n" - "Server: Apache\r\n" - "\r\n" - "flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"User-Agent: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; content:\"xyz\"; http_header; priority:1; sid:1;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd1 = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"Server: \"; http_header; pcre:\"/(?P.*)\\r\\n/HR\"; content:\"xyz\"; http_header; priority:3; sid:2;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next == NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->type != DETECT_PCRE) { - goto end; - } - DetectPcreData *pd2 = (DetectPcreData *)s->sm_lists[DETECT_SM_LIST_HHDMATCH]->next->ctx; - - if (pd1->capidx != pd2->capidx) { - printf("capidx mismatch, %u != %u: ", pd1->capidx, pd2->capidx); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - HtpState *http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect for p1 */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 matched on p1 but shouldn't have: "); - goto end; - } - - FlowVar *fv = FlowVarGet(&f, pd1->capidx); - if (fv != NULL) { - printf("flowvar, shouldn't have one: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - return result; -} - -/** - * \brief Test parsing of pcre's with the W modifier set. - */ -static int DetectPcreParseHttpHost(void) -{ - int result = 0; - DetectPcreData *pd = NULL; - int list = DETECT_SM_LIST_NOTSET; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - return 0; - } - - pd = DetectPcreParse(de_ctx, "/domain\\.com/W", &list); - if (pd == NULL) { - goto end; - } - DetectPcreFree(pd); - - list = DETECT_SM_LIST_NOTSET; - pd = DetectPcreParse(de_ctx, "/dOmain\\.com/W", &list); - if (pd != NULL) { - DetectPcreFree(pd); - goto end; - } - - /* Uppercase meta characters are valid. */ - list = DETECT_SM_LIST_NOTSET; - pd = DetectPcreParse(de_ctx, "/domain\\D+\\.com/W", &list); - if (pd == NULL) { - goto end; - } - DetectPcreFree(pd); - - /* This should not parse as the first \ escapes the second \, then - * we have a D. */ - list = DETECT_SM_LIST_NOTSET; - pd = DetectPcreParse(de_ctx, "/\\\\Ddomain\\.com/W", &list); - if (pd != NULL) { - DetectPcreFree(pd); - goto end; - } - - result = 1; - -end: - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectPcre - */ -void DetectPcreRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectPcreParseTest01", DetectPcreParseTest01, 1); - UtRegisterTest("DetectPcreParseTest02", DetectPcreParseTest02, 1); - UtRegisterTest("DetectPcreParseTest03", DetectPcreParseTest03, 1); - UtRegisterTest("DetectPcreParseTest04", DetectPcreParseTest04, 1); - UtRegisterTest("DetectPcreParseTest05", DetectPcreParseTest05, 1); - UtRegisterTest("DetectPcreParseTest06", DetectPcreParseTest06, 1); - UtRegisterTest("DetectPcreParseTest07", DetectPcreParseTest07, 1); - UtRegisterTest("DetectPcreParseTest08", DetectPcreParseTest08, 1); - UtRegisterTest("DetectPcreParseTest09", DetectPcreParseTest09, 1); - UtRegisterTest("DetectPcreParseTest10", DetectPcreParseTest10, 1); - UtRegisterTest("DetectPcreParseTest11", DetectPcreParseTest11, 1); - UtRegisterTest("DetectPcreParseTest12", DetectPcreParseTest12, 1); - UtRegisterTest("DetectPcreParseTest13", DetectPcreParseTest13, 1); - UtRegisterTest("DetectPcreParseTest14", DetectPcreParseTest14, 1); - UtRegisterTest("DetectPcreParseTest15", DetectPcreParseTest15, 1); - UtRegisterTest("DetectPcreParseTest16", DetectPcreParseTest16, 1); - UtRegisterTest("DetectPcreParseTest17", DetectPcreParseTest17, 1); - UtRegisterTest("DetectPcreParseTest18", DetectPcreParseTest18, 1); - UtRegisterTest("DetectPcreParseTest19", DetectPcreParseTest19, 1); - UtRegisterTest("DetectPcreParseTest20", DetectPcreParseTest20, 1); - UtRegisterTest("DetectPcreParseTest21", DetectPcreParseTest21, 1); - UtRegisterTest("DetectPcreParseTest22", DetectPcreParseTest22, 1); - UtRegisterTest("DetectPcreParseTest23", DetectPcreParseTest23, 1); - UtRegisterTest("DetectPcreParseTest24", DetectPcreParseTest24, 1); - UtRegisterTest("DetectPcreParseTest25", DetectPcreParseTest25, 1); - UtRegisterTest("DetectPcreParseTest26", DetectPcreParseTest26, 1); - UtRegisterTest("DetectPcreParseTest27", DetectPcreParseTest27, 1); - - UtRegisterTest("DetectPcreTestSig01B2g -- pcre test", DetectPcreTestSig01B2g, 1); - UtRegisterTest("DetectPcreTestSig01B3g -- pcre test", DetectPcreTestSig01B3g, 1); - UtRegisterTest("DetectPcreTestSig01Wm -- pcre test", DetectPcreTestSig01Wm, 1); - UtRegisterTest("DetectPcreTestSig02B2g -- pcre test", DetectPcreTestSig02B2g, 1); - UtRegisterTest("DetectPcreTestSig02B3g -- pcre test", DetectPcreTestSig02B3g, 1); - UtRegisterTest("DetectPcreTestSig02Wm -- pcre test", DetectPcreTestSig02Wm, 1); - UtRegisterTest("DetectPcreTestSig03B2g -- negated pcre test", DetectPcreTestSig03B2g, 1); - UtRegisterTest("DetectPcreTestSig03B3g -- negated pcre test", DetectPcreTestSig03B3g, 1); - UtRegisterTest("DetectPcreTestSig03Wm -- negated pcre test", DetectPcreTestSig03Wm, 1); - - UtRegisterTest("DetectPcreModifPTest04 -- Modifier P", DetectPcreModifPTest04, 1); - UtRegisterTest("DetectPcreModifPTest05 -- Modifier P fragmented", DetectPcreModifPTest05, 1); - UtRegisterTest("DetectPcreTestSig06", DetectPcreTestSig06, 1); - UtRegisterTest("DetectPcreTestSig07 -- anchored pcre", DetectPcreTestSig07, 1); - UtRegisterTest("DetectPcreTestSig08 -- anchored pcre", DetectPcreTestSig08, 1); - UtRegisterTest("DetectPcreTestSig09 -- Cookie modifier", DetectPcreTestSig09, 1); - UtRegisterTest("DetectPcreTestSig10 -- negated Cookie modifier", DetectPcreTestSig10, 1); - UtRegisterTest("DetectPcreTestSig11 -- Method modifier", DetectPcreTestSig11, 1); - UtRegisterTest("DetectPcreTestSig12 -- negated Method modifier", DetectPcreTestSig12, 1); - UtRegisterTest("DetectPcreTestSig13 -- Header modifier", DetectPcreTestSig13, 1); - UtRegisterTest("DetectPcreTestSig14 -- negated Header modifier", DetectPcreTestSig14, 1); - UtRegisterTest("DetectPcreTestSig15 -- relative Cookie modifier", DetectPcreTestSig15, 1); - UtRegisterTest("DetectPcreTestSig16 -- relative Method modifier", DetectPcreTestSig16, 1); - - UtRegisterTest("DetectPcreTxBodyChunksTest01", DetectPcreTxBodyChunksTest01, 1); - UtRegisterTest("DetectPcreTxBodyChunksTest02 -- modifier P, body chunks per tx", DetectPcreTxBodyChunksTest02, 1); - UtRegisterTest("DetectPcreTxBodyChunksTest03 -- modifier P, body chunks per tx", DetectPcreTxBodyChunksTest03, 1); - - UtRegisterTest("DetectPcreFlowvarCapture01 -- capture for http_header", DetectPcreFlowvarCapture01, 1); - UtRegisterTest("DetectPcreFlowvarCapture02 -- capture for http_header", DetectPcreFlowvarCapture02, 1); - UtRegisterTest("DetectPcreFlowvarCapture03 -- capture for http_header", DetectPcreFlowvarCapture03, 1); - - UtRegisterTest("DetectPcreParseHttpHost", DetectPcreParseHttpHost, 1); - -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-pcre.h b/framework/src/suricata/src/detect-pcre.h deleted file mode 100644 index e0098cb1..00000000 --- a/framework/src/suricata/src/detect-pcre.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_PCRE_H__ -#define __DETECT_PCRE_H__ - -#define DETECT_PCRE_RELATIVE 0x00001 -#define DETECT_PCRE_RAWBYTES 0x00002 -#define DETECT_PCRE_CASELESS 0x00004 -#define DETECT_PCRE_CAPTURE_PKT 0x00008 -#define DETECT_PCRE_CAPTURE_FLOW 0x00010 -#define DETECT_PCRE_MATCH_LIMIT 0x00020 -#define DETECT_PCRE_RELATIVE_NEXT 0x00040 -#define DETECT_PCRE_NEGATE 0x00080 - -typedef struct DetectPcreData_ { - /* pcre options */ - pcre *re; - pcre_extra *sd; - int opts; - uint16_t flags; - uint16_t capidx; - char *capname; -} DetectPcreData; - -/* prototypes */ -int DetectPcrePayloadMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, Packet *, Flow *, uint8_t *, uint32_t); -int DetectPcrePacketPayloadMatch(DetectEngineThreadCtx *, Packet *, Signature *, SigMatch *); -int DetectPcrePayloadDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, - Packet *, uint8_t *, uint16_t); -void DetectPcreRegister (void); - -#endif /* __DETECT_PCRE_H__ */ - diff --git a/framework/src/suricata/src/detect-pkt-data.c b/framework/src/suricata/src/detect-pkt-data.c deleted file mode 100644 index df65444a..00000000 --- a/framework/src/suricata/src/detect-pkt-data.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Xavier Lange - * - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-spm-bm.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -static int DetectPktDataSetup (DetectEngineCtx *, Signature *, char *); -static void DetectPktDataTestRegister(void); - -/** - * \brief Registration function for keyword: file_data - */ -void DetectPktDataRegister(void) -{ - sigmatch_table[DETECT_PKT_DATA].name = "pkt_data"; - sigmatch_table[DETECT_PKT_DATA].Match = NULL; - sigmatch_table[DETECT_PKT_DATA].AppLayerMatch = NULL; - sigmatch_table[DETECT_PKT_DATA].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_PKT_DATA].Setup = DetectPktDataSetup; - sigmatch_table[DETECT_PKT_DATA].Free = NULL; - sigmatch_table[DETECT_PKT_DATA].RegisterTests = DetectPktDataTestRegister; - sigmatch_table[DETECT_PKT_DATA].flags = SIGMATCH_NOOPT; -} - -/** - * \brief this function is used to parse pkt_data options - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param str pointer to the user provided "filestore" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectPktDataSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - SCEnter(); - s->list = DETECT_SM_LIST_NOTSET; - - return 0; -} - -#ifdef UNITTESTS - -/************************************Unittests*********************************/ - -static int DetectPktDataTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - SigMatch *sm = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - Signature *sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(file_data; content:\"in file data\";" - " pkt_data; content:\"in pkt data\";)"); - de_ctx->sig_list = sig; - if (de_ctx->sig_list == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE,"could not load test signature"); - goto end; - } - - /* sm should be in the MATCH list */ - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_FILEDATA]; - if (sm == NULL) { - printf("sm not in DETECT_SM_LIST_FILEDATA: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm == NULL) { - printf("sm not in DETECT_SM_LIST_PMATCH: "); - goto end; - } - - if (sm->type != DETECT_CONTENT) { - printf("sm type not DETECT_AL_HTTP_SERVER_BODY: "); - goto end; - } - - if (sm->next != NULL) { - goto end; - } - - - if (sig->list != DETECT_SM_LIST_NOTSET) { - printf("sticky buffer set: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} -#endif - -static void DetectPktDataTestRegister(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectPktDataTest01", DetectPktDataTest01, 1); -#endif -} - diff --git a/framework/src/suricata/src/detect-pkt-data.h b/framework/src/suricata/src/detect-pkt-data.h deleted file mode 100644 index fbaf8b98..00000000 --- a/framework/src/suricata/src/detect-pkt-data.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_PKTDATA_H__ -#define __DETECT_PKTDATA_H__ - -/* prototypes */ -void DetectPktDataRegister (void); - -#endif /* __DETECT_PKTDATA_H__ */ diff --git a/framework/src/suricata/src/detect-pktvar.c b/framework/src/suricata/src/detect-pktvar.c deleted file mode 100644 index c841f69d..00000000 --- a/framework/src/suricata/src/detect-pktvar.c +++ /dev/null @@ -1,259 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the pktvar keyword - */ - -#include "suricata-common.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "threads.h" -#include "pkt-var.h" -#include "detect-pktvar.h" -#include "util-spm.h" -#include "util-debug.h" - -#define PARSE_REGEX "(.*),(.*)" -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectPktvarMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectPktvarSetup (DetectEngineCtx *, Signature *, char *); - -void DetectPktvarRegister (void) -{ - sigmatch_table[DETECT_PKTVAR].name = "pktvar"; - sigmatch_table[DETECT_PKTVAR].Match = DetectPktvarMatch; - sigmatch_table[DETECT_PKTVAR].Setup = DetectPktvarSetup; - sigmatch_table[DETECT_PKTVAR].Free = NULL; - sigmatch_table[DETECT_PKTVAR].RegisterTests = NULL; - - sigmatch_table[DETECT_PKTVAR].flags |= SIGMATCH_PAYLOAD; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - return; -} - -/* - * returns 0: no match - * 1: match - * -1: error - */ - -int DetectPktvarMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - int ret = 0; - const DetectPktvarData *pd = (const DetectPktvarData *)ctx; - - PktVar *pv = PktVarGet(p, pd->name); - if (pv != NULL) { - uint8_t *ptr = SpmSearch(pv->value, pv->value_len, pd->content, pd->content_len); - if (ptr != NULL) - ret = 1; - } - - return ret; -} - -static int DetectPktvarSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectPktvarData *cd = NULL; - SigMatch *sm = NULL; - char *str = rawstr; - char dubbed = 0; - uint16_t len; - char *varname = NULL, *varcontent = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret != 3) { - SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for pktvar.", rawstr); - return -1; - - } - - const char *str_ptr; - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - return -1; - } - varname = (char *)str_ptr; - - if (ret > 2) { - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - return -1; - } - varcontent = (char *)str_ptr; - } - - SCLogDebug("varname %s, varcontent %s", varname, varcontent); - - if (varcontent[0] == '\"' && varcontent[strlen(varcontent)-1] == '\"') { - str = SCStrdup(varcontent+1); - if (unlikely(str == NULL)) { - return -1; - } - str[strlen(varcontent)-2] = '\0'; - dubbed = 1; - } - - len = strlen(str); - if (len == 0) { - if (dubbed) SCFree(str); - return -1; - } - - cd = SCMalloc(sizeof(DetectPktvarData)); - if (unlikely(cd == NULL)) - goto error; - - char converted = 0; - - { - uint16_t i, x; - uint8_t bin = 0, binstr[3] = "", binpos = 0; - for (i = 0, x = 0; i < len; i++) { - // printf("str[%02u]: %c\n", i, str[i]); - if (str[i] == '|') { - if (bin) { - bin = 0; - } else { - bin = 1; - } - } else { - if (bin) { - if (isdigit((unsigned char)str[i]) || - str[i] == 'A' || str[i] == 'a' || - str[i] == 'B' || str[i] == 'b' || - str[i] == 'C' || str[i] == 'c' || - str[i] == 'D' || str[i] == 'd' || - str[i] == 'E' || str[i] == 'e' || - str[i] == 'F' || str[i] == 'f') { - // printf("part of binary: %c\n", str[i]); - - binstr[binpos] = (char)str[i]; - binpos++; - - if (binpos == 2) { - uint8_t c = strtol((char *)binstr, (char **) NULL, 16) & 0xFF; - binpos = 0; - str[x] = c; - x++; - converted = 1; - } - } else if (str[i] == ' ') { - // printf("space as part of binary string\n"); - } - } else { - str[x] = str[i]; - x++; - } - } - } -#ifdef DEBUG - if (SCLogDebugEnabled()) { - for (i = 0; i < x; i++) { - if (isprint((unsigned char)str[i])) printf("%c", str[i]); - else printf("\\x%02u", str[i]); - } - printf("\n"); - } -#endif - - if (converted) - len = x; - } - - cd->content = SCMalloc(len); - if (cd->content == NULL) { - SCFree(cd); - if (dubbed) SCFree(str); - return -1; - } - - cd->name = SCStrdup(varname); - if (cd->name == NULL) { - SCFree(cd); - if (dubbed) SCFree(str); - return -1; - } - - memcpy(cd->content, str, len); - cd->content_len = len; - cd->flags = 0; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_PKTVAR; - sm->ctx = (SigMatchCtx *)cd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - if (dubbed) SCFree(str); - return 0; - -error: - if (dubbed) - SCFree(str); - if (cd) { - if (cd->name) - SCFree(cd->name); - SCFree(cd); - } - if (sm) - SCFree(sm); - return -1; -} - - diff --git a/framework/src/suricata/src/detect-pktvar.h b/framework/src/suricata/src/detect-pktvar.h deleted file mode 100644 index e5d1d3a6..00000000 --- a/framework/src/suricata/src/detect-pktvar.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_PKTVAR_H__ -#define __DETECT_PKTVAR_H__ - -typedef struct DetectPktvarData_ { - char *name; - uint8_t *content; - uint8_t content_len; - uint8_t flags; -} DetectPktvarData; - -/* prototypes */ -void DetectPktvarRegister (void); - -#endif /* __DETECT_PKTVAR_H__ */ - diff --git a/framework/src/suricata/src/detect-priority.c b/framework/src/suricata/src/detect-priority.c deleted file mode 100644 index 5bb0359f..00000000 --- a/framework/src/suricata/src/detect-priority.c +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * Implements the priority keyword - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-unittest.h" - -#define DETECT_PRIORITY_REGEX "^\\s*(\\d+|\"\\d+\")\\s*$" - -static pcre *regex = NULL; -static pcre_extra *regex_study = NULL; - -static int DetectPrioritySetup (DetectEngineCtx *, Signature *, char *); -void SCPriorityRegisterTests(void); - -/** - * \brief Registers the handler functions for the "priority" keyword - */ -void DetectPriorityRegister (void) -{ - const char *eb = NULL; - int eo; - int opts = 0; - - sigmatch_table[DETECT_PRIORITY].name = "priority"; - sigmatch_table[DETECT_PRIORITY].desc = "rules with a higher priority will be examined first"; - sigmatch_table[DETECT_PRIORITY].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Meta-settings#Priority"; - sigmatch_table[DETECT_PRIORITY].Match = NULL; - sigmatch_table[DETECT_PRIORITY].Setup = DetectPrioritySetup; - sigmatch_table[DETECT_PRIORITY].Free = NULL; - sigmatch_table[DETECT_PRIORITY].RegisterTests = SCPriorityRegisterTests; - - regex = pcre_compile(DETECT_PRIORITY_REGEX, opts, &eb, &eo, NULL); - if (regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - DETECT_PRIORITY_REGEX, eo, eb); - goto end; - } - - regex_study = pcre_study(regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto end; - } - - end: - return; -} - -static int DetectPrioritySetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - char copy_str[128] = ""; - -#define MAX_SUBSTRINGS 30 - int ret = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(regex, regex_study, rawstr, strlen(rawstr), 0, 0, ov, 30); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_MATCH, "Invalid Priority in Signature " - "- %s", rawstr); - return -1; - } - - ret = pcre_copy_substring((char *)rawstr, ov, 30, 1, copy_str, sizeof(copy_str)); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return -1; - } - - long prio = 0; - char *endptr = NULL; - prio = strtol(copy_str, &endptr, 10); - if (endptr == NULL || *endptr != '\0') { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Saw an invalid character as arg " - "to priority keyword"); - return -1; - } - /* if we have reached here, we have had a valid priority. Assign it */ - s->prio = prio; - - return 0; -} - -/*------------------------------Unittests-------------------------------------*/ - -#ifdef UNITTESTS - -int DetectPriorityTest01() -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Priority test\"; priority:2; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - - DetectEngineCtxFree(de_ctx); - -end: - return result; -} - -int DetectPriorityTest02() -{ - int result = 0; - Signature *last = NULL; - Signature *sig = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Priority test\"; priority:1; sid:1;)"); - de_ctx->sig_list = last = sig; - if (sig == NULL) { - result = 0; - } else { - result = 1; - result &= (sig->prio == 1); - } - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Priority test\"; priority:boo; sid:1;)"); - if (last != NULL) - last->next = sig; - result &= (sig == NULL); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Priority test\"; priority:10boo; sid:1;)"); - if (last != NULL) - last->next = sig; - result &= (sig == NULL); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Priority test\"; priority:b10oo; sid:1;)"); - if (last != NULL) - last->next = sig; - result &= (sig == NULL); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Priority test\"; priority:boo10; sid:1;)"); - if (last != NULL) - last->next = sig; - result &= (sig == NULL); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Priority test\"; priority:-1; sid:1;)"); - if (last != NULL) - last->next = sig; - result &= (sig == NULL); - - sig = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Priority test\"; sid:1;)"); - if (last != NULL) - last->next = sig; - if (sig == NULL) { - result &= 0; - } else { - result &= (sig->prio == 3); - } - - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - -end: - return result; -} - - -#endif /* UNITTESTS */ - -/** - * \brief This function registers unit tests for Classification Config API. - */ -void SCPriorityRegisterTests(void) -{ - -#ifdef UNITTESTS - - UtRegisterTest("DetectPriorityTest01", DetectPriorityTest01, 1); - UtRegisterTest("DetectPriorityTest02", DetectPriorityTest02, 1); - -#endif /* UNITTESTS */ - -} diff --git a/framework/src/suricata/src/detect-priority.h b/framework/src/suricata/src/detect-priority.h deleted file mode 100644 index 0ec877e5..00000000 --- a/framework/src/suricata/src/detect-priority.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * Implements the priority keyword - */ - -#ifndef __DETECT_PRIORITY_H__ -#define __DETECT_PRIORITY_H__ - -/* prototypes */ -void DetectPriorityRegister (void); - -#endif /* __DETECT_PRIORITY_H__ */ - diff --git a/framework/src/suricata/src/detect-rawbytes.c b/framework/src/suricata/src/detect-rawbytes.c deleted file mode 100644 index 872a71a0..00000000 --- a/framework/src/suricata/src/detect-rawbytes.c +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements rawbytes keyword support - * - * \todo Provide un-normalized telnet dce/rpc buffers to match on - */ - -#include "suricata-common.h" - -#include "decode.h" -#include "detect.h" -#include "detect-parse.h" -#include "flow-var.h" - -#include "detect-content.h" -#include "detect-pcre.h" - -#include "util-debug.h" - -static int DetectRawbytesSetup (DetectEngineCtx *, Signature *, char *); - -void DetectRawbytesRegister (void) -{ - sigmatch_table[DETECT_RAWBYTES].name = "rawbytes"; - sigmatch_table[DETECT_RAWBYTES].Match = NULL; - sigmatch_table[DETECT_RAWBYTES].Setup = DetectRawbytesSetup; - sigmatch_table[DETECT_RAWBYTES].Free = NULL; - sigmatch_table[DETECT_RAWBYTES].RegisterTests = NULL; - - sigmatch_table[DETECT_RAWBYTES].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_RAWBYTES].flags |= SIGMATCH_PAYLOAD; -} - -static int DetectRawbytesSetup (DetectEngineCtx *de_ctx, Signature *s, char *nullstr) -{ - SCEnter(); - - if (nullstr != NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "rawbytes has no value"); - return -1; - } - - if (s->list != DETECT_SM_LIST_NOTSET) { - SCLogError(SC_ERR_RAWBYTES_FILE_DATA, "\"rawbytes\" cannot be combined with \"file_data\""); - SCReturnInt(-1); - } - - SigMatch *pm = SigMatchGetLastSMFromLists(s, 2, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); - if (pm == NULL) { - SCLogError(SC_ERR_RAWBYTES_MISSING_CONTENT, "\"rawbytes\" needs a preceding content option"); - SCReturnInt(-1); - } - - switch (pm->type) { - case DETECT_CONTENT: - { - DetectContentData *cd = (DetectContentData *)pm->ctx; - if (cd->flags & DETECT_CONTENT_RAWBYTES) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple rawbytes modifiers for the same content. "); - SCReturnInt(-1); - } - cd->flags |= DETECT_CONTENT_RAWBYTES; - break; - } - default: - SCLogError(SC_ERR_RAWBYTES_MISSING_CONTENT, "\"rawbytes\" needs a preceding content option"); - SCReturnInt(-1); - } - - SCReturnInt(0); -} - diff --git a/framework/src/suricata/src/detect-rawbytes.h b/framework/src/suricata/src/detect-rawbytes.h deleted file mode 100644 index 8716e56a..00000000 --- a/framework/src/suricata/src/detect-rawbytes.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_RAWBYTES_H__ -#define __DETECT_RAWBYTES_H__ - -/* prototypes */ -void DetectRawbytesRegister (void); - -#endif /* __DETECT_RAWBYTES_H__ */ - diff --git a/framework/src/suricata/src/detect-reference.c b/framework/src/suricata/src/detect-reference.c deleted file mode 100644 index a672f5c2..00000000 --- a/framework/src/suricata/src/detect-reference.c +++ /dev/null @@ -1,376 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - * \author Anoop Saldanha - * - * Implements the reference keyword support - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "decode.h" -#include "flow-var.h" -#include "decode-events.h" -#include "stream-tcp.h" - -#include "util-reference-config.h" -#include "detect-reference.h" - -#include "util-unittest.h" -#include "util-byte.h" -#include "util-debug.h" - -#define PARSE_REGEX "^\\s*([A-Za-z0-9]+)\\s*,\"?\\s*\"?\\s*([a-zA-Z0-9\\-_\\.\\/\\?\\=]+)\"?\\s*\"?" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -static int DetectReferenceSetup(DetectEngineCtx *, Signature *s, char *str); - -/** - * \brief Registration function for the reference: keyword - */ -void DetectReferenceRegister(void) -{ - sigmatch_table[DETECT_REFERENCE].name = "reference"; - sigmatch_table[DETECT_REFERENCE].desc = "direct to places where information about the rule can be found"; - sigmatch_table[DETECT_REFERENCE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Meta-settings#Reference"; - sigmatch_table[DETECT_REFERENCE].Match = NULL; - sigmatch_table[DETECT_REFERENCE].Setup = DetectReferenceSetup; - sigmatch_table[DETECT_REFERENCE].Free = NULL; - sigmatch_table[DETECT_REFERENCE].RegisterTests = ReferenceRegisterTests; - - const char *eb; - int opts = 0; - int eo; - - opts |= PCRE_CASELESS; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at " - "offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - -error: - return; -} - -/** - * \brief Free a Reference object - */ -void DetectReferenceFree(DetectReference *ref) -{ - SCEnter(); - - if (ref->reference != NULL) { - SCFree(ref->reference); - } - SCFree(ref); - - SCReturn; -} - -/** - * \internal - * \brief This function is used to parse reference options passed via reference: keyword - * - * \param rawstr Pointer to the user provided reference options. - * - * \retval ref Pointer to signature reference on success. - * \retval NULL On failure. - */ -static DetectReference *DetectReferenceParse(char *rawstr, DetectEngineCtx *de_ctx) -{ - SCEnter(); - - DetectReference *ref = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - char key[64] = ""; - char content[1024] = ""; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), - 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 2) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Unable to parse \"reference\" " - "keyword argument - \"%s\". Invalid argument.", rawstr); - goto error; - } - - ref = SCMalloc(sizeof(DetectReference)); - if (unlikely(ref == NULL)) { - goto error; - } - memset(ref, 0, sizeof(DetectReference)); - - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, key, sizeof(key)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, content, sizeof(content)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (strlen(key) == 0 || strlen(content) == 0) - goto error; - - SCRConfReference *lookup_ref_conf = SCRConfGetReference(key, de_ctx); - if (lookup_ref_conf != NULL) { - ref->key = lookup_ref_conf->url; - } else { - SCLogError(SC_ERR_REFERENCE_UNKNOWN, "unknown reference key \"%s\". " - "Supported keys are defined in reference.config file. Please " - "have a look at the conf param \"reference-config-file\"", key); - goto error; - } - - /* make a copy so we can free pcre's substring */ - ref->reference = SCStrdup((char *)content); - if (ref->reference == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "strdup failed: %s", strerror(errno)); - goto error; - } - - /* free the substrings */ - SCReturnPtr(ref, "Reference"); - -error: - if (ref != NULL) - DetectReferenceFree(ref); - - SCReturnPtr(NULL, "Reference"); -} - -/** - * \internal - * \brief Used to add the parsed reference into the current signature. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Current Signature. - * \param m Pointer to the Current SigMatch. - * \param rawstr Pointer to the user provided reference options. - * - * \retval 0 On Success. - * \retval -1 On Failure. - */ -static int DetectReferenceSetup(DetectEngineCtx *de_ctx, Signature *s, - char *rawstr) -{ - SCEnter(); - - DetectReference *ref = NULL; - DetectReference *sig_refs = NULL; - - ref = DetectReferenceParse(rawstr, de_ctx); - if (ref == NULL) - goto error; - - SCLogDebug("ref %s %s", ref->key, ref->reference); - - if (s->references == NULL) { - s->references = ref; - } else { - sig_refs = s->references; - while (sig_refs->next != NULL) { - sig_refs = sig_refs->next; - } - sig_refs->next = ref; - ref->next = NULL; - } - - SCReturnInt(0); - -error: - SCReturnInt(-1); -} - -/***************************************Unittests******************************/ - -#ifdef UNITTESTS - -/** - * \test one valid reference. - * - * \retval 1 on succces. - * \retval 0 on failure. - */ -static int DetectReferenceParseTest01(void) -{ - int result = 0; - Signature *s = NULL; - DetectReference *ref = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto cleanup; - } - de_ctx->flags |= DE_QUIET; - - FILE *fd = SCRConfGenerateValidDummyReferenceConfigFD01(); - SCRConfLoadReferenceConfigFile(de_ctx, fd); - - s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(msg:\"One reference\"; reference:one,001-2010; sid:2;)"); - if (s == NULL) { - goto cleanup; - } - - if (s->references == NULL) { - goto cleanup; - } - - ref = s->references; - if (strcmp(ref->key, "http://www.one.com") != 0 || - strcmp(ref->reference, "001-2010") != 0) { - goto cleanup; - } - - result = 1; - -cleanup: - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - return result; - -} - -/** - * \test for two valid references. - * - * \retval 1 on succces. - * \retval 0 on failure. - */ -static int DetectReferenceParseTest02(void) -{ - int result = 0; - Signature *s = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto cleanup; - } - de_ctx->flags |= DE_QUIET; - - FILE *fd = SCRConfGenerateValidDummyReferenceConfigFD01(); - SCRConfLoadReferenceConfigFile(de_ctx, fd); - - s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(msg:\"Two references\"; " - "reference:one,openinfosecdoundation.txt; " - "reference:two,001-2010; sid:2;)"); - if (s == NULL) { - printf("sig parse failed: "); - goto cleanup; - } - - if (s->references == NULL || s->references->next == NULL) { - printf("no ref or not enough refs: "); - goto cleanup; - } - - if (strcmp(s->references->key, "http://www.one.com") != 0 || - strcmp(s->references->reference, "openinfosecdoundation.txt") != 0) { - printf("first ref failed: "); - goto cleanup; - } - - if (strcmp(s->references->next->key, "http://www.two.com") != 0 || - strcmp(s->references->next->reference, "001-2010") != 0) { - printf("second ref failed: "); - goto cleanup; - } - - result = 1; - -cleanup: - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - return result; -} - -/** - * \test parsing: invalid reference. - * - * \retval 1 on succces. - * \retval 0 on failure. - */ -static int DetectReferenceParseTest03(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto cleanup; - } - de_ctx->flags |= DE_QUIET; - - FILE *fd =SCRConfGenerateValidDummyReferenceConfigFD01(); - SCRConfLoadReferenceConfigFile(de_ctx, fd); - - s = de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(msg:\"invalid ref\"; " - "reference:unknownkey,001-2010; sid:2;)"); - if (s != NULL) { - printf("sig parsed even though it's invalid: "); - goto cleanup; - } - - result = 1; - -cleanup: - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - return result; -} - -#endif /* UNITTESTS */ - -void ReferenceRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectReferenceParseTest01", DetectReferenceParseTest01, 1); - UtRegisterTest("DetectReferenceParseTest02", DetectReferenceParseTest02, 1); - UtRegisterTest("DetectReferenceParseTest03", DetectReferenceParseTest03, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-reference.h b/framework/src/suricata/src/detect-reference.h deleted file mode 100644 index 6c513fe1..00000000 --- a/framework/src/suricata/src/detect-reference.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - */ - -#ifndef __DETECT_REFERENCE_H__ -#define __DETECT_REFERENCE_H__ - -#include "decode-events.h" -#include "decode-ipv4.h" -#include "decode-tcp.h" - -/** - * \brief Signature reference list. - */ -typedef struct DetectReference_ { - /* pointer to key */ - char *key; - /* reference data */ - char *reference; - /* next reference in the signature */ - struct DetectReference_ *next; -} DetectReference; - -/** - * Registration function for Reference keyword - */ -void DetectReferenceRegister(void); - -/** - * This function registers unit tests for Reference keyword. - */ -void ReferenceRegisterTests(void); - -/** - * Free function for a Reference object - */ -void DetectReferenceFree(DetectReference *); - -#endif /*__DETECT_REFERENCE_H__ */ diff --git a/framework/src/suricata/src/detect-replace.c b/framework/src/suricata/src/detect-replace.c deleted file mode 100644 index 57e06e7a..00000000 --- a/framework/src/suricata/src/detect-replace.c +++ /dev/null @@ -1,845 +0,0 @@ -/* Copyright (C) 2011-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - * Replace part of the detection engine. - * - * If previous filter is of content type, replace can be used to change - * the matched part to a new value. - */ - -#include "suricata-common.h" - -#include "runmodes.h" - -extern int run_mode; - -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-byte-extract.h" -#include "detect-replace.h" -#include "app-layer.h" - -#include "detect-engine-mpm.h" -#include "detect-engine.h" -#include "detect-engine-state.h" - -#include "util-checksum.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "flow-var.h" - -#include "util-debug.h" - -#include "pkt-var.h" -#include "host.h" -#include "util-profiling.h" - -static int DetectReplaceSetup(DetectEngineCtx *, Signature *, char *); -void DetectReplaceRegisterTests(void); - -void DetectReplaceRegister (void) -{ - sigmatch_table[DETECT_REPLACE].name = "replace"; - sigmatch_table[DETECT_REPLACE].Match = NULL; - sigmatch_table[DETECT_REPLACE].Setup = DetectReplaceSetup; - sigmatch_table[DETECT_REPLACE].Free = NULL; - sigmatch_table[DETECT_REPLACE].RegisterTests = DetectReplaceRegisterTests; - - sigmatch_table[DETECT_REPLACE].flags |= SIGMATCH_PAYLOAD; -} - -int DetectReplaceSetup(DetectEngineCtx *de_ctx, Signature *s, char *replacestr) -{ - uint8_t *content = NULL; - uint16_t len = 0; - uint32_t flags = 0; - SigMatch *pm = NULL; - DetectContentData *ud = NULL; - - int ret = DetectContentDataParse("replace", replacestr, &content, &len, &flags); - if (ret == -1) - goto error; - - if (flags & DETECT_CONTENT_NEGATED) { - SCLogError(SC_ERR_INVALID_VALUE, "Can't negate replacement string: %s", - replacestr); - goto error; - } - - switch (run_mode) { - case RUNMODE_NFQ: - case RUNMODE_IPFW: - break; - default: - SCLogWarning(SC_ERR_RUNMODE, - "Can't use 'replace' keyword in non IPS mode: %s", - s->sig_str); - /* this is a success, having the alert is interesting */ - return 0; - } - - /* add to the latest "content" keyword from either dmatch or pmatch */ - pm = SigMatchGetLastSMFromLists(s, 2, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH]); - if (pm == NULL) { - SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "replace needs" - "preceding content option for raw sig"); - SCFree(content); - return -1; - } - - /* we can remove this switch now with the unified structure */ - ud = (DetectContentData *)pm->ctx; - if (ud == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "invalid argument"); - SCFree(content); - return -1; - } - if (ud->flags & DETECT_CONTENT_NEGATED) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " - "negated keyword set along with a replacement"); - goto error; - } - if (ud->content_len != len) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a content " - "length different from replace length"); - goto error; - } - - ud->replace = SCMalloc(len); - if (ud->replace == NULL) { - goto error; - } - memcpy(ud->replace, content, len); - ud->replace_len = len; - ud->flags |= DETECT_CONTENT_REPLACE; - /* want packet matching only won't be able to replace data with - * a flow. - */ - s->flags |= SIG_FLAG_REQUIRE_PACKET; - SCFree(content); - - return 0; - -error: - SCFree(content); - return -1; -} - -/* Add to the head of the replace-list. - * - * The first to add to the replace-list has the highest priority. So, - * adding the the head of the list results in the newest modifications - * of content being applied first, so later changes can over ride - * earlier changes. Thus the highest priority modifications should be - * applied last. - */ -DetectReplaceList *DetectReplaceAddToList(DetectReplaceList *replist, - uint8_t *found, - DetectContentData *cd) -{ - DetectReplaceList *newlist; - - if (cd->content_len != cd->replace_len) - return NULL; - SCLogDebug("replace: Adding match"); - - newlist = SCMalloc(sizeof(DetectReplaceList)); - if (unlikely(newlist == NULL)) - return replist; - newlist->found = found; - newlist->cd = cd; - /* Push new value onto the front of the list. */ - newlist->next = replist; - - return newlist; -} - - -void DetectReplaceExecuteInternal(Packet *p, DetectReplaceList *replist) -{ - DetectReplaceList *tlist = NULL; - - SCLogDebug("replace: Executing match"); - while (replist) { - memcpy(replist->found, replist->cd->replace, replist->cd->replace_len); - SCLogDebug("replace: injecting '%s'", replist->cd->replace); - p->flags |= PKT_STREAM_MODIFIED; - ReCalculateChecksum(p); - tlist = replist; - replist = replist->next; - SCFree(tlist); - } -} - - -void DetectReplaceFreeInternal(DetectReplaceList *replist) -{ - DetectReplaceList *tlist = NULL; - while (replist) { - SCLogDebug("replace: Freeing match"); - tlist = replist; - replist = replist->next; - SCFree(tlist); - } -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test Test packet Matches - * \param raw_eth_pkt pointer to the ethernet packet - * \param pktsize size of the packet - * \param sig pointer to the signature to test - * \param sid sid number of the signature - * \retval return 1 if match - * \retval return 0 if not - */ -static -int DetectReplaceLongPatternMatchTest(uint8_t *raw_eth_pkt, uint16_t pktsize, - char *sig, uint32_t sid, uint8_t *pp, - uint16_t *len) -{ - int result = 0; - - Packet *p = NULL; - p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - - DecodeThreadVars dtv; - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - if (pp == NULL) { - SCLogDebug("replace: looks like a second run"); - } - - PacketCopyData(p, raw_eth_pkt, pktsize); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - dtv.app_tctx = AppLayerGetCtxThread(&th_v); - - FlowInitConfig(FLOW_QUIET); - DecodeEthernet(&th_v, &dtv, p, GET_PKT_DATA(p), pktsize, NULL); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig); - if (de_ctx->sig_list == NULL) { - goto end; - } - de_ctx->sig_list->next = NULL; - - if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->type == DETECT_CONTENT) { - DetectContentData *co = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx; - if (co->flags & DETECT_CONTENT_RELATIVE_NEXT) { - printf("relative next flag set on final match which is content: "); - goto end; - } - } - - SigGroupBuild(de_ctx); - DetectEngineAddToMaster(de_ctx); - DetectEngineThreadCtxInit(&th_v, NULL, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - DetectEngineMoveToFreeList(de_ctx); - - if (PacketAlertCheck(p, sid) != 1) { - SCLogDebug("replace: no alert on sig %d", sid); - goto end; - } - - if (pp) { - memcpy(pp, GET_PKT_DATA(p), GET_PKT_LEN(p)); - *len = pktsize; - SCLogDebug("replace: copying %d on %p", *len, pp); - } - - - result = 1; -end: - if (dtv.app_tctx != NULL) - AppLayerDestroyCtxThread(dtv.app_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEnginePruneFreeList(); - PACKET_RECYCLE(p); - FlowShutdown(); - SCFree(p); - - - return result; -} - - -/** - * \brief Wrapper for DetectContentLongPatternMatchTest - */ -int DetectReplaceLongPatternMatchTestWrp(char *sig, uint32_t sid, char *sig_rep, uint32_t sid_rep) -{ - int ret; - /** Real packet with the following tcp data: - * "Hi, this is a big test to check content matches of splitted" - * "patterns between multiple chunks!" - * (without quotes! :) ) - */ - uint8_t raw_eth_pkt[] = { - 0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, - 0x00,0x00,0x00,0x00,0x08,0x00,0x45,0x00, - 0x00,0x85,0x00,0x01,0x00,0x00,0x40,0x06, - 0x7c,0x70,0x7f,0x00,0x00,0x01,0x7f,0x00, - 0x00,0x01,0x00,0x14,0x00,0x50,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x02, - 0x20,0x00,0xc9,0xad,0x00,0x00,0x48,0x69, - 0x2c,0x20,0x74,0x68,0x69,0x73,0x20,0x69, - 0x73,0x20,0x61,0x20,0x62,0x69,0x67,0x20, - 0x74,0x65,0x73,0x74,0x20,0x74,0x6f,0x20, - 0x63,0x68,0x65,0x63,0x6b,0x20,0x63,0x6f, - 0x6e,0x74,0x65,0x6e,0x74,0x20,0x6d,0x61, - 0x74,0x63,0x68,0x65,0x73,0x20,0x6f,0x66, - 0x20,0x73,0x70,0x6c,0x69,0x74,0x74,0x65, - 0x64,0x20,0x70,0x61,0x74,0x74,0x65,0x72, - 0x6e,0x73,0x20,0x62,0x65,0x74,0x77,0x65, - 0x65,0x6e,0x20,0x6d,0x75,0x6c,0x74,0x69, - 0x70,0x6c,0x65,0x20,0x63,0x68,0x75,0x6e, - 0x6b,0x73,0x21 }; /* end raw_eth_pkt */ - uint8_t p[sizeof(raw_eth_pkt)]; - uint16_t psize = sizeof(raw_eth_pkt); - - /* would be unittest */ - int run_mode_backup = run_mode; - run_mode = RUNMODE_NFQ; - ret = DetectReplaceLongPatternMatchTest(raw_eth_pkt, (uint16_t)sizeof(raw_eth_pkt), - sig, sid, p, &psize); - if (ret == 1) { - SCLogDebug("replace: test1 phase1"); - ret = DetectReplaceLongPatternMatchTest(p, psize, sig_rep, sid_rep, NULL, NULL); - } - run_mode = run_mode_backup; - return ret; -} - - -/** - * \brief Wrapper for DetectContentLongPatternMatchTest - */ -int DetectReplaceLongPatternMatchTestUDPWrp(char *sig, uint32_t sid, char *sig_rep, uint32_t sid_rep) -{ - int ret; - /** Real UDP DNS packet with a request A to a1.twimg.com - */ - uint8_t raw_eth_pkt[] = { - 0x8c, 0xa9, 0x82, 0x75, 0x5d, 0x62, 0xb4, 0x07, - 0xf9, 0xf3, 0xc7, 0x0a, 0x08, 0x00, 0x45, 0x00, - 0x00, 0x3a, 0x92, 0x4f, 0x40, 0x00, 0x40, 0x11, - 0x31, 0x1a, 0xc0, 0xa8, 0x00, 0x02, 0xc1, 0xbd, - 0xf4, 0xe1, 0x3b, 0x7e, 0x00, 0x35, 0x00, 0x26, - 0xcb, 0x81, 0x37, 0x62, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x61, - 0x31, 0x05, 0x74, 0x77, 0x69, 0x6d, 0x67, 0x03, - 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 }; - - uint8_t p[sizeof(raw_eth_pkt)]; - uint16_t psize = sizeof(raw_eth_pkt); - - int run_mode_backup = run_mode; - run_mode = RUNMODE_NFQ; - ret = DetectReplaceLongPatternMatchTest(raw_eth_pkt, (uint16_t)sizeof(raw_eth_pkt), - sig, sid, p, &psize); - if (ret == 1) { - SCLogDebug("replace: test1 phase1 ok: %" PRIuMAX" vs %d",(uintmax_t)sizeof(raw_eth_pkt),psize); - ret = DetectReplaceLongPatternMatchTest(p, psize, sig_rep, sid_rep, NULL, NULL); - } - run_mode = run_mode_backup; - return ret; -} - -/** - * \test Check if replace is working - */ -static int DetectReplaceMatchTest01(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"big\"; replace:\"pig\"; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"this is a pig test\"; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working with offset - */ -static int DetectReplaceMatchTest02(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"th\"; offset: 4; replace:\"TH\"; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"THis\"; offset:4; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working with offset and keyword inversion - */ -static int DetectReplaceMatchTest03(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"th\"; replace:\"TH\"; offset: 4; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"THis\"; offset:4; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working with second content - */ -static int DetectReplaceMatchTest04(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"th\"; replace:\"TH\"; content:\"patter\"; replace:\"matter\"; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"THis\"; content:\"matterns\"; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is not done when second content don't match - */ -static int DetectReplaceMatchTest05(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"th\"; replace:\"TH\"; content:\"nutella\"; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"TH\"; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is not done when second content match and not - * first - */ -static int DetectReplaceMatchTest06(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"nutella\"; replace:\"commode\"; content:\"this is\"; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"commode\"; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working when nocase used - */ -static int DetectReplaceMatchTest07(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"BiG\"; nocase; replace:\"pig\"; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"this is a pig test\"; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working when depth is used - */ -static int DetectReplaceMatchTest08(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"big\"; depth:17; replace:\"pig\"; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"this is a pig test\"; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working when depth block match used - */ -static int DetectReplaceMatchTest09(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"big\"; depth:16; replace:\"pig\"; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"this is a pig test\"; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working when depth block match used - */ -static int DetectReplaceMatchTest10(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"big\"; depth:17; replace:\"pig\"; offset: 14; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"pig\"; depth:17; offset:14; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working with within - */ -static int DetectReplaceMatchTest11(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"big\"; replace:\"pig\"; content:\"to\"; within: 11; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"pig\"; depth:17; offset:14; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working with within - */ -static int DetectReplaceMatchTest12(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"big\"; replace:\"pig\"; content:\"to\"; within: 4; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"pig\"; depth:17; offset:14; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working with within - */ -static int DetectReplaceMatchTest13(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"big\"; replace:\"pig\"; content:\"test\"; distance: 1; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"pig\"; depth:17; offset:14; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working with within - */ -static int DetectReplaceMatchTest14(void) -{ - char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";" - " content:\"big\"; replace:\"pig\"; content:\"test\"; distance: 2; sid:1;)"; - char *sig_rep = "alert tcp any any -> any any (msg:\"replace worked\";" - " content:\"pig\"; depth:17; offset:14; sid:2;)"; - return DetectReplaceLongPatternMatchTestWrp(sig, 1, sig_rep, 2); -} - -/** - * \test Check if replace is working with within - */ -static int DetectReplaceMatchTest15(void) -{ - char *sig = "alert udp any any -> any any (msg:\"Nothing..\";" - " content:\"com\"; replace:\"org\"; sid:1;)"; - char *sig_rep = "alert udp any any -> any any (msg:\"replace worked\";" - " content:\"twimg|03|org\"; sid:2;)"; - return DetectReplaceLongPatternMatchTestUDPWrp(sig, 1, sig_rep, 2); -} - - -/** - * \test Parsing test - */ -static int DetectReplaceParseTest01(void) -{ - int run_mode_backup = run_mode; - run_mode = RUNMODE_NFQ; - - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; content:\"doh\"; replace:\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - run_mode = run_mode_backup; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test: non valid because of http protocol - */ -static int DetectReplaceParseTest02(void) -{ - int run_mode_backup = run_mode; - run_mode = RUNMODE_NFQ; - - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert http any any -> any any " - "(msg:\"test\"; content:\"doh\"; replace:\"bon\"; sid:238012;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - end: - run_mode = run_mode_backup; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test: non valid because of http_header on same content - * as replace keyword - */ -static int DetectReplaceParseTest03(void) -{ - int run_mode_backup = run_mode; - run_mode = RUNMODE_NFQ; - - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; content:\"doh\"; replace:\"don\"; http_header; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - run_mode = run_mode_backup; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test no content - */ -static int DetectReplaceParseTest04(void) -{ - int run_mode_backup = run_mode; - run_mode = RUNMODE_NFQ; - - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; replace:\"don\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - run_mode = run_mode_backup; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test content after replace - */ -static int DetectReplaceParseTest05(void) -{ - int run_mode_backup = run_mode; - run_mode = RUNMODE_NFQ; - - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; replace:\"don\"; content:\"doh\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - run_mode = run_mode_backup; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test content and replace length differ - */ -static int DetectReplaceParseTest06(void) -{ - int run_mode_backup = run_mode; - run_mode = RUNMODE_NFQ; - - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; content:\"don\"; replace:\"donut\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - run_mode = run_mode_backup; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test content and replace length differ - */ -static int DetectReplaceParseTest07(void) -{ - int run_mode_backup = run_mode; - run_mode = RUNMODE_NFQ; - - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; content:\"don\"; replace:\"dou\"; content:\"jpg\"; http_header; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - run_mode = run_mode_backup; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - - - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectContent - */ -void DetectReplaceRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ -/* matching */ - UtRegisterTest("DetectReplaceMatchTest01", DetectReplaceMatchTest01, 1); - UtRegisterTest("DetectReplaceMatchTest02", DetectReplaceMatchTest02, 1); - UtRegisterTest("DetectReplaceMatchTest03", DetectReplaceMatchTest03, 1); - UtRegisterTest("DetectReplaceMatchTest04", DetectReplaceMatchTest04, 1); - UtRegisterTest("DetectReplaceMatchTest05", DetectReplaceMatchTest05, 0); - UtRegisterTest("DetectReplaceMatchTest06", DetectReplaceMatchTest06, 0); - UtRegisterTest("DetectReplaceMatchTest07", DetectReplaceMatchTest07, 1); - UtRegisterTest("DetectReplaceMatchTest08", DetectReplaceMatchTest08, 1); - UtRegisterTest("DetectReplaceMatchTest09", DetectReplaceMatchTest09, 0); - UtRegisterTest("DetectReplaceMatchTest10", DetectReplaceMatchTest10, 1); - UtRegisterTest("DetectReplaceMatchTest11", DetectReplaceMatchTest11, 1); - UtRegisterTest("DetectReplaceMatchTest12", DetectReplaceMatchTest12, 0); - UtRegisterTest("DetectReplaceMatchTest13", DetectReplaceMatchTest13, 1); - UtRegisterTest("DetectReplaceMatchTest14", DetectReplaceMatchTest14, 0); - UtRegisterTest("DetectReplaceMatchTest15", DetectReplaceMatchTest15, 1); -/* parsing */ - UtRegisterTest("DetectReplaceParseTest01", DetectReplaceParseTest01, 1); - UtRegisterTest("DetectReplaceParseTest02", DetectReplaceParseTest02, 1); - UtRegisterTest("DetectReplaceParseTest03", DetectReplaceParseTest03, 1); - UtRegisterTest("DetectReplaceParseTest04", DetectReplaceParseTest04, 1); - UtRegisterTest("DetectReplaceParseTest05", DetectReplaceParseTest05, 1); - UtRegisterTest("DetectReplaceParseTest06", DetectReplaceParseTest06, 1); - UtRegisterTest("DetectReplaceParseTest07", DetectReplaceParseTest07, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-replace.h b/framework/src/suricata/src/detect-replace.h deleted file mode 100644 index 020f73c4..00000000 --- a/framework/src/suricata/src/detect-replace.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (C) 2011-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#ifndef __DETECT_REPLACE_H__ -#define __DETECT_REPLACE_H__ - -DetectReplaceList * DetectReplaceAddToList(DetectReplaceList *replist, uint8_t *found, DetectContentData *cd); - -/* Internal functions are only called via the inline functions below. */ -void DetectReplaceExecuteInternal(Packet *p, DetectReplaceList *replist); -void DetectReplaceFreeInternal(DetectReplaceList *replist); - -static inline void DetectReplaceExecute(Packet *p, DetectEngineThreadCtx *det_ctx) -{ - if (p == NULL || det_ctx->replist == NULL) - return; - DetectReplaceExecuteInternal(p, det_ctx->replist); - det_ctx->replist = NULL; -} - -static inline void DetectReplaceFree(DetectEngineThreadCtx *det_ctx) -{ - if (det_ctx->replist) { - DetectReplaceFreeInternal(det_ctx->replist); - det_ctx->replist = NULL; - } -} - -void DetectReplaceRegister (void); - -#endif diff --git a/framework/src/suricata/src/detect-rev.c b/framework/src/suricata/src/detect-rev.c deleted file mode 100644 index 6306f6cc..00000000 --- a/framework/src/suricata/src/detect-rev.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the rev keyword - */ - -#include "suricata-common.h" -#include "detect.h" -#include "util-debug.h" -#include "util-error.h" - -static int DetectRevSetup (DetectEngineCtx *, Signature *, char *); - -void DetectRevRegister (void) -{ - sigmatch_table[DETECT_REV].name = "rev"; - sigmatch_table[DETECT_REV].desc = "set version of the rule"; - sigmatch_table[DETECT_REV].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Meta-settings#Rev-Revision"; - sigmatch_table[DETECT_REV].Match = NULL; - sigmatch_table[DETECT_REV].Setup = DetectRevSetup; - sigmatch_table[DETECT_REV].Free = NULL; - sigmatch_table[DETECT_REV].RegisterTests = NULL; -} - -static int DetectRevSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - char *str = rawstr; - char dubbed = 0; - - /* strip "'s */ - if (rawstr[0] == '\"' && rawstr[strlen(rawstr)-1] == '\"') { - str = SCStrdup(rawstr+1); - if (unlikely(str == NULL)) - return -1; - - str[strlen(rawstr)-2] = '\0'; - dubbed = 1; - } - - unsigned long rev = 0; - char *endptr = NULL; - rev = strtoul(rawstr, &endptr, 10); - if (endptr == NULL || *endptr != '\0') { - SCLogError(SC_ERR_INVALID_SIGNATURE, "invalid character as arg " - "to rev keyword"); - goto error; - } - if (rev >= UINT_MAX) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "rev value to high, max %u", UINT_MAX); - goto error; - } - - s->rev = (uint32_t)rev; - - if (dubbed) - SCFree(str); - return 0; - - error: - if (dubbed) - SCFree(str); - return -1; -} - diff --git a/framework/src/suricata/src/detect-rev.h b/framework/src/suricata/src/detect-rev.h deleted file mode 100644 index 24ae202f..00000000 --- a/framework/src/suricata/src/detect-rev.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_REV_H__ -#define __DETECT_REV_H__ - -/* prototypes */ -void DetectRevRegister (void); - -#endif /* __DETECT_REV_H__ */ - diff --git a/framework/src/suricata/src/detect-rpc.c b/framework/src/suricata/src/detect-rpc.c deleted file mode 100644 index 86fc03c6..00000000 --- a/framework/src/suricata/src/detect-rpc.c +++ /dev/null @@ -1,609 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * - * Implements RPC keyword - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-rpc.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-siggroup.h" -#include "detect-engine-address.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" -#include "util-byte.h" - -/** - * \brief Regex for parsing our rpc options - */ -#define PARSE_REGEX "^\\s*([0-9]{0,10})\\s*(?:,\\s*([0-9]{0,10}|[*])\\s*(?:,\\s*([0-9]{0,10}|[*]))?)?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectRpcMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -int DetectRpcSetup (DetectEngineCtx *, Signature *, char *); -void DetectRpcRegisterTests(void); -void DetectRpcFree(void *); - -/** - * \brief Registration function for rpc keyword - */ -void DetectRpcRegister (void) -{ - sigmatch_table[DETECT_RPC].name = "rpc"; - sigmatch_table[DETECT_RPC].desc = "match RPC procedure numbers and RPC version"; - sigmatch_table[DETECT_RPC].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#rpc"; - sigmatch_table[DETECT_RPC].Match = DetectRpcMatch; - sigmatch_table[DETECT_RPC].Setup = DetectRpcSetup; - sigmatch_table[DETECT_RPC].Free = DetectRpcFree; - sigmatch_table[DETECT_RPC].RegisterTests = DetectRpcRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - /* XXX */ - return; -} - -/* - * returns 0: no match - * 1: match - * -1: error - */ - -/** - * \brief This function is used to match rpc request set on a packet with those passed via rpc - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectRpcData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectRpcMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - /* PrintRawDataFp(stdout, p->payload, p->payload_len); */ - const DetectRpcData *rd = (const DetectRpcData *)ctx; - char *rpcmsg = (char *)p->payload; - - if (PKT_IS_TCP(p)) { - /* if Rpc msg too small */ - if (p->payload_len < 28) { - SCLogDebug("TCP packet to small for the rpc msg (%u)", p->payload_len); - return 0; - } - rpcmsg += 4; - } else if (PKT_IS_UDP(p)) { - /* if Rpc msg too small */ - if (p->payload_len < 24) { - SCLogDebug("UDP packet to small for the rpc msg (%u)", p->payload_len); - return 0; - } - } else { - SCLogDebug("No valid proto for the rpc message"); - return 0; - } - - /* Point through the rpc msg structure. Use ntohl() to compare values */ - RpcMsg *msg = (RpcMsg *)rpcmsg; - - /* If its not a call, no match */ - if (ntohl(msg->type) != 0) { - SCLogDebug("RPC message type is not a call"); - return 0; - } - - if (ntohl(msg->prog) != rd->program) - return 0; - - if ((rd->flags & DETECT_RPC_CHECK_VERSION) && ntohl(msg->vers) != rd->program_version) - return 0; - - if ((rd->flags & DETECT_RPC_CHECK_PROCEDURE) && ntohl(msg->proc) != rd->procedure) - return 0; - - SCLogDebug("prog:%u pver:%u proc:%u matched", ntohl(msg->prog), ntohl(msg->vers), ntohl(msg->proc)); - return 1; -} - -/** - * \brief This function is used to parse rpc options passed via rpc keyword - * - * \param rpcstr Pointer to the user provided rpc options - * - * \retval rd pointer to DetectRpcData on success - * \retval NULL on failure - */ -DetectRpcData *DetectRpcParse (char *rpcstr) -{ - DetectRpcData *rd = NULL; - char *args[3] = {NULL,NULL,NULL}; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, rpcstr, strlen(rpcstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 ", string %s", ret, rpcstr); - goto error; - } - - if (ret > 1) { - const char *str_ptr; - res = pcre_get_substring((char *)rpcstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[0] = (char *)str_ptr; - - if (ret > 2) { - res = pcre_get_substring((char *)rpcstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[1] = (char *)str_ptr; - } - if (ret > 3) { - res = pcre_get_substring((char *)rpcstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - args[2] = (char *)str_ptr; - } - } - - rd = SCMalloc(sizeof(DetectRpcData)); - if (unlikely(rd == NULL)) - goto error; - rd->flags = 0; - rd->program = 0; - rd->program_version = 0; - rd->procedure = 0; - - int i; - for (i = 0; i < (ret -1); i++) { - if (args[i]) { - switch (i) { - case 0: - if (ByteExtractStringUint32(&rd->program, 10, strlen(args[i]), args[i]) <= 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid size specified for the rpc program:\"%s\"", args[i]); - goto error; - } - rd->flags |= DETECT_RPC_CHECK_PROGRAM; - break; - case 1: - if (args[i][0] != '*') { - if (ByteExtractStringUint32(&rd->program_version, 10, strlen(args[i]), args[i]) <= 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid size specified for the rpc version:\"%s\"", args[i]); - goto error; - } - rd->flags |= DETECT_RPC_CHECK_VERSION; - } - break; - case 2: - if (args[i][0] != '*') { - if (ByteExtractStringUint32(&rd->procedure, 10, strlen(args[i]), args[i]) <= 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid size specified for the rpc procedure:\"%s\"", args[i]); - goto error; - } - rd->flags |= DETECT_RPC_CHECK_PROCEDURE; - } - break; - } - } else { - SCLogError(SC_ERR_INVALID_VALUE, "invalid rpc option %s",args[i]); - goto error; - } - } - for (i = 0; i < (ret -1); i++){ - if (args[i] != NULL) - SCFree(args[i]); - } - return rd; - -error: - for (i = 0; i < (ret -1) && i < 3; i++){ - if (args[i] != NULL) - SCFree(args[i]); - } - if (rd != NULL) - DetectRpcFree(rd); - return NULL; - -} - -/** - * \brief this function is used to add the parsed rpcdata into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param m pointer to the Current SigMatch - * \param rpcstr pointer to the user provided rpc options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectRpcSetup (DetectEngineCtx *de_ctx, Signature *s, char *rpcstr) -{ - DetectRpcData *rd = NULL; - SigMatch *sm = NULL; - - rd = DetectRpcParse(rpcstr); - if (rd == NULL) goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_RPC; - sm->ctx = (SigMatchCtx *)rd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (rd != NULL) DetectRpcFree(rd); - if (sm != NULL) SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectRpcData - * - * \param rd pointer to DetectRpcData - */ -void DetectRpcFree(void *ptr) -{ - SCEnter(); - - if (ptr == NULL) { - SCReturn; - } - - DetectRpcData *rd = (DetectRpcData *)ptr; - SCFree(rd); - - SCReturn; -} - -#ifdef UNITTESTS -/** - * \test DetectRpcTestParse01 is a test to make sure that we return "something" - * when given valid rpc opt - */ -int DetectRpcTestParse01 (void) -{ - int result = 0; - DetectRpcData *rd = NULL; - rd = DetectRpcParse("123,444,555"); - if (rd != NULL) { - DetectRpcFree(rd); - result = 1; - } - - return result; -} - -/** - * \test DetectRpcTestParse02 is a test for setting the established rpc opt - */ -int DetectRpcTestParse02 (void) -{ - int result = 0; - DetectRpcData *rd = NULL; - rd = DetectRpcParse("111,222,333"); - if (rd != NULL) { - if (rd->flags & DETECT_RPC_CHECK_PROGRAM && - rd->flags & DETECT_RPC_CHECK_VERSION && - rd->flags & DETECT_RPC_CHECK_PROCEDURE && - rd->program == 111 && rd->program_version == 222 && - rd->procedure == 333) { - result = 1; - } else { - SCLogDebug("Error: Flags: %d; program: %u, version: %u, procedure: %u", rd->flags, rd->program, rd->program_version, rd->procedure); - } - DetectRpcFree(rd); - } - - return result; -} - -/** - * \test DetectRpcTestParse03 is a test for checking the wildcards - * and not specified fields - */ -int DetectRpcTestParse03 (void) -{ - int result = 1; - DetectRpcData *rd = NULL; - rd = DetectRpcParse("111,*,333"); - if (rd == NULL) - return 0; - - if ( !(rd->flags & DETECT_RPC_CHECK_PROGRAM && - !(rd->flags & DETECT_RPC_CHECK_VERSION) && - rd->flags & DETECT_RPC_CHECK_PROCEDURE && - rd->program == 111 && rd->program_version == 0 && - rd->procedure == 333)) - result = 0; - SCLogDebug("rd1 Flags: %d; program: %u, version: %u, procedure: %u", rd->flags, rd->program, rd->program_version, rd->procedure); - - DetectRpcFree(rd); - - rd = DetectRpcParse("111,222,*"); - if (rd == NULL) - return 0; - - if ( !(rd->flags & DETECT_RPC_CHECK_PROGRAM && - rd->flags & DETECT_RPC_CHECK_VERSION && - !(rd->flags & DETECT_RPC_CHECK_PROCEDURE) && - rd->program == 111 && rd->program_version == 222 && - rd->procedure == 0)) - result = 0; - SCLogDebug("rd2 Flags: %d; program: %u, version: %u, procedure: %u", rd->flags, rd->program, rd->program_version, rd->procedure); - - DetectRpcFree(rd); - - rd = DetectRpcParse("111,*,*"); - if (rd == NULL) - return 0; - - if ( !(rd->flags & DETECT_RPC_CHECK_PROGRAM && - !(rd->flags & DETECT_RPC_CHECK_VERSION) && - !(rd->flags & DETECT_RPC_CHECK_PROCEDURE) && - rd->program == 111 && rd->program_version == 0 && - rd->procedure == 0)) - result = 0; - SCLogDebug("rd2 Flags: %d; program: %u, version: %u, procedure: %u", rd->flags, rd->program, rd->program_version, rd->procedure); - - DetectRpcFree(rd); - - rd = DetectRpcParse("111,222"); - if (rd == NULL) - return 0; - - if ( !(rd->flags & DETECT_RPC_CHECK_PROGRAM && - rd->flags & DETECT_RPC_CHECK_VERSION && - !(rd->flags & DETECT_RPC_CHECK_PROCEDURE) && - rd->program == 111 && rd->program_version == 222 && - rd->procedure == 0)) - result = 0; - SCLogDebug("rd2 Flags: %d; program: %u, version: %u, procedure: %u", rd->flags, rd->program, rd->program_version, rd->procedure); - - DetectRpcFree(rd); - - rd = DetectRpcParse("111"); - if (rd == NULL) - return 0; - - if ( !(rd->flags & DETECT_RPC_CHECK_PROGRAM && - !(rd->flags & DETECT_RPC_CHECK_VERSION) && - !(rd->flags & DETECT_RPC_CHECK_PROCEDURE) && - rd->program == 111 && rd->program_version == 0 && - rd->procedure == 0)) - result = 0; - SCLogDebug("rd2 Flags: %d; program: %u, version: %u, procedure: %u", rd->flags, rd->program, rd->program_version, rd->procedure); - - DetectRpcFree(rd); - return result; -} - -/** - * \test DetectRpcTestParse04 is a test for check the discarding of empty options - */ -int DetectRpcTestParse04 (void) -{ - int result = 0; - DetectRpcData *rd = NULL; - rd = DetectRpcParse(""); - if (rd == NULL) { - result = 1; - } else { - SCLogDebug("Error: Flags: %d; program: %u, version: %u, procedure: %u", rd->flags, rd->program, rd->program_version, rd->procedure); - DetectRpcFree(rd); - } - - return result; -} - -/** - * \test DetectRpcTestParse05 is a test for check invalid values - */ -int DetectRpcTestParse05 (void) -{ - int result = 0; - DetectRpcData *rd = NULL; - rd = DetectRpcParse("111,aaa,*"); - if (rd == NULL) { - result = 1; - } else { - SCLogDebug("Error: Flags: %d; program: %u, version: %u, procedure: %u", rd->flags, rd->program, rd->program_version, rd->procedure); - DetectRpcFree(rd); - } - - return result; -} - -/** - * \test DetectRpcTestParse05 is a test to check the match function - */ -static int DetectRpcTestSig01(void) -{ - /* RPC Call */ - uint8_t buf[] = { - /* XID */ - 0x64,0xb2,0xb3,0x75, - /* Message type: Call (0) */ - 0x00,0x00,0x00,0x00, - /* RPC Version (2) */ - 0x00,0x00,0x00,0x02, - /* Program portmap (100000) */ - 0x00,0x01,0x86,0xa0, - /* Program version (2) */ - 0x00,0x00,0x00,0x02, - /* Program procedure (3) = GETPORT */ - 0x00,0x00,0x00,0x03, - /* AUTH_NULL */ - 0x00,0x00,0x00,0x00, - /* Length 0 */ - 0x00,0x00,0x00,0x00, - /* VERIFIER NULL */ - 0x00,0x00,0x00,0x00, - /* Length 0 */ - 0x00,0x00,0x00,0x00, - /* Program portmap */ - 0x00,0x01,0x86,0xa2, - /* Version 2 */ - 0x00,0x00,0x00,0x02, - /* Proto UDP */ - 0x00,0x00,0x00,0x11, - /* Port 0 */ - 0x00,0x00,0x00,0x00 }; - uint16_t buflen = sizeof(buf); - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(buf, buflen, IPPROTO_UDP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert udp any any -> any any (msg:\"RPC Get Port Call\"; rpc:100000, 2, 3; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert udp any any -> any any (msg:\"RPC Get Port Call\"; rpc:100000, 2, *; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert udp any any -> any any (msg:\"RPC Get Port Call\"; rpc:100000, *, 3; sid:3;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert udp any any -> any any (msg:\"RPC Get Port Call\"; rpc:100000, *, *; sid:4;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert udp any any -> any any (msg:\"RPC Get XXX Call.. no match\"; rpc:123456, *, 3; sid:5;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) == 0) { - printf("sid 1 didnt alert, but it should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2) == 0) { - printf("sid 2 didnt alert, but it should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 3) == 0) { - printf("sid 3 didnt alert, but it should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 4) == 0) { - printf("sid 4 didnt alert, but it should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 5) > 0) { - printf("sid 5 did alert, but should not: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - DetectSigGroupPrintMemory(); - DetectAddressPrintMemory(); - UTHFreePackets(&p, 1); -end: - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectRpc - */ -void DetectRpcRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectRpcTestParse01", DetectRpcTestParse01, 1); - UtRegisterTest("DetectRpcTestParse02", DetectRpcTestParse02, 1); - UtRegisterTest("DetectRpcTestParse03", DetectRpcTestParse03, 1); - UtRegisterTest("DetectRpcTestParse04", DetectRpcTestParse04, 1); - UtRegisterTest("DetectRpcTestParse05", DetectRpcTestParse05, 1); - UtRegisterTest("DetectRpcTestSig01", DetectRpcTestSig01, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-rpc.h b/framework/src/suricata/src/detect-rpc.h deleted file mode 100644 index 6a5bc6c7..00000000 --- a/framework/src/suricata/src/detect-rpc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_RPC_H__ -#define __DETECT_RPC_H__ - -/* At least we check the program, the version is optional, - * and the procedure is optional if we are checking the version. - * If we parse the wildcard "*" we will allow any value (no check) */ -#define DETECT_RPC_CHECK_PROGRAM 0x01 -#define DETECT_RPC_CHECK_VERSION 0x02 -#define DETECT_RPC_CHECK_PROCEDURE 0x04 - -/** Simple struct for a rpc msg call */ -typedef struct RpcMsg_ { - uint32_t xid; - uint32_t type; /**< CALL = 0 (We only search for CALLS */ - uint32_t rpcvers; /**< must be equal to two (2) */ - uint32_t prog; - uint32_t vers; - uint32_t proc; -} RpcMsg; - -/* Extract uint32_t */ -#define EXT_GET_UINT32T(buf) ((long)ntohl((long)*(buf)++)) - -typedef struct DetectRpcData_ { - uint32_t program; - uint32_t program_version; - uint32_t procedure; - uint8_t flags; -} DetectRpcData; - -/* prototypes */ -void DetectRpcRegister (void); - -#endif /* __DETECT_RPC_H__ */ - diff --git a/framework/src/suricata/src/detect-sameip.c b/framework/src/suricata/src/detect-sameip.c deleted file mode 100644 index a8e02908..00000000 --- a/framework/src/suricata/src/detect-sameip.c +++ /dev/null @@ -1,222 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - * - * Implements the sameip keyword. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "detect-sameip.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -static int DetectSameipMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static int DetectSameipSetup(DetectEngineCtx *, Signature *, char *); -static void DetectSameipRegisterTests(void); - -/** - * \brief Registration function for sameip: keyword - * \todo add support for no_stream and stream_only - */ -void DetectSameipRegister(void) -{ - sigmatch_table[DETECT_SAMEIP].name = "sameip"; - sigmatch_table[DETECT_SAMEIP].desc = "check if the IP address of the source is the same as the IP address of the destination"; - sigmatch_table[DETECT_SAMEIP].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#sameip"; - sigmatch_table[DETECT_SAMEIP].Match = DetectSameipMatch; - sigmatch_table[DETECT_SAMEIP].Setup = DetectSameipSetup; - sigmatch_table[DETECT_SAMEIP].Free = NULL; - sigmatch_table[DETECT_SAMEIP].RegisterTests = DetectSameipRegisterTests; - sigmatch_table[DETECT_SAMEIP].flags = SIGMATCH_NOOPT; -} - -/** - * \internal - * \brief This function is used to match packets with same src/dst IPs - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectSameipData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectSameipMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - return CMP_ADDR(&p->src, &p->dst) ? 1 : 0; -} - -/** - * \internal - * \brief this function is used to add the sameip option into the signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param optstr pointer to the user provided options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectSameipSetup(DetectEngineCtx *de_ctx, Signature *s, char *optstr) -{ - SigMatch *sm = NULL; - - /* Get this into a SigMatch and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_SAMEIP; - sm->ctx = NULL; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (sm != NULL) - SCFree(sm); - return -1; - -} - -#ifdef UNITTESTS - -/* NOTE: No parameters, so no parse tests */ - -/** - * \internal - * \brief This test tests sameip success and failure. - */ -static int DetectSameipSigTest01Real(int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET / HTTP/1.0\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - /* First packet has same IPs */ - p1 = UTHBuildPacketSrcDst(buf, buflen, IPPROTO_TCP, "1.2.3.4", "1.2.3.4"); - - /* Second packet does not have same IPs */ - p2 = UTHBuildPacketSrcDst(buf, buflen, IPPROTO_TCP, "1.2.3.4", "4.3.2.1"); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing sameip\"; sameip; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1) == 0) { - printf("sid 2 did not alert, but should have: "); - goto cleanup; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 1) != 0) { - printf("sid 2 alerted, but should not have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - return result; -} - -/** - * \test DetectSameipSigTest01B2g tests sameip under B2g MPM - */ -static int DetectSameipSigTest01B2g(void) -{ - return DetectSameipSigTest01Real(MPM_B2G); -} - -/** - * \test DetectSameipSigTest01B2g tests sameip under B3g MPM - */ -static int DetectSameipSigTest01B3g(void) -{ - return DetectSameipSigTest01Real(MPM_B3G); -} - -/** - * \test DetectSameipSigTest01B2g tests sameip under WuManber MPM - */ -static int DetectSameipSigTest01Wm(void) -{ - return DetectSameipSigTest01Real(MPM_WUMANBER); -} - -#endif /* UNITTESTS */ - -/** - * \internal - * \brief This function registers unit tests for DetectSameip - */ -static void DetectSameipRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectSameipSigTest01B2g", DetectSameipSigTest01B2g, 1); - UtRegisterTest("DetectSameipSigTest01B3g", DetectSameipSigTest01B3g, 1); - UtRegisterTest("DetectSameipSigTest01Wm", DetectSameipSigTest01Wm, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-sameip.h b/framework/src/suricata/src/detect-sameip.h deleted file mode 100644 index ef6b54b6..00000000 --- a/framework/src/suricata/src/detect-sameip.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - */ - -#ifndef __DETECT_SAMEIP_H__ -#define __DETECT_SAMEIP_H__ - -/* prototypes */ -void DetectSameipRegister(void); - -#endif /* __DETECT_SAMEIP_H__ */ diff --git a/framework/src/suricata/src/detect-seq.c b/framework/src/suricata/src/detect-seq.c deleted file mode 100644 index 4d285ca3..00000000 --- a/framework/src/suricata/src/detect-seq.c +++ /dev/null @@ -1,243 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - * - * Implements the seq keyword. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" -#include "detect.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "detect-seq.h" - -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -static int DetectSeqSetup(DetectEngineCtx *, Signature *, char *); -static int DetectSeqMatch(ThreadVars *, DetectEngineThreadCtx *, - Packet *, Signature *, const SigMatchCtx *); -static void DetectSeqRegisterTests(void); -static void DetectSeqFree(void *); - - -void DetectSeqRegister(void) -{ - sigmatch_table[DETECT_SEQ].name = "seq"; - sigmatch_table[DETECT_SEQ].desc = "check for a specific TCP sequence number"; - sigmatch_table[DETECT_SEQ].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#seq"; - sigmatch_table[DETECT_SEQ].Match = DetectSeqMatch; - sigmatch_table[DETECT_SEQ].Setup = DetectSeqSetup; - sigmatch_table[DETECT_SEQ].Free = DetectSeqFree; - sigmatch_table[DETECT_SEQ].RegisterTests = DetectSeqRegisterTests; -} - -/** - * \internal - * \brief This function is used to match packets with a given Seq number - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectSeqData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectSeqMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectSeqData *data = (const DetectSeqData *)ctx; - - /* This is only needed on TCP packets */ - if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) { - return 0; - } - - return (data->seq == TCP_GET_SEQ(p)) ? 1 : 0; -} - -/** - * \internal - * \brief this function is used to add the seq option into the signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param optstr pointer to the user provided options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectSeqSetup (DetectEngineCtx *de_ctx, Signature *s, char *optstr) -{ - DetectSeqData *data = NULL; - SigMatch *sm = NULL; - - data = SCMalloc(sizeof(DetectSeqData)); - if (unlikely(data == NULL)) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_SEQ; - - if (-1 == ByteExtractStringUint32(&data->seq, 10, 0, optstr)) { - goto error; - } - sm->ctx = (SigMatchCtx*)data; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (data) - SCFree(data); - if (sm) - SigMatchFree(sm); - return -1; - -} - -/** - * \internal - * \brief this function will free memory associated with seq option - * - * \param data pointer to seq configuration data - */ -static void DetectSeqFree(void *ptr) -{ - DetectSeqData *data = (DetectSeqData *)ptr; - SCFree(data); -} - - -#ifdef UNITTESTS - -/** - * \test DetectSeqSigTest01 tests parses - */ -static int DetectSeqSigTest01(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - /* These three are crammed in here as there is no Parse */ - if (SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing seq\";seq:foo;sid:1;)") != NULL) - { - printf("invalid seq accepted: "); - goto cleanup; - } - if (SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing seq\";seq:9999999999;sid:1;)") != NULL) - { - printf("overflowing seq accepted: "); - goto cleanup; - } - if (SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing seq\";seq:-100;sid:1;)") != NULL) - { - printf("negative seq accepted: "); - goto cleanup; - } - result = 1; - -cleanup: - if (de_ctx) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } -end: - return result; -} - -/** - * \test DetectSeqSigTest02 tests seq keyword - */ -static int DetectSeqSigTest02(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[1] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[2] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_ICMP); - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - /* TCP w/seq=42 */ - p[0]->tcph->th_seq = htonl(42); - - /* TCP w/seq=100 */ - p[1]->tcph->th_seq = htonl(100); - - char *sigs[2]; - sigs[0]= "alert tcp any any -> any any (msg:\"Testing seq\"; seq:41; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"Testing seq\"; seq:42; sid:2;)"; - - uint32_t sid[2] = {1, 2}; - - uint32_t results[3][2] = { - /* packet 0 match sid 1 but should not match sid 2 */ - {0, 1}, - /* packet 1 should not match */ - {0, 0}, - /* packet 2 should not match */ - {0, 0} }; - - result = UTHGenericTest(p, 3, sigs, sid, (uint32_t *) results, 2); - UTHFreePackets(p, 3); -end: - return result; -} - -#endif /* UNITTESTS */ - -/** - * \internal - * \brief This function registers unit tests for DetectSeq - */ -static void DetectSeqRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectSeqSigTest01", DetectSeqSigTest01, 1); - UtRegisterTest("DetectSeqSigTest02", DetectSeqSigTest02, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-seq.h b/framework/src/suricata/src/detect-seq.h deleted file mode 100644 index 813e8fab..00000000 --- a/framework/src/suricata/src/detect-seq.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - */ - -#ifndef __DETECT_SEQ_H__ -#define __DETECT_SEQ_H__ - -/** - * \brief seq data - */ -typedef struct DetectSeqData_ { - uint32_t seq; /**< seq to match */ -} DetectSeqData; - -/** - * \brief Registration function for ack: keyword - */ -void DetectSeqRegister(void); - -#endif /* __DETECT_SEQ_H__ */ - diff --git a/framework/src/suricata/src/detect-sid.c b/framework/src/suricata/src/detect-sid.c deleted file mode 100644 index a3ed3403..00000000 --- a/framework/src/suricata/src/detect-sid.c +++ /dev/null @@ -1,165 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the sid keyword - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-unittest.h" - -static int DetectSidSetup (DetectEngineCtx *, Signature *, char *); -static void DetectSidRegisterTests(void); - -void DetectSidRegister (void) -{ - sigmatch_table[DETECT_SID].name = "sid"; - sigmatch_table[DETECT_SID].desc = "set rule id"; - sigmatch_table[DETECT_SID].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Meta-settings#Sid-signature-id"; - sigmatch_table[DETECT_SID].Match = NULL; - sigmatch_table[DETECT_SID].Setup = DetectSidSetup; - sigmatch_table[DETECT_SID].Free = NULL; - sigmatch_table[DETECT_SID].RegisterTests = DetectSidRegisterTests; -} - -static int DetectSidSetup (DetectEngineCtx *de_ctx, Signature *s, char *sidstr) -{ - char *str = sidstr; - char duped = 0; - - /* Strip leading and trailing "s. */ - if (sidstr[0] == '\"') { - str = SCStrdup(sidstr + 1); - if (unlikely(str == NULL)) { - return -1; - } - if (strlen(str) && str[strlen(str) - 1] == '\"') { - str[strlen(str) - 1] = '\0'; - } - duped = 1; - } - - unsigned long id = 0; - char *endptr = NULL; - id = strtoul(sidstr, &endptr, 10); - if (endptr == NULL || *endptr != '\0') { - SCLogError(SC_ERR_INVALID_SIGNATURE, "invalid character as arg " - "to sid keyword"); - goto error; - } - if (id >= UINT_MAX) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "sid value to high, max %u", UINT_MAX); - goto error; - } - - s->id = (uint32_t)id; - - if (duped) - SCFree(str); - return 0; - - error: - if (duped) - SCFree(str); - return -1; -} - -#ifdef UNITTESTS - -static int SidTestParse01(void) -{ - int result = 0; - Signature *s = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - s = DetectEngineAppendSig(de_ctx, - "alert tcp 1.2.3.4 any -> any any (sid:1; gid:1;)"); - if (s == NULL || s->id != 1) - goto end; - - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SidTestParse02(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (DetectEngineAppendSig(de_ctx, - "alert tcp 1.2.3.4 any -> any any (sid:a; gid:1;)") != NULL) - goto end; - - result = 1; - -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SidTestParse03(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - if (DetectEngineAppendSig(de_ctx, - "alert tcp any any -> any any (content:\"ABC\"; sid:\";)") != NULL) - goto end; - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif - -/** - * \brief Register DetectSid unit tests. - */ -static void DetectSidRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SidTestParse01", SidTestParse01, 1); - UtRegisterTest("SidTestParse02", SidTestParse02, 1); - UtRegisterTest("SidTestParse03", SidTestParse03, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-sid.h b/framework/src/suricata/src/detect-sid.h deleted file mode 100644 index f7389d10..00000000 --- a/framework/src/suricata/src/detect-sid.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_SID_H__ -#define __DETECT_SID_H__ - -/* prototypes */ -void DetectSidRegister (void); - -#endif /* __DETECT_SID_H__ */ - diff --git a/framework/src/suricata/src/detect-ssh-proto-version.c b/framework/src/suricata/src/detect-ssh-proto-version.c deleted file mode 100644 index 96a8b676..00000000 --- a/framework/src/suricata/src/detect-ssh-proto-version.c +++ /dev/null @@ -1,700 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * - * Implements the ssh.protoversion keyword - * You can specify a concrete version like ssh.protoversion: 1.66 - * or search for protoversion 2 compat (1.99 is considered as 2) like - * ssh.protoversion:2_compat - * or just the beginning of the string like ssh.protoversion:"1." - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-ssh.h" -#include "detect-ssh-proto-version.h" - -#include "stream-tcp.h" - -/** - * \brief Regex for parsing the protoversion string - */ -#define PARSE_REGEX "^\\s*\"?\\s*([0-9]+([\\.\\-0-9]+)?|2_compat)\\s*\"?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectSshVersionMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, void *, Signature *, SigMatch *); -static int DetectSshVersionSetup (DetectEngineCtx *, Signature *, char *); -void DetectSshVersionRegisterTests(void); -void DetectSshVersionFree(void *); - -/** - * \brief Registration function for keyword: ssh.protoversion - */ -void DetectSshVersionRegister(void) -{ - sigmatch_table[DETECT_AL_SSH_PROTOVERSION].name = "ssh.protoversion"; - sigmatch_table[DETECT_AL_SSH_PROTOVERSION].Match = NULL; - sigmatch_table[DETECT_AL_SSH_PROTOVERSION].AppLayerMatch = DetectSshVersionMatch; - sigmatch_table[DETECT_AL_SSH_PROTOVERSION].alproto = ALPROTO_SSH; - sigmatch_table[DETECT_AL_SSH_PROTOVERSION].Setup = DetectSshVersionSetup; - sigmatch_table[DETECT_AL_SSH_PROTOVERSION].Free = DetectSshVersionFree; - sigmatch_table[DETECT_AL_SSH_PROTOVERSION].RegisterTests = DetectSshVersionRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - SCLogDebug("registering ssh.protoversion rule option"); - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -/** - * \brief match the specified version on a ssh session - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectSshVersionData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectSshVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - - DetectSshVersionData *ssh = (DetectSshVersionData *)m->ctx; - SshState *ssh_state = (SshState *)state; - if (ssh_state == NULL) { - SCLogDebug("no ssh state, no match"); - SCReturnInt(0); - } - - int ret = 0; - if ((flags & STREAM_TOCLIENT) && (ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - if (ssh->flags & SSH_FLAG_PROTOVERSION_2_COMPAT) { - SCLogDebug("looking for ssh server protoversion 2 compat"); - if (strncmp((char *) ssh_state->srv_hdr.proto_version, "2", 1) == 0 || - strncmp((char *) ssh_state->srv_hdr.proto_version, "2.", 2) == 0 || - strncmp((char *) ssh_state->srv_hdr.proto_version, "1.99", 4) == 0) - ret = 1; - } else { - SCLogDebug("looking for ssh server protoversion %s length %"PRIu16"", ssh->ver, ssh->len); - ret = (strncmp((char *) ssh_state->srv_hdr.proto_version, (char *) ssh->ver, ssh->len) == 0)? 1 : 0; - } - } else if ((flags & STREAM_TOSERVER) && (ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - if (ssh->flags & SSH_FLAG_PROTOVERSION_2_COMPAT) { - SCLogDebug("looking for client ssh client protoversion 2 compat"); - if (strncmp((char *) ssh_state->cli_hdr.proto_version, "2", 1) == 0 || - strncmp((char *) ssh_state->cli_hdr.proto_version, "2.", 2) == 0 || - strncmp((char *) ssh_state->cli_hdr.proto_version, "1.99", 4) == 0) - ret = 1; - } else { - SCLogDebug("looking for ssh client protoversion %s length %"PRIu16"", ssh->ver, ssh->len); - ret = (strncmp((char *) ssh_state->cli_hdr.proto_version, (char *) ssh->ver, ssh->len) == 0)? 1 : 0; - } - } - SCReturnInt(ret); -} - -/** - * \brief This function is used to parse IPV4 ip_id passed via keyword: "id" - * - * \param idstr Pointer to the user provided id option - * - * \retval id_d pointer to DetectSshVersionData on success - * \retval NULL on failure - */ -DetectSshVersionData *DetectSshVersionParse (char *str) -{ - DetectSshVersionData *ssh = NULL; - #define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, - ov, MAX_SUBSTRINGS); - - if (ret < 1 || ret > 3) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid ssh.protoversion option"); - goto error; - } - - if (ret > 1) { - const char *str_ptr; - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct id option */ - ssh = SCMalloc(sizeof(DetectSshVersionData)); - if (unlikely(ssh == NULL)) - goto error; - - memset(ssh, 0x00, sizeof(DetectSshVersionData)); - - /* If we expect a protocol version 2 or 1.99 (considered 2, we - * will compare it with both strings) */ - if (strcmp("2_compat", str_ptr) == 0) { - ssh->flags |= SSH_FLAG_PROTOVERSION_2_COMPAT; - SCLogDebug("will look for ssh protocol version 2 (2, 2.0, 1.99 that's considered as 2"); - return ssh; - } - - ssh->ver = (uint8_t *)SCStrdup((char*)str_ptr); - if (ssh->ver == NULL) { - goto error; - } - ssh->len = strlen((char *) ssh->ver); - - SCLogDebug("will look for ssh %s", ssh->ver); - } - - return ssh; - -error: - if (ssh != NULL) - DetectSshVersionFree(ssh); - return NULL; - -} - -/** - * \brief this function is used to add the parsed "id" option - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param idstr pointer to the user provided "id" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectSshVersionSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectSshVersionData *ssh = NULL; - SigMatch *sm = NULL; - - ssh = DetectSshVersionParse(str); - if (ssh == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_SSH) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - sm->type = DETECT_AL_SSH_PROTOVERSION; - sm->ctx = (void *)ssh; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_SSH; - return 0; - -error: - if (ssh != NULL) - DetectSshVersionFree(ssh); - if (sm != NULL) - SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectSshVersionData - * - * \param id_d pointer to DetectSshVersionData - */ -void DetectSshVersionFree(void *ptr) -{ - DetectSshVersionData *id_d = (DetectSshVersionData *)ptr; - SCFree(id_d); -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectSshVersionTestParse01 is a test to make sure that we parse - * a proto version correctly - */ -int DetectSshVersionTestParse01 (void) -{ - DetectSshVersionData *ssh = NULL; - ssh = DetectSshVersionParse("1.0"); - if (ssh != NULL && strncmp((char *) ssh->ver, "1.0", 3) == 0) { - DetectSshVersionFree(ssh); - return 1; - } - - return 0; -} - -/** - * \test DetectSshVersionTestParse02 is a test to make sure that we parse - * the proto version (compatible with proto version 2) correctly - */ -int DetectSshVersionTestParse02 (void) -{ - DetectSshVersionData *ssh = NULL; - ssh = DetectSshVersionParse("2_compat"); - if (ssh->flags & SSH_FLAG_PROTOVERSION_2_COMPAT) { - DetectSshVersionFree(ssh); - return 1; - } - - return 0; -} - -/** - * \test DetectSshVersionTestParse03 is a test to make sure that we - * don't return a ssh_data with an invalid value specified - */ -int DetectSshVersionTestParse03 (void) -{ - DetectSshVersionData *ssh = NULL; - ssh = DetectSshVersionParse("2_com"); - if (ssh != NULL) { - DetectSshVersionFree(ssh); - return 0; - } - ssh = DetectSshVersionParse(""); - if (ssh != NULL) { - DetectSshVersionFree(ssh); - return 0; - } - ssh = DetectSshVersionParse(".1"); - if (ssh != NULL) { - DetectSshVersionFree(ssh); - return 0; - } - ssh = DetectSshVersionParse("lalala"); - if (ssh != NULL) { - DetectSshVersionFree(ssh); - return 0; - } - - return 1; -} - - -#include "stream-tcp-reassemble.h" - -/** \test Send a get request in three chunks + more data. */ -static int DetectSshVersionTestDetect01(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-1."; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "10-PuTTY_2.123" ; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = "\n"; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = "whatever..."; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SSH; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.protoversion:1.10; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ( !(PacketAlertCheck(p, 1))) { - printf("Error, the sig should match: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - return result; -} - -/** \test Send a get request in three chunks + more data. */ -static int DetectSshVersionTestDetect02(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-1."; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "99-PuTTY_2.123" ; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = "\n"; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = "whatever..."; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SSH; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.protoversion:2_compat; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ( !(PacketAlertCheck(p, 1))) { - printf("Error, the sig should match: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - return result; -} - -/** \test Send a get request in three chunks + more data. */ -static int DetectSshVersionTestDetect03(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-1."; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "7-PuTTY_2.123" ; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = "\n"; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = "whatever..."; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SSH; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.protoversion:2_compat; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("Error, 1.7 version is not 2 compat, so the sig should not match: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectSshVersion - */ -void DetectSshVersionRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectSshVersionTestParse01", DetectSshVersionTestParse01, 1); - UtRegisterTest("DetectSshVersionTestParse02", DetectSshVersionTestParse02, 1); - UtRegisterTest("DetectSshVersionTestParse03", DetectSshVersionTestParse03, 1); - UtRegisterTest("DetectSshVersionTestDetect01", DetectSshVersionTestDetect01, 1); - UtRegisterTest("DetectSshVersionTestDetect02", DetectSshVersionTestDetect02, 1); - UtRegisterTest("DetectSshVersionTestDetect03", DetectSshVersionTestDetect03, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-ssh-proto-version.h b/framework/src/suricata/src/detect-ssh-proto-version.h deleted file mode 100644 index a4c8eddb..00000000 --- a/framework/src/suricata/src/detect-ssh-proto-version.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_SSH_VERSION_H__ -#define __DETECT_SSH_VERSION_H__ - -/** proto version 1.99 is considered proto version 2 */ -#define SSH_FLAG_PROTOVERSION_2_COMPAT 0x01 - -typedef struct DetectSshVersionData_ { - uint8_t *ver; /** ssh version to match */ - uint16_t len; /** ssh version length to match */ - uint8_t flags; -} DetectSshVersionData; - -/* prototypes */ -void DetectSshVersionRegister (void); - -#endif /* __DETECT_SSH_VERSION_H__ */ - diff --git a/framework/src/suricata/src/detect-ssh-software-version.c b/framework/src/suricata/src/detect-ssh-software-version.c deleted file mode 100644 index 4197bfff..00000000 --- a/framework/src/suricata/src/detect-ssh-software-version.c +++ /dev/null @@ -1,673 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * - * Implements the ssh.softwareversion keyword - * You can match over the software version string of ssh, and it will - * be compared from the beginning of the string so you can say for - * example ssh.softwareversion:"PuTTY" and it can match, or you can - * also specify the version, something like - * ssh.softwareversion:"PuTTY-Release-0.55" - * I find this useful to match over a known vulnerable server/client - * software version incombination to other checks, so you can know - * that the risk is higher - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-ssh.h" -#include "detect-ssh-software-version.h" - -#include "stream-tcp.h" - -/** - * \brief Regex for parsing the softwareversion string - */ -#define PARSE_REGEX "^\\s*\"?\\s*?([0-9a-zA-Z\\:\\.\\-\\_\\+\\s+]+)\\s*\"?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectSshSoftwareVersionMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, void *, Signature *, SigMatch *); -static int DetectSshSoftwareVersionSetup (DetectEngineCtx *, Signature *, char *); -void DetectSshSoftwareVersionRegisterTests(void); -void DetectSshSoftwareVersionFree(void *); -void DetectSshSoftwareVersionRegister(void); - -/** - * \brief Registration function for keyword: ssh.softwareversion - */ -void DetectSshSoftwareVersionRegister(void) -{ - sigmatch_table[DETECT_AL_SSH_SOFTWAREVERSION].name = "ssh.softwareversion"; - sigmatch_table[DETECT_AL_SSH_SOFTWAREVERSION].Match = NULL; - sigmatch_table[DETECT_AL_SSH_SOFTWAREVERSION].AppLayerMatch = DetectSshSoftwareVersionMatch; - sigmatch_table[DETECT_AL_SSH_SOFTWAREVERSION].alproto = ALPROTO_SSH; - sigmatch_table[DETECT_AL_SSH_SOFTWAREVERSION].Setup = DetectSshSoftwareVersionSetup; - sigmatch_table[DETECT_AL_SSH_SOFTWAREVERSION].Free = DetectSshSoftwareVersionFree; - sigmatch_table[DETECT_AL_SSH_SOFTWAREVERSION].RegisterTests = DetectSshSoftwareVersionRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - SCLogDebug("registering ssh.softwareversion rule option"); - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -/** - * \brief match the specified version on a ssh session - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectSshSoftwareVersionData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectSshSoftwareVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - - DetectSshSoftwareVersionData *ssh = (DetectSshSoftwareVersionData *)m->ctx; - SshState *ssh_state = (SshState *)state; - if (ssh_state == NULL) { - SCLogDebug("no ssh state, no match"); - SCReturnInt(0); - } - - int ret = 0; - if ((flags & STREAM_TOCLIENT) && (ssh_state->srv_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - SCLogDebug("looking for ssh server softwareversion %s length %"PRIu16" on %s", ssh->software_ver, ssh->len, ssh_state->srv_hdr.software_version); - ret = (strncmp((char *) ssh_state->srv_hdr.software_version, (char *) ssh->software_ver, ssh->len) == 0)? 1 : 0; - } else if ((flags & STREAM_TOSERVER) && (ssh_state->cli_hdr.flags & SSH_FLAG_VERSION_PARSED)) { - SCLogDebug("looking for ssh client softwareversion %s length %"PRIu16" on %s", ssh->software_ver, ssh->len, ssh_state->cli_hdr.software_version); - ret = (strncmp((char *) ssh_state->cli_hdr.software_version, (char *) ssh->software_ver, ssh->len) == 0)? 1 : 0; - } - SCReturnInt(ret); -} - -/** - * \brief This function is used to parse IPV4 ip_id passed via keyword: "id" - * - * \param idstr Pointer to the user provided id option - * - * \retval id_d pointer to DetectSshSoftwareVersionData on success - * \retval NULL on failure - */ -DetectSshSoftwareVersionData *DetectSshSoftwareVersionParse (char *str) -{ - DetectSshSoftwareVersionData *ssh = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, - ov, MAX_SUBSTRINGS); - - if (ret < 1 || ret > 3) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid ssh.softwareversion option"); - goto error; - } - - if (ret > 1) { - const char *str_ptr = NULL; - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct id option */ - ssh = SCMalloc(sizeof(DetectSshSoftwareVersionData)); - if (unlikely(ssh == NULL)) - goto error; - - ssh->software_ver = (uint8_t *)SCStrdup((char *)str_ptr); - if (ssh->software_ver == NULL) { - goto error; - } - pcre_free_substring(str_ptr); - - ssh->len = strlen((char *)ssh->software_ver); - - SCLogDebug("will look for ssh %s", ssh->software_ver); - } - - return ssh; - -error: - if (ssh != NULL) - DetectSshSoftwareVersionFree(ssh); - return NULL; - -} - -/** - * \brief this function is used to add the parsed "id" option - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param idstr pointer to the user provided "id" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectSshSoftwareVersionSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectSshSoftwareVersionData *ssh = NULL; - SigMatch *sm = NULL; - - ssh = DetectSshSoftwareVersionParse(str); - if (ssh == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_SSH) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - sm->type = DETECT_AL_SSH_SOFTWAREVERSION; - sm->ctx = (void *)ssh; - - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_SSH; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - return 0; - -error: - if (ssh != NULL) - DetectSshSoftwareVersionFree(ssh); - if (sm != NULL) - SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectSshSoftwareVersionData - * - * \param id_d pointer to DetectSshSoftwareVersionData - */ -void DetectSshSoftwareVersionFree(void *ptr) -{ - if (ptr == NULL) - return; - - DetectSshSoftwareVersionData *ssh = (DetectSshSoftwareVersionData *)ptr; - if (ssh->software_ver != NULL) - SCFree(ssh->software_ver); - SCFree(ssh); -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectSshSoftwareVersionTestParse01 is a test to make sure that we parse - * a software version correctly - */ -int DetectSshSoftwareVersionTestParse01 (void) -{ - DetectSshSoftwareVersionData *ssh = NULL; - ssh = DetectSshSoftwareVersionParse("PuTTY_1.0"); - if (ssh != NULL && strncmp((char *) ssh->software_ver, "PuTTY_1.0", 9) == 0) { - DetectSshSoftwareVersionFree(ssh); - return 1; - } - - return 0; -} - -/** - * \test DetectSshSoftwareVersionTestParse02 is a test to make sure that we parse - * the software version correctly - */ -int DetectSshSoftwareVersionTestParse02 (void) -{ - DetectSshSoftwareVersionData *ssh = NULL; - ssh = DetectSshSoftwareVersionParse("\"SecureCRT-4.0\""); - if (ssh != NULL && strncmp((char *) ssh->software_ver, "SecureCRT-4.0", 13) == 0) { - DetectSshSoftwareVersionFree(ssh); - return 1; - } - - return 0; -} - -/** - * \test DetectSshSoftwareVersionTestParse03 is a test to make sure that we - * don't return a ssh_data with an empty value specified - */ -int DetectSshSoftwareVersionTestParse03 (void) -{ - DetectSshSoftwareVersionData *ssh = NULL; - ssh = DetectSshSoftwareVersionParse(""); - if (ssh != NULL) { - DetectSshSoftwareVersionFree(ssh); - return 0; - } - - return 1; -} - - -#include "stream-tcp-reassemble.h" - -/** \test Send a get request in three chunks + more data. */ -static int DetectSshSoftwareVersionTestDetect01(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-1."; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "10-PuTTY_2.123" ; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = "\n"; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = "whatever..."; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SSH; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.softwareversion:PuTTY_2.123; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ( !(PacketAlertCheck(p, 1))) { - printf("Error, the sig should match: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - return result; -} - -/** \test Send a get request in three chunks + more data. */ -static int DetectSshSoftwareVersionTestDetect02(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-1.99-Pu"; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "TTY_2.123" ; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = "\n"; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = "whatever..."; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SSH; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.softwareversion:PuTTY_2.123; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ( !(PacketAlertCheck(p, 1))) { - printf("Error, the sig should match: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - return result; -} - -/** \test Send a get request in three chunks + more data. */ -static int DetectSshSoftwareVersionTestDetect03(void) -{ - int result = 0; - Flow f; - uint8_t sshbuf1[] = "SSH-1."; - uint32_t sshlen1 = sizeof(sshbuf1) - 1; - uint8_t sshbuf2[] = "7-PuTTY_2.123" ; - uint32_t sshlen2 = sizeof(sshbuf2) - 1; - uint8_t sshbuf3[] = "\n"; - uint32_t sshlen3 = sizeof(sshbuf3) - 1; - uint8_t sshbuf4[] = "whatever..."; - uint32_t sshlen4 = sizeof(sshbuf4) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_SSH; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ssh any any -> any any (msg:\"SSH\"; ssh.softwareversion:lalala-3.1.4; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf1, sshlen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf2, sshlen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf3, sshlen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_SSH, STREAM_TOSERVER, sshbuf4, sshlen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SshState *ssh_state = f.alstate; - if (ssh_state == NULL) { - printf("no ssh state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("Error, 1.7 version is not 2 compat, so the sig should not match: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectSshSoftwareVersion - */ -void DetectSshSoftwareVersionRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectSshSoftwareVersionTestParse01", DetectSshSoftwareVersionTestParse01, 1); - UtRegisterTest("DetectSshSoftwareVersionTestParse02", DetectSshSoftwareVersionTestParse02, 1); - UtRegisterTest("DetectSshSoftwareVersionTestParse03", DetectSshSoftwareVersionTestParse03, 1); - UtRegisterTest("DetectSshSoftwareVersionTestDetect01", DetectSshSoftwareVersionTestDetect01, 1); - UtRegisterTest("DetectSshSoftwareVersionTestDetect02", DetectSshSoftwareVersionTestDetect02, 1); - UtRegisterTest("DetectSshSoftwareVersionTestDetect03", DetectSshSoftwareVersionTestDetect03, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-ssh-software-version.h b/framework/src/suricata/src/detect-ssh-software-version.h deleted file mode 100644 index 70c37c74..00000000 --- a/framework/src/suricata/src/detect-ssh-software-version.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __DETECT_SSH_SOFTWARE_VERSION_H__ -#define __DETECT_SSH_SOFTWARE_VERSION_H__ - -typedef struct DetectSshSoftwareVersionData_ { - uint8_t *software_ver; /** ssh version to match */ - uint16_t len; /** ssh version length to match */ -} DetectSshSoftwareVersionData; - -/* prototypes */ -void DetectSshSoftwareVersionRegister(void); -void DetectSshSoftwareVersionRegisterTests(void); - -#endif /* __DETECT_SSH_SOFTWARE_VERSION_H__ */ - diff --git a/framework/src/suricata/src/detect-ssl-state.c b/framework/src/suricata/src/detect-ssl-state.c deleted file mode 100644 index fa296631..00000000 --- a/framework/src/suricata/src/detect-ssl-state.c +++ /dev/null @@ -1,913 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implements support for ssl_state keyword. - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "detect-ssl-state.h" - -#include "stream-tcp.h" -#include "app-layer-ssl.h" - -#define PARSE_REGEX1 "^\\s*([_a-zA-Z0-9]+)(.*)$" -static pcre *parse_regex1; -static pcre_extra *parse_regex1_study; - -#define PARSE_REGEX2 "^(?:\\s*[|]\\s*([_a-zA-Z0-9]+))(.*)$" -static pcre *parse_regex2; -static pcre_extra *parse_regex2_study; - -int DetectSslStateMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t, void *, Signature *, SigMatch *); -int DetectSslStateSetup(DetectEngineCtx *, Signature *, char *); -void DetectSslStateRegisterTests(void); -void DetectSslStateFree(void *); - -/** - * \brief Registers the keyword handlers for the "ssl_state" keyword. - */ -void DetectSslStateRegister(void) -{ - sigmatch_table[DETECT_AL_SSL_STATE].name = "ssl_state"; - sigmatch_table[DETECT_AL_SSL_STATE].Match = NULL; - sigmatch_table[DETECT_AL_SSL_STATE].AppLayerMatch = DetectSslStateMatch; - sigmatch_table[DETECT_AL_SSL_STATE].alproto = ALPROTO_TLS; - sigmatch_table[DETECT_AL_SSL_STATE].Setup = DetectSslStateSetup; - sigmatch_table[DETECT_AL_SSL_STATE].Free = DetectSslStateFree; - sigmatch_table[DETECT_AL_SSL_STATE].RegisterTests = DetectSslStateRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - SCLogDebug("registering ssl_state rule option"); - - /* PARSE_REGEX1 */ - parse_regex1 = pcre_compile(PARSE_REGEX1, opts, &eb, &eo, NULL); - if (parse_regex1 == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX1, eo, eb); - goto error; - } - - parse_regex1_study = pcre_study(parse_regex1, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - /* PARSE_REGEX2 */ - parse_regex2 = pcre_compile(PARSE_REGEX2, opts, &eb, &eo, NULL); - if (parse_regex2 == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX2, eo, eb); - goto error; - } - - parse_regex2_study = pcre_study(parse_regex2, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - -error: - return; -} - -/** - * \brief App layer match function ssl_state keyword. - * - * \param tv Pointer to threadvars. - * \param det_ctx Pointer to the thread's detection context. - * \param f Pointer to the flow. - * \param flags Flags. - * \param state App layer state. - * \param s Sig we are currently inspecting. - * \param m SigMatch we are currently inspecting. - * - * \retval 1 Match. - * \retval 0 No match. - */ -int DetectSslStateMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *alstate, Signature *s, - SigMatch *m) -{ - int result = 1; - DetectSslStateData *ssd = (DetectSslStateData *)m->ctx; - SSLState *ssl_state = (SSLState *)alstate; - if (ssl_state == NULL) { - SCLogDebug("no app state, no match"); - return 0; - } - - if ((ssd->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO) && - !(ssl_state->flags & SSL_AL_FLAG_STATE_CLIENT_HELLO)) { - result = 0; - goto end; - } - if ((ssd->flags & SSL_AL_FLAG_STATE_SERVER_HELLO) && - !(ssl_state->flags & SSL_AL_FLAG_STATE_SERVER_HELLO)) { - result = 0; - goto end; - } - if ((ssd->flags & SSL_AL_FLAG_STATE_CLIENT_KEYX) && - !(ssl_state->flags & SSL_AL_FLAG_STATE_CLIENT_KEYX)) { - result = 0; - goto end; - } - if ((ssd->flags & SSL_AL_FLAG_STATE_SERVER_KEYX) && - !(ssl_state->flags & SSL_AL_FLAG_STATE_SERVER_KEYX)) { - result = 0; - goto end; - } - - end: - return result; -} - -/** - * \brief Parse the arg supplied with ssl_state and return it in a - * DetectSslStateData instance. - * - * \param arg Pointer to the string to be parsed. - * - * \retval ssd Pointer to DetectSslStateData on succese. - * \retval NULL On failure. - */ -DetectSslStateData *DetectSslStateParse(char *arg) -{ -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov1[MAX_SUBSTRINGS]; - int ov2[MAX_SUBSTRINGS]; - const char *str1; - const char *str2; - uint32_t flags = 0; - DetectSslStateData *ssd = NULL; - - ret = pcre_exec(parse_regex1, parse_regex1_study, arg, strlen(arg), 0, 0, - ov1, MAX_SUBSTRINGS); - if (ret < 1) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid arg \"%s\" supplied to " - "ssl_state keyword.", arg); - goto error; - } - res = pcre_get_substring((char *)arg, ov1, MAX_SUBSTRINGS, 1, &str1); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (strcmp("client_hello", str1) == 0) { - flags |= DETECT_SSL_STATE_CLIENT_HELLO; - } else if (strcmp("server_hello", str1) == 0) { - flags |= DETECT_SSL_STATE_SERVER_HELLO; - } else if (strcmp("client_keyx", str1) == 0) { - flags |= DETECT_SSL_STATE_CLIENT_KEYX; - } else if (strcmp("server_keyx", str1) == 0) { - flags |= DETECT_SSL_STATE_SERVER_KEYX; - } else if (strcmp("unknown", str1) == 0) { - flags |= DETECT_SSL_STATE_UNKNOWN; - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Found invalid option \"%s\" " - "in ssl_state keyword.", str1); - goto error; - } - - pcre_free_substring(str1); - - res = pcre_get_substring((char *)arg, ov1, MAX_SUBSTRINGS, 2, &str1); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - while (res > 0) { - ret = pcre_exec(parse_regex2, parse_regex2_study, str1, strlen(str1), 0, 0, - ov2, MAX_SUBSTRINGS); - if (ret < 1) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid arg \"%s\" supplied to " - "ssl_state keyword.", arg); - goto error; - } - res = pcre_get_substring((char *)str1, ov2, MAX_SUBSTRINGS, 1, &str2); - if (res <= 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - if (strcmp("client_hello", str2) == 0) { - flags |= DETECT_SSL_STATE_CLIENT_HELLO; - } else if (strcmp("server_hello", str2) == 0) { - flags |= DETECT_SSL_STATE_SERVER_HELLO; - } else if (strcmp("client_keyx", str2) == 0) { - flags |= DETECT_SSL_STATE_CLIENT_KEYX; - } else if (strcmp("server_keyx", str2) == 0) { - flags |= DETECT_SSL_STATE_SERVER_KEYX; - } else if (strcmp("unknown", str2) == 0) { - flags |= DETECT_SSL_STATE_UNKNOWN; - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Found invalid option \"%s\" " - "in ssl_state keyword.", str2); - goto error; - } - - res = pcre_get_substring((char *)str1, ov2, MAX_SUBSTRINGS, 2, &str2); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - pcre_free_substring(str1); - str1 = str2; - } - - if ( (ssd = SCMalloc(sizeof(DetectSslStateData))) == NULL) { - goto error; - } - ssd->flags = flags; - - return ssd; - -error: - if (ssd != NULL) - DetectSslStateFree(ssd); - return NULL; -} - - /** - * \internal - * \brief Setup function for ssl_state keyword. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param s Pointer to the Current Signature - * \param arg String holding the arg. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int DetectSslStateSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - DetectSslStateData *ssd = NULL; - SigMatch *sm = NULL; - - ssd = DetectSslStateParse(arg); - if (ssd == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_AL_SSL_STATE; - sm->ctx = (SigMatchCtx*)ssd; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, - "Rule contains conflicting keywords. Have non-tls alproto " - "set for a rule containing \"ssl_state\" keyword"); - goto error; - } - s->alproto = ALPROTO_TLS; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - return 0; - -error: - if (ssd != NULL) - DetectSslStateFree(ssd); - if (sm != NULL) - SCFree(sm); - return -1; -} - -/** - * \brief Free memory associated with DetectSslStateData. - * - * \param ptr pointer to the data to be freed. - */ -void DetectSslStateFree(void *ptr) -{ - if (ptr != NULL) - SCFree(ptr); - - return; -} - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS - -int DetectSslStateTest01(void) -{ - DetectSslStateData *ssd = DetectSslStateParse("client_hello"); - if (ssd == NULL) { - printf("ssd == NULL\n"); - return 0; - } - if (ssd->flags == DETECT_SSL_STATE_CLIENT_HELLO) { - SCFree(ssd); - return 1; - } - - return 0; -} - -int DetectSslStateTest02(void) -{ - DetectSslStateData *ssd = DetectSslStateParse("server_hello | client_hello"); - if (ssd == NULL) { - printf("ssd == NULL\n"); - return 0; - } - if (ssd->flags == (DETECT_SSL_STATE_SERVER_HELLO | - DETECT_SSL_STATE_CLIENT_HELLO)) { - SCFree(ssd); - return 1; - } - - return 0; -} - -int DetectSslStateTest03(void) -{ - DetectSslStateData *ssd = DetectSslStateParse("server_hello | client_keyx | " - "client_hello"); - if (ssd == NULL) { - printf("ssd == NULL\n"); - return 0; - } - if (ssd->flags == (DETECT_SSL_STATE_SERVER_HELLO | - DETECT_SSL_STATE_CLIENT_KEYX | - DETECT_SSL_STATE_CLIENT_HELLO)) { - SCFree(ssd); - return 1; - } - - return 0; -} - -int DetectSslStateTest04(void) -{ - DetectSslStateData *ssd = DetectSslStateParse("server_hello | client_keyx | " - "client_hello | server_keyx | " - "unknown"); - if (ssd == NULL) { - printf("ssd == NULL\n"); - return 0; - } - if (ssd->flags == (DETECT_SSL_STATE_SERVER_HELLO | - DETECT_SSL_STATE_CLIENT_KEYX | - DETECT_SSL_STATE_CLIENT_HELLO | - DETECT_SSL_STATE_SERVER_KEYX | - DETECT_SSL_STATE_UNKNOWN)) { - SCFree(ssd); - return 1; - } - - return 0; -} - -int DetectSslStateTest05(void) -{ - DetectSslStateData *ssd = DetectSslStateParse("| server_hello | client_keyx | " - "client_hello | server_keyx | " - "unknown"); - - if (ssd != NULL) { - printf("ssd != NULL - failure\n"); - SCFree(ssd); - return 0; - } - - return 1; -} - -int DetectSslStateTest06(void) -{ - DetectSslStateData *ssd = DetectSslStateParse("server_hello | client_keyx | " - "client_hello | server_keyx | " - "unknown | "); - if (ssd != NULL) { - printf("ssd != NULL - failure\n"); - SCFree(ssd); - return 0; - } - - return 1; -} - -/** - * \test Test a valid dce_iface entry for a bind and bind_ack - */ -static int DetectSslStateTest07(void) -{ - uint8_t chello_buf[] = { - 0x80, 0x67, 0x01, 0x03, 0x00, 0x00, 0x4e, 0x00, - 0x00, 0x00, 0x10, 0x01, 0x00, 0x80, 0x03, 0x00, - 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x40, 0x02, - 0x00, 0x80, 0x04, 0x00, 0x80, 0x00, 0x00, 0x39, - 0x00, 0x00, 0x38, 0x00, 0x00, 0x35, 0x00, 0x00, - 0x33, 0x00, 0x00, 0x32, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x05, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x16, - 0x00, 0x00, 0x13, 0x00, 0xfe, 0xff, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x15, 0x00, 0x00, 0x12, 0x00, - 0xfe, 0xfe, 0x00, 0x00, 0x09, 0x00, 0x00, 0x64, - 0x00, 0x00, 0x62, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x06, 0xa8, 0xb8, 0x93, 0xbb, 0x90, 0xe9, 0x2a, - 0xa2, 0x4d, 0x6d, 0xcc, 0x1c, 0xe7, 0x2a, 0x80, - 0x21 - }; - uint32_t chello_buf_len = sizeof(chello_buf); - - uint8_t shello_buf[] = { - 0x16, 0x03, 0x00, 0x00, 0x4a, 0x02, - 0x00, 0x00, 0x46, 0x03, 0x00, 0x44, 0x4c, 0x94, - 0x8f, 0xfe, 0x81, 0xed, 0x93, 0x65, 0x02, 0x88, - 0xa3, 0xf8, 0xeb, 0x63, 0x86, 0x0e, 0x2c, 0xf6, - 0x8d, 0xd0, 0x0f, 0x2c, 0x2a, 0xd6, 0x4f, 0xcd, - 0x2d, 0x3c, 0x16, 0xd7, 0xd6, 0x20, 0xa0, 0xfb, - 0x60, 0x86, 0x3d, 0x1e, 0x76, 0xf3, 0x30, 0xfe, - 0x0b, 0x01, 0xfd, 0x1a, 0x01, 0xed, 0x95, 0xf6, - 0x7b, 0x8e, 0xc0, 0xd4, 0x27, 0xbf, 0xf0, 0x6e, - 0xc7, 0x56, 0xb1, 0x47, 0xce, 0x98, 0x00, 0x35, - 0x00, 0x16, 0x03, 0x00, 0x03, 0x44, 0x0b, 0x00, - 0x03, 0x40, 0x00, 0x03, 0x3d, 0x00, 0x03, 0x3a, - 0x30, 0x82, 0x03, 0x36, 0x30, 0x82, 0x02, 0x9f, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x30, - 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x58, 0x59, 0x31, - 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x0c, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, - 0x44, 0x65, 0x73, 0x65, 0x72, 0x74, 0x31, 0x13, - 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, - 0x0a, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x54, - 0x6f, 0x77, 0x6e, 0x31, 0x17, 0x30, 0x15, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x53, 0x6e, - 0x61, 0x6b, 0x65, 0x20, 0x4f, 0x69, 0x6c, 0x2c, - 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1e, 0x30, 0x1c, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x31, 0x15, 0x30, 0x13, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0c, 0x53, - 0x6e, 0x61, 0x6b, 0x65, 0x20, 0x4f, 0x69, 0x6c, - 0x20, 0x43, 0x41, 0x31, 0x1e, 0x30, 0x1c, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x01, 0x16, 0x0f, 0x63, 0x61, 0x40, 0x73, - 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, 0x6c, 0x2e, - 0x64, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, - 0x33, 0x30, 0x33, 0x30, 0x35, 0x31, 0x36, 0x34, - 0x37, 0x34, 0x35, 0x5a, 0x17, 0x0d, 0x30, 0x38, - 0x30, 0x33, 0x30, 0x33, 0x31, 0x36, 0x34, 0x37, - 0x34, 0x35, 0x5a, 0x30, 0x81, 0xa7, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x58, 0x59, 0x31, 0x15, 0x30, 0x13, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x0c, 0x53, 0x6e, - 0x61, 0x6b, 0x65, 0x20, 0x44, 0x65, 0x73, 0x65, - 0x72, 0x74, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x6e, 0x61, - 0x6b, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0e, 0x53, 0x6e, 0x61, 0x6b, 0x65, 0x20, - 0x4f, 0x69, 0x6c, 0x2c, 0x20, 0x4c, 0x74, 0x64, - 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x0e, 0x57, 0x65, 0x62, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x61, - 0x6d, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x10, 0x77, 0x77, 0x77, 0x2e, - 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, 0x6c, - 0x2e, 0x64, 0x6f, 0x6d, 0x31, 0x1f, 0x30, 0x1d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x09, 0x01, 0x16, 0x10, 0x77, 0x77, 0x77, - 0x40, 0x73, 0x6e, 0x61, 0x6b, 0x65, 0x6f, 0x69, - 0x6c, 0x2e, 0x64, 0x6f, 0x6d, 0x30, 0x81, 0x9f, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, - 0x81, 0x00, 0xa4, 0x6e, 0x53, 0x14, 0x0a, 0xde, - 0x2c, 0xe3, 0x60, 0x55, 0x9a, 0xf2, 0x42, 0xa6, - 0xaf, 0x47, 0x12, 0x2f, 0x17, 0xce, 0xfa, 0xba, - 0xdc, 0x4e, 0x63, 0x56, 0x34, 0xb9, 0xba, 0x73, - 0x4b, 0x78, 0x44, 0x3d, 0xc6, 0x6c, 0x69, 0xa4, - 0x25, 0xb3, 0x61, 0x02, 0x9d, 0x09, 0x04, 0x3f, - 0x72, 0x3d, 0xd8, 0x27, 0xd3, 0xb0, 0x5a, 0x45, - 0x77, 0xb7, 0x36, 0xe4, 0x26, 0x23, 0xcc, 0x12, - 0xb8, 0xae, 0xde, 0xa7, 0xb6, 0x3a, 0x82, 0x3c, - 0x7c, 0x24, 0x59, 0x0a, 0xf8, 0x96, 0x43, 0x8b, - 0xa3, 0x29, 0x36, 0x3f, 0x91, 0x7f, 0x5d, 0xc7, - 0x23, 0x94, 0x29, 0x7f, 0x0a, 0xce, 0x0a, 0xbd, - 0x8d, 0x9b, 0x2f, 0x19, 0x17, 0xaa, 0xd5, 0x8e, - 0xec, 0x66, 0xa2, 0x37, 0xeb, 0x3f, 0x57, 0x53, - 0x3c, 0xf2, 0xaa, 0xbb, 0x79, 0x19, 0x4b, 0x90, - 0x7e, 0xa7, 0xa3, 0x99, 0xfe, 0x84, 0x4c, 0x89, - 0xf0, 0x3d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x6e, 0x30, 0x6c, 0x30, 0x1b, 0x06, 0x03, 0x55, - 0x1d, 0x11, 0x04, 0x14, 0x30, 0x12, 0x81, 0x10, - 0x77, 0x77, 0x77, 0x40, 0x73, 0x6e, 0x61, 0x6b, - 0x65, 0x6f, 0x69, 0x6c, 0x2e, 0x64, 0x6f, 0x6d, - 0x30, 0x3a, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x2d, 0x16, - 0x2b, 0x6d, 0x6f, 0x64, 0x5f, 0x73, 0x73, 0x6c, - 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, - 0x6d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x20, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x30, 0x11, 0x06, 0x09, - 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, - 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0xae, 0x79, 0x79, 0x22, 0x90, 0x75, - 0xfd, 0xa6, 0xd5, 0xc4, 0xb8, 0xc4, 0x99, 0x4e, - 0x1c, 0x05, 0x7c, 0x91, 0x59, 0xbe, 0x89, 0x0d, - 0x3d, 0xc6, 0x8c, 0xa3, 0xcf, 0xf6, 0xba, 0x23, - 0xdf, 0xb8, 0xae, 0x44, 0x68, 0x8a, 0x8f, 0xb9, - 0x8b, 0xcb, 0x12, 0xda, 0xe6, 0xa2, 0xca, 0xa5, - 0xa6, 0x55, 0xd9, 0xd2, 0xa1, 0xad, 0xba, 0x9b, - 0x2c, 0x44, 0x95, 0x1d, 0x4a, 0x90, 0x59, 0x7f, - 0x83, 0xae, 0x81, 0x5e, 0x3f, 0x92, 0xe0, 0x14, - 0x41, 0x82, 0x4e, 0x7f, 0x53, 0xfd, 0x10, 0x23, - 0xeb, 0x8a, 0xeb, 0xe9, 0x92, 0xea, 0x61, 0xf2, - 0x8e, 0x19, 0xa1, 0xd3, 0x49, 0xc0, 0x84, 0x34, - 0x1e, 0x2e, 0x6e, 0xf6, 0x98, 0xe2, 0x87, 0x53, - 0xd6, 0x55, 0xd9, 0x1a, 0x8a, 0x92, 0x5c, 0xad, - 0xdc, 0x1e, 0x1c, 0x30, 0xa7, 0x65, 0x9d, 0xc2, - 0x4f, 0x60, 0xd2, 0x6f, 0xdb, 0xe0, 0x9f, 0x9e, - 0xbc, 0x41, 0x16, 0x03, 0x00, 0x00, 0x04, 0x0e, - 0x00, 0x00, 0x00 - }; - uint32_t shello_buf_len = sizeof(shello_buf); - - uint8_t client_change_cipher_spec_buf[] = { - 0x16, 0x03, 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, - 0x80, 0x65, 0x51, 0x2d, 0xa6, 0xd4, 0xa7, 0x38, - 0xdf, 0xac, 0x79, 0x1f, 0x0b, 0xd9, 0xb2, 0x61, - 0x7d, 0x73, 0x88, 0x32, 0xd9, 0xf2, 0x62, 0x3a, - 0x8b, 0x11, 0x04, 0x75, 0xca, 0x42, 0xff, 0x4e, - 0xd9, 0xcc, 0xb9, 0xfa, 0x86, 0xf3, 0x16, 0x2f, - 0x09, 0x73, 0x51, 0x66, 0xaa, 0x29, 0xcd, 0x80, - 0x61, 0x0f, 0xe8, 0x13, 0xce, 0x5b, 0x8e, 0x0a, - 0x23, 0xf8, 0x91, 0x5e, 0x5f, 0x54, 0x70, 0x80, - 0x8e, 0x7b, 0x28, 0xef, 0xb6, 0x69, 0xb2, 0x59, - 0x85, 0x74, 0x98, 0xe2, 0x7e, 0xd8, 0xcc, 0x76, - 0x80, 0xe1, 0xb6, 0x45, 0x4d, 0xc7, 0xcd, 0x84, - 0xce, 0xb4, 0x52, 0x79, 0x74, 0xcd, 0xe6, 0xd7, - 0xd1, 0x9c, 0xad, 0xef, 0x63, 0x6c, 0x0f, 0xf7, - 0x05, 0xe4, 0x4d, 0x1a, 0xd3, 0xcb, 0x9c, 0xd2, - 0x51, 0xb5, 0x61, 0xcb, 0xff, 0x7c, 0xee, 0xc7, - 0xbc, 0x5e, 0x15, 0xa3, 0xf2, 0x52, 0x0f, 0xbb, - 0x32, 0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16, - 0x03, 0x00, 0x00, 0x40, 0xa9, 0xd8, 0xd7, 0x35, - 0xbc, 0x39, 0x56, 0x98, 0xad, 0x87, 0x61, 0x2a, - 0xc4, 0x8f, 0xcc, 0x03, 0xcb, 0x93, 0x80, 0x81, - 0xb0, 0x4a, 0xc4, 0xd2, 0x09, 0x71, 0x3e, 0x90, - 0x3c, 0x8d, 0xe0, 0x95, 0x44, 0xfe, 0x56, 0xd1, - 0x7e, 0x88, 0xe2, 0x48, 0xfd, 0x76, 0x70, 0x76, - 0xe2, 0xcd, 0x06, 0xd0, 0xf3, 0x9d, 0x13, 0x79, - 0x67, 0x1e, 0x37, 0xf6, 0x98, 0xbe, 0x59, 0x18, - 0x4c, 0xfc, 0x75, 0x56 - }; - uint32_t client_change_cipher_spec_buf_len = - sizeof(client_change_cipher_spec_buf); - - uint8_t server_change_cipher_spec_buf[] = { - 0x14, 0x03, 0x00, 0x00, 0x01, 0x01, 0x16, 0x03, - 0x00, 0x00, 0x40, 0xce, 0x7c, 0x92, 0x43, 0x59, - 0xcc, 0x3d, 0x90, 0x91, 0x9c, 0x58, 0xf0, 0x7a, - 0xce, 0xae, 0x0d, 0x08, 0xe0, 0x76, 0xb4, 0x86, - 0xb1, 0x15, 0x5b, 0x32, 0xb8, 0x77, 0x53, 0xe7, - 0xa6, 0xf9, 0xd0, 0x95, 0x5f, 0xaa, 0x07, 0xc3, - 0x96, 0x7c, 0xc9, 0x88, 0xc2, 0x7a, 0x20, 0x89, - 0x4f, 0xeb, 0xeb, 0xb6, 0x19, 0xef, 0xaa, 0x27, - 0x73, 0x9d, 0xa6, 0xb4, 0x9f, 0xeb, 0x34, 0xe2, - 0x4d, 0x9f, 0x6b - }; - uint32_t server_change_cipher_spec_buf_len = - sizeof(server_change_cipher_spec_buf); - - uint8_t toserver_app_data_buf[] = { - 0x17, 0x03, 0x00, 0x01, 0xb0, 0x4a, 0xc3, 0x3e, - 0x9d, 0x77, 0x78, 0x01, 0x2c, 0xb4, 0xbc, 0x4c, - 0x9a, 0x84, 0xd7, 0xb9, 0x90, 0x0c, 0x21, 0x10, - 0xf0, 0xfa, 0x00, 0x7c, 0x16, 0xbb, 0x77, 0xfb, - 0x72, 0x42, 0x4f, 0xad, 0x50, 0x4a, 0xd0, 0xaa, - 0x6f, 0xaa, 0x44, 0x6c, 0x62, 0x94, 0x1b, 0xc5, - 0xfe, 0xe9, 0x1c, 0x5e, 0xde, 0x85, 0x0b, 0x0e, - 0x05, 0xe4, 0x18, 0x6e, 0xd2, 0xd3, 0xb5, 0x20, - 0xab, 0x81, 0xfd, 0x18, 0x9a, 0x73, 0xb8, 0xd7, - 0xef, 0xc3, 0xdd, 0x74, 0xd7, 0x9c, 0x1e, 0x6f, - 0x21, 0x6d, 0xf8, 0x24, 0xca, 0x3c, 0x70, 0x78, - 0x36, 0x12, 0x7a, 0x8a, 0x9c, 0xac, 0x4e, 0x1c, - 0xa8, 0xfb, 0x27, 0x30, 0xba, 0x9a, 0xf4, 0x2f, - 0x0a, 0xab, 0x80, 0x6a, 0xa1, 0x60, 0x74, 0xf0, - 0xe3, 0x91, 0x84, 0xe7, 0x90, 0x88, 0xcc, 0xf0, - 0x95, 0x7b, 0x0a, 0x22, 0xf2, 0xf9, 0x27, 0xe0, - 0xdd, 0x38, 0x0c, 0xfd, 0xe9, 0x03, 0x71, 0xdc, - 0x70, 0xa4, 0x6e, 0xdf, 0xe3, 0x72, 0x9e, 0xa1, - 0xf0, 0xc9, 0x00, 0xd6, 0x03, 0x55, 0x6a, 0x67, - 0x5d, 0x9c, 0xb8, 0x75, 0x01, 0xb0, 0x01, 0x9f, - 0xe6, 0xd2, 0x44, 0x18, 0xbc, 0xca, 0x7a, 0x10, - 0x39, 0xa6, 0xcf, 0x15, 0xc7, 0xf5, 0x35, 0xd4, - 0xb3, 0x6d, 0x91, 0x23, 0x84, 0x99, 0xba, 0xb0, - 0x7e, 0xd0, 0xc9, 0x4c, 0xbf, 0x3f, 0x33, 0x68, - 0x37, 0xb7, 0x7d, 0x44, 0xb0, 0x0b, 0x2c, 0x0f, - 0xd0, 0x75, 0xa2, 0x6b, 0x5b, 0xe1, 0x9f, 0xd4, - 0x69, 0x9a, 0x14, 0xc8, 0x29, 0xb7, 0xd9, 0x10, - 0xbb, 0x99, 0x30, 0x9a, 0xfb, 0xcc, 0x13, 0x1f, - 0x76, 0x4e, 0xe6, 0xdf, 0x14, 0xaa, 0xd5, 0x60, - 0xbf, 0x91, 0x49, 0x0d, 0x64, 0x42, 0x29, 0xa8, - 0x64, 0x27, 0xd4, 0x5e, 0x1b, 0x18, 0x03, 0xa8, - 0x73, 0xd6, 0x05, 0x6e, 0xf7, 0x50, 0xb0, 0x09, - 0x6b, 0x69, 0x7a, 0x12, 0x28, 0x58, 0xef, 0x5a, - 0x86, 0x11, 0xde, 0x71, 0x71, 0x9f, 0xca, 0xbd, - 0x79, 0x2a, 0xc2, 0xe5, 0x9b, 0x5e, 0x32, 0xe7, - 0xcb, 0x97, 0x6e, 0xa0, 0xea, 0xa4, 0xa4, 0x6a, - 0x32, 0xf9, 0x37, 0x39, 0xd8, 0x37, 0x6d, 0x63, - 0xf3, 0x08, 0x1c, 0xdd, 0x06, 0xdd, 0x2c, 0x2b, - 0x9f, 0x04, 0x88, 0x5f, 0x36, 0x42, 0xc1, 0xb1, - 0xc7, 0xe8, 0x2d, 0x5d, 0xa4, 0x6c, 0xe5, 0x60, - 0x94, 0xae, 0xd0, 0x90, 0x1e, 0x88, 0xa0, 0x87, - 0x52, 0xfb, 0xed, 0x97, 0xa5, 0x25, 0x5a, 0xb7, - 0x55, 0xc5, 0x13, 0x07, 0x85, 0x27, 0x40, 0xed, - 0xb8, 0xa0, 0x26, 0x13, 0x44, 0x0c, 0xfc, 0xcc, - 0x5a, 0x09, 0xe5, 0x44, 0xb5, 0x63, 0xa1, 0x43, - 0x51, 0x23, 0x4f, 0x17, 0x21, 0x89, 0x2e, 0x58, - 0xfd, 0xf9, 0x63, 0x74, 0x04, 0x70, 0x1e, 0x7d, - 0xd0, 0x66, 0xba, 0x40, 0x5e, 0x45, 0xdc, 0x39, - 0x7c, 0x53, 0x0f, 0xa8, 0x38, 0xb2, 0x13, 0x99, - 0x27, 0xd9, 0x4a, 0x51, 0xe9, 0x9f, 0x2a, 0x92, - 0xbb, 0x9c, 0x90, 0xab, 0xfd, 0xf1, 0xb7, 0x40, - 0x05, 0xa9, 0x7a, 0x20, 0x63, 0x36, 0xc1, 0xef, - 0xb9, 0xad, 0xa2, 0xe0, 0x1d, 0x20, 0x4f, 0xb2, - 0x34, 0xbd, 0xea, 0x07, 0xac, 0x21, 0xce, 0xf6, - 0x8a, 0xa2, 0x9e, 0xcd, 0xfa - }; - uint32_t toserver_app_data_buf_len = sizeof(toserver_app_data_buf); - - int result = 0; - Signature *s = NULL; - ThreadVars th_v; - Packet *p = NULL; - Flow f; - TcpSession ssn; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - SSLState *ssl_state = NULL; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - f.alproto = ALPROTO_TLS; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"ssl state\"; ssl_state:client_hello; " - "sid:1;)"); - if (s == NULL) - goto end; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"ssl state\"; " - "ssl_state:client_hello | server_hello; " - "sid:2;)"); - if (s == NULL) - goto end; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"ssl state\"; " - "ssl_state:client_hello | server_hello | " - "client_keyx; sid:3;)"); - if (s == NULL) - goto end; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(msg:\"ssl state\"; " - "ssl_state:client_hello | server_hello | " - "client_keyx | server_keyx; sid:4;)"); - if (s == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER | STREAM_START, chello_buf, - chello_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no ssl state: "); - goto end; - } - - /* do detect */ - p->alerts.cnt = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) - goto end; - if (PacketAlertCheck(p, 2)) - goto end; - if (PacketAlertCheck(p, 3)) - goto end; - if (PacketAlertCheck(p, 4)) - goto end; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, shello_buf, - shello_buf_len); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - p->alerts.cnt = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - if (!PacketAlertCheck(p, 2)) - goto end; - if (PacketAlertCheck(p, 3)) - goto end; - if (PacketAlertCheck(p, 4)) - goto end; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, client_change_cipher_spec_buf, - client_change_cipher_spec_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - p->alerts.cnt = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - if (PacketAlertCheck(p, 2)) - goto end; - if (!PacketAlertCheck(p, 3)) - goto end; - if (PacketAlertCheck(p, 4)) - goto end; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOCLIENT, server_change_cipher_spec_buf, - server_change_cipher_spec_buf_len); - if (r != 0) { - printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - p->alerts.cnt = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - if (PacketAlertCheck(p, 2)) - goto end; - if (PacketAlertCheck(p, 3)) - goto end; - if (PacketAlertCheck(p, 4)) - goto end; - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, toserver_app_data_buf, - toserver_app_data_buf_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - p->alerts.cnt = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - goto end; - if (PacketAlertCheck(p, 2)) - goto end; - if (PacketAlertCheck(p, 3)) - goto end; - if (PacketAlertCheck(p, 4)) - goto end; - - result = 1; - - end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void DetectSslStateRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectSslStateTest01", DetectSslStateTest01, 1); - UtRegisterTest("DetectSslStateTest02", DetectSslStateTest02, 1); - UtRegisterTest("DetectSslStateTest03", DetectSslStateTest03, 1); - UtRegisterTest("DetectSslStateTest04", DetectSslStateTest04, 1); - UtRegisterTest("DetectSslStateTest05", DetectSslStateTest05, 1); - UtRegisterTest("DetectSslStateTest06", DetectSslStateTest06, 1); - UtRegisterTest("DetectSslStateTest07", DetectSslStateTest07, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/detect-ssl-state.h b/framework/src/suricata/src/detect-ssl-state.h deleted file mode 100644 index a9c69a15..00000000 --- a/framework/src/suricata/src/detect-ssl-state.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef DETECT_SSL_STATE_H -#define DETECT_SSL_STATE_H - -#include "app-layer-ssl.h" - -/* we pick these flags flags from the parser */ -#define DETECT_SSL_STATE_CLIENT_HELLO SSL_AL_FLAG_STATE_CLIENT_HELLO -#define DETECT_SSL_STATE_SERVER_HELLO SSL_AL_FLAG_STATE_SERVER_HELLO -#define DETECT_SSL_STATE_CLIENT_KEYX SSL_AL_FLAG_STATE_CLIENT_KEYX -#define DETECT_SSL_STATE_SERVER_KEYX SSL_AL_FLAG_STATE_SERVER_KEYX -#define DETECT_SSL_STATE_UNKNOWN SSL_AL_FLAG_STATE_UNKNOWN - -typedef struct DetectSslStateData_ { - uint32_t flags; -} DetectSslStateData; - -void DetectSslStateRegister(void); - -#endif /* DETECT_SSL_STATE_H */ diff --git a/framework/src/suricata/src/detect-ssl-version.c b/framework/src/suricata/src/detect-ssl-version.c deleted file mode 100644 index 599d26b8..00000000 --- a/framework/src/suricata/src/detect-ssl-version.c +++ /dev/null @@ -1,804 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file detect-ssl-version.c - * - * \author Gurvinder Singh - * - * Implements the ssl_version keyword - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "detect-ssl-version.h" - -#include "stream-tcp.h" -#include "app-layer-ssl.h" - -/** - * \brief Regex for parsing "id" option, matching number or "number" - */ -#define PARSE_REGEX "^\\s*(!?[A-z0-9.]+)\\s*,?\\s*(!?[A-z0-9.]+)?\\s*\\,?\\s*" \ - "(!?[A-z0-9.]+)?\\s*,?\\s*(!?[A-z0-9.]+)?\\s*,?\\s*(!?[A-z0-9.]+)?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectSslVersionMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t, void *, Signature *, SigMatch *); -static int DetectSslVersionSetup(DetectEngineCtx *, Signature *, char *); -void DetectSslVersionRegisterTests(void); -void DetectSslVersionFree(void *); - -/** - * \brief Registration function for keyword: ssl_version - */ -void DetectSslVersionRegister(void) -{ - sigmatch_table[DETECT_AL_SSL_VERSION].name = "ssl_version"; - sigmatch_table[DETECT_AL_SSL_VERSION].Match = NULL; - sigmatch_table[DETECT_AL_SSL_VERSION].AppLayerMatch = DetectSslVersionMatch; - sigmatch_table[DETECT_AL_SSL_VERSION].alproto = ALPROTO_TLS; - sigmatch_table[DETECT_AL_SSL_VERSION].Setup = DetectSslVersionSetup; - sigmatch_table[DETECT_AL_SSL_VERSION].Free = DetectSslVersionFree; - sigmatch_table[DETECT_AL_SSL_VERSION].RegisterTests = DetectSslVersionRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - SCLogDebug("registering ssl_version rule option"); - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - return; -} - -/** - * \brief match the specified version on a ssl session - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectSslVersionData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectSslVersionMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - - int ret = 0; - uint16_t ver = 0; - uint8_t sig_ver = TLS_UNKNOWN; - - DetectSslVersionData *ssl = (DetectSslVersionData *)m->ctx; - SSLState *app_state = (SSLState *)state; - if (app_state == NULL) { - SCLogDebug("no app state, no match"); - SCReturnInt(0); - } - - if (flags & STREAM_TOCLIENT) { - SCLogDebug("server (toclient) version is 0x%02X", - app_state->server_connp.version); - ver = app_state->server_connp.version; - } else if (flags & STREAM_TOSERVER) { - SCLogDebug("client (toserver) version is 0x%02X", - app_state->client_connp.version); - ver = app_state->client_connp.version; - } - - switch (ver) { - case SSL_VERSION_2: - if (ver == ssl->data[SSLv2].ver) - ret = 1; - sig_ver = SSLv2; - break; - case SSL_VERSION_3: - if (ver == ssl->data[SSLv3].ver) - ret = 1; - sig_ver = SSLv3; - break; - case TLS_VERSION_10: - if (ver == ssl->data[TLS10].ver) - ret = 1; - sig_ver = TLS10; - break; - case TLS_VERSION_11: - if (ver == ssl->data[TLS11].ver) - ret = 1; - sig_ver = TLS11; - break; - case TLS_VERSION_12: - if (ver == ssl->data[TLS12].ver) - ret = 1; - sig_ver = TLS12; - break; - } - - if (sig_ver == TLS_UNKNOWN) - SCReturnInt(0); - - SCReturnInt(ret ^ ((ssl->data[sig_ver].flags & DETECT_SSL_VERSION_NEGATED) ? 1 : 0)); -} - -/** - * \brief This function is used to parse ssl_version data passed via - * keyword: "ssl_version" - * - * \param str Pointer to the user provided options - * - * \retval ssl pointer to DetectSslVersionData on success - * \retval NULL on failure - */ -DetectSslVersionData *DetectSslVersionParse(char *str) -{ - DetectSslVersionData *ssl = NULL; - #define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, - ov, MAX_SUBSTRINGS); - - if (ret < 1 || ret > 5) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid ssl_version option"); - goto error; - } - - if (ret > 1) { - const char *str_ptr[5]; - char *orig; - uint8_t found = 0, neg = 0; - char *tmp_str; - - /* We have a correct ssl_version options */ - ssl = SCCalloc(1, sizeof (DetectSslVersionData)); - if (unlikely(ssl == NULL)) - goto error; - - int i; - for (i = 1; i < ret; i++) { - res = pcre_get_substring((char *) str, ov, MAX_SUBSTRINGS, i, &str_ptr[i]); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - if (found == 0) - goto error; - break; - } - - orig = SCStrdup((char*) str_ptr[i]); - if (unlikely(orig == NULL)) { - goto error; - } - tmp_str = orig; - - /* Let's see if we need to scape "'s */ - if (tmp_str[0] == '"') { - tmp_str[strlen(tmp_str) - 1] = '\0'; - tmp_str += 1; - } - - - if (tmp_str[0] == '!') { - neg = 1; - tmp_str++; - } - - if (strncasecmp("sslv2", tmp_str, 5) == 0) { - ssl->data[SSLv2].ver = SSL_VERSION_2; - if (neg == 1) - ssl->data[SSLv2].flags |= DETECT_SSL_VERSION_NEGATED; - } else if (strncasecmp("sslv3", tmp_str, 5) == 0) { - ssl->data[SSLv3].ver = SSL_VERSION_3; - if (neg == 1) - ssl->data[SSLv3].flags |= DETECT_SSL_VERSION_NEGATED; - } else if (strncasecmp("tls1.0", tmp_str, 6) == 0) { - ssl->data[TLS10].ver = TLS_VERSION_10; - if (neg == 1) - ssl->data[TLS10].flags |= DETECT_SSL_VERSION_NEGATED; - } else if (strncasecmp("tls1.1", tmp_str, 6) == 0) { - ssl->data[TLS11].ver = TLS_VERSION_11; - if (neg == 1) - ssl->data[TLS11].flags |= DETECT_SSL_VERSION_NEGATED; - } else if (strncasecmp("tls1.2", tmp_str, 6) == 0) { - ssl->data[TLS12].ver = TLS_VERSION_12; - if (neg == 1) - ssl->data[TLS12].flags |= DETECT_SSL_VERSION_NEGATED; - } else if (strcmp(tmp_str, "") == 0) { - SCFree(orig); - if (found == 0) - goto error; - break; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "Invalid value"); - SCFree(orig); - goto error; - } - - found = 1; - neg = 0; - SCFree(orig); - } - } - - return ssl; - -error: - if (ssl != NULL) - DetectSslVersionFree(ssl); - return NULL; - -} - -/** - * \brief this function is used to add the parsed "id" option - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param idstr pointer to the user provided "id" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectSslVersionSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectSslVersionData *ssl = NULL; - SigMatch *sm = NULL; - - ssl = DetectSslVersionParse(str); - if (ssl == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_AL_SSL_VERSION; - sm->ctx = (void *)ssl; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - s->alproto = ALPROTO_TLS; - return 0; - -error: - if (ssl != NULL) - DetectSslVersionFree(ssl); - if (sm != NULL) - SCFree(sm); - return -1; -} - -/** - * \brief this function will free memory associated with DetectSslVersionData - * - * \param id_d pointer to DetectSslVersionData - */ -void DetectSslVersionFree(void *ptr) -{ - if (ptr != NULL) - SCFree(ptr); -} - -/**********************************Unittests***********************************/ - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectSslVersionTestParse01 is a test to make sure that we parse the - * "ssl_version" option correctly when given valid ssl_version option - */ -int DetectSslVersionTestParse01(void) -{ - DetectSslVersionData *ssl = NULL; - ssl = DetectSslVersionParse("SSlv3"); - if (ssl != NULL && ssl->data[SSLv3].ver == SSL_VERSION_3) { - DetectSslVersionFree(ssl); - return 1; - } - - return 0; -} - -/** - * \test DetectSslVersionTestParse02 is a test to make sure that we parse the - * "ssl_version" option correctly when given an invalid ssl_version option - * it should return ssl = NULL - */ -int DetectSslVersionTestParse02(void) -{ - DetectSslVersionData *ssl = NULL; - ssl = DetectSslVersionParse("2.5"); - if (ssl == NULL) { - DetectSslVersionFree(ssl); - return 1; - } - - return 0; -} - -/** - * \test DetectSslVersionTestParse03 is a test to make sure that we parse the - * "ssl_version" options correctly when given valid ssl_version options - */ -int DetectSslVersionTestParse03(void) -{ - DetectSslVersionData *ssl = NULL; - ssl = DetectSslVersionParse("SSlv3,tls1.0, !tls1.2"); - if (ssl != NULL && ssl->data[SSLv3].ver == SSL_VERSION_3 && - ssl->data[TLS10].ver == TLS_VERSION_10 && - ssl->data[TLS12].ver == TLS_VERSION_12 && - ssl->data[TLS12].flags & DETECT_SSL_VERSION_NEGATED) - { - DetectSslVersionFree(ssl); - return 1; - } - - return 0; -} - -#include "stream-tcp-reassemble.h" - -/** \test Send a get request in three chunks + more data. */ -static int DetectSslVersionTestDetect01(void) -{ - int result = 0; - Flow f; - uint8_t sslbuf1[] = { 0x16 }; - uint32_t ssllen1 = sizeof(sslbuf1); - uint8_t sslbuf2[] = { 0x03 }; - uint32_t ssllen2 = sizeof(sslbuf2); - uint8_t sslbuf3[] = { 0x01 }; - uint32_t ssllen3 = sizeof(sslbuf3); - uint8_t sslbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x01 }; - uint32_t ssllen4 = sizeof(sslbuf4); - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_TLS; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tls any any -> any any (msg:\"TLS\"; ssl_version:tls1.0; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf1, ssllen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf2, ssllen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf3, ssllen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf4, ssllen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *app_state = f.alstate; - if (app_state == NULL) { - printf("no ssl state: "); - goto end; - } - - if (app_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_connp.content_type); - goto end; - } - - if (app_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_connp.version); - goto end; - } - - SCLogDebug("app_state is at %p, app_state->server_connp.version 0x%02X app_state->client_connp.version 0x%02X", - app_state, app_state->server_connp.version, app_state->client_connp.version); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -static int DetectSslVersionTestDetect02(void) -{ - int result = 0; - Flow f; - uint8_t sslbuf1[] = { 0x16 }; - uint32_t ssllen1 = sizeof(sslbuf1); - uint8_t sslbuf2[] = { 0x03 }; - uint32_t ssllen2 = sizeof(sslbuf2); - uint8_t sslbuf3[] = { 0x01 }; - uint32_t ssllen3 = sizeof(sslbuf3); - uint8_t sslbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x02 }; - uint32_t ssllen4 = sizeof(sslbuf4); - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_TLS; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tls any any -> any any (msg:\"TLS\"; ssl_version:tls1.0; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf1, ssllen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf2, ssllen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf3, ssllen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf4, ssllen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *app_state = f.alstate; - if (app_state == NULL) { - printf("no ssl state: "); - goto end; - } - - if (app_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_connp.content_type); - goto end; - } - - if (app_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_connp.version); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("signature 1 didn't match while it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -static int DetectSslVersionTestDetect03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Flow f; - uint8_t sslbuf1[] = { 0x16 }; - uint32_t ssllen1 = sizeof(sslbuf1); - uint8_t sslbuf2[] = { 0x03 }; - uint32_t ssllen2 = sizeof(sslbuf2); - uint8_t sslbuf3[] = { 0x01 }; - uint32_t ssllen3 = sizeof(sslbuf3); - uint8_t sslbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x02 }; - uint32_t ssllen4 = sizeof(sslbuf4); - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->tcph->th_seq = htonl(1000); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - f.alproto = ALPROTO_TLS; - f.proto = p->proto; - - StreamTcpInitConfig(TRUE); - - StreamMsg *stream_msg = StreamMsgGetFromPool(); - if (stream_msg == NULL) { - printf("no stream_msg: "); - goto end; - } - - memcpy(stream_msg->data, sslbuf4, ssllen4); - stream_msg->data_len = ssllen4; - - ssn.toserver_smsg_head = stream_msg; - ssn.toserver_smsg_tail = stream_msg; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"TLS\"; ssl_version:tls1.0; content:\"|01 00 00 AD|\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf1, ssllen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf2, ssllen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf3, ssllen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, sslbuf4, ssllen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *app_state = f.alstate; - if (app_state == NULL) { - printf("no ssl state: "); - goto end; - } - - if (app_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", 0x16, app_state->client_connp.content_type); - goto end; - } - - if (app_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, app_state->client_connp.version); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("signature 1 didn't match while it should have: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectSslVersion - */ -void DetectSslVersionRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectSslVersionTestParse01", DetectSslVersionTestParse01, 1); - UtRegisterTest("DetectSslVersionTestParse02", DetectSslVersionTestParse02, 1); - UtRegisterTest("DetectSslVersionTestParse03", DetectSslVersionTestParse03, 1); - UtRegisterTest("DetectSslVersionTestDetect01", DetectSslVersionTestDetect01, 1); - UtRegisterTest("DetectSslVersionTestDetect02", DetectSslVersionTestDetect02, 1); - UtRegisterTest("DetectSslVersionTestDetect03", DetectSslVersionTestDetect03, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/detect-ssl-version.h b/framework/src/suricata/src/detect-ssl-version.h deleted file mode 100644 index b9a0f861..00000000 --- a/framework/src/suricata/src/detect-ssl-version.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file detect-ssl-version.h - * - * \author Gurvinder Singh - * - */ - -#ifndef DETECT_SSL_VERSION_H -#define DETECT_SSL_VERSION_H - -#define DETECT_SSL_VERSION_NEGATED 0x01 - -enum { - SSLv2 = 0, - SSLv3 = 1, - TLS10 = 2, - TLS11 = 3, - TLS12 = 4, - - TLS_SIZE = 5, - TLS_UNKNOWN = 6, -}; - -typedef struct SSLVersionData_ { - uint16_t ver; /** ssl version to match */ - uint8_t flags; -} SSLVersionData; - -typedef struct DetectSslVersionData_ { - SSLVersionData data[TLS_SIZE]; -} DetectSslVersionData; - -/* prototypes */ -void DetectSslVersionRegister (void); - -#endif /* DETECT_SSL_VERSION_H */ diff --git a/framework/src/suricata/src/detect-stream_size.c b/framework/src/suricata/src/detect-stream_size.c deleted file mode 100644 index c3eaad90..00000000 --- a/framework/src/suricata/src/detect-stream_size.c +++ /dev/null @@ -1,532 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - * Stream size for the engine. - */ - -#include "suricata-common.h" -#include "stream-tcp.h" -#include "util-unittest.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "flow.h" -#include "detect-stream_size.h" -#include "stream-tcp-private.h" -#include "util-debug.h" - -/** - * \brief Regex for parsing our flow options - */ -#define PARSE_REGEX "^\\s*([A-z_]+)\\s*,\\s*([<=>!]+)\\s*,\\s*([0-9]+)\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -/*prototypes*/ -int DetectStreamSizeMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectStreamSizeSetup (DetectEngineCtx *, Signature *, char *); -void DetectStreamSizeFree(void *); -void DetectStreamSizeRegisterTests(void); - -/** - * \brief Registration function for stream_size: keyword - */ - -void DetectStreamSizeRegister(void) -{ - sigmatch_table[DETECT_STREAM_SIZE].name = "stream_size"; - sigmatch_table[DETECT_STREAM_SIZE].desc = "match on amount of bytes of a stream"; - sigmatch_table[DETECT_STREAM_SIZE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Flow-keywords#stream_size"; - sigmatch_table[DETECT_STREAM_SIZE].Match = DetectStreamSizeMatch; - sigmatch_table[DETECT_STREAM_SIZE].Setup = DetectStreamSizeSetup; - sigmatch_table[DETECT_STREAM_SIZE].Free = DetectStreamSizeFree; - sigmatch_table[DETECT_STREAM_SIZE].RegisterTests = DetectStreamSizeRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - if (parse_regex != NULL) SCFree(parse_regex); - if (parse_regex_study != NULL) SCFree(parse_regex_study); - return; -} - -/** - * \brief Function to comapre the stream size against defined size in the user - * options. - * - * \param diff The stream size of server or client stream. - * \param stream_size User defined stream size - * \param mode The mode defined by user. - * - * \retval 1 on success and 0 on failure. - */ - -static int DetectStreamSizeCompare (uint32_t diff, uint32_t stream_size, uint8_t mode) { - - int ret = 0; - switch (mode) { - case DETECTSSIZE_LT: - if (diff < stream_size) - ret = 1; - break; - case DETECTSSIZE_LEQ: - if (diff <= stream_size) - ret = 1; - break; - case DETECTSSIZE_EQ: - if (diff == stream_size) - ret = 1; - break; - case DETECTSSIZE_NEQ: - if (diff != stream_size) - ret = 1; - break; - case DETECTSSIZE_GEQ: - if (diff >= stream_size) - ret = 1; - break; - case DETECTSSIZE_GT: - if (diff > stream_size) - ret = 1; - break; - } - - return ret; -} - -/** - * \brief This function is used to match Stream size rule option on a packet with those passed via stream_size: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectStreamSizeData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectStreamSizeMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - - int ret = 0; - const DetectStreamSizeData *sd = (const DetectStreamSizeData *)ctx; - - if (!(PKT_IS_TCP(p))) - return ret; - - uint32_t csdiff = 0; - uint32_t ssdiff = 0; - - if (p->flow == NULL) - return ret; - - TcpSession *ssn = (TcpSession *)p->flow->protoctx; - if (ssn == NULL) - return ret; - - if (sd->flags & STREAM_SIZE_SERVER) { - /* get the server stream size */ - ssdiff = ssn->server.next_seq - ssn->server.isn; - ret = DetectStreamSizeCompare(ssdiff, sd->ssize, sd->mode); - - } else if (sd->flags & STREAM_SIZE_CLIENT) { - /* get the client stream size */ - csdiff = ssn->client.next_seq - ssn->client.isn; - ret = DetectStreamSizeCompare(csdiff, sd->ssize, sd->mode); - - } else if (sd->flags & STREAM_SIZE_BOTH) { - ssdiff = ssn->server.next_seq - ssn->server.isn; - csdiff = ssn->client.next_seq - ssn->client.isn; - if (DetectStreamSizeCompare(ssdiff, sd->ssize, sd->mode) && DetectStreamSizeCompare(csdiff, sd->ssize, sd->mode)) - ret = 1; - - } else if (sd->flags & STREAM_SIZE_EITHER) { - ssdiff = ssn->server.next_seq - ssn->server.isn; - csdiff = ssn->client.next_seq - ssn->client.isn; - if (DetectStreamSizeCompare(ssdiff, sd->ssize, sd->mode) || DetectStreamSizeCompare(csdiff, sd->ssize, sd->mode)) - ret = 1; - } - - return ret; -} - -/** - * \brief This function is used to parse stream options passed via stream_size: keyword - * - * \param streamstr Pointer to the user provided stream_size options - * - * \retval sd pointer to DetectStreamSizeData on success - * \retval NULL on failure - */ - -DetectStreamSizeData *DetectStreamSizeParse (char *streamstr) -{ - - DetectStreamSizeData *sd = NULL; - char *arg = NULL; - char *value = NULL; - char *mode = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, streamstr, strlen(streamstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret != 4) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, streamstr); - goto error; - } - - const char *str_ptr; - - res = pcre_get_substring((char *)streamstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg = (char *)str_ptr; - - res = pcre_get_substring((char *)streamstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - mode = (char *)str_ptr; - - res = pcre_get_substring((char *)streamstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - value = (char *)str_ptr; - - sd = SCMalloc(sizeof(DetectStreamSizeData)); - if (unlikely(sd == NULL)) - goto error; - sd->ssize = 0; - sd->flags = 0; - - if (strlen(mode) == 0) - goto error; - - if (mode[0] == '=') { - sd->mode = DETECTSSIZE_EQ; - } else if (mode[0] == '<') { - sd->mode = DETECTSSIZE_LT; - if (strcmp("<=", mode) == 0) - sd->mode = DETECTSSIZE_LEQ; - } else if (mode[0] == '>') { - sd->mode = DETECTSSIZE_GT; - if (strcmp(">=", mode) == 0) - sd->mode = DETECTSSIZE_GEQ; - } else if (strcmp("!=", mode) == 0) { - sd->mode = DETECTSSIZE_NEQ; - } else { - SCLogError(SC_ERR_INVALID_OPERATOR, "Invalid operator"); - goto error; - } - - /* set the value */ - sd->ssize = (uint32_t)atoi(value); - - /* inspect our options and set the flags */ - if (strcmp(arg, "server") == 0) { - sd->flags |= STREAM_SIZE_SERVER; - } else if (strcmp(arg, "client") == 0) { - sd->flags |= STREAM_SIZE_CLIENT; - } else if ((strcmp(arg, "both") == 0)) { - sd->flags |= STREAM_SIZE_BOTH; - } else if (strcmp(arg, "either") == 0) { - sd->flags |= STREAM_SIZE_EITHER; - } else { - goto error; - } - - SCFree(mode); - SCFree(arg); - SCFree(value); - return sd; - -error: - if (mode != NULL) - SCFree(mode); - if (arg != NULL) - SCFree(arg); - if (value != NULL) - SCFree(value); - if (sd != NULL) - DetectStreamSizeFree(sd); - - return NULL; -} - -/** - * \brief this function is used to add the parsed stream size data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param streamstr pointer to the user provided stream size options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectStreamSizeSetup (DetectEngineCtx *de_ctx, Signature *s, char *streamstr) -{ - - DetectStreamSizeData *sd = NULL; - SigMatch *sm = NULL; - - sd = DetectStreamSizeParse(streamstr); - if (sd == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_STREAM_SIZE; - sm->ctx = (SigMatchCtx *)sd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - - return 0; - -error: - if (sd != NULL) DetectStreamSizeFree(sd); - if (sm != NULL) SCFree(sm); - return -1; -} - -/** - * \brief this function will free memory associated with DetectStreamSizeData - * - * \param ptr pointer to DetectStreamSizeData - */ -void DetectStreamSizeFree(void *ptr) -{ - DetectStreamSizeData *sd = (DetectStreamSizeData *)ptr; - SCFree(sd); -} - -#ifdef UNITTESTS -/** - * \test DetectStreamSizeParseTest01 is a test to make sure that we parse the - * user options correctly, when given valid stream_size options. - */ - -static int DetectStreamSizeParseTest01 (void) -{ - int result = 0; - DetectStreamSizeData *sd = NULL; - sd = DetectStreamSizeParse("server,<,6"); - if (sd != NULL) { - if (sd->flags & STREAM_SIZE_SERVER && sd->mode == DETECTSSIZE_LT && sd->ssize == 6) - result = 1; - DetectStreamSizeFree(sd); - } - - return result; -} - -/** - * \test DetectStreamSizeParseTest02 is a test to make sure that we detect the - * invalid stream_size options. - */ - -static int DetectStreamSizeParseTest02 (void) -{ - int result = 1; - DetectStreamSizeData *sd = NULL; - sd = DetectStreamSizeParse("invalidoption,<,6"); - if (sd != NULL) { - printf("expected: NULL got 0x%02X %" PRId16 ": ",sd->flags, sd->ssize); - result = 0; - DetectStreamSizeFree(sd); - } - - return result; -} - -/** - * \test DetectStreamSizeParseTest03 is a test to make sure that we match the - * packet correctly provided valid stream size. - */ - -static int DetectStreamSizeParseTest03 (void) -{ - - int result = 0; - DetectStreamSizeData *sd = NULL; - TcpSession ssn; - ThreadVars tv; - DetectEngineThreadCtx dtx; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Signature s; - SigMatch sm; - TcpStream client; - Flow f; - TCPHdr tcph; - - memset(&ssn, 0, sizeof(TcpSession)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtx, 0, sizeof(DetectEngineThreadCtx)); - memset(&s, 0, sizeof(Signature)); - memset(&sm, 0, sizeof(SigMatch)); - memset(&client, 0, sizeof(TcpStream)); - memset(&f, 0, sizeof(Flow)); - memset(&tcph, 0, sizeof(TCPHdr)); - - sd = DetectStreamSizeParse("client,>,8"); - if (sd != NULL) { - if (!(sd->flags & STREAM_SIZE_CLIENT)) { - printf("sd->flags not STREAM_SIZE_CLIENT: "); - DetectStreamSizeFree(sd); - SCFree(p); - return 0; - } - - if (sd->mode != DETECTSSIZE_GT) { - printf("sd->mode not DETECTSSIZE_GT: "); - DetectStreamSizeFree(sd); - SCFree(p); - return 0; - } - - if (sd->ssize != 8) { - printf("sd->ssize is %"PRIu32", not 8: ", sd->ssize); - DetectStreamSizeFree(sd); - SCFree(p); - return 0; - } - } else { - printf("sd == NULL: "); - SCFree(p); - return 0; - } - - client.next_seq = 20; - client.isn = 10; - ssn.client = client; - f.protoctx = &ssn; - p->flow = &f; - p->tcph = &tcph; - sm.ctx = (SigMatchCtx*)sd; - - result = DetectStreamSizeMatch(&tv, &dtx, p, &s, sm.ctx); - if (result == 0) { - printf("result 0 != 1: "); - } - DetectStreamSizeFree(sd); - SCFree(p); - return result; -} - -/** - * \test DetectStreamSizeParseTest04 is a test to make sure that we match the - * stream_size against invalid packet parameters. - */ - -static int DetectStreamSizeParseTest04 (void) -{ - - int result = 0; - DetectStreamSizeData *sd = NULL; - TcpSession ssn; - ThreadVars tv; - DetectEngineThreadCtx dtx; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Signature s; - SigMatch sm; - TcpStream client; - Flow f; - IPV4Hdr ip4h; - - memset(&ssn, 0, sizeof(TcpSession)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(&dtx, 0, sizeof(DetectEngineThreadCtx)); - memset(&s, 0, sizeof(Signature)); - memset(&sm, 0, sizeof(SigMatch)); - memset(&client, 0, sizeof(TcpStream)); - memset(&f, 0, sizeof(Flow)); - memset(&ip4h, 0, sizeof(IPV4Hdr)); - - sd = DetectStreamSizeParse(" client , > , 8 "); - if (sd != NULL) { - if (!(sd->flags & STREAM_SIZE_CLIENT) && sd->mode != DETECTSSIZE_GT && sd->ssize != 8) { - SCFree(p); - return 0; - } - } else - { - SCFree(p); - return 0; - } - - client.next_seq = 20; - client.isn = 12; - ssn.client = client; - f.protoctx = &ssn; - p->flow = &f; - p->ip4h = &ip4h; - sm.ctx = (SigMatchCtx*)sd; - - if (!DetectStreamSizeMatch(&tv, &dtx, p, &s, sm.ctx)) - result = 1; - - SCFree(p); - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectStreamSize - */ -void DetectStreamSizeRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectStreamSizeParseTest01", DetectStreamSizeParseTest01, 1); - UtRegisterTest("DetectStreamSizeParseTest02", DetectStreamSizeParseTest02, 1); - UtRegisterTest("DetectStreamSizeParseTest03", DetectStreamSizeParseTest03, 1); - UtRegisterTest("DetectStreamSizeParseTest04", DetectStreamSizeParseTest04, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-stream_size.h b/framework/src/suricata/src/detect-stream_size.h deleted file mode 100644 index 32f5c50b..00000000 --- a/framework/src/suricata/src/detect-stream_size.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - */ - -#ifndef _DETECT_STREAM_SIZE_H -#define _DETECT_STREAM_SIZE_H - -#define DETECTSSIZE_LT 0 -#define DETECTSSIZE_LEQ 1 -#define DETECTSSIZE_EQ 2 -#define DETECTSSIZE_NEQ 3 -#define DETECTSSIZE_GT 4 -#define DETECTSSIZE_GEQ 5 - -#define STREAM_SIZE_SERVER 0x01 -#define STREAM_SIZE_CLIENT 0x02 -#define STREAM_SIZE_BOTH 0x04 -#define STREAM_SIZE_EITHER 0x08 - -typedef struct DetectStreamSizeData_ { - uint8_t flags; - uint8_t mode; - uint32_t ssize; -}DetectStreamSizeData; - -void DetectStreamSizeRegister(void); - -#endif /* _DETECT_STREAM_SIZE_H */ - diff --git a/framework/src/suricata/src/detect-tag.c b/framework/src/suricata/src/detect-tag.c deleted file mode 100644 index d011a0be..00000000 --- a/framework/src/suricata/src/detect-tag.c +++ /dev/null @@ -1,488 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file detect-tag.c - * - * \author Pablo Rincon - * \author Victor Julien - * - * Implements the tag keyword - * - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-tag.h" -#include "detect-engine-tag.h" -#include "detect-engine.h" -#include "detect-engine-state.h" -#include "app-layer-parser.h" - -#include "debug.h" -#include "decode.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" -#include "stream-tcp-private.h" - -#include "util-time.h" -#include "util-byte.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" -#include "threads.h" - -SC_ATOMIC_EXTERN(unsigned int, num_tags); - -/* format: tag: , , , [direction]; */ -#define PARSE_REGEX "^\\s*(host|session)\\s*(,\\s*(\\d+)\\s*,\\s*(packets|bytes|seconds)\\s*(,\\s*(src|dst))?\\s*)?$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectTagMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectTagSetup(DetectEngineCtx *, Signature *, char *); -void DetectTagRegisterTests(void); -void DetectTagDataFree(void *); - -/** - * \brief Registration function for keyword tag - */ -void DetectTagRegister(void) -{ - sigmatch_table[DETECT_TAG].name = "tag"; - sigmatch_table[DETECT_TAG].Match = DetectTagMatch; - sigmatch_table[DETECT_TAG].Setup = DetectTagSetup; - sigmatch_table[DETECT_TAG].Free = DetectTagDataFree; - sigmatch_table[DETECT_TAG].RegisterTests = DetectTagRegisterTests; - sigmatch_table[DETECT_TAG].flags |= SIGMATCH_IPONLY_COMPAT; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - /* XXX */ - return; -} - -/** - * \brief This function is used to setup a tag for session/host - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectTagData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectTagMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectTagData *td = (const DetectTagData *)ctx; - DetectTagDataEntry tde; - memset(&tde, 0, sizeof(DetectTagDataEntry)); - - switch (td->type) { - case DETECT_TAG_TYPE_HOST: -#ifdef DEBUG - BUG_ON(!(td->direction == DETECT_TAG_DIR_SRC || td->direction == DETECT_TAG_DIR_DST)); -#endif - - tde.sid = s->id; - tde.gid = s->gid; - tde.last_ts = tde.first_ts = p->ts.tv_sec; - tde.metric = td->metric; - tde.count = td->count; - if (td->direction == DETECT_TAG_DIR_SRC) - tde.flags |= TAG_ENTRY_FLAG_DIR_SRC; - else if (td->direction == DETECT_TAG_DIR_DST) - tde.flags |= TAG_ENTRY_FLAG_DIR_DST; - - SCLogDebug("Tagging Host with sid %"PRIu32":%"PRIu32"", s->id, s->gid); - TagHashAddTag(&tde, p); - break; - case DETECT_TAG_TYPE_SESSION: - if (p->flow != NULL) { - SCLogDebug("Setting up tag for flow"); - /* If it already exists it will be updated */ - tde.sid = s->id; - tde.gid = s->gid; - tde.last_ts = tde.first_ts = p->ts.tv_sec; - tde.metric = td->metric; - tde.count = td->count; - - SCLogDebug("Adding to or updating flow; first_ts %u count %u", - tde.first_ts, tde.count); - TagFlowAdd(p, &tde); - } else { - SCLogDebug("No flow to append the session tag"); - } - break; -#ifdef DEBUG - default: - SCLogDebug("unknown type of a tag keyword (not session nor host)"); - BUG_ON(1); - break; -#endif - } - - return 1; -} - -/** - * \brief This function is used to parse tag options passed to tag keyword - * - * \param tagstr Pointer to the user provided tag options - * - * \retval td pointer to DetectTagData on success - * \retval NULL on failure - */ -DetectTagData *DetectTagParse(char *tagstr) -{ - DetectTagData td; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *str_ptr = NULL; - - ret = pcre_exec(parse_regex, parse_regex_study, tagstr, strlen(tagstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1) { - SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 ", string %s", ret, tagstr); - goto error; - } - - res = pcre_get_substring((char *)tagstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0 || str_ptr == NULL) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* Type */ - if (strcasecmp("session", str_ptr) == 0) { - td.type = DETECT_TAG_TYPE_SESSION; - } else if (strcasecmp("host", str_ptr) == 0) { - td.type = DETECT_TAG_TYPE_HOST; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "Invalid argument type. Must be session or host (%s)", tagstr); - goto error; - } - pcre_free_substring(str_ptr); - str_ptr = NULL; - - /* default tag is 256 packets from session or dst host */ - td.count = DETECT_TAG_MAX_PKTS; - td.metric = DETECT_TAG_METRIC_PACKET; - td.direction = DETECT_TAG_DIR_DST; - - if (ret > 4) { - res = pcre_get_substring((char *)tagstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); - if (res < 0 || str_ptr == NULL) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* count */ - if (ByteExtractStringUint32(&td.count, 10, strlen(str_ptr), - str_ptr) <= 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Invalid argument for count. Must be a value in the range of 0 to %"PRIu32" (%s)", UINT32_MAX, tagstr); - goto error; - } - - pcre_free_substring(str_ptr); - str_ptr = NULL; - - res = pcre_get_substring((char *)tagstr, ov, MAX_SUBSTRINGS, 4, &str_ptr); - if (res < 0 || str_ptr == NULL) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* metric */ - if (strcasecmp("packets", str_ptr) == 0) { - td.metric = DETECT_TAG_METRIC_PACKET; - if (DETECT_TAG_MAX_PKTS > 0 && td.count > DETECT_TAG_MAX_PKTS) - td.count = DETECT_TAG_MAX_PKTS; - /* TODO: load DETECT_TAG_MAX_PKTS from config */ - } else if (strcasecmp("seconds", str_ptr) == 0) { - td.metric = DETECT_TAG_METRIC_SECONDS; - } else if (strcasecmp("bytes", str_ptr) == 0) { - td.metric = DETECT_TAG_METRIC_BYTES; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "Invalid argument metric. Must be one of \"seconds\", \"packets\" or \"bytes\" (%s)", tagstr); - goto error; - } - - pcre_free_substring(str_ptr); - str_ptr = NULL; - - /* if specified, overwrite it */ - if (ret == 7) { - res = pcre_get_substring((char *)tagstr, ov, MAX_SUBSTRINGS, 6, &str_ptr); - if (res < 0 || str_ptr == NULL) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* metric */ - if (strcasecmp("src", str_ptr) == 0) { - td.direction = DETECT_TAG_DIR_SRC; - } else if (strcasecmp("dst", str_ptr) == 0) { - td.direction = DETECT_TAG_DIR_DST; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "Invalid argument direction. Must be one of \"src\" or \"dst\" (only valid for tag host type, not sessions) (%s)", tagstr); - goto error; - } - - if (td.type != DETECT_TAG_TYPE_HOST) { - SCLogWarning(SC_ERR_INVALID_VALUE, "Argument direction doesn't make sense for type \"session\" (%s [%"PRIu8"])", tagstr, td.type); - } - - pcre_free_substring(str_ptr); - str_ptr = NULL; - } - } - - DetectTagData *real_td = SCMalloc(sizeof(DetectTagData)); - if (unlikely(real_td == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - goto error; - } - - memcpy(real_td, &td, sizeof(DetectTagData)); - return real_td; - -error: - if (str_ptr != NULL) - pcre_free_substring(str_ptr); - return NULL; -} - -/** - * \brief this function is used to add the parsed tag data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param tagstr pointer to the user provided tag options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectTagSetup(DetectEngineCtx *de_ctx, Signature *s, char *tagstr) -{ - DetectTagData *td = NULL; - SigMatch *sm = NULL; - - td = DetectTagParse(tagstr); - if (td == NULL) goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_TAG; - sm->ctx = (SigMatchCtx *)td; - - /* Append it to the list of tags */ - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_TMATCH); - - return 0; - -error: - if (td != NULL) DetectTagDataFree(td); - if (sm != NULL) SCFree(sm); - return -1; - -} - -/** \internal - * \brief this function will free memory associated with - * DetectTagDataEntry - * - * \param td pointer to DetectTagDataEntry - */ -static void DetectTagDataEntryFree(void *ptr) -{ - if (ptr != NULL) { - DetectTagDataEntry *dte = (DetectTagDataEntry *)ptr; - SCFree(dte); - } -} - - -/** - * \brief this function will free all the entries of a list - * DetectTagDataEntry - * - * \param td pointer to DetectTagDataEntryList - */ -void DetectTagDataListFree(void *ptr) -{ - if (ptr != NULL) { - DetectTagDataEntry *entry = ptr; - - while (entry != NULL) { - DetectTagDataEntry *next_entry = entry->next; - DetectTagDataEntryFree(entry); - (void) SC_ATOMIC_SUB(num_tags, 1); - entry = next_entry; - } - } -} - -/** - * \brief this function will free memory associated with DetectTagData - * - * \param td pointer to DetectTagData - */ -void DetectTagDataFree(void *ptr) -{ - DetectTagData *td = (DetectTagData *)ptr; - SCFree(td); -} - -#ifdef UNITTESTS - -/** - * \test DetectTagTestParse01 is a test to make sure that we return "something" - * when given valid tag opt - */ -static int DetectTagTestParse01(void) -{ - int result = 0; - DetectTagData *td = NULL; - td = DetectTagParse("session, 123, packets"); - if (td != NULL && td->type == DETECT_TAG_TYPE_SESSION - && td->count == 123 - && td->metric == DETECT_TAG_METRIC_PACKET) { - DetectTagDataFree(td); - result = 1; - } - - return result; -} - -/** - * \test DetectTagTestParse02 is a test to check that we parse tag correctly - */ -static int DetectTagTestParse02(void) -{ - int result = 0; - DetectTagData *td = NULL; - td = DetectTagParse("host, 200, bytes, src"); - if (td != NULL && td->type == DETECT_TAG_TYPE_HOST - && td->count == 200 - && td->metric == DETECT_TAG_METRIC_BYTES - && td->direction == DETECT_TAG_DIR_SRC) { - result = 1; - DetectTagDataFree(td); - } - - return result; -} - -/** - * \test DetectTagTestParse03 is a test for setting the stateless tag opt - */ -static int DetectTagTestParse03(void) -{ - int result = 0; - DetectTagData *td = NULL; - td = DetectTagParse("host, 200, bytes, dst"); - if (td != NULL && td->type == DETECT_TAG_TYPE_HOST - && td->count == 200 - && td->metric == DETECT_TAG_METRIC_BYTES - && td->direction == DETECT_TAG_DIR_DST) { - result = 1; - DetectTagDataFree(td); - } - - return result; -} - -/** - * \test DetectTagTestParse04 is a test for default opts - */ -static int DetectTagTestParse04(void) -{ - int result = 0; - DetectTagData *td = NULL; - td = DetectTagParse("session"); - if (td != NULL && td->type == DETECT_TAG_TYPE_SESSION - && td->count == DETECT_TAG_MAX_PKTS - && td->metric == DETECT_TAG_METRIC_PACKET) { - result = 1; - DetectTagDataFree(td); - } - - return result; -} - -/** - * \test DetectTagTestParse05 is a test for default opts - */ -static int DetectTagTestParse05(void) -{ - int result = 0; - DetectTagData *td = NULL; - td = DetectTagParse("host"); - if (td != NULL && td->type == DETECT_TAG_TYPE_HOST - && td->count == DETECT_TAG_MAX_PKTS - && td->metric == DETECT_TAG_METRIC_PACKET - && td->direction == DETECT_TAG_DIR_DST) { - result = 1; - DetectTagDataFree(td); - } - - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectTag - */ -void DetectTagRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectTagTestParse01", DetectTagTestParse01, 1); - UtRegisterTest("DetectTagTestParse02", DetectTagTestParse02, 1); - UtRegisterTest("DetectTagTestParse03", DetectTagTestParse03, 1); - UtRegisterTest("DetectTagTestParse04", DetectTagTestParse04, 1); - UtRegisterTest("DetectTagTestParse05", DetectTagTestParse05, 1); - - DetectEngineTagRegisterTests(); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-tag.h b/framework/src/suricata/src/detect-tag.h deleted file mode 100644 index 080d36a7..00000000 --- a/framework/src/suricata/src/detect-tag.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * \author Victor Julien - */ - -#ifndef __DETECT_TAG_H__ -#define __DETECT_TAG_H__ - -#include "suricata-common.h" -#include "suricata.h" -#include "util-time.h" - -/* Limit the number of times a session can be tagged by the - * same rule without finishing older tags */ -#define DETECT_TAG_MATCH_LIMIT 10 - -/* Limit the number of tags that a session can have */ -#define DETECT_TAG_MAX_TAGS 50 - -/* Limit the number of pkts to capture. Change this to - * zero to make it unlimited - * TODO: load it from config (var tagged_packet_limit) */ -#define DETECT_TAG_MAX_PKTS 256 - -/* Type of tag: session or host */ -enum { - DETECT_TAG_TYPE_SESSION, - DETECT_TAG_TYPE_HOST, - DETECT_TAG_TYPE_MAX -}; - -enum { - DETECT_TAG_DIR_SRC, - DETECT_TAG_DIR_DST, - DETECT_TAG_DIR_MAX -}; - -enum { - DETECT_TAG_METRIC_PACKET, - DETECT_TAG_METRIC_SECONDS, - DETECT_TAG_METRIC_BYTES, - DETECT_TAG_METRIC_MAX -}; - -/** This will be the rule options/parameters */ -typedef struct DetectTagData_ { - uint8_t type; /**< tag type */ - uint8_t direction; /**< host direction */ - uint32_t count; /**< count */ - uint32_t metric; /**< metric */ -} DetectTagData; - -/** This is the installed data at the session/global or host table */ -typedef struct DetectTagDataEntry_ { - uint8_t flags:3; - uint8_t metric:5; - uint8_t pad0; - uint16_t cnt_match; /**< number of times this tag was reset/updated */ - - uint32_t count; /**< count setting from rule */ - uint32_t sid; /**< sid originating the tag */ - uint32_t gid; /**< gid originating the tag */ - union { - uint32_t packets; /**< number of packets (metric packets) */ - uint32_t bytes; /**< number of bytes (metric bytes) */ - }; - uint32_t first_ts; /**< First time seen (for metric = seconds) */ - uint32_t last_ts; /**< Last time seen (to prune old sessions) */ -#if __WORDSIZE == 64 - uint32_t pad1; -#endif - struct DetectTagDataEntry_ *next; /**< Pointer to the next tag of this - * session/src_host/dst_host (if any from other rule) */ -} DetectTagDataEntry; - -#define TAG_ENTRY_FLAG_DIR_SRC 0x01 -#define TAG_ENTRY_FLAG_DIR_DST 0x02 -#define TAG_ENTRY_FLAG_SKIPPED_FIRST 0x04 - -/* prototypes */ -void DetectTagRegister(void); -void DetectTagDataFree(void *ptr); -void DetectTagDataListFree(void *ptr); - -#endif /* __DETECT_TAG_H__ */ - diff --git a/framework/src/suricata/src/detect-template-buffer.c b/framework/src/suricata/src/detect-template-buffer.c deleted file mode 100644 index d9f9aa67..00000000 --- a/framework/src/suricata/src/detect-template-buffer.c +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file Set up of the "template_buffer" keyword to allow content inspections - * on the decoded template application layer buffers. - */ - -#include "suricata-common.h" -#include "conf.h" -#include "detect.h" -#include "app-layer-template.h" - -static int DetectTemplateBufferSetup(DetectEngineCtx *, Signature *, char *); -static void DetectTemplateBufferRegisterTests(void); - -void DetectTemplateBufferRegister(void) -{ - if (ConfGetNode("app-layer.protocols.template") == NULL) { - return; - } - - sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].name = "template_buffer"; - sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].desc = - "Template content modififier to match on the template buffers"; - sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].alproto = ALPROTO_TEMPLATE; - sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].Setup = DetectTemplateBufferSetup; - sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].RegisterTests = - DetectTemplateBufferRegisterTests; - - sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_NOOPT; - sigmatch_table[DETECT_AL_TEMPLATE_BUFFER].flags |= SIGMATCH_PAYLOAD; - - SCLogNotice("Template application layer detect registered."); -} - -static int DetectTemplateBufferSetup(DetectEngineCtx *de_ctx, Signature *s, - char *str) -{ - s->list = DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH; - s->alproto = ALPROTO_TEMPLATE; - return 0; -} - -#ifdef UNITTESTS - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer-parser.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "flow-util.h" -#include "stream-tcp.h" - -static int DetectTemplateBufferTest(void) -{ - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - Flow f; - Packet *p; - TcpSession tcp; - ThreadVars tv; - Signature *s; - - int result = 0; - - uint8_t request[] = "Hello World!"; - - /* Setup flow. */ - memset(&f, 0, sizeof(Flow)); - memset(&tcp, 0, sizeof(TcpSession)); - memset(&tv, 0, sizeof(ThreadVars)); - p = UTHBuildPacket(request, sizeof(request), IPPROTO_TCP); - FLOW_INITIALIZE(&f); - f.alproto = ALPROTO_TEMPLATE; - f.protoctx = (void *)&tcp; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST; - p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED; - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - /* This rule should match. */ - s = DetectEngineAppendSig(de_ctx, - "alert tcp any any -> any any (" - "msg:\"TEMPLATE Test Rule\"; " - "template_buffer; content:\"World!\"; " - "sid:1; rev:1;)"); - if (s == NULL) { - goto end; - } - - /* This rule should not match. */ - s = DetectEngineAppendSig(de_ctx, - "alert tcp any any -> any any (" - "msg:\"TEMPLATE Test Rule\"; " - "template_buffer; content:\"W0rld!\"; " - "sid:2; rev:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - AppLayerParserParse(alp_tctx, &f, ALPROTO_TEMPLATE, STREAM_TOSERVER, - request, sizeof(request)); - SCMutexUnlock(&f.m); - - /* Check that we have app-layer state. */ - if (f.alstate == NULL) { - goto end; - } - - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - if (!PacketAlertCheck(p, 1)) { - goto end; - } - if (PacketAlertCheck(p, 2)) { - goto end; - } - - result = 1; -end: - /* Cleanup. */ - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePacket(p); - - return result; -} - -#endif - -static void DetectTemplateBufferRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectTemplateBufferTest", DetectTemplateBufferTest, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-template-buffer.h b/framework/src/suricata/src/detect-template-buffer.h deleted file mode 100644 index 8a2ab8ba..00000000 --- a/framework/src/suricata/src/detect-template-buffer.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __DETECT_TEMPLATE_BUFFER_H__ -#define __DETECT_TEMPLATE_BUFFER_H__ - -#include "app-layer-template.h" - -void DetectTemplateBufferRegister(void); - -#endif /* __DETECT_TEMPLATE_BUFFER_H__ */ diff --git a/framework/src/suricata/src/detect-template.c b/framework/src/suricata/src/detect-template.c deleted file mode 100644 index ecad7880..00000000 --- a/framework/src/suricata/src/detect-template.c +++ /dev/null @@ -1,303 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author XXX Yourname - * - * XXX Short description of the purpose of this keyword - */ - -#include "suricata-common.h" -#include "util-unittest.h" - -#include "detect-parse.h" -#include "detect-engine.h" - -#include "detect-template.h" - -/** - * \brief Regex for parsing our keyword options - */ -#define PARSE_REGEX "^\\s*([0-9]+)?\\s*,s*([0-9]+)?\\s*$" -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -/* Prototypes of functions registered in DetectTemplateRegister below */ -static int DetectTemplateMatch (ThreadVars *, DetectEngineThreadCtx *, - Packet *, Signature *, const SigMatchCtx *); -static int DetectTemplateSetup (DetectEngineCtx *, Signature *, char *); -static void DetectTemplateFree (void *); -static void DetectTemplateRegisterTests (void); - -/** - * \brief Registration function for template: keyword - * - * This function is called once in the 'lifetime' of the engine. - */ -void DetectTemplateRegister(void) { - /* keyword name: this is how the keyword is used in a rule */ - sigmatch_table[DETECT_TEMPLATE].name = "template"; - /* description: listed in "suricata --list-keywords=all" */ - sigmatch_table[DETECT_TEMPLATE].desc = "give an introduction into how a detection module works"; - /* link to further documentation of the keyword. Normally on the Suricata redmine/wiki */ - sigmatch_table[DETECT_TEMPLATE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Suricata_Developers_Guide"; - /* match function is called when the signature is inspected on a packet */ - sigmatch_table[DETECT_TEMPLATE].Match = DetectTemplateMatch; - /* setup function is called during signature parsing, when the template - * keyword is encountered in the rule */ - sigmatch_table[DETECT_TEMPLATE].Setup = DetectTemplateSetup; - /* free function is called when the detect engine is freed. Normally at - * shutdown, but also during rule reloads. */ - sigmatch_table[DETECT_TEMPLATE].Free = DetectTemplateFree; - /* registers unittests into the system */ - sigmatch_table[DETECT_TEMPLATE].RegisterTests = DetectTemplateRegisterTests; - - /* set up the PCRE for keyword parsing */ - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at " - "offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - if (parse_regex != NULL) - SCFree(parse_regex); - if (parse_regex_study != NULL) - SCFree(parse_regex_study); - return; -} - -/** - * \brief This function is used to match TEMPLATE rule option on a packet - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch with context that we will cast into DetectTemplateData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectTemplateMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, - Signature *s, const SigMatchCtx *ctx) -{ - int ret = 0; - const DetectTemplateData *templated = (const DetectTemplateData *) ctx; -#if 0 - if (PKT_IS_PSEUDOPKT(p)) { - /* fake pkt */ - } - - if (PKT_IS_IPV4(p)) { - /* ipv4 pkt */ - } else if (PKT_IS_IPV6(p)) { - /* ipv6 pkt */ - } else { - SCLogDebug("packet is of not IPv4 or IPv6"); - return ret; - } -#endif - /* packet payload access */ - if (p->payload != NULL && p->payload_len > 0) { - if (templated->arg1 == p->payload[0] && - templated->arg2 == p->payload[p->payload_len - 1]) - { - ret = 1; - } - } - - return ret; -} - -/** - * \brief This function is used to parse template options passed via template: keyword - * - * \param templatestr Pointer to the user provided template options - * - * \retval templated pointer to DetectTemplateData on success - * \retval NULL on failure - */ -static DetectTemplateData *DetectTemplateParse (const char *templatestr) -{ - DetectTemplateData *templated = NULL; - char arg1[4] = ""; - char arg2[4] = ""; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, - templatestr, strlen(templatestr), - 0, 0, ov, MAX_SUBSTRINGS); - if (ret != 3) { - SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 "", ret); - goto error; - } - - res = pcre_copy_substring((char *) templatestr, ov, MAX_SUBSTRINGS, 1, arg1, sizeof(arg1)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - SCLogDebug("Arg1 \"%s\"", arg1); - - if (ret >= 3) { - res = pcre_copy_substring((char *) templatestr, ov, MAX_SUBSTRINGS, 2, arg2, sizeof(arg2)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - SCLogDebug("Arg2 \"%s\"", arg2); - - } - - templated = SCMalloc(sizeof (DetectTemplateData)); - if (unlikely(templated == NULL)) - goto error; - templated->arg1 = (uint8_t)atoi(arg1); - templated->arg2 = (uint8_t)atoi(arg2); - - return templated; - -error: - if (templated) - SCFree(templated); - return NULL; -} - -/** - * \brief parse the options from the 'template' keyword in the rule into - * the Signature data structure. - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param templatestr pointer to the user provided template options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectTemplateSetup (DetectEngineCtx *de_ctx, Signature *s, char *templatestr) -{ - DetectTemplateData *templated = NULL; - SigMatch *sm = NULL; - - templated = DetectTemplateParse(templatestr); - if (templated == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_TEMPLATE; - sm->ctx = (void *)templated; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (templated != NULL) - DetectTemplateFree(templated); - if (sm != NULL) - SCFree(sm); - return -1; -} - -/** - * \brief this function will free memory associated with DetectTemplateData - * - * \param ptr pointer to DetectTemplateData - */ -static void DetectTemplateFree(void *ptr) { - DetectTemplateData *templated = (DetectTemplateData *)ptr; - - /* do more specific cleanup here, if needed */ - - SCFree(templated); -} - -#ifdef UNITTESTS - -/** - * \test description of the test - */ - -static int DetectTemplateParseTest01 (void) { - DetectTemplateData *templated = NULL; - uint8_t res = 0; - - templated = DetectTemplateParse("1,10"); - if (templated != NULL) { - if (templated->arg1 == 1 && templated->arg2 == 10) - res = 1; - - DetectTemplateFree(templated); - } - - return res; -} - -static int DetectTemplateSignatureTest01 (void) { - uint8_t res = 0; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - Signature *sig = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (template:1,10; sid:1; rev:1;)"); - if (sig == NULL) { - printf("parsing signature failed: "); - goto end; - } - - /* if we get here, all conditions pass */ - res = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return res; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectTemplate - */ -void DetectTemplateRegisterTests(void) { -#ifdef UNITTESTS - UtRegisterTest("DetectTemplateParseTest01", - DetectTemplateParseTest01, 1); - UtRegisterTest("DetectTemplateSignatureTest01", - DetectTemplateSignatureTest01, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-template.h b/framework/src/suricata/src/detect-template.h deleted file mode 100644 index d86c0083..00000000 --- a/framework/src/suricata/src/detect-template.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author XXX Yourname - */ - -#ifndef __DETECT_TEMPLATE_H__ -#define __DETECT_TEMPLATE_H__ - -/** Per keyword data. This is set up by the DetectTemplateSetup() function. - * Each signature will have an instance of DetectTemplateData per occurence - * of the keyword. - * The structure should be considered static/readonly after initialization. - */ -typedef struct DetectTemplateData_ { - uint8_t arg1; - uint8_t arg2; -} DetectTemplateData; - -/** \brief registers the keyword into the engine. Called from - * detect.c::SigTableSetup() */ -void DetectTemplateRegister(void); - -#endif /* __DETECT_TEMPLATE_H__ */ diff --git a/framework/src/suricata/src/detect-threshold.c b/framework/src/suricata/src/detect-threshold.c deleted file mode 100644 index 236b6bf6..00000000 --- a/framework/src/suricata/src/detect-threshold.c +++ /dev/null @@ -1,1525 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup threshold - * @{ - */ - -/** - * \file - * - * \author Breno Silva - * \author Victor Julien - * - * Implements the threshold keyword. - * - * The feature depends on what is provided - * by detect-engine-threshold.c and util-threshold-config.c - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "host.h" -#include "host-storage.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "flow-var.h" -#include "decode-events.h" -#include "stream-tcp.h" - -#include "detect-threshold.h" -#include "detect-engine-threshold.h" -#include "detect-parse.h" -#include "detect-engine-address.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-byte.h" -#include "util-debug.h" - -#ifdef UNITTESTS -#include "util-cpu.h" -#endif - -#define PARSE_REGEX "^\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -static int DetectThresholdMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectThresholdSetup(DetectEngineCtx *, Signature *, char *); -static void DetectThresholdFree(void *); - -/** - * \brief Registration function for threshold: keyword - */ - -void DetectThresholdRegister(void) -{ - sigmatch_table[DETECT_THRESHOLD].name = "threshold"; - sigmatch_table[DETECT_THRESHOLD].desc = "control the rule's alert frequency"; - sigmatch_table[DETECT_THRESHOLD].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Rule-Thresholding#threshold"; - sigmatch_table[DETECT_THRESHOLD].Match = DetectThresholdMatch; - sigmatch_table[DETECT_THRESHOLD].Setup = DetectThresholdSetup; - sigmatch_table[DETECT_THRESHOLD].Free = DetectThresholdFree; - sigmatch_table[DETECT_THRESHOLD].RegisterTests = ThresholdRegisterTests; - /* this is compatible to ip-only signatures */ - sigmatch_table[DETECT_THRESHOLD].flags |= SIGMATCH_IPONLY_COMPAT; - - const char *eb; - int opts = 0; - int eo; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - -error: - return; - -} - -static int DetectThresholdMatch(ThreadVars *thv, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - return 1; -} - -/** - * \internal - * \brief This function is used to parse threshold options passed via threshold: keyword - * - * \param rawstr Pointer to the user provided threshold options - * - * \retval de pointer to DetectThresholdData on success - * \retval NULL on failure - */ -static DetectThresholdData *DetectThresholdParse(char *rawstr) -{ - DetectThresholdData *de = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *str_ptr = NULL; - char *args[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - char *copy_str = NULL, *threshold_opt = NULL; - int second_found = 0, count_found = 0; - int type_found = 0, track_found = 0; - int second_pos = 0, count_pos = 0; - uint16_t pos = 0; - int i = 0; - - copy_str = SCStrdup(rawstr); - if (unlikely(copy_str == NULL)) { - goto error; - } - - char *saveptr = NULL; - for (pos = 0, threshold_opt = strtok_r(copy_str,",", &saveptr); - pos < strlen(copy_str) && threshold_opt != NULL; - pos++, threshold_opt = strtok_r(NULL,"," , &saveptr)) - { - if(strstr(threshold_opt,"count")) - count_found++; - if(strstr(threshold_opt,"second")) - second_found++; - if(strstr(threshold_opt,"type")) - type_found++; - if(strstr(threshold_opt,"track")) - track_found++; - } - SCFree(copy_str); - copy_str = NULL; - - if(count_found != 1 || second_found != 1 || type_found != 1 || track_found != 1) - goto error; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - - if (ret < 5) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr); - goto error; - } - - de = SCMalloc(sizeof(DetectThresholdData)); - if (unlikely(de == NULL)) - goto error; - - memset(de,0,sizeof(DetectThresholdData)); - - for (i = 0; i < (ret - 1); i++) { - - res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS,i + 1, &str_ptr); - - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - args[i] = (char *)str_ptr; - - if (strncasecmp(args[i],"limit",strlen("limit")) == 0) - de->type = TYPE_LIMIT; - if (strncasecmp(args[i],"both",strlen("both")) == 0) - de->type = TYPE_BOTH; - if (strncasecmp(args[i],"threshold",strlen("threshold")) == 0) - de->type = TYPE_THRESHOLD; - if (strncasecmp(args[i],"by_dst",strlen("by_dst")) == 0) - de->track = TRACK_DST; - if (strncasecmp(args[i],"by_src",strlen("by_src")) == 0) - de->track = TRACK_SRC; - if (strncasecmp(args[i],"count",strlen("count")) == 0) - count_pos = i+1; - if (strncasecmp(args[i],"seconds",strlen("seconds")) == 0) - second_pos = i+1; - } - - if (args[count_pos] == NULL || args[second_pos] == NULL) { - goto error; - } - - if (ByteExtractStringUint32(&de->count, 10, strlen(args[count_pos]), - args[count_pos]) <= 0) { - goto error; - } - - if (ByteExtractStringUint32(&de->seconds, 10, strlen(args[second_pos]), - args[second_pos]) <= 0) { - goto error; - } - - for (i = 0; i < (ret - 1); i++){ - if (args[i] != NULL) SCFree(args[i]); - } - return de; - -error: - for (i = 0; i < (ret - 1); i++){ - if (args[i] != NULL) SCFree(args[i]); - } - if (de != NULL) - SCFree(de); - return NULL; -} - -/** - * \internal - * \brief this function is used to add the parsed threshold into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param rawstr pointer to the user provided threshold options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectThresholdSetup(DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectThresholdData *de = NULL; - SigMatch *sm = NULL; - SigMatch *tmpm = NULL; - - /* checks if there is a previous instance of detection_filter */ - tmpm = SigMatchGetLastSMFromLists(s, 2, - DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_MATCH]); - if (tmpm != NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "\"detection_filter\" and \"threshold\" are not allowed in the same rule"); - SCReturnInt(-1); - } - - de = DetectThresholdParse(rawstr); - if (de == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_THRESHOLD; - sm->ctx = (SigMatchCtx *)de; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD); - - return 0; - -error: - if (de) SCFree(de); - if (sm) SCFree(sm); - return -1; -} - -/** - * \internal - * \brief this function will free memory associated with DetectThresholdData - * - * \param de pointer to DetectThresholdData - */ -static void DetectThresholdFree(void *de_ptr) -{ - DetectThresholdData *de = (DetectThresholdData *)de_ptr; - if (de) { - DetectAddressHeadCleanup(&de->addrs); - SCFree(de); - } -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-threshold.h" -#include "util-time.h" -#include "util-hashlist.h" - -/** - * \test ThresholdTestParse01 is a test for a valid threshold options - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int ThresholdTestParse01(void) -{ - DetectThresholdData *de = NULL; - de = DetectThresholdParse("type limit,track by_dst,count 10,seconds 60"); - if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) { - DetectThresholdFree(de); - return 1; - } - - return 0; -} - -/** - * \test ThresholdTestParse02 is a test for a invalid threshold options - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int ThresholdTestParse02(void) -{ - DetectThresholdData *de = NULL; - de = DetectThresholdParse("type any,track by_dst,count 10,seconds 60"); - if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) { - DetectThresholdFree(de); - return 1; - } - - return 0; -} - -/** - * \test ThresholdTestParse03 is a test for a valid threshold options in any order - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int ThresholdTestParse03(void) -{ - DetectThresholdData *de = NULL; - de = DetectThresholdParse("track by_dst, type limit, seconds 60, count 10"); - if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) { - DetectThresholdFree(de); - return 1; - } - - return 0; -} - - -/** - * \test ThresholdTestParse04 is a test for an invalid threshold options in any order - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int ThresholdTestParse04(void) -{ - DetectThresholdData *de = NULL; - de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both, count 10"); - if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) { - DetectThresholdFree(de); - return 1; - } - - return 0; -} - -/** - * \test ThresholdTestParse05 is a test for a valid threshold options in any order - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int ThresholdTestParse05(void) -{ - DetectThresholdData *de = NULL; - de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both"); - if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) { - DetectThresholdFree(de); - return 1; - } - - return 0; -} - - -/** - * \test DetectThresholdTestSig1 is a test for checking the working of limit keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int DetectThresholdTestSig1(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - - HostInitConfig(HOST_QUIET); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; content:\"A\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - - if (s->flags & SIG_FLAG_IPONLY) { - printf("signature is ip-only: "); - goto end; - } - - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 1); - if (alerts != 1) { - printf("alerts %"PRIi32", expected 1: ", alerts); - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - if (alerts != 2) { - printf("alerts %"PRIi32", expected 2: ", alerts); - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - if (alerts != 3) { - printf("alerts %"PRIi32", expected 3: ", alerts); - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - if (alerts != 4) { - printf("alerts %"PRIi32", expected 4: ", alerts); - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - if (alerts != 5) { - printf("alerts %"PRIi32", expected 5: ", alerts); - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - if (alerts != 5) { - printf("alerts %"PRIi32", expected 5: ", alerts); - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - if (alerts != 5) { - printf("alerts %"PRIi32", expected 5: ", alerts); - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - if (alerts != 5) { - printf("alerts %"PRIi32", expected 5: ", alerts); - } - - if(alerts == 5) - result = 1; - else - printf("alerts %"PRIi32", expected 5: ", alerts); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); - - HostShutdown(); -end: - return result; -} - -/** - * \test DetectThresholdTestSig2 is a test for checking the working of threshold keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int DetectThresholdTestSig2(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - - HostInitConfig(HOST_QUIET); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold\"; threshold: type threshold, track by_dst, count 5, seconds 60; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - - if (alerts == 2) - result = 1; - else - goto cleanup; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test DetectThresholdTestSig3 is a test for checking the working of limit keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int DetectThresholdTestSig3(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - struct timeval ts; - DetectThresholdEntry *lookup_tsh = NULL; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - Host *host = HostLookupHostFromHash(&p->dst); - if (host == NULL) { - printf("host not found: "); - goto cleanup; - } - - if (!(ThresholdHostHasThreshold(host))) { - HostRelease(host); - printf("host has no threshold: "); - goto cleanup; - } - HostRelease(host); - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - host = HostLookupHostFromHash(&p->dst); - if (host == NULL) { - printf("host not found: "); - goto cleanup; - } - HostRelease(host); - - lookup_tsh = HostGetStorageById(host, ThresholdHostStorageId()); - if (lookup_tsh == NULL) { - HostRelease(host); - printf("lookup_tsh is NULL: "); - goto cleanup; - } - - alerts = lookup_tsh->current_count; - - if (alerts == 3) - result = 1; - else { - printf("alerts %u != 3: ", alerts); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test DetectThresholdTestSig4 is a test for checking the working of both keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int DetectThresholdTestSig4(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - struct timeval ts; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold both\"; threshold: type both, track by_dst, count 2, seconds 60; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - - if (alerts == 2) - result = 1; - else - goto cleanup; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test DetectThresholdTestSig5 is a test for checking the working of limit keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int DetectThresholdTestSig5(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - - HostInitConfig(HOST_QUIET); - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - - if(alerts == 10) - result = 1; - else { - printf("alerts %d != 10: ", alerts); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -static int DetectThresholdTestSig6Ticks(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - - HostInitConfig(HOST_QUIET); - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - uint64_t ticks_start = 0; - uint64_t ticks_end = 0; - - ticks_start = UtilCpuGetTicks(); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 1); - alerts += PacketAlertCheck(p, 1000); - ticks_end = UtilCpuGetTicks(); - printf("test run %"PRIu64"\n", (ticks_end - ticks_start)); - - if(alerts == 10) - result = 1; - else - goto cleanup; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test Test drop action being set even if thresholded - */ -static int DetectThresholdTestSig7(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - int drops = 0; - struct timeval ts; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type limit, track by_src, count 1, seconds 300; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - if (alerts == 1 && drops == 6) - result = 1; - else { - if (alerts != 1) - printf("alerts: %d != 1: ", alerts); - if (drops != 6) - printf("drops: %d != 6: ", drops); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test Test drop action being set even if thresholded - */ -static int DetectThresholdTestSig8(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - int drops = 0; - struct timeval ts; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type limit, track by_src, count 2, seconds 300; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - if (alerts == 2 && drops == 6) - result = 1; - else { - if (alerts != 1) - printf("alerts: %d != 1: ", alerts); - if (drops != 6) - printf("drops: %d != 6: ", drops); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test Test drop action being set even if thresholded - */ -static int DetectThresholdTestSig9(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - int drops = 0; - struct timeval ts; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type threshold, track by_src, count 3, seconds 100; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - if (alerts == 2 && drops == 2) - result = 1; - else { - if (alerts != 2) - printf("alerts: %d != 2: ", alerts); - if (drops != 2) - printf("drops: %d != 2: ", drops); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test Test drop action being set even if thresholded - */ -static int DetectThresholdTestSig10(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - int drops = 0; - struct timeval ts; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type threshold, track by_src, count 5, seconds 300; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - if (alerts == 1 && drops == 1) - result = 1; - else { - if (alerts != 1) - printf("alerts: %d != 1: ", alerts); - if (drops != 1) - printf("drops: %d != 1: ", drops); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test Test drop action being set even if thresholded - */ -static int DetectThresholdTestSig11(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - int drops = 0; - struct timeval ts; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type both, track by_src, count 3, seconds 300; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - if (alerts == 1 && drops == 4) - result = 1; - else { - if (alerts != 1) - printf("alerts: %d != 1: ", alerts); - if (drops != 4) - printf("drops: %d != 4: ", drops); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -/** - * \test Test drop action being set even if thresholded - */ -static int DetectThresholdTestSig12(void) -{ - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - int alerts = 0; - int drops = 0; - struct timeval ts; - - HostInitConfig(HOST_QUIET); - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type both, track by_src, count 5, seconds 300; sid:10;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - TimeSetIncrementTime(200); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0); - p->action = 0; - - if (alerts == 1 && drops == 2) - result = 1; - else { - if (alerts != 1) - printf("alerts: %d != 1: ", alerts); - if (drops != 2) - printf("drops: %d != 2: ", drops); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void*)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - HostShutdown(); - return result; -} - -#endif /* UNITTESTS */ - -void ThresholdRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("ThresholdTestParse01", ThresholdTestParse01, 1); - UtRegisterTest("ThresholdTestParse02", ThresholdTestParse02, 0); - UtRegisterTest("ThresholdTestParse03", ThresholdTestParse03, 1); - UtRegisterTest("ThresholdTestParse04", ThresholdTestParse04, 0); - UtRegisterTest("ThresholdTestParse05", ThresholdTestParse05, 1); - UtRegisterTest("DetectThresholdTestSig1", DetectThresholdTestSig1, 1); - UtRegisterTest("DetectThresholdTestSig2", DetectThresholdTestSig2, 1); - UtRegisterTest("DetectThresholdTestSig3", DetectThresholdTestSig3, 1); - UtRegisterTest("DetectThresholdTestSig4", DetectThresholdTestSig4, 1); - UtRegisterTest("DetectThresholdTestSig5", DetectThresholdTestSig5, 1); - UtRegisterTest("DetectThresholdTestSig6Ticks", DetectThresholdTestSig6Ticks, 1); - UtRegisterTest("DetectThresholdTestSig7", DetectThresholdTestSig7, 1); - UtRegisterTest("DetectThresholdTestSig8", DetectThresholdTestSig8, 1); - UtRegisterTest("DetectThresholdTestSig9", DetectThresholdTestSig9, 1); - UtRegisterTest("DetectThresholdTestSig10", DetectThresholdTestSig10, 1); - UtRegisterTest("DetectThresholdTestSig11", DetectThresholdTestSig11, 1); - UtRegisterTest("DetectThresholdTestSig12", DetectThresholdTestSig12, 1); -#endif /* UNITTESTS */ -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/detect-threshold.h b/framework/src/suricata/src/detect-threshold.h deleted file mode 100644 index 50e1d270..00000000 --- a/framework/src/suricata/src/detect-threshold.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva - */ - -#ifndef __DETECT_THRESHOLD_H__ -#define __DETECT_THRESHOLD_H__ - -#include "decode-events.h" -#include "decode-ipv4.h" -#include "decode-tcp.h" - -#define TYPE_LIMIT 1 -#define TYPE_BOTH 2 -#define TYPE_THRESHOLD 3 -#define TYPE_DETECTION 4 -#define TYPE_RATE 5 -#define TYPE_SUPPRESS 6 - -#define TRACK_DST 1 -#define TRACK_SRC 2 -#define TRACK_RULE 3 -#define TRACK_EITHER 4 /**< either src or dst: only used by suppress */ - -/* Get the new action to take */ -#define TH_ACTION_ALERT 0x01 -#define TH_ACTION_DROP 0x02 -#define TH_ACTION_PASS 0x04 -#define TH_ACTION_LOG 0x08 -#define TH_ACTION_SDROP 0x10 -#define TH_ACTION_REJECT 0x20 - -/** - * \typedef DetectThresholdData - * A typedef for DetectThresholdData_ - */ - -typedef struct DetectThresholdData_ { - uint32_t count; /**< Event count */ - uint32_t seconds; /**< Event seconds */ - uint8_t type; /**< Threshold type : limit , threshold, both, detection_filter */ - uint8_t track; /**< Track type: by_src, by_dst */ - uint8_t new_action; /**< new_action alert|drop|pass|log|sdrop|reject */ - uint32_t timeout; /**< timeout */ - uint32_t flags; /**< flags used to set option */ - DetectAddressHead addrs; -} DetectThresholdData; - -typedef struct DetectThresholdEntry_ { - uint32_t sid; /**< Signature id */ - uint32_t gid; /**< Signature group id */ - - uint32_t tv_timeout; /**< Timeout for new_action (for rate_filter) - its not "seconds", that define the time interval */ - uint32_t seconds; /**< Event seconds */ - uint32_t tv_sec1; /**< Var for time control */ - uint32_t tv_usec1; /**< Var for time control */ - uint32_t current_count; /**< Var for count control */ - int track; /**< Track type: by_src, by_src */ - - struct DetectThresholdEntry_ *next; -} DetectThresholdEntry; - - -/** - * Registration function for threshold: keyword - */ - -void DetectThresholdRegister(void); - -/** - * This function registers unit tests for Threshold - */ - -void ThresholdRegisterTests(void); - -#endif /*__DETECT_THRESHOLD_H__ */ diff --git a/framework/src/suricata/src/detect-tls-version.c b/framework/src/suricata/src/detect-tls-version.c deleted file mode 100644 index 51547260..00000000 --- a/framework/src/suricata/src/detect-tls-version.c +++ /dev/null @@ -1,722 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the tls.version keyword - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-ssl.h" -#include "detect-tls-version.h" - -#include "stream-tcp.h" - -/** - * \brief Regex for parsing "id" option, matching number or "number" - */ -#define PARSE_REGEX "^\\s*([A-z0-9\\.]+|\"[A-z0-9\\.]+\")\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectTlsVersionMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, void *, Signature *, SigMatch *); -static int DetectTlsVersionSetup (DetectEngineCtx *, Signature *, char *); -void DetectTlsVersionRegisterTests(void); -void DetectTlsVersionFree(void *); - -/** - * \brief Registration function for keyword: tls.version - */ -void DetectTlsVersionRegister (void) -{ - sigmatch_table[DETECT_AL_TLS_VERSION].name = "tls.version"; - sigmatch_table[DETECT_AL_TLS_VERSION].desc = "match on TLS/SSL version"; - sigmatch_table[DETECT_AL_TLS_VERSION].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/TLS-keywords#tlsversion"; - sigmatch_table[DETECT_AL_TLS_VERSION].Match = NULL; - sigmatch_table[DETECT_AL_TLS_VERSION].AppLayerMatch = DetectTlsVersionMatch; - sigmatch_table[DETECT_AL_TLS_VERSION].alproto = ALPROTO_TLS; - sigmatch_table[DETECT_AL_TLS_VERSION].Setup = DetectTlsVersionSetup; - sigmatch_table[DETECT_AL_TLS_VERSION].Free = DetectTlsVersionFree; - sigmatch_table[DETECT_AL_TLS_VERSION].RegisterTests = DetectTlsVersionRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - SCLogDebug("registering tls.version rule option"); - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - return; -} - -/** - * \brief match the specified version on a tls session - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectTlsVersionData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectTlsVersionMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - - DetectTlsVersionData *tls_data = (DetectTlsVersionData *)m->ctx; - SSLState *ssl_state = (SSLState *)state; - if (ssl_state == NULL) { - SCLogDebug("no tls state, no match"); - SCReturnInt(0); - } - - int ret = 0; - SCLogDebug("looking for tls_data->ver 0x%02X (flags 0x%02X)", tls_data->ver, flags); - - if (flags & STREAM_TOCLIENT) { - SCLogDebug("server (toclient) version is 0x%02X", ssl_state->server_connp.version); - if (tls_data->ver == ssl_state->server_connp.version) - ret = 1; - } else if (flags & STREAM_TOSERVER) { - SCLogDebug("client (toserver) version is 0x%02X", ssl_state->client_connp.version); - if (tls_data->ver == ssl_state->client_connp.version) - ret = 1; - } - - SCReturnInt(ret); -} - -/** - * \brief This function is used to parse IPV4 ip_id passed via keyword: "id" - * - * \param idstr Pointer to the user provided id option - * - * \retval id_d pointer to DetectTlsVersionData on success - * \retval NULL on failure - */ -DetectTlsVersionData *DetectTlsVersionParse (char *str) -{ - uint16_t temp; - DetectTlsVersionData *tls = NULL; - #define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0, - ov, MAX_SUBSTRINGS); - - if (ret < 1 || ret > 3) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid tls.version option"); - goto error; - } - - if (ret > 1) { - const char *str_ptr; - char *orig; - char *tmp_str; - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct id option */ - tls = SCMalloc(sizeof(DetectTlsVersionData)); - if (unlikely(tls == NULL)) - goto error; - - orig = SCStrdup((char*)str_ptr); - if (unlikely(orig == NULL)) { - goto error; - } - tmp_str=orig; - - /* Let's see if we need to scape "'s */ - if (tmp_str[0] == '"') - { - tmp_str[strlen(tmp_str) - 1] = '\0'; - tmp_str += 1; - } - - if (strcmp("1.0", tmp_str) == 0) { - temp = TLS_VERSION_10; - } else if (strcmp("1.1", tmp_str) == 0) { - temp = TLS_VERSION_11; - } else if (strcmp("1.2", tmp_str) == 0) { - temp = TLS_VERSION_12; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "Invalid value"); - goto error; - } - - tls->ver = temp; - - SCFree(orig); - - SCLogDebug("will look for tls %"PRIu8"", tls->ver); - } - - return tls; - -error: - if (tls != NULL) - DetectTlsVersionFree(tls); - return NULL; - -} - -/** - * \brief this function is used to add the parsed "id" option - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param idstr pointer to the user provided "id" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectTlsVersionSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectTlsVersionData *tls = NULL; - SigMatch *sm = NULL; - - tls = DetectTlsVersionParse(str); - if (tls == NULL) goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_AL_TLS_VERSION; - sm->ctx = (void *)tls; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - s->alproto = ALPROTO_TLS; - return 0; - -error: - if (tls != NULL) DetectTlsVersionFree(tls); - if (sm != NULL) SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectTlsVersionData - * - * \param id_d pointer to DetectTlsVersionData - */ -void DetectTlsVersionFree(void *ptr) -{ - DetectTlsVersionData *id_d = (DetectTlsVersionData *)ptr; - SCFree(id_d); -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectTlsVersionTestParse01 is a test to make sure that we parse the "id" - * option correctly when given valid id option - */ -int DetectTlsVersionTestParse01 (void) -{ - DetectTlsVersionData *tls = NULL; - tls = DetectTlsVersionParse("1.0"); - if (tls != NULL && tls->ver == TLS_VERSION_10) { - DetectTlsVersionFree(tls); - return 1; - } - - return 0; -} - -/** - * \test DetectTlsVersionTestParse02 is a test to make sure that we parse the "id" - * option correctly when given an invalid id option - * it should return id_d = NULL - */ -int DetectTlsVersionTestParse02 (void) -{ - DetectTlsVersionData *tls = NULL; - tls = DetectTlsVersionParse("2.5"); - if (tls == NULL) { - DetectTlsVersionFree(tls); - return 1; - } - - return 0; -} - -#include "stream-tcp-reassemble.h" - -/** \test Send a get request in three chunks + more data. */ -static int DetectTlsVersionTestDetect01(void) -{ - int result = 0; - Flow f; - uint8_t tlsbuf1[] = { 0x16 }; - uint32_t tlslen1 = sizeof(tlsbuf1); - uint8_t tlsbuf2[] = { 0x03 }; - uint32_t tlslen2 = sizeof(tlsbuf2); - uint8_t tlsbuf3[] = { 0x01 }; - uint32_t tlslen3 = sizeof(tlsbuf3); - uint8_t tlsbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x01 }; - uint32_t tlslen4 = sizeof(tlsbuf4); - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_TLS; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tls any any -> any any (msg:\"TLS\"; tls.version:1.0; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - 0x16, ssl_state->client_connp.content_type); - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.version); - goto end; - } - - SCLogDebug("ssl_state is at %p, ssl_state->server_version 0x%02X " - "ssl_state->client_version 0x%02X", - ssl_state, ssl_state->server_connp.version, - ssl_state->client_connp.version); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -static int DetectTlsVersionTestDetect02(void) -{ - int result = 0; - Flow f; - uint8_t tlsbuf1[] = { 0x16 }; - uint32_t tlslen1 = sizeof(tlsbuf1); - uint8_t tlsbuf2[] = { 0x03 }; - uint32_t tlslen2 = sizeof(tlsbuf2); - uint8_t tlsbuf3[] = { 0x01 }; - uint32_t tlslen3 = sizeof(tlsbuf3); - uint8_t tlsbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x02 }; - uint32_t tlslen4 = sizeof(tlsbuf4); - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_TLS; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tls any any -> any any (msg:\"TLS\"; tls.version:1.0; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - 0x16, ssl_state->client_connp.content_type); - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.version); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("signature 1 didn't match while it should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -static int DetectTlsVersionTestDetect03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Flow f; - uint8_t tlsbuf1[] = { 0x16 }; - uint32_t tlslen1 = sizeof(tlsbuf1); - uint8_t tlsbuf2[] = { 0x03 }; - uint32_t tlslen2 = sizeof(tlsbuf2); - uint8_t tlsbuf3[] = { 0x01 }; - uint32_t tlslen3 = sizeof(tlsbuf3); - uint8_t tlsbuf4[] = { 0x01, 0x00, 0x00, 0xad, 0x03, 0x02 }; - uint32_t tlslen4 = sizeof(tlsbuf4); - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p->tcph->th_seq = htonl(1000); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_TLS; - f.proto = p->proto; - - StreamTcpInitConfig(TRUE); - - StreamMsg *stream_msg = StreamMsgGetFromPool(); - if (stream_msg == NULL) { - printf("no stream_msg: "); - goto end; - } - - memcpy(stream_msg->data, tlsbuf4, tlslen4); - stream_msg->data_len = tlslen4; - - ssn.toserver_smsg_head = stream_msg; - ssn.toserver_smsg_tail = stream_msg; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"TLS\"; tls.version:1.0; content:\"|01 00 00 AD|\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf1, tlslen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf2, tlslen2); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf3, tlslen3); - if (r != 0) { - printf("toserver chunk 3 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_TLS, STREAM_TOSERVER, tlsbuf4, tlslen4); - if (r != 0) { - printf("toserver chunk 4 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SSLState *ssl_state = f.alstate; - if (ssl_state == NULL) { - printf("no tls state: "); - goto end; - } - - if (ssl_state->client_connp.content_type != 0x16) { - printf("expected content_type %" PRIu8 ", got %" PRIu8 ": ", - 0x16, ssl_state->client_connp.content_type); - goto end; - } - - if (ssl_state->client_connp.version != TLS_VERSION_10) { - printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", - TLS_VERSION_10, ssl_state->client_connp.version); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("signature 1 didn't match while it should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectTlsVersion - */ -void DetectTlsVersionRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectTlsVersionTestParse01", DetectTlsVersionTestParse01, 1); - UtRegisterTest("DetectTlsVersionTestParse02", DetectTlsVersionTestParse02, 1); - UtRegisterTest("DetectTlsVersionTestDetect01", DetectTlsVersionTestDetect01, 1); - UtRegisterTest("DetectTlsVersionTestDetect02", DetectTlsVersionTestDetect02, 1); - UtRegisterTest("DetectTlsVersionTestDetect03", DetectTlsVersionTestDetect03, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect-tls-version.h b/framework/src/suricata/src/detect-tls-version.h deleted file mode 100644 index c4dd1692..00000000 --- a/framework/src/suricata/src/detect-tls-version.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_TLS_VERSION_H__ -#define __DETECT_TLS_VERSION_H__ - -typedef struct DetectTlsVersionData_ { - uint16_t ver; /** tls version to match */ -} DetectTlsVersionData; - -/* prototypes */ -void DetectTlsVersionRegister (void); - -#endif /* __DETECT_TLS_VERSION_H__ */ - diff --git a/framework/src/suricata/src/detect-tls.c b/framework/src/suricata/src/detect-tls.c deleted file mode 100644 index 9b1d237b..00000000 --- a/framework/src/suricata/src/detect-tls.c +++ /dev/null @@ -1,853 +0,0 @@ -/* - * Copyright (C) 2011-2012 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - * Implements the tls.* keywords - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "app-layer.h" - -#include "app-layer-ssl.h" -#include "detect-tls.h" - -#include "stream-tcp.h" - -/** - * \brief Regex for parsing "id" option, matching number or "number" - */ - -#define PARSE_REGEX "^\\s*(\\!*)\\s*([A-z0-9\\s\\-\\.=,\\*@]+|\"[A-z0-9\\s\\-\\.=,\\*@]+\")\\s*$" -#define PARSE_REGEX_FINGERPRINT "^\\s*(\\!*)\\s*([A-z0-9\\:\\*]+|\"[A-z0-9\\:\\* ]+\")\\s*$" - -static pcre *subject_parse_regex; -static pcre_extra *subject_parse_regex_study; -static pcre *issuerdn_parse_regex; -static pcre_extra *issuerdn_parse_regex_study; -static pcre *fingerprint_parse_regex; -static pcre_extra *fingerprint_parse_regex_study; - -static int DetectTlsSubjectMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, void *, Signature *, SigMatch *); -static int DetectTlsSubjectSetup (DetectEngineCtx *, Signature *, char *); -static void DetectTlsSubjectRegisterTests(void); -static void DetectTlsSubjectFree(void *); -static int DetectTlsIssuerDNMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, void *, Signature *, SigMatch *); -static int DetectTlsIssuerDNSetup (DetectEngineCtx *, Signature *, char *); -static void DetectTlsIssuerDNRegisterTests(void); -static void DetectTlsIssuerDNFree(void *); -static int DetectTlsFingerprintMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, void *, Signature *, SigMatch *); -static int DetectTlsFingerprintSetup (DetectEngineCtx *, Signature *, char *); -static void DetectTlsFingerprintFree(void *); -static int DetectTlsStoreSetup (DetectEngineCtx *, Signature *, char *); -static int DetectTlsStoreMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t, void *, Signature *, SigMatch *); - -/** - * \brief Registration function for keyword: tls.version - */ -void DetectTlsRegister (void) -{ - sigmatch_table[DETECT_AL_TLS_SUBJECT].name = "tls.subject"; - sigmatch_table[DETECT_AL_TLS_SUBJECT].desc = "match TLS/SSL certificate Subject field"; - sigmatch_table[DETECT_AL_TLS_SUBJECT].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/TLS-keywords#tlssubject"; - sigmatch_table[DETECT_AL_TLS_SUBJECT].Match = NULL; - sigmatch_table[DETECT_AL_TLS_SUBJECT].AppLayerMatch = DetectTlsSubjectMatch; - sigmatch_table[DETECT_AL_TLS_SUBJECT].alproto = ALPROTO_TLS; - sigmatch_table[DETECT_AL_TLS_SUBJECT].Setup = DetectTlsSubjectSetup; - sigmatch_table[DETECT_AL_TLS_SUBJECT].Free = DetectTlsSubjectFree; - sigmatch_table[DETECT_AL_TLS_SUBJECT].RegisterTests = DetectTlsSubjectRegisterTests; - - sigmatch_table[DETECT_AL_TLS_ISSUERDN].name = "tls.issuerdn"; - sigmatch_table[DETECT_AL_TLS_ISSUERDN].desc = "match TLS/SSL certificate IssuerDN field"; - sigmatch_table[DETECT_AL_TLS_ISSUERDN].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/TLS-keywords#tlsissuerdn"; - sigmatch_table[DETECT_AL_TLS_ISSUERDN].Match = NULL; - sigmatch_table[DETECT_AL_TLS_ISSUERDN].AppLayerMatch = DetectTlsIssuerDNMatch; - sigmatch_table[DETECT_AL_TLS_ISSUERDN].alproto = ALPROTO_TLS; - sigmatch_table[DETECT_AL_TLS_ISSUERDN].Setup = DetectTlsIssuerDNSetup; - sigmatch_table[DETECT_AL_TLS_ISSUERDN].Free = DetectTlsIssuerDNFree; - sigmatch_table[DETECT_AL_TLS_ISSUERDN].RegisterTests = DetectTlsIssuerDNRegisterTests; - - sigmatch_table[DETECT_AL_TLS_FINGERPRINT].name = "tls.fingerprint"; - sigmatch_table[DETECT_AL_TLS_FINGERPRINT].desc = "match TLS/SSL certificate SHA1 fingerprint"; - sigmatch_table[DETECT_AL_TLS_FINGERPRINT].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/TLS-keywords#tlsfingerprint"; - sigmatch_table[DETECT_AL_TLS_FINGERPRINT].Match = NULL; - sigmatch_table[DETECT_AL_TLS_FINGERPRINT].AppLayerMatch = DetectTlsFingerprintMatch; - sigmatch_table[DETECT_AL_TLS_FINGERPRINT].alproto = ALPROTO_TLS; - sigmatch_table[DETECT_AL_TLS_FINGERPRINT].Setup = DetectTlsFingerprintSetup; - sigmatch_table[DETECT_AL_TLS_FINGERPRINT].Free = DetectTlsFingerprintFree; - sigmatch_table[DETECT_AL_TLS_FINGERPRINT].RegisterTests = NULL; - - sigmatch_table[DETECT_AL_TLS_STORE].name = "tls.store"; - sigmatch_table[DETECT_AL_TLS_STORE].desc = "store TLS/SSL certificate on disk"; - sigmatch_table[DETECT_AL_TLS_STORE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/TLS-keywords#tlsstore"; - sigmatch_table[DETECT_AL_TLS_STORE].Match = NULL; - sigmatch_table[DETECT_AL_TLS_STORE].AppLayerMatch = DetectTlsStoreMatch; - sigmatch_table[DETECT_AL_TLS_STORE].alproto = ALPROTO_TLS; - sigmatch_table[DETECT_AL_TLS_STORE].Setup = DetectTlsStoreSetup; - sigmatch_table[DETECT_AL_TLS_STORE].Free = NULL; - sigmatch_table[DETECT_AL_TLS_STORE].RegisterTests = NULL; - sigmatch_table[DETECT_AL_TLS_STORE].flags |= SIGMATCH_NOOPT; - - const char *eb; - int eo; - int opts = 0; - - SCLogDebug("registering tls.subject rule option"); - - subject_parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (subject_parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - subject_parse_regex_study = pcre_study(subject_parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - SCLogDebug("registering tls.issuerdn rule option"); - - issuerdn_parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (issuerdn_parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - issuerdn_parse_regex_study = pcre_study(issuerdn_parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - SCLogDebug("registering tls.fingerprint rule option"); - - fingerprint_parse_regex = pcre_compile(PARSE_REGEX_FINGERPRINT, opts, &eb, &eo, NULL); - if (fingerprint_parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX_FINGERPRINT, eo, eb); - goto error; - } - - fingerprint_parse_regex_study = pcre_study(fingerprint_parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - return; -} - -/** - * \brief match the specified Subject on a tls session - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectTlsData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectTlsSubjectMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - - DetectTlsData *tls_data = (DetectTlsData *)m->ctx; - SSLState *ssl_state = (SSLState *)state; - if (ssl_state == NULL) { - SCLogDebug("no tls state, no match"); - SCReturnInt(0); - } - - int ret = 0; - - SSLStateConnp *connp = NULL; - if (flags & STREAM_TOSERVER) { - connp = &ssl_state->client_connp; - } else { - connp = &ssl_state->server_connp; - } - - if (connp->cert0_subject != NULL) { - SCLogDebug("TLS: Subject is [%s], looking for [%s]\n", - connp->cert0_subject, tls_data->subject); - - if (strstr(connp->cert0_subject, tls_data->subject) != NULL) { - if (tls_data->flags & DETECT_CONTENT_NEGATED) { - ret = 0; - } else { - ret = 1; - } - } else { - if (tls_data->flags & DETECT_CONTENT_NEGATED) { - ret = 1; - } else { - ret = 0; - } - } - } else { - ret = 0; - } - - SCReturnInt(ret); -} - -/** - * \brief This function is used to parse IPV4 ip_id passed via keyword: "id" - * - * \param idstr Pointer to the user provided id option - * - * \retval id_d pointer to DetectTlsData on success - * \retval NULL on failure - */ -static DetectTlsData *DetectTlsSubjectParse (char *str) -{ - DetectTlsData *tls = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *str_ptr; - char *orig = NULL; - char *tmp_str; - uint32_t flag = 0; - - ret = pcre_exec(subject_parse_regex, subject_parse_regex_study, str, strlen(str), 0, 0, - ov, MAX_SUBSTRINGS); - - if (ret != 3) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid tls.subject option"); - goto error; - } - - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - if (str_ptr[0] == '!') - flag = DETECT_CONTENT_NEGATED; - - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct id option */ - tls = SCMalloc(sizeof(DetectTlsData)); - if (unlikely(tls == NULL)) - goto error; - tls->subject = NULL; - tls->flags = flag; - - orig = SCStrdup((char*)str_ptr); - if (unlikely(orig == NULL)) { - goto error; - } - tmp_str=orig; - - /* Let's see if we need to escape "'s */ - if (tmp_str[0] == '"') { - tmp_str[strlen(tmp_str) - 1] = '\0'; - tmp_str += 1; - } - - tls->subject = SCStrdup(tmp_str); - if (unlikely(tls->subject == NULL)) { - goto error; - } - - SCFree(orig); - - SCLogDebug("will look for TLS subject %s", tls->subject); - - return tls; - -error: - if (orig != NULL) - SCFree(orig); - if (tls != NULL) - DetectTlsSubjectFree(tls); - return NULL; - -} - -/** - * \brief this function is used to add the parsed "id" option - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param idstr pointer to the user provided "id" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectTlsSubjectSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectTlsData *tls = NULL; - SigMatch *sm = NULL; - - tls = DetectTlsSubjectParse(str); - if (tls == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - sm->type = DETECT_AL_TLS_SUBJECT; - sm->ctx = (void *)tls; - - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_TLS; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - return 0; - -error: - if (tls != NULL) - DetectTlsSubjectFree(tls); - if (sm != NULL) - SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectTlsData - * - * \param id_d pointer to DetectTlsData - */ -static void DetectTlsSubjectFree(void *ptr) -{ - DetectTlsData *id_d = (DetectTlsData *)ptr; - if (ptr == NULL) - return; - if (id_d->subject != NULL) - SCFree(id_d->subject); - SCFree(id_d); -} - -/** - * \brief this function registers unit tests for DetectTlsSubject - */ -static void DetectTlsSubjectRegisterTests(void) -{ -} - -/** - * \brief match the specified IssuerDN on a tls session - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectTlsData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectTlsIssuerDNMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - - DetectTlsData *tls_data = (DetectTlsData *)m->ctx; - SSLState *ssl_state = (SSLState *)state; - if (ssl_state == NULL) { - SCLogDebug("no tls state, no match"); - SCReturnInt(0); - } - - int ret = 0; - - SSLStateConnp *connp = NULL; - if (flags & STREAM_TOSERVER) { - connp = &ssl_state->client_connp; - } else { - connp = &ssl_state->server_connp; - } - - if (connp->cert0_issuerdn != NULL) { - SCLogDebug("TLS: IssuerDN is [%s], looking for [%s]\n", - connp->cert0_issuerdn, tls_data->issuerdn); - - if (strstr(connp->cert0_issuerdn, tls_data->issuerdn) != NULL) { - if (tls_data->flags & DETECT_CONTENT_NEGATED) { - ret = 0; - } else { - ret = 1; - } - } else { - if (tls_data->flags & DETECT_CONTENT_NEGATED) { - ret = 1; - } else { - ret = 0; - } - } - } else { - ret = 0; - } - - SCReturnInt(ret); -} - -/** - * \brief This function is used to parse IPV4 ip_id passed via keyword: "id" - * - * \param idstr Pointer to the user provided id option - * - * \retval id_d pointer to DetectTlsData on success - * \retval NULL on failure - */ -static DetectTlsData *DetectTlsIssuerDNParse(char *str) -{ - DetectTlsData *tls = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *str_ptr; - char *orig = NULL; - char *tmp_str; - uint32_t flag = 0; - - ret = pcre_exec(issuerdn_parse_regex, issuerdn_parse_regex_study, str, strlen(str), 0, 0, - ov, MAX_SUBSTRINGS); - - if (ret != 3) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid tls.issuerdn option"); - goto error; - } - - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - if (str_ptr[0] == '!') - flag = DETECT_CONTENT_NEGATED; - - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct id option */ - tls = SCMalloc(sizeof(DetectTlsData)); - if (unlikely(tls == NULL)) - goto error; - tls->issuerdn = NULL; - tls->flags = flag; - - orig = SCStrdup((char*)str_ptr); - if (unlikely(orig == NULL)) { - goto error; - } - tmp_str=orig; - - /* Let's see if we need to escape "'s */ - if (tmp_str[0] == '"') - { - tmp_str[strlen(tmp_str) - 1] = '\0'; - tmp_str += 1; - } - - tls->issuerdn = SCStrdup(tmp_str); - if (unlikely(tls->issuerdn == NULL)) { - goto error; - } - - SCFree(orig); - - SCLogDebug("Will look for TLS issuerdn %s", tls->issuerdn); - - return tls; - -error: - if (orig != NULL) - SCFree(orig); - if (tls != NULL) - DetectTlsIssuerDNFree(tls); - return NULL; - -} - -/** - * \brief this function is used to add the parsed "id" option - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param idstr pointer to the user provided "id" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectTlsIssuerDNSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectTlsData *tls = NULL; - SigMatch *sm = NULL; - - tls = DetectTlsIssuerDNParse(str); - if (tls == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - sm->type = DETECT_AL_TLS_ISSUERDN; - sm->ctx = (void *)tls; - - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_TLS; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - return 0; - -error: - if (tls != NULL) - DetectTlsIssuerDNFree(tls); - if (sm != NULL) - SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectTlsData - * - * \param id_d pointer to DetectTlsData - */ -static void DetectTlsIssuerDNFree(void *ptr) -{ - DetectTlsData *id_d = (DetectTlsData *)ptr; - SCFree(id_d->issuerdn); - SCFree(id_d); -} - -/** - * \brief This function is used to parse fingerprint passed via keyword: "fingerprint" - * - * \param idstr Pointer to the user provided fingerprint option - * - * \retval pointer to DetectTlsData on success - * \retval NULL on failure - */ -static DetectTlsData *DetectTlsFingerprintParse (char *str) -{ - DetectTlsData *tls = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - const char *str_ptr; - char *orig; - char *tmp_str; - uint32_t flag = 0; - - ret = pcre_exec(fingerprint_parse_regex, fingerprint_parse_regex_study, str, strlen(str), 0, 0, - ov, MAX_SUBSTRINGS); - - if (ret != 3) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid tls.fingerprint option"); - goto error; - } - - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - if (str_ptr[0] == '!') - flag = DETECT_CONTENT_NEGATED; - - res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct id option */ - tls = SCMalloc(sizeof(DetectTlsData)); - if (unlikely(tls == NULL)) - goto error; - tls->fingerprint = NULL; - tls->flags = flag; - - orig = SCStrdup((char*)str_ptr); - if (unlikely(orig == NULL)) { - goto error; - } - tmp_str=orig; - - /* Let's see if we need to escape "'s */ - if (tmp_str[0] == '"') - { - tmp_str[strlen(tmp_str) - 1] = '\0'; - tmp_str += 1; - } - - tls->fingerprint = SCStrdup(tmp_str); - if (tls->fingerprint == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate fingerprint"); - } - - SCFree(orig); - - SCLogDebug("will look for TLS fingerprint %s", tls->fingerprint); - - return tls; - -error: - if (tls != NULL) - DetectTlsFingerprintFree(tls); - return NULL; - -} -/** - * \brief match the specified fingerprint on a tls session - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectTlsData - * - * \retval 0 no match - * \retval 1 match - */ -static int DetectTlsFingerprintMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - DetectTlsData *tls_data = (DetectTlsData *)m->ctx; - SSLState *ssl_state = (SSLState *)state; - if (ssl_state == NULL) { - SCLogDebug("no tls state, no match"); - SCReturnInt(0); - } - - int ret = 0; - - if (ssl_state->server_connp.cert0_fingerprint != NULL) { - SCLogDebug("TLS: Fingerprint is [%s], looking for [%s]\n", - ssl_state->server_connp.cert0_fingerprint, - tls_data->fingerprint); - - if (tls_data->fingerprint && - (strstr(ssl_state->server_connp.cert0_fingerprint, - tls_data->fingerprint) != NULL)) { - if (tls_data->flags & DETECT_CONTENT_NEGATED) { - ret = 0; - } else { - ret = 1; - - } - } else { - if (tls_data->flags & DETECT_CONTENT_NEGATED) { - ret = 1; - } else { - ret = 0; - } - } - } else { - ret = 0; - } - - SCReturnInt(ret); -} - -/** - * \brief this function is used to add the parsed "fingerprint" option - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param id pointer to the user provided "fingerprint" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectTlsFingerprintSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - DetectTlsData *tls = NULL; - SigMatch *sm = NULL; - - tls = DetectTlsFingerprintParse(str); - if (tls == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - sm->type = DETECT_AL_TLS_FINGERPRINT; - sm->ctx = (void *)tls; - - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_TLS; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - return 0; - -error: - if (tls != NULL) - DetectTlsFingerprintFree(tls); - if (sm != NULL) - SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectTlsData - * - * \param pointer to DetectTlsData - */ -static void DetectTlsFingerprintFree(void *ptr) -{ - DetectTlsData *id_d = (DetectTlsData *)ptr; - if (id_d->fingerprint) - SCFree(id_d->fingerprint); - SCFree(id_d); -} - -/** - * \brief this function is used to add the parsed "store" option - * \brief into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param idstr pointer to the user provided "store" option - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectTlsStoreSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - SigMatch *sm = NULL; - - s->flags |= SIG_FLAG_TLSSTORE; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - sm->type = DETECT_AL_TLS_STORE; - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_TLS; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); - - return 0; - -error: - if (sm != NULL) - SCFree(sm); - return -1; - -} - -/** \warning modifies state */ -static int DetectTlsStoreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m) -{ - SCEnter(); - - SSLState *ssl_state = (SSLState *)state; - if (ssl_state == NULL) { - SCLogDebug("no tls state, no match"); - SCReturnInt(1); - } - - if (s->flags & SIG_FLAG_TLSSTORE) { - ssl_state->server_connp.cert_log_flag |= SSL_TLS_LOG_PEM; - } - - SCReturnInt(1); -} - - -/** - * \brief this function registers unit tests for DetectTlsIssuerDN - */ -static void DetectTlsIssuerDNRegisterTests(void) -{ -} diff --git a/framework/src/suricata/src/detect-tls.h b/framework/src/suricata/src/detect-tls.h deleted file mode 100644 index 71652eb9..00000000 --- a/framework/src/suricata/src/detect-tls.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2011-2012 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author Pierre Chifflier - */ - -#ifndef __DETECT_TLS_H__ -#define __DETECT_TLS_H__ - -typedef struct DetectTlsData_ { - uint16_t ver; /** tls version to match */ - uint32_t flags; /** flags containing match variant (Negation for example) */ - char * subject; /** tls certificate subject substring to match */ - char * issuerdn; /** tls certificate issuerDN substring to match */ - char * fingerprint; /** tls fingerprint substring to match */ -} DetectTlsData; - -/* prototypes */ -void DetectTlsRegister (void); - -#endif /* __DETECT_TLS_H__ */ diff --git a/framework/src/suricata/src/detect-tos.c b/framework/src/suricata/src/detect-tos.c deleted file mode 100644 index 40928261..00000000 --- a/framework/src/suricata/src/detect-tos.c +++ /dev/null @@ -1,430 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "threads.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" -#include "detect-tos.h" - -#include "app-layer-protos.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-byte.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#define PARSE_REGEX "^\\s*(!?\\s*[0-9]{1,3}|!?\\s*[xX][0-9a-fA-F]{1,2})\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -static int DetectTosSetup(DetectEngineCtx *, Signature *, char *); -static int DetectTosMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, - Signature *, const SigMatchCtx *); -static void DetectTosRegisterTests(void); -static void DetectTosFree(void *); - -#define DETECT_IPTOS_MIN 0 -#define DETECT_IPTOS_MAX 255 - -/** - * \brief Register Tos keyword. - */ -void DetectTosRegister(void) -{ - sigmatch_table[DETECT_TOS].name = "tos"; - sigmatch_table[DETECT_TOS].Match = DetectTosMatch; - sigmatch_table[DETECT_TOS].Setup = DetectTosSetup; - sigmatch_table[DETECT_TOS].Free = DetectTosFree; - sigmatch_table[DETECT_TOS].RegisterTests = DetectTosRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at " - "offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - return; -} - -/** - * \brief Match function for tos keyword. - * - * \param tv ThreadVars instance. - * \param det_ctx Pointer to the detection thread ctx. - * \param p Pointer to the packet. - * \param m Pointer to the SigMatch containing the tos data. - * - * \retval 0 no match - * \retval 1 match - */ -int DetectTosMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p, - Signature *s, const SigMatchCtx *ctx) -{ - const DetectTosData *tosd = (const DetectTosData *)ctx; - int result = 0; - - if (!PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p)) { - return 0; - } - - if (tosd->tos == IPV4_GET_IPTOS(p)) { - SCLogDebug("tos match found for %d\n", tosd->tos); - result = 1; - } - - return (tosd->negated ^ result); -} - -DetectTosData *DetectTosParse(char *arg) -{ - DetectTosData *tosd = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, arg, strlen(arg), 0, 0, - ov, MAX_SUBSTRINGS); - - if (ret != 2) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid tos option - %s. " - "The tos option value must be in the range " - "%u - %u", arg, DETECT_IPTOS_MIN, DETECT_IPTOS_MAX); - goto error; - } - - const char *str_ptr; - res = pcre_get_substring((char *)arg, ov, MAX_SUBSTRINGS, 1, - &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - int64_t tos = 0; - int negated = 0; - - if (*str_ptr == '!') { - str_ptr++; - negated = 1; - } - - while (isspace((unsigned char)*str_ptr)) - str_ptr++; - - if (*str_ptr == 'x' || *str_ptr == 'X') { - int r = ByteExtractStringSigned(&tos, 16, 0, str_ptr + 1); - if (r < 0) { - goto error; - } - } else { - int r = ByteExtractStringSigned(&tos, 10, 0, str_ptr); - if (r < 0) { - goto error; - } - } - if (!(tos >= DETECT_IPTOS_MIN && tos <= DETECT_IPTOS_MAX)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid tos argument - " - "%s. The tos option value must be in the range " - "%u - %u", str_ptr, DETECT_IPTOS_MIN, DETECT_IPTOS_MAX); - goto error; - } - - tosd = SCMalloc(sizeof(DetectTosData)); - if (unlikely(tosd == NULL)) - goto error; - tosd->tos = (uint8_t)tos; - tosd->negated = negated; - - return tosd; - -error: - if (tosd != NULL) - DetectTosFree(tosd); - return NULL; -} - -/** - * \brief Setup function for tos argument. Parse the argument and - * add it into the sig. - * - * \param de_ctx Detection Engine Context instance. - * \param s Pointer to the signature. - * \param arg Argument to be parsed. - * - * \retval 0 on Success. - * \retval -1 on Failure. - */ -int DetectTosSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg) -{ - DetectTosData *tosd; - SigMatch *sm; - - tosd = DetectTosParse(arg); - if (tosd == NULL) - goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_TOS; - sm->ctx = (SigMatchCtx *)tosd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - return -1; -} - -/** - * \brief Free data allocated by the tos keyword. - * - * \param tosd Data to be freed. - */ -void DetectTosFree(void *tosd) -{ - SCFree(tosd); -} - -/********************************Unittests***********************************/ - -#ifdef UNITTESTS - -int DetectTosTest01(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse("12"); - if (tosd != NULL && tosd->tos == 12 && !tosd->negated) { - DetectTosFree(tosd); - return 1; - } - - return 0; -} - -int DetectTosTest02(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse("123"); - if (tosd != NULL && tosd->tos == 123 && !tosd->negated) { - DetectTosFree(tosd); - return 1; - } - - return 0; -} - -int DetectTosTest03(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse(" 12 "); - if (tosd != NULL && tosd->tos == 12 && !tosd->negated) { - DetectTosFree(tosd); - return 1; - } - - return 0; -} - -int DetectTosTest04(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse("256"); - if (tosd != NULL) { - DetectTosFree(tosd); - return 0; - } - - return 1; -} - -int DetectTosTest05(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse("boom"); - if (tosd != NULL) { - DetectTosFree(tosd); - return 0; - } - - return 1; -} - -int DetectTosTest06(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse("x12"); - if (tosd != NULL && tosd->tos == 0x12 && !tosd->negated) { - DetectTosFree(tosd); - return 1; - } - - return 0; -} - -int DetectTosTest07(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse("X12"); - if (tosd != NULL && tosd->tos == 0x12 && !tosd->negated) { - DetectTosFree(tosd); - return 1; - } - - return 0; -} - -int DetectTosTest08(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse("x121"); - if (tosd != NULL) { - DetectTosFree(tosd); - return 0; - } - - return 1; -} - -int DetectTosTest09(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse("!12"); - if (tosd != NULL && tosd->tos == 12 && tosd->negated) { - DetectTosFree(tosd); - return 1; - } - - return 0; -} - -int DetectTosTest10(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse("!x12"); - if (tosd != NULL && tosd->tos == 0x12 && tosd->negated) { - DetectTosFree(tosd); - return 1; - } - - return 0; -} - -int DetectTosTest11(void) -{ - DetectTosData *tosd = NULL; - tosd = DetectTosParse(" ! 12"); - if (tosd != NULL && tosd->tos == 12 && tosd->negated) { - DetectTosFree(tosd); - return 1; - } - - return 0; -} - -int DetectTosTest12(void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - IPV4_SET_RAW_IPTOS(p->ip4h, 10); - - char *sigs[4]; - sigs[0]= "alert ip any any -> any any (msg:\"Testing id 1\"; tos:10; sid:1;)"; - sigs[1]= "alert ip any any -> any any (msg:\"Testing id 2\"; tos:!10; sid:2;)"; - sigs[2]= "alert ip any any -> any any (msg:\"Testing id 3\"; tos:20; sid:3;)"; - sigs[3]= "alert ip any any -> any any (msg:\"Testing id 3\"; tos:!20; sid:4;)"; - - uint32_t sid[4] = {1, 2, 3, 4}; - - uint32_t results[1][4] = - { - {1, 0, 0, 1}, - }; - - result = UTHGenericTest(&p, 1, sigs, sid, (uint32_t *) results, 4); - - UTHFreePackets(&p, 1); - -end: - return result; -} - -#endif - -void DetectTosRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectTosTest01", DetectTosTest01, 1); - UtRegisterTest("DetectTosTest02", DetectTosTest02, 1); - UtRegisterTest("DetectTosTest03", DetectTosTest03, 1); - UtRegisterTest("DetectTosTest04", DetectTosTest04, 1); - UtRegisterTest("DetectTosTest05", DetectTosTest05, 1); - UtRegisterTest("DetectTosTest06", DetectTosTest06, 1); - UtRegisterTest("DetectTosTest07", DetectTosTest07, 1); - UtRegisterTest("DetectTosTest08", DetectTosTest08, 1); - UtRegisterTest("DetectTosTest09", DetectTosTest09, 1); - UtRegisterTest("DetectTosTest10", DetectTosTest10, 1); - UtRegisterTest("DetectTosTest11", DetectTosTest11, 1); - UtRegisterTest("DetectTosTest12", DetectTosTest12, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/detect-tos.h b/framework/src/suricata/src/detect-tos.h deleted file mode 100644 index ef6fea69..00000000 --- a/framework/src/suricata/src/detect-tos.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_TOS_H__ -#define __DETECT_TOS_H__ - -typedef struct DetectTosData_ { - uint8_t negated; - uint8_t tos; -} DetectTosData; - -void DetectTosRegister(void); - -#endif /* __DETECT_TOS_H__ */ diff --git a/framework/src/suricata/src/detect-ttl.c b/framework/src/suricata/src/detect-ttl.c deleted file mode 100644 index 80f39667..00000000 --- a/framework/src/suricata/src/detect-ttl.c +++ /dev/null @@ -1,638 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - * Implements the ttl keyword - */ - -#include "suricata-common.h" -#include "stream-tcp.h" -#include "util-unittest.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-ttl.h" -#include "util-debug.h" - -/** - * \brief Regex for parsing our flow options - */ -#define PARSE_REGEX "^\\s*([0-9]*)?\\s*([<>=-]+)?\\s*([0-9]+)?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -/*prototypes*/ -int DetectTtlMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectTtlSetup (DetectEngineCtx *, Signature *, char *); -void DetectTtlFree (void *); -void DetectTtlRegisterTests (void); - -/** - * \brief Registration function for ttl: keyword - */ - -void DetectTtlRegister(void) -{ - sigmatch_table[DETECT_TTL].name = "ttl"; - sigmatch_table[DETECT_TTL].desc = "check for a specific IP time-to-live value"; - sigmatch_table[DETECT_TTL].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#ttl"; - sigmatch_table[DETECT_TTL].Match = DetectTtlMatch; - sigmatch_table[DETECT_TTL].Setup = DetectTtlSetup; - sigmatch_table[DETECT_TTL].Free = DetectTtlFree; - sigmatch_table[DETECT_TTL].RegisterTests = DetectTtlRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - if (parse_regex != NULL) SCFree(parse_regex); - if (parse_regex_study != NULL) SCFree(parse_regex_study); - return; -} - -/** - * \brief This function is used to match TTL rule option on a packet with those passed via ttl: - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectTtlData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectTtlMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - - int ret = 0; - uint8_t pttl; - const DetectTtlData *ttld = (const DetectTtlData *)ctx; - - if (PKT_IS_PSEUDOPKT(p)) - return 0; - - if (PKT_IS_IPV4(p)) { - pttl = IPV4_GET_IPTTL(p); - } else if (PKT_IS_IPV6(p)) { - pttl = IPV6_GET_HLIM(p); - } else { - SCLogDebug("Packet is of not IPv4 or IPv6"); - return ret; - } - - if (ttld->mode == DETECT_TTL_EQ && pttl == ttld->ttl1) - ret = 1; - else if (ttld->mode == DETECT_TTL_LT && pttl < ttld->ttl1) - ret = 1; - else if (ttld->mode == DETECT_TTL_GT && pttl > ttld->ttl1) - ret = 1; - else if (ttld->mode == DETECT_TTL_RA && (pttl > ttld->ttl1 && pttl < ttld->ttl2)) - ret = 1; - - return ret; -} - -/** - * \brief This function is used to parse ttl options passed via ttl: keyword - * - * \param ttlstr Pointer to the user provided ttl options - * - * \retval ttld pointer to DetectTtlData on success - * \retval NULL on failure - */ - -DetectTtlData *DetectTtlParse (char *ttlstr) -{ - - DetectTtlData *ttld = NULL; - char *arg1 = NULL; - char *arg2 = NULL; - char *arg3 = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, ttlstr, strlen(ttlstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 2 || ret > 4) { - SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 "", ret); - goto error; - } - const char *str_ptr; - - res = pcre_get_substring((char *) ttlstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg1 = (char *) str_ptr; - SCLogDebug("Arg1 \"%s\"", arg1); - - if (ret >= 3) { - res = pcre_get_substring((char *) ttlstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg2 = (char *) str_ptr; - SCLogDebug("Arg2 \"%s\"", arg2); - - if (ret >= 4) { - res = pcre_get_substring((char *) ttlstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg3 = (char *) str_ptr; - SCLogDebug("Arg3 \"%s\"", arg3); - } - } - - ttld = SCMalloc(sizeof (DetectTtlData)); - if (unlikely(ttld == NULL)) - goto error; - ttld->ttl1 = 0; - ttld->ttl2 = 0; - - if (arg2 != NULL) { - /*set the values*/ - switch(arg2[0]) { - case '<': - if (arg3 == NULL) - goto error; - - ttld->mode = DETECT_TTL_LT; - ttld->ttl1 = (uint8_t) atoi(arg3); - - SCLogDebug("ttl is %"PRIu8"",ttld->ttl1); - if (strlen(arg1) > 0) - goto error; - - break; - case '>': - if (arg3 == NULL) - goto error; - - ttld->mode = DETECT_TTL_GT; - ttld->ttl1 = (uint8_t) atoi(arg3); - - SCLogDebug("ttl is %"PRIu8"",ttld->ttl1); - if (strlen(arg1) > 0) - goto error; - - break; - case '-': - if (arg1 == NULL || strlen(arg1)== 0) - goto error; - if (arg3 == NULL || strlen(arg3)== 0) - goto error; - - ttld->mode = DETECT_TTL_RA; - ttld->ttl1 = (uint8_t) atoi(arg1); - - ttld->ttl2 = (uint8_t) atoi(arg3); - SCLogDebug("ttl is %"PRIu8" to %"PRIu8"",ttld->ttl1, ttld->ttl2); - if (ttld->ttl1 >= ttld->ttl2) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid ttl range. "); - goto error; - } - break; - default: - ttld->mode = DETECT_TTL_EQ; - - if ((arg2 != NULL && strlen(arg2) > 0) || (arg3 != NULL && strlen(arg3) > 0) || (arg1 == NULL ||strlen(arg1) == 0)) - goto error; - - ttld->ttl1 = (uint8_t) atoi(arg1); - break; - } - } else { - ttld->mode = DETECT_TTL_EQ; - - if ((arg2 != NULL && strlen(arg2) > 0) || - (arg3 != NULL && strlen(arg3) > 0) || - (arg1 == NULL ||strlen(arg1) == 0)) - goto error; - - ttld->ttl1 = (uint8_t) atoi(arg1); - } - - SCFree(arg1); - SCFree(arg2); - SCFree(arg3); - return ttld; - -error: - if (ttld) SCFree(ttld); - if (arg1) SCFree(arg1); - if (arg2) SCFree(arg2); - if (arg3) SCFree(arg3); - return NULL; -} - -/** - * \brief this function is used to attld the parsed ttl data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param ttlstr pointer to the user provided ttl options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectTtlSetup (DetectEngineCtx *de_ctx, Signature *s, char *ttlstr) -{ - - DetectTtlData *ttld = NULL; - SigMatch *sm = NULL; - - ttld = DetectTtlParse(ttlstr); - if (ttld == NULL) - goto error; - - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_TTL; - sm->ctx = (SigMatchCtx *)ttld; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (ttld != NULL) DetectTtlFree(ttld); - if (sm != NULL) SCFree(sm); - return -1; -} - -/** - * \brief this function will free memory associated with DetectTtlData - * - * \param ptr pointer to DetectTtlData - */ -void DetectTtlFree(void *ptr) -{ - DetectTtlData *ttld = (DetectTtlData *)ptr; - SCFree(ttld); -} - -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -/** - * \brief this function is used to initialize the detection engine context and - * setup the signature with passed values. - * - */ - -static int DetectTtlInitTest(DetectEngineCtx **de_ctx, Signature **sig, DetectTtlData **ttld, char *str) -{ - char fullstr[1024]; - int result = 0; - - *de_ctx = NULL; - *sig = NULL; - - if (snprintf(fullstr, 1024, "alert ip any any -> any any (msg:\"Ttl test\"; ttl:%s; sid:1;)", str) >= 1024) { - goto end; - } - - *de_ctx = DetectEngineCtxInit(); - if (*de_ctx == NULL) { - goto end; - } - - (*de_ctx)->flags |= DE_QUIET; - - (*de_ctx)->sig_list = SigInit(*de_ctx, fullstr); - if ((*de_ctx)->sig_list == NULL) { - goto end; - } - - *sig = (*de_ctx)->sig_list; - - *ttld = DetectTtlParse(str); - - result = 1; - -end: - return result; -} - -/** - * \test DetectTtlParseTest01 is a test for setting up an valid ttl value. - */ - -static int DetectTtlParseTest01 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse("10"); - if (ttld != NULL) { - if (ttld->ttl1 == 10 && ttld->mode == DETECT_TTL_EQ) - res = 1; - - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest02 is a test for setting up an valid ttl value with - * "<" operator. - */ - -static int DetectTtlParseTest02 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - ttld = DetectTtlParse("<10"); - if (ttld != NULL) { - if (ttld->ttl1 == 10 && ttld->mode == DETECT_TTL_LT) - res = 1; - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest03 is a test for setting up an valid ttl values with - * "-" operator. - */ - -static int DetectTtlParseTest03 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - ttld = DetectTtlParse("1-2"); - if (ttld != NULL) { - if (ttld->ttl1 == 1 && ttld->ttl2 == 2 && ttld->mode == DETECT_TTL_RA) - res = 1; - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest04 is a test for setting up an valid ttl value with - * ">" operator and include spaces arround the given values. - */ - -static int DetectTtlParseTest04 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse(" > 10 "); - if (ttld != NULL) { - if (ttld->ttl1 == 10 && ttld->mode == DETECT_TTL_GT) - res = 1; - - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest05 is a test for setting up an valid ttl values with - * "-" operator and include spaces arround the given values. - */ - -static int DetectTtlParseTest05 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse(" 1 - 2 "); - if (ttld != NULL) { - if (ttld->ttl1 == 1 && ttld->ttl2 == 2 && ttld->mode == DETECT_TTL_RA) - res = 1; - DetectTtlFree(ttld); - } - - return res; -} - -/** - * \test DetectTtlParseTest06 is a test for setting up an valid ttl values with - * invalid "=" operator and include spaces arround the given values. - */ - -static int DetectTtlParseTest06 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse(" 1 = 2 "); - if (ttld == NULL) - res = 1; - if (ttld) SCFree(ttld); - - return res; -} - -/** - * \test DetectTtlParseTest07 is a test for setting up an valid ttl values with - * invalid "<>" operator and include spaces arround the given values. - */ - -static int DetectTtlParseTest07 (void) -{ - DetectTtlData *ttld = NULL; - uint8_t res = 0; - - ttld = DetectTtlParse(" 1<>2 "); - if (ttld == NULL) - res = 1; - - if (ttld) SCFree(ttld); - - return res; -} - -/** - * \test DetectTtlSetpTest01 is a test for setting up an valid ttl values with - * valid "-" operator and include spaces arround the given values. In the - * test the values are setup with initializing the detection engine context - * setting up the signature itself. - */ - -static int DetectTtlSetpTest01(void) -{ - - DetectTtlData *ttld = NULL; - uint8_t res = 0; - Signature *sig = NULL; - DetectEngineCtx *de_ctx = NULL; - - res = DetectTtlInitTest(&de_ctx, &sig, &ttld, "1 - 2 "); - if (res == 0) { - goto end; - } - - if(ttld == NULL) - goto cleanup; - - if (ttld != NULL) { - if (ttld->ttl1 == 1 && ttld->ttl2 == 2 && ttld->mode == DETECT_TTL_RA) - res = 1; - } - -cleanup: - if (ttld) SCFree(ttld); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); -end: - return res; -} - -/** - * \test DetectTtlTestSig01 is a test for checking the working of ttl keyword - * by setting up the signature and later testing its working by matching - * the received packet against the sig. - */ - -static int DetectTtlTestSig1(void) -{ - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - int result = 0; - IPV4Hdr ip4h; - - memset(&th_v, 0, sizeof(th_v)); - memset(&ip4h, 0, sizeof(ip4h)); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - ip4h.ip_ttl = 15; - p->ip4h = &ip4h; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"with in ttl limit\"; ttl: >16; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Less than 17\"; ttl: <17; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Greater than 5\"; ttl:15; sid:3;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Equals tcp\"; ttl: 1-30; sid:4;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - printf("sid 1 alerted, but should not have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 2) == 0) { - printf("sid 2 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 3) == 0) { - printf("sid 3 did not alert, but should have: "); - goto cleanup; - } else if (PacketAlertCheck(p, 4) == 0) { - printf("sid 4 did not alert, but should have: "); - goto cleanup; - } - - result = 1; - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - SCFree(p); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectTtl - */ -void DetectTtlRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectTtlParseTest01", DetectTtlParseTest01, 1); - UtRegisterTest("DetectTtlParseTest02", DetectTtlParseTest02, 1); - UtRegisterTest("DetectTtlParseTest03", DetectTtlParseTest03, 1); - UtRegisterTest("DetectTtlParseTest04", DetectTtlParseTest04, 1); - UtRegisterTest("DetectTtlParseTest05", DetectTtlParseTest05, 1); - UtRegisterTest("DetectTtlParseTest06", DetectTtlParseTest06, 1); - UtRegisterTest("DetectTtlParseTest07", DetectTtlParseTest07, 1); - UtRegisterTest("DetectTtlSetpTest01", DetectTtlSetpTest01, 1); - UtRegisterTest("DetectTtlTestSig1", DetectTtlTestSig1, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-ttl.h b/framework/src/suricata/src/detect-ttl.h deleted file mode 100644 index 86505f76..00000000 --- a/framework/src/suricata/src/detect-ttl.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - */ - -#ifndef _DETECT_TTL_H -#define _DETECT_TTL_H - -#define DETECT_TTL_LT 0 /**< "less than" operator */ -#define DETECT_TTL_EQ 1 /**< "equals" operator (default) */ -#define DETECT_TTL_GT 2 /**< "greater than" operator */ -#define DETECT_TTL_RA 3 /**< "range" operator */ - -typedef struct DetectTtlData_ { - uint8_t ttl1; /**< first ttl value in the signature*/ - uint8_t ttl2; /**< second ttl value in the signature, in case of range - operator*/ - uint8_t mode; /**< operator used in the signature */ -}DetectTtlData; - -void DetectTtlRegister(void); - -#endif /* _DETECT_TTL_H */ - diff --git a/framework/src/suricata/src/detect-uricontent.c b/framework/src/suricata/src/detect-uricontent.c deleted file mode 100644 index 65d2ef94..00000000 --- a/framework/src/suricata/src/detect-uricontent.c +++ /dev/null @@ -1,1983 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Gurvinder Singh - * - * Simple uricontent match part of the detection engine. - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "detect-content.h" -#include "detect-http-uri.h" -#include "detect-uricontent.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-state.h" -#include "flow.h" -#include "detect-flow.h" -#include "flow-var.h" -#include "flow-util.h" -#include "threads.h" - -#include "stream-tcp.h" -#include "stream.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-protos.h" -#include "app-layer-htp.h" - -#include "util-mpm.h" -#include "util-print.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-binsearch.h" -#include "util-spm.h" -#include "util-spm-bm.h" -#include "conf.h" - -/* prototypes */ -static int DetectUricontentSetup (DetectEngineCtx *, Signature *, char *); -void HttpUriRegisterTests(void); - -int DetectAppLayerUricontentMatch (ThreadVars *, DetectEngineThreadCtx *, - Flow *, uint8_t , void *, - Signature *, SigMatch *); -void DetectUricontentFree(void *); - -/** - * \brief Registration function for uricontent: keyword - */ -void DetectUricontentRegister (void) -{ - sigmatch_table[DETECT_URICONTENT].name = "uricontent"; - sigmatch_table[DETECT_URICONTENT].AppLayerMatch = NULL; - sigmatch_table[DETECT_URICONTENT].Match = NULL; - sigmatch_table[DETECT_URICONTENT].Setup = DetectUricontentSetup; - sigmatch_table[DETECT_URICONTENT].Free = DetectUricontentFree; - sigmatch_table[DETECT_URICONTENT].RegisterTests = HttpUriRegisterTests; - sigmatch_table[DETECT_URICONTENT].alproto = ALPROTO_HTTP; - - sigmatch_table[DETECT_URICONTENT].flags |= SIGMATCH_PAYLOAD; -} - -/** - * \brief pass on the uricontent_max_id - * \param de_ctx pointer to the detect egine context whose max id is asked - */ -uint32_t DetectUricontentMaxId(DetectEngineCtx *de_ctx) -{ - return MpmPatternIdStoreGetMaxId(de_ctx->mpm_pattern_id_store); -} - -/** - * \brief this function will Free memory associated with DetectContentData - * - * \param cd pointer to DetectUricotentData - */ -void DetectUricontentFree(void *ptr) -{ - SCEnter(); - DetectContentData *cd = (DetectContentData *)ptr; - - if (cd == NULL) - SCReturn; - - BoyerMooreCtxDeInit(cd->bm_ctx); - SCFree(cd); - - SCReturn; -} - -/** - * \brief Helper function to print a DetectContentData - */ -void DetectUricontentPrint(DetectContentData *cd) -{ - int i = 0; - if (cd == NULL) { - SCLogDebug("Detect UricontentData \"cd\" is NULL"); - return; - } - char *tmpstr = SCMalloc(sizeof(char) * cd->content_len + 1); - if (unlikely(tmpstr == NULL)) - return; - - if (tmpstr != NULL) { - for (i = 0; i < cd->content_len; i++) { - if (isprint(cd->content[i])) - tmpstr[i] = cd->content[i]; - else - tmpstr[i] = '.'; - } - tmpstr[i] = '\0'; - SCLogDebug("Uricontent: \"%s\"", tmpstr); - SCFree(tmpstr); - } else { - SCLogDebug("Uricontent: "); - for (i = 0; i < cd->content_len; i++) - SCLogDebug("%c", cd->content[i]); - } - - SCLogDebug("Uricontent_id: %"PRIu32, cd->id); - SCLogDebug("Uricontent_len: %"PRIu16, cd->content_len); - SCLogDebug("Depth: %"PRIu16, cd->depth); - SCLogDebug("Offset: %"PRIu16, cd->offset); - SCLogDebug("Within: %"PRIi32, cd->within); - SCLogDebug("Distance: %"PRIi32, cd->distance); - SCLogDebug("flags: %u ", cd->flags); - SCLogDebug("negated: %s ", - cd->flags & DETECT_CONTENT_NEGATED ? "true" : "false"); - SCLogDebug("relative match next: %s ", - cd->flags & DETECT_CONTENT_RELATIVE_NEXT ? "true" : "false"); - SCLogDebug("-----------"); -} - -/** - * \brief Creates a SigMatch for the uricontent keyword being sent as argument, - * and appends it to the Signature(s). - * - * \param de_ctx Pointer to the detection engine context - * \param s Pointer to signature for the current Signature being parsed - * from the rules - * \param contentstr Pointer to the string holding the keyword value - * - * \retval 0 on success, -1 on failure - */ -int DetectUricontentSetup(DetectEngineCtx *de_ctx, Signature *s, char *contentstr) -{ - SCEnter(); - - char *legacy = NULL; - if (ConfGet("legacy.uricontent", &legacy) == 1) { - if (strcasecmp("disabled", legacy) == 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "uriconent deprecated. To " - "use a rule with \"uricontent\", either set the " - "option - \"legacy.uricontent\" in the conf to " - "\"enabled\" OR replace uricontent with " - "\'content:%s; http_uri;\'.", contentstr); - goto error; - } else if (strcasecmp("enabled", legacy) == 0) { - ; - } else { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid value found " - "for legacy.uriconent - \"%s\". Valid values are " - "\"enabled\" OR \"disabled\".", legacy); - goto error; - } - } - - if (DetectContentSetup(de_ctx, s, contentstr) < 0) - goto error; - - if (DetectHttpUriSetup(de_ctx, s, NULL) < 0) - goto error; - - SCReturnInt(0); -error: - SCReturnInt(-1); -} - -/** - * \brief Checks if the content sent as the argument, has a uricontent which - * has been provided in the rule. This match function matches the - * normalized http uri against the given rule using multi pattern - * search algorithms. - * - * \param det_ctx Pointer to the detection engine thread context - * \param content Pointer to the uri content currently being matched - * \param content_len Content_len of the received uri content - * - * \retval 1 if the uri contents match; 0 no match - */ -static inline int DoDetectAppLayerUricontentMatch (DetectEngineThreadCtx *det_ctx, - uint8_t *uri, uint16_t uri_len, uint8_t flags) -{ - int ret = 0; - /* run the pattern matcher against the uri */ - if (det_ctx->sgh->mpm_uricontent_minlen > uri_len) { - SCLogDebug("not searching as uri len is smaller than the " - "shortest uricontent length we need to match"); - } else { - SCLogDebug("search: (%p, minlen %" PRIu32 ", sgh->sig_cnt " - "%" PRIu32 ")", det_ctx->sgh, - det_ctx->sgh->mpm_uricontent_minlen, det_ctx->sgh->sig_cnt); - - ret += UriPatternSearch(det_ctx, uri, uri_len, flags); - - SCLogDebug("post search: cnt %" PRIu32, ret); - } - return ret; -} - -/** - * \brief Run the pattern matcher against the uri(s) - * - * We run against _all_ uri(s) we have as the pattern matcher will - * flag each sig that has a match. We need to do this for all uri(s) - * to not miss possible events. - * - * \param f locked flow - * \param htp_state initialized htp state - * - * \warning Make sure the flow/state is locked - * \todo what should we return? Just the fact that we matched? - */ -uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *txv, uint64_t idx) -{ - SCEnter(); - - htp_tx_t *tx = (htp_tx_t *)txv; - HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - uint32_t cnt = 0; - - if (tx_ud == NULL || tx_ud->request_uri_normalized == NULL) - goto end; - cnt = DoDetectAppLayerUricontentMatch(det_ctx, (uint8_t *) - bstr_ptr(tx_ud->request_uri_normalized), - bstr_len(tx_ud->request_uri_normalized), - flags); - -end: - SCReturnUInt(cnt); -} - -/* - * UNITTTESTS - */ - -#ifdef UNITTESTS - -#include "stream-tcp-reassemble.h" - -/** \test Test case where path traversal has been sent as a path string in the - * HTTP URL and normalized path string is checked */ -static int HTTPUriTest01(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "GET /../../images.gif HTTP/1.1\r\nHost: www.ExA" - "mPlE.cOM\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START| - STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - printf("AppLayerParse failed: r(%d) != 0: ", r); - goto end; - } - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0); - - if (tx->request_method_number != HTP_M_GET || - tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - goto end; - } - - if ((tx->request_hostname == NULL) || - (bstr_cmp_c(tx->request_hostname, "www.example.com") != 0)) - { - goto end; - } - - if ((tx->parsed_uri->path == NULL) || - (bstr_cmp_c(tx->parsed_uri->path, "/images.gif") != 0)) - { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - return result; -} - -/** \test Test case where path traversal has been sent in special characters in - * HEX encoding in the HTTP URL and normalized path string is checked */ -static int HTTPUriTest02(void) -{ - int result = 0; - Flow f; - HtpState *htp_state = NULL; - uint8_t httpbuf1[] = "GET /%2e%2e/images.gif HTTP/1.1\r\nHost: www.ExA" - "mPlE.cOM\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START| - STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - printf("AppLayerParse failed: r(%d) != 0: ", r); - goto end; - } - - htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0); - - if (tx->request_method_number != HTP_M_GET || - tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - goto end; - } - - if ((tx->request_hostname == NULL) || - (bstr_cmp_c(tx->request_hostname, "www.example.com") != 0)) - { - goto end; - } - - if ((tx->parsed_uri->path == NULL) || - (bstr_cmp_c(tx->parsed_uri->path, "/images.gif") != 0)) - { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - return result; -} - -/** \test Test case where NULL character has been sent in HEX encoding in the - * HTTP URL and normalized path string is checked */ -static int HTTPUriTest03(void) -{ - int result = 0; - Flow f; - HtpState *htp_state = NULL; - uint8_t httpbuf1[] = "GET%00 /images.gif HTTP/1.1\r\nHost: www.ExA" - "mPlE.cOM\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START| - STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - printf("AppLayerParse failed: r(%d) != 0: ", r); - goto end; - } - - htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0); - - if (tx->request_method_number != HTP_M_UNKNOWN || - tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - goto end; - } - - if ((tx->request_hostname == NULL) || - (bstr_cmp_c(tx->request_hostname, "www.example.com") != 0)) - { - goto end; - } - - if ((tx->parsed_uri->path == NULL) || - (bstr_cmp_c(tx->parsed_uri->path, "/images.gif") != 0)) - { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - return result; -} - - -/** \test Test case where self referencing directories request has been sent - * in the HTTP URL and normalized path string is checked */ -static int HTTPUriTest04(void) -{ - int result = 0; - Flow f; - HtpState *htp_state = NULL; - uint8_t httpbuf1[] = "GET /./././images.gif HTTP/1.1\r\nHost: www.ExA" - "mPlE.cOM\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - int r = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START| - STREAM_EOF, httpbuf1, httplen1); - if (r != 0) { - printf("AppLayerParse failed: r(%d) != 0: ", r); - goto end; - } - - htp_state = f.alstate; - if (htp_state == NULL) { - printf("no http state: "); - goto end; - } - - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, 0); - - if (tx->request_method_number != HTP_M_GET || - tx->request_protocol_number != HTP_PROTOCOL_1_1) - { - goto end; - } - - if ((tx->request_hostname == NULL) || - (bstr_cmp_c(tx->request_hostname, "www.example.com") != 0)) - { - goto end; - } - - if ((tx->parsed_uri->path == NULL) || - (bstr_cmp_c(tx->parsed_uri->path, "/images.gif") != 0)) - { - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - StreamTcpFreeConfig(TRUE); - if (htp_state != NULL) - HTPStateFree(htp_state); - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Checks if a uricontent is registered in a Signature - */ -int DetectUriSigTest01(void) -{ - SigMatch *sm = NULL; - int result = 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Signature *s = NULL; - - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\" Test uricontent\"; " - "content:\"me\"; uricontent:\"me\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - BUG_ON(de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH] == NULL); - - sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm->type == DETECT_CONTENT) { - result = 1; - } else { - result = 0; - } - - end: - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, det_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check the signature working to alert when http_cookie is matched . */ -static int DetectUriSigTest02(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST /one HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\nCookie:" - " hellocatch\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"foo\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"one\"; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"oisf\"; sid:3;)"); - if (s == NULL) { - goto end; - } - - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - printf("sig: 1 alerted, but it should not\n"); - goto end; - } else if (!PacketAlertCheck(p, 2)) { - printf("sig: 2 did not alerted, but it should\n"); - goto end; - } else if ((PacketAlertCheck(p, 3))) { - printf("sig: 3 alerted, but it should not\n"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - //if (http_state != NULL) HTPStateFree(http_state); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, det_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the working of search once per packet only in applayer - * match */ -static int DetectUriSigTest03(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t httpbuf1[] = "POST /one HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\nCookie:" - " hellocatch\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "POST /oneself HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\nCookie:" - " hellocatch\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"foo\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"one\"; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"self\"; sid:3;)"); - if (s == NULL) { - goto end; - } - - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - printf("sig 1 alerted, but it should not: "); - goto end; - } else if (!PacketAlertCheck(p, 2)) { - printf("sig 2 did not alert, but it should: "); - goto end; - } else if ((PacketAlertCheck(p, 3))) { - printf("sig 3 alerted, but it should not: "); - goto end; - } - - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf2, httplen2); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - printf("sig 1 alerted, but it should not (chunk 2): "); - goto end; - } else if (!PacketAlertCheck(p, 2)) { - printf("sig 2 alerted, but it should not (chunk 2): "); - goto end; - } else if (!(PacketAlertCheck(p, 3))) { - printf("sig 3 did not alert, but it should (chunk 2): "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, det_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Check that modifiers of content apply only to content keywords - * and the same for uricontent modifiers - */ -static int DetectUriSigTest04(void) -{ - int result = 0; - Signature *s = NULL; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"foo\"; sid:1;)"); - if (s == NULL || - s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_MATCH] != NULL) - { - printf("sig 1 failed to parse: "); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "uricontent:\"foo\"; content:\"bar\";sid:1;)"); - if (s == NULL || - s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_MATCH] != NULL) - { - printf("sig 2 failed to parse: "); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "uricontent:\"foo\"; content:\"bar\";" - " depth:10; offset: 5; sid:1;)"); - if (s == NULL || - s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL || - ((DetectContentData *)s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->depth != 15 || - ((DetectContentData *)s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->offset != 5 || - s->sm_lists[DETECT_SM_LIST_MATCH] != NULL) - { - printf("sig 3 failed to parse: "); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "content:\"foo\"; uricontent:\"bar\";" - " depth:10; offset: 5; sid:1;)"); - if (s == NULL || - s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL || - ((DetectContentData *)s->sm_lists[DETECT_SM_LIST_UMATCH]->ctx)->depth != 15 || - ((DetectContentData *)s->sm_lists[DETECT_SM_LIST_UMATCH]->ctx)->offset != 5 || - s->sm_lists[DETECT_SM_LIST_MATCH] != NULL) - { - printf("sig 4 failed to parse: "); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "uricontent:\"foo\"; content:\"bar\";" - " depth:10; offset: 5; within:3; sid:1;)"); - if (s != NULL) { - printf("sig 5 failed to parse: "); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "uricontent:\"foo\"; content:\"bar\";" - " depth:10; offset: 5; distance:3; sid:1;)"); - if (s != NULL) { - printf("sig 6 failed to parse: "); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "uricontent:\"foo\"; content:\"bar\";" - " depth:10; offset: 5; content:" - "\"two_contents\"; within:30; sid:1;)"); - if (s == NULL) { - goto end; - } else if (s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL || - ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->depth != 15 || - ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->offset != 5 || - ((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx)->within != 30 || - s->sm_lists[DETECT_SM_LIST_MATCH] != NULL) - { - printf("sig 7 failed to parse: "); - DetectContentPrint((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "uricontent:\"foo\"; content:\"bar\";" - " depth:10; offset: 5; uricontent:" - "\"two_uricontents\"; within:30; sid:1;)"); - if (s == NULL) { - goto end; - } else if (s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL || - ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->depth != 15 || - ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->offset != 5 || - ((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx)->within != 30 || - s->sm_lists[DETECT_SM_LIST_MATCH] != NULL) - { - printf("sig 8 failed to parse: "); - DetectUricontentPrint((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "uricontent:\"foo\"; content:\"bar\";" - " depth:10; offset: 5; content:" - "\"two_contents\"; distance:30; sid:1;)"); - if (s == NULL) { - goto end; - } else if ( - s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL || - ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->depth != 15 || - ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->offset != 5 || - ((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx)->distance != 30 || - s->sm_lists[DETECT_SM_LIST_MATCH] != NULL) - { - printf("sig 9 failed to parse: "); - DetectContentPrint((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "uricontent:\"foo\"; content:\"bar\";" - " depth:10; offset: 5; uricontent:" - "\"two_uricontents\"; distance:30; sid:1;)"); - if (s == NULL) { - goto end; - } else if ( - s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL || - s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL || - ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->depth != 15 || - ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->offset != 5 || - ((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx)->distance != 30 || - s->sm_lists[DETECT_SM_LIST_MATCH] != NULL) - { - printf("sig 10 failed to parse: "); - DetectUricontentPrint((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx); - goto end; - } - - s = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent and content\"; " - "uricontent:\"foo\"; content:\"bar\";" - " depth:10; offset: 5; uricontent:" - "\"two_uricontents\"; distance:30; " - "within:60; content:\"two_contents\";" - " within:70; distance:45; sid:1;)"); - if (s == NULL) { - printf("sig 10 failed to parse: "); - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_UMATCH] == NULL || s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) { - printf("umatch %p or pmatch %p: ", s->sm_lists[DETECT_SM_LIST_UMATCH], s->sm_lists[DETECT_SM_LIST_PMATCH]); - goto end; - } - - if ( ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->depth != 15 || - ((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx)->offset != 5 || - ((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx)->distance != 30 || - ((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx)->within != 60 || - ((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx)->distance != 45 || - ((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx)->within != 70 || - s->sm_lists[DETECT_SM_LIST_MATCH] != NULL) { - printf("sig 10 failed to parse, content not setup properly: "); - DetectContentPrint((DetectContentData*) s->sm_lists[DETECT_SM_LIST_PMATCH]->ctx); - DetectUricontentPrint((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx); - DetectContentPrint((DetectContentData*) s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check the modifiers for uricontent and content - * match - */ -static int DetectUriSigTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t httpbuf1[] = "POST /one/two/three HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\nCookie:" - " hellocatch\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - - p = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP); - p->tcph->th_seq = htonl(1000); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - f.proto = p->proto; - - StreamTcpInitConfig(TRUE); - - StreamMsg *stream_msg = StreamMsgGetFromPool(); - if (stream_msg == NULL) { - printf("no stream_msg: "); - goto end; - } - - memcpy(stream_msg->data, httpbuf1, httplen1); - stream_msg->data_len = httplen1; - - ssn.toserver_smsg_head = stream_msg; - ssn.toserver_smsg_tail = stream_msg; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; uricontent:\"foo\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; uricontent:\"one\"; content:\"two\"; sid:2;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; uricontent:\"one\"; offset:1; depth:10; " - "uricontent:\"two\"; distance:1; within: 4; uricontent:\"three\"; " - "distance:1; within: 6; sid:3;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - if ((PacketAlertCheck(p, 1))) { - printf("sig: 1 alerted, but it should not: "); - goto end; - } else if (! PacketAlertCheck(p, 2)) { - printf("sig: 2 did not alert, but it should: "); - goto end; - } else if (! (PacketAlertCheck(p, 3))) { - printf("sig: 3 did not alert, but it should: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, det_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the modifiers for uricontent and content - * match - */ -static int DetectUriSigTest06(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t httpbuf1[] = "POST /one/two/three HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\nCookie:" - " hellocatch\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - TCPHdr tcp_hdr; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - memset(&tcp_hdr, 0, sizeof(tcp_hdr)); - - - p = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP); - p->tcph->th_seq = htonl(1000); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - f.proto = p->proto; - - StreamTcpInitConfig(TRUE); - - StreamMsg *stream_msg = StreamMsgGetFromPool(); - if (stream_msg == NULL) { - printf("no stream_msg: "); - goto end; - } - - memcpy(stream_msg->data, httpbuf1, httplen1); - stream_msg->data_len = httplen1; - - ssn.toserver_smsg_head = stream_msg; - ssn.toserver_smsg_tail = stream_msg; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"foo\"; content:\"bar\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"one\"; offset:1; depth:10; " - "content:\"one\"; offset:1; depth:10; " - "uricontent:\"two\"; distance:1; within: 4; " - "content:\"two\"; distance:1; within: 4; " - "uricontent:\"three\"; distance:1; within: 6; " - "content:\"/three\"; distance:0; within: 7; " - "sid:2;)"); - - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"one\"; offset:1; depth:10; " - "uricontent:\"two\"; distance:1; within: 4; " - "uricontent:\"three\"; distance:1; within: 6; " - "sid:3;)"); - - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - if ((PacketAlertCheck(p, 1))) { - printf("sig: 1 alerted, but it should not:"); - goto end; - } else if (! PacketAlertCheck(p, 2)) { - printf("sig: 2 did not alert, but it should:"); - goto end; - } else if (! (PacketAlertCheck(p, 3))) { - printf("sig: 3 did not alert, but it should:"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, det_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the modifiers for uricontent and content - * match - */ -static int DetectUriSigTest07(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t httpbuf1[] = "POST /one/two/three HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\nCookie:" - " hellocatch\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(httpbuf1, httplen1, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"foo\"; content:\"bar\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"one\"; offset:1; depth:10; " - "content:\"one\"; offset:1; depth:10; " - "uricontent:\"two\"; distance:3; within: 4; " - "content:\"two\"; distance:1; within: 4; " - "uricontent:\"three\"; distance:1; within: 6; " - "content:\"/three\"; distance:0; within: 7; " - "sid:2;)"); - - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:" - "\" Test uricontent\"; " - "uricontent:\"one\"; offset:1; depth:10; " - "uricontent:\"two\"; distance:1; within: 4; " - "uricontent:\"six\"; distance:1; within: 6; " - "sid:3;)"); - - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - if (PacketAlertCheck(p, 1)) { - printf("sig: 1 alerted, but it should not:"); - goto end; - } else if (PacketAlertCheck(p, 2)) { - printf("sig: 2 alerted, but it should not:"); - goto end; - } else if (PacketAlertCheck(p, 3)) { - printf("sig: 3 alerted, but it should not:"); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, det_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test Test content for dce sig. - */ -int DetectUriSigTest08(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DetectUriSigTest09(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DetectUriSigTest10(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"boo; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test content for dce sig. - */ -int DetectUriSigTest11(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:boo\"; sid:238012;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriSigTest12(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectContentData *ud = 0; - Signature *s = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - s = de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent: !\"boo\"; sid:238012;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL: "); - goto end; - } - - if (s->sm_lists_tail[DETECT_SM_LIST_UMATCH] == NULL || s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx == NULL) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - ud = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_UMATCH]->ctx; - result = (strncmp("boo", (char *)ud->content, ud->content_len) == 0); - -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - - -/** - * \test Parsing test - */ -int DetectUriContentParseTest13(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"|\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest14(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"|af\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest15(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"af|\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest16(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"|af|\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest17(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"aast|\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest18(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"aast|af\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest19(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"aast|af|\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest20(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"|af|asdf\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest21(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"|af|af|\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"|af|af|af\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(msg:\"test\"; uricontent:\"|af|af|af|\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Parsing test - */ -int DetectUriContentParseTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 1; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"test\"; uricontent:\"\"; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 0; - goto end; - } - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -#endif /* UNITTESTS */ - -void HttpUriRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("HTTPUriTest01", HTTPUriTest01, 1); - UtRegisterTest("HTTPUriTest02", HTTPUriTest02, 1); - UtRegisterTest("HTTPUriTest03", HTTPUriTest03, 1); - UtRegisterTest("HTTPUriTest04", HTTPUriTest04, 1); - - UtRegisterTest("DetectUriSigTest01", DetectUriSigTest01, 1); - UtRegisterTest("DetectUriSigTest02", DetectUriSigTest02, 1); - UtRegisterTest("DetectUriSigTest03", DetectUriSigTest03, 1); - UtRegisterTest("DetectUriSigTest04 - Modifiers", DetectUriSigTest04, 1); - UtRegisterTest("DetectUriSigTest05 - Inspection", DetectUriSigTest05, 1); - UtRegisterTest("DetectUriSigTest06 - Inspection", DetectUriSigTest06, 1); - UtRegisterTest("DetectUriSigTest07 - Inspection", DetectUriSigTest07, 1); - UtRegisterTest("DetectUriSigTest08", DetectUriSigTest08, 1); - UtRegisterTest("DetectUriSigTest09", DetectUriSigTest09, 1); - UtRegisterTest("DetectUriSigTest10", DetectUriSigTest10, 1); - UtRegisterTest("DetectUriSigTest11", DetectUriSigTest11, 1); - UtRegisterTest("DetectUriSigTest12", DetectUriSigTest12, 1); - - UtRegisterTest("DetectUriContentParseTest13", DetectUriContentParseTest13, 1); - UtRegisterTest("DetectUriContentParseTest14", DetectUriContentParseTest14, 1); - UtRegisterTest("DetectUriContentParseTest15", DetectUriContentParseTest15, 1); - UtRegisterTest("DetectUriContentParseTest16", DetectUriContentParseTest16, 1); - UtRegisterTest("DetectUriContentParseTest17", DetectUriContentParseTest17, 1); - UtRegisterTest("DetectUriContentParseTest18", DetectUriContentParseTest18, 1); - UtRegisterTest("DetectUriContentParseTest19", DetectUriContentParseTest19, 1); - UtRegisterTest("DetectUriContentParseTest20", DetectUriContentParseTest20, 1); - UtRegisterTest("DetectUriContentParseTest21", DetectUriContentParseTest21, 1); - UtRegisterTest("DetectUriContentParseTest22", DetectUriContentParseTest22, 1); - UtRegisterTest("DetectUriContentParseTest23", DetectUriContentParseTest23, 1); - UtRegisterTest("DetectUriContentParseTest24", DetectUriContentParseTest24, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-uricontent.h b/framework/src/suricata/src/detect-uricontent.h deleted file mode 100644 index c32a923e..00000000 --- a/framework/src/suricata/src/detect-uricontent.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Gurvinder Singh - */ - -#ifndef __DETECT_URICONTENT_H__ -#define __DETECT_URICONTENT_H__ - -#include "detect-content.h" - -#include "util-spm-bm.h" -#include "app-layer-htp.h" - -/* prototypes */ -void DetectUricontentRegister (void); -uint32_t DetectUricontentMaxId(DetectEngineCtx *); -void DetectUricontentPrint(DetectContentData *); - -uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f, - HtpState *htp_state, uint8_t flags, - void *tx, uint64_t idx); - -#endif /* __DETECT_URICONTENT_H__ */ diff --git a/framework/src/suricata/src/detect-urilen.c b/framework/src/suricata/src/detect-urilen.c deleted file mode 100644 index 1355f559..00000000 --- a/framework/src/suricata/src/detect-urilen.c +++ /dev/null @@ -1,700 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - * Implements the urilen keyword - */ - -#include "suricata-common.h" -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-htp.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine-state.h" - -#include "detect-urilen.h" -#include "util-debug.h" -#include "util-byte.h" -#include "flow-util.h" -#include "stream-tcp.h" - -/** - * \brief Regex for parsing our urilen - */ -#define PARSE_REGEX "^(?:\\s*)(<|>)?(?:\\s*)([0-9]{1,5})(?:\\s*)(?:(<>)(?:\\s*)([0-9]{1,5}))?\\s*(?:,\\s*(norm|raw))?\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -/*prototypes*/ -static int DetectUrilenSetup (DetectEngineCtx *, Signature *, char *); -void DetectUrilenFree (void *); -void DetectUrilenRegisterTests (void); - -/** - * \brief Registration function for urilen: keyword - */ - -void DetectUrilenRegister(void) -{ - sigmatch_table[DETECT_AL_URILEN].name = "urilen"; - sigmatch_table[DETECT_AL_URILEN].desc = "match on the length of the HTTP uri"; - sigmatch_table[DETECT_AL_URILEN].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/HTTP-keywords#Urilen"; - sigmatch_table[DETECT_AL_URILEN].Match = NULL; - sigmatch_table[DETECT_AL_URILEN].alproto = ALPROTO_HTTP; - sigmatch_table[DETECT_AL_URILEN].AppLayerMatch = NULL /**< We handle this at detect-engine-uri.c now */; - sigmatch_table[DETECT_AL_URILEN].Setup = DetectUrilenSetup; - sigmatch_table[DETECT_AL_URILEN].Free = DetectUrilenFree; - sigmatch_table[DETECT_AL_URILEN].RegisterTests = DetectUrilenRegisterTests; - sigmatch_table[DETECT_AL_URILEN].flags |= SIGMATCH_PAYLOAD; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogDebug("pcre compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogDebug("pcre study failed: %s", eb); - goto error; - } - return; - -error: - if (parse_regex != NULL) - pcre_free(parse_regex); - if (parse_regex_study != NULL) - pcre_free_study(parse_regex_study); - return; -} - -/** - * \brief This function is used to parse urilen options passed via urilen: keyword - * - * \param urilenstr Pointer to the user provided urilen options - * - * \retval urilend pointer to DetectUrilenData on success - * \retval NULL on failure - */ - -DetectUrilenData *DetectUrilenParse (char *urilenstr) -{ - - DetectUrilenData *urilend = NULL; - char *arg1 = NULL; - char *arg2 = NULL; - char *arg3 = NULL; - char *arg4 = NULL; - char *arg5 = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, urilenstr, strlen(urilenstr), - 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 3 || ret > 6) { - SCLogError(SC_ERR_PCRE_PARSE, "urilen option pcre parse error: \"%s\"", urilenstr); - goto error; - } - const char *str_ptr; - - SCLogDebug("ret %d", ret); - - res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 1, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg1 = (char *) str_ptr; - SCLogDebug("Arg1 \"%s\"", arg1); - - res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 2, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg2 = (char *) str_ptr; - SCLogDebug("Arg2 \"%s\"", arg2); - - if (ret > 3) { - res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 3, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg3 = (char *) str_ptr; - SCLogDebug("Arg3 \"%s\"", arg3); - - if (ret > 4) { - res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 4, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg4 = (char *) str_ptr; - SCLogDebug("Arg4 \"%s\"", arg4); - } - if (ret > 5) { - res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 5, &str_ptr); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - arg5 = (char *) str_ptr; - SCLogDebug("Arg5 \"%s\"", arg5); - } - } - - urilend = SCMalloc(sizeof (DetectUrilenData)); - if (unlikely(urilend == NULL)) - goto error; - memset(urilend, 0, sizeof(DetectUrilenData)); - - if (arg1[0] == '<') - urilend->mode = DETECT_URILEN_LT; - else if (arg1[0] == '>') - urilend->mode = DETECT_URILEN_GT; - else - urilend->mode = DETECT_URILEN_EQ; - - if (arg3 != NULL && strcmp("<>", arg3) == 0) { - if (strlen(arg1) != 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Range specified but mode also set"); - goto error; - } - urilend->mode = DETECT_URILEN_RA; - } - - /** set the first urilen value */ - if (ByteExtractStringUint16(&urilend->urilen1,10,strlen(arg2),arg2) <= 0){ - SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size :\"%s\"",arg2); - goto error; - } - - /** set the second urilen value if specified */ - if (arg4 != NULL && strlen(arg4) > 0) { - if (urilend->mode != DETECT_URILEN_RA) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Multiple urilen values specified" - " but mode is not range"); - goto error; - } - - if(ByteExtractStringUint16(&urilend->urilen2,10,strlen(arg4),arg4) <= 0) - { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size :\"%s\"",arg4); - goto error; - } - - if (urilend->urilen2 <= urilend->urilen1){ - SCLogError(SC_ERR_INVALID_ARGUMENT,"urilen2:%"PRIu16" <= urilen:" - "%"PRIu16"",urilend->urilen2,urilend->urilen1); - goto error; - } - } - - if (arg5 != NULL) { - if (strcasecmp("raw", arg5) == 0) { - urilend->raw_buffer = 1; - } - } - - pcre_free_substring(arg1); - pcre_free_substring(arg2); - if (arg3 != NULL) - pcre_free_substring(arg3); - if (arg4 != NULL) - pcre_free_substring(arg4); - if (arg5 != NULL) - pcre_free_substring(arg5); - return urilend; - -error: - if (urilend) - SCFree(urilend); - if (arg1 != NULL) - SCFree(arg1); - if (arg2 != NULL) - SCFree(arg2); - if (arg3 != NULL) - SCFree(arg3); - if (arg4 != NULL) - SCFree(arg4); - return NULL; -} - -/** - * \brief this function is used to parse urilen data into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param urilenstr pointer to the user provided urilen options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -static int DetectUrilenSetup (DetectEngineCtx *de_ctx, Signature *s, char *urilenstr) -{ - SCEnter(); - DetectUrilenData *urilend = NULL; - SigMatch *sm = NULL; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains a non http " - "alproto set"); - goto error; - } - - urilend = DetectUrilenParse(urilenstr); - if (urilend == NULL) - goto error; - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - sm->type = DETECT_AL_URILEN; - sm->ctx = (void *)urilend; - - if (urilend->raw_buffer) - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_HRUDMATCH); - else - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_UMATCH); - - /* Flagged the signature as to inspect the app layer data */ - s->flags |= SIG_FLAG_APPLAYER; - s->alproto = ALPROTO_HTTP; - - SCReturnInt(0); - -error: - DetectUrilenFree(urilend); - SCReturnInt(-1); -} - -/** - * \brief this function will free memory associated with DetectUrilenData - * - * \param ptr pointer to DetectUrilenData - */ -void DetectUrilenFree(void *ptr) -{ - if (ptr == NULL) - return; - - DetectUrilenData *urilend = (DetectUrilenData *)ptr; - SCFree(urilend); -} - -#ifdef UNITTESTS - -#include "stream.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "app-layer-parser.h" - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest01(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse("10"); - if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_EQ && - !urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest02(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse(" < 10 "); - if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT && - !urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest03(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse(" > 10 "); - if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT && - !urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest04(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse(" 5 <> 10 "); - if (urilend != NULL) { - if (urilend->urilen1 == 5 && urilend->urilen2 == 10 && - urilend->mode == DETECT_URILEN_RA && - !urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest05(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse("5<>10,norm"); - if (urilend != NULL) { - if (urilend->urilen1 == 5 && urilend->urilen2 == 10 && - urilend->mode == DETECT_URILEN_RA && - !urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest06(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse("5<>10,raw"); - if (urilend != NULL) { - if (urilend->urilen1 == 5 && urilend->urilen2 == 10 && - urilend->mode == DETECT_URILEN_RA && - urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest07(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse(">10, norm "); - if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT && - !urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest08(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse("<10, norm "); - if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT && - !urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest09(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse(">10, raw "); - if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_GT && - urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** \test Test the Urilen keyword setup */ -static int DetectUrilenParseTest10(void) -{ - int ret = 0; - DetectUrilenData *urilend = NULL; - - urilend = DetectUrilenParse("<10, raw "); - if (urilend != NULL) { - if (urilend->urilen1 == 10 && urilend->mode == DETECT_URILEN_LT && - urilend->raw_buffer) - ret = 1; - - DetectUrilenFree(urilend); - } - return ret; -} - -/** - * \brief this function is used to initialize the detection engine context and - * setup the signature with passed values. - * - */ - -static int DetectUrilenInitTest(DetectEngineCtx **de_ctx, Signature **sig, - DetectUrilenData **urilend, char *str) -{ - char fullstr[1024]; - int result = 0; - - *de_ctx = NULL; - *sig = NULL; - - if (snprintf(fullstr, 1024, "alert ip any any -> any any (msg:\"Urilen " - "test\"; urilen:%s; sid:1;)", str) >= 1024) { - goto end; - } - - *de_ctx = DetectEngineCtxInit(); - if (*de_ctx == NULL) { - goto end; - } - - (*de_ctx)->flags |= DE_QUIET; - - (*de_ctx)->sig_list = SigInit(*de_ctx, fullstr); - if ((*de_ctx)->sig_list == NULL) { - goto end; - } - - *sig = (*de_ctx)->sig_list; - - *urilend = DetectUrilenParse(str); - - result = 1; - -end: - return result; -} - -/** - * \test DetectUrilenSetpTest01 is a test for setting up an valid urilen values - * with valid "<>" operator and include spaces arround the given values. - * In the test the values are setup with initializing the detection engine - * context and setting up the signature itself. - */ - -static int DetectUrilenSetpTest01(void) -{ - - DetectUrilenData *urilend = NULL; - uint8_t res = 0; - Signature *sig = NULL; - DetectEngineCtx *de_ctx = NULL; - - res = DetectUrilenInitTest(&de_ctx, &sig, &urilend, "1 <> 2 "); - if (res == 0) { - goto end; - } - - if(urilend == NULL) - goto cleanup; - - if (urilend != NULL) { - if (urilend->urilen1 == 1 && urilend->urilen2 == 2 && - urilend->mode == DETECT_URILEN_RA) - res = 1; - } - -cleanup: - if (urilend) SCFree(urilend); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); -end: - return res; -} - -/** \test Check a signature with gievn urilen */ -static int DetectUrilenSigTest01(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST /suricata HTTP/1.0\r\n" - "Host: foo.bar.tld\r\n" - "\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing urilen\"; " - "urilen: <5; sid:1;)"); - if (s == NULL) { - goto end; - } - - s = s->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(msg:\"Testing http_method\"; " - "urilen: >5; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, httpbuf1, httplen1); - if (r != 0) { - SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - HtpState *htp_state = f.alstate; - if (htp_state == NULL) { - SCLogDebug("no http state: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - printf("sid 1 alerted, but should not have: \n"); - goto end; - } - if (!PacketAlertCheck(p, 2)) { - printf("sid 2 did not alerted, but should have: \n"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - if (de_ctx != NULL) SigCleanSignatures(de_ctx); - if (de_ctx != NULL) DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectUrilen - */ -void DetectUrilenRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectUrilenParseTest01", DetectUrilenParseTest01, 1); - UtRegisterTest("DetectUrilenParseTest02", DetectUrilenParseTest02, 1); - UtRegisterTest("DetectUrilenParseTest03", DetectUrilenParseTest03, 1); - UtRegisterTest("DetectUrilenParseTest04", DetectUrilenParseTest04, 1); - UtRegisterTest("DetectUrilenParseTest05", DetectUrilenParseTest05, 1); - UtRegisterTest("DetectUrilenParseTest06", DetectUrilenParseTest06, 1); - UtRegisterTest("DetectUrilenParseTest07", DetectUrilenParseTest07, 1); - UtRegisterTest("DetectUrilenParseTest08", DetectUrilenParseTest08, 1); - UtRegisterTest("DetectUrilenParseTest09", DetectUrilenParseTest09, 1); - UtRegisterTest("DetectUrilenParseTest10", DetectUrilenParseTest10, 1); - UtRegisterTest("DetectUrilenSetpTest01", DetectUrilenSetpTest01, 1); - UtRegisterTest("DetectUrilenSigTest01", DetectUrilenSigTest01, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-urilen.h b/framework/src/suricata/src/detect-urilen.h deleted file mode 100644 index c853011d..00000000 --- a/framework/src/suricata/src/detect-urilen.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - */ - -#ifndef _DETECT_URILEN_H -#define _DETECT_URILEN_H - -#define DETECT_URILEN_LT 0 /**< "less than" operator */ -#define DETECT_URILEN_GT 1 /**< "greater than" operator */ -#define DETECT_URILEN_RA 2 /**< range operator */ -#define DETECT_URILEN_EQ 3 /**< equal operator */ - -typedef struct DetectUrilenData_ { - uint16_t urilen1; /**< 1st Uri Length value in the signature*/ - uint16_t urilen2; /**< 2nd Uri Length value in the signature*/ - uint8_t mode; /**< operator used in the signature */ - uint8_t raw_buffer; -}DetectUrilenData; - -int DetectUrilenMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t, void *, Signature *, SigMatch *); -void DetectUrilenRegister(void); - -#endif /* _DETECT_URILEN_H */ - diff --git a/framework/src/suricata/src/detect-window.c b/framework/src/suricata/src/detect-window.c deleted file mode 100644 index 0fb1afb8..00000000 --- a/framework/src/suricata/src/detect-window.c +++ /dev/null @@ -1,367 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * Implements the window keyword. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-window.h" -#include "flow.h" -#include "flow-var.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-byte.h" - -/** - * \brief Regex for parsing our window option - */ -#define PARSE_REGEX "^\\s*([!])?\\s*([0-9]{1,9}+)\\s*$" - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectWindowMatch(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -int DetectWindowSetup(DetectEngineCtx *, Signature *, char *); -void DetectWindowRegisterTests(void); -void DetectWindowFree(void *); - -/** - * \brief Registration function for window: keyword - */ -void DetectWindowRegister (void) -{ - sigmatch_table[DETECT_WINDOW].name = "window"; - sigmatch_table[DETECT_WINDOW].desc = "check for a specific TCP window size"; - sigmatch_table[DETECT_WINDOW].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords#Window"; - sigmatch_table[DETECT_WINDOW].Match = DetectWindowMatch; - sigmatch_table[DETECT_WINDOW].Setup = DetectWindowSetup; - sigmatch_table[DETECT_WINDOW].Free = DetectWindowFree; - sigmatch_table[DETECT_WINDOW].RegisterTests = DetectWindowRegisterTests; - - const char *eb; - int eo; - int opts = 0; - - #ifdef WINDOW_DEBUG - printf("detect-window: Registering window rule option\n"); - #endif - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - return; - -error: - /* XXX */ - return; -} - -/** - * \brief This function is used to match the window size on a packet - * - * \param t pointer to thread vars - * \param det_ctx pointer to the pattern matcher thread - * \param p pointer to the current packet - * \param m pointer to the sigmatch that we will cast into DetectWindowData - * - * \retval 0 no match - * \retval 1 match - */ -int DetectWindowMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectWindowData *wd = (const DetectWindowData *)ctx; - - if ( !(PKT_IS_TCP(p)) || wd == NULL || PKT_IS_PSEUDOPKT(p)) { - return 0; - } - - if ( (!wd->negated && wd->size == TCP_GET_WINDOW(p)) || (wd->negated && wd->size != TCP_GET_WINDOW(p))) { - return 1; - } - - return 0; -} - -/** - * \brief This function is used to parse window options passed via window: keyword - * - * \param windowstr Pointer to the user provided window options (negation! and size) - * - * \retval wd pointer to DetectWindowData on success - * \retval NULL on failure - */ -DetectWindowData *DetectWindowParse(char *windowstr) -{ - DetectWindowData *wd = NULL; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(parse_regex, parse_regex_study, windowstr, strlen(windowstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 1 || ret > 3) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, windowstr); - goto error; - } - - wd = SCMalloc(sizeof(DetectWindowData)); - if (unlikely(wd == NULL)) - goto error; - - if (ret > 1) { - char copy_str[128] = ""; - res = pcre_copy_substring((char *)windowstr, ov, MAX_SUBSTRINGS, 1, - copy_str, sizeof(copy_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - /* Detect if it's negated */ - if (copy_str[0] == '!') - wd->negated = 1; - else - wd->negated = 0; - - if (ret > 2) { - res = pcre_copy_substring((char *)windowstr, ov, MAX_SUBSTRINGS, 2, - copy_str, sizeof(copy_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - /* Get the window size if it's a valid value (in packets, we - * should alert if this doesn't happend from decode) */ - if (-1 == ByteExtractStringUint16(&wd->size, 10, 0, copy_str)) { - goto error; - } - } - } - - return wd; - -error: - if (wd != NULL) - DetectWindowFree(wd); - return NULL; - -} - -/** - * \brief this function is used to add the parsed window sizedata into the current signature - * - * \param de_ctx pointer to the Detection Engine Context - * \param s pointer to the Current Signature - * \param windowstr pointer to the user provided window options - * - * \retval 0 on Success - * \retval -1 on Failure - */ -int DetectWindowSetup (DetectEngineCtx *de_ctx, Signature *s, char *windowstr) -{ - DetectWindowData *wd = NULL; - SigMatch *sm = NULL; - - wd = DetectWindowParse(windowstr); - if (wd == NULL) goto error; - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_WINDOW; - sm->ctx = (SigMatchCtx *)wd; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - s->flags |= SIG_FLAG_REQUIRE_PACKET; - - return 0; - -error: - if (wd != NULL) DetectWindowFree(wd); - if (sm != NULL) SCFree(sm); - return -1; - -} - -/** - * \brief this function will free memory associated with DetectWindowData - * - * \param wd pointer to DetectWindowData - */ -void DetectWindowFree(void *ptr) -{ - DetectWindowData *wd = (DetectWindowData *)ptr; - SCFree(wd); -} - -#ifdef UNITTESTS /* UNITTESTS */ - -/** - * \test DetectWindowTestParse01 is a test to make sure that we set the size correctly - * when given valid window opt - */ -int DetectWindowTestParse01 (void) -{ - int result = 0; - DetectWindowData *wd = NULL; - wd = DetectWindowParse("35402"); - if (wd != NULL &&wd->size==35402) { - DetectWindowFree(wd); - result = 1; - } - - return result; -} - -/** - * \test DetectWindowTestParse02 is a test for setting the window opt negated - */ -int DetectWindowTestParse02 (void) -{ - int result = 0; - DetectWindowData *wd = NULL; - wd = DetectWindowParse("!35402"); - if (wd != NULL) { - if (wd->negated == 1 && wd->size==35402) { - result = 1; - } else { - printf("expected wd->negated=1 and wd->size=35402\n"); - } - DetectWindowFree(wd); - } - - return result; -} - -/** - * \test DetectWindowTestParse03 is a test to check for an empty value - */ -int DetectWindowTestParse03 (void) -{ - int result = 0; - DetectWindowData *wd = NULL; - wd = DetectWindowParse(""); - if (wd == NULL) { - result = 1; - } else { - printf("expected a NULL pointer (It was an empty string)\n"); - } - DetectWindowFree(wd); - - return result; -} - -/** - * \test DetectWindowTestParse03 is a test to check for a big value - */ -int DetectWindowTestParse04 (void) -{ - int result = 0; - DetectWindowData *wd = NULL; - wd = DetectWindowParse("1235402"); - if (wd != NULL) { - printf("expected a NULL pointer (It was exceeding the MAX window size)\n"); - DetectWindowFree(wd); - }else - result=1; - - return result; -} - -/** - * \test DetectWindowTestPacket01 is a test to check window with constructed packets - */ -int DetectWindowTestPacket01 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[1] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p[2] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_ICMP); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - /* TCP wwindow = 40 */ - p[0]->tcph->th_win = htons(40); - - /* TCP window = 41 */ - p[1]->tcph->th_win = htons(41); - - char *sigs[2]; - sigs[0]= "alert tcp any any -> any any (msg:\"Testing window 1\"; window:40; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"Testing window 2\"; window:41; sid:2;)"; - - uint32_t sid[2] = {1, 2}; - - uint32_t results[3][2] = { - /* packet 0 match sid 1 but should not match sid 2 */ - {1, 0}, - /* packet 1 should not match */ - {0, 1}, - /* packet 2 should not match */ - {0, 0} }; - result = UTHGenericTest(p, 3, sigs, sid, (uint32_t *) results, 2); - - UTHFreePackets(p, 3); -end: - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectWindow - */ -void DetectWindowRegisterTests(void) -{ - #ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectWindowTestParse01", DetectWindowTestParse01, 1); - UtRegisterTest("DetectWindowTestParse02", DetectWindowTestParse02, 1); - UtRegisterTest("DetectWindowTestParse03", DetectWindowTestParse03, 1); - UtRegisterTest("DetectWindowTestParse04", DetectWindowTestParse04, 1); - UtRegisterTest("DetectWindowTestPacket01" , DetectWindowTestPacket01 , 1); - #endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-window.h b/framework/src/suricata/src/detect-window.h deleted file mode 100644 index c51bbae3..00000000 --- a/framework/src/suricata/src/detect-window.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __DETECT_WINDOW_H__ -#define __DETECT_WINDOW_H__ - -#define MIN_WINDOW_VALUE 0 -#define MAX_WINDOW_VALUE 65535 - -typedef struct DetectWindowData_ { - uint8_t negated; /** negated? 1=True : 0=False */ - uint16_t size; /** window size to match */ -} DetectWindowData; - -/* prototypes */ -void DetectWindowRegister (void); - -#endif /* __DETECT_WINDOW_H__ */ - diff --git a/framework/src/suricata/src/detect-within.c b/framework/src/suricata/src/detect-within.c deleted file mode 100644 index 25c97238..00000000 --- a/framework/src/suricata/src/detect-within.c +++ /dev/null @@ -1,292 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * Implements the within keyword - */ - -#include "suricata-common.h" - -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-bytejump.h" -#include "detect-byte-extract.h" -#include "app-layer.h" -#include "detect-parse.h" - -#include "flow-var.h" - -#include "util-debug.h" -#include "detect-pcre.h" -#include "util-unittest.h" - -static int DetectWithinSetup(DetectEngineCtx *, Signature *, char *); -void DetectWithinRegisterTests(void); - -void DetectWithinRegister(void) -{ - sigmatch_table[DETECT_WITHIN].name = "within"; - sigmatch_table[DETECT_WITHIN].desc = "indicate that this content match has to be within a certain distance of the previous content keyword match"; - sigmatch_table[DETECT_WITHIN].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Payload_keywords#Within"; - sigmatch_table[DETECT_WITHIN].Match = NULL; - sigmatch_table[DETECT_WITHIN].Setup = DetectWithinSetup; - sigmatch_table[DETECT_WITHIN].Free = NULL; - sigmatch_table[DETECT_WITHIN].RegisterTests = DetectWithinRegisterTests; - - sigmatch_table[DETECT_WITHIN].flags |= SIGMATCH_PAYLOAD; -} - -/** \brief Setup within pattern (content/uricontent) modifier. - * - * \todo apply to uricontent - * - * \retval 0 ok - * \retval -1 error, sig needs to be invalidated - */ -static int DetectWithinSetup(DetectEngineCtx *de_ctx, Signature *s, char *withinstr) -{ - char *str = withinstr; - char dubbed = 0; - SigMatch *pm = NULL; - int ret = -1; - - /* strip "'s */ - if (withinstr[0] == '\"' && withinstr[strlen(withinstr)-1] == '\"') { - str = SCStrdup(withinstr+1); - if (unlikely(str == NULL)) - goto end; - str[strlen(withinstr) - 2] = '\0'; - dubbed = 1; - } - - /* retrive the sm to apply the depth against */ - if (s->list != DETECT_SM_LIST_NOTSET) { - pm = SigMatchGetLastSMFromLists(s, 2, DETECT_CONTENT, s->sm_lists_tail[s->list]); - } else { - pm = SigMatchGetLastSMFromLists(s, 28, - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRUDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_FILEDATA], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSCDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HSMDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HUADMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HHHDMATCH], - DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_HRHHDMATCH]); - } - if (pm == NULL) { - SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "within needs " - "preceding content, uricontent option, http_client_body, " - "http_server_body, http_header option, http_raw_header option, " - "http_method option, http_cookie, http_raw_uri, " - "http_stat_msg, http_stat_code, http_user_agent or " - "file_data/dce_stub_data sticky buffer option"); - goto end; - } - - - /* verify other conditions */ - DetectContentData *cd = (DetectContentData *)pm->ctx; - if (cd->flags & DETECT_CONTENT_WITHIN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple withins for the same content."); - goto end; - } - if ((cd->flags & DETECT_CONTENT_DEPTH) || (cd->flags & DETECT_CONTENT_OFFSET)) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use a relative " - "keyword like within/distance with a absolute " - "relative keyword like depth/offset for the same " - "content." ); - goto end; - } - if (cd->flags & DETECT_CONTENT_NEGATED && cd->flags & DETECT_CONTENT_FAST_PATTERN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " - "negated keyword set along with a fast_pattern"); - goto end; - } - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "can't have a relative " - "keyword set along with a fast_pattern:only;"); - goto end; - } - if (str[0] != '-' && isalpha((unsigned char)str[0])) { - SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(str, s); - if (bed_sm == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "unknown byte_extract var " - "seen in within - %s\n", str); - goto end; - } - cd->within = ((DetectByteExtractData *)bed_sm->ctx)->local_id; - cd->flags |= DETECT_CONTENT_WITHIN_BE; - } else { - cd->within = strtol(str, NULL, 10); - if (cd->within < (int32_t)cd->content_len) { - SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is " - "less than the content length \"%"PRIu32"\" which is invalid, since " - "this will never match. Invalidating signature", cd->within, - cd->content_len); - goto end; - } - } - cd->flags |= DETECT_CONTENT_WITHIN; - - /* these are the only ones against which we set a flag. We have other - * relative keywords like byttest, isdataat, bytejump, but we don't - * set a flag against them */ - SigMatch *prev_pm = SigMatchGetLastSMFromLists(s, 4, - DETECT_CONTENT, pm->prev, - DETECT_PCRE, pm->prev); - if (prev_pm == NULL) { - ret = 0; - goto end; - } - if (prev_pm->type == DETECT_CONTENT) { - DetectContentData *cd = (DetectContentData *)prev_pm->ctx; - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "previous keyword " - "has a fast_pattern:only; set. Can't " - "have relative keywords around a fast_pattern " - "only content"); - goto end; - } - cd->flags |= DETECT_CONTENT_RELATIVE_NEXT; - } else if (prev_pm->type == DETECT_PCRE) { - DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx; - pd->flags |= DETECT_PCRE_RELATIVE_NEXT; - } - - ret = 0; - end: - if (dubbed) - SCFree(str); - return ret; -} - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS -#include "util-unittest-helper.h" - /** - * \test DetectWithinTestPacket01 is a test to check matches of - * within, if the previous keyword is pcre (bug 145) - */ -int DetectWithinTestPacket01 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0" - "User-Agent: Wget/1.11.4" - "Accept: */*" - "Host: www.google.com" - "Connection: Keep-Alive" - "Date: Mon, 04 Jan 2010 17:29:39 GMT"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre with within " - "modifier\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\";" - " content:\"HTTP\"; within:5; sid:49; rev:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} - - -int DetectWithinTestPacket02 (void) -{ - int result = 0; - uint8_t *buf = (uint8_t *)"Zero Five Ten Fourteen"; - uint16_t buflen = strlen((char *)buf); - Packet *p; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - if (p == NULL) - goto end; - - char sig[] = "alert tcp any any -> any any (msg:\"pcre with within " - "modifier\"; content:\"Five\"; content:\"Ten\"; within:3; distance:1; sid:1;)"; - - result = UTHPacketMatchSig(p, sig); - - UTHFreePacket(p); -end: - return result; -} - -static int DetectWithinTestVarSetup(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - char sig[] = "alert tcp any any -> any any ( " - "msg:\"test rule\"; " - "content:\"abc\"; " - "http_client_body; " - "byte_extract:2,0,somevar,relative; " - "content:\"def\"; " - "within:somevar; " - "http_client_body; " - "sid:4; rev:1;)"; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->sig_list = SigInit(de_ctx, sig); - if (de_ctx->sig_list == NULL) { - goto end; - } - - result = 1; - -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -#endif /* UNITTESTS */ - -void DetectWithinRegisterTests(void) -{ - #ifdef UNITTESTS - UtRegisterTest("DetectWithinTestPacket01", DetectWithinTestPacket01, 1); - UtRegisterTest("DetectWithinTestPacket02", DetectWithinTestPacket02, 1); - UtRegisterTest("DetectWithinTestVarSetup", DetectWithinTestVarSetup, 1); - #endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-within.h b/framework/src/suricata/src/detect-within.h deleted file mode 100644 index 7ccaf264..00000000 --- a/framework/src/suricata/src/detect-within.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_WITHIN_H__ -#define __DETECT_WITHIN_H__ - -/* prototypes */ -void DetectWithinRegister (void); - -#endif /* __DETECT_WITHIN_H__ */ - diff --git a/framework/src/suricata/src/detect-xbits.c b/framework/src/suricata/src/detect-xbits.c deleted file mode 100644 index 876ddc36..00000000 --- a/framework/src/suricata/src/detect-xbits.c +++ /dev/null @@ -1,545 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements the xbits keyword - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "threads.h" -#include "flow.h" -#include "flow-util.h" -#include "detect-xbits.h" -#include "detect-hostbits.h" -#include "util-spm.h" - -#include "detect-engine-sigorder.h" - -#include "app-layer-parser.h" - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow-bit.h" -#include "host-bit.h" -#include "ippair-bit.h" -#include "util-var-name.h" -#include "util-unittest.h" -#include "util-debug.h" - -/* - xbits:set,bitname,track ip_pair,expire 60 - */ - -#define PARSE_REGEX "([a-z]+)" "(?:,\\s*([^,]+))?" "(?:,\\s*(?:track\\s+([^,]+)))" "(?:,\\s*(?:expire\\s+([^,]+)))?" -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -int DetectXbitMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); -static int DetectXbitSetup (DetectEngineCtx *, Signature *, char *); -void DetectXbitFree (void *); -void XBitsRegisterTests(void); - -void DetectXbitsRegister (void) -{ - sigmatch_table[DETECT_XBITS].name = "xbits"; - sigmatch_table[DETECT_XBITS].desc = "operate on bits"; -// sigmatch_table[DETECT_XBITS].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Flow-keywords#Flowbits"; - sigmatch_table[DETECT_XBITS].Match = DetectXbitMatch; - sigmatch_table[DETECT_XBITS].Setup = DetectXbitSetup; - sigmatch_table[DETECT_XBITS].Free = DetectXbitFree; - sigmatch_table[DETECT_XBITS].RegisterTests = XBitsRegisterTests; - /* this is compatible to ip-only signatures */ - sigmatch_table[DETECT_XBITS].flags |= SIGMATCH_IPONLY_COMPAT; - - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", PARSE_REGEX, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - return; - -error: - return; -} - -static int DetectIPPairbitMatchToggle (Packet *p, const DetectXbitsData *fd) -{ - IPPair *pair = IPPairGetIPPairFromHash(&p->src, &p->dst); - if (pair == NULL) - return 0; - - IPPairBitToggle(pair,fd->idx,p->ts.tv_sec + fd->expire); - IPPairRelease(pair); - return 1; -} - -/* return true even if bit not found */ -static int DetectIPPairbitMatchUnset (Packet *p, const DetectXbitsData *fd) -{ - IPPair *pair = IPPairLookupIPPairFromHash(&p->src, &p->dst); - if (pair == NULL) - return 1; - - IPPairBitUnset(pair,fd->idx); - IPPairRelease(pair); - return 1; -} - -static int DetectIPPairbitMatchSet (Packet *p, const DetectXbitsData *fd) -{ - IPPair *pair = IPPairGetIPPairFromHash(&p->src, &p->dst); - if (pair == NULL) - return 0; - - IPPairBitSet(pair, fd->idx, p->ts.tv_sec + fd->expire); - IPPairRelease(pair); - return 1; -} - -static int DetectIPPairbitMatchIsset (Packet *p, const DetectXbitsData *fd) -{ - int r = 0; - IPPair *pair = IPPairLookupIPPairFromHash(&p->src, &p->dst); - if (pair == NULL) - return 0; - - r = IPPairBitIsset(pair,fd->idx,p->ts.tv_sec); - IPPairRelease(pair); - return r; -} - -static int DetectIPPairbitMatchIsnotset (Packet *p, const DetectXbitsData *fd) -{ - int r = 0; - IPPair *pair = IPPairLookupIPPairFromHash(&p->src, &p->dst); - if (pair == NULL) - return 1; - - r = IPPairBitIsnotset(pair,fd->idx,p->ts.tv_sec); - IPPairRelease(pair); - return r; -} - -static int DetectXbitMatchIPPair(Packet *p, const DetectXbitsData *xd) -{ - switch (xd->cmd) { - case DETECT_XBITS_CMD_ISSET: - return DetectIPPairbitMatchIsset(p,xd); - case DETECT_XBITS_CMD_ISNOTSET: - return DetectIPPairbitMatchIsnotset(p,xd); - case DETECT_XBITS_CMD_SET: - return DetectIPPairbitMatchSet(p,xd); - case DETECT_XBITS_CMD_UNSET: - return DetectIPPairbitMatchUnset(p,xd); - case DETECT_XBITS_CMD_TOGGLE: - return DetectIPPairbitMatchToggle(p,xd); - default: - SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown cmd %" PRIu32 "", xd->cmd); - return 0; - } - return 0; -} - -/* - * returns 0: no match - * 1: match - * -1: error - */ - -int DetectXbitMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, const SigMatchCtx *ctx) -{ - const DetectXbitsData *fd = (const DetectXbitsData *)ctx; - if (fd == NULL) - return 0; - - switch (fd->type) { - case VAR_TYPE_HOST_BIT: - return DetectXbitMatchHost(p, (const DetectXbitsData *)fd); - break; - case VAR_TYPE_IPPAIR_BIT: - return DetectXbitMatchIPPair(p, (const DetectXbitsData *)fd); - break; - default: - break; - } - return 0; -} - -int DetectXbitSetup (DetectEngineCtx *de_ctx, Signature *s, char *rawstr) -{ - DetectXbitsData *cd = NULL; - SigMatch *sm = NULL; - uint8_t fb_cmd = 0; - uint8_t hb_dir = 0; -#define MAX_SUBSTRINGS 30 - int ret = 0, res = 0; - int ov[MAX_SUBSTRINGS]; - char fb_cmd_str[16] = "", fb_name[256] = ""; - char hb_dir_str[16] = ""; - enum VarTypes var_type = VAR_TYPE_NOT_SET; - int expire = 30; - - ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret != 2 && ret != 3 && ret != 4 && ret != 5) { - SCLogError(SC_ERR_PCRE_MATCH, "\"%s\" is not a valid setting for xbits.", rawstr); - return -1; - } - SCLogDebug("ret %d, %s", ret, rawstr); - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, fb_cmd_str, sizeof(fb_cmd_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - return -1; - } - - if (ret >= 3) { - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, fb_name, sizeof(fb_name)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - if (ret >= 4) { - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, hb_dir_str, sizeof(hb_dir_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - SCLogDebug("hb_dir_str %s", hb_dir_str); - if (strlen(hb_dir_str) > 0) { - if (strcmp(hb_dir_str, "ip_src") == 0) { - hb_dir = DETECT_XBITS_TRACK_IPSRC; - var_type = VAR_TYPE_HOST_BIT; - } else if (strcmp(hb_dir_str, "ip_dst") == 0) { - hb_dir = DETECT_XBITS_TRACK_IPDST; - var_type = VAR_TYPE_HOST_BIT; - } else if (strcmp(hb_dir_str, "ip_pair") == 0) { - hb_dir = DETECT_XBITS_TRACK_IPPAIR; - var_type = VAR_TYPE_IPPAIR_BIT; - } else { - // TODO - goto error; - } - } - - if (ret >= 5) { - char expire_str[16] = ""; - res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 4, expire_str, sizeof(expire_str)); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - SCLogDebug("expire_str %s", expire_str); - expire = atoi(expire_str); - SCLogDebug("expire %d", expire); - } - } - } - - if (strcmp(fb_cmd_str,"noalert") == 0) { - fb_cmd = DETECT_XBITS_CMD_NOALERT; - } else if (strcmp(fb_cmd_str,"isset") == 0) { - fb_cmd = DETECT_XBITS_CMD_ISSET; - } else if (strcmp(fb_cmd_str,"isnotset") == 0) { - fb_cmd = DETECT_XBITS_CMD_ISNOTSET; - } else if (strcmp(fb_cmd_str,"set") == 0) { - fb_cmd = DETECT_XBITS_CMD_SET; - } else if (strcmp(fb_cmd_str,"unset") == 0) { - fb_cmd = DETECT_XBITS_CMD_UNSET; - } else if (strcmp(fb_cmd_str,"toggle") == 0) { - fb_cmd = DETECT_XBITS_CMD_TOGGLE; - } else { - SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: flowbits action \"%s\" is not supported.", fb_cmd_str); - goto error; - } - - switch (fb_cmd) { - case DETECT_XBITS_CMD_NOALERT: - if (strlen(fb_name) != 0) - goto error; - s->flags |= SIG_FLAG_NOALERT; - return 0; - case DETECT_XBITS_CMD_ISNOTSET: - case DETECT_XBITS_CMD_ISSET: - case DETECT_XBITS_CMD_SET: - case DETECT_XBITS_CMD_UNSET: - case DETECT_XBITS_CMD_TOGGLE: - default: - if (strlen(fb_name) == 0) - goto error; - break; - } - - cd = SCMalloc(sizeof(DetectXbitsData)); - if (unlikely(cd == NULL)) - goto error; - - cd->idx = VariableNameGetIdx(de_ctx, fb_name, var_type); - cd->cmd = fb_cmd; - cd->tracker = hb_dir; - cd->type = var_type; - cd->expire = expire; - - SCLogDebug("idx %" PRIu32 ", cmd %s, name %s", - cd->idx, fb_cmd_str, strlen(fb_name) ? fb_name : "(none)"); - - /* Okay so far so good, lets get this into a SigMatch - * and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_XBITS; - sm->ctx = (void *)cd; - - switch (fb_cmd) { - /* case DETECT_XBITS_CMD_NOALERT can't happen here */ - - case DETECT_XBITS_CMD_ISNOTSET: - case DETECT_XBITS_CMD_ISSET: - /* checks, so packet list */ - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); - break; - - case DETECT_XBITS_CMD_SET: - case DETECT_XBITS_CMD_UNSET: - case DETECT_XBITS_CMD_TOGGLE: - /* modifiers, only run when entire sig has matched */ - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_POSTMATCH); - break; - } - - return 0; - -error: - if (cd != NULL) - SCFree(cd); - if (sm != NULL) - SCFree(sm); - return -1; -} - -void DetectXbitFree (void *ptr) -{ - DetectXbitsData *fd = (DetectXbitsData *)ptr; - - if (fd == NULL) - return; - - SCFree(fd); -} - -#ifdef UNITTESTS - -static void XBitsTestSetup(void) -{ - StorageInit(); - HostBitInitCtx(); - IPPairBitInitCtx(); - StorageFinalize(); - HostInitConfig(TRUE); - IPPairInitConfig(TRUE); -} - -static void XBitsTestShutdown(void) -{ - HostCleanup(); - IPPairCleanup(); - StorageCleanup(); -} - -/** - * \test HostBitsTestSig01 is a test for a valid noalert flowbits option - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int XBitsTestSig01(void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - XBitsTestSetup(); - - de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - printf("bad de_ctx: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (xbits:set,abc,track ip_pair; content:\"GET \"; sid:1;)"); - if (s == NULL) { - printf("bad sig: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - result = 1; - -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - XBitsTestShutdown(); - - SCFree(p); - return result; -} - -/** - * \test various options - * - * \retval 1 on succces - * \retval 0 on failure - */ - -static int XBitsTestSig02(void) -{ - Signature *s = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - int result = 0; - int error_count = 0; - - memset(&th_v, 0, sizeof(th_v)); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (xbits:isset,abc,track ip_src; content:\"GET \"; sid:1;)"); - if (s == NULL) { - error_count++; - } - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (xbits:isnotset,abc,track ip_dst; content:\"GET \"; sid:2;)"); - if (s == NULL) { - error_count++; - } - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (xbits:set,abc,track ip_pair; content:\"GET \"; sid:3;)"); - if (s == NULL) { - error_count++; - } - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (xbits:unset,abc,track ip_src; content:\"GET \"; sid:4;)"); - if (s == NULL) { - error_count++; - } - - s = DetectEngineAppendSig(de_ctx, - "alert ip any any -> any any (xbits:toggle,abc,track ip_dst; content:\"GET \"; sid:5;)"); - if (s == NULL) { - error_count++; - } - - if (error_count != 0) - goto end; - - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for XBits - */ -void XBitsRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("XBitsTestSig01", XBitsTestSig01, 1); - UtRegisterTest("XBitsTestSig02", XBitsTestSig02, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/detect-xbits.h b/framework/src/suricata/src/detect-xbits.h deleted file mode 100644 index 477aab8c..00000000 --- a/framework/src/suricata/src/detect-xbits.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_XBITS_H__ -#define __DETECT_XBITS_H__ - -#define DETECT_XBITS_CMD_SET 0 -#define DETECT_XBITS_CMD_TOGGLE 1 -#define DETECT_XBITS_CMD_UNSET 2 -#define DETECT_XBITS_CMD_ISNOTSET 3 -#define DETECT_XBITS_CMD_ISSET 4 -#define DETECT_XBITS_CMD_NOALERT 5 -#define DETECT_XBITS_CMD_MAX 6 - -#define DETECT_XBITS_TRACK_IPSRC 0 -#define DETECT_XBITS_TRACK_IPDST 1 -#define DETECT_XBITS_TRACK_IPPAIR 2 -#define DETECT_XBITS_TRACK_FLOW 3 - -typedef struct DetectXbitsData_ { - uint16_t idx; - uint8_t cmd; - uint8_t tracker; - uint32_t expire; - /** data type: host/ippair/flow used for sig sorting in sigorder */ - enum VarTypes type; -} DetectXbitsData; - -/* prototypes */ -void DetectXbitsRegister (void); - -#endif /* __DETECT_XBITS_H__ */ diff --git a/framework/src/suricata/src/detect.c b/framework/src/suricata/src/detect.c deleted file mode 100644 index 401d2b00..00000000 --- a/framework/src/suricata/src/detect.c +++ /dev/null @@ -1,12343 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Basic detection engine - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "flow-private.h" -#include "flow-bit.h" - -#include "detect-parse.h" -#include "detect-engine.h" - -#include "detect-engine-alert.h" -#include "detect-engine-siggroup.h" -#include "detect-engine-address.h" -#include "detect-engine-proto.h" -#include "detect-engine-port.h" -#include "detect-engine-mpm.h" -#include "detect-engine-iponly.h" -#include "detect-engine-threshold.h" - -#include "detect-engine-payload.h" -#include "detect-engine-dcepayload.h" -#include "detect-engine-uri.h" -#include "detect-dns-query.h" -#include "detect-engine-state.h" -#include "detect-engine-analyzer.h" -#include "detect-engine-filedata-smtp.h" - -#include "detect-http-cookie.h" -#include "detect-http-method.h" -#include "detect-http-ua.h" -#include "detect-http-hh.h" -#include "detect-http-hrh.h" - -#include "detect-engine-event.h" -#include "decode.h" - -#include "detect-base64-decode.h" -#include "detect-base64-data.h" -#include "detect-ipopts.h" -#include "detect-flags.h" -#include "detect-fragbits.h" -#include "detect-fragoffset.h" -#include "detect-gid.h" -#include "detect-ack.h" -#include "detect-seq.h" -#include "detect-content.h" -#include "detect-uricontent.h" -#include "detect-pcre.h" -#include "detect-depth.h" -#include "detect-nocase.h" -#include "detect-rawbytes.h" -#include "detect-bytetest.h" -#include "detect-bytejump.h" -#include "detect-sameip.h" -#include "detect-l3proto.h" -#include "detect-ipproto.h" -#include "detect-within.h" -#include "detect-distance.h" -#include "detect-offset.h" -#include "detect-sid.h" -#include "detect-priority.h" -#include "detect-classtype.h" -#include "detect-reference.h" -#include "detect-tag.h" -#include "detect-threshold.h" -#include "detect-metadata.h" -#include "detect-msg.h" -#include "detect-rev.h" -#include "detect-flow.h" -#include "detect-window.h" -#include "detect-ftpbounce.h" -#include "detect-isdataat.h" -#include "detect-id.h" -#include "detect-rpc.h" -#include "detect-asn1.h" -#include "detect-filename.h" -#include "detect-fileext.h" -#include "detect-filestore.h" -#include "detect-filemagic.h" -#include "detect-filemd5.h" -#include "detect-filesize.h" -#include "detect-dsize.h" -#include "detect-flowvar.h" -#include "detect-flowint.h" -#include "detect-pktvar.h" -#include "detect-noalert.h" -#include "detect-flowbits.h" -#include "detect-hostbits.h" -#include "detect-xbits.h" -#include "detect-csum.h" -#include "detect-stream_size.h" -#include "detect-engine-sigorder.h" -#include "detect-ttl.h" -#include "detect-fast-pattern.h" -#include "detect-itype.h" -#include "detect-icode.h" -#include "detect-icmp-id.h" -#include "detect-icmp-seq.h" -#include "detect-dce-iface.h" -#include "detect-dce-opnum.h" -#include "detect-dce-stub-data.h" -#include "detect-urilen.h" -#include "detect-detection-filter.h" -#include "detect-http-client-body.h" -#include "detect-http-server-body.h" -#include "detect-http-header.h" -#include "detect-http-raw-header.h" -#include "detect-http-uri.h" -#include "detect-http-raw-uri.h" -#include "detect-http-stat-msg.h" -#include "detect-engine-hcbd.h" -#include "detect-engine-hsbd.h" -#include "detect-engine-hhd.h" -#include "detect-engine-hrhd.h" -#include "detect-engine-hmd.h" -#include "detect-engine-hcd.h" -#include "detect-engine-hrud.h" -#include "detect-engine-hsmd.h" -#include "detect-engine-hscd.h" -#include "detect-engine-hua.h" -#include "detect-engine-hhhd.h" -#include "detect-engine-hrhhd.h" -#include "detect-byte-extract.h" -#include "detect-file-data.h" -#include "detect-pkt-data.h" -#include "detect-replace.h" -#include "detect-tos.h" -#include "detect-app-layer-event.h" -#include "detect-lua.h" -#include "detect-iprep.h" -#include "detect-geoip.h" -#include "detect-dns-query.h" -#include "detect-app-layer-protocol.h" -#include "detect-template.h" -#include "detect-template-buffer.h" - -#include "util-rule-vars.h" - -#include "app-layer.h" -#include "app-layer-protos.h" -#include "app-layer-htp.h" -#include "app-layer-smtp.h" -#include "app-layer-template.h" -#include "detect-tls.h" -#include "detect-tls-version.h" -#include "detect-ssh-proto-version.h" -#include "detect-ssh-software-version.h" -#include "detect-http-stat-code.h" -#include "detect-ssl-version.h" -#include "detect-ssl-state.h" -#include "detect-modbus.h" - -#include "action-globals.h" -#include "tm-threads.h" - -#include "pkt-var.h" - -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "stream-tcp.h" -#include "stream-tcp-inline.h" - -#include "util-var-name.h" -#include "util-classification-config.h" -#include "util-print.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-debug.h" -#include "util-hashlist.h" -#include "util-cuda.h" -#include "util-privs.h" -#include "util-profiling.h" -#include "util-validate.h" -#include "util-optimize.h" -#include "util-path.h" -#include "util-mpm-ac.h" - -#include "runmodes.h" - -#include - -extern int rule_reload; - -extern int engine_analysis; -static int fp_engine_analysis_set = 0; -static int rule_engine_analysis_set = 0; - -SigMatch *SigMatchAlloc(void); -void DetectExitPrintStats(ThreadVars *tv, void *data); - -void DbgPrintSigs(DetectEngineCtx *, SigGroupHead *); -void DbgPrintSigs2(DetectEngineCtx *, SigGroupHead *); -static void PacketCreateMask(Packet *, SignatureMask *, uint16_t, int, StreamMsg *, int); - -/* tm module api functions */ -TmEcode Detect(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode DetectThreadInit(ThreadVars *, void *, void **); -TmEcode DetectThreadDeinit(ThreadVars *, void *); - -void TmModuleDetectRegister (void) -{ - tmm_modules[TMM_DETECT].name = "Detect"; - tmm_modules[TMM_DETECT].ThreadInit = DetectThreadInit; - tmm_modules[TMM_DETECT].Func = Detect; - tmm_modules[TMM_DETECT].ThreadExitPrintStats = DetectExitPrintStats; - tmm_modules[TMM_DETECT].ThreadDeinit = DetectThreadDeinit; - tmm_modules[TMM_DETECT].RegisterTests = SigRegisterTests; - tmm_modules[TMM_DETECT].cap_flags = 0; - tmm_modules[TMM_DETECT].flags = TM_FLAG_DETECT_TM; - - PacketAlertTagInit(); -} - -void DetectExitPrintStats(ThreadVars *tv, void *data) -{ - DetectEngineThreadCtx *det_ctx = (DetectEngineThreadCtx *)data; - if (det_ctx == NULL) - return; -} - -/** - * \brief Create the path if default-rule-path was specified - * \param sig_file The name of the file - * \retval str Pointer to the string path + sig_file - */ -char *DetectLoadCompleteSigPath(const DetectEngineCtx *de_ctx, char *sig_file) -{ - char *defaultpath = NULL; - char *path = NULL; - char varname[128] = "default-rule-path"; - - if (strlen(de_ctx->config_prefix) > 0) { - snprintf(varname, sizeof(varname), "%s.default-rule-path", - de_ctx->config_prefix); - } - - /* Path not specified */ - if (PathIsRelative(sig_file)) { - if (ConfGet(varname, &defaultpath) == 1) { - SCLogDebug("Default path: %s", defaultpath); - size_t path_len = sizeof(char) * (strlen(defaultpath) + - strlen(sig_file) + 2); - path = SCMalloc(path_len); - if (unlikely(path == NULL)) - return NULL; - strlcpy(path, defaultpath, path_len); -#if defined OS_WIN32 || defined __CYGWIN__ - if (path[strlen(path) - 1] != '\\') - strlcat(path, "\\\\", path_len); -#else - if (path[strlen(path) - 1] != '/') - strlcat(path, "/", path_len); -#endif - strlcat(path, sig_file, path_len); - } else { - path = SCStrdup(sig_file); - if (unlikely(path == NULL)) - return NULL; - } - } else { - path = SCStrdup(sig_file); - if (unlikely(path == NULL)) - return NULL; - } - return path; -} - -/** - * \brief Load a file with signatures - * \param de_ctx Pointer to the detection engine context - * \param sig_file Filename to load signatures from - * \param goodsigs_tot Will store number of valid signatures in the file - * \param badsigs_tot Will store number of invalid signatures in the file - * \retval 0 on success, -1 on error - */ -static int DetectLoadSigFile(DetectEngineCtx *de_ctx, char *sig_file, - int *goodsigs, int *badsigs) -{ - Signature *sig = NULL; - int good = 0, bad = 0; - char line[DETECT_MAX_RULE_SIZE] = ""; - size_t offset = 0; - int lineno = 0, multiline = 0; - - (*goodsigs) = 0; - (*badsigs) = 0; - - FILE *fp = fopen(sig_file, "r"); - if (fp == NULL) { - SCLogError(SC_ERR_OPENING_RULE_FILE, "opening rule file %s:" - " %s.", sig_file, strerror(errno)); - return -1; - } - - while(fgets(line + offset, (int)sizeof(line) - offset, fp) != NULL) { - lineno++; - size_t len = strlen(line); - - /* ignore comments and empty lines */ - if (line[0] == '\n' || line [0] == '\r' || line[0] == ' ' || line[0] == '#' || line[0] == '\t') - continue; - - /* Check for multiline rules. */ - while (len > 0 && isspace((unsigned char)line[--len])); - if (line[len] == '\\') { - multiline++; - offset = len; - if (offset < sizeof(line) - 1) { - /* We have room for more. */ - continue; - } - /* No more room in line buffer, continue, rule will fail - * to parse. */ - } - - /* Check if we have a trailing newline, and remove it */ - len = strlen(line); - if (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) { - line[len - 1] = '\0'; - } - - /* Reset offset. */ - offset = 0; - - de_ctx->rule_file = sig_file; - de_ctx->rule_line = lineno - multiline; - - sig = DetectEngineAppendSig(de_ctx, line); - if (sig != NULL) { - if (rule_engine_analysis_set || fp_engine_analysis_set) { - sig->mpm_sm = RetrieveFPForSigV2(sig); - if (fp_engine_analysis_set) { - EngineAnalysisFP(sig, line); - } - if (rule_engine_analysis_set) { - EngineAnalysisRules(sig, line); - } - } - SCLogDebug("signature %"PRIu32" loaded", sig->id); - good++; - } else { - SCLogError(SC_ERR_INVALID_SIGNATURE, "error parsing signature \"%s\" from " - "file %s at line %"PRId32"", line, sig_file, lineno - multiline); - - if (rule_engine_analysis_set) { - EngineAnalysisRulesFailure(line, sig_file, lineno - multiline); - } - bad++; - } - multiline = 0; - } - fclose(fp); - - *goodsigs = good; - *badsigs = bad; - return 0; -} - -/** - * \brief Expands wildcards and reads signatures from each matching file - * \param de_ctx Pointer to the detection engine context - * \param sig_file Filename (or pattern) holding signatures - * \retval -1 on error - */ -static int ProcessSigFiles(DetectEngineCtx *de_ctx, char *pattern, - SigFileLoaderStat *st, int *good_sigs, int *bad_sigs) -{ - if (pattern == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "opening rule file null"); - return -1; - } - - glob_t files; - int r = glob(pattern, 0, NULL, &files); - - if (r == GLOB_NOMATCH) { - SCLogWarning(SC_ERR_NO_RULES, "No rule files match the pattern %s", pattern); - ++(st->bad_files); - ++(st->total_files); - return -1; - } else if (r != 0) { - SCLogError(SC_ERR_OPENING_RULE_FILE, "error expanding template %s: %s", - pattern, strerror(errno)); - return -1; - } - - for (size_t i = 0; i < (size_t)files.gl_pathc; i++) { - char *fname = files.gl_pathv[i]; - SCLogInfo("Loading rule file: %s", fname); - r = DetectLoadSigFile(de_ctx, fname, good_sigs, bad_sigs); - if (r < 0) { - ++(st->bad_files); - } - - ++(st->total_files); - - if (*good_sigs == 0) { - SCLogWarning(SC_ERR_NO_RULES, - "No rules loaded from %s", fname); - } - - st->good_sigs_total += *good_sigs; - st->bad_sigs_total += *bad_sigs; - } - - globfree(&files); - return r; -} - -/** - * \brief Load signatures - * \param de_ctx Pointer to the detection engine context - * \param sig_file Filename (or pattern) holding signatures - * \param sig_file_exclusive File passed in 'sig_file' should be loaded exclusively. - * \retval -1 on error - */ -int SigLoadSignatures(DetectEngineCtx *de_ctx, char *sig_file, int sig_file_exclusive) -{ - SCEnter(); - - ConfNode *rule_files; - ConfNode *file = NULL; - SigFileLoaderStat sig_stat; - int ret = 0; - char *sfile = NULL; - char varname[128] = "rule-files"; - int good_sigs = 0; - int bad_sigs = 0; - - memset(&sig_stat, 0, sizeof(SigFileLoaderStat)); - - if (strlen(de_ctx->config_prefix) > 0) { - snprintf(varname, sizeof(varname), "%s.rule-files", - de_ctx->config_prefix); - } - - if (RunmodeGetCurrent() == RUNMODE_ENGINE_ANALYSIS) { - fp_engine_analysis_set = SetupFPAnalyzer(); - rule_engine_analysis_set = SetupRuleAnalyzer(); - } - - /* ok, let's load signature files from the general config */ - if (!(sig_file != NULL && sig_file_exclusive == TRUE)) { - rule_files = ConfGetNode(varname); - if (rule_files != NULL) { - if (!ConfNodeIsSequence(rule_files)) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, - "Invalid rule-files configuration section: " - "expected a list of filenames."); - } - else { - TAILQ_FOREACH(file, &rule_files->head, next) { - sfile = DetectLoadCompleteSigPath(de_ctx, file->val); - good_sigs = bad_sigs = 0; - ret = ProcessSigFiles(de_ctx, sfile, &sig_stat, &good_sigs, &bad_sigs); - SCFree(sfile); - - if (ret != 0 || good_sigs == 0) { - if (de_ctx->failure_fatal == 1) { - exit(EXIT_FAILURE); - } - } - } - } - } - } - - /* If a Signature file is specified from commandline, parse it too */ - if (sig_file != NULL) { - ret = ProcessSigFiles(de_ctx, sig_file, &sig_stat, &good_sigs, &bad_sigs); - - if (ret != 0) { - if (de_ctx->failure_fatal == 1) { - exit(EXIT_FAILURE); - } - } - - if (good_sigs == 0) { - SCLogError(SC_ERR_NO_RULES, "No rules loaded from %s", sig_file); - - if (de_ctx->failure_fatal == 1) { - exit(EXIT_FAILURE); - } - } - } - - /* now we should have signatures to work with */ - if (sig_stat.good_sigs_total <= 0) { - if (sig_stat.total_files > 0) { - SCLogWarning(SC_ERR_NO_RULES_LOADED, "%d rule files specified, but no rule was loaded at all!", sig_stat.total_files); - } else { - SCLogInfo("No signatures supplied."); - goto end; - } - } else { - /* we report the total of files and rules successfully loaded and failed */ - SCLogInfo("%" PRId32 " rule files processed. %" PRId32 " rules successfully loaded, %" PRId32 " rules failed", - sig_stat.total_files, sig_stat.good_sigs_total, sig_stat.bad_sigs_total); - } - - if ((sig_stat.bad_sigs_total || sig_stat.bad_files) && de_ctx->failure_fatal) { - ret = -1; - goto end; - } - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - SCSigSignatureOrderingModuleCleanup(de_ctx); - - /* Setup the signature group lookup structure and pattern matchers */ - if (SigGroupBuild(de_ctx) < 0) - goto end; - - ret = 0; - - end: - if (RunmodeGetCurrent() == RUNMODE_ENGINE_ANALYSIS) { - if (rule_engine_analysis_set) { - CleanupRuleAnalyzer(); - } - if (fp_engine_analysis_set) { - CleanupFPAnalyzer(); - } - } - - DetectParseDupSigHashFree(de_ctx); - SCReturnInt(ret); -} - -int SigMatchSignaturesRunPostMatch(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p, - Signature *s) -{ - /* run the packet match functions */ - if (s->sm_arrays[DETECT_SM_LIST_POSTMATCH] != NULL) { - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_POSTMATCH); - - SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_POSTMATCH]; - SCLogDebug("running match functions, sm %p", smd); - - if (smd != NULL) { - while (1) { - KEYWORD_PROFILING_START; - (void)sigmatch_table[smd->type].Match(tv, det_ctx, p, s, smd->ctx); - KEYWORD_PROFILING_END(det_ctx, smd->type, 1); - if (smd->is_last) - break; - smd++; - } - } - } - - DetectReplaceExecute(p, det_ctx); - - if (s->flags & SIG_FLAG_FILESTORE) - DetectFilestorePostMatch(tv, det_ctx, p, s); - - return 1; -} - -/** - * \brief Get the SigGroupHead for a packet. - * - * \param de_ctx detection engine context - * \param det_ctx thread detection engine content - * \param p packet - * - * \retval sgh the SigGroupHead or NULL if non applies to the packet - */ -SigGroupHead *SigMatchSignaturesGetSgh(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p) -{ - SCEnter(); - - int f; - SigGroupHead *sgh = NULL; - - /* if the packet proto is 0 (not set), we're inspecting it against - * the decoder events sgh we have. */ - if (p->proto == 0 && p->events.cnt > 0) { - SCReturnPtr(de_ctx->decoder_event_sgh, "SigGroupHead"); - } - - /* select the flow_gh */ - if (p->flowflags & FLOW_PKT_TOCLIENT) - f = 0; - else - f = 1; - - SCLogDebug("f %d", f); - SCLogDebug("IP_GET_IPPROTO(p) %u", IP_GET_IPPROTO(p)); - - /* find the right mpm instance */ - DetectAddress *ag = DetectAddressLookupInHead(de_ctx->flow_gh[f].src_gh[IP_GET_IPPROTO(p)], &p->src); - if (ag != NULL) { - /* source group found, lets try a dst group */ - ag = DetectAddressLookupInHead(ag->dst_gh, &p->dst); - if (ag != NULL) { - if (ag->port == NULL) { - SCLogDebug("we don't have ports"); - sgh = ag->sh; - } else { - SCLogDebug("we have ports"); - - DetectPort *sport = DetectPortLookupGroup(ag->port,p->sp); - if (sport != NULL) { - DetectPort *dport = DetectPortLookupGroup(sport->dst_ph,p->dp); - if (dport != NULL) { - sgh = dport->sh; - } else { - SCLogDebug("no dst port group found for the packet with dp %"PRIu16"", p->dp); - } - } else { - SCLogDebug("no src port group found for the packet with sp %"PRIu16"", p->sp); - } - } - } else { - SCLogDebug("no dst address group found for the packet"); - } - } else { - SCLogDebug("no src address group found for the packet"); - } - - SCReturnPtr(sgh, "SigGroupHead"); -} - -/** \brief Get the smsgs relevant to this packet - * - * \param f LOCKED flow - * \param p packet - * \param flags stream flags - */ -static StreamMsg *SigMatchSignaturesGetSmsg(Flow *f, Packet *p, uint8_t flags) -{ - SCEnter(); - - DEBUG_ASSERT_FLOW_LOCKED(f); - - StreamMsg *smsg = NULL; - - if (p->proto == IPPROTO_TCP && f->protoctx != NULL && (p->flags & PKT_STREAM_EST)) { - TcpSession *ssn = (TcpSession *)f->protoctx; - - /* at stream eof, or in inline mode, inspect all smsg's */ - if ((flags & STREAM_EOF) || StreamTcpInlineMode()) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - smsg = ssn->toserver_smsg_head; - /* deref from the ssn */ - ssn->toserver_smsg_head = NULL; - ssn->toserver_smsg_tail = NULL; - - SCLogDebug("to_server smsg %p at stream eof", smsg); - } else { - smsg = ssn->toclient_smsg_head; - /* deref from the ssn */ - ssn->toclient_smsg_head = NULL; - ssn->toclient_smsg_tail = NULL; - - SCLogDebug("to_client smsg %p at stream eof", smsg); - } - } else { - if (p->flowflags & FLOW_PKT_TOSERVER) { - StreamMsg *head = ssn->toserver_smsg_head; - if (unlikely(head == NULL)) { - SCLogDebug("no smsgs in to_server direction"); - goto end; - } - - /* if the smsg is bigger than the current packet, we will - * process the smsg in a later run */ - if (SEQ_GT((head->seq + head->data_len), (TCP_GET_SEQ(p) + p->payload_len))) { - SCLogDebug("smsg ends beyond current packet, skipping for now %"PRIu32">%"PRIu32, - (head->seq + head->data_len), (TCP_GET_SEQ(p) + p->payload_len)); - goto end; - } - - smsg = head; - /* deref from the ssn */ - ssn->toserver_smsg_head = NULL; - ssn->toserver_smsg_tail = NULL; - - SCLogDebug("to_server smsg %p", smsg); - } else { - StreamMsg *head = ssn->toclient_smsg_head; - if (unlikely(head == NULL)) - goto end; - - /* if the smsg is bigger than the current packet, we will - * process the smsg in a later run */ - if (SEQ_GT((head->seq + head->data_len), (TCP_GET_SEQ(p) + p->payload_len))) { - SCLogDebug("smsg ends beyond current packet, skipping for now %"PRIu32">%"PRIu32, - (head->seq + head->data_len), (TCP_GET_SEQ(p) + p->payload_len)); - goto end; - } - - smsg = head; - /* deref from the ssn */ - ssn->toclient_smsg_head = NULL; - ssn->toclient_smsg_tail = NULL; - - SCLogDebug("to_client smsg %p", smsg); - } - } - } - -end: - SCReturnPtr(smsg, "StreamMsg"); -} - -static inline void DetectPrefilterMergeSort(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx) -// SigGroupHead *sgh) -{ - SigIntId mpm, nonmpm; - det_ctx->match_array_cnt = 0; - SigIntId *mpm_ptr = det_ctx->pmq.rule_id_array; - SigIntId *nonmpm_ptr = det_ctx->non_mpm_id_array; - //SigIntId *nonmpm_ptr = sgh->non_mpm_id_array; - uint32_t m_cnt = det_ctx->pmq.rule_id_array_cnt; - //uint32_t n_cnt = sgh->non_mpm_id_cnt; - uint32_t n_cnt = det_ctx->non_mpm_id_cnt; - SCLogDebug("PMQ rule id array count %d", det_ctx->pmq.rule_id_array_cnt); -// SCLogDebug("SGH non-MPM id count %d", sgh->non_mpm_id_cnt); - SigIntId *final_ptr; - uint32_t final_cnt; - SigIntId id; - SigIntId previous_id = (SigIntId)-1; - Signature **sig_array = de_ctx->sig_array; - Signature **match_array = det_ctx->match_array; - Signature *s; - - /* Load first values. */ - if (likely(m_cnt)) { - mpm = *mpm_ptr; - } else { - /* mpm list is empty */ - final_ptr = nonmpm_ptr; - final_cnt = n_cnt; - goto final; - } - if (likely(n_cnt)) { - nonmpm = *nonmpm_ptr; - } else { - /* non-mpm list is empty. */ - final_ptr = mpm_ptr; - final_cnt = m_cnt; - goto final; - } - while (1) { - if (mpm <= nonmpm) { - /* Take from mpm list */ - id = mpm; - - s = sig_array[id]; - /* As the mpm list can contain duplicates, check for that here. */ - if (likely(id != previous_id)) { - *match_array++ = s; - previous_id = id; - } - if (unlikely(--m_cnt == 0)) { - /* mpm list is now empty */ - final_ptr = nonmpm_ptr; - final_cnt = n_cnt; - goto final; - } - mpm_ptr++; - mpm = *mpm_ptr; - } else { - id = nonmpm; - - s = sig_array[id]; - /* As the mpm list can contain duplicates, check for that here. */ - if (likely(id != previous_id)) { - *match_array++ = s; - previous_id = id; - } - if (unlikely(--n_cnt == 0)) { - final_ptr = mpm_ptr; - final_cnt = m_cnt; - goto final; - } - nonmpm_ptr++; - nonmpm = *nonmpm_ptr; - } - } - - final: /* Only one list remaining. Just walk that list. */ - - while (final_cnt-- > 0) { - id = *final_ptr++; - s = sig_array[id]; - - /* As the mpm list can contain duplicates, check for that here. */ - if (likely(id != previous_id)) { - *match_array++ = s; - previous_id = id; - } - } - - det_ctx->match_array_cnt = match_array - det_ctx->match_array; - - BUG_ON((det_ctx->pmq.rule_id_array_cnt + det_ctx->non_mpm_id_cnt) < det_ctx->match_array_cnt); -} - -/* Return true is the list is sorted smallest to largest */ -static void QuickSortSigIntId(SigIntId *sids, uint32_t n) -{ - if (n < 2) - return; - SigIntId p = sids[n / 2]; - SigIntId *l = sids; - SigIntId *r = sids + n - 1; - while (l <= r) { - if (*l < p) - l++; - else if (*r > p) - r--; - else { - SigIntId t = *l; - *l = *r; - *r = t; - l++; - r--; - } - } - QuickSortSigIntId(sids, r - sids + 1); - QuickSortSigIntId(l, sids + n - l); -} - -#define SMS_USE_FLOW_SGH 0x01 -#define SMS_USED_PM 0x02 -#define SMS_USED_STREAM_PM 0x04 - -/** - * \internal - * \brief Run mpm on packet, stream and other buffers based on - * alproto, sgh state. - * - * \param de_ctx Pointer to the detection engine context. - * \param det_ctx Pointer to the detection engine thread context. - * \param smsg The stream segment to inspect for stream mpm. - * \param p Packet. - * \param flags Flags. - * \param alproto Flow alproto. - * \param has_state Bool indicating we have (al)state - * \param sms_runflags Used to store state by detection engine. - */ -static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, StreamMsg *smsg, Packet *p, - const uint8_t flags, const AppProto alproto, - const int has_state, uint8_t *sms_runflags) -{ - /* have a look at the reassembled stream (if any) */ - if (p->flowflags & FLOW_PKT_ESTABLISHED) { - SCLogDebug("p->flowflags & FLOW_PKT_ESTABLISHED"); - - /* all http based mpms */ - if (has_state && alproto == ALPROTO_HTTP) { - FLOWLOCK_WRLOCK(p->flow); - void *alstate = FlowGetAppState(p->flow); - if (alstate == NULL) { - SCLogDebug("no alstate"); - FLOWLOCK_UNLOCK(p->flow); - return; - } - - HtpState *htp_state = (HtpState *)alstate; - if (htp_state->connp == NULL) { - SCLogDebug("no HTTP connp"); - FLOWLOCK_UNLOCK(p->flow); - return; - } - - int tx_progress = 0; - uint64_t idx = AppLayerParserGetTransactionInspectId(p->flow->alparser, flags); - uint64_t total_txs = AppLayerParserGetTxCnt(IPPROTO_TCP, ALPROTO_HTTP, alstate); - for (; idx < total_txs; idx++) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, idx); - if (tx == NULL) - continue; - - if (p->flowflags & FLOW_PKT_TOSERVER) { - tx_progress = AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags); - - if (tx_progress > HTP_REQUEST_LINE) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_URI) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_URI); - DetectUricontentInspectMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_URI); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRUD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRUD); - DetectEngineRunHttpRawUriMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRUD); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HMD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HMD); - DetectEngineRunHttpMethodMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HMD); - } - } - - if (tx_progress >= HTP_REQUEST_HEADERS) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHHD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HHHD); - DetectEngineRunHttpHHMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HHHD); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHHD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHHD); - DetectEngineRunHttpHRHMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHHD); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HCD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HCD); - DetectEngineRunHttpCookieMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HCD); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HUAD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HUAD); - DetectEngineRunHttpUAMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HUAD); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HHD); - DetectEngineRunHttpHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HHD); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHD); - DetectEngineRunHttpRawHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHD); - } - } - - if (tx_progress >= HTP_REQUEST_BODY) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HCBD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HCBD); - DetectEngineRunHttpClientBodyMpm(de_ctx, det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HCBD); - } - } - } else { /* implied FLOW_PKT_TOCLIENT */ - tx_progress = AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags); - - if (tx_progress > HTP_RESPONSE_LINE) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSMD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSMD); - DetectEngineRunHttpStatMsgMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSMD); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSCD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSCD); - DetectEngineRunHttpStatCodeMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSCD); - } - } - - if (tx_progress >= HTP_RESPONSE_HEADERS) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HHD); - DetectEngineRunHttpHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HHD); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHD); - DetectEngineRunHttpRawHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHD); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HCD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HCD); - DetectEngineRunHttpCookieMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HCD); - } - } - - if (tx_progress >= HTP_RESPONSE_BODY) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSBD) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSBD); - DetectEngineRunHttpServerBodyMpm(de_ctx, det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSBD); - } - } - } - } /* for */ - - FLOWLOCK_UNLOCK(p->flow); - } - /* all dns based mpms */ - else if (alproto == ALPROTO_DNS && has_state) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_DNSQUERY) { - FLOWLOCK_RDLOCK(p->flow); - void *alstate = FlowGetAppState(p->flow); - if (alstate == NULL) { - SCLogDebug("no alstate"); - FLOWLOCK_UNLOCK(p->flow); - return; - } - - uint64_t idx = AppLayerParserGetTransactionInspectId(p->flow->alparser, flags); - uint64_t total_txs = AppLayerParserGetTxCnt(p->flow->proto, alproto, alstate); - for (; idx < total_txs; idx++) { - void *tx = AppLayerParserGetTx(p->flow->proto, alproto, alstate, idx); - if (tx == NULL) - continue; - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_DNSQUERY); - DetectDnsQueryInspectMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_DNSQUERY); - } - FLOWLOCK_UNLOCK(p->flow); - } - } - } else if (alproto == ALPROTO_SMTP && has_state) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_FD_SMTP) { - FLOWLOCK_RDLOCK(p->flow); - void *alstate = FlowGetAppState(p->flow); - if (alstate == NULL) { - SCLogDebug("no alstate"); - FLOWLOCK_UNLOCK(p->flow); - return; - } - - SMTPState *smtp_state = (SMTPState *)alstate; - uint64_t idx = AppLayerParserGetTransactionInspectId(p->flow->alparser, flags); - uint64_t total_txs = AppLayerParserGetTxCnt(p->flow->proto, alproto, alstate); - for (; idx < total_txs; idx++) { - void *tx = AppLayerParserGetTx(p->flow->proto, alproto, alstate, idx); - if (tx == NULL) - continue; - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_FD_SMTP); - DetectEngineRunSMTPMpm(de_ctx, det_ctx, p->flow, smtp_state, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_FD_SMTP); - } - FLOWLOCK_UNLOCK(p->flow); - } - } - } - - if (smsg != NULL && (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_STREAM)) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_STREAM); - StreamPatternSearch(det_ctx, p, smsg, flags); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_STREAM); - - *sms_runflags |= SMS_USED_STREAM_PM; - } else { - SCLogDebug("smsg NULL or no stream mpm for this sgh"); - } - } else { - SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED"); - } - - if (p->payload_len > 0 && (!(p->flags & PKT_NOPAYLOAD_INSPECTION))) { - if (!(p->flags & PKT_STREAM_ADD) && (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_STREAM)) { - *sms_runflags |= SMS_USED_PM; - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_PKT_STREAM); - PacketPatternSearchWithStreamCtx(det_ctx, p); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_PKT_STREAM); - } - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_PACKET) { - /* run the multi packet matcher against the payload of the packet */ - SCLogDebug("search: (%p, minlen %" PRIu32 ", sgh->sig_cnt %" PRIu32 ")", - det_ctx->sgh, det_ctx->sgh->mpm_content_minlen, det_ctx->sgh->sig_cnt); - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_PACKET); - PacketPatternSearch(det_ctx, p); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_PACKET); - - *sms_runflags |= SMS_USED_PM; - } - } - - /* UDP DNS inspection is independent of est or not */ - if (alproto == ALPROTO_DNS && has_state) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - SCLogDebug("mpm inspection"); - if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_DNSQUERY) { - FLOWLOCK_RDLOCK(p->flow); - void *alstate = FlowGetAppState(p->flow); - if (alstate == NULL) { - SCLogDebug("no alstate"); - FLOWLOCK_UNLOCK(p->flow); - return; - } - - uint64_t idx = AppLayerParserGetTransactionInspectId(p->flow->alparser, flags); - uint64_t total_txs = AppLayerParserGetTxCnt(p->flow->proto, alproto, alstate); - for (; idx < total_txs; idx++) { - void *tx = AppLayerParserGetTx(p->flow->proto, alproto, alstate, idx); - if (tx == NULL) - continue; - SCLogDebug("tx %p",tx); - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_DNSQUERY); - DetectDnsQueryInspectMpm(det_ctx, p->flow, alstate, flags, tx, idx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_DNSQUERY); - } - FLOWLOCK_UNLOCK(p->flow); - } - } - } - - /* Sort the rule list to lets look at pmq. - * NOTE due to merging of 'stream' pmqs we *MAY* have duplicate entries */ - if (det_ctx->pmq.rule_id_array_cnt > 1) { - QuickSortSigIntId(det_ctx->pmq.rule_id_array, det_ctx->pmq.rule_id_array_cnt); - } -} - -#ifdef DEBUG -static void DebugInspectIds(Packet *p, Flow *f, StreamMsg *smsg) -{ - SCLogDebug("pcap_cnt %02"PRIu64", %s, %12s, smsg %s", - p->pcap_cnt, p->flowflags & FLOW_PKT_TOSERVER ? "toserver" : "toclient", - p->flags & PKT_STREAM_EST ? "established" : "stateless", - smsg ? "yes" : "no"); - AppLayerParserStatePrintDetails(f->alparser); -} -#endif - -static void AlertDebugLogModeSyncFlowbitsNamesToPacketStruct(Packet *p, DetectEngineCtx *de_ctx) -{ -#define MALLOC_JUMP 5 - - int i = 0; - - GenericVar *gv = p->flow->flowvar; - - while (gv != NULL) { - i++; - gv = gv->next; - } - if (i == 0) - return; - - p->debuglog_flowbits_names_len = i; - - p->debuglog_flowbits_names = SCMalloc(sizeof(char *) * - p->debuglog_flowbits_names_len); - if (p->debuglog_flowbits_names == NULL) { - return; - } - memset(p->debuglog_flowbits_names, 0, - sizeof(char *) * p->debuglog_flowbits_names_len); - - i = 0; - gv = p->flow->flowvar; - while (gv != NULL) { - if (gv->type != DETECT_FLOWBITS) { - gv = gv->next; - continue; - } - - FlowBit *fb = (FlowBit *) gv; - char *name = VariableIdxGetName(de_ctx, fb->idx, VAR_TYPE_FLOW_BIT); - if (name != NULL) { - p->debuglog_flowbits_names[i] = SCStrdup(name); - if (p->debuglog_flowbits_names[i] == NULL) { - return; - } - i++; - } - - if (i == p->debuglog_flowbits_names_len) { - p->debuglog_flowbits_names_len += MALLOC_JUMP; - const char **names = SCRealloc(p->debuglog_flowbits_names, - sizeof(char *) * - p->debuglog_flowbits_names_len); - if (names == NULL) { - SCFree(p->debuglog_flowbits_names); - p->debuglog_flowbits_names = NULL; - p->debuglog_flowbits_names_len = 0; - return; - } - p->debuglog_flowbits_names = names; - memset(p->debuglog_flowbits_names + - p->debuglog_flowbits_names_len - MALLOC_JUMP, - 0, sizeof(char *) * MALLOC_JUMP); - } - - gv = gv->next; - } - - return; -} - -static inline void DetectPrefilterBuildNonMpmList(DetectEngineThreadCtx *det_ctx, SignatureMask mask) -{ - uint32_t x = 0; - for (x = 0; x < det_ctx->sgh->non_mpm_store_cnt; x++) { - /* only if the mask matches this rule can possibly match, - * so build the non_mpm array only for match candidates */ - SignatureMask rule_mask = det_ctx->sgh->non_mpm_store_array[x].mask; - if ((rule_mask & mask) == rule_mask) { - det_ctx->non_mpm_id_array[det_ctx->non_mpm_id_cnt++] = det_ctx->sgh->non_mpm_store_array[x].id; - } - } -} - -/** - * \brief Signature match function - * - * \retval 1 one or more signatures matched - * \retval 0 no matches were found - */ -int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p) -{ - uint8_t sms_runflags = 0; /* function flags */ - uint8_t alert_flags = 0; - AppProto alproto = ALPROTO_UNKNOWN; -#ifdef PROFILING - int smatch = 0; /* signature match: 1, no match: 0 */ -#endif - uint8_t flow_flags = 0; /* flow/state flags */ - StreamMsg *smsg = NULL; - Signature *s = NULL; - Signature *next_s = NULL; - uint8_t alversion = 0; - int state_alert = 0; - int alerts = 0; - int app_decoder_events = 0; - int has_state = 0; /* do we have an alstate to work with? */ - - SCEnter(); - - SCLogDebug("pcap_cnt %"PRIu64, p->pcap_cnt); - - p->alerts.cnt = 0; - det_ctx->filestore_cnt = 0; - - det_ctx->base64_decoded_len = 0; - - /* No need to perform any detection on this packet, if the the given flag is set.*/ - if (p->flags & PKT_NOPACKET_INSPECTION) { - SCReturnInt(0); - } - - /* Load the Packet's flow early, even though it might not be needed. - * Mark as a constant pointer, although the flow can change. - */ - Flow * const pflow = p->flow; - - /* grab the protocol state we will detect on */ - if (p->flags & PKT_HAS_FLOW) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - flow_flags = STREAM_TOSERVER; - SCLogDebug("flag STREAM_TOSERVER set"); - } else if (p->flowflags & FLOW_PKT_TOCLIENT) { - flow_flags = STREAM_TOCLIENT; - SCLogDebug("flag STREAM_TOCLIENT set"); - } - SCLogDebug("p->flowflags 0x%02x", p->flowflags); - - if (p->flags & PKT_STREAM_EOF) { - flow_flags |= STREAM_EOF; - SCLogDebug("STREAM_EOF set"); - } - - FLOWLOCK_WRLOCK(pflow); - { - /* store tenant_id in the flow so that we can use it - * for creating pseudo packets */ - if (p->tenant_id > 0 && pflow->tenant_id == 0) { - pflow->tenant_id = p->tenant_id; - } - - /* live ruleswap check for flow updates */ - if (pflow->de_ctx_id == 0) { - /* first time this flow is inspected, set id */ - pflow->de_ctx_id = de_ctx->id; - } else if (pflow->de_ctx_id != de_ctx->id) { - /* first time we inspect flow with this de_ctx, reset */ - pflow->flags &= ~FLOW_SGH_TOSERVER; - pflow->flags &= ~FLOW_SGH_TOCLIENT; - pflow->sgh_toserver = NULL; - pflow->sgh_toclient = NULL; - - pflow->de_ctx_id = de_ctx->id; - GenericVarFree(pflow->flowvar); - pflow->flowvar = NULL; - - DetectEngineStateReset(pflow->de_state, - (STREAM_TOSERVER|STREAM_TOCLIENT)); - DetectEngineStateResetTxs(pflow); - } - - /* set the iponly stuff */ - if (pflow->flags & FLOW_TOCLIENT_IPONLY_SET) - p->flowflags |= FLOW_PKT_TOCLIENT_IPONLY_SET; - if (pflow->flags & FLOW_TOSERVER_IPONLY_SET) - p->flowflags |= FLOW_PKT_TOSERVER_IPONLY_SET; - - /* Get the stored sgh from the flow (if any). Make sure we're not using - * the sgh for icmp error packets part of the same stream. */ - if (IP_GET_IPPROTO(p) == pflow->proto) { /* filter out icmp */ - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_GETSGH); - if ((p->flowflags & FLOW_PKT_TOSERVER) && (pflow->flags & FLOW_SGH_TOSERVER)) { - det_ctx->sgh = pflow->sgh_toserver; - sms_runflags |= SMS_USE_FLOW_SGH; - } else if ((p->flowflags & FLOW_PKT_TOCLIENT) && (pflow->flags & FLOW_SGH_TOCLIENT)) { - det_ctx->sgh = pflow->sgh_toclient; - sms_runflags |= SMS_USE_FLOW_SGH; - } - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_GETSGH); - - smsg = SigMatchSignaturesGetSmsg(pflow, p, flow_flags); -#if 0 - StreamMsg *tmpsmsg = smsg; - while (tmpsmsg) { - printf("detect ---start---:\n"); - PrintRawDataFp(stdout,tmpsmsg->data.data,tmpsmsg->data.data_len); - printf("detect ---end---:\n"); - tmpsmsg = tmpsmsg->next; - } -#endif - } - - /* Retrieve the app layer state and protocol and the tcp reassembled - * stream chunks. */ - if ((p->proto == IPPROTO_TCP && (p->flags & PKT_STREAM_EST)) || - (p->proto == IPPROTO_UDP) || - (p->proto == IPPROTO_SCTP && (p->flowflags & FLOW_PKT_ESTABLISHED))) - { - /* update flow flags with knowledge on disruptions */ - flow_flags = FlowGetDisruptionFlags(pflow, flow_flags); - has_state = (FlowGetAppState(pflow) != NULL); - alproto = FlowGetAppProtocol(pflow); - alversion = AppLayerParserGetStateVersion(pflow->alparser); - SCLogDebug("alstate %s, alproto %u", has_state ? "true" : "false", alproto); - } else { - SCLogDebug("packet doesn't have established flag set (proto %d)", p->proto); - } - - app_decoder_events = AppLayerParserHasDecoderEvents(pflow->proto, - pflow->alproto, - pflow->alstate, - pflow->alparser, - flow_flags); - } - FLOWLOCK_UNLOCK(pflow); - - if (((p->flowflags & FLOW_PKT_TOSERVER) && !(p->flowflags & FLOW_PKT_TOSERVER_IPONLY_SET)) || - ((p->flowflags & FLOW_PKT_TOCLIENT) && !(p->flowflags & FLOW_PKT_TOCLIENT_IPONLY_SET))) - { - SCLogDebug("testing against \"ip-only\" signatures"); - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_IPONLY); - IPOnlyMatchPacket(th_v, de_ctx, det_ctx, &de_ctx->io_ctx, &det_ctx->io_ctx, p); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_IPONLY); - - /* save in the flow that we scanned this direction... locking is - * done in the FlowSetIPOnlyFlag function. */ - FlowSetIPOnlyFlag(pflow, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0); - - } else if (((p->flowflags & FLOW_PKT_TOSERVER) && - (pflow->flags & FLOW_TOSERVER_IPONLY_SET)) || - ((p->flowflags & FLOW_PKT_TOCLIENT) && - (pflow->flags & FLOW_TOCLIENT_IPONLY_SET))) - { - /* If we have a drop from IP only module, - * we will drop the rest of the flow packets - * This will apply only to inline/IPS */ - if (pflow->flags & FLOW_ACTION_DROP) - { - alert_flags = PACKET_ALERT_FLAG_DROP_FLOW; - PACKET_DROP(p); - } - } - - if (!(sms_runflags & SMS_USE_FLOW_SGH)) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_GETSGH); - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_GETSGH); - } - -#ifdef DEBUG - if (pflow) { - SCMutexLock(&pflow->m); - DebugInspectIds(p, pflow, smsg); - SCMutexUnlock(&pflow->m); - } -#endif - } else { /* p->flags & PKT_HAS_FLOW */ - /* no flow */ - - /* Even without flow we should match the packet src/dst */ - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_IPONLY); - IPOnlyMatchPacket(th_v, de_ctx, det_ctx, &de_ctx->io_ctx, - &det_ctx->io_ctx, p); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_IPONLY); - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_GETSGH); - det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_GETSGH); - } - - /* if we didn't get a sig group head, we - * have nothing to do.... */ - if (det_ctx->sgh == NULL) { - SCLogDebug("no sgh for this packet, nothing to match against"); - goto end; - } - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL); - /* stateful app layer detection */ - if ((p->flags & PKT_HAS_FLOW) && has_state) { - memset(det_ctx->de_state_sig_array, 0x00, det_ctx->de_state_sig_array_len); - int has_inspectable_state = DeStateFlowHasInspectableState(pflow, alproto, alversion, flow_flags); - if (has_inspectable_state == 1) { - /* initialize to 0(DE_STATE_MATCH_HAS_NEW_STATE) */ - DeStateDetectContinueDetection(th_v, de_ctx, det_ctx, p, pflow, - flow_flags, alproto, alversion); - } else if (has_inspectable_state == 2) { - /* no inspectable state, so pretend we don't have a state at all */ - has_state = 0; - } - } - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL); - - /* create our prefilter mask */ - SignatureMask mask = 0; - PacketCreateMask(p, &mask, alproto, has_state, smsg, app_decoder_events); - - /* build and prefilter non_mpm list against the mask of the packet */ - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_NONMPMLIST); - det_ctx->non_mpm_id_cnt = 0; - if (likely(det_ctx->sgh->non_mpm_store_cnt > 0)) { - DetectPrefilterBuildNonMpmList(det_ctx, mask); - } - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_NONMPMLIST); - - /* run the mpm for each type */ - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM); - DetectMpmPrefilter(de_ctx, det_ctx, smsg, p, flow_flags, alproto, has_state, &sms_runflags); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM); -#ifdef PROFILING - if (th_v) { - StatsAddUI64(th_v, det_ctx->counter_mpm_list, - (uint64_t)det_ctx->pmq.rule_id_array_cnt); - StatsAddUI64(th_v, det_ctx->counter_nonmpm_list, - (uint64_t)det_ctx->sgh->non_mpm_store_cnt); - /* non mpm sigs after mask prefilter */ - StatsAddUI64(th_v, det_ctx->counter_fnonmpm_list, - (uint64_t)det_ctx->non_mpm_id_cnt); - } -#endif - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_PREFILTER); - DetectPrefilterMergeSort(de_ctx, det_ctx); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_PREFILTER); - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_RULES); - /* inspect the sigs against the packet */ - /* Prefetch the next signature. */ - SigIntId match_cnt = det_ctx->match_array_cnt; -#ifdef PROFILING - if (th_v) { - StatsAddUI64(th_v, det_ctx->counter_match_list, - (uint64_t)match_cnt); - } -#endif - Signature **match_array = det_ctx->match_array; - - uint32_t sflags, next_sflags = 0; - if (match_cnt) { - next_s = *match_array++; - next_sflags = next_s->flags; - } - - while (match_cnt--) { - RULE_PROFILING_START(p); - state_alert = 0; -#ifdef PROFILING - smatch = 0; -#endif - - s = next_s; - sflags = next_sflags; - if (match_cnt) { - next_s = *match_array++; - next_sflags = next_s->flags; - } - uint8_t s_proto_flags = s->proto.flags; - - SCLogDebug("inspecting signature id %"PRIu32"", s->id); - - /* if the sig has alproto and the session as well they should match */ - if (likely(sflags & SIG_FLAG_APPLAYER)) { - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != alproto) { - if (s->alproto == ALPROTO_DCERPC) { - if (alproto != ALPROTO_SMB && alproto != ALPROTO_SMB2) { - SCLogDebug("DCERPC sig, alproto not SMB or SMB2"); - goto next; - } - } else { - SCLogDebug("alproto mismatch"); - goto next; - } - } - } - - if (unlikely(sflags & SIG_FLAG_DSIZE)) { - if (likely(p->payload_len < s->dsize_low || p->payload_len > s->dsize_high)) { - SCLogDebug("kicked out as p->payload_len %u, dsize low %u, hi %u", - p->payload_len, s->dsize_low, s->dsize_high); - goto next; - } - } - - /* check for a pattern match of the one pattern in this sig. */ - if (likely(sflags & (SIG_FLAG_MPM_PACKET|SIG_FLAG_MPM_STREAM|SIG_FLAG_MPM_APPLAYER))) { - /* filter out sigs that want pattern matches, but - * have no matches */ - if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_pattern_id_div_8)] & s->mpm_pattern_id_mod_8)) { - if (sflags & SIG_FLAG_MPM_PACKET) { - if (!(sflags & SIG_FLAG_MPM_PACKET_NEG)) { - goto next; - } - } else if (sflags & SIG_FLAG_MPM_STREAM) { - /* filter out sigs that want pattern matches, but - * have no matches */ - if (!(sflags & SIG_FLAG_MPM_STREAM_NEG)) { - goto next; - } - } else if (sflags & SIG_FLAG_MPM_APPLAYER) { - if (!(sflags & SIG_FLAG_MPM_APPLAYER_NEG)) { - goto next; - } - } - } - } - if (sflags & SIG_FLAG_STATE_MATCH) { - if (det_ctx->de_state_sig_array[s->num] & DE_STATE_MATCH_NO_NEW_STATE) - goto next; - } - - /* check if this signature has a requirement for flowvars of some type - * and if so, if we actually have any in the flow. If not, the sig - * can't match and we skip it. */ - if ((p->flags & PKT_HAS_FLOW) && (sflags & SIG_FLAG_REQUIRE_FLOWVAR)) { - FLOWLOCK_RDLOCK(pflow); - int m = pflow->flowvar ? 1 : 0; - FLOWLOCK_UNLOCK(pflow); - - /* no flowvars? skip this sig */ - if (m == 0) { - SCLogDebug("skipping sig as the flow has no flowvars and sig " - "has SIG_FLAG_REQUIRE_FLOWVAR flag set."); - goto next; - } - } - - if ((s_proto_flags & DETECT_PROTO_IPV4) && !PKT_IS_IPV4(p)) { - SCLogDebug("ip version didn't match"); - goto next; - } - if ((s_proto_flags & DETECT_PROTO_IPV6) && !PKT_IS_IPV6(p)) { - SCLogDebug("ip version didn't match"); - goto next; - } - - if (DetectProtoContainsProto(&s->proto, IP_GET_IPPROTO(p)) == 0) { - SCLogDebug("proto didn't match"); - goto next; - } - - /* check the source & dst port in the sig */ - if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) { - if (!(sflags & SIG_FLAG_DP_ANY)) { - if (p->flags & PKT_IS_FRAGMENT) - goto next; - DetectPort *dport = DetectPortLookupGroup(s->dp,p->dp); - if (dport == NULL) { - SCLogDebug("dport didn't match."); - goto next; - } - } - if (!(sflags & SIG_FLAG_SP_ANY)) { - if (p->flags & PKT_IS_FRAGMENT) - goto next; - DetectPort *sport = DetectPortLookupGroup(s->sp,p->sp); - if (sport == NULL) { - SCLogDebug("sport didn't match."); - goto next; - } - } - } else if ((sflags & (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) != (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) { - SCLogDebug("port-less protocol and sig needs ports"); - goto next; - } - - /* check the destination address */ - if (!(sflags & SIG_FLAG_DST_ANY)) { - if (PKT_IS_IPV4(p)) { - if (DetectAddressMatchIPv4(s->addr_dst_match4, s->addr_dst_match4_cnt, &p->dst) == 0) - goto next; - } else if (PKT_IS_IPV6(p)) { - if (DetectAddressMatchIPv6(s->addr_dst_match6, s->addr_dst_match6_cnt, &p->dst) == 0) - goto next; - } - } - /* check the source address */ - if (!(sflags & SIG_FLAG_SRC_ANY)) { - if (PKT_IS_IPV4(p)) { - if (DetectAddressMatchIPv4(s->addr_src_match4, s->addr_src_match4_cnt, &p->src) == 0) - goto next; - } else if (PKT_IS_IPV6(p)) { - if (DetectAddressMatchIPv6(s->addr_src_match6, s->addr_src_match6_cnt, &p->src) == 0) - goto next; - } - } - - /* Check the payload keywords. If we are a MPM sig and we've made - * to here, we've had at least one of the patterns match */ - if (s->sm_arrays[DETECT_SM_LIST_PMATCH] != NULL) { - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_PMATCH); - /* if we have stream msgs, inspect against those first, - * but not for a "dsize" signature */ - if (sflags & SIG_FLAG_REQUIRE_STREAM) { - char pmatch = 0; - if (smsg != NULL) { - uint8_t pmq_idx = 0; - StreamMsg *smsg_inspect = smsg; - for ( ; smsg_inspect != NULL; smsg_inspect = smsg_inspect->next, pmq_idx++) { - /* filter out sigs that want pattern matches, but - * have no matches */ - if ((sflags & SIG_FLAG_MPM_STREAM) && !(sflags & SIG_FLAG_MPM_STREAM_NEG) && - !(det_ctx->smsg_pmq[pmq_idx].pattern_id_bitarray[(s->mpm_pattern_id_div_8)] & s->mpm_pattern_id_mod_8)) { - SCLogDebug("no match in this smsg"); - continue; - } - - if (DetectEngineInspectStreamPayload(de_ctx, det_ctx, s, pflow, smsg_inspect->data, smsg_inspect->data_len) == 1) { - SCLogDebug("match in smsg %p", smsg); - pmatch = 1; - det_ctx->flags |= DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH; - /* Tell the engine that this reassembled stream can drop the - * rest of the pkts with no further inspection */ - if (s->action & ACTION_DROP) - alert_flags |= PACKET_ALERT_FLAG_DROP_FLOW; - - alert_flags |= PACKET_ALERT_FLAG_STREAM_MATCH; - break; - } - } - - } /* if (smsg != NULL) */ - - /* no match? then inspect packet payload */ - if (pmatch == 0) { - SCLogDebug("no match in smsg, fall back to packet payload"); - - if (!(sflags & SIG_FLAG_REQUIRE_PACKET)) { - if (p->flags & PKT_STREAM_ADD) - goto next; - } - - if (sms_runflags & SMS_USED_PM) { - if ((sflags & SIG_FLAG_MPM_PACKET) && !(sflags & SIG_FLAG_MPM_PACKET_NEG) && - !(det_ctx->pmq.pattern_id_bitarray[(s->mpm_pattern_id_div_8)] & - s->mpm_pattern_id_mod_8)) { - goto next; - } - if (DetectEngineInspectPacketPayload(de_ctx, det_ctx, s, pflow, p) != 1) { - goto next; - } - } else { - if (DetectEngineInspectPacketPayload(de_ctx, det_ctx, s, pflow, p) != 1) { - goto next; - } - } - } - } else { - if (sms_runflags & SMS_USED_PM) { - if ((sflags & SIG_FLAG_MPM_PACKET) && !(sflags & SIG_FLAG_MPM_PACKET_NEG) && - !(det_ctx->pmq.pattern_id_bitarray[(s->mpm_pattern_id_div_8)] & - s->mpm_pattern_id_mod_8)) { - goto next; - } - if (DetectEngineInspectPacketPayload(de_ctx, det_ctx, s, pflow, p) != 1) { - goto next; - } - } else { - if (DetectEngineInspectPacketPayload(de_ctx, det_ctx, s, pflow, p) != 1) - goto next; - } - } - } - - /* run the packet match functions */ - if (s->sm_arrays[DETECT_SM_LIST_MATCH] != NULL) { - KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_MATCH); - SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_MATCH]; - - SCLogDebug("running match functions, sm %p", smd); - if (smd != NULL) { - while (1) { - KEYWORD_PROFILING_START; - if (sigmatch_table[smd->type].Match(th_v, det_ctx, p, s, smd->ctx) <= 0) { - KEYWORD_PROFILING_END(det_ctx, smd->type, 0); - goto next; - } - KEYWORD_PROFILING_END(det_ctx, smd->type, 1); - if (smd->is_last) - break; - smd++; - } - } - } - - SCLogDebug("s->sm_lists[DETECT_SM_LIST_AMATCH] %p, " - "s->sm_lists[DETECT_SM_LIST_UMATCH] %p, " - "s->sm_lists[DETECT_SM_LIST_DMATCH] %p, " - "s->sm_lists[DETECT_SM_LIST_HCDMATCH] %p", - s->sm_lists[DETECT_SM_LIST_AMATCH], - s->sm_lists[DETECT_SM_LIST_UMATCH], - s->sm_lists[DETECT_SM_LIST_DMATCH], - s->sm_lists[DETECT_SM_LIST_HCDMATCH]); - - /* consider stateful sig matches */ - if (sflags & SIG_FLAG_STATE_MATCH) { - if (has_state == 0) { - SCLogDebug("state matches but no state, we can't match"); - goto next; - } - - SCLogDebug("stateful app layer match inspection starting"); - - /* if DeStateDetectStartDetection matches, it's a full - * signature match. It will then call PacketAlertAppend - * itself, so we can skip it below. This is done so it - * can store the tx_id with the alert */ - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL); - state_alert = DeStateDetectStartDetection(th_v, de_ctx, det_ctx, s, - p, pflow, flow_flags, alproto, alversion); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL); - if (state_alert == 0) - goto next; - - /* match */ - if (s->action & ACTION_DROP) - alert_flags |= PACKET_ALERT_FLAG_DROP_FLOW; - - alert_flags |= PACKET_ALERT_FLAG_STATE_MATCH; - } - -#ifdef PROFILING - smatch = 1; -#endif - - SigMatchSignaturesRunPostMatch(th_v, de_ctx, det_ctx, p, s); - - if (!(sflags & SIG_FLAG_NOALERT)) { - /* stateful sigs call PacketAlertAppend from DeStateDetectStartDetection */ - if (!state_alert) - PacketAlertAppend(det_ctx, s, p, 0, alert_flags); - } else { - /* apply actions even if not alerting */ - DetectSignatureApplyActions(p, s); - } - alerts++; -next: - DetectFlowvarProcessList(det_ctx, pflow); - DetectReplaceFree(det_ctx); - RULE_PROFILING_END(det_ctx, s, smatch, p); - - det_ctx->flags = 0; - continue; - } - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_RULES); - -end: -#ifdef __SC_CUDA_SUPPORT__ - CudaReleasePacket(p); -#endif - - /* see if we need to increment the inspect_id and reset the de_state */ - if (has_state && AppLayerParserProtocolSupportsTxs(p->proto, alproto)) { - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL); - DeStateUpdateInspectTransactionId(pflow, flow_flags); - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL); - } - - /* so now let's iterate the alerts and remove the ones after a pass rule - * matched (if any). This is done inside PacketAlertFinalize() */ - /* PR: installed "tag" keywords are handled after the threshold inspection */ - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_ALERT); - PacketAlertFinalize(de_ctx, det_ctx, p); - if (p->alerts.cnt > 0) { - StatsAddUI64(th_v, det_ctx->counter_alerts, (uint64_t)p->alerts.cnt); - } - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_ALERT); - - PACKET_PROFILING_DETECT_START(p, PROF_DETECT_CLEANUP); - /* cleanup pkt specific part of the patternmatcher */ - PacketPatternCleanup(th_v, det_ctx); - - DetectEngineCleanHCBDBuffers(det_ctx); - DetectEngineCleanHSBDBuffers(det_ctx); - DetectEngineCleanHHDBuffers(det_ctx); - - /* store the found sgh (or NULL) in the flow to save us from looking it - * up again for the next packet. Also return any stream chunk we processed - * to the pool. */ - if (p->flags & PKT_HAS_FLOW) { - if (sms_runflags & SMS_USED_STREAM_PM) { - StreamPatternCleanup(th_v, det_ctx, smsg); - } - - FLOWLOCK_WRLOCK(pflow); - if (debuglog_enabled) { - if (p->alerts.cnt > 0) { - AlertDebugLogModeSyncFlowbitsNamesToPacketStruct(p, de_ctx); - } - } - - if (!(sms_runflags & SMS_USE_FLOW_SGH)) { - if ((p->flowflags & FLOW_PKT_TOSERVER) && !(pflow->flags & FLOW_SGH_TOSERVER)) { - /* first time we see this toserver sgh, store it */ - pflow->sgh_toserver = det_ctx->sgh; - pflow->flags |= FLOW_SGH_TOSERVER; - - /* see if this sgh requires us to consider file storing */ - if (pflow->sgh_toserver == NULL || pflow->sgh_toserver->filestore_cnt == 0) { - FileDisableStoring(pflow, STREAM_TOSERVER); - } - - /* see if this sgh requires us to consider file magic */ - if (!FileForceMagic() && (pflow->sgh_toserver == NULL || - !(pflow->sgh_toserver->flags & SIG_GROUP_HEAD_HAVEFILEMAGIC))) - { - SCLogDebug("disabling magic for flow"); - FileDisableMagic(pflow, STREAM_TOSERVER); - } - - /* see if this sgh requires us to consider file md5 */ - if (!FileForceMd5() && (pflow->sgh_toserver == NULL || - !(pflow->sgh_toserver->flags & SIG_GROUP_HEAD_HAVEFILEMD5))) - { - SCLogDebug("disabling md5 for flow"); - FileDisableMd5(pflow, STREAM_TOSERVER); - } - - /* see if this sgh requires us to consider filesize */ - if (pflow->sgh_toserver == NULL || - !(pflow->sgh_toserver->flags & SIG_GROUP_HEAD_HAVEFILESIZE)) - { - SCLogDebug("disabling filesize for flow"); - FileDisableFilesize(pflow, STREAM_TOSERVER); - } - } else if ((p->flowflags & FLOW_PKT_TOCLIENT) && !(pflow->flags & FLOW_SGH_TOCLIENT)) { - pflow->sgh_toclient = det_ctx->sgh; - pflow->flags |= FLOW_SGH_TOCLIENT; - - if (pflow->sgh_toclient == NULL || pflow->sgh_toclient->filestore_cnt == 0) { - FileDisableStoring(pflow, STREAM_TOCLIENT); - } - - /* check if this flow needs magic, if not disable it */ - if (!FileForceMagic() && (pflow->sgh_toclient == NULL || - !(pflow->sgh_toclient->flags & SIG_GROUP_HEAD_HAVEFILEMAGIC))) - { - SCLogDebug("disabling magic for flow"); - FileDisableMagic(pflow, STREAM_TOCLIENT); - } - - /* check if this flow needs md5, if not disable it */ - if (!FileForceMd5() && (pflow->sgh_toclient == NULL || - !(pflow->sgh_toclient->flags & SIG_GROUP_HEAD_HAVEFILEMD5))) - { - SCLogDebug("disabling md5 for flow"); - FileDisableMd5(pflow, STREAM_TOCLIENT); - } - - /* see if this sgh requires us to consider filesize */ - if (pflow->sgh_toclient == NULL || - !(pflow->sgh_toclient->flags & SIG_GROUP_HEAD_HAVEFILESIZE)) - { - SCLogDebug("disabling filesize for flow"); - FileDisableFilesize(pflow, STREAM_TOCLIENT); - } - } - } - - /* if we had no alerts that involved the smsgs, - * we can get rid of them now. */ - StreamMsgReturnListToPool(smsg); - - FLOWLOCK_UNLOCK(pflow); - } - PACKET_PROFILING_DETECT_END(p, PROF_DETECT_CLEANUP); - - SCReturnInt((int)(alerts > 0)); -} - -/** \brief Apply action(s) and Set 'drop' sig info, - * if applicable */ -void DetectSignatureApplyActions(Packet *p, const Signature *s) -{ - PACKET_UPDATE_ACTION(p, s->action); - - if (s->action & ACTION_DROP) { - if (p->alerts.drop.action == 0) { - p->alerts.drop.num = s->num; - p->alerts.drop.action = s->action; - p->alerts.drop.s = (Signature *)s; - } - } -} - -/* tm module api functions */ - -static DetectEngineThreadCtx *GetTenantById(HashTable *h, uint32_t id) -{ - /* technically we need to pass a DetectEngineThreadCtx struct with the - * tentant_id member. But as that member is the first in the struct, we - * can use the id directly. */ - return HashTableLookup(h, &id, 0); -} - -/** \brief Detection engine thread wrapper. - * \param tv thread vars - * \param p packet to inspect - * \param data thread specific data - * \param pq packet queue - * \retval TM_ECODE_FAILED error - * \retval TM_ECODE_OK ok - */ -TmEcode Detect(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - DEBUG_VALIDATE_PACKET(p); - - /* No need to perform any detection on this packet, if the the given flag is set.*/ - if ((p->flags & PKT_NOPACKET_INSPECTION) || - (PACKET_TEST_ACTION(p, ACTION_DROP))) - { - /* hack: if we are in pass the entire flow mode, we need to still - * update the inspect_id forward. So test for the condition here, - * and call the update code if necessary. */ - if (p->flow) { - uint8_t flags = 0; - FLOWLOCK_RDLOCK(p->flow); - int pass = ((p->flow->flags & FLOW_NOPACKET_INSPECTION)); - flags = FlowGetDisruptionFlags(p->flow, flags); - AppProto alproto = FlowGetAppProtocol(p->flow); - FLOWLOCK_UNLOCK(p->flow); - if (pass && AppLayerParserProtocolSupportsTxs(p->proto, alproto)) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - flags |= STREAM_TOSERVER; - } else { - flags |= STREAM_TOCLIENT; - } - DeStateUpdateInspectTransactionId(p->flow, flags); - } - } - return 0; - } - - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = (DetectEngineThreadCtx *)data; - if (det_ctx == NULL) { - printf("ERROR: Detect has no thread ctx\n"); - goto error; - } - - if (SC_ATOMIC_GET(det_ctx->so_far_used_by_detect) == 0) { - (void)SC_ATOMIC_SET(det_ctx->so_far_used_by_detect, 1); - SCLogDebug("Detect Engine using new det_ctx - %p", - det_ctx); - } - - /* if in MT mode _and_ we have tenants registered, use - * MT logic. */ - if (det_ctx->mt_det_ctxs_cnt > 0 && det_ctx->TenantGetId != NULL) - { - uint32_t tenant_id = p->tenant_id; - if (tenant_id == 0) - tenant_id = det_ctx->TenantGetId(det_ctx, p); - if (tenant_id > 0 && tenant_id < det_ctx->mt_det_ctxs_cnt) { - p->tenant_id = tenant_id; - det_ctx = GetTenantById(det_ctx->mt_det_ctxs_hash, tenant_id); - if (det_ctx == NULL) - return TM_ECODE_OK; - de_ctx = det_ctx->de_ctx; - if (de_ctx == NULL) - return TM_ECODE_OK; - - if (SC_ATOMIC_GET(det_ctx->so_far_used_by_detect) == 0) { - (void)SC_ATOMIC_SET(det_ctx->so_far_used_by_detect, 1); - SCLogDebug("MT de_ctx %p det_ctx %p (tenant %u)", de_ctx, det_ctx, tenant_id); - } - } else { - /* use default if no tenants are registered for this packet */ - de_ctx = det_ctx->de_ctx; - } - } else { - de_ctx = det_ctx->de_ctx; - } - - /* see if the packet matches one or more of the sigs */ - int r = SigMatchSignatures(tv,de_ctx,det_ctx,p); - if (r >= 0) { - return TM_ECODE_OK; - } - -error: - return TM_ECODE_FAILED; -} - -TmEcode DetectThreadInit(ThreadVars *t, void *initdata, void **data) -{ - return DetectEngineThreadCtxInit(t,initdata,data); -} - -TmEcode DetectThreadDeinit(ThreadVars *t, void *data) -{ - return DetectEngineThreadCtxDeinit(t,data); -} - -void SigCleanSignatures(DetectEngineCtx *de_ctx) -{ - Signature *s = NULL, *ns; - - if (de_ctx == NULL) - return; - - for (s = de_ctx->sig_list; s != NULL;) { - ns = s->next; - SigFree(s); - s = ns; - } - - de_ctx->sig_list = NULL; - - DetectEngineResetMaxSigId(de_ctx); - de_ctx->sig_list = NULL; -} - -/** \brief Find a specific signature by sid and gid - * \param de_ctx detection engine ctx - * \param sid the signature id - * \param gid the signature group id - * - * \retval s sig found - * \retval NULL sig not found - */ -Signature *SigFindSignatureBySidGid(DetectEngineCtx *de_ctx, uint32_t sid, uint32_t gid) -{ - Signature *s = NULL; - - if (de_ctx == NULL) - return NULL; - - for (s = de_ctx->sig_list; s != NULL; s = s->next) { - if (s->id == sid && s->gid == gid) - return s; - } - - return NULL; -} - - -int SignatureIsAppLayer(DetectEngineCtx *de_ctx, Signature *s) -{ - if (s->alproto != 0) - return 1; - - return 0; -} - -/** - * \brief Check if a signature contains the filestore keyword. - * - * \param s signature - * - * \retval 0 no - * \retval 1 yes - */ -int SignatureIsFilestoring(Signature *s) -{ - if (s == NULL) - return 0; - - if (s->flags & SIG_FLAG_FILESTORE) - return 1; - - return 0; -} - -/** - * \brief Check if a signature contains the filemagic keyword. - * - * \param s signature - * - * \retval 0 no - * \retval 1 yes - */ -int SignatureIsFilemagicInspecting(Signature *s) -{ - if (s == NULL) - return 0; - - if (s->file_flags & FILE_SIG_NEED_MAGIC) - return 1; - - return 0; -} - -/** - * \brief Check if a signature contains the filemd5 keyword. - * - * \param s signature - * - * \retval 0 no - * \retval 1 yes - */ -int SignatureIsFileMd5Inspecting(Signature *s) -{ - if (s == NULL) - return 0; - - if (s->file_flags & FILE_SIG_NEED_MD5) - return 1; - - return 0; -} - -/** - * \brief Check if a signature contains the filesize keyword. - * - * \param s signature - * - * \retval 0 no - * \retval 1 yes - */ -int SignatureIsFilesizeInspecting(Signature *s) -{ - if (s == NULL) - return 0; - - if (s->file_flags & FILE_SIG_NEED_SIZE) - return 1; - - return 0; -} - -/** \brief Test is a initialized signature is IP only - * \param de_ctx detection engine ctx - * \param s the signature - * \retval 1 sig is ip only - * \retval 0 sig is not ip only - */ -int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) -{ - if (s->alproto != ALPROTO_UNKNOWN) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_FILEDATA] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HHHDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_HRHHDMATCH] != NULL) - return 0; - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) - return 0; - - /* TMATCH list can be ignored, it contains TAGs and - * tags are compatible to IP-only. */ - - IPOnlyCIDRItem *cidr_item; - cidr_item = s->CidrSrc; - while (cidr_item != NULL) { - if (cidr_item->negated) - return 0; - - cidr_item = cidr_item->next; - } - cidr_item = s->CidrDst; - while (cidr_item != NULL) { - if (cidr_item->negated) - return 0; - - cidr_item = cidr_item->next; - } - - SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - if (sm == NULL) - goto iponly; - - for ( ; sm != NULL; sm = sm->next) { - if ( !(sigmatch_table[sm->type].flags & SIGMATCH_IPONLY_COMPAT)) - return 0; - /* we have enabled flowbits to be compatible with ip only sigs, as long - * as the sig only has a "set" flowbits */ - if (sm->type == DETECT_FLOWBITS && - (((DetectFlowbitsData *)sm->ctx)->cmd != DETECT_FLOWBITS_CMD_SET) ) { - return 0; - } - } - -iponly: - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("IP-ONLY (%" PRIu32 "): source %s, dest %s", s->id, - s->flags & SIG_FLAG_SRC_ANY ? "ANY" : "SET", - s->flags & SIG_FLAG_DST_ANY ? "ANY" : "SET"); - } - return 1; -} - -/** - * \internal - * \brief Check if the initialized signature is inspecting the packet payload - * \param de_ctx detection engine ctx - * \param s the signature - * \retval 1 sig is inspecting the payload - * \retval 0 sig is not inspecting the payload - */ -static int SignatureIsInspectingPayload(DetectEngineCtx *de_ctx, Signature *s) -{ - - if (s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - return 1; - } -#if 0 - SigMatch *sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm == NULL) - return 0; - - for (; sm != NULL; sm = sm->next) { - if (sigmatch_table[sm->type].flags & SIGMATCH_PAYLOAD) { - if (!(de_ctx->flags & DE_QUIET)) - SCLogDebug("Signature (%" PRIu32 "): is inspecting payload.", s->id); - return 1; - } - } -#endif - return 0; -} - -/** - * \internal - * \brief check if a signature is decoder event matching only - * \param de_ctx detection engine - * \param s the signature to test - * \retval 0 not a DEOnly sig - * \retval 1 DEOnly sig - */ -static int SignatureIsDEOnly(DetectEngineCtx *de_ctx, Signature *s) -{ - if (s->alproto != ALPROTO_UNKNOWN) { - SCReturnInt(0); - } - - if (s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_FILEDATA] != NULL || - s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HHHDMATCH] != NULL || - s->sm_lists[DETECT_SM_LIST_HRHHDMATCH] != NULL) - { - SCReturnInt(0); - } - - /* check for conflicting keywords */ - SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - for ( ;sm != NULL; sm = sm->next) { - if ( !(sigmatch_table[sm->type].flags & SIGMATCH_DEONLY_COMPAT)) - SCReturnInt(0); - } - - /* need at least one decode event keyword to be considered decode event. */ - sm = s->sm_lists[DETECT_SM_LIST_MATCH]; - for ( ;sm != NULL; sm = sm->next) { - if (sm->type == DETECT_DECODE_EVENT) - goto deonly; - if (sm->type == DETECT_ENGINE_EVENT) - goto deonly; - if (sm->type == DETECT_STREAM_EVENT) - goto deonly; - } - - SCReturnInt(0); - -deonly: - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("DE-ONLY (%" PRIu32 "): source %s, dest %s", s->id, - s->flags & SIG_FLAG_SRC_ANY ? "ANY" : "SET", - s->flags & SIG_FLAG_DST_ANY ? "ANY" : "SET"); - } - - SCReturnInt(1); -} - -#define MASK_TCP_INITDEINIT_FLAGS (TH_SYN|TH_RST|TH_FIN) -#define MASK_TCP_UNUSUAL_FLAGS (TH_URG|TH_ECN|TH_CWR) - -/* Create mask for this packet + it's flow if it has one - * - * Sets SIG_MASK_REQUIRE_PAYLOAD, SIG_MASK_REQUIRE_FLOW, - * SIG_MASK_REQUIRE_HTTP_STATE, SIG_MASK_REQUIRE_DCE_STATE - */ -static void -PacketCreateMask(Packet *p, SignatureMask *mask, AppProto alproto, int has_state, StreamMsg *smsg, - int app_decoder_events) -{ - /* no payload inspect flag doesn't apply to smsg */ - if (smsg != NULL || (!(p->flags & PKT_NOPAYLOAD_INSPECTION) && p->payload_len > 0)) { - SCLogDebug("packet has payload"); - (*mask) |= SIG_MASK_REQUIRE_PAYLOAD; - } else { - SCLogDebug("packet has no payload"); - (*mask) |= SIG_MASK_REQUIRE_NO_PAYLOAD; - } - - if (p->events.cnt > 0 || app_decoder_events != 0 || p->app_layer_events != NULL) { - SCLogDebug("packet/flow has events set"); - (*mask) |= SIG_MASK_REQUIRE_ENGINE_EVENT; - } - - if (PKT_IS_TCP(p)) { - if ((p->tcph->th_flags & MASK_TCP_INITDEINIT_FLAGS) != 0) { - (*mask) |= SIG_MASK_REQUIRE_FLAGS_INITDEINIT; - } - if ((p->tcph->th_flags & MASK_TCP_UNUSUAL_FLAGS) != 0) { - (*mask) |= SIG_MASK_REQUIRE_FLAGS_UNUSUAL; - } - } - - if (p->flags & PKT_HAS_FLOW) { - SCLogDebug("packet has flow"); - (*mask) |= SIG_MASK_REQUIRE_FLOW; - - if (has_state) { - switch(alproto) { - case ALPROTO_HTTP: - SCLogDebug("packet/flow has http state"); - (*mask) |= SIG_MASK_REQUIRE_HTTP_STATE; - break; - case ALPROTO_SMB: - case ALPROTO_SMB2: - case ALPROTO_DCERPC: - SCLogDebug("packet/flow has dce state"); - (*mask) |= SIG_MASK_REQUIRE_DCE_STATE; - break; - case ALPROTO_SSH: - SCLogDebug("packet/flow has ssh state"); - (*mask) |= SIG_MASK_REQUIRE_SSH_STATE; - break; - case ALPROTO_TLS: - SCLogDebug("packet/flow has tls state"); - (*mask) |= SIG_MASK_REQUIRE_TLS_STATE; - break; - case ALPROTO_DNS: - SCLogDebug("packet/flow has dns state"); - (*mask) |= SIG_MASK_REQUIRE_DNS_STATE; - break; - case ALPROTO_FTP: - SCLogDebug("packet/flow has ftp state"); - (*mask) |= SIG_MASK_REQUIRE_FTP_STATE; - break; - case ALPROTO_SMTP: - SCLogDebug("packet/flow has smtp state"); - (*mask) |= SIG_MASK_REQUIRE_SMTP_STATE; - break; - case ALPROTO_TEMPLATE: - SCLogDebug("packet/flow has template state"); - (*mask) |= SIG_MASK_REQUIRE_TEMPLATE_STATE; - break; - default: - SCLogDebug("packet/flow has other state"); - break; - } - } else { - SCLogDebug("no alstate"); - } - } -} - -static int SignatureCreateMask(Signature *s) -{ - SCEnter(); - - if (s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_PAYLOAD; - SCLogDebug("sig requires payload"); - } - - if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_DCE_STATE; - SCLogDebug("sig requires dce state"); - } - - if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_FILEDATA] != NULL) { - /* set the state depending from the protocol */ - if (s->alproto == ALPROTO_HTTP) - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - else if (s->alproto == ALPROTO_SMTP) - s->mask |= SIG_MASK_REQUIRE_SMTP_STATE; - - SCLogDebug("sig requires http or smtp app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HHHDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - if (s->sm_lists[DETECT_SM_LIST_HRHHDMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires http app state"); - } - - SigMatch *sm; - for (sm = s->sm_lists[DETECT_SM_LIST_AMATCH] ; sm != NULL; sm = sm->next) { - switch(sm->type) { - case DETECT_AL_URILEN: - case DETECT_AL_HTTP_URI: - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig requires dce http state"); - break; - case DETECT_AL_APP_LAYER_EVENT: - s->mask |= SIG_MASK_REQUIRE_ENGINE_EVENT; - break; - } - } - - for (sm = s->sm_lists[DETECT_SM_LIST_APP_EVENT] ; sm != NULL; sm = sm->next) { - switch (sm->type) { - case DETECT_AL_APP_LAYER_EVENT: - { - DetectAppLayerEventData *aed = (DetectAppLayerEventData *)sm->ctx; - switch (aed->alproto) { - case ALPROTO_HTTP: - s->mask |= SIG_MASK_REQUIRE_HTTP_STATE; - SCLogDebug("sig %u requires http app state (http event)", s->id); - break; - case ALPROTO_SMTP: - s->mask |= SIG_MASK_REQUIRE_SMTP_STATE; - SCLogDebug("sig %u requires smtp app state (smtp event)", s->id); - break; - case ALPROTO_DNS: - s->mask |= SIG_MASK_REQUIRE_DNS_STATE; - SCLogDebug("sig %u requires dns app state (dns event)", s->id); - break; - } - break; - } - } - } - - for (sm = s->sm_lists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) { - switch(sm->type) { - case DETECT_FLOWBITS: - { - /* figure out what flowbit action */ - DetectFlowbitsData *fb = (DetectFlowbitsData *)sm->ctx; - if (fb->cmd == DETECT_FLOWBITS_CMD_ISSET) { - /* not a mask flag, but still set it here */ - s->flags |= SIG_FLAG_REQUIRE_FLOWVAR; - - SCLogDebug("SIG_FLAG_REQUIRE_FLOWVAR set as sig has " - "flowbit isset option."); - } - - /* flow is required for any flowbit manipulation */ - s->mask |= SIG_MASK_REQUIRE_FLOW; - SCLogDebug("sig requires flow to be able to manipulate " - "flowbit(s)"); - break; - } - case DETECT_FLAGS: - { - DetectFlagsData *fl = (DetectFlagsData *)sm->ctx; - - if (fl->flags & TH_SYN) { - s->mask |= SIG_MASK_REQUIRE_FLAGS_INITDEINIT; - SCLogDebug("sig requires SIG_MASK_REQUIRE_FLAGS_INITDEINIT"); - } - if (fl->flags & TH_RST) { - s->mask |= SIG_MASK_REQUIRE_FLAGS_INITDEINIT; - SCLogDebug("sig requires SIG_MASK_REQUIRE_FLAGS_INITDEINIT"); - } - if (fl->flags & TH_FIN) { - s->mask |= SIG_MASK_REQUIRE_FLAGS_INITDEINIT; - SCLogDebug("sig requires SIG_MASK_REQUIRE_FLAGS_INITDEINIT"); - } - if (fl->flags & TH_URG) { - s->mask |= SIG_MASK_REQUIRE_FLAGS_UNUSUAL; - SCLogDebug("sig requires SIG_MASK_REQUIRE_FLAGS_UNUSUAL"); - } - if (fl->flags & TH_ECN) { - s->mask |= SIG_MASK_REQUIRE_FLAGS_UNUSUAL; - SCLogDebug("sig requires SIG_MASK_REQUIRE_FLAGS_UNUSUAL"); - } - if (fl->flags & TH_CWR) { - s->mask |= SIG_MASK_REQUIRE_FLAGS_UNUSUAL; - SCLogDebug("sig requires SIG_MASK_REQUIRE_FLAGS_UNUSUAL"); - } - break; - } - case DETECT_DSIZE: - { - DetectDsizeData *ds = (DetectDsizeData *)sm->ctx; - switch (ds->mode) { - case DETECTDSIZE_LT: - /* LT will include 0, so no payload. - * if GT is used in the same rule the - * flag will be set anyway. */ - break; - case DETECTDSIZE_RA: - case DETECTDSIZE_GT: - s->mask |= SIG_MASK_REQUIRE_PAYLOAD; - SCLogDebug("sig requires payload"); - break; - case DETECTDSIZE_EQ: - if (ds->dsize > 0) { - s->mask |= SIG_MASK_REQUIRE_PAYLOAD; - SCLogDebug("sig requires payload"); - } else if (ds->dsize == 0) { - s->mask |= SIG_MASK_REQUIRE_NO_PAYLOAD; - SCLogDebug("sig requires no payload"); - } - break; - } - break; - } - case DETECT_AL_APP_LAYER_EVENT: - s->mask |= SIG_MASK_REQUIRE_ENGINE_EVENT; - break; - case DETECT_ENGINE_EVENT: - s->mask |= SIG_MASK_REQUIRE_ENGINE_EVENT; - break; - } - } - - if (s->alproto == ALPROTO_SSH) { - s->mask |= SIG_MASK_REQUIRE_SSH_STATE; - SCLogDebug("sig requires ssh state"); - } - if (s->alproto == ALPROTO_TLS) { - s->mask |= SIG_MASK_REQUIRE_TLS_STATE; - SCLogDebug("sig requires tls state"); - } - if (s->alproto == ALPROTO_DNS) { - s->mask |= SIG_MASK_REQUIRE_DNS_STATE; - SCLogDebug("sig requires dns state"); - } - if (s->alproto == ALPROTO_FTP) { - s->mask |= SIG_MASK_REQUIRE_FTP_STATE; - SCLogDebug("sig requires ftp state"); - } - if (s->alproto == ALPROTO_SMTP) { - s->mask |= SIG_MASK_REQUIRE_SMTP_STATE; - SCLogDebug("sig requires smtp state"); - } - if (s->alproto == ALPROTO_TEMPLATE) { - s->mask |= SIG_MASK_REQUIRE_TEMPLATE_STATE; - SCLogDebug("sig requires template state"); - } - - if ((s->mask & SIG_MASK_REQUIRE_DCE_STATE) || - (s->mask & SIG_MASK_REQUIRE_HTTP_STATE) || - (s->mask & SIG_MASK_REQUIRE_SSH_STATE) || - (s->mask & SIG_MASK_REQUIRE_DNS_STATE) || - (s->mask & SIG_MASK_REQUIRE_FTP_STATE) || - (s->mask & SIG_MASK_REQUIRE_SMTP_STATE) || - (s->mask & SIG_MASK_REQUIRE_TEMPLATE_STATE) || - (s->mask & SIG_MASK_REQUIRE_TLS_STATE)) - { - s->mask |= SIG_MASK_REQUIRE_FLOW; - SCLogDebug("sig requires flow"); - } - - if (s->init_flags & SIG_FLAG_INIT_FLOW) { - s->mask |= SIG_MASK_REQUIRE_FLOW; - SCLogDebug("sig requires flow"); - } - - if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { - s->mask |= SIG_MASK_REQUIRE_FLOW; - SCLogDebug("sig requires flow"); - } - - if (s->flags & SIG_FLAG_APPLAYER) { - s->mask |= SIG_MASK_REQUIRE_FLOW; - SCLogDebug("sig requires flow"); - } - - SCLogDebug("mask %02X", s->mask); - SCReturnInt(0); -} - -static void SigInitStandardMpmFactoryContexts(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_mpm_context_proto_tcp_packet = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "packet_proto_tcp", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_proto_udp_packet = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "packet_proto_udp", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_proto_other_packet = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "packet_proto_other", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_uri = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "uri", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_stream = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "stream", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hcbd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hcbd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hsbd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hsbd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_smtp = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "smtp", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hhd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hhd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hrhd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hrhd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hmd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hmd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hcd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hcd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hrud = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hrud", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hsmd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hsmd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hscd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hscd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_huad = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "huad", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hhhd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hhhd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_hrhhd = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "hrhhd", - MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD); - de_ctx->sgh_mpm_context_app_proto_detect = - MpmFactoryRegisterMpmCtxProfile(de_ctx, "app_proto_detect", 0); - - return; -} - -/** \brief get max dsize "depth" - * \param s signature to get dsize value from - * \retval depth or negative value - */ -static int SigParseGetMaxDsize(Signature *s) -{ - if (s->flags & SIG_FLAG_DSIZE && s->dsize_sm != NULL) { - DetectDsizeData *dd = (DetectDsizeData *)s->dsize_sm->ctx; - - switch (dd->mode) { - case DETECTDSIZE_LT: - case DETECTDSIZE_EQ: - return dd->dsize; - case DETECTDSIZE_RA: - return dd->dsize2; - case DETECTDSIZE_GT: - default: - SCReturnInt(-2); - } - } - SCReturnInt(-1); -} - -/** \brief set prefilter dsize pair - * \param s signature to get dsize value from - */ -static void SigParseSetDsizePair(Signature *s) -{ - if (s->flags & SIG_FLAG_DSIZE && s->dsize_sm != NULL) { - DetectDsizeData *dd = (DetectDsizeData *)s->dsize_sm->ctx; - - uint16_t low = 0; - uint16_t high = 65535; - - switch (dd->mode) { - case DETECTDSIZE_LT: - low = 0; - high = dd->dsize; - break; - case DETECTDSIZE_EQ: - low = dd->dsize; - high = dd->dsize; - break; - case DETECTDSIZE_RA: - low = dd->dsize; - high = dd->dsize2; - break; - case DETECTDSIZE_GT: - low = dd->dsize; - high = 65535; - break; - } - s->dsize_low = low; - s->dsize_high = high; - - SCLogDebug("low %u, high %u", low, high); - } -} - -/** - * \brief Apply dsize as depth to content matches in the rule - * \param s signature to get dsize value from - */ -static void SigParseApplyDsizeToContent(Signature *s) -{ - SCEnter(); - - if (s->flags & SIG_FLAG_DSIZE) { - SigParseSetDsizePair(s); - - int dsize = SigParseGetMaxDsize(s); - if (dsize < 0) { - /* nothing to do */ - return; - } - - SigMatch *sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - for ( ; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_CONTENT) { - continue; - } - - DetectContentData *cd = (DetectContentData *)sm->ctx; - if (cd == NULL) { - continue; - } - - if (cd->depth == 0 || cd->depth >= dsize) { - cd->depth = (uint16_t)dsize; - SCLogDebug("updated %u, content %u to have depth %u " - "because of dsize.", s->id, cd->id, cd->depth); - } - } - } -} - -/** - * \brief Preprocess signature, classify ip-only, etc, build sig array - * - * \param de_ctx Pointer to the Detection Engine Context - * - * \retval 0 on success - * \retval -1 on failure - */ -int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) -{ - Signature *tmp_s = NULL; - uint32_t cnt_iponly = 0; - uint32_t cnt_payload = 0; - uint32_t cnt_applayer = 0; - uint32_t cnt_deonly = 0; - - //DetectAddressPrintMemory(); - //DetectSigGroupPrintMemory(); - //DetectPortPrintMemory(); - - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("building signature grouping structure, stage 1: " - "preprocessing rules..."); - } - -#ifdef HAVE_LUAJIT - /* run this before the mpm states are initialized */ - if (DetectLuajitSetupStatesPool(de_ctx->detect_luajit_instances, TRUE) != 0) { - if (de_ctx->failure_fatal) - return -1; - } -#endif - - de_ctx->sig_array_len = DetectEngineGetMaxSigId(de_ctx); - de_ctx->sig_array_size = (de_ctx->sig_array_len * sizeof(Signature *)); - de_ctx->sig_array = (Signature **)SCMalloc(de_ctx->sig_array_size); - if (de_ctx->sig_array == NULL) - goto error; - memset(de_ctx->sig_array,0,de_ctx->sig_array_size); - - SCLogDebug("signature lookup array: %" PRIu32 " sigs, %" PRIu32 " bytes", - de_ctx->sig_array_len, de_ctx->sig_array_size); - - /* now for every rule add the source group */ - for (tmp_s = de_ctx->sig_list; tmp_s != NULL; tmp_s = tmp_s->next) { - de_ctx->sig_array[tmp_s->num] = tmp_s; - - SCLogDebug("Signature %" PRIu32 ", internal id %" PRIu32 ", ptrs %p %p ", tmp_s->id, tmp_s->num, tmp_s, de_ctx->sig_array[tmp_s->num]); - - /* see if the sig is ip only */ - if (SignatureIsIPOnly(de_ctx, tmp_s) == 1) { - tmp_s->flags |= SIG_FLAG_IPONLY; - cnt_iponly++; - - SCLogDebug("Signature %"PRIu32" is considered \"IP only\"", tmp_s->id); - - /* see if any sig is inspecting the packet payload */ - } else if (SignatureIsInspectingPayload(de_ctx, tmp_s) == 1) { - tmp_s->init_flags |= SIG_FLAG_INIT_PAYLOAD; - cnt_payload++; - - SCLogDebug("Signature %"PRIu32" is considered \"Payload inspecting\"", tmp_s->id); - } else if (SignatureIsDEOnly(de_ctx, tmp_s) == 1) { - tmp_s->init_flags |= SIG_FLAG_INIT_DEONLY; - SCLogDebug("Signature %"PRIu32" is considered \"Decoder Event only\"", tmp_s->id); - cnt_deonly++; - } - - if (tmp_s->flags & SIG_FLAG_APPLAYER) { - SCLogDebug("Signature %"PRIu32" is considered \"Applayer inspecting\"", tmp_s->id); - cnt_applayer++; - } - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - uint16_t colen = 0; - char copresent = 0; - SigMatch *sm; - DetectContentData *co; - for (sm = tmp_s->sm_lists[DETECT_SM_LIST_MATCH]; sm != NULL; sm = sm->next) { - if (sm->type != DETECT_CONTENT) - continue; - - copresent = 1; - co = (DetectContentData *)sm->ctx; - if (co->content_len > colen) - colen = co->content_len; - } - - if (copresent && colen == 1) { - SCLogDebug("signature %8u content maxlen 1", tmp_s->id); - int proto; - for (proto = 0; proto < 256; proto++) { - if (tmp_s->proto.proto[(proto/8)] & (1<<(proto%8))) - SCLogDebug("=> proto %" PRId32 "", proto); - } - } - } -#endif /* DEBUG */ - - SignatureCreateMask(tmp_s); - SigParseApplyDsizeToContent(tmp_s); - - de_ctx->sig_cnt++; - } - - //DetectAddressPrintMemory(); - //DetectSigGroupPrintMemory(); - //DetectPortPrintMemory(); - - if (!(de_ctx->flags & DE_QUIET)) { - SCLogInfo("%" PRIu32 " signatures processed. %" PRIu32 " are IP-only " - "rules, %" PRIu32 " are inspecting packet payload, %"PRIu32 - " inspect application layer, %"PRIu32" are decoder event only", - de_ctx->sig_cnt, cnt_iponly, cnt_payload, cnt_applayer, - cnt_deonly); - - SCLogInfo("building signature grouping structure, stage 1: " - "preprocessing rules... complete"); - } - return 0; - -error: - return -1; -} - -static int DetectEngineLookupBuildSourceAddressList(DetectEngineCtx *de_ctx, DetectEngineLookupFlow *flow_gh, Signature *s, int family) -{ - DetectAddress *gr = NULL, *lookup_gr = NULL, *head = NULL; - int proto; - - if (family == AF_INET) { - head = s->src.ipv4_head; - } else if (family == AF_INET6) { - head = s->src.ipv6_head; - } else { - head = s->src.any_head; - } - - /* for each source address group in the signature... */ - for (gr = head; gr != NULL; gr = gr->next) { - BUG_ON(gr->ip.family == 0 && !(gr->flags & ADDRESS_FLAG_ANY)); - - /* ...and each protocol the signature matches on... */ - for (proto = 0; proto < 256; proto++) { - if ((s->proto.proto[(proto/8)] & (1<<(proto%8))) || (s->proto.flags & DETECT_PROTO_ANY)) { - /* ...see if the group is in the tmp list, and if not add it. */ - if (family == AF_INET) { - lookup_gr = DetectAddressLookupInList(flow_gh->tmp_gh[proto]->ipv4_head,gr); - } else if (family == AF_INET6) { - lookup_gr = DetectAddressLookupInList(flow_gh->tmp_gh[proto]->ipv6_head,gr); - } else { - lookup_gr = DetectAddressLookupInList(flow_gh->tmp_gh[proto]->any_head,gr); - } - - if (lookup_gr == NULL) { - DetectAddress *grtmp = DetectAddressCopy(gr); - if (grtmp == NULL) { - goto error; - } - SigGroupHeadAppendSig(de_ctx, &grtmp->sh, s); - - /* add to the lookup list */ - if (family == AF_INET) { - DetectAddressAdd(&flow_gh->tmp_gh[proto]->ipv4_head, grtmp); - } else if (family == AF_INET6) { - DetectAddressAdd(&flow_gh->tmp_gh[proto]->ipv6_head, grtmp); - } else { - DetectAddressAdd(&flow_gh->tmp_gh[proto]->any_head, grtmp); - } - } else { - /* our group will only have one sig, this one. So add that. */ - SigGroupHeadAppendSig(de_ctx, &lookup_gr->sh, s); - lookup_gr->cnt++; - } - } - } - } - - return 0; -error: - return -1; -} - -/** - * \brief add signature to the right flow group(s) - */ -static int DetectEngineLookupFlowAddSig(DetectEngineCtx *de_ctx, Signature *s, int family) -{ - SCLogDebug("s->id %u", s->id); - - if (s->flags & SIG_FLAG_TOCLIENT) { - SCLogDebug("s->id %u (toclient)", s->id); - DetectEngineLookupBuildSourceAddressList(de_ctx, - &de_ctx->flow_gh[0], s, family); - } - - if (s->flags & SIG_FLAG_TOSERVER) { - SCLogDebug("s->id %u (toserver)", s->id); - DetectEngineLookupBuildSourceAddressList(de_ctx, - &de_ctx->flow_gh[1], s, family); - } - - return 0; -} - -static DetectAddress *GetHeadPtr(DetectAddressHead *head, int family) -{ - DetectAddress *grhead; - - if (head == NULL) - return NULL; - - if (family == AF_INET) { - grhead = head->ipv4_head; - } else if (family == AF_INET6) { - grhead = head->ipv6_head; - } else { - grhead = head->any_head; - } - - return grhead; -} - -//#define SMALL_MPM(c) 0 -#define SMALL_MPM(c) ((c) == 1) -// || (c) == 2) -// || (c) == 3) - -int CreateGroupedAddrListCmpCnt(DetectAddress *a, DetectAddress *b) -{ - if (a->cnt > b->cnt) - return 1; - return 0; -} - -int CreateGroupedAddrListCmpMpmMinlen(DetectAddress *a, DetectAddress *b) -{ - if (a->sh == NULL || b->sh == NULL) - return 0; - - if (SMALL_MPM(a->sh->mpm_content_minlen)) - return 1; - - if (a->sh->mpm_content_minlen < b->sh->mpm_content_minlen) - return 1; - return 0; -} - -/* set unique_groups to 0 for no grouping. - * - * srchead is a ordered "inserted" list w/o internal overlap - * - */ -int CreateGroupedAddrList(DetectEngineCtx *de_ctx, DetectAddress *srchead, - int family, DetectAddressHead *newhead, - uint32_t unique_groups, - int (*CompareFunc)(DetectAddress *, DetectAddress *), - uint32_t max_idx) -{ - DetectAddress *tmplist = NULL, *tmplist2 = NULL, *joingr = NULL; - char insert = 0; - DetectAddress *gr, *next_gr; - uint32_t groups = 0; - - /* insert the addresses into the tmplist, where it will - * be sorted descending on 'cnt'. */ - for (gr = srchead; gr != NULL; gr = gr->next) { - BUG_ON(gr->ip.family == 0 && !(gr->flags & ADDRESS_FLAG_ANY)); - - if (SMALL_MPM(gr->sh->mpm_content_minlen) && unique_groups > 0) - unique_groups++; - - groups++; - - /* alloc a copy */ - DetectAddress *newtmp = DetectAddressCopy(gr); - if (newtmp == NULL) { - goto error; - } - SigGroupHeadCopySigs(de_ctx, gr->sh,&newtmp->sh); - - DetectPort *port = gr->port; - for ( ; port != NULL; port = port->next) { - DetectPortInsertCopy(de_ctx,&newtmp->port, port); - newtmp->flags |= ADDRESS_HAVEPORT; - } - - /* insert it */ - DetectAddress *tmpgr = tmplist, *prevtmpgr = NULL; - if (tmplist == NULL) { - /* empty list, set head */ - tmplist = newtmp; - } else { - /* look for the place to insert */ - for ( ; tmpgr != NULL&&!insert; tmpgr = tmpgr->next) { - if (CompareFunc(gr, tmpgr)) { - if (tmpgr == tmplist) { - newtmp->next = tmplist; - tmplist = newtmp; - } else { - newtmp->next = prevtmpgr->next; - prevtmpgr->next = newtmp; - } - insert = 1; - } - prevtmpgr = tmpgr; - } - if (insert == 0) { - newtmp->next = NULL; - prevtmpgr->next = newtmp; - } - insert = 0; - } - } - - uint32_t i = unique_groups; - if (i == 0) i = groups; - - for (gr = tmplist; gr != NULL; ) { - BUG_ON(gr->ip.family == 0 && !(gr->flags & ADDRESS_FLAG_ANY)); - - if (i == 0) { - if (joingr == NULL) { - joingr = DetectAddressCopy(gr); - if (joingr == NULL) { - goto error; - } - - SigGroupHeadCopySigs(de_ctx,gr->sh,&joingr->sh); - - DetectPort *port = gr->port; - for ( ; port != NULL; port = port->next) { - DetectPortInsertCopy(de_ctx,&joingr->port, port); - joingr->flags |= ADDRESS_HAVEPORT; - } - } else { - DetectAddressJoin(de_ctx, joingr, gr); - } - } else { - DetectAddress *newtmp = DetectAddressCopy(gr); - if (newtmp == NULL) { - goto error; - } - - SigGroupHeadCopySigs(de_ctx,gr->sh,&newtmp->sh); - - DetectPort *port = gr->port; - for ( ; port != NULL; port = port->next) { - DetectPortInsertCopy(de_ctx,&newtmp->port, port); - newtmp->flags |= ADDRESS_HAVEPORT; - } - - if (tmplist2 == NULL) { - tmplist2 = newtmp; - } else { - newtmp->next = tmplist2; - tmplist2 = newtmp; - } - } - if (i)i--; - - next_gr = gr->next; - DetectAddressFree(gr); - gr = next_gr; - } - - /* we now have a tmplist2 containing the 'unique' groups and - * possibly a joingr that covers the rest. Now build the newhead - * that we will pass back to the caller. - * - * Start with inserting the unique groups */ - for (gr = tmplist2; gr != NULL; ) { - BUG_ON(gr->ip.family == 0 && !(gr->flags & ADDRESS_FLAG_ANY)); - - DetectAddress *newtmp = DetectAddressCopy(gr); - if (newtmp == NULL) { - goto error; - } - SigGroupHeadCopySigs(de_ctx, gr->sh,&newtmp->sh); - - DetectPort *port = gr->port; - for ( ; port != NULL; port = port->next) { - DetectPortInsertCopy(de_ctx, &newtmp->port, port); - newtmp->flags |= ADDRESS_HAVEPORT; - } - - DetectAddressInsert(de_ctx, newhead, newtmp); - - next_gr = gr->next; - DetectAddressFree(gr); - gr = next_gr; - } - - /* if present, insert the joingr that covers the rest */ - if (joingr != NULL) { - DetectAddressInsert(de_ctx, newhead, joingr); - } - - return 0; -error: - return -1; -} - -int CreateGroupedPortListCmpCnt(DetectPort *a, DetectPort *b) -{ - if (a->cnt > b->cnt) - return 1; - return 0; -} - -int CreateGroupedPortListCmpMpmMinlen(DetectPort *a, DetectPort *b) -{ - if (a->sh == NULL || b->sh == NULL) - return 0; - - if (SMALL_MPM(a->sh->mpm_content_minlen)) - return 1; - - if (a->sh->mpm_content_minlen < b->sh->mpm_content_minlen) - return 1; - - return 0; -} - -static uint32_t g_groupportlist_maxgroups = 0; -static uint32_t g_groupportlist_groupscnt = 0; -static uint32_t g_groupportlist_totgroups = 0; - -int CreateGroupedPortList(DetectEngineCtx *de_ctx,HashListTable *port_hash, DetectPort **newhead, uint32_t unique_groups, int (*CompareFunc)(DetectPort *, DetectPort *), uint32_t max_idx) -{ - DetectPort *tmplist = NULL, *tmplist2 = NULL, *joingr = NULL; - char insert = 0; - DetectPort *gr, *next_gr; - uint32_t groups = 0; - - HashListTableBucket *htb = HashListTableGetListHead(port_hash); - - /* insert the addresses into the tmplist, where it will - * be sorted descending on 'cnt'. */ - for ( ; htb != NULL; htb = HashListTableGetListNext(htb)) { - gr = (DetectPort *)HashListTableGetListData(htb); - - SCLogDebug("hash list gr %p", gr); - DetectPortPrint(gr); - - if (SMALL_MPM(gr->sh->mpm_content_minlen) && unique_groups > 0) - unique_groups++; - - groups++; - - /* alloc a copy */ - DetectPort *newtmp = DetectPortCopySingle(de_ctx, gr); - if (newtmp == NULL) { - goto error; - } - - /* insert it */ - DetectPort *tmpgr = tmplist, *prevtmpgr = NULL; - if (tmplist == NULL) { - /* empty list, set head */ - tmplist = newtmp; - } else { - /* look for the place to insert */ - for ( ; tmpgr != NULL&&!insert; tmpgr = tmpgr->next) { - if (CompareFunc(gr, tmpgr)) { - if (tmpgr == tmplist) { - newtmp->next = tmplist; - tmplist = newtmp; - } else { - newtmp->next = prevtmpgr->next; - prevtmpgr->next = newtmp; - } - insert = 1; - } - prevtmpgr = tmpgr; - } - if (insert == 0) { - newtmp->next = NULL; - prevtmpgr->next = newtmp; - } - insert = 0; - } - } - - uint32_t i = unique_groups; - if (i == 0) i = groups; - - if (unique_groups > g_groupportlist_maxgroups) - g_groupportlist_maxgroups = unique_groups; - g_groupportlist_groupscnt++; - g_groupportlist_totgroups += unique_groups; - - for (gr = tmplist; gr != NULL; ) { - SCLogDebug("temp list gr %p", gr); - DetectPortPrint(gr); - - if (i == 0) { - if (joingr == NULL) { - joingr = DetectPortCopySingle(de_ctx,gr); - if (joingr == NULL) { - goto error; - } - } else { - DetectPortJoin(de_ctx,joingr, gr); - } - } else { - DetectPort *newtmp = DetectPortCopySingle(de_ctx,gr); - if (newtmp == NULL) { - goto error; - } - - if (tmplist2 == NULL) { - tmplist2 = newtmp; - } else { - newtmp->next = tmplist2; - tmplist2 = newtmp; - } - } - if (i)i--; - - next_gr = gr->next; - gr->next = NULL; - DetectPortFree(gr); - gr = next_gr; - } - - /* we now have a tmplist2 containing the 'unique' groups and - * possibly a joingr that covers the rest. Now build the newhead - * that we will pass back to the caller. - * - * Start with inserting the unique groups */ - for (gr = tmplist2; gr != NULL; ) { - SCLogDebug("temp list2 gr %p", gr); - DetectPortPrint(gr); - - DetectPort *newtmp = DetectPortCopySingle(de_ctx,gr); - if (newtmp == NULL) { - goto error; - } - - int r = DetectPortInsert(de_ctx,newhead,newtmp); - BUG_ON(r == -1); - - next_gr = gr->next; - gr->next = NULL; - DetectPortFree(gr); - gr = next_gr; - } - - DetectPortPrintList(*newhead); - - /* if present, insert the joingr that covers the rest */ - if (joingr != NULL) { - SCLogDebug("inserting joingr %p", joingr); - DetectPortInsert(de_ctx,newhead,joingr); - } else { - SCLogDebug("no joingr"); - } - - return 0; -error: - return -1; -} - -/** - * \internal - * \brief add a decoder event signature to the detection engine ctx - */ -static void DetectEngineAddDecoderEventSig(DetectEngineCtx *de_ctx, Signature *s) -{ - SCLogDebug("adding signature %"PRIu32" to the decoder event sgh", s->id); - SigGroupHeadAppendSig(de_ctx, &de_ctx->decoder_event_sgh, s); -} - -/** - * \brief Fill the global src group head, with the sigs included - * - * \param de_ctx Pointer to the Detection Engine Context whose Signatures have - * to be processed - * - * \retval 0 On success - * \retval -1 On failure - */ -int SigAddressPrepareStage2(DetectEngineCtx *de_ctx) -{ - Signature *tmp_s = NULL; - uint32_t sigs = 0; - - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("building signature grouping structure, stage 2: " - "building source address lists..."); - } - - IPOnlyInit(de_ctx, &de_ctx->io_ctx); - - int f, proto; - for (f = 0; f < FLOW_STATES; f++) { - for (proto = 0; proto < 256; proto++) { - de_ctx->flow_gh[f].src_gh[proto] = DetectAddressHeadInit(); - if (de_ctx->flow_gh[f].src_gh[proto] == NULL) { - goto error; - } - de_ctx->flow_gh[f].tmp_gh[proto] = DetectAddressHeadInit(); - if (de_ctx->flow_gh[f].tmp_gh[proto] == NULL) { - goto error; - } - } - } - - /* now for every rule add the source group to our temp lists */ - for (tmp_s = de_ctx->sig_list; tmp_s != NULL; tmp_s = tmp_s->next) { - SCLogDebug("tmp_s->id %"PRIu32, tmp_s->id); - if (tmp_s->flags & SIG_FLAG_IPONLY) { - IPOnlyAddSignature(de_ctx, &de_ctx->io_ctx, tmp_s); - } else { - DetectEngineLookupFlowAddSig(de_ctx, tmp_s, AF_INET); - DetectEngineLookupFlowAddSig(de_ctx, tmp_s, AF_INET6); - DetectEngineLookupFlowAddSig(de_ctx, tmp_s, AF_UNSPEC); - } - - if (tmp_s->init_flags & SIG_FLAG_INIT_DEONLY) { - DetectEngineAddDecoderEventSig(de_ctx, tmp_s); - } - - sigs++; - } - - /* create the final src addr list based on the tmplist. */ - for (f = 0; f < FLOW_STATES; f++) { - for (proto = 0; proto < 256; proto++) { - int groups = (f ? de_ctx->max_uniq_toserver_src_groups : de_ctx->max_uniq_toclient_src_groups); - - CreateGroupedAddrList(de_ctx, - de_ctx->flow_gh[f].tmp_gh[proto]->ipv4_head, AF_INET, - de_ctx->flow_gh[f].src_gh[proto], groups, - CreateGroupedAddrListCmpMpmMinlen, DetectEngineGetMaxSigId(de_ctx)); - - CreateGroupedAddrList(de_ctx, - de_ctx->flow_gh[f].tmp_gh[proto]->ipv6_head, AF_INET6, - de_ctx->flow_gh[f].src_gh[proto], groups, - CreateGroupedAddrListCmpMpmMinlen, DetectEngineGetMaxSigId(de_ctx)); - CreateGroupedAddrList(de_ctx, - de_ctx->flow_gh[f].tmp_gh[proto]->any_head, AF_UNSPEC, - de_ctx->flow_gh[f].src_gh[proto], groups, - CreateGroupedAddrListCmpMpmMinlen, DetectEngineGetMaxSigId(de_ctx)); - - DetectAddressHeadFree(de_ctx->flow_gh[f].tmp_gh[proto]); - de_ctx->flow_gh[f].tmp_gh[proto] = NULL; - } - } - //DetectAddressPrintMemory(); - //DetectSigGroupPrintMemory(); - - //printf("g_src_gh strt\n"); - //DetectAddressPrintList(g_src_gh->ipv4_head); - //printf("g_src_gh end\n"); - - IPOnlyPrepare(de_ctx); - IPOnlyPrint(de_ctx, &de_ctx->io_ctx); -#ifdef DEBUG - DetectAddress *gr = NULL; - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("%" PRIu32 " total signatures:", sigs); - } - - /* TCP */ - uint32_t cnt_any = 0, cnt_ipv4 = 0, cnt_ipv6 = 0; - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[IPPROTO_TCP]->any_head; gr != NULL; gr = gr->next) { - cnt_any++; - } - } - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[IPPROTO_TCP]->ipv4_head; gr != NULL; gr = gr->next) { - cnt_ipv4++; - } - } - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[IPPROTO_TCP]->ipv6_head; gr != NULL; gr = gr->next) { - cnt_ipv6++; - } - } - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("TCP Source address blocks: any: %4u, ipv4: %4u, ipv6: %4u.", cnt_any, cnt_ipv4, cnt_ipv6); - } - - cnt_any = 0, cnt_ipv4 = 0, cnt_ipv6 = 0; - /* UDP */ - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[IPPROTO_UDP]->any_head; gr != NULL; gr = gr->next) { - cnt_any++; - } - } - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[IPPROTO_UDP]->ipv4_head; gr != NULL; gr = gr->next) { - cnt_ipv4++; - } - } - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[IPPROTO_UDP]->ipv6_head; gr != NULL; gr = gr->next) { - cnt_ipv6++; - } - } - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("UDP Source address blocks: any: %4u, ipv4: %4u, ipv6: %4u.", cnt_any, cnt_ipv4, cnt_ipv6); - } - - cnt_any = 0, cnt_ipv4 = 0, cnt_ipv6 = 0; - /* SCTP */ - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[IPPROTO_SCTP]->any_head; gr != NULL; gr = gr->next) { - cnt_any++; - } - } - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[IPPROTO_SCTP]->ipv4_head; gr != NULL; gr = gr->next) { - cnt_ipv4++; - } - } - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[IPPROTO_SCTP]->ipv6_head; gr != NULL; gr = gr->next) { - cnt_ipv6++; - } - } - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("SCTP Source address blocks: any: %4u, ipv4: %4u, ipv6: %4u.", cnt_any, cnt_ipv4, cnt_ipv6); - } - - /* ICMP */ - cnt_any = 0, cnt_ipv4 = 0, cnt_ipv6 = 0; - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[1]->any_head; gr != NULL; gr = gr->next) { - cnt_any++; - } - } - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[1]->ipv4_head; gr != NULL; gr = gr->next) { - cnt_ipv4++; - } - } - for (f = 0; f < FLOW_STATES; f++) { - for (gr = de_ctx->flow_gh[f].src_gh[1]->ipv6_head; gr != NULL; gr = gr->next) { - cnt_ipv6++; - } - } - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("ICMP Source address blocks: any: %4u, ipv4: %4u, ipv6: %4u.", cnt_any, cnt_ipv4, cnt_ipv6); - } -#endif /* DEBUG */ - if (!(de_ctx->flags & DE_QUIET)) { - SCLogInfo("building signature grouping structure, stage 2: building source address list... complete"); - } - - return 0; -error: - printf("SigAddressPrepareStage2 error\n"); - return -1; -} - -/** - * \brief Build the destination address portion of the match tree - */ -int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressHead *head, int family, int flow) -{ - Signature *tmp_s = NULL; - DetectAddress *gr = NULL, *sgr = NULL, *lookup_gr = NULL; - uint32_t max_idx = 0; - - DetectAddress *grhead = NULL, *grdsthead = NULL, *grsighead = NULL; - - /* based on the family, select the list we are using in the head */ - grhead = GetHeadPtr(head, family); - - /* loop through the global source address list */ - for (gr = grhead; gr != NULL; gr = gr->next) { - //printf(" * Source group (BuildDestinationAddressHeads): "); DetectAddressPrint(gr); printf(" (%p)\n", gr); - - /* initialize the destination group head */ - gr->dst_gh = DetectAddressHeadInit(); - if (gr->dst_gh == NULL) { - goto error; - } - - /* use a tmp list for speeding up insertions */ - DetectAddress *tmp_gr_list = NULL; - - /* loop through all signatures in this source address group - * and build the temporary destination address list for it */ - uint32_t sig; - for (sig = 0; sig < de_ctx->sig_array_len; sig++) { - if (!(gr->sh->init->sig_array[(sig/8)] & (1<<(sig%8)))) - continue; - - tmp_s = de_ctx->sig_array[sig]; - if (tmp_s == NULL) - continue; - - //printf(" * (tmp) Signature %u (num %u)\n", tmp_s->id, tmp_s->num); - - max_idx = sig; - - /* build the temp list */ - grsighead = GetHeadPtr(&tmp_s->dst, family); - for (sgr = grsighead; sgr != NULL; sgr = sgr->next) { - //printf(" * (tmp) dst group: "); DetectAddressPrint(sgr); printf(" (%p)\n", sgr); - - if ((lookup_gr = DetectAddressLookupInList(tmp_gr_list, sgr)) == NULL) { - DetectAddress *grtmp = DetectAddressCopy(sgr); - if (grtmp == NULL) { - goto error; - } - SigGroupHeadAppendSig(de_ctx,&grtmp->sh,tmp_s); - - DetectAddressAdd(&tmp_gr_list,grtmp); - } else { - /* our group will only have one sig, this one. So add that. */ - SigGroupHeadAppendSig(de_ctx, &lookup_gr->sh, tmp_s); - lookup_gr->cnt++; - } - } - - } - - /* Create the destination address list, keeping in - * mind the limits we use. */ - int groups = (flow ? de_ctx->max_uniq_toserver_dst_groups : de_ctx->max_uniq_toclient_dst_groups); - - CreateGroupedAddrList(de_ctx, tmp_gr_list, family, gr->dst_gh, groups, - CreateGroupedAddrListCmpMpmMinlen, max_idx); - - /* see if the sig group head of each address group is the - * same as an earlier one. If it is, free our head and use - * a pointer to the earlier one. This saves _a lot_ of memory. - */ - grdsthead = GetHeadPtr(gr->dst_gh, family); - for (sgr = grdsthead; sgr != NULL; sgr = sgr->next) { - //printf(" * Destination group: "); DetectAddressPrint(sgr); printf("\n"); - - /* Because a pattern matcher context uses quite some - * memory, we first check if we can reuse it from - * another group head. */ - SigGroupHead *sgh = SigGroupHeadHashLookup(de_ctx, sgr->sh); - if (sgh == NULL) { - /* put the contents in our sig group head */ - SigGroupHeadSetSigCnt(sgr->sh, max_idx); - SigGroupHeadBuildMatchArray(de_ctx, sgr->sh, max_idx); - - /* init the pattern matcher, this will respect the copy - * setting */ - if (PatternMatchPrepareGroup(de_ctx, sgr->sh) < 0) { - printf("PatternMatchPrepareGroup failed\n"); - goto error; - } - SigGroupHeadHashAdd(de_ctx, sgr->sh); - SigGroupHeadStore(de_ctx, sgr->sh); - de_ctx->gh_unique++; - } else { - SCLogDebug("calling SigGroupHeadFree sgr %p, sgr->sh %p", sgr, sgr->sh); - SigGroupHeadFree(sgr->sh); - sgr->sh = sgh; - - de_ctx->gh_reuse++; - sgr->flags |= ADDRESS_SIGGROUPHEAD_COPY; - sgr->sh->flags |= SIG_GROUP_HEAD_REFERENCED; - } - } - - /* free the temp list */ - DetectAddressCleanupList(tmp_gr_list); - /* clear now unneeded sig group head */ - SCLogDebug("calling SigGroupHeadFree gr %p, gr->sh %p", gr, gr->sh); - SigGroupHeadFree(gr->sh); - gr->sh = NULL; - } - - return 0; -error: - return -1; -} - -//static -int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, DetectAddressHead *head, int family, int flow) -{ - Signature *tmp_s = NULL; - DetectAddress *src_gr = NULL, *dst_gr = NULL, *sig_gr = NULL, *lookup_gr = NULL; - DetectAddress *src_gr_head = NULL, *dst_gr_head = NULL, *sig_gr_head = NULL; - uint32_t max_idx = 0; - - /* loop through the global source address list */ - src_gr_head = GetHeadPtr(head,family); - for (src_gr = src_gr_head; src_gr != NULL; src_gr = src_gr->next) { - //printf(" * Source group: "); DetectAddressPrint(src_gr); printf("\n"); - - /* initialize the destination group head */ - src_gr->dst_gh = DetectAddressHeadInit(); - if (src_gr->dst_gh == NULL) { - goto error; - } - - /* use a tmp list for speeding up insertions */ - DetectAddress *tmp_gr_list = NULL; - - /* loop through all signatures in this source address group - * and build the temporary destination address list for it */ - uint32_t sig; - for (sig = 0; sig < de_ctx->sig_array_len; sig++) { - if (!(src_gr->sh->init->sig_array[(sig/8)] & (1<<(sig%8)))) - continue; - - tmp_s = de_ctx->sig_array[sig]; - if (tmp_s == NULL) - continue; - - //printf(" * Source group: "); DetectAddressPrint(src_gr); printf("\n"); - - max_idx = sig; - - /* build the temp list */ - sig_gr_head = GetHeadPtr(&tmp_s->dst,family); - for (sig_gr = sig_gr_head; sig_gr != NULL; sig_gr = sig_gr->next) { - //printf(" * Sig dst addr: "); DetectAddressPrint(sig_gr); printf("\n"); - - if ((lookup_gr = DetectAddressLookupInList(tmp_gr_list, sig_gr)) == NULL) { - DetectAddress *grtmp = DetectAddressCopy(sig_gr); - if (grtmp == NULL) { - goto error; - } - SigGroupHeadAppendSig(de_ctx, &grtmp->sh, tmp_s); - - DetectAddressAdd(&tmp_gr_list,grtmp); - } else { - /* our group will only have one sig, this one. So add that. */ - SigGroupHeadAppendSig(de_ctx, &lookup_gr->sh, tmp_s); - lookup_gr->cnt++; - } - - SCLogDebug("calling SigGroupHeadFree sig_gr %p, sig_gr->sh %p", sig_gr, sig_gr->sh); - SigGroupHeadFree(sig_gr->sh); - sig_gr->sh = NULL; - } - } - - /* Create the destination address list, keeping in - * mind the limits we use. */ - int groups = (flow ? de_ctx->max_uniq_toserver_dst_groups : de_ctx->max_uniq_toclient_dst_groups); - - CreateGroupedAddrList(de_ctx, tmp_gr_list, family, src_gr->dst_gh, groups, - CreateGroupedAddrListCmpMpmMinlen, max_idx); - - /* add the ports to the dst address groups and the sigs - * to the ports */ - dst_gr_head = GetHeadPtr(src_gr->dst_gh,family); - for (dst_gr = dst_gr_head; dst_gr != NULL; dst_gr = dst_gr->next) { - //printf(" * Destination group: "); DetectAddressPrint(dst_gr); printf("\n"); - - dst_gr->flags |= ADDRESS_HAVEPORT; - - if (dst_gr->sh == NULL) - continue; - - /* we will reuse address sig group heads at this points, - * because if the sigs are the same, the ports will be - * the same. Saves memory and a lot of init time. */ - SigGroupHead *lookup_sgh = SigGroupHeadHashLookup(de_ctx, dst_gr->sh); - if (lookup_sgh == NULL) { - DetectPortSpHashReset(de_ctx); - - uint32_t sig2; - for (sig2 = 0; sig2 < max_idx+1; sig2++) { - if (!(dst_gr->sh->init->sig_array[(sig2/8)] & (1<<(sig2%8)))) - continue; - - Signature *s = de_ctx->sig_array[sig2]; - if (s == NULL) - continue; - - //printf(" + Destination group (grouped): "); DetectAddressPrint(dst_gr); printf("\n"); - - DetectPort *sdp = s->sp; - for ( ; sdp != NULL; sdp = sdp->next) { - DetectPort *lookup_port = DetectPortSpHashLookup(de_ctx, sdp); - if (lookup_port == NULL) { - DetectPort *port = DetectPortCopySingle(de_ctx,sdp); - if (port == NULL) - goto error; - - SigGroupHeadAppendSig(de_ctx, &port->sh, s); - DetectPortSpHashAdd(de_ctx, port); - port->cnt = 1; - } else { - SigGroupHeadAppendSig(de_ctx, &lookup_port->sh, s); - lookup_port->cnt++; - } - } - } - - int spgroups = (flow ? de_ctx->max_uniq_toserver_sp_groups : de_ctx->max_uniq_toclient_sp_groups); - - CreateGroupedPortList(de_ctx, de_ctx->sport_hash_table, &dst_gr->port, spgroups, - CreateGroupedPortListCmpMpmMinlen, max_idx); - - SCLogDebug("adding sgh %p to the hash", dst_gr->sh); - SigGroupHeadHashAdd(de_ctx, dst_gr->sh); - - dst_gr->sh->init->port = dst_gr->port; - /* mark this head for deletion once we no longer need - * the hash. We're only using the port ptr, so no problem - * when we remove this after initialization is done */ - dst_gr->sh->flags |= SIG_GROUP_HEAD_FREE; - - /* for each destination port we setup the siggrouphead here */ - DetectPort *sp = dst_gr->port; - for ( ; sp != NULL; sp = sp->next) { - //printf(" * Src Port(range): "); DetectPortPrint(sp); printf("\n"); - - if (sp->sh == NULL) - continue; - - /* we will reuse address sig group heads at this points, - * because if the sigs are the same, the ports will be - * the same. Saves memory and a lot of init time. */ - SigGroupHead *lookup_sp_sgh = SigGroupHeadSPortHashLookup(de_ctx, sp->sh); - if (lookup_sp_sgh == NULL) { - DetectPortDpHashReset(de_ctx); - uint32_t sig2; - for (sig2 = 0; sig2 < max_idx+1; sig2++) { - if (!(sp->sh->init->sig_array[(sig2/8)] & (1<<(sig2%8)))) - continue; - - Signature *s = de_ctx->sig_array[sig2]; - if (s == NULL) - continue; - - DetectPort *sdp = s->dp; - for ( ; sdp != NULL; sdp = sdp->next) { - DetectPort *lookup_port = DetectPortDpHashLookup(de_ctx,sdp); - if (lookup_port == NULL) { - DetectPort *port = DetectPortCopySingle(de_ctx,sdp); - if (port == NULL) - goto error; - - SigGroupHeadAppendSig(de_ctx, &port->sh, s); - DetectPortDpHashAdd(de_ctx,port); - port->cnt = 1; - } else { - SigGroupHeadAppendSig(de_ctx, &lookup_port->sh, s); - lookup_port->cnt++; - } - } - } - - int dpgroups = (flow ? de_ctx->max_uniq_toserver_dp_groups : de_ctx->max_uniq_toclient_dp_groups); - - CreateGroupedPortList(de_ctx, de_ctx->dport_hash_table, - &sp->dst_ph, dpgroups, - CreateGroupedPortListCmpMpmMinlen, max_idx); - - SigGroupHeadSPortHashAdd(de_ctx, sp->sh); - - sp->sh->init->port = sp->dst_ph; - /* mark this head for deletion once we no longer need - * the hash. We're only using the port ptr, so no problem - * when we remove this after initialization is done */ - sp->sh->flags |= SIG_GROUP_HEAD_FREE; - - /* for each destination port we setup the siggrouphead here */ - DetectPort *dp = sp->dst_ph; - for ( ; dp != NULL; dp = dp->next) { - if (dp->sh == NULL) - continue; - - /* Because a pattern matcher context uses quite some - * memory, we first check if we can reuse it from - * another group head. */ - SigGroupHead *lookup_dp_sgh = SigGroupHeadDPortHashLookup(de_ctx, dp->sh); - if (lookup_dp_sgh == NULL) { - SCLogDebug("dp %p dp->sh %p is the original (sp %p, dst_gr %p, src_gr %p)", dp, dp->sh, sp, dst_gr, src_gr); - - SigGroupHeadSetSigCnt(dp->sh, max_idx); - SigGroupHeadBuildMatchArray(de_ctx,dp->sh, max_idx); - - /* init the pattern matcher, this will respect the copy - * setting */ - if (PatternMatchPrepareGroup(de_ctx, dp->sh) < 0) { - printf("PatternMatchPrepareGroup failed\n"); - goto error; - } - SigGroupHeadDPortHashAdd(de_ctx, dp->sh); - SigGroupHeadStore(de_ctx, dp->sh); - de_ctx->gh_unique++; - } else { - SCLogDebug("dp %p dp->sh %p is a copy", dp, dp->sh); - - SigGroupHeadFree(dp->sh); - dp->sh = lookup_dp_sgh; - dp->flags |= PORT_SIGGROUPHEAD_COPY; - dp->sh->flags |= SIG_GROUP_HEAD_REFERENCED; - - de_ctx->gh_reuse++; - } - } - /* sig group head found in hash, free it and use the hashed one */ - } else { - SigGroupHeadFree(sp->sh); - sp->sh = lookup_sp_sgh; - sp->flags |= PORT_SIGGROUPHEAD_COPY; - sp->sh->flags |= SIG_GROUP_HEAD_REFERENCED; - - SCLogDebug("replacing sp->dst_ph %p with lookup_sp_sgh->init->port %p", sp->dst_ph, lookup_sp_sgh->init->port); - DetectPortCleanupList(sp->dst_ph); - sp->dst_ph = lookup_sp_sgh->init->port; - sp->flags |= PORT_GROUP_PORTS_COPY; - - de_ctx->gh_reuse++; - } - } - } else { - SigGroupHeadFree(dst_gr->sh); - dst_gr->sh = lookup_sgh; - dst_gr->flags |= ADDRESS_SIGGROUPHEAD_COPY; - dst_gr->sh->flags |= SIG_GROUP_HEAD_REFERENCED; - - SCLogDebug("replacing dst_gr->port %p with lookup_sgh->init->port %p", dst_gr->port, lookup_sgh->init->port); - DetectPortCleanupList(dst_gr->port); - dst_gr->port = lookup_sgh->init->port; - dst_gr->flags |= ADDRESS_PORTS_COPY; - - de_ctx->gh_reuse++; - } - } - /* free the temp list */ - DetectAddressCleanupList(tmp_gr_list); - /* clear now unneeded sig group head */ - SigGroupHeadFree(src_gr->sh); - src_gr->sh = NULL; - - /* free dst addr sgh's */ - dst_gr_head = GetHeadPtr(src_gr->dst_gh,family); - for (dst_gr = dst_gr_head; dst_gr != NULL; dst_gr = dst_gr->next) { - if (!(dst_gr->flags & ADDRESS_SIGGROUPHEAD_COPY)) { - if (!(dst_gr->sh->flags & SIG_GROUP_HEAD_REFERENCED)) { - SCLogDebug("removing sgh %p from hash", dst_gr->sh); - - int r = SigGroupHeadHashRemove(de_ctx,dst_gr->sh); - BUG_ON(r == -1); - if (r == 0) { - SCLogDebug("removed sgh %p from hash", dst_gr->sh); - SigGroupHeadFree(dst_gr->sh); - dst_gr->sh = NULL; - } - } - } - } - } - - return 0; -error: - return -1; -} - -static void DetectEngineBuildDecoderEventSgh(DetectEngineCtx *de_ctx) -{ - if (de_ctx->decoder_event_sgh == NULL) - return; - - uint32_t max_idx = DetectEngineGetMaxSigId(de_ctx); - SigGroupHeadSetSigCnt(de_ctx->decoder_event_sgh, max_idx); - SigGroupHeadBuildMatchArray(de_ctx, de_ctx->decoder_event_sgh, max_idx); -} - -int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) -{ - int r; - - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("building signature grouping structure, stage 3: " - "building destination address lists..."); - } - //DetectAddressPrintMemory(); - //DetectSigGroupPrintMemory(); - //DetectPortPrintMemory(); - - int f = 0; - int proto; - for (f = 0; f < FLOW_STATES; f++) { - r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->flow_gh[f].src_gh[IPPROTO_TCP],AF_INET,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[6],AF_INET) failed\n"); - goto error; - } - r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->flow_gh[f].src_gh[IPPROTO_UDP],AF_INET,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[17],AF_INET) failed\n"); - goto error; - } - r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->flow_gh[f].src_gh[IPPROTO_SCTP],AF_INET,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[IPPROTO_SCTP],AF_INET) failed\n"); - goto error; - } - r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->flow_gh[f].src_gh[IPPROTO_TCP],AF_INET6,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[6],AF_INET) failed\n"); - goto error; - } - r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->flow_gh[f].src_gh[IPPROTO_UDP],AF_INET6,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[17],AF_INET) failed\n"); - goto error; - } - r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->flow_gh[f].src_gh[IPPROTO_SCTP],AF_INET6,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[IPPROTO_SCTP],AF_INET) failed\n"); - goto error; - } - r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->flow_gh[f].src_gh[IPPROTO_TCP],AF_UNSPEC,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[6],AF_INET) failed\n"); - goto error; - } - r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->flow_gh[f].src_gh[IPPROTO_UDP],AF_UNSPEC,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[17],AF_INET) failed\n"); - goto error; - } - r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->flow_gh[f].src_gh[IPPROTO_SCTP],AF_UNSPEC,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[IPPROTO_SCTP],AF_INET) failed\n"); - goto error; - } - for (proto = 0; proto < 256; proto++) { - if (proto == IPPROTO_TCP || proto == IPPROTO_UDP || proto == IPPROTO_SCTP) - continue; - - r = BuildDestinationAddressHeads(de_ctx, de_ctx->flow_gh[f].src_gh[proto],AF_INET,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[%" PRId32 "],AF_INET) failed\n", proto); - goto error; - } - r = BuildDestinationAddressHeads(de_ctx, de_ctx->flow_gh[f].src_gh[proto],AF_INET6,f); - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[%" PRId32 "],AF_INET6) failed\n", proto); - goto error; - } - r = BuildDestinationAddressHeads(de_ctx, de_ctx->flow_gh[f].src_gh[proto],AF_UNSPEC,f); /* for any */ - if (r < 0) { - printf ("BuildDestinationAddressHeads(src_gh[%" PRId32 "],AF_UNSPEC) failed\n", proto); - goto error; - } - } - } - - /* prepare the decoder event sgh */ - DetectEngineBuildDecoderEventSgh(de_ctx); - - /* cleanup group head (uri)content_array's */ - SigGroupHeadFreeMpmArrays(de_ctx); - /* cleanup group head sig arrays */ - SigGroupHeadFreeSigArrays(de_ctx); - - /* cleanup the hashes now since we won't need them - * after the initialization phase. */ - SigGroupHeadHashFree(de_ctx); - SigGroupHeadDPortHashFree(de_ctx); - SigGroupHeadSPortHashFree(de_ctx); - SigGroupHeadMpmHashFree(de_ctx); - SigGroupHeadMpmUriHashFree(de_ctx); - DetectPortDpHashFree(de_ctx); - DetectPortSpHashFree(de_ctx); - - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("max sig id %" PRIu32 ", array size %" PRIu32 "", DetectEngineGetMaxSigId(de_ctx), DetectEngineGetMaxSigId(de_ctx) / 8 + 1); - SCLogDebug("signature group heads: unique %" PRIu32 ", copies %" PRIu32 ".", de_ctx->gh_unique, de_ctx->gh_reuse); - SCLogDebug("port maxgroups: %" PRIu32 ", avg %" PRIu32 ", tot %" PRIu32 "", g_groupportlist_maxgroups, g_groupportlist_groupscnt ? g_groupportlist_totgroups/g_groupportlist_groupscnt : 0, g_groupportlist_totgroups); - - SCLogInfo("building signature grouping structure, stage 3: building destination address lists... complete"); - } - return 0; -error: - printf("SigAddressPrepareStage3 error\n"); - return -1; -} - -int SigAddressCleanupStage1(DetectEngineCtx *de_ctx) -{ - BUG_ON(de_ctx == NULL); - - if (!(de_ctx->flags & DE_QUIET)) { - SCLogDebug("cleaning up signature grouping structure..."); - } - - int f, proto; - for (f = 0; f < FLOW_STATES; f++) { - for (proto = 0; proto < 256; proto++) { - /* XXX fix this */ - DetectAddressHeadFree(de_ctx->flow_gh[f].src_gh[proto]); - de_ctx->flow_gh[f].src_gh[proto] = NULL; - } - } - - if (de_ctx->decoder_event_sgh) - SigGroupHeadFree(de_ctx->decoder_event_sgh); - de_ctx->decoder_event_sgh = NULL; - - IPOnlyDeinit(de_ctx, &de_ctx->io_ctx); - - if (!(de_ctx->flags & DE_QUIET)) { - SCLogInfo("cleaning up signature grouping structure... complete"); - } - return 0; -} - -void DbgPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - if (sgh == NULL) { - printf("\n"); - return; - } - - uint32_t sig; - for (sig = 0; sig < sgh->sig_cnt; sig++) { - printf("%" PRIu32 " ", sgh->match_array[sig]->id); - } - printf("\n"); -} - -void DbgPrintSigs2(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - if (sgh == NULL || sgh->init == NULL) { - printf("\n"); - return; - } - - uint32_t sig; - for (sig = 0; sig < DetectEngineGetMaxSigId(de_ctx); sig++) { - if (sgh->init->sig_array[(sig/8)] & (1<<(sig%8))) { - printf("%" PRIu32 " ", de_ctx->sig_array[sig]->id); - } - } - printf("\n"); -} - -void DbgSghContainsSig(DetectEngineCtx *de_ctx, SigGroupHead *sgh, uint32_t sid) -{ - if (sgh == NULL || sgh->init == NULL) { - printf("\n"); - return; - } - - uint32_t sig; - for (sig = 0; sig < DetectEngineGetMaxSigId(de_ctx); sig++) { - if (!(sgh->init->sig_array[(sig/8)] & (1<<(sig%8)))) - continue; - - Signature *s = de_ctx->sig_array[sig]; - if (s == NULL) - continue; - - if (sid == s->id) { - printf("%" PRIu32 " ", de_ctx->sig_array[sig]->id); - } - } - printf("\n"); -} - -/** \brief finalize preparing sgh's */ -int SigAddressPrepareStage4(DetectEngineCtx *de_ctx) -{ - SCEnter(); - - //SCLogInfo("sgh's %"PRIu32, de_ctx->sgh_array_cnt); - - uint32_t idx = 0; - - for (idx = 0; idx < de_ctx->sgh_array_cnt; idx++) { - SigGroupHead *sgh = de_ctx->sgh_array[idx]; - if (sgh == NULL) - continue; - SigGroupHeadSetFilemagicFlag(de_ctx, sgh); - SigGroupHeadSetFileMd5Flag(de_ctx, sgh); - SigGroupHeadSetFilesizeFlag(de_ctx, sgh); - SigGroupHeadSetFilestoreCount(de_ctx, sgh); - SCLogDebug("filestore count %u", sgh->filestore_cnt); - - SigGroupHeadBuildNonMpmArray(de_ctx, sgh); - - sgh->mpm_uricontent_minlen = SigGroupHeadGetMinMpmSize(de_ctx, sgh, DETECT_SM_LIST_UMATCH); - SCLogDebug("http_uri content min mpm len: %u", sgh->mpm_uricontent_minlen); - } - - if (de_ctx->decoder_event_sgh != NULL) { - /* no need to set filestore count here as that would make a - * signature not decode event only. */ - } - - SCFree(de_ctx->sgh_array); - de_ctx->sgh_array_cnt = 0; - de_ctx->sgh_array_size = 0; - - SCReturnInt(0); -} - -/* shortcut for debugging. If enabled Stage5 will - * print sigid's for all groups */ -#define PRINTSIGS - -/* just printing */ -int SigAddressPrepareStage5(DetectEngineCtx *de_ctx) -{ - DetectAddressHead *global_dst_gh = NULL; - DetectAddress *global_src_gr = NULL, *global_dst_gr = NULL; - uint32_t u; - - printf("* Building signature grouping structure, stage 5: print...\n"); - - int f, proto; - printf("\n"); - for (f = 0; f < FLOW_STATES; f++) { - printf("\n"); - for (proto = 0; proto < 256; proto++) { - if (proto != IPPROTO_TCP) - continue; - - for (global_src_gr = de_ctx->flow_gh[f].src_gh[proto]->ipv4_head; global_src_gr != NULL; - global_src_gr = global_src_gr->next) - { - printf("1 Src Addr: "); DetectAddressPrint(global_src_gr); - printf(" (sh %p)\n", global_src_gr->sh); - //printf("\n"); - -#ifdef PRINTSIGS - SigGroupHeadPrintSigs(de_ctx, global_src_gr->sh); - if (global_src_gr->sh != NULL) { - printf(" - "); - for (u = 0; u < global_src_gr->sh->sig_cnt; u++) { - Signature *s = global_src_gr->sh->match_array[u]; - printf("%" PRIu32 " ", s->id); - } - printf("\n"); - } -#endif - - global_dst_gh = global_src_gr->dst_gh; - if (global_dst_gh == NULL) - continue; - - for (global_dst_gr = global_dst_gh->ipv4_head; - global_dst_gr != NULL; - global_dst_gr = global_dst_gr->next) - { - printf(" 2 Dst Addr: "); DetectAddressPrint(global_dst_gr); - - //printf(" (sh %p) ", global_dst_gr->sh); - if (global_dst_gr->sh) { - if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) { - printf(" (COPY): "); - } else { - printf(" (ORIGINAL): "); - } - } else { - printf(" "); - } - -#ifdef PRINTSIGS - if (global_dst_gr->sh != NULL) { - printf(" - "); - for (u = 0; u < global_dst_gr->sh->sig_cnt; u++) { - Signature *s = global_dst_gr->sh->match_array[u]; - printf("%" PRIu32 " ", s->id); - } - printf("\n"); - } -#endif - - - DetectPort *sp = global_dst_gr->port; - for ( ; sp != NULL; sp = sp->next) { - printf(" 3 Src port(range): "); DetectPortPrint(sp); - //printf(" (sh %p)", sp->sh); - printf("\n"); - DetectPort *dp = sp->dst_ph; - for ( ; dp != NULL; dp = dp->next) { - printf(" 4 Dst port(range): "); DetectPortPrint(dp); - printf(" (sigs %" PRIu32 ", sgh %p, minlen %" PRIu32 ")", dp->sh->sig_cnt, dp->sh, dp->sh->mpm_content_minlen); -#ifdef PRINTSIGS - printf(" - "); - for (u = 0; u < dp->sh->sig_cnt; u++) { - Signature *s = dp->sh->match_array[u]; - printf("%" PRIu32 " ", s->id); - } -#endif - printf("\n"); - } - } - } - for (global_dst_gr = global_dst_gh->any_head; - global_dst_gr != NULL; - global_dst_gr = global_dst_gr->next) - { - printf(" - "); DetectAddressPrint(global_dst_gr); - //printf(" (sh %p) ", global_dst_gr->sh); - if (global_dst_gr->sh) { - if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) { - printf("(COPY)\n"); - } else { - printf("\n"); - } - } - DetectPort *sp = global_dst_gr->port; - for ( ; sp != NULL; sp = sp->next) { - printf(" * Src port(range): "); DetectPortPrint(sp); printf("\n"); - DetectPort *dp = sp->dst_ph; - for ( ; dp != NULL; dp = dp->next) { - printf(" * Dst port(range): "); DetectPortPrint(dp); - printf(" (sigs %" PRIu32 ")", dp->sh->sig_cnt); -#ifdef PRINTSIGS - printf(" - "); - for (u = 0; u < dp->sh->sig_cnt; u++) { - Signature *s = dp->sh->match_array[u]; - printf("%" PRIu32 " ", s->id); - } -#endif - printf("\n"); - } - } - } - } -#if 0 - for (global_src_gr = de_ctx->flow_gh[f].src_gh[proto]->ipv6_head; global_src_gr != NULL; - global_src_gr = global_src_gr->next) - { - printf("- "); DetectAddressPrint(global_src_gr); - //printf(" (sh %p)\n", global_src_gr->sh); - - global_dst_gh = global_src_gr->dst_gh; - if (global_dst_gh == NULL) - continue; - - for (global_dst_gr = global_dst_gh->ipv6_head; - global_dst_gr != NULL; - global_dst_gr = global_dst_gr->next) - { - printf(" - "); DetectAddressPrint(global_dst_gr); - //printf(" (sh %p) ", global_dst_gr->sh); - if (global_dst_gr->sh) { - if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) { - printf("(COPY)\n"); - } else { - printf("\n"); - } - } - DetectPort *sp = global_dst_gr->port; - for ( ; sp != NULL; sp = sp->next) { - printf(" * Src port(range): "); DetectPortPrint(sp); printf("\n"); - DetectPort *dp = sp->dst_ph; - for ( ; dp != NULL; dp = dp->next) { - printf(" * Dst port(range): "); DetectPortPrint(dp); - printf(" (sigs %" PRIu32 ")", dp->sh->sig_cnt); -#ifdef PRINTSIGS - printf(" - "); - for (u = 0; u < dp->sh->sig_cnt; u++) { - Signature *s = de_ctx->sig_array[dp->sh->match_array[u]]; - printf("%" PRIu32 " ", s->id); - } -#endif - printf("\n"); - } - } - } - for (global_dst_gr = global_dst_gh->any_head; - global_dst_gr != NULL; - global_dst_gr = global_dst_gr->next) - { - printf(" - "); DetectAddressPrint(global_dst_gr); - //printf(" (sh %p) ", global_dst_gr->sh); - if (global_dst_gr->sh) { - if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) { - printf("(COPY)\n"); - } else { - printf("\n"); - } - } - DetectPort *sp = global_dst_gr->port; - for ( ; sp != NULL; sp = sp->next) { - printf(" * Src port(range): "); DetectPortPrint(sp); printf("\n"); - DetectPort *dp = sp->dst_ph; - for ( ; dp != NULL; dp = dp->next) { - printf(" * Dst port(range): "); DetectPortPrint(dp); - printf(" (sigs %" PRIu32 ")", dp->sh->sig_cnt); -#ifdef PRINTSIGS - printf(" - "); - for (u = 0; u < dp->sh->sig_cnt; u++) { - Signature *s = de_ctx->sig_array[dp->sh->match_array[u]]; - printf("%" PRIu32 " ", s->id); - } -#endif - printf("\n"); - } - } - } - } - - for (global_src_gr = de_ctx->flow_gh[f].src_gh[proto]->any_head; global_src_gr != NULL; - global_src_gr = global_src_gr->next) - { - printf("- "); DetectAddressPrint(global_src_gr); - //printf(" (sh %p)\n", global_src_gr->sh); - - global_dst_gh = global_src_gr->dst_gh; - if (global_dst_gh == NULL) - continue; - - for (global_dst_gr = global_dst_gh->any_head; - global_dst_gr != NULL; - global_dst_gr = global_dst_gr->next) - { - printf(" - "); DetectAddressPrint(global_dst_gr); - //printf(" (sh %p) ", global_dst_gr->sh); - if (global_dst_gr->sh) { - if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) { - printf("(COPY)\n"); - } else { - printf("\n"); - } - } - DetectPort *sp = global_dst_gr->port; - for ( ; sp != NULL; sp = sp->next) { - printf(" * Src port(range): "); DetectPortPrint(sp); printf("\n"); - DetectPort *dp = sp->dst_ph; - for ( ; dp != NULL; dp = dp->next) { - printf(" * Dst port(range): "); DetectPortPrint(dp); - printf(" (sigs %" PRIu32 ")", dp->sh->sig_cnt); -#ifdef PRINTSIGS - printf(" - "); - for (u = 0; u < dp->sh->sig_cnt; u++) { - Signature *s = de_ctx->sig_array[dp->sh->match_array[u]]; - printf("%" PRIu32 " ", s->id); - } -#endif - printf("\n"); - } - } - } - for (global_dst_gr = global_dst_gh->ipv4_head; - global_dst_gr != NULL; - global_dst_gr = global_dst_gr->next) - { - printf(" - "); DetectAddressPrint(global_dst_gr); - //printf(" (sh %p) ", global_dst_gr->sh); - if (global_dst_gr->sh) { - if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) { - printf("(COPY)\n"); - } else { - printf("\n"); - } - } - DetectPort *sp = global_dst_gr->port; - for ( ; sp != NULL; sp = sp->next) { - printf(" * Src port(range): "); DetectPortPrint(sp); printf("\n"); - DetectPort *dp = sp->dst_ph; - for ( ; dp != NULL; dp = dp->next) { - printf(" * Dst port(range): "); DetectPortPrint(dp); - printf(" (sigs %" PRIu32 ")", dp->sh->sig_cnt); -#ifdef PRINTSIGS - printf(" - "); - for (u = 0; u < dp->sh->sig_cnt; u++) { - Signature *s = de_ctx->sig_array[dp->sh->match_array[u]]; - printf("%" PRIu32 " ", s->id); - } -#endif - printf("\n"); - } - } - } - for (global_dst_gr = global_dst_gh->ipv6_head; - global_dst_gr != NULL; - global_dst_gr = global_dst_gr->next) - { - printf(" - "); DetectAddressPrint(global_dst_gr); - //printf(" (sh %p) ", global_dst_gr->sh); - if (global_dst_gr->sh) { - if (global_dst_gr->sh->flags & ADDRESS_SIGGROUPHEAD_COPY) { - printf("(COPY)\n"); - } else { - printf("\n"); - } - } - DetectPort *sp = global_dst_gr->port; - for ( ; sp != NULL; sp = sp->next) { - printf(" * Src port(range): "); DetectPortPrint(sp); printf("\n"); - DetectPort *dp = sp->dst_ph; - for ( ; dp != NULL; dp = dp->next) { - printf(" * Dst port(range): "); DetectPortPrint(dp); - printf(" (sigs %" PRIu32 ")", dp->sh->sig_cnt); -#ifdef PRINTSIGS - printf(" - "); - for (u = 0; u < dp->sh->sig_cnt; u++) { - Signature *s = de_ctx->sig_array[dp->sh->match_array[u]]; - printf("%" PRIu32 " ", s->id); - } -#endif - printf("\n"); - } - } - } - } -#endif - } - } - - printf("* Building signature grouping structure, stage 5: print... done\n"); - return 0; -} - -static int SigMatchListLen(SigMatch *sm) -{ - int len = 0; - for (; sm != NULL; sm = sm->next) - len++; - - return len; -} - -static int SigMatchPrepare(DetectEngineCtx *de_ctx) -{ - SCEnter(); - - Signature *s = de_ctx->sig_list; - for (; s != NULL; s = s->next) { - int type; - for (type = 0; type < DETECT_SM_LIST_MAX; type++) { - SigMatch *sm = s->sm_lists[type]; - int len = SigMatchListLen(sm); - if (len == 0) - s->sm_arrays[type] = NULL; - else { - SigMatchData *smd = (SigMatchData*)SCMalloc(len * sizeof(SigMatchData)); - if (smd == NULL) { - SCLogError(SC_ERR_DETECT_PREPARE, "initializing the detection engine failed"); - exit(EXIT_FAILURE); - } - /* Copy sm type and Context into array */ - s->sm_arrays[type] = smd; - for (; sm != NULL; sm = sm->next, smd++) { - smd->type = sm->type; - smd->ctx = sm->ctx; - smd->is_last = (sm->next == NULL); - } - } - } - } - - SCReturnInt(0); -} - -/** - * \brief Convert the signature list into the runtime match structure. - * - * \param de_ctx Pointer to the Detection Engine Context whose Signatures have - * to be processed - * - * \retval 0 On Success. - * \retval -1 On failure. - */ -int SigGroupBuild(DetectEngineCtx *de_ctx) -{ - Signature *s = de_ctx->sig_list; - - /* Assign the unique order id of signatures after sorting, - * so the IP Only engine process them in order too. Also - * reset the old signums and assign new signums. We would - * have experienced Sig reordering by now, hence the new - * signums. */ - de_ctx->signum = 0; - while (s != NULL) { - s->num = de_ctx->signum++; - - s = s->next; - } - - if (DetectSetFastPatternAndItsId(de_ctx) < 0) - return -1; - - /* if we are using single sgh_mpm_context then let us init the standard mpm - * contexts using the mpm_ctx factory */ - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - SigInitStandardMpmFactoryContexts(de_ctx); - } - - if (SigAddressPrepareStage1(de_ctx) != 0) { - SCLogError(SC_ERR_DETECT_PREPARE, "initializing the detection engine failed"); - exit(EXIT_FAILURE); - } -//exit(0); - if (SigAddressPrepareStage2(de_ctx) != 0) { - SCLogError(SC_ERR_DETECT_PREPARE, "initializing the detection engine failed"); - exit(EXIT_FAILURE); - } - - if (SigAddressPrepareStage3(de_ctx) != 0) { - SCLogError(SC_ERR_DETECT_PREPARE, "initializing the detection engine failed"); - exit(EXIT_FAILURE); - } - if (SigAddressPrepareStage4(de_ctx) != 0) { - SCLogError(SC_ERR_DETECT_PREPARE, "initializing the detection engine failed"); - exit(EXIT_FAILURE); - } - - if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) { - MpmCtx *mpm_ctx = NULL; - -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA) { - /* setting it to default. You've gotta remove it once you fix the state table thing */ - SCACConstructBoth16and32StateTables(); - - MpmCudaConf *conf = CudaHandlerGetCudaProfile("mpm"); - CUcontext cuda_context = CudaHandlerModuleGetContext(MPM_AC_CUDA_MODULE_NAME, conf->device_id); - if (cuda_context == 0) { - SCLogError(SC_ERR_FATAL, "cuda context is NULL."); - exit(EXIT_FAILURE); - } - int r = SCCudaCtxPushCurrent(cuda_context); - if (r < 0) { - SCLogError(SC_ERR_FATAL, "context push failed."); - exit(EXIT_FAILURE); - } - } -#endif - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("packet- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("packet- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_other_packet, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("packet- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_uri, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_uri, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("uri- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcbd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcbd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hcbd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsbd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsbd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hsbd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_smtp, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_smtp, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("smtp- %d\n"; mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hhd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hrhd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hmd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hmd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hmd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hcd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrud, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrud, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hrud- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("stream- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsmd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hsmd- %d\n", mpm_ctx->pattern_cnt); - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsmd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hsmd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hscd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hscd- %d\n", mpm_ctx->pattern_cnt); - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hscd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hscd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_huad, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("huad- %d\n", mpm_ctx->pattern_cnt); - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_huad, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("huad- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhhd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hhhd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhhd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hhhd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhhd, 0); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hrhhd- %d\n", mpm_ctx->pattern_cnt); - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhhd, 1); - if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) { - mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx); - } - //printf("hrhhd- %d\n", mpm_ctx->pattern_cnt); - -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA) { - int r = SCCudaCtxPopCurrent(NULL); - if (r < 0) { - SCLogError(SC_ERR_FATAL, "cuda context pop failure."); - exit(EXIT_FAILURE); - } - } - - /* too late to call this either ways. Should be called post ac goto. - * \todo Support this. */ - DetermineCudaStateTableSize(de_ctx); -#endif - - } - -// SigAddressPrepareStage5(de_ctx); -// DetectAddressPrintMemory(); -// DetectSigGroupPrintMemory(); -// DetectPortPrintMemory(); - - if (SigMatchPrepare(de_ctx) != 0) { - SCLogError(SC_ERR_DETECT_PREPARE, "initializing the detection engine failed"); - exit(EXIT_FAILURE); - } - -#ifdef PROFILING - SCProfilingRuleInitCounters(de_ctx); -#endif - return 0; -} - -int SigGroupCleanup (DetectEngineCtx *de_ctx) -{ - SigAddressCleanupStage1(de_ctx); - - return 0; -} - -static inline void PrintFeatureList(int flags, char sep) -{ - int prev = 0; - if (flags & SIGMATCH_NOOPT) { - printf("No option"); - prev = 1; - } - if (flags & SIGMATCH_IPONLY_COMPAT) { - if (prev == 1) - printf("%c", sep); - printf("compatible with IP only rule"); - prev = 1; - } - if (flags & SIGMATCH_DEONLY_COMPAT) { - if (prev == 1) - printf("%c", sep); - printf("compatible with decoder event only rule"); - prev = 1; - } - if (flags & SIGMATCH_PAYLOAD) { - if (prev == 1) - printf("%c", sep); - printf("payload inspecting keyword"); - prev = 1; - } - if (prev == 0) { - printf("none"); - } -} - -static inline void SigMultilinePrint(int i, char *prefix) -{ - if (sigmatch_table[i].desc) { - printf("%sDescription: %s\n", prefix, sigmatch_table[i].desc); - } - printf("%sProtocol: %s\n", prefix, - AppLayerGetProtoName(sigmatch_table[i].alproto)); - printf("%sFeatures: ", prefix); - PrintFeatureList(sigmatch_table[i].flags, ','); - if (sigmatch_table[i].url) { - printf("\n%sDocumentation: %s", prefix, sigmatch_table[i].url); - } - printf("\n"); -} - -void SigTableList(const char *keyword) -{ - size_t size = sizeof(sigmatch_table) / sizeof(SigTableElmt); - size_t i; - char *proto_name; - - if (keyword == NULL) { - printf("=====Supported keywords=====\n"); - for (i = 0; i < size; i++) { - if (sigmatch_table[i].name != NULL) { - if (sigmatch_table[i].flags & SIGMATCH_NOT_BUILT) { - printf("- %s (not built-in)\n", sigmatch_table[i].name); - } else { - printf("- %s\n", sigmatch_table[i].name); - } - } - } - } else if (!strcmp("csv", keyword)) { - printf("name;description;app layer;features;documentation\n"); - for (i = 0; i < size; i++) { - if (sigmatch_table[i].name != NULL) { - if (sigmatch_table[i].flags & SIGMATCH_NOT_BUILT) { - continue; - } - printf("%s;", sigmatch_table[i].name); - if (sigmatch_table[i].desc) { - printf("%s", sigmatch_table[i].desc); - } - /* Build feature */ - proto_name = AppLayerGetProtoName(sigmatch_table[i].alproto); - printf(";%s;", proto_name ? proto_name : "Unset"); - PrintFeatureList(sigmatch_table[i].flags, ':'); - printf(";"); - if (sigmatch_table[i].url) { - printf("%s", sigmatch_table[i].url); - } - printf(";"); - printf("\n"); - } - } - } else if (!strcmp("all", keyword)) { - for (i = 0; i < size; i++) { - printf("%s:\n", sigmatch_table[i].name); - SigMultilinePrint(i, "\t"); - } - } else { - for (i = 0; i < size; i++) { - if ((sigmatch_table[i].name != NULL) && - !strcmp(sigmatch_table[i].name, keyword)) { - printf("= %s =\n", sigmatch_table[i].name); - if (sigmatch_table[i].flags & SIGMATCH_NOT_BUILT) { - printf("Not built-in\n"); - return; - } - SigMultilinePrint(i, ""); - return; - } - } - } - return; -} - -void SigTableSetup(void) -{ - memset(sigmatch_table, 0, sizeof(sigmatch_table)); - - DetectSidRegister(); - DetectPriorityRegister(); - DetectRevRegister(); - DetectClasstypeRegister(); - DetectReferenceRegister(); - DetectTagRegister(); - DetectThresholdRegister(); - DetectMetadataRegister(); - DetectMsgRegister(); - DetectAckRegister(); - DetectSeqRegister(); - DetectContentRegister(); - DetectUricontentRegister(); - DetectPcreRegister(); - DetectDepthRegister(); - DetectNocaseRegister(); - DetectRawbytesRegister(); - DetectBytetestRegister(); - DetectBytejumpRegister(); - DetectSameipRegister(); - DetectGeoipRegister(); - DetectL3ProtoRegister(); - DetectIPProtoRegister(); - DetectWithinRegister(); - DetectDistanceRegister(); - DetectOffsetRegister(); - DetectReplaceRegister(); - DetectFlowRegister(); - DetectWindowRegister(); - DetectRpcRegister(); - DetectFtpbounceRegister(); - DetectIsdataatRegister(); - DetectIdRegister(); - DetectDsizeRegister(); - DetectFlowvarRegister(); - DetectFlowintRegister(); - DetectPktvarRegister(); - DetectNoalertRegister(); - DetectFlowbitsRegister(); - DetectHostbitsRegister(); - DetectXbitsRegister(); - DetectEngineEventRegister(); - DetectIpOptsRegister(); - DetectFlagsRegister(); - DetectFragBitsRegister(); - DetectFragOffsetRegister(); - DetectGidRegister(); - DetectMarkRegister(); - DetectCsumRegister(); - DetectStreamSizeRegister(); - DetectTtlRegister(); - DetectTosRegister(); - DetectFastPatternRegister(); - DetectITypeRegister(); - DetectICodeRegister(); - DetectIcmpIdRegister(); - DetectIcmpSeqRegister(); - DetectDceIfaceRegister(); - DetectDceOpnumRegister(); - DetectDceStubDataRegister(); - DetectHttpCookieRegister(); - DetectHttpMethodRegister(); - DetectHttpStatMsgRegister(); - DetectTlsRegister(); - DetectTlsVersionRegister(); - DetectUrilenRegister(); - DetectDetectionFilterRegister(); - DetectHttpHeaderRegister(); - DetectHttpRawHeaderRegister(); - DetectHttpClientBodyRegister(); - DetectHttpServerBodyRegister(); - DetectHttpUriRegister(); - DetectHttpRawUriRegister(); - DetectAsn1Register(); - DetectSshVersionRegister(); - DetectSshSoftwareVersionRegister(); - DetectSslStateRegister(); - DetectHttpStatCodeRegister(); - DetectSslVersionRegister(); - DetectByteExtractRegister(); - DetectFiledataRegister(); - DetectPktDataRegister(); - DetectFilenameRegister(); - DetectFileextRegister(); - DetectFilestoreRegister(); - DetectFilemagicRegister(); - DetectFileMd5Register(); - DetectFilesizeRegister(); - DetectAppLayerEventRegister(); - DetectHttpUARegister(); - DetectHttpHHRegister(); - DetectHttpHRHRegister(); - DetectLuaRegister(); - DetectIPRepRegister(); - DetectDnsQueryRegister(); - DetectModbusRegister(); - DetectAppLayerProtocolRegister(); - DetectBase64DecodeRegister(); - DetectBase64DataRegister(); - DetectTemplateRegister(); - DetectTemplateBufferRegister(); -} - -void SigTableRegisterTests(void) -{ - /* register the tests */ - int i = 0; - for (i = 0; i < DETECT_TBLSIZE; i++) { - g_ut_modules++; - if (sigmatch_table[i].RegisterTests != NULL) { - sigmatch_table[i].RegisterTests(); - g_ut_covered++; - } else { - SCLogDebug("detection plugin %s has no unittest " - "registration function.", sigmatch_table[i].name); - - if (coverage_unittests) - SCLogWarning(SC_WARN_NO_UNITTESTS, "detection plugin %s has no unittest " - "registration function.", sigmatch_table[i].name); - } - } -} - -/* - * TESTS - */ - -#ifdef UNITTESTS -#include "flow-util.h" -#include "stream-tcp-reassemble.h" -#include "util-var-name.h" - -static const char *dummy_conf_string = - "%YAML 1.1\n" - "---\n" - "\n" - "default-log-dir: /var/log/suricata\n" - "\n" - "logging:\n" - "\n" - " default-log-level: debug\n" - "\n" - " default-format: \"<%t> - <%l>\"\n" - "\n" - " default-startup-message: Your IDS has started.\n" - "\n" - " default-output-filter:\n" - "\n" - " output:\n" - "\n" - " - interface: console\n" - " log-level: info\n" - "\n" - " - interface: file\n" - " filename: /var/log/suricata.log\n" - "\n" - " - interface: syslog\n" - " facility: local5\n" - " format: \"%l\"\n" - "\n" - "pfring:\n" - "\n" - " interface: eth0\n" - "\n" - " clusterid: 99\n" - "\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"[192.168.0.0/16,10.8.0.0/16,127.0.0.1,2001:888:" - "13c5:5AFE::/64,2001:888:13c5:CAFE::/64]\"\n" - "\n" - " EXTERNAL_NET: \"[!192.168.0.0/16,2000::/3]\"\n" - "\n" - " HTTP_SERVERS: \"!192.168.0.0/16\"\n" - "\n" - " SMTP_SERVERS: \"!192.168.0.0/16\"\n" - "\n" - " SQL_SERVERS: \"!192.168.0.0/16\"\n" - "\n" - " DNS_SERVERS: any\n" - "\n" - " TELNET_SERVERS: any\n" - "\n" - " AIM_SERVERS: any\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"80:81,88\"\n" - "\n" - " SHELLCODE_PORTS: 80\n" - "\n" - " ORACLE_PORTS: 1521\n" - "\n" - " SSH_PORTS: 22\n" - "\n"; - -static int SigTest01Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - int result = 0; - - char sig[] = "alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:1;)"; - if (UTHPacketMatchSigMpm(p, sig, mpm_type) == 0) { - result = 0; - goto end; - } -#if 0 - //printf("URI0 \"%s\", len %" PRIu32 "\n", p.http_uri.raw[0], p.http_uri.raw_size[0]); - //printf("URI1 \"%s\", len %" PRIu32 "\n", p.http_uri.raw[1], p.http_uri.raw_size[1]); - - if (p->http_uri.raw_size[0] == 5 && - memcmp(p->http_uri.raw[0], "/one/", 5) == 0 && - p->http_uri.raw_size[1] == 5 && - memcmp(p->http_uri.raw[1], "/two/", 5) == 0) - { - result = 1; - } - -#endif - result = 1; -end: - if (p != NULL) - UTHFreePacket(p); - return result; -} - -static int SigTest01B2g (void) -{ - return SigTest01Real(MPM_B2G); -} -static int SigTest01B3g (void) -{ - return SigTest01Real(MPM_B3G); -} -static int SigTest01Wm (void) -{ - return SigTest01Real(MPM_WUMANBER); -} - -static int SigTest02Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP); - char sig[] = "alert tcp any any -> any any (msg:\"HTTP TEST\"; content:\"Host: one.example.org\"; offset:20; depth:41; sid:1;)"; - int ret = UTHPacketMatchSigMpm(p, sig, mpm_type); - UTHFreePacket(p); - return ret; -} - -static int SigTest02B2g (void) -{ - return SigTest02Real(MPM_B2G); -} -static int SigTest02B3g (void) -{ - return SigTest02Real(MPM_B3G); -} -static int SigTest02Wm (void) -{ - return SigTest02Real(MPM_WUMANBER); -} - - -static int SigTest03Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; content:\"Host: one.example.org\"; offset:20; depth:39; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTest03B2g (void) -{ - return SigTest03Real(MPM_B2G); -} -static int SigTest03B3g (void) -{ - return SigTest03Real(MPM_B3G); -} -static int SigTest03Wm (void) -{ - return SigTest03Real(MPM_WUMANBER); -} - - -static int SigTest04Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" /* 20*/ - "Host: one.example.org\r\n" /* 23, post "Host:" 18 */ - "\r\n\r\n" /* 4 */ - "GET /two/ HTTP/1.1\r\n" /* 20 */ - "Host: two.example.org\r\n" /* 23 */ - "\r\n\r\n"; /* 4 */ - uint16_t buflen = strlen((char *)buf); - - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; content:\"Host:\"; offset:20; depth:25; content:\"Host:\"; distance:42; within:47; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTest04B2g (void) -{ - return SigTest04Real(MPM_B2G); -} -static int SigTest04B3g (void) -{ - return SigTest04Real(MPM_B3G); -} -static int SigTest04Wm (void) -{ - return SigTest04Real(MPM_WUMANBER); -} - - -static int SigTest05Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" /* 20 */ - "Host: one.example.org\r\n" /* 23, 43 */ - "\r\n\r\n" /* 4, 47 */ - "GET /two/ HTTP/1.1\r\n" /* 20, 67 */ - "Host: two.example.org\r\n" /* 23, 90 */ - "\r\n\r\n"; /* 4, 94 */ - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; content:\"Host:\"; offset:20; depth:25; content:\"Host:\"; distance:48; within:52; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!PacketAlertCheck(p, 1)) { - result = 1; - } else { - printf("sig matched but shouldn't have: "); - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTest05B2g (void) -{ - return SigTest05Real(MPM_B2G); -} -static int SigTest05B3g (void) -{ - return SigTest05Real(MPM_B3G); -} -static int SigTest05Wm (void) -{ - return SigTest05Real(MPM_WUMANBER); -} - - -static int SigTest06Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" /* 20 */ - "Host: one.example.org\r\n" /* 23, 43 */ - "\r\n\r\n" /* 4, 47 */ - "GET /two/ HTTP/1.1\r\n" /* 20, 67 */ - "Host: two.example.org\r\n" /* 23, 90 */ - "\r\n\r\n"; /* 4, 94 */ - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - TcpSession ssn; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI test\"; uricontent:\"two\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, buf, buflen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) && PacketAlertCheck(p, 2)) - result = 1; - else - printf("sid:1 %s, sid:2 %s: ", - PacketAlertCheck(p, 1) ? "OK" : "FAIL", - PacketAlertCheck(p, 2) ? "OK" : "FAIL"); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreePackets(&p, 1); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} -static int SigTest06B2g (void) -{ - return SigTest06Real(MPM_B2G); -} -static int SigTest06B3g (void) -{ - return SigTest06Real(MPM_B3G); -} -static int SigTest06Wm (void) -{ - return SigTest06Real(MPM_WUMANBER); -} - - -static int SigTest07Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" /* 20 */ - "Host: one.example.org\r\n" /* 23, 43 */ - "\r\n\r\n" /* 4, 47 */ - "GET /two/ HTTP/1.1\r\n" /* 20, 67 */ - "Host: two.example.org\r\n" /* 23, 90 */ - "\r\n\r\n"; /* 4, 94 */ - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - TcpSession ssn; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI test\"; uricontent:\"three\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, buf, buflen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) && PacketAlertCheck(p, 2)) - result = 0; - else - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreePackets(&p, 1); - StreamTcpFreeConfig(TRUE); - FlowCleanupAppLayer(&f); - FLOW_DESTROY(&f); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} -static int SigTest07B2g (void) -{ - return SigTest07Real(MPM_B2G); -} -static int SigTest07B3g (void) -{ - return SigTest07Real(MPM_B3G); -} -static int SigTest07Wm (void) -{ - return SigTest07Real(MPM_WUMANBER); -} - - -static int SigTest08Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.0\r\n" /* 20 */ - "Host: one.example.org\r\n" /* 23, 43 */ - "\r\n\r\n" /* 4, 47 */ - "GET /two/ HTTP/1.0\r\n" /* 20, 67 */ - "Host: two.example.org\r\n" /* 23, 90 */ - "\r\n\r\n"; /* 4, 94 */ - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - TcpSession ssn; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&f, 0, sizeof(Flow)); - memset(&th_v, 0, sizeof(th_v)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/1\\.0\\r\\n/G\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI test\"; uricontent:\"one\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, buf, buflen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) && PacketAlertCheck(p, 2)) - result = 1; - else - printf("sid:1 %s, sid:2 %s: ", - PacketAlertCheck(p, 1) ? "OK" : "FAIL", - PacketAlertCheck(p, 2) ? "OK" : "FAIL"); - -end: - FlowCleanupAppLayer(&f); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - if (det_ctx) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreePackets(&p, 1); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} -static int SigTest08B2g (void) -{ - return SigTest08Real(MPM_B2G); -} -static int SigTest08B3g (void) -{ - return SigTest08Real(MPM_B3G); -} -static int SigTest08Wm (void) -{ - return SigTest08Real(MPM_WUMANBER); -} - - -static int SigTest09Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.0\r\n" /* 20 */ - "Host: one.example.org\r\n" /* 23, 43 */ - "\r\n\r\n" /* 4, 47 */ - "GET /two/ HTTP/1.0\r\n" /* 20, 67 */ - "Host: two.example.org\r\n" /* 23, 90 */ - "\r\n\r\n"; /* 4, 94 */ - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - TcpSession ssn; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.flags |= FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/1\\.0\\r\\n/G\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI test\"; uricontent:\"two\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, buf, buflen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) && PacketAlertCheck(p, 2)) - result = 1; - else - result = 0; - -end: - FlowCleanupAppLayer(&f); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreePackets(&p, 1); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} -static int SigTest09B2g (void) -{ - return SigTest09Real(MPM_B2G); -} -static int SigTest09B3g (void) -{ - return SigTest09Real(MPM_B3G); -} -static int SigTest09Wm (void) -{ - return SigTest09Real(MPM_WUMANBER); -} - - -static int SigTest10Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "ABC"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - TcpSession ssn; - int result = 0; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Long content test (1)\"; content:\"ABCD\"; depth:4; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Long content test (2)\"; content:\"VWXYZ\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, buf, buflen); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) && PacketAlertCheck(p, 2)) - result = 0; - else - result = 1; - - end: - FlowCleanupAppLayer(&f); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - UTHFreePackets(&p, 1); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} -static int SigTest10B2g (void) -{ - return SigTest10Real(MPM_B2G); -} -static int SigTest10B3g (void) -{ - return SigTest10Real(MPM_B3G); -} -static int SigTest10Wm (void) -{ - return SigTest10Real(MPM_WUMANBER); -} - - -static int SigTest11Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - TcpSession ssn; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (content:\"ABCDEFGHIJ\"; content:\"klmnop\"; content:\"1234\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (content:\"VWXYZabcde\"; content:\"5678\"; content:\"89\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) && PacketAlertCheck(p, 2)) - result = 1; - - end: - FlowCleanupAppLayer(&f); - SigGroupCleanup(de_ctx); - if (det_ctx) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - UTHFreePackets(&p, 1); - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - return result; -} -static int SigTest11B2g (void) -{ - return SigTest11Real(MPM_B2G); -} -static int SigTest11B3g (void) -{ - return SigTest11Real(MPM_B3G); -} -static int SigTest11Wm (void) -{ - return SigTest11Real(MPM_WUMANBER); -} - - -static int SigTest12Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - Flow f; - memset(&f, 0, sizeof(Flow)); - - FLOW_INITIALIZE(&f); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Content order test\"; content:\"ABCDEFGHIJ\"; content:\"klmnop\"; content:\"1234\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) - result = 1; - else - result = 0; - - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); -end: - UTHFreePackets(&p, 1); - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - FLOW_DESTROY(&f); - return result; -} -static int SigTest12B2g (void) -{ - return SigTest12Real(MPM_B2G); -} -static int SigTest12B3g (void) -{ - return SigTest12Real(MPM_B3G); -} -static int SigTest12Wm (void) -{ - return SigTest12Real(MPM_WUMANBER); -} - - -static int SigTest13Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - Flow f; - memset(&f, 0, sizeof(Flow)); - - FLOW_INITIALIZE(&f); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - p->flow = &f; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Content order test\"; content:\"ABCDEFGHIJ\"; content:\"1234\"; content:\"klmnop\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) - result = 1; - else - result = 0; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - FLOW_DESTROY(&f); - return result; -} -static int SigTest13B2g (void) -{ - return SigTest13Real(MPM_B2G); -} -static int SigTest13B3g (void) -{ - return SigTest13Real(MPM_B3G); -} -static int SigTest13Wm (void) -{ - return SigTest13Real(MPM_WUMANBER); -} - - -static int SigTest14Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Content order test\"; content:\"ABCDEFGHIJ\"; content:\"1234\"; content:\"klmnop\"; distance:0; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) - result = 0; - else - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTest14B2g (void) -{ - return SigTest14Real(MPM_B2G); -} -static int SigTest14B3g (void) -{ - return SigTest14Real(MPM_B3G); -} -static int SigTest14Wm (void) -{ - return SigTest14Real(MPM_WUMANBER); -} - - -static int SigTest15Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "CONNECT 213.92.8.7:31204 HTTP/1.1"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - p->dp = 80; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any !$HTTP_PORTS (msg:\"ET POLICY Inbound HTTP CONNECT Attempt on Off-Port\"; content:\"CONNECT \"; nocase; depth:8; content:\" HTTP/1.\"; nocase; within:1000; sid:2008284; rev:2;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 2008284)) - result = 0; - else - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - ConfDeInit(); - ConfRestoreContextBackup(); - SCFree(p); - return result; -} -static int SigTest15B2g (void) -{ - return SigTest15Real(MPM_B2G); -} -static int SigTest15B3g (void) -{ - return SigTest15Real(MPM_B3G); -} -static int SigTest15Wm (void) -{ - return SigTest15Real(MPM_WUMANBER); -} - - -static int SigTest16Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "CONNECT 213.92.8.7:31204 HTTP/1.1"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(&p, 0, sizeof(p)); - - p = UTHBuildPacketSrcDstPorts((uint8_t *)buf, buflen, IPPROTO_TCP, 12345, 1234); - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any !$HTTP_PORTS (msg:\"ET POLICY Inbound HTTP CONNECT Attempt on Off-Port\"; content:\"CONNECT \"; nocase; depth:8; content:\" HTTP/1.\"; nocase; within:1000; sid:2008284; rev:2;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 2008284)) - result = 1; - else - printf("sid:2008284 %s: ", PacketAlertCheck(p, 2008284) ? "OK" : "FAIL"); - - SigGroupCleanup(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - ConfDeInit(); - ConfRestoreContextBackup(); - UTHFreePackets(&p, 1); - return result; -} -static int SigTest16B2g (void) -{ - return SigTest16Real(MPM_B2G); -} -static int SigTest16B3g (void) -{ - return SigTest16Real(MPM_B3G); -} -static int SigTest16Wm (void) -{ - return SigTest16Real(MPM_WUMANBER); -} - - -static int SigTest17Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" /* 20 */ - "Host: one.example.org\r\n" /* 23, 43 */ - "\r\n\r\n" /* 4, 47 */ - "GET /two/ HTTP/1.1\r\n" /* 20, 67 */ - "Host: two.example.org\r\n" /* 23, 90 */ - "\r\n\r\n"; /* 4, 94 */ - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacketSrcDstPorts((uint8_t *)buf, buflen, IPPROTO_TCP, 12345, 80); - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any $HTTP_PORTS (msg:\"HTTP host cap\"; content:\"Host:\"; pcre:\"/^Host: (?P.*)\\r\\n/m\"; noalert; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - PktVar *pv_hn = PktVarGet(p, "http_host"); - if (pv_hn != NULL) { - if (memcmp(pv_hn->value, "one.example.org", pv_hn->value_len < 15 ? pv_hn->value_len : 15) == 0) - result = 1; - else { - printf("\""); - PrintRawUriFp(stdout, pv_hn->value, pv_hn->value_len); - printf("\" != \"one.example.org\": "); - } - PktVarFree(pv_hn); - } else { - printf("Pkt var http_host not captured: "); - } - -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - ConfDeInit(); - ConfRestoreContextBackup(); - UTHFreePackets(&p, 1); - return result; -} -static int SigTest17B2g (void) -{ - return SigTest17Real(MPM_B2G); -} -static int SigTest17B3g (void) -{ - return SigTest17Real(MPM_B3G); -} -static int SigTest17Wm (void) -{ - return SigTest17Real(MPM_WUMANBER); -} - -static int SigTest18Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "220 (vsFTPd 2.0.5)\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - p->dp = 34260; - p->sp = 21; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any !21:902 -> any any (msg:\"ET MALWARE Suspicious 220 Banner on Local Port\"; content:\"220\"; offset:0; depth:4; pcre:\"/220[- ]/\"; sid:2003055; rev:4;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (!PacketAlertCheck(p, 2003055)) - result = 1; - else - printf("signature shouldn't match, but did: "); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p); - return result; -} -static int SigTest18B2g (void) -{ - return SigTest18Real(MPM_B2G); -} -static int SigTest18B3g (void) -{ - return SigTest18Real(MPM_B3G); -} -static int SigTest18Wm (void) -{ - return SigTest18Real(MPM_WUMANBER); -} - -int SigTest19Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "220 (vsFTPd 2.0.5)\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("192.168.0.1"); - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4"); - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - p->dp = 34260; - p->sp = 21; - p->flowflags |= FLOW_PKT_TOSERVER; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert ip $HOME_NET any -> 1.2.3.4 any (msg:\"IP-ONLY test (1)\"; sid:999; rev:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 999)) - result = 1; - else - printf("signature didn't match, but should have: "); - - SigGroupCleanup(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - ConfDeInit(); - ConfRestoreContextBackup(); - SCFree(p); - return result; -} -static int SigTest19B2g (void) -{ - return SigTest19Real(MPM_B2G); -} -static int SigTest19B3g (void) -{ - return SigTest19Real(MPM_B3G); -} -static int SigTest19Wm (void) -{ - return SigTest19Real(MPM_WUMANBER); -} - -static int SigTest20Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *) - "220 (vsFTPd 2.0.5)\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("192.168.0.1"); - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4"); - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - p->dp = 34260; - p->sp = 21; - p->flowflags |= FLOW_PKT_TOSERVER; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert ip $HOME_NET any -> [99.99.99.99,1.2.3.0/24,1.1.1.1,3.0.0.0/8] any (msg:\"IP-ONLY test (2)\"; sid:999; rev:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - //DetectEngineIPOnlyThreadInit(de_ctx,&det_ctx->io_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 999)) - result = 1; - else - printf("signature didn't match, but should have: "); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); - DetectEngineCtxFree(de_ctx); -end: - ConfDeInit(); - ConfRestoreContextBackup(); - SCFree(p); - return result; -} -static int SigTest20B2g (void) -{ - return SigTest20Real(MPM_B2G); -} -static int SigTest20B3g (void) -{ - return SigTest20Real(MPM_B3G); -} -static int SigTest20Wm (void) -{ - return SigTest20Real(MPM_WUMANBER); -} - - -static int SigTest21Real (int mpm_type) -{ - ThreadVars th_v; - memset(&th_v, 0, sizeof(th_v)); - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - Flow f; - memset(&f, 0, sizeof(f)); - FLOW_INITIALIZE(&f); - - /* packet 1 */ - uint8_t *buf1 = (uint8_t *)"GET /one/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buf1len = strlen((char *)buf1); - Packet *p1 = NULL; - /* packet 2 */ - uint8_t *buf2 = (uint8_t *)"GET /two/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buf2len = strlen((char *)buf2); - Packet *p2 = NULL; - - p1 = UTHBuildPacket((uint8_t *)buf1, buf1len, IPPROTO_TCP); - p1->flow = &f; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2 = UTHBuildPacket((uint8_t *)buf2, buf2len, IPPROTO_TCP); - p2->flow = &f; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"FLOWBIT SET\"; content:\"/one/\"; flowbits:set,TEST.one; flowbits:noalert; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"FLOWBIT TEST\"; content:\"/two/\"; flowbits:isset,TEST.one; sid:2;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 alerted, but shouldn't: "); - goto end; - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 2))) { - printf("sid 2 didn't alert, but should have: "); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - } - DetectEngineCtxFree(de_ctx); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - FLOW_DESTROY(&f); - return result; -} -static int SigTest21B2g (void) -{ - return SigTest21Real(MPM_B2G); -} -static int SigTest21B3g (void) -{ - return SigTest21Real(MPM_B3G); -} -static int SigTest21Wm (void) -{ - return SigTest21Real(MPM_WUMANBER); -} - - -static int SigTest22Real (int mpm_type) -{ - ThreadVars th_v; - memset(&th_v, 0, sizeof(th_v)); - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - Flow f; - memset(&f, 0, sizeof(f)); - FLOW_INITIALIZE(&f); - - /* packet 1 */ - uint8_t *buf1 = (uint8_t *)"GET /one/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buf1len = strlen((char *)buf1); - Packet *p1 = NULL; - - p1 = UTHBuildPacket((uint8_t *)buf1, buf1len, IPPROTO_TCP); - p1->flow = &f; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - /* packet 2 */ - uint8_t *buf2 = (uint8_t *)"GET /two/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buf2len = strlen((char *)buf2); - Packet *p2 = NULL; - - p2 = UTHBuildPacket((uint8_t *)buf2, buf2len, IPPROTO_TCP); - p2->flow = &f; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"FLOWBIT SET\"; content:\"/one/\"; flowbits:set,TEST.one; flowbits:noalert; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"FLOWBIT TEST\"; content:\"/two/\"; flowbits:isset,TEST.abc; sid:2;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 alerted, but shouldn't: "); - goto end; - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 2))) - result = 1; - else - printf("sid 2 alerted, but shouldn't: "); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - FLOW_DESTROY(&f); - return result; -} -static int SigTest22B2g (void) -{ - return SigTest22Real(MPM_B2G); -} -static int SigTest22B3g (void) -{ - return SigTest22Real(MPM_B3G); -} -static int SigTest22Wm (void) -{ - return SigTest22Real(MPM_WUMANBER); -} - -static int SigTest23Real (int mpm_type) -{ - ThreadVars th_v; - memset(&th_v, 0, sizeof(th_v)); - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - Flow f; - memset(&f, 0, sizeof(f)); - FLOW_INITIALIZE(&f); - - /* packet 1 */ - uint8_t *buf1 = (uint8_t *)"GET /one/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buf1len = strlen((char *)buf1); - Packet *p1 = NULL; - - p1 = UTHBuildPacket((uint8_t *)buf1, buf1len, IPPROTO_TCP); - p1->flow = &f; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - /* packet 2 */ - uint8_t *buf2 = (uint8_t *)"GET /two/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buf2len = strlen((char *)buf2); - Packet *p2 = NULL; - - p2 = UTHBuildPacket((uint8_t *)buf2, buf2len, IPPROTO_TCP); - p2->flow = &f; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"FLOWBIT SET\"; content:\"/one/\"; flowbits:toggle,TEST.one; flowbits:noalert; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"FLOWBIT TEST\"; content:\"/two/\"; flowbits:isset,TEST.one; sid:2;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) { - printf("sid 1 alerted, but shouldn't: "); - goto end; - } - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result = 1; - else - printf("sid 2 didn't alert, but should have: "); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - FLOW_DESTROY(&f); - return result; -} -static int SigTest23B2g (void) -{ - return SigTest23Real(MPM_B2G); -} -static int SigTest23B3g (void) -{ - return SigTest23Real(MPM_B3G); -} -static int SigTest23Wm (void) -{ - return SigTest23Real(MPM_WUMANBER); -} - -int SigTest24IPV4Keyword(void) -{ - uint8_t valid_raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03, - 0xc0, 0xa8, 0x01, 0x03}; - - uint8_t invalid_raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03, - 0xc0, 0xa8, 0x01, 0x06}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - PACKET_RESET_CHECKSUMS(p1); - PACKET_RESET_CHECKSUMS(p2); - - p1->ip4h = (IPV4Hdr *)valid_raw_ipv4; - - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = buflen; - p1->proto = IPPROTO_TCP; - - p2->ip4h = (IPV4Hdr *)invalid_raw_ipv4; - - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = buflen; - p2->proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert ip any any -> any any " - "(content:\"/one/\"; ipv4-csum:valid; " - "msg:\"ipv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig 1 parse: "); - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert ip any any -> any any " - "(content:\"/one/\"; ipv4-csum:invalid; " - "msg:\"ipv4-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - printf("sig 2 parse: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (!(PacketAlertCheck(p1, 1))) { - printf("signature 1 didn't match, but should have: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!((PacketAlertCheck(p2, 2)))) { - printf("signature 2 didn't match, but should have: "); - goto end; - } - - result = 1; -end: - if (det_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest25NegativeIPV4Keyword(void) -{ - uint8_t valid_raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03, - 0xc0, 0xa8, 0x01, 0x03}; - - uint8_t invalid_raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03, - 0xc0, 0xa8, 0x01, 0x06}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - PACKET_RESET_CHECKSUMS(p1); - PACKET_RESET_CHECKSUMS(p2); - - p1->ip4h = (IPV4Hdr *)valid_raw_ipv4; - - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = buflen; - p1->proto = IPPROTO_TCP; - - p2->ip4h = (IPV4Hdr *)invalid_raw_ipv4; - - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = buflen; - p2->proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert ip any any -> any any " - "(content:\"/one/\"; ipv4-csum:invalid; " - "msg:\"ipv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert ip any any -> any any " - "(content:\"/one/\"; ipv4-csum:valid; " - "msg:\"ipv4-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 0; - else - result &= 1; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 0; - else - result &= 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest26TCPV4Keyword(void) -{ - uint8_t raw_ipv4[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x8e, 0x7e, 0xb2, - 0xc0, 0xa8, 0x01, 0x03}; - - uint8_t valid_raw_tcp[] = { - 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, - 0xcf, 0x0d, 0x21, 0x80, 0x50, 0x12, 0x16, 0xa0, - 0x4A, 0x04, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, - 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x02}; - - uint8_t invalid_raw_tcp[] = { - 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, - 0xcf, 0x0d, 0x21, 0x80, 0x50, 0x12, 0x16, 0xa0, - 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, - 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x03}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PacketCopyData(p1, raw_ipv4, sizeof(raw_ipv4)); - PacketCopyDataOffset(p1, GET_PKT_LEN(p1), valid_raw_tcp, sizeof(valid_raw_tcp)); - - PacketCopyData(p2, raw_ipv4, sizeof(raw_ipv4)); - PacketCopyDataOffset(p2, GET_PKT_LEN(p2), invalid_raw_tcp, sizeof(invalid_raw_tcp)); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip4h = (IPV4Hdr *)GET_PKT_DATA(p1); - p1->tcph = (TCPHdr *)(GET_PKT_DATA(p1) + sizeof(raw_ipv4)); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = (uint8_t *)GET_PKT_DATA(p1) + sizeof(raw_ipv4) + 20; - p1->payload_len = 20; - p1->proto = IPPROTO_TCP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip4h = (IPV4Hdr *)GET_PKT_DATA(p2); - p2->tcph = (TCPHdr *)(GET_PKT_DATA(p2) + sizeof(raw_ipv4)); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = (uint8_t *)GET_PKT_DATA(p2) + sizeof(raw_ipv4) + 20; - p2->payload_len = 20; - p2->proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert ip any any -> any any " - "(content:\"|DE 01 03|\"; tcpv4-csum:valid; dsize:20; " - "msg:\"tcpv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert ip any any -> any any " - "(content:\"|DE 01 03|\"; tcpv4-csum:invalid; " - "msg:\"tcpv4-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (!(PacketAlertCheck(p1, 1))) { - printf("sig 1 didn't match: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 2))) { - printf("sig 2 didn't match: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - SCFree(p1); - SCFree(p2); - return result; -} - -/* Test SigTest26TCPV4Keyword but also check for invalid IPV4 checksum */ -static int SigTest26TCPV4AndNegativeIPV4Keyword(void) -{ - uint8_t raw_ipv4[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x8e, 0x7e, 0xb2, - 0xc0, 0xa8, 0x01, 0x03}; - - uint8_t valid_raw_tcp[] = { - 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, - 0xcf, 0x0d, 0x21, 0x80, 0x50, 0x12, 0x16, 0xa0, - 0x4A, 0x04, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, - 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x02}; - - uint8_t invalid_raw_tcp[] = { - 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, - 0xcf, 0x0d, 0x21, 0x80, 0x50, 0x12, 0x16, 0xa0, - 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, - 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x03}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PacketCopyData(p1, raw_ipv4, sizeof(raw_ipv4)); - PacketCopyDataOffset(p1, GET_PKT_LEN(p1), valid_raw_tcp, sizeof(valid_raw_tcp)); - - PacketCopyData(p2, raw_ipv4, sizeof(raw_ipv4)); - PacketCopyDataOffset(p2, GET_PKT_LEN(p2), invalid_raw_tcp, sizeof(invalid_raw_tcp)); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip4h = (IPV4Hdr *)GET_PKT_DATA(p1); - p1->tcph = (TCPHdr *)(GET_PKT_DATA(p1) + sizeof(raw_ipv4)); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = (uint8_t *)GET_PKT_DATA(p1) + sizeof(raw_ipv4) + 20; - p1->payload_len = 20; - p1->proto = IPPROTO_TCP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip4h = (IPV4Hdr *)GET_PKT_DATA(p2); - p2->tcph = (TCPHdr *)(GET_PKT_DATA(p2) + sizeof(raw_ipv4)); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = (uint8_t *)GET_PKT_DATA(p2) + sizeof(raw_ipv4) + 20; - p2->payload_len = 20; - p2->proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert ip any any -> any any " - "(content:\"|DE 01 03|\"; tcpv4-csum:valid; dsize:20; " - "ipv4-csum:invalid; " - "msg:\"tcpv4-csum and ipv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert ip any any -> any any " - "(content:\"|DE 01 03|\"; tcpv4-csum:invalid; " - "ipv4-csum:invalid; " - "msg:\"tcpv4-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (!(PacketAlertCheck(p1, 1))) { - printf("sig 1 didn't match: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 2))) { - printf("sig 2 didn't match: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - SCFree(p1); - SCFree(p2); - return result; -} - -/* Similar to SigTest26, but with different packet */ -static int SigTest26TCPV4AndIPV4Keyword(void) -{ - /* IPV4: src:192.168.176.67 dst: 192.168.176.116 - * TTL: 64 Flags: Don't Fragment - */ - uint8_t raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x40, 0x9b, 0xa4, 0x40, 0x00, - 0x40, 0x06, 0xbd, 0x0a, 0xc0, 0xa8, 0xb0, 0x43, - 0xc0, 0xa8, 0xb0, 0x74}; - - /* TCP: sport: 49517 dport: 445 Flags: SYN - * Window size: 65535, checksum: 0x2009, - * MTU: 1460, Window scale: 4, TSACK permitted, - * 24 bytes of options, no payload. - */ - uint8_t valid_raw_tcp[] = { - 0xc1, 0x6d, 0x01, 0xbd, 0x03, 0x10, 0xd3, 0xc9, - 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xff, 0xff, - 0x20, 0x09, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x01, 0x03, 0x03, 0x04, 0x01, 0x01, 0x08, 0x0a, - 0x19, 0x69, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x02, 0x00, 0x00}; - - uint8_t invalid_raw_tcp[] = { - 0xc1, 0x6d, 0x01, 0xbd, 0x03, 0x10, 0xd3, 0xc9, - 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xff, 0xff, - 0x20, 0x09, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x01, 0x03, 0x03, 0x04, 0x01, 0x01, 0x08, 0x0a, - 0x19, 0x69, 0x81, 0x7e, 0xFF, 0xAA, 0x00, 0x00, - 0x04, 0x02, 0x00, 0x00}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PacketCopyData(p1, raw_ipv4, sizeof(raw_ipv4)); - PacketCopyDataOffset(p1, GET_PKT_LEN(p1), valid_raw_tcp, sizeof(valid_raw_tcp)); - - PacketCopyData(p2, raw_ipv4, sizeof(raw_ipv4)); - PacketCopyDataOffset(p2, GET_PKT_LEN(p2), invalid_raw_tcp, sizeof(invalid_raw_tcp)); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip4h = (IPV4Hdr *)GET_PKT_DATA(p1); - p1->tcph = (TCPHdr *)(GET_PKT_DATA(p1) + sizeof(raw_ipv4)); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = (uint8_t *)GET_PKT_DATA(p1) + sizeof(raw_ipv4) + 20 + 24; - p1->payload_len = 0; - p1->proto = IPPROTO_TCP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip4h = (IPV4Hdr *)GET_PKT_DATA(p2); - p2->tcph = (TCPHdr *)(GET_PKT_DATA(p2) + sizeof(raw_ipv4)); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = (uint8_t *)GET_PKT_DATA(p2) + sizeof(raw_ipv4) + 20 + 24; - p2->payload_len = 0; - p2->proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert ip any any -> any any " - "(tcpv4-csum:valid; " - "ipv4-csum:valid; " - "msg:\"tcpv4-csum and ipv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert ip any any -> any any " - "(tcpv4-csum:invalid; " - "ipv4-csum:valid; " - "msg:\"tcpv4-csum and ipv4-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (!(PacketAlertCheck(p1, 1))) { - printf("sig 1 didn't match: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 2))) { - printf("sig 2 didn't match: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - SCFree(p1); - SCFree(p2); - return result; -} - -static int SigTest27NegativeTCPV4Keyword(void) -{ - uint8_t raw_ipv4[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x8e, 0x7e, 0xb2, - 0xc0, 0xa8, 0x01, 0x03}; - - uint8_t valid_raw_tcp[] = { - 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, - 0xcf, 0x0d, 0x21, 0x80, 0x50, 0x12, 0x16, 0xa0, - 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, - 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x02}; - - uint8_t invalid_raw_tcp[] = { - 0x00, 0x50, 0x8e, 0x16, 0x0d, 0x59, 0xcd, 0x3c, - 0xcf, 0x0d, 0x21, 0x80, 0x50, 0x12, 0x16, 0xa0, - 0xfa, 0x03, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, - 0x04, 0x02, 0x08, 0x0a, 0x6e, 0x18, 0x78, 0x73, - 0x01, 0x71, 0x74, 0xde, 0x01, 0x03, 0x03, 0x03}; - - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PacketCopyData(p1, raw_ipv4, sizeof(raw_ipv4)); - PacketCopyDataOffset(p1, GET_PKT_LEN(p1), valid_raw_tcp, sizeof(valid_raw_tcp)); - - PacketCopyData(p2, raw_ipv4, sizeof(raw_ipv4)); - PacketCopyDataOffset(p2, GET_PKT_LEN(p2), invalid_raw_tcp, sizeof(invalid_raw_tcp)); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip4h = (IPV4Hdr *)GET_PKT_DATA(p1); - p1->tcph = (TCPHdr *)(GET_PKT_DATA(p1) + sizeof(raw_ipv4)); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = (uint8_t *)GET_PKT_DATA(p1) + sizeof(raw_ipv4) + 20; - p1->payload_len = 20; - p1->proto = IPPROTO_TCP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip4h = (IPV4Hdr *)GET_PKT_DATA(p2); - p2->tcph = (TCPHdr *)(GET_PKT_DATA(p2) + sizeof(raw_ipv4)); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = (uint8_t *)GET_PKT_DATA(p2) + sizeof(raw_ipv4) + 20; - p2->payload_len = 20; - p2->proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"|DE 01 03|\"; tcpv4-csum:invalid; dsize:20; " - "msg:\"tcpv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"|DE 01 03|\"; tcpv4-csum:valid; dsize:20; " - "msg:\"tcpv4-csum keyword check(2)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (!PacketAlertCheck(p1, 1)) { - printf("sig 1 didn't match on p1: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) { - printf("sig 2 matched on p2: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest28TCPV6Keyword(void) -{ - static uint8_t valid_raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, - - 0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x06, 0x40, - 0x3f, 0xfe, 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x00, 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, - 0x3f, 0xfe, 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, - 0x02, 0xc0, 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, - - 0x03, 0xfe, 0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, - 0x0c, 0x7a, 0x08, 0x77, 0x50, 0x10, 0x21, 0x5c, - 0xf2, 0xf1, 0x00, 0x00, - - 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, 0xca, 0x5a, - 0x00, 0x01, 0x69, 0x27}; - - static uint8_t invalid_raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, - - 0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x06, 0x40, - 0x3f, 0xfe, 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x00, 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, - 0x3f, 0xfe, 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, - 0x02, 0xc0, 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, - - 0x03, 0xfe, 0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, - 0x0c, 0x7a, 0x08, 0x77, 0x50, 0x10, 0x21, 0x5c, - 0xc2, 0xf1, 0x00, 0x00, - - 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, 0xca, 0x5a, - 0x00, 0x01, 0x69, 0x28}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); - p1->tcph = (TCPHdr *) (valid_raw_ipv6 + 54); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = valid_raw_ipv6 + 54 + 20; - p1->payload_len = 12; - p1->proto = IPPROTO_TCP; - - if (TCP_GET_HLEN(p1) != 20) { - BUG_ON(1); - } - - PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); - p2->tcph = (TCPHdr *) (invalid_raw_ipv6 + 54); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = invalid_raw_ipv6 + 54 + 20;; - p2->payload_len = 12; - p2->proto = IPPROTO_TCP; - - if (TCP_GET_HLEN(p2) != 20) { - BUG_ON(1); - } - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"|00 01 69|\"; tcpv6-csum:valid; dsize:12; " - "msg:\"tcpv6-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"|00 01 69|\"; tcpv6-csum:invalid; dsize:12; " - "msg:\"tcpv6-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (!(PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match on p1: "); - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 2))) { - printf("sid 2 didn't match on p2: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest29NegativeTCPV6Keyword(void) -{ - static uint8_t valid_raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, - - 0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x06, 0x40, - 0x3f, 0xfe, 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x00, 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, - 0x3f, 0xfe, 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, - 0x02, 0xc0, 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, - - 0x03, 0xfe, 0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, - 0x0c, 0x7a, 0x08, 0x77, 0x50, 0x10, 0x21, 0x5c, - 0xf2, 0xf1, 0x00, 0x00, - - 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, 0xca, 0x5a, - 0x00, 0x01, 0x69, 0x27}; - - static uint8_t invalid_raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, - - 0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x06, 0x40, - 0x3f, 0xfe, 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x00, 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, - 0x3f, 0xfe, 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, - 0x02, 0xc0, 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, - - 0x03, 0xfe, 0x00, 0x16, 0xd6, 0x76, 0xf5, 0x2d, - 0x0c, 0x7a, 0x08, 0x77, 0x50, 0x10, 0x21, 0x5c, - 0xc2, 0xf1, 0x00, 0x00, - - 0x01, 0x01, 0x08, 0x0a, 0x00, 0x08, 0xca, 0x5a, - 0x00, 0x01, 0x69, 0x28}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); - p1->tcph = (TCPHdr *) (valid_raw_ipv6 + 54); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = valid_raw_ipv6 + 54 + 20; - p1->payload_len = 12; - p1->proto = IPPROTO_TCP; - - if (TCP_GET_HLEN(p1) != 20) { - BUG_ON(1); - } - - PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); - p2->tcph = (TCPHdr *) (invalid_raw_ipv6 + 54); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = invalid_raw_ipv6 + 54 + 20;; - p2->payload_len = 12; - p2->proto = IPPROTO_TCP; - - if (TCP_GET_HLEN(p2) != 20) { - BUG_ON(1); - } - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"|00 01 69|\"; tcpv6-csum:invalid; dsize:12; " - "msg:\"tcpv6-csum keyword check(1)\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"|00 01 69|\"; tcpv6-csum:valid; dsize:12; " - "msg:\"tcpv6-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - goto end; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - goto end; - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest30UDPV4Keyword(void) -{ - uint8_t raw_ipv4[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x11, 0x00, 0x00, 0xd0, 0x43, 0xdc, 0xdc, - 0xc0, 0xa8, 0x01, 0x03}; - - uint8_t valid_raw_udp[] = { - 0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0, - 0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67, - 0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63, - 0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, - 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b, - 0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65, - 0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0xc0, 0x26}; - - uint8_t invalid_raw_udp[] = { - 0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0, - 0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67, - 0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63, - 0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, - 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b, - 0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65, - 0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0xc0, 0x27}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP/1.0yyyyyyyyyyyyyyyy\r\n" - "\r\n\r\nyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip4h = (IPV4Hdr *)raw_ipv4; - p1->udph = (UDPHdr *)valid_raw_udp; - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = sizeof(valid_raw_udp) - UDP_HEADER_LEN; - p1->proto = IPPROTO_UDP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip4h = (IPV4Hdr *)raw_ipv4; - p2->udph = (UDPHdr *)invalid_raw_udp; - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = sizeof(invalid_raw_udp) - UDP_HEADER_LEN; - p2->proto = IPPROTO_UDP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(content:\"/one/\"; udpv4-csum:valid; " - "msg:\"udpv4-csum keyword check(1)\"; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert udp any any -> any any " - "(content:\"/one/\"; udpv4-csum:invalid; " - "msg:\"udpv4-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 1; - else - result &= 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 1; - else - result &= 0; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest31NegativeUDPV4Keyword(void) -{ - uint8_t raw_ipv4[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd0, 0x43, 0xdc, 0xdc, - 0xc0, 0xa8, 0x01, 0x03}; - - uint8_t valid_raw_udp[] = { - 0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0, - 0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67, - 0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63, - 0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, - 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b, - 0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65, - 0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0xc0, 0x26}; - - uint8_t invalid_raw_udp[] = { - 0x00, 0x35, 0xcf, 0x34, 0x00, 0x55, 0x6c, 0xe0, - 0x83, 0xfc, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x61, 0x67, - 0x65, 0x61, 0x64, 0x32, 0x11, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x73, 0x79, 0x6e, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x03, 0x63, - 0x6f, 0x6d, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, - 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x4b, - 0x50, 0x00, 0x12, 0x06, 0x70, 0x61, 0x67, 0x65, - 0x61, 0x64, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0xc0, 0x27}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP/1.0yyyyyyyyyyyyyyyy\r\n" - "\r\n\r\nyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip4h = (IPV4Hdr *)raw_ipv4; - p1->udph = (UDPHdr *)valid_raw_udp; - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = sizeof(valid_raw_udp) - UDP_HEADER_LEN; - p1->proto = IPPROTO_UDP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip4h = (IPV4Hdr *)raw_ipv4; - p2->udph = (UDPHdr *)invalid_raw_udp; - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = sizeof(invalid_raw_udp) - UDP_HEADER_LEN; - p2->proto = IPPROTO_UDP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(content:\"/one/\"; udpv4-csum:invalid; " - "msg:\"udpv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert udp any any -> any any " - "(content:\"/one/\"; udpv4-csum:valid; " - "msg:\"udpv4-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 0; - else - result &= 1; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) { - result &= 0; - } - else - result &= 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p1); - SCFree(p2); - return result; -} - - -int SigTest32UDPV6Keyword(void) -{ - static uint8_t valid_raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0, - 0x09, 0x00}; - - static uint8_t invalid_raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0, - 0x09, 0x01}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP\r\n" - "\r\n\r\n"; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); - p1->udph = (UDPHdr *) (valid_raw_ipv6 + 54); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = IPV6_GET_PLEN((p1)) - UDP_HEADER_LEN; - p1->proto = IPPROTO_UDP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); - p2->udph = (UDPHdr *) (invalid_raw_ipv6 + 54); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = IPV6_GET_PLEN((p2)) - UDP_HEADER_LEN; - p2->proto = IPPROTO_UDP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(content:\"/one/\"; udpv6-csum:valid; " - "msg:\"udpv6-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert udp any any -> any any " - "(content:\"/one/\"; udpv6-csum:invalid; " - "msg:\"udpv6-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 1; - else - result &= 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 1; - else - result &= 0; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest33NegativeUDPV6Keyword(void) -{ - static uint8_t valid_raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0, - 0x09, 0x00}; - - static uint8_t invalid_raw_ipv6[] = { - 0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, - 0x86, 0x05, 0x80, 0xda, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x02, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0xa0, 0x00, 0x14, 0x1a, 0xc3, 0x06, 0x02, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0x57, 0xb0, - 0x09, 0x01}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP\r\n" - "\r\n\r\n"; - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); - p1->udph = (UDPHdr *) (valid_raw_ipv6 + 54); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = IPV6_GET_PLEN((p1)) - UDP_HEADER_LEN; - p1->proto = IPPROTO_UDP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); - p2->udph = (UDPHdr *) (invalid_raw_ipv6 + 54); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = IPV6_GET_PLEN((p2)) - UDP_HEADER_LEN; - p2->proto = IPPROTO_UDP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert udp any any -> any any " - "(content:\"/one/\"; udpv6-csum:invalid; " - "msg:\"udpv6-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert udp any any -> any any " - "(content:\"/one/\"; udpv6-csum:valid; " - "msg:\"udpv6-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 0; - else - result &= 1; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 0; - else - result &= 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest34ICMPV4Keyword(void) -{ - uint8_t valid_raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0x3c, 0xa7, 0x7f, 0x00, 0x00, 0x01, - 0x7f, 0x00, 0x00, 0x01, 0x08, 0x00, 0xc3, 0x01, - 0x2b, 0x36, 0x00, 0x01, 0x3f, 0x16, 0x9a, 0x4a, - 0x41, 0x63, 0x04, 0x00, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37}; - - uint8_t invalid_raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0x3c, 0xa7, 0x7f, 0x00, 0x00, 0x01, - 0x7f, 0x00, 0x00, 0x01, 0x08, 0x00, 0xc3, 0x01, - 0x2b, 0x36, 0x00, 0x01, 0x3f, 0x16, 0x9a, 0x4a, - 0x41, 0x63, 0x04, 0x00, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x38}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip4h = (IPV4Hdr *)(valid_raw_ipv4); - p1->ip4h->ip_verhl = 69; - p1->icmpv4h = (ICMPV4Hdr *) (valid_raw_ipv4 + IPV4_GET_RAW_HLEN(p1->ip4h) * 4); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = buflen; - p1->proto = IPPROTO_ICMP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip4h = (IPV4Hdr *)(invalid_raw_ipv4); - p2->ip4h->ip_verhl = 69; - p2->icmpv4h = (ICMPV4Hdr *) (invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(p2->ip4h) * 4); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = buflen; - p2->proto = IPPROTO_ICMP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert icmp any any -> any any " - "(content:\"/one/\"; icmpv4-csum:valid; " - "msg:\"icmpv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert icmp any any -> any any " - "(content:\"/one/\"; icmpv4-csum:invalid; " - "msg:\"icmpv4-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 1; - else - result &= 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 1; - else - result &= 0; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest35NegativeICMPV4Keyword(void) -{ - uint8_t valid_raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0x3c, 0xa7, 0x7f, 0x00, 0x00, 0x01, - 0x7f, 0x00, 0x00, 0x01, 0x08, 0x00, 0xc3, 0x01, - 0x2b, 0x36, 0x00, 0x01, 0x3f, 0x16, 0x9a, 0x4a, - 0x41, 0x63, 0x04, 0x00, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37}; - - uint8_t invalid_raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, - 0x40, 0x01, 0x3c, 0xa7, 0x7f, 0x00, 0x00, 0x01, - 0x7f, 0x00, 0x00, 0x01, 0x08, 0x00, 0xc3, 0x01, - 0x2b, 0x36, 0x00, 0x01, 0x3f, 0x16, 0x9a, 0x4a, - 0x41, 0x63, 0x04, 0x00, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x38}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip4h = (IPV4Hdr *)(valid_raw_ipv4); - p1->ip4h->ip_verhl = 69; - p1->icmpv4h = (ICMPV4Hdr *) (valid_raw_ipv4 + IPV4_GET_RAW_HLEN(p1->ip4h) * 4); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = buflen; - p1->proto = IPPROTO_ICMP; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip4h = (IPV4Hdr *)(invalid_raw_ipv4); - p2->ip4h->ip_verhl = 69; - p2->icmpv4h = (ICMPV4Hdr *) (invalid_raw_ipv4 + IPV4_GET_RAW_HLEN(p2->ip4h) * 4); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = buflen; - p2->proto = IPPROTO_ICMP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert icmp any any -> any any " - "(content:\"/one/\"; icmpv4-csum:invalid; " - "msg:\"icmpv4-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert icmp any any -> any any " - "(content:\"/one/\"; icmpv4-csum:valid; " - "msg:\"icmpv4-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 0; - else - result &= 1; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 0; - else { - result &= 1; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest36ICMPV6Keyword(void) -{ - uint8_t valid_raw_ipv6[] = { - 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60, - 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60, - 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00, - 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed, - 0x08, 0x00}; - - uint8_t invalid_raw_ipv6[] = { - 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60, - 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60, - 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00, - 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed, - 0x08, 0x01}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); - p1->icmpv6h = (ICMPV6Hdr *) (valid_raw_ipv6 + 54); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = buflen; - p1->proto = IPPROTO_ICMPV6; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); - p2->icmpv6h = (ICMPV6Hdr *) (invalid_raw_ipv6 + 54); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = buflen; - p2->proto = IPPROTO_ICMPV6; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert icmpv6 any any -> any any " - "(content:\"/one/\"; icmpv6-csum:valid; " - "msg:\"icmpv6-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert icmpv6 any any -> any any " - "(content:\"/one/\"; icmpv6-csum:invalid; " - "msg:\"icmpv6-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 1; - else - result &= 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 1; - else - result &= 0; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest37NegativeICMPV6Keyword(void) -{ - uint8_t valid_raw_ipv6[] = { - 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60, - 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60, - 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00, - 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed, - 0x08, 0x00}; - - uint8_t invalid_raw_ipv6[] = { - 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60, - 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60, - 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00, - 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, - 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe, - 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe, - 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0, - 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75, - 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01, - 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed, - 0x08, 0x01}; - - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - Packet *p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) { - SCFree(p1); - return 0; - } - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - uint8_t *buf = (uint8_t *)"GET /one/ HTTP/1.0\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - memset(p2, 0, SIZE_OF_PACKET); - - PACKET_RESET_CHECKSUMS(p1); - p1->ip6h = (IPV6Hdr *)(valid_raw_ipv6 + 14); - p1->icmpv6h = (ICMPV6Hdr *) (valid_raw_ipv6 + 54); - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = buf; - p1->payload_len = buflen; - p1->proto = IPPROTO_ICMPV6; - - PACKET_RESET_CHECKSUMS(p2); - p2->ip6h = (IPV6Hdr *)(invalid_raw_ipv6 + 14); - p2->icmpv6h = (ICMPV6Hdr *) (invalid_raw_ipv6 + 54); - p2->src.family = AF_INET; - p2->dst.family = AF_INET; - p2->payload = buf; - p2->payload_len = buflen; - p2->proto = IPPROTO_ICMPV6; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert icmpv6 any any -> any any " - "(content:\"/one/\"; icmpv6-csum:invalid; " - "msg:\"icmpv6-csum keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx, - "alert icmpv6 any any -> any any " - "(content:\"/one/\"; icmpv6-csum:valid; " - "msg:\"icmpv6-csum keyword check(1)\"; " - "sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) - result &= 0; - else - result &= 1; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (PacketAlertCheck(p2, 2)) - result &= 0; - else - result &= 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p1); - SCFree(p2); - return result; -} - -int SigTest38Real(int mpm_type) -{ - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - uint8_t raw_eth[] = { - 0x00, 0x00, 0x03, 0x04, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00 - }; - uint8_t raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x7d, 0xd8, 0xf3, 0x40, 0x00, - 0x40, 0x06, 0x63, 0x85, 0x7f, 0x00, 0x00, 0x01, - 0x7f, 0x00, 0x00, 0x01 - }; - uint8_t raw_tcp[] = { - 0xad, 0x22, 0x04, 0x00, 0x16, 0x39, 0x72, - 0xe2, 0x16, 0x1f, 0x79, 0x84, 0x80, 0x18, - 0x01, 0x01, 0xfe, 0x71, 0x00, 0x00, 0x01, - 0x01, 0x08, 0x0a, 0x00, 0x22, 0xaa, 0x10, - 0x00, 0x22, 0xaa, 0x10 - }; - uint8_t buf[] = { - 0x00, 0x00, 0x00, 0x08, 0x62, 0x6f, 0x6f, 0x65, - 0x65, 0x6b, 0x0d, 0x0a, 0x4c, 0x45, 0x4e, 0x31, - 0x20, 0x38, 0x0d, 0x0a, 0x66, 0x6f, 0x30, 0x30, /* LEN1|20| ends at 17 */ - 0x30, 0x38, 0x0d, 0x0a, 0x4c, 0x45, 0x4e, 0x32, /* "0008" at offset 5 */ - 0x20, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, - 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, - 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, - 0x39, 0x39, 0x39, 0x0d, 0x0a, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, - 0x0a - }; - uint16_t ethlen = sizeof(raw_eth); - uint16_t ipv4len = sizeof(raw_ipv4); - uint16_t tcplen = sizeof(raw_tcp); - uint16_t buflen = sizeof(buf); - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - - /* Copy raw data into packet */ - if (PacketCopyData(p1, raw_eth, ethlen) == -1) { - SCFree(p1); - return 1; - } - if (PacketCopyDataOffset(p1, ethlen, raw_ipv4, ipv4len) == -1) { - SCFree(p1); - return 1; - } - if (PacketCopyDataOffset(p1, ethlen + ipv4len, raw_tcp, tcplen) == -1) { - SCFree(p1); - return 1; - } - if (PacketCopyDataOffset(p1, ethlen + ipv4len + tcplen, buf, buflen) == -1) { - SCFree(p1); - return 1; - } - SET_PKT_LEN(p1, ethlen + ipv4len + tcplen + buflen); - - PACKET_RESET_CHECKSUMS(p1); - p1->ethh = (EthernetHdr *)raw_eth; - p1->ip4h = (IPV4Hdr *)raw_ipv4; - p1->tcph = (TCPHdr *)raw_tcp; - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = GET_PKT_DATA(p1) + ethlen + ipv4len + tcplen; - p1->payload_len = buflen; - p1->proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"LEN1|20|\"; " - "byte_test:4,=,8,0; " - "msg:\"byte_test keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"LEN1|20|\"; " - "byte_test:4,=,8,5,relative,string,dec; " - "msg:\"byte_test keyword check(2)\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) { - result = 1; - } else { - result = 0; - printf("sid 1 didn't alert, but should have: "); - goto cleanup; - } - if (PacketAlertCheck(p1, 2)) { - result = 1; - } else { - result = 0; - printf("sid 2 didn't alert, but should have: "); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - SCFree(p1); - return result; -} -static int SigTest38B2g (void) -{ - return SigTest38Real(MPM_B2G); -} -static int SigTest38B3g (void) -{ - return SigTest38Real(MPM_B3G); -} -static int SigTest38Wm (void) -{ - return SigTest38Real(MPM_WUMANBER); -} - -int SigTest39Real(int mpm_type) -{ - Packet *p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - uint8_t raw_eth[] = { - 0x00, 0x00, 0x03, 0x04, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00 - }; - uint8_t raw_ipv4[] = { - 0x45, 0x00, 0x00, 0x7d, 0xd8, 0xf3, 0x40, 0x00, - 0x40, 0x06, 0x63, 0x85, 0x7f, 0x00, 0x00, 0x01, - 0x7f, 0x00, 0x00, 0x01 - }; - uint8_t raw_tcp[] = { - 0xad, 0x22, 0x04, 0x00, 0x16, 0x39, 0x72, - 0xe2, 0x16, 0x1f, 0x79, 0x84, 0x80, 0x18, - 0x01, 0x01, 0xfe, 0x71, 0x00, 0x00, 0x01, - 0x01, 0x08, 0x0a, 0x00, 0x22, 0xaa, 0x10, - 0x00, 0x22, 0xaa, 0x10 - }; - uint8_t buf[] = { - 0x00, 0x00, 0x00, 0x08, 0x62, 0x6f, 0x6f, 0x65, - 0x65, 0x6b, 0x0d, 0x0a, 0x4c, 0x45, 0x4e, 0x31, - 0x20, 0x38, 0x0d, 0x0a, 0x66, 0x30, 0x30, 0x30, - 0x38, 0x72, 0x0d, 0x0a, 0x4c, 0x45, 0x4e, 0x32, - 0x20, 0x39, 0x39, 0x4c, 0x45, 0x4e, 0x32, 0x39, - 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, - 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, - 0x39, 0x39, 0x39, 0x0d, 0x0a, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, - 0x0a - }; - uint16_t ethlen = sizeof(raw_eth); - uint16_t ipv4len = sizeof(raw_ipv4); - uint16_t tcplen = sizeof(raw_tcp); - uint16_t buflen = sizeof(buf); - - memset(&th_v, 0, sizeof(ThreadVars)); - memset(p1, 0, SIZE_OF_PACKET); - - /* Copy raw data into packet */ - if (PacketCopyData(p1, raw_eth, ethlen) == -1) { - SCFree(p1); - return 1; - } - if (PacketCopyDataOffset(p1, ethlen, raw_ipv4, ipv4len) == -1) { - SCFree(p1); - return 1; - } - if (PacketCopyDataOffset(p1, ethlen + ipv4len, raw_tcp, tcplen) == -1) { - SCFree(p1); - return 1; - } - if (PacketCopyDataOffset(p1, ethlen + ipv4len + tcplen, buf, buflen) == -1) { - SCFree(p1); - return 1; - } - SET_PKT_LEN(p1, ethlen + ipv4len + tcplen + buflen); - - PACKET_RESET_CHECKSUMS(p1); - p1->ethh = (EthernetHdr *)raw_eth; - p1->ip4h = (IPV4Hdr *)raw_ipv4; - p1->tcph = (TCPHdr *)raw_tcp; - p1->src.family = AF_INET; - p1->dst.family = AF_INET; - p1->payload = GET_PKT_DATA(p1) + ethlen + ipv4len + tcplen; - p1->payload_len = buflen; - p1->proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"LEN1|20|\"; " - "byte_test:4,=,8,0; " - "byte_jump:4,0; " - "byte_test:6,=,0x4c454e312038,0,relative; " - "msg:\"byte_jump keyword check(1)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result &= 0; - goto end; - } - // XXX TODO - de_ctx->sig_list->next = SigInit(de_ctx, - "alert tcp any any -> any any " - "(content:\"LEN1|20|\"; " - "byte_test:4,=,8,4,relative,string,dec; " - "byte_jump:4,4,relative,string,dec,post_offset 2; " - "byte_test:4,=,0x4c454e32,0,relative; " - "msg:\"byte_jump keyword check(2)\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result &= 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (PacketAlertCheck(p1, 1)) { - result = 1; - } else { - result = 0; - printf("sid 1 didn't alert, but should have: "); - goto cleanup; - } - if (PacketAlertCheck(p1, 2)) { - result = 1; - } else { - result = 0; - printf("sid 2 didn't alert, but should have: "); - goto cleanup; - } - -cleanup: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -end: - SCFree(p1); - return result; -} -static int SigTest39B2g (void) -{ - return SigTest39Real(MPM_B2G); -} -static int SigTest39B3g (void) -{ - return SigTest39Real(MPM_B3G); -} -static int SigTest39Wm (void) -{ - return SigTest39Real(MPM_WUMANBER); -} - - - -/** - * \test SigTest36ContentAndIsdataatKeywords01 is a test to check window with constructed packets, - * \brief expecting to match a size - */ - -int SigTest36ContentAndIsdataatKeywords01Real (int mpm_type) -{ - int result = 0; - - // Buid and decode the packet - - uint8_t raw_eth [] = { - 0x00,0x25,0x00,0x9e,0xfa,0xfe,0x00,0x02,0xcf,0x74,0xfe,0xe1,0x08,0x00,0x45,0x00 - ,0x01,0xcc,0xcb,0x91,0x00,0x00,0x34,0x06,0xdf,0xa8,0xd1,0x55,0xe3,0x67,0xc0,0xa8 - ,0x64,0x8c,0x00,0x50,0xc0,0xb7,0xd1,0x11,0xed,0x63,0x81,0xa9,0x9a,0x05,0x80,0x18 - ,0x00,0x75,0x0a,0xdd,0x00,0x00,0x01,0x01,0x08,0x0a,0x09,0x8a,0x06,0xd0,0x12,0x21 - ,0x2a,0x3b,0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x33,0x30,0x32,0x20,0x46 - ,0x6f,0x75,0x6e,0x64,0x0d,0x0a,0x4c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3a,0x20 - ,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x67,0x6f,0x6f,0x67,0x6c - ,0x65,0x2e,0x65,0x73,0x2f,0x0d,0x0a,0x43,0x61,0x63,0x68,0x65,0x2d,0x43,0x6f,0x6e - ,0x74,0x72,0x6f,0x6c,0x3a,0x20,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x0d,0x0a,0x43 - ,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,0x78 - ,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x3b,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d - ,0x55,0x54,0x46,0x2d,0x38,0x0d,0x0a,0x44,0x61,0x74,0x65,0x3a,0x20,0x4d,0x6f,0x6e - ,0x2c,0x20,0x31,0x34,0x20,0x53,0x65,0x70,0x20,0x32,0x30,0x30,0x39,0x20,0x30,0x38 - ,0x3a,0x34,0x38,0x3a,0x33,0x31,0x20,0x47,0x4d,0x54,0x0d,0x0a,0x53,0x65,0x72,0x76 - ,0x65,0x72,0x3a,0x20,0x67,0x77,0x73,0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74 - ,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,0x32,0x31,0x38,0x0d,0x0a,0x0d,0x0a - ,0x3c,0x48,0x54,0x4d,0x4c,0x3e,0x3c,0x48,0x45,0x41,0x44,0x3e,0x3c,0x6d,0x65,0x74 - ,0x61,0x20,0x68,0x74,0x74,0x70,0x2d,0x65,0x71,0x75,0x69,0x76,0x3d,0x22,0x63,0x6f - ,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x22,0x20,0x63,0x6f,0x6e,0x74 - ,0x65,0x6e,0x74,0x3d,0x22,0x74,0x65,0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x3b,0x63 - ,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x75,0x74,0x66,0x2d,0x38,0x22,0x3e,0x0a,0x3c - ,0x54,0x49,0x54,0x4c,0x45,0x3e,0x33,0x30,0x32,0x20,0x4d,0x6f,0x76,0x65,0x64,0x3c - ,0x2f,0x54,0x49,0x54,0x4c,0x45,0x3e,0x3c,0x2f,0x48,0x45,0x41,0x44,0x3e,0x3c,0x42 - ,0x4f,0x44,0x59,0x3e,0x0a,0x3c,0x48,0x31,0x3e,0x33,0x30,0x32,0x20,0x4d,0x6f,0x76 - ,0x65,0x64,0x3c,0x2f,0x48,0x31,0x3e,0x0a,0x54,0x68,0x65,0x20,0x64,0x6f,0x63,0x75 - ,0x6d,0x65,0x6e,0x74,0x20,0x68,0x61,0x73,0x20,0x6d,0x6f,0x76,0x65,0x64,0x0a,0x3c - ,0x41,0x20,0x48,0x52,0x45,0x46,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77 - ,0x77,0x77,0x2e,0x67,0x6f,0x6f,0x67,0x6c,0x65,0x2e,0x65,0x73,0x2f,0x22,0x3e,0x68 - ,0x65,0x72,0x65,0x3c,0x2f,0x41,0x3e,0x2e,0x0d,0x0a,0x3c,0x2f,0x42,0x4f,0x44,0x59 - ,0x3e,0x3c,0x2f,0x48,0x54,0x4d,0x4c,0x3e,0x0d,0x0a }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - DecodeThreadVars dtv; - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - FlowInitConfig(FLOW_QUIET); - DecodeEthernet(&th_v, &dtv, p, raw_eth, sizeof(raw_eth), NULL); - - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest36ContentAndIsdataatKeywords01 \"; content:\"HTTP\"; isdataat:404, relative; sid:101;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 101) == 0) { - result = 0; - goto end; - } else { - result=1; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); - DetectEngineCtxFree(de_ctx); - PACKET_RECYCLE(p); - FlowShutdown(); - - SCFree(p); - return result; - -end: - if(de_ctx) - { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if(det_ctx) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - //PatternMatchDestroy(mpm_ctx); - - if(de_ctx) - DetectEngineCtxFree(de_ctx); - - if (p != NULL) - PACKET_RECYCLE(p); - - FlowShutdown(); - - SCFree(p); - return result; -} - - -/** - * \test SigTest37ContentAndIsdataatKeywords02 is a test to check window with constructed packets, - * \brief not expecting to match a size - */ - -int SigTest37ContentAndIsdataatKeywords02Real (int mpm_type) -{ - int result = 0; - - // Buid and decode the packet - - uint8_t raw_eth [] = { - 0x00,0x25,0x00,0x9e,0xfa,0xfe,0x00,0x02,0xcf,0x74,0xfe,0xe1,0x08,0x00,0x45,0x00 - ,0x01,0xcc,0xcb,0x91,0x00,0x00,0x34,0x06,0xdf,0xa8,0xd1,0x55,0xe3,0x67,0xc0,0xa8 - ,0x64,0x8c,0x00,0x50,0xc0,0xb7,0xd1,0x11,0xed,0x63,0x81,0xa9,0x9a,0x05,0x80,0x18 - ,0x00,0x75,0x0a,0xdd,0x00,0x00,0x01,0x01,0x08,0x0a,0x09,0x8a,0x06,0xd0,0x12,0x21 - ,0x2a,0x3b,0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x33,0x30,0x32,0x20,0x46 - ,0x6f,0x75,0x6e,0x64,0x0d,0x0a,0x4c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x3a,0x20 - ,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x67,0x6f,0x6f,0x67,0x6c - ,0x65,0x2e,0x65,0x73,0x2f,0x0d,0x0a,0x43,0x61,0x63,0x68,0x65,0x2d,0x43,0x6f,0x6e - ,0x74,0x72,0x6f,0x6c,0x3a,0x20,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x0d,0x0a,0x43 - ,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,0x78 - ,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x3b,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d - ,0x55,0x54,0x46,0x2d,0x38,0x0d,0x0a,0x44,0x61,0x74,0x65,0x3a,0x20,0x4d,0x6f,0x6e - ,0x2c,0x20,0x31,0x34,0x20,0x53,0x65,0x70,0x20,0x32,0x30,0x30,0x39,0x20,0x30,0x38 - ,0x3a,0x34,0x38,0x3a,0x33,0x31,0x20,0x47,0x4d,0x54,0x0d,0x0a,0x53,0x65,0x72,0x76 - ,0x65,0x72,0x3a,0x20,0x67,0x77,0x73,0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74 - ,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,0x32,0x31,0x38,0x0d,0x0a,0x0d,0x0a - ,0x3c,0x48,0x54,0x4d,0x4c,0x3e,0x3c,0x48,0x45,0x41,0x44,0x3e,0x3c,0x6d,0x65,0x74 - ,0x61,0x20,0x68,0x74,0x74,0x70,0x2d,0x65,0x71,0x75,0x69,0x76,0x3d,0x22,0x63,0x6f - ,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x22,0x20,0x63,0x6f,0x6e,0x74 - ,0x65,0x6e,0x74,0x3d,0x22,0x74,0x65,0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x3b,0x63 - ,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x75,0x74,0x66,0x2d,0x38,0x22,0x3e,0x0a,0x3c - ,0x54,0x49,0x54,0x4c,0x45,0x3e,0x33,0x30,0x32,0x20,0x4d,0x6f,0x76,0x65,0x64,0x3c - ,0x2f,0x54,0x49,0x54,0x4c,0x45,0x3e,0x3c,0x2f,0x48,0x45,0x41,0x44,0x3e,0x3c,0x42 - ,0x4f,0x44,0x59,0x3e,0x0a,0x3c,0x48,0x31,0x3e,0x33,0x30,0x32,0x20,0x4d,0x6f,0x76 - ,0x65,0x64,0x3c,0x2f,0x48,0x31,0x3e,0x0a,0x54,0x68,0x65,0x20,0x64,0x6f,0x63,0x75 - ,0x6d,0x65,0x6e,0x74,0x20,0x68,0x61,0x73,0x20,0x6d,0x6f,0x76,0x65,0x64,0x0a,0x3c - ,0x41,0x20,0x48,0x52,0x45,0x46,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77 - ,0x77,0x77,0x2e,0x67,0x6f,0x6f,0x67,0x6c,0x65,0x2e,0x65,0x73,0x2f,0x22,0x3e,0x68 - ,0x65,0x72,0x65,0x3c,0x2f,0x41,0x3e,0x2e,0x0d,0x0a,0x3c,0x2f,0x42,0x4f,0x44,0x59 - ,0x3e,0x3c,0x2f,0x48,0x54,0x4d,0x4c,0x3e,0x0d,0x0a }; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - DecodeThreadVars dtv; - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(p, 0, SIZE_OF_PACKET); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - FlowInitConfig(FLOW_QUIET); - DecodeEthernet(&th_v, &dtv, p, raw_eth, sizeof(raw_eth), NULL); - - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - Signature *s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest37ContentAndIsdataatKeywords01 \"; content:\"HTTP\"; isdataat:500, relative; sid:101;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - result = 0; - goto end; - } - - if (s->sm_lists[DETECT_SM_LIST_PMATCH]->type != DETECT_CONTENT) { - printf("type not content: "); - goto end; - } -/* - if (s->sm_lists[DETECT_SM_LIST_PMATCH]->next == NULL) { - printf("s->sm_lists[DETECT_SM_LIST_PMATCH]->next == NULL: "); - goto end; - } - if (s->sm_lists[DETECT_SM_LIST_PMATCH]->next->type != DETECT_ISDATAAT) { - printf("type not isdataat: "); - goto end; - } -*/ - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 101) == 0) { - result = 1; - goto end; - } else { - printf("sig matched, but should not have: "); - result=0; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - PACKET_RECYCLE(p); - FlowShutdown(); - - SCFree(p); - return result; - -end: - if(de_ctx) - { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if(det_ctx) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if(de_ctx) - DetectEngineCtxFree(de_ctx); - - if (p != NULL) - PACKET_RECYCLE(p); - - FlowShutdown(); - - SCFree(p); - return result; -} - - -// Wrapper functions to pass the mpm_type -static int SigTest36ContentAndIsdataatKeywords01B2g (void) -{ - return SigTest36ContentAndIsdataatKeywords01Real(MPM_B2G); -} -static int SigTest36ContentAndIsdataatKeywords01B3g (void) -{ - return SigTest36ContentAndIsdataatKeywords01Real(MPM_B3G); -} -static int SigTest36ContentAndIsdataatKeywords01Wm (void) -{ - return SigTest36ContentAndIsdataatKeywords01Real(MPM_WUMANBER); -} - -static int SigTest37ContentAndIsdataatKeywords02B2g (void) -{ - return SigTest37ContentAndIsdataatKeywords02Real(MPM_B2G); -} -static int SigTest37ContentAndIsdataatKeywords02B3g (void) -{ - return SigTest37ContentAndIsdataatKeywords02Real(MPM_B3G); -} -static int SigTest37ContentAndIsdataatKeywords02Wm (void) -{ - return SigTest37ContentAndIsdataatKeywords02Real(MPM_WUMANBER); -} - - -/** - * \test SigTest41NoPacketInspection is a test to check that when PKT_NOPACKET_INSPECTION - * flag is set, we don't need to inspect the packet protocol header or its contents. - */ - -int SigTest40NoPacketInspection01(void) -{ - - uint8_t *buf = (uint8_t *) - "220 (vsFTPd 2.0.5)\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - TCPHdr tcphdr; - if (unlikely(p == NULL)) - return 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - PacketQueue pq; - Flow f; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - memset(&pq, 0, sizeof(pq)); - memset(&f, 0, sizeof(f)); - memset(&tcphdr, 0, sizeof(tcphdr)); - - p->src.family = AF_INET; - p->src.addr_data32[0] = UTHSetIPv4Address("192.168.0.1"); - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4"); - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - p->dp = 34260; - p->sp = 21; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flags |= PKT_NOPACKET_INSPECTION; - p->tcph = &tcphdr; - p->flow = &f; - - FLOW_INITIALIZE(&f); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> 1.2.3.4 any (msg:\"No Packet Inspection Test\"; flow:to_server; sid:2; rev:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - det_ctx->de_ctx = de_ctx; - - Detect(&th_v, p, det_ctx, &pq, NULL); - if (PacketAlertCheck(p, 2)) - result = 0; - else - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p); - return result; -} - -/** - * \test SigTest42NoPayloadInspection is a test to check that when PKT_NOPAYLOAD_INSPECTION - * flasg is set, we don't need to inspect the packet contents. - */ - -int SigTest40NoPayloadInspection02(void) -{ - - uint8_t *buf = (uint8_t *) - "220 (vsFTPd 2.0.5)\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 1; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - p->flags |= PKT_NOPAYLOAD_INSPECTION; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - result = 0; - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"No Payload TEST\"; content:\"220 (vsFTPd 2.0.5)\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - if (!(de_ctx->sig_list->init_flags & SIG_FLAG_INIT_PAYLOAD)) - result = 0; - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) - result &= 0; - else - result &= 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - SCFree(p); - return result; -} - -static int SigTestMemory01 (void) -{ - uint8_t *buf = (uint8_t *) - "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n" - "\r\n\r\n" - "GET /two/ HTTP/1.1\r\n" - "Host: two.example.org\r\n" - "\r\n\r\n"; - uint16_t buflen = strlen((char *)buf); - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = buf; - p->payload_len = buflen; - p->proto = IPPROTO_TCP; - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - -printf("@pre cleanup\n\n"); - DetectSigGroupPrintMemory(); - DetectAddressPrintMemory(); - DetectPortPrintMemory(); - - SigGroupCleanup(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - -printf("@exit\n\n"); - DetectSigGroupPrintMemory(); - DetectAddressPrintMemory(); - DetectPortPrintMemory(); - - result = 1; -end: - SCFree(p); - return result; -} - -static int SigTestMemory02 (void) -{ - ThreadVars th_v; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 456 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any 1:1000 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - -printf("@cleanup\n\n"); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - -printf("@exit\n\n"); - DetectSigGroupPrintMemory(); - DetectAddressPrintMemory(); - DetectPortPrintMemory(); -printf("@exit\n\n"); - DetectSigGroupPrintMemory(); - DetectAddressPrintMemory(); - DetectPortPrintMemory(); - - result = 1; -end: - return result; -} - -static int SigTestMemory03 (void) -{ - ThreadVars th_v; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> 1.2.3.4 456 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> 1.2.3.3-1.2.3.6 1:1000 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next->next = SigInit(de_ctx,"alert tcp any any -> !1.2.3.5 1:990 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; sid:3;)"); - if (de_ctx->sig_list->next->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - -printf("@cleanup\n\n"); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - -printf("@exit\n\n"); - DetectSigGroupPrintMemory(); - DetectAddressPrintMemory(); - DetectPortPrintMemory(); - - result = 1; -end: - return result; -} - -static int SigTestSgh01 (void) -{ - ThreadVars th_v; - int result = 0; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&th_v, 0, sizeof(th_v)); - - Packet *p = NULL; - p = UTHBuildPacketSrcDstPorts((uint8_t *)"a", 1, IPPROTO_TCP, 12345, 80); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"1\"; content:\"one\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->num != 0) { - printf("internal id != 0: "); - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any 81 (msg:\"2\"; content:\"two\"; content:\"abcd\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->next->num != 1) { - printf("internal id != 1: "); - goto end; - } - - de_ctx->sig_list->next->next = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"3\"; content:\"three\"; sid:3;)"); - if (de_ctx->sig_list->next->next == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->next->next->num != 2) { - printf("internal id != 2: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } -#if 0 - printf("-\n"); - printf("sgh->mpm_content_maxlen %u\n", sgh->mpm_content_maxlen); - printf("sgh->mpm_uricontent_maxlen %u\n", sgh->mpm_uricontent_maxlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); -#endif - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->match_array == NULL) { - printf("sgh->match_array == NULL: "); - goto end; - } - - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have (sgh->match_array[0] %p, expected %p): ", sgh->match_array[0], de_ctx->sig_list); - goto end; - } - if (sgh->match_array[1] != de_ctx->sig_list->next->next) { - printf("sgh doesn't contain sid 3, should have: "); - goto end; - } - - p->dp = 81; - - SigGroupHead *sgh2 = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh2 == NULL) { - printf("no sgh2: "); - goto end; - } -#if 0 - if (!(SigGroupHeadContainsSigId(de_ctx, sgh2, 1))) { - printf("sgh2 doesn't have sid 1: "); - goto end; - } -#endif - if (sgh2->sig_cnt != 1) { - printf("expected one sig, got %u in sgh2: ", sgh2->sig_cnt); - goto end; - } - - if (sgh2->match_array[0] != de_ctx->sig_list->next) { - printf("sgh doesn't contain sid 2, should have (sgh2->match_array[0] %p, expected %p): ", - sgh2->match_array[0], de_ctx->sig_list->next); - goto end; - } - -#if 0 - printf("-\n"); - printf("sgh2->mpm_content_minlen %u\n", sgh2->mpm_content_minlen); - printf("sgh2->mpm_uricontent_minlen %u\n", sgh2->mpm_uricontent_minlen); - printf("sgh2->sig_cnt %u\n", sgh2->sig_cnt); - printf("sgh2->sig_size %u\n", sgh2->sig_size); -#endif - if (sgh2->mpm_content_minlen != 4) { - printf("sgh2->mpm_content_minlen %u, expected 4: ", sgh2->mpm_content_minlen); - goto end; - } - - if (sgh2->match_array[0] != de_ctx->sig_list->next) { - printf("sgh2 doesn't contain sid 2, should have: "); - goto end; - } - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - - result = 1; -end: - return result; -} - -static int SigTestSgh02 (void) -{ - ThreadVars th_v; - int result = 0; - DetectEngineThreadCtx *det_ctx = NULL; - Packet *p = NULL; - p = UTHBuildPacketSrcDstPorts((uint8_t *)"a", 1, IPPROTO_TCP, 12345, 80); - - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80:82 (msg:\"1\"; content:\"one\"; content:\"1\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->num != 0) { - printf("internal id != 0: "); - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any 81 (msg:\"2\"; content:\"two2\"; content:\"abcdef\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->next->num != 1) { - printf("internal id != 1: "); - goto end; - } - de_ctx->sig_list->next->next = SigInit(de_ctx,"alert tcp any any -> any 80:81 (msg:\"3\"; content:\"three\"; content:\"abcdefgh\"; sid:3;)"); - if (de_ctx->sig_list->next->next == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->next->next->num != 2) { - printf("internal id != 2: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } - - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->match_array == NULL) { - printf("sgh->match_array == NULL: "); - goto end; - } - - if (sgh->sig_cnt != 2) { - printf("sgh sig cnt %u, expected 2: ", sgh->sig_cnt); - goto end; - } - - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have (sgh->match_array[0] %p, expected %p): ", sgh->match_array[0], de_ctx->sig_list); - goto end; - } - if (sgh->match_array[1] != de_ctx->sig_list->next->next) { - printf("sgh doesn't contain sid 3, should have: "); - goto end; - } -#if 0 - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - p->dp = 81; - - sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } - - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->sig_cnt != 3) { - printf("sgh sig cnt %u, expected 3: ", sgh->sig_cnt); - goto end; - } - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } - if (sgh->match_array[1] != de_ctx->sig_list->next) { - printf("sgh doesn't contain sid 2, should have: "); - goto end; - } - if (sgh->match_array[2] != de_ctx->sig_list->next->next) { - printf("sgh doesn't contain sid 3, should have: "); - goto end; - } -#if 0 - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - p->dp = 82; - - sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } - - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->sig_cnt != 1) { - printf("sgh sig cnt %u, expected 1: ", sgh->sig_cnt); - goto end; - } - - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } -#if 0 - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - p->src.family = AF_INET6; - p->dst.family = AF_INET6; - - sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } - - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->sig_cnt != 1) { - printf("sgh sig cnt %u, expected 1: ", sgh->sig_cnt); - goto end; - } - - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } -#if 0 - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - - result = 1; -end: - return result; -} - -static int SigTestSgh03 (void) -{ - ThreadVars th_v; - int result = 0; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload_len = 1; - p->proto = IPPROTO_TCP; - p->dp = 80; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4"); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> 1.2.3.4-1.2.3.6 any (msg:\"1\"; content:\"one\"; content:\"1\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->num != 0) { - printf("internal id != 0: "); - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx,"alert ip any any -> 1.2.3.5 any (msg:\"2\"; content:\"two2\"; content:\"abcdef\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->next->num != 1) { - printf("internal id != 1: "); - goto end; - } - de_ctx->sig_list->next->next = SigInit(de_ctx,"alert ip any any -> 1.2.3.4-1.2.3.5 any (msg:\"3\"; content:\"three\"; content:\"abcdefgh\"; sid:3;)"); - if (de_ctx->sig_list->next->next == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->next->next->num != 2) { - printf("internal id != 2: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } -#if 0 - printf("-\n"); - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->match_array == NULL) { - printf("sgh->match_array == NULL: "); - goto end; - } - - if (sgh->sig_cnt != 2) { - printf("sgh sig cnt %u, expected 2: ", sgh->sig_cnt); - goto end; - } - - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have (sgh->match_array[0] %p, expected %p): ", sgh->match_array[0], de_ctx->sig_list); - goto end; - } - if (sgh->match_array[1] != de_ctx->sig_list->next->next) { - printf("sgh doesn't contain sid 3, should have: "); - goto end; - } - - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.5"); - - sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } -#if 0 - printf("-\n"); - printf("sgh %p\n", sgh); - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - if (sgh->sig_cnt != 3) { - printf("sgh sig cnt %u, expected 3: ", sgh->sig_cnt); - goto end; - } - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } - if (sgh->match_array[1] != de_ctx->sig_list->next) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } - if (sgh->match_array[2] != de_ctx->sig_list->next->next) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } - - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3 (%x): ", sgh->mpm_content_minlen, p->dst.addr_data32[0]); - goto end; - } - - - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.6"); - - sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } -#if 0 - printf("-\n"); - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->sig_cnt != 1) { - printf("sgh sig cnt %u, expected 1: ", sgh->sig_cnt); - goto end; - } - - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - - result = 1; -end: - SCFree(p); - return result; -} - -static int SigTestSgh04 (void) -{ - ThreadVars th_v; - int result = 0; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload_len = 1; - p->proto = IPPROTO_TCP; - p->dp = 80; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4"); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> 1.2.3.4-1.2.3.6 any (msg:\"1\"; content:\"one\"; content:\"1\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->num != 0) { - printf("internal id != 0: "); - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx,"alert ip any any -> 1.2.3.5 any (msg:\"2\"; content:\"two2\"; content:\"abcdef\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->next->num != 1) { - printf("internal id != 1: "); - goto end; - } - de_ctx->sig_list->next->next = SigInit(de_ctx,"alert ip any any -> 1.2.3.4-1.2.3.5 any (msg:\"3\"; content:\"three\"; content:\"abcdefgh\"; sid:3;)"); - if (de_ctx->sig_list->next->next == NULL) { - result = 0; - goto end; - } - if (de_ctx->sig_list->next->next->num != 2) { - printf("internal id != 2: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } - - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->match_array == NULL) { - printf("sgh->match_array == NULL: "); - goto end; - } - - if (sgh->sig_cnt != 2) { - printf("sgh sig cnt %u, expected 2: ", sgh->sig_cnt); - goto end; - } - - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have (sgh->match_array[0] %p, expected %p): ", sgh->match_array[0], de_ctx->sig_list); - goto end; - } - if (sgh->match_array[1] != de_ctx->sig_list->next->next) { - printf("sgh doesn't contain sid 3, should have: "); - goto end; - } -#if 0 - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.5"); - - sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } - - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->sig_cnt != 3) { - printf("sgh sig cnt %u, expected 3: ", sgh->sig_cnt); - goto end; - } - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } - if (sgh->match_array[1] != de_ctx->sig_list->next) { - printf("sgh doesn't contain sid 2, should have: "); - goto end; - } - if (sgh->match_array[2] != de_ctx->sig_list->next->next) { - printf("sgh doesn't contain sid 3, should have: "); - goto end; - } -#if 0 - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.6"); - - sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } - - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->sig_cnt != 1) { - printf("sgh sig cnt %u, expected 1: ", sgh->sig_cnt); - goto end; - } - - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } -#if 0 - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - p->proto = IPPROTO_GRE; - - sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } -#if 0 - printf("-\n"); - printf("sgh->mpm_content_minlen %u\n", sgh->mpm_content_minlen); - printf("sgh->mpm_uricontent_minlen %u\n", sgh->mpm_uricontent_minlen); - printf("sgh->sig_cnt %u\n", sgh->sig_cnt); - printf("sgh->sig_size %u\n", sgh->sig_size); - printf("sgh->refcnt %u\n", sgh->refcnt); -#endif - if (sgh->mpm_content_minlen != 3) { - printf("sgh->mpm_content_minlen %u, expected 3: ", sgh->mpm_content_minlen); - goto end; - } - - if (sgh->match_array[0] != de_ctx->sig_list) { - printf("sgh doesn't contain sid 1, should have: "); - goto end; - } - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - - result = 1; -end: - SCFree(p); - return result; -} - -/** \test setting of mpm type */ -static int SigTestSgh05 (void) -{ - ThreadVars th_v; - int result = 0; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(th_v)); - memset(p, 0, SIZE_OF_PACKET); - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload_len = 1; - p->proto = IPPROTO_TCP; - p->dp = 80; - p->dst.addr_data32[0] = UTHSetIPv4Address("1.2.3.4"); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - de_ctx->mpm_matcher = MPM_WUMANBER; - - de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> 1.2.3.4-1.2.3.6 any (msg:\"1\"; content:\"one\"; content:\"1\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - printf("no sgh: "); - goto end; - } - - if (sgh->mpm_proto_tcp_ctx_ts != NULL || sgh->mpm_proto_tcp_ctx_tc != NULL || - sgh->mpm_proto_udp_ctx_ts != NULL || sgh->mpm_proto_udp_ctx_tc != NULL || - sgh->mpm_proto_other_ctx != NULL) { - printf("sgh->mpm_proto_tcp_ctx_ts != NULL || sgh->mpm_proto_tcp_ctx_tc != NULL" - "sgh->mpm_proto_udp_ctx_ts != NULL || sgh->mpm_proto_udp_ctx_tc != NULL" - "sgh->mpm_proto_other_ctx != NULL: "); - goto end; - } - - if (sgh->mpm_stream_ctx_ts == NULL || sgh->mpm_stream_ctx_tc == NULL) { - printf("sgh->mpm_stream_ctx == NULL || sgh->mpm_stream_ctx_tc == NULL: "); - goto end; - } - - if (sgh->mpm_stream_ctx_ts->mpm_type != MPM_WUMANBER) { - printf("sgh->mpm_type != MPM_WUMANBER, expected %d, got %d: ", MPM_WUMANBER, sgh->mpm_stream_ctx_ts->mpm_type); - goto end; - } - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - SigGroupCleanup(de_ctx); - DetectEngineCtxFree(de_ctx); - - result = 1; -end: - SCFree(p); - return result; -} - -static int SigTestContent01Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *)"01234567890123456789012345678901"; - uint16_t buflen = strlen((char *)buf); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - Packet *p = NULL; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Test 32\"; content:\"01234567890123456789012345678901\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) - result = 1; - else - printf("sig 1 didn't match: "); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTestContent01B2g (void) -{ - return SigTestContent01Real(MPM_B2G); -} -static int SigTestContent01B3g (void) -{ - return SigTestContent01Real(MPM_B3G); -} -static int SigTestContent01Wm (void) -{ - return SigTestContent01Real(MPM_WUMANBER); -} - -static int SigTestContent02Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *)"01234567890123456789012345678901"; - uint16_t buflen = strlen((char *)buf); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - Packet *p = NULL; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Test 32\"; content:\"01234567890123456789012345678901\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Test 31\"; content:\"0123456789012345678901234567890\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) { - if (PacketAlertCheck(p, 2)) { - result = 1; - } else - printf("sig 2 didn't match: "); - } - else - printf("sig 1 didn't match: "); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTestContent02B2g (void) -{ - return SigTestContent02Real(MPM_B2G); -} -static int SigTestContent02B3g (void) -{ - return SigTestContent02Real(MPM_B3G); -} -static int SigTestContent02Wm (void) -{ - return SigTestContent02Real(MPM_WUMANBER); -} - -static int SigTestContent03Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *)"01234567890123456789012345678901abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint16_t buflen = strlen((char *)buf); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - Packet *p = NULL; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Test 32\"; content:\"01234567890123456789012345678901\"; content:\"abcdefghijklmnopqrstuvwxyzABCDEF\"; distance:0; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) - result = 1; - else - printf("sig 1 didn't match: "); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTestContent03B2g (void) -{ - return SigTestContent03Real(MPM_B2G); -} -static int SigTestContent03B3g (void) -{ - return SigTestContent03Real(MPM_B3G); -} -static int SigTestContent03Wm (void) -{ - return SigTestContent03Real(MPM_WUMANBER); -} - -static int SigTestContent04Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *)"01234567890123456789012345678901abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint16_t buflen = strlen((char *)buf); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - Packet *p = NULL; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Test 32\"; content:\"01234567890123456789012345678901\"; content:\"abcdefghijklmnopqrstuvwxyzABCDEF\"; distance:0; within:32; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) - result = 1; - else - printf("sig 1 didn't match: "); - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTestContent04B2g (void) -{ - return SigTestContent04Real(MPM_B2G); -} -static int SigTestContent04B3g (void) -{ - return SigTestContent04Real(MPM_B3G); -} -static int SigTestContent04Wm (void) -{ - return SigTestContent04Real(MPM_WUMANBER); -} - -/** \test sigs with patterns at the limit of the pm's size limit */ -static int SigTestContent05Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *)"01234567890123456789012345678901PADabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint16_t buflen = strlen((char *)buf); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - Packet *p = NULL; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx == NULL: "); - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Test 32\"; content:\"01234567890123456789012345678901\"; content:\"abcdefghijklmnopqrstuvwxyzABCDEF\"; distance:0; within:32; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig1 parse failed: "); - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Test 32\"; content:\"01234567890123456789012345678901\"; content:\"abcdefghijklmnopqrstuvwxyzABCDEF\"; distance:1; within:32; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - printf("sig2 parse failed: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sig 1 matched but shouldn't: "); - goto end; - } - - if (PacketAlertCheck(p, 2)) { - printf("sig 2 matched but shouldn't: "); - goto end; - } - - result = 1; -end: - UTHFreePackets(&p, 1); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - return result; -} -static int SigTestContent05B2g (void) -{ - return SigTestContent05Real(MPM_B2G); -} -static int SigTestContent05B3g (void) -{ - return SigTestContent05Real(MPM_B3G); -} -static int SigTestContent05Wm (void) -{ - return SigTestContent05Real(MPM_WUMANBER); -} - -static int SigTestContent06Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *)"01234567890123456789012345678901abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint16_t buflen = strlen((char *)buf); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - Packet *p = NULL; - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Test 32 sig1\"; content:\"01234567890123456789012345678901\"; content:\"abcdefghijklmnopqrstuvwxyzABCDEF\"; distance:0; within:32; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - de_ctx->sig_list->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Test 32 sig2\"; content:\"01234567890123456789012345678901\"; content:\"abcdefg\"; sid:2;)"); - if (de_ctx->sig_list->next == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)){ - //printf("sig 1 matched :"); - }else{ - printf("sig 1 didn't match: "); - goto end; - } - - if (PacketAlertCheck(p, 2)){ - result = 1; - }else{ - printf("sig 2 didn't match: "); - goto end; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTestContent06B2g (void) -{ - return SigTestContent06Real(MPM_B2G); -} -static int SigTestContent06B3g (void) -{ - return SigTestContent06Real(MPM_B3G); -} -static int SigTestContent06Wm (void) -{ - return SigTestContent06Real(MPM_WUMANBER); -} - -static int SigTestWithinReal01 (int mpm_type) -{ - DecodeThreadVars dtv; - ThreadVars th_v; - int result = 0; - Packet *p1 = NULL; - Packet *p2 = NULL; - Packet *p3 = NULL; - Packet *p4 = NULL; - - uint8_t rawpkt1[] = { - 0x00,0x04,0x76,0xd3,0xd8,0x6a,0x00,0x24, - 0xe8,0x29,0xfa,0x4f,0x08,0x00,0x45,0x00, - 0x00,0x8c,0x95,0x50,0x00,0x00,0x40,0x06, - 0x2d,0x45,0xc0,0xa8,0x02,0x03,0xd0,0x45, - 0x24,0xe6,0x06,0xcc,0x03,0x09,0x18,0x72, - 0xd0,0xe3,0x1a,0xab,0x7c,0x98,0x50,0x00, - 0x02,0x00,0x46,0xa0,0x00,0x00,0x48,0x69, - 0x2c,0x20,0x74,0x68,0x69,0x73,0x20,0x69, - 0x73,0x20,0x61,0x20,0x62,0x69,0x67,0x20, - 0x74,0x65,0x73,0x74,0x20,0x74,0x6f,0x20, - 0x63,0x68,0x65,0x63,0x6b,0x20,0x63,0x6f, - 0x6e,0x74,0x65,0x6e,0x74,0x20,0x6d,0x61, - 0x74,0x63,0x68,0x65,0x73,0x0a,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00 }; /* end rawpkt1 */ - - uint8_t rawpkt2[] = { - 0x00,0x04,0x76,0xd3,0xd8,0x6a,0x00,0x24, - 0xe8,0x29,0xfa,0x4f,0x08,0x00,0x45,0x00, - 0x00,0x8c,0x30,0x87,0x00,0x00,0x40,0x06, - 0x92,0x0e,0xc0,0xa8,0x02,0x03,0xd0,0x45, - 0x24,0xe6,0x06,0xcd,0x03,0x09,0x73,0xec, - 0xd5,0x35,0x14,0x7d,0x7c,0x12,0x50,0x00, - 0x02,0x00,0xed,0x86,0x00,0x00,0x48,0x69, - 0x2c,0x20,0x74,0x68,0x69,0x73,0x20,0x69, - 0x73,0x20,0x61,0x20,0x62,0x69,0x67,0x20, - 0x74,0x65,0x73,0x74,0x20,0x74,0x6f,0x20, - 0x63,0x68,0x65,0x63,0x6b,0x20,0x63,0x6f, - 0x6e,0x74,0x65,0x6e,0x74,0x20,0x6d,0x61, - 0x74,0x63,0x68,0x65,0x73,0x0a,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00 }; /* end rawpkt2 */ - - uint8_t rawpkt3[] = { - 0x00,0x04,0x76,0xd3,0xd8,0x6a,0x00,0x24, - 0xe8,0x29,0xfa,0x4f,0x08,0x00,0x45,0x00, - 0x00,0x8c,0x57,0xd8,0x00,0x00,0x40,0x06, - 0x6a,0xbd,0xc0,0xa8,0x02,0x03,0xd0,0x45, - 0x24,0xe6,0x06,0xce,0x03,0x09,0x06,0x3d, - 0x02,0x22,0x2f,0x9b,0x6f,0x8f,0x50,0x00, - 0x02,0x00,0x1f,0xae,0x00,0x00,0x48,0x69, - 0x2c,0x20,0x74,0x68,0x69,0x73,0x20,0x69, - 0x73,0x20,0x61,0x20,0x62,0x69,0x67,0x20, - 0x74,0x65,0x73,0x74,0x20,0x74,0x6f,0x20, - 0x63,0x68,0x65,0x63,0x6b,0x20,0x63,0x6f, - 0x6e,0x74,0x65,0x6e,0x74,0x20,0x6d,0x61, - 0x74,0x63,0x68,0x65,0x73,0x0a,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00 }; /* end rawpkt3 */ - - uint8_t rawpkt4[] = { - 0x00,0x04,0x76,0xd3,0xd8,0x6a,0x00,0x24, - 0xe8,0x29,0xfa,0x4f,0x08,0x00,0x45,0x00, - 0x00,0x8c,0xa7,0x2e,0x00,0x00,0x40,0x06, - 0x1b,0x67,0xc0,0xa8,0x02,0x03,0xd0,0x45, - 0x24,0xe6,0x06,0xcf,0x03,0x09,0x00,0x0e, - 0xdf,0x72,0x3d,0xc2,0x21,0xce,0x50,0x00, - 0x02,0x00,0x88,0x25,0x00,0x00,0x48,0x69, - 0x2c,0x20,0x74,0x68,0x69,0x73,0x20,0x69, - 0x73,0x20,0x61,0x20,0x62,0x69,0x67,0x20, - 0x74,0x65,0x73,0x74,0x20,0x74,0x6f,0x20, - 0x63,0x68,0x65,0x63,0x6b,0x20,0x63,0x6f, - 0x6e,0x74,0x65,0x6e,0x74,0x20,0x6d,0x61, - 0x74,0x63,0x68,0x65,0x73,0x0a,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00 }; /* end rawpkt4 */ - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineThreadCtx *det_ctx = NULL; - - FlowInitConfig(FLOW_QUIET); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"within test\"; content:\"Hi, this is a big test to check \"; content:\"content matches\"; distance:0; within:15; sid:556;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - /* packet 1 */ - p1 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p1 == NULL)) - return 0; - memset(p1, 0, SIZE_OF_PACKET); - DecodeEthernet(&th_v, &dtv, p1, rawpkt1, sizeof(rawpkt1), NULL); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if (!(PacketAlertCheck(p1, 556))) { - printf("failed to match on packet 1: "); - goto end; - } - - /* packet 2 */ - p2 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p2 == NULL)) - return 0; - memset(p2, 0, SIZE_OF_PACKET); - DecodeEthernet(&th_v, &dtv, p2, rawpkt2, sizeof(rawpkt2), NULL); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - if (!(PacketAlertCheck(p2, 556))) { - printf("failed to match on packet 2: "); - goto end; - } - - /* packet 3 */ - p3 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p3 == NULL)) - return 0; - memset(p3, 0, SIZE_OF_PACKET); - DecodeEthernet(&th_v, &dtv, p3, rawpkt3, sizeof(rawpkt3), NULL); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p3); - if (!(PacketAlertCheck(p3, 556))) { - printf("failed to match on packet 3: "); - goto end; - } - - /* packet 4 */ - p4 = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p4 == NULL)) - return 0; - memset(p4, 0, SIZE_OF_PACKET); - DecodeEthernet(&th_v, &dtv, p4, rawpkt4, sizeof(rawpkt4), NULL); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p4); - if (!(PacketAlertCheck(p4, 556))) { - printf("failed to match on packet 4: "); - goto end; - } - - /* packet 5 */ - uint8_t *p5buf = (uint8_t *)"Hi, this is a big test to check content matches"; - uint16_t p5buflen = strlen((char *)p5buf); - Packet *p5 = UTHBuildPacket(p5buf, p5buflen, IPPROTO_TCP); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p5); - if (!(PacketAlertCheck(p5, 556))) { - printf("failed to match on packet 5: "); - goto end; - } - UTHFreePackets(&p5, 1); - - result = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - if (p1 != NULL) { - PACKET_RECYCLE(p1); - SCFree(p1); - } - if (p2 != NULL) { - PACKET_RECYCLE(p2); - SCFree(p2); - } - if (p3 != NULL) { - PACKET_RECYCLE(p3); - SCFree(p3); - } - if (p4 != NULL) { - PACKET_RECYCLE(p4); - SCFree(p4); - } - FlowShutdown(); - return result; -} - -static int SigTestWithinReal01B2g (void) -{ - return SigTestWithinReal01(MPM_B2G); -} -static int SigTestWithinReal01B3g (void) -{ - return SigTestWithinReal01(MPM_B3G); -} -static int SigTestWithinReal01Wm (void) -{ - return SigTestWithinReal01(MPM_WUMANBER); -} - -static int SigTestDepthOffset01Real (int mpm_type) -{ - uint8_t *buf = (uint8_t *)"01234567890123456789012345678901abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = mpm_type; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"depth offset\"; content:\"456\"; offset:4; depth:3; sid:1;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1)) - result = 1; - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); -end: - UTHFreePackets(&p, 1); - return result; -} -static int SigTestDepthOffset01B2g (void) -{ - return SigTestDepthOffset01Real(MPM_B2G); -} -static int SigTestDepthOffset01B3g (void) -{ - return SigTestDepthOffset01Real(MPM_B3G); -} -static int SigTestDepthOffset01Wm (void) -{ - return SigTestDepthOffset01Real(MPM_WUMANBER); -} - -static int SigTestDetectAlertCounter(void) -{ - Packet *p = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&tv, 0, sizeof(tv)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (msg:\"Test counter\"; " - "content:\"boo\"; sid:1;)"); - if (de_ctx->sig_list == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - tv.name = "detect_test"; - DetectEngineThreadCtxInit(&tv, de_ctx, (void *)&det_ctx); - - /* init counters */ - StatsSetupPrivate(&tv); - - p = UTHBuildPacket((uint8_t *)"boo", strlen("boo"), IPPROTO_TCP); - Detect(&tv, p, det_ctx, NULL, NULL); - result = (StatsGetLocalCounterValue(&tv, det_ctx->counter_alerts) == 1); - - Detect(&tv, p, det_ctx, NULL, NULL); - result &= (StatsGetLocalCounterValue(&tv, det_ctx->counter_alerts) == 2); - UTHFreePackets(&p, 1); - - p = UTHBuildPacket((uint8_t *)"roo", strlen("roo"), IPPROTO_TCP); - Detect(&tv, p, det_ctx, NULL, NULL); - result &= (StatsGetLocalCounterValue(&tv, det_ctx->counter_alerts) == 2); - UTHFreePackets(&p, 1); - - p = UTHBuildPacket((uint8_t *)"laboosa", strlen("laboosa"), IPPROTO_TCP); - Detect(&tv, p, det_ctx, NULL, NULL); - result &= (StatsGetLocalCounterValue(&tv, det_ctx->counter_alerts) == 3); - UTHFreePackets(&p, 1); - -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&tv, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test test if the engine set flag to drop pkts of a flow that - * triggered a drop action on IPS mode */ -static int SigTestDropFlow01(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "drop http any any -> any any " - "(msg:\"Test proto match\"; " - "sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should: "); - goto end; - } - - if ( !(p->flow->flags & FLOW_ACTION_DROP)) { - printf("sig 1 alerted but flow was not flagged correctly: "); - goto end; - } - - /* Ok, now we know that the flag is set for proto http */ - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test test if the engine set flag to drop pkts of a flow that - * triggered a drop action on IPS mode */ -static int SigTestDropFlow02(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 " - "(msg:\"Test proto match\"; uricontent:\"one\";" - "sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p); - - if (!PacketAlertCheck(p, 1)) { - printf("sig 1 didn't alert, but it should: "); - goto end; - } - - if ( !(p->flow->flags & FLOW_ACTION_DROP)) { - printf("sig 1 alerted but flow was not flagged correctly: "); - goto end; - } - - /* Ok, now we know that the flag is set for app layer sigs - * (ex: inspecting uricontent) */ - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test test if the engine set flag to drop pkts of a flow that - * triggered a drop action on IPS mode, and it doesn't inspect - * any other packet of the stream */ -static int SigTestDropFlow03(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - - uint8_t http_buf2[] = "POST /two HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf1) - 1; - - /* Set the engine mode to IPS */ - EngineModeSetIPS(); - - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 " - "(msg:\"Test proto match\"; uricontent:\"one\";" - "sid:1;)"); - if (s == NULL) { - goto end; - } - - /* the no inspection flag should be set after the first sig gets triggered, - * so the second packet should not match the next sig (because of no inspection) */ - s = de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any 80 " - "(msg:\"Test proto match\"; uricontent:\"two\";" - "sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p1); - - if (!PacketAlertCheck(p1, 1)) { - printf("sig 1 didn't alert on p1, but it should: "); - goto end; - } - - if ( !(p1->flow->flags & FLOW_ACTION_DROP)) { - printf("sig 1 alerted but flow was not flagged correctly: "); - goto end; - } - - /* Second part.. Let's feed with another packet */ - if (StreamTcpCheckFlowDrops(p2) == 1) { - SCLogDebug("This flow/stream triggered a drop rule"); - FlowSetNoPacketInspectionFlag(p2->flow); - DecodeSetNoPacketInspectionFlag(p2); - StreamTcpDisableAppLayer(p2->flow); - p2->action |= ACTION_DROP; - /* return the segments to the pool */ - StreamTcpSessionPktFree(p2); - } - - - if ( !(p2->flags & PKT_NOPACKET_INSPECTION)) { - printf("The packet was not flagged with no-inspection: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sig 1 alerted, but it should not since the no pkt inspection should be set: "); - goto end; - } - - if (PacketAlertCheck(p2, 2)) { - printf("sig 2 alerted, but it should not since the no pkt inspection should be set: "); - goto end; - } - - if ( !(PACKET_TEST_ACTION(p2, ACTION_DROP))) { - printf("A \"drop\" action should be set from the flow to the packet: "); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - - /* Restore mode to IDS */ - EngineModeSetIDS(); - return result; -} - -/** \test test if the engine set flag to drop pkts of a flow that - * triggered a drop action on IDS mode, but continue the inspection - * as usual (instead of on IPS mode) */ -static int SigTestDropFlow04(void) -{ - int result = 0; - Flow f; - HtpState *http_state = NULL; - uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf1_len = sizeof(http_buf1) - 1; - - uint8_t http_buf2[] = "POST /two HTTP/1.0\r\n" - "User-Agent: Mozilla/1.0\r\n" - "Cookie: hellocatch\r\n\r\n"; - uint32_t http_buf2_len = sizeof(http_buf1) - 1; - - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - - memset(&tv, 0, sizeof(ThreadVars)); - memset(&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof(TcpSession)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p1->flow = &f; - p1->flowflags |= FLOW_PKT_TOSERVER; - p1->flowflags |= FLOW_PKT_ESTABLISHED; - p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 " - "(msg:\"Test proto match\"; uricontent:\"one\";" - "sid:1;)"); - if (s == NULL) { - goto end; - } - - /* the no inspection flag should be set after the first sig gets triggered, - * so the second packet should not match the next sig (because of no inspection) */ - s = de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any 80 " - "(msg:\"Test proto match\"; uricontent:\"two\";" - "sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - SCMutexLock(&f.m); - int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - goto end; - } - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p1); - - if (!PacketAlertCheck(p1, 1)) { - printf("sig 1 didn't alert on p1, but it should: "); - goto end; - } - - if (PacketAlertCheck(p1, 2)) { - printf("sig 2 alerted on p1, but it should not: "); - goto end; - } - - if ( !(p1->flow->flags & FLOW_ACTION_DROP)) { - printf("sig 1 alerted but flow was not flagged correctly: "); - goto end; - } - - if (!(PACKET_TEST_ACTION(p1, ACTION_DROP))) { - printf("A \"drop\" action was set from the flow to the packet " - "which is right, but setting the flag shouldn't disable " - "inspection on the packet in IDS mode"); - goto end; - } - - /* Second part.. Let's feed with another packet */ - if (StreamTcpCheckFlowDrops(p2) == 1) { - FlowSetNoPacketInspectionFlag(p2->flow); - DecodeSetNoPacketInspectionFlag(p2); - StreamTcpDisableAppLayer(p2->flow); - p2->action |= ACTION_DROP; - /* return the segments to the pool */ - StreamTcpSessionPktFree(p2); - } - - if ( (p2->flags & PKT_NOPACKET_INSPECTION)) { - printf("The packet was flagged with no-inspection but we are not on IPS mode: "); - goto end; - } - - SCMutexLock(&f.m); - r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r); - SCMutexUnlock(&f.m); - goto end; - } - SCMutexUnlock(&f.m); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sig 1 alerted, but it should not: "); - goto end; - } - - if (!PacketAlertCheck(p2, 2)) { - printf("sig 2 didn't alert, but it should, since we are not on IPS mode: "); - goto end; - } - - if (!(PACKET_TEST_ACTION(p2, ACTION_DROP))) { - printf("A \"drop\" action was set from the flow to the packet " - "which is right, but setting the flag shouldn't disable " - "inspection on the packet in IDS mode"); - goto end; - } - - result = 1; - -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - - return result; -} - -/** \test ICMP packet shouldn't be matching port based sig - * Bug #611 */ -static int SigTestPorts01(void) -{ - int result = 0; - Packet *p1 = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - uint8_t payload[] = "AAAAAAAAAAAAAAAAAA"; - - memset(&tv, 0, sizeof(ThreadVars)); - - p1 = UTHBuildPacket(payload, sizeof(payload), IPPROTO_ICMP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->mpm_matcher = MPM_B2G; - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx, "alert ip any any -> any 80 " - "(content:\"AAA\"; sid:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sig 1 alerted on p1, but it should not: "); - goto end; - } - - result = 1; -end: - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p1, 1); - return result; -} - -/** \test almost identical patterns */ -static int SigTestBug01(void) -{ - int result = 0; - Packet *p1 = NULL; - Signature *s = NULL; - ThreadVars tv; - DetectEngineThreadCtx *det_ctx = NULL; - uint8_t payload[] = "!mymy"; - - memset(&tv, 0, sizeof(ThreadVars)); - - p1 = UTHBuildPacket(payload, sizeof(payload), IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(content:\"Omymy\"; nocase; sid:1;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " - "(content:\"!mymy\"; nocase; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx); - - /* do detect */ - SigMatchSignatures(&tv, de_ctx, det_ctx, p1); - - if (PacketAlertCheck(p1, 1)) { - printf("sig 1 alerted on p1, but it should not: "); - goto end; - } - if (!(PacketAlertCheck(p1, 2))) { - printf("sig 2 did not p1, but it should have: "); - goto end; - } - - result = 1; -end: - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&tv, det_ctx); - if (de_ctx != NULL) - SigGroupCleanup(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p1, 1); - return result; -} - -static const char *dummy_conf_string2 = - "%YAML 1.1\n" - "---\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"[10.10.10.0/24, !10.10.10.247]\"\n" - "\n" - " EXTERNAL_NET: \"any\"\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"80:81,88\"\n" - "\n"; - -static int DetectAddressYamlParsing01 (void) -{ - int result = 0; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string2, strlen(dummy_conf_string2)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - if ((DetectEngineAppendSig(de_ctx, "alert tcp $HOME_NET any -> any any (sid:1;)")) == NULL) - goto end; - if ((DetectEngineAppendSig(de_ctx, "alert tcp any any -> $HOME_NET any (sid:2;)")) == NULL) - goto end; - if ((DetectEngineAppendSig(de_ctx, "alert tcp $HOME_NET any -> $HOME_NET any (sid:3;)")) == NULL) - goto end; - - result = 1; - - DetectEngineCtxFree(de_ctx); -end: - ConfDeInit(); - ConfRestoreContextBackup(); - return result; -} - -static const char *dummy_conf_string3 = - "%YAML 1.1\n" - "---\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"[10.10.10.0/24, !10.10.10.247/32]\"\n" - "\n" - " EXTERNAL_NET: \"any\"\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"80:81,88\"\n" - "\n"; - -static int DetectAddressYamlParsing02 (void) -{ - int result = 0; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string3, strlen(dummy_conf_string3)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - if ((DetectEngineAppendSig(de_ctx, "alert tcp $HOME_NET any -> any any (sid:1;)")) == NULL) - goto end; - if ((DetectEngineAppendSig(de_ctx, "alert tcp any any -> $HOME_NET any (sid:2;)")) == NULL) - goto end; - if ((DetectEngineAppendSig(de_ctx, "alert tcp $HOME_NET any -> $HOME_NET any (sid:3;)")) == NULL) - goto end; - - result = 1; - - DetectEngineCtxFree(de_ctx); -end: - ConfDeInit(); - ConfRestoreContextBackup(); - return result; -} - -static const char *dummy_conf_string4 = - "%YAML 1.1\n" - "---\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"[10.10.10.0/24, !10.10.10.247/32]\"\n" - "\n" - " EXTERNAL_NET: \"any\"\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"80:81,88\"\n" - "\n"; - -static int DetectAddressYamlParsing03 (void) -{ - int result = 0; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string4, strlen(dummy_conf_string4)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - if ((DetectEngineAppendSig(de_ctx, "alert tcp $HOME_NET any -> any any (sid:1;)")) == NULL) - goto end; - if ((DetectEngineAppendSig(de_ctx, "alert tcp any any -> $HOME_NET any (sid:2;)")) == NULL) - goto end; - if ((DetectEngineAppendSig(de_ctx, "alert tcp $HOME_NET any -> $HOME_NET any (sid:3;)")) == NULL) - goto end; - - result = 1; - - DetectEngineCtxFree(de_ctx); -end: - ConfDeInit(); - ConfRestoreContextBackup(); - return result; -} - -static const char *dummy_conf_string5 = - "%YAML 1.1\n" - "---\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"[10.196.0.0/24, !10.196.0.15]\"\n" - "\n" - " EXTERNAL_NET: \"any\"\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"80:81,88\"\n" - "\n"; - -/** \test bug #815 */ -static int DetectAddressYamlParsing04 (void) -{ - int result = 0; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string5, strlen(dummy_conf_string5)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - if ((DetectEngineAppendSig(de_ctx, "alert tcp $HOME_NET any -> any any (sid:1;)")) == NULL) - goto end; - if ((DetectEngineAppendSig(de_ctx, "alert tcp any any -> $HOME_NET any (sid:2;)")) == NULL) - goto end; - if ((DetectEngineAppendSig(de_ctx, "alert tcp $HOME_NET any -> $HOME_NET any (sid:3;)")) == NULL) - goto end; - - result = 1; - - DetectEngineCtxFree(de_ctx); -end: - ConfDeInit(); - ConfRestoreContextBackup(); - return result; -} -#endif /* UNITTESTS */ - -void SigRegisterTests(void) -{ -#ifdef UNITTESTS - SigParseRegisterTests(); - IPOnlyRegisterTests(); - - UtRegisterTest("SigTest01B2g -- HTTP URI cap", SigTest01B2g, 1); - UtRegisterTest("SigTest01B3g -- HTTP URI cap", SigTest01B3g, 1); - UtRegisterTest("SigTest01Wm -- HTTP URI cap", SigTest01Wm, 1); - - UtRegisterTest("SigTest02B2g -- Offset/Depth match", SigTest02B2g, 1); - UtRegisterTest("SigTest02B3g -- Offset/Depth match", SigTest02B3g, 1); - UtRegisterTest("SigTest02Wm -- Offset/Depth match", SigTest02Wm, 1); - - UtRegisterTest("SigTest03B2g -- offset/depth mismatch", SigTest03B2g, 1); - UtRegisterTest("SigTest03B3g -- offset/depth mismatch", SigTest03B3g, 1); - UtRegisterTest("SigTest03Wm -- offset/depth mismatch", SigTest03Wm, 1); - - UtRegisterTest("SigTest04B2g -- distance/within match", SigTest04B2g, 1); - UtRegisterTest("SigTest04B3g -- distance/within match", SigTest04B3g, 1); - UtRegisterTest("SigTest04Wm -- distance/within match", SigTest04Wm, 1); - - UtRegisterTest("SigTest05B2g -- distance/within mismatch", SigTest05B2g, 1); - UtRegisterTest("SigTest05B3g -- distance/within mismatch", SigTest05B3g, 1); - UtRegisterTest("SigTest05Wm -- distance/within mismatch", SigTest05Wm, 1); - - UtRegisterTest("SigTest06B2g -- uricontent HTTP/1.1 match test", SigTest06B2g, 1); - UtRegisterTest("SigTest06B3g -- uricontent HTTP/1.1 match test", SigTest06B3g, 1); - UtRegisterTest("SigTest06wm -- uricontent HTTP/1.1 match test", SigTest06Wm, 1); - - UtRegisterTest("SigTest07B2g -- uricontent HTTP/1.1 mismatch test", SigTest07B2g, 1); - UtRegisterTest("SigTest07B3g -- uricontent HTTP/1.1 mismatch test", SigTest07B3g, 1); - UtRegisterTest("SigTest07Wm -- uricontent HTTP/1.1 mismatch test", SigTest07Wm, 1); - - UtRegisterTest("SigTest08B2g -- uricontent HTTP/1.0 match test", SigTest08B2g, 1); - UtRegisterTest("SigTest08B3g -- uricontent HTTP/1.0 match test", SigTest08B3g, 1); - UtRegisterTest("SigTest08Wm -- uricontent HTTP/1.0 match test", SigTest08Wm, 1); - - UtRegisterTest("SigTest09B2g -- uricontent HTTP/1.0 mismatch test", SigTest09B2g, 1); - UtRegisterTest("SigTest09B3g -- uricontent HTTP/1.0 mismatch test", SigTest09B3g, 1); - UtRegisterTest("SigTest09Wm -- uricontent HTTP/1.0 mismatch test", SigTest09Wm, 1); - - UtRegisterTest("SigTest10B2g -- long content match, longer than pkt", SigTest10B2g, 1); - UtRegisterTest("SigTest10B3g -- long content match, longer than pkt", SigTest10B3g, 1); - UtRegisterTest("SigTest10Wm -- long content match, longer than pkt", SigTest10Wm, 1); - - UtRegisterTest("SigTest11B2g -- mpm searching", SigTest11B2g, 1); - UtRegisterTest("SigTest11B3g -- mpm searching", SigTest11B3g, 1); - UtRegisterTest("SigTest11Wm -- mpm searching", SigTest11Wm, 1); - - UtRegisterTest("SigTest12B2g -- content order matching, normal", SigTest12B2g, 1); - UtRegisterTest("SigTest12B3g -- content order matching, normal", SigTest12B3g, 1); - UtRegisterTest("SigTest12Wm -- content order matching, normal", SigTest12Wm, 1); - - UtRegisterTest("SigTest13B2g -- content order matching, diff order", SigTest13B2g, 1); - UtRegisterTest("SigTest13B3g -- content order matching, diff order", SigTest13B3g, 1); - UtRegisterTest("SigTest13Wm -- content order matching, diff order", SigTest13Wm, 1); - - UtRegisterTest("SigTest14B2g -- content order matching, distance 0", SigTest14B2g, 1); - UtRegisterTest("SigTest14B3g -- content order matching, distance 0", SigTest14B3g, 1); - UtRegisterTest("SigTest14Wm -- content order matching, distance 0", SigTest14Wm, 1); - - UtRegisterTest("SigTest15B2g -- port negation sig (no match)", SigTest15B2g, 1); - UtRegisterTest("SigTest15B3g -- port negation sig (no match)", SigTest15B3g, 1); - UtRegisterTest("SigTest15Wm -- port negation sig (no match)", SigTest15Wm, 1); - - UtRegisterTest("SigTest16B2g -- port negation sig (match)", SigTest16B2g, 1); - UtRegisterTest("SigTest16B3g -- port negation sig (match)", SigTest16B3g, 1); - UtRegisterTest("SigTest16Wm -- port negation sig (match)", SigTest16Wm, 1); - - UtRegisterTest("SigTest17B2g -- HTTP Host Pkt var capture", SigTest17B2g, 1); - UtRegisterTest("SigTest17B3g -- HTTP Host Pkt var capture", SigTest17B3g, 1); - UtRegisterTest("SigTest17Wm -- HTTP Host Pkt var capture", SigTest17Wm, 1); - - UtRegisterTest("SigTest18B2g -- Ftp negation sig test", SigTest18B2g, 1); - UtRegisterTest("SigTest18B3g -- Ftp negation sig test", SigTest18B3g, 1); - UtRegisterTest("SigTest18Wm -- Ftp negation sig test", SigTest18Wm, 1); - - UtRegisterTest("SigTest19B2g -- IP-ONLY test (1)", SigTest19B2g, 1); - UtRegisterTest("SigTest19B3g -- IP-ONLY test (1)", SigTest19B3g, 1); - UtRegisterTest("SigTest19Wm -- IP-ONLY test (1)", SigTest19Wm, 1); - - UtRegisterTest("SigTest20B2g -- IP-ONLY test (2)", SigTest20B2g, 1); - UtRegisterTest("SigTest20B3g -- IP-ONLY test (2)", SigTest20B3g, 1); - UtRegisterTest("SigTest20Wm -- IP-ONLY test (2)", SigTest20Wm, 1); - - UtRegisterTest("SigTest21B2g -- FLOWBIT test (1)", SigTest21B2g, 1); - UtRegisterTest("SigTest21B3g -- FLOWBIT test (1)", SigTest21B3g, 1); - UtRegisterTest("SigTest21Wm -- FLOWBIT test (1)", SigTest21Wm, 1); - - UtRegisterTest("SigTest22B2g -- FLOWBIT test (2)", SigTest22B2g, 1); - UtRegisterTest("SigTest22B3g -- FLOWBIT test (2)", SigTest22B3g, 1); - UtRegisterTest("SigTest22Wm -- FLOWBIT test (2)", SigTest22Wm, 1); - - UtRegisterTest("SigTest23B2g -- FLOWBIT test (3)", SigTest23B2g, 1); - UtRegisterTest("SigTest23B3g -- FLOWBIT test (3)", SigTest23B3g, 1); - UtRegisterTest("SigTest23Wm -- FLOWBIT test (3)", SigTest23Wm, 1); - - UtRegisterTest("SigTest24IPV4Keyword", SigTest24IPV4Keyword, 1); - UtRegisterTest("SigTest25NegativeIPV4Keyword", - SigTest25NegativeIPV4Keyword, 1); - - UtRegisterTest("SigTest26TCPV4Keyword", SigTest26TCPV4Keyword, 1); - UtRegisterTest("SigTest26TCPV4AndNegativeIPV4Keyword", SigTest26TCPV4AndNegativeIPV4Keyword, 1); - UtRegisterTest("SigTest26TCPV4AndIPV4Keyword", SigTest26TCPV4AndIPV4Keyword, 1); - UtRegisterTest("SigTest27NegativeTCPV4Keyword", - SigTest27NegativeTCPV4Keyword, 1); - - UtRegisterTest("SigTest28TCPV6Keyword", SigTest28TCPV6Keyword, 1); - UtRegisterTest("SigTest29NegativeTCPV6Keyword", - SigTest29NegativeTCPV6Keyword, 1); - - UtRegisterTest("SigTest30UDPV4Keyword", SigTest30UDPV4Keyword, 1); - UtRegisterTest("SigTest31NegativeUDPV4Keyword", - SigTest31NegativeUDPV4Keyword, 1); - - UtRegisterTest("SigTest32UDPV6Keyword", SigTest32UDPV6Keyword, 1); - UtRegisterTest("SigTest33NegativeUDPV6Keyword", - SigTest33NegativeUDPV6Keyword, 1); - - UtRegisterTest("SigTest34ICMPV4Keyword", SigTest34ICMPV4Keyword, 1); - UtRegisterTest("SigTest35NegativeICMPV4Keyword", - SigTest35NegativeICMPV4Keyword, 1); - - /* The following tests check content options with isdataat options - relative to that content match - */ - - UtRegisterTest("SigTest36ContentAndIsdataatKeywords01B2g", - SigTest36ContentAndIsdataatKeywords01B2g, 1); - UtRegisterTest("SigTest36ContentAndIsdataatKeywords01B3g", - SigTest36ContentAndIsdataatKeywords01B3g, 1); - UtRegisterTest("SigTest36ContentAndIsdataatKeywords01Wm" , - SigTest36ContentAndIsdataatKeywords01Wm, 1); - - UtRegisterTest("SigTest37ContentAndIsdataatKeywords02B2g", - SigTest37ContentAndIsdataatKeywords02B2g, 1); - UtRegisterTest("SigTest37ContentAndIsdataatKeywords02B3g", - SigTest37ContentAndIsdataatKeywords02B3g, 1); - UtRegisterTest("SigTest37ContentAndIsdataatKeywords02Wm" , - SigTest37ContentAndIsdataatKeywords02Wm, 1); - - /* We need to enable these tests, as soon as we add the ICMPv6 protocol - support in our rules engine */ - //UtRegisterTest("SigTest36ICMPV6Keyword", SigTest36ICMPV6Keyword, 1); - //UtRegisterTest("SigTest37NegativeICMPV6Keyword", - // SigTest37NegativeICMPV6Keyword, 1); - - UtRegisterTest("SigTest38B2g -- byte_test test (1)", SigTest38B2g, 1); - UtRegisterTest("SigTest38B3g -- byte_test test (1)", SigTest38B3g, 1); - UtRegisterTest("SigTest38Wm -- byte_test test (1)", SigTest38Wm, 1); - - UtRegisterTest("SigTest39B2g -- byte_jump test (2)", SigTest39B2g, 1); - UtRegisterTest("SigTest39B3g -- byte_jump test (2)", SigTest39B3g, 1); - UtRegisterTest("SigTest39Wm -- byte_jump test (2)", SigTest39Wm, 1); - - UtRegisterTest("SigTest40NoPacketInspection01", SigTest40NoPacketInspection01, 1); - UtRegisterTest("SigTest40NoPayloadInspection02", SigTest40NoPayloadInspection02, 1); - - UtRegisterTest("SigTestMemory01", SigTestMemory01, 1); - UtRegisterTest("SigTestMemory02", SigTestMemory02, 1); - UtRegisterTest("SigTestMemory03", SigTestMemory03, 1); - - UtRegisterTest("SigTestSgh01", SigTestSgh01, 1); - UtRegisterTest("SigTestSgh02", SigTestSgh02, 1); - UtRegisterTest("SigTestSgh03", SigTestSgh03, 1); - UtRegisterTest("SigTestSgh04", SigTestSgh04, 1); - UtRegisterTest("SigTestSgh05", SigTestSgh05, 1); - - UtRegisterTest("SigTestContent01B2g -- 32 byte pattern", SigTestContent01B2g, 1); - UtRegisterTest("SigTestContent01B3g -- 32 byte pattern", SigTestContent01B3g, 1); - UtRegisterTest("SigTestContent01Wm -- 32 byte pattern", SigTestContent01Wm, 1); - - UtRegisterTest("SigTestContent02B2g -- 32+31 byte pattern", SigTestContent02B2g, 1); - UtRegisterTest("SigTestContent02B3g -- 32+31 byte pattern", SigTestContent02B3g, 1); - UtRegisterTest("SigTestContent02Wm -- 32+31 byte pattern", SigTestContent02Wm, 1); - - UtRegisterTest("SigTestContent03B2g -- 32 byte pattern, x2 + distance", SigTestContent03B2g, 1); - UtRegisterTest("SigTestContent03B3g -- 32 byte pattern, x2 + distance", SigTestContent03B3g, 1); - UtRegisterTest("SigTestContent03Wm -- 32 byte pattern, x2 + distance", SigTestContent03Wm, 1); - - UtRegisterTest("SigTestContent04B2g -- 32 byte pattern, x2 + distance/within", SigTestContent04B2g, 1); - UtRegisterTest("SigTestContent04B3g -- 32 byte pattern, x2 + distance/within", SigTestContent04B3g, 1); - UtRegisterTest("SigTestContent04Wm -- 32 byte pattern, x2 + distance/within", SigTestContent04Wm, 1); - - UtRegisterTest("SigTestContent05B2g -- distance/within", SigTestContent05B2g, 1); - UtRegisterTest("SigTestContent05B3g -- distance/within", SigTestContent05B3g, 1); - UtRegisterTest("SigTestContent05Wm -- distance/within", SigTestContent05Wm, 1); - - UtRegisterTest("SigTestContent06B2g -- distance/within ip only", SigTestContent06B2g, 1); - UtRegisterTest("SigTestContent06B3g -- distance/within ip only", SigTestContent06B3g, 1); - UtRegisterTest("SigTestContent06Wm -- distance/within ip only", SigTestContent06Wm, 1); - - UtRegisterTest("SigTestWithinReal01B2g", SigTestWithinReal01B2g, 1); - UtRegisterTest("SigTestWithinReal01B3g", SigTestWithinReal01B3g, 1); - UtRegisterTest("SigTestWithinReal01Wm", SigTestWithinReal01Wm, 1); - - UtRegisterTest("SigTestDepthOffset01B2g", SigTestDepthOffset01B2g, 1); - UtRegisterTest("SigTestDepthOffset01B3g", SigTestDepthOffset01B3g, 1); - UtRegisterTest("SigTestDepthOffset01Wm", SigTestDepthOffset01Wm, 1); - - UtRegisterTest("SigTestDetectAlertCounter", SigTestDetectAlertCounter, 1); - - UtRegisterTest("SigTestDropFlow01", SigTestDropFlow01, 1); - UtRegisterTest("SigTestDropFlow02", SigTestDropFlow02, 1); - UtRegisterTest("SigTestDropFlow03", SigTestDropFlow03, 1); - UtRegisterTest("SigTestDropFlow04", SigTestDropFlow04, 1); - - UtRegisterTest("DetectAddressYamlParsing01", DetectAddressYamlParsing01, 1); - UtRegisterTest("DetectAddressYamlParsing02", DetectAddressYamlParsing02, 1); - UtRegisterTest("DetectAddressYamlParsing03", DetectAddressYamlParsing03, 1); - UtRegisterTest("DetectAddressYamlParsing04", DetectAddressYamlParsing04, 1); - - UtRegisterTest("SigTestPorts01", SigTestPorts01, 1); - UtRegisterTest("SigTestBug01", SigTestBug01, 1); - -#if 0 - DetectSimdRegisterTests(); -#endif -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/detect.h b/framework/src/suricata/src/detect.h deleted file mode 100644 index 89ce35ab..00000000 --- a/framework/src/suricata/src/detect.h +++ /dev/null @@ -1,1290 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __DETECT_H__ -#define __DETECT_H__ - -#include - -#include "flow.h" - -#include "detect-engine-proto.h" -#include "detect-reference.h" - -#include "packet-queue.h" -#include "util-mpm.h" -#include "util-hash.h" -#include "util-hashlist.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-radix-tree.h" -#include "util-file.h" -#include "reputation.h" - -#include "detect-mark.h" - -#define DETECT_MAX_RULE_SIZE 8192 - -/* forward declarations for the structures from detect-engine-sigorder.h */ -struct SCSigOrderFunc_; -struct SCSigSignatureWrapper_; - -/* - - The detection engine groups similar signatures/rules together. Internally a - tree of different types of data is created on initialization. This is it's - global layout: - - For TCP/UDP - - - Flow direction - -- Protocol - -=- Src address - -==- Dst address - -===- Src port - -====- Dst port - - For the other protocols - - - Flow direction - -- Protocol - -=- Src address - -==- Dst address - -*/ - -/* - * DETECT ADDRESS - */ - -/* holds the values for different possible lists in struct Signature. - * These codes are access points to particular lists in the array - * Signature->sm_lists[DETECT_SM_LIST_MAX]. */ -enum DetectSigmatchListEnum { - DETECT_SM_LIST_MATCH = 0, - DETECT_SM_LIST_PMATCH, - /* list for http_uri keyword and the ones relative to it */ - DETECT_SM_LIST_UMATCH, - /* list for http_raw_uri keyword and the ones relative to it */ - DETECT_SM_LIST_HRUDMATCH, - /* list for http_client_body keyword and the ones relative to it */ - DETECT_SM_LIST_HCBDMATCH, - /* list for http_server_body keyword and the ones relative to it */ - DETECT_SM_LIST_FILEDATA, - /* list for http_header keyword and the ones relative to it */ - DETECT_SM_LIST_HHDMATCH, - /* list for http_raw_header keyword and the ones relative to it */ - DETECT_SM_LIST_HRHDMATCH, - /* list for http_stat_msg keyword and the ones relative to it */ - DETECT_SM_LIST_HSMDMATCH, - /* list for http_stat_code keyword and the ones relative to it */ - DETECT_SM_LIST_HSCDMATCH, - /* list for http_host keyword and the ones relative to it */ - DETECT_SM_LIST_HHHDMATCH, - /* list for http_raw_host keyword and the ones relative to it */ - DETECT_SM_LIST_HRHHDMATCH, - /* list for http_method keyword and the ones relative to it */ - DETECT_SM_LIST_HMDMATCH, - /* list for http_cookie keyword and the ones relative to it */ - DETECT_SM_LIST_HCDMATCH, - /* list for http_user_agent keyword and the ones relative to it */ - DETECT_SM_LIST_HUADMATCH, - /* list for http_request_line keyword and the ones relative to it */ - DETECT_SM_LIST_HRLMATCH, - /* app event engine sm list */ - DETECT_SM_LIST_APP_EVENT, - - DETECT_SM_LIST_AMATCH, - DETECT_SM_LIST_DMATCH, - DETECT_SM_LIST_TMATCH, - - DETECT_SM_LIST_FILEMATCH, - - DETECT_SM_LIST_DNSREQUEST_MATCH, /**< per DNS query tx match list */ - DETECT_SM_LIST_DNSRESPONSE_MATCH, /**< per DNS response tx match list */ - DETECT_SM_LIST_DNSQUERYNAME_MATCH, /**< per query in a tx list */ - - DETECT_SM_LIST_MODBUS_MATCH, - - DETECT_SM_LIST_BASE64_DATA, - - DETECT_SM_LIST_TEMPLATE_BUFFER_MATCH, - - /* list for post match actions: flowbit set, flowint increment, etc */ - DETECT_SM_LIST_POSTMATCH, - - /* lists for alert thresholding and suppression */ - DETECT_SM_LIST_SUPPRESS, - DETECT_SM_LIST_THRESHOLD, - DETECT_SM_LIST_MAX, - - /* used for Signature->list, which indicates which list - * we're adding keywords to in cases of sticky buffers like - * file_data */ - DETECT_SM_LIST_NOTSET, -}; - -/* a is ... than b */ -enum { - ADDRESS_ER = -1, /**< error e.g. compare ipv4 and ipv6 */ - ADDRESS_LT, /**< smaller [aaa] [bbb] */ - ADDRESS_LE, /**< smaller with overlap [aa[bab]bb] */ - ADDRESS_EQ, /**< exactly equal [abababab] */ - ADDRESS_ES, /**< within [bb[aaa]bb] and [[abab]bbb] and [bbb[abab]] */ - ADDRESS_EB, /**< completely overlaps [aa[bbb]aa] and [[baba]aaa] and [aaa[baba]] */ - ADDRESS_GE, /**< bigger with overlap [bb[aba]aa] */ - ADDRESS_GT, /**< bigger [bbb] [aaa] */ -}; - -#define ADDRESS_FLAG_ANY 0x01 /**< address is "any" */ -#define ADDRESS_FLAG_NOT 0x02 /**< address is negated */ - -#define ADDRESS_SIGGROUPHEAD_COPY 0x04 /**< sgh is a ptr to another sgh */ -#define ADDRESS_PORTS_COPY 0x08 /**< ports are a ptr to other ports */ -#define ADDRESS_PORTS_NOTUNIQ 0x10 -#define ADDRESS_HAVEPORT 0x20 /**< address has a ports ptr */ - -/** \brief address structure for use in the detection engine. - * - * Contains the address information and matching information. - */ -typedef struct DetectAddress_ { - /** address data for this group */ - Address ip; - Address ip2; - - /** ptr to the next address (dst addr in that case) or to the src port */ - union { - struct DetectAddressHead_ *dst_gh; /**< destination address */ - struct DetectPort_ *port; /**< source port */ - }; - - /** signatures that belong in this group */ - struct SigGroupHead_ *sh; - - /** flags affecting this address */ - uint8_t flags; - - /** ptr to the previous address in the list */ - struct DetectAddress_ *prev; - /** ptr to the next address in the list */ - struct DetectAddress_ *next; - - uint32_t cnt; -} DetectAddress; - -/** Signature grouping head. Here 'any', ipv4 and ipv6 are split out */ -typedef struct DetectAddressHead_ { - DetectAddress *any_head; - DetectAddress *ipv4_head; - DetectAddress *ipv6_head; -} DetectAddressHead; - - -#include "detect-threshold.h" - -typedef struct DetectMatchAddressIPv4_ { - uint32_t ip; /**< address in host order, start of range */ - uint32_t ip2; /**< address in host order, end of range */ -} DetectMatchAddressIPv4; - -typedef struct DetectMatchAddressIPv6_ { - uint32_t ip[4]; - uint32_t ip2[4]; -} DetectMatchAddressIPv6; - -/* - * DETECT PORT - */ - -/* a is ... than b */ -enum { - PORT_ER = -1, /* error e.g. compare ipv4 and ipv6 */ - PORT_LT, /* smaller [aaa] [bbb] */ - PORT_LE, /* smaller with overlap [aa[bab]bb] */ - PORT_EQ, /* exactly equal [abababab] */ - PORT_ES, /* within [bb[aaa]bb] and [[abab]bbb] and [bbb[abab]] */ - PORT_EB, /* completely overlaps [aa[bbb]aa] and [[baba]aaa] and [aaa[baba]] */ - PORT_GE, /* bigger with overlap [bb[aba]aa] */ - PORT_GT, /* bigger [bbb] [aaa] */ -}; - -#define PORT_FLAG_ANY 0x01 /**< 'any' special port */ -#define PORT_FLAG_NOT 0x02 /**< negated port */ -#define PORT_SIGGROUPHEAD_COPY 0x04 /**< sgh is a ptr copy */ -#define PORT_GROUP_PORTS_COPY 0x08 /**< dst_ph is a ptr copy */ - -/** \brief Port structure for detection engine */ -typedef struct DetectPort_ { - uint16_t port; - uint16_t port2; - - /* signatures that belong in this group */ - struct SigGroupHead_ *sh; - - struct DetectPort_ *dst_ph; - - /* double linked list */ - union { - struct DetectPort_ *prev; - struct DetectPort_ *hnext; /* hash next */ - }; - struct DetectPort_ *next; - - uint32_t cnt; - uint8_t flags; /**< flags for this port */ -} DetectPort; - -/* Signature flags */ -#define SIG_FLAG_SRC_ANY (1) /**< source is any */ -#define SIG_FLAG_DST_ANY (1<<1) /**< destination is any */ -#define SIG_FLAG_SP_ANY (1<<2) /**< source port is any */ -#define SIG_FLAG_DP_ANY (1<<3) /**< destination port is any */ - -#define SIG_FLAG_NOALERT (1<<4) /**< no alert flag is set */ -#define SIG_FLAG_DSIZE (1<<5) /**< signature has a dsize setting */ -#define SIG_FLAG_APPLAYER (1<<6) /**< signature applies to app layer instead of packets */ -#define SIG_FLAG_IPONLY (1<<7) /**< ip only signature */ - -#define SIG_FLAG_STATE_MATCH (1<<8) /**< signature has matches that require stateful inspection */ - -#define SIG_FLAG_REQUIRE_PACKET (1<<9) /**< signature is requiring packet match */ -#define SIG_FLAG_REQUIRE_STREAM (1<<10) /**< signature is requiring stream match */ - -#define SIG_FLAG_MPM_PACKET (1<<11) -#define SIG_FLAG_MPM_PACKET_NEG (1<<12) -#define SIG_FLAG_MPM_STREAM (1<<13) -#define SIG_FLAG_MPM_STREAM_NEG (1<<14) -#define SIG_FLAG_MPM_APPLAYER (1<<15) -#define SIG_FLAG_MPM_APPLAYER_NEG (1<<16) - -#define SIG_FLAG_REQUIRE_FLOWVAR (1<<17) /**< signature can only match if a flowbit, flowvar or flowint is available. */ - -#define SIG_FLAG_FILESTORE (1<<18) /**< signature has filestore keyword */ - -#define SIG_FLAG_TOSERVER (1<<19) -#define SIG_FLAG_TOCLIENT (1<<20) - -#define SIG_FLAG_TLSSTORE (1<<21) - -/* signature init flags */ -#define SIG_FLAG_INIT_DEONLY 1 /**< decode event only signature */ -#define SIG_FLAG_INIT_PACKET (1<<1) /**< signature has matches against a packet (as opposed to app layer) */ -#define SIG_FLAG_INIT_FLOW (1<<2) /**< signature has a flow setting */ -#define SIG_FLAG_INIT_BIDIREC (1<<3) /**< signature has bidirectional operator */ -#define SIG_FLAG_INIT_PAYLOAD (1<<4) /**< signature is inspecting the packet payload */ -#define SIG_FLAG_INIT_FIRST_IPPROTO_SEEN (1 << 5) /** < signature has seen the first ip_proto keyword */ - -/* signature mask flags */ -#define SIG_MASK_REQUIRE_PAYLOAD (1<<0) -#define SIG_MASK_REQUIRE_FLOW (1<<1) -#define SIG_MASK_REQUIRE_FLAGS_INITDEINIT (1<<2) /* SYN, FIN, RST */ -#define SIG_MASK_REQUIRE_FLAGS_UNUSUAL (1<<3) /* URG, ECN, CWR */ -#define SIG_MASK_REQUIRE_NO_PAYLOAD (1<<4) -#define SIG_MASK_REQUIRE_HTTP_STATE (1<<5) -#define SIG_MASK_REQUIRE_DCE_STATE (1<<6) -#define SIG_MASK_REQUIRE_ENGINE_EVENT (1<<7) -#define SIG_MASK_REQUIRE_SSH_STATE (1<<8) -#define SIG_MASK_REQUIRE_TLS_STATE (1<<9) -#define SIG_MASK_REQUIRE_DNS_STATE (1<<10) -#define SIG_MASK_REQUIRE_FTP_STATE (1<<11) -#define SIG_MASK_REQUIRE_SMTP_STATE (1<<12) -#define SIG_MASK_REQUIRE_TEMPLATE_STATE (1<<13) - -/* for now a uint8_t is enough */ -#define SignatureMask uint16_t - -#define DETECT_ENGINE_THREAD_CTX_INSPECTING_PACKET 0x0001 -#define DETECT_ENGINE_THREAD_CTX_INSPECTING_STREAM 0x0002 -#define DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH 0x0004 - -#define FILE_SIG_NEED_FILE 0x01 -#define FILE_SIG_NEED_FILENAME 0x02 -#define FILE_SIG_NEED_TYPE 0x04 -#define FILE_SIG_NEED_MAGIC 0x08 /**< need the start of the file */ -#define FILE_SIG_NEED_FILECONTENT 0x10 -#define FILE_SIG_NEED_MD5 0x20 -#define FILE_SIG_NEED_SIZE 0x40 - -/* Detection Engine flags */ -#define DE_QUIET 0x01 /**< DE is quiet (esp for unittests) */ - -typedef struct IPOnlyCIDRItem_ { - /* address data for this item */ - uint8_t family; - uint32_t ip[4]; - /* netmask in CIDR values (ex. /16 /18 /24..) */ - uint8_t netmask; - - /* If this host or net is negated for the signum */ - uint8_t negated; - SigIntId signum; /**< our internal id */ - - /* linked list, the header should be the biggest network */ - struct IPOnlyCIDRItem_ *next; - -} IPOnlyCIDRItem; - -/** \brief Used to start a pointer to SigMatch context - * Should never be dereferenced without casting to something else. - */ -typedef struct SigMatchCtx_ { - int foo; -} SigMatchCtx; - -/** \brief a single match condition for a signature */ -typedef struct SigMatch_ { - uint8_t type; /**< match type */ - uint16_t idx; /**< position in the signature */ - SigMatchCtx *ctx; /**< plugin specific data */ - struct SigMatch_ *next; - struct SigMatch_ *prev; -} SigMatch; - -/** \brief Data needed for Match() */ -typedef struct SigMatchData_ { - uint8_t type; /**< match type */ - uint8_t is_last; /**< Last element of the list */ - SigMatchCtx *ctx; /**< plugin specific data */ -} SigMatchData; - - -/** \brief Signature container */ -typedef struct Signature_ { - /* coccinelle: Signature:flags:SIG_FLAG */ - uint32_t flags; - - AppProto alproto; - - uint16_t dsize_low; - uint16_t dsize_high; - - uint16_t mpm_pattern_id_div_8; - uint8_t mpm_pattern_id_mod_8; - - SignatureMask mask; - SigIntId num; /**< signature number, internal id */ - - /** inline -- action */ - uint8_t action; - uint8_t file_flags; - - /** addresses, ports and proto this sig matches on */ - DetectProto proto; - - /** classification id **/ - uint8_t class; - - /** ipv4 match arrays */ - uint16_t addr_dst_match4_cnt; - uint16_t addr_src_match4_cnt; - uint16_t addr_dst_match6_cnt; - uint16_t addr_src_match6_cnt; - DetectMatchAddressIPv4 *addr_dst_match4; - DetectMatchAddressIPv4 *addr_src_match4; - /** ipv6 match arrays */ - DetectMatchAddressIPv6 *addr_dst_match6; - DetectMatchAddressIPv6 *addr_src_match6; - - uint32_t id; /**< sid, set by the 'sid' rule keyword */ - uint32_t gid; /**< generator id */ - uint32_t rev; - int prio; - - /** port settings for this signature */ - DetectPort *sp, *dp; - -#ifdef PROFILING - uint16_t profiling_id; -#endif - /** number of sigmatches in the match and pmatch list */ - uint16_t sm_cnt; - - /* used to hold flags that are predominantly used during init */ - uint32_t init_flags; - /* coccinelle: Signature:init_flags:SIG_FLAG_INIT_ */ - - /** netblocks and hosts specified at the sid, in CIDR format */ - IPOnlyCIDRItem *CidrSrc, *CidrDst; - - /* Hold copies of the sm lists for Match() */ - SigMatchData *sm_arrays[DETECT_SM_LIST_MAX]; - - /* holds all sm lists */ - struct SigMatch_ *sm_lists[DETECT_SM_LIST_MAX]; - /* holds all sm lists' tails */ - struct SigMatch_ *sm_lists_tail[DETECT_SM_LIST_MAX]; - - SigMatch *filestore_sm; - - char *msg; - - /** classification message */ - char *class_msg; - /** Reference */ - DetectReference *references; - - /** address settings for this signature */ - DetectAddressHead src, dst; - - /* used at init to determine max dsize */ - SigMatch *dsize_sm; - /* the fast pattern added from this signature */ - SigMatch *mpm_sm; - - /* SigMatch list used for adding content and friends. E.g. file_data; */ - int list; - - /* Be careful, this pointer is only valid while parsing the sig, - * to warn the user about any possible problem */ - char *sig_str; - - /** ptr to the next sig in the list */ - struct Signature_ *next; -} Signature; - -typedef struct DetectReplaceList_ { - struct DetectContentData_ *cd; - uint8_t *found; - struct DetectReplaceList_ *next; -} DetectReplaceList; - -/** only execute flowvar storage if rule matched */ -#define DETECT_FLOWVAR_TYPE_POSTMATCH 1 -/** execute flowvar storage even if rule doesn't match (for luajit) */ -#define DETECT_FLOWVAR_TYPE_ALWAYS 2 - -/** list for flowvar store candidates, to be stored from - * post-match function */ -typedef struct DetectFlowvarList_ { - uint16_t idx; /**< flowvar name idx */ - uint16_t len; /**< data len */ - uint8_t *buffer; /**< alloc'd buffer, may be freed by - post-match, post-non-match */ - int type; /**< type of store candidate POSTMATCH or ALWAYS */ - struct DetectFlowvarList_ *next; -} DetectFlowvarList; - -typedef struct DetectEngineIPOnlyThreadCtx_ { - uint8_t *sig_match_array; /* bit array of sig nums */ - uint32_t sig_match_size; /* size in bytes of the array */ -} DetectEngineIPOnlyThreadCtx; - -/** \brief IP only rules matching ctx. */ -typedef struct DetectEngineIPOnlyCtx_ { - /* lookup hashes */ - HashListTable *ht16_src, *ht16_dst; - HashListTable *ht24_src, *ht24_dst; - - /* Lookup trees */ - SCRadixTree *tree_ipv4src, *tree_ipv4dst; - SCRadixTree *tree_ipv6src, *tree_ipv6dst; - - /* Used to build the radix trees */ - IPOnlyCIDRItem *ip_src, *ip_dst; - - /* counters */ - uint32_t a_src_uniq16, a_src_total16; - uint32_t a_dst_uniq16, a_dst_total16; - uint32_t a_src_uniq24, a_src_total24; - uint32_t a_dst_uniq24, a_dst_total24; - - uint32_t max_idx; - - uint8_t *sig_init_array; /* bit array of sig nums */ - uint32_t sig_init_size; /* size in bytes of the array */ - - /* number of sigs in this head */ - uint32_t sig_cnt; - uint32_t *match_array; -} DetectEngineIPOnlyCtx; - -typedef struct DetectEngineLookupFlow_ { - DetectAddressHead *src_gh[256]; /* a head for each protocol */ - DetectAddressHead *tmp_gh[256]; -} DetectEngineLookupFlow; - -/* Flow status - * - * to server - * to client - */ -#define FLOW_STATES 2 - -/* mpm pattern id api */ -typedef struct MpmPatternIdStore_ { - HashTable *hash; - PatIntId max_id; - - uint32_t unique_patterns; - uint32_t shared_patterns; -} MpmPatternIdStore; - -/** \brief threshold ctx */ -typedef struct ThresholdCtx_ { - SCMutex threshold_table_lock; /**< Mutex for hash table */ - - /** to support rate_filter "by_rule" option */ - DetectThresholdEntry **th_entry; - uint32_t th_size; -} ThresholdCtx; - -typedef struct DetectEngineThreadKeywordCtxItem_ { - void *(*InitFunc)(void *); - void (*FreeFunc)(void *); - void *data; - struct DetectEngineThreadKeywordCtxItem_ *next; - int id; - const char *name; /* keyword name, for error printing */ -} DetectEngineThreadKeywordCtxItem; - -/** \brief main detection engine ctx */ -typedef struct DetectEngineCtx_ { - uint8_t flags; - int failure_fatal; - - int tenant_id; - - Signature *sig_list; - uint32_t sig_cnt; - - /* version of the srep data */ - uint32_t srep_version; - - /* reputation for netblocks */ - SRepCIDRTree *srepCIDR_ctx; - - Signature **sig_array; - uint32_t sig_array_size; /* size in bytes */ - uint32_t sig_array_len; /* size in array members */ - - uint32_t signum; - - /** Maximum value of all our sgh's non_mpm_store_cnt setting, - * used to alloc det_ctx::non_mpm_id_array */ - uint32_t non_mpm_store_cnt_max; - - /* used by the signature ordering module */ - struct SCSigOrderFunc_ *sc_sig_order_funcs; - - /* hash table used for holding the classification config info */ - HashTable *class_conf_ht; - /* hash table used for holding the reference config info */ - HashTable *reference_conf_ht; - - /* main sigs */ - DetectEngineLookupFlow flow_gh[FLOW_STATES]; - - uint32_t gh_unique, gh_reuse; - - /* init phase vars */ - HashListTable *sgh_hash_table; - - HashListTable *sgh_mpm_hash_table; - HashListTable *sgh_mpm_uri_hash_table; - HashListTable *sgh_mpm_stream_hash_table; - - HashListTable *sgh_sport_hash_table; - HashListTable *sgh_dport_hash_table; - - HashListTable *sport_hash_table; - HashListTable *dport_hash_table; - - HashListTable *variable_names; - HashListTable *variable_idxs; - uint16_t variable_names_idx; - - /* hash table used to cull out duplicate sigs */ - HashListTable *dup_sig_hash_table; - - DetectEngineIPOnlyCtx io_ctx; - ThresholdCtx ths_ctx; - - uint16_t mpm_matcher; /**< mpm matcher this ctx uses */ - - /* Config options */ - - uint16_t max_uniq_toclient_src_groups; - uint16_t max_uniq_toclient_dst_groups; - uint16_t max_uniq_toclient_sp_groups; - uint16_t max_uniq_toclient_dp_groups; - - uint16_t max_uniq_toserver_src_groups; - uint16_t max_uniq_toserver_dst_groups; - uint16_t max_uniq_toserver_sp_groups; - uint16_t max_uniq_toserver_dp_groups; - - /* specify the configuration for mpm context factory */ - uint8_t sgh_mpm_context; - - /** hash table for looking up patterns for - * id sharing and id tracking. */ - MpmPatternIdStore *mpm_pattern_id_store; - uint16_t max_fp_id; - - MpmCtxFactoryContainer *mpm_ctx_factory_container; - - /* maximum recursion depth for content inspection */ - int inspection_recursion_limit; - - /* conf parameter that limits the length of the http request body inspected */ - int hcbd_buffer_limit; - /* conf parameter that limits the length of the http response body inspected */ - int hsbd_buffer_limit; - - /* array containing all sgh's in use so we can loop - * through it in Stage4. */ - struct SigGroupHead_ **sgh_array; - uint32_t sgh_array_cnt; - uint32_t sgh_array_size; - - int32_t sgh_mpm_context_proto_tcp_packet; - int32_t sgh_mpm_context_proto_udp_packet; - int32_t sgh_mpm_context_proto_other_packet; - int32_t sgh_mpm_context_stream; - int32_t sgh_mpm_context_uri; - int32_t sgh_mpm_context_hcbd; - int32_t sgh_mpm_context_hsbd; - int32_t sgh_mpm_context_hhd; - int32_t sgh_mpm_context_hrhd; - int32_t sgh_mpm_context_hmd; - int32_t sgh_mpm_context_hcd; - int32_t sgh_mpm_context_hrud; - int32_t sgh_mpm_context_hsmd; - int32_t sgh_mpm_context_hscd; - int32_t sgh_mpm_context_huad; - int32_t sgh_mpm_context_hhhd; - int32_t sgh_mpm_context_hrhhd; - int32_t sgh_mpm_context_app_proto_detect; - int32_t sgh_mpm_context_dnsquery; - int32_t sgh_mpm_context_smtp; - - /* the max local id used amongst all sigs */ - int32_t byte_extract_max_local_id; - - /* id used by every detect engine ctx instance */ - uint32_t id; - - /** sgh for signatures that match against invalid packets. In those cases - * we can't lookup by proto, address, port as we don't have these */ - struct SigGroupHead_ *decoder_event_sgh; - - /* Maximum size of the buffer for decoded base64 data. */ - uint32_t base64_decode_max_len; - - /** Store rule file and line so that parsers can use them in errors. */ - char *rule_file; - int rule_line; - - /** list of keywords that need thread local ctxs */ - DetectEngineThreadKeywordCtxItem *keyword_list; - int keyword_id; - - int detect_luajit_instances; - -#ifdef PROFILING - struct SCProfileDetectCtx_ *profile_ctx; - struct SCProfileKeywordDetectCtx_ *profile_keyword_ctx; - struct SCProfileKeywordDetectCtx_ *profile_keyword_ctx_per_list[DETECT_SM_LIST_MAX]; -#endif - - char config_prefix[64]; - - /** minimal: essentially a stub */ - int minimal; - - /** how many de_ctx' are referencing this */ - uint32_t ref_cnt; - /** list in master: either active or freelist */ - struct DetectEngineCtx_ *next; - - /** id of loader thread 'owning' this de_ctx */ - int loader_id; - -} DetectEngineCtx; - -/* Engine groups profiles (low, medium, high, custom) */ -enum { - ENGINE_PROFILE_UNKNOWN, - ENGINE_PROFILE_LOW, - ENGINE_PROFILE_MEDIUM, - ENGINE_PROFILE_HIGH, - ENGINE_PROFILE_CUSTOM, - ENGINE_PROFILE_MAX -}; - -/* Siggroup mpm context profile */ -enum { - ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL, - ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE, - ENGINE_SGH_MPM_FACTORY_CONTEXT_AUTO -}; - -typedef struct HttpReassembledBody_ { - uint8_t *buffer; - uint32_t buffer_size; /**< size of the buffer itself */ - uint32_t buffer_len; /**< data len in the buffer */ - uint64_t offset; /**< data offset */ -} HttpReassembledBody; - -typedef struct FiledataReassembledBody_ { - uint8_t *buffer; - uint32_t buffer_size; /**< size of the buffer itself */ - uint32_t buffer_len; /**< data len in the buffer */ - uint64_t offset; /**< data offset */ -} FiledataReassembledBody; - -#define DETECT_FILESTORE_MAX 15 -/** \todo review how many we actually need here */ -#define DETECT_SMSG_PMQ_NUM 256 - -/** - * Detection engine thread data. - */ -typedef struct DetectEngineThreadCtx_ { - /** \note multi-tenant hash lookup code from Detect() *depends* - * on this beeing the first member */ - uint32_t tenant_id; - - /* the thread to which this detection engine thread belongs */ - ThreadVars *tv; - - SigIntId *non_mpm_id_array; - uint32_t non_mpm_id_cnt; // size is cnt * sizeof(uint32_t) - - uint32_t mt_det_ctxs_cnt; - struct DetectEngineThreadCtx_ **mt_det_ctxs; - HashTable *mt_det_ctxs_hash; - - struct DetectEngineTenantMapping_ *tenant_array; - uint32_t tenant_array_size; - - uint32_t (*TenantGetId)(const void *, const Packet *p); - - /* detection engine variables */ - - /** offset into the payload of the last match by: - * content, pcre, etc */ - uint32_t buffer_offset; - /* used by pcre match function alone */ - uint32_t pcre_match_start_offset; - - /* counter for the filestore array below -- up here for cache reasons. */ - uint16_t filestore_cnt; - - /* bool to hint the POSTMATCH list members about the lock status of the - * flow. If locked this is TRUE, unlocked or no-flow: FALSE */ - uint8_t flow_locked; - - HttpReassembledBody *hsbd; - uint64_t hsbd_start_tx_id; - uint16_t hsbd_buffers_size; - uint16_t hsbd_buffers_list_len; - - HttpReassembledBody *hcbd; - uint64_t hcbd_start_tx_id; - uint16_t hcbd_buffers_size; - uint16_t hcbd_buffers_list_len; - - uint8_t **hhd_buffers; - uint32_t *hhd_buffers_len; - uint16_t hhd_buffers_size; - uint16_t hhd_buffers_list_len; - uint64_t hhd_start_tx_id; - - FiledataReassembledBody *smtp; - uint64_t smtp_start_tx_id; - uint16_t smtp_buffers_size; - uint16_t smtp_buffers_list_len; - - /** id for alert counter */ - uint16_t counter_alerts; -#ifdef PROFILING - uint16_t counter_mpm_list; - uint16_t counter_nonmpm_list; - uint16_t counter_fnonmpm_list; - uint16_t counter_match_list; -#endif - - /* used to discontinue any more matching */ - uint16_t discontinue_matching; - uint16_t flags; - - /* bool: if tx_id is set, this is 1, otherwise 0 */ - uint16_t tx_id_set; - /** ID of the transaction currently being inspected. */ - uint64_t tx_id; - - SC_ATOMIC_DECLARE(int, so_far_used_by_detect); - - /* holds the current recursion depth on content inspection */ - int inspection_recursion_counter; - - /** array of signature pointers we're going to inspect in the detection - * loop. */ - Signature **match_array; - /** size of the array in items (mem size if * sizeof(Signature *) - * Only used during initialization. */ - uint32_t match_array_len; - /** size in use */ - SigIntId match_array_cnt; - - /** Array of sigs that had a state change */ - SigIntId de_state_sig_array_len; - uint8_t *de_state_sig_array; - - struct SigGroupHead_ *sgh; - /** pointer to the current mpm ctx that is stored - * in a rule group head -- can be either a content - * or uricontent ctx. */ - MpmThreadCtx mtc; /**< thread ctx for the mpm */ - MpmThreadCtx mtcu; /**< thread ctx for uricontent mpm */ - MpmThreadCtx mtcs; /**< thread ctx for stream mpm */ - PatternMatcherQueue pmq; - PatternMatcherQueue smsg_pmq[DETECT_SMSG_PMQ_NUM]; - - /** ip only rules ctx */ - DetectEngineIPOnlyThreadCtx io_ctx; - - /* byte jump values */ - uint64_t *bj_values; - - /* string to replace */ - DetectReplaceList *replist; - /* flowvars to store in post match function */ - DetectFlowvarList *flowvarlist; - - /* Array in which the filestore keyword stores file id and tx id. If the - * full signature matches, these are processed by a post-match filestore - * function to finalize the store. */ - struct { - uint16_t file_id; - uint64_t tx_id; - } filestore[DETECT_FILESTORE_MAX]; - - DetectEngineCtx *de_ctx; - /** store for keyword contexts that need a per thread storage because of - * thread safety issues */ - void **keyword_ctxs_array; - int keyword_ctxs_size; - - uint8_t *base64_decoded; - int base64_decoded_len; - int base64_decoded_len_max; - -#ifdef PROFILING - struct SCProfileData_ *rule_perf_data; - int rule_perf_data_size; - struct SCProfileKeywordData_ *keyword_perf_data; - struct SCProfileKeywordData_ *keyword_perf_data_per_list[DETECT_SM_LIST_MAX]; - int keyword_perf_list; /**< list we're currently inspecting, DETECT_SM_LIST_* */ -#endif -} DetectEngineThreadCtx; - -/** \brief element in sigmatch type table. - * \note FileMatch pointer below takes a locked flow, AppLayerMatch an unlocked flow - */ -typedef struct SigTableElmt_ { - /** Packet match function pointer */ - int (*Match)(ThreadVars *, DetectEngineThreadCtx *, Packet *, Signature *, const SigMatchCtx *); - - /** AppLayer match function pointer */ - int (*AppLayerMatch)(ThreadVars *, DetectEngineThreadCtx *, Flow *, uint8_t flags, void *alstate, Signature *, SigMatch *); - - /** AppLayer TX match function pointer */ - int (*AppLayerTxMatch)(ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t flags, void *alstate, void *txv, - const Signature *, const SigMatchCtx *); - - /** File match function pointer */ - int (*FileMatch)(ThreadVars *, /**< thread local vars */ - DetectEngineThreadCtx *, - Flow *, /**< *LOCKED* flow */ - uint8_t flags, File *, Signature *, SigMatch *); - - /** app layer proto from app-layer-protos.h this match applies to */ - AppProto alproto; - - /** keyword setup function pointer */ - int (*Setup)(DetectEngineCtx *, Signature *, char *); - - void (*Free)(void *); - void (*RegisterTests)(void); - - uint8_t flags; - char *name; /**< keyword name alias */ - char *alias; /**< name alias */ - char *desc; - char *url; - -} SigTableElmt; - -#define SIG_GROUP_HEAD_MPM_URI (1) -#define SIG_GROUP_HEAD_MPM_HCBD (1 << 1) -#define SIG_GROUP_HEAD_MPM_HHD (1 << 2) -#define SIG_GROUP_HEAD_MPM_HRHD (1 << 3) -#define SIG_GROUP_HEAD_MPM_HMD (1 << 4) -#define SIG_GROUP_HEAD_MPM_HCD (1 << 5) -#define SIG_GROUP_HEAD_MPM_HRUD (1 << 6) -#define SIG_GROUP_HEAD_MPM_HSBD (1 << 7) -#define SIG_GROUP_HEAD_MPM_HSMD (1 << 8) -#define SIG_GROUP_HEAD_MPM_HSCD (1 << 9) -#define SIG_GROUP_HEAD_MPM_HUAD (1 << 10) -#define SIG_GROUP_HEAD_MPM_HHHD (1 << 11) -#define SIG_GROUP_HEAD_MPM_HRHHD (1 << 12) - -#define SIG_GROUP_HEAD_MPM_COPY (1 << 13) -#define SIG_GROUP_HEAD_MPM_URI_COPY (1 << 14) -#define SIG_GROUP_HEAD_MPM_STREAM_COPY (1 << 15) -#define SIG_GROUP_HEAD_FREE (1 << 16) -#define SIG_GROUP_HEAD_MPM_PACKET (1 << 17) -#define SIG_GROUP_HEAD_MPM_STREAM (1 << 18) -#define SIG_GROUP_HEAD_REFERENCED (1 << 19) /**< sgh is being referenced by others, don't clear */ -#define SIG_GROUP_HEAD_HAVEFILEMAGIC (1 << 20) -#define SIG_GROUP_HEAD_HAVEFILEMD5 (1 << 21) -#define SIG_GROUP_HEAD_HAVEFILESIZE (1 << 22) -#define SIG_GROUP_HEAD_MPM_DNSQUERY (1 << 23) -#define SIG_GROUP_HEAD_MPM_FD_SMTP (1 << 24) - -typedef struct SigGroupHeadInitData_ { - /* list of content containers */ - uint8_t *content_array; - uint32_t content_size; - uint8_t *uri_content_array; - uint32_t uri_content_size; - uint8_t *stream_content_array; - uint32_t stream_content_size; - - uint8_t *sig_array; /**< bit array of sig nums (internal id's) */ - uint32_t sig_size; /**< size in bytes */ - - /* port ptr */ - struct DetectPort_ *port; -} SigGroupHeadInitData; - -typedef struct SignatureNonMpmStore_ { - SigIntId id; - SignatureMask mask; -} SignatureNonMpmStore; - -/** \brief Container for matching data for a signature group */ -typedef struct SigGroupHead_ { - uint32_t flags; - /* number of sigs in this head */ - SigIntId sig_cnt; - - /* track min pattern length for content. Used in grouping */ - uint16_t mpm_content_minlen; - - /** array of masks, used to check multiple masks against - * a packet using SIMD. */ -#if defined(__SSE3__) || defined(__tile__) - SignatureMask *mask_array; -#endif - - SignatureNonMpmStore *non_mpm_store_array; // size is non_mpm_store_cnt * sizeof(SignatureNonMpmStore) - uint32_t non_mpm_store_cnt; - - /* pattern matcher instances */ - MpmCtx *mpm_proto_other_ctx; - - MpmCtx *mpm_proto_tcp_ctx_ts; - MpmCtx *mpm_proto_udp_ctx_ts; - MpmCtx *mpm_stream_ctx_ts; - MpmCtx *mpm_uri_ctx_ts; - MpmCtx *mpm_hcbd_ctx_ts; - MpmCtx *mpm_hhd_ctx_ts; - MpmCtx *mpm_hrhd_ctx_ts; - MpmCtx *mpm_hmd_ctx_ts; - MpmCtx *mpm_hcd_ctx_ts; - MpmCtx *mpm_hrud_ctx_ts; - MpmCtx *mpm_huad_ctx_ts; - MpmCtx *mpm_hhhd_ctx_ts; - MpmCtx *mpm_hrhhd_ctx_ts; - MpmCtx *mpm_dnsquery_ctx_ts; - MpmCtx *mpm_smtp_filedata_ctx_ts; - - MpmCtx *mpm_proto_tcp_ctx_tc; - MpmCtx *mpm_proto_udp_ctx_tc; - MpmCtx *mpm_stream_ctx_tc; - MpmCtx *mpm_hsbd_ctx_tc; - MpmCtx *mpm_hhd_ctx_tc; - MpmCtx *mpm_hrhd_ctx_tc; - MpmCtx *mpm_hcd_ctx_tc; - MpmCtx *mpm_hsmd_ctx_tc; - MpmCtx *mpm_hscd_ctx_tc; - - uint16_t mpm_uricontent_minlen; /**< len of shortest mpm pattern in sgh */ - - /** the number of signatures in this sgh that have the filestore keyword - * set. */ - uint16_t filestore_cnt; - - /** Array with sig ptrs... size is sig_cnt * sizeof(Signature *) */ - Signature **match_array; - - /* ptr to our init data we only use at... init :) */ - SigGroupHeadInitData *init; -} SigGroupHead; - -/** sigmatch has no options, so the parser shouldn't expect any */ -#define SIGMATCH_NOOPT (1 << 0) -/** sigmatch is compatible with a ip only rule */ -#define SIGMATCH_IPONLY_COMPAT (1 << 1) -/** sigmatch is compatible with a decode event only rule */ -#define SIGMATCH_DEONLY_COMPAT (1 << 2) -/**< Flag to indicate that the signature inspects the packet payload */ -#define SIGMATCH_PAYLOAD (1 << 3) -/**< Flag to indicate that the signature is not built-in */ -#define SIGMATCH_NOT_BUILT (1 << 4) -/** sigmatch may have options, so the parser should be ready to - * deal with both cases */ -#define SIGMATCH_OPTIONAL_OPT (1 << 5) - -enum DetectEngineTenantSelectors -{ - TENANT_SELECTOR_UNKNOWN = 0, /**< not set */ - TENANT_SELECTOR_DIRECT, /**< method provides direct tenant id */ - TENANT_SELECTOR_VLAN, /**< map vlan to tenant id */ -}; - -typedef struct DetectEngineTenantMapping_ { - uint32_t tenant_id; - - /* traffic id that maps to the tenant id */ - uint32_t traffic_id; - - struct DetectEngineTenantMapping_ *next; -} DetectEngineTenantMapping; - -typedef struct DetectEngineMasterCtx_ { - SCMutex lock; - - /** enable multi tenant mode */ - int multi_tenant_enabled; - - /** list of active detection engines. This list is used to generate the - * threads det_ctx's */ - DetectEngineCtx *list; - - /** free list, containing detection engines that will be removed but may - * still be referenced by det_ctx's. Freed as soon as all references are - * gone. */ - DetectEngineCtx *free_list; - - enum DetectEngineTenantSelectors tenant_selector; - - /** list of tenant mappings. Updated under lock. Used to generate lookup - * structures. */ - DetectEngineTenantMapping *tenant_mapping_list; - -} DetectEngineMasterCtx; - -/** \brief Signature loader statistics */ -typedef struct SigFileLoaderStat_ { - int bad_files; - int total_files; - int good_sigs_total; - int bad_sigs_total; -} SigFileLoaderStat; - -/** Remember to add the options in SignatureIsIPOnly() at detect.c otherwise it wont be part of a signature group */ - -enum { - DETECT_SID, - DETECT_PRIORITY, - DETECT_REV, - DETECT_CLASSTYPE, - DETECT_THRESHOLD, - DETECT_METADATA, - DETECT_REFERENCE, - DETECT_TAG, - DETECT_MSG, - DETECT_CONTENT, - DETECT_URICONTENT, - DETECT_PCRE, - DETECT_ACK, - DETECT_SEQ, - DETECT_DEPTH, - DETECT_DISTANCE, - DETECT_WITHIN, - DETECT_OFFSET, - DETECT_REPLACE, - DETECT_NOCASE, - DETECT_FAST_PATTERN, - DETECT_RAWBYTES, - DETECT_BYTETEST, - DETECT_BYTEJUMP, - DETECT_SAMEIP, - DETECT_GEOIP, - DETECT_IPPROTO, - DETECT_FLOW, - DETECT_WINDOW, - DETECT_FTPBOUNCE, - DETECT_ISDATAAT, - DETECT_ID, - DETECT_RPC, - DETECT_DSIZE, - DETECT_FLOWVAR, - DETECT_FLOWVAR_POSTMATCH, - DETECT_FLOWINT, - DETECT_PKTVAR, - DETECT_NOALERT, - DETECT_FLOWBITS, - DETECT_HOSTBITS, - DETECT_IPV4_CSUM, - DETECT_TCPV4_CSUM, - DETECT_TCPV6_CSUM, - DETECT_UDPV4_CSUM, - DETECT_UDPV6_CSUM, - DETECT_ICMPV4_CSUM, - DETECT_ICMPV6_CSUM, - DETECT_STREAM_SIZE, - DETECT_TTL, - DETECT_ITYPE, - DETECT_ICODE, - DETECT_TOS, - DETECT_ICMP_ID, - DETECT_ICMP_SEQ, - DETECT_DETECTION_FILTER, - - DETECT_DECODE_EVENT, - DETECT_IPOPTS, - DETECT_FLAGS, - DETECT_FRAGBITS, - DETECT_FRAGOFFSET, - DETECT_GID, - DETECT_MARK, - - DETECT_AL_TLS_VERSION, - DETECT_AL_TLS_SUBJECT, - DETECT_AL_TLS_ISSUERDN, - DETECT_AL_TLS_FINGERPRINT, - DETECT_AL_TLS_STORE, - - DETECT_AL_HTTP_COOKIE, - DETECT_AL_HTTP_METHOD, - DETECT_AL_URILEN, - DETECT_AL_HTTP_CLIENT_BODY, - DETECT_AL_HTTP_SERVER_BODY, - DETECT_AL_HTTP_HEADER, - DETECT_AL_HTTP_RAW_HEADER, - DETECT_AL_HTTP_URI, - DETECT_AL_HTTP_RAW_URI, - DETECT_AL_HTTP_STAT_MSG, - DETECT_AL_HTTP_STAT_CODE, - DETECT_AL_HTTP_USER_AGENT, - DETECT_AL_HTTP_HOST, - DETECT_AL_HTTP_RAW_HOST, - DETECT_AL_SSH_PROTOVERSION, - DETECT_AL_SSH_SOFTWAREVERSION, - DETECT_AL_SSL_VERSION, - DETECT_AL_SSL_STATE, - DETECT_BYTE_EXTRACT, - DETECT_FILE_DATA, - DETECT_PKT_DATA, - DETECT_AL_APP_LAYER_EVENT, - DETECT_AL_APP_LAYER_PROTOCOL, - - DETECT_DCE_IFACE, - DETECT_DCE_OPNUM, - DETECT_DCE_STUB_DATA, - - DETECT_ASN1, - - DETECT_ENGINE_EVENT, - DETECT_STREAM_EVENT, - - DETECT_FILENAME, - DETECT_FILEEXT, - DETECT_FILESTORE, - DETECT_FILEMAGIC, - DETECT_FILEMD5, - DETECT_FILESIZE, - - DETECT_L3PROTO, - DETECT_LUA, - DETECT_IPREP, - - DETECT_AL_DNS_QUERY, - DETECT_AL_MODBUS, - - DETECT_XBITS, - DETECT_BASE64_DECODE, - DETECT_BASE64_DATA, - - DETECT_TEMPLATE, - DETECT_AL_TEMPLATE_BUFFER, - - /* make sure this stays last */ - DETECT_TBLSIZE, -}; - -/* Table with all SigMatch registrations */ -SigTableElmt sigmatch_table[DETECT_TBLSIZE]; - -/* detection api */ -SigMatch *SigMatchAlloc(void); -Signature *SigFindSignatureBySidGid(DetectEngineCtx *, uint32_t, uint32_t); -void SigMatchSignaturesBuildMatchArray(DetectEngineThreadCtx *, - Packet *, SignatureMask, - uint16_t); -void SigMatchFree(SigMatch *sm); -void SigCleanSignatures(DetectEngineCtx *); - -void SigTableRegisterTests(void); -void SigRegisterTests(void); -void DetectSimdRegisterTests(void); -void TmModuleDetectRegister (void); - -int SigGroupBuild(DetectEngineCtx *); -int SigGroupCleanup (DetectEngineCtx *de_ctx); -void SigAddressPrepareBidirectionals (DetectEngineCtx *); - -char *DetectLoadCompleteSigPath(const DetectEngineCtx *, char *sig_file); -int SigLoadSignatures (DetectEngineCtx *, char *, int); -void SigTableList(const char *keyword); -void SigTableSetup(void); -int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, - DetectEngineThreadCtx *det_ctx, Packet *p); - -int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s); -SigGroupHead *SigMatchSignaturesGetSgh(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p); - -Signature *DetectGetTagSignature(void); - -int SignatureIsFilestoring(Signature *); -int SignatureIsFilemagicInspecting(Signature *); -int SignatureIsFileMd5Inspecting(Signature *); -int SignatureIsFilesizeInspecting(Signature *); - -int DetectRegisterThreadCtxFuncs(DetectEngineCtx *, const char *name, void *(*InitFunc)(void *), void *data, void (*FreeFunc)(void *), int); -void *DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *, int); - -int SigMatchSignaturesRunPostMatch(ThreadVars *tv, - DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p, - Signature *s); -void DetectSignatureApplyActions(Packet *p, const Signature *s); - -#endif /* __DETECT_H__ */ - diff --git a/framework/src/suricata/src/flow-bit.c b/framework/src/suricata/src/flow-bit.c deleted file mode 100644 index 2e52b9ef..00000000 --- a/framework/src/suricata/src/flow-bit.c +++ /dev/null @@ -1,483 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements per flow bits. Actually, not a bit, - * but called that way because of Snort's flowbits. - * It's a binary storage. - * - * \todo move away from a linked list implementation - * \todo use different datatypes, such as string, int, etc. - * \todo have more than one instance of the same var, and be able to match on a - * specific one, or one all at a time. So if a certain capture matches - * multiple times, we can operate on all of them. - */ - -#include "suricata-common.h" -#include "threads.h" -#include "flow-bit.h" -#include "flow.h" -#include "flow-util.h" -#include "flow-private.h" -#include "detect.h" -#include "util-var.h" -#include "util-debug.h" -#include "util-unittest.h" - -/* get the flowbit with idx from the flow */ -static FlowBit *FlowBitGet(Flow *f, uint16_t idx) -{ - GenericVar *gv = f->flowvar; - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_FLOWBITS && gv->idx == idx) { - return (FlowBit *)gv; - } - } - - return NULL; -} - -/* add a flowbit to the flow */ -static void FlowBitAdd(Flow *f, uint16_t idx) -{ - FlowBit *fb = FlowBitGet(f, idx); - if (fb == NULL) { - fb = SCMalloc(sizeof(FlowBit)); - if (unlikely(fb == NULL)) - return; - - fb->type = DETECT_FLOWBITS; - fb->idx = idx; - fb->next = NULL; - GenericVarAppend(&f->flowvar, (GenericVar *)fb); - - //printf("FlowBitAdd: adding flowbit with idx %" PRIu32 "\n", idx); -#ifdef FLOWBITS_STATS - SCMutexLock(&flowbits_mutex); - flowbits_added++; - flowbits_memuse += sizeof(FlowBit); - if (flowbits_memuse > flowbits_memuse_max) - flowbits_memuse_max = flowbits_memuse; - SCMutexUnlock(&flowbits_mutex); -#endif /* FLOWBITS_STATS */ - } -} - -static void FlowBitRemove(Flow *f, uint16_t idx) -{ - FlowBit *fb = FlowBitGet(f, idx); - if (fb == NULL) - return; - - GenericVarRemove(&f->flowvar, (GenericVar *)fb); - - //printf("FlowBitRemove: remove flowbit with idx %" PRIu32 "\n", idx); -#ifdef FLOWBITS_STATS - SCMutexLock(&flowbits_mutex); - flowbits_removed++; - if (flowbits_memuse >= sizeof(FlowBit)) - flowbits_memuse -= sizeof(FlowBit); - else { - printf("ERROR: flowbits memory usage going below 0!\n"); - flowbits_memuse = 0; - } - SCMutexUnlock(&flowbits_mutex); -#endif /* FLOWBITS_STATS */ -} - -void FlowBitSetNoLock(Flow *f, uint16_t idx) -{ - FlowBit *fb = FlowBitGet(f, idx); - if (fb == NULL) { - FlowBitAdd(f, idx); - } -} - -void FlowBitSet(Flow *f, uint16_t idx) -{ - FLOWLOCK_WRLOCK(f); - FlowBitSetNoLock(f, idx); - FLOWLOCK_UNLOCK(f); -} - -void FlowBitUnsetNoLock(Flow *f, uint16_t idx) -{ - FlowBit *fb = FlowBitGet(f, idx); - if (fb != NULL) { - FlowBitRemove(f, idx); - } -} - -void FlowBitUnset(Flow *f, uint16_t idx) -{ - FLOWLOCK_WRLOCK(f); - FlowBitUnsetNoLock(f, idx); - FLOWLOCK_UNLOCK(f); -} - -void FlowBitToggleNoLock(Flow *f, uint16_t idx) -{ - FlowBit *fb = FlowBitGet(f, idx); - if (fb != NULL) { - FlowBitRemove(f, idx); - } else { - FlowBitAdd(f, idx); - } -} - -void FlowBitToggle(Flow *f, uint16_t idx) -{ - FLOWLOCK_WRLOCK(f); - FlowBitToggleNoLock(f, idx); - FLOWLOCK_UNLOCK(f); -} - -int FlowBitIsset(Flow *f, uint16_t idx) -{ - int r = 0; - FLOWLOCK_RDLOCK(f); - - FlowBit *fb = FlowBitGet(f, idx); - if (fb != NULL) { - r = 1; - } - - FLOWLOCK_UNLOCK(f); - return r; -} - -int FlowBitIsnotset(Flow *f, uint16_t idx) -{ - int r = 0; - FLOWLOCK_RDLOCK(f); - - FlowBit *fb = FlowBitGet(f, idx); - if (fb == NULL) { - r = 1; - } - - FLOWLOCK_UNLOCK(f); - return r; -} - -void FlowBitFree(FlowBit *fb) -{ - if (fb == NULL) - return; - - SCFree(fb); - -#ifdef FLOWBITS_STATS - SCMutexLock(&flowbits_mutex); - flowbits_removed++; - if (flowbits_memuse >= sizeof(FlowBit)) - flowbits_memuse -= sizeof(FlowBit); - else { - printf("ERROR: flowbits memory usage going below 0!\n"); - flowbits_memuse = 0; - } - SCMutexUnlock(&flowbits_mutex); -#endif /* FLOWBITS_STATS */ -} - - -/* TESTS */ -#ifdef UNITTESTS -static int FlowBitTest01 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - - FlowBit *fb = FlowBitGet(&f,0); - if (fb != NULL) - ret = 1; - - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest02 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBit *fb = FlowBitGet(&f,0); - if (fb == NULL) - ret = 1; - - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest03 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - - FlowBit *fb = FlowBitGet(&f,0); - if (fb == NULL) { - printf("fb == NULL although it was just added: "); - goto end; - } - - FlowBitRemove(&f, 0); - - fb = FlowBitGet(&f,0); - if (fb != NULL) { - printf("fb != NULL although it was just removed: "); - goto end; - } else { - ret = 1; - } -end: - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest04 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - FlowBitAdd(&f, 1); - FlowBitAdd(&f, 2); - FlowBitAdd(&f, 3); - - FlowBit *fb = FlowBitGet(&f,0); - if (fb != NULL) - ret = 1; - - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest05 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - FlowBitAdd(&f, 1); - FlowBitAdd(&f, 2); - FlowBitAdd(&f, 3); - - FlowBit *fb = FlowBitGet(&f,1); - if (fb != NULL) - ret = 1; - - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest06 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - FlowBitAdd(&f, 1); - FlowBitAdd(&f, 2); - FlowBitAdd(&f, 3); - - FlowBit *fb = FlowBitGet(&f,2); - if (fb != NULL) - ret = 1; - - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest07 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - FlowBitAdd(&f, 1); - FlowBitAdd(&f, 2); - FlowBitAdd(&f, 3); - - FlowBit *fb = FlowBitGet(&f,3); - if (fb != NULL) - ret = 1; - - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest08 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - FlowBitAdd(&f, 1); - FlowBitAdd(&f, 2); - FlowBitAdd(&f, 3); - - FlowBit *fb = FlowBitGet(&f,0); - if (fb == NULL) - goto end; - - FlowBitRemove(&f,0); - - fb = FlowBitGet(&f,0); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; -end: - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest09 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - FlowBitAdd(&f, 1); - FlowBitAdd(&f, 2); - FlowBitAdd(&f, 3); - - FlowBit *fb = FlowBitGet(&f,1); - if (fb == NULL) - goto end; - - FlowBitRemove(&f,1); - - fb = FlowBitGet(&f,1); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; -end: - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest10 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - FlowBitAdd(&f, 1); - FlowBitAdd(&f, 2); - FlowBitAdd(&f, 3); - - FlowBit *fb = FlowBitGet(&f,2); - if (fb == NULL) - goto end; - - FlowBitRemove(&f,2); - - fb = FlowBitGet(&f,2); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; -end: - GenericVarFree(f.flowvar); - return ret; -} - -static int FlowBitTest11 (void) -{ - int ret = 0; - - Flow f; - memset(&f, 0, sizeof(Flow)); - - FlowBitAdd(&f, 0); - FlowBitAdd(&f, 1); - FlowBitAdd(&f, 2); - FlowBitAdd(&f, 3); - - FlowBit *fb = FlowBitGet(&f,3); - if (fb == NULL) - goto end; - - FlowBitRemove(&f,3); - - fb = FlowBitGet(&f,3); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; -end: - GenericVarFree(f.flowvar); - return ret; -} - -#endif /* UNITTESTS */ - -void FlowBitRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("FlowBitTest01", FlowBitTest01, 1); - UtRegisterTest("FlowBitTest02", FlowBitTest02, 1); - UtRegisterTest("FlowBitTest03", FlowBitTest03, 1); - UtRegisterTest("FlowBitTest04", FlowBitTest04, 1); - UtRegisterTest("FlowBitTest05", FlowBitTest05, 1); - UtRegisterTest("FlowBitTest06", FlowBitTest06, 1); - UtRegisterTest("FlowBitTest07", FlowBitTest07, 1); - UtRegisterTest("FlowBitTest08", FlowBitTest08, 1); - UtRegisterTest("FlowBitTest09", FlowBitTest09, 1); - UtRegisterTest("FlowBitTest10", FlowBitTest10, 1); - UtRegisterTest("FlowBitTest11", FlowBitTest11, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/flow-bit.h b/framework/src/suricata/src/flow-bit.h deleted file mode 100644 index 1b966a00..00000000 --- a/framework/src/suricata/src/flow-bit.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __FLOW_BIT_H__ -#define __FLOW_BIT_H__ - -#include "flow.h" -#include "util-var.h" - -typedef struct FlowBit_ { - uint8_t type; /* type, DETECT_FLOWBITS in this case */ - uint16_t idx; /* name idx */ - GenericVar *next; /* right now just implement this as a list, - * in the long run we have think of something - * faster. */ -} FlowBit; - -void FlowBitFree(FlowBit *); -void FlowBitRegisterTests(void); - -void FlowBitSetNoLock(Flow *, uint16_t); -void FlowBitSet(Flow *, uint16_t); -void FlowBitUnsetNoLock(Flow *, uint16_t); -void FlowBitUnset(Flow *, uint16_t); -void FlowBitToggleNoLock(Flow *, uint16_t); -void FlowBitToggle(Flow *, uint16_t); -int FlowBitIsset(Flow *, uint16_t); -int FlowBitIsnotset(Flow *, uint16_t); -#endif /* __FLOW_BIT_H__ */ - diff --git a/framework/src/suricata/src/flow-hash.c b/framework/src/suricata/src/flow-hash.c deleted file mode 100644 index 9ddb3713..00000000 --- a/framework/src/suricata/src/flow-hash.c +++ /dev/null @@ -1,860 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon Crespo - * - * Flow Hashing functions. - */ - -#include "suricata-common.h" -#include "threads.h" - -#include "decode.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-hash.h" -#include "flow-util.h" -#include "flow-private.h" -#include "flow-manager.h" -#include "flow-storage.h" -#include "app-layer-parser.h" - -#include "util-time.h" -#include "util-debug.h" - -#include "util-hash-lookup3.h" - -#include "conf.h" -#include "output.h" -#include "output-flow.h" - -#define FLOW_DEFAULT_FLOW_PRUNE 5 - -SC_ATOMIC_EXTERN(unsigned int, flow_prune_idx); -SC_ATOMIC_EXTERN(unsigned int, flow_flags); - -static Flow *FlowGetUsedFlow(ThreadVars *tv, DecodeThreadVars *dtv); -static int handle_tcp_reuse = 1; - -#ifdef FLOW_DEBUG_STATS -#define FLOW_DEBUG_STATS_PROTO_ALL 0 -#define FLOW_DEBUG_STATS_PROTO_TCP 1 -#define FLOW_DEBUG_STATS_PROTO_UDP 2 -#define FLOW_DEBUG_STATS_PROTO_ICMP 3 -#define FLOW_DEBUG_STATS_PROTO_OTHER 4 - -static uint64_t flow_hash_count[5] = { 0, 0, 0, 0, 0 }; /* how often are we looking for a hash */ -static uint64_t flow_hash_loop_count[5] = { 0, 0, 0, 0, 0 }; /* how often do we loop through a hash bucket */ -static FILE *flow_hash_count_fp = NULL; -static SCSpinlock flow_hash_count_lock; - -#define FlowHashCountUpdate do { \ - SCSpinLock(&flow_hash_count_lock); \ - flow_hash_count[FLOW_DEBUG_STATS_PROTO_ALL]++; \ - flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ALL] += _flow_hash_counter; \ - if (f != NULL) { \ - if (p->proto == IPPROTO_TCP) { \ - flow_hash_count[FLOW_DEBUG_STATS_PROTO_TCP]++; \ - flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_TCP] += _flow_hash_counter; \ - } else if (p->proto == IPPROTO_UDP) {\ - flow_hash_count[FLOW_DEBUG_STATS_PROTO_UDP]++; \ - flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_UDP] += _flow_hash_counter; \ - } else if (p->proto == IPPROTO_ICMP) {\ - flow_hash_count[FLOW_DEBUG_STATS_PROTO_ICMP]++; \ - flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ICMP] += _flow_hash_counter; \ - } else {\ - flow_hash_count[FLOW_DEBUG_STATS_PROTO_OTHER]++; \ - flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_OTHER] += _flow_hash_counter; \ - } \ - } \ - SCSpinUnlock(&flow_hash_count_lock); \ -} while(0); - -#define FlowHashCountInit uint64_t _flow_hash_counter = 0 -#define FlowHashCountIncr _flow_hash_counter++; - -void FlowHashDebugInit(void) -{ -#ifdef FLOW_DEBUG_STATS - SCSpinInit(&flow_hash_count_lock, 0); -#endif - flow_hash_count_fp = fopen("flow-debug.log", "w+"); - if (flow_hash_count_fp != NULL) { - fprintf(flow_hash_count_fp, "ts,all,tcp,udp,icmp,other\n"); - } -} - -void FlowHashDebugPrint(uint32_t ts) -{ -#ifdef FLOW_DEBUG_STATS - if (flow_hash_count_fp == NULL) - return; - - float avg_all = 0, avg_tcp = 0, avg_udp = 0, avg_icmp = 0, avg_other = 0; - SCSpinLock(&flow_hash_count_lock); - if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ALL] != 0) - avg_all = (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ALL]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_ALL])); - if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_TCP] != 0) - avg_tcp = (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_TCP]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_TCP])); - if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_UDP] != 0) - avg_udp = (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_UDP]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_UDP])); - if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ICMP] != 0) - avg_icmp= (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_ICMP]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_ICMP])); - if (flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_OTHER] != 0) - avg_other= (float)(flow_hash_loop_count[FLOW_DEBUG_STATS_PROTO_OTHER]/(float)(flow_hash_count[FLOW_DEBUG_STATS_PROTO_OTHER])); - fprintf(flow_hash_count_fp, "%"PRIu32",%02.3f,%02.3f,%02.3f,%02.3f,%02.3f\n", ts, avg_all, avg_tcp, avg_udp, avg_icmp, avg_other); - fflush(flow_hash_count_fp); - memset(&flow_hash_count, 0, sizeof(flow_hash_count)); - memset(&flow_hash_loop_count, 0, sizeof(flow_hash_loop_count)); - SCSpinUnlock(&flow_hash_count_lock); -#endif -} - -void FlowHashDebugDeinit(void) -{ -#ifdef FLOW_DEBUG_STATS - struct timeval ts; - memset(&ts, 0, sizeof(ts)); - TimeGet(&ts); - FlowHashDebugPrint((uint32_t)ts.tv_sec); - if (flow_hash_count_fp != NULL) - fclose(flow_hash_count_fp); - SCSpinDestroy(&flow_hash_count_lock); -#endif -} - -#else - -#define FlowHashCountUpdate -#define FlowHashCountInit -#define FlowHashCountIncr - -#endif /* FLOW_DEBUG_STATS */ - -void FlowDisableTcpReuseHandling(void) -{ - handle_tcp_reuse = 0; -} - -/** \brief compare two raw ipv6 addrs - * - * \note we don't care about the real ipv6 ip's, this is just - * to consistently fill the FlowHashKey6 struct, without all - * the ntohl calls. - * - * \warning do not use elsewhere unless you know what you're doing. - * detect-engine-address-ipv6.c's AddressIPv6GtU32 is likely - * what you are looking for. - */ -static inline int FlowHashRawAddressIPv6GtU32(const uint32_t *a, const uint32_t *b) -{ - int i; - - for (i = 0; i < 4; i++) { - if (a[i] > b[i]) - return 1; - if (a[i] < b[i]) - break; - } - - return 0; -} - -typedef struct FlowHashKey4_ { - union { - struct { - uint32_t src, dst; - uint16_t sp, dp; - uint16_t proto; /**< u16 so proto and recur add up to u32 */ - uint16_t recur; /**< u16 so proto and recur add up to u32 */ - uint16_t vlan_id[2]; - }; - const uint32_t u32[5]; - }; -} FlowHashKey4; - -typedef struct FlowHashKey6_ { - union { - struct { - uint32_t src[4], dst[4]; - uint16_t sp, dp; - uint16_t proto; /**< u16 so proto and recur add up to u32 */ - uint16_t recur; /**< u16 so proto and recur add up to u32 */ - uint16_t vlan_id[2]; - }; - const uint32_t u32[11]; - }; -} FlowHashKey6; - -/* calculate the hash key for this packet - * - * we're using: - * hash_rand -- set at init time - * source port - * destination port - * source address - * destination address - * recursion level -- for tunnels, make sure different tunnel layers can - * never get mixed up. - * - * For ICMP we only consider UNREACHABLE errors atm. - */ -static inline uint32_t FlowGetKey(const Packet *p) -{ - uint32_t key; - - if (p->ip4h != NULL) { - if (p->tcph != NULL || p->udph != NULL) { - FlowHashKey4 fhk; - if (p->src.addr_data32[0] > p->dst.addr_data32[0]) { - fhk.src = p->src.addr_data32[0]; - fhk.dst = p->dst.addr_data32[0]; - } else { - fhk.src = p->dst.addr_data32[0]; - fhk.dst = p->src.addr_data32[0]; - } - if (p->sp > p->dp) { - fhk.sp = p->sp; - fhk.dp = p->dp; - } else { - fhk.sp = p->dp; - fhk.dp = p->sp; - } - fhk.proto = (uint16_t)p->proto; - fhk.recur = (uint16_t)p->recursion_level; - fhk.vlan_id[0] = p->vlan_id[0]; - fhk.vlan_id[1] = p->vlan_id[1]; - - uint32_t hash = hashword(fhk.u32, 5, flow_config.hash_rand); - key = hash % flow_config.hash_size; - - } else if (ICMPV4_DEST_UNREACH_IS_VALID(p)) { - uint32_t psrc = IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p)); - uint32_t pdst = IPV4_GET_RAW_IPDST_U32(ICMPV4_GET_EMB_IPV4(p)); - FlowHashKey4 fhk; - if (psrc > pdst) { - fhk.src = psrc; - fhk.dst = pdst; - } else { - fhk.src = pdst; - fhk.dst = psrc; - } - if (p->icmpv4vars.emb_sport > p->icmpv4vars.emb_dport) { - fhk.sp = p->icmpv4vars.emb_sport; - fhk.dp = p->icmpv4vars.emb_dport; - } else { - fhk.sp = p->icmpv4vars.emb_dport; - fhk.dp = p->icmpv4vars.emb_sport; - } - fhk.proto = (uint16_t)ICMPV4_GET_EMB_PROTO(p); - fhk.recur = (uint16_t)p->recursion_level; - fhk.vlan_id[0] = p->vlan_id[0]; - fhk.vlan_id[1] = p->vlan_id[1]; - - uint32_t hash = hashword(fhk.u32, 5, flow_config.hash_rand); - key = hash % flow_config.hash_size; - - } else { - FlowHashKey4 fhk; - if (p->src.addr_data32[0] > p->dst.addr_data32[0]) { - fhk.src = p->src.addr_data32[0]; - fhk.dst = p->dst.addr_data32[0]; - } else { - fhk.src = p->dst.addr_data32[0]; - fhk.dst = p->src.addr_data32[0]; - } - fhk.sp = 0xfeed; - fhk.dp = 0xbeef; - fhk.proto = (uint16_t)p->proto; - fhk.recur = (uint16_t)p->recursion_level; - fhk.vlan_id[0] = p->vlan_id[0]; - fhk.vlan_id[1] = p->vlan_id[1]; - - uint32_t hash = hashword(fhk.u32, 5, flow_config.hash_rand); - key = hash % flow_config.hash_size; - } - } else if (p->ip6h != NULL) { - FlowHashKey6 fhk; - if (FlowHashRawAddressIPv6GtU32(p->src.addr_data32, p->dst.addr_data32)) { - fhk.src[0] = p->src.addr_data32[0]; - fhk.src[1] = p->src.addr_data32[1]; - fhk.src[2] = p->src.addr_data32[2]; - fhk.src[3] = p->src.addr_data32[3]; - fhk.dst[0] = p->dst.addr_data32[0]; - fhk.dst[1] = p->dst.addr_data32[1]; - fhk.dst[2] = p->dst.addr_data32[2]; - fhk.dst[3] = p->dst.addr_data32[3]; - } else { - fhk.src[0] = p->dst.addr_data32[0]; - fhk.src[1] = p->dst.addr_data32[1]; - fhk.src[2] = p->dst.addr_data32[2]; - fhk.src[3] = p->dst.addr_data32[3]; - fhk.dst[0] = p->src.addr_data32[0]; - fhk.dst[1] = p->src.addr_data32[1]; - fhk.dst[2] = p->src.addr_data32[2]; - fhk.dst[3] = p->src.addr_data32[3]; - } - if (p->sp > p->dp) { - fhk.sp = p->sp; - fhk.dp = p->dp; - } else { - fhk.sp = p->dp; - fhk.dp = p->sp; - } - fhk.proto = (uint16_t)p->proto; - fhk.recur = (uint16_t)p->recursion_level; - fhk.vlan_id[0] = p->vlan_id[0]; - fhk.vlan_id[1] = p->vlan_id[1]; - - uint32_t hash = hashword(fhk.u32, 11, flow_config.hash_rand); - key = hash % flow_config.hash_size; - } else - key = 0; - - return key; -} - -/* Since two or more flows can have the same hash key, we need to compare - * the flow with the current flow key. */ -#define CMP_FLOW(f1,f2) \ - (((CMP_ADDR(&(f1)->src, &(f2)->src) && \ - CMP_ADDR(&(f1)->dst, &(f2)->dst) && \ - CMP_PORT((f1)->sp, (f2)->sp) && CMP_PORT((f1)->dp, (f2)->dp)) || \ - (CMP_ADDR(&(f1)->src, &(f2)->dst) && \ - CMP_ADDR(&(f1)->dst, &(f2)->src) && \ - CMP_PORT((f1)->sp, (f2)->dp) && CMP_PORT((f1)->dp, (f2)->sp))) && \ - (f1)->proto == (f2)->proto && \ - (f1)->recursion_level == (f2)->recursion_level && \ - (f1)->vlan_id[0] == (f2)->vlan_id[0] && \ - (f1)->vlan_id[1] == (f2)->vlan_id[1]) - -/** - * \brief See if a ICMP packet belongs to a flow by comparing the embedded - * packet in the ICMP error packet to the flow. - * - * \param f flow - * \param p ICMP packet - * - * \retval 1 match - * \retval 0 no match - */ -static inline int FlowCompareICMPv4(Flow *f, const Packet *p) -{ - if (ICMPV4_DEST_UNREACH_IS_VALID(p)) { - /* first check the direction of the flow, in other words, the client -> - * server direction as it's most likely the ICMP error will be a - * response to the clients traffic */ - if ((f->src.addr_data32[0] == IPV4_GET_RAW_IPSRC_U32( ICMPV4_GET_EMB_IPV4(p) )) && - (f->dst.addr_data32[0] == IPV4_GET_RAW_IPDST_U32( ICMPV4_GET_EMB_IPV4(p) )) && - f->sp == p->icmpv4vars.emb_sport && - f->dp == p->icmpv4vars.emb_dport && - f->proto == ICMPV4_GET_EMB_PROTO(p) && - f->recursion_level == p->recursion_level && - f->vlan_id[0] == p->vlan_id[0] && - f->vlan_id[1] == p->vlan_id[1]) - { - return 1; - - /* check the less likely case where the ICMP error was a response to - * a packet from the server. */ - } else if ((f->dst.addr_data32[0] == IPV4_GET_RAW_IPSRC_U32( ICMPV4_GET_EMB_IPV4(p) )) && - (f->src.addr_data32[0] == IPV4_GET_RAW_IPDST_U32( ICMPV4_GET_EMB_IPV4(p) )) && - f->dp == p->icmpv4vars.emb_sport && - f->sp == p->icmpv4vars.emb_dport && - f->proto == ICMPV4_GET_EMB_PROTO(p) && - f->recursion_level == p->recursion_level && - f->vlan_id[0] == p->vlan_id[0] && - f->vlan_id[1] == p->vlan_id[1]) - { - return 1; - } - - /* no match, fall through */ - } else { - /* just treat ICMP as a normal proto for now */ - return CMP_FLOW(f, p); - } - - return 0; -} - -int TcpSessionPacketSsnReuse(const Packet *p, const Flow *f, void *tcp_ssn); - -static inline int FlowCompare(Flow *f, const Packet *p) -{ - if (p->proto == IPPROTO_ICMP) { - return FlowCompareICMPv4(f, p); - } else if (p->proto == IPPROTO_TCP) { - if (CMP_FLOW(f, p) == 0) - return 0; - - /* if this session is 'reused', we don't return it anymore, - * so return false on the compare */ - if (f->flags & FLOW_TCP_REUSED) - return 0; - - if (handle_tcp_reuse == 1) { - /* lets see if we need to consider the existing session reuse */ - if (unlikely(TcpSessionPacketSsnReuse(p, f, f->protoctx) == 1)) { - /* okay, we need to setup a new flow for this packet. - * Flag the flow that it's been replaced by a new one */ - f->flags |= FLOW_TCP_REUSED; - SCLogDebug("flow obsolete: TCP reuse will use a new flow " - "starting with packet %"PRIu64, p->pcap_cnt); - return 0; - } - } - return 1; - } else { - return CMP_FLOW(f, p); - } -} - -/** - * \brief Check if we should create a flow based on a packet - * - * We use this check to filter out flow creation based on: - * - ICMP error messages - * - * \param p packet - * \retval 1 true - * \retval 0 false - */ -static inline int FlowCreateCheck(const Packet *p) -{ - if (PKT_IS_ICMPV4(p)) { - if (ICMPV4_IS_ERROR_MSG(p)) { - return 0; - } - } - - return 1; -} - -/** - * \brief Get a new flow - * - * Get a new flow. We're checking memcap first and will try to make room - * if the memcap is reached. - * - * \param tv thread vars - * \param dtv decode thread vars (for flow log api thread data) - * - * \retval f *LOCKED* flow on succes, NULL on error. - */ -static Flow *FlowGetNew(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p) -{ - Flow *f = NULL; - - if (FlowCreateCheck(p) == 0) { - return NULL; - } - - /* get a flow from the spare queue */ - f = FlowDequeue(&flow_spare_q); - if (f == NULL) { - /* If we reached the max memcap, we get a used flow */ - if (!(FLOW_CHECK_MEMCAP(sizeof(Flow) + FlowStorageSize()))) { - /* declare state of emergency */ - if (!(SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)) { - SC_ATOMIC_OR(flow_flags, FLOW_EMERGENCY); - - /* under high load, waking up the flow mgr each time leads - * to high cpu usage. Flows are not timed out much faster if - * we check a 1000 times a second. */ - FlowWakeupFlowManagerThread(); - } - - f = FlowGetUsedFlow(tv, dtv); - if (f == NULL) { - /* max memcap reached, so increments the counter */ - if (tv != NULL && dtv != NULL) { - StatsIncr(tv, dtv->counter_flow_memcap); - } - - /* very rare, but we can fail. Just giving up */ - return NULL; - } - - /* freed a flow, but it's unlocked */ - } else { - /* now see if we can alloc a new flow */ - f = FlowAlloc(); - if (f == NULL) { - if (tv != NULL && dtv != NULL) { - StatsIncr(tv, dtv->counter_flow_memcap); - } - return NULL; - } - - /* flow is initialized but *unlocked* */ - } - } else { - /* flow has been recycled before it went into the spare queue */ - - /* flow is initialized (recylced) but *unlocked* */ - } - - FLOWLOCK_WRLOCK(f); - return f; -} - -Flow *FlowGetFlowFromHashByPacket(const Packet *p) -{ - Flow *f = NULL; - - /* get the key to our bucket */ - uint32_t key = FlowGetKey(p); - /* get our hash bucket and lock it */ - FlowBucket *fb = &flow_hash[key]; - FBLOCK_LOCK(fb); - - SCLogDebug("fb %p fb->head %p", fb, fb->head); - - f = FlowGetNew(NULL, NULL, p); - if (f != NULL) { - /* flow is locked */ - if (fb->head == NULL) { - fb->head = f; - fb->tail = f; - } else { - f->hprev = fb->tail; - fb->tail->hnext = f; - fb->tail = f; - } - - /* got one, now lock, initialize and return */ - FlowInit(f, p); - f->fb = fb; - /* update the last seen timestamp of this flow */ - COPY_TIMESTAMP(&p->ts,&f->lastts); - - } - FBLOCK_UNLOCK(fb); - return f; -} - -/** \brief Lookup flow based on packet - * - * Find the flow belonging to this packet. If not found, no new flow - * is set up. - * - * \param p packet to lookup the flow for - * - * \retval f flow or NULL if not found - */ -Flow *FlowLookupFlowFromHash(const Packet *p) -{ - Flow *f = NULL; - - /* get the key to our bucket */ - uint32_t key = FlowGetKey(p); - /* get our hash bucket and lock it */ - FlowBucket *fb = &flow_hash[key]; - FBLOCK_LOCK(fb); - - SCLogDebug("fb %p fb->head %p", fb, fb->head); - - /* see if the bucket already has a flow */ - if (fb->head == NULL) { - FBLOCK_UNLOCK(fb); - return NULL; - } - - /* ok, we have a flow in the bucket. Let's find out if it is our flow */ - f = fb->head; - - /* see if this is the flow we are looking for */ - if (FlowCompare(f, p) == 0) { - while (f) { - FlowHashCountIncr; - - f = f->hnext; - - if (f == NULL) { - FBLOCK_UNLOCK(fb); - return NULL; - } - - if (FlowCompare(f, p) != 0) { - /* we found our flow, lets put it on top of the - * hash list -- this rewards active flows */ - if (f->hnext) { - f->hnext->hprev = f->hprev; - } - if (f->hprev) { - f->hprev->hnext = f->hnext; - } - if (f == fb->tail) { - fb->tail = f->hprev; - } - - f->hnext = fb->head; - f->hprev = NULL; - fb->head->hprev = f; - fb->head = f; - - /* found our flow, lock & return */ - FLOWLOCK_WRLOCK(f); - /* update the last seen timestamp of this flow */ - COPY_TIMESTAMP(&p->ts,&f->lastts); - - FBLOCK_UNLOCK(fb); - return f; - } - } - } - - /* lock & return */ - FLOWLOCK_WRLOCK(f); - /* update the last seen timestamp of this flow */ - COPY_TIMESTAMP(&p->ts,&f->lastts); - - FBLOCK_UNLOCK(fb); - return f; -} - -/** \brief Get Flow for packet - * - * Hash retrieval function for flows. Looks up the hash bucket containing the - * flow pointer. Then compares the packet with the found flow to see if it is - * the flow we need. If it isn't, walk the list until the right flow is found. - * - * If the flow is not found or the bucket was emtpy, a new flow is taken from - * the queue. FlowDequeue() will alloc new flows as long as we stay within our - * memcap limit. - * - * The p->flow pointer is updated to point to the flow. - * - * \param tv thread vars - * \param dtv decode thread vars (for flow log api thread data) - * - * \retval f *LOCKED* flow or NULL - */ -Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p) -{ - Flow *f = NULL; - FlowHashCountInit; - - /* get the key to our bucket */ - uint32_t key = FlowGetKey(p); - /* get our hash bucket and lock it */ - FlowBucket *fb = &flow_hash[key]; - FBLOCK_LOCK(fb); - - SCLogDebug("fb %p fb->head %p", fb, fb->head); - - FlowHashCountIncr; - - /* see if the bucket already has a flow */ - if (fb->head == NULL) { - f = FlowGetNew(tv, dtv, p); - if (f == NULL) { - FBLOCK_UNLOCK(fb); - FlowHashCountUpdate; - return NULL; - } - - /* flow is locked */ - fb->head = f; - fb->tail = f; - - /* got one, now lock, initialize and return */ - FlowInit(f, p); - f->fb = fb; - - /* update the last seen timestamp of this flow */ - COPY_TIMESTAMP(&p->ts,&f->lastts); - - FBLOCK_UNLOCK(fb); - FlowHashCountUpdate; - return f; - } - - /* ok, we have a flow in the bucket. Let's find out if it is our flow */ - f = fb->head; - - /* see if this is the flow we are looking for */ - if (FlowCompare(f, p) == 0) { - Flow *pf = NULL; /* previous flow */ - - while (f) { - FlowHashCountIncr; - - pf = f; - f = f->hnext; - - if (f == NULL) { - f = pf->hnext = FlowGetNew(tv, dtv, p); - if (f == NULL) { - FBLOCK_UNLOCK(fb); - FlowHashCountUpdate; - return NULL; - } - fb->tail = f; - - /* flow is locked */ - - f->hprev = pf; - - /* initialize and return */ - FlowInit(f, p); - f->fb = fb; - - /* update the last seen timestamp of this flow */ - COPY_TIMESTAMP(&p->ts,&f->lastts); - - FBLOCK_UNLOCK(fb); - FlowHashCountUpdate; - return f; - } - - if (FlowCompare(f, p) != 0) { - /* we found our flow, lets put it on top of the - * hash list -- this rewards active flows */ - if (f->hnext) { - f->hnext->hprev = f->hprev; - } - if (f->hprev) { - f->hprev->hnext = f->hnext; - } - if (f == fb->tail) { - fb->tail = f->hprev; - } - - f->hnext = fb->head; - f->hprev = NULL; - fb->head->hprev = f; - fb->head = f; - - /* found our flow, lock & return */ - FLOWLOCK_WRLOCK(f); - /* update the last seen timestamp of this flow */ - COPY_TIMESTAMP(&p->ts,&f->lastts); - - FBLOCK_UNLOCK(fb); - FlowHashCountUpdate; - return f; - } - } - } - - /* lock & return */ - FLOWLOCK_WRLOCK(f); - /* update the last seen timestamp of this flow */ - COPY_TIMESTAMP(&p->ts,&f->lastts); - - FBLOCK_UNLOCK(fb); - FlowHashCountUpdate; - return f; -} - -/** \internal - * \brief Get a flow from the hash directly. - * - * Called in conditions where the spare queue is empty and memcap is reached. - * - * Walks the hash until a flow can be freed. Timeouts are disregarded, use_cnt - * is adhered to. "flow_prune_idx" atomic int makes sure we don't start at the - * top each time since that would clear the top of the hash leading to longer - * and longer search times under high pressure (observed). - * - * \param tv thread vars - * \param dtv decode thread vars (for flow log api thread data) - * - * \retval f flow or NULL - */ -static Flow *FlowGetUsedFlow(ThreadVars *tv, DecodeThreadVars *dtv) -{ - uint32_t idx = SC_ATOMIC_GET(flow_prune_idx) % flow_config.hash_size; - uint32_t cnt = flow_config.hash_size; - - while (cnt--) { - if (++idx >= flow_config.hash_size) - idx = 0; - - FlowBucket *fb = &flow_hash[idx]; - - if (FBLOCK_TRYLOCK(fb) != 0) - continue; - - Flow *f = fb->tail; - if (f == NULL) { - FBLOCK_UNLOCK(fb); - continue; - } - - if (FLOWLOCK_TRYWRLOCK(f) != 0) { - FBLOCK_UNLOCK(fb); - continue; - } - - /** never prune a flow that is used by a packet or stream msg - * we are currently processing in one of the threads */ - if (SC_ATOMIC_GET(f->use_cnt) > 0) { - FBLOCK_UNLOCK(fb); - FLOWLOCK_UNLOCK(f); - continue; - } - - /* remove from the hash */ - if (f->hprev != NULL) - f->hprev->hnext = f->hnext; - if (f->hnext != NULL) - f->hnext->hprev = f->hprev; - if (fb->head == f) - fb->head = f->hnext; - if (fb->tail == f) - fb->tail = f->hprev; - - f->hnext = NULL; - f->hprev = NULL; - f->fb = NULL; - FBLOCK_UNLOCK(fb); - - int state = SC_ATOMIC_GET(f->flow_state); - if (state == FLOW_STATE_NEW) - f->flow_end_flags |= FLOW_END_FLAG_STATE_NEW; - else if (state == FLOW_STATE_ESTABLISHED) - f->flow_end_flags |= FLOW_END_FLAG_STATE_ESTABLISHED; - else if (state == FLOW_STATE_CLOSED) - f->flow_end_flags |= FLOW_END_FLAG_STATE_CLOSED; - - f->flow_end_flags |= FLOW_END_FLAG_FORCED; - - if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) - f->flow_end_flags |= FLOW_END_FLAG_EMERGENCY; - - /* invoke flow log api */ - if (dtv && dtv->output_flow_thread_data) - (void)OutputFlowLog(tv, dtv->output_flow_thread_data, f); - - FlowClearMemory(f, f->protomap); - - FLOWLOCK_UNLOCK(f); - - (void) SC_ATOMIC_ADD(flow_prune_idx, (flow_config.hash_size - cnt)); - return f; - } - - return NULL; -} diff --git a/framework/src/suricata/src/flow-hash.h b/framework/src/suricata/src/flow-hash.h deleted file mode 100644 index 4272896b..00000000 --- a/framework/src/suricata/src/flow-hash.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __FLOW_HASH_H__ -#define __FLOW_HASH_H__ - -/** Spinlocks or Mutex for the flow buckets. */ -//#define FBLOCK_SPIN -#define FBLOCK_MUTEX - -#ifdef FBLOCK_SPIN - #ifdef FBLOCK_MUTEX - #error Cannot enable both FBLOCK_SPIN and FBLOCK_MUTEX - #endif -#endif - -/* flow hash bucket -- the hash is basically an array of these buckets. - * Each bucket contains a flow or list of flows. All these flows have - * the same hashkey (the hash is a chained hash). When doing modifications - * to the list, the entire bucket is locked. */ -typedef struct FlowBucket_ { - Flow *head; - Flow *tail; -#ifdef FBLOCK_MUTEX - SCMutex m; -#elif defined FBLOCK_SPIN - SCSpinlock s; -#else - #error Enable FBLOCK_SPIN or FBLOCK_MUTEX -#endif -} __attribute__((aligned(CLS))) FlowBucket; - -#ifdef FBLOCK_SPIN - #define FBLOCK_INIT(fb) SCSpinInit(&(fb)->s, 0) - #define FBLOCK_DESTROY(fb) SCSpinDestroy(&(fb)->s) - #define FBLOCK_LOCK(fb) SCSpinLock(&(fb)->s) - #define FBLOCK_TRYLOCK(fb) SCSpinTrylock(&(fb)->s) - #define FBLOCK_UNLOCK(fb) SCSpinUnlock(&(fb)->s) -#elif defined FBLOCK_MUTEX - #define FBLOCK_INIT(fb) SCMutexInit(&(fb)->m, NULL) - #define FBLOCK_DESTROY(fb) SCMutexDestroy(&(fb)->m) - #define FBLOCK_LOCK(fb) SCMutexLock(&(fb)->m) - #define FBLOCK_TRYLOCK(fb) SCMutexTrylock(&(fb)->m) - #define FBLOCK_UNLOCK(fb) SCMutexUnlock(&(fb)->m) -#else - #error Enable FBLOCK_SPIN or FBLOCK_MUTEX -#endif - -/* prototypes */ - -Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *); - -void FlowDisableTcpReuseHandling(void); - -/** enable to print stats on hash lookups in flow-debug.log */ -//#define FLOW_DEBUG_STATS - -#ifdef FLOW_DEBUG_STATS -void FlowHashDebugInit(void); -void FlowHashDebugDeinit(void); -void FlowHashDebugPrint(uint32_t); -#else -#define FlowHashDebugInit(...) -#define FlowHashDebugPrint(...) -#define FlowHashDebugDeinit(...) -#endif - -#endif /* __FLOW_HASH_H__ */ - diff --git a/framework/src/suricata/src/flow-manager.c b/framework/src/suricata/src/flow-manager.c deleted file mode 100644 index 15ad6162..00000000 --- a/framework/src/suricata/src/flow-manager.c +++ /dev/null @@ -1,1285 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "conf.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "runmodes.h" - -#include "util-random.h" -#include "util-time.h" - -#include "flow.h" -#include "flow-queue.h" -#include "flow-hash.h" -#include "flow-util.h" -#include "flow-var.h" -#include "flow-private.h" -#include "flow-timeout.h" -#include "flow-manager.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-byte.h" - -#include "util-debug.h" -#include "util-privs.h" -#include "util-signal.h" - -#include "threads.h" -#include "detect.h" -#include "detect-engine-state.h" -#include "stream.h" - -#include "app-layer-parser.h" - -#include "host-timeout.h" -#include "defrag-timeout.h" -#include "ippair-timeout.h" - -#include "output-flow.h" - -/* Run mode selected at suricata.c */ -extern int run_mode; - -/* multi flow mananger support */ -static uint32_t flowmgr_number = 1; -/* atomic counter for flow managers, to assign instance id */ -SC_ATOMIC_DECLARE(uint32_t, flowmgr_cnt); - -/* multi flow recycler support */ -static uint32_t flowrec_number = 1; -/* atomic counter for flow recyclers, to assign instance id */ -SC_ATOMIC_DECLARE(uint32_t, flowrec_cnt); - -SC_ATOMIC_EXTERN(unsigned int, flow_flags); - -/* 1 seconds */ -#define FLOW_NORMAL_MODE_UPDATE_DELAY_SEC 1 -#define FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC 0 -/* 0.1 seconds */ -#define FLOW_EMERG_MODE_UPDATE_DELAY_SEC 0 -#define FLOW_EMERG_MODE_UPDATE_DELAY_NSEC 100000 -#define NEW_FLOW_COUNT_COND 10 - -typedef struct FlowTimeoutCounters_ { - uint32_t new; - uint32_t est; - uint32_t clo; - uint32_t tcp_reuse; -} FlowTimeoutCounters; - -/** - * \brief Used to disable flow manager thread(s). - * - * \todo Kinda hackish since it uses the tv name to identify flow manager - * thread. We need an all weather identification scheme. - */ -void FlowDisableFlowManagerThread(void) -{ - ThreadVars *tv = NULL; - int cnt = 0; - - /* wake up threads */ - uint32_t u; - for (u = 0; u < flowmgr_number; u++) - SCCtrlCondSignal(&flow_manager_ctrl_cond); - - SCMutexLock(&tv_root_lock); - - /* flow manager thread(s) is/are a part of mgmt threads */ - tv = tv_root[TVT_MGMT]; - - while (tv != NULL) { - if (strcasecmp(tv->name, "FlowManagerThread") == 0) { - TmThreadsSetFlag(tv, THV_KILL); - cnt++; - - /* value in seconds */ -#define THREAD_KILL_MAX_WAIT_TIME 60 - /* value in microseconds */ -#define WAIT_TIME 100 - - double total_wait_time = 0; - while (!TmThreadsCheckFlag(tv, THV_RUNNING_DONE)) { - usleep(WAIT_TIME); - total_wait_time += WAIT_TIME / 1000000.0; - if (total_wait_time > THREAD_KILL_MAX_WAIT_TIME) { - SCLogError(SC_ERR_FATAL, "Engine unable to " - "disable detect thread - \"%s\". " - "Killing engine", tv->name); - exit(EXIT_FAILURE); - } - } - } - tv = tv->next; - } - SCMutexUnlock(&tv_root_lock); - - /* wake up threads, another try */ - for (u = 0; u < flowmgr_number; u++) - SCCtrlCondSignal(&flow_manager_ctrl_cond); - - /* reset count, so we can kill and respawn (unix socket) */ - SC_ATOMIC_SET(flowmgr_cnt, 0); - return; -} - -/** \internal - * \brief get timeout for flow - * - * \param f flow - * \param state flow state - * \param emergency bool indicating emergency mode 1 yes, 0 no - * - * \retval timeout timeout in seconds - */ -static inline uint32_t FlowGetFlowTimeout(const Flow *f, int state, int emergency) -{ - uint32_t timeout; - - if (emergency) { - switch(state) { - default: - case FLOW_STATE_NEW: - timeout = flow_proto[f->protomap].emerg_new_timeout; - break; - case FLOW_STATE_ESTABLISHED: - timeout = flow_proto[f->protomap].emerg_est_timeout; - break; - case FLOW_STATE_CLOSED: - timeout = flow_proto[f->protomap].emerg_closed_timeout; - break; - } - } else { /* implies no emergency */ - switch(state) { - default: - case FLOW_STATE_NEW: - timeout = flow_proto[f->protomap].new_timeout; - break; - case FLOW_STATE_ESTABLISHED: - timeout = flow_proto[f->protomap].est_timeout; - break; - case FLOW_STATE_CLOSED: - timeout = flow_proto[f->protomap].closed_timeout; - break; - } - } - - return timeout; -} - -/** \internal - * \brief check if a flow is timed out - * - * \param f flow - * \param ts timestamp - * \param emergency bool indicating emergency mode - * - * \retval 0 not timed out - * \retval 1 timed out - */ -static int FlowManagerFlowTimeout(const Flow *f, int state, struct timeval *ts, int emergency) -{ - /* set the timeout value according to the flow operating mode, - * flow's state and protocol.*/ - uint32_t timeout = FlowGetFlowTimeout(f, state, emergency); - - /* do the timeout check */ - if ((int32_t)(f->lastts.tv_sec + timeout) >= ts->tv_sec) { - return 0; - } - - return 1; -} - -/** \internal - * \brief See if we can really discard this flow. Check use_cnt reference - * counter and force reassembly if necessary. - * - * \param f flow - * \param ts timestamp - * \param emergency bool indicating emergency mode - * - * \retval 0 not timed out just yet - * \retval 1 fully timed out, lets kill it - */ -static int FlowManagerFlowTimedOut(Flow *f, struct timeval *ts) -{ - /** never prune a flow that is used by a packet or stream msg - * we are currently processing in one of the threads */ - if (SC_ATOMIC_GET(f->use_cnt) > 0) { - return 0; - } - - int server = 0, client = 0; - if (!(f->flags & FLOW_TIMEOUT_REASSEMBLY_DONE) && - FlowForceReassemblyNeedReassembly(f, &server, &client) == 1) { - FlowForceReassemblyForFlow(f, server, client); - return 0; - } -#ifdef DEBUG - /* this should not be possible */ - BUG_ON(SC_ATOMIC_GET(f->use_cnt) > 0); -#endif - - return 1; -} - -/** - * \internal - * - * \brief check all flows in a hash row for timing out - * - * \param f last flow in the hash row - * \param ts timestamp - * \param emergency bool indicating emergency mode - * \param counters ptr to FlowTimeoutCounters structure - * - * \retval cnt timed out flows - */ -static uint32_t FlowManagerHashRowTimeout(Flow *f, struct timeval *ts, - int emergency, FlowTimeoutCounters *counters) -{ - uint32_t cnt = 0; - - do { - /* check flow timeout based on lastts and state. Both can be - * accessed w/o Flow lock as we do have the hash row lock (so flow - * can't disappear) and flow_state is atomic. lastts can only - * be modified when we have both the flow and hash row lock */ - - int state = SC_ATOMIC_GET(f->flow_state); - - /* timeout logic goes here */ - if (FlowManagerFlowTimeout(f, state, ts, emergency) == 0) { - f = f->hprev; - continue; - } - - /* before grabbing the flow lock, make sure we have at least - * 3 packets in the pool */ - PacketPoolWaitForN(3); - - FLOWLOCK_WRLOCK(f); - - Flow *next_flow = f->hprev; - - /* check if the flow is fully timed out and - * ready to be discarded. */ - if (FlowManagerFlowTimedOut(f, ts) == 1) { - /* remove from the hash */ - if (f->hprev != NULL) - f->hprev->hnext = f->hnext; - if (f->hnext != NULL) - f->hnext->hprev = f->hprev; - if (f->fb->head == f) - f->fb->head = f->hnext; - if (f->fb->tail == f) - f->fb->tail = f->hprev; - - f->hnext = NULL; - f->hprev = NULL; - - if (f->flags & FLOW_TCP_REUSED) - counters->tcp_reuse++; - - if (state == FLOW_STATE_NEW) - f->flow_end_flags |= FLOW_END_FLAG_STATE_NEW; - else if (state == FLOW_STATE_ESTABLISHED) - f->flow_end_flags |= FLOW_END_FLAG_STATE_ESTABLISHED; - else if (state == FLOW_STATE_CLOSED) - f->flow_end_flags |= FLOW_END_FLAG_STATE_CLOSED; - - if (emergency) - f->flow_end_flags |= FLOW_END_FLAG_EMERGENCY; - f->flow_end_flags |= FLOW_END_FLAG_TIMEOUT; - -// FlowClearMemory (f, f->protomap); - - /* no one is referring to this flow, use_cnt 0, removed from hash - * so we can unlock it and move it back to the spare queue. */ - FLOWLOCK_UNLOCK(f); - FlowEnqueue(&flow_recycle_q, f); - /* move to spare list */ -// FlowMoveToSpare(f); - - cnt++; - - switch (state) { - case FLOW_STATE_NEW: - default: - counters->new++; - break; - case FLOW_STATE_ESTABLISHED: - counters->est++; - break; - case FLOW_STATE_CLOSED: - counters->clo++; - break; - } - } else { - FLOWLOCK_UNLOCK(f); - } - - f = next_flow; - } while (f != NULL); - - return cnt; -} - -/** - * \brief time out flows from the hash - * - * \param ts timestamp - * \param try_cnt number of flows to time out max (0 is unlimited) - * \param hash_min min hash index to consider - * \param hash_max max hash index to consider - * \param counters ptr to FlowTimeoutCounters structure - * - * \retval cnt number of timed out flow - */ -static uint32_t FlowTimeoutHash(struct timeval *ts, uint32_t try_cnt, - uint32_t hash_min, uint32_t hash_max, - FlowTimeoutCounters *counters) -{ - uint32_t idx = 0; - uint32_t cnt = 0; - int emergency = 0; - - if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) - emergency = 1; - - for (idx = hash_min; idx < hash_max; idx++) { - FlowBucket *fb = &flow_hash[idx]; - - /* before grabbing the row lock, make sure we have at least - * 9 packets in the pool */ - PacketPoolWaitForN(9); - - if (FBLOCK_TRYLOCK(fb) != 0) - continue; - - /* flow hash bucket is now locked */ - - if (fb->tail == NULL) - goto next; - - /* we have a flow, or more than one */ - cnt += FlowManagerHashRowTimeout(fb->tail, ts, emergency, counters); - -next: - FBLOCK_UNLOCK(fb); - - if (try_cnt > 0 && cnt >= try_cnt) - break; - } - - return cnt; -} - -/** - * \internal - * - * \brief move all flows out of a hash row - * - * \param f last flow in the hash row - * - * \retval cnt removed out flows - */ -static uint32_t FlowManagerHashRowCleanup(Flow *f) -{ - uint32_t cnt = 0; - - do { - FLOWLOCK_WRLOCK(f); - - Flow *next_flow = f->hprev; - - int state = SC_ATOMIC_GET(f->flow_state); - - /* remove from the hash */ - if (f->hprev != NULL) - f->hprev->hnext = f->hnext; - if (f->hnext != NULL) - f->hnext->hprev = f->hprev; - if (f->fb->head == f) - f->fb->head = f->hnext; - if (f->fb->tail == f) - f->fb->tail = f->hprev; - - f->hnext = NULL; - f->hprev = NULL; - - if (state == FLOW_STATE_NEW) - f->flow_end_flags |= FLOW_END_FLAG_STATE_NEW; - else if (state == FLOW_STATE_ESTABLISHED) - f->flow_end_flags |= FLOW_END_FLAG_STATE_ESTABLISHED; - else if (state == FLOW_STATE_CLOSED) - f->flow_end_flags |= FLOW_END_FLAG_STATE_CLOSED; - - f->flow_end_flags |= FLOW_END_FLAG_SHUTDOWN; - - /* no one is referring to this flow, use_cnt 0, removed from hash - * so we can unlock it and move it to the recycle queue. */ - FLOWLOCK_UNLOCK(f); - - FlowEnqueue(&flow_recycle_q, f); - - cnt++; - - f = next_flow; - } while (f != NULL); - - return cnt; -} - -/** - * \brief remove all flows from the hash - * - * \retval cnt number of removes out flows - */ -static uint32_t FlowCleanupHash(void){ - uint32_t idx = 0; - uint32_t cnt = 0; - - for (idx = 0; idx < flow_config.hash_size; idx++) { - FlowBucket *fb = &flow_hash[idx]; - - FBLOCK_LOCK(fb); - - if (fb->tail != NULL) { - /* we have a flow, or more than one */ - cnt += FlowManagerHashRowCleanup(fb->tail); - } - - FBLOCK_UNLOCK(fb); - } - - return cnt; -} - -extern int g_detect_disabled; - -typedef struct FlowManagerThreadData_ { - uint32_t instance; - uint32_t min; - uint32_t max; - - uint16_t flow_mgr_cnt_clo; - uint16_t flow_mgr_cnt_new; - uint16_t flow_mgr_cnt_est; - uint16_t flow_mgr_spare; - uint16_t flow_emerg_mode_enter; - uint16_t flow_emerg_mode_over; - uint16_t flow_tcp_reuse; -} FlowManagerThreadData; - -static TmEcode FlowManagerThreadInit(ThreadVars *t, void *initdata, void **data) -{ - FlowManagerThreadData *ftd = SCCalloc(1, sizeof(FlowManagerThreadData)); - if (ftd == NULL) - return TM_ECODE_FAILED; - - ftd->instance = SC_ATOMIC_ADD(flowmgr_cnt, 1); - SCLogDebug("flow manager instance %u", ftd->instance); - - /* set the min and max value used for hash row walking - * each thread has it's own section of the flow hash */ - uint32_t range = flow_config.hash_size / flowmgr_number; - if (ftd->instance == 1) - ftd->max = range; - else if (ftd->instance == flowmgr_number) { - ftd->min = (range * (ftd->instance - 1)); - ftd->max = flow_config.hash_size; - } else { - ftd->min = (range * (ftd->instance - 1)); - ftd->max = (range * ftd->instance); - } - BUG_ON(ftd->min > flow_config.hash_size || ftd->max > flow_config.hash_size); - - SCLogDebug("instance %u hash range %u %u", ftd->instance, ftd->min, ftd->max); - - /* pass thread data back to caller */ - *data = ftd; - - ftd->flow_mgr_cnt_clo = StatsRegisterCounter("flow_mgr.closed_pruned", t); - ftd->flow_mgr_cnt_new = StatsRegisterCounter("flow_mgr.new_pruned", t); - ftd->flow_mgr_cnt_est = StatsRegisterCounter("flow_mgr.est_pruned", t); - ftd->flow_mgr_spare = StatsRegisterCounter("flow.spare", t); - ftd->flow_emerg_mode_enter = StatsRegisterCounter("flow.emerg_mode_entered", t); - ftd->flow_emerg_mode_over = StatsRegisterCounter("flow.emerg_mode_over", t); - ftd->flow_tcp_reuse = StatsRegisterCounter("flow.tcp_reuse", t); - - PacketPoolInit(); - return TM_ECODE_OK; -} - -static TmEcode FlowManagerThreadDeinit(ThreadVars *t, void *data) -{ - PacketPoolDestroy(); - SCFree(data); - return TM_ECODE_OK; -} - - -/** \brief Thread that manages the flow table and times out flows. - * - * \param td ThreadVars casted to void ptr - * - * Keeps an eye on the spare list, alloc flows if needed... - */ -static TmEcode FlowManager(ThreadVars *th_v, void *thread_data) -{ - /* block usr2. usr1 to be handled by the main thread only */ - UtilSignalBlock(SIGUSR2); - - FlowManagerThreadData *ftd = thread_data; - struct timeval ts; - uint32_t established_cnt = 0, new_cnt = 0, closing_cnt = 0; - int emerg = FALSE; - int prev_emerg = FALSE; - uint32_t last_sec = 0; - struct timespec cond_time; - int flow_update_delay_sec = FLOW_NORMAL_MODE_UPDATE_DELAY_SEC; - int flow_update_delay_nsec = FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC; -/* VJ leaving disabled for now, as hosts are only used by tags and the numbers - * are really low. Might confuse ppl - uint16_t flow_mgr_host_prune = StatsRegisterCounter("hosts.pruned", th_v); - uint16_t flow_mgr_host_active = StatsRegisterCounter("hosts.active", th_v); - uint16_t flow_mgr_host_spare = StatsRegisterCounter("hosts.spare", th_v); -*/ - memset(&ts, 0, sizeof(ts)); - - FlowHashDebugInit(); - - while (1) - { - if (TmThreadsCheckFlag(th_v, THV_PAUSE)) { - TmThreadsSetFlag(th_v, THV_PAUSED); - TmThreadTestThreadUnPaused(th_v); - TmThreadsUnsetFlag(th_v, THV_PAUSED); - } - - if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) { - emerg = TRUE; - - if (emerg == TRUE && prev_emerg == FALSE) { - prev_emerg = TRUE; - - SCLogDebug("Flow emergency mode entered..."); - - StatsIncr(th_v, ftd->flow_emerg_mode_enter); - } - } - - /* Get the time */ - memset(&ts, 0, sizeof(ts)); - TimeGet(&ts); - SCLogDebug("ts %" PRIdMAX "", (intmax_t)ts.tv_sec); - - if (((uint32_t)ts.tv_sec - last_sec) > 600) { - FlowHashDebugPrint((uint32_t)ts.tv_sec); - last_sec = (uint32_t)ts.tv_sec; - } - - /* see if we still have enough spare flows */ - if (ftd->instance == 1) - FlowUpdateSpareFlows(); - - /* try to time out flows */ - FlowTimeoutCounters counters = { 0, 0, 0, 0, }; - FlowTimeoutHash(&ts, 0 /* check all */, ftd->min, ftd->max, &counters); - - - if (ftd->instance == 1) { - DefragTimeoutHash(&ts); - //uint32_t hosts_pruned = - HostTimeoutHash(&ts); - IPPairTimeoutHash(&ts); - } -/* - StatsAddUI64(th_v, flow_mgr_host_prune, (uint64_t)hosts_pruned); - uint32_t hosts_active = HostGetActiveCount(); - StatsSetUI64(th_v, flow_mgr_host_active, (uint64_t)hosts_active); - uint32_t hosts_spare = HostGetSpareCount(); - StatsSetUI64(th_v, flow_mgr_host_spare, (uint64_t)hosts_spare); -*/ - StatsAddUI64(th_v, ftd->flow_mgr_cnt_clo, (uint64_t)counters.clo); - StatsAddUI64(th_v, ftd->flow_mgr_cnt_new, (uint64_t)counters.new); - StatsAddUI64(th_v, ftd->flow_mgr_cnt_est, (uint64_t)counters.est); - StatsAddUI64(th_v, ftd->flow_tcp_reuse, (uint64_t)counters.tcp_reuse); - - uint32_t len = 0; - FQLOCK_LOCK(&flow_spare_q); - len = flow_spare_q.len; - FQLOCK_UNLOCK(&flow_spare_q); - StatsSetUI64(th_v, ftd->flow_mgr_spare, (uint64_t)len); - - /* Don't fear, FlowManagerThread is here... - * clear emergency bit if we have at least xx flows pruned. */ - if (emerg == TRUE) { - SCLogDebug("flow_sparse_q.len = %"PRIu32" prealloc: %"PRIu32 - "flow_spare_q status: %"PRIu32"%% flows at the queue", - len, flow_config.prealloc, len * 100 / flow_config.prealloc); - /* only if we have pruned this "emergency_recovery" percentage - * of flows, we will unset the emergency bit */ - if (len * 100 / flow_config.prealloc > flow_config.emergency_recovery) { - SC_ATOMIC_AND(flow_flags, ~FLOW_EMERGENCY); - - emerg = FALSE; - prev_emerg = FALSE; - - flow_update_delay_sec = FLOW_NORMAL_MODE_UPDATE_DELAY_SEC; - flow_update_delay_nsec = FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC; - SCLogInfo("Flow emergency mode over, back to normal... unsetting" - " FLOW_EMERGENCY bit (ts.tv_sec: %"PRIuMAX", " - "ts.tv_usec:%"PRIuMAX") flow_spare_q status(): %"PRIu32 - "%% flows at the queue", (uintmax_t)ts.tv_sec, - (uintmax_t)ts.tv_usec, len * 100 / flow_config.prealloc); - - StatsIncr(th_v, ftd->flow_emerg_mode_over); - } else { - flow_update_delay_sec = FLOW_EMERG_MODE_UPDATE_DELAY_SEC; - flow_update_delay_nsec = FLOW_EMERG_MODE_UPDATE_DELAY_NSEC; - } - } - - if (TmThreadsCheckFlag(th_v, THV_KILL)) { - StatsSyncCounters(th_v); - break; - } - - cond_time.tv_sec = time(NULL) + flow_update_delay_sec; - cond_time.tv_nsec = flow_update_delay_nsec; - SCCtrlMutexLock(&flow_manager_ctrl_mutex); - SCCtrlCondTimedwait(&flow_manager_ctrl_cond, &flow_manager_ctrl_mutex, - &cond_time); - SCCtrlMutexUnlock(&flow_manager_ctrl_mutex); - - SCLogDebug("woke up... %s", SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY ? "emergency":""); - - StatsSyncCountersIfSignalled(th_v); - } - - FlowHashDebugDeinit(); - - SCLogInfo("%" PRIu32 " new flows, %" PRIu32 " established flows were " - "timed out, %"PRIu32" flows in closed state", new_cnt, - established_cnt, closing_cnt); - - return TM_ECODE_OK; -} - -static uint64_t FlowGetMemuse(void) -{ - uint64_t flow_memuse = SC_ATOMIC_GET(flow_memuse); - return flow_memuse; -} - -/** \brief spawn the flow manager thread */ -void FlowManagerThreadSpawn() -{ - intmax_t setting = 1; - (void)ConfGetInt("flow.managers", &setting); - - if (setting < 1 || setting > 1024) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, - "invalid flow.managers setting %"PRIdMAX, setting); - exit(EXIT_FAILURE); - } - flowmgr_number = (uint32_t)setting; - - SCLogInfo("using %u flow manager threads", flowmgr_number); - SCCtrlCondInit(&flow_manager_ctrl_cond, NULL); - SCCtrlMutexInit(&flow_manager_ctrl_mutex, NULL); - - StatsRegisterGlobalCounter("flow.memuse", FlowGetMemuse); - - uint32_t u; - for (u = 0; u < flowmgr_number; u++) { - ThreadVars *tv_flowmgr = NULL; - - char name[32] = ""; - snprintf(name, sizeof(name), "FlowManagerThread%02u", u+1); - - tv_flowmgr = TmThreadCreateMgmtThreadByName("FlowManagerThread", - "FlowManager", 0); - BUG_ON(tv_flowmgr == NULL); - - if (tv_flowmgr == NULL) { - printf("ERROR: TmThreadsCreate failed\n"); - exit(1); - } - if (TmThreadSpawn(tv_flowmgr) != TM_ECODE_OK) { - printf("ERROR: TmThreadSpawn failed\n"); - exit(1); - } - } - return; -} - -typedef struct FlowRecyclerThreadData_ { - void *output_thread_data; -} FlowRecyclerThreadData; - -static TmEcode FlowRecyclerThreadInit(ThreadVars *t, void *initdata, void **data) -{ - FlowRecyclerThreadData *ftd = SCCalloc(1, sizeof(FlowRecyclerThreadData)); - if (ftd == NULL) - return TM_ECODE_FAILED; - - if (OutputFlowLogThreadInit(t, NULL, &ftd->output_thread_data) != TM_ECODE_OK) { - SCLogError(SC_ERR_THREAD_INIT, "initializing flow log API for thread failed"); - SCFree(ftd); - return TM_ECODE_FAILED; - } - SCLogDebug("output_thread_data %p", ftd->output_thread_data); - - *data = ftd; - return TM_ECODE_OK; -} - -static TmEcode FlowRecyclerThreadDeinit(ThreadVars *t, void *data) -{ - FlowRecyclerThreadData *ftd = (FlowRecyclerThreadData *)data; - if (ftd->output_thread_data != NULL) - OutputFlowLogThreadDeinit(t, ftd->output_thread_data); - - SCFree(data); - return TM_ECODE_OK; -} - -/** \brief Thread that manages timed out flows. - * - * \param td ThreadVars casted to void ptr - */ -static TmEcode FlowRecycler(ThreadVars *th_v, void *thread_data) -{ - /* block usr2. usr2 to be handled by the main thread only */ - UtilSignalBlock(SIGUSR2); - - struct timeval ts; - struct timespec cond_time; - int flow_update_delay_sec = FLOW_NORMAL_MODE_UPDATE_DELAY_SEC; - int flow_update_delay_nsec = FLOW_NORMAL_MODE_UPDATE_DELAY_NSEC; - uint64_t recycled_cnt = 0; - FlowRecyclerThreadData *ftd = (FlowRecyclerThreadData *)thread_data; - BUG_ON(ftd == NULL); - - memset(&ts, 0, sizeof(ts)); - - while (1) - { - if (TmThreadsCheckFlag(th_v, THV_PAUSE)) { - TmThreadsSetFlag(th_v, THV_PAUSED); - TmThreadTestThreadUnPaused(th_v); - TmThreadsUnsetFlag(th_v, THV_PAUSED); - } - - /* Get the time */ - memset(&ts, 0, sizeof(ts)); - TimeGet(&ts); - SCLogDebug("ts %" PRIdMAX "", (intmax_t)ts.tv_sec); - - uint32_t len = 0; - FQLOCK_LOCK(&flow_recycle_q); - len = flow_recycle_q.len; - FQLOCK_UNLOCK(&flow_recycle_q); - - /* Loop through the queue and clean up all flows in it */ - if (len) { - Flow *f; - - while ((f = FlowDequeue(&flow_recycle_q)) != NULL) { - FLOWLOCK_WRLOCK(f); - - (void)OutputFlowLog(th_v, ftd->output_thread_data, f); - - FlowClearMemory (f, f->protomap); - FLOWLOCK_UNLOCK(f); - FlowMoveToSpare(f); - recycled_cnt++; - } - } - - SCLogDebug("%u flows to recycle", len); - - if (TmThreadsCheckFlag(th_v, THV_KILL)) { - StatsSyncCounters(th_v); - break; - } - - cond_time.tv_sec = time(NULL) + flow_update_delay_sec; - cond_time.tv_nsec = flow_update_delay_nsec; - SCCtrlMutexLock(&flow_recycler_ctrl_mutex); - SCCtrlCondTimedwait(&flow_recycler_ctrl_cond, - &flow_recycler_ctrl_mutex, &cond_time); - SCCtrlMutexUnlock(&flow_recycler_ctrl_mutex); - - SCLogDebug("woke up..."); - - StatsSyncCountersIfSignalled(th_v); - } - - SCLogInfo("%"PRIu64" flows processed", recycled_cnt); - - return TM_ECODE_OK; -} - -int FlowRecyclerReadyToShutdown(void) -{ - uint32_t len = 0; - FQLOCK_LOCK(&flow_recycle_q); - len = flow_recycle_q.len; - FQLOCK_UNLOCK(&flow_recycle_q); - - return ((len == 0)); -} - -/** \brief spawn the flow recycler thread */ -void FlowRecyclerThreadSpawn() -{ - intmax_t setting = 1; - (void)ConfGetInt("flow.recyclers", &setting); - - if (setting < 1 || setting > 1024) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, - "invalid flow.recyclers setting %"PRIdMAX, setting); - exit(EXIT_FAILURE); - } - flowrec_number = (uint32_t)setting; - - SCLogInfo("using %u flow recycler threads", flowrec_number); - - SCCtrlCondInit(&flow_recycler_ctrl_cond, NULL); - SCCtrlMutexInit(&flow_recycler_ctrl_mutex, NULL); - - - uint32_t u; - for (u = 0; u < flowrec_number; u++) { - ThreadVars *tv_flowmgr = NULL; - - char name[32] = ""; - snprintf(name, sizeof(name), "FlowRecyclerThread%02u", u+1); - - tv_flowmgr = TmThreadCreateMgmtThreadByName("FlowRecyclerThread", - "FlowRecycler", 0); - BUG_ON(tv_flowmgr == NULL); - - if (tv_flowmgr == NULL) { - printf("ERROR: TmThreadsCreate failed\n"); - exit(1); - } - if (TmThreadSpawn(tv_flowmgr) != TM_ECODE_OK) { - printf("ERROR: TmThreadSpawn failed\n"); - exit(1); - } - } - return; -} - -/** - * \brief Used to disable flow recycler thread(s). - * - * \note this should only be called when the flow manager is already gone - * - * \todo Kinda hackish since it uses the tv name to identify flow recycler - * thread. We need an all weather identification scheme. - */ -void FlowDisableFlowRecyclerThread(void) -{ - ThreadVars *tv = NULL; - int cnt = 0; - - /* move all flows still in the hash to the recycler queue */ - FlowCleanupHash(); - - /* make sure all flows are processed */ - do { - SCCtrlCondSignal(&flow_recycler_ctrl_cond); - usleep(10); - } while (FlowRecyclerReadyToShutdown() == 0); - - /* wake up threads */ - uint32_t u; - for (u = 0; u < flowrec_number; u++) - SCCtrlCondSignal(&flow_recycler_ctrl_cond); - - SCMutexLock(&tv_root_lock); - - /* flow recycler thread(s) is/are a part of mgmt threads */ - tv = tv_root[TVT_MGMT]; - - while (tv != NULL) { - if (strcasecmp(tv->name, "FlowRecyclerThread") == 0) { - TmThreadsSetFlag(tv, THV_KILL); - cnt++; - - /* value in seconds */ -#define THREAD_KILL_MAX_WAIT_TIME 60 - /* value in microseconds */ -#define WAIT_TIME 100 - - double total_wait_time = 0; - while (!TmThreadsCheckFlag(tv, THV_RUNNING_DONE)) { - usleep(WAIT_TIME); - total_wait_time += WAIT_TIME / 1000000.0; - if (total_wait_time > THREAD_KILL_MAX_WAIT_TIME) { - SCLogError(SC_ERR_FATAL, "Engine unable to " - "disable detect thread - \"%s\". " - "Killing engine", tv->name); - exit(EXIT_FAILURE); - } - } - } - tv = tv->next; - } - - /* wake up threads, another try */ - for (u = 0; u < flowrec_number; u++) - SCCtrlCondSignal(&flow_recycler_ctrl_cond); - - SCMutexUnlock(&tv_root_lock); - - /* reset count, so we can kill and respawn (unix socket) */ - SC_ATOMIC_SET(flowrec_cnt, 0); - return; -} - -void TmModuleFlowManagerRegister (void) -{ - tmm_modules[TMM_FLOWMANAGER].name = "FlowManager"; - tmm_modules[TMM_FLOWMANAGER].ThreadInit = FlowManagerThreadInit; - tmm_modules[TMM_FLOWMANAGER].ThreadDeinit = FlowManagerThreadDeinit; -// tmm_modules[TMM_FLOWMANAGER].RegisterTests = FlowManagerRegisterTests; - tmm_modules[TMM_FLOWMANAGER].Management = FlowManager; - tmm_modules[TMM_FLOWMANAGER].cap_flags = 0; - tmm_modules[TMM_FLOWMANAGER].flags = TM_FLAG_MANAGEMENT_TM; - SCLogDebug("%s registered", tmm_modules[TMM_FLOWMANAGER].name); - - SC_ATOMIC_INIT(flowmgr_cnt); -} - -void TmModuleFlowRecyclerRegister (void) -{ - tmm_modules[TMM_FLOWRECYCLER].name = "FlowRecycler"; - tmm_modules[TMM_FLOWRECYCLER].ThreadInit = FlowRecyclerThreadInit; - tmm_modules[TMM_FLOWRECYCLER].ThreadDeinit = FlowRecyclerThreadDeinit; -// tmm_modules[TMM_FLOWRECYCLER].RegisterTests = FlowRecyclerRegisterTests; - tmm_modules[TMM_FLOWRECYCLER].Management = FlowRecycler; - tmm_modules[TMM_FLOWRECYCLER].cap_flags = 0; - tmm_modules[TMM_FLOWRECYCLER].flags = TM_FLAG_MANAGEMENT_TM; - SCLogDebug("%s registered", tmm_modules[TMM_FLOWRECYCLER].name); - - SC_ATOMIC_INIT(flowrec_cnt); -} - -#ifdef UNITTESTS - -/** - * \test Test the timing out of a flow with a fresh TcpSession - * (just initialized, no data segments) in normal mode. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowMgrTest01 (void) -{ - TcpSession ssn; - Flow f; - FlowBucket fb; - struct timeval ts; - - FlowQueueInit(&flow_spare_q); - - memset(&ssn, 0, sizeof(TcpSession)); - memset(&f, 0, sizeof(Flow)); - memset(&ts, 0, sizeof(ts)); - memset(&fb, 0, sizeof(FlowBucket)); - - FBLOCK_INIT(&fb); - - FLOW_INITIALIZE(&f); - f.flags |= FLOW_TIMEOUT_REASSEMBLY_DONE; - - TimeGet(&ts); - f.lastts.tv_sec = ts.tv_sec - 5000; - f.protoctx = &ssn; - f.fb = &fb; - - f.proto = IPPROTO_TCP; - - int state = SC_ATOMIC_GET(f.flow_state); - if (FlowManagerFlowTimeout(&f, state, &ts, 0) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) { - FBLOCK_DESTROY(&fb); - FLOW_DESTROY(&f); - FlowQueueDestroy(&flow_spare_q); - return 0; - } - - FBLOCK_DESTROY(&fb); - FLOW_DESTROY(&f); - - FlowQueueDestroy(&flow_spare_q); - return 1; -} - -/** - * \test Test the timing out of a flow with a TcpSession - * (with data segments) in normal mode. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowMgrTest02 (void) -{ - TcpSession ssn; - Flow f; - FlowBucket fb; - struct timeval ts; - TcpSegment seg; - TcpStream client; - uint8_t payload[3] = {0x41, 0x41, 0x41}; - - FlowQueueInit(&flow_spare_q); - - memset(&ssn, 0, sizeof(TcpSession)); - memset(&f, 0, sizeof(Flow)); - memset(&fb, 0, sizeof(FlowBucket)); - memset(&ts, 0, sizeof(ts)); - memset(&seg, 0, sizeof(TcpSegment)); - memset(&client, 0, sizeof(TcpSegment)); - - FBLOCK_INIT(&fb); - FLOW_INITIALIZE(&f); - f.flags |= FLOW_TIMEOUT_REASSEMBLY_DONE; - - TimeGet(&ts); - seg.payload = payload; - seg.payload_len = 3; - seg.next = NULL; - seg.prev = NULL; - client.seg_list = &seg; - ssn.client = client; - ssn.server = client; - ssn.state = TCP_ESTABLISHED; - f.lastts.tv_sec = ts.tv_sec - 5000; - f.protoctx = &ssn; - f.fb = &fb; - f.proto = IPPROTO_TCP; - - int state = SC_ATOMIC_GET(f.flow_state); - if (FlowManagerFlowTimeout(&f, state, &ts, 0) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) { - FBLOCK_DESTROY(&fb); - FLOW_DESTROY(&f); - FlowQueueDestroy(&flow_spare_q); - return 0; - } - FBLOCK_DESTROY(&fb); - FLOW_DESTROY(&f); - FlowQueueDestroy(&flow_spare_q); - return 1; - -} - -/** - * \test Test the timing out of a flow with a fresh TcpSession - * (just initialized, no data segments) in emergency mode. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowMgrTest03 (void) -{ - TcpSession ssn; - Flow f; - FlowBucket fb; - struct timeval ts; - - FlowQueueInit(&flow_spare_q); - - memset(&ssn, 0, sizeof(TcpSession)); - memset(&f, 0, sizeof(Flow)); - memset(&ts, 0, sizeof(ts)); - memset(&fb, 0, sizeof(FlowBucket)); - - FBLOCK_INIT(&fb); - FLOW_INITIALIZE(&f); - f.flags |= FLOW_TIMEOUT_REASSEMBLY_DONE; - - TimeGet(&ts); - ssn.state = TCP_SYN_SENT; - f.lastts.tv_sec = ts.tv_sec - 300; - f.protoctx = &ssn; - f.fb = &fb; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_EMERGENCY; - - int state = SC_ATOMIC_GET(f.flow_state); - if (FlowManagerFlowTimeout(&f, state, &ts, 0) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) { - FBLOCK_DESTROY(&fb); - FLOW_DESTROY(&f); - FlowQueueDestroy(&flow_spare_q); - return 0; - } - - FBLOCK_DESTROY(&fb); - FLOW_DESTROY(&f); - FlowQueueDestroy(&flow_spare_q); - return 1; -} - -/** - * \test Test the timing out of a flow with a TcpSession - * (with data segments) in emergency mode. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowMgrTest04 (void) -{ - - TcpSession ssn; - Flow f; - FlowBucket fb; - struct timeval ts; - TcpSegment seg; - TcpStream client; - uint8_t payload[3] = {0x41, 0x41, 0x41}; - - FlowQueueInit(&flow_spare_q); - - memset(&ssn, 0, sizeof(TcpSession)); - memset(&f, 0, sizeof(Flow)); - memset(&fb, 0, sizeof(FlowBucket)); - memset(&ts, 0, sizeof(ts)); - memset(&seg, 0, sizeof(TcpSegment)); - memset(&client, 0, sizeof(TcpSegment)); - - FBLOCK_INIT(&fb); - FLOW_INITIALIZE(&f); - f.flags |= FLOW_TIMEOUT_REASSEMBLY_DONE; - - TimeGet(&ts); - seg.payload = payload; - seg.payload_len = 3; - seg.next = NULL; - seg.prev = NULL; - client.seg_list = &seg; - ssn.client = client; - ssn.server = client; - ssn.state = TCP_ESTABLISHED; - f.lastts.tv_sec = ts.tv_sec - 5000; - f.protoctx = &ssn; - f.fb = &fb; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_EMERGENCY; - - int state = SC_ATOMIC_GET(f.flow_state); - if (FlowManagerFlowTimeout(&f, state, &ts, 0) != 1 && FlowManagerFlowTimedOut(&f, &ts) != 1) { - FBLOCK_DESTROY(&fb); - FLOW_DESTROY(&f); - FlowQueueDestroy(&flow_spare_q); - return 0; - } - - FBLOCK_DESTROY(&fb); - FLOW_DESTROY(&f); - FlowQueueDestroy(&flow_spare_q); - return 1; -} - -/** - * \test Test flow allocations when it reach memcap - * - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowMgrTest05 (void) -{ - int result = 0; - - FlowInitConfig(FLOW_QUIET); - FlowConfig backup; - memcpy(&backup, &flow_config, sizeof(FlowConfig)); - - uint32_t ini = 0; - uint32_t end = flow_spare_q.len; - flow_config.memcap = 10000; - flow_config.prealloc = 100; - - /* Let's get the flow_spare_q empty */ - UTHBuildPacketOfFlows(ini, end, 0); - - /* And now let's try to reach the memcap val */ - while (FLOW_CHECK_MEMCAP(sizeof(Flow))) { - ini = end + 1; - end = end + 2; - UTHBuildPacketOfFlows(ini, end, 0); - } - - /* should time out normal */ - TimeSetIncrementTime(2000); - ini = end + 1; - end = end + 2;; - UTHBuildPacketOfFlows(ini, end, 0); - - struct timeval ts; - TimeGet(&ts); - /* try to time out flows */ - FlowTimeoutCounters counters = { 0, 0, 0, 0, }; - FlowTimeoutHash(&ts, 0 /* check all */, 0, flow_config.hash_size, &counters); - - if (flow_recycle_q.len > 0) { - result = 1; - } - - memcpy(&flow_config, &backup, sizeof(FlowConfig)); - FlowShutdown(); - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief Function to register the Flow Unitests. - */ -void FlowMgrRegisterTests (void) -{ -#ifdef UNITTESTS - UtRegisterTest("FlowMgrTest01 -- Timeout a flow having fresh TcpSession", FlowMgrTest01, 1); - UtRegisterTest("FlowMgrTest02 -- Timeout a flow having TcpSession with segments", FlowMgrTest02, 1); - UtRegisterTest("FlowMgrTest03 -- Timeout a flow in emergency having fresh TcpSession", FlowMgrTest03, 1); - UtRegisterTest("FlowMgrTest04 -- Timeout a flow in emergency having TcpSession with segments", FlowMgrTest04, 1); - UtRegisterTest("FlowMgrTest05 -- Test flow Allocations when it reach memcap", FlowMgrTest05, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/flow-manager.h b/framework/src/suricata/src/flow-manager.h deleted file mode 100644 index 32ae2b26..00000000 --- a/framework/src/suricata/src/flow-manager.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __FLOW_MANAGER_H__ -#define __FLOW_MANAGER_H__ - -/** flow manager scheduling condition */ -SCCtrlCondT flow_manager_ctrl_cond; -SCCtrlMutex flow_manager_ctrl_mutex; -#define FlowWakeupFlowManagerThread() SCCtrlCondSignal(&flow_manager_ctrl_cond) - -void FlowManagerThreadSpawn(void); -void FlowDisableFlowManagerThread(void); -void FlowMgrRegisterTests (void); - -/** flow recycler scheduling condition */ -SCCtrlCondT flow_recycler_ctrl_cond; -SCCtrlMutex flow_recycler_ctrl_mutex; -#define FlowWakeupFlowRecyclerThread() \ - SCCtrlCondSignal(&flow_recycler_ctrl_cond) - -void FlowRecyclerThreadSpawn(void); -void FlowDisableFlowRecyclerThread(void); - -void TmModuleFlowManagerRegister (void); -void TmModuleFlowRecyclerRegister (void); - -#endif /* __FLOW_MANAGER_H__ */ diff --git a/framework/src/suricata/src/flow-private.h b/framework/src/suricata/src/flow-private.h deleted file mode 100644 index bd25960b..00000000 --- a/framework/src/suricata/src/flow-private.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __FLOW_PRIVATE_H__ -#define __FLOW_PRIVATE_H__ - -#include "flow-hash.h" -#include "flow-queue.h" - -#include "util-atomic.h" - -/* global flow flags */ - -/** Flow engine is in emergency mode. This means it doesn't have enough spare - * flows for new flows and/or it's memcap limit it reached. In this state the - * flow engine with evaluate flows with lower timeout settings. */ -#define FLOW_EMERGENCY 0x01 - -/* Flow Time out values */ -#define FLOW_DEFAULT_NEW_TIMEOUT 30 -#define FLOW_DEFAULT_EST_TIMEOUT 300 -#define FLOW_DEFAULT_CLOSED_TIMEOUT 0 -#define FLOW_IPPROTO_TCP_NEW_TIMEOUT 30 -#define FLOW_IPPROTO_TCP_EST_TIMEOUT 300 -#define FLOW_IPPROTO_UDP_NEW_TIMEOUT 30 -#define FLOW_IPPROTO_UDP_EST_TIMEOUT 300 -#define FLOW_IPPROTO_ICMP_NEW_TIMEOUT 30 -#define FLOW_IPPROTO_ICMP_EST_TIMEOUT 300 - -#define FLOW_DEFAULT_EMERG_NEW_TIMEOUT 10 -#define FLOW_DEFAULT_EMERG_EST_TIMEOUT 100 -#define FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT 0 -#define FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT 10 -#define FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT 100 -#define FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT 10 -#define FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT 100 -#define FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT 10 -#define FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT 100 - -enum { - FLOW_PROTO_TCP = 0, - FLOW_PROTO_UDP, - FLOW_PROTO_ICMP, - FLOW_PROTO_SCTP, - FLOW_PROTO_DEFAULT, - - /* should be last */ - FLOW_PROTO_MAX, -}; - -/* - * Variables - */ - -/** FlowProto specific timeouts and free/state functions */ -FlowProto flow_proto[FLOW_PROTO_MAX]; - -/** spare/unused/prealloced flows live here */ -FlowQueue flow_spare_q; - -/** queue to pass flows to cleanup/log thread(s) */ -FlowQueue flow_recycle_q; - -FlowBucket *flow_hash; -FlowConfig flow_config; - -/** flow memuse counter (atomic), for enforcing memcap limit */ -SC_ATOMIC_DECLARE(long long unsigned int, flow_memuse); - -//#define FLOWBITS_STATS -#ifdef FLOWBITS_STATS -uint64_t flowbits_memuse; -uint64_t flowbits_memuse_max; -uint32_t flowbits_added; -uint32_t flowbits_removed; -SCMutex flowbits_mutex; -#endif /* FLOWBITS_STATS */ - -#endif /* __FLOW_PRIVATE_H__ */ - diff --git a/framework/src/suricata/src/flow-queue.c b/framework/src/suricata/src/flow-queue.c deleted file mode 100644 index b6a1138d..00000000 --- a/framework/src/suricata/src/flow-queue.c +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Flow queue handler functions - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "flow-private.h" -#include "flow-queue.h" -#include "flow-util.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-print.h" - -FlowQueue *FlowQueueNew() -{ - FlowQueue *q = (FlowQueue *)SCMalloc(sizeof(FlowQueue)); - if (q == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in FlowQueueNew. Exiting..."); - exit(EXIT_SUCCESS); - } - q = FlowQueueInit(q); - return q; -} - -FlowQueue *FlowQueueInit (FlowQueue *q) -{ - if (q != NULL) { - memset(q, 0, sizeof(FlowQueue)); - FQLOCK_INIT(q); - } - return q; -} - -/** - * \brief Destroy a flow queue - * - * \param q the flow queue to destroy - */ -void FlowQueueDestroy (FlowQueue *q) -{ - FQLOCK_DESTROY(q); -} - -/** - * \brief add a flow to a queue - * - * \param q queue - * \param f flow - */ -void FlowEnqueue (FlowQueue *q, Flow *f) -{ -#ifdef DEBUG - BUG_ON(q == NULL || f == NULL); -#endif - - FQLOCK_LOCK(q); - - /* more flows in queue */ - if (q->top != NULL) { - f->lnext = q->top; - q->top->lprev = f; - q->top = f; - /* only flow */ - } else { - q->top = f; - q->bot = f; - } - q->len++; -#ifdef DBG_PERF - if (q->len > q->dbg_maxlen) - q->dbg_maxlen = q->len; -#endif /* DBG_PERF */ - FQLOCK_UNLOCK(q); -} - -/** - * \brief remove a flow from the queue - * - * \param q queue - * - * \retval f flow or NULL if empty list. - */ -Flow *FlowDequeue (FlowQueue *q) -{ - FQLOCK_LOCK(q); - - Flow *f = q->bot; - if (f == NULL) { - FQLOCK_UNLOCK(q); - return NULL; - } - - /* more packets in queue */ - if (q->bot->lprev != NULL) { - q->bot = q->bot->lprev; - q->bot->lnext = NULL; - /* just the one we remove, so now empty */ - } else { - q->top = NULL; - q->bot = NULL; - } - -#ifdef DEBUG - BUG_ON(q->len == 0); -#endif - if (q->len > 0) - q->len--; - - f->lnext = NULL; - f->lprev = NULL; - - FQLOCK_UNLOCK(q); - return f; -} - -/** - * \brief Transfer a flow from a queue to the spare queue - * - * \param f the flow to be transfered - * \param q the source queue, where the flow will be removed. This queue is locked. - * - * \note spare queue needs locking - */ -void FlowMoveToSpare(Flow *f) -{ - /* now put it in spare */ - FQLOCK_LOCK(&flow_spare_q); - - /* add to new queue (append) */ - f->lprev = flow_spare_q.bot; - if (f->lprev != NULL) - f->lprev->lnext = f; - f->lnext = NULL; - flow_spare_q.bot = f; - if (flow_spare_q.top == NULL) - flow_spare_q.top = f; - - flow_spare_q.len++; -#ifdef DBG_PERF - if (flow_spare_q.len > flow_spare_q.dbg_maxlen) - flow_spare_q.dbg_maxlen = flow_spare_q.len; -#endif /* DBG_PERF */ - - FQLOCK_UNLOCK(&flow_spare_q); -} - diff --git a/framework/src/suricata/src/flow-queue.h b/framework/src/suricata/src/flow-queue.h deleted file mode 100644 index b370cd22..00000000 --- a/framework/src/suricata/src/flow-queue.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __FLOW_QUEUE_H__ -#define __FLOW_QUEUE_H__ - -#include "suricata-common.h" -#include "flow.h" - -/** Spinlocks or Mutex for the flow queues. */ -//#define FQLOCK_SPIN -#define FQLOCK_MUTEX - -#ifdef FQLOCK_SPIN - #ifdef FQLOCK_MUTEX - #error Cannot enable both FQLOCK_SPIN and FQLOCK_MUTEX - #endif -#endif - -/* Define a queue for storing flows */ -typedef struct FlowQueue_ -{ - Flow *top; - Flow *bot; - uint32_t len; -#ifdef DBG_PERF - uint32_t dbg_maxlen; -#endif /* DBG_PERF */ -#ifdef FQLOCK_MUTEX - SCMutex m; -#elif defined FQLOCK_SPIN - SCSpinlock s; -#else - #error Enable FQLOCK_SPIN or FQLOCK_MUTEX -#endif -} FlowQueue; - -#ifdef FQLOCK_SPIN - #define FQLOCK_INIT(q) SCSpinInit(&(q)->s, 0) - #define FQLOCK_DESTROY(q) SCSpinDestroy(&(q)->s) - #define FQLOCK_LOCK(q) SCSpinLock(&(q)->s) - #define FQLOCK_TRYLOCK(q) SCSpinTrylock(&(q)->s) - #define FQLOCK_UNLOCK(q) SCSpinUnlock(&(q)->s) -#elif defined FQLOCK_MUTEX - #define FQLOCK_INIT(q) SCMutexInit(&(q)->m, NULL) - #define FQLOCK_DESTROY(q) SCMutexDestroy(&(q)->m) - #define FQLOCK_LOCK(q) SCMutexLock(&(q)->m) - #define FQLOCK_TRYLOCK(q) SCMutexTrylock(&(q)->m) - #define FQLOCK_UNLOCK(q) SCMutexUnlock(&(q)->m) -#else - #error Enable FQLOCK_SPIN or FQLOCK_MUTEX -#endif - -/* prototypes */ -FlowQueue *FlowQueueNew(); -FlowQueue *FlowQueueInit(FlowQueue *); -void FlowQueueDestroy (FlowQueue *); - -void FlowEnqueue (FlowQueue *, Flow *); -Flow *FlowDequeue (FlowQueue *); - -void FlowMoveToSpare(Flow *); - -#endif /* __FLOW_QUEUE_H__ */ - diff --git a/framework/src/suricata/src/flow-storage.c b/framework/src/suricata/src/flow-storage.c deleted file mode 100644 index e4f4f8ae..00000000 --- a/framework/src/suricata/src/flow-storage.c +++ /dev/null @@ -1,296 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - * based on host-storage by Victor Julien - * - * Flow wrapper around storage api - */ - -#include "suricata-common.h" -#include "host-storage.h" -#include "flow-hash.h" -#include "flow-util.h" -#include "util-unittest.h" - -unsigned int FlowStorageSize(void) -{ - return StorageGetSize(STORAGE_FLOW); -} - -void *FlowGetStorageById(Flow *f, int id) -{ - return StorageGetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id); -} - -int FlowSetStorageById(Flow *f, int id, void *ptr) -{ - return StorageSetById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id, ptr); -} - -void *FlowAllocStorageById(Flow *f, int id) -{ - return StorageAllocByIdPrealloc((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id); -} - -void FlowFreeStorageById(Flow *f, int id) -{ - StorageFreeById((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW, id); -} - -void FlowFreeStorage(Flow *f) -{ - if (FlowStorageSize() > 0) - StorageFreeAll((Storage *)((void *)f + sizeof(Flow)), STORAGE_FLOW); -} - -int FlowStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)) { - return StorageRegister(STORAGE_FLOW, name, size, Alloc, Free); -} - -#ifdef UNITTESTS - -static void *StorageTestAlloc(unsigned int size) -{ - void *x = SCMalloc(size); - return x; -} -static void StorageTestFree(void *x) -{ - if (x) - SCFree(x); -} - -static int FlowStorageTest01(void) -{ - Flow *f = NULL; - - StorageInit(); - - int id1 = FlowStorageRegister("test", 8, StorageTestAlloc, StorageTestFree); - if (id1 < 0) - goto error; - int id2 = FlowStorageRegister("variable", 24, StorageTestAlloc, StorageTestFree); - if (id2 < 0) - goto error; - int id3 = FlowStorageRegister("store", sizeof(void *), StorageTestAlloc, StorageTestFree); - if (id3 < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - FlowInitConfig(FLOW_QUIET); - - f = FlowAlloc(); - if (f == NULL) { - goto error; - } - - void *ptr = FlowGetStorageById(f, id1); - if (ptr != NULL) { - goto error; - } - ptr = FlowGetStorageById(f, id2); - if (ptr != NULL) { - goto error; - } - ptr = FlowGetStorageById(f, id3); - if (ptr != NULL) { - goto error; - } - - void *ptr1a = FlowAllocStorageById(f, id1); - if (ptr1a == NULL) { - goto error; - } - void *ptr2a = FlowAllocStorageById(f, id2); - if (ptr2a == NULL) { - goto error; - } - void *ptr3a = FlowAllocStorageById(f, id3); - if (ptr3a == NULL) { - goto error; - } - - void *ptr1b = FlowGetStorageById(f, id1); - if (ptr1a != ptr1b) { - goto error; - } - void *ptr2b = FlowGetStorageById(f, id2); - if (ptr2a != ptr2b) { - goto error; - } - void *ptr3b = FlowGetStorageById(f, id3); - if (ptr3a != ptr3b) { - goto error; - } - - FlowClearMemory(f, 0); - FlowFree(f); - FlowShutdown(); - StorageCleanup(); - return 1; -error: - if (f != NULL) { - FlowClearMemory(f, 0); - FlowFree(f); - } - FlowShutdown(); - StorageCleanup(); - return 0; -} - -static int FlowStorageTest02(void) -{ - Flow *f = NULL; - - StorageInit(); - - int id1 = FlowStorageRegister("test", sizeof(void *), NULL, StorageTestFree); - if (id1 < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - FlowInitConfig(FLOW_QUIET); - f = FlowAlloc(); - if (f == NULL) { - goto error; - } - - void *ptr = FlowGetStorageById(f, id1); - if (ptr != NULL) { - goto error; - } - - void *ptr1a = SCMalloc(128); - if (unlikely(ptr1a == NULL)) { - goto error; - } - FlowSetStorageById(f, id1, ptr1a); - - void *ptr1b = FlowGetStorageById(f, id1); - if (ptr1a != ptr1b) { - goto error; - } - - - FlowClearMemory(f, 0); - FlowFree(f); - FlowShutdown(); - StorageCleanup(); - return 1; -error: - if (f != NULL) { - FlowClearMemory(f, 0); - FlowFree(f); - } - FlowShutdown(); - StorageCleanup(); - return 0; -} - -static int FlowStorageTest03(void) -{ - Flow *f = NULL; - - StorageInit(); - - int id1 = FlowStorageRegister("test1", sizeof(void *), NULL, StorageTestFree); - if (id1 < 0) - goto error; - int id2 = FlowStorageRegister("test2", sizeof(void *), NULL, StorageTestFree); - if (id2 < 0) - goto error; - int id3 = FlowStorageRegister("test3", 32, StorageTestAlloc, StorageTestFree); - if (id3 < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - FlowInitConfig(FLOW_QUIET); - f = FlowAlloc(); - if (f == NULL) { - goto error; - } - - void *ptr = FlowGetStorageById(f, id1); - if (ptr != NULL) { - goto error; - } - - void *ptr1a = SCMalloc(128); - if (unlikely(ptr1a == NULL)) { - goto error; - } - FlowSetStorageById(f, id1, ptr1a); - - void *ptr2a = SCMalloc(256); - if (unlikely(ptr2a == NULL)) { - goto error; - } - FlowSetStorageById(f, id2, ptr2a); - - void *ptr3a = FlowAllocStorageById(f, id3); - if (ptr3a == NULL) { - goto error; - } - - void *ptr1b = FlowGetStorageById(f, id1); - if (ptr1a != ptr1b) { - goto error; - } - void *ptr2b = FlowGetStorageById(f, id2); - if (ptr2a != ptr2b) { - goto error; - } - void *ptr3b = FlowGetStorageById(f, id3); - if (ptr3a != ptr3b) { - goto error; - } - - FlowClearMemory(f, 0); - FlowFree(f); - FlowShutdown(); - StorageCleanup(); - return 1; -error: - if (f != NULL) { - FlowClearMemory(f, 0); - FlowFree(f); - } - FlowShutdown(); - StorageCleanup(); - return 0; -} -#endif - -void RegisterFlowStorageTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("FlowStorageTest01", FlowStorageTest01, 1); - UtRegisterTest("FlowStorageTest02", FlowStorageTest02, 1); - UtRegisterTest("FlowStorageTest03", FlowStorageTest03, 1); -#endif -} diff --git a/framework/src/suricata/src/flow-storage.h b/framework/src/suricata/src/flow-storage.h deleted file mode 100644 index 93892d16..00000000 --- a/framework/src/suricata/src/flow-storage.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Flow wrapper around storage api - */ - -#ifndef __FLOW_STORAGE_H__ -#define __FLOW_STORAGE_H__ - -#include "util-storage.h" -#include "flow.h" - -unsigned int FlowStorageSize(void); - -void *FlowGetStorageById(Flow *h, int id); -int FlowSetStorageById(Flow *h, int id, void *ptr); -void *FlowAllocStorageById(Flow *h, int id); - -void FlowFreeStorageById(Flow *h, int id); -void FlowFreeStorage(Flow *h); - -void RegisterFlowStorageTests(void); - -int FlowStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)); - -#endif /* __FLOW_STORAGE_H__ */ diff --git a/framework/src/suricata/src/flow-timeout.c b/framework/src/suricata/src/flow-timeout.c deleted file mode 100644 index 8df85cdd..00000000 --- a/framework/src/suricata/src/flow-timeout.c +++ /dev/null @@ -1,572 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "conf.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "runmodes.h" - -#include "util-random.h" -#include "util-time.h" - -#include "flow.h" -#include "flow-queue.h" -#include "flow-hash.h" -#include "flow-util.h" -#include "flow-var.h" -#include "flow-private.h" -#include "flow-manager.h" -#include "pkt-var.h" -#include "host.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-byte.h" - -#include "util-debug.h" -#include "util-privs.h" - -#include "detect.h" -#include "detect-engine-state.h" -#include "stream.h" - -#include "app-layer-parser.h" -#include "app-layer.h" - -#include "util-profiling.h" - -/** - * \internal - * \brief Pseudo packet setup for flow forced reassembly. - * - * \param direction Direction of the packet. 0 indicates toserver and 1 - * indicates toclient. - * \param f Pointer to the flow. - * \param ssn Pointer to the tcp session. - * \param dummy Indicates to create a dummy pseudo packet. Not all pseudo - * packets need to force reassembly, in which case we just - * set dummy ack/seq values. - */ -static inline Packet *FlowForceReassemblyPseudoPacketSetup(Packet *p, - int direction, - Flow *f, - TcpSession *ssn, - int dummy) -{ - p->tenant_id = f->tenant_id; - p->datalink = DLT_RAW; - p->proto = IPPROTO_TCP; - FlowReference(&p->flow, f); - p->flags |= PKT_STREAM_EST; - p->flags |= PKT_STREAM_EOF; - p->flags |= PKT_HAS_FLOW; - p->flags |= PKT_PSEUDO_STREAM_END; - - if (f->flags & FLOW_NOPACKET_INSPECTION) { - DecodeSetNoPacketInspectionFlag(p); - } - if (f->flags & FLOW_NOPAYLOAD_INSPECTION) { - DecodeSetNoPayloadInspectionFlag(p); - } - - if (direction == 0) - p->flowflags |= FLOW_PKT_TOSERVER; - else - p->flowflags |= FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->payload = NULL; - p->payload_len = 0; - - if (FLOW_IS_IPV4(f)) { - if (direction == 0) { - FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->src, &p->src); - FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->dst, &p->dst); - p->sp = f->sp; - p->dp = f->dp; - } else { - FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->src, &p->dst); - FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->dst, &p->src); - p->sp = f->dp; - p->dp = f->sp; - } - - /* Check if we have enough room in direct data. We need ipv4 hdr + tcp hdr. - * Force an allocation if it is not the case. - */ - if (GET_PKT_DIRECT_MAX_SIZE(p) < 40) { - if (PacketCallocExtPkt(p, 40) == -1) { - return NULL; - } - } - /* set the ip header */ - p->ip4h = (IPV4Hdr *)GET_PKT_DATA(p); - /* version 4 and length 20 bytes for the tcp header */ - p->ip4h->ip_verhl = 0x45; - p->ip4h->ip_tos = 0; - p->ip4h->ip_len = htons(40); - p->ip4h->ip_id = 0; - p->ip4h->ip_off = 0; - p->ip4h->ip_ttl = 64; - p->ip4h->ip_proto = IPPROTO_TCP; - //p->ip4h->ip_csum = - if (direction == 0) { - p->ip4h->s_ip_src.s_addr = f->src.addr_data32[0]; - p->ip4h->s_ip_dst.s_addr = f->dst.addr_data32[0]; - } else { - p->ip4h->s_ip_src.s_addr = f->dst.addr_data32[0]; - p->ip4h->s_ip_dst.s_addr = f->src.addr_data32[0]; - } - - /* set the tcp header */ - p->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(p) + 20); - - SET_PKT_LEN(p, 40); /* ipv4 hdr + tcp hdr */ - - } else if (FLOW_IS_IPV6(f)) { - if (direction == 0) { - FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->src, &p->src); - FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->dst, &p->dst); - p->sp = f->sp; - p->dp = f->dp; - } else { - FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->src, &p->dst); - FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->dst, &p->src); - p->sp = f->dp; - p->dp = f->sp; - } - - /* Check if we have enough room in direct data. We need ipv6 hdr + tcp hdr. - * Force an allocation if it is not the case. - */ - if (GET_PKT_DIRECT_MAX_SIZE(p) < 60) { - if (PacketCallocExtPkt(p, 60) == -1) { - return NULL; - } - } - /* set the ip header */ - p->ip6h = (IPV6Hdr *)GET_PKT_DATA(p); - /* version 6 */ - p->ip6h->s_ip6_vfc = 0x60; - p->ip6h->s_ip6_flow = 0; - p->ip6h->s_ip6_nxt = IPPROTO_TCP; - p->ip6h->s_ip6_plen = htons(20); - p->ip6h->s_ip6_hlim = 64; - if (direction == 0) { - p->ip6h->s_ip6_src[0] = f->src.addr_data32[0]; - p->ip6h->s_ip6_src[1] = f->src.addr_data32[1]; - p->ip6h->s_ip6_src[2] = f->src.addr_data32[2]; - p->ip6h->s_ip6_src[3] = f->src.addr_data32[3]; - p->ip6h->s_ip6_dst[0] = f->dst.addr_data32[0]; - p->ip6h->s_ip6_dst[1] = f->dst.addr_data32[1]; - p->ip6h->s_ip6_dst[2] = f->dst.addr_data32[2]; - p->ip6h->s_ip6_dst[3] = f->dst.addr_data32[3]; - } else { - p->ip6h->s_ip6_src[0] = f->dst.addr_data32[0]; - p->ip6h->s_ip6_src[1] = f->dst.addr_data32[1]; - p->ip6h->s_ip6_src[2] = f->dst.addr_data32[2]; - p->ip6h->s_ip6_src[3] = f->dst.addr_data32[3]; - p->ip6h->s_ip6_dst[0] = f->src.addr_data32[0]; - p->ip6h->s_ip6_dst[1] = f->src.addr_data32[1]; - p->ip6h->s_ip6_dst[2] = f->src.addr_data32[2]; - p->ip6h->s_ip6_dst[3] = f->src.addr_data32[3]; - } - - /* set the tcp header */ - p->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(p) + 40); - - SET_PKT_LEN(p, 60); /* ipv6 hdr + tcp hdr */ - } - - p->tcph->th_offx2 = 0x50; - p->tcph->th_flags |= TH_ACK; - p->tcph->th_win = 10; - p->tcph->th_urp = 0; - - /* to server */ - if (direction == 0) { - p->tcph->th_sport = htons(f->sp); - p->tcph->th_dport = htons(f->dp); - - if (dummy) { - p->tcph->th_seq = htonl(ssn->client.next_seq); - p->tcph->th_ack = htonl(ssn->server.last_ack); - } else { - p->tcph->th_seq = htonl(ssn->client.next_seq); - p->tcph->th_ack = htonl(ssn->server.seg_list_tail->seq + - ssn->server.seg_list_tail->payload_len); - } - - /* to client */ - } else { - p->tcph->th_sport = htons(f->dp); - p->tcph->th_dport = htons(f->sp); - - if (dummy) { - p->tcph->th_seq = htonl(ssn->server.next_seq); - p->tcph->th_ack = htonl(ssn->client.last_ack); - } else { - p->tcph->th_seq = htonl(ssn->server.next_seq); - p->tcph->th_ack = htonl(ssn->client.seg_list_tail->seq + - ssn->client.seg_list_tail->payload_len); - } - } - - if (FLOW_IS_IPV4(f)) { - p->tcph->th_sum = TCPCalculateChecksum(p->ip4h->s_ip_addrs, - (uint16_t *)p->tcph, 20); - /* calc ipv4 csum as we may log it and barnyard might reject - * a wrong checksum */ - p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h, - IPV4_GET_RAW_HLEN(p->ip4h)); - } else if (FLOW_IS_IPV6(f)) { - p->tcph->th_sum = TCPCalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, 20); - } - - memset(&p->ts, 0, sizeof(struct timeval)); - TimeGet(&p->ts); - - AppLayerParserSetEOF(f->alparser); - - return p; -} - -static inline Packet *FlowForceReassemblyPseudoPacketGet(int direction, - Flow *f, - TcpSession *ssn, - int dummy) -{ - PacketPoolWait(); - Packet *p = PacketPoolGetPacket(); - if (p == NULL) { - return NULL; - } - - PACKET_PROFILING_START(p); - - return FlowForceReassemblyPseudoPacketSetup(p, direction, f, ssn, dummy); -} - -/** - * \brief Check if a flow needs forced reassembly, or any other processing - * - * \param f *LOCKED* flow - * \param server ptr to int that should be set to 1 or 2 if we return 1 - * \param client ptr to int that should be set to 1 or 2 if we return 1 - * - * \retval 0 no - * \retval 1 yes - */ -int FlowForceReassemblyNeedReassembly(Flow *f, int *server, int *client) -{ - TcpSession *ssn; - - if (f == NULL) { - *server = *client = STREAM_HAS_UNPROCESSED_SEGMENTS_NONE; - SCReturnInt(0); - } - - /* Get the tcp session for the flow */ - ssn = (TcpSession *)f->protoctx; - if (ssn == NULL) { - *server = *client = STREAM_HAS_UNPROCESSED_SEGMENTS_NONE; - SCReturnInt(0); - } - - *client = StreamNeedsReassembly(ssn, 0); - *server = StreamNeedsReassembly(ssn, 1); - - /* if state is not fully closed we assume that we haven't fully - * inspected the app layer state yet */ - if (ssn->state >= TCP_ESTABLISHED && ssn->state != TCP_CLOSED) - { - if (*client != STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) - *client = STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION; - - if (*server != STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) - *server = STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION; - } - - /* if app layer still needs some love, push through */ - if (f->alproto != ALPROTO_UNKNOWN && f->alstate != NULL && - AppLayerParserProtocolSupportsTxs(f->proto, f->alproto)) - { - uint64_t total_txs = AppLayerParserGetTxCnt(f->proto, f->alproto, f->alstate); - - if (AppLayerParserGetTransactionActive(f->proto, f->alproto, - f->alparser, STREAM_TOCLIENT) < total_txs) - { - if (*server != STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) - *server = STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION; - } - if (AppLayerParserGetTransactionActive(f->proto, f->alproto, - f->alparser, STREAM_TOSERVER) < total_txs) - { - if (*client != STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) - *client = STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION; - } - } - - /* nothing to do */ - if (*client == STREAM_HAS_UNPROCESSED_SEGMENTS_NONE && - *server == STREAM_HAS_UNPROCESSED_SEGMENTS_NONE) { - SCReturnInt(0); - } - - SCReturnInt(1); -} - -/** - * \internal - * \brief Forces reassembly for flow if it needs it. - * - * The function requires flow to be locked beforehand. - * - * \param f Pointer to the flow. - * \param server action required for server: 1 or 2 - * \param client action required for client: 1 or 2 - * - * \retval 0 This flow doesn't need any reassembly processing; 1 otherwise. - */ -int FlowForceReassemblyForFlow(Flow *f, int server, int client) -{ - Packet *p1 = NULL, *p2 = NULL, *p3 = NULL; - TcpSession *ssn; - - /* looks like we have no flows in this queue */ - if (f == NULL) { - return 0; - } - - /* Get the tcp session for the flow */ - ssn = (TcpSession *)f->protoctx; - if (ssn == NULL) { - return 0; - } - - /* The packets we use are based on what segments in what direction are - * unprocessed. - * p1 if we have client segments for reassembly purpose only. If we - * have no server segments p2 can be a toserver packet with dummy - * seq/ack, and if we have server segments p2 has to carry out reassembly - * for server segment as well, in which case we will also need a p3 in the - * toclient which is now dummy since all we need it for is detection */ - - /* insert a pseudo packet in the toserver direction */ - if (client == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) { - p1 = FlowForceReassemblyPseudoPacketGet(1, f, ssn, 0); - if (p1 == NULL) { - goto done; - } - PKT_SET_SRC(p1, PKT_SRC_FFR); - - if (server == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) { - p2 = FlowForceReassemblyPseudoPacketGet(0, f, ssn, 0); - if (p2 == NULL) { - FlowDeReference(&p1->flow); - TmqhOutputPacketpool(NULL, p1); - goto done; - } - PKT_SET_SRC(p2, PKT_SRC_FFR); - - p3 = FlowForceReassemblyPseudoPacketGet(1, f, ssn, 1); - if (p3 == NULL) { - FlowDeReference(&p1->flow); - TmqhOutputPacketpool(NULL, p1); - FlowDeReference(&p2->flow); - TmqhOutputPacketpool(NULL, p2); - goto done; - } - PKT_SET_SRC(p3, PKT_SRC_FFR); - } else { - p2 = FlowForceReassemblyPseudoPacketGet(0, f, ssn, 1); - if (p2 == NULL) { - FlowDeReference(&p1->flow); - TmqhOutputPacketpool(NULL, p1); - goto done; - } - PKT_SET_SRC(p2, PKT_SRC_FFR); - } - - } else if (client == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION) { - if (server == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) { - p1 = FlowForceReassemblyPseudoPacketGet(0, f, ssn, 0); - if (p1 == NULL) { - goto done; - } - PKT_SET_SRC(p1, PKT_SRC_FFR); - - p2 = FlowForceReassemblyPseudoPacketGet(1, f, ssn, 1); - if (p2 == NULL) { - FlowDeReference(&p1->flow); - TmqhOutputPacketpool(NULL, p1); - goto done; - } - PKT_SET_SRC(p2, PKT_SRC_FFR); - } else { - p1 = FlowForceReassemblyPseudoPacketGet(0, f, ssn, 1); - if (p1 == NULL) { - goto done; - } - PKT_SET_SRC(p1, PKT_SRC_FFR); - - if (server == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION) { - p2 = FlowForceReassemblyPseudoPacketGet(1, f, ssn, 1); - if (p2 == NULL) { - FlowDeReference(&p1->flow); - TmqhOutputPacketpool(NULL, p1); - goto done; - } - PKT_SET_SRC(p2, PKT_SRC_FFR); - } - } - - } else { - if (server == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY) { - p1 = FlowForceReassemblyPseudoPacketGet(0, f, ssn, 0); - if (p1 == NULL) { - goto done; - } - PKT_SET_SRC(p1, PKT_SRC_FFR); - - p2 = FlowForceReassemblyPseudoPacketGet(1, f, ssn, 1); - if (p2 == NULL) { - FlowDeReference(&p1->flow); - TmqhOutputPacketpool(NULL, p1); - goto done; - } - PKT_SET_SRC(p2, PKT_SRC_FFR); - } else if (server == STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION) { - p1 = FlowForceReassemblyPseudoPacketGet(1, f, ssn, 1); - if (p1 == NULL) { - goto done; - } - PKT_SET_SRC(p1, PKT_SRC_FFR); - } else { - /* impossible */ - BUG_ON(1); - } - } - - /* inject the packet(s) into the appropriate thread */ - int thread_id = (int)f->thread_id; - Packet *packets[4] = { p1, p2 ? p2 : p3, p2 ? p3 : NULL, NULL }; /**< null terminated array of packets */ - if (unlikely(!(TmThreadsInjectPacketsById(packets, thread_id)))) { - FlowDeReference(&p1->flow); - TmqhOutputPacketpool(NULL, p1); - if (p2) { - FlowDeReference(&p2->flow); - TmqhOutputPacketpool(NULL, p2); - } - if (p3) { - FlowDeReference(&p3->flow); - TmqhOutputPacketpool(NULL, p3); - } - } - - /* done, in case of error (no packet) we still tag flow as complete - * as we're probably resource stress if we couldn't get packets */ -done: - f->flags |= FLOW_TIMEOUT_REASSEMBLY_DONE; - return 1; -} - -/** - * \internal - * \brief Forces reassembly for flows that need it. - * - * When this function is called we're running in virtually dead engine, - * so locking the flows is not strictly required. The reasons it is still - * done are: - * - code consistency - * - silence complaining profilers - * - allow us to aggressively check using debug valdation assertions - * - be robust in case of future changes - * - locking overhead if neglectable when no other thread fights us - * - * \param q The queue to process flows from. - */ -static inline void FlowForceReassemblyForHash(void) -{ - Flow *f; - TcpSession *ssn; - int client_ok = 0; - int server_ok = 0; - uint32_t idx = 0; - - for (idx = 0; idx < flow_config.hash_size; idx++) { - FlowBucket *fb = &flow_hash[idx]; - - PacketPoolWaitForN(9); - FBLOCK_LOCK(fb); - - /* get the topmost flow from the QUEUE */ - f = fb->head; - - /* we need to loop through all the flows in the queue */ - while (f != NULL) { - PacketPoolWaitForN(3); - - FLOWLOCK_WRLOCK(f); - - /* Get the tcp session for the flow */ - ssn = (TcpSession *)f->protoctx; - - /* \todo Also skip flows that shouldn't be inspected */ - if (ssn == NULL) { - FLOWLOCK_UNLOCK(f); - f = f->hnext; - continue; - } - - if (FlowForceReassemblyNeedReassembly(f, &server_ok, &client_ok) == 1) { - FlowForceReassemblyForFlow(f, server_ok, client_ok); - } - - FLOWLOCK_UNLOCK(f); - - /* next flow in the queue */ - f = f->hnext; - } - FBLOCK_UNLOCK(fb); - } - return; -} - -/** - * \brief Force reassembly for all the flows that have unprocessed segments. - */ -void FlowForceReassembly(void) -{ - /* Carry out flow reassembly for unattended flows */ - FlowForceReassemblyForHash(); - return; -} - diff --git a/framework/src/suricata/src/flow-timeout.h b/framework/src/suricata/src/flow-timeout.h deleted file mode 100644 index 50e007ae..00000000 --- a/framework/src/suricata/src/flow-timeout.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __FLOW_TIMEOUT_H__ -#define __FLOW_TIMEOUT_H__ - -int FlowForceReassemblyForFlow(Flow *f, int server, int client); -int FlowForceReassemblyNeedReassembly(Flow *f, int *server, int *client); -void FlowForceReassembly(void); -void FlowForceReassemblySetup(int detect_disabled); - -#endif /* __FLOW_TIMEOUT_H__ */ diff --git a/framework/src/suricata/src/flow-util.c b/framework/src/suricata/src/flow-util.c deleted file mode 100644 index b4b54c18..00000000 --- a/framework/src/suricata/src/flow-util.c +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Flow utility functions - */ - -#include "suricata-common.h" -#include "threads.h" - -#include "flow.h" -#include "flow-private.h" -#include "flow-util.h" -#include "flow-var.h" -#include "app-layer.h" - -#include "util-var.h" -#include "util-debug.h" -#include "flow-storage.h" - -#include "detect.h" -#include "detect-engine-state.h" - -/** \brief allocate a flow - * - * We check against the memuse counter. If it passes that check we increment - * the counter first, then we try to alloc. - * - * \retval f the flow or NULL on out of memory - */ -Flow *FlowAlloc(void) -{ - Flow *f; - size_t size = sizeof(Flow) + FlowStorageSize(); - - if (!(FLOW_CHECK_MEMCAP(size))) { - return NULL; - } - - (void) SC_ATOMIC_ADD(flow_memuse, size); - - f = SCMalloc(size); - if (unlikely(f == NULL)) { - (void)SC_ATOMIC_SUB(flow_memuse, size); - return NULL; - } - memset(f, 0, size); - - FLOW_INITIALIZE(f); - return f; -} - - -/** - * \brief cleanup & free the memory of a flow - * - * \param f flow to clear & destroy - */ -void FlowFree(Flow *f) -{ - FLOW_DESTROY(f); - SCFree(f); - - size_t size = sizeof(Flow) + FlowStorageSize(); - (void) SC_ATOMIC_SUB(flow_memuse, size); -} - -/** - * \brief Function to map the protocol to the defined FLOW_PROTO_* enumeration. - * - * \param proto protocol which is needed to be mapped - */ - -uint8_t FlowGetProtoMapping(uint8_t proto) -{ - switch (proto) { - case IPPROTO_TCP: - return FLOW_PROTO_TCP; - case IPPROTO_UDP: - return FLOW_PROTO_UDP; - case IPPROTO_ICMP: - return FLOW_PROTO_ICMP; - case IPPROTO_SCTP: - return FLOW_PROTO_SCTP; - default: - return FLOW_PROTO_DEFAULT; - } -} - -uint8_t FlowGetReverseProtoMapping(uint8_t rproto) -{ - switch (rproto) { - case FLOW_PROTO_TCP: - return IPPROTO_TCP; - case FLOW_PROTO_UDP: - return IPPROTO_UDP; - case FLOW_PROTO_ICMP: - return IPPROTO_ICMP; - case FLOW_PROTO_SCTP: - return IPPROTO_SCTP; - default: - exit(EXIT_FAILURE); - } -} - -/* initialize the flow from the first packet - * we see from it. */ -void FlowInit(Flow *f, const Packet *p) -{ - SCEnter(); - SCLogDebug("flow %p", f); - - f->proto = p->proto; - f->recursion_level = p->recursion_level; - f->vlan_id[0] = p->vlan_id[0]; - f->vlan_id[1] = p->vlan_id[1]; - - if (PKT_IS_IPV4(p)) { - FLOW_SET_IPV4_SRC_ADDR_FROM_PACKET(p, &f->src); - FLOW_SET_IPV4_DST_ADDR_FROM_PACKET(p, &f->dst); - f->flags |= FLOW_IPV4; - } else if (PKT_IS_IPV6(p)) { - FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(p, &f->src); - FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(p, &f->dst); - f->flags |= FLOW_IPV6; - } -#ifdef DEBUG - /* XXX handle default */ - else { - printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__); - } -#endif - - if (p->tcph != NULL) { /* XXX MACRO */ - SET_TCP_SRC_PORT(p,&f->sp); - SET_TCP_DST_PORT(p,&f->dp); - } else if (p->udph != NULL) { /* XXX MACRO */ - SET_UDP_SRC_PORT(p,&f->sp); - SET_UDP_DST_PORT(p,&f->dp); - } else if (p->icmpv4h != NULL) { - f->type = p->type; - f->code = p->code; - } else if (p->icmpv6h != NULL) { - f->type = p->type; - f->code = p->code; - } else if (p->sctph != NULL) { /* XXX MACRO */ - SET_SCTP_SRC_PORT(p,&f->sp); - SET_SCTP_DST_PORT(p,&f->dp); - } /* XXX handle default */ -#ifdef DEBUG - else { - printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__); - } -#endif - COPY_TIMESTAMP(&p->ts, &f->startts); - - f->protomap = FlowGetProtoMapping(f->proto); - - SCReturn; -} - diff --git a/framework/src/suricata/src/flow-util.h b/framework/src/suricata/src/flow-util.h deleted file mode 100644 index ca6a49cc..00000000 --- a/framework/src/suricata/src/flow-util.h +++ /dev/null @@ -1,153 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __FLOW_UTIL_H__ -#define __FLOW_UTIL_H__ - -#include "detect-engine-state.h" -#include "tmqh-flow.h" - -#define COPY_TIMESTAMP(src,dst) ((dst)->tv_sec = (src)->tv_sec, (dst)->tv_usec = (src)->tv_usec) - -#define RESET_COUNTERS(f) do { \ - (f)->todstpktcnt = 0; \ - (f)->tosrcpktcnt = 0; \ - (f)->todstbytecnt = 0; \ - (f)->tosrcbytecnt = 0; \ - } while (0) - -#define FLOW_INITIALIZE(f) do { \ - (f)->sp = 0; \ - (f)->dp = 0; \ - (f)->proto = 0; \ - SC_ATOMIC_INIT((f)->flow_state); \ - SC_ATOMIC_INIT((f)->use_cnt); \ - (f)->tenant_id = 0; \ - (f)->probing_parser_toserver_alproto_masks = 0; \ - (f)->probing_parser_toclient_alproto_masks = 0; \ - (f)->flags = 0; \ - (f)->lastts.tv_sec = 0; \ - (f)->lastts.tv_usec = 0; \ - FLOWLOCK_INIT((f)); \ - (f)->protoctx = NULL; \ - (f)->flow_end_flags = 0; \ - (f)->alproto = 0; \ - (f)->alproto_ts = 0; \ - (f)->alproto_tc = 0; \ - (f)->data_al_so_far[0] = 0; \ - (f)->data_al_so_far[1] = 0; \ - (f)->de_ctx_id = 0; \ - (f)->thread_id = 0; \ - (f)->detect_alversion[0] = 0; \ - (f)->detect_alversion[1] = 0; \ - (f)->alparser = NULL; \ - (f)->alstate = NULL; \ - (f)->de_state = NULL; \ - (f)->sgh_toserver = NULL; \ - (f)->sgh_toclient = NULL; \ - (f)->flowvar = NULL; \ - (f)->hnext = NULL; \ - (f)->hprev = NULL; \ - (f)->lnext = NULL; \ - (f)->lprev = NULL; \ - SC_ATOMIC_INIT((f)->autofp_tmqh_flow_qid); \ - (void) SC_ATOMIC_SET((f)->autofp_tmqh_flow_qid, -1); \ - RESET_COUNTERS((f)); \ - } while (0) - -/** \brief macro to recycle a flow before it goes into the spare queue for reuse. - * - * Note that the lnext, lprev, hnext, hprev fields are untouched, those are - * managed by the queueing code. Same goes for fb (FlowBucket ptr) field. - */ -#define FLOW_RECYCLE(f) do { \ - FlowCleanupAppLayer((f)); \ - (f)->sp = 0; \ - (f)->dp = 0; \ - (f)->proto = 0; \ - SC_ATOMIC_RESET((f)->flow_state); \ - SC_ATOMIC_RESET((f)->use_cnt); \ - (f)->tenant_id = 0; \ - (f)->probing_parser_toserver_alproto_masks = 0; \ - (f)->probing_parser_toclient_alproto_masks = 0; \ - (f)->flags = 0; \ - (f)->lastts.tv_sec = 0; \ - (f)->lastts.tv_usec = 0; \ - (f)->protoctx = NULL; \ - (f)->flow_end_flags = 0; \ - (f)->alparser = NULL; \ - (f)->alstate = NULL; \ - (f)->alproto = 0; \ - (f)->alproto_ts = 0; \ - (f)->alproto_tc = 0; \ - (f)->data_al_so_far[0] = 0; \ - (f)->data_al_so_far[1] = 0; \ - (f)->de_ctx_id = 0; \ - (f)->thread_id = 0; \ - (f)->detect_alversion[0] = 0; \ - (f)->detect_alversion[1] = 0; \ - if ((f)->de_state != NULL) { \ - DetectEngineStateReset((f)->de_state, (STREAM_TOSERVER | STREAM_TOCLIENT)); \ - } \ - (f)->sgh_toserver = NULL; \ - (f)->sgh_toclient = NULL; \ - GenericVarFree((f)->flowvar); \ - (f)->flowvar = NULL; \ - if (SC_ATOMIC_GET((f)->autofp_tmqh_flow_qid) != -1) { \ - (void) SC_ATOMIC_SET((f)->autofp_tmqh_flow_qid, -1); \ - } \ - RESET_COUNTERS((f)); \ - } while(0) - -#define FLOW_DESTROY(f) do { \ - FlowCleanupAppLayer((f)); \ - SC_ATOMIC_DESTROY((f)->flow_state); \ - SC_ATOMIC_DESTROY((f)->use_cnt); \ - \ - FLOWLOCK_DESTROY((f)); \ - if ((f)->de_state != NULL) { \ - DetectEngineStateFlowFree((f)->de_state); \ - } \ - GenericVarFree((f)->flowvar); \ - SC_ATOMIC_DESTROY((f)->autofp_tmqh_flow_qid); \ - } while(0) - -/** \brief check if a memory alloc would fit in the memcap - * - * \param size memory allocation size to check - * - * \retval 1 it fits - * \retval 0 no fit - */ -#define FLOW_CHECK_MEMCAP(size) \ - ((((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)(size)) <= flow_config.memcap)) - -Flow *FlowAlloc(void); -Flow *FlowAllocDirect(void); -void FlowFree(Flow *); -uint8_t FlowGetProtoMapping(uint8_t); -void FlowInit(Flow *, const Packet *); -uint8_t FlowGetReverseProtoMapping(uint8_t rproto); - -#endif /* __FLOW_UTIL_H__ */ - diff --git a/framework/src/suricata/src/flow-var.c b/framework/src/suricata/src/flow-var.c deleted file mode 100644 index 5262b5a7..00000000 --- a/framework/src/suricata/src/flow-var.c +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon - * - * Flow level variable support for complex detection rules - * Supported types atm are String and Integers - */ - -#include "suricata-common.h" -#include "threads.h" -#include "flow-var.h" -#include "flow.h" -#include "detect.h" -#include "util-debug.h" - -/* puts a new value into a flowvar */ -static void FlowVarUpdateStr(FlowVar *fv, uint8_t *value, uint16_t size) -{ - if (fv->data.fv_str.value) - SCFree(fv->data.fv_str.value); - fv->data.fv_str.value = value; - fv->data.fv_str.value_len = size; -} - -/* puts a new value into a flowvar */ -static void FlowVarUpdateInt(FlowVar *fv, uint32_t value) -{ - fv->data.fv_int.value = value; -} - -/** \brief get the flowvar with index 'idx' from the flow - * \note flow is not locked by this function, caller is - * responsible - */ -FlowVar *FlowVarGet(Flow *f, uint16_t idx) -{ - GenericVar *gv = f->flowvar; - - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_FLOWVAR && gv->idx == idx) - return (FlowVar *)gv; - } - - return NULL; -} - -/* add a flowvar to the flow, or update it */ -void FlowVarAddStrNoLock(Flow *f, uint16_t idx, uint8_t *value, uint16_t size) -{ - FlowVar *fv = FlowVarGet(f, idx); - if (fv == NULL) { - fv = SCMalloc(sizeof(FlowVar)); - if (unlikely(fv == NULL)) - return; - - fv->type = DETECT_FLOWVAR; - fv->datatype = FLOWVAR_TYPE_STR; - fv->idx = idx; - fv->data.fv_str.value = value; - fv->data.fv_str.value_len = size; - fv->next = NULL; - - GenericVarAppend(&f->flowvar, (GenericVar *)fv); - } else { - FlowVarUpdateStr(fv, value, size); - } -} - -/* add a flowvar to the flow, or update it */ -void FlowVarAddStr(Flow *f, uint16_t idx, uint8_t *value, uint16_t size) -{ - FLOWLOCK_WRLOCK(f); - FlowVarAddStrNoLock(f, idx, value, size); - FLOWLOCK_UNLOCK(f); -} - -/* add a flowvar to the flow, or update it */ -void FlowVarAddIntNoLock(Flow *f, uint16_t idx, uint32_t value) -{ - FlowVar *fv = FlowVarGet(f, idx); - if (fv == NULL) { - fv = SCMalloc(sizeof(FlowVar)); - if (unlikely(fv == NULL)) - return; - - fv->type = DETECT_FLOWVAR; - fv->datatype = FLOWVAR_TYPE_INT; - fv->idx = idx; - fv->data.fv_int.value= value; - fv->next = NULL; - - GenericVarAppend(&f->flowvar, (GenericVar *)fv); - } else { - FlowVarUpdateInt(fv, value); - } -} - -/* add a flowvar to the flow, or update it */ -void FlowVarAddInt(Flow *f, uint16_t idx, uint32_t value) -{ - FLOWLOCK_WRLOCK(f); - FlowVarAddIntNoLock(f, idx, value); - FLOWLOCK_UNLOCK(f); -} - -void FlowVarFree(FlowVar *fv) -{ - if (fv == NULL) - return; - - if (fv->datatype == FLOWVAR_TYPE_STR) { - if (fv->data.fv_str.value != NULL) - SCFree(fv->data.fv_str.value); - } - SCFree(fv); -} - -void FlowVarPrint(GenericVar *gv) -{ - uint16_t u; - - if (!SCLogDebugEnabled()) - return; - - if (gv == NULL) - return; - - if (gv->type == DETECT_FLOWVAR || gv->type == DETECT_FLOWINT) { - FlowVar *fv = (FlowVar *)gv; - - if (fv->datatype == FLOWVAR_TYPE_STR) { - SCLogDebug("Name idx \"%" PRIu16 "\", Value \"", fv->idx); - for (u = 0; u < fv->data.fv_str.value_len; u++) { - if (isprint(fv->data.fv_str.value[u])) - SCLogDebug("%c", fv->data.fv_str.value[u]); - else - SCLogDebug("\\%02X", fv->data.fv_str.value[u]); - } - SCLogDebug("\", Len \"%" PRIu16 "\"\n", fv->data.fv_str.value_len); - } else if (fv->datatype == FLOWVAR_TYPE_INT) { - SCLogDebug("Name idx \"%" PRIu16 "\", Value \"%" PRIu32 "\"", fv->idx, - fv->data.fv_int.value); - } else { - SCLogDebug("Unknown data type at flowvars\n"); - } - } - FlowVarPrint(gv->next); -} - diff --git a/framework/src/suricata/src/flow-var.h b/framework/src/suricata/src/flow-var.h deleted file mode 100644 index e45d8030..00000000 --- a/framework/src/suricata/src/flow-var.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon - */ - -#ifndef __FLOW_VAR_H__ -#define __FLOW_VAR_H__ - -#include "flow.h" -#include "util-var.h" - -/** Available data types for Flowvars */ - -#define FLOWVAR_TYPE_STR 1 -#define FLOWVAR_TYPE_INT 2 - -/** Struct used to hold the string data type for flowvars */ -typedef struct FlowVarTypeStr { - uint8_t *value; - uint16_t value_len; -} FlowVarTypeStr; - -/** Struct used to hold the integer data type for flowvars */ -typedef struct FlowVarTypeInt_ { - uint32_t value; -} FlowVarTypeInt; - -/** Generic Flowvar Structure */ -typedef struct FlowVar_ { - uint8_t type; /* type, DETECT_FLOWVAR in this case */ - uint16_t idx; /* name idx */ - GenericVar *next; /* right now just implement this as a list, - * in the long run we have think of something - * faster. */ - uint8_t datatype; - union { - FlowVarTypeStr fv_str; - FlowVarTypeInt fv_int; - } data; - -} FlowVar; - -/** Flowvar Interface API */ - -void FlowVarAddStrNoLock(Flow *, uint16_t, uint8_t *, uint16_t); -void FlowVarAddStr(Flow *, uint16_t, uint8_t *, uint16_t); -void FlowVarAddIntNoLock(Flow *, uint16_t, uint32_t); -void FlowVarAddInt(Flow *, uint16_t, uint32_t); -FlowVar *FlowVarGet(Flow *, uint16_t); -void FlowVarFree(FlowVar *); -void FlowVarPrint(GenericVar *); - -#endif /* __FLOW_VAR_H__ */ - diff --git a/framework/src/suricata/src/flow.c b/framework/src/suricata/src/flow.c deleted file mode 100644 index abd9e7e5..00000000 --- a/framework/src/suricata/src/flow.c +++ /dev/null @@ -1,1147 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Flow implementation. - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "conf.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "runmodes.h" - -#include "util-random.h" -#include "util-time.h" - -#include "flow.h" -#include "flow-queue.h" -#include "flow-hash.h" -#include "flow-util.h" -#include "flow-var.h" -#include "flow-private.h" -#include "flow-timeout.h" -#include "flow-manager.h" -#include "flow-storage.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-byte.h" -#include "util-misc.h" - -#include "util-debug.h" -#include "util-privs.h" - -#include "detect.h" -#include "detect-engine-state.h" -#include "stream.h" - -#include "app-layer-parser.h" - -#define FLOW_DEFAULT_EMERGENCY_RECOVERY 30 - -//#define FLOW_DEFAULT_HASHSIZE 262144 -#define FLOW_DEFAULT_HASHSIZE 65536 -//#define FLOW_DEFAULT_MEMCAP 128 * 1024 * 1024 /* 128 MB */ -#define FLOW_DEFAULT_MEMCAP (32 * 1024 * 1024) /* 32 MB */ - -#define FLOW_DEFAULT_PREALLOC 10000 - -/** atomic int that is used when freeing a flow from the hash. In this - * case we walk the hash to find a flow to free. This var records where - * we left off in the hash. Without this only the top rows of the hash - * are freed. This isn't just about fairness. Under severe presure, the - * hash rows on top would be all freed and the time to find a flow to - * free increased with every run. */ -SC_ATOMIC_DECLARE(unsigned int, flow_prune_idx); - -/** atomic flags */ -SC_ATOMIC_DECLARE(unsigned int, flow_flags); - -void FlowRegisterTests(void); -void FlowInitFlowProto(); -int FlowSetProtoTimeout(uint8_t , uint32_t ,uint32_t ,uint32_t); -int FlowSetProtoEmergencyTimeout(uint8_t , uint32_t ,uint32_t ,uint32_t); -int FlowSetProtoFreeFunc(uint8_t, void (*Free)(void *)); - -/* Run mode selected at suricata.c */ -extern int run_mode; - -void FlowCleanupAppLayer(Flow *f) -{ - if (f == NULL || f->proto == 0) - return; - - AppLayerParserStateCleanup(f->proto, f->alproto, f->alstate, f->alparser); - f->alstate = NULL; - f->alparser = NULL; - return; -} - -/** \brief Make sure we have enough spare flows. - * - * Enforce the prealloc parameter, so keep at least prealloc flows in the - * spare queue and free flows going over the limit. - * - * \retval 1 if the queue was properly updated (or if it already was in good shape) - * \retval 0 otherwise. - */ -int FlowUpdateSpareFlows(void) -{ - SCEnter(); - uint32_t toalloc = 0, tofree = 0, len; - - FQLOCK_LOCK(&flow_spare_q); - len = flow_spare_q.len; - FQLOCK_UNLOCK(&flow_spare_q); - - if (len < flow_config.prealloc) { - toalloc = flow_config.prealloc - len; - - uint32_t i; - for (i = 0; i < toalloc; i++) { - Flow *f = FlowAlloc(); - if (f == NULL) - return 0; - - FlowEnqueue(&flow_spare_q,f); - } - } else if (len > flow_config.prealloc) { - tofree = len - flow_config.prealloc; - - uint32_t i; - for (i = 0; i < tofree; i++) { - /* FlowDequeue locks the queue */ - Flow *f = FlowDequeue(&flow_spare_q); - if (f == NULL) - return 1; - - FlowFree(f); - } - } - - return 1; -} - -/** \brief Set the IPOnly scanned flag for 'direction'. This function - * handles the locking too. - * \param f Flow to set the flag in - * \param direction direction to set the flag in - */ -void FlowSetIPOnlyFlag(Flow *f, char direction) -{ - FLOWLOCK_WRLOCK(f); - direction ? (f->flags |= FLOW_TOSERVER_IPONLY_SET) : - (f->flags |= FLOW_TOCLIENT_IPONLY_SET); - FLOWLOCK_UNLOCK(f); - return; -} - -/** \brief Set the IPOnly scanned flag for 'direction'. - * - * \param f Flow to set the flag in - * \param direction direction to set the flag in - */ -void FlowSetIPOnlyFlagNoLock(Flow *f, char direction) -{ - direction ? (f->flags |= FLOW_TOSERVER_IPONLY_SET) : - (f->flags |= FLOW_TOCLIENT_IPONLY_SET); - return; -} - -/** - * \brief determine the direction of the packet compared to the flow - * \retval 0 to_server - * \retval 1 to_client - */ -int FlowGetPacketDirection(const Flow *f, const Packet *p) -{ - if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) { - if (!(CMP_PORT(p->sp,p->dp))) { - /* update flags and counters */ - if (CMP_PORT(f->sp,p->sp)) { - return TOSERVER; - } else { - return TOCLIENT; - } - } else { - if (CMP_ADDR(&f->src,&p->src)) { - return TOSERVER; - } else { - return TOCLIENT; - } - } - } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) { - if (CMP_ADDR(&f->src,&p->src)) { - return TOSERVER; - } else { - return TOCLIENT; - } - } - - /* default to toserver */ - return TOSERVER; -} - -/** - * \brief Check to update "seen" flags - * - * \param p packet - * - * \retval 1 true - * \retval 0 false - */ -static inline int FlowUpdateSeenFlag(const Packet *p) -{ - if (PKT_IS_ICMPV4(p)) { - if (ICMPV4_IS_ERROR_MSG(p)) { - return 0; - } - } - - return 1; -} - -/** - * - * Remove packet from flow. This assumes this happens *before* the packet - * is added to the stream engine and other higher state. - * - * \todo we can't restore the lastts - */ -void FlowHandlePacketUpdateRemove(Flow *f, Packet *p) -{ - if (p->flowflags & FLOW_PKT_TOSERVER) { - f->todstpktcnt--; - f->todstbytecnt -= GET_PKT_LEN(p); - p->flowflags &= ~(FLOW_PKT_TOSERVER|FLOW_PKT_TOSERVER_FIRST); - } else { - f->tosrcpktcnt--; - f->tosrcbytecnt -= GET_PKT_LEN(p); - p->flowflags &= ~(FLOW_PKT_TOCLIENT|FLOW_PKT_TOCLIENT_FIRST); - } - p->flowflags &= ~FLOW_PKT_ESTABLISHED; - - /*set the detection bypass flags*/ - if (f->flags & FLOW_NOPACKET_INSPECTION) { - SCLogDebug("unsetting FLOW_NOPACKET_INSPECTION flag on flow %p", f); - DecodeUnsetNoPacketInspectionFlag(p); - } - if (f->flags & FLOW_NOPAYLOAD_INSPECTION) { - SCLogDebug("unsetting FLOW_NOPAYLOAD_INSPECTION flag on flow %p", f); - DecodeUnsetNoPayloadInspectionFlag(p); - } -} - -/** \brief Update Packet and Flow - * - * Updates packet and flow based on the new packet. - * - * \param f locked flow - * \param p packet - * - * \note overwrites p::flowflags - */ -void FlowHandlePacketUpdate(Flow *f, Packet *p) -{ - SCLogDebug("packet %"PRIu64" -- flow %p", p->pcap_cnt, f); - - /* Point the Packet at the Flow */ - FlowReference(&p->flow, f); - - /* update flags and counters */ - if (FlowGetPacketDirection(f, p) == TOSERVER) { - f->todstpktcnt++; - f->todstbytecnt += GET_PKT_LEN(p); - p->flowflags = FLOW_PKT_TOSERVER; - if (!(f->flags & FLOW_TO_DST_SEEN)) { - if (FlowUpdateSeenFlag(p)) { - f->flags |= FLOW_TO_DST_SEEN; - p->flowflags |= FLOW_PKT_TOSERVER_FIRST; - } - } - } else { - f->tosrcpktcnt++; - f->tosrcbytecnt += GET_PKT_LEN(p); - p->flowflags = FLOW_PKT_TOCLIENT; - if (!(f->flags & FLOW_TO_SRC_SEEN)) { - if (FlowUpdateSeenFlag(p)) { - f->flags |= FLOW_TO_SRC_SEEN; - p->flowflags |= FLOW_PKT_TOCLIENT_FIRST; - } - } - } - - if ((f->flags & (FLOW_TO_DST_SEEN|FLOW_TO_SRC_SEEN)) == (FLOW_TO_DST_SEEN|FLOW_TO_SRC_SEEN)) { - SCLogDebug("pkt %p FLOW_PKT_ESTABLISHED", p); - p->flowflags |= FLOW_PKT_ESTABLISHED; - - if (f->proto != IPPROTO_TCP) { - SC_ATOMIC_SET(f->flow_state, FLOW_STATE_ESTABLISHED); - } - } - - /*set the detection bypass flags*/ - if (f->flags & FLOW_NOPACKET_INSPECTION) { - SCLogDebug("setting FLOW_NOPACKET_INSPECTION flag on flow %p", f); - DecodeSetNoPacketInspectionFlag(p); - } - if (f->flags & FLOW_NOPAYLOAD_INSPECTION) { - SCLogDebug("setting FLOW_NOPAYLOAD_INSPECTION flag on flow %p", f); - DecodeSetNoPayloadInspectionFlag(p); - } -} - -/** \brief Entry point for packet flow handling - * - * This is called for every packet. - * - * \param tv threadvars - * \param dtv decode thread vars (for flow output api thread data) - * \param p packet to handle flow for - */ -void FlowHandlePacket(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p) -{ - /* Get this packet's flow from the hash. FlowHandlePacket() will setup - * a new flow if nescesary. If we get NULL, we're out of flow memory. - * The returned flow is locked. */ - Flow *f = FlowGetFlowFromHash(tv, dtv, p); - if (f == NULL) - return; - - FlowHandlePacketUpdate(f, p); - - FLOWLOCK_UNLOCK(f); - - /* set the flow in the packet */ - p->flags |= PKT_HAS_FLOW; - return; -} - -/** \brief initialize the configuration - * \warning Not thread safe */ -void FlowInitConfig(char quiet) -{ - SCLogDebug("initializing flow engine..."); - - memset(&flow_config, 0, sizeof(flow_config)); - SC_ATOMIC_INIT(flow_flags); - SC_ATOMIC_INIT(flow_memuse); - SC_ATOMIC_INIT(flow_prune_idx); - FlowQueueInit(&flow_spare_q); - FlowQueueInit(&flow_recycle_q); - - unsigned int seed = RandomTimePreseed(); - /* set defaults */ - flow_config.hash_rand = (int)( FLOW_DEFAULT_HASHSIZE * (rand_r(&seed) / RAND_MAX + 1.0)); - - flow_config.hash_size = FLOW_DEFAULT_HASHSIZE; - flow_config.memcap = FLOW_DEFAULT_MEMCAP; - flow_config.prealloc = FLOW_DEFAULT_PREALLOC; - - /* If we have specific config, overwrite the defaults with them, - * otherwise, leave the default values */ - intmax_t val = 0; - if (ConfGetInt("flow.emergency-recovery", &val) == 1) { - if (val <= 100 && val >= 1) { - flow_config.emergency_recovery = (uint8_t)val; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "flow.emergency-recovery must be in the range of 1 and 100 (as percentage)"); - flow_config.emergency_recovery = FLOW_DEFAULT_EMERGENCY_RECOVERY; - } - } else { - SCLogDebug("flow.emergency-recovery, using default value"); - flow_config.emergency_recovery = FLOW_DEFAULT_EMERGENCY_RECOVERY; - } - - /* Check if we have memcap and hash_size defined at config */ - char *conf_val; - uint32_t configval = 0; - - /** set config values for memcap, prealloc and hash_size */ - if ((ConfGet("flow.memcap", &conf_val)) == 1) - { - if (ParseSizeStringU64(conf_val, &flow_config.memcap) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing flow.memcap " - "from conf file - %s. Killing engine", - conf_val); - exit(EXIT_FAILURE); - } - } - if ((ConfGet("flow.hash-size", &conf_val)) == 1) - { - if (ByteExtractStringUint32(&configval, 10, strlen(conf_val), - conf_val) > 0) { - flow_config.hash_size = configval; - } - } - if ((ConfGet("flow.prealloc", &conf_val)) == 1) - { - if (ByteExtractStringUint32(&configval, 10, strlen(conf_val), - conf_val) > 0) { - flow_config.prealloc = configval; - } - } - SCLogDebug("Flow config from suricata.yaml: memcap: %"PRIu64", hash-size: " - "%"PRIu32", prealloc: %"PRIu32, flow_config.memcap, - flow_config.hash_size, flow_config.prealloc); - - /* alloc hash memory */ - uint64_t hash_size = flow_config.hash_size * sizeof(FlowBucket); - if (!(FLOW_CHECK_MEMCAP(hash_size))) { - SCLogError(SC_ERR_FLOW_INIT, "allocating flow hash failed: " - "max flow memcap is smaller than projected hash size. " - "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate " - "total hash size by multiplying \"flow.hash-size\" with %"PRIuMAX", " - "which is the hash bucket size.", flow_config.memcap, hash_size, - (uintmax_t)sizeof(FlowBucket)); - exit(EXIT_FAILURE); - } - flow_hash = SCCalloc(flow_config.hash_size, sizeof(FlowBucket)); - if (unlikely(flow_hash == NULL)) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in FlowInitConfig. Exiting..."); - exit(EXIT_FAILURE); - } - memset(flow_hash, 0, flow_config.hash_size * sizeof(FlowBucket)); - - uint32_t i = 0; - for (i = 0; i < flow_config.hash_size; i++) { - FBLOCK_INIT(&flow_hash[i]); - } - (void) SC_ATOMIC_ADD(flow_memuse, (flow_config.hash_size * sizeof(FlowBucket))); - - if (quiet == FALSE) { - SCLogInfo("allocated %llu bytes of memory for the flow hash... " - "%" PRIu32 " buckets of size %" PRIuMAX "", - SC_ATOMIC_GET(flow_memuse), flow_config.hash_size, - (uintmax_t)sizeof(FlowBucket)); - } - - /* pre allocate flows */ - for (i = 0; i < flow_config.prealloc; i++) { - if (!(FLOW_CHECK_MEMCAP(sizeof(Flow) + FlowStorageSize()))) { - SCLogError(SC_ERR_FLOW_INIT, "preallocating flows failed: " - "max flow memcap reached. Memcap %"PRIu64", " - "Memuse %"PRIu64".", flow_config.memcap, - ((uint64_t)SC_ATOMIC_GET(flow_memuse) + (uint64_t)sizeof(Flow))); - exit(EXIT_FAILURE); - } - - Flow *f = FlowAlloc(); - if (f == NULL) { - SCLogError(SC_ERR_FLOW_INIT, "preallocating flow failed: %s", strerror(errno)); - exit(EXIT_FAILURE); - } - - FlowEnqueue(&flow_spare_q,f); - } - - if (quiet == FALSE) { - SCLogInfo("preallocated %" PRIu32 " flows of size %" PRIuMAX "", - flow_spare_q.len, (uintmax_t)(sizeof(Flow) + + FlowStorageSize())); - SCLogInfo("flow memory usage: %llu bytes, maximum: %"PRIu64, - SC_ATOMIC_GET(flow_memuse), flow_config.memcap); - } - - FlowInitFlowProto(); - - return; -} - -/** \brief print some flow stats - * \warning Not thread safe */ -static void FlowPrintStats (void) -{ -#ifdef FLOWBITS_STATS - SCLogInfo("flowbits added: %" PRIu32 ", removed: %" PRIu32 ", max memory usage: %" PRIu32 "", - flowbits_added, flowbits_removed, flowbits_memuse_max); -#endif /* FLOWBITS_STATS */ - return; -} - -/** \brief shutdown the flow engine - * \warning Not thread safe */ -void FlowShutdown(void) -{ - Flow *f; - uint32_t u; - - FlowPrintStats(); - - /* free queues */ - while((f = FlowDequeue(&flow_spare_q))) { - FlowFree(f); - } - while((f = FlowDequeue(&flow_recycle_q))) { - FlowFree(f); - } - - /* clear and free the hash */ - if (flow_hash != NULL) { - /* clean up flow mutexes */ - for (u = 0; u < flow_config.hash_size; u++) { - Flow *f = flow_hash[u].head; - while (f) { -#ifdef DEBUG_VALIDATION - BUG_ON(SC_ATOMIC_GET(f->use_cnt) != 0); -#endif - Flow *n = f->hnext; - uint8_t proto_map = FlowGetProtoMapping(f->proto); - FlowClearMemory(f, proto_map); - FlowFree(f); - f = n; - } - - FBLOCK_DESTROY(&flow_hash[u]); - } - SCFree(flow_hash); - flow_hash = NULL; - } - (void) SC_ATOMIC_SUB(flow_memuse, flow_config.hash_size * sizeof(FlowBucket)); - FlowQueueDestroy(&flow_spare_q); - FlowQueueDestroy(&flow_recycle_q); - - SC_ATOMIC_DESTROY(flow_prune_idx); - SC_ATOMIC_DESTROY(flow_memuse); - SC_ATOMIC_DESTROY(flow_flags); - return; -} - -/** - * \brief Function to set the default timeout, free function and flow state - * function for all supported flow_proto. - */ - -void FlowInitFlowProto(void) -{ - /*Default*/ - flow_proto[FLOW_PROTO_DEFAULT].new_timeout = FLOW_DEFAULT_NEW_TIMEOUT; - flow_proto[FLOW_PROTO_DEFAULT].est_timeout = FLOW_DEFAULT_EST_TIMEOUT; - flow_proto[FLOW_PROTO_DEFAULT].closed_timeout = - FLOW_DEFAULT_CLOSED_TIMEOUT; - flow_proto[FLOW_PROTO_DEFAULT].emerg_new_timeout = - FLOW_DEFAULT_EMERG_NEW_TIMEOUT; - flow_proto[FLOW_PROTO_DEFAULT].emerg_est_timeout = - FLOW_DEFAULT_EMERG_EST_TIMEOUT; - flow_proto[FLOW_PROTO_DEFAULT].emerg_closed_timeout = - FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT; - flow_proto[FLOW_PROTO_DEFAULT].Freefunc = NULL; - /*TCP*/ - flow_proto[FLOW_PROTO_TCP].new_timeout = FLOW_IPPROTO_TCP_NEW_TIMEOUT; - flow_proto[FLOW_PROTO_TCP].est_timeout = FLOW_IPPROTO_TCP_EST_TIMEOUT; - flow_proto[FLOW_PROTO_TCP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT; - flow_proto[FLOW_PROTO_TCP].emerg_new_timeout = - FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT; - flow_proto[FLOW_PROTO_TCP].emerg_est_timeout = - FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT; - flow_proto[FLOW_PROTO_TCP].emerg_closed_timeout = - FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT; - flow_proto[FLOW_PROTO_TCP].Freefunc = NULL; - /*UDP*/ - flow_proto[FLOW_PROTO_UDP].new_timeout = FLOW_IPPROTO_UDP_NEW_TIMEOUT; - flow_proto[FLOW_PROTO_UDP].est_timeout = FLOW_IPPROTO_UDP_EST_TIMEOUT; - flow_proto[FLOW_PROTO_UDP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT; - flow_proto[FLOW_PROTO_UDP].emerg_new_timeout = - FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT; - flow_proto[FLOW_PROTO_UDP].emerg_est_timeout = - FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT; - flow_proto[FLOW_PROTO_UDP].emerg_closed_timeout = - FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT; - flow_proto[FLOW_PROTO_UDP].Freefunc = NULL; - /*ICMP*/ - flow_proto[FLOW_PROTO_ICMP].new_timeout = FLOW_IPPROTO_ICMP_NEW_TIMEOUT; - flow_proto[FLOW_PROTO_ICMP].est_timeout = FLOW_IPPROTO_ICMP_EST_TIMEOUT; - flow_proto[FLOW_PROTO_ICMP].closed_timeout = FLOW_DEFAULT_CLOSED_TIMEOUT; - flow_proto[FLOW_PROTO_ICMP].emerg_new_timeout = - FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT; - flow_proto[FLOW_PROTO_ICMP].emerg_est_timeout = - FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT; - flow_proto[FLOW_PROTO_ICMP].emerg_closed_timeout = - FLOW_DEFAULT_EMERG_CLOSED_TIMEOUT; - flow_proto[FLOW_PROTO_ICMP].Freefunc = NULL; - - /* Let's see if we have custom timeouts defined from config */ - const char *new = NULL; - const char *established = NULL; - const char *closed = NULL; - const char *emergency_new = NULL; - const char *emergency_established = NULL; - const char *emergency_closed = NULL; - - ConfNode *flow_timeouts = ConfGetNode("flow-timeouts"); - if (flow_timeouts != NULL) { - ConfNode *proto = NULL; - uint32_t configval = 0; - - /* Defaults. */ - proto = ConfNodeLookupChild(flow_timeouts, "default"); - if (proto != NULL) { - new = ConfNodeLookupChildValue(proto, "new"); - established = ConfNodeLookupChildValue(proto, "established"); - closed = ConfNodeLookupChildValue(proto, "closed"); - emergency_new = ConfNodeLookupChildValue(proto, "emergency-new"); - emergency_established = ConfNodeLookupChildValue(proto, - "emergency-established"); - emergency_closed = ConfNodeLookupChildValue(proto, - "emergency-closed"); - - if (new != NULL && - ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) { - - flow_proto[FLOW_PROTO_DEFAULT].new_timeout = configval; - } - if (established != NULL && - ByteExtractStringUint32(&configval, 10, strlen(established), - established) > 0) { - - flow_proto[FLOW_PROTO_DEFAULT].est_timeout = configval; - } - if (closed != NULL && - ByteExtractStringUint32(&configval, 10, strlen(closed), - closed) > 0) { - - flow_proto[FLOW_PROTO_DEFAULT].closed_timeout = configval; - } - if (emergency_new != NULL && - ByteExtractStringUint32(&configval, 10, strlen(emergency_new), - emergency_new) > 0) { - - flow_proto[FLOW_PROTO_DEFAULT].emerg_new_timeout = configval; - } - if (emergency_established != NULL && - ByteExtractStringUint32(&configval, 10, - strlen(emergency_established), - emergency_established) > 0) { - - flow_proto[FLOW_PROTO_DEFAULT].emerg_est_timeout= configval; - } - if (emergency_closed != NULL && - ByteExtractStringUint32(&configval, 10, - strlen(emergency_closed), - emergency_closed) > 0) { - - flow_proto[FLOW_PROTO_DEFAULT].emerg_closed_timeout = configval; - } - } - - /* TCP. */ - proto = ConfNodeLookupChild(flow_timeouts, "tcp"); - if (proto != NULL) { - new = ConfNodeLookupChildValue(proto, "new"); - established = ConfNodeLookupChildValue(proto, "established"); - closed = ConfNodeLookupChildValue(proto, "closed"); - emergency_new = ConfNodeLookupChildValue(proto, "emergency-new"); - emergency_established = ConfNodeLookupChildValue(proto, - "emergency-established"); - emergency_closed = ConfNodeLookupChildValue(proto, - "emergency-closed"); - - if (new != NULL && - ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) { - - flow_proto[FLOW_PROTO_TCP].new_timeout = configval; - } - if (established != NULL && - ByteExtractStringUint32(&configval, 10, strlen(established), - established) > 0) { - - flow_proto[FLOW_PROTO_TCP].est_timeout = configval; - } - if (closed != NULL && - ByteExtractStringUint32(&configval, 10, strlen(closed), - closed) > 0) { - - flow_proto[FLOW_PROTO_TCP].closed_timeout = configval; - } - if (emergency_new != NULL && - ByteExtractStringUint32(&configval, 10, strlen(emergency_new), - emergency_new) > 0) { - - flow_proto[FLOW_PROTO_TCP].emerg_new_timeout = configval; - } - if (emergency_established != NULL && - ByteExtractStringUint32(&configval, 10, - strlen(emergency_established), - emergency_established) > 0) { - - flow_proto[FLOW_PROTO_TCP].emerg_est_timeout = configval; - } - if (emergency_closed != NULL && - ByteExtractStringUint32(&configval, 10, - strlen(emergency_closed), - emergency_closed) > 0) { - - flow_proto[FLOW_PROTO_TCP].emerg_closed_timeout = configval; - } - } - - /* UDP. */ - proto = ConfNodeLookupChild(flow_timeouts, "udp"); - if (proto != NULL) { - new = ConfNodeLookupChildValue(proto, "new"); - established = ConfNodeLookupChildValue(proto, "established"); - emergency_new = ConfNodeLookupChildValue(proto, "emergency-new"); - emergency_established = ConfNodeLookupChildValue(proto, - "emergency-established"); - if (new != NULL && - ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) { - - flow_proto[FLOW_PROTO_UDP].new_timeout = configval; - } - if (established != NULL && - ByteExtractStringUint32(&configval, 10, strlen(established), - established) > 0) { - - flow_proto[FLOW_PROTO_UDP].est_timeout = configval; - } - if (emergency_new != NULL && - ByteExtractStringUint32(&configval, 10, strlen(emergency_new), - emergency_new) > 0) { - - flow_proto[FLOW_PROTO_UDP].emerg_new_timeout = configval; - } - if (emergency_established != NULL && - ByteExtractStringUint32(&configval, 10, - strlen(emergency_established), - emergency_established) > 0) { - - flow_proto[FLOW_PROTO_UDP].emerg_est_timeout = configval; - } - } - - /* ICMP. */ - proto = ConfNodeLookupChild(flow_timeouts, "icmp"); - if (proto != NULL) { - new = ConfNodeLookupChildValue(proto, "new"); - established = ConfNodeLookupChildValue(proto, "established"); - emergency_new = ConfNodeLookupChildValue(proto, "emergency-new"); - emergency_established = ConfNodeLookupChildValue(proto, - "emergency-established"); - - if (new != NULL && - ByteExtractStringUint32(&configval, 10, strlen(new), new) > 0) { - - flow_proto[FLOW_PROTO_ICMP].new_timeout = configval; - } - if (established != NULL && - ByteExtractStringUint32(&configval, 10, strlen(established), - established) > 0) { - - flow_proto[FLOW_PROTO_ICMP].est_timeout = configval; - } - if (emergency_new != NULL && - ByteExtractStringUint32(&configval, 10, strlen(emergency_new), - emergency_new) > 0) { - - flow_proto[FLOW_PROTO_ICMP].emerg_new_timeout = configval; - } - if (emergency_established != NULL && - ByteExtractStringUint32(&configval, 10, - strlen(emergency_established), - emergency_established) > 0) { - - flow_proto[FLOW_PROTO_ICMP].emerg_est_timeout = configval; - } - } - } - - return; -} - -/** - * \brief Function clear the flow memory before queueing it to spare flow - * queue. - * - * \param f pointer to the flow needed to be cleared. - * \param proto_map mapped value of the protocol to FLOW_PROTO's. - */ - -int FlowClearMemory(Flow* f, uint8_t proto_map) -{ - SCEnter(); - - /* call the protocol specific free function if we have one */ - if (flow_proto[proto_map].Freefunc != NULL) { - flow_proto[proto_map].Freefunc(f->protoctx); - } - - FlowFreeStorage(f); - - FLOW_RECYCLE(f); - - SCReturnInt(1); -} - -/** - * \brief Function to set the function to get protocol specific flow state. - * - * \param proto protocol of which function is needed to be set. - * \param Free Function pointer which will be called to free the protocol - * specific memory. - */ - -int FlowSetProtoFreeFunc (uint8_t proto, void (*Free)(void *)) -{ - uint8_t proto_map; - proto_map = FlowGetProtoMapping(proto); - - flow_proto[proto_map].Freefunc = Free; - return 1; -} - -/** - * \brief Function to set the timeout values for the specified protocol. - * - * \param proto protocol of which timeout value is needed to be set. - * \param new_timeout timeout value for the new flows. - * \param est_timeout timeout value for the established flows. - * \param closed_timeout timeout value for the closed flows. - */ - -int FlowSetProtoTimeout(uint8_t proto, uint32_t new_timeout, - uint32_t est_timeout, uint32_t closed_timeout) -{ - uint8_t proto_map; - proto_map = FlowGetProtoMapping(proto); - - flow_proto[proto_map].new_timeout = new_timeout; - flow_proto[proto_map].est_timeout = est_timeout; - flow_proto[proto_map].closed_timeout = closed_timeout; - - return 1; -} - -/** - * \brief Function to set the emergency timeout values for the specified - * protocol. - * - * \param proto protocol of which timeout value is needed to be set. - * \param emerg_new_timeout timeout value for the new flows. - * \param emerg_est_timeout timeout value for the established flows. - * \param emerg_closed_timeout timeout value for the closed flows. - */ - -int FlowSetProtoEmergencyTimeout(uint8_t proto, uint32_t emerg_new_timeout, - uint32_t emerg_est_timeout, - uint32_t emerg_closed_timeout) -{ - - uint8_t proto_map; - proto_map = FlowGetProtoMapping(proto); - - flow_proto[proto_map].emerg_new_timeout = emerg_new_timeout; - flow_proto[proto_map].emerg_est_timeout = emerg_est_timeout; - flow_proto[proto_map].emerg_closed_timeout = emerg_closed_timeout; - - return 1; -} - -AppProto FlowGetAppProtocol(const Flow *f) -{ - return f->alproto; -} - -void *FlowGetAppState(const Flow *f) -{ - return f->alstate; -} - -/** - * \brief get 'disruption' flags: GAP/DEPTH/PASS - * \param f locked flow - * \param flags existing flags to be ammended - * \retval flags original flags + disrupt flags (if any) - * \TODO handle UDP - */ -uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags) -{ - if (f->proto != IPPROTO_TCP) { - return flags; - } - if (f->protoctx == NULL) { - return flags; - } - - uint8_t newflags = flags; - TcpSession *ssn = f->protoctx; - TcpStream *stream = flags & STREAM_TOSERVER ? &ssn->client : &ssn->server; - - if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) { - newflags |= STREAM_DEPTH; - } - if (stream->flags & STREAMTCP_STREAM_FLAG_GAP) { - newflags |= STREAM_GAP; - } - /* todo: handle pass case (also for UDP!) */ - - return newflags; -} - -/************************************Unittests*******************************/ - -#ifdef UNITTESTS -#include "stream-tcp-private.h" -#include "threads.h" - -/** - * \test Test the setting of the per protocol timeouts. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowTest01 (void) -{ - uint8_t proto_map; - - FlowInitFlowProto(); - proto_map = FlowGetProtoMapping(IPPROTO_TCP); - - if ((flow_proto[proto_map].new_timeout != FLOW_IPPROTO_TCP_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_IPPROTO_TCP_EST_TIMEOUT) - && (flow_proto[proto_map].emerg_new_timeout != FLOW_IPPROTO_TCP_EMERG_NEW_TIMEOUT) && (flow_proto[proto_map].emerg_est_timeout != FLOW_IPPROTO_TCP_EMERG_EST_TIMEOUT)){ - printf ("failed in setting TCP flow timeout"); - return 0; - } - - proto_map = FlowGetProtoMapping(IPPROTO_UDP); - if ((flow_proto[proto_map].new_timeout != FLOW_IPPROTO_UDP_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_IPPROTO_UDP_EST_TIMEOUT) - && (flow_proto[proto_map].emerg_new_timeout != FLOW_IPPROTO_UDP_EMERG_NEW_TIMEOUT) && (flow_proto[proto_map].emerg_est_timeout != FLOW_IPPROTO_UDP_EMERG_EST_TIMEOUT)){ - printf ("failed in setting UDP flow timeout"); - return 0; - } - - proto_map = FlowGetProtoMapping(IPPROTO_ICMP); - if ((flow_proto[proto_map].new_timeout != FLOW_IPPROTO_ICMP_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_IPPROTO_ICMP_EST_TIMEOUT) - && (flow_proto[proto_map].emerg_new_timeout != FLOW_IPPROTO_ICMP_EMERG_NEW_TIMEOUT) && (flow_proto[proto_map].emerg_est_timeout != FLOW_IPPROTO_ICMP_EMERG_EST_TIMEOUT)){ - printf ("failed in setting ICMP flow timeout"); - return 0; - } - - proto_map = FlowGetProtoMapping(IPPROTO_DCCP); - if ((flow_proto[proto_map].new_timeout != FLOW_DEFAULT_NEW_TIMEOUT) && (flow_proto[proto_map].est_timeout != FLOW_DEFAULT_EST_TIMEOUT) - && (flow_proto[proto_map].emerg_new_timeout != FLOW_DEFAULT_EMERG_NEW_TIMEOUT) && (flow_proto[proto_map].emerg_est_timeout != FLOW_DEFAULT_EMERG_EST_TIMEOUT)){ - printf ("failed in setting default flow timeout"); - return 0; - } - - return 1; -} - -/*Test function for the unit test FlowTest02*/ - -void test(void *f) {} - -/** - * \test Test the setting of the per protocol free function to free the - * protocol specific memory. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowTest02 (void) -{ - FlowSetProtoFreeFunc(IPPROTO_DCCP, test); - FlowSetProtoFreeFunc(IPPROTO_TCP, test); - FlowSetProtoFreeFunc(IPPROTO_UDP, test); - FlowSetProtoFreeFunc(IPPROTO_ICMP, test); - - if (flow_proto[FLOW_PROTO_DEFAULT].Freefunc != test) { - printf("Failed in setting default free function\n"); - return 0; - } - if (flow_proto[FLOW_PROTO_TCP].Freefunc != test) { - printf("Failed in setting TCP free function\n"); - return 0; - } - if (flow_proto[FLOW_PROTO_UDP].Freefunc != test) { - printf("Failed in setting UDP free function\n"); - return 0; - } - if (flow_proto[FLOW_PROTO_ICMP].Freefunc != test) { - printf("Failed in setting ICMP free function\n"); - return 0; - } - return 1; -} - -/** - * \test Test flow allocations when it reach memcap - * - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowTest07 (void) -{ - int result = 0; - - FlowInitConfig(FLOW_QUIET); - FlowConfig backup; - memcpy(&backup, &flow_config, sizeof(FlowConfig)); - - uint32_t ini = 0; - uint32_t end = flow_spare_q.len; - flow_config.memcap = 10000; - flow_config.prealloc = 100; - - /* Let's get the flow_spare_q empty */ - UTHBuildPacketOfFlows(ini, end, 0); - - /* And now let's try to reach the memcap val */ - while (FLOW_CHECK_MEMCAP(sizeof(Flow))) { - ini = end + 1; - end = end + 2; - UTHBuildPacketOfFlows(ini, end, 0); - } - - /* should time out normal */ - TimeSetIncrementTime(2000); - ini = end + 1; - end = end + 2;; - UTHBuildPacketOfFlows(ini, end, 0); - - /* This means that the engine entered emerg mode: should happen as easy - * with flow mgr activated */ - if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) - result = 1; - - memcpy(&flow_config, &backup, sizeof(FlowConfig)); - FlowShutdown(); - - return result; -} - -/** - * \test Test flow allocations when it reach memcap - * - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowTest08 (void) -{ - int result = 0; - - FlowInitConfig(FLOW_QUIET); - FlowConfig backup; - memcpy(&backup, &flow_config, sizeof(FlowConfig)); - - uint32_t ini = 0; - uint32_t end = flow_spare_q.len; - flow_config.memcap = 10000; - flow_config.prealloc = 100; - - /* Let's get the flow_spare_q empty */ - UTHBuildPacketOfFlows(ini, end, 0); - - /* And now let's try to reach the memcap val */ - while (FLOW_CHECK_MEMCAP(sizeof(Flow))) { - ini = end + 1; - end = end + 2; - UTHBuildPacketOfFlows(ini, end, 0); - } - - /* By default we use 30 for timing out new flows. This means - * that the Emergency mode should be set */ - TimeSetIncrementTime(20); - ini = end + 1; - end = end + 2; - UTHBuildPacketOfFlows(ini, end, 0); - - /* This means that the engine released 5 flows by emergency timeout */ - if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) - result = 1; - - memcpy(&flow_config, &backup, sizeof(FlowConfig)); - FlowShutdown(); - - return result; -} - -/** - * \test Test flow allocations when it reach memcap - * - * - * \retval On success it returns 1 and on failure 0. - */ - -static int FlowTest09 (void) -{ - int result = 0; - - FlowInitConfig(FLOW_QUIET); - FlowConfig backup; - memcpy(&backup, &flow_config, sizeof(FlowConfig)); - - uint32_t ini = 0; - uint32_t end = flow_spare_q.len; - flow_config.memcap = 10000; - flow_config.prealloc = 100; - - /* Let's get the flow_spare_q empty */ - UTHBuildPacketOfFlows(ini, end, 0); - - /* And now let's try to reach the memcap val */ - while (FLOW_CHECK_MEMCAP(sizeof(Flow))) { - ini = end + 1; - end = end + 2; - UTHBuildPacketOfFlows(ini, end, 0); - } - - /* No timeout will work */ - TimeSetIncrementTime(5); - ini = end + 1; - end = end + 2; - UTHBuildPacketOfFlows(ini, end, 0); - - /* engine in emerg mode */ - if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) - result = 1; - - memcpy(&flow_config, &backup, sizeof(FlowConfig)); - FlowShutdown(); - - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief Function to register the Flow Unitests. - */ -void FlowRegisterTests (void) -{ -#ifdef UNITTESTS - UtRegisterTest("FlowTest01 -- Protocol Specific Timeouts", FlowTest01, 1); - UtRegisterTest("FlowTest02 -- Setting Protocol Specific Free Function", FlowTest02, 1); - UtRegisterTest("FlowTest07 -- Test flow Allocations when it reach memcap", FlowTest07, 1); - UtRegisterTest("FlowTest08 -- Test flow Allocations when it reach memcap", FlowTest08, 1); - UtRegisterTest("FlowTest09 -- Test flow Allocations when it reach memcap", FlowTest09, 1); - - FlowMgrRegisterTests(); - RegisterFlowStorageTests(); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/flow.h b/framework/src/suricata/src/flow.h deleted file mode 100644 index eab73776..00000000 --- a/framework/src/suricata/src/flow.h +++ /dev/null @@ -1,584 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __FLOW_H__ -#define __FLOW_H__ - -#include "decode.h" -#include "util-var.h" -#include "util-atomic.h" -#include "detect-tag.h" -#include "util-optimize.h" - -/* Part of the flow structure, so we declare it here. - * The actual declaration is in app-layer-parser.c */ -typedef struct AppLayerParserState_ AppLayerParserState; - -#define FLOW_QUIET TRUE -#define FLOW_VERBOSE FALSE - -#define TOSERVER 0 -#define TOCLIENT 1 - -/* per flow flags */ - -/** At least on packet from the source address was seen */ -#define FLOW_TO_SRC_SEEN 0x00000001 -/** At least on packet from the destination address was seen */ -#define FLOW_TO_DST_SEEN 0x00000002 -/** Don't return this from the flow hash. It has been replaced. */ -#define FLOW_TCP_REUSED 0x00000004 -/** no magic on files in this flow */ -#define FLOW_FILE_NO_MAGIC_TS 0x00000008 -#define FLOW_FILE_NO_MAGIC_TC 0x00000010 - -/** Flow was inspected against IP-Only sigs in the toserver direction */ -#define FLOW_TOSERVER_IPONLY_SET 0x00000020 -/** Flow was inspected against IP-Only sigs in the toclient direction */ -#define FLOW_TOCLIENT_IPONLY_SET 0x00000040 - -/** Packet belonging to this flow should not be inspected at all */ -#define FLOW_NOPACKET_INSPECTION 0x00000080 -/** Packet payloads belonging to this flow should not be inspected */ -#define FLOW_NOPAYLOAD_INSPECTION 0x00000100 - -/** All packets in this flow should be dropped */ -#define FLOW_ACTION_DROP 0x00000200 - -/** Sgh for toserver direction set (even if it's NULL) */ -#define FLOW_SGH_TOSERVER 0x00000800 -/** Sgh for toclient direction set (even if it's NULL) */ -#define FLOW_SGH_TOCLIENT 0x00001000 - -/** packet to server direction has been logged in drop file (only in IPS mode) */ -#define FLOW_TOSERVER_DROP_LOGGED 0x00002000 -/** packet to client direction has been logged in drop file (only in IPS mode) */ -#define FLOW_TOCLIENT_DROP_LOGGED 0x00004000 -/** alproto detect done. Right now we need it only for udp */ -#define FLOW_ALPROTO_DETECT_DONE 0x00008000 - -// vacany 1x - -/** Pattern matcher alproto detection done */ -#define FLOW_TS_PM_ALPROTO_DETECT_DONE 0x00020000 -/** Probing parser alproto detection done */ -#define FLOW_TS_PP_ALPROTO_DETECT_DONE 0x00040000 -/** Pattern matcher alproto detection done */ -#define FLOW_TC_PM_ALPROTO_DETECT_DONE 0x00100000 -/** Probing parser alproto detection done */ -#define FLOW_TC_PP_ALPROTO_DETECT_DONE 0x00200000 -#define FLOW_TIMEOUT_REASSEMBLY_DONE 0x00800000 -/** even if the flow has files, don't store 'm */ -#define FLOW_FILE_NO_STORE_TS 0x01000000 -#define FLOW_FILE_NO_STORE_TC 0x02000000 - -/** flow is ipv4 */ -#define FLOW_IPV4 0x04000000 -/** flow is ipv6 */ -#define FLOW_IPV6 0x08000000 - -/** no md5 on files in this flow */ -#define FLOW_FILE_NO_MD5_TS 0x10000000 -#define FLOW_FILE_NO_MD5_TC 0x20000000 - -/** no size tracking of files in this flow */ -#define FLOW_FILE_NO_SIZE_TS 0x40000000 -#define FLOW_FILE_NO_SIZE_TC 0x80000000 - -#define FLOW_IS_IPV4(f) \ - (((f)->flags & FLOW_IPV4) == FLOW_IPV4) -#define FLOW_IS_IPV6(f) \ - (((f)->flags & FLOW_IPV6) == FLOW_IPV6) - -#define FLOW_COPY_IPV4_ADDR_TO_PACKET(fa, pa) do { \ - (pa)->family = AF_INET; \ - (pa)->addr_data32[0] = (fa)->addr_data32[0]; \ - } while (0) - -#define FLOW_COPY_IPV6_ADDR_TO_PACKET(fa, pa) do { \ - (pa)->family = AF_INET6; \ - (pa)->addr_data32[0] = (fa)->addr_data32[0]; \ - (pa)->addr_data32[1] = (fa)->addr_data32[1]; \ - (pa)->addr_data32[2] = (fa)->addr_data32[2]; \ - (pa)->addr_data32[3] = (fa)->addr_data32[3]; \ - } while (0) - -/* Set the IPv4 addressesinto the Addrs of the Packet. - * Make sure p->ip4h is initialized and validated. - * - * We set the rest of the struct to 0 so we can - * prevent using memset. */ -#define FLOW_SET_IPV4_SRC_ADDR_FROM_PACKET(p, a) do { \ - (a)->addr_data32[0] = (uint32_t)(p)->ip4h->s_ip_src.s_addr; \ - (a)->addr_data32[1] = 0; \ - (a)->addr_data32[2] = 0; \ - (a)->addr_data32[3] = 0; \ - } while (0) - -#define FLOW_SET_IPV4_DST_ADDR_FROM_PACKET(p, a) do { \ - (a)->addr_data32[0] = (uint32_t)(p)->ip4h->s_ip_dst.s_addr; \ - (a)->addr_data32[1] = 0; \ - (a)->addr_data32[2] = 0; \ - (a)->addr_data32[3] = 0; \ - } while (0) - -/* clear the address structure by setting all fields to 0 */ -#define FLOW_CLEAR_ADDR(a) do { \ - (a)->addr_data32[0] = 0; \ - (a)->addr_data32[1] = 0; \ - (a)->addr_data32[2] = 0; \ - (a)->addr_data32[3] = 0; \ - } while (0) - -/* Set the IPv6 addressesinto the Addrs of the Packet. - * Make sure p->ip6h is initialized and validated. */ -#define FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(p, a) do { \ - (a)->addr_data32[0] = (p)->ip6h->s_ip6_src[0]; \ - (a)->addr_data32[1] = (p)->ip6h->s_ip6_src[1]; \ - (a)->addr_data32[2] = (p)->ip6h->s_ip6_src[2]; \ - (a)->addr_data32[3] = (p)->ip6h->s_ip6_src[3]; \ - } while (0) - -#define FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(p, a) do { \ - (a)->addr_data32[0] = (p)->ip6h->s_ip6_dst[0]; \ - (a)->addr_data32[1] = (p)->ip6h->s_ip6_dst[1]; \ - (a)->addr_data32[2] = (p)->ip6h->s_ip6_dst[2]; \ - (a)->addr_data32[3] = (p)->ip6h->s_ip6_dst[3]; \ - } while (0) - -/* pkt flow flags */ -#define FLOW_PKT_TOSERVER 0x01 -#define FLOW_PKT_TOCLIENT 0x02 -#define FLOW_PKT_ESTABLISHED 0x04 -#define FLOW_PKT_TOSERVER_IPONLY_SET 0x08 -#define FLOW_PKT_TOCLIENT_IPONLY_SET 0x10 -#define FLOW_PKT_TOSERVER_FIRST 0x20 -#define FLOW_PKT_TOCLIENT_FIRST 0x40 - -#define FLOW_END_FLAG_STATE_NEW 0x01 -#define FLOW_END_FLAG_STATE_ESTABLISHED 0x02 -#define FLOW_END_FLAG_STATE_CLOSED 0x04 -#define FLOW_END_FLAG_EMERGENCY 0x08 -#define FLOW_END_FLAG_TIMEOUT 0x10 -#define FLOW_END_FLAG_FORCED 0x20 -#define FLOW_END_FLAG_SHUTDOWN 0x40 - -/** Mutex or RWLocks for the flow. */ -//#define FLOWLOCK_RWLOCK -#define FLOWLOCK_MUTEX - -#ifdef FLOWLOCK_RWLOCK - #ifdef FLOWLOCK_MUTEX - #error Cannot enable both FLOWLOCK_RWLOCK and FLOWLOCK_MUTEX - #endif -#endif - -#ifdef FLOWLOCK_RWLOCK - #define FLOWLOCK_INIT(fb) SCRWLockInit(&(fb)->r, NULL) - #define FLOWLOCK_DESTROY(fb) SCRWLockDestroy(&(fb)->r) - #define FLOWLOCK_RDLOCK(fb) SCRWLockRDLock(&(fb)->r) - #define FLOWLOCK_WRLOCK(fb) SCRWLockWRLock(&(fb)->r) - #define FLOWLOCK_TRYRDLOCK(fb) SCRWLockTryRDLock(&(fb)->r) - #define FLOWLOCK_TRYWRLOCK(fb) SCRWLockTryWRLock(&(fb)->r) - #define FLOWLOCK_UNLOCK(fb) SCRWLockUnlock(&(fb)->r) -#elif defined FLOWLOCK_MUTEX - #define FLOWLOCK_INIT(fb) SCMutexInit(&(fb)->m, NULL) - #define FLOWLOCK_DESTROY(fb) SCMutexDestroy(&(fb)->m) - #define FLOWLOCK_RDLOCK(fb) SCMutexLock(&(fb)->m) - #define FLOWLOCK_WRLOCK(fb) SCMutexLock(&(fb)->m) - #define FLOWLOCK_TRYRDLOCK(fb) SCMutexTrylock(&(fb)->m) - #define FLOWLOCK_TRYWRLOCK(fb) SCMutexTrylock(&(fb)->m) - #define FLOWLOCK_UNLOCK(fb) SCMutexUnlock(&(fb)->m) -#else - #error Enable FLOWLOCK_RWLOCK or FLOWLOCK_MUTEX -#endif - -#define FLOW_IS_PM_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) : ((f)->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE)) -#define FLOW_IS_PP_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags & FLOW_TS_PP_ALPROTO_DETECT_DONE) : ((f)->flags & FLOW_TC_PP_ALPROTO_DETECT_DONE)) - -#define FLOW_SET_PM_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags |= FLOW_TS_PM_ALPROTO_DETECT_DONE) : ((f)->flags |= FLOW_TC_PM_ALPROTO_DETECT_DONE)) -#define FLOW_SET_PP_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags |= FLOW_TS_PP_ALPROTO_DETECT_DONE) : ((f)->flags |= FLOW_TC_PP_ALPROTO_DETECT_DONE)) - -#define FLOW_RESET_PM_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags &= ~FLOW_TS_PM_ALPROTO_DETECT_DONE) : ((f)->flags &= ~FLOW_TC_PM_ALPROTO_DETECT_DONE)) -#define FLOW_RESET_PP_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags &= ~FLOW_TS_PP_ALPROTO_DETECT_DONE) : ((f)->flags &= ~FLOW_TC_PP_ALPROTO_DETECT_DONE)) - -/* global flow config */ -typedef struct FlowCnf_ -{ - uint32_t hash_rand; - uint32_t hash_size; - uint64_t memcap; - uint32_t max_flows; - uint32_t prealloc; - - uint32_t timeout_new; - uint32_t timeout_est; - - uint32_t emerg_timeout_new; - uint32_t emerg_timeout_est; - uint32_t emergency_recovery; - -} FlowConfig; - -/* Hash key for the flow hash */ -typedef struct FlowKey_ -{ - Address src, dst; - Port sp, dp; - uint8_t proto; - uint8_t recursion_level; - -} FlowKey; - -typedef struct FlowAddress_ { - union { - uint32_t address_un_data32[4]; /* type-specific field */ - uint16_t address_un_data16[8]; /* type-specific field */ - uint8_t address_un_data8[16]; /* type-specific field */ - } address; -} FlowAddress; - -#define addr_data32 address.address_un_data32 -#define addr_data16 address.address_un_data16 -#define addr_data8 address.address_un_data8 - -#ifdef __tile__ -/* Atomic Ints performance better on Tile. */ -typedef unsigned int FlowRefCount; -#else -typedef unsigned short FlowRefCount; -#endif - -#ifdef __tile__ -/* Atomic Ints performance better on Tile. */ -typedef unsigned int FlowStateType; -#else -typedef unsigned short FlowStateType; -#endif - -/** Local Thread ID */ -typedef uint16_t FlowThreadId; - -/** - * \brief Flow data structure. - * - * The flow is a global data structure that is created for new packets of a - * flow and then looked up for the following packets of a flow. - * - * Locking - * - * The flow is updated/used by multiple packets at the same time. This is why - * there is a flow-mutex. It's a mutex and not a spinlock because some - * operations on the flow can be quite expensive, thus spinning would be - * too expensive. - * - * The flow "header" (addresses, ports, proto, recursion level) are static - * after the initialization and remain read-only throughout the entire live - * of a flow. This is why we can access those without protection of the lock. - */ - -typedef struct Flow_ -{ - /* flow "header", used for hashing and flow lookup. Static after init, - * so safe to look at without lock */ - FlowAddress src, dst; - union { - Port sp; /**< tcp/udp source port */ - uint8_t type; /**< icmp type */ - }; - union { - Port dp; /**< tcp/udp destination port */ - uint8_t code; /**< icmp code */ - }; - uint8_t proto; - uint8_t recursion_level; - uint16_t vlan_id[2]; - - /* end of flow "header" */ - - SC_ATOMIC_DECLARE(FlowStateType, flow_state); - - /** how many pkts and stream msgs are using the flow *right now*. This - * variable is atomic so not protected by the Flow mutex "m". - * - * On receiving a packet the counter is incremented while the flow - * bucked is locked, which is also the case on timeout pruning. - */ - SC_ATOMIC_DECLARE(FlowRefCount, use_cnt); - - /** flow queue id, used with autofp */ - SC_ATOMIC_DECLARE(int16_t, autofp_tmqh_flow_qid); - - /** flow tenant id, used to setup flow timeout and stream pseudo - * packets with the correct tenant id set */ - uint32_t tenant_id; - - uint32_t probing_parser_toserver_alproto_masks; - uint32_t probing_parser_toclient_alproto_masks; - - uint32_t flags; - - /* time stamp of last update (last packet). Set/updated under the - * flow and flow hash row locks, safe to read under either the - * flow lock or flow hash row lock. */ - struct timeval lastts; - -#ifdef FLOWLOCK_RWLOCK - SCRWLock r; -#elif defined FLOWLOCK_MUTEX - SCMutex m; -#else - #error Enable FLOWLOCK_RWLOCK or FLOWLOCK_MUTEX -#endif - - /** protocol specific data pointer, e.g. for TcpSession */ - void *protoctx; - - /** mapping to Flow's protocol specific protocols for timeouts - and state and free functions. */ - uint8_t protomap; - - uint8_t flow_end_flags; - /* coccinelle: Flow:flow_end_flags:FLOW_END_FLAG_ */ - - AppProto alproto; /**< \brief application level protocol */ - AppProto alproto_ts; - AppProto alproto_tc; - - uint32_t data_al_so_far[2]; - - /** detection engine ctx id used to inspect this flow. Set at initial - * inspection. If it doesn't match the currently in use de_ctx, the - * de_state and stored sgh ptrs are reset. */ - uint32_t de_ctx_id; - - /** Thread ID for the stream/detect portion of this flow */ - FlowThreadId thread_id; - - /** detect state 'alversion' inspected for both directions */ - uint8_t detect_alversion[2]; - - /** application level storage ptrs. - * - */ - AppLayerParserState *alparser; /**< parser internal state */ - void *alstate; /**< application layer state */ - - /** detection engine state */ - struct DetectEngineStateFlow_ *de_state; - - /** toclient sgh for this flow. Only use when FLOW_SGH_TOCLIENT flow flag - * has been set. */ - struct SigGroupHead_ *sgh_toclient; - /** toserver sgh for this flow. Only use when FLOW_SGH_TOSERVER flow flag - * has been set. */ - struct SigGroupHead_ *sgh_toserver; - - /* pointer to the var list */ - GenericVar *flowvar; - - /** hash list pointers, protected by fb->s */ - struct Flow_ *hnext; /* hash list */ - struct Flow_ *hprev; - struct FlowBucket_ *fb; - - /** queue list pointers, protected by queue mutex */ - struct Flow_ *lnext; /* list */ - struct Flow_ *lprev; - struct timeval startts; - - uint32_t todstpktcnt; - uint32_t tosrcpktcnt; - uint64_t todstbytecnt; - uint64_t tosrcbytecnt; -} Flow; - -enum { - FLOW_STATE_NEW = 0, - FLOW_STATE_ESTABLISHED, - FLOW_STATE_CLOSED, -}; - -typedef struct FlowProto_ { - uint32_t new_timeout; - uint32_t est_timeout; - uint32_t closed_timeout; - uint32_t emerg_new_timeout; - uint32_t emerg_est_timeout; - uint32_t emerg_closed_timeout; - void (*Freefunc)(void *); -} FlowProto; - -void FlowHandlePacket (ThreadVars *, DecodeThreadVars *, Packet *); -void FlowInitConfig (char); -void FlowPrintQueueInfo (void); -void FlowShutdown(void); -void FlowSetIPOnlyFlag(Flow *, char); -void FlowSetIPOnlyFlagNoLock(Flow *, char); - -void FlowRegisterTests (void); -int FlowSetProtoTimeout(uint8_t ,uint32_t ,uint32_t ,uint32_t); -int FlowSetProtoEmergencyTimeout(uint8_t ,uint32_t ,uint32_t ,uint32_t); -int FlowSetProtoFreeFunc (uint8_t , void (*Free)(void *)); -void FlowUpdateQueue(Flow *); - -struct FlowQueue_; - -int FlowUpdateSpareFlows(void); - -static inline void FlowLockSetNoPacketInspectionFlag(Flow *); -static inline void FlowSetNoPacketInspectionFlag(Flow *); -static inline void FlowLockSetNoPayloadInspectionFlag(Flow *); -static inline void FlowSetNoPayloadInspectionFlag(Flow *); - -int FlowGetPacketDirection(const Flow *, const Packet *); - -void FlowCleanupAppLayer(Flow *); - -/** ----- Inline functions ----- */ - -/** \brief Set the No Packet Inspection Flag after locking the flow. - * - * \param f Flow to set the flag in - */ -static inline void FlowLockSetNoPacketInspectionFlag(Flow *f) -{ - SCEnter(); - - SCLogDebug("flow %p", f); - FLOWLOCK_WRLOCK(f); - f->flags |= FLOW_NOPACKET_INSPECTION; - FLOWLOCK_UNLOCK(f); - - SCReturn; -} - -/** \brief Set the No Packet Inspection Flag without locking the flow. - * - * \param f Flow to set the flag in - */ -static inline void FlowSetNoPacketInspectionFlag(Flow *f) -{ - SCEnter(); - - SCLogDebug("flow %p", f); - f->flags |= FLOW_NOPACKET_INSPECTION; - - SCReturn; -} - -/** \brief Set the No payload inspection Flag after locking the flow. - * - * \param f Flow to set the flag in - */ -static inline void FlowLockSetNoPayloadInspectionFlag(Flow *f) -{ - SCEnter(); - - SCLogDebug("flow %p", f); - FLOWLOCK_WRLOCK(f); - f->flags |= FLOW_NOPAYLOAD_INSPECTION; - FLOWLOCK_UNLOCK(f); - - SCReturn; -} - -/** \brief Set the No payload inspection Flag without locking the flow. - * - * \param f Flow to set the flag in - */ -static inline void FlowSetNoPayloadInspectionFlag(Flow *f) -{ - SCEnter(); - - SCLogDebug("flow %p", f); - f->flags |= FLOW_NOPAYLOAD_INSPECTION; - - SCReturn; -} - -/** - * \brief increase the use count of a flow - * - * \param f flow to decrease use count for - */ -static inline void FlowIncrUsecnt(Flow *f) -{ - if (f == NULL) - return; - - (void) SC_ATOMIC_ADD(f->use_cnt, 1); -} - -/** - * \brief decrease the use count of a flow - * - * \param f flow to decrease use count for - */ -static inline void FlowDecrUsecnt(Flow *f) -{ - if (f == NULL) - return; - - (void) SC_ATOMIC_SUB(f->use_cnt, 1); -} - -/** \brief Reference the flow, bumping the flows use_cnt - * \note This should only be called once for a destination - * pointer */ -static inline void FlowReference(Flow **d, Flow *f) -{ - if (likely(f != NULL)) { -#ifdef DEBUG_VALIDATION - BUG_ON(*d == f); -#else - if (*d == f) - return; -#endif - FlowIncrUsecnt(f); - *d = f; - } -} - -static inline void FlowDeReference(Flow **d) -{ - if (likely(*d != NULL)) { - FlowDecrUsecnt(*d); - *d = NULL; - } -} - -int FlowClearMemory(Flow *,uint8_t ); - -AppProto FlowGetAppProtocol(const Flow *f); -void *FlowGetAppState(const Flow *f); -uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags); - -void FlowHandlePacketUpdateRemove(Flow *f, Packet *p); -void FlowHandlePacketUpdate(Flow *f, Packet *p); - -Flow *FlowGetFlowFromHashByPacket(const Packet *p); -Flow *FlowLookupFlowFromHash(const Packet *p); - -#endif /* __FLOW_H__ */ - diff --git a/framework/src/suricata/src/host-bit.c b/framework/src/suricata/src/host-bit.c deleted file mode 100644 index 6225673f..00000000 --- a/framework/src/suricata/src/host-bit.c +++ /dev/null @@ -1,503 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements per host bits. Actually, not a bit, - * but called that way because of Snort's flowbits. - * It's a binary storage. - * - * \todo move away from a linked list implementation - * \todo use different datatypes, such as string, int, etc. - */ - -#include "suricata-common.h" -#include "threads.h" -#include "host-bit.h" -#include "host.h" -#include "detect.h" -#include "util-var.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "host-storage.h" - -static int host_bit_id = -1; /**< Host storage id for bits */ - -void HostBitFreeAll(void *store) { - GenericVar *gv = store; - GenericVarFree(gv); -} - -void HostBitInitCtx(void) -{ - host_bit_id = HostStorageRegister("bit", sizeof(void *), NULL, HostBitFreeAll); - if (host_bit_id == -1) { - SCLogError(SC_ERR_HOST_INIT, "Can't initiate host storage for bits"); - exit(EXIT_FAILURE); - } -} - -/* lock before using this */ -int HostHasHostBits(Host *host) -{ - if (host == NULL) - return 0; - return HostGetStorageById(host, host_bit_id) ? 1 : 0; -} - -/** \retval 1 host timed out wrt xbits - * \retval 0 host still has active (non-expired) xbits */ -int HostBitsTimedoutCheck(Host *h, struct timeval *ts) -{ - GenericVar *gv = HostGetStorageById(h, host_bit_id); - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_XBITS) { - XBit *xb = (XBit *)gv; - if (xb->expire > (uint32_t)ts->tv_sec) - return 0; - } - } - return 1; -} - -/* get the bit with idx from the host */ -static XBit *HostBitGet(Host *h, uint16_t idx) -{ - GenericVar *gv = HostGetStorageById(h, host_bit_id); - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_XBITS && gv->idx == idx) { - return (XBit *)gv; - } - } - - return NULL; -} - -/* add a flowbit to the flow */ -static void HostBitAdd(Host *h, uint16_t idx, uint32_t expire) -{ - XBit *fb = HostBitGet(h, idx); - if (fb == NULL) { - fb = SCMalloc(sizeof(XBit)); - if (unlikely(fb == NULL)) - return; - - fb->type = DETECT_XBITS; - fb->idx = idx; - fb->next = NULL; - fb->expire = expire; - - GenericVar *gv = HostGetStorageById(h, host_bit_id); - GenericVarAppend(&gv, (GenericVar *)fb); - HostSetStorageById(h, host_bit_id, gv); - - // bit already set, lets update it's time - } else { - fb->expire = expire; - } -} - -static void HostBitRemove(Host *h, uint16_t idx) -{ - XBit *fb = HostBitGet(h, idx); - if (fb == NULL) - return; - - GenericVar *gv = HostGetStorageById(h, host_bit_id); - if (gv) { - GenericVarRemove(&gv, (GenericVar *)fb); - HostSetStorageById(h, host_bit_id, gv); - } -} - -void HostBitSet(Host *h, uint16_t idx, uint32_t expire) -{ - XBit *fb = HostBitGet(h, idx); - if (fb == NULL) { - HostBitAdd(h, idx, expire); - } -} - -void HostBitUnset(Host *h, uint16_t idx) -{ - XBit *fb = HostBitGet(h, idx); - if (fb != NULL) { - HostBitRemove(h, idx); - } -} - -void HostBitToggle(Host *h, uint16_t idx, uint32_t expire) -{ - XBit *fb = HostBitGet(h, idx); - if (fb != NULL) { - HostBitRemove(h, idx); - } else { - HostBitAdd(h, idx, expire); - } -} - -int HostBitIsset(Host *h, uint16_t idx, uint32_t ts) -{ - XBit *fb = HostBitGet(h, idx); - if (fb != NULL) { - if (fb->expire < ts) { - HostBitRemove(h,idx); - return 0; - } - return 1; - } - return 0; -} - -int HostBitIsnotset(Host *h, uint16_t idx, uint32_t ts) -{ - XBit *fb = HostBitGet(h, idx); - if (fb == NULL) { - return 1; - } - - if (fb->expire < ts) { - HostBitRemove(h,idx); - return 1; - } - return 0; -} - -/* TESTS */ -#ifdef UNITTESTS -static int HostBitTest01 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 0); - - XBit *fb = HostBitGet(h,0); - if (fb != NULL) - ret = 1; - - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest02 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - XBit *fb = HostBitGet(h,0); - if (fb == NULL) - ret = 1; - - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest03 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 30); - - XBit *fb = HostBitGet(h,0); - if (fb == NULL) { - printf("fb == NULL although it was just added: "); - goto end; - } - - HostBitRemove(h, 0); - - fb = HostBitGet(h,0); - if (fb != NULL) { - printf("fb != NULL although it was just removed: "); - goto end; - } else { - ret = 1; - } - - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest04 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 30); - HostBitAdd(h, 1, 30); - HostBitAdd(h, 2, 30); - HostBitAdd(h, 3, 30); - - XBit *fb = HostBitGet(h,0); - if (fb != NULL) - ret = 1; - - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest05 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 30); - HostBitAdd(h, 1, 30); - HostBitAdd(h, 2, 30); - HostBitAdd(h, 3, 30); - - XBit *fb = HostBitGet(h,1); - if (fb != NULL) - ret = 1; - - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest06 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 90); - HostBitAdd(h, 1, 90); - HostBitAdd(h, 2, 90); - HostBitAdd(h, 3, 90); - - XBit *fb = HostBitGet(h,2); - if (fb != NULL) - ret = 1; - - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest07 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 90); - HostBitAdd(h, 1, 90); - HostBitAdd(h, 2, 90); - HostBitAdd(h, 3, 90); - - XBit *fb = HostBitGet(h,3); - if (fb != NULL) - ret = 1; - - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest08 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 90); - HostBitAdd(h, 1, 90); - HostBitAdd(h, 2, 90); - HostBitAdd(h, 3, 90); - - XBit *fb = HostBitGet(h,0); - if (fb == NULL) - goto end; - - HostBitRemove(h,0); - - fb = HostBitGet(h,0); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest09 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 90); - HostBitAdd(h, 1, 90); - HostBitAdd(h, 2, 90); - HostBitAdd(h, 3, 90); - - XBit *fb = HostBitGet(h,1); - if (fb == NULL) - goto end; - - HostBitRemove(h,1); - - fb = HostBitGet(h,1); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest10 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 90); - HostBitAdd(h, 1, 90); - HostBitAdd(h, 2, 90); - HostBitAdd(h, 3, 90); - - XBit *fb = HostBitGet(h,2); - if (fb == NULL) - goto end; - - HostBitRemove(h,2); - - fb = HostBitGet(h,2); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; - HostFree(h); -end: - HostCleanup(); - return ret; -} - -static int HostBitTest11 (void) -{ - int ret = 0; - - HostInitConfig(TRUE); - Host *h = HostAlloc(); - if (h == NULL) - goto end; - - HostBitAdd(h, 0, 90); - HostBitAdd(h, 1, 90); - HostBitAdd(h, 2, 90); - HostBitAdd(h, 3, 90); - - XBit *fb = HostBitGet(h,3); - if (fb == NULL) - goto end; - - HostBitRemove(h,3); - - fb = HostBitGet(h,3); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; - HostFree(h); -end: - HostCleanup(); - return ret; -} - -#endif /* UNITTESTS */ - -void HostBitRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("HostBitTest01", HostBitTest01, 1); - UtRegisterTest("HostBitTest02", HostBitTest02, 1); - UtRegisterTest("HostBitTest03", HostBitTest03, 1); - UtRegisterTest("HostBitTest04", HostBitTest04, 1); - UtRegisterTest("HostBitTest05", HostBitTest05, 1); - UtRegisterTest("HostBitTest06", HostBitTest06, 1); - UtRegisterTest("HostBitTest07", HostBitTest07, 1); - UtRegisterTest("HostBitTest08", HostBitTest08, 1); - UtRegisterTest("HostBitTest09", HostBitTest09, 1); - UtRegisterTest("HostBitTest10", HostBitTest10, 1); - UtRegisterTest("HostBitTest11", HostBitTest11, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/host-bit.h b/framework/src/suricata/src/host-bit.h deleted file mode 100644 index d4bba11a..00000000 --- a/framework/src/suricata/src/host-bit.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __HOST_BIT_H__ -#define __HOST_BIT_H__ - -#include "host.h" -#include "util-var.h" - -void HostBitInitCtx(void); -void HostBitRegisterTests(void); - -int HostHasHostBits(Host *host); -int HostBitsTimedoutCheck(Host *h, struct timeval *ts); - -void HostBitSet(Host *, uint16_t, uint32_t); -void HostBitUnset(Host *, uint16_t); -void HostBitToggle(Host *, uint16_t, uint32_t); -int HostBitIsset(Host *, uint16_t, uint32_t); -int HostBitIsnotset(Host *, uint16_t, uint32_t); -#endif /* __HOST_BIT_H__ */ diff --git a/framework/src/suricata/src/host-queue.c b/framework/src/suricata/src/host-queue.c deleted file mode 100644 index 2ef1628d..00000000 --- a/framework/src/suricata/src/host-queue.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Host queue handler functions - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "host-queue.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-print.h" - -HostQueue *HostQueueInit (HostQueue *q) -{ - if (q != NULL) { - memset(q, 0, sizeof(HostQueue)); - HQLOCK_INIT(q); - } - return q; -} - -HostQueue *HostQueueNew() -{ - HostQueue *q = (HostQueue *)SCMalloc(sizeof(HostQueue)); - if (q == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in HostQueueNew. Exiting..."); - exit(EXIT_SUCCESS); - } - q = HostQueueInit(q); - return q; -} - -/** - * \brief Destroy a host queue - * - * \param q the host queue to destroy - */ -void HostQueueDestroy (HostQueue *q) -{ - HQLOCK_DESTROY(q); -} - -/** - * \brief add a host to a queue - * - * \param q queue - * \param h host - */ -void HostEnqueue (HostQueue *q, Host *h) -{ -#ifdef DEBUG - BUG_ON(q == NULL || h == NULL); -#endif - - HQLOCK_LOCK(q); - - /* more hosts in queue */ - if (q->top != NULL) { - h->lnext = q->top; - q->top->lprev = h; - q->top = h; - /* only host */ - } else { - q->top = h; - q->bot = h; - } - q->len++; -#ifdef DBG_PERF - if (q->len > q->dbg_maxlen) - q->dbg_maxlen = q->len; -#endif /* DBG_PERF */ - HQLOCK_UNLOCK(q); -} - -/** - * \brief remove a host from the queue - * - * \param q queue - * - * \retval h host or NULL if empty list. - */ -Host *HostDequeue (HostQueue *q) -{ - HQLOCK_LOCK(q); - - Host *h = q->bot; - if (h == NULL) { - HQLOCK_UNLOCK(q); - return NULL; - } - - /* more packets in queue */ - if (q->bot->lprev != NULL) { - q->bot = q->bot->lprev; - q->bot->lnext = NULL; - /* just the one we remove, so now empty */ - } else { - q->top = NULL; - q->bot = NULL; - } - -#ifdef DEBUG - BUG_ON(q->len == 0); -#endif - if (q->len > 0) - q->len--; - - h->lnext = NULL; - h->lprev = NULL; - - HQLOCK_UNLOCK(q); - return h; -} - -uint32_t HostQueueLen(HostQueue *q) -{ - uint32_t len; - HQLOCK_LOCK(q); - len = q->len; - HQLOCK_UNLOCK(q); - return len; -} - diff --git a/framework/src/suricata/src/host-queue.h b/framework/src/suricata/src/host-queue.h deleted file mode 100644 index 386d0f6e..00000000 --- a/framework/src/suricata/src/host-queue.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __HOST_QUEUE_H__ -#define __HOST_QUEUE_H__ - -#include "suricata-common.h" -#include "host.h" - -/** Spinlocks or Mutex for the host queues. */ -//#define HQLOCK_SPIN -#define HQLOCK_MUTEX - -#ifdef HQLOCK_SPIN - #ifdef HQLOCK_MUTEX - #error Cannot enable both HQLOCK_SPIN and HQLOCK_MUTEX - #endif -#endif - -/* Define a queue for storing hosts */ -typedef struct HostQueue_ -{ - Host *top; - Host *bot; - uint32_t len; -#ifdef DBG_PERF - uint32_t dbg_maxlen; -#endif /* DBG_PERF */ -#ifdef HQLOCK_MUTEX - SCMutex m; -#elif defined HQLOCK_SPIN - SCSpinlock s; -#else - #error Enable HQLOCK_SPIN or HQLOCK_MUTEX -#endif -} HostQueue; - -#ifdef HQLOCK_SPIN - #define HQLOCK_INIT(q) SCSpinInit(&(q)->s, 0) - #define HQLOCK_DESTROY(q) SCSpinDestroy(&(q)->s) - #define HQLOCK_LOCK(q) SCSpinLock(&(q)->s) - #define HQLOCK_TRYLOCK(q) SCSpinTrylock(&(q)->s) - #define HQLOCK_UNLOCK(q) SCSpinUnlock(&(q)->s) -#elif defined HQLOCK_MUTEX - #define HQLOCK_INIT(q) SCMutexInit(&(q)->m, NULL) - #define HQLOCK_DESTROY(q) SCMutexDestroy(&(q)->m) - #define HQLOCK_LOCK(q) SCMutexLock(&(q)->m) - #define HQLOCK_TRYLOCK(q) SCMutexTrylock(&(q)->m) - #define HQLOCK_UNLOCK(q) SCMutexUnlock(&(q)->m) -#else - #error Enable HQLOCK_SPIN or HQLOCK_MUTEX -#endif - -/* prototypes */ -HostQueue *HostQueueNew(); -HostQueue *HostQueueInit(HostQueue *); -void HostQueueDestroy (HostQueue *); - -void HostEnqueue (HostQueue *, Host *); -Host *HostDequeue (HostQueue *); -uint32_t HostQueueLen(HostQueue *); - -#endif /* __HOST_QUEUE_H__ */ - diff --git a/framework/src/suricata/src/host-storage.c b/framework/src/suricata/src/host-storage.c deleted file mode 100644 index fe157692..00000000 --- a/framework/src/suricata/src/host-storage.c +++ /dev/null @@ -1,337 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Host wrapper around storage api - */ - -#include "suricata-common.h" -#include "host-storage.h" -#include "util-unittest.h" - -unsigned int HostStorageSize(void) -{ - return StorageGetSize(STORAGE_HOST); -} - -/** \defgroup hoststorage Host storage API - * - * The Host storage API is a per-host storage. It is a mean to extend - * the Host structure with arbitrary data. - * - * You have first to register the storage via HostStorageRegister() during - * the init of your module. Then you can attach data via HostSetStorageById() - * and access them via HostGetStorageById(). - * @{ - */ - -/** - * \brief Register a Host storage - * - * \param name the name of the storage - * \param size integer coding the size of the stored value (sizeof(void *) is best choice here) - * \param Alloc allocation function for the storage (can be null) - * \param Free free function for the new storage - * - * \retval The ID of the newly register storage that will be used to access data - * - * It has to be called once during the init of the sub system - */ - -int HostStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)) { - return StorageRegister(STORAGE_HOST, name, size, Alloc, Free); -} - -/** - * \brief Store a pointer in a given Host storage - * - * \param h a pointer to the Host - * \param id the id of the storage (return of HostStorageRegister() call) - * \param ptr pointer to the data to store - */ - -int HostSetStorageById(Host *h, int id, void *ptr) -{ - return StorageSetById((Storage *)((void *)h + sizeof(Host)), STORAGE_HOST, id, ptr); -} - -/** - * \brief Get a value from a given Host storage - * - * \param h a pointer to the Host - * \param id the id of the storage (return of HostStorageRegister() call) - * - */ - -void *HostGetStorageById(Host *h, int id) -{ - return StorageGetById((Storage *)((void *)h + sizeof(Host)), STORAGE_HOST, id); -} - -/** - * @} - */ - -/* Start of "private" function */ - -void *HostAllocStorageById(Host *h, int id) -{ - return StorageAllocByIdPrealloc((Storage *)((void *)h + sizeof(Host)), STORAGE_HOST, id); -} - -void HostFreeStorageById(Host *h, int id) -{ - StorageFreeById((Storage *)((void *)h + sizeof(Host)), STORAGE_HOST, id); -} - -void HostFreeStorage(Host *h) -{ - if (HostStorageSize() > 0) - StorageFreeAll((Storage *)((void *)h + sizeof(Host)), STORAGE_HOST); -} - - -#ifdef UNITTESTS - -static void *StorageTestAlloc(unsigned int size) -{ - void *x = SCMalloc(size); - return x; -} -static void StorageTestFree(void *x) -{ - if (x) - SCFree(x); -} - -static int HostStorageTest01(void) -{ - StorageInit(); - - int id1 = HostStorageRegister("test", 8, StorageTestAlloc, StorageTestFree); - if (id1 < 0) - goto error; - int id2 = HostStorageRegister("variable", 24, StorageTestAlloc, StorageTestFree); - if (id2 < 0) - goto error; - int id3 = HostStorageRegister("store", sizeof(void *), StorageTestAlloc, StorageTestFree); - if (id3 < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - HostInitConfig(1); - - Address a; - memset(&a, 0x00, sizeof(a)); - a.addr_data32[0] = 0x01020304; - a.family = AF_INET; - Host *h = HostGetHostFromHash(&a); - if (h == NULL) { - printf("failed to get host: "); - goto error; - } - - void *ptr = HostGetStorageById(h, id1); - if (ptr != NULL) { - goto error; - } - ptr = HostGetStorageById(h, id2); - if (ptr != NULL) { - goto error; - } - ptr = HostGetStorageById(h, id3); - if (ptr != NULL) { - goto error; - } - - void *ptr1a = HostAllocStorageById(h, id1); - if (ptr1a == NULL) { - goto error; - } - void *ptr2a = HostAllocStorageById(h, id2); - if (ptr2a == NULL) { - goto error; - } - void *ptr3a = HostAllocStorageById(h, id3); - if (ptr3a == NULL) { - goto error; - } - - void *ptr1b = HostGetStorageById(h, id1); - if (ptr1a != ptr1b) { - goto error; - } - void *ptr2b = HostGetStorageById(h, id2); - if (ptr2a != ptr2b) { - goto error; - } - void *ptr3b = HostGetStorageById(h, id3); - if (ptr3a != ptr3b) { - goto error; - } - - HostRelease(h); - - HostShutdown(); - StorageCleanup(); - return 1; -error: - HostShutdown(); - StorageCleanup(); - return 0; -} - -static int HostStorageTest02(void) -{ - StorageInit(); - - int id1 = HostStorageRegister("test", sizeof(void *), NULL, StorageTestFree); - if (id1 < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - HostInitConfig(1); - - Address a; - memset(&a, 0x00, sizeof(a)); - a.addr_data32[0] = 0x01020304; - a.family = AF_INET; - Host *h = HostGetHostFromHash(&a); - if (h == NULL) { - printf("failed to get host: "); - goto error; - } - - void *ptr = HostGetStorageById(h, id1); - if (ptr != NULL) { - goto error; - } - - void *ptr1a = SCMalloc(128); - if (unlikely(ptr1a == NULL)) { - goto error; - } - HostSetStorageById(h, id1, ptr1a); - - void *ptr1b = HostGetStorageById(h, id1); - if (ptr1a != ptr1b) { - goto error; - } - - HostRelease(h); - - HostShutdown(); - StorageCleanup(); - return 1; -error: - HostShutdown(); - StorageCleanup(); - return 0; -} - -static int HostStorageTest03(void) -{ - StorageInit(); - - int id1 = HostStorageRegister("test1", sizeof(void *), NULL, StorageTestFree); - if (id1 < 0) - goto error; - int id2 = HostStorageRegister("test2", sizeof(void *), NULL, StorageTestFree); - if (id2 < 0) - goto error; - int id3 = HostStorageRegister("test3", 32, StorageTestAlloc, StorageTestFree); - if (id3 < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - HostInitConfig(1); - - Address a; - memset(&a, 0x00, sizeof(a)); - a.addr_data32[0] = 0x01020304; - a.family = AF_INET; - Host *h = HostGetHostFromHash(&a); - if (h == NULL) { - printf("failed to get host: "); - goto error; - } - - void *ptr = HostGetStorageById(h, id1); - if (ptr != NULL) { - goto error; - } - - void *ptr1a = SCMalloc(128); - if (unlikely(ptr1a == NULL)) { - goto error; - } - HostSetStorageById(h, id1, ptr1a); - - void *ptr2a = SCMalloc(256); - if (unlikely(ptr2a == NULL)) { - goto error; - } - HostSetStorageById(h, id2, ptr2a); - - void *ptr3a = HostAllocStorageById(h, id3); - if (ptr3a == NULL) { - goto error; - } - - void *ptr1b = HostGetStorageById(h, id1); - if (ptr1a != ptr1b) { - goto error; - } - void *ptr2b = HostGetStorageById(h, id2); - if (ptr2a != ptr2b) { - goto error; - } - void *ptr3b = HostGetStorageById(h, id3); - if (ptr3a != ptr3b) { - goto error; - } - - HostRelease(h); - - HostShutdown(); - StorageCleanup(); - return 1; -error: - HostShutdown(); - StorageCleanup(); - return 0; -} -#endif - -void RegisterHostStorageTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("HostStorageTest01", HostStorageTest01, 1); - UtRegisterTest("HostStorageTest02", HostStorageTest02, 1); - UtRegisterTest("HostStorageTest03", HostStorageTest03, 1); -#endif -} diff --git a/framework/src/suricata/src/host-storage.h b/framework/src/suricata/src/host-storage.h deleted file mode 100644 index b2bccbe2..00000000 --- a/framework/src/suricata/src/host-storage.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Host wrapper around storage api - */ - -#ifndef __HOST_STORAGE_H__ -#define __HOST_STORAGE_H__ - -#include "util-storage.h" -#include "host.h" - -unsigned int HostStorageSize(void); - -void *HostGetStorageById(Host *h, int id); -int HostSetStorageById(Host *h, int id, void *ptr); -void *HostAllocStorageById(Host *h, int id); - -void HostFreeStorageById(Host *h, int id); -void HostFreeStorage(Host *h); - -void RegisterHostStorageTests(void); - -int HostStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)); - -#endif /* __HOST_STORAGE_H__ */ diff --git a/framework/src/suricata/src/host-timeout.c b/framework/src/suricata/src/host-timeout.c deleted file mode 100644 index c8be4e05..00000000 --- a/framework/src/suricata/src/host-timeout.c +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "host.h" - -#include "detect-engine-tag.h" -#include "detect-engine-threshold.h" - -#include "host-bit.h" - -#include "reputation.h" - -uint32_t HostGetSpareCount(void) -{ - return HostSpareQueueGetSize(); -} - -uint32_t HostGetActiveCount(void) -{ - return SC_ATOMIC_GET(host_counter); -} - -/** \internal - * \brief See if we can really discard this host. Check use_cnt reference. - * - * \param h host - * \param ts timestamp - * - * \retval 0 not timed out just yet - * \retval 1 fully timed out, lets kill it - */ -static int HostHostTimedOut(Host *h, struct timeval *ts) -{ - int tags = 0; - int thresholds = 0; - int vars = 0; - - /** never prune a host that is used by a packet - * we are currently processing in one of the threads */ - if (SC_ATOMIC_GET(h->use_cnt) > 0) { - return 0; - } - - if (h->iprep) { - if (SRepHostTimedOut(h) == 0) - return 0; - - SCLogDebug("host %p reputation timed out", h); - } - - if (TagHostHasTag(h) && TagTimeoutCheck(h, ts) == 0) { - tags = 1; - } - if (ThresholdHostHasThreshold(h) && ThresholdTimeoutCheck(h, ts) == 0) { - thresholds = 1; - } - if (HostHasHostBits(h) && HostBitsTimedoutCheck(h, ts) == 0) { - vars = 1; - } - - if (tags || thresholds || vars) - return 0; - - SCLogDebug("host %p timed out", h); - return 1; -} - -/** - * \internal - * - * \brief check all hosts in a hash row for timing out - * - * \param hb host hash row *LOCKED* - * \param h last host in the hash row - * \param ts timestamp - * - * \retval cnt timed out hosts - */ -static uint32_t HostHashRowTimeout(HostHashRow *hb, Host *h, struct timeval *ts) -{ - uint32_t cnt = 0; - - do { - if (SCMutexTrylock(&h->m) != 0) { - h = h->hprev; - continue; - } - - Host *next_host = h->hprev; - - /* check if the host is fully timed out and - * ready to be discarded. */ - if (HostHostTimedOut(h, ts) == 1) { - /* remove from the hash */ - if (h->hprev != NULL) - h->hprev->hnext = h->hnext; - if (h->hnext != NULL) - h->hnext->hprev = h->hprev; - if (hb->head == h) - hb->head = h->hnext; - if (hb->tail == h) - hb->tail = h->hprev; - - h->hnext = NULL; - h->hprev = NULL; - - HostClearMemory (h); - - /* no one is referring to this host, use_cnt 0, removed from hash - * so we can unlock it and move it back to the spare queue. */ - SCMutexUnlock(&h->m); - - /* move to spare list */ - HostMoveToSpare(h); - - cnt++; - } else { - SCMutexUnlock(&h->m); - } - - h = next_host; - } while (h != NULL); - - return cnt; -} - -/** - * \brief time out hosts from the hash - * - * \param ts timestamp - * - * \retval cnt number of timed out host - */ -uint32_t HostTimeoutHash(struct timeval *ts) -{ - uint32_t idx = 0; - uint32_t cnt = 0; - - for (idx = 0; idx < host_config.hash_size; idx++) { - HostHashRow *hb = &host_hash[idx]; - - if (HRLOCK_TRYLOCK(hb) != 0) - continue; - - /* host hash bucket is now locked */ - - if (hb->tail == NULL) { - HRLOCK_UNLOCK(hb); - continue; - } - - /* we have a host, or more than one */ - cnt += HostHashRowTimeout(hb, hb->tail, ts); - HRLOCK_UNLOCK(hb); - } - - return cnt; -} - diff --git a/framework/src/suricata/src/host-timeout.h b/framework/src/suricata/src/host-timeout.h deleted file mode 100644 index 6ea1e894..00000000 --- a/framework/src/suricata/src/host-timeout.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __HOST_TIMEOUT_H__ -#define __HOST_TIMEOUT_H__ - -uint32_t HostTimeoutHash(struct timeval *ts); - -uint32_t HostGetSpareCount(void); -uint32_t HostGetActiveCount(void); - -#endif - diff --git a/framework/src/suricata/src/host.c b/framework/src/suricata/src/host.c deleted file mode 100644 index a28639cc..00000000 --- a/framework/src/suricata/src/host.c +++ /dev/null @@ -1,695 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Information about hosts. - */ - -#include "suricata-common.h" -#include "conf.h" - -#include "util-debug.h" -#include "host.h" -#include "host-storage.h" -#include "host-bit.h" - -#include "util-random.h" -#include "util-misc.h" -#include "util-byte.h" - -#include "host-queue.h" - -#include "detect-tag.h" -#include "detect-engine-tag.h" -#include "detect-engine-threshold.h" - -#include "util-hash-lookup3.h" - -static Host *HostGetUsedHost(void); - -/** queue with spare hosts */ -static HostQueue host_spare_q; - -/** size of the host object. Maybe updated in HostInitConfig to include - * the storage APIs additions. */ -static uint16_t g_host_size = sizeof(Host); - -uint32_t HostSpareQueueGetSize(void) -{ - return HostQueueLen(&host_spare_q); -} - -void HostMoveToSpare(Host *h) -{ - HostEnqueue(&host_spare_q, h); - (void) SC_ATOMIC_SUB(host_counter, 1); -} - -Host *HostAlloc(void) -{ - if (!(HOST_CHECK_MEMCAP(g_host_size))) { - return NULL; - } - (void) SC_ATOMIC_ADD(host_memuse, g_host_size); - - Host *h = SCMalloc(g_host_size); - if (unlikely(h == NULL)) - goto error; - - memset(h, 0x00, g_host_size); - - SCMutexInit(&h->m, NULL); - SC_ATOMIC_INIT(h->use_cnt); - return h; - -error: - return NULL; -} - -void HostFree(Host *h) -{ - if (h != NULL) { - HostClearMemory(h); - - SC_ATOMIC_DESTROY(h->use_cnt); - SCMutexDestroy(&h->m); - SCFree(h); - (void) SC_ATOMIC_SUB(host_memuse, g_host_size); - } -} - -Host *HostNew(Address *a) -{ - Host *h = HostAlloc(); - if (h == NULL) - goto error; - - /* copy address */ - COPY_ADDRESS(a, &h->a); - - return h; - -error: - return NULL; -} - -void HostClearMemory(Host *h) -{ - if (h->iprep != NULL) { - SCFree(h->iprep); - h->iprep = NULL; - } - - if (HostStorageSize() > 0) - HostFreeStorage(h); -} - -#define HOST_DEFAULT_HASHSIZE 4096 -#define HOST_DEFAULT_MEMCAP 16777216 -#define HOST_DEFAULT_PREALLOC 1000 - -/** \brief initialize the configuration - * \warning Not thread safe */ -void HostInitConfig(char quiet) -{ - SCLogDebug("initializing host engine..."); - if (HostStorageSize() > 0) - g_host_size = sizeof(Host) + HostStorageSize(); - - memset(&host_config, 0, sizeof(host_config)); - //SC_ATOMIC_INIT(flow_flags); - SC_ATOMIC_INIT(host_counter); - SC_ATOMIC_INIT(host_memuse); - SC_ATOMIC_INIT(host_prune_idx); - HostQueueInit(&host_spare_q); - - unsigned int seed = RandomTimePreseed(); - /* set defaults */ - host_config.hash_rand = (int)( HOST_DEFAULT_HASHSIZE * (rand_r(&seed) / RAND_MAX + 1.0)); - - host_config.hash_size = HOST_DEFAULT_HASHSIZE; - host_config.memcap = HOST_DEFAULT_MEMCAP; - host_config.prealloc = HOST_DEFAULT_PREALLOC; - - /* Check if we have memcap and hash_size defined at config */ - char *conf_val; - uint32_t configval = 0; - - /** set config values for memcap, prealloc and hash_size */ - if ((ConfGet("host.memcap", &conf_val)) == 1) - { - if (ParseSizeStringU64(conf_val, &host_config.memcap) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing host.memcap " - "from conf file - %s. Killing engine", - conf_val); - exit(EXIT_FAILURE); - } - } - if ((ConfGet("host.hash-size", &conf_val)) == 1) - { - if (ByteExtractStringUint32(&configval, 10, strlen(conf_val), - conf_val) > 0) { - host_config.hash_size = configval; - } - } - - if ((ConfGet("host.prealloc", &conf_val)) == 1) - { - if (ByteExtractStringUint32(&configval, 10, strlen(conf_val), - conf_val) > 0) { - host_config.prealloc = configval; - } else { - WarnInvalidConfEntry("host.prealloc", "%"PRIu32, host_config.prealloc); - } - } - SCLogDebug("Host config from suricata.yaml: memcap: %"PRIu64", hash-size: " - "%"PRIu32", prealloc: %"PRIu32, host_config.memcap, - host_config.hash_size, host_config.prealloc); - - /* alloc hash memory */ - uint64_t hash_size = host_config.hash_size * sizeof(HostHashRow); - if (!(HOST_CHECK_MEMCAP(hash_size))) { - SCLogError(SC_ERR_HOST_INIT, "allocating host hash failed: " - "max host memcap is smaller than projected hash size. " - "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate " - "total hash size by multiplying \"host.hash-size\" with %"PRIuMAX", " - "which is the hash bucket size.", host_config.memcap, hash_size, - (uintmax_t)sizeof(HostHashRow)); - exit(EXIT_FAILURE); - } - host_hash = SCCalloc(host_config.hash_size, sizeof(HostHashRow)); - if (unlikely(host_hash == NULL)) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in HostInitConfig. Exiting..."); - exit(EXIT_FAILURE); - } - memset(host_hash, 0, host_config.hash_size * sizeof(HostHashRow)); - - uint32_t i = 0; - for (i = 0; i < host_config.hash_size; i++) { - HRLOCK_INIT(&host_hash[i]); - } - (void) SC_ATOMIC_ADD(host_memuse, (host_config.hash_size * sizeof(HostHashRow))); - - if (quiet == FALSE) { - SCLogInfo("allocated %llu bytes of memory for the host hash... " - "%" PRIu32 " buckets of size %" PRIuMAX "", - SC_ATOMIC_GET(host_memuse), host_config.hash_size, - (uintmax_t)sizeof(HostHashRow)); - } - - /* pre allocate hosts */ - for (i = 0; i < host_config.prealloc; i++) { - if (!(HOST_CHECK_MEMCAP(g_host_size))) { - SCLogError(SC_ERR_HOST_INIT, "preallocating hosts failed: " - "max host memcap reached. Memcap %"PRIu64", " - "Memuse %"PRIu64".", host_config.memcap, - ((uint64_t)SC_ATOMIC_GET(host_memuse) + g_host_size)); - exit(EXIT_FAILURE); - } - - Host *h = HostAlloc(); - if (h == NULL) { - SCLogError(SC_ERR_HOST_INIT, "preallocating host failed: %s", strerror(errno)); - exit(EXIT_FAILURE); - } - HostEnqueue(&host_spare_q,h); - } - - if (quiet == FALSE) { - SCLogInfo("preallocated %" PRIu32 " hosts of size %" PRIu16 "", - host_spare_q.len, g_host_size); - SCLogInfo("host memory usage: %llu bytes, maximum: %"PRIu64, - SC_ATOMIC_GET(host_memuse), host_config.memcap); - } - - return; -} - -/** \brief print some host stats - * \warning Not thread safe */ -void HostPrintStats (void) -{ -#ifdef HOSTBITS_STATS - SCLogInfo("hostbits added: %" PRIu32 ", removed: %" PRIu32 ", max memory usage: %" PRIu32 "", - hostbits_added, hostbits_removed, hostbits_memuse_max); -#endif /* HOSTBITS_STATS */ - SCLogInfo("host memory usage: %llu bytes, maximum: %"PRIu64, - SC_ATOMIC_GET(host_memuse), host_config.memcap); - return; -} - -/** \brief shutdown the flow engine - * \warning Not thread safe */ -void HostShutdown(void) -{ - Host *h; - uint32_t u; - - HostPrintStats(); - - /* free spare queue */ - while((h = HostDequeue(&host_spare_q))) { - BUG_ON(SC_ATOMIC_GET(h->use_cnt) > 0); - HostFree(h); - } - - /* clear and free the hash */ - if (host_hash != NULL) { - for (u = 0; u < host_config.hash_size; u++) { - Host *h = host_hash[u].head; - while (h) { - Host *n = h->hnext; - HostFree(h); - h = n; - } - - HRLOCK_DESTROY(&host_hash[u]); - } - SCFree(host_hash); - host_hash = NULL; - } - (void) SC_ATOMIC_SUB(host_memuse, host_config.hash_size * sizeof(HostHashRow)); - HostQueueDestroy(&host_spare_q); - - SC_ATOMIC_DESTROY(host_prune_idx); - SC_ATOMIC_DESTROY(host_memuse); - SC_ATOMIC_DESTROY(host_counter); - //SC_ATOMIC_DESTROY(flow_flags); - return; -} - -/** \brief Cleanup the host engine - * - * Cleanup the host engine from tag and threshold. - * - */ -void HostCleanup(void) -{ - Host *h; - uint32_t u; - - if (host_hash != NULL) { - for (u = 0; u < host_config.hash_size; u++) { - h = host_hash[u].head; - HostHashRow *hb = &host_hash[u]; - HRLOCK_LOCK(hb); - while (h) { - if ((SC_ATOMIC_GET(h->use_cnt) > 0) && (h->iprep != NULL)) { - /* iprep is attached to host only clear local storage */ - HostFreeStorage(h); - h = h->hnext; - } else { - Host *n = h->hnext; - /* remove from the hash */ - if (h->hprev != NULL) - h->hprev->hnext = h->hnext; - if (h->hnext != NULL) - h->hnext->hprev = h->hprev; - if (hb->head == h) - hb->head = h->hnext; - if (hb->tail == h) - hb->tail = h->hprev; - h->hnext = NULL; - h->hprev = NULL; - HostClearMemory(h); - HostMoveToSpare(h); - h = n; - } - } - HRLOCK_UNLOCK(hb); - } - } - - return; -} - -/* calculate the hash key for this packet - * - * we're using: - * hash_rand -- set at init time - * source address - */ -uint32_t HostGetKey(Address *a) -{ - uint32_t key; - - if (a->family == AF_INET) { - uint32_t hash = hashword(&a->addr_data32[0], 1, host_config.hash_rand); - key = hash % host_config.hash_size; - } else if (a->family == AF_INET6) { - uint32_t hash = hashword(a->addr_data32, 4, host_config.hash_rand); - key = hash % host_config.hash_size; - } else - key = 0; - - return key; -} - -/* Since two or more hosts can have the same hash key, we need to compare - * the flow with the current flow key. */ -#define CMP_HOST(h,a) \ - (CMP_ADDR(&(h)->a, (a))) - -static inline int HostCompare(Host *h, Address *a) -{ - return CMP_HOST(h, a); -} - -/** - * \brief Get a new host - * - * Get a new host. We're checking memcap first and will try to make room - * if the memcap is reached. - * - * \retval h *LOCKED* host on succes, NULL on error. - */ -static Host *HostGetNew(Address *a) -{ - Host *h = NULL; - - /* get a host from the spare queue */ - h = HostDequeue(&host_spare_q); - if (h == NULL) { - /* If we reached the max memcap, we get a used host */ - if (!(HOST_CHECK_MEMCAP(g_host_size))) { - /* declare state of emergency */ - //if (!(SC_ATOMIC_GET(host_flags) & HOST_EMERGENCY)) { - // SC_ATOMIC_OR(host_flags, HOST_EMERGENCY); - - /* under high load, waking up the flow mgr each time leads - * to high cpu usage. Flows are not timed out much faster if - * we check a 1000 times a second. */ - // FlowWakeupFlowManagerThread(); - //} - - h = HostGetUsedHost(); - if (h == NULL) { - return NULL; - } - - /* freed a host, but it's unlocked */ - } else { - /* now see if we can alloc a new host */ - h = HostNew(a); - if (h == NULL) { - return NULL; - } - - /* host is initialized but *unlocked* */ - } - } else { - /* host has been recycled before it went into the spare queue */ - - /* host is initialized (recylced) but *unlocked* */ - } - - (void) SC_ATOMIC_ADD(host_counter, 1); - SCMutexLock(&h->m); - return h; -} - -void HostInit(Host *h, Address *a) -{ - COPY_ADDRESS(a, &h->a); - (void) HostIncrUsecnt(h); -} - -void HostRelease(Host *h) -{ - (void) HostDecrUsecnt(h); - SCMutexUnlock(&h->m); -} - -void HostLock(Host *h) -{ - SCMutexLock(&h->m); -} - -void HostUnlock(Host *h) -{ - SCMutexUnlock(&h->m); -} - - -/* HostGetHostFromHash - * - * Hash retrieval function for hosts. Looks up the hash bucket containing the - * host pointer. Then compares the packet with the found host to see if it is - * the host we need. If it isn't, walk the list until the right host is found. - * - * returns a *LOCKED* host or NULL - */ -Host *HostGetHostFromHash (Address *a) -{ - Host *h = NULL; - - /* get the key to our bucket */ - uint32_t key = HostGetKey(a); - /* get our hash bucket and lock it */ - HostHashRow *hb = &host_hash[key]; - HRLOCK_LOCK(hb); - - /* see if the bucket already has a host */ - if (hb->head == NULL) { - h = HostGetNew(a); - if (h == NULL) { - HRLOCK_UNLOCK(hb); - return NULL; - } - - /* host is locked */ - hb->head = h; - hb->tail = h; - - /* got one, now lock, initialize and return */ - HostInit(h,a); - - HRLOCK_UNLOCK(hb); - return h; - } - - /* ok, we have a host in the bucket. Let's find out if it is our host */ - h = hb->head; - - /* see if this is the host we are looking for */ - if (HostCompare(h, a) == 0) { - Host *ph = NULL; /* previous host */ - - while (h) { - ph = h; - h = h->hnext; - - if (h == NULL) { - h = ph->hnext = HostGetNew(a); - if (h == NULL) { - HRLOCK_UNLOCK(hb); - return NULL; - } - hb->tail = h; - - /* host is locked */ - - h->hprev = ph; - - /* initialize and return */ - HostInit(h,a); - - HRLOCK_UNLOCK(hb); - return h; - } - - if (HostCompare(h, a) != 0) { - /* we found our host, lets put it on top of the - * hash list -- this rewards active hosts */ - if (h->hnext) { - h->hnext->hprev = h->hprev; - } - if (h->hprev) { - h->hprev->hnext = h->hnext; - } - if (h == hb->tail) { - hb->tail = h->hprev; - } - - h->hnext = hb->head; - h->hprev = NULL; - hb->head->hprev = h; - hb->head = h; - - /* found our host, lock & return */ - SCMutexLock(&h->m); - (void) HostIncrUsecnt(h); - HRLOCK_UNLOCK(hb); - return h; - } - } - } - - /* lock & return */ - SCMutexLock(&h->m); - (void) HostIncrUsecnt(h); - HRLOCK_UNLOCK(hb); - return h; -} - -/** \brief look up a host in the hash - * - * \param a address to look up - * - * \retval h *LOCKED* host or NULL - */ -Host *HostLookupHostFromHash (Address *a) -{ - Host *h = NULL; - - /* get the key to our bucket */ - uint32_t key = HostGetKey(a); - /* get our hash bucket and lock it */ - HostHashRow *hb = &host_hash[key]; - HRLOCK_LOCK(hb); - - /* see if the bucket already has a host */ - if (hb->head == NULL) { - HRLOCK_UNLOCK(hb); - return h; - } - - /* ok, we have a host in the bucket. Let's find out if it is our host */ - h = hb->head; - - /* see if this is the host we are looking for */ - if (HostCompare(h, a) == 0) { - while (h) { - h = h->hnext; - - if (h == NULL) { - HRLOCK_UNLOCK(hb); - return h; - } - - if (HostCompare(h, a) != 0) { - /* we found our host, lets put it on top of the - * hash list -- this rewards active hosts */ - if (h->hnext) { - h->hnext->hprev = h->hprev; - } - if (h->hprev) { - h->hprev->hnext = h->hnext; - } - if (h == hb->tail) { - hb->tail = h->hprev; - } - - h->hnext = hb->head; - h->hprev = NULL; - hb->head->hprev = h; - hb->head = h; - - /* found our host, lock & return */ - SCMutexLock(&h->m); - (void) HostIncrUsecnt(h); - HRLOCK_UNLOCK(hb); - return h; - } - } - } - - /* lock & return */ - SCMutexLock(&h->m); - (void) HostIncrUsecnt(h); - HRLOCK_UNLOCK(hb); - return h; -} - -/** \internal - * \brief Get a host from the hash directly. - * - * Called in conditions where the spare queue is empty and memcap is reached. - * - * Walks the hash until a host can be freed. "host_prune_idx" atomic int makes - * sure we don't start at the top each time since that would clear the top of - * the hash leading to longer and longer search times under high pressure (observed). - * - * \retval h host or NULL - */ -static Host *HostGetUsedHost(void) -{ - uint32_t idx = SC_ATOMIC_GET(host_prune_idx) % host_config.hash_size; - uint32_t cnt = host_config.hash_size; - - while (cnt--) { - if (++idx >= host_config.hash_size) - idx = 0; - - HostHashRow *hb = &host_hash[idx]; - - if (HRLOCK_TRYLOCK(hb) != 0) - continue; - - Host *h = hb->tail; - if (h == NULL) { - HRLOCK_UNLOCK(hb); - continue; - } - - if (SCMutexTrylock(&h->m) != 0) { - HRLOCK_UNLOCK(hb); - continue; - } - - /** never prune a host that is used by a packets - * we are currently processing in one of the threads */ - if (SC_ATOMIC_GET(h->use_cnt) > 0) { - HRLOCK_UNLOCK(hb); - SCMutexUnlock(&h->m); - continue; - } - - /* remove from the hash */ - if (h->hprev != NULL) - h->hprev->hnext = h->hnext; - if (h->hnext != NULL) - h->hnext->hprev = h->hprev; - if (hb->head == h) - hb->head = h->hnext; - if (hb->tail == h) - hb->tail = h->hprev; - - h->hnext = NULL; - h->hprev = NULL; - HRLOCK_UNLOCK(hb); - - HostClearMemory (h); - - SCMutexUnlock(&h->m); - - (void) SC_ATOMIC_ADD(host_prune_idx, (host_config.hash_size - cnt)); - return h; - } - - return NULL; -} - -void HostRegisterUnittests(void) -{ - RegisterHostStorageTests(); -} - diff --git a/framework/src/suricata/src/host.h b/framework/src/suricata/src/host.h deleted file mode 100644 index e3dd167a..00000000 --- a/framework/src/suricata/src/host.h +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __HOST_H__ -#define __HOST_H__ - -#include "decode.h" -#include "util-storage.h" - -/** Spinlocks or Mutex for the flow buckets. */ -//#define HRLOCK_SPIN -#define HRLOCK_MUTEX - -#ifdef HRLOCK_SPIN - #ifdef HRLOCK_MUTEX - #error Cannot enable both HRLOCK_SPIN and HRLOCK_MUTEX - #endif -#endif - -#ifdef HRLOCK_SPIN - #define HRLOCK_TYPE SCSpinlock - #define HRLOCK_INIT(fb) SCSpinInit(&(fb)->lock, 0) - #define HRLOCK_DESTROY(fb) SCSpinDestroy(&(fb)->lock) - #define HRLOCK_LOCK(fb) SCSpinLock(&(fb)->lock) - #define HRLOCK_TRYLOCK(fb) SCSpinTrylock(&(fb)->lock) - #define HRLOCK_UNLOCK(fb) SCSpinUnlock(&(fb)->lock) -#elif defined HRLOCK_MUTEX - #define HRLOCK_TYPE SCMutex - #define HRLOCK_INIT(fb) SCMutexInit(&(fb)->lock, NULL) - #define HRLOCK_DESTROY(fb) SCMutexDestroy(&(fb)->lock) - #define HRLOCK_LOCK(fb) SCMutexLock(&(fb)->lock) - #define HRLOCK_TRYLOCK(fb) SCMutexTrylock(&(fb)->lock) - #define HRLOCK_UNLOCK(fb) SCMutexUnlock(&(fb)->lock) -#else - #error Enable HRLOCK_SPIN or HRLOCK_MUTEX -#endif - -typedef struct Host_ { - /** host mutex */ - SCMutex m; - - /** host address -- ipv4 or ipv6 */ - Address a; - - /** use cnt, reference counter */ - SC_ATOMIC_DECLARE(unsigned int, use_cnt); - - /** pointers to iprep storage */ - void *iprep; - - /** storage api handle */ - Storage *storage; - - /** hash pointers, protected by hash row mutex/spin */ - struct Host_ *hnext; - struct Host_ *hprev; - - /** list pointers, protected by host-queue mutex/spin */ - struct Host_ *lnext; - struct Host_ *lprev; -} Host; - -typedef struct HostHashRow_ { - HRLOCK_TYPE lock; - Host *head; - Host *tail; -} __attribute__((aligned(CLS))) HostHashRow; - -/** host hash table */ -HostHashRow *host_hash; - -#define HOST_VERBOSE 0 -#define HOST_QUIET 1 - -typedef struct HostConfig_ { - uint64_t memcap; - uint32_t hash_rand; - uint32_t hash_size; - uint32_t prealloc; -} HostConfig; - -/** \brief check if a memory alloc would fit in the memcap - * - * \param size memory allocation size to check - * - * \retval 1 it fits - * \retval 0 no fit - */ -#define HOST_CHECK_MEMCAP(size) \ - ((((uint64_t)SC_ATOMIC_GET(host_memuse) + (uint64_t)(size)) <= host_config.memcap)) - -#define HostIncrUsecnt(h) \ - (void)SC_ATOMIC_ADD((h)->use_cnt, 1) -#define HostDecrUsecnt(h) \ - (void)SC_ATOMIC_SUB((h)->use_cnt, 1) - -#define HostReference(dst_h_ptr, h) do { \ - if ((h) != NULL) { \ - HostIncrUsecnt((h)); \ - *(dst_h_ptr) = h; \ - } \ - } while (0) - -#define HostDeReference(src_h_ptr) do { \ - if (*(src_h_ptr) != NULL) { \ - HostDecrUsecnt(*(src_h_ptr)); \ - *(src_h_ptr) = NULL; \ - } \ - } while (0) - -HostConfig host_config; -SC_ATOMIC_DECLARE(unsigned long long int,host_memuse); -SC_ATOMIC_DECLARE(unsigned int,host_counter); -SC_ATOMIC_DECLARE(unsigned int,host_prune_idx); - -void HostInitConfig(char quiet); -void HostShutdown(void); -void HostCleanup(void); - -Host *HostLookupHostFromHash (Address *); -Host *HostGetHostFromHash (Address *); -void HostRelease(Host *); -void HostLock(Host *); -void HostClearMemory(Host *); -void HostMoveToSpare(Host *); -uint32_t HostSpareQueueGetSize(void); -void HostPrintStats (void); - -void HostRegisterUnittests(void); - -Host *HostAlloc(); -void HostFree(); - -void HostUnlock(Host *h); - -#endif /* __HOST_H__ */ - diff --git a/framework/src/suricata/src/ippair-bit.c b/framework/src/suricata/src/ippair-bit.c deleted file mode 100644 index 0cf5c60c..00000000 --- a/framework/src/suricata/src/ippair-bit.c +++ /dev/null @@ -1,506 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements per ippair bits. Actually, not a bit, - * but called that way because of Snort's flowbits. - * It's a binary storage. - * - * \todo move away from a linked list implementation - * \todo use different datatypes, such as string, int, etc. - */ - -#include "suricata-common.h" -#include "threads.h" -#include "ippair-bit.h" -#include "ippair.h" -#include "detect.h" -#include "util-var.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "ippair-storage.h" - -static int ippair_bit_id = -1; /**< IPPair storage id for bits */ - -void XBitFreeAll(void *store) { - GenericVar *gv = store; - GenericVarFree(gv); -} - -void IPPairBitInitCtx(void) -{ - ippair_bit_id = IPPairStorageRegister("bit", sizeof(void *), NULL, XBitFreeAll); - if (ippair_bit_id == -1) { - SCLogError(SC_ERR_IPPAIR_INIT, "Can't initiate ippair storage for bits"); - exit(EXIT_FAILURE); - } -} - -/* lock before using this */ -int IPPairHasBits(IPPair *ippair) -{ - if (ippair == NULL) - return 0; - return IPPairGetStorageById(ippair, ippair_bit_id) ? 1 : 0; -} - -/** \retval 1 ippair timed out wrt xbits - * \retval 0 ippair still has active (non-expired) xbits */ -int IPPairBitsTimedoutCheck(IPPair *h, struct timeval *ts) -{ - GenericVar *gv = IPPairGetStorageById(h, ippair_bit_id); - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_XBITS) { - XBit *xb = (XBit *)gv; - if (xb->expire > (uint32_t)ts->tv_sec) - return 0; - } - } - return 1; -} - -/* get the bit with idx from the ippair */ -static XBit *IPPairBitGet(IPPair *h, uint16_t idx) -{ - GenericVar *gv = IPPairGetStorageById(h, ippair_bit_id); - for ( ; gv != NULL; gv = gv->next) { - if (gv->type == DETECT_XBITS && gv->idx == idx) { - return (XBit *)gv; - } - } - - return NULL; -} - -/* add a flowbit to the flow */ -static void IPPairBitAdd(IPPair *h, uint16_t idx, uint32_t expire) -{ - XBit *fb = IPPairBitGet(h, idx); - if (fb == NULL) { - fb = SCMalloc(sizeof(XBit)); - if (unlikely(fb == NULL)) - return; - - fb->type = DETECT_XBITS; - fb->idx = idx; - fb->next = NULL; - fb->expire = expire; - - GenericVar *gv = IPPairGetStorageById(h, ippair_bit_id); - GenericVarAppend(&gv, (GenericVar *)fb); - IPPairSetStorageById(h, ippair_bit_id, gv); - - // bit already set, lets update it's timer - } else { - fb->expire = expire; - } -} - -static void IPPairBitRemove(IPPair *h, uint16_t idx) -{ - XBit *fb = IPPairBitGet(h, idx); - if (fb == NULL) - return; - - GenericVar *gv = IPPairGetStorageById(h, ippair_bit_id); - if (gv) { - GenericVarRemove(&gv, (GenericVar *)fb); - IPPairSetStorageById(h, ippair_bit_id, gv); - } -} - -void IPPairBitSet(IPPair *h, uint16_t idx, uint32_t expire) -{ - XBit *fb = IPPairBitGet(h, idx); - if (fb == NULL) { - IPPairBitAdd(h, idx, expire); - } -} - -void IPPairBitUnset(IPPair *h, uint16_t idx) -{ - XBit *fb = IPPairBitGet(h, idx); - if (fb != NULL) { - IPPairBitRemove(h, idx); - } -} - -void IPPairBitToggle(IPPair *h, uint16_t idx, uint32_t expire) -{ - XBit *fb = IPPairBitGet(h, idx); - if (fb != NULL) { - IPPairBitRemove(h, idx); - } else { - IPPairBitAdd(h, idx, expire); - } -} - -int IPPairBitIsset(IPPair *h, uint16_t idx, uint32_t ts) -{ - XBit *fb = IPPairBitGet(h, idx); - if (fb != NULL) { - if (fb->expire < ts) { - IPPairBitRemove(h, idx); - return 0; - } - - return 1; - } - return 0; -} - -int IPPairBitIsnotset(IPPair *h, uint16_t idx, uint32_t ts) -{ - XBit *fb = IPPairBitGet(h, idx); - if (fb == NULL) { - return 1; - } - - if (fb->expire < ts) { - IPPairBitRemove(h, idx); - return 1; - } - - return 0; -} - - -/* TESTS */ -#ifdef UNITTESTS -static int IPPairBitTest01 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0, 0); - - XBit *fb = IPPairBitGet(h,0); - if (fb != NULL) - ret = 1; - - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest02 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - XBit *fb = IPPairBitGet(h,0); - if (fb == NULL) - ret = 1; - - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest03 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0, 30); - - XBit *fb = IPPairBitGet(h,0); - if (fb == NULL) { - printf("fb == NULL although it was just added: "); - goto end; - } - - IPPairBitRemove(h, 0); - - fb = IPPairBitGet(h,0); - if (fb != NULL) { - printf("fb != NULL although it was just removed: "); - goto end; - } else { - ret = 1; - } - - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest04 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0,30); - IPPairBitAdd(h, 1,30); - IPPairBitAdd(h, 2,30); - IPPairBitAdd(h, 3,30); - - XBit *fb = IPPairBitGet(h,0); - if (fb != NULL) - ret = 1; - - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest05 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0,90); - IPPairBitAdd(h, 1,90); - IPPairBitAdd(h, 2,90); - IPPairBitAdd(h, 3,90); - - XBit *fb = IPPairBitGet(h,1); - if (fb != NULL) - ret = 1; - - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest06 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0,90); - IPPairBitAdd(h, 1,90); - IPPairBitAdd(h, 2,90); - IPPairBitAdd(h, 3,90); - - XBit *fb = IPPairBitGet(h,2); - if (fb != NULL) - ret = 1; - - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest07 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0,90); - IPPairBitAdd(h, 1,90); - IPPairBitAdd(h, 2,90); - IPPairBitAdd(h, 3,90); - - XBit *fb = IPPairBitGet(h,3); - if (fb != NULL) - ret = 1; - - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest08 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0,90); - IPPairBitAdd(h, 1,90); - IPPairBitAdd(h, 2,90); - IPPairBitAdd(h, 3,90); - - XBit *fb = IPPairBitGet(h,0); - if (fb == NULL) - goto end; - - IPPairBitRemove(h,0); - - fb = IPPairBitGet(h,0); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest09 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0,90); - IPPairBitAdd(h, 1,90); - IPPairBitAdd(h, 2,90); - IPPairBitAdd(h, 3,90); - - XBit *fb = IPPairBitGet(h,1); - if (fb == NULL) - goto end; - - IPPairBitRemove(h,1); - - fb = IPPairBitGet(h,1); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest10 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0,90); - IPPairBitAdd(h, 1,90); - IPPairBitAdd(h, 2,90); - IPPairBitAdd(h, 3,90); - - XBit *fb = IPPairBitGet(h,2); - if (fb == NULL) - goto end; - - IPPairBitRemove(h,2); - - fb = IPPairBitGet(h,2); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -static int IPPairBitTest11 (void) -{ - int ret = 0; - - IPPairInitConfig(TRUE); - IPPair *h = IPPairAlloc(); - if (h == NULL) - goto end; - - IPPairBitAdd(h, 0,90); - IPPairBitAdd(h, 1,90); - IPPairBitAdd(h, 2,90); - IPPairBitAdd(h, 3,90); - - XBit *fb = IPPairBitGet(h,3); - if (fb == NULL) - goto end; - - IPPairBitRemove(h,3); - - fb = IPPairBitGet(h,3); - if (fb != NULL) { - printf("fb != NULL even though it was removed: "); - goto end; - } - - ret = 1; - IPPairFree(h); -end: - IPPairCleanup(); - return ret; -} - -#endif /* UNITTESTS */ - -void IPPairBitRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("IPPairBitTest01", IPPairBitTest01, 1); - UtRegisterTest("IPPairBitTest02", IPPairBitTest02, 1); - UtRegisterTest("IPPairBitTest03", IPPairBitTest03, 1); - UtRegisterTest("IPPairBitTest04", IPPairBitTest04, 1); - UtRegisterTest("IPPairBitTest05", IPPairBitTest05, 1); - UtRegisterTest("IPPairBitTest06", IPPairBitTest06, 1); - UtRegisterTest("IPPairBitTest07", IPPairBitTest07, 1); - UtRegisterTest("IPPairBitTest08", IPPairBitTest08, 1); - UtRegisterTest("IPPairBitTest09", IPPairBitTest09, 1); - UtRegisterTest("IPPairBitTest10", IPPairBitTest10, 1); - UtRegisterTest("IPPairBitTest11", IPPairBitTest11, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/ippair-bit.h b/framework/src/suricata/src/ippair-bit.h deleted file mode 100644 index 44a0ac46..00000000 --- a/framework/src/suricata/src/ippair-bit.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __IPPAIR_BIT_H__ -#define __IPPAIR_BIT_H__ - -#include "ippair.h" -#include "util-var.h" - -void IPPairBitInitCtx(void); -void IPPairBitRegisterTests(void); - -int IPPairHasBits(IPPair *host); -int IPPairBitsTimedoutCheck(IPPair *h, struct timeval *ts); - -void IPPairBitSet(IPPair *, uint16_t, uint32_t); -void IPPairBitUnset(IPPair *, uint16_t); -void IPPairBitToggle(IPPair *, uint16_t, uint32_t); -int IPPairBitIsset(IPPair *, uint16_t, uint32_t); -int IPPairBitIsnotset(IPPair *, uint16_t, uint32_t); - -#endif /* __IPPAIR_BIT_H__ */ diff --git a/framework/src/suricata/src/ippair-queue.c b/framework/src/suricata/src/ippair-queue.c deleted file mode 100644 index 0f68200d..00000000 --- a/framework/src/suricata/src/ippair-queue.c +++ /dev/null @@ -1,143 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * IPPair queue handler functions - */ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "ippair-queue.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-print.h" - -IPPairQueue *IPPairQueueInit (IPPairQueue *q) -{ - if (q != NULL) { - memset(q, 0, sizeof(IPPairQueue)); - HQLOCK_INIT(q); - } - return q; -} - -IPPairQueue *IPPairQueueNew() -{ - IPPairQueue *q = (IPPairQueue *)SCMalloc(sizeof(IPPairQueue)); - if (q == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in IPPairQueueNew. Exiting..."); - exit(EXIT_SUCCESS); - } - q = IPPairQueueInit(q); - return q; -} - -/** - * \brief Destroy a ippair queue - * - * \param q the ippair queue to destroy - */ -void IPPairQueueDestroy (IPPairQueue *q) -{ - HQLOCK_DESTROY(q); -} - -/** - * \brief add a ippair to a queue - * - * \param q queue - * \param h ippair - */ -void IPPairEnqueue (IPPairQueue *q, IPPair *h) -{ -#ifdef DEBUG - BUG_ON(q == NULL || h == NULL); -#endif - - HQLOCK_LOCK(q); - - /* more ippairs in queue */ - if (q->top != NULL) { - h->lnext = q->top; - q->top->lprev = h; - q->top = h; - /* only ippair */ - } else { - q->top = h; - q->bot = h; - } - q->len++; -#ifdef DBG_PERF - if (q->len > q->dbg_maxlen) - q->dbg_maxlen = q->len; -#endif /* DBG_PERF */ - HQLOCK_UNLOCK(q); -} - -/** - * \brief remove a ippair from the queue - * - * \param q queue - * - * \retval h ippair or NULL if empty list. - */ -IPPair *IPPairDequeue (IPPairQueue *q) -{ - HQLOCK_LOCK(q); - - IPPair *h = q->bot; - if (h == NULL) { - HQLOCK_UNLOCK(q); - return NULL; - } - - /* more packets in queue */ - if (q->bot->lprev != NULL) { - q->bot = q->bot->lprev; - q->bot->lnext = NULL; - /* just the one we remove, so now empty */ - } else { - q->top = NULL; - q->bot = NULL; - } - -#ifdef DEBUG - BUG_ON(q->len == 0); -#endif - if (q->len > 0) - q->len--; - - h->lnext = NULL; - h->lprev = NULL; - - HQLOCK_UNLOCK(q); - return h; -} - -uint32_t IPPairQueueLen(IPPairQueue *q) -{ - uint32_t len; - HQLOCK_LOCK(q); - len = q->len; - HQLOCK_UNLOCK(q); - return len; -} diff --git a/framework/src/suricata/src/ippair-queue.h b/framework/src/suricata/src/ippair-queue.h deleted file mode 100644 index 5c80cf39..00000000 --- a/framework/src/suricata/src/ippair-queue.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __IPPAIR_QUEUE_H__ -#define __IPPAIR_QUEUE_H__ - -#include "suricata-common.h" -#include "ippair.h" - -/** Spinlocks or Mutex for the ippair queues. */ -//#define HQLOCK_SPIN -#define HQLOCK_MUTEX - -#ifdef HQLOCK_SPIN - #ifdef HQLOCK_MUTEX - #error Cannot enable both HQLOCK_SPIN and HQLOCK_MUTEX - #endif -#endif - -/* Define a queue for storing ippairs */ -typedef struct IPPairQueue_ -{ - IPPair *top; - IPPair *bot; - uint32_t len; -#ifdef DBG_PERF - uint32_t dbg_maxlen; -#endif /* DBG_PERF */ -#ifdef HQLOCK_MUTEX - SCMutex m; -#elif defined HQLOCK_SPIN - SCSpinlock s; -#else - #error Enable HQLOCK_SPIN or HQLOCK_MUTEX -#endif -} IPPairQueue; - -#ifdef HQLOCK_SPIN - #define HQLOCK_INIT(q) SCSpinInit(&(q)->s, 0) - #define HQLOCK_DESTROY(q) SCSpinDestroy(&(q)->s) - #define HQLOCK_LOCK(q) SCSpinLock(&(q)->s) - #define HQLOCK_TRYLOCK(q) SCSpinTrylock(&(q)->s) - #define HQLOCK_UNLOCK(q) SCSpinUnlock(&(q)->s) -#elif defined HQLOCK_MUTEX - #define HQLOCK_INIT(q) SCMutexInit(&(q)->m, NULL) - #define HQLOCK_DESTROY(q) SCMutexDestroy(&(q)->m) - #define HQLOCK_LOCK(q) SCMutexLock(&(q)->m) - #define HQLOCK_TRYLOCK(q) SCMutexTrylock(&(q)->m) - #define HQLOCK_UNLOCK(q) SCMutexUnlock(&(q)->m) -#else - #error Enable HQLOCK_SPIN or HQLOCK_MUTEX -#endif - -/* prototypes */ -IPPairQueue *IPPairQueueNew(); -IPPairQueue *IPPairQueueInit(IPPairQueue *); -void IPPairQueueDestroy (IPPairQueue *); - -void IPPairEnqueue (IPPairQueue *, IPPair *); -IPPair *IPPairDequeue (IPPairQueue *); -uint32_t IPPairQueueLen(IPPairQueue *); - -#endif /* __IPPAIR_QUEUE_H__ */ diff --git a/framework/src/suricata/src/ippair-storage.c b/framework/src/suricata/src/ippair-storage.c deleted file mode 100644 index dddc7136..00000000 --- a/framework/src/suricata/src/ippair-storage.c +++ /dev/null @@ -1,299 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * IPPair wrapper around storage api - */ - -#include "suricata-common.h" -#include "ippair-storage.h" -#include "util-unittest.h" - -unsigned int IPPairStorageSize(void) -{ - return StorageGetSize(STORAGE_IPPAIR); -} - -void *IPPairGetStorageById(IPPair *h, int id) -{ - return StorageGetById((Storage *)((void *)h + sizeof(IPPair)), STORAGE_IPPAIR, id); -} - -int IPPairSetStorageById(IPPair *h, int id, void *ptr) -{ - return StorageSetById((Storage *)((void *)h + sizeof(IPPair)), STORAGE_IPPAIR, id, ptr); -} - -void *IPPairAllocStorageById(IPPair *h, int id) -{ - return StorageAllocByIdPrealloc((Storage *)((void *)h + sizeof(IPPair)), STORAGE_IPPAIR, id); -} - -void IPPairFreeStorageById(IPPair *h, int id) -{ - StorageFreeById((Storage *)((void *)h + sizeof(IPPair)), STORAGE_IPPAIR, id); -} - -void IPPairFreeStorage(IPPair *h) -{ - if (IPPairStorageSize() > 0) - StorageFreeAll((Storage *)((void *)h + sizeof(IPPair)), STORAGE_IPPAIR); -} - -int IPPairStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)) { - return StorageRegister(STORAGE_IPPAIR, name, size, Alloc, Free); -} - -#ifdef UNITTESTS - -static void *StorageTestAlloc(unsigned int size) -{ - void *x = SCMalloc(size); - return x; -} -static void StorageTestFree(void *x) -{ - if (x) - SCFree(x); -} - -static int IPPairStorageTest01(void) -{ - StorageInit(); - - int id1 = IPPairStorageRegister("test", 8, StorageTestAlloc, StorageTestFree); - if (id1 < 0) - goto error; - int id2 = IPPairStorageRegister("variable", 24, StorageTestAlloc, StorageTestFree); - if (id2 < 0) - goto error; - int id3 = IPPairStorageRegister("store", sizeof(void *), StorageTestAlloc, StorageTestFree); - if (id3 < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - IPPairInitConfig(1); - - Address a, b; - memset(&a, 0x00, sizeof(a)); - memset(&b, 0x00, sizeof(b)); - a.addr_data32[0] = 0x01020304; - b.addr_data32[0] = 0x04030201; - a.family = AF_INET; - b.family = AF_INET; - IPPair *h = IPPairGetIPPairFromHash(&a, &b); - if (h == NULL) { - printf("failed to get ippair: "); - goto error; - } - - void *ptr = IPPairGetStorageById(h, id1); - if (ptr != NULL) { - goto error; - } - ptr = IPPairGetStorageById(h, id2); - if (ptr != NULL) { - goto error; - } - ptr = IPPairGetStorageById(h, id3); - if (ptr != NULL) { - goto error; - } - - void *ptr1a = IPPairAllocStorageById(h, id1); - if (ptr1a == NULL) { - goto error; - } - void *ptr2a = IPPairAllocStorageById(h, id2); - if (ptr2a == NULL) { - goto error; - } - void *ptr3a = IPPairAllocStorageById(h, id3); - if (ptr3a == NULL) { - goto error; - } - - void *ptr1b = IPPairGetStorageById(h, id1); - if (ptr1a != ptr1b) { - goto error; - } - void *ptr2b = IPPairGetStorageById(h, id2); - if (ptr2a != ptr2b) { - goto error; - } - void *ptr3b = IPPairGetStorageById(h, id3); - if (ptr3a != ptr3b) { - goto error; - } - - IPPairRelease(h); - - IPPairShutdown(); - StorageCleanup(); - return 1; -error: - IPPairShutdown(); - StorageCleanup(); - return 0; -} - -static int IPPairStorageTest02(void) -{ - StorageInit(); - - int id1 = IPPairStorageRegister("test", sizeof(void *), NULL, StorageTestFree); - if (id1 < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - IPPairInitConfig(1); - - Address a, b; - memset(&a, 0x00, sizeof(a)); - memset(&b, 0x00, sizeof(b)); - a.addr_data32[0] = 0x01020304; - b.addr_data32[0] = 0x04030201; - a.family = AF_INET; - b.family = AF_INET; - IPPair *h = IPPairGetIPPairFromHash(&a, &b); - if (h == NULL) { - printf("failed to get ippair: "); - goto error; - } - - void *ptr = IPPairGetStorageById(h, id1); - if (ptr != NULL) { - goto error; - } - - void *ptr1a = SCMalloc(128); - if (unlikely(ptr1a == NULL)) { - goto error; - } - IPPairSetStorageById(h, id1, ptr1a); - - void *ptr1b = IPPairGetStorageById(h, id1); - if (ptr1a != ptr1b) { - goto error; - } - - IPPairRelease(h); - - IPPairShutdown(); - StorageCleanup(); - return 1; -error: - IPPairShutdown(); - StorageCleanup(); - return 0; -} - -static int IPPairStorageTest03(void) -{ - StorageInit(); - - int id1 = IPPairStorageRegister("test1", sizeof(void *), NULL, StorageTestFree); - if (id1 < 0) - goto error; - int id2 = IPPairStorageRegister("test2", sizeof(void *), NULL, StorageTestFree); - if (id2 < 0) - goto error; - int id3 = IPPairStorageRegister("test3", 32, StorageTestAlloc, StorageTestFree); - if (id3 < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - IPPairInitConfig(1); - - Address a, b; - memset(&a, 0x00, sizeof(a)); - memset(&b, 0x00, sizeof(b)); - a.addr_data32[0] = 0x01020304; - b.addr_data32[0] = 0x04030201; - a.family = AF_INET; - b.family = AF_INET; - IPPair *h = IPPairGetIPPairFromHash(&a, &b); - if (h == NULL) { - printf("failed to get ippair: "); - goto error; - } - - void *ptr = IPPairGetStorageById(h, id1); - if (ptr != NULL) { - goto error; - } - - void *ptr1a = SCMalloc(128); - if (unlikely(ptr1a == NULL)) { - goto error; - } - IPPairSetStorageById(h, id1, ptr1a); - - void *ptr2a = SCMalloc(256); - if (unlikely(ptr2a == NULL)) { - goto error; - } - IPPairSetStorageById(h, id2, ptr2a); - - void *ptr3a = IPPairAllocStorageById(h, id3); - if (ptr3a == NULL) { - goto error; - } - - void *ptr1b = IPPairGetStorageById(h, id1); - if (ptr1a != ptr1b) { - goto error; - } - void *ptr2b = IPPairGetStorageById(h, id2); - if (ptr2a != ptr2b) { - goto error; - } - void *ptr3b = IPPairGetStorageById(h, id3); - if (ptr3a != ptr3b) { - goto error; - } - - IPPairRelease(h); - - IPPairShutdown(); - StorageCleanup(); - return 1; -error: - IPPairShutdown(); - StorageCleanup(); - return 0; -} -#endif - -void RegisterIPPairStorageTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("IPPairStorageTest01", IPPairStorageTest01, 1); - UtRegisterTest("IPPairStorageTest02", IPPairStorageTest02, 1); - UtRegisterTest("IPPairStorageTest03", IPPairStorageTest03, 1); -#endif -} diff --git a/framework/src/suricata/src/ippair-storage.h b/framework/src/suricata/src/ippair-storage.h deleted file mode 100644 index 0671ac91..00000000 --- a/framework/src/suricata/src/ippair-storage.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * IPPair wrapper around storage api - */ - -#ifndef __IPPAIR_STORAGE_H__ -#define __IPPAIR_STORAGE_H__ - -#include "util-storage.h" -#include "ippair.h" - -unsigned int IPPairStorageSize(void); - -void *IPPairGetStorageById(IPPair *h, int id); -int IPPairSetStorageById(IPPair *h, int id, void *ptr); -void *IPPairAllocStorageById(IPPair *h, int id); - -void IPPairFreeStorageById(IPPair *h, int id); -void IPPairFreeStorage(IPPair *h); - -void RegisterIPPairStorageTests(void); - -int IPPairStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)); - -#endif /* __IPPAIR_STORAGE_H__ */ diff --git a/framework/src/suricata/src/ippair-timeout.c b/framework/src/suricata/src/ippair-timeout.c deleted file mode 100644 index 1225f825..00000000 --- a/framework/src/suricata/src/ippair-timeout.c +++ /dev/null @@ -1,159 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "ippair.h" -#include "ippair-bit.h" - -uint32_t IPPairGetSpareCount(void) -{ - return IPPairSpareQueueGetSize(); -} - -uint32_t IPPairGetActiveCount(void) -{ - return SC_ATOMIC_GET(ippair_counter); -} - -/** \internal - * \brief See if we can really discard this ippair. Check use_cnt reference. - * - * \param h ippair - * \param ts timestamp - * - * \retval 0 not timed out just yet - * \retval 1 fully timed out, lets kill it - */ -static int IPPairTimedOut(IPPair *h, struct timeval *ts) -{ - int vars = 0; - - /** never prune a ippair that is used by a packet - * we are currently processing in one of the threads */ - if (SC_ATOMIC_GET(h->use_cnt) > 0) { - return 0; - } - - if (IPPairHasBits(h) && IPPairBitsTimedoutCheck(h, ts) == 0) { - vars = 1; - } - - if (vars) { - return 0; - } - - SCLogDebug("ippair %p timed out", h); - return 1; -} - -/** - * \internal - * - * \brief check all ippairs in a hash row for timing out - * - * \param hb ippair hash row *LOCKED* - * \param h last ippair in the hash row - * \param ts timestamp - * - * \retval cnt timed out ippairs - */ -static uint32_t IPPairHashRowTimeout(IPPairHashRow *hb, IPPair *h, struct timeval *ts) -{ - uint32_t cnt = 0; - - do { - if (SCMutexTrylock(&h->m) != 0) { - h = h->hprev; - continue; - } - - IPPair *next_ippair = h->hprev; - - /* check if the ippair is fully timed out and - * ready to be discarded. */ - if (IPPairTimedOut(h, ts) == 1) { - /* remove from the hash */ - if (h->hprev != NULL) - h->hprev->hnext = h->hnext; - if (h->hnext != NULL) - h->hnext->hprev = h->hprev; - if (hb->head == h) - hb->head = h->hnext; - if (hb->tail == h) - hb->tail = h->hprev; - - h->hnext = NULL; - h->hprev = NULL; - - IPPairClearMemory (h); - - /* no one is referring to this ippair, use_cnt 0, removed from hash - * so we can unlock it and move it back to the spare queue. */ - SCMutexUnlock(&h->m); - - /* move to spare list */ - IPPairMoveToSpare(h); - - cnt++; - } else { - SCMutexUnlock(&h->m); - } - - h = next_ippair; - } while (h != NULL); - - return cnt; -} - -/** - * \brief time out ippairs from the hash - * - * \param ts timestamp - * - * \retval cnt number of timed out ippair - */ -uint32_t IPPairTimeoutHash(struct timeval *ts) -{ - uint32_t idx = 0; - uint32_t cnt = 0; - - for (idx = 0; idx < ippair_config.hash_size; idx++) { - IPPairHashRow *hb = &ippair_hash[idx]; - - if (HRLOCK_TRYLOCK(hb) != 0) - continue; - - /* ippair hash bucket is now locked */ - - if (hb->tail == NULL) { - HRLOCK_UNLOCK(hb); - continue; - } - - /* we have a ippair, or more than one */ - cnt += IPPairHashRowTimeout(hb, hb->tail, ts); - HRLOCK_UNLOCK(hb); - } - - return cnt; -} diff --git a/framework/src/suricata/src/ippair-timeout.h b/framework/src/suricata/src/ippair-timeout.h deleted file mode 100644 index 15d8e96a..00000000 --- a/framework/src/suricata/src/ippair-timeout.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __IPPAIR_TIMEOUT_H__ -#define __IPPAIR_TIMEOUT_H__ - -uint32_t IPPairTimeoutHash(struct timeval *ts); - -uint32_t IPPairGetSpareCount(void); -uint32_t IPPairGetActiveCount(void); - -#endif diff --git a/framework/src/suricata/src/ippair.c b/framework/src/suricata/src/ippair.c deleted file mode 100644 index 79ecb76c..00000000 --- a/framework/src/suricata/src/ippair.c +++ /dev/null @@ -1,691 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Information about ippairs. - */ - -#include "suricata-common.h" -#include "conf.h" - -#include "util-debug.h" -#include "ippair.h" -#include "ippair-storage.h" - -#include "util-random.h" -#include "util-misc.h" -#include "util-byte.h" - -#include "ippair-queue.h" - -#include "detect-tag.h" -#include "detect-engine-tag.h" -#include "detect-engine-threshold.h" - -#include "util-hash-lookup3.h" - -static IPPair *IPPairGetUsedIPPair(void); - -/** queue with spare ippairs */ -static IPPairQueue ippair_spare_q; - -/** size of the ippair object. Maybe updated in IPPairInitConfig to include - * the storage APIs additions. */ -static uint16_t g_ippair_size = sizeof(IPPair); - -uint32_t IPPairSpareQueueGetSize(void) -{ - return IPPairQueueLen(&ippair_spare_q); -} - -void IPPairMoveToSpare(IPPair *h) -{ - IPPairEnqueue(&ippair_spare_q, h); - (void) SC_ATOMIC_SUB(ippair_counter, 1); -} - -IPPair *IPPairAlloc(void) -{ - if (!(IPPAIR_CHECK_MEMCAP(g_ippair_size))) { - return NULL; - } - - (void) SC_ATOMIC_ADD(ippair_memuse, g_ippair_size); - - IPPair *h = SCMalloc(g_ippair_size); - if (unlikely(h == NULL)) - goto error; - - memset(h, 0x00, g_ippair_size); - - SCMutexInit(&h->m, NULL); - SC_ATOMIC_INIT(h->use_cnt); - return h; - -error: - return NULL; -} - -void IPPairFree(IPPair *h) -{ - if (h != NULL) { - IPPairClearMemory(h); - - SC_ATOMIC_DESTROY(h->use_cnt); - SCMutexDestroy(&h->m); - SCFree(h); - (void) SC_ATOMIC_SUB(ippair_memuse, g_ippair_size); - } -} - -IPPair *IPPairNew(Address *a, Address *b) -{ - IPPair *p = IPPairAlloc(); - if (p == NULL) - goto error; - - /* copy addresses */ - COPY_ADDRESS(a, &p->a[0]); - COPY_ADDRESS(b, &p->a[1]); - - return p; - -error: - return NULL; -} - -void IPPairClearMemory(IPPair *h) -{ - if (IPPairStorageSize() > 0) - IPPairFreeStorage(h); -} - -#define IPPAIR_DEFAULT_HASHSIZE 4096 -#define IPPAIR_DEFAULT_MEMCAP 16777216 -#define IPPAIR_DEFAULT_PREALLOC 1000 - -/** \brief initialize the configuration - * \warning Not thread safe */ -void IPPairInitConfig(char quiet) -{ - SCLogDebug("initializing ippair engine..."); - if (IPPairStorageSize() > 0) - g_ippair_size = sizeof(IPPair) + IPPairStorageSize(); - - memset(&ippair_config, 0, sizeof(ippair_config)); - //SC_ATOMIC_INIT(flow_flags); - SC_ATOMIC_INIT(ippair_counter); - SC_ATOMIC_INIT(ippair_memuse); - SC_ATOMIC_INIT(ippair_prune_idx); - IPPairQueueInit(&ippair_spare_q); - - unsigned int seed = RandomTimePreseed(); - /* set defaults */ - ippair_config.hash_rand = (int)( IPPAIR_DEFAULT_HASHSIZE * (rand_r(&seed) / RAND_MAX + 1.0)); - - ippair_config.hash_size = IPPAIR_DEFAULT_HASHSIZE; - ippair_config.memcap = IPPAIR_DEFAULT_MEMCAP; - ippair_config.prealloc = IPPAIR_DEFAULT_PREALLOC; - - /* Check if we have memcap and hash_size defined at config */ - char *conf_val; - uint32_t configval = 0; - - /** set config values for memcap, prealloc and hash_size */ - if ((ConfGet("ippair.memcap", &conf_val)) == 1) - { - if (ParseSizeStringU64(conf_val, &ippair_config.memcap) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing ippair.memcap " - "from conf file - %s. Killing engine", - conf_val); - exit(EXIT_FAILURE); - } - } - if ((ConfGet("ippair.hash-size", &conf_val)) == 1) - { - if (ByteExtractStringUint32(&configval, 10, strlen(conf_val), - conf_val) > 0) { - ippair_config.hash_size = configval; - } - } - - if ((ConfGet("ippair.prealloc", &conf_val)) == 1) - { - if (ByteExtractStringUint32(&configval, 10, strlen(conf_val), - conf_val) > 0) { - ippair_config.prealloc = configval; - } else { - WarnInvalidConfEntry("ippair.prealloc", "%"PRIu32, ippair_config.prealloc); - } - } - SCLogDebug("IPPair config from suricata.yaml: memcap: %"PRIu64", hash-size: " - "%"PRIu32", prealloc: %"PRIu32, ippair_config.memcap, - ippair_config.hash_size, ippair_config.prealloc); - - /* alloc hash memory */ - uint64_t hash_size = ippair_config.hash_size * sizeof(IPPairHashRow); - if (!(IPPAIR_CHECK_MEMCAP(hash_size))) { - SCLogError(SC_ERR_IPPAIR_INIT, "allocating ippair hash failed: " - "max ippair memcap is smaller than projected hash size. " - "Memcap: %"PRIu64", Hash table size %"PRIu64". Calculate " - "total hash size by multiplying \"ippair.hash-size\" with %"PRIuMAX", " - "which is the hash bucket size.", ippair_config.memcap, hash_size, - (uintmax_t)sizeof(IPPairHashRow)); - exit(EXIT_FAILURE); - } - ippair_hash = SCCalloc(ippair_config.hash_size, sizeof(IPPairHashRow)); - if (unlikely(ippair_hash == NULL)) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in IPPairInitConfig. Exiting..."); - exit(EXIT_FAILURE); - } - memset(ippair_hash, 0, ippair_config.hash_size * sizeof(IPPairHashRow)); - - uint32_t i = 0; - for (i = 0; i < ippair_config.hash_size; i++) { - HRLOCK_INIT(&ippair_hash[i]); - } - (void) SC_ATOMIC_ADD(ippair_memuse, (ippair_config.hash_size * sizeof(IPPairHashRow))); - - if (quiet == FALSE) { - SCLogInfo("allocated %llu bytes of memory for the ippair hash... " - "%" PRIu32 " buckets of size %" PRIuMAX "", - SC_ATOMIC_GET(ippair_memuse), ippair_config.hash_size, - (uintmax_t)sizeof(IPPairHashRow)); - } - - /* pre allocate ippairs */ - for (i = 0; i < ippair_config.prealloc; i++) { - if (!(IPPAIR_CHECK_MEMCAP(g_ippair_size))) { - SCLogError(SC_ERR_IPPAIR_INIT, "preallocating ippairs failed: " - "max ippair memcap reached. Memcap %"PRIu64", " - "Memuse %"PRIu64".", ippair_config.memcap, - ((uint64_t)SC_ATOMIC_GET(ippair_memuse) + g_ippair_size)); - exit(EXIT_FAILURE); - } - - IPPair *h = IPPairAlloc(); - if (h == NULL) { - SCLogError(SC_ERR_IPPAIR_INIT, "preallocating ippair failed: %s", strerror(errno)); - exit(EXIT_FAILURE); - } - IPPairEnqueue(&ippair_spare_q,h); - } - - if (quiet == FALSE) { - SCLogInfo("preallocated %" PRIu32 " ippairs of size %" PRIu16 "", - ippair_spare_q.len, g_ippair_size); - SCLogInfo("ippair memory usage: %llu bytes, maximum: %"PRIu64, - SC_ATOMIC_GET(ippair_memuse), ippair_config.memcap); - } - - return; -} - -/** \brief print some ippair stats - * \warning Not thread safe */ -void IPPairPrintStats (void) -{ -#ifdef IPPAIRBITS_STATS - SCLogInfo("ippairbits added: %" PRIu32 ", removed: %" PRIu32 ", max memory usage: %" PRIu32 "", - ippairbits_added, ippairbits_removed, ippairbits_memuse_max); -#endif /* IPPAIRBITS_STATS */ - SCLogInfo("ippair memory usage: %llu bytes, maximum: %"PRIu64, - SC_ATOMIC_GET(ippair_memuse), ippair_config.memcap); - return; -} - -/** \brief shutdown the flow engine - * \warning Not thread safe */ -void IPPairShutdown(void) -{ - IPPair *h; - uint32_t u; - - IPPairPrintStats(); - - /* free spare queue */ - while((h = IPPairDequeue(&ippair_spare_q))) { - BUG_ON(SC_ATOMIC_GET(h->use_cnt) > 0); - IPPairFree(h); - } - - /* clear and free the hash */ - if (ippair_hash != NULL) { - for (u = 0; u < ippair_config.hash_size; u++) { - IPPair *h = ippair_hash[u].head; - while (h) { - IPPair *n = h->hnext; - IPPairFree(h); - h = n; - } - - HRLOCK_DESTROY(&ippair_hash[u]); - } - SCFree(ippair_hash); - ippair_hash = NULL; - } - (void) SC_ATOMIC_SUB(ippair_memuse, ippair_config.hash_size * sizeof(IPPairHashRow)); - IPPairQueueDestroy(&ippair_spare_q); - - SC_ATOMIC_DESTROY(ippair_prune_idx); - SC_ATOMIC_DESTROY(ippair_memuse); - SC_ATOMIC_DESTROY(ippair_counter); - //SC_ATOMIC_DESTROY(flow_flags); - return; -} - -/** \brief Cleanup the ippair engine - * - * Cleanup the ippair engine from tag and threshold. - * - */ -void IPPairCleanup(void) -{ - IPPair *h; - uint32_t u; - - if (ippair_hash != NULL) { - for (u = 0; u < ippair_config.hash_size; u++) { - h = ippair_hash[u].head; - IPPairHashRow *hb = &ippair_hash[u]; - HRLOCK_LOCK(hb); - while (h) { - if ((SC_ATOMIC_GET(h->use_cnt) > 0)) { - /* iprep is attached to ippair only clear local storage */ - IPPairFreeStorage(h); - h = h->hnext; - } else { - IPPair *n = h->hnext; - /* remove from the hash */ - if (h->hprev != NULL) - h->hprev->hnext = h->hnext; - if (h->hnext != NULL) - h->hnext->hprev = h->hprev; - if (hb->head == h) - hb->head = h->hnext; - if (hb->tail == h) - hb->tail = h->hprev; - h->hnext = NULL; - h->hprev = NULL; - IPPairClearMemory(h); - IPPairMoveToSpare(h); - h = n; - } - } - HRLOCK_UNLOCK(hb); - } - } - - return; -} - -/* calculate the hash key for this packet - * - * we're using: - * hash_rand -- set at init time - * source address - */ -static uint32_t IPPairGetKey(Address *a, Address *b) -{ - uint32_t key; - - if (a->family == AF_INET) { - uint32_t hash = hashword(&a->addr_data32[0], 1, ippair_config.hash_rand); - key = hash % ippair_config.hash_size; - } else if (a->family == AF_INET6) { - uint32_t hash = hashword(a->addr_data32, 4, ippair_config.hash_rand); - key = hash % ippair_config.hash_size; - } else - key = 0; - - return key; -} - -/* Since two or more ippairs can have the same hash key, we need to compare - * the ippair with the current addresses. */ -static inline int IPPairCompare(IPPair *p, Address *a, Address *b) -{ - /* compare in both directions */ - if ((CMP_ADDR(&p->a[0], a) && CMP_ADDR(&p->a[1], b)) || - (CMP_ADDR(&p->a[0], b) && CMP_ADDR(&p->a[1], a))) - return 1; - return 0; -} - -/** - * \brief Get a new ippair - * - * Get a new ippair. We're checking memcap first and will try to make room - * if the memcap is reached. - * - * \retval h *LOCKED* ippair on succes, NULL on error. - */ -static IPPair *IPPairGetNew(Address *a, Address *b) -{ - IPPair *h = NULL; - - /* get a ippair from the spare queue */ - h = IPPairDequeue(&ippair_spare_q); - if (h == NULL) { - /* If we reached the max memcap, we get a used ippair */ - if (!(IPPAIR_CHECK_MEMCAP(g_ippair_size))) { - /* declare state of emergency */ - //if (!(SC_ATOMIC_GET(ippair_flags) & IPPAIR_EMERGENCY)) { - // SC_ATOMIC_OR(ippair_flags, IPPAIR_EMERGENCY); - - /* under high load, waking up the flow mgr each time leads - * to high cpu usage. Flows are not timed out much faster if - * we check a 1000 times a second. */ - // FlowWakeupFlowManagerThread(); - //} - - h = IPPairGetUsedIPPair(); - if (h == NULL) { - return NULL; - } - - /* freed a ippair, but it's unlocked */ - } else { - /* now see if we can alloc a new ippair */ - h = IPPairNew(a,b); - if (h == NULL) { - return NULL; - } - - /* ippair is initialized but *unlocked* */ - } - } else { - /* ippair has been recycled before it went into the spare queue */ - - /* ippair is initialized (recylced) but *unlocked* */ - } - - (void) SC_ATOMIC_ADD(ippair_counter, 1); - SCMutexLock(&h->m); - return h; -} - -void IPPairInit(IPPair *h, Address *a, Address *b) -{ - COPY_ADDRESS(a, &h->a[0]); - COPY_ADDRESS(b, &h->a[1]); - (void) IPPairIncrUsecnt(h); -} - -void IPPairRelease(IPPair *h) -{ - (void) IPPairDecrUsecnt(h); - SCMutexUnlock(&h->m); -} - -void IPPairLock(IPPair *h) -{ - SCMutexLock(&h->m); -} - -void IPPairUnlock(IPPair *h) -{ - SCMutexUnlock(&h->m); -} - -/* IPPairGetIPPairFromHash - * - * Hash retrieval function for ippairs. Looks up the hash bucket containing the - * ippair pointer. Then compares the packet with the found ippair to see if it is - * the ippair we need. If it isn't, walk the list until the right ippair is found. - * - * returns a *LOCKED* ippair or NULL - */ -IPPair *IPPairGetIPPairFromHash (Address *a, Address *b) -{ - IPPair *h = NULL; - - /* get the key to our bucket */ - uint32_t key = IPPairGetKey(a, b); - /* get our hash bucket and lock it */ - IPPairHashRow *hb = &ippair_hash[key]; - HRLOCK_LOCK(hb); - - /* see if the bucket already has a ippair */ - if (hb->head == NULL) { - h = IPPairGetNew(a,b); - if (h == NULL) { - HRLOCK_UNLOCK(hb); - return NULL; - } - - /* ippair is locked */ - hb->head = h; - hb->tail = h; - - /* got one, now lock, initialize and return */ - IPPairInit(h,a,b); - - HRLOCK_UNLOCK(hb); - return h; - } - - /* ok, we have a ippair in the bucket. Let's find out if it is our ippair */ - h = hb->head; - - /* see if this is the ippair we are looking for */ - if (IPPairCompare(h, a, b) == 0) { - IPPair *ph = NULL; /* previous ippair */ - - while (h) { - ph = h; - h = h->hnext; - - if (h == NULL) { - h = ph->hnext = IPPairGetNew(a,b); - if (h == NULL) { - HRLOCK_UNLOCK(hb); - return NULL; - } - hb->tail = h; - - /* ippair is locked */ - - h->hprev = ph; - - /* initialize and return */ - IPPairInit(h,a,b); - - HRLOCK_UNLOCK(hb); - return h; - } - - if (IPPairCompare(h, a, b) != 0) { - /* we found our ippair, lets put it on top of the - * hash list -- this rewards active ippairs */ - if (h->hnext) { - h->hnext->hprev = h->hprev; - } - if (h->hprev) { - h->hprev->hnext = h->hnext; - } - if (h == hb->tail) { - hb->tail = h->hprev; - } - - h->hnext = hb->head; - h->hprev = NULL; - hb->head->hprev = h; - hb->head = h; - - /* found our ippair, lock & return */ - SCMutexLock(&h->m); - (void) IPPairIncrUsecnt(h); - HRLOCK_UNLOCK(hb); - return h; - } - } - } - - /* lock & return */ - SCMutexLock(&h->m); - (void) IPPairIncrUsecnt(h); - HRLOCK_UNLOCK(hb); - return h; -} - -/** \brief look up a ippair in the hash - * - * \param a address to look up - * - * \retval h *LOCKED* ippair or NULL - */ -IPPair *IPPairLookupIPPairFromHash (Address *a, Address *b) -{ - IPPair *h = NULL; - - /* get the key to our bucket */ - uint32_t key = IPPairGetKey(a, b); - /* get our hash bucket and lock it */ - IPPairHashRow *hb = &ippair_hash[key]; - HRLOCK_LOCK(hb); - - /* see if the bucket already has a ippair */ - if (hb->head == NULL) { - HRLOCK_UNLOCK(hb); - return h; - } - - /* ok, we have a ippair in the bucket. Let's find out if it is our ippair */ - h = hb->head; - - /* see if this is the ippair we are looking for */ - if (IPPairCompare(h, a, b) == 0) { - while (h) { - h = h->hnext; - - if (h == NULL) { - HRLOCK_UNLOCK(hb); - return h; - } - - if (IPPairCompare(h, a, b) != 0) { - /* we found our ippair, lets put it on top of the - * hash list -- this rewards active ippairs */ - if (h->hnext) { - h->hnext->hprev = h->hprev; - } - if (h->hprev) { - h->hprev->hnext = h->hnext; - } - if (h == hb->tail) { - hb->tail = h->hprev; - } - - h->hnext = hb->head; - h->hprev = NULL; - hb->head->hprev = h; - hb->head = h; - - /* found our ippair, lock & return */ - SCMutexLock(&h->m); - (void) IPPairIncrUsecnt(h); - HRLOCK_UNLOCK(hb); - return h; - } - } - } - - /* lock & return */ - SCMutexLock(&h->m); - (void) IPPairIncrUsecnt(h); - HRLOCK_UNLOCK(hb); - return h; -} - -/** \internal - * \brief Get a ippair from the hash directly. - * - * Called in conditions where the spare queue is empty and memcap is reached. - * - * Walks the hash until a ippair can be freed. "ippair_prune_idx" atomic int makes - * sure we don't start at the top each time since that would clear the top of - * the hash leading to longer and longer search times under high pressure (observed). - * - * \retval h ippair or NULL - */ -static IPPair *IPPairGetUsedIPPair(void) -{ - uint32_t idx = SC_ATOMIC_GET(ippair_prune_idx) % ippair_config.hash_size; - uint32_t cnt = ippair_config.hash_size; - - while (cnt--) { - if (++idx >= ippair_config.hash_size) - idx = 0; - - IPPairHashRow *hb = &ippair_hash[idx]; - - if (HRLOCK_TRYLOCK(hb) != 0) - continue; - - IPPair *h = hb->tail; - if (h == NULL) { - HRLOCK_UNLOCK(hb); - continue; - } - - if (SCMutexTrylock(&h->m) != 0) { - HRLOCK_UNLOCK(hb); - continue; - } - - /** never prune a ippair that is used by a packets - * we are currently processing in one of the threads */ - if (SC_ATOMIC_GET(h->use_cnt) > 0) { - HRLOCK_UNLOCK(hb); - SCMutexUnlock(&h->m); - continue; - } - - /* remove from the hash */ - if (h->hprev != NULL) - h->hprev->hnext = h->hnext; - if (h->hnext != NULL) - h->hnext->hprev = h->hprev; - if (hb->head == h) - hb->head = h->hnext; - if (hb->tail == h) - hb->tail = h->hprev; - - h->hnext = NULL; - h->hprev = NULL; - HRLOCK_UNLOCK(hb); - - IPPairClearMemory (h); - - SCMutexUnlock(&h->m); - - (void) SC_ATOMIC_ADD(ippair_prune_idx, (ippair_config.hash_size - cnt)); - return h; - } - - return NULL; -} - -void IPPairRegisterUnittests(void) -{ - RegisterIPPairStorageTests(); -} diff --git a/framework/src/suricata/src/ippair.h b/framework/src/suricata/src/ippair.h deleted file mode 100644 index 79affc62..00000000 --- a/framework/src/suricata/src/ippair.h +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __IPPAIR_H__ -#define __IPPAIR_H__ - -#include "decode.h" -#include "util-storage.h" - -/** Spinlocks or Mutex for the flow buckets. */ -//#define HRLOCK_SPIN -#define HRLOCK_MUTEX - -#ifdef HRLOCK_SPIN - #ifdef HRLOCK_MUTEX - #error Cannot enable both HRLOCK_SPIN and HRLOCK_MUTEX - #endif -#endif - -#ifdef HRLOCK_SPIN - #define HRLOCK_TYPE SCSpinlock - #define HRLOCK_INIT(fb) SCSpinInit(&(fb)->lock, 0) - #define HRLOCK_DESTROY(fb) SCSpinDestroy(&(fb)->lock) - #define HRLOCK_LOCK(fb) SCSpinLock(&(fb)->lock) - #define HRLOCK_TRYLOCK(fb) SCSpinTrylock(&(fb)->lock) - #define HRLOCK_UNLOCK(fb) SCSpinUnlock(&(fb)->lock) -#elif defined HRLOCK_MUTEX - #define HRLOCK_TYPE SCMutex - #define HRLOCK_INIT(fb) SCMutexInit(&(fb)->lock, NULL) - #define HRLOCK_DESTROY(fb) SCMutexDestroy(&(fb)->lock) - #define HRLOCK_LOCK(fb) SCMutexLock(&(fb)->lock) - #define HRLOCK_TRYLOCK(fb) SCMutexTrylock(&(fb)->lock) - #define HRLOCK_UNLOCK(fb) SCMutexUnlock(&(fb)->lock) -#else - #error Enable HRLOCK_SPIN or HRLOCK_MUTEX -#endif - -typedef struct IPPair_ { - /** ippair mutex */ - SCMutex m; - - /** ippair addresses -- ipv4 or ipv6 */ - Address a[2]; - - /** use cnt, reference counter */ - SC_ATOMIC_DECLARE(unsigned int, use_cnt); - - /** storage api handle */ - Storage *storage; - - /** hash pointers, protected by hash row mutex/spin */ - struct IPPair_ *hnext; - struct IPPair_ *hprev; - - /** list pointers, protected by ippair-queue mutex/spin */ - struct IPPair_ *lnext; - struct IPPair_ *lprev; -} IPPair; - -typedef struct IPPairHashRow_ { - HRLOCK_TYPE lock; - IPPair *head; - IPPair *tail; -} __attribute__((aligned(CLS))) IPPairHashRow; - -/** ippair hash table */ -IPPairHashRow *ippair_hash; - -#define IPPAIR_VERBOSE 0 -#define IPPAIR_QUIET 1 - -typedef struct IPPairConfig_ { - uint64_t memcap; - uint32_t hash_rand; - uint32_t hash_size; - uint32_t prealloc; -} IPPairConfig; - -/** \brief check if a memory alloc would fit in the memcap - * - * \param size memory allocation size to check - * - * \retval 1 it fits - * \retval 0 no fit - */ -#define IPPAIR_CHECK_MEMCAP(size) \ - ((((uint64_t)SC_ATOMIC_GET(ippair_memuse) + (uint64_t)(size)) <= ippair_config.memcap)) - -#define IPPairIncrUsecnt(h) \ - (void)SC_ATOMIC_ADD((h)->use_cnt, 1) -#define IPPairDecrUsecnt(h) \ - (void)SC_ATOMIC_SUB((h)->use_cnt, 1) - -#define IPPairReference(dst_h_ptr, h) do { \ - if ((h) != NULL) { \ - IPPairIncrUsecnt((h)); \ - *(dst_h_ptr) = h; \ - } \ - } while (0) - -#define IPPairDeReference(src_h_ptr) do { \ - if (*(src_h_ptr) != NULL) { \ - IPPairDecrUsecnt(*(src_h_ptr)); \ - *(src_h_ptr) = NULL; \ - } \ - } while (0) - -IPPairConfig ippair_config; -SC_ATOMIC_DECLARE(unsigned long long int,ippair_memuse); -SC_ATOMIC_DECLARE(unsigned int,ippair_counter); -SC_ATOMIC_DECLARE(unsigned int,ippair_prune_idx); - -void IPPairInitConfig(char quiet); -void IPPairShutdown(void); -void IPPairCleanup(void); - -IPPair *IPPairLookupIPPairFromHash (Address *, Address *); -IPPair *IPPairGetIPPairFromHash (Address *, Address *); -void IPPairRelease(IPPair *); -void IPPairLock(IPPair *); -void IPPairClearMemory(IPPair *); -void IPPairMoveToSpare(IPPair *); -uint32_t IPPairSpareQueueGetSize(void); -void IPPairPrintStats (void); - -void IPPairRegisterUnittests(void); - -IPPair *IPPairAlloc(void); -void IPPairFree(IPPair *); - -void IPPairLock(IPPair *); -void IPPairUnlock(IPPair *); - -#endif /* __IPPAIR_H__ */ diff --git a/framework/src/suricata/src/log-dnslog.c b/framework/src/suricata/src/log-dnslog.c deleted file mode 100644 index e30c3d3e..00000000 --- a/framework/src/suricata/src/log-dnslog.c +++ /dev/null @@ -1,362 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements dns logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "log-dnslog.h" -#include "app-layer-dns-common.h" -#include "app-layer-dns-udp.h" -#include "app-layer.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" -#include "util-time.h" - -#define DEFAULT_LOG_FILENAME "dns.log" - -#define MODULE_NAME "LogDnsLog" - -#define OUTPUT_BUFFER_SIZE 65535 - -/* we can do query logging as well, but it's disabled for now as the - * TX id handling doesn't expect it */ -#define QUERY 0 - -typedef struct LogDnsFileCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ -} LogDnsFileCtx; - -typedef struct LogDnsLogThread_ { - LogDnsFileCtx *dnslog_ctx; - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - uint32_t dns_cnt; - - MemBuffer *buffer; -} LogDnsLogThread; - -static void LogQuery(LogDnsLogThread *aft, char *timebuf, char *srcip, char *dstip, Port sp, Port dp, DNSTransaction *tx, DNSQueryEntry *entry) -{ - LogDnsFileCtx *hlog = aft->dnslog_ctx; - - SCLogDebug("got a DNS request and now logging !!"); - - /* reset */ - MemBufferReset(aft->buffer); - - /* time & tx */ - MemBufferWriteString(aft->buffer, - "%s [**] Query TX %04x [**] ", timebuf, tx->tx_id); - - /* query */ - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)((uint8_t *)entry + sizeof(DNSQueryEntry)), - entry->len); - - char record[16] = ""; - DNSCreateTypeString(entry->type, record, sizeof(record)); - MemBufferWriteString(aft->buffer, - " [**] %s [**] %s:%" PRIu16 " -> %s:%" PRIu16 "\n", - record, srcip, sp, dstip, dp); - - SCMutexLock(&hlog->file_ctx->fp_mutex); - hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), - MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); - SCMutexUnlock(&hlog->file_ctx->fp_mutex); -} - -static void LogAnswer(LogDnsLogThread *aft, char *timebuf, char *srcip, char *dstip, Port sp, Port dp, DNSTransaction *tx, DNSAnswerEntry *entry) -{ - LogDnsFileCtx *hlog = aft->dnslog_ctx; - - SCLogDebug("got a DNS response and now logging !!"); - - /* reset */ - MemBufferReset(aft->buffer); - /* time & tx*/ - MemBufferWriteString(aft->buffer, - "%s [**] Response TX %04x [**] ", timebuf, tx->tx_id); - - if (entry == NULL) { - if (tx->rcode) { - char rcode[16] = ""; - DNSCreateRcodeString(tx->rcode, rcode, sizeof(rcode)); - MemBufferWriteString(aft->buffer, "%s", rcode); - } else if (tx->recursion_desired) { - MemBufferWriteString(aft->buffer, "Recursion Desired"); - } - } else { - /* query */ - if (entry->fqdn_len > 0) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)((uint8_t *)entry + sizeof(DNSAnswerEntry)), - entry->fqdn_len); - } else { - MemBufferWriteString(aft->buffer, ""); - } - - char record[16] = ""; - DNSCreateTypeString(entry->type, record, sizeof(record)); - MemBufferWriteString(aft->buffer, - " [**] %s [**] TTL %u [**] ", record, entry->ttl); - - uint8_t *ptr = (uint8_t *)((uint8_t *)entry + sizeof(DNSAnswerEntry) + entry->fqdn_len); - if (entry->type == DNS_RECORD_TYPE_A) { - char a[16] = ""; - PrintInet(AF_INET, (const void *)ptr, a, sizeof(a)); - MemBufferWriteString(aft->buffer, "%s", a); - } else if (entry->type == DNS_RECORD_TYPE_AAAA) { - char a[46]; - PrintInet(AF_INET6, (const void *)ptr, a, sizeof(a)); - MemBufferWriteString(aft->buffer, "%s", a); - } else if (entry->data_len == 0) { - MemBufferWriteString(aft->buffer, ""); - } else { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, ptr, entry->data_len); - } - } - - /* ip/tcp header info */ - MemBufferWriteString(aft->buffer, - " [**] %s:%" PRIu16 " -> %s:%" PRIu16 "\n", - srcip, sp, dstip, dp); - - SCMutexLock(&hlog->file_ctx->fp_mutex); - hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), - MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); - SCMutexUnlock(&hlog->file_ctx->fp_mutex); -} - -static int LogDnsLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, - void *state, void *tx, uint64_t tx_id) -{ - LogDnsLogThread *aft = (LogDnsLogThread *)data; - DNSTransaction *dns_tx = (DNSTransaction *)tx; - SCLogDebug("pcap_cnt %ju", p->pcap_cnt); - char timebuf[64]; - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - int ipproto = 0; - if (PKT_IS_IPV4(p)) - ipproto = AF_INET; - else if (PKT_IS_IPV6(p)) - ipproto = AF_INET6; - - char srcip[46], dstip[46]; - Port sp, dp; - if ((PKT_IS_TOCLIENT(p))) { - switch (ipproto) { - case AF_INET: - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - break; - case AF_INET6: - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - break; - default: - goto end; - } - sp = p->sp; - dp = p->dp; - } else { - switch (ipproto) { - case AF_INET: - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip)); - break; - case AF_INET6: - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip)); - break; - default: - goto end; - } - sp = p->dp; - dp = p->sp; - } - - DNSQueryEntry *query = NULL; - TAILQ_FOREACH(query, &dns_tx->query_list, next) { - LogQuery(aft, timebuf, dstip, srcip, dp, sp, dns_tx, query); - } - - if (dns_tx->rcode) - LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, NULL); - if (dns_tx->recursion_desired) - LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, NULL); - - DNSAnswerEntry *entry = NULL; - TAILQ_FOREACH(entry, &dns_tx->answer_list, next) { - LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, entry); - } - - entry = NULL; - TAILQ_FOREACH(entry, &dns_tx->authority_list, next) { - LogAnswer(aft, timebuf, srcip, dstip, sp, dp, dns_tx, entry); - } - - aft->dns_cnt++; -end: - return 0; -} - -static TmEcode LogDnsLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogDnsLogThread *aft = SCMalloc(sizeof(LogDnsLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(LogDnsLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for DNSLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->dnslog_ctx= ((OutputCtx *)initdata)->data; - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode LogDnsLogThreadDeinit(ThreadVars *t, void *data) -{ - LogDnsLogThread *aft = (LogDnsLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(LogDnsLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void LogDnsLogExitPrintStats(ThreadVars *tv, void *data) -{ - LogDnsLogThread *aft = (LogDnsLogThread *)data; - if (aft == NULL) { - return; - } - - SCLogInfo("DNS logger logged %" PRIu32 " transactions", aft->dns_cnt); -} - -static void LogDnsLogDeInitCtx(OutputCtx *output_ctx) -{ - LogDnsFileCtx *dnslog_ctx = (LogDnsFileCtx *)output_ctx->data; - LogFileFreeCtx(dnslog_ctx->file_ctx); - SCFree(dnslog_ctx); - SCFree(output_ctx); -} - -/** \brief Create a new dns log LogFileCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFileCtx* to the file_ctx if succesful - * */ -static OutputCtx *LogDnsLogInitCtx(ConfNode *conf) -{ - LogFileCtx* file_ctx = LogFileNewCtx(); - - if(file_ctx == NULL) { - SCLogError(SC_ERR_DNS_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - LogDnsFileCtx *dnslog_ctx = SCMalloc(sizeof(LogDnsFileCtx)); - if (unlikely(dnslog_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - memset(dnslog_ctx, 0x00, sizeof(LogDnsFileCtx)); - - dnslog_ctx->file_ctx = file_ctx; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(dnslog_ctx); - return NULL; - } - - output_ctx->data = dnslog_ctx; - output_ctx->DeInit = LogDnsLogDeInitCtx; - - SCLogDebug("DNS log output initialized"); - - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_DNS); - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_DNS); - - return output_ctx; -} - -void TmModuleLogDnsLogRegister (void) -{ - tmm_modules[TMM_LOGDNSLOG].name = MODULE_NAME; - tmm_modules[TMM_LOGDNSLOG].ThreadInit = LogDnsLogThreadInit; - tmm_modules[TMM_LOGDNSLOG].ThreadExitPrintStats = LogDnsLogExitPrintStats; - tmm_modules[TMM_LOGDNSLOG].ThreadDeinit = LogDnsLogThreadDeinit; - tmm_modules[TMM_LOGDNSLOG].RegisterTests = NULL; - tmm_modules[TMM_LOGDNSLOG].cap_flags = 0; - tmm_modules[TMM_LOGDNSLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterTxModule(MODULE_NAME, "dns-log", LogDnsLogInitCtx, - ALPROTO_DNS, LogDnsLogger); - - /* enable the logger for the app layer */ - SCLogDebug("registered %s", MODULE_NAME); -} diff --git a/framework/src/suricata/src/log-dnslog.h b/framework/src/suricata/src/log-dnslog.h deleted file mode 100644 index acd00bc4..00000000 --- a/framework/src/suricata/src/log-dnslog.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __LOG_DNSLOG_H__ -#define __LOG_DNSLOG_H__ - -void TmModuleLogDnsLogRegister (void); - -#endif /* __LOG_DNSLOG_H__ */ diff --git a/framework/src/suricata/src/log-droplog.c b/framework/src/suricata/src/log-droplog.c deleted file mode 100644 index 6eafd9d5..00000000 --- a/framework/src/suricata/src/log-droplog.c +++ /dev/null @@ -1,507 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * \author Victor Julien - * - * Drop log module to log the dropped packet information in a format - * compatible to Linux' Netfilter. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" - -#include "threads.h" -#include "tm-threads.h" -#include "threadvars.h" -#include "util-debug.h" - -#include "decode-ipv4.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-reference.h" - -#include "output.h" -#include "log-droplog.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-classification-config.h" -#include "util-privs.h" -#include "util-print.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#define DEFAULT_LOG_FILENAME "drop.log" - -#define MODULE_NAME "LogDropLog" - -typedef struct LogDropLogThread_ { - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - LogFileCtx* file_ctx; - uint64_t drop_cnt; -} LogDropLogThread; - -/** - * \brief Initialize the droplog thread - * \param t Pointer the current thread variable - * \param initdata pointer to the output context - * \param data Pointer to the pointer to droplog thread to be initialized - * - * \return TM_ECODE_OK on success - */ -static TmEcode LogDropLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - if(initdata == NULL) { - SCLogDebug("Error getting context for LogDropLog. \"initdata\" argument NULL"); - return TM_ECODE_FAILED; - } - - LogDropLogThread *dlt = SCMalloc(sizeof(LogDropLogThread)); - if (unlikely(dlt == NULL)) - return TM_ECODE_FAILED; - memset(dlt, 0, sizeof(LogDropLogThread)); - - /** Use the Ouptut Context (file pointer and mutex) */ - dlt->file_ctx = ((OutputCtx *)initdata)->data; - - *data = (void *)dlt; - return TM_ECODE_OK; -} - -/** - * \brief Deinitialize the droplog thread - * \param t Pointer the current thread variable - * \param data Pointer to the droplog thread to be cleared - * - * \return TM_ECODE_OK on success - */ -static TmEcode LogDropLogThreadDeinit(ThreadVars *t, void *data) -{ - LogDropLogThread *dlt = (LogDropLogThread *)data; - if (dlt == NULL) { - return TM_ECODE_OK; - } - - /* clear memory */ - memset(dlt, 0, sizeof(LogDropLogThread)); - - SCFree(dlt); - return TM_ECODE_OK; -} - -/** - * \brief Destroy the LogFileCtx and cleared "drop" output module - * - * \param output_ctx pointer the output context to be cleared - */ -static void LogDropLogDeInitCtx(OutputCtx *output_ctx) -{ - OutputDropLoggerDisable(); - - if (output_ctx != NULL) { - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - if (logfile_ctx != NULL) { - LogFileFreeCtx(logfile_ctx); - } - SCFree(output_ctx); - } -} - -/** - * \brief Create a new LogFileCtx for "drop" output style. - * \param conf The configuration node for this output. - * \return A LogFileCtx pointer on success, NULL on failure. - */ -static OutputCtx *LogDropLogInitCtx(ConfNode *conf) -{ - if (OutputDropLoggerEnable() != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'drop' logger " - "can be enabled"); - return NULL; - } - - LogFileCtx *logfile_ctx = LogFileNewCtx(); - if (logfile_ctx == NULL) { - SCLogDebug("LogDropLogInitCtx: Could not create new LogFileCtx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(logfile_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(logfile_ctx); - return NULL; - } - output_ctx->data = logfile_ctx; - output_ctx->DeInit = LogDropLogDeInitCtx; - - return output_ctx; -} - -/** - * \brief Log the dropped packets in netfilter format when engine is running - * in inline mode - * - * \param tv Pointer the current thread variables - * \param p Pointer the packet which is being logged - * \param data Pointer to the droplog struct - * - * \return return TM_EODE_OK on success - */ -static int LogDropLogNetFilter (ThreadVars *tv, const Packet *p, void *data) -{ - LogDropLogThread *dlt = (LogDropLogThread *)data; - uint16_t proto = 0; - char timebuf[64]; - - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - SCMutexLock(&dlt->file_ctx->fp_mutex); - - if (dlt->file_ctx->rotation_flag) { - dlt->file_ctx->rotation_flag = 0; - if (SCConfLogReopen(dlt->file_ctx) != 0) { - /* Rotation failed, error already logged. */ - SCMutexUnlock(&dlt->file_ctx->fp_mutex); - return TM_ECODE_FAILED; - } - } - - char srcip[46] = ""; - char dstip[46] = ""; - - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, 16); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, 16); - fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16" " - "TOS=0x%02"PRIu8" TTL=%"PRIu8" ID=%"PRIu16"", timebuf, - srcip, dstip, IPV4_GET_IPLEN(p), IPV4_GET_IPTOS(p), - IPV4_GET_IPTTL(p), IPV4_GET_IPID(p)); - proto = IPV4_GET_IPPROTO(p); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - fprintf(dlt->file_ctx->fp, "%s: IN= OUT= SRC=%s DST=%s LEN=%"PRIu16"" - " TC=%"PRIu32" HOPLIMIT=%"PRIu8" FLOWLBL=%"PRIu32"", timebuf, - srcip, dstip, IPV6_GET_PLEN(p), IPV6_GET_CLASS(p), - IPV6_GET_HLIM(p), IPV6_GET_FLOW(p)); - proto = IPV6_GET_L4PROTO(p); - } - - if (SCProtoNameValid(proto) == TRUE) { - fprintf(dlt->file_ctx->fp, " PROTO=%s",known_proto[proto]); - } else { - fprintf(dlt->file_ctx->fp, " PROTO=%03"PRIu16"",proto); - } - - switch (proto) { - case IPPROTO_TCP: - fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16" " - "SEQ=%"PRIu32" ACK=%"PRIu32" WINDOW=%"PRIu32"", - GET_TCP_SRC_PORT(p), GET_TCP_DST_PORT(p), TCP_GET_SEQ(p), - TCP_GET_ACK(p), TCP_GET_WINDOW(p)); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_SYN(p) ? " SYN" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_ACK(p) ? " ACK" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_PUSH(p) ? " PSH" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_RST(p) ? " RST" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_URG(p) ? " URG" : ""); - fprintf(dlt->file_ctx->fp, TCP_ISSET_FLAG_FIN(p) ? " FIN" : ""); - fprintf(dlt->file_ctx->fp, " RES=0x%02"PRIu8" URGP=%"PRIu16"", - TCP_GET_RAW_X2(p->tcph), TCP_GET_URG_POINTER(p)); - break; - case IPPROTO_UDP: - fprintf(dlt->file_ctx->fp, " SPT=%"PRIu16" DPT=%"PRIu16"" - " LEN=%"PRIu16"", UDP_GET_SRC_PORT(p), - UDP_GET_DST_PORT(p), UDP_GET_LEN(p)); - break; - case IPPROTO_ICMP: - if (PKT_IS_ICMPV4(p)) { - fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8"" - " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV4_GET_TYPE(p), - ICMPV4_GET_CODE(p), ICMPV4_GET_ID(p), ICMPV4_GET_SEQ(p)); - } else if(PKT_IS_ICMPV6(p)) { - fprintf(dlt->file_ctx->fp, " TYPE=%"PRIu8" CODE=%"PRIu8"" - " ID=%"PRIu16" SEQ=%"PRIu16"", ICMPV6_GET_TYPE(p), - ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p)); - } - break; - default: - fprintf(dlt->file_ctx->fp," Unknown protocol"); - } - - fprintf(dlt->file_ctx->fp,"\n"); - - fflush(dlt->file_ctx->fp); - - dlt->drop_cnt++; - SCMutexUnlock(&dlt->file_ctx->fp_mutex); - - return TM_ECODE_OK; - -} - -/** - * \brief Check if we need to drop-log this packet - * - * \param tv Pointer the current thread variables - * \param p Pointer the packet which is tested - * - * \retval bool TRUE or FALSE - */ -static int LogDropCondition(ThreadVars *tv, const Packet *p) -{ - if (!EngineModeIsIPS()) { - SCLogDebug("engine is not running in inline mode, so returning"); - return FALSE; - } - if (PKT_IS_PSEUDOPKT(p)) { - SCLogDebug("drop log doesn't log pseudo packets"); - return FALSE; - } - - if (p->flow != NULL) { - int ret = FALSE; - FLOWLOCK_RDLOCK(p->flow); - if (p->flow->flags & FLOW_ACTION_DROP) { - if (PKT_IS_TOSERVER(p) && !(p->flow->flags & FLOW_TOSERVER_DROP_LOGGED)) - ret = TRUE; - else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED)) - ret = TRUE; - } - FLOWLOCK_UNLOCK(p->flow); - return ret; - } else if (PACKET_TEST_ACTION(p, ACTION_DROP)) { - return TRUE; - } - - return FALSE; -} - -/** - * \brief Log the dropped packets when engine is running in inline mode - * - * \param tv Pointer the current thread variables - * \param data Pointer to the droplog struct - * \param p Pointer the packet which is being logged - * - * \retval 0 on succes - */ -static int LogDropLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - - int r = LogDropLogNetFilter(tv, p, thread_data); - if (r < 0) - return -1; - - if (p->flow) { - FLOWLOCK_RDLOCK(p->flow); - if (p->flow->flags & FLOW_ACTION_DROP) { - if (PKT_IS_TOSERVER(p) && !(p->flow->flags & FLOW_TOSERVER_DROP_LOGGED)) - p->flow->flags |= FLOW_TOSERVER_DROP_LOGGED; - else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED)) - p->flow->flags |= FLOW_TOCLIENT_DROP_LOGGED; - } - FLOWLOCK_UNLOCK(p->flow); - } - return 0; -} - -static void LogDropLogExitPrintStats(ThreadVars *tv, void *data) -{ - LogDropLogThread *dlt = (LogDropLogThread *)data; - if (dlt == NULL) { - return; - } - - SCLogInfo("(%s) Dropped Packets %" PRIu64 "", tv->name, dlt->drop_cnt); -} - -/***************************** Unittests ****************************/ - -#ifdef UNITTESTS - -/** \brief test if the action is drop then packet should be logged */ -int LogDropLogTest01() -{ - int result = 0; - EngineModeSetIPS(); - - uint8_t *buf = (uint8_t *) "GET /one/ HTTP/1.1\r\n" - "Host: one.example.org\r\n"; - - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - LogDropLogThread dlt; - LogFileCtx *logfile_ctx = LogFileNewCtx(); - if (logfile_ctx == NULL) { - printf("Could not create new LogFileCtx\n"); - return 0; - } - - memset (&dlt, 0, sizeof(LogDropLogThread)); - dlt.file_ctx = logfile_ctx; - dlt.file_ctx->fp = stdout; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - return result; - } - - de_ctx->flags |= DE_QUIET; - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any any " - "(msg:\"LogDropLog test\"; content:\"GET\"; Classtype:unknown; sid:1;)"); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt == 1 && (PACKET_TEST_ACTION(p, ACTION_DROP))) - result = (strcmp(p->alerts.alerts[0].s->class_msg, "Unknown are we") == 0); - - if (LogDropCondition(NULL, p) == TRUE) - LogDropLogger(NULL, &dlt, p); - - if (dlt.drop_cnt == 0) { - printf("Packet should be logged but its not\n"); - result = 0; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); - EngineModeSetIDS(); - return result; -} - -/** \brief test if the action is alert then packet shouldn't be logged */ -int LogDropLogTest02() -{ - int result = 0; - EngineModeSetIPS(); - - uint8_t *buf = (uint8_t *) "GET"; - - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx; - LogDropLogThread dlt; - LogFileCtx *logfile_ctx = LogFileNewCtx(); - if (logfile_ctx == NULL) { - printf("Could not create new LogFileCtx\n"); - return 0; - } - - memset (&dlt, 0, sizeof(LogDropLogThread)); - dlt.file_ctx = logfile_ctx; - dlt.file_ctx->fp = stdout; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf, buflen, IPPROTO_UDP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - return result; - } - - de_ctx->flags |= DE_QUIET; - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - de_ctx->sig_list = SigInit(de_ctx, "alert udp any any -> any any " - "(msg:\"LogDropLog test\"; content:\"GET\"; Classtype:unknown; sid:1;)"); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt == 1 && p->alerts.alerts[0].action != ACTION_DROP) - result = (strcmp(p->alerts.alerts[0].s->class_msg, "Unknown are we") == 0); - - if (LogDropCondition(NULL, p) == TRUE) - LogDropLogger(NULL, &dlt, p); - - if (dlt.drop_cnt != 0) { - printf("Packet shouldn't be logged but it is\n"); - result = 0; - } - - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - UTHFreePackets(&p, 1); - - EngineModeSetIDS(); - return result; -} - -/** - * \brief This function registers unit tests for AlertFastLog API. - */ -static void LogDropLogRegisterTests(void) -{ - UtRegisterTest("LogDropLogTest01", LogDropLogTest01, 1); - UtRegisterTest("LogDropLogTest02", LogDropLogTest02, 1); -} -#endif - -/** \brief function to register the drop log module */ -void TmModuleLogDropLogRegister (void) -{ - - tmm_modules[TMM_LOGDROPLOG].name = MODULE_NAME; - tmm_modules[TMM_LOGDROPLOG].ThreadInit = LogDropLogThreadInit; - tmm_modules[TMM_LOGDROPLOG].ThreadExitPrintStats = LogDropLogExitPrintStats; - tmm_modules[TMM_LOGDROPLOG].ThreadDeinit = LogDropLogThreadDeinit; -#ifdef UNITTESTS - tmm_modules[TMM_LOGDROPLOG].RegisterTests = LogDropLogRegisterTests; -#endif - tmm_modules[TMM_LOGDROPLOG].cap_flags = 0; - tmm_modules[TMM_LOGDROPLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterPacketModule(MODULE_NAME, "drop", LogDropLogInitCtx, - LogDropLogger, LogDropCondition); -} diff --git a/framework/src/suricata/src/log-droplog.h b/framework/src/suricata/src/log-droplog.h deleted file mode 100644 index 2b266ad5..00000000 --- a/framework/src/suricata/src/log-droplog.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - */ - - -#ifndef ALERT_DROPLOG_H -#define ALERT_DROPLOG_H - -void TmModuleLogDropLogRegister(void); - -#endif /* ALERT_DROPLOG_H */ diff --git a/framework/src/suricata/src/log-file.c b/framework/src/suricata/src/log-file.c deleted file mode 100644 index 0c41e38d..00000000 --- a/framework/src/suricata/src/log-file.c +++ /dev/null @@ -1,465 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Log files we track. - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threadvars.h" -#include "tm-modules.h" - -#include "threads.h" - -#include "app-layer-parser.h" - -#include "detect-filemagic.h" - -#include "stream.h" - -#include "util-print.h" -#include "util-unittest.h" -#include "util-privs.h" -#include "util-debug.h" -#include "util-atomic.h" -#include "util-file.h" -#include "util-time.h" - -#include "output.h" - -#include "log-file.h" -#include "util-logopenfile.h" - -#include "app-layer-htp.h" -#include "app-layer-smtp.h" -#include "util-decode-mime.h" -#include "util-memcmp.h" -#include "stream-tcp-reassemble.h" - -#define MODULE_NAME "LogFileLog" - -#define DEFAULT_LOG_FILENAME "files-json.log" - -typedef struct LogFileLogThread_ { - LogFileCtx *file_ctx; - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - uint32_t file_cnt; -} LogFileLogThread; - -static void LogFileMetaGetUri(FILE *fp, const Packet *p, const File *ff) -{ - HtpState *htp_state = (HtpState *)p->flow->alstate; - if (htp_state != NULL) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid); - if (tx != NULL) { - HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud != NULL) { - if (tx_ud->request_uri_normalized != NULL) { - PrintRawJsonFp(fp, - bstr_ptr(tx_ud->request_uri_normalized), - bstr_len(tx_ud->request_uri_normalized)); - return; - } - } - } - } - - fprintf(fp, ""); -} - -static void LogFileMetaGetHost(FILE *fp, const Packet *p, const File *ff) -{ - HtpState *htp_state = (HtpState *)p->flow->alstate; - if (htp_state != NULL) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid); - if (tx != NULL && tx->request_hostname != NULL) { - PrintRawJsonFp(fp, (uint8_t *)bstr_ptr(tx->request_hostname), - bstr_len(tx->request_hostname)); - return; - } - } - - fprintf(fp, ""); -} - -static void LogFileMetaGetReferer(FILE *fp, const Packet *p, const File *ff) -{ - HtpState *htp_state = (HtpState *)p->flow->alstate; - if (htp_state != NULL) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid); - if (tx != NULL) { - htp_header_t *h = NULL; - h = (htp_header_t *)htp_table_get_c(tx->request_headers, - "Referer"); - if (h != NULL) { - PrintRawJsonFp(fp, (uint8_t *)bstr_ptr(h->value), - bstr_len(h->value)); - return; - } - } - } - - fprintf(fp, ""); -} - -static void LogFileMetaGetUserAgent(FILE *fp, const Packet *p, const File *ff) -{ - HtpState *htp_state = (HtpState *)p->flow->alstate; - if (htp_state != NULL) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid); - if (tx != NULL) { - htp_header_t *h = NULL; - h = (htp_header_t *)htp_table_get_c(tx->request_headers, - "User-Agent"); - if (h != NULL) { - PrintRawJsonFp(fp, (uint8_t *)bstr_ptr(h->value), - bstr_len(h->value)); - return; - } - } - } - - fprintf(fp, ""); -} - -static void LogFileMetaGetSmtp(FILE *fp, const Packet *p, const File *ff) -{ - SMTPState *state = (SMTPState *) p->flow->alstate; - if (state != NULL) { - SMTPTransaction *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_SMTP, state, ff->txid); - if (tx == NULL || tx->msg_tail == NULL) - return; - - /* Message Id */ - if (tx->msg_tail->msg_id != NULL) { - - fprintf(fp, "\"message-id\": \""); - PrintRawJsonFp(fp, (uint8_t *) tx->msg_tail->msg_id, - (int) tx->msg_tail->msg_id_len); - fprintf(fp, "\", "); - } - - /* Sender */ - MimeDecField *field = MimeDecFindField(tx->msg_tail, "from"); - if (field != NULL) { - fprintf(fp, "\"sender\": \""); - PrintRawJsonFp(fp, (uint8_t *) field->value, - (int) field->value_len); - fprintf(fp, "\", "); - } - } -} - -/** - * \internal - * \brief Write meta data on a single line json record - */ -static void LogFileWriteJsonRecord(LogFileLogThread *aft, const Packet *p, const File *ff, int ipver) -{ - SCMutexLock(&aft->file_ctx->fp_mutex); - - /* As writes are done via the LogFileCtx, check for rotation here. */ - if (aft->file_ctx->rotation_flag) { - aft->file_ctx->rotation_flag = 0; - if (SCConfLogReopen(aft->file_ctx) != 0) { - SCLogWarning(SC_ERR_FOPEN, "Failed to re-open log file. " - "Logging for this module will be disabled."); - } - } - - /* Bail early if no file pointer to write to (in the unlikely - * event file rotation failed. */ - if (aft->file_ctx->fp == NULL) { - SCMutexUnlock(&aft->file_ctx->fp_mutex); - return; - } - - FILE *fp = aft->file_ctx->fp; - char timebuf[64]; - AppProto alproto = FlowGetAppProtocol(p->flow); - - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - fprintf(fp, "{ "); - - if (ff->file_id > 0) - fprintf(fp, "\"id\": %u, ", ff->file_id); - - fprintf(fp, "\"timestamp\": \""); - PrintRawJsonFp(fp, (uint8_t *)timebuf, strlen(timebuf)); - fprintf(fp, "\", "); - if (p->pcap_cnt > 0) { - fprintf(fp, "\"pcap_pkt_num\": %"PRIu64", ", p->pcap_cnt); - } - - fprintf(fp, "\"ipver\": %d, ", ipver == AF_INET ? 4 : 6); - - char srcip[46], dstip[46]; - Port sp, dp; - switch (ipver) { - case AF_INET: - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - break; - case AF_INET6: - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - break; - default: - strlcpy(srcip, "", sizeof(srcip)); - strlcpy(dstip, "", sizeof(dstip)); - break; - } - sp = p->sp; - dp = p->dp; - - fprintf(fp, "\"srcip\": \"%s\", ", srcip); - fprintf(fp, "\"dstip\": \"%s\", ", dstip); - fprintf(fp, "\"protocol\": %" PRIu32 ", ", p->proto); - if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { - fprintf(fp, "\"sp\": %" PRIu16 ", ", sp); - fprintf(fp, "\"dp\": %" PRIu16 ", ", dp); - } - - if (alproto == ALPROTO_HTTP) { - fprintf(fp, "\"http_uri\": \""); - LogFileMetaGetUri(fp, p, ff); - fprintf(fp, "\", "); - - fprintf(fp, "\"http_host\": \""); - LogFileMetaGetHost(fp, p, ff); - fprintf(fp, "\", "); - - fprintf(fp, "\"http_referer\": \""); - LogFileMetaGetReferer(fp, p, ff); - fprintf(fp, "\", "); - - fprintf(fp, "\"http_user_agent\": \""); - LogFileMetaGetUserAgent(fp, p, ff); - fprintf(fp, "\", "); - } else if (p->flow->alproto == ALPROTO_SMTP) { - /* Only applicable to SMTP */ - LogFileMetaGetSmtp(fp, p, ff); - } - - fprintf(fp, "\"filename\": \""); - PrintRawJsonFp(fp, ff->name, ff->name_len); - fprintf(fp, "\", "); - - fprintf(fp, "\"magic\": \""); - if (ff->magic) { - PrintRawJsonFp(fp, (uint8_t *)ff->magic, strlen(ff->magic)); - } else { - fprintf(fp, "unknown"); - } - fprintf(fp, "\", "); - - switch (ff->state) { - case FILE_STATE_CLOSED: - fprintf(fp, "\"state\": \"CLOSED\", "); -#ifdef HAVE_NSS - if (ff->flags & FILE_MD5) { - fprintf(fp, "\"md5\": \""); - size_t x; - for (x = 0; x < sizeof(ff->md5); x++) { - fprintf(fp, "%02x", ff->md5[x]); - } - fprintf(fp, "\", "); - } -#endif - break; - case FILE_STATE_TRUNCATED: - fprintf(fp, "\"state\": \"TRUNCATED\", "); - break; - case FILE_STATE_ERROR: - fprintf(fp, "\"state\": \"ERROR\", "); - break; - default: - fprintf(fp, "\"state\": \"UNKNOWN\", "); - break; - } - fprintf(fp, "\"stored\": %s, ", ff->flags & FILE_STORED ? "true" : "false"); - fprintf(fp, "\"size\": %"PRIu64" ", ff->size); - fprintf(fp, "}\n"); - fflush(fp); - SCMutexUnlock(&aft->file_ctx->fp_mutex); -} - -static int LogFileLogger(ThreadVars *tv, void *thread_data, const Packet *p, const File *ff) -{ - SCEnter(); - LogFileLogThread *aft = (LogFileLogThread *)thread_data; - int ipver = -1; - - if (PKT_IS_IPV4(p)) { - ipver = AF_INET; - } else if (PKT_IS_IPV6(p)) { - ipver = AF_INET6; - } else { - return 0; - } - - BUG_ON(ff->flags & FILE_LOGGED); - - SCLogDebug("ff %p", ff); - - LogFileWriteJsonRecord(aft, p, ff, ipver); - - aft->file_cnt++; - return 0; -} - -static TmEcode LogFileLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogFileLogThread *aft = SCMalloc(sizeof(LogFileLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(LogFileLogThread)); - - if (initdata == NULL) - { - SCLogDebug("Error getting context for LogFile. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->file_ctx = ((OutputCtx *)initdata)->data; - - *data = (void *)aft; - return TM_ECODE_OK; -} - -TmEcode LogFileLogThreadDeinit(ThreadVars *t, void *data) -{ - LogFileLogThread *aft = (LogFileLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - /* clear memory */ - memset(aft, 0, sizeof(LogFileLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -void LogFileLogExitPrintStats(ThreadVars *tv, void *data) -{ - LogFileLogThread *aft = (LogFileLogThread *)data; - if (aft == NULL) { - return; - } - - SCLogInfo("(%s) Files logged: %" PRIu32 "", tv->name, aft->file_cnt); -} - -/** - * \internal - * - * \brief deinit the log ctx and write out the waldo - * - * \param output_ctx output context to deinit - */ -static void LogFileLogDeInitCtx(OutputCtx *output_ctx) -{ - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - LogFileFreeCtx(logfile_ctx); - free(output_ctx); -} - -/** \brief Create a new http log LogFileCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFileCtx* to the file_ctx if succesful - * */ -static OutputCtx *LogFileLogInitCtx(ConfNode *conf) -{ - LogFileCtx *logfile_ctx = LogFileNewCtx(); - if (logfile_ctx == NULL) { - SCLogDebug("Could not create new LogFileCtx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(logfile_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) - return NULL; - - output_ctx->data = logfile_ctx; - output_ctx->DeInit = LogFileLogDeInitCtx; - - const char *force_magic = ConfNodeLookupChildValue(conf, "force-magic"); - if (force_magic != NULL && ConfValIsTrue(force_magic)) { - FileForceMagicEnable(); - SCLogInfo("forcing magic lookup for logged files"); - } - - const char *force_md5 = ConfNodeLookupChildValue(conf, "force-md5"); - if (force_md5 != NULL && ConfValIsTrue(force_md5)) { -#ifdef HAVE_NSS - FileForceMd5Enable(); - SCLogInfo("forcing md5 calculation for logged files"); -#else - SCLogInfo("md5 calculation requires linking against libnss"); -#endif - } - - FileForceTrackingEnable(); - SCReturnPtr(output_ctx, "OutputCtx"); -} - -/** \brief Read the config set the file pointer, open the file - * \param file_ctx pointer to a created LogFileCtx using LogFileNewCtx() - * \param config_file for loading separate configs - * \return -1 if failure, 0 if succesful - * */ -int LogFileLogOpenFileCtx(LogFileCtx *file_ctx, const char *filename, const - char *mode) -{ - return 0; -} - -void TmModuleLogFileLogRegister (void) -{ - tmm_modules[TMM_FILELOG].name = MODULE_NAME; - tmm_modules[TMM_FILELOG].ThreadInit = LogFileLogThreadInit; - tmm_modules[TMM_FILELOG].Func = NULL; - tmm_modules[TMM_FILELOG].ThreadExitPrintStats = LogFileLogExitPrintStats; - tmm_modules[TMM_FILELOG].ThreadDeinit = LogFileLogThreadDeinit; - tmm_modules[TMM_FILELOG].RegisterTests = NULL; - tmm_modules[TMM_FILELOG].cap_flags = 0; - tmm_modules[TMM_FILELOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterFileModule(MODULE_NAME, "file-log", LogFileLogInitCtx, - LogFileLogger); - - SCLogDebug("registered"); -} diff --git a/framework/src/suricata/src/log-file.h b/framework/src/suricata/src/log-file.h deleted file mode 100644 index 08e0785b..00000000 --- a/framework/src/suricata/src/log-file.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __LOG_FILELOG_H__ -#define __LOG_FILELOG_H__ - -void TmModuleLogFileLogRegister (void); - -#endif /* __LOG_FILELOG_H__ */ diff --git a/framework/src/suricata/src/log-filestore.c b/framework/src/suricata/src/log-filestore.c deleted file mode 100644 index 4244b9a4..00000000 --- a/framework/src/suricata/src/log-filestore.c +++ /dev/null @@ -1,499 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threadvars.h" -#include "tm-modules.h" - -#include "threads.h" - -#include "app-layer-parser.h" - -#include "detect-filemagic.h" - -#include "stream.h" - -#include "util-print.h" -#include "util-unittest.h" -#include "util-privs.h" -#include "util-debug.h" -#include "util-atomic.h" -#include "util-file.h" -#include "util-time.h" - -#include "output.h" - -#include "log-file.h" -#include "util-logopenfile.h" - -#include "app-layer-htp.h" -#include "app-layer-smtp.h" -#include "util-decode-mime.h" -#include "util-memcmp.h" -#include "stream-tcp-reassemble.h" - -#define MODULE_NAME "LogFilestoreLog" - -static char g_logfile_base_dir[PATH_MAX] = "/tmp"; - -typedef struct LogFilestoreLogThread_ { - LogFileCtx *file_ctx; - /** LogFilestoreCtx has the pointer to the file and a mutex to allow multithreading */ - uint32_t file_cnt; -} LogFilestoreLogThread; - -static void LogFilestoreMetaGetUri(FILE *fp, const Packet *p, const File *ff) -{ - HtpState *htp_state = (HtpState *)p->flow->alstate; - if (htp_state != NULL) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid); - if (tx != NULL) { - HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud->request_uri_normalized != NULL) { - PrintRawUriFp(fp, bstr_ptr(tx_ud->request_uri_normalized), - bstr_len(tx_ud->request_uri_normalized)); - } - return; - } - } - - fprintf(fp, ""); -} - -static void LogFilestoreMetaGetHost(FILE *fp, const Packet *p, const File *ff) -{ - HtpState *htp_state = (HtpState *)p->flow->alstate; - if (htp_state != NULL) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid); - if (tx != NULL && tx->request_hostname != NULL) { - PrintRawUriFp(fp, (uint8_t *)bstr_ptr(tx->request_hostname), - bstr_len(tx->request_hostname)); - return; - } - } - - fprintf(fp, ""); -} - -static void LogFilestoreMetaGetReferer(FILE *fp, const Packet *p, const File *ff) -{ - HtpState *htp_state = (HtpState *)p->flow->alstate; - if (htp_state != NULL) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid); - if (tx != NULL) { - htp_header_t *h = NULL; - h = (htp_header_t *)htp_table_get_c(tx->request_headers, - "Referer"); - if (h != NULL) { - PrintRawUriFp(fp, (uint8_t *)bstr_ptr(h->value), - bstr_len(h->value)); - return; - } - } - } - - fprintf(fp, ""); -} - -static void LogFilestoreMetaGetUserAgent(FILE *fp, const Packet *p, const File *ff) -{ - HtpState *htp_state = (HtpState *)p->flow->alstate; - if (htp_state != NULL) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, ff->txid); - if (tx != NULL) { - htp_header_t *h = NULL; - h = (htp_header_t *)htp_table_get_c(tx->request_headers, - "User-Agent"); - if (h != NULL) { - PrintRawUriFp(fp, (uint8_t *)bstr_ptr(h->value), - bstr_len(h->value)); - return; - } - } - } - - fprintf(fp, ""); -} - -static void LogFilestoreMetaGetSmtp(FILE *fp, const Packet *p, const File *ff) -{ - SMTPState *state = (SMTPState *) p->flow->alstate; - if (state != NULL) { - SMTPTransaction *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_SMTP, state, ff->txid); - if (tx == NULL || tx->msg_tail == NULL) - return; - - /* Message Id */ - if (tx->msg_tail->msg_id != NULL) { - fprintf(fp, "MESSAGE-ID: "); - PrintRawUriFp(fp, (uint8_t *) tx->msg_tail->msg_id, tx->msg_tail->msg_id_len); - fprintf(fp, "\n"); - } - - /* Sender */ - MimeDecField *field = MimeDecFindField(tx->msg_tail, "from"); - if (field != NULL) { - fprintf(fp, "SENDER: "); - PrintRawUriFp(fp, (uint8_t *) field->value, field->value_len); - fprintf(fp, "\n"); - } - } -} - -static void LogFilestoreLogCreateMetaFile(const Packet *p, const File *ff, char *filename, int ipver) { - char metafilename[PATH_MAX] = ""; - snprintf(metafilename, sizeof(metafilename), "%s.meta", filename); - FILE *fp = fopen(metafilename, "w+"); - if (fp != NULL) { - char timebuf[64]; - - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - fprintf(fp, "TIME: %s\n", timebuf); - if (p->pcap_cnt > 0) { - fprintf(fp, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt); - } - - char srcip[46], dstip[46]; - Port sp, dp; - switch (ipver) { - case AF_INET: - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - break; - case AF_INET6: - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - break; - default: - strlcpy(srcip, "", sizeof(srcip)); - strlcpy(dstip, "", sizeof(dstip)); - break; - } - sp = p->sp; - dp = p->dp; - - fprintf(fp, "SRC IP: %s\n", srcip); - fprintf(fp, "DST IP: %s\n", dstip); - fprintf(fp, "PROTO: %" PRIu32 "\n", p->proto); - if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { - fprintf(fp, "SRC PORT: %" PRIu16 "\n", sp); - fprintf(fp, "DST PORT: %" PRIu16 "\n", dp); - } - - fprintf(fp, "APP PROTO: %s\n", - AppProtoToString(p->flow->alproto)); - - /* Only applicable to HTTP traffic */ - if (p->flow->alproto == ALPROTO_HTTP) { - fprintf(fp, "HTTP URI: "); - LogFilestoreMetaGetUri(fp, p, ff); - fprintf(fp, "\n"); - fprintf(fp, "HTTP HOST: "); - LogFilestoreMetaGetHost(fp, p, ff); - fprintf(fp, "\n"); - fprintf(fp, "HTTP REFERER: "); - LogFilestoreMetaGetReferer(fp, p, ff); - fprintf(fp, "\n"); - fprintf(fp, "HTTP USER AGENT: "); - LogFilestoreMetaGetUserAgent(fp, p, ff); - fprintf(fp, "\n"); - } else if (p->flow->alproto == ALPROTO_SMTP) { - /* Only applicable to SMTP */ - LogFilestoreMetaGetSmtp(fp, p, ff); - } - - fprintf(fp, "FILENAME: "); - PrintRawUriFp(fp, ff->name, ff->name_len); - fprintf(fp, "\n"); - - fclose(fp); - } -} - -static void LogFilestoreLogCloseMetaFile(const File *ff) -{ - char filename[PATH_MAX] = ""; - snprintf(filename, sizeof(filename), "%s/file.%u", - g_logfile_base_dir, ff->file_id); - char metafilename[PATH_MAX] = ""; - snprintf(metafilename, sizeof(metafilename), "%s.meta", filename); - FILE *fp = fopen(metafilename, "a"); - if (fp != NULL) { - fprintf(fp, "MAGIC: %s\n", - ff->magic ? ff->magic : ""); - - switch (ff->state) { - case FILE_STATE_CLOSED: - fprintf(fp, "STATE: CLOSED\n"); -#ifdef HAVE_NSS - if (ff->flags & FILE_MD5) { - fprintf(fp, "MD5: "); - size_t x; - for (x = 0; x < sizeof(ff->md5); x++) { - fprintf(fp, "%02x", ff->md5[x]); - } - fprintf(fp, "\n"); - } -#endif - break; - case FILE_STATE_TRUNCATED: - fprintf(fp, "STATE: TRUNCATED\n"); - break; - case FILE_STATE_ERROR: - fprintf(fp, "STATE: ERROR\n"); - break; - default: - fprintf(fp, "STATE: UNKNOWN\n"); - break; - } - fprintf(fp, "SIZE: %"PRIu64"\n", ff->size); - - fclose(fp); - } else { - SCLogInfo("opening %s failed: %s", metafilename, strerror(errno)); - } -} - -static int LogFilestoreLogger(ThreadVars *tv, void *thread_data, const Packet *p, const File *ff, const FileData *ffd, uint8_t flags) -{ - SCEnter(); - LogFilestoreLogThread *aft = (LogFilestoreLogThread *)thread_data; - char filename[PATH_MAX] = ""; - int file_fd = -1; - int ipver = -1; - - /* no flow, no htp state */ - if (p->flow == NULL) { - SCReturnInt(TM_ECODE_OK); - } - - if (PKT_IS_IPV4(p)) { - ipver = AF_INET; - } else if (PKT_IS_IPV6(p)) { - ipver = AF_INET6; - } else { - return 0; - } - - SCLogDebug("ff %p, ffd %p", ff, ffd); - - snprintf(filename, sizeof(filename), "%s/file.%u", - g_logfile_base_dir, ff->file_id); - - if (flags & OUTPUT_FILEDATA_FLAG_OPEN) { - aft->file_cnt++; - - /* create a .meta file that contains time, src/dst/sp/dp/proto */ - LogFilestoreLogCreateMetaFile(p, ff, filename, ipver); - - file_fd = open(filename, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644); - if (file_fd == -1) { - SCLogDebug("failed to create file"); - return -1; - } - /* we can get called with a NULL ffd when we need to close */ - } else if (ffd != NULL) { - file_fd = open(filename, O_APPEND | O_NOFOLLOW | O_WRONLY); - if (file_fd == -1) { - SCLogDebug("failed to open file %s: %s", filename, strerror(errno)); - return -1; - } - } - - if (file_fd != -1) { - ssize_t r = write(file_fd, (const void *)ffd->data, (size_t)ffd->len); - if (r == -1) { - SCLogDebug("write failed: %s", strerror(errno)); - } - close(file_fd); - } - - if (flags & OUTPUT_FILEDATA_FLAG_CLOSE) { - LogFilestoreLogCloseMetaFile(ff); - } - - return 0; -} - -static TmEcode LogFilestoreLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogFilestoreLogThread *aft = SCMalloc(sizeof(LogFilestoreLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(LogFilestoreLogThread)); - - if (initdata == NULL) - { - SCLogDebug("Error getting context for LogFilestore. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->file_ctx = ((OutputCtx *)initdata)->data; - - struct stat stat_buf; - if (stat(g_logfile_base_dir, &stat_buf) != 0) { - int ret; - ret = mkdir(g_logfile_base_dir, S_IRWXU|S_IXGRP|S_IRGRP); - if (ret != 0) { - int err = errno; - if (err != EEXIST) { - SCLogError(SC_ERR_LOGDIR_CONFIG, - "Cannot create file drop directory %s: %s", - g_logfile_base_dir, strerror(err)); - exit(EXIT_FAILURE); - } - } else { - SCLogInfo("Created file drop directory %s", - g_logfile_base_dir); - } - - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode LogFilestoreLogThreadDeinit(ThreadVars *t, void *data) -{ - LogFilestoreLogThread *aft = (LogFilestoreLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - /* clear memory */ - memset(aft, 0, sizeof(LogFilestoreLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void LogFilestoreLogExitPrintStats(ThreadVars *tv, void *data) -{ - LogFilestoreLogThread *aft = (LogFilestoreLogThread *)data; - if (aft == NULL) { - return; - } - - SCLogInfo("(%s) Files extracted %" PRIu32 "", tv->name, aft->file_cnt); -} - -/** - * \internal - * - * \brief deinit the log ctx and write out the waldo - * - * \param output_ctx output context to deinit - */ -static void LogFilestoreLogDeInitCtx(OutputCtx *output_ctx) -{ - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - LogFileFreeCtx(logfile_ctx); - SCFree(output_ctx); - -} - -/** \brief Create a new http log LogFilestoreCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFilestoreCtx* to the file_ctx if succesful - * */ -static OutputCtx *LogFilestoreLogInitCtx(ConfNode *conf) -{ - LogFileCtx *logfile_ctx = LogFileNewCtx(); - if (logfile_ctx == NULL) { - SCLogDebug("Could not create new LogFilestoreCtx"); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) - return NULL; - - output_ctx->data = NULL; - output_ctx->DeInit = LogFilestoreLogDeInitCtx; - - char *s_default_log_dir = NULL; - s_default_log_dir = ConfigGetLogDirectory(); - - const char *s_base_dir = NULL; - s_base_dir = ConfNodeLookupChildValue(conf, "log-dir"); - if (s_base_dir == NULL || strlen(s_base_dir) == 0) { - strlcpy(g_logfile_base_dir, - s_default_log_dir, sizeof(g_logfile_base_dir)); - } else { - if (PathIsAbsolute(s_base_dir)) { - strlcpy(g_logfile_base_dir, - s_base_dir, sizeof(g_logfile_base_dir)); - } else { - snprintf(g_logfile_base_dir, sizeof(g_logfile_base_dir), - "%s/%s", s_default_log_dir, s_base_dir); - } - } - - const char *force_magic = ConfNodeLookupChildValue(conf, "force-magic"); - if (force_magic != NULL && ConfValIsTrue(force_magic)) { - FileForceMagicEnable(); - SCLogInfo("forcing magic lookup for stored files"); - } - - const char *force_md5 = ConfNodeLookupChildValue(conf, "force-md5"); - if (force_md5 != NULL && ConfValIsTrue(force_md5)) { -#ifdef HAVE_NSS - FileForceMd5Enable(); - SCLogInfo("forcing md5 calculation for stored files"); -#else - SCLogInfo("md5 calculation requires linking against libnss"); -#endif - } - SCLogInfo("storing files in %s", g_logfile_base_dir); - - SCReturnPtr(output_ctx, "OutputCtx"); -} - -void TmModuleLogFilestoreRegister (void) -{ - tmm_modules[TMM_FILESTORE].name = MODULE_NAME; - tmm_modules[TMM_FILESTORE].ThreadInit = LogFilestoreLogThreadInit; - tmm_modules[TMM_FILESTORE].Func = NULL; - tmm_modules[TMM_FILESTORE].ThreadExitPrintStats = LogFilestoreLogExitPrintStats; - tmm_modules[TMM_FILESTORE].ThreadDeinit = LogFilestoreLogThreadDeinit; - tmm_modules[TMM_FILESTORE].RegisterTests = NULL; - tmm_modules[TMM_FILESTORE].cap_flags = 0; - tmm_modules[TMM_FILESTORE].flags = TM_FLAG_LOGAPI_TM; - tmm_modules[TMM_FILESTORE].priority = 10; - - OutputRegisterFiledataModule(MODULE_NAME, "file", LogFilestoreLogInitCtx, - LogFilestoreLogger); - OutputRegisterFiledataModule(MODULE_NAME, "file-store", LogFilestoreLogInitCtx, - LogFilestoreLogger); - - SCLogDebug("registered"); -} diff --git a/framework/src/suricata/src/log-filestore.h b/framework/src/suricata/src/log-filestore.h deleted file mode 100644 index bfbfd5fc..00000000 --- a/framework/src/suricata/src/log-filestore.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __LOG_FILESTORE_H__ -#define __LOG_FILESTORE_H__ - -void TmModuleLogFilestoreRegister (void); - -#endif /* __LOG_FILELOG_H__ */ diff --git a/framework/src/suricata/src/log-httplog.c b/framework/src/suricata/src/log-httplog.c deleted file mode 100644 index b9723d8c..00000000 --- a/framework/src/suricata/src/log-httplog.c +++ /dev/null @@ -1,738 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Ignacio Sanchez - * - * Implements http logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "log-httplog.h" -#include "app-layer-htp.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" -#include "util-time.h" - -#define DEFAULT_LOG_FILENAME "http.log" - -#define MODULE_NAME "LogHttpLog" - -#define OUTPUT_BUFFER_SIZE 65535 - -TmEcode LogHttpLogThreadInit(ThreadVars *, void *, void **); -TmEcode LogHttpLogThreadDeinit(ThreadVars *, void *); -void LogHttpLogExitPrintStats(ThreadVars *, void *); -static void LogHttpLogDeInitCtx(OutputCtx *); - -int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *, Flow *f, void *state, void *tx, uint64_t tx_id); - -void TmModuleLogHttpLogRegister (void) -{ - tmm_modules[TMM_LOGHTTPLOG].name = MODULE_NAME; - tmm_modules[TMM_LOGHTTPLOG].ThreadInit = LogHttpLogThreadInit; - tmm_modules[TMM_LOGHTTPLOG].ThreadExitPrintStats = LogHttpLogExitPrintStats; - tmm_modules[TMM_LOGHTTPLOG].ThreadDeinit = LogHttpLogThreadDeinit; - tmm_modules[TMM_LOGHTTPLOG].RegisterTests = NULL; - tmm_modules[TMM_LOGHTTPLOG].cap_flags = 0; - tmm_modules[TMM_LOGHTTPLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterTxModule(MODULE_NAME, "http-log", LogHttpLogInitCtx, - ALPROTO_HTTP, LogHttpLogger); -} - -#define LOG_HTTP_MAXN_NODES 64 -#define LOG_HTTP_NODE_STRLEN 256 -#define LOG_HTTP_NODE_MAXOUTPUTLEN 8192 - -#define TIMESTAMP_DEFAULT_FORMAT "%b %d, %Y; %H:%M:%S" -#define LOG_HTTP_CF_NONE "-" -#define LOG_HTTP_CF_LITERAL '%' -#define LOG_HTTP_CF_REQUEST_HOST 'h' -#define LOG_HTTP_CF_REQUEST_PROTOCOL 'H' -#define LOG_HTTP_CF_REQUEST_METHOD 'm' -#define LOG_HTTP_CF_REQUEST_URI 'u' -#define LOG_HTTP_CF_REQUEST_TIME 't' -#define LOG_HTTP_CF_REQUEST_HEADER 'i' -#define LOG_HTTP_CF_REQUEST_COOKIE 'C' -#define LOG_HTTP_CF_REQUEST_LEN 'b' -#define LOG_HTTP_CF_RESPONSE_STATUS 's' -#define LOG_HTTP_CF_RESPONSE_HEADER 'o' -#define LOG_HTTP_CF_RESPONSE_LEN 'B' -#define LOG_HTTP_CF_TIMESTAMP 't' -#define LOG_HTTP_CF_TIMESTAMP_U 'z' -#define LOG_HTTP_CF_CLIENT_IP 'a' -#define LOG_HTTP_CF_SERVER_IP 'A' -#define LOG_HTTP_CF_CLIENT_PORT 'p' -#define LOG_HTTP_CF_SERVER_PORT 'P' - -typedef struct LogHttpCustomFormatNode_ { - uint32_t type; /** Node format type. ie: LOG_HTTP_CF_LITERAL, LOG_HTTP_CF_REQUEST_HEADER */ - uint32_t maxlen; /** Maximun length of the data */ - char data[LOG_HTTP_NODE_STRLEN]; /** optional data. ie: http header name */ -} LogHttpCustomFormatNode; - -typedef struct LogHttpFileCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ - uint32_t cf_n; /** Total number of custom string format nodes */ - LogHttpCustomFormatNode *cf_nodes[LOG_HTTP_MAXN_NODES]; /** Custom format string nodes */ -} LogHttpFileCtx; - -#define LOG_HTTP_DEFAULT 0 -#define LOG_HTTP_EXTENDED 1 -#define LOG_HTTP_CUSTOM 2 - -typedef struct LogHttpLogThread_ { - LogHttpFileCtx *httplog_ctx; - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - uint32_t uri_cnt; - - MemBuffer *buffer; -} LogHttpLogThread; - -/* Retrieves the selected cookie value */ -static uint32_t GetCookieValue(uint8_t *rawcookies, uint32_t rawcookies_len, char *cookiename, - uint8_t **cookievalue) -{ - uint8_t *p = rawcookies; - uint8_t *cn = p; /* ptr to cookie name start */ - uint8_t *cv = NULL; /* ptr to cookie value start */ - while (p < rawcookies + rawcookies_len) { - if (cv == NULL && *p == '=') { - cv = p + 1; - } else if (cv != NULL && (*p == ';' || p == rawcookies + rawcookies_len - 1) ) { - /* Found end of cookie */ - p++; - if (strlen(cookiename) == (unsigned int) (cv-cn-1) && - strncmp(cookiename, (char *) cn, cv-cn-1) == 0) { - *cookievalue = cv; - return (uint32_t) (p-cv); - } - cv = NULL; - cn = p + 1; - } - p++; - } - return 0; -} - -/* Custom format logging */ -static void LogHttpLogCustom(LogHttpLogThread *aft, htp_tx_t *tx, const struct timeval *ts, - char *srcip, Port sp, char *dstip, Port dp) -{ - LogHttpFileCtx *httplog_ctx = aft->httplog_ctx; - uint32_t i; - uint32_t datalen; - char buf[128]; - - uint8_t *cvalue = NULL; - uint32_t cvalue_len = 0; - - htp_header_t *h_request_hdr; - htp_header_t *h_response_hdr; - - time_t time = ts->tv_sec; - struct tm local_tm; - struct tm *timestamp = SCLocalTime(time, &local_tm); - - for (i = 0; i < httplog_ctx->cf_n; i++) { - h_request_hdr = NULL; - h_response_hdr = NULL; - switch (httplog_ctx->cf_nodes[i]->type){ - case LOG_HTTP_CF_LITERAL: - /* LITERAL */ - MemBufferWriteString(aft->buffer, "%s", httplog_ctx->cf_nodes[i]->data); - break; - case LOG_HTTP_CF_TIMESTAMP: - /* TIMESTAMP */ - if (httplog_ctx->cf_nodes[i]->data[0] == '\0') { - strftime(buf, 62, TIMESTAMP_DEFAULT_FORMAT, timestamp); - } else { - strftime(buf, 62, httplog_ctx->cf_nodes[i]->data, timestamp); - } - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)buf,strlen(buf)); - break; - case LOG_HTTP_CF_TIMESTAMP_U: - /* TIMESTAMP USECONDS */ - snprintf(buf, 62, "%06u", (unsigned int) ts->tv_usec); - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)buf,strlen(buf)); - break; - case LOG_HTTP_CF_CLIENT_IP: - /* CLIENT IP ADDRESS */ - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)srcip,strlen(srcip)); - break; - case LOG_HTTP_CF_SERVER_IP: - /* SERVER IP ADDRESS */ - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)dstip,strlen(dstip)); - break; - case LOG_HTTP_CF_CLIENT_PORT: - /* CLIENT PORT */ - MemBufferWriteString(aft->buffer, "%" PRIu16 "", sp); - break; - case LOG_HTTP_CF_SERVER_PORT: - /* SERVER PORT */ - MemBufferWriteString(aft->buffer, "%" PRIu16 "", dp); - break; - case LOG_HTTP_CF_REQUEST_METHOD: - /* METHOD */ - if (tx->request_method != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_method), - bstr_len(tx->request_method)); - } else { - MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); - } - break; - case LOG_HTTP_CF_REQUEST_URI: - /* URI */ - if (tx->request_uri != NULL) { - datalen = httplog_ctx->cf_nodes[i]->maxlen; - if (datalen == 0 || datalen > bstr_len(tx->request_uri)) { - datalen = bstr_len(tx->request_uri); - } - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_uri), - datalen); - } else { - MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); - } - break; - case LOG_HTTP_CF_REQUEST_HOST: - /* HOSTNAME */ - if (tx->request_hostname != NULL) - { - datalen = httplog_ctx->cf_nodes[i]->maxlen; - if (datalen == 0 || datalen > bstr_len(tx->request_hostname)) { - datalen = bstr_len(tx->request_hostname); - } - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_hostname), - datalen); - } else { - MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); - } - break; - case LOG_HTTP_CF_REQUEST_PROTOCOL: - /* PROTOCOL */ - if (tx->request_protocol != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_protocol), - bstr_len(tx->request_protocol)); - } else { - MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); - } - break; - case LOG_HTTP_CF_REQUEST_HEADER: - /* REQUEST HEADER */ - if (tx->request_headers != NULL) { - h_request_hdr = htp_table_get_c(tx->request_headers, httplog_ctx->cf_nodes[i]->data); - } - if (h_request_hdr != NULL) { - datalen = httplog_ctx->cf_nodes[i]->maxlen; - if (datalen == 0 || datalen > bstr_len(h_request_hdr->value)) { - datalen = bstr_len(h_request_hdr->value); - } - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)bstr_ptr(h_request_hdr->value), - datalen); - } else { - MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); - } - break; - case LOG_HTTP_CF_REQUEST_COOKIE: - /* REQUEST COOKIE */ - if (tx->request_headers != NULL) { - h_request_hdr = htp_table_get_c(tx->request_headers, "Cookie"); - if (h_request_hdr != NULL) { - cvalue_len = GetCookieValue((uint8_t *) bstr_ptr(h_request_hdr->value), - bstr_len(h_request_hdr->value), (char *) httplog_ctx->cf_nodes[i]->data, - &cvalue); - } - } - if (cvalue_len > 0 && cvalue != NULL) { - datalen = httplog_ctx->cf_nodes[i]->maxlen; - if (datalen == 0 || datalen > cvalue_len) { - datalen = cvalue_len; - } - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, cvalue, datalen); - } else { - MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); - } - break; - case LOG_HTTP_CF_REQUEST_LEN: - /* REQUEST LEN */ - MemBufferWriteString(aft->buffer, "%"PRIuMAX"", (uintmax_t)tx->request_message_len); - break; - case LOG_HTTP_CF_RESPONSE_STATUS: - /* RESPONSE STATUS */ - if (tx->response_status != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)bstr_ptr(tx->response_status), - bstr_len(tx->response_status)); - } else { - MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); - } - break; - case LOG_HTTP_CF_RESPONSE_HEADER: - /* RESPONSE HEADER */ - if (tx->response_headers != NULL) { - h_response_hdr = htp_table_get_c(tx->response_headers, - httplog_ctx->cf_nodes[i]->data); - } - if (h_response_hdr != NULL) { - datalen = httplog_ctx->cf_nodes[i]->maxlen; - if (datalen == 0 || datalen > bstr_len(h_response_hdr->value)) { - datalen = bstr_len(h_response_hdr->value); - } - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)bstr_ptr(h_response_hdr->value), - datalen); - } else { - MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); - } - break; - case LOG_HTTP_CF_RESPONSE_LEN: - /* RESPONSE LEN */ - MemBufferWriteString(aft->buffer, "%"PRIuMAX"", (uintmax_t)tx->response_message_len); - break; - default: - /* NO MATCH */ - MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE); - SCLogDebug("No matching parameter %%%c for custom http log.", httplog_ctx->cf_nodes[i]->type); - break; - } - } - MemBufferWriteString(aft->buffer, "\n"); -} - -static void LogHttpLogExtended(LogHttpLogThread *aft, htp_tx_t *tx) -{ - MemBufferWriteString(aft->buffer, " [**] "); - - /* referer */ - htp_header_t *h_referer = NULL; - if (tx->request_headers != NULL) { - h_referer = htp_table_get_c(tx->request_headers, "referer"); - } - if (h_referer != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)bstr_ptr(h_referer->value), - bstr_len(h_referer->value)); - } else { - MemBufferWriteString(aft->buffer, ""); - } - MemBufferWriteString(aft->buffer, " [**] "); - - /* method */ - if (tx->request_method != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)bstr_ptr(tx->request_method), - bstr_len(tx->request_method)); - } - MemBufferWriteString(aft->buffer, " [**] "); - - /* protocol */ - if (tx->request_protocol != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)bstr_ptr(tx->request_protocol), - bstr_len(tx->request_protocol)); - } else { - MemBufferWriteString(aft->buffer, ""); - } - MemBufferWriteString(aft->buffer, " [**] "); - - /* response status */ - if (tx->response_status != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)bstr_ptr(tx->response_status), - bstr_len(tx->response_status)); - /* Redirect? */ - if ((tx->response_status_number > 300) && ((tx->response_status_number) < 303)) { - htp_header_t *h_location = htp_table_get_c(tx->response_headers, "location"); - if (h_location != NULL) { - MemBufferWriteString(aft->buffer, " => "); - - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)bstr_ptr(h_location->value), - bstr_len(h_location->value)); - } - } - } else { - MemBufferWriteString(aft->buffer, ""); - } - - /* length */ - MemBufferWriteString(aft->buffer, " [**] %"PRIuMAX" bytes", (uintmax_t)tx->response_message_len); -} - -static TmEcode LogHttpLogIPWrapper(ThreadVars *tv, void *data, const Packet *p, Flow *f, HtpState *htp_state, htp_tx_t *tx, uint64_t tx_id, int ipproto) -{ - SCEnter(); - - LogHttpLogThread *aft = (LogHttpLogThread *)data; - LogHttpFileCtx *hlog = aft->httplog_ctx; - char timebuf[64]; - - /* check if we have HTTP state or not */ - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - char srcip[46], dstip[46]; - Port sp, dp; - if ((PKT_IS_TOSERVER(p))) { - switch (ipproto) { - case AF_INET: - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - break; - case AF_INET6: - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - break; - default: - goto end; - } - sp = p->sp; - dp = p->dp; - } else { - switch (ipproto) { - case AF_INET: - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip)); - break; - case AF_INET6: - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip)); - break; - default: - goto end; - } - sp = p->dp; - dp = p->sp; - } - - SCLogDebug("got a HTTP request and now logging !!"); - - /* reset */ - MemBufferReset(aft->buffer); - - if (hlog->flags & LOG_HTTP_CUSTOM) { - LogHttpLogCustom(aft, tx, &p->ts, srcip, sp, dstip, dp); - } else { - /* time */ - MemBufferWriteString(aft->buffer, "%s ", timebuf); - - /* hostname */ - if (tx->request_hostname != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)bstr_ptr(tx->request_hostname), - bstr_len(tx->request_hostname)); - } else { - MemBufferWriteString(aft->buffer, ""); - } - MemBufferWriteString(aft->buffer, " [**] "); - - /* uri */ - if (tx->request_uri != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)bstr_ptr(tx->request_uri), - bstr_len(tx->request_uri)); - } - MemBufferWriteString(aft->buffer, " [**] "); - - /* user agent */ - htp_header_t *h_user_agent = NULL; - if (tx->request_headers != NULL) { - h_user_agent = htp_table_get_c(tx->request_headers, "user-agent"); - } - if (h_user_agent != NULL) { - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size, - (uint8_t *)bstr_ptr(h_user_agent->value), - bstr_len(h_user_agent->value)); - } else { - MemBufferWriteString(aft->buffer, ""); - } - if (hlog->flags & LOG_HTTP_EXTENDED) { - LogHttpLogExtended(aft, tx); - } - - /* ip/tcp header info */ - MemBufferWriteString(aft->buffer, - " [**] %s:%" PRIu16 " -> %s:%" PRIu16 "\n", - srcip, sp, dstip, dp); - } - - aft->uri_cnt ++; - - SCMutexLock(&hlog->file_ctx->fp_mutex); - hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), - MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); - SCMutexUnlock(&hlog->file_ctx->fp_mutex); - -end: - SCReturnInt(0); - -} - -int LogHttpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) -{ - SCEnter(); - - if (!(PKT_IS_TCP(p))) { - SCReturnInt(TM_ECODE_OK); - } - - int r = 0; - if (PKT_IS_IPV4(p)) { - r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET); - } else if (PKT_IS_IPV6(p)) { - r = LogHttpLogIPWrapper(tv, thread_data, p, f, (HtpState *)state, (htp_tx_t *)tx, tx_id, AF_INET6); - } - - SCReturnInt(r); -} - -TmEcode LogHttpLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogHttpLogThread *aft = SCMalloc(sizeof(LogHttpLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(LogHttpLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for HTTPLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->httplog_ctx= ((OutputCtx *)initdata)->data; - - *data = (void *)aft; - return TM_ECODE_OK; -} - -TmEcode LogHttpLogThreadDeinit(ThreadVars *t, void *data) -{ - LogHttpLogThread *aft = (LogHttpLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(LogHttpLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -void LogHttpLogExitPrintStats(ThreadVars *tv, void *data) -{ - LogHttpLogThread *aft = (LogHttpLogThread *)data; - if (aft == NULL) { - return; - } - - SCLogInfo("HTTP logger logged %" PRIu32 " requests", aft->uri_cnt); -} - -/** \brief Create a new http log LogFileCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFileCtx* to the file_ctx if succesful - * */ -OutputCtx *LogHttpLogInitCtx(ConfNode *conf) -{ - LogFileCtx* file_ctx = LogFileNewCtx(); - const char *p, *np; - uint32_t n; - if(file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - LogHttpFileCtx *httplog_ctx = SCMalloc(sizeof(LogHttpFileCtx)); - if (unlikely(httplog_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - memset(httplog_ctx, 0x00, sizeof(LogHttpFileCtx)); - - httplog_ctx->file_ctx = file_ctx; - httplog_ctx->cf_n=0; - - const char *extended = ConfNodeLookupChildValue(conf, "extended"); - const char *custom = ConfNodeLookupChildValue(conf, "custom"); - const char *customformat = ConfNodeLookupChildValue(conf, "customformat"); - - /* If custom logging format is selected, lets parse it */ - if (custom != NULL && customformat != NULL && ConfValIsTrue(custom)) { - p=customformat; - httplog_ctx->flags |= LOG_HTTP_CUSTOM; - for (httplog_ctx->cf_n = 0; httplog_ctx->cf_n < LOG_HTTP_MAXN_NODES-1 && p && *p != '\0'; - httplog_ctx->cf_n++){ - httplog_ctx->cf_nodes[httplog_ctx->cf_n] = SCMalloc(sizeof(LogHttpCustomFormatNode)); - if (httplog_ctx->cf_nodes[httplog_ctx->cf_n] == NULL) { - for (n = 0; n < httplog_ctx->cf_n; n++) { - SCFree(httplog_ctx->cf_nodes[n]); - } - LogFileFreeCtx(file_ctx); - SCFree(httplog_ctx); - return NULL; - } - httplog_ctx->cf_nodes[httplog_ctx->cf_n]->maxlen = 0; - - if (*p != '%'){ - /* Literal found in format string */ - httplog_ctx->cf_nodes[httplog_ctx->cf_n]->type = LOG_HTTP_CF_LITERAL; - np = strchr(p, '%'); - if (np == NULL){ - n = LOG_HTTP_NODE_STRLEN-2; - np = NULL; /* End */ - }else{ - n = np-p; - } - strlcpy(httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data,p,n+1); - p = np; - } else { - /* Non Literal found in format string */ - p++; - if (*p == '[') { /* Check if maxlength has been specified (ie: [25]) */ - p++; - np = strchr(p, ']'); - if (np != NULL) { - if (np-p > 0 && np-p < 10){ - long maxlen = strtol(p,NULL,10); - if (maxlen > 0 && maxlen < LOG_HTTP_NODE_MAXOUTPUTLEN) { - httplog_ctx->cf_nodes[httplog_ctx->cf_n]->maxlen = (uint32_t) maxlen; - } - } else { - goto parsererror; - } - p = np + 1; - } else { - goto parsererror; - } - } - if (*p == '{') { /* Simple format char */ - np = strchr(p, '}'); - if (np != NULL && np-p > 1 && np-p < LOG_HTTP_NODE_STRLEN-2) { - p++; - n = np-p; - strlcpy(httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data, p, n+1); - p = np; - } else { - goto parsererror; - } - p++; - } else { - httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data[0] = '\0'; - } - httplog_ctx->cf_nodes[httplog_ctx->cf_n]->type = *p; - if (*p == '%'){ - httplog_ctx->cf_nodes[httplog_ctx->cf_n]->type = LOG_HTTP_CF_LITERAL; - strlcpy(httplog_ctx->cf_nodes[httplog_ctx->cf_n]->data, "%", 2); - } - p++; - } - } - } else { - if (extended == NULL) { - httplog_ctx->flags |= LOG_HTTP_DEFAULT; - } else { - if (ConfValIsTrue(extended)) { - httplog_ctx->flags |= LOG_HTTP_EXTENDED; - } - } - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - goto parsererror; - } - - output_ctx->data = httplog_ctx; - output_ctx->DeInit = LogHttpLogDeInitCtx; - - SCLogDebug("HTTP log output initialized"); - - /* enable the logger for the app layer */ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_HTTP); - - return output_ctx; - -parsererror: - for (n = 0;n < httplog_ctx->cf_n;n++) { - SCFree(httplog_ctx->cf_nodes[n]); - } - LogFileFreeCtx(file_ctx); - SCFree(httplog_ctx); - SCLogError(SC_ERR_INVALID_ARGUMENT,"Syntax error in custom http log format string."); - return NULL; - -} - -static void LogHttpLogDeInitCtx(OutputCtx *output_ctx) -{ - LogHttpFileCtx *httplog_ctx = (LogHttpFileCtx *)output_ctx->data; - uint32_t i; - for (i = 0; i < httplog_ctx->cf_n; i++) { - SCFree(httplog_ctx->cf_nodes[i]); - } - LogFileFreeCtx(httplog_ctx->file_ctx); - SCFree(httplog_ctx); - SCFree(output_ctx); -} diff --git a/framework/src/suricata/src/log-httplog.h b/framework/src/suricata/src/log-httplog.h deleted file mode 100644 index c02d0d9d..00000000 --- a/framework/src/suricata/src/log-httplog.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __LOG_HTTPLOG_H__ -#define __LOG_HTTPLOG_H__ - -void TmModuleLogHttpLogRegister (void); -void TmModuleLogHttpLogIPv4Register (void); -void TmModuleLogHttpLogIPv6Register (void); -OutputCtx *LogHttpLogInitCtx(ConfNode *); - -#endif /* __LOG_HTTPLOG_H__ */ - diff --git a/framework/src/suricata/src/log-pcap.c b/framework/src/suricata/src/log-pcap.c deleted file mode 100644 index 21d41e8b..00000000 --- a/framework/src/suricata/src/log-pcap.c +++ /dev/null @@ -1,1197 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - - -/** - * \file - * - * \author William Metcalf - * \author Victor Julien - * - * Pcap packet logging module. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "log-pcap.h" -#include "decode-ipv4.h" - -#include "util-error.h" -#include "util-debug.h" -#include "util-time.h" -#include "util-byte.h" -#include "util-misc.h" -#include "util-cpu.h" -#include "util-atomic.h" - -#include "source-pcap.h" - -#include "output.h" - -#include "queue.h" - -#define DEFAULT_LOG_FILENAME "pcaplog" -#define MODULE_NAME "PcapLog" -#define MIN_LIMIT 1 * 1024 * 1024 -#define DEFAULT_LIMIT 100 * 1024 * 1024 -#define DEFAULT_FILE_LIMIT 0 - -#define LOGMODE_NORMAL 0 -#define LOGMODE_SGUIL 1 -#define LOGMODE_MULTI 2 - -#define RING_BUFFER_MODE_DISABLED 0 -#define RING_BUFFER_MODE_ENABLED 1 - -#define TS_FORMAT_SEC 0 -#define TS_FORMAT_USEC 1 - -#define USE_STREAM_DEPTH_DISABLED 0 -#define USE_STREAM_DEPTH_ENABLED 1 - -#define HONOR_PASS_RULES_DISABLED 0 -#define HONOR_PASS_RULES_ENABLED 1 - -SC_ATOMIC_DECLARE(uint32_t, thread_cnt); - -typedef struct PcapFileName_ { - char *filename; - char *dirname; - TAILQ_ENTRY(PcapFileName_) next; /**< Pointer to next Pcap File for tailq. */ -} PcapFileName; - -typedef struct PcapLogProfileData_ { - uint64_t total; - uint64_t cnt; -} PcapLogProfileData; - -#define MAX_TOKS 9 - -/** - * PcapLog thread vars - * - * Used for storing file options. - */ -typedef struct PcapLogData_ { - int use_stream_depth; /**< use stream depth i.e. ignore packets that reach limit */ - int honor_pass_rules; /**< don't log if pass rules have matched */ - int is_private; /**< TRUE if ctx is thread local */ - SCMutex plog_lock; - uint64_t pkt_cnt; /**< total number of packets */ - struct pcap_pkthdr *h; /**< pcap header struct */ - char *filename; /**< current filename */ - int mode; /**< normal or sguil */ - int prev_day; /**< last day, for finding out when */ - uint64_t size_current; /**< file current size */ - uint64_t size_limit; /**< file size limit */ - pcap_t *pcap_dead_handle; /**< pcap_dumper_t needs a handle */ - pcap_dumper_t *pcap_dumper; /**< actually writes the packets */ - uint64_t profile_data_size; /**< track in bytes how many bytes we wrote */ - uint32_t file_cnt; /**< count of pcap files we currently have */ - uint32_t max_files; /**< maximum files to use in ring buffer mode */ - - PcapLogProfileData profile_lock; - PcapLogProfileData profile_write; - PcapLogProfileData profile_unlock; - PcapLogProfileData profile_handles; // open handles - PcapLogProfileData profile_close; - PcapLogProfileData profile_open; - PcapLogProfileData profile_rotate; - - TAILQ_HEAD(, PcapFileName_) pcap_file_list; - - uint32_t thread_number; /**< thread number, first thread is 1, second 2, etc */ - int use_ringbuffer; /**< ring buffer mode enabled or disabled */ - int timestamp_format; /**< timestamp format sec or usec */ - char *prefix; /**< filename prefix */ - char dir[PATH_MAX]; /**< pcap log directory */ - int reported; - int threads; /**< number of threads (only set in the global) */ - char *filename_parts[MAX_TOKS]; - int filename_part_cnt; -} PcapLogData; - -typedef struct PcapLogThreadData_ { - PcapLogData *pcap_log; -} PcapLogThreadData; - -/* global pcap data for when we're using multi mode. At exit we'll - * merge counters into this one and then report counters. */ -static PcapLogData *g_pcap_data = NULL; - -static int PcapLogOpenFileCtx(PcapLogData *); -static TmEcode PcapLog(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -static TmEcode PcapLogDataInit(ThreadVars *, void *, void **); -static TmEcode PcapLogDataDeinit(ThreadVars *, void *); -static void PcapLogFileDeInitCtx(OutputCtx *); -static OutputCtx *PcapLogInitCtx(ConfNode *); -static void PcapLogProfilingDump(PcapLogData *); - -void TmModulePcapLogRegister(void) -{ - tmm_modules[TMM_PCAPLOG].name = MODULE_NAME; - tmm_modules[TMM_PCAPLOG].ThreadInit = PcapLogDataInit; - tmm_modules[TMM_PCAPLOG].Func = PcapLog; - tmm_modules[TMM_PCAPLOG].ThreadDeinit = PcapLogDataDeinit; - tmm_modules[TMM_PCAPLOG].RegisterTests = NULL; - - OutputRegisterModule(MODULE_NAME, "pcap-log", PcapLogInitCtx); - - SC_ATOMIC_INIT(thread_cnt); - return; -} - -#define PCAPLOG_PROFILE_START \ - uint64_t pcaplog_profile_ticks = UtilCpuGetTicks() - -#define PCAPLOG_PROFILE_END(prof) \ - (prof).total += (UtilCpuGetTicks() - pcaplog_profile_ticks); \ - (prof).cnt++ - -/** - * \brief Function to close pcaplog file - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param pl PcapLog thread variable. - */ -static int PcapLogCloseFile(ThreadVars *t, PcapLogData *pl) -{ - if (pl != NULL) { - PCAPLOG_PROFILE_START; - - if (pl->pcap_dumper != NULL) - pcap_dump_close(pl->pcap_dumper); - pl->size_current = 0; - pl->pcap_dumper = NULL; - - if (pl->pcap_dead_handle != NULL) - pcap_close(pl->pcap_dead_handle); - pl->pcap_dead_handle = NULL; - - PCAPLOG_PROFILE_END(pl->profile_close); - } - - return 0; -} - -static void PcapFileNameFree(PcapFileName *pf) -{ - if (pf != NULL) { - if (pf->filename != NULL) { - SCFree(pf->filename); - } - if (pf->dirname != NULL) { - SCFree(pf->dirname); - } - SCFree(pf); - } - - return; -} - -/** - * \brief Function to rotate pcaplog file - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param pl PcapLog thread variable. - * - * \retval 0 on succces - * \retval -1 on failure - */ -static int PcapLogRotateFile(ThreadVars *t, PcapLogData *pl) -{ - PcapFileName *pf; - PcapFileName *pfnext; - - PCAPLOG_PROFILE_START; - - if (PcapLogCloseFile(t,pl) < 0) { - SCLogDebug("PcapLogCloseFile failed"); - return -1; - } - - if (pl->use_ringbuffer == RING_BUFFER_MODE_ENABLED && pl->file_cnt >= pl->max_files) { - pf = TAILQ_FIRST(&pl->pcap_file_list); - SCLogDebug("Removing pcap file %s", pf->filename); - - if (remove(pf->filename) != 0) { - // VJ remove can fail because file is already gone - //LogWarning(SC_ERR_PCAP_FILE_DELETE_FAILED, - // "failed to remove log file %s: %s", - // pf->filename, strerror( errno )); - } - - /* Remove directory if Sguil mode and no files left in sguil dir */ - if (pl->mode == LOGMODE_SGUIL) { - pfnext = TAILQ_NEXT(pf,next); - - if (strcmp(pf->dirname, pfnext->dirname) == 0) { - SCLogDebug("Current entry dir %s and next entry %s " - "are equal: not removing dir", - pf->dirname, pfnext->dirname); - } else { - SCLogDebug("current entry %s and %s are " - "not equal: removing dir", - pf->dirname, pfnext->dirname); - - if (remove(pf->dirname) != 0) { - SCLogWarning(SC_ERR_PCAP_FILE_DELETE_FAILED, - "failed to remove sguil log %s: %s", - pf->dirname, strerror( errno )); - } - } - } - - TAILQ_REMOVE(&pl->pcap_file_list, pf, next); - PcapFileNameFree(pf); - pl->file_cnt--; - } - - if (PcapLogOpenFileCtx(pl) < 0) { - SCLogError(SC_ERR_FOPEN, "opening new pcap log file failed"); - return -1; - } - pl->file_cnt++; - SCLogDebug("file_cnt %u", pl->file_cnt); - - PCAPLOG_PROFILE_END(pl->profile_rotate); - return 0; -} - -static int PcapLogOpenHandles(PcapLogData *pl, Packet *p) -{ - PCAPLOG_PROFILE_START; - - SCLogDebug("Setting pcap-log link type to %u", p->datalink); - - if (pl->pcap_dead_handle == NULL) { - if ((pl->pcap_dead_handle = pcap_open_dead(p->datalink, - -1)) == NULL) { - SCLogDebug("Error opening dead pcap handle"); - return TM_ECODE_FAILED; - } - } - - if (pl->pcap_dumper == NULL) { - if ((pl->pcap_dumper = pcap_dump_open(pl->pcap_dead_handle, - pl->filename)) == NULL) { - SCLogInfo("Error opening dump file %s", pcap_geterr(pl->pcap_dead_handle)); - return TM_ECODE_FAILED; - } - } - - PCAPLOG_PROFILE_END(pl->profile_handles); - return TM_ECODE_OK; -} - -/** \internal - * \brief lock wrapper for main PcapLog() function - * NOTE: only meant for use in main PcapLog() function. - */ -static void PcapLogLock(PcapLogData *pl) -{ - if (!(pl->is_private)) { - PCAPLOG_PROFILE_START; - SCMutexLock(&pl->plog_lock); - PCAPLOG_PROFILE_END(pl->profile_lock); - } -} - -/** \internal - * \brief unlock wrapper for main PcapLog() function - * NOTE: only meant for use in main PcapLog() function. - */ -static void PcapLogUnlock(PcapLogData *pl) -{ - if (!(pl->is_private)) { - PCAPLOG_PROFILE_START; - SCMutexUnlock(&pl->plog_lock); - PCAPLOG_PROFILE_END(pl->profile_unlock); - } -} - -/** - * \brief Pcap logging main function - * - * \param t threadvar - * \param p packet - * \param data thread module specific data - * \param pq pre-packet-queue - * \param postpq post-packet-queue - * - * \retval TM_ECODE_OK on succes - * \retval TM_ECODE_FAILED on serious error - */ -static TmEcode PcapLog (ThreadVars *t, Packet *p, void *thread_data, PacketQueue *pq, - PacketQueue *postpq) -{ - size_t len; - int rotate = 0; - int ret = 0; - - PcapLogThreadData *td = (PcapLogThreadData *)thread_data; - PcapLogData *pl = td->pcap_log; - - if ((p->flags & PKT_PSEUDO_STREAM_END) || - ((p->flags & PKT_STREAM_NOPCAPLOG) && - (pl->use_stream_depth == USE_STREAM_DEPTH_ENABLED)) || - (IS_TUNNEL_PKT(p) && !IS_TUNNEL_ROOT_PKT(p)) || - (pl->honor_pass_rules && (p->flags & PKT_NOPACKET_INSPECTION))) - { - return TM_ECODE_OK; - } - - PcapLogLock(pl); - - pl->pkt_cnt++; - pl->h->ts.tv_sec = p->ts.tv_sec; - pl->h->ts.tv_usec = p->ts.tv_usec; - pl->h->caplen = GET_PKT_LEN(p); - pl->h->len = GET_PKT_LEN(p); - len = sizeof(*pl->h) + GET_PKT_LEN(p); - - if (pl->filename == NULL) { - ret = PcapLogOpenFileCtx(pl); - if (ret < 0) { - PcapLogUnlock(pl); - return TM_ECODE_FAILED; - } - SCLogDebug("Opening PCAP log file %s", pl->filename); - } - - if (pl->mode == LOGMODE_SGUIL) { - struct tm local_tm; - struct tm *tms = SCLocalTime(p->ts.tv_sec, &local_tm); - if (tms->tm_mday != pl->prev_day) { - rotate = 1; - pl->prev_day = tms->tm_mday; - } - } - - if ((pl->size_current + len) > pl->size_limit || rotate) { - if (PcapLogRotateFile(t,pl) < 0) { - PcapLogUnlock(pl); - SCLogDebug("rotation of pcap failed"); - return TM_ECODE_FAILED; - } - } - - /* XXX pcap handles, nfq, pfring, can only have one link type ipfw? we do - * this here as we don't know the link type until we get our first packet */ - if (pl->pcap_dead_handle == NULL || pl->pcap_dumper == NULL) { - if (PcapLogOpenHandles(pl, p) != TM_ECODE_OK) { - PcapLogUnlock(pl); - return TM_ECODE_FAILED; - } - } - - PCAPLOG_PROFILE_START; - pcap_dump((u_char *)pl->pcap_dumper, pl->h, GET_PKT_DATA(p)); - pl->size_current += len; - PCAPLOG_PROFILE_END(pl->profile_write); - pl->profile_data_size += len; - - SCLogDebug("pl->size_current %"PRIu64", pl->size_limit %"PRIu64, - pl->size_current, pl->size_limit); - - PcapLogUnlock(pl); - return TM_ECODE_OK; -} - -static PcapLogData *PcapLogDataCopy(const PcapLogData *pl) -{ - BUG_ON(pl->mode != LOGMODE_MULTI); - PcapLogData *copy = SCCalloc(1, sizeof(*copy)); - if (unlikely(copy == NULL)) { - return NULL; - } - - copy->h = SCCalloc(1, sizeof(*copy->h)); - if (unlikely(copy->h == NULL)) { - SCFree(copy); - return NULL; - } - - copy->prefix = SCStrdup(pl->prefix); - if (unlikely(copy->prefix == NULL)) { - SCFree(copy->h); - SCFree(copy); - return NULL; - } - - /* settings TODO move to global cfg struct */ - copy->is_private = TRUE; - copy->mode = pl->mode; - copy->max_files = pl->max_files; - copy->use_ringbuffer = pl->use_ringbuffer; - copy->timestamp_format = pl->timestamp_format; - copy->use_stream_depth = pl->use_stream_depth; - copy->size_limit = pl->size_limit; - - TAILQ_INIT(©->pcap_file_list); - SCMutexInit(©->plog_lock, NULL); - - strlcpy(copy->dir, pl->dir, sizeof(copy->dir)); - - int i; - for (i = 0; i < pl->filename_part_cnt && i < MAX_TOKS; i++) - copy->filename_parts[i] = pl->filename_parts[i]; - copy->filename_part_cnt = pl->filename_part_cnt; - - /* set thread number, first thread is 1 */ - copy->thread_number = SC_ATOMIC_ADD(thread_cnt, 1); - - SCLogDebug("copied, returning %p", copy); - return copy; -} - -static TmEcode PcapLogDataInit(ThreadVars *t, void *initdata, void **data) -{ - if (initdata == NULL) { - SCLogDebug("Error getting context for PcapLog. \"initdata\" argument NULL"); - return TM_ECODE_FAILED; - } - - PcapLogData *pl = ((OutputCtx *)initdata)->data; - - PcapLogThreadData *td = SCCalloc(1, sizeof(*td)); - if (unlikely(td == NULL)) - return TM_ECODE_FAILED; - - if (pl->mode == LOGMODE_MULTI) - td->pcap_log = PcapLogDataCopy(pl); - else - td->pcap_log = pl; - BUG_ON(td->pcap_log == NULL); - - PcapLogLock(td->pcap_log); - - /** Use the Ouptut Context (file pointer and mutex) */ - td->pcap_log->pkt_cnt = 0; - td->pcap_log->pcap_dead_handle = NULL; - td->pcap_log->pcap_dumper = NULL; - td->pcap_log->file_cnt = 1; - - struct timeval ts; - memset(&ts, 0x00, sizeof(struct timeval)); - TimeGet(&ts); - struct tm local_tm; - struct tm *tms = SCLocalTime(ts.tv_sec, &local_tm); - td->pcap_log->prev_day = tms->tm_mday; - - PcapLogUnlock(td->pcap_log); - - /* count threads in the global structure */ - SCMutexLock(&pl->plog_lock); - pl->threads++; - SCMutexUnlock(&pl->plog_lock); - - *data = (void *)td; - - return TM_ECODE_OK; -} - -static void StatsMerge(PcapLogData *dst, PcapLogData *src) -{ - dst->profile_open.total += src->profile_open.total; - dst->profile_open.cnt += src->profile_open.cnt; - - dst->profile_close.total += src->profile_close.total; - dst->profile_close.cnt += src->profile_close.cnt; - - dst->profile_write.total += src->profile_write.total; - dst->profile_write.cnt += src->profile_write.cnt; - - dst->profile_rotate.total += src->profile_rotate.total; - dst->profile_rotate.cnt += src->profile_rotate.cnt; - - dst->profile_handles.total += src->profile_handles.total; - dst->profile_handles.cnt += src->profile_handles.cnt; - - dst->profile_lock.total += src->profile_lock.total; - dst->profile_lock.cnt += src->profile_lock.cnt; - - dst->profile_unlock.total += src->profile_unlock.total; - dst->profile_unlock.cnt += src->profile_unlock.cnt; - - dst->profile_data_size += src->profile_data_size; -} - -/** - * \brief Thread deinit function. - * - * \param t Thread Variable containing input/output queue, cpu affinity etc. - * \param data PcapLog thread data. - * \retval TM_ECODE_OK on succces - * \retval TM_ECODE_FAILED on failure - */ -static TmEcode PcapLogDataDeinit(ThreadVars *t, void *thread_data) -{ - PcapLogThreadData *td = (PcapLogThreadData *)thread_data; - PcapLogData *pl = td->pcap_log; - - if (pl->pcap_dumper != NULL) { - if (PcapLogCloseFile(t,pl) < 0) { - SCLogDebug("PcapLogCloseFile failed"); - } - } - - if (pl->mode == LOGMODE_MULTI) { - SCMutexLock(&g_pcap_data->plog_lock); - StatsMerge(g_pcap_data, pl); - g_pcap_data->reported++; - if (g_pcap_data->threads == g_pcap_data->reported) - PcapLogProfilingDump(g_pcap_data); - SCMutexUnlock(&g_pcap_data->plog_lock); - } else { - if (pl->reported == 0) { - PcapLogProfilingDump(pl); - pl->reported = 1; - } - } - return TM_ECODE_OK; -} - -static int ParseFilename(PcapLogData *pl, const char *filename) -{ - char *toks[MAX_TOKS] = { NULL }; - int tok = 0; - char str[512] = ""; - int s = 0; - int i, x; - char *p = NULL; - - if (filename) { - for (i = 0; i < (int)strlen(filename); i++) { - if (tok >= MAX_TOKS) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "invalid filename option. Max 2 %%-sign options"); - goto error; - } - - str[s++] = filename[i]; - - if (filename[i] == '%') { - str[s-1] = '\0'; - SCLogDebug("filename with %%-sign: %s", str); - - p = SCStrdup(str); - if (p == NULL) - goto error; - toks[tok++] = p; - - s = 0; - - if (i+1 < (int)strlen(filename)) { - if (tok >= MAX_TOKS) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "invalid filename option. Max 2 %%-sign options"); - goto error; - } - - if (filename[i+1] != 'n' && filename[i+1] != 't' && filename[i+1] != 'i') { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "invalid filename option. Valid %%-sign options: %%n, %%i and %%t"); - goto error; - } - str[0] = '%'; - str[1] = filename[i+1]; - str[2] = '\0'; - p = SCStrdup(str); - if (p == NULL) - goto error; - toks[tok++] = p; - i++; - } - } - } - if (s) { - if (tok >= MAX_TOKS) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "invalid filename option. Max 3 %%-sign options"); - goto error; - - } - str[s++] = '\0'; - p = SCStrdup(str); - if (p == NULL) - goto error; - toks[tok++] = p; - } - - /* finally, store tokens in the pl */ - for (i = 0; i < tok; i++) { - if (toks[i] == NULL) - goto error; - - SCLogDebug("toks[%d] %s", i, toks[i]); - pl->filename_parts[i] = toks[i]; - } - pl->filename_part_cnt = tok; - } - return 0; -error: - for (x = 0; x < MAX_TOKS; x++) { - if (toks[x] != NULL) - SCFree(toks[x]); - } - return -1; -} - -/** \brief Fill in pcap logging struct from the provided ConfNode. - * \param conf The configuration node for this output. - * \retval output_ctx - * */ -static OutputCtx *PcapLogInitCtx(ConfNode *conf) -{ - PcapLogData *pl = SCMalloc(sizeof(PcapLogData)); - if (unlikely(pl == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate Memory for PcapLogData"); - exit(EXIT_FAILURE); - } - memset(pl, 0, sizeof(PcapLogData)); - - pl->h = SCMalloc(sizeof(*pl->h)); - if (pl->h == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, - "Failed to allocate Memory for pcap header struct"); - exit(EXIT_FAILURE); - } - - /* Set the defaults */ - pl->mode = LOGMODE_NORMAL; - pl->max_files = DEFAULT_FILE_LIMIT; - pl->use_ringbuffer = RING_BUFFER_MODE_DISABLED; - pl->timestamp_format = TS_FORMAT_SEC; - pl->use_stream_depth = USE_STREAM_DEPTH_DISABLED; - pl->honor_pass_rules = HONOR_PASS_RULES_DISABLED; - - TAILQ_INIT(&pl->pcap_file_list); - - SCMutexInit(&pl->plog_lock, NULL); - - /* conf params */ - - const char *filename = NULL; - - if (conf != NULL) { /* To faciliate unit tests. */ - filename = ConfNodeLookupChildValue(conf, "filename"); - } - - if (filename == NULL) - filename = DEFAULT_LOG_FILENAME; - - if ((pl->prefix = SCStrdup(filename)) == NULL) { - exit(EXIT_FAILURE); - } - - if (filename) { - if (ParseFilename(pl, filename) != 0) - exit(EXIT_FAILURE); - } - - pl->size_limit = DEFAULT_LIMIT; - if (conf != NULL) { - const char *s_limit = NULL; - s_limit = ConfNodeLookupChildValue(conf, "limit"); - if (s_limit != NULL) { - if (ParseSizeStringU64(s_limit, &pl->size_limit) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Failed to initialize unified2 output, invalid limit: %s", - s_limit); - exit(EXIT_FAILURE); - } - if (pl->size_limit < 4096) { - SCLogInfo("pcap-log \"limit\" value of %"PRIu64" assumed to be pre-1.2 " - "style: setting limit to %"PRIu64"mb", pl->size_limit, pl->size_limit); - uint64_t size = pl->size_limit * 1024 * 1024; - pl->size_limit = size; - } else if (pl->size_limit < MIN_LIMIT) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Fail to initialize pcap-log output, limit less than " - "allowed minimum."); - exit(EXIT_FAILURE); - } - } - } - - if (conf != NULL) { - const char *s_mode = NULL; - s_mode = ConfNodeLookupChildValue(conf, "mode"); - if (s_mode != NULL) { - if (strcasecmp(s_mode, "sguil") == 0) { - pl->mode = LOGMODE_SGUIL; - } else if (strcasecmp(s_mode, "multi") == 0) { - pl->mode = LOGMODE_MULTI; - } else if (strcasecmp(s_mode, "normal") != 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "log-pcap: invalid mode \"%s\". Valid options: \"normal\", " - "\"sguil\", or \"multi\" mode ", s_mode); - exit(EXIT_FAILURE); - } - } - - const char *s_dir = NULL; - s_dir = ConfNodeLookupChildValue(conf, "dir"); - if (s_dir == NULL) { - s_dir = ConfNodeLookupChildValue(conf, "sguil-base-dir"); - } - if (s_dir == NULL) { - if (pl->mode == LOGMODE_SGUIL) { - SCLogError(SC_ERR_LOGPCAP_SGUIL_BASE_DIR_MISSING, - "log-pcap \"sguil\" mode requires \"sguil-base-dir\" " - "option to be set."); - exit(EXIT_FAILURE); - } else { - char *log_dir = NULL; - log_dir = ConfigGetLogDirectory(); - - strlcpy(pl->dir, - log_dir, sizeof(pl->dir)); - SCLogInfo("Using log dir %s", pl->dir); - } - } else { - if (PathIsAbsolute(s_dir)) { - strlcpy(pl->dir, - s_dir, sizeof(pl->dir)); - } else { - char *log_dir = NULL; - log_dir = ConfigGetLogDirectory(); - - snprintf(pl->dir, sizeof(pl->dir), "%s/%s", - log_dir, s_dir); - } - - struct stat stat_buf; - if (stat(pl->dir, &stat_buf) != 0) { - SCLogError(SC_ERR_LOGDIR_CONFIG, "The sguil-base-dir directory \"%s\" " - "supplied doesn't exist. Shutting down the engine", - pl->dir); - exit(EXIT_FAILURE); - } - SCLogInfo("Using log dir %s", pl->dir); - } - } - - SCLogInfo("using %s logging", pl->mode == LOGMODE_SGUIL ? - "Sguil compatible" : (pl->mode == LOGMODE_MULTI ? "multi" : "normal")); - - uint32_t max_file_limit = DEFAULT_FILE_LIMIT; - if (conf != NULL) { - const char *max_number_of_files_s = NULL; - max_number_of_files_s = ConfNodeLookupChildValue(conf, "max-files"); - if (max_number_of_files_s != NULL) { - if (ByteExtractStringUint32(&max_file_limit, 10, 0, - max_number_of_files_s) == -1) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize " - "pcap-log output, invalid number of files limit: %s", - max_number_of_files_s); - exit(EXIT_FAILURE); - } else if (max_file_limit < 1) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Failed to initialize pcap-log output, limit less than " - "allowed minimum."); - exit(EXIT_FAILURE); - } else { - pl->max_files = max_file_limit; - pl->use_ringbuffer = RING_BUFFER_MODE_ENABLED; - } - } - } - - const char *ts_format = NULL; - if (conf != NULL) { /* To faciliate unit tests. */ - ts_format = ConfNodeLookupChildValue(conf, "ts-format"); - } - if (ts_format != NULL) { - if (strcasecmp(ts_format, "usec") == 0) { - pl->timestamp_format = TS_FORMAT_USEC; - } else if (strcasecmp(ts_format, "sec") != 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "log-pcap ts_format specified %s is invalid must be" - " \"sec\" or \"usec\"", ts_format); - exit(EXIT_FAILURE); - } - } - - const char *use_stream_depth = NULL; - if (conf != NULL) { /* To faciliate unit tests. */ - use_stream_depth = ConfNodeLookupChildValue(conf, "use-stream-depth"); - } - if (use_stream_depth != NULL) { - if (ConfValIsFalse(use_stream_depth)) { - pl->use_stream_depth = USE_STREAM_DEPTH_DISABLED; - } else if (ConfValIsTrue(use_stream_depth)) { - pl->use_stream_depth = USE_STREAM_DEPTH_ENABLED; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "log-pcap use_stream_depth specified is invalid must be"); - exit(EXIT_FAILURE); - } - } - - const char *honor_pass_rules = NULL; - if (conf != NULL) { /* To faciliate unit tests. */ - honor_pass_rules = ConfNodeLookupChildValue(conf, "honor-pass-rules"); - } - if (honor_pass_rules != NULL) { - if (ConfValIsFalse(honor_pass_rules)) { - pl->honor_pass_rules = HONOR_PASS_RULES_DISABLED; - } else if (ConfValIsTrue(honor_pass_rules)) { - pl->honor_pass_rules = HONOR_PASS_RULES_ENABLED; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "log-pcap honor-pass-rules specified is invalid"); - exit(EXIT_FAILURE); - } - } - - /* create the output ctx and send it back */ - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for OutputCtx."); - exit(EXIT_FAILURE); - } - output_ctx->data = pl; - output_ctx->DeInit = PcapLogFileDeInitCtx; - g_pcap_data = pl; - - return output_ctx; -} - -static void PcapLogFileDeInitCtx(OutputCtx *output_ctx) -{ - if (output_ctx == NULL) - return; - - PcapLogData *pl = output_ctx->data; - - PcapFileName *pf = NULL; - TAILQ_FOREACH(pf, &pl->pcap_file_list, next) { - SCLogDebug("PCAP files left at exit: %s\n", pf->filename); - } - - return; -} - -/** - * \brief Read the config set the file pointer, open the file - * - * \param PcapLogData. - * - * \retval -1 if failure - * \retval 0 if succesful - */ -static int PcapLogOpenFileCtx(PcapLogData *pl) -{ - char *filename = NULL; - - PCAPLOG_PROFILE_START; - - if (pl->filename != NULL) - filename = pl->filename; - else { - filename = SCMalloc(PATH_MAX); - if (unlikely(filename == NULL)) { - return -1; - } - pl->filename = filename; - } - - /** get the time so we can have a filename with seconds since epoch */ - struct timeval ts; - memset(&ts, 0x00, sizeof(struct timeval)); - TimeGet(&ts); - - /* Place to store the name of our PCAP file */ - PcapFileName *pf = SCMalloc(sizeof(PcapFileName)); - if (unlikely(pf == NULL)) { - return -1; - } - memset(pf, 0, sizeof(PcapFileName)); - - if (pl->mode == LOGMODE_SGUIL) { - struct tm local_tm; - struct tm *tms = SCLocalTime(ts.tv_sec, &local_tm); - - char dirname[32], dirfull[PATH_MAX] = ""; - - snprintf(dirname, sizeof(dirname), "%04d-%02d-%02d", - tms->tm_year + 1900, tms->tm_mon + 1, tms->tm_mday); - - /* create the filename to use */ - snprintf(dirfull, PATH_MAX, "%s/%s", pl->dir, dirname); - - /* if mkdir fails file open will fail, so deal with errors there */ -#ifndef OS_WIN32 - (void)mkdir(dirfull, 0700); -#else - (void)mkdir(dirfull); -#endif - if ((pf->dirname = SCStrdup(dirfull)) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for " - "directory name"); - goto error; - } - - if (pl->timestamp_format == TS_FORMAT_SEC) { - snprintf(filename, PATH_MAX, "%s/%s.%" PRIu32, dirfull, - pl->prefix, (uint32_t)ts.tv_sec); - } else { - snprintf(filename, PATH_MAX, "%s/%s.%" PRIu32 ".%" PRIu32, - dirfull, pl->prefix, (uint32_t)ts.tv_sec, (uint32_t)ts.tv_usec); - } - - } else if (pl->mode == LOGMODE_NORMAL) { - /* create the filename to use */ - if (pl->timestamp_format == TS_FORMAT_SEC) { - snprintf(filename, PATH_MAX, "%s/%s.%" PRIu32, pl->dir, - pl->prefix, (uint32_t)ts.tv_sec); - } else { - snprintf(filename, PATH_MAX, "%s/%s.%" PRIu32 ".%" PRIu32, pl->dir, - pl->prefix, (uint32_t)ts.tv_sec, (uint32_t)ts.tv_usec); - } - } else if (pl->mode == LOGMODE_MULTI) { - if (pl->filename_part_cnt > 0) { - /* assemble filename from stored tokens */ - - strlcpy(filename, pl->dir, PATH_MAX); - strlcat(filename, "/", PATH_MAX); - - int i; - for (i = 0; i < pl->filename_part_cnt; i++) { - if (pl->filename_parts[i] == NULL ||strlen(pl->filename_parts[i]) == 0) - continue; - - /* handle variables */ - if (pl->filename_parts[i][0] == '%') { - char str[64] = ""; - if (strlen(pl->filename_parts[i]) < 2) - continue; - - switch(pl->filename_parts[i][1]) { - case 'n': - snprintf(str, sizeof(str), "%u", pl->thread_number); - break; - case 'i': - { - long thread_id = SCGetThreadIdLong(); - snprintf(str, sizeof(str), "%"PRIu64, (uint64_t)thread_id); - break; - } - case 't': - /* create the filename to use */ - if (pl->timestamp_format == TS_FORMAT_SEC) { - snprintf(str, sizeof(str), "%"PRIu32, (uint32_t)ts.tv_sec); - } else { - snprintf(str, sizeof(str), "%"PRIu32".%"PRIu32, - (uint32_t)ts.tv_sec, (uint32_t)ts.tv_usec); - } - } - strlcat(filename, str, PATH_MAX); - - /* copy the rest over */ - } else { - strlcat(filename, pl->filename_parts[i], PATH_MAX); - } - } - } else { - /* create the filename to use */ - if (pl->timestamp_format == TS_FORMAT_SEC) { - snprintf(filename, PATH_MAX, "%s/%s.%u.%" PRIu32, pl->dir, - pl->prefix, pl->thread_number, (uint32_t)ts.tv_sec); - } else { - snprintf(filename, PATH_MAX, "%s/%s.%u.%" PRIu32 ".%" PRIu32, pl->dir, - pl->prefix, pl->thread_number, (uint32_t)ts.tv_sec, (uint32_t)ts.tv_usec); - } - } - SCLogDebug("multi-mode: filename %s", filename); - } - - if ((pf->filename = SCStrdup(pl->filename)) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory. For filename"); - goto error; - } - SCLogDebug("Opening pcap file log %s", pf->filename); - TAILQ_INSERT_TAIL(&pl->pcap_file_list, pf, next); - - PCAPLOG_PROFILE_END(pl->profile_open); - return 0; - -error: - PcapFileNameFree(pf); - return -1; -} - -static int profiling_pcaplog_enabled = 0; -static int profiling_pcaplog_output_to_file = 0; -static char *profiling_pcaplog_file_name = NULL; -static char *profiling_pcaplog_file_mode = "a"; - -static void FormatNumber(uint64_t num, char *str, size_t size) -{ - if (num < 1000UL) - snprintf(str, size, "%"PRIu64, num); - else if (num < 1000000UL) - snprintf(str, size, "%3.1fk", (float)num/1000UL); - else if (num < 1000000000UL) - snprintf(str, size, "%3.1fm", (float)num/1000000UL); - else - snprintf(str, size, "%3.1fb", (float)num/1000000000UL); -} - -static void ProfileReportPair(FILE *fp, const char *name, PcapLogProfileData *p) -{ - char ticks_str[32] = "n/a"; - char cnt_str[32] = "n/a"; - char avg_str[32] = "n/a"; - - FormatNumber((uint64_t)p->cnt, cnt_str, sizeof(cnt_str)); - FormatNumber((uint64_t)p->total, ticks_str, sizeof(ticks_str)); - if (p->cnt && p->total) - FormatNumber((uint64_t)(p->total/p->cnt), avg_str, sizeof(avg_str)); - - fprintf(fp, "%-28s %-10s %-10s %-10s\n", name, cnt_str, avg_str, ticks_str); -} - -static void ProfileReport(FILE *fp, PcapLogData *pl) -{ - ProfileReportPair(fp, "open", &pl->profile_open); - ProfileReportPair(fp, "close", &pl->profile_close); - ProfileReportPair(fp, "write", &pl->profile_write); - ProfileReportPair(fp, "rotate (incl open/close)", &pl->profile_rotate); - ProfileReportPair(fp, "handles", &pl->profile_handles); - ProfileReportPair(fp, "lock", &pl->profile_lock); - ProfileReportPair(fp, "unlock", &pl->profile_unlock); -} - -static void FormatBytes(uint64_t num, char *str, size_t size) -{ - if (num < 1000UL) - snprintf(str, size, "%"PRIu64, num); - else if (num < 1048576UL) - snprintf(str, size, "%3.1fKiB", (float)num/1000UL); - else if (num < 1073741824UL) - snprintf(str, size, "%3.1fMiB", (float)num/1000000UL); - else - snprintf(str, size, "%3.1fGiB", (float)num/1000000000UL); -} - -static void PcapLogProfilingDump(PcapLogData *pl) -{ - FILE *fp = NULL; - - if (profiling_pcaplog_enabled == 0) - return; - - if (profiling_pcaplog_output_to_file == 1) { - fp = fopen(profiling_pcaplog_file_name, profiling_pcaplog_file_mode); - if (fp == NULL) { - SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", - profiling_pcaplog_file_name, strerror(errno)); - return; - } - } else { - fp = stdout; - } - - /* counters */ - fprintf(fp, "\n\nOperation Cnt Avg ticks Total ticks\n"); - fprintf(fp, "---------------------------- ---------- ---------- -----------\n"); - - ProfileReport(fp, pl); - uint64_t total = pl->profile_write.total + pl->profile_rotate.total + - pl->profile_handles.total + pl->profile_open.total + - pl->profile_close.total + pl->profile_lock.total + - pl->profile_unlock.total; - - /* overall stats */ - fprintf(fp, "\nOverall: %"PRIu64" bytes written, average %d bytes per write.\n", - pl->profile_data_size, (int)(pl->profile_data_size / pl->profile_write.cnt)); - fprintf(fp, " PCAP data structure overhead: %"PRIuMAX" per write.\n", - (uintmax_t)sizeof(struct pcap_pkthdr)); - - /* print total bytes written */ - char bytes_str[32]; - FormatBytes(pl->profile_data_size, bytes_str, sizeof(bytes_str)); - fprintf(fp, " Size written: %s\n", bytes_str); - - /* ticks per MiB and GiB */ - uint64_t ticks_per_mib = 0, ticks_per_gib = 0; - uint64_t mib = pl->profile_data_size/(1024*1024); - if (mib) - ticks_per_mib = total/mib; - char ticks_per_mib_str[32] = "n/a"; - if (ticks_per_mib > 0) - FormatNumber(ticks_per_mib, ticks_per_mib_str, sizeof(ticks_per_mib_str)); - fprintf(fp, " Ticks per MiB: %s\n", ticks_per_mib_str); - - uint64_t gib = pl->profile_data_size/(1024*1024*1024); - if (gib) - ticks_per_gib = total/gib; - char ticks_per_gib_str[32] = "n/a"; - if (ticks_per_gib > 0) - FormatNumber(ticks_per_gib, ticks_per_gib_str, sizeof(ticks_per_gib_str)); - fprintf(fp, " Ticks per GiB: %s\n", ticks_per_gib_str); - - if (fp != stdout) - fclose(fp); -} - -void PcapLogProfileSetup(void) -{ - ConfNode *conf = ConfGetNode("profiling.pcap-log"); - if (conf != NULL && ConfNodeChildValueIsTrue(conf, "enabled")) { - profiling_pcaplog_enabled = 1; - SCLogInfo("pcap-log profiling enabled"); - - const char *filename = ConfNodeLookupChildValue(conf, "filename"); - if (filename != NULL) { - char *log_dir; - log_dir = ConfigGetLogDirectory(); - - profiling_pcaplog_file_name = SCMalloc(PATH_MAX); - if (unlikely(profiling_pcaplog_file_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name"); - exit(EXIT_FAILURE); - } - - snprintf(profiling_pcaplog_file_name, PATH_MAX, "%s/%s", log_dir, filename); - - const char *v = ConfNodeLookupChildValue(conf, "append"); - if (v == NULL || ConfValIsTrue(v)) { - profiling_pcaplog_file_mode = "a"; - } else { - profiling_pcaplog_file_mode = "w"; - } - - profiling_pcaplog_output_to_file = 1; - SCLogInfo("pcap-log profiling output goes to %s (mode %s)", - profiling_pcaplog_file_name, profiling_pcaplog_file_mode); - } - } -} diff --git a/framework/src/suricata/src/log-pcap.h b/framework/src/suricata/src/log-pcap.h deleted file mode 100644 index 0c6e7011..00000000 --- a/framework/src/suricata/src/log-pcap.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - - -/** - * \file - * - * \author William Metcalf - * \author Victor Julien - * - * Pcap packet logging module. - */ - -#ifndef __LOG_PCAP_H__ -#define __LOG_PCAP_H__ - -void TmModulePcapLogRegister (void); -void PcapLogProfileSetup(void); - -#endif /* __LOG_PCAP_H__ */ diff --git a/framework/src/suricata/src/log-stats.c b/framework/src/suricata/src/log-stats.c deleted file mode 100644 index 5fcb1c9f..00000000 --- a/framework/src/suricata/src/log-stats.c +++ /dev/null @@ -1,288 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "log-stats.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" -#include "util-time.h" - -#define DEFAULT_LOG_FILENAME "stats.log" -#define MODULE_NAME "LogStatsLog" -#define OUTPUT_BUFFER_SIZE 16384 - -#define LOG_STATS_TOTALS (1<<0) -#define LOG_STATS_THREADS (1<<1) - -TmEcode LogStatsLogThreadInit(ThreadVars *, void *, void **); -TmEcode LogStatsLogThreadDeinit(ThreadVars *, void *); -void LogStatsLogExitPrintStats(ThreadVars *, void *); -static void LogStatsLogDeInitCtx(OutputCtx *); - -typedef struct LogStatsFileCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ -} LogStatsFileCtx; - -typedef struct LogStatsLogThread_ { - LogStatsFileCtx *statslog_ctx; - MemBuffer *buffer; -} LogStatsLogThread; - -int LogStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *st) -{ - SCEnter(); - LogStatsLogThread *aft = (LogStatsLogThread *)thread_data; - - struct timeval tval; - struct tm *tms; - - gettimeofday(&tval, NULL); - struct tm local_tm; - tms = SCLocalTime(tval.tv_sec, &local_tm); - - /* Calculate the Engine uptime */ - int up_time = (int)difftime(tval.tv_sec, st->start_time); - int sec = up_time % 60; // Seconds in a minute - int in_min = up_time / 60; - int min = in_min % 60; // Minutes in a hour - int in_hours = in_min / 60; - int hours = in_hours % 24; // Hours in a day - int days = in_hours / 24; - - MemBufferWriteString(aft->buffer, "----------------------------------------------" - "---------------------\n"); - MemBufferWriteString(aft->buffer, "Date: %" PRId32 "/%" PRId32 "/%04d -- " - "%02d:%02d:%02d (uptime: %"PRId32"d, %02dh %02dm %02ds)\n", - tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, tms->tm_hour, - tms->tm_min, tms->tm_sec, days, hours, min, sec); - MemBufferWriteString(aft->buffer, "----------------------------------------------" - "---------------------\n"); - MemBufferWriteString(aft->buffer, "%-25s | %-25s | %-s\n", "Counter", "TM Name", - "Value"); - MemBufferWriteString(aft->buffer, "----------------------------------------------" - "---------------------\n"); - - /* global stats */ - uint32_t u = 0; - if (aft->statslog_ctx->flags & LOG_STATS_TOTALS) { - for (u = 0; u < st->nstats; u++) { - if (st->stats[u].name == NULL) - continue; - - char line[1024]; - size_t len = snprintf(line, sizeof(line), "%-25s | %-25s | %-" PRIu64 "\n", - st->stats[u].name, st->stats[u].tm_name, st->stats[u].value); - - /* since we can have many threads, the buffer might not be big enough. - * Expand if necessary. */ - if (MEMBUFFER_OFFSET(aft->buffer) + len > MEMBUFFER_SIZE(aft->buffer)) { - MemBufferExpand(&aft->buffer, OUTPUT_BUFFER_SIZE); - } - - MemBufferWriteString(aft->buffer, "%s", line); - } - } - - /* per thread stats */ - if (st->tstats != NULL && aft->statslog_ctx->flags & LOG_STATS_THREADS) { - /* for each thread (store) */ - uint32_t x; - for (x = 0; x < st->ntstats; x++) { - uint32_t offset = x * st->nstats; - - /* for each counter */ - for (u = offset; u < (offset + st->nstats); u++) { - if (st->tstats[u].name == NULL) - continue; - - char line[1024]; - size_t len = snprintf(line, sizeof(line), "%-25s | %-25s | %-" PRIu64 "\n", - st->tstats[u].name, st->tstats[u].tm_name, st->tstats[u].value); - - /* since we can have many threads, the buffer might not be big enough. - * Expand if necessary. */ - if (MEMBUFFER_OFFSET(aft->buffer) + len > MEMBUFFER_SIZE(aft->buffer)) { - MemBufferExpand(&aft->buffer, OUTPUT_BUFFER_SIZE); - } - - MemBufferWriteString(aft->buffer, "%s", line); - } - } - } - - SCMutexLock(&aft->statslog_ctx->file_ctx->fp_mutex); - aft->statslog_ctx->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), - MEMBUFFER_OFFSET(aft->buffer), aft->statslog_ctx->file_ctx); - SCMutexUnlock(&aft->statslog_ctx->file_ctx->fp_mutex); - - MemBufferReset(aft->buffer); - - SCReturnInt(0); -} - -TmEcode LogStatsLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogStatsLogThread *aft = SCMalloc(sizeof(LogStatsLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(LogStatsLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for HTTPLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->statslog_ctx= ((OutputCtx *)initdata)->data; - - *data = (void *)aft; - return TM_ECODE_OK; -} - -TmEcode LogStatsLogThreadDeinit(ThreadVars *t, void *data) -{ - LogStatsLogThread *aft = (LogStatsLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(LogStatsLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -void LogStatsLogExitPrintStats(ThreadVars *tv, void *data) -{ - LogStatsLogThread *aft = (LogStatsLogThread *)data; - if (aft == NULL) { - return; - } -} - -/** \brief Create a new http log LogFileCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFileCtx* to the file_ctx if succesful - * */ -OutputCtx *LogStatsLogInitCtx(ConfNode *conf) -{ - LogFileCtx *file_ctx = LogFileNewCtx(); - if (file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - LogStatsFileCtx *statslog_ctx = SCMalloc(sizeof(LogStatsFileCtx)); - if (unlikely(statslog_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - memset(statslog_ctx, 0x00, sizeof(LogStatsFileCtx)); - - statslog_ctx->flags = LOG_STATS_TOTALS; - - if (conf != NULL) { - const char *totals = ConfNodeLookupChildValue(conf, "totals"); - const char *threads = ConfNodeLookupChildValue(conf, "threads"); - SCLogDebug("totals %s threads %s", totals, threads); - - if (totals != NULL && ConfValIsFalse(totals)) { - statslog_ctx->flags &= ~LOG_STATS_TOTALS; - } - if (threads != NULL && ConfValIsTrue(threads)) { - statslog_ctx->flags |= LOG_STATS_THREADS; - } - SCLogDebug("statslog_ctx->flags %08x", statslog_ctx->flags); - } - - statslog_ctx->file_ctx = file_ctx; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(statslog_ctx); - return NULL; - } - - output_ctx->data = statslog_ctx; - output_ctx->DeInit = LogStatsLogDeInitCtx; - - SCLogDebug("STATS log output initialized"); - - return output_ctx; -} - -static void LogStatsLogDeInitCtx(OutputCtx *output_ctx) -{ - LogStatsFileCtx *statslog_ctx = (LogStatsFileCtx *)output_ctx->data; - LogFileFreeCtx(statslog_ctx->file_ctx); - SCFree(statslog_ctx); - SCFree(output_ctx); -} - -void TmModuleLogStatsLogRegister (void) -{ - tmm_modules[TMM_LOGSTATSLOG].name = MODULE_NAME; - tmm_modules[TMM_LOGSTATSLOG].ThreadInit = LogStatsLogThreadInit; - tmm_modules[TMM_LOGSTATSLOG].ThreadExitPrintStats = LogStatsLogExitPrintStats; - tmm_modules[TMM_LOGSTATSLOG].ThreadDeinit = LogStatsLogThreadDeinit; - tmm_modules[TMM_LOGSTATSLOG].RegisterTests = NULL; - tmm_modules[TMM_LOGSTATSLOG].cap_flags = 0; - tmm_modules[TMM_LOGSTATSLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterStatsModule(MODULE_NAME, "stats", LogStatsLogInitCtx, LogStatsLogger); -} diff --git a/framework/src/suricata/src/log-stats.h b/framework/src/suricata/src/log-stats.h deleted file mode 100644 index 957104f3..00000000 --- a/framework/src/suricata/src/log-stats.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __LOG_STATS_H__ -#define __LOG_STATS_H__ - -void TmModuleLogStatsLogRegister (void); - -#endif /* __LOG_HTTPLOG_H__ */ diff --git a/framework/src/suricata/src/log-tcp-data.c b/framework/src/suricata/src/log-tcp-data.c deleted file mode 100644 index c41dd4c2..00000000 --- a/framework/src/suricata/src/log-tcp-data.c +++ /dev/null @@ -1,345 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "log-tcp-data.h" -#include "app-layer-htp.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" -#include "util-time.h" - -#define DEFAULT_LOG_FILENAME "tcp-data.log" - -#define MODULE_NAME "LogTcpDataLog" - -#define OUTPUT_BUFFER_SIZE 65535 - -TmEcode LogTcpDataLogThreadInit(ThreadVars *, void *, void **); -TmEcode LogTcpDataLogThreadDeinit(ThreadVars *, void *); -void LogTcpDataLogExitPrintStats(ThreadVars *, void *); -static void LogTcpDataLogDeInitCtx(OutputCtx *); - -int LogTcpDataLogger(ThreadVars *tv, void *thread_data, const Flow *f, const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags); - -void TmModuleLogTcpDataLogRegister (void) { - tmm_modules[TMM_LOGTCPDATALOG].name = MODULE_NAME; - tmm_modules[TMM_LOGTCPDATALOG].ThreadInit = LogTcpDataLogThreadInit; - tmm_modules[TMM_LOGTCPDATALOG].ThreadExitPrintStats = LogTcpDataLogExitPrintStats; - tmm_modules[TMM_LOGTCPDATALOG].ThreadDeinit = LogTcpDataLogThreadDeinit; - tmm_modules[TMM_LOGTCPDATALOG].RegisterTests = NULL; - tmm_modules[TMM_LOGTCPDATALOG].cap_flags = 0; - tmm_modules[TMM_LOGTCPDATALOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterStreamingModule(MODULE_NAME, "tcp-data", LogTcpDataLogInitCtx, - LogTcpDataLogger, STREAMING_TCP_DATA); - OutputRegisterStreamingModule(MODULE_NAME, "http-body-data", LogTcpDataLogInitCtx, - LogTcpDataLogger, STREAMING_HTTP_BODIES); -} - -typedef struct LogTcpDataFileCtx_ { - LogFileCtx *file_ctx; - enum OutputStreamingType type; - const char *log_dir; - int file; - int dir; -} LogTcpDataFileCtx; - -typedef struct LogTcpDataLogThread_ { - LogTcpDataFileCtx *tcpdatalog_ctx; - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - MemBuffer *buffer; -} LogTcpDataLogThread; - -static int LogTcpDataLoggerDir(ThreadVars *tv, void *thread_data, const Flow *f, - const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags) -{ - SCEnter(); - LogTcpDataLogThread *aft = thread_data; - LogTcpDataFileCtx *td = aft->tcpdatalog_ctx; - char *mode = "a"; - - if (flags & OUTPUT_STREAMING_FLAG_OPEN) - mode = "w"; - - if (data && data_len) { - char srcip[46] = "", dstip[46] = ""; - if (FLOW_IS_IPV4(f)) { - PrintInet(AF_INET, (const void *)&f->src.addr_data32[0], srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)&f->dst.addr_data32[0], dstip, sizeof(dstip)); - } else if (FLOW_IS_IPV6(f)) { - PrintInet(AF_INET6, (const void *)f->src.addr_data32, srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)f->dst.addr_data32, dstip, sizeof(dstip)); - } - - char name[PATH_MAX]; - - char tx[64] = ""; - if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION) - snprintf(tx, sizeof(tx), "%"PRIu64, tx_id); - - snprintf(name, sizeof(name), "%s/%s/%s_%u-%s_%u-%s-%s.data", - td->log_dir, - td->type == STREAMING_HTTP_BODIES ? "http" : "tcp", - srcip, f->sp, dstip, f->dp, tx, - flags & OUTPUT_STREAMING_FLAG_TOSERVER ? "ts" : "tc"); - - FILE *fp = fopen(name, mode); - BUG_ON(fp == NULL); - - // PrintRawDataFp(stdout, (uint8_t *)data, data_len); - fwrite(data, data_len, 1, fp); - - fclose(fp); - } - SCReturnInt(TM_ECODE_OK); -} - -static int LogTcpDataLoggerFile(ThreadVars *tv, void *thread_data, const Flow *f, - const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags) -{ - SCEnter(); - LogTcpDataLogThread *aft = thread_data; - LogTcpDataFileCtx *td = aft->tcpdatalog_ctx; - - if (data && data_len) { - MemBufferReset(aft->buffer); - - char srcip[46] = "", dstip[46] = ""; - if (FLOW_IS_IPV4(f)) { - PrintInet(AF_INET, (const void *)&f->src.addr_data32[0], srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)&f->dst.addr_data32[0], dstip, sizeof(dstip)); - } else if (FLOW_IS_IPV6(f)) { - PrintInet(AF_INET6, (const void *)f->src.addr_data32, srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)f->dst.addr_data32, dstip, sizeof(dstip)); - } - - char name[PATH_MAX]; - snprintf(name, sizeof(name), "%s_%u-%s_%u-%s:", - srcip, f->sp, dstip, f->dp, - flags & OUTPUT_STREAMING_FLAG_TOSERVER ? "ts" : "tc"); - - PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)name,strlen(name)); - MemBufferWriteString(aft->buffer, "\n"); - - PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, - aft->buffer->size, (uint8_t *)data,data_len); - - SCMutexLock(&td->file_ctx->fp_mutex); - td->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), - MEMBUFFER_OFFSET(aft->buffer), td->file_ctx); - SCMutexUnlock(&td->file_ctx->fp_mutex); - } - SCReturnInt(TM_ECODE_OK); -} - -int LogTcpDataLogger(ThreadVars *tv, void *thread_data, const Flow *f, - const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags) -{ - SCEnter(); - LogTcpDataLogThread *aft = thread_data; - LogTcpDataFileCtx *td = aft->tcpdatalog_ctx; - - if (td->dir == 1) - LogTcpDataLoggerDir(tv, thread_data, f, data, data_len, tx_id, flags); - if (td->file == 1) - LogTcpDataLoggerFile(tv, thread_data, f, data, data_len, tx_id, flags); - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode LogTcpDataLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogTcpDataLogThread *aft = SCMalloc(sizeof(LogTcpDataLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(LogTcpDataLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->tcpdatalog_ctx= ((OutputCtx *)initdata)->data; - - *data = (void *)aft; - return TM_ECODE_OK; -} - -TmEcode LogTcpDataLogThreadDeinit(ThreadVars *t, void *data) -{ - LogTcpDataLogThread *aft = (LogTcpDataLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(LogTcpDataLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -void LogTcpDataLogExitPrintStats(ThreadVars *tv, void *data) { - LogTcpDataLogThread *aft = (LogTcpDataLogThread *)data; - if (aft == NULL) { - return; - } -} - -/** \brief Create a new http log LogFileCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFileCtx* to the file_ctx if succesful - * */ -OutputCtx *LogTcpDataLogInitCtx(ConfNode *conf) -{ - char filename[PATH_MAX] = ""; - char dirname[32] = ""; - strlcpy(filename, DEFAULT_LOG_FILENAME, sizeof(filename)); - - LogFileCtx *file_ctx = LogFileNewCtx(); - if(file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - LogTcpDataFileCtx *tcpdatalog_ctx = SCMalloc(sizeof(LogTcpDataFileCtx)); - if (unlikely(tcpdatalog_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - memset(tcpdatalog_ctx, 0x00, sizeof(LogTcpDataFileCtx)); - - tcpdatalog_ctx->file_ctx = file_ctx; - - if (conf) { - if (conf->name) { - if (strcmp(conf->name, "tcp-data") == 0) { - tcpdatalog_ctx->type = STREAMING_TCP_DATA; - snprintf(filename, sizeof(filename), "%s.log", conf->name); - strlcpy(dirname, "tcp", sizeof(dirname)); - } else if (strcmp(conf->name, "http-body-data") == 0) { - tcpdatalog_ctx->type = STREAMING_HTTP_BODIES; - snprintf(filename, sizeof(filename), "%s.log", conf->name); - strlcpy(dirname, "http", sizeof(dirname)); - } - } - - const char *logtype = ConfNodeLookupChildValue(conf, "type"); - if (logtype == NULL) - logtype = "file"; - - if (strcmp(logtype, "file") == 0) { - tcpdatalog_ctx->file = 1; - } else if (strcmp(logtype, "dir") == 0) { - tcpdatalog_ctx->dir = 1; - } else if (strcmp(logtype, "both") == 0) { - tcpdatalog_ctx->file = 1; - tcpdatalog_ctx->dir = 1; - } - } else { - tcpdatalog_ctx->file = 1; - tcpdatalog_ctx->dir = 0; - } - - if (tcpdatalog_ctx->file == 1) { - SCLogInfo("opening logfile"); - if (SCConfLogOpenGeneric(conf, file_ctx, filename, 1) < 0) { - LogFileFreeCtx(file_ctx); - SCFree(tcpdatalog_ctx); - return NULL; - } - } - - if (tcpdatalog_ctx->dir == 1) { - tcpdatalog_ctx->log_dir = ConfigGetLogDirectory(); - char dirfull[PATH_MAX]; - - /* create the filename to use */ - snprintf(dirfull, PATH_MAX, "%s/%s", tcpdatalog_ctx->log_dir, dirname); - - SCLogInfo("using directory %s", dirfull); - - /* if mkdir fails file open will fail, so deal with errors there */ -#ifndef OS_WIN32 - (void)mkdir(dirfull, 0700); -#else - (void)mkdir(dirfull); -#endif - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - goto parsererror; - } - - output_ctx->data = tcpdatalog_ctx; - output_ctx->DeInit = LogTcpDataLogDeInitCtx; - - SCLogDebug("Streaming log output initialized"); - return output_ctx; - -parsererror: - LogFileFreeCtx(file_ctx); - SCFree(tcpdatalog_ctx); - SCLogError(SC_ERR_INVALID_ARGUMENT,"Syntax error in custom http log format string."); - return NULL; - -} - -static void LogTcpDataLogDeInitCtx(OutputCtx *output_ctx) -{ - LogTcpDataFileCtx *tcpdatalog_ctx = (LogTcpDataFileCtx *)output_ctx->data; - LogFileFreeCtx(tcpdatalog_ctx->file_ctx); - SCFree(tcpdatalog_ctx); - SCFree(output_ctx); -} diff --git a/framework/src/suricata/src/log-tcp-data.h b/framework/src/suricata/src/log-tcp-data.h deleted file mode 100644 index 5123c3b2..00000000 --- a/framework/src/suricata/src/log-tcp-data.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __LOG_TCPDATALOG_H__ -#define __LOG_TCPDATALOG_H__ - -void TmModuleLogTcpDataLogRegister (void); -OutputCtx *LogTcpDataLogInitCtx(ConfNode *); - -#endif /* __LOG_TCPDATALOG_H__ */ diff --git a/framework/src/suricata/src/log-tlslog.c b/framework/src/suricata/src/log-tlslog.c deleted file mode 100644 index 53ebad8b..00000000 --- a/framework/src/suricata/src/log-tlslog.c +++ /dev/null @@ -1,396 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Roliers Jean-Paul - * \author Eric Leblond - * \author Victor Julien - * - * Implements TLS logging portion of the engine. The TLS logger is - * implemented as a packet logger, as the TLS parser is not transaction - * aware. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "log-tlslog.h" -#include "app-layer-ssl.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" -#include "util-crypt.h" -#include "util-time.h" - -#define DEFAULT_LOG_FILENAME "tls.log" - -#define MODULE_NAME "LogTlsLog" - -#define OUTPUT_BUFFER_SIZE 65535 -#define CERT_ENC_BUFFER_SIZE 2048 - -#define LOG_TLS_DEFAULT 0 -#define LOG_TLS_EXTENDED 1 - -typedef struct LogTlsFileCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ -} LogTlsFileCtx; - -typedef struct LogTlsLogThread_ { - LogTlsFileCtx *tlslog_ctx; - - /** LogTlsFileCtx has the pointer to the file and a mutex to allow multithreading */ - uint32_t tls_cnt; - - MemBuffer *buffer; -} LogTlsLogThread; - -static void LogTlsLogExtended(LogTlsLogThread *aft, SSLState * state) -{ - if (state->server_connp.cert0_fingerprint != NULL) { - MemBufferWriteString(aft->buffer, " SHA1='%s'", state->server_connp.cert0_fingerprint); - } - if (state->client_connp.sni != NULL) { - MemBufferWriteString(aft->buffer, " SNI='%s'", state->client_connp.sni); - } - switch (state->server_connp.version) { - case TLS_VERSION_UNKNOWN: - MemBufferWriteString(aft->buffer, " VERSION='UNDETERMINED'"); - break; - case SSL_VERSION_2: - MemBufferWriteString(aft->buffer, " VERSION='SSLv2'"); - break; - case SSL_VERSION_3: - MemBufferWriteString(aft->buffer, " VERSION='SSLv3'"); - break; - case TLS_VERSION_10: - MemBufferWriteString(aft->buffer, " VERSION='TLSv1'"); - break; - case TLS_VERSION_11: - MemBufferWriteString(aft->buffer, " VERSION='TLS 1.1'"); - break; - case TLS_VERSION_12: - MemBufferWriteString(aft->buffer, " VERSION='TLS 1.2'"); - break; - default: - MemBufferWriteString(aft->buffer, " VERSION='0x%04x'", - state->server_connp.version); - break; - } - MemBufferWriteString(aft->buffer, "\n"); -} - -int TLSGetIPInformations(const Packet *p, char* srcip, size_t srcip_len, - Port* sp, char* dstip, size_t dstip_len, - Port* dp, int ipproto) -{ - if ((PKT_IS_TOSERVER(p))) { - switch (ipproto) { - case AF_INET: - PrintInet(AF_INET, (const void *) GET_IPV4_SRC_ADDR_PTR(p), srcip, srcip_len); - PrintInet(AF_INET, (const void *) GET_IPV4_DST_ADDR_PTR(p), dstip, dstip_len); - break; - case AF_INET6: - PrintInet(AF_INET6, (const void *) GET_IPV6_SRC_ADDR(p), srcip, srcip_len); - PrintInet(AF_INET6, (const void *) GET_IPV6_DST_ADDR(p), dstip, dstip_len); - break; - default: - return 0; - } - *sp = p->sp; - *dp = p->dp; - } else { - switch (ipproto) { - case AF_INET: - PrintInet(AF_INET, (const void *) GET_IPV4_DST_ADDR_PTR(p), srcip, srcip_len); - PrintInet(AF_INET, (const void *) GET_IPV4_SRC_ADDR_PTR(p), dstip, dstip_len); - break; - case AF_INET6: - PrintInet(AF_INET6, (const void *) GET_IPV6_DST_ADDR(p), srcip, srcip_len); - PrintInet(AF_INET6, (const void *) GET_IPV6_SRC_ADDR(p), dstip, dstip_len); - break; - default: - return 0; - } - *sp = p->dp; - *dp = p->sp; - } - return 1; -} - -static TmEcode LogTlsLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogTlsLogThread *aft = SCMalloc(sizeof(LogTlsLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(LogTlsLogThread)); - - if (initdata == NULL) { - SCLogDebug( "Error getting context for TLSLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->tlslog_ctx = ((OutputCtx *) initdata)->data; - - *data = (void *) aft; - return TM_ECODE_OK; -} - -static TmEcode LogTlsLogThreadDeinit(ThreadVars *t, void *data) -{ - LogTlsLogThread *aft = (LogTlsLogThread *) data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(LogTlsLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void LogTlsLogDeInitCtx(OutputCtx *output_ctx) -{ - OutputTlsLoggerDisable(); - - LogTlsFileCtx *tlslog_ctx = (LogTlsFileCtx *) output_ctx->data; - LogFileFreeCtx(tlslog_ctx->file_ctx); - SCFree(tlslog_ctx); - SCFree(output_ctx); -} - -static void LogTlsLogExitPrintStats(ThreadVars *tv, void *data) -{ - LogTlsLogThread *aft = (LogTlsLogThread *) data; - if (aft == NULL) { - return; - } - - SCLogInfo("TLS logger logged %" PRIu32 " requests", aft->tls_cnt); -} - -/** \brief Create a new tls log LogFileCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFileCtx* to the file_ctx if succesful - * */ -static OutputCtx *LogTlsLogInitCtx(ConfNode *conf) -{ - if (OutputTlsLoggerEnable() != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'tls' logger " - "can be enabled"); - return NULL; - } - - LogFileCtx* file_ctx = LogFileNewCtx(); - - if (file_ctx == NULL) { - SCLogError(SC_ERR_TLS_LOG_GENERIC, "LogTlsLogInitCtx: Couldn't " - "create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - goto filectx_error; - } - - LogTlsFileCtx *tlslog_ctx = SCCalloc(1, sizeof(LogTlsFileCtx)); - if (unlikely(tlslog_ctx == NULL)) - goto filectx_error; - tlslog_ctx->file_ctx = file_ctx; - - const char *extended = ConfNodeLookupChildValue(conf, "extended"); - if (extended == NULL) { - tlslog_ctx->flags |= LOG_TLS_DEFAULT; - } else { - if (ConfValIsTrue(extended)) { - tlslog_ctx->flags |= LOG_TLS_EXTENDED; - } - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) - goto tlslog_error; - output_ctx->data = tlslog_ctx; - output_ctx->DeInit = LogTlsLogDeInitCtx; - - SCLogDebug("TLS log output initialized"); - - /* enable the logger for the app layer */ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_TLS); - - return output_ctx; - -tlslog_error: - SCFree(tlslog_ctx); -filectx_error: - LogFileFreeCtx(file_ctx); - return NULL; -} - -/** \internal - * \brief Condition function for TLS logger - * \retval bool true or false -- log now? - */ -static int LogTlsCondition(ThreadVars *tv, const Packet *p) -{ - if (p->flow == NULL) { - return FALSE; - } - - if (!(PKT_IS_TCP(p))) { - return FALSE; - } - - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_TLS) - goto dontlog; - - SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); - if (ssl_state == NULL) { - SCLogDebug("no tls state, so no request logging"); - goto dontlog; - } - - /* we only log the state once if we don't have to write - * the cert due to tls.store keyword. */ - if (!(ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) && - (ssl_state->flags & SSL_AL_FLAG_STATE_LOGGED)) - goto dontlog; - - if (ssl_state->server_connp.cert0_issuerdn == NULL || - ssl_state->server_connp.cert0_subject == NULL) - goto dontlog; - - /* todo: logic to log once */ - - FLOWLOCK_UNLOCK(p->flow); - return TRUE; -dontlog: - FLOWLOCK_UNLOCK(p->flow); - return FALSE; -} - -static int LogTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - LogTlsLogThread *aft = (LogTlsLogThread *)thread_data; - LogTlsFileCtx *hlog = aft->tlslog_ctx; - char timebuf[64]; - int ipproto = (PKT_IS_IPV4(p)) ? AF_INET : AF_INET6; - - if (unlikely(p->flow == NULL)) { - return 0; - } - - /* check if we have TLS state or not */ - FLOWLOCK_WRLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_TLS) - goto end; - - SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); - if (unlikely(ssl_state == NULL)) { - goto end; - } - - if (ssl_state->server_connp.cert0_issuerdn == NULL || ssl_state->server_connp.cert0_subject == NULL) - goto end; - - /* Don't log again the state. If we are here it was because we had - * to store the cert. */ - if (ssl_state->flags & SSL_AL_FLAG_STATE_LOGGED) - goto end; - - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); -#define PRINT_BUF_LEN 46 - char srcip[PRINT_BUF_LEN], dstip[PRINT_BUF_LEN]; - Port sp, dp; - if (!TLSGetIPInformations(p, srcip, PRINT_BUF_LEN, - &sp, dstip, PRINT_BUF_LEN, &dp, ipproto)) { - goto end; - } - - MemBufferReset(aft->buffer); - MemBufferWriteString(aft->buffer, - "%s %s:%d -> %s:%d TLS: Subject='%s' Issuerdn='%s'", - timebuf, srcip, sp, dstip, dp, - ssl_state->server_connp.cert0_subject, - ssl_state->server_connp.cert0_issuerdn); - - if (hlog->flags & LOG_TLS_EXTENDED) { - LogTlsLogExtended(aft, ssl_state); - } else { - MemBufferWriteString(aft->buffer, "\n"); - } - - aft->tls_cnt++; - - SCMutexLock(&hlog->file_ctx->fp_mutex); - hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), - MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); - SCMutexUnlock(&hlog->file_ctx->fp_mutex); - - /* we only log the state once */ - ssl_state->flags |= SSL_AL_FLAG_STATE_LOGGED; -end: - FLOWLOCK_UNLOCK(p->flow); - return 0; -} - -void TmModuleLogTlsLogRegister(void) -{ - tmm_modules[TMM_LOGTLSLOG].name = MODULE_NAME; - tmm_modules[TMM_LOGTLSLOG].ThreadInit = LogTlsLogThreadInit; - tmm_modules[TMM_LOGTLSLOG].Func = NULL; - tmm_modules[TMM_LOGTLSLOG].ThreadExitPrintStats = LogTlsLogExitPrintStats; - tmm_modules[TMM_LOGTLSLOG].ThreadDeinit = LogTlsLogThreadDeinit; - tmm_modules[TMM_LOGTLSLOG].RegisterTests = NULL; - tmm_modules[TMM_LOGTLSLOG].cap_flags = 0; - tmm_modules[TMM_LOGTLSLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterPacketModule(MODULE_NAME, "tls-log", LogTlsLogInitCtx, - LogTlsLogger, LogTlsCondition); -} diff --git a/framework/src/suricata/src/log-tlslog.h b/framework/src/suricata/src/log-tlslog.h deleted file mode 100644 index d3c9ce51..00000000 --- a/framework/src/suricata/src/log-tlslog.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Roliers Jean-Paul - * \author Eric Leblond - */ - -#ifndef __LOG_TLSLOG_H__ -#define __LOG_TLSLOG_H__ - -void TmModuleLogTlsLogRegister (void); - -int TLSGetIPInformations(const Packet *p, char* srcip, size_t srcip_len, - Port* sp, char* dstip, size_t dstip_len, - Port* dp, int ipproto); - -#endif /* __LOG_TLSLOG_H__ */ - diff --git a/framework/src/suricata/src/log-tlsstore.c b/framework/src/suricata/src/log-tlsstore.c deleted file mode 100644 index da23908e..00000000 --- a/framework/src/suricata/src/log-tlsstore.c +++ /dev/null @@ -1,439 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Roliers Jean-Paul - * \author Eric Leblond - * \author Victor Julien - * - * Implements TLS store portion of the engine. - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "log-tlslog.h" -#include "app-layer-ssl.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" -#include "util-crypt.h" -#include "util-time.h" - -#define MODULE_NAME "LogTlsStoreLog" - -static char tls_logfile_base_dir[PATH_MAX] = "/tmp"; -SC_ATOMIC_DECLARE(unsigned int, cert_id); -static char logging_dir_not_writable; - -#define LOGGING_WRITE_ISSUE_LIMIT 6 - -typedef struct LogTlsStoreLogThread_ { - uint32_t tls_cnt; - - uint8_t* enc_buf; - size_t enc_buf_len; -} LogTlsStoreLogThread; - -static int CreateFileName(const Packet *p, SSLState *state, char *filename) -{ -#define FILELEN 64 //filename len + extention + ending path / + some space - - int filenamelen = FILELEN + strlen(tls_logfile_base_dir); - int file_id = SC_ATOMIC_ADD(cert_id, 1); - - if (filenamelen + 1 > PATH_MAX) { - return 0; - } - - /* Use format : packet time + incremental ID - * When running on same pcap it will overwrite - * On a live device, we will not be able to overwrite */ - snprintf(filename, filenamelen, "%s/%ld.%ld-%d.pem", - tls_logfile_base_dir, - (long int)p->ts.tv_sec, - (long int)p->ts.tv_usec, - file_id); - return 1; -} - -static void LogTlsLogPem(LogTlsStoreLogThread *aft, const Packet *p, SSLState *state, int ipproto) -{ -#define PEMHEADER "-----BEGIN CERTIFICATE-----\n" -#define PEMFOOTER "-----END CERTIFICATE-----\n" - //Logging pem certificate - char filename[PATH_MAX] = ""; - FILE* fp = NULL; - FILE* fpmeta = NULL; - unsigned long pemlen; - unsigned char* pembase64ptr = NULL; - int ret; - uint8_t *ptmp; - SSLCertsChain *cert; - - if ((state->server_connp.cert_input == NULL) || (state->server_connp.cert_input_len == 0)) - SCReturn; - - CreateFileName(p, state, filename); - if (strlen(filename) == 0) { - SCLogWarning(SC_ERR_FOPEN, "Can't create PEM filename"); - SCReturn; - } - - fp = fopen(filename, "w"); - if (fp == NULL) { - if (logging_dir_not_writable < LOGGING_WRITE_ISSUE_LIMIT) { - SCLogWarning(SC_ERR_FOPEN, - "Can't create PEM file '%s' in '%s' directory", - filename, tls_logfile_base_dir); - logging_dir_not_writable++; - } - SCReturn; - } - - TAILQ_FOREACH(cert, &state->server_connp.certs, next) { - pemlen = (4 * (cert->cert_len + 2) / 3) +1; - if (pemlen > aft->enc_buf_len) { - ptmp = (uint8_t*) SCRealloc(aft->enc_buf, sizeof(uint8_t) * pemlen); - if (ptmp == NULL) { - SCFree(aft->enc_buf); - aft->enc_buf = NULL; - SCLogWarning(SC_ERR_MEM_ALLOC, "Can't allocate data for base64 encoding"); - goto end_fp; - } - aft->enc_buf = ptmp; - aft->enc_buf_len = pemlen; - } - - memset(aft->enc_buf, 0, aft->enc_buf_len); - - ret = Base64Encode((unsigned char*) cert->cert_data, cert->cert_len, aft->enc_buf, &pemlen); - if (ret != SC_BASE64_OK) { - SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "Invalid return of Base64Encode function"); - goto end_fwrite_fp; - } - - if (fprintf(fp, PEMHEADER) < 0) - goto end_fwrite_fp; - - pembase64ptr = aft->enc_buf; - while (pemlen > 0) { - size_t loffset = pemlen >= 64 ? 64 : pemlen; - if (fwrite(pembase64ptr, 1, loffset, fp) != loffset) - goto end_fwrite_fp; - if (fwrite("\n", 1, 1, fp) != 1) - goto end_fwrite_fp; - pembase64ptr += 64; - if (pemlen < 64) - break; - pemlen -= 64; - } - - if (fprintf(fp, PEMFOOTER) < 0) - goto end_fwrite_fp; - } - fclose(fp); - - //Logging certificate informations - memcpy(filename + (strlen(filename) - 3), "meta", 4); - fpmeta = fopen(filename, "w"); - if (fpmeta != NULL) { - #define PRINT_BUF_LEN 46 - char srcip[PRINT_BUF_LEN], dstip[PRINT_BUF_LEN]; - char timebuf[64]; - Port sp, dp; - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - if (!TLSGetIPInformations(p, srcip, PRINT_BUF_LEN, &sp, dstip, PRINT_BUF_LEN, &dp, ipproto)) - goto end_fwrite_fpmeta; - if (fprintf(fpmeta, "TIME: %s\n", timebuf) < 0) - goto end_fwrite_fpmeta; - if (p->pcap_cnt > 0) { - if (fprintf(fpmeta, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt) < 0) - goto end_fwrite_fpmeta; - } - if (fprintf(fpmeta, "SRC IP: %s\n", srcip) < 0) - goto end_fwrite_fpmeta; - if (fprintf(fpmeta, "DST IP: %s\n", dstip) < 0) - goto end_fwrite_fpmeta; - if (fprintf(fpmeta, "PROTO: %" PRIu32 "\n", p->proto) < 0) - goto end_fwrite_fpmeta; - if (PKT_IS_TCP(p) || PKT_IS_UDP(p)) { - if (fprintf(fpmeta, "SRC PORT: %" PRIu16 "\n", sp) < 0) - goto end_fwrite_fpmeta; - if (fprintf(fpmeta, "DST PORT: %" PRIu16 "\n", dp) < 0) - goto end_fwrite_fpmeta; - } - - if (fprintf(fpmeta, "TLS SUBJECT: %s\n" - "TLS ISSUERDN: %s\n" - "TLS FINGERPRINT: %s\n", - state->server_connp.cert0_subject, - state->server_connp.cert0_issuerdn, - state->server_connp.cert0_fingerprint) < 0) - goto end_fwrite_fpmeta; - - fclose(fpmeta); - } else { - if (logging_dir_not_writable < LOGGING_WRITE_ISSUE_LIMIT) { - SCLogWarning(SC_ERR_FOPEN, - "Can't create meta file '%s' in '%s' directory", - filename, tls_logfile_base_dir); - logging_dir_not_writable++; - } - SCReturn; - } - - /* Reset the store flag */ - state->server_connp.cert_log_flag &= ~SSL_TLS_LOG_PEM; - SCReturn; - -end_fwrite_fp: - fclose(fp); - if (logging_dir_not_writable < LOGGING_WRITE_ISSUE_LIMIT) { - SCLogWarning(SC_ERR_FWRITE, "Unable to write certificate"); - logging_dir_not_writable++; - } -end_fwrite_fpmeta: - if (fpmeta) { - fclose(fpmeta); - if (logging_dir_not_writable < LOGGING_WRITE_ISSUE_LIMIT) { - SCLogWarning(SC_ERR_FWRITE, "Unable to write certificate metafile"); - logging_dir_not_writable++; - } - } - SCReturn; -end_fp: - fclose(fp); - SCReturn; -} - -/** \internal - * \brief Condition function for TLS logger - * \retval bool true or false -- log now? - */ -static int LogTlsStoreCondition(ThreadVars *tv, const Packet *p) -{ - if (p->flow == NULL) { - return FALSE; - } - - if (!(PKT_IS_TCP(p))) { - return FALSE; - } - - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_TLS) - goto dontlog; - - SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); - if (ssl_state == NULL) { - SCLogDebug("no tls state, so no request logging"); - goto dontlog; - } - - /* we only log the state once if we don't have to write - * the cert due to tls.store keyword. */ - if (!(ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) && - (ssl_state->flags & SSL_AL_FLAG_STATE_STORED)) - goto dontlog; - - if (ssl_state->server_connp.cert0_issuerdn == NULL || - ssl_state->server_connp.cert0_subject == NULL) - goto dontlog; - - FLOWLOCK_UNLOCK(p->flow); - return TRUE; -dontlog: - FLOWLOCK_UNLOCK(p->flow); - return FALSE; -} - -static int LogTlsStoreLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - LogTlsStoreLogThread *aft = (LogTlsStoreLogThread *)thread_data; - int ipproto = (PKT_IS_IPV4(p)) ? AF_INET : AF_INET6; - /* check if we have TLS state or not */ - FLOWLOCK_WRLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_TLS) - goto end; - - SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); - if (unlikely(ssl_state == NULL)) { - goto end; - } - - if (ssl_state->server_connp.cert_log_flag & SSL_TLS_LOG_PEM) { - LogTlsLogPem(aft, p, ssl_state, ipproto); - } - - /* we only store the state once */ - ssl_state->flags |= SSL_AL_FLAG_STATE_STORED; -end: - FLOWLOCK_UNLOCK(p->flow); - return 0; -} - -static TmEcode LogTlsStoreLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogTlsStoreLogThread *aft = SCMalloc(sizeof(LogTlsStoreLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(LogTlsStoreLogThread)); - - if (initdata == NULL) { - SCLogDebug("Error getting context for LogTlsStore. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - struct stat stat_buf; - if (stat(tls_logfile_base_dir, &stat_buf) != 0) { - int ret; - ret = mkdir(tls_logfile_base_dir, S_IRWXU|S_IXGRP|S_IRGRP); - if (ret != 0) { - int err = errno; - if (err != EEXIST) { - SCLogError(SC_ERR_LOGDIR_CONFIG, - "Cannot create certs drop directory %s: %s", - tls_logfile_base_dir, strerror(err)); - exit(EXIT_FAILURE); - } - } else { - SCLogInfo("Created certs drop directory %s", - tls_logfile_base_dir); - } - - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode LogTlsStoreLogThreadDeinit(ThreadVars *t, void *data) -{ - LogTlsStoreLogThread *aft = (LogTlsStoreLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - /* clear memory */ - memset(aft, 0, sizeof(LogTlsStoreLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void LogTlsStoreLogExitPrintStats(ThreadVars *tv, void *data) -{ - LogTlsStoreLogThread *aft = (LogTlsStoreLogThread *)data; - if (aft == NULL) { - return; - } - - SCLogInfo("(%s) certificates extracted %" PRIu32 "", tv->name, aft->tls_cnt); -} - -/** - * \internal - * - * \brief deinit the log ctx and write out the waldo - * - * \param output_ctx output context to deinit - */ -static void LogTlsStoreLogDeInitCtx(OutputCtx *output_ctx) -{ - SCFree(output_ctx); -} - -/** \brief Create a new http log LogFilestoreCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFilestoreCtx* to the file_ctx if succesful - * */ -static OutputCtx *LogTlsStoreLogInitCtx(ConfNode *conf) -{ - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) - return NULL; - - output_ctx->data = NULL; - output_ctx->DeInit = LogTlsStoreLogDeInitCtx; - - /* FIXME we need to implement backward compability here */ - char *s_default_log_dir = NULL; - s_default_log_dir = ConfigGetLogDirectory(); - - const char *s_base_dir = NULL; - s_base_dir = ConfNodeLookupChildValue(conf, "certs-log-dir"); - if (s_base_dir == NULL || strlen(s_base_dir) == 0) { - strlcpy(tls_logfile_base_dir, - s_default_log_dir, sizeof(tls_logfile_base_dir)); - } else { - if (PathIsAbsolute(s_base_dir)) { - strlcpy(tls_logfile_base_dir, - s_base_dir, sizeof(tls_logfile_base_dir)); - } else { - snprintf(tls_logfile_base_dir, sizeof(tls_logfile_base_dir), - "%s/%s", s_default_log_dir, s_base_dir); - } - } - - SCLogInfo("storing certs in %s", tls_logfile_base_dir); - - SCReturnPtr(output_ctx, "OutputCtx"); -} - -void TmModuleLogTlsStoreRegister (void) -{ - tmm_modules[TMM_TLSSTORE].name = MODULE_NAME; - tmm_modules[TMM_TLSSTORE].ThreadInit = LogTlsStoreLogThreadInit; - tmm_modules[TMM_TLSSTORE].Func = NULL; - tmm_modules[TMM_TLSSTORE].ThreadExitPrintStats = LogTlsStoreLogExitPrintStats; - tmm_modules[TMM_TLSSTORE].ThreadDeinit = LogTlsStoreLogThreadDeinit; - tmm_modules[TMM_TLSSTORE].RegisterTests = NULL; - tmm_modules[TMM_TLSSTORE].cap_flags = 0; - tmm_modules[TMM_TLSSTORE].flags = TM_FLAG_LOGAPI_TM; - tmm_modules[TMM_TLSSTORE].priority = 10; - - OutputRegisterPacketModule(MODULE_NAME, "tls-store", LogTlsStoreLogInitCtx, - LogTlsStoreLogger, LogTlsStoreCondition); - - SC_ATOMIC_INIT(cert_id); - - SCLogDebug("registered"); -} diff --git a/framework/src/suricata/src/log-tlsstore.h b/framework/src/suricata/src/log-tlsstore.h deleted file mode 100644 index 6cbacab6..00000000 --- a/framework/src/suricata/src/log-tlsstore.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __LOG_TLSSTORE_H__ -#define __LOG_TLSSTORE_H__ - -void TmModuleLogTlsStoreRegister (void); - -#endif /* __LOG_TLSSTORE_H__ */ diff --git a/framework/src/suricata/src/output-file.c b/framework/src/suricata/src/output-file.c deleted file mode 100644 index 0f1e8521..00000000 --- a/framework/src/suricata/src/output-file.c +++ /dev/null @@ -1,298 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * AppLayer File Logger Output registration functions - */ - -#include "suricata-common.h" -#include "tm-modules.h" -#include "output-file.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "detect-filemagic.h" -#include "util-profiling.h" - -typedef struct OutputLoggerThreadStore_ { - void *thread_data; - struct OutputLoggerThreadStore_ *next; -} OutputLoggerThreadStore; - -/** per thread data for this module, contains a list of per thread - * data for the packet loggers. */ -typedef struct OutputLoggerThreadData_ { - OutputLoggerThreadStore *store; -} OutputLoggerThreadData; - -/* logger instance, a module + a output ctx, - * it's perfectly valid that have multiple instances of the same - * log module (e.g. http.log) with different output ctx'. */ -typedef struct OutputFileLogger_ { - FileLogger LogFunc; - OutputCtx *output_ctx; - struct OutputFileLogger_ *next; - const char *name; - TmmId module_id; -} OutputFileLogger; - -static OutputFileLogger *list = NULL; - -int OutputRegisterFileLogger(const char *name, FileLogger LogFunc, OutputCtx *output_ctx) -{ - int module_id = TmModuleGetIdByName(name); - if (module_id < 0) - return -1; - - OutputFileLogger *op = SCMalloc(sizeof(*op)); - if (op == NULL) - return -1; - memset(op, 0x00, sizeof(*op)); - - op->LogFunc = LogFunc; - op->output_ctx = output_ctx; - op->name = name; - op->module_id = (TmmId) module_id; - - if (list == NULL) - list = op; - else { - OutputFileLogger *t = list; - while (t->next) - t = t->next; - t->next = op; - } - - SCLogDebug("OutputRegisterTxLogger happy"); - return 0; -} - -static TmEcode OutputFileLog(ThreadVars *tv, Packet *p, void *thread_data, PacketQueue *pq, PacketQueue *postpq) -{ - BUG_ON(thread_data == NULL); - BUG_ON(list == NULL); - - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputFileLogger *logger = list; - OutputLoggerThreadStore *store = op_thread_data->store; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - BUG_ON(logger == NULL && store == NULL); - - uint8_t flags = 0; - Flow * const f = p->flow; - - /* no flow, no files */ - if (f == NULL) { - SCReturnInt(TM_ECODE_OK); - } - - if (p->flowflags & FLOW_PKT_TOCLIENT) - flags |= STREAM_TOCLIENT; - else - flags |= STREAM_TOSERVER; - - int file_close = (p->flags & PKT_PSEUDO_STREAM_END) ? 1 : 0; - int file_trunc = 0; - - FLOWLOCK_WRLOCK(f); // < need write lock for FilePrune below - file_trunc = StreamTcpReassembleDepthReached(p); - - FileContainer *ffc = AppLayerParserGetFiles(p->proto, f->alproto, - f->alstate, flags); - SCLogDebug("ffc %p", ffc); - if (ffc != NULL) { - File *ff; - for (ff = ffc->head; ff != NULL; ff = ff->next) { - if (ff->flags & FILE_LOGGED) - continue; - - SCLogDebug("ff %p", ff); - - if (file_trunc && ff->state < FILE_STATE_CLOSED) - ff->state = FILE_STATE_TRUNCATED; - - if (file_close && ff->state < FILE_STATE_CLOSED) - ff->state = FILE_STATE_TRUNCATED; - - if (ff->state == FILE_STATE_CLOSED || - ff->state == FILE_STATE_TRUNCATED || - ff->state == FILE_STATE_ERROR) - { - int file_logged = 0; - - if (FileForceMagic() && ff->magic == NULL) { - FilemagicGlobalLookup(ff); - } - - logger = list; - store = op_thread_data->store; - while (logger && store) { - BUG_ON(logger->LogFunc == NULL); - - SCLogDebug("logger %p", logger); - PACKET_PROFILING_TMM_START(p, logger->module_id); - logger->LogFunc(tv, store->thread_data, (const Packet *)p, (const File *)ff); - PACKET_PROFILING_TMM_END(p, logger->module_id); - file_logged = 1; - - logger = logger->next; - store = store->next; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - } - - if (file_logged) { - ff->flags |= FILE_LOGGED; - } - } - } - - FilePrune(ffc); - } - - FLOWLOCK_UNLOCK(f); - return TM_ECODE_OK; -} - -/** \brief thread init for the tx logger - * This will run the thread init functions for the individual registered - * loggers */ -static TmEcode OutputFileLogThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - OutputLoggerThreadData *td = SCMalloc(sizeof(*td)); - if (td == NULL) - return TM_ECODE_FAILED; - memset(td, 0x00, sizeof(*td)); - - *data = (void *)td; - - SCLogDebug("OutputFileLogThreadInit happy (*data %p)", *data); - - OutputFileLogger *logger = list; - while (logger) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadInit) { - void *retptr = NULL; - if (tm_module->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) { - OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts)); -/* todo */ BUG_ON(ts == NULL); - memset(ts, 0x00, sizeof(*ts)); - - /* store thread handle */ - ts->thread_data = retptr; - - if (td->store == NULL) { - td->store = ts; - } else { - OutputLoggerThreadStore *tmp = td->store; - while (tmp->next != NULL) - tmp = tmp->next; - tmp->next = ts; - } - - SCLogDebug("%s is now set up", logger->name); - } - } - - logger = logger->next; - } - - return TM_ECODE_OK; -} - -static TmEcode OutputFileLogThreadDeinit(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputFileLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadDeinit) { - tm_module->ThreadDeinit(tv, store->thread_data); - } - - OutputLoggerThreadStore *next_store = store->next; - SCFree(store); - store = next_store; - logger = logger->next; - } - return TM_ECODE_OK; -} - -static void OutputFileLogExitPrintStats(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputFileLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadExitPrintStats) { - tm_module->ThreadExitPrintStats(tv, store->thread_data); - } - - logger = logger->next; - store = store->next; - } -} - -void TmModuleFileLoggerRegister (void) -{ - tmm_modules[TMM_FILELOGGER].name = "__file_logger__"; - tmm_modules[TMM_FILELOGGER].ThreadInit = OutputFileLogThreadInit; - tmm_modules[TMM_FILELOGGER].Func = OutputFileLog; - tmm_modules[TMM_FILELOGGER].ThreadExitPrintStats = OutputFileLogExitPrintStats; - tmm_modules[TMM_FILELOGGER].ThreadDeinit = OutputFileLogThreadDeinit; - tmm_modules[TMM_FILELOGGER].cap_flags = 0; -} - -void OutputFileShutdown(void) -{ - OutputFileLogger *logger = list; - while (logger) { - OutputFileLogger *next_logger = logger->next; - SCFree(logger); - logger = next_logger; - } - - list = NULL; -} diff --git a/framework/src/suricata/src/output-file.h b/framework/src/suricata/src/output-file.h deleted file mode 100644 index 8b203e26..00000000 --- a/framework/src/suricata/src/output-file.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * AppLayer File Logger Output registration functions - */ - -#ifndef __OUTPUT_FILE_H__ -#define __OUTPUT_FILE_H__ - -#include "decode.h" -#include "util-file.h" - -/** packet logger function pointer type */ -typedef int (*FileLogger)(ThreadVars *, void *thread_data, const Packet *, const File *); - -/** packet logger condition function pointer type, - * must return true for packets that should be logged - */ -//typedef int (*TxLogCondition)(ThreadVars *, const Packet *); - -int OutputRegisterFileLogger(const char *name, FileLogger LogFunc, OutputCtx *); - -void TmModuleFileLoggerRegister (void); - -void OutputFileShutdown(void); - -#endif /* __OUTPUT_FILE_H__ */ diff --git a/framework/src/suricata/src/output-filedata.c b/framework/src/suricata/src/output-filedata.c deleted file mode 100644 index 8f466baf..00000000 --- a/framework/src/suricata/src/output-filedata.c +++ /dev/null @@ -1,485 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * AppLayer Filedata Logger Output registration functions - */ - -#include "suricata-common.h" -#include "tm-modules.h" -#include "output-filedata.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "detect-filemagic.h" -#include "conf.h" -#include "util-profiling.h" - -typedef struct OutputLoggerThreadStore_ { - void *thread_data; - struct OutputLoggerThreadStore_ *next; -} OutputLoggerThreadStore; - -/** per thread data for this module, contains a list of per thread - * data for the packet loggers. */ -typedef struct OutputLoggerThreadData_ { - OutputLoggerThreadStore *store; -} OutputLoggerThreadData; - -/* logger instance, a module + a output ctx, - * it's perfectly valid that have multiple instances of the same - * log module (e.g. http.log) with different output ctx'. */ -typedef struct OutputFiledataLogger_ { - FiledataLogger LogFunc; - OutputCtx *output_ctx; - struct OutputFiledataLogger_ *next; - const char *name; - TmmId module_id; -} OutputFiledataLogger; - -static OutputFiledataLogger *list = NULL; -static char g_waldo[PATH_MAX] = ""; -static SCMutex g_waldo_mutex = SCMUTEX_INITIALIZER; -static int g_waldo_init = 0; -static int g_waldo_deinit = 0; - -int OutputRegisterFiledataLogger(const char *name, FiledataLogger LogFunc, OutputCtx *output_ctx) -{ - int module_id = TmModuleGetIdByName(name); - if (module_id < 0) - return -1; - - OutputFiledataLogger *op = SCMalloc(sizeof(*op)); - if (op == NULL) - return -1; - memset(op, 0x00, sizeof(*op)); - - op->LogFunc = LogFunc; - op->output_ctx = output_ctx; - op->name = name; - op->module_id = (TmmId) module_id; - - if (list == NULL) - list = op; - else { - OutputFiledataLogger *t = list; - while (t->next) - t = t->next; - t->next = op; - } - - SCLogDebug("OutputRegisterTxLogger happy"); - return 0; -} - -SC_ATOMIC_DECLARE(unsigned int, file_id); - -static int CallLoggers(ThreadVars *tv, OutputLoggerThreadStore *store_list, - Packet *p, const File *ff, const FileData *ffd, uint8_t flags) -{ - OutputFiledataLogger *logger = list; - OutputLoggerThreadStore *store = store_list; - int file_logged = 0; - - while (logger && store) { - BUG_ON(logger->LogFunc == NULL); - - SCLogDebug("logger %p", logger); - PACKET_PROFILING_TMM_START(p, logger->module_id); - logger->LogFunc(tv, store->thread_data, (const Packet *)p, ff, ffd, flags); - PACKET_PROFILING_TMM_END(p, logger->module_id); - - file_logged = 1; - - logger = logger->next; - store = store->next; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - } - return file_logged; -} - -static TmEcode OutputFiledataLog(ThreadVars *tv, Packet *p, void *thread_data, PacketQueue *pq, PacketQueue *postpq) -{ - BUG_ON(thread_data == NULL); - BUG_ON(list == NULL); - - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputFiledataLogger *logger = list; - OutputLoggerThreadStore *store = op_thread_data->store; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - BUG_ON(logger == NULL && store == NULL); - - uint8_t flags = 0; - Flow * const f = p->flow; - - /* no flow, no files */ - if (f == NULL) { - SCReturnInt(TM_ECODE_OK); - } - - if (p->flowflags & FLOW_PKT_TOCLIENT) - flags |= STREAM_TOCLIENT; - else - flags |= STREAM_TOSERVER; - - int file_close = (p->flags & PKT_PSEUDO_STREAM_END) ? 1 : 0; - int file_trunc = 0; - - FLOWLOCK_WRLOCK(f); // < need write lock for FiledataPrune below - file_trunc = StreamTcpReassembleDepthReached(p); - - FileContainer *ffc = AppLayerParserGetFiles(p->proto, f->alproto, - f->alstate, flags); - SCLogDebug("ffc %p", ffc); - if (ffc != NULL) { - File *ff; - for (ff = ffc->head; ff != NULL; ff = ff->next) { - if (FileForceMagic() && ff->magic == NULL) { - FilemagicGlobalLookup(ff); - } - - SCLogDebug("ff %p", ff); - if (ff->flags & FILE_STORED) { - SCLogDebug("stored flag set"); - continue; - } - - if (!(ff->flags & FILE_STORE)) { - SCLogDebug("ff FILE_STORE not set"); - continue; - } - - /* if we have no data chunks left to log, we should still - * close the logger(s) */ - if (ff->chunks_head == NULL && (file_trunc || file_close)) { - CallLoggers(tv, store, p, ff, NULL, OUTPUT_FILEDATA_FLAG_CLOSE); - ff->flags |= FILE_STORED; - continue; - } - - FileData *ffd; - for (ffd = ff->chunks_head; ffd != NULL; ffd = ffd->next) { - uint8_t flags = 0; - int file_logged = 0; - FileData *write_ffd = ffd; - - SCLogDebug("ffd %p", ffd); - - /* special case: on stream end we may inform the - * loggers that the file is truncated. In this - * case we already logged the current ffd, which - * is the last in our list. */ - if (ffd->stored == 1) { - if (!(file_close == 1 || ffd->next == NULL)) { - continue; - } - - // call writer with NULL ffd, so it can 'close' - // so really a 'close' msg - write_ffd = NULL; - flags |= OUTPUT_FILEDATA_FLAG_CLOSE; - } - - /* store */ - - /* if file_id == 0, this is the first store of this file */ - if (ff->file_id == 0) { - /* new file */ - ff->file_id = SC_ATOMIC_ADD(file_id, 1); - flags |= OUTPUT_FILEDATA_FLAG_OPEN; - } else { - /* existing file */ - } - - /* if file needs to be closed or truncated, inform - * loggers */ - if ((file_close || file_trunc) && ff->state < FILE_STATE_CLOSED) { - ff->state = FILE_STATE_TRUNCATED; - } - - /* for the last data chunk we have, also tell the logger - * we're closing up */ - if (ffd->next == NULL && ff->state >= FILE_STATE_CLOSED) - flags |= OUTPUT_FILEDATA_FLAG_CLOSE; - - /* do the actual logging */ - file_logged = CallLoggers(tv, store, p, ff, write_ffd, flags); - - if (file_logged) { - ffd->stored = 1; - - /* all done */ - if (flags & OUTPUT_FILEDATA_FLAG_CLOSE) { - ff->flags |= FILE_STORED; - break; - } - } - } - } - - FilePrune(ffc); - } - - FLOWLOCK_UNLOCK(f); - return TM_ECODE_OK; -} - -/** - * \internal - * - * \brief Open the waldo file (if available) and load the file_id - * - * \param path full path for the waldo file - */ -static void LogFiledataLogLoadWaldo(const char *path) -{ - char line[16] = ""; - unsigned int id = 0; - - FILE *fp = fopen(path, "r"); - if (fp == NULL) { - SCLogInfo("couldn't open waldo: %s", strerror(errno)); - SCReturn; - } - - if (fgets(line, (int)sizeof(line), fp) != NULL) { - if (sscanf(line, "%10u", &id) == 1) { - SCLogInfo("id %u", id); - (void) SC_ATOMIC_CAS(&file_id, 0, id); - } - } - fclose(fp); -} - -/** - * \internal - * - * \brief Store the waldo file based on the file_id - * - * \param path full path for the waldo file - */ -static void LogFiledataLogStoreWaldo(const char *path) -{ - char line[16] = ""; - - if (SC_ATOMIC_GET(file_id) == 0) { - SCReturn; - } - - FILE *fp = fopen(path, "w"); - if (fp == NULL) { - SCLogInfo("couldn't open waldo: %s", strerror(errno)); - SCReturn; - } - - snprintf(line, sizeof(line), "%u\n", SC_ATOMIC_GET(file_id)); - if (fwrite(line, strlen(line), 1, fp) != 1) { - SCLogError(SC_ERR_FWRITE, "fwrite failed: %s", strerror(errno)); - } - fclose(fp); -} - -/** \brief thread init for the tx logger - * This will run the thread init functions for the individual registered - * loggers */ -static TmEcode OutputFiledataLogThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - OutputLoggerThreadData *td = SCMalloc(sizeof(*td)); - if (td == NULL) - return TM_ECODE_FAILED; - memset(td, 0x00, sizeof(*td)); - - *data = (void *)td; - - SCLogDebug("OutputFiledataLogThreadInit happy (*data %p)", *data); - - OutputFiledataLogger *logger = list; - while (logger) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadInit) { - void *retptr = NULL; - if (tm_module->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) { - OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts)); -/* todo */ BUG_ON(ts == NULL); - memset(ts, 0x00, sizeof(*ts)); - - /* store thread handle */ - ts->thread_data = retptr; - - if (td->store == NULL) { - td->store = ts; - } else { - OutputLoggerThreadStore *tmp = td->store; - while (tmp->next != NULL) - tmp = tmp->next; - tmp->next = ts; - } - - SCLogDebug("%s is now set up", logger->name); - } - } - - logger = logger->next; - } - - SCMutexLock(&g_waldo_mutex); - if (g_waldo_init == 0) { - ConfNode *node = ConfGetNode("file-store-waldo"); - if (node == NULL) { - ConfNode *outputs = ConfGetNode("outputs"); - if (outputs) { - ConfNode *output; - TAILQ_FOREACH(output, &outputs->head, next) { - /* we only care about file and file-store */ - if (!(strcmp(output->val, "file") == 0 || strcmp(output->val, "file-store") == 0)) - continue; - - ConfNode *file = ConfNodeLookupChild(output, output->val); - BUG_ON(file == NULL); - if (file == NULL) { - SCLogDebug("file-store failed, lets try 'file'"); - file = ConfNodeLookupChild(outputs, "file"); - if (file == NULL) - SCLogDebug("file failed as well, giving up"); - } - - if (file != NULL) { - node = ConfNodeLookupChild(file, "waldo"); - if (node == NULL) - SCLogDebug("no waldo node"); - } - } - } - } - if (node != NULL) { - char *s_default_log_dir = NULL; - s_default_log_dir = ConfigGetLogDirectory(); - - const char *waldo = node->val; - SCLogDebug("loading waldo %s", waldo); - if (waldo != NULL && strlen(waldo) > 0) { - if (PathIsAbsolute(waldo)) { - snprintf(g_waldo, sizeof(g_waldo), "%s", waldo); - } else { - snprintf(g_waldo, sizeof(g_waldo), "%s/%s", s_default_log_dir, waldo); - } - - SCLogDebug("loading waldo file %s", g_waldo); - LogFiledataLogLoadWaldo(g_waldo); - } - } - g_waldo_init = 1; - } - SCMutexUnlock(&g_waldo_mutex); - return TM_ECODE_OK; -} - -static TmEcode OutputFiledataLogThreadDeinit(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputFiledataLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadDeinit) { - tm_module->ThreadDeinit(tv, store->thread_data); - } - - OutputLoggerThreadStore *next_store = store->next; - SCFree(store); - store = next_store; - logger = logger->next; - } - - SCMutexLock(&g_waldo_mutex); - if (g_waldo_deinit == 0) { - if (strlen(g_waldo) > 0) { - SCLogDebug("we have a waldo at %s", g_waldo); - LogFiledataLogStoreWaldo(g_waldo); - } - g_waldo_deinit = 1; - } - SCMutexUnlock(&g_waldo_mutex); - return TM_ECODE_OK; -} - -static void OutputFiledataLogExitPrintStats(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputFiledataLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadExitPrintStats) { - tm_module->ThreadExitPrintStats(tv, store->thread_data); - } - - logger = logger->next; - store = store->next; - } -} - -void TmModuleFiledataLoggerRegister (void) -{ - tmm_modules[TMM_FILEDATALOGGER].name = "__filedata_logger__"; - tmm_modules[TMM_FILEDATALOGGER].ThreadInit = OutputFiledataLogThreadInit; - tmm_modules[TMM_FILEDATALOGGER].Func = OutputFiledataLog; - tmm_modules[TMM_FILEDATALOGGER].ThreadExitPrintStats = OutputFiledataLogExitPrintStats; - tmm_modules[TMM_FILEDATALOGGER].ThreadDeinit = OutputFiledataLogThreadDeinit; - tmm_modules[TMM_FILEDATALOGGER].cap_flags = 0; - - SC_ATOMIC_INIT(file_id); -} - -void OutputFiledataShutdown(void) -{ - OutputFiledataLogger *logger = list; - while (logger) { - OutputFiledataLogger *next_logger = logger->next; - SCFree(logger); - logger = next_logger; - } - - list = NULL; -} diff --git a/framework/src/suricata/src/output-filedata.h b/framework/src/suricata/src/output-filedata.h deleted file mode 100644 index 8900cd48..00000000 --- a/framework/src/suricata/src/output-filedata.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * AppLayer Filedata Logger Output registration functions - */ - -#ifndef __OUTPUT_FILEDATA_H__ -#define __OUTPUT_FILEDATA_H__ - -#include "decode.h" -#include "util-file.h" - -#define OUTPUT_FILEDATA_FLAG_OPEN 0x01 -#define OUTPUT_FILEDATA_FLAG_CLOSE 0x02 - -/** filedata logger function pointer type */ -typedef int (*FiledataLogger)(ThreadVars *, void *thread_data, const Packet *, - const File *, const FileData *, uint8_t); - -/** packet logger condition function pointer type, - * must return true for packets that should be logged - */ -//typedef int (*TxLogCondition)(ThreadVars *, const Packet *); - -int OutputRegisterFiledataLogger(const char *name, FiledataLogger LogFunc, OutputCtx *); - -void TmModuleFiledataLoggerRegister (void); - -void OutputFiledataShutdown(void); - -#endif /* __OUTPUT_FILE_H__ */ diff --git a/framework/src/suricata/src/output-flow.c b/framework/src/suricata/src/output-flow.c deleted file mode 100644 index 20d5d7d4..00000000 --- a/framework/src/suricata/src/output-flow.c +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Flow Logger Output registration functions - */ - -#include "suricata-common.h" -#include "tm-modules.h" -#include "output-flow.h" -#include "util-profiling.h" - -typedef struct OutputLoggerThreadStore_ { - void *thread_data; - struct OutputLoggerThreadStore_ *next; -} OutputLoggerThreadStore; - -/** per thread data for this module, contains a list of per thread - * data for the packet loggers. */ -typedef struct OutputLoggerThreadData_ { - OutputLoggerThreadStore *store; -} OutputLoggerThreadData; - -/* logger instance, a module + a output ctx, - * it's perfectly valid that have multiple instances of the same - * log module (e.g. http.log) with different output ctx'. */ -typedef struct OutputFlowLogger_ { - FlowLogger LogFunc; - OutputCtx *output_ctx; - struct OutputFlowLogger_ *next; - const char *name; - TmmId module_id; -} OutputFlowLogger; - -static OutputFlowLogger *list = NULL; - -int OutputRegisterFlowLogger(const char *name, FlowLogger LogFunc, OutputCtx *output_ctx) -{ - int module_id = TmModuleGetIdByName(name); - if (module_id < 0) - return -1; - - OutputFlowLogger *op = SCMalloc(sizeof(*op)); - if (op == NULL) - return -1; - memset(op, 0x00, sizeof(*op)); - - op->LogFunc = LogFunc; - op->output_ctx = output_ctx; - op->name = name; - op->module_id = (TmmId) module_id; - - if (list == NULL) - list = op; - else { - OutputFlowLogger *t = list; - while (t->next) - t = t->next; - t->next = op; - } - - SCLogDebug("OutputRegisterFlowLogger happy"); - return 0; -} - -/** \brief Run flow logger(s) - * \note flow is already write locked - */ -TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f) -{ - BUG_ON(thread_data == NULL); - - if (list == NULL) - return TM_ECODE_OK; - //BUG_ON(list == NULL); - - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputFlowLogger *logger = list; - OutputLoggerThreadStore *store = op_thread_data->store; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - BUG_ON(logger == NULL && store == NULL); - - logger = list; - store = op_thread_data->store; - while (logger && store) { - BUG_ON(logger->LogFunc == NULL); - - SCLogDebug("logger %p", logger); - //PACKET_PROFILING_TMM_START(p, logger->module_id); - logger->LogFunc(tv, store->thread_data, f); - //PACKET_PROFILING_TMM_END(p, logger->module_id); - - logger = logger->next; - store = store->next; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - } - - return TM_ECODE_OK; -} - -/** \brief thread init for the flow logger - * This will run the thread init functions for the individual registered - * loggers */ -TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - OutputLoggerThreadData *td = SCMalloc(sizeof(*td)); - if (td == NULL) - return TM_ECODE_FAILED; - memset(td, 0x00, sizeof(*td)); - - *data = (void *)td; - - SCLogDebug("OutputFlowLogThreadInit happy (*data %p)", *data); - - OutputFlowLogger *logger = list; - while (logger) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadInit) { - void *retptr = NULL; - if (tm_module->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) { - OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts)); -/* todo */ BUG_ON(ts == NULL); - memset(ts, 0x00, sizeof(*ts)); - - /* store thread handle */ - ts->thread_data = retptr; - - if (td->store == NULL) { - td->store = ts; - } else { - OutputLoggerThreadStore *tmp = td->store; - while (tmp->next != NULL) - tmp = tmp->next; - tmp->next = ts; - } - - SCLogDebug("%s is now set up", logger->name); - } - } - - logger = logger->next; - } - - return TM_ECODE_OK; -} - -TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputFlowLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadDeinit) { - tm_module->ThreadDeinit(tv, store->thread_data); - } - - OutputLoggerThreadStore *next_store = store->next; - SCFree(store); - store = next_store; - logger = logger->next; - } - - SCFree(op_thread_data); - return TM_ECODE_OK; -} - -void OutputFlowLogExitPrintStats(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputFlowLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadExitPrintStats) { - tm_module->ThreadExitPrintStats(tv, store->thread_data); - } - - logger = logger->next; - store = store->next; - } -} - -void OutputFlowShutdown(void) -{ - OutputFlowLogger *logger = list; - while (logger) { - OutputFlowLogger *next_logger = logger->next; - SCFree(logger); - logger = next_logger; - } - list = NULL; -} diff --git a/framework/src/suricata/src/output-flow.h b/framework/src/suricata/src/output-flow.h deleted file mode 100644 index af093e3e..00000000 --- a/framework/src/suricata/src/output-flow.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Flow Logger Output registration functions - */ - -#ifndef __OUTPUT_FLOW_H__ -#define __OUTPUT_FLOW_H__ - -#include "decode.h" - -/** flow logger function pointer type */ -typedef int (*FlowLogger)(ThreadVars *, void *thread_data, Flow *f); - -/** packet logger condition function pointer type, - * must return true for packets that should be logged - */ -//typedef int (*TxLogCondition)(ThreadVars *, const Packet *); - -int OutputRegisterFlowLogger(const char *name, FlowLogger LogFunc, OutputCtx *); - -void OutputFlowShutdown(void); - - -TmEcode OutputFlowLog(ThreadVars *tv, void *thread_data, Flow *f); -TmEcode OutputFlowLogThreadInit(ThreadVars *tv, void *initdata, void **data); -TmEcode OutputFlowLogThreadDeinit(ThreadVars *tv, void *thread_data); -void OutputFlowLogExitPrintStats(ThreadVars *tv, void *thread_data); - - -#endif /* __OUTPUT_FLOW_H__ */ diff --git a/framework/src/suricata/src/output-json-alert.c b/framework/src/suricata/src/output-json-alert.c deleted file mode 100644 index 2c0d0171..00000000 --- a/framework/src/suricata/src/output-json-alert.c +++ /dev/null @@ -1,700 +0,0 @@ -/* Copyright (C) 2013-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * Logs alerts in JSON format. - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" - -#include "threads.h" -#include "tm-threads.h" -#include "threadvars.h" -#include "util-debug.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-reference.h" -#include "app-layer-parser.h" -#include "app-layer-htp.h" -#include "app-layer-htp-xff.h" -#include "util-classification-config.h" -#include "util-syslog.h" -#include "util-logopenfile.h" - -#include "output.h" -#include "output-json.h" -#include "output-json-http.h" -#include "output-json-tls.h" -#include "output-json-ssh.h" -#include "output-json-smtp.h" -#include "output-json-email-common.h" - -#include "util-byte.h" -#include "util-privs.h" -#include "util-print.h" -#include "util-proto-name.h" -#include "util-optimize.h" -#include "util-buffer.h" -#include "util-crypt.h" - -#define MODULE_NAME "JsonAlertLog" - -#ifdef HAVE_LIBJANSSON - -#define LOG_JSON_PAYLOAD 1 -#define LOG_JSON_PACKET 2 -#define LOG_JSON_PAYLOAD_BASE64 4 -#define LOG_JSON_HTTP 8 -#define LOG_JSON_TLS 16 -#define LOG_JSON_SSH 32 -#define LOG_JSON_SMTP 64 - -#define JSON_STREAM_BUFFER_SIZE 4096 - -typedef struct AlertJsonOutputCtx_ { - LogFileCtx* file_ctx; - uint8_t flags; - HttpXFFCfg *xff_cfg; -} AlertJsonOutputCtx; - -typedef struct JsonAlertLogThread_ { - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - LogFileCtx* file_ctx; - MemBuffer *json_buffer; - MemBuffer *payload_buffer; - AlertJsonOutputCtx* json_output_ctx; -} JsonAlertLogThread; - -/* Callback function to pack payload contents from a stream into a buffer - * so we can report them in JSON output. */ -static int AlertJsonDumpStreamSegmentCallback(const Packet *p, void *data, uint8_t *buf, uint32_t buflen) -{ - MemBuffer *payload = (MemBuffer *)data; - MemBufferWriteRaw(payload, buf, buflen); - - return 1; -} - -static void AlertJsonTls(const Flow *f, json_t *js) -{ - SSLState *ssl_state = (SSLState *)FlowGetAppState(f); - if (ssl_state) { - json_t *tjs = json_object(); - if (unlikely(tjs == NULL)) - return; - - JsonTlsLogJSONBasic(tjs, ssl_state); - JsonTlsLogJSONExtended(tjs, ssl_state); - - json_object_set_new(js, "tls", tjs); - } - - return; -} - -static void AlertJsonSsh(const Flow *f, json_t *js) -{ - SshState *ssh_state = (SshState *)FlowGetAppState(f); - if (ssh_state) { - json_t *tjs = json_object(); - if (unlikely(tjs == NULL)) - return; - - JsonSshLogJSON(tjs, ssh_state); - - json_object_set_new(js, "ssh", tjs); - } - - return; -} - -void AlertJsonHeader(const Packet *p, const PacketAlert *pa, json_t *js) -{ - char *action = "allowed"; - if (pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) { - action = "blocked"; - } else if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { - action = "blocked"; - } - - /* Add tx_id to root element for correlation with other events. */ - json_object_del(js, "tx_id"); - if (pa->flags & PACKET_ALERT_FLAG_TX) - json_object_set_new(js, "tx_id", json_integer(pa->tx_id)); - - json_t *ajs = json_object(); - if (ajs == NULL) { - json_decref(js); - return; - } - - json_object_set_new(ajs, "action", json_string(action)); - json_object_set_new(ajs, "gid", json_integer(pa->s->gid)); - json_object_set_new(ajs, "signature_id", json_integer(pa->s->id)); - json_object_set_new(ajs, "rev", json_integer(pa->s->rev)); - json_object_set_new(ajs, "signature", - json_string((pa->s->msg) ? pa->s->msg : "")); - json_object_set_new(ajs, "category", - json_string((pa->s->class_msg) ? pa->s->class_msg : "")); - json_object_set_new(ajs, "severity", json_integer(pa->s->prio)); - - if (p->tenant_id > 0) - json_object_set_new(ajs, "tenant_id", json_integer(p->tenant_id)); - - /* alert */ - json_object_set_new(js, "alert", ajs); -} - -static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p) -{ - MemBuffer *payload = aft->payload_buffer; - AlertJsonOutputCtx *json_output_ctx = aft->json_output_ctx; - json_t *hjs = NULL; - - int i; - - if (p->alerts.cnt == 0) - return TM_ECODE_OK; - - json_t *js = CreateJSONHeader((Packet *)p, 0, "alert"); - if (unlikely(js == NULL)) - return TM_ECODE_OK; - - for (i = 0; i < p->alerts.cnt; i++) { - const PacketAlert *pa = &p->alerts.alerts[i]; - if (unlikely(pa->s == NULL)) { - continue; - } - - MemBufferReset(aft->json_buffer); - - /* alert */ - AlertJsonHeader(p, pa, js); - - if (json_output_ctx->flags & LOG_JSON_HTTP) { - if (p->flow != NULL) { - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - - /* http alert */ - if (proto == ALPROTO_HTTP) { - hjs = JsonHttpAddMetadata(p->flow, pa->tx_id); - if (hjs) - json_object_set_new(js, "http", hjs); - } - - FLOWLOCK_UNLOCK(p->flow); - } - } - - if (json_output_ctx->flags & LOG_JSON_TLS) { - if (p->flow != NULL) { - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - - /* http alert */ - if (proto == ALPROTO_TLS) - AlertJsonTls(p->flow, js); - - FLOWLOCK_UNLOCK(p->flow); - } - } - - if (json_output_ctx->flags & LOG_JSON_SSH) { - if (p->flow != NULL) { - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - - /* http alert */ - if (proto == ALPROTO_SSH) - AlertJsonSsh(p->flow, js); - - FLOWLOCK_UNLOCK(p->flow); - } - } - - if (json_output_ctx->flags & LOG_JSON_SMTP) { - if (p->flow != NULL) { - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - - /* http alert */ - if (proto == ALPROTO_SMTP) { - hjs = JsonSMTPAddMetadata(p->flow, pa->tx_id); - if (hjs) - json_object_set_new(js, "smtp", hjs); - - hjs = JsonEmailAddMetadata(p->flow, pa->tx_id); - if (hjs) - json_object_set_new(js, "email", hjs); - } - - FLOWLOCK_UNLOCK(p->flow); - } - } - - /* payload */ - if (json_output_ctx->flags & (LOG_JSON_PAYLOAD | LOG_JSON_PAYLOAD_BASE64)) { - int stream = (p->proto == IPPROTO_TCP) ? - (pa->flags & (PACKET_ALERT_FLAG_STATE_MATCH | PACKET_ALERT_FLAG_STREAM_MATCH) ? - 1 : 0) : 0; - - /* Is this a stream? If so, pack part of it into the payload field */ - if (stream) { - uint8_t flag; - - MemBufferReset(payload); - - if (!EngineModeIsIPS()) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - flag = FLOW_PKT_TOCLIENT; - } else { - flag = FLOW_PKT_TOSERVER; - } - } else { - if (p->flowflags & FLOW_PKT_TOSERVER) { - flag = FLOW_PKT_TOSERVER; - } else { - flag = FLOW_PKT_TOCLIENT; - } - } - - StreamSegmentForEach((const Packet *)p, flag, - AlertJsonDumpStreamSegmentCallback, - (void *)payload); - - if (json_output_ctx->flags & LOG_JSON_PAYLOAD_BASE64) { - unsigned long len = JSON_STREAM_BUFFER_SIZE * 2; - uint8_t encoded[len]; - Base64Encode(payload->buffer, payload->offset, encoded, &len); - json_object_set_new(js, "payload", json_string((char *)encoded)); - } - - if (json_output_ctx->flags & LOG_JSON_PAYLOAD) { - uint8_t printable_buf[payload->offset + 1]; - uint32_t offset = 0; - PrintStringsToBuffer(printable_buf, &offset, - sizeof(printable_buf), - payload->buffer, payload->offset); - json_object_set_new(js, "payload_printable", - json_string((char *)printable_buf)); - } - } else { - /* This is a single packet and not a stream */ - if (json_output_ctx->flags & LOG_JSON_PAYLOAD_BASE64) { - unsigned long len = p->payload_len * 2 + 1; - uint8_t encoded[len]; - Base64Encode(p->payload, p->payload_len, encoded, &len); - json_object_set_new(js, "payload", json_string((char *)encoded)); - } - - if (json_output_ctx->flags & LOG_JSON_PAYLOAD) { - uint8_t printable_buf[p->payload_len + 1]; - uint32_t offset = 0; - PrintStringsToBuffer(printable_buf, &offset, - p->payload_len + 1, - p->payload, p->payload_len); - json_object_set_new(js, "payload_printable", json_string((char *)printable_buf)); - } - } - - json_object_set_new(js, "stream", json_integer(stream)); - } - - /* base64-encoded full packet */ - if (json_output_ctx->flags & LOG_JSON_PACKET) { - unsigned long len = GET_PKT_LEN(p) * 2; - uint8_t encoded_packet[len]; - Base64Encode((unsigned char*) GET_PKT_DATA(p), GET_PKT_LEN(p), encoded_packet, &len); - json_object_set_new(js, "packet", json_string((char *)encoded_packet)); - } - - HttpXFFCfg *xff_cfg = json_output_ctx->xff_cfg; - - /* xff header */ - if (!(xff_cfg->flags & XFF_DISABLED) && p->flow != NULL) { - int have_xff_ip = 0; - char buffer[XFF_MAXLEN]; - - FLOWLOCK_RDLOCK(p->flow); - if (FlowGetAppProtocol(p->flow) == ALPROTO_HTTP) { - if (pa->flags & PACKET_ALERT_FLAG_TX) { - have_xff_ip = HttpXFFGetIPFromTx(p, pa->tx_id, xff_cfg, buffer, XFF_MAXLEN); - } else { - have_xff_ip = HttpXFFGetIP(p, xff_cfg, buffer, XFF_MAXLEN); - } - } - FLOWLOCK_UNLOCK(p->flow); - - if (have_xff_ip) { - if (xff_cfg->flags & XFF_EXTRADATA) { - json_object_set_new(js, "xff", json_string(buffer)); - } - else if (xff_cfg->flags & XFF_OVERWRITE) { - if (p->flowflags & FLOW_PKT_TOCLIENT) { - json_object_set(js, "dest_ip", json_string(buffer)); - } else { - json_object_set(js, "src_ip", json_string(buffer)); - } - } - } - } - - OutputJSONBuffer(js, aft->file_ctx, aft->json_buffer); - json_object_del(js, "alert"); - } - json_object_clear(js); - json_decref(js); - - return TM_ECODE_OK; -} - -static int AlertJsonDecoderEvent(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p) -{ - MemBuffer *buffer = (MemBuffer *)aft->json_buffer; - int i; - char timebuf[64]; - json_t *js; - - if (p->alerts.cnt == 0) - return TM_ECODE_OK; - - CreateIsoTimeString(&p->ts, timebuf, sizeof(timebuf)); - - for (i = 0; i < p->alerts.cnt; i++) { - MemBufferReset(buffer); - - const PacketAlert *pa = &p->alerts.alerts[i]; - if (unlikely(pa->s == NULL)) { - continue; - } - - char *action = "allowed"; - if (pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) { - action = "blocked"; - } else if ((pa->action & ACTION_DROP) && EngineModeIsIPS()) { - action = "blocked"; - } - - char buf[(32 * 3) + 1]; - PrintRawLineHexBuf(buf, sizeof(buf), GET_PKT_DATA(p), GET_PKT_LEN(p) < 32 ? GET_PKT_LEN(p) : 32); - - js = json_object(); - if (js == NULL) - return TM_ECODE_OK; - - json_t *ajs = json_object(); - if (ajs == NULL) { - json_decref(js); - return TM_ECODE_OK; - } - - /* time & tx */ - json_object_set_new(js, "timestamp", json_string(timebuf)); - - /* tuple */ - //json_object_set_new(js, "srcip", json_string(srcip)); - //json_object_set_new(js, "sp", json_integer(p->sp)); - //json_object_set_new(js, "dstip", json_string(dstip)); - //json_object_set_new(js, "dp", json_integer(p->dp)); - //json_object_set_new(js, "proto", json_integer(proto)); - - json_object_set_new(ajs, "action", json_string(action)); - json_object_set_new(ajs, "gid", json_integer(pa->s->gid)); - json_object_set_new(ajs, "signature_id", json_integer(pa->s->id)); - json_object_set_new(ajs, "rev", json_integer(pa->s->rev)); - json_object_set_new(ajs, "signature", - json_string((pa->s->msg) ? pa->s->msg : "")); - json_object_set_new(ajs, "category", - json_string((pa->s->class_msg) ? pa->s->class_msg : "")); - json_object_set_new(ajs, "severity", json_integer(pa->s->prio)); - - if (p->tenant_id > 0) - json_object_set_new(ajs, "tenant_id", json_integer(p->tenant_id)); - - /* alert */ - json_object_set_new(js, "alert", ajs); - OutputJSONBuffer(js, aft->file_ctx, buffer); - json_object_clear(js); - json_decref(js); - } - - return TM_ECODE_OK; -} - -static int JsonAlertLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - JsonAlertLogThread *aft = thread_data; - - if (PKT_IS_IPV4(p) || PKT_IS_IPV6(p)) { - return AlertJson(tv, aft, p); - } else if (p->alerts.cnt > 0) { - return AlertJsonDecoderEvent(tv, aft, p); - } - return 0; -} - -static int JsonAlertLogCondition(ThreadVars *tv, const Packet *p) -{ - return (p->alerts.cnt ? TRUE : FALSE); -} - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonAlertLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonAlertLogThread *aft = SCMalloc(sizeof(JsonAlertLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(JsonAlertLogThread)); - if(initdata == NULL) - { - SCLogDebug("Error getting context for AlertFastLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - aft->json_buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->json_buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - aft->payload_buffer = MemBufferCreateNew(JSON_STREAM_BUFFER_SIZE); - if (aft->payload_buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - /** Use the Output Context (file pointer and mutex) */ - AlertJsonOutputCtx *json_output_ctx = ((OutputCtx *)initdata)->data; - aft->file_ctx = json_output_ctx->file_ctx; - aft->json_output_ctx = json_output_ctx; - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonAlertLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonAlertLogThread *aft = (JsonAlertLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->json_buffer); - MemBufferFree(aft->payload_buffer); - - /* clear memory */ - memset(aft, 0, sizeof(JsonAlertLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void JsonAlertLogDeInitCtx(OutputCtx *output_ctx) -{ - SCLogDebug("cleaning up output_ctx"); - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - LogFileFreeCtx(logfile_ctx); - SCFree(output_ctx); -} - -static void JsonAlertLogDeInitCtxSub(OutputCtx *output_ctx) -{ - SCLogDebug("cleaning up sub output_ctx %p", output_ctx); - - AlertJsonOutputCtx *json_output_ctx = (AlertJsonOutputCtx *) output_ctx->data; - - if (json_output_ctx != NULL) { - HttpXFFCfg *xff_cfg = json_output_ctx->xff_cfg; - if (xff_cfg != NULL) { - SCFree(xff_cfg); - } - - SCFree(json_output_ctx); - } - SCFree(output_ctx); -} - -#define DEFAULT_LOG_FILENAME "alert.json" - -/** - * \brief Create a new LogFileCtx for "fast" output style. - * \param conf The configuration node for this output. - * \return A LogFileCtx pointer on success, NULL on failure. - */ -static OutputCtx *JsonAlertLogInitCtx(ConfNode *conf) -{ - LogFileCtx *logfile_ctx = LogFileNewCtx(); - if (logfile_ctx == NULL) { - SCLogDebug("AlertFastLogInitCtx2: Could not create new LogFileCtx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(logfile_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) - return NULL; - output_ctx->data = logfile_ctx; - output_ctx->DeInit = JsonAlertLogDeInitCtx; - - return output_ctx; -} - -/** - * \brief Create a new LogFileCtx for "fast" output style. - * \param conf The configuration node for this output. - * \return A LogFileCtx pointer on success, NULL on failure. - */ -static OutputCtx *JsonAlertLogInitCtxSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputJsonCtx *ajt = parent_ctx->data; - AlertJsonOutputCtx *json_output_ctx = NULL; - HttpXFFCfg *xff_cfg = NULL; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) - return NULL; - - json_output_ctx = SCMalloc(sizeof(AlertJsonOutputCtx)); - if (unlikely(json_output_ctx == NULL)) { - goto error; - } - memset(json_output_ctx, 0, sizeof(AlertJsonOutputCtx)); - - xff_cfg = SCMalloc(sizeof(HttpXFFCfg)); - if (unlikely(xff_cfg == NULL)) { - goto error; - } - memset(xff_cfg, 0, sizeof(HttpXFFCfg)); - - json_output_ctx->file_ctx = ajt->file_ctx; - json_output_ctx->xff_cfg = xff_cfg; - - if (conf != NULL) { - const char *payload = ConfNodeLookupChildValue(conf, "payload"); - const char *packet = ConfNodeLookupChildValue(conf, "packet"); - const char *payload_printable = ConfNodeLookupChildValue(conf, "payload-printable"); - const char *http = ConfNodeLookupChildValue(conf, "http"); - const char *tls = ConfNodeLookupChildValue(conf, "tls"); - const char *ssh = ConfNodeLookupChildValue(conf, "ssh"); - const char *smtp = ConfNodeLookupChildValue(conf, "smtp"); - - if (ssh != NULL) { - if (ConfValIsTrue(ssh)) { - json_output_ctx->flags |= LOG_JSON_SSH; - } - } - if (tls != NULL) { - if (ConfValIsTrue(tls)) { - json_output_ctx->flags |= LOG_JSON_TLS; - } - } - if (http != NULL) { - if (ConfValIsTrue(http)) { - json_output_ctx->flags |= LOG_JSON_HTTP; - } - } - if (smtp != NULL) { - if (ConfValIsTrue(smtp)) { - json_output_ctx->flags |= LOG_JSON_SMTP; - } - } - if (payload_printable != NULL) { - if (ConfValIsTrue(payload_printable)) { - json_output_ctx->flags |= LOG_JSON_PAYLOAD; - } - } - if (payload != NULL) { - if (ConfValIsTrue(payload)) { - json_output_ctx->flags |= LOG_JSON_PAYLOAD_BASE64; - } - } - if (packet != NULL) { - if (ConfValIsTrue(packet)) { - json_output_ctx->flags |= LOG_JSON_PACKET; - } - } - - HttpXFFGetCfg(conf, xff_cfg); - } - - output_ctx->data = json_output_ctx; - output_ctx->DeInit = JsonAlertLogDeInitCtxSub; - - return output_ctx; - -error: - if (json_output_ctx != NULL) { - SCFree(json_output_ctx); - } - if (output_ctx != NULL) { - SCFree(output_ctx); - } - - return NULL; -} - -void TmModuleJsonAlertLogRegister (void) -{ - tmm_modules[TMM_JSONALERTLOG].name = MODULE_NAME; - tmm_modules[TMM_JSONALERTLOG].ThreadInit = JsonAlertLogThreadInit; - tmm_modules[TMM_JSONALERTLOG].ThreadDeinit = JsonAlertLogThreadDeinit; - tmm_modules[TMM_JSONALERTLOG].cap_flags = 0; - tmm_modules[TMM_JSONALERTLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterPacketModule(MODULE_NAME, "alert-json-log", - JsonAlertLogInitCtx, JsonAlertLogger, JsonAlertLogCondition); - OutputRegisterPacketSubModule("eve-log", MODULE_NAME, "eve-log.alert", - JsonAlertLogInitCtxSub, JsonAlertLogger, JsonAlertLogCondition); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonAlertLogRegister (void) -{ - tmm_modules[TMM_JSONALERTLOG].name = MODULE_NAME; - tmm_modules[TMM_JSONALERTLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif - diff --git a/framework/src/suricata/src/output-json-alert.h b/framework/src/suricata/src/output-json-alert.h deleted file mode 100644 index a10a316d..00000000 --- a/framework/src/suricata/src/output-json-alert.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2013-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * Logs alerts in JSON format. - * - */ - -#ifndef __OUTPUT_JSON_ALERT_H__ -#define __OUTPUT_JSON_ALERT_H__ - -void TmModuleJsonAlertLogRegister (void); -#ifdef HAVE_LIBJANSSON -void AlertJsonHeader(const Packet *p, const PacketAlert *pa, json_t *js); -#endif /* HAVE_LIBJANSSON */ - -#endif /* __OUTPUT_JSON_ALERT_H__ */ - diff --git a/framework/src/suricata/src/output-json-dns.c b/framework/src/suricata/src/output-json-dns.c deleted file mode 100644 index 89c11b3e..00000000 --- a/framework/src/suricata/src/output-json-dns.c +++ /dev/null @@ -1,448 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * Implements JSON DNS logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" -#include "util-mem.h" -#include "app-layer-parser.h" -#include "output.h" -#include "app-layer-dns-udp.h" -#include "app-layer.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#include "output-json.h" - -#ifdef HAVE_LIBJANSSON -#include - -/* we can do query logging as well, but it's disabled for now as the - * TX id handling doesn't expect it */ -#define QUERY 0 - -typedef struct LogDnsFileCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ -} LogDnsFileCtx; - -typedef struct LogDnsLogThread_ { - LogDnsFileCtx *dnslog_ctx; - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - uint32_t dns_cnt; - - MemBuffer *buffer; -} LogDnsLogThread; - -static void LogQuery(LogDnsLogThread *aft, json_t *js, DNSTransaction *tx, - uint64_t tx_id, DNSQueryEntry *entry) -{ - MemBuffer *buffer = (MemBuffer *)aft->buffer; - - SCLogDebug("got a DNS request and now logging !!"); - - json_t *djs = json_object(); - if (djs == NULL) { - return; - } - - /* reset */ - MemBufferReset(buffer); - - /* type */ - json_object_set_new(djs, "type", json_string("query")); - - /* id */ - json_object_set_new(djs, "id", json_integer(tx->tx_id)); - - /* query */ - char *c; - c = BytesToString((uint8_t *)((uint8_t *)entry + sizeof(DNSQueryEntry)), entry->len); - if (c != NULL) { - json_object_set_new(djs, "rrname", json_string(c)); - SCFree(c); - } - - /* name */ - char record[16] = ""; - DNSCreateTypeString(entry->type, record, sizeof(record)); - json_object_set_new(djs, "rrtype", json_string(record)); - - /* tx id (tx counter) */ - json_object_set_new(djs, "tx_id", json_integer(tx_id)); - - /* dns */ - json_object_set_new(js, "dns", djs); - OutputJSONBuffer(js, aft->dnslog_ctx->file_ctx, buffer); - json_object_del(js, "dns"); -} - -static void OutputAnswer(LogDnsLogThread *aft, json_t *djs, DNSTransaction *tx, DNSAnswerEntry *entry) -{ - MemBuffer *buffer = (MemBuffer *)aft->buffer; - json_t *js = json_object(); - if (js == NULL) - return; - - /* type */ - json_object_set_new(js, "type", json_string("answer")); - - /* id */ - json_object_set_new(js, "id", json_integer(tx->tx_id)); - - /* rcode */ - char rcode[16] = ""; - DNSCreateRcodeString(tx->rcode, rcode, sizeof(rcode)); - json_object_set_new(js, "rcode", json_string(rcode)); - - /* we are logging an answer RR */ - if (entry != NULL) { - /* query */ - if (entry->fqdn_len > 0) { - char *c; - c = BytesToString((uint8_t *)((uint8_t *)entry + sizeof(DNSAnswerEntry)), - entry->fqdn_len); - if (c != NULL) { - json_object_set_new(js, "rrname", json_string(c)); - SCFree(c); - } - } - - /* name */ - char record[16] = ""; - DNSCreateTypeString(entry->type, record, sizeof(record)); - json_object_set_new(js, "rrtype", json_string(record)); - - /* ttl */ - json_object_set_new(js, "ttl", json_integer(entry->ttl)); - - uint8_t *ptr = (uint8_t *)((uint8_t *)entry + sizeof(DNSAnswerEntry)+ entry->fqdn_len); - if (entry->type == DNS_RECORD_TYPE_A) { - char a[16] = ""; - PrintInet(AF_INET, (const void *)ptr, a, sizeof(a)); - json_object_set_new(js, "rdata", json_string(a)); - } else if (entry->type == DNS_RECORD_TYPE_AAAA) { - char a[46] = ""; - PrintInet(AF_INET6, (const void *)ptr, a, sizeof(a)); - json_object_set_new(js, "rdata", json_string(a)); - } else if (entry->data_len == 0) { - json_object_set_new(js, "rdata", json_string("")); - } else if (entry->type == DNS_RECORD_TYPE_TXT || entry->type == DNS_RECORD_TYPE_CNAME || - entry->type == DNS_RECORD_TYPE_MX || entry->type == DNS_RECORD_TYPE_PTR) { - if (entry->data_len != 0) { - char buffer[256] = ""; - uint16_t copy_len = entry->data_len < (sizeof(buffer) - 1) ? - entry->data_len : sizeof(buffer) - 1; - memcpy(buffer, ptr, copy_len); - buffer[copy_len] = '\0'; - json_object_set_new(js, "rdata", json_string(buffer)); - } else { - json_object_set_new(js, "rdata", json_string("")); - } - } - } - - /* reset */ - MemBufferReset(buffer); - json_object_set_new(djs, "dns", js); - OutputJSONBuffer(djs, aft->dnslog_ctx->file_ctx, buffer); - json_object_del(djs, "dns"); - - return; -} - -static void OutputFailure(LogDnsLogThread *aft, json_t *djs, DNSTransaction *tx, DNSQueryEntry *entry) -{ - MemBuffer *buffer = (MemBuffer *)aft->buffer; - json_t *js = json_object(); - if (js == NULL) - return; - - /* type */ - json_object_set_new(js, "type", json_string("answer")); - - /* id */ - json_object_set_new(js, "id", json_integer(tx->tx_id)); - - /* rcode */ - char rcode[16] = ""; - DNSCreateRcodeString(tx->rcode, rcode, sizeof(rcode)); - json_object_set_new(js, "rcode", json_string(rcode)); - - /* no answer RRs, use query for rname */ - char *c; - c = BytesToString((uint8_t *)((uint8_t *)entry + sizeof(DNSQueryEntry)), entry->len); - if (c != NULL) { - json_object_set_new(js, "rrname", json_string(c)); - SCFree(c); - } - - /* reset */ - MemBufferReset(buffer); - json_object_set_new(djs, "dns", js); - OutputJSONBuffer(djs, aft->dnslog_ctx->file_ctx, buffer); - json_object_del(djs, "dns"); - - return; -} - -static void LogAnswers(LogDnsLogThread *aft, json_t *js, DNSTransaction *tx, uint64_t tx_id) -{ - - SCLogDebug("got a DNS response and now logging !!"); - - /* rcode != noerror */ - if (tx->rcode) { - /* Most DNS servers do not support multiple queries because - * the rcode in response is not per-query. Multiple queries - * are likely to lead to FORMERR, so log this. */ - DNSQueryEntry *query = NULL; - TAILQ_FOREACH(query, &tx->query_list, next) { - OutputFailure(aft, js, tx, query); - } - } - - DNSAnswerEntry *entry = NULL; - TAILQ_FOREACH(entry, &tx->answer_list, next) { - OutputAnswer(aft, js, tx, entry); - } - - entry = NULL; - TAILQ_FOREACH(entry, &tx->authority_list, next) { - OutputAnswer(aft, js, tx, entry); - } - -} - -static int JsonDnsLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id) -{ - SCEnter(); - - LogDnsLogThread *td = (LogDnsLogThread *)thread_data; - DNSTransaction *tx = txptr; - json_t *js; - - DNSQueryEntry *query = NULL; - TAILQ_FOREACH(query, &tx->query_list, next) { - js = CreateJSONHeader((Packet *)p, 1, "dns"); - if (unlikely(js == NULL)) - return TM_ECODE_OK; - - LogQuery(td, js, tx, tx_id, query); - - json_decref(js); - } - - js = CreateJSONHeader((Packet *)p, 0, "dns"); - if (unlikely(js == NULL)) - return TM_ECODE_OK; - - LogAnswers(td, js, tx, tx_id); - - json_decref(js); - - SCReturnInt(TM_ECODE_OK); -} - -#define OUTPUT_BUFFER_SIZE 65536 -static TmEcode LogDnsLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogDnsLogThread *aft = SCMalloc(sizeof(LogDnsLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(LogDnsLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for DNSLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->dnslog_ctx= ((OutputCtx *)initdata)->data; - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode LogDnsLogThreadDeinit(ThreadVars *t, void *data) -{ - LogDnsLogThread *aft = (LogDnsLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(LogDnsLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void LogDnsLogDeInitCtx(OutputCtx *output_ctx) -{ - LogDnsFileCtx *dnslog_ctx = (LogDnsFileCtx *)output_ctx->data; - LogFileFreeCtx(dnslog_ctx->file_ctx); - SCFree(dnslog_ctx); - SCFree(output_ctx); -} - -static void LogDnsLogDeInitCtxSub(OutputCtx *output_ctx) -{ - SCLogDebug("cleaning up sub output_ctx %p", output_ctx); - LogDnsFileCtx *dnslog_ctx = (LogDnsFileCtx *)output_ctx->data; - SCFree(dnslog_ctx); - SCFree(output_ctx); -} - -static OutputCtx *JsonDnsLogInitCtxSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - AlertJsonThread *ajt = parent_ctx->data; - - LogDnsFileCtx *dnslog_ctx = SCMalloc(sizeof(LogDnsFileCtx)); - if (unlikely(dnslog_ctx == NULL)) { - return NULL; - } - memset(dnslog_ctx, 0x00, sizeof(LogDnsFileCtx)); - - dnslog_ctx->file_ctx = ajt->file_ctx; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(dnslog_ctx); - return NULL; - } - - output_ctx->data = dnslog_ctx; - output_ctx->DeInit = LogDnsLogDeInitCtxSub; - - SCLogDebug("DNS log sub-module initialized"); - - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_DNS); - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_DNS); - - return output_ctx; -} - -#define DEFAULT_LOG_FILENAME "dns.json" -/** \brief Create a new dns log LogFileCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFileCtx* to the file_ctx if succesful - * */ -static OutputCtx *JsonDnsLogInitCtx(ConfNode *conf) -{ - LogFileCtx *file_ctx = LogFileNewCtx(); - - if(file_ctx == NULL) { - SCLogError(SC_ERR_DNS_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - LogDnsFileCtx *dnslog_ctx = SCMalloc(sizeof(LogDnsFileCtx)); - if (unlikely(dnslog_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - memset(dnslog_ctx, 0x00, sizeof(LogDnsFileCtx)); - - dnslog_ctx->file_ctx = file_ctx; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(dnslog_ctx); - return NULL; - } - - output_ctx->data = dnslog_ctx; - output_ctx->DeInit = LogDnsLogDeInitCtx; - - SCLogDebug("DNS log output initialized"); - - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_DNS); - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_DNS); - - return output_ctx; -} - - -#define MODULE_NAME "JsonDnsLog" -void TmModuleJsonDnsLogRegister (void) -{ - tmm_modules[TMM_JSONDNSLOG].name = MODULE_NAME; - tmm_modules[TMM_JSONDNSLOG].ThreadInit = LogDnsLogThreadInit; - tmm_modules[TMM_JSONDNSLOG].ThreadDeinit = LogDnsLogThreadDeinit; - tmm_modules[TMM_JSONDNSLOG].RegisterTests = NULL; - tmm_modules[TMM_JSONDNSLOG].cap_flags = 0; - tmm_modules[TMM_JSONDNSLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterTxModule(MODULE_NAME, "dns-json-log", JsonDnsLogInitCtx, - ALPROTO_DNS, JsonDnsLogger); - OutputRegisterTxSubModule("eve-log", MODULE_NAME, "eve-log.dns", JsonDnsLogInitCtxSub, - ALPROTO_DNS, JsonDnsLogger); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonDnsLogRegister (void) -{ - tmm_modules[TMM_JSONDNSLOG].name = "JsonDnsLog"; - tmm_modules[TMM_JSONDNSLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-dns.h b/framework/src/suricata/src/output-json-dns.h deleted file mode 100644 index f26227e3..00000000 --- a/framework/src/suricata/src/output-json-dns.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - */ - -#ifndef __OUTPUT_JSON_DNS_H__ -#define __OUTPUT_JSON_DNS_H__ - -void TmModuleJsonDnsLogRegister (void); - -#endif /* __OUTPUT_JSON_DNS_H__ */ diff --git a/framework/src/suricata/src/output-json-drop.c b/framework/src/suricata/src/output-json-drop.c deleted file mode 100644 index c9b01df8..00000000 --- a/framework/src/suricata/src/output-json-drop.c +++ /dev/null @@ -1,427 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * JSON Drop log module to log the dropped packet information - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" - -#include "threads.h" -#include "tm-threads.h" -#include "threadvars.h" -#include "util-debug.h" - -#include "decode-ipv4.h" -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-reference.h" - -#include "output.h" -#include "output-json.h" -#include "output-json-alert.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-classification-config.h" -#include "util-privs.h" -#include "util-print.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" -#include "util-buffer.h" - -#define MODULE_NAME "JsonDropLog" - -#ifdef HAVE_LIBJANSSON -#include - -#define LOG_DROP_ALERTS 1 - -typedef struct JsonDropOutputCtx_ { - LogFileCtx *file_ctx; - uint8_t flags; -} JsonDropOutputCtx; - -typedef struct JsonDropLogThread_ { - JsonDropOutputCtx *drop_ctx; - MemBuffer *buffer; -} JsonDropLogThread; - -/** - * \brief Log the dropped packets in netfilter format when engine is running - * in inline mode - * - * \param tv Pointer the current thread variables - * \param p Pointer the packet which is being logged - * - * \return return TM_EODE_OK on success - */ -static int DropLogJSON (JsonDropLogThread *aft, const Packet *p) -{ - uint16_t proto = 0; - MemBuffer *buffer = (MemBuffer *)aft->buffer; - json_t *js = CreateJSONHeader((Packet *)p, 0, "drop");//TODO const - if (unlikely(js == NULL)) - return TM_ECODE_OK; - - json_t *djs = json_object(); - if (unlikely(djs == NULL)) { - json_decref(js); - return TM_ECODE_OK; - } - - /* reset */ - MemBufferReset(buffer); - - if (PKT_IS_IPV4(p)) { - json_object_set_new(djs, "len", json_integer(IPV4_GET_IPLEN(p))); - json_object_set_new(djs, "tos", json_integer(IPV4_GET_IPTOS(p))); - json_object_set_new(djs, "ttl", json_integer(IPV4_GET_IPTTL(p))); - json_object_set_new(djs, "ipid", json_integer(IPV4_GET_IPID(p))); - proto = IPV4_GET_IPPROTO(p); - } else if (PKT_IS_IPV6(p)) { - json_object_set_new(djs, "len", json_integer(IPV6_GET_PLEN(p))); - json_object_set_new(djs, "tc", json_integer(IPV6_GET_CLASS(p))); - json_object_set_new(djs, "hoplimit", json_integer(IPV6_GET_HLIM(p))); - json_object_set_new(djs, "flowlbl", json_integer(IPV6_GET_FLOW(p))); - proto = IPV6_GET_L4PROTO(p); - } - switch (proto) { - case IPPROTO_TCP: - json_object_set_new(djs, "tcpseq", json_integer(TCP_GET_SEQ(p))); - json_object_set_new(djs, "tcpack", json_integer(TCP_GET_ACK(p))); - json_object_set_new(djs, "tcpwin", json_integer(TCP_GET_WINDOW(p))); - json_object_set_new(djs, "syn", TCP_ISSET_FLAG_SYN(p) ? json_true() : json_false()); - json_object_set_new(djs, "ack", TCP_ISSET_FLAG_ACK(p) ? json_true() : json_false()); - json_object_set_new(djs, "psh", TCP_ISSET_FLAG_PUSH(p) ? json_true() : json_false()); - json_object_set_new(djs, "rst", TCP_ISSET_FLAG_RST(p) ? json_true() : json_false()); - json_object_set_new(djs, "urg", TCP_ISSET_FLAG_URG(p) ? json_true() : json_false()); - json_object_set_new(djs, "fin", TCP_ISSET_FLAG_FIN(p) ? json_true() : json_false()); - json_object_set_new(djs, "tcpres", json_integer(TCP_GET_RAW_X2(p->tcph))); - json_object_set_new(djs, "tcpurgp", json_integer(TCP_GET_URG_POINTER(p))); - break; - case IPPROTO_UDP: - json_object_set_new(djs, "udplen", json_integer(UDP_GET_LEN(p))); - break; - case IPPROTO_ICMP: - if (PKT_IS_ICMPV4(p)) { - json_object_set_new(djs, "icmp_id", json_integer(ICMPV4_GET_ID(p))); - json_object_set_new(djs, "icmp_seq", json_integer(ICMPV4_GET_SEQ(p))); - } else if(PKT_IS_ICMPV6(p)) { - json_object_set_new(djs, "icmp_id", json_integer(ICMPV6_GET_ID(p))); - json_object_set_new(djs, "icmp_seq", json_integer(ICMPV6_GET_SEQ(p))); - } - break; - } - json_object_set_new(js, "drop", djs); - - if (aft->drop_ctx->flags & LOG_DROP_ALERTS) { - int logged = 0; - int i; - for (i = 0; i < p->alerts.cnt; i++) { - const PacketAlert *pa = &p->alerts.alerts[i]; - if (unlikely(pa->s == NULL)) { - continue; - } - if ((pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) || - ((pa->action & ACTION_DROP) && EngineModeIsIPS())) - { - AlertJsonHeader(p, pa, js); - logged = 1; - } - } - if (logged == 0) { - if (p->alerts.drop.action != 0) { - const PacketAlert *pa = &p->alerts.drop; - AlertJsonHeader(p, pa, js); - } - } - } - - OutputJSONBuffer(js, aft->drop_ctx->file_ctx, buffer); - json_object_del(js, "drop"); - json_object_clear(js); - json_decref(js); - - return TM_ECODE_OK; -} - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonDropLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonDropLogThread *aft = SCMalloc(sizeof(JsonDropLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(*aft)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for AlertFastLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - /** Use the Ouptut Context (file pointer and mutex) */ - aft->drop_ctx = ((OutputCtx *)initdata)->data; - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonDropLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonDropLogThread *aft = (JsonDropLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - - /* clear memory */ - memset(aft, 0, sizeof(*aft)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void JsonDropLogDeInitCtx(OutputCtx *output_ctx) -{ - OutputDropLoggerDisable(); - - LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - LogFileFreeCtx(logfile_ctx); - SCFree(output_ctx); -} - -static void JsonDropLogDeInitCtxSub(OutputCtx *output_ctx) -{ - OutputDropLoggerDisable(); - - SCLogDebug("cleaning up sub output_ctx %p", output_ctx); - SCFree(output_ctx); -} - -static void JsonDropOutputCtxFree(JsonDropOutputCtx *drop_ctx) -{ - if (drop_ctx != NULL) { - if (drop_ctx->file_ctx != NULL) - LogFileFreeCtx(drop_ctx->file_ctx); - SCFree(drop_ctx); - } -} - -#define DEFAULT_LOG_FILENAME "drop.json" -static OutputCtx *JsonDropLogInitCtx(ConfNode *conf) -{ - if (OutputDropLoggerEnable() != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'drop' logger " - "can be enabled"); - return NULL; - } - - JsonDropOutputCtx *drop_ctx = SCCalloc(1, sizeof(*drop_ctx)); - if (drop_ctx == NULL) - return NULL; - - drop_ctx->file_ctx = LogFileNewCtx(); - if (drop_ctx->file_ctx == NULL) { - JsonDropOutputCtxFree(drop_ctx); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, drop_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - JsonDropOutputCtxFree(drop_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - JsonDropOutputCtxFree(drop_ctx); - return NULL; - } - - if (conf) { - const char *extended = ConfNodeLookupChildValue(conf, "alerts"); - if (extended != NULL) { - if (ConfValIsTrue(extended)) { - drop_ctx->flags = LOG_DROP_ALERTS; - } - } - } - - output_ctx->data = drop_ctx; - output_ctx->DeInit = JsonDropLogDeInitCtx; - return output_ctx; -} - -static OutputCtx *JsonDropLogInitCtxSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - if (OutputDropLoggerEnable() != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'drop' logger " - "can be enabled"); - return NULL; - } - - AlertJsonThread *ajt = parent_ctx->data; - - JsonDropOutputCtx *drop_ctx = SCCalloc(1, sizeof(*drop_ctx)); - if (drop_ctx == NULL) - return NULL; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - JsonDropOutputCtxFree(drop_ctx); - return NULL; - } - - if (conf) { - const char *extended = ConfNodeLookupChildValue(conf, "alerts"); - if (extended != NULL) { - if (ConfValIsTrue(extended)) { - drop_ctx->flags = LOG_DROP_ALERTS; - } - } - } - - drop_ctx->file_ctx = ajt->file_ctx; - - output_ctx->data = drop_ctx; - output_ctx->DeInit = JsonDropLogDeInitCtxSub; - return output_ctx; -} - -/** - * \brief Log the dropped packets when engine is running in inline mode - * - * \param tv Pointer the current thread variables - * \param data Pointer to the droplog struct - * \param p Pointer the packet which is being logged - * - * \retval 0 on succes - */ -static int JsonDropLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - JsonDropLogThread *td = thread_data; - int r = DropLogJSON(td, p); - if (r < 0) - return -1; - - if (p->flow) { - FLOWLOCK_RDLOCK(p->flow); - if (p->flow->flags & FLOW_ACTION_DROP) { - if (PKT_IS_TOSERVER(p) && !(p->flow->flags & FLOW_TOSERVER_DROP_LOGGED)) - p->flow->flags |= FLOW_TOSERVER_DROP_LOGGED; - else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED)) - p->flow->flags |= FLOW_TOCLIENT_DROP_LOGGED; - } - FLOWLOCK_UNLOCK(p->flow); - } - return 0; -} - - -/** - * \brief Check if we need to drop-log this packet - * - * \param tv Pointer the current thread variables - * \param p Pointer the packet which is tested - * - * \retval bool TRUE or FALSE - */ -static int JsonDropLogCondition(ThreadVars *tv, const Packet *p) -{ - if (!EngineModeIsIPS()) { - SCLogDebug("engine is not running in inline mode, so returning"); - return FALSE; - } - if (PKT_IS_PSEUDOPKT(p)) { - SCLogDebug("drop log doesn't log pseudo packets"); - return FALSE; - } - - if (p->flow != NULL) { - int ret = FALSE; - - /* for a flow that will be dropped fully, log just once per direction */ - FLOWLOCK_RDLOCK(p->flow); - if (p->flow->flags & FLOW_ACTION_DROP) { - if (PKT_IS_TOSERVER(p) && !(p->flow->flags & FLOW_TOSERVER_DROP_LOGGED)) - ret = TRUE; - else if (PKT_IS_TOCLIENT(p) && !(p->flow->flags & FLOW_TOCLIENT_DROP_LOGGED)) - ret = TRUE; - } - FLOWLOCK_UNLOCK(p->flow); - - /* if drop is caused by signature, log anyway */ - if (p->alerts.drop.action != 0) - ret = TRUE; - - return ret; - } else if (PACKET_TEST_ACTION(p, ACTION_DROP)) { - return TRUE; - } - - return FALSE; -} - -void TmModuleJsonDropLogRegister (void) -{ - tmm_modules[TMM_JSONDROPLOG].name = MODULE_NAME; - tmm_modules[TMM_JSONDROPLOG].ThreadInit = JsonDropLogThreadInit; - tmm_modules[TMM_JSONDROPLOG].ThreadDeinit = JsonDropLogThreadDeinit; - tmm_modules[TMM_JSONDROPLOG].cap_flags = 0; - tmm_modules[TMM_JSONDROPLOG].flags = TM_FLAG_LOGAPI_TM; - - OutputRegisterPacketModule(MODULE_NAME, "drop-json-log", - JsonDropLogInitCtx, JsonDropLogger, JsonDropLogCondition); - OutputRegisterPacketSubModule("eve-log", MODULE_NAME, "eve-log.drop", - JsonDropLogInitCtxSub, JsonDropLogger, JsonDropLogCondition); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonDropLogRegister (void) -{ - tmm_modules[TMM_JSONDROPLOG].name = MODULE_NAME; - tmm_modules[TMM_JSONDROPLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-drop.h b/framework/src/suricata/src/output-json-drop.h deleted file mode 100644 index c02057c1..00000000 --- a/framework/src/suricata/src/output-json-drop.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - */ - -#ifndef __OUTPUT_JSON_DROP_H__ -#define __OUTPUT_JSON_DROP_H__ - -void TmModuleJsonDropLogRegister (void); - -#endif /* __OUTPUT_DROPLOG_H__ */ diff --git a/framework/src/suricata/src/output-json-email-common.c b/framework/src/suricata/src/output-json-email-common.c deleted file mode 100644 index 88cd3acf..00000000 --- a/framework/src/suricata/src/output-json-email-common.c +++ /dev/null @@ -1,459 +0,0 @@ -/* Copyright (C) 2007-2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * \author Eric Leblond - * - * Implements json common email logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "tm-threads-common.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" -#include "app-layer-parser.h" -#include "output.h" -#include "app-layer-smtp.h" -#include "app-layer.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-byte.h" - -#include "util-logopenfile.h" -#include "util-crypt.h" - -#include "output-json.h" -#include "output-json-email-common.h" - -#ifdef HAVE_LIBJANSSON -#include - -#define LOG_EMAIL_DEFAULT 0 -#define LOG_EMAIL_EXTENDED (1<<0) -#define LOG_EMAIL_ARRAY (1<<1) /* require array handling */ -#define LOG_EMAIL_COMMA (1<<2) /* require array handling */ -#define LOG_EMAIL_BODY_MD5 (1<<3) -#define LOG_EMAIL_SUBJECT_MD5 (1<<4) - -struct { - char *config_field; - char *email_field; - uint32_t flags; -} email_fields[] = { - { "reply_to", "reply-to", LOG_EMAIL_DEFAULT }, - { "bcc", "bcc", LOG_EMAIL_COMMA|LOG_EMAIL_EXTENDED }, - { "message_id", "message-id", LOG_EMAIL_EXTENDED }, - { "subject", "subject", LOG_EMAIL_EXTENDED }, - { "x_mailer", "x-mailer", LOG_EMAIL_EXTENDED }, - { "user_agent", "user-agent", LOG_EMAIL_EXTENDED }, - { "received", "received", LOG_EMAIL_ARRAY }, - { "x_originating_ip", "x-originating-ip", LOG_EMAIL_DEFAULT }, - { "in_reply_to", "in-reply-to", LOG_EMAIL_DEFAULT }, - { "references", "references", LOG_EMAIL_DEFAULT }, - { "importance", "importance", LOG_EMAIL_DEFAULT }, - { "priority", "priority", LOG_EMAIL_DEFAULT }, - { "sensitivity", "sensitivity", LOG_EMAIL_DEFAULT }, - { "organization", "organization", LOG_EMAIL_DEFAULT }, - { "content_md5", "content-md5", LOG_EMAIL_DEFAULT }, - { "date", "date", LOG_EMAIL_DEFAULT }, - { NULL, NULL, LOG_EMAIL_DEFAULT}, -}; - -static inline char *SkipWhiteSpaceTill(char *p, char *savep) -{ - char *sp = p; - if (unlikely(p == NULL)) { - return NULL; - } - while (((*sp == '\t') || (*sp == ' ')) && (sp < savep)) { - sp++; - } - return sp; -} - -static json_t* JsonEmailJsonArrayFromCommaList(const uint8_t *val, size_t len) -{ - json_t *ajs = json_array(); - if (likely(ajs != NULL)) { - char *savep = NULL; - char *p; - char *sp; - char *to_line = BytesToString((uint8_t *)val, len); - if (likely(to_line != NULL)) { - p = strtok_r(to_line, ",", &savep); - if (p == NULL) { - json_decref(ajs); - SCFree(to_line); - return NULL; - } - sp = SkipWhiteSpaceTill(p, savep); - json_array_append_new(ajs, json_string(sp)); - while ((p = strtok_r(NULL, ",", &savep)) != NULL) { - sp = SkipWhiteSpaceTill(p, savep); - json_array_append_new(ajs, json_string(sp)); - } - } - SCFree(to_line); - } - - return ajs; -} - - -#ifdef HAVE_NSS -static void JsonEmailLogJSONMd5(OutputJsonEmailCtx *email_ctx, json_t *js, SMTPTransaction *tx) -{ - if (email_ctx->flags & LOG_EMAIL_SUBJECT_MD5) { - MimeDecField *field; - MimeDecEntity *entity = tx->msg_tail; - if (entity == NULL) { - return; - } - field = MimeDecFindField(entity, "subject"); - if (field != NULL) { - unsigned char md5[MD5_LENGTH]; - char smd5[256]; - char *value = BytesToString((uint8_t *)field->value , field->value_len); - if (value) { - size_t i,x; - HASH_HashBuf(HASH_AlgMD5, md5, (unsigned char *)value, strlen(value)); - for (i = 0, x = 0; x < sizeof(md5); x++) { - i += snprintf(smd5 + i, 255 - i, "%02x", md5[x]); - } - json_object_set_new(js, "subject_md5", json_string(smd5)); - SCFree(value); - } - } - } - - if (email_ctx->flags & LOG_EMAIL_BODY_MD5) { - MimeDecParseState *mime_state = tx->mime_state; - if (mime_state && mime_state->md5_ctx && (mime_state->state_flag == PARSE_DONE)) { - size_t x; - int i; - char s[256]; - if (likely(s != NULL)) { - for (i = 0, x = 0; x < sizeof(mime_state->md5); x++) { - i += snprintf(s + i, 255-i, "%02x", mime_state->md5[x]); - } - json_object_set_new(js, "body_md5", json_string(s)); - } - } - } -} -#endif - -static int JsonEmailAddToJsonArray(const uint8_t *val, size_t len, void *data) -{ - json_t *ajs = data; - - if (ajs == NULL) - return 0; - char *value = BytesToString((uint8_t *)val, len); - json_array_append_new(ajs, json_string(value)); - SCFree(value); - return 1; -} - -static void JsonEmailLogJSONCustom(OutputJsonEmailCtx *email_ctx, json_t *js, SMTPTransaction *tx) -{ - int f = 0; - MimeDecField *field; - MimeDecEntity *entity = tx->msg_tail; - if (entity == NULL) { - return; - } - - while(email_fields[f].config_field) { - if (((email_ctx->fields & (1ULL<flags & LOG_EMAIL_EXTENDED) && (email_fields[f].flags & LOG_EMAIL_EXTENDED)) - ) { - if (email_fields[f].flags & LOG_EMAIL_ARRAY) { - json_t *ajs = json_array(); - if (ajs) { - int found = MimeDecFindFieldsForEach(entity, email_fields[f].email_field, JsonEmailAddToJsonArray, ajs); - if (found > 0) { - json_object_set_new(js, email_fields[f].config_field, ajs); - } else { - json_decref(ajs); - } - } - } else if (email_fields[f].flags & LOG_EMAIL_COMMA) { - field = MimeDecFindField(entity, email_fields[f].email_field); - if (field) { - json_t *ajs = JsonEmailJsonArrayFromCommaList(field->value, field->value_len); - if (ajs) { - json_object_set_new(js, email_fields[f].config_field, ajs); - } - } - } else { - field = MimeDecFindField(entity, email_fields[f].email_field); - if (field != NULL) { - char *s = BytesToString((uint8_t *)field->value, - (size_t)field->value_len); - if (likely(s != NULL)) { - json_object_set_new(js, email_fields[f].config_field, json_string(s)); - SCFree(s); - } - } - } - - } - f++; - } -} - -/* JSON format logging */ -json_t *JsonEmailLogJsonData(const Flow *f, void *state, void *vtx, uint64_t tx_id) -{ - SMTPState *smtp_state; - MimeDecParseState *mime_state; - MimeDecEntity *entity; - - json_t *sjs = json_object(); - if (sjs == NULL) { - SCReturnPtr(NULL, "json_t"); - } - - /* check if we have SMTP state or not */ - AppProto proto = FlowGetAppProtocol(f); - switch (proto) { - case ALPROTO_SMTP: - smtp_state = (SMTPState *)state; - if (smtp_state == NULL) { - SCLogDebug("no smtp state, so no request logging"); - SCReturnPtr(NULL, "json_t"); - } - SMTPTransaction *tx = vtx; - mime_state = tx->mime_state; - entity = tx->msg_tail; - SCLogDebug("lets go mime_state %p, entity %p, state_flag %u", mime_state, entity, mime_state ? mime_state->state_flag : 0); - break; - default: - /* don't know how we got here */ - SCReturnPtr(NULL, "json_t"); - } - if ((mime_state != NULL)) { - if (entity == NULL) { - SCReturnPtr(NULL, "json_t"); - } - - json_object_set_new(sjs, "status", - json_string(MimeDecParseStateGetStatus(mime_state))); - - MimeDecField *field; - - /* From: */ - field = MimeDecFindField(entity, "from"); - if (field != NULL) { - char *s = BytesToString((uint8_t *)field->value, - (size_t)field->value_len); - if (likely(s != NULL)) { - //printf("From: \"%s\"\n", s); - char * sp = SkipWhiteSpaceTill(s, s + strlen(s)); - json_object_set_new(sjs, "from", json_string(sp)); - SCFree(s); - } - } - - /* To: */ - field = MimeDecFindField(entity, "to"); - if (field != NULL) { - json_t *ajs = JsonEmailJsonArrayFromCommaList(field->value, field->value_len); - if (ajs) { - json_object_set_new(sjs, "to", ajs); - } - } - - /* Cc: */ - field = MimeDecFindField(entity, "cc"); - if (field != NULL) { - json_t *ajs = JsonEmailJsonArrayFromCommaList(field->value, field->value_len); - if (ajs) { - json_object_set_new(sjs, "cc", ajs); - } - } - - if (mime_state->stack == NULL || mime_state->stack->top == NULL || mime_state->stack->top->data == NULL) - SCReturnPtr(NULL, "json_t"); - - entity = (MimeDecEntity *)mime_state->stack->top->data; - int attch_cnt = 0; - int url_cnt = 0; - json_t *js_attch = json_array(); - json_t *js_url = json_array(); - if (entity->url_list != NULL) { - MimeDecUrl *url; - for (url = entity->url_list; url != NULL; url = url->next) { - char *s = BytesToString((uint8_t *)url->url, - (size_t)url->url_len); - if (s != NULL) { - json_array_append_new(js_url, - json_string(s)); - SCFree(s); - url_cnt += 1; - } - } - } - for (entity = entity->child; entity != NULL; entity = entity->next) { - if (entity->ctnt_flags & CTNT_IS_ATTACHMENT) { - - char *s = BytesToString((uint8_t *)entity->filename, - (size_t)entity->filename_len); - json_array_append_new(js_attch, - json_string(s)); - SCFree(s); - attch_cnt += 1; - } - if (entity->url_list != NULL) { - MimeDecUrl *url; - for (url = entity->url_list; url != NULL; url = url->next) { - char *s = BytesToString((uint8_t *)url->url, - (size_t)url->url_len); - if (s != NULL) { - json_array_append_new(js_url, - json_string(s)); - SCFree(s); - url_cnt += 1; - } - } - } - } - if (attch_cnt > 0) { - json_object_set_new(sjs, "attachment", js_attch); - } else { - json_decref(js_attch); - } - if (url_cnt > 0) { - json_object_set_new(sjs, "url", js_url); - } else { - json_decref(js_url); - } - SCReturnPtr(sjs, "json_t"); - } - - json_decref(sjs); - SCReturnPtr(NULL, "json_t"); -} - -/* JSON format logging */ -TmEcode JsonEmailLogJson(JsonEmailLogThread *aft, json_t *js, const Packet *p, Flow *f, void *state, void *vtx, uint64_t tx_id) -{ - json_t *sjs = JsonEmailLogJsonData(f, state, vtx, tx_id); - OutputJsonEmailCtx *email_ctx = aft->emaillog_ctx; - SMTPTransaction *tx = (SMTPTransaction *) vtx; - - if ((email_ctx->flags & LOG_EMAIL_EXTENDED) || (email_ctx->fields != 0)) - JsonEmailLogJSONCustom(email_ctx, sjs, tx); - -#ifdef HAVE_NSS - JsonEmailLogJSONMd5(email_ctx, sjs, tx); -#endif - - if (sjs) { - json_object_set_new(js, "email", sjs); - SCReturnInt(TM_ECODE_OK); - } else - SCReturnInt(TM_ECODE_FAILED); -} - -json_t *JsonEmailAddMetadata(const Flow *f, uint32_t tx_id) -{ - SMTPState *smtp_state = (SMTPState *)FlowGetAppState(f); - if (smtp_state) { - SMTPTransaction *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_SMTP, smtp_state, tx_id); - - if (tx) { - return JsonEmailLogJsonData(f, smtp_state, tx, tx_id); - } - } - - return NULL; -} - - -void OutputEmailInitConf(ConfNode *conf, OutputJsonEmailCtx *email_ctx) -{ - if (conf) { - const char *extended = ConfNodeLookupChildValue(conf, "extended"); - - if (extended != NULL) { - if (ConfValIsTrue(extended)) { - email_ctx->flags = LOG_EMAIL_EXTENDED; - } - } - - email_ctx->fields = 0; - ConfNode *custom; - if ((custom = ConfNodeLookupChild(conf, "custom")) != NULL) { - ConfNode *field; - TAILQ_FOREACH(field, &custom->head, next) { - if (field != NULL) { - int f = 0; - while(email_fields[f].config_field) { - if ((strcmp(email_fields[f].config_field, - field->val) == 0) || - (strcasecmp(email_fields[f].email_field, - field->val) == 0)) - { - email_ctx->fields |= (1ULL<flags = 0; - ConfNode *md5_conf; - if ((md5_conf = ConfNodeLookupChild(conf, "md5")) != NULL) { - ConfNode *field; - TAILQ_FOREACH(field, &md5_conf->head, next) { - if (field != NULL) { - if (strcmp("body", field->val) == 0) { - SCLogInfo("Going to log the md5 sum of email body"); - email_ctx->flags |= LOG_EMAIL_BODY_MD5; - } - if (strcmp("subject", field->val) == 0) { - SCLogInfo("Going to log the md5 sum of email subject"); - email_ctx->flags |= LOG_EMAIL_SUBJECT_MD5; - } - } - } - } - } - return; -} - - -#endif diff --git a/framework/src/suricata/src/output-json-email-common.h b/framework/src/suricata/src/output-json-email-common.h deleted file mode 100644 index 88cfa557..00000000 --- a/framework/src/suricata/src/output-json-email-common.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - */ - -#ifndef __OUTPUT_JSON_EMAIL_COMMON_H__ -#define __OUTPUT_JSON_EMAIL_COMMON_H__ - -typedef struct OutputJsonEmailCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ - uint64_t fields;/** Store fields */ -} OutputJsonEmailCtx; - - -#ifdef HAVE_LIBJANSSON -typedef struct JsonEmailLogThread_ { - OutputJsonEmailCtx *emaillog_ctx; - MemBuffer *buffer; -} JsonEmailLogThread; - -TmEcode JsonEmailLogJson(JsonEmailLogThread *aft, json_t *js, const Packet *p, Flow *f, void *state, void *vtx, uint64_t tx_id); -json_t *JsonEmailAddMetadata(const Flow *f, uint32_t tx_id); -#endif - -void OutputEmailInitConf(ConfNode *conf, OutputJsonEmailCtx *email_ctx); - -#endif /* __OUTPUT_JSON_EMAIL_COMMON_H__ */ diff --git a/framework/src/suricata/src/output-json-file.c b/framework/src/suricata/src/output-json-file.c deleted file mode 100644 index 9506a746..00000000 --- a/framework/src/suricata/src/output-json-file.c +++ /dev/null @@ -1,311 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * Log files we track. - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threadvars.h" -#include "tm-modules.h" - -#include "threads.h" - -#include "app-layer-parser.h" - -#include "detect-filemagic.h" - -#include "stream.h" - -#include "util-print.h" -#include "util-unittest.h" -#include "util-privs.h" -#include "util-debug.h" -#include "util-atomic.h" -#include "util-file.h" -#include "util-time.h" -#include "util-buffer.h" -#include "util-byte.h" - -#include "log-file.h" -#include "util-logopenfile.h" - -#include "output.h" -#include "output-json.h" -#include "output-json-http.h" -#include "output-json-smtp.h" -#include "output-json-email-common.h" - -#include "app-layer-htp.h" -#include "util-memcmp.h" -#include "stream-tcp-reassemble.h" - -#ifdef HAVE_LIBJANSSON -#include - -typedef struct OutputFileCtx_ { - LogFileCtx *file_ctx; - uint32_t file_cnt; -} OutputFileCtx; - -typedef struct JsonFileLogThread_ { - OutputFileCtx *filelog_ctx; - MemBuffer *buffer; -} JsonFileLogThread; - -/** - * \internal - * \brief Write meta data on a single line json record - */ -static void FileWriteJsonRecord(JsonFileLogThread *aft, const Packet *p, const File *ff) -{ - MemBuffer *buffer = (MemBuffer *)aft->buffer; - json_t *js = CreateJSONHeader((Packet *)p, 0, "fileinfo"); //TODO const - json_t *hjs = NULL; - if (unlikely(js == NULL)) - return; - - /* reset */ - MemBufferReset(buffer); - - switch (p->flow->alproto) { - case ALPROTO_HTTP: - hjs = JsonHttpAddMetadata(p->flow, ff->txid); - if (hjs) - json_object_set_new(js, "http", hjs); - break; - case ALPROTO_SMTP: - hjs = JsonSMTPAddMetadata(p->flow, ff->txid); - if (hjs) - json_object_set_new(js, "smtp", hjs); - hjs = JsonEmailAddMetadata(p->flow, ff->txid); - if (hjs) - json_object_set_new(js, "email", hjs); - break; - } - - - json_t *fjs = json_object(); - if (unlikely(fjs == NULL)) { - json_decref(js); - return; - } - - char *s = BytesToString(ff->name, ff->name_len); - json_object_set_new(fjs, "filename", json_string(s)); - if (s != NULL) - SCFree(s); - if (ff->magic) - json_object_set_new(fjs, "magic", json_string((char *)ff->magic)); - switch (ff->state) { - case FILE_STATE_CLOSED: - json_object_set_new(fjs, "state", json_string("CLOSED")); -#ifdef HAVE_NSS - if (ff->flags & FILE_MD5) { - size_t x; - int i; - char s[256]; - for (i = 0, x = 0; x < sizeof(ff->md5); x++) { - i += snprintf(&s[i], 255-i, "%02x", ff->md5[x]); - } - json_object_set_new(fjs, "md5", json_string(s)); - } -#endif - break; - case FILE_STATE_TRUNCATED: - json_object_set_new(fjs, "state", json_string("TRUNCATED")); - break; - case FILE_STATE_ERROR: - json_object_set_new(fjs, "state", json_string("ERROR")); - break; - default: - json_object_set_new(fjs, "state", json_string("UNKNOWN")); - break; - } - json_object_set_new(fjs, "stored", - (ff->flags & FILE_STORED) ? json_true() : json_false()); - if (ff->flags & FILE_STORED) { - json_object_set_new(fjs, "file_id", json_integer(ff->file_id)); - } - json_object_set_new(fjs, "size", json_integer(ff->size)); - json_object_set_new(fjs, "tx_id", json_integer(ff->txid)); - - /* originally just 'file', but due to bug 1127 naming it fileinfo */ - json_object_set_new(js, "fileinfo", fjs); - OutputJSONBuffer(js, aft->filelog_ctx->file_ctx, buffer); - json_object_del(js, "fileinfo"); - - switch (p->flow->alproto) { - case ALPROTO_HTTP: - json_object_del(js, "http"); - break; - case ALPROTO_SMTP: - json_object_del(js, "smtp"); - json_object_del(js, "email"); - break; - } - - json_object_clear(js); - json_decref(js); -} - -static int JsonFileLogger(ThreadVars *tv, void *thread_data, const Packet *p, const File *ff) -{ - SCEnter(); - JsonFileLogThread *aft = (JsonFileLogThread *)thread_data; - - BUG_ON(ff->flags & FILE_LOGGED); - - SCLogDebug("ff %p", ff); - - FileWriteJsonRecord(aft, p, ff); - return 0; -} - - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonFileLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonFileLogThread *aft = SCMalloc(sizeof(JsonFileLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(JsonFileLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for HTTPLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->filelog_ctx = ((OutputCtx *)initdata)->data; - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonFileLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonFileLogThread *aft = (JsonFileLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(JsonFileLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void OutputFileLogDeinitSub(OutputCtx *output_ctx) -{ - OutputFileCtx *ff_ctx = output_ctx->data; - SCFree(ff_ctx); - SCFree(output_ctx); -} - -/** \brief Create a new http log LogFileCtx. - * \param conf Pointer to ConfNode containing this loggers configuration. - * \return NULL if failure, LogFileCtx* to the file_ctx if succesful - * */ -OutputCtx *OutputFileLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputJsonCtx *ojc = parent_ctx->data; - - OutputFileCtx *output_file_ctx = SCMalloc(sizeof(OutputFileCtx)); - if (unlikely(output_file_ctx == NULL)) - return NULL; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(output_file_ctx); - return NULL; - } - - output_file_ctx->file_ctx = ojc->file_ctx; - - if (conf) { - const char *force_magic = ConfNodeLookupChildValue(conf, "force-magic"); - if (force_magic != NULL && ConfValIsTrue(force_magic)) { - FileForceMagicEnable(); - SCLogInfo("forcing magic lookup for logged files"); - } - - const char *force_md5 = ConfNodeLookupChildValue(conf, "force-md5"); - if (force_md5 != NULL && ConfValIsTrue(force_md5)) { -#ifdef HAVE_NSS - FileForceMd5Enable(); - SCLogInfo("forcing md5 calculation for logged files"); -#else - SCLogInfo("md5 calculation requires linking against libnss"); -#endif - } - } - - output_ctx->data = output_file_ctx; - output_ctx->DeInit = OutputFileLogDeinitSub; - - FileForceTrackingEnable(); - return output_ctx; -} - -void TmModuleJsonFileLogRegister (void) -{ - tmm_modules[TMM_JSONFILELOG].name = "JsonFileLog"; - tmm_modules[TMM_JSONFILELOG].ThreadInit = JsonFileLogThreadInit; - tmm_modules[TMM_JSONFILELOG].ThreadDeinit = JsonFileLogThreadDeinit; - tmm_modules[TMM_JSONFILELOG].flags = TM_FLAG_LOGAPI_TM; - - /* register as child of eve-log */ - OutputRegisterFileSubModule("eve-log", "JsonFileLog", "eve-log.files", - OutputFileLogInitSub, JsonFileLogger); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonFileLogRegister (void) -{ - tmm_modules[TMM_JSONFILELOG].name = "JsonFileLog"; - tmm_modules[TMM_JSONFILELOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-file.h b/framework/src/suricata/src/output-json-file.h deleted file mode 100644 index e101897f..00000000 --- a/framework/src/suricata/src/output-json-file.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - */ - -#ifndef __OUTPUT_JSON_FILE_H__ -#define __OUTPUT_JSON_FILE_H__ - -void TmModuleJsonFileLogRegister (void); - -#endif /* __OUTPUT_JSON_FILE_H__ */ diff --git a/framework/src/suricata/src/output-json-flow.c b/framework/src/suricata/src/output-json-flow.c deleted file mode 100644 index 7ff0d3d2..00000000 --- a/framework/src/suricata/src/output-json-flow.c +++ /dev/null @@ -1,485 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements Flow JSON logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" -#include "output-json.h" - -#include "stream-tcp-private.h" - -#ifdef HAVE_LIBJANSSON -#include - -typedef struct LogJsonFileCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ -} LogJsonFileCtx; - -typedef struct JsonFlowLogThread_ { - LogJsonFileCtx *flowlog_ctx; - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - uint32_t uri_cnt; - - MemBuffer *buffer; -} JsonFlowLogThread; - - -#define LOG_HTTP_DEFAULT 0 -#define LOG_HTTP_EXTENDED 1 -#define LOG_HTTP_CUSTOM 2 - -static json_t *CreateJSONHeaderFromFlow(Flow *f, char *event_type) -{ - char timebuf[64]; - char srcip[46], dstip[46]; - Port sp, dp; - - json_t *js = json_object(); - if (unlikely(js == NULL)) - return NULL; - - struct timeval tv; - memset(&tv, 0x00, sizeof(tv)); - TimeGet(&tv); - - CreateIsoTimeString(&tv, timebuf, sizeof(timebuf)); - - srcip[0] = '\0'; - dstip[0] = '\0'; - if (FLOW_IS_IPV4(f)) { - PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip)); - } else if (FLOW_IS_IPV6(f)) { - PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip)); - } - - sp = f->sp; - dp = f->dp; - - char proto[16]; - if (SCProtoNameValid(f->proto) == TRUE) { - strlcpy(proto, known_proto[f->proto], sizeof(proto)); - } else { - snprintf(proto, sizeof(proto), "%03" PRIu32, f->proto); - } - - /* time */ - json_object_set_new(js, "timestamp", json_string(timebuf)); - - CreateJSONFlowId(js, (const Flow *)f); - -#if 0 // TODO - /* sensor id */ - if (sensor_id >= 0) - json_object_set_new(js, "sensor_id", json_integer(sensor_id)); -#endif - if (event_type) { - json_object_set_new(js, "event_type", json_string(event_type)); - } -#if 0 - /* vlan */ - if (f->vlan_id[0] > 0) { - json_t *js_vlan; - switch (f->vlan_idx) { - case 1: - json_object_set_new(js, "vlan", - json_integer(f->vlan_id[0])); - break; - case 2: - js_vlan = json_array(); - if (unlikely(js != NULL)) { - json_array_append_new(js_vlan, - json_integer(VLAN_GET_ID1(p))); - json_array_append_new(js_vlan, - json_integer(VLAN_GET_ID2(p))); - json_object_set_new(js, "vlan", js_vlan); - } - break; - default: - /* shouldn't get here */ - break; - } - } -#endif - /* tuple */ - json_object_set_new(js, "src_ip", json_string(srcip)); - switch(f->proto) { - case IPPROTO_ICMP: - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - json_object_set_new(js, "src_port", json_integer(sp)); - break; - } - json_object_set_new(js, "dest_ip", json_string(dstip)); - switch(f->proto) { - case IPPROTO_ICMP: - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - json_object_set_new(js, "dest_port", json_integer(dp)); - break; - } - json_object_set_new(js, "proto", json_string(proto)); - switch (f->proto) { - case IPPROTO_ICMP: - case IPPROTO_ICMPV6: - json_object_set_new(js, "icmp_type", - json_integer(f->type)); - json_object_set_new(js, "icmp_code", - json_integer(f->code)); - break; - } - return js; -} - -/* JSON format logging */ -static void JsonFlowLogJSON(JsonFlowLogThread *aft, json_t *js, Flow *f) -{ -#if 0 - LogJsonFileCtx *flow_ctx = aft->flowlog_ctx; -#endif - json_t *hjs = json_object(); - if (hjs == NULL) { - return; - } - - json_object_set_new(hjs, "app_proto", json_string(AppProtoToString(f->alproto))); - - json_object_set_new(hjs, "pkts_toserver", - json_integer(f->todstpktcnt)); - json_object_set_new(hjs, "pkts_toclient", - json_integer(f->tosrcpktcnt)); - json_object_set_new(hjs, "bytes_toserver", - json_integer(f->todstbytecnt)); - json_object_set_new(hjs, "bytes_toclient", - json_integer(f->tosrcbytecnt)); - - char timebuf1[64], timebuf2[64]; - - CreateIsoTimeString(&f->startts, timebuf1, sizeof(timebuf1)); - CreateIsoTimeString(&f->lastts, timebuf2, sizeof(timebuf2)); - - json_object_set_new(hjs, "start", json_string(timebuf1)); - json_object_set_new(hjs, "end", json_string(timebuf2)); - - int32_t age = f->lastts.tv_sec - f->startts.tv_sec; - json_object_set_new(hjs, "age", - json_integer(age)); - - if (f->flow_end_flags & FLOW_END_FLAG_EMERGENCY) - json_object_set_new(hjs, "emergency", json_true()); - const char *state = NULL; - if (f->flow_end_flags & FLOW_END_FLAG_STATE_NEW) - state = "new"; - else if (f->flow_end_flags & FLOW_END_FLAG_STATE_ESTABLISHED) - state = "established"; - else if (f->flow_end_flags & FLOW_END_FLAG_STATE_CLOSED) - state = "closed"; - - json_object_set_new(hjs, "state", - json_string(state)); - - const char *reason = NULL; - if (f->flow_end_flags & FLOW_END_FLAG_TIMEOUT) - reason = "timeout"; - else if (f->flow_end_flags & FLOW_END_FLAG_FORCED) - reason = "forced"; - else if (f->flow_end_flags & FLOW_END_FLAG_SHUTDOWN) - reason = "shutdown"; - - json_object_set_new(hjs, "reason", - json_string(reason)); - - json_object_set_new(js, "flow", hjs); - - - /* TCP */ - if (f->proto == IPPROTO_TCP) { - json_t *tjs = json_object(); - if (tjs == NULL) { - return; - } - - TcpSession *ssn = f->protoctx; - - char hexflags[3] = ""; - snprintf(hexflags, sizeof(hexflags), "%02x", - ssn ? ssn->tcp_packet_flags : 0); - json_object_set_new(tjs, "tcp_flags", json_string(hexflags)); - - snprintf(hexflags, sizeof(hexflags), "%02x", - ssn ? ssn->client.tcp_flags : 0); - json_object_set_new(tjs, "tcp_flags_ts", json_string(hexflags)); - - snprintf(hexflags, sizeof(hexflags), "%02x", - ssn ? ssn->server.tcp_flags : 0); - json_object_set_new(tjs, "tcp_flags_tc", json_string(hexflags)); - - JsonTcpFlags(ssn ? ssn->tcp_packet_flags : 0, tjs); - - if (ssn) { - char *state = NULL; - switch (ssn->state) { - case TCP_NONE: - state = "none"; - break; - case TCP_LISTEN: - state = "listen"; - break; - case TCP_SYN_SENT: - state = "syn_sent"; - break; - case TCP_SYN_RECV: - state = "syn_recv"; - break; - case TCP_ESTABLISHED: - state = "established"; - break; - case TCP_FIN_WAIT1: - state = "fin_wait1"; - break; - case TCP_FIN_WAIT2: - state = "fin_wait2"; - break; - case TCP_TIME_WAIT: - state = "time_wait"; - break; - case TCP_LAST_ACK: - state = "last_ack"; - break; - case TCP_CLOSE_WAIT: - state = "close_wait"; - break; - case TCP_CLOSING: - state = "closing"; - break; - case TCP_CLOSED: - state = "closed"; - break; - } - json_object_set_new(tjs, "state", json_string(state)); - } - - json_object_set_new(js, "tcp", tjs); - } -} - -static int JsonFlowLogger(ThreadVars *tv, void *thread_data, Flow *f) -{ - SCEnter(); - JsonFlowLogThread *jhl = (JsonFlowLogThread *)thread_data; - MemBuffer *buffer = (MemBuffer *)jhl->buffer; - - /* reset */ - MemBufferReset(buffer); - - json_t *js = CreateJSONHeaderFromFlow(f, "flow"); //TODO const - if (unlikely(js == NULL)) - return TM_ECODE_OK; - - JsonFlowLogJSON(jhl, js, f); - - OutputJSONBuffer(js, jhl->flowlog_ctx->file_ctx, buffer); - json_object_del(js, "http"); - - json_object_clear(js); - json_decref(js); - - SCReturnInt(TM_ECODE_OK); -} - -static void OutputFlowLogDeinit(OutputCtx *output_ctx) -{ - LogJsonFileCtx *flow_ctx = output_ctx->data; - LogFileCtx *logfile_ctx = flow_ctx->file_ctx; - LogFileFreeCtx(logfile_ctx); - SCFree(flow_ctx); - SCFree(output_ctx); -} - -#define DEFAULT_LOG_FILENAME "flow.json" -OutputCtx *OutputFlowLogInit(ConfNode *conf) -{ - SCLogInfo("hi"); - LogFileCtx *file_ctx = LogFileNewCtx(); - if(file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - LogJsonFileCtx *flow_ctx = SCMalloc(sizeof(LogJsonFileCtx)); - if (unlikely(flow_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(flow_ctx); - return NULL; - } - - flow_ctx->file_ctx = file_ctx; - output_ctx->data = flow_ctx; - output_ctx->DeInit = OutputFlowLogDeinit; - - return output_ctx; -} - -static void OutputFlowLogDeinitSub(OutputCtx *output_ctx) -{ - LogJsonFileCtx *flow_ctx = output_ctx->data; - SCFree(flow_ctx); - SCFree(output_ctx); -} - -OutputCtx *OutputFlowLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputJsonCtx *ojc = parent_ctx->data; - - LogJsonFileCtx *flow_ctx = SCMalloc(sizeof(LogJsonFileCtx)); - if (unlikely(flow_ctx == NULL)) - return NULL; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(flow_ctx); - return NULL; - } - - flow_ctx->file_ctx = ojc->file_ctx; - flow_ctx->flags = LOG_HTTP_DEFAULT; - - output_ctx->data = flow_ctx; - output_ctx->DeInit = OutputFlowLogDeinitSub; - - return output_ctx; -} - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonFlowLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonFlowLogThread *aft = SCMalloc(sizeof(JsonFlowLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(JsonFlowLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for HTTPLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->flowlog_ctx = ((OutputCtx *)initdata)->data; //TODO - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonFlowLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonFlowLogThread *aft = (JsonFlowLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(JsonFlowLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -void TmModuleJsonFlowLogRegister (void) -{ - tmm_modules[TMM_JSONFLOWLOG].name = "JsonFlowLog"; - tmm_modules[TMM_JSONFLOWLOG].ThreadInit = JsonFlowLogThreadInit; - tmm_modules[TMM_JSONFLOWLOG].ThreadDeinit = JsonFlowLogThreadDeinit; - tmm_modules[TMM_JSONFLOWLOG].RegisterTests = NULL; - tmm_modules[TMM_JSONFLOWLOG].cap_flags = 0; - tmm_modules[TMM_JSONFLOWLOG].flags = TM_FLAG_LOGAPI_TM; - - /* register as separate module */ - OutputRegisterFlowModule("JsonFlowLog", "flow-json-log", - OutputFlowLogInit, JsonFlowLogger); - - /* also register as child of eve-log */ - OutputRegisterFlowSubModule("eve-log", "JsonFlowLog", "eve-log.flow", - OutputFlowLogInitSub, JsonFlowLogger); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonFlowLogRegister (void) -{ - tmm_modules[TMM_JSONFLOWLOG].name = "JsonFlowLog"; - tmm_modules[TMM_JSONFLOWLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-flow.h b/framework/src/suricata/src/output-json-flow.h deleted file mode 100644 index 1d32c9eb..00000000 --- a/framework/src/suricata/src/output-json-flow.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * Victor Julien - */ - -#ifndef __OUTPUT_JSON_FLOW_H__ -#define __OUTPUT_JSON_FLOW_H__ - -void TmModuleJsonFlowLogRegister (void); - -#endif /* __OUTPUT_JSON_FLOW_H__ */ diff --git a/framework/src/suricata/src/output-json-http.c b/framework/src/suricata/src/output-json-http.c deleted file mode 100644 index 68739873..00000000 --- a/framework/src/suricata/src/output-json-http.c +++ /dev/null @@ -1,615 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * Implements HTTP JSON logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer-htp.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" -#include "output-json.h" - -#ifdef HAVE_LIBJANSSON -#include - -typedef struct LogHttpFileCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ - uint64_t fields;/** Store fields */ -} LogHttpFileCtx; - -typedef struct JsonHttpLogThread_ { - LogHttpFileCtx *httplog_ctx; - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - uint32_t uri_cnt; - - MemBuffer *buffer; -} JsonHttpLogThread; - - -#define LOG_HTTP_DEFAULT 0 -#define LOG_HTTP_EXTENDED 1 -#define LOG_HTTP_REQUEST 2 /* request field */ -#define LOG_HTTP_ARRAY 4 /* require array handling */ - -typedef enum { - HTTP_FIELD_ACCEPT = 0, - HTTP_FIELD_ACCEPT_CHARSET, - HTTP_FIELD_ACCEPT_ENCODING, - HTTP_FIELD_ACCEPT_LANGUAGE, - HTTP_FIELD_ACCEPT_DATETIME, - HTTP_FIELD_AUTHORIZATION, - HTTP_FIELD_CACHE_CONTROL, - HTTP_FIELD_CONNECTION, - HTTP_FIELD_FROM, - HTTP_FIELD_MAX_FORWARDS, - HTTP_FIELD_ORIGIN, - HTTP_FIELD_PRAGMA, - HTTP_FIELD_PROXY_AUTHORIZATION, - HTTP_FIELD_RANGE, - HTTP_FIELD_TE, - HTTP_FIELD_VIA, - HTTP_FIELD_X_REQUESTED_WITH, - HTTP_FIELD_DNT, - HTTP_FIELD_X_FORWARDED_PROTO, - HTTP_FIELD_ACCEPT_RANGES, - HTTP_FIELD_AGE, - HTTP_FIELD_ALLOW, - HTTP_FIELD_CONTENT_ENCODING, - HTTP_FIELD_CONTENT_LANGUAGE, - HTTP_FIELD_CONTENT_LENGTH, - HTTP_FIELD_CONTENT_LOCATION, - HTTP_FIELD_CONTENT_MD5, - HTTP_FIELD_CONTENT_RANGE, - HTTP_FIELD_CONTENT_TYPE, - HTTP_FIELD_DATE, - HTTP_FIELD_ETAG, - HTTP_FIELD_EXPIRES, - HTTP_FIELD_LAST_MODIFIED, - HTTP_FIELD_LINK, - HTTP_FIELD_LOCATION, - HTTP_FIELD_PROXY_AUTHENTICATE, - HTTP_FIELD_REFERRER, - HTTP_FIELD_REFRESH, - HTTP_FIELD_RETRY_AFTER, - HTTP_FIELD_SERVER, - HTTP_FIELD_SET_COOKIE, - HTTP_FIELD_TRAILER, - HTTP_FIELD_TRANSFER_ENCODING, - HTTP_FIELD_UPGRADE, - HTTP_FIELD_VARY, - HTTP_FIELD_WARNING, - HTTP_FIELD_WWW_AUTHENTICATE, - HTTP_FIELD_SIZE -} HttpField; - -struct { - char *config_field; - char *htp_field; - uint32_t flags; -} http_fields[] = { - { "accept", "accept", LOG_HTTP_REQUEST }, - { "accept_charset", "accept-charset", LOG_HTTP_REQUEST }, - { "accept_encoding", "accept-encoding", LOG_HTTP_REQUEST }, - { "accept_language", "accept-language", LOG_HTTP_REQUEST }, - { "accept_datetime", "accept-datetime", LOG_HTTP_REQUEST }, - { "authorization", "authorization", LOG_HTTP_REQUEST }, - { "cache_control", "cache-control", LOG_HTTP_REQUEST }, - { "cookie", "cookie", LOG_HTTP_REQUEST|LOG_HTTP_ARRAY }, - { "from", "from", LOG_HTTP_REQUEST }, - { "max_forwards", "max-forwards", LOG_HTTP_REQUEST }, - { "origin", "origin", LOG_HTTP_REQUEST }, - { "pragma", "pragma", LOG_HTTP_REQUEST }, - { "proxy_authorization", "proxy-authorization", LOG_HTTP_REQUEST }, - { "range", "range", LOG_HTTP_REQUEST }, - { "te", "te", LOG_HTTP_REQUEST }, - { "via", "via", LOG_HTTP_REQUEST }, - { "x_requested_with", "x-requested-with", LOG_HTTP_REQUEST }, - { "dnt", "dnt", LOG_HTTP_REQUEST }, - { "x_forwarded_proto", "x-forwarded-proto", LOG_HTTP_REQUEST }, - { "accept_range", "accept-range", 0 }, - { "age", "age", 0 }, - { "allow", "allow", 0 }, - { "connection", "connection", 0 }, - { "content_encoding", "content-encoding", 0 }, - { "content_language", "content-language", 0 }, - { "content_length", "content-length", 0 }, - { "content_location", "content-location", 0 }, - { "content_md5", "content-md5", 0 }, - { "content_range", "content-range", 0 }, - { "content_type", "content-type", 0 }, - { "date", "date", 0 }, - { "etag", "etags", 0 }, - { "expires", "expires" , 0 }, - { "last_modified", "last-modified", 0 }, - { "link", "link", 0 }, - { "location", "location", 0 }, - { "proxy_authenticate", "proxy-authenticate", 0 }, - { "referrer", "referrer", LOG_HTTP_EXTENDED }, - { "refresh", "refresh", 0 }, - { "retry_after", "retry-after", 0 }, - { "server", "server", 0 }, - { "set_cookie", "set-cookie", 0 }, - { "trailer", "trailer", 0 }, - { "transfer_encoding", "transfer-encoding", 0 }, - { "upgrade", "upgrade", 0 }, - { "vary", "vary", 0 }, - { "warning", "warning", 0 }, - { "www_authenticate", "www-authenticate", 0 }, -}; - -void JsonHttpLogJSONBasic(json_t *js, htp_tx_t *tx) -{ - char *c; - - /* hostname */ - if (tx->request_hostname != NULL) - { - c = bstr_util_strdup_to_c(tx->request_hostname); - if (c != NULL) { - json_object_set_new(js, "hostname", json_string(c)); - SCFree(c); - } - } - - /* uri */ - if (tx->request_uri != NULL) - { - c = bstr_util_strdup_to_c(tx->request_uri); - if (c != NULL) { - json_object_set_new(js, "url", json_string(c)); - SCFree(c); - } - } - - /* user agent */ - htp_header_t *h_user_agent = NULL; - if (tx->request_headers != NULL) { - h_user_agent = htp_table_get_c(tx->request_headers, "user-agent"); - } - if (h_user_agent != NULL) { - c = bstr_util_strdup_to_c(h_user_agent->value); - if (c != NULL) { - json_object_set_new(js, "http_user_agent", json_string(c)); - SCFree(c); - } - } - - /* x-forwarded-for */ - htp_header_t *h_x_forwarded_for = NULL; - if (tx->request_headers != NULL) { - h_x_forwarded_for = htp_table_get_c(tx->request_headers, "x-forwarded-for"); - } - if (h_x_forwarded_for != NULL) { - c = bstr_util_strdup_to_c(h_x_forwarded_for->value); - if (c != NULL) { - json_object_set_new(js, "xff", json_string(c)); - SCFree(c); - } - } - - /* content-type */ - htp_header_t *h_content_type = NULL; - if (tx->response_headers != NULL) { - h_content_type = htp_table_get_c(tx->response_headers, "content-type"); - } - if (h_content_type != NULL) { - char *p; - c = bstr_util_strdup_to_c(h_content_type->value); - if (c != NULL) { - p = strchr(c, ';'); - if (p != NULL) - *p = '\0'; - json_object_set_new(js, "http_content_type", json_string(c)); - SCFree(c); - } - } -} - -static void JsonHttpLogJSONCustom(LogHttpFileCtx *http_ctx, json_t *js, htp_tx_t *tx) -{ - char *c; - HttpField f; - - for (f = HTTP_FIELD_ACCEPT; f < HTTP_FIELD_SIZE; f++) - { - if ((http_ctx->fields & (1ULL<flags & LOG_HTTP_EXTENDED) == 0) || - ((http_ctx->flags & LOG_HTTP_EXTENDED) != - (http_fields[f].flags & LOG_HTTP_EXTENDED))) - { - htp_header_t *h_field = NULL; - if ((http_fields[f].flags & LOG_HTTP_REQUEST) != 0) - { - if (tx->request_headers != NULL) { - h_field = htp_table_get_c(tx->request_headers, - http_fields[f].htp_field); - } - } else { - if (tx->response_headers != NULL) { - h_field = htp_table_get_c(tx->response_headers, - http_fields[f].htp_field); - } - } - if (h_field != NULL) { - c = bstr_util_strdup_to_c(h_field->value); - if (c != NULL) { - json_object_set_new(js, - http_fields[f].config_field, - json_string(c)); - SCFree(c); - } - } - } - } - } -} - -void JsonHttpLogJSONExtended(json_t *js, htp_tx_t *tx) -{ - char *c; - - /* referer */ - htp_header_t *h_referer = NULL; - if (tx->request_headers != NULL) { - h_referer = htp_table_get_c(tx->request_headers, "referer"); - } - if (h_referer != NULL) { - c = bstr_util_strdup_to_c(h_referer->value); - if (c != NULL) { - json_object_set_new(js, "http_refer", json_string(c)); - SCFree(c); - } - } - - /* method */ - if (tx->request_method != NULL) { - c = bstr_util_strdup_to_c(tx->request_method); - if (c != NULL) { - json_object_set_new(js, "http_method", json_string(c)); - SCFree(c); - } - } - - /* protocol */ - if (tx->request_protocol != NULL) { - c = bstr_util_strdup_to_c(tx->request_protocol); - if (c != NULL) { - json_object_set_new(js, "protocol", json_string(c)); - SCFree(c); - } - } - - /* response status */ - if (tx->response_status != NULL) { - c = bstr_util_strdup_to_c(tx->response_status); - if (c != NULL) { - unsigned int val = strtoul(c, NULL, 10); - json_object_set_new(js, "status", json_integer(val)); - SCFree(c); - } - - htp_header_t *h_location = htp_table_get_c(tx->response_headers, "location"); - if (h_location != NULL) { - c = bstr_util_strdup_to_c(h_location->value); - if (c != NULL) { - json_object_set_new(js, "redirect", json_string(c)); - SCFree(c); - } - } - } - - /* length */ - json_object_set_new(js, "length", json_integer(tx->response_message_len)); -} - -/* JSON format logging */ -static void JsonHttpLogJSON(JsonHttpLogThread *aft, json_t *js, htp_tx_t *tx, uint64_t tx_id) -{ - LogHttpFileCtx *http_ctx = aft->httplog_ctx; - json_t *hjs = json_object(); - if (hjs == NULL) { - return; - } - - JsonHttpLogJSONBasic(hjs, tx); - /* log custom fields if configured */ - if (http_ctx->fields != 0) - JsonHttpLogJSONCustom(http_ctx, hjs, tx); - if (http_ctx->flags & LOG_HTTP_EXTENDED) - JsonHttpLogJSONExtended(hjs, tx); - - json_object_set_new(js, "http", hjs); -} - -static int JsonHttpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id) -{ - SCEnter(); - - htp_tx_t *tx = txptr; - JsonHttpLogThread *jhl = (JsonHttpLogThread *)thread_data; - MemBuffer *buffer = (MemBuffer *)jhl->buffer; - - json_t *js = CreateJSONHeaderWithTxId((Packet *)p, 1, "http", tx_id); //TODO const - if (unlikely(js == NULL)) - return TM_ECODE_OK; - - SCLogDebug("got a HTTP request and now logging !!"); - - /* reset */ - MemBufferReset(buffer); - - JsonHttpLogJSON(jhl, js, tx, tx_id); - - OutputJSONBuffer(js, jhl->httplog_ctx->file_ctx, buffer); - json_object_del(js, "http"); - - json_object_clear(js); - json_decref(js); - - SCReturnInt(TM_ECODE_OK); -} - -json_t *JsonHttpAddMetadata(const Flow *f, uint64_t tx_id) -{ - HtpState *htp_state = (HtpState *)FlowGetAppState(f); - if (htp_state) { - htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, tx_id); - - if (tx) { - json_t *hjs = json_object(); - if (unlikely(hjs == NULL)) - return NULL; - - JsonHttpLogJSONBasic(hjs, tx); - JsonHttpLogJSONExtended(hjs, tx); - - return hjs; - } - } - - return NULL; -} - -static void OutputHttpLogDeinit(OutputCtx *output_ctx) -{ - LogHttpFileCtx *http_ctx = output_ctx->data; - LogFileCtx *logfile_ctx = http_ctx->file_ctx; - LogFileFreeCtx(logfile_ctx); - SCFree(http_ctx); - SCFree(output_ctx); -} - -#define DEFAULT_LOG_FILENAME "http.json" -OutputCtx *OutputHttpLogInit(ConfNode *conf) -{ - LogFileCtx *file_ctx = LogFileNewCtx(); - if(file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - LogHttpFileCtx *http_ctx = SCMalloc(sizeof(LogHttpFileCtx)); - if (unlikely(http_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(http_ctx); - return NULL; - } - - http_ctx->file_ctx = file_ctx; - http_ctx->flags = LOG_HTTP_DEFAULT; - - if (conf) { - const char *extended = ConfNodeLookupChildValue(conf, "extended"); - - if (extended != NULL) { - if (ConfValIsTrue(extended)) { - http_ctx->flags = LOG_HTTP_EXTENDED; - } - } - } - output_ctx->data = http_ctx; - output_ctx->DeInit = OutputHttpLogDeinit; - - /* enable the logger for the app layer */ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_HTTP); - - return output_ctx; -} - -static void OutputHttpLogDeinitSub(OutputCtx *output_ctx) -{ - LogHttpFileCtx *http_ctx = output_ctx->data; - SCFree(http_ctx); - SCFree(output_ctx); -} - -OutputCtx *OutputHttpLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputJsonCtx *ojc = parent_ctx->data; - - LogHttpFileCtx *http_ctx = SCMalloc(sizeof(LogHttpFileCtx)); - if (unlikely(http_ctx == NULL)) - return NULL; - memset(http_ctx, 0x00, sizeof(*http_ctx)); - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(http_ctx); - return NULL; - } - - http_ctx->file_ctx = ojc->file_ctx; - http_ctx->flags = LOG_HTTP_DEFAULT; - - if (conf) { - const char *extended = ConfNodeLookupChildValue(conf, "extended"); - - if (extended != NULL) { - if (ConfValIsTrue(extended)) { - http_ctx->flags = LOG_HTTP_EXTENDED; - } - } - - ConfNode *custom; - if ((custom = ConfNodeLookupChild(conf, "custom")) != NULL) { - ConfNode *field; - TAILQ_FOREACH(field, &custom->head, next) - { - if (field != NULL) - { - HttpField f; - for (f = HTTP_FIELD_ACCEPT; f < HTTP_FIELD_SIZE; f++) - { - if ((strcmp(http_fields[f].config_field, - field->val) == 0) || - (strcasecmp(http_fields[f].htp_field, - field->val) == 0)) - { - http_ctx->fields |= (1ULL<data = http_ctx; - output_ctx->DeInit = OutputHttpLogDeinitSub; - - /* enable the logger for the app layer */ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_HTTP); - - return output_ctx; -} - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonHttpLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonHttpLogThread *aft = SCMalloc(sizeof(JsonHttpLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(JsonHttpLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for HTTPLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->httplog_ctx = ((OutputCtx *)initdata)->data; //TODO - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonHttpLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonHttpLogThread *aft = (JsonHttpLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(JsonHttpLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -void TmModuleJsonHttpLogRegister (void) -{ - tmm_modules[TMM_JSONHTTPLOG].name = "JsonHttpLog"; - tmm_modules[TMM_JSONHTTPLOG].ThreadInit = JsonHttpLogThreadInit; - tmm_modules[TMM_JSONHTTPLOG].ThreadDeinit = JsonHttpLogThreadDeinit; - tmm_modules[TMM_JSONHTTPLOG].RegisterTests = NULL; - tmm_modules[TMM_JSONHTTPLOG].cap_flags = 0; - tmm_modules[TMM_JSONHTTPLOG].flags = TM_FLAG_LOGAPI_TM; - - /* register as separate module */ - OutputRegisterTxModule("JsonHttpLog", "http-json-log", OutputHttpLogInit, - ALPROTO_HTTP, JsonHttpLogger); - - /* also register as child of eve-log */ - OutputRegisterTxSubModule("eve-log", "JsonHttpLog", "eve-log.http", OutputHttpLogInitSub, - ALPROTO_HTTP, JsonHttpLogger); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonHttpLogRegister (void) -{ - tmm_modules[TMM_JSONHTTPLOG].name = "JsonHttpLog"; - tmm_modules[TMM_JSONHTTPLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-http.h b/framework/src/suricata/src/output-json-http.h deleted file mode 100644 index 0c886f3d..00000000 --- a/framework/src/suricata/src/output-json-http.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - */ - -#ifndef __OUTPUT_JSON_HTTP_H__ -#define __OUTPUT_JSON_HTTP_H__ - -void TmModuleJsonHttpLogRegister (void); - -#ifdef HAVE_LIBJANSSON -void JsonHttpLogJSONBasic(json_t *js, htp_tx_t *tx); -void JsonHttpLogJSONExtended(json_t *js, htp_tx_t *tx); -json_t *JsonHttpAddMetadata(const Flow *f, uint64_t tx_id); -#endif /* HAVE_LIBJANSSON */ - -#endif /* __OUTPUT_JSON_HTTP_H__ */ - diff --git a/framework/src/suricata/src/output-json-netflow.c b/framework/src/suricata/src/output-json-netflow.c deleted file mode 100644 index 153beb3d..00000000 --- a/framework/src/suricata/src/output-json-netflow.c +++ /dev/null @@ -1,467 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements Unidirectiontal NetFlow JSON logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" -#include "output-json.h" - -#include "stream-tcp-private.h" - -#ifdef HAVE_LIBJANSSON -#include - -typedef struct LogJsonFileCtx_ { - LogFileCtx *file_ctx; -} LogJsonFileCtx; - -typedef struct JsonNetFlowLogThread_ { - LogJsonFileCtx *flowlog_ctx; - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - - MemBuffer *buffer; -} JsonNetFlowLogThread; - - -static json_t *CreateJSONHeaderFromFlow(Flow *f, char *event_type, int dir) -{ - char timebuf[64]; - char srcip[46], dstip[46]; - Port sp, dp; - - json_t *js = json_object(); - if (unlikely(js == NULL)) - return NULL; - - struct timeval tv; - memset(&tv, 0x00, sizeof(tv)); - TimeGet(&tv); - - CreateIsoTimeString(&tv, timebuf, sizeof(timebuf)); - - srcip[0] = '\0'; - dstip[0] = '\0'; - if (FLOW_IS_IPV4(f)) { - if (dir == 0) { - PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip)); - } else { - PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), dstip, sizeof(dstip)); - } - } else if (FLOW_IS_IPV6(f)) { - if (dir == 0) { - PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip)); - } else { - PrintInet(AF_INET6, (const void *)&(f->dst.address), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)&(f->src.address), dstip, sizeof(dstip)); - } - } - - if (dir == 0) { - sp = f->sp; - dp = f->dp; - } else { - sp = f->dp; - dp = f->sp; - } - - char proto[16]; - if (SCProtoNameValid(f->proto) == TRUE) { - strlcpy(proto, known_proto[f->proto], sizeof(proto)); - } else { - snprintf(proto, sizeof(proto), "%03" PRIu32, f->proto); - } - - /* time */ - json_object_set_new(js, "timestamp", json_string(timebuf)); - - CreateJSONFlowId(js, (const Flow *)f); - -#if 0 // TODO - /* sensor id */ - if (sensor_id >= 0) - json_object_set_new(js, "sensor_id", json_integer(sensor_id)); -#endif - if (event_type) { - json_object_set_new(js, "event_type", json_string(event_type)); - } -#if 0 - /* vlan */ - if (f->vlan_id[0] > 0) { - json_t *js_vlan; - switch (f->vlan_idx) { - case 1: - json_object_set_new(js, "vlan", - json_integer(f->vlan_id[0])); - break; - case 2: - js_vlan = json_array(); - if (unlikely(js != NULL)) { - json_array_append_new(js_vlan, - json_integer(VLAN_GET_ID1(p))); - json_array_append_new(js_vlan, - json_integer(VLAN_GET_ID2(p))); - json_object_set_new(js, "vlan", js_vlan); - } - break; - default: - /* shouldn't get here */ - break; - } - } -#endif - /* tuple */ - json_object_set_new(js, "src_ip", json_string(srcip)); - switch(f->proto) { - case IPPROTO_ICMP: - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - json_object_set_new(js, "src_port", json_integer(sp)); - break; - } - json_object_set_new(js, "dest_ip", json_string(dstip)); - switch(f->proto) { - case IPPROTO_ICMP: - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - json_object_set_new(js, "dest_port", json_integer(dp)); - break; - } - json_object_set_new(js, "proto", json_string(proto)); - switch (f->proto) { - case IPPROTO_ICMP: - case IPPROTO_ICMPV6: - json_object_set_new(js, "icmp_type", - json_integer(f->type)); - json_object_set_new(js, "icmp_code", - json_integer(f->code)); - break; - } - return js; -} - -/* JSON format logging */ -static void JsonNetFlowLogJSONToServer(JsonNetFlowLogThread *aft, json_t *js, Flow *f) -{ - json_t *hjs = json_object(); - if (hjs == NULL) { - return; - } - - json_object_set_new(hjs, "app_proto", - json_string(AppProtoToString(f->alproto_ts ? f->alproto_ts : f->alproto))); - - json_object_set_new(hjs, "pkts", - json_integer(f->todstpktcnt)); - json_object_set_new(hjs, "bytes", - json_integer(f->todstbytecnt)); - - char timebuf1[64], timebuf2[64]; - - CreateIsoTimeString(&f->startts, timebuf1, sizeof(timebuf1)); - CreateIsoTimeString(&f->lastts, timebuf2, sizeof(timebuf2)); - - json_object_set_new(hjs, "start", json_string(timebuf1)); - json_object_set_new(hjs, "end", json_string(timebuf2)); - - int32_t age = f->lastts.tv_sec - f->startts.tv_sec; - json_object_set_new(hjs, "age", - json_integer(age)); - - json_object_set_new(js, "netflow", hjs); - - /* TCP */ - if (f->proto == IPPROTO_TCP) { - json_t *tjs = json_object(); - if (tjs == NULL) { - return; - } - - TcpSession *ssn = f->protoctx; - - char hexflags[3] = ""; - snprintf(hexflags, sizeof(hexflags), "%02x", - ssn ? ssn->client.tcp_flags : 0); - json_object_set_new(tjs, "tcp_flags", json_string(hexflags)); - - JsonTcpFlags(ssn ? ssn->client.tcp_flags : 0, tjs); - - json_object_set_new(js, "tcp", tjs); - } -} - -static void JsonNetFlowLogJSONToClient(JsonNetFlowLogThread *aft, json_t *js, Flow *f) -{ - json_t *hjs = json_object(); - if (hjs == NULL) { - return; - } - - json_object_set_new(hjs, "app_proto", - json_string(AppProtoToString(f->alproto_tc ? f->alproto_tc : f->alproto))); - - json_object_set_new(hjs, "pkts", - json_integer(f->tosrcpktcnt)); - json_object_set_new(hjs, "bytes", - json_integer(f->tosrcbytecnt)); - - char timebuf1[64], timebuf2[64]; - - CreateIsoTimeString(&f->startts, timebuf1, sizeof(timebuf1)); - CreateIsoTimeString(&f->lastts, timebuf2, sizeof(timebuf2)); - - json_object_set_new(hjs, "start", json_string(timebuf1)); - json_object_set_new(hjs, "end", json_string(timebuf2)); - - int32_t age = f->lastts.tv_sec - f->startts.tv_sec; - json_object_set_new(hjs, "age", - json_integer(age)); - - json_object_set_new(js, "netflow", hjs); - - /* TCP */ - if (f->proto == IPPROTO_TCP) { - json_t *tjs = json_object(); - if (tjs == NULL) { - return; - } - - TcpSession *ssn = f->protoctx; - - char hexflags[3] = ""; - snprintf(hexflags, sizeof(hexflags), "%02x", - ssn ? ssn->server.tcp_flags : 0); - json_object_set_new(tjs, "tcp_flags", json_string(hexflags)); - - JsonTcpFlags(ssn ? ssn->server.tcp_flags : 0, tjs); - - json_object_set_new(js, "tcp", tjs); - } -} - -static int JsonNetFlowLogger(ThreadVars *tv, void *thread_data, Flow *f) -{ - SCEnter(); - JsonNetFlowLogThread *jhl = (JsonNetFlowLogThread *)thread_data; - MemBuffer *buffer = (MemBuffer *)jhl->buffer; - - /* reset */ - MemBufferReset(buffer); - json_t *js = CreateJSONHeaderFromFlow(f, "netflow", 0); //TODO const - if (unlikely(js == NULL)) - return TM_ECODE_OK; - JsonNetFlowLogJSONToServer(jhl, js, f); - OutputJSONBuffer(js, jhl->flowlog_ctx->file_ctx, buffer); - json_object_del(js, "netflow"); - json_object_clear(js); - json_decref(js); - - /* reset */ - MemBufferReset(buffer); - js = CreateJSONHeaderFromFlow(f, "netflow", 1); //TODO const - if (unlikely(js == NULL)) - return TM_ECODE_OK; - JsonNetFlowLogJSONToClient(jhl, js, f); - OutputJSONBuffer(js, jhl->flowlog_ctx->file_ctx, buffer); - json_object_del(js, "netflow"); - json_object_clear(js); - json_decref(js); - - SCReturnInt(TM_ECODE_OK); -} - -static void OutputNetFlowLogDeinit(OutputCtx *output_ctx) -{ - LogJsonFileCtx *flow_ctx = output_ctx->data; - LogFileCtx *logfile_ctx = flow_ctx->file_ctx; - LogFileFreeCtx(logfile_ctx); - SCFree(flow_ctx); - SCFree(output_ctx); -} - -#define DEFAULT_LOG_FILENAME "netflow.json" -OutputCtx *OutputNetFlowLogInit(ConfNode *conf) -{ - SCLogInfo("hi"); - LogFileCtx *file_ctx = LogFileNewCtx(); - if(file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - LogJsonFileCtx *flow_ctx = SCMalloc(sizeof(LogJsonFileCtx)); - if (unlikely(flow_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(flow_ctx); - return NULL; - } - - flow_ctx->file_ctx = file_ctx; - output_ctx->data = flow_ctx; - output_ctx->DeInit = OutputNetFlowLogDeinit; - - return output_ctx; -} - -static void OutputNetFlowLogDeinitSub(OutputCtx *output_ctx) -{ - LogJsonFileCtx *flow_ctx = output_ctx->data; - SCFree(flow_ctx); - SCFree(output_ctx); -} - -OutputCtx *OutputNetFlowLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputJsonCtx *ojc = parent_ctx->data; - - LogJsonFileCtx *flow_ctx = SCMalloc(sizeof(LogJsonFileCtx)); - if (unlikely(flow_ctx == NULL)) - return NULL; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(flow_ctx); - return NULL; - } - - flow_ctx->file_ctx = ojc->file_ctx; - - output_ctx->data = flow_ctx; - output_ctx->DeInit = OutputNetFlowLogDeinitSub; - - return output_ctx; -} - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonNetFlowLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonNetFlowLogThread *aft = SCMalloc(sizeof(JsonNetFlowLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(JsonNetFlowLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for HTTPLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->flowlog_ctx = ((OutputCtx *)initdata)->data; //TODO - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonNetFlowLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonNetFlowLogThread *aft = (JsonNetFlowLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(JsonNetFlowLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -void TmModuleJsonNetFlowLogRegister (void) -{ - tmm_modules[TMM_JSONNETFLOWLOG].name = "JsonNetFlowLog"; - tmm_modules[TMM_JSONNETFLOWLOG].ThreadInit = JsonNetFlowLogThreadInit; - tmm_modules[TMM_JSONNETFLOWLOG].ThreadDeinit = JsonNetFlowLogThreadDeinit; - tmm_modules[TMM_JSONNETFLOWLOG].RegisterTests = NULL; - tmm_modules[TMM_JSONNETFLOWLOG].cap_flags = 0; - tmm_modules[TMM_JSONNETFLOWLOG].flags = TM_FLAG_LOGAPI_TM; - - /* register as separate module */ - OutputRegisterFlowModule("JsonNetFlowLog", "netflow-json-log", - OutputNetFlowLogInit, JsonNetFlowLogger); - - /* also register as child of eve-log */ - OutputRegisterFlowSubModule("eve-log", "JsonNetFlowLog", "eve-log.netflow", - OutputNetFlowLogInitSub, JsonNetFlowLogger); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonNetFlowLogRegister (void) -{ - tmm_modules[TMM_JSONNETFLOWLOG].name = "JsonNetFlowLog"; - tmm_modules[TMM_JSONNETFLOWLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-netflow.h b/framework/src/suricata/src/output-json-netflow.h deleted file mode 100644 index 361cc3a0..00000000 --- a/framework/src/suricata/src/output-json-netflow.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * Victor Julien - */ - -#ifndef __OUTPUT_JSON_NETFLOW_H__ -#define __OUTPUT_JSON_NETFLOW_H__ - -void TmModuleJsonNetFlowLogRegister (void); - -#endif /* __OUTPUT_JSON_FLOW_H__ */ diff --git a/framework/src/suricata/src/output-json-smtp.c b/framework/src/suricata/src/output-json-smtp.c deleted file mode 100644 index 617b7247..00000000 --- a/framework/src/suricata/src/output-json-smtp.c +++ /dev/null @@ -1,296 +0,0 @@ -/* Copyright (C) 2007-2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * Implements SMTP JSON logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer-smtp.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#include "output-json.h" -#include "output-json-email-common.h" - -#ifdef HAVE_LIBJANSSON -#include - -static json_t *JsonSmtpDataLogger(const Flow *f, void *state, void *vtx, uint64_t tx_id) -{ - json_t *sjs = json_object(); - SMTPTransaction *tx = vtx; - SMTPString *rcptto_str; - if (sjs == NULL) { - return NULL; - } - if (((SMTPState *)state)->helo) { - json_object_set_new(sjs, "helo", - json_string((const char *)((SMTPState *)state)->helo)); - } - if (tx->mail_from) { - json_object_set_new(sjs, "mail_from", - json_string((const char *)tx->mail_from)); - } - if (!TAILQ_EMPTY(&tx->rcpt_to_list)) { - json_t *js_rcptto = json_array(); - if (likely(js_rcptto != NULL)) { - TAILQ_FOREACH(rcptto_str, &tx->rcpt_to_list, next) { - json_array_append_new(js_rcptto, json_string((char *)rcptto_str->str)); - } - json_object_set_new(sjs, "rcpt_to", js_rcptto); - } - } - - return sjs; -} - -static int JsonSmtpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) -{ - SCEnter(); - JsonEmailLogThread *jhl = (JsonEmailLogThread *)thread_data; - MemBuffer *buffer = (MemBuffer *)jhl->buffer; - - json_t *sjs; - json_t *js = CreateJSONHeaderWithTxId((Packet *)p, 1, "smtp", tx_id); - if (unlikely(js == NULL)) - return TM_ECODE_OK; - - /* reset */ - MemBufferReset(buffer); - - sjs = JsonSmtpDataLogger(f, state, tx, tx_id); - if (sjs) { - json_object_set_new(js, "smtp", sjs); - } - - if (JsonEmailLogJson(jhl, js, p, f, state, tx, tx_id) == TM_ECODE_OK) { - OutputJSONBuffer(js, jhl->emaillog_ctx->file_ctx, buffer); - } - json_object_del(js, "email"); - if (sjs) { - json_object_del(js, "smtp"); - } - - json_object_clear(js); - json_decref(js); - - SCReturnInt(TM_ECODE_OK); - -} - -json_t *JsonSMTPAddMetadata(const Flow *f, uint64_t tx_id) -{ - SMTPState *smtp_state = (SMTPState *)FlowGetAppState(f); - if (smtp_state) { - SMTPTransaction *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_SMTP, smtp_state, tx_id); - - if (tx) { - return JsonSmtpDataLogger(f, smtp_state, tx, tx_id); - } - } - - return NULL; -} - -static void OutputSmtpLogDeInitCtx(OutputCtx *output_ctx) -{ - OutputJsonEmailCtx *email_ctx = output_ctx->data; - if (email_ctx != NULL) { - LogFileFreeCtx(email_ctx->file_ctx); - SCFree(email_ctx); - } - SCFree(output_ctx); -} - -static void OutputSmtpLogDeInitCtxSub(OutputCtx *output_ctx) -{ - SCLogDebug("cleaning up sub output_ctx %p", output_ctx); - OutputJsonEmailCtx *email_ctx = output_ctx->data; - if (email_ctx != NULL) { - SCFree(email_ctx); - } - SCFree(output_ctx); -} - -#define DEFAULT_LOG_FILENAME "smtp.json" -OutputCtx *OutputSmtpLogInit(ConfNode *conf) -{ - LogFileCtx *file_ctx = LogFileNewCtx(); - if(file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputJsonEmailCtx *email_ctx = SCMalloc(sizeof(OutputJsonEmailCtx)); - if (unlikely(email_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(email_ctx); - return NULL; - } - - email_ctx->file_ctx = file_ctx; - - output_ctx->data = email_ctx; - output_ctx->DeInit = OutputSmtpLogDeInitCtx; - - /* enable the logger for the app layer */ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_SMTP); - - return output_ctx; -} - -static OutputCtx *OutputSmtpLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputJsonCtx *ojc = parent_ctx->data; - - OutputJsonEmailCtx *email_ctx = SCMalloc(sizeof(OutputJsonEmailCtx)); - if (unlikely(email_ctx == NULL)) - return NULL; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(email_ctx); - return NULL; - } - - email_ctx->file_ctx = ojc->file_ctx; - - OutputEmailInitConf(conf, email_ctx); - - output_ctx->data = email_ctx; - output_ctx->DeInit = OutputSmtpLogDeInitCtxSub; - - /* enable the logger for the app layer */ - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_SMTP); - - return output_ctx; -} - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonSmtpLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonEmailLogThread *aft = SCMalloc(sizeof(JsonEmailLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(JsonEmailLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for SMTPLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->emaillog_ctx = ((OutputCtx *)initdata)->data; - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonSmtpLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonEmailLogThread *aft = (JsonEmailLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(JsonEmailLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -void TmModuleJsonSmtpLogRegister (void) { - tmm_modules[TMM_JSONSMTPLOG].name = "JsonSmtpLog"; - tmm_modules[TMM_JSONSMTPLOG].ThreadInit = JsonSmtpLogThreadInit; - tmm_modules[TMM_JSONSMTPLOG].ThreadDeinit = JsonSmtpLogThreadDeinit; - tmm_modules[TMM_JSONSMTPLOG].RegisterTests = NULL; - tmm_modules[TMM_JSONSMTPLOG].cap_flags = 0; - tmm_modules[TMM_JSONSMTPLOG].flags = TM_FLAG_LOGAPI_TM; - - /* register as separate module */ - OutputRegisterTxModule("JsonSmtpLog", "smtp-json-log", - OutputSmtpLogInit, ALPROTO_SMTP, - JsonSmtpLogger); - - /* also register as child of eve-log */ - OutputRegisterTxSubModule("eve-log", "JsonSmtpLog", - "eve-log.smtp", - OutputSmtpLogInitSub, ALPROTO_SMTP, - JsonSmtpLogger); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonSmtpLogRegister (void) -{ - tmm_modules[TMM_JSONSMTPLOG].name = "JsonSmtpLog"; - tmm_modules[TMM_JSONSMTPLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-smtp.h b/framework/src/suricata/src/output-json-smtp.h deleted file mode 100644 index 2f79d992..00000000 --- a/framework/src/suricata/src/output-json-smtp.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - */ - -#ifndef __OUTPUT_JSON_SMTP_H__ -#define __OUTPUT_JSON_SMTP_H__ - -void TmModuleJsonSmtpLogRegister (void); -#ifdef HAVE_LIBJANSSON -json_t *JsonSMTPAddMetadata(const Flow *f, uint64_t tx_id); -#endif - -#endif /* __OUTPUT_JSON_SMTP_H__ */ diff --git a/framework/src/suricata/src/output-json-ssh.c b/framework/src/suricata/src/output-json-ssh.c deleted file mode 100644 index 3dc4d10f..00000000 --- a/framework/src/suricata/src/output-json-ssh.c +++ /dev/null @@ -1,351 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements SSH JSON logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" -#include "app-layer-parser.h" -#include "output.h" -#include "app-layer-ssh.h" -#include "app-layer.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" -#include "util-crypt.h" - -#include "output-json.h" - -#ifdef HAVE_LIBJANSSON -#include - -#define MODULE_NAME "LogSshLog" - -typedef struct OutputSshCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ -} OutputSshCtx; - - -typedef struct JsonSshLogThread_ { - OutputSshCtx *sshlog_ctx; - MemBuffer *buffer; -} JsonSshLogThread; - - -void JsonSshLogJSON(json_t *tjs, SshState *ssh_state) -{ - json_t *cjs = json_object(); - if (cjs != NULL) { - json_object_set_new(cjs, "proto_version", - json_string((char *)ssh_state->cli_hdr.proto_version)); - - json_object_set_new(cjs, "software_version", - json_string((char *)ssh_state->cli_hdr.software_version)); - } - json_object_set_new(tjs, "client", cjs); - - json_t *sjs = json_object(); - if (sjs != NULL) { - json_object_set_new(sjs, "proto_version", - json_string((char *)ssh_state->srv_hdr.proto_version)); - - json_object_set_new(sjs, "software_version", - json_string((char *)ssh_state->srv_hdr.software_version)); - } - json_object_set_new(tjs, "server", sjs); - -} - -static int JsonSshLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - JsonSshLogThread *aft = (JsonSshLogThread *)thread_data; - MemBuffer *buffer = (MemBuffer *)aft->buffer; - OutputSshCtx *ssh_ctx = aft->sshlog_ctx; - - if (unlikely(p->flow == NULL)) { - return 0; - } - - /* check if we have SSH state or not */ - FLOWLOCK_WRLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_SSH) - goto end; - - SshState *ssh_state = (SshState *)FlowGetAppState(p->flow); - if (unlikely(ssh_state == NULL)) { - goto end; - } - - if (ssh_state->cli_hdr.software_version == NULL || ssh_state->srv_hdr.software_version == NULL) - goto end; - - json_t *js = CreateJSONHeader((Packet *)p, 1, "ssh");//TODO - if (unlikely(js == NULL)) - goto end; - - json_t *tjs = json_object(); - if (tjs == NULL) { - free(js); - goto end; - } - - /* reset */ - MemBufferReset(buffer); - - JsonSshLogJSON(tjs, ssh_state); - - json_object_set_new(js, "ssh", tjs); - - OutputJSONBuffer(js, ssh_ctx->file_ctx, buffer); - json_object_clear(js); - json_decref(js); - - /* we only log the state once */ - ssh_state->cli_hdr.flags |= SSH_FLAG_STATE_LOGGED; -end: - FLOWLOCK_UNLOCK(p->flow); - return 0; -} - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonSshLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonSshLogThread *aft = SCMalloc(sizeof(JsonSshLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(JsonSshLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for HTTPLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->sshlog_ctx = ((OutputCtx *)initdata)->data; - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonSshLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonSshLogThread *aft = (JsonSshLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(JsonSshLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void OutputSshLogDeinit(OutputCtx *output_ctx) -{ - OutputSshLoggerDisable(); - - OutputSshCtx *ssh_ctx = output_ctx->data; - LogFileCtx *logfile_ctx = ssh_ctx->file_ctx; - LogFileFreeCtx(logfile_ctx); - SCFree(ssh_ctx); - SCFree(output_ctx); -} - -#define DEFAULT_LOG_FILENAME "ssh.json" -OutputCtx *OutputSshLogInit(ConfNode *conf) -{ - if (OutputSshLoggerEnable() != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'ssh' logger " - "can be enabled"); - return NULL; - } - - LogFileCtx *file_ctx = LogFileNewCtx(); - if(file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputSshCtx *ssh_ctx = SCMalloc(sizeof(OutputSshCtx)); - if (unlikely(ssh_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(ssh_ctx); - return NULL; - } - - ssh_ctx->file_ctx = file_ctx; - - output_ctx->data = ssh_ctx; - output_ctx->DeInit = OutputSshLogDeinit; - - return output_ctx; -} - -static void OutputSshLogDeinitSub(OutputCtx *output_ctx) -{ - OutputSshLoggerDisable(); - - OutputSshCtx *ssh_ctx = output_ctx->data; - SCFree(ssh_ctx); - SCFree(output_ctx); -} - -OutputCtx *OutputSshLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputJsonCtx *ojc = parent_ctx->data; - - if (OutputSshLoggerEnable() != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'ssh' logger " - "can be enabled"); - return NULL; - } - - OutputSshCtx *ssh_ctx = SCMalloc(sizeof(OutputSshCtx)); - if (unlikely(ssh_ctx == NULL)) - return NULL; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(ssh_ctx); - return NULL; - } - - ssh_ctx->file_ctx = ojc->file_ctx; - - output_ctx->data = ssh_ctx; - output_ctx->DeInit = OutputSshLogDeinitSub; - - return output_ctx; -} - -/** \internal - * \brief Condition function for SSH logger - * \retval bool true or false -- log now? - */ -static int JsonSshCondition(ThreadVars *tv, const Packet *p) -{ - if (p->flow == NULL) { - return FALSE; - } - - if (!(PKT_IS_TCP(p))) { - return FALSE; - } - - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_SSH) - goto dontlog; - - SshState *ssh_state = (SshState *)FlowGetAppState(p->flow); - if (ssh_state == NULL) { - SCLogDebug("no ssh state, so no logging"); - goto dontlog; - } - - /* we only log the state once */ - if (ssh_state->cli_hdr.flags & SSH_FLAG_STATE_LOGGED) - goto dontlog; - - if (ssh_state->cli_hdr.software_version == NULL || - ssh_state->srv_hdr.software_version == NULL) - goto dontlog; - - /* todo: logic to log once */ - - FLOWLOCK_UNLOCK(p->flow); - return TRUE; -dontlog: - FLOWLOCK_UNLOCK(p->flow); - return FALSE; -} - -void TmModuleJsonSshLogRegister (void) -{ - tmm_modules[TMM_JSONSSHLOG].name = "JsonSshLog"; - tmm_modules[TMM_JSONSSHLOG].ThreadInit = JsonSshLogThreadInit; - tmm_modules[TMM_JSONSSHLOG].ThreadDeinit = JsonSshLogThreadDeinit; - tmm_modules[TMM_JSONSSHLOG].RegisterTests = NULL; - tmm_modules[TMM_JSONSSHLOG].cap_flags = 0; - tmm_modules[TMM_JSONSSHLOG].flags = TM_FLAG_LOGAPI_TM; - - /* register as separate module */ - OutputRegisterPacketModule("JsonSshLog", "ssh-json-log", OutputSshLogInit, - JsonSshLogger, JsonSshCondition); - - /* also register as child of eve-log */ - OutputRegisterPacketSubModule("eve-log", "JsonSshLog", "eve-log.ssh", OutputSshLogInitSub, - JsonSshLogger, JsonSshCondition); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonSshLogRegister (void) -{ - tmm_modules[TMM_JSONSSHLOG].name = "JsonSshLog"; - tmm_modules[TMM_JSONSSHLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-ssh.h b/framework/src/suricata/src/output-json-ssh.h deleted file mode 100644 index 5d0752bf..00000000 --- a/framework/src/suricata/src/output-json-ssh.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __OUTPUT_JSON_SSH_H__ -#define __OUTPUT_JSON_SSH_H__ - -void TmModuleJsonSshLogRegister (void); - -#ifdef HAVE_LIBJANSSON -#include "app-layer-ssh.h" - -void JsonSshLogJSON(json_t *js, SshState *tx); -#endif - -#endif /* __OUTPUT_JSON_SSH_H__ */ diff --git a/framework/src/suricata/src/output-json-stats.c b/framework/src/suricata/src/output-json-stats.c deleted file mode 100644 index fea7177a..00000000 --- a/framework/src/suricata/src/output-json-stats.c +++ /dev/null @@ -1,387 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * Implements JSON stats counters logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" -#include "output.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" -#include "util-crypt.h" - -#include "output-json.h" - -#define MODULE_NAME "JsonStatsLog" - -#ifdef HAVE_LIBJANSSON -#include - -#define JSON_STATS_TOTALS (1<<0) -#define JSON_STATS_THREADS (1<<1) -#define JSON_STATS_DELTAS (1<<2) - -typedef struct OutputStatsCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ -} OutputStatsCtx; - -typedef struct JsonStatsLogThread_ { - OutputStatsCtx *statslog_ctx; - MemBuffer *buffer; -} JsonStatsLogThread; - -static json_t *OutputStats2Json(json_t *js, const char *key) -{ - void *iter; - - const char *dot = index(key, '.'); - if (dot == NULL) - return NULL; - - size_t predot_len = (dot - key) + 1; - char s[predot_len]; - strlcpy(s, key, predot_len); - - iter = json_object_iter_at(js, s); - const char *s2 = index(dot+1, '.'); - - json_t *value = json_object_iter_value(iter); - if (value == NULL) { - value = json_object(); - json_object_set_new(js, s, value); - } - if (s2 != NULL) { - return OutputStats2Json(value, &key[dot-key+1]); - } - return value; -} - -static int JsonStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *st) -{ - SCEnter(); - JsonStatsLogThread *aft = (JsonStatsLogThread *)thread_data; - MemBuffer *buffer = (MemBuffer *)aft->buffer; - const char delta_suffix[] = "_delta"; - - struct timeval tval; - gettimeofday(&tval, NULL); - - json_t *js = json_object(); - if (unlikely(js == NULL)) - return 0; - - char timebuf[64]; - CreateIsoTimeString(&tval, timebuf, sizeof(timebuf)); - json_object_set_new(js, "timestamp", json_string(timebuf)); - - json_object_set_new(js, "event_type", json_string("stats")); - json_t *js_stats = json_object(); - if (unlikely(js_stats == NULL)) { - json_decref(js); - return 0; - } - - /* Uptime, in seconds. */ - json_object_set_new(js_stats, "uptime", - json_integer((int)difftime(tval.tv_sec, st->start_time))); - - uint32_t u = 0; - if (aft->statslog_ctx->flags & JSON_STATS_TOTALS) { - for (u = 0; u < st->nstats; u++) { - if (st->stats[u].name == NULL) - continue; - const char *name = st->stats[u].name; - const char *shortname = name; - if (rindex(name, '.') != NULL) { - shortname = &name[rindex(name, '.') - name + 1]; - } - json_t *js_type = OutputStats2Json(js_stats, name); - if (js_type != NULL) { - json_object_set_new(js_type, shortname, - json_integer(st->stats[u].value)); - if (aft->statslog_ctx->flags & JSON_STATS_DELTAS) { - char deltaname[strlen(shortname) + strlen(delta_suffix) + 1]; - snprintf(deltaname, sizeof(deltaname), "%s%s", shortname, - delta_suffix); - json_object_set_new(js_type, deltaname, - json_integer(st->stats[u].value - st->stats[u].pvalue)); - } - } - } - } - - /* per thread stats - stored in a "threads" object. */ - if (st->tstats != NULL && (aft->statslog_ctx->flags & JSON_STATS_THREADS)) { - /* for each thread (store) */ - json_t *threads = json_object(); - if (unlikely(threads == NULL)) { - json_decref(js); - return 0; - } - uint32_t x; - for (x = 0; x < st->ntstats; x++) { - uint32_t offset = x * st->nstats; - - /* for each counter */ - for (u = offset; u < (offset + st->nstats); u++) { - if (st->tstats[u].name == NULL) - continue; - - char str[256]; - snprintf(str, sizeof(str), "%s.%s", st->tstats[u].tm_name, st->tstats[u].name); - char *shortname = &str[rindex(str, '.') - str + 1]; - json_t *js_type = OutputStats2Json(threads, str); - - if (js_type != NULL) { - json_object_set_new(js_type, shortname, json_integer(st->tstats[u].value)); - - if (aft->statslog_ctx->flags & JSON_STATS_DELTAS) { - char deltaname[strlen(shortname) + strlen(delta_suffix) + 1]; - snprintf(deltaname, sizeof(deltaname), "%s%s", - shortname, delta_suffix); - json_object_set_new(js_type, deltaname, - json_integer(st->tstats[u].value - st->tstats[u].pvalue)); - } - } - } - } - json_object_set_new(js_stats, "threads", threads); - } - - json_object_set_new(js, "stats", js_stats); - - OutputJSONBuffer(js, aft->statslog_ctx->file_ctx, buffer); - MemBufferReset(buffer); - - json_object_clear(js_stats); - json_object_del(js, "stats"); - json_object_clear(js); - json_decref(js); - - SCReturnInt(0); -} - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonStatsLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonStatsLogThread *aft = SCMalloc(sizeof(JsonStatsLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(JsonStatsLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for json stats. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->statslog_ctx = ((OutputCtx *)initdata)->data; - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonStatsLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonStatsLogThread *aft = (JsonStatsLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - - /* clear memory */ - memset(aft, 0, sizeof(JsonStatsLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void OutputStatsLogDeinit(OutputCtx *output_ctx) -{ - - OutputStatsCtx *stats_ctx = output_ctx->data; - LogFileCtx *logfile_ctx = stats_ctx->file_ctx; - LogFileFreeCtx(logfile_ctx); - SCFree(stats_ctx); - SCFree(output_ctx); -} - -#define DEFAULT_LOG_FILENAME "stats.json" -OutputCtx *OutputStatsLogInit(ConfNode *conf) -{ - LogFileCtx *file_ctx = LogFileNewCtx(); - if(file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputStatsCtx *stats_ctx = SCMalloc(sizeof(OutputStatsCtx)); - if (unlikely(stats_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - stats_ctx->flags = JSON_STATS_TOTALS; - - if (conf != NULL) { - const char *totals = ConfNodeLookupChildValue(conf, "totals"); - const char *threads = ConfNodeLookupChildValue(conf, "threads"); - const char *deltas = ConfNodeLookupChildValue(conf, "deltas"); - SCLogDebug("totals %s threads %s deltas %s", totals, threads, deltas); - - if (totals != NULL && ConfValIsFalse(totals)) { - stats_ctx->flags &= ~JSON_STATS_TOTALS; - } - if (threads != NULL && ConfValIsTrue(threads)) { - stats_ctx->flags |= JSON_STATS_THREADS; - } - if (deltas != NULL && ConfValIsTrue(deltas)) { - stats_ctx->flags |= JSON_STATS_DELTAS; - } - SCLogDebug("stats_ctx->flags %08x", stats_ctx->flags); - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(stats_ctx); - return NULL; - } - - stats_ctx->file_ctx = file_ctx; - - output_ctx->data = stats_ctx; - output_ctx->DeInit = OutputStatsLogDeinit; - - return output_ctx; -} - -static void OutputStatsLogDeinitSub(OutputCtx *output_ctx) -{ - OutputStatsCtx *stats_ctx = output_ctx->data; - SCFree(stats_ctx); - SCFree(output_ctx); -} - -OutputCtx *OutputStatsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - AlertJsonThread *ajt = parent_ctx->data; - - OutputStatsCtx *stats_ctx = SCMalloc(sizeof(OutputStatsCtx)); - if (unlikely(stats_ctx == NULL)) - return NULL; - - stats_ctx->flags = JSON_STATS_TOTALS; - - if (conf != NULL) { - const char *totals = ConfNodeLookupChildValue(conf, "totals"); - const char *threads = ConfNodeLookupChildValue(conf, "threads"); - const char *deltas = ConfNodeLookupChildValue(conf, "deltas"); - SCLogDebug("totals %s threads %s deltas %s", totals, threads, deltas); - - if (totals != NULL && ConfValIsFalse(totals)) { - stats_ctx->flags &= ~JSON_STATS_TOTALS; - } - if (threads != NULL && ConfValIsTrue(threads)) { - stats_ctx->flags |= JSON_STATS_THREADS; - } - if (deltas != NULL && ConfValIsTrue(deltas)) { - stats_ctx->flags |= JSON_STATS_DELTAS; - } - SCLogDebug("stats_ctx->flags %08x", stats_ctx->flags); - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(stats_ctx); - return NULL; - } - - stats_ctx->file_ctx = ajt->file_ctx; - - output_ctx->data = stats_ctx; - output_ctx->DeInit = OutputStatsLogDeinitSub; - - return output_ctx; -} - -void TmModuleJsonStatsLogRegister (void) { - tmm_modules[TMM_JSONSTATSLOG].name = MODULE_NAME; - tmm_modules[TMM_JSONSTATSLOG].ThreadInit = JsonStatsLogThreadInit; - tmm_modules[TMM_JSONSTATSLOG].ThreadDeinit = JsonStatsLogThreadDeinit; - tmm_modules[TMM_JSONSTATSLOG].RegisterTests = NULL; - tmm_modules[TMM_JSONSTATSLOG].cap_flags = 0; - tmm_modules[TMM_JSONSTATSLOG].flags = TM_FLAG_LOGAPI_TM; - - /* register as separate module */ - OutputRegisterStatsModule(MODULE_NAME, "stats-json", OutputStatsLogInit, - JsonStatsLogger); - - /* also register as child of eve-log */ - OutputRegisterStatsSubModule("eve-log", MODULE_NAME, "eve-log.stats", - OutputStatsLogInitSub, JsonStatsLogger); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonStatsLogRegister (void) -{ - tmm_modules[TMM_JSONSTATSLOG].name = MODULE_NAME; - tmm_modules[TMM_JSONSTATSLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-stats.h b/framework/src/suricata/src/output-json-stats.h deleted file mode 100644 index 9ad1d9b8..00000000 --- a/framework/src/suricata/src/output-json-stats.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - */ - -#ifndef __OUTPUT_JSON_COUNTERS_H__ -#define __OUTPUT_JSON_COUNTERS_H__ - -void TmModuleJsonStatsLogRegister (void); - -#endif /* __OUTPUT_JSON_COUNTERS_H__ */ diff --git a/framework/src/suricata/src/output-json-template.c b/framework/src/suricata/src/output-json-template.c deleted file mode 100644 index d360e674..00000000 --- a/framework/src/suricata/src/output-json-template.c +++ /dev/null @@ -1,217 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-buffer.h" -#include "util-debug.h" -#include "util-byte.h" - -#include "output.h" -#include "output-json.h" - -#include "app-layer.h" -#include "app-layer-parser.h" - -#include "app-layer-template.h" - -#ifdef HAVE_LIBJANSSON -#include - -typedef struct LogTemplateFileCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; -} LogTemplateFileCtx; - -typedef struct LogTemplateLogThread_ { - LogTemplateFileCtx *templatelog_ctx; - uint32_t count; - MemBuffer *buffer; -} LogTemplateLogThread; - -static int JsonTemplateLogger(ThreadVars *tv, void *thread_data, - const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) -{ - TemplateTransaction *templatetx = tx; - LogTemplateLogThread *thread = thread_data; - MemBuffer *buffer = thread->buffer; - json_t *js, *templatejs; - - SCLogNotice("Logging template transaction %"PRIu64".", templatetx->tx_id); - - js = CreateJSONHeader((Packet *)p, 0, "template"); - if (unlikely(js == NULL)) { - return TM_ECODE_FAILED; - } - - templatejs = json_object(); - if (unlikely(templatejs == NULL)) { - goto error; - } - - /* Convert the request buffer to a string then log. */ - char *request_buffer = BytesToString(templatetx->request_buffer, - templatetx->request_buffer_len); - if (request_buffer != NULL) { - json_object_set_new(templatejs, "request", json_string(request_buffer)); - SCFree(request_buffer); - } - - /* Convert the response buffer to a string then log. */ - char *response_buffer = BytesToString(templatetx->response_buffer, - templatetx->response_buffer_len); - if (response_buffer != NULL) { - json_object_set_new(templatejs, "response", - json_string(response_buffer)); - SCFree(response_buffer); - } - - json_object_set_new(js, "template", templatejs); - - MemBufferReset(buffer); - OutputJSONBuffer(js, thread->templatelog_ctx->file_ctx, buffer); - - json_decref(js); - return TM_ECODE_OK; - -error: - if (templatejs != NULL) { - json_decref(templatejs); - } - json_decref(js); - return TM_ECODE_FAILED; -} - -static void OutputTemplateLogDeInitCtxSub(OutputCtx *output_ctx) -{ - LogTemplateFileCtx *templatelog_ctx = (LogTemplateFileCtx *)output_ctx->data; - SCFree(templatelog_ctx); - SCFree(output_ctx); -} - -static OutputCtx *OutputTemplateLogInitSub(ConfNode *conf, - OutputCtx *parent_ctx) -{ - AlertJsonThread *ajt = parent_ctx->data; - - LogTemplateFileCtx *templatelog_ctx = SCCalloc(1, sizeof(*templatelog_ctx)); - if (unlikely(templatelog_ctx == NULL)) { - return NULL; - } - templatelog_ctx->file_ctx = ajt->file_ctx; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(*output_ctx)); - if (unlikely(output_ctx == NULL)) { - SCFree(templatelog_ctx); - return NULL; - } - output_ctx->data = templatelog_ctx; - output_ctx->DeInit = OutputTemplateLogDeInitCtxSub; - - SCLogNotice("Template log sub-module initialized."); - - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_TEMPLATE); - - return output_ctx; -} - -#define OUTPUT_BUFFER_SIZE 65535 - -static TmEcode JsonTemplateLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogTemplateLogThread *thread = SCCalloc(1, sizeof(*thread)); - if (unlikely(thread == NULL)) { - return TM_ECODE_FAILED; - } - - if (initdata == NULL) { - SCLogDebug("Error getting context for Template. \"initdata\" is NULL."); - SCFree(thread); - return TM_ECODE_FAILED; - } - - thread->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (unlikely(thread->buffer == NULL)) { - SCFree(thread); - return TM_ECODE_FAILED; - } - - thread->templatelog_ctx = ((OutputCtx *)initdata)->data; - *data = (void *)thread; - - return TM_ECODE_OK; -} - -static TmEcode JsonTemplateLogThreadDeinit(ThreadVars *t, void *data) -{ - LogTemplateLogThread *thread = (LogTemplateLogThread *)data; - if (thread == NULL) { - return TM_ECODE_OK; - } - if (thread->buffer != NULL) { - MemBufferFree(thread->buffer); - } - SCFree(thread); - return TM_ECODE_OK; -} - -void TmModuleJsonTemplateLogRegister(void) -{ - if (ConfGetNode("app-layer.protocols.template") == NULL) { - return; - } - - tmm_modules[TMM_JSONTEMPLATELOG].name = "JsonTemplateLog"; - tmm_modules[TMM_JSONTEMPLATELOG].ThreadInit = JsonTemplateLogThreadInit; - tmm_modules[TMM_JSONTEMPLATELOG].ThreadDeinit = JsonTemplateLogThreadDeinit; - tmm_modules[TMM_JSONTEMPLATELOG].RegisterTests = NULL; - tmm_modules[TMM_JSONTEMPLATELOG].cap_flags = 0; - tmm_modules[TMM_JSONTEMPLATELOG].flags = TM_FLAG_LOGAPI_TM; - - /* Register as an eve sub-module. */ - OutputRegisterTxSubModule("eve-log", "JsonTemplateLog", "eve-log.template", - OutputTemplateLogInitSub, ALPROTO_TEMPLATE, JsonTemplateLogger); - - SCLogNotice("Template JSON logger registered."); -} - -#else /* No JSON support. */ - -static TmEcode JsonTemplateLogThreadInit(ThreadVars *t, void *initdata, - void **data) -{ - SCLogInfo("Cannot initialize JSON output for template. " - "JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonTemplateLogRegister(void) -{ - tmm_modules[TMM_JSONTEMPLATELOG].name = "JsonTemplateLog"; - tmm_modules[TMM_JSONTEMPLATELOG].ThreadInit = JsonTemplateLogThreadInit; -} - -#endif /* HAVE_LIBJANSSON */ diff --git a/framework/src/suricata/src/output-json-template.h b/framework/src/suricata/src/output-json-template.h deleted file mode 100644 index d071e182..00000000 --- a/framework/src/suricata/src/output-json-template.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __OUTPUT_JSON_TEMPLATE_H__ -#define __OUTPUT_JSON_TEMPLATE_H__ - -void TmModuleJsonTemplateLogRegister(void); - -#endif /* __OUTPUT_JSON_TEMPLATE_H__ */ diff --git a/framework/src/suricata/src/output-json-tls.c b/framework/src/suricata/src/output-json-tls.c deleted file mode 100644 index d8b8078f..00000000 --- a/framework/src/suricata/src/output-json-tls.c +++ /dev/null @@ -1,411 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * Implements TLS JSON logging portion of the engine. - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" -#include "app-layer-parser.h" -#include "output.h" -#include "app-layer-ssl.h" -#include "app-layer.h" -#include "util-privs.h" -#include "util-buffer.h" - -#include "util-logopenfile.h" -#include "util-crypt.h" - -#include "output-json.h" - -#ifdef HAVE_LIBJANSSON -#include - -SC_ATOMIC_DECLARE(unsigned int, cert_id); - -#define MODULE_NAME "LogTlsLog" - -#define LOG_TLS_DEFAULT 0 -#define LOG_TLS_EXTENDED (1 << 0) - -typedef struct OutputTlsCtx_ { - LogFileCtx *file_ctx; - uint32_t flags; /** Store mode */ -} OutputTlsCtx; - - -typedef struct JsonTlsLogThread_ { - OutputTlsCtx *tlslog_ctx; - MemBuffer *buffer; -} JsonTlsLogThread; - -#define SSL_VERSION_LENGTH 13 - -void JsonTlsLogJSONBasic(json_t *js, SSLState *ssl_state) -{ - /* tls.subject */ - json_object_set_new(js, "subject", - json_string(ssl_state->server_connp.cert0_subject)); - - /* tls.issuerdn */ - json_object_set_new(js, "issuerdn", - json_string(ssl_state->server_connp.cert0_issuerdn)); - -} - -void JsonTlsLogJSONExtended(json_t *tjs, SSLState * state) -{ - char ssl_version[SSL_VERSION_LENGTH + 1]; - - /* tls.fingerprint */ - json_object_set_new(tjs, "fingerprint", - json_string(state->server_connp.cert0_fingerprint)); - - /* tls.sni */ - if (state->client_connp.sni) { - json_object_set_new(tjs, "sni", - json_string(state->client_connp.sni)); - } - - /* tls.version */ - switch (state->server_connp.version) { - case TLS_VERSION_UNKNOWN: - snprintf(ssl_version, SSL_VERSION_LENGTH, "UNDETERMINED"); - break; - case SSL_VERSION_2: - snprintf(ssl_version, SSL_VERSION_LENGTH, "SSLv2"); - break; - case SSL_VERSION_3: - snprintf(ssl_version, SSL_VERSION_LENGTH, "SSLv3"); - break; - case TLS_VERSION_10: - snprintf(ssl_version, SSL_VERSION_LENGTH, "TLSv1"); - break; - case TLS_VERSION_11: - snprintf(ssl_version, SSL_VERSION_LENGTH, "TLS 1.1"); - break; - case TLS_VERSION_12: - snprintf(ssl_version, SSL_VERSION_LENGTH, "TLS 1.2"); - break; - default: - snprintf(ssl_version, SSL_VERSION_LENGTH, "0x%04x", - state->server_connp.version); - break; - } - json_object_set_new(tjs, "version", json_string(ssl_version)); -} - -static int JsonTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - JsonTlsLogThread *aft = (JsonTlsLogThread *)thread_data; - MemBuffer *buffer = (MemBuffer *)aft->buffer; - OutputTlsCtx *tls_ctx = aft->tlslog_ctx; - - if (unlikely(p->flow == NULL)) { - return 0; - } - - /* check if we have TLS state or not */ - FLOWLOCK_WRLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_TLS) - goto end; - - SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); - if (unlikely(ssl_state == NULL)) { - goto end; - } - - if (ssl_state->server_connp.cert0_issuerdn == NULL || ssl_state->server_connp.cert0_subject == NULL) - goto end; - - json_t *js = CreateJSONHeader((Packet *)p, 0, "tls");//TODO - if (unlikely(js == NULL)) - goto end; - - json_t *tjs = json_object(); - if (tjs == NULL) { - free(js); - goto end; - } - - /* reset */ - MemBufferReset(buffer); - - JsonTlsLogJSONBasic(tjs, ssl_state); - - if (tls_ctx->flags & LOG_TLS_EXTENDED) { - JsonTlsLogJSONExtended(tjs, ssl_state); - } - - json_object_set_new(js, "tls", tjs); - - OutputJSONBuffer(js, tls_ctx->file_ctx, buffer); - json_object_clear(js); - json_decref(js); - - /* we only log the state once */ - ssl_state->flags |= SSL_AL_FLAG_STATE_LOGGED; -end: - FLOWLOCK_UNLOCK(p->flow); - return 0; -} - -#define OUTPUT_BUFFER_SIZE 65535 -static TmEcode JsonTlsLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - JsonTlsLogThread *aft = SCMalloc(sizeof(JsonTlsLogThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(JsonTlsLogThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for HTTPLog. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - /* Use the Ouptut Context (file pointer and mutex) */ - aft->tlslog_ctx = ((OutputCtx *)initdata)->data; - - aft->buffer = MemBufferCreateNew(OUTPUT_BUFFER_SIZE); - if (aft->buffer == NULL) { - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -static TmEcode JsonTlsLogThreadDeinit(ThreadVars *t, void *data) -{ - JsonTlsLogThread *aft = (JsonTlsLogThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - MemBufferFree(aft->buffer); - /* clear memory */ - memset(aft, 0, sizeof(JsonTlsLogThread)); - - SCFree(aft); - return TM_ECODE_OK; -} - -static void OutputTlsLogDeinit(OutputCtx *output_ctx) -{ - OutputTlsLoggerDisable(); - - OutputTlsCtx *tls_ctx = output_ctx->data; - LogFileCtx *logfile_ctx = tls_ctx->file_ctx; - LogFileFreeCtx(logfile_ctx); - SCFree(tls_ctx); - SCFree(output_ctx); -} - -#define DEFAULT_LOG_FILENAME "tls.json" -OutputCtx *OutputTlsLogInit(ConfNode *conf) -{ - if (OutputTlsLoggerEnable() != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'tls' logger " - "can be enabled"); - return NULL; - } - - LogFileCtx *file_ctx = LogFileNewCtx(); - if(file_ctx == NULL) { - SCLogError(SC_ERR_HTTP_LOG_GENERIC, "couldn't create new file_ctx"); - return NULL; - } - - if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx)); - if (unlikely(tls_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - return NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(file_ctx); - SCFree(tls_ctx); - return NULL; - } - - tls_ctx->file_ctx = file_ctx; - tls_ctx->flags = LOG_TLS_DEFAULT; - - if (conf) { - const char *extended = ConfNodeLookupChildValue(conf, "extended"); - - if (extended != NULL) { - if (ConfValIsTrue(extended)) { - tls_ctx->flags = LOG_TLS_EXTENDED; - } - } - } - output_ctx->data = tls_ctx; - output_ctx->DeInit = OutputTlsLogDeinit; - - return output_ctx; -} - -static void OutputTlsLogDeinitSub(OutputCtx *output_ctx) -{ - OutputTlsLoggerDisable(); - - OutputTlsCtx *tls_ctx = output_ctx->data; - SCFree(tls_ctx); - SCFree(output_ctx); -} - -OutputCtx *OutputTlsLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - OutputJsonCtx *ojc = parent_ctx->data; - - if (OutputTlsLoggerEnable() != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "only one 'tls' logger " - "can be enabled"); - return NULL; - } - - OutputTlsCtx *tls_ctx = SCMalloc(sizeof(OutputTlsCtx)); - if (unlikely(tls_ctx == NULL)) - return NULL; - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(tls_ctx); - return NULL; - } - - tls_ctx->file_ctx = ojc->file_ctx; - tls_ctx->flags = LOG_TLS_DEFAULT; - - if (conf) { - const char *extended = ConfNodeLookupChildValue(conf, "extended"); - - if (extended != NULL) { - if (ConfValIsTrue(extended)) { - tls_ctx->flags = LOG_TLS_EXTENDED; - } - } - } - output_ctx->data = tls_ctx; - output_ctx->DeInit = OutputTlsLogDeinitSub; - - return output_ctx; -} - -/** \internal - * \brief Condition function for TLS logger - * \retval bool true or false -- log now? - */ -static int JsonTlsCondition(ThreadVars *tv, const Packet *p) -{ - if (p->flow == NULL) { - return FALSE; - } - - if (!(PKT_IS_TCP(p))) { - return FALSE; - } - - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_TLS) - goto dontlog; - - SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); - if (ssl_state == NULL) { - SCLogDebug("no tls state, so no request logging"); - goto dontlog; - } - - /* we only log the state once */ - if (ssl_state->flags & SSL_AL_FLAG_STATE_LOGGED) - goto dontlog; - - if (ssl_state->server_connp.cert0_issuerdn == NULL || - ssl_state->server_connp.cert0_subject == NULL) - goto dontlog; - - /* todo: logic to log once */ - - FLOWLOCK_UNLOCK(p->flow); - return TRUE; -dontlog: - FLOWLOCK_UNLOCK(p->flow); - return FALSE; -} - -void TmModuleJsonTlsLogRegister (void) -{ - tmm_modules[TMM_JSONTLSLOG].name = "JsonTlsLog"; - tmm_modules[TMM_JSONTLSLOG].ThreadInit = JsonTlsLogThreadInit; - tmm_modules[TMM_JSONTLSLOG].ThreadDeinit = JsonTlsLogThreadDeinit; - tmm_modules[TMM_JSONTLSLOG].RegisterTests = NULL; - tmm_modules[TMM_JSONTLSLOG].cap_flags = 0; - tmm_modules[TMM_JSONTLSLOG].flags = TM_FLAG_LOGAPI_TM; - - /* register as separate module */ - OutputRegisterPacketModule("JsonTlsLog", "tls-json-log", OutputTlsLogInit, - JsonTlsLogger, JsonTlsCondition); - - /* also register as child of eve-log */ - OutputRegisterPacketSubModule("eve-log", "JsonTlsLog", "eve-log.tls", OutputTlsLogInitSub, - JsonTlsLogger, JsonTlsCondition); -} - -#else - -static TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogInfo("Can't init JSON output - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -void TmModuleJsonTlsLogRegister (void) -{ - tmm_modules[TMM_JSONTLSLOG].name = "JsonTlsLog"; - tmm_modules[TMM_JSONTLSLOG].ThreadInit = OutputJsonThreadInit; -} - -#endif diff --git a/framework/src/suricata/src/output-json-tls.h b/framework/src/suricata/src/output-json-tls.h deleted file mode 100644 index f330ad89..00000000 --- a/framework/src/suricata/src/output-json-tls.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - */ - -#ifndef __OUTPUT_JSON_TLS_H__ -#define __OUTPUT_JSON_TLS_H__ - -void TmModuleJsonTlsLogRegister (void); - -#ifdef HAVE_LIBJANSSON -#include "app-layer-ssl.h" - -void JsonTlsLogJSONBasic(json_t *js, SSLState *ssl_state); -void JsonTlsLogJSONExtended(json_t *js, SSLState *ssl_state); -#endif /* HAVE_LIBJANSSON */ - -#endif /* __OUTPUT_JSON_TLS_H__ */ diff --git a/framework/src/suricata/src/output-json.c b/framework/src/suricata/src/output-json.c deleted file mode 100644 index b9c2b886..00000000 --- a/framework/src/suricata/src/output-json.c +++ /dev/null @@ -1,633 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * - * Logs alerts in JSON format. - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "conf.h" - -#include "threads.h" -#include "tm-threads.h" -#include "threadvars.h" -#include "util-debug.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-reference.h" -#include "app-layer-parser.h" -#include "util-classification-config.h" -#include "util-syslog.h" - -#include "output.h" -#include "output-json.h" - -#include "util-byte.h" -#include "util-privs.h" -#include "util-print.h" -#include "util-proto-name.h" -#include "util-optimize.h" -#include "util-buffer.h" -#include "util-logopenfile.h" -#include "util-device.h" - - -#ifndef HAVE_LIBJANSSON - -/** Handle the case where no JSON support is compiled in. - * - */ - -TmEcode OutputJson (ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode OutputJsonThreadInit(ThreadVars *, void *, void **); -TmEcode OutputJsonThreadDeinit(ThreadVars *, void *); -int OutputJsonOpenFileCtx(LogFileCtx *, char *); -void OutputJsonRegisterTests(void); - -void TmModuleOutputJsonRegister (void) -{ - tmm_modules[TMM_OUTPUTJSON].name = "OutputJSON"; - tmm_modules[TMM_OUTPUTJSON].ThreadInit = OutputJsonThreadInit; - tmm_modules[TMM_OUTPUTJSON].Func = OutputJson; - tmm_modules[TMM_OUTPUTJSON].ThreadDeinit = OutputJsonThreadDeinit; - tmm_modules[TMM_OUTPUTJSON].RegisterTests = OutputJsonRegisterTests; -} - -OutputCtx *OutputJsonInitCtx(ConfNode *conf) -{ - SCLogDebug("Can't init JSON output - JSON support was disabled during build."); - return NULL; -} - -TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - SCLogDebug("Can't init JSON output thread - JSON support was disabled during build."); - return TM_ECODE_FAILED; -} - -TmEcode OutputJson (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - return TM_ECODE_OK; -} - -TmEcode OutputJsonThreadDeinit(ThreadVars *t, void *data) -{ - return TM_ECODE_FAILED; -} - -void OutputJsonRegisterTests (void) -{ -} - -#else /* implied we do have JSON support */ - -#include - -#define DEFAULT_LOG_FILENAME "eve.json" -#define DEFAULT_ALERT_SYSLOG_FACILITY_STR "local0" -#define DEFAULT_ALERT_SYSLOG_FACILITY LOG_LOCAL0 -#define DEFAULT_ALERT_SYSLOG_LEVEL LOG_INFO -#define MODULE_NAME "OutputJSON" - -#define OUTPUT_BUFFER_SIZE 65535 - -TmEcode OutputJson (ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode OutputJsonThreadInit(ThreadVars *, void *, void **); -TmEcode OutputJsonThreadDeinit(ThreadVars *, void *); -void OutputJsonExitPrintStats(ThreadVars *, void *); -void OutputJsonRegisterTests(void); -static void OutputJsonDeInitCtx(OutputCtx *); - -void TmModuleOutputJsonRegister (void) -{ - tmm_modules[TMM_OUTPUTJSON].name = MODULE_NAME; - tmm_modules[TMM_OUTPUTJSON].ThreadInit = OutputJsonThreadInit; - tmm_modules[TMM_OUTPUTJSON].Func = OutputJson; - tmm_modules[TMM_OUTPUTJSON].ThreadExitPrintStats = OutputJsonExitPrintStats; - tmm_modules[TMM_OUTPUTJSON].ThreadDeinit = OutputJsonThreadDeinit; - tmm_modules[TMM_OUTPUTJSON].RegisterTests = OutputJsonRegisterTests; - tmm_modules[TMM_OUTPUTJSON].cap_flags = 0; - - OutputRegisterModule(MODULE_NAME, "eve-log", OutputJsonInitCtx); -} - -/* Default Sensor ID value */ -static int64_t sensor_id = -1; /* -1 = not defined */ - -/** \brief jsonify tcp flags field - * Only add 'true' fields in an attempt to keep things reasonably compact. - */ -void JsonTcpFlags(uint8_t flags, json_t *js) -{ - if (flags & TH_SYN) - json_object_set_new(js, "syn", json_true()); - if (flags & TH_FIN) - json_object_set_new(js, "fin", json_true()); - if (flags & TH_RST) - json_object_set_new(js, "rst", json_true()); - if (flags & TH_PUSH) - json_object_set_new(js, "psh", json_true()); - if (flags & TH_ACK) - json_object_set_new(js, "ack", json_true()); - if (flags & TH_URG) - json_object_set_new(js, "urg", json_true()); - if (flags & TH_ECN) - json_object_set_new(js, "ecn", json_true()); - if (flags & TH_CWR) - json_object_set_new(js, "cwr", json_true()); -} - -void CreateJSONFlowId(json_t *js, const Flow *f) -{ - if (f == NULL) - return; -#if __WORDSIZE == 64 - uint64_t addr = (uint64_t)f; -#else - uint32_t addr = (uint32_t)f; -#endif - json_object_set_new(js, "flow_id", json_integer(addr)); -} - -json_t *CreateJSONHeader(Packet *p, int direction_sensitive, char *event_type) -{ - char timebuf[64]; - char srcip[46], dstip[46]; - Port sp, dp; - - json_t *js = json_object(); - if (unlikely(js == NULL)) - return NULL; - - CreateIsoTimeString(&p->ts, timebuf, sizeof(timebuf)); - - srcip[0] = '\0'; - dstip[0] = '\0'; - if (direction_sensitive) { - if ((PKT_IS_TOSERVER(p))) { - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - } - sp = p->sp; - dp = p->dp; - } else { - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip)); - } - sp = p->dp; - dp = p->sp; - } - } else { - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - } - sp = p->sp; - dp = p->dp; - } - - char proto[16]; - if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) { - strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto)); - } else { - snprintf(proto, sizeof(proto), "%03" PRIu32, IP_GET_IPPROTO(p)); - } - - /* time & tx */ - json_object_set_new(js, "timestamp", json_string(timebuf)); - - CreateJSONFlowId(js, (const Flow *)p->flow); - - /* sensor id */ - if (sensor_id >= 0) - json_object_set_new(js, "sensor_id", json_integer(sensor_id)); - - /* input interface */ - if (p->livedev) { - json_object_set_new(js, "in_iface", json_string(p->livedev->dev)); - } - - /* pcap_cnt */ - if (p->pcap_cnt != 0) { - json_object_set_new(js, "pcap_cnt", json_integer(p->pcap_cnt)); - } - - if (event_type) { - json_object_set_new(js, "event_type", json_string(event_type)); - } - - /* vlan */ - if (p->vlan_idx > 0) { - json_t *js_vlan; - switch (p->vlan_idx) { - case 1: - json_object_set_new(js, "vlan", - json_integer(VLAN_GET_ID1(p))); - break; - case 2: - js_vlan = json_array(); - if (unlikely(js != NULL)) { - json_array_append_new(js_vlan, - json_integer(VLAN_GET_ID1(p))); - json_array_append_new(js_vlan, - json_integer(VLAN_GET_ID2(p))); - json_object_set_new(js, "vlan", js_vlan); - } - break; - default: - /* shouldn't get here */ - break; - } - } - - /* tuple */ - json_object_set_new(js, "src_ip", json_string(srcip)); - switch(p->proto) { - case IPPROTO_ICMP: - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - json_object_set_new(js, "src_port", json_integer(sp)); - break; - } - json_object_set_new(js, "dest_ip", json_string(dstip)); - switch(p->proto) { - case IPPROTO_ICMP: - break; - case IPPROTO_UDP: - case IPPROTO_TCP: - case IPPROTO_SCTP: - json_object_set_new(js, "dest_port", json_integer(dp)); - break; - } - json_object_set_new(js, "proto", json_string(proto)); - switch (p->proto) { - case IPPROTO_ICMP: - if (p->icmpv4h) { - json_object_set_new(js, "icmp_type", - json_integer(p->icmpv4h->type)); - json_object_set_new(js, "icmp_code", - json_integer(p->icmpv4h->code)); - } - break; - case IPPROTO_ICMPV6: - if (p->icmpv6h) { - json_object_set_new(js, "icmp_type", - json_integer(p->icmpv6h->type)); - json_object_set_new(js, "icmp_code", - json_integer(p->icmpv6h->code)); - } - break; - } - - return js; -} - -json_t *CreateJSONHeaderWithTxId(Packet *p, int direction_sensitive, char *event_type, uint32_t tx_id) -{ - json_t *js = CreateJSONHeader(p, direction_sensitive, event_type); - if (unlikely(js == NULL)) - return NULL; - - /* tx id for correlation with other events */ - json_object_set_new(js, "tx_id", json_integer(tx_id)); - - return js; -} - -static int MemBufferCallback(const char *str, size_t size, void *data) -{ - MemBuffer *memb = data; -#if 0 // can't expand, need a MemBuffer ** - /* since we can have many threads, the buffer might not be big enough. - * * Expand if necessary. */ - if (MEMBUFFER_OFFSET(memb) + size > MEMBUFFER_SIZE(memb)) { - MemBufferExpand(&memb, OUTPUT_BUFFER_SIZE); - } -#endif - MemBufferWriteRaw(memb, str, size); - return 0; -} - -int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer *buffer) -{ - if (file_ctx->sensor_name) { - json_object_set_new(js, "host", - json_string(file_ctx->sensor_name)); - } - - if (file_ctx->prefix) - MemBufferWriteRaw(buffer, file_ctx->prefix, file_ctx->prefix_len); - - int r = json_dump_callback(js, MemBufferCallback, buffer, - JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII| -#ifdef JSON_ESCAPE_SLASH - JSON_ESCAPE_SLASH -#else - 0 -#endif - ); - if (r != 0) - return TM_ECODE_OK; - - LogFileWrite(file_ctx, buffer); - return 0; -} - -TmEcode OutputJson (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - return TM_ECODE_OK; -} - -TmEcode OutputJsonThreadInit(ThreadVars *t, void *initdata, void **data) -{ - AlertJsonThread *aft = SCMalloc(sizeof(AlertJsonThread)); - if (unlikely(aft == NULL)) - return TM_ECODE_FAILED; - memset(aft, 0, sizeof(AlertJsonThread)); - - if(initdata == NULL) - { - SCLogDebug("Error getting context for AlertJson. \"initdata\" argument NULL"); - SCFree(aft); - return TM_ECODE_FAILED; - } - - *data = (void *)aft; - return TM_ECODE_OK; -} - -TmEcode OutputJsonThreadDeinit(ThreadVars *t, void *data) -{ - AlertJsonThread *aft = (AlertJsonThread *)data; - if (aft == NULL) { - return TM_ECODE_OK; - } - - SCFree(aft); - return TM_ECODE_OK; -} - -void OutputJsonExitPrintStats(ThreadVars *tv, void *data) -{ - AlertJsonThread *aft = (AlertJsonThread *)data; - if (aft == NULL) { - return; - } - - SCLogInfo("JSON output wrote %" PRIu64 " alerts", aft->file_ctx->alerts); - -} - -/** - * \brief Create a new LogFileCtx for "fast" output style. - * \param conf The configuration node for this output. - * \return A LogFileCtx pointer on success, NULL on failure. - */ -OutputCtx *OutputJsonInitCtx(ConfNode *conf) -{ - OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));; - - const char *sensor_name = ConfNodeLookupChildValue(conf, "sensor-name"); - - if (unlikely(json_ctx == NULL)) { - SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); - return NULL; - } - - json_ctx->file_ctx = LogFileNewCtx(); - if (unlikely(json_ctx->file_ctx == NULL)) { - SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); - SCFree(json_ctx); - return NULL; - } - - if (sensor_name) { - json_ctx->file_ctx->sensor_name = SCStrdup(sensor_name); - if (json_ctx->file_ctx->sensor_name == NULL) { - LogFileFreeCtx(json_ctx->file_ctx); - SCFree(json_ctx); - return NULL; - } - } else { - json_ctx->file_ctx->sensor_name = NULL; - } - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - LogFileFreeCtx(json_ctx->file_ctx); - SCFree(json_ctx); - return NULL; - } - - output_ctx->data = json_ctx; - output_ctx->DeInit = OutputJsonDeInitCtx; - - if (conf) { - const char *output_s = ConfNodeLookupChildValue(conf, "filetype"); - - // Backwards compatibility - if (output_s == NULL) { - output_s = ConfNodeLookupChildValue(conf, "type"); - } - - if (output_s != NULL) { - if (strcmp(output_s, "file") == 0 || - strcmp(output_s, "regular") == 0) { - json_ctx->json_out = LOGFILE_TYPE_FILE; - } else if (strcmp(output_s, "syslog") == 0) { - json_ctx->json_out = LOGFILE_TYPE_SYSLOG; - } else if (strcmp(output_s, "unix_dgram") == 0) { - json_ctx->json_out = LOGFILE_TYPE_UNIX_DGRAM; - } else if (strcmp(output_s, "unix_stream") == 0) { - json_ctx->json_out = LOGFILE_TYPE_UNIX_STREAM; - } else if (strcmp(output_s, "redis") == 0) { -#ifdef HAVE_LIBHIREDIS - json_ctx->json_out = LOGFILE_TYPE_REDIS; -#else - SCLogError(SC_ERR_INVALID_ARGUMENT, - "redis JSON output option is not compiled"); - exit(EXIT_FAILURE); -#endif - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Invalid JSON output option: %s", output_s); - exit(EXIT_FAILURE); - } - } - - const char *prefix = ConfNodeLookupChildValue(conf, "prefix"); - if (prefix != NULL) - { - SCLogInfo("Using prefix '%s' for JSON messages", prefix); - json_ctx->file_ctx->prefix = SCStrdup(prefix); - if (json_ctx->file_ctx->prefix == NULL) - { - SCLogError(SC_ERR_MEM_ALLOC, - "Failed to allocate memory for eve-log.prefix setting."); - exit(EXIT_FAILURE); - } - json_ctx->file_ctx->prefix_len = strlen(prefix); - } - - if (json_ctx->json_out == LOGFILE_TYPE_FILE || - json_ctx->json_out == LOGFILE_TYPE_UNIX_DGRAM || - json_ctx->json_out == LOGFILE_TYPE_UNIX_STREAM) - { - if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { - LogFileFreeCtx(json_ctx->file_ctx); - SCFree(json_ctx); - SCFree(output_ctx); - return NULL; - } - OutputRegisterFileRotationFlag(&json_ctx->file_ctx->rotation_flag); - - const char *format_s = ConfNodeLookupChildValue(conf, "format"); - if (format_s != NULL) { - if (strcmp(format_s, "indent") == 0) { - json_ctx->format = INDENT; - } else if (strcmp(format_s, "compact") == 0) { - json_ctx->format = COMPACT; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Invalid JSON format option: %s", format_s); - exit(EXIT_FAILURE); - } - } - } else if (json_ctx->json_out == LOGFILE_TYPE_SYSLOG) { - const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); - if (facility_s == NULL) { - facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; - } - - int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); - if (facility == -1) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," - " now using \"%s\" as syslog facility", facility_s, - DEFAULT_ALERT_SYSLOG_FACILITY_STR); - facility = DEFAULT_ALERT_SYSLOG_FACILITY; - } - - const char *level_s = ConfNodeLookupChildValue(conf, "level"); - if (level_s != NULL) { - int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); - if (level != -1) { - json_ctx->file_ctx->syslog_setup.alert_syslog_level = level; - } - } - - const char *ident = ConfNodeLookupChildValue(conf, "identity"); - /* if null we just pass that to openlog, which will then - * figure it out by itself. */ - - openlog(ident, LOG_PID|LOG_NDELAY, facility); - - } -#ifdef HAVE_LIBHIREDIS - else if (json_ctx->json_out == LOGFILE_TYPE_REDIS) { - ConfNode *redis_node = ConfNodeLookupChild(conf, "redis"); - if (!json_ctx->file_ctx->sensor_name) { - char hostname[1024]; - gethostname(hostname, 1023); - json_ctx->file_ctx->sensor_name = SCStrdup(hostname); - } - if (json_ctx->file_ctx->sensor_name == NULL) { - LogFileFreeCtx(json_ctx->file_ctx); - SCFree(json_ctx); - SCFree(output_ctx); - return NULL; - } - - if (SCConfLogOpenRedis(redis_node, json_ctx->file_ctx) < 0) { - LogFileFreeCtx(json_ctx->file_ctx); - SCFree(json_ctx); - SCFree(output_ctx); - return NULL; - } - } -#endif - - const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id"); - if (sensor_id_s != NULL) { - if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Failed to initialize JSON output, " - "invalid sensor-is: %s", sensor_id_s); - exit(EXIT_FAILURE); - } - } - - json_ctx->file_ctx->type = json_ctx->json_out; - } - - SCLogDebug("returning output_ctx %p", output_ctx); - return output_ctx; -} - -static void OutputJsonDeInitCtx(OutputCtx *output_ctx) -{ - OutputJsonCtx *json_ctx = (OutputJsonCtx *)output_ctx->data; - LogFileCtx *logfile_ctx = json_ctx->file_ctx; - LogFileFreeCtx(logfile_ctx); - SCFree(json_ctx); - SCFree(output_ctx); -} - -/*------------------------------Unittests-------------------------------------*/ - -#ifdef UNITTESTS - -#endif /* UNITTESTS */ - -/** - * \brief This function registers unit tests for AlertFastLog API. - */ -void OutputJsonRegisterTests(void) -{ - -#ifdef UNITTESTS - -#endif /* UNITTESTS */ - -} -#endif diff --git a/framework/src/suricata/src/output-json.h b/framework/src/suricata/src/output-json.h deleted file mode 100644 index 89e11d86..00000000 --- a/framework/src/suricata/src/output-json.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - */ - -#ifndef __OUTPUT_JSON_H__ -#define __OUTPUT_JSON_H__ - -void TmModuleOutputJsonRegister (void); - -#ifdef HAVE_LIBJANSSON - -#include "suricata-common.h" -#include "util-buffer.h" -#include "util-logopenfile.h" - -void CreateJSONFlowId(json_t *js, const Flow *f); -void JsonTcpFlags(uint8_t flags, json_t *js); -json_t *CreateJSONHeader(Packet *p, int direction_sensative, char *event_type); -json_t *CreateJSONHeaderWithTxId(Packet *p, int direction_sensitive, char *event_type, uint32_t tx_id); -TmEcode OutputJSON(json_t *js, void *data, uint64_t *count); -int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer *buffer); -OutputCtx *OutputJsonInitCtx(ConfNode *); - -enum JsonFormat { COMPACT, INDENT }; - -/* - * Global configuration context data - */ -typedef struct OutputJsonCtx_ { - LogFileCtx *file_ctx; - enum LogFileType json_out; - enum JsonFormat format; -} OutputJsonCtx; - -typedef struct AlertJsonThread_ { - /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - LogFileCtx *file_ctx; -} AlertJsonThread; - -#endif /* HAVE_LIBJANSSON */ - -#endif /* __OUTPUT_JSON_H__ */ diff --git a/framework/src/suricata/src/output-lua.c b/framework/src/suricata/src/output-lua.c deleted file mode 100644 index a8fcb246..00000000 --- a/framework/src/suricata/src/output-lua.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer-htp.h" -#include "app-layer.h" -#include "app-layer-ssl.h" -#include "app-layer-ssh.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#ifdef HAVE_LUA - -#include -#include -#include - -#include "util-lua.h" -#include "util-lua-common.h" -#include "util-lua-http.h" -#include "util-lua-dns.h" -#include "util-lua-tls.h" -#include "util-lua-ssh.h" - -#define MODULE_NAME "LuaLog" - -/** \brief structure containing global config - * The OutputLuaLogInitSub which is run per script - * can access this to get global config info through - * it's parent_ctx->data ptr. - */ -typedef struct LogLuaMasterCtx_ { - char path[PATH_MAX]; /**< contains script-dir */ -} LogLuaMasterCtx; - -typedef struct LogLuaCtx_ { - SCMutex m; - lua_State *luastate; - int deinit_once; -} LogLuaCtx; - -typedef struct LogLuaThreadCtx_ { - LogLuaCtx *lua_ctx; -} LogLuaThreadCtx; - -/** \internal - * \brief TX logger for lua scripts - * - * A single call to this function will run one script on a single - * transaction. - * - * NOTE: The flow (f) also referenced by p->flow is locked. - */ -static int LuaTxLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id) -{ - SCEnter(); - - LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data; - - SCMutexLock(&td->lua_ctx->m); - - LuaStateSetThreadVars(td->lua_ctx->luastate, tv); - LuaStateSetPacket(td->lua_ctx->luastate, (Packet *)p); - LuaStateSetTX(td->lua_ctx->luastate, txptr); - LuaStateSetFlow(td->lua_ctx->luastate, f, /* locked */LUA_FLOW_LOCKED_BY_PARENT); - - /* prepare data to pass to script */ - lua_getglobal(td->lua_ctx->luastate, "log"); - lua_newtable(td->lua_ctx->luastate); - LuaPushTableKeyValueInt(td->lua_ctx->luastate, "tx_id", (int)(tx_id)); - - int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1)); - } - - SCMutexUnlock(&td->lua_ctx->m); - SCReturnInt(0); -} - -/** \internal - * \brief Streaming logger for lua scripts - * - * Hooks into the Streaming Logger API. Gets called for each chunk of new - * streaming data. - */ -static int LuaStreamingLogger(ThreadVars *tv, void *thread_data, const Flow *f, - const uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags) -{ - SCEnter(); - - void *txptr = NULL; - LuaStreamingBuffer b = { data, data_len, flags }; - - SCLogDebug("flags %02x", flags); - - if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION) { - if (f && f->alstate) - txptr = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, tx_id); - } - - LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data; - - SCMutexLock(&td->lua_ctx->m); - - LuaStateSetThreadVars(td->lua_ctx->luastate, tv); - if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION) - LuaStateSetTX(td->lua_ctx->luastate, txptr); - LuaStateSetFlow(td->lua_ctx->luastate, (Flow *)f, /* locked */LUA_FLOW_LOCKED_BY_PARENT); - LuaStateSetStreamingBuffer(td->lua_ctx->luastate, &b); - - /* prepare data to pass to script */ - lua_getglobal(td->lua_ctx->luastate, "log"); - lua_newtable(td->lua_ctx->luastate); - - if (flags & OUTPUT_STREAMING_FLAG_TRANSACTION) - LuaPushTableKeyValueInt(td->lua_ctx->luastate, "tx_id", (int)(tx_id)); - - int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1)); - } - - SCMutexUnlock(&td->lua_ctx->m); - - SCReturnInt(TM_ECODE_OK); -} - -/** \internal - * \brief Packet Logger for lua scripts, for alerts - * - * A single call to this function will run one script for a single - * packet. If it is called, it means that the registered condition - * function has returned TRUE. - * - * The script is called once for each alert stored in the packet. - * - * NOTE: p->flow is UNlocked - */ -static int LuaPacketLoggerAlerts(ThreadVars *tv, void *thread_data, const Packet *p) -{ - LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data; - - char timebuf[64]; - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - if (!(PKT_IS_IPV4(p)) && !(PKT_IS_IPV6(p))) { - /* decoder event */ - goto not_supported; - } - - char proto[16] = ""; - if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) { - strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto)); - } else { - snprintf(proto, sizeof(proto), "PROTO:%03" PRIu32, IP_GET_IPPROTO(p)); - } - - /* loop through alerts stored in the packet */ - SCMutexLock(&td->lua_ctx->m); - uint16_t cnt; - for (cnt = 0; cnt < p->alerts.cnt; cnt++) { - const PacketAlert *pa = &p->alerts.alerts[cnt]; - if (unlikely(pa->s == NULL)) { - continue; - } - - lua_getglobal(td->lua_ctx->luastate, "log"); - - LuaStateSetThreadVars(td->lua_ctx->luastate, tv); - LuaStateSetPacket(td->lua_ctx->luastate, (Packet *)p); - LuaStateSetFlow(td->lua_ctx->luastate, p->flow, /* unlocked */LUA_FLOW_NOT_LOCKED_BY_PARENT); - LuaStateSetPacketAlert(td->lua_ctx->luastate, (PacketAlert *)pa); - - /* prepare data to pass to script */ - //lua_newtable(td->lua_ctx->luastate); - - int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1)); - } - } - SCMutexUnlock(&td->lua_ctx->m); -not_supported: - SCReturnInt(0); -} - -static int LuaPacketConditionAlerts(ThreadVars *tv, const Packet *p) -{ - if (p->alerts.cnt > 0) - return TRUE; - return FALSE; -} - -/** \internal - * \brief Packet Logger for lua scripts, for tls - * - * A single call to this function will run one script for a single - * packet. If it is called, it means that the registered condition - * function has returned TRUE. - * - * The script is called once for each packet. - */ -static int LuaPacketLoggerTls(ThreadVars *tv, void *thread_data, const Packet *p) -{ - LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data; - - char timebuf[64]; - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - SCMutexLock(&td->lua_ctx->m); - - lua_getglobal(td->lua_ctx->luastate, "log"); - - LuaStateSetThreadVars(td->lua_ctx->luastate, tv); - LuaStateSetPacket(td->lua_ctx->luastate, (Packet *)p); - LuaStateSetFlow(td->lua_ctx->luastate, p->flow, /* unlocked */LUA_FLOW_NOT_LOCKED_BY_PARENT); - - int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1)); - } - - SCMutexUnlock(&td->lua_ctx->m); - FLOWLOCK_WRLOCK(p->flow); - - SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); - if (ssl_state != NULL) - ssl_state->flags |= SSL_AL_FLAG_STATE_LOGGED_LUA; - - FLOWLOCK_UNLOCK(p->flow); - SCReturnInt(0); -} - -static int LuaPacketConditionTls(ThreadVars *tv, const Packet *p) -{ - if (p->flow == NULL) { - return FALSE; - } - - if (!(PKT_IS_IPV4(p)) && !(PKT_IS_IPV6(p))) { - return FALSE; - } - - if (!(PKT_IS_TCP(p))) { - return FALSE; - } - - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_TLS) - goto dontlog; - - SSLState *ssl_state = (SSLState *)FlowGetAppState(p->flow); - if (ssl_state == NULL) { - SCLogDebug("no tls state, so no request logging"); - goto dontlog; - } - - if (ssl_state->server_connp.cert0_issuerdn == NULL || - ssl_state->server_connp.cert0_subject == NULL) - goto dontlog; - - /* We only log the state once */ - if (ssl_state->flags & SSL_AL_FLAG_STATE_LOGGED_LUA) - goto dontlog; - - FLOWLOCK_UNLOCK(p->flow); - return TRUE; -dontlog: - FLOWLOCK_UNLOCK(p->flow); - return FALSE; -} - -/** \internal - * \brief Packet Logger for lua scripts, for ssh - * - * A single call to this function will run one script for a single - * packet. If it is called, it means that the registered condition - * function has returned TRUE. - * - * The script is called once for each packet. - */ -static int LuaPacketLoggerSsh(ThreadVars *tv, void *thread_data, const Packet *p) -{ - LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data; - - char timebuf[64]; - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - SCMutexLock(&td->lua_ctx->m); - - lua_getglobal(td->lua_ctx->luastate, "log"); - - LuaStateSetThreadVars(td->lua_ctx->luastate, tv); - LuaStateSetPacket(td->lua_ctx->luastate, (Packet *)p); - LuaStateSetFlow(td->lua_ctx->luastate, p->flow, /* unlocked */LUA_FLOW_NOT_LOCKED_BY_PARENT); - - int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1)); - } - - SCMutexUnlock(&td->lua_ctx->m); - FLOWLOCK_WRLOCK(p->flow); - - SshState *ssh_state = (SshState *)FlowGetAppState(p->flow); - if (ssh_state != NULL) - ssh_state->cli_hdr.flags |= SSH_FLAG_STATE_LOGGED_LUA; - - FLOWLOCK_UNLOCK(p->flow); - SCReturnInt(0); -} - -static int LuaPacketConditionSsh(ThreadVars *tv, const Packet *p) -{ - if (p->flow == NULL) { - return FALSE; - } - - if (!(PKT_IS_IPV4(p)) && !(PKT_IS_IPV6(p))) { - return FALSE; - } - - if (!(PKT_IS_TCP(p))) { - return FALSE; - } - - FLOWLOCK_RDLOCK(p->flow); - uint16_t proto = FlowGetAppProtocol(p->flow); - if (proto != ALPROTO_SSH) - goto dontlog; - - SshState *ssh_state = (SshState *)FlowGetAppState(p->flow); - if (ssh_state == NULL) { - SCLogDebug("no ssh state, so no request logging"); - goto dontlog; - } - - if (ssh_state->cli_hdr.software_version == NULL || - ssh_state->srv_hdr.software_version == NULL) - goto dontlog; - - /* We only log the state once */ - if (ssh_state->cli_hdr.flags & SSH_FLAG_STATE_LOGGED_LUA) - goto dontlog; - - FLOWLOCK_UNLOCK(p->flow); - return TRUE; -dontlog: - FLOWLOCK_UNLOCK(p->flow); - return FALSE; -} - -/** \internal - * \brief Packet Logger for lua scripts, for packets - * - * A single call to this function will run one script for a single - * packet. If it is called, it means that the registered condition - * function has returned TRUE. - * - * The script is called once for each packet. - * - * NOTE: p->flow is UNlocked - */ -static int LuaPacketLogger(ThreadVars *tv, void *thread_data, const Packet *p) -{ - LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data; - - char timebuf[64]; - - if ((!(PKT_IS_IPV4(p))) && (!(PKT_IS_IPV6(p)))) { - goto not_supported; - } - - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - - char proto[16] = ""; - if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) { - strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto)); - } else { - snprintf(proto, sizeof(proto), "PROTO:%03" PRIu32, IP_GET_IPPROTO(p)); - } - - /* loop through alerts stored in the packet */ - SCMutexLock(&td->lua_ctx->m); - lua_getglobal(td->lua_ctx->luastate, "log"); - - LuaStateSetThreadVars(td->lua_ctx->luastate, tv); - LuaStateSetPacket(td->lua_ctx->luastate, (Packet *)p); - LuaStateSetFlow(td->lua_ctx->luastate, p->flow, /* unlocked */LUA_FLOW_NOT_LOCKED_BY_PARENT); - - /* prepare data to pass to script */ - lua_newtable(td->lua_ctx->luastate); - - int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1)); - } - SCMutexUnlock(&td->lua_ctx->m); -not_supported: - SCReturnInt(0); -} - -static int LuaPacketCondition(ThreadVars *tv, const Packet *p) -{ - return TRUE; -} - -/** \internal - * \brief File API Logger function for Lua scripts - * - * Executes a script once for one file. - * - * TODO non-http support - * - * NOTE p->flow is locked at this point - */ -static int LuaFileLogger(ThreadVars *tv, void *thread_data, const Packet *p, const File *ff) -{ - SCEnter(); - LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data; - - if ((!(PKT_IS_IPV4(p))) && (!(PKT_IS_IPV6(p)))) - return 0; - - BUG_ON(ff->flags & FILE_LOGGED); - - SCLogDebug("ff %p", ff); - - /* Get the TX so the script can get more context about it. - * TODO hardcoded to HTTP currently */ - void *txptr = NULL; - if (p && p->flow && p->flow->alstate) - txptr = AppLayerParserGetTx(p->proto, ALPROTO_HTTP, p->flow->alstate, ff->txid); - - SCMutexLock(&td->lua_ctx->m); - - LuaStateSetThreadVars(td->lua_ctx->luastate, tv); - LuaStateSetPacket(td->lua_ctx->luastate, (Packet *)p); - LuaStateSetTX(td->lua_ctx->luastate, txptr); - LuaStateSetFlow(td->lua_ctx->luastate, p->flow, /* locked */LUA_FLOW_LOCKED_BY_PARENT); - LuaStateSetFile(td->lua_ctx->luastate, (File *)ff); - - /* get the lua function to call */ - lua_getglobal(td->lua_ctx->luastate, "log"); - - int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1)); - } - SCMutexUnlock(&td->lua_ctx->m); - return 0; -} - -/** \internal - * \brief Flow API Logger function for Lua scripts - * - * Executes a script once for one flow - * - * Note: flow 'f' is locked - */ -static int LuaFlowLogger(ThreadVars *tv, void *thread_data, Flow *f) -{ - SCEnter(); - LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data; - - SCLogDebug("f %p", f); - - SCMutexLock(&td->lua_ctx->m); - - LuaStateSetThreadVars(td->lua_ctx->luastate, tv); - LuaStateSetFlow(td->lua_ctx->luastate, f, /* locked */LUA_FLOW_LOCKED_BY_PARENT); - - /* get the lua function to call */ - lua_getglobal(td->lua_ctx->luastate, "log"); - - int retval = lua_pcall(td->lua_ctx->luastate, 0, 0, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1)); - } - SCMutexUnlock(&td->lua_ctx->m); - return 0; -} - - - -static int LuaStatsLogger(ThreadVars *tv, void *thread_data, const StatsTable *st) -{ - SCEnter(); - LogLuaThreadCtx *td = (LogLuaThreadCtx *)thread_data; - - SCMutexLock(&td->lua_ctx->m); - - lua_State *luastate = td->lua_ctx->luastate; - /* get the lua function to call */ - lua_getglobal(td->lua_ctx->luastate, "log"); - - /* create lua array, which is really just a table. The key is an int (1-x), - * the value another table with named fields: name, tm_name, value, pvalue. - * { 1, { name=, tmname=, value=, pvalue=}} - * { 2, { name=, tmname=, value=, pvalue=}} - * etc - */ - lua_newtable(luastate); - uint32_t u = 0; - for (; u < st->nstats; u++) { - lua_pushinteger(luastate, u + 1); - - lua_newtable(luastate); - - lua_pushstring(luastate, "name"); - lua_pushstring(luastate, st->stats[u].name); - lua_settable(luastate, -3); - - lua_pushstring(luastate, "tmname"); - lua_pushstring(luastate, st->stats[u].tm_name); - lua_settable(luastate, -3); - - lua_pushstring(luastate, "value"); - lua_pushinteger(luastate, st->stats[u].value); - lua_settable(luastate, -3); - - lua_pushstring(luastate, "pvalue"); - lua_pushinteger(luastate, st->stats[u].pvalue); - lua_settable(luastate, -3); - - lua_settable(luastate, -3); - } - - int retval = lua_pcall(td->lua_ctx->luastate, 1, 0, 0); - if (retval != 0) { - SCLogInfo("failed to run script: %s", lua_tostring(td->lua_ctx->luastate, -1)); - } - SCMutexUnlock(&td->lua_ctx->m); - return 0; - -} - -typedef struct LogLuaScriptOptions_ { - AppProto alproto; - int packet; - int alerts; - int file; - int streaming; - int tcp_data; - int http_body; - int flow; - int stats; -} LogLuaScriptOptions; - -/** \brief load and evaluate the script - * - * This function parses the script, checks if all the required functions - * are defined and runs the 'init' function. The init function will inform - * us what the scripts needs are. - * - * \param filename filename of lua script file - * \param options struct to pass script requirements/options back to caller - * \retval errcode 0 ok, -1 error - */ -static int LuaScriptInit(const char *filename, LogLuaScriptOptions *options) { - int status; - - lua_State *luastate = luaL_newstate(); - if (luastate == NULL) - goto error; - luaL_openlibs(luastate); - - /* hackish, needed to allow unittests to pass buffers as scripts instead of files */ -#if 0//def UNITTESTS - if (ut_script != NULL) { - status = luaL_loadbuffer(luastate, ut_script, strlen(ut_script), "unittest"); - if (status) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't load file: %s", lua_tostring(luastate, -1)); - goto error; - } - } else { -#endif - status = luaL_loadfile(luastate, filename); - if (status) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't load file: %s", lua_tostring(luastate, -1)); - goto error; - } -#if 0//def UNITTESTS - } -#endif - - /* prime the script (or something) */ - if (lua_pcall(luastate, 0, 0, 0) != 0) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't prime file: %s", lua_tostring(luastate, -1)); - goto error; - } - - lua_getglobal(luastate, "init"); - if (lua_type(luastate, -1) != LUA_TFUNCTION) { - SCLogError(SC_ERR_LUA_ERROR, "no init function in script"); - goto error; - } - - lua_newtable(luastate); /* stack at -1 */ - if (lua_gettop(luastate) == 0 || lua_type(luastate, 2) != LUA_TTABLE) { - SCLogError(SC_ERR_LUA_ERROR, "no table setup"); - goto error; - } - - lua_pushliteral(luastate, "script_api_ver"); - lua_pushnumber (luastate, 1); - lua_settable(luastate, -3); - - if (lua_pcall(luastate, 1, 1, 0) != 0) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't run script 'init' function: %s", lua_tostring(luastate, -1)); - goto error; - } - - /* process returns from script */ - if (lua_gettop(luastate) == 0) { - SCLogError(SC_ERR_LUA_ERROR, "init function in script should return table, nothing returned"); - goto error; - } - if (lua_type(luastate, 1) != LUA_TTABLE) { - SCLogError(SC_ERR_LUA_ERROR, "init function in script should return table, returned is not table"); - goto error; - } - - lua_pushnil(luastate); - const char *k, *v; - while (lua_next(luastate, -2)) { - k = lua_tostring(luastate, -2); - if (k == NULL) - continue; - - v = lua_tostring(luastate, -1); - lua_pop(luastate, 1); - if (v == NULL) - continue; - - SCLogDebug("k='%s', v='%s'", k, v); - - if (strcmp(k,"protocol") == 0 && strcmp(v, "http") == 0) - options->alproto = ALPROTO_HTTP; - else if (strcmp(k,"protocol") == 0 && strcmp(v, "dns") == 0) - options->alproto = ALPROTO_DNS; - else if (strcmp(k,"protocol") == 0 && strcmp(v, "tls") == 0) - options->alproto = ALPROTO_TLS; - else if (strcmp(k,"protocol") == 0 && strcmp(v, "ssh") == 0) - options->alproto = ALPROTO_SSH; - else if (strcmp(k, "type") == 0 && strcmp(v, "packet") == 0) - options->packet = 1; - else if (strcmp(k, "filter") == 0 && strcmp(v, "alerts") == 0) - options->alerts = 1; - else if (strcmp(k, "type") == 0 && strcmp(v, "file") == 0) - options->file = 1; - else if (strcmp(k, "type") == 0 && strcmp(v, "streaming") == 0) - options->streaming = 1; - else if (strcmp(k, "type") == 0 && strcmp(v, "flow") == 0) - options->flow = 1; - else if (strcmp(k, "filter") == 0 && strcmp(v, "tcp") == 0) - options->tcp_data = 1; - else if (strcmp(k, "type") == 0 && strcmp(v, "stats") == 0) - options->stats = 1; - else - SCLogInfo("unknown key and/or value: k='%s', v='%s'", k, v); - } - - if (((options->alproto != ALPROTO_UNKNOWN)) + options->packet + options->file > 1) { - SCLogError(SC_ERR_LUA_ERROR, "invalid combination of 'needs' in the script"); - goto error; - } - - lua_getglobal(luastate, "setup"); - if (lua_type(luastate, -1) != LUA_TFUNCTION) { - SCLogError(SC_ERR_LUA_ERROR, "no setup function in script"); - goto error; - } - - lua_getglobal(luastate, "log"); - if (lua_type(luastate, -1) != LUA_TFUNCTION) { - SCLogError(SC_ERR_LUA_ERROR, "no log function in script"); - goto error; - } - - lua_getglobal(luastate, "deinit"); - if (lua_type(luastate, -1) != LUA_TFUNCTION) { - SCLogError(SC_ERR_LUA_ERROR, "no deinit function in script"); - goto error; - } - - /* pop the table */ - lua_pop(luastate, 1); - lua_close(luastate); - return 0; -error: - lua_close(luastate); - return -1; -} - -/** \brief setup a luastate for use at runtime - * - * This loads the script, primes it and then runs the 'setup' function. - * - * \retval state Returns the set up luastate on success, NULL on error - */ -static lua_State *LuaScriptSetup(const char *filename) -{ - lua_State *luastate = luaL_newstate(); - if (luastate == NULL) { - SCLogError(SC_ERR_LUA_ERROR, "luaL_newstate failed"); - goto error; - } - - luaL_openlibs(luastate); - - int status; - /* hackish, needed to allow unittests to pass buffers as scripts instead of files */ -#if 0//def UNITTESTS - if (ut_script != NULL) { - status = luaL_loadbuffer(t->luastate, ut_script, strlen(ut_script), "unittest"); - if (status) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't load file: %s", lua_tostring(t->luastate, -1)); - goto error; - } - } else { -#endif - status = luaL_loadfile(luastate, filename); - if (status) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't load file: %s", lua_tostring(luastate, -1)); - goto error; - } -#if 0//def UNITTESTS - } -#endif - - /* prime the script */ - if (lua_pcall(luastate, 0, 0, 0) != 0) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't prime file: %s", lua_tostring(luastate, -1)); - goto error; - } - - lua_getglobal(luastate, "setup"); - - /* register functions common to all */ - LuaRegisterFunctions(luastate); - /* unconditionally register http function. They will only work - * if the tx is registered in the state at runtime though. */ - LuaRegisterHttpFunctions(luastate); - LuaRegisterDnsFunctions(luastate); - LuaRegisterTlsFunctions(luastate); - LuaRegisterSshFunctions(luastate); - - if (lua_pcall(luastate, 0, 0, 0) != 0) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't run script 'setup' function: %s", lua_tostring(luastate, -1)); - goto error; - } - - SCLogDebug("lua_State %p is set up", luastate); - return luastate; -error: - lua_close(luastate); - return NULL; -} - -/** \brief initialize output for a script instance - * - * Runs script 'setup' function. - */ -static OutputCtx *OutputLuaLogInitSub(ConfNode *conf, OutputCtx *parent_ctx) -{ - if (conf == NULL) - return NULL; - - LogLuaCtx *lua_ctx = SCMalloc(sizeof(LogLuaCtx)); - if (unlikely(lua_ctx == NULL)) - return NULL; - memset(lua_ctx, 0x00, sizeof(*lua_ctx)); - - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - SCFree(lua_ctx); - return NULL; - } - - SCMutexInit(&lua_ctx->m, NULL); - - const char *dir = ""; - if (parent_ctx && parent_ctx->data) { - LogLuaMasterCtx *mc = parent_ctx->data; - dir = mc->path; - } - - char path[PATH_MAX] = ""; - snprintf(path, sizeof(path),"%s%s%s", dir, strlen(dir) ? "/" : "", conf->val); - SCLogDebug("script full path %s", path); - - SCMutexLock(&lua_ctx->m); - lua_ctx->luastate = LuaScriptSetup(path); - SCMutexUnlock(&lua_ctx->m); - if (lua_ctx->luastate == NULL) - goto error; - - SCLogDebug("lua_ctx %p", lua_ctx); - - output_ctx->data = lua_ctx; - output_ctx->DeInit = NULL; - - return output_ctx; -error: - SCMutexDestroy(&lua_ctx->m); - SCFree(lua_ctx); - SCFree(output_ctx); - return NULL; -} - -static void LogLuaMasterFree(OutputCtx *oc) { - BUG_ON(oc == NULL); - if (oc->data) - SCFree(oc->data); -} - -/** \internal - * \brief initialize output instance for lua module - * - * Parses nested script list, primes them to find out what they - * inspect, then fills the OutputCtx::submodules list with the - * proper Logger function for the data type the script needs. - */ -static OutputCtx *OutputLuaLogInit(ConfNode *conf) -{ - const char *dir = ConfNodeLookupChildValue(conf, "scripts-dir"); - if (dir == NULL) - dir = ""; - - ConfNode *scripts = ConfNodeLookupChild(conf, "scripts"); - if (scripts == NULL) { - /* No "outputs" section in the configuration. */ - SCLogInfo("scripts not defined"); - return NULL; - } - - /* global output ctx setup */ - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); - if (unlikely(output_ctx == NULL)) { - return NULL; - } - output_ctx->data = SCCalloc(1, sizeof(LogLuaMasterCtx)); - if (unlikely(output_ctx->data == NULL)) { - SCFree(output_ctx); - return NULL; - } - output_ctx->DeInit = LogLuaMasterFree; - LogLuaMasterCtx *master_config = output_ctx->data; - strlcpy(master_config->path, dir, sizeof(master_config->path)); - TAILQ_INIT(&output_ctx->submodules); - - /* check the enables scripts and set them up as submodules */ - ConfNode *script; - TAILQ_FOREACH(script, &scripts->head, next) { - SCLogInfo("enabling script %s", script->val); - LogLuaScriptOptions opts; - memset(&opts, 0x00, sizeof(opts)); - - char path[PATH_MAX] = ""; - snprintf(path, sizeof(path),"%s%s%s", dir, strlen(dir) ? "/" : "", script->val); - SCLogDebug("script full path %s", path); - - int r = LuaScriptInit(path, &opts); - if (r != 0) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't initialize scipt"); - goto error; - } - - /* create an OutputModule for this script, based - * on it's needs. */ - OutputModule *om = SCCalloc(1, sizeof(*om)); - if (om == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "calloc() failed"); - goto error; - } - - om->name = MODULE_NAME; - om->conf_name = script->val; - om->InitSubFunc = OutputLuaLogInitSub; - - if (opts.alproto == ALPROTO_HTTP && opts.streaming) { - om->StreamingLogFunc = LuaStreamingLogger; - om->alproto = ALPROTO_HTTP; - AppLayerHtpEnableRequestBodyCallback(); - AppLayerHtpEnableResponseBodyCallback(); - } else if (opts.alproto == ALPROTO_HTTP) { - om->TxLogFunc = LuaTxLogger; - om->alproto = ALPROTO_HTTP; - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_HTTP); - } else if (opts.alproto == ALPROTO_TLS) { - om->PacketLogFunc = LuaPacketLoggerTls; - om->PacketConditionFunc = LuaPacketConditionTls; - } else if (opts.alproto == ALPROTO_DNS) { - om->TxLogFunc = LuaTxLogger; - om->alproto = ALPROTO_DNS; - AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_DNS); - AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_DNS); - } else if (opts.alproto == ALPROTO_SSH) { - om->PacketLogFunc = LuaPacketLoggerSsh; - om->PacketConditionFunc = LuaPacketConditionSsh; - } else if (opts.packet && opts.alerts) { - om->PacketLogFunc = LuaPacketLoggerAlerts; - om->PacketConditionFunc = LuaPacketConditionAlerts; - } else if (opts.packet && opts.alerts == 0) { - om->PacketLogFunc = LuaPacketLogger; - om->PacketConditionFunc = LuaPacketCondition; - } else if (opts.file) { - om->FileLogFunc = LuaFileLogger; - AppLayerHtpNeedFileInspection(); - } else if (opts.streaming && opts.tcp_data) { - om->StreamingLogFunc = LuaStreamingLogger; - } else if (opts.flow) { - om->FlowLogFunc = LuaFlowLogger; - } else if (opts.stats) { - om->StatsLogFunc = LuaStatsLogger; - } else { - SCLogError(SC_ERR_LUA_ERROR, "failed to setup thread module"); - SCFree(om); - goto error; - } - - TAILQ_INSERT_TAIL(&output_ctx->submodules, om, entries); - } - - return output_ctx; - -error: - - if (output_ctx != NULL) { - if (output_ctx->DeInit && output_ctx->data) - output_ctx->DeInit(output_ctx->data); - SCFree(output_ctx); - } - return NULL; -} - -/** \internal - * \brief Run the scripts 'deinit' function - */ -static void OutputLuaLogDoDeinit(LogLuaCtx *lua_ctx) -{ - lua_State *luastate = lua_ctx->luastate; - - lua_getglobal(luastate, "deinit"); - if (lua_type(luastate, -1) != LUA_TFUNCTION) { - SCLogError(SC_ERR_LUA_ERROR, "no deinit function in script"); - return; - } - //LuaPrintStack(luastate); - - if (lua_pcall(luastate, 0, 0, 0) != 0) { - SCLogError(SC_ERR_LUA_ERROR, "couldn't run script 'deinit' function: %s", lua_tostring(luastate, -1)); - return; - } -} - -/** \internal - * \brief Initialize the thread storage for lua - * - * Currently only stores a pointer to the global LogLuaCtx - */ -static TmEcode LuaLogThreadInit(ThreadVars *t, void *initdata, void **data) -{ - LogLuaThreadCtx *td = SCMalloc(sizeof(*td)); - if (unlikely(td == NULL)) - return TM_ECODE_FAILED; - memset(td, 0, sizeof(*td)); - - if (initdata == NULL) { - SCLogDebug("Error getting context for LuaLog. \"initdata\" argument NULL"); - SCFree(td); - return TM_ECODE_FAILED; - } - - LogLuaCtx *lua_ctx = ((OutputCtx *)initdata)->data; - SCLogDebug("lua_ctx %p", lua_ctx); - td->lua_ctx = lua_ctx; - *data = (void *)td; - return TM_ECODE_OK; -} - -/** \internal - * \brief Deinit the thread storage for lua - * - * Calls OutputLuaLogDoDeinit if no-one else already did. - */ -static TmEcode LuaLogThreadDeinit(ThreadVars *t, void *data) -{ - LogLuaThreadCtx *td = (LogLuaThreadCtx *)data; - if (td == NULL) { - return TM_ECODE_OK; - } - - SCMutexLock(&td->lua_ctx->m); - if (td->lua_ctx->deinit_once == 0) { - OutputLuaLogDoDeinit(td->lua_ctx); - td->lua_ctx->deinit_once = 1; - } - SCMutexUnlock(&td->lua_ctx->m); - - /* clear memory */ - memset(td, 0, sizeof(*td)); - - SCFree(td); - return TM_ECODE_OK; -} - -void TmModuleLuaLogRegister (void) { - tmm_modules[TMM_LUALOG].name = MODULE_NAME; - tmm_modules[TMM_LUALOG].ThreadInit = LuaLogThreadInit; - tmm_modules[TMM_LUALOG].ThreadDeinit = LuaLogThreadDeinit; - tmm_modules[TMM_LUALOG].RegisterTests = NULL; - tmm_modules[TMM_LUALOG].cap_flags = 0; - tmm_modules[TMM_LUALOG].flags = TM_FLAG_LOGAPI_TM; - - /* register as separate module */ - OutputRegisterModule(MODULE_NAME, "lua", OutputLuaLogInit); -} - -#else - -void TmModuleLuaLogRegister (void) { - /* no-op */ -} - -#endif diff --git a/framework/src/suricata/src/output-lua.h b/framework/src/suricata/src/output-lua.h deleted file mode 100644 index 627cdc37..00000000 --- a/framework/src/suricata/src/output-lua.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __OUTPUT_LUA_H__ -#define __OUTPUT_LUA_H__ - -void TmModuleLuaLogRegister (void); - -#endif /* __OUTPUT_LUA_H__ */ diff --git a/framework/src/suricata/src/output-packet.c b/framework/src/suricata/src/output-packet.c deleted file mode 100644 index d2cd901c..00000000 --- a/framework/src/suricata/src/output-packet.c +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Packet Logger Output registration functions - */ - -#include "suricata-common.h" -#include "tm-modules.h" -#include "output-packet.h" -#include "util-profiling.h" - -typedef struct OutputLoggerThreadStore_ { - void *thread_data; - struct OutputLoggerThreadStore_ *next; -} OutputLoggerThreadStore; - -/** per thread data for this module, contains a list of per thread - * data for the packet loggers. */ -typedef struct OutputLoggerThreadData_ { - OutputLoggerThreadStore *store; -} OutputLoggerThreadData; - -/* logger instance, a module + a output ctx, - * it's perfectly valid that have multiple instances of the same - * log module (e.g. fast.log) with different output ctx'. */ -typedef struct OutputPacketLogger_ { - PacketLogger LogFunc; - PacketLogCondition ConditionFunc; - OutputCtx *output_ctx; - struct OutputPacketLogger_ *next; - const char *name; - TmmId module_id; -} OutputPacketLogger; - -static OutputPacketLogger *list = NULL; - -int OutputRegisterPacketLogger(const char *name, PacketLogger LogFunc, PacketLogCondition ConditionFunc, OutputCtx *output_ctx) -{ - int module_id = TmModuleGetIdByName(name); - if (module_id < 0) - return -1; - - OutputPacketLogger *op = SCMalloc(sizeof(*op)); - if (op == NULL) - return -1; - memset(op, 0x00, sizeof(*op)); - - op->LogFunc = LogFunc; - op->ConditionFunc = ConditionFunc; - op->output_ctx = output_ctx; - op->name = name; - op->module_id = (TmmId) module_id; - - if (list == NULL) - list = op; - else { - OutputPacketLogger *t = list; - while (t->next) - t = t->next; - t->next = op; - } - - SCLogDebug("OutputRegisterPacketLogger happy"); - return 0; -} - -static TmEcode OutputPacketLog(ThreadVars *tv, Packet *p, void *thread_data, PacketQueue *pq, PacketQueue *postpq) -{ - BUG_ON(thread_data == NULL); - BUG_ON(list == NULL); - - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputPacketLogger *logger = list; - OutputLoggerThreadStore *store = op_thread_data->store; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - BUG_ON(logger == NULL && store == NULL); - - while (logger && store) { - BUG_ON(logger->LogFunc == NULL || logger->ConditionFunc == NULL); - - if ((logger->ConditionFunc(tv, (const Packet *)p)) == TRUE) { - PACKET_PROFILING_TMM_START(p, logger->module_id); - logger->LogFunc(tv, store->thread_data, (const Packet *)p); - PACKET_PROFILING_TMM_END(p, logger->module_id); - } - - logger = logger->next; - store = store->next; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - } - - return TM_ECODE_OK; -} - -/** \brief thread init for the packet logger - * This will run the thread init functions for the individual registered - * loggers */ -static TmEcode OutputPacketLogThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - OutputLoggerThreadData *td = SCMalloc(sizeof(*td)); - if (td == NULL) - return TM_ECODE_FAILED; - memset(td, 0x00, sizeof(*td)); - - *data = (void *)td; - - SCLogDebug("OutputPacketLogThreadInit happy (*data %p)", *data); - - OutputPacketLogger *logger = list; - while (logger) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadInit) { - void *retptr = NULL; - if (tm_module->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) { - OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts)); -/* todo */ BUG_ON(ts == NULL); - memset(ts, 0x00, sizeof(*ts)); - - /* store thread handle */ - ts->thread_data = retptr; - - if (td->store == NULL) { - td->store = ts; - } else { - OutputLoggerThreadStore *tmp = td->store; - while (tmp->next != NULL) - tmp = tmp->next; - tmp->next = ts; - } - - SCLogDebug("%s is now set up", logger->name); - } - } - - logger = logger->next; - } - - return TM_ECODE_OK; -} - -static TmEcode OutputPacketLogThreadDeinit(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputPacketLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadDeinit) { - tm_module->ThreadDeinit(tv, store->thread_data); - } - - OutputLoggerThreadStore *next_store = store->next; - SCFree(store); - store = next_store; - - logger = logger->next; - } - return TM_ECODE_OK; -} - -static void OutputPacketLogExitPrintStats(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputPacketLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadExitPrintStats) { - tm_module->ThreadExitPrintStats(tv, store->thread_data); - } - - logger = logger->next; - store = store->next; - } -} - -void TmModulePacketLoggerRegister (void) -{ - tmm_modules[TMM_PACKETLOGGER].name = "__packet_logger__"; - tmm_modules[TMM_PACKETLOGGER].ThreadInit = OutputPacketLogThreadInit; - tmm_modules[TMM_PACKETLOGGER].Func = OutputPacketLog; - tmm_modules[TMM_PACKETLOGGER].ThreadExitPrintStats = OutputPacketLogExitPrintStats; - tmm_modules[TMM_PACKETLOGGER].ThreadDeinit = OutputPacketLogThreadDeinit; - tmm_modules[TMM_PACKETLOGGER].cap_flags = 0; -} - -void OutputPacketShutdown(void) -{ - OutputPacketLogger *logger = list; - while (logger) { - OutputPacketLogger *next_logger = logger->next; - SCFree(logger); - logger = next_logger; - } - - /* reset list pointer */ - list = NULL; -} diff --git a/framework/src/suricata/src/output-packet.h b/framework/src/suricata/src/output-packet.h deleted file mode 100644 index 5ae1adf8..00000000 --- a/framework/src/suricata/src/output-packet.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Packet Logger Output registration functions - */ - -#ifndef __OUTPUT_PACKET_H__ -#define __OUTPUT_PACKET_H__ - -#include "decode.h" - -/** packet logger function pointer type */ -typedef int (*PacketLogger)(ThreadVars *, void *thread_data, const Packet *); - -/** packet logger condition function pointer type, - * must return true for packets that should be logged - */ -typedef int (*PacketLogCondition)(ThreadVars *, const Packet *); - -int OutputRegisterPacketLogger(const char *name, PacketLogger LogFunc, - PacketLogCondition ConditionFunc, OutputCtx *); - -void TmModulePacketLoggerRegister (void); - -void OutputPacketShutdown(void); - -#endif /* __OUTPUT_PACKET_H__ */ diff --git a/framework/src/suricata/src/output-stats.c b/framework/src/suricata/src/output-stats.c deleted file mode 100644 index a6752fc5..00000000 --- a/framework/src/suricata/src/output-stats.c +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Stats Logger Output registration functions - */ - -#include "suricata-common.h" -#include "tm-modules.h" -#include "output-stats.h" - -typedef struct OutputLoggerThreadStore_ { - void *thread_data; - struct OutputLoggerThreadStore_ *next; -} OutputLoggerThreadStore; - -/** per thread data for this module, contains a list of per thread - * data for the packet loggers. */ -typedef struct OutputLoggerThreadData_ { - OutputLoggerThreadStore *store; -} OutputLoggerThreadData; - -/* logger instance, a module + a output ctx, - * it's perfectly valid that have multiple instances of the same - * log module (e.g. http.log) with different output ctx'. */ -typedef struct OutputStatsLogger_ { - StatsLogger LogFunc; - OutputCtx *output_ctx; - struct OutputStatsLogger_ *next; - const char *name; - TmmId module_id; -} OutputStatsLogger; - -static OutputStatsLogger *list = NULL; - -int OutputRegisterStatsLogger(const char *name, StatsLogger LogFunc, OutputCtx *output_ctx) -{ - int module_id = TmModuleGetIdByName(name); - if (module_id < 0) - return -1; - - OutputStatsLogger *op = SCMalloc(sizeof(*op)); - if (op == NULL) - return -1; - memset(op, 0x00, sizeof(*op)); - - op->LogFunc = LogFunc; - op->output_ctx = output_ctx; - op->name = name; - op->module_id = (TmmId) module_id; - - if (list == NULL) - list = op; - else { - OutputStatsLogger *t = list; - while (t->next) - t = t->next; - t->next = op; - } - - SCLogDebug("OutputRegisterStatsLogger happy"); - return 0; -} - -TmEcode OutputStatsLog(ThreadVars *tv, void *thread_data, StatsTable *st) -{ - BUG_ON(thread_data == NULL); - BUG_ON(list == NULL); - - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputStatsLogger *logger = list; - OutputLoggerThreadStore *store = op_thread_data->store; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - BUG_ON(logger == NULL && store == NULL); - - logger = list; - store = op_thread_data->store; - while (logger && store) { - BUG_ON(logger->LogFunc == NULL); - - logger->LogFunc(tv, store->thread_data, st); - - logger = logger->next; - store = store->next; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - } - - return TM_ECODE_OK; -} - -/** \brief thread init for the tx logger - * This will run the thread init functions for the individual registered - * loggers */ -static TmEcode OutputStatsLogThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - OutputLoggerThreadData *td = SCMalloc(sizeof(*td)); - if (td == NULL) - return TM_ECODE_FAILED; - memset(td, 0x00, sizeof(*td)); - - *data = (void *)td; - - SCLogDebug("OutputStatsLogThreadInit happy (*data %p)", *data); - - OutputStatsLogger *logger = list; - while (logger) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadInit) { - void *retptr = NULL; - if (tm_module->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) { - OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts)); -/* todo */ BUG_ON(ts == NULL); - memset(ts, 0x00, sizeof(*ts)); - - /* store thread handle */ - ts->thread_data = retptr; - - if (td->store == NULL) { - td->store = ts; - } else { - OutputLoggerThreadStore *tmp = td->store; - while (tmp->next != NULL) - tmp = tmp->next; - tmp->next = ts; - } - - SCLogDebug("%s is now set up", logger->name); - } - } - - logger = logger->next; - } - - SCLogDebug("OutputStatsLogThreadInit happy (*data %p)", *data); - return TM_ECODE_OK; -} - -static TmEcode OutputStatsLogThreadDeinit(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputStatsLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadDeinit) { - tm_module->ThreadDeinit(tv, store->thread_data); - } - - OutputLoggerThreadStore *next_store = store->next; - SCFree(store); - store = next_store; - logger = logger->next; - } - return TM_ECODE_OK; -} - -static void OutputStatsLogExitPrintStats(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputStatsLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadExitPrintStats) { - tm_module->ThreadExitPrintStats(tv, store->thread_data); - } - - logger = logger->next; - store = store->next; - } -} - -void TmModuleStatsLoggerRegister (void) -{ - tmm_modules[TMM_STATSLOGGER].name = "__stats_logger__"; - tmm_modules[TMM_STATSLOGGER].ThreadInit = OutputStatsLogThreadInit; - //tmm_modules[TMM_STATSLOGGER].Func = OutputStatsLog; - tmm_modules[TMM_STATSLOGGER].ThreadExitPrintStats = OutputStatsLogExitPrintStats; - tmm_modules[TMM_STATSLOGGER].ThreadDeinit = OutputStatsLogThreadDeinit; - tmm_modules[TMM_STATSLOGGER].cap_flags = 0; -} - -int OutputStatsLoggersRegistered(void) -{ - if (list != NULL) - return 1; - return 0; -} - -void OutputStatsShutdown(void) -{ - OutputStatsLogger *logger = list; - while (logger) { - OutputStatsLogger *next_logger = logger->next; - SCFree(logger); - logger = next_logger; - } - list = NULL; -} diff --git a/framework/src/suricata/src/output-stats.h b/framework/src/suricata/src/output-stats.h deleted file mode 100644 index 75017ca2..00000000 --- a/framework/src/suricata/src/output-stats.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Stats Logger Output registration functions - */ - -#ifndef __OUTPUT_STATS_H__ -#define __OUTPUT_STATS_H__ - -typedef struct StatsRecord_ { - const char *name; - const char *tm_name; - uint64_t value; /**< total value */ - uint64_t pvalue; /**< prev value (may be higher for memuse counters) */ -} StatsRecord; - -typedef struct StatsTable_ { - StatsRecord *stats; /**< array of global stats, indexed by counters gid */ - StatsRecord *tstats; /**< array of arrays with per thread stats */ - uint32_t nstats; /**< size in records of 'stats' */ - uint32_t ntstats; /**< number of threads for which tstats stores stats */ - time_t start_time; - struct timeval ts; -} StatsTable; - -TmEcode OutputStatsLog(ThreadVars *tv, void *thread_data, StatsTable *st); - -typedef int (*StatsLogger)(ThreadVars *, void *thread_data, const StatsTable *); - -int OutputRegisterStatsLogger(const char *name, StatsLogger LogFunc, OutputCtx *); - -void TmModuleStatsLoggerRegister (void); - -int OutputStatsLoggersRegistered(void); - -void OutputStatsShutdown(void); - -#endif /* __OUTPUT_STATS_H__ */ diff --git a/framework/src/suricata/src/output-streaming.c b/framework/src/suricata/src/output-streaming.c deleted file mode 100644 index d416cbc3..00000000 --- a/framework/src/suricata/src/output-streaming.c +++ /dev/null @@ -1,469 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Logger for streaming data - */ - -#include "suricata-common.h" -#include "tm-modules.h" -#include "output-streaming.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-htp.h" -#include "util-print.h" -#include "conf.h" -#include "util-profiling.h" - -typedef struct OutputLoggerThreadStore_ { - void *thread_data; - struct OutputLoggerThreadStore_ *next; -} OutputLoggerThreadStore; - -/** per thread data for this module, contains a list of per thread - * data for the packet loggers. */ -typedef struct OutputLoggerThreadData_ { - OutputLoggerThreadStore *store; - uint32_t loggers; -} OutputLoggerThreadData; - -/* logger instance, a module + a output ctx, - * it's perfectly valid that have multiple instances of the same - * log module (e.g. http.log) with different output ctx'. */ -typedef struct OutputStreamingLogger_ { - StreamingLogger LogFunc; - OutputCtx *output_ctx; - struct OutputStreamingLogger_ *next; - const char *name; - TmmId module_id; - enum OutputStreamingType type; -} OutputStreamingLogger; - -static OutputStreamingLogger *list = NULL; - -int OutputRegisterStreamingLogger(const char *name, StreamingLogger LogFunc, - OutputCtx *output_ctx, enum OutputStreamingType type ) -{ - int module_id = TmModuleGetIdByName(name); - if (module_id < 0) - return -1; - - OutputStreamingLogger *op = SCMalloc(sizeof(*op)); - if (op == NULL) - return -1; - memset(op, 0x00, sizeof(*op)); - - op->LogFunc = LogFunc; - op->output_ctx = output_ctx; - op->name = name; - op->module_id = (TmmId) module_id; - op->type = type; - - if (list == NULL) - list = op; - else { - OutputStreamingLogger *t = list; - while (t->next) - t = t->next; - t->next = op; - } - - SCLogDebug("OutputRegisterTxLogger happy"); - return 0; -} - -typedef struct StreamerCallbackData_ { - OutputStreamingLogger *logger; - OutputLoggerThreadStore *store; - ThreadVars *tv; - Packet *p; - enum OutputStreamingType type; -} StreamerCallbackData; - -int Streamer(void *cbdata, Flow *f, uint8_t *data, uint32_t data_len, uint64_t tx_id, uint8_t flags) -{ - StreamerCallbackData *streamer_cbdata = (StreamerCallbackData *)cbdata; - BUG_ON(streamer_cbdata == NULL); - OutputStreamingLogger *logger = streamer_cbdata->logger; - OutputLoggerThreadStore *store = streamer_cbdata->store; - ThreadVars *tv = streamer_cbdata->tv; -#ifdef PROFILING - Packet *p = streamer_cbdata->p; -#endif - BUG_ON(logger == NULL); - BUG_ON(store == NULL); - - while (logger && store) { - BUG_ON(logger->LogFunc == NULL); - - if (logger->type == streamer_cbdata->type) { - SCLogDebug("logger %p", logger); - PACKET_PROFILING_TMM_START(p, logger->module_id); - logger->LogFunc(tv, store->thread_data, (const Flow *)f, data, data_len, tx_id, flags); - PACKET_PROFILING_TMM_END(p, logger->module_id); - } - - logger = logger->next; - store = store->next; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - } - - return 0; -} - -/** \brief Http Body Iterator for logging - * - * Global logic: - * - * - For each tx - * - For each body chunk - * - Invoke Streamer - */ - -int HttpBodyIterator(Flow *f, int close, void *cbdata, uint8_t iflags) -{ - SCLogDebug("called with %p, %d, %p, %02x", f, close, cbdata, iflags); - - HtpState *s = f->alstate; - if (s != NULL && s->conn != NULL) { - int tx_progress_done_value_ts = - AppLayerParserGetStateProgressCompletionStatus(IPPROTO_TCP, - ALPROTO_HTTP, STREAM_TOSERVER); - int tx_progress_done_value_tc = - AppLayerParserGetStateProgressCompletionStatus(IPPROTO_TCP, - ALPROTO_HTTP, STREAM_TOCLIENT); - - // for each tx - uint64_t tx_id = 0; - uint64_t total_txs = AppLayerParserGetTxCnt(f->proto, f->alproto, f->alstate); - SCLogDebug("s->conn %p", s->conn); - for (tx_id = 0; tx_id < total_txs; tx_id++) { // TODO optimization store log tx - htp_tx_t *tx = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, tx_id); - if (tx != NULL) { - int tx_done = 0; - int tx_logged = 0; - - int tx_progress_ts = AppLayerParserGetStateProgress( - IPPROTO_TCP, ALPROTO_HTTP, tx, FlowGetDisruptionFlags(f, STREAM_TOSERVER)); - if (tx_progress_ts >= tx_progress_done_value_ts) { - int tx_progress_tc = AppLayerParserGetStateProgress( - IPPROTO_TCP, ALPROTO_HTTP, tx, FlowGetDisruptionFlags(f, STREAM_TOCLIENT)); - if (tx_progress_tc >= tx_progress_done_value_tc) { - tx_done = 1; - } - } - - SCLogDebug("tx %p", tx); - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (htud != NULL) { - SCLogDebug("htud %p", htud); - HtpBody *body = NULL; - if (iflags & OUTPUT_STREAMING_FLAG_TOCLIENT) - body = &htud->request_body; - else if (iflags & OUTPUT_STREAMING_FLAG_TOSERVER) - body = &htud->response_body; - - if (body == NULL) { - SCLogDebug("no body"); - goto next; - } - if (body->first == NULL) { - SCLogDebug("no body chunks"); - goto next; - } - if (body->last->logged == 1) { - SCLogDebug("all logged already"); - goto next; - } - - // for each chunk - HtpBodyChunk *chunk = body->first; - for ( ; chunk != NULL; chunk = chunk->next) { - if (chunk->logged) { - SCLogDebug("logged %d", chunk->logged); - continue; - } - - uint8_t flags = iflags | OUTPUT_STREAMING_FLAG_TRANSACTION; - if (chunk->stream_offset == 0) - flags |= OUTPUT_STREAMING_FLAG_OPEN; - /* if we need to close and we're at the last segment in the list - * we add the 'close' flag so the logger can close up. */ - if ((tx_done || close) && chunk->next == NULL) { - flags |= OUTPUT_STREAMING_FLAG_CLOSE; - } - - // invoke Streamer - Streamer(cbdata, f, chunk->data, (uint32_t)chunk->len, tx_id, flags); - //PrintRawDataFp(stdout, chunk->data, chunk->len); - chunk->logged = 1; - tx_logged = 1; - } - - next: - /* if we need to close we need to invoke the Streamer for sure. If we - * logged no chunks, we call the Streamer with NULL data so it can - * close up. */ - if (tx_logged == 0 && (close||tx_done)) { - Streamer(cbdata, f, NULL, 0, tx_id, - OUTPUT_STREAMING_FLAG_CLOSE|OUTPUT_STREAMING_FLAG_TRANSACTION); - } - } - } - } - } - - - return 0; -} - -int StreamIterator(Flow *f, TcpStream *stream, int close, void *cbdata, uint8_t iflags) -{ - SCLogDebug("called with %p, %d, %p, %02x", f, close, cbdata, iflags); - int logged = 0; - - /* optimization: don't iterate list if we've logged all, - * so check the last segment's flags */ - if (stream->seg_list_tail != NULL && - (!(stream->seg_list_tail->flags & SEGMENTTCP_FLAG_LOGAPI_PROCESSED))) - { - TcpSegment *seg = stream->seg_list; - while (seg) { - uint8_t flags = iflags; - - if (seg->flags & SEGMENTTCP_FLAG_LOGAPI_PROCESSED) { - seg = seg->next; - continue; - } - - if (SEQ_GT(seg->seq + seg->payload_len, stream->last_ack)) { - SCLogDebug("seg not (fully) acked yet"); - break; - } - - if (seg->seq == stream->isn + 1) - flags |= OUTPUT_STREAMING_FLAG_OPEN; - /* if we need to close and we're at the last segment in the list - * we add the 'close' flag so the logger can close up. */ - if (close && seg->next == NULL) - flags |= OUTPUT_STREAMING_FLAG_CLOSE; - - Streamer(cbdata, f, seg->payload, (uint32_t)seg->payload_len, 0, flags); - - seg->flags |= SEGMENTTCP_FLAG_LOGAPI_PROCESSED; - - seg = seg->next; - - logged = 1; - } - } - - /* if we need to close we need to invoke the Streamer for sure. If we - * logged no segments, we call the Streamer with NULL data so it can - * close up. */ - if (logged == 0 && close) { - Streamer(cbdata, f, NULL, 0, 0, OUTPUT_STREAMING_FLAG_CLOSE); - } - - return 0; -} - -static TmEcode OutputStreamingLog(ThreadVars *tv, Packet *p, void *thread_data, PacketQueue *pq, PacketQueue *postpq) -{ - BUG_ON(thread_data == NULL); - BUG_ON(list == NULL); - - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputStreamingLogger *logger = list; - OutputLoggerThreadStore *store = op_thread_data->store; - - StreamerCallbackData streamer_cbdata = { logger, store, tv, p , 0}; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - BUG_ON(logger == NULL && store == NULL); - - uint8_t flags = 0; - Flow * const f = p->flow; - - /* no flow, no streaming */ - if (f == NULL) { - SCReturnInt(TM_ECODE_OK); - } - - if (p->flowflags & FLOW_PKT_TOCLIENT) - flags |= OUTPUT_STREAMING_FLAG_TOCLIENT; - else - flags |= OUTPUT_STREAMING_FLAG_TOSERVER; - - FLOWLOCK_WRLOCK(f); - - if (op_thread_data->loggers & (1<protoctx; - if (ssn) { - int close = (ssn->state >= TCP_CLOSED); - close |= ((p->flags & PKT_PSEUDO_STREAM_END) ? 1 : 0); - SCLogDebug("close ? %s", close ? "yes" : "no"); - - TcpStream *stream = flags & OUTPUT_STREAMING_FLAG_TOSERVER ? &ssn->client : &ssn->server; - - streamer_cbdata.type = STREAMING_TCP_DATA; - StreamIterator(p->flow, stream, close, (void *)&streamer_cbdata, flags); - } - } - if (op_thread_data->loggers & (1<alproto == ALPROTO_HTTP && f->alstate != NULL) { - int close = 0; - TcpSession *ssn = f->protoctx; - if (ssn) { - close = (ssn->state >= TCP_CLOSED); - close |= ((p->flags & PKT_PSEUDO_STREAM_END) ? 1 : 0); - } - SCLogDebug("close ? %s", close ? "yes" : "no"); - streamer_cbdata.type = STREAMING_HTTP_BODIES; - HttpBodyIterator(f, close, (void *)&streamer_cbdata, flags); - } - } - - FLOWLOCK_UNLOCK(f); - return TM_ECODE_OK; -} - -/** \brief thread init for the tx logger - * This will run the thread init functions for the individual registered - * loggers */ -static TmEcode OutputStreamingLogThreadInit(ThreadVars *tv, void *initdata, void **data) { - OutputLoggerThreadData *td = SCMalloc(sizeof(*td)); - if (td == NULL) - return TM_ECODE_FAILED; - memset(td, 0x00, sizeof(*td)); - - *data = (void *)td; - - SCLogDebug("OutputStreamingLogThreadInit happy (*data %p)", *data); - - OutputStreamingLogger *logger = list; - while (logger) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadInit) { - void *retptr = NULL; - if (tm_module->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) { - OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts)); -/* todo */ BUG_ON(ts == NULL); - memset(ts, 0x00, sizeof(*ts)); - - /* store thread handle */ - ts->thread_data = retptr; - - if (td->store == NULL) { - td->store = ts; - } else { - OutputLoggerThreadStore *tmp = td->store; - while (tmp->next != NULL) - tmp = tmp->next; - tmp->next = ts; - } - - SCLogInfo("%s is now set up", logger->name); - } - } - - td->loggers |= (1<type); - - logger = logger->next; - } - - return TM_ECODE_OK; -} - -static TmEcode OutputStreamingLogThreadDeinit(ThreadVars *tv, void *thread_data) { - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputStreamingLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadDeinit) { - tm_module->ThreadDeinit(tv, store->thread_data); - } - - logger = logger->next; - store = store->next; - } - - return TM_ECODE_OK; -} - -static void OutputStreamingLogExitPrintStats(ThreadVars *tv, void *thread_data) { - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputStreamingLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadExitPrintStats) { - tm_module->ThreadExitPrintStats(tv, store->thread_data); - } - - logger = logger->next; - store = store->next; - } -} - -void TmModuleStreamingLoggerRegister (void) { - tmm_modules[TMM_STREAMINGLOGGER].name = "__streaming_logger__"; - tmm_modules[TMM_STREAMINGLOGGER].ThreadInit = OutputStreamingLogThreadInit; - tmm_modules[TMM_STREAMINGLOGGER].Func = OutputStreamingLog; - tmm_modules[TMM_STREAMINGLOGGER].ThreadExitPrintStats = OutputStreamingLogExitPrintStats; - tmm_modules[TMM_STREAMINGLOGGER].ThreadDeinit = OutputStreamingLogThreadDeinit; - tmm_modules[TMM_STREAMINGLOGGER].cap_flags = 0; -} - -void OutputStreamingShutdown(void) -{ - OutputStreamingLogger *logger = list; - while (logger) { - OutputStreamingLogger *next_logger = logger->next; - SCFree(logger); - logger = next_logger; - } - list = NULL; -} diff --git a/framework/src/suricata/src/output-streaming.h b/framework/src/suricata/src/output-streaming.h deleted file mode 100644 index 8b303742..00000000 --- a/framework/src/suricata/src/output-streaming.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * AppLayer Filedata Logger Output registration functions - */ - -#ifndef __OUTPUT_STREAMING_H__ -#define __OUTPUT_STREAMING_H__ - -#include "decode.h" -#include "util-file.h" - -#define OUTPUT_STREAMING_FLAG_OPEN 0x01 -#define OUTPUT_STREAMING_FLAG_CLOSE 0x02 -#define OUTPUT_STREAMING_FLAG_TOSERVER 0x04 -#define OUTPUT_STREAMING_FLAG_TOCLIENT 0x08 -#define OUTPUT_STREAMING_FLAG_TRANSACTION 0x10 - -enum OutputStreamingType { - STREAMING_TCP_DATA, - STREAMING_HTTP_BODIES, -}; - -/** filedata logger function pointer type */ -typedef int (*StreamingLogger)(ThreadVars *, void *thread_data, - const Flow *f, const uint8_t *data, uint32_t data_len, - uint64_t tx_id, uint8_t flags); - -int OutputRegisterStreamingLogger(const char *name, StreamingLogger LogFunc, OutputCtx *, - enum OutputStreamingType); - -void TmModuleStreamingLoggerRegister (void); - -void OutputStreamingShutdown(void); - -#endif /* __OUTPUT_STREAMING_H__ */ diff --git a/framework/src/suricata/src/output-tx.c b/framework/src/suricata/src/output-tx.c deleted file mode 100644 index 93ba9956..00000000 --- a/framework/src/suricata/src/output-tx.c +++ /dev/null @@ -1,308 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * AppLayer TX Logger Output registration functions - */ - -#include "suricata-common.h" -#include "tm-modules.h" -#include "output-tx.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-profiling.h" - -typedef struct OutputLoggerThreadStore_ { - void *thread_data; - struct OutputLoggerThreadStore_ *next; -} OutputLoggerThreadStore; - -/** per thread data for this module, contains a list of per thread - * data for the packet loggers. */ -typedef struct OutputLoggerThreadData_ { - OutputLoggerThreadStore *store; -} OutputLoggerThreadData; - -/* logger instance, a module + a output ctx, - * it's perfectly valid that have multiple instances of the same - * log module (e.g. http.log) with different output ctx'. */ -typedef struct OutputTxLogger_ { - AppProto alproto; - TxLogger LogFunc; - OutputCtx *output_ctx; - struct OutputTxLogger_ *next; - const char *name; - TmmId module_id; -} OutputTxLogger; - -static OutputTxLogger *list = NULL; - -int OutputRegisterTxLogger(const char *name, AppProto alproto, TxLogger LogFunc, OutputCtx *output_ctx) -{ - int module_id = TmModuleGetIdByName(name); - if (module_id < 0) - return -1; - - OutputTxLogger *op = SCMalloc(sizeof(*op)); - if (op == NULL) - return -1; - memset(op, 0x00, sizeof(*op)); - - op->alproto = alproto; - op->LogFunc = LogFunc; - op->output_ctx = output_ctx; - op->name = name; - op->module_id = (TmmId) module_id; - - if (list == NULL) - list = op; - else { - OutputTxLogger *t = list; - while (t->next) - t = t->next; - t->next = op; - } - - SCLogDebug("OutputRegisterTxLogger happy"); - return 0; -} - -static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data, PacketQueue *pq, PacketQueue *postpq) -{ - BUG_ON(thread_data == NULL); - BUG_ON(list == NULL); - - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputTxLogger *logger = list; - OutputLoggerThreadStore *store = op_thread_data->store; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - BUG_ON(logger == NULL && store == NULL); - - if (p->flow == NULL) - return TM_ECODE_OK; - - Flow * const f = p->flow; - - FLOWLOCK_WRLOCK(f); /* WRITE lock before we updated flow logged id */ - AppProto alproto = f->alproto; - - if (AppLayerParserProtocolIsTxAware(p->proto, alproto) == 0) - goto end; - if (AppLayerParserProtocolHasLogger(p->proto, alproto) == 0) - goto end; - - void *alstate = f->alstate; - if (alstate == NULL) { - SCLogDebug("no alstate"); - goto end; - } - - uint64_t total_txs = AppLayerParserGetTxCnt(p->proto, alproto, alstate); - uint64_t tx_id = AppLayerParserGetTransactionLogId(f->alparser); - int tx_progress_done_value_ts = - AppLayerParserGetStateProgressCompletionStatus(p->proto, alproto, - STREAM_TOSERVER); - int tx_progress_done_value_tc = - AppLayerParserGetStateProgressCompletionStatus(p->proto, alproto, - STREAM_TOCLIENT); - int proto_logged = 0; - - for (; tx_id < total_txs; tx_id++) - { - void *tx = AppLayerParserGetTx(p->proto, alproto, alstate, tx_id); - if (tx == NULL) { - SCLogDebug("tx is NULL not logging"); - continue; - } - - if (!(AppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_EOF))) - { - int tx_progress = AppLayerParserGetStateProgress(p->proto, alproto, - tx, FlowGetDisruptionFlags(f, STREAM_TOSERVER)); - if (tx_progress < tx_progress_done_value_ts) { - SCLogDebug("progress not far enough, not logging"); - break; - } - - tx_progress = AppLayerParserGetStateProgress(p->proto, alproto, - tx, FlowGetDisruptionFlags(f, STREAM_TOCLIENT)); - if (tx_progress < tx_progress_done_value_tc) { - SCLogDebug("progress not far enough, not logging"); - break; - } - } - - // call each logger here (pseudo code) - logger = list; - store = op_thread_data->store; - while (logger && store) { - BUG_ON(logger->LogFunc == NULL); - - SCLogDebug("logger %p", logger); - if (logger->alproto == alproto) { - SCLogDebug("alproto match, logging tx_id %ju", tx_id); - PACKET_PROFILING_TMM_START(p, logger->module_id); - logger->LogFunc(tv, store->thread_data, p, f, alstate, tx, tx_id); - PACKET_PROFILING_TMM_END(p, logger->module_id); - proto_logged = 1; - } - - logger = logger->next; - store = store->next; - - BUG_ON(logger == NULL && store != NULL); - BUG_ON(logger != NULL && store == NULL); - } - - if (proto_logged) { - SCLogDebug("updating log tx_id %ju", tx_id); - AppLayerParserSetTransactionLogId(f->alparser); - } - } - -end: - FLOWLOCK_UNLOCK(f); - return TM_ECODE_OK; -} - -/** \brief thread init for the tx logger - * This will run the thread init functions for the individual registered - * loggers */ -static TmEcode OutputTxLogThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - OutputLoggerThreadData *td = SCMalloc(sizeof(*td)); - if (td == NULL) - return TM_ECODE_FAILED; - memset(td, 0x00, sizeof(*td)); - - *data = (void *)td; - - SCLogDebug("OutputTxLogThreadInit happy (*data %p)", *data); - - OutputTxLogger *logger = list; - while (logger) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadInit) { - void *retptr = NULL; - if (tm_module->ThreadInit(tv, (void *)logger->output_ctx, &retptr) == TM_ECODE_OK) { - OutputLoggerThreadStore *ts = SCMalloc(sizeof(*ts)); -/* todo */ BUG_ON(ts == NULL); - memset(ts, 0x00, sizeof(*ts)); - - /* store thread handle */ - ts->thread_data = retptr; - - if (td->store == NULL) { - td->store = ts; - } else { - OutputLoggerThreadStore *tmp = td->store; - while (tmp->next != NULL) - tmp = tmp->next; - tmp->next = ts; - } - - SCLogDebug("%s is now set up", logger->name); - } - } - - logger = logger->next; - } - - return TM_ECODE_OK; -} - -static TmEcode OutputTxLogThreadDeinit(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputTxLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadDeinit) { - tm_module->ThreadDeinit(tv, store->thread_data); - } - - OutputLoggerThreadStore *next_store = store->next; - SCFree(store); - store = next_store; - logger = logger->next; - } - return TM_ECODE_OK; -} - -static void OutputTxLogExitPrintStats(ThreadVars *tv, void *thread_data) -{ - OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; - OutputLoggerThreadStore *store = op_thread_data->store; - OutputTxLogger *logger = list; - - while (logger && store) { - TmModule *tm_module = TmModuleGetByName((char *)logger->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", logger->name); - exit(EXIT_FAILURE); - } - - if (tm_module->ThreadExitPrintStats) { - tm_module->ThreadExitPrintStats(tv, store->thread_data); - } - - logger = logger->next; - store = store->next; - } -} - -void TmModuleTxLoggerRegister (void) -{ - tmm_modules[TMM_TXLOGGER].name = "__tx_logger__"; - tmm_modules[TMM_TXLOGGER].ThreadInit = OutputTxLogThreadInit; - tmm_modules[TMM_TXLOGGER].Func = OutputTxLog; - tmm_modules[TMM_TXLOGGER].ThreadExitPrintStats = OutputTxLogExitPrintStats; - tmm_modules[TMM_TXLOGGER].ThreadDeinit = OutputTxLogThreadDeinit; - tmm_modules[TMM_TXLOGGER].cap_flags = 0; -} - -void OutputTxShutdown(void) -{ - OutputTxLogger *logger = list; - while (logger) { - OutputTxLogger *next_logger = logger->next; - SCFree(logger); - logger = next_logger; - } - list = NULL; -} diff --git a/framework/src/suricata/src/output-tx.h b/framework/src/suricata/src/output-tx.h deleted file mode 100644 index 7ffb8a6d..00000000 --- a/framework/src/suricata/src/output-tx.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * AppLayer TX Logger Output registration functions - */ - -#ifndef __OUTPUT_TX_H__ -#define __OUTPUT_TX_H__ - -#include "decode.h" - -/** packet logger function pointer type */ -typedef int (*TxLogger)(ThreadVars *, void *thread_data, const Packet *, Flow *f, void *state, void *tx, uint64_t tx_id); - -/** packet logger condition function pointer type, - * must return true for packets that should be logged - */ -//typedef int (*TxLogCondition)(ThreadVars *, const Packet *); - -int OutputRegisterTxLogger(const char *name, AppProto alproto, TxLogger LogFunc, OutputCtx *); - -void TmModuleTxLoggerRegister (void); - -void OutputTxShutdown(void); - -#endif /* __OUTPUT_PACKET_H__ */ diff --git a/framework/src/suricata/src/output.c b/framework/src/suricata/src/output.c deleted file mode 100644 index 1146b7b2..00000000 --- a/framework/src/suricata/src/output.c +++ /dev/null @@ -1,701 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited, Jason Ish - * - * Output registration functions - */ - -#include "suricata-common.h" -#include "flow.h" -#include "conf.h" -#include "tm-threads.h" -#include "util-error.h" -#include "util-debug.h" -#include "output.h" - -static TAILQ_HEAD(, OutputModule_) output_modules = - TAILQ_HEAD_INITIALIZER(output_modules); - -/** - * Registry of flags to be updated on file rotation notification. - */ -typedef struct OutputFileRolloverFlag_ { - int *flag; - - TAILQ_ENTRY(OutputFileRolloverFlag_) entries; -} OutputFileRolloverFlag; - -TAILQ_HEAD(, OutputFileRolloverFlag_) output_file_rotation_flags = - TAILQ_HEAD_INITIALIZER(output_file_rotation_flags); - -/** - * \brief Register an output module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *)) -{ - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) - goto error; - - module->name = name; - module->conf_name = conf_name; - module->InitFunc = InitFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Output module \"%s\" registered.", name); - - return; - -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered in OutputRegisterModule. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a packet output module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterPacketModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), - PacketLogger PacketLogFunc, PacketLogCondition PacketConditionFunc) -{ - if (unlikely(PacketLogFunc == NULL || PacketConditionFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->InitFunc = InitFunc; - module->PacketLogFunc = PacketLogFunc; - module->PacketConditionFunc = PacketConditionFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Packet logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a packet output sub-module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterPacketSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *parent_ctx), - PacketLogger PacketLogFunc, PacketLogCondition PacketConditionFunc) -{ - if (unlikely(PacketLogFunc == NULL || PacketConditionFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->parent_name = parent_name; - module->InitSubFunc = InitFunc; - module->PacketLogFunc = PacketLogFunc; - module->PacketConditionFunc = PacketConditionFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Packet logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a tx output module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterTxModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), AppProto alproto, - TxLogger TxLogFunc) -{ - if (unlikely(TxLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->InitFunc = InitFunc; - module->TxLogFunc = TxLogFunc; - module->alproto = alproto; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Tx logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -void -OutputRegisterTxSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *parent_ctx), - AppProto alproto, TxLogger TxLogFunc) -{ - if (unlikely(TxLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->parent_name = parent_name; - module->InitSubFunc = InitFunc; - module->TxLogFunc = TxLogFunc; - module->alproto = alproto; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Tx logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a file output module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterFileModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), FileLogger FileLogFunc) -{ - if (unlikely(FileLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->InitFunc = InitFunc; - module->FileLogFunc = FileLogFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("File logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a file output sub-module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterFileSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - FileLogger FileLogFunc) -{ - if (unlikely(FileLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->parent_name = parent_name; - module->InitSubFunc = InitFunc; - module->FileLogFunc = FileLogFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("File logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a file data output module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterFiledataModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), FiledataLogger FiledataLogFunc) -{ - if (unlikely(FiledataLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->InitFunc = InitFunc; - module->FiledataLogFunc = FiledataLogFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Filedata logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a file data output sub-module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterFiledataSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - FiledataLogger FiledataLogFunc) -{ - if (unlikely(FiledataLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->parent_name = parent_name; - module->InitSubFunc = InitFunc; - module->FiledataLogFunc = FiledataLogFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Filedata logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a flow output module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterFlowModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), FlowLogger FlowLogFunc) -{ - if (unlikely(FlowLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->InitFunc = InitFunc; - module->FlowLogFunc = FlowLogFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Flow logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a flow output sub-module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterFlowSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - FlowLogger FlowLogFunc) -{ - if (unlikely(FlowLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->parent_name = parent_name; - module->InitSubFunc = InitFunc; - module->FlowLogFunc = FlowLogFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Flow logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a streaming data output module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterStreamingModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), StreamingLogger StreamingLogFunc, - enum OutputStreamingType stream_type) -{ - if (unlikely(StreamingLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->InitFunc = InitFunc; - module->StreamingLogFunc = StreamingLogFunc; - module->stream_type = stream_type; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Streaming logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a streaming data output sub-module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterStreamingSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - StreamingLogger StreamingLogFunc, enum OutputStreamingType stream_type) -{ - if (unlikely(StreamingLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->parent_name = parent_name; - module->InitSubFunc = InitFunc; - module->StreamingLogFunc = StreamingLogFunc; - module->stream_type = stream_type; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Streaming logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a stats data output module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterStatsModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), StatsLogger StatsLogFunc) -{ - if (unlikely(StatsLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->InitFunc = InitFunc; - module->StatsLogFunc = StatsLogFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Stats logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Register a stats data output sub-module. - * - * This function will register an output module so it can be - * configured with the configuration file. - * - * \retval Returns 0 on success, -1 on failure. - */ -void -OutputRegisterStatsSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - StatsLogger StatsLogFunc) -{ - if (unlikely(StatsLogFunc == NULL)) { - goto error; - } - - OutputModule *module = SCCalloc(1, sizeof(*module)); - if (unlikely(module == NULL)) { - goto error; - } - - module->name = name; - module->conf_name = conf_name; - module->parent_name = parent_name; - module->InitSubFunc = InitFunc; - module->StatsLogFunc = StatsLogFunc; - TAILQ_INSERT_TAIL(&output_modules, module, entries); - - SCLogDebug("Stats logger \"%s\" registered.", name); - return; -error: - SCLogError(SC_ERR_FATAL, "Fatal error encountered. Exiting..."); - exit(EXIT_FAILURE); -} - -/** - * \brief Get an output module by name. - * - * \retval The OutputModule with the given name or NULL if no output module - * with the given name is registered. - */ -OutputModule * -OutputGetModuleByConfName(const char *conf_name) -{ - OutputModule *module; - - TAILQ_FOREACH(module, &output_modules, entries) { - if (strcmp(module->conf_name, conf_name) == 0) - return module; - } - - return NULL; -} - -/** - * \brief Deregister all modules. Useful for a memory clean exit. - */ -void -OutputDeregisterAll(void) -{ - OutputModule *module; - - while ((module = TAILQ_FIRST(&output_modules))) { - TAILQ_REMOVE(&output_modules, module, entries); - SCFree(module); - } -} - -static int drop_loggers = 0; - -int OutputDropLoggerEnable(void) -{ - if (drop_loggers) - return -1; - drop_loggers++; - return 0; -} - -void OutputDropLoggerDisable(void) -{ - if (drop_loggers) - drop_loggers--; -} - -static int tls_loggers = 0; - -int OutputTlsLoggerEnable(void) -{ - if (tls_loggers) - return -1; - tls_loggers++; - return 0; -} - -void OutputTlsLoggerDisable(void) -{ - if (tls_loggers) - tls_loggers--; -} - -static int ssh_loggers = 0; - -int OutputSshLoggerEnable(void) -{ - if (ssh_loggers) - return -1; - ssh_loggers++; - return 0; -} - -void OutputSshLoggerDisable(void) -{ - if (ssh_loggers) - ssh_loggers--; -} - -/** - * \brief Register a flag for file rotation notification. - * - * \param flag A pointer that will be set to 1 when file rotation is - * requested. - */ -void OutputRegisterFileRotationFlag(int *flag) -{ - OutputFileRolloverFlag *flag_entry = SCCalloc(1, sizeof(*flag_entry)); - if (unlikely(flag_entry == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, - "Failed to allocate memory to register file rotation flag"); - return; - } - flag_entry->flag = flag; - TAILQ_INSERT_TAIL(&output_file_rotation_flags, flag_entry, entries); -} - -/** - * \brief Unregister a file rotation flag. - * - * Note that it is safe to call this function with a flag that may not - * have been registered, in which case this function won't do - * anything. - * - * \param flag A pointer that has been previously registered for file - * rotation notifications. - */ -void OutputUnregisterFileRotationFlag(int *flag) -{ - OutputFileRolloverFlag *entry, *next; - for (entry = TAILQ_FIRST(&output_file_rotation_flags); entry != NULL; - entry = next) { - next = TAILQ_NEXT(entry, entries); - if (entry->flag == flag) { - TAILQ_REMOVE(&output_file_rotation_flags, entry, entries); - SCFree(entry); - break; - } - } -} - -/** - * \brief Notifies all registered file rotation notification flags. - */ -void OutputNotifyFileRotation(void) { - OutputFileRolloverFlag *flag; - TAILQ_FOREACH(flag, &output_file_rotation_flags, entries) { - *(flag->flag) = 1; - } -} diff --git a/framework/src/suricata/src/output.h b/framework/src/suricata/src/output.h deleted file mode 100644 index 9a4add0e..00000000 --- a/framework/src/suricata/src/output.h +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited, Jason Ish - */ - -#ifndef __OUTPUT_H__ -#define __OUTPUT_H__ - -#include "suricata.h" -#include "tm-threads.h" - -#define DEFAULT_LOG_MODE_APPEND "yes" -#define DEFAULT_LOG_FILETYPE "regular" - -#include "output-packet.h" -#include "output-tx.h" -#include "output-file.h" -#include "output-filedata.h" -#include "output-flow.h" -#include "output-streaming.h" -#include "output-stats.h" - -typedef struct OutputModule_ { - const char *name; - const char *conf_name; - const char *parent_name; - OutputCtx *(*InitFunc)(ConfNode *); - OutputCtx *(*InitSubFunc)(ConfNode *, OutputCtx *parent_ctx); - - PacketLogger PacketLogFunc; - PacketLogCondition PacketConditionFunc; - TxLogger TxLogFunc; - FileLogger FileLogFunc; - FiledataLogger FiledataLogFunc; - FlowLogger FlowLogFunc; - StreamingLogger StreamingLogFunc; - StatsLogger StatsLogFunc; - AppProto alproto; - enum OutputStreamingType stream_type; - - TAILQ_ENTRY(OutputModule_) entries; -} OutputModule; - -void OutputRegisterModule(const char *, const char *, OutputCtx *(*)(ConfNode *)); - -void OutputRegisterPacketModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), - PacketLogger LogFunc, PacketLogCondition ConditionFunc); -void OutputRegisterPacketSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - PacketLogger LogFunc, PacketLogCondition ConditionFunc); - -void OutputRegisterTxModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), AppProto alproto, - TxLogger TxLogFunc); -void OutputRegisterTxSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *parent_ctx), - AppProto alproto, TxLogger TxLogFunc); - -void OutputRegisterFileModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), FileLogger FileLogFunc); -void OutputRegisterFileSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - FileLogger FileLogFunc); - -void OutputRegisterFiledataModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), FiledataLogger FiledataLogFunc); -void OutputRegisterFiledataSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - FiledataLogger FiledataLogFunc); - -void OutputRegisterFlowModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), FlowLogger FlowLogFunc); -void OutputRegisterFlowSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - FlowLogger FlowLogFunc); - -void OutputRegisterStreamingModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), StreamingLogger StreamingLogFunc, - enum OutputStreamingType stream_type); -void OutputRegisterStreamingSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - StreamingLogger StreamingLogFunc, enum OutputStreamingType stream_type); - -void OutputRegisterStatsModule(const char *name, const char *conf_name, - OutputCtx *(*InitFunc)(ConfNode *), StatsLogger StatsLogFunc); -void OutputRegisterStatsSubModule(const char *parent_name, const char *name, - const char *conf_name, OutputCtx *(*InitFunc)(ConfNode *, OutputCtx *), - StatsLogger StatsLogFunc); - -OutputModule *OutputGetModuleByConfName(const char *name); -void OutputDeregisterAll(void); - -int OutputDropLoggerEnable(void); -void OutputDropLoggerDisable(void); - -int OutputTlsLoggerEnable(void); -void OutputTlsLoggerDisable(void); - -int OutputSshLoggerEnable(void); -void OutputSshLoggerDisable(void); - -void OutputRegisterFileRotationFlag(int *flag); -void OutputUnregisterFileRotationFlag(int *flag); -void OutputNotifyFileRotation(void); - -#endif /* ! __OUTPUT_H__ */ diff --git a/framework/src/suricata/src/packet-queue.c b/framework/src/suricata/src/packet-queue.c deleted file mode 100644 index c500971b..00000000 --- a/framework/src/suricata/src/packet-queue.c +++ /dev/null @@ -1,198 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Packet Queue portion of the engine. - */ - -#include "suricata-common.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "suricata.h" -#include "util-var.h" -#include "pkt-var.h" - -#ifdef DEBUG -void PacketQueueValidateDebug(PacketQueue *q) -{ - SCLogDebug("q->len %u, q->top %p, q->bot %p", q->len, q->top, q->bot); - - if (q->len == 0) { - BUG_ON(q->top != NULL); - BUG_ON(q->bot != NULL); - } else if(q->len == 1) { - SCLogDebug("q->top->next %p, q->top->prev %p", q->top->next, q->top->prev); - SCLogDebug("q->bot->next %p, q->bot->prev %p", q->bot->next, q->bot->prev); - - BUG_ON(q->top != q->bot); - BUG_ON(q->top->next != NULL); - BUG_ON(q->bot->next != NULL); - BUG_ON(q->top->prev != NULL); - BUG_ON(q->bot->prev != NULL); - } else if (q->len == 2) { - SCLogDebug("q->top->next %p, q->top->prev %p", q->top->next, q->top->prev); - SCLogDebug("q->bot->next %p, q->bot->prev %p", q->bot->next, q->bot->prev); - - BUG_ON(q->top == NULL); - BUG_ON(q->bot == NULL); - - BUG_ON(q->top == q->bot); - - BUG_ON(q->top->prev != NULL); - BUG_ON(q->top->next != q->bot); - - BUG_ON(q->bot->prev != q->top); - BUG_ON(q->bot->next != NULL); - } else { - BUG_ON(q->top == NULL); - BUG_ON(q->bot == NULL); - - SCLogDebug("q->top->next %p, q->top->prev %p", q->top->next, q->top->prev); - SCLogDebug("q->bot->next %p, q->bot->prev %p", q->bot->next, q->bot->prev); - - BUG_ON(q->top == q->bot); - BUG_ON(q->top->prev != NULL); - BUG_ON(q->bot->next != NULL); - - BUG_ON(q->top->next == q->bot); - BUG_ON(q->bot->prev == q->top); - - Packet *p, *pp; - for (p = q->top, pp = p->prev; p != NULL; pp = p, p = p->next) { - SCLogDebug("p %p, pp %p, p->next %p, p->prev %p", p, pp, p->next, p->prev); - BUG_ON(pp != p->prev); - } - - } -} - -#define BUGGER_ON(cond) { \ - if ((cond)) { \ - PacketQueueValidateDebug(q); \ - } \ -} - -void PacketQueueValidate(PacketQueue *q) -{ - if (q->len == 0) { - BUGGER_ON(q->top != NULL); - BUGGER_ON(q->bot != NULL); - } else if(q->len == 1) { - BUGGER_ON(q->top != q->bot); - BUGGER_ON(q->top->next != NULL); - BUGGER_ON(q->bot->next != NULL); - BUGGER_ON(q->top->prev != NULL); - BUGGER_ON(q->bot->prev != NULL); - } else if (q->len == 2) { - BUGGER_ON(q->top == NULL); - BUGGER_ON(q->bot == NULL); - - BUGGER_ON(q->top == q->bot); - - BUGGER_ON(q->top->prev != NULL); - BUGGER_ON(q->top->next != q->bot); - - BUGGER_ON(q->bot->prev != q->top); - BUGGER_ON(q->bot->next != NULL); - } else { - BUGGER_ON(q->top == NULL); - BUGGER_ON(q->bot == NULL); - - BUGGER_ON(q->top == q->bot); - BUGGER_ON(q->top->prev != NULL); - BUGGER_ON(q->bot->next != NULL); - - BUGGER_ON(q->top->next == q->bot); - BUGGER_ON(q->bot->prev == q->top); - - Packet *p, *pp; - for (p = q->top, pp = p->prev; p != NULL; pp = p, p = p->next) { - BUGGER_ON(pp != p->prev); - } - - } -} -#endif /* DEBUG */ - -void PacketEnqueue (PacketQueue *q, Packet *p) -{ - //PacketQueueValidateDebug(q); - - if (p == NULL) - return; - - /* more packets in queue */ - if (q->top != NULL) { - p->prev = NULL; - p->next = q->top; - q->top->prev = p; - q->top = p; - /* only packet */ - } else { - p->prev = NULL; - p->next = NULL; - q->top = p; - q->bot = p; - } - q->len++; -#ifdef DBG_PERF - if (q->len > q->dbg_maxlen) - q->dbg_maxlen = q->len; -#endif /* DBG_PERF */ - //PacketQueueValidateDebug(q); -} - -Packet *PacketDequeue (PacketQueue *q) -{ - Packet *p = NULL; - - //PacketQueueValidateDebug(q); - /* if the queue is empty there are no packets left. */ - if (q->len == 0) { - return NULL; - } - - q->len--; - - /* pull the bottom packet from the queue */ - p = q->bot; - /* Weird issue: sometimes it looks that two thread arrive - * here at the same time so the bot ptr is NULL (only on OS X?) - */ - if (p == NULL) { - return NULL; - } - - /* more packets in queue */ - if (q->bot->prev != NULL) { - q->bot = q->bot->prev; - q->bot->next = NULL; - /* just the one we remove, so now empty */ - } else { - q->top = NULL; - q->bot = NULL; - } - - //PacketQueueValidateDebug(q); - return p; -} - diff --git a/framework/src/suricata/src/packet-queue.h b/framework/src/suricata/src/packet-queue.h deleted file mode 100644 index b93a942b..00000000 --- a/framework/src/suricata/src/packet-queue.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __PACKET_QUEUE_H__ -#define __PACKET_QUEUE_H__ - -#include "threads.h" -#include "decode.h" - -void PacketEnqueue (PacketQueue *, Packet *); -Packet *PacketDequeue (PacketQueue *); - -#endif /* __PACKET_QUEUE_H__ */ - diff --git a/framework/src/suricata/src/pkt-var.c b/framework/src/suricata/src/pkt-var.c deleted file mode 100644 index b3878bde..00000000 --- a/framework/src/suricata/src/pkt-var.c +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implements per packet vars - * - * \todo move away from a linked list implementation - * \todo use different datatypes, such as string, int, etc. - * \todo have more than one instance of the same var, and be able to match on a - * specific one, or one all at a time. So if a certain capture matches - * multiple times, we can operate on all of them. - */ - -#include "suricata-common.h" -#include "decode.h" -#include "pkt-var.h" -#include "util-debug.h" - -/* puts a new value into a pktvar */ -void PktVarUpdate(PktVar *pv, uint8_t *value, uint16_t size) -{ - if (pv->value) SCFree(pv->value); - pv->value = value; - pv->value_len = size; -} - -/* get the pktvar with name 'name' from the pkt - * - * name is a normal string*/ -PktVar *PktVarGet(Packet *p, char *name) -{ - PktVar *pv = p->pktvar; - - for (;pv != NULL; pv = pv->next) { - if (pv->name && strcmp(pv->name, name) == 0) - return pv; - } - - return NULL; -} - -/* add a pktvar to the pkt, or update it */ -void PktVarAdd(Packet *p, char *name, uint8_t *value, uint16_t size) -{ - //printf("Adding packet var \"%s\" with value(%" PRId32 ") \"%s\"\n", name, size, value); - - PktVar *pv = PktVarGet(p, name); - if (pv == NULL) { - pv = SCMalloc(sizeof(PktVar)); - if (unlikely(pv == NULL)) - return; - - pv->name = name; - pv->value = value; - pv->value_len = size; - pv->next = NULL; - - PktVar *tpv = p->pktvar; - if (p->pktvar == NULL) p->pktvar = pv; - else { - while(tpv) { - if (tpv->next == NULL) { - tpv->next = pv; - return; - } - tpv = tpv->next; - } - } - } else { - PktVarUpdate(pv, value, size); - } -} - -void PktVarFree(PktVar *pv) -{ - if (pv == NULL) - return; - - pv->name = NULL; - if (pv->value != NULL) - SCFree(pv->value); - PktVar *pv_next = pv->next; - - SCFree(pv); - - if (pv_next != NULL) - PktVarFree(pv_next); -} - -void PktVarPrint(PktVar *pv) -{ - uint16_t i; - - if (pv == NULL) - return; - - printf("Name \"%s\", Value \"", pv->name); - for (i = 0; i < pv->value_len; i++) { - if (isprint(pv->value[i])) printf("%c", pv->value[i]); - else printf("\\%02X", pv->value[i]); - } - printf("\", Len \"%" PRIu32 "\"\n", pv->value_len); - - PktVarPrint(pv->next); -} - diff --git a/framework/src/suricata/src/pkt-var.h b/framework/src/suricata/src/pkt-var.h deleted file mode 100644 index 0ba87572..00000000 --- a/framework/src/suricata/src/pkt-var.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __PKT_VAR_H__ -#define __PKT_VAR_H__ - -void PktVarAdd(Packet *, char *, uint8_t *, uint16_t); -PktVar *PktVarGet(Packet *, char *); -void PktVarFree(PktVar *); -void PktVarPrint(PktVar *); - -#endif /* __PKT_VAR_H__ */ - diff --git a/framework/src/suricata/src/ptxdump.py b/framework/src/suricata/src/ptxdump.py deleted file mode 100644 index 097e5173..00000000 --- a/framework/src/suricata/src/ptxdump.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python -from string import * -import os, getopt, sys, platform - -header = '''/* Auto-generated by ptxdump.py DO NOT EDIT -* -* This file contains the ptx code of the Cuda kernels. -* A kernel is identified by its name and the compute capability (e.g. _sm_10). -*/ -''' - -def FormatCharHex(d): - s = hex(ord(d)) - if len(s) == 3: - s = "0x0" + s[2] - return s - -def CleanFileName(f): - v = f.replace("-","_") - v = v.replace(".ptx","") - return v - -if not(len(sys.argv[1:]) >= 2): - print("Usage: ptx2c.py ") - print("Description: creates a header file containing the ptx files as character array" + os.linesep) - sys.exit(0) - -out_h = sys.argv[1] + ".h" -out = open(out_h, 'w') - -out.writelines(header) -out.writelines("#ifdef __SC_CUDA_SUPPORT__\n") -out.writelines("#ifndef __ptxdump_h__\n") -out.writelines("#define __ptxdump_h__\n\n") - -# write char arrays -for file in sys.argv[2:]: - in_ptx = open(file, 'r') - source = in_ptx.read() - source_len = len(source) - - varname = CleanFileName(file) - - out.writelines("const unsigned char " + varname + "[" + str(source_len+1) + "] = {\n") - newlinecnt = 0 - for i in range(0, source_len): - out.write(FormatCharHex(source[i]) + ", ") - newlinecnt += 1 - if newlinecnt == 16: - newlinecnt = 0 - out.write("\n") - out.write("0x00\n};\n\n") - - print(sys.argv[0] + ": CUmodule " + varname + " packed successfully") - -# write retrieval function -out.writelines("const unsigned char* SCCudaPtxDumpGetModule(const char* module){\n"); -for file in sys.argv[2:]: - out.writelines('\tif (!strcmp(module, "' + file.replace(".ptx","")+'"))\n') - out.writelines("\t\treturn " + CleanFileName(file)+";\n") -out.writelines('\tSCLogError(SC_ERR_FATAL, "Error in SCCudaPtxDumpGetModule, module %s not found. Exiting...",module);\n') -out.writelines("\texit(EXIT_FAILURE);\n") -out.writelines("};\n") - -out.writelines("#endif /* __ptxdump_h__ */\n") -out.writelines("#endif /* __SC_CUDA_SUPPORT__ */\n") - -print(sys.argv[0] + ": " + out_h + " written successfully") - -in_ptx.close() -out.close() diff --git a/framework/src/suricata/src/queue.h b/framework/src/suricata/src/queue.h deleted file mode 100644 index 13455aa4..00000000 --- a/framework/src/suricata/src/queue.h +++ /dev/null @@ -1,543 +0,0 @@ -/* $OpenBSD: queue.h,v 1.32 2007/04/30 18:42:34 pedro Exp $ */ -/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ - -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * This file defines five types of data structures: singly-linked lists, - * lists, simple queues, tail queues, and circular queues. - * - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) -#define _Q_INVALIDATE(a) ((a) = ((void *)-1)) -#else -#define _Q_INVALIDATE(a) -#endif - -/* - * Singly-linked List definitions. - */ - -/* - * The following macros are not used and are in conflict with Win32 API - */ - -#if 0 - -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List access methods. - */ -#define SLIST_FIRST(head) ((head)->slh_first) -#define SLIST_END(head) NULL -#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_FOREACH(var, head, field) \ - for((var) = SLIST_FIRST(head); \ - (var) != SLIST_END(head); \ - (var) = SLIST_NEXT(var, field)) - -#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ - for ((varp) = &SLIST_FIRST((head)); \ - ((var) = *(varp)) != SLIST_END(head); \ - (varp) = &SLIST_NEXT((var), field)) - -/* - * Singly-linked List functions. - */ -#define SLIST_INIT(head) { \ - SLIST_FIRST(head) = SLIST_END(head); \ -} - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (0) - -#define SLIST_REMOVE_NEXT(head, elm, field) do { \ - (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if ((head)->slh_first == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } else { \ - struct type *curelm = (head)->slh_first; \ - \ - while (curelm->field.sle_next != (elm)) \ - curelm = curelm->field.sle_next; \ - curelm->field.sle_next = \ - curelm->field.sle_next->field.sle_next; \ - _Q_INVALIDATE((elm)->field.sle_next); \ - } \ -} while (0) - -#endif /* 0 */ - -/* - * List definitions. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List access methods - */ -#define LIST_FIRST(head) ((head)->lh_first) -#define LIST_END(head) NULL -#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_FOREACH(var, head, field) \ - for((var) = LIST_FIRST(head); \ - (var)!= LIST_END(head); \ - (var) = LIST_NEXT(var, field)) - -/* - * List functions. - */ -#define LIST_INIT(head) do { \ - LIST_FIRST(head) = LIST_END(head); \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (0) - -#define LIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ - _Q_INVALIDATE((elm)->field.le_prev); \ - _Q_INVALIDATE((elm)->field.le_next); \ -} while (0) - -#define LIST_REPLACE(elm, elm2, field) do { \ - if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ - (elm2)->field.le_next->field.le_prev = \ - &(elm2)->field.le_next; \ - (elm2)->field.le_prev = (elm)->field.le_prev; \ - *(elm2)->field.le_prev = (elm2); \ - _Q_INVALIDATE((elm)->field.le_prev); \ - _Q_INVALIDATE((elm)->field.le_next); \ -} while (0) - -/* - * Simple queue definitions. - */ -#define SIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define SIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define SIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue access methods. - */ -#define SIMPLEQ_FIRST(head) ((head)->sqh_first) -#define SIMPLEQ_END(head) NULL -#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) -#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - -#define SIMPLEQ_FOREACH(var, head, field) \ - for((var) = SIMPLEQ_FIRST(head); \ - (var) != SIMPLEQ_END(head); \ - (var) = SIMPLEQ_NEXT(var, field)) - -/* - * Simple queue functions. - */ -#define SIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (0) - -#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (0) - -#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (0) - -#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ - if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -/* - * Tail queue definitions. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * tail queue access methods - */ -#define TAILQ_FIRST(head) ((head)->tqh_first) -#define TAILQ_END(head) NULL -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -/* XXX */ -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) -#define TAILQ_EMPTY(head) \ - (TAILQ_FIRST(head) == TAILQ_END(head)) - -#define TAILQ_FOREACH(var, head, field) \ - for((var) = TAILQ_FIRST(head); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_NEXT(var, field)) - -/* removal safe iterator using a temprary element has last param */ -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for((var) = TAILQ_FIRST(head), \ - (tvar) = TAILQ_FIRST(head) ? TAILQ_NEXT(TAILQ_FIRST(head), field): NULL ; \ - (var) != TAILQ_END(head); \ - (var = tvar), (tvar) = var ? TAILQ_NEXT(var, field): NULL) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for((var) = TAILQ_LAST(head, headname); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_PREV(var, headname, field)) - -/* - * Tail queue functions. - */ -#define TAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ - _Q_INVALIDATE((elm)->field.tqe_prev); \ - _Q_INVALIDATE((elm)->field.tqe_next); \ -} while (0) - -#define TAILQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ - (elm2)->field.tqe_next->field.tqe_prev = \ - &(elm2)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm2)->field.tqe_next; \ - (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ - *(elm2)->field.tqe_prev = (elm2); \ - _Q_INVALIDATE((elm)->field.tqe_prev); \ - _Q_INVALIDATE((elm)->field.tqe_next); \ -} while (0) - -/* - * Circular queue definitions. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_HEAD_INITIALIZER(head) \ - { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue access methods - */ -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) -#define CIRCLEQ_LAST(head) ((head)->cqh_last) -#define CIRCLEQ_END(head) ((void *)(head)) -#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) -#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) -#define CIRCLEQ_EMPTY(head) \ - (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for((var) = CIRCLEQ_FIRST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_NEXT(var, field)) - -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for((var) = CIRCLEQ_LAST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_PREV(var, field)) - -/* - * Circular queue functions. - */ -#define CIRCLEQ_INIT(head) do { \ - (head)->cqh_first = CIRCLEQ_END(head); \ - (head)->cqh_last = CIRCLEQ_END(head); \ -} while (0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = CIRCLEQ_END(head); \ - if ((head)->cqh_last == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.cqe_next = CIRCLEQ_END(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} while (0) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ - _Q_INVALIDATE((elm)->field.cqe_prev); \ - _Q_INVALIDATE((elm)->field.cqe_next); \ -} while (0) - -#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ - CIRCLEQ_END(head)) \ - (head).cqh_last = (elm2); \ - else \ - (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ - if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ - CIRCLEQ_END(head)) \ - (head).cqh_first = (elm2); \ - else \ - (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ - _Q_INVALIDATE((elm)->field.cqe_prev); \ - _Q_INVALIDATE((elm)->field.cqe_next); \ -} while (0) - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/framework/src/suricata/src/reputation.c b/framework/src/suricata/src/reputation.c deleted file mode 100644 index d1aef713..00000000 --- a/framework/src/suricata/src/reputation.c +++ /dev/null @@ -1,2354 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * \author Victor Julien - * Original Idea by Matt Jonkman - * - * IP Reputation Module, initial API for IPV4 and IPV6 feed - */ - -#include "util-error.h" -#include "util-debug.h" -#include "util-ip.h" -#include "util-radix-tree.h" -#include "util-unittest.h" -#include "suricata-common.h" -#include "threads.h" -#include "util-print.h" -#include "host.h" -#include "conf.h" -#include "detect.h" -#include "reputation.h" - -/** effective reputation version, atomic as the host - * time out code will use it to check if a host's - * reputation info is outdated. */ -SC_ATOMIC_DECLARE(uint32_t, srep_eversion); -/** reputation version set to the host's reputation, - * this will be set to 1 before rep files are loaded, - * so hosts will always have a minial value of 1 */ -static uint32_t srep_version = 0; - -static uint32_t SRepIncrVersion(void) -{ - return ++srep_version; -} - -static uint32_t SRepGetVersion(void) -{ - return srep_version; -} - -void SRepResetVersion(void) -{ - srep_version = 0; -} - -static uint32_t SRepGetEffectiveVersion(void) -{ - return SC_ATOMIC_GET(srep_eversion); -} - -static void SRepCIDRFreeUserData(void *data) -{ - if (data != NULL) - SCFree(data); - - return; -} - -static void SRepCIDRAddNetblock(SRepCIDRTree *cidr_ctx, char *ip, int cat, int value) -{ - SReputation *user_data = NULL; - if ((user_data = SCMalloc(sizeof(SReputation))) == NULL) { - SCLogError(SC_ERR_FATAL, "Error allocating memory. Exiting"); - exit(EXIT_FAILURE); - } - memset(user_data, 0x00, sizeof(SReputation)); - - user_data->version = SRepGetVersion(); - user_data->rep[cat] = value; - - if (strchr(ip, ':') != NULL) { - if (cidr_ctx->srepIPV6_tree[cat] == NULL) { - cidr_ctx->srepIPV6_tree[cat] = SCRadixCreateRadixTree(SRepCIDRFreeUserData, NULL); - if (cidr_ctx->srepIPV6_tree[cat] == NULL) { - SCLogDebug("Error initializing Reputation IPV6 with CIDR module for cat %d", cat); - exit(EXIT_FAILURE); - } - SCLogDebug("Reputation IPV6 with CIDR module for cat %d initialized", cat); - } - - SCLogDebug("adding ipv6 host %s", ip); - if (SCRadixAddKeyIPV6String(ip, cidr_ctx->srepIPV6_tree[cat], (void *)user_data) == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, - "failed to add ipv6 host %s", ip); - } - - } else { - if (cidr_ctx->srepIPV4_tree[cat] == NULL) { - cidr_ctx->srepIPV4_tree[cat] = SCRadixCreateRadixTree(SRepCIDRFreeUserData, NULL); - if (cidr_ctx->srepIPV4_tree[cat] == NULL) { - SCLogDebug("Error initializing Reputation IPV4 with CIDR module for cat %d", cat); - exit(EXIT_FAILURE); - } - SCLogDebug("Reputation IPV4 with CIDR module for cat %d initialized", cat); - } - - SCLogDebug("adding ipv4 host %s", ip); - if (SCRadixAddKeyIPV4String(ip, cidr_ctx->srepIPV4_tree[cat], (void *)user_data) == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, - "failed to add ipv4 host %s", ip); - } - } -} - -static uint8_t SRepCIDRGetIPv4IPRep(SRepCIDRTree *cidr_ctx, uint8_t *ipv4_addr, uint8_t cat) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, cidr_ctx->srepIPV4_tree[cat], &user_data); - if (user_data == NULL) - return 0; - - SReputation *r = (SReputation *)user_data; - return r->rep[cat]; -} - -static uint8_t SRepCIDRGetIPv6IPRep(SRepCIDRTree *cidr_ctx, uint8_t *ipv6_addr, uint8_t cat) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, cidr_ctx->srepIPV6_tree[cat], &user_data); - if (user_data == NULL) - return 0; - - SReputation *r = (SReputation *)user_data; - return r->rep[cat]; -} - -uint8_t SRepCIDRGetIPRepSrc(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version) -{ - uint8_t rep = 0; - - if (PKT_IS_IPV4(p)) - rep = SRepCIDRGetIPv4IPRep(cidr_ctx, (uint8_t *)GET_IPV4_SRC_ADDR_PTR(p), cat); - else if (PKT_IS_IPV6(p)) - rep = SRepCIDRGetIPv6IPRep(cidr_ctx, (uint8_t *)GET_IPV6_SRC_ADDR(p), cat); - - return rep; -} - -uint8_t SRepCIDRGetIPRepDst(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version) -{ - uint8_t rep = 0; - - if (PKT_IS_IPV4(p)) - rep = SRepCIDRGetIPv4IPRep(cidr_ctx, (uint8_t *)GET_IPV4_DST_ADDR_PTR(p), cat); - else if (PKT_IS_IPV6(p)) - rep = SRepCIDRGetIPv6IPRep(cidr_ctx, (uint8_t *)GET_IPV6_DST_ADDR(p), cat); - - return rep; -} - -/** \brief Increment effective reputation version after - * a rule/reputatio reload is complete. */ -void SRepReloadComplete(void) -{ - (void) SC_ATOMIC_ADD(srep_eversion, 1); - SCLogDebug("effective Reputation version %u", SRepGetEffectiveVersion()); -} - -/** \brief Set effective reputation version after - * reputation initialization is complete. */ -void SRepInitComplete(void) -{ - (void) SC_ATOMIC_SET(srep_eversion, 1); - SCLogDebug("effective Reputation version %u", SRepGetEffectiveVersion()); -} - -/** \brief Check if a Host is timed out wrt ip rep, meaning a new - * version is in place. - * - * We clean up the old version here. - * - * \param h host - * - * \retval 0 not timed out - * \retval 1 timed out - */ -int SRepHostTimedOut(Host *h) -{ - BUG_ON(h == NULL); - - if (h->iprep == NULL) - return 1; - - uint32_t eversion = SRepGetEffectiveVersion(); - SReputation *r = h->iprep; - if (r->version < eversion) { - SCLogDebug("host %p has reputation version %u, " - "effective version is %u", h, r->version, eversion); - - SCFree(h->iprep); - h->iprep = NULL; - - HostDecrUsecnt(h); - return 1; - } - - return 0; -} - -static int SRepCatSplitLine(char *line, uint8_t *cat, char *shortname, size_t shortname_len) -{ - size_t line_len = strlen(line); - char *ptrs[2] = {NULL,NULL}; - int i = 0; - int idx = 0; - char *origline = line; - - while (i < (int)line_len) { - if (line[i] == ',' || line[i] == '\n' || line[i] == '\0' || i == (int)(line_len - 1)) { - line[i] = '\0'; - - ptrs[idx] = line; - idx++; - - line += (i+1); - i = 0; - - if (line >= origline + line_len) - break; - if (strlen(line) == 0) - break; - if (idx == 2) - break; - } else { - i++; - } - } - - if (idx != 2) { - return -1; - } - - SCLogDebug("%s, %s", ptrs[0], ptrs[1]); - - int c = atoi(ptrs[0]); - if (c < 0 || c >= SREP_MAX_CATS) { - return -1; - } - - *cat = (uint8_t)c; - strlcpy(shortname, ptrs[1], shortname_len); - return 0; - -} - -/** - * \retval 0 valid - * \retval 1 header - * \retval -1 boo - */ -static int SRepSplitLine(SRepCIDRTree *cidr_ctx, char *line, Address *ip, uint8_t *cat, uint8_t *value) -{ - size_t line_len = strlen(line); - char *ptrs[3] = {NULL,NULL,NULL}; - int i = 0; - int idx = 0; - char *origline = line; - - while (i < (int)line_len) { - if (line[i] == ',' || line[i] == '\n' || line[i] == '\0' || i == (int)(line_len - 1)) { - line[i] = '\0'; - - ptrs[idx] = line; - idx++; - - line += (i+1); - i = 0; - - if (line >= origline + line_len) - break; - if (strlen(line) == 0) - break; - if (idx == 3) - break; - } else { - i++; - } - } - - if (idx != 3) { - return -1; - } - - //SCLogInfo("%s, %s, %s", ptrs[0], ptrs[1], ptrs[2]); - - if (strcmp(ptrs[0], "ip") == 0) - return 1; - - int c = atoi(ptrs[1]); - if (c < 0 || c >= SREP_MAX_CATS) { - return -1; - } - - int v = atoi(ptrs[2]); - if (v < 0 || v > 127) { - return -1; - } - - if (strchr(ptrs[0], '/') != NULL) { - SRepCIDRAddNetblock(cidr_ctx, ptrs[0], c, v); - return 1; - } else { - if (inet_pton(AF_INET, ptrs[0], &ip->address) == 1) { - ip->family = AF_INET; - } else if (inet_pton(AF_INET6, ptrs[0], &ip->address) == 1) { - ip->family = AF_INET6; - } else { - return -1; - } - - *cat = c; - *value = v; - } - - return 0; -} - -#define SREP_SHORTNAME_LEN 32 -static char srep_cat_table[SREP_MAX_CATS][SREP_SHORTNAME_LEN]; - -int SRepCatValid(uint8_t cat) -{ - if (cat >= SREP_MAX_CATS) - return 0; - - if (strlen(srep_cat_table[cat]) == 0) - return 0; - - return 1; -} - -uint8_t SRepCatGetByShortname(char *shortname) -{ - uint8_t cat; - for (cat = 0; cat < SREP_MAX_CATS; cat++) { - if (strcmp(srep_cat_table[cat], shortname) == 0) - return cat; - } - - return 0; -} - -static int SRepLoadCatFile(char *filename) -{ - int r = 0; - FILE *fp = fopen(filename, "r"); - - if (fp == NULL) { - SCLogError(SC_ERR_OPENING_RULE_FILE, "opening ip rep file %s: %s", filename, strerror(errno)); - return -1; - } - - r = SRepLoadCatFileFromFD(fp); - - fclose(fp); - fp = NULL; - return r; -} - -int SRepLoadCatFileFromFD(FILE *fp) -{ - char line[8192] = ""; - Address a; - memset(&a, 0x00, sizeof(a)); - a.family = AF_INET; - memset(&srep_cat_table, 0x00, sizeof(srep_cat_table)); - - BUG_ON(SRepGetVersion() > 0); - - while(fgets(line, (int)sizeof(line), fp) != NULL) { - size_t len = strlen(line); - if (len == 0) - continue; - - /* ignore comments and empty lines */ - if (line[0] == '\n' || line [0] == '\r' || line[0] == ' ' || line[0] == '#' || line[0] == '\t') - continue; - - while (isspace((unsigned char)line[--len])); - - /* Check if we have a trailing newline, and remove it */ - len = strlen(line); - if (len == 0) - continue; - - if (line[len - 1] == '\n' || line[len - 1] == '\r') { - line[len - 1] = '\0'; - } - - uint8_t cat = 0; - char shortname[SREP_SHORTNAME_LEN]; - if (SRepCatSplitLine(line, &cat, shortname, sizeof(shortname)) == 0) { - strlcpy(srep_cat_table[cat], shortname, SREP_SHORTNAME_LEN); - } else { - SCLogError(SC_ERR_NO_REPUTATION, "bad line \"%s\"", line); - } - } - - SCLogDebug("IP Rep categories:"); - int i; - for (i = 0; i < SREP_MAX_CATS; i++) { - if (strlen(srep_cat_table[i]) == 0) - continue; - SCLogDebug("CAT %d, name %s", i, srep_cat_table[i]); - } - return 0; -} - -static int SRepLoadFile(SRepCIDRTree *cidr_ctx, char *filename) -{ - int r = 0; - FILE *fp = fopen(filename, "r"); - - if (fp == NULL) { - SCLogError(SC_ERR_OPENING_RULE_FILE, "opening ip rep file %s: %s", filename, strerror(errno)); - return -1; - } - - r = SRepLoadFileFromFD(cidr_ctx, fp); - - fclose(fp); - fp = NULL; - return r; - -} - -int SRepLoadFileFromFD(SRepCIDRTree *cidr_ctx, FILE *fp) -{ - char line[8192] = ""; - Address a; - memset(&a, 0x00, sizeof(a)); - a.family = AF_INET; - - while(fgets(line, (int)sizeof(line), fp) != NULL) { - size_t len = strlen(line); - if (len == 0) - continue; - - /* ignore comments and empty lines */ - if (line[0] == '\n' || line [0] == '\r' || line[0] == ' ' || line[0] == '#' || line[0] == '\t') - continue; - - while (isspace((unsigned char)line[--len])); - - /* Check if we have a trailing newline, and remove it */ - len = strlen(line); - if (len == 0) - continue; - - if (line[len - 1] == '\n' || line[len - 1] == '\r') { - line[len - 1] = '\0'; - } - - uint8_t cat = 0, value = 0; - int r = SRepSplitLine(cidr_ctx, line, &a, &cat, &value); - if (r < 0) { - SCLogError(SC_ERR_NO_REPUTATION, "bad line \"%s\"", line); - } else if (r == 0) { - if (a.family == AF_INET) { - char ipstr[16]; - PrintInet(AF_INET, (const void *)&a.address, ipstr, sizeof(ipstr)); - SCLogDebug("%s %u %u", ipstr, cat, value); - } else { - char ipstr[128]; - PrintInet(AF_INET6, (const void *)&a.address, ipstr, sizeof(ipstr)); - SCLogDebug("%s %u %u", ipstr, cat, value); - } - - Host *h = HostGetHostFromHash(&a); - if (h == NULL) { - SCLogError(SC_ERR_NO_REPUTATION, "failed to get a host, increase host.memcap"); - break; - } else { - //SCLogInfo("host %p", h); - - if (h->iprep == NULL) { - h->iprep = SCMalloc(sizeof(SReputation)); - if (h->iprep != NULL) { - memset(h->iprep, 0x00, sizeof(SReputation)); - - HostIncrUsecnt(h); - } - } - if (h->iprep != NULL) { - SReputation *rep = h->iprep; - - /* if version is outdated, it's an older entry that we'll - * now replace. */ - if (rep->version != SRepGetVersion()) { - memset(rep, 0x00, sizeof(SReputation)); - } - - rep->version = SRepGetVersion(); - rep->rep[cat] = value; - - SCLogDebug("host %p iprep %p setting cat %u to value %u", - h, h->iprep, cat, value); -#ifdef DEBUG - if (SCLogDebugEnabled()) { - int i; - for (i = 0; i < SREP_MAX_CATS; i++) { - if (rep->rep[i] == 0) - continue; - - SCLogDebug("--> host %p iprep %p cat %d to value %u", - h, h->iprep, i, rep->rep[i]); - } - } -#endif - } - - HostRelease(h); - } - } - } - - return 0; -} - -/** - * \brief Create the path if default-rule-path was specified - * \param sig_file The name of the file - * \retval str Pointer to the string path + sig_file - */ -static char *SRepCompleteFilePath(char *file) -{ - char *defaultpath = NULL; - char *path = NULL; - - /* Path not specified */ - if (PathIsRelative(file)) { - if (ConfGet("default-reputation-path", &defaultpath) == 1) { - SCLogDebug("Default path: %s", defaultpath); - size_t path_len = sizeof(char) * (strlen(defaultpath) + - strlen(file) + 2); - path = SCMalloc(path_len); - if (unlikely(path == NULL)) - return NULL; - strlcpy(path, defaultpath, path_len); -#if defined OS_WIN32 || defined __CYGWIN__ - if (path[strlen(path) - 1] != '\\') - strlcat(path, "\\\\", path_len); -#else - if (path[strlen(path) - 1] != '/') - strlcat(path, "/", path_len); -#endif - strlcat(path, file, path_len); - } else { - path = SCStrdup(file); - if (unlikely(path == NULL)) - return NULL; - } - } else { - path = SCStrdup(file); - if (unlikely(path == NULL)) - return NULL; - } - return path; -} - -/** \brief init reputation - * - * \param de_ctx detection engine ctx for tracking iprep version - * - * \retval 0 ok - * \retval -1 error - * - * If this function is called more than once, the category file - * is not reloaded. - */ -int SRepInit(DetectEngineCtx *de_ctx) -{ - ConfNode *files; - ConfNode *file = NULL; - int r = 0; - char *sfile = NULL; - char *filename = NULL; - int init = 0; - int i = 0; - - de_ctx->srepCIDR_ctx = (SRepCIDRTree *)SCMalloc(sizeof(SRepCIDRTree)); - if (de_ctx->srepCIDR_ctx == NULL) - exit(EXIT_FAILURE); - memset(de_ctx->srepCIDR_ctx, 0, sizeof(SRepCIDRTree)); - SRepCIDRTree *cidr_ctx = de_ctx->srepCIDR_ctx; - - for (i = 0; i < SREP_MAX_CATS; i++) { - cidr_ctx->srepIPV4_tree[i] = NULL; - cidr_ctx->srepIPV6_tree[i] = NULL; - } - - if (SRepGetVersion() == 0) { - SC_ATOMIC_INIT(srep_eversion); - init = 1; - } - - /* if both settings are missing, we assume the user doesn't want ip rep */ - (void)ConfGet("reputation-categories-file", &filename); - files = ConfGetNode("reputation-files"); - if (filename == NULL && files == NULL) { - SCLogInfo("IP reputation disabled"); - return 0; - } - - if (files == NULL) { - SCLogError(SC_ERR_NO_REPUTATION, "\"reputation-files\" not set"); - return -1; - } - - if (init) { - if (filename == NULL) { - SCLogError(SC_ERR_NO_REPUTATION, "\"reputation-categories-file\" not set"); - return -1; - } - - /* init even if we have reputation files, so that when we - * have a live reload, we have inited the cats */ - if (SRepLoadCatFile(filename) < 0) { - SCLogError(SC_ERR_NO_REPUTATION, "failed to load reputation " - "categories file %s", filename); - return -1; - } - } - - de_ctx->srep_version = SRepIncrVersion(); - SCLogDebug("Reputation version %u", de_ctx->srep_version); - - /* ok, let's load signature files from the general config */ - if (files != NULL) { - TAILQ_FOREACH(file, &files->head, next) { - sfile = SRepCompleteFilePath(file->val); - SCLogInfo("Loading reputation file: %s", sfile); - - r = SRepLoadFile(cidr_ctx, sfile); - if (r < 0){ - if (de_ctx->failure_fatal == 1) { - exit(EXIT_FAILURE); - } - } - SCFree(sfile); - } - } - - /* Set effective rep version. - * On live reload we will handle this after de_ctx has been swapped */ - if (init) { - SRepInitComplete(); - } - - HostPrintStats(); - return 0; -} - -void SRepDestroy(DetectEngineCtx *de_ctx) { - if (de_ctx->srepCIDR_ctx != NULL) { - int i; - for (i = 0; i < SREP_MAX_CATS; i++) { - if (de_ctx->srepCIDR_ctx->srepIPV4_tree[i] != NULL) { - SCRadixReleaseRadixTree(de_ctx->srepCIDR_ctx->srepIPV4_tree[i]); - de_ctx->srepCIDR_ctx->srepIPV4_tree[i] = NULL; - } - - if (de_ctx->srepCIDR_ctx->srepIPV6_tree[i] != NULL) { - SCRadixReleaseRadixTree(de_ctx->srepCIDR_ctx->srepIPV6_tree[i]); - de_ctx->srepCIDR_ctx->srepIPV6_tree[i] = NULL; - } - } - - SCFree(de_ctx->srepCIDR_ctx); - de_ctx->srepCIDR_ctx = NULL; - } -} - -#ifdef UNITTESTS - -#include "conf-yaml-loader.h" -#include "detect-engine.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -static int SRepTest01(void) -{ - char str[] = "1.2.3.4,1,2"; - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - return 0; - } - - SRepInit(de_ctx); - Address a; - uint8_t cat = 0, value = 0; - if (SRepSplitLine(de_ctx->srepCIDR_ctx, str, &a, &cat, &value) != 0) { - goto end; - } - - char ipstr[16]; - PrintInet(AF_INET, (const void *)&a.address, ipstr, sizeof(ipstr)); - - if (strcmp(ipstr, "1.2.3.4") != 0) - goto end; - - if (cat != 1) - goto end; - - if (value != 2) - goto end; - - result = 1; - -end: - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SRepTest02(void) -{ - char str[] = "1.1.1.1,"; - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - return 0; - } - - SRepInit(de_ctx); - Address a; - uint8_t cat = 0, value = 0; - if (SRepSplitLine(de_ctx->srepCIDR_ctx, str, &a, &cat, &value) == 0) { - goto end; - } - result = 1; - -end: - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SRepTest03(void) -{ - char str[] = "1,Shortname,Long Name"; - - uint8_t cat = 0; - char shortname[SREP_SHORTNAME_LEN]; - - if (SRepCatSplitLine(str, &cat, shortname, sizeof(shortname)) != 0) { - printf("split failed: "); - return 0; - } - - if (strcmp(shortname, "Shortname") != 0) { - printf("%s != Shortname: ", shortname); - return 0; - } - - if (cat != 1) { - printf("cat 1 != %u: ", cat); - return 0; - } - - return 1; -} - -static int SRepTest04(void) -{ - int result = 0; - - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - SRepInit(de_ctx); - - char str[] = "10.0.0.0/16,1,2"; - - Address a; - uint8_t cat = 0, value = 0; - if (SRepSplitLine(de_ctx->srepCIDR_ctx, str, &a, &cat, &value) != 1) { - goto end; - } - - result = 1; - -end: - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SRepTest05(void) -{ - Packet *p = NULL; - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - if (p == NULL) { - return result; - } - - p->src.addr_data32[0] = UTHSetIPv4Address("10.0.0.1"); - - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - return result; - } - SRepInit(de_ctx); - - char str[] = "10.0.0.0/16,1,20"; - - Address a; - uint8_t cat = 0, value = 0; - if (SRepSplitLine(de_ctx->srepCIDR_ctx, str, &a, &cat, &value) != 1) { - goto end; - } - cat = 1; - value = SRepCIDRGetIPRepSrc(de_ctx->srepCIDR_ctx, p, cat, 0); - if (value != 20) { - goto end; - } - result = 1; - -end: - UTHFreePacket(p); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SRepTest06(void) -{ - Packet *p = NULL; - int result = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - - p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); - if (p == NULL) { - return result; - } - - p->src.addr_data32[0] = UTHSetIPv4Address("192.168.0.1"); - - DetectEngineCtx *de_ctx; - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - return result; - } - SRepInit(de_ctx); - - char str[] = - "0.0.0.0/0,1,10\n" - "192.168.0.0/16,2,127"; - - Address a; - uint8_t cat = 0, value = 0; - if (SRepSplitLine(de_ctx->srepCIDR_ctx, str, &a, &cat, &value) != 1) { - goto end; - } - cat = 1; - value = SRepCIDRGetIPRepSrc(de_ctx->srepCIDR_ctx, p, cat, 0); - if (value != 10) { - goto end; - } - result = 1; - -end: - UTHFreePacket(p); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int SRepTest07(void) { - char str[] = "2000:0000:0000:0000:0000:0000:0000:0001,"; - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - return 0; - } - - SRepInit(de_ctx); - Address a; - uint8_t cat = 0, value = 0; - if (SRepSplitLine(de_ctx->srepCIDR_ctx, str, &a, &cat, &value) == 0) { - goto end; - } - result = 1; -end: - DetectEngineCtxFree(de_ctx); - return result; -} -#endif - -/** Global trees that hold host reputation for IPV4 and IPV6 hosts */ -IPReputationCtx *rep_ctx; - -/** - * \brief Initialization fuction for the Reputation Context (IPV4 and IPV6) - * - * \retval Pointer to the IPReputationCtx created - * NULL Error initializing moule; - */ -IPReputationCtx *SCReputationInitCtx(void) -{ - rep_ctx = (IPReputationCtx *)SCMalloc(sizeof(IPReputationCtx)); - if (rep_ctx == NULL) - return NULL; - memset(rep_ctx,0,sizeof(IPReputationCtx)); - - rep_ctx->reputationIPV4_tree = SCRadixCreateRadixTree(SCReputationFreeData, NULL); - if (rep_ctx->reputationIPV4_tree == NULL) { - SCLogDebug("Error initializing Reputation IPV4 module"); - return NULL; - } - - SCLogDebug("Reputation IPV4 module initialized"); - - rep_ctx->reputationIPV6_tree = SCRadixCreateRadixTree(SCReputationFreeData, NULL); - if (rep_ctx->reputationIPV6_tree == NULL) { - SCLogDebug("Error initializing Reputation IPV6 module"); - return NULL; - } - - SCLogDebug("Reputation IPV6 module initialized"); - if (SCMutexInit(&rep_ctx->reputationIPV4_lock, NULL) != 0) { - SCLogError(SC_ERR_MUTEX, "Mutex not correctly initialized"); - exit(EXIT_FAILURE); - } - if (SCMutexInit(&rep_ctx->reputationIPV6_lock, NULL) != 0) { - SCLogError(SC_ERR_MUTEX, "Mutex not correctly initialized"); - exit(EXIT_FAILURE); - } - - return rep_ctx; -} - - -/** - * \brief Allocates the Reputation structure for a host/netblock - * - * \retval rep_data On success, pointer to the rep_data that has to be sent - * along with the key, to be added to the Radix tree - */ -Reputation *SCReputationAllocData(void) -{ - Reputation *rep_data = NULL; - - if ( (rep_data = SCMalloc(sizeof(Reputation))) == NULL) - return NULL; - memset(rep_data,0, sizeof(Reputation)); - rep_data->ctime = time(NULL); - rep_data->mtime= time(NULL); - - return rep_data; -} - -/** - * \brief Used to SCFree the reputation data that is allocated by Reputation API - * - * \param Pointer to the data that has to be SCFreed - */ -void SCReputationFreeData(void *data) -{ - if (data != NULL) - SCFree(data); - - return; -} - -/** - * \brief Allocates the Reputation structure for a host/netblock - * - * \retval ReputationTransaction pointer On success - */ -ReputationTransaction *SCReputationTransactionAlloc(void) -{ - ReputationTransaction *rtx = NULL; - - if ( (rtx = SCMalloc(sizeof(ReputationTransaction))) == NULL) - return NULL; - memset(rtx, 0, sizeof(ReputationTransaction)); - - return rtx; -} - -/** - * \brief Used to SCFree the transaction data - * - * \param Pointer to the data that has to be SCFreed - */ -void SCReputationTransactionFreeData(void *data) -{ - if (data != NULL) - SCFree(data); - - return; -} - -/** - * \brief Apply the transaction of changes to the reputation - * We use transactions because we cant be locking/unlocking the - * trees foreach update. This help for a better performance - * - * \param rep_data pointer to the reputation to update - * \param rtx pointer to the transaction data - */ -void SCReputationApplyTransaction(Reputation *rep_data, ReputationTransaction *rtx) -{ - int i = 0; - - /* No modification needed */ - if ( !(rtx->flags & TRANSACTION_FLAG_NEEDSYNC)) - return; - - /* Here we should apply a formula, a threshold or similar, - * maybe values loaded from config */ - for (; i < REPUTATION_NUMBER; i++) { - if (rtx->flags & TRANSACTION_FLAG_INCS) { - if (rep_data->reps[i] + rtx->inc[i] < 255) - rep_data->reps[i] += rtx->inc[i]; - else - rep_data->reps[i] = 255; - } - if (rtx->flags & TRANSACTION_FLAG_DECS) { - if (rep_data->reps[i] - rtx->dec[i] > 0) - rep_data->reps[i] -= rtx->dec[i]; - else - rep_data->reps[i] = 0; - } - } - rep_data->mtime = time(NULL); - rep_data->flags |= REPUTATION_FLAG_NEEDSYNC; -} - -/** - * \brief Function that compare two reputation structs to determine if they are equal - * - * \param rep1 pointer to reputation 1 - * \param rep2 pointer to reputation 2 - * - * \retval 1 if they are equal; 0 if not - */ -int SCReputationEqual(Reputation *rep1, Reputation *rep2) -{ - return (memcmp(rep1->reps, rep2->reps, REPUTATION_NUMBER * sizeof(uint8_t)) == 0)? 1 : 0; -} - - -/** - * \brief Helper function to print the Reputation structure - * - * \param Pointer rep_data to a Reputation structure - */ -void SCReputationPrint(Reputation *rep_data) -{ - if (rep_data == NULL) { - printf("No Reputation Data!\n"); - return; - } - int i = 0; - for (; i < REPUTATION_NUMBER; i++) - printf("Rep_type %d = %d\n", i, rep_data->reps[i]); - - if (rep_data->flags & REPUTATION_FLAG_NEEDSYNC) - printf("REPUTATION_FLAG_NEEDSYNC = 1\n"); -} - -/** - * \brief Clone all the data of a reputation - * When you try to update the feed, if the data you have belongs - * to a netblock, it will be cloned and inserted or a host, with - * the modifications that you add - * - * \param orig Pointer to the original reputation (probably of a netblock) - * - * \retval Reputation Pointer to the reputation copy - */ -Reputation *SCReputationClone(Reputation *orig) -{ - Reputation *rep = NULL; - if (orig == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid arguments"); - return NULL; - } - - if ( (rep = SCMalloc(sizeof(Reputation))) == NULL) - return NULL; - memcpy(rep, orig, sizeof(Reputation)); - return rep; -} - -void SCReputationFreeCtx(IPReputationCtx *rep_ctx) -{ - if (rep_ctx->reputationIPV4_tree != NULL) { - SCRadixReleaseRadixTree(rep_ctx->reputationIPV4_tree); - rep_ctx->reputationIPV4_tree = NULL; - SCMutexDestroy(&rep_ctx->reputationIPV4_lock); - } - if (rep_ctx->reputationIPV6_tree != NULL) { - SCRadixReleaseRadixTree(rep_ctx->reputationIPV6_tree); - rep_ctx->reputationIPV6_tree = NULL; - SCMutexDestroy(&rep_ctx->reputationIPV6_lock); - } -} - -/** - * \brief Used to add a new reputation to the reputation module (only at the startup) - * - * \param ipv4addr pointer to the ipv4 address key - * \param netmask_value of the ipv4 address (can be a subnet or a host (32)) - * \param rep_data Reputation pointer to the Reputation associated to the host/net - * - * \retval NULL On failure; rep_data on success - */ -Reputation *SCReputationAddIPV4Data(uint8_t *ipv4addr, int netmask_value, Reputation *rep_data) -{ - struct in_addr *ipv4_addr = (struct in_addr *) ipv4addr; - - if (ipv4_addr == NULL || rep_data == NULL || rep_ctx == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid arguments"); - return NULL; - } - - /* If the reputation tree is not initialized yet */ - if (rep_ctx->reputationIPV4_tree == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Reputation trees not initialized"); - return NULL; - } - - if (netmask_value == 32) { - /* Be careful with the mutex */ - SCMutexLock(&rep_ctx->reputationIPV4_lock); - SCRadixAddKeyIPV4((uint8_t *)ipv4_addr, rep_ctx->reputationIPV4_tree, - (void *)rep_data); - SCMutexUnlock(&rep_ctx->reputationIPV4_lock); - - } else { - if (netmask_value < 0 || netmask_value > 31) { - SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Invalid IPV4 Netblock"); - return NULL; - } - - MaskIPNetblock((uint8_t *)ipv4_addr, netmask_value, 32); - - /* Be careful with the mutex */ - SCMutexLock(&rep_ctx->reputationIPV4_lock); - SCRadixAddKeyIPV4Netblock((uint8_t *)ipv4_addr, rep_ctx->reputationIPV4_tree, - (void *)rep_data, netmask_value); - SCMutexUnlock(&rep_ctx->reputationIPV4_lock); - } - - return rep_data; -} - -/** - * \brief Retrieves the Reputation of a host (exact match), given an ipv4 address in the raw - * address format. - * - * \param ipv4_addr Pointer to a raw ipv4 address. - * - * \retval Pointer to a copy of the host Reputation on success; - * NULL on failure, or on not finding the key; - */ -Reputation *SCReputationLookupIPV4ExactMatch(uint8_t *ipv4_addr) -{ - Reputation *rep_data = NULL; - - /* Be careful with this (locking)*/ - SCMutexLock(&rep_ctx->reputationIPV4_lock); - - void *user_data = NULL; - (void)SCRadixFindKeyIPV4ExactMatch(ipv4_addr, rep_ctx->reputationIPV4_tree, &user_data); - if (user_data == NULL) { - rep_data = NULL; - } else { - /* Yes, we clone it because the pointer can be outdated - * while another thread remove this reputation */ - rep_data = SCReputationClone((Reputation *)user_data); - } - - SCMutexUnlock(&rep_ctx->reputationIPV4_lock); - return rep_data; -} - -/** - * \brief Retrieves the Reputation of a host (best match), given an ipv4 address in the raw - * address format. - * - * \param ipv4_addr Pointer to a raw ipv4 address. - * - * \retval Pointer to a copy of the host Reputation on success; - * NULL on failure, or on not finding the key; - */ -Reputation *SCReputationLookupIPV4BestMatch(uint8_t *ipv4_addr) -{ - Reputation *rep_data; - - /* Be careful with this (locking)*/ - SCMutexLock(&rep_ctx->reputationIPV4_lock); - - void *user_data = NULL; - (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, rep_ctx->reputationIPV4_tree, &user_data); - if (user_data == NULL) { - rep_data = NULL; - } else { - /* Yes, we clone it because the pointer can be outdated - * while another thread remove this reputation */ - rep_data = SCReputationClone((Reputation *)user_data); - } - - SCMutexUnlock(&rep_ctx->reputationIPV4_lock); - return rep_data; -} - -/** - * \brief Retrieves the Reputation of a host (best match), given an ipv6 address in the raw - * address format. - * - * \param Pointer to a raw ipv6 address. - * - * \retval Pointer to a copy of the host Reputation on success; - * NULL on failure, or on not finding the key; - */ -Reputation *SCReputationLookupIPV6BestMatch(uint8_t *ipv6_addr) -{ - Reputation *rep_data; - - /* Be careful with this (locking)*/ - SCMutexLock(&rep_ctx->reputationIPV6_lock); - - void *user_data = NULL; - (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, rep_ctx->reputationIPV6_tree, &user_data); - if (user_data == NULL) { - rep_data = NULL; - } else { - /* Yes, we clone it because the pointer can be outdated - * while another thread remove this reputation */ - rep_data = SCReputationClone((Reputation *)user_data); - } - - SCMutexUnlock(&rep_ctx->reputationIPV6_lock); - return rep_data; -} - -/** - * \brief Retrieves the Reputation of a host (exact match), given an ipv6 address in the raw - * address format. - * - * \param Pointer to a raw ipv6 address. - * - * \retval Pointer to a copy of the host reputation on success; - * NULL on failure, or on not finding the key; - */ -Reputation *SCReputationLookupIPV6ExactMatch(uint8_t *ipv6_addr) -{ - Reputation *rep_data; - - /* Be careful with this (locking)*/ - SCMutexLock(&rep_ctx->reputationIPV6_lock); - - void *user_data = NULL; - (void)SCRadixFindKeyIPV6ExactMatch(ipv6_addr, rep_ctx->reputationIPV6_tree, &user_data); - if (user_data == NULL) { - rep_data = NULL; - } else { - /* Yes, we clone it because the pointer can be outdated - * while another thread remove this reputation */ - rep_data = SCReputationClone((Reputation *)user_data); - } - - SCMutexUnlock(&rep_ctx->reputationIPV6_lock); - return rep_data; -} - - -/** - * \brief Retrieves the Real Reputation of a host (exact match), given an ipv4 address in the raw - * address format. (Not thread safe!) - * - * \param ipv4_addr Pointer to a raw ipv4 address. - * - * \retval Pointer to the Reputation of the host on success; - * NULL on failure, or on not finding the key; - */ -Reputation *SCReputationLookupIPV4ExactMatchReal(uint8_t *ipv4_addr) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV4ExactMatch(ipv4_addr, rep_ctx->reputationIPV4_tree, &user_data); - if (user_data == NULL) { - return NULL; - } else { - return (Reputation *)user_data; - } -} - -/** - * \brief Retrieves the Real Reputation of a host (best match), given an ipv4 address in the raw - * address format. (Not thread safe!) - * - * \param ipv4_addr Pointer to a raw ipv4 address. - * - * \retval Pointer to the Reputation of the host on success; - * NULL on failure, or on not finding the key; - */ -Reputation *SCReputationLookupIPV4BestMatchReal(uint8_t *ipv4_addr) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, rep_ctx->reputationIPV4_tree, &user_data); - if (user_data == NULL) { - return NULL; - } else { - return (Reputation *)user_data; - } -} - -/** - * \brief Retrieves the Real Reputation of a host (best match), given an ipv6 address in the raw - * address format. (Not thread safe!) - * - * \param Pointer to a raw ipv6 address. - * - * \retval Pointer to the Reputation of the host on success; - * NULL on failure, or on not finding the key; - */ -Reputation *SCReputationLookupIPV6BestMatchReal(uint8_t *ipv6_addr) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, rep_ctx->reputationIPV6_tree, &user_data); - if (user_data == NULL) { - return NULL; - } else { - return (Reputation *)user_data; - } -} - -/** - * \brief Retrieves the Real Reputation of a host (exact match), given an ipv6 address in the raw - * address format. (Not thread safe!) - * - * \param Pointer to a raw ipv6 address. - * - * \retval Pointer to the Reputation of the host on success; - * NULL on failure, or on not finding the key; - */ -Reputation *SCReputationLookupIPV6ExactMatchReal(uint8_t *ipv6_addr) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV6ExactMatch(ipv6_addr, rep_ctx->reputationIPV6_tree, &user_data); - if (user_data == NULL) { - return NULL; - } else { - return (Reputation *)user_data; - } -} - -/** - * \brief Remove the node of the reputation tree associated to the ipv4 address - * - * \param ipv4_addr Pointer to a raw ipv4 address - * \param netmask_value netmask to apply to the address (32 for host) - * - */ -void SCReputationRemoveIPV4Data(uint8_t * ipv4_addr, uint8_t netmask_value) -{ - SCMutexLock(&rep_ctx->reputationIPV4_lock); - SCRadixRemoveKeyIPV4Netblock(ipv4_addr, rep_ctx->reputationIPV4_tree, netmask_value); - SCMutexUnlock(&rep_ctx->reputationIPV4_lock); -} - -/** - * \brief Remove the node of the reputation tree associated to the ipv6 address - * - * \param ipv6_addr Pointer to a raw ipv6 address - * \param netmask_value netmask to apply to the address (128 for host) - * - */ -void SCReputationRemoveIPV6Data(uint8_t * ipv6_addr, uint8_t netmask_value) -{ - SCMutexLock(&rep_ctx->reputationIPV6_lock); - SCRadixRemoveKeyIPV6Netblock(ipv6_addr, rep_ctx->reputationIPV6_tree, netmask_value); - SCMutexUnlock(&rep_ctx->reputationIPV6_lock); -} - -/** - * \brief Used to add a new reputation to the reputation module (only at the startup) - * - * \param ipv6addr pointer to the ipv6 address key - * \param netmask_value of the ipv6 address (can be a subnet) - * \param rep_data Reputation pointer to the Reputation associated to the host/net - * - * \retval NULL On failure - */ -Reputation *SCReputationAddIPV6Data(uint8_t *ipv6addr, int netmask_value, Reputation *rep_data) -{ - struct in_addr *ipv6_addr = (struct in_addr *) ipv6addr; - - if (ipv6_addr == NULL || rep_data == NULL || rep_ctx == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid arguments"); - return NULL; - } - - /* If the reputation tree is not initialized yet */ - if (rep_ctx->reputationIPV6_tree == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Reputation trees not initialized"); - return NULL; - } - - if (netmask_value == 128) { - /* Be careful with the mutex */ - SCMutexLock(&rep_ctx->reputationIPV6_lock); - SCRadixAddKeyIPV6((uint8_t *)ipv6_addr, rep_ctx->reputationIPV6_tree, - (void *)rep_data); - SCMutexUnlock(&rep_ctx->reputationIPV6_lock); - - } else { - if (netmask_value < 0 || netmask_value > 127) { - SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Invalid IPV6 Netblock"); - return NULL; - } - - MaskIPNetblock((uint8_t *)ipv6_addr, netmask_value, 128); - - /* Be careful with the mutex */ - SCMutexLock(&rep_ctx->reputationIPV6_lock); - SCRadixAddKeyIPV6Netblock((uint8_t *)ipv6_addr, rep_ctx->reputationIPV6_tree, - (void *)rep_data, netmask_value); - SCMutexUnlock(&rep_ctx->reputationIPV6_lock); - } - - return rep_data; -} - -/** - * \brief Update a reputation or insert a new one. If it doesn't exist - * it will try to search for the reputation of parent subnets to - * create the new reputation data based on this one - * - * \param ipv6addr pointer to the ipv6 address key - * \param rep_data Reputation pointer to the Reputation associated to the host/net - * - * \retval NULL On failure - */ -Reputation *SCReputationUpdateIPV4Data(uint8_t *ipv4addr, ReputationTransaction *rtx) -{ - struct in_addr *ipv4_addr = (struct in_addr *) ipv4addr; - Reputation *actual_rep; - - if (ipv4_addr == NULL || rtx == NULL || rep_ctx == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid arguments"); - return NULL; - } - - /* If the reputation tree is not initialized yet */ - if (rep_ctx->reputationIPV4_tree == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Reputation trees not initialized"); - return NULL; - } - - /* Be careful with the mutex */ - SCMutexLock(&rep_ctx->reputationIPV4_lock); - - /* Search exact match and update */ - actual_rep = SCReputationLookupIPV4ExactMatchReal(ipv4addr); - if (actual_rep == NULL) { - /* else search best match (parent subnets) */ - actual_rep =SCReputationLookupIPV4BestMatchReal(ipv4addr); - - if (actual_rep != NULL) { - /* clone from parent and insert host */ - actual_rep = SCReputationClone(actual_rep); - } else { - /* else insert a new reputation data for the host */ - actual_rep = SCReputationAllocData(); - /* If new, we only increment values */ - rtx->flags = TRANSACTION_FLAG_INCS; - rtx->flags |= TRANSACTION_FLAG_NEEDSYNC; - } - - /* insert the reputation data in the tree */ - SCRadixAddKeyIPV4((uint8_t *)ipv4_addr, rep_ctx->reputationIPV4_tree, - (void *)actual_rep); - } - /* Apply updates */ - SCReputationApplyTransaction(actual_rep, rtx); - - /* Unlock! */ - SCMutexUnlock(&rep_ctx->reputationIPV4_lock); - - return actual_rep; -} - -/** - * \brief Update a reputation or insert a new one. If it doesn't exist - * it will try to search for the reputation of parent subnets to - * create the new reputation data based on this one - * - * \param ipv6addr pointer to the ipv6 address key - * \param rep_data Reputation pointer to the Reputation associated to the host/net - * - * \retval NULL On failure - */ -Reputation *SCReputationUpdateIPV6Data(uint8_t *ipv6addr, ReputationTransaction *rtx) -{ - struct in_addr *ipv6_addr = (struct in_addr *) ipv6addr; - Reputation *actual_rep; - - if (ipv6_addr == NULL || rtx == NULL || rep_ctx == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid arguments"); - return NULL; - } - - /* If the reputation tree is not initialized yet */ - if (rep_ctx->reputationIPV6_tree == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Reputation trees not initialized"); - return NULL; - } - - /* Be careful with the mutex */ - SCMutexLock(&rep_ctx->reputationIPV6_lock); - - /* Search exact match and update */ - actual_rep = SCReputationLookupIPV6ExactMatchReal(ipv6addr); - if (actual_rep == NULL) { - /* else search best match (parent subnets) */ - actual_rep =SCReputationLookupIPV6BestMatchReal(ipv6addr); - - if (actual_rep != NULL) { - /* clone from parent and insert host */ - actual_rep = SCReputationClone(actual_rep); - } else { - /* else insert a new reputation data for the host */ - actual_rep = SCReputationAllocData(); - /* If new, we only increment values */ - rtx->flags = TRANSACTION_FLAG_INCS; - rtx->flags |= TRANSACTION_FLAG_NEEDSYNC; - } - - /* insert the reputation data in the tree */ - SCRadixAddKeyIPV6((uint8_t *)ipv6_addr, rep_ctx->reputationIPV6_tree, - (void *)actual_rep); - } - /* Apply updates */ - SCReputationApplyTransaction(actual_rep, rtx); - - /* Unlock! */ - SCMutexUnlock(&rep_ctx->reputationIPV6_lock); - - return actual_rep; -} - - -/* ----------------- UNITTESTS-------------------- */ -#ifdef UNITTESTS - -/** - * \test Adding (from numeric ipv4) and removing host reputation in the Reputation context - * tree. THe reputation data is the real one, no copies here. - */ -int SCReputationTestIPV4AddRemoveHost01(void) -{ - int i = 0; - struct in_addr in; - - SCReputationInitCtx(); - if (rep_ctx == NULL) { - SCLogInfo("Error initializing Reputation Module"); - return 0; - } - - Reputation *rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.6", &in) < 0) - goto error; - - /* Fill the reputation with some values.. */ - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 6; - - rep_orig = SCReputationAddIPV4Data((uint8_t *) &in, 32, rep_orig); - if (rep_orig == NULL) - goto error; - - Reputation *rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_orig) - goto error; - - rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.7", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 7; - - rep_orig = SCReputationAddIPV4Data((uint8_t *) &in, 32, rep_orig); - if (rep_orig == NULL) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_orig) - goto error; - - rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.7", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 7; - - rep_orig = SCReputationAddIPV4Data((uint8_t *) &in, 31, rep_orig); - if (rep_orig == NULL) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - /* It should return the host info and not the subnet info */ - if (rep_data == NULL || rep_data == rep_orig) - goto error; - - if (inet_pton(AF_INET, "192.168.1.8", &in) < 0) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - /* It should return the host info and not the subnet info */ - if (rep_data != NULL) - goto error; - - - /* Removing */ - if (inet_pton(AF_INET, "192.168.1.7", &in) < 0) - goto error; - - SCReputationRemoveIPV4Data((uint8_t *) &in, 32); - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.6", &in) < 0) - goto error; - - SCReputationRemoveIPV4Data((uint8_t *) &in, 32); - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - SCRadixPrintTree(rep_ctx->reputationIPV4_tree); - - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 1; - -error: - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 0; -} - -/** - * \test Adding (from numeric ipv6) and removing host reputation in the Reputation context - * tree. THe reputation data is the real one, no copies here. - */ -int SCReputationTestIPV6AddRemoveHost01(void) -{ - uint8_t in[16]; - uint8_t i = 0; - - SCReputationInitCtx(); - if (rep_ctx == NULL) { - SCLogInfo("Error initializing Reputation Module"); - return 0; - } - - if (inet_pton(AF_INET6, "aaaa:bbbb:cccc:dddd:1223:1722:3425:2362", &in) < 0) - goto error; - - Reputation *rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - /* Fill the reputation with some values.. */ - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 1; - - rep_orig = SCReputationAddIPV6Data((uint8_t *) &in, 128, rep_orig); - if (rep_orig == NULL) - goto error; - - Reputation *rep_data = SCReputationLookupIPV6ExactMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_orig) - goto error; - - rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET6, "aaaa:bbbb:cccc:dddd:1223:1722:3425:2363", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 8; - - rep_orig = SCReputationAddIPV6Data((uint8_t *) &in, 128, rep_orig); - if (rep_orig == NULL) - goto error; - - rep_data = SCReputationLookupIPV6ExactMatchReal((uint8_t *) &in); - - if (rep_data == NULL || rep_data != rep_orig) - goto error; - - rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET6, "aaaa:bbbb:cccc:dddd:1223:1722:3425:2363", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 7; - - rep_orig = SCReputationAddIPV6Data((uint8_t *) &in, 127, rep_orig); - if (rep_orig == NULL) - goto error; - - rep_data = SCReputationLookupIPV6ExactMatchReal((uint8_t *) &in); - /* It should return the host info and not the subnet info */ - if (rep_data == NULL || rep_data == rep_orig) - goto error; - - - /* Removing */ - if (inet_pton(AF_INET6, "aaaa:bbbb:cccc:dddd:1223:1722:3425:2363", &in) < 0) - goto error; - - SCReputationRemoveIPV6Data((uint8_t *) &in, 128); - - rep_data = SCReputationLookupIPV6ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - if (inet_pton(AF_INET6, "aaaa:bbbb:cccc:dddd:1223:1722:3425:2362", &in) < 0) - goto error; - - SCReputationRemoveIPV6Data((uint8_t *) &in, 128); - rep_data = SCReputationLookupIPV6ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - SCRadixPrintTree(rep_ctx->reputationIPV6_tree); - - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 1; - -error: - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 0; -} - -/** - * \test Adding (from numeric ipv4) and retrieving reputations - * tree. The reputation data retireved are copies of the original. - */ -int SCReputationTestIPV4AddRemoveHost02(void) -{ - int i = 0; - struct in_addr in; - - SCReputationInitCtx(); - if (rep_ctx == NULL) { - SCLogInfo("Error initializing Reputation Module"); - return 0; - } - - Reputation *rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.6", &in) < 0) - goto error; - - /* Fill the reputation with some values.. */ - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 6; - - rep_orig = SCReputationAddIPV4Data((uint8_t *) &in, 32, rep_orig); - if (rep_orig == NULL) - goto error; - - Reputation *rep_data = SCReputationLookupIPV4ExactMatch((uint8_t *) &in); - if (rep_data == NULL || SCReputationEqual(rep_data, rep_orig) == 0) - goto error; - - rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.7", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 7; - - rep_orig = SCReputationAddIPV4Data((uint8_t *) &in, 32, rep_orig); - if (rep_orig == NULL) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatch((uint8_t *) &in); - if (rep_data == NULL || SCReputationEqual(rep_data, rep_orig) == 0) - goto error; - - rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.7", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 9; - - rep_orig = SCReputationAddIPV4Data((uint8_t *) &in, 31, rep_orig); - if (rep_orig == NULL) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatch((uint8_t *) &in); - /* It should return the host info and not the subnet info */ - if (rep_data == NULL || SCReputationEqual(rep_data, rep_orig) == 1) - goto error; - - SCRadixPrintTree(rep_ctx->reputationIPV4_tree); - - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 1; - -error: - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 0; -} - -/** - * \test Adding (from numeric ipv6) and removing host reputation in the Reputation context - * tree. The reputation data retireved are copies of the original. - */ -int SCReputationTestIPV6AddRemoveHost02(void) -{ - int i = 0; - uint8_t in[16]; - - SCReputationInitCtx(); - if (rep_ctx == NULL) { - SCLogInfo("Error initializing Reputation Module"); - return 0; - } - - Reputation *rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET6, "aaaa:bbbb:cccc:dddd:1223:1722:3425:2362", &in) < 0) - goto error; - - /* Fill the reputation with some values.. */ - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 6; - - rep_orig = SCReputationAddIPV6Data((uint8_t *) &in, 128, rep_orig); - if (rep_orig == NULL) - goto error; - - Reputation *rep_data = SCReputationLookupIPV6ExactMatch((uint8_t *) &in); - if (rep_data == NULL || SCReputationEqual(rep_data, rep_orig) == 0) - goto error; - - rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - if (inet_pton(AF_INET6, "aaaa:bbbb:cccc:dddd:1223:1722:3425:2363", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 7; - - rep_orig = SCReputationAddIPV6Data((uint8_t *) &in, 128, rep_orig); - if (rep_orig == NULL) - goto error; - - rep_data = SCReputationLookupIPV6ExactMatch((uint8_t *) &in); - if (rep_data == NULL || SCReputationEqual(rep_data, rep_orig) == 0) - goto error; - - rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET6, "aaaa:bbbb:cccc:dddd:1223:1722:3425:2363", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 9; - - rep_orig = SCReputationAddIPV6Data((uint8_t *) &in, 127, rep_orig); - if (rep_orig == NULL) - goto error; - - rep_data = SCReputationLookupIPV6ExactMatch((uint8_t *) &in); - /* It should return the host info and not the subnet info */ - if (rep_data == NULL || SCReputationEqual(rep_data, rep_orig) == 1) - goto error; - - if (inet_pton(AF_INET6, "aaaa:bbbb:cccc:dddd:1223:1722:3425:2364", &in) < 0) - goto error; - - rep_data = SCReputationLookupIPV6ExactMatch((uint8_t *) &in); - /* It should return the host info and not the subnet info */ - if (rep_data != NULL) - goto error; - - SCRadixPrintTree(rep_ctx->reputationIPV6_tree); - - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 1; - -error: - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 0; -} - -/** - * \test Test searches (best and exact matches) - */ -int SCReputationTestIPV4BestExactMatch01(void) -{ - int i = 0; - struct in_addr in; - - SCReputationInitCtx(); - if (rep_ctx == NULL) { - SCLogInfo("Error initializing Reputation Module"); - return 0; - } - - Reputation *rep_origC = NULL; - Reputation *rep_origB = NULL; - Reputation *rep_origA = NULL; - - Reputation *rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.6", &in) < 0) - goto error; - - /* Fill the reputation with some values.. */ - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 6; - - /* adding a host */ - rep_orig = SCReputationAddIPV4Data((uint8_t *) &in, 32, rep_orig); - if (rep_orig == NULL) - goto error; - Reputation *rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_orig) - goto error; - - rep_orig = SCReputationAllocData(); - if (rep_orig == NULL) - goto error; - - /* Adding C subnet */ - if (inet_pton(AF_INET, "192.168.1.0", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 7; - - rep_origC = SCReputationAddIPV4Data((uint8_t *) &in, 24, rep_orig); - if (rep_origC == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.5", &in) < 0) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - rep_data = SCReputationLookupIPV4BestMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_origC) - goto error; - - rep_orig = SCReputationAllocData(); - /* Adding B subnet */ - if (inet_pton(AF_INET, "192.168.0.0", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 7; - - rep_origB = SCReputationAddIPV4Data((uint8_t *) &in, 16, rep_orig); - if (rep_origB == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.5", &in) < 0) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - rep_data = SCReputationLookupIPV4BestMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_origC) - goto error; - - if (inet_pton(AF_INET, "192.168.2.5", &in) < 0) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - rep_data = SCReputationLookupIPV4BestMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_origB) - goto error; - - rep_orig = SCReputationAllocData(); - /* Adding A subnet */ - if (inet_pton(AF_INET, "192.0.0.0", &in) < 0) - goto error; - - for (i = 0; i < REPUTATION_NUMBER; i++) - rep_orig->reps[i] = i * 10 + 7; - - rep_origA = SCReputationAddIPV4Data((uint8_t *) &in, 8, rep_orig); - if (rep_origA == NULL) - goto error; - - if (inet_pton(AF_INET, "192.168.1.5", &in) < 0) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - rep_data = SCReputationLookupIPV4BestMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_origC) - goto error; - - if (inet_pton(AF_INET, "192.168.2.5", &in) < 0) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - rep_data = SCReputationLookupIPV4BestMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_origB) - goto error; - - if (inet_pton(AF_INET, "192.167.2.5", &in) < 0) - goto error; - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data != NULL) - goto error; - - rep_data = SCReputationLookupIPV4BestMatchReal((uint8_t *) &in); - if (rep_data == NULL || rep_data != rep_origA) - goto error; - - SCRadixPrintTree(rep_ctx->reputationIPV4_tree); - - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 1; -error: - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 0; -} - -/** - * \test Update transactions - */ -int SCReputationTestIPV4Update01(void) -{ - int i = 0; - struct in_addr in; - - SCReputationInitCtx(); - if (rep_ctx == NULL) { - SCLogInfo("Error initializing Reputation Module"); - return 0; - } - - Reputation *rep_orig = SCReputationAllocData(); - - ReputationTransaction rtx; - memset(&rtx, 0, sizeof(ReputationTransaction)); - if (rep_orig == NULL) - goto error; - - /* Fill the reputation with some values.. */ - for (i = 0; i < REPUTATION_NUMBER; i++) { - rep_orig->reps[i] = 10; - } - - if (inet_pton(AF_INET, "192.168.0.0", &in) < 0) - goto error; - - /* Add add it as net */ - rep_orig = SCReputationAddIPV4Data((uint8_t *) &in, 16, rep_orig); - if (rep_orig == NULL) - goto error; - - rtx.dec[REPUTATION_DDOS] = 5; - rtx.inc[REPUTATION_PHISH] = 50; - rtx.inc[REPUTATION_MALWARE] = 30; - rtx.flags |= TRANSACTION_FLAG_NEEDSYNC; - rtx.flags |= TRANSACTION_FLAG_INCS; - rtx.flags |= TRANSACTION_FLAG_DECS; - - if (inet_pton(AF_INET, "192.168.10.100", &in) < 0) - goto error; - - /* Update (it will create the host entry with the data of the net) */ - SCReputationUpdateIPV4Data((uint8_t *)&in, &rtx); - - /* Create the reputation that any host 192.168.* should have */ - Reputation *rep_aux = SCReputationAllocData(); - - /* Fill the reputation with some values.. */ - for (i = 0; i < REPUTATION_NUMBER; i++) { - rep_aux->reps[i] = 10; - } - - rep_aux->reps[REPUTATION_DDOS] = 5; - rep_aux->reps[REPUTATION_PHISH] = 60; - rep_aux->reps[REPUTATION_MALWARE] = 40; - - Reputation *rep_data = SCReputationLookupIPV4BestMatchReal((uint8_t *) &in); - if (rep_data == NULL || SCReputationEqual(rep_data, rep_aux) != 1) - goto error; - - /* Now that is created, it should update only the host */ - rtx.dec[REPUTATION_DDOS] = 50; - rtx.inc[REPUTATION_PHISH] = 50; - rtx.inc[REPUTATION_MALWARE] = 50; - - rep_aux->reps[REPUTATION_DDOS] = 0; - rep_aux->reps[REPUTATION_PHISH] = 110; - rep_aux->reps[REPUTATION_MALWARE] = 90; - - SCReputationUpdateIPV4Data((uint8_t *)&in, &rtx); - - rep_data = SCReputationLookupIPV4ExactMatchReal((uint8_t *) &in); - if (rep_data == NULL || SCReputationEqual(rep_data, rep_aux) != 1) - goto error; - - /* So let's see if we add a host and get the parent data again */ - if (inet_pton(AF_INET, "192.168.10.101", &in) < 0) - goto error; - - rep_aux->reps[REPUTATION_DDOS] = 10; - rep_aux->reps[REPUTATION_PHISH] = 10; - rep_aux->reps[REPUTATION_MALWARE] = 10; - - rep_data = SCReputationLookupIPV4BestMatchReal((uint8_t *) &in); - - if (rep_data == NULL || SCReputationEqual(rep_data, rep_aux) != 1) - goto error; - - SCRadixPrintTree(rep_ctx->reputationIPV4_tree); - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 1; - -error: - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 0; -} - -/** - * \test Update transactions - */ -int SCReputationTestIPV6Update01(void) -{ - int i = 0; - uint8_t in[16]; - - SCReputationInitCtx(); - if (rep_ctx == NULL) { - SCLogInfo("Error initializing Reputation Module"); - return 0; - } - - Reputation *rep_orig = SCReputationAllocData(); - - ReputationTransaction rtx; - memset(&rtx, 0, sizeof(ReputationTransaction)); - if (rep_orig == NULL) - goto error; - - /* Fill the reputation with some values.. */ - for (i = 0; i < REPUTATION_NUMBER; i++) { - rep_orig->reps[i] = 10; - } - - if (inet_pton(AF_INET6, "8762:2352:6261:7265:EE23:21AD:2121:1DDD", &in) < 0) - goto error; - - /* Add add it as net */ - rep_orig = SCReputationAddIPV6Data((uint8_t *) &in, 98, rep_orig); - if (rep_orig == NULL) - goto error; - - rtx.dec[REPUTATION_DDOS] = 5; - rtx.inc[REPUTATION_PHISH] = 50; - rtx.inc[REPUTATION_MALWARE] = 30; - rtx.flags |= TRANSACTION_FLAG_NEEDSYNC; - rtx.flags |= TRANSACTION_FLAG_INCS; - rtx.flags |= TRANSACTION_FLAG_DECS; - - if (inet_pton(AF_INET6, "8762:2352:6261:7265:EE23:21AD:2121:1ABA", &in) < 0) - goto error; - - /* Update (it will create the host entry with the data of the net) */ - SCReputationUpdateIPV6Data((uint8_t *)&in, &rtx); - - /* Create the reputation that any host 192.168.* should have */ - Reputation *rep_aux = SCReputationAllocData(); - - /* Fill the reputation with some values.. */ - for (i = 0; i < REPUTATION_NUMBER; i++) { - rep_aux->reps[i] = 10; - } - - rep_aux->reps[REPUTATION_DDOS] = 5; - rep_aux->reps[REPUTATION_PHISH] = 60; - rep_aux->reps[REPUTATION_MALWARE] = 40; - - Reputation *rep_data = SCReputationLookupIPV6BestMatchReal((uint8_t *) &in); - if (rep_data == NULL || SCReputationEqual(rep_data, rep_aux) != 1) - goto error; - - /* Now that is created, it should update only the host */ - rtx.dec[REPUTATION_DDOS] = 50; - rtx.inc[REPUTATION_PHISH] = 50; - rtx.inc[REPUTATION_MALWARE] = 50; - - rep_aux->reps[REPUTATION_DDOS] = 0; - rep_aux->reps[REPUTATION_PHISH] = 110; - rep_aux->reps[REPUTATION_MALWARE] = 90; - - SCReputationUpdateIPV6Data((uint8_t *)&in, &rtx); - - rep_data = SCReputationLookupIPV6ExactMatchReal((uint8_t *) &in); - if (rep_data == NULL || SCReputationEqual(rep_data, rep_aux) != 1) - goto error; - - /* So let's see if we add a host and get the parent data again */ - if (inet_pton(AF_INET6, "8762:2352:6261:7265:EE23:21AD:2121:1ACB", &in) < 0) - goto error; - - rep_aux->reps[REPUTATION_DDOS] = 10; - rep_aux->reps[REPUTATION_PHISH] = 10; - rep_aux->reps[REPUTATION_MALWARE] = 10; - - rep_data = SCReputationLookupIPV6BestMatchReal((uint8_t *) &in); - - - if (rep_data == NULL || SCReputationEqual(rep_data, rep_aux) != 1) - goto error; - - SCRadixPrintTree(rep_ctx->reputationIPV6_tree); - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 1; - -error: - SCReputationFreeCtx(rep_ctx); - rep_ctx = NULL; - return 0; -} - -#endif /* UNITTESTS */ - -/** Register the following unittests for the Reputation module */ -void SCReputationRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SCReputationTestIPV4AddRemoveHost01", - SCReputationTestIPV4AddRemoveHost01, 1); - UtRegisterTest("SCReputationTestIPV6AddRemoveHost01", - SCReputationTestIPV6AddRemoveHost01, 1); - - UtRegisterTest("SCReputationTestIPV4BestExactMatch01", - SCReputationTestIPV4BestExactMatch01, 1); - - UtRegisterTest("SCReputationTestIPV4AddRemoveHost02", - SCReputationTestIPV4AddRemoveHost02, 1); - UtRegisterTest("SCReputationTestIPV6AddRemoveHost02", - SCReputationTestIPV6AddRemoveHost02, 1); - - UtRegisterTest("SCReputationTestIPV4Update01", - SCReputationTestIPV4Update01, 1); - UtRegisterTest("SCReputationTestIPV6Update01", - SCReputationTestIPV6Update01, 1); - - UtRegisterTest("SRepTest01", SRepTest01, 1); - UtRegisterTest("SRepTest02", SRepTest02, 1); - UtRegisterTest("SRepTest03", SRepTest03, 1); - UtRegisterTest("SRepTest04", SRepTest04, 1); - UtRegisterTest("SRepTest05", SRepTest05, 1); - UtRegisterTest("SRepTest06", SRepTest06, 1); - UtRegisterTest("SRepTest07", SRepTest07, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/reputation.h b/framework/src/suricata/src/reputation.h deleted file mode 100644 index 347731fe..00000000 --- a/framework/src/suricata/src/reputation.h +++ /dev/null @@ -1,123 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * \author Victor Julien - * Original Idea by Matt Jonkman - */ - -#ifndef __REPUTATION_H__ -#define __REPUTATION_H__ - -#include "host.h" - -#define SREP_MAX_CATS 60 - -typedef struct SRepCIDRTree_ { - SCRadixTree *srepIPV4_tree[SREP_MAX_CATS]; - SCRadixTree *srepIPV6_tree[SREP_MAX_CATS]; -} SRepCIDRTree; - -typedef struct SReputation_ { - uint32_t version; - uint8_t rep[SREP_MAX_CATS]; -} SReputation; - -uint8_t SRepCatGetByShortname(char *shortname); -int SRepInit(struct DetectEngineCtx_ *de_ctx); -void SRepDestroy(struct DetectEngineCtx_ *de_ctx); -void SRepReloadComplete(void); -int SRepHostTimedOut(Host *); - -/** Reputation numbers (types) that we can use to lookup/update, etc - * Please, dont convert this to a enum since we want the same reputation - * codes always. */ -#define REPUTATION_SPAM 0 /**< spammer */ -#define REPUTATION_CNC 1 /**< CnC server */ -#define REPUTATION_SCAN 2 /**< scanner */ -#define REPUTATION_HOSTILE 3 /**< hijacked nets, RBN nets, etc */ -#define REPUTATION_DYNAMIC 4 /**< Known dial up, residential, user networks */ -#define REPUTATION_PUBLICACCESS 5 /**< known internet cafe's open access points */ -#define REPUTATION_PROXY 6 /**< known tor out nodes, proxy servers, etc */ -#define REPUTATION_P2P 7 /**< Heavy p2p node, torrent server, other sharing services */ -#define REPUTATION_UTILITY 8 /**< known good places like google, yahoo, msn.com, etc */ -#define REPUTATION_DDOS 9 /**< Known ddos participant */ -#define REPUTATION_PHISH 10 /**< Known Phishing site */ -#define REPUTATION_MALWARE 11 /**< Known Malware distribution site. Hacked web server, etc */ -#define REPUTATION_ZOMBIE 12 /**< Known Zombie (botnet member) They typically are Scanner or Hostile, - but if collaboration with botnet snooping, like we did back in - 2005 or so, can proactively identify online zombies that joined a - botnet, you may want to break those out separately */ -#define REPUTATION_NUMBER 13 /**< number of rep types we have for data structure size (be careful with this) */ - - -/* Flags for reputation */ -#define REPUTATION_FLAG_NEEDSYNC 0x01 /**< rep was changed by engine, needs sync with external hub */ - -/** Reputation Context for IPV4 IPV6 */ -typedef struct IPReputationCtx_ { - /** Radix trees that holds the host reputation information */ - SCRadixTree *reputationIPV4_tree; - SCRadixTree *reputationIPV6_tree; - - /** Mutex to support concurrent access */ - SCMutex reputationIPV4_lock; - SCMutex reputationIPV6_lock; -}IPReputationCtx; - -uint8_t SRepCIDRGetIPRepSrc(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version); -uint8_t SRepCIDRGetIPRepDst(SRepCIDRTree *cidr_ctx, Packet *p, uint8_t cat, uint32_t version); -void SRepResetVersion(); -int SRepLoadCatFileFromFD(FILE *fp); -int SRepLoadFileFromFD(SRepCIDRTree *cidr_ctx, FILE *fp); - -/** Reputation Data */ -//TODO: Add a timestamp here to know the last update of this reputation. -typedef struct Reputation_ { - uint8_t reps[REPUTATION_NUMBER]; /**< array of 8 bit reputations */ - uint8_t flags; /**< reputation flags */ - time_t ctime; /**< creation time (epoch) */ - time_t mtime; /**< modification time (epoch) */ -} Reputation; - -/* flags for transactions */ -#define TRANSACTION_FLAG_NEEDSYNC 0x01 /**< We will apply the transaction only if necesary */ -#define TRANSACTION_FLAG_INCS 0x02 /**< We will increment only if necesary */ -#define TRANSACTION_FLAG_DECS 0x04 /**< We will decrement only if necesary */ - -/* transaction for feedback */ -typedef struct ReputationTransaction_ { - uint16_t inc[REPUTATION_NUMBER]; - uint16_t dec[REPUTATION_NUMBER]; - uint8_t flags; -} ReputationTransaction; - -/* API */ -Reputation *SCReputationAllocData(); -Reputation *SCReputationClone(Reputation *); -void SCReputationFreeData(void *); - -IPReputationCtx *SCReputationInitCtx(void); -void SCReputationFreeCtx(IPReputationCtx *); - -void SCReputationPrint(Reputation *); -void SCReputationRegisterTests(void); - -#endif /* __REPUTATION_H__ */ diff --git a/framework/src/suricata/src/respond-reject-libnet11.c b/framework/src/suricata/src/respond-reject-libnet11.c deleted file mode 100644 index b27b74e9..00000000 --- a/framework/src/suricata/src/respond-reject-libnet11.c +++ /dev/null @@ -1,541 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author William Metcalf - * - * RespondRejectLibnet11 used to send out libnet based - * TCP resets and ICMP unreachables. - * - * \todo calculate TTL base on average from stream tracking - * \todo come up with a way for users to specify icmp unreachable type - * \todo Possibly default to port unreachable for UDP traffic this seems - * to be the default in flexresp and iptables - * \todo implement ipv6 resets - * \todo implement pre-alloc resets for speed - */ - -#include "suricata-common.h" - -#include "decode.h" -#include "decode-ipv4.h" -#include "decode-tcp.h" -#include "decode-sctp.h" -#include "decode-udp.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "action-globals.h" -#include "respond-reject.h" -#include "respond-reject-libnet11.h" -#include "util-device.h" - -#ifdef HAVE_LIBNET11 - -/** set to true in main if we're setting caps. We need it here if we're using - * reject rules as libnet 1.1 is not compatible with caps. */ -extern int sc_set_caps; - -#include - -extern uint8_t host_mode; - -typedef struct Libnet11Packet_ { - uint32_t ack, seq; - uint16_t window, dsize; - uint8_t ttl; - uint16_t id; - uint32_t flow; - uint8_t class; - struct libnet_in6_addr src6, dst6; - uint32_t src4, dst4; - uint16_t sp, dp; - size_t len; -} Libnet11Packet; - -int RejectSendLibnet11L3IPv4TCP(ThreadVars *tv, Packet *p, void *data, int dir) -{ - - Libnet11Packet lpacket; - libnet_t *c; /* libnet context */ - char ebuf[LIBNET_ERRBUF_SIZE]; - int result; - char *devname = NULL; - - /* fill in struct defaults */ - lpacket.ttl = 0; - lpacket.id = 0; - lpacket.flow = 0; - lpacket.class = 0; - - if (IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode) && (p->livedev)) { - devname = p->livedev->dev; - SCLogDebug("Will emit reject packet on dev %s", devname); - } - if ((c = libnet_init(LIBNET_RAW4, devname, ebuf)) == NULL) { - SCLogError(SC_ERR_LIBNET_INIT,"libnet_init failed: %s", ebuf); - return 1; - } - - if (p->tcph == NULL) - return 1; - - /* save payload len */ - lpacket.dsize = p->payload_len; - - switch (dir) { - case REJECT_DIR_SRC: - SCLogDebug("sending a tcp reset to src"); - /* We follow http://tools.ietf.org/html/rfc793#section-3.4 : - * If packet has no ACK, the seq number is 0 and the ACK is built - * the normal way. If packet has a ACK, the seq of the RST packet - * is equal to the ACK of incoming packet and the ACK is build - * using packet sequence number and size of the data. */ - if (TCP_GET_ACK(p) == 0) { - lpacket.seq = 0; - lpacket.ack = TCP_GET_SEQ(p) + lpacket.dsize + 1; - } else { - lpacket.seq = TCP_GET_ACK(p); - lpacket.ack = TCP_GET_SEQ(p) + lpacket.dsize; - } - - lpacket.sp = TCP_GET_DST_PORT(p); - lpacket.dp = TCP_GET_SRC_PORT(p); - - lpacket.src4 = GET_IPV4_DST_ADDR_U32(p); - lpacket.dst4 = GET_IPV4_SRC_ADDR_U32(p); - break; - case REJECT_DIR_DST: - SCLogDebug("sending a tcp reset to dst"); - lpacket.seq = TCP_GET_SEQ(p); - lpacket.ack = TCP_GET_ACK(p); - - lpacket.sp = TCP_GET_SRC_PORT(p); - lpacket.dp = TCP_GET_DST_PORT(p); - - lpacket.src4 = GET_IPV4_SRC_ADDR_U32(p); - lpacket.dst4 = GET_IPV4_DST_ADDR_U32(p); - break; - default: - SCLogError(SC_ERR_LIBNET_INVALID_DIR, - "reset not src or dst returning"); - return 1; - } - - lpacket.window = TCP_GET_WINDOW(p); - //lpacket.seq += lpacket.dsize; - - /* TODO come up with ttl calc function */ - lpacket.ttl = 64; - - /* build the package */ - if ((libnet_build_tcp( - lpacket.sp, /* source port */ - lpacket.dp, /* dst port */ - lpacket.seq, /* seq number */ - lpacket.ack, /* ack number */ - TH_RST|TH_ACK, /* flags */ - lpacket.window, /* window size */ - 0, /* checksum */ - 0, /* urgent flag */ - LIBNET_TCP_H, /* header length */ - NULL, /* payload */ - 0, /* payload length */ - c, /* libnet context */ - 0)) < 0) /* libnet ptag */ - { - SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_tcp %s", libnet_geterror(c)); - goto cleanup; - } - - if ((libnet_build_ipv4( - LIBNET_TCP_H + LIBNET_IPV4_H, /* entire packet length */ - 0, /* tos */ - lpacket.id, /* ID */ - 0, /* fragmentation flags and offset */ - lpacket.ttl, /* TTL */ - IPPROTO_TCP, /* protocol */ - 0, /* checksum */ - lpacket.src4, /* source address */ - lpacket.dst4, /* destination address */ - NULL, /* pointer to packet data (or NULL) */ - 0, /* payload length */ - c, /* libnet context pointer */ - 0)) < 0) /* packet id */ - { - SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ipv4 %s", libnet_geterror(c)); - goto cleanup; - } - - result = libnet_write(c); - if (result == -1) { - SCLogError(SC_ERR_LIBNET_WRITE_FAILED,"libnet_write failed: %s", libnet_geterror(c)); - goto cleanup; - } - -cleanup: - libnet_destroy (c); - return 0; -} - -int RejectSendLibnet11L3IPv4ICMP(ThreadVars *tv, Packet *p, void *data, int dir) -{ - Libnet11Packet lpacket; - libnet_t *c; /* libnet context */ - char ebuf[LIBNET_ERRBUF_SIZE]; - int result; - char *devname = NULL; - - /* fill in struct defaults */ - lpacket.ttl = 0; - lpacket.id = 0; - lpacket.flow = 0; - lpacket.class = 0; - - lpacket.len = (IPV4_GET_HLEN(p) + p->payload_len); - - if (IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode) && (p->livedev)) { - devname = p->livedev->dev; - } - if ((c = libnet_init(LIBNET_RAW4, devname, ebuf)) == NULL) { - SCLogError(SC_ERR_LIBNET_INIT,"libnet_inint failed: %s", ebuf); - return 1; - } - - switch (dir) { - case REJECT_DIR_SRC: - lpacket.src4 = GET_IPV4_DST_ADDR_U32(p); - lpacket.dst4 = GET_IPV4_SRC_ADDR_U32(p); - break; - case REJECT_DIR_DST: - lpacket.src4 = GET_IPV4_SRC_ADDR_U32(p); - lpacket.dst4 = GET_IPV4_DST_ADDR_U32(p); - break; - default: - SCLogError(SC_ERR_LIBNET_INVALID_DIR, - "reset not src or dst returning"); - return 1; - } - - /* TODO come up with ttl calc function */ - lpacket.ttl = 64; - - /* build the package */ - if ((libnet_build_icmpv4_unreach( - ICMP_DEST_UNREACH, /* type */ - ICMP_HOST_ANO, /* code */ - 0, /* checksum */ - (uint8_t *)p->ip4h, /* payload */ - lpacket.len, /* payload length */ - c, /* libnet context */ - 0)) < 0) /* libnet ptag */ - { - SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_icmpv4_unreach %s", libnet_geterror(c)); - goto cleanup; - } - - if ((libnet_build_ipv4( - LIBNET_ICMPV4_H + LIBNET_IPV4_H + - lpacket.len, /* entire packet length */ - 0, /* tos */ - lpacket.id, /* ID */ - 0, /* fragmentation flags and offset */ - lpacket.ttl, /* TTL */ - IPPROTO_ICMP, /* protocol */ - 0, /* checksum */ - lpacket.src4, /* source address */ - lpacket.dst4, /* destination address */ - NULL, /* pointer to packet data (or NULL) */ - 0, /* payload length */ - c, /* libnet context pointer */ - 0)) < 0) /* packet id */ - { - SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ipv4 %s", libnet_geterror(c)); - goto cleanup; - } - - result = libnet_write(c); - if (result == -1) { - SCLogError(SC_ERR_LIBNET_WRITE_FAILED,"libnet_write_raw_ipv4 failed: %s", libnet_geterror(c)); - goto cleanup; - } - -cleanup: - libnet_destroy (c); - return 0; -} - -int RejectSendLibnet11L3IPv6TCP(ThreadVars *tv, Packet *p, void *data, int dir) -{ - - Libnet11Packet lpacket; - libnet_t *c; /* libnet context */ - char ebuf[LIBNET_ERRBUF_SIZE]; - int result; - char *devname = NULL; - - /* fill in struct defaults */ - lpacket.ttl = 0; - lpacket.id = 0; - lpacket.flow = 0; - lpacket.class = 0; - - if (IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode) && (p->livedev)) { - devname = p->livedev->dev; - } - if ((c = libnet_init(LIBNET_RAW6, devname, ebuf)) == NULL) { - SCLogError(SC_ERR_LIBNET_INIT,"libnet_init failed: %s", ebuf); - return 1; - } - - if (p->tcph == NULL) - return 1; - - /* save payload len */ - lpacket.dsize = p->payload_len; - - switch (dir) { - case REJECT_DIR_SRC: - SCLogDebug("sending a tcp reset to src"); - /* We follow http://tools.ietf.org/html/rfc793#section-3.4 : - * If packet has no ACK, the seq number is 0 and the ACK is built - * the normal way. If packet has a ACK, the seq of the RST packet - * is equal to the ACK of incoming packet and the ACK is build - * using packet sequence number and size of the data. */ - if (TCP_GET_ACK(p) == 0) { - lpacket.seq = 0; - lpacket.ack = TCP_GET_SEQ(p) + lpacket.dsize + 1; - } else { - lpacket.seq = TCP_GET_ACK(p); - lpacket.ack = TCP_GET_SEQ(p) + lpacket.dsize; - } - - lpacket.sp = TCP_GET_DST_PORT(p); - lpacket.dp = TCP_GET_SRC_PORT(p); - - memcpy(lpacket.src6.libnet_s6_addr, GET_IPV6_DST_ADDR(p), 16); - memcpy(lpacket.dst6.libnet_s6_addr, GET_IPV6_SRC_ADDR(p), 16); - - break; - case REJECT_DIR_DST: - SCLogDebug("sending a tcp reset to dst"); - lpacket.seq = TCP_GET_SEQ(p); - lpacket.ack = TCP_GET_ACK(p); - - lpacket.sp = TCP_GET_SRC_PORT(p); - lpacket.dp = TCP_GET_DST_PORT(p); - - memcpy(lpacket.src6.libnet_s6_addr, GET_IPV6_SRC_ADDR(p), 16); - memcpy(lpacket.dst6.libnet_s6_addr, GET_IPV6_DST_ADDR(p), 16); - break; - default: - SCLogError(SC_ERR_LIBNET_INVALID_DIR, - "reset not src or dst returning"); - return 1; - } - - lpacket.window = TCP_GET_WINDOW(p); - //lpacket.seq += lpacket.dsize; - - /* TODO come up with ttl calc function */ - lpacket.ttl = 64; - - /* build the package */ - if ((libnet_build_tcp( - lpacket.sp, /* source port */ - lpacket.dp, /* dst port */ - lpacket.seq, /* seq number */ - lpacket.ack, /* ack number */ - TH_RST|TH_ACK, /* flags */ - lpacket.window, /* window size */ - 0, /* checksum */ - 0, /* urgent flag */ - LIBNET_TCP_H, /* header length */ - NULL, /* payload */ - 0, /* payload length */ - c, /* libnet context */ - 0)) < 0) /* libnet ptag */ - { - SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_tcp %s", libnet_geterror(c)); - goto cleanup; - } - - if ((libnet_build_ipv6( - lpacket.class, /* traffic class */ - lpacket.flow, /* Flow label */ - LIBNET_TCP_H, /* payload length */ - IPPROTO_TCP, /* next header */ - lpacket.ttl, /* TTL */ - lpacket.src6, /* source address */ - lpacket.dst6, /* destination address */ - NULL, /* pointer to packet data (or NULL) */ - 0, /* payload length */ - c, /* libnet context pointer */ - 0)) < 0) /* packet id */ - { - SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ipv6 %s", libnet_geterror(c)); - goto cleanup; - } - - result = libnet_write(c); - if (result == -1) { - SCLogError(SC_ERR_LIBNET_WRITE_FAILED,"libnet_write failed: %s", libnet_geterror(c)); - goto cleanup; - } - -cleanup: - libnet_destroy (c); - return 0; -} - -#ifdef HAVE_LIBNET_ICMPV6_UNREACH -int RejectSendLibnet11L3IPv6ICMP(ThreadVars *tv, Packet *p, void *data, int dir) -{ - Libnet11Packet lpacket; - libnet_t *c; /* libnet context */ - char ebuf[LIBNET_ERRBUF_SIZE]; - int result; - char *devname = NULL; - - /* fill in struct defaults */ - lpacket.ttl = 0; - lpacket.id = 0; - lpacket.flow = 0; - lpacket.class = 0; - - - lpacket.len = IPV6_GET_PLEN(p) + IPV6_HEADER_LEN; - - if (IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode) && (p->livedev)) { - devname = p->livedev->dev; - } - if ((c = libnet_init(LIBNET_RAW6, devname, ebuf)) == NULL) { - SCLogError(SC_ERR_LIBNET_INIT,"libnet_inint failed: %s", ebuf); - return 1; - } - - switch (dir) { - case REJECT_DIR_SRC: - memcpy(lpacket.src6.libnet_s6_addr, GET_IPV6_DST_ADDR(p), 16); - memcpy(lpacket.dst6.libnet_s6_addr, GET_IPV6_SRC_ADDR(p), 16); - break; - case REJECT_DIR_DST: - memcpy(lpacket.src6.libnet_s6_addr, GET_IPV6_SRC_ADDR(p), 16); - memcpy(lpacket.dst6.libnet_s6_addr, GET_IPV6_DST_ADDR(p), 16); - break; - default: - SCLogError(SC_ERR_LIBNET_INVALID_DIR, - "reset not src or dst returning"); - return 1; - } - - /* TODO come up with ttl calc function */ - lpacket.ttl = 64; - - /* build the package */ - if ((libnet_build_icmpv6_unreach( - ICMP6_DST_UNREACH, /* type */ - ICMP6_DST_UNREACH_ADMIN, /* code */ - 0, /* checksum */ - (uint8_t *)p->ip6h, /* payload */ - lpacket.len, /* payload length */ - c, /* libnet context */ - 0)) < 0) /* libnet ptag */ - { - SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_icmpv6_unreach %s", libnet_geterror(c)); - goto cleanup; - } - - if ((libnet_build_ipv6( - lpacket.class, /* traffic class */ - lpacket.flow, /* Flow label */ - LIBNET_ICMPV6_H + lpacket.len, /* IPv6 payload length */ - IPPROTO_ICMPV6, /* next header */ - lpacket.ttl, /* TTL */ - lpacket.src6, /* source address */ - lpacket.dst6, /* destination address */ - NULL, /* pointer to packet data (or NULL) */ - 0, /* payload length */ - c, /* libnet context pointer */ - 0)) < 0) /* packet id */ - { - SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ipv6 %s", libnet_geterror(c)); - goto cleanup; - } - - result = libnet_write(c); - if (result == -1) { - SCLogError(SC_ERR_LIBNET_WRITE_FAILED,"libnet_write_raw_ipv6 failed: %s", libnet_geterror(c)); - goto cleanup; - } - -cleanup: - libnet_destroy (c); - return 0; -} -#else /* HAVE_LIBNET_ICMPV6_UNREACH */ - -int RejectSendLibnet11L3IPv6ICMP(ThreadVars *tv, Packet *p, void *data, int dir) -{ - SCLogError(SC_ERR_LIBNET_NOT_ENABLED, "Libnet ICMPv6 based rejects are disabled." - "Usually this means that you don't have a patched libnet installed," - " or configure couldn't find it."); - return 0; -} -#endif /* HAVE_LIBNET_ICMPV6_UNREACH */ - - -#else - -int RejectSendLibnet11L3IPv4TCP(ThreadVars *tv, Packet *p, void *data, int dir) -{ - SCLogError(SC_ERR_LIBNET_NOT_ENABLED, "Libnet based rejects are disabled." - "Usually this means that you don't have libnet installed," - " or configure couldn't find it."); - return 0; -} - -int RejectSendLibnet11L3IPv4ICMP(ThreadVars *tv, Packet *p, void *data, int dir) -{ - SCLogError(SC_ERR_LIBNET_NOT_ENABLED, "Libnet based rejects are disabled." - "Usually this means that you don't have libnet installed," - " or configure couldn't find it."); - return 0; -} - -int RejectSendLibnet11L3IPv6TCP(ThreadVars *tv, Packet *p, void *data, int dir) -{ - SCLogError(SC_ERR_LIBNET_NOT_ENABLED, "Libnet based rejects are disabled." - "Usually this means that you don't have libnet installed," - " or configure couldn't find it."); - return 0; -} - -int RejectSendLibnet11L3IPv6ICMP(ThreadVars *tv, Packet *p, void *data, int dir) -{ - SCLogError(SC_ERR_LIBNET_NOT_ENABLED, "Libnet based rejects are disabled." - "Usually this means that you don't have libnet installed," - " or configure couldn't find it."); - return 0; -} - -#endif /* HAVE_LIBNET11 */ diff --git a/framework/src/suricata/src/respond-reject-libnet11.h b/framework/src/suricata/src/respond-reject-libnet11.h deleted file mode 100644 index f2e605b9..00000000 --- a/framework/src/suricata/src/respond-reject-libnet11.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author William Metcalf - */ - -#ifndef __RESPOND_REJECT_LIBNET11_H__ -#define __RESPOND_REJECT_LIBNET11_H__ - -int RejectSendLibnet11L3IPv4TCP(ThreadVars *, Packet *, void *,int); -int RejectSendLibnet11L3IPv4ICMP(ThreadVars *, Packet *, void *,int); - -int RejectSendLibnet11L3IPv6TCP(ThreadVars *, Packet *, void *,int); -int RejectSendLibnet11L3IPv6ICMP(ThreadVars *, Packet *, void *,int); -#endif /* __RESPOND_REJECT_LIBNET11_H__ */ diff --git a/framework/src/suricata/src/respond-reject.c b/framework/src/suricata/src/respond-reject.c deleted file mode 100644 index ea756d7e..00000000 --- a/framework/src/suricata/src/respond-reject.c +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author William Metcalf - * - * RespondReject is a threaded wrapper for sending Rejects - * - * \todo RespondRejectFunc returns 1 on error, 0 on ok... why? For now it should - * just return 0 always, error handling is a TODO in the threading model (VJ) - */ - -#include "suricata-common.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "action-globals.h" - -#include "respond-reject.h" -#include "respond-reject-libnet11.h" - -#include "util-debug.h" -#include "util-privs.h" - -int RejectSendIPv4TCP(ThreadVars *, Packet *, void *); -int RejectSendIPv4ICMP(ThreadVars *, Packet *, void *); -int RejectSendIPv6TCP(ThreadVars *, Packet *, void *); -int RejectSendIPv6ICMP(ThreadVars *, Packet *, void *); - -void TmModuleRespondRejectRegister (void) -{ - tmm_modules[TMM_RESPONDREJECT].name = "RespondReject"; - tmm_modules[TMM_RESPONDREJECT].ThreadInit = NULL; - tmm_modules[TMM_RESPONDREJECT].Func = RespondRejectFunc; - tmm_modules[TMM_RESPONDREJECT].ThreadDeinit = NULL; - tmm_modules[TMM_RESPONDREJECT].RegisterTests = NULL; - tmm_modules[TMM_RESPONDREJECT].cap_flags = 0; /* libnet is not compat with caps */ -} - -TmEcode RespondRejectFunc(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - int ret = 0; - - /* ACTION_REJECT defaults to rejecting the SRC */ - if (!(PACKET_TEST_ACTION(p, ACTION_REJECT)) && - !(PACKET_TEST_ACTION(p, ACTION_REJECT_DST)) && - !(PACKET_TEST_ACTION(p, ACTION_REJECT_BOTH))) { - return TM_ECODE_OK; - } - - if (PKT_IS_IPV4(p)) { - if (PKT_IS_TCP(p)) { - ret = RejectSendIPv4TCP(tv, p, data); - } else { - ret = RejectSendIPv4ICMP(tv, p, data); - } - } else if (PKT_IS_IPV6(p)) { - if (PKT_IS_TCP(p)) { - ret = RejectSendIPv6TCP(tv, p, data); - } else { - ret = RejectSendIPv6ICMP(tv, p, data); - } - } else { - /* we're only supporting IPv4 and IPv6 */ - return TM_ECODE_OK; - } - - if (ret) - return TM_ECODE_FAILED; - else - return TM_ECODE_OK; -} - -int RejectSendIPv4TCP(ThreadVars *tv, Packet *p, void *data) -{ - SCEnter(); - int r = 0; - if (PACKET_TEST_ACTION(p, ACTION_REJECT)) { - r = RejectSendLibnet11L3IPv4TCP(tv, p, data, REJECT_DIR_SRC); - SCReturnInt(r); - } else if (PACKET_TEST_ACTION(p, ACTION_REJECT_DST)) { - r = RejectSendLibnet11L3IPv4TCP(tv, p, data, REJECT_DIR_DST); - SCReturnInt(r); - } else if(PACKET_TEST_ACTION(p, ACTION_REJECT_BOTH)) { - int ret; - ret = RejectSendLibnet11L3IPv4TCP(tv, p, data, REJECT_DIR_SRC); - if (RejectSendLibnet11L3IPv4TCP(tv, p, data, REJECT_DIR_DST) == 0) { - SCReturnInt(0); - } else { - SCReturnInt(ret); - } - } - SCReturnInt(0); -} - -int RejectSendIPv4ICMP(ThreadVars *tv, Packet *p, void *data) -{ - SCEnter(); - int r = 0; - if (PACKET_TEST_ACTION(p, ACTION_REJECT)) { - r = RejectSendLibnet11L3IPv4ICMP(tv, p, data, REJECT_DIR_SRC); - SCReturnInt(r); - } else if (PACKET_TEST_ACTION(p, ACTION_REJECT_DST)) { - r = RejectSendLibnet11L3IPv4ICMP(tv, p, data, REJECT_DIR_DST); - SCReturnInt(r); - } else if(PACKET_TEST_ACTION(p, ACTION_REJECT_BOTH)) { - int ret; - ret = RejectSendLibnet11L3IPv4ICMP(tv, p, data, REJECT_DIR_SRC); - if (RejectSendLibnet11L3IPv4ICMP(tv, p, data, REJECT_DIR_DST) == 0) { - SCReturnInt(0); - } else { - SCReturnInt(ret); - } - } - SCReturnInt(0); -} - -int RejectSendIPv6TCP(ThreadVars *tv, Packet *p, void *data) -{ - SCEnter(); - int r = 0; - if (PACKET_TEST_ACTION(p, ACTION_REJECT)) { - r = RejectSendLibnet11L3IPv6TCP(tv, p, data, REJECT_DIR_SRC); - SCReturnInt(r); - } else if (PACKET_TEST_ACTION(p, ACTION_REJECT_DST)) { - r = RejectSendLibnet11L3IPv6TCP(tv, p, data, REJECT_DIR_DST); - SCReturnInt(r); - } else if(PACKET_TEST_ACTION(p, ACTION_REJECT_BOTH)) { - int ret; - ret = RejectSendLibnet11L3IPv6TCP(tv, p, data, REJECT_DIR_SRC); - if (RejectSendLibnet11L3IPv6TCP(tv, p, data, REJECT_DIR_DST) == 0) { - SCReturnInt(0); - } else { - SCReturnInt(ret); - } - } - SCReturnInt(0); -} - -int RejectSendIPv6ICMP(ThreadVars *tv, Packet *p, void *data) -{ - SCEnter(); - int r = 0; - if (PACKET_TEST_ACTION(p, ACTION_REJECT)) { - r = RejectSendLibnet11L3IPv6ICMP(tv, p, data, REJECT_DIR_SRC); - SCReturnInt(r); - } else if (PACKET_TEST_ACTION(p, ACTION_REJECT_DST)) { - r = RejectSendLibnet11L3IPv6ICMP(tv, p, data, REJECT_DIR_DST); - SCReturnInt(r); - } else if(PACKET_TEST_ACTION(p, ACTION_REJECT_BOTH)) { - int ret; - ret = RejectSendLibnet11L3IPv6ICMP(tv, p, data, REJECT_DIR_SRC); - if (RejectSendLibnet11L3IPv6ICMP(tv, p, data, REJECT_DIR_DST) == 0) { - SCReturnInt(0); - } else { - SCReturnInt(ret); - } - } - SCReturnInt(0); -} - diff --git a/framework/src/suricata/src/respond-reject.h b/framework/src/suricata/src/respond-reject.h deleted file mode 100644 index 6a004f4d..00000000 --- a/framework/src/suricata/src/respond-reject.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author William Metcalf - */ - -#ifndef __RESPOND_REJECT_H__ -#define __RESPOND_REJECT_H__ - -#include "tm-threads.h" - -#define REJECT_DIR_SRC 0 -#define REJECT_DIR_DST 1 - -void TmModuleRespondRejectRegister (void); -TmEcode RespondRejectFunc(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); - -#endif /* __RESPOND_REJECT_H__ */ diff --git a/framework/src/suricata/src/runmode-af-packet.c b/framework/src/suricata/src/runmode-af-packet.c deleted file mode 100644 index fc17a4bd..00000000 --- a/framework/src/suricata/src/runmode-af-packet.c +++ /dev/null @@ -1,590 +0,0 @@ -/* Copyright (C) 2011,2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup afppacket - * - * @{ - */ - -/** - * \file - * - * \author Eric Leblond - * - * AF_PACKET socket runmode - * - */ - - -#include "suricata-common.h" -#include "config.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-af-packet.h" -#include "log-httplog.h" -#include "output.h" -#include "detect-engine-mpm.h" - -#include "alert-fastlog.h" -#include "alert-prelude.h" -#include "alert-unified2-alert.h" -#include "alert-debuglog.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-device.h" -#include "util-runmodes.h" -#include "util-ioctl.h" - -#include "source-af-packet.h" - -extern int max_pending_packets; - -static const char *default_mode_workers = NULL; - -const char *RunModeAFPGetDefaultMode(void) -{ - return default_mode_workers; -} - -void RunModeIdsAFPRegister(void) -{ - RunModeRegisterNewRunMode(RUNMODE_AFP_DEV, "single", - "Single threaded af-packet mode", - RunModeIdsAFPSingle); - RunModeRegisterNewRunMode(RUNMODE_AFP_DEV, "workers", - "Workers af-packet mode, each thread does all" - " tasks from acquisition to logging", - RunModeIdsAFPWorkers); - default_mode_workers = "workers"; - RunModeRegisterNewRunMode(RUNMODE_AFP_DEV, "autofp", - "Multi socket AF_PACKET mode. Packets from " - "each flow are assigned to a single detect " - "thread.", - RunModeIdsAFPAutoFp); - return; -} - -void AFPDerefConfig(void *conf) -{ - AFPIfaceConfig *pfp = (AFPIfaceConfig *)conf; - /* Pcap config is used only once but cost of this low. */ - if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) { - SCFree(pfp); - } -} - -/** - * \brief extract information from config file - * - * The returned structure will be freed by the thread init function. - * This is thus necessary to or copy the structure before giving it - * to thread or to reparse the file for each thread (and thus have - * new structure. - * - * \return a AFPIfaceConfig corresponding to the interface name - */ -void *ParseAFPConfig(const char *iface) -{ - char *threadsstr = NULL; - ConfNode *if_root; - ConfNode *if_default = NULL; - ConfNode *af_packet_node; - AFPIfaceConfig *aconf = SCMalloc(sizeof(*aconf)); - char *tmpclusterid; - char *tmpctype; - char *copymodestr; - intmax_t value; - int boolval; - char *bpf_filter = NULL; - char *out_iface = NULL; - - if (unlikely(aconf == NULL)) { - return NULL; - } - - if (iface == NULL) { - SCFree(aconf); - return NULL; - } - - strlcpy(aconf->iface, iface, sizeof(aconf->iface)); - aconf->threads = 1; - SC_ATOMIC_INIT(aconf->ref); - (void) SC_ATOMIC_ADD(aconf->ref, 1); - aconf->buffer_size = 0; - aconf->cluster_id = 1; - aconf->cluster_type = PACKET_FANOUT_HASH; - aconf->promisc = 1; - aconf->checksum_mode = CHECKSUM_VALIDATION_KERNEL; - aconf->DerefFunc = AFPDerefConfig; - aconf->flags = 0; - aconf->bpf_filter = NULL; - aconf->out_iface = NULL; - aconf->copy_mode = AFP_COPY_MODE_NONE; - - if (ConfGet("bpf-filter", &bpf_filter) == 1) { - if (strlen(bpf_filter) > 0) { - aconf->bpf_filter = bpf_filter; - SCLogInfo("Going to use command-line provided bpf filter '%s'", - aconf->bpf_filter); - } - } - - /* Find initial node */ - af_packet_node = ConfGetNode("af-packet"); - if (af_packet_node == NULL) { - SCLogInfo("Unable to find af-packet config using default value"); - return aconf; - } - - if_root = ConfNodeLookupKeyValue(af_packet_node, "interface", iface); - - if_default = ConfNodeLookupKeyValue(af_packet_node, "interface", "default"); - - if (if_root == NULL && if_default == NULL) { - SCLogInfo("Unable to find af-packet config for " - "interface \"%s\" or \"default\", using default value", - iface); - return aconf; - } - - /* If there is no setting for current interface use default one as main iface */ - if (if_root == NULL) { - if_root = if_default; - if_default = NULL; - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "threads", &threadsstr) != 1) { - aconf->threads = 0; - } else { - if (threadsstr != NULL) { - if (strcmp(threadsstr, "auto") == 0) { - aconf->threads = 0; - } else { - aconf->threads = (uint8_t)atoi(threadsstr); - } - } - } - if (aconf->threads == 0) { - int rss_queues; - aconf->threads = (int)UtilCpuGetNumProcessorsOnline(); - /* Get the number of RSS queues and take the min */ - rss_queues = GetIfaceRSSQueuesNum(iface); - if (rss_queues > 0) { - if (rss_queues < aconf->threads) { - aconf->threads = rss_queues; - SCLogInfo("More core than RSS queues, using %d threads for interface %s", - aconf->threads, iface); - } - } - if (aconf->threads) - SCLogInfo("Using %d AF_PACKET threads for interface %s", aconf->threads, iface); - } - if (aconf->threads <= 0) { - aconf->threads = 1; - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "copy-iface", &out_iface) == 1) { - if (strlen(out_iface) > 0) { - aconf->out_iface = out_iface; - } - } - - (void)ConfGetChildValueBoolWithDefault(if_root, if_default, "use-mmap", (int *)&boolval); - if (boolval) { - SCLogInfo("Enabling mmaped capture on iface %s", - aconf->iface); - aconf->flags |= AFP_RING_MODE; - } - (void)ConfGetChildValueBoolWithDefault(if_root, if_default, "use-emergency-flush", (int *)&boolval); - if (boolval) { - SCLogInfo("Enabling ring emergency flush on iface %s", - aconf->iface); - aconf->flags |= AFP_EMERGENCY_MODE; - } - - - aconf->copy_mode = AFP_COPY_MODE_NONE; - if (ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", ©modestr) == 1) { - if (aconf->out_iface == NULL) { - SCLogInfo("Copy mode activated but no destination" - " iface. Disabling feature"); - } else if (!(aconf->flags & AFP_RING_MODE)) { - SCLogInfo("Copy mode activated but use-mmap " - "set to no. Disabling feature"); - } else if (strlen(copymodestr) <= 0) { - aconf->out_iface = NULL; - } else if (strcmp(copymodestr, "ips") == 0) { - SCLogInfo("AF_PACKET IPS mode activated %s->%s", - iface, - aconf->out_iface); - aconf->copy_mode = AFP_COPY_MODE_IPS; - } else if (strcmp(copymodestr, "tap") == 0) { - SCLogInfo("AF_PACKET TAP mode activated %s->%s", - iface, - aconf->out_iface); - aconf->copy_mode = AFP_COPY_MODE_TAP; - } else { - SCLogInfo("Invalid mode (not in tap, ips)"); - } - } - - SC_ATOMIC_RESET(aconf->ref); - (void) SC_ATOMIC_ADD(aconf->ref, aconf->threads); - - if (ConfGetChildValueWithDefault(if_root, if_default, "cluster-id", &tmpclusterid) != 1) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config"); - } else { - aconf->cluster_id = (uint16_t)atoi(tmpclusterid); - SCLogDebug("Going to use cluster-id %" PRId32, aconf->cluster_id); - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "cluster-type", &tmpctype) != 1) { - SCLogError(SC_ERR_GET_CLUSTER_TYPE_FAILED,"Could not get cluster-type from config"); - } else if (strcmp(tmpctype, "cluster_round_robin") == 0) { - SCLogInfo("Using round-robin cluster mode for AF_PACKET (iface %s)", - aconf->iface); - aconf->cluster_type = PACKET_FANOUT_LB; - } else if (strcmp(tmpctype, "cluster_flow") == 0) { - /* In hash mode, we also ask for defragmentation needed to - * compute the hash */ - uint16_t defrag = 0; - int conf_val = 0; - SCLogInfo("Using flow cluster mode for AF_PACKET (iface %s)", - aconf->iface); - ConfGetChildValueBoolWithDefault(if_root, if_default, "defrag", &conf_val); - if (conf_val) { - SCLogInfo("Using defrag kernel functionality for AF_PACKET (iface %s)", - aconf->iface); - defrag = PACKET_FANOUT_FLAG_DEFRAG; - } - aconf->cluster_type = PACKET_FANOUT_HASH | defrag; - } else if (strcmp(tmpctype, "cluster_cpu") == 0) { - SCLogInfo("Using cpu cluster mode for AF_PACKET (iface %s)", - aconf->iface); - aconf->cluster_type = PACKET_FANOUT_CPU; - } else if (strcmp(tmpctype, "cluster_qm") == 0) { - SCLogInfo("Using queue based cluster mode for AF_PACKET (iface %s)", - aconf->iface); - aconf->cluster_type = PACKET_FANOUT_QM; - } else if (strcmp(tmpctype, "cluster_random") == 0) { - SCLogInfo("Using random based cluster mode for AF_PACKET (iface %s)", - aconf->iface); - aconf->cluster_type = PACKET_FANOUT_RND; - } else if (strcmp(tmpctype, "cluster_rollover") == 0) { - SCLogInfo("Using rollover based cluster mode for AF_PACKET (iface %s)", - aconf->iface); - aconf->cluster_type = PACKET_FANOUT_ROLLOVER; - - } else { - SCLogError(SC_ERR_INVALID_CLUSTER_TYPE,"invalid cluster-type %s",tmpctype); - SCFree(aconf); - return NULL; - } - - int conf_val = 0; - ConfGetChildValueBoolWithDefault(if_root, if_default, "rollover", &conf_val); - if (conf_val) { - SCLogInfo("Using rollover kernel functionality for AF_PACKET (iface %s)", - aconf->iface); - aconf->cluster_type |= PACKET_FANOUT_FLAG_ROLLOVER; - } - - /*load af_packet bpf filter*/ - /* command line value has precedence */ - if (ConfGet("bpf-filter", &bpf_filter) != 1) { - if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", &bpf_filter) == 1) { - if (strlen(bpf_filter) > 0) { - aconf->bpf_filter = bpf_filter; - SCLogInfo("Going to use bpf filter %s", aconf->bpf_filter); - } - } - } - - if ((ConfGetChildValueIntWithDefault(if_root, if_default, "buffer-size", &value)) == 1) { - aconf->buffer_size = value; - } else { - aconf->buffer_size = 0; - } - if ((ConfGetChildValueIntWithDefault(if_root, if_default, "ring-size", &value)) == 1) { - aconf->ring_size = value; - if (value * aconf->threads < max_pending_packets) { - aconf->ring_size = max_pending_packets / aconf->threads + 1; - SCLogWarning(SC_ERR_AFP_CREATE, "Inefficient setup: ring-size < max_pending_packets. " - "Resetting to decent value %d.", aconf->ring_size); - /* We want at least that max_pending_packets packets can be handled by the - * interface. This is generous if we have multiple interfaces listening. */ - } - } else { - /* We want that max_pending_packets packets can be handled by suricata - * for this interface. To take burst into account we multiply the obtained - * size by 2. */ - aconf->ring_size = max_pending_packets * 2 / aconf->threads; - } - - (void)ConfGetChildValueBoolWithDefault(if_root, if_default, "disable-promisc", (int *)&boolval); - if (boolval) { - SCLogInfo("Disabling promiscuous mode on iface %s", - aconf->iface); - aconf->promisc = 0; - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "checksum-checks", &tmpctype) == 1) { - if (strcmp(tmpctype, "auto") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_AUTO; - } else if (strcmp(tmpctype, "yes") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_ENABLE; - } else if (strcmp(tmpctype, "no") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_DISABLE; - } else if (strcmp(tmpctype, "kernel") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_KERNEL; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid value for checksum-checks for %s", aconf->iface); - } - } - - if (GetIfaceOffloading(iface) == 1) { - SCLogWarning(SC_ERR_AFP_CREATE, - "Using AF_PACKET with GRO or LRO activated can lead to capture problems"); - } - - return aconf; -} - -int AFPConfigGeThreadsCount(void *conf) -{ - AFPIfaceConfig *afp = (AFPIfaceConfig *)conf; - return afp->threads; -} - -int AFPRunModeIsIPS() -{ - int nlive = LiveGetDeviceCount(); - int ldev; - ConfNode *if_root; - ConfNode *if_default = NULL; - ConfNode *af_packet_node; - int has_ips = 0; - int has_ids = 0; - - /* Find initial node */ - af_packet_node = ConfGetNode("af-packet"); - if (af_packet_node == NULL) { - return 0; - } - - if_default = ConfNodeLookupKeyValue(af_packet_node, "interface", "default"); - - for (ldev = 0; ldev < nlive; ldev++) { - char *live_dev = LiveGetDeviceName(ldev); - if (live_dev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); - return 0; - } - char *copymodestr = NULL; - if_root = ConfNodeLookupKeyValue(af_packet_node, "interface", live_dev); - - if (if_root == NULL) { - if (if_default == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); - return 0; - } - if_root = if_default; - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", ©modestr) == 1) { - if (strcmp(copymodestr, "ips") == 0) { - has_ips = 1; - } else { - has_ids = 1; - } - } else { - has_ids = 1; - } - } - - if (has_ids && has_ips) { - SCLogInfo("AF_PACKET mode using IPS and IDS mode"); - for (ldev = 0; ldev < nlive; ldev++) { - char *live_dev = LiveGetDeviceName(ldev); - if (live_dev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); - return 0; - } - if_root = ConfNodeLookupKeyValue(af_packet_node, "interface", live_dev); - char *copymodestr = NULL; - - if (if_root == NULL) { - if (if_default == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); - return 0; - } - if_root = if_default; - } - - if (! ((ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", ©modestr) == 1) && - (strcmp(copymodestr, "ips") == 0))) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "AF_PACKET IPS mode used and interface '%s' is in IDS or TAP mode. " - "Sniffing '%s' but expect bad result as stream-inline is activated.", - live_dev, live_dev); - } - } - } - - return has_ips; -} - -int RunModeIdsAFPAutoFp(void) -{ - SCEnter(); - -/* We include only if AF_PACKET is enabled */ -#ifdef HAVE_AF_PACKET - int ret; - char *live_dev = NULL; - - RunModeInitialize(); - - TimeModeSetLive(); - - (void)ConfGet("af-packet.live-interface", &live_dev); - - SCLogDebug("live_dev %s", live_dev); - - if (AFPPeersListInit() != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "Unable to init peers list."); - exit(EXIT_FAILURE); - } - - ret = RunModeSetLiveCaptureAutoFp(ParseAFPConfig, - AFPConfigGeThreadsCount, - "ReceiveAFP", - "DecodeAFP", "RxAFP", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - /* In IPS mode each threads must have a peer */ - if (AFPPeersListCheck() != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "Some IPS capture threads did not peer."); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsAFPAutoFp initialised"); -#endif /* HAVE_AF_PACKET */ - - SCReturnInt(0); -} - -/** - * \brief Single thread version of the AF_PACKET processing. - */ -int RunModeIdsAFPSingle(void) -{ - SCEnter(); -#ifdef HAVE_AF_PACKET - int ret; - char *live_dev = NULL; - - RunModeInitialize(); - TimeModeSetLive(); - - (void)ConfGet("af-packet.live-interface", &live_dev); - - if (AFPPeersListInit() != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "Unable to init peers list."); - exit(EXIT_FAILURE); - } - - ret = RunModeSetLiveCaptureSingle(ParseAFPConfig, - AFPConfigGeThreadsCount, - "ReceiveAFP", - "DecodeAFP", "AFPacket", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - /* In IPS mode each threads must have a peer */ - if (AFPPeersListCheck() != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "Some IPS capture threads did not peer."); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsAFPSingle initialised"); - -#endif /* HAVE_AF_PACKET */ - SCReturnInt(0); -} - -/** - * \brief Workers version of the AF_PACKET processing. - * - * Start N threads with each thread doing all the work. - * - */ -int RunModeIdsAFPWorkers(void) -{ - SCEnter(); -#ifdef HAVE_AF_PACKET - int ret; - char *live_dev = NULL; - - RunModeInitialize(); - TimeModeSetLive(); - - (void)ConfGet("af-packet.live-interface", &live_dev); - - if (AFPPeersListInit() != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "Unable to init peers list."); - exit(EXIT_FAILURE); - } - - ret = RunModeSetLiveCaptureWorkers(ParseAFPConfig, - AFPConfigGeThreadsCount, - "ReceiveAFP", - "DecodeAFP", "AFPacket", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - /* In IPS mode each threads must have a peer */ - if (AFPPeersListCheck() != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "Some IPS capture threads did not peer."); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsAFPWorkers initialised"); - -#endif /* HAVE_AF_PACKET */ - SCReturnInt(0); -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/runmode-af-packet.h b/framework/src/suricata/src/runmode-af-packet.h deleted file mode 100644 index 79fe436a..00000000 --- a/framework/src/suricata/src/runmode-af-packet.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Eric Leblond - */ - -#ifndef __RUNMODE_AF_PACKET_H__ -#define __RUNMODE_AF_PACKET_H__ - -int RunModeIdsAFPSingle(void); -int RunModeIdsAFPAutoFp(void); -int RunModeIdsAFPWorkers(void); -void RunModeIdsAFPRegister(void); -const char *RunModeAFPGetDefaultMode(void); -int AFPRunModeIsIPS(); - -#endif /* __RUNMODE_AF_PACKET_H__ */ diff --git a/framework/src/suricata/src/runmode-erf-dag.c b/framework/src/suricata/src/runmode-erf-dag.c deleted file mode 100644 index 5653b9ec..00000000 --- a/framework/src/suricata/src/runmode-erf-dag.c +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-erf-dag.h" -#include "output.h" - -#include "detect-engine.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-runmodes.h" - -static const char *default_mode; - -static int DagConfigGetThreadCount(void *conf) -{ - return 1; -} - -static void *ParseDagConfig(const char *iface) -{ - return (void *)iface; -} - -const char *RunModeErfDagGetDefaultMode(void) -{ - return default_mode; -} - -void RunModeErfDagRegister(void) -{ - default_mode = "autofp"; - - RunModeRegisterNewRunMode(RUNMODE_DAG, "autofp", - "Multi threaded DAG mode. Packets from " - "each flow are assigned to a single detect " - "thread, unlike \"dag_auto\" where packets " - "from the same flow can be processed by any " - "detect thread", - RunModeIdsErfDagAutoFp); - - RunModeRegisterNewRunMode(RUNMODE_DAG, "single", - "Singled threaded DAG mode", - RunModeIdsErfDagSingle); - - RunModeRegisterNewRunMode(RUNMODE_DAG, "workers", - "Workers DAG mode, each thread does all " - " tasks from acquisition to logging", - RunModeIdsErfDagWorkers); - - return; -} - -int RunModeIdsErfDagSingle(void) -{ - int ret; - - SCEnter(); - - RunModeInitialize(); - - TimeModeSetLive(); - - ret = RunModeSetLiveCaptureSingle(ParseDagConfig, - DagConfigGetThreadCount, - "ReceiveErfDag", - "DecodeErfDag", - "RxDAG", - NULL); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "DAG single runmode failed to start"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsDagSingle initialised"); - - SCReturnInt(0); -} - -int RunModeIdsErfDagAutoFp(void) -{ - int ret; - - SCEnter(); - - RunModeInitialize(); - - TimeModeSetLive(); - - ret = RunModeSetLiveCaptureAutoFp(ParseDagConfig, - DagConfigGetThreadCount, - "ReceiveErfDag", - "DecodeErfDag", - "RxDAG", - NULL); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "DAG autofp runmode failed to start"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsDagAutoFp initialised"); - - SCReturnInt(0); -} - -int RunModeIdsErfDagWorkers(void) -{ - int ret; - - SCEnter(); - - RunModeInitialize(); - - TimeModeSetLive(); - - ret = RunModeSetLiveCaptureWorkers(ParseDagConfig, - DagConfigGetThreadCount, - "ReceiveErfDag", - "DecodeErfDag", - "RxDAG", - NULL); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "DAG workers runmode failed to start"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsErfDagWorkers initialised"); - - SCReturnInt(0); -} diff --git a/framework/src/suricata/src/runmode-erf-dag.h b/framework/src/suricata/src/runmode-erf-dag.h deleted file mode 100644 index c4b2a59c..00000000 --- a/framework/src/suricata/src/runmode-erf-dag.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __RUNMODE_ERF_DAG_H__ -#define __RUNMODE_ERF_DAG_H__ - -int RunModeIdsErfDagAutoFp(void); -int RunModeIdsErfDagSingle(void); -int RunModeIdsErfDagWorkers(void); -void RunModeErfDagRegister(void); -const char *RunModeErfDagGetDefaultMode(void); - -#endif /* __RUNMODE_ERF_DAG_H__ */ diff --git a/framework/src/suricata/src/runmode-erf-file.c b/framework/src/suricata/src/runmode-erf-file.c deleted file mode 100644 index 19dbb683..00000000 --- a/framework/src/suricata/src/runmode-erf-file.c +++ /dev/null @@ -1,279 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-erf-file.h" -#include "output.h" - -#include "detect-engine.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" - -#include "util-runmodes.h" - -static const char *default_mode; - -const char *RunModeErfFileGetDefaultMode(void) -{ - return default_mode; -} - -void RunModeErfFileRegister(void) -{ - default_mode = "autofp"; - - RunModeRegisterNewRunMode(RUNMODE_ERF_FILE, "single", - "Single threaded ERF file mode", - RunModeErfFileSingle); - - RunModeRegisterNewRunMode(RUNMODE_ERF_FILE, "autofp", - "Multi threaded ERF file mode. Packets from " - "each flow are assigned to a single detect thread", - RunModeErfFileAutoFp); - - return; -} - -int RunModeErfFileSingle(void) -{ - char *file; - - SCEnter(); - - if (ConfGet("erf-file.file", &file) == 0) { - SCLogError(SC_ERR_RUNMODE, "Failed to get erf-file.file from config."); - exit(EXIT_FAILURE); - } - - RunModeInitialize(); - - TimeModeSetOffline(); - - /* Basically the same setup as PCAP files. */ - - ThreadVars *tv = TmThreadCreatePacketHandler("ErfFile", - "packetpool", "packetpool", - "packetpool", "packetpool", - "pktacqloop"); - if (tv == NULL) { - printf("ERROR: TmThreadsCreate failed\n"); - exit(EXIT_FAILURE); - } - - TmModule *tm_module = TmModuleGetByName("ReceiveErfFile"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName failed for ReceiveErfFile\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, file); - - tm_module = TmModuleGetByName("DecodeErfFile"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName DecodeErfFile failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - tm_module = TmModuleGetByName("StreamTcp"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName StreamTcp failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - if (DetectEngineEnabled()) { - tm_module = TmModuleGetByName("Detect"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName Detect failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - } - - SetupOutputs(tv); - - if (TmThreadSpawn(tv) != TM_ECODE_OK) { - printf("ERROR: TmThreadSpawn failed\n"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeErfFileSingle initialised"); - - SCReturnInt(0); -} - -int RunModeErfFileAutoFp(void) -{ - SCEnter(); - char tname[TM_THREAD_NAME_MAX]; - char qname[TM_QUEUE_NAME_MAX]; - uint16_t cpu = 0; - char *queues = NULL; - int thread; - - RunModeInitialize(); - RunmodeSetFlowStreamAsync(); - - char *file = NULL; - if (ConfGet("erf-file.file", &file) == 0) { - SCLogError(SC_ERR_RUNMODE, - "Failed retrieving erf-file.file from config"); - exit(EXIT_FAILURE); - } - - TimeModeSetOffline(); - - /* Available cpus */ - uint16_t ncpus = UtilCpuGetNumProcessorsOnline(); - - /* start with cpu 1 so that if we're creating an odd number of detect - * threads we're not creating the most on CPU0. */ - if (ncpus > 0) - cpu = 1; - - /* always create at least one thread */ - int thread_max = TmThreadGetNbThreads(DETECT_CPU_SET); - if (thread_max == 0) - thread_max = ncpus * threading_detect_ratio; - if (thread_max < 1) - thread_max = 1; - - queues = RunmodeAutoFpCreatePickupQueuesString(thread_max); - if (queues == NULL) { - SCLogError(SC_ERR_RUNMODE, "RunmodeAutoFpCreatePickupQueuesString failed"); - exit(EXIT_FAILURE); - } - - /* create the threads */ - ThreadVars *tv = - TmThreadCreatePacketHandler("ReceiveErfFile", - "packetpool", "packetpool", - queues, "flow", - "pktacqloop"); - SCFree(queues); - - if (tv == NULL) { - printf("ERROR: TmThreadsCreate failed\n"); - exit(EXIT_FAILURE); - } - TmModule *tm_module = TmModuleGetByName("ReceiveErfFile"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName failed for ReceiveErfFile\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, file); - - tm_module = TmModuleGetByName("DecodeErfFile"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName DecodeErfFile failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - if (threading_set_cpu_affinity) { - TmThreadSetCPUAffinity(tv, 0); - if (ncpus > 1) - TmThreadSetThreadPriority(tv, PRIO_MEDIUM); - } - - if (TmThreadSpawn(tv) != TM_ECODE_OK) { - printf("ERROR: TmThreadSpawn failed\n"); - exit(EXIT_FAILURE); - } - - for (thread = 0; thread < thread_max; thread++) { - snprintf(tname, sizeof(tname), "Detect%d", thread+1); - snprintf(qname, sizeof(qname), "pickup%d", thread+1); - - SCLogDebug("tname %s, qname %s", tname, qname); - - char *thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - printf("ERROR: Can't allocate thread name\n"); - exit(EXIT_FAILURE); - } - SCLogDebug("Assigning %s affinity to cpu %u", thread_name, cpu); - - ThreadVars *tv_detect_ncpu = - TmThreadCreatePacketHandler(thread_name, - qname, "flow", - "packetpool", "packetpool", - "varslot"); - if (tv_detect_ncpu == NULL) { - printf("ERROR: TmThreadsCreate failed\n"); - exit(EXIT_FAILURE); - } - tm_module = TmModuleGetByName("StreamTcp"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName StreamTcp failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL); - - if (DetectEngineEnabled()) { - tm_module = TmModuleGetByName("Detect"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName Detect failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL); - } - - if (threading_set_cpu_affinity) { - TmThreadSetCPUAffinity(tv_detect_ncpu, (int)cpu); - /* If we have more than one core/cpu, the first Detect thread - * (at cpu 0) will have less priority (higher 'nice' value) - * In this case we will set the thread priority to +10 (default is 0) - */ - if (cpu == 0 && ncpus > 1) { - TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_LOW); - } else if (ncpus > 1) { - TmThreadSetThreadPriority(tv_detect_ncpu, PRIO_MEDIUM); - } - } - - char *thread_group_name = SCStrdup("Detect"); - if (unlikely(thread_group_name == NULL)) { - printf("Error allocating memory\n"); - exit(EXIT_FAILURE); - } - tv_detect_ncpu->thread_group_name = thread_group_name; - - /* add outputs as well */ - SetupOutputs(tv_detect_ncpu); - - if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) { - printf("ERROR: TmThreadSpawn failed\n"); - exit(EXIT_FAILURE); - } - - if ((cpu + 1) == ncpus) - cpu = 0; - else - cpu++; - } - - SCLogInfo("RunModeErfFileAutoFp initialised"); - - SCReturnInt(0); -} diff --git a/framework/src/suricata/src/runmode-erf-file.h b/framework/src/suricata/src/runmode-erf-file.h deleted file mode 100644 index 54a8ba89..00000000 --- a/framework/src/suricata/src/runmode-erf-file.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __RUNMODE_ERF_FILE_H__ -#define __RUNMODE_ERF_FILE_H__ - -int RunModeErfFileSingle(void); -int RunModeErfFileAutoFp(void); -void RunModeErfFileRegister(void); -const char *RunModeErfFileGetDefaultMode(void); - -#endif /* __RUNMODE_ERF_FILE_H__ */ diff --git a/framework/src/suricata/src/runmode-ipfw.c b/framework/src/suricata/src/runmode-ipfw.c deleted file mode 100644 index 841692e1..00000000 --- a/framework/src/suricata/src/runmode-ipfw.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Eric Leblond - * - * Handling of ipfw runmodes. - */ - - - -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-ipfw.h" -#include "output.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-runmodes.h" -#include "source-ipfw.h" -#include "util-device.h" - -static const char *default_mode; - -const char *RunModeIpsIPFWGetDefaultMode(void) -{ - return default_mode; -} - -void RunModeIpsIPFWRegister(void) -{ - default_mode = "autofp"; - - RunModeRegisterNewRunMode(RUNMODE_IPFW, "autofp", - "Multi threaded IPFW IPS mode with respect to flow", - RunModeIpsIPFWAutoFp); - - RunModeRegisterNewRunMode(RUNMODE_IPFW, "workers", - "Multi queue IPFW IPS mode with one thread per queue", - RunModeIpsIPFWWorker); - - return; -} - -int RunModeIpsIPFWAutoFp(void) -{ - SCEnter(); - int ret = 0; -#ifdef IPFW - - RunModeInitialize(); - - TimeModeSetLive(); - - LiveDeviceHasNoStats(); - - ret = RunModeSetIPSAutoFp(IPFWGetThread, - "ReceiveIPFW", - "VerdictIPFW", - "DecodeIPFW"); -#endif /* IPFW */ - return ret; -} - -int RunModeIpsIPFWWorker(void) -{ - SCEnter(); - int ret = 0; -#ifdef IPFW - - RunModeInitialize(); - - TimeModeSetLive(); - - LiveDeviceHasNoStats(); - - ret = RunModeSetIPSWorker(IPFWGetThread, - "ReceiveIPFW", - "VerdictIPFW", - "DecodeIPFW"); -#endif /* IPFW */ - return ret; -} diff --git a/framework/src/suricata/src/runmode-ipfw.h b/framework/src/suricata/src/runmode-ipfw.h deleted file mode 100644 index 5c8345b1..00000000 --- a/framework/src/suricata/src/runmode-ipfw.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __RUNMODE_IPFW_H__ -#define __RUNMODE_IPFW_H__ - -int RunModeIpsIPFWAutoFp(void); -int RunModeIpsIPFWWorker(void); -void RunModeIpsIPFWRegister(void); -const char *RunModeIpsIPFWGetDefaultMode(void); - -#endif /* __RUNMODE_IPFW_H__ */ diff --git a/framework/src/suricata/src/runmode-napatech.c b/framework/src/suricata/src/runmode-napatech.c deleted file mode 100644 index 7c161ad8..00000000 --- a/framework/src/suricata/src/runmode-napatech.c +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author nPulse Technologies, LLC. - * \author Matt Keeler - */ -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "output.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-runmodes.h" -#include "util-device.h" - -#include "runmode-napatech.h" - -// need NapatechStreamDevConf structure -#include "source-napatech.h" - -#define NT_RUNMODE_AUTOFP 1 -#define NT_RUNMODE_WORKERS 2 - -static const char *default_mode = NULL; -#ifdef HAVE_NAPATECH -static int num_configured_streams = 0; -#endif - -const char *RunModeNapatechGetDefaultMode(void) -{ - return default_mode; -} - -void RunModeNapatechRegister(void) -{ -#ifdef HAVE_NAPATECH - default_mode = "autofp"; - RunModeRegisterNewRunMode(RUNMODE_NAPATECH, "autofp", - "Multi threaded Napatech mode. Packets from " - "each flow are assigned to a single detect " - "thread instead of any detect thread", - RunModeNapatechAutoFp); - RunModeRegisterNewRunMode(RUNMODE_NAPATECH, "workers", - "Workers Napatech mode, each thread does all" - " tasks from acquisition to logging", - RunModeNapatechWorkers); - return; -#endif -} - -#ifdef HAVE_NAPATECH -int NapatechRegisterDeviceStreams() -{ - NtInfoStream_t info_stream; - NtInfo_t info; - char error_buf[100]; - int status; - int i; - char live_dev_buf[9]; - int use_all_streams; - ConfNode *ntstreams; - ConfNode *stream_id; - - if (ConfGetBool("napatech.use-all-streams", &use_all_streams) == 0) - { - SCLogError(SC_ERR_RUNMODE, "Failed retrieving napatech.use-all-streams from Conf"); - exit(EXIT_FAILURE); - } - - if (use_all_streams) - { - SCLogInfo("Using All Napatech Streams"); - // When using the default streams we need to query the service for a list of all configured - if ((status = NT_InfoOpen(&info_stream, "SuricataStreamInfo")) != NT_SUCCESS) - { - NT_ExplainError(status, error_buf, sizeof(error_buf) -1); - SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "NT_InfoOpen failed: %s", error_buf); - return -1; - } - - info.cmd = NT_INFO_CMD_READ_STREAM; - if ((status = NT_InfoRead(info_stream, &info)) != NT_SUCCESS) - { - NT_ExplainError(status, error_buf, sizeof(error_buf) -1); - SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "NT_InfoRead failed: %s", error_buf); - return -1; - } - - num_configured_streams = info.u.stream.data.count; - for (i = 0; i < num_configured_streams; i++) - { - // The Stream IDs do not have to be sequential - snprintf(live_dev_buf, sizeof(live_dev_buf), "nt%d", info.u.stream.data.streamIDList[i]); - LiveRegisterDevice(live_dev_buf); - } - - if ((status = NT_InfoClose(info_stream)) != NT_SUCCESS) - { - NT_ExplainError(status, error_buf, sizeof(error_buf) -1); - SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "NT_InfoClose failed: %s", error_buf); - return -1; - } - } - else - { - SCLogInfo("Using Selected Napatech Streams"); - // When not using the default streams we need to parse the array of streams from the conf - if ((ntstreams = ConfGetNode("napatech.streams")) == NULL) - { - SCLogError(SC_ERR_RUNMODE, "Failed retrieving napatech.streams from Conf"); - exit(EXIT_FAILURE); - } - - // Loop through all stream numbers in the array and register the devices - TAILQ_FOREACH(stream_id, &ntstreams->head, next) - { - if (stream_id == NULL) - { - SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "Couldn't Parse Stream Configuration"); - exit(EXIT_FAILURE); - } - num_configured_streams++; - - snprintf(live_dev_buf, sizeof(live_dev_buf), "nt%d", atoi(stream_id->val)); - LiveRegisterDevice(live_dev_buf); - } - } - return 0; -} - -void *NapatechConfigParser(const char *device) -{ - // Expect device to be of the form nt%d where %d is the stream id to use - int dev_len = strlen(device); - struct NapatechStreamDevConf *conf = SCMalloc(sizeof(struct NapatechStreamDevConf)); - if (unlikely(conf == NULL)) - return NULL; - if (dev_len < 3 || dev_len > 5) - { - SCLogError(SC_ERR_NAPATECH_PARSE_CONFIG, "Could not parse config for device: %s - invalid length", device); - return NULL; - } - - // device+5 is a pointer to the beginning of the stream id after the constant nt portion - conf->stream_id = atoi(device+2); - - // Set the host buffer allowance for this stream - // Right now we just look at the global default - there is no per-stream hba configuration - if (ConfGetInt("napatech.hba", &conf->hba) == 0) - conf->hba = -1; - - return (void *) conf; -} - -int NapatechGetThreadsCount(void *conf __attribute__((unused))) { - // No matter which live device it is there is no reason to ever use more than 1 thread - // 2 or more thread would cause packet duplication - return 1; -} - -static int NapatechInit(int runmode) -{ - int ret; - char errbuf[100]; - - RunModeInitialize(); - TimeModeSetLive(); - - /* Initialize the API and check version compatibility */ - if ((ret = NT_Init(NTAPI_VERSION)) != NT_SUCCESS) { - NT_ExplainError(ret, errbuf, sizeof(errbuf)); - SCLogError(SC_ERR_NAPATECH_INIT_FAILED ,"NT_Init failed. Code 0x%X = %s", ret, errbuf); - exit(EXIT_FAILURE); - } - - ret = NapatechRegisterDeviceStreams(); - if (ret < 0 || num_configured_streams <= 0) { - SCLogError(SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, "Unable to setup up Napatech Streams"); - exit(EXIT_FAILURE); - } - - switch(runmode) { - case NT_RUNMODE_AUTOFP: - ret = RunModeSetLiveCaptureAutoFp(NapatechConfigParser, NapatechGetThreadsCount, - "NapatechStream", "NapatechDecode", - "RxNT", NULL); - break; - case NT_RUNMODE_WORKERS: - ret = RunModeSetLiveCaptureWorkers(NapatechConfigParser, NapatechGetThreadsCount, - "NapatechStream", "NapatechDecode", - "RxNT", NULL); - break; - default: - ret = -1; - } - - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Runmode start failed"); - exit(EXIT_FAILURE); - } - return 0; -} - -int RunModeNapatechAutoFp(void) -{ - return NapatechInit(NT_RUNMODE_AUTOFP); -} - -int RunModeNapatechWorkers(void) -{ - return NapatechInit(NT_RUNMODE_WORKERS); -} - -#endif diff --git a/framework/src/suricata/src/runmode-napatech.h b/framework/src/suricata/src/runmode-napatech.h deleted file mode 100644 index d10b4063..00000000 --- a/framework/src/suricata/src/runmode-napatech.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \autor nPulse Technologies, LLC. - * \author Matt Keeler - */ - -#ifndef __RUNMODE_NAPATECH_H__ -#define __RUNMODE_NAPATECH_H__ - -#ifdef HAVE_NAPATECH -#include -#endif - -int RunModeNapatechAutoFp(void); -int RunModeNapatechWorkers(void); -void RunModeNapatechRegister(void); -const char *RunModeNapatechGetDefaultMode(void); - -#endif /* __RUNMODE_NAPATECH_H__ */ diff --git a/framework/src/suricata/src/runmode-netmap.c b/framework/src/suricata/src/runmode-netmap.c deleted file mode 100644 index 3289275e..00000000 --- a/framework/src/suricata/src/runmode-netmap.c +++ /dev/null @@ -1,459 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** -* \ingroup netmap -* -* @{ -*/ - -/** -* \file -* -* \author Aleksey Katargin -* -* Netmap runmode -* -*/ - -#include "suricata-common.h" -#include "config.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-netmap.h" -#include "log-httplog.h" -#include "output.h" -#include "detect-engine-mpm.h" - -#include "alert-fastlog.h" -#include "alert-prelude.h" -#include "alert-unified2-alert.h" -#include "alert-debuglog.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-device.h" -#include "util-runmodes.h" -#include "util-ioctl.h" - -#include "source-netmap.h" - -extern int max_pending_packets; - -static const char *default_mode_workers = NULL; - -const char *RunModeNetmapGetDefaultMode(void) -{ - return default_mode_workers; -} - -void RunModeIdsNetmapRegister(void) -{ - RunModeRegisterNewRunMode(RUNMODE_NETMAP, "single", - "Single threaded netmap mode", - RunModeIdsNetmapSingle); - RunModeRegisterNewRunMode(RUNMODE_NETMAP, "workers", - "Workers netmap mode, each thread does all" - " tasks from acquisition to logging", - RunModeIdsNetmapWorkers); - default_mode_workers = "workers"; - RunModeRegisterNewRunMode(RUNMODE_NETMAP, "autofp", - "Multi threaded netmap mode. Packets from " - "each flow are assigned to a single detect " - "thread.", - RunModeIdsNetmapAutoFp); - return; -} - -#ifdef HAVE_NETMAP - -static void NetmapDerefConfig(void *conf) -{ - NetmapIfaceConfig *pfp = (NetmapIfaceConfig *)conf; - /* config is used only once but cost of this low. */ - if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) { - SCFree(pfp); - } -} - -/** -* \brief extract information from config file -* -* The returned structure will be freed by the thread init function. -* This is thus necessary to or copy the structure before giving it -* to thread or to reparse the file for each thread (and thus have -* new structure. -* -* \return a NetmapIfaceConfig corresponding to the interface name -*/ -static void *ParseNetmapConfig(const char *iface_name) -{ - char *threadsstr = NULL; - ConfNode *if_root; - ConfNode *if_default = NULL; - ConfNode *netmap_node; - NetmapIfaceConfig *aconf = SCMalloc(sizeof(*aconf)); - char *tmpctype; - char *copymodestr; - int boolval; - char *bpf_filter = NULL; - char *out_iface = NULL; - - if (unlikely(aconf == NULL)) { - return NULL; - } - - if (iface_name == NULL) { - SCFree(aconf); - return NULL; - } - - memset(aconf, 0, sizeof(*aconf)); - aconf->DerefFunc = NetmapDerefConfig; - aconf->threads = 1; - aconf->promisc = 1; - aconf->checksum_mode = CHECKSUM_VALIDATION_AUTO; - aconf->copy_mode = NETMAP_COPY_MODE_NONE; - strlcpy(aconf->iface_name, iface_name, sizeof(aconf->iface_name)); - SC_ATOMIC_INIT(aconf->ref); - (void) SC_ATOMIC_ADD(aconf->ref, 1); - - strlcpy(aconf->iface, aconf->iface_name, sizeof(aconf->iface)); - if (aconf->iface[0]) { - size_t len = strlen(aconf->iface); - if (aconf->iface[len-1] == '+') { - aconf->iface[len-1] = '\0'; - aconf->iface_sw = 1; - } - } - - if (ConfGet("bpf-filter", &bpf_filter) == 1) { - if (strlen(bpf_filter) > 0) { - aconf->bpf_filter = bpf_filter; - SCLogInfo("Going to use command-line provided bpf filter '%s'", - aconf->bpf_filter); - } - } - - /* Find initial node */ - netmap_node = ConfGetNode("netmap"); - if (netmap_node == NULL) { - SCLogInfo("Unable to find netmap config using default value"); - return aconf; - } - - if_root = ConfNodeLookupKeyValue(netmap_node, "interface", aconf->iface_name); - - if_default = ConfNodeLookupKeyValue(netmap_node, "interface", "default"); - - if (if_root == NULL && if_default == NULL) { - SCLogInfo("Unable to find netmap config for " - "interface \"%s\" or \"default\", using default value", - aconf->iface_name); - return aconf; - } - - /* If there is no setting for current interface use default one as main iface */ - if (if_root == NULL) { - if_root = if_default; - if_default = NULL; - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "threads", &threadsstr) != 1) { - aconf->threads = 1; - } else { - if (strcmp(threadsstr, "auto") == 0) { - aconf->threads = GetIfaceRSSQueuesNum(aconf->iface); - } else { - aconf->threads = (uint8_t)atoi(threadsstr); - } - } - - if (aconf->threads <= 0) { - aconf->threads = 1; - } - if (aconf->threads) { - SCLogInfo("Using %d threads for interface %s", aconf->threads, - aconf->iface_name); - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "copy-iface", &out_iface) == 1) { - if (strlen(out_iface) > 0) { - aconf->out_iface_name = out_iface; - } - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", ©modestr) == 1) { - if (aconf->out_iface_name == NULL) { - SCLogInfo("Copy mode activated but no destination" - " iface. Disabling feature"); - } else if (strlen(copymodestr) <= 0) { - aconf->out_iface_name = NULL; - } else if (strcmp(copymodestr, "ips") == 0) { - SCLogInfo("Netmap IPS mode activated %s->%s", - aconf->iface_name, - aconf->out_iface_name); - aconf->copy_mode = NETMAP_COPY_MODE_IPS; - } else if (strcmp(copymodestr, "tap") == 0) { - SCLogInfo("Netmap TAP mode activated %s->%s", - aconf->iface_name, - aconf->out_iface_name); - aconf->copy_mode = NETMAP_COPY_MODE_TAP; - } else { - SCLogInfo("Invalid mode (not in tap, ips)"); - } - } - - if (aconf->out_iface_name && aconf->out_iface_name[0]) { - strlcpy(aconf->out_iface, aconf->out_iface_name, - sizeof(aconf->out_iface)); - size_t len = strlen(aconf->out_iface); - if (aconf->out_iface[len-1] == '+') { - aconf->out_iface[len-1] = '\0'; - aconf->out_iface_sw = 1; - } - } - - SC_ATOMIC_RESET(aconf->ref); - (void) SC_ATOMIC_ADD(aconf->ref, aconf->threads); - - /* load netmap bpf filter */ - /* command line value has precedence */ - if (ConfGet("bpf-filter", &bpf_filter) != 1) { - if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", &bpf_filter) == 1) { - if (strlen(bpf_filter) > 0) { - aconf->bpf_filter = bpf_filter; - SCLogInfo("Going to use bpf filter %s", aconf->bpf_filter); - } - } - } - - (void)ConfGetChildValueBoolWithDefault(if_root, if_default, "disable-promisc", (int *)&boolval); - if (boolval) { - SCLogInfo("Disabling promiscuous mode on iface %s", aconf->iface); - aconf->promisc = 0; - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "checksum-checks", &tmpctype) == 1) { - if (strcmp(tmpctype, "auto") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_AUTO; - } else if (strcmp(tmpctype, "yes") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_ENABLE; - } else if (strcmp(tmpctype, "no") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_DISABLE; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid value for checksum-checks for %s", aconf->iface_name); - } - } - - return aconf; -} - -static int NetmapConfigGeThreadsCount(void *conf) -{ - NetmapIfaceConfig *aconf = (NetmapIfaceConfig *)conf; - return aconf->threads; -} - -int NetmapRunModeIsIPS() -{ - int nlive = LiveGetDeviceCount(); - int ldev; - ConfNode *if_root; - ConfNode *if_default = NULL; - ConfNode *netmap_node; - int has_ips = 0; - int has_ids = 0; - - /* Find initial node */ - netmap_node = ConfGetNode("netmap"); - if (netmap_node == NULL) { - return 0; - } - - if_default = ConfNodeLookupKeyValue(netmap_node, "interface", "default"); - - for (ldev = 0; ldev < nlive; ldev++) { - char *live_dev = LiveGetDeviceName(ldev); - if (live_dev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); - return 0; - } - char *copymodestr = NULL; - if_root = ConfNodeLookupKeyValue(netmap_node, "interface", live_dev); - - if (if_root == NULL) { - if (if_default == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); - return 0; - } - if_root = if_default; - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", ©modestr) == 1) { - if (strcmp(copymodestr, "ips") == 0) { - has_ips = 1; - } else { - has_ids = 1; - } - } else { - has_ids = 1; - } - } - - if (has_ids && has_ips) { - SCLogInfo("Netmap mode using IPS and IDS mode"); - for (ldev = 0; ldev < nlive; ldev++) { - char *live_dev = LiveGetDeviceName(ldev); - if (live_dev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); - return 0; - } - if_root = ConfNodeLookupKeyValue(netmap_node, "interface", live_dev); - char *copymodestr = NULL; - - if (if_root == NULL) { - if (if_default == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Problem with config file"); - return 0; - } - if_root = if_default; - } - - if (! ((ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", ©modestr) == 1) && - (strcmp(copymodestr, "ips") == 0))) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Netmap IPS mode used and interface '%s' is in IDS or TAP mode. " - "Sniffing '%s' but expect bad result as stream-inline is activated.", - live_dev, live_dev); - } - } - } - - return has_ips; -} - -#endif // #ifdef HAVE_NETMAP - -int RunModeIdsNetmapAutoFp(void) -{ - SCEnter(); - -#ifdef HAVE_NETMAP - int ret; - char *live_dev = NULL; - - RunModeInitialize(); - - TimeModeSetLive(); - - (void)ConfGet("netmap.live-interface", &live_dev); - - SCLogDebug("live_dev %s", live_dev); - - ret = RunModeSetLiveCaptureAutoFp( - ParseNetmapConfig, - NetmapConfigGeThreadsCount, - "ReceiveNetmap", - "DecodeNetmap", "RxNetmap", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsNetmapAutoFp initialised"); -#endif /* HAVE_NETMAP */ - - SCReturnInt(0); -} - -/** -* \brief Single thread version of the netmap processing. -*/ -int RunModeIdsNetmapSingle(void) -{ - SCEnter(); - -#ifdef HAVE_NETMAP - int ret; - char *live_dev = NULL; - - RunModeInitialize(); - TimeModeSetLive(); - - (void)ConfGet("netmap.live-interface", &live_dev); - - ret = RunModeSetLiveCaptureSingle( - ParseNetmapConfig, - NetmapConfigGeThreadsCount, - "ReceiveNetmap", - "DecodeNetmap", "NetmapPkt", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsNetmapSingle initialised"); - -#endif /* HAVE_NETMAP */ - SCReturnInt(0); -} - -/** -* \brief Workers version of the netmap processing. -* -* Start N threads with each thread doing all the work. -* -*/ -int RunModeIdsNetmapWorkers(void) -{ - SCEnter(); - -#ifdef HAVE_NETMAP - int ret; - char *live_dev = NULL; - - RunModeInitialize(); - TimeModeSetLive(); - - (void)ConfGet("netmap.live-interface", &live_dev); - - ret = RunModeSetLiveCaptureWorkers( - ParseNetmapConfig, - NetmapConfigGeThreadsCount, - "ReceiveNetmap", - "DecodeNetmap", "NetmapPkt", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsNetmapWorkers initialised"); - -#endif /* HAVE_NETMAP */ - SCReturnInt(0); -} - -/** -* @} -*/ diff --git a/framework/src/suricata/src/runmode-netmap.h b/framework/src/suricata/src/runmode-netmap.h deleted file mode 100644 index 988c349a..00000000 --- a/framework/src/suricata/src/runmode-netmap.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file -* -* \author Aleksey Katargin -*/ - -#ifndef __RUNMODE_NETMAP_H__ -#define __RUNMODE_NETMAP_H__ - -int RunModeIdsNetmapSingle(void); -int RunModeIdsNetmapAutoFp(void); -int RunModeIdsNetmapWorkers(void); -void RunModeIdsNetmapRegister(void); -const char *RunModeNetmapGetDefaultMode(void); -int NetmapRunModeIsIPS(); - -#endif /* __RUNMODE_NETMAP_H__ */ diff --git a/framework/src/suricata/src/runmode-nflog.c b/framework/src/suricata/src/runmode-nflog.c deleted file mode 100644 index 9c08f9ae..00000000 --- a/framework/src/suricata/src/runmode-nflog.c +++ /dev/null @@ -1,254 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Giuseppe Longo - */ -#include "suricata-common.h" -#include "config.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-nflog.h" - -#include "util-debug.h" -#include "util-device.h" -#include "util-runmodes.h" -#include "util-misc.h" - -#include "source-nflog.h" - -static const char *default_mode = NULL; - -const char *RunModeIdsNflogGetDefaultMode(void) -{ - return default_mode; -} - -void RunModeIdsNflogRegister(void) -{ - default_mode = "autofp"; - RunModeRegisterNewRunMode(RUNMODE_NFLOG, "autofp", - "Multi threaded nflog mode", - RunModeIdsNflogAutoFp); - RunModeRegisterNewRunMode(RUNMODE_NFLOG, "single", - "Single threaded nflog mode", - RunModeIdsNflogSingle); - RunModeRegisterNewRunMode(RUNMODE_NFLOG, "workers", - "Workers nflog mode", - RunModeIdsNflogWorkers); - return; -} - - -static void NflogDerefConfig(void *data) -{ - NflogGroupConfig *nflogconf = (NflogGroupConfig *)data; - SCFree(nflogconf); -} - -void *ParseNflogConfig(const char *group) -{ - ConfNode *group_root; - ConfNode *group_default = NULL; - ConfNode *nflog_node; - NflogGroupConfig *nflogconf = SCMalloc(sizeof(*nflogconf)); - intmax_t bufsize; - intmax_t bufsize_max; - intmax_t qthreshold; - intmax_t qtimeout; - int boolval; - - if (unlikely(nflogconf == NULL)) - return NULL; - - if (group == NULL) { - SCFree(nflogconf); - return NULL; - } - - nflogconf->DerefFunc = NflogDerefConfig; - nflog_node = ConfGetNode("nflog"); - - if (nflog_node == NULL) { - SCLogInfo("Unable to find nflog config using default value"); - return nflogconf; - } - - group_root = ConfNodeLookupKeyValue(nflog_node, "group", group); - - group_default = ConfNodeLookupKeyValue(nflog_node, "group", "default"); - - if (group_root == NULL && group_default == NULL) { - SCLogInfo("Unable to find nflog config for " - "group \"%s\" or \"default\", using default value", - group); - return nflogconf; - } - - nflogconf->nful_overrun_warned = 0; - strlcpy(nflogconf->numgroup, group, sizeof(nflogconf->numgroup)); - - if (ParseSizeStringU16(group, &nflogconf->group) < 0) { - SCLogError(SC_ERR_NFLOG_GROUP, "NFLOG's group number invalid."); - exit(EXIT_FAILURE); - } - - boolval = ConfGetChildValueIntWithDefault(group_root, group_default, - "buffer-size", &bufsize); - - if (boolval) - nflogconf->nlbufsiz = bufsize; - else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid buffer-size value"); - SCFree(nflogconf); - return NULL; - } - - boolval = ConfGetChildValueIntWithDefault(group_root, group_default, - "max-size", &bufsize_max); - - if (boolval) - nflogconf->nlbufsiz_max = bufsize_max; - else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid max-size value"); - SCFree(nflogconf); - return NULL; - } - - if (nflogconf->nlbufsiz > nflogconf->nlbufsiz_max) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "buffer-size value larger " - "than max-size value, adjusting buffer-size"); - nflogconf->nlbufsiz = nflogconf->nlbufsiz_max; - } - - boolval = ConfGetChildValueIntWithDefault(group_root, group_default, - "qthreshold", &qthreshold); - - if (boolval) - nflogconf->qthreshold = qthreshold; - else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid qthreshold value"); - SCFree(nflogconf); - return NULL; - } - - boolval = ConfGetChildValueIntWithDefault(group_root, group_default, - "qtimeout", &qtimeout); - - if (boolval) - nflogconf->qtimeout = qtimeout; - else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid qtimeout value"); - SCFree(nflogconf); - return NULL; - } - - return nflogconf; -} - -int NflogConfigGeThreadsCount(void *conf) -{ - /* for each nflog group there is no reason to use more than 1 thread */ - return 1; -} - -int RunModeIdsNflogAutoFp(void) -{ - SCEnter(); - -#ifdef HAVE_NFLOG - int ret = 0; - char *live_dev = NULL; - - RunModeInitialize(); - TimeModeSetLive(); - - ret = RunModeSetLiveCaptureAutoFp(ParseNflogConfig, - NflogConfigGeThreadsCount, - "ReceiveNFLOG", - "DecodeNFLOG", - "RecvNFLOG", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsNflogAutoFp initialised"); -#endif /* HAVE_NFLOG */ - - SCReturnInt(0); -} - -int RunModeIdsNflogSingle(void) -{ - SCEnter(); - -#ifdef HAVE_NFLOG - int ret = 0; - char *live_dev = NULL; - - RunModeInitialize(); - TimeModeSetLive(); - - ret = RunModeSetLiveCaptureSingle(ParseNflogConfig, - NflogConfigGeThreadsCount, - "ReceiveNFLOG", - "DecodeNFLOG", - "RecvNFLOG", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsNflogSingle initialised"); -#endif /* HAVE_NFLOG */ - - SCReturnInt(0); -} - -int RunModeIdsNflogWorkers(void) -{ - SCEnter(); - -#ifdef HAVE_NFLOG - int ret = 0; - char *live_dev = NULL; - - RunModeInitialize(); - TimeModeSetLive(); - - ret = RunModeSetLiveCaptureWorkers(ParseNflogConfig, - NflogConfigGeThreadsCount, - "ReceiveNFLOG", - "DecodeNFLOG", - "RecvNFLOG", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsNflogWorkers initialised"); -#endif /* HAVE_NFLOG */ - - SCReturnInt(0); -} diff --git a/framework/src/suricata/src/runmode-nflog.h b/framework/src/suricata/src/runmode-nflog.h deleted file mode 100644 index 9c70c693..00000000 --- a/framework/src/suricata/src/runmode-nflog.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Giuseppe Longo - */ -#ifndef __RUNMODE_NFLOG_H__ -#define __RUNMODE_NFLOG_H__ - -int RunModeIdsNflogAutoFp(void); -int RunModeIdsNflogSingle(void); -int RunModeIdsNflogWorkers(void); -void RunModeIdsNflogRegister(void); -const char *RunModeIdsNflogGetDefaultMode(void); - -#endif /* __RUNMODE_NFLOG_H__ */ diff --git a/framework/src/suricata/src/runmode-nfq.c b/framework/src/suricata/src/runmode-nfq.c deleted file mode 100644 index 67fa5bcb..00000000 --- a/framework/src/suricata/src/runmode-nfq.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Eric Leblond - * - * Handling of NFQ runmodes. - */ - - -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-nfq.h" -#include "output.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-runmodes.h" -#include "util-device.h" - -static const char *default_mode; - -const char *RunModeIpsNFQGetDefaultMode(void) -{ - return default_mode; -} - -void RunModeIpsNFQRegister(void) -{ - default_mode = "autofp"; - RunModeRegisterNewRunMode(RUNMODE_NFQ, "autofp", - "Multi threaded NFQ IPS mode with respect to flow", - RunModeIpsNFQAutoFp); - - RunModeRegisterNewRunMode(RUNMODE_NFQ, "workers", - "Multi queue NFQ IPS mode with one thread per queue", - RunModeIpsNFQWorker); - return; -} - -int RunModeIpsNFQAutoFp(void) -{ - SCEnter(); - int ret = 0; -#ifdef NFQ - - RunModeInitialize(); - - TimeModeSetLive(); - - LiveDeviceHasNoStats(); - - ret = RunModeSetIPSAutoFp(NFQGetThread, - "ReceiveNFQ", - "VerdictNFQ", - "DecodeNFQ"); -#endif /* NFQ */ - return ret; -} - -int RunModeIpsNFQWorker(void) -{ - SCEnter(); - int ret = 0; -#ifdef NFQ - - RunModeInitialize(); - - TimeModeSetLive(); - - LiveDeviceHasNoStats(); - - ret = RunModeSetIPSWorker(NFQGetThread, - "ReceiveNFQ", - "VerdictNFQ", - "DecodeNFQ"); -#endif /* NFQ */ - return ret; -} diff --git a/framework/src/suricata/src/runmode-nfq.h b/framework/src/suricata/src/runmode-nfq.h deleted file mode 100644 index 6ad88014..00000000 --- a/framework/src/suricata/src/runmode-nfq.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __RUNMODE_NFQ_H__ -#define __RUNMODE_NFQ_H__ - -int RunModeIpsNFQAutoFp(void); -int RunModeIpsNFQWorker(void); -void RunModeIpsNFQRegister(void); -const char *RunModeIpsNFQGetDefaultMode(void); - -#endif /* __RUNMODE_NFQ_H__ */ diff --git a/framework/src/suricata/src/runmode-pcap-file.c b/framework/src/suricata/src/runmode-pcap-file.c deleted file mode 100644 index fab14639..00000000 --- a/framework/src/suricata/src/runmode-pcap-file.c +++ /dev/null @@ -1,281 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-pcap-file.h" -#include "output.h" - -#include "detect-engine.h" -#include "source-pcap-file.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" - -#include "util-runmodes.h" - -static const char *default_mode = NULL; - -const char *RunModeFilePcapGetDefaultMode(void) -{ - return default_mode; -} - -void RunModeFilePcapRegister(void) -{ - RunModeRegisterNewRunMode(RUNMODE_PCAP_FILE, "single", - "Single threaded pcap file mode", - RunModeFilePcapSingle); - default_mode = "autofp"; - RunModeRegisterNewRunMode(RUNMODE_PCAP_FILE, "autofp", - "Multi threaded pcap file mode. Packets from " - "each flow are assigned to a single detect thread, " - "unlike \"pcap-file-auto\" where packets from " - "the same flow can be processed by any detect " - "thread", - RunModeFilePcapAutoFp); - - return; -} - -/** - * \brief Single thread version of the Pcap file processing. - */ -int RunModeFilePcapSingle(void) -{ - char *file = NULL; - if (ConfGet("pcap-file.file", &file) == 0) { - SCLogError(SC_ERR_RUNMODE, "Failed retrieving pcap-file from Conf"); - exit(EXIT_FAILURE); - } - - RunModeInitialize(); - TimeModeSetOffline(); - - PcapFileGlobalInit(); - - /* create the threads */ - ThreadVars *tv = TmThreadCreatePacketHandler("PcapFile", - "packetpool", "packetpool", - "packetpool", "packetpool", - "pktacqloop"); - if (tv == NULL) { - SCLogError(SC_ERR_RUNMODE, "threading setup failed"); - exit(EXIT_FAILURE); - } - - TmModule *tm_module = TmModuleGetByName("ReceivePcapFile"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for ReceivePcap"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, file); - - tm_module = TmModuleGetByName("DecodePcapFile"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName DecodePcap failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - tm_module = TmModuleGetByName("StreamTcp"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - if (DetectEngineEnabled()) { - tm_module = TmModuleGetByName("Detect"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - } - - SetupOutputs(tv); - - TmThreadSetCPU(tv, DETECT_CPU_SET); - - if (TmThreadSpawn(tv) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - - return 0; -} - -/** - * \brief RunModeFilePcapAutoFp set up the following thread packet handlers: - * - Receive thread (from pcap file) - * - Decode thread - * - Stream thread - * - Detect: If we have only 1 cpu, it will setup one Detect thread - * If we have more than one, it will setup num_cpus - 1 - * starting from the second cpu available. - * - Outputs thread - * By default the threads will use the first cpu available - * except the Detection threads if we have more than one cpu. - * - * \retval 0 If all goes well. (If any problem is detected the engine will - * exit()). - */ -int RunModeFilePcapAutoFp(void) -{ - SCEnter(); - char tname[TM_THREAD_NAME_MAX]; - char qname[TM_QUEUE_NAME_MAX]; - uint16_t cpu = 0; - char *queues = NULL; - int thread; - - RunModeInitialize(); - RunmodeSetFlowStreamAsync(); - - char *file = NULL; - if (ConfGet("pcap-file.file", &file) == 0) { - SCLogError(SC_ERR_RUNMODE, "Failed retrieving pcap-file from Conf"); - exit(EXIT_FAILURE); - } - SCLogDebug("file %s", file); - - TimeModeSetOffline(); - - PcapFileGlobalInit(); - - /* Available cpus */ - uint16_t ncpus = UtilCpuGetNumProcessorsOnline(); - - /* start with cpu 1 so that if we're creating an odd number of detect - * threads we're not creating the most on CPU0. */ - if (ncpus > 0) - cpu = 1; - - /* always create at least one thread */ - int thread_max = TmThreadGetNbThreads(DETECT_CPU_SET); - if (thread_max == 0) - thread_max = ncpus * threading_detect_ratio; - if (thread_max < 1) - thread_max = 1; - - queues = RunmodeAutoFpCreatePickupQueuesString(thread_max); - if (queues == NULL) { - SCLogError(SC_ERR_RUNMODE, "RunmodeAutoFpCreatePickupQueuesString failed"); - exit(EXIT_FAILURE); - } - - /* create the threads */ - ThreadVars *tv_receivepcap = - TmThreadCreatePacketHandler("ReceivePcapFile", - "packetpool", "packetpool", - queues, "flow", - "pktacqloop"); - SCFree(queues); - - if (tv_receivepcap == NULL) { - SCLogError(SC_ERR_FATAL, "threading setup failed"); - exit(EXIT_FAILURE); - } - TmModule *tm_module = TmModuleGetByName("ReceivePcapFile"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for ReceivePcap"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_receivepcap, tm_module, file); - - tm_module = TmModuleGetByName("DecodePcapFile"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName DecodePcap failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_receivepcap, tm_module, NULL); - - TmThreadSetCPU(tv_receivepcap, RECEIVE_CPU_SET); - - if (TmThreadSpawn(tv_receivepcap) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - - for (thread = 0; thread < thread_max; thread++) { - snprintf(tname, sizeof(tname), "Detect%d", thread+1); - snprintf(qname, sizeof(qname), "pickup%d", thread+1); - - SCLogDebug("tname %s, qname %s", tname, qname); - - char *thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - SCLogError(SC_ERR_RUNMODE, "failed to strdup thread name"); - exit(EXIT_FAILURE); - } - SCLogDebug("Assigning %s affinity to cpu %u", thread_name, cpu); - - ThreadVars *tv_detect_ncpu = - TmThreadCreatePacketHandler(thread_name, - qname, "flow", - "packetpool", "packetpool", - "varslot"); - if (tv_detect_ncpu == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - tm_module = TmModuleGetByName("StreamTcp"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL); - - if (DetectEngineEnabled()) { - tm_module = TmModuleGetByName("Detect"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL); - } - - char *thread_group_name = SCStrdup("Detect"); - if (unlikely(thread_group_name == NULL)) { - SCLogError(SC_ERR_RUNMODE, "error allocating memory"); - exit(EXIT_FAILURE); - } - tv_detect_ncpu->thread_group_name = thread_group_name; - - /* add outputs as well */ - SetupOutputs(tv_detect_ncpu); - - TmThreadSetCPU(tv_detect_ncpu, DETECT_CPU_SET); - - if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - - if ((cpu + 1) == ncpus) - cpu = 0; - else - cpu++; - } - - return 0; -} diff --git a/framework/src/suricata/src/runmode-pcap-file.h b/framework/src/suricata/src/runmode-pcap-file.h deleted file mode 100644 index 52cab022..00000000 --- a/framework/src/suricata/src/runmode-pcap-file.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __RUNMODE_PCAP_FILE_H__ -#define __RUNMODE_PCAP_FILE_H__ - -int RunModeFilePcapSingle(void); -int RunModeFilePcapAutoFp(void); -void RunModeFilePcapRegister(void); -const char *RunModeFilePcapGetDefaultMode(void); - -#endif /* __RUNMODE_PCAP_FILE_H__ */ diff --git a/framework/src/suricata/src/runmode-pcap.c b/framework/src/suricata/src/runmode-pcap.c deleted file mode 100644 index 6561c1c8..00000000 --- a/framework/src/suricata/src/runmode-pcap.c +++ /dev/null @@ -1,328 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-pcap.h" -#include "log-httplog.h" -#include "output.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-device.h" -#include "util-runmodes.h" -#include "util-atomic.h" -#include "util-misc.h" - -static const char *default_mode = NULL; - -const char *RunModeIdsGetDefaultMode(void) -{ - return default_mode; -} - -int RunModeIdsPcapWorkers(void); - -void RunModeIdsPcapRegister(void) -{ - RunModeRegisterNewRunMode(RUNMODE_PCAP_DEV, "single", - "Single threaded pcap live mode", - RunModeIdsPcapSingle); - default_mode = "autofp"; - RunModeRegisterNewRunMode(RUNMODE_PCAP_DEV, "autofp", - "Multi threaded pcap live mode. Packets from " - "each flow are assigned to a single detect thread, " - "unlike \"pcap_live_auto\" where packets from " - "the same flow can be processed by any detect " - "thread", - RunModeIdsPcapAutoFp); - RunModeRegisterNewRunMode(RUNMODE_PCAP_DEV, "workers", - "Workers pcap live mode, each thread does all" - " tasks from acquisition to logging", - RunModeIdsPcapWorkers); - - return; -} - -void PcapDerefConfig(void *conf) -{ - PcapIfaceConfig *pfp = (PcapIfaceConfig *)conf; - /* Pcap config is used only once but cost of this low. */ - if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) { - SCFree(pfp); - } -} - - -void *ParsePcapConfig(const char *iface) -{ - char *threadsstr = NULL; - ConfNode *if_root; - ConfNode *if_default = NULL; - ConfNode *pcap_node; - PcapIfaceConfig *aconf = SCMalloc(sizeof(*aconf)); - char *tmpbpf; - char *tmpctype; - intmax_t value; - int promisc = 0; - intmax_t snaplen = 0; - - if (unlikely(aconf == NULL)) { - return NULL; - } - - if (iface == NULL) { - SCFree(aconf); - return NULL; - } - - memset(aconf, 0x00, sizeof(*aconf)); - strlcpy(aconf->iface, iface, sizeof(aconf->iface)); - - aconf->buffer_size = 0; - /* If set command line option has precedence over config */ - if ((ConfGetInt("pcap.buffer-size", &value)) == 1) { - SCLogInfo("Pcap will use %d buffer size", (int)value); - aconf->buffer_size = value; - } - - aconf->checksum_mode = CHECKSUM_VALIDATION_AUTO; - aconf->bpf_filter = NULL; - if ((ConfGet("bpf-filter", &tmpbpf)) == 1) { - aconf->bpf_filter = tmpbpf; - } - - SC_ATOMIC_INIT(aconf->ref); - aconf->DerefFunc = PcapDerefConfig; - aconf->threads = 1; - - /* Find initial node */ - pcap_node = ConfGetNode("pcap"); - if (pcap_node == NULL) { - SCLogInfo("Unable to find pcap config using default value"); - return aconf; - } - - if_root = ConfNodeLookupKeyValue(pcap_node, "interface", iface); - - if_default = ConfNodeLookupKeyValue(pcap_node, "interface", "default"); - - if (if_root == NULL && if_default == NULL) { - SCLogInfo("Unable to find pcap config for " - "interface %s, using default value", - iface); - return aconf; - } - - /* If there is no setting for current interface use default one as main iface */ - if (if_root == NULL) { - if_root = if_default; - if_default = NULL; - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "threads", &threadsstr) != 1) { - aconf->threads = 1; - } else { - if (threadsstr != NULL) { - aconf->threads = (uint8_t)atoi(threadsstr); - } - } - if (aconf->threads == 0) { - aconf->threads = 1; - } - (void) SC_ATOMIC_ADD(aconf->ref, aconf->threads); - - if (aconf->buffer_size == 0) { - char *s_limit = NULL; - int ret; - ret = ConfGetChildValueWithDefault(if_root, if_default, "buffer-size", &s_limit); - if (ret == 1 && s_limit) { - uint64_t bsize = 0; - - if (ParseSizeStringU64(s_limit, &bsize) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Failed to parse pcap buffer size: %s", - s_limit); - } else { - /* the string 2gb returns 2147483648 which is 1 to high - * for a int. */ - if (bsize == (uint64_t)((uint64_t)INT_MAX + (uint64_t)1)) - bsize = (uint64_t)INT_MAX; - - if (bsize > INT_MAX) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Failed to set pcap buffer size: 2gb max. %"PRIu64" > %d", bsize, INT_MAX); - } else { - aconf->buffer_size = (int)bsize; - } - } - } - } - - if (aconf->bpf_filter == NULL) { - /* set bpf filter if we have one */ - if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", &tmpbpf) != 1) { - SCLogDebug("could not get bpf or none specified"); - } else { - aconf->bpf_filter = tmpbpf; - } - } else { - SCLogInfo("BPF filter set from command line or via old 'bpf-filter' option."); - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "checksum-checks", &tmpctype) == 1) { - if (strcmp(tmpctype, "auto") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_AUTO; - } else if (strcmp(tmpctype, "yes") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_ENABLE; - } else if (strcmp(tmpctype, "no") == 0) { - aconf->checksum_mode = CHECKSUM_VALIDATION_DISABLE; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid value for checksum-checks for %s", aconf->iface); - } - } - - aconf->promisc = LIBPCAP_PROMISC; - if (ConfGetChildValueBoolWithDefault(if_root, if_default, "promisc", &promisc) != 1) { - SCLogDebug("could not get promisc or none specified"); - } else { - aconf->promisc = promisc; - } - - aconf->snaplen = 0; - if (ConfGetChildValueIntWithDefault(if_root, if_default, "snaplen", &snaplen) != 1) { - SCLogDebug("could not get snaplen or none specified"); - } else { - aconf->snaplen = snaplen; - } - - - return aconf; -} - -int PcapConfigGeThreadsCount(void *conf) -{ - PcapIfaceConfig *pfp = (PcapIfaceConfig *)conf; - return pfp->threads; -} - -/** - * \brief Single thread version of the Pcap live processing. - */ -int RunModeIdsPcapSingle(void) -{ - int ret; - char *live_dev = NULL; - - SCEnter(); - - RunModeInitialize(); - TimeModeSetLive(); - - (void)ConfGet("pcap.single-pcap-dev", &live_dev); - - ret = RunModeSetLiveCaptureSingle(ParsePcapConfig, - PcapConfigGeThreadsCount, - "ReceivePcap", - "DecodePcap", "PcapLive", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Runmode start failed"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsPcapSingle initialised"); - - SCReturnInt(0); -} - -/** - * \brief RunModIdsPcapAutoFp set up the following thread packet handlers: - * - Receive thread (from pcap device) - * - Decode thread - * - Stream thread - * - Detect: If we have only 1 cpu, it will setup one Detect thread - * If we have more than one, it will setup num_cpus - 1 - * starting from the second cpu available. - * - Outputs thread - * By default the threads will use the first cpu available - * except the Detection threads if we have more than one cpu. - * - * \retval 0 If all goes well. (If any problem is detected the engine will - * exit()). - */ -int RunModeIdsPcapAutoFp(void) -{ - int ret; - char *live_dev = NULL; - - SCEnter(); - RunModeInitialize(); - TimeModeSetLive(); - - (void) ConfGet("pcap.single-pcap-dev", &live_dev); - - ret = RunModeSetLiveCaptureAutoFp(ParsePcapConfig, - PcapConfigGeThreadsCount, - "ReceivePcap", - "DecodePcap", "RxPcap", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Runmode start failed"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsPcapAutoFp initialised"); - - SCReturnInt(0); -} - -/** - * \brief Workers version of the PCAP LIVE processing. - * - * Start N threads with each thread doing all the work. - * - */ -int RunModeIdsPcapWorkers(void) -{ - int ret; - char *live_dev = NULL; - SCEnter(); - - RunModeInitialize(); - TimeModeSetLive(); - - (void) ConfGet("pcap.single-pcap-dev", &live_dev); - - ret = RunModeSetLiveCaptureWorkers(ParsePcapConfig, - PcapConfigGeThreadsCount, - "ReceivePcap", - "DecodePcap", "RxPcap", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Unable to start runmode"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsPcapWorkers initialised"); - - SCReturnInt(0); -} diff --git a/framework/src/suricata/src/runmode-pcap.h b/framework/src/suricata/src/runmode-pcap.h deleted file mode 100644 index b68c6ddc..00000000 --- a/framework/src/suricata/src/runmode-pcap.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __RUNMODE_PCAP_H__ -#define __RUNMODE_PCAP_H__ - -int RunModeIdsPcapSingle(void); -int RunModeIdsPcapAutoFp(void); -void RunModeIdsPcapRegister(void); -const char *RunModeIdsGetDefaultMode(void); - -#endif /* __RUNMODE_PCAP_H__ */ diff --git a/framework/src/suricata/src/runmode-pfring.c b/framework/src/suricata/src/runmode-pfring.c deleted file mode 100644 index f08bdad8..00000000 --- a/framework/src/suricata/src/runmode-pfring.c +++ /dev/null @@ -1,525 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-pfring.h" -#include "source-pfring.h" -#include "output.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-runmodes.h" -#include "util-device.h" - -static const char *default_mode_autofp = NULL; - - -#define PFRING_CONF_V1 1 -#define PFRING_CONF_V2 2 - -const char *RunModeIdsPfringGetDefaultMode(void) -{ -#ifdef HAVE_PFRING - return default_mode_autofp; -#else - return NULL; -#endif -} - -void RunModeIdsPfringRegister(void) -{ - default_mode_autofp = "autofp"; - RunModeRegisterNewRunMode(RUNMODE_PFRING, "autofp", - "Multi threaded pfring mode. Packets from " - "each flow are assigned to a single detect " - "thread, unlike \"pfring_auto\" where packets " - "from the same flow can be processed by any " - "detect thread", - RunModeIdsPfringAutoFp); - RunModeRegisterNewRunMode(RUNMODE_PFRING, "single", - "Single threaded pfring mode", - RunModeIdsPfringSingle); - RunModeRegisterNewRunMode(RUNMODE_PFRING, "workers", - "Workers pfring mode, each thread does all" - " tasks from acquisition to logging", - RunModeIdsPfringWorkers); - return; -} - -void PfringDerefConfig(void *conf) -{ - PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf; - if (SC_ATOMIC_SUB(pfp->ref, 1) == 0) { - if (pfp->bpf_filter) { - SCFree(pfp->bpf_filter); - } - SCFree(pfp); - } -} - -/** - * \brief extract information from config file - * - * The returned structure will be freed by the thread init function. - * This is thus necessary to or copy the structure before giving it - * to thread or to reparse the file for each thread (and thus have - * new structure. - * - * If old config system is used, then return the smae parameters - * value for each interface. - * - * \return a PfringIfaceConfig corresponding to the interface name - */ -void *OldParsePfringConfig(const char *iface) -{ - char *threadsstr = NULL; - PfringIfaceConfig *pfconf = SCMalloc(sizeof(*pfconf)); - char *tmpclusterid; -#ifdef HAVE_PFRING - char *tmpctype = NULL; - cluster_type default_ctype = CLUSTER_ROUND_ROBIN; -#endif - - if (unlikely(pfconf == NULL)) { - return NULL; - } - - if (iface == NULL) { - SCFree(pfconf); - return NULL; - } - - strlcpy(pfconf->iface, iface, sizeof(pfconf->iface)); - pfconf->flags = 0; - pfconf->threads = 1; - pfconf->cluster_id = 1; -#ifdef HAVE_PFRING - pfconf->ctype = default_ctype; -#endif - pfconf->DerefFunc = PfringDerefConfig; - pfconf->checksum_mode = CHECKSUM_VALIDATION_AUTO; - SC_ATOMIC_INIT(pfconf->ref); - (void) SC_ATOMIC_ADD(pfconf->ref, 1); - - /* Find initial node */ - if (ConfGet("pfring.threads", &threadsstr) != 1) { - pfconf->threads = 1; - } else { - if (threadsstr != NULL) { - pfconf->threads = (uint8_t)atoi(threadsstr); - } - } - if (pfconf->threads == 0) { - pfconf->threads = 1; - } - - SC_ATOMIC_RESET(pfconf->ref); - (void) SC_ATOMIC_ADD(pfconf->ref, pfconf->threads); - - if (strncmp(pfconf->iface, "zc", 2) == 0) { - SCLogInfo("ZC interface detected, not setting cluster-id"); - } - else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) { - SCLogInfo("DNA interface detected, not setting cluster-id"); - } else if (ConfGet("pfring.cluster-id", &tmpclusterid) != 1) { - SCLogError(SC_ERR_INVALID_ARGUMENT,"Could not get cluster-id from config"); - } else { - pfconf->cluster_id = (uint16_t)atoi(tmpclusterid); - pfconf->flags |= PFRING_CONF_FLAGS_CLUSTER; - SCLogDebug("Going to use cluster-id %" PRId32, pfconf->cluster_id); - } - -#ifdef HAVE_PFRING - if (strncmp(pfconf->iface, "zc", 2) == 0) { - SCLogInfo("ZC interface detected, not setting cluster type for PF_RING (iface %s)", - pfconf->iface); - } else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) { - SCLogInfo("DNA interface detected, not setting cluster type for PF_RING (iface %s)", - pfconf->iface); - } else if (ConfGet("pfring.cluster-type", &tmpctype) != 1) { - SCLogError(SC_ERR_GET_CLUSTER_TYPE_FAILED,"Could not get cluster-type from config"); - } else if (strcmp(tmpctype, "cluster_round_robin") == 0) { - SCLogInfo("Using round-robin cluster mode for PF_RING (iface %s)", - pfconf->iface); - pfconf->ctype = (cluster_type)tmpctype; - } else if (strcmp(tmpctype, "cluster_flow") == 0) { - SCLogInfo("Using flow cluster mode for PF_RING (iface %s)", - pfconf->iface); - pfconf->ctype = (cluster_type)tmpctype; - } else { - SCLogError(SC_ERR_INVALID_CLUSTER_TYPE,"invalid cluster-type %s",tmpctype); - SCFree(pfconf); - return NULL; - } -#endif /* HAVE_PFRING */ - - return pfconf; -} - -/** - * \brief extract information from config file - * - * The returned structure will be freed by the thread init function. - * This is thus necessary to or copy the structure before giving it - * to thread or to reparse the file for each thread (and thus have - * new structure. - * - * If old config system is used, then return the smae parameters - * value for each interface. - * - * \return a PfringIfaceConfig corresponding to the interface name - */ -void *ParsePfringConfig(const char *iface) -{ - char *threadsstr = NULL; - ConfNode *if_root; - ConfNode *if_default = NULL; - ConfNode *pf_ring_node; - PfringIfaceConfig *pfconf = SCMalloc(sizeof(*pfconf)); - char *tmpclusterid; - char *tmpctype = NULL; -#ifdef HAVE_PFRING - cluster_type default_ctype = CLUSTER_ROUND_ROBIN; - int getctype = 0; -#endif - char *bpf_filter = NULL; - - if (unlikely(pfconf == NULL)) { - return NULL; - } - - if (iface == NULL) { - SCFree(pfconf); - return NULL; - } - - memset(pfconf, 0, sizeof(PfringIfaceConfig)); - strlcpy(pfconf->iface, iface, sizeof(pfconf->iface)); - pfconf->threads = 1; - pfconf->cluster_id = 1; -#ifdef HAVE_PFRING - pfconf->ctype = (cluster_type)default_ctype; -#endif - pfconf->DerefFunc = PfringDerefConfig; - SC_ATOMIC_INIT(pfconf->ref); - (void) SC_ATOMIC_ADD(pfconf->ref, 1); - - /* Find initial node */ - pf_ring_node = ConfGetNode("pfring"); - if (pf_ring_node == NULL) { - SCLogInfo("Unable to find pfring config using default value"); - return pfconf; - } - - if_root = ConfNodeLookupKeyValue(pf_ring_node, "interface", iface); - - if_default = ConfNodeLookupKeyValue(pf_ring_node, "interface", "default"); - - if (if_root == NULL && if_default == NULL) { - SCLogInfo("Unable to find pfring config for " - "interface %s, using default value or 1.0 " - "configuration system. ", - iface); - return pfconf; - } - - /* If there is no setting for current interface use default one as main iface */ - if (if_root == NULL) { - if_root = if_default; - if_default = NULL; - } - - if (ConfGetChildValueWithDefault(if_root, if_default, "threads", &threadsstr) != 1) { - pfconf->threads = 1; - } else { - if (threadsstr != NULL) { - pfconf->threads = (uint8_t)atoi(threadsstr); - } - } - if (pfconf->threads == 0) { - pfconf->threads = 1; - } - - SC_ATOMIC_RESET(pfconf->ref); - (void) SC_ATOMIC_ADD(pfconf->ref, pfconf->threads); - - /* command line value has precedence */ - if (ConfGet("pfring.cluster-id", &tmpclusterid) == 1) { - pfconf->cluster_id = (uint16_t)atoi(tmpclusterid); - pfconf->flags |= PFRING_CONF_FLAGS_CLUSTER; - SCLogDebug("Going to use command-line provided cluster-id %" PRId32, - pfconf->cluster_id); - } else { - - if (strncmp(pfconf->iface, "zc", 2) == 0) { - SCLogInfo("ZC interface detected, not setting cluster-id for PF_RING (iface %s)", - pfconf->iface); - } else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) { - SCLogInfo("DNA interface detected, not setting cluster-id for PF_RING (iface %s)", - pfconf->iface); - } else if (ConfGetChildValueWithDefault(if_root, if_default, "cluster-id", &tmpclusterid) != 1) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Could not get cluster-id from config"); - } else { - pfconf->cluster_id = (uint16_t)atoi(tmpclusterid); - pfconf->flags |= PFRING_CONF_FLAGS_CLUSTER; - SCLogDebug("Going to use cluster-id %" PRId32, pfconf->cluster_id); - } - } - - /*load pfring bpf filter*/ - /* command line value has precedence */ - if (ConfGet("bpf-filter", &bpf_filter) == 1) { - if (strlen(bpf_filter) > 0) { - pfconf->bpf_filter = SCStrdup(bpf_filter); - if (unlikely(pfconf->bpf_filter == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, - "Can't allocate BPF filter string"); - } else { - SCLogDebug("Going to use command-line provided bpf filter %s", - pfconf->bpf_filter); - } - } - } else { - if (ConfGetChildValueWithDefault(if_root, if_default, "bpf-filter", &bpf_filter) == 1) { - if (strlen(bpf_filter) > 0) { - pfconf->bpf_filter = SCStrdup(bpf_filter); - if (unlikely(pfconf->bpf_filter == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, - "Can't allocate BPF filter string"); - } else { - SCLogDebug("Going to use bpf filter %s", - pfconf->bpf_filter); - } - } - } - } - -#ifdef HAVE_PFRING - if (ConfGet("pfring.cluster-type", &tmpctype) == 1) { - SCLogDebug("Going to use command-line provided cluster-type"); - getctype = 1; - } else { - if (strncmp(pfconf->iface, "zc", 2) == 0) { - SCLogInfo("ZC interface detected, not setting cluster type for PF_RING (iface %s)", - pfconf->iface); - } else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) { - SCLogInfo("DNA interface detected, not setting cluster type for PF_RING (iface %s)", - pfconf->iface); - } else if (ConfGetChildValueWithDefault(if_root, if_default, "cluster-type", &tmpctype) != 1) { - SCLogError(SC_ERR_GET_CLUSTER_TYPE_FAILED, - "Could not get cluster-type from config"); - } else { - getctype = 1; - } - } - - if (getctype) { - if (strcmp(tmpctype, "cluster_round_robin") == 0) { - SCLogInfo("Using round-robin cluster mode for PF_RING (iface %s)", - pfconf->iface); - pfconf->ctype = CLUSTER_ROUND_ROBIN; - } else if (strcmp(tmpctype, "cluster_flow") == 0) { - SCLogInfo("Using flow cluster mode for PF_RING (iface %s)", - pfconf->iface); - pfconf->ctype = CLUSTER_FLOW; - } else { - SCLogError(SC_ERR_INVALID_CLUSTER_TYPE, - "invalid cluster-type %s", - tmpctype); - SCFree(pfconf); - return NULL; - } - } -#endif /* HAVE_PFRING */ - if (ConfGetChildValueWithDefault(if_root, if_default, "checksum-checks", &tmpctype) == 1) { - if (strcmp(tmpctype, "auto") == 0) { - pfconf->checksum_mode = CHECKSUM_VALIDATION_AUTO; - } else if (strcmp(tmpctype, "yes") == 0) { - pfconf->checksum_mode = CHECKSUM_VALIDATION_ENABLE; - } else if (strcmp(tmpctype, "no") == 0) { - pfconf->checksum_mode = CHECKSUM_VALIDATION_DISABLE; - } else if (strcmp(tmpctype, "rx-only") == 0) { - pfconf->checksum_mode = CHECKSUM_VALIDATION_RXONLY; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid value for checksum-checks for %s", pfconf->iface); - } - } - - return pfconf; -} - -int PfringConfigGeThreadsCount(void *conf) -{ - PfringIfaceConfig *pfp = (PfringIfaceConfig *)conf; - return pfp->threads; -} - -int PfringConfLevel() -{ - char *def_dev; - /* 1.0 config should return a string */ - if (ConfGet("pfring.interface", &def_dev) != 1) { - return PFRING_CONF_V2; - } else { - return PFRING_CONF_V1; - } - return PFRING_CONF_V2; -} - -#ifdef HAVE_PFRING -static int GetDevAndParser(char **live_dev, ConfigIfaceParserFunc *parser) -{ - ConfGet("pfring.live-interface", live_dev); - - /* determine which config type we have */ - if (PfringConfLevel() > PFRING_CONF_V1) { - *parser = ParsePfringConfig; - } else { - SCLogInfo("Using 1.0 style configuration for pfring"); - *parser = OldParsePfringConfig; - /* In v1: try to get interface name from config */ - if (*live_dev == NULL) { - if (ConfGet("pfring.interface", live_dev) == 1) { - SCLogInfo("Using interface %s", *live_dev); - LiveRegisterDevice(*live_dev); - } else { - SCLogInfo("No interface found, problem incoming"); - *live_dev = NULL; - } - } - } - - return 0; -} -#endif - -int RunModeIdsPfringAutoFp(void) -{ - SCEnter(); - -/* We include only if pfring is enabled */ -#ifdef HAVE_PFRING - int ret; - char *live_dev = NULL; - ConfigIfaceParserFunc tparser; - - RunModeInitialize(); - - TimeModeSetLive(); - - ret = GetDevAndParser(&live_dev, &tparser); - if (ret != 0) { - SCLogError(SC_ERR_MISSING_CONFIG_PARAM, - "Unable to get parser and interface params"); - exit(EXIT_FAILURE); - } - - ret = RunModeSetLiveCaptureAutoFp(tparser, - PfringConfigGeThreadsCount, - "ReceivePfring", - "DecodePfring", "RxPFR", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Runmode start failed"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsPfringAutoFp initialised"); -#endif /* HAVE_PFRING */ - - return 0; -} - -int RunModeIdsPfringSingle(void) -{ - SCEnter(); - -/* We include only if pfring is enabled */ -#ifdef HAVE_PFRING - int ret; - char *live_dev = NULL; - ConfigIfaceParserFunc tparser; - - RunModeInitialize(); - - TimeModeSetLive(); - - ret = GetDevAndParser(&live_dev, &tparser); - if (ret != 0) { - SCLogError(SC_ERR_MISSING_CONFIG_PARAM, - "Unable to get parser and interface params"); - exit(EXIT_FAILURE); - } - - ret = RunModeSetLiveCaptureSingle(tparser, - PfringConfigGeThreadsCount, - "ReceivePfring", - "DecodePfring", "RxPFR", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Runmode start failed"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsPfringSingle initialised"); -#endif /* HAVE_PFRING */ - - return 0; -} - -int RunModeIdsPfringWorkers(void) -{ - SCEnter(); - -/* We include only if pfring is enabled */ -#ifdef HAVE_PFRING - int ret; - char *live_dev = NULL; - ConfigIfaceParserFunc tparser; - - RunModeInitialize(); - - TimeModeSetLive(); - - ret = GetDevAndParser(&live_dev, &tparser); - if (ret != 0) { - SCLogError(SC_ERR_MISSING_CONFIG_PARAM, - "Unable to get parser and interface params"); - exit(EXIT_FAILURE); - } - - ret = RunModeSetLiveCaptureWorkers(tparser, - PfringConfigGeThreadsCount, - "ReceivePfring", - "DecodePfring", "RxPFR", - live_dev); - if (ret != 0) { - SCLogError(SC_ERR_RUNMODE, "Runmode start failed"); - exit(EXIT_FAILURE); - } - - SCLogInfo("RunModeIdsPfringWorkers initialised"); -#endif /* HAVE_PFRING */ - - return 0; -} diff --git a/framework/src/suricata/src/runmode-pfring.h b/framework/src/suricata/src/runmode-pfring.h deleted file mode 100644 index 316c82f7..00000000 --- a/framework/src/suricata/src/runmode-pfring.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __RUNMODE_PFRING_H__ -#define __RUNMODE_PFRING_H__ - -#include "suricata-common.h" - -int RunModeIdsPfringAutoFp(void); -int RunModeIdsPfringSingle(void); -int RunModeIdsPfringWorkers(void); -void RunModeIdsPfringRegister(void); -const char *RunModeIdsPfringGetDefaultMode(void); - -#endif /* __RUNMODE_PFRING_H__ */ diff --git a/framework/src/suricata/src/runmode-tile.c b/framework/src/suricata/src/runmode-tile.c deleted file mode 100644 index 38f5afec..00000000 --- a/framework/src/suricata/src/runmode-tile.c +++ /dev/null @@ -1,287 +0,0 @@ -/* Copyright (C) 2011-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * \author Ken Steele, Tilera Corporation - * - * Tilera TILE-Gx runmode support - */ - -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-tile.h" -#include "output.h" -#include "source-mpipe.h" - -#include "detect-engine.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-device.h" - -#ifdef HAVE_MPIPE -/* Number of configured parallel pipelines. */ -int tile_num_pipelines; -#endif - -/* - * runmode support for tilegx - */ - -static const char *mpipe_default_mode = "workers"; - -const char *RunModeTileMpipeGetDefaultMode(void) -{ - return mpipe_default_mode; -} - -void RunModeTileMpipeRegister(void) -{ -#ifdef HAVE_MPIPE - RunModeRegisterNewRunMode(RUNMODE_TILERA_MPIPE, "workers", - "Workers tilegx mpipe mode, each thread does all" - " tasks from acquisition to logging", - RunModeTileMpipeWorkers); - mpipe_default_mode = "workers"; -#endif -} - -#ifdef HAVE_MPIPE - -void *ParseMpipeConfig(const char *iface) -{ - ConfNode *if_root; - ConfNode *mpipe_node; - MpipeIfaceConfig *aconf = SCMalloc(sizeof(*aconf)); - char *copymodestr; - char *out_iface = NULL; - - if (unlikely(aconf == NULL)) { - return NULL; - } - - if (iface == NULL) { - SCFree(aconf); - return NULL; - } - - strlcpy(aconf->iface, iface, sizeof(aconf->iface)); - - /* Find initial node */ - mpipe_node = ConfGetNode("mpipe.inputs"); - if (mpipe_node == NULL) { - SCLogInfo("Unable to find mpipe config using default value"); - return aconf; - } - - if_root = ConfNodeLookupKeyValue(mpipe_node, "interface", iface); - if (if_root == NULL) { - SCLogInfo("Unable to find mpipe config for " - "interface %s, using default value", - iface); - return aconf; - } - - if (ConfGetChildValue(if_root, "copy-iface", &out_iface) == 1) { - if (strlen(out_iface) > 0) { - aconf->out_iface = out_iface; - } - } - aconf->copy_mode = MPIPE_COPY_MODE_NONE; - if (ConfGetChildValue(if_root, "copy-mode", ©modestr) == 1) { - if (aconf->out_iface == NULL) { - SCLogInfo("Copy mode activated but no destination" - " iface. Disabling feature"); - } else if (strlen(copymodestr) <= 0) { - aconf->out_iface = NULL; - } else if (strcmp(copymodestr, "ips") == 0) { - SCLogInfo("MPIPE IPS mode activated %s->%s", - iface, - aconf->out_iface); - aconf->copy_mode = MPIPE_COPY_MODE_IPS; - } else if (strcmp(copymodestr, "tap") == 0) { - SCLogInfo("MPIPE TAP mode activated %s->%s", - iface, - aconf->out_iface); - aconf->copy_mode = MPIPE_COPY_MODE_TAP; - } else { - SCLogError(SC_ERR_RUNMODE, "Invalid mode (expected tap or ips)"); - exit(EXIT_FAILURE); - } - } - return aconf; -} - -/** - * \brief RunModeTileMpipeWorkers set up to process all modules in each thread. - * - * \param iface pointer to the name of the interface from which we will - * fetch the packets - * \retval 0 if all goes well. (If any problem is detected the engine will - * exit()) - */ -int RunModeTileMpipeWorkers(void) -{ - SCEnter(); - char tname[TM_THREAD_NAME_MAX]; - char *thread_name; - TmModule *tm_module; - int pipe; - - RunModeInitialize(); - - /* Available cpus */ - uint16_t ncpus = UtilCpuGetNumProcessorsOnline(); - - TimeModeSetLive(); - - unsigned int pipe_max = 1; - if (ncpus > 1) - pipe_max = ncpus - 1; - - intmax_t threads; - - if (ConfGetInt("mpipe.threads", &threads) == 1) { - tile_num_pipelines = threads; - } else { - tile_num_pipelines = pipe_max; - } - SCLogInfo("%d Tilera worker threads", tile_num_pipelines); - - ReceiveMpipeInit(); - - char *mpipe_dev = NULL; - int nlive = LiveGetDeviceCount(); - if (nlive > 0) { - SCLogInfo("Using %d live device(s).", nlive); - /*mpipe_dev = LiveGetDevice(0);*/ - } else { - /* - * Attempt to get interface from config file - * overrides -i from command line. - */ - if (ConfGet("mpipe.interface", &mpipe_dev) == 0) { - if (ConfGet("mpipe.single_mpipe_dev", &mpipe_dev) == 0) { - SCLogError(SC_ERR_RUNMODE, "Failed retrieving " - "mpipe.single_mpipe_dev from Conf"); - exit(EXIT_FAILURE); - } - } - } - - /* Get affinity for worker */ - cpu_set_t cpus; - //int result = tmc_cpus_get_my_affinity(&cpus); - int result = tmc_cpus_get_dataplane_cpus(&cpus); - if (result < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "tmc_cpus_get_my_affinity() returned=%d", result); - SCReturnInt(TM_ECODE_FAILED); - } - - for (pipe = 0; pipe < tile_num_pipelines; pipe++) { - char *mpipe_devc; - - if (nlive > 0) { - mpipe_devc = SCStrdup("multi"); - } else { - mpipe_devc = SCStrdup(mpipe_dev); - } - if (unlikely(mpipe_devc == NULL)) { - printf("ERROR: SCStrdup failed for ReceiveMpipe\n"); - exit(EXIT_FAILURE); - } - - snprintf(tname, sizeof(tname), "Worker%d", pipe+1); - thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - printf("ERROR: SCStrdup failed for ReceiveMpipe\n"); - exit(EXIT_FAILURE); - } - - /* create the threads */ - ThreadVars *tv_worker = - TmThreadCreatePacketHandler(thread_name, - "packetpool", "packetpool", - "packetpool", "packetpool", - "pktacqloop"); - if (tv_worker == NULL) { - printf("ERROR: TmThreadsCreate failed\n"); - exit(EXIT_FAILURE); - } - tm_module = TmModuleGetByName("ReceiveMpipe"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName failed for ReceiveMpipe\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_worker, tm_module, (void *)mpipe_devc); - - /* Bind to a single cpu. */ - int pipe_cpu = tmc_cpus_find_nth_cpu(&cpus, pipe); - tv_worker->rank = pipe; - - TmThreadSetCPUAffinity(tv_worker, pipe_cpu); - - tm_module = TmModuleGetByName("DecodeMpipe"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName DecodeMpipe failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_worker, tm_module, NULL); - - tm_module = TmModuleGetByName("StreamTcp"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName StreamTcp failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_worker, tm_module, NULL); - - if (DetectEngineEnabled()) { - tm_module = TmModuleGetByName("Detect"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName Detect failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_worker, tm_module, NULL); - } - - tm_module = TmModuleGetByName("RespondReject"); - if (tm_module == NULL) { - printf("ERROR: TmModuleGetByName for RespondReject failed\n"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_worker, tm_module, NULL); - - SetupOutputs(tv_worker); - - if (TmThreadSpawn(tv_worker) != TM_ECODE_OK) { - printf("ERROR: TmThreadSpawn failed\n"); - exit(EXIT_FAILURE); - } - } - - return 0; -} - -#endif diff --git a/framework/src/suricata/src/runmode-tile.h b/framework/src/suricata/src/runmode-tile.h deleted file mode 100644 index ec6c9e50..00000000 --- a/framework/src/suricata/src/runmode-tile.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 2011-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * \author Ken Steele, Tilera Corporation - * - * Tilera TILE-Gx runmode support - */ - -#ifndef __RUNMODE_TILE_H__ -#define __RUNMODE_TILE_H__ - -#include "suricata-common.h" - -const char *RunModeTileMpipeGetDefaultMode(void); -void RunModeTileMpipeRegister(void); - -extern int tile_num_pipelines; - -int RunModeTileMpipeWorkers(void); - -void *ParseMpipeConfig(const char *iface); - -#endif /* __RUNMODE_TILE_H__ */ diff --git a/framework/src/suricata/src/runmode-unittests.c b/framework/src/suricata/src/runmode-unittests.c deleted file mode 100644 index 33220209..00000000 --- a/framework/src/suricata/src/runmode-unittests.c +++ /dev/null @@ -1,311 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Eric Leblond - */ - -#include "suricata-common.h" -#include "config.h" -#include "util-unittest.h" - -#ifdef UNITTESTS - -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-address.h" -#include "detect-engine-proto.h" -#include "detect-engine-port.h" -#include "detect-engine-mpm.h" -#include "detect-engine-sigorder.h" -#include "detect-engine-payload.h" -#include "detect-engine-dcepayload.h" -#include "detect-engine-uri.h" -#include "detect-engine-hcbd.h" -#include "detect-engine-hsbd.h" -#include "detect-engine-hhd.h" -#include "detect-engine-hrhd.h" -#include "detect-engine-hmd.h" -#include "detect-engine-hcd.h" -#include "detect-engine-hrud.h" -#include "detect-engine-hsmd.h" -#include "detect-engine-hscd.h" -#include "detect-engine-hua.h" -#include "detect-engine-hhhd.h" -#include "detect-engine-hrhhd.h" -#include "detect-engine-state.h" -#include "detect-engine-tag.h" -#include "detect-engine-modbus.h" -#include "detect-engine-filedata-smtp.h" -#include "detect-fast-pattern.h" -#include "flow.h" -#include "flow-timeout.h" -#include "flow-manager.h" -#include "flow-var.h" -#include "flow-bit.h" -#include "pkt-var.h" - -#include "host.h" -#include "host-bit.h" -#include "ippair.h" -#include "ippair-bit.h" -#include "unix-manager.h" - -#include "app-layer-detect-proto.h" -#include "app-layer-parser.h" -#include "app-layer.h" -#include "app-layer-smb.h" -#include "app-layer-dcerpc.h" -#include "app-layer-dcerpc-udp.h" -#include "app-layer-htp.h" -#include "app-layer-ftp.h" -#include "app-layer-ssl.h" -#include "app-layer-ssh.h" -#include "app-layer-smtp.h" - -#include "util-action.h" -#include "util-radix-tree.h" -#include "util-host-os-info.h" -#include "util-cidr.h" -#include "util-unittest-helper.h" -#include "util-time.h" -#include "util-rule-vars.h" -#include "util-classification-config.h" -#include "util-threshold-config.h" -#include "util-reference-config.h" -#include "util-profiling.h" -#include "util-magic.h" -#include "util-memcmp.h" -#include "util-misc.h" -#include "util-ringbuffer.h" -#include "util-signal.h" - -#include "reputation.h" -#include "util-atomic.h" -#include "util-spm.h" -#include "util-hash.h" -#include "util-hashlist.h" -#include "util-bloomfilter.h" -#include "util-bloomfilter-counting.h" -#include "util-pool.h" -#include "util-byte.h" -#include "util-proto-name.h" -#include "util-memrchr.h" - -#include "util-mpm-ac.h" -#include "detect-engine-mpm.h" - -#include "util-decode-asn1.h" - -#include "conf.h" -#include "conf-yaml-loader.h" -#include "tmqh-flow.h" -#include "defrag.h" -#include "detect-engine-siggroup.h" - -#endif /* UNITTESTS */ - -void RegisterAllModules(); -void TmqhSetup (void); - -/** - * Run or list unittests - * - * \param list_unittests If set to 1, list unittests. Run them if set to 0. - * \param regex_arg A regular expression to select unittests to run - * - * This function is terminal and will call exit after being called. - */ - -void RunUnittests(int list_unittests, char *regex_arg) -{ -#ifdef UNITTESTS - /* Initializations for global vars, queues, etc (memsets, mutex init..) */ - GlobalInits(); - TimeInit(); - SupportFastPatternForSigMatchTypes(); - - default_packet_size = DEFAULT_PACKET_SIZE; -#ifdef __SC_CUDA_SUPPORT__ - /* Init the CUDA environment */ - SCCudaInitCudaEnvironment(); - CudaBufferInit(); -#endif - /* load the pattern matchers */ - MpmTableSetup(); -#ifdef __SC_CUDA_SUPPORT__ - MpmCudaEnvironmentSetup(); -#endif - - AppLayerSetup(); - - /* hardcoded initialization code */ - SigTableSetup(); /* load the rule keywords */ - TmqhSetup(); - - StorageInit(); - CIDRInit(); - SigParsePrepare(); - -#ifdef DBG_MEM_ALLOC - SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem); -#endif - SCReputationInitCtx(); - SCProtoNameInit(); - - TagInitCtx(); - SCReferenceConfInit(); - SCClassConfInit(); - - RegisterAllModules(); - - DetectEngineRegisterAppInspectionEngines(); - - HostBitInitCtx(); - - StorageFinalize(); - /* test and initialize the unittesting subsystem */ - if(regex_arg == NULL){ - regex_arg = ".*"; - UtRunSelftest(regex_arg); /* inits and cleans up again */ - } - - AppLayerHtpEnableRequestBodyCallback(); - AppLayerHtpNeedFileInspection(); - - UtInitialize(); - UTHRegisterTests(); - SCReputationRegisterTests(); - TmModuleRegisterTests(); - SigTableRegisterTests(); - HashTableRegisterTests(); - HashListTableRegisterTests(); - BloomFilterRegisterTests(); - BloomFilterCountingRegisterTests(); - PoolRegisterTests(); - ByteRegisterTests(); - MpmRegisterTests(); - FlowBitRegisterTests(); - HostBitRegisterTests(); - IPPairBitRegisterTests(); - StatsRegisterTests(); - DecodePPPRegisterTests(); - DecodeVLANRegisterTests(); - DecodeRawRegisterTests(); - DecodePPPOERegisterTests(); - DecodeICMPV4RegisterTests(); - DecodeICMPV6RegisterTests(); - DecodeIPV4RegisterTests(); - DecodeIPV6RegisterTests(); - DecodeTCPRegisterTests(); - DecodeUDPV4RegisterTests(); - DecodeGRERegisterTests(); - DecodeAsn1RegisterTests(); - DecodeMPLSRegisterTests(); - AppLayerProtoDetectUnittestsRegister(); - ConfRegisterTests(); - ConfYamlRegisterTests(); - TmqhFlowRegisterTests(); - FlowRegisterTests(); - HostRegisterUnittests(); - IPPairRegisterUnittests(); - SCSigRegisterSignatureOrderingTests(); - SCRadixRegisterTests(); - DefragRegisterTests(); - SigGroupHeadRegisterTests(); - SCHInfoRegisterTests(); - SCRuleVarsRegisterTests(); - AppLayerParserRegisterUnittests(); - ThreadMacrosRegisterTests(); - UtilSpmSearchRegistertests(); - UtilActionRegisterTests(); - SCClassConfRegisterTests(); - SCThresholdConfRegisterTests(); - SCRConfRegisterTests(); -#ifdef __SC_CUDA_SUPPORT__ - SCCudaRegisterTests(); -#endif - PayloadRegisterTests(); - DcePayloadRegisterTests(); - UriRegisterTests(); -#ifdef PROFILING - SCProfilingRegisterTests(); -#endif - DeStateRegisterTests(); - DetectRingBufferRegisterTests(); - MemcmpRegisterTests(); - DetectEngineHttpClientBodyRegisterTests(); - DetectEngineHttpServerBodyRegisterTests(); - DetectEngineHttpHeaderRegisterTests(); - DetectEngineHttpRawHeaderRegisterTests(); - DetectEngineHttpMethodRegisterTests(); - DetectEngineHttpCookieRegisterTests(); - DetectEngineHttpRawUriRegisterTests(); - DetectEngineHttpStatMsgRegisterTests(); - DetectEngineHttpStatCodeRegisterTests(); - DetectEngineHttpUARegisterTests(); - DetectEngineHttpHHRegisterTests(); - DetectEngineHttpHRHRegisterTests(); - DetectEngineInspectModbusRegisterTests(); - DetectEngineRegisterTests(); - DetectEngineSMTPFiledataRegisterTests(); - SCLogRegisterTests(); - MagicRegisterTests(); - UtilMiscRegisterTests(); - DetectAddressTests(); - DetectProtoTests(); - DetectPortTests(); - SCAtomicRegisterTests(); - MemrchrRegisterTests(); -#ifdef __SC_CUDA_SUPPORT__ - CudaBufferRegisterUnittests(); -#endif - AppLayerUnittestsRegister(); - MimeDecRegisterTests(); - if (list_unittests) { - UtListTests(regex_arg); - } else { - /* global packet pool */ - extern intmax_t max_pending_packets; - max_pending_packets = 128; - PacketPoolInit(); - - uint32_t failed = UtRunTests(regex_arg); - PacketPoolDestroy(); - UtCleanup(); -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA) - MpmCudaBufferDeSetup(); - CudaHandlerFreeProfiles(); -#endif - if (failed) { - exit(EXIT_FAILURE); - } - } - -#ifdef DBG_MEM_ALLOC - SCLogInfo("Total memory used (without SCFree()): %"PRIdMAX, (intmax_t)global_mem); -#endif - - exit(EXIT_SUCCESS); -#else - SCLogError(SC_ERR_NOT_SUPPORTED, "Unittests are not build-in"); - exit(EXIT_FAILURE); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/runmode-unittests.h b/framework/src/suricata/src/runmode-unittests.h deleted file mode 100644 index 8ccd296d..00000000 --- a/framework/src/suricata/src/runmode-unittests.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Eric Leblond - */ - - -#ifndef __UTIL_RUNMODE_UNITTESTS_H__ -#define __UTIL_RUNMODE_UNITTESTS_H__ - -int RunUnittests(int list_unittests, char *regex_arg); - -#endif /* __UTIL_RUNMODE_UNITTESTS_H__ */ diff --git a/framework/src/suricata/src/runmode-unix-socket.c b/framework/src/suricata/src/runmode-unix-socket.c deleted file mode 100644 index 06a71869..00000000 --- a/framework/src/suricata/src/runmode-unix-socket.c +++ /dev/null @@ -1,838 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-pcap-file.h" -#include "output.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "unix-manager.h" - -#include "detect-engine.h" - -#include "flow-manager.h" -#include "flow-timeout.h" -#include "stream-tcp.h" -#include "output.h" -#include "host.h" -#include "defrag.h" -#include "ippair.h" -#include "app-layer.h" - -#include "util-profiling.h" - -#include "conf-yaml-loader.h" - -#include "detect-engine.h" - -static const char *default_mode = NULL; - -int unix_socket_mode_is_running = 0; - -typedef struct PcapFiles_ { - char *filename; - char *output_dir; - int tenant_id; - TAILQ_ENTRY(PcapFiles_) next; -} PcapFiles; - -typedef struct PcapCommand_ { - TAILQ_HEAD(, PcapFiles_) files; - int running; - char *currentfile; -} PcapCommand; - -const char *RunModeUnixSocketGetDefaultMode(void) -{ - return default_mode; -} - -#ifdef BUILD_UNIX_SOCKET - -static int unix_manager_file_task_running = 0; -static int unix_manager_file_task_failed = 0; - -/** - * \brief return list of files in the queue - * - * \retval 0 in case of error, 1 in case of success - */ -static TmEcode UnixSocketPcapFilesList(json_t *cmd, json_t* answer, void *data) -{ - PcapCommand *this = (PcapCommand *) data; - int i = 0; - PcapFiles *file; - json_t *jdata; - json_t *jarray; - - jdata = json_object(); - if (jdata == NULL) { - json_object_set_new(answer, "message", - json_string("internal error at json object creation")); - return TM_ECODE_FAILED; - } - jarray = json_array(); - if (jarray == NULL) { - json_decref(jdata); - json_object_set_new(answer, "message", - json_string("internal error at json object creation")); - return TM_ECODE_FAILED; - } - TAILQ_FOREACH(file, &this->files, next) { - json_array_append_new(jarray, json_string(file->filename)); - i++; - } - json_object_set_new(jdata, "count", json_integer(i)); - json_object_set_new(jdata, "files", jarray); - json_object_set_new(answer, "message", jdata); - return TM_ECODE_OK; -} - -static TmEcode UnixSocketPcapFilesNumber(json_t *cmd, json_t* answer, void *data) -{ - PcapCommand *this = (PcapCommand *) data; - int i = 0; - PcapFiles *file; - - TAILQ_FOREACH(file, &this->files, next) { - i++; - } - json_object_set_new(answer, "message", json_integer(i)); - return TM_ECODE_OK; -} - -static TmEcode UnixSocketPcapCurrent(json_t *cmd, json_t* answer, void *data) -{ - PcapCommand *this = (PcapCommand *) data; - - if (this->currentfile) { - json_object_set_new(answer, "message", json_string(this->currentfile)); - } else { - json_object_set_new(answer, "message", json_string("None")); - } - return TM_ECODE_OK; -} - - - -static void PcapFilesFree(PcapFiles *cfile) -{ - if (cfile == NULL) - return; - if (cfile->filename) - SCFree(cfile->filename); - if (cfile->output_dir) - SCFree(cfile->output_dir); - SCFree(cfile); -} - -/** - * \brief Add file to file queue - * - * \param this a UnixCommand:: structure - * \param filename absolute filename - * \param output_dir absolute name of directory where log will be put - * - * \retval 0 in case of error, 1 in case of success - */ -static TmEcode UnixListAddFile(PcapCommand *this, - const char *filename, const char *output_dir, int tenant_id) -{ - PcapFiles *cfile = NULL; - if (filename == NULL || this == NULL) - return TM_ECODE_FAILED; - cfile = SCMalloc(sizeof(PcapFiles)); - if (unlikely(cfile == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate new file"); - return TM_ECODE_FAILED; - } - memset(cfile, 0, sizeof(PcapFiles)); - - cfile->filename = SCStrdup(filename); - if (unlikely(cfile->filename == NULL)) { - SCFree(cfile); - SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup filename"); - return TM_ECODE_FAILED; - } - - if (output_dir) { - cfile->output_dir = SCStrdup(output_dir); - if (unlikely(cfile->output_dir == NULL)) { - SCFree(cfile->filename); - SCFree(cfile); - SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup output_dir"); - return TM_ECODE_FAILED; - } - } - - cfile->tenant_id = tenant_id; - - TAILQ_INSERT_TAIL(&this->files, cfile, next); - return TM_ECODE_OK; -} - -/** - * \brief Command to add a file to treatment list - * - * \param cmd the content of command Arguments as a json_t object - * \param answer the json_t object that has to be used to answer - * \param data pointer to data defining the context here a PcapCommand:: - */ -TmEcode UnixSocketAddPcapFile(json_t *cmd, json_t* answer, void *data) -{ - PcapCommand *this = (PcapCommand *) data; - int ret; - const char *filename; - const char *output_dir; - int tenant_id = 0; -#ifdef OS_WIN32 - struct _stat st; -#else - struct stat st; -#endif /* OS_WIN32 */ - - json_t *jarg = json_object_get(cmd, "filename"); - if(!json_is_string(jarg)) { - SCLogInfo("error: command is not a string"); - json_object_set_new(answer, "message", json_string("command is not a string")); - return TM_ECODE_FAILED; - } - filename = json_string_value(jarg); -#ifdef OS_WIN32 - if(_stat(filename, &st) != 0) { -#else - if(stat(filename, &st) != 0) { -#endif /* OS_WIN32 */ - json_object_set_new(answer, "message", json_string("File does not exist")); - return TM_ECODE_FAILED; - } - - json_t *oarg = json_object_get(cmd, "output-dir"); - if (oarg != NULL) { - if(!json_is_string(oarg)) { - SCLogInfo("error: output dir is not a string"); - json_object_set_new(answer, "message", json_string("output dir is not a string")); - return TM_ECODE_FAILED; - } - output_dir = json_string_value(oarg); - } else { - SCLogInfo("error: can't get output-dir"); - json_object_set_new(answer, "message", json_string("output dir param is mandatory")); - return TM_ECODE_FAILED; - } - -#ifdef OS_WIN32 - if(_stat(output_dir, &st) != 0) { -#else - if(stat(output_dir, &st) != 0) { -#endif /* OS_WIN32 */ - json_object_set_new(answer, "message", json_string("Output directory does not exist")); - return TM_ECODE_FAILED; - } - - json_t *targ = json_object_get(cmd, "tenant"); - if (targ != NULL) { - if(!json_is_number(targ)) { - json_object_set_new(answer, "message", json_string("tenant is not a number")); - return TM_ECODE_FAILED; - } - tenant_id = json_number_value(targ); - } - - ret = UnixListAddFile(this, filename, output_dir, tenant_id); - switch(ret) { - case TM_ECODE_FAILED: - json_object_set_new(answer, "message", json_string("Unable to add file to list")); - return TM_ECODE_FAILED; - case TM_ECODE_OK: - SCLogInfo("Added file '%s' to list", filename); - json_object_set_new(answer, "message", json_string("Successfully added file to list")); - return TM_ECODE_OK; - } - return TM_ECODE_OK; -} - -/** - * \brief Handle the file queue - * - * This function check if there is currently a file - * being parse. If it is not the case, it will start to - * work on a new file. This implies to start a new 'pcap-file' - * running mode after having set the file and the output dir. - * This function also handles the cleaning of the previous - * running mode. - * - * \param this a UnixCommand:: structure - * \retval 0 in case of error, 1 in case of success - */ -TmEcode UnixSocketPcapFilesCheck(void *data) -{ - PcapCommand *this = (PcapCommand *) data; - if (unix_manager_file_task_running == 1) { - return TM_ECODE_OK; - } - if ((unix_manager_file_task_failed == 1) || (this->running == 1)) { - if (unix_manager_file_task_failed) { - SCLogInfo("Preceeding task failed, cleaning the running mode"); - } - unix_manager_file_task_failed = 0; - this->running = 0; - if (this->currentfile) { - SCFree(this->currentfile); - } - this->currentfile = NULL; - - /* needed by FlowForceReassembly */ - PacketPoolInit(); - - /* handle graceful shutdown of the flow engine, it's helper - * threads and the packet threads */ - FlowDisableFlowManagerThread(); - TmThreadDisableReceiveThreads(); - FlowForceReassembly(); - TmThreadDisablePacketThreads(); - FlowDisableFlowRecyclerThread(); - - /* kill the stats threads */ - TmThreadKillThreadsFamily(TVT_MGMT); - TmThreadClearThreadsFamily(TVT_MGMT); - - /* kill packet threads -- already in 'disabled' state */ - TmThreadKillThreadsFamily(TVT_PPT); - TmThreadClearThreadsFamily(TVT_PPT); - - PacketPoolDestroy(); - - /* mgt and ppt threads killed, we can run non thread-safe - * shutdown functions */ - StatsReleaseResources(); - RunModeShutDown(); - FlowShutdown(); - IPPairShutdown(); - HostCleanup(); - StreamTcpFreeConfig(STREAM_VERBOSE); - DefragDestroy(); - TmqResetQueues(); -#ifdef PROFILING - if (profiling_rules_enabled) - SCProfilingDump(); - SCProfilingDestroy(); -#endif - } - if (!TAILQ_EMPTY(&this->files)) { - PcapFiles *cfile = TAILQ_FIRST(&this->files); - TAILQ_REMOVE(&this->files, cfile, next); - SCLogInfo("Starting run for '%s'", cfile->filename); - unix_manager_file_task_running = 1; - this->running = 1; - if (ConfSet("pcap-file.file", cfile->filename) != 1) { - SCLogInfo("Can not set working file to '%s'", cfile->filename); - PcapFilesFree(cfile); - return TM_ECODE_FAILED; - } - if (cfile->output_dir) { - if (ConfSet("default-log-dir", cfile->output_dir) != 1) { - SCLogInfo("Can not set output dir to '%s'", cfile->output_dir); - PcapFilesFree(cfile); - return TM_ECODE_FAILED; - } - } - if (cfile->tenant_id > 0) { - char tstr[16] = ""; - snprintf(tstr, sizeof(tstr), "%d", cfile->tenant_id); - if (ConfSet("pcap-file.tenant-id", tstr) != 1) { - SCLogInfo("Can not set working tenant-id to '%s'", tstr); - PcapFilesFree(cfile); - return TM_ECODE_FAILED; - } - } else { - SCLogInfo("pcap-file.tenant-id not set"); - } - this->currentfile = SCStrdup(cfile->filename); - if (unlikely(this->currentfile == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed file name allocation"); - return TM_ECODE_FAILED; - } - PcapFilesFree(cfile); - StatsInit(); -#ifdef PROFILING - SCProfilingRulesGlobalInit(); - SCProfilingKeywordsGlobalInit(); - SCProfilingInit(); -#endif /* PROFILING */ - DefragInit(); - FlowInitConfig(FLOW_QUIET); - IPPairInitConfig(FLOW_QUIET); - StreamTcpInitConfig(STREAM_VERBOSE); - AppLayerRegisterGlobalCounters(); - RunModeInitializeOutputs(); - StatsSetupPostConfig(); - RunModeDispatch(RUNMODE_PCAP_FILE, NULL); - FlowManagerThreadSpawn(); - FlowRecyclerThreadSpawn(); - StatsSpawnThreads(); - /* Un-pause all the paused threads */ - TmThreadContinueThreads(); - } - return TM_ECODE_OK; -} -#endif - -void RunModeUnixSocketRegister(void) -{ -#ifdef BUILD_UNIX_SOCKET - RunModeRegisterNewRunMode(RUNMODE_UNIX_SOCKET, "single", - "Unix socket mode", - RunModeUnixSocketSingle); - default_mode = "single"; -#endif - return; -} - -void UnixSocketPcapFile(TmEcode tm) -{ -#ifdef BUILD_UNIX_SOCKET - switch (tm) { - case TM_ECODE_DONE: - unix_manager_file_task_running = 0; - break; - case TM_ECODE_FAILED: - unix_manager_file_task_running = 0; - unix_manager_file_task_failed = 1; - break; - case TM_ECODE_OK: - break; - } -#endif -} - -#ifdef BUILD_UNIX_SOCKET -/** - * \brief Command to add a tenant handler - * - * \param cmd the content of command Arguments as a json_t object - * \param answer the json_t object that has to be used to answer - * \param data pointer to data defining the context here a PcapCommand:: - */ -TmEcode UnixSocketRegisterTenantHandler(json_t *cmd, json_t* answer, void *data) -{ - const char *htype; - json_int_t traffic_id = -1; - - if (!(DetectEngineMultiTenantEnabled())) { - SCLogInfo("error: multi-tenant support not enabled"); - json_object_set_new(answer, "message", json_string("multi-tenant support not enabled")); - return TM_ECODE_FAILED; - } - - /* 1 get tenant id */ - json_t *jarg = json_object_get(cmd, "id"); - if (!json_is_integer(jarg)) { - SCLogInfo("error: command is not a string"); - json_object_set_new(answer, "message", json_string("id is not an integer")); - return TM_ECODE_FAILED; - } - int tenant_id = json_integer_value(jarg); - - /* 2 get tenant handler type */ - jarg = json_object_get(cmd, "htype"); - if (!json_is_string(jarg)) { - SCLogInfo("error: command is not a string"); - json_object_set_new(answer, "message", json_string("command is not a string")); - return TM_ECODE_FAILED; - } - htype = json_string_value(jarg); - - SCLogDebug("add-tenant-handler: %d %s", tenant_id, htype); - - /* 3 get optional hargs */ - json_t *hargs = json_object_get(cmd, "hargs"); - if (hargs != NULL) { - if (!json_is_integer(hargs)) { - SCLogInfo("error: hargs not a number"); - json_object_set_new(answer, "message", json_string("hargs not a number")); - return TM_ECODE_FAILED; - } - traffic_id = json_integer_value(hargs); - } - - /* 4 add to system */ - int r = -1; - if (strcmp(htype, "pcap") == 0) { - r = DetectEngineTentantRegisterPcapFile(tenant_id); - } else if (strcmp(htype, "vlan") == 0) { - if (traffic_id < 0) { - json_object_set_new(answer, "message", json_string("vlan requires argument")); - return TM_ECODE_FAILED; - } - if (traffic_id > USHRT_MAX) { - json_object_set_new(answer, "message", json_string("vlan argument out of range")); - return TM_ECODE_FAILED; - } - - SCLogInfo("VLAN handler: id %u maps to tenant %u", (uint32_t)traffic_id, tenant_id); - r = DetectEngineTentantRegisterVlanId(tenant_id, (uint32_t)traffic_id); - } - if (r != 0) { - json_object_set_new(answer, "message", json_string("handler setup failure")); - return TM_ECODE_FAILED; - } - - if (DetectEngineMTApply() < 0) { - json_object_set_new(answer, "message", json_string("couldn't apply settings")); - // TODO cleanup - return TM_ECODE_FAILED; - } - - json_object_set_new(answer, "message", json_string("handler added")); - return TM_ECODE_OK; -} - -/** - * \brief Command to remove a tenant handler - * - * \param cmd the content of command Arguments as a json_t object - * \param answer the json_t object that has to be used to answer - * \param data pointer to data defining the context here a PcapCommand:: - */ -TmEcode UnixSocketUnregisterTenantHandler(json_t *cmd, json_t* answer, void *data) -{ - const char *htype; - json_int_t traffic_id = -1; - - if (!(DetectEngineMultiTenantEnabled())) { - SCLogInfo("error: multi-tenant support not enabled"); - json_object_set_new(answer, "message", json_string("multi-tenant support not enabled")); - return TM_ECODE_FAILED; - } - - /* 1 get tenant id */ - json_t *jarg = json_object_get(cmd, "id"); - if (!json_is_integer(jarg)) { - SCLogInfo("error: command is not a string"); - json_object_set_new(answer, "message", json_string("id is not an integer")); - return TM_ECODE_FAILED; - } - int tenant_id = json_integer_value(jarg); - - /* 2 get tenant handler type */ - jarg = json_object_get(cmd, "htype"); - if (!json_is_string(jarg)) { - SCLogInfo("error: command is not a string"); - json_object_set_new(answer, "message", json_string("command is not a string")); - return TM_ECODE_FAILED; - } - htype = json_string_value(jarg); - - SCLogDebug("add-tenant-handler: %d %s", tenant_id, htype); - - /* 3 get optional hargs */ - json_t *hargs = json_object_get(cmd, "hargs"); - if (hargs != NULL) { - if (!json_is_integer(hargs)) { - SCLogInfo("error: hargs not a number"); - json_object_set_new(answer, "message", json_string("hargs not a number")); - return TM_ECODE_FAILED; - } - traffic_id = json_integer_value(hargs); - } - - /* 4 add to system */ - int r = -1; - if (strcmp(htype, "pcap") == 0) { - r = DetectEngineTentantUnregisterPcapFile(tenant_id); - } else if (strcmp(htype, "vlan") == 0) { - if (traffic_id < 0) { - json_object_set_new(answer, "message", json_string("vlan requires argument")); - return TM_ECODE_FAILED; - } - if (traffic_id > USHRT_MAX) { - json_object_set_new(answer, "message", json_string("vlan argument out of range")); - return TM_ECODE_FAILED; - } - - SCLogInfo("VLAN handler: id %u maps to tenant %u", (uint32_t)traffic_id, tenant_id); - r = DetectEngineTentantUnregisterVlanId(tenant_id, (uint32_t)traffic_id); - } - if (r != 0) { - json_object_set_new(answer, "message", json_string("handler unregister failure")); - return TM_ECODE_FAILED; - } - - /* 5 apply it */ - if (DetectEngineMTApply() < 0) { - json_object_set_new(answer, "message", json_string("couldn't apply settings")); - // TODO cleanup - return TM_ECODE_FAILED; - } - - json_object_set_new(answer, "message", json_string("handler added")); - return TM_ECODE_OK; -} - -/** - * \brief Command to add a tenant - * - * \param cmd the content of command Arguments as a json_t object - * \param answer the json_t object that has to be used to answer - * \param data pointer to data defining the context here a PcapCommand:: - */ -TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data) -{ - const char *filename; -#ifdef OS_WIN32 - struct _stat st; -#else - struct stat st; -#endif /* OS_WIN32 */ - - if (!(DetectEngineMultiTenantEnabled())) { - SCLogInfo("error: multi-tenant support not enabled"); - json_object_set_new(answer, "message", json_string("multi-tenant support not enabled")); - return TM_ECODE_FAILED; - } - - /* 1 get tenant id */ - json_t *jarg = json_object_get(cmd, "id"); - if (!json_is_integer(jarg)) { - json_object_set_new(answer, "message", json_string("id is not an integer")); - return TM_ECODE_FAILED; - } - int tenant_id = json_integer_value(jarg); - - /* 2 get tenant yaml */ - jarg = json_object_get(cmd, "filename"); - if (!json_is_string(jarg)) { - json_object_set_new(answer, "message", json_string("command is not a string")); - return TM_ECODE_FAILED; - } - filename = json_string_value(jarg); -#ifdef OS_WIN32 - if(_stat(filename, &st) != 0) { -#else - if(stat(filename, &st) != 0) { -#endif /* OS_WIN32 */ - json_object_set_new(answer, "message", json_string("file does not exist")); - return TM_ECODE_FAILED; - } - - SCLogDebug("add-tenant: %d %s", tenant_id, filename); - - /* setup the yaml in this loop so that it's not done by the loader - * threads. ConfYamlLoadFileWithPrefix is not thread safe. */ - char prefix[64]; - snprintf(prefix, sizeof(prefix), "multi-detect.%d", tenant_id); - if (ConfYamlLoadFileWithPrefix(filename, prefix) != 0) { - SCLogError(SC_ERR_CONF_YAML_ERROR, "failed to load yaml %s", filename); - json_object_set_new(answer, "message", json_string("failed to load yaml")); - return TM_ECODE_FAILED; - } - - /* 3 load into the system */ - if (DetectEngineLoadTenantBlocking(tenant_id, filename) != 0) { - json_object_set_new(answer, "message", json_string("adding tenant failed")); - return TM_ECODE_FAILED; - } - - /* 4 apply to the running system */ - if (DetectEngineMTApply() < 0) { - json_object_set_new(answer, "message", json_string("couldn't apply settings")); - // TODO cleanup - return TM_ECODE_FAILED; - } - - json_object_set_new(answer, "message", json_string("adding tenant succeeded")); - return TM_ECODE_OK; -} - -static int reload_cnt = 1; -/** - * \brief Command to reload a tenant - * - * \param cmd the content of command Arguments as a json_t object - * \param answer the json_t object that has to be used to answer - * \param data pointer to data defining the context here a PcapCommand:: - */ -TmEcode UnixSocketReloadTenant(json_t *cmd, json_t* answer, void *data) -{ - const char *filename; -#ifdef OS_WIN32 - struct _stat st; -#else - struct stat st; -#endif /* OS_WIN32 */ - - if (!(DetectEngineMultiTenantEnabled())) { - SCLogInfo("error: multi-tenant support not enabled"); - json_object_set_new(answer, "message", json_string("multi-tenant support not enabled")); - return TM_ECODE_FAILED; - } - - /* 1 get tenant id */ - json_t *jarg = json_object_get(cmd, "id"); - if (!json_is_integer(jarg)) { - json_object_set_new(answer, "message", json_string("id is not an integer")); - return TM_ECODE_FAILED; - } - int tenant_id = json_integer_value(jarg); - - /* 2 get tenant yaml */ - jarg = json_object_get(cmd, "filename"); - if (!json_is_string(jarg)) { - json_object_set_new(answer, "message", json_string("command is not a string")); - return TM_ECODE_FAILED; - } - filename = json_string_value(jarg); -#ifdef OS_WIN32 - if(_stat(filename, &st) != 0) { -#else - if(stat(filename, &st) != 0) { -#endif /* OS_WIN32 */ - json_object_set_new(answer, "message", json_string("file does not exist")); - return TM_ECODE_FAILED; - } - - SCLogDebug("reload-tenant: %d %s", tenant_id, filename); - - char prefix[64]; - snprintf(prefix, sizeof(prefix), "multi-detect.%d.reload.%d", tenant_id, reload_cnt); - SCLogInfo("prefix %s", prefix); - - if (ConfYamlLoadFileWithPrefix(filename, prefix) != 0) { - json_object_set_new(answer, "message", json_string("failed to load yaml")); - return TM_ECODE_FAILED; - } - - /* 3 load into the system */ - if (DetectEngineReloadTenantBlocking(tenant_id, filename, reload_cnt) != 0) { - json_object_set_new(answer, "message", json_string("reload tenant failed")); - return TM_ECODE_FAILED; - } - - reload_cnt++; - - /* apply to the running system */ - if (DetectEngineMTApply() < 0) { - json_object_set_new(answer, "message", json_string("couldn't apply settings")); - // TODO cleanup - return TM_ECODE_FAILED; - } - - json_object_set_new(answer, "message", json_string("reloading tenant succeeded")); - return TM_ECODE_OK; -} - -/** - * \brief Command to remove a tenant - * - * \param cmd the content of command Arguments as a json_t object - * \param answer the json_t object that has to be used to answer - * \param data pointer to data defining the context here a PcapCommand:: - */ -TmEcode UnixSocketUnregisterTenant(json_t *cmd, json_t* answer, void *data) -{ - if (!(DetectEngineMultiTenantEnabled())) { - SCLogInfo("error: multi-tenant support not enabled"); - json_object_set_new(answer, "message", json_string("multi-tenant support not enabled")); - return TM_ECODE_FAILED; - } - - /* 1 get tenant id */ - json_t *jarg = json_object_get(cmd, "id"); - if (!json_is_integer(jarg)) { - SCLogInfo("error: command is not a string"); - json_object_set_new(answer, "message", json_string("id is not an integer")); - return TM_ECODE_FAILED; - } - int tenant_id = json_integer_value(jarg); - - SCLogInfo("remove-tenant: %d TODO", tenant_id); - - /* 2 remove it from the system */ - char prefix[64]; - snprintf(prefix, sizeof(prefix), "multi-detect.%d", tenant_id); - - DetectEngineCtx *de_ctx = DetectEngineGetByTenantId(tenant_id); - if (de_ctx == NULL) { - json_object_set_new(answer, "message", json_string("tenant detect engine not found")); - return TM_ECODE_FAILED; - } - - /* move to free list */ - DetectEngineMoveToFreeList(de_ctx); - DetectEngineDeReference(&de_ctx); - - /* update the threads */ - if (DetectEngineMTApply() < 0) { - json_object_set_new(answer, "message", json_string("couldn't apply settings")); - // TODO cleanup - return TM_ECODE_FAILED; - } - - /* walk free list, freeing the removed de_ctx */ - DetectEnginePruneFreeList(); - - json_object_set_new(answer, "message", json_string("work in progress")); - return TM_ECODE_OK; -} -#endif /* BUILD_UNIX_SOCKET */ - -/** - * \brief Single thread version of the Pcap file processing. - */ -int RunModeUnixSocketSingle(void) -{ -#ifdef BUILD_UNIX_SOCKET - PcapCommand *pcapcmd = SCMalloc(sizeof(PcapCommand)); - - if (unlikely(pcapcmd == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can not allocate pcap command"); - return 1; - } - TAILQ_INIT(&pcapcmd->files); - pcapcmd->running = 0; - pcapcmd->currentfile = NULL; - - UnixManagerThreadSpawn(1); - - unix_socket_mode_is_running = 1; - - UnixManagerRegisterCommand("pcap-file", UnixSocketAddPcapFile, pcapcmd, UNIX_CMD_TAKE_ARGS); - UnixManagerRegisterCommand("pcap-file-number", UnixSocketPcapFilesNumber, pcapcmd, 0); - UnixManagerRegisterCommand("pcap-file-list", UnixSocketPcapFilesList, pcapcmd, 0); - UnixManagerRegisterCommand("pcap-current", UnixSocketPcapCurrent, pcapcmd, 0); - - UnixManagerRegisterBackgroundTask(UnixSocketPcapFilesCheck, pcapcmd); -#endif - - return 0; -} - -int RunModeUnixSocketIsActive(void) -{ - return unix_socket_mode_is_running; -} - - - - diff --git a/framework/src/suricata/src/runmode-unix-socket.h b/framework/src/suricata/src/runmode-unix-socket.h deleted file mode 100644 index 20b0fea4..00000000 --- a/framework/src/suricata/src/runmode-unix-socket.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Eric Leblond - */ - -#ifndef __RUNMODE_UNIX_SOCKET_H__ -#define __RUNMODE_UNIX_SOCKET_H__ - -int RunModeUnixSocketSingle(void); -void RunModeUnixSocketRegister(void); -const char *RunModeUnixSocketGetDefaultMode(void); - -int RunModeUnixSocketIsActive(void); - -void UnixSocketPcapFile(TmEcode tm); - -#ifdef BUILD_UNIX_SOCKET -TmEcode UnixSocketRegisterTenantHandler(json_t *cmd, json_t* answer, void *data); -TmEcode UnixSocketUnregisterTenantHandler(json_t *cmd, json_t* answer, void *data); -TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data); -TmEcode UnixSocketReloadTenant(json_t *cmd, json_t* answer, void *data); -TmEcode UnixSocketUnregisterTenant(json_t *cmd, json_t* answer, void *data); -#endif - -#endif /* __RUNMODE_UNIX_SOCKET_H__ */ diff --git a/framework/src/suricata/src/runmodes.c b/framework/src/suricata/src/runmodes.c deleted file mode 100644 index 5a9f9762..00000000 --- a/framework/src/suricata/src/runmodes.c +++ /dev/null @@ -1,927 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - * - * Pre-cooked threading runmodes. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "tm-threads.h" -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-byte.h" -#include "util-affinity.h" -#include "conf.h" -#include "queue.h" -#include "runmodes.h" -#include "util-unittest.h" -#include "util-misc.h" - -#include "alert-fastlog.h" -#include "alert-prelude.h" -#include "alert-unified2-alert.h" -#include "alert-debuglog.h" - -#include "log-httplog.h" - -#include "output.h" - -#include "source-pfring.h" - -int debuglog_enabled = 0; - -/** - * \brief Holds description for a runmode. - */ -typedef struct RunMode_ { - /* the runmode type */ - int runmode; - const char *name; - const char *description; - /* runmode function */ - int (*RunModeFunc)(void); -} RunMode; - -typedef struct RunModes_ { - int no_of_runmodes; - RunMode *runmodes; -} RunModes; - -/** - * A list of output modules that will be active for the run mode. - */ -typedef struct RunModeOutput_ { - const char *name; - TmModule *tm_module; - OutputCtx *output_ctx; - - TAILQ_ENTRY(RunModeOutput_) entries; -} RunModeOutput; -TAILQ_HEAD(, RunModeOutput_) RunModeOutputs = - TAILQ_HEAD_INITIALIZER(RunModeOutputs); - -static RunModes runmodes[RUNMODE_USER_MAX]; - -static char *active_runmode; - -/* free list for our outputs */ -typedef struct OutputFreeList_ { - TmModule *tm_module; - OutputCtx *output_ctx; - - TAILQ_ENTRY(OutputFreeList_) entries; -} OutputFreeList; -TAILQ_HEAD(, OutputFreeList_) output_free_list = - TAILQ_HEAD_INITIALIZER(output_free_list); - -/** - * \internal - * \brief Translate a runmode mode to a printale string. - * - * \param runmode Runmode to be converted into a printable string. - * - * \retval string Printable string. - */ -static const char *RunModeTranslateModeToName(int runmode) -{ - switch (runmode) { - case RUNMODE_PCAP_DEV: - return "PCAP_DEV"; - case RUNMODE_PCAP_FILE: - return "PCAP_FILE"; - case RUNMODE_PFRING: -#ifdef HAVE_PFRING - return "PFRING"; -#else - return "PFRING(DISABLED)"; -#endif - case RUNMODE_NFQ: - return "NFQ"; - case RUNMODE_NFLOG: - return "NFLOG"; - case RUNMODE_IPFW: - return "IPFW"; - case RUNMODE_ERF_FILE: - return "ERF_FILE"; - case RUNMODE_DAG: - return "ERF_DAG"; - case RUNMODE_NAPATECH: - return "NAPATECH"; - case RUNMODE_UNITTEST: - return "UNITTEST"; - case RUNMODE_TILERA_MPIPE: - return "MPIPE"; - case RUNMODE_AFP_DEV: - return "AF_PACKET_DEV"; - case RUNMODE_NETMAP: -#ifdef HAVE_NETMAP - return "NETMAP"; -#else - return "NETMAP(DISABLED)"; -#endif - case RUNMODE_UNIX_SOCKET: - return "UNIX_SOCKET"; - default: - SCLogError(SC_ERR_UNKNOWN_RUN_MODE, "Unknown runtime mode. Aborting"); - exit(EXIT_FAILURE); - } -} - -/** - * \internal - * \brief Dispatcher function for runmodes. Calls the required runmode function - * based on runmode + runmode_custom_id. - * - * \param runmode The runmode type. - * \param runmode_customd_id The runmode custom id. - */ -static RunMode *RunModeGetCustomMode(int runmode, const char *custom_mode) -{ - int i; - - for (i = 0; i < runmodes[runmode].no_of_runmodes; i++) { - if (strcmp(runmodes[runmode].runmodes[i].name, custom_mode) == 0) - return &runmodes[runmode].runmodes[i]; - } - - return NULL; -} - - -/** - * Return the running mode - * - * The returned string must not be freed. - * - * \return a string containing the current running mode - */ -char *RunmodeGetActive(void) -{ - return active_runmode; -} - -/** - * Return the running mode - * - * The returned string must not be freed. - * - * \return a string containing the current running mode - */ -const char *RunModeGetMainMode(void) -{ - int mainmode = RunmodeGetCurrent(); - - return RunModeTranslateModeToName(mainmode); -} - -/** - * \brief Register all runmodes in the engine. - */ -void RunModeRegisterRunModes(void) -{ - memset(runmodes, 0, sizeof(runmodes)); - - RunModeIdsPcapRegister(); - RunModeFilePcapRegister(); - RunModeIdsPfringRegister(); - RunModeIpsNFQRegister(); - RunModeIpsIPFWRegister(); - RunModeErfFileRegister(); - RunModeErfDagRegister(); - RunModeNapatechRegister(); - RunModeIdsAFPRegister(); - RunModeIdsNetmapRegister(); - RunModeIdsNflogRegister(); - RunModeTileMpipeRegister(); - RunModeUnixSocketRegister(); -#ifdef UNITTESTS - UtRunModeRegister(); -#endif - return; -} - -/** - * \brief Lists all registered runmodes. - */ -void RunModeListRunmodes(void) -{ - printf("------------------------------------- Runmodes -------------------" - "-----------------------\n"); - - printf("| %-17s | %-17s | %-10s \n", - "RunMode Type", "Custom Mode ", "Description"); - printf("|-----------------------------------------------------------------" - "-----------------------\n"); - int i = RUNMODE_UNKNOWN + 1; - int j = 0; - for ( ; i < RUNMODE_USER_MAX; i++) { - int mode_displayed = 0; - for (j = 0; j < runmodes[i].no_of_runmodes; j++) { - if (mode_displayed == 1) { - printf("| ----------------------------------------------" - "-----------------------\n"); - RunMode *runmode = &runmodes[i].runmodes[j]; - printf("| %-17s | %-17s | %-27s \n", - "", - runmode->name, - runmode->description); - } else { - RunMode *runmode = &runmodes[i].runmodes[j]; - printf("| %-17s | %-17s | %-27s \n", - RunModeTranslateModeToName(runmode->runmode), - runmode->name, - runmode->description); - } - if (mode_displayed == 0) - mode_displayed = 1; - } - if (mode_displayed == 1) { - printf("|-----------------------------------------------------------------" - "-----------------------\n"); - } - } - - return; -} - -/** - */ -void RunModeDispatch(int runmode, const char *custom_mode) -{ - char *local_custom_mode = NULL; - - if (custom_mode == NULL) { - char *val = NULL; - if (ConfGet("runmode", &val) != 1) { - custom_mode = NULL; - } else { - custom_mode = val; - } - } - - if (custom_mode == NULL || strcmp(custom_mode, "auto") == 0) { - switch (runmode) { - case RUNMODE_PCAP_DEV: - custom_mode = RunModeIdsGetDefaultMode(); - break; - case RUNMODE_PCAP_FILE: - custom_mode = RunModeFilePcapGetDefaultMode(); - break; -#ifdef HAVE_PFRING - case RUNMODE_PFRING: - custom_mode = RunModeIdsPfringGetDefaultMode(); - break; -#endif - case RUNMODE_NFQ: - custom_mode = RunModeIpsNFQGetDefaultMode(); - break; - case RUNMODE_IPFW: - custom_mode = RunModeIpsIPFWGetDefaultMode(); - break; - case RUNMODE_ERF_FILE: - custom_mode = RunModeErfFileGetDefaultMode(); - break; - case RUNMODE_DAG: - custom_mode = RunModeErfDagGetDefaultMode(); - break; - case RUNMODE_TILERA_MPIPE: - custom_mode = RunModeTileMpipeGetDefaultMode(); - break; - case RUNMODE_NAPATECH: - custom_mode = RunModeNapatechGetDefaultMode(); - break; - case RUNMODE_AFP_DEV: - custom_mode = RunModeAFPGetDefaultMode(); - break; - case RUNMODE_NETMAP: - custom_mode = RunModeNetmapGetDefaultMode(); - break; - case RUNMODE_UNIX_SOCKET: - custom_mode = RunModeUnixSocketGetDefaultMode(); - break; - case RUNMODE_NFLOG: - custom_mode = RunModeIdsNflogGetDefaultMode(); - break; - default: - SCLogError(SC_ERR_UNKNOWN_RUN_MODE, "Unknown runtime mode. Aborting"); - exit(EXIT_FAILURE); - } - } else { /* if (custom_mode == NULL) */ - /* Add compability with old 'worker' name */ - if (!strcmp("worker", custom_mode)) { - SCLogWarning(SC_ERR_RUNMODE, "'worker' mode have been renamed " - "to 'workers', please modify your setup."); - local_custom_mode = SCStrdup("workers"); - if (unlikely(local_custom_mode == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup custom mode"); - exit(EXIT_FAILURE); - } - custom_mode = local_custom_mode; - } - } - -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA && - strcasecmp(custom_mode, "autofp") != 0) { - SCLogError(SC_ERR_RUNMODE, "When using a cuda mpm, the only runmode we " - "support is autofp."); - exit(EXIT_FAILURE); - } -#endif - - RunMode *mode = RunModeGetCustomMode(runmode, custom_mode); - if (mode == NULL) { - SCLogError(SC_ERR_RUNMODE, "The custom type \"%s\" doesn't exist " - "for this runmode type \"%s\". Please use --list-runmodes to " - "see available custom types for this runmode", - custom_mode, RunModeTranslateModeToName(runmode)); - exit(EXIT_FAILURE); - } - - /* Export the custom mode */ - active_runmode = SCStrdup(custom_mode); - if (unlikely(active_runmode == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup active mode"); - exit(EXIT_FAILURE); - } - - mode->RunModeFunc(); - - if (local_custom_mode != NULL) - SCFree(local_custom_mode); - return; -} - -/** - * \brief Registers a new runmode. - * - * \param runmode Runmode type. - * \param name Custom mode for this specific runmode type. Within each - * runmode type, each custom name is a primary key. - * \param description Description for this runmode. - * \param RunModeFunc The function to be run for this runmode. - */ -void RunModeRegisterNewRunMode(int runmode, const char *name, - const char *description, - int (*RunModeFunc)(void)) -{ - void *ptmp; - if (RunModeGetCustomMode(runmode, name) != NULL) { - SCLogError(SC_ERR_RUNMODE, "A runmode by this custom name has already " - "been registered. Please use an unique name"); - return; - } - - ptmp = SCRealloc(runmodes[runmode].runmodes, - (runmodes[runmode].no_of_runmodes + 1) * sizeof(RunMode)); - if (ptmp == NULL) { - SCFree(runmodes[runmode].runmodes); - runmodes[runmode].runmodes = NULL; - exit(EXIT_FAILURE); - } - runmodes[runmode].runmodes = ptmp; - - RunMode *mode = &runmodes[runmode].runmodes[runmodes[runmode].no_of_runmodes]; - runmodes[runmode].no_of_runmodes++; - - mode->runmode = runmode; - mode->name = SCStrdup(name); - if (unlikely(mode->name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate string"); - exit(EXIT_FAILURE); - } - mode->description = SCStrdup(description); - if (unlikely(mode->description == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate string"); - exit(EXIT_FAILURE); - } - mode->RunModeFunc = RunModeFunc; - - return; -} - -/** - * Setup the outputs for this run mode. - * - * \param tv The ThreadVars for the thread the outputs will be - * appended to. - */ -void RunOutputFreeList(void) -{ - OutputFreeList *output; - while ((output = TAILQ_FIRST(&output_free_list))) { - SCLogDebug("output %s %p %p", output->tm_module->name, output, output->output_ctx); - - if (output->output_ctx != NULL && output->output_ctx->DeInit != NULL) - output->output_ctx->DeInit(output->output_ctx); - - TAILQ_REMOVE(&output_free_list, output, entries); - SCFree(output); - } -} - -static TmModule *pkt_logger_module = NULL; -static TmModule *tx_logger_module = NULL; -static TmModule *file_logger_module = NULL; -static TmModule *filedata_logger_module = NULL; -static TmModule *streaming_logger_module = NULL; - -int RunModeOutputFileEnabled(void) -{ - return (file_logger_module != NULL); -} - -int RunModeOutputFiledataEnabled(void) -{ - return (filedata_logger_module != NULL); -} - -/** - * Cleanup the run mode. - */ -void RunModeShutDown(void) -{ - RunOutputFreeList(); - - OutputPacketShutdown(); - OutputTxShutdown(); - OutputFileShutdown(); - OutputFiledataShutdown(); - OutputStreamingShutdown(); - OutputStatsShutdown(); - OutputFlowShutdown(); - - /* Close any log files. */ - RunModeOutput *output; - while ((output = TAILQ_FIRST(&RunModeOutputs))) { - SCLogDebug("Shutting down output %s.", output->tm_module->name); - TAILQ_REMOVE(&RunModeOutputs, output, entries); - SCFree(output); - } - - /* reset logger pointers */ - pkt_logger_module = NULL; - tx_logger_module = NULL; - file_logger_module = NULL; - filedata_logger_module = NULL; - streaming_logger_module = NULL; -} - -/** \internal - * \brief add Sub RunModeOutput to list for Submodule so we can free - * the output ctx at shutdown and unix socket reload */ -static void AddOutputToFreeList(OutputModule *module, OutputCtx *output_ctx) -{ - TmModule *tm_module = TmModuleGetByName(module->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", module->name); - exit(EXIT_FAILURE); - } - OutputFreeList *fl_output = SCCalloc(1, sizeof(OutputFreeList)); - if (unlikely(fl_output == NULL)) - return; - fl_output->tm_module = tm_module; - fl_output->output_ctx = output_ctx; - TAILQ_INSERT_TAIL(&output_free_list, fl_output, entries); -} - - -static int GetRunModeOutputPriority(RunModeOutput *module) -{ - TmModule *tm = TmModuleGetByName(module->name); - if (tm == NULL) - return 0; - - return tm->priority; -} - -static void InsertInRunModeOutputs(RunModeOutput *runmode_output) -{ - RunModeOutput *r_output = NULL; - int output_priority = GetRunModeOutputPriority(runmode_output); - - TAILQ_FOREACH(r_output, &RunModeOutputs, entries) { - if (GetRunModeOutputPriority(r_output) < output_priority) - break; - } - if (r_output) { - TAILQ_INSERT_BEFORE(r_output, runmode_output, entries); - } else { - TAILQ_INSERT_TAIL(&RunModeOutputs, runmode_output, entries); - } -} - -/** \brief Turn output into thread module */ -static void SetupOutput(const char *name, OutputModule *module, OutputCtx *output_ctx) -{ - /* flow logger doesn't run in the packet path */ - if (module->FlowLogFunc) { - OutputRegisterFlowLogger(module->name, module->FlowLogFunc, output_ctx); - return; - } - /* stats logger doesn't run in the packet path */ - if (module->StatsLogFunc) { - OutputRegisterStatsLogger(module->name, module->StatsLogFunc, output_ctx); - return; - } - - TmModule *tm_module = TmModuleGetByName(module->name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for %s failed", module->name); - exit(EXIT_FAILURE); - } - if (strcmp(tmm_modules[TMM_ALERTDEBUGLOG].name, tm_module->name) == 0) - debuglog_enabled = 1; - - if (module->PacketLogFunc) { - SCLogDebug("%s is a packet logger", module->name); - OutputRegisterPacketLogger(module->name, module->PacketLogFunc, - module->PacketConditionFunc, output_ctx); - - /* need one instance of the packet logger module */ - if (pkt_logger_module == NULL) { - pkt_logger_module = TmModuleGetByName("__packet_logger__"); - if (pkt_logger_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for __packet_logger__ failed"); - exit(EXIT_FAILURE); - } - - RunModeOutput *runmode_output = SCCalloc(1, sizeof(RunModeOutput)); - if (unlikely(runmode_output == NULL)) - return; - runmode_output->name = module->name; - runmode_output->tm_module = pkt_logger_module; - runmode_output->output_ctx = NULL; - InsertInRunModeOutputs(runmode_output); - SCLogDebug("__packet_logger__ added"); - } - } else if (module->TxLogFunc) { - SCLogDebug("%s is a tx logger", module->name); - OutputRegisterTxLogger(module->name, module->alproto, - module->TxLogFunc, output_ctx); - - /* need one instance of the tx logger module */ - if (tx_logger_module == NULL) { - tx_logger_module = TmModuleGetByName("__tx_logger__"); - if (tx_logger_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for __tx_logger__ failed"); - exit(EXIT_FAILURE); - } - - RunModeOutput *runmode_output = SCCalloc(1, sizeof(RunModeOutput)); - if (unlikely(runmode_output == NULL)) - return; - runmode_output->name = module->name; - runmode_output->tm_module = tx_logger_module; - runmode_output->output_ctx = NULL; - InsertInRunModeOutputs(runmode_output); - SCLogDebug("__tx_logger__ added"); - } - } else if (module->FiledataLogFunc) { - SCLogDebug("%s is a filedata logger", module->name); - OutputRegisterFiledataLogger(module->name, module->FiledataLogFunc, output_ctx); - - /* need one instance of the tx logger module */ - if (filedata_logger_module == NULL) { - filedata_logger_module = TmModuleGetByName("__filedata_logger__"); - if (filedata_logger_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for __filedata_logger__ failed"); - exit(EXIT_FAILURE); - } - - RunModeOutput *runmode_output = SCCalloc(1, sizeof(RunModeOutput)); - if (unlikely(runmode_output == NULL)) - return; - runmode_output->name = module->name; - runmode_output->tm_module = filedata_logger_module; - runmode_output->output_ctx = NULL; - InsertInRunModeOutputs(runmode_output); - SCLogDebug("__filedata_logger__ added"); - } - } else if (module->FileLogFunc) { - SCLogDebug("%s is a file logger", module->name); - OutputRegisterFileLogger(module->name, module->FileLogFunc, output_ctx); - - /* need one instance of the tx logger module */ - if (file_logger_module == NULL) { - file_logger_module = TmModuleGetByName("__file_logger__"); - if (file_logger_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for __file_logger__ failed"); - exit(EXIT_FAILURE); - } - - RunModeOutput *runmode_output = SCCalloc(1, sizeof(RunModeOutput)); - if (unlikely(runmode_output == NULL)) - return; - runmode_output->name = module->name; - runmode_output->tm_module = file_logger_module; - runmode_output->output_ctx = NULL; - InsertInRunModeOutputs(runmode_output); - SCLogDebug("__file_logger__ added"); - } - } else if (module->StreamingLogFunc) { - SCLogDebug("%s is a streaming logger", module->name); - OutputRegisterStreamingLogger(module->name, module->StreamingLogFunc, - output_ctx, module->stream_type); - - /* need one instance of the streaming logger module */ - if (streaming_logger_module == NULL) { - streaming_logger_module = TmModuleGetByName("__streaming_logger__"); - if (streaming_logger_module == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "TmModuleGetByName for __streaming_logger__ failed"); - exit(EXIT_FAILURE); - } - - RunModeOutput *runmode_output = SCCalloc(1, sizeof(RunModeOutput)); - if (unlikely(runmode_output == NULL)) - return; - runmode_output->name = module->name; - runmode_output->tm_module = streaming_logger_module; - runmode_output->output_ctx = NULL; - InsertInRunModeOutputs(runmode_output); - SCLogDebug("__streaming_logger__ added"); - } - } else { - SCLogDebug("%s is a regular logger", module->name); - - RunModeOutput *runmode_output = SCCalloc(1, sizeof(RunModeOutput)); - if (unlikely(runmode_output == NULL)) - return; - runmode_output->name = module->name; - runmode_output->tm_module = tm_module; - runmode_output->output_ctx = output_ctx; - InsertInRunModeOutputs(runmode_output); - } -} - -/** - * Initialize the output modules. - */ -void RunModeInitializeOutputs(void) -{ - ConfNode *outputs = ConfGetNode("outputs"); - if (outputs == NULL) { - /* No "outputs" section in the configuration. */ - return; - } - - ConfNode *output, *output_config; - const char *enabled; - char tls_log_enabled = 0; - char tls_store_present = 0; - - TAILQ_FOREACH(output, &outputs->head, next) { - - output_config = ConfNodeLookupChild(output, output->val); - if (output_config == NULL) { - /* Shouldn't happen. */ - FatalError(SC_ERR_INVALID_ARGUMENT, - "Failed to lookup configuration child node: %s", output->val); - } - - if (strcmp(output->val, "tls-store") == 0) { - tls_store_present = 1; - } - - enabled = ConfNodeLookupChildValue(output_config, "enabled"); - if (enabled == NULL || !ConfValIsTrue(enabled)) { - continue; - } - - if (strncmp(output->val, "unified-", sizeof("unified-") - 1) == 0) { - SCLogWarning(SC_ERR_NOT_SUPPORTED, - "Unified1 is no longer supported," - " use Unified2 instead " - "(see https://redmine.openinfosecfoundation.org/issues/353" - " for an explanation)"); - continue; - } else if (strcmp(output->val, "alert-prelude") == 0) { -#ifndef PRELUDE - SCLogWarning(SC_ERR_NOT_SUPPORTED, - "Prelude support not compiled in. Reconfigure/" - "recompile with --enable-prelude to add Prelude " - "support."); - continue; -#endif - } else if (strcmp(output->val, "eve-log") == 0) { -#ifndef HAVE_LIBJANSSON - SCLogWarning(SC_ERR_NOT_SUPPORTED, - "Eve-log support not compiled in. Reconfigure/" - "recompile with libjansson and its development " - "files installed to add eve-log support."); - continue; -#endif - } else if (strcmp(output->val, "lua") == 0) { -#ifndef HAVE_LUA - SCLogWarning(SC_ERR_NOT_SUPPORTED, - "lua support not compiled in. Reconfigure/" - "recompile with lua(jit) and its development " - "files installed to add lua support."); - continue; -#endif - } else if (strcmp(output->val, "tls-log") == 0) { - tls_log_enabled = 1; - } - - OutputModule *module = OutputGetModuleByConfName(output->val); - if (module == NULL) { - FatalErrorOnInit(SC_ERR_INVALID_ARGUMENT, - "No output module named %s", output->val); - continue; - } - - OutputCtx *output_ctx = NULL; - if (module->InitFunc != NULL) { - output_ctx = module->InitFunc(output_config); - if (output_ctx == NULL) { - FatalErrorOnInit(SC_ERR_INVALID_ARGUMENT, "output module setup failed"); - continue; - } - } else if (module->InitSubFunc != NULL) { - SCLogInfo("skipping submodule"); - continue; - } - - // TODO if module == parent, find it's children - if (strcmp(output->val, "eve-log") == 0) { - ConfNode *types = ConfNodeLookupChild(output_config, "types"); - SCLogDebug("types %p", types); - if (types != NULL) { - ConfNode *type = NULL; - TAILQ_FOREACH(type, &types->head, next) { - SCLogInfo("enabling 'eve-log' module '%s'", type->val); - - char subname[256]; - snprintf(subname, sizeof(subname), "%s.%s", output->val, type->val); - - OutputModule *sub_module = OutputGetModuleByConfName(subname); - if (sub_module == NULL) { - FatalErrorOnInit(SC_ERR_INVALID_ARGUMENT, - "No output module named %s", subname); - continue; - } - if (sub_module->parent_name == NULL || - strcmp(sub_module->parent_name,output->val) != 0) { - FatalError(SC_ERR_INVALID_ARGUMENT, - "bad parent for %s", subname); - } - if (sub_module->InitSubFunc == NULL) { - FatalError(SC_ERR_INVALID_ARGUMENT, - "bad sub-module for %s", subname); - } - ConfNode *sub_output_config = ConfNodeLookupChild(type, type->val); - // sub_output_config may be NULL if no config - - /* pass on parent output_ctx */ - OutputCtx *sub_output_ctx = - sub_module->InitSubFunc(sub_output_config, output_ctx); - if (sub_output_ctx == NULL) { - continue; - } - - AddOutputToFreeList(sub_module, sub_output_ctx); - SetupOutput(sub_module->name, sub_module, sub_output_ctx); - } - } - /* add 'eve-log' to free list as it's the owner of the - * main output ctx from which the sub-modules share the - * LogFileCtx */ - AddOutputToFreeList(module, output_ctx); - - } else if (strcmp(output->val, "lua") == 0) { - SCLogDebug("handle lua"); - - ConfNode *scripts = ConfNodeLookupChild(output_config, "scripts"); - BUG_ON(scripts == NULL); //TODO - - OutputModule *m; - TAILQ_FOREACH(m, &output_ctx->submodules, entries) { - SCLogDebug("m %p %s:%s", m, m->name, m->conf_name); - - ConfNode *script = NULL; - TAILQ_FOREACH(script, &scripts->head, next) { - SCLogDebug("script %s", script->val); - if (strcmp(script->val, m->conf_name) == 0) { - break; - } - } - BUG_ON(script == NULL); - - /* pass on parent output_ctx */ - OutputCtx *sub_output_ctx = - m->InitSubFunc(script, output_ctx); - if (sub_output_ctx == NULL) { - SCLogInfo("sub_output_ctx NULL, skipping"); - continue; - } - - SetupOutput(m->name, m, sub_output_ctx); - } - - } else { - AddOutputToFreeList(module, output_ctx); - SetupOutput(module->name, module, output_ctx); - } - } - - /* Backward compatibility code */ - if (!tls_store_present && tls_log_enabled) { - /* old YAML with no "tls-store" in outputs. "tls-log" value needs - * to be started using 'tls-log' config as own config */ - SCLogWarning(SC_ERR_CONF_YAML_ERROR, - "Please use 'tls-store' in YAML to configure TLS storage"); - - TAILQ_FOREACH(output, &outputs->head, next) { - output_config = ConfNodeLookupChild(output, output->val); - - if (strcmp(output->val, "tls-log") == 0) { - - OutputModule *module = OutputGetModuleByConfName("tls-store"); - if (module == NULL) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, - "No output module named %s, ignoring", "tls-store"); - continue; - } - - OutputCtx *output_ctx = NULL; - if (module->InitFunc != NULL) { - output_ctx = module->InitFunc(output_config); - if (output_ctx == NULL) { - continue; - } - } - - AddOutputToFreeList(module, output_ctx); - SetupOutput(module->name, module, output_ctx); - } - } - } - -} - -/** - * Setup the outputs for this run mode. - * - * \param tv The ThreadVars for the thread the outputs will be - * appended to. - */ -void SetupOutputs(ThreadVars *tv) -{ - RunModeOutput *output; - TAILQ_FOREACH(output, &RunModeOutputs, entries) { - tv->cap_flags |= output->tm_module->cap_flags; - TmSlotSetFuncAppend(tv, output->tm_module, output->output_ctx); - } -} - -float threading_detect_ratio = 1; - -/** - * Initialize multithreading settings. - */ -void RunModeInitialize(void) -{ - threading_set_cpu_affinity = FALSE; - if ((ConfGetBool("threading.set-cpu-affinity", &threading_set_cpu_affinity)) == 0) { - threading_set_cpu_affinity = FALSE; - } - /* try to get custom cpu mask value if needed */ - if (threading_set_cpu_affinity == TRUE) { - AffinitySetupLoadFromConfig(); - } - if ((ConfGetFloat("threading.detect-thread-ratio", &threading_detect_ratio)) != 1) { - if (ConfGetNode("threading.detect-thread-ratio") != NULL) - WarnInvalidConfEntry("threading.detect-thread-ratio", "%s", "1"); - threading_detect_ratio = 1; - } - - SCLogDebug("threading.detect-thread-ratio %f", threading_detect_ratio); -} diff --git a/framework/src/suricata/src/runmodes.h b/framework/src/suricata/src/runmodes.h deleted file mode 100644 index bd8d0326..00000000 --- a/framework/src/suricata/src/runmodes.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Victor Julien - */ - -#ifndef __RUNMODES_H__ -#define __RUNMODES_H__ - -/* Run mode */ -enum { - RUNMODE_UNKNOWN = 0, - RUNMODE_PCAP_DEV, - RUNMODE_PCAP_FILE, - RUNMODE_PFRING, - RUNMODE_NFQ, - RUNMODE_NFLOG, - RUNMODE_IPFW, - RUNMODE_ERF_FILE, - RUNMODE_DAG, - RUNMODE_AFP_DEV, - RUNMODE_NETMAP, - RUNMODE_TILERA_MPIPE, - RUNMODE_UNITTEST, - RUNMODE_NAPATECH, - RUNMODE_UNIX_SOCKET, - RUNMODE_USER_MAX, /* Last standard running mode */ - RUNMODE_LIST_KEYWORDS, - RUNMODE_LIST_APP_LAYERS, - RUNMODE_LIST_CUDA_CARDS, - RUNMODE_LIST_RUNMODES, - RUNMODE_PRINT_VERSION, - RUNMODE_PRINT_BUILDINFO, - RUNMODE_PRINT_USAGE, - RUNMODE_DUMP_CONFIG, - RUNMODE_CONF_TEST, - RUNMODE_LIST_UNITTEST, - RUNMODE_ENGINE_ANALYSIS, -#ifdef OS_WIN32 - RUNMODE_INSTALL_SERVICE, - RUNMODE_REMOVE_SERVICE, - RUNMODE_CHANGE_SERVICE_PARAMS, -#endif - RUNMODE_MAX, -}; - -char *RunmodeGetActive(void); -const char *RunModeGetMainMode(void); - -void RunModeListRunmodes(void); -void RunModeDispatch(int, const char *); -void RunModeRegisterRunModes(void); -void RunModeRegisterNewRunMode(int, const char *, const char *, - int (*RunModeFunc)(void)); -void RunModeInitialize(void); -void RunModeInitializeOutputs(void); -void SetupOutputs(ThreadVars *); -void RunModeShutDown(void); - -/* bool indicating if file logger is enabled */ -int RunModeOutputFileEnabled(void); -/* bool indicating if filedata logger is enabled */ -int RunModeOutputFiledataEnabled(void); - -#include "runmode-pcap.h" -#include "runmode-pcap-file.h" -#include "runmode-pfring.h" -#include "runmode-tile.h" -#include "runmode-nfq.h" -#include "runmode-ipfw.h" -#include "runmode-erf-file.h" -#include "runmode-erf-dag.h" -#include "runmode-napatech.h" -#include "runmode-af-packet.h" -#include "runmode-nflog.h" -#include "runmode-unix-socket.h" -#include "runmode-netmap.h" - -int threading_set_cpu_affinity; -extern float threading_detect_ratio; - -extern int debuglog_enabled; - -#endif /* __RUNMODES_H__ */ diff --git a/framework/src/suricata/src/source-af-packet.c b/framework/src/suricata/src/source-af-packet.c deleted file mode 100644 index 3f1f44e1..00000000 --- a/framework/src/suricata/src/source-af-packet.c +++ /dev/null @@ -1,1919 +0,0 @@ -/* Copyright (C) 2011-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \defgroup afppacket AF_PACKET running mode - * - * @{ - */ - -/** - * \file - * - * \author Eric Leblond - * - * AF_PACKET socket acquisition support - * - * \todo watch other interface event to detect suppression of the monitored - * interface - */ - -#include "suricata-common.h" -#include "config.h" -#include "suricata.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "tm-modules.h" -#include "tm-threads.h" -#include "tm-threads-common.h" -#include "conf.h" -#include "util-debug.h" -#include "util-device.h" -#include "util-error.h" -#include "util-privs.h" -#include "util-optimize.h" -#include "util-checksum.h" -#include "util-ioctl.h" -#include "util-host-info.h" -#include "tmqh-packetpool.h" -#include "source-af-packet.h" -#include "runmodes.h" - -#ifdef __SC_CUDA_SUPPORT__ - -#include "util-cuda.h" -#include "util-cuda-buffer.h" -#include "util-mpm-ac.h" -#include "util-cuda-handlers.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "util-cuda-vars.h" - -#endif /* __SC_CUDA_SUPPORT__ */ - -#ifdef HAVE_AF_PACKET - -#if HAVE_SYS_IOCTL_H -#include -#endif - -#if HAVE_LINUX_IF_ETHER_H -#include -#endif - -#if HAVE_LINUX_IF_PACKET_H -#include -#endif - -#if HAVE_LINUX_IF_ARP_H -#include -#endif - -#if HAVE_LINUX_FILTER_H -#include -#endif - -#if HAVE_SYS_MMAN_H -#include -#endif - -#endif /* HAVE_AF_PACKET */ - -extern int max_pending_packets; - -#ifndef HAVE_AF_PACKET - -TmEcode NoAFPSupportExit(ThreadVars *, void *, void **); - -void TmModuleReceiveAFPRegister (void) -{ - tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP"; - tmm_modules[TMM_RECEIVEAFP].ThreadInit = NoAFPSupportExit; - tmm_modules[TMM_RECEIVEAFP].Func = NULL; - tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = NULL; - tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEAFP].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEAFP].cap_flags = 0; - tmm_modules[TMM_RECEIVEAFP].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Registration Function for DecodeAFP. - * \todo Unit tests are needed for this module. - */ -void TmModuleDecodeAFPRegister (void) -{ - tmm_modules[TMM_DECODEAFP].name = "DecodeAFP"; - tmm_modules[TMM_DECODEAFP].ThreadInit = NoAFPSupportExit; - tmm_modules[TMM_DECODEAFP].Func = NULL; - tmm_modules[TMM_DECODEAFP].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEAFP].ThreadDeinit = NULL; - tmm_modules[TMM_DECODEAFP].RegisterTests = NULL; - tmm_modules[TMM_DECODEAFP].cap_flags = 0; - tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM; -} - -/** - * \brief this function prints an error message and exits. - */ -TmEcode NoAFPSupportExit(ThreadVars *tv, void *initdata, void **data) -{ - SCLogError(SC_ERR_NO_AF_PACKET,"Error creating thread %s: you do not have " - "support for AF_PACKET enabled, on Linux host please recompile " - "with --enable-af-packet", tv->name); - exit(EXIT_FAILURE); -} - -#else /* We have AF_PACKET support */ - -#define AFP_IFACE_NAME_LENGTH 48 - -#define AFP_STATE_DOWN 0 -#define AFP_STATE_UP 1 - -#define AFP_RECONNECT_TIMEOUT 500000 -#define AFP_DOWN_COUNTER_INTERVAL 40 - -#define POLL_TIMEOUT 100 - -#ifndef TP_STATUS_USER_BUSY -/* for new use latest bit available in tp_status */ -#define TP_STATUS_USER_BUSY (1 << 31) -#endif - -#ifndef TP_STATUS_VLAN_VALID -#define TP_STATUS_VLAN_VALID (1 << 4) -#endif - -/** protect pfring_set_bpf_filter, as it is not thread safe */ -static SCMutex afpacket_bpf_set_filter_lock = SCMUTEX_INITIALIZER; - -enum { - AFP_READ_OK, - AFP_READ_FAILURE, - AFP_FAILURE, - AFP_KERNEL_DROP, -}; - -enum { - AFP_FATAL_ERROR = 1, - AFP_RECOVERABLE_ERROR, -}; - -union thdr { - struct tpacket2_hdr *h2; - void *raw; -}; - -/** - * \brief Structure to hold thread specific variables. - */ -typedef struct AFPThreadVars_ -{ - /* thread specific socket */ - int socket; - /* handle state */ - unsigned char afp_state; - - /* data link type for the thread */ - int datalink; - int cooked; - - /* counters */ - uint64_t pkts; - uint64_t bytes; - uint64_t errs; - - ThreadVars *tv; - TmSlot *slot; - - uint8_t *data; /** Per function and thread data */ - int datalen; /** Length of per function and thread data */ - - int vlan_disabled; - - char iface[AFP_IFACE_NAME_LENGTH]; - LiveDevice *livedev; - int down_count; - - /* Filter */ - char *bpf_filter; - - /* socket buffer size */ - int buffer_size; - int promisc; - ChecksumValidationMode checksum_mode; - - /* IPS stuff */ - char out_iface[AFP_IFACE_NAME_LENGTH]; - AFPPeer *mpeer; - - int flags; - uint16_t capture_kernel_packets; - uint16_t capture_kernel_drops; - - int cluster_id; - int cluster_type; - - int threads; - int copy_mode; - - struct tpacket_req req; - unsigned int tp_hdrlen; - unsigned int ring_buflen; - char *ring_buf; - char *frame_buf; - unsigned int frame_offset; - int ring_size; - -} AFPThreadVars; - -TmEcode ReceiveAFP(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode ReceiveAFPThreadInit(ThreadVars *, void *, void **); -void ReceiveAFPThreadExitStats(ThreadVars *, void *); -TmEcode ReceiveAFPThreadDeinit(ThreadVars *, void *); -TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot); - -TmEcode DecodeAFPThreadInit(ThreadVars *, void *, void **); -TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data); -TmEcode DecodeAFP(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); - -TmEcode AFPSetBPFFilter(AFPThreadVars *ptv); -static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose); -static int AFPGetDevFlags(int fd, const char *ifname); -static int AFPDerefSocket(AFPPeer* peer); -static int AFPRefSocket(AFPPeer* peer); - -/** - * \brief Registration Function for RecieveAFP. - * \todo Unit tests are needed for this module. - */ -void TmModuleReceiveAFPRegister (void) -{ - tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP"; - tmm_modules[TMM_RECEIVEAFP].ThreadInit = ReceiveAFPThreadInit; - tmm_modules[TMM_RECEIVEAFP].Func = NULL; - tmm_modules[TMM_RECEIVEAFP].PktAcqLoop = ReceiveAFPLoop; - tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = ReceiveAFPThreadExitStats; - tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEAFP].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEAFP].cap_flags = SC_CAP_NET_RAW; - tmm_modules[TMM_RECEIVEAFP].flags = TM_FLAG_RECEIVE_TM; -} - - -/** - * \defgroup afppeers AFP peers list - * - * AF_PACKET has an IPS mode were interface are peered: packet from - * on interface are sent the peered interface and the other way. The ::AFPPeer - * list is maitaining the list of peers. Each ::AFPPeer is storing the needed - * information to be able to send packet on the interface. - * A element of the list must not be destroyed during the run of Suricata as it - * is used by ::Packet and other threads. - * - * @{ - */ - -typedef struct AFPPeersList_ { - TAILQ_HEAD(, AFPPeer_) peers; /**< Head of list of fragments. */ - int cnt; - int peered; - int turn; /**< Next value for initialisation order */ - SC_ATOMIC_DECLARE(int, reached); /**< Counter used to synchronize start */ -} AFPPeersList; - -/** - * \brief Update the peer. - * - * Update the AFPPeer of a thread ie set new state, socket number - * or iface index. - * - */ -void AFPPeerUpdate(AFPThreadVars *ptv) -{ - if (ptv->mpeer == NULL) { - return; - } - (void)SC_ATOMIC_SET(ptv->mpeer->if_idx, AFPGetIfnumByDev(ptv->socket, ptv->iface, 0)); - (void)SC_ATOMIC_SET(ptv->mpeer->socket, ptv->socket); - (void)SC_ATOMIC_SET(ptv->mpeer->state, ptv->afp_state); -} - -/** - * \brief Clean and free ressource used by an ::AFPPeer - */ -void AFPPeerClean(AFPPeer *peer) -{ - if (peer->flags & AFP_SOCK_PROTECT) - SCMutexDestroy(&peer->sock_protect); - SC_ATOMIC_DESTROY(peer->socket); - SC_ATOMIC_DESTROY(peer->if_idx); - SC_ATOMIC_DESTROY(peer->state); - SCFree(peer); -} - -AFPPeersList peerslist; - - -/** - * \brief Init the global list of ::AFPPeer - */ -TmEcode AFPPeersListInit() -{ - SCEnter(); - TAILQ_INIT(&peerslist.peers); - peerslist.peered = 0; - peerslist.cnt = 0; - peerslist.turn = 0; - SC_ATOMIC_INIT(peerslist.reached); - (void) SC_ATOMIC_SET(peerslist.reached, 0); - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Check that all ::AFPPeer got a peer - * - * \retval TM_ECODE_FAILED if some threads are not peered or TM_ECODE_OK else. - */ -TmEcode AFPPeersListCheck() -{ -#define AFP_PEERS_MAX_TRY 4 -#define AFP_PEERS_WAIT 20000 - int try = 0; - SCEnter(); - while (try < AFP_PEERS_MAX_TRY) { - if (peerslist.cnt != peerslist.peered) { - usleep(AFP_PEERS_WAIT); - } else { - SCReturnInt(TM_ECODE_OK); - } - try++; - } - SCLogError(SC_ERR_AFP_CREATE, "Threads number not equals"); - SCReturnInt(TM_ECODE_FAILED); -} - -/** - * \brief Declare a new AFP thread to AFP peers list. - */ -TmEcode AFPPeersListAdd(AFPThreadVars *ptv) -{ - SCEnter(); - AFPPeer *peer = SCMalloc(sizeof(AFPPeer)); - AFPPeer *pitem; - int mtu, out_mtu; - - if (unlikely(peer == NULL)) { - SCReturnInt(TM_ECODE_FAILED); - } - memset(peer, 0, sizeof(AFPPeer)); - SC_ATOMIC_INIT(peer->socket); - SC_ATOMIC_INIT(peer->sock_usage); - SC_ATOMIC_INIT(peer->if_idx); - SC_ATOMIC_INIT(peer->state); - peer->flags = ptv->flags; - peer->turn = peerslist.turn++; - - if (peer->flags & AFP_SOCK_PROTECT) { - SCMutexInit(&peer->sock_protect, NULL); - } - - (void)SC_ATOMIC_SET(peer->sock_usage, 0); - (void)SC_ATOMIC_SET(peer->state, AFP_STATE_DOWN); - strlcpy(peer->iface, ptv->iface, AFP_IFACE_NAME_LENGTH); - ptv->mpeer = peer; - /* add element to iface list */ - TAILQ_INSERT_TAIL(&peerslist.peers, peer, next); - - if (ptv->copy_mode != AFP_COPY_MODE_NONE) { - peerslist.cnt++; - - /* Iter to find a peer */ - TAILQ_FOREACH(pitem, &peerslist.peers, next) { - if (pitem->peer) - continue; - if (strcmp(pitem->iface, ptv->out_iface)) - continue; - peer->peer = pitem; - pitem->peer = peer; - mtu = GetIfaceMTU(ptv->iface); - out_mtu = GetIfaceMTU(ptv->out_iface); - if (mtu != out_mtu) { - SCLogError(SC_ERR_AFP_CREATE, - "MTU on %s (%d) and %s (%d) are not equal, " - "transmission of packets bigger than %d will fail.", - ptv->iface, mtu, - ptv->out_iface, out_mtu, - (out_mtu > mtu) ? mtu : out_mtu); - } - peerslist.peered += 2; - break; - } - } - - AFPPeerUpdate(ptv); - - SCReturnInt(TM_ECODE_OK); -} - -int AFPPeersListWaitTurn(AFPPeer *peer) -{ - /* If turn is zero, we already have started threads once */ - if (peerslist.turn == 0) - return 0; - - if (peer->turn == SC_ATOMIC_GET(peerslist.reached)) - return 0; - return 1; -} - -void AFPPeersListReachedInc() -{ - if (peerslist.turn == 0) - return; - - if (SC_ATOMIC_ADD(peerslist.reached, 1) == peerslist.turn) { - SCLogInfo("All AFP capture threads are running."); - (void)SC_ATOMIC_SET(peerslist.reached, 0); - /* Set turn to 0 to skip syncrhonization when ReceiveAFPLoop is - * restarted. - */ - peerslist.turn = 0; - } -} - -static int AFPPeersListStarted() -{ - return !peerslist.turn; -} - -/** - * \brief Clean the global peers list. - */ -void AFPPeersListClean() -{ - AFPPeer *pitem; - - while ((pitem = TAILQ_FIRST(&peerslist.peers))) { - TAILQ_REMOVE(&peerslist.peers, pitem, next); - AFPPeerClean(pitem); - } -} - -/** - * @} - */ - -/** - * \brief Registration Function for DecodeAFP. - * \todo Unit tests are needed for this module. - */ -void TmModuleDecodeAFPRegister (void) -{ - tmm_modules[TMM_DECODEAFP].name = "DecodeAFP"; - tmm_modules[TMM_DECODEAFP].ThreadInit = DecodeAFPThreadInit; - tmm_modules[TMM_DECODEAFP].Func = DecodeAFP; - tmm_modules[TMM_DECODEAFP].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEAFP].ThreadDeinit = DecodeAFPThreadDeinit; - tmm_modules[TMM_DECODEAFP].RegisterTests = NULL; - tmm_modules[TMM_DECODEAFP].cap_flags = 0; - tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM; -} - - -static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose); - -static inline void AFPDumpCounters(AFPThreadVars *ptv) -{ -#ifdef PACKET_STATISTICS - struct tpacket_stats kstats; - socklen_t len = sizeof (struct tpacket_stats); - if (getsockopt(ptv->socket, SOL_PACKET, PACKET_STATISTICS, - &kstats, &len) > -1) { - SCLogDebug("(%s) Kernel: Packets %" PRIu32 ", dropped %" PRIu32 "", - ptv->tv->name, - kstats.tp_packets, kstats.tp_drops); - StatsAddUI64(ptv->tv, ptv->capture_kernel_packets, kstats.tp_packets); - StatsAddUI64(ptv->tv, ptv->capture_kernel_drops, kstats.tp_drops); - (void) SC_ATOMIC_ADD(ptv->livedev->drop, (uint64_t) kstats.tp_drops); - (void) SC_ATOMIC_ADD(ptv->livedev->pkts, (uint64_t) kstats.tp_packets); - } -#endif -} - -/** - * \brief AF packet read function. - * - * This function fills - * From here the packets are picked up by the DecodeAFP thread. - * - * \param user pointer to AFPThreadVars - * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success - */ -int AFPRead(AFPThreadVars *ptv) -{ - Packet *p = NULL; - /* XXX should try to use read that get directly to packet */ - int offset = 0; - int caplen; - struct sockaddr_ll from; - struct iovec iov; - struct msghdr msg; - struct cmsghdr *cmsg; - union { - struct cmsghdr cmsg; - char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))]; - } cmsg_buf; - unsigned char aux_checksum = 0; - - msg.msg_name = &from; - msg.msg_namelen = sizeof(from); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = &cmsg_buf; - msg.msg_controllen = sizeof(cmsg_buf); - msg.msg_flags = 0; - - if (ptv->cooked) - offset = SLL_HEADER_LEN; - else - offset = 0; - iov.iov_len = ptv->datalen - offset; - iov.iov_base = ptv->data + offset; - - caplen = recvmsg(ptv->socket, &msg, MSG_TRUNC); - - if (caplen < 0) { - SCLogWarning(SC_ERR_AFP_READ, "recvmsg failed with error code %" PRId32, - errno); - SCReturnInt(AFP_READ_FAILURE); - } - - p = PacketGetFromQueueOrAlloc(); - if (p == NULL) { - SCReturnInt(AFP_FAILURE); - } - PKT_SET_SRC(p, PKT_SRC_WIRE); - - /* get timestamp of packet via ioctl */ - if (ioctl(ptv->socket, SIOCGSTAMP, &p->ts) == -1) { - SCLogWarning(SC_ERR_AFP_READ, "recvmsg failed with error code %" PRId32, - errno); - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(AFP_READ_FAILURE); - } - - ptv->pkts++; - ptv->bytes += caplen + offset; - p->livedev = ptv->livedev; - - /* add forged header */ - if (ptv->cooked) { - SllHdr * hdrp = (SllHdr *)ptv->data; - /* XXX this is minimalist, but this seems enough */ - hdrp->sll_protocol = from.sll_protocol; - } - - p->datalink = ptv->datalink; - SET_PKT_LEN(p, caplen + offset); - if (PacketCopyData(p, ptv->data, GET_PKT_LEN(p)) == -1) { - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(AFP_FAILURE); - } - SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)", - GET_PKT_LEN(p), p, GET_PKT_DATA(p)); - - /* We only check for checksum disable */ - if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) { - p->flags |= PKT_IGNORE_CHECKSUM; - } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) { - if (ptv->livedev->ignore_checksum) { - p->flags |= PKT_IGNORE_CHECKSUM; - } else if (ChecksumAutoModeCheck(ptv->pkts, - SC_ATOMIC_GET(ptv->livedev->pkts), - SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) { - ptv->livedev->ignore_checksum = 1; - p->flags |= PKT_IGNORE_CHECKSUM; - } - } else { - aux_checksum = 1; - } - - /* List is NULL if we don't have activated auxiliary data */ - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { - struct tpacket_auxdata *aux; - - if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) || - cmsg->cmsg_level != SOL_PACKET || - cmsg->cmsg_type != PACKET_AUXDATA) - continue; - - aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg); - - if (aux_checksum && (aux->tp_status & TP_STATUS_CSUMNOTREADY)) { - p->flags |= PKT_IGNORE_CHECKSUM; - } - break; - } - - if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(AFP_FAILURE); - } - SCReturnInt(AFP_READ_OK); -} - -TmEcode AFPWritePacket(Packet *p) -{ - struct sockaddr_ll socket_address; - int socket; - - if (p->afp_v.copy_mode == AFP_COPY_MODE_IPS) { - if (PACKET_TEST_ACTION(p, ACTION_DROP)) { - return TM_ECODE_OK; - } - } - - if (SC_ATOMIC_GET(p->afp_v.peer->state) == AFP_STATE_DOWN) - return TM_ECODE_OK; - - if (p->ethh == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, "Should have an Ethernet header"); - return TM_ECODE_FAILED; - } - /* Index of the network device */ - socket_address.sll_ifindex = SC_ATOMIC_GET(p->afp_v.peer->if_idx); - /* Address length*/ - socket_address.sll_halen = ETH_ALEN; - /* Destination MAC */ - memcpy(socket_address.sll_addr, p->ethh, 6); - - /* Send packet, locking the socket if necessary */ - if (p->afp_v.peer->flags & AFP_SOCK_PROTECT) - SCMutexLock(&p->afp_v.peer->sock_protect); - socket = SC_ATOMIC_GET(p->afp_v.peer->socket); - if (sendto(socket, GET_PKT_DATA(p), GET_PKT_LEN(p), 0, - (struct sockaddr*) &socket_address, - sizeof(struct sockaddr_ll)) < 0) { - SCLogWarning(SC_ERR_SOCKET, "Sending packet failed on socket %d: %s", - socket, - strerror(errno)); - if (p->afp_v.peer->flags & AFP_SOCK_PROTECT) - SCMutexUnlock(&p->afp_v.peer->sock_protect); - return TM_ECODE_FAILED; - } - if (p->afp_v.peer->flags & AFP_SOCK_PROTECT) - SCMutexUnlock(&p->afp_v.peer->sock_protect); - - return TM_ECODE_OK; -} - -void AFPReleaseDataFromRing(Packet *p) -{ - /* Need to be in copy mode and need to detect early release - where Ethernet header could not be set (and pseudo packet) */ - if ((p->afp_v.copy_mode != AFP_COPY_MODE_NONE) && !PKT_IS_PSEUDOPKT(p)) { - AFPWritePacket(p); - } - - if (AFPDerefSocket(p->afp_v.mpeer) == 0) - goto cleanup; - - if (p->afp_v.relptr) { - union thdr h; - h.raw = p->afp_v.relptr; - h.h2->tp_status = TP_STATUS_KERNEL; - } - -cleanup: - AFPV_CLEANUP(&p->afp_v); -} - -void AFPReleasePacket(Packet *p) -{ - AFPReleaseDataFromRing(p); - PacketFreeOrRelease(p); -} - -/** - * \brief AF packet read function for ring - * - * This function fills - * From here the packets are picked up by the DecodeAFP thread. - * - * \param user pointer to AFPThreadVars - * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success - */ -int AFPReadFromRing(AFPThreadVars *ptv) -{ - Packet *p = NULL; - union thdr h; - struct sockaddr_ll *from; - uint8_t emergency_flush = 0; - int read_pkts = 0; - int loop_start = -1; - - - /* Loop till we have packets available */ - while (1) { - if (unlikely(suricata_ctl_flags != 0)) { - break; - } - - /* Read packet from ring */ - h.raw = (((union thdr **)ptv->frame_buf)[ptv->frame_offset]); - if (h.raw == NULL) { - SCReturnInt(AFP_FAILURE); - } - - if ((! h.h2->tp_status) || (h.h2->tp_status & TP_STATUS_USER_BUSY)) { - if (read_pkts == 0) { - if (loop_start == -1) { - loop_start = ptv->frame_offset; - } else if (unlikely(loop_start == (int)ptv->frame_offset)) { - SCReturnInt(AFP_READ_OK); - } - if (++ptv->frame_offset >= ptv->req.tp_frame_nr) { - ptv->frame_offset = 0; - } - continue; - } - if ((emergency_flush) && (ptv->flags & AFP_EMERGENCY_MODE)) { - SCReturnInt(AFP_KERNEL_DROP); - } else { - SCReturnInt(AFP_READ_OK); - } - } - - read_pkts++; - loop_start = -1; - - /* Our packet is still used by suricata, we exit read loop to - * gain some time */ - if (h.h2->tp_status & TP_STATUS_USER_BUSY) { - SCReturnInt(AFP_READ_OK); - } - - if ((ptv->flags & AFP_EMERGENCY_MODE) && (emergency_flush == 1)) { - h.h2->tp_status = TP_STATUS_KERNEL; - goto next_frame; - } - - p = PacketGetFromQueueOrAlloc(); - if (p == NULL) { - SCReturnInt(AFP_FAILURE); - } - PKT_SET_SRC(p, PKT_SRC_WIRE); - - /* Suricata will treat packet so telling it is busy, this - * status will be reset to 0 (ie TP_STATUS_KERNEL) in the release - * function. */ - h.h2->tp_status |= TP_STATUS_USER_BUSY; - - from = (void *)h.raw + TPACKET_ALIGN(ptv->tp_hdrlen); - - ptv->pkts++; - ptv->bytes += h.h2->tp_len; - p->livedev = ptv->livedev; - - /* add forged header */ - if (ptv->cooked) { - SllHdr * hdrp = (SllHdr *)ptv->data; - /* XXX this is minimalist, but this seems enough */ - hdrp->sll_protocol = from->sll_protocol; - } - - p->datalink = ptv->datalink; - if (h.h2->tp_len > h.h2->tp_snaplen) { - SCLogDebug("Packet length (%d) > snaplen (%d), truncating", - h.h2->tp_len, h.h2->tp_snaplen); - } - - /* get vlan id from header */ - if ((!ptv->vlan_disabled) && - (h.h2->tp_status & TP_STATUS_VLAN_VALID || h.h2->tp_vlan_tci)) { - p->vlan_id[0] = h.h2->tp_vlan_tci; - p->vlan_idx = 1; - p->vlanh[0] = NULL; - } - - if (ptv->flags & AFP_ZERO_COPY) { - if (PacketSetData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) { - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(AFP_FAILURE); - } else { - p->afp_v.relptr = h.raw; - p->ReleasePacket = AFPReleasePacket; - p->afp_v.mpeer = ptv->mpeer; - AFPRefSocket(ptv->mpeer); - - p->afp_v.copy_mode = ptv->copy_mode; - if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) { - p->afp_v.peer = ptv->mpeer->peer; - } else { - p->afp_v.peer = NULL; - } - } - } else { - if (PacketCopyData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) { - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(AFP_FAILURE); - } - } - /* Timestamp */ - p->ts.tv_sec = h.h2->tp_sec; - p->ts.tv_usec = h.h2->tp_nsec/1000; - SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)", - GET_PKT_LEN(p), p, GET_PKT_DATA(p)); - - /* We only check for checksum disable */ - if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) { - p->flags |= PKT_IGNORE_CHECKSUM; - } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) { - if (ptv->livedev->ignore_checksum) { - p->flags |= PKT_IGNORE_CHECKSUM; - } else if (ChecksumAutoModeCheck(ptv->pkts, - SC_ATOMIC_GET(ptv->livedev->pkts), - SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) { - ptv->livedev->ignore_checksum = 1; - p->flags |= PKT_IGNORE_CHECKSUM; - } - } else { - if (h.h2->tp_status & TP_STATUS_CSUMNOTREADY) { - p->flags |= PKT_IGNORE_CHECKSUM; - } - } - if (h.h2->tp_status & TP_STATUS_LOSING) { - emergency_flush = 1; - AFPDumpCounters(ptv); - } - - /* release frame if not in zero copy mode */ - if (!(ptv->flags & AFP_ZERO_COPY)) { - h.h2->tp_status = TP_STATUS_KERNEL; - } - - if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { - h.h2->tp_status = TP_STATUS_KERNEL; - if (++ptv->frame_offset >= ptv->req.tp_frame_nr) { - ptv->frame_offset = 0; - } - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(AFP_FAILURE); - } - -next_frame: - if (++ptv->frame_offset >= ptv->req.tp_frame_nr) { - ptv->frame_offset = 0; - /* Get out of loop to be sure we will reach maintenance tasks */ - SCReturnInt(AFP_READ_OK); - } - } - - SCReturnInt(AFP_READ_OK); -} - -/** - * \brief Reference socket - * - * \retval O in case of failure, 1 in case of success - */ -static int AFPRefSocket(AFPPeer* peer) -{ - if (unlikely(peer == NULL)) - return 0; - - (void)SC_ATOMIC_ADD(peer->sock_usage, 1); - return 1; -} - - -/** - * \brief Dereference socket - * - * \retval 1 if socket is still alive, 0 if not - */ -static int AFPDerefSocket(AFPPeer* peer) -{ - if (peer == NULL) - return 1; - - if (SC_ATOMIC_SUB(peer->sock_usage, 1) == 0) { - if (SC_ATOMIC_GET(peer->state) == AFP_STATE_DOWN) { - SCLogInfo("Cleaning socket connected to '%s'", peer->iface); - close(SC_ATOMIC_GET(peer->socket)); - return 0; - } - } - return 1; -} - -void AFPSwitchState(AFPThreadVars *ptv, int state) -{ - ptv->afp_state = state; - ptv->down_count = 0; - - AFPPeerUpdate(ptv); - - /* Do cleaning if switching to down state */ - if (state == AFP_STATE_DOWN) { - if (ptv->frame_buf) { - /* only used in reading phase, we can free it */ - SCFree(ptv->frame_buf); - ptv->frame_buf = NULL; - } - if (ptv->socket != -1) { - /* we need to wait for all packets to return data */ - if (SC_ATOMIC_SUB(ptv->mpeer->sock_usage, 1) == 0) { - SCLogInfo("Cleaning socket connected to '%s'", ptv->iface); - close(ptv->socket); - ptv->socket = -1; - } - } - } - if (state == AFP_STATE_UP) { - (void)SC_ATOMIC_SET(ptv->mpeer->sock_usage, 1); - } -} - -static int AFPReadAndDiscard(AFPThreadVars *ptv, struct timeval *synctv) -{ - struct sockaddr_ll from; - struct iovec iov; - struct msghdr msg; - struct timeval ts; - union { - struct cmsghdr cmsg; - char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))]; - } cmsg_buf; - - - if (unlikely(suricata_ctl_flags != 0)) { - return 1; - } - - msg.msg_name = &from; - msg.msg_namelen = sizeof(from); - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = &cmsg_buf; - msg.msg_controllen = sizeof(cmsg_buf); - msg.msg_flags = 0; - - iov.iov_len = ptv->datalen; - iov.iov_base = ptv->data; - - recvmsg(ptv->socket, &msg, MSG_TRUNC); - - if (ioctl(ptv->socket, SIOCGSTAMP, &ts) == -1) { - /* FIXME */ - return -1; - } - - if ((ts.tv_sec > synctv->tv_sec) || - (ts.tv_sec >= synctv->tv_sec && - ts.tv_usec > synctv->tv_usec)) { - return 1; - } - return 0; -} - -static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv) -{ - union thdr h; - - if (unlikely(suricata_ctl_flags != 0)) { - return 1; - } - - /* Read packet from ring */ - h.raw = (((union thdr **)ptv->frame_buf)[ptv->frame_offset]); - if (h.raw == NULL) { - return -1; - } - - if (((time_t)h.h2->tp_sec > synctv->tv_sec) || - ((time_t)h.h2->tp_sec == synctv->tv_sec && - (suseconds_t) (h.h2->tp_nsec / 1000) > synctv->tv_usec)) { - return 1; - } - - h.h2->tp_status = TP_STATUS_KERNEL; - if (++ptv->frame_offset >= ptv->req.tp_frame_nr) { - ptv->frame_offset = 0; - } - - - return 0; -} - -/** \brief wait for all afpacket threads to fully init - * - * Discard packets before all threads are ready, as the cluster - * setup is not complete yet. - * - * if AFPPeersListStarted() returns true init is complete - * - * \retval r 1 = happy, otherwise unhappy - */ -static int AFPSynchronizeStart(AFPThreadVars *ptv) -{ - int r; - struct timeval synctv; - struct pollfd fds; - - fds.fd = ptv->socket; - fds.events = POLLIN; - - /* Set timeval to end of the world */ - synctv.tv_sec = 0xffffffff; - synctv.tv_usec = 0xffffffff; - - while (1) { - r = poll(&fds, 1, POLL_TIMEOUT); - if (r > 0 && - (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) { - SCLogWarning(SC_ERR_AFP_READ, "poll failed %02x", - fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL)); - return 0; - } else if (r > 0) { - if (AFPPeersListStarted() && synctv.tv_sec == (time_t) 0xffffffff) { - gettimeofday(&synctv, NULL); - } - if (ptv->flags & AFP_RING_MODE) { - r = AFPReadAndDiscardFromRing(ptv, &synctv); - } else { - r = AFPReadAndDiscard(ptv, &synctv); - } - SCLogDebug("Discarding on %s", ptv->tv->name); - switch (r) { - case 1: - SCLogInfo("Starting to read on %s", ptv->tv->name); - return 1; - case -1: - return r; - } - /* no packets */ - } else if (r == 0 && AFPPeersListStarted()) { - SCLogInfo("Starting to read on %s", ptv->tv->name); - return 1; - } else if (r < 0) { /* only exit on error */ - SCLogWarning(SC_ERR_AFP_READ, "poll failed with retval %d", r); - return 0; - } - } - return 1; -} - -/** - * \brief Try to reopen socket - * - * \retval 0 in case of success, negative if error occurs or a condition - * is not met. - */ -static int AFPTryReopen(AFPThreadVars *ptv) -{ - int afp_activate_r; - - ptv->down_count++; - - - /* Don't reconnect till we have packet that did not release data */ - if (SC_ATOMIC_GET(ptv->mpeer->sock_usage) != 0) { - return -1; - } - - afp_activate_r = AFPCreateSocket(ptv, ptv->iface, 0); - if (afp_activate_r != 0) { - if (ptv->down_count % AFP_DOWN_COUNTER_INTERVAL == 0) { - SCLogWarning(SC_ERR_AFP_CREATE, "Can not open iface '%s'", - ptv->iface); - } - return afp_activate_r; - } - - SCLogInfo("Interface '%s' is back", ptv->iface); - return 0; -} - -/** - * \brief Main AF_PACKET reading Loop function - */ -TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - AFPThreadVars *ptv = (AFPThreadVars *)data; - struct pollfd fds; - int r; - TmSlot *s = (TmSlot *)slot; - time_t last_dump = 0; - struct timeval current_time; - - ptv->slot = s->slot_next; - - if (ptv->afp_state == AFP_STATE_DOWN) { - /* Wait for our turn, threads before us must have opened the socket */ - while (AFPPeersListWaitTurn(ptv->mpeer)) { - usleep(1000); - if (suricata_ctl_flags != 0) { - break; - } - } - r = AFPCreateSocket(ptv, ptv->iface, 1); - if (r < 0) { - switch (-r) { - case AFP_FATAL_ERROR: - SCLogError(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket, fatal error"); - /* fatal is fatal, we want suri to exit */ - EngineKill(); - //tv->aof = THV_ENGINE_EXIT; - SCReturnInt(TM_ECODE_FAILED); - case AFP_RECOVERABLE_ERROR: - SCLogWarning(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket, retrying soon"); - } - } - AFPPeersListReachedInc(); - } - if (ptv->afp_state == AFP_STATE_UP) { - SCLogInfo("Thread %s using socket %d", tv->name, ptv->socket); - AFPSynchronizeStart(ptv); - } - - fds.fd = ptv->socket; - fds.events = POLLIN; - - while (1) { - /* Start by checking the state of our interface */ - if (unlikely(ptv->afp_state == AFP_STATE_DOWN)) { - int dbreak = 0; - - do { - usleep(AFP_RECONNECT_TIMEOUT); - if (suricata_ctl_flags != 0) { - dbreak = 1; - break; - } - r = AFPTryReopen(ptv); - fds.fd = ptv->socket; - } while (r < 0); - if (dbreak == 1) - break; - } - - /* make sure we have at least one packet in the packet pool, to prevent - * us from alloc'ing packets at line rate */ - PacketPoolWait(); - - r = poll(&fds, 1, POLL_TIMEOUT); - - if (suricata_ctl_flags != 0) { - break; - } - - if (r > 0 && - (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) { - if (fds.revents & (POLLHUP | POLLRDHUP)) { - AFPSwitchState(ptv, AFP_STATE_DOWN); - continue; - } else if (fds.revents & POLLERR) { - char c; - /* Do a recv to get errno */ - if (recv(ptv->socket, &c, sizeof c, MSG_PEEK) != -1) - continue; /* what, no error? */ - SCLogError(SC_ERR_AFP_READ, - "Error reading data from iface '%s': (%d" PRIu32 ") %s", - ptv->iface, errno, strerror(errno)); - AFPSwitchState(ptv, AFP_STATE_DOWN); - continue; - } else if (fds.revents & POLLNVAL) { - SCLogError(SC_ERR_AFP_READ, "Invalid polling request"); - AFPSwitchState(ptv, AFP_STATE_DOWN); - continue; - } - } else if (r > 0) { - if (ptv->flags & AFP_RING_MODE) { - r = AFPReadFromRing(ptv); - } else { - /* AFPRead will call TmThreadsSlotProcessPkt on read packets */ - r = AFPRead(ptv); - } - switch (r) { - case AFP_READ_FAILURE: - /* AFPRead in error: best to reset the socket */ - SCLogError(SC_ERR_AFP_READ, - "AFPRead error reading data from iface '%s': (%d" PRIu32 ") %s", - ptv->iface, errno, strerror(errno)); - AFPSwitchState(ptv, AFP_STATE_DOWN); - continue; - case AFP_FAILURE: - AFPSwitchState(ptv, AFP_STATE_DOWN); - SCReturnInt(TM_ECODE_FAILED); - break; - case AFP_READ_OK: - /* Trigger one dump of stats every second */ - TimeGet(¤t_time); - if (current_time.tv_sec != last_dump) { - AFPDumpCounters(ptv); - last_dump = current_time.tv_sec; - } - break; - case AFP_KERNEL_DROP: - AFPDumpCounters(ptv); - break; - } - } else if ((r < 0) && (errno != EINTR)) { - SCLogError(SC_ERR_AFP_READ, "Error reading data from iface '%s': (%d" PRIu32 ") %s", - ptv->iface, - errno, strerror(errno)); - AFPSwitchState(ptv, AFP_STATE_DOWN); - continue; - } - StatsSyncCountersIfSignalled(tv); - } - - AFPDumpCounters(ptv); - StatsSyncCountersIfSignalled(tv); - SCReturnInt(TM_ECODE_OK); -} - -static int AFPGetDevFlags(int fd, const char *ifname) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { - SCLogError(SC_ERR_AFP_CREATE, "Unable to find type for iface \"%s\": %s", - ifname, strerror(errno)); - return -1; - } - - return ifr.ifr_flags; -} - - -static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) { - if (verbose) - SCLogError(SC_ERR_AFP_CREATE, "Unable to find iface %s: %s", - ifname, strerror(errno)); - return -1; - } - - return ifr.ifr_ifindex; -} - -static int AFPGetDevLinktype(int fd, const char *ifname) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { - SCLogError(SC_ERR_AFP_CREATE, "Unable to find type for iface \"%s\": %s", - ifname, strerror(errno)); - return -1; - } - - switch (ifr.ifr_hwaddr.sa_family) { - case ARPHRD_LOOPBACK: - return LINKTYPE_ETHERNET; - case ARPHRD_PPP: - return LINKTYPE_RAW; - default: - return ifr.ifr_hwaddr.sa_family; - } -} - -static int AFPComputeRingParams(AFPThreadVars *ptv, int order) -{ - /* Compute structure: - Target is to store all pending packets - with a size equal to MTU + auxdata - And we keep a decent number of block - - To do so: - Compute frame_size (aligned to be able to fit in block - Check which block size we need. Blocksize is a 2^n * pagesize - We then need to get order, big enough to have - frame_size < block size - Find number of frame per block (divide) - Fill in packet_req - - Compute frame size: - described in packet_mmap.txt - dependant on snaplen (need to use a variable ?) -snaplen: MTU ? -tp_hdrlen determine_version in daq_afpacket -in V1: sizeof(struct tpacket_hdr); -in V2: val in getsockopt(instance->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len) -frame size: TPACKET_ALIGN(snaplen + TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN); - - */ - int tp_hdrlen = sizeof(struct tpacket_hdr); - int snaplen = default_packet_size; - - if (snaplen == 0) { - snaplen = GetIfaceMaxPacketSize(ptv->iface); - if (snaplen <= 0) { - SCLogWarning(SC_ERR_INVALID_VALUE, - "Unable to get MTU, setting snaplen to sane default of 1514"); - snaplen = 1514; - } - } - - ptv->req.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN); - ptv->req.tp_block_size = getpagesize() << order; - int frames_per_block = ptv->req.tp_block_size / ptv->req.tp_frame_size; - if (frames_per_block == 0) { - SCLogInfo("frame size to big"); - return -1; - } - ptv->req.tp_frame_nr = ptv->ring_size; - ptv->req.tp_block_nr = ptv->req.tp_frame_nr / frames_per_block + 1; - /* exact division */ - ptv->req.tp_frame_nr = ptv->req.tp_block_nr * frames_per_block; - SCLogInfo("AF_PACKET RX Ring params: block_size=%d block_nr=%d frame_size=%d frame_nr=%d", - ptv->req.tp_block_size, ptv->req.tp_block_nr, - ptv->req.tp_frame_size, ptv->req.tp_frame_nr); - return 1; -} - -static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose) -{ - int r; - int ret = AFP_FATAL_ERROR; - struct packet_mreq sock_params; - struct sockaddr_ll bind_address; - int order; - unsigned int i; - int if_idx; - - /* open socket */ - ptv->socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (ptv->socket == -1) { - SCLogError(SC_ERR_AFP_CREATE, "Couldn't create a AF_PACKET socket, error %s", strerror(errno)); - goto error; - } - if_idx = AFPGetIfnumByDev(ptv->socket, devname, verbose); - /* bind socket */ - memset(&bind_address, 0, sizeof(bind_address)); - bind_address.sll_family = AF_PACKET; - bind_address.sll_protocol = htons(ETH_P_ALL); - bind_address.sll_ifindex = if_idx; - if (bind_address.sll_ifindex == -1) { - if (verbose) - SCLogError(SC_ERR_AFP_CREATE, "Couldn't find iface %s", devname); - ret = AFP_RECOVERABLE_ERROR; - goto socket_err; - } - - if (ptv->promisc != 0) { - /* Force promiscuous mode */ - memset(&sock_params, 0, sizeof(sock_params)); - sock_params.mr_type = PACKET_MR_PROMISC; - sock_params.mr_ifindex = bind_address.sll_ifindex; - r = setsockopt(ptv->socket, SOL_PACKET, PACKET_ADD_MEMBERSHIP,(void *)&sock_params, sizeof(sock_params)); - if (r < 0) { - SCLogError(SC_ERR_AFP_CREATE, - "Couldn't switch iface %s to promiscuous, error %s", - devname, strerror(errno)); - goto frame_err; - } - } - - if (ptv->checksum_mode == CHECKSUM_VALIDATION_KERNEL) { - int val = 1; - if (setsockopt(ptv->socket, SOL_PACKET, PACKET_AUXDATA, &val, - sizeof(val)) == -1 && errno != ENOPROTOOPT) { - SCLogWarning(SC_ERR_NO_AF_PACKET, - "'kernel' checksum mode not supported, failling back to full mode."); - ptv->checksum_mode = CHECKSUM_VALIDATION_ENABLE; - } - } - - /* set socket recv buffer size */ - if (ptv->buffer_size != 0) { - /* - * Set the socket buffer size to the specified value. - */ - SCLogInfo("Setting AF_PACKET socket buffer to %d", ptv->buffer_size); - if (setsockopt(ptv->socket, SOL_SOCKET, SO_RCVBUF, - &ptv->buffer_size, - sizeof(ptv->buffer_size)) == -1) { - SCLogError(SC_ERR_AFP_CREATE, - "Couldn't set buffer size to %d on iface %s, error %s", - ptv->buffer_size, devname, strerror(errno)); - goto frame_err; - } - } - - r = bind(ptv->socket, (struct sockaddr *)&bind_address, sizeof(bind_address)); - if (r < 0) { - if (verbose) { - if (errno == ENETDOWN) { - SCLogError(SC_ERR_AFP_CREATE, - "Couldn't bind AF_PACKET socket, iface %s is down", - devname); - } else { - SCLogError(SC_ERR_AFP_CREATE, - "Couldn't bind AF_PACKET socket to iface %s, error %s", - devname, strerror(errno)); - } - } - ret = AFP_RECOVERABLE_ERROR; - goto frame_err; - } - -#ifdef HAVE_PACKET_FANOUT - /* add binded socket to fanout group */ - if (ptv->threads > 1) { - uint32_t option = 0; - uint16_t mode = ptv->cluster_type; - uint16_t id = ptv->cluster_id; - option = (mode << 16) | (id & 0xffff); - r = setsockopt(ptv->socket, SOL_PACKET, PACKET_FANOUT,(void *)&option, sizeof(option)); - if (r < 0) { - SCLogError(SC_ERR_AFP_CREATE, - "Coudn't set fanout mode, error %s", - strerror(errno)); - goto frame_err; - } - } -#endif - - int if_flags = AFPGetDevFlags(ptv->socket, ptv->iface); - if (if_flags == -1) { - if (verbose) { - SCLogError(SC_ERR_AFP_READ, - "Can not acces to interface '%s'", - ptv->iface); - } - ret = AFP_RECOVERABLE_ERROR; - goto frame_err; - } - if ((if_flags & IFF_UP) == 0) { - if (verbose) { - SCLogError(SC_ERR_AFP_READ, - "Interface '%s' is down", - ptv->iface); - } - ret = AFP_RECOVERABLE_ERROR; - goto frame_err; - } - - if (ptv->flags & AFP_RING_MODE) { - int val = TPACKET_V2; - unsigned int len = sizeof(val); - if (getsockopt(ptv->socket, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) { - if (errno == ENOPROTOOPT) { - SCLogError(SC_ERR_AFP_CREATE, - "Too old kernel giving up (need 2.6.27 at least)"); - } - SCLogError(SC_ERR_AFP_CREATE, "Error when retrieving packet header len"); - goto socket_err; - } - ptv->tp_hdrlen = val; - - val = TPACKET_V2; - if (setsockopt(ptv->socket, SOL_PACKET, PACKET_VERSION, &val, - sizeof(val)) < 0) { - SCLogError(SC_ERR_AFP_CREATE, - "Can't activate TPACKET_V2 on packet socket: %s", - strerror(errno)); - goto socket_err; - } - - /* Allocate RX ring */ -#define DEFAULT_ORDER 3 - for (order = DEFAULT_ORDER; order >= 0; order--) { - if (AFPComputeRingParams(ptv, order) != 1) { - SCLogInfo("Ring parameter are incorrect. Please correct the devel"); - } - - r = setsockopt(ptv->socket, SOL_PACKET, PACKET_RX_RING, (void *) &ptv->req, sizeof(ptv->req)); - if (r < 0) { - if (errno == ENOMEM) { - SCLogInfo("Memory issue with ring parameters. Retrying."); - continue; - } - SCLogError(SC_ERR_MEM_ALLOC, - "Unable to allocate RX Ring for iface %s: (%d) %s", - devname, - errno, - strerror(errno)); - goto socket_err; - } else { - break; - } - } - - if (order < 0) { - SCLogError(SC_ERR_MEM_ALLOC, - "Unable to allocate RX Ring for iface %s (order 0 failed)", - devname); - goto socket_err; - } - - /* Allocate the Ring */ - ptv->ring_buflen = ptv->req.tp_block_nr * ptv->req.tp_block_size; - ptv->ring_buf = mmap(0, ptv->ring_buflen, PROT_READ|PROT_WRITE, - MAP_SHARED, ptv->socket, 0); - if (ptv->ring_buf == MAP_FAILED) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to mmap"); - goto socket_err; - } - /* allocate a ring for each frame header pointer*/ - ptv->frame_buf = SCMalloc(ptv->req.tp_frame_nr * sizeof (union thdr *)); - if (ptv->frame_buf == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate frame buf"); - goto mmap_err; - } - memset(ptv->frame_buf, 0, ptv->req.tp_frame_nr * sizeof (union thdr *)); - /* fill the header ring with proper frame ptr*/ - ptv->frame_offset = 0; - for (i = 0; i < ptv->req.tp_block_nr; ++i) { - void *base = &ptv->ring_buf[i * ptv->req.tp_block_size]; - unsigned int j; - for (j = 0; j < ptv->req.tp_block_size / ptv->req.tp_frame_size; ++j, ++ptv->frame_offset) { - (((union thdr **)ptv->frame_buf)[ptv->frame_offset]) = base; - base += ptv->req.tp_frame_size; - } - } - ptv->frame_offset = 0; - } - - SCLogInfo("Using interface '%s' via socket %d", (char *)devname, ptv->socket); - - - ptv->datalink = AFPGetDevLinktype(ptv->socket, ptv->iface); - switch (ptv->datalink) { - case ARPHRD_PPP: - case ARPHRD_ATM: - ptv->cooked = 1; - break; - } - - TmEcode rc; - rc = AFPSetBPFFilter(ptv); - if (rc == TM_ECODE_FAILED) { - SCLogError(SC_ERR_AFP_CREATE, "Set AF_PACKET bpf filter \"%s\" failed.", ptv->bpf_filter); - goto frame_err; - } - - /* Init is ok */ - AFPSwitchState(ptv, AFP_STATE_UP); - return 0; - -frame_err: - if (ptv->frame_buf) - SCFree(ptv->frame_buf); -mmap_err: - /* Packet mmap does the cleaning when socket is closed */ -socket_err: - close(ptv->socket); - ptv->socket = -1; -error: - return -ret; -} - -TmEcode AFPSetBPFFilter(AFPThreadVars *ptv) -{ - struct bpf_program filter; - struct sock_fprog fcode; - int rc; - - if (!ptv->bpf_filter) - return TM_ECODE_OK; - - SCMutexLock(&afpacket_bpf_set_filter_lock); - - SCLogInfo("Using BPF '%s' on iface '%s'", - ptv->bpf_filter, - ptv->iface); - if (pcap_compile_nopcap(default_packet_size, /* snaplen_arg */ - ptv->datalink, /* linktype_arg */ - &filter, /* program */ - ptv->bpf_filter, /* const char *buf */ - 0, /* optimize */ - 0 /* mask */ - ) == -1) { - SCLogError(SC_ERR_AFP_CREATE, "Filter compilation failed."); - SCMutexUnlock(&afpacket_bpf_set_filter_lock); - return TM_ECODE_FAILED; - } - SCMutexUnlock(&afpacket_bpf_set_filter_lock); - - if (filter.bf_insns == NULL) { - SCLogError(SC_ERR_AFP_CREATE, "Filter badly setup."); - return TM_ECODE_FAILED; - } - - fcode.len = filter.bf_len; - fcode.filter = (struct sock_filter*)filter.bf_insns; - - rc = setsockopt(ptv->socket, SOL_SOCKET, SO_ATTACH_FILTER, &fcode, sizeof(fcode)); - - if(rc == -1) { - SCLogError(SC_ERR_AFP_CREATE, "Failed to attach filter: %s", strerror(errno)); - return TM_ECODE_FAILED; - } - - return TM_ECODE_OK; -} - - -/** - * \brief Init function for ReceiveAFP. - * - * \param tv pointer to ThreadVars - * \param initdata pointer to the interface passed from the user - * \param data pointer gets populated with AFPThreadVars - * - * \todo Create a general AFP setup function. - */ -TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - AFPIfaceConfig *afpconfig = initdata; - - if (initdata == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - AFPThreadVars *ptv = SCMalloc(sizeof(AFPThreadVars)); - if (unlikely(ptv == NULL)) { - afpconfig->DerefFunc(afpconfig); - SCReturnInt(TM_ECODE_FAILED); - } - memset(ptv, 0, sizeof(AFPThreadVars)); - - ptv->tv = tv; - ptv->cooked = 0; - - strlcpy(ptv->iface, afpconfig->iface, AFP_IFACE_NAME_LENGTH); - ptv->iface[AFP_IFACE_NAME_LENGTH - 1]= '\0'; - - ptv->livedev = LiveGetDevice(ptv->iface); - if (ptv->livedev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); - SCFree(ptv); - SCReturnInt(TM_ECODE_FAILED); - } - - ptv->buffer_size = afpconfig->buffer_size; - ptv->ring_size = afpconfig->ring_size; - - ptv->promisc = afpconfig->promisc; - ptv->checksum_mode = afpconfig->checksum_mode; - ptv->bpf_filter = NULL; - - ptv->threads = 1; -#ifdef HAVE_PACKET_FANOUT - ptv->cluster_type = PACKET_FANOUT_LB; - ptv->cluster_id = 1; - /* We only set cluster info if the number of reader threads is greater than 1 */ - if (afpconfig->threads > 1) { - ptv->cluster_id = afpconfig->cluster_id; - ptv->cluster_type = afpconfig->cluster_type; - ptv->threads = afpconfig->threads; - } -#endif - ptv->flags = afpconfig->flags; - - if (afpconfig->bpf_filter) { - ptv->bpf_filter = afpconfig->bpf_filter; - } - -#ifdef PACKET_STATISTICS - ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", - ptv->tv); - ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops", - ptv->tv); -#endif - - char *active_runmode = RunmodeGetActive(); - - if (active_runmode && !strcmp("workers", active_runmode)) { - ptv->flags |= AFP_ZERO_COPY; - SCLogInfo("Enabling zero copy mode"); - } else { - /* If we are using copy mode we need a lock */ - ptv->flags |= AFP_SOCK_PROTECT; - } - - /* If we are in RING mode, then we can use ZERO copy - * by using the data release mechanism */ - if (ptv->flags & AFP_RING_MODE) { - ptv->flags |= AFP_ZERO_COPY; - SCLogInfo("Enabling zero copy mode by using data release call"); - } - - ptv->copy_mode = afpconfig->copy_mode; - if (ptv->copy_mode != AFP_COPY_MODE_NONE) { - strlcpy(ptv->out_iface, afpconfig->out_iface, AFP_IFACE_NAME_LENGTH); - ptv->out_iface[AFP_IFACE_NAME_LENGTH - 1]= '\0'; - /* Warn about BPF filter consequence */ - if (ptv->bpf_filter) { - SCLogWarning(SC_WARN_UNCOMMON, "Enabling a BPF filter in IPS mode result" - " in dropping all non matching packets."); - } - } - - - if (AFPPeersListAdd(ptv) == TM_ECODE_FAILED) { - SCFree(ptv); - afpconfig->DerefFunc(afpconfig); - SCReturnInt(TM_ECODE_FAILED); - } - -#define T_DATA_SIZE 70000 - ptv->data = SCMalloc(T_DATA_SIZE); - if (ptv->data == NULL) { - afpconfig->DerefFunc(afpconfig); - SCFree(ptv); - SCReturnInt(TM_ECODE_FAILED); - } - ptv->datalen = T_DATA_SIZE; -#undef T_DATA_SIZE - - *data = (void *)ptv; - - afpconfig->DerefFunc(afpconfig); - - /* A bit strange to have this here but we only have vlan information - * during reading so we need to know if we want to keep vlan during - * the capture phase */ - int vlanbool = 0; - if ((ConfGetBool("vlan.use-for-tracking", &vlanbool)) == 1 && vlanbool == 0) { - ptv->vlan_disabled = 1; - } - - /* If kernel is older than 3.0, VLAN is not stripped so we don't - * get the info from packet extended header but we will use a standard - * parsing of packet data (See Linux commit bcc6d47903612c3861201cc3a866fb604f26b8b2) */ - if (! SCKernelVersionIsAtLeast(3, 0)) { - ptv->vlan_disabled = 1; - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function prints stats to the screen at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into AFPThreadVars for ptv - */ -void ReceiveAFPThreadExitStats(ThreadVars *tv, void *data) -{ - SCEnter(); - AFPThreadVars *ptv = (AFPThreadVars *)data; - -#ifdef PACKET_STATISTICS - AFPDumpCounters(ptv); - SCLogInfo("(%s) Kernel: Packets %" PRIu64 ", dropped %" PRIu64 "", - tv->name, - StatsGetLocalCounterValue(tv, ptv->capture_kernel_packets), - StatsGetLocalCounterValue(tv, ptv->capture_kernel_drops)); -#endif - - SCLogInfo("(%s) Packets %" PRIu64 ", bytes %" PRIu64 "", tv->name, ptv->pkts, ptv->bytes); -} - -/** - * \brief DeInit function closes af packet socket at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into AFPThreadVars for ptv - */ -TmEcode ReceiveAFPThreadDeinit(ThreadVars *tv, void *data) -{ - AFPThreadVars *ptv = (AFPThreadVars *)data; - - AFPSwitchState(ptv, AFP_STATE_DOWN); - - if (ptv->data != NULL) { - SCFree(ptv->data); - ptv->data = NULL; - } - ptv->datalen = 0; - - ptv->bpf_filter = NULL; - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function passes off to link type decoders. - * - * DecodeAFP reads packets from the PacketQueue and passes - * them off to the proper link type decoder. - * - * \param t pointer to ThreadVars - * \param p pointer to the current packet - * \param data pointer that gets cast into AFPThreadVars for ptv - * \param pq pointer to the current PacketQueue - */ -TmEcode DecodeAFP(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - SCEnter(); - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - /* If suri has set vlan during reading, we increase vlan counter */ - if (p->vlan_idx) { - StatsIncr(tv, dtv->counter_vlan); - } - - /* call the decoder */ - switch(p->datalink) { - case LINKTYPE_LINUX_SLL: - DecodeSll(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - case LINKTYPE_ETHERNET: - DecodeEthernet(tv, dtv, p,GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - case LINKTYPE_PPP: - DecodePPP(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - case LINKTYPE_RAW: - DecodeRaw(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - default: - SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "Error: datalink type %" PRId32 " not yet supported in module DecodeAFP", p->datalink); - break; - } - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodeAFPThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - DecodeThreadVars *dtv = NULL; - - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - -#ifdef __SC_CUDA_SUPPORT__ - if (CudaThreadVarsInit(&dtv->cuda_vars) < 0) - SCReturnInt(TM_ECODE_FAILED); -#endif - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -#endif /* HAVE_AF_PACKET */ -/* eof */ -/** - * @} - */ diff --git a/framework/src/suricata/src/source-af-packet.h b/framework/src/suricata/src/source-af-packet.h deleted file mode 100644 index 61f4e69e..00000000 --- a/framework/src/suricata/src/source-af-packet.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Copyright (C) 2011,2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#ifndef __SOURCE_AFP_H__ -#define __SOURCE_AFP_H__ - -#ifndef HAVE_PACKET_FANOUT /* not defined if linux/if_packet.h trying to force */ -#define HAVE_PACKET_FANOUT 1 - -#define PACKET_FANOUT 18 - -#define PACKET_FANOUT_HASH 0 -#define PACKET_FANOUT_LB 1 -#define PACKET_FANOUT_CPU 2 -#define PACKET_FANOUT_ROLLOVER 3 -#define PACKET_FANOUT_RND 4 -#define PACKET_FANOUT_QM 5 - -#define PACKET_FANOUT_FLAG_ROLLOVER 0x1000 -#define PACKET_FANOUT_FLAG_DEFRAG 0x8000 -#else /* HAVE_PACKET_FANOUT */ -#include -#endif /* HAVE_PACKET_FANOUT */ -#include "queue.h" - -/* value for flags */ -#define AFP_RING_MODE (1<<0) -#define AFP_ZERO_COPY (1<<1) -#define AFP_SOCK_PROTECT (1<<2) -#define AFP_EMERGENCY_MODE (1<<3) - -#define AFP_COPY_MODE_NONE 0 -#define AFP_COPY_MODE_TAP 1 -#define AFP_COPY_MODE_IPS 2 - -#define AFP_FILE_MAX_PKTS 256 -#define AFP_IFACE_NAME_LENGTH 48 - -typedef struct AFPIfaceConfig_ -{ - char iface[AFP_IFACE_NAME_LENGTH]; - /* number of threads */ - int threads; - /* socket buffer size */ - int buffer_size; - /* ring size in number of packets */ - int ring_size; - /* cluster param */ - int cluster_id; - int cluster_type; - /* promisc mode */ - int promisc; - /* misc use flags including ring mode */ - int flags; - int copy_mode; - ChecksumValidationMode checksum_mode; - char *bpf_filter; - char *out_iface; - SC_ATOMIC_DECLARE(unsigned int, ref); - void (*DerefFunc)(void *); -} AFPIfaceConfig; - -/** - * \ingroup afppeers - * @{ - */ - -typedef struct AFPPeer_ { - char iface[AFP_IFACE_NAME_LENGTH]; - SC_ATOMIC_DECLARE(int, socket); - SC_ATOMIC_DECLARE(int, sock_usage); - SC_ATOMIC_DECLARE(int, if_idx); - SC_ATOMIC_DECLARE(uint8_t, state); - SCMutex sock_protect; - int flags; - int turn; /**< Field used to store initialisation order. */ - struct AFPPeer_ *peer; - TAILQ_ENTRY(AFPPeer_) next; -} AFPPeer; - -/** - * \brief per packet AF_PACKET vars - * - * This structure is used y the release data system and is cleaned - * up by the AFPV_CLEANUP macro below. - */ -typedef struct AFPPacketVars_ -{ - void *relptr; - int copy_mode; - AFPPeer *peer; /**< Sending peer for IPS/TAP mode */ - /** Pointer to ::AFPPeer used for capture. Field is used to be able - * to do reference counting. - */ - AFPPeer *mpeer; -} AFPPacketVars; - -#define AFPV_CLEANUP(afpv) do { \ - (afpv)->relptr = NULL; \ - (afpv)->copy_mode = 0; \ - (afpv)->peer = NULL; \ - (afpv)->mpeer = NULL; \ -} while(0) - -/** - * @} - */ - -void TmModuleReceiveAFPRegister (void); -void TmModuleDecodeAFPRegister (void); - -TmEcode AFPPeersListInit(); -TmEcode AFPPeersListCheck(); -void AFPPeersListClean(); - - -#endif /* __SOURCE_AFP_H__ */ diff --git a/framework/src/suricata/src/source-erf-dag.c b/framework/src/suricata/src/source-erf-dag.c deleted file mode 100644 index f6640712..00000000 --- a/framework/src/suricata/src/source-erf-dag.c +++ /dev/null @@ -1,670 +0,0 @@ -/* Copyright (C) 2010-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited. - * \author Jason MacLulich - * - * Support for reading ERF records from a DAG card. - * - * Only ethernet supported at this time. - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "tm-threads.h" - -#include "util-privs.h" -#include "util-device.h" -#include "tmqh-packetpool.h" - -#ifndef HAVE_DAG - -TmEcode NoErfDagSupportExit(ThreadVars *, void *, void **); - -void -TmModuleReceiveErfDagRegister(void) -{ - tmm_modules[TMM_RECEIVEERFDAG].name = "ReceiveErfDag"; - tmm_modules[TMM_RECEIVEERFDAG].ThreadInit = NoErfDagSupportExit; - tmm_modules[TMM_RECEIVEERFDAG].Func = NULL; - tmm_modules[TMM_RECEIVEERFDAG].ThreadExitPrintStats = NULL; - tmm_modules[TMM_RECEIVEERFDAG].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEERFDAG].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEERFDAG].cap_flags = SC_CAP_NET_ADMIN; - tmm_modules[TMM_RECEIVEERFDAG].flags = TM_FLAG_RECEIVE_TM; -} - -void -TmModuleDecodeErfDagRegister(void) -{ - tmm_modules[TMM_DECODEERFDAG].name = "DecodeErfDag"; - tmm_modules[TMM_DECODEERFDAG].ThreadInit = NoErfDagSupportExit; - tmm_modules[TMM_DECODEERFDAG].Func = NULL; - tmm_modules[TMM_DECODEERFDAG].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEERFDAG].ThreadDeinit = NULL; - tmm_modules[TMM_DECODEERFDAG].RegisterTests = NULL; - tmm_modules[TMM_DECODEERFDAG].cap_flags = 0; - tmm_modules[TMM_DECODEERFDAG].flags = TM_FLAG_DECODE_TM; -} - -TmEcode -NoErfDagSupportExit(ThreadVars *tv, void *initdata, void **data) -{ - SCLogError(SC_ERR_DAG_NOSUPPORT, - "Error creating thread %s: you do not have support for DAG cards " - "enabled please recompile with --enable-dag", tv->name); - exit(EXIT_FAILURE); -} - -#else /* Implied we do have DAG support */ - -#include "source-erf-dag.h" -#include - -/* Minimum amount of data to read from the DAG at a time. */ -#define MINDATA 32768 - -/* Maximum time (us) to wait for MINDATA to be read. */ -#define MAXWAIT 20000 - -/* Poll interval in microseconds. */ -#define POLL_INTERVAL 1000; - -/* Number of bytes per loop to process before fetching more data. */ -#define BYTES_PER_LOOP (4 * 1024 * 1024) /* 4 MB */ - -extern int max_pending_packets; - -typedef struct ErfDagThreadVars_ { - ThreadVars *tv; - TmSlot *slot; - - int dagfd; - int dagstream; - char dagname[DAGNAME_BUFSIZE]; - - struct timeval maxwait, poll; /* Could possibly be made static */ - - LiveDevice *livedev; - - uint64_t bytes; - uint16_t packets; - uint16_t drops; - - /* Current location in the DAG stream input buffer. - */ - uint8_t *top; - uint8_t *btm; - -} ErfDagThreadVars; - -static inline TmEcode ProcessErfDagRecords(ErfDagThreadVars *ewtn, uint8_t *top, - uint32_t *pkts_read); -static inline TmEcode ProcessErfDagRecord(ErfDagThreadVars *ewtn, char *prec); -TmEcode ReceiveErfDagLoop(ThreadVars *, void *data, void *slot); -TmEcode ReceiveErfDagThreadInit(ThreadVars *, void *, void **); -void ReceiveErfDagThreadExitStats(ThreadVars *, void *); -TmEcode ReceiveErfDagThreadDeinit(ThreadVars *, void *); -TmEcode DecodeErfDagThreadInit(ThreadVars *, void *, void **); -TmEcode DecodeErfDagThreadDeinit(ThreadVars *tv, void *data); -TmEcode DecodeErfDag(ThreadVars *, Packet *, void *, PacketQueue *, - PacketQueue *); -void ReceiveErfDagCloseStream(int dagfd, int stream); - -/** - * \brief Register the ERF file receiver (reader) module. - */ -void -TmModuleReceiveErfDagRegister(void) -{ - tmm_modules[TMM_RECEIVEERFDAG].name = "ReceiveErfDag"; - tmm_modules[TMM_RECEIVEERFDAG].ThreadInit = ReceiveErfDagThreadInit; - tmm_modules[TMM_RECEIVEERFDAG].Func = NULL; - tmm_modules[TMM_RECEIVEERFDAG].PktAcqLoop = ReceiveErfDagLoop; - tmm_modules[TMM_RECEIVEERFDAG].ThreadExitPrintStats = - ReceiveErfDagThreadExitStats; - tmm_modules[TMM_RECEIVEERFDAG].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEERFDAG].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEERFDAG].cap_flags = 0; - tmm_modules[TMM_RECEIVEERFDAG].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Register the ERF file decoder module. - */ -void -TmModuleDecodeErfDagRegister(void) -{ - tmm_modules[TMM_DECODEERFDAG].name = "DecodeErfDag"; - tmm_modules[TMM_DECODEERFDAG].ThreadInit = DecodeErfDagThreadInit; - tmm_modules[TMM_DECODEERFDAG].Func = DecodeErfDag; - tmm_modules[TMM_DECODEERFDAG].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEERFDAG].ThreadDeinit = DecodeErfDagThreadDeinit; - tmm_modules[TMM_DECODEERFDAG].RegisterTests = NULL; - tmm_modules[TMM_DECODEERFDAG].cap_flags = 0; - tmm_modules[TMM_DECODEERFDAG].flags = TM_FLAG_DECODE_TM; -} - -/** - * \brief Initialize the ERF receiver thread, generate a single - * ErfDagThreadVar structure for each thread, this will - * contain a DAG file descriptor which is read when the - * thread executes. - * - * \param tv Thread variable to ThreadVars - * \param initdata Initial data to the interface passed from the user, - * this is processed by the user. - * - * We assume that we have only a single name for the DAG - * interface. - * - * \param data data pointer gets populated with - * - */ -TmEcode -ReceiveErfDagThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - int stream_count = 0; - - if (initdata == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Error: No DAG interface provided."); - SCReturnInt(TM_ECODE_FAILED); - } - - ErfDagThreadVars *ewtn = SCMalloc(sizeof(ErfDagThreadVars)); - if (unlikely(ewtn == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, - "Failed to allocate memory for ERF DAG thread vars."); - exit(EXIT_FAILURE); - } - - memset(ewtn, 0, sizeof(*ewtn)); - - /* dag_parse_name will return a DAG device name and stream number - * to open for this thread. - */ - if (dag_parse_name(initdata, ewtn->dagname, DAGNAME_BUFSIZE, - &ewtn->dagstream) < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Failed to parse DAG interface: %s", - (char*)initdata); - SCFree(ewtn); - exit(EXIT_FAILURE); - } - - ewtn->livedev = LiveGetDevice(initdata); - if (ewtn->livedev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Unable to get %s live device", - (char *)initdata); - SCFree(ewtn); - SCReturnInt(TM_ECODE_FAILED); - } - - SCLogInfo("Opening DAG: %s on stream: %d for processing", - ewtn->dagname, ewtn->dagstream); - - if ((ewtn->dagfd = dag_open(ewtn->dagname)) < 0) { - SCLogError(SC_ERR_ERF_DAG_OPEN_FAILED, "Failed to open DAG: %s", - ewtn->dagname); - SCFree(ewtn); - SCReturnInt(TM_ECODE_FAILED); - } - - /* Check to make sure the card has enough available streams to - * support reading from the one specified. - */ - if ((stream_count = dag_rx_get_stream_count(ewtn->dagfd)) < 0) { - SCLogError(SC_ERR_ERF_DAG_OPEN_FAILED, - "Failed to open stream: %d, DAG: %s, could not query stream count", - ewtn->dagstream, ewtn->dagname); - SCFree(ewtn); - SCReturnInt(TM_ECODE_FAILED); - } - - /* Check to make sure we have enough rx streams to open the stream - * the user is asking for. - */ - if (ewtn->dagstream > stream_count * 2) { - SCLogError(SC_ERR_ERF_DAG_OPEN_FAILED, - "Failed to open stream: %d, DAG: %s, insufficient streams: %d", - ewtn->dagstream, ewtn->dagname, stream_count); - SCFree(ewtn); - SCReturnInt(TM_ECODE_FAILED); - } - - /* If we are transmitting into a soft DAG card then set the stream - * to act in reverse mode. - */ - if (0 != (ewtn->dagstream & 0x01)) { - /* Setting reverse mode for using with soft dag from daemon side */ - if (dag_set_mode(ewtn->dagfd, ewtn->dagstream, DAG_REVERSE_MODE)) { - SCLogError(SC_ERR_ERF_DAG_STREAM_OPEN_FAILED, - "Failed to set mode to DAG_REVERSE_MODE on stream: %d, DAG: %s", - ewtn->dagstream, ewtn->dagname); - SCFree(ewtn); - SCReturnInt(TM_ECODE_FAILED); - } - } - - if (dag_attach_stream(ewtn->dagfd, ewtn->dagstream, 0, 0) < 0) { - SCLogError(SC_ERR_ERF_DAG_STREAM_OPEN_FAILED, - "Failed to open DAG stream: %d, DAG: %s", - ewtn->dagstream, ewtn->dagname); - SCFree(ewtn); - SCReturnInt(TM_ECODE_FAILED); - } - - if (dag_start_stream(ewtn->dagfd, ewtn->dagstream) < 0) { - SCLogError(SC_ERR_ERF_DAG_STREAM_START_FAILED, - "Failed to start DAG stream: %d, DAG: %s", - ewtn->dagstream, ewtn->dagname); - SCFree(ewtn); - SCReturnInt(TM_ECODE_FAILED); - } - - SCLogInfo("Attached and started stream: %d on DAG: %s", - ewtn->dagstream, ewtn->dagname); - - /* - * Initialise DAG Polling parameters. - */ - timerclear(&ewtn->maxwait); - ewtn->maxwait.tv_usec = MAXWAIT; - timerclear(&ewtn->poll); - ewtn->poll.tv_usec = POLL_INTERVAL; - - /* 32kB minimum data to return -- we still restrict the number of - * pkts that are processed to a maximum of dag_max_read_packets. - */ - if (dag_set_stream_poll(ewtn->dagfd, ewtn->dagstream, MINDATA, - &(ewtn->maxwait), &(ewtn->poll)) < 0) { - SCLogError(SC_ERR_ERF_DAG_STREAM_SET_FAILED, - "Failed to set poll parameters for stream: %d, DAG: %s", - ewtn->dagstream, ewtn->dagname); - SCFree(ewtn); - SCReturnInt(TM_ECODE_FAILED); - } - - ewtn->packets = StatsRegisterCounter("capture.dag_packets", tv); - ewtn->drops = StatsRegisterCounter("capture.dag_drops", tv); - - ewtn->tv = tv; - *data = (void *)ewtn; - - SCLogInfo("Starting processing packets from stream: %d on DAG: %s", - ewtn->dagstream, ewtn->dagname); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Receives packets from a DAG interface. - * - * \param tv pointer to ThreadVars - * \param data pointer to ErfDagThreadVars - * \param slot slot containing task information - * - * \retval TM_ECODE_OK on success - * \retval TM_ECODE_FAILED on failure - */ -TmEcode -ReceiveErfDagLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - ErfDagThreadVars *dtv = (ErfDagThreadVars *)data; - uint32_t diff = 0; - int err; - uint8_t *top = NULL; - uint32_t pkts_read = 0; - TmSlot *s = (TmSlot *)slot; - - dtv->slot = s->slot_next; - - while (1) { - if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) { - SCReturnInt(TM_ECODE_OK); - } - - top = dag_advance_stream(dtv->dagfd, dtv->dagstream, &(dtv->btm)); - if (top == NULL) { - if (errno == EAGAIN) { - if (dtv->dagstream & 0x1) { - usleep(10 * 1000); - dtv->btm = dtv->top; - } - continue; - } else { - SCLogError(SC_ERR_ERF_DAG_STREAM_READ_FAILED, - "Failed to read from stream: %d, DAG: %s when " - "using dag_advance_stream", - dtv->dagstream, dtv->dagname); - SCReturnInt(TM_ECODE_FAILED); - } - } - - diff = top - dtv->btm; - if (diff == 0) { - continue; - } - - assert(diff >= dag_record_size); - - err = ProcessErfDagRecords(dtv, top, &pkts_read); - - if (err == TM_ECODE_FAILED) { - SCLogError(SC_ERR_ERF_DAG_STREAM_READ_FAILED, - "Failed to read from stream: %d, DAG: %s", - dtv->dagstream, dtv->dagname); - ReceiveErfDagCloseStream(dtv->dagfd, dtv->dagstream); - SCReturnInt(TM_ECODE_FAILED); - } - - StatsSyncCountersIfSignalled(tv); - - SCLogDebug("Read %d records from stream: %d, DAG: %s", - pkts_read, dtv->dagstream, dtv->dagname); - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Process a chunk of records read from a DAG interface. - * - * This function takes a pointer to buffer read from the DAG interface - * and processes it individual records. - */ -static inline TmEcode -ProcessErfDagRecords(ErfDagThreadVars *ewtn, uint8_t *top, uint32_t *pkts_read) -{ - SCEnter(); - - int err = 0; - dag_record_t *dr = NULL; - char *prec = NULL; - int rlen; - char hdr_type = 0; - int processed = 0; - - *pkts_read = 0; - - while (((top - ewtn->btm) >= dag_record_size) && - ((processed + dag_record_size) < BYTES_PER_LOOP)) { - - /* Make sure we have at least one packet in the packet pool, - * to prevent us from alloc'ing packets at line rate. */ - PacketPoolWait(); - - prec = (char *)ewtn->btm; - dr = (dag_record_t*)prec; - rlen = ntohs(dr->rlen); - hdr_type = dr->type; - - /* If we don't have enough data to finish processing this ERF - * record return and maybe next time we will. - */ - if ((top - ewtn->btm) < rlen) - SCReturnInt(TM_ECODE_OK); - - ewtn->btm += rlen; - processed += rlen; - - /* Only support ethernet at this time. */ - switch (hdr_type & 0x7f) { - case TYPE_PAD: - /* Skip. */ - continue; - case TYPE_DSM_COLOR_ETH: - case TYPE_COLOR_ETH: - case TYPE_COLOR_HASH_ETH: - /* In these types the color value overwrites the lctr - * (drop count). */ - break; - case TYPE_ETH: - if (dr->lctr) { - StatsAddUI64(ewtn->tv, ewtn->drops, ntohs(dr->lctr)); - } - break; - default: - SCLogError(SC_ERR_UNIMPLEMENTED, - "Processing of DAG record type: %d not implemented.", dr->type); - SCReturnInt(TM_ECODE_FAILED); - } - - err = ProcessErfDagRecord(ewtn, prec); - if (err != TM_ECODE_OK) { - SCReturnInt(TM_ECODE_FAILED); - } - - (*pkts_read)++; - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Process a DAG record into a TM packet buffer. - * \param prec pointer to a DAG record. - * \param - */ -static inline TmEcode -ProcessErfDagRecord(ErfDagThreadVars *ewtn, char *prec) -{ - SCEnter(); - - int wlen = 0; - int rlen = 0; - int hdr_num = 0; - char hdr_type = 0; - dag_record_t *dr = (dag_record_t*)prec; - erf_payload_t *pload; - Packet *p; - - hdr_type = dr->type; - wlen = ntohs(dr->wlen); - rlen = ntohs(dr->rlen); - - /* count extension headers */ - while (hdr_type & 0x80) { - if (rlen < (dag_record_size + (hdr_num * 8))) { - SCLogError(SC_ERR_UNIMPLEMENTED, - "Insufficient captured packet length."); - SCReturnInt(TM_ECODE_FAILED); - } - hdr_type = prec[(dag_record_size + (hdr_num * 8))]; - hdr_num++; - } - - /* Check that the whole frame was captured */ - if (rlen < (dag_record_size + (8 * hdr_num) + 2 + wlen)) { - SCLogInfo("Incomplete frame captured."); - SCReturnInt(TM_ECODE_OK); - } - - /* skip over extension headers */ - pload = (erf_payload_t *)(prec + dag_record_size + (8 * hdr_num)); - - p = PacketGetFromQueueOrAlloc(); - if (p == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, - "Failed to allocate a Packet on stream: %d, DAG: %s", - ewtn->dagstream, ewtn->dagname); - SCReturnInt(TM_ECODE_FAILED); - } - PKT_SET_SRC(p, PKT_SRC_WIRE); - - SET_PKT_LEN(p, wlen); - p->datalink = LINKTYPE_ETHERNET; - - /* Take into account for link type Ethernet ETH frame starts - * after ther ERF header + pad. - */ - if (unlikely(PacketCopyData(p, pload->eth.dst, GET_PKT_LEN(p)))) { - TmqhOutputPacketpool(ewtn->tv, p); - SCReturnInt(TM_ECODE_FAILED); - } - - /* Convert ERF time to timeval - from libpcap. */ - uint64_t ts = dr->ts; - p->ts.tv_sec = ts >> 32; - ts = (ts & 0xffffffffULL) * 1000000; - ts += 0x80000000; /* rounding */ - p->ts.tv_usec = ts >> 32; - if (p->ts.tv_usec >= 1000000) { - p->ts.tv_usec -= 1000000; - p->ts.tv_sec++; - } - - StatsIncr(ewtn->tv, ewtn->packets); - ewtn->bytes += wlen; - - if (TmThreadsSlotProcessPkt(ewtn->tv, ewtn->slot, p) != TM_ECODE_OK) { - TmqhOutputPacketpool(ewtn->tv, p); - SCReturnInt(TM_ECODE_FAILED); - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Print some stats to the log at program exit. - * - * \param tv Pointer to ThreadVars. - * \param data Pointer to data, ErfFileThreadVars. - */ -void -ReceiveErfDagThreadExitStats(ThreadVars *tv, void *data) -{ - ErfDagThreadVars *ewtn = (ErfDagThreadVars *)data; - - (void)SC_ATOMIC_SET(ewtn->livedev->pkts, - StatsGetLocalCounterValue(tv, ewtn->packets)); - (void)SC_ATOMIC_SET(ewtn->livedev->drop, - StatsGetLocalCounterValue(tv, ewtn->drops)); - - SCLogInfo("Stream: %d; Bytes: %"PRIu64"; Packets: %"PRIu64 - "; Drops: %"PRIu64, - ewtn->dagstream, - ewtn->bytes, - StatsGetLocalCounterValue(tv, ewtn->packets), - StatsGetLocalCounterValue(tv, ewtn->drops)); -} - -/** - * \brief Deinitializes the DAG card. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PcapThreadVars for ptv - */ -TmEcode -ReceiveErfDagThreadDeinit(ThreadVars *tv, void *data) -{ - SCEnter(); - - ErfDagThreadVars *ewtn = (ErfDagThreadVars *)data; - - ReceiveErfDagCloseStream(ewtn->dagfd, ewtn->dagstream); - - SCReturnInt(TM_ECODE_OK); -} - -void -ReceiveErfDagCloseStream(int dagfd, int stream) -{ - dag_stop_stream(dagfd, stream); - dag_detach_stream(dagfd, stream); - dag_close(dagfd); -} - -/** Decode ErfDag */ - -/** - * \brief This function passes off to link type decoders. - * - * DecodeErfDag reads packets from the PacketQueue and passes - * them off to the proper link type decoder. - * - * \param t pointer to ThreadVars - * \param p pointer to the current packet - * \param data pointer that gets cast into PcapThreadVars for ptv - * \param pq pointer to the current PacketQueue - */ -TmEcode -DecodeErfDag(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, - PacketQueue *postpq) -{ - SCEnter(); - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - /* call the decoder */ - switch(p->datalink) { - case LINKTYPE_ETHERNET: - DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - default: - SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, - "Error: datalink type %" PRId32 - " not yet supported in module DecodeErfDag", - p->datalink); - break; - } - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode -DecodeErfDagThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - DecodeThreadVars *dtv = NULL; - - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode -DecodeErfDagThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -#endif /* HAVE_DAG */ diff --git a/framework/src/suricata/src/source-erf-dag.h b/framework/src/suricata/src/source-erf-dag.h deleted file mode 100644 index e712798b..00000000 --- a/framework/src/suricata/src/source-erf-dag.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited - * \author Jason MacLulich - */ - -#ifndef __SOURCE_ERF_DAG_H__ -#define __SOURCE_ERF_DAG_H__ - -void TmModuleReceiveErfDagRegister(void); -void TmModuleDecodeErfDagRegister(void); - -#endif /* __SOURCE_ERF_DAG_H__ */ - diff --git a/framework/src/suricata/src/source-erf-file.c b/framework/src/suricata/src/source-erf-file.c deleted file mode 100644 index 938621c4..00000000 --- a/framework/src/suricata/src/source-erf-file.c +++ /dev/null @@ -1,308 +0,0 @@ -/* Copyright (C) 2010-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited. - * - * Support for reading ERF files. - * - * Only ethernet supported at this time. - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "tm-threads.h" - -#define DAG_TYPE_ETH 2 - -typedef struct DagFlags_ { - uint8_t iface:2; - uint8_t vlen:1; - uint8_t trunc:1; - uint8_t rxerror:1; - uint8_t dserror:1; - uint8_t reserved:1; - uint8_t direction:1; -} DagFlags; - -typedef struct DagRecord_ { - uint64_t ts; - uint8_t type; - DagFlags flags; - uint16_t rlen; - uint16_t lctr; - uint16_t wlen; - uint16_t pad; -} __attribute__((packed)) DagRecord; - -typedef struct ErfFileThreadVars_ { - ThreadVars *tv; - TmSlot *slot; - - FILE *erf; - - uint32_t pkts; - uint64_t bytes; -} ErfFileThreadVars; - -static inline TmEcode ReadErfRecord(ThreadVars *, Packet *, void *); -TmEcode ReceiveErfFileLoop(ThreadVars *, void *, void *); -TmEcode ReceiveErfFileThreadInit(ThreadVars *, void *, void **); -void ReceiveErfFileThreadExitStats(ThreadVars *, void *); -TmEcode ReceiveErfFileThreadDeinit(ThreadVars *, void *); - -TmEcode DecodeErfFileThreadInit(ThreadVars *, void *, void **); -TmEcode DecodeErfFileThreadDeinit(ThreadVars *tv, void *data); -TmEcode DecodeErfFile(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); - -/** - * \brief Register the ERF file receiver (reader) module. - */ -void -TmModuleReceiveErfFileRegister(void) -{ - tmm_modules[TMM_RECEIVEERFFILE].name = "ReceiveErfFile"; - tmm_modules[TMM_RECEIVEERFFILE].ThreadInit = ReceiveErfFileThreadInit; - tmm_modules[TMM_RECEIVEERFFILE].Func = NULL; - tmm_modules[TMM_RECEIVEERFFILE].PktAcqLoop = ReceiveErfFileLoop; - tmm_modules[TMM_RECEIVEERFFILE].ThreadExitPrintStats = - ReceiveErfFileThreadExitStats; - tmm_modules[TMM_RECEIVEERFFILE].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEERFFILE].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEERFFILE].cap_flags = 0; - tmm_modules[TMM_RECEIVEERFFILE].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Register the ERF file decoder module. - */ -void -TmModuleDecodeErfFileRegister(void) -{ - tmm_modules[TMM_DECODEERFFILE].name = "DecodeErfFile"; - tmm_modules[TMM_DECODEERFFILE].ThreadInit = DecodeErfFileThreadInit; - tmm_modules[TMM_DECODEERFFILE].Func = DecodeErfFile; - tmm_modules[TMM_DECODEERFFILE].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEERFFILE].ThreadDeinit = DecodeErfFileThreadDeinit; - tmm_modules[TMM_DECODEERFFILE].RegisterTests = NULL; - tmm_modules[TMM_DECODEERFFILE].cap_flags = 0; - tmm_modules[TMM_DECODEERFFILE].flags = TM_FLAG_DECODE_TM; -} - -/** - * \brief ERF file reading loop. - */ -TmEcode ReceiveErfFileLoop(ThreadVars *tv, void *data, void *slot) -{ - Packet *p = NULL; - ErfFileThreadVars *etv = (ErfFileThreadVars *)data; - - etv->slot = ((TmSlot *)slot)->slot_next; - - while (1) { - if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) { - SCReturnInt(TM_ECODE_OK); - } - - /* Make sure we have at least one packet in the packet pool, - * to prevent us from alloc'ing packets at line rate. */ - PacketPoolWait(); - - p = PacketGetFromQueueOrAlloc(); - if (unlikely(p == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate a packet."); - EngineStop(); - SCReturnInt(TM_ECODE_FAILED); - } - PKT_SET_SRC(p, PKT_SRC_WIRE); - - if (ReadErfRecord(tv, p, data) != TM_ECODE_OK) { - TmqhOutputPacketpool(etv->tv, p); - EngineStop(); - SCReturnInt(TM_ECODE_FAILED); - } - - if (TmThreadsSlotProcessPkt(etv->tv, etv->slot, p) != TM_ECODE_OK) { - EngineStop(); - SCReturnInt(TM_ECODE_FAILED); - } - } - SCReturnInt(TM_ECODE_FAILED); -} - -static inline TmEcode ReadErfRecord(ThreadVars *tv, Packet *p, void *data) -{ - SCEnter(); - - ErfFileThreadVars *etv = (ErfFileThreadVars *)data; - DagRecord dr; - - int r = fread(&dr, sizeof(DagRecord), 1, etv->erf); - if (r < 1) { - if (feof(etv->erf)) { - SCLogInfo("End of ERF file reached"); - } - else { - SCLogInfo("Error reading ERF record"); - } - SCReturnInt(TM_ECODE_FAILED); - } - int rlen = ntohs(dr.rlen); - int wlen = ntohs(dr.wlen); - r = fread(GET_PKT_DATA(p), rlen - sizeof(DagRecord), 1, etv->erf); - if (r < 1) { - if (feof(etv->erf)) { - SCLogInfo("End of ERF file reached"); - } - else { - SCLogInfo("Error reading ERF record"); - } - SCReturnInt(TM_ECODE_FAILED); - } - - /* Only support ethernet at this time. */ - if (dr.type != DAG_TYPE_ETH) { - SCLogError(SC_ERR_UNIMPLEMENTED, - "DAG record type %d not implemented.", dr.type); - SCReturnInt(TM_ECODE_FAILED); - } - - GET_PKT_LEN(p) = wlen; - p->datalink = LINKTYPE_ETHERNET; - - /* Convert ERF time to timeval - from libpcap. */ - uint64_t ts = dr.ts; - p->ts.tv_sec = ts >> 32; - ts = (ts & 0xffffffffULL) * 1000000; - ts += 0x80000000; /* rounding */ - p->ts.tv_usec = ts >> 32; - if (p->ts.tv_usec >= 1000000) { - p->ts.tv_usec -= 1000000; - p->ts.tv_sec++; - } - - etv->pkts++; - etv->bytes += wlen; - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Initialize the ERF receiver thread. - */ -TmEcode -ReceiveErfFileThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - - if (initdata == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Error: No filename provided."); - SCReturnInt(TM_ECODE_FAILED); - } - - FILE *erf = fopen((const char *)initdata, "r"); - if (erf == NULL) { - SCLogError(SC_ERR_FOPEN, "Failed to open %s: %s", (char *)initdata, - strerror(errno)); - exit(EXIT_FAILURE); - } - - ErfFileThreadVars *etv = SCMalloc(sizeof(ErfFileThreadVars)); - if (unlikely(etv == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for ERF file thread vars."); - fclose(erf); - SCReturnInt(TM_ECODE_FAILED); - } - memset(etv, 0, sizeof(*etv)); - etv->erf = erf; - etv->tv = tv; - *data = (void *)etv; - - SCLogInfo("Processing ERF file %s", (char *)initdata); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Initialize the ERF decoder thread. - */ -TmEcode -DecodeErfFileThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - DecodeThreadVars *dtv = NULL; - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodeErfFileThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Decode the ERF file. - * - * This function ups the decoder counters and then passes the packet - * off to the ethernet decoder. - */ -TmEcode -DecodeErfFile(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - SCEnter(); - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - /* Update counters. */ - DecodeUpdatePacketCounters(tv, dtv, p); - - DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Print some stats to the log at program exit. - * - * \param tv Pointer to ThreadVars. - * \param data Pointer to data, ErfFileThreadVars. - */ -void -ReceiveErfFileThreadExitStats(ThreadVars *tv, void *data) -{ - ErfFileThreadVars *etv = (ErfFileThreadVars *)data; - - SCLogInfo("Packets: %"PRIu32"; Bytes: %"PRIu64, etv->pkts, etv->bytes); -} diff --git a/framework/src/suricata/src/source-erf-file.h b/framework/src/suricata/src/source-erf-file.h deleted file mode 100644 index fc56f743..00000000 --- a/framework/src/suricata/src/source-erf-file.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited - */ - -#ifndef __SOURCE_ERF_H__ -#define __SOURCE_ERF_H__ - -void TmModuleReceiveErfFileRegister(void); -void TmModuleDecodeErfFileRegister(void); - -#endif /* __SOURCE_ERF_H__ */ diff --git a/framework/src/suricata/src/source-ipfw.c b/framework/src/suricata/src/source-ipfw.c deleted file mode 100644 index 4c68958b..00000000 --- a/framework/src/suricata/src/source-ipfw.c +++ /dev/null @@ -1,796 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Nick Rogness - * \author Eric Leblond - * - * IPFW packet acquisition support - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "source-ipfw.h" -#include "util-debug.h" -#include "conf.h" -#include "util-byte.h" -#include "util-privs.h" -#include "util-device.h" -#include "runmodes.h" - -#define IPFW_ACCEPT 0 -#define IPFW_DROP 1 - -#define IPFW_SOCKET_POLL_MSEC 300 - -#ifndef IP_MAXPACKET -#define IP_MAXPACKET 65535 -#endif - -#ifndef IPFW -/* Handle the case if --enable-ipfw was not used - * - */ - -TmEcode NoIPFWSupportExit(ThreadVars *, void *, void **); - -void TmModuleReceiveIPFWRegister (void) -{ - - tmm_modules[TMM_RECEIVEIPFW].name = "ReceiveIPFW"; - tmm_modules[TMM_RECEIVEIPFW].ThreadInit = NoIPFWSupportExit; - tmm_modules[TMM_RECEIVEIPFW].Func = NULL; - tmm_modules[TMM_RECEIVEIPFW].ThreadExitPrintStats = NULL; - tmm_modules[TMM_RECEIVEIPFW].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEIPFW].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEIPFW].flags = TM_FLAG_RECEIVE_TM; -} - -void TmModuleVerdictIPFWRegister (void) -{ - tmm_modules[TMM_VERDICTIPFW].name = "VerdictIPFW"; - tmm_modules[TMM_VERDICTIPFW].ThreadInit = NoIPFWSupportExit; - tmm_modules[TMM_VERDICTIPFW].Func = NULL; - tmm_modules[TMM_VERDICTIPFW].ThreadExitPrintStats = NULL; - tmm_modules[TMM_VERDICTIPFW].ThreadDeinit = NULL; - tmm_modules[TMM_VERDICTIPFW].RegisterTests = NULL; -} - -void TmModuleDecodeIPFWRegister (void) -{ - tmm_modules[TMM_DECODEIPFW].name = "DecodeIPFW"; - tmm_modules[TMM_DECODEIPFW].ThreadInit = NoIPFWSupportExit; - tmm_modules[TMM_DECODEIPFW].Func = NULL; - tmm_modules[TMM_DECODEIPFW].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEIPFW].ThreadDeinit = NULL; - tmm_modules[TMM_DECODEIPFW].RegisterTests = NULL; - tmm_modules[TMM_DECODEIPFW].cap_flags = 0; - tmm_modules[TMM_DECODEIPFW].flags = TM_FLAG_DECODE_TM; -} - -TmEcode NoIPFWSupportExit(ThreadVars *tv, void *initdata, void **data) -{ - - SCLogError(SC_ERR_IPFW_NOSUPPORT,"Error creating thread %s: you do not have support for ipfw " - "enabled please recompile with --enable-ipfw", tv->name); - exit(EXIT_FAILURE); -} - -#else /* We have IPFW compiled in */ - -extern int max_pending_packets; - -/** - * \brief Structure to hold thread specific variables. - */ -typedef struct IPFWThreadVars_ -{ - /* data link type for the thread, probably not needed */ - int datalink; - - /* this one should be not changing after init */ - uint16_t port_num; - /* position into the NFQ queue var array */ - uint16_t ipfw_index; - - /* counters */ - uint32_t pkts; - uint64_t bytes; - uint32_t errs; - uint32_t accepted; - uint32_t dropped; -} IPFWThreadVars; - -static IPFWThreadVars ipfw_t[IPFW_MAX_QUEUE]; -static IPFWQueueVars ipfw_q[IPFW_MAX_QUEUE]; -static uint16_t receive_port_num = 0; -static SCMutex ipfw_init_lock; - -/* IPFW Prototypes */ -void *IPFWGetQueue(int number); -TmEcode ReceiveIPFWThreadInit(ThreadVars *, void *, void **); -TmEcode ReceiveIPFW(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode ReceiveIPFWLoop(ThreadVars *tv, void *data, void *slot); -void ReceiveIPFWThreadExitStats(ThreadVars *, void *); -TmEcode ReceiveIPFWThreadDeinit(ThreadVars *, void *); - -TmEcode IPFWSetVerdict(ThreadVars *, IPFWThreadVars *, Packet *); -TmEcode VerdictIPFW(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode VerdictIPFWThreadInit(ThreadVars *, void *, void **); -void VerdictIPFWThreadExitStats(ThreadVars *, void *); -TmEcode VerdictIPFWThreadDeinit(ThreadVars *, void *); - -TmEcode DecodeIPFWThreadInit(ThreadVars *, void *, void **); -TmEcode DecodeIPFWThreadDeinit(ThreadVars *tv, void *data); -TmEcode DecodeIPFW(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); - -/** - * \brief Registration Function for RecieveIPFW. - * \todo Unit tests are needed for this module. - */ -void TmModuleReceiveIPFWRegister (void) -{ - SCMutexInit(&ipfw_init_lock, NULL); - - tmm_modules[TMM_RECEIVEIPFW].name = "ReceiveIPFW"; - tmm_modules[TMM_RECEIVEIPFW].ThreadInit = ReceiveIPFWThreadInit; - tmm_modules[TMM_RECEIVEIPFW].Func = NULL; - tmm_modules[TMM_RECEIVEIPFW].PktAcqLoop = ReceiveIPFWLoop; - tmm_modules[TMM_RECEIVEIPFW].ThreadExitPrintStats = ReceiveIPFWThreadExitStats; - tmm_modules[TMM_RECEIVEIPFW].ThreadDeinit = ReceiveIPFWThreadDeinit; - tmm_modules[TMM_RECEIVEIPFW].cap_flags = SC_CAP_NET_ADMIN | SC_CAP_NET_RAW | - SC_CAP_NET_BIND_SERVICE | - SC_CAP_NET_BROADCAST; /** \todo untested */ - tmm_modules[TMM_RECEIVEIPFW].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEIPFW].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Registration Function for VerdictIPFW. - * \todo Unit tests are needed for this module. - */ -void TmModuleVerdictIPFWRegister (void) -{ - tmm_modules[TMM_VERDICTIPFW].name = "VerdictIPFW"; - tmm_modules[TMM_VERDICTIPFW].ThreadInit = VerdictIPFWThreadInit; - tmm_modules[TMM_VERDICTIPFW].Func = VerdictIPFW; - tmm_modules[TMM_VERDICTIPFW].ThreadExitPrintStats = VerdictIPFWThreadExitStats; - tmm_modules[TMM_VERDICTIPFW].ThreadDeinit = VerdictIPFWThreadDeinit; - tmm_modules[TMM_VERDICTIPFW].cap_flags = SC_CAP_NET_ADMIN | SC_CAP_NET_RAW | - SC_CAP_NET_BIND_SERVICE; /** \todo untested */ - tmm_modules[TMM_VERDICTIPFW].RegisterTests = NULL; -} - -/** - * \brief Registration Function for DecodeIPFW. - * \todo Unit tests are needed for this module. - */ -void TmModuleDecodeIPFWRegister (void) -{ - tmm_modules[TMM_DECODEIPFW].name = "DecodeIPFW"; - tmm_modules[TMM_DECODEIPFW].ThreadInit = DecodeIPFWThreadInit; - tmm_modules[TMM_DECODEIPFW].Func = DecodeIPFW; - tmm_modules[TMM_DECODEIPFW].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEIPFW].ThreadDeinit = DecodeIPFWThreadDeinit; - tmm_modules[TMM_DECODEIPFW].RegisterTests = NULL; - tmm_modules[TMM_DECODEIPFW].flags = TM_FLAG_DECODE_TM; -} - -static inline void IPFWMutexInit(IPFWQueueVars *nq) -{ - char *active_runmode = RunmodeGetActive(); - - if (active_runmode && !strcmp("workers", active_runmode)) { - nq->use_mutex = 0; - SCLogInfo("IPFW running in 'workers' runmode, will not use mutex."); - } else { - nq->use_mutex = 1; - } - if (nq->use_mutex) - SCMutexInit(&nq->socket_lock, NULL); -} - -static inline void IPFWMutexLock(IPFWQueueVars *nq) -{ - if (nq->use_mutex) - SCMutexLock(&nq->socket_lock); -} - -static inline void IPFWMutexUnlock(IPFWQueueVars *nq) -{ - if (nq->use_mutex) - SCMutexUnlock(&nq->socket_lock); -} - -TmEcode ReceiveIPFWLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - IPFWThreadVars *ptv = (IPFWThreadVars *)data; - IPFWQueueVars *nq = NULL; - uint8_t pkt[IP_MAXPACKET]; - int pktlen=0; - struct pollfd IPFWpoll; - struct timeval IPFWts; - Packet *p = NULL; - - nq = IPFWGetQueue(ptv->ipfw_index); - if (nq == NULL) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Can't get thread variable"); - SCReturnInt(TM_ECODE_FAILED); - } - - SCLogInfo("Thread '%s' will run on port %d (item %d)", - tv->name, nq->port_num, ptv->ipfw_index); - while (1) { - if (unlikely(suricata_ctl_flags != 0)) { - SCReturnInt(TM_ECODE_OK); - } - - IPFWpoll.fd = nq->fd; - IPFWpoll.events = POLLRDNORM; - /* Poll the socket for status */ - if ( (poll(&IPFWpoll, 1, IPFW_SOCKET_POLL_MSEC)) > 0) { - if (!(IPFWpoll.revents & (POLLRDNORM | POLLERR))) - continue; - } - - if ((pktlen = recvfrom(nq->fd, pkt, sizeof(pkt), 0, - (struct sockaddr *)&nq->ipfw_sin, - &nq->ipfw_sinlen)) == -1) { - /* We received an error on socket read */ - if (errno == EINTR || errno == EWOULDBLOCK) { - /* Nothing for us to process */ - continue; - } else { - SCLogWarning(SC_WARN_IPFW_RECV, - "Read from IPFW divert socket failed: %s", - strerror(errno)); - SCReturnInt(TM_ECODE_FAILED); - } - } - /* We have a packet to process */ - memset (&IPFWts, 0, sizeof(struct timeval)); - gettimeofday(&IPFWts, NULL); - - /* make sure we have at least one packet in the packet pool, to prevent - * us from alloc'ing packets at line rate */ - PacketPoolWait(); - - p = PacketGetFromQueueOrAlloc(); - if (p == NULL) { - SCReturnInt(TM_ECODE_FAILED); - } - PKT_SET_SRC(p, PKT_SRC_WIRE); - - SCLogDebug("Received Packet Len: %d", pktlen); - - p->ts.tv_sec = IPFWts.tv_sec; - p->ts.tv_usec = IPFWts.tv_usec; - - ptv->pkts++; - ptv->bytes += pktlen; - - p->datalink = ptv->datalink; - - p->ipfw_v.ipfw_index = ptv->ipfw_index; - - PacketCopyData(p, pkt, pktlen); - SCLogDebug("Packet info: pkt_len: %" PRIu32 " (pkt %02x, pkt_data %02x)", - GET_PKT_LEN(p), *pkt, GET_PKT_DATA(p)); - - if (TmThreadsSlotProcessPkt(tv, ((TmSlot *) slot)->slot_next, p) - != TM_ECODE_OK) { - TmqhOutputPacketpool(tv, p); - SCReturnInt(TM_ECODE_FAILED); - } - - StatsSyncCountersIfSignalled(tv); - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Init function for RecieveIPFW. - * - * This is a setup function for recieving packets - * via ipfw divert, binds a socket, and prepares to - * to read from it. - * - * \param tv pointer to ThreadVars - * \param initdata pointer to the divert port passed from the user - * \param data pointer gets populated with IPFWThreadVars - * - */ -TmEcode ReceiveIPFWThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - struct timeval timev; - int flag; - IPFWThreadVars *ntv = (IPFWThreadVars *) initdata; - IPFWQueueVars *nq = IPFWGetQueue(ntv->ipfw_index); - - sigset_t sigs; - sigfillset(&sigs); - pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); - - SCEnter(); - - IPFWMutexInit(nq); - /* We need a divert socket to play with */ - if ((nq->fd = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) { - SCLogError(SC_ERR_IPFW_SOCK,"Can't create divert socket: %s", strerror(errno)); - SCReturnInt(TM_ECODE_FAILED); - } - - /* set a timeout to the socket so we can check for a signal - * in case we don't get packets for a longer period. */ - timev.tv_sec = 1; - timev.tv_usec = 0; - - if (setsockopt(nq->fd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev)) == -1) { - SCLogError(SC_ERR_IPFW_SETSOCKOPT,"Can't set IPFW divert socket timeout: %s", strerror(errno)); - SCReturnInt(TM_ECODE_FAILED); - } - - /* set SO_BROADCAST on the divert socket, otherwise sendto() - * returns EACCES when reinjecting broadcast packets. */ - flag = 1; - - if (setsockopt(nq->fd, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag)) == -1) { - SCLogError(SC_ERR_IPFW_SETSOCKOPT,"Can't set IPFW divert socket broadcast flag: %s", strerror(errno)); - SCReturnInt(TM_ECODE_FAILED); - } - - nq->ipfw_sinlen=sizeof(nq->ipfw_sin); - memset(&nq->ipfw_sin, 0, nq->ipfw_sinlen); - nq->ipfw_sin.sin_family = PF_INET; - nq->ipfw_sin.sin_addr.s_addr = INADDR_ANY; - nq->ipfw_sin.sin_port = htons(nq->port_num); - - /* Bind that SOB */ - if (bind(nq->fd, (struct sockaddr *)&nq->ipfw_sin, nq->ipfw_sinlen) == -1) { - SCLogError(SC_ERR_IPFW_BIND,"Can't bind divert socket on port %d: %s",nq->port_num,strerror(errno)); - SCReturnInt(TM_ECODE_FAILED); - } - - ntv->datalink = DLT_RAW; - - *data = (void *)ntv; - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function prints stats to the screen at exit. - * \todo Unit tests are needed for this module. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into IPFWThreadVars for ptv - */ -void ReceiveIPFWThreadExitStats(ThreadVars *tv, void *data) -{ - IPFWThreadVars *ptv = (IPFWThreadVars *)data; - - SCEnter(); - - SCLogNotice("(%s) Treated: Pkts %" PRIu32 ", Bytes %" PRIu64 ", Errors %" PRIu32 "", - tv->name, ptv->pkts, ptv->bytes, ptv->errs); - SCLogNotice("(%s) Verdict: Accepted %"PRIu32", Dropped %"PRIu32 "", - tv->name, ptv->accepted, ptv->dropped); - - - SCReturn; -} - -/** - * \brief DeInit function closes divert socket at exit. - * \todo Unit tests are needed for this module. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into IPFWThreadVars for ptv - */ -TmEcode ReceiveIPFWThreadDeinit(ThreadVars *tv, void *data) -{ - IPFWThreadVars *ptv = (IPFWThreadVars *)data; - IPFWQueueVars *nq = IPFWGetQueue(ptv->ipfw_index); - - SCEnter(); - - /* Attempt to shut the socket down...close instead? */ - if (shutdown(nq->fd, SHUT_RD) < 0) { - SCLogWarning(SC_WARN_IPFW_UNBIND,"Unable to disable ipfw socket: %s",strerror(errno)); - SCReturnInt(TM_ECODE_FAILED); - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function passes off to link type decoders. - * \todo Unit tests are needed for this module. - * - * DecodeIPFW reads packets from the PacketQueue and passes - * them off to the proper link type decoder. - * - * \param tv pointer to ThreadVars - * \param p pointer to the current packet - * \param data pointer that gets cast into IPFWThreadVars for ptv - * \param pq pointer to the PacketQueue - */ -TmEcode DecodeIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p); - IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p); - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - SCEnter(); - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - /* Process IP packets */ - if (IPV4_GET_RAW_VER(ip4h) == 4) { - SCLogDebug("DecodeIPFW ip4 processing"); - DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - - } else if(IPV6_GET_RAW_VER(ip6h) == 6) { - SCLogDebug("DecodeIPFW ip6 processing"); - DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - - } else { - /* We don't support anything besides IP packets for now, bridged packets? */ - SCLogInfo("IPFW unknown protocol support %02x", *GET_PKT_DATA(p)); - SCReturnInt(TM_ECODE_FAILED); - } - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function initializes the DecodeThreadVariables - * - * - * \param tv pointer to ThreadVars - * \param initdata pointer for passing in args - * \param data pointer that gets cast into IPFWThreadVars for ptv - */ -TmEcode DecodeIPFWThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - DecodeThreadVars *dtv = NULL; - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodeIPFWThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function sets the Verdict and processes the packet - * - * - * \param tv pointer to ThreadVars - * \param p pointer to the Packet - */ -TmEcode IPFWSetVerdict(ThreadVars *tv, IPFWThreadVars *ptv, Packet *p) -{ - uint32_t verdict; - struct pollfd IPFWpoll; - IPFWQueueVars *nq = NULL; - - SCEnter(); - - if (p == NULL) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Packet is NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - nq = IPFWGetQueue(p->ipfw_v.ipfw_index); - if (nq == NULL) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "No thread found"); - SCReturnInt(TM_ECODE_FAILED); - } - - IPFWpoll.fd = nq->fd; - IPFWpoll.events = POLLWRNORM; - - if (PACKET_TEST_ACTION(p, ACTION_DROP)) { - verdict = IPFW_DROP; - } else { - verdict = IPFW_ACCEPT; - } - - if (verdict == IPFW_ACCEPT) { - SCLogDebug("IPFW Verdict is to Accept"); - ptv->accepted++; - - /* For divert sockets, accepting means writing the - * packet back to the socket for ipfw to pick up - */ - SCLogDebug("IPFWSetVerdict writing to socket %d, %p, %u", nq->fd, GET_PKT_DATA(p),GET_PKT_LEN(p)); - -#if 0 - while ((poll(&IPFWpoll,1,IPFW_SOCKET_POLL_MSEC)) < 1) { - /* Did we receive a signal to shutdown */ - if (TmThreadsCheckFlag(tv, THV_KILL) || TmThreadsCheckFlag(tv, THV_PAUSE)) { - SCLogInfo("Received ThreadShutdown: IPFW divert socket writing interrupted"); - SCReturnInt(TM_ECODE_OK); - } - } -#endif - - IPFWMutexLock(nq); - if (sendto(nq->fd, GET_PKT_DATA(p), GET_PKT_LEN(p), 0,(struct sockaddr *)&nq->ipfw_sin, nq->ipfw_sinlen) == -1) { - int r = errno; - switch (r) { - default: - SCLogWarning(SC_WARN_IPFW_XMIT,"Write to ipfw divert socket failed: %s",strerror(r)); - IPFWMutexUnlock(nq); - SCReturnInt(TM_ECODE_FAILED); - case EHOSTDOWN: - case ENETDOWN: - break; - } - } - - IPFWMutexUnlock(nq); - - SCLogDebug("Sent Packet back into IPFW Len: %d",GET_PKT_LEN(p)); - - } /* end IPFW_ACCEPT */ - - - if (verdict == IPFW_DROP) { - SCLogDebug("IPFW SetVerdict is to DROP"); - ptv->dropped++; - - /** \todo For divert sockets, dropping means not writing the packet back to the socket. - * Need to see if there is some better way to free the packet from the queue */ - - } /* end IPFW_DROP */ - - SCReturnInt(TM_ECODE_OK); -} - - -/** - * \brief This function handles the Verdict processing - * \todo Unit tests are needed for this module. - * - * - * \param tv pointer to ThreadVars - * \param p pointer to the Packet - * \param data pointer that gets cast into IPFWThreadVars for ptv - * \param pq pointer for the Packet Queue access (Not used) - */ -TmEcode VerdictIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - IPFWThreadVars *ptv = (IPFWThreadVars *)data; - TmEcode retval = TM_ECODE_OK; - - SCEnter(); - - /* can't verdict a "fake" packet */ - if (p->flags & PKT_PSEUDO_STREAM_END) { - SCReturnInt(TM_ECODE_OK); - } - - /* This came from NFQ. - * if this is a tunnel packet we check if we are ready to verdict - * already. */ - if (IS_TUNNEL_PKT(p)) { - char verdict = 1; - - SCMutex *m = p->root ? &p->root->tunnel_mutex : &p->tunnel_mutex; - SCMutexLock(m); - - /* if there are more tunnel packets than ready to verdict packets, - * we won't verdict this one - */ - if (TUNNEL_PKT_TPR(p) > TUNNEL_PKT_RTV(p)) { - SCLogDebug("VerdictIPFW: not ready to verdict yet: " - "TUNNEL_PKT_TPR(p) > TUNNEL_PKT_RTV(p) = %" PRId32 - " > %" PRId32 "", TUNNEL_PKT_TPR(p), TUNNEL_PKT_RTV(p)); - verdict = 0; - } - - SCMutexUnlock(m); - - /* don't verdict if we are not ready */ - if (verdict == 1) { - SCLogDebug("Setting verdict on tunnel"); - retval = IPFWSetVerdict(tv, ptv, p->root ? p->root : p); - - } else { - TUNNEL_INCR_PKT_RTV(p); - } - } else { - /* no tunnel, verdict normally */ - SCLogDebug("Setting verdict on non-tunnel"); - retval = IPFWSetVerdict(tv, ptv, p); - } /* IS_TUNNEL_PKT end */ - - SCReturnInt(retval); -} - -/** - * \brief This function initializes the VerdictThread - * - * - * \param t pointer to ThreadVars - * \param initdata pointer for passing in args - * \param data pointer that gets cast into IPFWThreadVars for ptv - */ -TmEcode VerdictIPFWThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - - IPFWThreadVars *ptv = NULL; - - SCEnter(); - - /* Setup Thread vars */ - if ( (ptv = SCMalloc(sizeof(IPFWThreadVars))) == NULL) - SCReturnInt(TM_ECODE_FAILED); - memset(ptv, 0, sizeof(IPFWThreadVars)); - - - *data = (void *)ptv; - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function deinitializes the VerdictThread - * - * - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into IPFWThreadVars for ptv - */ -TmEcode VerdictIPFWThreadDeinit(ThreadVars *tv, void *data) -{ - - SCEnter(); - - /* We don't need to do anything...not sure quite yet */ - - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function prints stats for the VerdictThread - * - * - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into IPFWThreadVars for ptv - */ -void VerdictIPFWThreadExitStats(ThreadVars *tv, void *data) -{ - IPFWThreadVars *ptv = (IPFWThreadVars *)data; - SCLogInfo("IPFW Processing: - (%s) Pkts accepted %" PRIu32 ", dropped %" PRIu32 "", tv->name, ptv->accepted, ptv->dropped); -} - -/** - * \brief Add an IPFW divert - * - * \param string with the queue name - * - * \retval 0 on success. - * \retval -1 on failure. - */ -int IPFWRegisterQueue(char *queue) -{ - IPFWThreadVars *ntv = NULL; - IPFWQueueVars *nq = NULL; - /* Extract the queue number from the specified command line argument */ - uint16_t port_num = 0; - if ((ByteExtractStringUint16(&port_num, 10, strlen(queue), queue)) < 0) - { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified queue number %s is not " - "valid", queue); - return -1; - } - - SCMutexLock(&ipfw_init_lock); - if (receive_port_num >= IPFW_MAX_QUEUE) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "too much IPFW divert port registered (%d)", - receive_port_num); - SCMutexUnlock(&ipfw_init_lock); - return -1; - } - if (receive_port_num == 0) { - memset(&ipfw_t, 0, sizeof(ipfw_t)); - memset(&ipfw_q, 0, sizeof(ipfw_q)); - } - - ntv = &ipfw_t[receive_port_num]; - ntv->ipfw_index = receive_port_num; - - nq = &ipfw_q[receive_port_num]; - nq->port_num = port_num; - receive_port_num++; - SCMutexUnlock(&ipfw_init_lock); - LiveRegisterDevice(queue); - - SCLogDebug("Queue \"%s\" registered.", queue); - return 0; -} - -/** - * \brief Get a pointer to the IPFW queue at index - * - * \param number idx of the queue in our array - * - * \retval ptr pointer to the IPFWThreadVars at index - * \retval NULL on error - */ -void *IPFWGetQueue(int number) -{ - if (number >= receive_port_num) - return NULL; - - return (void *)&ipfw_q[number]; -} - -/** - * \brief Get a pointer to the IPFW thread at index - * - * This function is temporary used as configuration parser. - * - * \param number idx of the queue in our array - * - * \retval ptr pointer to the IPFWThreadVars at index - * \retval NULL on error - */ -void *IPFWGetThread(int number) -{ - if (number >= receive_port_num) - return NULL; - - return (void *)&ipfw_t[number]; -} - -#endif /* End ifdef IPFW */ - -/* eof */ - diff --git a/framework/src/suricata/src/source-ipfw.h b/framework/src/suricata/src/source-ipfw.h deleted file mode 100644 index 94c560a4..00000000 --- a/framework/src/suricata/src/source-ipfw.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Nick Rogness - * \author Eric Leblond - */ - -#ifndef __SOURCE_IPFW_H__ -#define __SOURCE_IPFW_H__ - -#define IPFW_MAX_QUEUE 16 - -/* per packet IPFW vars (Not used) */ -typedef struct IPFWPacketVars_ -{ - int ipfw_index; -} IPFWPacketVars; - -typedef struct IPFWQueueVars_ -{ - int fd; - SCMutex socket_lock; - uint8_t use_mutex; - /* this one should be not changing after init */ - uint16_t port_num; - /* position into the ipfw queue var array */ - uint16_t ipfw_index; - struct sockaddr_in ipfw_sin; - socklen_t ipfw_sinlen; - -#ifdef DBG_PERF - int dbg_maxreadsize; -#endif /* DBG_PERF */ - - /* counters */ - uint32_t pkts; - uint64_t bytes; - uint32_t errs; - uint32_t accepted; - uint32_t dropped; - uint32_t replaced; - -} IPFWQueueVars; - -void *IPFWGetThread(int number); -int IPFWRegisterQueue(char *queue); - -void TmModuleReceiveIPFWRegister (void); -void TmModuleVerdictIPFWRegister (void); -void TmModuleDecodeIPFWRegister (void); - - -#endif /* __SOURCE_IPFW_H__ */ diff --git a/framework/src/suricata/src/source-mpipe.c b/framework/src/suricata/src/source-mpipe.c deleted file mode 100644 index 9fdebf65..00000000 --- a/framework/src/suricata/src/source-mpipe.c +++ /dev/null @@ -1,1095 +0,0 @@ -/* Copyright (C) 2011-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * \author Ken Steele, Tilera Corporation - * - * Tilera TILE-Gx mpipe ingress packet support. - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "host.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "tm-threads-common.h" -#include "runmode-tile.h" -#include "source-mpipe.h" -#include "conf.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-privs.h" -#include "util-device.h" -#include "util-mem.h" -#include "util-profiling.h" -#include "tmqh-packetpool.h" -#include "pkt-var.h" - -#ifdef HAVE_MPIPE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Align "p" mod "align", assuming "p" is a "void*". */ -#define ALIGN(p, align) do { (p) += -(long)(p) & ((align) - 1); } while(0) - -#define VERIFY(VAL, WHAT) \ - do { \ - int __val = (VAL); \ - if (__val < 0) { \ - SCLogError(SC_ERR_INVALID_ARGUMENT,(WHAT)); \ - SCReturnInt(TM_ECODE_FAILED); \ - } \ - } while (0) - -#define min(a,b) (((a) < (b)) ? (a) : (b)) - -/** storage for mpipe device names */ -typedef struct MpipeDevice_ { - char *dev; /**< the device (e.g. "xgbe1") */ - TAILQ_ENTRY(MpipeDevice_) next; -} MpipeDevice; - - -/** private device list */ -static TAILQ_HEAD(, MpipeDevice_) mpipe_devices = - TAILQ_HEAD_INITIALIZER(mpipe_devices); - -static int first_stack; -static uint32_t headroom = 2; - -/** - * \brief Structure to hold thread specific variables. - */ -typedef struct MpipeThreadVars_ -{ - ChecksumValidationMode checksum_mode; - - /* counters */ - uint32_t pkts; - uint64_t bytes; - uint32_t errs; - - ThreadVars *tv; - TmSlot *slot; - - Packet *in_p; - - /** stats/counters */ - uint16_t max_mpipe_depth; - uint16_t mpipe_drop; - uint16_t counter_no_buffers_0; - uint16_t counter_no_buffers_1; - uint16_t counter_no_buffers_2; - uint16_t counter_no_buffers_3; - uint16_t counter_no_buffers_4; - uint16_t counter_no_buffers_5; - uint16_t counter_no_buffers_6; - uint16_t counter_no_buffers_7; - -} MpipeThreadVars; - -TmEcode ReceiveMpipeLoop(ThreadVars *tv, void *data, void *slot); -TmEcode ReceiveMpipeThreadInit(ThreadVars *, void *, void **); -void ReceiveMpipeThreadExitStats(ThreadVars *, void *); - -TmEcode DecodeMpipeThreadInit(ThreadVars *, void *, void **); -TmEcode DecodeMpipeThreadDeinit(ThreadVars *tv, void *data); -TmEcode DecodeMpipe(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -static int MpipeReceiveOpenIqueue(int rank); - -#define MAX_CHANNELS 32 /* can probably find this in the MDE */ - -/* - * mpipe configuration. - */ - -/* The mpipe context (shared by all workers) */ -static gxio_mpipe_context_t context_body; -static gxio_mpipe_context_t* context = &context_body; - -/* First allocated Notification ring for iQueues. */ -static int first_notif_ring; - -/* The ingress queue for this worker thread */ -static __thread gxio_mpipe_iqueue_t* thread_iqueue; - -/* The egress queues (one per port) */ -static gxio_mpipe_equeue_t equeue[MAX_CHANNELS]; - -/* the number of entries in an equeue ring */ -static const int equeue_entries = 8192; - -/* Array of mpipe links */ -static gxio_mpipe_link_t mpipe_link[MAX_CHANNELS]; - -/* Per interface configuration data */ -static MpipeIfaceConfig *mpipe_conf[MAX_CHANNELS]; - -/* Per interface TAP/IPS configuration */ - -/* egress equeue associated with each ingress channel */ -static MpipePeerVars channel_to_equeue[MAX_CHANNELS]; - -/** - * \brief Registration Function for ReceiveMpipe. - * \todo Unit tests are needed for this module. - */ -void TmModuleReceiveMpipeRegister (void) -{ - tmm_modules[TMM_RECEIVEMPIPE].name = "ReceiveMpipe"; - tmm_modules[TMM_RECEIVEMPIPE].ThreadInit = ReceiveMpipeThreadInit; - tmm_modules[TMM_RECEIVEMPIPE].Func = NULL; - tmm_modules[TMM_RECEIVEMPIPE].PktAcqLoop = ReceiveMpipeLoop; - tmm_modules[TMM_RECEIVEMPIPE].ThreadExitPrintStats = ReceiveMpipeThreadExitStats; - tmm_modules[TMM_RECEIVEMPIPE].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEMPIPE].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEMPIPE].cap_flags = SC_CAP_NET_RAW; - tmm_modules[TMM_RECEIVEMPIPE].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Registraction Function for DecodeNetio. - * \todo Unit tests are needed for this module. - */ -void TmModuleDecodeMpipeRegister (void) -{ - tmm_modules[TMM_DECODEMPIPE].name = "DecodeMpipe"; - tmm_modules[TMM_DECODEMPIPE].ThreadInit = DecodeMpipeThreadInit; - tmm_modules[TMM_DECODEMPIPE].Func = DecodeMpipe; - tmm_modules[TMM_DECODEMPIPE].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEMPIPE].ThreadDeinit = DecodeMpipeThreadDeinit; - tmm_modules[TMM_DECODEMPIPE].RegisterTests = NULL; - tmm_modules[TMM_DECODEMPIPE].cap_flags = 0; - tmm_modules[TMM_DECODEMPIPE].flags = TM_FLAG_DECODE_TM; -} - -/* Release Packet without sending. */ -void MpipeReleasePacket(Packet *p) -{ - /* Use this thread's context to free the packet. */ - // TODO: Check for dual mPipes. - gxio_mpipe_iqueue_t* iqueue = thread_iqueue; - int bucket = p->mpipe_v.idesc.bucket_id; - gxio_mpipe_credit(iqueue->context, iqueue->ring, bucket, 1); - - gxio_mpipe_push_buffer(iqueue->context, - p->mpipe_v.idesc.stack_idx, - (void*)(intptr_t)p->mpipe_v.idesc.va); -} - -/* Unconditionally send packet, then release packet buffer. */ -void MpipeReleasePacketCopyTap(Packet *p) -{ - gxio_mpipe_iqueue_t* iqueue = thread_iqueue; - int bucket = p->mpipe_v.idesc.bucket_id; - gxio_mpipe_credit(iqueue->context, iqueue->ring, bucket, 1); - gxio_mpipe_edesc_t edesc; - edesc.words[0] = 0; - edesc.words[1] = 0; - edesc.bound = 1; - edesc.xfer_size = p->mpipe_v.idesc.l2_size; - edesc.va = p->mpipe_v.idesc.va; - edesc.stack_idx = p->mpipe_v.idesc.stack_idx; - edesc.hwb = 1; /* mPIPE will return packet buffer to proper stack. */ - edesc.size = p->mpipe_v.idesc.size; - int channel = p->mpipe_v.idesc.channel; - /* Tell mPIPE to egress the packet. */ - gxio_mpipe_equeue_put(channel_to_equeue[channel].peer_equeue, edesc); -} - -/* Release Packet and send copy if action is not DROP. */ -void MpipeReleasePacketCopyIPS(Packet *p) -{ - if (unlikely(PACKET_TEST_ACTION(p, ACTION_DROP))) { - /* Return packet buffer without sending the packet. */ - MpipeReleasePacket(p); - } else { - /* Send packet */ - MpipeReleasePacketCopyTap(p); - } -} - -/** - * \brief Mpipe Packet Process function. - * - * This function fills in our packet structure from mpipe. - * From here the packets are picked up by the DecodeMpipe thread. - * - * \param user pointer to MpipeThreadVars passed from pcap_dispatch - * \param h pointer to gxio packet header - * \param pkt pointer to current packet - */ -static inline -Packet *MpipeProcessPacket(MpipeThreadVars *ptv, gxio_mpipe_idesc_t *idesc) -{ - int caplen = idesc->l2_size; - u_char *pkt = gxio_mpipe_idesc_get_va(idesc); - Packet *p = (Packet *)(pkt - sizeof(Packet) - headroom/*2*/); - - PACKET_RECYCLE(p); - PKT_SET_SRC(p, PKT_SRC_WIRE); - - ptv->bytes += caplen; - ptv->pkts++; - - gettimeofday(&p->ts, NULL); - - p->datalink = LINKTYPE_ETHERNET; - /* No need to check return value, since the only error is pkt == NULL which can't happen here. */ - PacketSetData(p, pkt, caplen); - - /* copy only the fields we use later */ - p->mpipe_v.idesc.bucket_id = idesc->bucket_id; - p->mpipe_v.idesc.nr = idesc->nr; - p->mpipe_v.idesc.cs = idesc->cs; - p->mpipe_v.idesc.va = idesc->va; - p->mpipe_v.idesc.stack_idx = idesc->stack_idx; - MpipePeerVars *equeue_info = &channel_to_equeue[idesc->channel]; - if (equeue_info->copy_mode != MPIPE_COPY_MODE_NONE) { - p->mpipe_v.idesc.size = idesc->size; - p->mpipe_v.idesc.l2_size = idesc->l2_size; - p->mpipe_v.idesc.channel = idesc->channel; - p->ReleasePacket = equeue_info->ReleasePacket; - } else { - p->ReleasePacket = MpipeReleasePacket; - } - - if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) - p->flags |= PKT_IGNORE_CHECKSUM; - - return p; -} - -static uint16_t XlateStack(MpipeThreadVars *ptv, int stack_idx) -{ - switch(stack_idx - first_stack) { - case 0: - return ptv->counter_no_buffers_0; - case 1: - return ptv->counter_no_buffers_1; - case 2: - return ptv->counter_no_buffers_2; - case 3: - return ptv->counter_no_buffers_3; - case 4: - return ptv->counter_no_buffers_4; - case 5: - return ptv->counter_no_buffers_5; - case 6: - return ptv->counter_no_buffers_6; - case 7: - return ptv->counter_no_buffers_7; - default: - return ptv->counter_no_buffers_7; - } -} - -static void SendNoOpPacket(ThreadVars *tv, TmSlot *slot) -{ - Packet *p = PacketPoolGetPacket(); - if (p == NULL) { - return; - } - - p->datalink = DLT_RAW; - p->proto = IPPROTO_TCP; - - /* So that DecodeMpipe ignores is. */ - p->flags |= PKT_PSEUDO_STREAM_END; - - p->flow = NULL; - - TmThreadsSlotProcessPkt(tv, slot, p); -} - -/** - * \brief Receives packets from an interface via gxio mpipe. - */ -TmEcode ReceiveMpipeLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - MpipeThreadVars *ptv = (MpipeThreadVars *)data; - TmSlot *s = (TmSlot *)slot; - ptv->slot = s->slot_next; - Packet *p = NULL; - int rank = tv->rank; - int max_queued = 0; - char *ctype; - - ptv->checksum_mode = CHECKSUM_VALIDATION_DISABLE; - if (ConfGet("mpipe.checksum-checks", &ctype) == 1) { - if (strcmp(ctype, "yes") == 0) { - ptv->checksum_mode = CHECKSUM_VALIDATION_ENABLE; - } else if (strcmp(ctype, "no") == 0) { - ptv->checksum_mode = CHECKSUM_VALIDATION_DISABLE; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Invalid value for checksum-check for mpipe"); - } - } - - /* Open Ingress Queue for this worker thread. */ - MpipeReceiveOpenIqueue(rank); - gxio_mpipe_iqueue_t* iqueue = thread_iqueue; - int update_counter = 0; - uint64_t last_packet_time = get_cycle_count(); - - for (;;) { - - /* Check to see how many packets are available to process. */ - gxio_mpipe_idesc_t *idesc; - int n = gxio_mpipe_iqueue_try_peek(iqueue, &idesc); - if (likely(n > 0)) { - int i; - int m = min(n, 16); - - /* Prefetch the idescs (64 bytes each). */ - for (i = 0; i < m; i++) { - __insn_prefetch(&idesc[i]); - } - if (unlikely(n > max_queued)) { - StatsSetUI64(tv, ptv->max_mpipe_depth, - (uint64_t)n); - max_queued = n; - } - for (i = 0; i < m; i++, idesc++) { - if (likely(!gxio_mpipe_idesc_has_error(idesc))) { - p = MpipeProcessPacket(ptv, idesc); - p->mpipe_v.rank = rank; - if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - if (idesc->be) { - /* Buffer Error - No buffer available, so mPipe - * dropped the packet. */ - StatsIncr(tv, XlateStack(ptv, idesc->stack_idx)); - } else { - /* Bad packet. CRC error */ - StatsIncr(tv, ptv->mpipe_drop); - gxio_mpipe_iqueue_drop(iqueue, idesc); - } - gxio_mpipe_iqueue_release(iqueue, idesc); - } - } - /* Move forward M packets in ingress ring. */ - gxio_mpipe_iqueue_advance(iqueue, m); - - last_packet_time = get_cycle_count(); - } - if (update_counter-- <= 0) { - /* Only periodically update and check for termination. */ - StatsSyncCountersIfSignalled(tv); - update_counter = 10000; - - if (suricata_ctl_flags != 0) { - break; - } - - // If no packet has been received for some period of time, process a NOP packet - // just to make sure that pseudo packets from the Flow manager get processed. - uint64_t now = get_cycle_count(); - if (now - last_packet_time > 100000000) { - SendNoOpPacket(ptv->tv, ptv->slot); - last_packet_time = now; - } - } - } - SCReturnInt(TM_ECODE_OK); -} - -static void MpipeRegisterPerfCounters(MpipeThreadVars *ptv, ThreadVars *tv) -{ - /* register counters */ - ptv->max_mpipe_depth = StatsRegisterCounter("mpipe.max_mpipe_depth", tv); - ptv->mpipe_drop = StatsRegisterCounter("mpipe.drop", tv); - ptv->counter_no_buffers_0 = StatsRegisterCounter("mpipe.no_buf0", tv); - ptv->counter_no_buffers_1 = StatsRegisterCounter("mpipe.no_buf1", tv); - ptv->counter_no_buffers_2 = StatsRegisterCounter("mpipe.no_buf2", tv); - ptv->counter_no_buffers_3 = StatsRegisterCounter("mpipe.no_buf3", tv); - ptv->counter_no_buffers_4 = StatsRegisterCounter("mpipe.no_buf4", tv); - ptv->counter_no_buffers_5 = StatsRegisterCounter("mpipe.no_buf5", tv); - ptv->counter_no_buffers_6 = StatsRegisterCounter("mpipe.no_buf6", tv); - ptv->counter_no_buffers_7 = StatsRegisterCounter("mpipe.no_buf7", tv); -} - -static const gxio_mpipe_buffer_size_enum_t gxio_buffer_sizes[] = { - GXIO_MPIPE_BUFFER_SIZE_128, - GXIO_MPIPE_BUFFER_SIZE_256, - GXIO_MPIPE_BUFFER_SIZE_512, - GXIO_MPIPE_BUFFER_SIZE_1024, - GXIO_MPIPE_BUFFER_SIZE_1664, - GXIO_MPIPE_BUFFER_SIZE_4096, - GXIO_MPIPE_BUFFER_SIZE_10368, - GXIO_MPIPE_BUFFER_SIZE_16384 -}; - -static const int buffer_sizes[] = { - 128, - 256, - 512, - 1024, - 1664, - 4096, - 10368, - 16384 -}; - -static int NormalizeBufferWeights(float buffer_weights[], int num_weights) -{ - int stack_count = 0; - /* Count required buffer stacks and normalize weights to sum to 1.0. */ - float total_weight = 0; - for (int i = 0; i < num_weights; i++) { - if (buffer_weights[i] != 0) { - ++stack_count; - total_weight += buffer_weights[i]; - } - } - /* Convert each weight to a value between 0 and 1. inclusive. */ - for (int i = 0; i < num_weights; i++) { - if (buffer_weights[i] != 0) { - buffer_weights[i] /= total_weight; - } - } - - SCLogInfo("DEBUG: %u non-zero sized stacks", stack_count); - return stack_count; -} - -static TmEcode ReceiveMpipeAllocatePacketBuffers(void) -{ - SCEnter(); - int num_buffers; - int result; - int total_buffers = 0; - - /* Relative weighting for the number of buffers of each size. - */ - float buffer_weight[] = { - 0 , /* 128 */ - 4 , /* 256 */ - 0 , /* 512 */ - 0 , /* 1024 */ - 4 , /* 1664 */ - 0 , /* 4096 */ - 0 , /* 10386 */ - 0 /* 16384 */ - }; - - int num_weights = sizeof(buffer_weight)/sizeof(buffer_weight[0]); - if (ConfGetNode("mpipe.stack") != NULL) { - float weight; - for (int i = 0; i < num_weights; i++) - buffer_weight[i] = 0; - if (ConfGetFloat("mpipe.stack.size128", &weight)) - buffer_weight[0] = weight; - if (ConfGetFloat("mpipe.stack.size256", &weight)) - buffer_weight[1] = weight; - if (ConfGetFloat("mpipe.stack.size512", &weight)) - buffer_weight[2] = weight; - if (ConfGetFloat("mpipe.stack.size1024", &weight)) - buffer_weight[3] = weight; - if (ConfGetFloat("mpipe.stack.size1664", &weight)) - buffer_weight[4] = weight; - if (ConfGetFloat("mpipe.stack.size4096", &weight)) - buffer_weight[5] = weight; - if (ConfGetFloat("mpipe.stack.size10386", &weight)) - buffer_weight[6] = weight; - if (ConfGetFloat("mpipe.stack.size16384", &weight)) - buffer_weight[7] = weight; - } - - int stack_count = NormalizeBufferWeights(buffer_weight, num_weights); - - /* Allocate one of the largest pages to hold our buffer stack, - * notif ring, and packets. First get a bit map of the - * available page sizes. */ - unsigned long available_pagesizes = tmc_alloc_get_pagesizes(); - - void *packet_page = NULL; - size_t tile_vhuge_size = 64 * 1024; - - /* Try the largest available page size first to see if any - * pages of that size can be allocated. */ - for (int i = sizeof(available_pagesizes) * 8 - 1; i; i--) { - unsigned long size = 1UL<= 1) && (value <= 4096)) { - /* Must be a power of 2, so round up to next power of 2. */ - int ceiling_log2 = 64 - __builtin_clz((int64_t)value - 1); - *num_buckets = 1 << (ceiling_log2); - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Illegal mpipe.buckets value (%ld). must be between 1 and 4096.", value); - } - } - if (ConfGetInt("mpipe.min-buckets", &value) == 1) { - /* range check */ - if ((value >= 1) && (value <= 4096)) { - /* Must be a power of 2, so round up to next power of 2. */ - int ceiling_log2 = 64 - __builtin_clz((int64_t)value - 1); - min_buckets = 1 << (ceiling_log2); - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Illegal min-mpipe.buckets value (%ld). must be between 1 and 4096.", value); - } - } - - /* Allocate buckets. Keep trying half the number of requested buckets until min-bucket is reached. */ - while (1) { - *first_bucket = gxio_mpipe_alloc_buckets(context, *num_buckets, 0, 0); - if (*first_bucket != GXIO_MPIPE_ERR_NO_BUCKET) - break; - /* Failed to allocate the requested number of buckets. Keep - * trying less buckets until min-buckets is reached. - */ - if (*num_buckets <= min_buckets) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Could not allocate (%d) mpipe buckets. " - "Try a smaller mpipe.buckets value in suricata.yaml", *num_buckets); - SCReturnInt(TM_ECODE_FAILED); - } - /* Cut the number of requested buckets in half and try again. */ - *num_buckets /= 2; - } - - /* Init group and buckets, preserving packet order among flows. */ - gxio_mpipe_bucket_mode_t mode = GXIO_MPIPE_BUCKET_STATIC_FLOW_AFFINITY; - char *balance; - if (ConfGet("mpipe.load-balance", &balance) == 1) { - if (balance) { - if (strcmp(balance, "static") == 0) { - mode = GXIO_MPIPE_BUCKET_STATIC_FLOW_AFFINITY; - SCLogInfo("Using \"static\" flow affinity load balancing with %d buckets.", *num_buckets); - } else if (strcmp(balance, "dynamic") == 0) { - mode = GXIO_MPIPE_BUCKET_DYNAMIC_FLOW_AFFINITY; - SCLogInfo("Using \"dynamic\" flow affinity load balancing with %d buckets.", *num_buckets); - } else if (strcmp(balance, "sticky") == 0) { - mode = GXIO_MPIPE_BUCKET_STICKY_FLOW_LOCALITY; - SCLogInfo("Using \"sticky\" load balancing with %d buckets.", *num_buckets); - } else if (strcmp(balance, "round-robin") == 0) { - mode = GXIO_MPIPE_BUCKET_ROUND_ROBIN; - } else { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, - "Illegal load balancing mode \"%s\"", balance); - balance = "static"; - } - } - } else { - balance = "static"; - } - SCLogInfo("Using \"%s\" load balancing with %d buckets.", balance, *num_buckets); - - result = gxio_mpipe_init_notif_group_and_buckets(context, group, - ring, num_workers, - *first_bucket, - *num_buckets, - mode); - VERIFY(result, "gxio_mpipe_init_notif_group_and_buckets()"); - - SCReturnInt(TM_ECODE_OK); -} - -/* \brief Register mPIPE classifier rules to start receiving packets. - * - * \param Index of the first classifier bucket - * \param Number of classifier buckets. - * - * \return result code where <0 is an error. - */ -static int ReceiveMpipeRegisterRules(int bucket, int num_buckets) -{ - /* Register for packets. */ - gxio_mpipe_rules_t rules; - gxio_mpipe_rules_init(&rules, context); - gxio_mpipe_rules_begin(&rules, bucket, num_buckets, NULL); - /* Give Suricata priority over Linux to receive packets. */ - gxio_mpipe_rules_set_priority(&rules, -100); - return gxio_mpipe_rules_commit(&rules); -} - -/* \brief Initialize mPIPE ingress ring - * - * \param name of interface to open - * \param Array of port configuations - * - * \return Output port channel number, or -1 on error - */ -static int MpipeReceiveOpenIqueue(int rank) -{ - /* Initialize the NotifRings. */ - size_t notif_ring_entries = 2048; - intmax_t value = 0; - if (ConfGetInt("mpipe.iqueue-packets", &value) == 1) { - /* range check */ - if (value == 128 || value == 512 || value == 2048 || value == (64 * 1024)) { - notif_ring_entries = value; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Illegal mpipe.iqueue_packets value. must be 128, 512, 2048 or 65536."); - } - } - - size_t notif_ring_size = notif_ring_entries * sizeof(gxio_mpipe_idesc_t); - - tmc_alloc_t alloc = TMC_ALLOC_INIT; - /* Allocate the memory locally on this thread's CPU. */ - tmc_alloc_set_home(&alloc, TMC_ALLOC_HOME_TASK); - /* Allocate all the memory on one page. Which is required for the - notif ring, not the iqueue. */ - if (notif_ring_size > (size_t)getpagesize()) - tmc_alloc_set_huge(&alloc); - int needed = notif_ring_size + sizeof(gxio_mpipe_iqueue_t); - // TODO - Save the rest of the Huge Page for other allocations. - void *iqueue_mem = tmc_alloc_map(&alloc, needed); - if (iqueue_mem == NULL) { - SCLogError(SC_ERR_FATAL, "Failed to allocate memory for mPIPE iQueue"); - return TM_ECODE_FAILED; - } - - thread_iqueue = iqueue_mem + notif_ring_size; - int result = gxio_mpipe_iqueue_init(thread_iqueue, context, first_notif_ring + rank, - iqueue_mem, notif_ring_size, 0); - if (result < 0) { - VERIFY(result, "gxio_mpipe_iqueue_init()"); - } - - return TM_ECODE_OK; -} - -/* \brief Initialize on MPIPE egress port - * - * Initialize one mPIPE egress port for use in IPS mode. - * The port must be one of the input ports. - * - * \param name of interface to open - * \param Array of port configuations - * - * \return Output port channel number, or -1 on error - */ -static int MpipeReceiveOpenEgress(char *out_iface, int iface_idx, - int copy_mode, - MpipeIfaceConfig *mpipe_conf[]) -{ - int channel; - int nlive = LiveGetDeviceCount(); - int result; - - /* Initialize an equeue */ - result = gxio_mpipe_alloc_edma_rings(context, 1, 0, 0); - if (result < 0) { - SCLogError(SC_ERR_FATAL, "Failed to allocate mPIPE egress ring"); - return result; - } - uint32_t ering = result; - size_t edescs_size = equeue_entries * sizeof(gxio_mpipe_edesc_t); - tmc_alloc_t edescs_alloc = TMC_ALLOC_INIT; - tmc_alloc_set_pagesize(&edescs_alloc, edescs_size); - void *edescs = tmc_alloc_map(&edescs_alloc, edescs_size); - if (edescs == NULL) { - SCLogError(SC_ERR_FATAL, - "Failed to allocate egress descriptors"); - return -1; - } - /* retrieve channel of outbound interface */ - for (int j = 0; j < nlive; j++) { - if (strcmp(out_iface, mpipe_conf[j]->iface) == 0) { - channel = gxio_mpipe_link_channel(&mpipe_link[j]); - SCLogInfo("egress link: %s is channel: %d", - out_iface, channel); - result = gxio_mpipe_equeue_init(&equeue[iface_idx], - context, - ering, - channel, - edescs, - edescs_size, - 0); - if (result < 0) { - SCLogError(SC_ERR_FATAL, - "mPIPE Failed to initialize egress queue"); - return -1; - } - /* Record the mapping from ingress port to egress port. - * The egress information is stored indexed by ingress channel. - */ - channel = gxio_mpipe_link_channel(&mpipe_link[iface_idx]); - channel_to_equeue[channel].peer_equeue = &equeue[iface_idx]; - channel_to_equeue[channel].copy_mode = copy_mode; - if (copy_mode == MPIPE_COPY_MODE_IPS) - channel_to_equeue[channel].ReleasePacket = MpipeReleasePacketCopyIPS; - else - channel_to_equeue[channel].ReleasePacket = MpipeReleasePacketCopyTap; - - SCLogInfo("ingress link: %s is channel: %d copy_mode: %d", - out_iface, channel, copy_mode); - - return channel; - } - } - - /* Did not find matching interface name */ - SCLogError(SC_ERR_INVALID_ARGUMENT, "Could not find egress interface: %s", - out_iface); - return -1; -} - -TmEcode ReceiveMpipeThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - int rank = tv->rank; - int num_buckets = 4096; - int num_workers = tile_num_pipelines; - - if (initdata == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - MpipeThreadVars *ptv = SCMalloc(sizeof(MpipeThreadVars)); - if (unlikely(ptv == NULL)) - SCReturnInt(TM_ECODE_FAILED); - - memset(ptv, 0, sizeof(MpipeThreadVars)); - - ptv->tv = tv; - - int result; - char *link_name = (char *)initdata; - - MpipeRegisterPerfCounters(ptv, tv); - - *data = (void *)ptv; - - /* Only rank 0 does initialization of mpipe */ - if (rank != 0) - SCReturnInt(TM_ECODE_OK); - - /* Initialize and configure mPIPE, which is only done by one core. */ - - if (strcmp(link_name, "multi") == 0) { - int nlive = LiveGetDeviceCount(); - int instance = gxio_mpipe_link_instance(LiveGetDeviceName(0)); - for (int i = 1; i < nlive; i++) { - link_name = LiveGetDeviceName(i); - if (gxio_mpipe_link_instance(link_name) != instance) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "All interfaces not on same mpipe instance"); - SCReturnInt(TM_ECODE_FAILED); - } - } - result = gxio_mpipe_init(context, instance); - VERIFY(result, "gxio_mpipe_init()"); - /* open ingress interfaces */ - for (int i = 0; i < nlive; i++) { - link_name = LiveGetDeviceName(i); - SCLogInfo("opening interface %s", link_name); - result = gxio_mpipe_link_open(&mpipe_link[i], context, - link_name, 0); - VERIFY(result, "gxio_mpipe_link_open()"); - mpipe_conf[i] = ParseMpipeConfig(link_name); - } - /* find and open egress interfaces for IPS modes */ - for (int i = 0; i < nlive; i++) { - MpipeIfaceConfig *aconf = mpipe_conf[i]; - if (aconf != NULL) { - if (aconf->copy_mode != MPIPE_COPY_MODE_NONE) { - int channel = MpipeReceiveOpenEgress(aconf->out_iface, - i, aconf->copy_mode, - mpipe_conf); - if (channel < 0) { - SCReturnInt(TM_ECODE_FAILED); - } - } - } - } - } else { - SCLogInfo("using single interface %s", (char *)initdata); - - /* Start the driver. */ - result = gxio_mpipe_init(context, gxio_mpipe_link_instance(link_name)); - VERIFY(result, "gxio_mpipe_init()"); - - gxio_mpipe_link_t link; - result = gxio_mpipe_link_open(&link, context, link_name, 0); - VERIFY(result, "gxio_mpipe_link_open()"); - } - /* Allocate some NotifRings. */ - result = gxio_mpipe_alloc_notif_rings(context, - num_workers, - 0, 0); - VERIFY(result, "gxio_mpipe_alloc_notif_rings()"); - first_notif_ring = result; - - int first_bucket = 0; - int rc; - rc = ReceiveMpipeCreateBuckets(first_notif_ring, num_workers, - &first_bucket, &num_buckets); - if (rc != TM_ECODE_OK) - SCReturnInt(rc); - - rc = ReceiveMpipeAllocatePacketBuffers(); - if (rc != TM_ECODE_OK) - SCReturnInt(rc); - - result = ReceiveMpipeRegisterRules(first_bucket, num_buckets); - if (result < 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Registering mPIPE classifier rules, %s", - gxio_strerror(result)); - SCReturnInt(TM_ECODE_FAILED); - } - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode ReceiveMpipeInit(void) -{ - SCEnter(); - - SCLogInfo("tile_num_pipelines: %d", tile_num_pipelines); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function prints stats to the screen at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into NetiohreadVars for ptv - */ -void ReceiveMpipeThreadExitStats(ThreadVars *tv, void *data) -{ - SCEnter(); - SCReturn; -} - -TmEcode DecodeMpipeThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - DecodeThreadVars *dtv = NULL; - - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodeMpipeThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodeMpipe(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, - PacketQueue *postq) -{ - SCEnter(); - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - /* call the decoder */ - DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Add a mpipe device for monitoring - * - * \param dev string with the device name - * - * \retval 0 on success. - * \retval -1 on failure. - */ -int MpipeLiveRegisterDevice(char *dev) -{ - MpipeDevice *nd = SCMalloc(sizeof(MpipeDevice)); - if (unlikely(nd == NULL)) { - return -1; - } - - nd->dev = SCStrdup(dev); - if (unlikely(nd->dev == NULL)) { - SCFree(nd); - return -1; - } - TAILQ_INSERT_TAIL(&mpipe_devices, nd, next); - - SCLogDebug("Mpipe device \"%s\" registered.", dev); - return 0; -} - -/** - * \brief Get the number of registered devices - * - * \retval cnt the number of registered devices - */ -int MpipeLiveGetDeviceCount(void) -{ - int i = 0; - MpipeDevice *nd; - - TAILQ_FOREACH(nd, &mpipe_devices, next) { - i++; - } - - return i; -} - -#endif // HAVE_MPIPE diff --git a/framework/src/suricata/src/source-mpipe.h b/framework/src/suricata/src/source-mpipe.h deleted file mode 100644 index 2c335bff..00000000 --- a/framework/src/suricata/src/source-mpipe.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (C) 2011-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * \author Ken Steele, Tilera Corporation - */ - -#ifndef __SOURCE_MPIPE_H__ -#define __SOURCE_MPIPE_H__ - -#ifdef HAVE_MPIPE - -#include -#include - -#define MPIPE_FREE_PACKET(p) MpipeFreePacket((p)) - -#define MPIPE_COPY_MODE_NONE 0 -#define MPIPE_COPY_MODE_TAP 1 -#define MPIPE_COPY_MODE_IPS 2 - -#define MPIPE_IFACE_NAME_LENGTH 8 - -typedef struct MpipeIfaceConfig_ -{ - char iface[MPIPE_IFACE_NAME_LENGTH]; - int copy_mode; - char *out_iface; -} MpipeIfaceConfig; - -typedef struct MpipePeer_ -{ - int channel; - char iface[MPIPE_IFACE_NAME_LENGTH]; -} MpipePeer; - -/* per interface TAP/IPS configuration */ -typedef struct MpipePeerVars_ -{ - gxio_mpipe_equeue_t *peer_equeue; - void (*ReleasePacket)(struct Packet_ *); - int copy_mode; -} MpipePeerVars; - -/* per packet Mpipe vars */ -typedef struct MpipePacketVars_ -{ - /* TileGX mpipe stuff */ - struct { - uint_reg_t channel : 5; - uint_reg_t l2_size : 14; - uint_reg_t size : 3; - uint_reg_t bucket_id : 13; - uint_reg_t nr : 1; - uint_reg_t cs : 1; - uint_reg_t va : 42; - uint_reg_t stack_idx : 5; - } idesc; - - /* packetpool this was allocated from */ - uint8_t rank; - - gxio_mpipe_equeue_t *peer_equeue; -} MpipePacketVars; - -int MpipeLiveRegisterDevice(char *); -int MpipeLiveGetDeviceCount(void); -char *MpipeLiveGetDevice(int); -void MpipeFreePacket(void *arg); -void TmModuleReceiveMpipeRegister (void); -void TmModuleDecodeMpipeRegister (void); - -TmEcode ReceiveMpipeInit(void); - -#endif /* HAVE_MPIPE */ -#endif /* __SOURCE_MPIPE_H__ */ diff --git a/framework/src/suricata/src/source-napatech.c b/framework/src/suricata/src/source-napatech.c deleted file mode 100644 index 27432314..00000000 --- a/framework/src/suricata/src/source-napatech.c +++ /dev/null @@ -1,402 +0,0 @@ -/* Copyright (C) 2012-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author nPulse Technologies, LLC. - * \author Matt Keeler - * - * Support for NAPATECH adapter with the 3GD Driver/API. - * Requires libntapi from Napatech A/S. - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "threadvars.h" -#include "util-optimize.h" -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "tm-modules.h" - -#include "util-privs.h" -#include "tmqh-packetpool.h" - -#ifndef HAVE_NAPATECH - -TmEcode NoNapatechSupportExit(ThreadVars *, void *, void **); - - -void TmModuleNapatechStreamRegister (void) -{ - tmm_modules[TMM_RECEIVENAPATECH].name = "NapatechStream"; - tmm_modules[TMM_RECEIVENAPATECH].ThreadInit = NoNapatechSupportExit; - tmm_modules[TMM_RECEIVENAPATECH].Func = NULL; - tmm_modules[TMM_RECEIVENAPATECH].ThreadExitPrintStats = NULL; - tmm_modules[TMM_RECEIVENAPATECH].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVENAPATECH].RegisterTests = NULL; - tmm_modules[TMM_RECEIVENAPATECH].cap_flags = SC_CAP_NET_ADMIN; -} - -void TmModuleNapatechDecodeRegister (void) -{ - tmm_modules[TMM_DECODENAPATECH].name = "NapatechDecode"; - tmm_modules[TMM_DECODENAPATECH].ThreadInit = NoNapatechSupportExit; - tmm_modules[TMM_DECODENAPATECH].Func = NULL; - tmm_modules[TMM_DECODENAPATECH].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODENAPATECH].ThreadDeinit = NULL; - tmm_modules[TMM_DECODENAPATECH].RegisterTests = NULL; - tmm_modules[TMM_DECODENAPATECH].cap_flags = 0; - tmm_modules[TMM_DECODENAPATECH].flags = TM_FLAG_DECODE_TM; -} - -TmEcode NoNapatechSupportExit(ThreadVars *tv, void *initdata, void **data) -{ - SCLogError(SC_ERR_NAPATECH_NOSUPPORT, - "Error creating thread %s: you do not have support for Napatech adapter " - "enabled please recompile with --enable-napatech", tv->name); - exit(EXIT_FAILURE); -} - -#else /* Implied we do have NAPATECH support */ - -#include "source-napatech.h" -#include - -extern int max_pending_packets; - -typedef struct NapatechThreadVars_ { - ThreadVars *tv; - NtNetStreamRx_t rx_stream; - uint64_t stream_id; - int hba; - uint64_t pkts; - uint64_t drops; - uint64_t bytes; - - TmSlot *slot; -} NapatechThreadVars; - - -TmEcode NapatechStreamThreadInit(ThreadVars *, void *, void **); -void NapatechStreamThreadExitStats(ThreadVars *, void *); -TmEcode NapatechStreamLoop(ThreadVars *tv, void *data, void *slot); - -TmEcode NapatechDecodeThreadInit(ThreadVars *, void *, void **); -TmEcode NapatechDecodeThreadDeinit(ThreadVars *tv, void *data); -TmEcode NapatechDecode(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); - -/** - * \brief Register the Napatech receiver (reader) module. - */ -void TmModuleNapatechStreamRegister(void) -{ - tmm_modules[TMM_RECEIVENAPATECH].name = "NapatechStream"; - tmm_modules[TMM_RECEIVENAPATECH].ThreadInit = NapatechStreamThreadInit; - tmm_modules[TMM_RECEIVENAPATECH].Func = NULL; - tmm_modules[TMM_RECEIVENAPATECH].PktAcqLoop = NapatechStreamLoop; - tmm_modules[TMM_RECEIVENAPATECH].ThreadExitPrintStats = NapatechStreamThreadExitStats; - tmm_modules[TMM_RECEIVENAPATECH].ThreadDeinit = NapatechStreamThreadDeinit; - tmm_modules[TMM_RECEIVENAPATECH].RegisterTests = NULL; - tmm_modules[TMM_RECEIVENAPATECH].cap_flags = SC_CAP_NET_RAW; - tmm_modules[TMM_RECEIVENAPATECH].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Register the Napatech decoder module. - */ -void TmModuleNapatechDecodeRegister(void) -{ - tmm_modules[TMM_DECODENAPATECH].name = "NapatechDecode"; - tmm_modules[TMM_DECODENAPATECH].ThreadInit = NapatechDecodeThreadInit; - tmm_modules[TMM_DECODENAPATECH].Func = NapatechDecode; - tmm_modules[TMM_DECODENAPATECH].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODENAPATECH].ThreadDeinit = NapatechDecodeThreadDeinit; - tmm_modules[TMM_DECODENAPATECH].RegisterTests = NULL; - tmm_modules[TMM_DECODENAPATECH].cap_flags = 0; - tmm_modules[TMM_DECODENAPATECH].flags = TM_FLAG_DECODE_TM; -} - -/** - * \brief Initialize the Napatech receiver thread, generate a single - * NapatechThreadVar structure for each thread, this will - * contain a NtNetStreamRx_t stream handle which is used when the - * thread executes to acquire the packets. - * - * \param tv Thread variable to ThreadVars - * \param initdata Initial data to the adapter passed from the user, - * this is processed by the user. - * - * For now, we assume that we have only a single name for the NAPATECH - * adapter. - * - * \param data data pointer gets populated with - * - */ -TmEcode NapatechStreamThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - struct NapatechStreamDevConf *conf = (struct NapatechStreamDevConf *)initdata; - uintmax_t stream_id = conf->stream_id; - *data = NULL; - - SCLogInfo("Napatech Thread Stream ID:%lu", stream_id); - - NapatechThreadVars *ntv = SCMalloc(sizeof(NapatechThreadVars)); - if (unlikely(ntv == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for NAPATECH thread vars."); - exit(EXIT_FAILURE); - } - - memset(ntv, 0, sizeof (NapatechThreadVars)); - ntv->stream_id = stream_id; - ntv->tv = tv; - ntv->hba = conf->hba; - - SCLogInfo("Started processing packets from NAPATECH Stream: %lu", ntv->stream_id); - - *data = (void *)ntv; - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Main Napatech reading Loop function - */ -TmEcode NapatechStreamLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - int32_t status; - char errbuf[100]; - uint64_t pkt_ts; - NtNetBuf_t packet_buffer; - NapatechThreadVars *ntv = (NapatechThreadVars *)data; - NtNetRx_t stat_cmd; - - SCLogInfo("Opening NAPATECH Stream: %lu for processing", ntv->stream_id); - - if ((status = NT_NetRxOpen(&(ntv->rx_stream), "SuricataStream", NT_NET_INTERFACE_PACKET, ntv->stream_id, ntv->hba)) != NT_SUCCESS) { - NT_ExplainError(status, errbuf, sizeof(errbuf)); - SCLogError(SC_ERR_NAPATECH_OPEN_FAILED, "Failed to open NAPATECH Stream: %lu - %s", ntv->stream_id, errbuf); - SCFree(ntv); - SCReturnInt(TM_ECODE_FAILED); - } - - stat_cmd.cmd = NT_NETRX_READ_CMD_STREAM_DROP; - - SCLogInfo("Napatech Packet Stream Loop Started for Stream ID: %lu", ntv->stream_id); - - TmSlot *s = (TmSlot *)slot; - ntv->slot = s->slot_next; - - while (!(suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL))) { - /* make sure we have at least one packet in the packet pool, to prevent - * us from alloc'ing packets at line rate */ - PacketPoolWait(); - - /* - * Napatech returns packets 1 at a time - */ - status = NT_NetRxGet(ntv->rx_stream, &packet_buffer, 1000); - if (unlikely(status == NT_STATUS_TIMEOUT || status == NT_STATUS_TRYAGAIN)) { - /* - * no frames currently available - */ - continue; - } else if (unlikely(status != NT_SUCCESS)) { - SCLogError(SC_ERR_NAPATECH_STREAM_NEXT_FAILED, - "Failed to read from Napatech Stream: %lu", - ntv->stream_id); - SCReturnInt(TM_ECODE_FAILED); - } - - Packet *p = PacketGetFromQueueOrAlloc(); - if (unlikely(p == NULL)) { - NT_NetRxRelease(ntv->rx_stream, packet_buffer); - SCReturnInt(TM_ECODE_FAILED); - } - - pkt_ts = NT_NET_GET_PKT_TIMESTAMP(packet_buffer); - - /* - * Handle the different timestamp forms that the napatech cards could use - * - NT_TIMESTAMP_TYPE_NATIVE is not supported due to having an base of 0 as opposed to NATIVE_UNIX which has a base of 1/1/1970 - */ - switch(NT_NET_GET_PKT_TIMESTAMP_TYPE(packet_buffer)) { - case NT_TIMESTAMP_TYPE_NATIVE_UNIX: - p->ts.tv_sec = pkt_ts / 100000000; - p->ts.tv_usec = ((pkt_ts % 100000000) / 100) + (pkt_ts % 100) > 50 ? 1 : 0; - break; - case NT_TIMESTAMP_TYPE_PCAP: - p->ts.tv_sec = pkt_ts >> 32; - p->ts.tv_usec = pkt_ts & 0xFFFFFFFF; - break; - case NT_TIMESTAMP_TYPE_PCAP_NANOTIME: - p->ts.tv_sec = pkt_ts >> 32; - p->ts.tv_usec = ((pkt_ts & 0xFFFFFFFF) / 1000) + (pkt_ts % 1000) > 500 ? 1 : 0; - break; - case NT_TIMESTAMP_TYPE_NATIVE_NDIS: - /* number of seconds between 1/1/1601 and 1/1/1970 */ - p->ts.tv_sec = (pkt_ts / 100000000) - 11644473600; - p->ts.tv_usec = ((pkt_ts % 100000000) / 100) + (pkt_ts % 100) > 50 ? 1 : 0; - break; - default: - SCLogError(SC_ERR_NAPATECH_TIMESTAMP_TYPE_NOT_SUPPORTED, - "Packet from Napatech Stream: %lu does not have a supported timestamp format", - ntv->stream_id); - NT_NetRxRelease(ntv->rx_stream, packet_buffer); - SCReturnInt(TM_ECODE_FAILED); - } - - SCLogDebug("p->ts.tv_sec %"PRIuMAX"", (uintmax_t)p->ts.tv_sec); - p->datalink = LINKTYPE_ETHERNET; - - ntv->pkts++; - ntv->bytes += NT_NET_GET_PKT_WIRE_LENGTH(packet_buffer); - - // Update drop counter - if (unlikely((status = NT_NetRxRead(ntv->rx_stream, &stat_cmd)) != NT_SUCCESS)) - { - NT_ExplainError(status, errbuf, sizeof(errbuf)); - SCLogWarning(SC_ERR_NAPATECH_STAT_DROPS_FAILED, "Couldn't retrieve drop statistics from the RX stream: %lu - %s", ntv->stream_id, errbuf); - } - else - { - ntv->drops += stat_cmd.u.streamDrop.pktsDropped; - } - - if (unlikely(PacketCopyData(p, (uint8_t *)NT_NET_GET_PKT_L2_PTR(packet_buffer), NT_NET_GET_PKT_WIRE_LENGTH(packet_buffer)))) { - TmqhOutputPacketpool(ntv->tv, p); - NT_NetRxRelease(ntv->rx_stream, packet_buffer); - SCReturnInt(TM_ECODE_FAILED); - } - - if (unlikely(TmThreadsSlotProcessPkt(ntv->tv, ntv->slot, p) != TM_ECODE_OK)) { - TmqhOutputPacketpool(ntv->tv, p); - NT_NetRxRelease(ntv->rx_stream, packet_buffer); - SCReturnInt(TM_ECODE_FAILED); - } - - NT_NetRxRelease(ntv->rx_stream, packet_buffer); - StatsSyncCountersIfSignalled(tv); - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Print some stats to the log at program exit. - * - * \param tv Pointer to ThreadVars. - * \param data Pointer to data, ErfFileThreadVars. - */ -void NapatechStreamThreadExitStats(ThreadVars *tv, void *data) -{ - NapatechThreadVars *ntv = (NapatechThreadVars *)data; - double percent = 0; - if (ntv->drops > 0) - percent = (((double) ntv->drops) / (ntv->pkts+ntv->drops)) * 100; - - SCLogNotice("Stream: %lu; Packets: %"PRIu64"; Drops: %"PRIu64" (%5.2f%%); Bytes: %"PRIu64, ntv->stream_id, ntv->pkts, ntv->drops, percent, ntv->bytes); -} - -/** - * \brief Deinitializes the NAPATECH card. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PcapThreadVars for ptv - */ -TmEcode NapatechStreamThreadDeinit(ThreadVars *tv, void *data) -{ - SCEnter(); - NapatechThreadVars *ntv = (NapatechThreadVars *)data; - SCLogDebug("Closing Napatech Stream: %d", ntv->stream_id); - NT_NetRxClose(ntv->rx_stream); - SCReturnInt(TM_ECODE_OK); -} - - -/** Decode Napatech */ - -/** - * \brief This function passes off to link type decoders. - * - * NapatechDecode reads packets from the PacketQueue and passes - * them off to the proper link type decoder. - * - * \param t pointer to ThreadVars - * \param p pointer to the current packet - * \param data pointer that gets cast into PcapThreadVars for ptv - * \param pq pointer to the current PacketQueue - */ -TmEcode NapatechDecode(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, - PacketQueue *postpq) -{ - SCEnter(); - - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - switch (p->datalink) { - case LINKTYPE_ETHERNET: - DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - default: - SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, - "Error: datalink type %" PRId32 " not yet supported in module NapatechDecode", - p->datalink); - break; - } - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode NapatechDecodeThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - DecodeThreadVars *dtv = NULL; - - dtv = DecodeThreadVarsAlloc(tv); - - if(dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode NapatechDecodeThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -#endif /* HAVE_NAPATECH */ diff --git a/framework/src/suricata/src/source-napatech.h b/framework/src/suricata/src/source-napatech.h deleted file mode 100644 index eee79dc7..00000000 --- a/framework/src/suricata/src/source-napatech.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author nPulse Technologies, LLC - * \author Matt Keeler - */ - -#ifndef __SOURCE_NAPATECH_H__ -#define __SOURCE_NAPATECH_H__ - -void TmModuleNapatechStreamRegister (void); -TmEcode NapatechStreamThreadDeinit(ThreadVars *tv, void *data); -void TmModuleNapatechDecodeRegister (void); - -struct NapatechStreamDevConf -{ - int stream_id; - intmax_t hba; -}; - -#ifdef HAVE_NAPATECH - -#include - -#endif - -#endif /* __SOURCE_NAPATECH_H__ */ diff --git a/framework/src/suricata/src/source-netmap.c b/framework/src/suricata/src/source-netmap.c deleted file mode 100644 index 73930118..00000000 --- a/framework/src/suricata/src/source-netmap.c +++ /dev/null @@ -1,1098 +0,0 @@ -/* Copyright (C) 2011-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** -* \defgroup netmap Netmap running mode -* -* @{ -*/ - -/** -* \file -* -* \author Aleksey Katargin -* -* Netmap socket acquisition support -* -*/ - -#include "suricata-common.h" -#include "config.h" -#include "suricata.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "tm-modules.h" -#include "tm-threads.h" -#include "tm-threads-common.h" -#include "conf.h" -#include "util-debug.h" -#include "util-device.h" -#include "util-error.h" -#include "util-privs.h" -#include "util-optimize.h" -#include "util-checksum.h" -#include "util-ioctl.h" -#include "util-host-info.h" -#include "tmqh-packetpool.h" -#include "source-netmap.h" -#include "runmodes.h" - -#ifdef __SC_CUDA_SUPPORT__ - -#include "util-cuda.h" -#include "util-cuda-buffer.h" -#include "util-mpm-ac.h" -#include "util-cuda-handlers.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "util-cuda-vars.h" - -#endif /* __SC_CUDA_SUPPORT__ */ - -#ifdef HAVE_NETMAP - -#if HAVE_SYS_IOCTL_H -#include -#endif - -#if HAVE_SYS_MMAN_H -#include -#endif - -#include - -#endif /* HAVE_NETMAP */ - -extern int max_pending_packets; - -#ifndef HAVE_NETMAP - -TmEcode NoNetmapSupportExit(ThreadVars *, void *, void **); - -void TmModuleReceiveNetmapRegister (void) -{ - tmm_modules[TMM_RECEIVENETMAP].name = "ReceiveNetmap"; - tmm_modules[TMM_RECEIVENETMAP].ThreadInit = NoNetmapSupportExit; - tmm_modules[TMM_RECEIVENETMAP].Func = NULL; - tmm_modules[TMM_RECEIVENETMAP].ThreadExitPrintStats = NULL; - tmm_modules[TMM_RECEIVENETMAP].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVENETMAP].RegisterTests = NULL; - tmm_modules[TMM_RECEIVENETMAP].cap_flags = 0; - tmm_modules[TMM_RECEIVENETMAP].flags = TM_FLAG_RECEIVE_TM; -} - -/** -* \brief Registration Function for DecodeNetmap. -* \todo Unit tests are needed for this module. -*/ -void TmModuleDecodeNetmapRegister (void) -{ - tmm_modules[TMM_DECODENETMAP].name = "DecodeNetmap"; - tmm_modules[TMM_DECODENETMAP].ThreadInit = NoNetmapSupportExit; - tmm_modules[TMM_DECODENETMAP].Func = NULL; - tmm_modules[TMM_DECODENETMAP].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODENETMAP].ThreadDeinit = NULL; - tmm_modules[TMM_DECODENETMAP].RegisterTests = NULL; - tmm_modules[TMM_DECODENETMAP].cap_flags = 0; - tmm_modules[TMM_DECODENETMAP].flags = TM_FLAG_DECODE_TM; -} - -/** -* \brief this function prints an error message and exits. -*/ -TmEcode NoNetmapSupportExit(ThreadVars *tv, void *initdata, void **data) -{ - SCLogError(SC_ERR_NO_NETMAP,"Error creating thread %s: you do not have " - "support for netmap enabled, please recompile " - "with --enable-netmap", tv->name); - exit(EXIT_FAILURE); -} - -#else /* We have NETMAP support */ - -#define max(a, b) (((a) > (b)) ? (a) : (b)) - -#define POLL_TIMEOUT 100 - -#if defined(__linux__) -#define POLL_EVENTS (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL) -#else -#define POLL_EVENTS (POLLHUP|POLLERR|POLLNVAL) -#endif - -enum { - NETMAP_OK, - NETMAP_FAILURE, -}; - -enum { - NETMAP_FLAG_ZERO_COPY = 1, -}; - -/** - * \brief Netmap ring isntance. - */ -typedef struct NetmapRing -{ - int fd; - struct netmap_ring *rx; - struct netmap_ring *tx; - int dst_ring_from; - int dst_ring_to; - int dst_next_ring; - SCSpinlock tx_lock; -} NetmapRing; - -/** - * \brief Netmap device instance. - */ -typedef struct NetmapDevice_ -{ - char ifname[IFNAMSIZ]; - void *mem; - size_t memsize; - struct netmap_if *nif; - int rings_cnt; - int rx_rings_cnt; - int tx_rings_cnt; - /* hw rings + sw ring */ - NetmapRing *rings; - unsigned int ref; - SC_ATOMIC_DECLARE(unsigned int, threads_run); - TAILQ_ENTRY(NetmapDevice_) next; -} NetmapDevice; - -/** - * \brief Module thread local variables. - */ -typedef struct NetmapThreadVars_ -{ - /* receive inteface */ - NetmapDevice *ifsrc; - /* dst interface for IPS mode */ - NetmapDevice *ifdst; - - int src_ring_from; - int src_ring_to; - int thread_idx; - int flags; - struct bpf_program bpf_prog; - - /* internal shit */ - TmSlot *slot; - ThreadVars *tv; - LiveDevice *livedev; - - /* copy from config */ - int copy_mode; - ChecksumValidationMode checksum_mode; - - /* counters */ - uint64_t pkts; - uint64_t bytes; - uint64_t drops; - uint16_t capture_kernel_packets; - uint16_t capture_kernel_drops; - - -} NetmapThreadVars; - -typedef TAILQ_HEAD(NetmapDeviceList_, NetmapDevice_) NetmapDeviceList; - -static NetmapDeviceList netmap_devlist = TAILQ_HEAD_INITIALIZER(netmap_devlist); -static SCMutex netmap_devlist_lock = SCMUTEX_INITIALIZER; - -/** - * \brief Get interface flags. - * \param fd Network susbystem file descritor. - * \param ifname Inteface name. - * \return Interface flags or -1 on error - */ -static int NetmapGetIfaceFlags(int fd, const char *ifname) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - - if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Unable to get flags for iface \"%s\": %s", - ifname, strerror(errno)); - return -1; - } - -#ifdef OS_FREEBSD - int flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); - return flags; -#else - return ifr.ifr_flags; -#endif -} - -/** - * \brief Set interface flags. - * \param fd Network susbystem file descritor. - * \param ifname Inteface name. - * \param flags Flags to set. - * \return Zero on success. - */ -static int NetmapSetIfaceFlags(int fd, const char *ifname, int flags) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); -#ifdef OS_FREEBSD - ifr.ifr_flags = flags & 0xffff; - ifr.ifr_flagshigh = flags >> 16; -#else - ifr.ifr_flags = flags; -#endif - - if (ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Unable to set flags for iface \"%s\": %s", - ifname, strerror(errno)); - return -1; - } - - return 0; -} - -/** - * \brief Open interface in netmap mode. - * \param ifname Interface name. - * \param promisc Enable promiscuous mode. - * \param dev Pointer to requested netmap device instance. - * \param verbose Verbose error logging. - * \return Zero on success. - */ -static int NetmapOpen(char *ifname, int promisc, NetmapDevice **pdevice, int verbose) -{ - NetmapDevice *pdev = NULL; - struct nmreq nm_req; - - *pdevice = NULL; - - SCMutexLock(&netmap_devlist_lock); - - /* search interface in our already opened list */ - TAILQ_FOREACH(pdev, &netmap_devlist, next) { - if (strcmp(ifname, pdev->ifname) == 0) { - *pdevice = pdev; - pdev->ref++; - SCMutexUnlock(&netmap_devlist_lock); - return 0; - } - } - - /* not found, create new record */ - pdev = SCMalloc(sizeof(*pdev)); - if (unlikely(pdev == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed"); - goto error; - } - - memset(pdev, 0, sizeof(*pdev)); - SC_ATOMIC_INIT(pdev->threads_run); - strlcpy(pdev->ifname, ifname, sizeof(pdev->ifname)); - - /* open netmap */ - int fd = open("/dev/netmap", O_RDWR); - if (fd == -1) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Couldn't open netmap device, error %s", - strerror(errno)); - goto error_pdev; - } - - /* check interface is up */ - int if_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (if_fd < 0) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Couldn't create control socket for '%s' interface", - ifname); - goto error_fd; - } - int if_flags = NetmapGetIfaceFlags(if_fd, ifname); - if (if_flags == -1) { - if (verbose) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Can not access to interface '%s'", - ifname); - } - close(if_fd); - goto error_fd; - } - if ((if_flags & IFF_UP) == 0) { - if (verbose) { - SCLogError(SC_ERR_NETMAP_CREATE, "Interface '%s' is down", ifname); - } - close(if_fd); - goto error_fd; - } - if (promisc) { - if_flags |= IFF_PROMISC; - NetmapSetIfaceFlags(if_fd, ifname, if_flags); - } - close(if_fd); - - /* query netmap info */ - memset(&nm_req, 0, sizeof(nm_req)); - strlcpy(nm_req.nr_name, ifname, sizeof(nm_req.nr_name)); - nm_req.nr_version = NETMAP_API; - - if (ioctl(fd, NIOCGINFO, &nm_req) != 0) { - if (verbose) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Couldn't query netmap for %s, error %s", - ifname, strerror(errno)); - } - goto error_fd; - }; - - pdev->memsize = nm_req.nr_memsize; - pdev->rx_rings_cnt = nm_req.nr_rx_rings; - pdev->tx_rings_cnt = nm_req.nr_tx_rings; - pdev->rings_cnt = max(pdev->rx_rings_cnt, pdev->tx_rings_cnt); - - /* hw rings + sw ring */ - pdev->rings = SCMalloc(sizeof(*pdev->rings) * (pdev->rings_cnt + 1)); - if (unlikely(pdev->rings == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed"); - goto error_fd; - } - memset(pdev->rings, 0, sizeof(*pdev->rings) * (pdev->rings_cnt + 1)); - - /* open individual instance for each ring */ - int success_cnt = 0; - for (int i = 0; i <= pdev->rings_cnt; i++) { - NetmapRing *pring = &pdev->rings[i]; - pring->fd = open("/dev/netmap", O_RDWR); - if (pring->fd == -1) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Couldn't open netmap device: %s", - strerror(errno)); - break; - } - - if (i < pdev->rings_cnt) { - nm_req.nr_flags = NR_REG_ONE_NIC; - nm_req.nr_ringid = i | NETMAP_NO_TX_POLL; - } else { - nm_req.nr_flags = NR_REG_SW; - nm_req.nr_ringid = NETMAP_NO_TX_POLL; - } - if (ioctl(pring->fd, NIOCREGIF, &nm_req) != 0) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Couldn't register %s with netmap: %s", - ifname, strerror(errno)); - break; - } - - if (pdev->mem == NULL) { - pdev->mem = mmap(0, pdev->memsize, PROT_WRITE | PROT_READ, - MAP_SHARED, pring->fd, 0); - if (pdev->mem == MAP_FAILED) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Couldn't mmap netmap device: %s", - strerror(errno)); - break; - } - pdev->nif = NETMAP_IF(pdev->mem, nm_req.nr_offset); - } - - if ((i < pdev->rx_rings_cnt) || (i == pdev->rings_cnt)) { - pring->rx = NETMAP_RXRING(pdev->nif, i); - } - if ((i < pdev->tx_rings_cnt) || (i == pdev->rings_cnt)) { - pring->tx = NETMAP_TXRING(pdev->nif, i); - } - SCSpinInit(&pring->tx_lock, 0); - success_cnt++; - } - - if (success_cnt != (pdev->rings_cnt + 1)) { - for(int i = 0; i < success_cnt; i++) { - close(pdev->rings[i].fd); - } - if (pdev->mem) { - munmap(pdev->mem, pdev->memsize); - } - SCFree(pdev->rings); - goto error_fd; - } - - close(fd); - *pdevice = pdev; - - TAILQ_INSERT_TAIL(&netmap_devlist, pdev, next); - SCMutexUnlock(&netmap_devlist_lock); - - return 0; - -error_fd: - close(fd); -error_pdev: - SCFree(pdev); -error: - SCMutexUnlock(&netmap_devlist_lock); - return -1; -} - -/** - * \brief Close or dereference netmap device instance. - * \param pdev Netmap device instance. - * \return Zero on success. - */ -static int NetmapClose(NetmapDevice *dev) -{ - NetmapDevice *pdev, *tmp; - - SCMutexLock(&netmap_devlist_lock); - - TAILQ_FOREACH_SAFE(pdev, &netmap_devlist, next, tmp) { - if (pdev == dev) { - pdev->ref--; - if (!pdev->ref) { - munmap(pdev->mem, pdev->memsize); - for (int i = 0; i <= pdev->rings_cnt; i++) { - NetmapRing *pring = &pdev->rings[i]; - close(pring->fd); - SCSpinDestroy(&pring->tx_lock); - } - SCFree(pdev->rings); - TAILQ_REMOVE(&netmap_devlist, pdev, next); - SCFree(pdev); - } - SCMutexUnlock(&netmap_devlist_lock); - return 0; - } - } - - SCMutexUnlock(&netmap_devlist_lock); - return -1; -} - -/** - * \brief PcapDumpCounters - * \param ntv - */ -static inline void NetmapDumpCounters(NetmapThreadVars *ntv) -{ - StatsAddUI64(ntv->tv, ntv->capture_kernel_packets, ntv->pkts); - StatsAddUI64(ntv->tv, ntv->capture_kernel_drops, ntv->drops); - (void) SC_ATOMIC_ADD(ntv->livedev->drop, ntv->drops); - (void) SC_ATOMIC_ADD(ntv->livedev->pkts, ntv->pkts); - ntv->drops = 0; - ntv->pkts = 0; -} - -/** - * \brief Init function for ReceiveNetmap. - * \param tv pointer to ThreadVars - * \param initdata pointer to the interface passed from the user - * \param data pointer gets populated with NetmapThreadVars - */ -static TmEcode ReceiveNetmapThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - NetmapIfaceConfig *aconf = initdata; - - if (initdata == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - NetmapThreadVars *ntv = SCMalloc(sizeof(*ntv)); - if (unlikely(ntv == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed"); - goto error; - } - memset(ntv, 0, sizeof(*ntv)); - - ntv->tv = tv; - ntv->checksum_mode = aconf->checksum_mode; - ntv->copy_mode = aconf->copy_mode; - - ntv->livedev = LiveGetDevice(aconf->iface_name); - if (ntv->livedev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); - goto error_ntv; - } - - if (NetmapOpen(aconf->iface, aconf->promisc, &ntv->ifsrc, 1) != 0) { - goto error_ntv; - } - - if (unlikely(!aconf->iface_sw && !ntv->ifsrc->rx_rings_cnt)) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Input interface '%s' does not have Rx rings", - aconf->iface_name); - goto error_src; - } - - if (unlikely(aconf->iface_sw && aconf->threads > 1)) { - SCLogError(SC_ERR_INVALID_VALUE, - "Interface '%s+'. " - "Thread count can't be greater than 1 for SW ring.", - aconf->iface_name); - goto error_src; - } else if (unlikely(aconf->threads > ntv->ifsrc->rx_rings_cnt)) { - SCLogError(SC_ERR_INVALID_VALUE, - "Thread count can't be greater than Rx ring count. " - "Configured %d threads for interface '%s' with %d Rx rings.", - aconf->threads, aconf->iface_name, ntv->ifsrc->rx_rings_cnt); - goto error_src; - } - - if (aconf->iface_sw) { - ntv->thread_idx = 0; - } else { - do { - ntv->thread_idx = SC_ATOMIC_GET(ntv->ifsrc->threads_run); - } while (SC_ATOMIC_CAS(&ntv->ifsrc->threads_run, ntv->thread_idx, ntv->thread_idx + 1) == 0); - } - - /* calculate thread rings binding */ - if (aconf->iface_sw) { - ntv->src_ring_from = ntv->src_ring_to = ntv->ifsrc->rings_cnt; - } else { - int tmp = (ntv->ifsrc->rx_rings_cnt + 1) / aconf->threads; - ntv->src_ring_from = ntv->thread_idx * tmp; - ntv->src_ring_to = ntv->src_ring_from + tmp - 1; - if (ntv->thread_idx == (aconf->threads - 1)) { - ntv->src_ring_to = ntv->ifsrc->rx_rings_cnt - 1; - } - } - SCLogDebug("netmap: %s thread:%d rings:%d-%d", aconf->iface_name, - ntv->thread_idx, ntv->src_ring_from, ntv->src_ring_to); - - if (aconf->copy_mode != NETMAP_COPY_MODE_NONE) { - if (NetmapOpen(aconf->out_iface, 0, &ntv->ifdst, 1) != 0) { - goto error_src; - } - - if (unlikely(!aconf->out_iface_sw && !ntv->ifdst->tx_rings_cnt)) { - SCLogError(SC_ERR_NETMAP_CREATE, - "Output interface '%s' does not have Tx rings", - aconf->out_iface_name); - goto error_dst; - } - - /* calculate dst rings bindings */ - for (int i = ntv->src_ring_from; i <= ntv->src_ring_to; i++) { - NetmapRing *ring = &ntv->ifsrc->rings[i]; - if (aconf->out_iface_sw) { - ring->dst_ring_from = ring->dst_ring_to = ntv->ifdst->rings_cnt; - } else if (ntv->ifdst->tx_rings_cnt > ntv->ifsrc->rx_rings_cnt) { - int tmp = (ntv->ifdst->tx_rings_cnt + 1) / ntv->ifsrc->rx_rings_cnt; - ring->dst_ring_from = i * tmp; - ring->dst_ring_to = ring->dst_ring_from + tmp - 1; - if (i == (ntv->src_ring_to - 1)) { - ring->dst_ring_to = ntv->ifdst->tx_rings_cnt - 1; - } - } else { - ring->dst_ring_from = ring->dst_ring_to = - i % ntv->ifdst->tx_rings_cnt; - } - ring->dst_next_ring = ring->dst_ring_from; - - SCLogDebug("netmap: %s(%d)->%s(%d-%d)", - aconf->iface_name, i, aconf->out_iface_name, - ring->dst_ring_from, ring->dst_ring_to); - } - } - - /* basic counters */ - ntv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", - ntv->tv); - ntv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops", - ntv->tv); - - /* enable zero-copy mode for workers runmode */ - char const *active_runmode = RunmodeGetActive(); - if ((aconf->copy_mode != NETMAP_COPY_MODE_NONE) && active_runmode - && !strcmp("workers", active_runmode)) { - if (likely(ntv->ifsrc->mem == ntv->ifdst->mem)) { - ntv->flags |= NETMAP_FLAG_ZERO_COPY; - SCLogInfo("Enabling zero copy mode for %s->%s", - aconf->iface_name, aconf->out_iface_name); - } else { - SCLogInfo("Unable to set zero copy mode for %s->%s", - aconf->iface_name, aconf->out_iface_name); - } - } - - if (aconf->bpf_filter) { - SCLogInfo("Using BPF '%s' on iface '%s'", - aconf->bpf_filter, ntv->ifsrc->ifname); - if (pcap_compile_nopcap(default_packet_size, /* snaplen_arg */ - LINKTYPE_ETHERNET, /* linktype_arg */ - &ntv->bpf_prog, /* program */ - aconf->bpf_filter, /* const char *buf */ - 1, /* optimize */ - PCAP_NETMASK_UNKNOWN /* mask */ - ) == -1) { - SCLogError(SC_ERR_NETMAP_CREATE, "Filter compilation failed."); - goto error_dst; - } - } - - if (GetIfaceOffloading(aconf->iface) == 1) { - SCLogWarning(SC_ERR_NETMAP_CREATE, - "Using mmap mode with GRO or LRO activated can lead to capture problems"); - } - - *data = (void *)ntv; - aconf->DerefFunc(aconf); - SCReturnInt(TM_ECODE_OK); - -error_dst: - if (aconf->copy_mode != NETMAP_COPY_MODE_NONE) { - NetmapClose(ntv->ifdst); - } -error_src: - NetmapClose(ntv->ifsrc); -error_ntv: - SCFree(ntv); -error: - aconf->DerefFunc(aconf); - SCReturnInt(TM_ECODE_FAILED); -} - -/** - * \brief Output packet to destination interface or drop. - * \param ntv Thread local variables. - * \param p Source packet. - */ -static TmEcode NetmapWritePacket(NetmapThreadVars *ntv, Packet *p) -{ - if (ntv->copy_mode == NETMAP_COPY_MODE_IPS) { - if (PACKET_TEST_ACTION(p, ACTION_DROP)) { - return TM_ECODE_OK; - } - } - - /* map src ring_id to dst ring_id */ - NetmapRing *rxring = &ntv->ifsrc->rings[p->netmap_v.ring_id]; - NetmapRing *txring = &ntv->ifdst->rings[p->netmap_v.dst_ring_id]; - - SCSpinLock(&txring->tx_lock); - - if (!nm_ring_space(txring->tx)) { - ntv->drops++; - SCSpinUnlock(&txring->tx_lock); - return TM_ECODE_FAILED; - } - - struct netmap_slot *ts = &txring->tx->slot[txring->tx->cur]; - - if (ntv->flags & NETMAP_FLAG_ZERO_COPY) { - struct netmap_slot *rs = &rxring->rx->slot[p->netmap_v.slot_id]; - - /* swap slot buffers */ - uint32_t tmp_idx; - tmp_idx = ts->buf_idx; - ts->buf_idx = rs->buf_idx; - rs->buf_idx = tmp_idx; - - ts->len = rs->len; - - ts->flags |= NS_BUF_CHANGED; - rs->flags |= NS_BUF_CHANGED; - } else { - unsigned char *slot_data = (unsigned char *)NETMAP_BUF(txring->tx, ts->buf_idx); - memcpy(slot_data, GET_PKT_DATA(p), GET_PKT_LEN(p)); - ts->len = GET_PKT_LEN(p); - ts->flags |= NS_BUF_CHANGED; - } - - txring->tx->head = txring->tx->cur = nm_ring_next(txring->tx, txring->tx->cur); - if ((ntv->flags & NETMAP_FLAG_ZERO_COPY) == 0) { - ioctl(txring->fd, NIOCTXSYNC, 0); - } - - SCSpinUnlock(&txring->tx_lock); - - return TM_ECODE_OK; -} - -/** - * \brief Packet release routine. - * \param p Packet. - */ -static void NetmapReleasePacket(Packet *p) -{ - NetmapThreadVars *ntv = (NetmapThreadVars *)p->netmap_v.ntv; - - /* Need to be in copy mode and need to detect early release - where Ethernet header could not be set (and pseudo packet) */ - if ((ntv->copy_mode != NETMAP_COPY_MODE_NONE) && !PKT_IS_PSEUDOPKT(p)) { - NetmapWritePacket(ntv, p); - } - - PacketFreeOrRelease(p); -} - -/** - * \brief Read packets from ring and pass them further. - * \param ntv Thread local variables. - * \param ring_id Ring id to read. - */ -static int NetmapRingRead(NetmapThreadVars *ntv, int ring_id) -{ - SCEnter(); - - NetmapRing *ring = &ntv->ifsrc->rings[ring_id]; - struct netmap_ring *rx = ring->rx; - uint32_t avail = nm_ring_space(rx); - uint32_t cur = rx->cur; - - while (likely(avail-- > 0)) { - struct netmap_slot *slot = &rx->slot[cur]; - unsigned char *slot_data = (unsigned char *)NETMAP_BUF(rx, slot->buf_idx); - - if (ntv->bpf_prog.bf_len) { - struct pcap_pkthdr pkthdr = { {0, 0}, slot->len, slot->len }; - if (pcap_offline_filter(&ntv->bpf_prog, &pkthdr, slot_data) == 0) { - /* rejected by bpf */ - cur = nm_ring_next(rx, cur); - continue; - } - } - - Packet *p = PacketGetFromQueueOrAlloc(); - if (unlikely(p == NULL)) { - SCReturnInt(NETMAP_FAILURE); - } - - PKT_SET_SRC(p, PKT_SRC_WIRE); - p->livedev = ntv->livedev; - p->datalink = LINKTYPE_ETHERNET; - p->ts = rx->ts; - ntv->pkts++; - ntv->bytes += slot->len; - - /* checksum validation */ - if (ntv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) { - p->flags |= PKT_IGNORE_CHECKSUM; - } else if (ntv->checksum_mode == CHECKSUM_VALIDATION_AUTO) { - if (ntv->livedev->ignore_checksum) { - p->flags |= PKT_IGNORE_CHECKSUM; - } else if (ChecksumAutoModeCheck(ntv->pkts, - SC_ATOMIC_GET(ntv->livedev->pkts), - SC_ATOMIC_GET(ntv->livedev->invalid_checksums))) { - ntv->livedev->ignore_checksum = 1; - p->flags |= PKT_IGNORE_CHECKSUM; - } - } - - if (ntv->flags & NETMAP_FLAG_ZERO_COPY) { - if (PacketSetData(p, slot_data, slot->len) == -1) { - TmqhOutputPacketpool(ntv->tv, p); - SCReturnInt(NETMAP_FAILURE); - } - } else { - if (PacketCopyData(p, slot_data, slot->len) == -1) { - TmqhOutputPacketpool(ntv->tv, p); - SCReturnInt(NETMAP_FAILURE); - } - } - - p->ReleasePacket = NetmapReleasePacket; - p->netmap_v.ring_id = ring_id; - p->netmap_v.slot_id = cur; - p->netmap_v.dst_ring_id = ring->dst_next_ring; - p->netmap_v.ntv = ntv; - - if (ring->dst_ring_from != ring->dst_ring_to) { - ring->dst_next_ring++; - if (ring->dst_next_ring == ring->dst_ring_to) { - ring->dst_next_ring = ring->dst_ring_from; - } - } - - SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)", - GET_PKT_LEN(p), p, GET_PKT_DATA(p)); - - if (TmThreadsSlotProcessPkt(ntv->tv, ntv->slot, p) != TM_ECODE_OK) { - TmqhOutputPacketpool(ntv->tv, p); - SCReturnInt(NETMAP_FAILURE); - } - - cur = nm_ring_next(rx, cur); - } - rx->head = rx->cur = cur; - - SCReturnInt(NETMAP_OK); -} - -/** - * \brief Main netmap reading loop function - */ -static TmEcode ReceiveNetmapLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - TmSlot *s = (TmSlot *)slot; - NetmapThreadVars *ntv = (NetmapThreadVars *)data; - struct pollfd *fds; - int rings_count = ntv->src_ring_to - ntv->src_ring_from + 1; - - ntv->slot = s->slot_next; - - fds = SCMalloc(sizeof(*fds) * rings_count); - if (unlikely(fds == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed"); - SCReturnInt(TM_ECODE_FAILED); - } - - for (int i = 0; i < rings_count; i++) { - fds[i].fd = ntv->ifsrc->rings[ntv->src_ring_from + i].fd; - fds[i].events = POLLIN; - } - - for(;;) { - if (suricata_ctl_flags != 0) { - break; - } - - /* make sure we have at least one packet in the packet pool, - * to prevent us from alloc'ing packets at line rate */ - PacketPoolWait(); - - int r = poll(fds, rings_count, POLL_TIMEOUT); - - if (r < 0) { - /* error */ - if(errno != EINTR) - SCLogError(SC_ERR_NETMAP_READ, - "Error polling netmap from iface '%s': (%d" PRIu32 ") %s", - ntv->ifsrc->ifname, errno, strerror(errno)); - continue; - } else if (r == 0) { - /* no events, timeout */ - SCLogDebug("(%s:%d-%d) Poll timeout", ntv->ifsrc->ifname, - ntv->src_ring_from, ntv->src_ring_to); - continue; - } - - for (int i = 0; i < rings_count; i++) { - if (fds[i].revents & POLL_EVENTS) { - if (fds[i].revents & POLLERR) { - SCLogError(SC_ERR_NETMAP_READ, - "Error reading data from iface '%s': (%d" PRIu32 ") %s", - ntv->ifsrc->ifname, errno, strerror(errno)); - } else if (fds[i].revents & POLLNVAL) { - SCLogError(SC_ERR_NETMAP_READ, - "Invalid polling request"); - } - continue; - } - - if (likely(fds[i].revents & POLLIN)) { - int src_ring_id = ntv->src_ring_from + i; - NetmapRingRead(ntv, src_ring_id); - - if ((ntv->copy_mode != NETMAP_COPY_MODE_NONE) && - (ntv->flags & NETMAP_FLAG_ZERO_COPY)) { - - NetmapRing *src_ring = &ntv->ifsrc->rings[src_ring_id]; - - /* sync dst tx rings */ - for (int j = src_ring->dst_ring_from; j <= src_ring->dst_ring_to; j++) { - NetmapRing *dst_ring = &ntv->ifdst->rings[j]; - /* if locked, another loop already do sync */ - if (SCSpinTrylock(&dst_ring->tx_lock) == 0) { - ioctl(dst_ring->fd, NIOCTXSYNC, 0); - SCSpinUnlock(&dst_ring->tx_lock); - } - } - } - } - } - - NetmapDumpCounters(ntv); - StatsSyncCountersIfSignalled(tv); - } - - SCFree(fds); - StatsSyncCountersIfSignalled(tv); - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function prints stats to the screen at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into NetmapThreadVars for ntv - */ -static void ReceiveNetmapThreadExitStats(ThreadVars *tv, void *data) -{ - SCEnter(); - NetmapThreadVars *ntv = (NetmapThreadVars *)data; - - NetmapDumpCounters(ntv); - SCLogInfo("(%s) Kernel: Packets %" PRIu64 ", dropped %" PRIu64 ", bytes %" PRIu64 "", - tv->name, - StatsGetLocalCounterValue(tv, ntv->capture_kernel_packets), - StatsGetLocalCounterValue(tv, ntv->capture_kernel_drops), - ntv->bytes); -} - -/** - * \brief - * \param tv - * \param data Pointer to NetmapThreadVars. - */ -static TmEcode ReceiveNetmapThreadDeinit(ThreadVars *tv, void *data) -{ - SCEnter(); - - NetmapThreadVars *ntv = (NetmapThreadVars *)data; - - if (ntv->ifsrc) { - NetmapClose(ntv->ifsrc); - ntv->ifsrc = NULL; - } - if (ntv->ifdst) { - NetmapClose(ntv->ifdst); - ntv->ifdst = NULL; - } - if (ntv->bpf_prog.bf_insns) { - pcap_freecode(&ntv->bpf_prog); - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Prepare netmap decode thread. - * \param tv Thread local avariables. - * \param initdata Thread config. - * \param data Pointer to DecodeThreadVars placed here. - */ -static TmEcode DecodeNetmapThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - DecodeThreadVars *dtv = NULL; - - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - -#ifdef __SC_CUDA_SUPPORT__ - if (CudaThreadVarsInit(&dtv->cuda_vars) < 0) - SCReturnInt(TM_ECODE_FAILED); -#endif - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function passes off to link type decoders. - * - * DecodeNetmap reads packets from the PacketQueue and passes - * them off to the proper link type decoder. - * - * \param t pointer to ThreadVars - * \param p pointer to the current packet - * \param data pointer that gets cast into NetmapThreadVars for ntv - * \param pq pointer to the current PacketQueue - * \param postpq - */ -static TmEcode DecodeNetmap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - SCEnter(); - - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - SCReturnInt(TM_ECODE_OK); - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief - * \param tv - * \param data Pointer to DecodeThreadVars. - */ -static TmEcode DecodeNetmapThreadDeinit(ThreadVars *tv, void *data) -{ - SCEnter(); - - if (data != NULL) - DecodeThreadVarsFree(tv, data); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Registration Function for RecieveNetmap. - */ -void TmModuleReceiveNetmapRegister(void) -{ - tmm_modules[TMM_RECEIVENETMAP].name = "ReceiveNetmap"; - tmm_modules[TMM_RECEIVENETMAP].ThreadInit = ReceiveNetmapThreadInit; - tmm_modules[TMM_RECEIVENETMAP].Func = NULL; - tmm_modules[TMM_RECEIVENETMAP].PktAcqLoop = ReceiveNetmapLoop; - tmm_modules[TMM_RECEIVENETMAP].ThreadExitPrintStats = ReceiveNetmapThreadExitStats; - tmm_modules[TMM_RECEIVENETMAP].ThreadDeinit = ReceiveNetmapThreadDeinit; - tmm_modules[TMM_RECEIVENETMAP].RegisterTests = NULL; - tmm_modules[TMM_RECEIVENETMAP].cap_flags = SC_CAP_NET_RAW; - tmm_modules[TMM_RECEIVENETMAP].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Registration Function for DecodeNetmap. - */ -void TmModuleDecodeNetmapRegister(void) -{ - tmm_modules[TMM_DECODENETMAP].name = "DecodeNetmap"; - tmm_modules[TMM_DECODENETMAP].ThreadInit = DecodeNetmapThreadInit; - tmm_modules[TMM_DECODENETMAP].Func = DecodeNetmap; - tmm_modules[TMM_DECODENETMAP].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODENETMAP].ThreadDeinit = DecodeNetmapThreadDeinit; - tmm_modules[TMM_DECODENETMAP].RegisterTests = NULL; - tmm_modules[TMM_DECODENETMAP].cap_flags = 0; - tmm_modules[TMM_DECODENETMAP].flags = TM_FLAG_DECODE_TM; -} - -#endif /* HAVE_NETMAP */ -/* eof */ -/** -* @} -*/ diff --git a/framework/src/suricata/src/source-netmap.h b/framework/src/suricata/src/source-netmap.h deleted file mode 100644 index c52b5050..00000000 --- a/framework/src/suricata/src/source-netmap.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** -* \file -* -* \author Aleksey Katargin -*/ - -#ifndef __SOURCE_NETMAP_H__ -#define __SOURCE_NETMAP_H__ - -#include "queue.h" - -/* copy modes */ -enum { - NETMAP_COPY_MODE_NONE, - NETMAP_COPY_MODE_TAP, - NETMAP_COPY_MODE_IPS, -}; - -#define NETMAP_IFACE_NAME_LENGTH 48 - -typedef struct NetmapIfaceConfig_ -{ - /* semantic interface name */ - char iface_name[NETMAP_IFACE_NAME_LENGTH]; - /* real inner interface name */ - char iface[NETMAP_IFACE_NAME_LENGTH]; - /* sw ring flag for iface */ - int iface_sw; - int threads; - int promisc; - int copy_mode; - ChecksumValidationMode checksum_mode; - char *bpf_filter; - /* semantic interface name */ - char *out_iface_name; - /* real inner interface name */ - char out_iface[NETMAP_IFACE_NAME_LENGTH]; - /* sw ring flag for out_iface */ - int out_iface_sw; - SC_ATOMIC_DECLARE(unsigned int, ref); - void (*DerefFunc)(void *); -} NetmapIfaceConfig; - -typedef struct NetmapPacketVars_ -{ - int ring_id; - int slot_id; - int dst_ring_id; - /* NetmapThreadVars */ - void *ntv; -} NetmapPacketVars; - -void TmModuleReceiveNetmapRegister (void); -void TmModuleDecodeNetmapRegister (void); - -#endif /* __SOURCE_NETMAP_H__ */ diff --git a/framework/src/suricata/src/source-nflog.c b/framework/src/suricata/src/source-nflog.c deleted file mode 100644 index 7722244f..00000000 --- a/framework/src/suricata/src/source-nflog.c +++ /dev/null @@ -1,550 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Giuseppe Longo - * - * Netfilter's netfilter_log support - */ -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "packet-queue.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "tm-modules.h" -#include "tm-queuehandlers.h" -#include "tmqh-packetpool.h" - -#include "runmodes.h" -#include "util-error.h" -#include "util-device.h" - -#ifndef HAVE_NFLOG -/** Handle the case where no NFLOG support is compiled in. - * - */ - -TmEcode NoNFLOGSupportExit(ThreadVars *, void *, void **); - -void TmModuleReceiveNFLOGRegister (void) -{ - tmm_modules[TMM_RECEIVENFLOG].name = "ReceiveNFLOG"; - tmm_modules[TMM_RECEIVENFLOG].ThreadInit = NoNFLOGSupportExit; -} - -void TmModuleDecodeNFLOGRegister (void) -{ - tmm_modules[TMM_DECODENFLOG].name = "DecodeNFLOG"; - tmm_modules[TMM_DECODENFLOG].ThreadInit = NoNFLOGSupportExit; -} - -TmEcode NoNFLOGSupportExit(ThreadVars *tv, void *initdata, void **data) -{ - SCLogError(SC_ERR_NFLOG_NOSUPPORT,"Error creating thread %s: you do not have support for nflog " - "enabled please recompile with --enable-nflog", tv->name); - exit(EXIT_FAILURE); -} - -#else /* implied we do have NFLOG support */ - -#include "source-nflog.h" - -TmEcode ReceiveNFLOGThreadInit(ThreadVars *, void *, void **); -TmEcode ReceiveNFLOGThreadDeinit(ThreadVars *, void *); -TmEcode ReceiveNFLOGLoop(ThreadVars *, void *, void *); -void ReceiveNFLOGThreadExitStats(ThreadVars *, void *); - -TmEcode DecodeNFLOGThreadInit(ThreadVars *, void *, void **); -TmEcode DecodeNFLOGThreadDeinit(ThreadVars *tv, void *data); -TmEcode DecodeNFLOG(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); - -static int runmode_workers; - -/* Structure to hold thread specific variables */ -typedef struct NFLOGThreadVars_ { - ThreadVars *tv; - TmSlot *slot; - - char *data; - int datalen; - - uint16_t group; - uint32_t nlbufsiz; - uint32_t nlbufsiz_max; - uint32_t qthreshold; - uint32_t qtimeout; - - struct nflog_handle *h; - struct nflog_g_handle *gh; - - LiveDevice *livedev; - int nful_overrun_warned; - - /* counters */ - uint32_t pkts; - uint64_t bytes; - uint32_t errs; - - uint16_t capture_kernel_packets; - uint16_t capture_kernel_drops; -} NFLOGThreadVars; - -/** - * \brief Registration function for ReceiveNFLOG - */ -void TmModuleReceiveNFLOGRegister (void) -{ - tmm_modules[TMM_RECEIVENFLOG].name = "ReceiveNFLOG"; - tmm_modules[TMM_RECEIVENFLOG].ThreadInit = ReceiveNFLOGThreadInit; - tmm_modules[TMM_RECEIVENFLOG].Func = NULL; - tmm_modules[TMM_RECEIVENFLOG].PktAcqLoop = ReceiveNFLOGLoop; - tmm_modules[TMM_RECEIVENFLOG].ThreadExitPrintStats = ReceiveNFLOGThreadExitStats; - tmm_modules[TMM_RECEIVENFLOG].ThreadDeinit = ReceiveNFLOGThreadDeinit; - tmm_modules[TMM_RECEIVENFLOG].RegisterTests = NULL; - tmm_modules[TMM_RECEIVENFLOG].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Registration function for DecodeNFLOG - */ -void TmModuleDecodeNFLOGRegister (void) -{ - tmm_modules[TMM_DECODENFLOG].name = "DecodeNFLOG"; - tmm_modules[TMM_DECODENFLOG].ThreadInit = DecodeNFLOGThreadInit; - tmm_modules[TMM_DECODENFLOG].Func = DecodeNFLOG; - tmm_modules[TMM_DECODENFLOG].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODENFLOG].ThreadDeinit = DecodeNFLOGThreadDeinit; - tmm_modules[TMM_DECODENFLOG].RegisterTests = NULL; - tmm_modules[TMM_DECODENFLOG].flags = TM_FLAG_DECODE_TM; -} - -/** - * \brief NFLOG callback function - * This function setup a packet from a nflog message - */ -static int NFLOGCallback(struct nflog_g_handle *gh, struct nfgenmsg *msg, - struct nflog_data *nfa, void *data) -{ - NFLOGThreadVars *ntv = (NFLOGThreadVars *) data; - struct nfulnl_msg_packet_hdr *ph; - char *payload; - int ret; - - /* grab a packet*/ - Packet *p = PacketGetFromQueueOrAlloc(); - if (p == NULL) - return -1; - - PKT_SET_SRC(p, PKT_SRC_WIRE); - - ph = nflog_get_msg_packet_hdr(nfa); - if (ph != NULL) { - p->nflog_v.hw_protocol = ph->hw_protocol; - } - - p->nflog_v.ifi = nflog_get_indev(nfa); - p->nflog_v.ifo = nflog_get_outdev(nfa); - - ret = nflog_get_payload(nfa, &payload); - - if (ret > 0) { - if (ret > 65536) { - SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "NFLOG sent too big packet"); - SET_PKT_LEN(p, 0); - } else if (runmode_workers) - PacketSetData(p, (uint8_t *)payload, ret); - else - PacketCopyData(p, (uint8_t *)payload, ret); - } else if (ret == -1) - SET_PKT_LEN(p, 0); - - ret = nflog_get_timestamp(nfa, &p->ts); - if (ret != 0) { - memset(&p->ts, 0, sizeof(struct timeval)); - gettimeofday(&p->ts, NULL); - } - - p->datalink = DLT_RAW; - -#ifdef COUNTERS - ntv->pkts++; - ntv->bytes += GET_PKT_LEN(p); -#endif - (void) SC_ATOMIC_ADD(ntv->livedev->pkts, 1); - - if (TmThreadsSlotProcessPkt(ntv->tv, ntv->slot, p) != TM_ECODE_OK) { - TmqhOutputPacketpool(ntv->tv, p); - return -1; - } - - return 0; -} - -/** - * \brief Receives packet from a nflog group via libnetfilter_log - * This is a setup function for recieving packets via libnetfilter_log. - * \param tv pointer to ThreadVars - * \param initdata pointer to the group passed from the user - * \param data pointer gets populated with NFLOGThreadVars - * \retvalTM_ECODE_OK on success - * \retval TM_ECODE_FAILED on error - */ -TmEcode ReceiveNFLOGThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - NflogGroupConfig *nflconfig = initdata; - - if (initdata == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - NFLOGThreadVars *ntv = SCMalloc(sizeof(NFLOGThreadVars)); - if (unlikely(ntv == NULL)) { - nflconfig->DerefFunc(nflconfig); - SCReturnInt(TM_ECODE_FAILED); - } - memset(ntv, 0, sizeof(NFLOGThreadVars)); - - ntv->tv = tv; - ntv->group = nflconfig->group; - ntv->nlbufsiz = nflconfig->nlbufsiz; - ntv->nlbufsiz_max = nflconfig->nlbufsiz_max; - ntv->qthreshold = nflconfig->qthreshold; - ntv->qtimeout = nflconfig->qtimeout; - ntv->nful_overrun_warned = nflconfig->nful_overrun_warned; - - ntv->h = nflog_open(); - if (ntv->h == NULL) { - SCLogError(SC_ERR_NFLOG_OPEN, "nflog_open() failed"); - SCFree(ntv); - return TM_ECODE_FAILED; - } - - SCLogDebug("binding netfilter_log as nflog handler for AF_INET and AF_INET6"); - - if (nflog_bind_pf(ntv->h, AF_INET) < 0) { - SCLogError(SC_ERR_NFLOG_BIND, "nflog_bind_pf() for AF_INET failed"); - exit(EXIT_FAILURE); - } - if (nflog_bind_pf(ntv->h, AF_INET6) < 0) { - SCLogError(SC_ERR_NFLOG_BIND, "nflog_bind_pf() for AF_INET6 failed"); - exit(EXIT_FAILURE); - } - - ntv->gh = nflog_bind_group(ntv->h, ntv->group); - if (!ntv->gh) { - SCLogError(SC_ERR_NFLOG_OPEN, "nflog_bind_group() failed"); - SCFree(ntv); - return TM_ECODE_FAILED; - } - - if (nflog_set_mode(ntv->gh, NFULNL_COPY_PACKET, 0xFFFF) < 0) { - SCLogError(SC_ERR_NFLOG_SET_MODE, "can't set packet_copy mode"); - SCFree(ntv); - return TM_ECODE_FAILED; - } - - nflog_callback_register(ntv->gh, &NFLOGCallback, (void *)ntv); - - if (ntv->nlbufsiz < ntv->nlbufsiz_max) - ntv->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ntv->h), ntv->nlbufsiz); - else { - SCLogError(SC_ERR_NFLOG_MAX_BUFSIZ, "Maximum buffer size (%d) in NFLOG " - "has been reached", ntv->nlbufsiz); - return TM_ECODE_FAILED; - } - - if (nflog_set_qthresh(ntv->gh, ntv->qthreshold) >= 0) - SCLogDebug("NFLOG netlink queue threshold has been set to %d", - ntv->qthreshold); - else - SCLogDebug("NFLOG netlink queue threshold can't be set to %d", - ntv->qthreshold); - - if (nflog_set_timeout(ntv->gh, ntv->qtimeout) >= 0) - SCLogDebug("NFLOG netlink queue timeout has been set to %d", - ntv->qtimeout); - else - SCLogDebug("NFLOG netlink queue timeout can't be set to %d", - ntv->qtimeout); - - ntv->livedev = LiveGetDevice(nflconfig->numgroup); - if (ntv->livedev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); - SCFree(ntv); - SCReturnInt(TM_ECODE_FAILED); - } - - /* set a timeout to the socket so we can check for a signal - * in case we don't get packets for a longer period. */ - struct timeval timev; - timev.tv_sec = 1; - timev.tv_usec = 0; - - int fd = nflog_fd(ntv->h); - if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev)) == -1) { - SCLogWarning(SC_WARN_NFLOG_SETSOCKOPT, "can't set socket " - "timeout: %s", strerror(errno)); - } - -#ifdef PACKET_STATISTICS - ntv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", - ntv->tv); - ntv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops", - ntv->tv); -#endif - - char *active_runmode = RunmodeGetActive(); - if (active_runmode && !strcmp("workers", active_runmode)) - runmode_workers = 1; - else - runmode_workers = 0; - -#define T_DATA_SIZE 70000 - ntv->data = SCMalloc(T_DATA_SIZE); - if (ntv->data == NULL) { - nflconfig->DerefFunc(nflconfig); - SCFree(ntv); - SCReturnInt(TM_ECODE_FAILED); - } - - ntv->datalen = T_DATA_SIZE; -#undef T_DATA_SIZE - - *data = (void *)ntv; - - nflconfig->DerefFunc(nflconfig); - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief DeInit function unbind group and close nflog's handle - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into NFLogThreadVars - * \retval TM_ECODE_OK is always returned - */ -TmEcode ReceiveNFLOGThreadDeinit(ThreadVars *tv, void *data) -{ - NFLOGThreadVars *ntv = (NFLOGThreadVars *)data; - - SCLogDebug("closing nflog group %d", ntv->group); - if (nflog_unbind_pf(ntv->h, AF_INET) < 0) { - SCLogError(SC_ERR_NFLOG_UNBIND, "nflog_unbind_pf() for AF_INET failed"); - exit(EXIT_FAILURE); - } - - if (nflog_unbind_pf(ntv->h, AF_INET6) < 0) { - SCLogError(SC_ERR_NFLOG_UNBIND, "nflog_unbind_pf() for AF_INET6 failed"); - exit(EXIT_FAILURE); - } - - if (ntv->gh) { - nflog_unbind_group(ntv->gh); - ntv->gh = NULL; - } - - if (ntv->h) { - nflog_close(ntv->h); - ntv->h = NULL; - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Increases netlink buffer size - * - * This function netlink's buffer size until - * the max buffer size is reached - * - * \param data pointer that gets cast into NFLOGThreadVars - * \param size netlink buffer size - */ -static int NFLOGSetnlbufsiz(void *data, unsigned int size) -{ - SCEnter(); - NFLOGThreadVars *ntv = (NFLOGThreadVars *)data; - - if (size < ntv->nlbufsiz_max) { - ntv->nlbufsiz = nfnl_rcvbufsiz(nflog_nfnlh(ntv->h), ntv->nlbufsiz); - return 1; - } - - SCLogWarning(SC_WARN_NFLOG_MAXBUFSIZ_REACHED, - "Maximum buffer size (%d) in NFLOG has been " - "reached. Please, consider raising " - "`buffer-size` and `max-size` in nflog configuration", - ntv->nlbufsiz); - return 0; - -} - -/** - * \brief Recieves packets from a group via libnetfilter_log. - * - * This function recieves packets from a group and passes - * the packet on to the nflog callback function. - * - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into NFLOGThreadVars - * \param slot slot containing task information - * \retval TM_ECODE_OK on success - * \retval TM_ECODE_FAILED on failure - */ -TmEcode ReceiveNFLOGLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - NFLOGThreadVars *ntv = (NFLOGThreadVars *)data; - int rv, fd; - int ret = -1; - - ntv->slot = ((TmSlot *) slot)->slot_next; - - fd = nflog_fd(ntv->h); - if (fd < 0) { - SCLogError(SC_ERR_NFLOG_FD, "Can't obtain a file descriptor"); - SCReturnInt(TM_ECODE_FAILED); - } - - while (1) { - if (suricata_ctl_flags != 0) - break; - - rv = recv(fd, ntv->data, ntv->datalen, 0); - if (rv < 0) { - /*We received an error on socket read */ - if (errno == EINTR || errno == EWOULDBLOCK) { - /*Nothing for us to process */ - continue; - } else if (errno == ENOBUFS) { - if (!ntv->nful_overrun_warned) { - int s = ntv->nlbufsiz * 2; - if (NFLOGSetnlbufsiz((void *)ntv, s)) { - SCLogWarning(SC_WARN_NFLOG_LOSING_EVENTS, - "We are losing events, " - "increasing buffer size " - "to %d", ntv->nlbufsiz); - } else { - ntv->nful_overrun_warned = 1; - } - } - continue; - } else { - SCLogWarning(SC_WARN_NFLOG_RECV, - "Read from NFLOG fd failed: %s", - strerror(errno)); - SCReturnInt(TM_ECODE_FAILED); - } - } - - ret = nflog_handle_packet(ntv->h, ntv->data, rv); - if (ret != 0) - SCLogWarning(SC_ERR_NFLOG_HANDLE_PKT, - "nflog_handle_packet error %" PRId32 "", ret); - - StatsSyncCountersIfSignalled(tv); - } - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function prints stats to the screen at exit - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into NFLOGThreadVars - */ -void ReceiveNFLOGThreadExitStats(ThreadVars *tv, void *data) -{ - SCEnter(); - NFLOGThreadVars *ntv = (NFLOGThreadVars *)data; - - SCLogNotice("(%s) Pkts %" PRIu32 ", Bytes %" PRIu64 "", - tv->name, ntv->pkts, ntv->bytes); -} - - -/** - * \brief Decode IPv4/v6 packets. - * - * \param tv pointer to ThreadVars - * \param p pointer to the current packet - * \param data pointer that gets cast into NFLOGThreadVars for ptv - * \param pq pointer to the current PacketQueue - * - * \retval TM_ECODE_OK is always returned - */ -TmEcode DecodeNFLOG(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - SCEnter(); - IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p); - IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p); - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - DecodeUpdatePacketCounters(tv, dtv, p); - - if (IPV4_GET_RAW_VER(ip4h) == 4) { - SCLogDebug("IPv4 packet"); - DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - } else if(IPV6_GET_RAW_VER(ip6h) == 6) { - SCLogDebug("IPv6 packet"); - DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - } else { - SCLogDebug("packet unsupported by NFLOG, first byte: %02x", *GET_PKT_DATA(p)); - } - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This an Init function for DecodeNFLOG - * - * \param tv pointer to ThreadVars - * \param initdata pointer to initilization data. - * \param data pointer that gets cast into NFLOGThreadVars - * \retval TM_ECODE_OK is returned on success - * \retval TM_ECODE_FAILED is returned on error - */ -TmEcode DecodeNFLOGThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - DecodeThreadVars *dtv = NULL; - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodeNFLOGThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -#endif /* NFLOG */ diff --git a/framework/src/suricata/src/source-nflog.h b/framework/src/suricata/src/source-nflog.h deleted file mode 100644 index 98dd9edf..00000000 --- a/framework/src/suricata/src/source-nflog.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Giuseppe Longo - */ - -#ifndef __SOURCE_NFLOG_H__ -#define __SOURCE_NFLOG_H__ - -#ifdef HAVE_NFLOG -#include -#include -#endif /* HAVE_NFLOG */ - -#define NFLOG_GROUP_NAME_LENGTH 48 -typedef struct NflogGroupConfig_ -{ - /* nflog's group */ - uint16_t group; - /* netlink buffer size */ - uint32_t nlbufsiz; - /* netlink max buffer size */ - uint32_t nlbufsiz_max; - /* max amount of logs in buffer*/ - uint32_t qthreshold; - /* max time to push log buffer */ - uint32_t qtimeout; - - /* used to initialize livedev */ - char numgroup[NFLOG_GROUP_NAME_LENGTH]; - - int nful_overrun_warned; - - void (*DerefFunc)(void *); -} NflogGroupConfig; - -typedef struct NFLOGPacketVars_ -{ - uint32_t mark; - uint32_t ifi; - uint32_t ifo; - uint16_t hw_protocol; - -} NFLOGPacketVars; - -void TmModuleReceiveNFLOGRegister(void); -void TmModuleDecodeNFLOGRegister(void); - -#endif /* __SOURCE_NFLOG_H__ */ diff --git a/framework/src/suricata/src/source-nfq-prototypes.h b/framework/src/suricata/src/source-nfq-prototypes.h deleted file mode 100644 index eef25884..00000000 --- a/framework/src/suricata/src/source-nfq-prototypes.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __SOURCE_NFQ_PROTOTYPES_H__ -#define __SOURCE_NFQ_PROTOTYPES_H__ - -void TmModuleReceiveNFQRegister (void); -void TmModuleVerdictNFQRegister (void); -void TmModuleDecodeNFQRegister (void); - -#endif /* __SOURCE_NFQ_PROTOTYPES_H__ */ - diff --git a/framework/src/suricata/src/source-nfq.c b/framework/src/suricata/src/source-nfq.c deleted file mode 100644 index 38770cb9..00000000 --- a/framework/src/suricata/src/source-nfq.c +++ /dev/null @@ -1,1277 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Eric Leblond - * - * Netfilter's netfilter_queue support for reading packets from the - * kernel and setting verdicts back to it (inline mode). - * Supported on Linux and Windows. - * - * \todo test if Receive and Verdict if both are present - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "packet-queue.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" -#include "tm-queuehandlers.h" -#include "tmqh-packetpool.h" - -#include "conf.h" -#include "config.h" -#include "conf-yaml-loader.h" -#include "source-nfq-prototypes.h" -#include "action-globals.h" - -#include "util-debug.h" -#include "util-error.h" -#include "util-byte.h" -#include "util-privs.h" -#include "util-device.h" - -#include "runmodes.h" - -#include "source-nfq.h" - -#ifndef NFQ -/** Handle the case where no NFQ support is compiled in. - * - */ - -TmEcode NoNFQSupportExit(ThreadVars *, void *, void **); - -void TmModuleReceiveNFQRegister (void) -{ - tmm_modules[TMM_RECEIVENFQ].name = "ReceiveNFQ"; - tmm_modules[TMM_RECEIVENFQ].ThreadInit = NoNFQSupportExit; - tmm_modules[TMM_RECEIVENFQ].Func = NULL; - tmm_modules[TMM_RECEIVENFQ].ThreadExitPrintStats = NULL; - tmm_modules[TMM_RECEIVENFQ].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVENFQ].RegisterTests = NULL; - tmm_modules[TMM_RECEIVENFQ].cap_flags = SC_CAP_NET_ADMIN; - tmm_modules[TMM_RECEIVENFQ].flags = TM_FLAG_RECEIVE_TM; -} - -void TmModuleVerdictNFQRegister (void) -{ - tmm_modules[TMM_VERDICTNFQ].name = "VerdictNFQ"; - tmm_modules[TMM_VERDICTNFQ].ThreadInit = NoNFQSupportExit; - tmm_modules[TMM_VERDICTNFQ].Func = NULL; - tmm_modules[TMM_VERDICTNFQ].ThreadExitPrintStats = NULL; - tmm_modules[TMM_VERDICTNFQ].ThreadDeinit = NULL; - tmm_modules[TMM_VERDICTNFQ].RegisterTests = NULL; - tmm_modules[TMM_VERDICTNFQ].cap_flags = SC_CAP_NET_ADMIN; -} - -void TmModuleDecodeNFQRegister (void) -{ - tmm_modules[TMM_DECODENFQ].name = "DecodeNFQ"; - tmm_modules[TMM_DECODENFQ].ThreadInit = NoNFQSupportExit; - tmm_modules[TMM_DECODENFQ].Func = NULL; - tmm_modules[TMM_DECODENFQ].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODENFQ].ThreadDeinit = NULL; - tmm_modules[TMM_DECODENFQ].RegisterTests = NULL; - tmm_modules[TMM_DECODENFQ].cap_flags = 0; - tmm_modules[TMM_DECODENFQ].flags = TM_FLAG_DECODE_TM; -} - -TmEcode NoNFQSupportExit(ThreadVars *tv, void *initdata, void **data) -{ - SCLogError(SC_ERR_NFQ_NOSUPPORT,"Error creating thread %s: you do not have support for nfqueue " - "enabled please recompile with --enable-nfqueue", tv->name); - exit(EXIT_FAILURE); -} - -#else /* implied we do have NFQ support */ - -extern int max_pending_packets; - -#define MAX_ALREADY_TREATED 5 -#define NFQ_VERDICT_RETRY_TIME 3 -static int already_seen_warning; -static int runmode_workers; - -#define NFQ_BURST_FACTOR 4 - -#ifndef SOL_NETLINK -#define SOL_NETLINK 270 -#endif - -//#define NFQ_DFT_QUEUE_LEN NFQ_BURST_FACTOR * MAX_PENDING -//#define NFQ_NF_BUFSIZE 1500 * NFQ_DFT_QUEUE_LEN - -typedef struct NFQThreadVars_ -{ - uint16_t nfq_index; - ThreadVars *tv; - TmSlot *slot; - - char *data; /** Per function and thread data */ - int datalen; /** Length of per function and thread data */ - - CaptureStats stats; - -} NFQThreadVars; -/* shared vars for all for nfq queues and threads */ -static NFQGlobalVars nfq_g; - -static NFQThreadVars nfq_t[NFQ_MAX_QUEUE]; -static NFQQueueVars nfq_q[NFQ_MAX_QUEUE]; -static uint16_t receive_queue_num = 0; -static SCMutex nfq_init_lock; - -TmEcode ReceiveNFQLoop(ThreadVars *tv, void *data, void *slot); -TmEcode ReceiveNFQThreadInit(ThreadVars *, void *, void **); -TmEcode ReceiveNFQThreadDeinit(ThreadVars *, void *); -void ReceiveNFQThreadExitStats(ThreadVars *, void *); - -TmEcode VerdictNFQ(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode VerdictNFQThreadInit(ThreadVars *, void *, void **); -TmEcode VerdictNFQThreadDeinit(ThreadVars *, void *); - -TmEcode DecodeNFQ(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode DecodeNFQThreadInit(ThreadVars *, void *, void **); -TmEcode DecodeNFQThreadDeinit(ThreadVars *tv, void *data); - -TmEcode NFQSetVerdict(Packet *p); - -typedef enum NFQMode_ { - NFQ_ACCEPT_MODE, - NFQ_REPEAT_MODE, - NFQ_ROUTE_MODE, -} NFQMode; - -#define NFQ_FLAG_FAIL_OPEN (1 << 0) - -typedef struct NFQCnf_ { - NFQMode mode; - uint32_t mark; - uint32_t mask; - uint32_t next_queue; - uint32_t flags; - uint8_t batchcount; -} NFQCnf; - -NFQCnf nfq_config; - -void TmModuleReceiveNFQRegister (void) -{ - /* XXX create a general NFQ setup function */ - memset(&nfq_g, 0, sizeof(nfq_g)); - SCMutexInit(&nfq_init_lock, NULL); - - tmm_modules[TMM_RECEIVENFQ].name = "ReceiveNFQ"; - tmm_modules[TMM_RECEIVENFQ].ThreadInit = ReceiveNFQThreadInit; - tmm_modules[TMM_RECEIVENFQ].Func = NULL; - tmm_modules[TMM_RECEIVENFQ].PktAcqLoop = ReceiveNFQLoop; - tmm_modules[TMM_RECEIVENFQ].ThreadExitPrintStats = ReceiveNFQThreadExitStats; - tmm_modules[TMM_RECEIVENFQ].ThreadDeinit = ReceiveNFQThreadDeinit; - tmm_modules[TMM_RECEIVENFQ].RegisterTests = NULL; - tmm_modules[TMM_RECEIVENFQ].flags = TM_FLAG_RECEIVE_TM; -} - -void TmModuleVerdictNFQRegister (void) -{ - tmm_modules[TMM_VERDICTNFQ].name = "VerdictNFQ"; - tmm_modules[TMM_VERDICTNFQ].ThreadInit = VerdictNFQThreadInit; - tmm_modules[TMM_VERDICTNFQ].Func = VerdictNFQ; - tmm_modules[TMM_VERDICTNFQ].ThreadExitPrintStats = NULL; - tmm_modules[TMM_VERDICTNFQ].ThreadDeinit = VerdictNFQThreadDeinit; - tmm_modules[TMM_VERDICTNFQ].RegisterTests = NULL; -} - -void TmModuleDecodeNFQRegister (void) -{ - tmm_modules[TMM_DECODENFQ].name = "DecodeNFQ"; - tmm_modules[TMM_DECODENFQ].ThreadInit = DecodeNFQThreadInit; - tmm_modules[TMM_DECODENFQ].Func = DecodeNFQ; - tmm_modules[TMM_DECODENFQ].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODENFQ].ThreadDeinit = DecodeNFQThreadDeinit; - tmm_modules[TMM_DECODENFQ].RegisterTests = NULL; - tmm_modules[TMM_DECODENFQ].flags = TM_FLAG_DECODE_TM; -} - -/** \brief To initialize the NFQ global configuration data - * - * \param quiet It tells the mode of operation, if it is TRUE nothing will - * be get printed. - */ -void NFQInitConfig(char quiet) -{ - intmax_t value = 0; - char* nfq_mode = NULL; - int boolval; - - SCLogDebug("Initializing NFQ"); - - memset(&nfq_config, 0, sizeof(nfq_config)); - - if ((ConfGet("nfq.mode", &nfq_mode)) == 0) { - nfq_config.mode = NFQ_ACCEPT_MODE; - } else { - if (!strcmp("accept", nfq_mode)) { - nfq_config.mode = NFQ_ACCEPT_MODE; - } else if (!strcmp("repeat", nfq_mode)) { - nfq_config.mode = NFQ_REPEAT_MODE; - } else if (!strcmp("route", nfq_mode)) { - nfq_config.mode = NFQ_ROUTE_MODE; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Unknown nfq.mode"); - exit(EXIT_FAILURE); - } - } - - (void)ConfGetBool("nfq.fail-open", (int *)&boolval); - if (boolval) { -#ifdef HAVE_NFQ_SET_QUEUE_FLAGS - SCLogInfo("Enabling fail-open on queue"); - nfq_config.flags |= NFQ_FLAG_FAIL_OPEN; -#else - SCLogError(SC_ERR_NFQ_NOSUPPORT, - "nfq.%s set but NFQ library has no support for it.", "fail-open"); -#endif - } - - if ((ConfGetInt("nfq.repeat-mark", &value)) == 1) { - nfq_config.mark = (uint32_t)value; - } - - if ((ConfGetInt("nfq.repeat-mask", &value)) == 1) { - nfq_config.mask = (uint32_t)value; - } - - if ((ConfGetInt("nfq.route-queue", &value)) == 1) { - nfq_config.next_queue = ((uint32_t)value) << 16; - } - - if ((ConfGetInt("nfq.batchcount", &value)) == 1) { -#ifdef HAVE_NFQ_SET_VERDICT_BATCH - if (value > 255) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "nfq.batchcount cannot exceed 255."); - value = 255; - } - if (value > 1) - nfq_config.batchcount = (uint8_t) (value - 1); -#else - SCLogWarning(SC_ERR_NFQ_NOSUPPORT, - "nfq.%s set but NFQ library has no support for it.", "batchcount"); -#endif - } - - if (!quiet) { - switch (nfq_config.mode) { - case NFQ_ACCEPT_MODE: - SCLogInfo("NFQ running in standard ACCEPT/DROP mode"); - break; - case NFQ_REPEAT_MODE: - SCLogInfo("NFQ running in REPEAT mode with mark %"PRIu32"/%"PRIu32, - nfq_config.mark, nfq_config.mask); - break; - case NFQ_ROUTE_MODE: - SCLogInfo("NFQ running in route mode with next queue %"PRIu32, - nfq_config.next_queue >> 16); - break; - } - } - -} - -static uint8_t NFQVerdictCacheLen(NFQQueueVars *t) -{ -#ifdef HAVE_NFQ_SET_VERDICT_BATCH - return t->verdict_cache.len; -#else - return 0; -#endif -} - -static void NFQVerdictCacheFlush(NFQQueueVars *t) -{ -#ifdef HAVE_NFQ_SET_VERDICT_BATCH - int ret; - int iter = 0; - - do { - if (t->verdict_cache.mark_valid) - ret = nfq_set_verdict_batch2(t->qh, - t->verdict_cache.packet_id, - t->verdict_cache.verdict, - t->verdict_cache.mark); - else - ret = nfq_set_verdict_batch(t->qh, - t->verdict_cache.packet_id, - t->verdict_cache.verdict); - } while ((ret < 0) && (iter++ < NFQ_VERDICT_RETRY_TIME)); - - if (ret < 0) { - SCLogWarning(SC_ERR_NFQ_SET_VERDICT, "nfq_set_verdict_batch failed: %s", - strerror(errno)); - } else { - t->verdict_cache.len = 0; - t->verdict_cache.mark_valid = 0; - } -#endif -} - -static int NFQVerdictCacheAdd(NFQQueueVars *t, Packet *p, uint32_t verdict) -{ -#ifdef HAVE_NFQ_SET_VERDICT_BATCH - if (t->verdict_cache.maxlen == 0) - return -1; - - if (p->flags & PKT_STREAM_MODIFIED || verdict == NF_DROP) - goto flush; - - if (p->flags & PKT_MARK_MODIFIED) { - if (!t->verdict_cache.mark_valid) { - if (t->verdict_cache.len) - goto flush; - t->verdict_cache.mark_valid = 1; - t->verdict_cache.mark = p->nfq_v.mark; - } else if (t->verdict_cache.mark != p->nfq_v.mark) { - goto flush; - } - } else if (t->verdict_cache.mark_valid) { - goto flush; - } - - if (t->verdict_cache.len == 0) { - t->verdict_cache.verdict = verdict; - } else if (t->verdict_cache.verdict != verdict) - goto flush; - - /* same verdict, mark not set or identical -> can cache */ - t->verdict_cache.packet_id = p->nfq_v.id; - - if (t->verdict_cache.len >= t->verdict_cache.maxlen) - NFQVerdictCacheFlush(t); - else - t->verdict_cache.len++; - return 0; - flush: - /* can't cache. Flush current cache and signal caller it should send single verdict */ - if (NFQVerdictCacheLen(t) > 0) - NFQVerdictCacheFlush(t); -#endif - return -1; -} - -static inline void NFQMutexInit(NFQQueueVars *nq) -{ - char *active_runmode = RunmodeGetActive(); - - if (active_runmode && !strcmp("workers", active_runmode)) { - nq->use_mutex = 0; - runmode_workers = 1; - SCLogInfo("NFQ running in 'workers' runmode, will not use mutex."); - } else { - nq->use_mutex = 1; - runmode_workers = 0; - SCMutexInit(&nq->mutex_qh, NULL); - } -} - -#define NFQMutexLock(nq) do { \ - if ((nq)->use_mutex) \ - SCMutexLock(&(nq)->mutex_qh); \ -} while (0) - -#define NFQMutexUnlock(nq) do { \ - if ((nq)->use_mutex) \ - SCMutexUnlock(&(nq)->mutex_qh); \ -} while (0) - -/** - * \brief Read data from nfq message and setup Packet - * - * \note - * In case of error, this function verdict the packet - * to avoid skb to get stuck in kernel. - */ -int NFQSetupPkt (Packet *p, struct nfq_q_handle *qh, void *data) -{ - struct nfq_data *tb = (struct nfq_data *)data; - int ret; - char *pktdata; - struct nfqnl_msg_packet_hdr *ph; - - ph = nfq_get_msg_packet_hdr(tb); - if (ph != NULL) { - p->nfq_v.id = ntohl(ph->packet_id); - //p->nfq_v.hw_protocol = ntohs(p->nfq_v.ph->hw_protocol); - p->nfq_v.hw_protocol = ph->hw_protocol; - } - p->nfq_v.mark = nfq_get_nfmark(tb); - if (nfq_config.mode == NFQ_REPEAT_MODE) { - if ((nfq_config.mark & nfq_config.mask) == - (p->nfq_v.mark & nfq_config.mask)) { - int iter = 0; - if (already_seen_warning < MAX_ALREADY_TREATED) - SCLogInfo("Packet seems already treated by suricata"); - already_seen_warning++; - do { - ret = nfq_set_verdict(qh, p->nfq_v.id, NF_ACCEPT, 0, NULL); - } while ((ret < 0) && (iter++ < NFQ_VERDICT_RETRY_TIME)); - if (ret < 0) { - SCLogWarning(SC_ERR_NFQ_SET_VERDICT, - "nfq_set_verdict of %p failed %" PRId32 ": %s", - p, ret, strerror(errno)); - } - return -1 ; - } - } - p->nfq_v.ifi = nfq_get_indev(tb); - p->nfq_v.ifo = nfq_get_outdev(tb); - p->nfq_v.verdicted = 0; - -#ifdef NFQ_GET_PAYLOAD_SIGNED - ret = nfq_get_payload(tb, &pktdata); -#else - ret = nfq_get_payload(tb, (unsigned char **) &pktdata); -#endif /* NFQ_GET_PAYLOAD_SIGNED */ - if (ret > 0) { - /* nfq_get_payload returns a pointer to a part of memory - * that is not preserved over the lifetime of our packet. - * So we need to copy it. */ - if (ret > 65536) { - /* Will not be able to copy data ! Set length to 0 - * to trigger an error in packet decoding. - * This is unlikely to happen */ - SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "NFQ sent too big packet"); - SET_PKT_LEN(p, 0); - } else if (runmode_workers) { - PacketSetData(p, (uint8_t *)pktdata, ret); - } else { - PacketCopyData(p, (uint8_t *)pktdata, ret); - } - } else if (ret == -1) { - /* unable to get pointer to data, ensure packet length is zero. - * This will trigger an error in packet decoding */ - SET_PKT_LEN(p, 0); - } - - ret = nfq_get_timestamp(tb, &p->ts); - if (ret != 0) { - memset (&p->ts, 0, sizeof(struct timeval)); - gettimeofday(&p->ts, NULL); - } - - p->datalink = DLT_RAW; - return 0; -} - -static void NFQReleasePacket(Packet *p) -{ - if (unlikely(!p->nfq_v.verdicted)) { - PACKET_UPDATE_ACTION(p, ACTION_DROP); - NFQSetVerdict(p); - } - PacketFreeOrRelease(p); -} - -static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, - struct nfq_data *nfa, void *data) -{ - NFQThreadVars *ntv = (NFQThreadVars *)data; - ThreadVars *tv = ntv->tv; - int ret; - - /* grab a packet */ - Packet *p = PacketGetFromQueueOrAlloc(); - if (p == NULL) { - return -1; - } - PKT_SET_SRC(p, PKT_SRC_WIRE); - - p->nfq_v.nfq_index = ntv->nfq_index; - ret = NFQSetupPkt(p, qh, (void *)nfa); - if (ret == -1) { -#ifdef COUNTERS - NFQQueueVars *nfq_q = NFQGetQueue(ntv->nfq_index); - nfq_q->errs++; - nfq_q->pkts++; - nfq_q->bytes += GET_PKT_LEN(p); -#endif /* COUNTERS */ - /* NFQSetupPkt is issuing a verdict - so we only recycle Packet and leave */ - TmqhOutputPacketpool(tv, p); - return 0; - } - - p->ReleasePacket = NFQReleasePacket; - -#ifdef COUNTERS - NFQQueueVars *nfq_q = NFQGetQueue(ntv->nfq_index); - nfq_q->pkts++; - nfq_q->bytes += GET_PKT_LEN(p); -#endif /* COUNTERS */ - - if (ntv->slot) { - if (TmThreadsSlotProcessPkt(tv, ntv->slot, p) != TM_ECODE_OK) { - TmqhOutputPacketpool(ntv->tv, p); - return -1; - } - } else { - /* pass on... */ - tv->tmqh_out(tv, p); - } - - return 0; -} - -TmEcode NFQInitThread(NFQThreadVars *nfq_t, uint32_t queue_maxlen) -{ -#ifndef OS_WIN32 - struct timeval tv; - int opt; -#endif - NFQQueueVars *nfq_q = NFQGetQueue(nfq_t->nfq_index); - if (nfq_q == NULL) { - SCLogError(SC_ERR_NFQ_OPEN, "no queue for given index"); - return TM_ECODE_FAILED; - } - SCLogDebug("opening library handle"); - nfq_q->h = nfq_open(); - if (!nfq_q->h) { - SCLogError(SC_ERR_NFQ_OPEN, "nfq_open() failed"); - return TM_ECODE_FAILED; - } - - if (nfq_g.unbind == 0) - { - /* VJ: on my Ubuntu Hardy system this fails the first time it's - * run. Ignoring the error seems to have no bad effects. */ - SCLogDebug("unbinding existing nf_queue handler for AF_INET (if any)"); - if (nfq_unbind_pf(nfq_q->h, AF_INET) < 0) { - SCLogError(SC_ERR_NFQ_UNBIND, "nfq_unbind_pf() for AF_INET failed"); - exit(EXIT_FAILURE); - } - if (nfq_unbind_pf(nfq_q->h, AF_INET6) < 0) { - SCLogError(SC_ERR_NFQ_UNBIND, "nfq_unbind_pf() for AF_INET6 failed"); - exit(EXIT_FAILURE); - } - nfq_g.unbind = 1; - - SCLogDebug("binding nfnetlink_queue as nf_queue handler for AF_INET and AF_INET6"); - - if (nfq_bind_pf(nfq_q->h, AF_INET) < 0) { - SCLogError(SC_ERR_NFQ_BIND, "nfq_bind_pf() for AF_INET failed"); - exit(EXIT_FAILURE); - } - if (nfq_bind_pf(nfq_q->h, AF_INET6) < 0) { - SCLogError(SC_ERR_NFQ_BIND, "nfq_bind_pf() for AF_INET6 failed"); - exit(EXIT_FAILURE); - } - } - - SCLogInfo("binding this thread %d to queue '%" PRIu32 "'", nfq_t->nfq_index, nfq_q->queue_num); - - /* pass the thread memory as a void ptr so the - * callback function has access to it. */ - nfq_q->qh = nfq_create_queue(nfq_q->h, nfq_q->queue_num, &NFQCallBack, (void *)nfq_t); - if (nfq_q->qh == NULL) - { - SCLogError(SC_ERR_NFQ_CREATE_QUEUE, "nfq_create_queue failed"); - return TM_ECODE_FAILED; - } - - SCLogDebug("setting copy_packet mode"); - - /* 05DC = 1500 */ - //if (nfq_set_mode(nfq_t->qh, NFQNL_COPY_PACKET, 0x05DC) < 0) { - if (nfq_set_mode(nfq_q->qh, NFQNL_COPY_PACKET, 0xFFFF) < 0) { - SCLogError(SC_ERR_NFQ_SET_MODE, "can't set packet_copy mode"); - return TM_ECODE_FAILED; - } - -#ifdef HAVE_NFQ_MAXLEN - if (queue_maxlen > 0) { - SCLogInfo("setting queue length to %" PRId32 "", queue_maxlen); - - /* non-fatal if it fails */ - if (nfq_set_queue_maxlen(nfq_q->qh, queue_maxlen) < 0) { - SCLogWarning(SC_ERR_NFQ_MAXLEN, "can't set queue maxlen: your kernel probably " - "doesn't support setting the queue length"); - } - } -#endif /* HAVE_NFQ_MAXLEN */ - -#ifndef OS_WIN32 - /* set netlink buffer size to a decent value */ - nfnl_rcvbufsiz(nfq_nfnlh(nfq_q->h), queue_maxlen * 1500); - SCLogInfo("setting nfnl bufsize to %" PRId32 "", queue_maxlen * 1500); - - nfq_q->nh = nfq_nfnlh(nfq_q->h); - nfq_q->fd = nfnl_fd(nfq_q->nh); - NFQMutexInit(nfq_q); - - /* Set some netlink specific option on the socket to increase - performance */ - opt = 1; -#ifdef NETLINK_BROADCAST_SEND_ERROR - if (setsockopt(nfq_q->fd, SOL_NETLINK, - NETLINK_BROADCAST_SEND_ERROR, &opt, sizeof(int)) == -1) { - SCLogWarning(SC_ERR_NFQ_SETSOCKOPT, - "can't set netlink broadcast error: %s", - strerror(errno)); - } -#endif - /* Don't send error about no buffer space available but drop the - packets instead */ -#ifdef NETLINK_NO_ENOBUFS - if (setsockopt(nfq_q->fd, SOL_NETLINK, - NETLINK_NO_ENOBUFS, &opt, sizeof(int)) == -1) { - SCLogWarning(SC_ERR_NFQ_SETSOCKOPT, - "can't set netlink enobufs: %s", - strerror(errno)); - } -#endif - -#ifdef HAVE_NFQ_SET_QUEUE_FLAGS - if (nfq_config.flags & NFQ_FLAG_FAIL_OPEN) { - uint32_t flags = NFQA_CFG_F_FAIL_OPEN; - uint32_t mask = NFQA_CFG_F_FAIL_OPEN; - int r = nfq_set_queue_flags(nfq_q->qh, mask, flags); - - if (r == -1) { - SCLogWarning(SC_ERR_NFQ_SET_MODE, "can't set fail-open mode: %s", - strerror(errno)); - } else { - SCLogInfo("fail-open mode should be set on queue"); - } - } -#endif - -#ifdef HAVE_NFQ_SET_VERDICT_BATCH - if (runmode_workers) { - nfq_q->verdict_cache.maxlen = nfq_config.batchcount; - } else if (nfq_config.batchcount) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "nfq.batchcount is only valid in workers runmode."); - } -#endif - - /* set a timeout to the socket so we can check for a signal - * in case we don't get packets for a longer period. */ - tv.tv_sec = 1; - tv.tv_usec = 0; - - if(setsockopt(nfq_q->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { - SCLogWarning(SC_ERR_NFQ_SETSOCKOPT, "can't set socket timeout: %s", strerror(errno)); - } - - SCLogDebug("nfq_q->h %p, nfq_q->nh %p, nfq_q->qh %p, nfq_q->fd %" PRId32 "", - nfq_q->h, nfq_q->nh, nfq_q->qh, nfq_q->fd); -#else /* OS_WIN32 */ - NFQMutexInit(nfq_q); - nfq_q->ovr.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - nfq_q->fd = nfq_fd(nfq_q->h); - SCLogDebug("nfq_q->h %p, nfq_q->qh %p, nfq_q->fd %p", nfq_q->h, nfq_q->qh, nfq_q->fd); -#endif /* OS_WIN32 */ - - return TM_ECODE_OK; -} - -TmEcode ReceiveNFQThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCMutexLock(&nfq_init_lock); - -#ifndef OS_WIN32 - sigset_t sigs; - sigfillset(&sigs); - pthread_sigmask(SIG_BLOCK, &sigs, NULL); -#endif /* OS_WIN32 */ - - NFQThreadVars *ntv = (NFQThreadVars *) initdata; - /* store the ThreadVars pointer in our NFQ thread context - * as we will need it in our callback function */ - ntv->tv = tv; - - int r = NFQInitThread(ntv, (max_pending_packets * NFQ_BURST_FACTOR)); - if (r < 0) { - SCLogError(SC_ERR_NFQ_THREAD_INIT, "nfq thread failed to initialize"); - - SCMutexUnlock(&nfq_init_lock); - exit(EXIT_FAILURE); - } - -#define T_DATA_SIZE 70000 - ntv->data = SCMalloc(T_DATA_SIZE); - if (ntv->data == NULL) { - SCMutexUnlock(&nfq_init_lock); - return TM_ECODE_FAILED; - } - ntv->datalen = T_DATA_SIZE; -#undef T_DATA_SIZE - - *data = (void *)ntv; - - SCMutexUnlock(&nfq_init_lock); - return TM_ECODE_OK; -} - - -TmEcode ReceiveNFQThreadDeinit(ThreadVars *t, void *data) -{ - NFQThreadVars *ntv = (NFQThreadVars *)data; - NFQQueueVars *nq = NFQGetQueue(ntv->nfq_index); - - if (ntv->data != NULL) { - SCFree(ntv->data); - ntv->data = NULL; - } - ntv->datalen = 0; - - NFQMutexLock(nq); - SCLogDebug("starting... will close queuenum %" PRIu32 "", nq->queue_num); - if (nq->qh) { - nfq_destroy_queue(nq->qh); - nq->qh = NULL; - } - NFQMutexUnlock(nq); - - return TM_ECODE_OK; -} - - -TmEcode VerdictNFQThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - NFQThreadVars *ntv = (NFQThreadVars *) initdata; - - CaptureStatsSetup(tv, &ntv->stats); - - *data = (void *)ntv; - return TM_ECODE_OK; -} - -TmEcode VerdictNFQThreadDeinit(ThreadVars *tv, void *data) -{ - NFQThreadVars *ntv = (NFQThreadVars *)data; - NFQQueueVars *nq = NFQGetQueue(ntv->nfq_index); - - SCLogDebug("starting... will close queuenum %" PRIu32 "", nq->queue_num); - NFQMutexLock(nq); - if (nq->qh) { - nfq_destroy_queue(nq->qh); - nq->qh = NULL; - } - NFQMutexUnlock(nq); - - return TM_ECODE_OK; -} - -/** - * \brief Add a Netfilter queue - * - * \param string with the queue name - * - * \retval 0 on success. - * \retval -1 on failure. - */ -int NFQRegisterQueue(char *queue) -{ - NFQThreadVars *ntv = NULL; - NFQQueueVars *nq = NULL; - /* Extract the queue number from the specified command line argument */ - uint16_t queue_num = 0; - if ((ByteExtractStringUint16(&queue_num, 10, strlen(queue), queue)) < 0) - { - SCLogError(SC_ERR_INVALID_ARGUMENT, "specified queue number %s is not " - "valid", queue); - return -1; - } - - SCMutexLock(&nfq_init_lock); - if (receive_queue_num >= NFQ_MAX_QUEUE) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "too much Netfilter queue registered (%d)", - receive_queue_num); - SCMutexUnlock(&nfq_init_lock); - return -1; - } - if (receive_queue_num == 0) { - memset(&nfq_t, 0, sizeof(nfq_t)); - memset(&nfq_q, 0, sizeof(nfq_q)); - } - - ntv = &nfq_t[receive_queue_num]; - ntv->nfq_index = receive_queue_num; - - nq = &nfq_q[receive_queue_num]; - nq->queue_num = queue_num; - receive_queue_num++; - SCMutexUnlock(&nfq_init_lock); - LiveRegisterDevice(queue); - - SCLogDebug("Queue \"%s\" registered.", queue); - return 0; -} - - - -/** - * \brief Get a pointer to the NFQ queue at index - * - * \param number idx of the queue in our array - * - * \retval ptr pointer to the NFQThreadVars at index - * \retval NULL on error - */ -void *NFQGetQueue(int number) -{ - if (number >= receive_queue_num) - return NULL; - - return (void *)&nfq_q[number]; -} - -/** - * \brief Get a pointer to the NFQ thread at index - * - * This function is temporary used as configuration parser. - * - * \param number idx of the queue in our array - * - * \retval ptr pointer to the NFQThreadVars at index - * \retval NULL on error - */ -void *NFQGetThread(int number) -{ - if (number >= receive_queue_num) - return NULL; - - return (void *)&nfq_t[number]; -} - -/** - * \brief NFQ function to get a packet from the kernel - * - * \note separate functions for Linux and Win32 for readability. - */ -#ifndef OS_WIN32 -void NFQRecvPkt(NFQQueueVars *t, NFQThreadVars *tv) -{ - int rv, ret; - int flag = NFQVerdictCacheLen(t) ? MSG_DONTWAIT : 0; - - /* XXX what happens on rv == 0? */ - rv = recv(t->fd, tv->data, tv->datalen, flag); - - if (rv < 0) { - if (errno == EINTR || errno == EWOULDBLOCK) { - /* no error on timeout */ - if (flag) - NFQVerdictCacheFlush(t); - } else { -#ifdef COUNTERS - NFQMutexLock(t); - t->errs++; - NFQMutexUnlock(t); -#endif /* COUNTERS */ - } - } else if(rv == 0) { - SCLogWarning(SC_ERR_NFQ_RECV, "recv got returncode 0"); - } else { -#ifdef DBG_PERF - if (rv > t->dbg_maxreadsize) - t->dbg_maxreadsize = rv; -#endif /* DBG_PERF */ - - //printf("NFQRecvPkt: t %p, rv = %" PRId32 "\n", t, rv); - - NFQMutexLock(t); - if (t->qh != NULL) { - ret = nfq_handle_packet(t->h, tv->data, rv); - } else { - SCLogWarning(SC_ERR_NFQ_HANDLE_PKT, "NFQ handle has been destroyed"); - ret = -1; - } - NFQMutexUnlock(t); - - if (ret != 0) { - SCLogWarning(SC_ERR_NFQ_HANDLE_PKT, "nfq_handle_packet error %" PRId32 "", ret); - } - } -} -#else /* WIN32 version of NFQRecvPkt */ -void NFQRecvPkt(NFQQueueVars *t, NFQThreadVars *tv) -{ - int rv, ret; - static int timeouted = 0; - - if (timeouted) { - if (WaitForSingleObject(t->ovr.hEvent, 1000) == WAIT_TIMEOUT) { - rv = -1; - errno = EINTR; - goto process_rv; - } - timeouted = 0; - } - -read_packet_again: - - if (!ReadFile(t->fd, tv->buf, sizeof(tv->buf), (DWORD*)&rv, &t->ovr)) { - if (GetLastError() != ERROR_IO_PENDING) { - rv = -1; - errno = EIO; - } else { - if (WaitForSingleObject(t->ovr.hEvent, 1000) == WAIT_TIMEOUT) { - rv = -1; - errno = EINTR; - timeouted = 1; - } else { - /* We needn't to call GetOverlappedResult() because it always - * fail with our error code ERROR_MORE_DATA. */ - goto read_packet_again; - } - } - } - -process_rv: - - if (rv < 0) { - if (errno == EINTR) { - /* no error on timeout */ - } else { -#ifdef COUNTERS - t->errs++; -#endif /* COUNTERS */ - } - } else if(rv == 0) { - SCLogWarning(SC_ERR_NFQ_RECV, "recv got returncode 0"); - } else { -#ifdef DBG_PERF - if (rv > t->dbg_maxreadsize) - t->dbg_maxreadsize = rv; -#endif /* DBG_PERF */ - - //printf("NFQRecvPkt: t %p, rv = %" PRId32 "\n", t, rv); - - NFQMutexLock(t); - if (t->qh) { - ret = nfq_handle_packet(t->h, buf, rv); - } else { - SCLogWarning(SC_ERR_NFQ_HANDLE_PKT, "NFQ handle has been destroyed"); - ret = -1; - } - NFQMutexUnlock(t); - - if (ret != 0) { - SCLogWarning(SC_ERR_NFQ_HANDLE_PKT, "nfq_handle_packet error %" PRId32 "", ret); - } - } -} -#endif /* OS_WIN32 */ - -/** - * \brief Main NFQ reading Loop function - */ -TmEcode ReceiveNFQLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - NFQThreadVars *ntv = (NFQThreadVars *)data; - NFQQueueVars *nq = NFQGetQueue(ntv->nfq_index); - - ntv->slot = ((TmSlot *) slot)->slot_next; - - while(1) { - if (suricata_ctl_flags != 0) { - NFQMutexLock(nq); - if (nq->qh) { - nfq_destroy_queue(nq->qh); - nq->qh = NULL; - } - NFQMutexUnlock(nq); - break; - } - NFQRecvPkt(nq, ntv); - - StatsSyncCountersIfSignalled(tv); - } - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief NFQ receive module stats printing function - */ -void ReceiveNFQThreadExitStats(ThreadVars *tv, void *data) -{ - NFQThreadVars *ntv = (NFQThreadVars *)data; - NFQQueueVars *nq = NFQGetQueue(ntv->nfq_index); -#ifdef COUNTERS - SCLogNotice("(%s) Treated: Pkts %" PRIu32 ", Bytes %" PRIu64 ", Errors %" PRIu32 "", - tv->name, nq->pkts, nq->bytes, nq->errs); - SCLogNotice("(%s) Verdict: Accepted %"PRIu32", Dropped %"PRIu32", Replaced %"PRIu32, - tv->name, nq->accepted, nq->dropped, nq->replaced); -#endif -} - -/** - * \brief NFQ verdict function - */ -TmEcode NFQSetVerdict(Packet *p) -{ - int iter = 0; - int ret = 0; - uint32_t verdict = NF_ACCEPT; - /* we could also have a direct pointer but we need to have a ref counf in this case */ - NFQQueueVars *t = nfq_q + p->nfq_v.nfq_index; - - /** \todo add a test on validity of the entry NFQQueueVars could have been - * wipeout - */ - - p->nfq_v.verdicted = 1; - - /* can't verdict a "fake" packet */ - if (p->flags & PKT_PSEUDO_STREAM_END) { - return TM_ECODE_OK; - } - - //printf("%p verdicting on queue %" PRIu32 "\n", t, t->queue_num); - NFQMutexLock(t); - - if (t->qh == NULL) { - /* Somebody has started a clean-up, we leave */ - NFQMutexUnlock(t); - return TM_ECODE_OK; - } - - if (PACKET_TEST_ACTION(p, ACTION_DROP)) { - verdict = NF_DROP; -#ifdef COUNTERS - t->dropped++; -#endif /* COUNTERS */ - } else { - switch (nfq_config.mode) { - default: - case NFQ_ACCEPT_MODE: - verdict = NF_ACCEPT; - break; - case NFQ_REPEAT_MODE: - verdict = NF_REPEAT; - break; - case NFQ_ROUTE_MODE: - verdict = ((uint32_t) NF_QUEUE) | nfq_config.next_queue; - break; - } - - if (p->flags & PKT_STREAM_MODIFIED) { -#ifdef COUNTERS - t->replaced++; -#endif /* COUNTERS */ - } - -#ifdef COUNTERS - t->accepted++; -#endif /* COUNTERS */ - } - - ret = NFQVerdictCacheAdd(t, p, verdict); - if (ret == 0) { - NFQMutexUnlock(t); - return TM_ECODE_OK; - } - - do { - switch (nfq_config.mode) { - default: - case NFQ_ACCEPT_MODE: - case NFQ_ROUTE_MODE: - if (p->flags & PKT_MARK_MODIFIED) { -#ifdef HAVE_NFQ_SET_VERDICT2 - if (p->flags & PKT_STREAM_MODIFIED) { - ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict, - p->nfq_v.mark, - GET_PKT_LEN(p), GET_PKT_DATA(p)); - } else { - ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict, - p->nfq_v.mark, - 0, NULL); - } -#else /* fall back to old function */ - if (p->flags & PKT_STREAM_MODIFIED) { - ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict, - htonl(p->nfq_v.mark), - GET_PKT_LEN(p), GET_PKT_DATA(p)); - } else { - ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict, - htonl(p->nfq_v.mark), - 0, NULL); - } -#endif /* HAVE_NFQ_SET_VERDICT2 */ - } else { - if (p->flags & PKT_STREAM_MODIFIED) { - ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, - GET_PKT_LEN(p), GET_PKT_DATA(p)); - } else { - ret = nfq_set_verdict(t->qh, p->nfq_v.id, verdict, 0, NULL); - } - - } - break; - case NFQ_REPEAT_MODE: -#ifdef HAVE_NFQ_SET_VERDICT2 - if (p->flags & PKT_STREAM_MODIFIED) { - ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict, - (nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask), - GET_PKT_LEN(p), GET_PKT_DATA(p)); - } else { - ret = nfq_set_verdict2(t->qh, p->nfq_v.id, verdict, - (nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask), - 0, NULL); - } -#else /* fall back to old function */ - if (p->flags & PKT_STREAM_MODIFIED) { - ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict, - htonl((nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask)), - GET_PKT_LEN(p), GET_PKT_DATA(p)); - } else { - ret = nfq_set_verdict_mark(t->qh, p->nfq_v.id, verdict, - htonl((nfq_config.mark & nfq_config.mask) | (p->nfq_v.mark & ~nfq_config.mask)), - 0, NULL); - } -#endif /* HAVE_NFQ_SET_VERDICT2 */ - break; - } - } while ((ret < 0) && (iter++ < NFQ_VERDICT_RETRY_TIME)); - - NFQMutexUnlock(t); - - if (ret < 0) { - SCLogWarning(SC_ERR_NFQ_SET_VERDICT, - "nfq_set_verdict of %p failed %" PRId32 ": %s", - p, ret, strerror(errno)); - return TM_ECODE_FAILED; - } - return TM_ECODE_OK; -} - -/** - * \brief NFQ verdict module packet entry function - */ -TmEcode VerdictNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - NFQThreadVars *ntv = (NFQThreadVars *)data; - /* update counters */ - CaptureStatsUpdate(tv, &ntv->stats, p); - - int ret; - /* if this is a tunnel packet we check if we are ready to verdict - * already. */ - if (IS_TUNNEL_PKT(p)) { - char verdict = 1; - //printf("VerdictNFQ: tunnel pkt: %p %s\n", p, p->root ? "upper layer" : "root"); - - SCMutex *m = p->root ? &p->root->tunnel_mutex : &p->tunnel_mutex; - SCMutexLock(m); - - /* if there are more tunnel packets than ready to verdict packets, - * we won't verdict this one */ - if (TUNNEL_PKT_TPR(p) > TUNNEL_PKT_RTV(p)) { - SCLogDebug("not ready to verdict yet: TUNNEL_PKT_TPR(p) > " - "TUNNEL_PKT_RTV(p) = %" PRId32 " > %" PRId32, - TUNNEL_PKT_TPR(p), TUNNEL_PKT_RTV(p)); - verdict = 0; - } - - SCMutexUnlock(m); - - /* don't verdict if we are not ready */ - if (verdict == 1) { - //printf("VerdictNFQ: setting verdict\n"); - ret = NFQSetVerdict(p->root ? p->root : p); - if (ret != TM_ECODE_OK) - return ret; - } else { - TUNNEL_INCR_PKT_RTV(p); - } - } else { - /* no tunnel, verdict normally */ - ret = NFQSetVerdict(p); - if (ret != TM_ECODE_OK) - return ret; - } - return TM_ECODE_OK; -} - -/** - * \brief Decode a packet coming from NFQ - */ -TmEcode DecodeNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - - IPV4Hdr *ip4h = (IPV4Hdr *)GET_PKT_DATA(p); - IPV6Hdr *ip6h = (IPV6Hdr *)GET_PKT_DATA(p); - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - DecodeUpdatePacketCounters(tv, dtv, p); - - if (IPV4_GET_RAW_VER(ip4h) == 4) { - SCLogDebug("IPv4 packet"); - DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - } else if(IPV6_GET_RAW_VER(ip6h) == 6) { - SCLogDebug("IPv6 packet"); - DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - } else { - SCLogDebug("packet unsupported by NFQ, first byte: %02x", *GET_PKT_DATA(p)); - } - - PacketDecodeFinalize(tv, dtv, p); - - return TM_ECODE_OK; -} - -/** - * \brief Initialize the NFQ Decode threadvars - */ -TmEcode DecodeNFQThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - DecodeThreadVars *dtv = NULL; - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - - return TM_ECODE_OK; -} - -TmEcode DecodeNFQThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -#endif /* NFQ */ - diff --git a/framework/src/suricata/src/source-nfq.h b/framework/src/suricata/src/source-nfq.h deleted file mode 100644 index 41a54b78..00000000 --- a/framework/src/suricata/src/source-nfq.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __SOURCE_NFQ_H__ -#define __SOURCE_NFQ_H__ - -#ifdef NFQ - -#include "threads.h" -#ifdef OS_WIN32 -#include -#else -#include /* for NF_ACCEPT */ -#endif -#include - -#define NFQ_MAX_QUEUE 16 - -/* idea: set the recv-thread id in the packet to - * select an verdict-queue */ - -typedef struct NFQPacketVars_ -{ - int id; /* this nfq packets id */ - uint16_t nfq_index; /* index in NFQ array */ - uint8_t verdicted; - - uint32_t mark; - uint32_t ifi; - uint32_t ifo; - uint16_t hw_protocol; -} NFQPacketVars; - -typedef struct NFQQueueVars_ -{ - struct nfq_handle *h; -#ifndef OS_WIN32 - struct nfnl_handle *nh; - int fd; -#else - HANDLE fd; - OVERLAPPED ovr; -#endif - uint8_t use_mutex; - /* 2 threads deal with the queue handle, so add a mutex */ - struct nfq_q_handle *qh; - SCMutex mutex_qh; - /* this one should be not changing after init */ - uint16_t queue_num; - /* position into the NFQ queue var array */ - uint16_t nfq_index; - -#ifdef DBG_PERF - int dbg_maxreadsize; -#endif /* DBG_PERF */ - - /* counters */ - uint32_t pkts; - uint64_t bytes; - uint32_t errs; - uint32_t accepted; - uint32_t dropped; - uint32_t replaced; - struct { - uint32_t packet_id; /* id of last processed packet */ - uint32_t verdict; - uint32_t mark; - uint8_t mark_valid:1; - uint8_t len; - uint8_t maxlen; - } verdict_cache; - -} NFQQueueVars; - - - -typedef struct NFQGlobalVars_ -{ - char unbind; -} NFQGlobalVars; - -void NFQInitConfig(char quiet); -int NFQRegisterQueue(char *queue); -int NFQGetQueueCount(void); -void *NFQGetQueue(int number); -int NFQGetQueueNum(int number); -void *NFQGetThread(int number); -#endif /* NFQ */ -#endif /* __SOURCE_NFQ_H__ */ - diff --git a/framework/src/suricata/src/source-pcap-file.c b/framework/src/suricata/src/source-pcap-file.c deleted file mode 100644 index 0b982fd3..00000000 --- a/framework/src/suricata/src/source-pcap-file.c +++ /dev/null @@ -1,475 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * File based pcap packet acquisition support - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "source-pcap-file.h" -#include "util-time.h" -#include "util-debug.h" -#include "conf.h" -#include "util-error.h" -#include "util-privs.h" -#include "tmqh-packetpool.h" -#include "tm-threads.h" -#include "util-optimize.h" -#include "flow-manager.h" -#include "util-profiling.h" -#include "runmode-unix-socket.h" -#include "util-checksum.h" -#include "util-atomic.h" - -#ifdef __SC_CUDA_SUPPORT__ - -#include "util-cuda.h" -#include "util-cuda-buffer.h" -#include "util-mpm-ac.h" -#include "util-cuda-handlers.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "util-cuda-vars.h" - -#endif /* __SC_CUDA_SUPPORT__ */ - -extern int max_pending_packets; - -//static int pcap_max_read_packets = 0; - -typedef struct PcapFileGlobalVars_ { - pcap_t *pcap_handle; - int (*Decoder)(ThreadVars *, DecodeThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); - int datalink; - struct bpf_program filter; - uint64_t cnt; /** packet counter */ - ChecksumValidationMode conf_checksum_mode; - ChecksumValidationMode checksum_mode; - SC_ATOMIC_DECLARE(unsigned int, invalid_checksums); - -} PcapFileGlobalVars; - -/** max packets < 65536 */ -//#define PCAP_FILE_MAX_PKTS 256 - -typedef struct PcapFileThreadVars_ -{ - uint32_t tenant_id; - - /* counters */ - uint32_t pkts; - uint64_t bytes; - - ThreadVars *tv; - TmSlot *slot; - - /** callback result -- set if one of the thread module failed. */ - int cb_result; - - uint8_t done; - uint32_t errs; -} PcapFileThreadVars; - -static PcapFileGlobalVars pcap_g; - -TmEcode ReceivePcapFileLoop(ThreadVars *, void *, void *); - -TmEcode ReceivePcapFileThreadInit(ThreadVars *, void *, void **); -void ReceivePcapFileThreadExitStats(ThreadVars *, void *); -TmEcode ReceivePcapFileThreadDeinit(ThreadVars *, void *); - -TmEcode DecodePcapFile(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode DecodePcapFileThreadInit(ThreadVars *, void *, void **); -TmEcode DecodePcapFileThreadDeinit(ThreadVars *tv, void *data); - -void TmModuleReceivePcapFileRegister (void) -{ - memset(&pcap_g, 0x00, sizeof(pcap_g)); - - tmm_modules[TMM_RECEIVEPCAPFILE].name = "ReceivePcapFile"; - tmm_modules[TMM_RECEIVEPCAPFILE].ThreadInit = ReceivePcapFileThreadInit; - tmm_modules[TMM_RECEIVEPCAPFILE].Func = NULL; - tmm_modules[TMM_RECEIVEPCAPFILE].PktAcqLoop = ReceivePcapFileLoop; - tmm_modules[TMM_RECEIVEPCAPFILE].ThreadExitPrintStats = ReceivePcapFileThreadExitStats; - tmm_modules[TMM_RECEIVEPCAPFILE].ThreadDeinit = ReceivePcapFileThreadDeinit; - tmm_modules[TMM_RECEIVEPCAPFILE].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEPCAPFILE].cap_flags = 0; - tmm_modules[TMM_RECEIVEPCAPFILE].flags = TM_FLAG_RECEIVE_TM; -} - -void TmModuleDecodePcapFileRegister (void) -{ - tmm_modules[TMM_DECODEPCAPFILE].name = "DecodePcapFile"; - tmm_modules[TMM_DECODEPCAPFILE].ThreadInit = DecodePcapFileThreadInit; - tmm_modules[TMM_DECODEPCAPFILE].Func = DecodePcapFile; - tmm_modules[TMM_DECODEPCAPFILE].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEPCAPFILE].ThreadDeinit = DecodePcapFileThreadDeinit; - tmm_modules[TMM_DECODEPCAPFILE].RegisterTests = NULL; - tmm_modules[TMM_DECODEPCAPFILE].cap_flags = 0; - tmm_modules[TMM_DECODEPCAPFILE].flags = TM_FLAG_DECODE_TM; -} - -void PcapFileGlobalInit() -{ - SC_ATOMIC_INIT(pcap_g.invalid_checksums); -} - -void PcapFileCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt) -{ - SCEnter(); - - PcapFileThreadVars *ptv = (PcapFileThreadVars *)user; - Packet *p = PacketGetFromQueueOrAlloc(); - - if (unlikely(p == NULL)) { - SCReturn; - } - PACKET_PROFILING_TMM_START(p, TMM_RECEIVEPCAPFILE); - - PKT_SET_SRC(p, PKT_SRC_WIRE); - p->ts.tv_sec = h->ts.tv_sec; - p->ts.tv_usec = h->ts.tv_usec; - SCLogDebug("p->ts.tv_sec %"PRIuMAX"", (uintmax_t)p->ts.tv_sec); - p->datalink = pcap_g.datalink; - p->pcap_cnt = ++pcap_g.cnt; - - p->pcap_v.tenant_id = ptv->tenant_id; - ptv->pkts++; - ptv->bytes += h->caplen; - - if (unlikely(PacketCopyData(p, pkt, h->caplen))) { - TmqhOutputPacketpool(ptv->tv, p); - PACKET_PROFILING_TMM_END(p, TMM_RECEIVEPCAPFILE); - SCReturn; - } - - /* We only check for checksum disable */ - if (pcap_g.checksum_mode == CHECKSUM_VALIDATION_DISABLE) { - p->flags |= PKT_IGNORE_CHECKSUM; - } else if (pcap_g.checksum_mode == CHECKSUM_VALIDATION_AUTO) { - if (ChecksumAutoModeCheck(ptv->pkts, p->pcap_cnt, - SC_ATOMIC_GET(pcap_g.invalid_checksums))) { - pcap_g.checksum_mode = CHECKSUM_VALIDATION_DISABLE; - p->flags |= PKT_IGNORE_CHECKSUM; - } - } - - PACKET_PROFILING_TMM_END(p, TMM_RECEIVEPCAPFILE); - - if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { - pcap_breakloop(pcap_g.pcap_handle); - ptv->cb_result = TM_ECODE_FAILED; - } - - SCReturn; -} - -/** - * \brief Main PCAP file reading Loop function - */ -TmEcode ReceivePcapFileLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - int packet_q_len = 64; - PcapFileThreadVars *ptv = (PcapFileThreadVars *)data; - int r; - TmSlot *s = (TmSlot *)slot; - - ptv->slot = s->slot_next; - ptv->cb_result = TM_ECODE_OK; - - while (1) { - if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) { - SCReturnInt(TM_ECODE_OK); - } - - /* make sure we have at least one packet in the packet pool, to prevent - * us from alloc'ing packets at line rate */ - PacketPoolWait(); - - /* Right now we just support reading packets one at a time. */ - r = pcap_dispatch(pcap_g.pcap_handle, packet_q_len, - (pcap_handler)PcapFileCallbackLoop, (u_char *)ptv); - if (unlikely(r == -1)) { - SCLogError(SC_ERR_PCAP_DISPATCH, "error code %" PRId32 " %s", - r, pcap_geterr(pcap_g.pcap_handle)); - if (! RunModeUnixSocketIsActive()) { - /* in the error state we just kill the engine */ - EngineKill(); - SCReturnInt(TM_ECODE_FAILED); - } else { - pcap_close(pcap_g.pcap_handle); - pcap_g.pcap_handle = NULL; - UnixSocketPcapFile(TM_ECODE_DONE); - SCReturnInt(TM_ECODE_DONE); - } - } else if (unlikely(r == 0)) { - SCLogInfo("pcap file end of file reached (pcap err code %" PRId32 ")", r); - if (! RunModeUnixSocketIsActive()) { - EngineStop(); - } else { - pcap_close(pcap_g.pcap_handle); - pcap_g.pcap_handle = NULL; - UnixSocketPcapFile(TM_ECODE_DONE); - SCReturnInt(TM_ECODE_DONE); - } - break; - } else if (ptv->cb_result == TM_ECODE_FAILED) { - SCLogError(SC_ERR_PCAP_DISPATCH, "Pcap callback PcapFileCallbackLoop failed"); - if (! RunModeUnixSocketIsActive()) { - EngineKill(); - SCReturnInt(TM_ECODE_FAILED); - } else { - pcap_close(pcap_g.pcap_handle); - pcap_g.pcap_handle = NULL; - UnixSocketPcapFile(TM_ECODE_DONE); - SCReturnInt(TM_ECODE_DONE); - } - } - StatsSyncCountersIfSignalled(tv); - } - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode ReceivePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - char *tmpbpfstring = NULL; - char *tmpstring = NULL; - if (initdata == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "error: initdata == NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - SCLogInfo("reading pcap file %s", (char *)initdata); - - PcapFileThreadVars *ptv = SCMalloc(sizeof(PcapFileThreadVars)); - if (unlikely(ptv == NULL)) - SCReturnInt(TM_ECODE_FAILED); - memset(ptv, 0, sizeof(PcapFileThreadVars)); - - intmax_t tenant = 0; - if (ConfGetInt("pcap-file.tenant-id", &tenant) == 1) { - if (tenant > 0 && tenant < UINT_MAX) { - ptv->tenant_id = (uint32_t)tenant; - SCLogInfo("tenant %u", ptv->tenant_id); - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "tenant out of range"); - } - } - - char errbuf[PCAP_ERRBUF_SIZE] = ""; - pcap_g.pcap_handle = pcap_open_offline((char *)initdata, errbuf); - if (pcap_g.pcap_handle == NULL) { - SCLogError(SC_ERR_FOPEN, "%s\n", errbuf); - SCFree(ptv); - if (! RunModeUnixSocketIsActive()) { - return TM_ECODE_FAILED; - } else { - UnixSocketPcapFile(TM_ECODE_FAILED); - SCReturnInt(TM_ECODE_DONE); - } - } - - if (ConfGet("bpf-filter", &tmpbpfstring) != 1) { - SCLogDebug("could not get bpf or none specified"); - } else { - SCLogInfo("using bpf-filter \"%s\"", tmpbpfstring); - - if(pcap_compile(pcap_g.pcap_handle,&pcap_g.filter,tmpbpfstring,1,0) < 0) { - SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(pcap_g.pcap_handle)); - SCFree(ptv); - return TM_ECODE_FAILED; - } - - if(pcap_setfilter(pcap_g.pcap_handle,&pcap_g.filter) < 0) { - SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(pcap_g.pcap_handle)); - SCFree(ptv); - return TM_ECODE_FAILED; - } - } - - pcap_g.datalink = pcap_datalink(pcap_g.pcap_handle); - SCLogDebug("datalink %" PRId32 "", pcap_g.datalink); - - switch(pcap_g.datalink) { - case LINKTYPE_LINUX_SLL: - pcap_g.Decoder = DecodeSll; - break; - case LINKTYPE_ETHERNET: - pcap_g.Decoder = DecodeEthernet; - break; - case LINKTYPE_PPP: - pcap_g.Decoder = DecodePPP; - break; - case LINKTYPE_RAW: - pcap_g.Decoder = DecodeRaw; - break; - case LINKTYPE_NULL: - pcap_g.Decoder = DecodeNull; - break; - - default: - SCLogError(SC_ERR_UNIMPLEMENTED, "datalink type %" PRId32 " not " - "(yet) supported in module PcapFile.\n", pcap_g.datalink); - SCFree(ptv); - if (! RunModeUnixSocketIsActive()) { - SCReturnInt(TM_ECODE_FAILED); - } else { - pcap_close(pcap_g.pcap_handle); - pcap_g.pcap_handle = NULL; - UnixSocketPcapFile(TM_ECODE_DONE); - SCReturnInt(TM_ECODE_DONE); - } - } - - if (ConfGet("pcap-file.checksum-checks", &tmpstring) != 1) { - pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_AUTO; - } else { - if (strcmp(tmpstring, "auto") == 0) { - pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_AUTO; - } else if (strcmp(tmpstring, "yes") == 0) { - pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_ENABLE; - } else if (strcmp(tmpstring, "no") == 0) { - pcap_g.conf_checksum_mode = CHECKSUM_VALIDATION_DISABLE; - } - } - pcap_g.checksum_mode = pcap_g.conf_checksum_mode; - - ptv->tv = tv; - *data = (void *)ptv; - - SCReturnInt(TM_ECODE_OK); -} - -void ReceivePcapFileThreadExitStats(ThreadVars *tv, void *data) -{ - SCEnter(); - PcapFileThreadVars *ptv = (PcapFileThreadVars *)data; - - if (pcap_g.conf_checksum_mode == CHECKSUM_VALIDATION_AUTO && - pcap_g.cnt < CHECKSUM_SAMPLE_COUNT && - SC_ATOMIC_GET(pcap_g.invalid_checksums)) { - uint64_t chrate = pcap_g.cnt / SC_ATOMIC_GET(pcap_g.invalid_checksums); - if (chrate < CHECKSUM_INVALID_RATIO) - SCLogWarning(SC_ERR_INVALID_CHECKSUM, - "1/%" PRIu64 "th of packets have an invalid checksum," - " consider setting pcap-file.checksum-checks variable to no" - " or use '-k none' option on command line.", - chrate); - else - SCLogInfo("1/%" PRIu64 "th of packets have an invalid checksum", - chrate); - } - SCLogNotice("Pcap-file module read %" PRIu32 " packets, %" PRIu64 " bytes", ptv->pkts, ptv->bytes); - return; -} - -TmEcode ReceivePcapFileThreadDeinit(ThreadVars *tv, void *data) -{ - SCEnter(); - PcapFileThreadVars *ptv = (PcapFileThreadVars *)data; - if (ptv) { - SCFree(ptv); - } - SCReturnInt(TM_ECODE_OK); -} - -double prev_signaled_ts = 0; - -TmEcode DecodePcapFile(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - SCEnter(); - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - double curr_ts = p->ts.tv_sec + p->ts.tv_usec / 1000.0; - if (curr_ts < prev_signaled_ts || (curr_ts - prev_signaled_ts) > 60.0) { - prev_signaled_ts = curr_ts; - FlowWakeupFlowManagerThread(); - } - - /* update the engine time representation based on the timestamp - * of the packet. */ - TimeSet(&p->ts); - - /* call the decoder */ - pcap_g.Decoder(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - -#ifdef DEBUG - BUG_ON(p->pkt_src != PKT_SRC_WIRE && p->pkt_src != PKT_SRC_FFR); -#endif - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - DecodeThreadVars *dtv = NULL; - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - -#ifdef __SC_CUDA_SUPPORT__ - if (CudaThreadVarsInit(&dtv->cuda_vars) < 0) - SCReturnInt(TM_ECODE_FAILED); -#endif - - *data = (void *)dtv; - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodePcapFileThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -void PcapIncreaseInvalidChecksum() -{ - (void) SC_ATOMIC_ADD(pcap_g.invalid_checksums, 1); -} - -/* eof */ - diff --git a/framework/src/suricata/src/source-pcap-file.h b/framework/src/suricata/src/source-pcap-file.h deleted file mode 100644 index fa76a1a8..00000000 --- a/framework/src/suricata/src/source-pcap-file.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __SOURCE_PCAP_FILE_H__ -#define __SOURCE_PCAP_FILE_H__ - -void TmModuleReceivePcapFileRegister (void); -void TmModuleDecodePcapFileRegister (void); - -void PcapIncreaseInvalidChecksum(); - -void PcapFileGlobalInit(); - -#endif /* __SOURCE_PCAP_FILE_H__ */ - diff --git a/framework/src/suricata/src/source-pcap.c b/framework/src/suricata/src/source-pcap.c deleted file mode 100644 index 0656f958..00000000 --- a/framework/src/suricata/src/source-pcap.c +++ /dev/null @@ -1,826 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Live pcap packet acquisition support - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "source-pcap.h" -#include "conf.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-privs.h" -#include "util-device.h" -#include "util-optimize.h" -#include "util-checksum.h" -#include "util-ioctl.h" -#include "tmqh-packetpool.h" - -#ifdef __SC_CUDA_SUPPORT__ - -#include "util-cuda.h" -#include "util-cuda-buffer.h" -#include "util-mpm-ac.h" -#include "util-cuda-handlers.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "util-cuda-vars.h" - -#endif /* __SC_CUDA_SUPPORT__ */ - -#define PCAP_STATE_DOWN 0 -#define PCAP_STATE_UP 1 - -#define PCAP_RECONNECT_TIMEOUT 500000 - -/** - * \brief Structure to hold thread specific variables. - */ -typedef struct PcapThreadVars_ -{ - /* thread specific handle */ - pcap_t *pcap_handle; - /* handle state */ - unsigned char pcap_state; - /* thread specific bpf */ - struct bpf_program filter; - /* ptr to string from config */ - char *bpf_filter; - - time_t last_stats_dump; - - /* data link type for the thread */ - int datalink; - - /* counters */ - uint32_t pkts; - uint64_t bytes; - uint32_t errs; - - uint16_t capture_kernel_packets; - uint16_t capture_kernel_drops; - uint16_t capture_kernel_ifdrops; - - ThreadVars *tv; - TmSlot *slot; - - /** callback result -- set if one of the thread module failed. */ - int cb_result; - - /* pcap buffer size */ - int pcap_buffer_size; - int pcap_snaplen; - - ChecksumValidationMode checksum_mode; - -#if LIBPCAP_VERSION_MAJOR == 0 - char iface[PCAP_IFACE_NAME_LENGTH]; -#endif - LiveDevice *livedev; -} PcapThreadVars; - -TmEcode ReceivePcapThreadInit(ThreadVars *, void *, void **); -void ReceivePcapThreadExitStats(ThreadVars *, void *); -TmEcode ReceivePcapThreadDeinit(ThreadVars *, void *); -TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot); - -TmEcode DecodePcapThreadInit(ThreadVars *, void *, void **); -TmEcode DecodePcapThreadDeinit(ThreadVars *tv, void *data); -TmEcode DecodePcap(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); - -/** protect pcap_compile and pcap_setfilter, as they are not thread safe: - * http://seclists.org/tcpdump/2009/q1/62 */ -static SCMutex pcap_bpf_compile_lock = SCMUTEX_INITIALIZER; - -/** - * \brief Registration Function for RecievePcap. - * \todo Unit tests are needed for this module. - */ -void TmModuleReceivePcapRegister (void) -{ - tmm_modules[TMM_RECEIVEPCAP].name = "ReceivePcap"; - tmm_modules[TMM_RECEIVEPCAP].ThreadInit = ReceivePcapThreadInit; - tmm_modules[TMM_RECEIVEPCAP].Func = NULL; - tmm_modules[TMM_RECEIVEPCAP].PktAcqLoop = ReceivePcapLoop; - tmm_modules[TMM_RECEIVEPCAP].ThreadExitPrintStats = ReceivePcapThreadExitStats; - tmm_modules[TMM_RECEIVEPCAP].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEPCAP].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEPCAP].cap_flags = SC_CAP_NET_RAW; - tmm_modules[TMM_RECEIVEPCAP].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Registration Function for DecodePcap. - * \todo Unit tests are needed for this module. - */ -void TmModuleDecodePcapRegister (void) -{ - tmm_modules[TMM_DECODEPCAP].name = "DecodePcap"; - tmm_modules[TMM_DECODEPCAP].ThreadInit = DecodePcapThreadInit; - tmm_modules[TMM_DECODEPCAP].Func = DecodePcap; - tmm_modules[TMM_DECODEPCAP].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEPCAP].ThreadDeinit = DecodePcapThreadDeinit; - tmm_modules[TMM_DECODEPCAP].RegisterTests = NULL; - tmm_modules[TMM_DECODEPCAP].cap_flags = 0; - tmm_modules[TMM_DECODEPCAP].flags = TM_FLAG_DECODE_TM; -} - -static inline void PcapDumpCounters(PcapThreadVars *ptv) -{ - struct pcap_stat pcap_s; - if (likely((pcap_stats(ptv->pcap_handle, &pcap_s) >= 0))) { - StatsSetUI64(ptv->tv, ptv->capture_kernel_packets, pcap_s.ps_recv); - StatsSetUI64(ptv->tv, ptv->capture_kernel_drops, pcap_s.ps_drop); - (void) SC_ATOMIC_SET(ptv->livedev->drop, pcap_s.ps_drop); - StatsSetUI64(ptv->tv, ptv->capture_kernel_ifdrops, pcap_s.ps_ifdrop); - } -} - - -#if LIBPCAP_VERSION_MAJOR == 1 -static int PcapTryReopen(PcapThreadVars *ptv) -{ - int pcap_activate_r; - - ptv->pcap_state = PCAP_STATE_DOWN; - pcap_activate_r = pcap_activate(ptv->pcap_handle); - if (pcap_activate_r != 0) { - return pcap_activate_r; - } - /* set bpf filter if we have one */ - if (ptv->bpf_filter != NULL) { - if(pcap_compile(ptv->pcap_handle,&ptv->filter,ptv->bpf_filter,1,0) < 0) { - SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle)); - return -1; - } - - if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { - SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle)); - return -1; - } - } - - SCLogInfo("Recovering interface listening"); - ptv->pcap_state = PCAP_STATE_UP; - return 0; -} -#else /* implied LIBPCAP_VERSION_MAJOR == 0 */ -static int PcapTryReopen(PcapThreadVars *ptv) -{ - char errbuf[PCAP_ERRBUF_SIZE] = ""; - - ptv->pcap_state = PCAP_STATE_DOWN; - pcap_close(ptv->pcap_handle); - - ptv->pcap_handle = pcap_open_live((char *)ptv->iface, ptv->pcap_snaplen, - LIBPCAP_PROMISC, LIBPCAP_COPYWAIT, errbuf); - if (ptv->pcap_handle == NULL) { - SCLogError(SC_ERR_PCAP_OPEN_LIVE, "Problem creating pcap handler for live mode, error %s", errbuf); - return -1; - } - - /* set bpf filter if we have one */ - if (ptv->bpf_filter != NULL) { - SCLogInfo("using bpf-filter \"%s\"", ptv->bpf_filter); - - if(pcap_compile(ptv->pcap_handle,&ptv->filter,ptv->bpf_filter,1,0) < 0) { - SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle)); - return -1; - } - - if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { - SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle)); - return -1; - } - } - - SCLogInfo("Recovering interface listening"); - ptv->pcap_state = PCAP_STATE_UP; - return 0; -} - -#endif - -void PcapCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt) -{ - SCEnter(); - - PcapThreadVars *ptv = (PcapThreadVars *)user; - Packet *p = PacketGetFromQueueOrAlloc(); - struct timeval current_time; - - if (unlikely(p == NULL)) { - SCReturn; - } - - PKT_SET_SRC(p, PKT_SRC_WIRE); - p->ts.tv_sec = h->ts.tv_sec; - p->ts.tv_usec = h->ts.tv_usec; - SCLogDebug("p->ts.tv_sec %"PRIuMAX"", (uintmax_t)p->ts.tv_sec); - p->datalink = ptv->datalink; - - ptv->pkts++; - ptv->bytes += h->caplen; - (void) SC_ATOMIC_ADD(ptv->livedev->pkts, 1); - p->livedev = ptv->livedev; - - if (unlikely(PacketCopyData(p, pkt, h->caplen))) { - TmqhOutputPacketpool(ptv->tv, p); - SCReturn; - } - - switch (ptv->checksum_mode) { - case CHECKSUM_VALIDATION_AUTO: - if (ptv->livedev->ignore_checksum) { - p->flags |= PKT_IGNORE_CHECKSUM; - } else if (ChecksumAutoModeCheck(ptv->pkts, - SC_ATOMIC_GET(ptv->livedev->pkts), - SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) { - ptv->livedev->ignore_checksum = 1; - p->flags |= PKT_IGNORE_CHECKSUM; - } - break; - case CHECKSUM_VALIDATION_DISABLE: - p->flags |= PKT_IGNORE_CHECKSUM; - break; - default: - break; - } - - if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { - pcap_breakloop(ptv->pcap_handle); - ptv->cb_result = TM_ECODE_FAILED; - } - - /* Trigger one dump of stats every second */ - TimeGet(¤t_time); - if (current_time.tv_sec != ptv->last_stats_dump) { - PcapDumpCounters(ptv); - ptv->last_stats_dump = current_time.tv_sec; - } - - SCReturn; -} - -/** - * \brief Main PCAP reading Loop function - */ -TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - int packet_q_len = 64; - PcapThreadVars *ptv = (PcapThreadVars *)data; - int r; - TmSlot *s = (TmSlot *)slot; - - ptv->slot = s->slot_next; - ptv->cb_result = TM_ECODE_OK; - - while (1) { - if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) { - SCReturnInt(TM_ECODE_OK); - } - - /* make sure we have at least one packet in the packet pool, to prevent - * us from alloc'ing packets at line rate */ - PacketPoolWait(); - - /* Right now we just support reading packets one at a time. */ - r = pcap_dispatch(ptv->pcap_handle, packet_q_len, - (pcap_handler)PcapCallbackLoop, (u_char *)ptv); - if (unlikely(r < 0)) { - int dbreak = 0; - SCLogError(SC_ERR_PCAP_DISPATCH, "error code %" PRId32 " %s", - r, pcap_geterr(ptv->pcap_handle)); -#ifdef PCAP_ERROR_BREAK - if (r == PCAP_ERROR_BREAK) { - SCReturnInt(ptv->cb_result); - } -#endif - do { - usleep(PCAP_RECONNECT_TIMEOUT); - if (suricata_ctl_flags != 0) { - dbreak = 1; - break; - } - r = PcapTryReopen(ptv); - } while (r < 0); - if (dbreak) { - break; - } - } else if (ptv->cb_result == TM_ECODE_FAILED) { - SCLogError(SC_ERR_PCAP_DISPATCH, "Pcap callback PcapCallbackLoop failed"); - SCReturnInt(TM_ECODE_FAILED); - } - - StatsSyncCountersIfSignalled(tv); - } - - PcapDumpCounters(ptv); - StatsSyncCountersIfSignalled(tv); - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Init function for ReceivePcap. - * - * This is a setup function for recieving packets - * via libpcap. There are two versions of this function - * depending on the major version of libpcap used. - * For versions prior to 1.x we use open_pcap_live, - * for versions 1.x and greater we use pcap_create + pcap_activate. - * - * \param tv pointer to ThreadVars - * \param initdata pointer to the interface passed from the user - * \param data pointer gets populated with PcapThreadVars - * - * \todo Create a general pcap setup function. - */ -#if LIBPCAP_VERSION_MAJOR == 1 -TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - PcapIfaceConfig *pcapconfig = initdata; - - if (initdata == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars)); - if (unlikely(ptv == NULL)) { - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } - memset(ptv, 0, sizeof(PcapThreadVars)); - - ptv->tv = tv; - - ptv->livedev = LiveGetDevice(pcapconfig->iface); - if (ptv->livedev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); - SCFree(ptv); - SCReturnInt(TM_ECODE_FAILED); - } - - SCLogInfo("using interface %s", (char *)pcapconfig->iface); - - ptv->checksum_mode = pcapconfig->checksum_mode; - if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) { - SCLogInfo("Running in 'auto' checksum mode. Detection of interface state will require " - xstr(CHECKSUM_SAMPLE_COUNT) " packets."); - } - - /* XXX create a general pcap setup function */ - char errbuf[PCAP_ERRBUF_SIZE]; - ptv->pcap_handle = pcap_create((char *)pcapconfig->iface, errbuf); - if (ptv->pcap_handle == NULL) { - if (strlen(errbuf)) { - SCLogError(SC_ERR_PCAP_CREATE, "Couldn't create a new pcap handler for %s, error %s", - (char *)pcapconfig->iface, errbuf); - } else { - SCLogError(SC_ERR_PCAP_CREATE, "Couldn't create a new pcap handler for %s", - (char *)pcapconfig->iface); - } - SCFree(ptv); - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } - - if (pcapconfig->snaplen == 0) { - /* We set snaplen if we can get the MTU */ - ptv->pcap_snaplen = GetIfaceMaxPacketSize(pcapconfig->iface); - } else { - ptv->pcap_snaplen = pcapconfig->snaplen; - } - if (ptv->pcap_snaplen > 0) { - /* set Snaplen. Must be called before pcap_activate */ - int pcap_set_snaplen_r = pcap_set_snaplen(ptv->pcap_handle, ptv->pcap_snaplen); - if (pcap_set_snaplen_r != 0) { - SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "Couldn't set snaplen, error: %s", pcap_geterr(ptv->pcap_handle)); - SCFree(ptv); - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } - SCLogInfo("Set snaplen to %d for '%s'", ptv->pcap_snaplen, - pcapconfig->iface); - } - - /* set Promisc, and Timeout. Must be called before pcap_activate */ - int pcap_set_promisc_r = pcap_set_promisc(ptv->pcap_handle, pcapconfig->promisc); - //printf("ReceivePcapThreadInit: pcap_set_promisc(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_promisc_r); - if (pcap_set_promisc_r != 0) { - SCLogError(SC_ERR_PCAP_SET_PROMISC, "Couldn't set promisc mode, error %s", pcap_geterr(ptv->pcap_handle)); - SCFree(ptv); - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } - - int pcap_set_timeout_r = pcap_set_timeout(ptv->pcap_handle,LIBPCAP_COPYWAIT); - //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_timeout_r); - if (pcap_set_timeout_r != 0) { - SCLogError(SC_ERR_PCAP_SET_TIMEOUT, "Problems setting timeout, error %s", pcap_geterr(ptv->pcap_handle)); - SCFree(ptv); - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } -#ifdef HAVE_PCAP_SET_BUFF - ptv->pcap_buffer_size = pcapconfig->buffer_size; - if (ptv->pcap_buffer_size >= 0 && ptv->pcap_buffer_size <= INT_MAX) { - if (ptv->pcap_buffer_size > 0) - SCLogInfo("Going to use pcap buffer size of %" PRId32 "", ptv->pcap_buffer_size); - - int pcap_set_buffer_size_r = pcap_set_buffer_size(ptv->pcap_handle,ptv->pcap_buffer_size); - //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_buffer_size_r); - if (pcap_set_buffer_size_r != 0) { - SCLogError(SC_ERR_PCAP_SET_BUFF_SIZE, "Problems setting pcap buffer size, error %s", pcap_geterr(ptv->pcap_handle)); - SCFree(ptv); - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } - } -#endif /* HAVE_PCAP_SET_BUFF */ - - /* activate the handle */ - int pcap_activate_r = pcap_activate(ptv->pcap_handle); - //printf("ReceivePcapThreadInit: pcap_activate(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_activate_r); - if (pcap_activate_r != 0) { - SCLogError(SC_ERR_PCAP_ACTIVATE_HANDLE, "Couldn't activate the pcap handler, error %s", pcap_geterr(ptv->pcap_handle)); - SCFree(ptv); - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } else { - ptv->pcap_state = PCAP_STATE_UP; - } - - /* set bpf filter if we have one */ - if (pcapconfig->bpf_filter) { - SCMutexLock(&pcap_bpf_compile_lock); - - ptv->bpf_filter = pcapconfig->bpf_filter; - - if (pcap_compile(ptv->pcap_handle,&ptv->filter,ptv->bpf_filter,1,0) < 0) { - SCLogError(SC_ERR_BPF, "bpf compilation error %s", pcap_geterr(ptv->pcap_handle)); - - SCMutexUnlock(&pcap_bpf_compile_lock); - SCFree(ptv); - pcapconfig->DerefFunc(pcapconfig); - return TM_ECODE_FAILED; - } - - if (pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { - SCLogError(SC_ERR_BPF, "could not set bpf filter %s", pcap_geterr(ptv->pcap_handle)); - - SCMutexUnlock(&pcap_bpf_compile_lock); - SCFree(ptv); - pcapconfig->DerefFunc(pcapconfig); - return TM_ECODE_FAILED; - } - - SCMutexUnlock(&pcap_bpf_compile_lock); - } - - /* Making it conditional to Linux even if GetIfaceOffloading return 0 - * for non Linux. */ -#ifdef HAVE_LINUX_ETHTOOL_H - if (GetIfaceOffloading(pcapconfig->iface) == 1) { - SCLogWarning(SC_ERR_PCAP_CREATE, - "Using Pcap capture with GRO or LRO activated can lead to " - "capture problems."); - } -#endif /* HAVE_LINUX_ETHTOOL_H */ - - ptv->datalink = pcap_datalink(ptv->pcap_handle); - - pcapconfig->DerefFunc(pcapconfig); - - ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", - ptv->tv); - ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops", - ptv->tv); - ptv->capture_kernel_ifdrops = StatsRegisterCounter("capture.kernel_ifdrops", - ptv->tv); - - *data = (void *)ptv; - SCReturnInt(TM_ECODE_OK); -} -#else /* implied LIBPCAP_VERSION_MAJOR == 0 */ -TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - PcapIfaceConfig *pcapconfig = initdata; - - if (initdata == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); - SCReturnInt(TM_ECODE_FAILED); - } - - PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars)); - if (unlikely(ptv == NULL)) { - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } - memset(ptv, 0, sizeof(PcapThreadVars)); - - ptv->tv = tv; - - ptv->livedev = LiveGetDevice(pcapconfig->iface); - if (ptv->livedev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); - SCReturnInt(TM_ECODE_FAILED); - } - - SCLogInfo("using interface %s", pcapconfig->iface); - if (strlen(pcapconfig->iface) > PCAP_IFACE_NAME_LENGTH) { - SCFree(ptv); - /* Dereference config */ - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } - strlcpy(ptv->iface, pcapconfig->iface, PCAP_IFACE_NAME_LENGTH); - - if (pcapconfig->snaplen == 0) { - /* We try to set snaplen from MTU value */ - ptv->pcap_snaplen = GetIfaceMaxPacketSize(pcapconfig->iface); - /* be conservative with old pcap lib to mimic old tcpdump behavior - when MTU was not available. */ - if (ptv->pcap_snaplen <= 0) - ptv->pcap_snaplen = LIBPCAP_SNAPLEN; - } else { - ptv->pcap_snaplen = pcapconfig->snaplen; - } - - char errbuf[PCAP_ERRBUF_SIZE] = ""; - ptv->pcap_handle = pcap_open_live(ptv->iface, ptv->pcap_snaplen, - LIBPCAP_PROMISC, LIBPCAP_COPYWAIT, errbuf); - if (ptv->pcap_handle == NULL) { - SCLogError(SC_ERR_PCAP_OPEN_LIVE, "Problem creating pcap handler for live mode, error %s", errbuf); - SCFree(ptv); - /* Dereference config */ - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); - } - - /* set bpf filter if we have one */ - if (pcapconfig->bpf_filter) { - SCMutexLock(&pcap_bpf_compile_lock); - - ptv->bpf_filter = pcapconfig->bpf_filter; - SCLogInfo("using bpf-filter \"%s\"", ptv->bpf_filter); - - if(pcap_compile(ptv->pcap_handle,&ptv->filter, ptv->bpf_filter,1,0) < 0) { - SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle)); - - SCMutexUnlock(&pcap_bpf_compile_lock); - SCFree(ptv); - /* Dereference config */ - pcapconfig->DerefFunc(pcapconfig); - return TM_ECODE_FAILED; - } - - if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { - SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle)); - - SCMutexUnlock(&pcap_bpf_compile_lock); - SCFree(ptv); - /* Dereference config */ - pcapconfig->DerefFunc(pcapconfig); - return TM_ECODE_FAILED; - } - - SCMutexUnlock(&pcap_bpf_compile_lock); - } - - ptv->datalink = pcap_datalink(ptv->pcap_handle); - - ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", - ptv->tv); - ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops", - ptv->tv); - ptv->capture_kernel_ifdrops = StatsRegisterCounter("capture.kernel_ifdrops", - ptv->tv); - - *data = (void *)ptv; - - /* Dereference config */ - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_OK); -} -#endif /* LIBPCAP_VERSION_MAJOR */ - -/** - * \brief This function prints stats to the screen at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PcapThreadVars for ptv - */ -void ReceivePcapThreadExitStats(ThreadVars *tv, void *data) -{ - SCEnter(); - PcapThreadVars *ptv = (PcapThreadVars *)data; - struct pcap_stat pcap_s; - - if (pcap_stats(ptv->pcap_handle, &pcap_s) < 0) { - SCLogError(SC_ERR_STAT,"(%s) Failed to get pcap_stats: %s", tv->name, pcap_geterr(ptv->pcap_handle)); - SCLogInfo("(%s) Packets %" PRIu32 ", bytes %" PRIu64 "", tv->name, ptv->pkts, ptv->bytes); - - return; - } else { - SCLogInfo("(%s) Packets %" PRIu32 ", bytes %" PRIu64 "", tv->name, ptv->pkts, ptv->bytes); - - /* these numbers are not entirely accurate as ps_recv contains packets that are still waiting to be processed at exit. - * ps_drop only contains packets dropped by the driver and not any packets dropped by the interface. - * Additionally see http://tracker.icir.org/bro/ticket/18 - * - * Note: ps_recv includes dropped packets and should be considered total. - * Unless we start to look at ps_ifdrop which isn't supported everywhere. - */ - SCLogInfo("(%s) Pcap Total:%" PRIu64 " Recv:%" PRIu64 " Drop:%" PRIu64 " (%02.1f%%).", tv->name, - (uint64_t)pcap_s.ps_recv, (uint64_t)pcap_s.ps_recv - (uint64_t)pcap_s.ps_drop, (uint64_t)pcap_s.ps_drop, - (((float)(uint64_t)pcap_s.ps_drop)/(float)(uint64_t)pcap_s.ps_recv)*100); - - return; - } -} - -/** - * \brief DeInit function closes pcap_handle at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PcapThreadVars for ptv - */ -TmEcode ReceivePcapThreadDeinit(ThreadVars *tv, void *data) -{ - PcapThreadVars *ptv = (PcapThreadVars *)data; - - pcap_close(ptv->pcap_handle); - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief This function passes off to link type decoders. - * - * DecodePcap reads packets from the PacketQueue and passes - * them off to the proper link type decoder. - * - * \param t pointer to ThreadVars - * \param p pointer to the current packet - * \param data pointer that gets cast into PcapThreadVars for ptv - * \param pq pointer to the current PacketQueue - */ -TmEcode DecodePcap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - SCEnter(); - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - /* call the decoder */ - switch(p->datalink) { - case LINKTYPE_LINUX_SLL: - DecodeSll(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - case LINKTYPE_ETHERNET: - DecodeEthernet(tv, dtv, p,GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - case LINKTYPE_PPP: - DecodePPP(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - case LINKTYPE_RAW: - DecodeRaw(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - case LINKTYPE_NULL: - DecodeNull(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - break; - default: - SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "Error: datalink type %" PRId32 " not yet supported in module DecodePcap", p->datalink); - break; - } - - PacketDecodeFinalize(tv, dtv, p); - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodePcapThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - DecodeThreadVars *dtv = NULL; - - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - -#ifdef __SC_CUDA_SUPPORT__ - if (CudaThreadVarsInit(&dtv->cuda_vars) < 0) - SCReturnInt(TM_ECODE_FAILED); -#endif - - *data = (void *)dtv; - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode DecodePcapThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - -void PcapTranslateIPToDevice(char *pcap_dev, size_t len) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t *alldevsp = NULL; - pcap_if_t *devsp = NULL; - - struct addrinfo aiHints; - struct addrinfo *aiList = NULL; - int retVal = 0; - - memset(&aiHints, 0, sizeof(aiHints)); - aiHints.ai_family = AF_UNSPEC; - aiHints.ai_flags = AI_NUMERICHOST; - - /* try to translate IP */ - if ((retVal = getaddrinfo(pcap_dev, NULL, &aiHints, &aiList)) != 0) { - return; - } - - if (pcap_findalldevs(&alldevsp, errbuf)) { - freeaddrinfo(aiList); - return; - } - - for (devsp = alldevsp; devsp ; devsp = devsp->next) { - pcap_addr_t *ip = NULL; - - for (ip = devsp->addresses; ip ; ip = ip->next) { - - if (aiList->ai_family != ip->addr->sa_family) { - continue; - } - - if (ip->addr->sa_family == AF_INET) { - if (memcmp(&((struct sockaddr_in*)aiList->ai_addr)->sin_addr, &((struct sockaddr_in*)ip->addr)->sin_addr, sizeof(struct in_addr))) { - continue; - } - } else if (ip->addr->sa_family == AF_INET6) { - if (memcmp(&((struct sockaddr_in6*)aiList->ai_addr)->sin6_addr, &((struct sockaddr_in6*)ip->addr)->sin6_addr, sizeof(struct in6_addr))) { - continue; - } - } else { - continue; - } - - freeaddrinfo(aiList); - - memset(pcap_dev, 0, len); - strlcpy(pcap_dev, devsp->name, len); - - pcap_freealldevs(alldevsp); - return; - } - } - - freeaddrinfo(aiList); - - pcap_freealldevs(alldevsp); -} - -/* eof */ - diff --git a/framework/src/suricata/src/source-pcap.h b/framework/src/suricata/src/source-pcap.h deleted file mode 100644 index ac6d331d..00000000 --- a/framework/src/suricata/src/source-pcap.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __SOURCE_PCAP_H__ -#define __SOURCE_PCAP_H__ - -void TmModuleReceivePcapRegister (void); -void TmModuleDecodePcapRegister (void); -void PcapTranslateIPToDevice(char *pcap_dev, size_t len); - -int PcapLiveRegisterDevice(char *); -int PcapLiveGetDeviceCount(void); -char *PcapLiveGetDevice(int); - -#define LIBPCAP_SNAPLEN 1518 -#define LIBPCAP_COPYWAIT 500 -#define LIBPCAP_PROMISC 1 - -/* per packet Pcap vars */ -typedef struct PcapPacketVars_ -{ - uint32_t tenant_id; -} PcapPacketVars; - -/** needs to be able to contain Windows adapter id's, so - * must be quite long. */ -#define PCAP_IFACE_NAME_LENGTH 128 - -typedef struct PcapIfaceConfig_ -{ - char iface[PCAP_IFACE_NAME_LENGTH]; - /* number of threads */ - int threads; - /* socket buffer size */ - int buffer_size; - /* snapshot length */ - int snaplen; - /* promiscuous value */ - int promisc; - /* BPF filter */ - char *bpf_filter; - ChecksumValidationMode checksum_mode; - SC_ATOMIC_DECLARE(unsigned int, ref); - void (*DerefFunc)(void *); -} PcapIfaceConfig; - - - -#endif /* __SOURCE_PCAP_H__ */ - diff --git a/framework/src/suricata/src/source-pfring.c b/framework/src/suricata/src/source-pfring.c deleted file mode 100644 index 527086f5..00000000 --- a/framework/src/suricata/src/source-pfring.c +++ /dev/null @@ -1,682 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author William Metcalf - * \author Eric Leblond - * - * PF_RING packet acquisition support - * - * \todo remove requirement for setting cluster so old 3.x versions are supported - * \todo implement DNA support - * \todo Allow ring options such as snaplen etc, to be user configurable. - */ - -#ifdef HAVE_PFRING -#include -#endif /* HAVE_PFRING */ - -#include "suricata-common.h" -#include "suricata.h" -#include "conf.h" -#include "decode.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "source-pfring.h" -#include "util-debug.h" -#include "util-checksum.h" -#include "util-privs.h" -#include "util-device.h" -#include "util-host-info.h" -#include "runmodes.h" - -#ifdef __SC_CUDA_SUPPORT__ - -#include "util-cuda.h" -#include "util-cuda-buffer.h" -#include "util-mpm-ac.h" -#include "util-cuda-handlers.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "util-cuda-vars.h" - -#endif /* __SC_CUDA_SUPPORT__ */ - -TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot); -TmEcode ReceivePfringThreadInit(ThreadVars *, void *, void **); -void ReceivePfringThreadExitStats(ThreadVars *, void *); -TmEcode ReceivePfringThreadDeinit(ThreadVars *, void *); - -TmEcode DecodePfringThreadInit(ThreadVars *, void *, void **); -TmEcode DecodePfring(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode DecodePfringThreadDeinit(ThreadVars *tv, void *data); - -extern int max_pending_packets; - -#ifndef HAVE_PFRING - -/*Handle cases where we don't have PF_RING support built-in*/ -TmEcode NoPfringSupportExit(ThreadVars *, void *, void **); - -void TmModuleReceivePfringRegister (void) -{ - tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring"; - tmm_modules[TMM_RECEIVEPFRING].ThreadInit = NoPfringSupportExit; - tmm_modules[TMM_RECEIVEPFRING].Func = NULL; - tmm_modules[TMM_RECEIVEPFRING].ThreadExitPrintStats = NULL; - tmm_modules[TMM_RECEIVEPFRING].ThreadDeinit = NULL; - tmm_modules[TMM_RECEIVEPFRING].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEPFRING].cap_flags = SC_CAP_NET_ADMIN | SC_CAP_NET_RAW | - SC_CAP_NET_BIND_SERVICE | SC_CAP_NET_BROADCAST; - tmm_modules[TMM_RECEIVEPFRING].flags = TM_FLAG_RECEIVE_TM; -} - -void TmModuleDecodePfringRegister (void) -{ - tmm_modules[TMM_DECODEPFRING].name = "DecodePfring"; - tmm_modules[TMM_DECODEPFRING].ThreadInit = NoPfringSupportExit; - tmm_modules[TMM_DECODEPFRING].Func = NULL; - tmm_modules[TMM_DECODEPFRING].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEPFRING].ThreadDeinit = NULL; - tmm_modules[TMM_DECODEPFRING].RegisterTests = NULL; - tmm_modules[TMM_DECODEPFRING].cap_flags = 0; - tmm_modules[TMM_DECODEPFRING].flags = TM_FLAG_DECODE_TM; -} - -/** - * \brief this funciton prints an error message and exits. - * \param tv pointer to ThreadVars - * \param initdata pointer to the interface passed from the user - * \param data pointer gets populated with PfringThreadVars - */ -TmEcode NoPfringSupportExit(ThreadVars *tv, void *initdata, void **data) -{ - SCLogError(SC_ERR_NO_PF_RING,"Error creating thread %s: you do not have support for pfring " - "enabled please recompile with --enable-pfring", tv->name); - exit(EXIT_FAILURE); -} - -#else /* implied we do have PF_RING support */ - -/** protect pfring_set_bpf_filter, as it is not thread safe */ -static SCMutex pfring_bpf_set_filter_lock = SCMUTEX_INITIALIZER; - -/* XXX replace with user configurable options */ -#define LIBPFRING_PROMISC 1 -#define LIBPFRING_REENTRANT 0 -#define LIBPFRING_WAIT_FOR_INCOMING 1 - -typedef enum { - PFRING_FLAGS_ZERO_COPY = 0x1 -} PfringThreadVarsFlags; - -/** - * \brief Structure to hold thread specific variables. - */ -typedef struct PfringThreadVars_ -{ - /* thread specific handle */ - pfring *pd; - - /* counters */ - uint64_t bytes; - uint64_t pkts; - - uint16_t capture_kernel_packets; - uint16_t capture_kernel_drops; - - uint32_t flags; - - ThreadVars *tv; - TmSlot *slot; - - int vlan_disabled; - - /* threads count */ - int threads; - - cluster_type ctype; - - uint8_t cluster_id; - char *interface; - LiveDevice *livedev; - - char *bpf_filter; - - ChecksumValidationMode checksum_mode; -} PfringThreadVars; - -/** - * \brief Registration Function for RecievePfring. - * \todo Unit tests are needed for this module. - */ -void TmModuleReceivePfringRegister (void) -{ - tmm_modules[TMM_RECEIVEPFRING].name = "ReceivePfring"; - tmm_modules[TMM_RECEIVEPFRING].ThreadInit = ReceivePfringThreadInit; - tmm_modules[TMM_RECEIVEPFRING].Func = NULL; - tmm_modules[TMM_RECEIVEPFRING].PktAcqLoop = ReceivePfringLoop; - tmm_modules[TMM_RECEIVEPFRING].ThreadExitPrintStats = ReceivePfringThreadExitStats; - tmm_modules[TMM_RECEIVEPFRING].ThreadDeinit = ReceivePfringThreadDeinit; - tmm_modules[TMM_RECEIVEPFRING].RegisterTests = NULL; - tmm_modules[TMM_RECEIVEPFRING].flags = TM_FLAG_RECEIVE_TM; -} - -/** - * \brief Registration Function for DecodePfring. - * \todo Unit tests are needed for this module. - */ -void TmModuleDecodePfringRegister (void) -{ - tmm_modules[TMM_DECODEPFRING].name = "DecodePfring"; - tmm_modules[TMM_DECODEPFRING].ThreadInit = DecodePfringThreadInit; - tmm_modules[TMM_DECODEPFRING].Func = DecodePfring; - tmm_modules[TMM_DECODEPFRING].ThreadExitPrintStats = NULL; - tmm_modules[TMM_DECODEPFRING].ThreadDeinit = DecodePfringThreadDeinit; - tmm_modules[TMM_DECODEPFRING].RegisterTests = NULL; - tmm_modules[TMM_DECODEPFRING].flags = TM_FLAG_DECODE_TM; -} - -static inline void PfringDumpCounters(PfringThreadVars *ptv) -{ - pfring_stat pfring_s; - if (likely((pfring_stats(ptv->pd, &pfring_s) >= 0))) { - /* pfring counter is per socket and is not cleared after read. - * So to get the number of packet on the interface we can add - * the newly seen packets and drops for this thread and add it - * to the interface counter */ - uint64_t th_pkts = StatsGetLocalCounterValue(ptv->tv, ptv->capture_kernel_packets); - uint64_t th_drops = StatsGetLocalCounterValue(ptv->tv, ptv->capture_kernel_drops); - SC_ATOMIC_ADD(ptv->livedev->pkts, pfring_s.recv - th_pkts); - SC_ATOMIC_ADD(ptv->livedev->drop, pfring_s.drop - th_drops); - StatsSetUI64(ptv->tv, ptv->capture_kernel_packets, pfring_s.recv); - StatsSetUI64(ptv->tv, ptv->capture_kernel_drops, pfring_s.drop); - } -} - -/** - * \brief Pfring Packet Process function. - * - * This function fills in our packet structure from libpfring. - * From here the packets are picked up by the DecodePfring thread. - * - * \param user pointer to PfringThreadVars - * \param h pointer to pfring packet header - * \param p pointer to the current packet - */ -static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Packet *p) -{ - - PfringThreadVars *ptv = (PfringThreadVars *)user; - - ptv->bytes += h->caplen; - ptv->pkts++; - p->livedev = ptv->livedev; - - /* PF_RING may fail to set timestamp */ - if (h->ts.tv_sec == 0) { - gettimeofday((struct timeval *)&h->ts, NULL); - } - - p->ts.tv_sec = h->ts.tv_sec; - p->ts.tv_usec = h->ts.tv_usec; - - /* PF_RING all packets are marked as a link type of ethernet - * so that is what we do here. */ - p->datalink = LINKTYPE_ETHERNET; - - /* get vlan id from header. Check on vlan_id not null even if comment in - * header announce NO_VLAN is used when there is no VLAN. But NO_VLAN - * is not defined nor used in PF_RING code. And vlan_id is set to 0 - * in PF_RING kernel code when there is no VLAN. */ - if ((!ptv->vlan_disabled) && h->extended_hdr.parsed_pkt.vlan_id) { - p->vlan_id[0] = h->extended_hdr.parsed_pkt.vlan_id; - p->vlan_idx = 1; - p->vlanh[0] = NULL; - } - - switch (ptv->checksum_mode) { - case CHECKSUM_VALIDATION_RXONLY: - if (h->extended_hdr.rx_direction == 0) { - p->flags |= PKT_IGNORE_CHECKSUM; - } - break; - case CHECKSUM_VALIDATION_DISABLE: - p->flags |= PKT_IGNORE_CHECKSUM; - break; - case CHECKSUM_VALIDATION_AUTO: - if (ptv->livedev->ignore_checksum) { - p->flags |= PKT_IGNORE_CHECKSUM; - } else if (ChecksumAutoModeCheck(ptv->pkts, - SC_ATOMIC_GET(ptv->livedev->pkts), - SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) { - ptv->livedev->ignore_checksum = 1; - p->flags |= PKT_IGNORE_CHECKSUM; - } - break; - default: - break; - } - - SET_PKT_LEN(p, h->caplen); -} - -/** - * \brief Recieves packets from an interface via libpfring. - * - * This function recieves packets from an interface and passes - * the packet on to the pfring callback function. - * - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PfringThreadVars for ptv - * \param slot slot containing task information - * \retval TM_ECODE_OK on success - * \retval TM_ECODE_FAILED on failure - */ -TmEcode ReceivePfringLoop(ThreadVars *tv, void *data, void *slot) -{ - SCEnter(); - - PfringThreadVars *ptv = (PfringThreadVars *)data; - Packet *p = NULL; - struct pfring_pkthdr hdr; - TmSlot *s = (TmSlot *)slot; - time_t last_dump = 0; - u_int buffer_size; - u_char *pkt_buffer; - - ptv->slot = s->slot_next; - - /* we have to enable the ring here as we need to do it after all - * the threads have called pfring_set_cluster(). */ - int rc = pfring_enable_ring(ptv->pd); - if (rc != 0) { - SCLogError(SC_ERR_PF_RING_OPEN, "pfring_enable_ring failed returned %d ", rc); - SCReturnInt(TM_ECODE_FAILED); - } - - while(1) { - if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) { - SCReturnInt(TM_ECODE_OK); - } - - /* make sure we have at least one packet in the packet pool, to prevent - * us from alloc'ing packets at line rate */ - PacketPoolWait(); - - p = PacketGetFromQueueOrAlloc(); - if (p == NULL) { - SCReturnInt(TM_ECODE_FAILED); - } - PKT_SET_SRC(p, PKT_SRC_WIRE); - - /* Some flavours of PF_RING may fail to set timestamp - see PF-RING-enabled libpcap code*/ - hdr.ts.tv_sec = hdr.ts.tv_usec = 0; - - /* Check for Zero-copy mode */ - if (ptv->flags & PFRING_FLAGS_ZERO_COPY) { - buffer_size = 0; - pkt_buffer = NULL; - } else { - buffer_size = GET_PKT_DIRECT_MAX_SIZE(p); - pkt_buffer = GET_PKT_DIRECT_DATA(p); - } - - /* Depending on what compile time options are used for pfring we either return 0 or -1 on error and always 1 for success */ - int r = pfring_recv(ptv->pd, &pkt_buffer, - buffer_size, - &hdr, - LIBPFRING_WAIT_FOR_INCOMING); - - /* Check for Zero-copy mode */ - if (ptv->flags & PFRING_FLAGS_ZERO_COPY) { - PacketSetData(p, pkt_buffer, hdr.caplen); - } - - if (r == 1) { - //printf("RecievePfring src %" PRIu32 " sport %" PRIu32 " dst %" PRIu32 " dstport %" PRIu32 "\n", - // hdr.parsed_pkt.ipv4_src,hdr.parsed_pkt.l4_src_port, hdr.parsed_pkt.ipv4_dst,hdr.parsed_pkt.l4_dst_port); - - PfringProcessPacket(ptv, &hdr, p); - - if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) { - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(TM_ECODE_FAILED); - } - - /* Trigger one dump of stats every second */ - if (p->ts.tv_sec != last_dump) { - PfringDumpCounters(ptv); - last_dump = p->ts.tv_sec; - } - } else { - SCLogError(SC_ERR_PF_RING_RECV,"pfring_recv error %" PRId32 "", r); - TmqhOutputPacketpool(ptv->tv, p); - SCReturnInt(TM_ECODE_FAILED); - } - StatsSyncCountersIfSignalled(tv); - } - - return TM_ECODE_OK; -} - -/** - * \brief Init function for RecievePfring. - * - * This is a setup function for recieving packets - * via libpfring. - * - * \param tv pointer to ThreadVars - * \param initdata pointer to the interface passed from the user - * \param data pointer gets populated with PfringThreadVars - * \todo add a config option for setting cluster id - * \todo Create a general pfring setup function. - * \retval TM_ECODE_OK on success - * \retval TM_ECODE_FAILED on error - */ -TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - int rc; - u_int32_t version = 0; - PfringIfaceConfig *pfconf = (PfringIfaceConfig *) initdata; - unsigned int opflag; - char const *active_runmode = RunmodeGetActive(); - - if (pfconf == NULL) - return TM_ECODE_FAILED; - - PfringThreadVars *ptv = SCMalloc(sizeof(PfringThreadVars)); - if (unlikely(ptv == NULL)) { - pfconf->DerefFunc(pfconf); - return TM_ECODE_FAILED; - } - memset(ptv, 0, sizeof(PfringThreadVars)); - - ptv->tv = tv; - ptv->threads = 1; - - ptv->interface = SCStrdup(pfconf->iface); - if (unlikely(ptv->interface == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate device string"); - SCFree(ptv); - SCReturnInt(TM_ECODE_FAILED); - } - - ptv->livedev = LiveGetDevice(pfconf->iface); - if (ptv->livedev == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device"); - SCFree(ptv); - SCReturnInt(TM_ECODE_FAILED); - } - - /* enable zero-copy mode for workers runmode */ - if (active_runmode && strcmp("workers", active_runmode) == 0) { - ptv->flags |= PFRING_FLAGS_ZERO_COPY; - SCLogInfo("Enabling zero-copy for %s", ptv->interface); - } - - ptv->checksum_mode = pfconf->checksum_mode; - - opflag = PF_RING_PROMISC; - - /* if suri uses VLAN and if we have a recent kernel, we need - * to use parsed_pkt to get VLAN info */ - if ((! ptv->vlan_disabled) && SCKernelVersionIsAtLeast(3, 0)) { - opflag |= PF_RING_LONG_HEADER; - } - - if (ptv->checksum_mode == CHECKSUM_VALIDATION_RXONLY) { - if (strncmp(ptv->interface, "dna", 3) == 0) { - SCLogWarning(SC_ERR_INVALID_VALUE, - "Can't use rxonly checksum-checks on DNA interface," - " resetting to auto"); - ptv->checksum_mode = CHECKSUM_VALIDATION_AUTO; - } else { - opflag |= PF_RING_LONG_HEADER; - } - } - - ptv->pd = pfring_open(ptv->interface, (uint32_t)default_packet_size, opflag); - if (ptv->pd == NULL) { - SCLogError(SC_ERR_PF_RING_OPEN,"Failed to open %s: pfring_open error." - " Check if %s exists and pf_ring module is loaded.", - ptv->interface, - ptv->interface); - pfconf->DerefFunc(pfconf); - SCFree(ptv); - return TM_ECODE_FAILED; - } else { - pfring_set_application_name(ptv->pd, PROG_NAME); - pfring_version(ptv->pd, &version); - } - - /* We only set cluster info if the number of pfring threads is greater than 1 */ - ptv->threads = pfconf->threads; - - ptv->cluster_id = pfconf->cluster_id; - - if ((ptv->threads == 1) && (strncmp(ptv->interface, "dna", 3) == 0)) { - SCLogInfo("DNA interface detected, not adding thread to cluster"); - } else if (strncmp(ptv->interface, "zc", 2) == 0) { - SCLogInfo("ZC interface detected, not adding thread to cluster"); - } else { - ptv->ctype = pfconf->ctype; - rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, ptv->ctype); - - if (rc != 0) { - SCLogError(SC_ERR_PF_RING_SET_CLUSTER_FAILED, "pfring_set_cluster " - "returned %d for cluster-id: %d", rc, ptv->cluster_id); - if (rc != PF_RING_ERROR_NOT_SUPPORTED || (pfconf->flags & PFRING_CONF_FLAGS_CLUSTER)) { - /* cluster is mandatory as explicitly specified in the configuration */ - pfconf->DerefFunc(pfconf); - return TM_ECODE_FAILED; - } - } - } - - if (ptv->threads > 1) { - SCLogInfo("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d", - tv->name, (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8, - version & 0x000000FF, ptv->interface, ptv->cluster_id); - } else { - SCLogInfo("(%s) Using PF_RING v.%d.%d.%d, interface %s, cluster-id %d, single-pfring-thread", - tv->name, (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8, - version & 0x000000FF, ptv->interface, ptv->cluster_id); - } - - if (pfconf->bpf_filter) { - ptv->bpf_filter = SCStrdup(pfconf->bpf_filter); - if (unlikely(ptv->bpf_filter == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Set PF_RING bpf filter failed."); - } else { - SCMutexLock(&pfring_bpf_set_filter_lock); - rc = pfring_set_bpf_filter(ptv->pd, ptv->bpf_filter); - SCMutexUnlock(&pfring_bpf_set_filter_lock); - - if (rc < 0) { - SCLogInfo("Set PF_RING bpf filter \"%s\" failed.", - ptv->bpf_filter); - } - } - } - - ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets", - ptv->tv); - ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops", - ptv->tv); - - /* A bit strange to have this here but we only have vlan information - * during reading so we need to know if we want to keep vlan during - * the capture phase */ - int vlanbool = 0; - if ((ConfGetBool("vlan.use-for-tracking", &vlanbool)) == 1 && vlanbool == 0) { - ptv->vlan_disabled = 1; - } - - /* If kernel is older than 3.8, VLAN is not stripped so we don't - * get the info from packt extended header but we will use a standard - * parsing */ - if (! SCKernelVersionIsAtLeast(3, 0)) { - ptv->vlan_disabled = 1; - } - - /* If VLAN tracking is disabled, set cluster type to 5-tuple or in case of a - * ZC interface, do nothing */ - if (ptv->vlan_disabled && ptv->ctype == CLUSTER_FLOW && - strncmp(ptv->interface, "zc", 2) != 0) { - SCLogInfo("VLAN disabled, setting cluster type to CLUSTER_FLOW_5_TUPLE"); - rc = pfring_set_cluster(ptv->pd, ptv->cluster_id, CLUSTER_FLOW_5_TUPLE); - - if (rc != 0) { - SCLogError(SC_ERR_PF_RING_SET_CLUSTER_FAILED, "pfring_set_cluster " - "returned %d for cluster-id: %d", rc, ptv->cluster_id); - pfconf->DerefFunc(pfconf); - return TM_ECODE_FAILED; - } - } - - *data = (void *)ptv; - pfconf->DerefFunc(pfconf); - - return TM_ECODE_OK; -} - -/** - * \brief This function prints stats to the screen at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PfringThreadVars for ptv - */ -void ReceivePfringThreadExitStats(ThreadVars *tv, void *data) -{ - PfringThreadVars *ptv = (PfringThreadVars *)data; - - PfringDumpCounters(ptv); - SCLogInfo("(%s) Kernel: Packets %" PRIu64 ", dropped %" PRIu64 "", - tv->name, - StatsGetLocalCounterValue(tv, ptv->capture_kernel_packets), - StatsGetLocalCounterValue(tv, ptv->capture_kernel_drops)); - SCLogInfo("(%s) Packets %" PRIu64 ", bytes %" PRIu64 "", tv->name, ptv->pkts, ptv->bytes); -} - -/** - * \brief DeInit function closes pd at exit. - * \param tv pointer to ThreadVars - * \param data pointer that gets cast into PfringThreadVars for ptvi - * \retval TM_ECODE_OK is always returned - */ -TmEcode ReceivePfringThreadDeinit(ThreadVars *tv, void *data) -{ - PfringThreadVars *ptv = (PfringThreadVars *)data; - if (ptv->interface) - SCFree(ptv->interface); - pfring_remove_from_cluster(ptv->pd); - - if (ptv->bpf_filter) { - pfring_remove_bpf_filter(ptv->pd); - SCFree(ptv->bpf_filter); - } - - pfring_close(ptv->pd); - return TM_ECODE_OK; -} - -/** - * \brief This function passes off to link type decoders. - * - * DecodePfring reads packets from the PacketQueue. Inside of libpcap version of - * PF_RING all packets are marked as a link type of ethernet so that is what we do here. - * - * \param tv pointer to ThreadVars - * \param p pointer to the current packet - * \param data pointer that gets cast into PfringThreadVars for ptv - * \param pq pointer to the current PacketQueue - * - * \todo Verify that PF_RING only deals with ethernet traffic - * - * \warning This function bypasses the pkt buf and len macro's - * - * \retval TM_ECODE_OK is always returned - */ -TmEcode DecodePfring(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - DecodeThreadVars *dtv = (DecodeThreadVars *)data; - - /* XXX HACK: flow timeout can call us for injected pseudo packets - * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */ - if (p->flags & PKT_PSEUDO_STREAM_END) - return TM_ECODE_OK; - - /* update counters */ - DecodeUpdatePacketCounters(tv, dtv, p); - - /* If suri has set vlan during reading, we increase vlan counter */ - if (p->vlan_idx) { - StatsIncr(tv, dtv->counter_vlan); - } - - DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); - - PacketDecodeFinalize(tv, dtv, p); - - return TM_ECODE_OK; -} - -/** - * \brief This an Init function for DecodePfring - * - * \param tv pointer to ThreadVars - * \param initdata pointer to initilization data. - * \param data pointer that gets cast into PfringThreadVars for ptv - * \retval TM_ECODE_OK is returned on success - * \retval TM_ECODE_FAILED is returned on error - */ -TmEcode DecodePfringThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - DecodeThreadVars *dtv = NULL; - - dtv = DecodeThreadVarsAlloc(tv); - - if (dtv == NULL) - SCReturnInt(TM_ECODE_FAILED); - - DecodeRegisterPerfCounters(dtv, tv); - - *data = (void *)dtv; - -#ifdef __SC_CUDA_SUPPORT__ - if (CudaThreadVarsInit(&dtv->cuda_vars) < 0) - SCReturnInt(TM_ECODE_FAILED); -#endif - - return TM_ECODE_OK; -} - -TmEcode DecodePfringThreadDeinit(ThreadVars *tv, void *data) -{ - if (data != NULL) - DecodeThreadVarsFree(tv, data); - SCReturnInt(TM_ECODE_OK); -} - - -#endif /* HAVE_PFRING */ -/* eof */ diff --git a/framework/src/suricata/src/source-pfring.h b/framework/src/suricata/src/source-pfring.h deleted file mode 100644 index 9871f458..00000000 --- a/framework/src/suricata/src/source-pfring.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author William Metcalf - */ - -#ifndef __SOURCE_PFRING_H__ -#define __SOURCE_PFRING_H__ - -#define PFRING_IFACE_NAME_LENGTH 48 - -#include -#ifdef HAVE_PFRING -#include -#endif - -typedef enum { - PFRING_CONF_FLAGS_CLUSTER = 0x1 -} PfringIfaceConfigFlags; - -typedef struct PfringIfaceConfig_ -{ - uint32_t flags; - - /* cluster param */ - int cluster_id; -#ifdef HAVE_PFRING - cluster_type ctype; -#endif - char iface[PFRING_IFACE_NAME_LENGTH]; - /* number of threads */ - int threads; - - char *bpf_filter; - - ChecksumValidationMode checksum_mode; - SC_ATOMIC_DECLARE(unsigned int, ref); - void (*DerefFunc)(void *); -} PfringIfaceConfig; - - - -void TmModuleReceivePfringRegister (void); -void TmModuleDecodePfringRegister (void); - -int PfringConfGetThreads(void); -void PfringLoadConfig(void); - -/* We don't have to use an enum that sucks in our code */ -#define CLUSTER_FLOW 0 -#define CLUSTER_ROUND_ROBIN 1 -#define CLUSTER_FLOW_5_TUPLE 4 -#endif /* __SOURCE_PFRING_H__ */ diff --git a/framework/src/suricata/src/stream-tcp-inline.c b/framework/src/suricata/src/stream-tcp-inline.c deleted file mode 100644 index b8961ba2..00000000 --- a/framework/src/suricata/src/stream-tcp-inline.c +++ /dev/null @@ -1,657 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Functions for the "inline mode" of the stream engine. - */ - -#include "suricata-common.h" -#include "stream-tcp-inline.h" - -#include "util-memcmp.h" -#include "util-print.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -/** defined in stream-tcp-reassemble.c */ -extern int stream_inline; - -/** - * \brief See if stream engine is operating in inline mode - * - * \retval 0 no - * \retval 1 yes - */ -int StreamTcpInlineMode(void) -{ - return stream_inline; -} - -/** - * \brief Compare the shared data portion of two segments - * - * If no data is shared, 0 will be returned. - * - * \param seg1 first segment - * \param seg2 second segment - * - * \retval 0 shared data is the same (or no data is shared) - * \retval 1 shared data is different - */ -int StreamTcpInlineSegmentCompare(TcpSegment *seg1, TcpSegment *seg2) -{ - SCEnter(); - - if (seg1 == NULL || seg2 == NULL) { - SCReturnInt(0); - } - - if (SEQ_EQ(seg1->seq, seg2->seq) && seg1->payload_len == seg2->payload_len) { - int r = SCMemcmp(seg1->payload, seg2->payload, seg1->payload_len); -#if 0 - if (r) { - PrintRawDataFp(stdout,seg1->payload,seg1->payload_len); - PrintRawDataFp(stdout,seg2->payload,seg2->payload_len); - } -#endif - SCReturnInt(r); - } else if (SEQ_GT(seg1->seq, (seg2->seq + seg2->payload_len))) { - SCReturnInt(0); - } else if (SEQ_GT(seg2->seq, (seg1->seq + seg1->payload_len))) { - SCReturnInt(0); - } else { - SCLogDebug("seg1 %u (%u), seg2 %u (%u)", seg1->seq, - seg1->payload_len, seg2->seq, seg2->payload_len); - - uint32_t seg1_end = seg1->seq + seg1->payload_len; - uint32_t seg2_end = seg2->seq + seg2->payload_len; - SCLogDebug("seg1_end %u, seg2_end %u", seg1_end, seg2_end); -#if 0 - SCLogDebug("seg1"); - PrintRawDataFp(stdout,seg1->payload,seg1->payload_len); - SCLogDebug("seg2"); - PrintRawDataFp(stdout,seg2->payload,seg2->payload_len); -#endif - /* get the minimal seg*_end */ - uint32_t end = (SEQ_GT(seg1_end, seg2_end)) ? seg2_end : seg1_end; - /* and the max seq */ - uint32_t seq = (SEQ_LT(seg1->seq, seg2->seq)) ? seg2->seq : seg1->seq; - - SCLogDebug("seq %u, end %u", seq, end); - - uint16_t seg1_off = seq - seg1->seq; - uint16_t seg2_off = seq - seg2->seq; - SCLogDebug("seg1_off %u, seg2_off %u", seg1_off, seg2_off); - - uint32_t range = end - seq; - SCLogDebug("range %u", range); - BUG_ON(range > 65536); - - if (range) { - int r = SCMemcmp(seg1->payload+seg1_off, seg2->payload+seg2_off, range); -#if 0 - if (r) { - PrintRawDataFp(stdout,seg1->payload+seg1_off,range); - PrintRawDataFp(stdout,seg2->payload+seg2_off,range); - - PrintRawDataFp(stdout,seg1->payload,seg1->payload_len); - PrintRawDataFp(stdout,seg2->payload,seg2->payload_len); - } -#endif - SCReturnInt(r); - } - SCReturnInt(0); - } -} - -/** - * \brief Replace (part of) the payload portion of a packet by the data - * in a TCP segment - * - * \param p Packet - * \param seg TCP segment - * - * \todo What about reassembled fragments? - * \todo What about unwrapped tunnel packets? - */ -void StreamTcpInlineSegmentReplacePacket(Packet *p, TcpSegment *seg) -{ - SCEnter(); - - uint32_t pseq = TCP_GET_SEQ(p); - uint32_t tseq = seg->seq; - - /* check if segment is within the packet */ - if (tseq + seg->payload_len < pseq) { - SCReturn; - } else if (pseq + p->payload_len < tseq) { - SCReturn; - } else { - /** \todo review logic */ - uint32_t pend = pseq + p->payload_len; - uint32_t tend = tseq + seg->payload_len; - SCLogDebug("pend %u, tend %u", pend, tend); - - //SCLogDebug("packet"); - //PrintRawDataFp(stdout,p->payload,p->payload_len); - //SCLogDebug("seg"); - //PrintRawDataFp(stdout,seg->payload,seg->payload_len); - - /* get the minimal seg*_end */ - uint32_t end = (SEQ_GT(pend, tend)) ? tend : pend; - /* and the max seq */ - uint32_t seq = (SEQ_LT(pseq, tseq)) ? tseq : pseq; - - SCLogDebug("seq %u, end %u", seq, end); - - uint16_t poff = seq - pseq; - uint16_t toff = seq - tseq; - SCLogDebug("poff %u, toff %u", poff, toff); - - uint32_t range = end - seq; - SCLogDebug("range %u", range); - BUG_ON(range > 65536); - - if (range) { - /* update the packets payload. As payload is a ptr to either - * p->pkt or p->ext_pkt that is updated as well */ - memcpy(p->payload+poff, seg->payload+toff, range); - - /* flag as modified so we can reinject / replace after - * recalculating the checksum */ - p->flags |= PKT_STREAM_MODIFIED; - } - } -} - -#ifdef UNITTESTS - -/** \test full overlap */ -static int StreamTcpInlineTest01(void) -{ - SCEnter(); - - uint8_t payload1[] = "AAC"; /* packet */ - uint8_t payload2[] = "ABC"; /* segment */ - int result = 0; - TcpSegment *t = NULL; - - Packet *p = UTHBuildPacketSrcDstPorts(payload1, sizeof(payload1)-1, IPPROTO_TCP, 1024, 80); - if (p == NULL || p->tcph == NULL) { - printf("generating test packet failed: "); - goto end; - } - p->tcph->th_seq = htonl(10000000UL); - - t = SCMalloc(sizeof(TcpSegment)); - if (unlikely(t == NULL)) { - printf("alloc TcpSegment failed: "); - goto end; - } - memset(t, 0x00, sizeof(TcpSegment)); - t->payload = payload2; - t->payload_len = sizeof(payload2)-1; - t->seq = 10000000UL; - - StreamTcpInlineSegmentReplacePacket(p, t); - - if (!(p->flags & PKT_STREAM_MODIFIED)) { - printf("PKT_STREAM_MODIFIED pkt flag not set: "); - goto end; - } - - if (memcmp(p->payload, t->payload, p->payload_len) != 0) { - printf("Packet:\n"); - PrintRawDataFp(stdout,p->payload,p->payload_len); - printf("Segment:\n"); - PrintRawDataFp(stdout,t->payload,t->payload_len); - printf("payloads didn't match: "); - goto end; - } - - uint8_t *pkt = GET_PKT_DATA(p)+(GET_PKT_LEN(p)-sizeof(payload1)+1); - if (memcmp(pkt,payload2,sizeof(payload2)-1) != 0) { - PrintRawDataFp(stdout,pkt,3); - PrintRawDataFp(stdout,GET_PKT_DATA(p),GET_PKT_LEN(p)); - goto end; - } - - result = 1; -end: - if (p != NULL) { - UTHFreePacket(p); - } - if (t != NULL) { - SCFree(t); - } - SCReturnInt(result); -} - -/** \test full overlap */ -static int StreamTcpInlineTest02(void) -{ - SCEnter(); - - uint8_t payload1[] = "xxx"; /* packet */ - uint8_t payload2[] = "ABCDE"; /* segment */ - int result = 0; - TcpSegment *t = NULL; - - Packet *p = UTHBuildPacketSrcDstPorts(payload1, sizeof(payload1)-1, IPPROTO_TCP, 1024, 80); - if (p == NULL || p->tcph == NULL) { - printf("generating test packet failed: "); - goto end; - } - p->tcph->th_seq = htonl(10000001UL); - - t = SCMalloc(sizeof(TcpSegment)); - if (unlikely(t == NULL)) { - printf("alloc TcpSegment failed: "); - goto end; - } - memset(t, 0x00, sizeof(TcpSegment)); - t->payload = payload2; - t->payload_len = sizeof(payload2)-1; - t->seq = 10000000UL; - - StreamTcpInlineSegmentReplacePacket(p, t); - - if (!(p->flags & PKT_STREAM_MODIFIED)) { - printf("PKT_STREAM_MODIFIED pkt flag not set: "); - goto end; - } - - if (memcmp(p->payload, t->payload+1, p->payload_len) != 0) { - printf("Packet:\n"); - PrintRawDataFp(stdout,p->payload,p->payload_len); - printf("Segment:\n"); - PrintRawDataFp(stdout,t->payload,t->payload_len); - printf("payloads didn't match: "); - goto end; - } - - uint8_t *pkt = GET_PKT_DATA(p)+(GET_PKT_LEN(p)-sizeof(payload1)+1); - if (memcmp(pkt,payload2+1,sizeof(payload2)-3) != 0) { - printf("Segment:\n"); - PrintRawDataFp(stdout,payload2+1,sizeof(payload2)-3); - printf("Packet:\n"); - PrintRawDataFp(stdout,pkt,3); - printf("Packet (full):\n"); - PrintRawDataFp(stdout,GET_PKT_DATA(p),GET_PKT_LEN(p)); - printf("packet data doesn't match: "); - goto end; - } - - result = 1; -end: - if (p != NULL) { - UTHFreePacket(p); - } - if (t != NULL) { - SCFree(t); - } - SCReturnInt(result); -} - -/** \test partial overlap */ -static int StreamTcpInlineTest03(void) -{ - SCEnter(); - - uint8_t payload1[] = "xxxxxxxxxxxx"; /* packet */ - uint8_t payload2[] = "ABCDE"; /* segment */ - int result = 0; - TcpSegment *t = NULL; - - Packet *p = UTHBuildPacketSrcDstPorts(payload1, sizeof(payload1)-1, IPPROTO_TCP, 1024, 80); - if (p == NULL || p->tcph == NULL) { - printf("generating test packet failed: "); - goto end; - } - p->tcph->th_seq = htonl(10000000UL); - - t = SCMalloc(sizeof(TcpSegment)); - if (unlikely(t == NULL)) { - printf("alloc TcpSegment failed: "); - goto end; - } - memset(t, 0x00, sizeof(TcpSegment)); - t->payload = payload2; - t->payload_len = sizeof(payload2)-1; - t->seq = 10000003UL; - - StreamTcpInlineSegmentReplacePacket(p, t); - - if (!(p->flags & PKT_STREAM_MODIFIED)) { - printf("PKT_STREAM_MODIFIED pkt flag not set: "); - goto end; - } - - if (memcmp(p->payload+3, t->payload, t->payload_len) != 0) { - printf("Packet:\n"); - PrintRawDataFp(stdout,p->payload,p->payload_len); - printf("Segment:\n"); - PrintRawDataFp(stdout,t->payload,t->payload_len); - printf("payloads didn't match: "); - goto end; - } - - uint8_t *pkt = GET_PKT_DATA(p)+(GET_PKT_LEN(p)-sizeof(payload1)+1 + 3); - if (memcmp(pkt,payload2,sizeof(payload2)-1) != 0) { - printf("Segment:\n"); - PrintRawDataFp(stdout,payload2+1,sizeof(payload2)-3); - printf("Packet:\n"); - PrintRawDataFp(stdout,pkt,3); - printf("Packet (full):\n"); - PrintRawDataFp(stdout,GET_PKT_DATA(p),GET_PKT_LEN(p)); - printf("packet data doesn't match: "); - goto end; - } - - result = 1; -end: - if (p != NULL) { - UTHFreePacket(p); - } - if (t != NULL) { - SCFree(t); - } - SCReturnInt(result); -} - -/** \test partial overlap */ -static int StreamTcpInlineTest04(void) -{ - SCEnter(); - - uint8_t payload1[] = "xxxxxxxxxxxx"; /* packet */ - uint8_t payload2[] = "ABCDE"; /* segment */ - int result = 0; - TcpSegment *t = NULL; - - Packet *p = UTHBuildPacketSrcDstPorts(payload1, sizeof(payload1)-1, IPPROTO_TCP, 1024, 80); - if (p == NULL || p->tcph == NULL) { - printf("generating test packet failed: "); - goto end; - } - p->tcph->th_seq = htonl(10000003UL); - - t = SCMalloc(sizeof(TcpSegment)); - if (unlikely(t == NULL)) { - printf("alloc TcpSegment failed: "); - goto end; - } - memset(t, 0x00, sizeof(TcpSegment)); - t->payload = payload2; - t->payload_len = sizeof(payload2)-1; - t->seq = 10000000UL; - - StreamTcpInlineSegmentReplacePacket(p, t); - - if (!(p->flags & PKT_STREAM_MODIFIED)) { - printf("PKT_STREAM_MODIFIED pkt flag not set: "); - goto end; - } - - if (memcmp(p->payload, t->payload+3, 2) != 0) { - printf("Packet:\n"); - PrintRawDataFp(stdout,p->payload,p->payload_len); - printf("Segment:\n"); - PrintRawDataFp(stdout,t->payload,t->payload_len); - printf("payloads didn't match: "); - goto end; - } - - uint8_t *pkt = GET_PKT_DATA(p)+(GET_PKT_LEN(p)-sizeof(payload1)+1); - if (memcmp(pkt,payload2+3,2) != 0) { - printf("Segment:\n"); - PrintRawDataFp(stdout,payload2+3,2); - printf("Packet:\n"); - PrintRawDataFp(stdout,pkt,3); - printf("Packet (full):\n"); - PrintRawDataFp(stdout,GET_PKT_DATA(p),GET_PKT_LEN(p)); - printf("packet data doesn't match: "); - goto end; - } - - result = 1; -end: - if (p != NULL) { - UTHFreePacket(p); - } - if (t != NULL) { - SCFree(t); - } - SCReturnInt(result); -} -/** \test partial overlap */ -static int StreamTcpInlineTest05(void) -{ - SCEnter(); - - uint8_t payload1[] = "xxxxxxxxxxxx"; /* packet */ - uint8_t payload2[] = "ABCDE"; /* segment */ - int result = 0; - TcpSegment *t = NULL; - - Packet *p = UTHBuildPacketSrcDstPorts(payload1, sizeof(payload1)-1, IPPROTO_TCP, 1024, 80); - if (p == NULL || p->tcph == NULL) { - printf("generating test packet failed: "); - goto end; - } - p->tcph->th_seq = htonl(10000000UL); - - t = SCMalloc(sizeof(TcpSegment)); - if (unlikely(t == NULL)) { - printf("alloc TcpSegment failed: "); - goto end; - } - memset(t, 0x00, sizeof(TcpSegment)); - t->payload = payload2; - t->payload_len = sizeof(payload2)-1; - t->seq = 10000010UL; - - StreamTcpInlineSegmentReplacePacket(p, t); - - if (!(p->flags & PKT_STREAM_MODIFIED)) { - printf("PKT_STREAM_MODIFIED pkt flag not set: "); - goto end; - } - - if (memcmp(p->payload+10, t->payload, 2) != 0) { - printf("Packet:\n"); - PrintRawDataFp(stdout,p->payload,p->payload_len); - printf("Segment:\n"); - PrintRawDataFp(stdout,t->payload,t->payload_len); - printf("payloads didn't match: "); - goto end; - } - - uint8_t *pkt = GET_PKT_DATA(p)+(GET_PKT_LEN(p)-sizeof(payload1)+1); - if (memcmp(pkt+10,payload2,2) != 0) { - printf("Segment:\n"); - PrintRawDataFp(stdout,payload2,2); - printf("Packet:\n"); - PrintRawDataFp(stdout,pkt,3); - printf("Packet (full):\n"); - PrintRawDataFp(stdout,GET_PKT_DATA(p),GET_PKT_LEN(p)); - printf("packet data doesn't match: "); - goto end; - } - - result = 1; -end: - if (p != NULL) { - UTHFreePacket(p); - } - if (t != NULL) { - SCFree(t); - } - SCReturnInt(result); -} - -/** \test no overlap */ -static int StreamTcpInlineTest06(void) -{ - SCEnter(); - - uint8_t payload1[] = "xxxxxxxxxxxx"; /* packet */ - uint8_t payload2[] = "ABCDE"; /* segment */ - int result = 0; - TcpSegment *t = NULL; - - Packet *p = UTHBuildPacketSrcDstPorts(payload1, sizeof(payload1)-1, IPPROTO_TCP, 1024, 80); - if (p == NULL || p->tcph == NULL) { - printf("generating test packet failed: "); - goto end; - } - p->tcph->th_seq = htonl(10000020UL); - - t = SCMalloc(sizeof(TcpSegment)); - if (unlikely(t == NULL)) { - printf("alloc TcpSegment failed: "); - goto end; - } - memset(t, 0x00, sizeof(TcpSegment)); - t->payload = payload2; - t->payload_len = sizeof(payload2)-1; - t->seq = 10000000UL; - - StreamTcpInlineSegmentReplacePacket(p, t); - - if (p->flags & PKT_STREAM_MODIFIED) { - printf("PKT_STREAM_MODIFIED pkt flag set, but it shouldn't: "); - goto end; - } - - if (memcmp(p->payload, payload1, sizeof(payload1)-1) != 0) { - printf("Packet:\n"); - PrintRawDataFp(stdout,p->payload,p->payload_len); - printf("Original payload:\n"); - PrintRawDataFp(stdout,payload1,sizeof(payload1)-1); - printf("payloads didn't match: "); - goto end; - } - - uint8_t *pkt = GET_PKT_DATA(p)+(GET_PKT_LEN(p)-sizeof(payload1)+1); - if (memcmp(pkt,payload1,sizeof(payload1)-1) != 0) { - printf("Segment:\n"); - PrintRawDataFp(stdout,payload2,2); - printf("Packet:\n"); - PrintRawDataFp(stdout,pkt,3); - printf("Packet (full):\n"); - PrintRawDataFp(stdout,GET_PKT_DATA(p),GET_PKT_LEN(p)); - printf("packet data doesn't match: "); - goto end; - } - - result = 1; -end: - if (p != NULL) { - UTHFreePacket(p); - } - if (t != NULL) { - SCFree(t); - } - SCReturnInt(result); -} - -/** \test no overlap */ -static int StreamTcpInlineTest07(void) -{ - SCEnter(); - - uint8_t payload1[] = "xxxxxxxxxxxx"; /* packet */ - uint8_t payload2[] = "ABCDE"; /* segment */ - int result = 0; - TcpSegment *t = NULL; - - Packet *p = UTHBuildPacketSrcDstPorts(payload1, sizeof(payload1)-1, IPPROTO_TCP, 1024, 80); - if (p == NULL || p->tcph == NULL) { - printf("generating test packet failed: "); - goto end; - } - p->tcph->th_seq = htonl(10000000UL); - - t = SCMalloc(sizeof(TcpSegment)); - if (unlikely(t == NULL)) { - printf("alloc TcpSegment failed: "); - goto end; - } - memset(t, 0x00, sizeof(TcpSegment)); - t->payload = payload2; - t->payload_len = sizeof(payload2)-1; - t->seq = 10000020UL; - - StreamTcpInlineSegmentReplacePacket(p, t); - - if (p->flags & PKT_STREAM_MODIFIED) { - printf("PKT_STREAM_MODIFIED pkt flag set, but it shouldn't: "); - goto end; - } - - if (memcmp(p->payload, payload1, sizeof(payload1)-1) != 0) { - printf("Packet:\n"); - PrintRawDataFp(stdout,p->payload,p->payload_len); - printf("Original payload:\n"); - PrintRawDataFp(stdout,payload1,sizeof(payload1)-1); - printf("payloads didn't match: "); - goto end; - } - - uint8_t *pkt = GET_PKT_DATA(p)+(GET_PKT_LEN(p)-sizeof(payload1)+1); - if (memcmp(pkt,payload1,sizeof(payload1)-1) != 0) { - printf("Segment:\n"); - PrintRawDataFp(stdout,payload2,2); - printf("Packet:\n"); - PrintRawDataFp(stdout,pkt,3); - printf("Packet (full):\n"); - PrintRawDataFp(stdout,GET_PKT_DATA(p),GET_PKT_LEN(p)); - printf("packet data doesn't match: "); - goto end; - } - - result = 1; -end: - if (p != NULL) { - UTHFreePacket(p); - } - if (t != NULL) { - SCFree(t); - } - SCReturnInt(result); -} -#endif /* UNITTESTS */ - -void StreamTcpInlineRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("StreamTcpInlineTest01", StreamTcpInlineTest01, 1); - UtRegisterTest("StreamTcpInlineTest02", StreamTcpInlineTest02, 1); - UtRegisterTest("StreamTcpInlineTest03", StreamTcpInlineTest03, 1); - UtRegisterTest("StreamTcpInlineTest04", StreamTcpInlineTest04, 1); - UtRegisterTest("StreamTcpInlineTest05", StreamTcpInlineTest05, 1); - UtRegisterTest("StreamTcpInlineTest06", StreamTcpInlineTest06, 1); - UtRegisterTest("StreamTcpInlineTest07", StreamTcpInlineTest07, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/stream-tcp-inline.h b/framework/src/suricata/src/stream-tcp-inline.h deleted file mode 100644 index 49d49781..00000000 --- a/framework/src/suricata/src/stream-tcp-inline.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __STREAM_TCP_INLINE_H__ -#define __STREAM_TCP_INLINE_H__ - -#include "stream-tcp-private.h" - -int StreamTcpInlineMode(void); -int StreamTcpInlineSegmentCompare(TcpSegment *, TcpSegment *); -void StreamTcpInlineSegmentReplacePacket(Packet *, TcpSegment *); - -void StreamTcpInlineRegisterTests(void); - -#endif /* __STREAM_TCP_INLINE_H__ */ - diff --git a/framework/src/suricata/src/stream-tcp-private.h b/framework/src/suricata/src/stream-tcp-private.h deleted file mode 100644 index 5c03c4bc..00000000 --- a/framework/src/suricata/src/stream-tcp-private.h +++ /dev/null @@ -1,246 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __STREAM_TCP_PRIVATE_H__ -#define __STREAM_TCP_PRIVATE_H__ - -#include "decode.h" -#include "util-pool.h" -#include "util-pool-thread.h" - -#define STREAMTCP_QUEUE_FLAG_TS 0x01 -#define STREAMTCP_QUEUE_FLAG_WS 0x02 -#define STREAMTCP_QUEUE_FLAG_SACK 0x04 - -/** currently only SYN/ACK */ -typedef struct TcpStateQueue_ { - uint8_t flags; - uint8_t wscale; - uint16_t win; - uint32_t seq; - uint32_t ack; - uint32_t ts; - uint32_t pkt_ts; - struct TcpStateQueue_ *next; -} TcpStateQueue; - -typedef struct StreamTcpSackRecord_ { - uint32_t le; /**< left edge, host order */ - uint32_t re; /**< right edge, host order */ - struct StreamTcpSackRecord_ *next; -} StreamTcpSackRecord; - -typedef struct TcpSegment_ { - uint8_t *payload; - uint16_t payload_len; /**< actual size of the payload */ - uint16_t pool_size; /**< size of the memory */ - uint32_t seq; - struct TcpSegment_ *next; - struct TcpSegment_ *prev; - /* coccinelle: TcpSegment:flags:SEGMENTTCP_FLAG */ - uint8_t flags; -} TcpSegment; - -typedef struct TcpStream_ { - uint16_t flags:12; /**< Flag specific to the stream e.g. Timestamp */ - /* coccinelle: TcpStream:flags:STREAMTCP_STREAM_FLAG_ */ - uint16_t wscale:4; /**< wscale setting in this direction, 4 bits as max val is 15 */ - uint8_t os_policy; /**< target based OS policy used for reassembly and handling packets*/ - uint8_t tcp_flags; /**< TCP flags seen */ - - uint32_t isn; /**< initial sequence number */ - uint32_t next_seq; /**< next expected sequence number */ - uint32_t last_ack; /**< last ack'd sequence number in this stream */ - uint32_t next_win; /**< next max seq within window */ - uint32_t window; /**< current window setting, after wscale is applied */ - - uint32_t last_ts; /**< Time stamp (TSVAL) of the last seen packet for this stream*/ - uint32_t last_pkt_ts; /**< Time of last seen packet for this stream (needed for PAWS update) - This will be used to validate the last_ts, when connection has been idle for - longer time.(RFC 1323)*/ - /* reassembly */ - uint32_t ra_app_base_seq; /**< reassembled seq. We've reassembled up to this point. */ - uint32_t ra_raw_base_seq; /**< reassembled seq. We've reassembled up to this point. */ - - TcpSegment *seg_list; /**< list of TCP segments that are not yet (fully) used in reassembly */ - TcpSegment *seg_list_tail; /**< Last segment in the reassembled stream seg list*/ - - StreamTcpSackRecord *sack_head; /**< head of list of SACK records */ - StreamTcpSackRecord *sack_tail; /**< tail of list of SACK records */ -} TcpStream; - -/* from /usr/include/netinet/tcp.h */ -enum -{ - TCP_NONE, - TCP_LISTEN, - TCP_SYN_SENT, - TCP_SYN_RECV, - TCP_ESTABLISHED, - TCP_FIN_WAIT1, - TCP_FIN_WAIT2, - TCP_TIME_WAIT, - TCP_LAST_ACK, - TCP_CLOSE_WAIT, - TCP_CLOSING, - TCP_CLOSED, -}; - -/* - * Per SESSION flags - */ - -/** Flag for mid stream session */ -#define STREAMTCP_FLAG_MIDSTREAM 0x0001 -/** Flag for mid stream established session */ -#define STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED 0x0002 -/** Flag for mid session when syn/ack is received */ -#define STREAMTCP_FLAG_MIDSTREAM_SYNACK 0x0004 -/** Flag for TCP Timestamp option */ -#define STREAMTCP_FLAG_TIMESTAMP 0x0008 -/** Server supports wscale (even though it can be 0) */ -#define STREAMTCP_FLAG_SERVER_WSCALE 0x0010 -/** 'Raw' reassembly is disabled for this ssn. */ -#define STREAMTCP_FLAG_DISABLE_RAW 0x0020 -/** Flag to indicate that the session is handling asynchronous stream.*/ -#define STREAMTCP_FLAG_ASYNC 0x0040 -/** Flag to indicate we're dealing with 4WHS: SYN, SYN, SYN/ACK, ACK - * (http://www.breakingpointsystems.com/community/blog/tcp-portals-the-three-way-handshake-is-a-lie) */ -#define STREAMTCP_FLAG_4WHS 0x0080 -/** Flag to indicate that this session is possible trying to evade the detection - * (http://www.packetstan.com/2010/06/recently-ive-been-on-campaign-to-make.html) */ -#define STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT 0x0100 -/** Flag to indicate the client (SYN pkt) permits SACK */ -#define STREAMTCP_FLAG_CLIENT_SACKOK 0x0200 -/** Flag to indicate both sides of the session permit SACK (SYN + SYN/ACK) */ -#define STREAMTCP_FLAG_SACKOK 0x0400 -/** Flag for triggering RAW reassembly before the size limit is reached or - the stream reaches EOF. */ -#define STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY 0x0800 -/** 3WHS confirmed by server -- if suri sees 3whs ACK but server doesn't (pkt - * is lost on the way to server), SYN/ACK is retransmitted. If server sends - * normal packet we assume 3whs to be completed. Only used for SYN/ACK resend - * event. */ -#define STREAMTCP_FLAG_3WHS_CONFIRMED 0x1000 -/** App Layer tracking/reassembly is disabled */ -#define STREAMTCP_FLAG_APP_LAYER_DISABLED 0x2000 - -/* - * Per STREAM flags - */ - -/** stream is in a gap state */ -#define STREAMTCP_STREAM_FLAG_GAP 0x0001 -/** Flag to avoid stream reassembly/app layer inspection for the stream */ -#define STREAMTCP_STREAM_FLAG_NOREASSEMBLY 0x0002 -/** we received a keep alive */ -#define STREAMTCP_STREAM_FLAG_KEEPALIVE 0x0004 -/** Stream has reached it's reassembly depth, all further packets are ignored */ -#define STREAMTCP_STREAM_FLAG_DEPTH_REACHED 0x0008 -// vacancy -/** Stream supports TIMESTAMP -- used to set ssn STREAMTCP_FLAG_TIMESTAMP - * flag. */ -#define STREAMTCP_STREAM_FLAG_TIMESTAMP 0x0020 -/** Flag to indicate the zero value of timestamp */ -#define STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP 0x0040 -/** App proto detection completed */ -#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED 0x0080 -/** App proto detection skipped */ -#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_SKIPPED 0x0100 -/** Raw reassembly disabled for new segments */ -#define STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED 0x0200 -// vacancy 2x -/** NOTE: flags field is 12 bits */ - - -/* - * Per SEGMENT flags - */ -/** Flag to indicate that the current segment has been processed by the - * reassembly code and should be deleted after app layer protocol has been - * detected. */ -#define SEGMENTTCP_FLAG_RAW_PROCESSED 0x01 -/** App Layer reassembly code is done with this segment */ -#define SEGMENTTCP_FLAG_APPLAYER_PROCESSED 0x02 -/** Log API (streaming) has processed this segment */ -#define SEGMENTTCP_FLAG_LOGAPI_PROCESSED 0x04 - - -#define PAWS_24DAYS 2073600 /**< 24 days in seconds */ - -#define PKT_IS_IN_RIGHT_DIR(ssn, p) ((ssn)->flags & STREAMTCP_FLAG_MIDSTREAM_SYNACK ? \ - PKT_IS_TOSERVER(p) ? (p)->flowflags &= ~FLOW_PKT_TOSERVER \ - (p)->flowflags |= FLOW_PKT_TOCLIENT : (p)->flowflags &= ~FLOW_PKT_TOCLIENT \ - (p)->flowflags |= FLOW_PKT_TOSERVER : 0) - -/* Macro's for comparing Sequence numbers - * Page 810 from TCP/IP Illustrated, Volume 2. */ -#define SEQ_EQ(a,b) ((int32_t)((a) - (b)) == 0) -#define SEQ_LT(a,b) ((int32_t)((a) - (b)) < 0) -#define SEQ_LEQ(a,b) ((int32_t)((a) - (b)) <= 0) -#define SEQ_GT(a,b) ((int32_t)((a) - (b)) > 0) -#define SEQ_GEQ(a,b) ((int32_t)((a) - (b)) >= 0) - -#define STREAMTCP_SET_RA_BASE_SEQ(stream, seq) { \ - do { \ - (stream)->ra_raw_base_seq = (seq); \ - (stream)->ra_app_base_seq = (seq); \ - } while(0); \ -} - -#define StreamTcpSetEvent(p, e) { \ - SCLogDebug("setting event %"PRIu8" on pkt %p (%"PRIu64")", (e), p, (p)->pcap_cnt); \ - ENGINE_SET_EVENT((p), (e)); \ -} - -typedef struct TcpSession_ { - PoolThreadReserved res; - uint8_t state; - uint8_t queue_len; /**< length of queue list below */ - int8_t data_first_seen_dir; - /** track all the tcp flags we've seen */ - uint8_t tcp_packet_flags; - /* coccinelle: TcpSession:flags:STREAMTCP_FLAG */ - uint16_t flags; - TcpStream server; - TcpStream client; - struct StreamMsg_ *toserver_smsg_head; /**< list of stream msgs (for detection inspection) */ - struct StreamMsg_ *toserver_smsg_tail; /**< list of stream msgs (for detection inspection) */ - struct StreamMsg_ *toclient_smsg_head; /**< list of stream msgs (for detection inspection) */ - struct StreamMsg_ *toclient_smsg_tail; /**< list of stream msgs (for detection inspection) */ - - TcpStateQueue *queue; /**< list of SYN/ACK candidates */ -} TcpSession; - -#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream) \ - ((stream)->flags |= STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) -#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream) \ - ((stream)->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) -#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream) \ - ((stream)->flags &= ~STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED); -#define StreamTcpDisableAppLayerReassembly(ssn) do { \ - SCLogDebug("setting STREAMTCP_FLAG_APP_LAYER_DISABLED on ssn %p", ssn); \ - ((ssn)->flags |= STREAMTCP_FLAG_APP_LAYER_DISABLED); \ - } while (0); - -#endif /* __STREAM_TCP_PRIVATE_H__ */ diff --git a/framework/src/suricata/src/stream-tcp-reassemble.c b/framework/src/suricata/src/stream-tcp-reassemble.c deleted file mode 100644 index a947fab3..00000000 --- a/framework/src/suricata/src/stream-tcp-reassemble.c +++ /dev/null @@ -1,8757 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * \author Victor Julien - * - * Reference: - * Judy Novak, Steve Sturges: Target-Based TCP Stream Reassembly August, 2007 - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "debug.h" -#include "detect.h" -#include "flow.h" -#include "threads.h" -#include "conf.h" - -#include "flow-util.h" - -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-pool.h" -#include "util-unittest.h" -#include "util-print.h" -#include "util-host-os-info.h" -#include "util-unittest-helper.h" -#include "util-byte.h" - -#include "stream-tcp.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp-inline.h" -#include "stream-tcp-util.h" - -#include "stream.h" - -#include "util-debug.h" -#include "app-layer-protos.h" -#include "app-layer.h" -#include "app-layer-events.h" - -#include "detect-engine-state.h" - -#include "util-profiling.h" - -#define PSEUDO_PACKET_PAYLOAD_SIZE 65416 /* 64 Kb minus max IP and TCP header */ - -#ifdef DEBUG -static SCMutex segment_pool_memuse_mutex; -static uint64_t segment_pool_memuse = 0; -static uint64_t segment_pool_memcnt = 0; -#endif - -/* We define several pools with prealloced segments with fixed size - * payloads. We do this to prevent having to do an SCMalloc call for every - * data segment we receive, which would be a large performance penalty. - * The cost is in memory of course. The number of pools and the properties - * of the pools are determined by the yaml. */ -static int segment_pool_num = 0; -static Pool **segment_pool = NULL; -static SCMutex *segment_pool_mutex = NULL; -static uint16_t *segment_pool_pktsizes = NULL; -#ifdef DEBUG -static SCMutex segment_pool_cnt_mutex; -static uint64_t segment_pool_cnt = 0; -#endif -/* index to the right pool for all packet sizes. */ -static uint16_t segment_pool_idx[65536]; /* O(1) lookups of the pool */ -static int check_overlap_different_data = 0; - -/* Memory use counter */ -SC_ATOMIC_DECLARE(uint64_t, ra_memuse); - -/* prototypes */ -static int HandleSegmentStartsBeforeListSegment(ThreadVars *, TcpReassemblyThreadCtx *, - TcpStream *, TcpSegment *, TcpSegment *, Packet *); -static int HandleSegmentStartsAtSameListSegment(ThreadVars *, TcpReassemblyThreadCtx *, - TcpStream *, TcpSegment *, TcpSegment *, Packet *); -static int HandleSegmentStartsAfterListSegment(ThreadVars *, TcpReassemblyThreadCtx *, - TcpStream *, TcpSegment *, TcpSegment *, Packet *); -void StreamTcpSegmentDataReplace(TcpSegment *, TcpSegment *, uint32_t, uint16_t); -void StreamTcpSegmentDataCopy(TcpSegment *, TcpSegment *); -TcpSegment* StreamTcpGetSegment(ThreadVars *tv, TcpReassemblyThreadCtx *, uint16_t); -void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t); -void StreamTcpReassemblePseudoPacketCreate(TcpStream *, Packet *, PacketQueue *); -static int StreamTcpSegmentDataCompare(TcpSegment *dst_seg, TcpSegment *src_seg, - uint32_t start_point, uint16_t len); - -void StreamTcpReassembleConfigEnableOverlapCheck(void) -{ - check_overlap_different_data = 1; -} - -/** - * \brief Function to Increment the memory usage counter for the TCP reassembly - * segments - * - * \param size Size of the TCP segment and its payload length memory allocated - */ -void StreamTcpReassembleIncrMemuse(uint64_t size) -{ - (void) SC_ATOMIC_ADD(ra_memuse, size); - return; -} - -/** - * \brief Function to Decrease the memory usage counter for the TCP reassembly - * segments - * - * \param size Size of the TCP segment and its payload length memory allocated - */ -void StreamTcpReassembleDecrMemuse(uint64_t size) -{ - (void) SC_ATOMIC_SUB(ra_memuse, size); - return; -} - -uint64_t StreamTcpReassembleMemuseGlobalCounter(void) -{ - uint64_t smemuse = SC_ATOMIC_GET(ra_memuse); - return smemuse; -} - -/** - * \brief Function to Check the reassembly memory usage counter against the - * allowed max memory usgae for TCP segments. - * - * \param size Size of the TCP segment and its payload length memory allocated - * \retval 1 if in bounds - * \retval 0 if not in bounds - */ -int StreamTcpReassembleCheckMemcap(uint32_t size) -{ - if (stream_config.reassembly_memcap == 0 || - (uint64_t)((uint64_t)size + SC_ATOMIC_GET(ra_memuse)) <= stream_config.reassembly_memcap) - return 1; - return 0; -} - -/** \brief alloc a tcp segment pool entry */ -void *TcpSegmentPoolAlloc() -{ - if (StreamTcpReassembleCheckMemcap((uint32_t)sizeof(TcpSegment)) == 0) { - return NULL; - } - - TcpSegment *seg = NULL; - - seg = SCMalloc(sizeof (TcpSegment)); - if (unlikely(seg == NULL)) - return NULL; - return seg; -} - -int TcpSegmentPoolInit(void *data, void *payload_len) -{ - TcpSegment *seg = (TcpSegment *) data; - uint16_t size = *((uint16_t *) payload_len); - - /* do this before the can bail, so TcpSegmentPoolCleanup - * won't have uninitialized memory to consider. */ - memset(seg, 0, sizeof (TcpSegment)); - - if (StreamTcpReassembleCheckMemcap((uint32_t)size + (uint32_t)sizeof(TcpSegment)) == 0) { - return 0; - } - - seg->pool_size = size; - seg->payload_len = seg->pool_size; - - seg->payload = SCMalloc(seg->payload_len); - if (seg->payload == NULL) { - return 0; - } - -#ifdef DEBUG - SCMutexLock(&segment_pool_memuse_mutex); - segment_pool_memuse += seg->payload_len; - segment_pool_memcnt++; - SCLogDebug("segment_pool_memcnt %"PRIu64"", segment_pool_memcnt); - SCMutexUnlock(&segment_pool_memuse_mutex); -#endif - - StreamTcpReassembleIncrMemuse((uint32_t)seg->pool_size + sizeof(TcpSegment)); - return 1; -} - -/** \brief clean up a tcp segment pool entry */ -void TcpSegmentPoolCleanup(void *ptr) -{ - if (ptr == NULL) - return; - - TcpSegment *seg = (TcpSegment *) ptr; - - StreamTcpReassembleDecrMemuse((uint32_t)seg->pool_size + sizeof(TcpSegment)); - -#ifdef DEBUG - SCMutexLock(&segment_pool_memuse_mutex); - segment_pool_memuse -= seg->pool_size; - segment_pool_memcnt--; - SCLogDebug("segment_pool_memcnt %"PRIu64"", segment_pool_memcnt); - SCMutexUnlock(&segment_pool_memuse_mutex); -#endif - - SCFree(seg->payload); - return; -} - -/** - * \brief Function to return the segment back to the pool. - * - * \param seg Segment which will be returned back to the pool. - */ -void StreamTcpSegmentReturntoPool(TcpSegment *seg) -{ - if (seg == NULL) - return; - - seg->next = NULL; - seg->prev = NULL; - - uint16_t idx = segment_pool_idx[seg->pool_size]; - SCMutexLock(&segment_pool_mutex[idx]); - PoolReturn(segment_pool[idx], (void *) seg); - SCLogDebug("segment_pool[%"PRIu16"]->empty_stack_size %"PRIu32"", - idx,segment_pool[idx]->empty_stack_size); - SCMutexUnlock(&segment_pool_mutex[idx]); - -#ifdef DEBUG - SCMutexLock(&segment_pool_cnt_mutex); - segment_pool_cnt--; - SCMutexUnlock(&segment_pool_cnt_mutex); -#endif -} - -/** - * \brief return all segments in this stream into the pool(s) - * - * \param stream the stream to cleanup - */ -void StreamTcpReturnStreamSegments (TcpStream *stream) -{ - TcpSegment *seg = stream->seg_list; - TcpSegment *next_seg; - - if (seg == NULL) - return; - - while (seg != NULL) { - next_seg = seg->next; - StreamTcpSegmentReturntoPool(seg); - seg = next_seg; - } - - stream->seg_list = NULL; - stream->seg_list_tail = NULL; -} - -/** \param f locked flow */ -void StreamTcpDisableAppLayer(Flow *f) -{ - if (f->protoctx == NULL) - return; - - TcpSession *ssn = (TcpSession *)f->protoctx; - StreamTcpSetStreamFlagAppProtoDetectionCompleted(&ssn->client); - StreamTcpSetStreamFlagAppProtoDetectionCompleted(&ssn->server); - StreamTcpDisableAppLayerReassembly(ssn); -} - -/** \param f locked flow */ -int StreamTcpAppLayerIsDisabled(Flow *f) -{ - if (f->protoctx == NULL || f->proto != IPPROTO_TCP) - return 0; - - TcpSession *ssn = (TcpSession *)f->protoctx; - return (ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED); -} - -typedef struct SegmentSizes_ -{ - uint16_t pktsize; - uint32_t prealloc; -} SegmentSizes; - -/* sort small to big */ -static int SortByPktsize(const void *a, const void *b) -{ - const SegmentSizes *s0 = a; - const SegmentSizes *s1 = b; - return s0->pktsize - s1->pktsize; -} - -int StreamTcpReassemblyConfig(char quiet) -{ - Pool **my_segment_pool = NULL; - SCMutex *my_segment_lock = NULL; - uint16_t *my_segment_pktsizes = NULL; - SegmentSizes sizes[256]; - memset(&sizes, 0x00, sizeof(sizes)); - - int npools = 0; - ConfNode *segs = ConfGetNode("stream.reassembly.segments"); - if (segs != NULL) { - ConfNode *seg; - TAILQ_FOREACH(seg, &segs->head, next) { - ConfNode *segsize = ConfNodeLookupChild(seg,"size"); - if (segsize == NULL) - continue; - ConfNode *segpre = ConfNodeLookupChild(seg,"prealloc"); - if (segpre == NULL) - continue; - - if (npools >= 256) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "too many segment packet " - "pools defined, max is 256"); - return -1; - } - - SCLogDebug("segsize->val %s", segsize->val); - SCLogDebug("segpre->val %s", segpre->val); - - uint16_t pktsize = 0; - if (ByteExtractStringUint16(&pktsize, 10, strlen(segsize->val), - segsize->val) == -1) - { - SCLogError(SC_ERR_INVALID_ARGUMENT, "segment packet size " - "of %s is invalid", segsize->val); - return -1; - } - uint32_t prealloc = 0; - if (ByteExtractStringUint32(&prealloc, 10, strlen(segpre->val), - segpre->val) == -1) - { - SCLogError(SC_ERR_INVALID_ARGUMENT, "segment prealloc of " - "%s is invalid", segpre->val); - return -1; - } - - sizes[npools].pktsize = pktsize; - sizes[npools].prealloc = prealloc; - SCLogDebug("pktsize %u, prealloc %u", sizes[npools].pktsize, - sizes[npools].prealloc); - npools++; - } - } - - SCLogDebug("npools %d", npools); - if (npools > 0) { - /* sort the array as the index code below relies on it */ - qsort(&sizes, npools, sizeof(sizes[0]), SortByPktsize); - if (sizes[npools - 1].pktsize != 0xffff) { - sizes[npools].pktsize = 0xffff; - sizes[npools].prealloc = 8; - npools++; - SCLogInfo("appended a segment pool for pktsize 65536"); - } - } else if (npools == 0) { - /* defaults */ - sizes[0].pktsize = 4; - sizes[0].prealloc = 256; - sizes[1].pktsize = 16; - sizes[1].prealloc = 512; - sizes[2].pktsize = 112; - sizes[2].prealloc = 512; - sizes[3].pktsize = 248; - sizes[3].prealloc = 512; - sizes[4].pktsize = 512; - sizes[4].prealloc = 512; - sizes[5].pktsize = 768; - sizes[5].prealloc = 1024; - sizes[6].pktsize = 1448; - sizes[6].prealloc = 1024; - sizes[7].pktsize = 0xffff; - sizes[7].prealloc = 128; - npools = 8; - } - - int i = 0; - for (i = 0; i < npools; i++) { - SCLogDebug("pktsize %u, prealloc %u", sizes[i].pktsize, sizes[i].prealloc); - } - - my_segment_pool = SCMalloc(npools * sizeof(Pool *)); - if (my_segment_pool == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "malloc failed"); - return -1; - } - my_segment_lock = SCMalloc(npools * sizeof(SCMutex)); - if (my_segment_lock == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "malloc failed"); - - SCFree(my_segment_pool); - return -1; - } - my_segment_pktsizes = SCMalloc(npools * sizeof(uint16_t)); - if (my_segment_pktsizes == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "malloc failed"); - - SCFree(my_segment_lock); - SCFree(my_segment_pool); - return -1; - } - uint32_t my_segment_poolsizes[npools]; - - for (i = 0; i < npools; i++) { - my_segment_pktsizes[i] = sizes[i].pktsize; - my_segment_poolsizes[i] = sizes[i].prealloc; - SCMutexInit(&my_segment_lock[i], NULL); - - /* setup the pool */ - SCMutexLock(&my_segment_lock[i]); - my_segment_pool[i] = PoolInit(0, my_segment_poolsizes[i], 0, - TcpSegmentPoolAlloc, TcpSegmentPoolInit, - (void *) &my_segment_pktsizes[i], - TcpSegmentPoolCleanup, NULL); - SCMutexUnlock(&my_segment_lock[i]); - - if (my_segment_pool[i] == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "couldn't set up segment pool " - "for packet size %u. Memcap too low?", my_segment_pktsizes[i]); - exit(EXIT_FAILURE); - } - - SCLogDebug("my_segment_pktsizes[i] %u, my_segment_poolsizes[i] %u", - my_segment_pktsizes[i], my_segment_poolsizes[i]); - if (!quiet) - SCLogInfo("segment pool: pktsize %u, prealloc %u", - my_segment_pktsizes[i], my_segment_poolsizes[i]); - } - - uint16_t idx = 0; - uint16_t u16 = 0; - while (1) { - if (idx <= my_segment_pktsizes[u16]) { - segment_pool_idx[idx] = u16; - if (my_segment_pktsizes[u16] == idx) - u16++; - } - - if (idx == 0xffff) - break; - - idx++; - } - /* set the globals */ - segment_pool = my_segment_pool; - segment_pool_mutex = my_segment_lock; - segment_pool_pktsizes = my_segment_pktsizes; - segment_pool_num = npools; - - uint32_t stream_chunk_prealloc = 250; - ConfNode *chunk = ConfGetNode("stream.reassembly.chunk-prealloc"); - if (chunk) { - uint32_t prealloc = 0; - if (ByteExtractStringUint32(&prealloc, 10, strlen(chunk->val), chunk->val) == -1) - { - SCLogError(SC_ERR_INVALID_ARGUMENT, "chunk-prealloc of " - "%s is invalid", chunk->val); - return -1; - } - stream_chunk_prealloc = prealloc; - } - if (!quiet) - SCLogInfo("stream.reassembly \"chunk-prealloc\": %u", stream_chunk_prealloc); - StreamMsgQueuesInit(stream_chunk_prealloc); - - intmax_t zero_copy_size = 128; - if (ConfGetInt("stream.reassembly.zero-copy-size", &zero_copy_size) == 1) { - if (zero_copy_size < 0 || zero_copy_size > 0xffff) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "stream.reassembly.zero-copy-size of " - "%"PRIiMAX" is invalid: valid values are 0 to 65535", zero_copy_size); - return -1; - } - } - stream_config.zero_copy_size = (uint16_t)zero_copy_size; - if (!quiet) - SCLogInfo("stream.reassembly \"zero-copy-size\": %u", stream_config.zero_copy_size); - - return 0; -} - -int StreamTcpReassembleInit(char quiet) -{ - /* init the memcap/use tracker */ - SC_ATOMIC_INIT(ra_memuse); - - if (StreamTcpReassemblyConfig(quiet) < 0) - return -1; -#ifdef DEBUG - SCMutexInit(&segment_pool_memuse_mutex, NULL); - SCMutexInit(&segment_pool_cnt_mutex, NULL); -#endif - - StatsRegisterGlobalCounter("tcp.reassembly_memuse", - StreamTcpReassembleMemuseGlobalCounter); - return 0; -} - -#ifdef DEBUG -static uint32_t dbg_app_layer_gap; -static uint32_t dbg_app_layer_gap_candidate; -#endif - -void StreamTcpReassembleFree(char quiet) -{ - uint16_t u16 = 0; - for (u16 = 0; u16 < segment_pool_num; u16++) { - SCMutexLock(&segment_pool_mutex[u16]); - - if (quiet == FALSE) { - PoolPrintSaturation(segment_pool[u16]); - SCLogDebug("segment_pool[u16]->empty_stack_size %"PRIu32", " - "segment_pool[u16]->alloc_stack_size %"PRIu32", alloced " - "%"PRIu32"", segment_pool[u16]->empty_stack_size, - segment_pool[u16]->alloc_stack_size, - segment_pool[u16]->allocated); - - if (segment_pool[u16]->max_outstanding > segment_pool[u16]->allocated) { - SCLogInfo("TCP segment pool of size %u had a peak use of %u segments, " - "more than the prealloc setting of %u", segment_pool_pktsizes[u16], - segment_pool[u16]->max_outstanding, segment_pool[u16]->allocated); - } - } - PoolFree(segment_pool[u16]); - - SCMutexUnlock(&segment_pool_mutex[u16]); - SCMutexDestroy(&segment_pool_mutex[u16]); - } - SCFree(segment_pool); - SCFree(segment_pool_mutex); - SCFree(segment_pool_pktsizes); - segment_pool = NULL; - segment_pool_mutex = NULL; - segment_pool_pktsizes = NULL; - - StreamMsgQueuesDeinit(quiet); - -#ifdef DEBUG - SCLogDebug("segment_pool_cnt %"PRIu64"", segment_pool_cnt); - SCLogDebug("segment_pool_memuse %"PRIu64"", segment_pool_memuse); - SCLogDebug("segment_pool_memcnt %"PRIu64"", segment_pool_memcnt); - SCMutexDestroy(&segment_pool_memuse_mutex); - SCMutexDestroy(&segment_pool_cnt_mutex); - SCLogInfo("dbg_app_layer_gap %u", dbg_app_layer_gap); - SCLogInfo("dbg_app_layer_gap_candidate %u", dbg_app_layer_gap_candidate); -#endif -} - -TcpReassemblyThreadCtx *StreamTcpReassembleInitThreadCtx(ThreadVars *tv) -{ - SCEnter(); - TcpReassemblyThreadCtx *ra_ctx = SCMalloc(sizeof(TcpReassemblyThreadCtx)); - if (unlikely(ra_ctx == NULL)) - return NULL; - - memset(ra_ctx, 0x00, sizeof(TcpReassemblyThreadCtx)); - - ra_ctx->app_tctx = AppLayerGetCtxThread(tv); - - SCReturnPtr(ra_ctx, "TcpReassemblyThreadCtx"); -} - -void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *ra_ctx) -{ - SCEnter(); - AppLayerDestroyCtxThread(ra_ctx->app_tctx); -#ifdef DEBUG - SCLogDebug("reassembly fast path stats: fp1 %"PRIu64" fp2 %"PRIu64" sp %"PRIu64, - ra_ctx->fp1, ra_ctx->fp2, ra_ctx->sp); -#endif - SCFree(ra_ctx); - SCReturn; -} - -void PrintList2(TcpSegment *seg) -{ - TcpSegment *prev_seg = NULL; - - if (seg == NULL) - return; - - uint32_t next_seq = seg->seq; - - while (seg != NULL) { - if (SEQ_LT(next_seq,seg->seq)) { - SCLogDebug("missing segment(s) for %" PRIu32 " bytes of data", - (seg->seq - next_seq)); - } - - SCLogDebug("seg %10"PRIu32" len %" PRIu16 ", seg %p, prev %p, next %p", - seg->seq, seg->payload_len, seg, seg->prev, seg->next); - - if (seg->prev != NULL && SEQ_LT(seg->seq,seg->prev->seq)) { - /* check for SEQ_LT cornercase where a - b is exactly 2147483648, - * which makes the marco return TRUE in both directions. This is - * a hack though, we're going to check next how we end up with - * a segment list with seq differences that big */ - if (!(SEQ_LT(seg->prev->seq,seg->seq))) { - SCLogDebug("inconsistent list: SEQ_LT(seg->seq,seg->prev->seq)) ==" - " TRUE, seg->seq %" PRIu32 ", seg->prev->seq %" PRIu32 "" - "", seg->seq, seg->prev->seq); - } - } - - if (SEQ_LT(seg->seq,next_seq)) { - SCLogDebug("inconsistent list: SEQ_LT(seg->seq,next_seq)) == TRUE, " - "seg->seq %" PRIu32 ", next_seq %" PRIu32 "", seg->seq, - next_seq); - } - - if (prev_seg != seg->prev) { - SCLogDebug("inconsistent list: prev_seg %p != seg->prev %p", - prev_seg, seg->prev); - } - - next_seq = seg->seq + seg->payload_len; - SCLogDebug("next_seq is now %"PRIu32"", next_seq); - prev_seg = seg; - seg = seg->next; - } -} - -void PrintList(TcpSegment *seg) -{ - TcpSegment *prev_seg = NULL; - TcpSegment *head_seg = seg; - - if (seg == NULL) - return; - - uint32_t next_seq = seg->seq; - - while (seg != NULL) { - if (SEQ_LT(next_seq,seg->seq)) { - SCLogDebug("missing segment(s) for %" PRIu32 " bytes of data", - (seg->seq - next_seq)); - } - - SCLogDebug("seg %10"PRIu32" len %" PRIu16 ", seg %p, prev %p, next %p, flags 0x%02x", - seg->seq, seg->payload_len, seg, seg->prev, seg->next, seg->flags); - - if (seg->prev != NULL && SEQ_LT(seg->seq,seg->prev->seq)) { - /* check for SEQ_LT cornercase where a - b is exactly 2147483648, - * which makes the marco return TRUE in both directions. This is - * a hack though, we're going to check next how we end up with - * a segment list with seq differences that big */ - if (!(SEQ_LT(seg->prev->seq,seg->seq))) { - SCLogDebug("inconsistent list: SEQ_LT(seg->seq,seg->prev->seq)) == " - "TRUE, seg->seq %" PRIu32 ", seg->prev->seq %" PRIu32 "", - seg->seq, seg->prev->seq); - PrintList2(head_seg); - abort(); - } - } - - if (SEQ_LT(seg->seq,next_seq)) { - SCLogDebug("inconsistent list: SEQ_LT(seg->seq,next_seq)) == TRUE, " - "seg->seq %" PRIu32 ", next_seq %" PRIu32 "", seg->seq, - next_seq); - PrintList2(head_seg); - abort(); - } - - if (prev_seg != seg->prev) { - SCLogDebug("inconsistent list: prev_seg %p != seg->prev %p", - prev_seg, seg->prev); - PrintList2(head_seg); - abort(); - } - - next_seq = seg->seq + seg->payload_len; - SCLogDebug("next_seq is now %"PRIu32"", next_seq); - prev_seg = seg; - seg = seg->next; - } -} - -/** - * \internal - * \brief Get the active ra_base_seq, considering stream gaps - * - * \retval seq the active ra_base_seq - */ -static inline uint32_t StreamTcpReassembleGetRaBaseSeq(TcpStream *stream) -{ - if (!(stream->flags & STREAMTCP_STREAM_FLAG_GAP)) { - SCReturnUInt(stream->ra_app_base_seq); - } else { - SCReturnUInt(stream->ra_raw_base_seq); - } -} - -/** - * \internal - * \brief Function to handle the insertion newly arrived segment, - * The packet is handled based on its target OS. - * - * \param stream The given TCP stream to which this new segment belongs - * \param seg Newly arrived segment - * \param p received packet - * - * \retval 0 success - * \retval -1 error -- either we hit a memory issue (OOM/memcap) or we received - * a segment before ra_base_seq. - */ -int StreamTcpReassembleInsertSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpStream *stream, TcpSegment *seg, Packet *p) -{ - SCEnter(); - - TcpSegment *list_seg = stream->seg_list; - TcpSegment *next_list_seg = NULL; - -#if DEBUG - PrintList(stream->seg_list); -#endif - - int ret_value = 0; - char return_seg = FALSE; - - /* before our ra_app_base_seq we don't insert it in our list, - * or ra_raw_base_seq if in stream gap state */ - if (SEQ_LT((TCP_GET_SEQ(p)+p->payload_len),(StreamTcpReassembleGetRaBaseSeq(stream)+1))) - { - SCLogDebug("not inserting: SEQ+payload %"PRIu32", last_ack %"PRIu32", " - "ra_(app|raw)_base_seq %"PRIu32, (TCP_GET_SEQ(p)+p->payload_len), - stream->last_ack, StreamTcpReassembleGetRaBaseSeq(stream)+1); - return_seg = TRUE; - ret_value = -1; - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ); - goto end; - } - - SCLogDebug("SEQ %"PRIu32", SEQ+payload %"PRIu32", last_ack %"PRIu32", " - "ra_app_base_seq %"PRIu32, TCP_GET_SEQ(p), (TCP_GET_SEQ(p)+p->payload_len), - stream->last_ack, stream->ra_app_base_seq); - - if (seg == NULL) { - goto end; - } - - /* fast track */ - if (list_seg == NULL) { - SCLogDebug("empty list, inserting seg %p seq %" PRIu32 ", " - "len %" PRIu32 "", seg, seg->seq, seg->payload_len); - stream->seg_list = seg; - seg->prev = NULL; - stream->seg_list_tail = seg; - goto end; - } - - /* insert the segment in the stream list using this fast track, if seg->seq - is equal or higher than stream->seg_list_tail.*/ - if (SEQ_GEQ(seg->seq, (stream->seg_list_tail->seq + - stream->seg_list_tail->payload_len))) - { - stream->seg_list_tail->next = seg; - seg->prev = stream->seg_list_tail; - stream->seg_list_tail = seg; - - goto end; - } - - /* If the OS policy is not set then set the OS policy for this stream */ - if (stream->os_policy == 0) { - StreamTcpSetOSPolicy(stream, p); - } - - for (; list_seg != NULL; list_seg = next_list_seg) { - next_list_seg = list_seg->next; - - SCLogDebug("seg %p, list_seg %p, list_prev %p list_seg->next %p, " - "segment length %" PRIu32 "", seg, list_seg, list_seg->prev, - list_seg->next, seg->payload_len); - SCLogDebug("seg->seq %"PRIu32", list_seg->seq %"PRIu32"", - seg->seq, list_seg->seq); - - /* segment starts before list */ - if (SEQ_LT(seg->seq, list_seg->seq)) { - /* seg is entirely before list_seg */ - if (SEQ_LEQ((seg->seq + seg->payload_len), list_seg->seq)) { - SCLogDebug("before list seg: seg->seq %" PRIu32 ", list_seg->seq" - " %" PRIu32 ", list_seg->payload_len %" PRIu32 ", " - "list_seg->prev %p", seg->seq, list_seg->seq, - list_seg->payload_len, list_seg->prev); - seg->next = list_seg; - if (list_seg->prev == NULL) { - stream->seg_list = seg; - } - if (list_seg->prev != NULL) { - list_seg->prev->next = seg; - seg->prev = list_seg->prev; - } - list_seg->prev = seg; - - goto end; - - /* seg overlap with next seg(s) */ - } else { - ret_value = HandleSegmentStartsBeforeListSegment(tv, ra_ctx, stream, list_seg, seg, p); - if (ret_value == 1) { - ret_value = 0; - return_seg = TRUE; - goto end; - } else if (ret_value == -1) { - SCLogDebug("HandleSegmentStartsBeforeListSegment failed"); - ret_value = -1; - return_seg = TRUE; - goto end; - } - } - - /* seg starts at same sequence number as list_seg */ - } else if (SEQ_EQ(seg->seq, list_seg->seq)) { - ret_value = HandleSegmentStartsAtSameListSegment(tv, ra_ctx, stream, list_seg, seg, p); - if (ret_value == 1) { - ret_value = 0; - return_seg = TRUE; - goto end; - } else if (ret_value == -1) { - SCLogDebug("HandleSegmentStartsAtSameListSegment failed"); - ret_value = -1; - return_seg = TRUE; - goto end; - } - - /* seg starts at sequence number higher than list_seg */ - } else if (SEQ_GT(seg->seq, list_seg->seq)) { - if (((SEQ_GEQ(seg->seq, (list_seg->seq + list_seg->payload_len)))) - && SEQ_GT((seg->seq + seg->payload_len), - (list_seg->seq + list_seg->payload_len))) - { - SCLogDebug("starts beyond list end, ends after list end: " - "seg->seq %" PRIu32 ", list_seg->seq %" PRIu32 ", " - "list_seg->payload_len %" PRIu32 " (%" PRIu32 ")", - seg->seq, list_seg->seq, list_seg->payload_len, - list_seg->seq + list_seg->payload_len); - - if (list_seg->next == NULL) { - list_seg->next = seg; - seg->prev = list_seg; - stream->seg_list_tail = seg; - goto end; - } - } else { - ret_value = HandleSegmentStartsAfterListSegment(tv, ra_ctx, stream, list_seg, seg, p); - if (ret_value == 1) { - ret_value = 0; - return_seg = TRUE; - goto end; - } else if (ret_value == -1) { - SCLogDebug("HandleSegmentStartsAfterListSegment failed"); - ret_value = -1; - return_seg = TRUE; - goto end; - } - } - } - } - -end: - if (return_seg == TRUE && seg != NULL) { - StreamTcpSegmentReturntoPool(seg); - } - -#ifdef DEBUG - PrintList(stream->seg_list); -#endif - SCReturnInt(ret_value); -} - -/** - * \brief Function to handle the newly arrived segment, when newly arrived - * starts with the sequence number lower than the original segment and - * ends at different position relative to original segment. - * The packet is handled based on its target OS. - * - * \param list_seg Original Segment in the stream - * \param seg Newly arrived segment - * \param prev_seg Previous segment in the stream segment list - * \param p Packet - * - * \retval 1 success and done - * \retval 0 success, but not done yet - * \retval -1 error, will *only* happen on memory errors - */ - -static int HandleSegmentStartsBeforeListSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpStream *stream, TcpSegment *list_seg, TcpSegment *seg, Packet *p) -{ - SCEnter(); - - uint16_t overlap = 0; - uint16_t packet_length = 0; - uint32_t overlap_point = 0; - char end_before = FALSE; - char end_after = FALSE; - char end_same = FALSE; - char return_after = FALSE; - uint8_t os_policy = stream->os_policy; -#ifdef DEBUG - SCLogDebug("seg->seq %" PRIu32 ", seg->payload_len %" PRIu32 "", seg->seq, - seg->payload_len); - PrintList(stream->seg_list); -#endif - - if (SEQ_GT((seg->seq + seg->payload_len), list_seg->seq) && - SEQ_LT((seg->seq + seg->payload_len),(list_seg->seq + - list_seg->payload_len))) - { - /* seg starts before list seg, ends beyond it but before list end */ - end_before = TRUE; - - /* [aaaa[abab]bbbb] a = seg, b = list_seg, overlap is the part [abab] - * We know seg->seq + seg->payload_len is bigger than list_seg->seq */ - overlap = (seg->seq + seg->payload_len) - list_seg->seq; - overlap_point = list_seg->seq; - SCLogDebug("starts before list seg, ends before list end: seg->seq " - "%" PRIu32 ", list_seg->seq %" PRIu32 ", " - "list_seg->payload_len %" PRIu16 " overlap is %" PRIu32 ", " - "overlap point %"PRIu32"", seg->seq, list_seg->seq, - list_seg->payload_len, overlap, overlap_point); - } else if (SEQ_EQ((seg->seq + seg->payload_len), (list_seg->seq + - list_seg->payload_len))) - { - /* seg fully overlaps list_seg, starts before, at end point - * [aaa[ababab]] where a = seg, b = list_seg - * overlap is [ababab], which is list_seg->payload_len */ - overlap = list_seg->payload_len; - end_same = TRUE; - overlap_point = list_seg->seq; - SCLogDebug("starts before list seg, ends at list end: list prev %p" - "seg->seq %" PRIu32 ", list_seg->seq %" PRIu32 "," - "list_seg->payload_len %" PRIu32 " overlap is %" PRIu32 "", - list_seg->prev, seg->seq, list_seg->seq, - list_seg->payload_len, overlap); - /* seg fully overlaps list_seg, starts before, ends after list endpoint */ - } else if (SEQ_GT((seg->seq + seg->payload_len), (list_seg->seq + - list_seg->payload_len))) - { - /* seg fully overlaps list_seg, starts before, ends after list endpoint - * [aaa[ababab]aaa] where a = seg, b = list_seg - * overlap is [ababab] which is list_seg->payload_len */ - overlap = list_seg->payload_len; - end_after = TRUE; - overlap_point = list_seg->seq; - SCLogDebug("starts before list seg, ends after list end: seg->seq " - "%" PRIu32 ", seg->payload_len %"PRIu32" list_seg->seq " - "%" PRIu32 ", list_seg->payload_len %" PRIu32 " overlap is" - " %" PRIu32 "", seg->seq, seg->payload_len, - list_seg->seq, list_seg->payload_len, overlap); - } - - if (overlap > 0) { - /* handle the case where we need to fill a gap before list_seg first */ - if (list_seg->prev != NULL && SEQ_LT((list_seg->prev->seq + list_seg->prev->payload_len), list_seg->seq)) { - SCLogDebug("GAP to fill before list segment, size %u", list_seg->seq - (list_seg->prev->seq + list_seg->prev->payload_len)); - - uint32_t new_seq = (list_seg->prev->seq + list_seg->prev->payload_len); - if (SEQ_GT(seg->seq, new_seq)) { - new_seq = seg->seq; - } - - packet_length = list_seg->seq - new_seq; - if (packet_length > seg->payload_len) { - packet_length = seg->payload_len; - } - - TcpSegment *new_seg = StreamTcpGetSegment(tv, ra_ctx, packet_length); - if (new_seg == NULL) { - SCLogDebug("segment_pool[%"PRIu16"] is empty", segment_pool_idx[packet_length]); - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT); - SCReturnInt(-1); - } - new_seg->payload_len = packet_length; - - new_seg->seq = new_seq; - - SCLogDebug("new_seg->seq %"PRIu32" and new->payload_len " - "%" PRIu16"", new_seg->seq, new_seg->payload_len); - - new_seg->next = list_seg; - new_seg->prev = list_seg->prev; - list_seg->prev->next = new_seg; - list_seg->prev = new_seg; - - /* create a new seg, copy the list_seg data over */ - StreamTcpSegmentDataCopy(new_seg, seg); - -#ifdef DEBUG - PrintList(stream->seg_list); -#endif - } - - /* Handling case when the segment starts before the first segment in - * the list */ - if (list_seg->prev == NULL) { - if (end_after == TRUE && list_seg->next != NULL && - SEQ_LT(list_seg->next->seq, (seg->seq + seg->payload_len))) - { - packet_length = (list_seg->seq - seg->seq) + list_seg->payload_len; - } else { - packet_length = seg->payload_len + (list_seg->payload_len - overlap); - return_after = TRUE; - } - - SCLogDebug("entered here packet_length %" PRIu32 ", seg->payload_len" - " %" PRIu32 ", list->payload_len %" PRIu32 "", - packet_length, seg->payload_len, list_seg->payload_len); - - TcpSegment *new_seg = StreamTcpGetSegment(tv, ra_ctx, packet_length); - if (new_seg == NULL) { - SCLogDebug("segment_pool[%"PRIu16"] is empty", segment_pool_idx[packet_length]); - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT); - SCReturnInt(-1); - } - new_seg->payload_len = packet_length; - new_seg->seq = seg->seq; - new_seg->next = list_seg->next; - new_seg->prev = list_seg->prev; - - StreamTcpSegmentDataCopy(new_seg, list_seg); - - /* first the data before the list_seg->seq */ - uint16_t replace = (uint16_t) (list_seg->seq - seg->seq); - SCLogDebug("copying %"PRIu16" bytes to new_seg", replace); - StreamTcpSegmentDataReplace(new_seg, seg, seg->seq, replace); - - /* if any, data after list_seg->seq + list_seg->payload_len */ - if (SEQ_GT((seg->seq + seg->payload_len), (list_seg->seq + - list_seg->payload_len)) && return_after == TRUE) - { - replace = (uint16_t)(((seg->seq + seg->payload_len) - - (list_seg->seq + - list_seg->payload_len))); - SCLogDebug("replacing %"PRIu16"", replace); - StreamTcpSegmentDataReplace(new_seg, seg, (list_seg->seq + - list_seg->payload_len), replace); - } - - /* update the stream last_seg in case of removal of list_seg */ - if (stream->seg_list_tail == list_seg) - stream->seg_list_tail = new_seg; - - StreamTcpSegmentReturntoPool(list_seg); - list_seg = new_seg; - if (new_seg->prev != NULL) { - new_seg->prev->next = new_seg; - } - if (new_seg->next != NULL) { - new_seg->next->prev = new_seg; - } - - stream->seg_list = new_seg; - SCLogDebug("list_seg now %p, stream->seg_list now %p", list_seg, - stream->seg_list); - - } else if (end_before == TRUE || end_same == TRUE) { - /* Handling overlapping with more than one segment and filling gap */ - if (SEQ_GT(list_seg->seq, (list_seg->prev->seq + - list_seg->prev->payload_len))) - { - SCLogDebug("list_seg->prev %p list_seg->prev->seq %"PRIu32" " - "list_seg->prev->payload_len %"PRIu16"", - list_seg->prev, list_seg->prev->seq, - list_seg->prev->payload_len); - if (SEQ_LT(list_seg->prev->seq, seg->seq)) { - packet_length = list_seg->payload_len + (list_seg->seq - - seg->seq); - } else { - packet_length = list_seg->payload_len + (list_seg->seq - - (list_seg->prev->seq + list_seg->prev->payload_len)); - } - - TcpSegment *new_seg = StreamTcpGetSegment(tv, ra_ctx, packet_length); - if (new_seg == NULL) { - SCLogDebug("segment_pool[%"PRIu16"] is empty", segment_pool_idx[packet_length]); - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT); - SCReturnInt(-1); - } - - new_seg->payload_len = packet_length; - if (SEQ_GT((list_seg->prev->seq + list_seg->prev->payload_len), - seg->seq)) - { - new_seg->seq = (list_seg->prev->seq + - list_seg->prev->payload_len); - } else { - new_seg->seq = seg->seq; - } - SCLogDebug("new_seg->seq %"PRIu32" and new->payload_len " - "%" PRIu16"", new_seg->seq, new_seg->payload_len); - new_seg->next = list_seg->next; - new_seg->prev = list_seg->prev; - - StreamTcpSegmentDataCopy(new_seg, list_seg); - - uint16_t copy_len = (uint16_t) (list_seg->seq - seg->seq); - SCLogDebug("copy_len %" PRIu32 " (%" PRIu32 " - %" PRIu32 ")", - copy_len, list_seg->seq, seg->seq); - StreamTcpSegmentDataReplace(new_seg, seg, seg->seq, copy_len); - - /*update the stream last_seg in case of removal of list_seg*/ - if (stream->seg_list_tail == list_seg) - stream->seg_list_tail = new_seg; - - StreamTcpSegmentReturntoPool(list_seg); - list_seg = new_seg; - if (new_seg->prev != NULL) { - new_seg->prev->next = new_seg; - } - if (new_seg->next != NULL) { - new_seg->next->prev = new_seg; - } - } - } else if (end_after == TRUE) { - if (list_seg->next != NULL) { - if (SEQ_LEQ((seg->seq + seg->payload_len), list_seg->next->seq)) - { - if (SEQ_GT(seg->seq, (list_seg->prev->seq + - list_seg->prev->payload_len))) - { - packet_length = list_seg->payload_len + (list_seg->seq - - seg->seq); - } else { - packet_length = list_seg->payload_len + (list_seg->seq - - (list_seg->prev->seq + - list_seg->prev->payload_len)); - } - - packet_length += (seg->seq + seg->payload_len) - - (list_seg->seq + list_seg->payload_len); - - TcpSegment *new_seg = StreamTcpGetSegment(tv, ra_ctx, packet_length); - if (new_seg == NULL) { - SCLogDebug("segment_pool[%"PRIu16"] is empty", segment_pool_idx[packet_length]); - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT); - SCReturnInt(-1); - } - new_seg->payload_len = packet_length; - if (SEQ_GT((list_seg->prev->seq + - list_seg->prev->payload_len), seg->seq)) - { - new_seg->seq = (list_seg->prev->seq + - list_seg->prev->payload_len); - } else { - new_seg->seq = seg->seq; - } - SCLogDebug("new_seg->seq %"PRIu32" and new->payload_len " - "%" PRIu16"", new_seg->seq, new_seg->payload_len); - new_seg->next = list_seg->next; - new_seg->prev = list_seg->prev; - - /* create a new seg, copy the list_seg data over */ - StreamTcpSegmentDataCopy(new_seg, list_seg); - - /* copy the part before list_seg */ - uint16_t copy_len = list_seg->seq - new_seg->seq; - StreamTcpSegmentDataReplace(new_seg, seg, new_seg->seq, - copy_len); - - /* copy the part after list_seg */ - copy_len = (seg->seq + seg->payload_len) - - (list_seg->seq + list_seg->payload_len); - StreamTcpSegmentDataReplace(new_seg, seg, (list_seg->seq + - list_seg->payload_len), copy_len); - - if (new_seg->prev != NULL) { - new_seg->prev->next = new_seg; - } - if (new_seg->next != NULL) { - new_seg->next->prev = new_seg; - } - /*update the stream last_seg in case of removal of list_seg*/ - if (stream->seg_list_tail == list_seg) - stream->seg_list_tail = new_seg; - - StreamTcpSegmentReturntoPool(list_seg); - list_seg = new_seg; - return_after = TRUE; - } - /* Handle the case, when list_seg is the end of segment list, but - seg is ending after the list_seg. So we need to copy the data - from newly received segment. After copying return the newly - received seg to pool */ - } else { - if (SEQ_GT(seg->seq, (list_seg->prev->seq + - list_seg->prev->payload_len))) - { - packet_length = list_seg->payload_len + (list_seg->seq - - seg->seq); - } else { - packet_length = list_seg->payload_len + (list_seg->seq - - (list_seg->prev->seq + - list_seg->prev->payload_len)); - } - - packet_length += (seg->seq + seg->payload_len) - - (list_seg->seq + list_seg->payload_len); - - TcpSegment *new_seg = StreamTcpGetSegment(tv, ra_ctx, packet_length); - if (new_seg == NULL) { - SCLogDebug("segment_pool[%"PRIu16"] is empty", - segment_pool_idx[packet_length]); - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT); - SCReturnInt(-1); - } - new_seg->payload_len = packet_length; - - if (SEQ_GT((list_seg->prev->seq + - list_seg->prev->payload_len), seg->seq)) - { - new_seg->seq = (list_seg->prev->seq + - list_seg->prev->payload_len); - } else { - new_seg->seq = seg->seq; - } - SCLogDebug("new_seg->seq %"PRIu32" and new->payload_len " - "%" PRIu16"", new_seg->seq, new_seg->payload_len); - new_seg->next = list_seg->next; - new_seg->prev = list_seg->prev; - - /* create a new seg, copy the list_seg data over */ - StreamTcpSegmentDataCopy(new_seg, list_seg); - - /* copy the part before list_seg */ - uint16_t copy_len = list_seg->seq - new_seg->seq; - StreamTcpSegmentDataReplace(new_seg, seg, new_seg->seq, - copy_len); - - /* copy the part after list_seg */ - copy_len = (seg->seq + seg->payload_len) - - (list_seg->seq + list_seg->payload_len); - StreamTcpSegmentDataReplace(new_seg, seg, (list_seg->seq + - list_seg->payload_len), copy_len); - - if (new_seg->prev != NULL) { - new_seg->prev->next = new_seg; - } - - /*update the stream last_seg in case of removal of list_seg*/ - if (stream->seg_list_tail == list_seg) - stream->seg_list_tail = new_seg; - - StreamTcpSegmentReturntoPool(list_seg); - list_seg = new_seg; - return_after = TRUE; - } - } - - if (check_overlap_different_data && - !StreamTcpSegmentDataCompare(seg, list_seg, list_seg->seq, overlap)) { - /* interesting, overlap with different data */ - StreamTcpSetEvent(p, STREAM_REASSEMBLY_OVERLAP_DIFFERENT_DATA); - } - - if (StreamTcpInlineMode()) { - if (StreamTcpInlineSegmentCompare(seg, list_seg) != 0) { - StreamTcpInlineSegmentReplacePacket(p, list_seg); - } - } else { - switch (os_policy) { - case OS_POLICY_SOLARIS: - case OS_POLICY_HPUX11: - if (end_after == TRUE || end_same == TRUE) { - StreamTcpSegmentDataReplace(list_seg, seg, overlap_point, - overlap); - } else { - SCLogDebug("using old data in starts before list case, " - "list_seg->seq %" PRIu32 " policy %" PRIu32 " " - "overlap %" PRIu32 "", list_seg->seq, os_policy, - overlap); - } - break; - case OS_POLICY_VISTA: - case OS_POLICY_FIRST: - SCLogDebug("using old data in starts before list case, " - "list_seg->seq %" PRIu32 " policy %" PRIu32 " " - "overlap %" PRIu32 "", list_seg->seq, os_policy, - overlap); - break; - case OS_POLICY_BSD: - case OS_POLICY_HPUX10: - case OS_POLICY_IRIX: - case OS_POLICY_WINDOWS: - case OS_POLICY_WINDOWS2K3: - case OS_POLICY_OLD_LINUX: - case OS_POLICY_LINUX: - case OS_POLICY_MACOS: - case OS_POLICY_LAST: - default: - SCLogDebug("replacing old data in starts before list seg " - "list_seg->seq %" PRIu32 " policy %" PRIu32 " " - "overlap %" PRIu32 "", list_seg->seq, os_policy, - overlap); - StreamTcpSegmentDataReplace(list_seg, seg, overlap_point, - overlap); - break; - } - } - /* To return from for loop as seg is finished with current list_seg - no need to check further (improve performance) */ - if (end_before == TRUE || end_same == TRUE || return_after == TRUE) { - SCReturnInt(1); - } - } - - SCReturnInt(0); -} - -/** - * \brief Function to handle the newly arrived segment, when newly arrived - * starts with the same sequence number as the original segment and - * ends at different position relative to original segment. - * The packet is handled based on its target OS. - * - * \param list_seg Original Segment in the stream - * \param seg Newly arrived segment - * \param prev_seg Previous segment in the stream segment list - * - * \retval 1 success and done - * \retval 0 success, but not done yet - * \retval -1 error, will *only* happen on memory errors - */ - -static int HandleSegmentStartsAtSameListSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpStream *stream, TcpSegment *list_seg, TcpSegment *seg, Packet *p) -{ - uint16_t overlap = 0; - uint16_t packet_length; - char end_before = FALSE; - char end_after = FALSE; - char end_same = FALSE; - char handle_beyond = FALSE; - uint8_t os_policy = stream->os_policy; - - if (SEQ_LT((seg->seq + seg->payload_len), (list_seg->seq + - list_seg->payload_len))) - { - /* seg->seg == list_seg->seq and list_seg->payload_len > seg->payload_len - * [[ababab]bbbb] where a = seg, b = list_seg - * overlap is the [ababab] part, which equals seg->payload_len. */ - overlap = seg->payload_len; - end_before = TRUE; - SCLogDebug("starts at list seq, ends before list end: seg->seq " - "%" PRIu32 ", list_seg->seq %" PRIu32 ", " - "list_seg->payload_len %" PRIu32 " overlap is %" PRIu32, - seg->seq, list_seg->seq, list_seg->payload_len, overlap); - - } else if (SEQ_EQ((seg->seq + seg->payload_len), (list_seg->seq + - list_seg->payload_len))) - { - /* seg starts at seq, ends at seq, retransmission. - * both segments are the same, so overlap is either - * seg->payload_len or list_seg->payload_len */ - - /* check csum, ack, other differences? */ - overlap = seg->payload_len; - end_same = TRUE; - SCLogDebug("(retransmission) starts at list seq, ends at list end: " - "seg->seq %" PRIu32 ", list_seg->seq %" PRIu32 ", " - "list_seg->payload_len %" PRIu32 " overlap is %"PRIu32"", - seg->seq, list_seg->seq, list_seg->payload_len, overlap); - - } else if (SEQ_GT((seg->seq + seg->payload_len), - (list_seg->seq + list_seg->payload_len))) { - /* seg starts at seq, ends beyond seq. */ - /* seg->seg == list_seg->seq and seg->payload_len > list_seg->payload_len - * [[ababab]aaaa] where a = seg, b = list_seg - * overlap is the [ababab] part, which equals list_seg->payload_len. */ - overlap = list_seg->payload_len; - end_after = TRUE; - SCLogDebug("starts at list seq, ends beyond list end: seg->seq " - "%" PRIu32 ", list_seg->seq %" PRIu32 ", " - "list_seg->payload_len %" PRIu32 " overlap is %" PRIu32 "", - seg->seq, list_seg->seq, list_seg->payload_len, overlap); - } - if (overlap > 0) { - /*Handle the case when newly arrived segment ends after original - segment and original segment is the last segment in the list - or the next segment in the list starts after the end of new segment*/ - if (end_after == TRUE) { - char fill_gap = FALSE; - - if (list_seg->next != NULL) { - /* first see if we have space left to fill up */ - if (SEQ_LT((list_seg->seq + list_seg->payload_len), - list_seg->next->seq)) - { - fill_gap = TRUE; - } - - /* then see if we overlap (partly) with the next seg */ - if (SEQ_GT((seg->seq + seg->payload_len), list_seg->next->seq)) - { - handle_beyond = TRUE; - } - /* Handle the case, when list_seg is the end of segment list, but - seg is ending after the list_seg. So we need to copy the data - from newly received segment. After copying return the newly - received seg to pool */ - } else { - fill_gap = TRUE; - } - - SCLogDebug("fill_gap %s, handle_beyond %s", fill_gap?"TRUE":"FALSE", - handle_beyond?"TRUE":"FALSE"); - - if (fill_gap == TRUE) { - /* if there is a gap after this list_seg we fill it now with a - * new seg */ - SCLogDebug("filling gap: list_seg->next->seq %"PRIu32"", - list_seg->next?list_seg->next->seq:0); - if (handle_beyond == TRUE) { - packet_length = list_seg->next->seq - - (list_seg->seq + list_seg->payload_len); - } else { - packet_length = seg->payload_len - list_seg->payload_len; - } - - SCLogDebug("packet_length %"PRIu16"", packet_length); - - TcpSegment *new_seg = StreamTcpGetSegment(tv, ra_ctx, packet_length); - if (new_seg == NULL) { - SCLogDebug("egment_pool[%"PRIu16"] is empty", segment_pool_idx[packet_length]); - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT); - return -1; - } - new_seg->payload_len = packet_length; - new_seg->seq = list_seg->seq + list_seg->payload_len; - new_seg->next = list_seg->next; - if (new_seg->next != NULL) - new_seg->next->prev = new_seg; - new_seg->prev = list_seg; - list_seg->next = new_seg; - SCLogDebug("new_seg %p, new_seg->next %p, new_seg->prev %p, " - "list_seg->next %p", new_seg, new_seg->next, - new_seg->prev, list_seg->next); - StreamTcpSegmentDataReplace(new_seg, seg, new_seg->seq, - new_seg->payload_len); - - /*update the stream last_seg in case of removal of list_seg*/ - if (stream->seg_list_tail == list_seg) - stream->seg_list_tail = new_seg; - } - } - - if (check_overlap_different_data && - !StreamTcpSegmentDataCompare(list_seg, seg, seg->seq, overlap)) { - /* interesting, overlap with different data */ - StreamTcpSetEvent(p, STREAM_REASSEMBLY_OVERLAP_DIFFERENT_DATA); - } - - if (StreamTcpInlineMode()) { - if (StreamTcpInlineSegmentCompare(list_seg, seg) != 0) { - StreamTcpInlineSegmentReplacePacket(p, list_seg); - } - } else { - switch (os_policy) { - case OS_POLICY_OLD_LINUX: - case OS_POLICY_SOLARIS: - case OS_POLICY_HPUX11: - if (end_after == TRUE || end_same == TRUE) { - StreamTcpSegmentDataReplace(list_seg, seg, seg->seq, overlap); - } else { - SCLogDebug("using old data in starts at list case, " - "list_seg->seq %" PRIu32 " policy %" PRIu32 " " - "overlap %" PRIu32 "", list_seg->seq, os_policy, - overlap); - } - break; - case OS_POLICY_LAST: - StreamTcpSegmentDataReplace(list_seg, seg, seg->seq, overlap); - break; - case OS_POLICY_LINUX: - if (end_after == TRUE) { - StreamTcpSegmentDataReplace(list_seg, seg, seg->seq, overlap); - } else { - SCLogDebug("using old data in starts at list case, " - "list_seg->seq %" PRIu32 " policy %" PRIu32 " " - "overlap %" PRIu32 "", list_seg->seq, os_policy, - overlap); - } - break; - case OS_POLICY_BSD: - case OS_POLICY_HPUX10: - case OS_POLICY_IRIX: - case OS_POLICY_WINDOWS: - case OS_POLICY_WINDOWS2K3: - case OS_POLICY_VISTA: - case OS_POLICY_MACOS: - case OS_POLICY_FIRST: - default: - SCLogDebug("using old data in starts at list case, list_seg->seq" - " %" PRIu32 " policy %" PRIu32 " overlap %" PRIu32 "", - list_seg->seq, os_policy, overlap); - break; - } - } - - /* return 1 if we're done */ - if (end_before == TRUE || end_same == TRUE || handle_beyond == FALSE) { - return 1; - } - } - return 0; -} - -/** - * \internal - * \brief Function to handle the newly arrived segment, when newly arrived - * starts with the sequence number higher than the original segment and - * ends at different position relative to original segment. - * The packet is handled based on its target OS. - * - * \param list_seg Original Segment in the stream - * \param seg Newly arrived segment - * \param prev_seg Previous segment in the stream segment list - - * \retval 1 success and done - * \retval 0 success, but not done yet - * \retval -1 error, will *only* happen on memory errors - */ - -static int HandleSegmentStartsAfterListSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpStream *stream, TcpSegment *list_seg, TcpSegment *seg, Packet *p) -{ - SCEnter(); - uint16_t overlap = 0; - uint16_t packet_length; - char end_before = FALSE; - char end_after = FALSE; - char end_same = FALSE; - char handle_beyond = FALSE; - uint8_t os_policy = stream->os_policy; - - if (SEQ_LT((seg->seq + seg->payload_len), (list_seg->seq + - list_seg->payload_len))) - { - /* seg starts after list, ends before list end - * [bbbb[ababab]bbbb] where a = seg, b = list_seg - * overlap is the part [ababab] which is seg->payload_len */ - overlap = seg->payload_len; - end_before = TRUE; - - SCLogDebug("starts beyond list seq, ends before list end: seg->seq" - " %" PRIu32 ", list_seg->seq %" PRIu32 ", list_seg->payload_len " - "%" PRIu32 " overlap is %" PRIu32 "", seg->seq, list_seg->seq, - list_seg->payload_len, overlap); - - } else if (SEQ_EQ((seg->seq + seg->payload_len), - (list_seg->seq + list_seg->payload_len))) { - /* seg starts after seq, before end, ends at seq - * [bbbb[ababab]] where a = seg, b = list_seg - * overlapping part is [ababab], thus seg->payload_len */ - overlap = seg->payload_len; - end_same = TRUE; - - SCLogDebug("starts beyond list seq, ends at list end: seg->seq" - " %" PRIu32 ", list_seg->seq %" PRIu32 ", list_seg->payload_len " - "%" PRIu32 " overlap is %" PRIu32 "", seg->seq, list_seg->seq, - list_seg->payload_len, overlap); - - } else if (SEQ_LT(seg->seq, list_seg->seq + list_seg->payload_len) && - SEQ_GT((seg->seq + seg->payload_len), (list_seg->seq + - list_seg->payload_len))) - { - /* seg starts after seq, before end, ends beyond seq. - * - * [bbb[ababab]aaa] where a = seg, b = list_seg. - * overlap is the [ababab] part, which can be get using: - * (list_seg->seq + list_seg->payload_len) - seg->seg */ - overlap = (list_seg->seq + list_seg->payload_len) - seg->seq; - end_after = TRUE; - - SCLogDebug("starts beyond list seq, ends after list seq end: " - "seg->seq %" PRIu32 ", seg->payload_len %"PRIu16" (%"PRIu32") " - "list_seg->seq %" PRIu32 ", list_seg->payload_len %" PRIu32 " " - "(%"PRIu32") overlap is %" PRIu32 "", seg->seq, seg->payload_len, - seg->seq + seg->payload_len, list_seg->seq, list_seg->payload_len, - list_seg->seq + list_seg->payload_len, overlap); - } - if (overlap > 0) { - /*Handle the case when newly arrived segment ends after original - segment and original segment is the last segment in the list*/ - if (end_after == TRUE) { - char fill_gap = FALSE; - - if (list_seg->next != NULL) { - /* first see if we have space left to fill up */ - if (SEQ_LT((list_seg->seq + list_seg->payload_len), - list_seg->next->seq)) - { - fill_gap = TRUE; - } - - /* then see if we overlap (partly) with the next seg */ - if (SEQ_GT((seg->seq + seg->payload_len), list_seg->next->seq)) - { - handle_beyond = TRUE; - } - } else { - fill_gap = TRUE; - } - - SCLogDebug("fill_gap %s, handle_beyond %s", fill_gap?"TRUE":"FALSE", - handle_beyond?"TRUE":"FALSE"); - - if (fill_gap == TRUE) { - /* if there is a gap after this list_seg we fill it now with a - * new seg */ - if (list_seg->next != NULL) { - SCLogDebug("filling gap: list_seg->next->seq %"PRIu32"", - list_seg->next?list_seg->next->seq:0); - - packet_length = list_seg->next->seq - (list_seg->seq + - list_seg->payload_len); - } else { - packet_length = seg->payload_len - overlap; - } - if (packet_length > (seg->payload_len - overlap)) { - packet_length = seg->payload_len - overlap; - } - SCLogDebug("packet_length %"PRIu16"", packet_length); - - TcpSegment *new_seg = StreamTcpGetSegment(tv, ra_ctx, packet_length); - if (new_seg == NULL) { - SCLogDebug("segment_pool[%"PRIu16"] is empty", segment_pool_idx[packet_length]); - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT); - SCReturnInt(-1); - } - new_seg->payload_len = packet_length; - new_seg->seq = list_seg->seq + list_seg->payload_len; - new_seg->next = list_seg->next; - if (new_seg->next != NULL) - new_seg->next->prev = new_seg; - new_seg->prev = list_seg; - list_seg->next = new_seg; - - SCLogDebug("new_seg %p, new_seg->next %p, new_seg->prev %p, " - "list_seg->next %p new_seg->seq %"PRIu32"", new_seg, - new_seg->next, new_seg->prev, list_seg->next, - new_seg->seq); - - StreamTcpSegmentDataReplace(new_seg, seg, new_seg->seq, - new_seg->payload_len); - - /* update the stream last_seg in case of removal of list_seg */ - if (stream->seg_list_tail == list_seg) - stream->seg_list_tail = new_seg; - } - } - - if (check_overlap_different_data && - !StreamTcpSegmentDataCompare(list_seg, seg, seg->seq, overlap)) { - /* interesting, overlap with different data */ - StreamTcpSetEvent(p, STREAM_REASSEMBLY_OVERLAP_DIFFERENT_DATA); - } - - if (StreamTcpInlineMode()) { - if (StreamTcpInlineSegmentCompare(list_seg, seg) != 0) { - StreamTcpInlineSegmentReplacePacket(p, list_seg); - } - } else { - switch (os_policy) { - case OS_POLICY_SOLARIS: - case OS_POLICY_HPUX11: - if (end_after == TRUE) { - StreamTcpSegmentDataReplace(list_seg, seg, seg->seq, overlap); - } else { - SCLogDebug("using old data in starts beyond list case, " - "list_seg->seq %" PRIu32 " policy %" PRIu32 " " - "overlap %" PRIu32 "", list_seg->seq, os_policy, - overlap); - } - break; - case OS_POLICY_LAST: - StreamTcpSegmentDataReplace(list_seg, seg, seg->seq, overlap); - break; - case OS_POLICY_BSD: - case OS_POLICY_HPUX10: - case OS_POLICY_IRIX: - case OS_POLICY_WINDOWS: - case OS_POLICY_WINDOWS2K3: - case OS_POLICY_VISTA: - case OS_POLICY_OLD_LINUX: - case OS_POLICY_LINUX: - case OS_POLICY_MACOS: - case OS_POLICY_FIRST: - default: /* DEFAULT POLICY */ - SCLogDebug("using old data in starts beyond list case, " - "list_seg->seq %" PRIu32 " policy %" PRIu32 " " - "overlap %" PRIu32 "", list_seg->seq, os_policy, - overlap); - break; - } - } - if (end_before == TRUE || end_same == TRUE || handle_beyond == FALSE) { - SCReturnInt(1); - } - } - SCReturnInt(0); -} - -/** - * \brief check if stream in pkt direction has depth reached - * - * \param p packet with *LOCKED* flow - * - * \retval 1 stream has depth reached - * \retval 0 stream does not have depth reached - */ -int StreamTcpReassembleDepthReached(Packet *p) -{ - if (p->flow != NULL && p->flow->protoctx != NULL) { - TcpSession *ssn = p->flow->protoctx; - TcpStream *stream; - if (p->flowflags & FLOW_PKT_TOSERVER) { - stream = &ssn->client; - } else { - stream = &ssn->server; - } - - return (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) ? 1 : 0; - } - - return 0; -} - -/** - * \internal - * \brief Function to Check the reassembly depth valuer against the - * allowed max depth of the stream reassmbly for TCP streams. - * - * \param stream stream direction - * \param seq sequence number where "size" starts - * \param size size of the segment that is added - * - * \retval size Part of the size that fits in the depth, 0 if none - */ -static uint32_t StreamTcpReassembleCheckDepth(TcpStream *stream, - uint32_t seq, uint32_t size) -{ - SCEnter(); - - /* if the configured depth value is 0, it means there is no limit on - reassembly depth. Otherwise carry on my boy ;) */ - if (stream_config.reassembly_depth == 0) { - SCReturnUInt(size); - } - - /* if the final flag is set, we're not accepting anymore */ - if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) { - SCReturnUInt(0); - } - - /* if the ra_base_seq has moved passed the depth window we stop - * checking and just reject the rest of the packets including - * retransmissions. Saves us the hassle of dealing with sequence - * wraps as well */ - if (SEQ_GEQ((StreamTcpReassembleGetRaBaseSeq(stream)+1),(stream->isn + stream_config.reassembly_depth))) { - stream->flags |= STREAMTCP_STREAM_FLAG_DEPTH_REACHED; - SCReturnUInt(0); - } - - SCLogDebug("full Depth not yet reached: %"PRIu32" <= %"PRIu32, - (StreamTcpReassembleGetRaBaseSeq(stream)+1), - (stream->isn + stream_config.reassembly_depth)); - - if (SEQ_GEQ(seq, stream->isn) && SEQ_LT(seq, (stream->isn + stream_config.reassembly_depth))) { - /* packet (partly?) fits the depth window */ - - if (SEQ_LEQ((seq + size),(stream->isn + stream_config.reassembly_depth))) { - /* complete fit */ - SCReturnUInt(size); - } else { - /* partial fit, return only what fits */ - uint32_t part = (stream->isn + stream_config.reassembly_depth) - seq; -#if DEBUG - BUG_ON(part > size); -#else - if (part > size) - part = size; -#endif - SCReturnUInt(part); - } - } - - SCReturnUInt(0); -} - -static void StreamTcpStoreStreamChunk(TcpSession *ssn, StreamMsg *smsg, const Packet *p, int streaminline) -{ - uint8_t direction = 0; - - if ((!streaminline && (p->flowflags & FLOW_PKT_TOSERVER)) || - ( streaminline && (p->flowflags & FLOW_PKT_TOCLIENT))) - { - direction = STREAM_TOCLIENT; - SCLogDebug("stream chunk is to_client"); - } else { - direction = STREAM_TOSERVER; - SCLogDebug("stream chunk is to_server"); - } - - /* store the smsg in the tcp stream */ - if (direction == STREAM_TOSERVER) { - SCLogDebug("storing smsg in the to_server"); - - /* put the smsg in the stream list */ - if (ssn->toserver_smsg_head == NULL) { - ssn->toserver_smsg_head = smsg; - ssn->toserver_smsg_tail = smsg; - smsg->next = NULL; - smsg->prev = NULL; - } else { - StreamMsg *cur = ssn->toserver_smsg_tail; - cur->next = smsg; - smsg->prev = cur; - smsg->next = NULL; - ssn->toserver_smsg_tail = smsg; - } - } else { - SCLogDebug("storing smsg in the to_client"); - - /* put the smsg in the stream list */ - if (ssn->toclient_smsg_head == NULL) { - ssn->toclient_smsg_head = smsg; - ssn->toclient_smsg_tail = smsg; - smsg->next = NULL; - smsg->prev = NULL; - } else { - StreamMsg *cur = ssn->toclient_smsg_tail; - cur->next = smsg; - smsg->prev = cur; - smsg->next = NULL; - ssn->toclient_smsg_tail = smsg; - } - } -} - -/** - * \brief Insert a packets TCP data into the stream reassembly engine. - * - * \retval 0 good segment, as far as we checked. - * \retval -1 badness, reason to drop in inline mode - * - * If the retval is 0 the segment is inserted correctly, or overlap is handled, - * or it wasn't added because of reassembly depth. - * - */ -int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpSession *ssn, TcpStream *stream, Packet *p) -{ - SCEnter(); - - if (ssn->data_first_seen_dir == 0) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - ssn->data_first_seen_dir = STREAM_TOSERVER; - } else { - ssn->data_first_seen_dir = STREAM_TOCLIENT; - } - } - - if ((ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) && - (stream->flags & STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED)) { - SCLogDebug("ssn %p: both app and raw reassembly disabled, not reassembling", ssn); - SCReturnInt(0); - } - - /* If we have reached the defined depth for either of the stream, then stop - reassembling the TCP session */ - uint32_t size = StreamTcpReassembleCheckDepth(stream, TCP_GET_SEQ(p), p->payload_len); - SCLogDebug("ssn %p: check depth returned %"PRIu32, ssn, size); - - if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) { - /* increment stream depth counter */ - StatsIncr(tv, ra_ctx->counter_tcp_stream_depth); - - stream->flags |= STREAMTCP_STREAM_FLAG_NOREASSEMBLY; - SCLogDebug("ssn %p: reassembly depth reached, " - "STREAMTCP_STREAM_FLAG_NOREASSEMBLY set", ssn); - } - if (size == 0) { - SCLogDebug("ssn %p: depth reached, not reassembling", ssn); - SCReturnInt(0); - } - -#if DEBUG - BUG_ON(size > p->payload_len); -#else - if (size > p->payload_len) - size = p->payload_len; -#endif - - TcpSegment *seg = StreamTcpGetSegment(tv, ra_ctx, size); - if (seg == NULL) { - SCLogDebug("segment_pool[%"PRIu16"] is empty", segment_pool_idx[size]); - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_NO_SEGMENT); - SCReturnInt(-1); - } - - memcpy(seg->payload, p->payload, size); - seg->payload_len = size; - seg->seq = TCP_GET_SEQ(p); - - if (ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) - seg->flags |= SEGMENTTCP_FLAG_APPLAYER_PROCESSED; - - /* if raw reassembly is disabled for new segments, flag each - * segment as complete for raw before insert */ - if (stream->flags & STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED) { - seg->flags |= SEGMENTTCP_FLAG_RAW_PROCESSED; - SCLogDebug("segment %p flagged with SEGMENTTCP_FLAG_RAW_PROCESSED, " - "flags %02x", seg, seg->flags); - } - - /* proto detection skipped, but now we do get data. Set event. */ - if (stream->seg_list == NULL && - stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_SKIPPED) { - - AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, - APPLAYER_PROTO_DETECTION_SKIPPED); - } - - if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, seg, p) != 0) { - SCLogDebug("StreamTcpReassembleInsertSegment failed"); - SCReturnInt(-1); - } - - SCReturnInt(0); -} - -static uint8_t StreamGetAppLayerFlags(TcpSession *ssn, TcpStream *stream, - Packet *p) -{ - uint8_t flag = 0; - - if (!(stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED)) { - flag |= STREAM_START; - } - - if (ssn->state == TCP_CLOSED) { - flag |= STREAM_EOF; - } - if (p->flags & PKT_PSEUDO_STREAM_END) { - flag |= STREAM_EOF; - } - - if (StreamTcpInlineMode() == 0) { - if (p->flowflags & FLOW_PKT_TOSERVER) { - flag |= STREAM_TOCLIENT; - } else { - flag |= STREAM_TOSERVER; - } - } else { - if (p->flowflags & FLOW_PKT_TOSERVER) { - flag |= STREAM_TOSERVER; - } else { - flag |= STREAM_TOCLIENT; - } - } - - if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) { - flag |= STREAM_DEPTH; - } - return flag; -} - -static void StreamTcpSetupMsg(TcpSession *ssn, TcpStream *stream, Packet *p, - StreamMsg *smsg) -{ - SCEnter(); - smsg->data_len = 0; - SCLogDebug("smsg %p", smsg); - SCReturn; -} - -/** - * \brief Check the minimum size limits for reassembly. - * - * \retval 0 don't reassemble yet - * \retval 1 do reassemble - */ -static int StreamTcpReassembleRawCheckLimit(TcpSession *ssn, TcpStream *stream, - Packet *p) -{ - SCEnter(); - - if (stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) { - SCLogDebug("reassembling now as STREAMTCP_STREAM_FLAG_NOREASSEMBLY is set, so not expecting any new packets"); - SCReturnInt(1); - } - - if (ssn->flags & STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY) { - SCLogDebug("reassembling now as STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY is set"); - ssn->flags &= ~STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY; - SCReturnInt(1); - } - - if (stream->flags & STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED) { - SCLogDebug("reassembling now as STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED is set, " - "so no new segments will be considered"); - SCReturnInt(1); - } - - /* some states mean we reassemble no matter how much data we have */ - if (ssn->state >= TCP_TIME_WAIT) - SCReturnInt(1); - - if (p->flags & PKT_PSEUDO_STREAM_END) - SCReturnInt(1); - - /* check if we have enough data to send to L7 */ - if (p->flowflags & FLOW_PKT_TOCLIENT) { - SCLogDebug("StreamMsgQueueGetMinChunkLen(STREAM_TOSERVER) %"PRIu32, - StreamMsgQueueGetMinChunkLen(FLOW_PKT_TOSERVER)); - - if (StreamMsgQueueGetMinChunkLen(FLOW_PKT_TOSERVER) > - (stream->last_ack - stream->ra_raw_base_seq)) { - SCLogDebug("toserver min chunk len not yet reached: " - "last_ack %"PRIu32", ra_raw_base_seq %"PRIu32", %"PRIu32" < " - "%"PRIu32"", stream->last_ack, stream->ra_raw_base_seq, - (stream->last_ack - stream->ra_raw_base_seq), - StreamMsgQueueGetMinChunkLen(FLOW_PKT_TOSERVER)); - SCReturnInt(0); - } - } else { - SCLogDebug("StreamMsgQueueGetMinChunkLen(STREAM_TOCLIENT) %"PRIu32, - StreamMsgQueueGetMinChunkLen(FLOW_PKT_TOCLIENT)); - - if (StreamMsgQueueGetMinChunkLen(FLOW_PKT_TOCLIENT) > - (stream->last_ack - stream->ra_raw_base_seq)) { - SCLogDebug("toclient min chunk len not yet reached: " - "last_ack %"PRIu32", ra_base_seq %"PRIu32", %"PRIu32" < " - "%"PRIu32"", stream->last_ack, stream->ra_raw_base_seq, - (stream->last_ack - stream->ra_raw_base_seq), - StreamMsgQueueGetMinChunkLen(FLOW_PKT_TOCLIENT)); - SCReturnInt(0); - } - } - - SCReturnInt(1); -} - -/** - * \brief see if app layer is done with a segment - * - * \retval 1 app layer is done with this segment - * \retval 0 not done yet - */ -#define StreamTcpAppLayerSegmentProcessed(ssn, stream, segment) \ - (( ( (ssn)->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) || \ - ( (stream)->flags & STREAMTCP_STREAM_FLAG_GAP ) || \ - ( (segment)->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED ) ? 1 :0 )) - -/** \internal - * \brief check if we can remove a segment from our segment list - * - * If a segment is entirely before the oldest smsg, we can discard it. Otherwise - * we keep it around to be able to log it. - * - * \retval 1 yes - * \retval 0 no - */ -static inline int StreamTcpReturnSegmentCheck(const Flow *f, TcpSession *ssn, TcpStream *stream, TcpSegment *seg) -{ - if (stream == &ssn->client && ssn->toserver_smsg_head != NULL) { - /* not (seg is entirely before first smsg, skip) */ - if (!(SEQ_LEQ(seg->seq + seg->payload_len, ssn->toserver_smsg_head->seq))) { - SCReturnInt(0); - } - } else if (stream == &ssn->server && ssn->toclient_smsg_head != NULL) { - /* not (seg is entirely before first smsg, skip) */ - if (!(SEQ_LEQ(seg->seq + seg->payload_len, ssn->toclient_smsg_head->seq))) { - SCReturnInt(0); - } - } - - /* if proto detect isn't done, we're not returning */ - if (!(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream))) { - SCReturnInt(0); - } - - /* check app layer conditions */ - if (!(StreamTcpAppLayerSegmentProcessed(ssn, stream, seg))) { - SCReturnInt(0); - } - - /* check raw reassembly conditions */ - if (!(seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED)) { - SCReturnInt(0); - } - - SCReturnInt(1); -} - -static void StreamTcpRemoveSegmentFromStream(TcpStream *stream, TcpSegment *seg) -{ - if (seg->prev == NULL) { - stream->seg_list = seg->next; - if (stream->seg_list != NULL) - stream->seg_list->prev = NULL; - } else { - seg->prev->next = seg->next; - if (seg->next != NULL) - seg->next->prev = seg->prev; - } - - if (stream->seg_list_tail == seg) - stream->seg_list_tail = seg->prev; -} - -/** - * \brief Update the stream reassembly upon receiving a data segment - * - * | left edge | right edge based on sliding window size - * [aaa] - * [aaabbb] - * ... - * [aaabbbcccdddeeefff] - * [bbbcccdddeeefffggg] <- cut off aaa to adhere to the window size - * - * GAP situation: each chunk that is uninterrupted has it's own smsg - * [aaabbb].[dddeeefff] - * [aaa].[ccc].[eeefff] - * - * A flag will be set to indicate where the *NEW* payload starts. This - * is to aid the detection code for alert only sigs. - * - * \todo this function is too long, we need to break it up. It needs it BAD - */ -static int StreamTcpReassembleInlineRaw (TcpReassemblyThreadCtx *ra_ctx, - TcpSession *ssn, TcpStream *stream, Packet *p) -{ - SCEnter(); - SCLogDebug("start p %p, seq %"PRIu32, p, TCP_GET_SEQ(p)); - - if (ssn->flags & STREAMTCP_FLAG_DISABLE_RAW) - SCReturnInt(0); - if (stream->seg_list == NULL) { - SCReturnInt(0); - } - - uint32_t ra_base_seq = stream->ra_raw_base_seq; - StreamMsg *smsg = NULL; - uint32_t smsg_offset = 0; - uint16_t payload_offset = 0; - uint16_t payload_len = 0; - TcpSegment *seg = stream->seg_list; - uint32_t next_seq = ra_base_seq + 1; - int gap = 0; - - uint32_t chunk_size = PKT_IS_TOSERVER(p) ? - stream_config.reassembly_toserver_chunk_size : - stream_config.reassembly_toclient_chunk_size; - - /* determine the left edge and right edge */ - uint32_t right_edge = TCP_GET_SEQ(p) + p->payload_len; - uint32_t left_edge = right_edge - chunk_size; - - /* shift the window to the right if the left edge doesn't cover segments */ - if (SEQ_GT(seg->seq,left_edge)) { - right_edge += (seg->seq - left_edge); - left_edge = seg->seq; - } - - SCLogDebug("left_edge %"PRIu32", right_edge %"PRIu32, left_edge, right_edge); - - /* loop through the segments and fill one or more msgs */ - for (; seg != NULL && SEQ_LT(seg->seq, right_edge); ) { - SCLogDebug("seg %p", seg); - - /* If packets are fully before ra_base_seq, skip them. We do this - * because we've reassembled up to the ra_base_seq point already, - * so we won't do anything with segments before it anyway. */ - SCLogDebug("checking for pre ra_base_seq %"PRIu32" seg %p seq %"PRIu32"" - " len %"PRIu16", combined %"PRIu32" and right_edge " - "%"PRIu32"", ra_base_seq, seg, seg->seq, - seg->payload_len, seg->seq+seg->payload_len, right_edge); - - /* Remove the segments which are completely before the ra_base_seq */ - if (SEQ_LT((seg->seq + seg->payload_len), (ra_base_seq - chunk_size))) - { - SCLogDebug("removing pre ra_base_seq %"PRIu32" seg %p seq %"PRIu32"" - " len %"PRIu16"", ra_base_seq, seg, seg->seq, - seg->payload_len); - - /* only remove if app layer reassembly is ready too */ - if (StreamTcpAppLayerSegmentProcessed(ssn, stream, seg)) { - TcpSegment *next_seg = seg->next; - StreamTcpRemoveSegmentFromStream(stream, seg); - StreamTcpSegmentReturntoPool(seg); - seg = next_seg; - /* otherwise, just flag it for removal */ - } else { - seg->flags |= SEGMENTTCP_FLAG_RAW_PROCESSED; - seg = seg->next; - } - continue; - } - - /* if app layer protocol has been detected, then remove all the segments - * which has been previously processed and reassembled - * - * If the stream is in GAP state the app layer flag won't be set */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream) && - (seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) && - StreamTcpAppLayerSegmentProcessed(ssn, stream, seg)) - { - SCLogDebug("segment(%p) of length %"PRIu16" has been processed," - " so return it to pool", seg, seg->payload_len); - TcpSegment *next_seg = seg->next; - StreamTcpRemoveSegmentFromStream(stream, seg); - StreamTcpSegmentReturntoPool(seg); - seg = next_seg; - continue; - } - - /* we've run into a sequence gap, wrap up any existing smsg and - * queue it so the next chunk (if any) is in a new smsg */ - if (SEQ_GT(seg->seq, next_seq)) { - /* pass on pre existing smsg (if any) */ - if (smsg != NULL && smsg->data_len > 0) { - StreamTcpStoreStreamChunk(ssn, smsg, p, 1); - stream->ra_raw_base_seq = ra_base_seq; - smsg = NULL; - } - - gap = 1; - } - - /* if the segment ends beyond left_edge we need to consider it */ - if (SEQ_GT((seg->seq + seg->payload_len), left_edge)) { - SCLogDebug("seg->seq %" PRIu32 ", seg->payload_len %" PRIu32 ", " - "left_edge %" PRIu32 "", seg->seq, - seg->payload_len, left_edge); - - /* handle segments partly before ra_base_seq */ - if (SEQ_GT(left_edge, seg->seq)) { - payload_offset = left_edge - seg->seq; - - if (SEQ_LT(right_edge, (seg->seq + seg->payload_len))) { - payload_len = (right_edge - seg->seq) - payload_offset; - } else { - payload_len = seg->payload_len - payload_offset; - } - - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - BUG_ON((payload_len + payload_offset) > seg->payload_len); - } - } else { - payload_offset = 0; - - if (SEQ_LT(right_edge, (seg->seq + seg->payload_len))) { - payload_len = right_edge - seg->seq; - } else { - payload_len = seg->payload_len; - } - } - SCLogDebug("payload_offset is %"PRIu16", payload_len is %"PRIu16"" - " and stream->last_ack is %"PRIu32"", payload_offset, - payload_len, stream->last_ack); - - if (payload_len == 0) { - SCLogDebug("no payload_len, so bail out"); - break; - } - - if (smsg == NULL) { - smsg = StreamMsgGetFromPool(); - if (smsg == NULL) { - SCLogDebug("stream_msg_pool is empty"); - return -1; - } - - smsg_offset = 0; - - StreamTcpSetupMsg(ssn, stream, p, smsg); - smsg->seq = ra_base_seq + 1; - } - - /* copy the data into the smsg */ - uint32_t copy_size = smsg->data_size - smsg_offset; - if (copy_size > payload_len) { - copy_size = payload_len; - } - if (SCLogDebugEnabled()) { - BUG_ON(copy_size > smsg->data_size); - } - SCLogDebug("copy_size is %"PRIu16"", copy_size); - memcpy(smsg->data + smsg_offset, seg->payload + payload_offset, - copy_size); - smsg_offset += copy_size; - - SCLogDebug("seg total %u, seq %u off %u copy %u, ra_base_seq %u", - (seg->seq + payload_offset + copy_size), seg->seq, - payload_offset, copy_size, ra_base_seq); - if (gap == 0 && SEQ_GT((seg->seq + payload_offset + copy_size),ra_base_seq+1)) { - ra_base_seq += copy_size; - } - SCLogDebug("ra_base_seq %"PRIu32, ra_base_seq); - - smsg->data_len += copy_size; - - /* queue the smsg if it's full */ - if (smsg->data_len == smsg->data_size) { - StreamTcpStoreStreamChunk(ssn, smsg, p, 1); - stream->ra_raw_base_seq = ra_base_seq; - smsg = NULL; - } - - /* if the payload len is bigger than what we copied, we handle the - * rest of the payload next... */ - if (copy_size < payload_len) { - SCLogDebug("copy_size %" PRIu32 " < %" PRIu32 "", copy_size, - payload_len); - payload_offset += copy_size; - payload_len -= copy_size; - SCLogDebug("payload_offset is %"PRIu16", seg->payload_len is " - "%"PRIu16" and stream->last_ack is %"PRIu32"", - payload_offset, seg->payload_len, stream->last_ack); - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - } - - /* we need a while loop here as the packets theoretically can be - * 64k */ - char segment_done = FALSE; - while (segment_done == FALSE) { - SCLogDebug("new msg at offset %" PRIu32 ", payload_len " - "%" PRIu32 "", payload_offset, payload_len); - - /* get a new message - XXX we need a setup function */ - smsg = StreamMsgGetFromPool(); - if (smsg == NULL) { - SCLogDebug("stream_msg_pool is empty"); - SCReturnInt(-1); - } - smsg_offset = 0; - - StreamTcpSetupMsg(ssn, stream,p,smsg); - smsg->seq = ra_base_seq + 1; - - copy_size = smsg->data_size - smsg_offset; - if ((int32_t)copy_size > (seg->payload_len - payload_offset)) { - copy_size = (seg->payload_len - payload_offset); - } - if (SCLogDebugEnabled()) { - BUG_ON(copy_size > smsg->data_size); - } - - SCLogDebug("copy payload_offset %" PRIu32 ", smsg_offset " - "%" PRIu32 ", copy_size %" PRIu32 "", - payload_offset, smsg_offset, copy_size); - memcpy(smsg->data + smsg_offset, seg->payload + - payload_offset, copy_size); - smsg_offset += copy_size; - if (gap == 0 && SEQ_GT((seg->seq + payload_offset + copy_size),ra_base_seq+1)) { - ra_base_seq += copy_size; - } - SCLogDebug("ra_base_seq %"PRIu32, ra_base_seq); - smsg->data_len += copy_size; - SCLogDebug("copied payload_offset %" PRIu32 ", " - "smsg_offset %" PRIu32 ", copy_size %" PRIu32 "", - payload_offset, smsg_offset, copy_size); - if (smsg->data_len == smsg->data_size) { - StreamTcpStoreStreamChunk(ssn, smsg, p, 1); - stream->ra_raw_base_seq = ra_base_seq; - smsg = NULL; - } - - /* see if we have segment payload left to process */ - if ((copy_size + payload_offset) < seg->payload_len) { - payload_offset += copy_size; - payload_len -= copy_size; - - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - } - } else { - payload_offset = 0; - segment_done = TRUE; - } - } - } - } - - /* done with this segment, return it to the pool */ - TcpSegment *next_seg = seg->next; - next_seq = seg->seq + seg->payload_len; - - if (SEQ_LT((seg->seq + seg->payload_len), (ra_base_seq - chunk_size))) { - if (seg->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED) { - StreamTcpRemoveSegmentFromStream(stream, seg); - SCLogDebug("removing seg %p, seg->next %p", seg, seg->next); - StreamTcpSegmentReturntoPool(seg); - } else { - seg->flags |= SEGMENTTCP_FLAG_RAW_PROCESSED; - } - } - seg = next_seg; - } - - /* put the partly filled smsg in the queue */ - if (smsg != NULL) { - StreamTcpStoreStreamChunk(ssn, smsg, p, 1); - smsg = NULL; - stream->ra_raw_base_seq = ra_base_seq; - } - - /* see if we can clean up some segments */ - left_edge = (ra_base_seq + 1) - chunk_size; - SCLogDebug("left_edge %"PRIu32", ra_base_seq %"PRIu32, left_edge, ra_base_seq); - - /* loop through the segments to remove unneeded segments */ - for (seg = stream->seg_list; seg != NULL && SEQ_LEQ((seg->seq + p->payload_len), left_edge); ) { - SCLogDebug("seg %p seq %"PRIu32", len %"PRIu16", sum %"PRIu32, seg, seg->seq, seg->payload_len, seg->seq+seg->payload_len); - - /* only remove if app layer reassembly is ready too */ - if (StreamTcpAppLayerSegmentProcessed(ssn, stream, seg)) { - TcpSegment *next_seg = seg->next; - StreamTcpRemoveSegmentFromStream(stream, seg); - StreamTcpSegmentReturntoPool(seg); - seg = next_seg; - } else { - break; - } - } - SCLogDebug("stream->ra_raw_base_seq %u", stream->ra_raw_base_seq); - SCReturnInt(0); -} - -/** \brief Remove idle TcpSegments from TcpSession - * - * \param f flow - * \param flags direction flags - */ -void StreamTcpPruneSession(Flow *f, uint8_t flags) -{ - if (f == NULL || f->protoctx == NULL) - return; - - TcpSession *ssn = f->protoctx; - TcpStream *stream = NULL; - - if (flags & STREAM_TOSERVER) { - stream = &ssn->client; - } else if (flags & STREAM_TOCLIENT) { - stream = &ssn->server; - } else { - return; - } - - /* loop through the segments and fill one or more msgs */ - TcpSegment *seg = stream->seg_list; - - for (; seg != NULL && SEQ_LT(seg->seq, stream->last_ack);) - { - SCLogDebug("seg %p, SEQ %"PRIu32", LEN %"PRIu16", SUM %"PRIu32", FLAGS %02x", - seg, seg->seq, seg->payload_len, - (uint32_t)(seg->seq + seg->payload_len), seg->flags); - - if (StreamTcpReturnSegmentCheck(f, ssn, stream, seg) == 0) { - break; - } - - TcpSegment *next_seg = seg->next; - StreamTcpRemoveSegmentFromStream(stream, seg); - StreamTcpSegmentReturntoPool(seg); - seg = next_seg; - continue; - } -} - -#ifdef DEBUG -static uint64_t GetStreamSize(TcpStream *stream) -{ - if (stream) { - uint64_t size = 0; - uint32_t cnt = 0; - - TcpSegment *seg = stream->seg_list; - while (seg) { - cnt++; - size += (uint64_t)seg->payload_len; - - seg = seg->next; - } - - SCLogDebug("size %"PRIu64", cnt %"PRIu32, size, cnt); - return size; - } - return (uint64_t)0; -} - -static void GetSessionSize(TcpSession *ssn, Packet *p) -{ - uint64_t size = 0; - if (ssn) { - size = GetStreamSize(&ssn->client); - size += GetStreamSize(&ssn->server); - - //if (size > 900000) - // SCLogInfo("size %"PRIu64", packet %"PRIu64, size, p->pcap_cnt); - SCLogDebug("size %"PRIu64", packet %"PRIu64, size, p->pcap_cnt); - } -} -#endif - -typedef struct ReassembleData_ { - uint32_t ra_base_seq; - uint32_t data_len; - uint8_t data[4096]; - int partial; /* last segment was processed only partially */ - uint32_t data_sent; /* data passed on this run */ -} ReassembleData; - -/** \internal - * \brief test if segment follows a gap. If so, handle the gap - * - * If in inline mode, segment may be un-ack'd. In this case we - * consider it a gap, but it's not 'final' yet. - * - * \retval bool 1 gap 0 no gap - */ -int DoHandleGap(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpSession *ssn, TcpStream *stream, TcpSegment *seg, ReassembleData *rd, - Packet *p, uint32_t next_seq) -{ - if (unlikely(SEQ_GT(seg->seq, next_seq))) { - /* we've run into a sequence gap */ - - if (StreamTcpInlineMode()) { - /* don't conclude it's a gap until we see that the data - * that is missing was acked. */ - if (SEQ_GT(seg->seq,stream->last_ack) && ssn->state != TCP_CLOSED) - return 1; - } - - /* first, pass on data before the gap */ - if (rd->data_len > 0) { - SCLogDebug("pre GAP data"); - - /* process what we have so far */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - rd->data, rd->data_len, - StreamGetAppLayerFlags(ssn, stream, p)); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - rd->data_sent += rd->data_len; - rd->data_len = 0; - } - -#ifdef DEBUG - uint32_t gap_len = seg->seq - next_seq; - SCLogDebug("expected next_seq %" PRIu32 ", got %" PRIu32 " , " - "stream->last_ack %" PRIu32 ". Seq gap %" PRIu32"", - next_seq, seg->seq, stream->last_ack, gap_len); -#endif - /* We have missed the packet and end host has ack'd it, so - * IDS should advance it's ra_base_seq and should not consider this - * packet any longer, even if it is retransmitted, as end host will - * drop it anyway */ - rd->ra_base_seq = seg->seq - 1; - - /* send gap "signal" */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - NULL, 0, StreamGetAppLayerFlags(ssn, stream, p)|STREAM_GAP); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - - /* set a GAP flag and make sure not bothering this stream anymore */ - SCLogDebug("STREAMTCP_STREAM_FLAG_GAP set"); - stream->flags |= STREAMTCP_STREAM_FLAG_GAP; - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_SEQ_GAP); - StatsIncr(tv, ra_ctx->counter_tcp_reass_gap); -#ifdef DEBUG - dbg_app_layer_gap++; -#endif - return 1; - } - return 0; -} - -static inline int DoReassemble(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpSession *ssn, TcpStream *stream, TcpSegment *seg, ReassembleData *rd, - Packet *p) -{ - /* fast paths: send data directly into the app layer, w/o first doing - * a copy step. However, don't use the fast path until protocol detection - * has been completed - * TODO if initial data is big enough for proto detect, we could do the - * fast path anyway. */ - if (stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) { - /* fast path 1: segment is exactly what we need */ - if (likely(rd->data_len == 0 && - SEQ_EQ(seg->seq, rd->ra_base_seq+1) && - SEQ_EQ(stream->last_ack, (seg->seq + seg->payload_len)))) - { - /* process single segment directly */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - seg->payload, seg->payload_len, - StreamGetAppLayerFlags(ssn, stream, p)); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - rd->data_sent += seg->payload_len; - rd->ra_base_seq += seg->payload_len; -#ifdef DEBUG - ra_ctx->fp1++; -#endif - /* if after the first data chunk we have no alproto yet, - * there is no point in continueing here. */ - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)) { - SCLogDebug("no alproto after first data chunk"); - return 0; - } - return 1; - /* fast path 2: segment acked completely, meets minimal size req for 0copy processing */ - } else if (rd->data_len == 0 && - SEQ_EQ(seg->seq, rd->ra_base_seq+1) && - SEQ_GT(stream->last_ack, (seg->seq + seg->payload_len)) && - seg->payload_len >= stream_config.zero_copy_size) - { - /* process single segment directly */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - seg->payload, seg->payload_len, - StreamGetAppLayerFlags(ssn, stream, p)); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - rd->data_sent += seg->payload_len; - rd->ra_base_seq += seg->payload_len; -#ifdef DEBUG - ra_ctx->fp2++; -#endif - /* if after the first data chunk we have no alproto yet, - * there is no point in continueing here. */ - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)) { - SCLogDebug("no alproto after first data chunk"); - return 0; - } - return 1; - } - } -#ifdef DEBUG - ra_ctx->sp++; -#endif - uint16_t payload_offset = 0; - uint16_t payload_len = 0; - - /* start clean */ - rd->partial = FALSE; - - /* if the segment ends beyond ra_base_seq we need to consider it */ - if (SEQ_GT((seg->seq + seg->payload_len), rd->ra_base_seq+1)) { - SCLogDebug("seg->seq %" PRIu32 ", seg->payload_len %" PRIu32 ", " - "ra_base_seq %" PRIu32 ", last_ack %"PRIu32, seg->seq, - seg->payload_len, rd->ra_base_seq, stream->last_ack); - - if (StreamTcpInlineMode() == 0) { - /* handle segments partly before ra_base_seq */ - if (SEQ_GT(rd->ra_base_seq, seg->seq)) { - payload_offset = (rd->ra_base_seq + 1) - seg->seq; - SCLogDebug("payload_offset %u", payload_offset); - - if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) { - if (SEQ_LT(stream->last_ack, (rd->ra_base_seq + 1))) { - payload_len = (stream->last_ack - seg->seq); - SCLogDebug("payload_len %u", payload_len); - } else { - payload_len = (stream->last_ack - seg->seq) - payload_offset; - SCLogDebug("payload_len %u", payload_len); - } - rd->partial = TRUE; - } else { - payload_len = seg->payload_len - payload_offset; - SCLogDebug("payload_len %u", payload_len); - } - - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - BUG_ON((payload_len + payload_offset) > seg->payload_len); - } - } else { - payload_offset = 0; - - if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) { - payload_len = stream->last_ack - seg->seq; - SCLogDebug("payload_len %u", payload_len); - - rd->partial = TRUE; - } else { - payload_len = seg->payload_len; - SCLogDebug("payload_len %u", payload_len); - } - } - /* inline mode, don't consider last_ack as we process un-ACK'd segments */ - } else { - /* handle segments partly before ra_base_seq */ - if (SEQ_GT(rd->ra_base_seq, seg->seq)) { - payload_offset = rd->ra_base_seq - seg->seq - 1; - payload_len = seg->payload_len - payload_offset; - - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - BUG_ON((payload_len + payload_offset) > seg->payload_len); - } - } else { - payload_offset = 0; - payload_len = seg->payload_len; - } - } - SCLogDebug("payload_offset is %"PRIu16", payload_len is %"PRIu16"" - " and stream->last_ack is %"PRIu32"", payload_offset, - payload_len, stream->last_ack); - - if (payload_len == 0) { - SCLogDebug("no payload_len, so bail out"); - return 0; - } - - /* copy the data into the buffer */ - uint16_t copy_size = sizeof(rd->data) - rd->data_len; - if (copy_size > payload_len) { - copy_size = payload_len; - } - if (SCLogDebugEnabled()) { - BUG_ON(copy_size > sizeof(rd->data)); - } - SCLogDebug("copy_size is %"PRIu16"", copy_size); - memcpy(rd->data + rd->data_len, seg->payload + payload_offset, copy_size); - rd->data_len += copy_size; - rd->ra_base_seq += copy_size; - SCLogDebug("ra_base_seq %"PRIu32", data_len %"PRIu32, rd->ra_base_seq, rd->data_len); - - /* queue the smsg if it's full */ - if (rd->data_len == sizeof(rd->data)) { - /* process what we have so far */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - rd->data, rd->data_len, - StreamGetAppLayerFlags(ssn, stream, p)); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - rd->data_sent += rd->data_len; - rd->data_len = 0; - - /* if after the first data chunk we have no alproto yet, - * there is no point in continueing here. */ - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)) { - SCLogDebug("no alproto after first data chunk"); - return 0; - } - } - - /* if the payload len is bigger than what we copied, we handle the - * rest of the payload next... */ - if (copy_size < payload_len) { - SCLogDebug("copy_size %" PRIu32 " < %" PRIu32 "", copy_size, - payload_len); - - payload_offset += copy_size; - payload_len -= copy_size; - SCLogDebug("payload_offset is %"PRIu16", seg->payload_len is " - "%"PRIu16" and stream->last_ack is %"PRIu32"", - payload_offset, seg->payload_len, stream->last_ack); - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - } - - /* we need a while loop here as the packets theoretically can be - * 64k */ - char segment_done = FALSE; - while (segment_done == FALSE) { - SCLogDebug("new msg at offset %" PRIu32 ", payload_len " - "%" PRIu32 "", payload_offset, payload_len); - rd->data_len = 0; - - copy_size = sizeof(rd->data) - rd->data_len; - if (copy_size > (seg->payload_len - payload_offset)) { - copy_size = (seg->payload_len - payload_offset); - } - if (SCLogDebugEnabled()) { - BUG_ON(copy_size > sizeof(rd->data)); - } - - SCLogDebug("copy payload_offset %" PRIu32 ", data_len " - "%" PRIu32 ", copy_size %" PRIu32 "", - payload_offset, rd->data_len, copy_size); - memcpy(rd->data + rd->data_len, seg->payload + - payload_offset, copy_size); - rd->data_len += copy_size; - rd->ra_base_seq += copy_size; - SCLogDebug("ra_base_seq %"PRIu32, rd->ra_base_seq); - SCLogDebug("copied payload_offset %" PRIu32 ", " - "data_len %" PRIu32 ", copy_size %" PRIu32 "", - payload_offset, rd->data_len, copy_size); - - if (rd->data_len == sizeof(rd->data)) { - /* process what we have so far */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - rd->data, rd->data_len, - StreamGetAppLayerFlags(ssn, stream, p)); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - rd->data_sent += rd->data_len; - rd->data_len = 0; - - /* if after the first data chunk we have no alproto yet, - * there is no point in continueing here. */ - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)) { - SCLogDebug("no alproto after first data chunk"); - return 0; - } - } - - /* see if we have segment payload left to process */ - if ((copy_size + payload_offset) < seg->payload_len) { - payload_offset += copy_size; - payload_len -= copy_size; - - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - } - } else { - payload_offset = 0; - segment_done = TRUE; - } - } - } - } - - return 1; -} - -/** - * \brief Update the stream reassembly upon receiving an ACK packet. - * - * Stream is in the opposite direction of the packet, as the ACK-packet - * is ACK'ing the stream. - * - * One of the utilities call by this function AppLayerHandleTCPData(), - * has a feature where it will call this very same function for the - * stream opposing the stream it is called with. This shouldn't cause - * any issues, since processing of each stream is independent of the - * other stream. - * - * \todo this function is too long, we need to break it up. It needs it BAD - */ -int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpSession *ssn, TcpStream *stream, - Packet *p) -{ - SCEnter(); - - /* this function can be directly called by app layer protocol - * detection. */ - if (stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) { - SCLogDebug("stream no reassembly flag set. Mostly called via " - "app proto detection."); - SCReturnInt(0); - } - - SCLogDebug("stream->seg_list %p", stream->seg_list); -#ifdef DEBUG - PrintList(stream->seg_list); - GetSessionSize(ssn, p); -#endif - - /* Check if we have a gap at the start of the stream. 2 conditions: - * 1. no segments, but last_ack moved fwd - * 2. segments, but clearly some missing: if last_ack is - * bigger than the list start and the list start is bigger than - * next_seq, we know we are missing data that has been ack'd. That - * won't get retransmitted, so it's a data gap. - */ - if (!(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED)) { - int ackadd = (ssn->state >= TCP_FIN_WAIT2) ? 2 : 1; - if ((stream->seg_list == NULL && /*1*/ - stream->ra_app_base_seq == stream->isn && - SEQ_GT(stream->last_ack, stream->isn + ackadd)) - || - (stream->seg_list != NULL && /*2*/ - SEQ_GT(stream->seg_list->seq, stream->ra_app_base_seq+1) && - SEQ_LT(stream->seg_list->seq, stream->last_ack))) - { - if (stream->seg_list == NULL) { - SCLogDebug("no segs, last_ack moved fwd so GAP " - "(base %u, isn %u, last_ack %u => diff %u) p %"PRIu64, - stream->ra_app_base_seq, stream->isn, stream->last_ack, - stream->last_ack - (stream->isn + ackadd), p->pcap_cnt); - } - - /* send gap signal */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - NULL, 0, - StreamGetAppLayerFlags(ssn, stream, p)|STREAM_GAP); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - - /* set a GAP flag and make sure not bothering this stream anymore */ - SCLogDebug("STREAMTCP_STREAM_FLAG_GAP set"); - stream->flags |= STREAMTCP_STREAM_FLAG_GAP; - - StreamTcpSetEvent(p, STREAM_REASSEMBLY_SEQ_GAP); - StatsIncr(tv, ra_ctx->counter_tcp_reass_gap); -#ifdef DEBUG - dbg_app_layer_gap++; -#endif - SCReturnInt(0); - } - } - - /* if no segments are in the list or all are already processed, - * and state is beyond established, we send an empty msg */ - TcpSegment *seg_tail = stream->seg_list_tail; - if (seg_tail == NULL || - (seg_tail->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED)) - { - /* send an empty EOF msg if we have no segments but TCP state - * is beyond ESTABLISHED */ - if (ssn->state >= TCP_CLOSING || (p->flags & PKT_PSEUDO_STREAM_END)) { - SCLogDebug("sending empty eof message"); - /* send EOF to app layer */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - NULL, 0, - StreamGetAppLayerFlags(ssn, stream, p)); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - - SCReturnInt(0); - } - } - - /* no segments, nothing to do */ - if (stream->seg_list == NULL) { - SCLogDebug("no segments in the list to reassemble"); - SCReturnInt(0); - } - - - if (stream->flags & STREAMTCP_STREAM_FLAG_GAP) { - SCReturnInt(0); - } - - /* stream->ra_app_base_seq remains at stream->isn until protocol is - * detected. */ - ReassembleData rd; - rd.ra_base_seq = stream->ra_app_base_seq; - rd.data_len = 0; - rd.data_sent = 0; - rd.partial = FALSE; - uint32_t next_seq = rd.ra_base_seq + 1; - - SCLogDebug("ra_base_seq %"PRIu32", last_ack %"PRIu32", next_seq %"PRIu32, - rd.ra_base_seq, stream->last_ack, next_seq); - - /* loop through the segments and fill one or more msgs */ - TcpSegment *seg = stream->seg_list; - SCLogDebug("pre-loop seg %p", seg); -#ifdef DEBUG_VALIDATION - uint64_t bytes = 0; -#endif - for (; seg != NULL; ) - { -#ifdef DEBUG_VALIDATION - bytes += seg->payload_len; -#endif - /* if in inline mode, we process all segments regardless of whether - * they are ack'd or not. In non-inline, we process only those that - * are at least partly ack'd. */ - if (StreamTcpInlineMode() == 0 && SEQ_GEQ(seg->seq, stream->last_ack)) - break; - - SCLogDebug("seg %p, SEQ %"PRIu32", LEN %"PRIu16", SUM %"PRIu32, - seg, seg->seq, seg->payload_len, - (uint32_t)(seg->seq + seg->payload_len)); - - if (StreamTcpReturnSegmentCheck(p->flow, ssn, stream, seg) == 1) { - SCLogDebug("removing segment"); - TcpSegment *next_seg = seg->next; - StreamTcpRemoveSegmentFromStream(stream, seg); - StreamTcpSegmentReturntoPool(seg); - seg = next_seg; - continue; - } else if (StreamTcpAppLayerSegmentProcessed(ssn, stream, seg)) { - TcpSegment *next_seg = seg->next; - seg = next_seg; - continue; - } - - /* check if we have a sequence gap and if so, handle it */ - if (DoHandleGap(tv, ra_ctx, ssn, stream, seg, &rd, p, next_seq) == 1) - break; - - /* process this segment */ - if (DoReassemble(tv, ra_ctx, ssn, stream, seg, &rd, p) == 0) - break; - - /* done with this segment, return it to the pool */ - TcpSegment *next_seg = seg->next; - next_seq = seg->seq + seg->payload_len; - if (rd.partial == FALSE) { - SCLogDebug("fully done with segment in app layer reassembly (seg %p seq %"PRIu32")", - seg, seg->seq); - seg->flags |= SEGMENTTCP_FLAG_APPLAYER_PROCESSED; - SCLogDebug("flags now %02x", seg->flags); - } else { - SCLogDebug("not yet fully done with segment in app layer reassembly"); - } - seg = next_seg; - } -#ifdef DEBUG_VALIDATION /* we should never have this much data queued */ - BUG_ON(bytes > 1000000ULL && bytes > (stream->window * 1.5)); -#endif - - /* put the partly filled smsg in the queue to the l7 handler */ - if (rd.data_len > 0) { - SCLogDebug("data_len > 0, %u", rd.data_len); - /* process what we have so far */ - BUG_ON(rd.data_len > sizeof(rd.data)); - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - rd.data, rd.data_len, - StreamGetAppLayerFlags(ssn, stream, p)); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - } - - /* if no data was sent to the applayer, we send it a empty 'nudge' - * when in inline mode */ - if (StreamTcpInlineMode() && rd.data_sent == 0 && ssn->state > TCP_ESTABLISHED) { - SCLogDebug("sending empty eof message"); - /* send EOF to app layer */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream, - NULL, 0, StreamGetAppLayerFlags(ssn, stream, p)); - AppLayerProfilingStore(ra_ctx->app_tctx, p); - } - - /* store ra_base_seq in the stream */ - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)) { - stream->ra_app_base_seq = rd.ra_base_seq; - } else { - TcpSegment *tmp_seg = stream->seg_list; - while (tmp_seg != NULL) { - if (!(tmp_seg->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED)) - break; - tmp_seg->flags &= ~SEGMENTTCP_FLAG_APPLAYER_PROCESSED; - tmp_seg = tmp_seg->next; - } - } - SCLogDebug("stream->ra_app_base_seq %u", stream->ra_app_base_seq); - SCReturnInt(0); -} - -typedef struct ReassembleRawData_ { - uint32_t ra_base_seq; - int partial; /* last segment was processed only partially */ - StreamMsg *smsg; - uint32_t smsg_offset; // TODO diff with smsg->data_len? -} ReassembleRawData; - -static void DoHandleRawGap(TcpSession *ssn, TcpStream *stream, TcpSegment *seg, Packet *p, - ReassembleRawData *rd, uint32_t next_seq) -{ - /* we've run into a sequence gap */ - if (SEQ_GT(seg->seq, next_seq)) { - /* pass on pre existing smsg (if any) */ - if (rd->smsg != NULL && rd->smsg->data_len > 0) { - /* if app layer protocol has not been detected till yet, - then check did we have sent message to app layer already - or not. If not then sent the message and set flag that first - message has been sent. No more data till proto has not - been detected */ - StreamTcpStoreStreamChunk(ssn, rd->smsg, p, 0); - stream->ra_raw_base_seq = rd->ra_base_seq; - rd->smsg = NULL; - } - - /* see what the length of the gap is, gap length is seg->seq - - * (ra_base_seq +1) */ -#ifdef DEBUG - uint32_t gap_len = seg->seq - next_seq; - SCLogDebug("expected next_seq %" PRIu32 ", got %" PRIu32 " , " - "stream->last_ack %" PRIu32 ". Seq gap %" PRIu32"", - next_seq, seg->seq, stream->last_ack, gap_len); -#endif - stream->ra_raw_base_seq = rd->ra_base_seq; - - /* We have missed the packet and end host has ack'd it, so - * IDS should advance it's ra_base_seq and should not consider this - * packet any longer, even if it is retransmitted, as end host will - * drop it anyway */ - rd->ra_base_seq = seg->seq - 1; - } -} - -static int DoRawReassemble(TcpSession *ssn, TcpStream *stream, TcpSegment *seg, Packet *p, - ReassembleRawData *rd) -{ - uint16_t payload_offset = 0; - uint16_t payload_len = 0; - - /* start clean */ - rd->partial = FALSE; - - /* if the segment ends beyond ra_base_seq we need to consider it */ - if (SEQ_GT((seg->seq + seg->payload_len), rd->ra_base_seq+1)) { - SCLogDebug("seg->seq %" PRIu32 ", seg->payload_len %" PRIu32 ", " - "ra_base_seq %" PRIu32 "", seg->seq, - seg->payload_len, rd->ra_base_seq); - - /* handle segments partly before ra_base_seq */ - if (SEQ_GT(rd->ra_base_seq, seg->seq)) { - payload_offset = rd->ra_base_seq - seg->seq; - - if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) { - - if (SEQ_LT(stream->last_ack, rd->ra_base_seq)) { - payload_len = (stream->last_ack - seg->seq); - } else { - payload_len = (stream->last_ack - seg->seq) - payload_offset; - } - rd->partial = TRUE; - } else { - payload_len = seg->payload_len - payload_offset; - } - - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - BUG_ON((payload_len + payload_offset) > seg->payload_len); - } - } else { - payload_offset = 0; - - if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) { - payload_len = stream->last_ack - seg->seq; - rd->partial = TRUE; - } else { - payload_len = seg->payload_len; - } - } - SCLogDebug("payload_offset is %"PRIu16", payload_len is %"PRIu16"" - " and stream->last_ack is %"PRIu32"", payload_offset, - payload_len, stream->last_ack); - - if (payload_len == 0) { - SCLogDebug("no payload_len, so bail out"); - return 1; // TODO - } - - if (rd->smsg == NULL) { - rd->smsg = StreamMsgGetFromPool(); - if (rd->smsg == NULL) { - SCLogDebug("stream_msg_pool is empty"); - return -1; - } - - rd->smsg_offset = 0; - - StreamTcpSetupMsg(ssn, stream, p, rd->smsg); - rd->smsg->seq = rd->ra_base_seq + 1; - SCLogDebug("smsg->seq %u", rd->smsg->seq); - } - - /* copy the data into the smsg */ - uint32_t copy_size = rd->smsg->data_size - rd->smsg_offset; - if (copy_size > payload_len) { - copy_size = payload_len; - } - if (SCLogDebugEnabled()) { - BUG_ON(copy_size > rd->smsg->data_size); - } - SCLogDebug("copy_size is %"PRIu16"", copy_size); - memcpy(rd->smsg->data + rd->smsg_offset, seg->payload + payload_offset, - copy_size); - rd->smsg_offset += copy_size; - rd->ra_base_seq += copy_size; - SCLogDebug("ra_base_seq %"PRIu32, rd->ra_base_seq); - - rd->smsg->data_len += copy_size; - - /* queue the smsg if it's full */ - if (rd->smsg->data_len == rd->smsg->data_size) { - StreamTcpStoreStreamChunk(ssn, rd->smsg, p, 0); - stream->ra_raw_base_seq = rd->ra_base_seq; - rd->smsg = NULL; - } - - /* if the payload len is bigger than what we copied, we handle the - * rest of the payload next... */ - if (copy_size < payload_len) { - SCLogDebug("copy_size %" PRIu32 " < %" PRIu32 "", copy_size, - payload_len); - - payload_offset += copy_size; - payload_len -= copy_size; - SCLogDebug("payload_offset is %"PRIu16", seg->payload_len is " - "%"PRIu16" and stream->last_ack is %"PRIu32"", - payload_offset, seg->payload_len, stream->last_ack); - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - } - - /* we need a while loop here as the packets theoretically can be - * 64k */ - char segment_done = FALSE; - while (segment_done == FALSE) { - SCLogDebug("new msg at offset %" PRIu32 ", payload_len " - "%" PRIu32 "", payload_offset, payload_len); - - /* get a new message - XXX we need a setup function */ - rd->smsg = StreamMsgGetFromPool(); - if (rd->smsg == NULL) { - SCLogDebug("stream_msg_pool is empty"); - SCReturnInt(-1); - } - rd->smsg_offset = 0; - - StreamTcpSetupMsg(ssn, stream, p, rd->smsg); - rd->smsg->seq = rd->ra_base_seq + 1; - - copy_size = rd->smsg->data_size - rd->smsg_offset; - if (copy_size > payload_len) { - copy_size = payload_len; - } - if (SCLogDebugEnabled()) { - BUG_ON(copy_size > rd->smsg->data_size); - } - - SCLogDebug("copy payload_offset %" PRIu32 ", smsg_offset " - "%" PRIu32 ", copy_size %" PRIu32 "", - payload_offset, rd->smsg_offset, copy_size); - memcpy(rd->smsg->data + rd->smsg_offset, seg->payload + - payload_offset, copy_size); - rd->smsg_offset += copy_size; - rd->ra_base_seq += copy_size; - SCLogDebug("ra_base_seq %"PRIu32, rd->ra_base_seq); - rd->smsg->data_len += copy_size; - SCLogDebug("copied payload_offset %" PRIu32 ", " - "smsg_offset %" PRIu32 ", copy_size %" PRIu32 "", - payload_offset, rd->smsg_offset, copy_size); - if (rd->smsg->data_len == rd->smsg->data_size) { - StreamTcpStoreStreamChunk(ssn, rd->smsg, p, 0); - stream->ra_raw_base_seq = rd->ra_base_seq; - rd->smsg = NULL; - } - - /* see if we have segment payload left to process */ - if (copy_size < payload_len) { - payload_offset += copy_size; - payload_len -= copy_size; - - if (SCLogDebugEnabled()) { - BUG_ON(payload_offset > seg->payload_len); - } - } else { - payload_offset = 0; - segment_done = TRUE; - } - } - } - } - return 1; -} - -/** - * \brief Update the stream reassembly upon receiving an ACK packet. - * \todo this function is too long, we need to break it up. It needs it BAD - */ -static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx, - TcpSession *ssn, TcpStream *stream, Packet *p) -{ - SCEnter(); - SCLogDebug("start p %p", p); - - if (ssn->flags & STREAMTCP_FLAG_DISABLE_RAW) - SCReturnInt(0); - - if (stream->seg_list == NULL) { - SCLogDebug("no segments in the list to reassemble"); - SCReturnInt(0); - } - -#if 0 - if (ssn->state <= TCP_ESTABLISHED && - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)) { - SCLogDebug("only starting raw reassembly after app layer protocol " - "detection has completed."); - SCReturnInt(0); - } -#endif - /* check if we have enough data */ - if (StreamTcpReassembleRawCheckLimit(ssn,stream,p) == 0) { - SCLogDebug("not yet reassembling"); - SCReturnInt(0); - } - - TcpSegment *seg = stream->seg_list; - ReassembleRawData rd; - rd.smsg = NULL; - rd.ra_base_seq = stream->ra_raw_base_seq; - rd.smsg_offset = 0; - uint32_t next_seq = rd.ra_base_seq + 1; - - SCLogDebug("ra_base_seq %"PRIu32", last_ack %"PRIu32", next_seq %"PRIu32, - rd.ra_base_seq, stream->last_ack, next_seq); - - /* loop through the segments and fill one or more msgs */ - for (; seg != NULL && SEQ_LT(seg->seq, stream->last_ack);) - { - SCLogDebug("seg %p, SEQ %"PRIu32", LEN %"PRIu16", SUM %"PRIu32", flags %02x", - seg, seg->seq, seg->payload_len, - (uint32_t)(seg->seq + seg->payload_len), seg->flags); - - if (StreamTcpReturnSegmentCheck(p->flow, ssn, stream, seg) == 1) { - SCLogDebug("removing segment"); - TcpSegment *next_seg = seg->next; - StreamTcpRemoveSegmentFromStream(stream, seg); - StreamTcpSegmentReturntoPool(seg); - seg = next_seg; - continue; - } else if(seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) { - TcpSegment *next_seg = seg->next; - seg = next_seg; - continue; - } - - DoHandleRawGap(ssn, stream, seg, p, &rd, next_seq); - - if (DoRawReassemble(ssn, stream, seg, p, &rd) == 0) - break; - - /* done with this segment, return it to the pool */ - TcpSegment *next_seg = seg->next; - next_seq = seg->seq + seg->payload_len; - if (rd.partial == FALSE) { - SCLogDebug("fully done with segment in raw reassembly (seg %p seq %"PRIu32")", - seg, seg->seq); - seg->flags |= SEGMENTTCP_FLAG_RAW_PROCESSED; - SCLogDebug("flags now %02x", seg->flags); - } else { - SCLogDebug("not yet fully done with segment in raw reassembly"); - } - seg = next_seg; - } - - /* put the partly filled smsg in the queue to the l7 handler */ - if (rd.smsg != NULL) { - StreamTcpStoreStreamChunk(ssn, rd.smsg, p, 0); - rd.smsg = NULL; - stream->ra_raw_base_seq = rd.ra_base_seq; - } - - SCReturnInt(0); -} - -/** \brief update app layer and raw reassembly - * - * \retval r 0 on success, -1 on error - */ -int StreamTcpReassembleHandleSegmentUpdateACK (ThreadVars *tv, - TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p) -{ - SCEnter(); - - SCLogDebug("stream->seg_list %p", stream->seg_list); - - int r = 0; - if (!(StreamTcpInlineMode())) { - if (StreamTcpReassembleAppLayer(tv, ra_ctx, ssn, stream, p) < 0) - r = -1; - if (StreamTcpReassembleRaw(ra_ctx, ssn, stream, p) < 0) - r = -1; - } - - SCLogDebug("stream->seg_list %p", stream->seg_list); - SCReturnInt(r); -} - -int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpSession *ssn, TcpStream *stream, - Packet *p, PacketQueue *pq) -{ - SCEnter(); - SCLogDebug("ssn %p, stream %p, p %p, p->payload_len %"PRIu16"", - ssn, stream, p, p->payload_len); - - /* we need to update the opposing stream in - * StreamTcpReassembleHandleSegmentUpdateACK */ - TcpStream *opposing_stream = NULL; - if (stream == &ssn->client) { - opposing_stream = &ssn->server; - } else { - opposing_stream = &ssn->client; - } - - /* handle ack received */ - if (StreamTcpReassembleHandleSegmentUpdateACK(tv, ra_ctx, ssn, opposing_stream, p) != 0) - { - SCLogDebug("StreamTcpReassembleHandleSegmentUpdateACK error"); - SCReturnInt(-1); - } - - /* If no stream reassembly/application layer protocol inspection, then - simple return */ - if (p->payload_len > 0 && !(stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - SCLogDebug("calling StreamTcpReassembleHandleSegmentHandleData"); - - if (StreamTcpReassembleHandleSegmentHandleData(tv, ra_ctx, ssn, stream, p) != 0) { - SCLogDebug("StreamTcpReassembleHandleSegmentHandleData error"); - SCReturnInt(-1); - } - - p->flags |= PKT_STREAM_ADD; - } - - /* in stream inline mode even if we have no data we call the reassembly - * functions to handle EOF */ - if (StreamTcpInlineMode()) { - int r = 0; - if (StreamTcpReassembleAppLayer(tv, ra_ctx, ssn, stream, p) < 0) - r = -1; - if (StreamTcpReassembleInlineRaw(ra_ctx, ssn, stream, p) < 0) - r = -1; - - if (r < 0) { - SCReturnInt(-1); - } - } - - SCReturnInt(0); -} - -/** - * \brief Function to replace the data from a specific point up to given length. - * - * \param dst_seg Destination segment to replace the data - * \param src_seg Source segment of which data is to be written to destination - * \param start_point Starting point to replace the data onwards - * \param len Length up to which data is need to be replaced - * - * \todo VJ We can remove the abort()s later. - * \todo VJ Why not memcpy? - */ -void StreamTcpSegmentDataReplace(TcpSegment *dst_seg, TcpSegment *src_seg, - uint32_t start_point, uint16_t len) -{ - uint32_t seq; - uint16_t src_pos = 0; - uint16_t dst_pos = 0; - - SCLogDebug("start_point %u", start_point); - - if (SEQ_GT(start_point, dst_seg->seq)) { - dst_pos = start_point - dst_seg->seq; - } else if (SEQ_LT(start_point, dst_seg->seq)) { - dst_pos = dst_seg->seq - start_point; - } - - if (SCLogDebugEnabled()) { - BUG_ON(((len + dst_pos) - 1) > dst_seg->payload_len); - } else { - if (((len + dst_pos) - 1) > dst_seg->payload_len) - return; - } - - src_pos = (uint16_t)(start_point - src_seg->seq); - - SCLogDebug("Replacing data from dst_pos %"PRIu16"", dst_pos); - - for (seq = start_point; SEQ_LT(seq, (start_point + len)) && - src_pos < src_seg->payload_len && dst_pos < dst_seg->payload_len; - seq++, dst_pos++, src_pos++) - { - dst_seg->payload[dst_pos] = src_seg->payload[src_pos]; - } - - SCLogDebug("Replaced data of size %"PRIu16" up to src_pos %"PRIu16 - " dst_pos %"PRIu16, len, src_pos, dst_pos); -} - -/** - * \brief Function to compare the data from a specific point up to given length. - * - * \param dst_seg Destination segment to compare the data - * \param src_seg Source segment of which data is to be compared to destination - * \param start_point Starting point to compare the data onwards - * \param len Length up to which data is need to be compared - * - * \retval 1 same - * \retval 0 different - */ -static int StreamTcpSegmentDataCompare(TcpSegment *dst_seg, TcpSegment *src_seg, - uint32_t start_point, uint16_t len) -{ - uint32_t seq; - uint16_t src_pos = 0; - uint16_t dst_pos = 0; - - SCLogDebug("start_point %u dst_seg %u src_seg %u", start_point, dst_seg->seq, src_seg->seq); - - if (SEQ_GT(start_point, dst_seg->seq)) { - SCLogDebug("start_point %u > dst %u", start_point, dst_seg->seq); - dst_pos = start_point - dst_seg->seq; - } else if (SEQ_LT(start_point, dst_seg->seq)) { - SCLogDebug("start_point %u < dst %u", start_point, dst_seg->seq); - dst_pos = dst_seg->seq - start_point; - } - - if (SCLogDebugEnabled()) { - BUG_ON(((len + dst_pos) - 1) > dst_seg->payload_len); - } else { - if (((len + dst_pos) - 1) > dst_seg->payload_len) - return 1; - } - - src_pos = (uint16_t)(start_point - src_seg->seq); - - SCLogDebug("Comparing data from dst_pos %"PRIu16", src_pos %u", dst_pos, src_pos); - - for (seq = start_point; SEQ_LT(seq, (start_point + len)) && - src_pos < src_seg->payload_len && dst_pos < dst_seg->payload_len; - seq++, dst_pos++, src_pos++) - { - if (dst_seg->payload[dst_pos] != src_seg->payload[src_pos]) { - SCLogDebug("data is different %02x != %02x, dst_pos %u, src_pos %u", dst_seg->payload[dst_pos], src_seg->payload[src_pos], dst_pos, src_pos); - return 0; - } - } - - SCLogDebug("Compared data of size %"PRIu16" up to src_pos %"PRIu16 - " dst_pos %"PRIu16, len, src_pos, dst_pos); - return 1; -} - -/** - * \brief Function to copy the data from src_seg to dst_seg. - * - * \param dst_seg Destination segment for copying the contents - * \param src_seg Source segment to copy its contents - * - * \todo VJ wouldn't a memcpy be more appropriate here? - * - * \warning Both segments need to be properly initialized. - */ - -void StreamTcpSegmentDataCopy(TcpSegment *dst_seg, TcpSegment *src_seg) -{ - uint32_t u; - uint16_t dst_pos = 0; - uint16_t src_pos = 0; - uint32_t seq; - - if (SEQ_GT(dst_seg->seq, src_seg->seq)) { - src_pos = dst_seg->seq - src_seg->seq; - seq = dst_seg->seq; - } else { - dst_pos = src_seg->seq - dst_seg->seq; - seq = src_seg->seq; - } - - SCLogDebug("Copying data from seq %"PRIu32"", seq); - for (u = seq; - (SEQ_LT(u, (src_seg->seq + src_seg->payload_len)) && - SEQ_LT(u, (dst_seg->seq + dst_seg->payload_len))); u++) - { - //SCLogDebug("u %"PRIu32, u); - - dst_seg->payload[dst_pos] = src_seg->payload[src_pos]; - - dst_pos++; - src_pos++; - } - SCLogDebug("Copyied data of size %"PRIu16" up to dst_pos %"PRIu16"", - src_pos, dst_pos); -} - -/** - * \brief Function to get the segment of required length from the pool. - * - * \param len Length which tells the required size of needed segment. - * - * \retval seg Segment from the pool or NULL - */ -TcpSegment* StreamTcpGetSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, uint16_t len) -{ - uint16_t idx = segment_pool_idx[len]; - SCLogDebug("segment_pool_idx %" PRIu32 " for payload_len %" PRIu32 "", - idx, len); - - SCMutexLock(&segment_pool_mutex[idx]); - TcpSegment *seg = (TcpSegment *) PoolGet(segment_pool[idx]); - - SCLogDebug("segment_pool[%u]->empty_stack_size %u, segment_pool[%u]->alloc_" - "list_size %u, alloc %u", idx, segment_pool[idx]->empty_stack_size, - idx, segment_pool[idx]->alloc_stack_size, - segment_pool[idx]->allocated); - SCMutexUnlock(&segment_pool_mutex[idx]); - - SCLogDebug("seg we return is %p", seg); - if (seg == NULL) { - SCLogDebug("segment_pool[%u]->empty_stack_size %u, " - "alloc %u", idx, segment_pool[idx]->empty_stack_size, - segment_pool[idx]->allocated); - /* Increment the counter to show that we are not able to serve the - segment request due to memcap limit */ - StatsIncr(tv, ra_ctx->counter_tcp_segment_memcap); - } else { - seg->flags = stream_config.segment_init_flags; - seg->next = NULL; - seg->prev = NULL; - } - -#ifdef DEBUG - SCMutexLock(&segment_pool_cnt_mutex); - segment_pool_cnt++; - SCMutexUnlock(&segment_pool_cnt_mutex); -#endif - - return seg; -} - -/** - * \brief Trigger RAW stream reassembly - * - * Used by AppLayerTriggerRawStreamReassembly to trigger RAW stream - * reassembly from the applayer, for example upon completion of a - * HTTP request. - * - * Works by setting a flag in the TcpSession that is unset as soon - * as it's checked. Since everything happens when operating under - * a single lock period, no side effects are expected. - * - * \param ssn TcpSession - */ -void StreamTcpReassembleTriggerRawReassembly(TcpSession *ssn) -{ -#ifdef DEBUG - BUG_ON(ssn == NULL); -#endif - - if (ssn != NULL) { - SCLogDebug("flagged ssn %p for immediate raw reassembly", ssn); - ssn->flags |= STREAMTCP_FLAG_TRIGGER_RAW_REASSEMBLY; - } -} - -#ifdef UNITTESTS -/** unit tests and it's support functions below */ - -static int UtTestSmsg(StreamMsg *smsg, const uint8_t *buf, uint32_t buf_len) -{ - if (smsg == NULL) - return 0; - - if (smsg->data_len != buf_len) { - return 0; - } - - if (!(memcmp(buf, smsg->data, buf_len) == 0)) { - printf("data is not what we expected:\nExpected:\n"); - PrintRawDataFp(stdout, (uint8_t *)buf, buf_len); - printf("Got:\n"); - PrintRawDataFp(stdout, smsg->data, smsg->data_len); - return 0; - } - return 1; -} - -static uint32_t UtSsnSmsgCnt(TcpSession *ssn, uint8_t direction) -{ - uint32_t cnt = 0; - StreamMsg *smsg = (direction == STREAM_TOSERVER) ? - ssn->toserver_smsg_head : - ssn->toclient_smsg_head; - while (smsg) { - cnt++; - smsg = smsg->next; - } - return cnt; -} - -/** \brief The Function tests the reassembly engine working for different - * OSes supported. It includes all the OS cases and send - * crafted packets to test the reassembly. - * - * \param stream The stream which will contain the reassembled segments - */ - -static int StreamTcpReassembleStreamTest(TcpStream *stream) -{ - - TcpSession ssn; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->tcph->th_seq = htonl(12); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x42, 2, 4); /*BB*/ - p->tcph->th_seq = htonl(16); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x43, 3, 4); /*CCC*/ - p->tcph->th_seq = htonl(18); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x44, 1, 4); /*D*/ - p->tcph->th_seq = htonl(22); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x45, 2, 4); /*EE*/ - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x46, 3, 4); /*FFF*/ - p->tcph->th_seq = htonl(27); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x47, 2, 4); /*GG*/ - p->tcph->th_seq = htonl(30); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x48, 2, 4); /*HH*/ - p->tcph->th_seq = htonl(32); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x49, 1, 4); /*I*/ - p->tcph->th_seq = htonl(34); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4a, 4, 4); /*JJJJ*/ - p->tcph->th_seq = htonl(13); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 4; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4b, 3, 4); /*KKK*/ - p->tcph->th_seq = htonl(18); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4c, 3, 4); /*LLL*/ - p->tcph->th_seq = htonl(21); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4d, 3, 4); /*MMM*/ - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4e, 1, 4); /*N*/ - p->tcph->th_seq = htonl(28); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4f, 1, 4); /*O*/ - p->tcph->th_seq = htonl(31); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x50, 1, 4); /*P*/ - p->tcph->th_seq = htonl(32); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x51, 2, 4); /*QQ*/ - p->tcph->th_seq = htonl(34); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x30, 1, 4); /*0*/ - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpReassembleFreeThreadCtx(ra_ctx); - - SCFree(p); - return 1; -} - -/** \brief The Function to create the packet with given payload, which is used - * to test the reassembly of the engine. - * - * \param payload The variable used to store the payload contents of the - * current packet. - * \param value The value which current payload will have for this packet - * \param payload_len The length of the filed payload for current packet. - * \param len Length of the payload array - */ - -void StreamTcpCreateTestPacket(uint8_t *payload, uint8_t value, - uint8_t payload_len, uint8_t len) -{ - uint8_t i; - for (i = 0; i < payload_len; i++) - payload[i] = value; - for (; i < len; i++) - payload = NULL; -} - -/** \brief The Function Checks the reassembled stream contents against predefined - * stream contents according to OS policy used. - * - * \param stream_policy Predefined value of stream for different OS policies - * \param stream Reassembled stream returned from the reassembly functions - */ - -int StreamTcpCheckStreamContents(uint8_t *stream_policy, uint16_t sp_size, TcpStream *stream) -{ - TcpSegment *temp; - uint16_t i = 0; - uint8_t j; - -#ifdef DEBUG - if (SCLogDebugEnabled()) { - TcpSegment *temp1; - for (temp1 = stream->seg_list; temp1 != NULL; temp1 = temp1->next) - PrintRawDataFp(stdout, temp1->payload, temp1->payload_len); - - PrintRawDataFp(stdout, stream_policy, sp_size); - } -#endif - - for (temp = stream->seg_list; temp != NULL; temp = temp->next) { - j = 0; - for (; j < temp->payload_len; j++) { - SCLogDebug("i %"PRIu16", len %"PRIu32", stream %"PRIx32" and temp is %"PRIx8"", - i, temp->payload_len, stream_policy[i], temp->payload[j]); - - if (stream_policy[i] == temp->payload[j]) { - i++; - continue; - } else - return 0; - } - } - return 1; -} - -/** \brief The Function Checks the Stream Queue contents against predefined - * stream contents. - * - * \param stream_contents Predefined value of stream contents - * \param stream Queue which has the stream contents - * - * \retval On success the function returns 1, on failure 0. - */ -static int StreamTcpCheckChunks (TcpSession *ssn, uint8_t *stream_contents) -{ - SCEnter(); - - StreamMsg *msg; - uint16_t i = 0; - uint8_t j; - uint8_t cnt = 0; - - if (ssn == NULL) { - printf("ssn == NULL, "); - SCReturnInt(0); - } - - if (ssn->toserver_smsg_head == NULL) { - printf("ssn->toserver_smsg_head == NULL, "); - SCReturnInt(0); - } - - msg = ssn->toserver_smsg_head; - while(msg != NULL) { - cnt++; - j = 0; - for (; j < msg->data_len; j++) { - SCLogDebug("i is %" PRIu32 " and len is %" PRIu32 " and temp is %" PRIx32 "", i, msg->data_len, msg->data[j]); - - if (stream_contents[i] == msg->data[j]) { - i++; - continue; - } else { - SCReturnInt(0); - } - } - msg = msg->next; - } - SCReturnInt(1); -} - -/* \brief The function craft packets to test the overlapping, where - * new segment stats before the list segment. - * - * \param stream The stream which will contain the reassembled segments and - * also tells the OS policy used for reassembling the segments. - */ - -static int StreamTcpTestStartsBeforeListSegment(TcpStream *stream) { - TcpSession ssn; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 1, 4); /*B*/ - p->tcph->th_seq = htonl(16); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x44, 1, 4); /*D*/ - p->tcph->th_seq = htonl(22); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x45, 2, 4); /*EE*/ - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x41, 2, 4); /*AA*/ - p->tcph->th_seq = htonl(15); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4a, 4, 4); /*JJJJ*/ - p->tcph->th_seq = htonl(14); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 4; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - SCLogDebug("sending segment with SEQ 21, len 3"); - StreamTcpCreateTestPacket(payload, 0x4c, 3, 4); /*LLL*/ - p->tcph->th_seq = htonl(21); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4d, 3, 4); /*MMM*/ - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - SCFree(p); - return 1; -} - -/* \brief The function craft packets to test the overlapping, where - * new segment stats at the same seq no. as the list segment. - * - * \param stream The stream which will contain the reassembled segments and - * also tells the OS policy used for reassembling the segments. - */ - -static int StreamTcpTestStartsAtSameListSegment(TcpStream *stream) -{ - TcpSession ssn; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, 4); /*CCC*/ - p->tcph->th_seq = htonl(18); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x48, 2, 4); /*HH*/ - p->tcph->th_seq = htonl(32); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x49, 1, 4); /*I*/ - p->tcph->th_seq = htonl(34); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4b, 3, 4); /*KKK*/ - p->tcph->th_seq = htonl(18); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4c, 4, 4); /*LLLL*/ - p->tcph->th_seq = htonl(18); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 4; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x50, 1, 4); /*P*/ - p->tcph->th_seq = htonl(32); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x51, 2, 4); /*QQ*/ - p->tcph->th_seq = htonl(34); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - SCFree(p); - return 1; -} - -/* \brief The function craft packets to test the overlapping, where - * new segment stats after the list segment. - * - * \param stream The stream which will contain the reassembled segments and - * also tells the OS policy used for reassembling the segments. - */ - - -static int StreamTcpTestStartsAfterListSegment(TcpStream *stream) -{ - TcpSession ssn; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 2, 4); /*AA*/ - p->tcph->th_seq = htonl(12); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x46, 3, 4); /*FFF*/ - p->tcph->th_seq = htonl(27); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 3; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x47, 2, 4); /*GG*/ - p->tcph->th_seq = htonl(30); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4a, 2, 4); /*JJ*/ - p->tcph->th_seq = htonl(13); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 2; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4f, 1, 4); /*O*/ - p->tcph->th_seq = htonl(31); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpCreateTestPacket(payload, 0x4e, 1, 4); /*N*/ - p->tcph->th_seq = htonl(28); - p->tcph->th_ack = htonl(31); - p->payload = payload; - p->payload_len = 1; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - SCFree(p); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * before the list segment and BSD policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest01(void) -{ - TcpStream stream; - uint8_t stream_before_bsd[10] = {0x4a, 0x4a, 0x4a, 0x4a, 0x4c, 0x4c, - 0x4c, 0x4d, 0x4d, 0x4d}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpTestStartsBeforeListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_before_bsd,sizeof(stream_before_bsd), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * at the same seq no. as the list segment and BSD policy is used - * to reassemble segments. - */ - -static int StreamTcpReassembleTest02(void) -{ - TcpStream stream; - uint8_t stream_same_bsd[8] = {0x43, 0x43, 0x43, 0x4c, 0x48, 0x48, - 0x49, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpTestStartsAtSameListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_same_bsd, sizeof(stream_same_bsd), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * after the list segment and BSD policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest03(void) -{ - TcpStream stream; - uint8_t stream_after_bsd[8] = {0x41, 0x41, 0x4a, 0x46, 0x46, 0x46, - 0x47, 0x47}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpTestStartsAfterListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_after_bsd, sizeof(stream_after_bsd), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly engine for all the case - * before, same and after overlapping and BSD policy is used to - * reassemble segments. - */ - -static int StreamTcpReassembleTest04(void) -{ - TcpStream stream; - uint8_t stream_bsd[25] = {0x30, 0x41, 0x41, 0x41, 0x4a, 0x4a, 0x42, 0x43, - 0x43, 0x43, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, - 0x46, 0x46, 0x46, 0x47, 0x47, 0x48, 0x48, 0x49, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; - StreamTcpInitConfig(TRUE); - if (StreamTcpReassembleStreamTest(&stream) == 0) { - printf("failed in segments reassembly: "); - return 0; - } - if (StreamTcpCheckStreamContents(stream_bsd, sizeof(stream_bsd), &stream) == 0) { - printf("failed in stream matching: "); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * before the list segment and VISTA policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest05(void) -{ - TcpStream stream; - uint8_t stream_before_vista[10] = {0x4a, 0x41, 0x42, 0x4a, 0x4c, 0x44, - 0x4c, 0x4d, 0x45, 0x45}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_VISTA; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsBeforeListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_before_vista, sizeof(stream_before_vista), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * at the same seq no. as the list segment and VISTA policy is used - * to reassemble segments. - */ - -static int StreamTcpReassembleTest06(void) -{ - TcpStream stream; - uint8_t stream_same_vista[8] = {0x43, 0x43, 0x43, 0x4c, 0x48, 0x48, - 0x49, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_VISTA; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpTestStartsAtSameListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_same_vista, sizeof(stream_same_vista), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * after the list segment and BSD policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest07(void) -{ - TcpStream stream; - uint8_t stream_after_vista[8] = {0x41, 0x41, 0x4a, 0x46, 0x46, 0x46, - 0x47, 0x47}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_VISTA; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpTestStartsAfterListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_after_vista, sizeof(stream_after_vista), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly engine for all the case - * before, same and after overlapping and VISTA policy is used to - * reassemble segments. - */ - -static int StreamTcpReassembleTest08(void) -{ - TcpStream stream; - uint8_t stream_vista[25] = {0x30, 0x41, 0x41, 0x41, 0x4a, 0x42, 0x42, 0x43, - 0x43, 0x43, 0x4c, 0x44, 0x4c, 0x4d, 0x45, 0x45, - 0x46, 0x46, 0x46, 0x47, 0x47, 0x48, 0x48, 0x49, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_VISTA; - StreamTcpInitConfig(TRUE); - if (StreamTcpReassembleStreamTest(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_vista, sizeof(stream_vista), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * before the list segment and LINUX policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest09(void) -{ - TcpStream stream; - uint8_t stream_before_linux[10] = {0x4a, 0x4a, 0x4a, 0x4a, 0x4c, 0x4c, - 0x4c, 0x4d, 0x4d, 0x4d}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_LINUX; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsBeforeListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_before_linux, sizeof(stream_before_linux), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * at the same seq no. as the list segment and LINUX policy is used - * to reassemble segments. - */ - -static int StreamTcpReassembleTest10(void) -{ - TcpStream stream; - uint8_t stream_same_linux[8] = {0x4c, 0x4c, 0x4c, 0x4c, 0x48, 0x48, - 0x51, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_LINUX; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsAtSameListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_same_linux, sizeof(stream_same_linux), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * after the list segment and LINUX policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest11(void) -{ - TcpStream stream; - uint8_t stream_after_linux[8] = {0x41, 0x41, 0x4a, 0x46, 0x46, 0x46, - 0x47, 0x47}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_LINUX; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsAfterListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_after_linux, sizeof(stream_after_linux), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly engine for all the case - * before, same and after overlapping and LINUX policy is used to - * reassemble segments. - */ - -static int StreamTcpReassembleTest12(void) -{ - TcpStream stream; - uint8_t stream_linux[25] = {0x30, 0x41, 0x41, 0x41, 0x4a, 0x4a, 0x42, 0x43, - 0x43, 0x43, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, - 0x46, 0x46, 0x46, 0x47, 0x47, 0x48, 0x48, 0x51, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_LINUX; - StreamTcpInitConfig(TRUE); - if (StreamTcpReassembleStreamTest(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_linux, sizeof(stream_linux), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * before the list segment and OLD_LINUX policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest13(void) -{ - TcpStream stream; - uint8_t stream_before_old_linux[10] = {0x4a, 0x4a, 0x4a, 0x4a, 0x4c, 0x4c, - 0x4c, 0x4d, 0x4d, 0x4d}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_OLD_LINUX; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsBeforeListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_before_old_linux, sizeof(stream_before_old_linux), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * at the same seq no. as the list segment and OLD_LINUX policy is - * used to reassemble segments. - */ - -static int StreamTcpReassembleTest14(void) -{ - TcpStream stream; - uint8_t stream_same_old_linux[8] = {0x4c, 0x4c, 0x4c, 0x4c, 0x48, 0x48, - 0x51, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_OLD_LINUX; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsAtSameListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_same_old_linux, sizeof(stream_same_old_linux), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * after the list segment and OLD_LINUX policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest15(void) -{ - TcpStream stream; - uint8_t stream_after_old_linux[8] = {0x41, 0x41, 0x4a, 0x46, 0x46, 0x46, - 0x47, 0x47}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_OLD_LINUX; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsAfterListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_after_old_linux, sizeof(stream_after_old_linux), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly engine for all the case - * before, same and after overlapping and OLD_LINUX policy is used to - * reassemble segments. - */ - -static int StreamTcpReassembleTest16(void) -{ - TcpStream stream; - uint8_t stream_old_linux[25] = {0x30, 0x41, 0x41, 0x41, 0x4a, 0x4a, 0x42, 0x4b, - 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, - 0x46, 0x46, 0x46, 0x47, 0x47, 0x48, 0x48, 0x51, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_OLD_LINUX; - StreamTcpInitConfig(TRUE); - if (StreamTcpReassembleStreamTest(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_old_linux, sizeof(stream_old_linux), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * before the list segment and SOLARIS policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest17(void) -{ - TcpStream stream; - uint8_t stream_before_solaris[10] = {0x4a, 0x4a, 0x4a, 0x4a, 0x4c, 0x4c, - 0x4c, 0x4d, 0x4d, 0x4d}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_SOLARIS; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsBeforeListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_before_solaris, sizeof(stream_before_solaris), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * at the same seq no. as the list segment and SOLARIS policy is used - * to reassemble segments. - */ - -static int StreamTcpReassembleTest18(void) -{ - TcpStream stream; - uint8_t stream_same_solaris[8] = {0x4c, 0x4c, 0x4c, 0x4c, 0x48, 0x48, - 0x51, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_SOLARIS; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsAtSameListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_same_solaris, sizeof(stream_same_solaris), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * after the list segment and SOLARIS policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest19(void) -{ - TcpStream stream; - uint8_t stream_after_solaris[8] = {0x41, 0x4a, 0x4a, 0x46, 0x46, 0x46, - 0x47, 0x47}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_SOLARIS; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsAfterListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - StreamTcpFreeConfig(TRUE); - return 0; - } - if (StreamTcpCheckStreamContents(stream_after_solaris, sizeof(stream_after_solaris), &stream) == 0) { - printf("failed in stream matching!!\n"); - StreamTcpFreeConfig(TRUE); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly engine for all the case - * before, same and after overlapping and SOLARIS policy is used to - * reassemble segments. - */ - -static int StreamTcpReassembleTest20(void) -{ - TcpStream stream; - uint8_t stream_solaris[25] = {0x30, 0x41, 0x4a, 0x4a, 0x4a, 0x42, 0x42, 0x4b, - 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, - 0x46, 0x46, 0x46, 0x47, 0x47, 0x48, 0x48, 0x51, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_SOLARIS; - StreamTcpInitConfig(TRUE); - if (StreamTcpReassembleStreamTest(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - StreamTcpFreeConfig(TRUE); - return 0; - } - if (StreamTcpCheckStreamContents(stream_solaris, sizeof(stream_solaris), &stream) == 0) { - printf("failed in stream matching!!\n"); - StreamTcpFreeConfig(TRUE); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * before the list segment and LAST policy is used to reassemble - * segments. - */ - -static int StreamTcpReassembleTest21(void) -{ - TcpStream stream; - uint8_t stream_before_last[10] = {0x4a, 0x4a, 0x4a, 0x4a, 0x4c, 0x4c, - 0x4c, 0x4d, 0x4d, 0x4d}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_LAST; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsBeforeListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_before_last, sizeof(stream_before_last), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * at the same seq no. as the list segment and LAST policy is used - * to reassemble segments. - */ - -static int StreamTcpReassembleTest22(void) -{ - TcpStream stream; - uint8_t stream_same_last[8] = {0x4c, 0x4c, 0x4c, 0x4c, 0x50, 0x48, - 0x51, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_LAST; - StreamTcpInitConfig(TRUE); - if (StreamTcpTestStartsAtSameListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_same_last, sizeof(stream_same_last), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly when new segment starts - * after the list segment and LAST policy is used to reassemble - * segments. - */ -static int StreamTcpReassembleTest23(void) -{ - TcpStream stream; - uint8_t stream_after_last[8] = {0x41, 0x4a, 0x4a, 0x46, 0x4e, 0x46, 0x47, 0x4f}; - memset(&stream, 0, sizeof (TcpStream)); - - stream.os_policy = OS_POLICY_LAST; - StreamTcpInitConfig(TRUE); - - if (StreamTcpTestStartsAfterListSegment(&stream) == 0) { - printf("failed in segments reassembly!!\n"); - return 0; - } - if (StreamTcpCheckStreamContents(stream_after_last, sizeof(stream_after_last), &stream) == 0) { - printf("failed in stream matching!!\n"); - return 0; - } - StreamTcpFreeConfig(TRUE); - return 1; -} - -/** \brief The Function to test the reassembly engine for all the case - * before, same and after overlapping and LAST policy is used to - * reassemble segments. - */ - -static int StreamTcpReassembleTest24(void) -{ - int ret = 0; - TcpStream stream; - uint8_t stream_last[25] = {0x30, 0x41, 0x4a, 0x4a, 0x4a, 0x4a, 0x42, 0x4b, - 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, - 0x46, 0x4e, 0x46, 0x47, 0x4f, 0x50, 0x48, 0x51, 0x51}; - memset(&stream, 0, sizeof (TcpStream)); - - stream.os_policy = OS_POLICY_LAST; - StreamTcpInitConfig(TRUE); - - if (StreamTcpReassembleStreamTest(&stream) == 0) { - printf("failed in segments reassembly: "); - goto end; - } - if (StreamTcpCheckStreamContents(stream_last, sizeof(stream_last), &stream) == 0) { - printf("failed in stream matching: "); - goto end; - } - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** \brief The Function to test the missed packets handling with given payload, - * which is used to test the reassembly of the engine. - * - * \param stream Stream which contain the packets - * \param seq Sequence number of the packet - * \param ack Acknowledgment number of the packet - * \param payload The variable used to store the payload contents of the - * current packet. - * \param len The length of the payload for current packet. - * \param th_flag The TCP flags - * \param flowflags The packet flow direction - * \param state The TCP session state - * - * \retval On success it returns 0 and on failure it return -1. - */ - -static int StreamTcpTestMissedPacket (TcpReassemblyThreadCtx *ra_ctx, - TcpSession *ssn, uint32_t seq, uint32_t ack, uint8_t *payload, - uint16_t len, uint8_t th_flags, uint8_t flowflags, uint8_t state) -{ - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return -1; - Flow f; - TCPHdr tcph; - Port sp; - Port dp; - struct in_addr in; - ThreadVars tv; - PacketQueue pq; - - memset(&pq,0,sizeof(PacketQueue)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&tv, 0, sizeof (ThreadVars)); - - sp = 200; - dp = 220; - - FLOW_INITIALIZE(&f); - if (inet_pton(AF_INET, "1.2.3.4", &in) != 1) { - SCFree(p); - return -1; - } - f.src.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.5", &in) != 1) { - SCFree(p); - return -1; - } - f.dst.addr_data32[0] = in.s_addr; - f.flags |= FLOW_IPV4; - f.sp = sp; - f.dp = dp; - f.protoctx = ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(seq); - tcph.th_ack = htonl(ack); - tcph.th_flags = th_flags; - p->tcph = &tcph; - p->flowflags = flowflags; - - p->payload = payload; - p->payload_len = len; - ssn->state = state; - - TcpStream *s = NULL; - if (flowflags & FLOW_PKT_TOSERVER) { - s = &ssn->server; - } else { - s = &ssn->client; - } - - SCMutexLock(&f.m); - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, ssn, s, p, &pq) == -1) { - SCMutexUnlock(&f.m); - SCFree(p); - return -1; - } - - SCMutexUnlock(&f.m); - SCFree(p); - return 0; -} - -/** - * \test Test the handling of packets missed by both IDS and the end host. - * The packet is missed in the starting of the stream. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest25 (void) -{ - int ret = 0; - uint8_t payload[4]; - uint32_t seq; - uint32_t ack; - TcpSession ssn; - uint8_t th_flag; - uint8_t flowflags; - uint8_t check_contents[7] = {0x41, 0x41, 0x41, 0x42, 0x42, 0x43, 0x43}; - - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - memset(&ssn, 0, sizeof (TcpSession)); - - flowflags = FLOW_PKT_TOSERVER; - th_flag = TH_ACK|TH_PUSH; - ack = 20; - StreamTcpInitConfig(TRUE); - - StreamTcpCreateTestPacket(payload, 0x42, 2, 4); /*BB*/ - seq = 10; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - StreamTcpCreateTestPacket(payload, 0x43, 2, 4); /*CC*/ - seq = 12; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - ssn.server.next_seq = 14; - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - seq = 7; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 3, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - if (StreamTcpCheckStreamContents(check_contents, sizeof(check_contents), &ssn.server) == 0) { - printf("failed in stream matching: "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test the handling of packets missed by both IDS and the end host. - * The packet is missed in the middle of the stream. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest26 (void) -{ - int ret = 0; - uint8_t payload[4]; - uint32_t seq; - uint32_t ack; - TcpSession ssn; - uint8_t th_flag; - uint8_t flowflags; - uint8_t check_contents[7] = {0x41, 0x41, 0x41, 0x42, 0x42, 0x43, 0x43}; - memset(&ssn, 0, sizeof (TcpSession)); - flowflags = FLOW_PKT_TOSERVER; - th_flag = TH_ACK|TH_PUSH; - ack = 20; - StreamTcpInitConfig(TRUE); - - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - seq = 10; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 3, th_flag, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - StreamTcpCreateTestPacket(payload, 0x43, 2, 4); /*CC*/ - seq = 15; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - StreamTcpCreateTestPacket(payload, 0x42, 2, 4); /*BB*/ - seq = 13; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - if (StreamTcpCheckStreamContents(check_contents, sizeof(check_contents), &ssn.server) == 0) { - printf("failed in stream matching: "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test the handling of packets missed by both IDS and the end host. - * The packet is missed in the end of the stream. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest27 (void) -{ - int ret = 0; - uint8_t payload[4]; - uint32_t seq; - uint32_t ack; - TcpSession ssn; - uint8_t th_flag; - uint8_t flowflags; - uint8_t check_contents[7] = {0x41, 0x41, 0x41, 0x42, 0x42, 0x43, 0x43}; - memset(&ssn, 0, sizeof (TcpSession)); - flowflags = FLOW_PKT_TOSERVER; - th_flag = TH_ACK|TH_PUSH; - ack = 20; - StreamTcpInitConfig(TRUE); - - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - seq = 10; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 3, th_flag, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - StreamTcpCreateTestPacket(payload, 0x42, 2, 4); /*BB*/ - seq = 13; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - StreamTcpCreateTestPacket(payload, 0x43, 2, 4); /*CC*/ - seq = 15; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - if (StreamTcpCheckStreamContents(check_contents, sizeof(check_contents), &ssn.server) == 0) { - printf("failed in stream matching: "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test the handling of packets missed by IDS, but the end host has - * received it and send the acknowledgment of it. The packet is missed - * in the starting of the stream. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest28 (void) -{ - int ret = 0; - uint8_t payload[4]; - uint32_t seq; - uint32_t ack; - uint8_t th_flag; - uint8_t th_flags; - uint8_t flowflags; - uint8_t check_contents[5] = {0x41, 0x41, 0x42, 0x42, 0x42}; - TcpSession ssn; - memset(&ssn, 0, sizeof (TcpSession)); - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - StreamTcpInitConfig(TRUE); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - flowflags = FLOW_PKT_TOSERVER; - th_flag = TH_ACK|TH_PUSH; - th_flags = TH_ACK; - - ssn.server.last_ack = 22; - ssn.server.ra_raw_base_seq = ssn.server.ra_app_base_seq = 6; - ssn.server.isn = 6; - - StreamTcpCreateTestPacket(payload, 0x41, 2, 4); /*AA*/ - seq = 10; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly (1): "); - goto end; - } - - flowflags = FLOW_PKT_TOCLIENT; - StreamTcpCreateTestPacket(payload, 0x00, 0, 4); - seq = 20; - ack = 12; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 0, th_flags, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly (2): "); - goto end; - } - - flowflags = FLOW_PKT_TOSERVER; - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - seq = 12; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 3, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly (4): "); - goto end; - } - - flowflags = FLOW_PKT_TOCLIENT; - StreamTcpCreateTestPacket(payload, 0x00, 0, 4); - seq = 20; - ack = 15; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 0, th_flags, flowflags, TCP_TIME_WAIT) == -1) { - printf("failed in segments reassembly (5): "); - goto end; - } - - if (StreamTcpCheckChunks(&ssn, check_contents) == 0) { - printf("failed in stream matching (6): "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test the handling of packets missed by IDS, but the end host has - * received it and send the acknowledgment of it. The packet is missed - * in the middle of the stream. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest29 (void) -{ - int ret = 0; - uint8_t payload[4]; - uint32_t seq; - uint32_t ack; - uint8_t th_flag; - uint8_t th_flags; - uint8_t flowflags; - uint8_t check_contents[5] = {0x41, 0x41, 0x42, 0x42, 0x42}; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - TcpSession ssn; - memset(&ssn, 0, sizeof (TcpSession)); - - flowflags = FLOW_PKT_TOSERVER; - th_flag = TH_ACK|TH_PUSH; - th_flags = TH_ACK; - - ssn.server.last_ack = 22; - ssn.server.ra_raw_base_seq = 9; - ssn.server.isn = 9; - StreamTcpInitConfig(TRUE); - - StreamTcpCreateTestPacket(payload, 0x41, 2, 4); /*AA*/ - seq = 10; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOCLIENT; - StreamTcpCreateTestPacket(payload, 0x00, 0, 4); - seq = 20; - ack = 15; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 0, th_flags, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOSERVER; - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - seq = 15; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 3, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOCLIENT; - StreamTcpCreateTestPacket(payload, 0x00, 0, 4); - seq = 20; - ack = 18; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 0, th_flags, flowflags, TCP_TIME_WAIT) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - if (StreamTcpCheckChunks(&ssn, check_contents) == 0) { - printf("failed in stream matching: "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test the handling of packets missed by IDS, but the end host has - * received it and send the acknowledgment of it. The packet is missed - * at the end of the stream. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest30 (void) -{ - int ret = 0; - uint8_t payload[4]; - uint32_t seq; - uint32_t ack; - uint8_t th_flag; - uint8_t th_flags; - uint8_t flowflags; - uint8_t check_contents[6] = {0x41, 0x41, 0x42, 0x42, 0x42, 0x00}; - TcpSession ssn; - memset(&ssn, 0, sizeof (TcpSession)); - - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - flowflags = FLOW_PKT_TOSERVER; - th_flag = TH_ACK|TH_PUSH; - th_flags = TH_ACK; - - ssn.client.last_ack = 2; - ssn.client.isn = 1; - - ssn.server.last_ack = 22; - ssn.server.ra_raw_base_seq = ssn.server.ra_app_base_seq = 9; - ssn.server.isn = 9; - - StreamTcpInitConfig(TRUE); - StreamTcpCreateTestPacket(payload, 0x41, 2, 4); /*AA*/ - seq = 10; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOCLIENT; - StreamTcpCreateTestPacket(payload, 0x00, 0, 4); - seq = 20; - ack = 12; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 0, th_flags, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOSERVER; - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - seq = 12; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 3, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOCLIENT; - StreamTcpCreateTestPacket(payload, 0x00, 0, 4); - seq = 20; - ack = 18; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 0, th_flags, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - th_flag = TH_FIN|TH_ACK; - seq = 18; - ack = 20; - flowflags = FLOW_PKT_TOSERVER; - StreamTcpCreateTestPacket(payload, 0x00, 1, 4); - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 1, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOCLIENT; - StreamTcpCreateTestPacket(payload, 0x00, 0, 4); - seq = 20; - ack = 18; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 0, th_flag, flowflags, TCP_TIME_WAIT) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - if (StreamTcpCheckChunks(&ssn, check_contents) == 0) { - printf("failed in stream matching: "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test to reassemble the packets using the fast track method, as most - * packets arrives in order. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest31 (void) -{ - int ret = 0; - uint8_t payload[4]; - uint32_t seq; - uint32_t ack; - uint8_t th_flag; - uint8_t flowflags; - uint8_t check_contents[5] = {0x41, 0x41, 0x42, 0x42, 0x42}; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - TcpSession ssn; - memset(&ssn, 0, sizeof (TcpSession)); - - flowflags = FLOW_PKT_TOSERVER; - th_flag = TH_ACK|TH_PUSH; - - ssn.server.ra_raw_base_seq = 9; - ssn.server.isn = 9; - StreamTcpInitConfig(TRUE); - - StreamTcpCreateTestPacket(payload, 0x41, 2, 4); /*AA*/ - seq = 10; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1){ - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOSERVER; - StreamTcpCreateTestPacket(payload, 0x42, 1, 4); /*B*/ - seq = 15; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 1, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOSERVER; - StreamTcpCreateTestPacket(payload, 0x42, 1, 4); /*B*/ - seq = 12; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 1, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - flowflags = FLOW_PKT_TOSERVER; - StreamTcpCreateTestPacket(payload, 0x42, 1, 4); /*B*/ - seq = 16; - ack = 20; - if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 1, th_flag, flowflags, TCP_ESTABLISHED) == -1) { - printf("failed in segments reassembly: "); - goto end; - } - - if (StreamTcpCheckStreamContents(check_contents, 5, &ssn.server) == 0) { - printf("failed in stream matching: "); - goto end; - } - - if (ssn.server.seg_list_tail->seq != 16) { - printf("failed in fast track handling: "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -static int StreamTcpReassembleTest32(void) -{ - TcpSession ssn; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - TcpStream stream; - uint8_t ret = 0; - uint8_t check_contents[35] = {0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, - 0x43, 0x43, 0x43}; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; - uint8_t payload[20] = ""; - - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - p->tcph->th_seq = htonl(10); - p->tcph->th_ack = htonl(31); - p->payload_len = 10; - StreamTcpCreateTestPacket(payload, 0x41, 10, 20); /*AA*/ - p->payload = payload; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(31); - p->payload_len = 10; - StreamTcpCreateTestPacket(payload, 0x42, 10, 20); /*BB*/ - p->payload = payload; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(40); - p->tcph->th_ack = htonl(31); - p->payload_len = 10; - StreamTcpCreateTestPacket(payload, 0x43, 10, 20); /*CC*/ - p->payload = payload; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(5); - p->tcph->th_ack = htonl(31); - p->payload_len = 20; - StreamTcpCreateTestPacket(payload, 0x41, 20, 20); /*AA*/ - p->payload = payload; - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) - goto end; - - if (StreamTcpCheckStreamContents(check_contents, 35, &stream) != 0) { - ret = 1; - } else { - printf("failed in stream matching: "); - } - - -end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - return ret; -} - -static int StreamTcpReassembleTest33(void) -{ - TcpSession ssn; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - TcpStream stream; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; - uint8_t packet[1460] = ""; - - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = packet; - - p->tcph->th_seq = htonl(10); - p->tcph->th_ack = htonl(31); - p->payload_len = 10; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(31); - p->payload_len = 10; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(40); - p->tcph->th_ack = htonl(31); - p->payload_len = 10; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(5); - p->tcph->th_ack = htonl(31); - p->payload_len = 30; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpFreeConfig(TRUE); - SCFree(p); - return 1; -} - -static int StreamTcpReassembleTest34(void) -{ - TcpSession ssn; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - TcpStream stream; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; - uint8_t packet[1460] = ""; - - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = packet; - - p->tcph->th_seq = htonl(857961230); - p->tcph->th_ack = htonl(31); - p->payload_len = 304; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(857961534); - p->tcph->th_ack = htonl(31); - p->payload_len = 1460; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(857963582); - p->tcph->th_ack = htonl(31); - p->payload_len = 1460; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(857960946); - p->tcph->th_ack = htonl(31); - p->payload_len = 1460; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpFreeConfig(TRUE); - SCFree(p); - return 1; -} - -/** \test Test the bug 56 condition */ -static int StreamTcpReassembleTest35(void) -{ - TcpSession ssn; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - TcpStream stream; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; - uint8_t packet[1460] = ""; - - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 10); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 10); - - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = packet; - - p->tcph->th_seq = htonl(2257022155UL); - p->tcph->th_ack = htonl(1374943142); - p->payload_len = 142; - stream.last_ack = 2257022285UL; - stream.ra_raw_base_seq = 2257022172UL; - stream.ra_app_base_seq = 2257022172UL; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(2257022285UL); - p->tcph->th_ack = htonl(1374943142); - p->payload_len = 34; - stream.last_ack = 2257022285UL; - stream.ra_raw_base_seq = 2257022172UL; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpFreeConfig(TRUE); - SCFree(p); - return 1; -} - -/** \test Test the bug 57 condition */ -static int StreamTcpReassembleTest36(void) -{ - TcpSession ssn; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - TcpStream stream; - memset(&stream, 0, sizeof (TcpStream)); - stream.os_policy = OS_POLICY_BSD; - uint8_t packet[1460] = ""; - - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 10); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 10); - - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = packet; - - p->tcph->th_seq = htonl(1549588966); - p->tcph->th_ack = htonl(4162241372UL); - p->payload_len = 204; - stream.last_ack = 1549589007; - stream.ra_raw_base_seq = 1549589101; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(1549589007); - p->tcph->th_ack = htonl(4162241372UL); - p->payload_len = 23; - stream.last_ack = 1549589007; - stream.ra_raw_base_seq = 1549589101; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpFreeConfig(TRUE); - SCFree(p); - return 1; -} - -/** \test Test the bug 76 condition */ -static int StreamTcpReassembleTest37(void) -{ - TcpSession ssn; - Flow f; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - TcpStream stream; - uint8_t packet[1460] = ""; - PacketQueue pq; - ThreadVars tv; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 10); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 10); - - memset(&stream, 0, sizeof (TcpStream)); - memset(&pq,0,sizeof(PacketQueue)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&tv, 0, sizeof (ThreadVars)); - - FLOW_INITIALIZE(&f); - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = packet; - stream.os_policy = OS_POLICY_BSD; - - p->tcph->th_seq = htonl(3061088537UL); - p->tcph->th_ack = htonl(1729548549UL); - p->payload_len = 1391; - stream.last_ack = 3061091137UL; - stream.ra_raw_base_seq = 3061091309UL; - stream.ra_app_base_seq = 3061091309UL; - - /* pre base_seq, so should be rejected */ - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) != -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(3061089928UL); - p->tcph->th_ack = htonl(1729548549UL); - p->payload_len = 1391; - stream.last_ack = 3061091137UL; - stream.ra_raw_base_seq = 3061091309UL; - stream.ra_app_base_seq = 3061091309UL; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - p->tcph->th_seq = htonl(3061091319UL); - p->tcph->th_ack = htonl(1729548549UL); - p->payload_len = 1391; - stream.last_ack = 3061091137UL; - stream.ra_raw_base_seq = 3061091309UL; - stream.ra_app_base_seq = 3061091309UL; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &stream, p, &pq) == -1) { - SCFree(p); - return 0; - } - - StreamTcpFreeConfig(TRUE); - SCFree(p); - return 1; -} - -/** - * \test Test to make sure we don't send the smsg from toclient to app layer - * until the app layer protocol has been detected and one smsg from - * toserver side has been sent to app layer. - * - * Unittest modified by commit - - * - * commit bab1636377bb4f1b7b889f4e3fd594795085eaa4 - * Author: Anoop Saldanha - * Date: Fri Feb 15 18:58:33 2013 +0530 - * - * Improved app protocol detection. - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpReassembleTest38 (void) -{ - int ret = 0; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - TCPHdr tcph; - Port sp; - Port dp; - struct in_addr in; - TcpSession ssn; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&ssn, 0, sizeof(TcpSession)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - - StreamTcpInitConfig(TRUE); - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - uint8_t httpbuf2[] = "POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - uint8_t httpbuf1[] = "HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - FLOW_INITIALIZE(&f); - if (inet_pton(AF_INET, "1.2.3.4", &in) != 1) - goto end; - f.src.addr_data32[0] = in.s_addr; - if (inet_pton(AF_INET, "1.2.3.5", &in) != 1) - goto end; - f.dst.addr_data32[0] = in.s_addr; - sp = 200; - dp = 220; - - ssn.server.ra_raw_base_seq = ssn.server.ra_app_base_seq = 9; - ssn.server.isn = 9; - ssn.server.last_ack = 60; - ssn.client.ra_raw_base_seq = ssn.client.ra_app_base_seq = 9; - ssn.client.isn = 9; - ssn.client.last_ack = 9; - f.alproto = ALPROTO_UNKNOWN; - - f.flags |= FLOW_IPV4; - f.sp = sp; - f.dp = dp; - f.protoctx = &ssn; - f.proto = IPPROTO_TCP; - p->flow = &f; - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - p->payload = httpbuf2; - p->payload_len = httplen2; - ssn.state = TCP_ESTABLISHED; - - TcpStream *s = NULL; - s = &ssn.server; - - SCMutexLock(&f.m); - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (1): "); - goto end; - } - - /* Check if we have stream smsgs in queue */ - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) > 0) { - printf("there shouldn't be any stream smsgs in the queue (2): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload = httpbuf1; - p->payload_len = httplen1; - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(55); - s = &ssn.client; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (3): "); - goto end; - } - - /* Check if we have stream smsgs in queue */ - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 1) { - printf("there should one stream smsg in the queue (6): "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - return ret; -} - -/** - * \test Test to make sure that we don't return the segments until the app - * layer proto has been detected and after that remove the processed - * segments. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest39 (void) -{ - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread *stt = NULL; - TCPHdr tcph; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - StreamTcpThreadInit(&tv, NULL, (void **)&stt); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - f.flags = FLOW_IPV4; - f.proto = IPPROTO_TCP; - p->flow = &f; - p->tcph = &tcph; - - SCMutexLock(&f.m); - int ret = 0; - - StreamTcpInitConfig(TRUE); - - /* handshake */ - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - - TcpSession *ssn = (TcpSession *)f.protoctx; - - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list != NULL || - ssn->server.seg_list != NULL || - ssn->toserver_smsg_head != NULL || - ssn->toclient_smsg_head != NULL || - ssn->data_first_seen_dir != 0) { - printf("failure 1\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list != NULL || - ssn->server.seg_list != NULL || - ssn->toserver_smsg_head != NULL || - ssn->toclient_smsg_head != NULL || - ssn->data_first_seen_dir != 0) { - printf("failure 2\n"); - goto end; - } - - /* handshake */ - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list != NULL || - ssn->server.seg_list != NULL || - ssn->toserver_smsg_head != NULL || - ssn->toclient_smsg_head != NULL || - ssn->data_first_seen_dir != 0) { - printf("failure 3\n"); - goto end; - } - - /* partial request */ - uint8_t request1[] = { 0x47, 0x45, }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request1); - p->payload = request1; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next != NULL || - ssn->server.seg_list != NULL || - ssn->toserver_smsg_head != NULL || - ssn->toclient_smsg_head != NULL || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 4\n"); - goto end; - } - - - /* response ack against partial request */ - p->tcph->th_ack = htonl(3); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next != NULL || - ssn->server.seg_list != NULL || - ssn->toserver_smsg_head != NULL || - ssn->toclient_smsg_head != NULL || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 5\n"); - goto end; - } - - /* complete partial request */ - uint8_t request2[] = { - 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, - 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, - 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, - 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, - 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, - 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(3); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request2); - p->payload = request2; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_UNKNOWN || - f.alproto_ts != ALPROTO_UNKNOWN || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next == NULL || - ssn->client.seg_list->next->next != NULL || - ssn->server.seg_list != NULL || - ssn->toserver_smsg_head != NULL || - ssn->toclient_smsg_head != NULL || - ssn->data_first_seen_dir != STREAM_TOSERVER) { - printf("failure 6\n"); - goto end; - } - - /* response - request ack */ - uint8_t response[] = { - 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, - 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, - 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, - 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53, - 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, - 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, - 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, - 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32, - 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, - 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32, - 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a, - 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, - 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31, - 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, - 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, - 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, - 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63, - 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, - 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, - 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, - 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, - 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, - 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58, - 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, - 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77, - 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, - 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, - 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, - 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, - 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, - 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = sizeof(response); - p->payload = response; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_UNKNOWN || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next == NULL || - ssn->client.seg_list->next->next != NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 7\n"); - goto end; - } - - /* response ack from request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next == NULL || - ssn->client.seg_list->next->next != NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 8\n"); - goto end; - } - - /* response - acking */ - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next == NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 9\n"); - goto end; - } - - /* response ack from request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next == NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 10\n"); - goto end; - } - - /* response - acking the request again*/ - p->tcph->th_ack = htonl(88); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next == NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 11\n"); - goto end; - } - - /*** New Request ***/ - - /* partial request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(88); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request1); - p->payload = request1; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next == NULL || - ssn->client.seg_list->next->next == NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 12\n"); - goto end; - } - - - /* response ack against partial request */ - p->tcph->th_ack = htonl(90); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next == NULL || - ssn->client.seg_list->next->next == NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 13\n"); - goto end; - } - - /* complete request */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(90); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = sizeof(request2); - p->payload = request2; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list == NULL || - ssn->client.seg_list->next == NULL || - ssn->client.seg_list->next->next == NULL || - ssn->client.seg_list->next->next->next == NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 14\n"); - goto end; - } - - /* response ack against second partial request */ - p->tcph->th_ack = htonl(175); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list->next == NULL || - ssn->client.seg_list->next->next == NULL || - ssn->client.seg_list->next->next->next == NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 15\n"); - goto end; - } - - if (ssn->toserver_smsg_head == NULL || - ssn->toserver_smsg_head->next == NULL || - ssn->toserver_smsg_head->next->next != NULL || - ssn->toclient_smsg_head == NULL || - ssn->toclient_smsg_head->next != NULL) { - printf("failure 16\n"); - goto end; - } - - StreamMsgReturnListToPool(ssn->toserver_smsg_head); - ssn->toserver_smsg_head = ssn->toserver_smsg_tail = NULL; - StreamMsgReturnListToPool(ssn->toclient_smsg_head); - ssn->toclient_smsg_head = ssn->toclient_smsg_tail = NULL; - - /* response acking a request */ - p->tcph->th_ack = htonl(175); - p->tcph->th_seq = htonl(328); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list != NULL || - ssn->server.seg_list == NULL || - ssn->server.seg_list->next != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 15\n"); - goto end; - } - - /* request acking a response */ - p->tcph->th_ack = htonl(328); - p->tcph->th_seq = htonl(175); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = 0; - p->payload = NULL; - if (StreamTcpPacket(&tv, p, stt, &pq) == -1) - goto end; - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || - !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || - f.alproto != ALPROTO_HTTP || - f.alproto_ts != ALPROTO_HTTP || - f.alproto_tc != ALPROTO_HTTP || - f.data_al_so_far[0] != 0 || - f.data_al_so_far[1] != 0 || - ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || - !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || - !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || - ssn->client.seg_list != NULL || - ssn->server.seg_list != NULL || - ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { - printf("failure 15\n"); - goto end; - } - - - ret = 1; -end: - StreamTcpThreadDeinit(&tv, (void *)stt); - StreamTcpSessionClear(p->flow->protoctx); - StreamTcpFreeConfig(TRUE); - SCFree(p); - SCMutexUnlock(&f.m); - return ret; -} - -/** - * \test Test to make sure that we sent all the segments from the initial - * segments to app layer until we have detected the app layer proto. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest40 (void) -{ - int ret = 0; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow *f = NULL; - TCPHdr tcph; - TcpSession ssn; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&ssn, 0, sizeof(TcpSession)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - - StreamTcpInitConfig(TRUE); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 130); - - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - uint8_t httpbuf1[] = "P"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf3[] = "O"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - uint8_t httpbuf4[] = "S"; - uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */ - uint8_t httpbuf5[] = "T \r\n"; - uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */ - - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - ssn.server.ra_raw_base_seq = ssn.server.ra_app_base_seq = 9; - ssn.server.isn = 9; - ssn.server.last_ack = 10; - ssn.client.ra_raw_base_seq = ssn.client.ra_app_base_seq = 9; - ssn.client.isn = 9; - ssn.client.last_ack = 10; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - p->flow = f; - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(10); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - p->payload = httpbuf1; - p->payload_len = httplen1; - ssn.state = TCP_ESTABLISHED; - - TcpStream *s = NULL; - s = &ssn.client; - - SCMutexLock(&f->m); - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (1): "); - goto end; - } - - /* Check if we have stream smsgs in queue */ - if (UtSsnSmsgCnt(&ssn, STREAM_TOCLIENT) > 0) { - printf("there shouldn't be any stream smsgs in the queue, as we didn't" - " processed any smsg from toserver side till yet (2): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload = httpbuf2; - p->payload_len = httplen2; - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(11); - s = &ssn.server; - ssn.server.last_ack = 11; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (3): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = httpbuf3; - p->payload_len = httplen3; - tcph.th_seq = htonl(11); - tcph.th_ack = htonl(55); - s = &ssn.client; - ssn.client.last_ack = 55; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (5): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload = httpbuf2; - p->payload_len = httplen2; - tcph.th_seq = htonl(55); - tcph.th_ack = htonl(12); - s = &ssn.server; - ssn.server.last_ack = 12; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (6): "); - goto end; - } - - /* check is have the segment in the list and flagged or not */ - if (ssn.client.seg_list == NULL || - (ssn.client.seg_list->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED)) - { - printf("the list is NULL or the processed segment has not been flaged (7): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = httpbuf4; - p->payload_len = httplen4; - tcph.th_seq = htonl(12); - tcph.th_ack = htonl(100); - s = &ssn.client; - ssn.client.last_ack = 100; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (10): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload = httpbuf2; - p->payload_len = httplen2; - tcph.th_seq = htonl(100); - tcph.th_ack = htonl(13); - s = &ssn.server; - ssn.server.last_ack = 13; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (11): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = httpbuf5; - p->payload_len = httplen5; - tcph.th_seq = htonl(13); - tcph.th_ack = htonl(145); - s = &ssn.client; - ssn.client.last_ack = 145; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (14): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload = httpbuf2; - p->payload_len = httplen2; - tcph.th_seq = htonl(145); - tcph.th_ack = htonl(16); - s = &ssn.server; - ssn.server.last_ack = 16; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (15): "); - goto end; - } - - /* Check if we have stream smsgs in queue */ - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) == 0) { - printf("there should be a stream smsgs in the queue, as we have detected" - " the app layer protocol and one smsg from toserver side has " - "been sent (16): "); - goto end; - } - - if (f->alproto != ALPROTO_HTTP) { - printf("app layer proto has not been detected (18): "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - SCFree(p); - SCMutexUnlock(&f->m); - UTHFreeFlow(f); - return ret; -} - -/** - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest43 (void) -{ - int ret = 0; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow *f = NULL; - TCPHdr tcph; - TcpSession ssn; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&ssn, 0, sizeof(TcpSession)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - - StreamTcpInitConfig(TRUE); - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - uint8_t httpbuf1[] = "/ HTTP/1.0\r\nUser-Agent: Victor/1.0"; - - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - - uint8_t httpbuf3[] = "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu" - "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN" - "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N" - "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk" - "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l" - "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN" - "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt" - "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz" - "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw" - "aG9uZT\r\n\r\n"; - uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */ - - ssn.server.ra_raw_base_seq = ssn.server.ra_app_base_seq = 9; - ssn.server.isn = 9; - ssn.server.last_ack = 600; - ssn.client.ra_raw_base_seq = ssn.client.ra_app_base_seq = 9; - ssn.client.isn = 9; - ssn.client.last_ack = 600; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - p->flow = f; - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(10); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOCLIENT; - - p->payload = httpbuf2; - p->payload_len = httplen2; - ssn.state = TCP_ESTABLISHED; - - TcpStream *s = NULL; - s = &ssn.server; - - SCMutexLock(&f->m); - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (1): "); - goto end; - } - - /* Check if we have stream smsgs in queue */ - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) > 0) { - printf("there shouldn't be any stream smsgs in the queue (2): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = httpbuf1; - p->payload_len = httplen1; - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(55); - s = &ssn.client; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (3): "); - goto end; - } - - /* Check if we have stream smsgs in queue */ - if (UtSsnSmsgCnt(&ssn, STREAM_TOCLIENT) > 0) { - printf("there shouldn't be any stream smsgs in the queue, as we didn't" - " processed any smsg from toserver side till yet (4): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload = httpbuf2; - p->payload_len = httplen2; - tcph.th_seq = htonl(55); - tcph.th_ack = htonl(44); - s = &ssn.server; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (5): "); - goto end; - } - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn.client)) { - printf("app layer detected flag isn't set, it should be (8): "); - goto end; - } - - /* This packets induces a packet gap and also shows why we need to - process the current segment completely, even if it results in sending more - than one smsg to the app layer. If we don't send more than one smsg in - this case, then the first segment of lentgh 34 bytes will be sent to - app layer and protocol can not be detected in that message and moreover - the segment lentgh is less than the max. signature size for protocol - detection, so this will keep looping !! */ - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = httpbuf3; - p->payload_len = httplen3; - tcph.th_seq = htonl(54); - tcph.th_ack = htonl(100); - s = &ssn.client; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (9): "); - goto end; - } - - /* Check if we have stream smsgs in queue */ - if (UtSsnSmsgCnt(&ssn, STREAM_TOCLIENT) > 0) { - printf("there shouldn't be any stream smsgs in the queue, as we didn't" - " detected the app layer protocol till yet (10): "); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload = httpbuf2; - p->payload_len = httplen2; - tcph.th_seq = htonl(100); - tcph.th_ack = htonl(53); - s = &ssn.server; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet (11): "); - goto end; - } - /* the flag should be set, as the smsg scanned size has crossed the max. - signature size for app proto detection */ - if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn.client)) { - printf("app layer detected flag is not set, it should be (14): "); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - SCFree(p); - SCMutexUnlock(&f->m); - UTHFreeFlow(f); - return ret; -} - -/** \test Test the memcap incrementing/decrementing and memcap check */ -static int StreamTcpReassembleTest44(void) -{ - uint8_t ret = 0; - StreamTcpInitConfig(TRUE); - uint32_t memuse = SC_ATOMIC_GET(ra_memuse); - - StreamTcpReassembleIncrMemuse(500); - if (SC_ATOMIC_GET(ra_memuse) != (memuse+500)) { - printf("failed in incrementing the memory"); - goto end; - } - - StreamTcpReassembleDecrMemuse(500); - if (SC_ATOMIC_GET(ra_memuse) != memuse) { - printf("failed in decrementing the memory"); - goto end; - } - - if (StreamTcpReassembleCheckMemcap(500) != 1) { - printf("failed in validating the memcap"); - goto end; - } - - if (StreamTcpReassembleCheckMemcap((memuse + stream_config.reassembly_memcap)) != 0) { - printf("failed in validating the memcap"); - goto end; - } - - StreamTcpFreeConfig(TRUE); - - if (SC_ATOMIC_GET(ra_memuse) != 0) { - printf("failed in clearing the memory"); - goto end; - } - - ret = 1; - return ret; -end: - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test to make sure that reassembly_depth is enforced. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest45 (void) -{ - int ret = 0; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow *f = NULL; - TCPHdr tcph; - TcpSession ssn; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&ssn, 0, sizeof(TcpSession)); - ThreadVars tv; - memset(&tv, 0, sizeof (ThreadVars)); - - uint8_t httpbuf1[] = "/ HTTP/1.0\r\nUser-Agent: Victor/1.0"; - - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - StreamTcpInitConfig(TRUE); - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - STREAMTCP_SET_RA_BASE_SEQ(&ssn.server, 9); - ssn.server.isn = 9; - ssn.server.last_ack = 60; - STREAMTCP_SET_RA_BASE_SEQ(&ssn.client, 9); - ssn.client.isn = 9; - ssn.client.last_ack = 9; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - p->flow = f; - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOCLIENT; - - p->payload = httpbuf1; - p->payload_len = httplen1; - ssn.state = TCP_ESTABLISHED; - - /* set the default value of reassembly depth, as there is no config file */ - stream_config.reassembly_depth = httplen1 + 1; - - TcpStream *s = NULL; - s = &ssn.server; - - SCMutexLock(&f->m); - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toclient packet: "); - goto end; - } - - /* Check if we have flags set or not */ - if (s->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) { - printf("there shouldn't be a noreassembly flag be set: "); - goto end; - } - STREAMTCP_SET_RA_BASE_SEQ(&ssn.server, ssn.server.isn + httplen1); - - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = httplen1; - s = &ssn.client; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet: "); - goto end; - } - - /* Check if we have flags set or not */ - if (s->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) { - printf("there shouldn't be a noreassembly flag be set: "); - goto end; - } - STREAMTCP_SET_RA_BASE_SEQ(&ssn.client, ssn.client.isn + httplen1); - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = httplen1; - s = &ssn.server; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet: "); - goto end; - } - - /* Check if we have flags set or not */ - if (!(s->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - printf("the noreassembly flags should be set, " - "p.payload_len %"PRIu16" stream_config.reassembly_" - "depth %"PRIu32": ", p->payload_len, - stream_config.reassembly_depth); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - SCFree(p); - SCMutexUnlock(&f->m); - UTHFreeFlow(f); - return ret; -} - -/** - * \test Test the undefined config value of reassembly depth. - * the default value of 0 will be loaded and stream will be reassembled - * until the session ended - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest46 (void) -{ - int ret = 0; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow *f = NULL; - TCPHdr tcph; - TcpSession ssn; - ThreadVars tv; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&ssn, 0, sizeof(TcpSession)); - memset(&tv, 0, sizeof (ThreadVars)); - - uint8_t httpbuf1[] = "/ HTTP/1.0\r\nUser-Agent: Victor/1.0"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - StreamTcpInitConfig(TRUE); - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - STREAMTCP_SET_RA_BASE_SEQ(&ssn.server, 9); - ssn.server.isn = 9; - ssn.server.last_ack = 60; - ssn.server.next_seq = ssn.server.isn; - STREAMTCP_SET_RA_BASE_SEQ(&ssn.client, 9); - ssn.client.isn = 9; - ssn.client.last_ack = 9; - ssn.client.next_seq = ssn.client.isn; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - p->flow = f; - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOCLIENT; - - p->payload = httpbuf1; - p->payload_len = httplen1; - ssn.state = TCP_ESTABLISHED; - - stream_config.reassembly_depth = 0; - - TcpStream *s = NULL; - s = &ssn.server; - - SCMutexLock(&f->m); - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toclient packet\n"); - goto end; - } - - /* Check if we have flags set or not */ - if ((ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) || - (ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - printf("there shouldn't be any no reassembly flag be set \n"); - goto end; - } - STREAMTCP_SET_RA_BASE_SEQ(&ssn.server, ssn.server.isn + httplen1); - - p->flowflags = FLOW_PKT_TOSERVER; - p->payload_len = httplen1; - s = &ssn.client; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet\n"); - goto end; - } - - /* Check if we have flags set or not */ - if ((ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) || - (ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - printf("there shouldn't be any no reassembly flag be set \n"); - goto end; - } - STREAMTCP_SET_RA_BASE_SEQ(&ssn.client, ssn.client.isn + httplen1); - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload_len = httplen1; - tcph.th_seq = htonl(10 + httplen1); - tcph.th_ack = htonl(20 + httplen1); - s = &ssn.server; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver packet\n"); - goto end; - } - - /* Check if we have flags set or not */ - if ((ssn.client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) || - (ssn.server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) { - printf("the no_reassembly flags should not be set, " - "p->payload_len %"PRIu16" stream_config.reassembly_" - "depth %"PRIu32": ", p->payload_len, - stream_config.reassembly_depth); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - SCFree(p); - SCMutexUnlock(&f->m); - UTHFreeFlow(f); - return ret; -} - -/** - * \test Test to make sure we detect the sequence wrap around and continue - * stream reassembly properly. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpReassembleTest47 (void) -{ - int ret = 0; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return 0; - Flow *f = NULL; - TCPHdr tcph; - TcpSession ssn; - ThreadVars tv; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&ssn, 0, sizeof(TcpSession)); - memset(&tv, 0, sizeof (ThreadVars)); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 0); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 0); - - StreamTcpInitConfig(TRUE); - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - - uint8_t httpbuf1[] = "GET /EVILSUFF HTTP/1.1\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - - ssn.server.ra_raw_base_seq = ssn.server.ra_app_base_seq = 572799781UL; - ssn.server.isn = 572799781UL; - ssn.server.last_ack = 572799782UL; - ssn.client.ra_raw_base_seq = ssn.client.ra_app_base_seq = 4294967289UL; - ssn.client.isn = 4294967289UL; - ssn.client.last_ack = 21; - - f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - p->flow = f; - - tcph.th_win = htons(5480); - ssn.state = TCP_ESTABLISHED; - TcpStream *s = NULL; - uint8_t cnt = 0; - - SCMutexLock(&f->m); - for (cnt=0; cnt < httplen1; cnt++) { - tcph.th_seq = htonl(ssn.client.isn + 1 + cnt); - tcph.th_ack = htonl(572799782UL); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = &httpbuf1[cnt]; - p->payload_len = 1; - s = &ssn.client; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver " - "packet\n"); - goto end; - } - - p->flowflags = FLOW_PKT_TOCLIENT; - p->payload = NULL; - p->payload_len = 0; - tcph.th_seq = htonl(572799782UL); - tcph.th_ack = htonl(ssn.client.isn + 1 + cnt); - tcph.th_flags = TH_ACK; - p->tcph = &tcph; - s = &ssn.server; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) { - printf("failed in segments reassembly, while processing toserver " - "packet\n"); - goto end; - } - } - - if (f->alproto != ALPROTO_HTTP) { - printf("App layer protocol (HTTP) should have been detected\n"); - goto end; - } - - ret = 1; -end: - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - SCFree(p); - SCMutexUnlock(&f->m); - UTHFreeFlow(f); - return ret; -} - -/** \test 3 in order segments in inline reassembly */ -static int StreamTcpReassembleInlineTest01(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - uint8_t stream_payload[] = "AAAAABBBBBCCCCC"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(12); - p->flow = &f; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 12, 'C', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - ssn.client.next_seq = 17; - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 1) { - printf("expected a single stream message: "); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload, 15) == 0) - goto end; - - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test 3 in order segments, then reassemble, add one more and reassemble again. - * test the sliding window reassembly. - */ -static int StreamTcpReassembleInlineTest02(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - uint8_t stream_payload1[] = "AAAAABBBBBCCCCC"; - uint8_t stream_payload2[] = "AAAAABBBBBCCCCCDDDDD"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(12); - p->flow = &f; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 12, 'C', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - ssn.client.next_seq = 17; - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 1) { - printf("expected a single stream message: "); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload1, 15) == 0) - goto end; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 17, 'D', 5) == -1) { - printf("failed to add segment 4: "); - goto end; - } - ssn.client.next_seq = 22; - - r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed 2: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 2) { - printf("expected a single stream message: "); - goto end; - } - - smsg = ssn.toserver_smsg_head->next; - if (UtTestSmsg(smsg, stream_payload2, 20) == 0) - goto end; - - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test 3 in order segments, then reassemble, add one more and reassemble again. - * test the sliding window reassembly with a small window size so that we - * cutting off at the start (left edge) - */ -static int StreamTcpReassembleInlineTest03(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - stream_config.reassembly_toserver_chunk_size = 15; - - uint8_t stream_payload1[] = "AAAAABBBBBCCCCC"; - uint8_t stream_payload2[] = "BBBBBCCCCCDDDDD"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(12); - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 12, 'C', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - ssn.client.next_seq = 17; - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 1) { - printf("expected a single stream message 1: "); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload1, 15) == 0) - goto end; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 17, 'D', 5) == -1) { - printf("failed to add segment 4: "); - goto end; - } - ssn.client.next_seq = 22; - - p->tcph->th_seq = htonl(17); - - r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed 2: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 2) { - printf("expected two stream messages: "); - goto end; - } - - smsg = ssn.toserver_smsg_head->next; - if (UtTestSmsg(smsg, stream_payload2, 15) == 0) - goto end; - - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test 3 in order segments, then reassemble, add one more and reassemble again. - * test the sliding window reassembly with a small window size so that we - * cutting off at the start (left edge) with small packet overlap. - */ -static int StreamTcpReassembleInlineTest04(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - stream_config.reassembly_toserver_chunk_size = 16; - - uint8_t stream_payload1[] = "AAAAABBBBBCCCCC"; - uint8_t stream_payload2[] = "ABBBBBCCCCCDDDDD"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(12); - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 12, 'C', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - ssn.client.next_seq = 17; - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 1) { - printf("expected a single stream message: "); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload1, 15) == 0) - goto end; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 17, 'D', 5) == -1) { - printf("failed to add segment 4: "); - goto end; - } - ssn.client.next_seq = 22; - - p->tcph->th_seq = htonl(17); - - r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed 2: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 2) { - printf("expected a single stream message: "); - goto end; - } - - smsg = ssn.toserver_smsg_head->next; - if (UtTestSmsg(smsg, stream_payload2, 16) == 0) - goto end; - - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test with a GAP we should have 2 smsgs */ -static int StreamTcpReassembleInlineTest05(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - uint8_t stream_payload1[] = "AAAAABBBBB"; - uint8_t stream_payload2[] = "DDDDD"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(12); - p->flow = &f; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - ssn.client.next_seq = 12; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 17, 'D', 5) == -1) { - printf("failed to add segment 4: "); - goto end; - } - - p->tcph->th_seq = htonl(17); - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 2) { - printf("expected a single stream message: "); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload1, 10) == 0) - goto end; - - smsg = ssn.toserver_smsg_head->next; - if (UtTestSmsg(smsg, stream_payload2, 5) == 0) - goto end; - - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test with a GAP we should have 2 smsgs, with filling the GAP later */ -static int StreamTcpReassembleInlineTest06(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - uint8_t stream_payload1[] = "AAAAABBBBB"; - uint8_t stream_payload2[] = "DDDDD"; - uint8_t stream_payload3[] = "AAAAABBBBBCCCCCDDDDD"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(12); - p->flow = &f; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - ssn.client.next_seq = 12; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 17, 'D', 5) == -1) { - printf("failed to add segment 4: "); - goto end; - } - - p->tcph->th_seq = htonl(17); - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 2) { - printf("expected two stream messages: "); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload1, 10) == 0) - goto end; - - smsg = ssn.toserver_smsg_head->next; - if (UtTestSmsg(smsg, stream_payload2, 5) == 0) - goto end; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 12, 'C', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - ssn.client.next_seq = 22; - - p->tcph->th_seq = htonl(12); - - r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 3) { - printf("expected a single stream message, got %u: ", UtSsnSmsgCnt(&ssn, STREAM_TOSERVER)); - goto end; - } - - smsg = ssn.toserver_smsg_head->next->next; - if (UtTestSmsg(smsg, stream_payload3, 20) == 0) - goto end; - - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test with a GAP we should have 2 smsgs, with filling the GAP later, small - * window */ -static int StreamTcpReassembleInlineTest07(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - stream_config.reassembly_toserver_chunk_size = 16; - - uint8_t stream_payload1[] = "ABBBBB"; - uint8_t stream_payload2[] = "DDDDD"; - uint8_t stream_payload3[] = "AAAAABBBBBCCCCCD"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(12); - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - ssn.client.next_seq = 12; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 17, 'D', 5) == -1) { - printf("failed to add segment 4: "); - goto end; - } - - p->tcph->th_seq = htonl(17); - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 2) { - printf("expected a single stream message, got %u: ", UtSsnSmsgCnt(&ssn, STREAM_TOSERVER)); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload1, 6) == 0) - goto end; - - smsg = ssn.toserver_smsg_head->next; - if (UtTestSmsg(smsg, stream_payload2, 5) == 0) - goto end; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 12, 'C', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - ssn.client.next_seq = 22; - - p->tcph->th_seq = htonl(12); - - r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 3) { - printf("expected a single stream message, got %u: ", UtSsnSmsgCnt(&ssn, STREAM_TOSERVER)); - goto end; - } - - smsg = ssn.toserver_smsg_head->next->next; - if (UtTestSmsg(smsg, stream_payload3, 16) == 0) - goto end; - - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test 3 in order segments, then reassemble, add one more and reassemble again. - * test the sliding window reassembly with a small window size so that we - * cutting off at the start (left edge). Test if the first segment is - * removed from the list. - */ -static int StreamTcpReassembleInlineTest08(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - stream_config.reassembly_toserver_chunk_size = 15; - ssn.client.flags |= STREAMTCP_STREAM_FLAG_GAP; - - uint8_t stream_payload1[] = "AAAAABBBBBCCCCC"; - uint8_t stream_payload2[] = "BBBBBCCCCCDDDDD"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(12); - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 12, 'C', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - ssn.client.next_seq = 17; - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 1) { - printf("expected a single stream message: "); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload1, 15) == 0) - goto end; - - if (ssn.client.ra_raw_base_seq != 16) { - printf("ra_raw_base_seq %"PRIu32", expected 16: ", ssn.client.ra_raw_base_seq); - goto end; - } - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 17, 'D', 5) == -1) { - printf("failed to add segment 4: "); - goto end; - } - ssn.client.next_seq = 22; - - p->tcph->th_seq = htonl(17); - - r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed 2: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 2) { - printf("expected a single stream message, got %u: ", UtSsnSmsgCnt(&ssn, STREAM_TOSERVER)); - goto end; - } - - smsg = ssn.toserver_smsg_head->next; - if (UtTestSmsg(smsg, stream_payload2, 15) == 0) - goto end; - - if (ssn.client.ra_raw_base_seq != 21) { - printf("ra_raw_base_seq %"PRIu32", expected 21: ", ssn.client.ra_raw_base_seq); - goto end; - } - - if (ssn.client.seg_list->seq != 7) { - printf("expected segment 2 (seq 7) to be first in the list, got seq %"PRIu32": ", ssn.client.seg_list->seq); - goto end; - } - - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test 3 in order segments, then reassemble, add one more and reassemble again. - * test the sliding window reassembly with a small window size so that we - * cutting off at the start (left edge). Test if the first segment is - * removed from the list. - */ -static int StreamTcpReassembleInlineTest09(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - stream_config.reassembly_toserver_chunk_size = 20; - ssn.client.flags |= STREAMTCP_STREAM_FLAG_GAP; - - uint8_t stream_payload1[] = "AAAAABBBBBCCCCC"; - uint8_t stream_payload2[] = "DDDDD"; - uint8_t stream_payload3[] = "AAAAABBBBBCCCCCDDDDD"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(17); - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 17, 'D', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - ssn.client.next_seq = 12; - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 2) { - printf("expected 2 stream message2, got %u: ", UtSsnSmsgCnt(&ssn, STREAM_TOSERVER)); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload1, 10) == 0) - goto end; - - smsg = ssn.toserver_smsg_head->next; - if (UtTestSmsg(smsg, stream_payload2, 5) == 0) - goto end; - - if (ssn.client.ra_raw_base_seq != 11) { - printf("ra_raw_base_seq %"PRIu32", expected 11: ", ssn.client.ra_raw_base_seq); - goto end; - } - - /* close the GAP and see if we properly reassemble and update ra_base_seq */ - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 12, 'C', 5) == -1) { - printf("failed to add segment 4: "); - goto end; - } - ssn.client.next_seq = 22; - - p->tcph->th_seq = htonl(12); - - r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed 2: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 3) { - printf("expected 3 stream messages: "); - goto end; - } - - smsg = ssn.toserver_smsg_head->next->next; - if (UtTestSmsg(smsg, stream_payload3, 20) == 0) - goto end; - - if (ssn.client.ra_raw_base_seq != 21) { - printf("ra_raw_base_seq %"PRIu32", expected 21: ", ssn.client.ra_raw_base_seq); - goto end; - } - - if (ssn.client.seg_list->seq != 2) { - printf("expected segment 1 (seq 2) to be first in the list, got seq %"PRIu32": ", ssn.client.seg_list->seq); - goto end; - } - - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test App Layer reassembly. - */ -static int StreamTcpReassembleInlineTest10(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow *f = NULL; - Packet *p = NULL; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTInitInline(); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.server, 1); - ssn.server.last_ack = 2; - StreamTcpUTSetupStream(&ssn.client, 1); - ssn.client.last_ack = 2; - - f = UTHBuildFlow(AF_INET, "1.1.1.1", "2.2.2.2", 1024, 80); - if (f == NULL) - goto end; - f->protoctx = &ssn; - f->proto = IPPROTO_TCP; - - uint8_t stream_payload1[] = "GE"; - uint8_t stream_payload2[] = "T /"; - uint8_t stream_payload3[] = "HTTP/1.0\r\n\r\n"; - - p = UTHBuildPacketReal(stream_payload3, 12, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(7); - p->flow = f; - p->flowflags |= FLOW_PKT_TOSERVER; - - SCMutexLock(&f->m); - if (StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, 2, stream_payload1, 2) == -1) { - printf("failed to add segment 1: "); - goto end; - } - ssn.server.next_seq = 4; - - int r = StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p); - if (r < 0) { - printf("StreamTcpReassembleAppLayer failed: "); - goto end; - } - - /* ssn.server.ra_app_base_seq should be isn here. */ - if (ssn.server.ra_app_base_seq != 1 || ssn.server.ra_app_base_seq != ssn.server.isn) { - printf("expected ra_app_base_seq 1, got %u: ", ssn.server.ra_app_base_seq); - goto end; - } - - if (StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, 4, stream_payload2, 3) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithPayload(&tv, ra_ctx, &ssn.server, 7, stream_payload3, 12) == -1) { - printf("failed to add segment 3: "); - goto end; - } - ssn.server.next_seq = 19; - - r = StreamTcpReassembleAppLayer(&tv, ra_ctx, &ssn, &ssn.server, p); - if (r < 0) { - printf("StreamTcpReassembleAppLayer failed: "); - goto end; - } - - if (ssn.server.ra_app_base_seq != 18) { - printf("expected ra_app_base_seq 18, got %u: ", ssn.server.ra_app_base_seq); - goto end; - } - - ret = 1; -end: - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - SCMutexUnlock(&f->m); - UTHFreeFlow(f); - return ret; -} - -/** \test test insert with overlap - */ -static int StreamTcpReassembleInsertTest01(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - Flow f; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - FLOW_INITIALIZE(&f); - - uint8_t stream_payload1[] = "AAAAABBBBBCCCCCDDDDD"; - uint8_t payload[] = { 'C', 'C', 'C', 'C', 'C' }; - Packet *p = UTHBuildPacketReal(payload, 5, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - printf("couldn't get a packet: "); - goto end; - } - p->tcph->th_seq = htonl(12); - p->flow = &f; - - SCMutexLock(&f.m); - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 14, 'D', 2) == -1) { - printf("failed to add segment 3: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 16, 'D', 6) == -1) { - printf("failed to add segment 4: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 12, 'C', 5) == -1) { - printf("failed to add segment 5: "); - goto end; - } - ssn.client.next_seq = 21; - - int r = StreamTcpReassembleInlineRaw(ra_ctx, &ssn, &ssn.client, p); - if (r < 0) { - printf("StreamTcpReassembleInlineRaw failed: "); - goto end; - } - - if (UtSsnSmsgCnt(&ssn, STREAM_TOSERVER) != 1) { - printf("expected a single stream message: "); - goto end; - } - - StreamMsg *smsg = ssn.toserver_smsg_head; - if (UtTestSmsg(smsg, stream_payload1, 20) == 0) - goto end; - - if (ssn.client.ra_raw_base_seq != 21) { - printf("ra_raw_base_seq %"PRIu32", expected 21: ", ssn.client.ra_raw_base_seq); - goto end; - } - ret = 1; -end: - SCMutexUnlock(&f.m); - FLOW_DESTROY(&f); - UTHFreePacket(p); - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test test insert with overlaps - */ -static int StreamTcpReassembleInsertTest02(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - - int i; - for (i = 2; i < 10; i++) { - int len; - len = i % 2; - if (len == 0) - len = 1; - int seq; - seq = i * 10; - if (seq < 2) - seq = 2; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, seq, 'A', len) == -1) { - printf("failed to add segment 1: "); - goto end; - } - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'B', 1024) == -1) { - printf("failed to add segment 2: "); - goto end; - } - - ret = 1; -end: - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -/** \test test insert with overlaps - */ -static int StreamTcpReassembleInsertTest03(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpSession ssn; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTSetupSession(&ssn); - StreamTcpUTSetupStream(&ssn.client, 1); - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, 2, 'A', 1024) == -1) { - printf("failed to add segment 2: "); - goto end; - } - - int i; - for (i = 2; i < 10; i++) { - int len; - len = i % 2; - if (len == 0) - len = 1; - int seq; - seq = i * 10; - if (seq < 2) - seq = 2; - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &ssn.client, seq, 'B', len) == -1) { - printf("failed to add segment 2: "); - goto end; - } - } - ret = 1; -end: - StreamTcpUTClearSession(&ssn); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -#endif /* UNITTESTS */ - -/** \brief The Function Register the Unit tests to test the reassembly engine - * for various OS policies. - */ - -void StreamTcpReassembleRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("StreamTcpReassembleTest01 -- BSD OS Before Reassembly Test", StreamTcpReassembleTest01, 1); - UtRegisterTest("StreamTcpReassembleTest02 -- BSD OS At Same Reassembly Test", StreamTcpReassembleTest02, 1); - UtRegisterTest("StreamTcpReassembleTest03 -- BSD OS After Reassembly Test", StreamTcpReassembleTest03, 1); - UtRegisterTest("StreamTcpReassembleTest04 -- BSD OS Complete Reassembly Test", StreamTcpReassembleTest04, 1); - UtRegisterTest("StreamTcpReassembleTest05 -- VISTA OS Before Reassembly Test", StreamTcpReassembleTest05, 1); - UtRegisterTest("StreamTcpReassembleTest06 -- VISTA OS At Same Reassembly Test", StreamTcpReassembleTest06, 1); - UtRegisterTest("StreamTcpReassembleTest07 -- VISTA OS After Reassembly Test", StreamTcpReassembleTest07, 1); - UtRegisterTest("StreamTcpReassembleTest08 -- VISTA OS Complete Reassembly Test", StreamTcpReassembleTest08, 1); - UtRegisterTest("StreamTcpReassembleTest09 -- LINUX OS Before Reassembly Test", StreamTcpReassembleTest09, 1); - UtRegisterTest("StreamTcpReassembleTest10 -- LINUX OS At Same Reassembly Test", StreamTcpReassembleTest10, 1); - UtRegisterTest("StreamTcpReassembleTest11 -- LINUX OS After Reassembly Test", StreamTcpReassembleTest11, 1); - UtRegisterTest("StreamTcpReassembleTest12 -- LINUX OS Complete Reassembly Test", StreamTcpReassembleTest12, 1); - UtRegisterTest("StreamTcpReassembleTest13 -- LINUX_OLD OS Before Reassembly Test", StreamTcpReassembleTest13, 1); - UtRegisterTest("StreamTcpReassembleTest14 -- LINUX_OLD At Same Reassembly Test", StreamTcpReassembleTest14, 1); - UtRegisterTest("StreamTcpReassembleTest15 -- LINUX_OLD OS After Reassembly Test", StreamTcpReassembleTest15, 1); - UtRegisterTest("StreamTcpReassembleTest16 -- LINUX_OLD OS Complete Reassembly Test", StreamTcpReassembleTest16, 1); - UtRegisterTest("StreamTcpReassembleTest17 -- SOLARIS OS Before Reassembly Test", StreamTcpReassembleTest17, 1); - UtRegisterTest("StreamTcpReassembleTest18 -- SOLARIS At Same Reassembly Test", StreamTcpReassembleTest18, 1); - UtRegisterTest("StreamTcpReassembleTest19 -- SOLARIS OS After Reassembly Test", StreamTcpReassembleTest19, 1); - UtRegisterTest("StreamTcpReassembleTest20 -- SOLARIS OS Complete Reassembly Test", StreamTcpReassembleTest20, 1); - UtRegisterTest("StreamTcpReassembleTest21 -- LAST OS Before Reassembly Test", StreamTcpReassembleTest21, 1); - UtRegisterTest("StreamTcpReassembleTest22 -- LAST OS At Same Reassembly Test", StreamTcpReassembleTest22, 1); - UtRegisterTest("StreamTcpReassembleTest23 -- LAST OS After Reassembly Test", StreamTcpReassembleTest23, 1); - UtRegisterTest("StreamTcpReassembleTest24 -- LAST OS Complete Reassembly Test", StreamTcpReassembleTest24, 1); - UtRegisterTest("StreamTcpReassembleTest25 -- Gap at Start Reassembly Test", StreamTcpReassembleTest25, 1); - UtRegisterTest("StreamTcpReassembleTest26 -- Gap at middle Reassembly Test", StreamTcpReassembleTest26, 1); - UtRegisterTest("StreamTcpReassembleTest27 -- Gap at after Reassembly Test", StreamTcpReassembleTest27, 1); - UtRegisterTest("StreamTcpReassembleTest28 -- Gap at Start IDS missed packet Reassembly Test", StreamTcpReassembleTest28, 1); - UtRegisterTest("StreamTcpReassembleTest29 -- Gap at Middle IDS missed packet Reassembly Test", StreamTcpReassembleTest29, 1); - UtRegisterTest("StreamTcpReassembleTest30 -- Gap at End IDS missed packet Reassembly Test", StreamTcpReassembleTest30, 1); - UtRegisterTest("StreamTcpReassembleTest31 -- Fast Track Reassembly Test", StreamTcpReassembleTest31, 1); - UtRegisterTest("StreamTcpReassembleTest32 -- Bug test", StreamTcpReassembleTest32, 1); - UtRegisterTest("StreamTcpReassembleTest33 -- Bug test", StreamTcpReassembleTest33, 1); - UtRegisterTest("StreamTcpReassembleTest34 -- Bug test", StreamTcpReassembleTest34, 1); - UtRegisterTest("StreamTcpReassembleTest35 -- Bug56 test", StreamTcpReassembleTest35, 1); - UtRegisterTest("StreamTcpReassembleTest36 -- Bug57 test", StreamTcpReassembleTest36, 1); - UtRegisterTest("StreamTcpReassembleTest37 -- Bug76 test", StreamTcpReassembleTest37, 1); - UtRegisterTest("StreamTcpReassembleTest38 -- app proto test", StreamTcpReassembleTest38, 1); - UtRegisterTest("StreamTcpReassembleTest39 -- app proto test", StreamTcpReassembleTest39, 1); - UtRegisterTest("StreamTcpReassembleTest40 -- app proto test", StreamTcpReassembleTest40, 1); - UtRegisterTest("StreamTcpReassembleTest43 -- min smsg size test", StreamTcpReassembleTest43, 1); - UtRegisterTest("StreamTcpReassembleTest44 -- Memcap Test", StreamTcpReassembleTest44, 1); - UtRegisterTest("StreamTcpReassembleTest45 -- Depth Test", StreamTcpReassembleTest45, 1); - UtRegisterTest("StreamTcpReassembleTest46 -- Depth Test", StreamTcpReassembleTest46, 1); - UtRegisterTest("StreamTcpReassembleTest47 -- TCP Sequence Wraparound Test", StreamTcpReassembleTest47, 1); - - UtRegisterTest("StreamTcpReassembleInlineTest01 -- inline RAW ra", StreamTcpReassembleInlineTest01, 1); - UtRegisterTest("StreamTcpReassembleInlineTest02 -- inline RAW ra 2", StreamTcpReassembleInlineTest02, 1); - UtRegisterTest("StreamTcpReassembleInlineTest03 -- inline RAW ra 3", StreamTcpReassembleInlineTest03, 1); - UtRegisterTest("StreamTcpReassembleInlineTest04 -- inline RAW ra 4", StreamTcpReassembleInlineTest04, 1); - UtRegisterTest("StreamTcpReassembleInlineTest05 -- inline RAW ra 5 GAP", StreamTcpReassembleInlineTest05, 1); - UtRegisterTest("StreamTcpReassembleInlineTest06 -- inline RAW ra 6 GAP", StreamTcpReassembleInlineTest06, 1); - UtRegisterTest("StreamTcpReassembleInlineTest07 -- inline RAW ra 7 GAP", StreamTcpReassembleInlineTest07, 1); - UtRegisterTest("StreamTcpReassembleInlineTest08 -- inline RAW ra 8 cleanup", StreamTcpReassembleInlineTest08, 1); - UtRegisterTest("StreamTcpReassembleInlineTest09 -- inline RAW ra 9 GAP cleanup", StreamTcpReassembleInlineTest09, 1); - - UtRegisterTest("StreamTcpReassembleInlineTest10 -- inline APP ra 10", StreamTcpReassembleInlineTest10, 1); - - UtRegisterTest("StreamTcpReassembleInsertTest01 -- insert with overlap", StreamTcpReassembleInsertTest01, 1); - UtRegisterTest("StreamTcpReassembleInsertTest02 -- insert with overlap", StreamTcpReassembleInsertTest02, 1); - UtRegisterTest("StreamTcpReassembleInsertTest03 -- insert with overlap", StreamTcpReassembleInsertTest03, 1); - - StreamTcpInlineRegisterTests(); - StreamTcpUtilRegisterTests(); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/stream-tcp-reassemble.h b/framework/src/suricata/src/stream-tcp-reassemble.h deleted file mode 100644 index b6e798ce..00000000 --- a/framework/src/suricata/src/stream-tcp-reassemble.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Gurvinder Singh - */ - -#ifndef __STREAM_TCP_REASSEMBLE_H__ -#define __STREAM_TCP_REASSEMBLE_H__ - -#include "stream-tcp-private.h" -#include "stream.h" -#include "app-layer-detect-proto.h" -#include "stream-tcp-private.h" - -/** Supported OS list and default OS policy is BSD */ -enum -{ - OS_POLICY_NONE = 1, - OS_POLICY_BSD, - OS_POLICY_BSD_RIGHT, - OS_POLICY_OLD_LINUX, - OS_POLICY_LINUX, - OS_POLICY_OLD_SOLARIS, - OS_POLICY_SOLARIS, - OS_POLICY_HPUX10, - OS_POLICY_HPUX11, - OS_POLICY_IRIX, - OS_POLICY_MACOS, - OS_POLICY_WINDOWS, - OS_POLICY_VISTA, - OS_POLICY_WINDOWS2K3, - OS_POLICY_FIRST, - OS_POLICY_LAST -}; - -typedef struct TcpReassemblyThreadCtx_ { - void *app_tctx; - /** TCP segments which are not being reassembled due to memcap was reached */ - uint16_t counter_tcp_segment_memcap; - /** number of streams that stop reassembly because their depth is reached */ - uint16_t counter_tcp_stream_depth; - /** count number of streams with a unrecoverable stream gap (missing pkts) */ - uint16_t counter_tcp_reass_gap; -#ifdef DEBUG - uint64_t fp1; - uint64_t fp2; - uint64_t sp; -#endif -} TcpReassemblyThreadCtx; - -#define OS_POLICY_DEFAULT OS_POLICY_BSD - -int StreamTcpReassembleHandleSegment(ThreadVars *, TcpReassemblyThreadCtx *, TcpSession *, TcpStream *, Packet *, PacketQueue *); -int StreamTcpReassembleInit(char); -void StreamTcpReassembleFree(char); -void StreamTcpReassembleRegisterTests(void); -TcpReassemblyThreadCtx *StreamTcpReassembleInitThreadCtx(ThreadVars *tv); -void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *); -int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, - TcpSession *ssn, TcpStream *stream, - Packet *p); - -void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t); - -void StreamTcpSetSessionNoReassemblyFlag (TcpSession *, char ); -void StreamTcpSetDisableRawReassemblyFlag (TcpSession *ssn, char direction); - -void StreamTcpSetOSPolicy(TcpStream *, Packet *); -void StreamTcpReassemblePause (TcpSession *, char ); -void StreamTcpReassembleUnPause (TcpSession *, char ); -int StreamTcpCheckStreamContents(uint8_t *, uint16_t , TcpStream *); - -int StreamTcpReassembleInsertSegment(ThreadVars *, TcpReassemblyThreadCtx *, TcpStream *, TcpSegment *, Packet *); -TcpSegment* StreamTcpGetSegment(ThreadVars *, TcpReassemblyThreadCtx *, uint16_t); - -void StreamTcpReturnStreamSegments(TcpStream *); -void StreamTcpSegmentReturntoPool(TcpSegment *); - -void StreamTcpReassembleTriggerRawReassembly(TcpSession *); - -void StreamTcpPruneSession(Flow *, uint8_t); -int StreamTcpReassembleDepthReached(Packet *p); - -void StreamTcpReassembleIncrMemuse(uint64_t size); -void StreamTcpReassembleDecrMemuse(uint64_t size); -int StreamTcpReassembleCheckMemcap(uint32_t size); - -void StreamTcpDisableAppLayer(Flow *f); -int StreamTcpAppLayerIsDisabled(Flow *f); - -#endif /* __STREAM_TCP_REASSEMBLE_H__ */ - diff --git a/framework/src/suricata/src/stream-tcp-sack.c b/framework/src/suricata/src/stream-tcp-sack.c deleted file mode 100644 index 9e5503f7..00000000 --- a/framework/src/suricata/src/stream-tcp-sack.c +++ /dev/null @@ -1,960 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Stream engine TCP SACK handling. - */ - -#include "suricata-common.h" -#include "stream-tcp.h" -#include "stream-tcp-private.h" -#include "stream-tcp-sack.h" -#include "util-unittest.h" - -#ifdef DEBUG -void StreamTcpSackPrintList(TcpStream *stream) -{ - StreamTcpSackRecord *rec = stream->sack_head; - for (; rec != NULL; rec = rec->next) { - SCLogDebug("record %8u - %8u", rec->le, rec->re); - } -} -#endif /* DEBUG */ - -static StreamTcpSackRecord *StreamTcpSackRecordAlloc(void) -{ - if (StreamTcpCheckMemcap((uint32_t)sizeof(StreamTcpSackRecord)) == 0) - return NULL; - - StreamTcpSackRecord *rec = SCMalloc(sizeof(*rec)); - if (unlikely(rec == NULL)) - return NULL; - - StreamTcpIncrMemuse((uint64_t)sizeof(*rec)); - return rec; -} - -static void StreamTcpSackRecordFree(StreamTcpSackRecord *rec) -{ - SCFree(rec); - StreamTcpDecrMemuse((uint64_t)sizeof(*rec)); -} - -/** - * \brief insert a SACK range - * - * \param le left edge in host order - * \param re right edge in host order - * - * \retval 0 all is good - * \retval -1 error - */ -static int StreamTcpSackInsertRange(TcpStream *stream, uint32_t le, uint32_t re) -{ - SCLogDebug("le %u, re %u", le, re); -#ifdef DEBUG - StreamTcpSackPrintList(stream); -#endif - - /* if to the left of last_ack then ignore */ - if (SEQ_LT(re, stream->last_ack)) { - SCLogDebug("too far left. discarding"); - goto end; - } - /* if to the right of the tcp window then ignore */ - if (SEQ_GT(le, (stream->last_ack + stream->window))) { - SCLogDebug("too far right. discarding"); - goto end; - } - if (stream->sack_head != NULL) { - StreamTcpSackRecord *rec; - - for (rec = stream->sack_head; rec != NULL; rec = rec->next) { - SCLogDebug("rec %p, le %u, re %u", rec, rec->le, rec->re); - - if (SEQ_LT(le, rec->le)) { - SCLogDebug("SEQ_LT(le, rec->le)"); - if (SEQ_LT(re, rec->le)) { - SCLogDebug("SEQ_LT(re, rec->le)"); - // entirely before, prepend - StreamTcpSackRecord *stsr = StreamTcpSackRecordAlloc(); - if (unlikely(stsr == NULL)) { - SCReturnInt(-1); - } - stsr->le = le; - stsr->re = re; - - stsr->next = stream->sack_head; - stream->sack_head = stsr; - goto end; - } else if (SEQ_EQ(re, rec->le)) { - SCLogDebug("SEQ_EQ(re, rec->le)"); - // starts before, ends on rec->le, expand - rec->le = le; - } else if (SEQ_GT(re, rec->le)) { - SCLogDebug("SEQ_GT(re, rec->le)"); - // starts before, ends beyond rec->le - if (SEQ_LEQ(re, rec->re)) { - SCLogDebug("SEQ_LEQ(re, rec->re)"); - // ends before rec->re, expand - rec->le = le; - } else { // implied if (re > rec->re) - SCLogDebug("implied if (re > rec->re), le set to %u", rec->re); - le = rec->re; - continue; - } - } - } else if (SEQ_EQ(le, rec->le)) { - SCLogDebug("SEQ_EQ(le, rec->le)"); - if (SEQ_LEQ(re, rec->re)) { - SCLogDebug("SEQ_LEQ(re, rec->re)"); - // new record fully overlapped - SCReturnInt(0); - } else { // implied re > rec->re - SCLogDebug("implied re > rec->re"); - if (rec->next != NULL) { - if (SEQ_LEQ(re, rec->next->le)) { - rec->re = re; - goto end; - } else { - rec->re = rec->next->le; - le = rec->next->le; - SCLogDebug("le is now %u", le); - continue; - } - } else { - rec->re = re; - goto end; - } - } - } else { // implied (le > rec->le) - SCLogDebug("implied (le > rec->le)"); - if (SEQ_LT(le, rec->re)) { - SCLogDebug("SEQ_LT(le, rec->re))"); - // new record fully overlapped - if (SEQ_GT(re, rec->re)) { - SCLogDebug("SEQ_GT(re, rec->re)"); - - if (rec->next != NULL) { - if (SEQ_LEQ(re, rec->next->le)) { - rec->re = re; - goto end; - } else { - rec->re = rec->next->le; - le = rec->next->le; - continue; - } - } else { - rec->re = re; - goto end; - } - } - - SCLogDebug("new range fully overlapped"); - SCReturnInt(0); - } else if (SEQ_EQ(le, rec->re)) { - SCLogDebug("here"); - // new record fully overlapped - //int r = StreamTcpSackInsertRange(stream, rec->re+1, re); - //SCReturnInt(r); - le = rec->re; - continue; - } else { /* implied le > rec->re */ - SCLogDebug("implied le > rec->re"); - if (rec->next == NULL) { - SCLogDebug("rec->next == NULL"); - StreamTcpSackRecord *stsr = StreamTcpSackRecordAlloc(); - if (unlikely(stsr == NULL)) { - SCReturnInt(-1); - } - stsr->le = le; - stsr->re = re; - stsr->next = NULL; - - stream->sack_tail->next = stsr; - stream->sack_tail = stsr; - goto end; - } else { - SCLogDebug("implied rec->next != NULL"); - if (SEQ_LT(le, rec->next->le) && SEQ_LT(re, rec->next->le)) { - SCLogDebug("SEQ_LT(le, rec->next->le) && SEQ_LT(re, rec->next->le)"); - StreamTcpSackRecord *stsr = StreamTcpSackRecordAlloc(); - if (unlikely(stsr == NULL)) { - SCReturnInt(-1); - } - stsr->le = le; - stsr->re = re; - stsr->next = rec->next; - rec->next = stsr; - - } else if (SEQ_LT(le, rec->next->le) && SEQ_GEQ(re, rec->next->le)) { - SCLogDebug("SEQ_LT(le, rec->next->le) && SEQ_GEQ(re, rec->next->le)"); - StreamTcpSackRecord *stsr = StreamTcpSackRecordAlloc(); - if (unlikely(stsr == NULL)) { - SCReturnInt(-1); - } - stsr->le = le; - stsr->re = rec->next->le; - stsr->next = rec->next; - rec->next = stsr; - - le = rec->next->le; - } - } - } - } - } - } else { - SCLogDebug("implied empty list"); - StreamTcpSackRecord *stsr = StreamTcpSackRecordAlloc(); - if (unlikely(stsr == NULL)) { - SCReturnInt(-1); - } - stsr->le = le; - stsr->re = re; - stsr->next = NULL; - - stream->sack_head = stsr; - stream->sack_tail = stsr; - } - - StreamTcpSackPruneList(stream); -end: - SCReturnInt(0); -} - -/** - * \brief Update stream with SACK records from a TCP packet. - * - * \param stream The stream to update. - * \param p packet to get the SACK records from - * - * \retval -1 error - * \retval 0 ok - */ -int StreamTcpSackUpdatePacket(TcpStream *stream, Packet *p) -{ - int records = TCP_GET_SACK_CNT(p); - int record = 0; - - TCPOptSackRecord *sack_rec = (TCPOptSackRecord *)(TCP_GET_SACK_PTR(p)); - - for (record = 0; record < records; record++) { - SCLogDebug("%p last_ack %u, left edge %u, right edge %u", sack_rec, - stream->last_ack, ntohl(sack_rec->le), ntohl(sack_rec->re)); - - if (SEQ_LEQ(ntohl(sack_rec->re), stream->last_ack)) { - SCLogDebug("record before last_ack"); - goto next; - } - - /** \todo need a metric to a check for a right edge limit */ -/* - if (SEQ_GT(ntohl(sack_rec->re), stream->next_seq)) { - SCLogDebug("record beyond next_seq %u", stream->next_seq); - goto next; - } -*/ - if (SEQ_GEQ(ntohl(sack_rec->le), ntohl(sack_rec->re))) { - SCLogDebug("invalid record: le >= re"); - goto next; - } - - if (StreamTcpSackInsertRange(stream, ntohl(sack_rec->le), - ntohl(sack_rec->re)) == -1) - { - SCReturnInt(-1); - } - - next: - sack_rec++; - } -#ifdef DEBUG - StreamTcpSackPrintList(stream); -#endif - SCReturnInt(0); -} - -void StreamTcpSackPruneList(TcpStream *stream) -{ - SCEnter(); - - StreamTcpSackRecord *rec = stream->sack_head; - - while (rec != NULL) { - if (SEQ_LT(rec->re, stream->last_ack)) { - SCLogDebug("removing le %u re %u", rec->le, rec->re); - - if (rec->next != NULL) { - stream->sack_head = rec->next; - StreamTcpSackRecordFree(rec); - rec = stream->sack_head; - continue; - } else { - stream->sack_head = NULL; - stream->sack_tail = NULL; - StreamTcpSackRecordFree(rec); - break; - } - } else if (SEQ_LT(rec->le, stream->last_ack)) { - SCLogDebug("adjusting record to le %u re %u", rec->le, rec->re); - /* last ack inside this record, update */ - rec->le = stream->last_ack; - break; - } else { - SCLogDebug("record beyond last_ack, nothing to do. Bailing out."); - break; - } - } -#ifdef DEBUG - StreamTcpSackPrintList(stream); -#endif - SCReturn; -} - -/** - * \brief Free SACK list from a stream - * - * \param stream Stream to cleanup - */ -void StreamTcpSackFreeList(TcpStream *stream) -{ - SCEnter(); - - StreamTcpSackRecord *rec = stream->sack_head; - StreamTcpSackRecord *next = NULL; - - while (rec != NULL) { - next = rec->next; - StreamTcpSackRecordFree(rec); - rec = next; - } - - stream->sack_head = NULL; - stream->sack_tail = NULL; - SCReturn; -} - - -#ifdef UNITTESTS - -/** - * \test Test the insertion of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest01 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 100; - - StreamTcpSackInsertRange(&stream, 1, 10); - StreamTcpSackInsertRange(&stream, 10, 20); - StreamTcpSackInsertRange(&stream, 10, 20); - StreamTcpSackInsertRange(&stream, 1, 20); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 1 || stream.sack_head->re != 20) { - printf("list in weird state, head le %u, re %u: ", - stream.sack_head->le, stream.sack_head->re); - goto end; - } - - if (StreamTcpSackedSize(&stream) != 19) { - printf("size should be 19, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the insertion of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest02 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 100; - - StreamTcpSackInsertRange(&stream, 10, 20); - StreamTcpSackInsertRange(&stream, 1, 20); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 1 || stream.sack_head->re != 20) { - printf("list in weird state, head le %u, re %u: ", - stream.sack_head->le, stream.sack_head->re); - goto end; - } - - if (StreamTcpSackedSize(&stream) != 19) { - printf("size should be 19, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the insertion of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest03 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 100; - - StreamTcpSackInsertRange(&stream, 10, 20); - StreamTcpSackInsertRange(&stream, 5, 15); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - StreamTcpSackInsertRange(&stream, 15, 25); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 5) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 20) { - printf("size should be 20, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the insertion of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest04 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 100; - - StreamTcpSackInsertRange(&stream, 0, 20); - StreamTcpSackInsertRange(&stream, 30, 50); - StreamTcpSackInsertRange(&stream, 10, 25); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 0) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 45) { - printf("size should be 45, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the insertion of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest05 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 100; - - StreamTcpSackInsertRange(&stream, 0, 20); - StreamTcpSackInsertRange(&stream, 30, 50); - StreamTcpSackInsertRange(&stream, 10, 35); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 0) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 50) { - printf("size should be 50, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the insertion of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest06 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 100; - - StreamTcpSackInsertRange(&stream, 0, 9); - StreamTcpSackInsertRange(&stream, 11, 19); - StreamTcpSackInsertRange(&stream, 21, 29); - StreamTcpSackInsertRange(&stream, 31, 39); - StreamTcpSackInsertRange(&stream, 0, 40); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 0) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 40) { - printf("size should be 40, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the pruning of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest07 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 100; - - StreamTcpSackInsertRange(&stream, 0, 9); - StreamTcpSackInsertRange(&stream, 11, 19); - StreamTcpSackInsertRange(&stream, 21, 29); - StreamTcpSackInsertRange(&stream, 31, 39); - StreamTcpSackInsertRange(&stream, 0, 40); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 0) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 40) { - printf("size should be 40, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - stream.last_ack = 10; - - StreamTcpSackPruneList(&stream); - - if (StreamTcpSackedSize(&stream) != 30) { - printf("size should be 30, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the pruning of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest08 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 100; - - StreamTcpSackInsertRange(&stream, 0, 9); - StreamTcpSackInsertRange(&stream, 11, 19); - StreamTcpSackInsertRange(&stream, 21, 29); - StreamTcpSackInsertRange(&stream, 31, 39); - StreamTcpSackInsertRange(&stream, 0, 40); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 0) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 40) { - printf("size should be 40, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - stream.last_ack = 41; - - StreamTcpSackPruneList(&stream); - - if (StreamTcpSackedSize(&stream) != 0) { - printf("size should be 0, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the pruning of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest09 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 100; - - StreamTcpSackInsertRange(&stream, 0, 9); - StreamTcpSackInsertRange(&stream, 11, 19); - StreamTcpSackInsertRange(&stream, 21, 29); - StreamTcpSackInsertRange(&stream, 31, 39); - StreamTcpSackInsertRange(&stream, 0, 40); - -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 0) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 40) { - printf("size should be 40, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - stream.last_ack = 39; - - StreamTcpSackPruneList(&stream); - - if (StreamTcpSackedSize(&stream) != 1) { - printf("size should be 1, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the pruning of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest10 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 1000; - - StreamTcpSackInsertRange(&stream, 100, 119); - StreamTcpSackInsertRange(&stream, 111, 119); - StreamTcpSackInsertRange(&stream, 121, 129); - StreamTcpSackInsertRange(&stream, 131, 139); - StreamTcpSackInsertRange(&stream, 100, 140); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 100) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 40) { - printf("size should be 40, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - stream.last_ack = 99; - - StreamTcpSackPruneList(&stream); - - if (StreamTcpSackedSize(&stream) != 40) { - printf("size should be 40, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the pruning of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest11 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 1000; - - StreamTcpSackInsertRange(&stream, 100, 119); - StreamTcpSackInsertRange(&stream, 111, 119); - StreamTcpSackInsertRange(&stream, 121, 129); - StreamTcpSackInsertRange(&stream, 131, 139); - StreamTcpSackInsertRange(&stream, 101, 140); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 100) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 40) { - printf("size should be 40, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - stream.last_ack = 99; - - StreamTcpSackPruneList(&stream); - - if (StreamTcpSackedSize(&stream) != 40) { - printf("size should be 40, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the pruning of SACK ranges. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest12 (void) -{ - TcpStream stream; - int retval = 0; - - memset(&stream, 0, sizeof(stream)); - stream.window = 2000; - - StreamTcpSackInsertRange(&stream, 800, 1000); - StreamTcpSackInsertRange(&stream, 700, 900); - StreamTcpSackInsertRange(&stream, 600, 800); - StreamTcpSackInsertRange(&stream, 500, 700); - StreamTcpSackInsertRange(&stream, 100, 600); -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (stream.sack_head->le != 100) { - goto end; - } - - if (StreamTcpSackedSize(&stream) != 900) { - printf("size should be 900, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - StreamTcpSackInsertRange(&stream, 0, 1000); - - if (StreamTcpSackedSize(&stream) != 1000) { - printf("size should be 1000, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - stream.last_ack = 500; - - StreamTcpSackPruneList(&stream); - - if (StreamTcpSackedSize(&stream) != 500) { - printf("size should be 500, is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the insertion on out of window condition. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest13 (void) { - TcpStream stream; - int retval = 0; - int i; - - memset(&stream, 0, sizeof(stream)); - stream.last_ack = 10000; - stream.window = 2000; - - for (i = 0; i < 10; i++) { - StreamTcpSackInsertRange(&stream, 100+(20*i), 110+(20*i)); - } -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (StreamTcpSackedSize(&stream) != 0) { - printf("Sacked size is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -/** - * \test Test the insertion of out of window condition. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpSackTest14 (void) { - TcpStream stream; - int retval = 0; - int i; - - memset(&stream, 0, sizeof(stream)); - stream.last_ack = 1000; - stream.window = 2000; - - for (i = 0; i < 10; i++) { - StreamTcpSackInsertRange(&stream, 4000+(20*i), 4010+(20*i)); - } -#ifdef DEBUG - StreamTcpSackPrintList(&stream); -#endif /* DEBUG */ - - if (StreamTcpSackedSize(&stream) != 0) { - printf("Sacked size is %u: ", StreamTcpSackedSize(&stream)); - goto end; - } - - retval = 1; -end: - SCReturnInt(retval); -} - -#endif /* UNITTESTS */ - -void StreamTcpSackRegisterTests (void) -{ -#ifdef UNITTESTS - UtRegisterTest("StreamTcpSackTest01 -- Insertion", - StreamTcpSackTest01, 1); - UtRegisterTest("StreamTcpSackTest02 -- Insertion", - StreamTcpSackTest02, 1); - UtRegisterTest("StreamTcpSackTest03 -- Insertion", - StreamTcpSackTest03, 1); - UtRegisterTest("StreamTcpSackTest04 -- Insertion", - StreamTcpSackTest04, 1); - UtRegisterTest("StreamTcpSackTest05 -- Insertion", - StreamTcpSackTest05, 1); - UtRegisterTest("StreamTcpSackTest06 -- Insertion", - StreamTcpSackTest06, 1); - UtRegisterTest("StreamTcpSackTest07 -- Pruning", - StreamTcpSackTest07, 1); - UtRegisterTest("StreamTcpSackTest08 -- Pruning", - StreamTcpSackTest08, 1); - UtRegisterTest("StreamTcpSackTest09 -- Pruning", - StreamTcpSackTest09, 1); - UtRegisterTest("StreamTcpSackTest10 -- Pruning", - StreamTcpSackTest10, 1); - UtRegisterTest("StreamTcpSackTest11 -- Insertion && Pruning", - StreamTcpSackTest11, 1); - UtRegisterTest("StreamTcpSackTest12 -- Insertion && Pruning", - StreamTcpSackTest12, 1); - UtRegisterTest("StreamTcpSackTest13 -- Insertion out of window", - StreamTcpSackTest13, 1); - UtRegisterTest("StreamTcpSackTest14 -- Insertion out of window", - StreamTcpSackTest14, 1); -#endif -} diff --git a/framework/src/suricata/src/stream-tcp-sack.h b/framework/src/suricata/src/stream-tcp-sack.h deleted file mode 100644 index 632fa14d..00000000 --- a/framework/src/suricata/src/stream-tcp-sack.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __STREAM_TCP_SACK_H__ -#define __STREAM_TCP_SACK_H__ - -#include "suricata-common.h" -#include "util-optimize.h" - -/** - * \brief Get the size of the SACKed ranges - * - * \param stream Stream to get the size for. - * - * \retval size the size - * - * Optimized for case where SACK is not in use in the - * stream, as it *should* only be used in case of packet - * loss. - */ -static inline uint32_t StreamTcpSackedSize(TcpStream *stream) -{ - if (likely(stream->sack_head == NULL)) { - SCReturnUInt(0U); - } else { - uint32_t size = 0; - - StreamTcpSackRecord *rec = NULL; - - for (rec = stream->sack_head; rec != NULL; rec = rec->next) { - size += (rec->re - rec->le); - } - - SCReturnUInt(size); - } -} - -int StreamTcpSackUpdatePacket(TcpStream *, Packet *); -void StreamTcpSackPruneList(TcpStream *); -void StreamTcpSackFreeList(TcpStream *); -void StreamTcpSackRegisterTests (void); - -#endif /* __STREAM_TCP_SACK_H__*/ diff --git a/framework/src/suricata/src/stream-tcp-util.c b/framework/src/suricata/src/stream-tcp-util.c deleted file mode 100644 index 405684fd..00000000 --- a/framework/src/suricata/src/stream-tcp-util.c +++ /dev/null @@ -1,264 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Helper functions for the stream engine. - */ - -#include "suricata-common.h" - -#include "stream-tcp-reassemble.h" -#include "stream-tcp-inline.h" -#include "stream-tcp.h" -#include "stream-tcp-util.h" - -#include "util-memcmp.h" -#include "util-print.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#ifdef UNITTESTS - -/* unittest helper functions */ - -extern int stream_inline; - -void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx) -{ - StreamTcpInitConfig(TRUE); - *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); -} - -void StreamTcpUTDeinit(TcpReassemblyThreadCtx *ra_ctx) -{ - StreamTcpReassembleFreeThreadCtx(ra_ctx); - StreamTcpFreeConfig(TRUE); - stream_inline = 0; -} - -void StreamTcpUTInitInline(void) { - stream_inline = 1; -} - -void StreamTcpUTSetupSession(TcpSession *ssn) -{ - memset(ssn, 0x00, sizeof(TcpSession)); -} - -void StreamTcpUTClearSession(TcpSession *ssn) -{ - StreamTcpUTClearStream(&ssn->client); - StreamTcpUTClearStream(&ssn->server); -} - -void StreamTcpUTSetupStream(TcpStream *s, uint32_t isn) -{ - memset(s, 0x00, sizeof(TcpStream)); - - s->isn = isn; - STREAMTCP_SET_RA_BASE_SEQ(s, isn); -} - -void StreamTcpUTClearStream(TcpStream *s) -{ - StreamTcpReturnStreamSegments(s); -} - -int StreamTcpUTAddSegmentWithPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len) -{ - TcpSegment *s = StreamTcpGetSegment(tv, ra_ctx, len); - if (s == NULL) { - return -1; - } - - s->seq = seq; - s->payload_len = len; - memcpy(s->payload, payload, len); - - Packet *p = UTHBuildPacketReal(s->payload, s->payload_len, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - return -1; - } - p->tcph->th_seq = htonl(seq); - - if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p) < 0) - return -1; - - UTHFreePacket(p); - return 0; -} - -int StreamTcpUTAddSegmentWithByte(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t byte, uint16_t len) -{ - TcpSegment *s = StreamTcpGetSegment(tv, ra_ctx, len); - if (s == NULL) { - return -1; - } - - s->seq = seq; - s->payload_len = len; - memset(s->payload, byte, len); - - Packet *p = UTHBuildPacketReal(s->payload, s->payload_len, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); - if (p == NULL) { - return -1; - } - p->tcph->th_seq = htonl(seq); - - if (StreamTcpReassembleInsertSegment(tv, ra_ctx, stream, s, p) < 0) - return -1; - UTHFreePacket(p); - return 0; -} - -/* tests */ - -int StreamTcpUtilTest01(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - - StreamTcpUTInit(&ra_ctx); - - if (ra_ctx == NULL) { - printf("ra_ctx is NULL: "); - goto end; - } - - ret = 1; -end: - StreamTcpUTDeinit(ra_ctx); - return ret; -} - - -int StreamTcpUtilStreamTest01(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpStream stream; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTSetupStream(&stream, 1); - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 12, 'C', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - - TcpSegment *seg = stream.seg_list; - if (seg->seq != 2) { - printf("first seg in the list should have seq 2: "); - goto end; - } - - seg = seg->next; - if (seg->seq != 7) { - printf("first seg in the list should have seq 7: "); - goto end; - } - - seg = seg->next; - if (seg->seq != 12) { - printf("first seg in the list should have seq 12: "); - goto end; - } - - ret = 1; -end: - StreamTcpUTClearStream(&stream); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -int StreamTcpUtilStreamTest02(void) -{ - int ret = 0; - TcpReassemblyThreadCtx *ra_ctx = NULL; - ThreadVars tv; - TcpStream stream; - - memset(&tv, 0x00, sizeof(tv)); - - StreamTcpUTInit(&ra_ctx); - StreamTcpUTSetupStream(&stream, 1); - - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 7, 'B', 5) == -1) { - printf("failed to add segment 2: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 12, 'C', 5) == -1) { - printf("failed to add segment 3: "); - goto end; - } - if (StreamTcpUTAddSegmentWithByte(&tv, ra_ctx, &stream, 2, 'A', 5) == -1) { - printf("failed to add segment 1: "); - goto end; - } - - TcpSegment *seg = stream.seg_list; - if (seg->seq != 2) { - printf("first seg in the list should have seq 2: "); - goto end; - } - - seg = seg->next; - if (seg->seq != 7) { - printf("first seg in the list should have seq 7: "); - goto end; - } - - seg = seg->next; - if (seg->seq != 12) { - printf("first seg in the list should have seq 12: "); - goto end; - } - - ret = 1; -end: - StreamTcpUTClearStream(&stream); - StreamTcpUTDeinit(ra_ctx); - return ret; -} - -#endif - -void StreamTcpUtilRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("StreamTcpUtilTest01", StreamTcpUtilTest01, 1); - UtRegisterTest("StreamTcpUtilStreamTest01", StreamTcpUtilStreamTest01, 1); - UtRegisterTest("StreamTcpUtilStreamTest02", StreamTcpUtilStreamTest02, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/stream-tcp-util.h b/framework/src/suricata/src/stream-tcp-util.h deleted file mode 100644 index 72f2b4fc..00000000 --- a/framework/src/suricata/src/stream-tcp-util.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __STREAM_TCP_UTIL_H__ -#define __STREAM_TCP_UTIL_H__ - -#include "stream-tcp-private.h" - -void StreamTcpUTInit(TcpReassemblyThreadCtx **); -void StreamTcpUTDeinit(TcpReassemblyThreadCtx *); - -void StreamTcpUTInitInline(void); - -void StreamTcpUTSetupSession(TcpSession *); -void StreamTcpUTClearSession(TcpSession *); - -void StreamTcpUTSetupStream(TcpStream *, uint32_t isn); -void StreamTcpUTClearStream(TcpStream *); - -int StreamTcpUTAddSegmentWithByte(ThreadVars *, TcpReassemblyThreadCtx *, TcpStream *, uint32_t, uint8_t, uint16_t); -int StreamTcpUTAddSegmentWithPayload(ThreadVars *, TcpReassemblyThreadCtx *, TcpStream *, uint32_t, uint8_t *, uint16_t); - - -void StreamTcpUtilRegisterTests(void); - -#endif /* __STREAM_TCP_UTIL_H__ */ - diff --git a/framework/src/suricata/src/stream-tcp.c b/framework/src/suricata/src/stream-tcp.c deleted file mode 100644 index 9dce7070..00000000 --- a/framework/src/suricata/src/stream-tcp.c +++ /dev/null @@ -1,10820 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Gurvinder Singh - * - * TCP stream tracking and reassembly engine. - * - * \todo - 4WHS: what if after the 2nd SYN we turn out to be normal 3WHS anyway? - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "decode.h" -#include "debug.h" -#include "detect.h" - -#include "flow.h" -#include "flow-util.h" - -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-pool.h" -#include "util-pool-thread.h" -#include "util-checksum.h" -#include "util-unittest.h" -#include "util-print.h" -#include "util-debug.h" -#include "util-device.h" - -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" -#include "stream-tcp.h" -#include "stream-tcp-inline.h" -#include "stream-tcp-sack.h" -#include "stream-tcp-util.h" -#include "stream.h" - -#include "pkt-var.h" -#include "host.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-protos.h" -#include "app-layer-htp-mem.h" - -#include "util-host-os-info.h" -#include "util-privs.h" -#include "util-profiling.h" -#include "util-misc.h" -#include "util-validate.h" -#include "util-runmodes.h" - -#include "source-pcap-file.h" - -//#define DEBUG - -#define STREAMTCP_DEFAULT_PREALLOC 2048 -#define STREAMTCP_DEFAULT_MEMCAP (32 * 1024 * 1024) /* 32mb */ -#define STREAMTCP_DEFAULT_REASSEMBLY_MEMCAP (64 * 1024 * 1024) /* 64mb */ -#define STREAMTCP_DEFAULT_TOSERVER_CHUNK_SIZE 2560 -#define STREAMTCP_DEFAULT_TOCLIENT_CHUNK_SIZE 2560 -#define STREAMTCP_DEFAULT_MAX_SYNACK_QUEUED 5 - -#define STREAMTCP_NEW_TIMEOUT 60 -#define STREAMTCP_EST_TIMEOUT 3600 -#define STREAMTCP_CLOSED_TIMEOUT 120 - -#define STREAMTCP_EMERG_NEW_TIMEOUT 10 -#define STREAMTCP_EMERG_EST_TIMEOUT 300 -#define STREAMTCP_EMERG_CLOSED_TIMEOUT 20 - -TmEcode StreamTcp (ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); -TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **); -TmEcode StreamTcpThreadDeinit(ThreadVars *, void *); -void StreamTcpExitPrintStats(ThreadVars *, void *); -static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *, TcpSession *, Packet *, PacketQueue *); -void StreamTcpRegisterTests (void); -void StreamTcpReturnStreamSegments (TcpStream *); -void StreamTcpInitConfig(char); -int StreamTcpGetFlowState(void *); -void StreamTcpSetOSPolicy(TcpStream*, Packet*); -void StreamTcpPseudoPacketCreateStreamEndPacket(ThreadVars *tv, StreamTcpThread *stt, Packet *p, TcpSession *ssn, PacketQueue *pq); - -static int StreamTcpValidateTimestamp(TcpSession * , Packet *); -static int StreamTcpHandleTimestamp(TcpSession * , Packet *); -static int StreamTcpValidateRst(TcpSession * , Packet *); -static inline int StreamTcpValidateAck(TcpSession *ssn, TcpStream *, Packet *); - -static PoolThread *ssn_pool = NULL; -static SCMutex ssn_pool_mutex = SCMUTEX_INITIALIZER; /**< init only, protect initializing and growing pool */ -#ifdef DEBUG -static uint64_t ssn_pool_cnt = 0; /** counts ssns, protected by ssn_pool_mutex */ -#endif - -uint64_t StreamTcpReassembleMemuseGlobalCounter(void); -SC_ATOMIC_DECLARE(uint64_t, st_memuse); - -/* stream engine running in "inline" mode. */ -int stream_inline = 0; - -void TmModuleStreamTcpRegister (void) -{ - tmm_modules[TMM_STREAMTCP].name = "StreamTcp"; - tmm_modules[TMM_STREAMTCP].ThreadInit = StreamTcpThreadInit; - tmm_modules[TMM_STREAMTCP].Func = StreamTcp; - tmm_modules[TMM_STREAMTCP].ThreadExitPrintStats = StreamTcpExitPrintStats; - tmm_modules[TMM_STREAMTCP].ThreadDeinit = StreamTcpThreadDeinit; - tmm_modules[TMM_STREAMTCP].RegisterTests = StreamTcpRegisterTests; - tmm_modules[TMM_STREAMTCP].cap_flags = 0; - tmm_modules[TMM_STREAMTCP].flags = TM_FLAG_STREAM_TM; -} - -void StreamTcpIncrMemuse(uint64_t size) -{ - (void) SC_ATOMIC_ADD(st_memuse, size); - return; -} - -void StreamTcpDecrMemuse(uint64_t size) -{ - (void) SC_ATOMIC_SUB(st_memuse, size); - return; -} - -uint64_t StreamTcpMemuseCounter(void) -{ - uint64_t memusecopy = SC_ATOMIC_GET(st_memuse); - return memusecopy; -} - -/** - * \brief Check if alloc'ing "size" would mean we're over memcap - * - * \retval 1 if in bounds - * \retval 0 if not in bounds - */ -int StreamTcpCheckMemcap(uint64_t size) -{ - if (stream_config.memcap == 0 || size + SC_ATOMIC_GET(st_memuse) <= stream_config.memcap) - return 1; - return 0; -} - -/** - * \brief Function to return the stream back to the pool. It returns the - * segments in the stream to the segment pool. - * - * This function is called when the flow is destroyed, so it should free - * *everything* related to the tcp session. So including the app layer - * data. We are guaranteed to only get here when the flow's use_cnt is 0. - * - * \param ssn Void ptr to the ssn. - */ -void StreamTcpSessionClear(void *ssnptr) -{ - SCEnter(); - StreamMsg *smsg = NULL; - TcpStateQueue *q, *q_next; - - TcpSession *ssn = (TcpSession *)ssnptr; - if (ssn == NULL) - SCReturn; - - StreamTcpReturnStreamSegments(&ssn->client); - StreamTcpReturnStreamSegments(&ssn->server); - - //AppLayerParserCleanupState(ssn); - - StreamTcpSackFreeList(&ssn->client); - StreamTcpSackFreeList(&ssn->server); - - /* if we have (a) smsg(s), return to the pool */ - smsg = ssn->toserver_smsg_head; - while(smsg != NULL) { - StreamMsg *smsg_next = smsg->next; - SCLogDebug("returning smsg %p to pool", smsg); - smsg->next = NULL; - smsg->prev = NULL; - StreamMsgReturnToPool(smsg); - smsg = smsg_next; - } - ssn->toserver_smsg_head = NULL; - - smsg = ssn->toclient_smsg_head; - while(smsg != NULL) { - StreamMsg *smsg_next = smsg->next; - SCLogDebug("returning smsg %p to pool", smsg); - smsg->next = NULL; - smsg->prev = NULL; - StreamMsgReturnToPool(smsg); - smsg = smsg_next; - } - ssn->toclient_smsg_head = NULL; - - q = ssn->queue; - while (q != NULL) { - q_next = q->next; - SCFree(q); - q = q_next; - StreamTcpDecrMemuse((uint64_t)sizeof(TcpStateQueue)); - } - ssn->queue = NULL; - ssn->queue_len = 0; - - memset(ssn, 0, sizeof(TcpSession)); - PoolThreadReturn(ssn_pool, ssn); -#ifdef DEBUG - SCMutexLock(&ssn_pool_mutex); - ssn_pool_cnt--; - SCMutexUnlock(&ssn_pool_mutex); -#endif - - SCReturn; -} - -/** - * \brief Function to return the stream segments back to the pool. - * - * We don't clear out the app layer storage here as that is under protection - * of the "use_cnt" reference counter in the flow. This function is called - * when the use_cnt is always at least 1 (this pkt has incremented the flow - * use_cnt itself), so we don't bother. - * - * \param p Packet used to identify the stream. - */ -void StreamTcpSessionPktFree (Packet *p) -{ - SCEnter(); - - TcpSession *ssn = (TcpSession *)p->flow->protoctx; - if (ssn == NULL) - SCReturn; - - StreamTcpReturnStreamSegments(&ssn->client); - StreamTcpReturnStreamSegments(&ssn->server); - - SCReturn; -} - -/** \brief Stream alloc function for the Pool - * \retval ptr void ptr to TcpSession structure with all vars set to 0/NULL - */ -void *StreamTcpSessionPoolAlloc() -{ - void *ptr = NULL; - - if (StreamTcpCheckMemcap((uint32_t)sizeof(TcpSession)) == 0) - return NULL; - - ptr = SCMalloc(sizeof(TcpSession)); - if (unlikely(ptr == NULL)) - return NULL; - - return ptr; -} - -int StreamTcpSessionPoolInit(void *data, void* initdata) -{ - memset(data, 0, sizeof(TcpSession)); - StreamTcpIncrMemuse((uint64_t)sizeof(TcpSession)); - - return 1; -} - -/** \brief Pool free function - * \param s Void ptr to TcpSession memory */ -void StreamTcpSessionPoolCleanup(void *s) -{ - StreamMsg *smsg = NULL; - TcpStateQueue *q, *q_next; - - if (s == NULL) - return; - - TcpSession *ssn = (TcpSession *)s; - - StreamTcpReturnStreamSegments(&ssn->client); - StreamTcpReturnStreamSegments(&ssn->server); - - /* if we have (a) smsg(s), return to the pool */ - smsg = ssn->toserver_smsg_head; - while(smsg != NULL) { - StreamMsg *smsg_next = smsg->next; - SCLogDebug("returning smsg %p to pool", smsg); - smsg->next = NULL; - smsg->prev = NULL; - StreamMsgReturnToPool(smsg); - smsg = smsg_next; - } - ssn->toserver_smsg_head = NULL; - - smsg = ssn->toclient_smsg_head; - while(smsg != NULL) { - StreamMsg *smsg_next = smsg->next; - SCLogDebug("returning smsg %p to pool", smsg); - smsg->next = NULL; - smsg->prev = NULL; - StreamMsgReturnToPool(smsg); - smsg = smsg_next; - } - ssn->toclient_smsg_head = NULL; - - q = ssn->queue; - while (q != NULL) { - q_next = q->next; - SCFree(q); - q = q_next; - StreamTcpDecrMemuse((uint64_t)sizeof(TcpStateQueue)); - } - ssn->queue = NULL; - ssn->queue_len = 0; - - StreamTcpDecrMemuse((uint64_t)sizeof(TcpSession)); -} - -/** \brief To initialize the stream global configuration data - * - * \param quiet It tells the mode of operation, if it is TRUE nothing will - * be get printed. - */ - -void StreamTcpInitConfig(char quiet) -{ - intmax_t value = 0; - uint16_t rdrange = 10; - - SCLogDebug("Initializing Stream"); - - memset(&stream_config, 0, sizeof(stream_config)); - - if ((ConfGetInt("stream.max-sessions", &value)) == 1) { - SCLogWarning(SC_WARN_OPTION_OBSOLETE, "max-sessions is obsolete. " - "Number of concurrent sessions is now only limited by Flow and " - "TCP stream engine memcaps."); - } - - if ((ConfGetInt("stream.prealloc-sessions", &value)) == 1) { - stream_config.prealloc_sessions = (uint32_t)value; - } else { - if (RunmodeIsUnittests()) { - stream_config.prealloc_sessions = 128; - } else { - stream_config.prealloc_sessions = STREAMTCP_DEFAULT_PREALLOC; - if (ConfGetNode("stream.prealloc-sessions") != NULL) { - WarnInvalidConfEntry("stream.prealloc_sessions", - "%"PRIu32, - stream_config.prealloc_sessions); - } - } - } - if (!quiet) { - SCLogInfo("stream \"prealloc-sessions\": %"PRIu32" (per thread)", - stream_config.prealloc_sessions); - } - - char *temp_stream_memcap_str; - if (ConfGet("stream.memcap", &temp_stream_memcap_str) == 1) { - if (ParseSizeStringU64(temp_stream_memcap_str, &stream_config.memcap) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing stream.memcap " - "from conf file - %s. Killing engine", - temp_stream_memcap_str); - exit(EXIT_FAILURE); - } - } else { - stream_config.memcap = STREAMTCP_DEFAULT_MEMCAP; - } - - if (!quiet) { - SCLogInfo("stream \"memcap\": %"PRIu64, stream_config.memcap); - } - - ConfGetBool("stream.midstream", &stream_config.midstream); - - if (!quiet) { - SCLogInfo("stream \"midstream\" session pickups: %s", stream_config.midstream ? "enabled" : "disabled"); - } - - ConfGetBool("stream.async-oneside", &stream_config.async_oneside); - - if (!quiet) { - SCLogInfo("stream \"async-oneside\": %s", stream_config.async_oneside ? "enabled" : "disabled"); - } - - int csum = 0; - - if ((ConfGetBool("stream.checksum-validation", &csum)) == 1) { - if (csum == 1) { - stream_config.flags |= STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION; - } - /* Default is that we validate the checksum of all the packets */ - } else { - stream_config.flags |= STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION; - } - - if (!quiet) { - SCLogInfo("stream \"checksum-validation\": %s", - stream_config.flags & STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION ? - "enabled" : "disabled"); - } - - int inl = 0; - - - char *temp_stream_inline_str; - if (ConfGet("stream.inline", &temp_stream_inline_str) == 1) { - /* checking for "auto" and falling back to boolean to provide - * backward compatibility */ - if (strcmp(temp_stream_inline_str, "auto") == 0) { - if (EngineModeIsIPS()) { - stream_inline = 1; - } else { - stream_inline = 0; - } - } else if (ConfGetBool("stream.inline", &inl) == 1) { - stream_inline = inl; - } - } - - if (!quiet) { - SCLogInfo("stream.\"inline\": %s", stream_inline ? "enabled" : "disabled"); - } - - if ((ConfGetInt("stream.max-synack-queued", &value)) == 1) { - if (value >= 0 && value <= 255) { - stream_config.max_synack_queued = (uint8_t)value; - } else { - stream_config.max_synack_queued = (uint8_t)STREAMTCP_DEFAULT_MAX_SYNACK_QUEUED; - } - } else { - stream_config.max_synack_queued = (uint8_t)STREAMTCP_DEFAULT_MAX_SYNACK_QUEUED; - } - if (!quiet) { - SCLogInfo("stream \"max-synack-queued\": %"PRIu8, stream_config.max_synack_queued); - } - - char *temp_stream_reassembly_memcap_str; - if (ConfGet("stream.reassembly.memcap", &temp_stream_reassembly_memcap_str) == 1) { - if (ParseSizeStringU64(temp_stream_reassembly_memcap_str, - &stream_config.reassembly_memcap) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing " - "stream.reassembly.memcap " - "from conf file - %s. Killing engine", - temp_stream_reassembly_memcap_str); - exit(EXIT_FAILURE); - } - } else { - stream_config.reassembly_memcap = STREAMTCP_DEFAULT_REASSEMBLY_MEMCAP; - } - - if (!quiet) { - SCLogInfo("stream.reassembly \"memcap\": %"PRIu64"", stream_config.reassembly_memcap); - } - - char *temp_stream_reassembly_depth_str; - if (ConfGet("stream.reassembly.depth", &temp_stream_reassembly_depth_str) == 1) { - if (ParseSizeStringU32(temp_stream_reassembly_depth_str, - &stream_config.reassembly_depth) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing " - "stream.reassembly.depth " - "from conf file - %s. Killing engine", - temp_stream_reassembly_depth_str); - exit(EXIT_FAILURE); - } - } else { - stream_config.reassembly_depth = 0; - } - - if (!quiet) { - SCLogInfo("stream.reassembly \"depth\": %"PRIu32"", stream_config.reassembly_depth); - } - - int randomize = 0; - if ((ConfGetBool("stream.reassembly.randomize-chunk-size", &randomize)) == 0) { - /* randomize by default if value not set - * In ut mode we disable, to get predictible test results */ - if (!(RunmodeIsUnittests())) - randomize = 1; - } - - if (randomize) { - char *temp_rdrange; - if (ConfGet("stream.reassembly.randomize-chunk-range", - &temp_rdrange) == 1) { - if (ParseSizeStringU16(temp_rdrange, &rdrange) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing " - "stream.reassembly.randomize-chunk-range " - "from conf file - %s. Killing engine", - temp_rdrange); - exit(EXIT_FAILURE); - } else if (rdrange >= 100) { - SCLogError(SC_ERR_INVALID_VALUE, - "stream.reassembly.randomize-chunk-range " - "must be lower than 100"); - exit(EXIT_FAILURE); - } - } - /* set a "random" seed */ - srandom(time(0)); - } - - char *temp_stream_reassembly_toserver_chunk_size_str; - if (ConfGet("stream.reassembly.toserver-chunk-size", - &temp_stream_reassembly_toserver_chunk_size_str) == 1) { - if (ParseSizeStringU16(temp_stream_reassembly_toserver_chunk_size_str, - &stream_config.reassembly_toserver_chunk_size) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing " - "stream.reassembly.toserver-chunk-size " - "from conf file - %s. Killing engine", - temp_stream_reassembly_toserver_chunk_size_str); - exit(EXIT_FAILURE); - } - } else { - stream_config.reassembly_toserver_chunk_size = - STREAMTCP_DEFAULT_TOSERVER_CHUNK_SIZE; - } - - if (randomize) { - stream_config.reassembly_toserver_chunk_size += - (int) (stream_config.reassembly_toserver_chunk_size * - (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); - } - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, - stream_config.reassembly_toserver_chunk_size); - - char *temp_stream_reassembly_toclient_chunk_size_str; - if (ConfGet("stream.reassembly.toclient-chunk-size", - &temp_stream_reassembly_toclient_chunk_size_str) == 1) { - if (ParseSizeStringU16(temp_stream_reassembly_toclient_chunk_size_str, - &stream_config.reassembly_toclient_chunk_size) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing " - "stream.reassembly.toclient-chunk-size " - "from conf file - %s. Killing engine", - temp_stream_reassembly_toclient_chunk_size_str); - exit(EXIT_FAILURE); - } - } else { - stream_config.reassembly_toclient_chunk_size = - STREAMTCP_DEFAULT_TOCLIENT_CHUNK_SIZE; - } - - if (randomize) { - stream_config.reassembly_toclient_chunk_size += - (int) (stream_config.reassembly_toclient_chunk_size * - (random() * 1.0 / RAND_MAX - 0.5) * rdrange / 100); - } - - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, - stream_config.reassembly_toclient_chunk_size); - - if (!quiet) { - SCLogInfo("stream.reassembly \"toserver-chunk-size\": %"PRIu16, - stream_config.reassembly_toserver_chunk_size); - SCLogInfo("stream.reassembly \"toclient-chunk-size\": %"PRIu16, - stream_config.reassembly_toclient_chunk_size); - } - - int enable_raw = 1; - if (ConfGetBool("stream.reassembly.raw", &enable_raw) == 1) { - if (!enable_raw) { - stream_config.ssn_init_flags = STREAMTCP_FLAG_DISABLE_RAW; - stream_config.segment_init_flags = SEGMENTTCP_FLAG_RAW_PROCESSED; - } - } else { - enable_raw = 1; - } - if (!quiet) - SCLogInfo("stream.reassembly.raw: %s", enable_raw ? "enabled" : "disabled"); - - /* init the memcap/use tracking */ - SC_ATOMIC_INIT(st_memuse); - StatsRegisterGlobalCounter("tcp.memuse", StreamTcpMemuseCounter); - - StreamTcpReassembleInit(quiet); - - /* set the default free function and flow state function - * values. */ - FlowSetProtoFreeFunc(IPPROTO_TCP, StreamTcpSessionClear); - -#ifdef UNITTESTS - if (RunmodeIsUnittests()) { - SCMutexLock(&ssn_pool_mutex); - if (ssn_pool == NULL) { - ssn_pool = PoolThreadInit(1, /* thread */ - 0, /* unlimited */ - stream_config.prealloc_sessions, - sizeof(TcpSession), - StreamTcpSessionPoolAlloc, - StreamTcpSessionPoolInit, NULL, - StreamTcpSessionPoolCleanup, NULL); - } - SCMutexUnlock(&ssn_pool_mutex); - } -#endif -} - -void StreamTcpFreeConfig(char quiet) -{ - StreamTcpReassembleFree(quiet); - - SCMutexLock(&ssn_pool_mutex); - if (ssn_pool != NULL) { - PoolThreadFree(ssn_pool); - ssn_pool = NULL; - } - SCMutexUnlock(&ssn_pool_mutex); - SCMutexDestroy(&ssn_pool_mutex); - - SCLogDebug("ssn_pool_cnt %"PRIu64"", ssn_pool_cnt); -} - -/** \brief The function is used to to fetch a TCP session from the - * ssn_pool, when a TCP SYN is received. - * - * \param quiet Packet P, which has been recieved for the new TCP session. - * - * \retval TcpSession A new TCP session with field initilaized to 0/NULL. - */ -TcpSession *StreamTcpNewSession (Packet *p, int id) -{ - TcpSession *ssn = (TcpSession *)p->flow->protoctx; - - if (ssn == NULL) { - p->flow->protoctx = PoolThreadGetById(ssn_pool, id); -#ifdef DEBUG - SCMutexLock(&ssn_pool_mutex); - if (p->flow->protoctx != NULL) - ssn_pool_cnt++; - SCMutexUnlock(&ssn_pool_mutex); -#endif - - ssn = (TcpSession *)p->flow->protoctx; - if (ssn == NULL) { - SCLogDebug("ssn_pool is empty"); - return NULL; - } - - ssn->state = TCP_NONE; - ssn->flags = stream_config.ssn_init_flags; - ssn->tcp_packet_flags = p->tcph ? p->tcph->th_flags : 0; - - if (PKT_IS_TOSERVER(p)) { - ssn->client.tcp_flags = p->tcph ? p->tcph->th_flags : 0; - ssn->server.tcp_flags = 0; - } else if (PKT_IS_TOCLIENT(p)) { - ssn->server.tcp_flags = p->tcph ? p->tcph->th_flags : 0; - ssn->client.tcp_flags = 0; - } - } - - return ssn; -} - -static void StreamTcpPacketSetState(Packet *p, TcpSession *ssn, - uint8_t state) -{ - if (state == ssn->state || PKT_IS_PSEUDOPKT(p)) - return; - - ssn->state = state; - - /* update the flow state */ - switch(ssn->state) { - case TCP_ESTABLISHED: - case TCP_FIN_WAIT1: - case TCP_FIN_WAIT2: - case TCP_CLOSING: - case TCP_CLOSE_WAIT: - SC_ATOMIC_SET(p->flow->flow_state, FLOW_STATE_ESTABLISHED); - break; - case TCP_LAST_ACK: - case TCP_TIME_WAIT: - case TCP_CLOSED: - SC_ATOMIC_SET(p->flow->flow_state, FLOW_STATE_CLOSED); - break; - } -} - -/** - * \brief Function to set the OS policy for the given stream based on the - * destination of the received packet. - * - * \param stream TcpStream of which os_policy needs to set - * \param p Packet which is used to set the os policy - */ -void StreamTcpSetOSPolicy(TcpStream *stream, Packet *p) -{ - int ret = 0; - - if (PKT_IS_IPV4(p)) { - /* Get the OS policy based on destination IP address, as destination - OS will decide how to react on the anomalies of newly received - packets */ - ret = SCHInfoGetIPv4HostOSFlavour((uint8_t *)GET_IPV4_DST_ADDR_PTR(p)); - if (ret > 0) - stream->os_policy = ret; - else - stream->os_policy = OS_POLICY_DEFAULT; - - } else if (PKT_IS_IPV6(p)) { - /* Get the OS policy based on destination IP address, as destination - OS will decide how to react on the anomalies of newly received - packets */ - ret = SCHInfoGetIPv6HostOSFlavour((uint8_t *)GET_IPV6_DST_ADDR(p)); - if (ret > 0) - stream->os_policy = ret; - else - stream->os_policy = OS_POLICY_DEFAULT; - } - - if (stream->os_policy == OS_POLICY_BSD_RIGHT) - stream->os_policy = OS_POLICY_BSD; - else if (stream->os_policy == OS_POLICY_OLD_SOLARIS) - stream->os_policy = OS_POLICY_SOLARIS; - - SCLogDebug("Policy is %"PRIu8"", stream->os_policy); - -} - -/** - * \brief get the size of a stream - * - * \note this just calculates the diff between isn and last_ack - * and will not consider sequence wrap arounds (streams - * bigger than 4gb). - * - * \retval size stream size - */ -uint32_t StreamTcpGetStreamSize(TcpStream *stream) -{ - return (stream->last_ack - stream->isn - 1); -} - -/** - * \brief macro to update last_ack only if the new value is higher - * - * \param ssn session - * \param stream stream to update - * \param ack ACK value to test and set - */ -#define StreamTcpUpdateLastAck(ssn, stream, ack) { \ - if (SEQ_GT((ack), (stream)->last_ack)) \ - { \ - SCLogDebug("ssn %p: last_ack set to %"PRIu32", moved %u forward", (ssn), (ack), (ack) - (stream)->last_ack); \ - if ((SEQ_LEQ((stream)->last_ack, (stream)->next_seq) && SEQ_GT((ack),(stream)->next_seq))) { \ - SCLogDebug("last_ack just passed next_seq: %u (was %u) > %u", (ack), (stream)->last_ack, (stream)->next_seq); \ - } else { \ - SCLogDebug("next_seq (%u) <> last_ack now %d", (stream)->next_seq, (int)(stream)->next_seq - (ack)); \ - }\ - (stream)->last_ack = (ack); \ - StreamTcpSackPruneList((stream)); \ - } else { \ - SCLogDebug("ssn %p: no update: ack %u, last_ack %"PRIu32", next_seq %u (state %u)", \ - (ssn), (ack), (stream)->last_ack, (stream)->next_seq, (ssn)->state); \ - }\ -} - -/** - * \brief macro to update next_win only if the new value is higher - * - * \param ssn session - * \param stream stream to update - * \param win window value to test and set - */ -#define StreamTcpUpdateNextWin(ssn, stream, win) { \ - uint32_t sacked_size__ = StreamTcpSackedSize((stream)); \ - if (SEQ_GT(((win) + sacked_size__), (stream)->next_win)) { \ - (stream)->next_win = ((win) + sacked_size__); \ - SCLogDebug("ssn %p: next_win set to %"PRIu32, (ssn), (stream)->next_win); \ - } \ -} - -static int StreamTcpPacketIsRetransmission(TcpStream *stream, Packet *p) -{ - if (p->payload_len == 0) - SCReturnInt(0); - - /* retransmission of already partially ack'd data */ - if (SEQ_LT(TCP_GET_SEQ(p), stream->last_ack) && SEQ_GT((TCP_GET_SEQ(p) + p->payload_len), stream->last_ack)) - { - StreamTcpSetEvent(p, STREAM_PKT_RETRANSMISSION); - SCReturnInt(1); - } - - /* retransmission of already ack'd data */ - if (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), stream->last_ack)) { - StreamTcpSetEvent(p, STREAM_PKT_RETRANSMISSION); - SCReturnInt(1); - } - - /* retransmission of in flight data */ - if (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), stream->next_seq)) { - StreamTcpSetEvent(p, STREAM_PKT_RETRANSMISSION); - SCReturnInt(2); - } - - SCLogDebug("seq %u payload_len %u => %u, last_ack %u, next_seq %u", TCP_GET_SEQ(p), - p->payload_len, (TCP_GET_SEQ(p) + p->payload_len), stream->last_ack, stream->next_seq); - SCReturnInt(0); -} - -/** - * \internal - * \brief Function to handle the TCP_CLOSED or NONE state. The function handles - * packets while the session state is None which means a newly - * initialized structure, or a fully closed session. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - * - * \retval 0 ok - * \retval -1 error - */ -static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - if (p->tcph->th_flags & TH_RST) { - StreamTcpSetEvent(p, STREAM_RST_BUT_NO_SESSION); - SCLogDebug("RST packet received, no session setup"); - return -1; - - } else if (p->tcph->th_flags & TH_FIN) { - StreamTcpSetEvent(p, STREAM_FIN_BUT_NO_SESSION); - SCLogDebug("FIN packet received, no session setup"); - return -1; - - /* SYN/ACK */ - } else if ((p->tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { - if (stream_config.midstream == FALSE && - stream_config.async_oneside == FALSE) - return 0; - - if (ssn == NULL) { - ssn = StreamTcpNewSession(p, stt->ssn_pool_id); - if (ssn == NULL) { - StatsIncr(tv, stt->counter_tcp_ssn_memcap); - return -1; - } - StatsIncr(tv, stt->counter_tcp_sessions); - } - /* set the state */ - StreamTcpPacketSetState(p, ssn, TCP_SYN_RECV); - SCLogDebug("ssn %p: =~ midstream picked ssn state is now " - "TCP_SYN_RECV", ssn); - ssn->flags |= STREAMTCP_FLAG_MIDSTREAM; - /* Flag used to change the direct in the later stage in the session */ - ssn->flags |= STREAMTCP_FLAG_MIDSTREAM_SYNACK; - - /* sequence number & window */ - ssn->server.isn = TCP_GET_SEQ(p); - STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); - ssn->server.next_seq = ssn->server.isn + 1; - ssn->server.window = TCP_GET_WINDOW(p); - SCLogDebug("ssn %p: server window %u", ssn, ssn->server.window); - - ssn->client.isn = TCP_GET_ACK(p) - 1; - STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn); - ssn->client.next_seq = ssn->client.isn + 1; - - ssn->client.last_ack = TCP_GET_ACK(p); - ssn->server.last_ack = TCP_GET_SEQ(p); - - ssn->server.next_win = ssn->server.last_ack + ssn->server.window; - - /** If the client has a wscale option the server had it too, - * so set the wscale for the server to max. Otherwise none - * will have the wscale opt just like it should. */ - if (p->tcpvars.ws != NULL) { - ssn->client.wscale = TCP_GET_WSCALE(p); - ssn->server.wscale = TCP_WSCALE_MAX; - } - - SCLogDebug("ssn %p: ssn->client.isn %"PRIu32", ssn->client.next_seq" - " %"PRIu32", ssn->client.last_ack %"PRIu32"", ssn, - ssn->client.isn, ssn->client.next_seq, - ssn->client.last_ack); - SCLogDebug("ssn %p: ssn->server.isn %"PRIu32", ssn->server.next_seq" - " %"PRIu32", ssn->server.last_ack %"PRIu32"", ssn, - ssn->server.isn, ssn->server.next_seq, - ssn->server.last_ack); - - /* Set the timestamp value for both streams, if packet has timestamp - * option enabled.*/ - if (p->tcpvars.ts != NULL) { - ssn->server.last_ts = TCP_GET_TSVAL(p); - ssn->client.last_ts = TCP_GET_TSECR(p); - SCLogDebug("ssn %p: ssn->server.last_ts %" PRIu32" " - "ssn->client.last_ts %" PRIu32"", ssn, - ssn->server.last_ts, ssn->client.last_ts); - - ssn->flags |= STREAMTCP_FLAG_TIMESTAMP; - - ssn->server.last_pkt_ts = p->ts.tv_sec; - if (ssn->server.last_ts == 0) - ssn->server.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - if (ssn->client.last_ts == 0) - ssn->client.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - - } else { - ssn->server.last_ts = 0; - ssn->client.last_ts = 0; - } - - if (TCP_GET_SACKOK(p) == 1) { - ssn->flags |= STREAMTCP_FLAG_SACKOK; - SCLogDebug("ssn %p: SYN/ACK with SACK permitted, assuming " - "SACK permitted for both sides", ssn); - } - - /* packet thinks it is in the wrong direction, flip it */ - StreamTcpPacketSwitchDir(ssn, p); - - } else if (p->tcph->th_flags & TH_SYN) { - if (ssn == NULL) { - ssn = StreamTcpNewSession(p, stt->ssn_pool_id); - if (ssn == NULL) { - StatsIncr(tv, stt->counter_tcp_ssn_memcap); - return -1; - } - - StatsIncr(tv, stt->counter_tcp_sessions); - } - - /* set the state */ - StreamTcpPacketSetState(p, ssn, TCP_SYN_SENT); - SCLogDebug("ssn %p: =~ ssn state is now TCP_SYN_SENT", ssn); - - /* set the sequence numbers and window */ - ssn->client.isn = TCP_GET_SEQ(p); - STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn); - ssn->client.next_seq = ssn->client.isn + 1; - - /* Set the stream timestamp value, if packet has timestamp option - * enabled. */ - if (p->tcpvars.ts != NULL) { - ssn->client.last_ts = TCP_GET_TSVAL(p); - SCLogDebug("ssn %p: p->tcpvars.ts %p, %02x", ssn, p->tcpvars.ts, - ssn->client.last_ts); - - if (ssn->client.last_ts == 0) - ssn->client.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - - ssn->client.last_pkt_ts = p->ts.tv_sec; - ssn->client.flags |= STREAMTCP_STREAM_FLAG_TIMESTAMP; - } - - ssn->server.window = TCP_GET_WINDOW(p); - if (p->tcpvars.ws != NULL) { - ssn->flags |= STREAMTCP_FLAG_SERVER_WSCALE; - ssn->server.wscale = TCP_GET_WSCALE(p); - } - - if (TCP_GET_SACKOK(p) == 1) { - ssn->flags |= STREAMTCP_FLAG_CLIENT_SACKOK; - SCLogDebug("ssn %p: SACK permited on SYN packet", ssn); - } - - SCLogDebug("ssn %p: ssn->client.isn %" PRIu32 ", " - "ssn->client.next_seq %" PRIu32 ", ssn->client.last_ack " - "%"PRIu32"", ssn, ssn->client.isn, ssn->client.next_seq, - ssn->client.last_ack); - - } else if (p->tcph->th_flags & TH_ACK) { - if (stream_config.midstream == FALSE) - return 0; - - if (ssn == NULL) { - ssn = StreamTcpNewSession(p, stt->ssn_pool_id); - if (ssn == NULL) { - StatsIncr(tv, stt->counter_tcp_ssn_memcap); - return -1; - } - StatsIncr(tv, stt->counter_tcp_sessions); - } - /* set the state */ - StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); - SCLogDebug("ssn %p: =~ midstream picked ssn state is now " - "TCP_ESTABLISHED", ssn); - - ssn->flags = STREAMTCP_FLAG_MIDSTREAM; - ssn->flags |= STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED; - - /** window scaling for midstream pickups, we can't do much other - * than assume that it's set to the max value: 14 */ - ssn->client.wscale = TCP_WSCALE_MAX; - ssn->server.wscale = TCP_WSCALE_MAX; - - /* set the sequence numbers and window */ - ssn->client.isn = TCP_GET_SEQ(p) - 1; - STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn); - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - ssn->client.last_ack = TCP_GET_SEQ(p); - ssn->client.next_win = ssn->client.last_ack + ssn->client.window; - SCLogDebug("ssn %p: ssn->client.isn %u, ssn->client.next_seq %u", - ssn, ssn->client.isn, ssn->client.next_seq); - - ssn->server.isn = TCP_GET_ACK(p) - 1; - STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); - ssn->server.next_seq = ssn->server.isn + 1; - ssn->server.last_ack = TCP_GET_ACK(p); - ssn->server.next_win = ssn->server.last_ack; - - SCLogDebug("ssn %p: ssn->client.next_win %"PRIu32", " - "ssn->server.next_win %"PRIu32"", ssn, - ssn->client.next_win, ssn->server.next_win); - SCLogDebug("ssn %p: ssn->client.last_ack %"PRIu32", " - "ssn->server.last_ack %"PRIu32"", ssn, - ssn->client.last_ack, ssn->server.last_ack); - - /* Set the timestamp value for both streams, if packet has timestamp - * option enabled.*/ - if (p->tcpvars.ts != NULL) { - ssn->client.last_ts = TCP_GET_TSVAL(p); - ssn->server.last_ts = TCP_GET_TSECR(p); - SCLogDebug("ssn %p: ssn->server.last_ts %" PRIu32" " - "ssn->client.last_ts %" PRIu32"", ssn, - ssn->server.last_ts, ssn->client.last_ts); - - ssn->flags |= STREAMTCP_FLAG_TIMESTAMP; - - ssn->client.last_pkt_ts = p->ts.tv_sec; - if (ssn->server.last_ts == 0) - ssn->server.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - if (ssn->client.last_ts == 0) - ssn->client.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - - } else { - ssn->server.last_ts = 0; - ssn->client.last_ts = 0; - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p, pq); - - ssn->flags |= STREAMTCP_FLAG_SACKOK; - SCLogDebug("ssn %p: assuming SACK permitted for both sides", ssn); - - } else { - SCLogDebug("default case"); - } - - return 0; -} - -/** \internal - * \brief Setup TcpStateQueue based on SYN/ACK packet - */ -static inline void StreamTcp3whsSynAckToStateQueue(Packet *p, TcpStateQueue *q) -{ - q->flags = 0; - q->wscale = 0; - q->ts = 0; - q->win = TCP_GET_WINDOW(p); - q->seq = TCP_GET_SEQ(p); - q->ack = TCP_GET_ACK(p); - q->pkt_ts = p->ts.tv_sec; - - if (TCP_GET_SACKOK(p) == 1) - q->flags |= STREAMTCP_QUEUE_FLAG_SACK; - - if (p->tcpvars.ws != NULL) { - q->flags |= STREAMTCP_QUEUE_FLAG_WS; - q->wscale = TCP_GET_WSCALE(p); - } - if (p->tcpvars.ts != NULL) { - q->flags |= STREAMTCP_QUEUE_FLAG_TS; - q->ts = TCP_GET_TSVAL(p); - } -} - -/** \internal - * \brief Find the Queued SYN/ACK that is the same as this SYN/ACK - * \retval q or NULL */ -TcpStateQueue *StreamTcp3whsFindSynAckBySynAck(TcpSession *ssn, Packet *p) -{ - TcpStateQueue *q = ssn->queue; - TcpStateQueue search; - - StreamTcp3whsSynAckToStateQueue(p, &search); - - while (q != NULL) { - if (search.flags == q->flags && - search.wscale == q->wscale && - search.win == q->win && - search.seq == q->seq && - search.ack == q->ack && - search.ts == q->ts) { - return q; - } - - q = q->next; - } - - return q; -} - -int StreamTcp3whsQueueSynAck(TcpSession *ssn, Packet *p) -{ - /* first see if this is already in our list */ - if (StreamTcp3whsFindSynAckBySynAck(ssn, p) != NULL) - return 0; - - if (ssn->queue_len == stream_config.max_synack_queued) { - SCLogDebug("ssn %p: =~ SYN/ACK queue limit reached", ssn); - StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_FLOOD); - return -1; - } - - if (StreamTcpCheckMemcap((uint32_t)sizeof(TcpStateQueue)) == 0) { - SCLogDebug("ssn %p: =~ SYN/ACK queue failed: stream memcap reached", ssn); - return -1; - } - - TcpStateQueue *q = SCMalloc(sizeof(*q)); - if (unlikely(q == NULL)) { - SCLogDebug("ssn %p: =~ SYN/ACK queue failed: alloc failed", ssn); - return -1; - } - memset(q, 0x00, sizeof(*q)); - StreamTcpIncrMemuse((uint64_t)sizeof(TcpStateQueue)); - - StreamTcp3whsSynAckToStateQueue(p, q); - - /* put in list */ - q->next = ssn->queue; - ssn->queue = q; - ssn->queue_len++; - return 0; -} - -/** \internal - * \brief Find the Queued SYN/ACK that goes with this ACK - * \retval q or NULL */ -TcpStateQueue *StreamTcp3whsFindSynAckByAck(TcpSession *ssn, Packet *p) -{ - uint32_t ack = TCP_GET_SEQ(p); - uint32_t seq = TCP_GET_ACK(p) - 1; - TcpStateQueue *q = ssn->queue; - - while (q != NULL) { - if (seq == q->seq && - ack == q->ack) { - return q; - } - - q = q->next; - } - - return NULL; -} - -/** \internal - * \brief Update SSN after receiving a valid SYN/ACK - * - * Normally we update the SSN from the SYN/ACK packet. But in case - * of queued SYN/ACKs, we can use one of those. - * - * \param ssn TCP session - * \param p Packet - * \param q queued state if used, NULL otherwise - * - * To make sure all SYN/ACK based state updates are in one place, - * this function can updated based on Packet or TcpStateQueue, where - * the latter takes precedence. - */ -static void StreamTcp3whsSynAckUpdate(TcpSession *ssn, Packet *p, TcpStateQueue *q) -{ - TcpStateQueue update; - if (likely(q == NULL)) { - StreamTcp3whsSynAckToStateQueue(p, &update); - q = &update; - } - - if (ssn->state != TCP_SYN_RECV) { - /* update state */ - StreamTcpPacketSetState(p, ssn, TCP_SYN_RECV); - SCLogDebug("ssn %p: =~ ssn state is now TCP_SYN_RECV", ssn); - } - /* sequence number & window */ - ssn->server.isn = q->seq; - STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); - ssn->server.next_seq = ssn->server.isn + 1; - - ssn->client.window = q->win; - SCLogDebug("ssn %p: window %" PRIu32 "", ssn, ssn->server.window); - - /* Set the timestamp values used to validate the timestamp of - * received packets.*/ - if ((q->flags & STREAMTCP_QUEUE_FLAG_TS) && - (ssn->client.flags & STREAMTCP_STREAM_FLAG_TIMESTAMP)) - { - ssn->server.last_ts = q->ts; - SCLogDebug("ssn %p: ssn->server.last_ts %" PRIu32" " - "ssn->client.last_ts %" PRIu32"", ssn, - ssn->server.last_ts, ssn->client.last_ts); - ssn->flags |= STREAMTCP_FLAG_TIMESTAMP; - ssn->server.last_pkt_ts = q->pkt_ts; - if (ssn->server.last_ts == 0) - ssn->server.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - } else { - ssn->client.last_ts = 0; - ssn->server.last_ts = 0; - ssn->client.flags &= ~STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - } - - ssn->client.last_ack = q->ack; - ssn->server.last_ack = ssn->server.isn + 1; - - /** check for the presense of the ws ptr to determine if we - * support wscale at all */ - if ((ssn->flags & STREAMTCP_FLAG_SERVER_WSCALE) && - (q->flags & STREAMTCP_QUEUE_FLAG_WS)) - { - ssn->client.wscale = q->wscale; - } else { - ssn->client.wscale = 0; - } - - if ((ssn->flags & STREAMTCP_FLAG_CLIENT_SACKOK) && - (q->flags & STREAMTCP_QUEUE_FLAG_SACK)) { - ssn->flags |= STREAMTCP_FLAG_SACKOK; - SCLogDebug("ssn %p: SACK permitted for session", ssn); - } else { - ssn->flags &= ~STREAMTCP_FLAG_SACKOK; - } - - ssn->server.next_win = ssn->server.last_ack + ssn->server.window; - ssn->client.next_win = ssn->client.last_ack + ssn->client.window; - SCLogDebug("ssn %p: ssn->server.next_win %" PRIu32 "", ssn, - ssn->server.next_win); - SCLogDebug("ssn %p: ssn->client.next_win %" PRIu32 "", ssn, - ssn->client.next_win); - SCLogDebug("ssn %p: ssn->server.isn %" PRIu32 ", " - "ssn->server.next_seq %" PRIu32 ", " - "ssn->server.last_ack %" PRIu32 " " - "(ssn->client.last_ack %" PRIu32 ")", ssn, - ssn->server.isn, ssn->server.next_seq, - ssn->server.last_ack, ssn->client.last_ack); - - /* unset the 4WHS flag as we received this SYN/ACK as part of a - * (so far) valid 3WHS */ - if (ssn->flags & STREAMTCP_FLAG_4WHS) - SCLogDebug("ssn %p: STREAMTCP_FLAG_4WHS unset, normal SYN/ACK" - " so considering 3WHS", ssn); - - ssn->flags &=~ STREAMTCP_FLAG_4WHS; -} - -/** - * \brief Function to handle the TCP_SYN_SENT state. The function handles - * SYN, SYN/ACK, RST packets and correspondingly changes the connection - * state. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - */ - -static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - if (ssn == NULL) - return -1; - - SCLogDebug("ssn %p: pkt received: %s", ssn, PKT_IS_TOCLIENT(p) ? - "toclient":"toserver"); - - /* RST */ - if (p->tcph->th_flags & TH_RST) { - if (!StreamTcpValidateRst(ssn, p)) - return -1; - - if (PKT_IS_TOSERVER(p)) { - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->client.isn) && - SEQ_EQ(TCP_GET_WINDOW(p), 0) && - SEQ_EQ(TCP_GET_ACK(p), (ssn->client.isn + 1))) - { - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received and state changed to " - "TCP_CLOSED", ssn); - } - } else { - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received and state changed to " - "TCP_CLOSED", ssn); - } - - /* FIN */ - } else if (p->tcph->th_flags & TH_FIN) { - /** \todo */ - - /* SYN/ACK */ - } else if ((p->tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { - if ((ssn->flags & STREAMTCP_FLAG_4WHS) && PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: SYN/ACK received on 4WHS session", ssn); - - /* Check if the SYN/ACK packet ack's the earlier - * received SYN packet. */ - if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->server.isn + 1))) { - StreamTcpSetEvent(p, STREAM_4WHS_SYNACK_WITH_WRONG_ACK); - - SCLogDebug("ssn %p: 4WHS ACK mismatch, packet ACK %"PRIu32"" - " != %" PRIu32 " from stream", ssn, - TCP_GET_ACK(p), ssn->server.isn + 1); - return -1; - } - - /* Check if the SYN/ACK packet SEQ's the *FIRST* received SYN - * packet. */ - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.isn))) { - StreamTcpSetEvent(p, STREAM_4WHS_SYNACK_WITH_WRONG_SYN); - - SCLogDebug("ssn %p: 4WHS SEQ mismatch, packet SEQ %"PRIu32"" - " != %" PRIu32 " from *first* SYN pkt", ssn, - TCP_GET_SEQ(p), ssn->client.isn); - return -1; - } - - - /* update state */ - StreamTcpPacketSetState(p, ssn, TCP_SYN_RECV); - SCLogDebug("ssn %p: =~ 4WHS ssn state is now TCP_SYN_RECV", ssn); - - /* sequence number & window */ - ssn->client.isn = TCP_GET_SEQ(p); - STREAMTCP_SET_RA_BASE_SEQ(&ssn->client, ssn->client.isn); - ssn->client.next_seq = ssn->client.isn + 1; - - ssn->server.window = TCP_GET_WINDOW(p); - SCLogDebug("ssn %p: 4WHS window %" PRIu32 "", ssn, - ssn->client.window); - - /* Set the timestamp values used to validate the timestamp of - * received packets. */ - if ((p->tcpvars.ts != NULL) && - (ssn->server.flags & STREAMTCP_STREAM_FLAG_TIMESTAMP)) - { - ssn->client.last_ts = TCP_GET_TSVAL(p); - SCLogDebug("ssn %p: 4WHS ssn->client.last_ts %" PRIu32" " - "ssn->server.last_ts %" PRIu32"", ssn, - ssn->client.last_ts, ssn->server.last_ts); - ssn->flags |= STREAMTCP_FLAG_TIMESTAMP; - ssn->client.last_pkt_ts = p->ts.tv_sec; - if (ssn->client.last_ts == 0) - ssn->client.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - } else { - ssn->server.last_ts = 0; - ssn->client.last_ts = 0; - ssn->server.flags &= ~STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - } - - ssn->server.last_ack = TCP_GET_ACK(p); - ssn->client.last_ack = ssn->client.isn + 1; - - /** check for the presense of the ws ptr to determine if we - * support wscale at all */ - if ((ssn->flags & STREAMTCP_FLAG_SERVER_WSCALE) && - (p->tcpvars.ws != NULL)) - { - ssn->server.wscale = TCP_GET_WSCALE(p); - } else { - ssn->server.wscale = 0; - } - - if ((ssn->flags & STREAMTCP_FLAG_CLIENT_SACKOK) && - TCP_GET_SACKOK(p) == 1) { - ssn->flags |= STREAMTCP_FLAG_SACKOK; - SCLogDebug("ssn %p: SACK permitted for 4WHS session", ssn); - } - - ssn->client.next_win = ssn->client.last_ack + ssn->client.window; - ssn->server.next_win = ssn->server.last_ack + ssn->server.window; - SCLogDebug("ssn %p: 4WHS ssn->client.next_win %" PRIu32 "", ssn, - ssn->client.next_win); - SCLogDebug("ssn %p: 4WHS ssn->server.next_win %" PRIu32 "", ssn, - ssn->server.next_win); - SCLogDebug("ssn %p: 4WHS ssn->client.isn %" PRIu32 ", " - "ssn->client.next_seq %" PRIu32 ", " - "ssn->client.last_ack %" PRIu32 " " - "(ssn->server.last_ack %" PRIu32 ")", ssn, - ssn->client.isn, ssn->client.next_seq, - ssn->client.last_ack, ssn->server.last_ack); - - /* done here */ - return 0; - } - - if (PKT_IS_TOSERVER(p)) { - StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_IN_WRONG_DIRECTION); - SCLogDebug("ssn %p: SYN/ACK received in the wrong direction", ssn); - return -1; - } - - /* Check if the SYN/ACK packet ack's the earlier - * received SYN packet. */ - if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->client.isn + 1))) { - StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_WITH_WRONG_ACK); - SCLogDebug("ssn %p: ACK mismatch, packet ACK %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p), - ssn->client.isn + 1); - return -1; - } - - StreamTcp3whsSynAckUpdate(ssn, p, /* no queue override */NULL); - - } else if (p->tcph->th_flags & TH_SYN) { - SCLogDebug("ssn %p: SYN packet on state SYN_SENT... resent", ssn); - if (ssn->flags & STREAMTCP_FLAG_4WHS) { - SCLogDebug("ssn %p: SYN packet on state SYN_SENT... resent of " - "4WHS SYN", ssn); - } - - if (PKT_IS_TOCLIENT(p)) { - /** a SYN only packet in the opposite direction could be: - * http://www.breakingpointsystems.com/community/blog/tcp- - * portals-the-three-way-handshake-is-a-lie - * - * \todo improve resetting the session */ - - /* indicate that we're dealing with 4WHS here */ - ssn->flags |= STREAMTCP_FLAG_4WHS; - SCLogDebug("ssn %p: STREAMTCP_FLAG_4WHS flag set", ssn); - - /* set the sequence numbers and window for server - * We leave the ssn->client.isn in place as we will - * check the SYN/ACK pkt with that. - */ - ssn->server.isn = TCP_GET_SEQ(p); - STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); - ssn->server.next_seq = ssn->server.isn + 1; - - /* Set the stream timestamp value, if packet has timestamp - * option enabled. */ - if (p->tcpvars.ts != NULL) { - ssn->server.last_ts = TCP_GET_TSVAL(p); - SCLogDebug("ssn %p: p->tcpvars.ts %p, %02x", ssn, - p->tcpvars.ts, ssn->server.last_ts); - - if (ssn->server.last_ts == 0) - ssn->server.flags |= STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - ssn->server.last_pkt_ts = p->ts.tv_sec; - ssn->server.flags |= STREAMTCP_STREAM_FLAG_TIMESTAMP; - } - - ssn->server.window = TCP_GET_WINDOW(p); - if (p->tcpvars.ws != NULL) { - ssn->flags |= STREAMTCP_FLAG_SERVER_WSCALE; - ssn->server.wscale = TCP_GET_WSCALE(p); - } else { - ssn->flags &= ~STREAMTCP_FLAG_SERVER_WSCALE; - ssn->server.wscale = 0; - } - - if (TCP_GET_SACKOK(p) == 1) { - ssn->flags |= STREAMTCP_FLAG_CLIENT_SACKOK; - } else { - ssn->flags &= ~STREAMTCP_FLAG_CLIENT_SACKOK; - } - - SCLogDebug("ssn %p: 4WHS ssn->server.isn %" PRIu32 ", " - "ssn->server.next_seq %" PRIu32 ", " - "ssn->server.last_ack %"PRIu32"", ssn, - ssn->server.isn, ssn->server.next_seq, - ssn->server.last_ack); - SCLogDebug("ssn %p: 4WHS ssn->client.isn %" PRIu32 ", " - "ssn->client.next_seq %" PRIu32 ", " - "ssn->client.last_ack %"PRIu32"", ssn, - ssn->client.isn, ssn->client.next_seq, - ssn->client.last_ack); - } - - /** \todo check if it's correct or set event */ - - } else if (p->tcph->th_flags & TH_ACK) { - /* Handle the asynchronous stream, when we receive a SYN packet - and now istead of receving a SYN/ACK we receive a ACK from the - same host, which sent the SYN, this suggests the ASNYC streams.*/ - if (stream_config.async_oneside == FALSE) - return 0; - - /* we are in AYNC (one side) mode now. */ - - /* one side async means we won't see a SYN/ACK, so we can - * only check the SYN. */ - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq))) { - StreamTcpSetEvent(p, STREAM_3WHS_ASYNC_WRONG_SEQ); - - SCLogDebug("ssn %p: SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream",ssn, TCP_GET_SEQ(p), - ssn->client.next_seq); - return -1; - } - - ssn->flags |= STREAMTCP_FLAG_ASYNC; - StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); - SCLogDebug("ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn); - - ssn->client.window = TCP_GET_WINDOW(p); - ssn->client.last_ack = TCP_GET_SEQ(p); - ssn->client.next_win = ssn->client.last_ack + ssn->client.window; - - /* Set the server side parameters */ - ssn->server.isn = TCP_GET_ACK(p) - 1; - STREAMTCP_SET_RA_BASE_SEQ(&ssn->server, ssn->server.isn); - ssn->server.next_seq = ssn->server.isn + 1; - ssn->server.last_ack = ssn->server.next_seq; - ssn->server.next_win = ssn->server.last_ack; - - SCLogDebug("ssn %p: synsent => Asynchronous stream, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->client.next_seq %" PRIu32 "" - ,ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) - + p->payload_len, ssn->client.next_seq); - - /* if SYN had wscale, assume it to be supported. Otherwise - * we know it not to be supported. */ - if (ssn->flags & STREAMTCP_FLAG_SERVER_WSCALE) { - ssn->client.wscale = TCP_WSCALE_MAX; - } - - /* Set the timestamp values used to validate the timestamp of - * received packets.*/ - if (p->tcpvars.ts != NULL && - (ssn->client.flags & STREAMTCP_STREAM_FLAG_TIMESTAMP)) - { - ssn->flags |= STREAMTCP_FLAG_TIMESTAMP; - ssn->client.flags &= ~STREAMTCP_STREAM_FLAG_TIMESTAMP; - ssn->client.last_pkt_ts = p->ts.tv_sec; - } else { - ssn->client.last_ts = 0; - ssn->client.flags &= ~STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - } - - if (ssn->flags & STREAMTCP_FLAG_CLIENT_SACKOK) { - ssn->flags |= STREAMTCP_FLAG_SACKOK; - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - - } else { - SCLogDebug("ssn %p: default case", ssn); - } - - return 0; -} - -/** - * \brief Function to handle the TCP_SYN_RECV state. The function handles - * SYN, SYN/ACK, ACK, FIN, RST packets and correspondingly changes - * the connection state. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - * - * \retval 0 ok - * \retval -1 error - */ - -static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - if (ssn == NULL) - return -1; - - if (p->tcph->th_flags & TH_RST) { - if (!StreamTcpValidateRst(ssn, p)) - return -1; - - uint8_t reset = TRUE; - /* After receiveing the RST in SYN_RECV state and if detection - evasion flags has been set, then the following operating - systems will not closed the connection. As they consider the - packet as stray packet and not belonging to the current - session, for more information check - http://www.packetstan.com/2010/06/recently-ive-been-on-campaign-to-make.html */ - if (ssn->flags & STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT) { - if (PKT_IS_TOSERVER(p)) { - if ((ssn->server.os_policy == OS_POLICY_LINUX) || - (ssn->server.os_policy == OS_POLICY_OLD_LINUX) || - (ssn->server.os_policy == OS_POLICY_SOLARIS)) - { - reset = FALSE; - SCLogDebug("Detection evasion has been attempted, so" - " not resetting the connection !!"); - } - } else { - if ((ssn->client.os_policy == OS_POLICY_LINUX) || - (ssn->client.os_policy == OS_POLICY_OLD_LINUX) || - (ssn->client.os_policy == OS_POLICY_SOLARIS)) - { - reset = FALSE; - SCLogDebug("Detection evasion has been attempted, so" - " not resetting the connection !!"); - } - } - } - - if (reset == TRUE) { - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received and state changed to " - "TCP_CLOSED", ssn); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - } - - } else if (p->tcph->th_flags & TH_FIN) { - /* FIN is handled in the same way as in TCP_ESTABLISHED case */; - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if ((StreamTcpHandleFin(tv, stt, ssn, p, pq)) == -1) - return -1; - - /* SYN/ACK */ - } else if ((p->tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { - SCLogDebug("ssn %p: SYN/ACK packet on state SYN_RECV. resent", ssn); - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: SYN/ACK-pkt to server in SYN_RECV state", ssn); - - StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_TOSERVER_ON_SYN_RECV); - return -1; - } - - /* Check if the SYN/ACK packets ACK matches the earlier - * received SYN/ACK packet. */ - if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack))) { - SCLogDebug("ssn %p: ACK mismatch, packet ACK %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p), - ssn->client.isn + 1); - - StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_RESEND_WITH_DIFFERENT_ACK); - return -1; - } - - /* Check if the SYN/ACK packet SEQ the earlier - * received SYN/ACK packet, server resend with different ISN. */ - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->server.isn))) { - SCLogDebug("ssn %p: SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_SEQ(p), - ssn->client.isn); - - if (StreamTcp3whsQueueSynAck(ssn, p) == -1) - return -1; - SCLogDebug("ssn %p: queued different SYN/ACK", ssn); - } - - } else if (p->tcph->th_flags & TH_SYN) { - SCLogDebug("ssn %p: SYN packet on state SYN_RECV... resent", ssn); - - if (PKT_IS_TOCLIENT(p)) { - SCLogDebug("ssn %p: SYN-pkt to client in SYN_RECV state", ssn); - - StreamTcpSetEvent(p, STREAM_3WHS_SYN_TOCLIENT_ON_SYN_RECV); - return -1; - } - - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.isn))) { - SCLogDebug("ssn %p: SYN with different SEQ on SYN_RECV state", ssn); - - StreamTcpSetEvent(p, STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV); - return -1; - } - - } else if (p->tcph->th_flags & TH_ACK) { - if (ssn->queue_len) { - SCLogDebug("ssn %p: checking ACK against queued SYN/ACKs", ssn); - TcpStateQueue *q = StreamTcp3whsFindSynAckByAck(ssn, p); - if (q != NULL) { - SCLogDebug("ssn %p: here we update state against queued SYN/ACK", ssn); - StreamTcp3whsSynAckUpdate(ssn, p, /* using queue to update state */q); - } else { - SCLogDebug("ssn %p: none found, now checking ACK against original SYN/ACK (state)", ssn); - } - } - - - /* If the timestamp option is enabled for both the streams, then - * validate the received packet timestamp value against the - * stream->last_ts. If the timestamp is valid then process the - * packet normally otherwise the drop the packet (RFC 1323)*/ - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!(StreamTcpValidateTimestamp(ssn, p))) { - return -1; - } - } - - if ((ssn->flags & STREAMTCP_FLAG_4WHS) && PKT_IS_TOCLIENT(p)) { - SCLogDebug("ssn %p: ACK received on 4WHS session",ssn); - - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq))) { - SCLogDebug("ssn %p: 4WHS wrong seq nr on packet", ssn); - StreamTcpSetEvent(p, STREAM_4WHS_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: 4WHS invalid ack nr on packet", ssn); - StreamTcpSetEvent(p, STREAM_4WHS_INVALID_ACK); - return -1; - } - - SCLogDebug("4WHS normal pkt"); - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - ssn->server.next_seq += p->payload_len; - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - ssn->client.next_win = ssn->client.last_ack + ssn->client.window; - - StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); - SCLogDebug("ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - - SCLogDebug("ssn %p: ssn->client.next_win %" PRIu32 ", " - "ssn->client.last_ack %"PRIu32"", ssn, - ssn->client.next_win, ssn->client.last_ack); - return 0; - } - - /* Check if the ACK received is in right direction. But when we have - * picked up a mid stream session after missing the initial SYN pkt, - * in this case the ACK packet can arrive from either client (normal - * case) or from server itself (asynchronous streams). Therefore - * the check has been avoided in this case */ - if (PKT_IS_TOCLIENT(p)) { - /* special case, handle 4WHS, so SYN/ACK in the opposite - * direction */ - if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM_SYNACK) { - SCLogDebug("ssn %p: ACK received on midstream SYN/ACK " - "pickup session",ssn); - /* fall through */ - } else { - SCLogDebug("ssn %p: ACK received in the wrong direction", - ssn); - - StreamTcpSetEvent(p, STREAM_3WHS_ACK_IN_WRONG_DIR); - return -1; - } - } - - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ %" PRIu32 "" - ", ACK %" PRIu32 "", ssn, p->payload_len, TCP_GET_SEQ(p), - TCP_GET_ACK(p)); - - /* Check both seq and ack number before accepting the packet and - changing to ESTABLISHED state */ - if ((SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq)) && - SEQ_EQ(TCP_GET_ACK(p), ssn->server.next_seq)) { - SCLogDebug("normal pkt"); - - /* process the packet normal, No Async streams :) */ - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - ssn->client.next_seq += p->payload_len; - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - - ssn->server.next_win = ssn->server.last_ack + ssn->server.window; - - if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) { - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - ssn->client.next_win = ssn->client.last_ack + ssn->client.window; - ssn->server.next_win = ssn->server.last_ack + - ssn->server.window; - if (!(ssn->flags & STREAMTCP_FLAG_MIDSTREAM_SYNACK)) { - /* window scaling for midstream pickups, we can't do much - * other than assume that it's set to the max value: 14 */ - ssn->server.wscale = TCP_WSCALE_MAX; - ssn->client.wscale = TCP_WSCALE_MAX; - ssn->flags |= STREAMTCP_FLAG_SACKOK; - } - } - - StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); - SCLogDebug("ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - - /* If asynchronous stream handling is allowed then set the session, - if packet's seq number is equal the expected seq no.*/ - } else if (stream_config.async_oneside == TRUE && - (SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq))) - { - /*set the ASYNC flag used to indicate the session as async stream - and helps in relaxing the windows checks.*/ - ssn->flags |= STREAMTCP_FLAG_ASYNC; - ssn->server.next_seq += p->payload_len; - ssn->server.last_ack = TCP_GET_SEQ(p); - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - ssn->client.last_ack = TCP_GET_ACK(p); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) { - ssn->server.window = TCP_GET_WINDOW(p); - ssn->client.next_win = ssn->server.last_ack + - ssn->server.window; - /* window scaling for midstream pickups, we can't do much - * other than assume that it's set to the max value: 14 */ - ssn->server.wscale = TCP_WSCALE_MAX; - ssn->client.wscale = TCP_WSCALE_MAX; - ssn->flags |= STREAMTCP_FLAG_SACKOK; - } - - SCLogDebug("ssn %p: synrecv => Asynchronous stream, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->server.next_seq %" PRIu32 "\n" - , ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) - + p->payload_len, ssn->server.next_seq); - - StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); - SCLogDebug("ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - /* Upon receiving the packet with correct seq number and wrong - ACK number, it causes the other end to send RST. But some target - system (Linux & solaris) does not RST the connection, so it is - likely to avoid the detection */ - } else if (SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq)){ - ssn->flags |= STREAMTCP_FLAG_DETECTION_EVASION_ATTEMPT; - SCLogDebug("ssn %p: wrong ack nr on packet, possible evasion!!", - ssn); - - StreamTcpSetEvent(p, STREAM_3WHS_RIGHT_SEQ_WRONG_ACK_EVASION); - return -1; - - /* if we get a packet with a proper ack, but a seq that is beyond - * next_seq but in-window, we probably missed some packets */ - } else if (SEQ_GT(TCP_GET_SEQ(p), ssn->client.next_seq) && - SEQ_LEQ(TCP_GET_SEQ(p),ssn->client.next_win) && - SEQ_EQ(TCP_GET_ACK(p), ssn->server.next_seq)) - { - SCLogDebug("ssn %p: ACK for missing data", ssn); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; - SCLogDebug("ssn %p: ACK for missing data: ssn->client.next_seq %u", ssn, ssn->client.next_seq); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - - ssn->server.next_win = ssn->server.last_ack + ssn->server.window; - - if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) { - ssn->client.window = TCP_GET_WINDOW(p); - ssn->server.next_win = ssn->server.last_ack + - ssn->server.window; - /* window scaling for midstream pickups, we can't do much - * other than assume that it's set to the max value: 14 */ - ssn->server.wscale = TCP_WSCALE_MAX; - ssn->client.wscale = TCP_WSCALE_MAX; - ssn->flags |= STREAMTCP_FLAG_SACKOK; - } - - StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); - SCLogDebug("ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - } else { - SCLogDebug("ssn %p: wrong seq nr on packet", ssn); - - StreamTcpSetEvent(p, STREAM_3WHS_WRONG_SEQ_WRONG_ACK); - return -1; - } - - SCLogDebug("ssn %p: ssn->server.next_win %" PRIu32 ", " - "ssn->server.last_ack %"PRIu32"", ssn, - ssn->server.next_win, ssn->server.last_ack); - } else { - SCLogDebug("ssn %p: default case", ssn); - } - - return 0; -} - -/** - * \brief Function to handle the TCP_ESTABLISHED state packets, which are - * sent by the client to server. The function handles - * ACK packets and call StreamTcpReassembleHandleSegment() to handle - * the reassembly. - * - * Timestamp has already been checked at this point. - * - * \param tv Thread Variable containig input/output queue, cpu affinity etc. - * \param ssn Pointer to the current TCP session - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - */ -static int HandleEstablishedPacketToServer(ThreadVars *tv, TcpSession *ssn, Packet *p, - StreamTcpThread *stt, PacketQueue *pq) -{ - SCLogDebug("ssn %p: =+ pkt (%" PRIu32 ") is to server: SEQ %" PRIu32 "," - "ACK %" PRIu32 ", WIN %"PRIu16"", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p), TCP_GET_WINDOW(p)); - - if (StreamTcpValidateAck(ssn, &(ssn->server), p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_EST_INVALID_ACK); - return -1; - } - - /* check for Keep Alive */ - if ((p->payload_len == 0 || p->payload_len == 1) && - (TCP_GET_SEQ(p) == (ssn->client.next_seq - 1))) { - SCLogDebug("ssn %p: pkt is keep alive", ssn); - - /* normal pkt */ - } else if (!(SEQ_GEQ((TCP_GET_SEQ(p)+p->payload_len), ssn->client.last_ack))) { - if (ssn->flags & STREAMTCP_FLAG_ASYNC) { - SCLogDebug("ssn %p: server => Asynchrouns stream, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," - " ssn->client.last_ack %" PRIu32 ", ssn->client.next_win" - "%" PRIu32"(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win); - - /* update the last_ack to current seq number as the session is - * async and other stream is not updating it anymore :( */ - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_SEQ(p)); - - } else if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p)) && - (stream_config.async_oneside == TRUE) && - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM)) { - SCLogDebug("ssn %p: server => Asynchronous stream, packet SEQ." - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win); - - /* it seems we missed SYN and SYN/ACK packets of this session. - * Update the last_ack to current seq number as the session - * is async and other stream is not updating it anymore :( */ - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_SEQ(p)); - ssn->flags |= STREAMTCP_FLAG_ASYNC; - - } else if (SEQ_EQ(ssn->client.last_ack, (ssn->client.isn + 1)) && - (stream_config.async_oneside == TRUE) && - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM)) { - SCLogDebug("ssn %p: server => Asynchronous stream, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win); - - /* it seems we missed SYN and SYN/ACK packets of this session. - * Update the last_ack to current seq number as the session - * is async and other stream is not updating it anymore :(*/ - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_SEQ(p)); - ssn->flags |= STREAMTCP_FLAG_ASYNC; - - /* if last ack is beyond next_seq, we have accepted ack's for missing data. - * In this case we do accept the data before last_ack if it is (partly) - * beyond next seq */ - } else if (SEQ_GT(ssn->client.last_ack, ssn->client.next_seq) && - SEQ_GT((TCP_GET_SEQ(p)+p->payload_len),ssn->client.next_seq)) - { - SCLogDebug("ssn %p: PKT SEQ %"PRIu32" payload_len %"PRIu16 - " before last_ack %"PRIu32", after next_seq %"PRIu32":" - " acked data that we haven't seen before", - ssn, TCP_GET_SEQ(p), p->payload_len, ssn->client.last_ack, ssn->client.next_seq); - if (SEQ_EQ(TCP_GET_SEQ(p),ssn->client.next_seq)) { - ssn->client.next_seq += p->payload_len; - } - } else { - SCLogDebug("ssn %p: server => SEQ before last_ack, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 "), " - "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->client.next_win); - - SCLogDebug("ssn %p: rejecting because pkt before last_ack", ssn); - StreamTcpSetEvent(p, STREAM_EST_PKT_BEFORE_LAST_ACK); - return -1; - } - } - - int zerowindowprobe = 0; - /* zero window probe */ - if (p->payload_len == 1 && TCP_GET_SEQ(p) == ssn->client.next_seq && ssn->client.window == 0) { - SCLogDebug("ssn %p: zero window probe", ssn); - zerowindowprobe = 1; - - /* expected packet */ - } else if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { - ssn->client.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->client.next_seq %" PRIu32 "", - ssn, ssn->client.next_seq); - /* not completely as expected, but valid */ - } else if (SEQ_LT(TCP_GET_SEQ(p),ssn->client.next_seq) && - SEQ_GT((TCP_GET_SEQ(p)+p->payload_len), ssn->client.next_seq)) - { - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; - SCLogDebug("ssn %p: ssn->client.next_seq %"PRIu32 - " (started before next_seq, ended after)", - ssn, ssn->client.next_seq); - /* if next_seq has fallen behind last_ack, we got some catching up to do */ - } else if (SEQ_LT(ssn->client.next_seq, ssn->client.last_ack)) { - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; - SCLogDebug("ssn %p: ssn->client.next_seq %"PRIu32 - " (next_seq had fallen behind last_ack)", - ssn, ssn->client.next_seq); - } else { - SCLogDebug("ssn %p: no update to ssn->client.next_seq %"PRIu32 - " SEQ %u SEQ+ %u last_ack %u", - ssn, ssn->client.next_seq, - TCP_GET_SEQ(p), TCP_GET_SEQ(p)+p->payload_len, ssn->client.last_ack); - } - - /* in window check */ - if (zerowindowprobe) { - SCLogDebug("ssn %p: zero window probe, skipping oow check", ssn); - } else if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) || - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || - (ssn->flags & STREAMTCP_FLAG_ASYNC)) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->client.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->client.next_win); - - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - SCLogDebug("ssn %p: ssn->server.window %"PRIu32"", ssn, - ssn->server.window); - - /* Check if the ACK value is sane and inside the window limit */ - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - SCLogDebug("ack %u last_ack %u next_seq %u", TCP_GET_ACK(p), ssn->server.last_ack, ssn->server.next_seq); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpSackUpdatePacket(&ssn->server, p); - - /* update next_win */ - StreamTcpUpdateNextWin(ssn, &ssn->server, (ssn->server.last_ack + ssn->server.window)); - - /* handle data (if any) */ - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p, pq); - } else { - SCLogDebug("ssn %p: toserver => SEQ out of window, packet SEQ " - "%" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," - "ssn->client.last_ack %" PRIu32 ", ssn->client.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->client.last_ack, ssn->client.next_win, - (TCP_GET_SEQ(p) + p->payload_len) - ssn->client.next_win); - SCLogDebug("ssn %p: window %u sacked %u", ssn, ssn->client.window, - StreamTcpSackedSize(&ssn->client)); - StreamTcpSetEvent(p, STREAM_EST_PACKET_OUT_OF_WINDOW); - return -1; - } - return 0; -} - -/** - * \brief Function to handle the TCP_ESTABLISHED state packets, which are - * sent by the server to client. The function handles - * ACK packets and call StreamTcpReassembleHandleSegment() to handle - * the reassembly - * - * Timestamp has already been checked at this point. - * - * \param tv Thread Variable containig input/output queue, cpu affinity etc. - * \param ssn Pointer to the current TCP session - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - */ -static int HandleEstablishedPacketToClient(ThreadVars *tv, TcpSession *ssn, Packet *p, - StreamTcpThread *stt, PacketQueue *pq) -{ - SCLogDebug("ssn %p: =+ pkt (%" PRIu32 ") is to client: SEQ %" PRIu32 "," - " ACK %" PRIu32 ", WIN %"PRIu16"", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p), TCP_GET_WINDOW(p)); - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_EST_INVALID_ACK); - return -1; - } - - /* To get the server window value from the servers packet, when connection - is picked up as midstream */ - if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) && - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED)) - { - ssn->server.window = TCP_GET_WINDOW(p); - ssn->server.next_win = ssn->server.last_ack + ssn->server.window; - ssn->flags &= ~STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED; - SCLogDebug("ssn %p: adjusted midstream ssn->server.next_win to " - "%" PRIu32 "", ssn, ssn->server.next_win); - } - - /* check for Keep Alive */ - if ((p->payload_len == 0 || p->payload_len == 1) && - (TCP_GET_SEQ(p) == (ssn->server.next_seq - 1))) { - SCLogDebug("ssn %p: pkt is keep alive", ssn); - - /* normal pkt */ - } else if (!(SEQ_GEQ((TCP_GET_SEQ(p)+p->payload_len), ssn->server.last_ack))) { - if (ssn->flags & STREAMTCP_FLAG_ASYNC) { - - SCLogDebug("ssn %p: client => Asynchrouns stream, packet SEQ" - " %" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," - " ssn->client.last_ack %" PRIu32 ", ssn->client.next_win" - " %"PRIu32"(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->server.last_ack, ssn->server.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->server.next_win); - - ssn->server.last_ack = TCP_GET_SEQ(p); - - /* if last ack is beyond next_seq, we have accepted ack's for missing data. - * In this case we do accept the data before last_ack if it is (partly) - * beyond next seq */ - } else if (SEQ_GT(ssn->server.last_ack, ssn->server.next_seq) && - SEQ_GT((TCP_GET_SEQ(p)+p->payload_len),ssn->server.next_seq)) - { - SCLogDebug("ssn %p: PKT SEQ %"PRIu32" payload_len %"PRIu16 - " before last_ack %"PRIu32", after next_seq %"PRIu32":" - " acked data that we haven't seen before", - ssn, TCP_GET_SEQ(p), p->payload_len, ssn->server.last_ack, ssn->server.next_seq); - if (SEQ_EQ(TCP_GET_SEQ(p),ssn->server.next_seq)) { - ssn->server.next_seq += p->payload_len; - } - } else { - SCLogDebug("ssn %p: PKT SEQ %"PRIu32" payload_len %"PRIu16 - " before last_ack %"PRIu32". next_seq %"PRIu32, - ssn, TCP_GET_SEQ(p), p->payload_len, ssn->server.last_ack, ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_EST_PKT_BEFORE_LAST_ACK); - return -1; - } - } - - int zerowindowprobe = 0; - /* zero window probe */ - if (p->payload_len == 1 && TCP_GET_SEQ(p) == ssn->server.next_seq && ssn->server.window == 0) { - SCLogDebug("ssn %p: zero window probe", ssn); - zerowindowprobe = 1; - - /* expected packet */ - } else if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) { - ssn->server.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", - ssn, ssn->server.next_seq); - /* not completely as expected, but valid */ - } else if (SEQ_LT(TCP_GET_SEQ(p),ssn->server.next_seq) && - SEQ_GT((TCP_GET_SEQ(p)+p->payload_len), ssn->server.next_seq)) - { - ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len; - SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 - " (started before next_seq, ended after)", - ssn, ssn->server.next_seq); - /* if next_seq has fallen behind last_ack, we got some catching up to do */ - } else if (SEQ_LT(ssn->server.next_seq, ssn->server.last_ack)) { - ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len; - SCLogDebug("ssn %p: ssn->server.next_seq %"PRIu32 - " (next_seq had fallen behind last_ack)", - ssn, ssn->server.next_seq); - } else { - SCLogDebug("ssn %p: no update to ssn->server.next_seq %"PRIu32 - " SEQ %u SEQ+ %u last_ack %u", - ssn, ssn->server.next_seq, - TCP_GET_SEQ(p), TCP_GET_SEQ(p)+p->payload_len, ssn->server.last_ack); - } - - if (zerowindowprobe) { - SCLogDebug("ssn %p: zero window probe, skipping oow check", ssn); - } else if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) || - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || - (ssn->flags & STREAMTCP_FLAG_ASYNC)) { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - SCLogDebug("ssn %p: ssn->client.window %"PRIu32"", ssn, - ssn->client.window); - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpSackUpdatePacket(&ssn->client, p); - - StreamTcpUpdateNextWin(ssn, &ssn->client, (ssn->client.last_ack + ssn->client.window)); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p, pq); - } else { - SCLogDebug("ssn %p: client => SEQ out of window, packet SEQ" - "%" PRIu32 ", payload size %" PRIu32 " (%" PRIu32 ")," - " ssn->server.last_ack %" PRIu32 ", ssn->server.next_win " - "%" PRIu32 "(%"PRIu32")", ssn, TCP_GET_SEQ(p), - p->payload_len, TCP_GET_SEQ(p) + p->payload_len, - ssn->server.last_ack, ssn->server.next_win, - TCP_GET_SEQ(p) + p->payload_len - ssn->server.next_win); - StreamTcpSetEvent(p, STREAM_EST_PACKET_OUT_OF_WINDOW); - return -1; - } - return 0; -} - -/** - * \internal - * - * \brief Find the highest sequence number needed to consider all segments as ACK'd - * - * Used to treat all segments as ACK'd upon receiving a valid RST. - * - * \param stream stream to inspect the segments from - * \param seq sequence number to check against - * - * \retval ack highest ack we need to set - */ -static inline uint32_t StreamTcpResetGetMaxAck(TcpStream *stream, uint32_t seq) -{ - uint32_t ack = seq; - - if (stream->seg_list_tail != NULL) { - if (SEQ_GT((stream->seg_list_tail->seq + stream->seg_list_tail->payload_len), ack)) - { - ack = stream->seg_list_tail->seq + stream->seg_list_tail->payload_len; - } - } - - SCReturnUInt(ack); -} - -/** - * \brief Function to handle the TCP_ESTABLISHED state. The function handles - * ACK, FIN, RST packets and correspondingly changes the connection - * state. The function handles the data inside packets and call - * StreamTcpReassembleHandleSegment(tv, ) to handle the reassembling. - * - * \param tv Thread Variable containig input/output queue, cpu affinity etc. - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - */ - -static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - if (ssn == NULL) - return -1; - - if (p->tcph->th_flags & TH_RST) { - if (!StreamTcpValidateRst(ssn, p)) - return -1; - - /* force both streams to reassemble, if necessary */ - StreamTcpPseudoPacketCreateStreamEndPacket(tv, stt, p, ssn, pq); - - if (PKT_IS_TOSERVER(p)) { - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received and state changed to " - "TCP_CLOSED", ssn); - - ssn->server.next_seq = TCP_GET_ACK(p); - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; - SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", ssn, - ssn->server.next_seq); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - - /* don't return packets to pools here just yet, the pseudo - * packet will take care, otherwise the normal session - * cleanup. */ - } else { - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received and state changed to " - "TCP_CLOSED", ssn); - - ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1; - ssn->client.next_seq = TCP_GET_ACK(p); - - SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", ssn, - ssn->server.next_seq); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack); - - /* don't return packets to pools here just yet, the pseudo - * packet will take care, otherwise the normal session - * cleanup. */ - } - - } else if (p->tcph->th_flags & TH_FIN) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - SCLogDebug("ssn (%p: FIN received SEQ" - " %" PRIu32 ", last ACK %" PRIu32 ", next win %"PRIu32"," - " win %" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack, ssn->server.next_win, - ssn->server.window); - - if ((StreamTcpHandleFin(tv, stt, ssn, p, pq)) == -1) - return -1; - - /* SYN/ACK */ - } else if ((p->tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { - SCLogDebug("ssn %p: SYN/ACK packet on state ESTABLISHED... resent", - ssn); - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: SYN/ACK-pkt to server in ESTABLISHED state", ssn); - - StreamTcpSetEvent(p, STREAM_EST_SYNACK_TOSERVER); - return -1; - } - - /* Check if the SYN/ACK packets ACK matches the earlier - * received SYN/ACK packet. */ - if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack))) { - SCLogDebug("ssn %p: ACK mismatch, packet ACK %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p), - ssn->client.isn + 1); - - StreamTcpSetEvent(p, STREAM_EST_SYNACK_RESEND_WITH_DIFFERENT_ACK); - return -1; - } - - /* Check if the SYN/ACK packet SEQ the earlier - * received SYN packet. */ - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->server.isn))) { - SCLogDebug("ssn %p: SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p), - ssn->client.isn + 1); - - StreamTcpSetEvent(p, STREAM_EST_SYNACK_RESEND_WITH_DIFF_SEQ); - return -1; - } - - if (ssn->flags & STREAMTCP_FLAG_3WHS_CONFIRMED) { - /* a resend of a SYN while we are established already -- fishy */ - StreamTcpSetEvent(p, STREAM_EST_SYNACK_RESEND); - return -1; - } - - SCLogDebug("ssn %p: SYN/ACK packet on state ESTABLISHED... resent. " - "Likely due server not receiving final ACK in 3whs", ssn); - - /* resetting state to TCP_SYN_RECV as we should get another ACK now */ - StreamTcpPacketSetState(p, ssn, TCP_SYN_RECV); - SCLogDebug("ssn %p: =~ ssn state is now reset to TCP_SYN_RECV", ssn); - return 0; - - } else if (p->tcph->th_flags & TH_SYN) { - SCLogDebug("ssn %p: SYN packet on state ESTABLISED... resent", ssn); - if (PKT_IS_TOCLIENT(p)) { - SCLogDebug("ssn %p: SYN-pkt to client in EST state", ssn); - - StreamTcpSetEvent(p, STREAM_EST_SYN_TOCLIENT); - return -1; - } - - if (!(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.isn))) { - SCLogDebug("ssn %p: SYN with different SEQ on SYN_RECV state", ssn); - - StreamTcpSetEvent(p, STREAM_EST_SYN_RESEND_DIFF_SEQ); - return -1; - } - - /* a resend of a SYN while we are established already -- fishy */ - StreamTcpSetEvent(p, STREAM_EST_SYN_RESEND); - return -1; - - } else if (p->tcph->th_flags & TH_ACK) { - /* Urgent pointer size can be more than the payload size, as it tells - * the future coming data from the sender will be handled urgently - * until data of size equal to urgent offset has been processed - * (RFC 2147) */ - - /* If the timestamp option is enabled for both the streams, then - * validate the received packet timestamp value against the - * stream->last_ts. If the timestamp is valid then process the - * packet normally otherwise the drop the packet (RFC 1323) */ - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if (PKT_IS_TOSERVER(p)) { - /* Process the received packet to server */ - HandleEstablishedPacketToServer(tv, ssn, p, stt, pq); - - SCLogDebug("ssn %p: next SEQ %" PRIu32 ", last ACK %" PRIu32 "," - " next win %" PRIu32 ", win %" PRIu32 "", ssn, - ssn->client.next_seq, ssn->server.last_ack - ,ssn->client.next_win, ssn->client.window); - - } else { /* implied to client */ - if (!(ssn->flags & STREAMTCP_FLAG_3WHS_CONFIRMED)) { - ssn->flags |= STREAMTCP_FLAG_3WHS_CONFIRMED; - SCLogDebug("3whs is now confirmed by server"); - } - - /* Process the received packet to client */ - HandleEstablishedPacketToClient(tv, ssn, p, stt, pq); - - SCLogDebug("ssn %p: next SEQ %" PRIu32 ", last ACK %" PRIu32 "," - " next win %" PRIu32 ", win %" PRIu32 "", ssn, - ssn->server.next_seq, ssn->client.last_ack, - ssn->server.next_win, ssn->server.window); - } - } else { - SCLogDebug("ssn %p: default case", ssn); - } - - return 0; -} - -/** - * \brief Function to handle the FIN packets for states TCP_SYN_RECV and - * TCP_ESTABLISHED and changes to another TCP state as required. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - * - * \retval 0 success - * \retval -1 something wrong with the packet - */ - -static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt, - TcpSession *ssn, Packet *p, PacketQueue *pq) -{ - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ %" PRIu32 "," - " ACK %" PRIu32 "", ssn, p->payload_len, TCP_GET_SEQ(p), - TCP_GET_ACK(p)); - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN_INVALID_ACK); - return -1; - } - - if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_SEQ(p), - ssn->client.next_seq); - - StreamTcpSetEvent(p, STREAM_FIN_OUT_OF_WINDOW); - return -1; - } - - StreamTcpPacketSetState(p, ssn, TCP_CLOSE_WAIT); - SCLogDebug("ssn %p: state changed to TCP_CLOSE_WAIT", ssn); - - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq)) - ssn->client.next_seq = TCP_GET_SEQ(p) + p->payload_len; - - SCLogDebug("ssn %p: ssn->client.next_seq %" PRIu32 "", ssn, - ssn->client.next_seq); - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client packet - and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->client, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", - ssn, ssn->client.next_seq, ssn->server.last_ack); - } else { /* implied to client */ - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ %" PRIu32 ", " - "ACK %" PRIu32 "", ssn, p->payload_len, TCP_GET_SEQ(p), - TCP_GET_ACK(p)); - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN_INVALID_ACK); - return -1; - } - - if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 " != " - "%" PRIu32 " from stream", ssn, TCP_GET_SEQ(p), - ssn->server.next_seq); - - StreamTcpSetEvent(p, STREAM_FIN_OUT_OF_WINDOW); - return -1; - } - - StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT1); - SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT1", ssn); - - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq)) - ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len; - - SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", ssn, - ssn->server.next_seq); - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client packet - and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, &ssn->server, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK %" PRIu32 "", - ssn, ssn->server.next_seq, ssn->client.last_ack); - } - - return 0; -} - -/** - * \brief Function to handle the TCP_FIN_WAIT1 state. The function handles - * ACK, FIN, RST packets and correspondingly changes the connection - * state. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - * - * \retval 0 success - * \retval -1 something wrong with the packet - */ - -static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - if (ssn == NULL) - return -1; - - if (p->tcph->th_flags & TH_RST) { - if (!StreamTcpValidateRst(ssn, p)) - return -1; - - /* force both streams to reassemble, if necessary */ - StreamTcpPseudoPacketCreateStreamEndPacket(tv, stt, p, ssn, pq); - - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED", - ssn); - - if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - } - - } else if ((p->tcph->th_flags & (TH_FIN|TH_ACK)) == (TH_FIN|TH_ACK)) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - - if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - StreamTcpSetEvent(p, STREAM_FIN1_FIN_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN1_INVALID_ACK); - return -1; - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); - SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { - ssn->client.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->client.next_seq %" PRIu32 "", - ssn, ssn->client.next_seq); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - } else { /* implied to client */ - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - - if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_FIN1_FIN_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN1_INVALID_ACK); - return -1; - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); - SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); - - if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) { - ssn->server.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", - ssn, ssn->server.next_seq); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack); - } - - } else if (p->tcph->th_flags & TH_FIN) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - - if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - StreamTcpSetEvent(p, STREAM_FIN1_FIN_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN1_INVALID_ACK); - return -1; - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_CLOSING); - SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn); - - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { - ssn->client.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->client.next_seq %" PRIu32 "", - ssn, ssn->client.next_seq); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - } else { /* implied to client */ - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - - int retransmission = 0; - - if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_FIN1_FIN_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN1_INVALID_ACK); - return -1; - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_CLOSING); - SCLogDebug("ssn %p: state changed to TCP_CLOSING", ssn); - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); - - if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) { - ssn->server.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", - ssn, ssn->server.next_seq); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack); - } - } else if (p->tcph->th_flags & TH_SYN) { - SCLogDebug("ssn (%p): SYN pkt on FinWait1", ssn); - StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); - return -1; - - } else if (p->tcph->th_flags & TH_ACK) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - - if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN1_INVALID_ACK); - return -1; - } - - if (!retransmission) { - if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) || - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || - ssn->flags & STREAMTCP_FLAG_ASYNC) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->client.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->client.next_win); - - if (TCP_GET_SEQ(p) == ssn->client.next_seq) { - StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2); - SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn); - } - } else { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - - StreamTcpSetEvent(p, STREAM_FIN1_ACK_WRONG_SEQ); - return -1; - } - - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { - ssn->client.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->client.next_seq %" PRIu32 "", - ssn, ssn->client.next_seq); - } - - StreamTcpSackUpdatePacket(&ssn->server, p); - - /* update next_win */ - StreamTcpUpdateNextWin(ssn, &ssn->server, (ssn->server.last_ack + ssn->server.window)); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - - } else { /* implied to client */ - - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - - int retransmission = 0; - - if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN1_INVALID_ACK); - return -1; - } - - if (!retransmission) { - if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) || - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || - (ssn->flags & STREAMTCP_FLAG_ASYNC)) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win); - - if (TCP_GET_SEQ(p) == ssn->server.next_seq) { - StreamTcpPacketSetState(p, ssn, TCP_FIN_WAIT2); - SCLogDebug("ssn %p: state changed to TCP_FIN_WAIT2", ssn); - } - } else { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_FIN1_ACK_WRONG_SEQ); - return -1; - } - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); - - if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) { - ssn->server.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", - ssn, ssn->server.next_seq); - } - - StreamTcpSackUpdatePacket(&ssn->client, p); - - /* update next_win */ - StreamTcpUpdateNextWin(ssn, &ssn->client, (ssn->client.last_ack + ssn->client.window)); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack); - } - } else { - SCLogDebug("ssn (%p): default case", ssn); - } - - return 0; -} - -/** - * \brief Function to handle the TCP_FIN_WAIT2 state. The function handles - * ACK, RST, FIN packets and correspondingly changes the connection - * state. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - */ - -static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - if (ssn == NULL) - return -1; - - if (p->tcph->th_flags & TH_RST) { - if (!StreamTcpValidateRst(ssn, p)) - return -1; - - /* force both streams to reassemble, if necessary */ - StreamTcpPseudoPacketCreateStreamEndPacket(tv, stt, p, ssn, pq); - - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED", - ssn); - - if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - } - - } else if (p->tcph->th_flags & TH_FIN) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq - 1) && - SEQ_EQ(TCP_GET_ACK(p), ssn->server.last_ack)) { - SCLogDebug("ssn %p: retransmission", ssn); - retransmission = 1; - } else if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ " - "%" PRIu32 " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - StreamTcpSetEvent(p, STREAM_FIN2_FIN_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN2_INVALID_ACK); - return -1; - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); - SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - } else { /* implied to client */ - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - - if (SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq - 1) && - SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack)) { - SCLogDebug("ssn %p: retransmission", ssn); - retransmission = 1; - } else if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - - } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ " - "%" PRIu32 " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_FIN2_FIN_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN2_INVALID_ACK); - return -1; - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); - SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack); - } - - } else if (p->tcph->th_flags & TH_SYN) { - SCLogDebug("ssn (%p): SYN pkt on FinWait2", ssn); - StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); - return -1; - - } else if (p->tcph->th_flags & TH_ACK) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - - if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN2_INVALID_ACK); - return -1; - } - - if (!retransmission) { - if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->client.next_win) || - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || - (ssn->flags & STREAMTCP_FLAG_ASYNC)) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->client.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->client.next_win); - - } else { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ); - return -1; - } - - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) { - ssn->client.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->client.next_seq %" PRIu32 "", - ssn, ssn->client.next_seq); - } - - StreamTcpSackUpdatePacket(&ssn->server, p); - - /* update next_win */ - StreamTcpUpdateNextWin(ssn, &ssn->server, (ssn->server.last_ack + ssn->server.window)); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - } else { /* implied to client */ - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - - if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_FIN2_INVALID_ACK); - return -1; - } - - if (!retransmission) { - if (SEQ_LEQ(TCP_GET_SEQ(p) + p->payload_len, ssn->server.next_win) || - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) || - (ssn->flags & STREAMTCP_FLAG_ASYNC)) - { - SCLogDebug("ssn %p: seq %"PRIu32" in window, ssn->server.next_win " - "%" PRIu32 "", ssn, TCP_GET_SEQ(p), ssn->server.next_win); - } else { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_FIN2_ACK_WRONG_SEQ); - return -1; - } - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) { - ssn->server.next_seq += p->payload_len; - SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "", - ssn, ssn->server.next_seq); - } - - StreamTcpSackUpdatePacket(&ssn->client, p); - - /* update next_win */ - StreamTcpUpdateNextWin(ssn, &ssn->client, (ssn->client.last_ack + ssn->client.window)); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack); - } - } else { - SCLogDebug("ssn %p: default case", ssn); - } - - return 0; -} - -/** - * \brief Function to handle the TCP_CLOSING state. Upon arrival of ACK - * the connection goes to TCP_TIME_WAIT state. The state has been - * reached as both end application has been closed. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - */ - -static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - if (ssn == NULL) - return -1; - - if (p->tcph->th_flags & TH_RST) { - if (!StreamTcpValidateRst(ssn, p)) - return -1; - - /* force both streams to reassemble, if necessary */ - StreamTcpPseudoPacketCreateStreamEndPacket(tv, stt, p, ssn, pq); - - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED", - ssn); - - if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - } - - } else if (p->tcph->th_flags & TH_SYN) { - SCLogDebug("ssn (%p): SYN pkt on Closing", ssn); - StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); - return -1; - - } else if (p->tcph->th_flags & TH_ACK) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (TCP_GET_SEQ(p) != ssn->client.next_seq) { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - StreamTcpSetEvent(p, STREAM_CLOSING_ACK_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_CLOSING_INVALID_ACK); - return -1; - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); - SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - } else { /* implied to client */ - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (TCP_GET_SEQ(p) != ssn->server.next_seq) { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_CLOSING_ACK_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_CLOSING_INVALID_ACK); - return -1; - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_TIME_WAIT); - SCLogDebug("ssn %p: state changed to TCP_TIME_WAIT", ssn); - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - SCLogDebug("StreamTcpPacketStateClosing (%p): =+ next SEQ " - "%" PRIu32 ", last ACK %" PRIu32 "", ssn, - ssn->server.next_seq, ssn->client.last_ack); - } - } else { - SCLogDebug("ssn %p: default case", ssn); - } - - return 0; -} - -/** - * \brief Function to handle the TCP_CLOSE_WAIT state. Upon arrival of FIN - * packet from server the connection goes to TCP_LAST_ACK state. - * The state is possible only for server host. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - */ - -static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - SCEnter(); - - if (ssn == NULL) { - SCReturnInt(-1); - } - - if (PKT_IS_TOCLIENT(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - } else { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - } - - if (p->tcph->th_flags & TH_RST) { - if (!StreamTcpValidateRst(ssn, p)) - return -1; - - /* force both streams to reassemble, if necessary */ - StreamTcpPseudoPacketCreateStreamEndPacket(tv, stt, p, ssn, pq); - - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED", - ssn); - - if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - } - - } else if (p->tcph->th_flags & TH_FIN) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - SCReturnInt(-1); - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - - int retransmission = 0; - if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (!retransmission) { - if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_FIN_OUT_OF_WINDOW); - SCReturnInt(-1); - } - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_INVALID_ACK); - SCReturnInt(-1); - } - - /* don't update to LAST_ACK here as we want a toclient FIN for that */ - - if (!retransmission) - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - } else { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - - int retransmission = 0; - if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (!retransmission) { - if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || - SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_FIN_OUT_OF_WINDOW); - SCReturnInt(-1); - } - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_INVALID_ACK); - SCReturnInt(-1); - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_LAST_ACK); - SCLogDebug("ssn %p: state changed to TCP_LAST_ACK", ssn); - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack); - } - - } else if (p->tcph->th_flags & TH_SYN) { - SCLogDebug("ssn (%p): SYN pkt on CloseWait", ssn); - StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); - SCReturnInt(-1); - - } else if (p->tcph->th_flags & TH_ACK) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - SCReturnInt(-1); - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - - int retransmission = 0; - if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->client.last_ack))) { - SCLogDebug("ssn %p: -> retransmission", ssn); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK); - SCReturnInt(-1); - - } else if (SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_ACK_OUT_OF_WINDOW); - SCReturnInt(-1); - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_INVALID_ACK); - SCReturnInt(-1); - } - - if (!retransmission) { - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - if (SEQ_EQ(TCP_GET_SEQ(p),ssn->client.next_seq)) - ssn->client.next_seq += p->payload_len; - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - } else { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->server.last_ack))) { - SCLogDebug("ssn %p: -> retransmission", ssn); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_PKT_BEFORE_LAST_ACK); - SCReturnInt(-1); - - } else if (SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) - { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_ACK_OUT_OF_WINDOW); - SCReturnInt(-1); - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_CLOSEWAIT_INVALID_ACK); - SCReturnInt(-1); - } - - if (!retransmission) { - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); - - if (SEQ_EQ(TCP_GET_SEQ(p),ssn->server.next_seq)) - ssn->server.next_seq += p->payload_len; - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack); - } - - } else { - SCLogDebug("ssn %p: default case", ssn); - } - SCReturnInt(0); -} - -/** - * \brief Function to handle the TCP_LAST_ACK state. Upon arrival of ACK - * the connection goes to TCP_CLOSED state and stream memory is - * returned back to pool. The state is possible only for server host. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - */ - -static int StreamTcpPacketStateLastAck(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - if (ssn == NULL) - return -1; - - if (p->tcph->th_flags & TH_RST) { - if (!StreamTcpValidateRst(ssn, p)) - return -1; - - /* force both streams to reassemble, if necessary */ - StreamTcpPseudoPacketCreateStreamEndPacket(tv, stt, p, ssn, pq); - - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED", - ssn); - - if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - } - - } else if (p->tcph->th_flags & TH_FIN) { - /** \todo */ - - } else if (p->tcph->th_flags & TH_SYN) { - SCLogDebug("ssn (%p): SYN pkt on LastAck", ssn); - StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); - return -1; - - } else if (p->tcph->th_flags & TH_ACK) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - - int retransmission = 0; - if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } - - if (TCP_GET_SEQ(p) != ssn->client.next_seq && TCP_GET_SEQ(p) != ssn->client.next_seq + 1) { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - StreamTcpSetEvent(p, STREAM_LASTACK_ACK_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_LASTACK_INVALID_ACK); - SCReturnInt(-1); - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn); - - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - } - } else { - SCLogDebug("ssn %p: default case", ssn); - } - - return 0; -} - -/** - * \brief Function to handle the TCP_TIME_WAIT state. Upon arrival of ACK - * the connection goes to TCP_CLOSED state and stream memory is - * returned back to pool. - * - * \param tv Thread Variable containig input/output queue, cpu affinity - * \param p Packet which has to be handled in this TCP state. - * \param stt Strean Thread module registered to handle the stream handling - */ - -static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p, - StreamTcpThread *stt, TcpSession *ssn, PacketQueue *pq) -{ - if (ssn == NULL) - return -1; - - if (p->tcph->th_flags & TH_RST) { - if (!StreamTcpValidateRst(ssn, p)) - return -1; - - /* force both streams to reassemble, if necessary */ - StreamTcpPseudoPacketCreateStreamEndPacket(tv, stt, p, ssn, pq); - - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED", - ssn); - - if (PKT_IS_TOSERVER(p)) { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->server, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - } else { - if ((p->tcph->th_flags & TH_ACK) && StreamTcpValidateAck(ssn, &ssn->client, p) == 0) - StreamTcpUpdateLastAck(ssn, &ssn->client, - StreamTcpResetGetMaxAck(&ssn->client, TCP_GET_ACK(p))); - - StreamTcpUpdateLastAck(ssn, &ssn->server, - StreamTcpResetGetMaxAck(&ssn->server, TCP_GET_SEQ(p))); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - } - - } else if (p->tcph->th_flags & TH_FIN) { - /** \todo */ - - } else if (p->tcph->th_flags & TH_SYN) { - SCLogDebug("ssn (%p): SYN pkt on TimeWait", ssn); - StreamTcpSetEvent(p, STREAM_SHUTDOWN_SYN_RESEND); - return -1; - - } else if (p->tcph->th_flags & TH_ACK) { - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) - return -1; - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - - } else if (TCP_GET_SEQ(p) != ssn->client.next_seq && TCP_GET_SEQ(p) != ssn->client.next_seq+1) { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->client.next_seq); - StreamTcpSetEvent(p, STREAM_TIMEWAIT_ACK_WRONG_SEQ); - return -1; - } - - if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_TIMEWAIT_INVALID_ACK); - SCReturnInt(-1); - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn); - - ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p))) - ssn->server.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->client.next_seq, - ssn->server.last_ack); - - StreamTcpPseudoPacketCreateStreamEndPacket(tv, stt, p, ssn, pq); - } else { - SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to client: SEQ " - "%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len, - TCP_GET_SEQ(p), TCP_GET_ACK(p)); - int retransmission = 0; - if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { - SCLogDebug("ssn %p: packet is retransmission", ssn); - retransmission = 1; - } else if (TCP_GET_SEQ(p) != ssn->server.next_seq && TCP_GET_SEQ(p) != ssn->server.next_seq+1) { - if (p->payload_len > 0 && TCP_GET_SEQ(p) == ssn->server.last_ack) { - SCLogDebug("ssn %p: -> retransmission", ssn); - SCReturnInt(0); - } else { - SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" - " != %" PRIu32 " from stream", ssn, - TCP_GET_SEQ(p), ssn->server.next_seq); - StreamTcpSetEvent(p, STREAM_TIMEWAIT_ACK_WRONG_SEQ); - return -1; - } - } - - if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_TIMEWAIT_INVALID_ACK); - SCReturnInt(-1); - } - - if (!retransmission) { - StreamTcpPacketSetState(p, ssn, TCP_CLOSED); - SCLogDebug("ssn %p: state changed to TCP_CLOSED", ssn); - - ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale; - } - - StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p)); - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - StreamTcpHandleTimestamp(ssn, p); - } - - /* Update the next_seq, in case if we have missed the client - packet and server has already received and acked it */ - if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p))) - ssn->client.next_seq = TCP_GET_ACK(p); - - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK " - "%" PRIu32 "", ssn, ssn->server.next_seq, - ssn->client.last_ack); - - StreamTcpPseudoPacketCreateStreamEndPacket(tv, stt, p, ssn, pq); - } - - } else { - SCLogDebug("ssn %p: default case", ssn); - } - - return 0; -} - -/** - * \retval 1 packet is a keep alive pkt - * \retval 0 packet is not a keep alive pkt - */ -static int StreamTcpPacketIsKeepAlive(TcpSession *ssn, Packet *p) -{ - TcpStream *stream = NULL, *ostream = NULL; - uint32_t seq; - uint32_t ack; - - if (p->flags & PKT_PSEUDO_STREAM_END) - return 0; - - /* - rfc 1122: - An implementation SHOULD send a keep-alive segment with no - data; however, it MAY be configurable to send a keep-alive - segment containing one garbage octet, for compatibility with - erroneous TCP implementations. - */ - if (p->payload_len > 1) - return 0; - - if ((p->tcph->th_flags & (TH_SYN|TH_FIN|TH_RST)) != 0) { - return 0; - } - - if (PKT_IS_TOSERVER(p)) { - stream = &ssn->client; - ostream = &ssn->server; - } else { - stream = &ssn->server; - ostream = &ssn->client; - } - - seq = TCP_GET_SEQ(p); - ack = TCP_GET_ACK(p); - - if (ack == ostream->last_ack && seq == (stream->next_seq - 1)) { - SCLogDebug("packet is TCP keep-alive: %"PRIu64, p->pcap_cnt); - stream->flags |= STREAMTCP_STREAM_FLAG_KEEPALIVE; - return 1; - } - SCLogDebug("seq %u (%u), ack %u (%u)", seq, (stream->next_seq - 1), ack, ostream->last_ack); - return 0; -} - -/** - * \retval 1 packet is a keep alive ACK pkt - * \retval 0 packet is not a keep alive ACK pkt - */ -static int StreamTcpPacketIsKeepAliveACK(TcpSession *ssn, Packet *p) -{ - TcpStream *stream = NULL, *ostream = NULL; - uint32_t seq; - uint32_t ack; - uint32_t pkt_win; - - if (p->flags & PKT_PSEUDO_STREAM_END) - return 0; - /* should get a normal ACK to a Keep Alive */ - if (p->payload_len > 0) - return 0; - - if ((p->tcph->th_flags & (TH_SYN|TH_FIN|TH_RST)) != 0) - return 0; - - if (TCP_GET_WINDOW(p) == 0) - return 0; - - if (PKT_IS_TOSERVER(p)) { - stream = &ssn->client; - ostream = &ssn->server; - } else { - stream = &ssn->server; - ostream = &ssn->client; - } - - seq = TCP_GET_SEQ(p); - ack = TCP_GET_ACK(p); - - pkt_win = TCP_GET_WINDOW(p) << ostream->wscale; - if (pkt_win != ostream->window) - return 0; - - if ((ostream->flags & STREAMTCP_STREAM_FLAG_KEEPALIVE) && ack == ostream->last_ack && seq == stream->next_seq) { - SCLogDebug("packet is TCP keep-aliveACK: %"PRIu64, p->pcap_cnt); - ostream->flags &= ~STREAMTCP_STREAM_FLAG_KEEPALIVE; - return 1; - } - SCLogDebug("seq %u (%u), ack %u (%u) FLAG_KEEPALIVE: %s", seq, stream->next_seq, ack, ostream->last_ack, - ostream->flags & STREAMTCP_STREAM_FLAG_KEEPALIVE ? "set" : "not set"); - return 0; -} - -static void StreamTcpClearKeepAliveFlag(TcpSession *ssn, Packet *p) -{ - TcpStream *stream = NULL; - - if (p->flags & PKT_PSEUDO_STREAM_END) - return; - - if (PKT_IS_TOSERVER(p)) { - stream = &ssn->client; - } else { - stream = &ssn->server; - } - - if (stream->flags & STREAMTCP_STREAM_FLAG_KEEPALIVE) { - stream->flags &= ~STREAMTCP_STREAM_FLAG_KEEPALIVE; - SCLogDebug("FLAG_KEEPALIVE cleared"); - } -} - -/** - * \retval 1 packet is a window update pkt - * \retval 0 packet is not a window update pkt - */ -static int StreamTcpPacketIsWindowUpdate(TcpSession *ssn, Packet *p) -{ - TcpStream *stream = NULL, *ostream = NULL; - uint32_t seq; - uint32_t ack; - uint32_t pkt_win; - - if (p->flags & PKT_PSEUDO_STREAM_END) - return 0; - - if (ssn->state < TCP_ESTABLISHED) - return 0; - - if (p->payload_len > 0) - return 0; - - if ((p->tcph->th_flags & (TH_SYN|TH_FIN|TH_RST)) != 0) - return 0; - - if (TCP_GET_WINDOW(p) == 0) - return 0; - - if (PKT_IS_TOSERVER(p)) { - stream = &ssn->client; - ostream = &ssn->server; - } else { - stream = &ssn->server; - ostream = &ssn->client; - } - - seq = TCP_GET_SEQ(p); - ack = TCP_GET_ACK(p); - - pkt_win = TCP_GET_WINDOW(p) << ostream->wscale; - if (pkt_win == ostream->window) - return 0; - - if (ack == ostream->last_ack && seq == stream->next_seq) { - SCLogDebug("packet is TCP window update: %"PRIu64, p->pcap_cnt); - return 1; - } - SCLogDebug("seq %u (%u), ack %u (%u)", seq, stream->next_seq, ack, ostream->last_ack); - return 0; -} - -/** - * Try to detect whether a packet is a valid FIN 4whs final ack. - * - */ -static int StreamTcpPacketIsFinShutdownAck(TcpSession *ssn, Packet *p) -{ - TcpStream *stream = NULL, *ostream = NULL; - uint32_t seq; - uint32_t ack; - - if (p->flags & PKT_PSEUDO_STREAM_END) - return 0; - if (!(ssn->state == TCP_TIME_WAIT || ssn->state == TCP_CLOSE_WAIT || ssn->state == TCP_LAST_ACK)) - return 0; - if (p->tcph->th_flags != TH_ACK) - return 0; - if (p->payload_len != 0) - return 0; - - if (PKT_IS_TOSERVER(p)) { - stream = &ssn->client; - ostream = &ssn->server; - } else { - stream = &ssn->server; - ostream = &ssn->client; - } - - seq = TCP_GET_SEQ(p); - ack = TCP_GET_ACK(p); - - SCLogDebug("%"PRIu64", seq %u ack %u stream->next_seq %u ostream->next_seq %u", - p->pcap_cnt, seq, ack, stream->next_seq, ostream->next_seq); - - if (SEQ_EQ(stream->next_seq + 1, seq) && SEQ_EQ(ack, ostream->next_seq + 1)) { - return 1; - } - return 0; -} - -/** - * Try to detect packets doing bad window updates - * - * See bug 1238. - * - * Find packets that are unexpected, and shrink the window to the point - * where the packets we do expect are rejected for being out of window. - * - * The logic we use here is: - * - packet seq > next_seq - * - packet ack > next_seq (packet acks unseen data) - * - packet shrinks window more than it's own data size - * - packet shrinks window more than the diff between it's ack and the - * last_ack value - * - * Packets coming in after packet loss can look quite a bit like this. - */ -static int StreamTcpPacketIsBadWindowUpdate(TcpSession *ssn, Packet *p) -{ - TcpStream *stream = NULL, *ostream = NULL; - uint32_t seq; - uint32_t ack; - uint32_t pkt_win; - - if (p->flags & PKT_PSEUDO_STREAM_END) - return 0; - - if (ssn->state < TCP_ESTABLISHED || ssn->state == TCP_CLOSED) - return 0; - - if ((p->tcph->th_flags & (TH_SYN|TH_FIN|TH_RST)) != 0) - return 0; - - if (PKT_IS_TOSERVER(p)) { - stream = &ssn->client; - ostream = &ssn->server; - } else { - stream = &ssn->server; - ostream = &ssn->client; - } - - seq = TCP_GET_SEQ(p); - ack = TCP_GET_ACK(p); - - pkt_win = TCP_GET_WINDOW(p) << ostream->wscale; - - if (pkt_win < ostream->window) { - uint32_t diff = ostream->window - pkt_win; - if (diff > p->payload_len && - SEQ_GT(ack, ostream->next_seq) && - SEQ_GT(seq, stream->next_seq)) - { - SCLogDebug("%"PRIu64", pkt_win %u, stream win %u, diff %u, dsize %u", - p->pcap_cnt, pkt_win, ostream->window, diff, p->payload_len); - SCLogDebug("%"PRIu64", pkt_win %u, stream win %u", - p->pcap_cnt, pkt_win, ostream->window); - SCLogDebug("%"PRIu64", seq %u ack %u ostream->next_seq %u ostream->last_ack %u, ostream->next_win %u, diff %u (%u)", - p->pcap_cnt, seq, ack, ostream->next_seq, ostream->last_ack, ostream->next_win, - ostream->next_seq - ostream->last_ack, stream->next_seq - stream->last_ack); - - /* get the expected window shrinking from looking at ack vs last_ack. - * Observed a lot of just a little overrunning that value. So added some - * margin that is still ok. To make sure this isn't a loophole to still - * close the window, this is limited to windows above 1024. Both values - * are rather arbitrary. */ - uint32_t adiff = ack - ostream->last_ack; - if (((pkt_win > 1024) && (diff > (adiff + 32))) || - ((pkt_win <= 1024) && (diff > adiff))) - { - SCLogDebug("pkt ACK %u is %u bytes beyond last_ack %u, shrinks window by %u " - "(allowing 32 bytes extra): pkt WIN %u", ack, adiff, ostream->last_ack, diff, pkt_win); - SCLogDebug("%u - %u = %u (state %u)", diff, adiff, diff - adiff, ssn->state); - StreamTcpSetEvent(p, STREAM_PKT_BAD_WINDOW_UPDATE); - return 1; - } - } - - } - SCLogDebug("seq %u (%u), ack %u (%u)", seq, stream->next_seq, ack, ostream->last_ack); - return 0; -} - -/* flow is and stays locked */ -int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt, - PacketQueue *pq) -{ - SCEnter(); - - DEBUG_ASSERT_FLOW_LOCKED(p->flow); - - SCLogDebug("p->pcap_cnt %"PRIu64, p->pcap_cnt); - - /* assign the thread id to the flow */ - if (unlikely(p->flow->thread_id == 0)) { - p->flow->thread_id = (FlowThreadId)tv->id; -#ifdef DEBUG - } else if (unlikely((FlowThreadId)tv->id != p->flow->thread_id)) { - SCLogDebug("wrong thread: flow has %u, we are %d", p->flow->thread_id, tv->id); -#endif - } - - TcpSession *ssn = (TcpSession *)p->flow->protoctx; - - /* track TCP flags */ - if (ssn != NULL) { - ssn->tcp_packet_flags |= p->tcph->th_flags; - if (PKT_IS_TOSERVER(p)) - ssn->client.tcp_flags |= p->tcph->th_flags; - else if (PKT_IS_TOCLIENT(p)) - ssn->server.tcp_flags |= p->tcph->th_flags; - } - - /* update counters */ - if ((p->tcph->th_flags & (TH_SYN|TH_ACK)) == (TH_SYN|TH_ACK)) { - StatsIncr(tv, stt->counter_tcp_synack); - } else if (p->tcph->th_flags & (TH_SYN)) { - StatsIncr(tv, stt->counter_tcp_syn); - } - if (p->tcph->th_flags & (TH_RST)) { - StatsIncr(tv, stt->counter_tcp_rst); - } - - /* broken TCP http://ask.wireshark.org/questions/3183/acknowledgment-number-broken-tcp-the-acknowledge-field-is-nonzero-while-the-ack-flag-is-not-set */ - if (!(p->tcph->th_flags & TH_ACK) && TCP_GET_ACK(p) != 0) { - StreamTcpSetEvent(p, STREAM_PKT_BROKEN_ACK); - } - - /* If we are on IPS mode, and got a drop action triggered from - * the IP only module, or from a reassembled msg and/or from an - * applayer detection, then drop the rest of the packets of the - * same stream and avoid inspecting it any further */ - if (StreamTcpCheckFlowDrops(p) == 1) { - SCLogDebug("This flow/stream triggered a drop rule"); - FlowSetNoPacketInspectionFlag(p->flow); - DecodeSetNoPacketInspectionFlag(p); - StreamTcpDisableAppLayer(p->flow); - PACKET_DROP(p); - /* return the segments to the pool */ - StreamTcpSessionPktFree(p); - SCReturnInt(0); - } - - if (ssn == NULL || ssn->state == TCP_NONE) { - if (StreamTcpPacketStateNone(tv, p, stt, ssn, &stt->pseudo_queue) == -1) { - goto error; - } - - if (ssn != NULL) - SCLogDebug("ssn->alproto %"PRIu16"", p->flow->alproto); - } else { - /* special case for PKT_PSEUDO_STREAM_END packets: - * bypass the state handling and various packet checks, - * we care about reassembly here. */ - if (p->flags & PKT_PSEUDO_STREAM_END) { - if (PKT_IS_TOCLIENT(p)) { - ssn->client.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, p, pq); - } else { - ssn->server.last_ack = TCP_GET_ACK(p); - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, p, pq); - } - /* straight to 'skip' as we already handled reassembly */ - goto skip; - } - - /* check if the packet is in right direction, when we missed the - SYN packet and picked up midstream session. */ - if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM_SYNACK) - StreamTcpPacketSwitchDir(ssn, p); - - if (StreamTcpPacketIsKeepAlive(ssn, p) == 1) { - goto skip; - } - if (StreamTcpPacketIsKeepAliveACK(ssn, p) == 1) { - StreamTcpClearKeepAliveFlag(ssn, p); - goto skip; - } - StreamTcpClearKeepAliveFlag(ssn, p); - - /* if packet is not a valid window update, check if it is perhaps - * a bad window update that we should ignore (and alert on) */ - if (StreamTcpPacketIsFinShutdownAck(ssn, p) == 0) - if (StreamTcpPacketIsWindowUpdate(ssn, p) == 0) - if (StreamTcpPacketIsBadWindowUpdate(ssn,p)) - goto skip; - - switch (ssn->state) { - case TCP_SYN_SENT: - if(StreamTcpPacketStateSynSent(tv, p, stt, ssn, &stt->pseudo_queue)) { - goto error; - } - break; - case TCP_SYN_RECV: - if(StreamTcpPacketStateSynRecv(tv, p, stt, ssn, &stt->pseudo_queue)) { - goto error; - } - break; - case TCP_ESTABLISHED: - if(StreamTcpPacketStateEstablished(tv, p, stt, ssn, &stt->pseudo_queue)) { - goto error; - } - break; - case TCP_FIN_WAIT1: - if(StreamTcpPacketStateFinWait1(tv, p, stt, ssn, &stt->pseudo_queue)) { - goto error; - } - break; - case TCP_FIN_WAIT2: - if(StreamTcpPacketStateFinWait2(tv, p, stt, ssn, &stt->pseudo_queue)) { - goto error; - } - break; - case TCP_CLOSING: - if(StreamTcpPacketStateClosing(tv, p, stt, ssn, &stt->pseudo_queue)) { - goto error; - } - break; - case TCP_CLOSE_WAIT: - if(StreamTcpPacketStateCloseWait(tv, p, stt, ssn, &stt->pseudo_queue)) { - goto error; - } - break; - case TCP_LAST_ACK: - if(StreamTcpPacketStateLastAck(tv, p, stt, ssn, &stt->pseudo_queue)) { - goto error; - } - break; - case TCP_TIME_WAIT: - if(StreamTcpPacketStateTimeWait(tv, p, stt, ssn, &stt->pseudo_queue)) { - goto error; - } - break; - case TCP_CLOSED: - /* TCP session memory is not returned to pool until timeout. */ - SCLogDebug("packet received on closed state"); - break; - default: - SCLogDebug("packet received on default state"); - break; - } - skip: - - if (ssn->state >= TCP_ESTABLISHED) { - p->flags |= PKT_STREAM_EST; - } - } - - /* deal with a pseudo packet that is created upon receiving a RST - * segment. To be sure we process both sides of the connection, we - * inject a fake packet into the system, forcing reassembly of the - * opposing direction. - * There should be only one, but to be sure we do a while loop. */ - if (ssn != NULL) { - while (stt->pseudo_queue.len > 0) { - SCLogDebug("processing pseudo packet / stream end"); - Packet *np = PacketDequeue(&stt->pseudo_queue); - if (np != NULL) { - /* process the opposing direction of the original packet */ - if (PKT_IS_TOSERVER(np)) { - SCLogDebug("pseudo packet is to server"); - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->client, np, NULL); - } else { - SCLogDebug("pseudo packet is to client"); - StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn, - &ssn->server, np, NULL); - } - - /* enqueue this packet so we inspect it in detect etc */ - PacketEnqueue(pq, np); - } - SCLogDebug("processing pseudo packet / stream end done"); - } - - /* recalc the csum on the packet if it was modified */ - if (p->flags & PKT_STREAM_MODIFIED) { - ReCalculateChecksum(p); - } - - /* check for conditions that may make us not want to log this packet */ - - /* streams that hit depth */ - if ((ssn->client.flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) || - (ssn->server.flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED)) - { - p->flags |= PKT_STREAM_NOPCAPLOG; - } - - /* encrypted packets */ - if ((PKT_IS_TOSERVER(p) && (ssn->client.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY)) || - (PKT_IS_TOCLIENT(p) && (ssn->server.flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY))) - { - p->flags |= PKT_STREAM_NOPCAPLOG; - } - } - - SCReturnInt(0); - -error: - /* make sure we don't leave packets in our pseudo queue */ - while (stt->pseudo_queue.len > 0) { - Packet *np = PacketDequeue(&stt->pseudo_queue); - if (np != NULL) { - PacketEnqueue(pq, np); - } - } - - /* recalc the csum on the packet if it was modified */ - if (p->flags & PKT_STREAM_MODIFIED) { - ReCalculateChecksum(p); - } - - if (StreamTcpInlineMode()) { - PACKET_DROP(p); - } - SCReturnInt(-1); -} - -/** - * \brief Function to validate the checksum of the received packet. If the - * checksum is invalid, packet will be dropped, as the end system will - * also drop the packet. - * - * \param p Packet of which checksum has to be validated - * \retval 1 if the checksum is valid, otherwise 0 - */ -static inline int StreamTcpValidateChecksum(Packet *p) -{ - int ret = 1; - - if (p->flags & PKT_IGNORE_CHECKSUM) - return ret; - - if (p->level4_comp_csum == -1) { - if (PKT_IS_IPV4(p)) { - p->level4_comp_csum = TCPCalculateChecksum(p->ip4h->s_ip_addrs, - (uint16_t *)p->tcph, - (p->payload_len + - TCP_GET_HLEN(p))); - } else if (PKT_IS_IPV6(p)) { - p->level4_comp_csum = TCPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, - (p->payload_len + - TCP_GET_HLEN(p))); - } - } - - if (p->level4_comp_csum != p->tcph->th_sum) { - ret = 0; - SCLogDebug("Checksum of received packet %p is invalid",p); - if (p->livedev) { - (void) SC_ATOMIC_ADD(p->livedev->invalid_checksums, 1); - } else if (p->pcap_cnt) { - PcapIncreaseInvalidChecksum(); - } - } - - return ret; -} - -/** \internal - * \brief check if a packet is a valid stream started - * \retval bool true/false */ -static int TcpSessionPacketIsStreamStarter(const Packet *p) -{ - if (p->tcph->th_flags == TH_SYN) { - SCLogDebug("packet %"PRIu64" is a stream starter: %02x", p->pcap_cnt, p->tcph->th_flags); - return 1; - } - - if (stream_config.midstream == TRUE || stream_config.async_oneside == TRUE) { - if (p->tcph->th_flags == (TH_SYN|TH_ACK)) { - SCLogDebug("packet %"PRIu64" is a midstream stream starter: %02x", p->pcap_cnt, p->tcph->th_flags); - return 1; - } - } - return 0; -} - -/** \internal - * \brief Check if Flow and TCP SSN allow this flow/tuple to be reused - * \retval bool true yes reuse, false no keep tracking old ssn */ -static int TcpSessionReuseDoneEnoughSyn(const Packet *p, const Flow *f, const TcpSession *ssn) -{ - if (FlowGetPacketDirection(f, p) == TOSERVER) { - if (ssn == NULL) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p null. No reuse.", p->pcap_cnt, ssn); - return 0; - } - if (SEQ_EQ(ssn->client.isn, TCP_GET_SEQ(p))) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->pcap_cnt, ssn); - return 0; - } - if (ssn->state >= TCP_LAST_ACK) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->pcap_cnt, ssn, ssn->state); - return 1; - } - if (ssn->state == TCP_NONE) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state == TCP_NONE (%u). Reuse.", p->pcap_cnt, ssn, ssn->state); - return 1; - } - if (ssn->state < TCP_LAST_ACK) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->pcap_cnt, ssn, ssn->state); - return 0; - } - - } else { - if (ssn == NULL) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p null. Reuse.", p->pcap_cnt, ssn); - return 1; - } - if (ssn->state >= TCP_LAST_ACK) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->pcap_cnt, ssn, ssn->state); - return 1; - } - if (ssn->state == TCP_NONE) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state == TCP_NONE (%u). Reuse.", p->pcap_cnt, ssn, ssn->state); - return 1; - } - if (ssn->state < TCP_LAST_ACK) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->pcap_cnt, ssn, ssn->state); - return 0; - } - } - - SCLogDebug("default: how did we get here?"); - return 0; -} - -/** \internal - * \brief check if ssn is done enough for reuse by syn/ack - * \note should only be called if midstream is enabled - */ -static int TcpSessionReuseDoneEnoughSynAck(const Packet *p, const Flow *f, const TcpSession *ssn) -{ - if (FlowGetPacketDirection(f, p) == TOCLIENT) { - if (ssn == NULL) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p null. No reuse.", p->pcap_cnt, ssn); - return 0; - } - if (SEQ_EQ(ssn->server.isn, TCP_GET_SEQ(p))) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->pcap_cnt, ssn); - return 0; - } - if (ssn->state >= TCP_LAST_ACK) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->pcap_cnt, ssn, ssn->state); - return 1; - } - if (ssn->state == TCP_NONE) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state == TCP_NONE (%u). Reuse.", p->pcap_cnt, ssn, ssn->state); - return 1; - } - if (ssn->state < TCP_LAST_ACK) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->pcap_cnt, ssn, ssn->state); - return 0; - } - - } else { - if (ssn == NULL) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p null. Reuse.", p->pcap_cnt, ssn); - return 1; - } - if (ssn->state >= TCP_LAST_ACK) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->pcap_cnt, ssn, ssn->state); - return 1; - } - if (ssn->state == TCP_NONE) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state == TCP_NONE (%u). Reuse.", p->pcap_cnt, ssn, ssn->state); - return 1; - } - if (ssn->state < TCP_LAST_ACK) { - SCLogDebug("steam starter packet %"PRIu64", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->pcap_cnt, ssn, ssn->state); - return 0; - } - } - - SCLogDebug("default: how did we get here?"); - return 0; -} - -/** \brief Check if SSN is done enough for reuse - * - * Reuse means a new TCP session reuses the tuple (flow in suri) - * - * \retval bool true if ssn can be reused, false if not */ -int TcpSessionReuseDoneEnough(const Packet *p, const Flow *f, const TcpSession *ssn) -{ - if (p->tcph->th_flags == TH_SYN) { - return TcpSessionReuseDoneEnoughSyn(p, f, ssn); - } - - if (stream_config.midstream == TRUE || stream_config.async_oneside == TRUE) { - if (p->tcph->th_flags == (TH_SYN|TH_ACK)) { - return TcpSessionReuseDoneEnoughSynAck(p, f, ssn); - } - } - - return 0; -} - -int TcpSessionPacketSsnReuse(const Packet *p, const Flow *f, const void *tcp_ssn) -{ - if (p->proto == IPPROTO_TCP && p->tcph != NULL) { - if (TcpSessionPacketIsStreamStarter(p) == 1) { - if (TcpSessionReuseDoneEnough(p, f, tcp_ssn) == 1) { - return 1; - } - } - } - return 0; -} - -/** \brief Handle TCP reuse of tuple - * - * Logic: - * 1. see if packet could trigger a new session - * 2. see if the flow/ssn is in a state where we want to support the reuse - * 3. disconnect packet from the old flow - * -> at this point new packets can still find the old flow - * -> as the flow's reference count != 0, it can't disappear - * 4. setup a new flow unconditionally - * 5. attach packet to new flow - * 6. tag old flow as FLOW_TCP_REUSED - * -> NEW packets won't find it - * -> existing packets in our queues may still reference it - * 7. dereference the old flow (reference cnt *may* now be 0, - * if no other packets reference it) - * - * The packets that still hold a reference to the old flow are updated - * by HandleFlowReuseApplyToPacket() - */ -static void TcpSessionReuseHandle(Packet *p) { - if (likely(TcpSessionPacketIsStreamStarter(p) == 0)) - return; - - int reuse = 0; - FLOWLOCK_RDLOCK(p->flow); - reuse = TcpSessionReuseDoneEnough(p, p->flow, p->flow->protoctx); - if (!reuse) { - SCLogDebug("steam starter packet %"PRIu64", but state not " - "ready to be reused", p->pcap_cnt); - FLOWLOCK_UNLOCK(p->flow); - return; - } - - SCLogDebug("steam starter packet %"PRIu64", and state " - "ready to be reused", p->pcap_cnt); - - /* ok, this packet needs a new flow */ - - /* first, get a reference to the old flow */ - Flow *old_f = NULL; - FlowReference(&old_f, p->flow); - - /* get some settings that we move over to the new flow */ - FlowThreadId thread_id = old_f->thread_id; - int autofp_tmqh_flow_qid = SC_ATOMIC_GET(old_f->autofp_tmqh_flow_qid); - - /* disconnect the packet from the old flow */ - FlowHandlePacketUpdateRemove(p->flow, p); - FLOWLOCK_UNLOCK(p->flow); - FlowDeReference(&p->flow); // < can't disappear while usecnt >0 - - /* Can't tag flow as reused yet, would be a race condition: - * new packets will not get old flow because of FLOW_TCP_REUSED, - * so new flow may be created. This new flow could be handled in - * a different thread. */ - - /* Get a flow. It will be either a locked flow or NULL */ - Flow *new_f = FlowGetFlowFromHashByPacket(p); - if (new_f == NULL) { - FlowDeReference(&old_f); // < can't disappear while usecnt >0 - return; - } - - /* update flow and packet */ - FlowHandlePacketUpdate(new_f, p); - BUG_ON(new_f != p->flow); - - /* copy flow balancing settings */ - new_f->thread_id = thread_id; - SC_ATOMIC_SET(new_f->autofp_tmqh_flow_qid, autofp_tmqh_flow_qid); - - FLOWLOCK_UNLOCK(new_f); - - /* tag original flow that it's now unused */ - FLOWLOCK_WRLOCK(old_f); - SCLogDebug("old flow %p tagged with FLOW_TCP_REUSED by packet %"PRIu64"!", old_f, p->pcap_cnt); - old_f->flags |= FLOW_TCP_REUSED; - FLOWLOCK_UNLOCK(old_f); - FlowDeReference(&old_f); // < can't disappear while usecnt >0 - - SCLogDebug("new flow %p set up for packet %"PRIu64"!", p->flow, p->pcap_cnt); -} - -/** \brief Handle packets that reference the wrong flow because of TCP reuse - * - * In the case of TCP reuse we can have many packets that were assigned - * a flow by the capture/decode threads before the stream engine decided - * that a new flow was needed for these packets. - * When HandleFlowReuse creates a new flow, the packets already processed - * by the flow engine will still reference the old flow. - * - * This function detects this case and replaces the flow for those packets. - * It's a fairly expensive operation, but it should be rare as it's only - * done for packets that were already in the engine when the TCP reuse - * case was handled. New packets are assigned the correct flow by the - * flow engine. - */ -static void TcpSessionReuseHandleApplyToPacket(Packet *p) -{ - int need_flow_replace = 0; - - FLOWLOCK_WRLOCK(p->flow); - if (p->flow->flags & FLOW_TCP_REUSED) { - SCLogDebug("packet %"PRIu64" attached to outdated flow and ssn", p->pcap_cnt); - need_flow_replace = 1; - } - - if (likely(need_flow_replace == 0)) { - /* Work around a race condition: if HandleFlowReuse has inserted a new flow, - * it will not have seen both sides of the session yet. The packet we have here - * may be the first that got the flow directly from the hash right after the - * flow was added. In this case it won't have FLOW_PKT_ESTABLISHED flag set. */ - if ((p->flow->flags & FLOW_TO_DST_SEEN) && (p->flow->flags & FLOW_TO_SRC_SEEN)) { - p->flowflags |= FLOW_PKT_ESTABLISHED; - SCLogDebug("packet %"PRIu64" / flow %p: p->flowflags |= FLOW_PKT_ESTABLISHED (%u/%u)", p->pcap_cnt, p->flow, p->flow->todstpktcnt, p->flow->tosrcpktcnt); - } else { - SCLogDebug("packet %"PRIu64" / flow %p: p->flowflags NOT FLOW_PKT_ESTABLISHED (%u/%u)", p->pcap_cnt, p->flow, p->flow->todstpktcnt, p->flow->tosrcpktcnt); - } - SCLogDebug("packet %"PRIu64" attached to regular flow %p and ssn", p->pcap_cnt, p->flow); - FLOWLOCK_UNLOCK(p->flow); - return; - } - - /* disconnect packet from old flow */ - FlowHandlePacketUpdateRemove(p->flow, p); - FLOWLOCK_UNLOCK(p->flow); - FlowDeReference(&p->flow); // < can't disappear while usecnt >0 - - /* find the new flow that does belong to this packet */ - Flow *new_f = FlowLookupFlowFromHash(p); - if (new_f == NULL) { - // TODO reset packet flag wrt flow: direction, HAS_FLOW etc - p->flags &= ~PKT_HAS_FLOW; - return; - } - FlowHandlePacketUpdate(new_f, p); - BUG_ON(new_f != p->flow); - FLOWLOCK_UNLOCK(new_f); - SCLogDebug("packet %"PRIu64" switched over to new flow %p!", p->pcap_cnt, p->flow); -} - -TmEcode StreamTcp (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) -{ - StreamTcpThread *stt = (StreamTcpThread *)data; - TmEcode ret = TM_ECODE_OK; - - if (!(PKT_IS_TCP(p))) - return TM_ECODE_OK; - - if (p->flow == NULL) { - StatsIncr(tv, stt->counter_tcp_no_flow); - return TM_ECODE_OK; - } - - if (stream_config.flags & STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION) { - if (StreamTcpValidateChecksum(p) == 0) { - StatsIncr(tv, stt->counter_tcp_invalid_checksum); - return TM_ECODE_OK; - } - } else { - p->flags |= PKT_IGNORE_CHECKSUM; - } - - if (stt->runmode_flow_stream_async) { - /* "autofp" handling of TCP session/flow reuse */ - if (!(p->flags & PKT_PSEUDO_STREAM_END)) { - /* apply previous reuses to this packet */ - TcpSessionReuseHandleApplyToPacket(p); - if (p->flow == NULL) - return ret; - - if (!(p->flowflags & FLOW_PKT_TOSERVER_FIRST)) { - /* after that, check for 'new' reuse */ - TcpSessionReuseHandle(p); - if (p->flow == NULL) - return ret; - } - } - } - AppLayerProfilingReset(stt->ra_ctx->app_tctx); - - FLOWLOCK_WRLOCK(p->flow); - ret = StreamTcpPacket(tv, p, stt, pq); - FLOWLOCK_UNLOCK(p->flow); - - //if (ret) - // return TM_ECODE_FAILED; - - stt->pkts++; - return ret; -} - -TmEcode StreamTcpThreadInit(ThreadVars *tv, void *initdata, void **data) -{ - SCEnter(); - StreamTcpThread *stt = SCMalloc(sizeof(StreamTcpThread)); - if (unlikely(stt == NULL)) - SCReturnInt(TM_ECODE_FAILED); - memset(stt, 0, sizeof(StreamTcpThread)); - stt->ssn_pool_id = -1; - - *data = (void *)stt; - - stt->counter_tcp_sessions = StatsRegisterCounter("tcp.sessions", tv); - stt->counter_tcp_ssn_memcap = StatsRegisterCounter("tcp.ssn_memcap_drop", tv); - stt->counter_tcp_pseudo = StatsRegisterCounter("tcp.pseudo", tv); - stt->counter_tcp_pseudo_failed = StatsRegisterCounter("tcp.pseudo_failed", tv); - stt->counter_tcp_invalid_checksum = StatsRegisterCounter("tcp.invalid_checksum", tv); - stt->counter_tcp_no_flow = StatsRegisterCounter("tcp.no_flow", tv); - stt->counter_tcp_syn = StatsRegisterCounter("tcp.syn", tv); - stt->counter_tcp_synack = StatsRegisterCounter("tcp.synack", tv); - stt->counter_tcp_rst = StatsRegisterCounter("tcp.rst", tv); - - /* init reassembly ctx */ - stt->ra_ctx = StreamTcpReassembleInitThreadCtx(tv); - if (stt->ra_ctx == NULL) - SCReturnInt(TM_ECODE_FAILED); - - stt->ra_ctx->counter_tcp_segment_memcap = StatsRegisterCounter("tcp.segment_memcap_drop", tv); - stt->ra_ctx->counter_tcp_stream_depth = StatsRegisterCounter("tcp.stream_depth_reached", tv); - stt->ra_ctx->counter_tcp_reass_gap = StatsRegisterCounter("tcp.reassembly_gap", tv); - - SCLogDebug("StreamTcp thread specific ctx online at %p, reassembly ctx %p", - stt, stt->ra_ctx); - - SCMutexLock(&ssn_pool_mutex); - if (ssn_pool == NULL) { - ssn_pool = PoolThreadInit(1, /* thread */ - 0, /* unlimited */ - stream_config.prealloc_sessions, - sizeof(TcpSession), - StreamTcpSessionPoolAlloc, - StreamTcpSessionPoolInit, NULL, - StreamTcpSessionPoolCleanup, NULL); - stt->ssn_pool_id = 0; - SCLogDebug("pool size %d, thread ssn_pool_id %d", PoolThreadSize(ssn_pool), stt->ssn_pool_id); - } else { - /* grow ssn_pool until we have a element for our thread id */ - stt->ssn_pool_id = PoolThreadGrow(ssn_pool, - 0, /* unlimited */ - stream_config.prealloc_sessions, - sizeof(TcpSession), - StreamTcpSessionPoolAlloc, - StreamTcpSessionPoolInit, NULL, - StreamTcpSessionPoolCleanup, NULL); - SCLogDebug("pool size %d, thread ssn_pool_id %d", PoolThreadSize(ssn_pool), stt->ssn_pool_id); - } - SCMutexUnlock(&ssn_pool_mutex); - if (stt->ssn_pool_id < 0 || ssn_pool == NULL) - SCReturnInt(TM_ECODE_FAILED); - - /* see if need to enable the TCP reuse handling in the stream engine */ - stt->runmode_flow_stream_async = RunmodeGetFlowStreamAsync(); - SCLogDebug("Flow and Stream engine run %s", - stt->runmode_flow_stream_async ? "asynchronous" : "synchronous"); - - SCReturnInt(TM_ECODE_OK); -} - -TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data) -{ - SCEnter(); - StreamTcpThread *stt = (StreamTcpThread *)data; - if (stt == NULL) { - return TM_ECODE_OK; - } - - /* XXX */ - - /* free reassembly ctx */ - StreamTcpReassembleFreeThreadCtx(stt->ra_ctx); - - /* clear memory */ - memset(stt, 0, sizeof(StreamTcpThread)); - - SCFree(stt); - SCReturnInt(TM_ECODE_OK); -} - -void StreamTcpExitPrintStats(ThreadVars *tv, void *data) -{ - StreamTcpThread *stt = (StreamTcpThread *)data; - if (stt == NULL) { - return; - } - - SCLogInfo("Stream TCP processed %" PRIu64 " TCP packets", stt->pkts); -} - -/** - * \brief Function to check the validity of the RST packets based on the - * target OS of the given packet. - * - * \param ssn TCP session to which the given packet belongs - * \param p Packet which has to be checked for its validity - * - * \retval 0 unacceptable RST - * \retval 1 acceptable RST - * - * WebSense sends RST packets that are: - * - RST flag, win 0, ack 0, seq = nextseq - * - */ - -static int StreamTcpValidateRst(TcpSession *ssn, Packet *p) -{ - - uint8_t os_policy; - - if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) { - if (!StreamTcpValidateTimestamp(ssn, p)) { - SCReturnInt(0); - } - } - - /* Set up the os_policy to be used in validating the RST packets based on - target system */ - if (PKT_IS_TOSERVER(p)) { - if (ssn->server.os_policy == 0) - StreamTcpSetOSPolicy(&ssn->server, p); - - os_policy = ssn->server.os_policy; - - if (p->tcph->th_flags & TH_ACK && - TCP_GET_ACK(p) && StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_RST_INVALID_ACK); - SCReturnInt(0); - } - - } else { - if (ssn->client.os_policy == 0) - StreamTcpSetOSPolicy(&ssn->client, p); - - os_policy = ssn->client.os_policy; - - if (p->tcph->th_flags & TH_ACK && - TCP_GET_ACK(p) && StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { - SCLogDebug("ssn %p: rejecting because of invalid ack value", ssn); - StreamTcpSetEvent(p, STREAM_RST_INVALID_ACK); - SCReturnInt(0); - } - } - - switch (os_policy) { - case OS_POLICY_HPUX11: - if(PKT_IS_TOSERVER(p)){ - if(SEQ_GEQ(TCP_GET_SEQ(p), ssn->client.next_seq)) { - SCLogDebug("reset is Valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); - return 1; - } else { - SCLogDebug("reset is not Valid! Packet SEQ: %" PRIu32 " " - "and server SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->client.next_seq); - return 0; - } - } else { /* implied to client */ - if(SEQ_GEQ(TCP_GET_SEQ(p), ssn->server.next_seq)) { - SCLogDebug("reset is valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); - return 1; - } else { - SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " " - "and client SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->server.next_seq); - return 0; - } - } - break; - case OS_POLICY_OLD_LINUX: - case OS_POLICY_LINUX: - case OS_POLICY_SOLARIS: - if(PKT_IS_TOSERVER(p)){ - if(SEQ_GEQ((TCP_GET_SEQ(p)+p->payload_len), - ssn->client.last_ack)) - { /*window base is needed !!*/ - if(SEQ_LT(TCP_GET_SEQ(p), - (ssn->client.next_seq + ssn->client.window))) - { - SCLogDebug("reset is Valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); - return 1; - } - } else { - SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " and" - " server SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->client.next_seq); - return 0; - } - } else { /* implied to client */ - if(SEQ_GEQ((TCP_GET_SEQ(p) + p->payload_len), - ssn->server.last_ack)) - { /*window base is needed !!*/ - if(SEQ_LT(TCP_GET_SEQ(p), - (ssn->server.next_seq + ssn->server.window))) - { - SCLogDebug("reset is Valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); - return 1; - } - } else { - SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " and" - " client SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->server.next_seq); - return 0; - } - } - break; - default: - case OS_POLICY_BSD: - case OS_POLICY_FIRST: - case OS_POLICY_HPUX10: - case OS_POLICY_IRIX: - case OS_POLICY_MACOS: - case OS_POLICY_LAST: - case OS_POLICY_WINDOWS: - case OS_POLICY_WINDOWS2K3: - case OS_POLICY_VISTA: - if(PKT_IS_TOSERVER(p)) { - if(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq)) { - SCLogDebug("reset is valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); - return 1; - } else { - SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " " - "and server SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->client.next_seq); - return 0; - } - } else { /* implied to client */ - if(SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq)) { - SCLogDebug("reset is valid! Packet SEQ: %" PRIu32 "", - TCP_GET_SEQ(p)); - return 1; - } else { - SCLogDebug("reset is not valid! Packet SEQ: %" PRIu32 " and" - " client SEQ: %" PRIu32 "", TCP_GET_SEQ(p), - ssn->server.next_seq); - return 0; - } - } - break; - } - return 0; -} - -/** - * \brief Function to check the validity of the received timestamp based on - * the target OS of the given stream. - * - * It's passive except for: - * 1. it sets the os policy on the stream if necessary - * 2. it sets an event in the packet if necessary - * - * \param ssn TCP session to which the given packet belongs - * \param p Packet which has to be checked for its validity - * - * \retval 1 if the timestamp is valid - * \retval 0 if the timestamp is invalid - */ -static int StreamTcpValidateTimestamp (TcpSession *ssn, Packet *p) -{ - SCEnter(); - - TcpStream *sender_stream; - TcpStream *receiver_stream; - uint8_t ret = 1; - uint8_t check_ts = 1; - - if (PKT_IS_TOSERVER(p)) { - sender_stream = &ssn->client; - receiver_stream = &ssn->server; - } else { - sender_stream = &ssn->server; - receiver_stream = &ssn->client; - } - - /* Set up the os_policy to be used in validating the timestamps based on - the target system */ - if (receiver_stream->os_policy == 0) { - StreamTcpSetOSPolicy(receiver_stream, p); - } - - if (p->tcpvars.ts != NULL) { - uint32_t ts = TCP_GET_TSVAL(p); - uint32_t last_pkt_ts = sender_stream->last_pkt_ts; - uint32_t last_ts = sender_stream->last_ts; - - if (sender_stream->flags & STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP) { - /* The 3whs used the timestamp with 0 value. */ - switch (receiver_stream->os_policy) { - case OS_POLICY_LINUX: - case OS_POLICY_WINDOWS2K3: - /* Linux and windows 2003 does not allow the use of 0 as - * timestamp in the 3whs. */ - check_ts = 0; - break; - - case OS_POLICY_OLD_LINUX: - case OS_POLICY_WINDOWS: - case OS_POLICY_VISTA: - if (SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) { - last_ts = ts; - check_ts = 0; /*next packet will be checked for validity - and stream TS has been updated with this - one.*/ - } - break; - } - } - - if (receiver_stream->os_policy == OS_POLICY_HPUX11) { - /* HPUX11 igoners the timestamp of out of order packets */ - if (!SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) - check_ts = 0; - } - - if (ts == 0) { - switch (receiver_stream->os_policy) { - case OS_POLICY_OLD_LINUX: - case OS_POLICY_WINDOWS: - case OS_POLICY_WINDOWS2K3: - case OS_POLICY_VISTA: - case OS_POLICY_SOLARIS: - /* Old Linux and windows allowed packet with 0 timestamp. */ - break; - default: - /* other OS simply drop the pakcet with 0 timestamp, when - * 3whs has valid timestamp*/ - goto invalid; - } - } - - if (check_ts) { - int32_t result = 0; - - SCLogDebug("ts %"PRIu32", last_ts %"PRIu32"", ts, last_ts); - - if (receiver_stream->os_policy == OS_POLICY_LINUX) { - /* Linux accepts TS which are off by one.*/ - result = (int32_t) ((ts - last_ts) + 1); - } else { - result = (int32_t) (ts - last_ts); - } - - SCLogDebug("result %"PRIi32", p->ts.tv_sec %"PRIuMAX"", result, (uintmax_t)p->ts.tv_sec); - - if (last_pkt_ts == 0 && - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM)) - { - last_pkt_ts = p->ts.tv_sec; - } - - if (result < 0) { - SCLogDebug("timestamp is not valid last_ts " - "%" PRIu32 " p->tcpvars->ts %" PRIu32 " result " - "%" PRId32 "", last_ts, ts, result); - /* candidate for rejection */ - ret = 0; - } else if ((sender_stream->last_ts != 0) && - (((uint32_t) p->ts.tv_sec) > - last_pkt_ts + PAWS_24DAYS)) - { - SCLogDebug("packet is not valid last_pkt_ts " - "%" PRIu32 " p->ts.tv_sec %" PRIu32 "", - last_pkt_ts, (uint32_t) p->ts.tv_sec); - /* candidate for rejection */ - ret = 0; - } - - if (ret == 0) { - /* if the timestamp of packet is not valid then, check if the - * current stream timestamp is not so old. if so then we need to - * accept the packet and update the stream->last_ts (RFC 1323)*/ - if ((SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) && - (((uint32_t) p->ts.tv_sec > (last_pkt_ts + PAWS_24DAYS)))) - { - SCLogDebug("timestamp considered valid anyway"); - } else { - goto invalid; - } - } - } - } - - SCReturnInt(1); - -invalid: - StreamTcpSetEvent(p, STREAM_PKT_INVALID_TIMESTAMP); - SCReturnInt(0); -} - -/** - * \brief Function to check the validity of the received timestamp based on - * the target OS of the given stream and update the session. - * - * \param ssn TCP session to which the given packet belongs - * \param p Packet which has to be checked for its validity - * - * \retval 1 if the timestamp is valid - * \retval 0 if the timestamp is invalid - */ -static int StreamTcpHandleTimestamp (TcpSession *ssn, Packet *p) -{ - SCEnter(); - - TcpStream *sender_stream; - TcpStream *receiver_stream; - uint8_t ret = 1; - uint8_t check_ts = 1; - - if (PKT_IS_TOSERVER(p)) { - sender_stream = &ssn->client; - receiver_stream = &ssn->server; - } else { - sender_stream = &ssn->server; - receiver_stream = &ssn->client; - } - - /* Set up the os_policy to be used in validating the timestamps based on - the target system */ - if (receiver_stream->os_policy == 0) { - StreamTcpSetOSPolicy(receiver_stream, p); - } - - if (p->tcpvars.ts != NULL) { - uint32_t ts = TCP_GET_TSVAL(p); - - if (sender_stream->flags & STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP) { - /* The 3whs used the timestamp with 0 value. */ - switch (receiver_stream->os_policy) { - case OS_POLICY_LINUX: - case OS_POLICY_WINDOWS2K3: - /* Linux and windows 2003 does not allow the use of 0 as - * timestamp in the 3whs. */ - ssn->flags &= ~STREAMTCP_FLAG_TIMESTAMP; - check_ts = 0; - break; - - case OS_POLICY_OLD_LINUX: - case OS_POLICY_WINDOWS: - case OS_POLICY_VISTA: - sender_stream->flags &= ~STREAMTCP_STREAM_FLAG_ZERO_TIMESTAMP; - if (SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) { - sender_stream->last_ts = ts; - check_ts = 0; /*next packet will be checked for validity - and stream TS has been updated with this - one.*/ - } - break; - default: - break; - } - } - - if (receiver_stream->os_policy == OS_POLICY_HPUX11) { - /*HPUX11 igoners the timestamp of out of order packets*/ - if (!SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) - check_ts = 0; - } - - if (ts == 0) { - switch (receiver_stream->os_policy) { - case OS_POLICY_OLD_LINUX: - case OS_POLICY_WINDOWS: - case OS_POLICY_WINDOWS2K3: - case OS_POLICY_VISTA: - case OS_POLICY_SOLARIS: - /* Old Linux and windows allowed packet with 0 timestamp. */ - break; - default: - /* other OS simply drop the pakcet with 0 timestamp, when - * 3whs has valid timestamp*/ - goto invalid; - } - } - - if (check_ts) { - int32_t result = 0; - - SCLogDebug("ts %"PRIu32", last_ts %"PRIu32"", ts, sender_stream->last_ts); - - if (receiver_stream->os_policy == OS_POLICY_LINUX) { - /* Linux accepts TS which are off by one.*/ - result = (int32_t) ((ts - sender_stream->last_ts) + 1); - } else { - result = (int32_t) (ts - sender_stream->last_ts); - } - - SCLogDebug("result %"PRIi32", p->ts.tv_sec %"PRIuMAX"", result, (uintmax_t)p->ts.tv_sec); - - if (sender_stream->last_pkt_ts == 0 && - (ssn->flags & STREAMTCP_FLAG_MIDSTREAM)) - { - sender_stream->last_pkt_ts = p->ts.tv_sec; - } - - if (result < 0) { - SCLogDebug("timestamp is not valid sender_stream->last_ts " - "%" PRIu32 " p->tcpvars->ts %" PRIu32 " result " - "%" PRId32 "", sender_stream->last_ts, ts, result); - /* candidate for rejection */ - ret = 0; - } else if ((sender_stream->last_ts != 0) && - (((uint32_t) p->ts.tv_sec) > - sender_stream->last_pkt_ts + PAWS_24DAYS)) - { - SCLogDebug("packet is not valid sender_stream->last_pkt_ts " - "%" PRIu32 " p->ts.tv_sec %" PRIu32 "", - sender_stream->last_pkt_ts, (uint32_t) p->ts.tv_sec); - /* candidate for rejection */ - ret = 0; - } - - if (ret == 1) { - /* Update the timestamp and last seen packet time for this - * stream */ - if (SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) - sender_stream->last_ts = ts; - - sender_stream->last_pkt_ts = p->ts.tv_sec; - - } else if (ret == 0) { - /* if the timestamp of packet is not valid then, check if the - * current stream timestamp is not so old. if so then we need to - * accept the packet and update the stream->last_ts (RFC 1323)*/ - if ((SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) && - (((uint32_t) p->ts.tv_sec > (sender_stream->last_pkt_ts + PAWS_24DAYS)))) - { - sender_stream->last_ts = ts; - sender_stream->last_pkt_ts = p->ts.tv_sec; - - SCLogDebug("timestamp considered valid anyway"); - } else { - goto invalid; - } - } - } - } else { - /* Solaris stops using timestamps if a packet is received - without a timestamp and timestamps were used on that stream. */ - if (receiver_stream->os_policy == OS_POLICY_SOLARIS) - ssn->flags &= ~STREAMTCP_FLAG_TIMESTAMP; - } - - SCReturnInt(1); - -invalid: - StreamTcpSetEvent(p, STREAM_PKT_INVALID_TIMESTAMP); - SCReturnInt(0); -} - -/** - * \brief Function to test the received ACK values against the stream window - * and previous ack value. ACK values should be higher than previous - * ACK value and less than the next_win value. - * - * \param ssn TcpSession for state access - * \param stream TcpStream of which last_ack needs to be tested - * \param p Packet which is used to test the last_ack - * - * \retval 0 ACK is valid, last_ack is updated if ACK was higher - * \retval -1 ACK is invalid - */ -static inline int StreamTcpValidateAck(TcpSession *ssn, TcpStream *stream, Packet *p) -{ - SCEnter(); - - uint32_t ack = TCP_GET_ACK(p); - - /* fast track */ - if (SEQ_GT(ack, stream->last_ack) && SEQ_LEQ(ack, stream->next_win)) - { - SCLogDebug("ACK in bounds"); - SCReturnInt(0); - } - /* fast track */ - else if (SEQ_EQ(ack, stream->last_ack)) { - SCLogDebug("pkt ACK %"PRIu32" == stream last ACK %"PRIu32, TCP_GET_ACK(p), stream->last_ack); - SCReturnInt(0); - } - - /* exception handling */ - if (SEQ_LT(ack, stream->last_ack)) { - SCLogDebug("pkt ACK %"PRIu32" < stream last ACK %"PRIu32, TCP_GET_ACK(p), stream->last_ack); - - /* This is an attempt to get a 'left edge' value that we can check against. - * It doesn't work when the window is 0, need to think of a better way. */ - - if (stream->window != 0 && SEQ_LT(ack, (stream->last_ack - stream->window))) { - SCLogDebug("ACK %"PRIu32" is before last_ack %"PRIu32" - window " - "%"PRIu32" = %"PRIu32, ack, stream->last_ack, - stream->window, stream->last_ack - stream->window); - goto invalid; - } - - SCReturnInt(0); - } - - if (ssn->state > TCP_SYN_SENT && SEQ_GT(ack, stream->next_win)) { - SCLogDebug("ACK %"PRIu32" is after next_win %"PRIu32, ack, stream->next_win); - goto invalid; - /* a toclient RST as a reponse to SYN, next_win is 0, ack will be isn+1, just like - * the syn ack */ - } else if (ssn->state == TCP_SYN_SENT && PKT_IS_TOCLIENT(p) && - p->tcph->th_flags & TH_RST && - SEQ_EQ(ack, stream->isn + 1)) { - SCReturnInt(0); - } - - SCLogDebug("default path leading to invalid: ACK %"PRIu32", last_ack %"PRIu32 - " next_win %"PRIu32, ack, stream->last_ack, stream->next_win); -invalid: - StreamTcpSetEvent(p, STREAM_PKT_INVALID_ACK); - SCReturnInt(-1); -} - -/** \brief Set the No reassembly flag for the given direction in given TCP - * session. - * - * \param ssn TCP Session to set the flag in - * \param direction direction to set the flag in: 0 toserver, 1 toclient - */ -void StreamTcpSetSessionNoReassemblyFlag (TcpSession *ssn, char direction) -{ - direction ? (ssn->server.flags |= STREAMTCP_STREAM_FLAG_NOREASSEMBLY) : - (ssn->client.flags |= STREAMTCP_STREAM_FLAG_NOREASSEMBLY); -} - -/** \brief Set the No reassembly flag for the given direction in given TCP - * session. - * - * \param ssn TCP Session to set the flag in - * \param direction direction to set the flag in: 0 toserver, 1 toclient - */ -void StreamTcpSetDisableRawReassemblyFlag (TcpSession *ssn, char direction) -{ - direction ? (ssn->server.flags |= STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED) : - (ssn->client.flags |= STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED); -} - -#define PSEUDO_PKT_SET_IPV4HDR(nipv4h,ipv4h) do { \ - IPV4_SET_RAW_VER(nipv4h, IPV4_GET_RAW_VER(ipv4h)); \ - IPV4_SET_RAW_HLEN(nipv4h, IPV4_GET_RAW_HLEN(ipv4h)); \ - IPV4_SET_RAW_IPLEN(nipv4h, IPV4_GET_RAW_IPLEN(ipv4h)); \ - IPV4_SET_RAW_IPTOS(nipv4h, IPV4_GET_RAW_IPTOS(ipv4h)); \ - IPV4_SET_RAW_IPPROTO(nipv4h, IPV4_GET_RAW_IPPROTO(ipv4h)); \ - (nipv4h)->s_ip_src = IPV4_GET_RAW_IPDST(ipv4h); \ - (nipv4h)->s_ip_dst = IPV4_GET_RAW_IPSRC(ipv4h); \ - } while (0) - -#define PSEUDO_PKT_SET_IPV6HDR(nipv6h,ipv6h) do { \ - (nipv6h)->s_ip6_src[0] = (ipv6h)->s_ip6_dst[0]; \ - (nipv6h)->s_ip6_src[1] = (ipv6h)->s_ip6_dst[1]; \ - (nipv6h)->s_ip6_src[2] = (ipv6h)->s_ip6_dst[2]; \ - (nipv6h)->s_ip6_src[3] = (ipv6h)->s_ip6_dst[3]; \ - (nipv6h)->s_ip6_dst[0] = (ipv6h)->s_ip6_src[0]; \ - (nipv6h)->s_ip6_dst[1] = (ipv6h)->s_ip6_src[1]; \ - (nipv6h)->s_ip6_dst[2] = (ipv6h)->s_ip6_src[2]; \ - (nipv6h)->s_ip6_dst[3] = (ipv6h)->s_ip6_src[3]; \ - IPV6_SET_RAW_NH(nipv6h, IPV6_GET_RAW_NH(ipv6h)); \ - } while (0) - -#define PSEUDO_PKT_SET_TCPHDR(ntcph,tcph) do { \ - COPY_PORT((tcph)->th_dport, (ntcph)->th_sport); \ - COPY_PORT((tcph)->th_sport, (ntcph)->th_dport); \ - (ntcph)->th_seq = (tcph)->th_ack; \ - (ntcph)->th_ack = (tcph)->th_seq; \ - } while (0) - -/** - * \brief Function to fetch a packet from the packet allocation queue for - * creation of the pseudo packet from the reassembled stream. - * - * @param parent Pointer to the parent of the pseudo packet - * @param pkt pointer to the raw packet of the parent - * @param len length of the packet - * @return upon success returns the pointer to the new pseudo packet - * otherwise NULL - */ -Packet *StreamTcpPseudoSetup(Packet *parent, uint8_t *pkt, uint32_t len) -{ - SCEnter(); - - if (len == 0) { - SCReturnPtr(NULL, "Packet"); - } - - Packet *p = PacketGetFromQueueOrAlloc(); - if (p == NULL) { - SCReturnPtr(NULL, "Packet"); - } - - /* set the root ptr to the lowest layer */ - if (parent->root != NULL) - p->root = parent->root; - else - p->root = parent; - - /* copy packet and set lenght, proto */ - p->proto = parent->proto; - p->datalink = parent->datalink; - - PacketCopyData(p, pkt, len); - p->recursion_level = parent->recursion_level + 1; - p->ts.tv_sec = parent->ts.tv_sec; - p->ts.tv_usec = parent->ts.tv_usec; - - FlowReference(&p->flow, parent->flow); - /* set tunnel flags */ - - /* tell new packet it's part of a tunnel */ - SET_TUNNEL_PKT(p); - /* tell parent packet it's part of a tunnel */ - SET_TUNNEL_PKT(parent); - - /* increment tunnel packet refcnt in the root packet */ - TUNNEL_INCR_PKT_TPR(p); - - return p; -} - -/** - * \brief Function to setup the IP and TCP header of the pseudo packet from - * the newly copied raw packet contents of the parent. - * - * @param np pointer to the pseudo packet - * @param p pointer to the original packet - */ -static void StreamTcpPseudoPacketSetupHeader(Packet *np, Packet *p) -{ - /* Setup the IP header */ - if (PKT_IS_IPV4(p)) { - np->ip4h = (IPV4Hdr *)((uint8_t *)GET_PKT_DATA(np) + (GET_PKT_LEN(np) - IPV4_GET_IPLEN(p))); - PSEUDO_PKT_SET_IPV4HDR(np->ip4h, p->ip4h); - - /* Similarly setup the TCP header with ports in opposite direction */ - np->tcph = (TCPHdr *)((uint8_t *)np->ip4h + IPV4_GET_HLEN(np)); - - PSEUDO_PKT_SET_TCPHDR(np->tcph, p->tcph); - - /* Setup the adress and port details */ - SET_IPV4_SRC_ADDR(p, &np->dst); - SET_IPV4_DST_ADDR(p, &np->src); - SET_TCP_SRC_PORT(p, &np->dp); - SET_TCP_DST_PORT(p, &np->sp); - - } else if (PKT_IS_IPV6(p)) { - np->ip6h = (IPV6Hdr *)((uint8_t *)GET_PKT_DATA(np) + (GET_PKT_LEN(np) - IPV6_GET_PLEN(p) - IPV6_HEADER_LEN)); - PSEUDO_PKT_SET_IPV6HDR(np->ip6h, p->ip6h); - - /* Similarly setup the TCP header with ports in opposite direction */ - np->tcph = (TCPHdr *)((uint8_t *)np->ip6h + IPV6_HEADER_LEN); - PSEUDO_PKT_SET_TCPHDR(np->tcph, p->tcph); - - /* Setup the adress and port details */ - SET_IPV6_SRC_ADDR(p, &np->dst); - SET_IPV6_DST_ADDR(p, &np->src); - SET_TCP_SRC_PORT(p, &np->dp); - SET_TCP_DST_PORT(p, &np->sp); - } - - /* we don't need a payload (if any) */ - np->payload = NULL; - np->payload_len = 0; -} - -/** \brief Create a pseudo packet injected into the engine to signal the - * opposing direction of this stream to wrap up stream reassembly. - * - * \param p real packet - * \param pq packet queue to store the new pseudo packet in - */ -void StreamTcpPseudoPacketCreateStreamEndPacket(ThreadVars *tv, StreamTcpThread *stt, Packet *p, TcpSession *ssn, PacketQueue *pq) -{ - SCEnter(); - - if (p->flags & PKT_PSEUDO_STREAM_END) { - SCReturn; - } - - /* no need for a pseudo packet if there is nothing left to reassemble */ - if (ssn->server.seg_list == NULL && ssn->client.seg_list == NULL) { - SCReturn; - } - - Packet *np = StreamTcpPseudoSetup(p, GET_PKT_DATA(p), GET_PKT_LEN(p)); - if (np == NULL) { - SCLogDebug("The packet received from packet allocation is NULL"); - StatsIncr(tv, stt->counter_tcp_pseudo_failed); - SCReturn; - } - PKT_SET_SRC(np, PKT_SRC_STREAM_TCP_STREAM_END_PSEUDO); - - /* Setup the IP and TCP headers */ - StreamTcpPseudoPacketSetupHeader(np,p); - - np->tenant_id = p->flow->tenant_id; - - np->flowflags = p->flowflags; - - np->flags |= PKT_STREAM_EST; - np->flags |= PKT_STREAM_EOF; - np->flags |= PKT_HAS_FLOW; - np->flags |= PKT_PSEUDO_STREAM_END; - - if (p->flags & PKT_NOPACKET_INSPECTION) { - DecodeSetNoPacketInspectionFlag(np); - } - if (p->flags & PKT_NOPAYLOAD_INSPECTION) { - DecodeSetNoPayloadInspectionFlag(np); - } - - if (PKT_IS_TOSERVER(p)) { - SCLogDebug("original is to_server, so pseudo is to_client"); - np->flowflags &= ~FLOW_PKT_TOSERVER; - np->flowflags |= FLOW_PKT_TOCLIENT; -#ifdef DEBUG - BUG_ON(!(PKT_IS_TOCLIENT(np))); - BUG_ON((PKT_IS_TOSERVER(np))); -#endif - } else if (PKT_IS_TOCLIENT(p)) { - SCLogDebug("original is to_client, so pseudo is to_server"); - np->flowflags &= ~FLOW_PKT_TOCLIENT; - np->flowflags |= FLOW_PKT_TOSERVER; -#ifdef DEBUG - BUG_ON(!(PKT_IS_TOSERVER(np))); - BUG_ON((PKT_IS_TOCLIENT(np))); -#endif - } - - PacketEnqueue(pq, np); - - StatsIncr(tv, stt->counter_tcp_pseudo); - SCReturn; -} - -/** - * \brief Run callback function on each TCP segment - * - * This function is used by StreamMsgForEach() which - * should be used directly. - * - * \return -1 in case of error, the number of segment in case of success - * - */ -int StreamTcpSegmentForEach(const Packet *p, uint8_t flag, StreamSegmentCallback CallbackFunc, void *data) -{ - TcpSession *ssn = NULL; - TcpStream *stream = NULL; - int ret = 0; - int cnt = 0; - - if (p->flow == NULL) - return 0; - - FLOWLOCK_RDLOCK(p->flow); - ssn = (TcpSession *)p->flow->protoctx; - - if (ssn == NULL) { - FLOWLOCK_UNLOCK(p->flow); - return 0; - } - - if (flag & FLOW_PKT_TOSERVER) { - stream = &(ssn->server); - } else { - stream = &(ssn->client); - } - TcpSegment *seg = stream->seg_list; - for (; seg != NULL && SEQ_LT(seg->seq, stream->last_ack);) { - ret = CallbackFunc(p, data, seg->payload, seg->payload_len); - if (ret != 1) { - SCLogDebug("Callback function has failed"); - FLOWLOCK_UNLOCK(p->flow); - return -1; - } - seg = seg->next; - cnt++; - } - FLOWLOCK_UNLOCK(p->flow); - return cnt; -} - -#ifdef UNITTESTS - -/** - * \test Test the allocation of TCP session for a given packet from the - * ssn_pool. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest01 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - - TcpSession *ssn = StreamTcpNewSession(p, 0); - if (ssn == NULL) { - printf("Session can not be allocated: "); - goto end; - } - f.protoctx = ssn; - - if (f.alparser != NULL) { - printf("AppLayer field not set to NULL: "); - goto end; - } - if (ssn->state != 0) { - printf("TCP state field not set to 0: "); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the deallocation of TCP session for a given packet and return - * the memory back to ssn_pool and corresponding segments to segment - * pool. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest02 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx ra_ctx; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&ra_ctx, 0, sizeof(TcpReassemblyThreadCtx)); - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - int ret = 0; - stt.ra_ctx = &ra_ctx; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->flowflags = FLOW_PKT_TOCLIENT; - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(6); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->flowflags = FLOW_PKT_TOCLIENT; - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a TCP session when we missed the intial - * SYN packet of the session. The session is setup only if midstream - * sessions are allowed to setup. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest03 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_SYN|TH_ACK; - p->tcph = &tcph; - int ret = 0; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(19); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.midstream != TRUE) { - ret = 1; - goto end; - } - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 20 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11) - goto end; - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a TCP session when we missed the intial - * SYN/ACK packet of the session. The session is setup only if - * midstream sessions are allowed to setup. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest04 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK; - p->tcph = &tcph; - - int ret = 0; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(9); - p->tcph->th_ack = htonl(19); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.midstream != TRUE) { - ret = 1; - goto end; - } - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 10 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 20) - goto end; - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a TCP session when we missed the intial - * 3WHS packet of the session. The session is setup only if - * midstream sessions are allowed to setup. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest05 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[4]; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(13); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, 4); /*CCC*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(19); - p->tcph->th_ack = htonl(16); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x44, 3, 4); /*DDD*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.midstream != TRUE) { - ret = 1; - goto end; - } - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 16 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) - goto end; - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a TCP session when we have seen only the - * FIN, RST packets packet of the session. The session is setup only if - * midstream sessions are allowed to setup. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest06 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - TcpSession ssn; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - - tcph.th_flags = TH_FIN; - p->tcph = &tcph; - - SCMutexLock(&f.m); - /* StreamTcpPacket returns -1 on unsolicited FIN */ - if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) { - printf("StreamTcpPacket failed: "); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx)) != NULL) { - printf("we have a ssn while we shouldn't: "); - goto end; - } - - p->tcph->th_flags = TH_RST; - /* StreamTcpPacket returns -1 on unsolicited RST */ - if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) { - printf("StreamTcpPacket failed (2): "); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx)) != NULL) { - printf("we have a ssn while we shouldn't (2): "); - goto end; - } - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the working on PAWS. The packet will be dropped by stream, as - * its timestamp is old, although the segment is in the window. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest07 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[1] = {0x42}; - TCPVars tcpvars; - TCPOpt ts; - uint32_t data[2]; - PacketQueue pq; - - memset(p, 0, SIZE_OF_PACKET); - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof(StreamTcpThread)); - memset(&tcph, 0, sizeof(TCPHdr)); - memset(&tcpvars, 0, sizeof(TCPVars)); - memset(&ts, 0, sizeof(TCPOpt)); - - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - stream_config.midstream = TRUE; - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - - data[0] = htonl(10); - data[1] = htonl(11); - - ts.type = TCP_OPT_TS; - ts.len = 10; - ts.data = (uint8_t *)data; - tcpvars.ts = &ts; - p->tcpvars = tcpvars; - - p->payload = payload; - p->payload_len = 1; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - data[0] = htonl(2); - p->tcpvars.ts->data = (uint8_t *)data; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - if (((TcpSession *) (p->flow->protoctx))->client.next_seq != 11) { - printf("the timestamp values are client %"PRIu32" server %" PRIu32"" - " seq %" PRIu32 "\n", TCP_GET_TSVAL(p), TCP_GET_TSECR(p), - ((TcpSession *) (p->flow->protoctx))->client.next_seq); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - ret = 1; - } -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the working on PAWS. The packet will be accpeted by engine as - * the timestamp is valid and it is in window. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest08 (void) -{ - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[1] = {0x42}; - TCPVars tcpvars; - TCPOpt ts; - uint32_t data[2]; - - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof(StreamTcpThread)); - memset(&tcph, 0, sizeof(TCPHdr)); - memset(&tcpvars, 0, sizeof(TCPVars)); - memset(&ts, 0, sizeof(TCPOpt)); - - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - stream_config.midstream = TRUE; - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - - data[0] = htonl(10); - data[1] = htonl(11); - - ts.type = TCP_OPT_TS; - ts.len = 10; - ts.data = (uint8_t *)data; - tcpvars.ts = &ts; - p->tcpvars = tcpvars; - - p->payload = payload; - p->payload_len = 1; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(20); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - data[0] = htonl(12); - p->tcpvars.ts->data = (uint8_t *)data; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (((TcpSession *) (p->flow->protoctx))->client.next_seq != 12) { - printf("the timestamp values are client %"PRIu32" server %" PRIu32 " " - "seq %" PRIu32 "\n", TCP_GET_TSVAL(p), TCP_GET_TSECR(p), - ((TcpSession *) (p->flow->protoctx))->client.next_seq); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the working of No stream reassembly flag. The stream will not - * reassemble the segment if the flag is set. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest09 (void) -{ - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[1] = {0x42}; - - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof(StreamTcpThread)); - memset(&tcph, 0, sizeof(TCPHdr)); - - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - stream_config.midstream = TRUE; - - //prevent L7 from kicking in - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - - p->payload = payload; - p->payload_len = 1; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(12); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpSetSessionNoReassemblyFlag(((TcpSession *)(p->flow->protoctx)), 0); - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (((TcpSession *) (p->flow->protoctx))->client.seg_list->next == NULL) - ret = 1; - - StreamTcpSessionClear(p->flow->protoctx); -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a TCP session when we are seeing asynchronous - * stream, while we see all the packets in that stream from start. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest10 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[4]; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(11); - tcph.th_flags = TH_SYN; - p->tcph = &tcph; - int ret = 0; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(6); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.async_oneside != TRUE) { - ret = 1; - goto end; - } - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) { - printf("failed in setting state\n"); - goto end; - } - - if (! (((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) { - printf("failed in setting asynchronous session\n"); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->client.last_ack != 6 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11) { - printf("failed in seq %"PRIu32" match\n", - ((TcpSession *)(p->flow->protoctx))->client.last_ack); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a TCP session when we are seeing asynchronous - * stream, while we missed the SYN packet of that stream. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest11 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[4]; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(1); - tcph.th_flags = TH_SYN|TH_ACK; - p->tcph = &tcph; - int ret = 0; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(2); - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.async_oneside != TRUE) { - ret = 1; - goto end; - } - - if (! (((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) { - printf("failed in setting asynchronous session\n"); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) { - printf("failed in setting state\n"); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 2 && - ((TcpSession *)(p->flow->protoctx))->client.next_seq != 1) { - printf("failed in seq %"PRIu32" match\n", - ((TcpSession *)(p->flow->protoctx))->server.last_ack); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a TCP session when we are seeing asynchronous - * stream, while we missed the SYN and SYN/ACK packets in that stream. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest12 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[4]; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(11); - tcph.th_flags = TH_ACK; - p->tcph = &tcph; - int ret = 0; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(10); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(6); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.async_oneside != TRUE) { - ret = 1; - goto end; - } - - if (! (((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) { - printf("failed in setting asynchronous session\n"); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) { - printf("failed in setting state\n"); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->client.last_ack != 6 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 11) { - printf("failed in seq %"PRIu32" match\n", - ((TcpSession *)(p->flow->protoctx))->client.last_ack); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a TCP session when we are seeing asynchronous - * stream, while we missed the SYN and SYN/ACK packets in that stream. - * Later, we start to receive the packet from other end stream too. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest13 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[4]; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(11); - tcph.th_flags = TH_ACK; - p->tcph = &tcph; - int ret = 0; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(10); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(6); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.async_oneside != TRUE) { - ret = 1; - goto end; - } - - if (! (((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_ASYNC)) { - printf("failed in setting asynchronous session\n"); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) { - printf("failed in setting state\n"); - goto end; - } - - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(9); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->client.last_ack != 9 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 14) { - printf("failed in seq %"PRIu32" match\n", - ((TcpSession *)(p->flow->protoctx))->client.last_ack); - goto end; - } - - StreamTcpSessionPktFree(p); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/* Dummy conf string to setup the OS policy for unit testing */ -static const char *dummy_conf_string = - "%YAML 1.1\n" - "---\n" - "\n" - "default-log-dir: /var/log/eidps\n" - "\n" - "logging:\n" - "\n" - " default-log-level: debug\n" - "\n" - " default-format: \"<%t> - <%l>\"\n" - "\n" - " default-startup-message: Your IDS has started.\n" - "\n" - " default-output-filter:\n" - "\n" - "host-os-policy:\n" - "\n" - " windows: 192.168.0.1\n" - "\n" - " linux: 192.168.0.2\n" - "\n"; -/* Dummy conf string to setup the OS policy for unit testing */ -static const char *dummy_conf_string1 = - "%YAML 1.1\n" - "---\n" - "\n" - "default-log-dir: /var/log/eidps\n" - "\n" - "logging:\n" - "\n" - " default-log-level: debug\n" - "\n" - " default-format: \"<%t> - <%l>\"\n" - "\n" - " default-startup-message: Your IDS has started.\n" - "\n" - " default-output-filter:\n" - "\n" - "host-os-policy:\n" - "\n" - " windows: 192.168.0.0/24," "192.168.1.1\n" - "\n" - " linux: 192.168.1.0/24," "192.168.0.1\n" - "\n"; - -/** - * \brief Function to parse the dummy conf string and get the value of IP - * address for the corresponding OS policy type. - * - * \param conf_val_name Name of the OS policy type - * \retval returns IP address as string on success and NULL on failure - */ -char *StreamTcpParseOSPolicy (char *conf_var_name) -{ - SCEnter(); - char conf_var_type_name[15] = "host-os-policy"; - char *conf_var_full_name = NULL; - char *conf_var_value = NULL; - - if (conf_var_name == NULL) - goto end; - - /* the + 2 is for the '.' and the string termination character '\0' */ - conf_var_full_name = (char *)SCMalloc(strlen(conf_var_type_name) + - strlen(conf_var_name) + 2); - if (conf_var_full_name == NULL) - goto end; - - if (snprintf(conf_var_full_name, - strlen(conf_var_type_name) + strlen(conf_var_name) + 2, "%s.%s", - conf_var_type_name, conf_var_name) < 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Error in making the conf full name"); - goto end; - } - - if (ConfGet(conf_var_full_name, &conf_var_value) != 1) { - SCLogError(SC_ERR_UNKNOWN_VALUE, "Error in getting conf value for conf name %s", - conf_var_full_name); - goto end; - } - - SCLogDebug("Value obtained from the yaml conf file, for the var " - "\"%s\" is \"%s\"", conf_var_name, conf_var_value); - - end: - if (conf_var_full_name != NULL) - SCFree(conf_var_full_name); - SCReturnCharPtr(conf_var_value); - - -} -/** - * \test Test the setting up a OS policy. Te OS policy values are defined in - * the config string "dummy_conf_string" - * - * \retval On success it returns 1 and on failure 0 - */ - -static int StreamTcpTest14 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[4]; - struct in_addr addr; - IPV4Hdr ipv4h; - char os_policy_name[10] = "windows"; - char *ip_addr; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&addr, 0, sizeof(addr)); - memset(&ipv4h, 0, sizeof(ipv4h)); - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - - /* Load the config string in to parser */ - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - /* Get the IP address as string and add it to Host info tree for lookups */ - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name)); - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - addr.s_addr = inet_addr("192.168.0.1"); - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->dst.family = AF_INET; - p->dst.address.address_un_data32[0] = addr.s_addr; - p->ip4h = &ipv4h; - - StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(15); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(14); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - addr.s_addr = inet_addr("192.168.0.2"); - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - p->dst.address.address_un_data32[0] = addr.s_addr; - - StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.midstream != TRUE) { - ret = 1; - goto end; - } - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) { - printf("failed in next_seq match client.next_seq %"PRIu32"" - " server.next_seq %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->client.next_seq, - ((TcpSession *)(p->flow->protoctx))->server.next_seq); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->client.os_policy != - OS_POLICY_WINDOWS && ((TcpSession *) - (p->flow->protoctx))->server.os_policy != OS_POLICY_LINUX) - { - printf("failed in setting up OS policy, client.os_policy: %"PRIu8"" - " should be %"PRIu8" and server.os_policy: %"PRIu8"" - " should be %"PRIu8"\n", ((TcpSession *) - (p->flow->protoctx))->client.os_policy, OS_POLICY_WINDOWS, - ((TcpSession *)(p->flow->protoctx))->server.os_policy, - OS_POLICY_LINUX); - goto end; - } - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - ConfDeInit(); - ConfRestoreContextBackup(); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a TCP session using the 4WHS: - * SYN, SYN, SYN/ACK, ACK - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcp4WHSTest01 (void) -{ - int ret = 0; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = 0; - tcph.th_flags = TH_SYN; - p->tcph = &tcph; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = 0; - p->tcph->th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) { - printf("STREAMTCP_FLAG_4WHS flag not set: "); - goto end; - } - - p->tcph->th_seq = htonl(10); - p->tcph->th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */ - p->tcph->th_flags = TH_SYN|TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(21); - p->tcph->th_ack = htonl(10); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) { - printf("state is not ESTABLISHED: "); - goto end; - } - - ret = 1; -end: - StreamTcpSessionClear(p->flow->protoctx); - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test set up a TCP session using the 4WHS: - * SYN, SYN, SYN/ACK, ACK, but the SYN/ACK does - * not have the right SEQ - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcp4WHSTest02 (void) -{ - int ret = 0; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = 0; - tcph.th_flags = TH_SYN; - p->tcph = &tcph; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = 0; - p->tcph->th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) { - printf("STREAMTCP_FLAG_4WHS flag not set: "); - goto end; - } - - p->tcph->th_seq = htonl(30); - p->tcph->th_ack = htonl(21); /* the SYN/ACK uses the SEQ from the first SYN pkt */ - p->tcph->th_flags = TH_SYN|TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) { - printf("SYN/ACK pkt not rejected but it should have: "); - goto end; - } - - ret = 1; -end: - StreamTcpSessionClear(p->flow->protoctx); - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test set up a TCP session using the 4WHS: - * SYN, SYN, SYN/ACK, ACK: however the SYN/ACK and ACK - * are part of a normal 3WHS - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcp4WHSTest03 (void) -{ - int ret = 0; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - memset(p, 0, SIZE_OF_PACKET); - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - p->flow = &f; - - StreamTcpInitConfig(TRUE); - - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = 0; - tcph.th_flags = TH_SYN; - p->tcph = &tcph; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = 0; - p->tcph->th_flags = TH_SYN; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if ((!(((TcpSession *)(p->flow->protoctx))->flags & STREAMTCP_FLAG_4WHS))) { - printf("STREAMTCP_FLAG_4WHS flag not set: "); - goto end; - } - - p->tcph->th_seq = htonl(30); - p->tcph->th_ack = htonl(11); - p->tcph->th_flags = TH_SYN|TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(11); - p->tcph->th_ack = htonl(31); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) { - printf("state is not ESTABLISHED: "); - goto end; - } - - ret = 1; -end: - StreamTcpSessionClear(p->flow->protoctx); - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a OS policy. Te OS policy values are defined in - * the config string "dummy_conf_string1" - * - * \retval On success it returns 1 and on failure 0 - */ - -static int StreamTcpTest15 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[4]; - struct in_addr addr; - IPV4Hdr ipv4h; - char os_policy_name[10] = "windows"; - char *ip_addr; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&addr, 0, sizeof(addr)); - memset(&ipv4h, 0, sizeof(ipv4h)); - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - - /* Load the config string in to parser */ - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1)); - - /* Get the IP address as string and add it to Host info tree for lookups */ - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name)); - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - addr.s_addr = inet_addr("192.168.0.20"); - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->dst.family = AF_INET; - p->dst.address.address_un_data32[0] = addr.s_addr; - p->ip4h = &ipv4h; - - StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(15); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(14); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - addr.s_addr = inet_addr("192.168.1.20"); - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - p->dst.address.address_un_data32[0] = addr.s_addr; - - StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.midstream != TRUE) { - ret = 1; - goto end; - } - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) { - printf("failed in next_seq match client.next_seq %"PRIu32"" - " server.next_seq %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->client.next_seq, - ((TcpSession *)(p->flow->protoctx))->server.next_seq); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->client.os_policy != - OS_POLICY_WINDOWS && ((TcpSession *) - (p->flow->protoctx))->server.os_policy != OS_POLICY_LINUX) - { - printf("failed in setting up OS policy, client.os_policy: %"PRIu8"" - " should be %"PRIu8" and server.os_policy: %"PRIu8"" - " should be %"PRIu8"\n", ((TcpSession *) - (p->flow->protoctx))->client.os_policy, OS_POLICY_WINDOWS, - ((TcpSession *)(p->flow->protoctx))->server.os_policy, - OS_POLICY_LINUX); - goto end; - } - StreamTcpSessionPktFree(p); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - ConfDeInit(); - ConfRestoreContextBackup(); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a OS policy. Te OS policy values are defined in - * the config string "dummy_conf_string1" - * - * \retval On success it returns 1 and on failure 0 - */ - -static int StreamTcpTest16 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[4]; - struct in_addr addr; - IPV4Hdr ipv4h; - char os_policy_name[10] = "windows"; - char *ip_addr; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&addr, 0, sizeof(addr)); - memset(&ipv4h, 0, sizeof(ipv4h)); - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - - /* Load the config string in to parser */ - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1)); - - /* Get the IP address as string and add it to Host info tree for lookups */ - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name)); - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - addr.s_addr = inet_addr("192.168.0.1"); - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->dst.family = AF_INET; - p->dst.address.address_un_data32[0] = addr.s_addr; - p->ip4h = &ipv4h; - - StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(15); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(14); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - addr.s_addr = inet_addr("192.168.1.1"); - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - p->dst.address.address_un_data32[0] = addr.s_addr; - - StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.midstream != TRUE) { - ret = 1; - goto end; - } - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) { - printf("failed in next_seq match client.next_seq %"PRIu32"" - " server.next_seq %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->client.next_seq, - ((TcpSession *)(p->flow->protoctx))->server.next_seq); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->client.os_policy != - OS_POLICY_LINUX && ((TcpSession *) - (p->flow->protoctx))->server.os_policy != OS_POLICY_WINDOWS) - { - printf("failed in setting up OS policy, client.os_policy: %"PRIu8"" - " should be %"PRIu8" and server.os_policy: %"PRIu8"" - " should be %"PRIu8"\n", ((TcpSession *) - (p->flow->protoctx))->client.os_policy, OS_POLICY_LINUX, - ((TcpSession *)(p->flow->protoctx))->server.os_policy, - OS_POLICY_WINDOWS); - goto end; - } - StreamTcpSessionPktFree(p); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - ConfDeInit(); - ConfRestoreContextBackup(); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the setting up a OS policy. Te OS policy values are defined in - * the config string "dummy_conf_string1". To check the setting of - * Default os policy - * - * \retval On success it returns 1 and on failure 0 - */ - -static int StreamTcpTest17 (void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - uint8_t payload[4]; - struct in_addr addr; - IPV4Hdr ipv4h; - char os_policy_name[10] = "windows"; - char *ip_addr; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&addr, 0, sizeof(addr)); - memset(&ipv4h, 0, sizeof(ipv4h)); - FLOW_INITIALIZE(&f); - p->flow = &f; - int ret = 0; - - StreamTcpInitConfig(TRUE); - - /* Load the config string in to parser */ - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1)); - - /* Get the IP address as string and add it to Host info tree for lookups */ - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - strlcpy(os_policy_name, "linux\0", sizeof(os_policy_name)); - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - addr.s_addr = inet_addr("192.168.0.1"); - tcph.th_win = htons(5480); - tcph.th_seq = htonl(10); - tcph.th_ack = htonl(20); - tcph.th_flags = TH_ACK|TH_PUSH; - p->tcph = &tcph; - p->dst.family = AF_INET; - p->dst.address.address_un_data32[0] = addr.s_addr; - p->ip4h = &ipv4h; - - StreamTcpCreateTestPacket(payload, 0x41, 3, sizeof(payload)); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(20); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x42, 3, sizeof(payload)); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(15); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(14); - p->tcph->th_ack = htonl(23); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x43, 3, sizeof(payload)); /*CCC*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - addr.s_addr = inet_addr("10.1.1.1"); - p->tcph->th_seq = htonl(25); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - p->dst.address.address_un_data32[0] = addr.s_addr; - - StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_seq = htonl(24); - p->tcph->th_ack = htonl(13); - p->tcph->th_flags = TH_ACK|TH_PUSH; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x44, 3, sizeof(payload)); /*DDD*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - if (stream_config.midstream != TRUE) { - ret = 1; - goto end; - } - if (((TcpSession *)(p->flow->protoctx))->state != TCP_ESTABLISHED) - goto end; - - if (((TcpSession *)(p->flow->protoctx))->client.next_seq != 13 && - ((TcpSession *)(p->flow->protoctx))->server.next_seq != 23) { - printf("failed in next_seq match client.next_seq %"PRIu32"" - " server.next_seq %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->client.next_seq, - ((TcpSession *)(p->flow->protoctx))->server.next_seq); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->client.os_policy != - OS_POLICY_LINUX && ((TcpSession *) - (p->flow->protoctx))->server.os_policy != OS_POLICY_DEFAULT) - { - printf("failed in setting up OS policy, client.os_policy: %"PRIu8"" - " should be %"PRIu8" and server.os_policy: %"PRIu8"" - " should be %"PRIu8"\n", ((TcpSession *) - (p->flow->protoctx))->client.os_policy, OS_POLICY_LINUX, - ((TcpSession *)(p->flow->protoctx))->server.os_policy, - OS_POLICY_DEFAULT); - goto end; - } - StreamTcpSessionPktFree(p); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - ConfDeInit(); - ConfRestoreContextBackup(); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** \test Test the various OS policies based on different IP addresses from - confuguration defined in 'dummy_conf_string1' */ -static int StreamTcpTest18 (void) -{ - - struct in_addr addr; - char os_policy_name[10] = "windows"; - char *ip_addr; - TcpStream stream; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV4Hdr ipv4h; - int ret = 0; - - memset(&addr, 0, sizeof(addr)); - memset(&stream, 0, sizeof(stream)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(ipv4h)); - - StreamTcpInitConfig(TRUE); - SCHInfoCleanResources(); - - /* Load the config string in to parser */ - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1)); - - /* Get the IP address as string and add it to Host info tree for lookups */ - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - - p->dst.family = AF_INET; - p->ip4h = &ipv4h; - addr.s_addr = inet_addr("192.168.1.1"); - p->dst.address.address_un_data32[0] = addr.s_addr; - StreamTcpSetOSPolicy(&stream, p); - - if (stream.os_policy != OS_POLICY_WINDOWS) - goto end; - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - ConfDeInit(); - ConfRestoreContextBackup(); - SCFree(p); - return ret; -} -/** \test Test the various OS policies based on different IP addresses from - confuguration defined in 'dummy_conf_string1' */ -static int StreamTcpTest19 (void) -{ - - struct in_addr addr; - char os_policy_name[10] = "windows"; - char *ip_addr; - TcpStream stream; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV4Hdr ipv4h; - int ret = 0; - - memset(&addr, 0, sizeof(addr)); - memset(&stream, 0, sizeof(stream)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(ipv4h)); - - StreamTcpInitConfig(TRUE); - SCHInfoCleanResources(); - - /* Load the config string in to parser */ - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1)); - - /* Get the IP address as string and add it to Host info tree for lookups */ - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - - p->dst.family = AF_INET; - p->ip4h = &ipv4h; - addr.s_addr = inet_addr("192.168.0.30"); - p->dst.address.address_un_data32[0] = addr.s_addr; - StreamTcpSetOSPolicy(&stream, p); - - if (stream.os_policy != OS_POLICY_WINDOWS) { - printf("expected os_policy: %"PRIu8" but received %"PRIu8": ", - OS_POLICY_WINDOWS, stream.os_policy); - goto end; - } - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - ConfDeInit(); - ConfRestoreContextBackup(); - SCFree(p); - return ret; -} -/** \test Test the various OS policies based on different IP addresses from - confuguration defined in 'dummy_conf_string1' */ -static int StreamTcpTest20 (void) -{ - - struct in_addr addr; - char os_policy_name[10] = "linux"; - char *ip_addr; - TcpStream stream; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV4Hdr ipv4h; - int ret = 0; - - memset(&addr, 0, sizeof(addr)); - memset(&stream, 0, sizeof(stream)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(ipv4h)); - - StreamTcpInitConfig(TRUE); - SCHInfoCleanResources(); - - /* Load the config string in to parser */ - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1)); - - /* Get the IP address as string and add it to Host info tree for lookups */ - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - - p->dst.family = AF_INET; - p->ip4h = &ipv4h; - addr.s_addr = inet_addr("192.168.0.1"); - p->dst.address.address_un_data32[0] = addr.s_addr; - StreamTcpSetOSPolicy(&stream, p); - - if (stream.os_policy != OS_POLICY_LINUX) { - printf("expected os_policy: %"PRIu8" but received %"PRIu8"\n", - OS_POLICY_LINUX, stream.os_policy); - goto end; - } - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - ConfDeInit(); - ConfRestoreContextBackup(); - SCFree(p); - return ret; -} -/** \test Test the various OS policies based on different IP addresses from - confuguration defined in 'dummy_conf_string1' */ -static int StreamTcpTest21 (void) -{ - - struct in_addr addr; - char os_policy_name[10] = "linux"; - char *ip_addr; - TcpStream stream; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV4Hdr ipv4h; - int ret = 0; - - memset(&addr, 0, sizeof(addr)); - memset(&stream, 0, sizeof(stream)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(ipv4h)); - - StreamTcpInitConfig(TRUE); - SCHInfoCleanResources(); - - /* Load the config string in to parser */ - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1)); - - /* Get the IP address as string and add it to Host info tree for lookups */ - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - - p->dst.family = AF_INET; - p->ip4h = &ipv4h; - addr.s_addr = inet_addr("192.168.1.30"); - p->dst.address.address_un_data32[0] = addr.s_addr; - StreamTcpSetOSPolicy(&stream, p); - - if (stream.os_policy != OS_POLICY_LINUX) { - printf("expected os_policy: %"PRIu8" but received %"PRIu8"\n", - OS_POLICY_LINUX, stream.os_policy); - goto end; - } - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - ConfDeInit(); - ConfRestoreContextBackup(); - SCFree(p); - return ret; -} -/** \test Test the various OS policies based on different IP addresses from - confuguration defined in 'dummy_conf_string1' */ -static int StreamTcpTest22 (void) -{ - - struct in_addr addr; - char os_policy_name[10] = "windows"; - char *ip_addr; - TcpStream stream; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - IPV4Hdr ipv4h; - int ret = 0; - - memset(&addr, 0, sizeof(addr)); - memset(&stream, 0, sizeof(stream)); - memset(p, 0, SIZE_OF_PACKET); - memset(&ipv4h, 0, sizeof(ipv4h)); - - StreamTcpInitConfig(TRUE); - SCHInfoCleanResources(); - - /* Load the config string in to parser */ - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string1, strlen(dummy_conf_string1)); - - /* Get the IP address as string and add it to Host info tree for lookups */ - ip_addr = StreamTcpParseOSPolicy(os_policy_name); - SCHInfoAddHostOSInfo(os_policy_name, ip_addr, -1); - - p->dst.family = AF_INET; - p->ip4h = &ipv4h; - addr.s_addr = inet_addr("123.231.2.1"); - p->dst.address.address_un_data32[0] = addr.s_addr; - StreamTcpSetOSPolicy(&stream, p); - - if (stream.os_policy != OS_POLICY_DEFAULT) { - printf("expected os_policy: %"PRIu8" but received %"PRIu8"\n", - OS_POLICY_DEFAULT, stream.os_policy); - goto end; - } - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - ConfDeInit(); - ConfRestoreContextBackup(); - SCFree(p); - return ret; -} - -/** \test Test the stream mem leaks conditions. */ -static int StreamTcpTest23(void) -{ - TcpSession ssn; - Flow f; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - uint8_t packet[1460] = ""; - ThreadVars tv; - int result = 1; - PacketQueue pq; - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - - memset(&pq,0,sizeof(PacketQueue)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(p, 0, SIZE_OF_PACKET); - memset(&f, 0, sizeof (Flow)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&tv, 0, sizeof (ThreadVars)); - - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - FLOW_INITIALIZE(&f); - ssn.client.os_policy = OS_POLICY_BSD; - f.protoctx = &ssn; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = packet; - ssn.client.ra_app_base_seq = ssn.client.ra_raw_base_seq = ssn.client.last_ack = 3184324453UL; - - p->tcph->th_seq = htonl(3184324453UL); - p->tcph->th_ack = htonl(3373419609UL); - p->payload_len = 2; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &ssn.client, p, &pq) == -1) { - printf("failed in segment reassmebling: "); - result &= 0; - goto end; - } - - p->tcph->th_seq = htonl(3184324455UL); - p->tcph->th_ack = htonl(3373419621UL); - p->payload_len = 2; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &ssn.client, p, &pq) == -1) { - printf("failed in segment reassmebling: "); - result &= 0; - goto end; - } - - p->tcph->th_seq = htonl(3184324453UL); - p->tcph->th_ack = htonl(3373419621UL); - p->payload_len = 6; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &ssn.client, p, &pq) == -1) { - printf("failed in segment reassmebling: "); - result &= 0; -// goto end; - } - - if(ssn.client.seg_list_tail != NULL && ssn.client.seg_list_tail->payload_len != 4) { - printf("failed in segment reassmebling: "); - result &= 0; - } - -end: - StreamTcpReturnStreamSegments(&ssn.client); - StreamTcpFreeConfig(TRUE); - if (SC_ATOMIC_GET(st_memuse) == 0) { - result &= 1; - } else { - printf("smemuse.stream_memuse %"PRIu64"\n", SC_ATOMIC_GET(st_memuse)); - } - SCFree(p); - FLOW_DESTROY(&f); - return result; -} - -/** \test Test the stream mem leaks conditions. */ -static int StreamTcpTest24(void) -{ - TcpSession ssn; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - uint8_t packet[1460] = ""; - ThreadVars tv; - int result = 1; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - memset(&ssn, 0, sizeof (TcpSession)); - memset(p, 0, SIZE_OF_PACKET); - memset(&f, 0, sizeof (Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&tcph, 0, sizeof (TCPHdr)); - FLOW_INITIALIZE(&f); - ssn.client.os_policy = OS_POLICY_BSD; - f.protoctx = &ssn; - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->proto = IPPROTO_TCP; - p->flow = &f; - tcph.th_win = 5480; - tcph.th_flags = TH_PUSH | TH_ACK; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - p->payload = packet; - ssn.client.ra_app_base_seq = ssn.client.ra_raw_base_seq = ssn.client.last_ack = 3184324453UL; - - p->tcph->th_seq = htonl(3184324455UL); - p->tcph->th_ack = htonl(3373419621UL); - p->payload_len = 4; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &ssn.client, p, &pq) == -1) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - p->tcph->th_seq = htonl(3184324459UL); - p->tcph->th_ack = htonl(3373419633UL); - p->payload_len = 2; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &ssn.client, p, &pq) == -1) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - p->tcph->th_seq = htonl(3184324459UL); - p->tcph->th_ack = htonl(3373419657UL); - p->payload_len = 4; - - if (StreamTcpReassembleHandleSegment(&tv, ra_ctx,&ssn, &ssn.client, p, &pq) == -1) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - if(ssn.client.seg_list_tail != NULL && ssn.client.seg_list_tail->payload_len != 2) { - printf("failed in segment reassmebling\n"); - result &= 0; - } - -end: - StreamTcpReturnStreamSegments(&ssn.client); - StreamTcpFreeConfig(TRUE); - if (SC_ATOMIC_GET(st_memuse) == 0) { - result &= 1; - } else { - printf("smemuse.stream_memuse %"PRIu64"\n", SC_ATOMIC_GET(st_memuse)); - } - SCFree(p); - FLOW_DESTROY(&f); - return result; -} - -/** - * \test Test the initialization of tcp streams with congestion flags - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpTest25(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - int ret = 0; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - stt.ra_ctx = ra_ctx; - p->flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN | TH_CWR; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - /* prevent L7 from kicking in */ - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOSERVER, 4096); - StreamMsgQueueSetMinChunkLen(FLOW_PKT_TOCLIENT, 4096); - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->flowflags = FLOW_PKT_TOCLIENT; - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(6); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->flowflags = FLOW_PKT_TOCLIENT; - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the initialization of tcp streams with congestion flags - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpTest26(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - int ret = 0; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - stt.ra_ctx = ra_ctx; - p->flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN | TH_ECN; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->flowflags = FLOW_PKT_TOCLIENT; - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(6); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->flowflags = FLOW_PKT_TOCLIENT; - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the initialization of tcp streams with congestion flags - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpTest27(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - int ret = 0; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - stt.ra_ctx = ra_ctx; - p->flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN | TH_CWR | TH_ECN; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->flowflags = FLOW_PKT_TOCLIENT; - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(6); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x42, 3, 4); /*BBB*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - p->flowflags = FLOW_PKT_TOCLIENT; - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) - goto end; - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** \test Test the memcap incrementing/decrementing and memcap check */ -static int StreamTcpTest28(void) -{ - uint8_t ret = 0; - StreamTcpInitConfig(TRUE); - uint32_t memuse = SC_ATOMIC_GET(st_memuse); - - StreamTcpIncrMemuse(500); - if (SC_ATOMIC_GET(st_memuse) != (memuse+500)) { - printf("failed in incrementing the memory"); - goto end; - } - - StreamTcpDecrMemuse(500); - if (SC_ATOMIC_GET(st_memuse) != memuse) { - printf("failed in decrementing the memory"); - goto end; - } - - if (StreamTcpCheckMemcap(500) != 1) { - printf("failed in validating the memcap"); - goto end; - } - - if (StreamTcpCheckMemcap((memuse + stream_config.memcap)) != 0) { - printf("failed in validating the overflowed memcap"); - goto end; - } - - StreamTcpFreeConfig(TRUE); - - if (SC_ATOMIC_GET(st_memuse) != 0) { - printf("failed in clearing the memory"); - goto end; - } - - ret = 1; - return ret; -end: - StreamTcpFreeConfig(TRUE); - return ret; -} - -#if 0 -/** - * \test Test the resetting of the sesison with bad checksum packet and later - * send the malicious contents on the session. Engine should drop the - * packet with the bad checksum. - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpTest29(void) -{ - Packet p; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - TcpSession ssn; - IPV4Hdr ipv4h; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - struct in_addr addr; - struct in_addr addr1; - TCPCache tcpc; - TCPVars tcpvars; - TcpStream server; - TcpStream client; - - memset (&p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset (&ipv4h, 0, sizeof(IPV4Hdr)); - memset (&addr, 0, sizeof(addr)); - memset (&addr1, 0, sizeof(addr1)); - memset (&tcpc, 0, sizeof(tcpc)); - memset (&tcpvars, 0, sizeof(tcpvars)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&server, 0, sizeof (TcpStream)); - memset(&client, 0, sizeof (TcpStream)); - uint8_t packet[1460] = ""; - int result = 1; - - FLOW_INITIALIZE(&f); - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - - ssn.client.os_policy = OS_POLICY_BSD; - p.src.family = AF_INET; - p.dst.family = AF_INET; - p.proto = IPPROTO_TCP; - p.flow = &f; - tcph.th_win = 5480; - p.tcph = &tcph; - p.payload = packet; - p.ip4h = &ipv4h; - p.tcpc = tcpc; - p.tcpc.level4_comp_csum = -1; - tcpvars.hlen = 20; - p.tcpvars = tcpvars; - ssn.state = TCP_ESTABLISHED; - addr.s_addr = inet_addr("10.1.3.53"); - p.dst.address.address_un_data32[0] = addr.s_addr; - addr1.s_addr = inet_addr("10.1.3.7"); - p.src.address.address_un_data32[0] = addr1.s_addr; - f.protoctx = &ssn; - stt.ra_ctx = ra_ctx; - ssn.server = server; - ssn.client = client; - ssn.client.isn = 10; - ssn.client.window = 5184; - ssn.client.last_ack = 10; - ssn.client.ra_base_seq = 10; - ssn.client.next_win = 5184; - ssn.server.isn = 119197101; - ssn.server.window = 5184; - ssn.server.next_win = 5184; - ssn.server.last_ack = 119197101; - ssn.server.ra_base_seq = 119197101; - - tcph.th_flags = TH_PUSH | TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - p.tcph->th_seq = htonl(11); - p.tcph->th_ack = htonl(119197102); - p.payload_len = 4; - p.ip4h->ip_src = addr1; - p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src), - (uint16_t *)p.tcph, - (p.payload_len + - p.tcpvars.hlen) ); - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - tcph.th_flags = TH_ACK; - p.flowflags = FLOW_PKT_TOCLIENT; - p.tcph->th_seq = htonl(119197102); - p.tcph->th_ack = htonl(15); - p.payload_len = 0; - p.ip4h->ip_src = addr; - p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src), - (uint16_t *)p.tcph, - (p.payload_len + - p.tcpvars.hlen) ); - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - tcph.th_flags = TH_RST | TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - p.tcph->th_seq = htonl(15); - p.tcph->th_ack = htonl(119197102); - p.payload_len = 0; - p.ip4h->ip_src = addr1; - p.tcph->th_sum = 12345; - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - if (ssn.state != TCP_ESTABLISHED) { - printf("the ssn.state should be TCP_ESTABLISHED(%"PRIu8"), not %"PRIu8"" - "\n", TCP_ESTABLISHED, ssn.state); - result &= 0; - goto end; - } - -end: - StreamTcpReturnStreamSegments(&ssn.client); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Test the overlapping of the packet with bad checksum packet and later - * send the malicious contents on the session. Engine should drop the - * packet with the bad checksum. - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpTest30(void) -{ - Packet p; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - TcpSession ssn; - IPV4Hdr ipv4h; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - struct in_addr addr; - struct in_addr addr1; - TCPCache tcpc; - TCPVars tcpvars; - TcpStream server; - TcpStream client; - - memset (&p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset (&ipv4h, 0, sizeof(IPV4Hdr)); - memset (&addr, 0, sizeof(addr)); - memset (&addr1, 0, sizeof(addr1)); - memset (&tcpc, 0, sizeof(tcpc)); - memset (&tcpvars, 0, sizeof(tcpvars)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&server, 0, sizeof (TcpStream)); - memset(&client, 0, sizeof (TcpStream)); - uint8_t payload[9] = "AAAAAAAAA"; - uint8_t payload1[9] = "GET /EVIL"; - uint8_t expected_content[9] = { 0x47, 0x45, 0x54, 0x20, 0x2f, 0x45, 0x56, - 0x49, 0x4c }; - int result = 1; - - FLOW_INITIALIZE(&f); - StreamTcpInitConfig(TRUE); - - /* prevent L7 from kicking in */ - - ssn.client.os_policy = OS_POLICY_BSD; - p.src.family = AF_INET; - p.dst.family = AF_INET; - p.proto = IPPROTO_TCP; - p.flow = &f; - tcph.th_win = 5480; - p.tcph = &tcph; - p.payload = payload; - p.ip4h = &ipv4h; - p.tcpc = tcpc; - p.tcpc.level4_comp_csum = -1; - p.tcpvars = tcpvars; - ssn.state = TCP_ESTABLISHED; - addr.s_addr = inet_addr("10.1.3.53"); - p.dst.address.address_un_data32[0] = addr.s_addr; - addr1.s_addr = inet_addr("10.1.3.7"); - p.src.address.address_un_data32[0] = addr1.s_addr; - f.protoctx = &ssn; - stt.ra_ctx = ra_ctx; - ssn.server = server; - ssn.client = client; - ssn.client.isn = 10; - ssn.client.window = 5184; - ssn.client.last_ack = 10; - ssn.client.ra_base_seq = 10; - ssn.client.next_win = 5184; - ssn.server.isn = 1351079940; - ssn.server.window = 5184; - ssn.server.next_win = 1351088132; - ssn.server.last_ack = 1351079940; - ssn.server.ra_base_seq = 1351079940; - - tcph.th_flags = TH_PUSH | TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - p.tcph->th_seq = htonl(11); - p.tcph->th_ack = htonl(1351079940); - p.payload_len = 9; - p.ip4h->ip_src = addr1; - p.tcph->th_sum = 12345; - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - tcph.th_flags = TH_PUSH | TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - p.tcph->th_seq = htonl(11); - p.tcph->th_ack = htonl(1351079940); - p.payload = payload1; - p.payload_len = 9; - p.ip4h->ip_src = addr1; - p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src), - (uint16_t *)p.tcph, - (p.payload_len + - p.tcpvars.hlen) ); - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - tcph.th_flags = TH_ACK; - p.flowflags = FLOW_PKT_TOCLIENT; - p.tcph->th_seq = htonl(1351079940); - p.tcph->th_ack = htonl(20); - p.payload_len = 0; - p.ip4h->ip_src = addr; - p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src), - (uint16_t *)p.tcph, - (p.payload_len + - p.tcpvars.hlen) ); - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - if (StreamTcpCheckStreamContents(expected_content, 9, &ssn.client) != 1) { - printf("the contents are not as expected(GET /EVIL), contents are: "); - PrintRawDataFp(stdout, ssn.client.seg_list->payload, 9); - result &= 0; - goto end; - } - -end: - StreamTcpReturnStreamSegments(&ssn.client); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Test the multiple SYN packet handling with bad checksum and timestamp - * value. Engine should drop the bad checksum packet and establish - * TCP session correctly. - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpTest31(void) -{ - Packet p; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - TcpSession ssn; - IPV4Hdr ipv4h; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - struct in_addr addr; - struct in_addr addr1; - TCPCache tcpc; - TCPVars tcpvars; - TcpStream server; - TcpStream client; - TCPOpt tcpopt; - - memset (&p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset (&ipv4h, 0, sizeof(IPV4Hdr)); - memset (&addr, 0, sizeof(addr)); - memset (&addr1, 0, sizeof(addr1)); - memset (&tcpc, 0, sizeof(tcpc)); - memset (&tcpvars, 0, sizeof(tcpvars)); - memset(&ssn, 0, sizeof (TcpSession)); - memset(&server, 0, sizeof (TcpStream)); - memset(&client, 0, sizeof (TcpStream)); - memset(&tcpopt, 0, sizeof (TCPOpt)); - int result = 1; - - StreamTcpInitConfig(TRUE); - - FLOW_INITIALIZE(&f); - /* prevent L7 from kicking in */ - - ssn.client.os_policy = OS_POLICY_LINUX; - p.src.family = AF_INET; - p.dst.family = AF_INET; - p.proto = IPPROTO_TCP; - p.flow = &f; - tcph.th_win = 5480; - p.tcph = &tcph; - p.ip4h = &ipv4h; - p.tcpc = tcpc; - p.tcpc.level4_comp_csum = -1; - p.tcpvars = tcpvars; - p.tcpvars.ts = &tcpopt; - addr.s_addr = inet_addr("10.1.3.53"); - p.dst.address.address_un_data32[0] = addr.s_addr; - addr1.s_addr = inet_addr("10.1.3.7"); - p.src.address.address_un_data32[0] = addr1.s_addr; - f.protoctx = &ssn; - stt.ra_ctx = ra_ctx; - ssn.server = server; - ssn.client = client; - ssn.client.isn = 10; - ssn.client.window = 5184; - ssn.client.last_ack = 10; - ssn.client.ra_base_seq = 10; - ssn.client.next_win = 5184; - ssn.server.isn = 1351079940; - ssn.server.window = 5184; - ssn.server.next_win = 1351088132; - ssn.server.last_ack = 1351079940; - ssn.server.ra_base_seq = 1351079940; - - tcph.th_flags = TH_SYN; - p.flowflags = FLOW_PKT_TOSERVER; - p.tcph->th_seq = htonl(10); - p.payload_len = 0; - p.ip4h->ip_src = addr1; - p.tcpc.ts1 = 100; - p.tcph->th_sum = 12345; - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - tcph.th_flags = TH_SYN; - p.flowflags = FLOW_PKT_TOSERVER; - p.tcph->th_seq = htonl(10); - p.payload_len = 0; - p.ip4h->ip_src = addr1; - p.tcpc.ts1 = 10; - p.tcpc.level4_comp_csum = -1; - p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src), - (uint16_t *)p.tcph, - (p.payload_len + - p.tcpvars.hlen) ); - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - ssn.flags |= STREAMTCP_FLAG_TIMESTAMP; - tcph.th_flags = TH_SYN | TH_ACK; - p.flowflags = FLOW_PKT_TOCLIENT; - p.tcph->th_seq = htonl(1351079940); - p.tcph->th_ack = htonl(11); - p.payload_len = 0; - p.tcpc.ts1 = 10; - p.ip4h->ip_src = addr; - p.tcpc.level4_comp_csum = -1; - p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src), - (uint16_t *)p.tcph, - (p.payload_len + - p.tcpvars.hlen) ); - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - tcph.th_flags = TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - p.tcph->th_seq = htonl(11); - p.tcph->th_ack = htonl(1351079941); - p.payload_len = 0; - p.tcpc.ts1 = 10; - p.ip4h->ip_src = addr1; - p.tcpc.level4_comp_csum = -1; - p.tcph->th_sum = TCPCalculateChecksum((uint16_t *)&(p.ip4h->ip_src), - (uint16_t *)p.tcph, - (p.payload_len + - p.tcpvars.hlen) ); - - if (StreamTcp(&tv, &p, (void *)&stt, NULL, NULL) != TM_ECODE_OK) { - printf("failed in segment reassmebling\n"); - result &= 0; - goto end; - } - - if (ssn.state != TCP_ESTABLISHED) { - printf("the should have been changed to TCP_ESTABLISHED!!\n "); - result &= 0; - goto end; - } - -end: - StreamTcpReturnStreamSegments(&ssn.client); - StreamTcpFreeConfig(TRUE); - return result; -} - -/** - * \test Test the initialization of tcp streams with ECN & CWR flags - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpTest32(void) -{ - Packet p; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - int ret = 0; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset (&p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - stt.ra_ctx = ra_ctx; - p.flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN | TH_CWR | TH_ECN; - p.tcph = &tcph; - p.flowflags = FLOW_PKT_TOSERVER; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_ack = htonl(1); - p.tcph->th_flags = TH_SYN | TH_ACK | TH_ECN; - p.flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - p.tcph->th_ack = htonl(1); - p.tcph->th_seq = htonl(1); - p.tcph->th_flags = TH_ACK | TH_ECN | TH_CWR; - p.flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - p.tcph->th_ack = htonl(1); - p.tcph->th_seq = htonl(2); - p.tcph->th_flags = TH_PUSH | TH_ACK | TH_ECN | TH_CWR; - p.flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p.payload = payload; - p.payload_len = 3; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - p.flowflags = FLOW_PKT_TOCLIENT; - p.tcph->th_flags = TH_ACK; - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - if (((TcpSession *)p.flow->protoctx)->state != TCP_ESTABLISHED) { - printf("the TCP state should be TCP_ESTABLISEHD\n"); - goto end; - } - StreamTcpSessionClear(p.flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test the allocation of TCP session for a given packet when the same - * ports have been used to start the new session after resetting the - * previous session. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest33 (void) -{ - Packet p; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - TcpReassemblyThreadCtx ra_ctx; - StreamMsgQueue stream_q; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&stream_q, 0, sizeof(StreamMsgQueue)); - memset(&ra_ctx, 0, sizeof(TcpReassemblyThreadCtx)); - memset (&p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - p.flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p.tcph = &tcph; - p.flowflags = FLOW_PKT_TOSERVER; - int ret = 0; - ra_ctx.stream_q = &stream_q; - stt.ra_ctx = &ra_ctx; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_ack = htonl(1); - p.tcph->th_flags = TH_SYN | TH_ACK; - p.flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_ack = htonl(1); - p.tcph->th_seq = htonl(1); - p.tcph->th_flags = TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_ack = htonl(1); - p.tcph->th_seq = htonl(1); - p.tcph->th_flags = TH_RST | TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - if (((TcpSession *)(p.flow->protoctx))->state != TCP_CLOSED) { - printf("Tcp session should have been closed\n"); - goto end; - } - - p.tcph->th_seq = htonl(1); - p.tcph->th_flags = TH_SYN; - p.flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_seq = htonl(1); - p.tcph->th_ack = htonl(2); - p.tcph->th_flags = TH_SYN | TH_ACK; - p.flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_ack = htonl(2); - p.tcph->th_seq = htonl(2); - p.tcph->th_flags = TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - if (((TcpSession *)(p.flow->protoctx))->state != TCP_ESTABLISHED) { - printf("Tcp session should have been ESTABLISHED\n"); - goto end; - } - - ret = 1; -end: - StreamTcpSessionClear(p.flow->protoctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test the allocation of TCP session for a given packet when the SYN - * packet is sent with the PUSH flag set. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest34 (void) -{ - Packet p; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - TcpReassemblyThreadCtx ra_ctx; - StreamMsgQueue stream_q; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&stream_q, 0, sizeof(StreamMsgQueue)); - memset(&ra_ctx, 0, sizeof(TcpReassemblyThreadCtx)); - memset (&p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - p.flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN|TH_PUSH; - p.tcph = &tcph; - p.flowflags = FLOW_PKT_TOSERVER; - int ret = 0; - ra_ctx.stream_q = &stream_q; - stt.ra_ctx = &ra_ctx; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_ack = htonl(1); - p.tcph->th_flags = TH_SYN | TH_ACK; - p.flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_ack = htonl(1); - p.tcph->th_seq = htonl(1); - p.tcph->th_flags = TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - if (((TcpSession *)(p.flow->protoctx))->state != TCP_ESTABLISHED) { - printf("Tcp session should have been establisehd\n"); - goto end; - } - - ret = 1; -end: - StreamTcpSessionClear(p.flow->protoctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test the allocation of TCP session for a given packet when the SYN - * packet is sent with the URG flag set. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest35 (void) -{ - Packet p; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - TcpReassemblyThreadCtx ra_ctx; - StreamMsgQueue stream_q; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - memset(&stream_q, 0, sizeof(StreamMsgQueue)); - memset(&ra_ctx, 0, sizeof(TcpReassemblyThreadCtx)); - memset (&p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - p.flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN|TH_URG; - p.tcph = &tcph; - p.flowflags = FLOW_PKT_TOSERVER; - int ret = 0; - ra_ctx.stream_q = &stream_q; - stt.ra_ctx = &ra_ctx; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_ack = htonl(1); - p.tcph->th_flags = TH_SYN | TH_ACK; - p.flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - p.tcph->th_ack = htonl(1); - p.tcph->th_seq = htonl(1); - p.tcph->th_flags = TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) - goto end; - - if (((TcpSession *)(p.flow->protoctx))->state != TCP_ESTABLISHED) { - printf("Tcp session should have been establisehd\n"); - goto end; - } - - ret = 1; -end: - StreamTcpSessionClear(p.flow->protoctx); - StreamTcpFreeConfig(TRUE); - return ret; -} - -/** - * \test Test the processing of PSH and URG flag in tcp session. - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpTest36(void) -{ - Packet p; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - int ret = 0; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset (&p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - stt.ra_ctx = ra_ctx; - p.flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p.tcph = &tcph; - p.flowflags = FLOW_PKT_TOSERVER; - - StreamTcpInitConfig(TRUE); - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1) { - printf("failed in processing packet\n"); - goto end; - } - - p.tcph->th_ack = htonl(1); - p.tcph->th_flags = TH_SYN | TH_ACK; - p.flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - p.tcph->th_ack = htonl(1); - p.tcph->th_seq = htonl(1); - p.tcph->th_flags = TH_ACK; - p.flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - if (((TcpSession *)p.flow->protoctx)->state != TCP_ESTABLISHED) { - printf("the TCP state should be TCP_ESTABLISEHD\n"); - goto end; - } - - p.tcph->th_ack = htonl(2); - p.tcph->th_seq = htonl(1); - p.tcph->th_flags = TH_PUSH | TH_ACK | TH_URG; - p.flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p.payload = payload; - p.payload_len = 3; - - if (StreamTcpPacket(&tv, &p, &stt, &pq) == -1 || (TcpSession *)p.flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - if (((TcpSession *)p.flow->protoctx)->client.next_seq != 4) { - printf("the ssn->client.next_seq should be 4, but it is %"PRIu32"\n", - ((TcpSession *)p.flow->protoctx)->client.next_seq); - goto end; - } - - StreamTcpSessionClear(p.flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - return ret; -} -#endif - -/** - * \test Test the processing of out of order FIN packets in tcp session. - * - * \retval On success it returns 1 and on failure 0. - */ -static int StreamTcpTest37(void) -{ - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - uint8_t payload[4]; - TCPHdr tcph; - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - int ret = 0; - PacketQueue pq; - memset(&pq,0,sizeof(PacketQueue)); - - memset(p, 0, SIZE_OF_PACKET); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - FLOW_INITIALIZE(&f); - - stt.ra_ctx = ra_ctx; - p->flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet\n"); - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - if (((TcpSession *)p->flow->protoctx)->state != TCP_ESTABLISHED) { - printf("the TCP state should be TCP_ESTABLISEHD\n"); - goto end; - } - - p->tcph->th_ack = htonl(2); - p->tcph->th_seq = htonl(4); - p->tcph->th_flags = TH_ACK|TH_FIN; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - if (((TcpSession *)p->flow->protoctx)->state != TCP_CLOSE_WAIT) { - printf("the TCP state should be TCP_CLOSE_WAIT\n"); - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - p->tcph->th_ack = htonl(4); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_ACK; - p->payload_len = 0; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1 || (TcpSession *)p->flow->protoctx == NULL) { - printf("failed in processing packet\n"); - goto end; - } - - if (((TcpSession *)p->flow->protoctx)->client.ra_raw_base_seq != 3) { - printf("the ssn->client.next_seq should be 3, but it is %"PRIu32"\n", - ((TcpSession *)p->flow->protoctx)->client.ra_raw_base_seq); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** - * \test Test the validation of the ACK number before setting up the - * stream.last_ack. - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest38 (void) -{ - int ret = 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - uint8_t payload[128]; - TCPHdr tcph; - PacketQueue pq; - - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&pq,0,sizeof(PacketQueue)); - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - memset(p, 0, SIZE_OF_PACKET); - - FLOW_INITIALIZE(&f); - p->flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - stt.ra_ctx = ra_ctx; - - StreamTcpInitConfig(TRUE); - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - p->tcph->th_ack = htonl(29847); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - /* last_ack value should be 1 as the previous sent ACK value is out of - window */ - if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 1) { - printf("the server.last_ack should be 1, but it is %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->server.last_ack); - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x41, 127, 128); /*AAA*/ - p->payload = payload; - p->payload_len = 127; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 128) { - printf("the server.next_seq should be 128, but it is %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->server.next_seq); - goto end; - } - - p->tcph->th_ack = htonl(256); // in window, but beyond next_seq - p->tcph->th_seq = htonl(5); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - /* last_ack value should be 256, as the previous sent ACK value - is inside window */ - if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 256) { - printf("the server.last_ack should be 1, but it is %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->server.last_ack); - goto end; - } - - p->tcph->th_ack = htonl(128); - p->tcph->th_seq = htonl(8); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - /* last_ack value should be 256 as the previous sent ACK value is inside - window */ - if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 256) { - printf("the server.last_ack should be 256, but it is %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->server.last_ack); - goto end; - } - - ret = 1; - -end: - StreamTcpSessionClear(p->flow->protoctx); - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - if (stt.ra_ctx != NULL) - StreamTcpReassembleFreeThreadCtx(stt.ra_ctx); - return ret; -} - -/** - * \test Test the validation of the ACK number before setting up the - * stream.last_ack and update the next_seq after loosing the . - * - * \retval On success it returns 1 and on failure 0. - */ - -static int StreamTcpTest39 (void) -{ - Flow f; - ThreadVars tv; - StreamTcpThread stt; - uint8_t payload[4]; - TCPHdr tcph; - PacketQueue pq; - - TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx(NULL); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - memset(&pq,0,sizeof(PacketQueue)); - - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - memset(p, 0, SIZE_OF_PACKET); - - FLOW_INITIALIZE(&f); - p->flow = &f; - tcph.th_win = htons(5480); - tcph.th_flags = TH_SYN; - p->tcph = &tcph; - p->flowflags = FLOW_PKT_TOSERVER; - int ret = 0; - stt.ra_ctx = ra_ctx; - - StreamTcpInitConfig(TRUE); - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - p->tcph->th_ack = htonl(1); - p->tcph->th_seq = htonl(1); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 4) { - printf("the server.next_seq should be 4, but it is %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->server.next_seq); - goto end; - } - - p->tcph->th_ack = htonl(4); - p->tcph->th_seq = htonl(2); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - /* last_ack value should be 4 as the previous sent ACK value is inside - window */ - if (((TcpSession *)(p->flow->protoctx))->server.last_ack != 4) { - printf("the server.last_ack should be 4, but it is %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->server.last_ack); - goto end; - } - - p->tcph->th_seq = htonl(4); - p->tcph->th_ack = htonl(5); - p->tcph->th_flags = TH_PUSH | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - StreamTcpCreateTestPacket(payload, 0x41, 3, 4); /*AAA*/ - p->payload = payload; - p->payload_len = 3; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) { - printf("failed in processing packet in StreamTcpPacket\n"); - goto end; - } - - /* next_seq value should be 2987 as the previous sent ACK value is inside - window */ - if (((TcpSession *)(p->flow->protoctx))->server.next_seq != 7) { - printf("the server.next_seq should be 7, but it is %"PRIu32"\n", - ((TcpSession *)(p->flow->protoctx))->server.next_seq); - goto end; - } - - ret = 1; - -end: - StreamTcpSessionClear(p->flow->protoctx); - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - if (stt.ra_ctx != NULL) - StreamTcpReassembleFreeThreadCtx(stt.ra_ctx); - return ret; -} - -static int StreamTcpTest40(void) -{ - uint8_t raw_vlan[] = { - 0x00, 0x20, 0x08, 0x00, 0x45, 0x00, 0x00, 0x34, - 0x3b, 0x36, 0x40, 0x00, 0x40, 0x06, 0xb7, 0xc9, - 0x83, 0x97, 0x20, 0x81, 0x83, 0x97, 0x20, 0x15, - 0x04, 0x8a, 0x17, 0x70, 0x4e, 0x14, 0xdf, 0x55, - 0x4d, 0x3d, 0x5a, 0x61, 0x80, 0x10, 0x6b, 0x50, - 0x3c, 0x4c, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, - 0x00, 0x04, 0xf0, 0xc8, 0x01, 0x99, 0xa3, 0xf3 - }; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - PACKET_INITIALIZE(p); - - SET_PKT_LEN(p, sizeof(raw_vlan)); - memcpy(GET_PKT_DATA(p), raw_vlan, sizeof(raw_vlan)); - memset(&dtv, 0, sizeof(DecodeThreadVars)); - - FlowInitConfig(FLOW_QUIET); - - DecodeVLAN(&tv, &dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), NULL); - - if(p->vlanh == NULL) { - SCFree(p); - return 0; - } - - if(p->tcph == NULL) { - SCFree(p); - return 0; - } - - Packet *np = StreamTcpPseudoSetup(p, GET_PKT_DATA(p), GET_PKT_LEN(p)); - if (np == NULL) { - printf("the packet received from packet allocation is NULL: "); - return 0; - } - - StreamTcpPseudoPacketSetupHeader(np,p); - - if (((uint8_t *)p->tcph - (uint8_t *)p->ip4h) != ((uint8_t *)np->tcph - (uint8_t *)np->ip4h)) { - return 0; - } - - PACKET_RECYCLE(np); - PACKET_RECYCLE(p); - FlowShutdown(); - - return 1; -} - -static int StreamTcpTest41(void) -{ - /* IPV6/TCP/no eth header */ - uint8_t raw_ip[] = { - 0x60, 0x00, 0x00, 0x00, 0x00, 0x28, 0x06, 0x40, - 0x20, 0x01, 0x06, 0x18, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x51, 0x99, 0xcc, 0x70, - 0x20, 0x01, 0x06, 0x18, 0x00, 0x01, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, - 0x8c, 0x9b, 0x00, 0x50, 0x6a, 0xe7, 0x07, 0x36, - 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x16, 0x30, - 0x29, 0x9c, 0x00, 0x00, 0x02, 0x04, 0x05, 0x8c, - 0x04, 0x02, 0x08, 0x0a, 0x00, 0xdd, 0x1a, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x02 }; - Packet *p = SCMalloc(SIZE_OF_PACKET); - if (unlikely(p == NULL)) - return 0; - ThreadVars tv; - DecodeThreadVars dtv; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&tv, 0, sizeof(ThreadVars)); - memset(p, 0, SIZE_OF_PACKET); - PACKET_INITIALIZE(p); - - if (PacketCopyData(p, raw_ip, sizeof(raw_ip)) == -1) { - PacketFree(p); - return 1; - } - - FlowInitConfig(FLOW_QUIET); - - DecodeRaw(&tv, &dtv, p, raw_ip, GET_PKT_LEN(p), NULL); - - if (p->ip6h == NULL) { - printf("expected a valid ipv6 header but it was NULL: "); - FlowShutdown(); - SCFree(p); - return 1; - } - - if(p->tcph == NULL) { - SCFree(p); - return 0; - } - - Packet *np = StreamTcpPseudoSetup(p, GET_PKT_DATA(p), GET_PKT_LEN(p)); - if (np == NULL) { - printf("the packet received from packet allocation is NULL: "); - return 0; - } - - StreamTcpPseudoPacketSetupHeader(np,p); - - if (((uint8_t *)p->tcph - (uint8_t *)p->ip6h) != ((uint8_t *)np->tcph - (uint8_t *)np->ip6h)) { - return 0; - } - - PACKET_RECYCLE(np); - PACKET_RECYCLE(p); - SCFree(p); - FlowShutdown(); - - return 1; -} - -/** \test multiple different SYN/ACK, pick first */ -static int StreamTcpTest42 (void) -{ - int ret = 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - PacketQueue pq; - Packet *p = SCMalloc(SIZE_OF_PACKET); - TcpSession *ssn; - - if (unlikely(p == NULL)) - return 0; - memset(p, 0, SIZE_OF_PACKET); - - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - StreamTcpInitConfig(TRUE); - - FLOW_INITIALIZE(&f); - p->tcph = &tcph; - tcph.th_win = htons(5480); - p->flow = &f; - - /* SYN pkt */ - tcph.th_flags = TH_SYN; - tcph.th_seq = htonl(100); - p->flowflags = FLOW_PKT_TOSERVER; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(500); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(1000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* ACK */ - p->tcph->th_ack = htonl(501); - p->tcph->th_seq = htonl(101); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - ssn = p->flow->protoctx; - - if (ssn->state != TCP_ESTABLISHED) { - printf("state not TCP_ESTABLISHED: "); - goto end; - } - - if (ssn->server.isn != 500) { - SCLogDebug("ssn->server.isn %"PRIu32" != %"PRIu32"", - ssn->server.isn, 500); - goto end; - } - if (ssn->client.isn != 100) { - SCLogDebug("ssn->client.isn %"PRIu32" != %"PRIu32"", - ssn->client.isn, 100); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** \test multiple different SYN/ACK, pick second */ -static int StreamTcpTest43 (void) -{ - int ret = 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - PacketQueue pq; - Packet *p = SCMalloc(SIZE_OF_PACKET); - TcpSession *ssn; - - if (unlikely(p == NULL)) - return 0; - memset(p, 0, SIZE_OF_PACKET); - - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - StreamTcpInitConfig(TRUE); - - FLOW_INITIALIZE(&f); - p->tcph = &tcph; - tcph.th_win = htons(5480); - p->flow = &f; - - /* SYN pkt */ - tcph.th_flags = TH_SYN; - tcph.th_seq = htonl(100); - p->flowflags = FLOW_PKT_TOSERVER; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(500); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(1000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* ACK */ - p->tcph->th_ack = htonl(1001); - p->tcph->th_seq = htonl(101); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - ssn = p->flow->protoctx; - - if (ssn->state != TCP_ESTABLISHED) { - printf("state not TCP_ESTABLISHED: "); - goto end; - } - - if (ssn->server.isn != 1000) { - SCLogDebug("ssn->server.isn %"PRIu32" != %"PRIu32"", - ssn->server.isn, 1000); - goto end; - } - if (ssn->client.isn != 100) { - SCLogDebug("ssn->client.isn %"PRIu32" != %"PRIu32"", - ssn->client.isn, 100); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** \test multiple different SYN/ACK, pick neither */ -static int StreamTcpTest44 (void) -{ - int ret = 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - PacketQueue pq; - Packet *p = SCMalloc(SIZE_OF_PACKET); - TcpSession *ssn; - - if (unlikely(p == NULL)) - return 0; - memset(p, 0, SIZE_OF_PACKET); - - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - StreamTcpInitConfig(TRUE); - - FLOW_INITIALIZE(&f); - p->tcph = &tcph; - tcph.th_win = htons(5480); - p->flow = &f; - - /* SYN pkt */ - tcph.th_flags = TH_SYN; - tcph.th_seq = htonl(100); - p->flowflags = FLOW_PKT_TOSERVER; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(500); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(1000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* ACK */ - p->tcph->th_ack = htonl(3001); - p->tcph->th_seq = htonl(101); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) - goto end; - - ssn = p->flow->protoctx; - - if (ssn->state != TCP_SYN_RECV) { - SCLogDebug("state not TCP_SYN_RECV"); - goto end; - } - - if (ssn->client.isn != 100) { - SCLogDebug("ssn->client.isn %"PRIu32" != %"PRIu32"", - ssn->client.isn, 100); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - FLOW_DESTROY(&f); - return ret; -} - -/** \test multiple different SYN/ACK, over the limit */ -static int StreamTcpTest45 (void) -{ - int ret = 0; - Flow f; - ThreadVars tv; - StreamTcpThread stt; - TCPHdr tcph; - PacketQueue pq; - Packet *p = SCMalloc(SIZE_OF_PACKET); - TcpSession *ssn; - - if (unlikely(p == NULL)) - return 0; - memset(p, 0, SIZE_OF_PACKET); - - memset(&pq,0,sizeof(PacketQueue)); - memset (&f, 0, sizeof(Flow)); - memset(&tv, 0, sizeof (ThreadVars)); - memset(&stt, 0, sizeof (StreamTcpThread)); - memset(&tcph, 0, sizeof (TCPHdr)); - - StreamTcpInitConfig(TRUE); - stream_config.max_synack_queued = 2; - - FLOW_INITIALIZE(&f); - p->tcph = &tcph; - tcph.th_win = htons(5480); - p->flow = &f; - - /* SYN pkt */ - tcph.th_flags = TH_SYN; - tcph.th_seq = htonl(100); - p->flowflags = FLOW_PKT_TOSERVER; - - SCMutexLock(&f.m); - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(500); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(1000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(2000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - /* SYN/ACK */ - p->tcph->th_seq = htonl(3000); - p->tcph->th_ack = htonl(101); - p->tcph->th_flags = TH_SYN | TH_ACK; - p->flowflags = FLOW_PKT_TOCLIENT; - - if (StreamTcpPacket(&tv, p, &stt, &pq) != -1) - goto end; - - /* ACK */ - p->tcph->th_ack = htonl(1001); - p->tcph->th_seq = htonl(101); - p->tcph->th_flags = TH_ACK; - p->flowflags = FLOW_PKT_TOSERVER; - - if (StreamTcpPacket(&tv, p, &stt, &pq) == -1) - goto end; - - ssn = p->flow->protoctx; - - if (ssn->state != TCP_ESTABLISHED) { - printf("state not TCP_ESTABLISHED: "); - goto end; - } - - if (ssn->server.isn != 1000) { - SCLogDebug("ssn->server.isn %"PRIu32" != %"PRIu32"", - ssn->server.isn, 1000); - goto end; - } - if (ssn->client.isn != 100) { - SCLogDebug("ssn->client.isn %"PRIu32" != %"PRIu32"", - ssn->client.isn, 100); - goto end; - } - - StreamTcpSessionClear(p->flow->protoctx); - - ret = 1; -end: - StreamTcpFreeConfig(TRUE); - SCMutexUnlock(&f.m); - SCFree(p); - return ret; -} - -#endif /* UNITTESTS */ - -void StreamTcpRegisterTests (void) -{ -#ifdef UNITTESTS - UtRegisterTest("StreamTcpTest01 -- TCP session allocation", - StreamTcpTest01, 1); - UtRegisterTest("StreamTcpTest02 -- TCP session deallocation", - StreamTcpTest02, 1); - UtRegisterTest("StreamTcpTest03 -- SYN missed MidStream session", - StreamTcpTest03, 1); - UtRegisterTest("StreamTcpTest04 -- SYN/ACK missed MidStream session", - StreamTcpTest04, 1); - UtRegisterTest("StreamTcpTest05 -- 3WHS missed MidStream session", - StreamTcpTest05, 1); - UtRegisterTest("StreamTcpTest06 -- FIN, RST message MidStream session", - StreamTcpTest06, 1); - UtRegisterTest("StreamTcpTest07 -- PAWS invalid timestamp", - StreamTcpTest07, 1); - UtRegisterTest("StreamTcpTest08 -- PAWS valid timestamp", - StreamTcpTest08, 1); - UtRegisterTest("StreamTcpTest09 -- No Client Reassembly", - StreamTcpTest09, 1); - UtRegisterTest("StreamTcpTest10 -- No missed packet Async stream", - StreamTcpTest10, 1); - UtRegisterTest("StreamTcpTest11 -- SYN missed Async stream", - StreamTcpTest11, 1); - UtRegisterTest("StreamTcpTest12 -- SYN/ACK missed Async stream", - StreamTcpTest12, 1); - UtRegisterTest("StreamTcpTest13 -- opposite stream packets for Async " - "stream", StreamTcpTest13, 1); - UtRegisterTest("StreamTcp4WHSTest01", StreamTcp4WHSTest01, 1); - UtRegisterTest("StreamTcp4WHSTest02", StreamTcp4WHSTest02, 1); - UtRegisterTest("StreamTcp4WHSTest03", StreamTcp4WHSTest03, 1); - UtRegisterTest("StreamTcpTest14 -- setup OS policy", StreamTcpTest14, 1); - UtRegisterTest("StreamTcpTest15 -- setup OS policy", StreamTcpTest15, 1); - UtRegisterTest("StreamTcpTest16 -- setup OS policy", StreamTcpTest16, 1); - UtRegisterTest("StreamTcpTest17 -- setup OS policy", StreamTcpTest17, 1); - UtRegisterTest("StreamTcpTest18 -- setup OS policy", StreamTcpTest18, 1); - UtRegisterTest("StreamTcpTest19 -- setup OS policy", StreamTcpTest19, 1); - UtRegisterTest("StreamTcpTest20 -- setup OS policy", StreamTcpTest20, 1); - UtRegisterTest("StreamTcpTest21 -- setup OS policy", StreamTcpTest21, 1); - UtRegisterTest("StreamTcpTest22 -- setup OS policy", StreamTcpTest22, 1); - UtRegisterTest("StreamTcpTest23 -- stream memory leaks", StreamTcpTest23, 1); - UtRegisterTest("StreamTcpTest24 -- stream memory leaks", StreamTcpTest24, 1); - UtRegisterTest("StreamTcpTest25 -- test ecn/cwr sessions", - StreamTcpTest25, 1); - UtRegisterTest("StreamTcpTest26 -- test ecn/cwr sessions", - StreamTcpTest26, 1); - UtRegisterTest("StreamTcpTest27 -- test ecn/cwr sessions", - StreamTcpTest27, 1); - UtRegisterTest("StreamTcpTest28 -- Memcap Test", StreamTcpTest28, 1); - -#if 0 /* VJ 2010/09/01 disabled since they blow up on Fedora and Fedora is - * right about blowing up. The checksum functions are not used properly - * in the tests. */ - UtRegisterTest("StreamTcpTest29 -- Badchecksum Reset Test", StreamTcpTest29, 1); - UtRegisterTest("StreamTcpTest30 -- Badchecksum Overlap Test", StreamTcpTest30, 1); - UtRegisterTest("StreamTcpTest31 -- MultipleSyns Test", StreamTcpTest31, 1); - UtRegisterTest("StreamTcpTest32 -- Bogus CWR Test", StreamTcpTest32, 1); - UtRegisterTest("StreamTcpTest33 -- RST-SYN Again Test", StreamTcpTest33, 1); - UtRegisterTest("StreamTcpTest34 -- SYN-PUSH Test", StreamTcpTest34, 1); - UtRegisterTest("StreamTcpTest35 -- SYN-URG Test", StreamTcpTest35, 1); - UtRegisterTest("StreamTcpTest36 -- PUSH-URG Test", StreamTcpTest36, 1); -#endif - UtRegisterTest("StreamTcpTest37 -- Out of order FIN Test", StreamTcpTest37, 1); - - UtRegisterTest("StreamTcpTest38 -- validate ACK", StreamTcpTest38, 1); - UtRegisterTest("StreamTcpTest39 -- update next_seq", StreamTcpTest39, 1); - - UtRegisterTest("StreamTcpTest40 -- pseudo setup", StreamTcpTest40, 1); - UtRegisterTest("StreamTcpTest41 -- pseudo setup", StreamTcpTest41, 1); - - UtRegisterTest("StreamTcpTest42 -- SYN/ACK queue", StreamTcpTest42, 1); - UtRegisterTest("StreamTcpTest43 -- SYN/ACK queue", StreamTcpTest43, 1); - UtRegisterTest("StreamTcpTest44 -- SYN/ACK queue", StreamTcpTest44, 1); - UtRegisterTest("StreamTcpTest45 -- SYN/ACK queue", StreamTcpTest45, 1); - - /* set up the reassembly tests as well */ - StreamTcpReassembleRegisterTests(); - - StreamTcpSackRegisterTests (); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/stream-tcp.h b/framework/src/suricata/src/stream-tcp.h deleted file mode 100644 index f7c3ab10..00000000 --- a/framework/src/suricata/src/stream-tcp.h +++ /dev/null @@ -1,232 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Gurvinder Singh - */ - -#ifndef __STREAM_TCP_H__ -#define __STREAM_TCP_H__ - -#include "stream-tcp-private.h" - -#define COUNTER_STREAMTCP_STREAMS 1 - -#include "app-layer-detect-proto.h" -#include "util-mpm.h" -#include "stream.h" -#include "stream-tcp-reassemble.h" - -#define STREAM_VERBOSE FALSE -/* Flag to indicate that the checksum validation for the stream engine - has been enabled */ -#define STREAMTCP_INIT_FLAG_CHECKSUM_VALIDATION 0x01 - -/*global flow data*/ -typedef struct TcpStreamCnf_ { - /** stream tracking - * - * max stream mem usage - */ - uint64_t memcap; - uint64_t reassembly_memcap; /**< max memory usage for stream reassembly */ - - uint32_t ssn_init_flags; /**< new ssn flags will be initialized to this */ - uint8_t segment_init_flags; /**< new seg flags will be initialized to this */ - - uint16_t zero_copy_size; /**< use zero copy for app layer above segments - * of this size */ - - uint32_t prealloc_sessions; /**< ssns to prealloc per stream thread */ - int midstream; - int async_oneside; - uint32_t reassembly_depth; /**< Depth until when we reassemble the stream */ - - uint16_t reassembly_toserver_chunk_size; - uint16_t reassembly_toclient_chunk_size; - - int check_overlap_different_data; - - /** reassembly -- inline mode - * - * sliding window size for raw stream reassembly - */ - uint32_t reassembly_inline_window; - uint8_t flags; - uint8_t max_synack_queued; -} TcpStreamCnf; - -typedef struct StreamTcpThread_ { - int ssn_pool_id; - - /** if set to true, we activate the TCP tuple reuse code in the - * stream engine. */ - int runmode_flow_stream_async; - - uint64_t pkts; - - /** queue for pseudo packet(s) that were created in the stream - * process and need further handling. Currently only used when - * receiving (valid) RST packets */ - PacketQueue pseudo_queue; - - uint16_t counter_tcp_sessions; - /** sessions not picked up because memcap was reached */ - uint16_t counter_tcp_ssn_memcap; - /** pseudo packets processed */ - uint16_t counter_tcp_pseudo; - /** pseudo packets failed to setup */ - uint16_t counter_tcp_pseudo_failed; - /** packets rejected because their csum is invalid */ - uint16_t counter_tcp_invalid_checksum; - /** TCP packets with no associated flow */ - uint16_t counter_tcp_no_flow; - /** sessions reused */ - uint16_t counter_tcp_reused_ssn; - /** syn pkts */ - uint16_t counter_tcp_syn; - /** syn/ack pkts */ - uint16_t counter_tcp_synack; - /** rst pkts */ - uint16_t counter_tcp_rst; - - /** tcp reassembly thread data */ - TcpReassemblyThreadCtx *ra_ctx; -} StreamTcpThread; - -TcpStreamCnf stream_config; -void TmModuleStreamTcpRegister (void); -void StreamTcpInitConfig (char); -void StreamTcpFreeConfig(char); -void StreamTcpRegisterTests (void); - -void StreamTcpSessionPktFree (Packet *); - -void StreamTcpIncrMemuse(uint64_t); -void StreamTcpDecrMemuse(uint64_t); -int StreamTcpCheckMemcap(uint64_t); - -Packet *StreamTcpPseudoSetup(Packet *, uint8_t *, uint32_t); - -int StreamTcpSegmentForEach(const Packet *p, uint8_t flag, - StreamSegmentCallback CallbackFunc, - void *data); -void StreamTcpReassembleConfigEnableOverlapCheck(void); - -/** ------- Inline functions: ------ */ - -/** - * \brief If we are on IPS mode, and got a drop action triggered from - * the IP only module, or from a reassembled msg and/or from an - * applayer detection, then drop the rest of the packets of the - * same stream and avoid inspecting it any further - * \param p pointer to the Packet to check - * \retval 1 if we must drop this stream - * \retval 0 if the stream still legal - */ -static inline int StreamTcpCheckFlowDrops(Packet *p) -{ - /* If we are on IPS mode, and got a drop action triggered from - * the IP only module, or from a reassembled msg and/or from an - * applayer detection, then drop the rest of the packets of the - * same stream and avoid inspecting it any further */ - if (EngineModeIsIPS() && (p->flow->flags & FLOW_ACTION_DROP)) - return 1; - - return 0; -} - -/** - * \brief Function to flip the direction When we missed the SYN packet, - * SYN/ACK is considered as sent by server, but our engine flagged the - * packet as from client for the host whose packet is received first in - * the session. - * - * \param ssn TcpSession to whom this packet belongs - * \param p Packet whose flag has to be changed - */ -static inline void StreamTcpPacketSwitchDir(TcpSession *ssn, Packet *p) -{ - SCLogDebug("ssn %p: switching pkt direction", ssn); - - if (PKT_IS_TOSERVER(p)) { - p->flowflags &= ~FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_TOCLIENT; - - if (p->flowflags & FLOW_PKT_TOSERVER_FIRST) { - p->flowflags &= ~FLOW_PKT_TOSERVER_FIRST; - p->flowflags |= FLOW_PKT_TOCLIENT_FIRST; - } - } else { - p->flowflags &= ~FLOW_PKT_TOCLIENT; - p->flowflags |= FLOW_PKT_TOSERVER; - - if (p->flowflags & FLOW_PKT_TOCLIENT_FIRST) { - p->flowflags &= ~FLOW_PKT_TOCLIENT_FIRST; - p->flowflags |= FLOW_PKT_TOSERVER_FIRST; - } - } -} - -enum { - /* stream has no segments for forced reassembly, nor for detection */ - STREAM_HAS_UNPROCESSED_SEGMENTS_NONE = 0, - /* stream seems to have segments that need to be forced reassembled */ - STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY = 1, - /* stream has no segments for forced reassembly, but only segments that - * have been sent for detection, but are stuck in the detection queues */ - STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION = 2, -}; - -static inline int StreamNeedsReassembly(TcpSession *ssn, int direction) -{ - /* server tcp state */ - if (direction) { - if (ssn->server.seg_list != NULL && - (!(ssn->server.seg_list_tail->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) || - !(ssn->server.seg_list_tail->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED)) ) { - return STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY; - } else if (ssn->toclient_smsg_head != NULL) { - return STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION; - } else { - return STREAM_HAS_UNPROCESSED_SEGMENTS_NONE; - } - } else { - if (ssn->client.seg_list != NULL && - (!(ssn->client.seg_list_tail->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) || - !(ssn->client.seg_list_tail->flags & SEGMENTTCP_FLAG_APPLAYER_PROCESSED)) ) { - return STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_REASSEMBLY; - } else if (ssn->toserver_smsg_head != NULL) { - return STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION; - } else { - return STREAM_HAS_UNPROCESSED_SEGMENTS_NONE; - } - } -} - -TmEcode StreamTcpThreadInit(ThreadVars *, void *, void **); -TmEcode StreamTcpThreadDeinit(ThreadVars *tv, void *data); -int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt, - PacketQueue *pq); -void StreamTcpSessionClear(void *ssnptr); -uint32_t StreamTcpGetStreamSize(TcpStream *stream); - -#endif /* __STREAM_TCP_H__ */ - diff --git a/framework/src/suricata/src/stream.c b/framework/src/suricata/src/stream.c deleted file mode 100644 index 8aabd6dc..00000000 --- a/framework/src/suricata/src/stream.c +++ /dev/null @@ -1,290 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Stream Chunk Handling API - */ - -#include "suricata-common.h" -#include "decode.h" -#include "threads.h" -#include "stream.h" -#include "util-pool.h" -#include "util-debug.h" -#include "stream-tcp.h" -#include "flow-util.h" - -#ifdef DEBUG -static SCMutex stream_pool_memuse_mutex; -static uint64_t stream_pool_memuse = 0; -static uint64_t stream_pool_memcnt = 0; -#endif - -/* per queue setting */ -static uint16_t toserver_min_chunk_len = 2560; -static uint16_t toclient_min_chunk_len = 2560; - -static Pool *stream_msg_pool = NULL; -static SCMutex stream_msg_pool_mutex = SCMUTEX_INITIALIZER; - -static void StreamMsgEnqueue (StreamMsgQueue *q, StreamMsg *s) -{ - SCEnter(); - SCLogDebug("s %p", s); - /* more packets in queue */ - if (q->top != NULL) { - s->next = q->top; - q->top->prev = s; - q->top = s; - /* only packet */ - } else { - q->top = s; - q->bot = s; - } - q->len++; -#ifdef DBG_PERF - if (q->len > q->dbg_maxlen) - q->dbg_maxlen = q->len; -#endif /* DBG_PERF */ - SCReturn; -} - -static StreamMsg *StreamMsgDequeue (StreamMsgQueue *q) -{ - SCEnter(); - - /* if the queue is empty there are no packets left. - * In that case we sleep and try again. */ - if (q->len == 0) { - SCReturnPtr(NULL, "StreamMsg"); - } - - /* pull the bottom packet from the queue */ - StreamMsg *s = q->bot; - - /* more packets in queue */ - if (q->bot->prev != NULL) { - q->bot = q->bot->prev; - q->bot->next = NULL; - /* just the one we remove, so now empty */ - } else { - q->top = NULL; - q->bot = NULL; - } - q->len--; - - s->next = NULL; - s->prev = NULL; - SCReturnPtr(s, "StreamMsg"); -} - -/* Used by stream reassembler to get msgs */ -StreamMsg *StreamMsgGetFromPool(void) -{ - SCMutexLock(&stream_msg_pool_mutex); - StreamMsg *s = (StreamMsg *)PoolGet(stream_msg_pool); - SCMutexUnlock(&stream_msg_pool_mutex); - return s; -} - -/* Used by l7inspection to return msgs to pool */ -void StreamMsgReturnToPool(StreamMsg *s) -{ - SCLogDebug("s %p", s); - SCMutexLock(&stream_msg_pool_mutex); - PoolReturn(stream_msg_pool, (void *)s); - SCMutexUnlock(&stream_msg_pool_mutex); -} - -/* Used by l7inspection to get msgs with data */ -StreamMsg *StreamMsgGetFromQueue(StreamMsgQueue *q) -{ - if (q->len > 0) { - StreamMsg *s = StreamMsgDequeue(q); - return s; - } else { - /* return NULL if we have no stream msg. Should only happen on signals. */ - return NULL; - } -} - -/* Used by stream reassembler to fill the queue for l7inspect reading */ -void StreamMsgPutInQueue(StreamMsgQueue *q, StreamMsg *s) -{ - StreamMsgEnqueue(q, s); - SCLogDebug("q->len %" PRIu32 "", q->len); -} - -#define SIZE 4072 -void *StreamMsgPoolAlloc(void) -{ - if (StreamTcpReassembleCheckMemcap((uint32_t)(sizeof(StreamMsg)+SIZE)) == 0) - return NULL; - - StreamMsg *m = SCCalloc(1, (sizeof(StreamMsg) + SIZE)); - if (m != NULL) { - m->data = (uint8_t *)m + sizeof(StreamMsg); - m->data_size = SIZE; - - StreamTcpReassembleIncrMemuse((uint32_t)(sizeof(StreamMsg)+SIZE)); - } - - return m; -} - -int StreamMsgInit(void *data, void *initdata) -{ - StreamMsg *s = data; - memset(s->data, 0, s->data_size); - -#ifdef DEBUG - SCMutexLock(&stream_pool_memuse_mutex); - stream_pool_memuse += (sizeof(StreamMsg) + SIZE); - stream_pool_memcnt ++; - SCMutexUnlock(&stream_pool_memuse_mutex); -#endif - return 1; -} - -void StreamMsgPoolFree(void *ptr) -{ - if (ptr) { - SCFree(ptr); - StreamTcpReassembleDecrMemuse((uint32_t)(sizeof(StreamMsg)+SIZE)); - } -} - -void StreamMsgQueuesInit(uint32_t prealloc) -{ -#ifdef DEBUG - SCMutexInit(&stream_pool_memuse_mutex, NULL); -#endif - SCMutexLock(&stream_msg_pool_mutex); - stream_msg_pool = PoolInit(0, prealloc, 0, - StreamMsgPoolAlloc,StreamMsgInit, - NULL,NULL,StreamMsgPoolFree); - if (stream_msg_pool == NULL) - exit(EXIT_FAILURE); /* XXX */ - SCMutexUnlock(&stream_msg_pool_mutex); -} - -void StreamMsgQueuesDeinit(char quiet) -{ - if (quiet == FALSE) { - if (stream_msg_pool->max_outstanding > stream_msg_pool->allocated) - SCLogInfo("TCP segment chunk pool had a peak use of %u chunks, " - "more than the prealloc setting of %u", - stream_msg_pool->max_outstanding, stream_msg_pool->allocated); - } - - SCMutexLock(&stream_msg_pool_mutex); - PoolFree(stream_msg_pool); - SCMutexUnlock(&stream_msg_pool_mutex); - -#ifdef DEBUG - SCMutexDestroy(&stream_pool_memuse_mutex); - - if (quiet == FALSE) - SCLogDebug("stream_pool_memuse %"PRIu64", stream_pool_memcnt %"PRIu64"", stream_pool_memuse, stream_pool_memcnt); -#endif -} - -/** \brief alloc a stream msg queue - * \retval smq ptr to the queue or NULL */ -StreamMsgQueue *StreamMsgQueueGetNew(void) -{ - if (StreamTcpReassembleCheckMemcap((uint32_t)sizeof(StreamMsgQueue)) == 0) - return NULL; - - StreamMsgQueue *smq = SCMalloc(sizeof(StreamMsgQueue)); - if (unlikely(smq == NULL)) - return NULL; - - StreamTcpReassembleIncrMemuse((uint32_t)sizeof(StreamMsgQueue)); - - memset(smq, 0x00, sizeof(StreamMsgQueue)); - return smq; -} - -/** \brief Free a StreamMsgQueue - * \param q the queue to free - * \todo we may want to consider non empty queue's - */ -void StreamMsgQueueFree(StreamMsgQueue *q) -{ - SCFree(q); - StreamTcpReassembleDecrMemuse((uint32_t)sizeof(StreamMsgQueue)); -} - -void StreamMsgQueueSetMinChunkLen(uint8_t dir, uint16_t len) -{ - if (dir == FLOW_PKT_TOSERVER) { - toserver_min_chunk_len = len; - } else { - toclient_min_chunk_len = len; - } -} - -uint16_t StreamMsgQueueGetMinChunkLen(uint8_t dir) -{ - if (dir == FLOW_PKT_TOSERVER) { - return toserver_min_chunk_len; - } else { - return toclient_min_chunk_len; - } -} - -/** \brief Return a list of smsgs to the pool */ -void StreamMsgReturnListToPool(void *list) -{ - /* if we have (a) smsg(s), return to the pool */ - StreamMsg *smsg = (StreamMsg *)list; - while (smsg != NULL) { - StreamMsg *smsg_next = smsg->next; - SCLogDebug("returning smsg %p to pool", smsg); - smsg->next = NULL; - smsg->prev = NULL; - StreamMsgReturnToPool(smsg); - smsg = smsg_next; - } -} - -/** \brief Run callback for all segments - * - * \return -1 in case of error, the number of segment in case of success - */ -int StreamSegmentForEach(const Packet *p, uint8_t flag, StreamSegmentCallback CallbackFunc, void *data) -{ - switch(p->proto) { - case IPPROTO_TCP: - return StreamTcpSegmentForEach(p, flag, CallbackFunc, data); - break; -#ifdef DEBUG - case IPPROTO_UDP: - SCLogWarning(SC_ERR_UNKNOWN_PROTOCOL, "UDP is currently unsupported"); - break; - default: - SCLogWarning(SC_ERR_UNKNOWN_PROTOCOL, "This protocol is currently unsupported"); - break; -#endif - } - return 0; -} diff --git a/framework/src/suricata/src/stream.h b/framework/src/suricata/src/stream.h deleted file mode 100644 index dfe5c342..00000000 --- a/framework/src/suricata/src/stream.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __STREAM_H__ -#define __STREAM_H__ - -#include "flow.h" - -#define STREAM_START 0x01 -#define STREAM_EOF 0x02 -#define STREAM_TOSERVER 0x04 -#define STREAM_TOCLIENT 0x08 -#define STREAM_GAP 0x10 /**< data gap encountered */ -#define STREAM_DEPTH 0x20 /**< depth reached */ - -typedef struct StreamMsg_ { - struct StreamMsg_ *next; - struct StreamMsg_ *prev; - - uint32_t seq; /**< sequence number */ - uint32_t data_len; /**< length of the data */ - uint32_t data_size; - uint8_t *data; /**< reassembled data: ptr to after this - * struct */ -} StreamMsg; - -typedef struct StreamMsgQueue_ { - StreamMsg *top; - StreamMsg *bot; - uint16_t len; -#ifdef DBG_PERF - uint16_t dbg_maxlen; -#endif /* DBG_PERF */ -} StreamMsgQueue; - -/* prototypes */ -void StreamMsgQueuesInit(uint32_t prealloc); -void StreamMsgQueuesDeinit(char); - -StreamMsg *StreamMsgGetFromPool(void); -void StreamMsgReturnToPool(StreamMsg *); -StreamMsg *StreamMsgGetFromQueue(StreamMsgQueue *); -void StreamMsgPutInQueue(StreamMsgQueue *, StreamMsg *); - -StreamMsgQueue *StreamMsgQueueGetNew(void); -void StreamMsgQueueFree(StreamMsgQueue *); - -void StreamMsgQueueSetMinChunkLen(uint8_t dir, uint16_t len); -uint16_t StreamMsgQueueGetMinChunkLen(uint8_t); - -void StreamMsgReturnListToPool(void *); - -typedef int (*StreamSegmentCallback)(const Packet *, void *, uint8_t *, uint32_t); -int StreamSegmentForEach(const Packet *p, uint8_t flag, - StreamSegmentCallback CallbackFunc, - void *data); - -#endif /* __STREAM_H__ */ - diff --git a/framework/src/suricata/src/suricata-common.h b/framework/src/suricata/src/suricata-common.h deleted file mode 100644 index 388f1a42..00000000 --- a/framework/src/suricata/src/suricata-common.h +++ /dev/null @@ -1,343 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Common includes, etc. - */ - -#ifndef __SURICATA_COMMON_H__ -#define __SURICATA_COMMON_H__ - -#ifdef DEBUG -#define DBG_PERF -#endif - -#define TRUE 1 -#define FALSE 0 - -#define _GNU_SOURCE -#define __USE_GNU - -#if HAVE_CONFIG_H -#include -#endif - -#ifndef CLS -#warning "L1 cache line size not detected during build. Assuming 64 bytes." -#define CLS 64 -#endif - -#if HAVE_STDIO_H -#include -#endif - -#if HAVE_STDINT_h -#include -#endif - -#if HAVE_STDARG_H -#include -#endif - -#ifdef HAVE_STDLIB_H -#include -#endif - -#if HAVE_ERRNO_H -#include -#endif - -#if HAVE_UNISTD_H -#include -#endif - -#if HAVE_INTTYPES_H -#include -#endif - -#if HAVE_LIMITS_H -#include -#endif - -#if HAVE_CTYPE_H -#include -#endif - -#if HAVE_STRING_H -#include -#endif - -#if HAVE_FCNTL_H -#include -#endif - -#ifdef HAVE_TIME_H -#include -#endif - -#if HAVE_SYS_SYSCALL_H -#include -#endif - -#if HAVE_SYSCALL_H -#include -#endif - -#if HAVE_SYS_TYPES_H -#include /* for gettid(2) */ -#endif - -#if HAVE_SCHED_H -#include /* for sched_setaffinity(2) */ -#endif - -#include - -#ifdef HAVE_SYSLOG_H -#include -#else -#ifdef OS_WIN32 -#include "win32-syslog.h" -#endif /* OS_WIN32 */ -#endif /* HAVE_SYSLOG_H */ - -#ifdef OS_WIN32 -#include "win32-misc.h" -#include "win32-service.h" -#endif /* OS_WIN32 */ - -#if HAVE_SYS_TIME_H -#include -#endif - -#if HAVE_POLL_H -#include -#endif - -#if HAVE_SYS_SIGNAL_H -#include -#endif - -#if HAVE_SIGNAL_H -#include -#endif - -#if HAVE_SYS_TYPES_H -#include -#endif - -#if HAVE_SYS_SOCKET_H -#include -#endif - -#if HAVE_SYS_STAT_H -#include -#endif - -#if HAVE_NETINET_IN_H -#include -#endif - -#if HAVE_ARPA_INET_H -#include -#endif - -#if HAVE_NETDB_H -#include -#endif - -#ifdef HAVE_PCAP_H -#include -#endif - -#ifdef HAVE_PCAP_PCAP_H -#include -#endif - -#ifdef HAVE_PCAP_BPF_H -#include -#endif - -#if __CYGWIN__ -#if !defined _X86_ && !defined __x86_64 -#define _X86_ -#endif -#endif - -#ifdef HAVE_WINDOWS_H -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 -#endif -#include -#endif - -#ifdef HAVE_W32API_WINBASE_H -#include -#endif - -#ifdef HAVE_W32API_WTYPES_H -#include -#endif - -#if !__CYGWIN__ -#ifdef HAVE_WINSOCK2_H -#include -#endif -#ifdef HAVE_WS2TCPIP_H -#include -#endif -#endif /* !__CYGWIN__ */ - -#if CPPCHECK==1 -#define BUG_ON(x) if (((x))) exit(1) -#else -#ifdef HAVE_ASSERT_H -#include -#define BUG_ON(x) assert(!(x)) -#else -#define BUG_ON(x) -#endif -#endif - -/* we need this to stringify the defines which are supplied at compiletime see: - http://gcc.gnu.org/onlinedocs/gcc-3.4.1/cpp/Stringification.html#Stringification */ -#define xstr(s) str(s) -#define str(s) #s - -/** type for the internal signature id. Since it's used in the matching engine - * extensively keeping this as small as possible reduces the overall memory - * footprint of the engine. Set to uint32_t if the engine needs to support - * more than 64k sigs. */ -//#define SigIntId uint16_t -#define SigIntId uint32_t - -/** same for pattern id's */ -#define PatIntId uint16_t - -/** FreeBSD does not define __WORDSIZE, but it uses __LONG_BIT */ -#ifndef __WORDSIZE - #ifdef __LONG_BIT - #define __WORDSIZE __LONG_BIT - #else - #ifdef LONG_BIT - #define __WORDSIZE LONG_BIT - #endif - #endif -#endif - -/** Windows does not define __WORDSIZE, but it uses __X86__ */ -#ifndef __WORDSIZE - #if defined(__X86__) || defined(_X86_) - #define __WORDSIZE 32 - #else - #if defined(__X86_64__) || defined(_X86_64_) - #define __WORDSIZE 64 - #endif - #endif - - #ifndef __WORDSIZE - #warning Defaulting to __WORDSIZE 32 - #define __WORDSIZE 32 - #endif -#endif - -/** darwin doesn't defined __BYTE_ORDER and friends, but BYTE_ORDER */ -#ifndef __BYTE_ORDER -#ifdef BYTE_ORDER -#define __BYTE_ORDER BYTE_ORDER -#endif -#endif - -#ifndef __LITTLE_ENDIAN -#ifdef LITTLE_ENDIAN -#define __LITTLE_ENDIAN LITTLE_ENDIAN -#endif -#endif - -#ifndef __BIG_ENDIAN -#ifdef BIG_ENDIAN -#define __BIG_ENDIAN BIG_ENDIAN -#endif -#endif - -#ifndef HAVE_PCRE_FREE_STUDY -#define pcre_free_study pcre_free -#endif - -#ifndef MIN -#define MIN(x, y) (((x)<(y))?(x):(y)) -#endif - -typedef enum PacketProfileDetectId_ { - PROF_DETECT_MPM, - PROF_DETECT_MPM_PACKET, /* PKT MPM */ - PROF_DETECT_MPM_PKT_STREAM, /* PKT inspected with stream MPM */ - PROF_DETECT_MPM_STREAM, /* STREAM MPM */ - PROF_DETECT_MPM_URI, - PROF_DETECT_MPM_HCBD, - PROF_DETECT_MPM_HSBD, - PROF_DETECT_MPM_HHD, - PROF_DETECT_MPM_HRHD, - PROF_DETECT_MPM_HMD, - PROF_DETECT_MPM_HCD, - PROF_DETECT_MPM_HRUD, - PROF_DETECT_MPM_HSMD, - PROF_DETECT_MPM_HSCD, - PROF_DETECT_MPM_HUAD, - PROF_DETECT_MPM_HHHD, - PROF_DETECT_MPM_HRHHD, - PROF_DETECT_MPM_DNSQUERY, - PROF_DETECT_IPONLY, - PROF_DETECT_RULES, - PROF_DETECT_STATEFUL, - PROF_DETECT_PREFILTER, - PROF_DETECT_NONMPMLIST, - PROF_DETECT_ALERT, - PROF_DETECT_CLEANUP, - PROF_DETECT_GETSGH, - PROF_DETECT_MPM_FD_SMTP, - - PROF_DETECT_SIZE, -} PacketProfileDetectId; - -#include -#include "threads.h" -#include "tm-threads-common.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-mem.h" -#include "detect-engine-alert.h" -#include "util-optimize.h" -#include "util-path.h" -#include "util-conf.h" - -#ifndef HAVE_STRLCAT -size_t strlcat(char *, const char *src, size_t siz); -#endif -#ifndef HAVE_STRLCPY -size_t strlcpy(char *dst, const char *src, size_t siz); -#endif - -extern int coverage_unittests; -extern int g_ut_modules; -extern int g_ut_covered; -#endif /* __SURICATA_COMMON_H__ */ - diff --git a/framework/src/suricata/src/suricata.c b/framework/src/suricata/src/suricata.c deleted file mode 100644 index b368f21d..00000000 --- a/framework/src/suricata/src/suricata.c +++ /dev/null @@ -1,2564 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#include "suricata-common.h" -#include "config.h" - -#if HAVE_GETOPT_H -#include -#endif - -#if HAVE_SIGNAL_H -#include -#endif - -#ifdef HAVE_NSS -#include -#include -#endif - -#include "suricata.h" -#include "decode.h" -#include "detect.h" -#include "packet-queue.h" -#include "threads.h" -#include "threadvars.h" - -#include "util-atomic.h" -#include "util-spm.h" -#include "util-cpu.h" -#include "util-action.h" -#include "util-pidfile.h" -#include "util-ioctl.h" -#include "util-device.h" -#include "util-misc.h" -#include "util-running-modes.h" - -#include "detect-engine.h" -#include "detect-parse.h" -#include "detect-fast-pattern.h" -#include "detect-engine-tag.h" -#include "detect-engine-threshold.h" -#include "detect-engine-address.h" -#include "detect-engine-port.h" -#include "detect-engine-mpm.h" - -#include "tm-queuehandlers.h" -#include "tm-queues.h" -#include "tm-threads.h" - -#include "tmqh-flow.h" - -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "alert-fastlog.h" -#include "alert-unified2-alert.h" -#include "alert-debuglog.h" -#include "alert-prelude.h" -#include "alert-syslog.h" -#include "output-json-alert.h" - -#include "output-json-flow.h" -#include "output-json-netflow.h" -#include "log-droplog.h" -#include "output-json-drop.h" -#include "log-httplog.h" -#include "output-json-http.h" -#include "log-dnslog.h" -#include "output-json-dns.h" -#include "log-tlslog.h" -#include "log-tlsstore.h" -#include "output-json-tls.h" -#include "output-json-ssh.h" -#include "log-pcap.h" -#include "log-file.h" -#include "output-json-file.h" -#include "output-json-smtp.h" -#include "output-json-stats.h" -#include "log-filestore.h" -#include "log-tcp-data.h" -#include "log-stats.h" - -#include "output-json.h" - -#include "output-json-template.h" - -#include "stream-tcp.h" - -#include "source-nfq.h" -#include "source-nfq-prototypes.h" - -#include "source-nflog.h" - -#include "source-ipfw.h" - -#include "source-pcap.h" -#include "source-pcap-file.h" - -#include "source-pfring.h" - -#include "source-erf-file.h" -#include "source-erf-dag.h" -#include "source-napatech.h" - -#include "source-af-packet.h" -#include "source-netmap.h" -#include "source-mpipe.h" - -#include "respond-reject.h" - -#include "flow.h" -#include "flow-timeout.h" -#include "flow-manager.h" -#include "flow-var.h" -#include "flow-bit.h" -#include "pkt-var.h" -#include "host-bit.h" - -#include "ippair.h" -#include "ippair-bit.h" - -#include "host.h" -#include "unix-manager.h" - -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-htp.h" - -#include "util-radix-tree.h" -#include "util-host-os-info.h" -#include "util-cidr.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-time.h" -#include "util-rule-vars.h" -#include "util-classification-config.h" -#include "util-threshold-config.h" -#include "util-reference-config.h" -#include "util-profiling.h" -#include "util-magic.h" -#include "util-signal.h" - -#include "util-coredump-config.h" - -#include "util-decode-mime.h" - -#include "defrag.h" - -#include "runmodes.h" -#include "runmode-unittests.h" - -#include "util-cuda.h" -#include "util-decode-asn1.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-daemon.h" -#include "reputation.h" - -#include "output.h" -#include "output-lua.h" - -#include "output-packet.h" -#include "output-tx.h" -#include "output-file.h" -#include "output-filedata.h" -#include "output-streaming.h" - -#include "util-privs.h" - -#include "tmqh-packetpool.h" - -#include "util-proto-name.h" -#ifdef __SC_CUDA_SUPPORT__ -#include "util-cuda-buffer.h" -#include "util-mpm-ac.h" -#endif -#include "util-storage.h" -#include "host-storage.h" - -/* - * we put this here, because we only use it here in main. - */ -volatile sig_atomic_t sigint_count = 0; -volatile sig_atomic_t sighup_count = 0; -volatile sig_atomic_t sigterm_count = 0; -volatile sig_atomic_t sigusr2_count = 0; - -/* - * Flag to indicate if the engine is at the initialization - * or already processing packets. 3 stages: SURICATA_INIT, - * SURICATA_RUNTIME and SURICATA_FINALIZE - */ -SC_ATOMIC_DECLARE(unsigned int, engine_stage); - -/* Max packets processed simultaniously per thread. */ -#define DEFAULT_MAX_PENDING_PACKETS 1024 - -/** suricata engine control flags */ -volatile uint8_t suricata_ctl_flags = 0; - -/** Run mode selected */ -int run_mode = RUNMODE_UNKNOWN; - -/** Engine mode: inline (ENGINE_MODE_IPS) or just - * detection mode (ENGINE_MODE_IDS by default) */ -static enum EngineMode g_engine_mode = ENGINE_MODE_IDS; - -/** Host mode: set if box is sniffing only - * or is a router */ -uint8_t host_mode = SURI_HOST_IS_SNIFFER_ONLY; - -/** Maximum packets to simultaneously process. */ -intmax_t max_pending_packets; - -/** global indicating if detection is enabled */ -int g_detect_disabled = 0; - -/** set caps or not */ -int sc_set_caps; - -char *conf_filename = NULL; - -int EngineModeIsIPS(void) -{ - return (g_engine_mode == ENGINE_MODE_IPS); -} - -int EngineModeIsIDS(void) -{ - return (g_engine_mode == ENGINE_MODE_IDS); -} - -void EngineModeSetIPS(void) -{ - g_engine_mode = ENGINE_MODE_IPS; -} - -void EngineModeSetIDS(void) -{ - g_engine_mode = ENGINE_MODE_IDS; -} - -int RunmodeIsUnittests(void) -{ - if (run_mode == RUNMODE_UNITTEST) - return 1; - - return 0; -} - -int RunmodeGetCurrent(void) -{ - return run_mode; -} - -static void SignalHandlerSigint(/*@unused@*/ int sig) -{ - sigint_count = 1; - suricata_ctl_flags |= SURICATA_STOP; -} -static void SignalHandlerSigterm(/*@unused@*/ int sig) -{ - sigterm_count = 1; - suricata_ctl_flags |= SURICATA_KILL; -} - -void SignalHandlerSigusr2StartingUp(int sig) -{ - SCLogInfo("Live rule reload only possible after engine completely started."); -} - -void SignalHandlerSigusr2DelayedDetect(int sig) -{ - SCLogWarning(SC_ERR_LIVE_RULE_SWAP, "Live rule reload blocked while delayed detect is still loading."); -} - -void SignalHandlerSigusr2SigFileStartup(int sig) -{ - SCLogInfo("Live rule reload not possible if -s or -S option used at runtime."); -} - -/** - * SIGUSR2 handler. Just set sigusr2_count. The main loop will act on - * it. - */ -void SignalHandlerSigusr2(int sig) -{ - sigusr2_count = 1; -} - -/** - * SIGHUP handler. Just set sighup_count. The main loop will act on - * it. - */ -static void SignalHandlerSigHup(/*@unused@*/ int sig) -{ - sighup_count = 1; -} - -#ifdef DBG_MEM_ALLOC -#ifndef _GLOBAL_MEM_ -#define _GLOBAL_MEM_ -/* This counter doesn't complain realloc's(), it's gives - * an aproximation for the startup */ -size_t global_mem = 0; -#ifdef DBG_MEM_ALLOC_SKIP_STARTUP -uint8_t print_mem_flag = 0; -#else -uint8_t print_mem_flag = 1; -#endif -#endif -#endif - -void CreateLowercaseTable() -{ - /* create table for O(1) lowercase conversion lookup. It was removed, but - * we still need it for cuda. So resintalling it back into the codebase */ - int c = 0; - memset(g_u8_lowercasetable, 0x00, sizeof(g_u8_lowercasetable)); - for ( ; c < 256; c++) { - if (c >= 'A' && c <= 'Z') - g_u8_lowercasetable[c] = (c + ('a' - 'A')); - else - g_u8_lowercasetable[c] = c; - } -} - -void GlobalInits() -{ - memset(trans_q, 0, sizeof(trans_q)); - memset(data_queues, 0, sizeof(data_queues)); - - /* Initialize the trans_q mutex */ - int blah; - int r = 0; - for(blah=0;blah<256;blah++) { - r |= SCMutexInit(&trans_q[blah].mutex_q, NULL); - r |= SCCondInit(&trans_q[blah].cond_q, NULL); - - r |= SCMutexInit(&data_queues[blah].mutex_q, NULL); - r |= SCCondInit(&data_queues[blah].cond_q, NULL); - } - - if (r != 0) { - SCLogInfo("Trans_Q Mutex not initialized correctly"); - exit(EXIT_FAILURE); - } - - CreateLowercaseTable(); -} - -/* XXX hack: make sure threads can stop the engine by calling this - function. Purpose: pcap file mode needs to be able to tell the - engine the file eof is reached. */ -void EngineStop(void) -{ - suricata_ctl_flags |= SURICATA_STOP; -} - -void EngineKill(void) -{ - suricata_ctl_flags |= SURICATA_KILL; -} - -/** - * \brief Used to indicate that the current task is done. - * - * This is mainly used by pcap-file to tell it has finished - * to treat a pcap files when running in unix-socket mode. - */ -void EngineDone(void) -{ - suricata_ctl_flags |= SURICATA_DONE; -} - -static int SetBpfString(int optind, char *argv[]) -{ - char *bpf_filter = NULL; - uint32_t bpf_len = 0; - int tmpindex = 0; - - /* attempt to parse remaining args as bpf filter */ - tmpindex = optind; - while(argv[tmpindex] != NULL) { - bpf_len+=strlen(argv[tmpindex]) + 1; - tmpindex++; - } - - if (bpf_len == 0) - return TM_ECODE_OK; - - if (EngineModeIsIPS()) { - SCLogError(SC_ERR_NOT_SUPPORTED, - "BPF filter not available in IPS mode." - " Use firewall filtering if possible."); - return TM_ECODE_FAILED; - } - - bpf_filter = SCMalloc(bpf_len); - if (unlikely(bpf_filter == NULL)) - return TM_ECODE_OK; - memset(bpf_filter, 0x00, bpf_len); - - tmpindex = optind; - while(argv[tmpindex] != NULL) { - strlcat(bpf_filter, argv[tmpindex],bpf_len); - if(argv[tmpindex + 1] != NULL) { - strlcat(bpf_filter," ", bpf_len); - } - tmpindex++; - } - - if(strlen(bpf_filter) > 0) { - if (ConfSetFinal("bpf-filter", bpf_filter) != 1) { - SCLogError(SC_ERR_FATAL, "Failed to set bpf filter."); - return TM_ECODE_FAILED; - } - } - SCFree(bpf_filter); - - return TM_ECODE_OK; -} - -static void SetBpfStringFromFile(char *filename) -{ - char *bpf_filter = NULL; - char *bpf_comment_tmp = NULL; - char *bpf_comment_start = NULL; - uint32_t bpf_len = 0; -#ifdef OS_WIN32 - struct _stat st; -#else - struct stat st; -#endif /* OS_WIN32 */ - FILE *fp = NULL; - size_t nm = 0; - - if (EngineModeIsIPS()) { - SCLogError(SC_ERR_NOT_SUPPORTED, - "BPF filter not available in IPS mode." - " Use firewall filtering if possible."); - exit(EXIT_FAILURE); - } - -#ifdef OS_WIN32 - if(_stat(filename, &st) != 0) { -#else - if(stat(filename, &st) != 0) { -#endif /* OS_WIN32 */ - SCLogError(SC_ERR_FOPEN, "Failed to stat file %s", filename); - exit(EXIT_FAILURE); - } - bpf_len = st.st_size + 1; - - fp = fopen(filename,"r"); - if (fp == NULL) { - SCLogError(SC_ERR_FOPEN, "Failed to open file %s", filename); - exit(EXIT_FAILURE); - } - - bpf_filter = SCMalloc(bpf_len * sizeof(char)); - if (unlikely(bpf_filter == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate buffer for bpf filter in file %s", filename); - exit(EXIT_FAILURE); - } - memset(bpf_filter, 0x00, bpf_len); - - nm = fread(bpf_filter, bpf_len - 1, 1, fp); - if((ferror(fp) != 0)||( nm != 1)) { - *bpf_filter='\0'; - } - fclose(fp); - - if(strlen(bpf_filter) > 0) { - /*replace comments with space*/ - bpf_comment_start = bpf_filter; - while((bpf_comment_tmp = strchr(bpf_comment_start, '#')) != NULL) { - while((*bpf_comment_tmp !='\0') && - (*bpf_comment_tmp != '\r') && (*bpf_comment_tmp != '\n')) - { - *bpf_comment_tmp++ = ' '; - } - bpf_comment_start = bpf_comment_tmp; - } - /*remove remaining '\r' and '\n' */ - while((bpf_comment_tmp = strchr(bpf_filter, '\r')) != NULL) { - *bpf_comment_tmp = ' '; - } - while((bpf_comment_tmp = strchr(bpf_filter, '\n')) != NULL) { - *bpf_comment_tmp = ' '; - } - if(ConfSetFinal("bpf-filter", bpf_filter) != 1) { - SCLogError(SC_ERR_FOPEN, "ERROR: Failed to set bpf filter!"); - SCFree(bpf_filter); - exit(EXIT_FAILURE); - } - } - SCFree(bpf_filter); -} - -void usage(const char *progname) -{ -#ifdef REVISION - printf("%s %s (rev %s)\n", PROG_NAME, PROG_VER, xstr(REVISION)); -#else - printf("%s %s\n", PROG_NAME, PROG_VER); -#endif - printf("USAGE: %s [OPTIONS] [BPF FILTER]\n\n", progname); - printf("\t-c : path to configuration file\n"); - printf("\t-T : test configuration file (use with -c)\n"); - printf("\t-i : run in pcap live mode\n"); - printf("\t-F : bpf filter file\n"); - printf("\t-r : run in pcap file/offline mode\n"); -#ifdef NFQ - printf("\t-q : run in inline nfqueue mode\n"); -#endif /* NFQ */ -#ifdef IPFW - printf("\t-d : run in inline ipfw divert mode\n"); -#endif /* IPFW */ - printf("\t-s : path to signature file loaded in addition to suricata.yaml settings (optional)\n"); - printf("\t-S : path to signature file loaded exclusively (optional)\n"); - printf("\t-l : default log directory\n"); -#ifndef OS_WIN32 - printf("\t-D : run as daemon\n"); -#else - printf("\t--service-install : install as service\n"); - printf("\t--service-remove : remove service\n"); - printf("\t--service-change-params : change service startup parameters\n"); -#endif /* OS_WIN32 */ - printf("\t-k [all|none] : force checksum check (all) or disabled it (none)\n"); - printf("\t-V : display Suricata version\n"); - printf("\t-v[v] : increase default Suricata verbosity\n"); -#ifdef UNITTESTS - printf("\t-u : run the unittests and exit\n"); - printf("\t-U, --unittest-filter=REGEX : filter unittests with a regex\n"); - printf("\t--list-unittests : list unit tests\n"); - printf("\t--fatal-unittests : enable fatal failure on unittest error\n"); - printf("\t--unittests-coverage : display unittest coverage report\n"); -#endif /* UNITTESTS */ - printf("\t--list-app-layer-protos : list supported app layer protocols\n"); - printf("\t--list-keywords[=all|csv|] : list keywords implemented by the engine\n"); -#ifdef __SC_CUDA_SUPPORT__ - printf("\t--list-cuda-cards : list cuda supported cards\n"); -#endif - printf("\t--list-runmodes : list supported runmodes\n"); - printf("\t--runmode : specific runmode modification the engine should run. The argument\n" - "\t supplied should be the id for the runmode obtained by running\n" - "\t --list-runmodes\n"); - printf("\t--engine-analysis : print reports on analysis of different sections in the engine and exit.\n" - "\t Please have a look at the conf parameter engine-analysis on what reports\n" - "\t can be printed\n"); - printf("\t--pidfile : write pid to this file\n"); - printf("\t--init-errors-fatal : enable fatal failure on signature init error\n"); - printf("\t--disable-detection : disable detection engine\n"); - printf("\t--dump-config : show the running configuration\n"); - printf("\t--build-info : display build information\n"); - printf("\t--pcap[=] : run in pcap mode, no value select interfaces from suricata.yaml\n"); -#ifdef HAVE_PCAP_SET_BUFF - printf("\t--pcap-buffer-size : size of the pcap buffer value from 0 - %i\n",INT_MAX); -#endif /* HAVE_SET_PCAP_BUFF */ -#ifdef HAVE_AF_PACKET - printf("\t--af-packet[=] : run in af-packet mode, no value select interfaces from suricata.yaml\n"); -#endif -#ifdef HAVE_NETMAP - printf("\t--netmap[=] : run in netmap mode, no value select interfaces from suricata.yaml\n"); -#endif -#ifdef HAVE_PFRING - printf("\t--pfring[=] : run in pfring mode, use interfaces from suricata.yaml\n"); - printf("\t--pfring-int : run in pfring mode, use interface \n"); - printf("\t--pfring-cluster-id : pfring cluster id \n"); - printf("\t--pfring-cluster-type : pfring cluster type for PF_RING 4.1.2 and later cluster_round_robin|cluster_flow\n"); -#endif /* HAVE_PFRING */ -#ifdef HAVE_LIBCAP_NG - printf("\t--user : run suricata as this user after init\n"); - printf("\t--group : run suricata as this group after init\n"); -#endif /* HAVE_LIBCAP_NG */ - printf("\t--erf-in : process an ERF file\n"); -#ifdef HAVE_DAG - printf("\t--dag : process ERF records from DAG interface X, stream Y\n"); -#endif -#ifdef HAVE_NAPATECH - printf("\t--napatech : run Napatech Streams using the API\n"); -#endif -#ifdef BUILD_UNIX_SOCKET - printf("\t--unix-socket[=] : use unix socket to control suricata work\n"); -#endif -#ifdef HAVE_MPIPE - printf("\t--mpipe : run with tilegx mpipe interface(s)\n"); -#endif - printf("\t--set name=value : set a configuration value\n"); - printf("\n"); - printf("\nTo run the engine with default configuration on " - "interface eth0 with signature file \"signatures.rules\", run the " - "command as:\n\n%s -c suricata.yaml -s signatures.rules -i eth0 \n\n", - progname); -} - -void SCPrintBuildInfo(void) -{ - char *bits = "-bits"; - char *endian = "-endian"; - char features[2048] = ""; - char *tls = "pthread key"; - -#ifdef REVISION - printf("This is %s version %s (rev %s)\n", PROG_NAME, PROG_VER, xstr(REVISION)); -#elif defined RELEASE - printf("This is %s version %s RELEASE\n", PROG_NAME, PROG_VER); -#else - printf("This is %s version %s\n", PROG_NAME, PROG_VER); -#endif - -#ifdef DEBUG - strlcat(features, "DEBUG ", sizeof(features)); -#endif -#ifdef DEBUG_VALIDATION - strlcat(features, "DEBUG_VALIDATION ", sizeof(features)); -#endif -#ifdef UNITTESTS - strlcat(features, "UNITTESTS ", sizeof(features)); -#endif -#ifdef NFQ - strlcat(features, "NFQ ", sizeof(features)); -#endif -#ifdef IPFW - strlcat(features, "IPFW ", sizeof(features)); -#endif -#ifdef HAVE_PCAP_SET_BUFF - strlcat(features, "PCAP_SET_BUFF ", sizeof(features)); -#endif -#if LIBPCAP_VERSION_MAJOR == 1 - strlcat(features, "LIBPCAP_VERSION_MAJOR=1 ", sizeof(features)); -#elif LIBPCAP_VERSION_MAJOR == 0 - strlcat(features, "LIBPCAP_VERSION_MAJOR=0 ", sizeof(features)); -#endif -#ifdef __SC_CUDA_SUPPORT__ - strlcat(features, "CUDA ", sizeof(features)); -#endif -#ifdef HAVE_PFRING - strlcat(features, "PF_RING ", sizeof(features)); -#endif -#ifdef HAVE_AF_PACKET - strlcat(features, "AF_PACKET ", sizeof(features)); -#endif -#ifdef HAVE_NETMAP - strlcat(features, "NETMAP ", sizeof(features)); -#endif -#ifdef HAVE_PACKET_FANOUT - strlcat(features, "HAVE_PACKET_FANOUT ", sizeof(features)); -#endif -#ifdef HAVE_DAG - strlcat(features, "DAG ", sizeof(features)); -#endif -#ifdef HAVE_LIBCAP_NG - strlcat(features, "LIBCAP_NG ", sizeof(features)); -#endif -#ifdef HAVE_LIBNET11 - strlcat(features, "LIBNET1.1 ", sizeof(features)); -#endif -#ifdef HAVE_HTP_URI_NORMALIZE_HOOK - strlcat(features, "HAVE_HTP_URI_NORMALIZE_HOOK ", sizeof(features)); -#endif -#ifdef PCRE_HAVE_JIT - strlcat(features, "PCRE_JIT ", sizeof(features)); -#endif -#ifdef HAVE_NSS - strlcat(features, "HAVE_NSS ", sizeof(features)); -#endif -#ifdef HAVE_LUA - strlcat(features, "HAVE_LUA ", sizeof(features)); -#endif -#ifdef HAVE_LUAJIT - strlcat(features, "HAVE_LUAJIT ", sizeof(features)); -#endif -#ifdef HAVE_LIBJANSSON - strlcat(features, "HAVE_LIBJANSSON ", sizeof(features)); -#endif -#ifdef PROFILING - strlcat(features, "PROFILING ", sizeof(features)); -#endif -#ifdef PROFILE_LOCKING - strlcat(features, "PROFILE_LOCKING ", sizeof(features)); -#endif -#ifdef TLS - strlcat(features, "TLS ", sizeof(features)); -#endif - if (strlen(features) == 0) { - strlcat(features, "none", sizeof(features)); - } - - printf("Features: %s\n", features); - - /* SIMD stuff */ - memset(features, 0x00, sizeof(features)); -#if defined(__SSE4_2__) - strlcat(features, "SSE_4_2 ", sizeof(features)); -#endif -#if defined(__SSE4_1__) - strlcat(features, "SSE_4_1 ", sizeof(features)); -#endif -#if defined(__SSE3__) - strlcat(features, "SSE_3 ", sizeof(features)); -#endif -#if defined(__tile__) - strlcat(features, "Tilera ", sizeof(features)); -#endif - if (strlen(features) == 0) { - strlcat(features, "none", sizeof(features)); - } - printf("SIMD support: %s\n", features); - - /* atomics stuff */ - memset(features, 0x00, sizeof(features)); -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) - strlcat(features, "1 ", sizeof(features)); -#endif -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) - strlcat(features, "2 ", sizeof(features)); -#endif -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) - strlcat(features, "4 ", sizeof(features)); -#endif -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) - strlcat(features, "8 ", sizeof(features)); -#endif -#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) - strlcat(features, "16 ", sizeof(features)); -#endif - if (strlen(features) == 0) { - strlcat(features, "none", sizeof(features)); - } else { - strlcat(features, "byte(s)", sizeof(features)); - } - printf("Atomic intrisics: %s\n", features); - -#if __WORDSIZE == 64 - bits = "64-bits"; -#elif __WORDSIZE == 32 - bits = "32-bits"; -#endif - -#if __BYTE_ORDER == __BIG_ENDIAN - endian = "Big-endian"; -#elif __BYTE_ORDER == __LITTLE_ENDIAN - endian = "Little-endian"; -#endif - - printf("%s, %s architecture\n", bits, endian); -#ifdef __GNUC__ - printf("GCC version %s, C version %"PRIiMAX"\n", __VERSION__, (intmax_t)__STDC_VERSION__); -#else - printf("C version %"PRIiMAX"\n", (intmax_t)__STDC_VERSION__); -#endif - -#if __SSP__ == 1 - printf("compiled with -fstack-protector\n"); -#endif -#if __SSP_ALL__ == 2 - printf("compiled with -fstack-protector-all\n"); -#endif -#ifdef _FORTIFY_SOURCE - printf("compiled with _FORTIFY_SOURCE=%d\n", _FORTIFY_SOURCE); -#endif -#ifdef CLS - printf("L1 cache line size (CLS)=%d\n", CLS); -#endif -#ifdef TLS - tls = "__thread"; -#endif - printf("thread local storage method: %s\n", tls); - - printf("compiled with %s, linked against %s\n", - HTP_VERSION_STRING_FULL, htp_get_version()); - printf("\n"); -#include "build-info.h" -} - -int coverage_unittests; -int g_ut_modules; -int g_ut_covered; - -void RegisterAllModules() -{ - /* commanders */ - TmModuleUnixManagerRegister(); - /* managers */ - TmModuleFlowManagerRegister(); - TmModuleFlowRecyclerRegister(); - /* nfq */ - TmModuleReceiveNFQRegister(); - TmModuleVerdictNFQRegister(); - TmModuleDecodeNFQRegister(); - /* ipfw */ - TmModuleReceiveIPFWRegister(); - TmModuleVerdictIPFWRegister(); - TmModuleDecodeIPFWRegister(); - /* pcap live */ - TmModuleReceivePcapRegister(); - TmModuleDecodePcapRegister(); - /* pcap file */ - TmModuleReceivePcapFileRegister(); - TmModuleDecodePcapFileRegister(); -#ifdef HAVE_MPIPE - /* mpipe */ - TmModuleReceiveMpipeRegister(); - TmModuleDecodeMpipeRegister(); -#endif - /* af-packet */ - TmModuleReceiveAFPRegister(); - TmModuleDecodeAFPRegister(); - /* netmap */ - TmModuleReceiveNetmapRegister(); - TmModuleDecodeNetmapRegister(); - /* pfring */ - TmModuleReceivePfringRegister(); - TmModuleDecodePfringRegister(); - /* dag file */ - TmModuleReceiveErfFileRegister(); - TmModuleDecodeErfFileRegister(); - /* dag live */ - TmModuleReceiveErfDagRegister(); - TmModuleDecodeErfDagRegister(); - /* napatech */ - TmModuleNapatechStreamRegister(); - TmModuleNapatechDecodeRegister(); - - /* stream engine */ - TmModuleStreamTcpRegister(); - /* detection */ - TmModuleDetectRegister(); - /* respond-reject */ - TmModuleRespondRejectRegister(); - - TmModuleLuaLogRegister(); - /* fast log */ - TmModuleAlertFastLogRegister(); - /* debug log */ - TmModuleAlertDebugLogRegister(); - /* prelue log */ - TmModuleAlertPreludeRegister(); - /* syslog log */ - TmModuleAlertSyslogRegister(); - /* unified2 log */ - TmModuleUnified2AlertRegister(); - /* drop log */ - TmModuleLogDropLogRegister(); - TmModuleJsonDropLogRegister(); - /* json log */ - TmModuleOutputJsonRegister(); - /* email logs */ - TmModuleJsonSmtpLogRegister(); - /* http log */ - TmModuleLogHttpLogRegister(); - TmModuleJsonHttpLogRegister(); - /* tls log */ - TmModuleLogTlsLogRegister(); - TmModuleJsonTlsLogRegister(); - TmModuleLogTlsStoreRegister(); - /* ssh */ - TmModuleJsonSshLogRegister(); - /* pcap log */ - TmModulePcapLogRegister(); - /* file log */ - TmModuleLogFileLogRegister(); - TmModuleJsonFileLogRegister(); - TmModuleLogFilestoreRegister(); - /* dns log */ - TmModuleLogDnsLogRegister(); - TmModuleJsonDnsLogRegister(); - /* tcp streaming data */ - TmModuleLogTcpDataLogRegister(); - /* log stats */ - TmModuleLogStatsLogRegister(); - - TmModuleJsonAlertLogRegister(); - /* flow/netflow */ - TmModuleJsonFlowLogRegister(); - TmModuleJsonNetFlowLogRegister(); - /* json stats */ - TmModuleJsonStatsLogRegister(); - - /* Template JSON logger. */ - TmModuleJsonTemplateLogRegister(); - - /* log api */ - TmModulePacketLoggerRegister(); - TmModuleTxLoggerRegister(); - TmModuleFileLoggerRegister(); - TmModuleFiledataLoggerRegister(); - TmModuleStreamingLoggerRegister(); - TmModuleStatsLoggerRegister(); - TmModuleDebugList(); - /* nflog */ - TmModuleReceiveNFLOGRegister(); - TmModuleDecodeNFLOGRegister(); - -} - -TmEcode LoadYamlConfig(char *conf_filename) -{ - SCEnter(); - - if (conf_filename == NULL) - SCReturnInt(TM_ECODE_OK); - - if (ConfYamlLoadFile(conf_filename) != 0) { - /* Error already displayed. */ - SCReturnInt(TM_ECODE_FAILED); - } - - SCReturnInt(TM_ECODE_OK); -} - -static TmEcode ParseInterfacesList(int run_mode, char *pcap_dev) -{ - SCEnter(); - - /* run the selected runmode */ - if (run_mode == RUNMODE_PCAP_DEV) { - if (strlen(pcap_dev) == 0) { - int ret = LiveBuildDeviceList("pcap"); - if (ret == 0) { - SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for pcap"); - SCReturnInt(TM_ECODE_FAILED); - } - } -#ifdef HAVE_MPIPE - } else if (run_mode == RUNMODE_TILERA_MPIPE) { - if (strlen(pcap_dev)) { - if (ConfSetFinal("mpipe.single_mpipe_dev", pcap_dev) != 1) { - fprintf(stderr, "ERROR: Failed to set mpipe.single_mpipe_dev\n"); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - int ret = LiveBuildDeviceList("mpipe.inputs"); - if (ret == 0) { - fprintf(stderr, "ERROR: No interface found in config for mpipe\n"); - SCReturnInt(TM_ECODE_FAILED); - } - } -#endif - } else if (run_mode == RUNMODE_PFRING) { - /* FIXME add backward compat support */ - /* iface has been set on command line */ - if (strlen(pcap_dev)) { - if (ConfSetFinal("pfring.live-interface", pcap_dev) != 1) { - SCLogError(SC_ERR_INITIALIZATION, "Failed to set pfring.live-interface"); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - /* not an error condition if we have a 1.0 config */ - LiveBuildDeviceList("pfring"); - } - } else if (run_mode == RUNMODE_AFP_DEV) { - /* iface has been set on command line */ - if (strlen(pcap_dev)) { - if (ConfSetFinal("af-packet.live-interface", pcap_dev) != 1) { - SCLogError(SC_ERR_INITIALIZATION, "Failed to set af-packet.live-interface"); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - int ret = LiveBuildDeviceList("af-packet"); - if (ret == 0) { - SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for af-packet"); - SCReturnInt(TM_ECODE_FAILED); - } - if (AFPRunModeIsIPS()) { - SCLogInfo("AF_PACKET: Setting IPS mode"); - EngineModeSetIPS(); - } - } -#ifdef HAVE_NETMAP - } else if (run_mode == RUNMODE_NETMAP) { - /* iface has been set on command line */ - if (strlen(pcap_dev)) { - if (ConfSetFinal("netmap.live-interface", pcap_dev) != 1) { - SCLogError(SC_ERR_INITIALIZATION, "Failed to set netmap.live-interface"); - SCReturnInt(TM_ECODE_FAILED); - } - } else { - int ret = LiveBuildDeviceList("netmap"); - if (ret == 0) { - SCLogError(SC_ERR_INITIALIZATION, "No interface found in config for netmap"); - SCReturnInt(TM_ECODE_FAILED); - } - if (NetmapRunModeIsIPS()) { - SCLogInfo("Netmap: Setting IPS mode"); - EngineModeSetIPS(); - } - } -#endif -#ifdef HAVE_NFLOG - } else if (run_mode == RUNMODE_NFLOG) { - int ret = LiveBuildDeviceListCustom("nflog", "group"); - if (ret == 0) { - SCLogError(SC_ERR_INITIALIZATION, "No group found in config for nflog"); - SCReturnInt(TM_ECODE_FAILED); - } -#endif - } - - SCReturnInt(TM_ECODE_OK); -} - -static void SCInstanceInit(SCInstance *suri) -{ - suri->run_mode = RUNMODE_UNKNOWN; - - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - suri->sig_file = NULL; - suri->sig_file_exclusive = FALSE; - suri->pid_filename = NULL; - suri->regex_arg = NULL; - - suri->keyword_info = NULL; - suri->runmode_custom_mode = NULL; -#ifndef OS_WIN32 - suri->user_name = NULL; - suri->group_name = NULL; - suri->do_setuid = FALSE; - suri->do_setgid = FALSE; - suri->userid = 0; - suri->groupid = 0; -#endif /* OS_WIN32 */ - suri->delayed_detect = 0; - suri->daemon = 0; - suri->offline = 0; - suri->verbose = 0; - /* use -1 as unknown */ - suri->checksum_validation = -1; -#if HAVE_DETECT_DISABLED==1 - g_detect_disabled = suri->disabled_detect = 1; -#else - g_detect_disabled = suri->disabled_detect = 0; -#endif -} - -static TmEcode PrintVersion() -{ -#ifdef REVISION - printf("This is %s version %s (rev %s)\n", PROG_NAME, PROG_VER, xstr(REVISION)); -#elif defined RELEASE - printf("This is %s version %s RELEASE\n", PROG_NAME, PROG_VER); -#else - printf("This is %s version %s\n", PROG_NAME, PROG_VER); -#endif - return TM_ECODE_OK; -} - -static TmEcode SCPrintVersion() -{ -#ifdef REVISION - SCLogNotice("This is %s version %s (rev %s)", PROG_NAME, PROG_VER, xstr(REVISION)); -#elif defined RELEASE - SCLogNotice("This is %s version %s RELEASE", PROG_NAME, PROG_VER); -#else - SCLogNotice("This is %s version %s", PROG_NAME, PROG_VER); -#endif - return TM_ECODE_OK; -} - -static void SCSetStartTime(SCInstance *suri) -{ - memset(&suri->start_time, 0, sizeof(suri->start_time)); - gettimeofday(&suri->start_time, NULL); -} - -static void SCPrintElapsedTime(SCInstance *suri) -{ - struct timeval end_time; - memset(&end_time, 0, sizeof(end_time)); - gettimeofday(&end_time, NULL); - uint64_t milliseconds = ((end_time.tv_sec - suri->start_time.tv_sec) * 1000) + - (((1000000 + end_time.tv_usec - suri->start_time.tv_usec) / 1000) - 1000); - SCLogInfo("time elapsed %.3fs", (float)milliseconds/(float)1000); -} - -static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) -{ - int opt; - - int dump_config = 0; - int list_app_layer_protocols = 0; - int list_unittests = 0; - int list_cuda_cards = 0; - int list_runmodes = 0; - int list_keywords = 0; - int build_info = 0; - int conf_test = 0; - int engine_analysis = 0; - int ret = TM_ECODE_OK; - -#ifdef UNITTESTS - coverage_unittests = 0; - g_ut_modules = 0; - g_ut_covered = 0; -#endif - - struct option long_opts[] = { - {"dump-config", 0, &dump_config, 1}, - {"pfring", optional_argument, 0, 0}, - {"pfring-int", required_argument, 0, 0}, - {"pfring-cluster-id", required_argument, 0, 0}, - {"pfring-cluster-type", required_argument, 0, 0}, - {"af-packet", optional_argument, 0, 0}, - {"netmap", optional_argument, 0, 0}, - {"pcap", optional_argument, 0, 0}, -#ifdef BUILD_UNIX_SOCKET - {"unix-socket", optional_argument, 0, 0}, -#endif - {"pcap-buffer-size", required_argument, 0, 0}, - {"unittest-filter", required_argument, 0, 'U'}, - {"list-app-layer-protos", 0, &list_app_layer_protocols, 1}, - {"list-unittests", 0, &list_unittests, 1}, - {"list-cuda-cards", 0, &list_cuda_cards, 1}, - {"list-runmodes", 0, &list_runmodes, 1}, - {"list-keywords", optional_argument, &list_keywords, 1}, - {"runmode", required_argument, NULL, 0}, - {"engine-analysis", 0, &engine_analysis, 1}, -#ifdef OS_WIN32 - {"service-install", 0, 0, 0}, - {"service-remove", 0, 0, 0}, - {"service-change-params", 0, 0, 0}, -#endif /* OS_WIN32 */ - {"pidfile", required_argument, 0, 0}, - {"init-errors-fatal", 0, 0, 0}, - {"disable-detection", 0, 0, 0}, - {"fatal-unittests", 0, 0, 0}, - {"unittests-coverage", 0, &coverage_unittests, 1}, - {"user", required_argument, 0, 0}, - {"group", required_argument, 0, 0}, - {"erf-in", required_argument, 0, 0}, - {"dag", required_argument, 0, 0}, - {"napatech", 0, 0, 0}, - {"build-info", 0, &build_info, 1}, -#ifdef HAVE_MPIPE - {"mpipe", optional_argument, 0, 0}, -#endif - {"set", required_argument, 0, 0}, -#ifdef HAVE_NFLOG - {"nflog", optional_argument, 0, 0}, -#endif - {NULL, 0, NULL, 0} - }; - - /* getopt_long stores the option index here. */ - int option_index = 0; - - char short_opts[] = "c:TDhi:l:q:d:r:us:S:U:VF:vk:"; - - while ((opt = getopt_long(argc, argv, short_opts, long_opts, &option_index)) != -1) { - switch (opt) { - case 0: - if (strcmp((long_opts[option_index]).name , "pfring") == 0 || - strcmp((long_opts[option_index]).name , "pfring-int") == 0) { -#ifdef HAVE_PFRING - suri->run_mode = RUNMODE_PFRING; - if (optarg != NULL) { - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - LiveRegisterDevice(optarg); - } -#else - SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure " - "to pass --enable-pfring to configure when building."); - return TM_ECODE_FAILED; -#endif /* HAVE_PFRING */ - } - else if(strcmp((long_opts[option_index]).name , "pfring-cluster-id") == 0){ -#ifdef HAVE_PFRING - if (ConfSetFinal("pfring.cluster-id", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set pfring.cluster-id.\n"); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure " - "to pass --enable-pfring to configure when building."); - return TM_ECODE_FAILED; -#endif /* HAVE_PFRING */ - } - else if(strcmp((long_opts[option_index]).name , "pfring-cluster-type") == 0){ -#ifdef HAVE_PFRING - if (ConfSetFinal("pfring.cluster-type", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set pfring.cluster-type.\n"); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_PF_RING,"PF_RING not enabled. Make sure " - "to pass --enable-pfring to configure when building."); - return TM_ECODE_FAILED; -#endif /* HAVE_PFRING */ - } - else if (strcmp((long_opts[option_index]).name , "af-packet") == 0){ -#ifdef HAVE_AF_PACKET - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_AFP_DEV; - if (optarg) { - LiveRegisterDevice(optarg); - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - } - } else if (suri->run_mode == RUNMODE_AFP_DEV) { - SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " - "multiple devices to get packets is experimental."); - if (optarg) { - LiveRegisterDevice(optarg); - } else { - SCLogInfo("Multiple af-packet option without interface on each is useless"); - break; - } - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_AF_PACKET,"AF_PACKET not enabled. On Linux " - "host, make sure to pass --enable-af-packet to " - "configure when building."); - return TM_ECODE_FAILED; -#endif - } else if (strcmp((long_opts[option_index]).name , "netmap") == 0){ -#ifdef HAVE_NETMAP - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_NETMAP; - if (optarg) { - LiveRegisterDevice(optarg); - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - } - } else if (suri->run_mode == RUNMODE_NETMAP) { - SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " - "multiple devices to get packets is experimental."); - if (optarg) { - LiveRegisterDevice(optarg); - } else { - SCLogInfo("Multiple netmap option without interface on each is useless"); - break; - } - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_NETMAP, "NETMAP not enabled."); - return TM_ECODE_FAILED; -#endif - } else if (strcmp((long_opts[option_index]).name, "nflog") == 0) { -#ifdef HAVE_NFLOG - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_NFLOG; - LiveBuildDeviceListCustom("nflog", "group"); - } -#else - SCLogError(SC_ERR_NFLOG_NOSUPPORT, "NFLOG not enabled."); - return TM_ECODE_FAILED; -#endif /* HAVE_NFLOG */ - } else if (strcmp((long_opts[option_index]).name , "pcap") == 0) { - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_PCAP_DEV; - if (optarg) { - LiveRegisterDevice(optarg); - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - } - } else if (suri->run_mode == RUNMODE_PCAP_DEV) { -#ifdef OS_WIN32 - SCLogError(SC_ERR_PCAP_MULTI_DEV_NO_SUPPORT, "pcap multi dev " - "support is not (yet) supported on Windows."); - return TM_ECODE_FAILED; -#else - SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " - "multiple pcap devices to get packets is experimental."); - LiveRegisterDevice(optarg); -#endif - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } - } else if(strcmp((long_opts[option_index]).name, "init-errors-fatal") == 0) { - if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) { - fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n"); - return TM_ECODE_FAILED; - } -#ifdef BUILD_UNIX_SOCKET - } else if (strcmp((long_opts[option_index]).name , "unix-socket") == 0) { - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_UNIX_SOCKET; - if (optarg) { - if (ConfSetFinal("unix-command.filename", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set unix-command.filename.\n"); - return TM_ECODE_FAILED; - } - - } - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#endif - } - else if(strcmp((long_opts[option_index]).name, "list-app-layer-protocols") == 0) { - /* listing all supported app layer protocols */ - } - else if(strcmp((long_opts[option_index]).name, "list-unittests") == 0) { -#ifdef UNITTESTS - suri->run_mode = RUNMODE_LIST_UNITTEST; -#else - fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n"); - return TM_ECODE_FAILED; -#endif /* UNITTESTS */ - } else if(strcmp((long_opts[option_index]).name, "list-cuda-cards") == 0) { -#ifndef __SC_CUDA_SUPPORT__ - fprintf(stderr, "ERROR: Cuda not enabled. Make sure to pass " - "--enable-cuda to configure when building.\n"); - return TM_ECODE_FAILED; -#endif /* UNITTESTS */ - } else if (strcmp((long_opts[option_index]).name, "list-runmodes") == 0) { - suri->run_mode = RUNMODE_LIST_RUNMODES; - return TM_ECODE_OK; - } else if (strcmp((long_opts[option_index]).name, "list-keywords") == 0) { - if (optarg) { - if (strcmp("short",optarg)) { - suri->keyword_info = optarg; - } - } - } else if (strcmp((long_opts[option_index]).name, "runmode") == 0) { - suri->runmode_custom_mode = optarg; - } else if(strcmp((long_opts[option_index]).name, "engine-analysis") == 0) { - // do nothing for now - } -#ifdef OS_WIN32 - else if(strcmp((long_opts[option_index]).name, "service-install") == 0) { - suri->run_mode = RUNMODE_INSTALL_SERVICE; - return TM_ECODE_OK; - } - else if(strcmp((long_opts[option_index]).name, "service-remove") == 0) { - suri->run_mode = RUNMODE_REMOVE_SERVICE; - return TM_ECODE_OK; - } - else if(strcmp((long_opts[option_index]).name, "service-change-params") == 0) { - suri->run_mode = RUNMODE_CHANGE_SERVICE_PARAMS; - return TM_ECODE_OK; - } -#endif /* OS_WIN32 */ - else if(strcmp((long_opts[option_index]).name, "pidfile") == 0) { - suri->pid_filename = optarg; - } - else if(strcmp((long_opts[option_index]).name, "disable-detection") == 0) { - g_detect_disabled = suri->disabled_detect = 1; - SCLogInfo("detection engine disabled"); - } - else if(strcmp((long_opts[option_index]).name, "fatal-unittests") == 0) { -#ifdef UNITTESTS - if (ConfSetFinal("unittests.failure-fatal", "1") != 1) { - fprintf(stderr, "ERROR: Failed to set unittests failure-fatal.\n"); - return TM_ECODE_FAILED; - } -#else - fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n"); - return TM_ECODE_FAILED; -#endif /* UNITTESTS */ - } - else if(strcmp((long_opts[option_index]).name, "user") == 0) { -#ifndef HAVE_LIBCAP_NG - SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to" - " drop privileges, but it was not compiled into Suricata."); - return TM_ECODE_FAILED; -#else - suri->user_name = optarg; - suri->do_setuid = TRUE; -#endif /* HAVE_LIBCAP_NG */ - } - else if(strcmp((long_opts[option_index]).name, "group") == 0) { -#ifndef HAVE_LIBCAP_NG - SCLogError(SC_ERR_LIBCAP_NG_REQUIRED, "libcap-ng is required to" - " drop privileges, but it was not compiled into Suricata."); - return TM_ECODE_FAILED; -#else - suri->group_name = optarg; - suri->do_setgid = TRUE; -#endif /* HAVE_LIBCAP_NG */ - } - else if (strcmp((long_opts[option_index]).name, "erf-in") == 0) { - suri->run_mode = RUNMODE_ERF_FILE; - if (ConfSetFinal("erf-file.file", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set erf-file.file\n"); - return TM_ECODE_FAILED; - } - } - else if (strcmp((long_opts[option_index]).name, "dag") == 0) { -#ifdef HAVE_DAG - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_DAG; - } - else if (suri->run_mode != RUNMODE_DAG) { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, - "more than one run mode has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } - LiveRegisterDevice(optarg); -#else - SCLogError(SC_ERR_DAG_REQUIRED, "libdag and a DAG card are required" - " to receieve packets using --dag."); - return TM_ECODE_FAILED; -#endif /* HAVE_DAG */ - } - else if (strcmp((long_opts[option_index]).name, "napatech") == 0) { -#ifdef HAVE_NAPATECH - suri->run_mode = RUNMODE_NAPATECH; -#else - SCLogError(SC_ERR_NAPATECH_REQUIRED, "libntapi and a Napatech adapter are required" - " to capture packets using --napatech."); - return TM_ECODE_FAILED; -#endif /* HAVE_NAPATECH */ - } - else if(strcmp((long_opts[option_index]).name, "pcap-buffer-size") == 0) { -#ifdef HAVE_PCAP_SET_BUFF - if (ConfSetFinal("pcap.buffer-size", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set pcap-buffer-size.\n"); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NO_PCAP_SET_BUFFER_SIZE, "The version of libpcap you have" - " doesn't support setting buffer size."); -#endif /* HAVE_PCAP_SET_BUFF */ - } - else if(strcmp((long_opts[option_index]).name, "build-info") == 0) { - suri->run_mode = RUNMODE_PRINT_BUILDINFO; - return TM_ECODE_OK; - } -#ifdef HAVE_MPIPE - else if(strcmp((long_opts[option_index]).name , "mpipe") == 0) { - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_TILERA_MPIPE; - if (optarg != NULL) { - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - strlcpy(suri->pcap_dev, optarg, - ((strlen(optarg) < sizeof(suri->pcap_dev)) ? - (strlen(optarg) + 1) : sizeof(suri->pcap_dev))); - LiveRegisterDevice(optarg); - } - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, - "more than one run mode has been specified"); - usage(argv[0]); - exit(EXIT_FAILURE); - } - } -#endif - else if (strcmp((long_opts[option_index]).name, "set") == 0) { - if (optarg != NULL) { - /* Quick validation. */ - char *val = strchr(optarg, '='); - if (val == NULL) { - SCLogError(SC_ERR_CMD_LINE, - "Invalid argument for --set, must be key=val."); - exit(EXIT_FAILURE); - } - if (!ConfSetFromString(optarg, 1)) { - fprintf(stderr, "Failed to set configuration value %s.", - optarg); - exit(EXIT_FAILURE); - } - } - } - break; - case 'c': - conf_filename = optarg; - break; - case 'T': - SCLogInfo("Running suricata under test mode"); - conf_test = 1; - if (ConfSetFinal("engine.init-failure-fatal", "1") != 1) { - fprintf(stderr, "ERROR: Failed to set engine init-failure-fatal.\n"); - return TM_ECODE_FAILED; - } - break; -#ifndef OS_WIN32 - case 'D': - suri->daemon = 1; - break; -#endif /* OS_WIN32 */ - case 'h': - suri->run_mode = RUNMODE_PRINT_USAGE; - return TM_ECODE_OK; - case 'i': - memset(suri->pcap_dev, 0, sizeof(suri->pcap_dev)); - - if (optarg == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -i"); - return TM_ECODE_FAILED; - } - - /* some windows shells require escaping of the \ in \Device. Otherwise - * the backslashes are stripped. We put them back here. */ - if (strlen(optarg) > 9 && strncmp(optarg, "DeviceNPF", 9) == 0) { - snprintf(suri->pcap_dev, sizeof(suri->pcap_dev), "\\Device\\NPF%s", optarg+9); - } else { - strlcpy(suri->pcap_dev, optarg, ((strlen(optarg) < sizeof(suri->pcap_dev)) ? (strlen(optarg)+1) : (sizeof(suri->pcap_dev)))); - PcapTranslateIPToDevice(suri->pcap_dev, sizeof(suri->pcap_dev)); - } - - if (strcmp(suri->pcap_dev, optarg) != 0) { - SCLogInfo("translated %s to pcap device %s", optarg, suri->pcap_dev); - } else if (strlen(suri->pcap_dev) > 0 && isdigit((unsigned char)suri->pcap_dev[0])) { - SCLogError(SC_ERR_PCAP_TRANSLATE, "failed to find a pcap device for IP %s", optarg); - return TM_ECODE_FAILED; - } - - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_PCAP_DEV; - LiveRegisterDevice(suri->pcap_dev); - } else if (suri->run_mode == RUNMODE_PCAP_DEV) { -#ifdef OS_WIN32 - SCLogError(SC_ERR_PCAP_MULTI_DEV_NO_SUPPORT, "pcap multi dev " - "support is not (yet) supported on Windows."); - return TM_ECODE_FAILED; -#else - SCLogWarning(SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, "using " - "multiple pcap devices to get packets is experimental."); - LiveRegisterDevice(suri->pcap_dev); -#endif - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } - break; - case 'l': - if (optarg == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -l"); - return TM_ECODE_FAILED; - } - - if (ConfigSetLogDirectory(optarg) != TM_ECODE_OK) { - SCLogError(SC_ERR_FATAL, "Failed to set log directory.\n"); - return TM_ECODE_FAILED; - } - if (ConfigCheckLogDirectory(optarg) != TM_ECODE_OK) { - SCLogError(SC_ERR_LOGDIR_CMDLINE, "The logging directory \"%s\"" - " supplied at the commandline (-l %s) doesn't " - "exist. Shutting down the engine.", optarg, optarg); - return TM_ECODE_FAILED; - } - break; - case 'q': -#ifdef NFQ - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_NFQ; - EngineModeSetIPS(); - if (NFQRegisterQueue(optarg) == -1) - return TM_ECODE_FAILED; - } else if (suri->run_mode == RUNMODE_NFQ) { - if (NFQRegisterQueue(optarg) == -1) - return TM_ECODE_FAILED; - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_NFQ_NOSUPPORT,"NFQUEUE not enabled. Make sure to pass --enable-nfqueue to configure when building."); - return TM_ECODE_FAILED; -#endif /* NFQ */ - break; - case 'd': -#ifdef IPFW - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_IPFW; - EngineModeSetIPS(); - if (IPFWRegisterQueue(optarg) == -1) - return TM_ECODE_FAILED; - } else if (suri->run_mode == RUNMODE_IPFW) { - if (IPFWRegisterQueue(optarg) == -1) - return TM_ECODE_FAILED; - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - SCLogError(SC_ERR_IPFW_NOSUPPORT,"IPFW not enabled. Make sure to pass --enable-ipfw to configure when building."); - return TM_ECODE_FAILED; -#endif /* IPFW */ - break; - case 'r': - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_PCAP_FILE; - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode " - "has been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } - if (ConfSetFinal("pcap-file.file", optarg) != 1) { - fprintf(stderr, "ERROR: Failed to set pcap-file.file\n"); - return TM_ECODE_FAILED; - } - break; - case 's': - if (suri->sig_file != NULL) { - SCLogError(SC_ERR_CMD_LINE, "can't have multiple -s options or mix -s and -S."); - return TM_ECODE_FAILED; - } - suri->sig_file = optarg; - break; - case 'S': - if (suri->sig_file != NULL) { - SCLogError(SC_ERR_CMD_LINE, "can't have multiple -S options or mix -s and -S."); - return TM_ECODE_FAILED; - } - suri->sig_file = optarg; - suri->sig_file_exclusive = TRUE; - break; - case 'u': -#ifdef UNITTESTS - if (suri->run_mode == RUNMODE_UNKNOWN) { - suri->run_mode = RUNMODE_UNITTEST; - } else { - SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode has" - " been specified"); - usage(argv[0]); - return TM_ECODE_FAILED; - } -#else - fprintf(stderr, "ERROR: Unit tests not enabled. Make sure to pass --enable-unittests to configure when building.\n"); - return TM_ECODE_FAILED; -#endif /* UNITTESTS */ - break; - case 'U': -#ifdef UNITTESTS - suri->regex_arg = optarg; - - if(strlen(suri->regex_arg) == 0) - suri->regex_arg = NULL; -#endif - break; - case 'V': - suri->run_mode = RUNMODE_PRINT_VERSION; - return TM_ECODE_OK; - case 'F': - if (optarg == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -F"); - return TM_ECODE_FAILED; - } - - SetBpfStringFromFile(optarg); - break; - case 'v': - suri->verbose++; - break; - case 'k': - if (optarg == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "no option argument (optarg) for -k"); - return TM_ECODE_FAILED; - } - if (!strcmp("all", optarg)) - suri->checksum_validation = 1; - else if (!strcmp("none", optarg)) - suri->checksum_validation = 0; - else { - SCLogError(SC_ERR_INITIALIZATION, "option '%s' invalid for -k", optarg); - return TM_ECODE_FAILED; - } - break; - default: - usage(argv[0]); - return TM_ECODE_FAILED; - } - } - - if (suri->disabled_detect && suri->sig_file != NULL) { - SCLogError(SC_ERR_INITIALIZATION, "can't use -s/-S when detection is disabled"); - return TM_ECODE_FAILED; - } - - if (list_app_layer_protocols) - suri->run_mode = RUNMODE_LIST_APP_LAYERS; - if (list_cuda_cards) - suri->run_mode = RUNMODE_LIST_CUDA_CARDS; - if (list_keywords) - suri->run_mode = RUNMODE_LIST_KEYWORDS; - if (list_unittests) - suri->run_mode = RUNMODE_LIST_UNITTEST; - if (dump_config) - suri->run_mode = RUNMODE_DUMP_CONFIG; - if (conf_test) - suri->run_mode = RUNMODE_CONF_TEST; - if (engine_analysis) - suri->run_mode = RUNMODE_ENGINE_ANALYSIS; - - ret = SetBpfString(optind, argv); - if (ret != TM_ECODE_OK) - return ret; - - return TM_ECODE_OK; -} - -#ifdef OS_WIN32 -static int WindowsInitService(int argc, char **argv) -{ - if (SCRunningAsService()) { - char path[MAX_PATH]; - char *p = NULL; - strlcpy(path, argv[0], MAX_PATH); - if ((p = strrchr(path, '\\'))) { - *p = '\0'; - } - if (!SetCurrentDirectory(path)) { - SCLogError(SC_ERR_FATAL, "Can't set current directory to: %s", path); - return -1; - } - SCLogInfo("Current directory is set to: %s", path); - daemon = 1; - SCServiceInit(argc, argv); - } - - /* Windows socket subsystem initialization */ - WSADATA wsaData; - if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData)) { - SCLogError(SC_ERR_FATAL, "Can't initialize Windows sockets: %d", WSAGetLastError()); - return -1; - } - - return 0; -} -#endif /* OS_WIN32 */ - -static int MayDaemonize(SCInstance *suri) -{ - if (suri->daemon == 1 && suri->pid_filename == NULL) { - if (ConfGet("pid-file", &suri->pid_filename) == 1) { - SCLogInfo("Use pid file %s from config file.", suri->pid_filename); - } else { - suri->pid_filename = DEFAULT_PID_FILENAME; - } - } - - if (suri->pid_filename != NULL && SCPidfileTestRunning(suri->pid_filename) != 0) { - suri->pid_filename = NULL; - return TM_ECODE_FAILED; - } - - if (suri->daemon == 1) { - Daemonize(); - } - - if (suri->pid_filename != NULL) { - if (SCPidfileCreate(suri->pid_filename) != 0) { - suri->pid_filename = NULL; - SCLogError(SC_ERR_PIDFILE_DAEMON, - "Unable to create PID file, concurrent run of" - " Suricata can occur."); - SCLogError(SC_ERR_PIDFILE_DAEMON, - "PID file creation WILL be mandatory for daemon mode" - " in future version"); - } - } - - return TM_ECODE_OK; -} - -static int InitSignalHandler(SCInstance *suri) -{ - /* registering signals we use */ - UtilSignalHandlerSetup(SIGINT, SignalHandlerSigint); - UtilSignalHandlerSetup(SIGTERM, SignalHandlerSigterm); - UtilSignalHandlerSetup(SIGPIPE, SIG_IGN); - UtilSignalHandlerSetup(SIGSYS, SIG_IGN); - -#ifndef OS_WIN32 - /* SIGHUP is not implemented on WIN32 */ - UtilSignalHandlerSetup(SIGHUP, SignalHandlerSigHup); - - /* Try to get user/group to run suricata as if - command line as not decide of that */ - if (suri->do_setuid == FALSE && suri->do_setgid == FALSE) { - char *id; - if (ConfGet("run-as.user", &id) == 1) { - suri->do_setuid = TRUE; - suri->user_name = id; - } - if (ConfGet("run-as.group", &id) == 1) { - suri->do_setgid = TRUE; - suri->group_name = id; - } - } - /* Get the suricata user ID to given user ID */ - if (suri->do_setuid == TRUE) { - if (SCGetUserID(suri->user_name, suri->group_name, - &suri->userid, &suri->groupid) != 0) { - SCLogError(SC_ERR_UID_FAILED, "failed in getting user ID"); - return TM_ECODE_FAILED; - } - - sc_set_caps = TRUE; - /* Get the suricata group ID to given group ID */ - } else if (suri->do_setgid == TRUE) { - if (SCGetGroupID(suri->group_name, &suri->groupid) != 0) { - SCLogError(SC_ERR_GID_FAILED, "failed in getting group ID"); - return TM_ECODE_FAILED; - } - - sc_set_caps = TRUE; - } -#endif /* OS_WIN32 */ - - return TM_ECODE_OK; -} - -int StartInternalRunMode(SCInstance *suri, int argc, char **argv) -{ - /* Treat internal running mode */ - switch(suri->run_mode) { - case RUNMODE_LIST_KEYWORDS: - ListKeywords(suri->keyword_info); - return TM_ECODE_DONE; - case RUNMODE_LIST_APP_LAYERS: - ListAppLayerProtocols(); - return TM_ECODE_DONE; - case RUNMODE_PRINT_VERSION: - PrintVersion(); - return TM_ECODE_DONE; - case RUNMODE_PRINT_BUILDINFO: - SCPrintBuildInfo(); - return TM_ECODE_DONE; - case RUNMODE_PRINT_USAGE: - usage(argv[0]); - return TM_ECODE_DONE; -#ifdef __SC_CUDA_SUPPORT__ - case RUNMODE_LIST_CUDA_CARDS: - return ListCudaCards(); -#endif - case RUNMODE_LIST_RUNMODES: - RunModeListRunmodes(); - return TM_ECODE_DONE; - case RUNMODE_LIST_UNITTEST: - RunUnittests(1, suri->regex_arg); -#ifdef OS_WIN32 - case RUNMODE_INSTALL_SERVICE: - if (SCServiceInstall(argc, argv)) { - return TM_ECODE_FAILED; - } - SCLogInfo("Suricata service has been successfuly installed."); - return TM_ECODE_DONE; - case RUNMODE_REMOVE_SERVICE: - if (SCServiceRemove(argc, argv)) { - return TM_ECODE_FAILED; - } - SCLogInfo("Suricata service has been successfuly removed."); - return TM_ECODE_DONE; - case RUNMODE_CHANGE_SERVICE_PARAMS: - if (SCServiceChangeParams(argc, argv)) { - return TM_ECODE_FAILED; - } - SCLogInfo("Suricata service startup parameters has been successfuly changed."); - return TM_ECODE_DONE; -#endif /* OS_WIN32 */ - default: - /* simply continue for other running mode */ - break; - } - return TM_ECODE_OK; -} - -static int FinalizeRunMode(SCInstance *suri, char **argv) -{ - switch (suri->run_mode) { - case RUNMODE_PCAP_FILE: - case RUNMODE_ERF_FILE: - case RUNMODE_ENGINE_ANALYSIS: - suri->offline = 1; - break; - case RUNMODE_UNKNOWN: - usage(argv[0]); - return TM_ECODE_FAILED; - } - /* Set the global run mode */ - run_mode = suri->run_mode; - - - return TM_ECODE_OK; -} - -static void SetupDelayedDetect(SCInstance *suri) -{ - /* In offline mode delayed init of detect is a bad idea */ - if (suri->offline) { - suri->delayed_detect = 0; - } else { - ConfNode *denode = NULL; - ConfNode *decnf = ConfGetNode("detect-engine"); - if (decnf != NULL) { - TAILQ_FOREACH(denode, &decnf->head, next) { - if (strcmp(denode->val, "delayed-detect") == 0) { - (void)ConfGetChildValueBool(denode, "delayed-detect", &suri->delayed_detect); - } - } - } - } - - SCLogInfo("Delayed detect %s", suri->delayed_detect ? "enabled" : "disabled"); - if (suri->delayed_detect) { - SCLogInfo("Packets will start being processed before signatures are active."); - } - -} - -static int LoadSignatures(DetectEngineCtx *de_ctx, SCInstance *suri) -{ - if (SigLoadSignatures(de_ctx, suri->sig_file, suri->sig_file_exclusive) < 0) { - SCLogError(SC_ERR_NO_RULES_LOADED, "Loading signatures failed."); - if (de_ctx->failure_fatal) - return TM_ECODE_FAILED; - } - - SCThresholdConfInitContext(de_ctx, NULL); - return TM_ECODE_OK; -} - -static int ConfigGetCaptureValue(SCInstance *suri) -{ - /* Pull the max pending packets from the config, if not found fall - * back on a sane default. */ - if (ConfGetInt("max-pending-packets", &max_pending_packets) != 1) - max_pending_packets = DEFAULT_MAX_PENDING_PACKETS; - if (max_pending_packets >= 65535) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "Maximum max-pending-packets setting is 65534. " - "Please check %s for errors", conf_filename); - return TM_ECODE_FAILED; - } - - SCLogDebug("Max pending packets set to %"PRIiMAX, max_pending_packets); - - /* Pull the default packet size from the config, if not found fall - * back on a sane default. */ - char *temp_default_packet_size; - if ((ConfGet("default-packet-size", &temp_default_packet_size)) != 1) { - int lthread; - int nlive; - switch (suri->run_mode) { - case RUNMODE_PCAP_DEV: - case RUNMODE_AFP_DEV: - case RUNMODE_NETMAP: - case RUNMODE_PFRING: - nlive = LiveGetDeviceCount(); - for (lthread = 0; lthread < nlive; lthread++) { - char *live_dev = LiveGetDeviceName(lthread); - unsigned int iface_max_packet_size = GetIfaceMaxPacketSize(live_dev); - if (iface_max_packet_size > default_packet_size) - default_packet_size = iface_max_packet_size; - } - if (default_packet_size) - break; - /* fall through */ - default: - default_packet_size = DEFAULT_PACKET_SIZE; - } - } else { - if (ParseSizeStringU32(temp_default_packet_size, &default_packet_size) < 0) { - SCLogError(SC_ERR_SIZE_PARSE, "Error parsing max-pending-packets " - "from conf file - %s. Killing engine", - temp_default_packet_size); - return TM_ECODE_FAILED; - } - } - - SCLogDebug("Default packet size set to %"PRIu32, default_packet_size); - - return TM_ECODE_OK; -} -/** - * This function is meant to contain code that needs - * to be run once the configuration has been loaded. - */ -static int PostConfLoadedSetup(SCInstance *suri) -{ - char *hostmode = NULL; - - /* load the pattern matchers */ - MpmTableSetup(); -#ifdef __SC_CUDA_SUPPORT__ - MpmCudaEnvironmentSetup(); -#endif - - switch (suri->checksum_validation) { - case 0: - ConfSet("stream.checksum-validation", "0"); - break; - case 1: - ConfSet("stream.checksum-validation", "1"); - break; - } - - AppLayerSetup(); - - /* Check for the existance of the default logging directory which we pick - * from suricata.yaml. If not found, shut the engine down */ - suri->log_dir = ConfigGetLogDirectory(); - - if (ConfigCheckLogDirectory(suri->log_dir) != TM_ECODE_OK) { - SCLogError(SC_ERR_LOGDIR_CONFIG, "The logging directory \"%s\" " - "supplied by %s (default-log-dir) doesn't exist. " - "Shutting down the engine", suri->log_dir, conf_filename); - SCReturnInt(TM_ECODE_FAILED); - } - - if (ConfigGetCaptureValue(suri) != TM_ECODE_OK) { - SCReturnInt(TM_ECODE_FAILED); - } - - if (ConfGet("host-mode", &hostmode) == 1) { - if (!strcmp(hostmode, "router")) { - host_mode = SURI_HOST_IS_ROUTER; - } else if (!strcmp(hostmode, "sniffer-only")) { - host_mode = SURI_HOST_IS_SNIFFER_ONLY; - } else { - if (strcmp(hostmode, "auto") != 0) { - WarnInvalidConfEntry("host-mode", "%s", "auto"); - } - if (EngineModeIsIPS()) { - host_mode = SURI_HOST_IS_ROUTER; - } else { - host_mode = SURI_HOST_IS_SNIFFER_ONLY; - } - } - } else { - if (EngineModeIsIPS()) { - host_mode = SURI_HOST_IS_ROUTER; - SCLogInfo("No 'host-mode': suricata is in IPS mode, using " - "default setting 'router'"); - } else { - host_mode = SURI_HOST_IS_SNIFFER_ONLY; - SCLogInfo("No 'host-mode': suricata is in IDS mode, using " - "default setting 'sniffer-only'"); - } - } - -#ifdef NFQ - if (suri->run_mode == RUNMODE_NFQ) - NFQInitConfig(FALSE); -#endif - - /* Load the Host-OS lookup. */ - SCHInfoLoadFromConfig(); - if (suri->run_mode != RUNMODE_UNIX_SOCKET) { - DefragInit(); - } - - if (suri->run_mode == RUNMODE_ENGINE_ANALYSIS) { - SCLogInfo("== Carrying out Engine Analysis =="); - char *temp = NULL; - if (ConfGet("engine-analysis", &temp) == 0) { - SCLogInfo("no engine-analysis parameter(s) defined in conf file. " - "Please define/enable them in the conf to use this " - "feature."); - SCReturnInt(TM_ECODE_FAILED); - } - } - - /* hardcoded initialization code */ - SigTableSetup(); /* load the rule keywords */ - TmqhSetup(); - - StorageInit(); - CIDRInit(); - SigParsePrepare(); -#ifdef PROFILING - if (suri->run_mode != RUNMODE_UNIX_SOCKET) { - SCProfilingRulesGlobalInit(); - SCProfilingKeywordsGlobalInit(); - SCProfilingInit(); - } -#endif /* PROFILING */ - SCReputationInitCtx(); - SCProtoNameInit(); - - TagInitCtx(); - ThresholdInit(); - HostBitInitCtx(); - IPPairBitInitCtx(); - - if (DetectAddressTestConfVars() < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "basic address vars test failed. Please check %s for errors", conf_filename); - SCReturnInt(TM_ECODE_FAILED); - } - if (DetectPortTestConfVars() < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "basic port vars test failed. Please check %s for errors", conf_filename); - SCReturnInt(TM_ECODE_FAILED); - } - - RegisterAllModules(); - - AppLayerHtpNeedFileInspection(); - - DetectEngineRegisterAppInspectionEngines(); - - if (suri->sig_file != NULL) - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2SigFileStartup); - else - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2StartingUp); - - StorageFinalize(); - - TmModuleRunInit(); - - PcapLogProfileSetup(); - SCReturnInt(TM_ECODE_OK); -} - -int main(int argc, char **argv) -{ - SCInstance suri; - - SCInstanceInit(&suri); - - sc_set_caps = FALSE; - - SC_ATOMIC_INIT(engine_stage); - - /* initialize the logging subsys */ - SCLogInitLogModule(NULL); - - if (SCSetThreadName("Suricata-Main") < 0) { - SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name"); - } - - ParseSizeInit(); - - RunModeRegisterRunModes(); - - /* By default use IDS mode, but if nfq or ipfw - * are specified, IPS mode will overwrite this */ - EngineModeSetIDS(); - - -#ifdef OS_WIN32 - /* service initialization */ - if (WindowsInit(argc, argv) != 0) { - exit(EXIT_FAILURE); - } -#endif /* OS_WIN32 */ - - /* Initialize the configuration module. */ - ConfInit(); - - if (ParseCommandLine(argc, argv, &suri) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - switch (StartInternalRunMode(&suri, argc, argv)) { - case TM_ECODE_DONE: - exit(EXIT_SUCCESS); - case TM_ECODE_FAILED: - exit(EXIT_FAILURE); - } - - if (FinalizeRunMode(&suri, argv) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - if (suri.run_mode == RUNMODE_UNITTEST) - RunUnittests(0, suri.regex_arg); - -#ifdef __SC_CUDA_SUPPORT__ - /* Init the CUDA environment */ - SCCudaInitCudaEnvironment(); - CudaBufferInit(); -#endif - - if (!CheckValidDaemonModes(suri.daemon, suri.run_mode)) { - exit(EXIT_FAILURE); - } - - /* Initializations for global vars, queues, etc (memsets, mutex init..) */ - GlobalInits(); - TimeInit(); - SupportFastPatternForSigMatchTypes(); - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - StatsInit(); - } - - if (conf_filename == NULL) - conf_filename = DEFAULT_CONF_FILE; - - /** \todo we need an api for these */ - /* Load yaml configuration file if provided. */ - if (LoadYamlConfig(conf_filename) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - if (suri.run_mode == RUNMODE_DUMP_CONFIG) { - ConfDump(); - exit(EXIT_SUCCESS); - } - - /* Since our config is now loaded we can finish configurating the - * logging module. */ - SCLogLoadConfig(suri.daemon, suri.verbose); - - SCPrintVersion(); - - UtilCpuPrintSummary(); - - if (ParseInterfacesList(suri.run_mode, suri.pcap_dev) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - if (PostConfLoadedSetup(&suri) != TM_ECODE_OK) { - exit(EXIT_FAILURE); - } - - if (MayDaemonize(&suri) != TM_ECODE_OK) - exit(EXIT_FAILURE); - - if (InitSignalHandler(&suri) != TM_ECODE_OK) - exit(EXIT_FAILURE); - -#ifdef HAVE_NSS - /* init NSS for md5 */ - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - NSS_NoDB_Init(NULL); -#endif - - if (suri.disabled_detect) { - /* disable raw reassembly */ - (void)ConfSetFinal("stream.reassembly.raw", "false"); - } - - HostInitConfig(HOST_VERBOSE); - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - FlowInitConfig(FLOW_VERBOSE); - StreamTcpInitConfig(STREAM_VERBOSE); - IPPairInitConfig(IPPAIR_VERBOSE); - AppLayerRegisterGlobalCounters(); - } - - if (MagicInit() != 0) - exit(EXIT_FAILURE); - - DetectEngineCtx *de_ctx = NULL; - if (!suri.disabled_detect) { - SCClassConfInit(); - SCReferenceConfInit(); - SetupDelayedDetect(&suri); - int mt_enabled = 0; - (void)ConfGetBool("multi-detect.enabled", &mt_enabled); - int default_tenant = 0; - if (mt_enabled) - (void)ConfGetBool("multi-detect.default", &default_tenant); - if (DetectEngineMultiTenantSetup() == -1) { - SCLogError(SC_ERR_INITIALIZATION, "initializing multi-detect " - "detection engine contexts failed."); - exit(EXIT_FAILURE); - } - if (suri.delayed_detect || (mt_enabled && !default_tenant)) { - de_ctx = DetectEngineCtxInitMinimal(); - } else { - de_ctx = DetectEngineCtxInit(); - } - if (de_ctx == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "initializing detection engine " - "context failed."); - exit(EXIT_FAILURE); - } - -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA) - CudaVarsSetDeCtx(de_ctx); -#endif /* __SC_CUDA_SUPPORT__ */ - - if (!de_ctx->minimal) { - if (LoadSignatures(de_ctx, &suri) != TM_ECODE_OK) - exit(EXIT_FAILURE); - if (suri.run_mode == RUNMODE_ENGINE_ANALYSIS) { - exit(EXIT_SUCCESS); - } - } - - DetectEngineAddToMaster(de_ctx); - } else { - /* tell the app layer to consider only the log id */ - RegisterAppLayerGetActiveTxIdFunc(AppLayerTransactionGetActiveLogOnly); - } - - SCAsn1LoadConfig(); - - CoredumpLoadConfig(); - - SCSetStartTime(&suri); - - SCDropMainThreadCaps(suri.userid, suri.groupid); - - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - RunModeInitializeOutputs(); - StatsSetupPostConfig(); - } - - if(suri.run_mode == RUNMODE_CONF_TEST){ - SCLogNotice("Configuration provided was successfully loaded. Exiting."); - exit(EXIT_SUCCESS); - } - - RunModeDispatch(suri.run_mode, suri.runmode_custom_mode); - - /* In Unix socket runmode, Flow manager is started on demand */ - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - /* Spawn the unix socket manager thread */ - int unix_socket = 0; - if (ConfGetBool("unix-command.enabled", &unix_socket) != 1) - unix_socket = 0; - if (unix_socket == 1) { - UnixManagerThreadSpawn(0); -#ifdef BUILD_UNIX_SOCKET - UnixManagerRegisterCommand("iface-stat", LiveDeviceIfaceStat, NULL, - UNIX_CMD_TAKE_ARGS); - UnixManagerRegisterCommand("iface-list", LiveDeviceIfaceList, NULL, 0); -#endif - } - /* Spawn the flow manager thread */ - FlowManagerThreadSpawn(); - FlowRecyclerThreadSpawn(); - StatsSpawnThreads(); - } - -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA) - SCACCudaStartDispatcher(); -#endif - - /* Check if the alloted queues have at least 1 reader and writer */ - TmValidateQueueState(); - - /* Wait till all the threads have been initialized */ - if (TmThreadWaitOnThreadInit() == TM_ECODE_FAILED) { - SCLogError(SC_ERR_INITIALIZATION, "Engine initialization failed, " - "aborting..."); - exit(EXIT_FAILURE); - } - - (void) SC_ATOMIC_CAS(&engine_stage, SURICATA_INIT, SURICATA_RUNTIME); - PacketPoolPostRunmodes(); - - /* Un-pause all the paused threads */ - TmThreadContinueThreads(); - /* registering singal handlers we use. We register usr2 here, so that one - * can't call it during the first sig load phase or while threads are still - * starting up. */ - if (DetectEngineEnabled() && suri.sig_file == NULL && - suri.delayed_detect == 0) - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2); - - if (suri.delayed_detect) { - /* force 'reload', this will load the rules and swap engines */ - DetectEngineReload(NULL, &suri); - - if (suri.sig_file != NULL) - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2SigFileStartup); - else - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2); - SCLogNotice("Signature(s) loaded, Detect thread(s) activated."); - } - - -#ifdef DBG_MEM_ALLOC - SCLogInfo("Memory used at startup: %"PRIdMAX, (intmax_t)global_mem); -#ifdef DBG_MEM_ALLOC_SKIP_STARTUP - print_mem_flag = 1; -#endif -#endif - - int engine_retval = EXIT_SUCCESS; - while(1) { - if (suricata_ctl_flags & (SURICATA_KILL | SURICATA_STOP)) { - SCLogNotice("Signal Received. Stopping engine."); - - break; - } - - TmThreadCheckThreadState(); - - if (sighup_count > 0) { - OutputNotifyFileRotation(); - sighup_count--; - } - - if (sigusr2_count > 0) { - DetectEngineReload(conf_filename, &suri); - sigusr2_count--; - } else if (DetectEngineReloadIsStart()) { - DetectEngineReload(conf_filename, &suri); - DetectEngineReloadSetDone(); - } - - usleep(10* 1000); - } - - /* Update the engine stage/status flag */ - (void) SC_ATOMIC_CAS(&engine_stage, SURICATA_RUNTIME, SURICATA_DEINIT); - - UnixSocketKillSocketThread(); - - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - /* First we need to disable the flow manager thread */ - FlowDisableFlowManagerThread(); - } - - - /* Disable packet acquisition first */ - TmThreadDisableReceiveThreads(); - - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - /* we need a packet pool for FlowForceReassembly */ - PacketPoolInit(); - - FlowForceReassembly(); - /* kill receive threads when they have processed all - * flow timeout packets */ - TmThreadDisablePacketThreads(); - } - - SCPrintElapsedTime(&suri); - - /* before TmThreadKillThreads, as otherwise that kills it - * but more slowly */ - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - FlowDisableFlowRecyclerThread(); - } - - /* kill remaining threads */ - TmThreadKillThreads(); - - - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - /* destroy the packet pool for flow reassembly after all - * the other threads are gone. */ - PacketPoolDestroy(); - - StatsReleaseResources(); - IPPairShutdown(); - FlowShutdown(); - StreamTcpFreeConfig(STREAM_VERBOSE); - } - HostShutdown(); - - HTPFreeConfig(); - HTPAtExitPrintStats(); - -#ifdef DBG_MEM_ALLOC - SCLogInfo("Total memory used (without SCFree()): %"PRIdMAX, (intmax_t)global_mem); -#ifdef DBG_MEM_ALLOC_SKIP_STARTUP - print_mem_flag = 0; -#endif -#endif - - SCPidfileRemove(suri.pid_filename); - - AppLayerHtpPrintStats(); - - /** TODO this can do into it's own func */ - de_ctx = DetectEngineGetCurrent(); - if (de_ctx) { - DetectEngineMoveToFreeList(de_ctx); - DetectEngineDeReference(&de_ctx); - } - DetectEnginePruneFreeList(); - - AppLayerDeSetup(); - - TagDestroyCtx(); - - LiveDeviceListClean(); - RunModeShutDown(); - OutputDeregisterAll(); - TimeDeinit(); - SCProtoNameDeInit(); - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - DefragDestroy(); - } - if (!suri.disabled_detect) { - SCReferenceConfDeinit(); - SCClassConfDeinit(); - } - MagicDeinit(); - TmqhCleanup(); - TmModuleRunDeInit(); - ParseSizeDeinit(); -#ifdef HAVE_NSS - NSS_Shutdown(); - PR_Cleanup(); -#endif - -#ifdef HAVE_AF_PACKET - AFPPeersListClean(); -#endif - -#ifdef PROFILING - if (suri.run_mode != RUNMODE_UNIX_SOCKET) { - if (profiling_rules_enabled) - SCProfilingDump(); - SCProfilingDestroy(); - } -#endif - -#ifdef OS_WIN32 - if (daemon) { - return 0; - } -#endif /* OS_WIN32 */ - - SC_ATOMIC_DESTROY(engine_stage); - -#ifdef __SC_CUDA_SUPPORT__ - if (PatternMatchDefaultMatcher() == MPM_AC_CUDA) - MpmCudaBufferDeSetup(); - CudaHandlerFreeProfiles(); -#endif - ConfDeInit(); - - exit(engine_retval); -} diff --git a/framework/src/suricata/src/suricata.h b/framework/src/suricata/src/suricata.h deleted file mode 100644 index b11239ac..00000000 --- a/framework/src/suricata/src/suricata.h +++ /dev/null @@ -1,197 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \mainpage Doxygen documentation - * - * \section intro_sec Introduction - * - * The Suricata Engine is an Open Source Next Generation Intrusion Detection - * and Prevention Engine. This engine is not intended to just replace or - * emulate the existing tools in the industry, but will bring new ideas and - * technologies to the field. - * - * \section dev_doc Developer documentation - * - * You've reach the automically generated documentation of Suricata. This - * document contains information about architecture and code structure. It - * is attended for developers wanting to understand or contribute to Suricata. - * - * \subsection modules Modules - * - * Documentation is generate from comments placed in all parts of the code. - * But you will also find some groups describing specific functional parts: - * - \ref decode - * - \ref httplayer - * - \ref sigstate - * - \ref threshold - * - * \section archi Architecture - * - * \subsection datastruct Data structures - * - * Regarding matching, there is three main data structures which are: - * - ::Packet: Data relative to an individual packet with information about - * linked structure such as the ::Flow the ::Packet belongs to. - * - ::Flow: Information about a flow for example a TCP session - * - ::StreamMsg: structure containing the reassembled data - * - * \subsection runmode Running mode - * - * Suricata is multithreaded and running modes define how the different - * threads are working together. You can see util-runmodes.c for example - * of running mode. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __SURICATA_H__ -#define __SURICATA_H__ - -#include "suricata-common.h" -#include "packet-queue.h" -#include "data-queue.h" - -/* the name of our binary */ -#define PROG_NAME "Suricata" -#define PROG_VER "3.0dev" - -/* workaround SPlint error (don't know __gnuc_va_list) */ -#ifdef S_SPLINT_S -# include -# define CONFIG_DIR "/etc/suricata" -#endif - -#define DEFAULT_CONF_FILE CONFIG_DIR "/suricata.yaml" - -#define DEFAULT_PID_DIR LOCAL_STATE_DIR "/run/" -#define DEFAULT_PID_BASENAME "suricata.pid" -#define DEFAULT_PID_FILENAME DEFAULT_PID_DIR DEFAULT_PID_BASENAME - -/* runtime engine control flags */ -#define SURICATA_STOP (1 << 0) /**< gracefully stop the engine: process all - outstanding packets first */ -#define SURICATA_KILL (1 << 1) /**< shut down asap, discarding outstanding - packets. */ -#define SURICATA_DONE (1 << 2) /**< packets capture ended */ - -/* Engine stage/status*/ -enum { - SURICATA_INIT = 0, - SURICATA_RUNTIME, - SURICATA_DEINIT -}; - -/* Engine is acting as */ -enum EngineMode { - ENGINE_MODE_IDS, - ENGINE_MODE_IPS, -}; - -void EngineModeSetIPS(void); -void EngineModeSetIDS(void); -int EngineModeIsIPS(void); -int EngineModeIsIDS(void); - -/* Box is acting as router */ -enum { - SURI_HOST_IS_SNIFFER_ONLY, - SURI_HOST_IS_ROUTER, -}; - -#define IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode) ((host_mode) == SURI_HOST_IS_SNIFFER_ONLY) -#define IS_SURI_HOST_MODE_ROUTER(host_mode) ((host_mode) == SURI_HOST_IS_ROUTER) - -/* queue's between various other threads - * XXX move to the TmQueue structure later - */ -PacketQueue trans_q[256]; - -SCDQDataQueue data_queues[256]; - -typedef struct SCInstance_ { - int run_mode; - - char pcap_dev[128]; - char *sig_file; - int sig_file_exclusive; - char *pid_filename; - char *regex_arg; - - char *keyword_info; - char *runmode_custom_mode; -#ifndef OS_WIN32 - char *user_name; - char *group_name; - uint8_t do_setuid; - uint8_t do_setgid; - uint32_t userid; - uint32_t groupid; -#endif /* OS_WIN32 */ - int delayed_detect; - int disabled_detect; - int daemon; - int offline; - int verbose; - int checksum_validation; - - struct timeval start_time; - - char *log_dir; -} SCInstance; - - -/* memset to zeros, and mutex init! */ -void GlobalInits(); - -extern volatile uint8_t suricata_ctl_flags; - -/* uppercase to lowercase conversion lookup table */ -uint8_t g_u8_lowercasetable[256]; - -extern char *conf_filename; - -/* marco to do the actual lookup */ -//#define u8_tolower(c) g_u8_lowercasetable[(c)] -// these 2 are slower: -//#define u8_tolower(c) ((c) >= 'A' && (c) <= 'Z') ? g_u8_lowercasetable[(c)] : (c) -//#define u8_tolower(c) (((c) >= 'A' && (c) <= 'Z') ? ((c) + ('a' - 'A')) : (c)) - -/* this is faster than the table lookup */ -#include -#define u8_tolower(c) tolower((uint8_t)(c)) - -void EngineStop(void); -void EngineKill(void); -void EngineDone(void); - -/* live rule swap required this to be made static */ -void SignalHandlerSigusr2(int); -void SignalHandlerSigusr2EngineShutdown(int); -void SignalHandlerSigusr2Idle(int sig); - -int RunmodeIsUnittests(void); -int RunmodeGetCurrent(void); -int IsRuleReloadSet(int quiet); - -extern int run_mode; - -#endif /* __SURICATA_H__ */ - diff --git a/framework/src/suricata/src/threads-arch-tile.h b/framework/src/suricata/src/threads-arch-tile.h deleted file mode 100644 index d022d90e..00000000 --- a/framework/src/suricata/src/threads-arch-tile.h +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (C) 2011-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ken Steele, Tilera Corporation - */ - -#ifndef __THREADS_ARCH_TILE_H__ -#define __THREADS_ARCH_TILE_H__ - -#include -#include - -/* NOTE: On Tilera datapath threads use the TMC (Tilera Multicore - * Components) library spin mutexes while the control threads use - * pthread mutexes. So the pthread mutex types are split out so that - * their use can be differentiated. - */ - -/* ctrl mutex */ -#define SCCtrlMutex pthread_mutex_t -#define SCCtrlMutexAttr pthread_mutexattr_t -#define SCCtrlMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr) -#define SCCtrlMutexLock(mut) pthread_mutex_lock(mut) -#define SCCtrlMutexTrylock(mut) pthread_mutex_trylock(mut) -#define SCCtrlMutexUnlock(mut) pthread_mutex_unlock(mut) -#define SCCtrlMutexDestroy pthread_mutex_destroy - -/* ctrl cond */ -#define SCCtrlCondT pthread_cond_t -#define SCCtrlCondInit pthread_cond_init -#define SCCtrlCondSignal pthread_cond_signal -#define SCCtrlCondTimedwait pthread_cond_timedwait -#define SCCtrlCondWait pthread_cond_wait -#define SCCtrlCondDestroy pthread_cond_destroy - -/* mutex */ - -#define SCMutex tmc_spin_queued_mutex_t -#define SCMutexAttr -#define SCMutexDestroy(x) ({ (void)(x); 0; }) -#define SCMUTEX_INITIALIZER TMC_SPIN_QUEUED_MUTEX_INIT -#define SCMutexInit(mut, mutattr) ({ \ - int ret = 0; \ - tmc_spin_queued_mutex_init(mut); \ - ret; \ -}) -#define SCMutexLock(mut) ({ \ - int ret = 0; \ - tmc_spin_queued_mutex_lock(mut); \ - ret; \ -}) -#define SCMutexTrylock(mut) ({ \ - int ret = (tmc_spin_queued_mutex_trylock(mut) == 0) ? 0 : EBUSY; \ - ret; \ -}) -#define SCMutexUnlock(mut) ({ \ - int ret = 0; \ - tmc_spin_queued_mutex_unlock(mut); \ - ret; \ -}) - -/* conditions */ - -/* Ignore signals when using spin locks */ -#define SCCondT uint8_t -#define SCCondInit(x,y) ({ 0; }) -#define SCCondSignal(x) ({ 0; }) -#define SCCondDestroy(x) ({ 0; }) - -static inline void cycle_sleep(int cycles) -{ - uint64_t end = get_cycle_count() + cycles; - while (get_cycle_count() < end) - ; -} -#define SCCondWait(x,y) cycle_sleep(300) - -/* spinlocks */ - -#define SCSpinlock tmc_spin_queued_mutex_t -#define SCSpinLock(spin) ({ tmc_spin_queued_mutex_lock(spin); 0; }) -#define SCSpinTrylock(spin) (tmc_spin_queued_mutex_trylock(spin) ? EBUSY : 0) -#define SCSpinUnlock(spin) ({ tmc_spin_queued_mutex_unlock(spin); 0; }) -#define SCSpinInit(spin, spin_attr) ({ tmc_spin_queued_mutex_init(spin); 0; }) -#define SCSpinDestroy(spin) ({ (void)(spin); 0; }) - -/* rwlocks */ - -#define SCRWLock tmc_spin_rwlock_t -#define SCRWLockDestroy(x) ({ (void)(x); 0; }) -#define SCRWLockInit(rwl, rwlattr ) ({ tmc_spin_rwlock_init(rwl); 0; }) -#define SCRWLockWRLock(rwl) ({ tmc_spin_rwlock_wrlock(rwl); 0; }) -#define SCRWLockRDLock(rwl) ({ tmc_spin_rwlock_rdlock(rwl); 0; }) -#define SCRWLockTryWRLock(rwl) (tmc_spin_rwlock_trywrlock(rwl) ? EBUSY : 0) -#define SCRWLockTryRDLock(rwl) (tmc_spin_rwlock_tryrdlock(rwl) ? EBUSY : 0) -#define SCRWLockUnlock(rwl) ({ tmc_spin_rwlock_unlock(rwl); 0; }) -#endif diff --git a/framework/src/suricata/src/threads-debug.h b/framework/src/suricata/src/threads-debug.h deleted file mode 100644 index 050e3056..00000000 --- a/framework/src/suricata/src/threads-debug.h +++ /dev/null @@ -1,389 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon Crespo - * - * Threading functions defined as macros: debug variants - */ - -#ifndef __THREADS_DEBUG_H__ -#define __THREADS_DEBUG_H__ - -/* mutex */ - -/** When dbg threads is defined, if a mutex fail to lock, it's - * initialized, logged, and does a second try; This is to prevent the system to freeze; - * It is for Mac OS X users; - * If you see a mutex, spinlock or condiion not initialized, report it please! - */ -#define SCMutexLock_dbg(mut) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") locking mutex %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut); \ - int retl = pthread_mutex_lock(mut); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") locked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retl); \ - if (retl != 0) { \ - switch (retl) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - retl = pthread_mutex_init(mut, NULL); \ - if (retl != 0) \ - exit(EXIT_FAILURE); \ - retl = pthread_mutex_lock(mut); \ - break; \ - case EDEADLK: \ - printf("A deadlock would occur if the thread blocked waiting for mutex\n"); \ - break; \ - } \ - } \ - retl; \ -}) - -#define SCMutexTrylock_dbg(mut) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocking mutex %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut); \ - int rett = pthread_mutex_trylock(mut); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, rett); \ - if (rett != 0) { \ - switch (rett) { \ - case EINVAL: \ - printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \ - break; \ - case EBUSY: \ - printf("Mutex is already locked\n"); \ - break; \ - } \ - } \ - rett; \ -}) - -#define SCMutexInit_dbg(mut, mutattr) ({ \ - int ret; \ - ret = pthread_mutex_init(mut, mutattr); \ - if (ret != 0) { \ - switch (ret) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") mutex %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, ret); \ - break; \ - case EAGAIN: \ - printf("The system temporarily lacks the resources to create another mutex\n"); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") mutex %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, ret); \ - break; \ - case ENOMEM: \ - printf("The process cannot allocate enough memory to create another mutex\n"); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") mutex %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, ret); \ - break; \ - } \ - } \ - ret; \ -}) - -#define SCMutexUnlock_dbg(mut) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocking mutex %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut); \ - int retu = pthread_mutex_unlock(mut); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retu); \ - if (retu != 0) { \ - switch (retu) { \ - case EINVAL: \ - printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \ - break; \ - case EPERM: \ - printf("The current thread does not hold a lock on mutex\n"); \ - break; \ - } \ - } \ - retu; \ -}) - -#define SCMutex pthread_mutex_t -#define SCMutexAttr pthread_mutexattr_t -#define SCMutexInit(mut, mutattrs) SCMutexInit_dbg(mut, mutattrs) -#define SCMutexLock(mut) SCMutexLock_dbg(mut) -#define SCMutexTrylock(mut) SCMutexTrylock_dbg(mut) -#define SCMutexUnlock(mut) SCMutexUnlock_dbg(mut) -#define SCMutexDestroy pthread_mutex_destroy -#define SCMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER - -/* conditions */ - -#define SCCondWait_dbg(cond, mut) ({ \ - int ret = pthread_cond_wait(cond, mut); \ - switch (ret) { \ - case EINVAL: \ - printf("The value specified by attr is invalid (or a SCCondT not initialized!)\n"); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") failed SCCondWait %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, ret); \ - break; \ - } \ - ret; \ -}) - -/* conditions */ -#define SCCondT pthread_cond_t -#define SCCondInit pthread_cond_init -#define SCCondSignal pthread_cond_signal -#define SCCondDestroy pthread_cond_destroy -#define SCCondWait SCCondWait_dbg - -/* spinlocks */ - -#define SCSpinLock_dbg(spin) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") locking spin %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin); \ - int ret = pthread_spin_lock(spin); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocked spin %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \ - switch (ret) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - break; \ - case EDEADLK: \ - printf("A deadlock would occur if the thread blocked waiting for spin\n"); \ - break; \ - } \ - ret; \ -}) - -#define SCSpinTrylock_dbg(spin) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocking spin %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin); \ - int ret = pthread_spin_trylock(spin); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocked spin %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \ - switch (ret) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - break; \ - case EDEADLK: \ - printf("A deadlock would occur if the thread blocked waiting for spin\n"); \ - break; \ - case EBUSY: \ - printf("A thread currently holds the lock\n"); \ - break; \ - } \ - ret; \ -}) - -#define SCSpinUnlock_dbg(spin) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocking spin %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin); \ - int ret = pthread_spin_unlock(spin); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") unlockedspin %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \ - switch (ret) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - break; \ - case EPERM: \ - printf("The calling thread does not hold the lock\n"); \ - break; \ - } \ - ret; \ -}) - -#define SCSpinInit_dbg(spin, spin_attr) ({ \ - int ret = pthread_spin_init(spin, spin_attr); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") spinlock %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \ - switch (ret) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - break; \ - case EBUSY: \ - printf("A thread currently holds the lock\n"); \ - break; \ - case ENOMEM: \ - printf("The process cannot allocate enough memory to create another spin\n"); \ - break; \ - case EAGAIN: \ - printf("The system temporarily lacks the resources to create another spin\n"); \ - break; \ - } \ - ret; \ -}) - -#define SCSpinDestroy_dbg(spin) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") condition %p waiting\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin); \ - int ret = pthread_spin_destroy(spin); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") condition %p passed %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), spin, ret); \ - switch (ret) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - break; \ - case EBUSY: \ - printf("A thread currently holds the lock\n"); \ - break; \ - case ENOMEM: \ - printf("The process cannot allocate enough memory to create another spin\n"); \ - break; \ - case EAGAIN: \ - printf("The system temporarily lacks the resources to create another spin\n"); \ - break; \ - } \ - ret; \ -}) - -#define SCSpinlock pthread_spinlock_t -#define SCSpinLock SCSpinLock_dbg -#define SCSpinTrylock SCSpinTrylock_dbg -#define SCSpinUnlock SCSpinUnlock_dbg -#define SCSpinInit SCSpinInit_dbg -#define SCSpinDestroy SCSpinDestroy_dbg - -/* rwlocks */ - -/** When dbg threads is defined, if a rwlock fail to lock, it's - * initialized, logged, and does a second try; This is to prevent the system to freeze; - * If you see a rwlock, spinlock or condiion not initialized, report it please! - */ -#define SCRWLockRDLock_dbg(rwl) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") locking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \ - int retl = pthread_rwlock_rdlock(rwl); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") locked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, retl); \ - if (retl != 0) { \ - switch (retl) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - retl = pthread_rwlock_init(rwl, NULL); \ - if (retl != 0) \ - exit(EXIT_FAILURE); \ - retl = pthread_rwlock_rdlock(rwl); \ - break; \ - case EDEADLK: \ - printf("A deadlock would occur if the thread blocked waiting for rwlock\n"); \ - break; \ - } \ - } \ - retl; \ -}) - -#define SCRWLockWRLock_dbg(rwl) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") locking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \ - int retl = pthread_rwlock_wrlock(rwl); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") locked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, retl); \ - if (retl != 0) { \ - switch (retl) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - retl = pthread_rwlock_init(rwl, NULL); \ - if (retl != 0) \ - exit(EXIT_FAILURE); \ - retl = pthread_rwlock_wrlock(rwl); \ - break; \ - case EDEADLK: \ - printf("A deadlock would occur if the thread blocked waiting for rwlock\n"); \ - break; \ - } \ - } \ - retl; \ -}) - - -#define SCRWLockTryWRLock_dbg(rwl) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \ - int rett = pthread_rwlock_trywrlock(rwl); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, rett); \ - if (rett != 0) { \ - switch (rett) { \ - case EINVAL: \ - printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \ - break; \ - case EBUSY: \ - printf("RWLock is already locked\n"); \ - break; \ - } \ - } \ - rett; \ -}) - -#define SCRWLockTryRDLock_dbg(rwl) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \ - int rett = pthread_rwlock_tryrdlock(rwl); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") trylocked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, rett); \ - if (rett != 0) { \ - switch (rett) { \ - case EINVAL: \ - printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \ - break; \ - case EBUSY: \ - printf("RWLock is already locked\n"); \ - break; \ - } \ - } \ - rett; \ -}) - -#define SCRWLockInit_dbg(rwl, rwlattr) ({ \ - int ret; \ - ret = pthread_rwlock_init(rwl, rwlattr); \ - if (ret != 0) { \ - switch (ret) { \ - case EINVAL: \ - printf("The value specified by attr is invalid\n"); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") rwlock %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, ret); \ - break; \ - case EAGAIN: \ - printf("The system temporarily lacks the resources to create another rwlock\n"); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") rwlock %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, ret); \ - break; \ - case ENOMEM: \ - printf("The process cannot allocate enough memory to create another rwlock\n"); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") rwlock %p initialization returned %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, ret); \ - break; \ - } \ - } \ - ret; \ -}) - -#define SCRWLockUnlock_dbg(rwl) ({ \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocking rwlock %p\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl); \ - int retu = pthread_rwlock_unlock(rwl); \ - printf("%16s(%s:%d): (thread:%"PRIuMAX") unlocked rwlock %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), rwl, retu); \ - if (retu != 0) { \ - switch (retu) { \ - case EINVAL: \ - printf("%16s(%s:%d): The value specified by attr is invalid\n", __FUNCTION__, __FILE__, __LINE__); \ - break; \ - case EPERM: \ - printf("The current thread does not hold a lock on rwlock\n"); \ - break; \ - } \ - } \ - retu; \ -}) - -#define SCRWLock pthread_rwlock_t -#define SCRWLockInit(rwl, rwlattrs) SCRWLockInit_dbg(rwl, rwlattrs) -#define SCRWLockRDLock(rwl) SCRWLockRDLock_dbg(rwl) -#define SCRWLockWRLock(rwl) SCRWLockWRLock_dbg(rwl) -#define SCRWLockTryWRLock(rwl) SCRWLockTryWRLock_dbg(rwl) -#define SCRWLockTryRDLock(rwl) SCRWLockTryRDLock_dbg(rwl) -#define SCRWLockUnlock(rwl) SCRWLockUnlock_dbg(rwl) -#define SCRWLockDestroy pthread_rwlock_destroy - -/* ctrl mutex */ -#define SCCtrlMutex pthread_mutex_t -#define SCCtrlMutexAttr pthread_mutexattr_t -#define SCCtrlMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr) -#define SCCtrlMutexLock(mut) pthread_mutex_lock(mut) -#define SCCtrlMutexTrylock(mut) pthread_mutex_trylock(mut) -#define SCCtrlMutexUnlock(mut) pthread_mutex_unlock(mut) -#define SCCtrlMutexDestroy pthread_mutex_destroy - -/* ctrl conditions */ -#define SCCtrlCondT pthread_cond_t -#define SCCtrlCondInit pthread_cond_init -#define SCCtrlCondSignal pthread_cond_signal -#define SCCtrlCondTimedwait pthread_cond_timedwait -#define SCCtrlCondWait pthread_cond_wait -#define SCCtrlCondDestroy pthread_cond_destroy - -#endif diff --git a/framework/src/suricata/src/threads-profile.h b/framework/src/suricata/src/threads-profile.h deleted file mode 100644 index 6e19673b..00000000 --- a/framework/src/suricata/src/threads-profile.h +++ /dev/null @@ -1,218 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Lock profiling wrappers - */ - -#ifndef __THREADS_PROFILE_H__ -#define __THREADS_PROFILE_H__ - -/* profiling */ - -typedef struct ProfilingLock_ { - char *file; - char *func; - int line; - int type; - uint32_t cont; - uint64_t ticks; -} ProfilingLock; - -extern __thread ProfilingLock locks[PROFILING_MAX_LOCKS]; -extern __thread int locks_idx; -extern __thread int record_locks; - -extern __thread uint64_t mutex_lock_contention; -extern __thread uint64_t mutex_lock_wait_ticks; -extern __thread uint64_t mutex_lock_cnt; - -/* mutex */ - -//printf("%16s(%s:%d): (thread:%"PRIuMAX") locked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retl); -#define SCMutexLock_profile(mut) ({ \ - mutex_lock_cnt++; \ - int retl = 0; \ - int cont = 0; \ - uint64_t mutex_lock_start = UtilCpuGetTicks(); \ - if (pthread_mutex_trylock((mut)) != 0) { \ - mutex_lock_contention++; \ - cont = 1; \ - retl = pthread_mutex_lock(mut); \ - } \ - uint64_t mutex_lock_end = UtilCpuGetTicks(); \ - mutex_lock_wait_ticks += (uint64_t)(mutex_lock_end - mutex_lock_start); \ - \ - if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \ - locks[locks_idx].file = (char *)__FILE__; \ - locks[locks_idx].func = (char *)__func__; \ - locks[locks_idx].line = (int)__LINE__; \ - locks[locks_idx].type = LOCK_MUTEX; \ - locks[locks_idx].cont = cont; \ - locks[locks_idx].ticks = (uint64_t)(mutex_lock_end - mutex_lock_start); \ - locks_idx++; \ - } \ - retl; \ -}) - -#define SCMutex pthread_mutex_t -#define SCMutexAttr pthread_mutexattr_t -#define SCMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr) -#define SCMutexLock(mut) SCMutexLock_profile(mut) -#define SCMutexTrylock(mut) pthread_mutex_trylock(mut) -#define SCMutexUnlock(mut) pthread_mutex_unlock(mut) -#define SCMutexDestroy pthread_mutex_destroy -#define SCMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER - -/* conditions */ - -#define SCCondT pthread_cond_t -#define SCCondInit pthread_cond_init -#define SCCondSignal pthread_cond_signal -#define SCCondDestroy pthread_cond_destroy -#define SCCondWait(cond, mut) pthread_cond_wait(cond, mut) - -/* spinlocks */ - -extern __thread uint64_t spin_lock_contention; -extern __thread uint64_t spin_lock_wait_ticks; -extern __thread uint64_t spin_lock_cnt; - -//printf("%16s(%s:%d): (thread:%"PRIuMAX") locked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retl); -#define SCSpinLock_profile(spin) ({ \ - spin_lock_cnt++; \ - int retl = 0; \ - int cont = 0; \ - uint64_t spin_lock_start = UtilCpuGetTicks(); \ - if (pthread_spin_trylock((spin)) != 0) { \ - spin_lock_contention++; \ - cont = 1; \ - retl = pthread_spin_lock((spin)); \ - } \ - uint64_t spin_lock_end = UtilCpuGetTicks(); \ - spin_lock_wait_ticks += (uint64_t)(spin_lock_end - spin_lock_start); \ - \ - if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \ - locks[locks_idx].file = (char *)__FILE__; \ - locks[locks_idx].func = (char *)__func__; \ - locks[locks_idx].line = (int)__LINE__; \ - locks[locks_idx].type = LOCK_SPIN; \ - locks[locks_idx].cont = cont; \ - locks[locks_idx].ticks = (uint64_t)(spin_lock_end - spin_lock_start); \ - locks_idx++; \ - } \ - retl; \ -}) - -#define SCSpinlock pthread_spinlock_t -#define SCSpinLock(mut) SCSpinLock_profile(mut) -#define SCSpinTrylock(spin) pthread_spin_trylock(spin) -#define SCSpinUnlock(spin) pthread_spin_unlock(spin) -#define SCSpinInit(spin, spin_attr) pthread_spin_init(spin, spin_attr) -#define SCSpinDestroy(spin) pthread_spin_destroy(spin) - -/* rwlocks */ - -extern __thread uint64_t rww_lock_contention; -extern __thread uint64_t rww_lock_wait_ticks; -extern __thread uint64_t rww_lock_cnt; - -#define SCRWLockWRLock_profile(mut) ({ \ - rww_lock_cnt++; \ - int retl = 0; \ - int cont = 0; \ - uint64_t rww_lock_start = UtilCpuGetTicks(); \ - if (pthread_rwlock_trywrlock((mut)) != 0) { \ - rww_lock_contention++; \ - cont = 1; \ - retl = pthread_rwlock_wrlock(mut); \ - } \ - uint64_t rww_lock_end = UtilCpuGetTicks(); \ - rww_lock_wait_ticks += (uint64_t)(rww_lock_end - rww_lock_start); \ - \ - if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \ - locks[locks_idx].file = (char *)__FILE__; \ - locks[locks_idx].func = (char *)__func__; \ - locks[locks_idx].line = (int)__LINE__; \ - locks[locks_idx].type = LOCK_RWW; \ - locks[locks_idx].cont = cont; \ - locks[locks_idx].ticks = (uint64_t)(rww_lock_end - rww_lock_start); \ - locks_idx++; \ - } \ - retl; \ -}) - -extern __thread uint64_t rwr_lock_contention; -extern __thread uint64_t rwr_lock_wait_ticks; -extern __thread uint64_t rwr_lock_cnt; - -#define SCRWLockRDLock_profile(mut) ({ \ - rwr_lock_cnt++; \ - int retl = 0; \ - int cont = 0; \ - uint64_t rwr_lock_start = UtilCpuGetTicks(); \ - if (pthread_rwlock_tryrdlock((mut)) != 0) { \ - rwr_lock_contention++; \ - cont = 1; \ - retl = pthread_rwlock_rdlock(mut); \ - } \ - uint64_t rwr_lock_end = UtilCpuGetTicks(); \ - rwr_lock_wait_ticks += (uint64_t)(rwr_lock_end - rwr_lock_start); \ - \ - if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \ - locks[locks_idx].file = (char *)__FILE__; \ - locks[locks_idx].func = (char *)__func__; \ - locks[locks_idx].line = (int)__LINE__; \ - locks[locks_idx].type = LOCK_RWR; \ - locks[locks_idx].cont = cont; \ - locks[locks_idx].ticks = (uint64_t)(rwr_lock_end - rwr_lock_start); \ - locks_idx++; \ - } \ - retl; \ -}) - -#define SCRWLock pthread_rwlock_t -#define SCRWLockInit(rwl, rwlattr ) pthread_rwlock_init(rwl, rwlattr) -#define SCRWLockWRLock(mut) SCRWLockWRLock_profile(mut) -#define SCRWLockRDLock(mut) SCRWLockRDLock_profile(mut) -#define SCRWLockTryWRLock(rwl) pthread_rwlock_trywrlock(rwl) -#define SCRWLockTryRDLock(rwl) pthread_rwlock_tryrdlock(rwl) -#define SCRWLockUnlock(rwl) pthread_rwlock_unlock(rwl) -#define SCRWLockDestroy pthread_rwlock_destroy - -/* ctrl mutex */ -#define SCCtrlMutex pthread_mutex_t -#define SCCtrlMutexAttr pthread_mutexattr_t -#define SCCtrlMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr) -#define SCCtrlMutexLock(mut) pthread_mutex_lock(mut) -#define SCCtrlMutexTrylock(mut) pthread_mutex_trylock(mut) -#define SCCtrlMutexUnlock(mut) pthread_mutex_unlock(mut) -#define SCCtrlMutexDestroy pthread_mutex_destroy - -/* ctrl conditions */ -#define SCCtrlCondT pthread_cond_t -#define SCCtrlCondInit pthread_cond_init -#define SCCtrlCondSignal pthread_cond_signal -#define SCCtrlCondTimedwait pthread_cond_timedwait -#define SCCtrlCondWait pthread_cond_wait -#define SCCtrlCondDestroy pthread_cond_destroy - -#endif diff --git a/framework/src/suricata/src/threads.c b/framework/src/suricata/src/threads.c deleted file mode 100644 index 6e585825..00000000 --- a/framework/src/suricata/src/threads.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon Crespo - * - * This file now only contains unit tests see macros in threads.h - */ - -#include "suricata-common.h" -#include "util-unittest.h" -#include "debug.h" -#include "util-debug.h" -#include "threads.h" - -#ifdef UNITTESTS /* UNIT TESTS */ - -/** - * \brief Test Mutex macros - */ -int ThreadMacrosTest01Mutex(void) -{ - SCMutex mut; - int r = 0; - r |= SCMutexInit(&mut, NULL); - r |= SCMutexLock(&mut); - r |= (SCMutexTrylock(&mut) == EBUSY)? 0 : 1; - r |= SCMutexUnlock(&mut); - r |= SCMutexDestroy(&mut); - - return (r == 0)? 1 : 0; -} - -/** - * \brief Test Spinlock Macros - * - * Valgrind's DRD tool (valgrind-3.5.0-Debian) reports: - * - * ==31156== Recursive locking not allowed: mutex 0x7fefff97c, recursion count 1, owner 1. - * ==31156== at 0x4C2C77E: pthread_spin_trylock (drd_pthread_intercepts.c:829) - * ==31156== by 0x40EB3E: ThreadMacrosTest02Spinlocks (threads.c:40) - * ==31156== by 0x532E8A: UtRunTests (util-unittest.c:182) - * ==31156== by 0x4065C3: main (suricata.c:789) - * - * To me this is a false positve, as the whole point of "trylock" is to see - * if a spinlock is actually locked. - * - */ -int ThreadMacrosTest02Spinlocks(void) -{ - SCSpinlock mut; - int r = 0; - r |= SCSpinInit(&mut, 0); - r |= SCSpinLock(&mut); -#ifndef __OpenBSD__ - r |= (SCSpinTrylock(&mut) == EBUSY)? 0 : 1; -#else - r |= (SCSpinTrylock(&mut) == EDEADLK)? 0 : 1; -#endif - r |= SCSpinUnlock(&mut); - r |= SCSpinDestroy(&mut); - - return (r == 0)? 1 : 0; -} - -/** - * \brief Test RWLock macros - */ -int ThreadMacrosTest03RWLocks(void) -{ - SCRWLock rwl_write; - int r = 0; - r |= SCRWLockInit(&rwl_write, NULL); - r |= SCRWLockWRLock(&rwl_write); -/* work around OS X 10.10 Yosemite returning EDEADLK. All other - * OS' (and versions of OS X that I tested) seem to return EBUSY - * instead. */ -#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__==101000 - r |= (SCRWLockTryWRLock(&rwl_write) == EDEADLK)? 0 : 1; -#else - r |= (SCRWLockTryWRLock(&rwl_write) == EBUSY)? 0 : 1; -#endif - r |= SCRWLockUnlock(&rwl_write); - r |= SCRWLockDestroy(&rwl_write); - - return (r == 0)? 1 : 0; -} - -/** - * \brief Test RWLock macros - */ -int ThreadMacrosTest04RWLocks(void) -{ - SCRWLock rwl_read; - int r = 0; - r |= SCRWLockInit(&rwl_read, NULL); - r |= SCRWLockRDLock(&rwl_read); - r |= (SCRWLockTryWRLock(&rwl_read) == EBUSY)? 0 : 1; - r |= SCRWLockUnlock(&rwl_read); - r |= SCRWLockDestroy(&rwl_read); - - return (r == 0)? 1 : 0; -} - -/** - * \brief Test RWLock macros - */ -int ThreadMacrosTest05RWLocks(void) -{ - SCRWLock rwl_read; - int r = 0; - r |= SCRWLockInit(&rwl_read, NULL); - r |= SCRWLockWRLock(&rwl_read); - r |= (SCRWLockTryRDLock(&rwl_read) == EBUSY)? 0 : 1; - r |= SCRWLockUnlock(&rwl_read); - r |= SCRWLockDestroy(&rwl_read); - - return (r == 0)? 1 : 0; -} - -#endif /* UNIT TESTS */ - -/** - * \brief this function registers unit tests for DetectId - */ -void ThreadMacrosRegisterTests(void) -{ -#ifdef UNITTESTS /* UNIT TESTS */ - UtRegisterTest("ThreadMacrosTest01Mutex", ThreadMacrosTest01Mutex, 1); - UtRegisterTest("ThreadMacrosTest02Spinlocks", ThreadMacrosTest02Spinlocks, 1); - UtRegisterTest("ThreadMacrosTest03RWLocks", ThreadMacrosTest03RWLocks, 1); - UtRegisterTest("ThreadMacrosTest04RWLocks", ThreadMacrosTest04RWLocks, 1); -#endif /* UNIT TESTS */ -} diff --git a/framework/src/suricata/src/threads.h b/framework/src/suricata/src/threads.h deleted file mode 100644 index 0a843b7f..00000000 --- a/framework/src/suricata/src/threads.h +++ /dev/null @@ -1,300 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon Crespo - * - * Threading functions defined as macros - */ - -#ifndef __THREADS_H__ -#define __THREADS_H__ - -#if HAVE_CONFIG_H -#include -#endif - -/* need this for the _POSIX_SPIN_LOCKS define */ -#if HAVE_UNISTD_H -#include -#endif - -#ifdef PROFILING -#include "util-cpu.h" -#ifdef PROFILE_LOCKING -#include "util-profiling-locks.h" -#endif /* PROFILE_LOCKING */ -#endif /* PROFILING */ - -#if defined OS_FREEBSD || __OpenBSD__ - -#if ! defined __OpenBSD__ -#include -#endif -enum { - PRIO_LOW = 2, - PRIO_MEDIUM = 0, - PRIO_HIGH = -2, -}; - -#elif OS_DARWIN - -#include -enum { - PRIO_LOW = 2, - PRIO_MEDIUM = 0, - PRIO_HIGH = -2, -}; - -#elif OS_WIN32 - -#include -enum { - PRIO_LOW = THREAD_PRIORITY_LOWEST, - PRIO_MEDIUM = THREAD_PRIORITY_NORMAL, - PRIO_HIGH = THREAD_PRIORITY_HIGHEST, -}; - -#else /* LINUX */ - -#if HAVE_SYS_SYSCALL_H -#include -#endif -#if HAVE_SYS_PRCTL_H -#include -#define THREAD_NAME_LEN 16 -#endif - -enum { - PRIO_LOW = 2, - PRIO_MEDIUM = 0, - PRIO_HIGH = -2, -}; - -#endif /* OS_FREEBSD */ - -#include - -/* The mutex/spinlock/condition definitions and functions are used - * in the same way as the POSIX definitions; Anyway we are centralizing - * them here to make an easier portability process and debugging process; - * Please, make sure you initialize mutex and spinlocks before using them - * because, some OS doesn't initialize them for you :) - */ - -//#define DBG_THREADS - -#ifdef __tile__ - #include "threads-arch-tile.h" -#elif defined DBG_THREADS - #ifdef PROFILE_LOCKING - #error "Cannot mix DBG_THREADS and PROFILE_LOCKING" - #endif - #include "threads-debug.h" -#elif defined PROFILE_LOCKING - #include "threads-profile.h" -#else /* normal */ - -/* mutex */ -#define SCMutex pthread_mutex_t -#define SCMutexAttr pthread_mutexattr_t -#define SCMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr) -#define SCMutexLock(mut) pthread_mutex_lock(mut) -#define SCMutexTrylock(mut) pthread_mutex_trylock(mut) -#define SCMutexUnlock(mut) pthread_mutex_unlock(mut) -#define SCMutexDestroy pthread_mutex_destroy -#define SCMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER - -/* rwlocks */ -#define SCRWLock pthread_rwlock_t -#define SCRWLockInit(rwl, rwlattr ) pthread_rwlock_init(rwl, rwlattr) -#define SCRWLockWRLock(rwl) pthread_rwlock_wrlock(rwl) -#define SCRWLockRDLock(rwl) pthread_rwlock_rdlock(rwl) -#define SCRWLockTryWRLock(rwl) pthread_rwlock_trywrlock(rwl) -#define SCRWLockTryRDLock(rwl) pthread_rwlock_tryrdlock(rwl) -#define SCRWLockUnlock(rwl) pthread_rwlock_unlock(rwl) -#define SCRWLockDestroy pthread_rwlock_destroy - -/* conditions */ -#define SCCondT pthread_cond_t -#define SCCondInit pthread_cond_init -#define SCCondSignal pthread_cond_signal -#define SCCondDestroy pthread_cond_destroy -#define SCCondWait(cond, mut) pthread_cond_wait(cond, mut) - -/* ctrl mutex */ -#define SCCtrlMutex pthread_mutex_t -#define SCCtrlMutexAttr pthread_mutexattr_t -#define SCCtrlMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr) -#define SCCtrlMutexLock(mut) pthread_mutex_lock(mut) -#define SCCtrlMutexTrylock(mut) pthread_mutex_trylock(mut) -#define SCCtrlMutexUnlock(mut) pthread_mutex_unlock(mut) -#define SCCtrlMutexDestroy pthread_mutex_destroy - -/* ctrl conditions */ -#define SCCtrlCondT pthread_cond_t -#define SCCtrlCondInit pthread_cond_init -#define SCCtrlCondSignal pthread_cond_signal -#define SCCtrlCondTimedwait pthread_cond_timedwait -#define SCCtrlCondWait pthread_cond_wait -#define SCCtrlCondDestroy pthread_cond_destroy - -/* spinlocks */ -#if ((_POSIX_SPIN_LOCKS - 200112L) < 0L) || defined HELGRIND -#define SCSpinlock SCMutex -#define SCSpinLock(spin) SCMutexLock((spin)) -#define SCSpinTrylock(spin) SCMutexTrylock((spin)) -#define SCSpinUnlock(spin) SCMutexUnlock((spin)) -#define SCSpinInit(spin, spin_attr) SCMutexInit((spin), NULL) -#define SCSpinDestroy(spin) SCMutexDestroy((spin)) -#else /* no spinlocks */ -#define SCSpinlock pthread_spinlock_t -#define SCSpinLock(spin) pthread_spin_lock(spin) -#define SCSpinTrylock(spin) pthread_spin_trylock(spin) -#define SCSpinUnlock(spin) pthread_spin_unlock(spin) -#define SCSpinInit(spin, spin_attr) pthread_spin_init(spin, spin_attr) -#define SCSpinDestroy(spin) pthread_spin_destroy(spin) -#endif /* no spinlocks */ - -#endif /* __tile__ */ - -#if (!defined SCMutex || !defined SCMutexAttr || !defined SCMutexInit || \ - !defined SCMutexLock || !defined SCMutexTrylock || \ - !defined SCMutexUnlock || !defined SCMutexDestroy || \ - !defined SCMUTEX_INITIALIZER) -#error "Mutex types and/or macro's not properly defined" -#endif -#if (!defined SCCtrlMutex || !defined SCCtrlMutexAttr || !defined SCCtrlMutexInit || \ - !defined SCCtrlMutexLock || !defined SCCtrlMutexTrylock || \ - !defined SCCtrlMutexUnlock || !defined SCCtrlMutexDestroy) -#error "SCCtrlMutex types and/or macro's not properly defined" -#endif - -#if (!defined SCSpinlock || !defined SCSpinLock || \ - !defined SCSpinTrylock || !defined SCSpinUnlock || \ - !defined SCSpinInit || !defined SCSpinDestroy) -#error "Spinlock types and/or macro's not properly defined" -#endif - -#if (!defined SCRWLock || !defined SCRWLockInit || !defined SCRWLockWRLock || \ - !defined SCRWLockRDLock || !defined SCRWLockTryWRLock || \ - !defined SCRWLockTryRDLock || !defined SCRWLockUnlock || !defined SCRWLockDestroy) -#error "SCRWLock types and/or macro's not properly defined" -#endif - -#if (!defined SCCondT || !defined SCCondInit || !defined SCCondSignal || \ - !defined SCCondDestroy || !defined SCCondWait) -#error "SCCond types and/or macro's not properly defined" -#endif - -#if (!defined SCCtrlCondT || !defined SCCtrlCondInit || !defined SCCtrlCondSignal ||\ - !defined SCCtrlCondDestroy || !defined SCCtrlCondTimedwait) -#error "SCCtrlCond types and/or macro's not properly defined" -#endif - -/** Get the Current Thread Id */ -#ifdef OS_FREEBSD -#include - -#define SCGetThreadIdLong(...) ({ \ - long tmpthid; \ - thr_self(&tmpthid); \ - u_long tid = (u_long)tmpthid; \ - tid; \ -}) -#elif __OpenBSD__ -#define SCGetThreadIdLong(...) ({ \ - pid_t tpid; \ - tpid = getpid(); \ - u_long tid = (u_long)tpid; \ - tid; \ -}) -#elif __CYGWIN__ -#define SCGetThreadIdLong(...) ({ \ - u_long tid = (u_long)GetCurrentThreadId(); \ - tid; \ -}) -#elif OS_WIN32 -#define SCGetThreadIdLong(...) ({ \ - u_long tid = (u_long)GetCurrentThreadId(); \ - tid; \ -}) -#elif OS_DARWIN -#define SCGetThreadIdLong(...) ({ \ - thread_port_t tpid; \ - tpid = mach_thread_self(); \ - u_long tid = (u_long)tpid; \ - tid; \ -}) -#else -#define SCGetThreadIdLong(...) ({ \ - pid_t tmpthid; \ - tmpthid = syscall(SYS_gettid); \ - u_long tid = (u_long)tmpthid; \ - tid; \ -}) -#endif /* OS FREEBSD */ - -/* - * OS specific macro's for setting the thread name. "top" can display - * this name. - */ -#if defined OS_FREEBSD /* FreeBSD */ -/** \todo Add implementation for FreeBSD */ -#define SCSetThreadName(n) ({ \ - char tname[16] = ""; \ - if (strlen(n) > 16) \ - SCLogDebug("Thread name is too long, truncating it..."); \ - strlcpy(tname, n, 16); \ - pthread_set_name_np(pthread_self(), tname); \ - 0; \ -}) -#elif defined __OpenBSD__ /* OpenBSD */ -/** \todo Add implementation for OpenBSD */ -#define SCSetThreadName(n) (0) -#elif defined OS_WIN32 /* Windows */ -/** \todo Add implementation for Windows */ -#define SCSetThreadName(n) (0) -#elif defined OS_DARWIN /* Mac OS X */ -/** \todo Add implementation for MacOS */ -#define SCSetThreadName(n) (0) -#elif defined PR_SET_NAME /* PR_SET_NAME */ -/** - * \brief Set the threads name - */ -#define SCSetThreadName(n) ({ \ - char tname[THREAD_NAME_LEN + 1] = ""; \ - if (strlen(n) > THREAD_NAME_LEN) \ - SCLogDebug("Thread name is too long, truncating it..."); \ - strlcpy(tname, n, THREAD_NAME_LEN); \ - int ret = 0; \ - if ((ret = prctl(PR_SET_NAME, tname, 0, 0, 0)) < 0) \ - SCLogDebug("Error setting thread name \"%s\": %s", tname, strerror(errno)); \ - ret; \ -}) -#else -#define SCSetThreadName(n) (0) -#endif - - -void ThreadMacrosRegisterTests(void); - -#endif /* __THREADS_H__ */ - diff --git a/framework/src/suricata/src/threadvars.h b/framework/src/suricata/src/threadvars.h deleted file mode 100644 index 79a2b34d..00000000 --- a/framework/src/suricata/src/threadvars.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __THREADVARS_H__ -#define __THREADVARS_H__ - -#include "util-mpm.h" -#include "util-affinity.h" -#include "tm-queues.h" -#include "counters.h" -#include "threads.h" - -struct TmSlot_; - -/** Thread flags set and read by threads to control the threads */ -#define THV_USE 1 /** thread is in use */ -#define THV_INIT_DONE (1 << 1) /** thread initialization done */ -#define THV_PAUSE (1 << 2) /** signal thread to pause itself */ -#define THV_PAUSED (1 << 3) /** the thread is paused atm */ -#define THV_KILL (1 << 4) /** thread has been asked to cleanup and exit */ -#define THV_FAILED (1 << 5) /** thread has encountered an error and failed */ -#define THV_CLOSED (1 << 6) /** thread done, should be joinable */ -/* used to indicate the thread is going through de-init. Introduced as more - * of a hack for solving stream-timeout-shutdown. Is set by the main thread. */ -#define THV_DEINIT (1 << 7) -#define THV_RUNNING_DONE (1 << 8) /** thread has completed running and is entering - * the de-init phase */ -#define THV_KILL_PKTACQ (1 << 9) /**< flag thread to stop packet acq */ -#define THV_FLOW_LOOP (1 << 10) /**< thread is in flow shutdown loop */ - -/** Thread flags set and read by threads, to control the threads, when they - * encounter certain conditions like failure */ -#define THV_RESTART_THREAD 0x01 /** restart the thread */ -#define THV_ENGINE_EXIT 0x02 /** shut the engine down gracefully */ - -/** Maximum no of times a thread can be restarted */ -#define THV_MAX_RESTARTS 50 - -/** \brief Per thread variable structure */ -typedef struct ThreadVars_ { - pthread_t t; - char *name; - char *thread_group_name; - - SC_ATOMIC_DECLARE(unsigned int, flags); - - /** aof(action on failure) determines what should be done with the thread - when it encounters certain conditions like failures */ - uint8_t aof; - - /** no of times the thread has been restarted on failure */ - uint8_t restarted; - - /** TmModule::flags for each module part of this thread */ - uint8_t tmm_flags; - - /** local id */ - int id; - - /** queue's */ - Tmq *inq; - Tmq *outq; - void *outctx; - char *outqh_name; - - /** queue handlers */ - struct Packet_ * (*tmqh_in)(struct ThreadVars_ *); - void (*InShutdownHandler)(struct ThreadVars_ *); - void (*tmqh_out)(struct ThreadVars_ *, struct Packet_ *); - - /** slot functions */ - void *(*tm_func)(void *); - struct TmSlot_ *tm_slots; - - /** stream packet queue for flow time out injection */ - struct PacketQueue_ *stream_pq; - - uint8_t thread_setup_flags; - - /** the type of thread as defined in tm-threads.h (TVT_PPT, TVT_MGMT) */ - uint8_t type; - - uint16_t cpu_affinity; /** cpu or core number to set affinity to */ - uint16_t rank; - int thread_priority; /** priority (real time) for this thread. Look at threads.h */ - - /* counters */ - - /** public counter store: counter syncs update this */ - StatsPublicThreadContext perf_public_ctx; - - /** private counter store: counter updates modify this */ - StatsPrivateThreadContext perf_private_ctx; - - SCCtrlMutex *ctrl_mutex; - SCCtrlCondT *ctrl_cond; - - uint8_t cap_flags; /**< Flags to indicate the capabilities of all the - TmModules resgitered under this thread */ - struct ThreadVars_ *next; - struct ThreadVars_ *prev; -} ThreadVars; - -/** Thread setup flags: */ -#define THREAD_SET_AFFINITY 0x01 /** CPU/Core affinity */ -#define THREAD_SET_PRIORITY 0x02 /** Real time priority */ -#define THREAD_SET_AFFTYPE 0x04 /** Priority and affinity */ - -#endif /* __THREADVARS_H__ */ - diff --git a/framework/src/suricata/src/tm-modules.c b/framework/src/suricata/src/tm-modules.c deleted file mode 100644 index 06190b65..00000000 --- a/framework/src/suricata/src/tm-modules.c +++ /dev/null @@ -1,283 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Thread Module functions - */ - -#include "suricata-common.h" -#include "packet-queue.h" -#include "tm-threads.h" -#include "util-debug.h" -#include "threads.h" -#include "util-logopenfile.h" - -void TmModuleDebugList(void) -{ - TmModule *t; - uint16_t i; - - for (i = 0; i < TMM_SIZE; i++) { - t = &tmm_modules[i]; - - if (t->name == NULL) - continue; - - SCLogDebug("%s:%p", t->name, t->Func); - } -} - -/** \brief get a tm module ptr by name - * \param name name string - * \retval ptr to the module or NULL */ -TmModule *TmModuleGetByName(const char *name) -{ - TmModule *t; - uint16_t i; - - for (i = 0; i < TMM_SIZE; i++) { - t = &tmm_modules[i]; - - if (t->name == NULL) - continue; - - if (strcmp(t->name, name) == 0) - return t; - } - - return NULL; -} - -/** \brief get the id of a module from it's name - * \param name registered name of the module - * \retval id the id or -1 in case of error */ -int TmModuleGetIdByName(const char *name) -{ - TmModule *tm = TmModuleGetByName(name); - if (tm == NULL) - return -1;; - return TmModuleGetIDForTM(tm); -} - -/** - * \brief Returns a TM Module by its id. - * - * \param id Id of the TM Module to return. - * - * \retval Pointer of the module to be returned if available; - * NULL if unavailable. - */ -TmModule *TmModuleGetById(int id) -{ - - if (id < 0 || id >= TMM_SIZE) { - SCLogError(SC_ERR_TM_MODULES_ERROR, "Threading module with the id " - "\"%d\" doesn't exist", id); - return NULL; - } - - return &tmm_modules[id]; -} - -/** - * \brief Given a TM Module, returns its id. - * - * \param tm Pointer to the TM Module. - * - * \retval id of the TM Module if available; -1 if unavailable. - */ -int TmModuleGetIDForTM(TmModule *tm) -{ - TmModule *t; - int i; - - for (i = 0; i < TMM_SIZE; i++) { - t = &tmm_modules[i]; - - if (t->name == NULL) - continue; - - if (strcmp(t->name, tm->name) == 0) - return i; - } - - return -1; -} - - -void TmModuleRunInit(void) -{ - TmModule *t; - uint16_t i; - - for (i = 0; i < TMM_SIZE; i++) { - t = &tmm_modules[i]; - - if (t->name == NULL) - continue; - - if (t->Init == NULL) - continue; - - t->Init(); - } -} - -void TmModuleRunDeInit(void) -{ - TmModule *t; - uint16_t i; - - for (i = 0; i < TMM_SIZE; i++) { - t = &tmm_modules[i]; - - if (t->name == NULL) - continue; - - if (t->DeInit == NULL) - continue; - - t->DeInit(); - } -} - -/** \brief register all unittests for the tm modules */ -void TmModuleRegisterTests(void) -{ -#ifdef UNITTESTS - TmModule *t; - uint16_t i; - - for (i = 0; i < TMM_SIZE; i++) { - t = &tmm_modules[i]; - - if (t->name == NULL) - continue; - - g_ut_modules++; - - - if (t->RegisterTests == NULL) { - if (coverage_unittests) - SCLogWarning(SC_WARN_NO_UNITTESTS, "threading module %s has no unittest " - "registration function.", t->name); - } else { - t->RegisterTests(); - g_ut_covered++; - } - } -#endif /* UNITTESTS */ -} - -#define CASE_CODE(E) case E: return #E - -/** - * \brief Maps the TmmId, to its string equivalent - * - * \param id tmm id - * - * \retval string equivalent for the tmm id - */ -const char * TmModuleTmmIdToString(TmmId id) -{ - switch (id) { - CASE_CODE (TMM_RECEIVENFLOG); - CASE_CODE (TMM_DECODENFLOG); - CASE_CODE (TMM_DECODENFQ); - CASE_CODE (TMM_VERDICTNFQ); - CASE_CODE (TMM_RECEIVENFQ); - CASE_CODE (TMM_RECEIVEPCAP); - CASE_CODE (TMM_RECEIVEPCAPFILE); - CASE_CODE (TMM_DECODEPCAP); - CASE_CODE (TMM_DECODEPCAPFILE); - CASE_CODE (TMM_RECEIVEPFRING); - CASE_CODE (TMM_DECODEPFRING); - CASE_CODE (TMM_DETECT); - CASE_CODE (TMM_ALERTFASTLOG); - CASE_CODE (TMM_ALERTFASTLOG4); - CASE_CODE (TMM_ALERTFASTLOG6); - CASE_CODE (TMM_ALERTUNIFIED2ALERT); - CASE_CODE (TMM_ALERTPRELUDE); - CASE_CODE (TMM_ALERTDEBUGLOG); - CASE_CODE (TMM_ALERTSYSLOG); - CASE_CODE (TMM_LOGDROPLOG); - CASE_CODE (TMM_ALERTSYSLOG4); - CASE_CODE (TMM_ALERTSYSLOG6); - CASE_CODE (TMM_RESPONDREJECT); - CASE_CODE (TMM_LOGDNSLOG); - CASE_CODE (TMM_LOGHTTPLOG); - CASE_CODE (TMM_LOGHTTPLOG4); - CASE_CODE (TMM_LOGHTTPLOG6); - CASE_CODE (TMM_LOGTLSLOG); - CASE_CODE (TMM_LOGTLSLOG4); - CASE_CODE (TMM_LOGTLSLOG6); - CASE_CODE (TMM_LOGTCPDATALOG); - CASE_CODE (TMM_PCAPLOG); - CASE_CODE (TMM_FILELOG); - CASE_CODE (TMM_FILESTORE); - CASE_CODE (TMM_STREAMTCP); - CASE_CODE (TMM_DECODEIPFW); - CASE_CODE (TMM_VERDICTIPFW); - CASE_CODE (TMM_RECEIVEIPFW); - CASE_CODE (TMM_RECEIVEERFFILE); - CASE_CODE (TMM_DECODEERFFILE); - CASE_CODE (TMM_RECEIVEERFDAG); - CASE_CODE (TMM_DECODEERFDAG); - CASE_CODE (TMM_RECEIVEMPIPE); - CASE_CODE (TMM_DECODEMPIPE); - CASE_CODE (TMM_RECEIVENAPATECH); - CASE_CODE (TMM_DECODENAPATECH); - CASE_CODE (TMM_RECEIVEAFP); - CASE_CODE (TMM_ALERTPCAPINFO); - CASE_CODE (TMM_DECODEAFP); - CASE_CODE (TMM_PACKETLOGGER); - CASE_CODE (TMM_TXLOGGER); - CASE_CODE (TMM_STATSLOGGER); - CASE_CODE (TMM_FILELOGGER); - CASE_CODE (TMM_FILEDATALOGGER); - CASE_CODE (TMM_STREAMINGLOGGER); - CASE_CODE (TMM_JSONALERTLOG); - CASE_CODE (TMM_JSONDROPLOG); - CASE_CODE (TMM_JSONDNSLOG); - CASE_CODE (TMM_JSONHTTPLOG); - CASE_CODE (TMM_JSONFILELOG); - CASE_CODE (TMM_JSONFLOWLOG); - CASE_CODE (TMM_JSONNETFLOWLOG); - CASE_CODE (TMM_JSONSMTPLOG); - CASE_CODE (TMM_JSONSSHLOG); - CASE_CODE (TMM_JSONSTATSLOG); - CASE_CODE (TMM_JSONTLSLOG); - CASE_CODE (TMM_OUTPUTJSON); - CASE_CODE (TMM_FLOWMANAGER); - CASE_CODE (TMM_FLOWRECYCLER); - CASE_CODE (TMM_UNIXMANAGER); - CASE_CODE (TMM_DETECTLOADER); - CASE_CODE (TMM_LUALOG); - CASE_CODE (TMM_LOGSTATSLOG); - CASE_CODE (TMM_JSONTEMPLATELOG); - CASE_CODE (TMM_RECEIVENETMAP); - CASE_CODE (TMM_DECODENETMAP); - CASE_CODE (TMM_TLSSTORE); - - CASE_CODE (TMM_SIZE); - } - return ""; -} diff --git a/framework/src/suricata/src/tm-modules.h b/framework/src/suricata/src/tm-modules.h deleted file mode 100644 index c9d4e1f5..00000000 --- a/framework/src/suricata/src/tm-modules.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __TM_MODULES_H__ -#define __TM_MODULES_H__ - -#include "tm-threads-common.h" -#include "threadvars.h" - -/* thread flags */ -#define TM_FLAG_RECEIVE_TM 0x01 -#define TM_FLAG_DECODE_TM 0x02 -#define TM_FLAG_STREAM_TM 0x04 -#define TM_FLAG_DETECT_TM 0x08 -#define TM_FLAG_LOGAPI_TM 0x10 /**< TM is run by Log API */ -#define TM_FLAG_MANAGEMENT_TM 0x20 -#define TM_FLAG_COMMAND_TM 0x40 - -typedef struct TmModule_ { - char *name; - - /** thread handling */ - TmEcode (*ThreadInit)(ThreadVars *, void *, void **); - void (*ThreadExitPrintStats)(ThreadVars *, void *); - TmEcode (*ThreadDeinit)(ThreadVars *, void *); - - /** the packet processing function */ - TmEcode (*Func)(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); - - TmEcode (*PktAcqLoop)(ThreadVars *, void *, void *); - - TmEcode (*Management)(ThreadVars *, void *); - - /** global Init/DeInit */ - TmEcode (*Init)(void); - TmEcode (*DeInit)(void); - - void (*RegisterTests)(void); - - uint8_t cap_flags; /**< Flags to indicate the capability requierment of - the given TmModule */ - /* Other flags used by the module */ - uint8_t flags; - /* priority in the logging order, higher priority is runned first */ - uint8_t priority; -} TmModule; - -TmModule tmm_modules[TMM_SIZE]; - -/** - * Structure that output modules use to maintain private data. - */ -typedef struct OutputCtx_ { - - /** Pointer to data private to the output. */ - void *data; - - /** Pointer to a cleanup function. */ - void (*DeInit)(struct OutputCtx_ *); - - TAILQ_HEAD(, OutputModule_) submodules; -} OutputCtx; - -TmModule *TmModuleGetByName(const char *name); -TmModule *TmModuleGetById(int id); -int TmModuleGetIdByName(const char *name); -int TmModuleGetIDForTM(TmModule *tm); -TmEcode TmModuleRegister(char *name, int (*module_func)(ThreadVars *, Packet *, void *)); -void TmModuleDebugList(void); -void TmModuleRegisterTests(void); -const char * TmModuleTmmIdToString(TmmId id); - -void TmModuleRunInit(void); -void TmModuleRunDeInit(void); - -#endif /* __TM_MODULES_H__ */ - diff --git a/framework/src/suricata/src/tm-queuehandlers.c b/framework/src/suricata/src/tm-queuehandlers.c deleted file mode 100644 index 007a8ab3..00000000 --- a/framework/src/suricata/src/tm-queuehandlers.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Master Queue Handler - */ - -#include "suricata-common.h" -#include "packet-queue.h" -#include "decode.h" -#include "threads.h" -#include "threadvars.h" - -#include "tm-queuehandlers.h" -#include "tmqh-simple.h" -#include "tmqh-nfq.h" -#include "tmqh-packetpool.h" -#include "tmqh-flow.h" -#include "tmqh-ringbuffer.h" - -void TmqhSetup (void) -{ - memset(&tmqh_table, 0, sizeof(tmqh_table)); - - TmqhSimpleRegister(); - TmqhNfqRegister(); - TmqhPacketpoolRegister(); - TmqhFlowRegister(); - TmqhRingBufferRegister(); -} - -/** \brief Clean up registration time allocs */ -void TmqhCleanup(void) -{ - TmqhRingBufferDestroy(); -} - -Tmqh* TmqhGetQueueHandlerByName(char *name) -{ - int i; - - for (i = 0; i < TMQH_SIZE; i++) { - if (strcmp(name, tmqh_table[i].name) == 0) - return &tmqh_table[i]; - } - - return NULL; -} - diff --git a/framework/src/suricata/src/tm-queuehandlers.h b/framework/src/suricata/src/tm-queuehandlers.h deleted file mode 100644 index 63249799..00000000 --- a/framework/src/suricata/src/tm-queuehandlers.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __TM_QUEUEHANDLERS_H__ -#define __TM_QUEUEHANDLERS_H__ - -enum { - TMQH_SIMPLE, - TMQH_NFQ, - TMQH_PACKETPOOL, - TMQH_FLOW, - TMQH_RINGBUFFER_MRSW, - TMQH_RINGBUFFER_SRSW, - TMQH_RINGBUFFER_SRMW, - - TMQH_SIZE, -}; - -typedef struct Tmqh_ { - char *name; - Packet *(*InHandler)(ThreadVars *); - void (*InShutdownHandler)(ThreadVars *); - void (*OutHandler)(ThreadVars *, Packet *); - void *(*OutHandlerCtxSetup)(char *); - void (*OutHandlerCtxFree)(void *); - void (*RegisterTests)(void); -} Tmqh; - -Tmqh tmqh_table[TMQH_SIZE]; - -void TmqhSetup (void); -void TmqhCleanup(void); -Tmqh* TmqhGetQueueHandlerByName(char *name); - -#endif /* __TM_QUEUEHANDLERS_H__ */ - diff --git a/framework/src/suricata/src/tm-queues.c b/framework/src/suricata/src/tm-queues.c deleted file mode 100644 index e549a975..00000000 --- a/framework/src/suricata/src/tm-queues.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Thread module management functions - */ - -#include "suricata.h" -#include "threads.h" -#include "tm-queues.h" -#include "util-debug.h" - -#define TMQ_MAX_QUEUES 256 - -static uint16_t tmq_id = 0; -static Tmq tmqs[TMQ_MAX_QUEUES]; - -Tmq* TmqAlloc(void) -{ - Tmq *q = SCMalloc(sizeof(Tmq)); - if (unlikely(q == NULL)) - goto error; - - memset(q, 0, sizeof(Tmq)); - return q; - -error: - return NULL; -} - -Tmq* TmqCreateQueue(char *name) -{ - if (tmq_id >= TMQ_MAX_QUEUES) - goto error; - - Tmq *q = &tmqs[tmq_id]; - q->name = name; - q->id = tmq_id++; - /* for cuda purposes */ - q->q_type = 0; - - SCLogDebug("created queue \'%s\', %p", name, q); - return q; - -error: - SCLogError(SC_ERR_THREAD_QUEUE, "too many thread queues %u, max is %u", tmq_id+1, TMQ_MAX_QUEUES); - return NULL; -} - -Tmq* TmqGetQueueByName(char *name) -{ - uint16_t i; - - for (i = 0; i < tmq_id; i++) { - if (strcmp(tmqs[i].name, name) == 0) - return &tmqs[i]; - } - - return NULL; -} - -void TmqDebugList(void) -{ - uint16_t i = 0; - for (i = 0; i < tmq_id; i++) { - /* get a lock accessing the len */ - SCMutexLock(&trans_q[tmqs[i].id].mutex_q); - printf("TmqDebugList: id %" PRIu32 ", name \'%s\', len %" PRIu32 "\n", tmqs[i].id, tmqs[i].name, trans_q[tmqs[i].id].len); - SCMutexUnlock(&trans_q[tmqs[i].id].mutex_q); - } -} - -void TmqResetQueues(void) -{ - memset(&tmqs, 0x00, sizeof(tmqs)); - tmq_id = 0; -} - -/** - * \brief Checks if all the queues allocated so far have at least one reader - * and writer. - */ -void TmValidateQueueState(void) -{ - int i = 0; - char err = FALSE; - - for (i = 0; i < tmq_id; i++) { - SCMutexLock(&trans_q[tmqs[i].id].mutex_q); - if (tmqs[i].reader_cnt == 0) { - SCLogError(SC_ERR_THREAD_QUEUE, "queue \"%s\" doesn't have a reader (id %d, max %u)", tmqs[i].name, i, tmq_id); - err = TRUE; - } else if (tmqs[i].writer_cnt == 0) { - SCLogError(SC_ERR_THREAD_QUEUE, "queue \"%s\" doesn't have a writer (id %d, max %u)", tmqs[i].name, i, tmq_id); - err = TRUE; - } - SCMutexUnlock(&trans_q[tmqs[i].id].mutex_q); - - if (err == TRUE) - goto error; - } - - return; - -error: - SCLogError(SC_ERR_FATAL, "fatal error during threading setup"); - exit(EXIT_FAILURE); -} diff --git a/framework/src/suricata/src/tm-queues.h b/framework/src/suricata/src/tm-queues.h deleted file mode 100644 index 01dbb6e7..00000000 --- a/framework/src/suricata/src/tm-queues.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __TM_QUEUES_H__ -#define __TM_QUEUES_H__ - -typedef struct Tmq_ { - char *name; - uint16_t id; - uint16_t reader_cnt; - uint16_t writer_cnt; - /* 0 for packet-queue and 1 for data-queue */ - uint8_t q_type; -} Tmq; - -Tmq* TmqCreateQueue(char *name); -Tmq* TmqGetQueueByName(char *name); - -void TmqDebugList(void); -void TmqResetQueues(void); -void TmValidateQueueState(void); - -#endif /* __TM_QUEUES_H__ */ - diff --git a/framework/src/suricata/src/tm-threads-common.h b/framework/src/suricata/src/tm-threads-common.h deleted file mode 100644 index 6a66b417..00000000 --- a/framework/src/suricata/src/tm-threads-common.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#ifndef __TM_THREADS_COMMON_H__ -#define __TM_THREADS_COMMON_H__ - -/** \brief Thread Model Module id's. - * - * \note anything added here should also be added to TmModuleTmmIdToString - * in tm-modules.c - */ -typedef enum { - TMM_DECODENFQ, - TMM_VERDICTNFQ, - TMM_RECEIVENFQ, - TMM_RECEIVEPCAP, - TMM_RECEIVEPCAPFILE, - TMM_DECODEPCAP, - TMM_DECODEPCAPFILE, - TMM_RECEIVEPFRING, - TMM_DECODEPFRING, - TMM_DETECT, - TMM_ALERTFASTLOG, - TMM_ALERTFASTLOG4, - TMM_ALERTFASTLOG6, - TMM_ALERTUNIFIED2ALERT, - TMM_ALERTPRELUDE, - TMM_ALERTDEBUGLOG, - TMM_ALERTSYSLOG, - TMM_LOGDROPLOG, - TMM_ALERTSYSLOG4, - TMM_ALERTSYSLOG6, - TMM_RESPONDREJECT, - TMM_LOGDNSLOG, - TMM_LOGHTTPLOG, - TMM_LOGHTTPLOG4, - TMM_LOGHTTPLOG6, - TMM_LOGTLSLOG, - TMM_LOGTLSLOG4, - TMM_LOGTLSLOG6, - TMM_LOGTCPDATALOG, - TMM_OUTPUTJSON, - TMM_PCAPLOG, - TMM_FILELOG, - TMM_FILESTORE, - TMM_STREAMTCP, - TMM_DECODEIPFW, - TMM_VERDICTIPFW, - TMM_RECEIVEIPFW, - TMM_RECEIVEERFFILE, - TMM_DECODEERFFILE, - TMM_RECEIVEERFDAG, - TMM_DECODEERFDAG, - TMM_RECEIVEAFP, - TMM_DECODEAFP, - TMM_RECEIVENETMAP, - TMM_DECODENETMAP, - TMM_ALERTPCAPINFO, - TMM_RECEIVEMPIPE, - TMM_DECODEMPIPE, - TMM_RECEIVENAPATECH, - TMM_DECODENAPATECH, - TMM_PACKETLOGGER, - TMM_TXLOGGER, - TMM_STATSLOGGER, - TMM_FILELOGGER, - TMM_FILEDATALOGGER, - TMM_STREAMINGLOGGER, - TMM_JSONALERTLOG, - TMM_JSONDROPLOG, - TMM_JSONHTTPLOG, - TMM_JSONDNSLOG, - TMM_JSONSMTPLOG, - TMM_JSONSSHLOG, - TMM_JSONSTATSLOG, - TMM_JSONTLSLOG, - TMM_JSONFILELOG, - TMM_RECEIVENFLOG, - TMM_DECODENFLOG, - TMM_JSONFLOWLOG, - TMM_JSONNETFLOWLOG, - TMM_LOGSTATSLOG, - TMM_JSONTEMPLATELOG, - - TMM_FLOWMANAGER, - TMM_FLOWRECYCLER, - TMM_DETECTLOADER, - - TMM_UNIXMANAGER, - - TMM_LUALOG, - TMM_TLSSTORE, - TMM_SIZE, -} TmmId; - -/*Error codes for the thread modules*/ -typedef enum { - TM_ECODE_OK = 0, /**< Thread module exits OK*/ - TM_ECODE_FAILED, /**< Thread module exits due to failure*/ - TM_ECODE_DONE, /**< Thread module task is finished*/ -} TmEcode; - -/* ThreadVars type */ -enum { - TVT_PPT, - TVT_MGMT, - TVT_CMD, - TVT_MAX, -}; - -#endif /* __TM_THREADS_COMMON_H__ */ - diff --git a/framework/src/suricata/src/tm-threads.c b/framework/src/suricata/src/tm-threads.c deleted file mode 100644 index 2b26404f..00000000 --- a/framework/src/suricata/src/tm-threads.c +++ /dev/null @@ -1,2203 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * \author Eric Leblond - * - * Thread management functions. - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "stream.h" -#include "runmodes.h" -#include "threadvars.h" -#include "tm-queues.h" -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "tmqh-packetpool.h" -#include "threads.h" -#include "util-debug.h" -#include "util-privs.h" -#include "util-cpu.h" -#include "util-optimize.h" -#include "util-profiling.h" -#include "util-signal.h" -#include "queue.h" - -#ifdef PROFILE_LOCKING -__thread uint64_t mutex_lock_contention; -__thread uint64_t mutex_lock_wait_ticks; -__thread uint64_t mutex_lock_cnt; - -__thread uint64_t spin_lock_contention; -__thread uint64_t spin_lock_wait_ticks; -__thread uint64_t spin_lock_cnt; - -__thread uint64_t rww_lock_contention; -__thread uint64_t rww_lock_wait_ticks; -__thread uint64_t rww_lock_cnt; - -__thread uint64_t rwr_lock_contention; -__thread uint64_t rwr_lock_wait_ticks; -__thread uint64_t rwr_lock_cnt; -#endif - -#ifdef OS_FREEBSD -#include -#include -#include -#include -#include -#define cpu_set_t cpuset_t -#endif /* OS_FREEBSD */ - -/* prototypes */ -static int SetCPUAffinity(uint16_t cpu); - -/* root of the threadvars list */ -ThreadVars *tv_root[TVT_MAX] = { NULL }; - -/* lock to protect tv_root */ -SCMutex tv_root_lock = SCMUTEX_INITIALIZER; - -/* Action On Failure(AOF). Determines how the engine should behave when a - * thread encounters a failure. Defaults to restart the failed thread */ -uint8_t tv_aof = THV_RESTART_THREAD; - -/** - * \brief Check if a thread flag is set. - * - * \retval 1 flag is set. - * \retval 0 flag is not set. - */ -int TmThreadsCheckFlag(ThreadVars *tv, uint16_t flag) -{ - return (SC_ATOMIC_GET(tv->flags) & flag) ? 1 : 0; -} - -/** - * \brief Set a thread flag. - */ -void TmThreadsSetFlag(ThreadVars *tv, uint16_t flag) -{ - SC_ATOMIC_OR(tv->flags, flag); -} - -/** - * \brief Unset a thread flag. - */ -void TmThreadsUnsetFlag(ThreadVars *tv, uint16_t flag) -{ - SC_ATOMIC_AND(tv->flags, ~flag); -} - -/** - * \brief Separate run function so we can call it recursively. - * - * \todo Deal with post_pq for slots beyond the first. - */ -TmEcode TmThreadsSlotVarRun(ThreadVars *tv, Packet *p, - TmSlot *slot) -{ - TmEcode r; - TmSlot *s; - Packet *extra_p; - - for (s = slot; s != NULL; s = s->slot_next) { - TmSlotFunc SlotFunc = SC_ATOMIC_GET(s->SlotFunc); - PACKET_PROFILING_TMM_START(p, s->tm_id); - - if (unlikely(s->id == 0)) { - r = SlotFunc(tv, p, SC_ATOMIC_GET(s->slot_data), &s->slot_pre_pq, &s->slot_post_pq); - } else { - r = SlotFunc(tv, p, SC_ATOMIC_GET(s->slot_data), &s->slot_pre_pq, NULL); - } - - PACKET_PROFILING_TMM_END(p, s->tm_id); - - /* handle error */ - if (unlikely(r == TM_ECODE_FAILED)) { - /* Encountered error. Return packets to packetpool and return */ - TmqhReleasePacketsToPacketPool(&s->slot_pre_pq); - - SCMutexLock(&s->slot_post_pq.mutex_q); - TmqhReleasePacketsToPacketPool(&s->slot_post_pq); - SCMutexUnlock(&s->slot_post_pq.mutex_q); - - TmThreadsSetFlag(tv, THV_FAILED); - return TM_ECODE_FAILED; - } - - /* handle new packets */ - while (s->slot_pre_pq.top != NULL) { - extra_p = PacketDequeue(&s->slot_pre_pq); - if (unlikely(extra_p == NULL)) - continue; - - /* see if we need to process the packet */ - if (s->slot_next != NULL) { - r = TmThreadsSlotVarRun(tv, extra_p, s->slot_next); - if (unlikely(r == TM_ECODE_FAILED)) { - TmqhReleasePacketsToPacketPool(&s->slot_pre_pq); - - SCMutexLock(&s->slot_post_pq.mutex_q); - TmqhReleasePacketsToPacketPool(&s->slot_post_pq); - SCMutexUnlock(&s->slot_post_pq.mutex_q); - - TmqhOutputPacketpool(tv, extra_p); - TmThreadsSetFlag(tv, THV_FAILED); - return TM_ECODE_FAILED; - } - } - tv->tmqh_out(tv, extra_p); - } - } - - return TM_ECODE_OK; -} - -/** \internal - * - * \brief Process flow timeout packets - * - * Process flow timeout pseudo packets. During shutdown this loop - * is run until the flow engine kills the thread and the queue is - * empty. - */ -static int TmThreadTimeoutLoop(ThreadVars *tv, TmSlot *s) -{ - TmSlot *stream_slot = NULL, *slot = NULL; - int run = 1; - int r = TM_ECODE_OK; - - for (slot = s; slot != NULL; slot = slot->slot_next) { - if (slot->tm_id == TMM_STREAMTCP) { - stream_slot = slot; - break; - } - } - - if (tv->stream_pq == NULL || stream_slot == NULL) - return r; - - SCLogDebug("flow end loop starting"); - while(run) { - Packet *p; - if (tv->stream_pq->len != 0) { - SCMutexLock(&tv->stream_pq->mutex_q); - p = PacketDequeue(tv->stream_pq); - SCMutexUnlock(&tv->stream_pq->mutex_q); - BUG_ON(p == NULL); - - if ((r = TmThreadsSlotProcessPkt(tv, stream_slot, p) != TM_ECODE_OK)) { - if (r == TM_ECODE_FAILED) - run = 0; - } - } else { - usleep(1); - } - - if (tv->stream_pq->len == 0 && TmThreadsCheckFlag(tv, THV_KILL)) { - run = 0; - } - } - SCLogDebug("flow end loop complete"); - - return r; -} - -/* - - pcap/nfq - - pkt read - callback - process_pkt - - pfring - - pkt read - process_pkt - - slot: - setup - - pkt_ack_loop(tv, slot_data) - - deinit - - process_pkt: - while(s) - run s; - queue; - - */ - -void *TmThreadsSlotPktAcqLoop(void *td) -{ - /* block usr2. usr2 to be handled by the main thread only */ - UtilSignalBlock(SIGUSR2); - - ThreadVars *tv = (ThreadVars *)td; - TmSlot *s = tv->tm_slots; - char run = 1; - TmEcode r = TM_ECODE_OK; - TmSlot *slot = NULL; - - /* Set the thread name */ - if (SCSetThreadName(tv->name) < 0) { - SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name"); - } - - if (tv->thread_setup_flags != 0) - TmThreadSetupOptions(tv); - - /* Drop the capabilities for this thread */ - SCDropCaps(tv); - - PacketPoolInit(); - - /* check if we are setup properly */ - if (s == NULL || s->PktAcqLoop == NULL || tv->tmqh_in == NULL || tv->tmqh_out == NULL) { - SCLogError(SC_ERR_FATAL, "TmSlot or ThreadVars badly setup: s=%p," - " PktAcqLoop=%p, tmqh_in=%p," - " tmqh_out=%p", - s, s ? s->PktAcqLoop : NULL, tv->tmqh_in, tv->tmqh_out); - EngineKill(); - - TmThreadsSetFlag(tv, THV_CLOSED | THV_RUNNING_DONE); - pthread_exit((void *) -1); - return NULL; - } - - for (slot = s; slot != NULL; slot = slot->slot_next) { - if (slot->SlotThreadInit != NULL) { - void *slot_data = NULL; - r = slot->SlotThreadInit(tv, slot->slot_initdata, &slot_data); - if (r != TM_ECODE_OK) { - if (r == TM_ECODE_DONE) { - EngineDone(); - TmThreadsSetFlag(tv, THV_CLOSED | THV_INIT_DONE | THV_RUNNING_DONE); - goto error; - } else { - EngineKill(); - TmThreadsSetFlag(tv, THV_CLOSED | THV_RUNNING_DONE); - goto error; - } - } - (void)SC_ATOMIC_SET(slot->slot_data, slot_data); - } - memset(&slot->slot_pre_pq, 0, sizeof(PacketQueue)); - SCMutexInit(&slot->slot_pre_pq.mutex_q, NULL); - memset(&slot->slot_post_pq, 0, sizeof(PacketQueue)); - SCMutexInit(&slot->slot_post_pq.mutex_q, NULL); - - /* get the 'pre qeueue' from module before the stream module */ - if (slot->slot_next != NULL && slot->slot_next->tm_id == TMM_STREAMTCP) { - SCLogDebug("pre-stream packetqueue %p (postq)", &s->slot_post_pq); - tv->stream_pq = &slot->slot_post_pq; - /* if the stream module is the first, get the threads input queue */ - } else if (slot == (TmSlot *)tv->tm_slots && slot->tm_id == TMM_STREAMTCP) { - tv->stream_pq = &trans_q[tv->inq->id]; - SCLogDebug("pre-stream packetqueue %p (inq)", &slot->slot_pre_pq); - } - } - - StatsSetupPrivate(tv); - - TmThreadsSetFlag(tv, THV_INIT_DONE); - - while(run) { - if (TmThreadsCheckFlag(tv, THV_PAUSE)) { - TmThreadsSetFlag(tv, THV_PAUSED); - TmThreadTestThreadUnPaused(tv); - TmThreadsUnsetFlag(tv, THV_PAUSED); - } - - r = s->PktAcqLoop(tv, SC_ATOMIC_GET(s->slot_data), s); - - if (r == TM_ECODE_FAILED || TmThreadsCheckFlag(tv, THV_KILL_PKTACQ) - || suricata_ctl_flags) { - run = 0; - } - if (r == TM_ECODE_DONE) { - run = 0; - } - } - StatsSyncCounters(tv); - - TmThreadsSetFlag(tv, THV_FLOW_LOOP); - - /* process all pseudo packets the flow timeout may throw at us */ - TmThreadTimeoutLoop(tv, s); - - TmThreadsSetFlag(tv, THV_RUNNING_DONE); - TmThreadWaitForFlag(tv, THV_DEINIT); - - PacketPoolDestroy(); - - for (slot = s; slot != NULL; slot = slot->slot_next) { - if (slot->SlotThreadExitPrintStats != NULL) { - slot->SlotThreadExitPrintStats(tv, SC_ATOMIC_GET(slot->slot_data)); - } - - if (slot->SlotThreadDeinit != NULL) { - r = slot->SlotThreadDeinit(tv, SC_ATOMIC_GET(slot->slot_data)); - if (r != TM_ECODE_OK) { - TmThreadsSetFlag(tv, THV_CLOSED); - goto error; - } - } - - BUG_ON(slot->slot_pre_pq.len); - BUG_ON(slot->slot_post_pq.len); - } - - tv->stream_pq = NULL; - SCLogDebug("%s ending", tv->name); - TmThreadsSetFlag(tv, THV_CLOSED); - pthread_exit((void *) 0); - return NULL; - -error: - tv->stream_pq = NULL; - pthread_exit((void *) -1); - return NULL; -} - - -/** - * \todo Only the first "slot" currently makes the "post_pq" available - * to the thread module. - */ -void *TmThreadsSlotVar(void *td) -{ - /* block usr2. usr2 to be handled by the main thread only */ - UtilSignalBlock(SIGUSR2); - - ThreadVars *tv = (ThreadVars *)td; - TmSlot *s = (TmSlot *)tv->tm_slots; - Packet *p = NULL; - char run = 1; - TmEcode r = TM_ECODE_OK; - - PacketPoolInitEmpty(); - - /* Set the thread name */ - if (SCSetThreadName(tv->name) < 0) { - SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name"); - } - - if (tv->thread_setup_flags != 0) - TmThreadSetupOptions(tv); - - /* Drop the capabilities for this thread */ - SCDropCaps(tv); - - /* check if we are setup properly */ - if (s == NULL || tv->tmqh_in == NULL || tv->tmqh_out == NULL) { - EngineKill(); - - TmThreadsSetFlag(tv, THV_CLOSED | THV_RUNNING_DONE); - pthread_exit((void *) -1); - return NULL; - } - - for (; s != NULL; s = s->slot_next) { - if (s->SlotThreadInit != NULL) { - void *slot_data = NULL; - r = s->SlotThreadInit(tv, s->slot_initdata, &slot_data); - if (r != TM_ECODE_OK) { - EngineKill(); - - TmThreadsSetFlag(tv, THV_CLOSED | THV_RUNNING_DONE); - goto error; - } - (void)SC_ATOMIC_SET(s->slot_data, slot_data); - } - memset(&s->slot_pre_pq, 0, sizeof(PacketQueue)); - SCMutexInit(&s->slot_pre_pq.mutex_q, NULL); - memset(&s->slot_post_pq, 0, sizeof(PacketQueue)); - SCMutexInit(&s->slot_post_pq.mutex_q, NULL); - - /* special case: we need to access the stream queue - * from the flow timeout code */ - - /* get the 'pre qeueue' from module before the stream module */ - if (s->slot_next != NULL && s->slot_next->tm_id == TMM_STREAMTCP) { - SCLogDebug("pre-stream packetqueue %p (preq)", &s->slot_pre_pq); - tv->stream_pq = &s->slot_pre_pq; - /* if the stream module is the first, get the threads input queue */ - } else if (s == (TmSlot *)tv->tm_slots && s->tm_id == TMM_STREAMTCP) { - tv->stream_pq = &trans_q[tv->inq->id]; - SCLogDebug("pre-stream packetqueue %p (inq)", &s->slot_pre_pq); - } - } - - StatsSetupPrivate(tv); - - TmThreadsSetFlag(tv, THV_INIT_DONE); - - s = (TmSlot *)tv->tm_slots; - - while (run) { - if (TmThreadsCheckFlag(tv, THV_PAUSE)) { - TmThreadsSetFlag(tv, THV_PAUSED); - TmThreadTestThreadUnPaused(tv); - TmThreadsUnsetFlag(tv, THV_PAUSED); - } - - /* input a packet */ - p = tv->tmqh_in(tv); - - if (p != NULL) { - /* run the thread module(s) */ - r = TmThreadsSlotVarRun(tv, p, s); - if (r == TM_ECODE_FAILED) { - TmqhOutputPacketpool(tv, p); - TmThreadsSetFlag(tv, THV_FAILED); - break; - } - - /* output the packet */ - tv->tmqh_out(tv, p); - - } /* if (p != NULL) */ - - /* now handle the post_pq packets */ - TmSlot *slot; - for (slot = s; slot != NULL; slot = slot->slot_next) { - if (slot->slot_post_pq.top != NULL) { - while (1) { - SCMutexLock(&slot->slot_post_pq.mutex_q); - Packet *extra_p = PacketDequeue(&slot->slot_post_pq); - SCMutexUnlock(&slot->slot_post_pq.mutex_q); - - if (extra_p == NULL) - break; - - if (slot->slot_next != NULL) { - r = TmThreadsSlotVarRun(tv, extra_p, slot->slot_next); - if (r == TM_ECODE_FAILED) { - SCMutexLock(&slot->slot_post_pq.mutex_q); - TmqhReleasePacketsToPacketPool(&slot->slot_post_pq); - SCMutexUnlock(&slot->slot_post_pq.mutex_q); - - TmqhOutputPacketpool(tv, extra_p); - TmThreadsSetFlag(tv, THV_FAILED); - break; - } - } - /* output the packet */ - tv->tmqh_out(tv, extra_p); - } /* while */ - } /* if */ - } /* for */ - - if (TmThreadsCheckFlag(tv, THV_KILL)) { - run = 0; - } - } /* while (run) */ - StatsSyncCounters(tv); - - TmThreadsSetFlag(tv, THV_RUNNING_DONE); - TmThreadWaitForFlag(tv, THV_DEINIT); - - PacketPoolDestroy(); - - s = (TmSlot *)tv->tm_slots; - - for ( ; s != NULL; s = s->slot_next) { - if (s->SlotThreadExitPrintStats != NULL) { - s->SlotThreadExitPrintStats(tv, SC_ATOMIC_GET(s->slot_data)); - } - - if (s->SlotThreadDeinit != NULL) { - r = s->SlotThreadDeinit(tv, SC_ATOMIC_GET(s->slot_data)); - if (r != TM_ECODE_OK) { - TmThreadsSetFlag(tv, THV_CLOSED); - goto error; - } - } - BUG_ON(s->slot_pre_pq.len); - BUG_ON(s->slot_post_pq.len); - } - - SCLogDebug("%s ending", tv->name); - tv->stream_pq = NULL; - TmThreadsSetFlag(tv, THV_CLOSED); - pthread_exit((void *) 0); - return NULL; - -error: - tv->stream_pq = NULL; - pthread_exit((void *) -1); - return NULL; -} - -static void *TmThreadsManagement(void *td) -{ - /* block usr2. usr2 to be handled by the main thread only */ - UtilSignalBlock(SIGUSR2); - - ThreadVars *tv = (ThreadVars *)td; - TmSlot *s = (TmSlot *)tv->tm_slots; - TmEcode r = TM_ECODE_OK; - - BUG_ON(s == NULL); - - /* Set the thread name */ - if (SCSetThreadName(tv->name) < 0) { - SCLogWarning(SC_ERR_THREAD_INIT, "Unable to set thread name"); - } - - if (tv->thread_setup_flags != 0) - TmThreadSetupOptions(tv); - - /* Drop the capabilities for this thread */ - SCDropCaps(tv); - - SCLogDebug("%s starting", tv->name); - - if (s->SlotThreadInit != NULL) { - void *slot_data = NULL; - r = s->SlotThreadInit(tv, s->slot_initdata, &slot_data); - if (r != TM_ECODE_OK) { - EngineKill(); - - TmThreadsSetFlag(tv, THV_CLOSED | THV_RUNNING_DONE); - pthread_exit((void *) -1); - return NULL; - } - (void)SC_ATOMIC_SET(s->slot_data, slot_data); - } - memset(&s->slot_pre_pq, 0, sizeof(PacketQueue)); - memset(&s->slot_post_pq, 0, sizeof(PacketQueue)); - - StatsSetupPrivate(tv); - - TmThreadsSetFlag(tv, THV_INIT_DONE); - - r = s->Management(tv, SC_ATOMIC_GET(s->slot_data)); - /* handle error */ - if (r == TM_ECODE_FAILED) { - TmThreadsSetFlag(tv, THV_FAILED); - } - - if (TmThreadsCheckFlag(tv, THV_KILL)) { - StatsSyncCounters(tv); - } - - TmThreadsSetFlag(tv, THV_RUNNING_DONE); - TmThreadWaitForFlag(tv, THV_DEINIT); - - if (s->SlotThreadExitPrintStats != NULL) { - s->SlotThreadExitPrintStats(tv, SC_ATOMIC_GET(s->slot_data)); - } - - if (s->SlotThreadDeinit != NULL) { - r = s->SlotThreadDeinit(tv, SC_ATOMIC_GET(s->slot_data)); - if (r != TM_ECODE_OK) { - TmThreadsSetFlag(tv, THV_CLOSED); - pthread_exit((void *) -1); - return NULL; - } - } - - TmThreadsSetFlag(tv, THV_CLOSED); - pthread_exit((void *) 0); - return NULL; -} - -/** - * \brief We set the slot functions. - * - * \param tv Pointer to the TV to set the slot function for. - * \param name Name of the slot variant. - * \param fn_p Pointer to a custom slot function. Used only if slot variant - * "name" is "custom". - * - * \retval TmEcode TM_ECODE_OK on success; TM_ECODE_FAILED on failure. - */ -TmEcode TmThreadSetSlots(ThreadVars *tv, char *name, void *(*fn_p)(void *)) -{ - if (name == NULL) { - if (fn_p == NULL) { - printf("Both slot name and function pointer can't be NULL inside " - "TmThreadSetSlots\n"); - goto error; - } else { - name = "custom"; - } - } - - if (strcmp(name, "varslot") == 0) { - tv->tm_func = TmThreadsSlotVar; - } else if (strcmp(name, "pktacqloop") == 0) { - tv->tm_func = TmThreadsSlotPktAcqLoop; - } else if (strcmp(name, "management") == 0) { - tv->tm_func = TmThreadsManagement; - } else if (strcmp(name, "command") == 0) { - tv->tm_func = TmThreadsManagement; - } else if (strcmp(name, "custom") == 0) { - if (fn_p == NULL) - goto error; - tv->tm_func = fn_p; - } else { - printf("Error: Slot \"%s\" not supported\n", name); - goto error; - } - - return TM_ECODE_OK; - -error: - return TM_ECODE_FAILED; -} - -ThreadVars *TmThreadsGetTVContainingSlot(TmSlot *tm_slot) -{ - ThreadVars *tv; - int i; - - SCMutexLock(&tv_root_lock); - - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - - while (tv) { - TmSlot *slots = tv->tm_slots; - while (slots != NULL) { - if (slots == tm_slot) { - SCMutexUnlock(&tv_root_lock); - return tv; - } - slots = slots->slot_next; - } - tv = tv->next; - } - } - - SCMutexUnlock(&tv_root_lock); - - return NULL; -} - -/** - * \brief Appends a new entry to the slots. - * - * \param tv TV the slot is attached to. - * \param tm TM to append. - * \param data Data to be passed on to the slot init function. - * - * \retval The allocated TmSlot or NULL if there is an error - */ -static inline TmSlot * _TmSlotSetFuncAppend(ThreadVars *tv, TmModule *tm, void *data) -{ - TmSlot *slot = SCMalloc(sizeof(TmSlot)); - if (unlikely(slot == NULL)) - return NULL; - memset(slot, 0, sizeof(TmSlot)); - SC_ATOMIC_INIT(slot->slot_data); - slot->tv = tv; - slot->SlotThreadInit = tm->ThreadInit; - slot->slot_initdata = data; - SC_ATOMIC_INIT(slot->SlotFunc); - (void)SC_ATOMIC_SET(slot->SlotFunc, tm->Func); - slot->PktAcqLoop = tm->PktAcqLoop; - slot->Management = tm->Management; - slot->SlotThreadExitPrintStats = tm->ThreadExitPrintStats; - slot->SlotThreadDeinit = tm->ThreadDeinit; - /* we don't have to check for the return value "-1". We wouldn't have - * received a TM as arg, if it didn't exist */ - slot->tm_id = TmModuleGetIDForTM(tm); - - tv->tmm_flags |= tm->flags; - tv->cap_flags |= tm->cap_flags; - - if (tv->tm_slots == NULL) { - tv->tm_slots = slot; - slot->id = 0; - } else { - TmSlot *a = (TmSlot *)tv->tm_slots, *b = NULL; - - /* get the last slot */ - for ( ; a != NULL; a = a->slot_next) { - b = a; - } - /* append the new slot */ - if (b != NULL) { - b->slot_next = slot; - slot->id = b->id + 1; - } - } - - return slot; -} - -void TmSlotFree(TmSlot *tms) -{ - SC_ATOMIC_DESTROY(tms->slot_data); - SCFree(tms); -} - -/** - * \brief Appends a new entry to the slots. - * - * \param tv TV the slot is attached to. - * \param tm TM to append. - * \param data Data to be passed on to the slot init function. - */ -void TmSlotSetFuncAppend(ThreadVars *tv, TmModule *tm, void *data) -{ - _TmSlotSetFuncAppend(tv, tm, data); -} - -/** - * \brief Returns the slot holding a TM with the particular tm_id. - * - * \param tm_id TM id of the TM whose slot has to be returned. - * - * \retval slots Pointer to the slot. - */ -TmSlot *TmSlotGetSlotForTM(int tm_id) -{ - ThreadVars *tv = NULL; - TmSlot *slots; - int i; - - SCMutexLock(&tv_root_lock); - - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - while (tv) { - slots = tv->tm_slots; - while (slots != NULL) { - if (slots->tm_id == tm_id) { - SCMutexUnlock(&tv_root_lock); - return slots; - } - slots = slots->slot_next; - } - tv = tv->next; - } - } - - SCMutexUnlock(&tv_root_lock); - - return NULL; -} - -#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ -static int SetCPUAffinitySet(cpu_set_t *cs) -{ -#if defined OS_FREEBSD - int r = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, - SCGetThreadIdLong(), sizeof(cpu_set_t),cs); -#elif OS_DARWIN - int r = thread_policy_set(mach_thread_self(), THREAD_AFFINITY_POLICY, - (void*)cs, THREAD_AFFINITY_POLICY_COUNT); -#else - pid_t tid = syscall(SYS_gettid); - int r = sched_setaffinity(tid, sizeof(cpu_set_t), cs); -#endif /* OS_FREEBSD */ - - if (r != 0) { - printf("Warning: sched_setaffinity failed (%" PRId32 "): %s\n", r, - strerror(errno)); - return -1; - } - - return 0; -} -#endif - - -/** - * \brief Set the thread affinity on the calling thread. - * - * \param cpuid Id of the core/cpu to setup the affinity. - * - * \retval 0 If all goes well; -1 if something is wrong. - */ -static int SetCPUAffinity(uint16_t cpuid) -{ -#if defined __OpenBSD__ - return 0; -#else - int cpu = (int)cpuid; - -#if defined OS_WIN32 || defined __CYGWIN__ - DWORD cs = 1 << cpu; - - int r = (0 == SetThreadAffinityMask(GetCurrentThread(), cs)); - if (r != 0) { - printf("Warning: sched_setaffinity failed (%" PRId32 "): %s\n", r, - strerror(errno)); - return -1; - } - SCLogDebug("CPU Affinity for thread %lu set to CPU %" PRId32, - SCGetThreadIdLong(), cpu); - - return 0; - -#else - cpu_set_t cs; - - CPU_ZERO(&cs); - CPU_SET(cpu, &cs); - return SetCPUAffinitySet(&cs); -#endif /* windows */ -#endif /* not supported */ -} - - -/** - * \brief Set the thread options (thread priority). - * - * \param tv Pointer to the ThreadVars to setup the thread priority. - * - * \retval TM_ECODE_OK. - */ -TmEcode TmThreadSetThreadPriority(ThreadVars *tv, int prio) -{ - tv->thread_setup_flags |= THREAD_SET_PRIORITY; - tv->thread_priority = prio; - - return TM_ECODE_OK; -} - -/** - * \brief Adjusting nice value for threads. - */ -void TmThreadSetPrio(ThreadVars *tv) -{ - SCEnter(); -#ifndef __CYGWIN__ -#ifdef OS_WIN32 - if (0 == SetThreadPriority(GetCurrentThread(), tv->thread_priority)) { - SCLogError(SC_ERR_THREAD_NICE_PRIO, "Error setting priority for " - "thread %s: %s", tv->name, strerror(errno)); - } else { - SCLogDebug("Priority set to %"PRId32" for thread %s", - tv->thread_priority, tv->name); - } -#else - int ret = nice(tv->thread_priority); - if (ret == -1) { - SCLogError(SC_ERR_THREAD_NICE_PRIO, "Error setting nice value " - "for thread %s: %s", tv->name, strerror(errno)); - } else { - SCLogDebug("Nice value set to %"PRId32" for thread %s", - tv->thread_priority, tv->name); - } -#endif /* OS_WIN32 */ -#endif - SCReturn; -} - - -/** - * \brief Set the thread options (cpu affinity). - * - * \param tv pointer to the ThreadVars to setup the affinity. - * \param cpu cpu on which affinity is set. - * - * \retval TM_ECODE_OK - */ -TmEcode TmThreadSetCPUAffinity(ThreadVars *tv, uint16_t cpu) -{ - tv->thread_setup_flags |= THREAD_SET_AFFINITY; - tv->cpu_affinity = cpu; - - return TM_ECODE_OK; -} - - -TmEcode TmThreadSetCPU(ThreadVars *tv, uint8_t type) -{ - if (!threading_set_cpu_affinity) - return TM_ECODE_OK; - - if (type > MAX_CPU_SET) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "invalid cpu type family"); - return TM_ECODE_FAILED; - } - - tv->thread_setup_flags |= THREAD_SET_AFFTYPE; - tv->cpu_affinity = type; - - return TM_ECODE_OK; -} - -int TmThreadGetNbThreads(uint8_t type) -{ - if (type >= MAX_CPU_SET) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "invalid cpu type family"); - return 0; - } - - return thread_affinity[type].nb_threads; -} - -/** - * \brief Set the thread options (cpu affinitythread). - * Priority should be already set by pthread_create. - * - * \param tv pointer to the ThreadVars of the calling thread. - */ -TmEcode TmThreadSetupOptions(ThreadVars *tv) -{ - if (tv->thread_setup_flags & THREAD_SET_AFFINITY) { - SCLogInfo("Setting affinity for \"%s\" Module to cpu/core " - "%"PRIu16", thread id %lu", tv->name, tv->cpu_affinity, - SCGetThreadIdLong()); - SetCPUAffinity(tv->cpu_affinity); - } - -#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ - if (tv->thread_setup_flags & THREAD_SET_PRIORITY) - TmThreadSetPrio(tv); - if (tv->thread_setup_flags & THREAD_SET_AFFTYPE) { - ThreadsAffinityType *taf = &thread_affinity[tv->cpu_affinity]; - if (taf->mode_flag == EXCLUSIVE_AFFINITY) { - int cpu = AffinityGetNextCPU(taf); - SetCPUAffinity(cpu); - /* If CPU is in a set overwrite the default thread prio */ - if (CPU_ISSET(cpu, &taf->lowprio_cpu)) { - tv->thread_priority = PRIO_LOW; - } else if (CPU_ISSET(cpu, &taf->medprio_cpu)) { - tv->thread_priority = PRIO_MEDIUM; - } else if (CPU_ISSET(cpu, &taf->hiprio_cpu)) { - tv->thread_priority = PRIO_HIGH; - } else { - tv->thread_priority = taf->prio; - } - SCLogInfo("Setting prio %d for \"%s\" Module to cpu/core " - "%d, thread id %lu", tv->thread_priority, - tv->name, cpu, SCGetThreadIdLong()); - } else { - SetCPUAffinitySet(&taf->cpu_set); - tv->thread_priority = taf->prio; - SCLogInfo("Setting prio %d for \"%s\" thread " - ", thread id %lu", tv->thread_priority, - tv->name, SCGetThreadIdLong()); - } - TmThreadSetPrio(tv); - } -#endif - - return TM_ECODE_OK; -} - -/** - * \brief Creates and returns the TV instance for a new thread. - * - * \param name Name of this TV instance - * \param inq_name Incoming queue name - * \param inqh_name Incoming queue handler name as set by TmqhSetup() - * \param outq_name Outgoing queue name - * \param outqh_name Outgoing queue handler as set by TmqhSetup() - * \param slots String representation for the slot function to be used - * \param fn_p Pointer to function when \"slots\" is of type \"custom\" - * \param mucond Flag to indicate whether to initialize the condition - * and the mutex variables for this newly created TV. - * - * \retval the newly created TV instance, or NULL on error - */ -ThreadVars *TmThreadCreate(char *name, char *inq_name, char *inqh_name, - char *outq_name, char *outqh_name, char *slots, - void * (*fn_p)(void *), int mucond) -{ - ThreadVars *tv = NULL; - Tmq *tmq = NULL; - Tmqh *tmqh = NULL; - - SCLogDebug("creating thread \"%s\"...", name); - - /* XXX create separate function for this: allocate a thread container */ - tv = SCMalloc(sizeof(ThreadVars)); - if (unlikely(tv == NULL)) - goto error; - memset(tv, 0, sizeof(ThreadVars)); - - SC_ATOMIC_INIT(tv->flags); - SCMutexInit(&tv->perf_public_ctx.m, NULL); - - tv->name = name; - /* default state for every newly created thread */ - TmThreadsSetFlag(tv, THV_PAUSE); - TmThreadsSetFlag(tv, THV_USE); - /* default aof for every newly created thread */ - tv->aof = THV_RESTART_THREAD; - - /* set the incoming queue */ - if (inq_name != NULL && strcmp(inq_name, "packetpool") != 0) { - SCLogDebug("inq_name \"%s\"", inq_name); - - tmq = TmqGetQueueByName(inq_name); - if (tmq == NULL) { - tmq = TmqCreateQueue(inq_name); - if (tmq == NULL) - goto error; - } - SCLogDebug("tmq %p", tmq); - - tv->inq = tmq; - tv->inq->reader_cnt++; - SCLogDebug("tv->inq %p", tv->inq); - } - if (inqh_name != NULL) { - SCLogDebug("inqh_name \"%s\"", inqh_name); - - tmqh = TmqhGetQueueHandlerByName(inqh_name); - if (tmqh == NULL) - goto error; - - tv->tmqh_in = tmqh->InHandler; - tv->InShutdownHandler = tmqh->InShutdownHandler; - SCLogDebug("tv->tmqh_in %p", tv->tmqh_in); - } - - /* set the outgoing queue */ - if (outqh_name != NULL) { - SCLogDebug("outqh_name \"%s\"", outqh_name); - - tmqh = TmqhGetQueueHandlerByName(outqh_name); - if (tmqh == NULL) - goto error; - - tv->tmqh_out = tmqh->OutHandler; - tv->outqh_name = tmqh->name; - - if (outq_name != NULL && strcmp(outq_name, "packetpool") != 0) { - SCLogDebug("outq_name \"%s\"", outq_name); - - if (tmqh->OutHandlerCtxSetup != NULL) { - tv->outctx = tmqh->OutHandlerCtxSetup(outq_name); - if (tv->outctx == NULL) - goto error; - tv->outq = NULL; - } else { - tmq = TmqGetQueueByName(outq_name); - if (tmq == NULL) { - tmq = TmqCreateQueue(outq_name); - if (tmq == NULL) - goto error; - } - SCLogDebug("tmq %p", tmq); - - tv->outq = tmq; - tv->outctx = NULL; - tv->outq->writer_cnt++; - } - } - } - - if (TmThreadSetSlots(tv, slots, fn_p) != TM_ECODE_OK) { - goto error; - } - - if (mucond != 0) - TmThreadInitMC(tv); - - return tv; - -error: - SCLogError(SC_ERR_THREAD_CREATE, "failed to setup a thread"); - - if (tv != NULL) - SCFree(tv); - return NULL; -} - -/** - * \brief Creates and returns a TV instance for a Packet Processing Thread. - * This function doesn't support custom slots, and hence shouldn't be - * supplied \"custom\" as its slot type. All PPT threads are created - * with a mucond(see TmThreadCreate declaration) of 0. Hence the tv - * conditional variables are not used to kill the thread. - * - * \param name Name of this TV instance - * \param inq_name Incoming queue name - * \param inqh_name Incoming queue handler name as set by TmqhSetup() - * \param outq_name Outgoing queue name - * \param outqh_name Outgoing queue handler as set by TmqhSetup() - * \param slots String representation for the slot function to be used - * - * \retval the newly created TV instance, or NULL on error - */ -ThreadVars *TmThreadCreatePacketHandler(char *name, char *inq_name, - char *inqh_name, char *outq_name, - char *outqh_name, char *slots) -{ - ThreadVars *tv = NULL; - - tv = TmThreadCreate(name, inq_name, inqh_name, outq_name, outqh_name, - slots, NULL, 0); - - if (tv != NULL) { - tv->type = TVT_PPT; - tv->id = TmThreadsRegisterThread(tv, tv->type); - } - - - return tv; -} - -/** - * \brief Creates and returns the TV instance for a Management thread(MGMT). - * This function supports only custom slot functions and hence a - * function pointer should be sent as an argument. - * - * \param name Name of this TV instance - * \param fn_p Pointer to function when \"slots\" is of type \"custom\" - * \param mucond Flag to indicate whether to initialize the condition - * and the mutex variables for this newly created TV. - * - * \retval the newly created TV instance, or NULL on error - */ -ThreadVars *TmThreadCreateMgmtThread(char *name, void *(fn_p)(void *), - int mucond) -{ - ThreadVars *tv = NULL; - - tv = TmThreadCreate(name, NULL, NULL, NULL, NULL, "custom", fn_p, mucond); - - if (tv != NULL) { - tv->type = TVT_MGMT; - tv->id = TmThreadsRegisterThread(tv, tv->type); - TmThreadSetCPU(tv, MANAGEMENT_CPU_SET); - } - - return tv; -} - -/** - * \brief Creates and returns the TV instance for a Management thread(MGMT). - * This function supports only custom slot functions and hence a - * function pointer should be sent as an argument. - * - * \param name Name of this TV instance - * \param module Name of TmModule with MANAGEMENT flag set. - * \param mucond Flag to indicate whether to initialize the condition - * and the mutex variables for this newly created TV. - * - * \retval the newly created TV instance, or NULL on error - */ -ThreadVars *TmThreadCreateMgmtThreadByName(char *name, char *module, - int mucond) -{ - ThreadVars *tv = NULL; - - tv = TmThreadCreate(name, NULL, NULL, NULL, NULL, "management", NULL, mucond); - - if (tv != NULL) { - tv->type = TVT_MGMT; - tv->id = TmThreadsRegisterThread(tv, tv->type); - TmThreadSetCPU(tv, MANAGEMENT_CPU_SET); - - TmModule *m = TmModuleGetByName(module); - if (m) { - TmSlotSetFuncAppend(tv, m, NULL); - } - } - - return tv; -} - -/** - * \brief Creates and returns the TV instance for a Command thread (CMD). - * This function supports only custom slot functions and hence a - * function pointer should be sent as an argument. - * - * \param name Name of this TV instance - * \param module Name of TmModule with COMMAND flag set. - * \param mucond Flag to indicate whether to initialize the condition - * and the mutex variables for this newly created TV. - * - * \retval the newly created TV instance, or NULL on error - */ -ThreadVars *TmThreadCreateCmdThreadByName(char *name, char *module, - int mucond) -{ - ThreadVars *tv = NULL; - - tv = TmThreadCreate(name, NULL, NULL, NULL, NULL, "command", NULL, mucond); - - if (tv != NULL) { - tv->type = TVT_CMD; - tv->id = TmThreadsRegisterThread(tv, tv->type); - TmThreadSetCPU(tv, MANAGEMENT_CPU_SET); - - TmModule *m = TmModuleGetByName(module); - if (m) { - TmSlotSetFuncAppend(tv, m, NULL); - } - } - - return tv; -} - -/** - * \brief Appends this TV to tv_root based on its type - * - * \param type holds the type this TV belongs to. - */ -void TmThreadAppend(ThreadVars *tv, int type) -{ - SCMutexLock(&tv_root_lock); - - if (tv_root[type] == NULL) { - tv_root[type] = tv; - tv->next = NULL; - tv->prev = NULL; - - SCMutexUnlock(&tv_root_lock); - - return; - } - - ThreadVars *t = tv_root[type]; - - while (t) { - if (t->next == NULL) { - t->next = tv; - tv->prev = t; - tv->next = NULL; - break; - } - - t = t->next; - } - - SCMutexUnlock(&tv_root_lock); - - return; -} - -/** - * \brief Removes this TV from tv_root based on its type - * - * \param tv The tv instance to remove from the global tv list. - * \param type Holds the type this TV belongs to. - */ -void TmThreadRemove(ThreadVars *tv, int type) -{ - SCMutexLock(&tv_root_lock); - - if (tv_root[type] == NULL) { - SCMutexUnlock(&tv_root_lock); - - return; - } - - ThreadVars *t = tv_root[type]; - while (t != tv) { - t = t->next; - } - - if (t != NULL) { - if (t->prev != NULL) - t->prev->next = t->next; - if (t->next != NULL) - t->next->prev = t->prev; - - if (t == tv_root[type]) - tv_root[type] = t->next;; - } - - SCMutexUnlock(&tv_root_lock); - - return; -} - -/** - * \brief Kill a thread. - * - * \param tv A ThreadVars instance corresponding to the thread that has to be - * killed. - */ -void TmThreadKillThread(ThreadVars *tv) -{ - int i = 0; - - if (tv == NULL) - return; - - if (tv->inq != NULL) { - /* we wait till we dry out all the inq packets, before we - * kill this thread. Do note that you should have disabled - * packet acquire by now using TmThreadDisableReceiveThreads()*/ - if (!(strlen(tv->inq->name) == strlen("packetpool") && - strcasecmp(tv->inq->name, "packetpool") == 0)) { - PacketQueue *q = &trans_q[tv->inq->id]; - while (q->len != 0) { - usleep(1000); - } - } - } - - /* set the thread flag informing the thread that it needs to be - * terminated */ - TmThreadsSetFlag(tv, THV_KILL); - TmThreadsSetFlag(tv, THV_DEINIT); - - /* to be sure, signal more */ - int cnt = 0; - while (1) { - if (TmThreadsCheckFlag(tv, THV_CLOSED)) { - SCLogDebug("signalled the thread %" PRId32 " times", cnt); - break; - } - - cnt++; - - if (tv->InShutdownHandler != NULL) { - tv->InShutdownHandler(tv); - } - if (tv->inq != NULL) { - for (i = 0; i < (tv->inq->reader_cnt + tv->inq->writer_cnt); i++) { - if (tv->inq->q_type == 0) - SCCondSignal(&trans_q[tv->inq->id].cond_q); - else - SCCondSignal(&data_queues[tv->inq->id].cond_q); - } - SCLogDebug("signalled tv->inq->id %" PRIu32 "", tv->inq->id); - } - - if (tv->ctrl_cond != NULL ) { - pthread_cond_broadcast(tv->ctrl_cond); - } - - usleep(100); - } - - if (tv->outctx != NULL) { - Tmqh *tmqh = TmqhGetQueueHandlerByName(tv->outqh_name); - if (tmqh == NULL) - BUG_ON(1); - - if (tmqh->OutHandlerCtxFree != NULL) { - tmqh->OutHandlerCtxFree(tv->outctx); - } - } - - /* join it */ - pthread_join(tv->t, NULL); - SCLogDebug("thread %s stopped", tv->name); - - return; -} - -/** - * \brief Disable all threads having the specified TMs. - * - * Breaks out of the packet acquisition loop, and bumps - * into the 'flow loop', where it will process packets - * from the flow engine's shutdown handling. - */ -void TmThreadDisableReceiveThreads(void) -{ - /* value in seconds */ -#define THREAD_KILL_MAX_WAIT_TIME 60 - /* value in microseconds */ -#define WAIT_TIME 100 - - double total_wait_time = 0; - - ThreadVars *tv = NULL; - -again: - SCMutexLock(&tv_root_lock); - - /* all receive threads are part of packet processing threads */ - tv = tv_root[TVT_PPT]; - - /* we do have to keep in mind that TVs are arranged in the order - * right from receive to log. The moment we fail to find a - * receive TM amongst the slots in a tv, it indicates we are done - * with all receive threads */ - while (tv) { - int disable = 0; - /* obtain the slots for this TV */ - TmSlot *slots = tv->tm_slots; - while (slots != NULL) { - TmModule *tm = TmModuleGetById(slots->tm_id); - - if (tm->flags & TM_FLAG_RECEIVE_TM) { - disable = 1; - break; - } - - slots = slots->slot_next; - continue; - } - - if (disable) { - if (tv->inq != NULL) { - /* we wait till we dry out all the inq packets, before we - * kill this thread. Do note that you should have disabled - * packet acquire by now using TmThreadDisableReceiveThreads()*/ - if (!(strlen(tv->inq->name) == strlen("packetpool") && - strcasecmp(tv->inq->name, "packetpool") == 0)) { - PacketQueue *q = &trans_q[tv->inq->id]; - if (q->len != 0) { - SCMutexUnlock(&tv_root_lock); - /* don't sleep while holding a lock */ - usleep(1000); - goto again; - } - } - } - - /* we found a receive TV. Send it a KILL_PKTACQ signal. */ - TmThreadsSetFlag(tv, THV_KILL_PKTACQ); - - if (tv->inq != NULL) { - int i; - for (i = 0; i < (tv->inq->reader_cnt + tv->inq->writer_cnt); i++) { - if (tv->inq->q_type == 0) - SCCondSignal(&trans_q[tv->inq->id].cond_q); - else - SCCondSignal(&data_queues[tv->inq->id].cond_q); - } - SCLogDebug("signalled tv->inq->id %" PRIu32 "", tv->inq->id); - } - - /* wait for it to enter the 'flow loop' stage */ - while (!TmThreadsCheckFlag(tv, THV_FLOW_LOOP)) { - usleep(WAIT_TIME); - total_wait_time += WAIT_TIME / 1000000.0; - if (total_wait_time > THREAD_KILL_MAX_WAIT_TIME) { - SCLogError(SC_ERR_FATAL, "Engine unable to " - "disable detect thread - \"%s\". " - "Killing engine", tv->name); - exit(EXIT_FAILURE); - } - } - } - - tv = tv->next; - } - - SCMutexUnlock(&tv_root_lock); - - return; -} - -/** - * \brief Disable all threads having the specified TMs. - */ -void TmThreadDisablePacketThreads(void) -{ - /* value in seconds */ -#define THREAD_KILL_MAX_WAIT_TIME 60 - /* value in microseconds */ -#define WAIT_TIME 100 - - double total_wait_time = 0; - - ThreadVars *tv = NULL; - -again: - SCMutexLock(&tv_root_lock); - - /* all receive threads are part of packet processing threads */ - tv = tv_root[TVT_PPT]; - - /* we do have to keep in mind that TVs are arranged in the order - * right from receive to log. The moment we fail to find a - * receive TM amongst the slots in a tv, it indicates we are done - * with all receive threads */ - while (tv) { - if (tv->inq != NULL) { - /* we wait till we dry out all the inq packets, before we - * kill this thread. Do note that you should have disabled - * packet acquire by now using TmThreadDisableReceiveThreads()*/ - if (!(strlen(tv->inq->name) == strlen("packetpool") && - strcasecmp(tv->inq->name, "packetpool") == 0)) { - PacketQueue *q = &trans_q[tv->inq->id]; - if (q->len != 0) { - SCMutexUnlock(&tv_root_lock); - /* don't sleep while holding a lock */ - usleep(1000); - goto again; - } - } - } - - /* we found our receive TV. Send it a KILL signal. This is all - * we need to do to kill receive threads */ - TmThreadsSetFlag(tv, THV_KILL); - - if (tv->inq != NULL) { - int i; - for (i = 0; i < (tv->inq->reader_cnt + tv->inq->writer_cnt); i++) { - if (tv->inq->q_type == 0) - SCCondSignal(&trans_q[tv->inq->id].cond_q); - else - SCCondSignal(&data_queues[tv->inq->id].cond_q); - } - SCLogDebug("signalled tv->inq->id %" PRIu32 "", tv->inq->id); - } - - while (!TmThreadsCheckFlag(tv, THV_RUNNING_DONE)) { - usleep(WAIT_TIME); - total_wait_time += WAIT_TIME / 1000000.0; - if (total_wait_time > THREAD_KILL_MAX_WAIT_TIME) { - SCLogError(SC_ERR_FATAL, "Engine unable to " - "disable detect thread - \"%s\". " - "Killing engine", tv->name); - exit(EXIT_FAILURE); - } - } - - tv = tv->next; - } - - SCMutexUnlock(&tv_root_lock); - - return; -} - -TmSlot *TmThreadGetFirstTmSlotForPartialPattern(const char *tm_name) -{ - ThreadVars *tv = NULL; - TmSlot *slots = NULL; - - SCMutexLock(&tv_root_lock); - - /* all receive threads are part of packet processing threads */ - tv = tv_root[TVT_PPT]; - - while (tv) { - slots = tv->tm_slots; - - while (slots != NULL) { - TmModule *tm = TmModuleGetById(slots->tm_id); - - char *found = strstr(tm->name, tm_name); - if (found != NULL) - goto end; - - slots = slots->slot_next; - } - - tv = tv->next; - } - - end: - SCMutexUnlock(&tv_root_lock); - return slots; -} - -void TmThreadKillThreadsFamily(int family) -{ - ThreadVars *tv = NULL; - - if ((family < 0) || (family >= TVT_MAX)) - return; - - SCMutexLock(&tv_root_lock); - tv = tv_root[family]; - - while (tv) { - TmThreadKillThread(tv); - - tv = tv->next; - } - SCMutexUnlock(&tv_root_lock); -} - -void TmThreadKillThreads(void) -{ - int i = 0; - - for (i = 0; i < TVT_MAX; i++) { - TmThreadKillThreadsFamily(i); - } - - return; -} - -void TmThreadFree(ThreadVars *tv) -{ - TmSlot *s; - TmSlot *ps; - if (tv == NULL) - return; - - SCLogDebug("Freeing thread '%s'.", tv->name); - - StatsThreadCleanup(tv); - - s = (TmSlot *)tv->tm_slots; - while (s) { - ps = s; - s = s->slot_next; - SCFree(ps); - } - - TmThreadsUnregisterThread(tv->id); - SCFree(tv); -} - -void TmThreadClearThreadsFamily(int family) -{ - ThreadVars *tv = NULL; - ThreadVars *ptv = NULL; - - if ((family < 0) || (family >= TVT_MAX)) - return; - - SCMutexLock(&tv_root_lock); - tv = tv_root[family]; - - while (tv) { - ptv = tv; - tv = tv->next; - TmThreadFree(ptv); - } - tv_root[family] = NULL; - SCMutexUnlock(&tv_root_lock); -} - -/** - * \brief Spawns a thread associated with the ThreadVars instance tv - * - * \retval TM_ECODE_OK on success and TM_ECODE_FAILED on failure - */ -TmEcode TmThreadSpawn(ThreadVars *tv) -{ - pthread_attr_t attr; - if (tv->tm_func == NULL) { - printf("ERROR: no thread function set\n"); - return TM_ECODE_FAILED; - } - - /* Initialize and set thread detached attribute */ - pthread_attr_init(&attr); - - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - - int rc = pthread_create(&tv->t, &attr, tv->tm_func, (void *)tv); - if (rc) { - printf("ERROR; return code from pthread_create() is %" PRId32 "\n", rc); - return TM_ECODE_FAILED; - } - - TmThreadWaitForFlag(tv, THV_INIT_DONE | THV_RUNNING_DONE); - - TmThreadAppend(tv, tv->type); - return TM_ECODE_OK; -} - -/** - * \brief Sets the thread flags for a thread instance(tv) - * - * \param tv Pointer to the thread instance for which the flag has to be set - * \param flags Holds the thread state this thread instance has to be set to - */ -#if 0 -void TmThreadSetFlags(ThreadVars *tv, uint8_t flags) -{ - if (tv != NULL) - tv->flags = flags; - - return; -} -#endif -/** - * \brief Sets the aof(Action on failure) for a thread instance(tv) - * - * \param tv Pointer to the thread instance for which the aof has to be set - * \param aof Holds the aof this thread instance has to be set to - */ -void TmThreadSetAOF(ThreadVars *tv, uint8_t aof) -{ - if (tv != NULL) - tv->aof = aof; - - return; -} - -/** - * \brief Initializes the mutex and condition variables for this TV - * - * It can be used by a thread to control a wait loop that can also be - * influenced by other threads. - * - * \param tv Pointer to a TV instance - */ -void TmThreadInitMC(ThreadVars *tv) -{ - if ( (tv->ctrl_mutex = SCMalloc(sizeof(*tv->ctrl_mutex))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in TmThreadInitMC. " - "Exiting..."); - exit(EXIT_FAILURE); - } - - if (SCCtrlMutexInit(tv->ctrl_mutex, NULL) != 0) { - printf("Error initializing the tv->m mutex\n"); - exit(EXIT_FAILURE); - } - - if ( (tv->ctrl_cond = SCMalloc(sizeof(*tv->ctrl_cond))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in TmThreadInitMC. " - "Exiting..."); - exit(EXIT_FAILURE); - } - - if (SCCtrlCondInit(tv->ctrl_cond, NULL) != 0) { - SCLogError(SC_ERR_FATAL, "Error initializing the tv->cond condition " - "variable"); - exit(EXIT_FAILURE); - } - - return; -} - -/** - * \brief Tests if the thread represented in the arg has been unpaused or not. - * - * The function would return if the thread tv has been unpaused or if the - * kill flag for the thread has been set. - * - * \param tv Pointer to the TV instance. - */ -void TmThreadTestThreadUnPaused(ThreadVars *tv) -{ - while (TmThreadsCheckFlag(tv, THV_PAUSE)) { - usleep(100); - - if (TmThreadsCheckFlag(tv, THV_KILL)) - break; - } - - return; -} - -/** - * \brief Waits till the specified flag(s) is(are) set. We don't bother if - * the kill flag has been set or not on the thread. - * - * \param tv Pointer to the TV instance. - */ -void TmThreadWaitForFlag(ThreadVars *tv, uint16_t flags) -{ - while (!TmThreadsCheckFlag(tv, flags)) { - usleep(100); - } - - return; -} - -/** - * \brief Unpauses a thread - * - * \param tv Pointer to a TV instance that has to be unpaused - */ -void TmThreadContinue(ThreadVars *tv) -{ - TmThreadsUnsetFlag(tv, THV_PAUSE); - - return; -} - -/** - * \brief Unpauses all threads present in tv_root - */ -void TmThreadContinueThreads() -{ - ThreadVars *tv = NULL; - int i = 0; - - SCMutexLock(&tv_root_lock); - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - while (tv != NULL) { - TmThreadContinue(tv); - tv = tv->next; - } - } - SCMutexUnlock(&tv_root_lock); - - return; -} - -/** - * \brief Pauses a thread - * - * \param tv Pointer to a TV instance that has to be paused - */ -void TmThreadPause(ThreadVars *tv) -{ - TmThreadsSetFlag(tv, THV_PAUSE); - - return; -} - -/** - * \brief Pauses all threads present in tv_root - */ -void TmThreadPauseThreads() -{ - ThreadVars *tv = NULL; - int i = 0; - - TmThreadsListThreads(); - - SCMutexLock(&tv_root_lock); - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - while (tv != NULL) { - TmThreadPause(tv); - tv = tv->next; - } - } - SCMutexUnlock(&tv_root_lock); - - return; -} - -/** - * \brief Restarts the thread sent as the argument - * - * \param tv Pointer to the thread instance(tv) to be restarted - */ -static void TmThreadRestartThread(ThreadVars *tv) -{ - if (tv->restarted >= THV_MAX_RESTARTS) { - SCLogError(SC_ERR_TM_THREADS_ERROR,"thread restarts exceeded " - "threshold limit for thread \"%s\"", tv->name); - exit(EXIT_FAILURE); - } - - TmThreadsUnsetFlag(tv, THV_CLOSED); - TmThreadsUnsetFlag(tv, THV_FAILED); - - if (TmThreadSpawn(tv) != TM_ECODE_OK) { - SCLogError(SC_ERR_THREAD_SPAWN, "thread \"%s\" failed to spawn", tv->name); - exit(EXIT_FAILURE); - } - - tv->restarted++; - SCLogInfo("thread \"%s\" restarted", tv->name); - - return; -} - -/** - * \brief Used to check the thread for certain conditions of failure. If the - * thread has been specified to restart on failure, the thread is - * restarted. If the thread has been specified to gracefully shutdown - * the engine on failure, it does so. The global aof flag, tv_aof - * overrides the thread aof flag, if it holds a THV_ENGINE_EXIT; - */ -void TmThreadCheckThreadState(void) -{ - ThreadVars *tv = NULL; - int i = 0; - - SCMutexLock(&tv_root_lock); - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - - while (tv) { - if (TmThreadsCheckFlag(tv, THV_FAILED)) { - TmThreadsSetFlag(tv, THV_DEINIT); - pthread_join(tv->t, NULL); - if ((tv_aof & THV_ENGINE_EXIT) || (tv->aof & THV_ENGINE_EXIT)) { - EngineKill(); - goto end; - } else { - /* if the engine kill-stop has been received by now, chuck - * restarting and return to kill the engine */ - if ((suricata_ctl_flags & SURICATA_KILL) || - (suricata_ctl_flags & SURICATA_STOP)) { - goto end; - } - TmThreadRestartThread(tv); - } - } - tv = tv->next; - } - } -end: - SCMutexUnlock(&tv_root_lock); - return; -} - -/** - * \brief Used to check if all threads have finished their initialization. On - * finding an un-initialized thread, it waits till that thread completes - * its initialization, before proceeding to the next thread. - * - * \retval TM_ECODE_OK all initialized properly - * \retval TM_ECODE_FAILED failure - */ -TmEcode TmThreadWaitOnThreadInit(void) -{ - ThreadVars *tv = NULL; - int i = 0; - uint16_t mgt_num = 0; - uint16_t ppt_num = 0; - - SCMutexLock(&tv_root_lock); - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - while (tv != NULL) { - char started = FALSE; - while (started == FALSE) { - if (TmThreadsCheckFlag(tv, THV_INIT_DONE)) { - started = TRUE; - } else { - /* sleep a little to give the thread some - * time to finish initialization */ - usleep(100); - } - - if (TmThreadsCheckFlag(tv, THV_FAILED)) { - SCMutexUnlock(&tv_root_lock); - SCLogError(SC_ERR_THREAD_INIT, "thread \"%s\" failed to " - "initialize.", tv->name); - return TM_ECODE_FAILED; - } - if (TmThreadsCheckFlag(tv, THV_CLOSED)) { - SCMutexUnlock(&tv_root_lock); - SCLogError(SC_ERR_THREAD_INIT, "thread \"%s\" closed on " - "initialization.", tv->name); - return TM_ECODE_FAILED; - } - } - - if (i == TVT_MGMT) mgt_num++; - else if (i == TVT_PPT) ppt_num++; - - tv = tv->next; - } - } - SCMutexUnlock(&tv_root_lock); - - SCLogNotice("all %"PRIu16" packet processing threads, %"PRIu16" management " - "threads initialized, engine started.", ppt_num, mgt_num); - - return TM_ECODE_OK; -} - -/** - * \brief Returns the TV for the calling thread. - * - * \retval tv Pointer to the ThreadVars instance for the calling thread; - * NULL on no match - */ -ThreadVars *TmThreadsGetCallingThread(void) -{ - pthread_t self = pthread_self(); - ThreadVars *tv = NULL; - int i = 0; - - SCMutexLock(&tv_root_lock); - - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - while (tv) { - if (pthread_equal(self, tv->t)) { - SCMutexUnlock(&tv_root_lock); - return tv; - } - tv = tv->next; - } - } - - SCMutexUnlock(&tv_root_lock); - - return NULL; -} - -/** - * \brief returns a count of all the threads that match the flag - */ -uint32_t TmThreadCountThreadsByTmmFlags(uint8_t flags) -{ - ThreadVars *tv = NULL; - int i = 0; - uint32_t cnt = 0; - - SCMutexLock(&tv_root_lock); - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; - while (tv != NULL) { - if ((tv->tmm_flags & flags) == flags) - cnt++; - - tv = tv->next; - } - } - SCMutexUnlock(&tv_root_lock); - return cnt; -} - -typedef struct Thread_ { - ThreadVars *tv; /**< threadvars structure */ - const char *name; - int type; - int in_use; /**< bool to indicate this is in use */ -} Thread; - -typedef struct Threads_ { - Thread *threads; - size_t threads_size; - int threads_cnt; -} Threads; - -static Threads thread_store = { NULL, 0, 0 }; -static SCMutex thread_store_lock = SCMUTEX_INITIALIZER; - -void TmThreadsListThreads(void) -{ - Thread *t; - size_t s; - - SCMutexLock(&thread_store_lock); - - for (s = 0; s < thread_store.threads_size; s++) { - t = &thread_store.threads[s]; - if (t == NULL || t->in_use == 0) - continue; - SCLogInfo("Thread %"PRIuMAX", %s type %d, tv %p", (uintmax_t)s+1, t->name, t->type, t->tv); - } - - SCMutexUnlock(&thread_store_lock); -} - -#define STEP 32 -/** - * \retval id thread id, or 0 if not found - */ -int TmThreadsRegisterThread(ThreadVars *tv, const int type) -{ - SCMutexLock(&thread_store_lock); - if (thread_store.threads == NULL) { - thread_store.threads = SCCalloc(STEP, sizeof(Thread)); - BUG_ON(thread_store.threads == NULL); - thread_store.threads_size = STEP; - } - - size_t s; - for (s = 0; s < thread_store.threads_size; s++) { - if (thread_store.threads[s].in_use == 0) { - Thread *t = &thread_store.threads[s]; - t->name = tv->name; - t->type = type; - t->tv = tv; - t->in_use = 1; - - SCMutexUnlock(&thread_store_lock); - return (int)(s+1); - } - } - - /* if we get here the array is completely filled */ - void *newmem = SCRealloc(thread_store.threads, ((thread_store.threads_size + STEP) * sizeof(Thread))); - BUG_ON(newmem == NULL); - thread_store.threads = newmem; - memset((uint8_t *)thread_store.threads + (thread_store.threads_size * sizeof(Thread)), 0x00, STEP); - - Thread *t = &thread_store.threads[thread_store.threads_size]; - t->name = tv->name; - t->type = type; - t->tv = tv; - t->in_use = 1; - - s = thread_store.threads_size; - thread_store.threads_size += STEP; - - SCMutexUnlock(&thread_store_lock); - return (int)(s+1); -} -#undef STEP - -void TmThreadsUnregisterThread(const int id) -{ - SCMutexLock(&thread_store_lock); - if (id <= 0 || id > (int)thread_store.threads_size) { - SCMutexUnlock(&thread_store_lock); - return; - } - - /* id is one higher than index */ - int idx = id - 1; - - /* reset thread_id, which serves as clearing the record */ - thread_store.threads[idx].in_use = 0; - - /* check if we have at least one registered thread left */ - size_t s; - for (s = 0; s < thread_store.threads_size; s++) { - Thread *t = &thread_store.threads[s]; - if (t->in_use == 1) { - goto end; - } - } - - /* if we get here no threads are registered */ - SCFree(thread_store.threads); - thread_store.threads = NULL; - thread_store.threads_size = 0; - thread_store.threads_cnt = 0; - -end: - SCMutexUnlock(&thread_store_lock); -} - -/** - * \retval r 1 if packet was accepted, 0 otherwise - * \note if packet was not accepted, it's still the responsibility - * of the caller. - */ -int TmThreadsInjectPacketsById(Packet **packets, const int id) -{ - if (id <= 0 || id > (int)thread_store.threads_size) - return 0; - - int idx = id - 1; - - Thread *t = &thread_store.threads[idx]; - ThreadVars *tv = t->tv; - - if (tv == NULL || tv->stream_pq == NULL) - return 0; - - SCMutexLock(&tv->stream_pq->mutex_q); - while (*packets != NULL) { - PacketEnqueue(tv->stream_pq, *packets); - packets++; - } - SCMutexUnlock(&tv->stream_pq->mutex_q); - - /* wake up listening thread(s) if necessary */ - if (tv->inq != NULL) { - SCCondSignal(&trans_q[tv->inq->id].cond_q); - } - return 1; -} diff --git a/framework/src/suricata/src/tm-threads.h b/framework/src/suricata/src/tm-threads.h deleted file mode 100644 index 397fbd2e..00000000 --- a/framework/src/suricata/src/tm-threads.h +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - */ - -#ifndef __TM_THREADS_H__ -#define __TM_THREADS_H__ - -#include "tmqh-packetpool.h" -#include "tm-threads-common.h" -#include "tm-modules.h" - -#define TM_QUEUE_NAME_MAX 16 -#define TM_THREAD_NAME_MAX 16 - -typedef TmEcode (*TmSlotFunc)(ThreadVars *, Packet *, void *, PacketQueue *, - PacketQueue *); - -typedef struct TmSlot_ { - /* the TV holding this slot */ - ThreadVars *tv; - - /* function pointers */ - SC_ATOMIC_DECLARE(TmSlotFunc, SlotFunc); - - TmEcode (*PktAcqLoop)(ThreadVars *, void *, void *); - - TmEcode (*SlotThreadInit)(ThreadVars *, void *, void **); - void (*SlotThreadExitPrintStats)(ThreadVars *, void *); - TmEcode (*SlotThreadDeinit)(ThreadVars *, void *); - - /* data storage */ - void *slot_initdata; - SC_ATOMIC_DECLARE(void *, slot_data); - - /* queue filled by the SlotFunc with packets that will - * be processed futher _before_ the current packet. - * The locks in the queue are NOT used */ - PacketQueue slot_pre_pq; - - /* queue filled by the SlotFunc with packets that will - * be processed futher _after_ the current packet. The - * locks in the queue are NOT used */ - PacketQueue slot_post_pq; - - /* store the thread module id */ - int tm_id; - - /* slot id, only used my TmVarSlot to know what the first slot is */ - int id; - - /* linked list, only used when you have multiple slots(used by TmVarSlot) */ - struct TmSlot_ *slot_next; - - /* just called once, so not perf critical */ - TmEcode (*Management)(ThreadVars *, void *); - -} TmSlot; - -extern ThreadVars *tv_root[TVT_MAX]; - -extern SCMutex tv_root_lock; - -void TmSlotSetFuncAppend(ThreadVars *, TmModule *, void *); -void TmSlotSetFuncAppendDelayed(ThreadVars *, TmModule *, void *, int delayed); -TmSlot *TmSlotGetSlotForTM(int); - -ThreadVars *TmThreadCreate(char *, char *, char *, char *, char *, char *, - void *(fn_p)(void *), int); -ThreadVars *TmThreadCreatePacketHandler(char *, char *, char *, char *, char *, - char *); -ThreadVars *TmThreadCreateMgmtThread(char *name, void *(fn_p)(void *), int); -ThreadVars *TmThreadCreateMgmtThreadByName(char *name, char *module, - int mucond); -ThreadVars *TmThreadCreateCmdThreadByName(char *name, char *module, - int mucond); -TmEcode TmThreadSpawn(ThreadVars *); -void TmThreadSetFlags(ThreadVars *, uint8_t); -void TmThreadSetAOF(ThreadVars *, uint8_t); -void TmThreadKillThread(ThreadVars *); -void TmThreadKillThreadsFamily(int family); -void TmThreadKillThreads(void); -void TmThreadClearThreadsFamily(int family); -void TmThreadAppend(ThreadVars *, int); -void TmThreadRemove(ThreadVars *, int); - -TmEcode TmThreadSetCPUAffinity(ThreadVars *, uint16_t); -TmEcode TmThreadSetThreadPriority(ThreadVars *, int); -TmEcode TmThreadSetCPU(ThreadVars *, uint8_t); -TmEcode TmThreadSetupOptions(ThreadVars *); -void TmThreadSetPrio(ThreadVars *); -int TmThreadGetNbThreads(uint8_t type); - -void TmThreadInitMC(ThreadVars *); -void TmThreadTestThreadUnPaused(ThreadVars *); -void TmThreadContinue(ThreadVars *); -void TmThreadContinueThreads(void); -void TmThreadPause(ThreadVars *); -void TmThreadPauseThreads(void); -void TmThreadCheckThreadState(void); -TmEcode TmThreadWaitOnThreadInit(void); -ThreadVars *TmThreadsGetCallingThread(void); - -int TmThreadsCheckFlag(ThreadVars *, uint16_t); -void TmThreadsSetFlag(ThreadVars *, uint16_t); -void TmThreadsUnsetFlag(ThreadVars *, uint16_t); -void TmThreadWaitForFlag(ThreadVars *, uint16_t); - -TmEcode TmThreadsSlotVarRun (ThreadVars *tv, Packet *p, TmSlot *slot); - -ThreadVars *TmThreadsGetTVContainingSlot(TmSlot *); -void TmThreadDisablePacketThreads(void); -void TmThreadDisableReceiveThreads(void); -TmSlot *TmThreadGetFirstTmSlotForPartialPattern(const char *); - -uint32_t TmThreadCountThreadsByTmmFlags(uint8_t flags); - -/** - * \brief Process the rest of the functions (if any) and queue. - */ -static inline TmEcode TmThreadsSlotProcessPkt(ThreadVars *tv, TmSlot *s, Packet *p) -{ - TmEcode r = TM_ECODE_OK; - - if (s == NULL) { - tv->tmqh_out(tv, p); - return r; - } - - if (TmThreadsSlotVarRun(tv, p, s) == TM_ECODE_FAILED) { - TmqhOutputPacketpool(tv, p); - TmSlot *slot = s; - while (slot != NULL) { - SCMutexLock(&slot->slot_post_pq.mutex_q); - TmqhReleasePacketsToPacketPool(&slot->slot_post_pq); - SCMutexUnlock(&slot->slot_post_pq.mutex_q); - - slot = slot->slot_next; - } - TmThreadsSetFlag(tv, THV_FAILED); - r = TM_ECODE_FAILED; - - } else { - tv->tmqh_out(tv, p); - - /* post process pq */ - TmSlot *slot = s; - while (slot != NULL) { - if (slot->slot_post_pq.top != NULL) { - while (1) { - SCMutexLock(&slot->slot_post_pq.mutex_q); - Packet *extra_p = PacketDequeue(&slot->slot_post_pq); - SCMutexUnlock(&slot->slot_post_pq.mutex_q); - - if (extra_p == NULL) - break; - - if (slot->slot_next != NULL) { - r = TmThreadsSlotVarRun(tv, extra_p, slot->slot_next); - if (r == TM_ECODE_FAILED) { - SCMutexLock(&slot->slot_post_pq.mutex_q); - TmqhReleasePacketsToPacketPool(&slot->slot_post_pq); - SCMutexUnlock(&slot->slot_post_pq.mutex_q); - - TmqhOutputPacketpool(tv, extra_p); - TmThreadsSetFlag(tv, THV_FAILED); - break; - } - } - tv->tmqh_out(tv, extra_p); - } - } /* if (slot->slot_post_pq.top != NULL) */ - slot = slot->slot_next; - } /* while (slot != NULL) */ - } - - return r; -} - - -void TmThreadsListThreads(void); -int TmThreadsRegisterThread(ThreadVars *tv, const int type); -void TmThreadsUnregisterThread(const int id); -int TmThreadsInjectPacketsById(Packet **, int id); - -#endif /* __TM_THREADS_H__ */ diff --git a/framework/src/suricata/src/tmqh-flow.c b/framework/src/suricata/src/tmqh-flow.c deleted file mode 100644 index c0898ef0..00000000 --- a/framework/src/suricata/src/tmqh-flow.c +++ /dev/null @@ -1,510 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Anoop Saldanha - * - * Simple output queue handler that makes sure all packets of the same flow - * are sent to the same queue. We support different kind of q handlers. Have - * a look at "autofp-scheduler" conf to further undertsand the various q - * handlers we provide. - */ - -#include "suricata.h" -#include "packet-queue.h" -#include "decode.h" -#include "threads.h" -#include "threadvars.h" -#include "tmqh-flow.h" - -#include "tm-queuehandlers.h" - -#include "conf.h" -#include "util-unittest.h" - -Packet *TmqhInputFlow(ThreadVars *t); -void TmqhOutputFlowHash(ThreadVars *t, Packet *p); -void TmqhOutputFlowActivePackets(ThreadVars *t, Packet *p); -void TmqhOutputFlowRoundRobin(ThreadVars *t, Packet *p); -void *TmqhOutputFlowSetupCtx(char *queue_str); -void TmqhOutputFlowFreeCtx(void *ctx); -void TmqhFlowRegisterTests(void); - -void TmqhFlowRegister(void) -{ - tmqh_table[TMQH_FLOW].name = "flow"; - tmqh_table[TMQH_FLOW].InHandler = TmqhInputFlow; - tmqh_table[TMQH_FLOW].OutHandlerCtxSetup = TmqhOutputFlowSetupCtx; - tmqh_table[TMQH_FLOW].OutHandlerCtxFree = TmqhOutputFlowFreeCtx; - tmqh_table[TMQH_FLOW].RegisterTests = TmqhFlowRegisterTests; - - char *scheduler = NULL; - if (ConfGet("autofp-scheduler", &scheduler) == 1) { - if (strcasecmp(scheduler, "round-robin") == 0) { - SCLogInfo("AutoFP mode using \"Round Robin\" flow load balancer"); - tmqh_table[TMQH_FLOW].OutHandler = TmqhOutputFlowRoundRobin; - } else if (strcasecmp(scheduler, "active-packets") == 0) { - SCLogInfo("AutoFP mode using \"Active Packets\" flow load balancer"); - tmqh_table[TMQH_FLOW].OutHandler = TmqhOutputFlowActivePackets; - } else if (strcasecmp(scheduler, "hash") == 0) { - SCLogInfo("AutoFP mode using \"Hash\" flow load balancer"); - tmqh_table[TMQH_FLOW].OutHandler = TmqhOutputFlowHash; - } else { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry \"%s\" " - "for autofp-scheduler in conf. Killing engine.", - scheduler); - exit(EXIT_FAILURE); - } - } else { - SCLogInfo("AutoFP mode using default \"Active Packets\" flow load balancer"); - tmqh_table[TMQH_FLOW].OutHandler = TmqhOutputFlowActivePackets; - } - - return; -} - -/* same as 'simple' */ -Packet *TmqhInputFlow(ThreadVars *tv) -{ - PacketQueue *q = &trans_q[tv->inq->id]; - - StatsSyncCountersIfSignalled(tv); - - SCMutexLock(&q->mutex_q); - if (q->len == 0) { - /* if we have no packets in queue, wait... */ - SCCondWait(&q->cond_q, &q->mutex_q); - } - - if (q->len > 0) { - Packet *p = PacketDequeue(q); - SCMutexUnlock(&q->mutex_q); - return p; - } else { - /* return NULL if we have no pkt. Should only happen on signals. */ - SCMutexUnlock(&q->mutex_q); - return NULL; - } -} - -static int StoreQueueId(TmqhFlowCtx *ctx, char *name) -{ - void *ptmp; - Tmq *tmq = TmqGetQueueByName(name); - if (tmq == NULL) { - tmq = TmqCreateQueue(SCStrdup(name)); - if (tmq == NULL) - return -1; - } - tmq->writer_cnt++; - - uint16_t id = tmq->id; - - if (ctx->queues == NULL) { - ctx->size = 1; - ctx->queues = SCMalloc(ctx->size * sizeof(TmqhFlowMode)); - if (ctx->queues == NULL) { - return -1; - } - memset(ctx->queues, 0, ctx->size * sizeof(TmqhFlowMode)); - } else { - ctx->size++; - ptmp = SCRealloc(ctx->queues, ctx->size * sizeof(TmqhFlowMode)); - if (ptmp == NULL) { - SCFree(ctx->queues); - ctx->queues = NULL; - return -1; - } - ctx->queues = ptmp; - - memset(ctx->queues + (ctx->size - 1), 0, sizeof(TmqhFlowMode)); - } - ctx->queues[ctx->size - 1].q = &trans_q[id]; - SC_ATOMIC_INIT(ctx->queues[ctx->size - 1].total_packets); - SC_ATOMIC_INIT(ctx->queues[ctx->size - 1].total_flows); - - return 0; -} - -/** - * \brief setup the queue handlers ctx - * - * Parses a comma separated string "queuename1,queuename2,etc" - * and sets the ctx up to devide flows over these queue's. - * - * \param queue_str comma separated string with output queue names - * - * \retval ctx queues handlers ctx or NULL in error - */ -void *TmqhOutputFlowSetupCtx(char *queue_str) -{ - if (queue_str == NULL || strlen(queue_str) == 0) - return NULL; - - SCLogDebug("queue_str %s", queue_str); - - TmqhFlowCtx *ctx = SCMalloc(sizeof(TmqhFlowCtx)); - if (unlikely(ctx == NULL)) - return NULL; - memset(ctx,0x00,sizeof(TmqhFlowCtx)); - - char *str = SCStrdup(queue_str); - if (unlikely(str == NULL)) { - goto error; - } - char *tstr = str; - - /* parse the comma separated string */ - do { - char *comma = strchr(tstr,','); - if (comma != NULL) { - *comma = '\0'; - char *qname = tstr; - int r = StoreQueueId(ctx,qname); - if (r < 0) - goto error; - } else { - char *qname = tstr; - int r = StoreQueueId(ctx,qname); - if (r < 0) - goto error; - } - tstr = comma ? (comma + 1) : comma; - } while (tstr != NULL); - - SC_ATOMIC_INIT(ctx->round_robin_idx); - - SCFree(str); - return (void *)ctx; - -error: - SCFree(ctx); - if (str != NULL) - SCFree(str); - return NULL; -} - -void TmqhOutputFlowFreeCtx(void *ctx) -{ - int i; - TmqhFlowCtx *fctx = (TmqhFlowCtx *)ctx; - - SCLogInfo("AutoFP - Total flow handler queues - %" PRIu16, - fctx->size); - for (i = 0; i < fctx->size; i++) { - SCLogInfo("AutoFP - Queue %-2"PRIu32 " - pkts: %-12"PRIu64" flows: %-12"PRIu64, i, - SC_ATOMIC_GET(fctx->queues[i].total_packets), - SC_ATOMIC_GET(fctx->queues[i].total_flows)); - SC_ATOMIC_DESTROY(fctx->queues[i].total_packets); - SC_ATOMIC_DESTROY(fctx->queues[i].total_flows); - } - - SCFree(fctx->queues); - - return; -} - -/** - * \brief select the queue to output in a round robin fashion. - * - * \param tv thread vars - * \param p packet - */ -void TmqhOutputFlowRoundRobin(ThreadVars *tv, Packet *p) -{ - int16_t qid = 0; - - TmqhFlowCtx *ctx = (TmqhFlowCtx *)tv->outctx; - - /* if no flow we use the first queue, - * should be rare */ - if (p->flow != NULL) { - qid = SC_ATOMIC_GET(p->flow->autofp_tmqh_flow_qid); - if (qid == -1) { - qid = SC_ATOMIC_ADD(ctx->round_robin_idx, 1); - if (qid >= ctx->size) { - SC_ATOMIC_RESET(ctx->round_robin_idx); - qid = 0; - } - (void) SC_ATOMIC_ADD(ctx->queues[qid].total_flows, 1); - (void) SC_ATOMIC_SET(p->flow->autofp_tmqh_flow_qid, qid); - } - } else { - qid = ctx->last++; - - if (ctx->last == ctx->size) - ctx->last = 0; - } - (void) SC_ATOMIC_ADD(ctx->queues[qid].total_packets, 1); - - PacketQueue *q = ctx->queues[qid].q; - SCMutexLock(&q->mutex_q); - PacketEnqueue(q, p); - SCCondSignal(&q->cond_q); - SCMutexUnlock(&q->mutex_q); - - return; -} - -/** - * \brief select the queue to output to based on queue lengths. - * - * \param tv thread vars - * \param p packet - */ -void TmqhOutputFlowActivePackets(ThreadVars *tv, Packet *p) -{ - int16_t qid = 0; - - TmqhFlowCtx *ctx = (TmqhFlowCtx *)tv->outctx; - - /* if no flow we use the first queue, - * should be rare */ - if (p->flow != NULL) { - qid = SC_ATOMIC_GET(p->flow->autofp_tmqh_flow_qid); - if (qid == -1) { - uint16_t i = 0; - int lowest_id = 0; - TmqhFlowMode *queues = ctx->queues; - uint32_t lowest = queues[i].q->len; - for (i = 1; i < ctx->size; i++) { - if (queues[i].q->len < lowest) { - lowest = queues[i].q->len; - lowest_id = i; - } - } - qid = lowest_id; - (void) SC_ATOMIC_SET(p->flow->autofp_tmqh_flow_qid, lowest_id); - (void) SC_ATOMIC_ADD(ctx->queues[qid].total_flows, 1); - } - } else { - qid = ctx->last++; - - if (ctx->last == ctx->size) - ctx->last = 0; - } - (void) SC_ATOMIC_ADD(ctx->queues[qid].total_packets, 1); - - PacketQueue *q = ctx->queues[qid].q; - SCMutexLock(&q->mutex_q); - PacketEnqueue(q, p); - SCCondSignal(&q->cond_q); - SCMutexUnlock(&q->mutex_q); - - return; -} - -/** - * \brief select the queue to output based on address hash. - * - * \param tv thread vars. - * \param p packet. - */ -void TmqhOutputFlowHash(ThreadVars *tv, Packet *p) -{ - int16_t qid = 0; - - TmqhFlowCtx *ctx = (TmqhFlowCtx *)tv->outctx; - - /* if no flow we use the first queue, - * should be rare */ - if (p->flow != NULL) { - qid = SC_ATOMIC_GET(p->flow->autofp_tmqh_flow_qid); - if (qid == -1) { -#if __WORDSIZE == 64 - uint64_t addr = (uint64_t)p->flow; -#else - uint32_t addr = (uint32_t)p->flow; -#endif - addr >>= 7; - - /* we don't have to worry about possible overflow, since - * ctx->size will be lesser than 2 ** 31 for sure */ - qid = addr % ctx->size; - (void) SC_ATOMIC_SET(p->flow->autofp_tmqh_flow_qid, qid); - (void) SC_ATOMIC_ADD(ctx->queues[qid].total_flows, 1); - } - } else { - qid = ctx->last++; - - if (ctx->last == ctx->size) - ctx->last = 0; - } - (void) SC_ATOMIC_ADD(ctx->queues[qid].total_packets, 1); - - PacketQueue *q = ctx->queues[qid].q; - SCMutexLock(&q->mutex_q); - PacketEnqueue(q, p); - SCCondSignal(&q->cond_q); - SCMutexUnlock(&q->mutex_q); - - return; -} - -#ifdef UNITTESTS - -static int TmqhOutputFlowSetupCtxTest01(void) -{ - int retval = 0; - Tmq *tmq = NULL; - TmqhFlowCtx *fctx = NULL; - - TmqResetQueues(); - - tmq = TmqCreateQueue("queue1"); - if (tmq == NULL) - goto end; - tmq = TmqCreateQueue("queue2"); - if (tmq == NULL) - goto end; - tmq = TmqCreateQueue("another"); - if (tmq == NULL) - goto end; - tmq = TmqCreateQueue("yetanother"); - if (tmq == NULL) - goto end; - - char *str = "queue1,queue2,another,yetanother"; - void *ctx = TmqhOutputFlowSetupCtx(str); - - if (ctx == NULL) - goto end; - - fctx = (TmqhFlowCtx *)ctx; - - if (fctx->size != 4) - goto end; - - if (fctx->queues == NULL) - goto end; - - if (fctx->queues[0].q != &trans_q[0]) - goto end; - if (fctx->queues[1].q != &trans_q[1]) - goto end; - if (fctx->queues[2].q != &trans_q[2]) - goto end; - if (fctx->queues[3].q != &trans_q[3]) - goto end; - - retval = 1; -end: - if (fctx != NULL) - TmqhOutputFlowFreeCtx(fctx); - TmqResetQueues(); - return retval; -} - -static int TmqhOutputFlowSetupCtxTest02(void) -{ - int retval = 0; - Tmq *tmq = NULL; - TmqhFlowCtx *fctx = NULL; - - TmqResetQueues(); - - tmq = TmqCreateQueue("queue1"); - if (tmq == NULL) - goto end; - tmq = TmqCreateQueue("queue2"); - if (tmq == NULL) - goto end; - tmq = TmqCreateQueue("another"); - if (tmq == NULL) - goto end; - tmq = TmqCreateQueue("yetanother"); - if (tmq == NULL) - goto end; - - char *str = "queue1"; - void *ctx = TmqhOutputFlowSetupCtx(str); - - if (ctx == NULL) - goto end; - - fctx = (TmqhFlowCtx *)ctx; - - if (fctx->size != 1) - goto end; - - if (fctx->queues == NULL) - goto end; - - if (fctx->queues[0].q != &trans_q[0]) - goto end; - - retval = 1; -end: - if (fctx != NULL) - TmqhOutputFlowFreeCtx(fctx); - TmqResetQueues(); - return retval; -} - -static int TmqhOutputFlowSetupCtxTest03(void) -{ - int retval = 0; - TmqhFlowCtx *fctx = NULL; - - TmqResetQueues(); - - char *str = "queue1,queue2,another,yetanother"; - void *ctx = TmqhOutputFlowSetupCtx(str); - - if (ctx == NULL) - goto end; - - fctx = (TmqhFlowCtx *)ctx; - - if (fctx->size != 4) - goto end; - - if (fctx->queues == NULL) - goto end; - - if (fctx->queues[0].q != &trans_q[0]) - goto end; - if (fctx->queues[1].q != &trans_q[1]) - goto end; - if (fctx->queues[2].q != &trans_q[2]) - goto end; - if (fctx->queues[3].q != &trans_q[3]) - goto end; - - retval = 1; -end: - if (fctx != NULL) - TmqhOutputFlowFreeCtx(fctx); - TmqResetQueues(); - return retval; -} - -#endif /* UNITTESTS */ - -void TmqhFlowRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("TmqhOutputFlowSetupCtxTest01", TmqhOutputFlowSetupCtxTest01, 1); - UtRegisterTest("TmqhOutputFlowSetupCtxTest02", TmqhOutputFlowSetupCtxTest02, 1); - UtRegisterTest("TmqhOutputFlowSetupCtxTest03", TmqhOutputFlowSetupCtxTest03, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/tmqh-flow.h b/framework/src/suricata/src/tmqh-flow.h deleted file mode 100644 index ccf92633..00000000 --- a/framework/src/suricata/src/tmqh-flow.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __TMQH_FLOW_H__ -#define __TMQH_FLOW_H__ - -typedef struct TmqhFlowMode_ { - PacketQueue *q; - SC_ATOMIC_DECLARE(uint64_t, total_packets); - SC_ATOMIC_DECLARE(uint64_t, total_flows); -} TmqhFlowMode; - -/** \brief Ctx for the flow queue handler - * \param size number of queues to output to - * \param queues array of queue id's this flow handler outputs to */ -typedef struct TmqhFlowCtx_ { - uint16_t size; - uint16_t last; - - TmqhFlowMode *queues; - - SC_ATOMIC_DECLARE(uint16_t, round_robin_idx); -} TmqhFlowCtx; - -void TmqhFlowRegister (void); -void TmqhFlowRegisterTests(void); - -#endif /* __TMQH_FLOW_H__ */ diff --git a/framework/src/suricata/src/tmqh-nfq.c b/framework/src/suricata/src/tmqh-nfq.c deleted file mode 100644 index 90b9e77a..00000000 --- a/framework/src/suricata/src/tmqh-nfq.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * NFQ Verdict Handler - */ - -#include "suricata-common.h" -#include "packet-queue.h" -#include "decode.h" -#include "threads.h" -#include "threadvars.h" - -#include "tm-queuehandlers.h" - -void TmqhOutputVerdictNfq(ThreadVars *t, Packet *p); - -void TmqhNfqRegister (void) -{ - tmqh_table[TMQH_NFQ].name = "nfq"; - tmqh_table[TMQH_NFQ].InHandler = NULL; - tmqh_table[TMQH_NFQ].OutHandler = TmqhOutputVerdictNfq; -} - -void TmqhOutputVerdictNfq(ThreadVars *t, Packet *p) -{ -/* XXX not scaling */ -#if 0 - PacketQueue *q = &trans_q[p->verdict_q_id]; - - SCMutexLock(&q->mutex_q); - PacketEnqueue(q, p); - SCCondSignal(&q->cond_q); - SCMutexUnlock(&q->mutex_q); -#endif -} - diff --git a/framework/src/suricata/src/tmqh-nfq.h b/framework/src/suricata/src/tmqh-nfq.h deleted file mode 100644 index 50884c88..00000000 --- a/framework/src/suricata/src/tmqh-nfq.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __TMQH_NFQ_H__ -#define __TMQH_NFQ_H__ - -void TmqhNfqRegister (void); - -#endif /* __TMQH_NFQ_H__ */ diff --git a/framework/src/suricata/src/tmqh-packetpool.c b/framework/src/suricata/src/tmqh-packetpool.c deleted file mode 100644 index 75139254..00000000 --- a/framework/src/suricata/src/tmqh-packetpool.c +++ /dev/null @@ -1,599 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Packetpool queue handlers. Packet pool is implemented as a stack. - */ - -#include "suricata.h" -#include "packet-queue.h" -#include "decode.h" -#include "detect.h" -#include "detect-uricontent.h" -#include "threads.h" -#include "threadvars.h" -#include "flow.h" -#include "flow-util.h" -#include "host.h" - -#include "stream.h" -#include "stream-tcp-reassemble.h" - -#include "tm-queuehandlers.h" -#include "tm-threads.h" -#include "tm-modules.h" - -#include "pkt-var.h" - -#include "tmqh-packetpool.h" - -#include "util-debug.h" -#include "util-error.h" -#include "util-profiling.h" -#include "util-device.h" - -/* Number of freed packet to save for one pool before freeing them. */ -#define MAX_PENDING_RETURN_PACKETS 32 -static uint32_t max_pending_return_packets = MAX_PENDING_RETURN_PACKETS; - -#ifdef TLS -__thread PktPool thread_pkt_pool; - -static inline PktPool *GetThreadPacketPool(void) -{ - return &thread_pkt_pool; -} -#else -/* __thread not supported. */ -static pthread_key_t pkt_pool_thread_key; -static SCMutex pkt_pool_thread_key_mutex = SCMUTEX_INITIALIZER; -static int pkt_pool_thread_key_initialized = 0; - -static void PktPoolThreadDestroy(void * buf) -{ - SCFreeAligned(buf); -} - -static void TmqhPacketPoolInit(void) -{ - SCMutexLock(&pkt_pool_thread_key_mutex); - if (pkt_pool_thread_key_initialized) { - /* Key has already been created. */ - SCMutexUnlock(&pkt_pool_thread_key_mutex); - return; - } - - /* Create the pthread Key that is used to look up thread specific - * data buffer. Needs to be created only once. - */ - int r = pthread_key_create(&pkt_pool_thread_key, PktPoolThreadDestroy); - if (r != 0) { - SCLogError(SC_ERR_MEM_ALLOC, "pthread_key_create failed with %d", r); - exit(EXIT_FAILURE); - } - - pkt_pool_thread_key_initialized = 1; - SCMutexUnlock(&pkt_pool_thread_key_mutex); -} - -static PktPool *ThreadPacketPoolCreate(void) -{ - TmqhPacketPoolInit(); - - /* Create a new pool for this thread. */ - PktPool* pool = (PktPool*)SCMallocAligned(sizeof(PktPool), CLS); - if (pool == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "malloc failed"); - exit(EXIT_FAILURE); - } - memset(pool,0x0,sizeof(*pool)); - - int r = pthread_setspecific(pkt_pool_thread_key, pool); - if (r != 0) { - SCLogError(SC_ERR_MEM_ALLOC, "pthread_setspecific failed with %d", r); - exit(EXIT_FAILURE); - } - - return pool; -} - -static inline PktPool *GetThreadPacketPool(void) -{ - PktPool* pool = (PktPool*)pthread_getspecific(pkt_pool_thread_key); - if (pool == NULL) - pool = ThreadPacketPoolCreate(); - - return pool; -} -#endif - -/** - * \brief TmqhPacketpoolRegister - * \initonly - */ -void TmqhPacketpoolRegister (void) -{ - tmqh_table[TMQH_PACKETPOOL].name = "packetpool"; - tmqh_table[TMQH_PACKETPOOL].InHandler = TmqhInputPacketpool; - tmqh_table[TMQH_PACKETPOOL].OutHandler = TmqhOutputPacketpool; -} - -static int PacketPoolIsEmpty(PktPool *pool) -{ - /* Check local stack first. */ - if (pool->head || pool->return_stack.head) - return 0; - - return 1; -} - -void PacketPoolWait(void) -{ - PktPool *my_pool = GetThreadPacketPool(); - - if (PacketPoolIsEmpty(my_pool)) { - SCMutexLock(&my_pool->return_stack.mutex); - SC_ATOMIC_ADD(my_pool->return_stack.sync_now, 1); - SCCondWait(&my_pool->return_stack.cond, &my_pool->return_stack.mutex); - SCMutexUnlock(&my_pool->return_stack.mutex); - } - - while(PacketPoolIsEmpty(my_pool)) - cc_barrier(); -} - -/** \brief Wait until we have the requested ammount of packets in the pool - * - * In some cases waiting for packets is undesirable. Especially when - * a wait would happen under a lock of some kind, other parts of the - * engine could have to wait. - * - * This function only returns when at least N packets are in our pool. - * - * \param n number of packets needed - */ -void PacketPoolWaitForN(int n) -{ - PktPool *my_pool = GetThreadPacketPool(); - Packet *p = NULL; - - while (1) { - int i = 0; - PacketPoolWait(); - - /* count packets in our stack */ - p = my_pool->head; - while (p != NULL) { - if (++i == n) - return; - - p = p->next; - } - - /* continue counting in the return stack */ - if (my_pool->return_stack.head != NULL) { - SCMutexLock(&my_pool->return_stack.mutex); - p = my_pool->return_stack.head; - while (p != NULL) { - if (++i == n) { - SCMutexUnlock(&my_pool->return_stack.mutex); - return; - } - p = p->next; - } - SCMutexUnlock(&my_pool->return_stack.mutex); - - /* or signal that we need packets and wait */ - } else { - SCMutexLock(&my_pool->return_stack.mutex); - SC_ATOMIC_ADD(my_pool->return_stack.sync_now, 1); - SCCondWait(&my_pool->return_stack.cond, &my_pool->return_stack.mutex); - SCMutexUnlock(&my_pool->return_stack.mutex); - } - } -} - -/** \brief a initialized packet - * - * \warning Use *only* at init, not at packet runtime - */ -static void PacketPoolStorePacket(Packet *p) -{ - /* Clear the PKT_ALLOC flag, since that indicates to push back - * onto the ring buffer. */ - p->flags &= ~PKT_ALLOC; - p->pool = GetThreadPacketPool(); - p->ReleasePacket = PacketPoolReturnPacket; - PacketPoolReturnPacket(p); -} - -static void PacketPoolGetReturnedPackets(PktPool *pool) -{ - SCMutexLock(&pool->return_stack.mutex); - /* Move all the packets from the locked return stack to the local stack. */ - pool->head = pool->return_stack.head; - pool->return_stack.head = NULL; - SCMutexUnlock(&pool->return_stack.mutex); -} - -/** \brief Get a new packet from the packet pool - * - * Only allocates from the thread's local stack, or mallocs new packets. - * If the local stack is empty, first move all the return stack packets to - * the local stack. - * \retval Packet pointer, or NULL on failure. - */ -Packet *PacketPoolGetPacket(void) -{ - PktPool *pool = GetThreadPacketPool(); -#ifdef DEBUG_VALIDATION - BUG_ON(pool->initialized == 0); - BUG_ON(pool->destroyed == 1); -#endif /* DEBUG_VALIDATION */ - if (pool->head) { - /* Stack is not empty. */ - Packet *p = pool->head; - pool->head = p->next; - p->pool = pool; - PACKET_REINIT(p); - return p; - } - - /* Local Stack is empty, so check the return stack, which requires - * locking. */ - PacketPoolGetReturnedPackets(pool); - - /* Try to allocate again. Need to check for not empty again, since the - * return stack might have been empty too. - */ - if (pool->head) { - /* Stack is not empty. */ - Packet *p = pool->head; - pool->head = p->next; - p->pool = pool; - PACKET_REINIT(p); - return p; - } - - /* Failed to allocate a packet, so return NULL. */ - /* Optionally, could allocate a new packet here. */ - return NULL; -} - -/** \brief Return packet to Packet pool - * - */ -void PacketPoolReturnPacket(Packet *p) -{ - PktPool *my_pool = GetThreadPacketPool(); - - PACKET_RELEASE_REFS(p); - - PktPool *pool = p->pool; - if (pool == NULL) { - PacketFree(p); - return; - } -#ifdef DEBUG_VALIDATION - BUG_ON(pool->initialized == 0); - BUG_ON(pool->destroyed == 1); - BUG_ON(my_pool->initialized == 0); - BUG_ON(my_pool->destroyed == 1); -#endif /* DEBUG_VALIDATION */ - - if (pool == my_pool) { - /* Push back onto this thread's own stack, so no locking. */ - p->next = my_pool->head; - my_pool->head = p; - } else { - PktPool *pending_pool = my_pool->pending_pool; - if (pending_pool == NULL) { - /* No pending packet, so store the current packet. */ - my_pool->pending_pool = pool; - my_pool->pending_head = p; - my_pool->pending_tail = p; - my_pool->pending_count = 1; - } else if (pending_pool == pool) { - /* Another packet for the pending pool list. */ - p->next = my_pool->pending_head; - my_pool->pending_head = p; - my_pool->pending_count++; - if (SC_ATOMIC_GET(pool->return_stack.sync_now) || my_pool->pending_count > max_pending_return_packets) { - /* Return the entire list of pending packets. */ - SCMutexLock(&pool->return_stack.mutex); - my_pool->pending_tail->next = pool->return_stack.head; - pool->return_stack.head = my_pool->pending_head; - SC_ATOMIC_RESET(pool->return_stack.sync_now); - SCMutexUnlock(&pool->return_stack.mutex); - SCCondSignal(&pool->return_stack.cond); - /* Clear the list of pending packets to return. */ - my_pool->pending_pool = NULL; - my_pool->pending_head = NULL; - my_pool->pending_tail = NULL; - my_pool->pending_count = 0; - } - } else { - /* Push onto return stack for this pool */ - SCMutexLock(&pool->return_stack.mutex); - p->next = pool->return_stack.head; - pool->return_stack.head = p; - SC_ATOMIC_RESET(pool->return_stack.sync_now); - SCMutexUnlock(&pool->return_stack.mutex); - SCCondSignal(&pool->return_stack.cond); - } - } -} - -void PacketPoolInitEmpty(void) -{ -#ifndef TLS - TmqhPacketPoolInit(); -#endif - - PktPool *my_pool = GetThreadPacketPool(); - -#ifdef DEBUG_VALIDATION - BUG_ON(my_pool->initialized); - my_pool->initialized = 1; - my_pool->destroyed = 0; -#endif /* DEBUG_VALIDATION */ - - SCMutexInit(&my_pool->return_stack.mutex, NULL); - SCCondInit(&my_pool->return_stack.cond, NULL); - SC_ATOMIC_INIT(my_pool->return_stack.sync_now); -} - -void PacketPoolInit(void) -{ - extern intmax_t max_pending_packets; - -#ifndef TLS - TmqhPacketPoolInit(); -#endif - - PktPool *my_pool = GetThreadPacketPool(); - -#ifdef DEBUG_VALIDATION - BUG_ON(my_pool->initialized); - my_pool->initialized = 1; - my_pool->destroyed = 0; -#endif /* DEBUG_VALIDATION */ - - SCMutexInit(&my_pool->return_stack.mutex, NULL); - SCCondInit(&my_pool->return_stack.cond, NULL); - SC_ATOMIC_INIT(my_pool->return_stack.sync_now); - - /* pre allocate packets */ - SCLogDebug("preallocating packets... packet size %" PRIuMAX "", - (uintmax_t)SIZE_OF_PACKET); - int i = 0; - for (i = 0; i < max_pending_packets; i++) { - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered while allocating a packet. Exiting..."); - exit(EXIT_FAILURE); - } - PacketPoolStorePacket(p); - } - SCLogInfo("preallocated %"PRIiMAX" packets. Total memory %"PRIuMAX"", - max_pending_packets, (uintmax_t)(max_pending_packets*SIZE_OF_PACKET)); - -} - -void PacketPoolDestroy(void) -{ - Packet *p = NULL; - PktPool *my_pool = GetThreadPacketPool(); - -#ifdef DEBUG_VALIDATION - BUG_ON(my_pool->destroyed); -#endif /* DEBUG_VALIDATION */ - - if (my_pool && my_pool->pending_pool != NULL) { - p = my_pool->pending_head; - while (p) { - Packet *next_p = p->next; - PacketFree(p); - p = next_p; - my_pool->pending_count--; - } -#ifdef DEBUG_VALIDATION - BUG_ON(my_pool->pending_count); -#endif /* DEBUG_VALIDATION */ - my_pool->pending_pool = NULL; - my_pool->pending_head = NULL; - my_pool->pending_tail = NULL; - } - - while ((p = PacketPoolGetPacket()) != NULL) { - PacketFree(p); - } - - SC_ATOMIC_DESTROY(my_pool->return_stack.sync_now); - -#ifdef DEBUG_VALIDATION - my_pool->initialized = 0; - my_pool->destroyed = 1; -#endif /* DEBUG_VALIDATION */ -} - -Packet *TmqhInputPacketpool(ThreadVars *tv) -{ - return PacketPoolGetPacket(); -} - -void TmqhOutputPacketpool(ThreadVars *t, Packet *p) -{ - int proot = 0; - - SCEnter(); - SCLogDebug("Packet %p, p->root %p, alloced %s", p, p->root, p->flags & PKT_ALLOC ? "true" : "false"); - - /** \todo make this a callback - * Release tcp segments. Done here after alerting can use them. */ - if (p->flow != NULL && p->proto == IPPROTO_TCP) { - SCMutexLock(&p->flow->m); - StreamTcpPruneSession(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? - STREAM_TOSERVER : STREAM_TOCLIENT); - SCMutexUnlock(&p->flow->m); - } - - if (IS_TUNNEL_PKT(p)) { - SCLogDebug("Packet %p is a tunnel packet: %s", - p,p->root ? "upper layer" : "tunnel root"); - - /* get a lock to access root packet fields */ - SCMutex *m = p->root ? &p->root->tunnel_mutex : &p->tunnel_mutex; - SCMutexLock(m); - - if (IS_TUNNEL_ROOT_PKT(p)) { - SCLogDebug("IS_TUNNEL_ROOT_PKT == TRUE"); - if (TUNNEL_PKT_TPR(p) == 0) { - SCLogDebug("TUNNEL_PKT_TPR(p) == 0, no more tunnel packet " - "depending on this root"); - /* if this packet is the root and there are no - * more tunnel packets, return it to the pool */ - - /* fall through */ - } else { - SCLogDebug("tunnel root Packet %p: TUNNEL_PKT_TPR(p) > 0, so " - "packets are still depending on this root, setting " - "p->tunnel_verdicted == 1", p); - /* if this is the root and there are more tunnel - * packets, return this to the pool. It's still referenced - * by the tunnel packets, and we will return it - * when we handle them */ - SET_TUNNEL_PKT_VERDICTED(p); - - PACKET_PROFILING_END(p); - SCMutexUnlock(m); - SCReturn; - } - } else { - SCLogDebug("NOT IS_TUNNEL_ROOT_PKT, so tunnel pkt"); - - /* the p->root != NULL here seems unnecessary: IS_TUNNEL_PKT checks - * that p->tunnel_pkt == 1, IS_TUNNEL_ROOT_PKT checks that + - * p->root == NULL. So when we are here p->root can only be - * non-NULL, right? CLANG thinks differently. May be a FP, but - * better safe than sorry. VJ */ - if (p->root != NULL && IS_TUNNEL_PKT_VERDICTED(p->root) && - TUNNEL_PKT_TPR(p) == 1) - { - SCLogDebug("p->root->tunnel_verdicted == 1 && TUNNEL_PKT_TPR(p) == 1"); - /* the root is ready and we are the last tunnel packet, - * lets enqueue them both. */ - TUNNEL_DECR_PKT_TPR_NOLOCK(p); - - /* handle the root */ - SCLogDebug("setting proot = 1 for root pkt, p->root %p " - "(tunnel packet %p)", p->root, p); - proot = 1; - - /* fall through */ - } else { - /* root not ready yet, so get rid of the tunnel pkt only */ - - SCLogDebug("NOT p->root->tunnel_verdicted == 1 && " - "TUNNEL_PKT_TPR(p) == 1 (%" PRIu32 ")", TUNNEL_PKT_TPR(p)); - - TUNNEL_DECR_PKT_TPR_NOLOCK(p); - - /* fall through */ - } - } - SCMutexUnlock(m); - - SCLogDebug("tunnel stuff done, move on (proot %d)", proot); - } - - FlowDeReference(&p->flow); - - /* we're done with the tunnel root now as well */ - if (proot == 1) { - SCLogDebug("getting rid of root pkt... alloc'd %s", p->root->flags & PKT_ALLOC ? "true" : "false"); - - FlowDeReference(&p->root->flow); - - p->root->ReleasePacket(p->root); - p->root = NULL; - } - - PACKET_PROFILING_END(p); - - p->ReleasePacket(p); - - SCReturn; -} - -/** - * \brief Release all the packets in the queue back to the packetpool. Mainly - * used by threads that have failed, and wants to return the packets back - * to the packetpool. - * - * \param pq Pointer to the packetqueue from which the packets have to be - * returned back to the packetpool - * - * \warning this function assumes that the pq does not use locking - */ -void TmqhReleasePacketsToPacketPool(PacketQueue *pq) -{ - Packet *p = NULL; - - if (pq == NULL) - return; - - while ( (p = PacketDequeue(pq)) != NULL) - TmqhOutputPacketpool(NULL, p); - - return; -} - -/** - * \brief Set the max_pending_return_packets value - * - * Set it to the max pending packets value, devided by the number - * of lister threads. Normally, in autofp these are the stream/detect/log - * worker threads. - * - * The max_pending_return_packets value needs to stay below the packet - * pool size of the 'producers' (normally pkt capture threads but also - * flow timeout injection ) to avoid a deadlock where all the 'workers' - * keep packets in their return pools, while the capture thread can't - * continue because its pool is empty. - */ -void PacketPoolPostRunmodes(void) -{ - extern intmax_t max_pending_packets; - - uint32_t threads = TmThreadCountThreadsByTmmFlags(TM_FLAG_DETECT_TM); - if (threads == 0) - return; - if (threads > max_pending_packets) - return; - - uint32_t packets = (max_pending_packets / threads) - 1; - if (packets < max_pending_return_packets) - max_pending_return_packets = packets; - - SCLogDebug("detect threads %u, max packets %u, max_pending_return_packets %u", - threads, (uint)threads, max_pending_return_packets); -} diff --git a/framework/src/suricata/src/tmqh-packetpool.h b/framework/src/suricata/src/tmqh-packetpool.h deleted file mode 100644 index 2b6b90b0..00000000 --- a/framework/src/suricata/src/tmqh-packetpool.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __TMQH_PACKETPOOL_H__ -#define __TMQH_PACKETPOOL_H__ - -#include "decode.h" -#include "threads.h" -#include "util-atomic.h" - - /* Return stack, onto which other threads free packets. */ -typedef struct PktPoolLockedStack_{ - /* linked list of free packets. */ - SCMutex mutex; - SCCondT cond; - SC_ATOMIC_DECLARE(int, sync_now); - Packet *head; -} __attribute__((aligned(CLS))) PktPoolLockedStack; - -typedef struct PktPool_ { - /* link listed of free packets local to this thread. - * No mutex is needed. - */ - Packet *head; - /* Packets waiting (pending) to be returned to the given Packet - * Pool. Accumulate packets for the same pool until a theshold is - * reached, then return them all at once. Keep the head and tail - * to fast insertion of the entire list onto a return stack. - */ - struct PktPool_ *pending_pool; - Packet *pending_head; - Packet *pending_tail; - uint32_t pending_count; - -#ifdef DEBUG_VALIDATION - int initialized; - int destroyed; -#endif /* DEBUG_VALIDATION */ - - /* All members above this point are accessed locally by only one thread, so - * these should live on their own cache line. - */ - - /* Return stack, where other threads put packets that they free that belong - * to this thread. - */ - PktPoolLockedStack return_stack; -} PktPool; - -Packet *TmqhInputPacketpool(ThreadVars *); -void TmqhOutputPacketpool(ThreadVars *, Packet *); -void TmqhReleasePacketsToPacketPool(PacketQueue *); -void TmqhPacketpoolRegister(void); -Packet *PacketPoolGetPacket(void); -void PacketPoolWait(void); -void PacketPoolWaitForN(int n); -void PacketPoolReturnPacket(Packet *p); -void PacketPoolInit(void); -void PacketPoolInitEmpty(void); -void PacketPoolDestroy(void); -void PacketPoolPostRunmodes(void); - -#endif /* __TMQH_PACKETPOOL_H__ */ diff --git a/framework/src/suricata/src/tmqh-ringbuffer.c b/framework/src/suricata/src/tmqh-ringbuffer.c deleted file mode 100644 index 29228e1a..00000000 --- a/framework/src/suricata/src/tmqh-ringbuffer.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * RingBuffer queue handler - */ - -#include "suricata.h" -#include "packet-queue.h" -#include "decode.h" -#include "threads.h" -#include "threadvars.h" - -#include "tm-queuehandlers.h" - -#include "util-ringbuffer.h" - -static RingBuffer8 *ringbuffers[256]; - -Packet *TmqhInputRingBufferMrSw(ThreadVars *t); -void TmqhOutputRingBufferMrSw(ThreadVars *t, Packet *p); -Packet *TmqhInputRingBufferSrSw(ThreadVars *t); -void TmqhOutputRingBufferSrSw(ThreadVars *t, Packet *p); -Packet *TmqhInputRingBufferSrMw(ThreadVars *t); -void TmqhOutputRingBufferSrMw(ThreadVars *t, Packet *p); -void TmqhInputRingBufferShutdownHandler(ThreadVars *); - -/** - * \brief TmqhRingBufferRegister - * \initonly - */ -void TmqhRingBufferRegister (void) -{ - tmqh_table[TMQH_RINGBUFFER_MRSW].name = "ringbuffer_mrsw"; - tmqh_table[TMQH_RINGBUFFER_MRSW].InHandler = TmqhInputRingBufferMrSw; - tmqh_table[TMQH_RINGBUFFER_MRSW].InShutdownHandler = TmqhInputRingBufferShutdownHandler; - tmqh_table[TMQH_RINGBUFFER_MRSW].OutHandler = TmqhOutputRingBufferMrSw; - - tmqh_table[TMQH_RINGBUFFER_SRSW].name = "ringbuffer_srsw"; - tmqh_table[TMQH_RINGBUFFER_SRSW].InHandler = TmqhInputRingBufferSrSw; - tmqh_table[TMQH_RINGBUFFER_SRSW].InShutdownHandler = TmqhInputRingBufferShutdownHandler; - tmqh_table[TMQH_RINGBUFFER_SRSW].OutHandler = TmqhOutputRingBufferSrSw; - - tmqh_table[TMQH_RINGBUFFER_SRMW].name = "ringbuffer_srmw"; - tmqh_table[TMQH_RINGBUFFER_SRMW].InHandler = TmqhInputRingBufferSrMw; - tmqh_table[TMQH_RINGBUFFER_SRMW].InShutdownHandler = TmqhInputRingBufferShutdownHandler; - tmqh_table[TMQH_RINGBUFFER_SRMW].OutHandler = TmqhOutputRingBufferSrMw; - - memset(ringbuffers, 0, sizeof(ringbuffers)); - - int i = 0; - for (i = 0; i < 256; i++) { - ringbuffers[i] = RingBuffer8Init(); - if (ringbuffers[i] == NULL) { - SCLogError(SC_ERR_FATAL, "Error allocating memory to register Ringbuffers. Exiting..."); - exit(EXIT_FAILURE); - } - } -} - -void TmqhRingBufferDestroy (void) -{ - int i = 0; - for (i = 0; i < 256; i++) { - RingBuffer8Destroy(ringbuffers[i]); - } -} - -void TmqhInputRingBufferShutdownHandler(ThreadVars *tv) -{ - if (tv == NULL || tv->inq == NULL) { - return; - } - - RingBuffer8 *rb = ringbuffers[tv->inq->id]; - if (rb == NULL) { - return; - } - - RingBuffer8Shutdown(rb); -} - -Packet *TmqhInputRingBufferMrSw(ThreadVars *t) -{ - RingBuffer8 *rb = ringbuffers[t->inq->id]; - - Packet *p = (Packet *)RingBufferMrSw8Get(rb); - - StatsSyncCountersIfSignalled(t); - - return p; -} - -void TmqhOutputRingBufferMrSw(ThreadVars *t, Packet *p) -{ - RingBuffer8 *rb = ringbuffers[t->outq->id]; - RingBufferMrSw8Put(rb, (void *)p); -} - -Packet *TmqhInputRingBufferSrSw(ThreadVars *t) -{ - RingBuffer8 *rb = ringbuffers[t->inq->id]; - - Packet *p = (Packet *)RingBufferSrSw8Get(rb); - - StatsSyncCountersIfSignalled(t); - - return p; -} - -void TmqhOutputRingBufferSrSw(ThreadVars *t, Packet *p) -{ - RingBuffer8 *rb = ringbuffers[t->outq->id]; - RingBufferSrSw8Put(rb, (void *)p); -} - -Packet *TmqhInputRingBufferSrMw(ThreadVars *t) -{ - RingBuffer8 *rb = ringbuffers[t->inq->id]; - - Packet *p = (Packet *)RingBufferSrMw8Get(rb); - - StatsSyncCountersIfSignalled(t); - - return p; -} - -void TmqhOutputRingBufferSrMw(ThreadVars *t, Packet *p) -{ - RingBuffer8 *rb = ringbuffers[t->outq->id]; - RingBufferSrMw8Put(rb, (void *)p); -} - diff --git a/framework/src/suricata/src/tmqh-ringbuffer.h b/framework/src/suricata/src/tmqh-ringbuffer.h deleted file mode 100644 index f38fce99..00000000 --- a/framework/src/suricata/src/tmqh-ringbuffer.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __TMQH_RINGBUFFER_H__ -#define __TMQH_RINGBUFFER_H__ - -void TmqhRingBufferRegister (void); -void TmqhRingBufferDestroy (void); - -#endif /* __TMQH_RINGBUFFER_H__ */ diff --git a/framework/src/suricata/src/tmqh-simple.c b/framework/src/suricata/src/tmqh-simple.c deleted file mode 100644 index bc09dff3..00000000 --- a/framework/src/suricata/src/tmqh-simple.c +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Simple queue handler - */ - -#include "suricata.h" -#include "packet-queue.h" -#include "decode.h" -#include "threads.h" -#include "threadvars.h" - -#include "tm-queuehandlers.h" - -Packet *TmqhInputSimple(ThreadVars *t); -void TmqhOutputSimple(ThreadVars *t, Packet *p); -void TmqhInputSimpleShutdownHandler(ThreadVars *); - -void TmqhSimpleRegister (void) -{ - tmqh_table[TMQH_SIMPLE].name = "simple"; - tmqh_table[TMQH_SIMPLE].InHandler = TmqhInputSimple; - tmqh_table[TMQH_SIMPLE].InShutdownHandler = TmqhInputSimpleShutdownHandler; - tmqh_table[TMQH_SIMPLE].OutHandler = TmqhOutputSimple; -} - -Packet *TmqhInputSimple(ThreadVars *t) -{ - PacketQueue *q = &trans_q[t->inq->id]; - - StatsSyncCountersIfSignalled(t); - - SCMutexLock(&q->mutex_q); - - if (q->len == 0) { - /* if we have no packets in queue, wait... */ - SCCondWait(&q->cond_q, &q->mutex_q); - } - - if (q->len > 0) { - Packet *p = PacketDequeue(q); - SCMutexUnlock(&q->mutex_q); - return p; - } else { - /* return NULL if we have no pkt. Should only happen on signals. */ - SCMutexUnlock(&q->mutex_q); - return NULL; - } -} - -void TmqhInputSimpleShutdownHandler(ThreadVars *tv) -{ - int i; - - if (tv == NULL || tv->inq == NULL) { - return; - } - - for (i = 0; i < (tv->inq->reader_cnt + tv->inq->writer_cnt); i++) - SCCondSignal(&trans_q[tv->inq->id].cond_q); -} - -void TmqhOutputSimple(ThreadVars *t, Packet *p) -{ - SCLogDebug("Packet %p, p->root %p, alloced %s", p, p->root, p->flags & PKT_ALLOC ? "true":"false"); - - PacketQueue *q = &trans_q[t->outq->id]; - - SCMutexLock(&q->mutex_q); - PacketEnqueue(q, p); - SCCondSignal(&q->cond_q); - SCMutexUnlock(&q->mutex_q); -} - -/*******************************Generic-Q-Handlers*****************************/ - -/** - * \brief Public version of TmqhInputSimple from the tmqh-simple queue - * handler, except that it is a generic version that is directly - * tied to a "SCDQDataQueue" instance(sent as an arg). - * - * Retrieves a data_instance from the queue. If the queue is empty, it - * waits on the queue, till a data_instance is enqueued into the queue - * by some other module. - * - * All references to "data_instance" means a reference to a data structure - * instance that implements the template "struct SCDQGenericQData_". - * - * \param q The SCDQDataQueue instance to wait on. - * - * \retval p The returned packet from the queue. - * \retval data The returned data_instance from the queue. - */ -SCDQGenericQData *TmqhInputSimpleOnQ(SCDQDataQueue *q) -{ - SCMutexLock(&q->mutex_q); - if (q->len == 0) { - /* if we have no packets in queue, wait... */ - SCCondWait(&q->cond_q, &q->mutex_q); - } - - if (q->len > 0) { - SCDQGenericQData *data = SCDQDataDequeue(q); - SCMutexUnlock(&q->mutex_q); - return data; - } else { - /* return NULL if we have no data in the queue. Should only happen - * on signals. */ - SCMutexUnlock(&q->mutex_q); - return NULL; - } -} - -/** - * \brief Public version of TmqhOutputSimple from the tmqh-simple queue - * handler, except that it is a generic version that is directly - * tied to a SCDQDataQueue instance(sent as an arg). - * - * Pumps out a data_instance into the queue. If the queue is empty, it - * waits on the queue, till a data_instance is enqueued into the queue. - * - * All references to "data_instance" means a reference to a data structure - * instance that implements the template "struct SCDQGenericQData_". - * - * \param q The SCDQDataQueue instance to pump the data into. - * \param data The data instance to be enqueued. - */ -void TmqhOutputSimpleOnQ(SCDQDataQueue *q, SCDQGenericQData *data) -{ - SCMutexLock(&q->mutex_q); - SCDQDataEnqueue(q, data); - SCCondSignal(&q->cond_q); - SCMutexUnlock(&q->mutex_q); - - return; -} diff --git a/framework/src/suricata/src/tmqh-simple.h b/framework/src/suricata/src/tmqh-simple.h deleted file mode 100644 index 1d4417b4..00000000 --- a/framework/src/suricata/src/tmqh-simple.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __TMQH_SIMPLE_H__ -#define __TMQH_SIMPLE_H__ - -#include "data-queue.h" - -SCDQGenericQData *TmqhInputSimpleOnQ(SCDQDataQueue *); -void TmqhOutputSimpleOnQ(SCDQDataQueue *, SCDQGenericQData *); - -void TmqhSimpleRegister (void); - -#endif /* __TMQH_SIMPLE_H__ */ diff --git a/framework/src/suricata/src/unix-manager.c b/framework/src/suricata/src/unix-manager.c deleted file mode 100644 index 9357f4c5..00000000 --- a/framework/src/suricata/src/unix-manager.c +++ /dev/null @@ -1,1030 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "unix-manager.h" -#include "detect-engine.h" -#include "tm-threads.h" -#include "runmodes.h" -#include "conf.h" - -#include "util-privs.h" -#include "util-debug.h" -#include "util-signal.h" - -#include -#include -#include - -#ifdef BUILD_UNIX_SOCKET -#include - -// MSG_NOSIGNAL does not exists on OS X -#ifdef OS_DARWIN -# ifndef MSG_NOSIGNAL -# define MSG_NOSIGNAL SO_NOSIGPIPE -# endif -#endif - -#define SOCKET_PATH LOCAL_STATE_DIR "/run/suricata/" -#define SOCKET_FILENAME "suricata-command.socket" -#define SOCKET_TARGET SOCKET_PATH SOCKET_FILENAME - -typedef struct Command_ { - char *name; - TmEcode (*Func)(json_t *, json_t *, void *); - void *data; - int flags; - TAILQ_ENTRY(Command_) next; -} Command; - -typedef struct Task_ { - TmEcode (*Func)(void *); - void *data; - TAILQ_ENTRY(Task_) next; -} Task; - -typedef struct UnixClient_ { - int fd; - TAILQ_ENTRY(UnixClient_) next; -} UnixClient; - -typedef struct UnixCommand_ { - time_t start_timestamp; - int socket; - struct sockaddr_un client_addr; - int select_max; - TAILQ_HEAD(, Command_) commands; - TAILQ_HEAD(, Task_) tasks; - TAILQ_HEAD(, UnixClient_) clients; -} UnixCommand; - -/** - * \brief Create a command unix socket on system - * - * \retval 0 in case of error, 1 in case of success - */ -int UnixNew(UnixCommand * this) -{ - struct sockaddr_un addr; - int len; - int ret; - int on = 1; - char *sockettarget = NULL; - char *socketname; - - this->start_timestamp = time(NULL); - this->socket = -1; - this->select_max = 0; - - TAILQ_INIT(&this->commands); - TAILQ_INIT(&this->tasks); - TAILQ_INIT(&this->clients); - - if (ConfGet("unix-command.filename", &socketname) == 1) { - if (PathIsAbsolute(socketname)) { - sockettarget = SCStrdup(socketname); - if (unlikely(sockettarget == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate socket name"); - return 0; - } - } else { - int socketlen = strlen(SOCKET_PATH) + strlen(socketname) + 2; - sockettarget = SCMalloc(socketlen); - if (unlikely(sockettarget == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate socket name"); - return 0; - } - snprintf(sockettarget, socketlen, "%s/%s", SOCKET_PATH, socketname); - - /* Create socket dir */ - ret = mkdir(SOCKET_PATH, S_IRWXU|S_IXGRP|S_IRGRP); - if ( ret != 0 ) { - int err = errno; - if (err != EEXIST) { - SCFree(sockettarget); - SCLogError(SC_ERR_OPENING_FILE, - "Cannot create socket directory %s: %s", SOCKET_PATH, strerror(err)); - return 0; - } - } - - } - SCLogInfo("Using unix socket file '%s'", sockettarget); - } - if (sockettarget == NULL) { - sockettarget = SCStrdup(SOCKET_TARGET); - if (unlikely(sockettarget == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate socket name"); - return 0; - } - } - - /* Remove socket file */ - (void) unlink(sockettarget); - - /* set address */ - addr.sun_family = AF_UNIX; - strlcpy(addr.sun_path, sockettarget, sizeof(addr.sun_path)); - addr.sun_path[sizeof(addr.sun_path) - 1] = 0; - len = strlen(addr.sun_path) + sizeof(addr.sun_family); - - /* create socket */ - this->socket = socket(AF_UNIX, SOCK_STREAM, 0); - if (this->socket == -1) { - SCLogWarning(SC_ERR_OPENING_FILE, - "Unix Socket: unable to create UNIX socket %s: %s", - addr.sun_path, strerror(errno)); - SCFree(sockettarget); - return 0; - } - this->select_max = this->socket + 1; - - /* Set file mode: will not fully work on most system, the group - * permission is not changed on some Linux and *BSD won't do the - * chmod. */ - ret = fchmod(this->socket, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); - if (ret == -1) { - int err = errno; - SCLogWarning(SC_ERR_INITIALIZATION, - "Unable to change permission on socket: %s (%d)", - strerror(err), - err); - } - /* set reuse option */ - ret = setsockopt(this->socket, SOL_SOCKET, SO_REUSEADDR, - (char *) &on, sizeof(on)); - if ( ret != 0 ) { - SCLogWarning(SC_ERR_INITIALIZATION, - "Cannot set sockets options: %s.", strerror(errno)); - } - - /* bind socket */ - ret = bind(this->socket, (struct sockaddr *) &addr, len); - if (ret == -1) { - SCLogWarning(SC_ERR_INITIALIZATION, - "Unix socket: UNIX socket bind(%s) error: %s", - sockettarget, strerror(errno)); - SCFree(sockettarget); - return 0; - } - - /* listen */ - if (listen(this->socket, 1) == -1) { - SCLogWarning(SC_ERR_INITIALIZATION, - "Command server: UNIX socket listen() error: %s", - strerror(errno)); - SCFree(sockettarget); - return 0; - } - SCFree(sockettarget); - return 1; -} - -void UnixCommandSetMaxFD(UnixCommand *this) -{ - UnixClient *item; - - if (this == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Unix command is NULL, warn devel"); - return; - } - - this->select_max = this->socket + 1; - TAILQ_FOREACH(item, &this->clients, next) { - if (item->fd >= this->select_max) { - this->select_max = item->fd + 1; - } - } -} - -/** - * \brief Close the unix socket - */ -void UnixCommandClose(UnixCommand *this, int fd) -{ - UnixClient *item; - int found = 0; - - TAILQ_FOREACH(item, &this->clients, next) { - if (item->fd == fd) { - found = 1; - break; - } - } - - if (found == 0) { - SCLogError(SC_ERR_INVALID_VALUE, "No fd found in client list"); - return; - } - - TAILQ_REMOVE(&this->clients, item, next); - - close(item->fd); - UnixCommandSetMaxFD(this); - SCFree(item); -} - -/** - * \brief Callback function used to send message to socket - */ -int UnixCommandSendCallback(const char *buffer, size_t size, void *data) -{ - int fd = *(int *) data; - - if (send(fd, buffer, size, MSG_NOSIGNAL) == -1) { - SCLogInfo("Unable to send block: %s", strerror(errno)); - return -1; - } - - return 0; -} - -#define UNIX_PROTO_VERSION_LENGTH 200 -#define UNIX_PROTO_VERSION "0.1" - -/** - * \brief Accept a new client on unix socket - * - * The function is called when a new user is detected - * in UnixMain(). It does the initial protocol negotiation - * with client. - * - * \retval 0 in case of error, 1 in case of success - */ -int UnixCommandAccept(UnixCommand *this) -{ - char buffer[UNIX_PROTO_VERSION_LENGTH + 1]; - json_t *client_msg; - json_t *server_msg; - json_t *version; - json_error_t jerror; - int client; - int ret; - UnixClient *uclient = NULL; - - /* accept client socket */ - socklen_t len = sizeof(this->client_addr); - client = accept(this->socket, (struct sockaddr *) &this->client_addr, - &len); - if (client < 0) { - SCLogInfo("Unix socket: accept() error: %s", - strerror(errno)); - return 0; - } - SCLogDebug("Unix socket: client connection"); - - /* read client version */ - buffer[sizeof(buffer)-1] = 0; - ret = recv(client, buffer, sizeof(buffer)-1, 0); - if (ret < 0) { - SCLogInfo("Command server: client doesn't send version"); - close(client); - return 0; - } - if (ret >= (int)(sizeof(buffer)-1)) { - SCLogInfo("Command server: client message is too long, " - "disconnect him."); - close(client); - return 0; - } - buffer[ret] = 0; - - client_msg = json_loads(buffer, 0, &jerror); - if (client_msg == NULL) { - SCLogInfo("Invalid command, error on line %d: %s\n", jerror.line, jerror.text); - close(client); - return 0; - } - - version = json_object_get(client_msg, "version"); - if (!json_is_string(version)) { - SCLogInfo("error: version is not a string"); - close(client); - json_decref(client_msg); - return 0; - } - - /* check client version */ - if (strcmp(json_string_value(version), UNIX_PROTO_VERSION) != 0) { - SCLogInfo("Unix socket: invalid client version: \"%s\"", - json_string_value(version)); - json_decref(client_msg); - close(client); - return 0; - } else { - SCLogInfo("Unix socket: client version: \"%s\"", - json_string_value(version)); - } - - json_decref(client_msg); - /* send answer */ - server_msg = json_object(); - if (server_msg == NULL) { - close(client); - return 0; - } - json_object_set_new(server_msg, "return", json_string("OK")); - - if (json_dump_callback(server_msg, UnixCommandSendCallback, &client, 0) == -1) { - SCLogWarning(SC_ERR_SOCKET, "Unable to send command"); - json_decref(server_msg); - close(client); - return 0; - } - json_decref(server_msg); - - /* client connected */ - SCLogDebug("Unix socket: client connected"); - - uclient = SCMalloc(sizeof(UnixClient)); - if (unlikely(uclient == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't allocate new cient"); - return 0; - } - uclient->fd = client; - TAILQ_INSERT_TAIL(&this->clients, uclient, next); - UnixCommandSetMaxFD(this); - return 1; -} - -int UnixCommandBackgroundTasks(UnixCommand* this) -{ - int ret = 1; - Task *ltask; - - TAILQ_FOREACH(ltask, &this->tasks, next) { - int fret = ltask->Func(ltask->data); - if (fret != TM_ECODE_OK) { - ret = 0; - } - } - return ret; -} - -/** - * \brief Command dispatcher - * - * \param this a UnixCommand:: structure - * \param command a string containing a json formatted - * command - * - * \retval 0 in case of error, 1 in case of success - */ -int UnixCommandExecute(UnixCommand * this, char *command, UnixClient *client) -{ - int ret = 1; - json_error_t error; - json_t *jsoncmd = NULL; - json_t *cmd = NULL; - json_t *server_msg = json_object(); - const char * value; - int found = 0; - Command *lcmd; - - if (server_msg == NULL) { - return 0; - } - - jsoncmd = json_loads(command, 0, &error); - if (jsoncmd == NULL) { - SCLogInfo("Invalid command, error on line %d: %s\n", error.line, error.text); - goto error; - } - - cmd = json_object_get(jsoncmd, "command"); - if(!json_is_string(cmd)) { - SCLogInfo("error: command is not a string"); - goto error_cmd; - } - value = json_string_value(cmd); - - TAILQ_FOREACH(lcmd, &this->commands, next) { - if (!strcmp(value, lcmd->name)) { - int fret = TM_ECODE_OK; - found = 1; - if (lcmd->flags & UNIX_CMD_TAKE_ARGS) { - cmd = json_object_get(jsoncmd, "arguments"); - if(!json_is_object(cmd)) { - SCLogInfo("error: argument is not an object"); - goto error_cmd; - } - } - fret = lcmd->Func(cmd, server_msg, lcmd->data); - if (fret != TM_ECODE_OK) { - ret = 0; - } - break; - } - } - - if (found == 0) { - json_object_set_new(server_msg, "message", json_string("Unknown command")); - ret = 0; - } - - switch (ret) { - case 0: - json_object_set_new(server_msg, "return", json_string("NOK")); - break; - case 1: - json_object_set_new(server_msg, "return", json_string("OK")); - break; - } - - /* send answer */ - if (json_dump_callback(server_msg, UnixCommandSendCallback, &client->fd, 0) == -1) { - SCLogWarning(SC_ERR_SOCKET, "Unable to send command"); - goto error_cmd; - } - - json_decref(jsoncmd); - json_decref(server_msg); - return ret; - -error_cmd: - json_decref(jsoncmd); -error: - json_decref(server_msg); - UnixCommandClose(this, client->fd); - return 0; -} - -void UnixCommandRun(UnixCommand * this, UnixClient *client) -{ - char buffer[4096]; - int ret; - ret = recv(client->fd, buffer, sizeof(buffer) - 1, 0); - if (ret <= 0) { - if (ret == 0) { - SCLogDebug("Unix socket: lost connection with client"); - } else { - SCLogError(SC_ERR_SOCKET, "Unix socket: error on recv() from client: %s", - strerror(errno)); - } - UnixCommandClose(this, client->fd); - return; - } - if (ret >= (int)(sizeof(buffer)-1)) { - SCLogInfo("Command server: client command is too long, " - "disconnect him."); - UnixCommandClose(this, client->fd); - } - buffer[ret] = 0; - UnixCommandExecute(this, buffer, client); -} - -/** - * \brief Select function - * - * \retval 0 in case of error, 1 in case of success - */ -int UnixMain(UnixCommand * this) -{ - struct timeval tv; - int ret; - fd_set select_set; - UnixClient *uclient; - UnixClient *tclient; - - /* Wait activity on the socket */ - FD_ZERO(&select_set); - FD_SET(this->socket, &select_set); - TAILQ_FOREACH(uclient, &this->clients, next) { - FD_SET(uclient->fd, &select_set); - } - - tv.tv_sec = 0; - tv.tv_usec = 200 * 1000; - ret = select(this->select_max, &select_set, NULL, NULL, &tv); - - /* catch select() error */ - if (ret == -1) { - /* Signal was caught: just ignore it */ - if (errno == EINTR) { - return 1; - } - SCLogError(SC_ERR_SOCKET, "Command server: select() fatal error: %s", strerror(errno)); - return 0; - } - - if (suricata_ctl_flags & (SURICATA_STOP | SURICATA_KILL)) { - return 1; - } - - /* timeout: continue */ - if (ret == 0) { - return 1; - } - - TAILQ_FOREACH_SAFE(uclient, &this->clients, next, tclient) { - if (FD_ISSET(uclient->fd, &select_set)) { - UnixCommandRun(this, uclient); - } - } - if (FD_ISSET(this->socket, &select_set)) { - if (!UnixCommandAccept(this)) - return 1; - } - - return 1; -} - -/** - * \brief Used to kill unix manager thread(s). - * - * \todo Kinda hackish since it uses the tv name to identify unix manager - * thread. We need an all weather identification scheme. - */ -void UnixKillUnixManagerThread(void) -{ - ThreadVars *tv = NULL; - int cnt = 0; - - SCCtrlCondSignal(&unix_manager_ctrl_cond); - - SCMutexLock(&tv_root_lock); - - /* flow manager thread(s) is/are a part of mgmt threads */ - tv = tv_root[TVT_CMD]; - - while (tv != NULL) { - if (strcasecmp(tv->name, "UnixManagerThread") == 0) { - TmThreadsSetFlag(tv, THV_KILL); - TmThreadsSetFlag(tv, THV_DEINIT); - - /* be sure it has shut down */ - while (!TmThreadsCheckFlag(tv, THV_CLOSED)) { - usleep(100); - } - cnt++; - } - tv = tv->next; - } - - /* not possible, unless someone decides to rename UnixManagerThread */ - if (cnt == 0) { - SCMutexUnlock(&tv_root_lock); - abort(); - } - - SCMutexUnlock(&tv_root_lock); - return; -} - - -TmEcode UnixManagerShutdownCommand(json_t *cmd, - json_t *server_msg, void *data) -{ - SCEnter(); - json_object_set_new(server_msg, "message", json_string("Closing Suricata")); - EngineStop(); - SCReturnInt(TM_ECODE_OK); -} - -TmEcode UnixManagerVersionCommand(json_t *cmd, - json_t *server_msg, void *data) -{ - SCEnter(); - json_object_set_new(server_msg, "message", json_string( -#ifdef REVISION - PROG_VER xstr(REVISION) -#elif defined RELEASE - PROG_VER " RELEASE" -#else - PROG_VER -#endif - )); - SCReturnInt(TM_ECODE_OK); -} - -TmEcode UnixManagerUptimeCommand(json_t *cmd, - json_t *server_msg, void *data) -{ - SCEnter(); - int uptime; - UnixCommand *ucmd = (UnixCommand *)data; - - uptime = time(NULL) - ucmd->start_timestamp; - json_object_set_new(server_msg, "message", json_integer(uptime)); - SCReturnInt(TM_ECODE_OK); -} - -TmEcode UnixManagerRunningModeCommand(json_t *cmd, - json_t *server_msg, void *data) -{ - SCEnter(); - json_object_set_new(server_msg, "message", json_string(RunmodeGetActive())); - SCReturnInt(TM_ECODE_OK); -} - -TmEcode UnixManagerCaptureModeCommand(json_t *cmd, - json_t *server_msg, void *data) -{ - SCEnter(); - json_object_set_new(server_msg, "message", json_string(RunModeGetMainMode())); - SCReturnInt(TM_ECODE_OK); -} - -TmEcode UnixManagerReloadRules(json_t *cmd, json_t *server_msg, void *data) -{ - SCEnter(); - DetectEngineReloadStart(); - - while (DetectEngineReloadIsDone() == 0) - usleep(100); - - json_object_set_new(server_msg, "message", json_string("done")); - SCReturnInt(TM_ECODE_OK); -} - -TmEcode UnixManagerConfGetCommand(json_t *cmd, - json_t *server_msg, void *data) -{ - SCEnter(); - - char *confval = NULL; - char *variable = NULL; - - json_t *jarg = json_object_get(cmd, "variable"); - if(!json_is_string(jarg)) { - SCLogInfo("error: variable is not a string"); - json_object_set_new(server_msg, "message", json_string("variable is not a string")); - SCReturnInt(TM_ECODE_FAILED); - } - - variable = (char *)json_string_value(jarg); - if (ConfGet(variable, &confval) != 1) { - json_object_set_new(server_msg, "message", json_string("Unable to get value")); - SCReturnInt(TM_ECODE_FAILED); - } - - if (confval) { - json_object_set_new(server_msg, "message", json_string(confval)); - SCReturnInt(TM_ECODE_OK); - } - - json_object_set_new(server_msg, "message", json_string("No string value")); - SCReturnInt(TM_ECODE_FAILED); -} - -TmEcode UnixManagerListCommand(json_t *cmd, - json_t *answer, void *data) -{ - SCEnter(); - json_t *jdata; - json_t *jarray; - Command *lcmd = NULL; - UnixCommand *gcmd = (UnixCommand *) data; - int i = 0; - - jdata = json_object(); - if (jdata == NULL) { - json_object_set_new(answer, "message", - json_string("internal error at json object creation")); - return TM_ECODE_FAILED; - } - jarray = json_array(); - if (jarray == NULL) { - json_object_set_new(answer, "message", - json_string("internal error at json object creation")); - return TM_ECODE_FAILED; - } - - TAILQ_FOREACH(lcmd, &gcmd->commands, next) { - json_array_append(jarray, json_string(lcmd->name)); - i++; - } - - json_object_set_new(jdata, "count", json_integer(i)); - json_object_set_new(jdata, "commands", jarray); - json_object_set_new(answer, "message", jdata); - SCReturnInt(TM_ECODE_OK); -} - - -#if 0 -TmEcode UnixManagerReloadRules(json_t *cmd, - json_t *server_msg, void *data) -{ - SCEnter(); - if (suricata_ctl_flags != 0) { - json_object_set_new(server_msg, "message", - json_string("Live rule swap no longer possible." - " Engine in shutdown mode.")); - SCReturn(TM_ECODE_FAILED); - } else { - /* FIXME : need to check option value */ - UtilSignalHandlerSetup(SIGUSR2, SignalHandlerSigusr2Idle); - DetectEngineSpawnLiveRuleSwapMgmtThread(); - json_object_set_new(server_msg, "message", json_string("Reloading rules")); - } - SCReturn(TM_ECODE_OK); -} -#endif - -static UnixCommand command; - -/** - * \brief Add a command to the list of commands - * - * This function adds a command to the list of commands available - * through the unix socket. - * - * When a command is received from user through the unix socket, the content - * of 'Command' field in the JSON message is match against keyword, then the - * Func is called. See UnixSocketAddPcapFile() for an example. - * - * \param keyword name of the command - * \param Func function to run when command is received - * \param data a pointer to data that are passed to Func when it is run - * \param flags a flag now used to tune the command type - * \retval TM_ECODE_OK in case of success, TM_ECODE_FAILED in case of failure - */ -TmEcode UnixManagerRegisterCommand(const char * keyword, - TmEcode (*Func)(json_t *, json_t *, void *), - void *data, int flags) -{ - SCEnter(); - Command *cmd = NULL; - Command *lcmd = NULL; - - if (Func == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Null function"); - SCReturnInt(TM_ECODE_FAILED); - } - - if (keyword == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Null keyword"); - SCReturnInt(TM_ECODE_FAILED); - } - - TAILQ_FOREACH(lcmd, &command.commands, next) { - if (!strcmp(keyword, lcmd->name)) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "%s already registered", keyword); - SCReturnInt(TM_ECODE_FAILED); - } - } - - cmd = SCMalloc(sizeof(Command)); - if (unlikely(cmd == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't alloc cmd"); - SCReturnInt(TM_ECODE_FAILED); - } - cmd->name = SCStrdup(keyword); - if (unlikely(cmd->name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't alloc cmd name"); - SCFree(cmd); - SCReturnInt(TM_ECODE_FAILED); - } - cmd->Func = Func; - cmd->data = data; - cmd->flags = flags; - /* Add it to the list */ - TAILQ_INSERT_TAIL(&command.commands, cmd, next); - - SCReturnInt(TM_ECODE_OK); -} - -/** - * \brief Add a task to the list of tasks - * - * This function adds a task to run in the background. The task is run - * each time the UnixMain() function exits from select. - * - * \param Func function to run when a command is received - * \param data a pointer to data that are passed to Func when it is run - * \retval TM_ECODE_OK in case of success, TM_ECODE_FAILED in case of failure - */ -TmEcode UnixManagerRegisterBackgroundTask(TmEcode (*Func)(void *), - void *data) -{ - SCEnter(); - Task *task = NULL; - - if (Func == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Null function"); - SCReturnInt(TM_ECODE_FAILED); - } - - task = SCMalloc(sizeof(Task)); - if (unlikely(task == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't alloc task"); - SCReturnInt(TM_ECODE_FAILED); - } - task->Func = Func; - task->data = data; - /* Add it to the list */ - TAILQ_INSERT_TAIL(&command.tasks, task, next); - - SCReturnInt(TM_ECODE_OK); -} - -typedef struct UnixManagerThreadData_ { - int padding; -} UnixManagerThreadData; - -static TmEcode UnixManagerThreadInit(ThreadVars *t, void *initdata, void **data) -{ - UnixManagerThreadData *utd = SCCalloc(1, sizeof(*utd)); - if (utd == NULL) - return TM_ECODE_FAILED; - - *data = utd; - return TM_ECODE_OK; -} - -static TmEcode UnixManagerThreadDeinit(ThreadVars *t, void *data) -{ - SCFree(data); - return TM_ECODE_OK; -} - -static TmEcode UnixManager(ThreadVars *th_v, void *thread_data) -{ - int ret; - - /* set the thread name */ - SCLogDebug("%s started...", th_v->name); - - StatsSetupPrivate(th_v); - - if (UnixNew(&command) == 0) { - int failure_fatal = 0; - SCLogError(SC_ERR_INITIALIZATION, - "Unable to create unix command socket"); - if (ConfGetBool("engine.init-failure-fatal", &failure_fatal) != 1) { - SCLogDebug("ConfGetBool could not load the value."); - } - if (failure_fatal) { - exit(EXIT_FAILURE); - } else { - return TM_ECODE_FAILED; - } - } - - /* Set the threads capability */ - th_v->cap_flags = 0; - SCDropCaps(th_v); - - /* Init Unix socket */ - UnixManagerRegisterCommand("shutdown", UnixManagerShutdownCommand, NULL, 0); - UnixManagerRegisterCommand("command-list", UnixManagerListCommand, &command, 0); - UnixManagerRegisterCommand("help", UnixManagerListCommand, &command, 0); - UnixManagerRegisterCommand("version", UnixManagerVersionCommand, &command, 0); - UnixManagerRegisterCommand("uptime", UnixManagerUptimeCommand, &command, 0); - UnixManagerRegisterCommand("running-mode", UnixManagerRunningModeCommand, &command, 0); - UnixManagerRegisterCommand("capture-mode", UnixManagerCaptureModeCommand, &command, 0); - UnixManagerRegisterCommand("conf-get", UnixManagerConfGetCommand, &command, UNIX_CMD_TAKE_ARGS); - UnixManagerRegisterCommand("dump-counters", StatsOutputCounterSocket, NULL, 0); - UnixManagerRegisterCommand("reload-rules", UnixManagerReloadRules, NULL, 0); - UnixManagerRegisterCommand("register-tenant-handler", UnixSocketRegisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS); - UnixManagerRegisterCommand("unregister-tenant-handler", UnixSocketUnregisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS); - UnixManagerRegisterCommand("register-tenant", UnixSocketRegisterTenant, &command, UNIX_CMD_TAKE_ARGS); - UnixManagerRegisterCommand("reload-tenant", UnixSocketReloadTenant, &command, UNIX_CMD_TAKE_ARGS); - UnixManagerRegisterCommand("unregister-tenant", UnixSocketUnregisterTenant, &command, UNIX_CMD_TAKE_ARGS); - - - TmThreadsSetFlag(th_v, THV_INIT_DONE); - while (1) { - ret = UnixMain(&command); - if (ret == 0) { - SCLogError(SC_ERR_FATAL, "Fatal error on unix socket"); - } - - if ((ret == 0) || (TmThreadsCheckFlag(th_v, THV_KILL))) { - UnixClient *item; - UnixClient *titem; - TAILQ_FOREACH_SAFE(item, &(&command)->clients, next, titem) { - close(item->fd); - SCFree(item); - } - StatsSyncCounters(th_v); - break; - } - - UnixCommandBackgroundTasks(&command); - } - return TM_ECODE_OK; -} - - -/** \brief Spawn the unix socket manager thread - * - * \param mode if set to 1, init failure cause suricata exit - * */ -void UnixManagerThreadSpawn(int mode) -{ - ThreadVars *tv_unixmgr = NULL; - - SCCtrlCondInit(&unix_manager_ctrl_cond, NULL); - SCCtrlMutexInit(&unix_manager_ctrl_mutex, NULL); - - tv_unixmgr = TmThreadCreateCmdThreadByName("UnixManagerThread", - "UnixManager", 0); - - if (tv_unixmgr == NULL) { - SCLogError(SC_ERR_INITIALIZATION, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - if (TmThreadSpawn(tv_unixmgr) != TM_ECODE_OK) { - SCLogError(SC_ERR_INITIALIZATION, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - if (mode == 1) { - if (TmThreadsCheckFlag(tv_unixmgr, THV_RUNNING_DONE)) { - SCLogError(SC_ERR_INITIALIZATION, "Unix socket init failed"); - exit(EXIT_FAILURE); - } - } - return; -} - -/** - * \brief Used to kill unix manager thread(s). - * - * \todo Kinda hackish since it uses the tv name to identify unix manager - * thread. We need an all weather identification scheme. - */ -void UnixSocketKillSocketThread(void) -{ - ThreadVars *tv = NULL; - - SCMutexLock(&tv_root_lock); - - /* unix manager thread(s) is/are a part of command threads */ - tv = tv_root[TVT_CMD]; - - while (tv != NULL) { - if (strcasecmp(tv->name, "UnixManagerThread") == 0) { - /* If the thread dies during init it will have - * THV_RUNNING_DONE set, so we can set the correct flag - * and exit. - */ - if (TmThreadsCheckFlag(tv, THV_RUNNING_DONE)) { - TmThreadsSetFlag(tv, THV_KILL); - TmThreadsSetFlag(tv, THV_DEINIT); - TmThreadsSetFlag(tv, THV_CLOSED); - break; - } - TmThreadsSetFlag(tv, THV_KILL); - TmThreadsSetFlag(tv, THV_DEINIT); - /* Be sure it has shut down */ - while (!TmThreadsCheckFlag(tv, THV_CLOSED)) { - usleep(100); - } - } - tv = tv->next; - } - - SCMutexUnlock(&tv_root_lock); - return; -} - -#else /* BUILD_UNIX_SOCKET */ - -void UnixManagerThreadSpawn(int mode) -{ - SCLogError(SC_ERR_UNIMPLEMENTED, "Unix socket is not compiled"); - return; -} - -void UnixSocketKillSocketThread(void) -{ - return; -} - -#endif /* BUILD_UNIX_SOCKET */ - -void TmModuleUnixManagerRegister (void) -{ -#ifdef BUILD_UNIX_SOCKET - tmm_modules[TMM_UNIXMANAGER].name = "UnixManager"; - tmm_modules[TMM_UNIXMANAGER].ThreadInit = UnixManagerThreadInit; - tmm_modules[TMM_UNIXMANAGER].ThreadDeinit = UnixManagerThreadDeinit; - tmm_modules[TMM_UNIXMANAGER].Management = UnixManager; - tmm_modules[TMM_UNIXMANAGER].cap_flags = 0; - tmm_modules[TMM_UNIXMANAGER].flags = TM_FLAG_COMMAND_TM; -#endif /* BUILD_UNIX_SOCKET */ -} diff --git a/framework/src/suricata/src/unix-manager.h b/framework/src/suricata/src/unix-manager.h deleted file mode 100644 index 848da761..00000000 --- a/framework/src/suricata/src/unix-manager.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (C) 2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#ifndef UNIX_MANAGER_H -#define UNIX_MANAGER_H - -#ifdef BUILD_UNIX_SOCKET -#include -#endif - -#define UNIX_CMD_TAKE_ARGS 1 - -SCCtrlCondT unix_manager_ctrl_cond; -SCCtrlMutex unix_manager_ctrl_mutex; - -void UnixManagerThreadSpawn(int mode); -void UnixSocketKillSocketThread(void); - - -#ifdef BUILD_UNIX_SOCKET -TmEcode UnixManagerRegisterCommand(const char * keyword, - TmEcode (*Func)(json_t *, json_t *, void *), - void *data, int flags); -TmEcode UnixManagerRegisterBackgroundTask( - TmEcode (*Func)(void *), - void *data); -#endif - -void TmModuleUnixManagerRegister(void); - -#endif /* UNIX_MANAGER_H */ diff --git a/framework/src/suricata/src/util-action.c b/framework/src/suricata/src/util-action.c deleted file mode 100644 index 2b349748..00000000 --- a/framework/src/suricata/src/util-action.c +++ /dev/null @@ -1,1627 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#include "suricata-common.h" - -#include "action-globals.h" -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-sigorder.h" - -#include "util-unittest.h" -#include "util-action.h" -#include "util-unittest-helper.h" -#include "util-debug.h" - -/* Default order: */ -uint8_t action_order_sigs[4] = {ACTION_PASS, ACTION_DROP, ACTION_REJECT, ACTION_ALERT}; -/* This order can be changed from config */ - -/** - * \brief Return the priority associated to an action (to order sigs - * as specified at config) - * action_order_sigs has this priority by index val - * so action_order_sigs[0] has to be inspected first. - * This function is called from detect-engine-sigorder - * \param action can be one of ACTION_PASS, ACTION_DROP, - * ACTION_REJECT or ACTION_ALERT - * \retval uint8_t the priority (order of this actions) - */ -uint8_t ActionOrderVal(uint8_t action) -{ - /* reject_both and reject_dst have the same prio as reject */ - if( (action & ACTION_REJECT) || - (action & ACTION_REJECT_BOTH) || - (action & ACTION_REJECT_DST)) { - action = ACTION_REJECT; - } - uint8_t i = 0; - for (; i < 4; i++) { - if (action_order_sigs[i] == action) - return i; - } - /* Unknown action, set just a low prio (high val) */ - return 10; -} - -/** - * \brief Return the ACTION_* bit from their ascii value - * \param action can be one of "pass", "drop", - * "reject" or "alert" - * \retval uint8_t can be one of ACTION_PASS, ACTION_DROP, - * ACTION_REJECT or ACTION_ALERT - */ -uint8_t ActionAsciiToFlag(char *action) -{ - if (strcmp(action,"pass") == 0) - return ACTION_PASS; - if (strcmp(action,"drop") == 0) - return ACTION_DROP; - if (strcmp(action,"reject") == 0) - return ACTION_REJECT; - if (strcmp(action,"alert") == 0) - return ACTION_ALERT; - - return 0; -} - -/** - * \brief Load the action order from config. If none is provided, - * it will be default to ACTION_PASS, ACTION_DROP, - * ACTION_REJECT, ACTION_ALERT (pass has the highest prio) - * - * \retval 0 on success; -1 on fatal error; - */ -int ActionInitConfig() -{ - uint8_t actions_used = 0; - uint8_t action_flag = 0; - uint8_t actions_config[4] = {0, 0, 0, 0}; - int order = 0; - - ConfNode *action_order; - ConfNode *action = NULL; - - /* Let's load the order of actions from the general config */ - action_order = ConfGetNode("action-order"); - if (action_order == NULL) { - /* No configuration, use defaults. */ - return 0; - } - else { - TAILQ_FOREACH(action, &action_order->head, next) { - SCLogDebug("Loading action order : %s", action->val); - action_flag = ActionAsciiToFlag(action->val); - if (action_flag == 0) { - SCLogError(SC_ERR_ACTION_ORDER, "action-order, invalid action: \"%s\". Please, use" - " \"pass\",\"drop\",\"alert\",\"reject\". You have" - " to specify all of them, without quotes and without" - " capital letters", action->val); - goto error; - } - - if (actions_used & action_flag) { - SCLogError(SC_ERR_ACTION_ORDER, "action-order, action already set: \"%s\". Please," - " use \"pass\",\"drop\",\"alert\",\"reject\". You" - " have to specify all of them, without quotes and" - " without capital letters", action->val); - goto error; - } - - if (order >= 4) { - SCLogError(SC_ERR_ACTION_ORDER, "action-order, you have already specified all the " - "possible actions plus \"%s\". Please, use \"pass\"," - "\"drop\",\"alert\",\"reject\". You have to specify" - " all of them, without quotes and without capital" - " letters", action->val); - goto error; - } - actions_used |= action_flag; - actions_config[order++] = action_flag; - } - } - if (order < 4) { - SCLogError(SC_ERR_ACTION_ORDER, "action-order, the config didn't specify all of the " - "actions. Please, use \"pass\",\"drop\",\"alert\"," - "\"reject\". You have to specify all of them, without" - " quotes and without capital letters"); - goto error; - } - - /* Now, it's a valid config. Override the default preset */ - for (order = 0; order < 4; order++) { - action_order_sigs[order] = actions_config[order]; - } - - return 0; - - error: - return -1; -} - -#ifdef UNITTESTS -#include "util-unittest.h" - -/** - * \test Check that we invalidate duplicated actions - * (It should default to pass, drop, reject, alert) - */ -int UtilActionTest01(void) -{ - int res = 1; - char config[] = "\ -%YAML 1.1\n\ ----\n\ -action-order:\n\ - - alert\n\ - - drop\n\ - - reject\n\ - - alert\n"; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ActionInitConfig(); - if (action_order_sigs[0] != ACTION_PASS || - action_order_sigs[1] != ACTION_DROP || - action_order_sigs[2] != ACTION_REJECT || - action_order_sigs[3] != ACTION_ALERT) - { - res = 0; - } - ConfRestoreContextBackup(); - - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we invalidate with unknown keywords - * (It should default to pass, drop, reject, alert) - */ -int UtilActionTest02(void) -{ - int res = 1; - char config[] = "\ -%YAML 1.1\n\ ----\n\ -action-order:\n\ - - alert\n\ - - drop\n\ - - reject\n\ - - ftw\n"; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ActionInitConfig(); - if (action_order_sigs[0] != ACTION_PASS || - action_order_sigs[1] != ACTION_DROP || - action_order_sigs[2] != ACTION_REJECT || - action_order_sigs[3] != ACTION_ALERT) - { - res = 0; - } - ConfRestoreContextBackup(); - - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we invalidate if any action is missing - * (It should default to pass, drop, reject, alert) - */ -int UtilActionTest03(void) -{ - int res = 1; - char config[] = "\ -%YAML 1.1\n\ ----\n\ -action-order:\n\ - - alert\n\ - - drop\n\ - - reject\n"; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ActionInitConfig(); - if (action_order_sigs[0] != ACTION_PASS || - action_order_sigs[1] != ACTION_DROP || - action_order_sigs[2] != ACTION_REJECT || - action_order_sigs[3] != ACTION_ALERT) - { - res = 0; - } - ConfRestoreContextBackup(); - - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we invalidate if any action is missing - * (It should default to pass, drop, reject, alert) - */ -int UtilActionTest04(void) -{ - int res = 1; - char config[] = "\ -%YAML 1.1\n\ ----\n\ -action-order:\n"; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ActionInitConfig(); - if (action_order_sigs[0] != ACTION_PASS || - action_order_sigs[1] != ACTION_DROP || - action_order_sigs[2] != ACTION_REJECT || - action_order_sigs[3] != ACTION_ALERT) - { - res = 0; - } - ConfRestoreContextBackup(); - - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we invalidate with unknown keywords - * and/or more than the expected - * (It should default to pass, drop, reject, alert) - */ -int UtilActionTest05(void) -{ - int res = 1; - char config[] = "\ -%YAML 1.1\n\ ----\n\ -action-order:\n\ - - alert\n\ - - drop\n\ - - reject\n\ - - pass\n\ - - whatever\n"; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ActionInitConfig(); - if (action_order_sigs[0] != ACTION_PASS || - action_order_sigs[1] != ACTION_DROP || - action_order_sigs[2] != ACTION_REJECT || - action_order_sigs[3] != ACTION_ALERT) - { - res = 0; - } - ConfRestoreContextBackup(); - - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we load a valid config - */ -int UtilActionTest06(void) -{ - int res = 1; - char config[] = "\ -%YAML 1.1\n\ ----\n\ -action-order:\n\ - - alert\n\ - - drop\n\ - - reject\n\ - - pass\n"; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ActionInitConfig(); - if (action_order_sigs[0] != ACTION_ALERT || - action_order_sigs[1] != ACTION_DROP || - action_order_sigs[2] != ACTION_REJECT || - action_order_sigs[3] != ACTION_PASS) - { - res = 0; - } - ConfRestoreContextBackup(); - - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we load a valid config - */ -int UtilActionTest07(void) -{ - int res = 1; - char config[] = "\ -%YAML 1.1\n\ ----\n\ -action-order:\n\ - - pass\n\ - - alert\n\ - - drop\n\ - - reject\n"; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ActionInitConfig(); - if (action_order_sigs[0] != ACTION_PASS || - action_order_sigs[1] != ACTION_ALERT || - action_order_sigs[2] != ACTION_DROP || - action_order_sigs[3] != ACTION_REJECT) - { - res = 0; - } - ConfRestoreContextBackup(); - - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we handle the "pass" action - * correctly at the IP Only engine in the default case - */ -int UtilActionTest08(void) -{ - int res = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert ip any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "pass ip 192.168.1.1 80 -> any any (msg:\"sig 2\"; sid:2;)"; - sigs[2]= "alert ip any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {1, 0, 1}, - {0, 0, 0}, - {1, 0, 1} }; - /* This means that with the second packet, the results will be - * all ({0,0,0}) since, we should match the "pass" rule first - */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - return res; -} - -/** - * \test Check that we handle the "pass" action - * correctly at the IP Only engine with more - * prio to drop - */ -int UtilActionTest09(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_PASS; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert ip any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "pass ip 192.168.1.1 80 -> any any (msg:\"sig 2\"; sid:2;)"; - sigs[2]= "drop ip any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {1, 0, 1}, - {0, 0, 1}, - {1, 0, 1} }; - /* This means that with the second packet, the results will be - * all ({0,0,1}) since, we should match the "drop" rule first. - * Later the "pass" rule will avoid the "alert" rule match - */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we handle the "pass" action - * correctly at the detection engine in the default case - */ -int UtilActionTest10(void) -{ - int res = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - uint8_t *buf2 = (uint8_t *)"wo!"; - uint16_t buflen2 = strlen((char *)buf2); - Packet *p[3]; - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf2, buflen2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert ip any any -> any any (msg:\"sig 1\"; content:\"Hi all\"; sid:1;)"; - sigs[1]= "pass ip any any -> any any (msg:\"sig 2\"; content:\"wo\"; sid:2;)"; - sigs[2]= "alert ip any any -> any any (msg:\"sig 3\"; content:\"Hi all\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {1, 0, 1}, - {0, 0, 0}, - {1, 0, 1} }; - /* This means that with the second packet, the results will be - * all ({0,0,0}) since, we should match the "pass" rule first - */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - return res; -} - -/** - * \test Check that we handle the "pass" action - * correctly at the detection engine with more - * prio to drop - */ -int UtilActionTest11(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - uint8_t *buf2 = (uint8_t *)"Hi all wo!"; - uint16_t buflen2 = strlen((char *)buf2); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_PASS; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf2, buflen2, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; content:\"Hi all\"; sid:1;)"; - sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"wo\"; sid:2;)"; - sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; content:\"Hi all\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {1, 0, 1}, - {0, 0, 1}, - {1, 0, 1} }; - /* This means that with the second packet, the results will be - * all ({0,0,1}) since, we should match the "drop" rule first. - * Later the "pass" rule will avoid the "alert" rule match - */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we handle the "pass" action - * correctly at the detection engine in the default case - */ -int UtilActionTest12(void) -{ - int res = 0; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert ip any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "pass ip any any -> any any (msg:\"Testing normal 2\"; sid:2;)"; - sigs[2]= "alert ip any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0} }; - /* All should match the 3 sigs, but the action pass has prio */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - return res; -} - -/** - * \test Check that we handle the "pass" action - * correctly at the detection engine with more - * prio to drop - */ -int UtilActionTest13(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_PASS; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; content:\"Hi all\"; sid:1;)"; - sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; content:\"Hi all\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {0, 0, 1}, - {0, 0, 1}, - {0, 0, 1} }; - /* All the patckets should match the 3 sigs. As drop has more - * priority than pass, it should alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check that we handle the "pass" action - * correctly at the detection engine with more - * prio to drop and alert - */ -int UtilActionTest14(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_ALERT; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_PASS; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; content:\"Hi all\"; sid:1;)"; - sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; content:\"Hi all\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {1, 0, 1}, - {1, 0, 1}, - {1, 0, 1} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - return res; -} - -/** - * \test Check mixed sigs (iponly and normal) - */ -int UtilActionTest15(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - return res; -} - -/** - * \test Check mixed sigs (iponly and normal) - */ -int UtilActionTest16(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "drop tcp any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "pass tcp any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - return res; -} - -/** - * \test Check mixed sigs (iponly and normal) - */ -int UtilActionTest17(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "pass tcp any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "drop tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {0, 0, 0}, - {0, 0, 0}, - {0, 0, 0} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - return res; -} - -/** - * \test Check mixed sigs (iponly and normal) with more prio for drop - */ -int UtilActionTest18(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_PASS; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {0, 0, 1}, - {0, 0, 1}, - {0, 0, 1} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - return res; -} - -/** - * \test Check mixed sigs (iponly and normal) with more prio for drop - */ -int UtilActionTest19(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_PASS; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "drop tcp any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "pass tcp any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {1, 0, 0}, - {1, 0, 0}, - {1, 0, 0} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - return res; -} - -/** - * \test Check mixed sigs (iponly and normal) with more prio for drop - */ -int UtilActionTest20(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_PASS; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "pass tcp any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "drop tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {0, 1, 0}, - {0, 1, 0}, - {0, 1, 0} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - return res; -} - -/** - * \test Check mixed sigs (iponly and normal) with more prio for alert and drop - */ -int UtilActionTest21(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_ALERT; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_PASS; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "alert tcp any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "pass tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "drop tcp any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {1, 0, 1}, - {1, 0, 1}, - {1, 0, 1} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - return res; -} - -/** - * \test Check mixed sigs (iponly and normal) with more prio for alert and drop - */ -int UtilActionTest22(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_ALERT; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_PASS; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "drop tcp any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "alert tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "pass tcp any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {1, 1, 0}, - {1, 1, 0}, - {1, 1, 0} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - -end: - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - - return res; -} - -/** - * \test Check mixed sigs (iponly and normal) with more prio for alert and drop - */ -int UtilActionTest23(void) -{ - int res = 1; - uint8_t *buf = (uint8_t *)"Hi all!"; - uint16_t buflen = strlen((char *)buf); - Packet *p[3]; - - action_order_sigs[0] = ACTION_DROP; - action_order_sigs[1] = ACTION_ALERT; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_PASS; - - p[0] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - p[1] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.1", "192.168.1.5", - 80, 41424); - p[2] = UTHBuildPacketReal((uint8_t *)buf, buflen, IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", - 41424, 80); - - if (p[0] == NULL || p[1] == NULL ||p[2] == NULL) - goto end; - - char *sigs[3]; - sigs[0]= "pass tcp any any -> any any (msg:\"sig 1\"; sid:1;)"; - sigs[1]= "drop tcp any any -> any any (msg:\"sig 2\"; content:\"Hi all\"; sid:2;)"; - sigs[2]= "alert tcp any any -> any any (msg:\"sig 3\"; sid:3;)"; - - uint32_t sid[3] = {1, 2, 3}; - - uint32_t results[3][3] = { - {0, 1, 1}, - {0, 1, 1}, - {0, 1, 1} }; - /* All the patckets should match the 3 sigs. As drop - * and alert have more priority than pass, both should - * alert on each packet */ - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto cleanup; - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, 3) == 0) - goto cleanup; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - - res = UTHMatchPacketsWithResults(de_ctx, p, 3, sid, (uint32_t *) results, 3); - -cleanup: - UTHFreePackets(p, 3); - - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } - - /* Restore default values */ - action_order_sigs[0] = ACTION_PASS; - action_order_sigs[1] = ACTION_DROP; - action_order_sigs[2] = ACTION_REJECT; - action_order_sigs[3] = ACTION_ALERT; - -end: - return res; -} - -/** - * \test Check that the expected defaults are loaded if the - * action-order configuration is not present. - */ -int UtilActionTest24(void) -{ - int res = 1; - char config[] = "%YAML 1.1\n" - "---\n"; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - if (ActionInitConfig() != 0) { - res = 0; - goto done; - } - if (action_order_sigs[0] != ACTION_PASS || - action_order_sigs[1] != ACTION_DROP || - action_order_sigs[2] != ACTION_REJECT || - action_order_sigs[3] != ACTION_ALERT) { - res = 0; - } - -done: - ConfRestoreContextBackup(); - return res; -} - -#endif - -/* Register unittests */ -void UtilActionRegisterTests(void) -{ -#ifdef UNITTESTS - /* Generic tests */ - UtRegisterTest("UtilActionTest01", UtilActionTest01, 1); - UtRegisterTest("UtilActionTest02", UtilActionTest02, 1); - UtRegisterTest("UtilActionTest02", UtilActionTest02, 1); - UtRegisterTest("UtilActionTest03", UtilActionTest03, 1); - UtRegisterTest("UtilActionTest04", UtilActionTest04, 1); - UtRegisterTest("UtilActionTest05", UtilActionTest05, 1); - UtRegisterTest("UtilActionTest06", UtilActionTest06, 1); - UtRegisterTest("UtilActionTest07", UtilActionTest07, 1); - UtRegisterTest("UtilActionTest08", UtilActionTest08, 1); - UtRegisterTest("UtilActionTest09", UtilActionTest09, 1); - UtRegisterTest("UtilActionTest10", UtilActionTest10, 1); - UtRegisterTest("UtilActionTest11", UtilActionTest11, 1); - UtRegisterTest("UtilActionTest12", UtilActionTest12, 1); - UtRegisterTest("UtilActionTest13", UtilActionTest13, 1); - UtRegisterTest("UtilActionTest14", UtilActionTest14, 1); - UtRegisterTest("UtilActionTest15", UtilActionTest15, 1); - UtRegisterTest("UtilActionTest16", UtilActionTest16, 1); - UtRegisterTest("UtilActionTest17", UtilActionTest17, 1); - UtRegisterTest("UtilActionTest18", UtilActionTest18, 1); - UtRegisterTest("UtilActionTest19", UtilActionTest19, 1); - UtRegisterTest("UtilActionTest20", UtilActionTest20, 1); - UtRegisterTest("UtilActionTest21", UtilActionTest21, 1); - UtRegisterTest("UtilActionTest22", UtilActionTest22, 1); - UtRegisterTest("UtilActionTest23", UtilActionTest23, 1); - UtRegisterTest("UtilActionTest24", UtilActionTest24, 1); -#endif -} diff --git a/framework/src/suricata/src/util-action.h b/framework/src/suricata/src/util-action.h deleted file mode 100644 index bc711314..00000000 --- a/framework/src/suricata/src/util-action.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __ACTION_ORDER_H__ -#define __ACTION_ORDER_H__ -#include "suricata-common.h" -int ActionInitConfig(); -uint8_t ActionOrderVal(uint8_t); -void UtilActionRegisterTests(void); - -#endif /* __ACTION_ORDER_H__ */ diff --git a/framework/src/suricata/src/util-affinity.c b/framework/src/suricata/src/util-affinity.c deleted file mode 100644 index 82456c20..00000000 --- a/framework/src/suricata/src/util-affinity.c +++ /dev/null @@ -1,323 +0,0 @@ -/* Copyright (C) 2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Eric Leblond - * - * CPU affinity related code and helper. - */ - -#include "suricata-common.h" -#define _THREAD_AFFINITY -#include "util-affinity.h" -#include "util-cpu.h" -#include "conf.h" -#include "threads.h" -#include "queue.h" -#include "runmodes.h" - -ThreadsAffinityType thread_affinity[MAX_CPU_SET] = { - { - .name = "receive-cpu-set", - .mode_flag = EXCLUSIVE_AFFINITY, - .prio = PRIO_MEDIUM, - .lcpu = 0, - }, - { - .name = "decode-cpu-set", - .mode_flag = BALANCED_AFFINITY, - .prio = PRIO_MEDIUM, - .lcpu = 0, - }, - { - .name = "stream-cpu-set", - .mode_flag = BALANCED_AFFINITY, - .prio = PRIO_MEDIUM, - .lcpu = 0, - }, - { - .name = "detect-cpu-set", - .mode_flag = EXCLUSIVE_AFFINITY, - .prio = PRIO_MEDIUM, - .lcpu = 0, - }, - { - .name = "verdict-cpu-set", - .mode_flag = BALANCED_AFFINITY, - .prio = PRIO_MEDIUM, - .lcpu = 0, - }, - { - .name = "reject-cpu-set", - .mode_flag = BALANCED_AFFINITY, - .prio = PRIO_MEDIUM, - .lcpu = 0, - }, - { - .name = "output-cpu-set", - .mode_flag = BALANCED_AFFINITY, - .prio = PRIO_MEDIUM, - .lcpu = 0, - }, - { - .name = "management-cpu-set", - .mode_flag = BALANCED_AFFINITY, - .prio = PRIO_MEDIUM, - .lcpu = 0, - }, - -}; - -int thread_affinity_init_done = 0; - -/** - * \brief find affinity by its name - * \retval a pointer to the affinity or NULL if not found - */ -ThreadsAffinityType * GetAffinityTypeFromName(const char *name) -{ - int i; - for (i = 0; i < MAX_CPU_SET; i++) { - if (!strcmp(thread_affinity[i].name, name)) { - return &thread_affinity[i]; - } - } - return NULL; -} - -#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ -static void AffinitySetupInit() -{ - int i, j; - int ncpu = UtilCpuGetNumProcessorsConfigured(); - - SCLogDebug("Initialize affinity setup\n"); - /* be conservative relatively to OS: use all cpus by default */ - for (i = 0; i < MAX_CPU_SET; i++) { - cpu_set_t *cs = &thread_affinity[i].cpu_set; - CPU_ZERO(cs); - for (j = 0; j < ncpu; j++) { - CPU_SET(j, cs); - } - SCMutexInit(&thread_affinity[i].taf_mutex, NULL); - } - return; -} - -static void build_cpuset(char *name, ConfNode *node, cpu_set_t *cpu) -{ - ConfNode *lnode; - TAILQ_FOREACH(lnode, &node->head, next) { - int i; - long int a,b; - int stop = 0; - int max = UtilCpuGetNumProcessorsOnline() - 1; - if (!strcmp(lnode->val, "all")) { - a = 0; - b = max; - stop = 1; - } else if (index(lnode->val, '-') != NULL) { - char *sep = index(lnode->val, '-'); - char *end; - a = strtoul(lnode->val, &end, 10); - if (end != sep) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "%s: invalid cpu range (start invalid): \"%s\"", - name, - lnode->val); - exit(EXIT_FAILURE); - } - b = strtol(sep + 1, &end, 10); - if (end != sep + strlen(sep)) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "%s: invalid cpu range (end invalid): \"%s\"", - name, - lnode->val); - exit(EXIT_FAILURE); - } - if (a > b) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "%s: invalid cpu range (bad order): \"%s\"", - name, - lnode->val); - exit(EXIT_FAILURE); - } - if (b > max) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "%s: upper bound (%ld) of cpu set is too high, only %d cpu(s)", - name, - b, max + 1); - } - } else { - char *end; - a = strtoul(lnode->val, &end, 10); - if (end != lnode->val + strlen(lnode->val)) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "%s: invalid cpu range (not an integer): \"%s\"", - name, - lnode->val); - exit(EXIT_FAILURE); - } - b = a; - } - for (i = a; i<= b; i++) { - CPU_SET(i, cpu); - } - if (stop) - break; - } -} -#endif /* OS_WIN32 and __OpenBSD__ */ - -/** - * \brief Extract cpu affinity configuration from current config file - */ - -void AffinitySetupLoadFromConfig() -{ -#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ - ConfNode *root = ConfGetNode("threading.cpu-affinity"); - ConfNode *affinity; - - if (thread_affinity_init_done == 0) { - AffinitySetupInit(); - thread_affinity_init_done = 1; - } - - SCLogDebug("Load affinity from config\n"); - if (root == NULL) { - SCLogInfo("can't get cpu-affinity node"); - return; - } - - TAILQ_FOREACH(affinity, &root->head, next) { - ThreadsAffinityType *taf = GetAffinityTypeFromName(affinity->val); - ConfNode *node = NULL; - ConfNode *nprio = NULL; - - if (taf == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "unknown cpu-affinity type"); - exit(EXIT_FAILURE); - } else { - SCLogInfo("Found affinity definition for \"%s\"", - affinity->val); - } - - CPU_ZERO(&taf->cpu_set); - node = ConfNodeLookupChild(affinity->head.tqh_first, "cpu"); - if (node == NULL) { - SCLogInfo("unable to find 'cpu'"); - } else { - build_cpuset(affinity->val, node, &taf->cpu_set); - } - - CPU_ZERO(&taf->lowprio_cpu); - CPU_ZERO(&taf->medprio_cpu); - CPU_ZERO(&taf->hiprio_cpu); - nprio = ConfNodeLookupChild(affinity->head.tqh_first, "prio"); - if (nprio != NULL) { - node = ConfNodeLookupChild(nprio, "low"); - if (node == NULL) { - SCLogDebug("unable to find 'low' prio using default value"); - } else { - build_cpuset(affinity->val, node, &taf->lowprio_cpu); - } - - node = ConfNodeLookupChild(nprio, "medium"); - if (node == NULL) { - SCLogDebug("unable to find 'medium' prio using default value"); - } else { - build_cpuset(affinity->val, node, &taf->medprio_cpu); - } - - node = ConfNodeLookupChild(nprio, "high"); - if (node == NULL) { - SCLogDebug("unable to find 'high' prio using default value"); - } else { - build_cpuset(affinity->val, node, &taf->hiprio_cpu); - } - node = ConfNodeLookupChild(nprio, "default"); - if (node != NULL) { - if (!strcmp(node->val, "low")) { - taf->prio = PRIO_LOW; - } else if (!strcmp(node->val, "medium")) { - taf->prio = PRIO_MEDIUM; - } else if (!strcmp(node->val, "high")) { - taf->prio = PRIO_HIGH; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "unknown cpu_affinity prio"); - exit(EXIT_FAILURE); - } - SCLogInfo("Using default prio '%s'", node->val); - } - } - - node = ConfNodeLookupChild(affinity->head.tqh_first, "mode"); - if (node != NULL) { - if (!strcmp(node->val, "exclusive")) { - taf->mode_flag = EXCLUSIVE_AFFINITY; - } else if (!strcmp(node->val, "balanced")) { - taf->mode_flag = BALANCED_AFFINITY; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENT, "unknown cpu_affinity node"); - exit(EXIT_FAILURE); - } - } - - node = ConfNodeLookupChild(affinity->head.tqh_first, "threads"); - if (node != NULL) { - taf->nb_threads = atoi(node->val); - if (! taf->nb_threads) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "bad value for threads count"); - exit(EXIT_FAILURE); - } - } - } -#endif /* OS_WIN32 and __OpenBSD__ */ -} - -/** - * \brief Return next cpu to use for a given thread family - * \retval the cpu to used given by its id - */ -int AffinityGetNextCPU(ThreadsAffinityType *taf) -{ - int ncpu = 0; - -#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ - int iter = 0; - SCMutexLock(&taf->taf_mutex); - ncpu = taf->lcpu; - while (!CPU_ISSET(ncpu, &taf->cpu_set) && iter < 2) { - ncpu++; - if (ncpu >= UtilCpuGetNumProcessorsOnline()) { - ncpu = 0; - iter++; - } - } - if (iter == 2) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "cpu_set does not contains available cpus, cpu afinity conf is invalid"); - } - taf->lcpu = ncpu + 1; - if (taf->lcpu >= UtilCpuGetNumProcessorsOnline()) - taf->lcpu = 0; - SCMutexUnlock(&taf->taf_mutex); - SCLogInfo("Setting affinity on CPU %d", ncpu); -#endif /* OS_WIN32 and __OpenBSD__ */ - return ncpu; -} diff --git a/framework/src/suricata/src/util-affinity.h b/framework/src/suricata/src/util-affinity.h deleted file mode 100644 index 9ca30fcf..00000000 --- a/framework/src/suricata/src/util-affinity.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (C) 2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#ifndef __UTIL_AFFINITY_H__ -#define __UTIL_AFFINITY_H__ -#include "suricata-common.h" - -#if defined OS_FREEBSD -#include -#include -#include -#include -#include -#define cpu_set_t cpuset_t -#elif defined __OpenBSD__ -#include -#include -#include -#elif defined OS_DARWIN -#include -#include -#include -#define cpu_set_t thread_affinity_policy_data_t -#define CPU_SET(cpu_id, new_mask) (*(new_mask)).affinity_tag = (cpu_id + 1) -#define CPU_ISSET(cpu_id, new_mask) ((*(new_mask)).affinity_tag == (cpu_id + 1)) -#define CPU_ZERO(new_mask) (*(new_mask)).affinity_tag = THREAD_AFFINITY_TAG_NULL -#endif - -enum { - RECEIVE_CPU_SET, - DECODE_CPU_SET, - STREAM_CPU_SET, - DETECT_CPU_SET, - VERDICT_CPU_SET, - REJECT_CPU_SET, - OUTPUT_CPU_SET, - MANAGEMENT_CPU_SET, - MAX_CPU_SET -}; - -enum { - BALANCED_AFFINITY, - EXCLUSIVE_AFFINITY, - MAX_AFFINITY -}; - -typedef struct ThreadsAffinityType_ { - char *name; -#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ - cpu_set_t cpu_set; -#endif - uint8_t mode_flag; - int prio; - int nb_threads; -#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ - cpu_set_t lowprio_cpu; - cpu_set_t medprio_cpu; - cpu_set_t hiprio_cpu; -#endif - SCMutex taf_mutex; - uint16_t lcpu; /* use by exclusive mode */ -} ThreadsAffinityType; - -/** store thread affinity mode for all type of threads */ -#ifndef _THREAD_AFFINITY -extern ThreadsAffinityType thread_affinity[MAX_CPU_SET]; -#endif - -void AffinitySetupLoadFromConfig(); -ThreadsAffinityType * GetAffinityTypeFromName(const char *name); - -int AffinityGetNextCPU(ThreadsAffinityType *taf); - -#endif /* __UTIL_AFFINITY_H__ */ diff --git a/framework/src/suricata/src/util-atomic.c b/framework/src/suricata/src/util-atomic.c deleted file mode 100644 index 9ad448e6..00000000 --- a/framework/src/suricata/src/util-atomic.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "util-atomic.h" -#include "util-unittest.h" - -#ifdef UNITTESTS - -static int SCAtomicTest01(void) -{ - int result = 0; - int a = 10; - int b = 20; - int *temp_int = NULL; - - SC_ATOMIC_DECL_AND_INIT(void *, temp); - - temp_int = SC_ATOMIC_GET(temp); - if (temp_int != NULL) - goto end; - - (void)SC_ATOMIC_SET(temp, &a); - temp_int = SC_ATOMIC_GET(temp); - if (temp_int == NULL) - goto end; - if (*temp_int != a) - goto end; - - (void)SC_ATOMIC_SET(temp, &b); - temp_int = SC_ATOMIC_GET(temp); - if (temp_int == NULL) - goto end; - if (*temp_int != b) - goto end; - - result = 1; - - end: - return result; -} - -#endif /* UNITTESTS */ - -void SCAtomicRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SCAtomicTest01", SCAtomicTest01, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/util-atomic.h b/framework/src/suricata/src/util-atomic.h deleted file mode 100644 index cbcfc868..00000000 --- a/framework/src/suricata/src/util-atomic.h +++ /dev/null @@ -1,476 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon - * - * API for atomic operations. Uses atomic instructions (GCC only at this time) - * where available, falls back to (spin)locked* operations otherwise. - * - * To prevent developers from accidentally working with the atomic variables - * directly instead of through the proper macro's, a marco trick is performed - * that exposes different variable names than the developer uses. So if the dev - * uses "somevar", internally "somevar_sc_atomic__" is used. - * - * Where available, we use __sync_fetch_and_add and - * __sync_bool_compare_and_swap. If those are unavailable, the API - * transparently created a matching (spin)lock for each atomic variable. The - * lock will be named "somevar_sc_lock__" - * - * (*) where spinlocks are unavailable, the threading api falls back to mutex - */ - - -#ifndef __UTIL_ATOMIC_H__ -#define __UTIL_ATOMIC_H__ - -/* test if we have atomic operations support */ -#if (!defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || \ - !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)) && \ - !defined(__tile__) - -/* Do not have atomic operations support, so implement them with locks. */ - -/** - * \brief wrapper to declare an atomic variable including a (spin) lock - * to protect it. - * - * \warning Variable and lock are _not_ initialized. - */ -#define SC_ATOMIC_DECLARE(type, name) \ - type name ## _sc_atomic__; \ - SCSpinlock name ## _sc_lock__ - -/** - * \brief wrapper to reference an atomic variable already declared on another file (including the spin lock) - * - */ -#define SC_ATOMIC_EXTERN(type, name) \ - extern type name ## _sc_atomic__; \ - extern SCSpinlock name ## _sc_lock__ - -/** - * \brief wrapper to declare an atomic variable including a (spin) lock - * to protect it and initialize them. - */ -#define SC_ATOMIC_DECL_AND_INIT(type, name) \ - type name ## _sc_atomic__ = 0; \ - SCSpinlock name ## _sc_lock__; \ - SCSpinInit(&(name ## _sc_lock__), 0) - -/** - * \brief Initialize the previously declared atomic variable and it's - * lock. - */ -#define SC_ATOMIC_INIT(name) do { \ - SCSpinInit(&(name ## _sc_lock__), 0); \ - (name ## _sc_atomic__) = 0; \ - } while(0) - -/** - * \brief Initialize the previously declared atomic variable and it's - * lock. - */ -#define SC_ATOMIC_RESET(name) do { \ - (name ## _sc_atomic__) = 0; \ - } while(0) - -/** - * \brief Destroy the lock used to protect this variable - */ -#define SC_ATOMIC_DESTROY(name) do { \ - SCSpinDestroy(&(name ## _sc_lock__)); \ - } while (0) - -/** - * \brief add a value to our atomic variable - * - * \param name the atomic variable - * \param val the value to add to the variable - */ -#define SC_ATOMIC_ADD(name, val) ({\ - typeof(name ## _sc_atomic__) var; \ - do { \ - SCSpinLock(&(name ## _sc_lock__)); \ - (name ## _sc_atomic__) += (val); \ - var = (name ## _sc_atomic__); \ - SCSpinUnlock(&(name ## _sc_lock__)); \ - } while(0); \ - var ; \ -}) - -/** - * \brief sub a value from our atomic variable - * - * \param name the atomic variable - * \param val the value to sub from the variable - */ -#define SC_ATOMIC_SUB(name, val) ({ \ - typeof(name ## _sc_atomic__) var; \ - do { \ - SCSpinLock(&(name ## _sc_lock__)); \ - (name ## _sc_atomic__) -= (val); \ - var = (name ## _sc_atomic__); \ - SCSpinUnlock(&(name ## _sc_lock__)); \ - } while(0); \ - var ; \ -}) - -/** - * \brief Bitwise AND a value from our atomic variable - * - * \param name the atomic variable - * \param val the value to sub from the variable - */ -#define SC_ATOMIC_AND(name, val) \ - do { \ - SCSpinLock(&(name ## _sc_lock__)); \ - (name ## _sc_atomic__) &= (val); \ - SCSpinUnlock(&(name ## _sc_lock__)); \ - } while(0) - -/** - * \brief Bitwise OR a value from our atomic variable - * - * \param name the atomic variable - * \param val the value to sub from the variable - */ -#define SC_ATOMIC_OR(name, val) \ - do { \ - SCSpinLock(&(name ## _sc_lock__)); \ - (name ## _sc_atomic__) |= (val); \ - SCSpinUnlock(&(name ## _sc_lock__)); \ - } while(0) - -/** - * \brief Bitwise NAND a value from our atomic variable - * - * \param name the atomic variable - * \param val the value to sub from the variable - */ -#define SC_ATOMIC_NAND(name, val) \ - do { \ - SCSpinLock(&(name ## _sc_lock__)); \ - (name ## _sc_atomic__) = ~(name ## _sc_atomic__) & (val); \ - SCSpinUnlock(&(name ## _sc_lock__)); \ - } while(0) - -/** - * \brief Bitwise XOR a value from our atomic variable - * - * \param name the atomic variable - * \param val the value to sub from the variable - */ -#define SC_ATOMIC_XOR(name, val) \ - do { \ - SCSpinLock(&(name ## _sc_lock__)); \ - (name ## _sc_atomic__) ^= (val); \ - SCSpinUnlock(&(name ## _sc_lock__)); \ - } while(0) - -/** - * \brief Get the value from the atomic variable. - * - * \retval var value - */ -#define SC_ATOMIC_GET(name) ({ \ - typeof(name ## _sc_atomic__) var; \ - do { \ - SCSpinLock(&(name ## _sc_lock__)); \ - var = (name ## _sc_atomic__); \ - SCSpinUnlock(&(name ## _sc_lock__)); \ - } while (0); \ - var; \ -}) - -/** - * \brief Set the value for the atomic variable. - * - * \retval var value - */ -#define SC_ATOMIC_SET(name, val) ({ \ - typeof(name ## _sc_atomic__) var; \ - do { \ - SCSpinLock(&(name ## _sc_lock__)); \ - var = (name ## _sc_atomic__) = val; \ - SCSpinUnlock(&(name ## _sc_lock__)); \ - } while (0); \ - var; \ -}) - -/** - * \brief atomic Compare and Switch - * - * \warning "name" is passed to us as "&var" - */ -#define SC_ATOMIC_CAS(name, cmpval, newval) ({ \ - char r = 0; \ - do { \ - SCSpinLock((name ## _sc_lock__)); \ - if (*(name ## _sc_atomic__) == (cmpval)) { \ - *(name ## _sc_atomic__) = (newval); \ - r = 1; \ - } \ - SCSpinUnlock((name ## _sc_lock__)); \ - } while(0); \ - r; \ -}) - -#else /* we do have support for CAS */ - -/** - * \brief wrapper for OS/compiler specific atomic compare and swap (CAS) - * function. - * - * \param addr Address of the variable to CAS - * \param tv Test value to compare the value at address against - * \param nv New value to set the variable at addr to - * - * \retval 0 CAS failed - * \retval 1 CAS succeeded - */ -#define SCAtomicCompareAndSwap(addr, tv, nv) \ - __sync_bool_compare_and_swap((addr), (tv), (nv)) - -/** - * \brief wrapper for OS/compiler specific atomic fetch and add - * function. - * - * \param addr Address of the variable to add to - * \param value Value to add to the variable at addr - */ -#define SCAtomicFetchAndAdd(addr, value) \ - __sync_fetch_and_add((addr), (value)) - -/** - * \brief wrapper for OS/compiler specific atomic fetch and sub - * function. - * - * \param addr Address of the variable to add to - * \param value Value to sub from the variable at addr - */ -#define SCAtomicFetchAndSub(addr, value) \ - __sync_fetch_and_sub((addr), (value)) - -/** - * \brief wrapper for OS/compiler specific atomic fetch and add - * function. - * - * \param addr Address of the variable to add to - * \param value Value to add to the variable at addr - */ -#define SCAtomicAddAndFetch(addr, value) \ - __sync_add_and_fetch((addr), (value)) - -/** - * \brief wrapper for OS/compiler specific atomic fetch and sub - * function. - * - * \param addr Address of the variable to add to - * \param value Value to sub from the variable at addr - */ -#define SCAtomicSubAndFetch(addr, value) \ - __sync_sub_and_fetch((addr), (value)) - - - -/** - * \brief wrapper for OS/compiler specific atomic fetch and "AND" - * function. - * - * \param addr Address of the variable to AND to - * \param value Value to add to the variable at addr - */ -#define SCAtomicFetchAndAnd(addr, value) \ - __sync_fetch_and_and((addr), (value)) - -/** - * \brief wrapper for OS/compiler specific atomic fetch and "NAND" - * function. - * - * \param addr Address of the variable to NAND to - * \param value Value to add to the variable at addr - */ -#define SCAtomicFetchAndNand(addr, value) \ - __sync_fetch_and_nand((addr), (value)) - -/** - * \brief wrapper for OS/compiler specific atomic fetch and "XOR" - * function. - * - * \param addr Address of the variable to XOR to - * \param value Value to add to the variable at addr - */ -#define SCAtomicFetchAndXor(addr, value) \ - __sync_fetch_and_xor((addr), (value)) - - -/** - * \brief wrapper for OS/compiler specific atomic fetch and or - * function. - * - * \param addr Address of the variable to or to - * \param value Value to add to the variable at addr - */ -#define SCAtomicFetchAndOr(addr, value) \ - __sync_fetch_and_or((addr), (value)) - -/** - * \brief wrapper for declaring atomic variables. - * - * \warning Only char, short, int, long, long long and their unsigned - * versions are supported. - * - * \param type Type of the variable (char, short, int, long, long long) - * \param name Name of the variable. - * - * We just declare the variable here as we rely on atomic operations - * to modify it, so no need for locks. - * - * \warning variable is not initialized - */ -#define SC_ATOMIC_DECLARE(type, name) \ - type name ## _sc_atomic__ - -/** - * \brief wrapper for referencing an atomic variable declared on another file. - * - * \warning Only char, short, int, long, long long and their unsigned - * versions are supported. - * - * \param type Type of the variable (char, short, int, long, long long) - * \param name Name of the variable. - * - * We just declare the variable here as we rely on atomic operations - * to modify it, so no need for locks. - * - */ -#define SC_ATOMIC_EXTERN(type, name) \ - extern type name ## _sc_atomic__ - -/** - * \brief wrapper for declaring an atomic variable and initializing it. - **/ -#define SC_ATOMIC_DECL_AND_INIT(type, name) \ - type name ## _sc_atomic__ = 0 - -/** - * \brief wrapper for initializing an atomic variable. - **/ -#define SC_ATOMIC_INIT(name) \ - (name ## _sc_atomic__) = 0 - -/** - * \brief wrapper for reinitializing an atomic variable. - **/ -#define SC_ATOMIC_RESET(name) \ - (name ## _sc_atomic__) = 0 - -/** - * \brief No-op. - */ -#define SC_ATOMIC_DESTROY(name) - -/** - * \brief add a value to our atomic variable - * - * \param name the atomic variable - * \param val the value to add to the variable - */ -#define SC_ATOMIC_ADD(name, val) \ - SCAtomicAddAndFetch(&(name ## _sc_atomic__), (val)) - -/** - * \brief sub a value from our atomic variable - * - * \param name the atomic variable - * \param val the value to sub from the variable - */ -#define SC_ATOMIC_SUB(name, val) \ - SCAtomicSubAndFetch(&(name ## _sc_atomic__), (val)) - -/** - * \brief Bitwise OR a value to our atomic variable - * - * \param name the atomic variable - * \param val the value to OR to the variable - */ -#define SC_ATOMIC_OR(name, val) \ - SCAtomicFetchAndOr(&(name ## _sc_atomic__), (val)) - -/** - * \brief Bitwise AND a value to our atomic variable - * - * \param name the atomic variable - * \param val the value to AND to the variable - */ -#define SC_ATOMIC_AND(name, val) \ - SCAtomicFetchAndAnd(&(name ## _sc_atomic__), (val)) - -/** - * \brief Bitwise NAND a value to our atomic variable - * - * \param name the atomic variable - * \param val the value to NAND to the variable - */ -#define SC_ATOMIC_NAND(name, val) \ - SCAtomicFetchAndNand(&(name ## _sc_atomic__), (val)) - -/** - * \brief Bitwise XOR a value to our atomic variable - * - * \param name the atomic variable - * \param val the value to XOR to the variable - */ -#define SC_ATOMIC_XOR(name, val) \ - SCAtomicFetchAndXor(&(name ## _sc_atomic__), (val)) - -/** - * \brief atomic Compare and Switch - * - * \warning "name" is passed to us as "&var" - */ -#define SC_ATOMIC_CAS(name, cmpval, newval) \ - SCAtomicCompareAndSwap((name ## _sc_atomic__), cmpval, newval) - -/** - * \brief Get the value from the atomic variable. - * - * \retval var value - */ -#define SC_ATOMIC_GET(name) \ - (name ## _sc_atomic__) - -/** - * \brief Set the value for the atomic variable. - * - * \retval var value - */ -#define SC_ATOMIC_SET(name, val) ({ \ - while (SC_ATOMIC_CAS(&name, SC_ATOMIC_GET(name), val) == 0) \ - ; \ - }) - -#endif /* !no atomic operations */ - -void SCAtomicRegisterTests(void); - -#endif /* __UTIL_ATOMIC_H__ */ - diff --git a/framework/src/suricata/src/util-base64.c b/framework/src/suricata/src/util-base64.c deleted file mode 100644 index bea92d52..00000000 --- a/framework/src/suricata/src/util-base64.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author David Abarbanel - * - */ - -#include "util-base64.h" - -/* Constants */ -#define BASE64_TABLE_MAX 122 - -/* Base64 character to index conversion table */ -/* Characters are mapped as "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" */ -static const int b64table[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, - -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51 }; - -/** - * \brief Gets a base64-decoded value from an encoded character - * - * \param c The encoded character - * - * \return The decoded value (0 or above), or -1 if the parameter is invalid - */ -static inline int GetBase64Value(uint8_t c) -{ - int val = -1; - - /* Pull from conversion table */ - if (c <= BASE64_TABLE_MAX) { - val = b64table[(int) c]; - } - - return val; -} - -/** - * \brief Decodes a 4-byte base64-encoded block into a 3-byte ascii-encoded block - * - * \param ascii the 3-byte ascii output block - * \param b64 the 4-byte base64 input block - * - * \return none - */ -static inline void DecodeBase64Block(uint8_t ascii[ASCII_BLOCK], uint8_t b64[B64_BLOCK]) -{ - ascii[0] = (uint8_t) (b64[0] << 2) | (b64[1] >> 4); - ascii[1] = (uint8_t) (b64[1] << 4) | (b64[2] >> 2); - ascii[2] = (uint8_t) (b64[2] << 6) | (b64[3]); -} - -/** - * \brief Decodes a base64-encoded string buffer into an ascii-encoded byte buffer - * - * \param dest The destination byte buffer - * \param src The source string - * \param len The length of the source string - * \param strict If set file on invalid byte, otherwise return what has been - * decoded. - * - * \return Number of bytes decoded, or 0 if no data is decoded or it fails - */ -uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len, - int strict) -{ - int val; - uint32_t padding = 0, numDecoded = 0, bbidx = 0, valid = 1, i; - uint8_t *dptr = dest; - uint8_t b64[B64_BLOCK] = { 0,0,0,0 }; - - /* Traverse through each alpha-numeric letter in the source array */ - for(i = 0; i < len && src[i] != 0; i++) { - - /* Get decimal representation */ - val = GetBase64Value(src[i]); - if (val < 0) { - - /* Invalid character found, so decoding fails */ - if (src[i] != '=') { - valid = 0; - if (strict) { - numDecoded = 0; - } - break; - } - padding++; - } - - /* For each alpha-numeric letter in the source array, find the numeric - * value */ - b64[bbidx++] = (val > 0 ? val : 0); - - /* Decode every 4 base64 bytes into 3 ascii bytes */ - if (bbidx == B64_BLOCK) { - - /* For every 4 bytes, add 3 bytes but deduct the '=' padded blocks */ - numDecoded += ASCII_BLOCK - (padding < B64_BLOCK ? - padding : ASCII_BLOCK); - - /* Decode base-64 block into ascii block and move pointer */ - DecodeBase64Block(dptr, b64); - dptr += ASCII_BLOCK; - - /* Reset base-64 block and index */ - bbidx = 0; - padding = 0; - } - } - - /* Finish remaining b64 bytes by padding */ - if (valid && bbidx > 0) { - - /* Decode remaining */ - numDecoded += ASCII_BLOCK - (B64_BLOCK - bbidx); - DecodeBase64Block(dptr, b64); - } - - if (numDecoded == 0) { - SCLogDebug("base64 decoding failed"); - } - - return numDecoded; -} diff --git a/framework/src/suricata/src/util-base64.h b/framework/src/suricata/src/util-base64.h deleted file mode 100644 index 7c8bed62..00000000 --- a/framework/src/suricata/src/util-base64.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author David Abarbanel - * - */ - -#ifndef __UTIL_BASE64_H_ -#define __UTIL_BASE64_H_ - -#include "suricata-common.h" -#include "threads.h" -#include "debug.h" -#include "decode.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-state.h" - -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - -#include "util-debug.h" -#include "util-spm-bm.h" - -/* Constants */ -#define ASCII_BLOCK 3 -#define B64_BLOCK 4 - -/* Function prototypes */ -uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len, - int strict); - -#endif diff --git a/framework/src/suricata/src/util-binsearch.c b/framework/src/suricata/src/util-binsearch.c deleted file mode 100644 index 59627759..00000000 --- a/framework/src/suricata/src/util-binsearch.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Binary search utility functions - * - * \todo replace this by a better algo - */ - -#include "suricata-common.h" -#include "suricata.h" - -void BinSearchInit (void) -{ - /* nothing no more */ -} - -/* Binary search. - * - * Returns: - * - ptr to start of the match - * - null if no match - */ -/* simple bin search modelled loosely after strstr */ -uint8_t * -BinSearch(const uint8_t *haystack, size_t haystack_len, - const uint8_t *needle, size_t needle_len) -{ - const uint8_t *h, *n; - const uint8_t *hmax = haystack + haystack_len; - const uint8_t *nmax = needle + (needle_len - 1); - - if (needle_len == 0) - return NULL; - - for (n = needle; haystack != hmax; haystack++) { - if (*haystack != *n) { - continue; - } - /* one byte needles */ - if (needle_len == 1) - return (uint8_t *)haystack; - - for (h = haystack+1, n++; h != hmax; h++, n++) { - //printf("h %c n %c\n", isprint(*h) ? *h : 'X', *n); - if (*h != *n) { - break; - } - /* if we run out of needle we fully matched */ - if (n == nmax) { - return (uint8_t *)haystack; - } - } - n = needle; - } - return NULL; -} - -/* Caseless binary search. More expensive that the one that - * respects case. - * - * Returns: - * - ptr to start of the match - * - null if no match - */ -uint8_t * -BinSearchNocase(const uint8_t *haystack, size_t haystack_len, - const uint8_t *needle, size_t needle_len) -{ - const uint8_t *h, *n; - const uint8_t *hmax = haystack + haystack_len; - const uint8_t *nmax = needle + (needle_len - 1); - - if (needle_len == 0) - return NULL; - - for (n = needle; haystack != hmax; haystack++) { - if (*haystack != *n && *haystack != u8_tolower(*n)) { - continue; - } - for (h = haystack+1, n++; h != hmax; h++, n++) { - if (*h != *n && *h != u8_tolower(*n)) { - break; - } - /* if we run out of needle we fully matched */ - if (n == nmax) { - return (uint8_t *)haystack; - } - } - n = needle; - } - return NULL; -} - diff --git a/framework/src/suricata/src/util-binsearch.h b/framework/src/suricata/src/util-binsearch.h deleted file mode 100644 index 857e0838..00000000 --- a/framework/src/suricata/src/util-binsearch.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_BINSEARCH_H__ -#define __UTIL_BINSEARCH_H__ - -void BinSearchInit (void); -uint8_t *BinSearch(const uint8_t *, size_t, const uint8_t *, size_t); -uint8_t *BinSearchNocase(const uint8_t *, size_t, const uint8_t *, size_t); - -#endif /* __UTIL_BINSEARCH_H__ */ - diff --git a/framework/src/suricata/src/util-bloomfilter-counting.c b/framework/src/suricata/src/util-bloomfilter-counting.c deleted file mode 100644 index 443b8d79..00000000 --- a/framework/src/suricata/src/util-bloomfilter-counting.c +++ /dev/null @@ -1,410 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Counting Bloom Filter implementation. Can be used with 8, 16, 32 bits - * counters. - */ - -#include "suricata-common.h" -#include "util-bloomfilter-counting.h" -#include "util-unittest.h" - -/* type: 1, 2 or 4 for 8, 16, or 32 bit counters - * - */ -BloomFilterCounting *BloomFilterCountingInit(uint32_t size, uint8_t type, uint8_t iter, uint32_t (*Hash)(void *, uint16_t, uint8_t, uint32_t)) { - BloomFilterCounting *bf = NULL; - - if (iter == 0) - goto error; - - if (Hash == NULL || size == 0) { - //printf("ERROR: BloomFilterCountingInit no Hash function\n"); - goto error; - } - - if (type != 1 && type != 2 && type != 4) { - //printf("ERROR: BloomFilterCountingInit only 1, 2 and 4 bytes are supported\n"); - goto error; - } - - /* setup the filter */ - bf = SCMalloc(sizeof(BloomFilterCounting)); - if (unlikely(bf == NULL)) - goto error; - memset(bf,0,sizeof(BloomFilterCounting)); - bf->type = type; /* size of the type: 1, 2, 4 */ - bf->array_size = size; - bf->hash_iterations = iter; - bf->Hash = Hash; - - /* setup the bitarray */ - bf->array = SCMalloc(bf->array_size * bf->type); - if (bf->array == NULL) - goto error; - memset(bf->array,0,bf->array_size * bf->type); - - return bf; - -error: - if (bf != NULL) { - if (bf->array != NULL) - SCFree(bf->array); - - SCFree(bf); - } - return NULL; -} - -void BloomFilterCountingFree(BloomFilterCounting *bf) -{ - if (bf != NULL) { - if (bf->array != NULL) - SCFree(bf->array); - - SCFree(bf); - } -} - -void BloomFilterCountingPrint(BloomFilterCounting *bf) -{ - printf("\n------ Counting Bloom Filter Stats ------\n"); - printf("Buckets: %" PRIu32 "\n", bf->array_size); - printf("Counter size: %" PRIu32 "\n", bf->type); - printf("Memory size: %" PRIu32 " bytes\n", bf->array_size * bf->type); - printf("Hash function pointer: %p\n", bf->Hash); - printf("Hash functions: %" PRIu32 "\n", bf->hash_iterations); - printf("-----------------------------------------\n"); -} - -int BloomFilterCountingAdd(BloomFilterCounting *bf, void *data, uint16_t datalen) -{ - uint8_t iter = 0; - uint32_t hash = 0; - - if (bf == NULL || data == NULL || datalen == 0) - return -1; - - for (iter = 0; iter < bf->hash_iterations; iter++) { - hash = bf->Hash(data, datalen, iter, bf->array_size) * bf->type; - if (bf->type == 1) { - uint8_t *u8 = (uint8_t *)&bf->array[hash]; - if ((*u8) != 255) - (*u8)++; - } else if (bf->type == 2) { - uint16_t *u16 = (uint16_t *)&bf->array[hash]; - if ((*u16) != 65535) - (*u16)++; - } else if (bf->type == 4) { - uint32_t *u32 = (uint32_t *)&bf->array[hash]; - if ((*u32) != 4294967295UL) - (*u32)++; - } - } - - return 0; -} - -int BloomFilterCountingRemove(BloomFilterCounting *bf, void *data, uint16_t datalen) -{ - uint8_t iter = 0; - uint32_t hash = 0; - - if (bf == NULL || data == NULL || datalen == 0) - return -1; - - /* only remove data that was actually added */ - if (BloomFilterCountingTest(bf, data, datalen) == 0) { - printf("ERROR: BloomFilterCountingRemove tried to remove data " - "that was never added to the set or was already removed.\n"); - return -1; - } - - /* decrease counters for every iteration */ - for (iter = 0; iter < bf->hash_iterations; iter++) { - hash = bf->Hash(data, datalen, iter, bf->array_size) * bf->type; - if (bf->type == 1) { - uint8_t *u8 = (uint8_t *)&bf->array[hash]; - if ((*u8) > 0) - (*u8)--; - else { - printf("ERROR: BloomFilterCountingRemove tried to decrease a " - "counter below zero.\n"); - return -1; - } - } else if (bf->type == 2) { - uint16_t *u16 = (uint16_t *)&bf->array[hash]; - if ((*u16) > 0) - (*u16)--; - else { - printf("ERROR: BloomFilterCountingRemove tried to decrease a " - "counter below zero.\n"); - return -1; - } - } else if (bf->type == 4) { - uint32_t *u32 = (uint32_t *)&bf->array[hash]; - if ((*u32) > 0) - (*u32)--; - else { - printf("ERROR: BloomFilterCountingRemove tried to decrease a " - "counter below zero.\n"); - return -1; - } - } - } - - return 0; -} - -/* Test if data matches our filter and is likely to be in the set - * - * returns 0: for no match - * 1: match - */ -int BloomFilterCountingTest(BloomFilterCounting *bf, void *data, uint16_t datalen) -{ - uint8_t iter = 0; - uint32_t hash = 0; - int hit = 1; - - /* check each hash iteration */ - for (iter = 0; iter < bf->hash_iterations; iter++) { - hash = bf->Hash(data, datalen, iter, bf->array_size) * bf->type; - if (bf->type == 1) { - uint8_t *u8 = (uint8_t *)&bf->array[hash]; - if ((*u8) == 0x00) { - hit = 0; - break; - } - } else if (bf->type == 2) { - uint16_t *u16 = (uint16_t *)&bf->array[hash]; - if ((*u16) == 0x0000) { - hit = 0; - break; - } - } else if (bf->type == 4) { - uint32_t *u32 = (uint32_t *)&bf->array[hash]; - if ((*u32) == 0x00000000) { - hit = 0; - break; - } - } - } - - return hit; -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -static uint32_t BloomHash(void *data, uint16_t datalen, uint8_t iter, uint32_t hash_size) -{ - uint8_t *d = (uint8_t *)data; - uint32_t i; - uint32_t hash = 0; - - for (i = 0; i < datalen; i++) { - if (i == 0) hash += (((uint32_t)*d++)); - else if (i == 1) hash += (((uint32_t)*d++) * datalen); - else hash *= (((uint32_t)*d++) * i); - } - - hash *= (iter + datalen); - hash %= hash_size; - return hash; -} - -static int BloomFilterCountingTestInit01 (void) -{ - BloomFilterCounting *bf = BloomFilterCountingInit(1024, 4, 4, BloomHash); - if (bf == NULL) - return 0; - - BloomFilterCountingFree(bf); - return 1; -} - -/* no hash function, so it should fail */ -static int BloomFilterCountingTestInit02 (void) -{ - BloomFilterCounting *bf = BloomFilterCountingInit(1024, 4, 4, NULL); - if (bf == NULL) - return 1; - - BloomFilterCountingFree(bf); - return 0; -} - -static int BloomFilterCountingTestInit03 (void) -{ - int result = 0; - BloomFilterCounting *bf = BloomFilterCountingInit(1024, 4, 4, BloomHash); - if (bf == NULL) - return 0; - - if (bf->Hash == BloomHash) - result = 1; - - BloomFilterCountingFree(bf); - return result; -} - -static int BloomFilterCountingTestInit04 (void) -{ - BloomFilterCounting *bf = BloomFilterCountingInit(1024, 0, 4, BloomHash); - if (bf == NULL) - return 1; - - BloomFilterCountingFree(bf); - return 0; -} - -static int BloomFilterCountingTestInit05 (void) -{ - BloomFilterCounting *bf = BloomFilterCountingInit(0, 4, 4, BloomHash); - if (bf == NULL) - return 1; - - BloomFilterCountingFree(bf); - return 0; -} - -static int BloomFilterCountingTestInit06 (void) -{ - BloomFilterCounting *bf = BloomFilterCountingInit(32, 3, 4, BloomHash); - if (bf == NULL) - return 1; - - BloomFilterCountingFree(bf); - return 0; -} - -static int BloomFilterCountingTestAdd01 (void) -{ - int result = 0; - BloomFilterCounting *bf = BloomFilterCountingInit(1024, 4, 4, BloomHash); - if (bf == NULL) - return 0; - - int r = BloomFilterCountingAdd(bf, "test", 0); - if (r == 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (bf != NULL) BloomFilterCountingFree(bf); - return result; -} - -static int BloomFilterCountingTestAdd02 (void) -{ - int result = 0; - BloomFilterCounting *bf = BloomFilterCountingInit(1024, 4, 4, BloomHash); - if (bf == NULL) - return 0; - - int r = BloomFilterCountingAdd(bf, NULL, 4); - if (r == 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (bf != NULL) BloomFilterCountingFree(bf); - return result; -} - -static int BloomFilterCountingTestFull01 (void) -{ - int result = 0; - BloomFilterCounting *bf = BloomFilterCountingInit(32, 4, 4, BloomHash); - if (bf == NULL) { - printf("init failed: "); - goto end; - } - - int r = BloomFilterCountingAdd(bf, "test", 4); - if (r != 0) { - printf("first add: "); - goto end; - } - - r = BloomFilterCountingTest(bf, "test", 4); - if (r != 1) { - printf("2nd add: "); - goto end; - } - - r = BloomFilterCountingRemove(bf, "test", 4); - if (r != 0) { - printf("3rd add: "); - goto end; - } - - /* all is good! */ - result = 1; -end: - if (bf != NULL) - BloomFilterCountingFree(bf); - return result; -} - -static int BloomFilterCountingTestFull02 (void) -{ - int result = 0; - BloomFilterCounting *bf = BloomFilterCountingInit(32, 4, 4, BloomHash); - if (bf == NULL) - goto end; - - int r = BloomFilterCountingTest(bf, "test", 4); - if (r != 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (bf != NULL) BloomFilterCountingFree(bf); - return result; -} -#endif - -void BloomFilterCountingRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("BloomFilterCountingTestInit01", BloomFilterCountingTestInit01, 1); - UtRegisterTest("BloomFilterCountingTestInit02", BloomFilterCountingTestInit02, 1); - UtRegisterTest("BloomFilterCountingTestInit03", BloomFilterCountingTestInit03, 1); - UtRegisterTest("BloomFilterCountingTestInit04", BloomFilterCountingTestInit04, 1); - UtRegisterTest("BloomFilterCountingTestInit05", BloomFilterCountingTestInit05, 1); - UtRegisterTest("BloomFilterCountingTestInit06", BloomFilterCountingTestInit06, 1); - - UtRegisterTest("BloomFilterCountingTestAdd01", BloomFilterCountingTestAdd01, 1); - UtRegisterTest("BloomFilterCountingTestAdd02", BloomFilterCountingTestAdd02, 1); - - UtRegisterTest("BloomFilterCountingTestFull01", BloomFilterCountingTestFull01, 1); - UtRegisterTest("BloomFilterCountingTestFull02", BloomFilterCountingTestFull02, 1); -#endif -} - diff --git a/framework/src/suricata/src/util-bloomfilter-counting.h b/framework/src/suricata/src/util-bloomfilter-counting.h deleted file mode 100644 index 80d790be..00000000 --- a/framework/src/suricata/src/util-bloomfilter-counting.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __BLOOMFILTERCOUNTING_H__ -#define __BLOOMFILTERCOUNTING_H__ - -/* Bloom filter structure */ -typedef struct BloomFilterCounting_ { - uint8_t *array; - uint32_t array_size; /* size in buckets */ - uint8_t type; /* 1, 2 or 4 byte counters */ - uint8_t hash_iterations; - uint32_t (*Hash)(void *, uint16_t, uint8_t, uint32_t); -} BloomFilterCounting; - -/* prototypes */ -BloomFilterCounting *BloomFilterCountingInit(uint32_t, uint8_t, uint8_t, uint32_t (*Hash)(void *, uint16_t, uint8_t, uint32_t)); -void BloomFilterCountingFree(BloomFilterCounting *); -void BloomFilterCountingPrint(BloomFilterCounting *); -int BloomFilterCountingAdd(BloomFilterCounting *, void *, uint16_t); -int BloomFilterCountingRemove(BloomFilterCounting *, void *, uint16_t); -int BloomFilterCountingTest(BloomFilterCounting *, void *, uint16_t); - -void BloomFilterCountingRegisterTests(void); - -#endif /* __BLOOMFILTERCOUNTING_H__ */ - diff --git a/framework/src/suricata/src/util-bloomfilter.c b/framework/src/suricata/src/util-bloomfilter.c deleted file mode 100644 index 5718fb10..00000000 --- a/framework/src/suricata/src/util-bloomfilter.c +++ /dev/null @@ -1,290 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Bitwise bloom filter implementation - */ - -#include "suricata-common.h" -#include "util-bloomfilter.h" -#include "util-unittest.h" - -BloomFilter *BloomFilterInit(uint32_t size, uint8_t iter, uint32_t (*Hash)(void *, uint16_t, uint8_t, uint32_t)) { - BloomFilter *bf = NULL; - - if (size == 0 || iter == 0) - goto error; - - if (Hash == NULL) { - //printf("ERROR: BloomFilterInit no Hash function\n"); - goto error; - } - - /* setup the filter */ - bf = SCMalloc(sizeof(BloomFilter)); - if (unlikely(bf == NULL)) - goto error; - memset(bf,0,sizeof(BloomFilter)); - bf->bitarray_size = size; - bf->hash_iterations = iter; - bf->Hash = Hash; - - /* setup the bitarray */ - bf->bitarray = SCMalloc((bf->bitarray_size/8)+1); - if (bf->bitarray == NULL) - goto error; - memset(bf->bitarray,0,(bf->bitarray_size/8)+1); - - return bf; - -error: - if (bf != NULL) { - if (bf->bitarray != NULL) - SCFree(bf->bitarray); - - SCFree(bf); - } - return NULL; -} - -void BloomFilterFree(BloomFilter *bf) -{ - if (bf != NULL) { - if (bf->bitarray != NULL) - SCFree(bf->bitarray); - - SCFree(bf); - } -} - -void BloomFilterPrint(BloomFilter *bf) -{ - printf("\n---------- Bloom Filter Stats -----------\n"); - printf("Buckets: %" PRIu32 "\n", bf->bitarray_size); - printf("Memory size: %" PRIu32 " bytes\n", bf->bitarray_size/8 + 1); - printf("Hash function pointer: %p\n", bf->Hash); - printf("Hash functions: %" PRIu32 "\n", bf->hash_iterations); - printf("-----------------------------------------\n"); -} - -int BloomFilterAdd(BloomFilter *bf, void *data, uint16_t datalen) -{ - uint8_t iter = 0; - uint32_t hash = 0; - - if (bf == NULL || data == NULL || datalen == 0) - return -1; - - for (iter = 0; iter < bf->hash_iterations; iter++) { - hash = bf->Hash(data, datalen, iter, bf->bitarray_size); - bf->bitarray[hash/8] |= (1<bitarray_size/8) + 1); -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -static uint32_t BloomFilterTestHash(void *data, uint16_t datalen, uint8_t iter, uint32_t hash_size) -{ - uint8_t *d = (uint8_t *)data; - uint32_t i; - uint32_t hash = 0; - - for (i = 0; i < datalen; i++) { - if (i == 0) hash += (((uint32_t)*d++)); - else if (i == 1) hash += (((uint32_t)*d++) * datalen); - else hash *= (((uint32_t)*d++) * i); - } - - hash *= (iter + datalen); - hash %= hash_size; - return hash; -} - -static int BloomFilterTestInit01 (void) -{ - BloomFilter *bf = BloomFilterInit(1024, 4, BloomFilterTestHash); - if (bf == NULL) - return 0; - - BloomFilterFree(bf); - return 1; -} - -/* no hash function, so it should fail */ -static int BloomFilterTestInit02 (void) -{ - BloomFilter *bf = BloomFilterInit(1024, 4, NULL); - if (bf == NULL) - return 1; - - BloomFilterFree(bf); - return 0; -} - -static int BloomFilterTestInit03 (void) -{ - int result = 0; - BloomFilter *bf = BloomFilterInit(1024, 4, BloomFilterTestHash); - if (bf == NULL) - return 0; - - if (bf->Hash == BloomFilterTestHash) - result = 1; - - BloomFilterFree(bf); - return result; -} - -static int BloomFilterTestInit04 (void) -{ - BloomFilter *bf = BloomFilterInit(1024, 0, BloomFilterTestHash); - if (bf == NULL) - return 1; - - BloomFilterFree(bf); - return 0; -} - -static int BloomFilterTestInit05 (void) -{ - BloomFilter *bf = BloomFilterInit(0, 4, BloomFilterTestHash); - if (bf == NULL) - return 1; - - BloomFilterFree(bf); - return 0; -} - -static int BloomFilterTestAdd01 (void) -{ - int result = 0; - BloomFilter *bf = BloomFilterInit(1024, 4, BloomFilterTestHash); - if (bf == NULL) - return 0; - - int r = BloomFilterAdd(bf, "test", 0); - if (r == 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (bf != NULL) BloomFilterFree(bf); - return result; -} - -static int BloomFilterTestAdd02 (void) -{ - int result = 0; - BloomFilter *bf = BloomFilterInit(1024, 4, BloomFilterTestHash); - if (bf == NULL) - return 0; - - int r = BloomFilterAdd(bf, NULL, 4); - if (r == 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (bf != NULL) BloomFilterFree(bf); - return result; -} - -static int BloomFilterTestFull01 (void) -{ - int result = 0; - BloomFilter *bf = BloomFilterInit(32, 4, BloomFilterTestHash); - if (bf == NULL) - goto end; - - int r = BloomFilterAdd(bf, "test", 4); - if (r != 0) - goto end; - - r = BloomFilterTest(bf, "test", 4); - if (r != 1) - goto end; - - /* all is good! */ - result = 1; -end: - if (bf != NULL) BloomFilterFree(bf); - return result; -} - -static int BloomFilterTestFull02 (void) -{ - int result = 0; - BloomFilter *bf = BloomFilterInit(32, 4, BloomFilterTestHash); - if (bf == NULL) - goto end; - - int r = BloomFilterTest(bf, "test", 4); - if (r != 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (bf != NULL) BloomFilterFree(bf); - return result; -} -#endif /* UNITTESTS */ - -void BloomFilterRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("BloomFilterTestInit01", BloomFilterTestInit01, 1); - UtRegisterTest("BloomFilterTestInit02", BloomFilterTestInit02, 1); - UtRegisterTest("BloomFilterTestInit03", BloomFilterTestInit03, 1); - UtRegisterTest("BloomFilterTestInit04", BloomFilterTestInit04, 1); - UtRegisterTest("BloomFilterTestInit05", BloomFilterTestInit05, 1); - - UtRegisterTest("BloomFilterTestAdd01", BloomFilterTestAdd01, 1); - UtRegisterTest("BloomFilterTestAdd02", BloomFilterTestAdd02, 1); - - UtRegisterTest("BloomFilterTestFull01", BloomFilterTestFull01, 1); - UtRegisterTest("BloomFilterTestFull02", BloomFilterTestFull02, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/util-bloomfilter.h b/framework/src/suricata/src/util-bloomfilter.h deleted file mode 100644 index e7a5874f..00000000 --- a/framework/src/suricata/src/util-bloomfilter.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __BLOOMFILTER_H__ -#define __BLOOMFILTER_H__ - -/* Bloom Filter structure */ -typedef struct BloomFilter_ { - uint8_t hash_iterations; - uint32_t (*Hash)(void *, uint16_t, uint8_t, uint32_t); - uint32_t bitarray_size; - uint8_t *bitarray; -} BloomFilter; - -/* prototypes */ -BloomFilter *BloomFilterInit(uint32_t, uint8_t, uint32_t (*Hash)(void *, uint16_t, uint8_t, uint32_t)); -void BloomFilterFree(BloomFilter *); -void BloomFilterPrint(BloomFilter *); -int BloomFilterAdd(BloomFilter *, void *, uint16_t); -uint32_t BloomFilterMemoryCnt(BloomFilter *); -uint32_t BloomFilterMemorySize(BloomFilter *); - -void BloomFilterRegisterTests(void); - -/** ----- Inline functions ---- */ - -static inline int BloomFilterTest(BloomFilter *, void *, uint16_t); - -static inline int BloomFilterTest(BloomFilter *bf, void *data, uint16_t datalen) -{ - uint8_t iter = 0; - uint32_t hash = 0; - int hit = 1; - - for (iter = 0; iter < bf->hash_iterations; iter++) { - hash = bf->Hash(data, datalen, iter, bf->bitarray_size); - if (!(bf->bitarray[hash/8] & (1< - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "util-debug.h" -#include "util-buffer.h" - -/* 10 mb */ -#define MAX_LIMIT 10485760 - -MemBuffer *MemBufferCreateNew(uint32_t size) -{ - if (size > MAX_LIMIT) { - SCLogWarning(SC_ERR_MEM_BUFFER_API, "Mem buffer asked to create " - "buffer with size greater than API limit - %d", MAX_LIMIT); - return NULL; - } - - uint32_t total_size = size + sizeof(MemBuffer); - - MemBuffer *buffer = SCMalloc(total_size); - if (unlikely(buffer == NULL)) { - return NULL; - } - memset(buffer, 0, total_size); - - buffer->size = size; - buffer->buffer = (uint8_t *)buffer + sizeof(MemBuffer); - - return buffer; -} - -/** \brief expand membuffer by size of 'expand_by' - * - * If expansion failed, buffer will still be valid. - * - * \retval result 0 ok, -1 expansion failed - */ -int MemBufferExpand(MemBuffer **buffer, uint32_t expand_by) { - if (((*buffer)->size + expand_by) > MAX_LIMIT) { - SCLogWarning(SC_ERR_MEM_BUFFER_API, "Mem buffer asked to create " - "buffer with size greater than API limit - %d", MAX_LIMIT); - return -1; - } - - uint32_t total_size = (*buffer)->size + sizeof(MemBuffer) + expand_by; - - MemBuffer *tbuffer = SCRealloc(*buffer, total_size); - if (unlikely(tbuffer == NULL)) { - return -1; - } - - *buffer = tbuffer; - (*buffer)->size += expand_by; - (*buffer)->buffer = (uint8_t *)tbuffer + sizeof(MemBuffer); - - SCLogDebug("expanded buffer by %u, size is now %u", expand_by, (*buffer)->size); - return 0; -} - -void MemBufferFree(MemBuffer *buffer) -{ - SCFree(buffer); - - return; -} diff --git a/framework/src/suricata/src/util-buffer.h b/framework/src/suricata/src/util-buffer.h deleted file mode 100644 index 58d5098a..00000000 --- a/framework/src/suricata/src/util-buffer.h +++ /dev/null @@ -1,177 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_BUFFER_H__ -#define __UTIL_BUFFER_H__ - -typedef struct MemBuffer_ { - uint8_t *buffer; - uint32_t size; - uint32_t offset; -} MemBuffer; - -MemBuffer *MemBufferCreateNew(uint32_t size); -int MemBufferExpand(MemBuffer **buffer, uint32_t expand_by); -void MemBufferFree(MemBuffer *buffer); - -/** - * \brief Reset the mem buffer. - * - * \param mem_buffer Pointer to the mem buffer instance. - */ -#define MemBufferReset(mem_buffer) do { \ - (mem_buffer)->buffer[0] = 0; \ - (mem_buffer)->offset = 0; \ - } while (0) - -/** - * \brief Get the MemBuffers underlying buffer. - */ -#define MEMBUFFER_BUFFER(mem_buffer) (mem_buffer)->buffer - -/** - * \brief Get the MemBuffers current offset. - */ -#define MEMBUFFER_OFFSET(mem_buffer) (mem_buffer)->offset - -/** - * \brief Get the MemBuffers current size. - */ -#define MEMBUFFER_SIZE(mem_buffer) (mem_buffer)->size - -/** - * \brief Write a buffer to the file pointer. - * - * Accepted buffers can contain both printable and non-printable - * characters. Printable characters are written in the printable - * format and the non-printable chars are written in hex codes - * using the |XX| format. - * - * For example this would be the kind of output in the file - - * onetwo|EF|three|ED|five - * - * \param buffer Pointer to the src MemBuffer instance to write. - * \param fp Pointer to the file file instance to write to. - */ -#define MemBufferPrintToFP(buffer, fp) do { \ - uint32_t i; \ - \ - for (i = 0; i < (buffer)->offset; i++) { \ - if (isprint(buffer->buffer[i])) \ - fprintf(fp, "%c", (buffer)->buffer[i]); \ - else \ - fprintf(fp, "|%02X|", (buffer)->buffer[i]); \ - } \ - } while (0) - -/** - * \brief Write a buffer to the file pointer as a printable char string. - * - * \param buffer Pointer to the src MemBuffer instance to write. - * \param fp Pointer to the file file instance to write to. - */ -#define MemBufferPrintToFPAsString(mem_buffer, fp) ({ \ - fwrite((mem_buffer)->buffer, sizeof(uint8_t), (mem_buffer)->offset, fp); \ -}) - -/** - * \brief Write a buffer in hex format. - * - * \param buffer Pointer to the src MemBuffer instance to write. - * \param fp Pointer to the file file instance to write to. - */ -#define MemBufferPrintToFPAsHex(buffer, fp) do { \ - uint32_t i; \ - \ - for (i = 0; i < (buffer)->offset; i++) { \ - if (((buffer)->offset % 8) == 0) \ - fprintf(fp, "\n"); \ - fprintf(fp, " %02X", (buffer)->buffer[i]); \ - } \ - } while (0) - - -/** - * \brief Write a raw buffer to the MemBuffer dst. - * - * When we say raw buffer it indicates a buffer that need not be - * purely a string buffer. It can be a pure string buffer or not or - * a mixture of both. Hence we don't accept any format strings. - * - * If the remaining space on the buffer is lesser than the length of - * the buffer to write, it is truncated to fit into the empty space. - * - * Also after every write a '\0' is appended. This would indicate - * that the total available space to write in the buffer is - * MemBuffer->size - 1 and not Membuffer->size. The reason we - * append the '\0' is for supporting writing pure string buffers - * as well, that can later be used by other string handling funcs. - * - * \param raw_buffer The buffer to write. - * \param raw_buffer_len Length of the above buffer. - */ -#define MemBufferWriteRaw(dst, raw_buffer, raw_buffer_len) do { \ - uint32_t write_len; \ - \ - if (((raw_buffer_len) >= (dst)->size - (dst)->offset)) { \ - SCLogDebug("Truncating data write since it exceeded buffer limit of " \ - "- %"PRIu32"\n", (dst)->size); \ - write_len = ((dst)->size - (dst)->offset) - 1; \ - } else { \ - write_len = (raw_buffer_len); \ - } \ - \ - memcpy((dst)->buffer + (dst)->offset, (raw_buffer), write_len); \ - (dst)->offset += write_len; \ - dst->buffer[dst->offset] = '\0'; \ - } while (0) - -/** - * \brief Write a string buffer to the Membuffer dst. - * - * This function takes a format string and arguments for the format - * string like sprintf. - * - * An example usage of this is - - * MemBufferWriteString(mem_buffer_instance, \"%d - %s\", 10, \"one\"); - * - * \param dst The dst MemBuffer instance. - * \param format The format string. - * \param ... Variable arguments. - */ -#define MemBufferWriteString(dst, ...) do { \ - int cw = snprintf((char *)(dst)->buffer + (dst)->offset, \ - (dst)->size - (dst)->offset, \ - __VA_ARGS__); \ - if (cw >= 0) { \ - if ( ((dst)->offset + cw) >= (dst)->size) { \ - SCLogDebug("Truncating data write since it exceeded buffer " \ - "limit of - %"PRIu32"\n", (dst)->size); \ - (dst)->offset = (dst)->size - 1; \ - } else { \ - (dst->offset) += cw; \ - } \ - } \ - } while (0) - -#endif /* __UTIL_BUFFER_H__ */ diff --git a/framework/src/suricata/src/util-byte.c b/framework/src/suricata/src/util-byte.c deleted file mode 100644 index 1d8e088a..00000000 --- a/framework/src/suricata/src/util-byte.c +++ /dev/null @@ -1,629 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - * - * Byte utility functions - */ - -#include "suricata-common.h" -#include "util-byte.h" -#include "util-unittest.h" -#include "util-debug.h" - -/** \brief Turn byte array into string. - * - * All non-printables are copied over, except for '\0', which is - * turned into literal \0 in the string. - * - * \param bytes byte array - * \param nbytes number of bytes - * \return string nul-terminated string or NULL on error - */ -char *BytesToString(const uint8_t *bytes, size_t nbytes) -{ - size_t n = nbytes + 1; - size_t nulls = 0; - - size_t u; - for (u = 0; u < nbytes; u++) { - if (bytes[u] == '\0') - nulls++; - } - n += nulls; - - char *string = SCCalloc(1, n); - if (string == NULL) - return NULL; - - if (nulls == 0) { - /* no nulls */ - memcpy(string, bytes, nbytes); - } else { - /* nulls present */ - char *dst = string; - for (u = 0; u < nbytes; u++) { - if (bytes[u] == '\0') { - *dst++ = '\\'; - *dst++ = '0'; - } else { - *dst++ = bytes[u]; - } - } - } - return string; -} - -int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes) -{ - uint64_t i64; - int ret; - - /* Uint64 is limited to 8 bytes */ - if (len > 8) { - /** \todo Need standard return values */ - return -1; - } - - ret = ByteExtract(&i64, e, len, bytes); - if (ret <= 0) { - return ret; - } - - *res = (uint64_t)i64; - - return ret; -} - -int ByteExtractUint32(uint32_t *res, int e, uint16_t len, const uint8_t *bytes) -{ - uint64_t i64; - int ret; - - /* Uint32 is limited to 4 bytes */ - if (len > 4) { - /** \todo Need standard return values */ - return -1; - } - - ret = ByteExtract(&i64, e, len, bytes); - if (ret <= 0) { - return ret; - } - - *res = (uint32_t)i64; - - return ret; -} - -int ByteExtractUint16(uint16_t *res, int e, uint16_t len, const uint8_t *bytes) -{ - uint64_t i64; - int ret; - - /* Uint16 is limited to 2 bytes */ - if (len > 2) { - /** \todo Need standard return values */ - return -1; - } - - ret = ByteExtract(&i64, e, len, bytes); - if (ret <= 0) { - return ret; - } - - *res = (uint16_t)i64; - - return ret; -} - -int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str) -{ - const char *ptr = str; - char *endptr = NULL; - - /* 23 - This is the largest string (octal, with a zero prefix) that - * will not overflow uint64_t. The only way this length - * could be over 23 and still not overflow is if it were zero - * prefixed and we only support 1 byte of zero prefix for octal. - * - * "01777777777777777777777" = 0xffffffffffffffff - */ - char strbuf[24]; - - if (len > 23) { - SCLogError(SC_ERR_ARG_LEN_LONG, "len too large (23 max)"); - return -1; - } - - if (len) { - /* Extract out the string so it can be null terminated */ - memcpy(strbuf, str, len); - strbuf[len] = '\0'; - ptr = strbuf; - } - - errno = 0; - *res = strtoull(ptr, &endptr, base); - - if (errno == ERANGE) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range"); - return -1; - /* If there is no numeric value in the given string then strtoull(), makes - endptr equals to ptr and return 0 as result */ - } else if (endptr == ptr && *res == 0) { - SCLogDebug("No numeric value"); - return -1; - } else if (endptr == ptr) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Invalid numeric value"); - return -1; - } - /* This will interfere with some rules that do not know the length - * in advance and instead are just using the max. - */ -#if 0 - else if (len && *endptr != '\0') { - fprintf(stderr, "ByteExtractString: Extra characters following numeric value\n"); - return -1; - } -#endif - - return (endptr - ptr); -} - -int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str) -{ - return ByteExtractString(res, base, len, str); -} - -int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str) -{ - uint64_t i64; - int ret; - - ret = ByteExtractString(&i64, base, len, str); - if (ret <= 0) { - return ret; - } - - *res = (uint32_t)i64; - - if ((uint64_t)(*res) != i64) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range " - "(%" PRIu64 " > %" PRIuMAX ")", i64, (uintmax_t)UINT_MAX); - return -1; - } - - return ret; -} - -int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const char *str) -{ - uint64_t i64; - int ret; - - ret = ByteExtractString(&i64, base, len, str); - if (ret <= 0) { - return ret; - } - - *res = (uint16_t)i64; - - if ((uint64_t)(*res) != i64) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range " - "(%" PRIu64 " > %" PRIuMAX ")", i64, (uintmax_t)USHRT_MAX); - return -1; - } - - return ret; -} - -int ByteExtractStringUint8(uint8_t *res, int base, uint16_t len, const char *str) -{ - uint64_t i64; - int ret; - - ret = ByteExtractString(&i64, base, len, str); - if (ret <= 0) { - return ret; - } - - *res = (uint8_t)i64; - - if ((uint64_t)(*res) != i64) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range " - "(%" PRIu64 " > %" PRIuMAX ")", i64, (uintmax_t)UCHAR_MAX); - return -1; - } - - return ret; -} - -int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *str) -{ - const char *ptr = str; - char *endptr; - - /* 23 - This is the largest string (octal, with a zero prefix) that - * will not overflow int64_t. The only way this length - * could be over 23 and still not overflow is if it were zero - * prefixed and we only support 1 byte of zero prefix for octal. - * - * "-0777777777777777777777" = 0xffffffffffffffff - */ - char strbuf[24]; - - if (len > 23) { - SCLogError(SC_ERR_ARG_LEN_LONG, "len too large (23 max)"); - return -1; - } - - if (len) { - /* Extract out the string so it can be null terminated */ - memcpy(strbuf, str, len); - strbuf[len] = '\0'; - ptr = strbuf; - } - - errno = 0; - *res = strtoll(ptr, &endptr, base); - - if (errno == ERANGE) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range"); - return -1; - } else if (endptr == str) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Invalid numeric value"); - return -1; - } - /* This will interfere with some rules that do not know the length - * in advance and instead are just using the max. - */ -#if 0 - else if (len && *endptr != '\0') { - fprintf(stderr, "ByteExtractStringSigned: Extra characters following numeric value\n"); - return -1; - } -#endif - - //fprintf(stderr, "ByteExtractStringSigned: Extracted base %d: 0x%" PRIx64 "\n", base, *res); - - return (endptr - ptr); -} - -int ByteExtractStringInt64(int64_t *res, int base, uint16_t len, const char *str) -{ - return ByteExtractStringSigned(res, base, len, str); -} - -int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str) -{ - int64_t i64; - int ret; - - ret = ByteExtractStringSigned(&i64, base, len, str); - if (ret <= 0) { - return ret; - } - - *res = (int32_t)i64; - - if ((int64_t)(*res) != i64) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range " - "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)INT_MAX); - return -1; - } - - return ret; -} - -int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const char *str) -{ - int64_t i64; - int ret; - - ret = ByteExtractStringSigned(&i64, base, len, str); - if (ret <= 0) { - return ret; - } - - *res = (int16_t)i64; - - if ((int64_t)(*res) != i64) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range " - "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)SHRT_MAX); - return -1; - } - - return ret; -} - -int ByteExtractStringInt8(int8_t *res, int base, uint16_t len, const char *str) -{ - int64_t i64; - int ret; - - ret = ByteExtractStringSigned(&i64, base, len, str); - if (ret <= 0) { - return ret; - } - - *res = (int8_t)i64; - - if ((int64_t)(*res) != i64) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range " - "(%" PRIi64 " > %" PRIiMAX ")\n", i64, (intmax_t)CHAR_MAX); - return -1; - } - - return ret; -} - -/* UNITTESTS */ -#ifdef UNITTESTS - -static int ByteTest01 (void) -{ - uint16_t val = 0x0102; - uint16_t i16 = 0xbfbf; - uint8_t bytes[2] = { 0x02, 0x01 }; - int ret = ByteExtractUint16(&i16, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes); - - if ((ret == 2) && (i16 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest02 (void) -{ - uint16_t val = 0x0102; - uint16_t i16 = 0xbfbf; - uint8_t bytes[2] = { 0x01, 0x02 }; - int ret = ByteExtractUint16(&i16, BYTE_BIG_ENDIAN, sizeof(bytes), bytes); - - if ((ret == 2) && (i16 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest03 (void) -{ - uint32_t val = 0x01020304; - uint32_t i32 = 0xbfbfbfbf; - uint8_t bytes[4] = { 0x04, 0x03, 0x02, 0x01 }; - int ret = ByteExtractUint32(&i32, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes); - - if ((ret == 4) && (i32 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest04 (void) -{ - uint32_t val = 0x01020304; - uint32_t i32 = 0xbfbfbfbf; - uint8_t bytes[4] = { 0x01, 0x02, 0x03, 0x04 }; - int ret = ByteExtractUint32(&i32, BYTE_BIG_ENDIAN, sizeof(bytes), bytes); - - if ((ret == 4) && (i32 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest05 (void) -{ - uint64_t val = 0x0102030405060708ULL; - uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL; - uint8_t bytes[8] = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; - int ret = ByteExtractUint64(&i64, BYTE_LITTLE_ENDIAN, sizeof(bytes), bytes); - - if ((ret == 8) && (i64 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest06 (void) -{ - uint64_t val = 0x0102030405060708ULL; - uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL; - uint8_t bytes[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; - int ret = ByteExtractUint64(&i64, BYTE_BIG_ENDIAN, sizeof(bytes), bytes); - - if ((ret == 8) && (i64 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest07 (void) -{ - const char *str = "1234567890"; - uint64_t val = 1234567890; - uint64_t i64 = 0xbfbfbfbfbfbfbfbfULL; - int ret = ByteExtractStringUint64(&i64, 10, strlen(str), str); - - if ((ret == 10) && (i64 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest08 (void) -{ - const char *str = "1234567890"; - uint32_t val = 1234567890; - uint32_t i32 = 0xbfbfbfbf; - int ret = ByteExtractStringUint32(&i32, 10, strlen(str), str); - - if ((ret == 10) && (i32 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest09 (void) -{ - const char *str = "12345"; - uint16_t val = 12345; - uint16_t i16 = 0xbfbf; - int ret = ByteExtractStringUint16(&i16, 10, strlen(str), str); - - if ((ret == 5) && (i16 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest10 (void) -{ - const char *str = "123"; - uint8_t val = 123; - uint8_t i8 = 0xbf; - int ret = ByteExtractStringUint8(&i8, 10, strlen(str), str); - - if ((ret == 3) && (i8 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest11 (void) -{ - const char *str = "-1234567890"; - int64_t val = -1234567890; - int64_t i64 = 0xbfbfbfbfbfbfbfbfULL; - int ret = ByteExtractStringInt64(&i64, 10, strlen(str), str); - - if ((ret == 11) && (i64 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest12 (void) -{ - const char *str = "-1234567890"; - int32_t val = -1234567890; - int32_t i32 = 0xbfbfbfbf; - int ret = ByteExtractStringInt32(&i32, 10, strlen(str), str); - - if ((ret == 11) && (i32 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest13 (void) -{ - const char *str = "-12345"; - int16_t val = -12345; - int16_t i16 = 0xbfbf; - int ret = ByteExtractStringInt16(&i16, 10, strlen(str), str); - - if ((ret == 6) && (i16 == val)) { - return 1; - } - - return 0; -} - -static int ByteTest14 (void) -{ - const char *str = "-123"; - int8_t val = -123; - int8_t i8 = 0xbf; - int ret = ByteExtractStringInt8(&i8, 10, strlen(str), str); - - if ((ret == 4) && (i8 == val)) { - return 1; - } - - return 0; -} - -/** \test max u32 value */ -static int ByteTest15 (void) -{ - const char *str = "4294967295"; - uint32_t val = 4294967295UL; - uint32_t u32 = 0xffffffff; - - int ret = ByteExtractStringUint32(&u32, 10, strlen(str), str); - if ((ret == 10) && (u32 == val)) { - return 1; - } - - return 0; -} - -/** \test max u32 value + 1 */ -static int ByteTest16 (void) -{ - const char *str = "4294967296"; - uint32_t u32 = 0; - - int ret = ByteExtractStringUint32(&u32, 10, strlen(str), str); - if (ret != 0) { - return 1; - } - - return 0; -} -#endif /* UNITTESTS */ - -void ByteRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("ByteTest01", ByteTest01, 1); - UtRegisterTest("ByteTest02", ByteTest02, 1); - UtRegisterTest("ByteTest03", ByteTest03, 1); - UtRegisterTest("ByteTest04", ByteTest04, 1); - UtRegisterTest("ByteTest05", ByteTest05, 1); - UtRegisterTest("ByteTest06", ByteTest06, 1); - UtRegisterTest("ByteTest07", ByteTest07, 1); - UtRegisterTest("ByteTest08", ByteTest08, 1); - UtRegisterTest("ByteTest09", ByteTest09, 1); - UtRegisterTest("ByteTest10", ByteTest10, 1); - UtRegisterTest("ByteTest11", ByteTest11, 1); - UtRegisterTest("ByteTest12", ByteTest12, 1); - UtRegisterTest("ByteTest13", ByteTest13, 1); - UtRegisterTest("ByteTest14", ByteTest14, 1); - UtRegisterTest("ByteTest15", ByteTest15, 1); - UtRegisterTest("ByteTest16", ByteTest16, 1); -#endif /* UNITTESTS */ -} - - diff --git a/framework/src/suricata/src/util-byte.h b/framework/src/suricata/src/util-byte.h deleted file mode 100644 index 82c16a4d..00000000 --- a/framework/src/suricata/src/util-byte.h +++ /dev/null @@ -1,292 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Brian Rectanus - */ - -#ifndef __UTIL_BYTE_H__ -#define __UTIL_BYTE_H__ - -#include - -#define BYTE_BIG_ENDIAN 0 -#define BYTE_LITTLE_ENDIAN 1 - -/** Wrappers for OS dependent byte swapping functions */ -#ifdef OS_FREEBSD -#include -#define SCByteSwap16(x) bswap16(x) -#define SCByteSwap32(x) bswap32(x) -#define SCByteSwap64(x) bswap64(x) -#elif defined __OpenBSD__ -#include -#define SCByteSwap16(x) swap16(x) -#define SCByteSwap32(x) swap32(x) -#define SCByteSwap64(x) swap64(x) -#elif OS_DARWIN -#include -#define SCByteSwap16(x) OSSwapInt16(x) -#define SCByteSwap32(x) OSSwapInt32(x) -#define SCByteSwap64(x) OSSwapInt64(x) -#elif defined(__WIN32) || defined(_WIN32) -/* Quick & dirty solution, nothing seems to exist for this in Win32 API */ -#define SCByteSwap16(x) \ - ((((x) & 0xff00) >> 8) \ - | (((x) & 0x00ff) << 8)) -#define SCByteSwap32(x) \ - ((((x) & 0xff000000) >> 24) \ - | (((x) & 0x00ff0000) >> 8) \ - | (((x) & 0x0000ff00) << 8) \ - | (((x) & 0x000000ff) << 24)) -#define SCByteSwap64(x) \ - ((((x) & 0xff00000000000000ull) >> 56) \ - | (((x) & 0x00ff000000000000ull) >> 40) \ - | (((x) & 0x0000ff0000000000ull) >> 24) \ - | (((x) & 0x000000ff00000000ull) >> 8) \ - | (((x) & 0x00000000ff000000ull) << 8) \ - | (((x) & 0x0000000000ff0000ull) << 24) \ - | (((x) & 0x000000000000ff00ull) << 40) \ - | (((x) & 0x00000000000000ffull) << 56)) -#else -#include -#define SCByteSwap16(x) bswap_16(x) -#define SCByteSwap32(x) bswap_32(x) -#define SCByteSwap64(x) bswap_64(x) -#endif /* OS_FREEBSD */ - -/** \brief Turn byte array into string. - * - * All non-printables are copied over, except for '\0', which is - * turned into literal \0 in the string. - * - * \param bytes byte array - * \param nbytes number of bytes - * \return string nul-terminated string or NULL on error - */ -char *BytesToString(const uint8_t *bytes, size_t nbytes); - -/** - * Extract bytes from a byte string and convert to a unint64_t. - * - * \param res Stores result - * \param e Endianness (BYTE_BIG_ENDIAN or BYTE_LITTLE_ENDIAN) - * \param len Number of bytes to extract (8 max) - * \param bytes Data to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes); - -/** - * Extract bytes from a byte string and convert to a unint32_t. - * - * \param res Stores result - * \param e Endianness (BYTE_BIG_ENDIAN or BYTE_LITTLE_ENDIAN) - * \param len Number of bytes to extract (8 max) - * \param bytes Data to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractUint32(uint32_t *res, int e, uint16_t len, const uint8_t *bytes); - -/** - * Extract bytes from a byte string and convert to a unint16_t. - * - * \param res Stores result - * \param e Endianness (BYTE_BIG_ENDIAN or BYTE_LITTLE_ENDIAN) - * \param len Number of bytes to extract (8 max) - * \param bytes Data to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractUint16(uint16_t *res, int e, uint16_t len, const uint8_t *bytes); - -/** - * Extract unsigned integer value from a string. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractString(uint64_t *res, int base, uint16_t len, const char *str); - -/** - * Extract unsigned integer value from a string as uint64_t. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param len Number of bytes to extract (23 max) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str); - -/** - * Extract unsigned integer value from a string as uint32_t. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str); - -/** - * Extract unsigned integer value from a string as uint16_t. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractStringUint16(uint16_t *res, int base, uint16_t len, const char *str); - -/** - * Extract unsigned integer value from a string as uint8_t. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractStringUint8(uint8_t *res, int base, uint16_t len, const char *str); - -/** - * Extract signed integer value from a string. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractStringSigned(int64_t *res, int base, uint16_t len, const char *str); - -/** - * Extract signed integer value from a string as uint64_t. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractStringInt64(int64_t *res, int base, uint16_t len, const char *str); - -/** - * Extract signed integer value from a string as uint32_t. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str); - -/** - * Extract signed integer value from a string as uint16_t. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractStringInt16(int16_t *res, int base, uint16_t len, const char *str); - -/** - * Extract signed integer value from a string as uint8_t. - * - * \param res Stores result - * \param base Base of the number to extract - * \param len Number of bytes to extract (23 max or 0 for unbounded) - * \param str String to extract from - * - * \return n Number of bytes extracted on success - * \return -1 On error - */ -int ByteExtractStringInt8(int8_t *res, int base, uint16_t len, const char *str); - -#ifdef UNITTESTS -void ByteRegisterTests(void); -#endif /* UNITTESTS */ - -/** ------ Inline functions ----- */ -static inline int ByteExtract(uint64_t *res, int e, uint16_t len, const uint8_t *bytes) -{ - uint64_t b = 0; - int i; - - if ((e != BYTE_BIG_ENDIAN) && (e != BYTE_LITTLE_ENDIAN)) { - /** \todo Need standard return values */ - return -1; - } - - *res = 0; - - /* Go through each byte and merge it into the result in the correct order */ - /** \todo Probably a more efficient way to do this. */ - for (i = 0; i < len; i++) { - - if (e == BYTE_LITTLE_ENDIAN) { - b = bytes[i]; - } - else { - b = bytes[len - i - 1]; - } - - *res |= (b << ((i & 7) << 3)); - - } - - return len; -} - - -#endif /* __UTIL_BYTE_H__ */ - diff --git a/framework/src/suricata/src/util-checksum.c b/framework/src/suricata/src/util-checksum.c deleted file mode 100644 index 455e2f52..00000000 --- a/framework/src/suricata/src/util-checksum.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (C) 2011-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - * Util functions for checskum. - */ - -#include "suricata-common.h" - -#include "util-checksum.h" - -int ReCalculateChecksum(Packet *p) -{ - if (PKT_IS_IPV4(p)) { - if (PKT_IS_TCP(p)) { - /* TCP */ - p->tcph->th_sum = 0; - p->tcph->th_sum = TCPCalculateChecksum(p->ip4h->s_ip_addrs, - (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p))); - } else if (PKT_IS_UDP(p)) { - p->udph->uh_sum = 0; - p->udph->uh_sum = UDPV4CalculateChecksum(p->ip4h->s_ip_addrs, - (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN)); - } - /* IPV4 */ - p->ip4h->ip_csum = 0; - p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h, - IPV4_GET_RAW_HLEN(p->ip4h)); - } else if (PKT_IS_IPV6(p)) { - /* just TCP for IPV6 */ - if (PKT_IS_TCP(p)) { - p->tcph->th_sum = 0; - p->tcph->th_sum = TCPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->tcph, (p->payload_len + TCP_GET_HLEN(p))); - } else if (PKT_IS_UDP(p)) { - p->udph->uh_sum = 0; - p->udph->uh_sum = UDPV6CalculateChecksum(p->ip6h->s_ip6_addrs, - (uint16_t *)p->udph, (p->payload_len + UDP_HEADER_LEN)); - } - } - - return 0; -} - -/** - * \brief Check if the number of invalid checksums indicate checksum - * offloading in place. - * - * \retval 1 yes, offloading in place - * \retval 0 no, no offloading used - */ -int ChecksumAutoModeCheck(uint32_t thread_count, - unsigned int iface_count, unsigned int iface_fail) -{ - if (thread_count == CHECKSUM_SAMPLE_COUNT) { - if (iface_fail != 0) { - if ((iface_count / iface_fail) < CHECKSUM_INVALID_RATIO) { - SCLogInfo("More than 1/%dth of packets have an invalid " - "checksum, assuming checksum offloading is used (%u/%u)", - CHECKSUM_INVALID_RATIO, iface_fail, iface_count); - return 1; - } else { - SCLogInfo("Less than 1/%dth of packets have an invalid " - "checksum, assuming checksum offloading is NOT used (%u/%u)", - CHECKSUM_INVALID_RATIO, iface_fail, iface_count); - } - } else { - SCLogInfo("No packets with invalid checksum, assuming checksum offloading is NOT used"); - } - } - return 0; -} diff --git a/framework/src/suricata/src/util-checksum.h b/framework/src/suricata/src/util-checksum.h deleted file mode 100644 index dc14334c..00000000 --- a/framework/src/suricata/src/util-checksum.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2011-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#ifndef __UTIL_CHECKSUM_H__ -#define __UTIL_CHECKSUM_H__ - -int ReCalculateChecksum(Packet *p); -int ChecksumAutoModeCheck(uint32_t thread_count, - unsigned int iface_count, unsigned int iface_fail); - -/* constant linked with detection of interface with - * invalid checksums */ -#define CHECKSUM_SAMPLE_COUNT 1000 -#define CHECKSUM_INVALID_RATIO 10 - -#endif diff --git a/framework/src/suricata/src/util-cidr.c b/framework/src/suricata/src/util-cidr.c deleted file mode 100644 index 300a4455..00000000 --- a/framework/src/suricata/src/util-cidr.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * CIDR utility functions - */ - -#include "suricata-common.h" - -static uint32_t cidrs[33]; - -void CIDRInit(void) -{ - int i = 0; - - /* skip 0 as it will result in 0xffffffff */ - cidrs[0] = 0; - for (i = 1; i < 33; i++) { - cidrs[i] = htonl(0xFFFFFFFF << (32 - i)); - //printf("CIDRInit: cidrs[%02d] = 0x%08X\n", i, cidrs[i]); - } -} - -uint32_t CIDRGet(int cidr) -{ - if (cidr < 0 || cidr > 32) - return 0; - return cidrs[cidr]; -} - diff --git a/framework/src/suricata/src/util-cidr.h b/framework/src/suricata/src/util-cidr.h deleted file mode 100644 index ee275b4c..00000000 --- a/framework/src/suricata/src/util-cidr.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_NETMASK_H__ -#define __UTIL_NETMASK_H__ - -void CIDRInit(void); -uint32_t CIDRGet(int); - -#endif /* __UTIL_NETMASK_H__ */ - diff --git a/framework/src/suricata/src/util-classification-config.c b/framework/src/suricata/src/util-classification-config.c deleted file mode 100644 index e88d4f20..00000000 --- a/framework/src/suricata/src/util-classification-config.c +++ /dev/null @@ -1,839 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Used for parsing a classification.config file - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-engine.h" -#include "util-hash.h" - -#include "conf.h" -#include "util-classification-config.h" -#include "util-unittest.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-fmemopen.h" - -/* Regex to parse the classtype argument from a Signature. The first substring - * holds the classtype name, the second substring holds the classtype the - * classtype description, and the third argument holds the priority */ -#define DETECT_CLASSCONFIG_REGEX "^\\s*config\\s*classification\\s*:\\s*([a-zA-Z][a-zA-Z0-9-_]*)\\s*,\\s*(.+)\\s*,\\s*(\\d+)\\s*$" - -/* Default path for the classification.config file */ -#if defined OS_WIN32 || defined __CYGWIN__ -#define SC_CLASS_CONF_DEF_CONF_FILEPATH CONFIG_DIR "\\\\classification.config" -#else -#define SC_CLASS_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/classification.config" -#endif - -static pcre *regex = NULL; -static pcre_extra *regex_study = NULL; - -uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen); -char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1, - void *data2, uint16_t datalen2); -void SCClassConfClasstypeHashFree(void *ch); -static char *SCClassConfGetConfFilename(const DetectEngineCtx *de_ctx); - -void SCClassConfInit(void) -{ - const char *eb = NULL; - int eo; - int opts = 0; - - regex = pcre_compile(DETECT_CLASSCONFIG_REGEX, opts, &eb, &eo, NULL); - if (regex == NULL) { - SCLogDebug("Compile of \"%s\" failed at offset %" PRId32 ": %s", - DETECT_CLASSCONFIG_REGEX, eo, eb); - return; - } - - regex_study = pcre_study(regex, 0, &eb); - if (eb != NULL) { - pcre_free(regex); - regex = NULL; - SCLogDebug("pcre study failed: %s", eb); - return; - } - return; -} - -void SCClassConfDeinit(void) -{ - if (regex != NULL) { - pcre_free(regex); - regex = NULL; - } - if (regex_study != NULL) { - pcre_free(regex_study); - regex_study = NULL; - } -} - - -/** - * \brief Inits the context to be used by the Classification Config parsing API. - * - * This function initializes the hash table to be used by the Detection - * Engine Context to hold the data from the classification.config file, - * obtains the file desc to parse the classification.config file, and - * inits the regex used to parse the lines from classification.config - * file. - * - * \param de_ctx Pointer to the Detection Engine Context. - * - * \retval fp NULL on error - */ -FILE *SCClassConfInitContextAndLocalResources(DetectEngineCtx *de_ctx, FILE *fd) -{ - char *filename = NULL; - - /* init the hash table to be used by the classification config Classtypes */ - de_ctx->class_conf_ht = HashTableInit(128, SCClassConfClasstypeHashFunc, - SCClassConfClasstypeHashCompareFunc, - SCClassConfClasstypeHashFree); - if (de_ctx->class_conf_ht == NULL) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "Error initializing the hash " - "table"); - goto error; - } - - /* if it is not NULL, use the file descriptor. The hack so that we can - * avoid using a dummy classification file for testing purposes and - * instead use an input stream against a buffer containing the - * classification strings */ - if (fd == NULL) { - filename = SCClassConfGetConfFilename(de_ctx); - if ( (fd = fopen(filename, "r")) == NULL) { -#ifdef UNITTESTS - if (RunmodeIsUnittests()) - goto error; // silently fail -#endif - SCLogError(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, strerror(errno)); - goto error; - } - } - - return fd; - - error: - if (de_ctx->class_conf_ht != NULL) { - HashTableFree(de_ctx->class_conf_ht); - de_ctx->class_conf_ht = NULL; - } - if (fd != NULL) { - fclose(fd); - fd = NULL; - } - - return NULL; -} - - -/** - * \brief Returns the path for the Classification Config file. We check if we - * can retrieve the path from the yaml conf file. If it is not present, - * return the default path for the classification file which is - * "./classification.config". - * - * \retval log_filename Pointer to a string containing the path for the - * Classification Config file. - */ -static char *SCClassConfGetConfFilename(const DetectEngineCtx *de_ctx) -{ - char *log_filename = NULL; - char config_value[256] = ""; - - if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0) { - snprintf(config_value, sizeof(config_value), - "%s.classification-file", de_ctx->config_prefix); - - /* try loading prefix setting, fall back to global if that - * fails. */ - if (ConfGet(config_value, &log_filename) != 1) { - if (ConfGet("classification-file", &log_filename) != 1) { - log_filename = (char *)SC_CLASS_CONF_DEF_CONF_FILEPATH; - } - } - } else { - if (ConfGet("classification-file", &log_filename) != 1) { - log_filename = (char *)SC_CLASS_CONF_DEF_CONF_FILEPATH; - } - } - - return log_filename; -} - -/** - * \brief Releases resources used by the Classification Config API. - */ -static void SCClassConfDeInitLocalResources(DetectEngineCtx *de_ctx, FILE *fd) -{ - if (fd != NULL) { - fclose(fd); - fd = NULL; - } -} - -/** - * \brief Releases resources used by the Classification Config API. - */ -void SCClassConfDeInitContext(DetectEngineCtx *de_ctx) -{ - if (de_ctx->class_conf_ht != NULL) - HashTableFree(de_ctx->class_conf_ht); - - de_ctx->class_conf_ht = NULL; - - return; -} - -/** - * \brief Converts a string to lowercase. - * - * \param str Pointer to the string to be converted. - */ -static char *SCClassConfStringToLowercase(const char *str) -{ - char *new_str = NULL; - char *temp_str = NULL; - - if ( (new_str = SCStrdup(str)) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - return NULL; - } - - temp_str = new_str; - while (*temp_str != '\0') { - *temp_str = tolower((unsigned char)*temp_str); - temp_str++; - } - - return new_str; -} - -/** - * \brief Parses a line from the classification file and adds it to Classtype - * hash table in DetectEngineCtx, i.e. DetectEngineCtx->class_conf_ht. - * - * \param rawstr Pointer to the string to be parsed. - * \param index Relative index of the string to be parsed. - * \param de_ctx Pointer to the Detection Engine Context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCClassConfAddClasstype(char *rawstr, uint8_t index, DetectEngineCtx *de_ctx) -{ - char ct_name[64]; - char ct_desc[512]; - char ct_priority_str[16]; - int ct_priority = 0; - uint8_t ct_id = index; - - SCClassConfClasstype *ct_new = NULL; - SCClassConfClasstype *ct_lookup = NULL; - -#define MAX_SUBSTRINGS 30 - int ret = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(regex, regex_study, rawstr, strlen(rawstr), 0, 0, ov, 30); - if (ret < 0) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid Classtype in " - "classification.config file"); - goto error; - } - - /* retrieve the classtype name */ - ret = pcre_copy_substring((char *)rawstr, ov, 30, 1, ct_name, sizeof(ct_name)); - if (ret < 0) { - SCLogInfo("pcre_copy_substring() failed"); - goto error; - } - - /* retrieve the classtype description */ - ret = pcre_copy_substring((char *)rawstr, ov, 30, 2, ct_desc, sizeof(ct_desc)); - if (ret < 0) { - SCLogInfo("pcre_copy_substring() failed"); - goto error; - } - - /* retrieve the classtype priority */ - ret = pcre_copy_substring((char *)rawstr, ov, 30, 3, ct_priority_str, sizeof(ct_priority_str)); - if (ret < 0) { - SCLogInfo("pcre_copy_substring() failed"); - goto error; - } - if (strlen(ct_priority_str) == 0) { - goto error; - } - - ct_priority = atoi(ct_priority_str); - - /* Create a new instance of the parsed Classtype string */ - ct_new = SCClassConfAllocClasstype(ct_id, ct_name, ct_desc, ct_priority); - if (ct_new == NULL) - goto error; - - /* Check if the Classtype is present in the HashTable. In case it's present - * ignore it, as it is a duplicate. If not present, add it to the table */ - ct_lookup = HashTableLookup(de_ctx->class_conf_ht, ct_new, 0); - if (ct_lookup == NULL) { - if (HashTableAdd(de_ctx->class_conf_ht, ct_new, 0) < 0) - SCLogDebug("HashTable Add failed"); - } else { - SCLogDebug("Duplicate classtype found inside classification.config"); - if (ct_new->classtype_desc) SCFree(ct_new->classtype_desc); - if (ct_new->classtype) SCFree(ct_new->classtype); - SCFree(ct_new); - } - - return 0; - - error: - return -1; -} - -/** - * \brief Checks if a string is a comment or a blank line. - * - * Comments lines are lines of the following format - - * "# This is a comment string" or - * " # This is a comment string". - * - * \param line String that has to be checked - * - * \retval 1 On the argument string being a comment or blank line - * \retval 0 Otherwise - */ -static int SCClassConfIsLineBlankOrComment(char *line) -{ - while (*line != '\0') { - /* we have a comment */ - if (*line == '#') - return 1; - - /* this line is neither a comment line, nor a blank line */ - if (!isspace((unsigned char)*line)) - return 0; - - line++; - } - - /* we have a blank line */ - return 1; -} - -/** - * \brief Parses the Classification Config file and updates the - * DetectionEngineCtx->class_conf_ht with the Classtype information. - * - * \param de_ctx Pointer to the Detection Engine Context. - */ -void SCClassConfParseFile(DetectEngineCtx *de_ctx, FILE *fd) -{ - char line[1024]; - uint8_t i = 1; - - while (fgets(line, sizeof(line), fd) != NULL) { - if (SCClassConfIsLineBlankOrComment(line)) - continue; - - SCClassConfAddClasstype(line, i, de_ctx); - i++; - } - -#ifdef UNITTESTS - SCLogInfo("Added \"%d\" classification types from the classification file", - de_ctx->class_conf_ht->count); -#endif - - return; -} - -/** - * \brief Returns a new SCClassConfClasstype instance. The classtype string - * is converted into lowercase, before being assigned to the instance. - * - * \param classtype Pointer to the classification type. - * \param classtype_desc Pointer to the classification type description. - * \param priority Holds the priority for the classification type. - * - * \retval ct Pointer to the new instance of SCClassConfClasstype on success; - * NULL on failure. - */ -SCClassConfClasstype *SCClassConfAllocClasstype(uint8_t classtype_id, - const char *classtype, - const char *classtype_desc, - int priority) -{ - SCClassConfClasstype *ct = NULL; - - if (classtype == NULL) - return NULL; - - if ( (ct = SCMalloc(sizeof(SCClassConfClasstype))) == NULL) - return NULL; - memset(ct, 0, sizeof(SCClassConfClasstype)); - - if ( (ct->classtype = SCClassConfStringToLowercase(classtype)) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - - SCClassConfDeAllocClasstype(ct); - return NULL; - } - - if (classtype_desc != NULL && - (ct->classtype_desc = SCStrdup(classtype_desc)) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - - SCClassConfDeAllocClasstype(ct); - return NULL; - } - - ct->classtype_id = classtype_id; - ct->priority = priority; - - return ct; -} - -/** - * \brief Frees a SCClassConfClasstype instance - * - * \param Pointer to the SCClassConfClasstype instance that has to be freed - */ -void SCClassConfDeAllocClasstype(SCClassConfClasstype *ct) -{ - if (ct != NULL) { - if (ct->classtype != NULL) - SCFree(ct->classtype); - - if (ct->classtype_desc != NULL) - SCFree(ct->classtype_desc); - - SCFree(ct); - } - - return; -} - -/** - * \brief Hashing function to be used to hash the Classtype name. Would be - * supplied as an argument to the HashTableInit function for - * DetectEngineCtx->class_conf_ht. - * - * \param ht Pointer to the HashTable. - * \param data Pointer to the data to be hashed. In this case, the data - * would be a pointer to a SCClassConfClasstype instance. - * \param datalen Not used by this function. - */ -uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen) -{ - SCClassConfClasstype *ct = (SCClassConfClasstype *)data; - uint32_t hash = 0; - int i = 0; - - int len = strlen(ct->classtype); - - for (i = 0; i < len; i++) - hash += tolower((unsigned char)(ct->classtype)[i]); - - hash = hash % ht->array_size; - - return hash; -} - -/** - * \brief Used to compare two Classtypes that have been stored in the HashTable. - * This function is supplied as an argument to the HashTableInit function - * for DetectionEngineCtx->class_conf_ct. - * - * \param data1 Pointer to the first SCClassConfClasstype to be compared. - * \param len1 Not used by this function. - * \param data2 Pointer to the second SCClassConfClasstype to be compared. - * \param len2 Not used by this function. - * - * \retval 1 On data1 and data2 being equal. - * \retval 0 On data1 and data2 not being equal. - */ -char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1, - void *data2, uint16_t datalen2) -{ - SCClassConfClasstype *ct1 = (SCClassConfClasstype *)data1; - SCClassConfClasstype *ct2 = (SCClassConfClasstype *)data2; - int len1 = 0; - int len2 = 0; - - if (ct1 == NULL || ct2 == NULL) - return 0; - - if (ct1->classtype == NULL || ct2->classtype == NULL) - return 0; - - len1 = strlen(ct1->classtype); - len2 = strlen(ct2->classtype); - - if (len1 == len2 && memcmp(ct1->classtype, ct2->classtype, len1) == 0) { - SCLogDebug("Match found inside Classification-Config hash function"); - return 1; - } - - return 0; -} - -/** - * \brief Used to free the Classification Config Hash Data that was stored in - * DetectEngineCtx->class_conf_ht Hashtable. - * - * \param ch Pointer to the data that has to be freed. - */ -void SCClassConfClasstypeHashFree(void *ch) -{ - SCClassConfDeAllocClasstype(ch); - - return; -} - -/** - * \brief Loads the Classtype info from the classification.config file. - * - * The classification.config file contains the different classtypes, - * that can be used to label Signatures. Each line of the file should - * have the following format - - * classtype_name, classtype_description, priority - * None of the above parameters should hold a quote inside the file. - * - * \param de_ctx Pointer to the Detection Engine Context that should be updated - * with Classtype information. - */ -void SCClassConfLoadClassficationConfigFile(DetectEngineCtx *de_ctx, FILE *fd) -{ - fd = SCClassConfInitContextAndLocalResources(de_ctx, fd); - if (fd == NULL) { -#ifdef UNITTESTS - if (RunmodeIsUnittests() && fd == NULL) { - return; - } -#endif - SCLogError(SC_ERR_OPENING_FILE, "please check the \"classification-file\" " - "option in your suricata.yaml file"); - return; - } - - SCClassConfParseFile(de_ctx, fd); - SCClassConfDeInitLocalResources(de_ctx, fd); - - return; -} - -/** - * \brief Gets the classtype from the corresponding hash table stored - * in the Detection Engine Context's class conf ht, given the - * classtype name. - * - * \param ct_name Pointer to the classtype name that has to be looked up. - * \param de_ctx Pointer to the Detection Engine Context. - * - * \retval lookup_ct_info Pointer to the SCClassConfClasstype instance from - * the hash table on success; NULL on failure. - */ -SCClassConfClasstype *SCClassConfGetClasstype(const char *ct_name, - DetectEngineCtx *de_ctx) -{ - char name[strlen(ct_name) + 1]; - size_t s; - for (s = 0; s < strlen(ct_name); s++) - name[s] = tolower((unsigned char)ct_name[s]); - name[s] = '\0'; - - SCClassConfClasstype ct_lookup = {0, name, NULL, 0 }; - SCClassConfClasstype *lookup_ct_info = HashTableLookup(de_ctx->class_conf_ht, - &ct_lookup, 0); - return lookup_ct_info; -} - -/*----------------------------------Unittests---------------------------------*/ - - -#ifdef UNITTESTS - -/** - * \brief Creates a dummy classification file, with all valid Classtypes, for - * testing purposes. - * - * \file_path Pointer to the file_path for the dummy classification file. - */ -FILE *SCClassConfGenerateValidDummyClassConfigFD01(void) -{ - const char *buffer = - "config classification: nothing-wrong,Nothing Wrong With Us,3\n" - "config classification: unknown,Unknown are we,3\n" - "config classification: bad-unknown,We think it's bad, 2\n"; - - FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Classifiation Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy classification file, with some valid Classtypes and a - * couple of invalid Classtypes, for testing purposes. - * - * \file_path Pointer to the file_path for the dummy classification file. - */ -FILE *SCClassConfGenerateInValidDummyClassConfigFD02(void) -{ - const char *buffer = - "config classification: not-suspicious,Not Suspicious Traffic,3\n" - "onfig classification: unknown,Unknown Traffic,3\n" - "config classification: _badunknown,Potentially Bad Traffic, 2\n" - "config classification: bamboola1,Unknown Traffic,3\n" - "config classification: misc-activity,Misc activity,-1\n" - "config classification: policy-violation,Potential Corporate " - "config classification: bamboola,Unknown Traffic,3\n"; - - FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Classifiation Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy classification file, with all invalid Classtypes, for - * testing purposes. - * - * \file_path Pointer to the file_path for the dummy classification file. - */ -FILE *SCClassConfGenerateInValidDummyClassConfigFD03(void) -{ - const char *buffer = - "conig classification: not-suspicious,Not Suspicious Traffic,3\n" - "onfig classification: unknown,Unknown Traffic,3\n" - "config classification: _badunknown,Potentially Bad Traffic, 2\n" - "config classification: misc-activity,Misc activity,-1\n"; - - FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Classifiation Config test code"); - - return fd; -} - -/** - * \test Check that the classification file is loaded and the detection engine - * content class_conf_hash_table loaded with the classtype data. - */ -int SCClassConfTest01(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 0; - - if (de_ctx == NULL) - return result; - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - if (de_ctx->class_conf_ht == NULL) - return result; - - result = (de_ctx->class_conf_ht->count == 3); - if (result == 0) printf("de_ctx->class_conf_ht->count %u: ", de_ctx->class_conf_ht->count); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Check that invalid classtypes present in the classification config file - * aren't loaded. - */ -int SCClassConfTest02(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 0; - - if (de_ctx == NULL) - return result; - - FILE *fd = SCClassConfGenerateInValidDummyClassConfigFD03(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - if (de_ctx->class_conf_ht == NULL) - return result; - - result = (de_ctx->class_conf_ht->count == 0); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Check that only valid classtypes are loaded into the hash table from - * the classfication.config file. - */ -int SCClassConfTest03(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 0; - - if (de_ctx == NULL) - return result; - - FILE *fd = SCClassConfGenerateInValidDummyClassConfigFD02(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - if (de_ctx->class_conf_ht == NULL) - return result; - - result = (de_ctx->class_conf_ht->count == 3); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Check if the classtype info from the classification.config file have - * been loaded into the hash table. - */ -int SCClassConfTest04(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 1; - - if (de_ctx == NULL) - return 0; - - FILE *fd = SCClassConfGenerateValidDummyClassConfigFD01(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - if (de_ctx->class_conf_ht == NULL) - return 0; - - result = (de_ctx->class_conf_ht->count == 3); - - result &= (SCClassConfGetClasstype("unknown", de_ctx) != NULL); - result &= (SCClassConfGetClasstype("unKnoWn", de_ctx) != NULL); - result &= (SCClassConfGetClasstype("bamboo", de_ctx) == NULL); - result &= (SCClassConfGetClasstype("bad-unknown", de_ctx) != NULL); - result &= (SCClassConfGetClasstype("BAD-UNKnOWN", de_ctx) != NULL); - result &= (SCClassConfGetClasstype("bed-unknown", de_ctx) == NULL); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Check if the classtype info from the invalid classification.config file - * have not been loaded into the hash table, and cross verify to check - * that the hash table contains no classtype data. - */ -int SCClassConfTest05(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 1; - - if (de_ctx == NULL) - return 0; - - FILE *fd = SCClassConfGenerateInValidDummyClassConfigFD03(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - if (de_ctx->class_conf_ht == NULL) - return 0; - - result = (de_ctx->class_conf_ht->count == 0); - - result &= (SCClassConfGetClasstype("unknown", de_ctx) == NULL); - result &= (SCClassConfGetClasstype("unKnoWn", de_ctx) == NULL); - result &= (SCClassConfGetClasstype("bamboo", de_ctx) == NULL); - result &= (SCClassConfGetClasstype("bad-unknown", de_ctx) == NULL); - result &= (SCClassConfGetClasstype("BAD-UNKnOWN", de_ctx) == NULL); - result &= (SCClassConfGetClasstype("bed-unknown", de_ctx) == NULL); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Check if the classtype info from the classification.config file have - * been loaded into the hash table. - */ -int SCClassConfTest06(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 1; - - if (de_ctx == NULL) - return 0; - - FILE *fd = SCClassConfGenerateInValidDummyClassConfigFD02(); - SCClassConfLoadClassficationConfigFile(de_ctx, fd); - - if (de_ctx->class_conf_ht == NULL) - return 0; - - result = (de_ctx->class_conf_ht->count == 3); - - result &= (SCClassConfGetClasstype("unknown", de_ctx) == NULL); - result &= (SCClassConfGetClasstype("not-suspicious", de_ctx) != NULL); - result &= (SCClassConfGetClasstype("bamboola1", de_ctx) != NULL); - result &= (SCClassConfGetClasstype("bamboola1", de_ctx) != NULL); - result &= (SCClassConfGetClasstype("BAMBOolA1", de_ctx) != NULL); - result &= (SCClassConfGetClasstype("unkNOwn", de_ctx) == NULL); - - DetectEngineCtxFree(de_ctx); - - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief This function registers unit tests for Classification Config API. - */ -void SCClassConfRegisterTests(void) -{ - -#ifdef UNITTESTS - - UtRegisterTest("SCClassConfTest01", SCClassConfTest01, 1); - UtRegisterTest("SCClassConfTest02", SCClassConfTest02, 1); - UtRegisterTest("SCClassConfTest03", SCClassConfTest03, 1); - UtRegisterTest("SCClassConfTest04", SCClassConfTest04, 1); - UtRegisterTest("SCClassConfTest05", SCClassConfTest05, 1); - UtRegisterTest("SCClassConfTest06", SCClassConfTest06, 1); - -#endif /* UNITTESTS */ - -} diff --git a/framework/src/suricata/src/util-classification-config.h b/framework/src/suricata/src/util-classification-config.h deleted file mode 100644 index 7e916c2c..00000000 --- a/framework/src/suricata/src/util-classification-config.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_CLASSIFICATION_CONFIG_H__ -#define __UTIL_CLASSIFICATION_CONFIG_H__ - -/** - * \brief Container for a Classtype from the Classification.config file. - */ -typedef struct SCClassConfClasstype_ { - /* The index of the classification within classification.confg */ - uint8_t classtype_id; - - /* The classtype name. This is the primary key for a Classification. */ - char *classtype; - - /* Description for a classification. Would be used while printing out - * the classification info for a Signature, by the fast-log module. */ - char *classtype_desc; - - /* The priority this classification type carries */ - int priority; -} SCClassConfClasstype; - -SCClassConfClasstype *SCClassConfAllocClasstype(uint8_t, const char *, - const char *, int); -void SCClassConfDeAllocClasstype(SCClassConfClasstype *); -void SCClassConfLoadClassficationConfigFile(DetectEngineCtx *, FILE *fd); -SCClassConfClasstype *SCClassConfGetClasstype(const char *, - DetectEngineCtx *); -void SCClassConfDeInitContext(DetectEngineCtx *); -void SCClassConfRegisterTests(void); - -/* for unittests */ -FILE *SCClassConfGenerateValidDummyClassConfigFD01(void); -FILE *SCClassConfGenerateInValidDummyClassConfigFD02(void); -FILE *SCClassConfGenerateInValidDummyClassConfigFD03(void); - -void SCClassConfInit(void); -void SCClassConfDeinit(void); - -#endif /* __UTIL_CLASSIFICATION_CONFIG_H__ */ diff --git a/framework/src/suricata/src/util-clock.h b/framework/src/suricata/src/util-clock.h deleted file mode 100644 index e6e3517b..00000000 --- a/framework/src/suricata/src/util-clock.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_CLOCK_H__ -#define __UTIL_CLOCK_H__ - -#include - -/* Feel free to add more macros */ - -#define CLOCK_INIT clock_t clo1, clo2; clo1 = clo2 = 0; -#define CLOCK_START clo1 = clock() - -#define CLOCK_END clo2 = clock() - -#define CLOCK_PRINT_SEC printf("Seconds spent: %.4fs\n", ((clo2 - clo1)/(double)CLOCKS_PER_SEC)) - -#define GET_CLOCK_END_SECS ((clo1 - clo2)/(double)CLOCKS_PER_SEC) - -#endif /*__UTIL_CLOCK_H__ */ diff --git a/framework/src/suricata/src/util-conf.c b/framework/src/suricata/src/util-conf.c deleted file mode 100644 index e0f25d1d..00000000 --- a/framework/src/suricata/src/util-conf.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - */ - -#include "suricata-common.h" -#include "config.h" -#include "conf.h" - -TmEcode ConfigSetLogDirectory(char *name) -{ - return ConfSetFinal("default-log-dir", name) ? TM_ECODE_OK : TM_ECODE_FAILED; -} - -char *ConfigGetLogDirectory() -{ - char *log_dir = NULL; - - if (ConfGet("default-log-dir", &log_dir) != 1) { -#ifdef OS_WIN32 - log_dir = _getcwd(NULL, 0); - if (log_dir == NULL) { - log_dir = DEFAULT_LOG_DIR; - } -#else - log_dir = DEFAULT_LOG_DIR; -#endif /* OS_WIN32 */ - } - - return log_dir; -} - -TmEcode ConfigCheckLogDirectory(char *log_dir) -{ - SCEnter(); -#ifdef OS_WIN32 - struct _stat buf; - if (_stat(log_dir, &buf) != 0) { -#else - struct stat buf; - if (stat(log_dir, &buf) != 0) { -#endif /* OS_WIN32 */ - SCReturnInt(TM_ECODE_FAILED); - } - SCReturnInt(TM_ECODE_OK); -} diff --git a/framework/src/suricata/src/util-conf.h b/framework/src/suricata/src/util-conf.h deleted file mode 100644 index 74d87e30..00000000 --- a/framework/src/suricata/src/util-conf.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - */ - -#ifndef __UTIL_UTIL_CONF_H__ -#define __UTIL_UTIL_CONF_H__ - -TmEcode ConfigSetLogDirectory(char *name); -char *ConfigGetLogDirectory(); -TmEcode ConfigCheckLogDirectory(char *log_dir); - -#endif /* __UTIL_UTIL_CONF_H__ */ diff --git a/framework/src/suricata/src/util-coredump-config.c b/framework/src/suricata/src/util-coredump-config.c deleted file mode 100644 index 2115f930..00000000 --- a/framework/src/suricata/src/util-coredump-config.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eileen Donlon - * - * Coredump configuration - */ - -#define _FILE_OFFSET_BITS 64 -#include "util-coredump-config.h" -#include "conf.h" -#include - -/** - * \brief Configures the core dump size. - * - * \retval Returns 1 on success and 0 on failure. - * - */ -int32_t CoredumpLoadConfig (void) -{ - /* get core dump configuration settings for suricata */ - char* dump_size_config = NULL; - rlim_t max_dump = 0; - uint32_t unlimited = 0; - size_t rlim_size = sizeof(rlim_t); - - if (ConfGet ("coredump.max-dump", &dump_size_config) == 0) { - SCLogDebug ("core dump size not specified"); - return 1; - } - if (strcasecmp (dump_size_config, "unlimited") == 0) { - unlimited = 1; - } - else { - /* disallow negative values */ - if (strchr (dump_size_config, '-') != NULL) { - SCLogInfo ("Negative value for core dump size; ignored."); - return 0; - } - /* the size of rlim_t is platform dependent */ - if (rlim_size > 8) { - SCLogInfo ("Unexpected type for rlim_t"); - return 0; - } - errno = 0; - if (rlim_size == 8) { - max_dump = (rlim_t) strtoull (dump_size_config, NULL, 10); - } - else if (rlim_size == 4) { - max_dump = (rlim_t) strtoul (dump_size_config, NULL, 10); - } - if ((errno == ERANGE) || (errno != 0 && max_dump == 0)) { - SCLogInfo ("Illegal core dump size: %s.", dump_size_config); - return 0; - } - SCLogInfo ("Max dump is %llu", (unsigned long long) max_dump); - } - -#if defined OS_WIN32 - /* todo: use the registry to get/set dump configuration */ - SCLogInfo("Configuring core dump is not yet supported on Windows."); - return 0; -#endif - -#ifdef HAVE_SYS_PRCTL_H - /* Linux specific core dump configuration; set dumpable flag if needed */ - int dumpable = 0; - dumpable = prctl (PR_GET_DUMPABLE, 0, 0, 0, 0); - if (dumpable == -1) { - SCLogInfo ("Can't get core dump configuration of process."); - } - else if (unlimited == 1 || max_dump > 0) { - /* try to enable core dump for this process */ - if (prctl (PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) { - SCLogInfo ("Unable to make this process dumpable."); - return 0; - } else { - SCLogDebug ("Process is dumpable."); - } - } - /* don't clear dumpable flag since this will have other effects; - * just set dump size to 0 below */ -#endif /* Linux specific */ - - struct rlimit lim; /*existing limit*/ - struct rlimit new_lim; /*desired limit*/ - - /* get the current core dump file configuration */ - if (getrlimit (RLIMIT_CORE, &lim) == -1) { - SCLogInfo ("Can't read coredump limit for this process."); - return 0; - } - - if (unlimited) { - /* we want no limit on coredump size */ - if (lim.rlim_max == RLIM_INFINITY && lim.rlim_cur == RLIM_INFINITY) { - SCLogInfo ("Core dump size is unlimited."); - return 1; - } - else { - new_lim.rlim_max = RLIM_INFINITY; - new_lim.rlim_cur = RLIM_INFINITY; - if (setrlimit (RLIMIT_CORE, &new_lim) == 0) { - SCLogInfo ("Core dump size set to unlimited."); - return 1; - } - if (errno == EPERM) { - /* couldn't raise the hard limit to unlimited; - * try increasing the soft limit to the hard limit instead */ - if (lim.rlim_cur < lim.rlim_max) { - new_lim.rlim_cur = lim.rlim_max; - if (setrlimit (RLIMIT_CORE, & new_lim) == 0) { - SCLogInfo ("Could not set core dump size to unlimited; core dump size set to the hard limit."); - return 0; - } - else { - SCLogInfo ("Failed to set core dump size to unlimited or to the hard limit."); - return 0; - } - } - SCLogInfo ("Could not set core dump size to unlimited; it's set to the hard limit."); - return 0; - } - } - } - else { - /* we want a non-infinite soft limit on coredump size */ - new_lim.rlim_cur = max_dump; - - /* check whether the hard limit needs to be adjusted */ - if (lim.rlim_max == RLIM_INFINITY) { - /* keep the current value (unlimited) for the hard limit */ - new_lim.rlim_max = lim.rlim_max; - } -#ifdef RLIM_SAVED_MAX - else if (lim.rlim_max == RLIM_SAVED_MAX) { - /* keep the current value (unknown) for the hard limit */ - new_lim.rlim_max = lim.rlim_max; - } -#endif - else if (lim.rlim_max < max_dump) { - /* need to raise the hard coredump size limit */ - new_lim.rlim_max = max_dump; - } - else { - /* hard limit is ample */ - new_lim.rlim_max = lim.rlim_max; - } - if (setrlimit (RLIMIT_CORE, &new_lim) == 0) { - SCLogInfo ("Core dump setting attempted is %llu", (unsigned long long) new_lim.rlim_cur); - struct rlimit actual_lim; - if (getrlimit (RLIMIT_CORE, &actual_lim) == 0) { - if (actual_lim.rlim_cur == RLIM_INFINITY) { - SCLogInfo ("Core dump size set to unlimited."); - } -#ifdef RLIM_SAVED_CUR - else if (actual_lim.rlim_cur == RLIM_SAVED_CUR) { - SCLogInfo ("Core dump size set to soft limit."); - } -#endif - else { - SCLogInfo ("Core dump size set to %llu", (unsigned long long) actual_lim.rlim_cur); - } - } - return 1; - } - - if (errno == EINVAL || errno == EPERM) { - /* could't increase the hard limit, or the soft limit exceeded the hard - * limit; try to raise the soft limit to the hard limit */ - if ((lim.rlim_cur < max_dump && lim.rlim_cur < lim.rlim_max) -#ifdef RLIM_SAVED_CUR - || (lim.rlim_cur == RLIM_SAVED_CUR) -#endif - ){ - new_lim.rlim_max = lim.rlim_max; - new_lim.rlim_cur = lim.rlim_max; - if (setrlimit (RLIMIT_CORE, &new_lim) == 0) { - SCLogInfo("Core dump size set to the hard limit."); - return 0; - } - } - } - } - /* failed to set the coredump limit */ - SCLogInfo ("Could't set coredump size to %s.", dump_size_config); - return 0; -} diff --git a/framework/src/suricata/src/util-coredump-config.h b/framework/src/suricata/src/util-coredump-config.h deleted file mode 100644 index 7994421b..00000000 --- a/framework/src/suricata/src/util-coredump-config.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eileen Donlon - */ - -#ifndef __COREDUMP_CONFIG_H__ -#define __COREDUMP_CONFIG_H__ - -#include "suricata-common.h" - -int32_t CoredumpLoadConfig (void); - -#endif /* __COREDUMP_CONFIG_H__ */ diff --git a/framework/src/suricata/src/util-cpu.c b/framework/src/suricata/src/util-cpu.c deleted file mode 100644 index f8f748bc..00000000 --- a/framework/src/suricata/src/util-cpu.c +++ /dev/null @@ -1,231 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * Retrieve CPU information (configured CPUs, online CPUs) - */ - -#include "util-error.h" -#include "util-debug.h" -#include "suricata-common.h" - -/** - * Ok, if they should use sysconf, check that they have the macro's - * (syscalls) defined; - * - * Note: For windows it's different; Check the following: - * SYSTEM_INFO info; - * GetSystemInfo(&info); - * -> info.dwNumberOfProcessors; - */ -#ifdef _SC_NPROCESSORS_CONF -#define SYSCONF_NPROCESSORS_CONF_COMPAT -#endif - -#ifdef _SC_NPROCESSORS_ONLN -#define SYSCONF_NPROCESSORS_ONLN_COMPAT -#endif - -/* This one is available on Solaris 10 */ -#ifdef _SC_NPROCESSORS_MAX -#define SYSCONF_NPROCESSORS_MAX_COMPAT -#endif - -/** - * \brief Get the number of cpus configured in the system - * \retval 0 if the syscall is not available or we have an error; - * otherwise it will return the number of cpus configured - */ -uint16_t UtilCpuGetNumProcessorsConfigured() -{ -#ifdef SYSCONF_NPROCESSORS_CONF_COMPAT - long nprocs = -1; - nprocs = sysconf(_SC_NPROCESSORS_CONF); - if (nprocs < 1) { - SCLogError(SC_ERR_SYSCALL, "Couldn't retrieve the number of cpus " - "configured (%s)", strerror(errno)); - return 0; - } - - if (nprocs > UINT16_MAX) { - SCLogDebug("It seems that there are more than %"PRIu16" CPUs " - "configured on this system. You can modify util-cpu.{c,h} " - "to use uint32_t to support it", UINT16_MAX); - return UINT16_MAX; - } - - return (uint16_t)nprocs; -#elif OS_WIN32 - long nprocs = -1; - const char* envvar = getenv("NUMBER_OF_PROCESSORS"); - nprocs = (NULL != envvar) ? atoi(envvar) : 0; - if (nprocs < 1) { - SCLogError(SC_ERR_SYSCALL, "Couldn't retrieve the number of cpus " - "configured from the NUMBER_OF_PROCESSORS environment variable"); - return 0; - } - return (uint16_t)nprocs; -#else - SCLogError(SC_ERR_SYSCONF, "Couldn't retrieve the number of cpus " - "configured, sysconf macro unavailable"); - return 0; -#endif -} - -/** - * \brief Get the number of cpus online in the system - * \retval 0 if the syscall is not available or we have an error; - * otherwise it will return the number of cpus online - */ -uint16_t UtilCpuGetNumProcessorsOnline() -{ -#ifdef SYSCONF_NPROCESSORS_ONLN_COMPAT - long nprocs = -1; - nprocs = sysconf(_SC_NPROCESSORS_ONLN); - if (nprocs < 1) { - SCLogError(SC_ERR_SYSCALL, "Couldn't retrieve the number of cpus " - "online (%s)", strerror(errno)); - return 0; - } - - if (nprocs > UINT16_MAX) { - SCLogDebug("It seems that there are more than %"PRIu16" CPUs online. " - "You can modify util-cpu.{c,h} to use uint32_t to " - "support it", UINT16_MAX); - return UINT16_MAX; - } - - return nprocs; -#elif OS_WIN32 - return UtilCpuGetNumProcessorsConfigured(); -#else - SCLogError(SC_ERR_SYSCONF, "Couldn't retrieve the number of cpus online, " - "synconf macro unavailable"); - return 0; -#endif -} - -/** - * \brief Get the maximum number of cpus allowed in the system - * This syscall is present on Solaris, but it's not on linux - * or macosx. Maybe you should look at UtilCpuGetNumProcessorsConfigured() - * \retval 0 if the syscall is not available or we have an error; - * otherwise it will return the number of cpus allowed - */ -uint16_t UtilCpuGetNumProcessorsMax() -{ -#ifdef SYSCONF_NPROCESSORS_MAX_COMPAT - long nprocs = -1; - nprocs = sysconf(_SC_NPROCESSORS_MAX); - if (nprocs < 1) { - SCLogError(SC_ERR_SYSCALL, "Couldn't retrieve the maximum number of cpus " - "allowed by the system (%s)", strerror(errno)); - return 0; - } - - if (nprocs > UINT16_MAX) { - SCLogDebug("It seems that the system support more that %"PRIu16" CPUs. You " - "can modify util-cpu.{c,h} to use uint32_t to support it", UINT16_MAX); - return UINT16_MAX; - } - - return (uint16_t)nprocs; -#else - SCLogError(SC_ERR_SYSCONF, "Couldn't retrieve the maximum number of cpus allowed by " - "the system, synconf macro unavailable"); - return 0; -#endif -} - -/** - * \brief Print a summary of CPUs detected (configured and online) - */ -void UtilCpuPrintSummary() -{ - uint16_t cpus_conf = UtilCpuGetNumProcessorsConfigured(); - uint16_t cpus_online = UtilCpuGetNumProcessorsOnline(); - - SCLogDebug("CPUs Summary: "); - if (cpus_conf > 0) - SCLogDebug("CPUs configured: %"PRIu16, cpus_conf); - if (cpus_online > 0) - SCLogInfo("CPUs/cores online: %"PRIu16, cpus_online); - if (cpus_online == 0 && cpus_conf == 0) - SCLogInfo("Couldn't retireve any information of CPU's, please, send your operating " - "system info and check util-cpu.{c,h}"); -} - -/** - * Get the current number of ticks from the CPU. - * - * \todo We'll have to deal with removig ticks from the extra cpuids inbetween - * 2 calls. - */ -#if defined(__tile__) -#include -uint64_t UtilCpuGetTicks(void) -{ - return get_cycle_count(); -} -#else -uint64_t UtilCpuGetTicks(void) -{ - uint64_t val; -#if defined(__GNUC__) && (defined(__x86_64) || defined(_X86_64_) || defined(ia_64) || defined(__i386__)) -#if defined(__x86_64) || defined(_X86_64_) || defined(ia_64) - __asm__ __volatile__ ( - "xorl %%eax,%%eax\n\t" - "cpuid\n\t" - ::: "%rax", "%rbx", "%rcx", "%rdx"); -#else - __asm__ __volatile__ ( - "xorl %%eax,%%eax\n\t" - "pushl %%ebx\n\t" - "cpuid\n\t" - "popl %%ebx\n\t" - ::: "%eax", "%ecx", "%edx"); -#endif - uint32_t a, d; - __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d)); - val = ((uint64_t)a) | (((uint64_t)d) << 32); -#if defined(__x86_64) || defined(_X86_64_) || defined(ia_64) - __asm__ __volatile__ ( - "xorl %%eax,%%eax\n\t" - "cpuid\n\t" - ::: "%rax", "%rbx", "%rcx", "%rdx"); -#else - __asm__ __volatile__ ( - "xorl %%eax,%%eax\n\t" - "pushl %%ebx\n\t" - "cpuid\n\t" - "popl %%ebx\n\t" - ::: "%eax", "%ecx", "%edx"); -#endif - -#else /* #if defined(__GNU__) */ -#warning Using inferior version of UtilCpuGetTicks - struct timeval now; - gettimeofday(&now, NULL); - val = (now.tv_sec * 1000000) + now.tv_usec; -#endif - return val; -} -#endif /* __tile__ */ diff --git a/framework/src/suricata/src/util-cpu.h b/framework/src/suricata/src/util-cpu.h deleted file mode 100644 index c7af0359..00000000 --- a/framework/src/suricata/src/util-cpu.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - */ - -#ifndef __UTIL_CPU_H__ -#define __UTIL_CPU_H__ - -/* Processors configured: */ -uint16_t UtilCpuGetNumProcessorsConfigured(); -/* Processors online: */ -uint16_t UtilCpuGetNumProcessorsOnline(); - -/* Only on Solaris */ -uint16_t UtilCpuGetNumProcessorsMax(); - -void UtilCpuPrintSummary(); - -uint64_t UtilCpuGetTicks(void); - -#endif /* __UTIL_CPU_H__ */ diff --git a/framework/src/suricata/src/util-crypt.c b/framework/src/suricata/src/util-crypt.c deleted file mode 100644 index a9d82013..00000000 --- a/framework/src/suricata/src/util-crypt.c +++ /dev/null @@ -1,306 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Roliers Jean-Paul - * - * Implements cryptographic functions. - * Based on the libtomcrypt library ( http://libtom.org/?page=features&newsitems=5&whatfile=crypt ) - * - * Implementation of function using NSS is not linked with libtomcrypt. - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "util-crypt.h" -#ifdef HAVE_NSS -#include -#endif - -#ifndef HAVE_NSS - -#define F0(x,y,z) (z ^ (x & (y ^ z))) -#define F1(x,y,z) (x ^ y ^ z) -#define F2(x,y,z) ((x & y) | (z & (x | y))) -#define F3(x,y,z) (x ^ y ^ z) - - -static int Sha1Compress(HashState *md, unsigned char *buf) -{ - uint32_t a,b,c,d,e,W[80],i; - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) { - LOAD32H(W[i], buf + (4*i)); - } - - /* copy state */ - a = md->sha1.state[0]; - b = md->sha1.state[1]; - c = md->sha1.state[2]; - d = md->sha1.state[3]; - e = md->sha1.state[4]; - - /* expand it */ - for (i = 16; i < 80; i++) { - W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); - } - - /* compress */ - /* round one */ - #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); - #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); - #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); - #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); - - for (i = 0; i < 20; ) { - FF0(a,b,c,d,e,i++); - FF0(e,a,b,c,d,i++); - FF0(d,e,a,b,c,i++); - FF0(c,d,e,a,b,i++); - FF0(b,c,d,e,a,i++); - } - - /* round two */ - for (; i < 40; ) { - FF1(a,b,c,d,e,i++); - FF1(e,a,b,c,d,i++); - FF1(d,e,a,b,c,i++); - FF1(c,d,e,a,b,i++); - FF1(b,c,d,e,a,i++); - } - - /* round three */ - for (; i < 60; ) { - FF2(a,b,c,d,e,i++); - FF2(e,a,b,c,d,i++); - FF2(d,e,a,b,c,i++); - FF2(c,d,e,a,b,i++); - FF2(b,c,d,e,a,i++); - } - - /* round four */ - for (; i < 80; ) { - FF3(a,b,c,d,e,i++); - FF3(e,a,b,c,d,i++); - FF3(d,e,a,b,c,i++); - FF3(c,d,e,a,b,i++); - FF3(b,c,d,e,a,i++); - } - - #undef FF0 - #undef FF1 - #undef FF2 - #undef FF3 - - /* store */ - md->sha1.state[0] = md->sha1.state[0] + a; - md->sha1.state[1] = md->sha1.state[1] + b; - md->sha1.state[2] = md->sha1.state[2] + c; - md->sha1.state[3] = md->sha1.state[3] + d; - md->sha1.state[4] = md->sha1.state[4] + e; - - return SC_SHA_1_OK; -} - -static int Sha1Init(HashState * md) -{ - if(md == NULL) - { - return SC_SHA_1_NOK; - } - md->sha1.state[0] = 0x67452301UL; - md->sha1.state[1] = 0xefcdab89UL; - md->sha1.state[2] = 0x98badcfeUL; - md->sha1.state[3] = 0x10325476UL; - md->sha1.state[4] = 0xc3d2e1f0UL; - md->sha1.curlen = 0; - md->sha1.length = 0; - return SC_SHA_1_OK; -} - -static int Sha1Process (HashState * md, const unsigned char *in, unsigned long inlen) -{ - if(md == NULL || in == NULL) { - return SC_SHA_1_INVALID_ARG; - } - - unsigned long n; - int err; - - if (md->sha1.curlen > sizeof(md->sha1.buf)) { - return SC_SHA_1_INVALID_ARG; - } - while (inlen > 0) { - if (md-> sha1.curlen == 0 && inlen >= 64) { - if ((err = Sha1Compress(md, (unsigned char *)in)) != SC_SHA_1_OK) { - return err; - } - md-> sha1 .length += 64 * 8; - in += 64; - inlen -= 64; - } else { - n = MIN(inlen, (64 - md-> sha1 .curlen)); - memcpy(md-> sha1 .buf + md-> sha1.curlen, in, (size_t)n); - md-> sha1 .curlen += n; - in += n; - inlen -= n; - if (md-> sha1 .curlen == 64) { - if ((err = Sha1Compress(md, md-> sha1 .buf)) != SC_SHA_1_OK) { - return err; - } - md-> sha1 .length += 8*64; - md-> sha1 .curlen = 0; - } - } - } - return SC_SHA_1_OK; -} - - - -static int Sha1Done(HashState * md, unsigned char *out) -{ - int i; - - if (md == NULL || out == NULL) - { - return SC_SHA_1_NOK; - } - - if (md->sha1.curlen >= sizeof(md->sha1.buf)) { - return SC_SHA_1_INVALID_ARG; - } - - /* increase the length of the message */ - md->sha1.length += md->sha1.curlen * 8; - - /* append the '1' bit */ - md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md->sha1.curlen > 56) { - while (md->sha1.curlen < 64) { - md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; - } - Sha1Compress(md, md->sha1.buf); - md->sha1.curlen = 0; - } - - /* pad upto 56 bytes of zeroes */ - while (md->sha1.curlen < 56) { - md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; - } - - /* store length */ - STORE64H(md->sha1.length, md->sha1.buf+56); - Sha1Compress(md, md->sha1.buf); - - /* copy output */ - for (i = 0; i < 5; i++) { - STORE32H(md->sha1.state[i], out+(4*i)); - } - - memset(md, 0, sizeof(HashState)); - - return SC_SHA_1_OK; -} - -unsigned char* ComputeSHA1(unsigned char* buff, int bufflen) -{ - HashState md; - unsigned char* lResult = (unsigned char*) SCMalloc((sizeof(unsigned char) * 20)); - if (lResult == NULL) - return NULL; - Sha1Init(&md); - Sha1Process(&md, buff, bufflen); - Sha1Done(&md, lResult); - return lResult; -} - -#else /* HAVE_NSS */ - -unsigned char* ComputeSHA1(unsigned char* buff, int bufflen) -{ - HASHContext *sha1_ctx = HASH_Create(HASH_AlgSHA1); - unsigned char* lResult = NULL; - unsigned int rlen; - if (sha1_ctx == NULL) { - return NULL; - } - - lResult = (unsigned char*) SCMalloc((sizeof(unsigned char) * 20)); - if (lResult == NULL) { - HASH_Destroy(sha1_ctx); - return NULL; - } - HASH_Begin(sha1_ctx); - HASH_Update(sha1_ctx, buff, bufflen); - HASH_End(sha1_ctx, lResult, &rlen, (sizeof(unsigned char) * 20)); - HASH_Destroy(sha1_ctx); - - return lResult; -} - -#endif /* HAVE_NSS */ - -static const char *b64codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -int Base64Encode(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen) -{ - unsigned long i, len2, leven; - unsigned char *p; - if(in == NULL || out == NULL || outlen == NULL) - { - return SC_BASE64_INVALID_ARG; - } - /* valid output size ? */ - len2 = 4 * ((inlen + 2) / 3); - if (*outlen < len2 + 1) { - *outlen = len2 + 1; - return SC_BASE64_OVERFLOW; - } - p = out; - leven = 3*(inlen / 3); - for (i = 0; i < leven; i += 3) { - *p++ = b64codes[(in[0] >> 2) & 0x3F]; - *p++ = b64codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F]; - *p++ = b64codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F]; - *p++ = b64codes[in[2] & 0x3F]; - in += 3; - } - /* Pad it if necessary... */ - if (i < inlen) { - unsigned a = in[0]; - unsigned b = (i+1 < inlen) ? in[1] : 0; - - *p++ = b64codes[(a >> 2) & 0x3F]; - *p++ = b64codes[(((a & 3) << 4) + (b >> 4)) & 0x3F]; - *p++ = (i+1 < inlen) ? b64codes[(((b & 0xf) << 2)) & 0x3F] : '='; - *p++ = '='; - } - /* append a NULL byte */ - *p = '\0'; - /* return ok */ - *outlen = p - out; - return SC_BASE64_OK; -} diff --git a/framework/src/suricata/src/util-crypt.h b/framework/src/suricata/src/util-crypt.h deleted file mode 100644 index 7a3540b2..00000000 --- a/framework/src/suricata/src/util-crypt.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Roliers Jean-Paul - * - * Implements cryptographic functions. - * Based on the libtomcrypt library ( http://libtom.org/?page=features&newsitems=5&whatfile=crypt ) - */ - -#ifndef UTIL_CRYPT_H_ -#define UTIL_CRYPT_H_ - -#include "suricata-common.h" - -typedef enum { - SC_SHA_1_OK, - SC_SHA_1_NOK, - SC_SHA_1_INVALID_ARG, - - SC_BASE64_OK, - SC_BASE64_INVALID_ARG, - SC_BASE64_OVERFLOW, - -} CryptId; - -#ifndef HAVE_NSS - -#define LOAD32H(x, y) \ - { x = ((unsigned long)((y)[0] & 255)<<24) | \ - ((unsigned long)((y)[1] & 255)<<16) | \ - ((unsigned long)((y)[2] & 255)<<8) | \ - ((unsigned long)((y)[3] & 255)); } - -#define STORE64H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ - (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ - (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ - (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } - -#define STORE32H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ - (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } - -#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#ifndef MIN -#define MIN(x, y) ( ((x)<(y))?(x):(y) ) -#endif - -typedef struct Sha1State_ { - uint64_t length; - uint32_t state[5], curlen; - unsigned char buf[64]; -} Sha1State; - -typedef union HashState_ { - char dummy[1]; - Sha1State sha1; - void *data; -} HashState; - -#endif /* don't HAVE_NSS */ - -unsigned char* ComputeSHA1(unsigned char* buff, int bufflen); -int Base64Encode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); - -#endif /* UTIL_CRYPT_H_ */ diff --git a/framework/src/suricata/src/util-cuda-buffer.c b/framework/src/suricata/src/util-cuda-buffer.c deleted file mode 100644 index efaef9ff..00000000 --- a/framework/src/suricata/src/util-cuda-buffer.c +++ /dev/null @@ -1,1358 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * API has be introduced to allow buffering of data by multiple writers - * asynronously. The current version only allows sequential reads. - * - * The API works by first registering a couple of buffers, which would - * be sliced and allocated for use by the API to potential writers. - * - * The registration API requires 3 buffers to be registered. The data - * buffer(d_buffer), into which the API buffers data, the pointer buffer - * (p_buffer), which would hold the pointer var instance corresponding to - * its entry in the d_buffer, and the offset buffer(o_buffer), which - * holds an offset entry for the data corresponding to the pointer buffer - * entry. - * - * A writer wishing to write data would be required to obtain a slice - * using CudaBufferGetSlice. Once data has been written to the slice, - * it can report back saying the slice has been written to by setting - * a flag in the slice - SC_ATOMIC_SET(slice->done, 1). - * - * A reader wishing to retrieve the data written by writers, will do - * so using the API call - CudaBufferCullCompletedSlices(). Once data - * has been consumed, the reader would report back using - * CudaBufferReportCulledConsumption() so that resources can be freed - * to be reallocated to other writers. - */ - -#ifdef __SC_CUDA_SUPPORT__ - -#include "suricata-common.h" -#include "suricata.h" - -#include "util-atomic.h" -#include "util-pool.h" -#include "util-misc.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-cuda-buffer.h" - -/* rotation limit for the buffers. This basically decides at what position - * inside alloced buffer should the API rotate and start using the buffer - * from the start - The right value's from 0.1-1.0. Do note that the - * rotation decision is taken when the culling process takes place. - * Have a look at - CudaBufferCullCompletedSlices */ -#define CUDA_BUFFER_BUFFER_ROTATION_LIMIT 0.75 - -/* The max buffer size that be registered to CudaBufferRegisterNew */ -#define CUDA_BUFFER_BUFFER_LIMIT (1 * 1024 * 1024 * 1024) - -/* 100,000 * 5 = 500,000 */ -#define CUDA_BUFFER_ITEM_LIMIT (100000 * 5) - -/* a million slices to be prealloced = 100,000 * 10 */ -#define CUDA_BUFFER_SLICE_POOL_PREALLOC (100000 * 10) - -/* we store all our slices here */ -static Pool *slice_pool = NULL; -/* mutex for the above slice pool */ -static SCMutex slice_pool_mutex; - -/** - * \brief Used by a consumer to report back(and thus have it freed), - * once it has consumed data returned in the CudaBufferCulledInfo - * instance(obtained from the call to CudaBufferCullCompletedSlices). - */ -void CudaBufferReportCulledConsumption(CudaBufferData *cb_data, - CudaBufferCulledInfo *culled_info) -{ - SCMutexLock(&cb_data->m); - - if (culled_info->d_buffer_reset) { - cb_data->d_buffer_read = 0; - } else { - if (culled_info->no_of_items != 0) { - cb_data->d_buffer_read = culled_info->d_buffer_start_offset + - culled_info->d_buffer_len; - } - } - - if (culled_info->op_buffer_reset) { - cb_data->op_buffer_read = 0; - } else { - if (culled_info->no_of_items != 0) { - cb_data->op_buffer_read += culled_info->no_of_items; - } - } - - SCMutexUnlock(&cb_data->m); -} - -/** - * \brief Remove slices that are done. "Done" as in worker threads are done - * writing data to it. - * - * \param cb_data Pointer to the CudaBufferData instance. - */ -void CudaBufferCullCompletedSlices(CudaBufferData *cb_data, - CudaBufferCulledInfo *culled_info, - uint32_t size_limit) -{ - culled_info->no_of_items = 0; - culled_info->d_buffer_reset = 0; - culled_info->op_buffer_reset = 0; - - SCMutexLock(&cb_data->m); - - int buffer_reset = 0; - uint32_t d_buffer_write_temp = 0; - uint32_t op_buffer_write_temp = 0; - - if ((cb_data->d_buffer_write >= - (cb_data->d_buffer_len * CUDA_BUFFER_BUFFER_ROTATION_LIMIT)) && - (cb_data->d_buffer_read != 0)) - { - SCLogDebug("d_buffer reset"); - d_buffer_write_temp = cb_data->d_buffer_write; - cb_data->d_buffer_write = 0; - buffer_reset = 1; - culled_info->d_buffer_reset = 1; - } - - /* reset op_buffer */ - if ((cb_data->op_buffer_write >= - (cb_data->op_buffer_len * CUDA_BUFFER_BUFFER_ROTATION_LIMIT)) && - (cb_data->op_buffer_read != 0)) - { - SCLogDebug("op_buffer reset"); - op_buffer_write_temp = cb_data->op_buffer_write; - cb_data->op_buffer_write = 0; - buffer_reset = 1; - culled_info->op_buffer_reset = 1; - } - - CudaBufferSlice *slice_temp = cb_data->slice_head; - CudaBufferSlice *max_culled_slice = NULL; - uint32_t curr_size = 0; - - while (slice_temp != NULL) { - if (!SC_ATOMIC_GET(slice_temp->done)) { - SCLogDebug("CudaBuffer waiting on an item to finish"); - if (buffer_reset) { - while (!SC_ATOMIC_GET(slice_temp->done)) - usleep(1); - } else { - break; - } - } - - if (curr_size + (slice_temp->end_offset - slice_temp->start_offset + 1) > size_limit) { - if (buffer_reset) { - cb_data->op_buffer_write = op_buffer_write_temp; - cb_data->d_buffer_write = d_buffer_write_temp; - culled_info->d_buffer_reset = 0; - culled_info->op_buffer_reset = 0; - } - break; - } - - max_culled_slice = slice_temp; - curr_size += (slice_temp->end_offset - slice_temp->start_offset + 1); - - slice_temp = slice_temp->next; - } - - CudaBufferSlice *slice_head = cb_data->slice_head; - - if (max_culled_slice != NULL) { - cb_data->slice_head = max_culled_slice->next; - if (max_culled_slice->next == NULL) { - cb_data->slice_tail = NULL; - } - max_culled_slice->next = NULL; - } else { - SCMutexUnlock(&cb_data->m); - return; - } - - culled_info->d_buffer_start_offset = slice_head->start_offset; - culled_info->d_buffer_len = (max_culled_slice->end_offset - - slice_head->start_offset + 1); - culled_info->op_buffer_start_offset = cb_data->op_buffer_read; - SCMutexUnlock(&cb_data->m); - - /* push out the used slices to the the slice_pool */ - SCMutexLock(&slice_pool_mutex); - slice_temp = slice_head; - while (slice_temp != max_culled_slice) { - CudaBufferSlice *tmp = slice_temp->next; - - PoolReturn(slice_pool, slice_temp); - culled_info->no_of_items++; - - slice_temp = tmp; - } - PoolReturn(slice_pool, slice_temp); - culled_info->no_of_items++; - SCMutexUnlock(&slice_pool_mutex); - - return; -} - -/** - * \internal - * \brief Adds a slice to the CudaBufferData slice list. - * - * We expect the CudaBufferData instance to be locked. - * - * \param cb_data Pointer to the CudaBufferdata instance. - * \param slice Pointer to the slice to be pushed. - */ -static inline void CudaBufferAppendSlice(CudaBufferData *cb_data, CudaBufferSlice *slice) -{ - slice->next = NULL; - - if (cb_data->slice_head == NULL) { - cb_data->slice_head = slice; - cb_data->slice_tail = slice; - } else { - cb_data->slice_tail->next = slice; - cb_data->slice_tail = slice; - } - - return; -} - -/** - * \brief Gets a new buffer slice for a consumer to write to. - * - * All slices returned are aligned to the next 8 byte boundary. - * - * \param cb_data Pointer to the CudaBufferdata instance. - * \param len Length of the slice required. - * \param p Pointer to the var corresponding to the data to store. - * - * \retval slice Pointer to the slice if successful; NULL if unsuccessful. - */ -CudaBufferSlice *CudaBufferGetSlice(CudaBufferData *cb_data, uint32_t len, void *p) -{ -#define ALIGN_UP(offset, alignment) (offset) = ((offset) + (alignment) - 1) & ~((alignment) - 1) - - SCMutexLock(&slice_pool_mutex); - CudaBufferSlice *slice = PoolGet(slice_pool); - SCMutexUnlock(&slice_pool_mutex); - if (slice == NULL) { - return NULL; - } - - SCMutexLock(&cb_data->m); - - if (cb_data->d_buffer_write < cb_data->d_buffer_read) { - if (cb_data->d_buffer_write + len >= cb_data->d_buffer_read) { - SCLogDebug("d_buffer full"); - SCMutexUnlock(&cb_data->m); - - SCMutexLock(&slice_pool_mutex); - PoolReturn(slice_pool, slice); - SCMutexUnlock(&slice_pool_mutex); - return NULL; - } - } else { - if (cb_data->d_buffer_write + len > cb_data->d_buffer_len) { - SCLogDebug("d_buffer limit hit - buffer_len - %"PRIu32, - cb_data->d_buffer_len); - SCMutexUnlock(&cb_data->m); - - SCMutexLock(&slice_pool_mutex); - PoolReturn(slice_pool, slice); - SCMutexUnlock(&slice_pool_mutex); - return NULL; - } - } - - if (cb_data->op_buffer_write < cb_data->op_buffer_read) { - if (cb_data->op_buffer_write + 1 >= cb_data->op_buffer_read) { - SCLogDebug("op_buffer full"); - SCMutexUnlock(&cb_data->m); - - SCMutexLock(&slice_pool_mutex); - PoolReturn(slice_pool, slice); - SCMutexUnlock(&slice_pool_mutex); - return NULL; - } - } else { - if (cb_data->op_buffer_write + 1 > cb_data->op_buffer_len) { - SCLogDebug("op_buffer limit hit - buffer_len - %"PRIu32, - cb_data->op_buffer_len); - SCMutexUnlock(&cb_data->m); - - SCMutexLock(&slice_pool_mutex); - PoolReturn(slice_pool, slice); - SCMutexUnlock(&slice_pool_mutex); - return NULL; - } - } - - slice->start_offset = cb_data->d_buffer_write; - cb_data->d_buffer_write = slice->start_offset + len; - ALIGN_UP(cb_data->d_buffer_write, 8); - slice->end_offset = cb_data->d_buffer_write - 1; - slice->buffer = cb_data->d_buffer; - SC_ATOMIC_SET(slice->done, 0); - - CudaBufferAppendSlice(cb_data, slice); - cb_data->no_of_items++; - - cb_data->o_buffer[cb_data->op_buffer_write] = slice->start_offset; - cb_data->p_buffer[cb_data->op_buffer_write] = p; - cb_data->op_buffer_write++; - - SCMutexUnlock(&cb_data->m); - - return slice; -} - -void CudaBufferDeRegister(CudaBufferData *cb_data) -{ - CudaBufferSlice *slice_temp = cb_data->slice_head; - SCMutexLock(&slice_pool_mutex); - while (slice_temp != NULL) { - CudaBufferSlice *slice_temp_next = slice_temp->next; - PoolReturn(slice_pool, slice_temp); - slice_temp = slice_temp_next; - } - SCMutexUnlock(&slice_pool_mutex); - - SCMutexDestroy(&cb_data->m); - SCFree(cb_data); - - return; -} - -/** - * \brief Registers a new buffer to be handled by the CudaBuffer API. - * - * More on what this API does can be understood from the API - * docs at the start of this file. - * - * \param d_buffer The data buffer to work with. - * \param d_buffer_len Length of d_buffer. - * \param o_buffer The offset buffer. - * \param p_buffer The pointer buffer. - * \param op_buffer_no_of_items Length of o_buffer and p_buffer. Please - * note that both o_buffer and p_buffer - * should be of the same length. - * \param len Length of the buffer to be assigned. - */ -CudaBufferData *CudaBufferRegisterNew(uint8_t *d_buffer, uint32_t d_buffer_len, - uint32_t *o_buffer, void **p_buffer, - uint32_t op_buffer_no_of_items) -{ - if (d_buffer_len > CUDA_BUFFER_BUFFER_LIMIT) { - SCLogError(SC_ERR_CUDA_BUFFER_ERROR, "Buffer max limit exceeded. We " - "accept a max limit of %u bytes", CUDA_BUFFER_BUFFER_LIMIT); - return NULL; - } - - if ((d_buffer_len % 8) != 0) { - SCLogError(SC_ERR_CUDA_BUFFER_ERROR, "Please specify a buffer length which " - "is a multiple of 8"); - return NULL; - } - - CudaBufferData *new = SCMalloc(sizeof(CudaBufferData)); - if (unlikely(new == NULL)) { - return NULL; - } - memset(new, 0, sizeof(CudaBufferData)); - - /* payload/data buffer and set its size */ - new->d_buffer = d_buffer; - new->d_buffer_len = d_buffer_len; - - /* offset buffer and set its size */ - new->o_buffer = o_buffer; - new->p_buffer = p_buffer; - /* common to the above 2 malloc'ed buffers */ - new->op_buffer_len = op_buffer_no_of_items; - - /* used to lock this new instance when it's used */ - SCMutexInit(&new->m, NULL); - - return new; -} - -static void *CudaBufferSlicePoolAlloc(void *null) -{ - void *ptr = SCMalloc(sizeof(CudaBufferSlice)); - if (unlikely(ptr == NULL)) - return NULL; - memset(ptr, 0, sizeof(CudaBufferSlice)); - - SC_ATOMIC_INIT(((CudaBufferSlice *)ptr)->done); - - return ptr; -} - -static int CudaBufferSlicePoolInit(void *data, void *init_data) -{ - SC_ATOMIC_INIT(((CudaBufferSlice *)data)->done); - - return 1; -} - -/* disabled to reflect the changes made in PoolInit */ -#if 0 -static void CudaBufferSlicePoolFree(void *data) -{ - SC_ATOMIC_DESTROY(((CudaBufferSlice *)data)->done); - SCFree(data); - - return; -} -#endif - -static void CudaBufferSlicePoolCleanup(void *data) -{ - SC_ATOMIC_DESTROY(((CudaBufferSlice *)data)->done); - - return; -} - -/** - * \brief Init the API. To be called only once at startup time. - */ -void CudaBufferInit(void) -{ - SCMutexInit(&slice_pool_mutex, NULL); - - slice_pool = PoolInit(CUDA_BUFFER_SLICE_POOL_PREALLOC, - CUDA_BUFFER_SLICE_POOL_PREALLOC, - sizeof(CudaBufferSlice), - CudaBufferSlicePoolAlloc, - CudaBufferSlicePoolInit, - NULL, - CudaBufferSlicePoolCleanup, - NULL); - if (slice_pool == NULL) { - SCLogError(SC_ERR_POOL_INIT, "CudaBuffer slice_pool is not initialized"); - exit(EXIT_FAILURE); - } - - return; -} - -/****************************Unittests***************************/ - -#ifdef UNITTESTS - -int CudaBufferTest01(void) -{ - CudaBufferSlice *slice1, *slice2, *slice3, *slice4, *slice_temp; - int result = 0; - - uint8_t *d_buffer = SCMalloc(sizeof(uint8_t) * 64); - uint32_t *o_buffer = SCMalloc(sizeof(uint32_t) * 64); - void **p_buffer = SCMalloc(sizeof(void *) * 64); - if (d_buffer == NULL || o_buffer == NULL || p_buffer == NULL) { - printf("failure 0\n"); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - return 0; - } - - CudaBufferData *data = CudaBufferRegisterNew(d_buffer, 64, - o_buffer, p_buffer, 64); - if (data == NULL) { - goto end; - } - - /* new slice */ - slice1 = CudaBufferGetSlice(data, 8, NULL); - if (slice1->start_offset != 0 || slice1->end_offset != 7 || - SC_ATOMIC_GET(slice1->done) != 0) { - printf("failure 1\n"); - goto end; - } - if (data->d_buffer_write != 8 || data->d_buffer_read != 0 || - data->op_buffer_write != 1 || data->op_buffer_read != 0 || - data->no_of_items != 1) { - printf("failure 2\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 0 || slice_temp->end_offset != 7 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 3\n"); - goto end; - } - if (slice_temp->next != NULL) { - printf("failure 4\n"); - goto end; - } - - /* new slice */ - slice2 = CudaBufferGetSlice(data, 16, NULL); - if (slice2->start_offset != 8 || slice2->end_offset != 23 || - SC_ATOMIC_GET(slice2->done) != 0) { - printf("failure 5\n"); - goto end; - } - if (data->d_buffer_write != 24 || data->d_buffer_read != 0 || - data->op_buffer_write != 2 || data->op_buffer_read != 0 || - data->no_of_items != 2) { - printf("failure 6\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 0 || slice_temp->end_offset != 7 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 7\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp->start_offset != 8 || slice_temp->end_offset != 23 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 8\n"); - goto end; - } - if (slice_temp->next != NULL) { - printf("failure 9\n"); - goto end; - } - - /* new slice */ - slice3 = CudaBufferGetSlice(data, 36, NULL); - if (slice3->start_offset != 24 || slice3->end_offset != 63 || - SC_ATOMIC_GET(slice3->done) != 0) { - printf("failure 10\n"); - goto end; - } - if (data->d_buffer_write != 64 || data->d_buffer_read != 0 || - data->op_buffer_write != 3 || data->op_buffer_read != 0 || - data->no_of_items != 3) { - printf("failure 11\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 0 || slice_temp->end_offset != 7 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 12\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp->start_offset != 8 || slice_temp->end_offset != 23 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 13\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp->start_offset != 24 || slice_temp->end_offset != 63 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 14\n"); - goto end; - } - if (slice_temp->next != NULL) { - printf("failure 15\n"); - goto end; - } - - slice4 = CudaBufferGetSlice(data, 10, NULL); - if (slice4 != NULL) { - printf("failure 16\n"); - goto end; - } - - result = 1; - end: - slice_temp = data->slice_head; - while (slice_temp != NULL) { - SC_ATOMIC_SET(slice_temp->done, 1); - slice_temp = slice_temp->next; - } - CudaBufferCulledInfo culled_info; - memset(&culled_info, 0, sizeof(CudaBufferCulledInfo)); - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->slice_head != NULL || data->slice_tail != NULL) { - printf("failure 17\n"); - result = 0; - } - - CudaBufferDeRegister(data); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - - return result; -} - -int CudaBufferTest02(void) -{ - CudaBufferSlice *slice1, *slice2, *slice3, *slice_temp; - int result = 0; - - uint8_t *d_buffer = SCMalloc(sizeof(uint8_t) * 64); - uint32_t *o_buffer = SCMalloc(sizeof(uint32_t) * 64); - void **p_buffer = SCMalloc(sizeof(void *) * 64); - if (d_buffer == NULL || o_buffer == NULL || p_buffer == NULL) { - printf("failure 0\n"); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - return 0; - } - - CudaBufferData *data = CudaBufferRegisterNew(d_buffer, 64, - o_buffer, p_buffer, 64); - if (data == NULL) { - goto end; - } - - slice1 = CudaBufferGetSlice(data, 8, NULL); - slice2 = CudaBufferGetSlice(data, 16, NULL); - if (data->d_buffer_write != 24 || data->d_buffer_read != 0 || - data->op_buffer_write != 2 || data->op_buffer_read != 0 || - data->no_of_items != 2) { - printf("failure 1\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 0 || slice_temp->end_offset != 7 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 2\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp->start_offset != 8 || slice_temp->end_offset != 23 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 3\n"); - goto end; - } - if (slice_temp->next != NULL) { - printf("failure 4\n"); - goto end; - } - - /* culling */ - CudaBufferCulledInfo culled_info; - memset(&culled_info, 0, sizeof(CudaBufferCulledInfo)); - - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (culled_info.no_of_items != 0) { - printf("failure 5\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 0 || slice_temp->end_offset != 7 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 6\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp->start_offset != 8 || slice_temp->end_offset != 23 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 7\n"); - goto end; - } - if (slice_temp->next != NULL) { - printf("failure 8\n"); - goto end; - } - - SC_ATOMIC_SET(slice2->done, 1); - - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (culled_info.no_of_items != 0) { - printf("failure 9\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 0 || slice_temp->end_offset != 7 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 10\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp->start_offset != 8 || slice_temp->end_offset != 23 || - SC_ATOMIC_GET(slice_temp->done) != 1) { - printf("failure 11\n"); - goto end; - } - if (slice_temp->next != NULL) { - printf("failure 12\n"); - goto end; - } - - SC_ATOMIC_SET(slice1->done, 1); - - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (culled_info.no_of_items != 2) { - printf("failure 13\n"); - goto end; - } - if (data->slice_head != NULL || data->slice_tail != NULL) { - printf("failure 14\n"); - goto end; - } - if (culled_info.d_buffer_start_offset != 0 || - culled_info.d_buffer_len != 24 || - culled_info.op_buffer_start_offset != 0 || - culled_info.d_buffer_reset != 0 || culled_info.op_buffer_reset != 0) { - printf("failure 15\n"); - goto end; - } - if (data->d_buffer_write != 24 || data->d_buffer_read != 0 || - data->op_buffer_write != 2 || data->op_buffer_read != 0 || - data->no_of_items != 2) { - printf("failure 16\n"); - goto end; - } - CudaBufferReportCulledConsumption(data, &culled_info); - if (data->d_buffer_write != 24 || data->d_buffer_read != 24 || - data->op_buffer_write != 2 || data->op_buffer_read != 2 || - data->no_of_items != 2) { - printf("failure 17\n"); - goto end; - } - - /* new slice */ - slice3 = CudaBufferGetSlice(data, 8, NULL); - if (slice3->start_offset != 24 || slice3->end_offset != 31 || - SC_ATOMIC_GET(slice3->done) != 0) { - printf("failure 18\n"); - goto end; - } - if (data->d_buffer_write != 32 || data->d_buffer_read != 24 || - data->op_buffer_write != 3 || data->op_buffer_read != 2 || - data->no_of_items != 3) { - printf("failure 19\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 24 || slice_temp->end_offset != 31 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 20\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp != NULL) { - printf("failure 21\n"); - goto end; - } - - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (culled_info.no_of_items != 0) { - printf("failure 22\n"); - goto end; - } - if (data->d_buffer_write != 32 || data->d_buffer_read != 24 || - data->op_buffer_write != 3 || data->op_buffer_read != 2 || - data->no_of_items != 3) { - printf("failure 23\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 24 || slice_temp->end_offset != 31 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 24\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp != NULL) { - printf("failure 25\n"); - goto end; - } - - /* set done flag */ - SC_ATOMIC_SET(slice3->done, 1); - if (slice3->start_offset != 24 || slice3->end_offset != 31 || - SC_ATOMIC_GET(slice3->done) != 1) { - printf("failure 26\n"); - goto end; - } - if (data->d_buffer_write != 32 || data->d_buffer_read != 24 || - data->op_buffer_write != 3 || data->op_buffer_read != 2 || - data->no_of_items != 3) { - printf("failure 27\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 24 || slice_temp->end_offset != 31 || - SC_ATOMIC_GET(slice_temp->done) != 1) { - printf("failure 28\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp != NULL) { - printf("failure 29\n"); - goto end; - } - - /* culling */ - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (culled_info.no_of_items != 1) { - printf("failure 30\n"); - goto end; - } - if (data->slice_head != NULL || data->slice_tail != NULL) { - printf("failure 31\n"); - goto end; - } - if (culled_info.d_buffer_start_offset != 24 || - culled_info.d_buffer_len != 8 || - culled_info.op_buffer_start_offset != 2 || - culled_info.d_buffer_reset != 0 || culled_info.op_buffer_reset != 0) { - printf("failure 32\n"); - goto end; - } - if (data->d_buffer_write != 32 || data->d_buffer_read != 24 || - data->op_buffer_write != 3 || data->op_buffer_read != 2 || - data->no_of_items != 3) { - printf("failure 33\n"); - goto end; - } - CudaBufferReportCulledConsumption(data, &culled_info); - if (data->d_buffer_write != 32 || data->d_buffer_read != 32 || - data->op_buffer_write != 3 || data->op_buffer_read != 3 || - data->no_of_items != 3) { - printf("failure 34\n"); - goto end; - } - - result = 1; - end: - slice_temp = data->slice_head; - while (slice_temp != NULL) { - SC_ATOMIC_SET(slice_temp->done, 1); - slice_temp = slice_temp->next; - } - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->slice_head != NULL || data->slice_tail != NULL) { - printf("failure 35\n"); - result = 0; - } - - CudaBufferDeRegister(data); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - - return result; -} - -int CudaBufferTest03(void) -{ - CudaBufferSlice *slice, *slice_temp; - int result = 0; - - uint8_t *d_buffer = SCMalloc(sizeof(uint8_t) * 64); - uint32_t *o_buffer = SCMalloc(sizeof(uint32_t) * 64); - void **p_buffer = SCMalloc(sizeof(void *) * 64); - if (d_buffer == NULL || o_buffer == NULL || p_buffer == NULL) { - printf("failure 0\n"); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - return 0; - } - - CudaBufferData *data = CudaBufferRegisterNew(d_buffer, 64, - o_buffer, p_buffer, 64); - if (data == NULL) { - goto end; - } - - slice = CudaBufferGetSlice(data, 16, NULL); - BUG_ON(slice == NULL); - slice = CudaBufferGetSlice(data, 16, NULL); - BUG_ON(slice == NULL); - slice = CudaBufferGetSlice(data, 24, NULL); - BUG_ON(slice == NULL); - - /* culling */ - CudaBufferCulledInfo culled_info; - memset(&culled_info, 0, sizeof(CudaBufferCulledInfo)); - - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (culled_info.no_of_items != 0) { - printf("failure 1\n"); - goto end; - } - if (data->d_buffer_write != 56 || data->d_buffer_read != 0 || - data->op_buffer_write != 3 || data->op_buffer_read != 0 || - data->no_of_items != 3) { - printf("failure 2\n"); - goto end; - } - slice_temp = data->slice_head; - if (slice_temp->start_offset != 0 || slice_temp->end_offset != 15 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 3\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp->start_offset != 16 || slice_temp->end_offset != 31 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 4\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp->start_offset != 32 || slice_temp->end_offset != 55 || - SC_ATOMIC_GET(slice_temp->done) != 0) { - printf("failure 5\n"); - goto end; - } - slice_temp = slice_temp->next; - if (slice_temp != NULL) { - printf("failure 6\n"); - goto end; - } - - result = 1; - end: - slice_temp = data->slice_head; - while (slice_temp != NULL) { - SC_ATOMIC_SET(slice_temp->done, 1); - slice_temp = slice_temp->next; - } - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->slice_head != NULL || data->slice_tail != NULL) { - printf("failure 7\n"); - result = 0; - } - - CudaBufferDeRegister(data); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - - return result; -} - -int CudaBufferTest04(void) -{ - CudaBufferSlice *slice1, *slice2, *slice3, *slice_temp; - int result = 0; - - uint8_t *d_buffer = SCMalloc(sizeof(uint8_t) * 64); - uint32_t *o_buffer = SCMalloc(sizeof(uint32_t) * 64); - void **p_buffer = SCMalloc(sizeof(void *) * 64); - if (d_buffer == NULL || o_buffer == NULL || p_buffer == NULL) { - printf("failure 0\n"); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - return 0; - } - - CudaBufferData *data = CudaBufferRegisterNew(d_buffer, 64, - o_buffer, p_buffer, 64); - if (data == NULL) { - goto end; - } - - slice1 = CudaBufferGetSlice(data, 16, NULL); - slice2 = CudaBufferGetSlice(data, 16, NULL); - slice3 = CudaBufferGetSlice(data, 24, NULL); - - SC_ATOMIC_SET(slice1->done, 1); - - /* culling */ - CudaBufferCulledInfo culled_info; - memset(&culled_info, 0, sizeof(CudaBufferCulledInfo)); - - if (data->d_buffer_write != 56 || data->d_buffer_read != 0 || - data->op_buffer_write != 3 || data->op_buffer_read != 0 || - data->no_of_items != 3) { - printf("failure 1\n"); - goto end; - } - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (culled_info.no_of_items != 1) { - printf("failure 2\n"); - goto end; - } - if (data->d_buffer_write != 56 || data->d_buffer_read != 0 || - data->op_buffer_write != 3 || data->op_buffer_read != 0 || - data->no_of_items != 3) { - printf("failure 3\n"); - goto end; - } - CudaBufferReportCulledConsumption(data, &culled_info); - if (data->d_buffer_write != 56 || data->d_buffer_read != 16 || - data->op_buffer_write != 3 || data->op_buffer_read != 1 || - data->no_of_items != 3) { - printf("failure 4\n"); - goto end; - } - - SC_ATOMIC_SET(slice2->done, 1); - SC_ATOMIC_SET(slice3->done, 1); - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (culled_info.no_of_items != 2) { - printf("failure 5\n"); - goto end; - } - if (data->d_buffer_write != 0 || data->d_buffer_read != 16 || - data->op_buffer_write != 3 || data->op_buffer_read != 1 || - data->no_of_items != 3) { - printf("failure 6\n"); - goto end; - } - CudaBufferReportCulledConsumption(data, &culled_info); - if (data->d_buffer_write != 0 || data->d_buffer_read != 0 || - data->op_buffer_write != 3 || data->op_buffer_read != 3 || - data->no_of_items != 3) { - printf("failure 7\n"); - goto end; - } - - slice_temp = data->slice_head; - while (slice_temp != NULL) { - SC_ATOMIC_SET(slice_temp->done, 1); - slice_temp = slice_temp->next; - } - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->slice_head != NULL || data->slice_tail != NULL) { - printf("failure 8\n"); - goto end; - } - - result = 1; - end: - slice_temp = data->slice_head; - while (slice_temp != NULL) { - SC_ATOMIC_SET(slice_temp->done, 1); - slice_temp = slice_temp->next; - } - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->slice_head != NULL || data->slice_tail != NULL) { - printf("failure 9\n"); - result = 0; - } - - CudaBufferDeRegister(data); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - - return result; -} - -int CudaBufferTest05(void) -{ - CudaBufferSlice *slice1, *slice2, *slice3, *slice_temp; - int result = 0; - - uint8_t *d_buffer = SCMalloc(sizeof(uint8_t) * 64); - uint32_t *o_buffer = SCMalloc(sizeof(uint32_t) * 64); - void **p_buffer = SCMalloc(sizeof(void *) * 64); - if (d_buffer == NULL || o_buffer == NULL || p_buffer == NULL) { - printf("failure 0\n"); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - return 0; - } - - CudaBufferData *data = CudaBufferRegisterNew(d_buffer, 64, - o_buffer, p_buffer, 64); - if (data == NULL) { - goto end; - } - - slice1 = CudaBufferGetSlice(data, 16, NULL); - slice2 = CudaBufferGetSlice(data, 16, NULL); - slice3 = CudaBufferGetSlice(data, 24, NULL); - - SC_ATOMIC_SET(slice1->done, 1); - - /* culling */ - CudaBufferCulledInfo culled_info; - memset(&culled_info, 0, sizeof(CudaBufferCulledInfo)); - - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - CudaBufferReportCulledConsumption(data, &culled_info); - - SC_ATOMIC_SET(slice2->done, 1); - SC_ATOMIC_SET(slice3->done, 1); - - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - CudaBufferReportCulledConsumption(data, &culled_info); - slice1 = CudaBufferGetSlice(data, 16, NULL); - if (slice1 == NULL) { - printf("failure 1\n"); - goto end; - } - slice2 = CudaBufferGetSlice(data, 16, NULL); - if (slice2 == NULL) { - printf("failure 2\n"); - goto end; - } - slice3 = CudaBufferGetSlice(data, 24, NULL); - if (slice2 == NULL) { - printf("failure 3\n"); - goto end; - } - - result = 1; - end: - slice_temp = data->slice_head; - while (slice_temp != NULL) { - SC_ATOMIC_SET(slice_temp->done, 1); - slice_temp = slice_temp->next; - } - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->slice_head != NULL || data->slice_tail != NULL) { - printf("failure 4\n"); - result = 0; - } - - CudaBufferDeRegister(data); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - - return result; -} - -int CudaBufferTest06(void) -{ - CudaBufferSlice *slice, *slice_temp; - int result = 0; - CudaBufferCulledInfo culled_info; - memset(&culled_info, 0, sizeof(CudaBufferCulledInfo)); - - uint8_t *d_buffer = SCMalloc(sizeof(uint8_t) * 64); - uint32_t *o_buffer = SCMalloc(sizeof(uint32_t) * 64); - void **p_buffer = SCMalloc(sizeof(void *) * 64); - if (d_buffer == NULL || o_buffer == NULL || p_buffer == NULL) { - printf("failure 0\n"); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - return 0; - } - - CudaBufferData *data = CudaBufferRegisterNew(d_buffer, 64, - o_buffer, p_buffer, 64); - if (data == NULL) { - goto end; - } - - slice = CudaBufferGetSlice(data, 3, NULL); - memcpy(slice->buffer + slice->start_offset, - "one", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - slice = CudaBufferGetSlice(data, 3, NULL); - memcpy(slice->buffer + slice->start_offset, - "two", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - if (data->d_buffer_write != 16 || data->d_buffer_read != 0 || - data->op_buffer_write != 2 || data->op_buffer_read != 0 || - data->no_of_items != 2) { - printf("failure 1\n"); - goto end; - } - - slice = CudaBufferGetSlice(data, 5, NULL); - memcpy(slice->buffer + slice->start_offset, - "three", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - slice = CudaBufferGetSlice(data, 4, NULL); - memcpy(slice->buffer + slice->start_offset, - "four", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - slice = CudaBufferGetSlice(data, 4, NULL); - memcpy(slice->buffer + slice->start_offset, - "five", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - if (data->d_buffer_write != 40 || data->d_buffer_read != 0 || - data->op_buffer_write != 5 || data->op_buffer_read != 0 || - data->no_of_items != 5) { - printf("failure 2\n"); - goto end; - } - - slice = CudaBufferGetSlice(data, 3, NULL); - memcpy(slice->buffer + slice->start_offset, - "six", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - slice = CudaBufferGetSlice(data, 5, NULL); - memcpy(slice->buffer + slice->start_offset, - "seven", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - if (memcmp(data->d_buffer, "one", 3) != 0 || - memcmp(data->d_buffer + 8, "two", 3) != 0 || - memcmp(data->d_buffer + 16, "three", 5) != 0 || - memcmp(data->d_buffer + 24, "four", 4) != 0 || - memcmp(data->d_buffer + 32, "five", 4) != 0 || - memcmp(data->d_buffer + 40, "six", 3) != 0 || - memcmp(data->d_buffer + 48, "seven", 5) != 0) { - printf("failure 3\n"); - goto end; - } - - if (data->d_buffer_write != 56 || data->d_buffer_read != 0 || - data->op_buffer_write != 7 || data->op_buffer_read != 0 || - data->no_of_items != 7) { - printf("failure 4\n"); - goto end; - } - - /* culling */ - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->d_buffer_write != 56 || data->d_buffer_read != 0 || - data->op_buffer_write != 7 || data->op_buffer_read != 0 || - data->no_of_items != 7) { - printf("failure 5\n"); - goto end; - } - CudaBufferReportCulledConsumption(data, &culled_info); - if (data->d_buffer_write != 56 || data->d_buffer_read != 56 || - data->op_buffer_write != 7 || data->op_buffer_read != 7 || - data->no_of_items != 7) { - printf("failure 6\n"); - goto end; - } - - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->d_buffer_write != 0 || data->d_buffer_read != 56 || - data->op_buffer_write != 7 || data->op_buffer_read != 7 || - data->no_of_items != 7) { - printf("failure 7\n"); - goto end; - } - CudaBufferReportCulledConsumption(data, &culled_info); - - if (data->d_buffer_write != 0 || data->d_buffer_read != 0 || - data->op_buffer_write != 7 || data->op_buffer_read != 7 || - data->no_of_items != 7) { - printf("failure 8\n"); - goto end; - } - - slice = CudaBufferGetSlice(data, 5, NULL); - memcpy(slice->buffer + slice->start_offset, - "eight", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - slice = CudaBufferGetSlice(data, 4, NULL); - memcpy(slice->buffer + slice->start_offset, - "nine", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - slice = CudaBufferGetSlice(data, 3, NULL); - memcpy(slice->buffer + slice->start_offset, - "ten", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - slice = CudaBufferGetSlice(data, 6, NULL); - memcpy(slice->buffer + slice->start_offset, - "eleven", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - slice = CudaBufferGetSlice(data, 6, NULL); - memcpy(slice->buffer + slice->start_offset, - "twelve", slice->end_offset - slice->start_offset + 1); - SC_ATOMIC_SET(slice->done, 1); - - if (data->d_buffer_write != 40 || data->d_buffer_read != 0 || - data->op_buffer_write != 12 || data->op_buffer_read != 7 || - data->no_of_items != 12) { - printf("failure 9\n"); - goto end; - } - - if (memcmp(data->d_buffer, "eight", 5) != 0 || - memcmp(data->d_buffer + 8, "nine", 4) != 0 || - memcmp(data->d_buffer + 16, "ten", 3) != 0 || - memcmp(data->d_buffer + 24, "eleven", 6) != 0 || - memcmp(data->d_buffer + 32, "twelve", 6) != 0) { - printf("failure 10\n"); - goto end; - } - - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->d_buffer_write != 40 || data->d_buffer_read != 0 || - data->op_buffer_write != 12 || data->op_buffer_read != 7 || - data->no_of_items != 12) { - printf("failure 11\n"); - goto end; - } - CudaBufferReportCulledConsumption(data, &culled_info); - - if (data->d_buffer_write != 40 || data->d_buffer_read != 40 || - data->op_buffer_write != 12 || data->op_buffer_read != 12 || - data->no_of_items != 12) { - printf("failure 12\n"); - goto end; - } - - result = 1; - end: - slice_temp = data->slice_head; - while (slice_temp != NULL) { - SC_ATOMIC_SET(slice_temp->done, 1); - slice_temp = slice_temp->next; - } - CudaBufferCullCompletedSlices(data, &culled_info, UTIL_MPM_CUDA_GPU_TRANSFER_SIZE); - if (data->slice_head != NULL || data->slice_tail != NULL) { - printf("failure 13\n"); - result = 0; - } - - CudaBufferDeRegister(data); - SCFree(d_buffer); - SCFree(o_buffer); - SCFree(p_buffer); - - return result; -} - -#endif /* #ifdef UNITTESTS */ - -void CudaBufferRegisterUnittests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("CudaBufferTest01", CudaBufferTest01, 1); - UtRegisterTest("CudaBufferTest02", CudaBufferTest02, 1); - UtRegisterTest("CudaBufferTest03", CudaBufferTest03, 1); - UtRegisterTest("CudaBufferTest04", CudaBufferTest04, 1); - UtRegisterTest("CudaBufferTest05", CudaBufferTest05, 1); - UtRegisterTest("CudaBufferTest06", CudaBufferTest06, 1); -#endif - - return; -} - -#endif /* __SC_CUDA_SUPPORT__ */ diff --git a/framework/src/suricata/src/util-cuda-buffer.h b/framework/src/suricata/src/util-cuda-buffer.h deleted file mode 100644 index ab494e67..00000000 --- a/framework/src/suricata/src/util-cuda-buffer.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file API to allow buffering of data. - * - * Introduced with cuda as the primary objective. Allows multiple - * threads to simultaneously access a single buffer and write to it. - * - * Current version allows only serial reads from the buffer. - * When the need arises, the API will be updated to allow multiple - * non-sequential reads. - * - * \author Anoop Saldanha - */ - -#ifdef __SC_CUDA_SUPPORT__ - -#ifndef __UTIL_CUDA_BUFFER_H__ -#define __UTIL_CUDA_BUFFER_H__ - -#include "util-atomic.h" - -/** - * \brief Used by consumers to retrieve the data buffered. - */ -typedef struct CudaBufferCulledInfo_ { - uint32_t no_of_items; - - uint32_t d_buffer_start_offset; - uint32_t d_buffer_len; - - /* we use no_of_items to determine the no of items here */ - uint32_t op_buffer_start_offset; - - uint8_t d_buffer_reset; - uint8_t op_buffer_reset; -} CudaBufferCulledInfo; - -/** - * /brief A slice which contains details on where to buffer data by a - * writer. - */ -typedef struct CudaBufferSlice_ { - uint32_t start_offset; - uint32_t end_offset; - uint8_t *buffer; - SC_ATOMIC_DECLARE(uint8_t, done); - - struct CudaBufferSlice_ *next; -} CudaBufferSlice; - -typedef struct CudaBufferData_ { - /* the data buffer */ - uint8_t *d_buffer; - uint32_t d_buffer_len; - uint32_t d_buffer_write; - uint32_t d_buffer_read; - - /* debug only. Can be removed */ - uint32_t no_of_items; - - /* these 2 buffers below - o_buffer and p_buffer should be - * used/updated in tandem - * p_buffer is the ptr buffer that points to a data instance that - * represents it's corresponding data stored in d_buffer. - * o_buffer is the corresponding entry to the one in p_buffer, which - * holds the offset to the corresponding entry in d_buffer. */ - uint32_t *o_buffer; - void **p_buffer; - uint32_t op_buffer_len; - uint32_t op_buffer_write; - uint32_t op_buffer_read; - - /* slice lists used by writers */ - CudaBufferSlice *slice_head; - CudaBufferSlice *slice_tail; - - /* mutex used by the entire struct */ - SCMutex m; -} CudaBufferData; - -void CudaBufferReportCulledConsumption(CudaBufferData *cb_data, - CudaBufferCulledInfo *culled_info); -void CudaBufferCullCompletedSlices(CudaBufferData *cb_data, - CudaBufferCulledInfo *culled_info, uint32_t size_limit); -CudaBufferSlice *CudaBufferGetSlice(CudaBufferData *data, uint32_t len, void *p); -void CudaBufferDeRegister(CudaBufferData *cb_data); -CudaBufferData *CudaBufferRegisterNew(uint8_t *d_buffer, uint32_t d_buffer_len, - uint32_t *o_buffer, void **p_buffer, - uint32_t op_buffer_no_of_items); -void CudaBufferInit(void); -void CudaBufferRegisterUnittests(void); - -#endif /* __UTIL_CUDA_BUFFER_H__ */ - -#endif /* __SC_CUDA_SUPPORT__ */ diff --git a/framework/src/suricata/src/util-cuda-handlers.c b/framework/src/suricata/src/util-cuda-handlers.c deleted file mode 100644 index a6cbeec9..00000000 --- a/framework/src/suricata/src/util-cuda-handlers.c +++ /dev/null @@ -1,363 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -/* compile in, only if we have a CUDA enabled device on the machine, with the - * toolkit and the driver installed */ -#ifdef __SC_CUDA_SUPPORT__ - -#include "suricata-common.h" - -#include "util-error.h" -#include "util-debug.h" -#include "conf.h" -#include "util-cuda.h" -#include "util-cuda-handlers.h" - -/* file only exists if cuda is enabled */ -#include "cuda-ptxdump.h" - -/************************conf file profile section**********************/ - -typedef struct CudaHandlerConfProfile_ { - char *name; - void *ctx; - void (*Free)(void *); - - struct CudaHandlerConfProfile_ *next; -} CudaHandlerConfProfile; - -static CudaHandlerConfProfile *conf_profiles = NULL; -/* protects above var */ -static SCMutex mutex = SCMUTEX_INITIALIZER; - -void CudaHandlerAddCudaProfileFromConf(const char *name, - void *(*Callback)(ConfNode *node), - void (*Free)(void *)) -{ - /* we don't do data validation */ - SCMutexLock(&mutex); - - CudaHandlerConfProfile *tmp_cp = conf_profiles; - while (tmp_cp != NULL && strcasecmp(name, tmp_cp->name) != 0) - tmp_cp = tmp_cp->next; - - if (tmp_cp != NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "We already have a cuda conf " - "profile by the name \"%s\" registered.", name); - exit(EXIT_FAILURE); - } - - char tmp[200]; - int r = snprintf(tmp, sizeof(tmp), "%s%s", "cuda.", name); - if (r < 0) { - SCLogError(SC_ERR_FATAL, "snprintf failure."); - exit(EXIT_FAILURE); - } else if (r > (int)sizeof(tmp)) { - SCLogError(SC_ERR_FATAL, "buffer not big enough to write param."); - exit(EXIT_FAILURE); - } - void *ctx = Callback(ConfGetNode(tmp)); - if (ctx == NULL) { - SCMutexUnlock(&mutex); - return; - } - - CudaHandlerConfProfile *new_cp = SCMalloc(sizeof(CudaHandlerConfProfile)); - if (unlikely(new_cp == NULL)) - exit(EXIT_FAILURE); - memset(new_cp, 0, sizeof(CudaHandlerConfProfile)); - new_cp->name = SCStrdup(name); - if (new_cp->name == NULL) - exit(EXIT_FAILURE); - new_cp->ctx = ctx; - new_cp->Free = Free; - - if (conf_profiles == NULL) { - conf_profiles = new_cp; - } else { - new_cp->next = conf_profiles; - conf_profiles = new_cp; - } - - SCMutexUnlock(&mutex); - return; -} - -void *CudaHandlerGetCudaProfile(const char *name) -{ - SCMutexLock(&mutex); - - CudaHandlerConfProfile *tmp_cp = conf_profiles; - while (tmp_cp != NULL && strcasecmp(name, tmp_cp->name) != 0) - tmp_cp = tmp_cp->next; - - if (tmp_cp == NULL) { - SCMutexUnlock(&mutex); - return NULL; - } - - SCMutexUnlock(&mutex); - return tmp_cp->ctx; -} - -void CudaHandlerFreeProfiles(void) -{ - SCMutexLock(&mutex); - - CudaHandlerConfProfile *tmp = conf_profiles; - while (tmp != NULL) { - CudaHandlerConfProfile *curr = tmp; - tmp = tmp->next; - SCFree(curr->name); - if (curr->Free != NULL) - curr->Free(curr->ctx); - SCFree(curr); - } - - SCMutexUnlock(&mutex); - return; -} - -/*******************cuda context related data section*******************/ - -/* we use a concept where every device on the gpu has only 1 context. If - * a section in the engine wants to use a device and tries to open a context - * on it, we first check if a context is already created for the device and if - * so we return it. If not we create a new one and update with the entry */ - -static CUcontext *cuda_contexts = NULL; -static int no_of_cuda_contexts = 0; - -typedef struct CudaHandlerModuleData_ { - char *name; - void *data; - - struct CudaHandlerModuleData_ *next; -} CudaHandlerModuleData; - -typedef struct CudaHandlerModule_ { - char *name; - - /* the context used by this module */ - CUcontext context; - /* the device on which the above context was created */ - int device_id; - CudaHandlerModuleData *module_data; - - struct CudaHandlerModule_ *next; -} CudaHandlerModule; - -static CudaHandlerModule *cudahl_modules = NULL; - -CUcontext CudaHandlerModuleGetContext(const char *name, int device_id) -{ - void *ptmp; - SCMutexLock(&mutex); - - CudaHandlerModule *module = cudahl_modules; - while (module != NULL && strcasecmp(module->name, name) != 0) - module = module->next; - if (module != NULL) { - if (module->device_id != device_id) { - SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Module already " - "registered, but the new device_id is different " - "from the already registered device_id."); - exit(EXIT_FAILURE); - } - SCMutexUnlock(&mutex); - return module->context; - } - - CudaHandlerModule *new_module = SCMalloc(sizeof(CudaHandlerModule)); - if (unlikely(new_module == NULL)) - exit(EXIT_FAILURE); - memset(new_module, 0, sizeof(CudaHandlerModule)); - new_module->device_id = device_id; - new_module->name = SCStrdup(name); - if (new_module->name == NULL) - exit(EXIT_FAILURE); - if (cudahl_modules == NULL) { - cudahl_modules = new_module; - } else { - new_module->next = cudahl_modules; - cudahl_modules = new_module; - } - - if (no_of_cuda_contexts <= device_id) { - ptmp = SCRealloc(cuda_contexts, sizeof(CUcontext) * (device_id + 1)); - if (unlikely(ptmp == NULL)) { - SCFree(cuda_contexts); - cuda_contexts = NULL; - exit(EXIT_FAILURE); - } - cuda_contexts = ptmp; - - memset(cuda_contexts + no_of_cuda_contexts, 0, - sizeof(CUcontext) * ((device_id + 1) - no_of_cuda_contexts)); - no_of_cuda_contexts = device_id + 1; - } - - if (cuda_contexts[device_id] == 0) { - SCCudaDevices *devices = SCCudaGetDeviceList(); - if (SCCudaCtxCreate(&cuda_contexts[device_id], CU_CTX_SCHED_BLOCKING_SYNC, - devices->devices[device_id]->device) == -1) { - SCLogDebug("ctxcreate failure."); - exit(EXIT_FAILURE); - } - } - new_module->context = cuda_contexts[device_id]; - - SCMutexUnlock(&mutex); - return cuda_contexts[device_id]; -} - -void CudaHandlerModuleStoreData(const char *module_name, - const char *data_name, void *data_ptr) -{ - SCMutexLock(&mutex); - - CudaHandlerModule *module = cudahl_modules; - while (module != NULL && strcasecmp(module->name, module_name) != 0) - module = module->next; - if (module == NULL) { - SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Trying to retrieve data " - "\"%s\" from module \"%s\" that hasn't been registered " - "yet.", module_name, data_name); - exit(EXIT_FAILURE); - } - - CudaHandlerModuleData *data = module->module_data; - while (data != NULL && (strcasecmp(data_name, data->name) != 0)) { - data = data->next; - } - if (data != NULL) { - SCLogWarning(SC_ERR_CUDA_HANDLER_ERROR, "Data \"%s\" already " - "registered for this module \"%s\".", data_name, - module_name); - SCMutexUnlock(&mutex); - goto end; - } - - CudaHandlerModuleData *new_data = SCMalloc(sizeof(CudaHandlerModuleData)); - if (unlikely(new_data == NULL)) - exit(EXIT_FAILURE); - memset(new_data, 0, sizeof(CudaHandlerModuleData)); - new_data->name = SCStrdup(data_name); - if (new_data->name == NULL) - exit(EXIT_FAILURE); - new_data->data = data_ptr; - - if (module->module_data == NULL) { - module->module_data = new_data; - } else { - new_data->next = module->module_data; - module->module_data = new_data; - } - - SCMutexUnlock(&mutex); - - end: - return; -} - -void *CudaHandlerModuleGetData(const char *module_name, const char *data_name) -{ - SCMutexLock(&mutex); - - CudaHandlerModule *module = cudahl_modules; - while (module != NULL && strcasecmp(module->name, module_name) != 0) - module = module->next; - if (module == NULL) { - SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Trying to retrieve data " - "\"%s\" from module \"%s\" that hasn't been registered " - "yet.", module_name, data_name); - SCMutexUnlock(&mutex); - return NULL; - } - - CudaHandlerModuleData *data = module->module_data; - while (data != NULL && (strcasecmp(data_name, data->name) != 0)) { - data = data->next; - } - if (data == NULL) { - SCLogInfo("Data \"%s\" already registered for this module \"%s\". " - "Returning it.", data_name, module_name); - SCMutexUnlock(&mutex); - return NULL; - } - - SCMutexUnlock(&mutex); - return data->data; -} - -int CudaHandlerGetCudaModule(CUmodule *p_module, const char *ptx_image) -{ -#define CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE 15 - - int i = 0; - - /* select the ptx image based on the compute capability supported by all - * devices (i.e. the lowest) */ - char *image = SCMalloc(strlen(ptx_image) + CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE); - if (unlikely(image == NULL)) { - exit(EXIT_FAILURE); - } - memset(image, 0x00, strlen(ptx_image) + CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE); - - int major = INT_MAX; - int minor = INT_MAX; - SCCudaDevices *devices = SCCudaGetDeviceList(); - for (i = 0; i < devices->count; i++){ - if (devices->devices[i]->major_rev < major){ - major = devices->devices[i]->major_rev; - minor = devices->devices[i]->minor_rev; - } - if (devices->devices[i]->major_rev == major && - devices->devices[i]->minor_rev < minor){ - minor = devices->devices[i]->minor_rev; - } - } - snprintf(image, - strlen(ptx_image) + CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE, - "%s_sm_%u%u", - ptx_image, major, minor); - - /* we don't have a cuda module associated with this module. Create a - * cuda module, update the module with this cuda module reference and - * then return the module refernce back to the calling function using - * the argument */ - SCLogDebug("Loading kernel module: %s\n",image); - if (SCCudaModuleLoadData(p_module, (void *)SCCudaPtxDumpGetModule(image)) == -1) - goto error; - SCFree(image); - - return 0; - error: - SCFree(image); - return -1; - -#undef CUDA_HANDLER_GET_CUDA_MODULE_BUFFER_EXTRA_SPACE -} - - -#endif /* __SC_CUDA_SUPPORT__ */ diff --git a/framework/src/suricata/src/util-cuda-handlers.h b/framework/src/suricata/src/util-cuda-handlers.h deleted file mode 100644 index eee227df..00000000 --- a/framework/src/suricata/src/util-cuda-handlers.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_CUDA_HANDLERS__H__ -#define __UTIL_CUDA_HANDLERS__H__ - -#include "conf.h" -#include "util-cuda.h" - -/************************conf file profile section**********************/ - -void CudaHandlerAddCudaProfileFromConf(const char *name, - void *(*Callback)(ConfNode *node), - void (*Free)(void *)); -void *CudaHandlerGetCudaProfile(const char *name); -void CudaHandlerFreeProfiles(void); - -/*******************cuda context related data section*******************/ - -#define CUDA_HANDLER_MODULE_DATA_TYPE_MEMORY_HOST 0 -#define CUDA_HANDLER_MODULE_DATA_TYPE_MEMORY_DEVICE 1 -#define CUDA_HANDLER_MODULE_DATA_TYPE_CUDA_BUFFER 2 - -CUcontext CudaHandlerModuleGetContext(const char *module_name, int device_id); -void CudaHandlerModuleStoreData(const char *module_name, - const char *data_name, void *data_ptr); -void *CudaHandlerModuleGetData(const char *module_name, const char *data_name); -int CudaHandlerGetCudaModule(CUmodule *p_module, const char *ptx_image); - -#endif /* __UTIL_CUDA_HANDLERS__H__ */ diff --git a/framework/src/suricata/src/util-cuda-vars.c b/framework/src/suricata/src/util-cuda-vars.c deleted file mode 100644 index 624c09f8..00000000 --- a/framework/src/suricata/src/util-cuda-vars.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifdef __SC_CUDA_SUPPORT__ - -#include "suricata.h" -#include "util-mpm.h" -#include "util-cuda-handlers.h" -#include "util-cuda-vars.h" -#include "detect-engine-mpm.h" -#include "util-debug.h" -#include "util-mpm-ac.h" - -static DetectEngineCtx *cuda_de_ctx = NULL; - -void CudaVarsSetDeCtx(DetectEngineCtx *de_ctx) -{ - if (cuda_de_ctx != NULL) { - SCLogError(SC_ERR_FATAL, "CudaVarsSetDeCtx() called more than once. " - "This function should be called only once during the " - "lifetime of the engine."); - exit(EXIT_FAILURE); - } - - cuda_de_ctx = de_ctx; - - return; -} - -int CudaThreadVarsInit(CudaThreadVars *ctv) -{ - if (PatternMatchDefaultMatcher() != MPM_AC_CUDA) - return 0; - - MpmCudaConf *conf = CudaHandlerGetCudaProfile("mpm"); - if (conf == NULL) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error obtaining cuda mpm profile."); - return -1; - } - - ctv->mpm_is_cuda = 1; - ctv->cuda_ac_cb = CudaHandlerModuleGetData(MPM_AC_CUDA_MODULE_NAME, MPM_AC_CUDA_MODULE_CUDA_BUFFER_NAME); - ctv->data_buffer_size_max_limit = conf->data_buffer_size_max_limit; - ctv->data_buffer_size_min_limit = conf->data_buffer_size_min_limit; - ctv->mpm_proto_tcp_ctx_ts = MpmFactoryGetMpmCtxForProfile(cuda_de_ctx, cuda_de_ctx->sgh_mpm_context_proto_tcp_packet, 0); - ctv->mpm_proto_tcp_ctx_tc = MpmFactoryGetMpmCtxForProfile(cuda_de_ctx, cuda_de_ctx->sgh_mpm_context_proto_tcp_packet, 1); - ctv->mpm_proto_udp_ctx_ts = MpmFactoryGetMpmCtxForProfile(cuda_de_ctx, cuda_de_ctx->sgh_mpm_context_proto_udp_packet, 0); - ctv->mpm_proto_udp_ctx_tc = MpmFactoryGetMpmCtxForProfile(cuda_de_ctx, cuda_de_ctx->sgh_mpm_context_proto_udp_packet, 1); - ctv->mpm_proto_other_ctx = MpmFactoryGetMpmCtxForProfile(cuda_de_ctx, cuda_de_ctx->sgh_mpm_context_proto_other_packet, 0); - - return 0; -} - -#endif diff --git a/framework/src/suricata/src/util-cuda-vars.h b/framework/src/suricata/src/util-cuda-vars.h deleted file mode 100644 index 9c24a915..00000000 --- a/framework/src/suricata/src/util-cuda-vars.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifdef __SC_CUDA_SUPPORT__ - -#ifndef __UTIL_CUDA_VARS__H__ -#define __UTIL_CUDA_VARS__H__ - -#include "util-cuda-buffer.h" -#include "util-mpm.h" -#include "threads.h" - -typedef struct CudaThreadVars_ { - /* cb - CudaBuffer */ - CudaBufferData *cuda_ac_cb; - - MpmCtx *mpm_proto_other_ctx; - - MpmCtx *mpm_proto_tcp_ctx_ts; - MpmCtx *mpm_proto_udp_ctx_ts; - - MpmCtx *mpm_proto_tcp_ctx_tc; - MpmCtx *mpm_proto_udp_ctx_tc; - - uint16_t data_buffer_size_max_limit; - uint16_t data_buffer_size_min_limit; - - uint8_t mpm_is_cuda; -} CudaThreadVars; - -typedef struct CudaPacketVars_ { - uint8_t cuda_mpm_enabled; - uint8_t cuda_done; - uint16_t cuda_gpu_matches; - SCMutex cuda_mutex; - SCCondT cuda_cond; - uint32_t cuda_results[(UTIL_MPM_CUDA_DATA_BUFFER_SIZE_MAX_LIMIT_DEFAULT * 2) + 1]; -} CudaPacketVars; - -void CudaVarsSetDeCtx(struct DetectEngineCtx_ *de_ctx); -int CudaThreadVarsInit(CudaThreadVars *ctv); - -#endif /* __UTIL_CUDA_VARS__H__ */ - -#endif /* __SC_CUDA_SUPPORT__ */ diff --git a/framework/src/suricata/src/util-cuda.c b/framework/src/suricata/src/util-cuda.c deleted file mode 100644 index 3ada56b2..00000000 --- a/framework/src/suricata/src/util-cuda.c +++ /dev/null @@ -1,5455 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * NVIDIA CUDA utility functions - last referenced Cuda Toolkit 4.2 - */ - -/* compile in, only if we have a CUDA enabled device on the machine, with the - * toolkit and the driver installed */ -#ifdef __SC_CUDA_SUPPORT__ - -#include -#include "util-cuda.h" -#include "suricata-common.h" - -#include "util-error.h" -#include "util-debug.h" -#include "util-unittest.h" - -#define CASE_CODE(E) case E: return #E - -typedef enum SCCudaAPIS_ { - /* init api */ - SC_CUDA_CU_INIT, - - /* version management api */ - SC_CUDA_CU_DRIVER_GET_VERSION, - - /* device management api */ - SC_CUDA_CU_DEVICE_COMPUTE_CAPABILITY, - SC_CUDA_CU_DEVICE_GET, - SC_CUDA_CU_DEVICE_GET_ATTRIBUTE, - SC_CUDA_CU_DEVICE_GET_COUNT, - SC_CUDA_CU_DEVICE_GET_NAME, - SC_CUDA_CU_DEVICE_GET_PROPERTIES, - SC_CUDA_CU_DEVICE_TOTAL_MEM, - - /* context management api */ - SC_CUDA_CU_CTX_CREATE, - SC_CUDA_CU_CTX_DESTROY, - SC_CUDA_CU_CTX_GET_API_VERSION, - SC_CUDA_CU_CTX_GET_CACHE_CONFIG, - SC_CUDA_CU_CTX_GET_CURRENT, - SC_CUDA_CU_CTX_GET_DEVICE, - SC_CUDA_CU_CTX_GET_LIMIT, - SC_CUDA_CU_CTX_POP_CURRENT, - SC_CUDA_CU_CTX_PUSH_CURRENT, - SC_CUDA_CU_CTX_SET_CACHE_CONFIG, - SC_CUDA_CU_CTX_SET_CURRENT, - SC_CUDA_CU_CTX_SET_LIMIT, - SC_CUDA_CU_CTX_SYNCHRONIZE, - SC_CUDA_CU_CTX_ATTACH, - SC_CUDA_CU_CTX_DETACH, - - /* module management api */ - SC_CUDA_CU_MODULE_GET_FUNCTION, - SC_CUDA_CU_MODULE_GET_GLOBAL, - SC_CUDA_CU_MODULE_GET_SURF_REF, - SC_CUDA_CU_MODULE_GET_TEX_REF, - SC_CUDA_CU_MODULE_LOAD, - SC_CUDA_CU_MODULE_LOAD_DATA, - SC_CUDA_CU_MODULE_LOAD_DATA_EX, - SC_CUDA_CU_MODULE_LOAD_FAT_BINARY, - SC_CUDA_CU_MODULE_UNLOAD, - - /* memory management api */ - SC_CUDA_CU_ARRAY_3D_CREATE, - SC_CUDA_CU_ARRAY_3D_GET_DESCRIPTOR, - SC_CUDA_CU_ARRAY_CREATE, - SC_CUDA_CU_ARRAY_DESTROY, - SC_CUDA_CU_ARRAY_GET_DESCRIPTOR, - SC_CUDA_CU_DEVICE_GET_BY_PCI_BUS_ID, - SC_CUDA_CU_DEVICE_GET_PCI_BUS_ID, - SC_CUDA_CU_IPC_CLOSE_MEM_HANDLE, - SC_CUDA_CU_IPC_GET_EVENT_HANDLE, - SC_CUDA_CU_IPC_GET_MEM_HANDLE, - SC_CUDA_CU_IPC_OPEN_EVENT_HANDLE, - SC_CUDA_CU_IPC_OPEN_MEM_HANDLE, - SC_CUDA_CU_MEM_ALLOC, - SC_CUDA_CU_MEM_ALLOC_HOST, - SC_CUDA_CU_MEM_ALLOC_PITCH, - SC_CUDA_CU_MEMCPY, - SC_CUDA_CU_MEMCPY_2D, - SC_CUDA_CU_MEMCPY_2D_ASYNC, - SC_CUDA_CU_MEMCPY_2D_UNALIGNED, - SC_CUDA_CU_MEMCPY_3D, - SC_CUDA_CU_MEMCPY_3D_ASYNC, - SC_CUDA_CU_MEMCPY_3D_PEER, - SC_CUDA_CU_MEMCPY_3D_PEER_ASYNC, - SC_CUDA_CU_MEMCPY_ASYNC, - SC_CUDA_CU_MEMCPY_A_TO_A, - SC_CUDA_CU_MEMCPY_A_TO_D, - SC_CUDA_CU_MEMCPY_A_TO_H, - SC_CUDA_CU_MEMCPY_A_TO_H_ASYNC, - SC_CUDA_CU_MEMCPY_D_TO_A, - SC_CUDA_CU_MEMCPY_D_TO_D, - SC_CUDA_CU_MEMCPY_D_TO_D_ASYNC, - SC_CUDA_CU_MEMCPY_D_TO_H, - SC_CUDA_CU_MEMCPY_D_TO_H_ASYNC, - SC_CUDA_CU_MEMCPY_H_TO_A, - SC_CUDA_CU_MEMCPY_H_TO_A_ASYNC, - SC_CUDA_CU_MEMCPY_H_TO_D, - SC_CUDA_CU_MEMCPY_H_TO_D_ASYNC, - SC_CUDA_CU_MEMCPY_PEER, - SC_CUDA_CU_MEMCPY_PEER_ASYNC, - SC_CUDA_CU_MEM_FREE, - SC_CUDA_CU_MEM_FREE_HOST, - SC_CUDA_CU_MEM_GET_ADDRESS_RANGE, - SC_CUDA_CU_MEM_GET_INFO, - SC_CUDA_CU_MEM_HOST_ALLOC, - SC_CUDA_CU_MEM_HOST_GET_DEVICE_POINTER, - SC_CUDA_CU_MEM_HOST_GET_FLAGS, - SC_CUDA_CU_MEM_HOST_REGISTER, - SC_CUDA_CU_MEM_HOST_UNREGISTER, - SC_CUDA_CU_MEMSET_D16, - SC_CUDA_CU_MEMSET_D16_ASYNC, - SC_CUDA_CU_MEMSET_D2_D16, - SC_CUDA_CU_MEMSET_D2_D16_ASYNC, - SC_CUDA_CU_MEMSET_D2_D32, - SC_CUDA_CU_MEMSET_D2_D32_ASYNC, - SC_CUDA_CU_MEMSET_D2_D8, - SC_CUDA_CU_MEMSET_D2_D8_ASYNC, - SC_CUDA_CU_MEMSET_D32, - SC_CUDA_CU_MEMSET_D32_ASYNC, - SC_CUDA_CU_MEMSET_D8, - SC_CUDA_CU_MEMSET_D8_ASYNC, - - /* unified addresssing */ - SC_CUDA_CU_POINTER_GET_ATTRIBUTE, - - /* stream management api */ - SC_CUDA_CU_STREAM_CREATE, - SC_CUDA_CU_STREAM_DESTROY, - SC_CUDA_CU_STREAM_QUERY, - SC_CUDA_CU_STREAM_SYNCHRONIZE, - SC_CUDA_CU_STREAM_WAIT_EVENT, - - /* event management api */ - SC_CUDA_CU_EVENT_CREATE, - SC_CUDA_CU_EVENT_DESTROY, - SC_CUDA_CU_EVENT_ELAPSED_TIME, - SC_CUDA_CU_EVENT_QUERY, - SC_CUDA_CU_EVENT_RECORD, - SC_CUDA_CU_EVENT_SYNCHRONIZE, - - /* execution control api */ - SC_CUDA_CU_FUNC_GET_ATTRIBUTE, - SC_CUDA_CU_FUNC_SET_CACHE_CONFIG, - SC_CUDA_CU_LAUNCH_KERNEL, - SC_CUDA_CU_FUNC_SET_BLOCK_SHAPE, - SC_CUDA_CU_FUNC_SET_SHARED_SIZE, - SC_CUDA_CU_LAUNCH, - SC_CUDA_CU_LAUNCH_GRID, - SC_CUDA_CU_LAUNCH_GRID_ASYNC, - SC_CUDA_CU_PARAM_SETF, - SC_CUDA_CU_PARAM_SETI, - SC_CUDA_CU_PARAM_SET_SIZE, - SC_CUDA_CU_PARAM_SET_TEX_REF, - SC_CUDA_CU_PARAM_SETV, - - /* texture reference api */ - SC_CUDA_CU_TEX_REF_CREATE, - SC_CUDA_CU_TEX_REF_DESTROY, - SC_CUDA_CU_TEX_REF_GET_ADDRESS, - SC_CUDA_CU_TEX_REF_GET_ADDRESS_MODE, - SC_CUDA_CU_TEX_REF_GET_ARRAY, - SC_CUDA_CU_TEX_REF_GET_FILTER_MODE, - SC_CUDA_CU_TEX_REF_GET_FLAGS, - SC_CUDA_CU_TEX_REF_GET_FORMAT, - SC_CUDA_CU_TEX_REF_SET_ADDRESS, - SC_CUDA_CU_TEX_REF_SET_ADDRESS_2D, - SC_CUDA_CU_TEX_REF_SET_ADDRESS_MODE, - SC_CUDA_CU_TEX_REF_SET_ARRAY, - SC_CUDA_CU_TEX_REF_SET_FILTER_MODE, - SC_CUDA_CU_TEX_REF_SET_FLAGS, - SC_CUDA_CU_TEX_REF_SET_FORMAT, -} SCCudaAPIS; - -SCEnumCharMap sc_cuda_api_names_string_map[] = { - /* init api */ - { "cuInit", SC_CUDA_CU_INIT }, - - /* version management api */ - { "cuDriverGetVersion", SC_CUDA_CU_DRIVER_GET_VERSION }, - - /* device management api */ - { "cuDeviceComputeCapability", SC_CUDA_CU_DEVICE_COMPUTE_CAPABILITY }, - { "cuDeviceGet", SC_CUDA_CU_DEVICE_GET }, - { "cuDeviceGetAttribute", SC_CUDA_CU_DEVICE_GET_ATTRIBUTE }, - { "cuDeviceGetCount", SC_CUDA_CU_DEVICE_GET_COUNT }, - { "cuDeviceGetName", SC_CUDA_CU_DEVICE_GET_NAME }, - { "cuDeviceGetProperties", SC_CUDA_CU_DEVICE_GET_PROPERTIES }, - { "cuDeviceTotalMem", SC_CUDA_CU_DEVICE_TOTAL_MEM }, - - /* context management api */ - { "cuCtxCreate", SC_CUDA_CU_CTX_CREATE }, - { "cuCtxDestroy", SC_CUDA_CU_CTX_DESTROY }, - { "cuCtxGetApiVersion", SC_CUDA_CU_CTX_GET_API_VERSION }, - { "cuCtxGetCacheConfig", SC_CUDA_CU_CTX_GET_CACHE_CONFIG }, - { "cuCtxGetCurrent", SC_CUDA_CU_CTX_GET_CURRENT }, - { "cuCtxGetDevice", SC_CUDA_CU_CTX_GET_DEVICE }, - { "cuCtxGetLimit", SC_CUDA_CU_CTX_GET_LIMIT }, - { "cuCtxPopCurrent", SC_CUDA_CU_CTX_POP_CURRENT }, - { "cuCtxPushCurrent", SC_CUDA_CU_CTX_PUSH_CURRENT }, - { "cuCtxSetCacheConfig", SC_CUDA_CU_CTX_SET_CACHE_CONFIG }, - { "cuCtxSetCurrent", SC_CUDA_CU_CTX_SET_CURRENT }, - { "cuCtxSetLimit", SC_CUDA_CU_CTX_SET_LIMIT }, - { "cuCtxSynchronize", SC_CUDA_CU_CTX_SYNCHRONIZE }, - { "cuCtxAttach", SC_CUDA_CU_CTX_ATTACH }, - { "cuCtxDetach", SC_CUDA_CU_CTX_DETACH }, - - /* module management api */ - { "cuModuleGetFunction", SC_CUDA_CU_MODULE_GET_FUNCTION }, - { "cuModuleGetGlobal", SC_CUDA_CU_MODULE_GET_GLOBAL }, - { "cuModuleGetSurfRef", SC_CUDA_CU_MODULE_GET_SURF_REF }, - { "cuModuleGetTexRef", SC_CUDA_CU_MODULE_GET_TEX_REF }, - { "cuModuleLoad", SC_CUDA_CU_MODULE_LOAD }, - { "cuModuleLoadData", SC_CUDA_CU_MODULE_LOAD_DATA }, - { "cuModuleLoadDataEx", SC_CUDA_CU_MODULE_LOAD_DATA_EX }, - { "cuModuleLoadFatBinary", SC_CUDA_CU_MODULE_LOAD_FAT_BINARY }, - { "cuModuleUnload", SC_CUDA_CU_MODULE_UNLOAD }, - - /* memory management api */ - { "cuArray3DCreate", SC_CUDA_CU_ARRAY_3D_CREATE }, - { "cuArray3DGetDescriptor", SC_CUDA_CU_ARRAY_3D_GET_DESCRIPTOR }, - { "cuArrayCreate", SC_CUDA_CU_ARRAY_CREATE }, - { "cuArrayDestroy", SC_CUDA_CU_ARRAY_DESTROY }, - { "cuArrayGetDescriptor", SC_CUDA_CU_ARRAY_GET_DESCRIPTOR }, - { "cuDeviceGetByPCIBusId", SC_CUDA_CU_DEVICE_GET_BY_PCI_BUS_ID }, - { "cuDeviceGetPCIBusId", SC_CUDA_CU_DEVICE_GET_PCI_BUS_ID }, - { "cuIpcCloseMemHandle", SC_CUDA_CU_IPC_CLOSE_MEM_HANDLE }, - { "cuIpcGetEventHandle", SC_CUDA_CU_IPC_GET_MEM_HANDLE }, - { "cuIpcGetMemHandle", SC_CUDA_CU_IPC_GET_MEM_HANDLE }, - { "cuIpcOpenEventHandle", SC_CUDA_CU_IPC_OPEN_EVENT_HANDLE }, - { "cuIpcOpenMemHandle", SC_CUDA_CU_IPC_OPEN_MEM_HANDLE }, - { "cuMemAlloc", SC_CUDA_CU_MEM_ALLOC }, - { "cuMemAllocHost", SC_CUDA_CU_MEM_ALLOC_HOST }, - { "cuMemAllocPitch", SC_CUDA_CU_MEM_ALLOC_PITCH }, - { "cuMemcpy", SC_CUDA_CU_MEMCPY }, - { "cuMemcpy2D", SC_CUDA_CU_MEMCPY_2D }, - { "cuMemcpy2DAsync", SC_CUDA_CU_MEMCPY_2D_ASYNC }, - { "cuMemcpy2DUnaligned", SC_CUDA_CU_MEMCPY_2D_UNALIGNED }, - { "cuMemcpy3D", SC_CUDA_CU_MEMCPY_3D }, - { "cuMemcpy3DAsync", SC_CUDA_CU_MEMCPY_3D_ASYNC }, - { "cuMemcpy3DPeer", SC_CUDA_CU_MEMCPY_3D_PEER }, - { "cuMemcpy3DPeerAsync", SC_CUDA_CU_MEMCPY_3D_PEER_ASYNC }, - { "cuMemcpyAsync", SC_CUDA_CU_MEMCPY_ASYNC }, - { "cuMemcpyAtoA", SC_CUDA_CU_MEMCPY_A_TO_A }, - { "cuMemcpyAtoD", SC_CUDA_CU_MEMCPY_A_TO_D }, - { "cuMemcpyAtoH", SC_CUDA_CU_MEMCPY_A_TO_H }, - { "cuMemcpyAtoHAsync", SC_CUDA_CU_MEMCPY_A_TO_H_ASYNC }, - { "cuMemcpyDtoA", SC_CUDA_CU_MEMCPY_D_TO_A }, - { "cuMemcpyDtoD", SC_CUDA_CU_MEMCPY_D_TO_D }, - { "cuMemcpyDtoDAsync", SC_CUDA_CU_MEMCPY_D_TO_D_ASYNC }, - { "cuMemcpyDtoH", SC_CUDA_CU_MEMCPY_D_TO_H }, - { "cuMemcpyDtoHAsync", SC_CUDA_CU_MEMCPY_D_TO_H_ASYNC }, - { "cuMemcpyHtoA", SC_CUDA_CU_MEMCPY_H_TO_A }, - { "cuMemcpyHtoAAsync", SC_CUDA_CU_MEMCPY_H_TO_A_ASYNC }, - { "cuMemcpyHtoD", SC_CUDA_CU_MEMCPY_H_TO_D }, - { "cuMemcpyHtoDAsync", SC_CUDA_CU_MEMCPY_H_TO_D_ASYNC }, - { "cuMemcpyPeer", SC_CUDA_CU_MEMCPY_PEER }, - { "cuMemcpyPeerAsync", SC_CUDA_CU_MEMCPY_PEER_ASYNC }, - { "cuMemFree", SC_CUDA_CU_MEM_FREE }, - { "cuMemFreeHost", SC_CUDA_CU_MEM_FREE_HOST }, - { "cuMemGetAddressRange", SC_CUDA_CU_MEM_GET_ADDRESS_RANGE }, - { "cuMemGetInfo", SC_CUDA_CU_MEM_GET_INFO }, - { "cuMemHostAlloc", SC_CUDA_CU_MEM_HOST_ALLOC }, - { "cuMemHostGetDevicePointer", SC_CUDA_CU_MEM_HOST_GET_DEVICE_POINTER }, - { "cuMemHostGetFlags", SC_CUDA_CU_MEM_HOST_GET_FLAGS }, - { "cuMemHostRegister", SC_CUDA_CU_MEM_HOST_REGISTER }, - { "cuMemHostUnregister", SC_CUDA_CU_MEM_HOST_UNREGISTER }, - { "cuMemsetD16", SC_CUDA_CU_MEMSET_D16 }, - { "cuMemsetD16Async", SC_CUDA_CU_MEMSET_D16_ASYNC }, - { "cuMemsetD2D16", SC_CUDA_CU_MEMSET_D2_D16 }, - { "cuMemsetD2D16Async", SC_CUDA_CU_MEMSET_D2_D16_ASYNC }, - { "cuMemsetD2D32", SC_CUDA_CU_MEMSET_D2_D32 }, - { "cuMemsetD2D32Async", SC_CUDA_CU_MEMSET_D2_D32_ASYNC }, - { "cuMemsetD2D8", SC_CUDA_CU_MEMSET_D2_D8 }, - { "cuMemsetD2D8Async", SC_CUDA_CU_MEMSET_D2_D8_ASYNC }, - { "cuMemsetD32", SC_CUDA_CU_MEMSET_D32 }, - { "cuMemsetD32Async", SC_CUDA_CU_MEMSET_D32_ASYNC }, - { "cuMemsetD8", SC_CUDA_CU_MEMSET_D8 }, - { "cuMemsetD8Async", SC_CUDA_CU_MEMSET_D8_ASYNC }, - - /* unified addressing */ - { "cuPointerGetAttribute", SC_CUDA_CU_POINTER_GET_ATTRIBUTE }, - - /* stream management api */ - { "cuStreamCreate", SC_CUDA_CU_STREAM_CREATE }, - { "cuStreamDestroy", SC_CUDA_CU_STREAM_DESTROY }, - { "cuStreamQuery", SC_CUDA_CU_STREAM_QUERY }, - { "cuStreamSynchronize", SC_CUDA_CU_STREAM_SYNCHRONIZE }, - { "cuStreamWaitEvent", SC_CUDA_CU_STREAM_WAIT_EVENT }, - - /* event management api */ - { "cuEventCreate", SC_CUDA_CU_EVENT_CREATE }, - { "cuEventDestroy", SC_CUDA_CU_EVENT_DESTROY }, - { "cuEventElapseTime", SC_CUDA_CU_EVENT_ELAPSED_TIME }, - { "cuEventQuery", SC_CUDA_CU_EVENT_QUERY }, - { "cuEventRecord", SC_CUDA_CU_EVENT_RECORD }, - { "cuEventSynchronize", SC_CUDA_CU_EVENT_SYNCHRONIZE }, - - /* execution control api */ - { "cuFuncGetAttribute", SC_CUDA_CU_FUNC_GET_ATTRIBUTE }, - { "cuFuncSetCacheConfig", SC_CUDA_CU_FUNC_SET_CACHE_CONFIG }, - { "cuLaunchKernel", SC_CUDA_CU_LAUNCH_KERNEL }, - { "cuFuncSetBlockShape", SC_CUDA_CU_FUNC_SET_BLOCK_SHAPE }, - { "cuFuncSetSharedSize", SC_CUDA_CU_FUNC_SET_SHARED_SIZE }, - { "cuLaunch", SC_CUDA_CU_LAUNCH }, - { "cuLaunchGrid", SC_CUDA_CU_LAUNCH_GRID }, - { "cuLaunchGridAsync", SC_CUDA_CU_LAUNCH_GRID_ASYNC }, - { "cuParamSetf", SC_CUDA_CU_PARAM_SETF }, - { "cuParamSeti", SC_CUDA_CU_PARAM_SETI }, - { "cuParamSetSize", SC_CUDA_CU_PARAM_SET_SIZE }, - { "cuSetTexRef", SC_CUDA_CU_PARAM_SET_TEX_REF }, - { "cuSetv", SC_CUDA_CU_PARAM_SETV }, - - /* texture reference api */ - { "cuTexRefCreate", SC_CUDA_CU_TEX_REF_CREATE}, - { "cuTexRefDestroy", SC_CUDA_CU_TEX_REF_DESTROY}, - { "cuTexRefGetAddress", SC_CUDA_CU_TEX_REF_GET_ADDRESS}, - { "cuTexRefGetAddressMode", SC_CUDA_CU_TEX_REF_GET_ADDRESS_MODE}, - { "cuTexRefGetArray", SC_CUDA_CU_TEX_REF_GET_ARRAY}, - { "cuTexRefGetFilterMode", SC_CUDA_CU_TEX_REF_GET_FILTER_MODE}, - { "cuTexRefGetFlags", SC_CUDA_CU_TEX_REF_GET_FLAGS}, - { "cuTexRefGetFormat", SC_CUDA_CU_TEX_REF_GET_FORMAT}, - { "cuTexRefSetAddress", SC_CUDA_CU_TEX_REF_SET_ADDRESS}, - { "cuTexRefSetAddress2D", SC_CUDA_CU_TEX_REF_SET_ADDRESS_2D}, - { "cuTexRefSetAddressMode", SC_CUDA_CU_TEX_REF_SET_ADDRESS_MODE}, - { "cuTexRefSetArray", SC_CUDA_CU_TEX_REF_SET_ARRAY}, - { "cuTexRefSetFilterMode", SC_CUDA_CU_TEX_REF_SET_FILTER_MODE}, - { "cuTexRefSetFlags", SC_CUDA_CU_TEX_REF_SET_FLAGS}, - { "cuTexRefSetFormat", SC_CUDA_CU_TEX_REF_SET_FORMAT}, - - { NULL, -1 }, -}; - -static SCCudaDevices *devices = NULL; - -/*****************************Error_Handling_API*******************************/ - -/** - * \internal - * \brief Maps the error enums from SCCudaAPIS to strings using the preprocessor - * #ENUM_VALUE. This is mainly needed for logging purposes to log the - * error codes. - * - * \param err The error_code for which the string has to be returned. - * - * \retval The string equivalent of the error code. - */ -static const char *SCCudaGetErrorCodeInString(int err) -{ - switch (err) { - CASE_CODE(CUDA_SUCCESS); - CASE_CODE(CUDA_ERROR_INVALID_VALUE); - CASE_CODE(CUDA_ERROR_OUT_OF_MEMORY); - CASE_CODE(CUDA_ERROR_NOT_INITIALIZED); - CASE_CODE(CUDA_ERROR_DEINITIALIZED); - CASE_CODE(CUDA_ERROR_PROFILER_DISABLED); - CASE_CODE(CUDA_ERROR_PROFILER_NOT_INITIALIZED); - CASE_CODE(CUDA_ERROR_PROFILER_ALREADY_STARTED); - CASE_CODE(CUDA_ERROR_PROFILER_ALREADY_STOPPED); - CASE_CODE(CUDA_ERROR_NO_DEVICE); - CASE_CODE(CUDA_ERROR_INVALID_DEVICE); - CASE_CODE(CUDA_ERROR_INVALID_IMAGE); - CASE_CODE(CUDA_ERROR_INVALID_CONTEXT); - /* deprecated error code as of 3.2 */ - CASE_CODE(CUDA_ERROR_CONTEXT_ALREADY_CURRENT); - CASE_CODE(CUDA_ERROR_MAP_FAILED); - CASE_CODE(CUDA_ERROR_UNMAP_FAILED); - CASE_CODE(CUDA_ERROR_ARRAY_IS_MAPPED); - CASE_CODE(CUDA_ERROR_ALREADY_MAPPED); - CASE_CODE(CUDA_ERROR_NO_BINARY_FOR_GPU); - CASE_CODE(CUDA_ERROR_ALREADY_ACQUIRED); - CASE_CODE(CUDA_ERROR_NOT_MAPPED); - CASE_CODE(CUDA_ERROR_NOT_MAPPED_AS_ARRAY); - CASE_CODE(CUDA_ERROR_NOT_MAPPED_AS_POINTER); - CASE_CODE(CUDA_ERROR_ECC_UNCORRECTABLE); - CASE_CODE(CUDA_ERROR_UNSUPPORTED_LIMIT); - CASE_CODE(CUDA_ERROR_CONTEXT_ALREADY_IN_USE); - CASE_CODE(CUDA_ERROR_INVALID_SOURCE); - CASE_CODE(CUDA_ERROR_FILE_NOT_FOUND); - CASE_CODE(CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND); - CASE_CODE(CUDA_ERROR_SHARED_OBJECT_INIT_FAILED); - CASE_CODE(CUDA_ERROR_OPERATING_SYSTEM); - CASE_CODE(CUDA_ERROR_INVALID_HANDLE); - CASE_CODE(CUDA_ERROR_NOT_FOUND); - CASE_CODE(CUDA_ERROR_NOT_READY); - CASE_CODE(CUDA_ERROR_LAUNCH_FAILED); - CASE_CODE(CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES); - CASE_CODE(CUDA_ERROR_LAUNCH_TIMEOUT); - CASE_CODE(CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING); - CASE_CODE(CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED); - CASE_CODE(CUDA_ERROR_PEER_ACCESS_NOT_ENABLED); - CASE_CODE(CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE); - CASE_CODE(CUDA_ERROR_CONTEXT_IS_DESTROYED); - CASE_CODE(CUDA_ERROR_ASSERT); - CASE_CODE(CUDA_ERROR_TOO_MANY_PEERS); - CASE_CODE(CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED); - CASE_CODE(CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED); - CASE_CODE(CUDA_ERROR_UNKNOWN); - default: - return "CUDA_UNKNOWN_ERROR_CODE"; - } -} - -/** - * \internal - * \brief A generic function that handles the return values from the CUDA driver - * API. - * - * \param result The result from the CUDA driver API call. - * \param api_type An enum value SCCudaAPIS corresponing to the API for which the - * result was returned. The enum is needed to map the api type to - * a string for logging purposes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int SCCudaHandleRetValue(CUresult result, SCCudaAPIS api_type) -{ - if (result == CUDA_SUCCESS) { - SCLogDebug("%s executed successfully", - SCMapEnumValueToName(api_type, sc_cuda_api_names_string_map)); - return 0; - } else { - SCLogError(SC_ERR_CUDA_ERROR, "%s failed. Returned errocode - %s", - SCMapEnumValueToName(api_type, sc_cuda_api_names_string_map), - SCCudaGetErrorCodeInString(result)); - return -1; - } -} - -/*****************************Cuda_Initialization_API**************************/ - -/** - * \internal - * \brief Inits the cuda driver API. - * - * \param flags Currently should be 0. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaInit(unsigned int flags) -{ - CUresult result = cuInit(flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_INIT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/*****************************Version_Management_API***************************/ - -/** - * \brief Returns in *driver_version the version number of the installed CUDA - * driver. This function automatically returns CUDA_ERROR_INVALID_VALUE - * if the driver_version argument is NULL. - * - * \param driver_version Returns the CUDA driver version. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaDriverGetVersion(int *driver_version) -{ - CUresult result = 0; - - if (driver_version == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "driver_version NULL"); - goto error; - } - - result = cuDriverGetVersion(driver_version); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DRIVER_GET_VERSION) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/*****************************Device_Management_API****************************/ - -/** - * \internal - * \brief Returns the major and the minor revision numbers that define the - * compute capability for the device that is sent as the argument. - * - * \param major Pointer to an integer, that will be updated with the major revision. - * \param minor Pointer to an integer, that will be updated with the minor revision. - * \param dev The device handle. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaDeviceComputeCapability(int *major, int *minor, CUdevice dev) -{ - CUresult result = 0; - - if (major == NULL || minor == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "major is NULL or minor is NULL"); - goto error; - } - - result = cuDeviceComputeCapability(major, minor, dev); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DEVICE_COMPUTE_CAPABILITY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \internal - * \brief Returns a device handle given an ordinal in the range - * [0, cuDeviceGetCount() - 1]. - * - * \param device Pointer to a CUDevice instance that will be updated with the - * device handle. - * \param ordinal An index in the range [0, cuDeviceGetCount() - 1]. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaDeviceGet(CUdevice *device, int ordinal) -{ - CUresult result = 0; - - if (device == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "device NULL"); - goto error; - } - - result = cuDeviceGet(device, ordinal); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DEVICE_GET) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \internal - * \brief Returns the various attributes for the device that is sent as the arg. - * - * The supported attributes are: - * - * CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK: Maximum number of threads - * per block; - * CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X: Maximum x-dimension of a block; - * CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y: Maximum y-dimension of a block; - * CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z: Maximum z-dimension of a block; - * CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X: Maximum x-dimension of a grid; - * CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y: Maximum y-dimension of a grid; - * CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z: Maximum z-dimension of a grid; - * CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK: Maximum amount of - * shared mem-ory available to a thread block in bytes; this amount - * is shared by all thread blocks simultaneously resident on a - * multiprocessor; - * CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY: Memory available on device - * for __constant_-_ variables in a CUDA C kernel in bytes; - * CU_DEVICE_ATTRIBUTE_WARP_SIZE: Warp size in threads; - * CU_DEVICE_ATTRIBUTE_MAX_PITCH: Maximum pitch in bytes allowed by the - * memory copy functions that involve memory regions allocated - * through cuMemAllocPitch(); - * CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK: Maximum number of 32-bit - * registers avail-able to a thread block; this number is shared by - * all thread blocks simultaneously resident on a multiprocessor; - * CU_DEVICE_ATTRIBUTE_CLOCK_RATE: Peak clock frequency in kilohertz; - * CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT: Alignment requirement; texture - * base addresses aligned to textureAlign bytes do not need an offset - * applied to texture fetches; - * CU_DEVICE_ATTRIBUTE_GPU_OVERLAP: 1 if the device can concurrently copy - * memory between host and device while executing a kernel, or 0 if not; - * CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT: Number of multiprocessors on - * the device; - * CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT: 1 if there is a run time limit - * for kernels executed on the device, or 0 if not; - * CU_DEVICE_ATTRIBUTE_INTEGRATED: 1 if the device is integrated with the - * memory subsystem, or 0 if not; - * CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY: 1 if the device can map host - * memory into the CUDA address space, or 0 if not; - * CU_DEVICE_ATTRIBUTE_COMPUTE_MODE: Compute mode that device is currently - * in. Available modes are as follows: - * - CU_COMPUTEMODE_DEFAULT: Default mode - Device is not restricted - * and can have multiple CUDA contexts present at a single time. - * - CU_COMPUTEMODE_EXCLUSIVE: Compute-exclusive mode - Device can have - * only one CUDA con-text present on it at a time. - * - CU_COMPUTEMODE_PROHIBITED: Compute-prohibited mode - Device is - * prohibited from creating new CUDA contexts. - * - * \param pi Pointer to an interger instance that will be updated with the - * attribute value. - * \param attrib Device attribute to query. - * \param dev The device handle. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaDeviceGetAttribute(int *pi, CUdevice_attribute attrib, - CUdevice dev) -{ - CUresult result = 0; - - if (pi == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "prop is NULL"); - goto error; - } - - result = cuDeviceGetAttribute(pi, attrib, dev); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DEVICE_GET_ATTRIBUTE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \internal - * \brief Gets the total no of devices with compute capability greater than or - * equal to 1.0 that are available for execution. - * - * \param count Pointer to an integer that will be updated with the device count. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaDeviceGetCount(int *count) -{ - CUresult result = 0; - - if (count == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "count NULL"); - goto error; - } - - result = cuDeviceGetCount(count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DEVICE_GET_COUNT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \internal - * \brief Returns the device name, given the device handle. - * - * \param name Pointer to a char buffer which will be updated with the device name. - * \param len Length of the above buffer. - * \param dev The device handle. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaDeviceGetName(char *name, int len, CUdevice dev) -{ - CUresult result = 0; - - if (name == NULL || len == 0) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "name is NULL or len is 0"); - goto error; - } - - result = cuDeviceGetName(name, len, dev); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DEVICE_GET_NAME) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \internal - * \brief Returns the properties of the device. The CUdevprop structure is - * defined as - * - * typedef struct CUdevprop_st { - * int maxThreadsPerBlock; - * int maxThreadsDim[3]; - * int maxGridSize[3]; - * int sharedMemPerBlock; - * int totalConstantMemory; - * int SIMDWidth; - * int memPitch; - * int regsPerBlock; - * int clockRate; - * int textureAlign - * } CUdevprop; - * - * \param prop Pointer to a CUdevprop instance that holds the device properties. - * \param dev The device handle. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaDeviceGetProperties(CUdevprop *prop, CUdevice dev) -{ - CUresult result = 0; - - if (prop == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "prop is NULL"); - goto error; - } - - result = cuDeviceGetProperties(prop, dev); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DEVICE_GET_PROPERTIES) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \internal - * \brief Returns the total amount of memory availabe on the device which - * is sent as the argument. - * - * \param bytes Pointer to an unsigned int instance, that will be updated with - * total memory for the device. - * \param dev The device handle. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaDeviceTotalMem(size_t *bytes, CUdevice dev) -{ - CUresult result = 0; - - if (bytes == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "bytes is NULL"); - goto error; - } - - result = cuDeviceTotalMem(bytes, dev); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DEVICE_TOTAL_MEM) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \internal - * \brief Creates and returns a new instance of SCCudaDevice. - * - * \retval device Pointer to the new instance of SCCudaDevice. - */ -static SCCudaDevice *SCCudaAllocSCCudaDevice(void) -{ - SCCudaDevice *device = SCMalloc(sizeof(SCCudaDevice)); - if (unlikely(device == NULL)) - return NULL; - memset(device, 0 , sizeof(SCCudaDevice)); - - return device; -} - -/** - * \internal - * \brief Frees an instance of SCCudaDevice. - * - * \param device Pointer to the an instance of SCCudaDevice to be freed. - */ -static void SCCudaDeAllocSCCudaDevice(SCCudaDevice *device) -{ - SCFree(device); - - return; -} - -/** - * \internal - * \brief Creates and returns a new instance of SCCudaDevices. - * - * \retval devices Pointer to the new instance of SCCudaDevices. - */ -static SCCudaDevices *SCCudaAllocSCCudaDevices(void) -{ - SCCudaDevices *devices = SCMalloc(sizeof(SCCudaDevices)); - if (unlikely(devices == NULL)) - return NULL; - memset(devices, 0 , sizeof(SCCudaDevices)); - - return devices; -} - -/** - * \internal - * \brief Frees an instance of SCCudaDevices. - * - * \param device Pointer to the an instance of SCCudaDevices to be freed. - */ -static void SCCudaDeAllocSCCudaDevices(SCCudaDevices *devices) -{ - int i = 0; - - if (devices == NULL) - return; - - if (devices->devices != NULL) { - for (i = 0; i < devices->count; i++) - SCCudaDeAllocSCCudaDevice(devices->devices[i]); - - SCFree(devices->devices); - } - - SCFree(devices); - - return; -} - -/** - * \brief Retrieves all the devices and all the information corresponding to - * the devices on the CUDA device available on this system and returns - * a SCCudaDevices instances which holds all this information. - * - * \retval devices Pointer to a SCCudaDevices instance that holds information - * for all the CUDA devices on the system. - */ -static SCCudaDevices *SCCudaGetDevices(void) -{ - SCCudaDevices *devices = SCCudaAllocSCCudaDevices(); - int i = 0; - - if (SCCudaDeviceGetCount(&devices->count) == -1) - goto error; - - devices->devices = SCMalloc(devices->count * sizeof(SCCudaDevice *)); - if (devices->devices == NULL) - goto error; - - /* update the device properties */ - for (i = 0; i < devices->count; i++) { - devices->devices[i] = SCCudaAllocSCCudaDevice(); - - if (SCCudaDeviceGet(&devices->devices[i]->device, i) == -1) - goto error; - - if (SCCudaDeviceComputeCapability(&devices->devices[i]->major_rev, - &devices->devices[i]->minor_rev, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetName(devices->devices[i]->name, - SC_CUDA_DEVICE_NAME_MAX_LEN, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceTotalMem(&devices->devices[i]->bytes, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetProperties(&devices->devices[i]->prop, - devices->devices[i]->device) == -1) { - goto error; - } - - /* retrieve the attributes */ - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_threads_per_block, - CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_block_dim_x, - CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_block_dim_y, - CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_block_dim_z, - CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_grid_dim_x, - CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_grid_dim_y, - CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_grid_dim_z, - CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_shared_memory_per_block, - CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_total_constant_memory, - CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_warp_size, - CU_DEVICE_ATTRIBUTE_WARP_SIZE, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_pitch, - CU_DEVICE_ATTRIBUTE_MAX_PITCH, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_max_registers_per_block, - CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_clock_rate, - CU_DEVICE_ATTRIBUTE_CLOCK_RATE, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_texture_alignment, - CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_gpu_overlap, - CU_DEVICE_ATTRIBUTE_GPU_OVERLAP, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_multiprocessor_count, - CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_kernel_exec_timeout, - CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_integrated, - CU_DEVICE_ATTRIBUTE_INTEGRATED, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_can_map_host_memory, - CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, - devices->devices[i]->device) == -1) { - goto error; - } - - if (SCCudaDeviceGetAttribute(&devices->devices[i]->attr_compute_mode, - CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, - devices->devices[i]->device) == -1) { - goto error; - } - } - -#ifdef DEBUG - SCCudaPrintDeviceList(devices); -#endif - - return devices; - - error: - SCCudaDeAllocSCCudaDevices(devices); - return NULL; -} - -/** - * \brief Prints the information for all the devices for this CUDA platform, - * supplied inside the argument. - * - * \param devices Pointer to a SCCudaDevices instance that holds information on - * the devices. - */ -void SCCudaPrintDeviceList(SCCudaDevices *devices) -{ - int i = 0; - - if (devices == NULL) { - SCLogError(SC_ERR_CUDA_ERROR, "CUDA environment not initialized. " - "Please initialized the CUDA environment by calling " - "SCCudaInitCudaEnvironment() before making any calls " - "to the CUDA API."); - return; - } - - SCLogDebug("Printing device info for this CUDA context"); - SCLogDebug("No of devices: %d", devices->count); - - for (i = 0; i < devices->count; i++) { - SCLogDebug("Device ID: %d", devices->devices[i]->device); - SCLogDebug("Device Name: %s", devices->devices[i]->name); - SCLogDebug("Device Major Revision: %d", devices->devices[i]->major_rev); - SCLogDebug("Device Minor Revision: %d", devices->devices[i]->minor_rev); - - /* Cudevprop */ - SCLogDebug("Device Max Threads Per Block: %d", - devices->devices[i]->prop.maxThreadsPerBlock); - SCLogDebug("Device Max Threads Dim: [%d, %d, %d]", - devices->devices[i]->prop.maxThreadsDim[0], - devices->devices[i]->prop.maxThreadsDim[1], - devices->devices[i]->prop.maxThreadsDim[2]); - SCLogDebug("Device Max Grid Size: [%d, %d, %d]", - devices->devices[i]->prop.maxGridSize[0], - devices->devices[i]->prop.maxGridSize[1], - devices->devices[i]->prop.maxGridSize[2]); - SCLogDebug("Device Shared Memory Per Block: %d", - devices->devices[i]->prop.sharedMemPerBlock); - SCLogDebug("Device Total Constant Memory: %d", - devices->devices[i]->prop.totalConstantMemory); - SCLogDebug("Device SIMD Width(Warp Size): %d", - devices->devices[i]->prop.SIMDWidth); - SCLogDebug("Device Maximum Mem Pitch: %d", devices->devices[i]->prop.memPitch); - SCLogDebug("Device Total Registers Available Per Block: %d", - devices->devices[i]->prop.regsPerBlock); - SCLogDebug("Device Clock Frequency: %d", devices->devices[i]->prop.clockRate); - SCLogDebug("Device Texture Alignment Requirement: %d", - devices->devices[i]->prop.textureAlign); - - - /* device attributes */ - SCLogDebug("Device Max Threads Per Block: %d", - devices->devices[i]->attr_max_threads_per_block); - SCLogDebug("Device Max Block Dim X: %d", - devices->devices[i]->attr_max_block_dim_x); - SCLogDebug("Device Max Block Dim Y: %d", - devices->devices[i]->attr_max_block_dim_y); - SCLogDebug("Device Max Block Dim Z: %d", - devices->devices[i]->attr_max_block_dim_z); - SCLogDebug("Device Max Grid Dim X: %d", - devices->devices[i]->attr_max_grid_dim_x); - SCLogDebug("Device Max Grid Dim Y: %d", - devices->devices[i]->attr_max_grid_dim_y); - SCLogDebug("Device Max Grid Dim Z: %d", - devices->devices[i]->attr_max_grid_dim_z); - SCLogDebug("Device Max Shared Memory Per Block: %d", - devices->devices[i]->attr_max_shared_memory_per_block); - SCLogDebug("Device Total Constant Memory: %d", - devices->devices[i]->attr_total_constant_memory); - SCLogDebug("Device Warp Size: %d", devices->devices[i]->attr_warp_size); - SCLogDebug("Device Max Pitch: %d", devices->devices[i]->attr_max_pitch); - SCLogDebug("Device Max Registers Per Block: %d", - devices->devices[i]->attr_max_registers_per_block); - SCLogDebug("Device Clock Rate: %d", devices->devices[i]->attr_clock_rate); - SCLogDebug("Device Texture Alignement: %d", - devices->devices[i]->attr_texture_alignment); - SCLogDebug("Device GPU Overlap: %s", - (devices->devices[i]->attr_gpu_overlap == 1) ? "Yes": "No"); - SCLogDebug("Device Multiprocessor Count: %d", - devices->devices[i]->attr_multiprocessor_count); - SCLogDebug("Device Kernel Exec Timeout: %s", - (devices->devices[i]->attr_kernel_exec_timeout) ? "Yes": "No"); - SCLogDebug("Device Integrated With Memory Subsystem: %s", - (devices->devices[i]->attr_integrated) ? "Yes": "No"); - SCLogDebug("Device Can Map Host Memory: %s", - (devices->devices[i]->attr_can_map_host_memory) ? "Yes": "No"); - if (devices->devices[i]->attr_compute_mode == CU_COMPUTEMODE_DEFAULT) - SCLogDebug("Device Compute Mode: CU_COMPUTEMODE_DEFAULT"); - else if (devices->devices[i]->attr_compute_mode == CU_COMPUTEMODE_EXCLUSIVE) - SCLogDebug("Device Compute Mode: CU_COMPUTEMODE_EXCLUSIVE"); - else if (devices->devices[i]->attr_compute_mode == CU_COMPUTEMODE_PROHIBITED) - SCLogDebug("Device Compute Mode: CU_COMPUTEMODE_PROHIBITED"); - } - - return; -} - -/** - * \brief Prints some basic information for the default device(the first devie) - * we will be using on this cuda platform for use by our engine. This - * function is basically to be used to print some minimal information to - * the user at engine startup. - * - * \param devices Pointer to a SCCudaDevices instance that holds information on - * the devices. - */ -void SCCudaPrintBasicDeviceInfo(SCCudaDevices *devices) -{ - int i = 0; - - if (devices == NULL) { - SCLogError(SC_ERR_CUDA_ERROR, "CUDA environment not initialized. " - "Please initialized the CUDA environment by calling " - "SCCudaInitCudaEnvironment() before making any calls " - "to the CUDA API."); - return; - } - - for (i = 0; i < devices->count; i++) { - SCLogInfo("GPU Device %d: %s, %d Multiprocessors, %dMHz, CUDA Compute " - "Capability %d.%d", i + 1, - devices->devices[i]->name, - devices->devices[i]->attr_multiprocessor_count, - devices->devices[i]->attr_clock_rate/1000, - devices->devices[i]->major_rev, - devices->devices[i]->minor_rev); - } - - return; -} - -/** - * \brief Gets the device list, for the CUDA platform environment initialized by - * the engine. - * - * \retval devices Pointer to the CUDA device list on success; NULL on failure. - */ -SCCudaDevices *SCCudaGetDeviceList(void) -{ - if (devices == NULL) { - SCLogError(SC_ERR_CUDA_ERROR, "CUDA environment not initialized. " - "Please initialized the CUDA environment by calling " - "SCCudaInitCudaEnvironment() before making any calls " - "to the CUDA API."); - return NULL; - } - - return devices; -} - -/*****************************Context_Management_API***************************/ - -/** - * \brief Creates a new CUDA context and associates it with the calling thread. - * The flags parameter is described below. The context is created with - * a usage count of 1 and the caller of cuCtxCreate() must call - * cuCtxDestroy() or cuCtxDetach() when done using the context. If a - * context is already current to the thread, it is supplanted by the - * newly created context and may be restored by a subsequent call to - * cuCtxPopCurrent(). The two LSBs of the flags parameter can be used - * to control how the OS thread, which owns the CUDA context at the - * time of an API call, interacts with the OS scheduler when waiting for - * results from the GPU. - * - * - CU_CTX_SCHED_AUTO: The default value if the flags parameter is zero, - * uses a heuristic based on the number of active CUDA contexts in - * the process C and the number of logical processors in the system - * P. If C > P, then CUDA will yield to other OS threads when - * waiting for the GPU, otherwise CUDA will not yield while waiting - * for results and actively spin on the processor. - * - CU_CTX_SCHED_SPIN: Instruct CUDA to actively spin when waiting for - * results from the GPU. This can de-crease latency when waiting for - * the GPU, but may lower the performance of CPU threads if they are - * performing work in parallel with the CUDA thread. - * - CU_CTX_SCHED_YIELD: Instruct CUDA to yield its thread when waiting - * for results from the GPU. This can increase latency when waiting - * for the GPU, but can increase the performance of CPU threads - * performing work in parallel with the GPU. - * - CU_CTX_BLOCKING_SYNC: Instruct CUDA to block the CPU thread on a - * synchronization primitive when waiting for the GPU to finish work. - * - CU_CTX_MAP_HOST: Instruct CUDA to support mapped pinned allocations. - * This flag must be set in order to allocate pinned host memory - * that is accessible to the GPU. - * - * Note to Linux users: - * Context creation will fail with CUDA_ERROR_UNKNOWN if the compute mode - * of the device is CU_COMPUTEMODE_PROHIBITED. Similarly, context creation - * will also fail with CUDA_ERROR_UNKNOWN if the compute mode for the - * device is set to CU_COMPUTEMODE_EXCLUSIVE and there is already an - * active context on the device. The function cuDeviceGetAttribute() can - * be used with CU_DEVICE_ATTRIBUTE_COMPUTE_MODE to determine the compute - * mode of the device. The nvidia-smi tool can be used to set the compute - * mode for devices. Documentation for nvidia-smi can be obtained by - * passing a -h option to it. - * - * \param pctx Returned context handle of the current context. - * \param flags Context creation flags. - * \param dev Device to create context on. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaCtxCreate(CUcontext *pctx, unsigned int flags, CUdevice dev) -{ - CUresult result = 0; - - if (pctx == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "pctx NULL"); - goto error; - } - - result = cuCtxCreate(pctx, flags, dev); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_CREATE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Destroys the CUDA context specified by ctx. If the context usage count - * is not equal to 1, or the context is current to any CPU thread other - * than the current one, this function fails. Floating contexts (detached - * from a CPU thread via cuCtxPopCurrent()) may be destroyed by this - * function. - * - * \param ctx Context to destroy. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaCtxDestroy(CUcontext ctx) -{ - CUresult result = 0; - - result = cuCtxDestroy(ctx); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_DESTROY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaCtxGetApiVersion(CUcontext ctx, unsigned int *version) -{ - CUresult result = 0; - - if (version == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "version NULL"); - goto error; - } - - result = cuCtxGetApiVersion(ctx, version); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_GET_API_VERSION) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaCtxGetCacheConfig(CUfunc_cache *pconfig) -{ - CUresult result = 0; - - if (pconfig == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "pconfig NULL"); - goto error; - } - - result = cuCtxGetCacheConfig(pconfig); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_GET_CACHE_CONFIG) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaCtxGetCurrent(CUcontext *pctx) -{ - CUresult result = 0; - - if (pctx == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "pctx NULL"); - goto error; - } - - result = cuCtxGetCurrent(pctx); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_GET_CURRENT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *device the ordinal of the current context's device. - * - * \param device Returned device id for the current context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaCtxGetDevice(CUdevice *device) -{ - CUresult result = 0; - - if (device == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "device NULL"); - goto error; - } - - result = cuCtxGetDevice(device); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_GET_DEVICE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaCtxGetLimit(size_t *pvalue, CUlimit limit) -{ - CUresult result = 0; - - result = cuCtxGetLimit(pvalue, limit); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_GET_LIMIT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Pops the current CUDA context from the CPU thread. The CUDA context - * must have a usage count of 1. CUDA contexts have a usage count of 1 - * upon creation; the usage count may be incremented with cuCtxAttach() - * and decremented with cuCtxDetach(). - * - * If successful, cuCtxPopCurrent() passes back the new context handle - * in *pctx. The old context may then be made current to a different CPU - * thread by calling cuCtxPushCurrent(). - * - * Floating contexts may be destroyed by calling cuCtxDestroy(). - * - * If a context was current to the CPU thread before cuCtxCreate() or - * cuCtxPushCurrent() was called, this function makes that context - * current to the CPU thread again. - * - * \param pctx Returned new context handle. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaCtxPopCurrent(CUcontext *pctx) -{ - CUresult result = 0; - - result = cuCtxPopCurrent(pctx); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_POP_CURRENT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Pushes the given context ctx onto the CPU thread's stack of current - * contexts. The speci?ed context becomes the CPU thread's current - * context, so all CUDA functions that operate on the current context - * are affected. - * - * The previous current context may be made current again by calling - * cuCtxDestroy() or cuCtxPopCurrent(). - * - * The context must be "floating," i.e. not attached to any thread. - * Contexts are made to float by calling cuCtxPopCurrent(). - * - * \param ctx Floating context to attach. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaCtxPushCurrent(CUcontext ctx) -{ - CUresult result = 0; - - result = cuCtxPushCurrent(ctx); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_PUSH_CURRENT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaCtxSetCacheConfig(CUfunc_cache config) -{ - CUresult result = 0; - - result = cuCtxSetCacheConfig(config); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_SET_CACHE_CONFIG) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaCtxSetCurrent(CUcontext ctx) -{ - CUresult result = 0; - - result = cuCtxSetCurrent(ctx); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_SET_CURRENT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaCtxSetLimit(CUlimit limit, size_t value) -{ - CUresult result = 0; - - result = cuCtxSetLimit(value, limit); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_SET_LIMIT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Blocks until the device has completed all preceding requested tasks. - * cuCtxSynchronize() returns an error if one of the preceding tasks failed. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaCtxSynchronize(void) -{ - CUresult result = 0; - - result = cuCtxSynchronize(); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_SYNCHRONIZE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Increments the usage count of the context and passes back a context - * handle in *pctx that must be passed to cuCtxDetach() when the - * application is done with the context. cuCtxAttach() fails if there is - * no context current to the thread. Currently, the flags parameter must - * be 0. - * - * \param pctx Returned context handle of the current context. - * \param flags Context attach flags (must be 0). - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaCtxAttach(CUcontext *pctx, unsigned int flags) -{ - CUresult result = 0; - - SCLogInfo("Cuda API - %s deprecated", - SCMapEnumValueToName(SC_CUDA_CU_CTX_ATTACH, - sc_cuda_api_names_string_map)); - - if (pctx == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "pctx NULL"); - goto error; - } - - result = cuCtxAttach(pctx, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_ATTACH) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Decrements the usage count of the context ctx, and destroys the - * context if the usage count goes to 0. The context must be a handle - * that was passed back by cuCtxCreate() or cuCtxAttach(), and must be - * current to the calling thread. - * - * \param ctx Context to destroy. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaCtxDetach(CUcontext ctx) -{ - CUresult result = 0; - - SCLogInfo("Cuda API - %s deprecated", - SCMapEnumValueToName(SC_CUDA_CU_CTX_DETACH, - sc_cuda_api_names_string_map)); - - result = cuCtxDetach(ctx); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_CTX_DETACH) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/*****************************Module_Management_API****************************/ - -/** - * \brief Returns in *hfunc the handle of the function of name \"name\" located - * in module hmod. If no function of that name exists, - * cuModuleGetFunction() returns CUDA_ERROR_NOT_FOUND. - * - * \param hfunc Returned function handle. - * \param hmod Module to return function from. - * \param name Name of function to retrieve. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaModuleGetFunction(CUfunction *hfunc, CUmodule hmod, const char *name) -{ - CUresult result = 0; - - if (hfunc == NULL || name == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "hfunc is NULL or name is NULL"); - goto error; - } - - result = cuModuleGetFunction(hfunc, hmod, name); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MODULE_GET_FUNCTION) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *dptr and *bytes the base pointer and size of the global - * name \"name\" located in module hmod. If no variable of that name - * exists, cuModuleGetGlobal() returns CUDA_ERROR_NOT_FOUND. Both - * parameters dptr and bytes are optional. If one of them is NULL, - * it is ignored. - * - * \param dptr Returned global device pointer. - * \param bytes Returned global size in bytes. - * \param hmod Module to return function from. - * \param name Name of global to retrieve. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaModuleGetGlobal(CUdeviceptr *dptr, size_t *bytes, CUmodule hmod, - const char *name) -{ - CUresult result = 0; - - if (name == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "name is NULL"); - goto error; - } - - result = cuModuleGetGlobal(dptr, bytes, hmod, name); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MODULE_GET_GLOBAL) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaModuleGetSurfRef(CUsurfref *p_surf_ref, CUmodule hmod, const char *name) -{ - CUresult result = 0; - - if (p_surf_ref == NULL || name == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_surf_ref is NULL or name is NULL"); - goto error; - } - - result = cuModuleGetSurfRef(p_surf_ref, hmod, name); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MODULE_GET_SURF_REF) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *p_tex_ref the handle of the texture reference of name - * \"name\" in the module hmod. If no texture reference of that name - * exists, cuModuleGetTexRef() returns CUDA_ERROR_NOT_FOUND. This texture - * reference handle should not be destroyed, since it will be destroyed - * when the module is unloaded. - * - * \param p_tex_ref Returned global device pointer. - * \param hmod Module to retrieve texture reference from. - * \param name Name of the texture reference to retrieve. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaModuleGetTexRef(CUtexref *p_tex_ref, CUmodule hmod, const char *name) -{ - CUresult result = 0; - - if (p_tex_ref == NULL || name == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_tex_ref is NULL or name is NULL"); - goto error; - } - - result = cuModuleGetTexRef(p_tex_ref, hmod, name); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MODULE_GET_TEX_REF) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Takes a filename fname and loads the corresponding module \"module\" - * into the current context. The CUDA driver API does not attempt to - * lazily allocate the resources needed by a module; if the memory for - * functions and data (constant and global) needed by the module cannot - * be allocated, cuModuleLoad() fails. The file should be a cubin file - * as output by nvcc or a PTX file, either as output by nvcc or handwrtten. - * - * \param module Returned module. - * \param fname Filename of module to load. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaModuleLoad(CUmodule *module, const char *fname) -{ - CUresult result = 0; - - if (module == NULL || fname == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "module is NULL or fname is NULL"); - goto error; - } - - result = cuModuleLoad(module, fname); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MODULE_LOAD) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Takes a pointer image and loads the corresponding module \"module\" - * into the current context. The pointer may be obtained by mapping a - * cubin or PTX file, passing a cubin or PTX ?le as a NULL-terminated - * text string, or incorporating a cubin object into the executable - * resources and using operating system calls such as Windows - * FindResource() to obtain the pointer. - * - * \param module Returned module. - * \param image Module data to load - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaModuleLoadData(CUmodule *module, const void *image) -{ - CUresult result = 0; - - if (module == NULL || image == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "module is NULL or image is NULL"); - goto error; - } - - result = cuModuleLoadData(module, image); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MODULE_LOAD_DATA) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Takes a pointer image and loads the corresponding module module into - * the current context. The pointer may be obtained by mapping a cubin or - * PTX file, passing a cubin or PTX file as a NULL-terminated text - * string, or incorporating a cubin object into the executable resources - * and using operating system calls such as Windows FindResource() to - * obtain the pointer. Options are passed as an array via options and any - * corresponding parameters are passed in optionValues. The number of - * total options is supplied via numOptions. Any outputs will be returned - * via optionValues. Supported options are: - * - * - CU_JIT_MAX_REGISTERS: input specifies the maximum number of registers - * per thread; - * - CU_JIT_THREADS_PER_BLOCK: input specifies number of threads per block - * to target compilation for; output returns the number of threads - * the compiler actually targeted; - * - CU_JIT_WALL_TIME: output returns the float value of wall clock time, - * in milliseconds, spent compiling the PTX code; - * - CU_JIT_INFO_LOG_BUFFER: input is a pointer to a buffer in which to - * print any informational log messages from PTX assembly; - * - CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES: input is the size in bytes of the - * buffer; output is the number of bytes filled with messages; - * - CU_JIT_ERROR_LOG_BUFFER: input is a pointer to a buffer in which to - * print any error log messages from PTX assembly; - * - CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES: input is the size in bytes of the - * buffer; output is the number of bytes filled with messages; - * - CU_JIT_OPTIMIZATION_LEVEL: input is the level of optimization to apply - * to generated code (0 - 4), with 4 being the default and highest - * level; - * - CU_JIT_TARGET_FROM_CUCONTEXT: causes compilation target to be - * determined based on current attached context (default); - * - CU_JIT_TARGET: input is the compilation target based on supplied - * CUjit_target_enum; possible values are: - * -- CU_TARGET_COMPUTE_10 - * -- CU_TARGET_COMPUTE_11 - * -- CU_TARGET_COMPUTE_12 - * -- CU_TARGET_COMPUTE_13 - * - * \param module Returned module. - * \param image Module data to load. - * \param numOptions Number of options. - * \param options Options for JIT. - * \param optionValues Option values for JIT. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaModuleLoadDataEx(CUmodule *module, const void *image, - unsigned int num_options, CUjit_option *options, - void **option_values) -{ - CUresult result = 0; - - if (module == NULL || image == NULL || options == NULL || - option_values == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "module is NULL or image is NULL or options is NULL or " - "option_values is NULL"); - goto error; - } - - result = cuModuleLoadDataEx(module, image, num_options, options, option_values); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MODULE_LOAD_DATA_EX) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Takes a pointer fat_cubin and loads the corresponding module \"module\" - * into the current context. The pointer represents a fat binary object, - * which is a collection of different cubin files, all representing the - * same device code, but compiled and optimized for different - * architectures. There is currently no documented API for constructing - * and using fat binary objects by programmers, and therefore this - * function is an internal function in this version of CUDA. More - * information can be found in the nvcc document. - * - * \param module Returned module. - * \param fatCubin Fat binary to load. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaModuleLoadFatBinary(CUmodule *module, const void *fat_cubin) -{ - CUresult result = 0; - - if (module == NULL || fat_cubin == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "module is NULL or fatCubin is NULL"); - goto error; - } - - result = cuModuleLoadFatBinary(module, fat_cubin); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MODULE_LOAD_FAT_BINARY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Unloads a module hmod from the current context. - * - * \param module Module to unload - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaModuleUnload(CUmodule hmod) -{ - CUresult result = 0; - - result = cuModuleUnload(hmod); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MODULE_UNLOAD) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/****************************Memory_Management_API*****************************/ - -/** - * \brief Creates a CUDA array according to the CUDA_ARRAY3D_DESCRIPTOR - * structure pAllocateArray and returns a handle to the new CUDA - * array in *p_handle. The CUDA_ARRAY3D_DESCRIPTOR is defined as: - * - * typedef struct { - * unsigned int Width; - * unsigned int Height; - * unsigned int Depth; - * CUarray_format Format; - * unsigned int NumChannels; - * unsigned int Flags; - * } CUDA_ARRAY3D_DESCRIPTOR; - * - * where: - * - * - Width, Height, and Depth are the width, height, and depth of the - * CUDA array (in elements); the CUDA array is one-dimensional if -v * height and depth are 0, two-dimensional if depth is 0, and - * three-dimensional otherwise; - * - Format speci?es the format of the elements; CUarray_format is - * defined as: - * - * typedef enum CUarray_format_enum { - * CU_AD_FORMAT_UNSIGNED_INT8 = 0x01, - * CU_AD_FORMAT_UNSIGNED_INT16 = 0x02, - * CU_AD_FORMAT_UNSIGNED_INT32 = 0x03, - * CU_AD_FORMAT_SIGNED_INT8 = 0x08, - * CU_AD_FORMAT_SIGNED_INT16 = 0x09, - * CU_AD_FORMAT_SIGNED_INT32 = 0x0a, - * CU_AD_FORMAT_HALF = 0x10, - * CU_AD_FORMAT_FLOAT = 0x20 - * } CUarray_format; - * - * - NumChannels speci?es the number of packed components per CUDA array - * element; it may be 1, 2, or 4; - * - Flags provides for future features. For now, it must be set to 0. - * - * Here are examples of CUDA array descriptions: - * - * Description for a CUDA array of 2048 floats: - * - * CUDA_ARRAY3D_DESCRIPTOR desc; - * desc.Format = CU_AD_FORMAT_FLOAT; - * desc.NumChannels = 1; - * desc.Width = 2048; - * desc.Height = 0; - * desc.Depth = 0; - * - * Description for a 64 x 64 CUDA array of floats: - * - * CUDA_ARRAY3D_DESCRIPTOR desc; - * desc.Format = CU_AD_FORMAT_FLOAT; - * desc.NumChannels = 1; - * desc.Width = 64; - * desc.Height = 64; - * desc.Depth = 0; - * - * Description for a width x height x depth CUDA array of 64-bit, - * 4x16-bit float16's: - * - * CUDA_ARRAY3D_DESCRIPTOR desc; - * desc.FormatFlags = CU_AD_FORMAT_HALF; - * desc.NumChannels = 4; - * desc.Width = width; - * desc.Height = height; - * desc.Depth = depth; - * - * \param p_handle Returned Handle. - * \param p_allocate_array 3D array descriptor. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaArray3DCreate(CUarray *p_handle, - const CUDA_ARRAY3D_DESCRIPTOR *p_allocate_array) -{ - CUresult result = 0; - - if (p_handle == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_handle is NULL"); - goto error; - } - - result = cuArray3DCreate(p_handle, p_allocate_array); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_ARRAY_3D_CREATE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *p_rray_descriptor a descriptor containing information on - * the format and dimensions of the CUDA array h_array. It is useful for - * subroutines that have been passed a CUDA array, but need to know the - * CUDA array parameters for validation or other purposes. - * - * This function may be called on 1D and 2D arrays, in which case the - * Height and/or Depth members of the descriptor struct will be set to 0. - * - * \param p_array_descriptor Returned 3D array descriptor. - * \param h_array 3D array to get descriptor of. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaArray3DGetDescriptor(CUDA_ARRAY3D_DESCRIPTOR *p_array_descriptor, - CUarray h_array) -{ - CUresult result = 0; - - if (p_array_descriptor == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_array_descriptor is NULL"); - goto error; - } - - result = cuArray3DGetDescriptor(p_array_descriptor, h_array); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_ARRAY_3D_GET_DESCRIPTOR) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Creates a CUDA array according to the CUDA_ARRAY_DESCRIPTOR structure - * p_allocate_array and returns a handle to the new CUDA array in - * p_handle. The CUDA_ARRAY_DESCRIPTOR is defined as: - * - * typedef struct { - * unsigned int Width; - * unsigned int Height; - * CUarray_format Format; - * unsigned int NumChannels; - * } CUDA_ARRAY_DESCRIPTOR; - * - * where: - * - * - Width, and Height are the width, and height of the CUDA array - * (in elements); the CUDA array is one-dimensional if height is 0, - * two-dimensional otherwise; - * - Format speci?es the format of the elements; CUarray_format is - * defined as: - * - * typedef enum CUarray_format_enum { - * CU_AD_FORMAT_UNSIGNED_INT8 = 0x01, - * CU_AD_FORMAT_UNSIGNED_INT16 = 0x02, - * CU_AD_FORMAT_UNSIGNED_INT32 = 0x03, - * CU_AD_FORMAT_SIGNED_INT8 = 0x08, - * CU_AD_FORMAT_SIGNED_INT16 = 0x09, - * CU_AD_FORMAT_SIGNED_INT32 = 0x0a, - * CU_AD_FORMAT_HALF = 0x10, - * CU_AD_FORMAT_FLOAT = 0x20 - * } CUarray_format; - * - * - NumChannels specifies the number of packed components per CUDA - * array element; it may be 1, 2, or 4; - * - * Here are examples of CUDA array descriptions: - * - * Description for a CUDA array of 2048 floats: - * - * CUDA_ARRAY_DESCRIPTOR desc; - * desc.Format = CU_AD_FORMAT_FLOAT; - * desc.NumChannels = 1; - * desc.Width = 2048; - * desc.Height = 1; - * - * Description for a 64 x 64 CUDA array of floats: - * - * CUDA_ARRAY_DESCRIPTOR desc; - * desc.Format = CU_AD_FORMAT_FLOAT; - * desc.NumChannels = 1; - * desc.Width = 64; - * desc.Height = 64; - * - * Description for a width x height CUDA array of 64-bit, 4x16-bit - * float16's: - * - * CUDA_ARRAY_DESCRIPTOR desc; - * desc.FormatFlags = CU_AD_FORMAT_HALF; - * desc.NumChannels = 4; - * desc.Width = width; - * desc.Height = height; - * - * Description for a width x height CUDA array of 16-bit elements, each - * of which is two 8-bit unsigned chars: - * - * CUDA_ARRAY_DESCRIPTOR arrayDesc; - * desc.FormatFlags = CU_AD_FORMAT_UNSIGNED_INT8; - * desc.NumChannels = 2; - * desc.Width = width; - * desc.Height = height; - * - * \param p_handle Returned array. - * \param p_allocate_array Array descriptor. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaArrayCreate(CUarray *p_handle, - const CUDA_ARRAY_DESCRIPTOR *p_allocate_array) -{ - CUresult result = 0; - - if (p_handle == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_handle is NULL"); - goto error; - } - - result = cuArrayCreate(p_handle, p_allocate_array); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_ARRAY_CREATE) == -1) - goto error; - - return 0; - - error: - return -1; -} - - -/** - * \brief Destroys the CUDA array h_array. - * - * \param h_array Array to destroy. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaArrayDestroy(CUarray h_array) -{ - int result = cuArrayDestroy(h_array); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_ARRAY_DESTROY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *p_array_descriptor a descriptor containing information on - * the format and dimensions of the CUDA array h_array. It is useful for - * subroutines that have been passed a CUDA array, but need to know the - * CUDA array parameters for validation or other purposes. - * - * \param p_array_descriptor Returned array descriptor. - * \param h_array Array to get descriptor of. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaArrayGetDescriptor(CUDA_ARRAY_DESCRIPTOR *p_array_descriptor, - CUarray h_array) -{ - CUresult result = 0; - - if (p_array_descriptor == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_array_descriptor is NULL"); - goto error; - } - - result = cuArrayGetDescriptor(p_array_descriptor, h_array); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_ARRAY_GET_DESCRIPTOR) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaDeviceGetByPCIBusId(CUdevice *dev, char *pci_bus_id) -{ - CUresult result = 0; - - result = cuDeviceGetByPCIBusId(dev, pci_bus_id); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DEVICE_GET_BY_PCI_BUS_ID) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaDeviceGetPCIBusId(char *pci_bus_id, int len, CUdevice dev) -{ - CUresult result = 0; - - result = cuDeviceGetPCIBusId(pci_bus_id, len, dev); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_DEVICE_GET_PCI_BUS_ID) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaIpcCloseMemHandle(CUdeviceptr dptr) -{ - CUresult result = 0; - - result = cuIpcCloseMemHandle(dptr); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_IPC_CLOSE_MEM_HANDLE) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaIpcGetEventHandle(CUipcEventHandle *p_handle, CUevent event) -{ - CUresult result = 0; - - result = cuIpcGetEventHandle(p_handle, event); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_IPC_GET_MEM_HANDLE) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaIpcGetMemHandle(CUipcMemHandle *p_handle, CUdeviceptr dptr) -{ - CUresult result = 0; - - result = cuIpcGetMemHandle(p_handle, dptr); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_IPC_GET_MEM_HANDLE) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaIpcOpenEventHandle(CUevent *ph_event, CUipcEventHandle handle) -{ - CUresult result = 0; - - result = cuIpcOpenEventHandle(ph_event, handle); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_IPC_GET_MEM_HANDLE) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaIpcOpenMemHandle(CUdeviceptr *pdptr, CUipcMemHandle handle, - unsigned int flags) -{ - CUresult result = 0; - - result = cuIpcOpenMemHandle(pdptr, handle, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_IPC_OPEN_EVENT_HANDLE) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Returns in *p_array_descriptor a descriptor containing information on - * the format and dimensions of the CUDA array h_array. It is useful for - * subroutines that have been passed a CUDA array, but need to know the - * CUDA array parameters for validation or other purposes. - * - * \param p_array_descriptor Returned array descriptor. - * \param h_array Array to get descriptor of. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemAlloc(CUdeviceptr *dptr, size_t byte_size) -{ - CUresult result = 0; - - if (dptr == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "dptr is NULL"); - goto error; - } - - result = cuMemAlloc(dptr, byte_size); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_ALLOC) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Allocates bytesize bytes of host memory that is page-locked and - * accessible to the device. The driver tracks the vir-tual memory - * ranges allocated with this function and automatically accelerates - * calls to functions such as cuMemcpy(). Since the memory can be - * accessed directly by the device, it can be read or written with - * much higher bandwidth than pageable memory obtained with functions - * such as SCMalloc(). Allocating excessive amounts of memory with - * cuMemAllocHost() may degrade system performance, since it reduces - * the amount of memory available to the system for paging. As a result, - * this function is best used sparingly to allocate staging areas for - * data exchange between host and device. - * - * \param pp Returned host pointer to page-locked memory. - * \param byte_size Requested allocation size in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemAllocHost(void **pp, size_t byte_size) -{ - CUresult result = 0; - - if (pp == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "pp is NULL"); - goto error; - } - - result = cuMemAllocHost(pp, byte_size); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_ALLOC_HOST) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Allocates at least width_in_bytes * height bytes of linear memory on the - * device and returns in *dptr a pointer to the allocated memory. The - * function may pad the allocation to ensure that corresponding pointers in - * any given row will continue to meet the alignment requirements for - * coalescing as the address is updated from row to row. ElementSizeBytes - * specifies the size of the largest reads and writes that will be - * performed on the memory range. - * - * element_size_bytes may be 4, 8 or 16 (since coalesced memory - * transactions are not possible on other data sizes). If element_size_bytes - * is smaller than the actual read/write size of a kernel, the kernel will - * run correctly, but possibly at reduced speed. The pitch returned in - * *p_itch by cuMemAllocPitch() is the width in bytes of the allocation. - * The intended usage of pitch is as a separate parameter of the allocation, - * used to compute addresses within the 2D array. Given the row and column - * of an array element of type T, the address is computed as: - * - * T * p_element = (T*)((char*)base_address + row * pitch) + column; - * - * The pitch returned by cuMemAllocPitch() is guaranteed to work with - * cuMemcpy2D() under all circumstances. For allocations of 2D arrays, it - * is recommended that programmers consider performing pitch allocations - * using cuMemAllocPitch(). Due to alignment restrictions in the hardware, - * this is especially true if the application will be performing 2D memory - * copies between different regions of device memory (whether linear memory - * or CUDA arrays). - * - * \param dptr Returned device pointer. - * \param p_pitch Returned pitch of allocation in bytes. - * \param width_in_bytes Requested allocation width in bytes. - * \param height Requested allocation width in rows. - * \param element_size_bytes Size of largest reads/writes for range. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemAllocPitch(CUdeviceptr *dptr, size_t *p_pitch, - size_t width_in_bytes, - size_t height, - unsigned int element_size_bytes) -{ - CUresult result = 0; - - if (dptr == NULL || p_pitch == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "dptr is NULL or p_pitch is NULL"); - goto error; - } - - result = cuMemAllocPitch(dptr, p_pitch, width_in_bytes, height, - element_size_bytes); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_ALLOC_PITCH) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemcpy(CUdeviceptr dst, CUdeviceptr src, size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpy(dst, src, byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY) == -1) - goto error; - - return 0; - error: - return -1; -} - - -/** - * \brief Perform a 2D memory copy according to the parameters specified in - * p_copy. The CUDA_MEMCPY2D structure is defined as: - * - * typedef struct CUDA_MEMCPY2D_st { - * unsigned int srcXInBytes, srcY; - * CUmemorytype srcMemoryType; - * const void *srcHost; - * CUdeviceptr srcDevice; - * CUarray srcArray; - * unsigned int srcPitch; - * unsigned int dstXInBytes, dstY; - * CUmemorytype dstMemoryType; - * void *dstHost; - * CUdeviceptr dstDevice; - * CUarray dstArray; - * unsigned int dstPitch; - * unsigned int WidthInBytes; - * unsigned int Height; - * } CUDA_MEMCPY2D; - * - * where: - * - * - srcMemoryType and dstMemoryType specify the type of memory of the - * source and destination, respectively; - * - * CUmemorytype_enum is de?ned as: - * - * typedef enum CUmemorytype_enum { - * CU_MEMORYTYPE_HOST = 0x01, - * CU_MEMORYTYPE_DEVICE = 0x02, - * CU_MEMORYTYPE_ARRAY = 0x03 - * } CUmemorytype; - * - * If srcMemoryType is CU_MEMORYTYPE_HOST, srcHost and srcPitch specify - * the (host) base address of the source data and the bytes per row to - * apply. srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_DEVICE, srcDevice and srcPitch - * specify the (device) base address of the source data and the bytes per - * row to apply. srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_ARRAY, srcArray speci?es the handle - * of the source data. srcHost, srcDevice and srcPitch are ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_HOST, dstHost and dstPitch specify - * the (host) base address of the destination data and the bytes per row - * to apply. dstArray is ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_DEVICE, dstDevice and dstPitch - * specify the (device) base address of the destination data and the - * bytes per row to apply. dstArray is ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_ARRAY, dstArray specifies the handle - * of the destination data dstHost, dstDevice and dstPitch are ignored. - * - * - srcXInBytes and srcY specify the base address of the source data for - * the copy. - * - * For host pointers, the starting address is - * - * void* Start = (void*)((char*)srcHost+srcY*srcPitch + srcXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr Start = srcDevice+srcY*srcPitch+srcXInBytes; - * - * For CUDA arrays, srcXInBytes must be evenly divisible by the array - * element size. - * - * - dstXInBytes and dstY specify the base address of the destination data - * for the copy. - * - * For host pointers, the base address is - * - * void* dstStart = (void*)((char*)dstHost+dstY*dstPitch + dstXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr dstStart = dstDevice+dstY*dstPitch+dstXInBytes; - * - * For CUDA arrays, dstXInBytes must be evenly divisible by the array - * element size. - * - * - WidthInBytes and Height specify the width (in bytes) and height of - * the 2D copy being performed. Any pitches must be greater than or - * equal to WidthInBytes. - * - * cuMemcpy2D() returns an error if any pitch is greater than the - * maximum allowed (CU_DEVICE_ATTRIBUTE_MAX_PITCH). cuMemAllocPitch() - * passes back pitches that always work with cuMemcpy2D(). On intra-device - * memory copies (device ? device, CUDA array ? device, CUDA array ? - * CUDA array), cuMemcpy2D() may fail for pitches not computed by - * cuMemAllocPitch(). cuMemcpy2DUnaligned() does not have this restriction, - * but may run signi?cantly slower in the cases where cuMemcpy2D() would - * have returned an error code. - * - * \param p_copy Parameters for the memory copy. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpy2D(const CUDA_MEMCPY2D *p_copy) -{ - CUresult result = 0; - - if (p_copy == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_copy is NULL"); - goto error; - } - - result = cuMemcpy2D(p_copy); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_2D) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Perform a 2D memory copy according to the parameters specified in - * p_copy. The CUDA_MEMCPY2D structure is defined as: - * - * typedef struct CUDA_MEMCPY2D_st { - * unsigned int srcXInBytes, srcY; - * CUmemorytype srcMemoryType; - * const void *srcHost; - * CUdeviceptr srcDevice; - * CUarray srcArray; - * unsigned int srcPitch; - * unsigned int dstXInBytes, dstY; - * CUmemorytype dstMemoryType; - * void *dstHost; - * CUdeviceptr dstDevice; - * CUarray dstArray; - * unsigned int dstPitch; - * unsigned int WidthInBytes; - * unsigned int Height; - * } CUDA_MEMCPY2D; - * - * where: - * - * - srcMemoryType and dstMemoryType specify the type of memory of the - * source and destination, respectively; - * - * CUmemorytype_enum is de?ned as: - * - * typedef enum CUmemorytype_enum { - * CU_MEMORYTYPE_HOST = 0x01, - * CU_MEMORYTYPE_DEVICE = 0x02, - * CU_MEMORYTYPE_ARRAY = 0x03 - * } CUmemorytype; - * - * If srcMemoryType is CU_MEMORYTYPE_HOST, srcHost and srcPitch specify - * the (host) base address of the source data and the bytes per row to - * apply. srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_DEVICE, srcDevice and srcPitch - * specify the (device) base address of the source data and the bytes per - * row to apply. srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_ARRAY, srcArray speci?es the handle - * of the source data. srcHost, srcDevice and srcPitch are ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_HOST, dstHost and dstPitch specify - * the (host) base address of the destination data and the bytes per row - * to apply. dstArray is ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_DEVICE, dstDevice and dstPitch - * specify the (device) base address of the destination data and the - * bytes per row to apply. dstArray is ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_ARRAY, dstArray specifies the handle - * of the destination data dstHost, dstDevice and dstPitch are ignored. - * - * - srcXInBytes and srcY specify the base address of the source data for - * the copy. - * - * For host pointers, the starting address is - * - * void* Start = (void*)((char*)srcHost+srcY*srcPitch + srcXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr Start = srcDevice+srcY*srcPitch+srcXInBytes; - * - * For CUDA arrays, srcXInBytes must be evenly divisible by the array - * element size. - * - * - dstXInBytes and dstY specify the base address of the destination data - * for the copy. - * - * For host pointers, the base address is - * - * void* dstStart = (void*)((char*)dstHost+dstY*dstPitch + dstXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr dstStart = dstDevice+dstY*dstPitch+dstXInBytes; - * - * For CUDA arrays, dstXInBytes must be evenly divisible by the array - * element size. - * - * - WidthInBytes and Height specify the width (in bytes) and height of - * the 2D copy being performed. Any pitches must be greater than or - * equal to WidthInBytes. - * - * cuMemcpy2D() returns an error if any pitch is greater than the - * maximum allowed (CU_DEVICE_ATTRIBUTE_MAX_PITCH). cuMemAllocPitch() - * passes back pitches that always work with cuMemcpy2D(). On intra-device - * memory copies (device ? device, CUDA array ? device, CUDA array ? - * CUDA array), cuMemcpy2D() may fail for pitches not computed by - * cuMemAllocPitch(). cuMemcpy2DUnaligned() does not have this restriction, - * but may run signi?cantly slower in the cases where cuMemcpy2D() would - * have returned an error code. - * - * cuMemcpy2DAsync() is asynchronous and can optionally be associated to a - * stream by passing a non-zero hStream argument. It only works on - * page-locked host memory and returns an error if a pointer to pageable - * memory is passed as input. - * - * \param p_copy Parameters for the memory copy. - * \param h_stream Stream identifier. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpy2DAsync(const CUDA_MEMCPY2D *p_copy, CUstream h_stream) -{ - CUresult result = 0; - - if (p_copy == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_copy is NULL"); - goto error; - } - - result = cuMemcpy2DAsync(p_copy, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_2D_ASYNC) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Perform a 2D memory copy according to the parameters specified in - * p_copy. The CUDA_MEMCPY2D structure is defined as: - * - * typedef struct CUDA_MEMCPY2D_st { - * unsigned int srcXInBytes, srcY; - * CUmemorytype srcMemoryType; - * const void *srcHost; - * CUdeviceptr srcDevice; - * CUarray srcArray; - * unsigned int srcPitch; - * unsigned int dstXInBytes, dstY; - * CUmemorytype dstMemoryType; - * void *dstHost; - * CUdeviceptr dstDevice; - * CUarray dstArray; - * unsigned int dstPitch; - * unsigned int WidthInBytes; - * unsigned int Height; - * } CUDA_MEMCPY2D; - * - * where: - * - * - srcMemoryType and dstMemoryType specify the type of memory of the - * source and destination, respectively; - * - * CUmemorytype_enum is de?ned as: - * - * typedef enum CUmemorytype_enum { - * CU_MEMORYTYPE_HOST = 0x01, - * CU_MEMORYTYPE_DEVICE = 0x02, - * CU_MEMORYTYPE_ARRAY = 0x03 - * } CUmemorytype; - * - * If srcMemoryType is CU_MEMORYTYPE_HOST, srcHost and srcPitch specify - * the (host) base address of the source data and the bytes per row to - * apply. srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_DEVICE, srcDevice and srcPitch - * specify the (device) base address of the source data and the bytes per - * row to apply. srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_ARRAY, srcArray speci?es the handle - * of the source data. srcHost, srcDevice and srcPitch are ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_HOST, dstHost and dstPitch specify - * the (host) base address of the destination data and the bytes per row - * to apply. dstArray is ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_DEVICE, dstDevice and dstPitch - * specify the (device) base address of the destination data and the - * bytes per row to apply. dstArray is ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_ARRAY, dstArray specifies the handle - * of the destination data dstHost, dstDevice and dstPitch are ignored. - * - * - srcXInBytes and srcY specify the base address of the source data for - * the copy. - * - * For host pointers, the starting address is - * - * void* Start = (void*)((char*)srcHost+srcY*srcPitch + srcXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr Start = srcDevice+srcY*srcPitch+srcXInBytes; - * - * For CUDA arrays, srcXInBytes must be evenly divisible by the array - * element size. - * - * - dstXInBytes and dstY specify the base address of the destination data - * for the copy. - * - * For host pointers, the base address is - * - * void* dstStart = (void*)((char*)dstHost+dstY*dstPitch + dstXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr dstStart = dstDevice+dstY*dstPitch+dstXInBytes; - * - * For CUDA arrays, dstXInBytes must be evenly divisible by the array - * element size. - * - * - WidthInBytes and Height specify the width (in bytes) and height of - * the 2D copy being performed. Any pitches must be greater than or - * equal to WidthInBytes. - * - * cuMemcpy2D() returns an error if any pitch is greater than the - * maximum allowed (CU_DEVICE_ATTRIBUTE_MAX_PITCH). cuMemAllocPitch() - * passes back pitches that always work with cuMemcpy2D(). On intra-device - * memory copies (device ? device, CUDA array ? device, CUDA array ? - * CUDA array), cuMemcpy2D() may fail for pitches not computed by - * cuMemAllocPitch(). cuMemcpy2DUnaligned() does not have this restriction, - * but may run signi?cantly slower in the cases where cuMemcpy2D() would - * have returned an error code. - * - * cuMemcpy2DAsync() is asynchronous and can optionally be associated to a - * stream by passing a non-zero hStream argument. It only works on - * page-locked host memory and returns an error if a pointer to pageable - * memory is passed as input. - * - * \param p_copy Parameters for the memory copy. - * \param h_stream Stream identifier. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpy2DUnaligned(const CUDA_MEMCPY2D *p_copy) -{ - CUresult result = 0; - - if (p_copy == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_copy is NULL"); - goto error; - } - - result = cuMemcpy2DUnaligned(p_copy); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_2D_UNALIGNED) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Perform a 3D memory copy according to the parameters specified in - * p_copy. The CUDA_MEMCPY3D structure is defined as: - * - * typedef struct CUDA_MEMCPY3D_st { - * unsigned int srcXInBytes, srcY, srcZ; - * unsigned int srcLOD; - * CUmemorytype srcMemoryType; - * const void *srcHost; - * CUdeviceptr srcDevice; - * CUarray srcArray; - * unsigned int srcPitch; // ignored when src is array - * unsigned int srcHeight; // ignored when src is array; may be 0 if Depth==1 - * unsigned int dstXInBytes, dstY, dstZ; - * unsigned int dstLOD; - * CUmemorytype dstMemoryType; - * void *dstHost; - * CUdeviceptr dstDevice; - * CUarray dstArray; - * unsigned int dstPitch; // ignored when dst is array - * unsigned int dstHeight; // ignored when dst is array; may be 0 if Depth==1 - * unsigned int WidthInBytes; - * unsigned int Height; - * unsigned int Depth; - * } CUDA_MEMCPY3D; - * - * where: - * - * - srcMemoryType and dstMemoryType specify the type of memory of the - * source and destination, respectively; - * CUmemorytype_enum is defined as: - * - * typedef enum CUmemorytype_enum { - * CU_MEMORYTYPE_HOST = 0x01, - * CU_MEMORYTYPE_DEVICE = 0x02, - * CU_MEMORYTYPE_ARRAY = 0x03 - * } CUmemorytype; - * - * If srcMemoryType is CU_MEMORYTYPE_HOST, srcHost, srcPitch and srcHeight - * specify the (host) base address of the source data, the bytes per row, - * and the height of each 2D slice of the 3D array. srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_DEVICE, srcDevice, srcPitch and - * srcHeight specify the (device) base address of the source data, the - * bytes per row, and the height of each 2D slice of the 3D array. - * srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_ARRAY, srcArray specifies the handle - * of the source data. srcHost, srcDevice, srcPitch and srcHeight are - * ignored. If dstMemoryType is CU_MEMORYTYPE_HOST, dstHost and dstPitch - * specify the (host) base address of the destination data, the bytes per - * row, and the height of each 2D slice of the 3D array. dstArray is - * ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_DEVICE, dstDevice and dstPitch - * specify the (device) base address of the destination data, the bytes - * per row, and the height of each 2D slice of the 3D array. dstArray is - * ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_ARRAY, dstArray specifies the - * handle of the destination data. dstHost, dstDevice, dstPitch and - * dstHeight are ignored. - * - * - srcXInBytes, srcY and srcZ specify the base address of the source - * data for the copy. - * - * For host pointers, the starting address is - * - * void* Start = (void*)((char*)srcHost+(srcZ*srcHeight+srcY)*srcPitch + srcXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr Start = srcDevice+(srcZ*srcHeight+srcY)*srcPitch+srcXInBytes; - * - * For CUDA arrays, srcXInBytes must be evenly divisible by the array - * element size. - * - * - dstXInBytes, dstY and dstZ specify the base address of the destination - * data for the copy. - * - * For host pointers, the base address is - * - * void* dstStart = (void*)((char*)dstHost+(dstZ*dstHeight+dstY)*dstPitch + dstXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr dstStart = dstDevice+(dstZ*dstHeight+dstY)*dstPitch+dstXInBytes; - * - * For CUDA arrays, dstXInBytes must be evenly divisible by the array - * element size. - * - * - WidthInBytes, Height and Depth specify the width (in bytes), height - * and depth of the 3D copy being performed. Any pitches must be greater - * than or equal to WidthInBytes. - * - * cuMemcpy3D() returns an error if any pitch is greater than the maximum - * allowed (CU_DEVICE_ATTRIBUTE_MAX_PITCH). - * - * The srcLOD and dstLOD members of the CUDA_MEMCPY3D structure must be - * set to 0. - * - * \param p_copy Parameters for the memory copy. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpy3D(const CUDA_MEMCPY3D *p_copy) -{ - CUresult result = 0; - - if (p_copy == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_copy is NULL"); - goto error; - } - - result = cuMemcpy3D(p_copy); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_3D) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Perform a 3D memory copy according to the parameters specified in - * p_copy. The CUDA_MEMCPY3D structure is defined as: - * - * typedef struct CUDA_MEMCPY3D_st { - * unsigned int srcXInBytes, srcY, srcZ; - * unsigned int srcLOD; - * CUmemorytype srcMemoryType; - * const void *srcHost; - * CUdeviceptr srcDevice; - * CUarray srcArray; - * unsigned int srcPitch; // ignored when src is array - * unsigned int srcHeight; // ignored when src is array; may be 0 if Depth==1 - * unsigned int dstXInBytes, dstY, dstZ; - * unsigned int dstLOD; - * CUmemorytype dstMemoryType; - * void *dstHost; - * CUdeviceptr dstDevice; - * CUarray dstArray; - * unsigned int dstPitch; // ignored when dst is array - * unsigned int dstHeight; // ignored when dst is array; may be 0 if Depth==1 - * unsigned int WidthInBytes; - * unsigned int Height; - * unsigned int Depth; - * } CUDA_MEMCPY3D; - * - * where: - * - * - srcMemoryType and dstMemoryType specify the type of memory of the - * source and destination, respectively; - * CUmemorytype_enum is defined as: - * - * typedef enum CUmemorytype_enum { - * CU_MEMORYTYPE_HOST = 0x01, - * CU_MEMORYTYPE_DEVICE = 0x02, - * CU_MEMORYTYPE_ARRAY = 0x03 - * } CUmemorytype; - * - * If srcMemoryType is CU_MEMORYTYPE_HOST, srcHost, srcPitch and srcHeight - * specify the (host) base address of the source data, the bytes per row, - * and the height of each 2D slice of the 3D array. srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_DEVICE, srcDevice, srcPitch and - * srcHeight specify the (device) base address of the source data, the - * bytes per row, and the height of each 2D slice of the 3D array. - * srcArray is ignored. - * - * If srcMemoryType is CU_MEMORYTYPE_ARRAY, srcArray specifies the handle - * of the source data. srcHost, srcDevice, srcPitch and srcHeight are - * ignored. If dstMemoryType is CU_MEMORYTYPE_HOST, dstHost and dstPitch - * specify the (host) base address of the destination data, the bytes per - * row, and the height of each 2D slice of the 3D array. dstArray is - * ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_DEVICE, dstDevice and dstPitch - * specify the (device) base address of the destination data, the bytes - * per row, and the height of each 2D slice of the 3D array. dstArray is - * ignored. - * - * If dstMemoryType is CU_MEMORYTYPE_ARRAY, dstArray specifies the - * handle of the destination data. dstHost, dstDevice, dstPitch and - * dstHeight are ignored. - * - * - srcXInBytes, srcY and srcZ specify the base address of the source - * data for the copy. - * - * For host pointers, the starting address is - * - * void* Start = (void*)((char*)srcHost+(srcZ*srcHeight+srcY)*srcPitch + srcXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr Start = srcDevice+(srcZ*srcHeight+srcY)*srcPitch+srcXInBytes; - * - * For CUDA arrays, srcXInBytes must be evenly divisible by the array - * element size. - * - * - dstXInBytes, dstY and dstZ specify the base address of the destination - * data for the copy. - * - * For host pointers, the base address is - * - * void* dstStart = (void*)((char*)dstHost+(dstZ*dstHeight+dstY)*dstPitch + dstXInBytes); - * - * For device pointers, the starting address is - * - * CUdeviceptr dstStart = dstDevice+(dstZ*dstHeight+dstY)*dstPitch+dstXInBytes; - * - * For CUDA arrays, dstXInBytes must be evenly divisible by the array - * element size. - * - * - WidthInBytes, Height and Depth specify the width (in bytes), height - * and depth of the 3D copy being performed. Any pitches must be greater - * than or equal to WidthInBytes. - * - * cuMemcpy3D() returns an error if any pitch is greater than the maximum - * allowed (CU_DEVICE_ATTRIBUTE_MAX_PITCH). - * - * cuMemcpy3DAsync() is asynchronous and can optionally be associated - * to a stream by passing a non-zero hStream argument. It only works on - * page-locked host memory and returns an error if a pointer to pageable - * memory is passed as input. - * - * The srcLOD and dstLOD members of the CUDA_MEMCPY3D structure must be - * set to 0. - * - * \param p_copy Parameters for the memory copy. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpy3DAsync(const CUDA_MEMCPY3D *p_copy, CUstream h_stream) -{ - CUresult result = 0; - - if (p_copy == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_copy is NULL"); - goto error; - } - - result = cuMemcpy3DAsync(p_copy, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_3D_ASYNC) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemcpy3DPeer(const CUDA_MEMCPY3D_PEER *p_copy) -{ - CUresult result = 0; - - result = cuMemcpy3DPeer(p_copy); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_3D_PEER) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaMemcpy3DPeerAsync(const CUDA_MEMCPY3D_PEER *p_copy, - CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemcpy3DPeerAsync(p_copy, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_3D_PEER_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaMemcpyAsync(CUdeviceptr dst, CUdeviceptr src, size_t byte_count, - CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemcpyAsync(dst, src, byte_count, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Copies from one 1D CUDA array to another. dstArray and srcArray - * specify the handles of the destination and source CUDA arrays for the - * copy, respectively. dstIndex and srcIndex specify the destination and - * source indices into the CUDA array. These values are in the range - * [0, Width-1] for the CUDA array; they are not byte offsets. ByteCount - * is the number of bytes to be copied. The size of the elements in the - * CUDA arrays need not be the same format, but the elements must be the - * same size; and count must be evenly divisible by that size. - * - * \param dst_array Destination array. - * \param dst_index Offset of destination array. - * \param src_array Source array. - * \param src_index Offset of source array. - * \param byte_count Size of memory copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyAtoA(CUarray dst_array, size_t dst_offset, - CUarray src_array, size_t src_offset, - size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpyAtoA(dst_array, dst_offset, src_array, src_offset, - byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_A_TO_A) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \param Copies from one 1D CUDA array to device memory. dstDevice specifies the - * base pointer of the destination and must be naturally aligned with the - * CUDA array elements. hSrc and SrcIndex specify the CUDA array handle and - * the index (in array elements) of the array element where the copy is - * to begin. ByteCount speci?es the number of bytes to copy and must be - * evenly divisible by the array element size. - * - * \param dst_device Destination device pointer. - * \param h_src Source array. - * \param src_index Offset of source array. - * \param byte_count Size of memory copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyAtoD(CUdeviceptr dst_device, CUarray src_array, - size_t src_offset, size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpyAtoD(dst_device, src_array, src_offset, byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_A_TO_D) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \param Copies from one 1D CUDA array to host memory. dstHost specifies the - * base pointer of the destination. srcArray and srcIndex specify the - * CUDA array handle and starting index of the source data. ByteCount - * specifies the number of bytes to copy. - * - * \param dst_device Destination device pointer. - * \param h_src Source array. - * \param src_index Offset of source array. - * \param byte_count Size of memory copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyAtoH(void *dst_host, CUarray src_array, size_t src_offset, - size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpyAtoH(dst_host, src_array, src_offset, byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_A_TO_H) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \param Copies from one 1D CUDA array to host memory. dstHost specifies the - * base pointer of the destination. srcArray and srcIndex specify the - * CUDA array handle and starting index of the source data. ByteCount - * specifies the number of bytes to copy. - * - * cuMemcpyAtoHAsync() is asynchronous and can optionally be associated - * to a stream by passing a non-zero stream argument. It only works on - * page-locked host memory and returns an error if a pointer to pageable - * memory is passed as input. - * - * \param dst_device Destination device pointer. - * \param src_array Source array. - * \param src_index Offset of source array. - * \param byte_count Size of memory copy in bytes. - * \param h_stream Stream identifier. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyAtoHAsync(void *dst_host, CUarray src_array, - size_t src_offset, size_t byte_count, - CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemcpyAtoHAsync(dst_host, src_array, src_offset, byte_count, - h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_A_TO_H_ASYNC) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Copies from device memory to a 1D CUDA array. dstArray and dstIndex - * specify the CUDA array handle and starting index of the destination - * data. srcDevice speci?es the base pointer of the source. ByteCount - * specifies the number of bytes to copy. - * - * \param dst_array Destination array. - * \param dst_index Offset of destination array. - * \param src_device Source device pointer. - * \param byte_count Size of memory copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyDtoA(CUarray dst_array, size_t dst_offset, - CUdeviceptr src_device, size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpyDtoA(dst_array, dst_offset, src_device, byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_D_TO_A) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Copies from device memory to device memory. dstDevice and srcDevice are - * the base pointers of the destination and source, respectively. - * byte_count specifies the number of bytes to copy. Note that this - * function is asynchronous. - * - * \param dst_device Destination device pointer. - * \param src_device Source device pointer. - * \param byte_count Size of memory copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyDtoD(CUdeviceptr dst_device, CUdeviceptr src_device, - size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpyDtoD(dst_device, src_device, byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_D_TO_D) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemcpyDtoDAsync(CUdeviceptr dst_device, CUdeviceptr src_device, - size_t byte_count, CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemcpyDtoDAsync(dst_device, src_device, byte_count, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_D_TO_D_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - - -/** - * \brief Copies from device to host memory. dst_host and src_device specify - * the base pointers of the destination and source, respectively. - * byte_count specifies the number of bytes to copy. Note that this - * function is synchronous. - * - * \param dst_host Destination device pointer. - * \param src_device Source device pointer. - * \param byte_count Size of memory copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyDtoH(void *dst_host, CUdeviceptr src_device, - size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpyDtoH(dst_host, src_device, byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_D_TO_H) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Copies from device to host memory. dst_host and src_device specify - * the base pointers of the destination and source, respectively. - * byte_count specifies the number of bytes to copy. - * - * cuMemcpyDtoHAsync() is asynchronous and can optionally be associated - * to a stream by passing a non-zero h_stream argument. It only works - * on page-locked memory and returns an error if a pointer to pageable - * memory is passed as input. - * - * \param dst_host Destination device pointer. - * \param src_device Source device pointer. - * \param byte_count Size of memory copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyDtoHAsync(void *dst_host, CUdeviceptr src_device, - size_t byte_count, CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemcpyDtoHAsync(dst_host, src_device, byte_count, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_D_TO_H_ASYNC) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Copies from host memory to a 1D CUDA array. dst_array and dst_index - * specify the CUDA array handle and starting index of the destination - * data. p_src specifies the base address of the source. byte_count - * specifies the number of bytes to copy. - * - * \param dst_array Destination array. - * \param dst_index Offset of destination array. - * \param p_src Source host pointer. - * \param byte_count Size of memory copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyHtoA(CUarray dst_array, size_t dst_offset, - const void *src_host, size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpyHtoA(dst_array, dst_offset, src_host, byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_H_TO_A) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Copies from host memory to a 1D CUDA array. dst_array and dst_index - * specify the CUDA array handle and starting index of the destination - * data. p_src specifies the base address of the source. byte_count - * specfies the number of bytes to copy. - * - * cuMemcpyHtoAAsync() is asynchronous and can optionally be associated - * to a stream by passing a non-zero h_stream argument. It only works on - * page-locked memory and returns an error if a pointer to pageable - * memory is passed as input. - * - * \param dst_array Destination array. - * \param dst_index Offset of destination array. - * \param p_src Source host pointer. - * \param byte_count Size of memory copy in bytes. - * \param h_stream Stream identifier. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyHtoAAsync(CUarray dst_array, size_t dst_offset, - const void *src_host, size_t byte_count, - CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemcpyHtoAAsync(dst_array, dst_offset, src_host, byte_count, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_H_TO_A_ASYNC) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Copies from host memory to device memory. dst_device and src_host - * are the base addresses of the destination and source, respectively. - * byte_count specifies the number of bytes to copy. Note that this - * function is synchronous. - * - * \param dst_device Destination device pointer. - * \param src_host Source host pointer. - * \param byte_count Size of memory copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyHtoD(CUdeviceptr dst_device, const void *src_host, - size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpyHtoD(dst_device, src_host,byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_H_TO_D) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Copies from host memory to device memory. dst_device and src_host are - * the base addresses of the destination and source, respectively. - * byte_count specifies the number of bytes to copy. - * - * cuMemcpyHtoDAsync() is asynchronous and can optionally be associated - * to a stream by passing a non-zero h_stream argument. It only works on - * page-locked memory and returns an error if a pointer to pageable - * memory is passed as input. - * - * - * \param dst_device Destination device pointer. - * \param src_host Source host pointer. - * \param byte_count Size of memory copy in bytes. - * \param h_stream Stream identifier. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemcpyHtoDAsync(CUdeviceptr dst_device, const void *src_host, - size_t byte_count, CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemcpyHtoDAsync(dst_device, src_host, byte_count, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_H_TO_D_ASYNC) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemcpyPeer(CUdeviceptr dst_device, CUcontext dst_context, - CUdeviceptr src_device, CUcontext src_context, - size_t byte_count) -{ - CUresult result = 0; - - result = cuMemcpyPeer(dst_device, dst_context, src_device, src_context, - byte_count); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_PEER) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaMemcpyPeerAsync(CUdeviceptr dst_device, CUcontext dst_context, - CUdeviceptr src_device, CUcontext src_context, - size_t byte_count, CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemcpyPeerAsync(dst_device, dst_context, src_device, src_context, - byte_count, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMCPY_PEER_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Frees the memory space pointed to by dptr, which must have been - * returned by a previous call to cuMemAlloc() or cuMemAllocPitch(). - * - * \param dptr Pointer to the memory to free. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemFree(CUdeviceptr dptr) -{ - CUresult result = 0; - - result = cuMemFree(dptr); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_FREE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Frees the memory space pointed to by p, which must have been returned - * by a previous call to cuMemAllocHost(). - * - * \param p Pointer to the memory to free. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemFreeHost(void *p) -{ - CUresult result = 0; - - if (p == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p is NULL"); - goto error; - } - - result = cuMemFreeHost(p); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_FREE_HOST) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns the base address in *pbase and size in *psize of the allocation - * by cuMemAlloc() or cuMemAllocPitch() that contains the input pointer - * dptr. Both parameters pbase and psize are optional. If one of them is - * NULL, it is ignored. - * - * \param pbase Returned base address. - * \param psize Returned size of device memory allocation. - * \param dptr Device pointer to query - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemGetAddressRange(CUdeviceptr *pbase, size_t *psize, - CUdeviceptr dptr) -{ - CUresult result = 0; - - result = cuMemGetAddressRange(pbase, psize, dptr); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_GET_ADDRESS_RANGE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *free and *total respectively, the free and total amount - * of memory available for allocation by the CUDA context, in bytes. - * - * \param free Returned free memory in bytes. - * \param total Returned total memory in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemGetInfo(size_t *free, size_t *total) -{ - CUresult result = 0; - - if (free == NULL || total == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "free is NULL || total is NULL"); - goto error; - } - - result = cuMemGetInfo(free, total); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_GET_INFO) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Allocates bytesize bytes of host memory that is page-locked and - * accessible to the device. The driver tracks the virtual memory ranges - * allocated with this function and automatically accelerates calls to - * functions such as cuMemcpyHtoD(). Since the memory can be accessed - * directly by the device, it can be read or written with much higher - * bandwidth than pageable memory obtained with functions such as - * SCMalloc(). Allocating excessive amounts of pinned memory may degrade - * system performance, since it reduces the amount of memory available - * to the system for paging. As a result, this function is best used - * sparingly to allocate staging areas for data exchange between host - * and device. - * - * The Flags parameter enables different options to be specified that - * affect the allocation, as follows. - * - * - CU_MEMHOSTALLOC_PORTABLE: The memory returned by this call will be - * considered as pinned memory by all CUDA contexts, not just the one - * that performed the allocation. - * - CU_MEMHOSTALLOC_DEVICEMAP: Maps the allocation into the CUDA - * address space. The device pointer to the memory may be obtained by - * calling cuMemHostGetDevicePointer(). This feature is available only - * on GPUs with compute capability greater than or equal to 1.1. - * - CU_MEMHOSTALLOC_WRITECOMBINED: Allocates the memory as write-combined - * (WC). WC memory can be transferred across the PCI Express bus more - * quickly on some system con?gurations, but cannot be read efficiently - * by most CPUs. WC memory is a good option for buffers that will be - * written by the CPU and read by the GPU via mapped pinned memory or - * host->device transfers. All of these fags are orthogonal to one - * another: a developer may allocate memory that is portable, mapped - * and/or write-combined with no restrictions. - * - * The CUDA context must have been created with the CU_CTX_MAP_HOST flag - * in order for the CU_MEMHOSTALLOC_MAPPED flag to have any effect. - * - * The CU_MEMHOSTALLOC_MAPPED flag may be specified on CUDA contexts for - * devices that do not support mapped pinned memory. The failure is - * deferred to cuMemHostGetDevicePointer() because the memory may be - * mapped into other CUDA contexts via the CU_MEMHOSTALLOC_PORTABLE flag. - * - * The memory allocated by this function must be freed with cuMemFreeHost(). - * - * \param pp Returned host pointer to page-locked memory. - * \param byte_size Requested allocation size in bytes. - * \param flags Flags for allocation request. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemHostAlloc(void **pp, size_t byte_size, unsigned int flags) -{ - CUresult result = 0; - - result = cuMemHostAlloc(pp, byte_size, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_HOST_ALLOC) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Passes back the device pointer pdptr corresponding to the mapped, - * pinned host buffer p allocated by cuMemHostAlloc. - * - * cuMemHostGetDevicePointer() will fail if the CU_MEMALLOCHOST_DEVICEMAP - * flag was not speci?ed at the time the memory was allocated, or if the - * function is called on a GPU that does not support mapped pinned memory. - * - * Flags provides for future releases. For now, it must be set to 0. - * - * \param pdptr Returned device pointer. - * \param p Host pointer. - * \param flags Options(must be 0). - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemHostGetDevicePointer(CUdeviceptr *pdptr, void *p, unsigned int flags) -{ - CUresult result = 0; - - result = cuMemHostGetDevicePointer(pdptr, p, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_HOST_GET_DEVICE_POINTER) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Passes back the flags p_flags that were specified when allocating the - * pinned host buffer p allocated by cuMemHostAlloc. - * - * cuMemHostGetFlags() will fail if the pointer does not reside in an - * allocation performed by cuMemAllocHost() or cuMemHostAlloc(). - * - * \param p_flags Returned flags word. - * \param p Host pointer. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemHostGetFlags(unsigned int *p_flags, void *p) -{ - CUresult result = 0; - - result = cuMemHostGetFlags(p_flags, p); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_HOST_GET_FLAGS) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemHostRegister(void *p, size_t byte_size, unsigned int flags) -{ - CUresult result = 0; - - result = cuMemHostRegister(p, byte_size, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_HOST_REGISTER) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaMemHostUnregister(void *p) -{ - CUresult result = 0; - - result = cuMemHostUnregister(p); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEM_HOST_UNREGISTER) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Sets the memory range of N 16-bit values to the speci?ed value us. - * - * \param dst_device Destination device pointer. - * \param us Value to set. - * \param n Number of elements. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemsetD16(CUdeviceptr dst_device, unsigned short us, size_t n) -{ - CUresult result = 0; - - result = cuMemsetD16(dst_device, us, n); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D16) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemsetD16Async(CUdeviceptr dst_device, unsigned short us, - size_t n, CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemsetD16Async(dst_device, us, n, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D16_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Sets the 2D memory range of Width 16-bit values to the specified - * value us. Height specifies the number of rows to set, and dst_pitch - * specifies the number of bytes between each row. This function - * performs fastest when the pitch is one that has been passed back - * by cuMemAllocPitch(). - * - * \param dst_device Destination device pointer. - * \param dst_pitch Pitch of destination device pointer. - * \param us Value to set - * \param width Width of row. - * \param height Number of rows - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemsetD2D16(CUdeviceptr dst_device, size_t dst_pitch, - unsigned short us, size_t width, - size_t height) -{ - CUresult result = 0; - - result = cuMemsetD2D16(dst_device, dst_pitch, us, width, height); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D2_D16) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemsetD2D16Async(CUdeviceptr dst_device, size_t dst_pitch, - unsigned short us, size_t width, - size_t height, CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemsetD2D16Async(dst_device, dst_pitch, us, width, height, - h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D2_D16_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Sets the 2D memory range of Width 32-bit values to the specified value - * ui. Height speci?es the number of rows to set, and dstPitch specifies - * the number of bytes between each row. This function performs fastest - * when the pitch is one that has been passed back by cuMemAllocPitch(). - * - * \param dst_device Destination device pointer. - * \param dst_pitch Pitch of destination device pointer. - * \param ui Value to set - * \param width Width of row. - * \param height Number of rows - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemsetD2D32(CUdeviceptr dst_device, size_t dst_pitch, - unsigned int ui, size_t width, size_t height) -{ - CUresult result = 0; - - result = cuMemsetD2D32(dst_device, dst_pitch, ui, width, height); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D2_D32) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemsetD2D32Async(CUdeviceptr dst_device, size_t dst_pitch, - unsigned int ui, size_t width, size_t height, - CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemsetD2D32Async(dst_device, dst_pitch, ui, width, height, - h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D2_D32_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Sets the 2D memory range of Width 8-bit values to the specified value - * uc. Height speci?es the number of rows to set, and dstPitch specifies - * the number of bytes between each row. This function performs fastest - * when the pitch is one that has been passed back by cuMemAllocPitch(). - * - * \param dst_device Destination device pointer. - * \param dst_pitch Pitch of destination device pointer. - * \param uc Value to set - * \param width Width of row. - * \param height Number of rows - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemsetD2D8(CUdeviceptr dst_device, size_t dst_pitch, - unsigned char uc, size_t width, size_t height) -{ - CUresult result = 0; - - result = cuMemsetD2D8(dst_device, dst_pitch, uc, width, height); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D2_D8) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemsetD2D8Async(CUdeviceptr dst_device, size_t dst_pitch, - unsigned char uc, size_t width, size_t height, - CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemsetD2D8Async(dst_device, dst_pitch, uc, width, height, - h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D2_D8_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Sets the memory range of N 32-bit values to the specified value ui. - * - * \param dst_device Destination device pointer. - * \param ui Value to set. - * \param n Number of elements. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemsetD32(CUdeviceptr dst_device, unsigned int ui, size_t n) -{ - CUresult result = 0; - - result = cuMemsetD32(dst_device, ui, n); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D32) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemsetD32Async(CUdeviceptr dst_device, unsigned int ui, - size_t n, CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemsetD32Async(dst_device, ui, n, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D32_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Sets the memory range of N 8-bit values to the specified value ui. - * - * \param dst_device Destination device pointer. - * \param uc Value to set. - * \param n Number of elements. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaMemsetD8(CUdeviceptr dst_device, unsigned char uc, size_t n) -{ - CUresult result = 0; - - result = cuMemsetD8(dst_device, uc, n); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D8) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaMemsetD8Async(CUdeviceptr dst_device, unsigned char uc, - size_t n, CUstream h_stream) -{ - CUresult result = 0; - - result = cuMemsetD8Async(dst_device, uc, n, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_MEMSET_D8_ASYNC) == -1) - goto error; - - return 0; - error: - return -1; -} - -/*****************************Unified_Addressing_API****************************/ - -int SCCudaPointerGetAttribute(void *data, CUpointer_attribute attribute, - CUdeviceptr ptr) -{ - CUresult result = 0; - - result = cuPointerGetAttribute(data, attribute, ptr); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_POINTER_GET_ATTRIBUTE) == -1) - goto error; - - return 0; - error: - return -1; -} - -/*****************************Stream_Management_API****************************/ - -/** - * \brief Creates a stream and returns a handle in ph_stream. Flags is - * required to be 0. - * - * \param ph_stream Returned newly created stream. - * \param flags Parameters for stream creation(must be 0). - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaStreamCreate(CUstream *ph_stream, unsigned int flags) -{ - CUresult result = 0; - - if (ph_stream == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "phStream is NULL"); - goto error; - } - - result = cuStreamCreate(ph_stream, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_STREAM_CREATE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Destroys the stream specified by h_stream. - * - * \param h_stream Stream to destroy. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaStreamDestroy(CUstream h_stream) -{ - CUresult result = 0; - - result = cuStreamDestroy(h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_STREAM_DESTROY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns CUDA_SUCCESS if all operations in the stream specifed by - * h_stream have completed, or CUDA_ERROR_NOT_READY if not. - * - * \param h_stream Stream to query status of. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaStreamQuery(CUstream h_stream) -{ - CUresult result = 0; - - result = cuStreamQuery(h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_STREAM_QUERY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Waits until the device has completed all operations in the stream - * specified by h_stream. - * - * \param h_stream Stream to wait for. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaStreamSynchronize(CUstream h_stream) -{ - CUresult result = 0; - - result = cuStreamSynchronize(h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_STREAM_SYNCHRONIZE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaStreamWaitEvent(CUstream h_stream, CUevent h_event, - unsigned int flags) -{ - CUresult result = 0; - - result = cuStreamWaitEvent(h_stream, h_event, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_STREAM_WAIT_EVENT) == -1) - goto error; - - return 0; - error: - return -1; -} - -/*****************************Event_Management_API*****************************/ - -/** - * \brief Creates an event *ph_event with the flags specified via flags. Valid - * flags include: - * - * CU_EVENT_DEFAULT: Default event creation flag. - * CU_EVENT_BLOCKING_SYNC: Specifies that event should use blocking - * synchronization. - * - * \param ph_event Returns newly created event. - * \param flags Event creation flags. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaEventCreate(CUevent *ph_event, unsigned int flags) -{ - CUresult result = 0; - - if (ph_event == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "ph_event is NULL"); - goto error; - } - - result = cuEventCreate(ph_event, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_EVENT_CREATE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Destroys the event specified by h_event. - * - * \param h_event Event to destroy. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaEventDestroy(CUevent h_event) -{ - CUresult result = 0; - - result = cuEventDestroy(h_event); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_EVENT_DESTROY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Computes the elapsed time between two events (in milliseconds with - * a resolution of around 0.5 microseconds). If either event has not - * been recorded yet, this function returns CUDA_ERROR_NOT_READY. If - * either event has been recorded with a non-zero stream, the result - * is undefined. - * - * \param p_milli_seconds Returned elapsed time in milliseconds. - * \param h_start Starting event. - * \param h_end Ending event. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaEventElapsedTime(float *p_milli_seconds, CUevent h_start, CUevent h_end) -{ - CUresult result = 0; - - if (p_milli_seconds == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_milli_seconds is NULL"); - goto error; - } - - result = cuEventElapsedTime(p_milli_seconds, h_start, h_end); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_EVENT_ELAPSED_TIME) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns CUDA_SUCCESS if the event has actually been recorded, or - * CUDA_ERROR_NOT_READY if not. If cuEventRecord() has not been called - * on this event, the function returns CUDA_ERROR_INVALID_VALUE. - * - * \param h_event Event to query. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaEventQuery(CUevent h_event) -{ - CUresult result = 0; - - result = cuEventQuery(h_event); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_EVENT_QUERY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Records an event. If stream is non-zero, the event is recorded after - * all preceding operations in the stream have been completed; otherwise, - * it is recorded after all preceding operations in the CUDA context have - * been completed. Since operation is asynchronous, cuEventQuery() and/or - * cuEventSynchronize() must be used to determine when the event has - * actually been recorded. - * - * If cuEventRecord() has previously been called and the event has not - * been recorded yet, this function returns CUDA_ERROR_INVALID_VALUE. - * - * \param h_event Event to record. - * \param h_stream Stream to record event for. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaEventRecord(CUevent h_event, CUstream h_stream) -{ - CUresult result = 0; - - result = cuEventRecord(h_event, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_EVENT_RECORD) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Waits until the event has actually been recorded. If cuEventRecord() - * has been called on this event, the function returns - * CUDA_ERROR_INVALID_VALUE. - * - * If cuEventRecord() has previously been called and the event has not - * been recorded yet, this function returns CUDA_ERROR_INVALID_VALUE. - * - * \param h_event Event to wait for. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaEventSynchronize(CUevent h_event) -{ - CUresult result = 0; - - result = cuEventSynchronize(h_event); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_EVENT_SYNCHRONIZE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/***********************Execution_Control_Management_API***********************/ - -/** - * \brief Returns in *pi the integer value of the attribute attrib on the - * kernel given by hfunc. The supported attributes are: - * - * - CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK: The number of threads - * beyond which a launch of the function would fail. This number - * depends on both the function and the device on which the - * function is currently loaded. - * - CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES: The size in bytes of - * statically-allocated shared memory required by this function. - * This does not include dynamically-allocated shared memory - * requested by the user at runtime. - * - CU_FUNC_ATTRIBUTE_CONST_SIZE_BYTES: The size in bytes of - * user-allocated constant memory required by this function. - * - CU_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES: The size in bytes of thread - * local memory used by this function. - * - CU_FUNC_ATTRIBUTE_NUM_REGS: The number of registers used by each - * thread of this function. - * - * \param pi Pointer to an integer which would be updated with the returned - * attribute value. - * \param attrib Attribute requested. - * \param hfunc Function to query attribute of. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaFuncGetAttribute(int *pi, CUfunction_attribute attrib, CUfunction hfunc) -{ - CUresult result = 0; - - if (pi == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "pi is NULL"); - goto error; - } - - result = cuFuncGetAttribute(pi, attrib, hfunc); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_FUNC_GET_ATTRIBUTE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -int SCCudaFuncSetCacheConfig(CUfunction hfunc, CUfunc_cache config) -{ - CUresult result = 0; - - result = cuFuncSetCacheConfig(hfunc, config); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_FUNC_SET_CACHE_CONFIG) == -1) - goto error; - - return 0; - error: - return -1; -} - -int SCCudaLaunchKernel(CUfunction f, unsigned int grid_dim_x, - unsigned int grid_dim_y, unsigned int grid_dim_z, - unsigned int block_dim_x, unsigned int block_dim_y, - unsigned int block_dim_z, unsigned int shared_mem_bytes, - CUstream h_stream, void **kernel_params, void **extra) -{ - CUresult result = 0; - - result = cuLaunchKernel(f, grid_dim_x, grid_dim_y, grid_dim_z, - block_dim_x, block_dim_y, block_dim_z, - shared_mem_bytes, h_stream, kernel_params, extra); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_LAUNCH_KERNEL) == -1) - goto error; - - return 0; - error: - return -1; -} - -/** - * \brief Specifies the x, y, and z dimensions of the thread blocks that are - * created when the kernel given by hfunc is launched. - * - * \param hfunc Kernel to specify dimensions of. - * \param x X dimension. - * \param y Y dimension. - * \param z Z dimension. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaFuncSetBlockShape(CUfunction hfunc, int x, int y, int z) -{ - CUresult result = 0; - - result = cuFuncSetBlockShape(hfunc, x, y, z); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_FUNC_SET_BLOCK_SHAPE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Sets through bytes the amount of dynamic shared memory that will be - * available to each thread block when the kernel given by hfunc is - * launched. - * - * \param hfunc Kernel to specify dynamic shared memory for. - * \param bytes Dynamic shared memory size per thread in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaFuncSetSharedSize(CUfunction hfunc, unsigned int bytes) -{ - CUresult result = 0; - - result = cuFuncSetSharedSize(hfunc, bytes); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_FUNC_SET_SHARED_SIZE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Invokes the kernel f on a 1 x 1 x 1 grid of blocks. The block contains - * the number of threads specified by a previous call to - * cuFuncSetBlockShape(). - * - * \param f Kernel to launch. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaLaunch(CUfunction f) -{ - CUresult result = 0; - - result = cuLaunch(f); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_LAUNCH) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Invokes the kernel f on a grid_width x grid_height grid of blocks. - * Each block contains the number of threads specified by a previous call - * to cuFuncSetBlockShape(). - * - * \param f Kernel to launch. - * \param grid_width Width of grid in blocks. - * \param grib_height Height of grid in blocks. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaLaunchGrid(CUfunction f, int grid_width, int grid_height) -{ - CUresult result = 0; - - result = cuLaunchGrid(f, grid_width, grid_height); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_LAUNCH_GRID) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Invokes the kernel f on a grid_width x grid_height grid of blocks. - * Each block contains the number of threads specified by a previous call - * to cuFuncSetBlockShape(). cuLaunchGridAsync() can optionally be - * associated to a stream by passing a non-zero hStream argument. - * - * \param f Kernel to launch. - * \param grid_width Width of grid in blocks. - * \param grib_height Height of grid in blocks. - * \param h_stream Stream identifier. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaLaunchGridAsync(CUfunction f, int grid_width, int grid_height, - CUstream h_stream) -{ - CUresult result = 0; - - result = cuLaunchGridAsync(f, grid_width, grid_height, h_stream); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_LAUNCH_GRID_ASYNC) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Sets a foating-point parameter that will be specified the next time - * the kernel corresponding to hfunc will be invoked. offset is a byte - * offset. - * - * \param h_func Kernel to add parameter to. - * \param offset Offset to add parameter to argument list. - * \param value Value of parameter. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaParamSetf(CUfunction h_func, int offset, float value) -{ - CUresult result = 0; - - result = cuParamSetf(h_func, offset, value); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_PARAM_SETF) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Sets an integer parameter that will be specified the next time - * the kernel corresponding to hfunc will be invoked. offset is a byte - * offset. - * - * \param h_func Kernel to add parameter to. - * \param offset Offset to add parameter to argument list. - * \param value Value of parameter. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaParamSeti(CUfunction h_func, int offset, unsigned int value) -{ - CUresult result = 0; - - result = cuParamSeti(h_func, offset, value); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_PARAM_SETI) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Sets through numbytes the total size in bytes needed by the function - * parameters of the kernel corresponding to hfunc. - * - * \param h_func Kernel to set parameter size for. - * \param num_bytes Size of paramter list in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaParamSetSize(CUfunction h_func, unsigned int num_bytes) -{ - CUresult result = 0; - - result = cuParamSetSize(h_func, num_bytes); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_PARAM_SET_SIZE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Makes the CUDA array or linear memory bound to the texture reference - * h_tex_ref available to a device program as a texture. In this version - * of CUDA, the texture-reference must be obtained via cuModuleGetTexRef() - * and the tex_unit parameter must be set to CU_PARAM_TR_DEFAULT. - * - * \param h_func Kernel to add texture-reference to. - * \param tex_unit Texture unit (must be CU_PARAM_TR_DEFAULT). - * \param h_tex_ref Texture-reference to add to argument list. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaParamSetTexRef(CUfunction h_func, int tex_unit, CUtexref h_tex_ref) -{ - CUresult result = 0; - - result = cuParamSetTexRef(h_func, tex_unit, h_tex_ref); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_PARAM_SET_TEX_REF) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Copies an arbitrary amount of data (specified in numbytes) from ptr - * into the parameter space of the kernel corresponding to hfunc. - * offset is a byte offset. - * - * \param h_func Kernel to add data to. - * \param offset Offset to add data to argument list. - * \param ptr Pointer to arbitrary data. - * \param num_bytes Size of data to copy in bytes. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaParamSetv(CUfunction h_func, int offset, void *ptr, - unsigned int num_bytes) -{ - CUresult result = 0; - - if (ptr == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "ptr is NULL"); - goto error; - } - - result = cuParamSetv(h_func, offset, ptr, num_bytes); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_PARAM_SETV) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/***********************Texture_Reference_Management_API***********************/ - -/** - * \brief Creates a texture reference and returns its handle in *pTexRef. Once - * created, the application must call cuTexRefSetArray() or cuTexRefSetAddress() - * to associate the reference with allocated memory. Other texture reference - * functions are used to specify the format and interpretation (addressing, - * filtering, etc.) to be used when the memory is read through this texture - * reference. To associate the texture reference with a texture ordinal for - * a given function, the application should call cuParamSetTexRef(). - * - * \param p_tex_ref Returned texture reference - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefCreate(CUtexref *p_tex_ref) -{ - CUresult result = 0; - - if (p_tex_ref == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_tex_ref is NULL"); - goto error; - } - - result = cuTexRefCreate(p_tex_ref); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_CREATE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Destroys the texture reference specified by hTexRef. - * - * \param h_tex_ref Texture reference to destroy - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefDestroy(CUtexref h_tex_ref) -{ - CUresult result = 0; - - result = cuTexRefDestroy(h_tex_ref); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_DESTROY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *pdptr the base address bound to the texture reference - * hTexRef, or returns CUDA_ERROR_INVALID_VALUE if the texture reference - * is not bound to any device memory range. - * - * \param pdptr Returned device address - * \param h_tex_ref Texture reference - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefGetAddress(CUdeviceptr *pdptr, CUtexref h_tex_ref) -{ - CUresult result = 0; - - if (pdptr == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "pdptr is NULL"); - goto error; - } - - result = cuTexRefGetAddress(pdptr, h_tex_ref); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_GET_ADDRESS) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *pam the addressing mode corresponding to the dimension - * dim of the texture reference hTexRef. Currently, the only valid value - * for dim are 0 and 1. - * - * \param pam Returned addressing mode - * \param h_tex_ref Texture reference - * \param dim Dimension - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefGetAddressMode(CUaddress_mode *pam, CUtexref h_tex_ref, int dim) -{ - CUresult result = 0; - - if (pam == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "pam is NULL"); - goto error; - } - - result = cuTexRefGetAddressMode(pam, h_tex_ref, dim); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_GET_ADDRESS_MODE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *phArray the CUDA array bound to the texture reference - * hTexRef, or returns CUDA_ERROR_INVALID_VALUE if the texture reference - * is not bound to any CUDA array. - * - * \param ph_array Returned array - * \param h_tex_ref Texture reference - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefGetArray(CUarray *ph_array, CUtexref h_tex_ref) -{ - CUresult result = 0; - - if (ph_array == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "ph_array is NULL"); - goto error; - } - - result = cuTexRefGetArray(ph_array, h_tex_ref); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_GET_ARRAY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *pfm the filtering mode of the texture reference hTexRef. - * - * \param pfm Returned filtering mode - * \param h_tex_ref Texture reference - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefGetFilterMode(CUfilter_mode *pfm, CUtexref h_tex_ref) -{ - CUresult result = 0; - - if (pfm == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "pfm is NULL"); - goto error; - } - - result = cuTexRefGetFilterMode(pfm, h_tex_ref); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_GET_FILTER_MODE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *pFlags the flags of the texture reference hTexRef. - * - * \param p_flags Returned flags - * \param h_tex_ref Texture reference - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefGetFlags(unsigned int *p_flags, CUtexref h_tex_ref) -{ - CUresult result = 0; - - if (p_flags == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_flags is NULL"); - goto error; - } - - result = cuTexRefGetFlags(p_flags, h_tex_ref); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_GET_FLAGS) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Returns in *pFormat and *pNumChannels the format and number of - * components of the CUDA array bound to the texture reference hTexRef. - * If pFormat or pNumChannels is NULL, it will be ignored. - * - * \param p_format Returned format - * \param p_num_channels Returned number of components - * \param h_tex_ref Texture reference - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefGetFormat(CUarray_format *p_format, int *p_num_channels, - CUtexref h_tex_ref) -{ - CUresult result = 0; - - if (p_format == NULL || p_num_channels == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "p_format == NULL || p_num_channels == NULL"); - goto error; - } - - result = cuTexRefGetFormat(p_format, p_num_channels, h_tex_ref); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_GET_FORMAT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Binds a linear address range to the texture reference hTexRef. Any - * previous address or CUDA array state associated with the texture - * reference is superseded by this function. Any memory previously - * bound to hTexRef is unbound. - * - * Since the hardware enforces an alignment requirement on texture - * base addresses, cuTexRefSetAddress() passes back a byte offset in - * *ByteOffset that must be applied to texture fetches in order to read - * from the desired memory. This offset must be divided by the texel - * size and passed to kernels that read from the texture so they can be - * applied to the tex1Dfetch() function. - * - * If the device memory pointer was returned from cuMemAlloc(), the - * offset is guaranteed to be 0 and NULL may be passed as the - * ByteOffset parameter. - * - * \param byte_offset Returned byte offset - * \param h_tex_ref Texture reference to bind - * \param dptr Device pointer to bind - * \param bytes Size of memory to bind in bytes - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefSetAddress(size_t *byte_offset, CUtexref h_tex_ref, - CUdeviceptr dptr, unsigned int bytes) -{ - CUresult result = 0; - - if (byte_offset == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument supplied. " - "byte_offset is NULL"); - goto error; - } - - result = cuTexRefSetAddress(byte_offset, h_tex_ref, dptr, bytes); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_SET_ADDRESS) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Binds a linear address range to the texture reference hTexRef. Any - * previous address or CUDA array state associated with the texture - * reference is superseded by this function. Any memory previously bound - * to hTexRef is unbound. - * - * Using a tex2D() function inside a kernel requires a call to either - * cuTexRefSetArray() to bind the corresponding texture reference to an - * array, or cuTexRefSetAddress2D() to bind the texture reference to - * linear memory. - * - * Function calls to cuTexRefSetFormat() cannot follow calls to - * cuTexRefSetAddress2D() for the same texture reference. - * - * It is required that dptr be aligned to the appropriate hardware- - * specific texture alignment. You can query this value using the device - * attribute CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT. If an unaligned dptr - * is supplied, CUDA_ERROR_INVALID_VALUE is returned. - * - * \param h_tex_ref Texture reference to bind - * \param desc Descriptor of CUDA array - * \param dptr Device pointer to bind - * \param pitch Line pitch in bytes - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefSetAddress2D(CUtexref h_tex_ref, const CUDA_ARRAY_DESCRIPTOR *desc, - CUdeviceptr dptr, unsigned int pitch) -{ - CUresult result = 0; - - result = cuTexRefSetAddress2D(h_tex_ref, desc, dptr, pitch); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_SET_ADDRESS_2D) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Specifies the addressing mode am for the given dimension dim of the - * texture reference hTexRef. If dim is zero, the addressing mode is - * applied to the first parameter of the functions used to fetch from - * the texture; if dim is 1, the second, and so on. CUaddress_mode is - * defined as: - * - * typedef enum CUaddress_mode_enum { - * CU_TR_ADDRESS_MODE_WRAP = 0, - * CU_TR_ADDRESS_MODE_CLAMP = 1, - * CU_TR_ADDRESS_MODE_MIRROR = 2, - * } CUaddress_mode; - * - * \param h_tex_ref Texture reference - * \param dim Dimension - * \param am Addressing mode to set - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefSetAddressMode(CUtexref h_tex_ref, int dim, CUaddress_mode am) -{ - CUresult result = 0; - - result = cuTexRefSetAddressMode(h_tex_ref, dim, am); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_SET_ADDRESS_MODE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Binds the CUDA array hArray to the texture reference hTexRef. Any - * previous address or CUDA array state associated with the texture - * reference is superseded by this function. Flags must be set to - * CU_TRSA_OVERRIDE_FORMAT. Any CUDA array previously bound to hTexRef - * is unbound. - * - * \param h_tex_ref Texture reference to bind - * \param h_array Array to bind - * \param flags Options (must be CU_TRSA_OVERRIDE_FORMAT) - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefSetArray(CUtexref h_tex_ref, CUarray h_array, unsigned int flags) -{ - CUresult result = 0; - - result = cuTexRefSetArray(h_tex_ref, h_array, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_SET_ARRAY) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Specifies the filtering mode fm to be used when reading memory through - * the texture reference hTexRef. CUfilter_mode_enum is defined as: - * - * typedef enum CUfilter_mode_enum { - * CU_TR_FILTER_MODE_POINT = 0, - * CU_TR_FILTER_MODE_LINEAR = 1 - * } CUfilter_mode; - * - * \param h_tex_ref Texture reference - * \param fm Filtering mode to set - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefSetFilterMode(CUtexref h_tex_ref, CUfilter_mode fm) -{ - CUresult result = 0; - - result = cuTexRefSetFilterMode(h_tex_ref, fm); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_SET_FILTER_MODE) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Specifies optional flags via Flags to specify the behavior of data - * returned through the texture reference hTexRef. The valid flags are: - * - * * CU_TRSF_READ_AS_INTEGER, which suppresses the default behavior of - * having the texture promote integer data to floating point data in - * the range [0, 1]; - * * CU_TRSF_NORMALIZED_COORDINATES, which suppresses the default - * behavior of having the texture coordinates range from [0, Dim) where - * Dim is the width or height of the CUDA array. Instead, the texture - * coordinates [0, 1.0) reference the entire breadth of the array - * dimension; - * - * \param h_tex_ref Texture reference - * \param flags Optional flags to set - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefSetFlags(CUtexref h_tex_ref, unsigned int flags) -{ - CUresult result = 0; - - result = cuTexRefSetFlags(h_tex_ref, flags); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_SET_FLAGS) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/** - * \brief Specifies the format of the data to be read by the texture reference - * hTexRef. fmt and NumPackedComponents are exactly analogous to the - * Format and NumChannels members of the CUDA_ARRAY_DESCRIPTOR structure: - * They specify the format of each component and the number of components - * per array element. - * - * \param h_tex_ref Texture reference - * \param fmt Format to set - * \param num_packed_components Number of components per array element - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCCudaTexRefSetFormat(CUtexref h_tex_ref, CUarray_format fmt, - int num_packed_components) -{ - CUresult result = 0; - - result = cuTexRefSetFormat(h_tex_ref, fmt, num_packed_components); - if (SCCudaHandleRetValue(result, SC_CUDA_CU_TEX_REF_SET_FORMAT) == -1) - goto error; - - return 0; - - error: - return -1; -} - -/**************************Cuda_Env_Initialization_API*************************/ - -/** - * \brief Initialize the CUDA Environment for the engine. - * - * \retval 0 On successfully initializing the CUDA environment for the engine. - * \retval -1 On failure. - */ -int SCCudaInitCudaEnvironment(void) -{ - if (devices != NULL) { - SCLogWarning(SC_ERR_CUDA_ERROR, "CUDA engine already initalized!!!!"); - return 0; - } - - if (SCCudaInit(0) == -1) { - SCLogError(SC_ERR_CUDA_ERROR, "Error initializing CUDA API. SCCudaInit() " - "returned -1"); - goto error; - } - - if ( (devices = SCCudaGetDevices()) == NULL) { - SCLogError(SC_ERR_CUDA_ERROR, "Error getting CUDA device list. " - "SCCudaGetDevices() returned NULL"); - goto error; - } - - SCCudaPrintBasicDeviceInfo(devices); - - return 0; - - error: - SCCudaDeAllocSCCudaDevices(devices); - return -1; -} - -/**********************************Cuda_Utility********************************/ - -/** - * \brief List the cuda cards on the system. - * - */ -void SCCudaListCards(void) -{ - int i = 0; - - if (devices == NULL) { - SCLogWarning(SC_ERR_CUDA_ERROR, "CUDA engine not initalized! Please " - "initialize the cuda environment using " - "SCCudaInitCudaEnvironment()."); - return; - } - - printf("CUDA Cards recognized by the suricata CUDA module - \n"); - printf("|-----------------------------------------------------------------------------|\n"); - printf("| %-10s | %-20s | %-10s | %-10s | %-13s |\n", - "Device Id", " Device Name", " Multi-", "Clock Rate", "Cuda Compute"); - printf("| %-10s | %-20s | %-10s | %-10s | %-13s |\n", - "", "", "Processors", " (MHz)", "Capability"); - printf("|-----------------------------------------------------------------------------|\n"); - for (i = 0; i < devices->count; i++) { - printf("| %-10d | %-20s | %-10d | %-10d | %d.%-11d |\n", - i, - devices->devices[i]->name, - devices->devices[i]->attr_multiprocessor_count, - devices->devices[i]->attr_clock_rate/1000, - devices->devices[i]->major_rev, - devices->devices[i]->minor_rev); - } - printf("|-----------------------------------------------------------------------------|\n"); - - return; -} - -int SCCudaIsCudaDeviceIdValid(int cuda_device_id) -{ - if (devices == NULL) { - SCLogWarning(SC_ERR_CUDA_ERROR, "CUDA engine not initalized! Please " - "initialize the cuda environment using " - "SCCudaInitCudaEnvironment()."); - return 0; - } - - return (cuda_device_id < devices->count); -} - -/**********************************Unittests***********************************/ - -int SCCudaTest01(void) -{ - SCCudaDevices *devices = SCCudaGetDeviceList(); - - if (devices == NULL) - return 0; - - return (devices->count != 0); -} - -#if defined(__x86_64__) || defined(__ia64__) -/** - * extern "C" __global__ void SCCudaSuricataTest(int *input, int *output) - * { - * output[threadIdx.x] = input[threadIdx.x] * 2; - * } - */ -static const char *sc_cuda_test_kernel_64_bit = - " .version 1.4\n" - " .target sm_10, map_f64_to_f32\n" - " .entry SCCudaSuricataTest (\n" - " .param .u64 __cudaparm_SCCudaSuricataTest_input,\n" - " .param .u64 __cudaparm_SCCudaSuricataTest_output)\n" - "{\n" - " .reg .u32 %r<5>;\n" - " .reg .u64 %rd<8>;\n" - " .loc 15 1 0\n" - " $LBB1_SCCudaSuricataTest:\n" - " .loc 15 3 0\n" - " cvt.u32.u16 %r1, %tid.x;\n" - " cvt.u64.u32 %rd1, %r1;\n" - " mul.lo.u64 %rd2, %rd1, 4;\n" - " ld.param.u64 %rd3, [__cudaparm_SCCudaSuricataTest_input];\n" - " add.u64 %rd4, %rd3, %rd2;\n" - " ld.global.s32 %r2, [%rd4+0];\n" - " mul.lo.s32 %r3, %r2, 2;\n" - " ld.param.u64 %rd5, [__cudaparm_SCCudaSuricataTest_output];\n" - " add.u64 %rd6, %rd5, %rd2;\n" - " st.global.s32 [%rd6+0], %r3;\n" - " .loc 15 4 0\n" - " exit;\n" - " $LDWend_SCCudaSuricataTest:\n" - "} // SCCudaSuricataTest\n" - "\n"; -#else -/** - * extern "C" __global__ void SCCudaSuricataTest(int *input, int *output) - * { - * output[threadIdx.x] = input[threadIdx.x] * 2; - * } - */ -static const char *sc_cuda_test_kernel_32_bit = - " .version 1.4\n" - " .target sm_10, map_f64_to_f32\n" - " .entry SCCudaSuricataTest (\n" - " .param .u32 __cudaparm_SCCudaSuricataTest_input,\n" - " .param .u32 __cudaparm_SCCudaSuricataTest_output)\n" - " {\n" - " .reg .u16 %rh<3>;\n" - " .reg .u32 %r<9>;\n" - " .loc 15 2 0\n" - "$LBB1_SCCudaSuricataTest:\n" - " .loc 15 4 0\n" - " mov.u16 %rh1, %tid.x;\n" - " mul.wide.u16 %r1, %rh1, 4;\n" - " ld.param.u32 %r2, [__cudaparm_SCCudaSuricataTest_input];\n" - " add.u32 %r3, %r2, %r1;\n" - " ld.global.s32 %r4, [%r3+0];\n" - " mul.lo.s32 %r5, %r4, 2;\n" - " ld.param.u32 %r6, [__cudaparm_SCCudaSuricataTest_output];\n" - " add.u32 %r7, %r6, %r1;\n" - " st.global.s32 [%r7+0], %r5;\n" - " .loc 15 5 0\n" - " exit;\n" - "$LDWend_SCCudaSuricataTest:\n" - " } // SCCudaSuricataTest\n" - ""; -#endif - -int SCCudaTest02(void) -{ -#define ALIGN_UP(offset, alignment) do { \ - (offset) = ((offset) + (alignment) - 1) & ~((alignment) - 1); \ - } while (0) -#define N 256 - CUcontext context; - CUmodule module; - CUfunction kernel; - CUdeviceptr d_input, d_output; - int h_input[N]; - int h_result[N]; - SCCudaDevices *devices = SCCudaGetDeviceList(); - int result = 0; - int offset = 0; - int i = 0; - - if (devices == NULL) - goto end; - - if (devices->count == 0) - goto end; - - if (SCCudaCtxCreate(&context, 0, devices->devices[0]->device) == -1) - goto end; - -#if defined(__x86_64__) || defined(__ia64__) - if (SCCudaModuleLoadData(&module, (void *)sc_cuda_test_kernel_64_bit) == -1) - goto end; -#else - if (SCCudaModuleLoadData(&module, (void *)sc_cuda_test_kernel_32_bit) == -1) - goto end; -#endif - - if (SCCudaModuleGetFunction(&kernel, module, "SCCudaSuricataTest") == -1) - goto end; - - for (i = 0; i < N; i++) - h_input[i] = i * 2; - - if (SCCudaMemAlloc(&d_input, N * sizeof(int)) == -1) - goto end; - - if (SCCudaMemcpyHtoD(d_input, h_input, N * sizeof(int)) == -1) - goto end; - - if (SCCudaMemAlloc(&d_output, N * sizeof(int)) == -1) - goto end; - - offset = 0; - ALIGN_UP(offset, __alignof(void *)); - if (SCCudaParamSetv(kernel, offset, (void *)&d_input, sizeof(void *)) == -1) - goto end; - offset += sizeof(void *); - - ALIGN_UP(offset, __alignof(void *)); - if (SCCudaParamSetv(kernel, offset, (void *)&d_output, sizeof(void *)) == -1) - goto end; - offset += sizeof(void *); - - if (SCCudaParamSetSize(kernel, offset) == -1) - goto end; - - if (SCCudaFuncSetBlockShape(kernel, N, 1, 1) == -1) - goto end; - - if (SCCudaLaunchGrid(kernel, 1, 1) == -1) - goto end; - - if (SCCudaMemcpyDtoH(h_result, d_output, N * sizeof(int)) == -1) - goto end; - - for (i = 0; i < N; i++) - h_input[i] = i * 4; - - for (i = 0; i < N; i++) { - if (h_result[i] != h_input[i]) - goto end; - } - - if (SCCudaMemFree(d_input) == -1) - goto end; - - if (SCCudaMemFree(d_output) == -1) - goto end; - - if (SCCudaModuleUnload(module) == -1) - goto end; - - if (SCCudaCtxDestroy(context) == -1) - goto end; - - result = 1; - - end: - return result; -} - -void SCCudaRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SCCudaTest01", SCCudaTest01, 1); - UtRegisterTest("SCCudaTest02", SCCudaTest02, 1); -#endif - - return; -} - -#endif /* __SC_CUDA_SUPPORT__ */ diff --git a/framework/src/suricata/src/util-cuda.h b/framework/src/suricata/src/util-cuda.h deleted file mode 100644 index 8e544fd0..00000000 --- a/framework/src/suricata/src/util-cuda.h +++ /dev/null @@ -1,323 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_CUDA__H__ -#define __UTIL_CUDA__H__ - -#ifdef __SC_CUDA_SUPPORT__ - -#include - -#define SC_CUDA_DEFAULT_DEVICE 0 -#define SC_CUDA_DEVICE_NAME_MAX_LEN 128 - -typedef struct SCCudaDevice_ { - /* device id */ - CUdevice device; - - /* device name */ - char name[SC_CUDA_DEVICE_NAME_MAX_LEN]; - - /* device compute capability */ - int major_rev; - int minor_rev; - - /* device properties */ - CUdevprop prop; - - /* device total memory */ - size_t bytes; - - /* device attributes. We could have used a fixed int array table to hold - * the attributes, but it is better we specify it exclusively this way, - * since the usage would be less error prone */ - int attr_max_threads_per_block; - int attr_max_block_dim_x; - int attr_max_block_dim_y; - int attr_max_block_dim_z; - int attr_max_grid_dim_x; - int attr_max_grid_dim_y; - int attr_max_grid_dim_z; - int attr_max_shared_memory_per_block; - int attr_total_constant_memory; - int attr_warp_size; - int attr_max_pitch; - int attr_max_registers_per_block; - int attr_clock_rate; - int attr_texture_alignment; - int attr_gpu_overlap; - int attr_multiprocessor_count; - int attr_kernel_exec_timeout; - int attr_integrated; - int attr_can_map_host_memory; - int attr_compute_mode; -} SCCudaDevice; - - -typedef struct SCCudaDevices_ { - int count; - SCCudaDevice **devices; -} SCCudaDevices; - - -/**************************Cuda_Initialization_API**************************/ -int SCCudaInit(unsigned int flags); - -/***************************Version_Management_API***************************/ -int SCCudaDriverGetVersion(int *driver_version); - -/***************************Device_Management_API****************************/ -int SCCudaDeviceComputeCapability(int *major, int *minor, CUdevice dev); -int SCCudaDeviceGet(CUdevice *device, int ordinal); -int SCCudaDeviceGetAttribute(int *pi, CUdevice_attribute attrib, - CUdevice dev); -int SCCudaDeviceGetCount(int *count); -int SCCudaDeviceGetName(char *name, int len, CUdevice dev); -int SCCudaDeviceGetProperties(CUdevprop *prop, CUdevice dev); -int SCCudaDeviceTotalMem(size_t *bytes, CUdevice dev); - -void SCCudaPrintDeviceList(SCCudaDevices *); -void SCCudaPrintBasicDeviceInfo(SCCudaDevices *); -SCCudaDevices *SCCudaGetDeviceList(void); - -/***************************Context_Management_API***************************/ -int SCCudaCtxCreate(CUcontext *pctx, unsigned int flags, CUdevice dev); -int SCCudaCtxDestroy(CUcontext ctx); -int SCCudaCtxGetApiVersion(CUcontext ctx, unsigned int *version); -int SCCudaCtxGetCacheConfig(CUfunc_cache *pconfig); -int SCCudaCtxGetCurrent(CUcontext *pctx); -int SCCudaCtxGetDevice(CUdevice *device); -int SCCudaCtxGetLimit(size_t *pvalue, CUlimit limit); -int SCCudaCtxPopCurrent(CUcontext *pctx); -int SCCudaCtxPushCurrent(CUcontext ctx); -int SCCudaCtxSetCacheConfig(CUfunc_cache config); -int SCCudaCtxSetCurrent(CUcontext ctx); -int SCCudaCtxSetLimit(CUlimit limit, size_t value); -int SCCudaCtxSynchronize(void); -int SCCudaCtxAttach(CUcontext *pctx, unsigned int flags); -int SCCudaCtxDetach(CUcontext ctx); - -/***************************Module_Management_API****************************/ -int SCCudaModuleGetFunction(CUfunction *hfunc, CUmodule hmod, - const char *name); -int SCCudaModuleGetGlobal(CUdeviceptr *dptr, size_t *bytes, CUmodule hmod, - const char *name); -int SCCudaModuleGetSurfRef(CUsurfref *p_surf_ref, CUmodule hmod, - const char *name); -int SCCudaModuleGetTexRef(CUtexref *p_tex_ref, CUmodule hmod, - const char *name); -int SCCudaModuleLoad(CUmodule *module, const char *fname); -int SCCudaModuleLoadData(CUmodule *module, const void *image); -int SCCudaModuleLoadDataEx(CUmodule *module, const void *image, - unsigned int num_options, CUjit_option *options, - void **option_values); -int SCCudaModuleLoadFatBinary(CUmodule *module, const void *fat_cubin); -int SCCudaModuleUnload(CUmodule hmod); - -/**************************Memory_Management_API*****************************/ -int SCCudaArray3DCreate(CUarray *p_handle, - const CUDA_ARRAY3D_DESCRIPTOR *p_allocate_array); -int SCCudaArray3DGetDescriptor(CUDA_ARRAY3D_DESCRIPTOR *p_array_descriptor, - CUarray h_array); -int SCCudaArrayCreate(CUarray *p_handle, - const CUDA_ARRAY_DESCRIPTOR *p_allocate_array); -int SCCudaArrayDestroy(CUarray h_array); -int SCCudaArrayGetDescriptor(CUDA_ARRAY_DESCRIPTOR *p_array_descriptor, - CUarray h_array); -int SCCudaDeviceGetByPCIBusId(CUdevice *dev, char *pci_bus_id); -int SCCudaDeviceGetPCIBusId(char *pci_bus_id, int len, CUdevice dev); -int SCCudaIpcCloseMemHandle(CUdeviceptr dptr); -int SCCudaIpcGetEventHandle(CUipcEventHandle *p_handle, CUevent event); -int SCCudaIpcGetMemHandle(CUipcMemHandle *p_handle, CUdeviceptr dptr); -int SCCudaIpcOpenEventHandle(CUevent *ph_event, CUipcEventHandle handle); -int SCCudaIpcOpenMemHandle(CUdeviceptr *pdptr, CUipcMemHandle handle, - unsigned int flags); -int SCCudaMemAlloc(CUdeviceptr *dptr, size_t byte_size); -int SCCudaMemAllocHost(void **pp, size_t byte_size); -int SCCudaMemAllocPitch(CUdeviceptr *dptr, size_t *p_pitch, - size_t width_in_bytes, - size_t height, - unsigned int element_size_bytes); -int SCCudaMemcpy(CUdeviceptr dst, CUdeviceptr src, size_t byte_count); -int SCCudaMemcpy2D(const CUDA_MEMCPY2D *p_copy); -int SCCudaMemcpy2DAsync(const CUDA_MEMCPY2D *p_copy, CUstream h_stream); -int SCCudaMemcpy2DUnaligned(const CUDA_MEMCPY2D *p_copy); -int SCCudaMemcpy3D(const CUDA_MEMCPY3D *p_copy); -int SCCudaMemcpy3DAsync(const CUDA_MEMCPY3D *p_copy, CUstream h_stream); -int SCCudaMemcpy3DPeer(const CUDA_MEMCPY3D_PEER *p_copy); -int SCCudaMemcpy3DPeerAsync(const CUDA_MEMCPY3D_PEER *p_copy, - CUstream h_stream); -int SCCudaMemcpyAsync(CUdeviceptr dst, CUdeviceptr src, size_t byte_count, - CUstream h_stream); -int SCCudaMemcpyAtoA(CUarray dst_array, size_t dst_offset, - CUarray src_array, size_t src_offset, - size_t byte_count); -int SCCudaMemcpyAtoD(CUdeviceptr dst_device, CUarray src_array, - size_t src_offset, size_t byte_count); -int SCCudaMemcpyAtoH(void *dst_host, CUarray src_array, size_t src_offset, - size_t byte_count); -int SCCudaMemcpyAtoHAsync(void *dst_host, CUarray src_array, - size_t src_offset, size_t byte_count, - CUstream h_stream); -int SCCudaMemcpyDtoA(CUarray dst_array, size_t dst_offset, - CUdeviceptr src_device, size_t byte_count); -int SCCudaMemcpyDtoD(CUdeviceptr dst_device, CUdeviceptr src_device, - size_t byte_count); -int SCCudaMemcpyDtoDAsync(CUdeviceptr dst_device, CUdeviceptr src_device, - size_t byte_count, CUstream h_stream); -int SCCudaMemcpyDtoH(void *dst_host, CUdeviceptr src_device, - size_t byte_count); -int SCCudaMemcpyDtoHAsync(void *dst_host, CUdeviceptr src_device, - size_t byte_count, CUstream h_stream); -int SCCudaMemcpyHtoA(CUarray dst_array, size_t dst_offset, - const void *src_host, size_t byte_count); -int SCCudaMemcpyHtoAAsync(CUarray dst_array, size_t dst_offset, - const void *src_host, size_t byte_count, - CUstream h_stream); -int SCCudaMemcpyHtoD(CUdeviceptr dst_device, const void *src_host, - size_t byte_count); -int SCCudaMemcpyHtoDAsync(CUdeviceptr dst_device, const void *src_host, - size_t byte_count, CUstream h_stream); -int SCCudaMemcpyPeer(CUdeviceptr dst_device, CUcontext dst_context, - CUdeviceptr src_device, CUcontext src_context, - size_t byte_count); -int SCCudaMemcpyPeerAsync(CUdeviceptr dst_device, CUcontext dst_context, - CUdeviceptr src_device, CUcontext src_context, - size_t byte_count, CUstream h_stream); -int SCCudaMemFree(CUdeviceptr dptr); -int SCCudaMemFreeHost(void *p); -int SCCudaMemGetAddressRange(CUdeviceptr *pbase, size_t *psize, - CUdeviceptr dptr); -int SCCudaMemGetInfo(size_t *free, size_t *total); -int SCCudaMemHostAlloc(void **pp, size_t byte_size, unsigned int flags); -int SCCudaMemHostGetDevicePointer(CUdeviceptr *pdptr, void *p, - unsigned int flags); -int SCCudaMemHostGetFlags(unsigned int *p_flags, void *p); -int SCCudaMemHostRegister(void *p, size_t byte_size, unsigned int flags); -int SCCudaMemHostUnregister(void *p); -int SCCudaMemsetD16(CUdeviceptr dst_device, unsigned short us, size_t n); -int SCCudaMemsetD16Async(CUdeviceptr dst_device, unsigned short us, - size_t n, CUstream h_stream); -int SCCudaMemsetD2D16(CUdeviceptr dst_device, size_t dst_pitch, - unsigned short us, size_t width, - size_t height); -int SCCudaMemsetD2D16Async(CUdeviceptr dst_device, size_t dst_pitch, - unsigned short us, size_t width, - size_t height, CUstream h_stream); -int SCCudaMemsetD2D32(CUdeviceptr dst_device, size_t dst_pitch, - unsigned int ui, size_t width, size_t height); -int SCCudaMemsetD2D32Async(CUdeviceptr dst_device, size_t dst_pitch, - unsigned int ui, size_t width, size_t height, - CUstream h_stream); -int SCCudaMemsetD2D8(CUdeviceptr dst_device, size_t dst_pitch, - unsigned char uc, size_t width, size_t height); -int SCCudaMemsetD2D8Async(CUdeviceptr dst_device, size_t dst_pitch, - unsigned char uc, size_t width, size_t height, - CUstream h_stream); -int SCCudaMemsetD32(CUdeviceptr dst_device, unsigned int ui, size_t n); -int SCCudaMemsetD32Async(CUdeviceptr dst_device, unsigned int ui, - size_t n, CUstream h_stream); -int SCCudaMemsetD8(CUdeviceptr dst_device, unsigned char uc, size_t n); -int SCCudaMemsetD8Async(CUdeviceptr dst_device, unsigned char uc, - size_t n, CUstream h_stream); - -/***************************Unified_Addressing_API****************************/ - -int SCCudaPointerGetAttribute(void *data, CUpointer_attribute attribute, - CUdeviceptr ptr); - -/***************************Stream_Management_API****************************/ -int SCCudaStreamCreate(CUstream *ph_stream, unsigned int flags); -int SCCudaStreamDestroy(CUstream h_stream); -int SCCudaStreamQuery(CUstream h_stream); -int SCCudaStreamSynchronize(CUstream h_stream); -int SCCudaStreamWaitEvent(CUstream h_stream, CUevent h_event, - unsigned int flags); - -/***************************Event_Management_API*****************************/ -int SCCudaEventCreate(CUevent *ph_event, unsigned int flags); -int SCCudaEventDestroy(CUevent h_event); -int SCCudaEventElapsedTime(float *p_milli_seconds, CUevent h_start, - CUevent h_end); -int SCCudaEventQuery(CUevent h_event); -int SCCudaEventRecord(CUevent h_event, CUstream h_stream); -int SCCudaEventSynchronize(CUevent h_event); - -/***********************Execution_Control_Management_API***********************/ -int SCCudaFuncGetAttribute(int *pi, CUfunction_attribute attrib, - CUfunction hfunc); -int SCCudaFuncSetCacheConfig(CUfunction hfunc, CUfunc_cache config); -int SCCudaLaunchKernel(CUfunction f, unsigned int grid_dim_x, - unsigned int grid_dim_y, unsigned int grid_dim_z, - unsigned int block_dim_x, unsigned int block_dim_y, - unsigned int block_dim_z, unsigned int shared_mem_bytes, - CUstream h_stream, void **kernel_params, void **extra); -int SCCudaFuncSetBlockShape(CUfunction hfunc, int x, int y, int z); -int SCCudaFuncSetSharedSize(CUfunction hfunc, unsigned int bytes); -int SCCudaLaunch(CUfunction f); -int SCCudaLaunchGrid(CUfunction f, int grid_width, int grid_height); -int SCCudaLaunchGridAsync(CUfunction f, int grid_width, int grid_height, - CUstream h_stream); -int SCCudaParamSetf(CUfunction h_func, int offset, float value); -int SCCudaParamSeti(CUfunction h_func, int offset, unsigned int value); -int SCCudaParamSetSize(CUfunction h_func, unsigned int num_bytes); -int SCCudaParamSetTexRef(CUfunction h_func, int tex_unit, CUtexref h_tex_ref); -int SCCudaParamSetv(CUfunction h_func, int offset, void *ptr, - unsigned int num_bytes); - -/*********************Texture_Reference_Management_API***********************/ -int SCCudaTexRefCreate(CUtexref *p_tex_ref); -int SCCudaTexRefDestroy(CUtexref h_tex_ref); -int SCCudaTexRefGetAddress(CUdeviceptr *pdptr, CUtexref h_tex_ref); -int SCCudaTexRefGetAddressMode(CUaddress_mode *pam, CUtexref h_tex_ref, - int dim); -int SCCudaTexRefGetArray(CUarray *ph_array, CUtexref h_tex_ref); -int SCCudaTexRefGetFilterMode(CUfilter_mode *pfm, CUtexref h_tex_ref); -int SCCudaTexRefGetFlags(unsigned int *p_flags, CUtexref h_tex_ref); -int SCCudaTexRefGetFormat(CUarray_format *p_format, int *p_num_channels, - CUtexref h_tex_ref); -int SCCudaTexRefSetAddress(size_t *byte_offset, CUtexref h_tex_ref, - CUdeviceptr dptr, unsigned int bytes); -int SCCudaTexRefSetAddress2D(CUtexref h_tex_ref, - const CUDA_ARRAY_DESCRIPTOR *desc, - CUdeviceptr dptr, unsigned int pitch); -int SCCudaTexRefSetAddressMode(CUtexref h_tex_ref, int dim, CUaddress_mode am); -int SCCudaTexRefSetArray(CUtexref h_tex_ref, CUarray h_array, - unsigned int flags); -int SCCudaTexRefSetFilterMode(CUtexref h_tex_ref, CUfilter_mode fm); -int SCCudaTexRefSetFlags(CUtexref h_tex_ref, unsigned int flags); -int SCCudaTexRefSetFormat(CUtexref h_tex_ref, CUarray_format fmt, - int num_packed_components); - -/************************Cuda_Env_Initialization_API*************************/ -int SCCudaInitCudaEnvironment(void); - -/********************************Cuda_Utility********************************/ -void SCCudaListCards(void); -int SCCudaIsCudaDeviceIdValid(int cuda_device_id); - -/********************************Unittests***********************************/ -void SCCudaRegisterTests(void); - -#endif /* __SC_CUDA_SUPPORT__ */ -#endif /* __UTIL_CUDA_H__ */ diff --git a/framework/src/suricata/src/util-daemon.c b/framework/src/suricata/src/util-daemon.c deleted file mode 100644 index 2eec7af1..00000000 --- a/framework/src/suricata/src/util-daemon.c +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias Galvan - * - * Daemonization process - */ - -#include "suricata.h" -#include "suricata-common.h" -#include "runmodes.h" -#include "util-daemon.h" -#include "util-debug.h" -#include "conf.h" - -#ifndef OS_WIN32 - -#include -#include -#include - -static volatile sig_atomic_t sigflag = 0; - -/** - * \brief Signal handler used to take the parent process out of stand-by - */ -static void SignalHandlerSigusr1 (int signo) -{ - sigflag = 1; -} - -/** - * \brief Tell the parent process the child is ready - * - * \param pid pid of the parent process to signal - */ -static void TellWaitingParent (pid_t pid) -{ - kill(pid, SIGUSR1); -} - -/** - * \brief Set the parent on stand-by until the child is ready - * - * \param pid pid of the child process to wait - */ -static void WaitForChild (pid_t pid) -{ - int status; - SCLogDebug("Daemon: Parent waiting for child to be ready..."); - /* Wait until child signals is ready */ - while (sigflag == 0) { - if (waitpid(pid, &status, WNOHANG)) { - /* Check if the child is still there, otherwise the parent should exit */ - if (WIFEXITED(status) || WIFSIGNALED(status)) { - SCLogError(SC_ERR_DAEMON, "Child died unexpectedly"); - exit(EXIT_FAILURE); - } - } - /* sigsuspend(); */ - sleep(1); - } -} - -/** - * \brief Close stdin, stdout, stderr.Redirect logging info to syslog - * - */ -static void SetupLogging (void) -{ - /* Redirect stdin, stdout, stderr to /dev/null */ - int fd = open("/dev/null", O_RDWR); - if (fd < 0) - return; - if (dup2(fd, 0) < 0) - return; - if (dup2(fd, 1) < 0) - return; - if (dup2(fd, 2) < 0) - return; - close(fd); -} - -/** - * \brief Daemonize the process - * - */ -void Daemonize (void) -{ - pid_t pid, sid; - - /* Register the signal handler */ - signal(SIGUSR1, SignalHandlerSigusr1); - - /** \todo We should check if wie allow more than 1 instance - to run simultaneously. Maybe change the behaviour - through conf file */ - - /* Creates a new process */ - pid = fork(); - - if (pid < 0) { - /* Fork error */ - SCLogError(SC_ERR_DAEMON, "Error forking the process"); - exit(EXIT_FAILURE); - } else if (pid == 0) { - /* Child continues here */ - char *daemondir; - - umask(027); - - sid = setsid(); - if (sid < 0) { - SCLogError(SC_ERR_DAEMON, "Error creating new session"); - exit(EXIT_FAILURE); - } - - if (ConfGet("daemon-directory", &daemondir) == 1) { - if ((chdir(daemondir)) < 0) { - SCLogError(SC_ERR_DAEMON, "Error changing to working directory"); - exit(EXIT_FAILURE); - } - } -#ifndef OS_WIN32 - else { - if (chdir("/") < 0) { - SCLogError(SC_ERR_DAEMON, "Error changing to working directory '/'"); - } - } -#endif - - SetupLogging(); - - /* Child is ready, tell its parent */ - TellWaitingParent(getppid()); - - /* Daemon is up and running */ - SCLogDebug("Daemon is running"); - return; - } - /* Parent continues here, waiting for child to be ready */ - SCLogDebug("Parent is waiting for child to be ready"); - WaitForChild(pid); - - /* Parent exits */ - SCLogDebug("Child is ready, parent exiting"); - exit(EXIT_SUCCESS); - -} - -#endif /* ifndef OS_WIN32 */ - -/** - * \brief Check for a valid combination daemon/mode - * - * \param daemon daemon on or off - * \param mode selected mode - * - * \retval 1 valid combination - * \retval 0 invalid combination - */ -int CheckValidDaemonModes (int daemon, int mode) -{ - if (daemon) { - switch (mode) { - case RUNMODE_PCAP_FILE: - SCLogError(SC_ERR_INVALID_RUNMODE, "ERROR: pcap offline mode cannot run as daemon"); - return 0; - case RUNMODE_UNITTEST: - SCLogError(SC_ERR_INVALID_RUNMODE, "ERROR: unittests cannot run as daemon"); - return 0; - default: - SCLogDebug("Allowed mode"); - break; - } - } - return 1; -} diff --git a/framework/src/suricata/src/util-daemon.h b/framework/src/suricata/src/util-daemon.h deleted file mode 100644 index ef8dc725..00000000 --- a/framework/src/suricata/src/util-daemon.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gerardo Iglesias Galvan - */ - -#ifndef __UTIL_DAEMON_H__ -#define __UTIL_DAEMON_H__ - -/** \todo Adjust path */ -#define DAEMON_WORKING_DIRECTORY "/" - -#ifdef OS_WIN32 -#define Daemonize() -#else -void Daemonize (void); -#endif - -int CheckValidDaemonModes (int, int); - -#endif /* __UTIL_DAEMON_H__ */ diff --git a/framework/src/suricata/src/util-debug-filters.c b/framework/src/suricata/src/util-debug-filters.c deleted file mode 100644 index 6c06b0af..00000000 --- a/framework/src/suricata/src/util-debug-filters.c +++ /dev/null @@ -1,1009 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Debug filter utility functions - */ - -#include "suricata-common.h" - -/* both of these are defined in util-debug.c */ -extern int sc_log_module_initialized; -extern int sc_log_module_cleaned; - -/* used to indicate if any FG filters are registered */ -int sc_log_fg_filters_present = 0; - -/* used to indicate if any FD filters are registered */ -int sc_log_fd_filters_present = 0; - -/** - * \brief Holds the fine-grained filters - */ -SCLogFGFilterFile *sc_log_fg_filters[SC_LOG_FILTER_MAX] = { NULL, NULL }; - -/** - * \brief Mutex for accessing the fine-grained fiters sc_log_fg_filters - */ -static SCMutex sc_log_fg_filters_m[SC_LOG_FILTER_MAX] = { SCMUTEX_INITIALIZER, - SCMUTEX_INITIALIZER }; - -/** - * \brief Holds the function-dependent filters - */ -static SCLogFDFilter *sc_log_fd_filters = NULL; - -/** - * \brief Mutex for accessing the function-dependent filters sc_log_fd_filters - */ -static SCMutex sc_log_fd_filters_m = SCMUTEX_INITIALIZER; - -/** - * \brief Holds the thread_list required by function-dependent filters - */ -static SCLogFDFilterThreadList *sc_log_fd_filters_tl = NULL; - -/** - * \brief Mutex for accessing the FD thread_list sc_log_fd_filters_tl - */ -static SCMutex sc_log_fd_filters_tl_m = SCMUTEX_INITIALIZER; - -/** - * \brief Helper function used internally to add a FG filter - * - * \param file File_name of the filter - * \param function Function_name of the filter - * \param line Line number of the filter - * \param listtype The filter listtype. Can be either a blacklist or whitelist - * filter listtype(SC_LOG_FILTER_BL or SC_LOG_FILTER_WL) - * - * \retval 0 on successfully adding the filter; - * \retval -1 on failure - */ -int SCLogAddFGFilter(const char *file, const char *function, - int line, int listtype) -{ - SCLogFGFilterFile *fgf_file = NULL; - SCLogFGFilterFile *prev_fgf_file = NULL; - - SCLogFGFilterFunc *fgf_func = NULL; - SCLogFGFilterFunc *prev_fgf_func = NULL; - - SCLogFGFilterLine *fgf_line = NULL; - SCLogFGFilterLine *prev_fgf_line = NULL; - - int found = 0; - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return -1 ; - } - - if (file == NULL && function == NULL && line < 0) { - printf("Error: Invalid arguments supplied to SCLogAddFGFilter\n"); - return -1; - } - - SCMutex *m = &sc_log_fg_filters_m[listtype]; - - SCMutexLock(m); - - fgf_file = sc_log_fg_filters[listtype]; - - prev_fgf_file = fgf_file; - while (fgf_file != NULL) { - prev_fgf_file = fgf_file; - if (file == NULL && fgf_file->file == NULL) - found = 1; - else if (file != NULL && fgf_file->file != NULL) - found = (strcmp(file, fgf_file->file) == 0); - else - found = 0; - - if (found == 1) - break; - - fgf_file = fgf_file->next; - } - - if (found == 0) { - SCLogAddToFGFFileList(prev_fgf_file, file, function, line, listtype); - goto done; - } - - found = 0; - fgf_func = fgf_file->func; - prev_fgf_func = fgf_func; - while (fgf_func != NULL) { - prev_fgf_func = fgf_func; - if (function == NULL && fgf_func->func == NULL) - found = 1; - else if (function != NULL && fgf_func->func != NULL) - found = (strcmp(function, fgf_func->func) == 0); - else - found = 0; - - if (found == 1) - break; - - fgf_func = fgf_func->next; - } - - if (found == 0) { - SCLogAddToFGFFuncList(fgf_file, prev_fgf_func, function, line); - goto done; - } - - found = 0; - fgf_line = fgf_func->line; - prev_fgf_line = fgf_line; - while(fgf_line != NULL) { - prev_fgf_line = fgf_line; - if (line == fgf_line->line) { - found = 1; - break; - } - - fgf_line = fgf_line->next; - } - - if (found == 0) { - SCLogAddToFGFLineList(fgf_func, prev_fgf_line, line); - goto done; - } - - done: - SCMutexUnlock(&sc_log_fg_filters_m[listtype]); - sc_log_fg_filters_present = 1; - - return 0; -} - -/** - * \brief Internal function used to check for matches against registered FG - * filters. Checks if there is a match for the incoming log_message with - * any of the FG filters. Based on whether the filter type is whitelist - * or blacklist, the function allows the message to be logged or not. - * - * \param file File_name from where the log_message originated - * \param function Function_name from where the log_message originated - * \param line Line number from where the log_message originated - * \param listtype The filter listtype. Can be either a blacklist or whitelist - * filter listtype(SC_LOG_FILTER_BL or SC_LOG_FILTER_WL) - * - * \retval 1 if there is a match - * \retval 0 on no match - * \retval -1 on failure - */ -static int SCLogMatchFGFilter(const char *file, const char *function, int line, - int listtype) -{ - SCLogFGFilterFile *fgf_file = NULL; - SCLogFGFilterFunc *fgf_func = NULL; - SCLogFGFilterLine *fgf_line = NULL; - int match = 1; - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return -1; - } - - SCMutexLock(&sc_log_fg_filters_m[listtype]); - - fgf_file = sc_log_fg_filters[listtype]; - - if (fgf_file == NULL) { - SCMutexUnlock(&sc_log_fg_filters_m[listtype]); - return 1; - } - - while(fgf_file != NULL) { - match = 1; - - match &= (fgf_file->file != NULL)? !strcmp(file, fgf_file->file): 1; - - if (match == 0) { - fgf_file = fgf_file->next; - continue; - } - - fgf_func = fgf_file->func; - while (fgf_func != NULL) { - match = 1; - - match &= (fgf_func->func != NULL)? !strcmp(function, fgf_func->func): 1; - - if (match == 0) { - fgf_func = fgf_func->next; - continue; - } - - fgf_line = fgf_func->line; - while (fgf_line != NULL) { - match = 1; - - match &= (fgf_line->line != -1)? (line == fgf_line->line): 1; - - if (match == 1) - break; - - fgf_line = fgf_line->next; - } - - if (match == 1) - break; - - fgf_func = fgf_func->next; - } - - if (match == 1) { - SCMutexUnlock(&sc_log_fg_filters_m[listtype]); - if (listtype == SC_LOG_FILTER_WL) - return 1; - else - return 0; - } - - fgf_file = fgf_file->next; - } - - SCMutexUnlock(&sc_log_fg_filters_m[listtype]); - - if (listtype == SC_LOG_FILTER_WL) - return 0; - else - return 1; -} - -/** - * \brief Checks if there is a match for the incoming log_message with any - * of the FG filters. If there is a match, it allows the message - * to be logged, else it rejects that message. - * - * \param file File_name from where the log_message originated - * \param function Function_name from where the log_message originated - * \param line Line number from where the log_message originated - * - * \retval 1 if there is a match - * \retval 0 on no match - * \retval -1 on failure - */ -int SCLogMatchFGFilterWL(const char *file, const char *function, int line) -{ - return SCLogMatchFGFilter(file, function, line, SC_LOG_FILTER_WL); -} - -/** - * \brief Checks if there is a match for the incoming log_message with any - * of the FG filters. If there is a match it rejects the logging - * for that messages, else it allows that message to be logged - * - * \praram file File_name from where the log_message originated - * \param function Function_name from where the log_message originated - * \param line Line number from where the log_message originated - * - * \retval 1 if there is a match - * \retval 0 on no match - * \retval -1 on failure - */ -int SCLogMatchFGFilterBL(const char *file, const char *function, int line) -{ - return SCLogMatchFGFilter(file, function, line, SC_LOG_FILTER_BL); -} - -/** - * \brief Adds a Whitelist(WL) fine-grained(FG) filter. A FG filter WL filter - * allows messages that match this filter, to be logged, while the filter - * is defined using a file_name, function_name and line_number. - * - * If a particular paramter in the fg-filter(file, function and line), - * shouldn't be considered while logging the message, one can supply - * NULL for the file_name or function_name and a negative line_no. - * - * \param file File_name of the filter - * \param function Function_name of the filter - * \param line Line number of the filter - * - * \retval 0 on successfully adding the filter; - * \retval -1 on failure - */ -int SCLogAddFGFilterWL(const char *file, const char *function, int line) -{ - return SCLogAddFGFilter(file, function, line, SC_LOG_FILTER_WL); -} - -/** - * \brief Adds a Blacklist(BL) fine-grained(FG) filter. A FG filter BL filter - * allows messages that don't match this filter, to be logged, while the - * filter is defined using a file_name, function_name and line_number - * - * If a particular paramter in the fg-filter(file, function and line), - * shouldn't be considered while logging the message, one can supply - * NULL for the file_name or function_name and a negative line_no. - * - * \param file File_name of the filter - * \param function Function_name of the filter - * \param line Line number of the filter - * - * \retval 0 on successfully adding the filter - * \retval -1 on failure - */ -int SCLogAddFGFilterBL(const char *file, const char *function, int line) -{ - return SCLogAddFGFilter(file, function, line, SC_LOG_FILTER_BL); -} - -void SCLogReleaseFGFilters(void) -{ - SCLogFGFilterFile *fgf_file = NULL; - SCLogFGFilterFunc *fgf_func = NULL; - SCLogFGFilterLine *fgf_line = NULL; - - void *temp = NULL; - - int i = 0; - - for (i = 0; i < SC_LOG_FILTER_MAX; i++) { - SCMutexLock(&sc_log_fg_filters_m[i]); - - fgf_file = sc_log_fg_filters[i]; - while (fgf_file != NULL) { - - fgf_func = fgf_file->func; - while (fgf_func != NULL) { - - fgf_line = fgf_func->line; - while(fgf_line != NULL) { - temp = fgf_line; - fgf_line = fgf_line->next; - SCFree(temp); - } - - if (fgf_func->func != NULL) - SCFree(fgf_func->func); - temp = fgf_func; - fgf_func = fgf_func->next; - SCFree(temp); - } - - if (fgf_file->file != NULL) - SCFree(fgf_file->file); - temp = fgf_file; - fgf_file = fgf_file->next; - SCFree(temp); - } - - SCMutexUnlock(&sc_log_fg_filters_m[i]); - sc_log_fg_filters[i] = NULL; - } - - return; -} - -/** - * \brief Prints the FG filters(both WL and BL). Used for debugging purposes. - * - * \retval count The no of FG filters - */ -int SCLogPrintFGFilters() -{ - SCLogFGFilterFile *fgf_file = NULL; - SCLogFGFilterFunc *fgf_func = NULL; - SCLogFGFilterLine *fgf_line = NULL; - - int count = 0; - int i = 0; - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return 0; - } - -#ifdef DEBUG - printf("Fine grained filters:\n"); -#endif - - for (i = 0; i < SC_LOG_FILTER_MAX; i++) { - SCMutexLock(&sc_log_fg_filters_m[i]); - - fgf_file = sc_log_fg_filters[i]; - while (fgf_file != NULL) { - - fgf_func = fgf_file->func; - while (fgf_func != NULL) { - - fgf_line = fgf_func->line; - while(fgf_line != NULL) { -#ifdef DEBUG - printf("%s - ", fgf_file->file); - printf("%s - ", fgf_func->func); - printf("%d\n", fgf_line->line); -#endif - - count++; - - fgf_line = fgf_line->next; - } - - fgf_func = fgf_func->next; - } - - fgf_file = fgf_file->next; - } - SCMutexUnlock(&sc_log_fg_filters_m[i]); - } - - return count; -} - - - -/* --------------------------------------------------|-------------------------- - * -------------------------- Code for the FD Filter |-------------------------- - * --------------------------------------------------V-------------------------- - */ - -/** - * \brief Checks if there is a match for the incoming log_message with any - * of the FD filters - * - * \param function Function_name from where the log_message originated - * - * \retval 1 if there is a match - * \retval 0 on no match; - */ -int SCLogMatchFDFilter(const char *function) -{ -#ifndef DEBUG - return 1; -#else - SCLogFDFilterThreadList *thread_list = NULL; - - pthread_t self = pthread_self(); - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return 0; - } - - SCMutexLock(&sc_log_fd_filters_tl_m); - - if (sc_log_fd_filters_tl == NULL) { - SCMutexUnlock(&sc_log_fd_filters_tl_m); - if (sc_log_fd_filters != NULL) - return 0; - return 1; - } - - thread_list = sc_log_fd_filters_tl; - while (thread_list != NULL) { - if (pthread_equal(self, thread_list->t)) { - if (thread_list->entered > 0) { - SCMutexUnlock(&sc_log_fd_filters_tl_m); - return 1; - } - SCMutexUnlock(&sc_log_fd_filters_tl_m); - return 0; - } - - thread_list = thread_list->next; - } - - SCMutexUnlock(&sc_log_fd_filters_tl_m); - - return 0; -#endif -} - -/** - * \brief Updates a FD filter, based on whether the function that calls this - * function, is registered as a FD filter or not. This is called by - * a function only on its entry - * - * \param function Function_name from where the log_message originated - * - * \retval 1 Since it is a hack to get things working inside the macros - */ -int SCLogCheckFDFilterEntry(const char *function) -{ - SCLogFDFilter *curr = NULL; - - SCLogFDFilterThreadList *thread_list = NULL; - SCLogFDFilterThreadList *thread_list_temp = NULL; - - //pid_t self = syscall(SYS_gettid); - pthread_t self = pthread_self(); - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return 0; - } - - SCMutexLock(&sc_log_fd_filters_m); - - curr = sc_log_fd_filters; - - while (curr != NULL) { - if (strcmp(function, curr->func) == 0) - break; - - curr = curr->next; - } - - if (curr == NULL) { - SCMutexUnlock(&sc_log_fd_filters_m); - return 1; - } - - SCMutexUnlock(&sc_log_fd_filters_m); - - SCMutexLock(&sc_log_fd_filters_tl_m); - - thread_list = sc_log_fd_filters_tl; - while (thread_list != NULL) { - if (pthread_equal(self, thread_list->t)) - break; - - thread_list = thread_list->next; - } - - if (thread_list != NULL) { - thread_list->entered++; - SCMutexUnlock(&sc_log_fd_filters_tl_m); - return 1; - } - - if ( (thread_list_temp = SCMalloc(sizeof(SCLogFDFilterThreadList))) == NULL) { - SCMutexUnlock(&sc_log_fd_filters_tl_m); - return 0; - } - memset(thread_list_temp, 0, sizeof(SCLogFDFilterThreadList)); - - thread_list_temp->t = self; - thread_list_temp->entered++; - - sc_log_fd_filters_tl = thread_list_temp; - - SCMutexUnlock(&sc_log_fd_filters_tl_m); - - return 1; -} - -/** - * \brief Updates a FD filter, based on whether the function that calls this - * function, is registered as a FD filter or not. This is called by - * a function only before its exit. - * - * \param function Function_name from where the log_message originated - * - */ -void SCLogCheckFDFilterExit(const char *function) -{ - SCLogFDFilter *curr = NULL; - - SCLogFDFilterThreadList *thread_list = NULL; - - //pid_t self = syscall(SYS_gettid); - pthread_t self = pthread_self(); - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return; - } - - SCMutexLock(&sc_log_fd_filters_m); - - curr = sc_log_fd_filters; - - while (curr != NULL) { - if (strcmp(function, curr->func) == 0) - break; - - curr = curr->next; - } - - if (curr == NULL) { - SCMutexUnlock(&sc_log_fd_filters_m); - return; - } - - SCMutexUnlock(&sc_log_fd_filters_m); - - SCMutexLock(&sc_log_fd_filters_tl_m); - - thread_list = sc_log_fd_filters_tl; - while (thread_list != NULL) { - if (pthread_equal(self, thread_list->t)) - break; - - thread_list = thread_list->next; - } - - SCMutexUnlock(&sc_log_fd_filters_tl_m); - - if (thread_list != NULL) - thread_list->entered--; - - return; -} - -/** - * \brief Adds a Function-Dependent(FD) filter - * - * \param Name of the function for which a FD filter has to be registered - * - * \retval 0 on success - * \retval -1 on failure - */ -int SCLogAddFDFilter(const char *function) -{ - SCLogFDFilter *curr = NULL; - SCLogFDFilter *prev = NULL; - SCLogFDFilter *temp = NULL; - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return -1; - } - - if (function == NULL) { - printf("Invalid argument supplied to SCLogAddFDFilter\n"); - return -1; - } - - SCMutexLock(&sc_log_fd_filters_m); - - curr = sc_log_fd_filters; - while (curr != NULL) { - prev = curr; - - if (strcmp(function, curr->func) == 0) { - - SCMutexUnlock(&sc_log_fd_filters_m); - return 0; - } - - curr = curr->next; - } - - if ( (temp = SCMalloc(sizeof(SCLogFDFilter))) == NULL) { - printf("Error Allocating memory (SCMalloc)\n"); - exit(EXIT_FAILURE); - } - memset(temp, 0, sizeof(SCLogFDFilter)); - - if ( (temp->func = SCStrdup(function)) == NULL) { - printf("Error Allocating memory (SCStrdup)\n"); - exit(EXIT_FAILURE); - } - - if (sc_log_fd_filters == NULL) - sc_log_fd_filters = temp; - /* clang thinks prev can be NULL, but it can't be unless - * sc_log_fd_filters is also NULL which is handled here. - * Doing this "fix" to shut clang up. */ - else if (prev != NULL) - prev->next = temp; - - SCMutexUnlock(&sc_log_fd_filters_m); - sc_log_fd_filters_present = 1; - - return 0; -} - -/** - * \brief Releases all the FD filters added to the logging module - */ -void SCLogReleaseFDFilters(void) -{ - SCLogFDFilter *fdf = NULL; - SCLogFDFilter *temp = NULL; - - SCMutexLock(&sc_log_fd_filters_m); - - fdf = sc_log_fd_filters; - while (fdf != NULL) { - temp = fdf; - fdf = fdf->next; - SCLogReleaseFDFilter(temp); - } - - sc_log_fd_filters = NULL; - - SCMutexUnlock( &sc_log_fd_filters_m ); - - return; -} - -/** - * \brief Removes a Function-Dependent(FD) filter - * - * \param Name of the function for which a FD filter has to be unregistered - * - * \retval 0 on success(the filter was removed or the filter was not present) - * \retval -1 on failure/error - */ -int SCLogRemoveFDFilter(const char *function) -{ - SCLogFDFilter *curr = NULL; - SCLogFDFilter *prev = NULL; - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return -1 ; - } - - if (function == NULL) { - printf("Invalid argument(s) supplied to SCLogRemoveFDFilter\n"); - return -1; - } - - SCMutexLock(&sc_log_fd_filters_m); - - if (sc_log_fd_filters == NULL) { - SCMutexUnlock(&sc_log_fd_filters_m); - return 0; - } - - curr = sc_log_fd_filters; - prev = curr; - while (curr != NULL) { - if (strcmp(function, curr->func) == 0) - break; - - prev = curr; - curr = curr->next; - } - - if (curr == NULL) { - - SCMutexUnlock(&sc_log_fd_filters_m); - - return 0; - } - - if (sc_log_fd_filters == curr) - sc_log_fd_filters = curr->next; - else - prev->next = curr->next; - - SCLogReleaseFDFilter(curr); - - SCMutexUnlock(&sc_log_fd_filters_m); - - if (sc_log_fd_filters == NULL) - sc_log_fd_filters_present = 0; - - return 0; -} - -/** - * \brief Prints the FG filters(both WL and BL). Used for debugging purposes. - * - * \retval count The no of FG filters - */ -int SCLogPrintFDFilters(void) -{ - SCLogFDFilter *fdf = NULL; - int count = 0; - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return 0; - } - -#ifdef DEBUG - printf("FD filters:\n"); -#endif - - SCMutexLock(&sc_log_fd_filters_m); - - fdf = sc_log_fd_filters; - while (fdf != NULL) { -#ifdef DEBUG - printf("%s \n", fdf->func); -#endif - fdf = fdf->next; - count++; - } - - SCMutexUnlock(&sc_log_fd_filters_m); - - return count; -} - -/** - * \brief Helper function used internally to add a FG filter. This function is - * called when the file component of the incoming filter has no entry - * in the filter list. - * - * \param fgf_file The file component(basically the position in the list) from - * the filter list, after which the new filter has to be added - * \param file File_name of the filter - * \param function Function_name of the filter - * \param line Line number of the filter - * \param listtype The filter listtype. Can be either a blacklist or whitelist - * filter listtype(SC_LOG_FILTER_BL or SC_LOG_FILTER_WL) - */ -void SCLogAddToFGFFileList(SCLogFGFilterFile *fgf_file, - const char *file, - const char *function, int line, - int listtype) -{ - SCLogFGFilterFile *fgf_file_temp = NULL; - SCLogFGFilterFunc *fgf_func_temp = NULL; - SCLogFGFilterLine *fgf_line_temp = NULL; - - if ( (fgf_file_temp = SCMalloc(sizeof(SCLogFGFilterFile))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFileList. Exiting..."); - exit(EXIT_FAILURE); - } - memset(fgf_file_temp, 0, sizeof(SCLogFGFilterFile)); - - if ( file != NULL && (fgf_file_temp->file = SCStrdup(file)) == NULL) { - printf("Error Allocating memory\n"); - exit(EXIT_FAILURE); - } - - if ( (fgf_func_temp = SCMalloc(sizeof(SCLogFGFilterFunc))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFileList. Exiting..."); - exit(EXIT_FAILURE); - } - memset(fgf_func_temp, 0, sizeof(SCLogFGFilterFunc)); - - if ( function != NULL && (fgf_func_temp->func = SCStrdup(function)) == NULL) { - printf("Error Allocating memory\n"); - exit(EXIT_FAILURE); - } - - if ( (fgf_line_temp = SCMalloc(sizeof(SCLogFGFilterLine))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFileList. Exiting..."); - exit(EXIT_FAILURE); - } - memset(fgf_line_temp, 0, sizeof(SCLogFGFilterLine)); - - fgf_line_temp->line = line; - - /* add to the lists */ - fgf_func_temp->line = fgf_line_temp; - - fgf_file_temp->func = fgf_func_temp; - - if (fgf_file == NULL) - sc_log_fg_filters[listtype] = fgf_file_temp; - else - fgf_file->next = fgf_file_temp; - - return; -} - -/** - * \brief Helper function used internally to add a FG filter. This function is - * called when the file component of the incoming filter has an entry - * in the filter list, but the function component doesn't have an entry - * for the corresponding file component - * - * \param fgf_file The file component from the filter list to which the new - * filter has to be added - * \param fgf_func The function component(basically the position in the list), - * from the filter list, after which the new filter has to be - * added - * \param function Function_name of the filter - * \param line Line number of the filter - */ -void SCLogAddToFGFFuncList(SCLogFGFilterFile *fgf_file, - SCLogFGFilterFunc *fgf_func, - const char *function, int line) -{ - SCLogFGFilterFunc *fgf_func_temp = NULL; - SCLogFGFilterLine *fgf_line_temp = NULL; - - if ( (fgf_func_temp = SCMalloc(sizeof(SCLogFGFilterFunc))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFuncList. Exiting..."); - exit(EXIT_FAILURE); - } - memset(fgf_func_temp, 0, sizeof(SCLogFGFilterFunc)); - - if ( function != NULL && (fgf_func_temp->func = SCStrdup(function)) == NULL) { - printf("Error Allocating memory\n"); - exit(EXIT_FAILURE); - } - - if ( (fgf_line_temp = SCMalloc(sizeof(SCLogFGFilterLine))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFFuncList. Exiting..."); - exit(EXIT_FAILURE); - } - memset(fgf_line_temp, 0, sizeof(SCLogFGFilterLine)); - - fgf_line_temp->line = line; - - /* add to the lists */ - fgf_func_temp->line = fgf_line_temp; - - if (fgf_func == NULL) - fgf_file->func = fgf_func_temp; - else - fgf_func->next = fgf_func_temp; - - return; -} - -/** - * \brief Helper function used internally to add a FG filter. This function is - * called when the file and function components of the incoming filter - * have an entry in the filter list, but the line component doesn't have - * an entry for the corresponding function component - * - * \param fgf_func The function component from the filter list to which the new - * filter has to be added - * \param fgf_line The function component(basically the position in the list), - * from the filter list, after which the new filter has to be - * added - * \param line Line number of the filter - */ -void SCLogAddToFGFLineList(SCLogFGFilterFunc *fgf_func, - SCLogFGFilterLine *fgf_line, - int line) -{ - SCLogFGFilterLine *fgf_line_temp = NULL; - - if ( (fgf_line_temp = SCMalloc(sizeof(SCLogFGFilterLine))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAddToFGFLineList. Exiting..."); - exit(EXIT_FAILURE); - } - memset(fgf_line_temp, 0, sizeof(SCLogFGFilterLine)); - - fgf_line_temp->line = line; - - /* add to the lists */ - if (fgf_line == NULL) - fgf_func->line = fgf_line_temp; - else - fgf_line->next = fgf_line_temp; - - return; -} - -/** - * \brief Releases the memory alloted to a FD filter - * - * \param Pointer to the FD filter that has to be freed - */ -void SCLogReleaseFDFilter(SCLogFDFilter *fdf) -{ - if (fdf != NULL) { - if (fdf->func != NULL) - SCFree(fdf->func); - SCFree(fdf); - } - - return; -} - diff --git a/framework/src/suricata/src/util-debug-filters.h b/framework/src/suricata/src/util-debug-filters.h deleted file mode 100644 index bbbcf9af..00000000 --- a/framework/src/suricata/src/util-debug-filters.h +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __DEBUG_FILTERS_H__ -#define __DEBUG_FILTERS_H__ - -#include -#include "threads.h" -#include "util-mem.h" - -/** - * \brief Enum that holds the different kinds of filters available - */ -enum { - SC_LOG_FILTER_BL = 0, - SC_LOG_FILTER_WL = 1, - SC_LOG_FILTER_MAX = 2, -}; - -/** - * \brief Structure used to hold the line_no details of a FG filter - */ -typedef struct SCLogFGFilterLine_ { - int line; - - struct SCLogFGFilterLine_ *next; -} SCLogFGFilterLine; - -/** - * \brief structure used to hold the function details of a FG filter - */ -typedef struct SCLogFGFilterFunc_ { - char *func; - SCLogFGFilterLine *line; - - struct SCLogFGFilterFunc_ *next; -} SCLogFGFilterFunc; - -/** - * \brief Structure used to hold FG filters. Encapsulates filename details, - * func details, which inturn encapsulates the line_no details - */ -typedef struct SCLogFGFilterFile_ { - char *file; - SCLogFGFilterFunc *func; - - struct SCLogFGFilterFile_ *next; -} SCLogFGFilterFile; - -/** - * \brief Structure used to hold the thread_list used by FD filters - */ -typedef struct SCLogFDFilterThreadList_ { - int entered; - pthread_t t; -// pid_t t; - - struct SCLogFDFilterThreadList_ *next; -} SCLogFDFilterThreadList; - -/** - * \brief Structure that holds the FD filters - */ -typedef struct SCLogFDFilter_ { - char *func; - - struct SCLogFDFilter_ *next; -} SCLogFDFilter; - - -extern int sc_log_fg_filters_present; - -extern int sc_log_fd_filters_present; - - -int SCLogAddFGFilterWL(const char *, const char *, int); - -int SCLogAddFGFilterBL(const char *, const char *, int); - -int SCLogMatchFGFilterBL(const char *, const char *, int); - -int SCLogMatchFGFilterWL(const char *, const char *, int); - -void SCLogReleaseFGFilters(void); - -int SCLogAddFDFilter(const char *); - -int SCLogPrintFDFilters(void); - -void SCLogReleaseFDFilters(void); - -int SCLogRemoveFDFilter(const char *); - -int SCLogCheckFDFilterEntry(const char *); - -void SCLogCheckFDFilterExit(const char *); - -int SCLogMatchFDFilter(const char *); - -int SCLogPrintFGFilters(void); - -void SCLogAddToFGFFileList(SCLogFGFilterFile *, - const char *, - const char *, int, - int); - -void SCLogAddToFGFFuncList(SCLogFGFilterFile *, - SCLogFGFilterFunc *, - const char *, int); - -void SCLogAddToFGFLineList(SCLogFGFilterFunc *, - SCLogFGFilterLine *, - int); - -void SCLogReleaseFDFilter(SCLogFDFilter *); -#endif /* __DEBUG_H__ */ diff --git a/framework/src/suricata/src/util-debug.c b/framework/src/suricata/src/util-debug.c deleted file mode 100644 index d9af08c4..00000000 --- a/framework/src/suricata/src/util-debug.c +++ /dev/null @@ -1,1653 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Debug utility functions - */ - -#include "suricata-common.h" -#include "threads.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-enum.h" -#include "util-debug-filters.h" - -#include "decode.h" -#include "detect.h" -#include "packet-queue.h" -#include "threadvars.h" - -#include "tm-queuehandlers.h" -#include "tm-queues.h" -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-syslog.h" - -#include "conf.h" - -/* holds the string-enum mapping for the enums held in the table SCLogLevel */ -SCEnumCharMap sc_log_level_map[ ] = { - { "Not set", SC_LOG_NOTSET}, - { "None", SC_LOG_NONE }, - { "Emergency", SC_LOG_EMERGENCY }, - { "Alert", SC_LOG_ALERT }, - { "Critical", SC_LOG_CRITICAL }, - { "Error", SC_LOG_ERROR }, - { "Warning", SC_LOG_WARNING }, - { "Notice", SC_LOG_NOTICE }, - { "Info", SC_LOG_INFO }, - { "Debug", SC_LOG_DEBUG }, - { NULL, -1 } -}; - -/* holds the string-enum mapping for the enums held in the table SCLogOPIface */ -SCEnumCharMap sc_log_op_iface_map[ ] = { - { "Console", SC_LOG_OP_IFACE_CONSOLE }, - { "File", SC_LOG_OP_IFACE_FILE }, - { "Syslog", SC_LOG_OP_IFACE_SYSLOG }, - { NULL, -1 } -}; - -#if defined (OS_WIN32) -/** - * \brief Used for synchronous output on WIN32 - */ -static SCMutex sc_log_stream_lock = NULL; -#endif /* OS_WIN32 */ - -/** - * \brief Holds the config state for the logging module - */ -static SCLogConfig *sc_log_config = NULL; - -/** - * \brief Returns the full path given a file and configured log dir - */ -static char *SCLogGetLogFilename(char *); - -/** - * \brief Holds the global log level. Is the same as sc_log_config->log_level - */ -SCLogLevel sc_log_global_log_level; - -/** - * \brief Used to indicate whether the logging module has been init or not - */ -int sc_log_module_initialized = 0; - -/** - * \brief Used to indicate whether the logging module has been cleaned or not - */ -int sc_log_module_cleaned = 0; - -/** - * \brief Maps the SC logging level to the syslog logging level - * - * \param The SC logging level that has to be mapped to the syslog_log_level - * - * \retval syslog_log_level The mapped syslog_api_log_level, for the logging - * module api's internal log_level - */ -static inline int SCLogMapLogLevelToSyslogLevel(int log_level) -{ - int syslog_log_level = 0; - - switch (log_level) { - case SC_LOG_EMERGENCY: - syslog_log_level = LOG_EMERG; - break; - case SC_LOG_ALERT: - syslog_log_level = LOG_ALERT; - break; - case SC_LOG_CRITICAL: - syslog_log_level = LOG_CRIT; - break; - case SC_LOG_ERROR: - syslog_log_level = LOG_ERR; - break; - case SC_LOG_WARNING: - syslog_log_level = LOG_WARNING; - break; - case SC_LOG_NOTICE: - syslog_log_level = LOG_NOTICE; - break; - case SC_LOG_INFO: - syslog_log_level = LOG_INFO; - break; - case SC_LOG_DEBUG: - syslog_log_level = LOG_DEBUG; - break; - default: - syslog_log_level = LOG_EMERG; - break; - } - - return syslog_log_level; -} - -/** - * \brief Output function that logs a character string out to a file descriptor - * - * \param fd Pointer to the file descriptor - * \param msg Pointer to the character string that should be logged - */ -static inline void SCLogPrintToStream(FILE *fd, char *msg) -{ -#if defined (OS_WIN32) - SCMutexLock(&sc_log_stream_lock); -#endif /* OS_WIN32 */ - - if (fprintf(fd, "%s\n", msg) < 0) - printf("Error writing to stream using fprintf\n"); - - fflush(fd); - -#if defined (OS_WIN32) - SCMutexUnlock(&sc_log_stream_lock); -#endif /* OS_WIN32 */ - - return; -} - -/** - * \brief Output function that logs a character string throught the syslog iface - * - * \param syslog_log_level Holds the syslog_log_level that the message should be - * logged as - * \param msg Pointer to the char string, that should be logged - * - * \todo syslog is thread-safe according to POSIX manual and glibc code, but we - * we will have to look into non POSIX compliant boxes like freeBSD - */ -static inline void SCLogPrintToSyslog(int syslog_log_level, const char *msg) -{ - //static struct syslog_data data = SYSLOG_DATA_INIT; - //syslog_r(syslog_log_level, NULL, "%s", msg); - - syslog(syslog_log_level, "%s", msg); - - return; -} - -#ifdef HAVE_LIBJANSSON -/** - */ -int SCLogMessageJSON(struct timeval *tval, char *buffer, size_t buffer_size, - SCLogLevel log_level, const char *file, - unsigned line, const char *function, SCError error_code, - const char *message) -{ - json_t *js = json_object(); - if (unlikely(js == NULL)) - goto error; - json_t *ejs = json_object(); - if (unlikely(ejs == NULL)) - goto error; - - char timebuf[64]; - CreateIsoTimeString(tval, timebuf, sizeof(timebuf)); - json_object_set_new(js, "timestamp", json_string(timebuf)); - - json_object_set_new(js, "event_type", json_string("engine")); - - if (error_code > 0) { - json_object_set_new(ejs, "error_code", json_integer(error_code)); - json_object_set_new(ejs, "error", json_string(SCErrorToString(error_code))); - } - - if (message) - json_object_set_new(ejs, "message", json_string(message)); - - if (log_level >= SC_LOG_DEBUG) { - if (function) - json_object_set_new(ejs, "function", json_string(function)); - - if (file) - json_object_set_new(ejs, "file", json_string(file)); - - if (line > 0) - json_object_set_new(ejs, "line", json_integer(line)); - } - - json_object_set_new(js, "engine", ejs); - - char *js_s = json_dumps(js, - JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII| -#ifdef JSON_ESCAPE_SLASH - JSON_ESCAPE_SLASH -#else - 0 -#endif - ); - snprintf(buffer, buffer_size, "%s", js_s); - free(js_s); - - json_object_del(js, "engine"); - json_object_clear(js); - json_decref(js); - - return 0; -error: - return -1; -} -#endif /* HAVE_LIBJANSSON */ - -/** - * \brief Adds the global log_format to the outgoing buffer - * - * \param log_level log_level of the message that has to be logged - * \param msg Buffer containing the outgoing message - * \param file File_name from where the message originated - * \param function Function_name from where the message originated - * \param line Line_no from where the messaged originated - * - * \retval SC_OK on success; else an error code - */ -static SCError SCLogMessageGetBuffer( - struct timeval *tval, int color, SCLogOPType type, - char *buffer, size_t buffer_size, - const char *log_format, - - const SCLogLevel log_level, const char *file, - const unsigned int line, const char *function, - const SCError error_code, const char *message) -{ -#ifdef HAVE_LIBJANSSON - if (type == SC_LOG_OP_TYPE_JSON) - return SCLogMessageJSON(tval, buffer, buffer_size, log_level, file, line, function, error_code, message); -#endif - - char *temp = buffer; - const char *s = NULL; - struct tm *tms = NULL; - - char *redb = ""; - char *red = ""; - char *yellowb = ""; - char *yellow = ""; - char *green = ""; - char *blue = ""; - char *reset = ""; - if (color) { - redb = "\x1b[1;31m"; - red = "\x1b[31m"; - yellowb = "\x1b[1;33m"; - yellow = "\x1b[33m"; - green = "\x1b[32m"; - blue = "\x1b[34m"; - reset = "\x1b[0m"; - } - - /* no of characters_written(cw) by snprintf */ - int cw = 0; - - if (sc_log_module_initialized != 1) { -#ifdef DEBUG - printf("Logging module not initialized. Call SCLogInitLogModule(), " - "before using the logging API\n"); -#endif - return SC_ERR_LOG_MODULE_NOT_INIT; - } - - char *temp_fmt = strdup(log_format); - if (unlikely(temp_fmt == NULL)) { - return SC_ERR_MEM_ALLOC; - } - char *temp_fmt_h = temp_fmt; - char *substr = temp_fmt; - - while ( (temp_fmt = index(temp_fmt, SC_LOG_FMT_PREFIX)) ) { - if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) { - if (temp_fmt_h != NULL) - SCFree(temp_fmt_h); - return SC_OK; - } - switch(temp_fmt[1]) { - case SC_LOG_FMT_TIME: - temp_fmt[0] = '\0'; - - struct tm local_tm; - tms = SCLocalTime(tval->tv_sec, &local_tm); - - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%d/%d/%04d -- %02d:%02d:%02d%s", - substr, green, tms->tm_mday, tms->tm_mon + 1, - tms->tm_year + 1900, tms->tm_hour, tms->tm_min, - tms->tm_sec, reset); - if (cw < 0) - goto error; - temp += cw; - temp_fmt++; - substr = temp_fmt; - substr++; - break; - - case SC_LOG_FMT_PID: - temp_fmt[0] = '\0'; - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%u%s", substr, yellow, getpid(), reset); - if (cw < 0) - goto error; - temp += cw; - temp_fmt++; - substr = temp_fmt; - substr++; - break; - - case SC_LOG_FMT_TID: - temp_fmt[0] = '\0'; - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%lu%s", substr, yellow, SCGetThreadIdLong(), reset); - if (cw < 0) - goto error; - temp += cw; - temp_fmt++; - substr = temp_fmt; - substr++; - break; - case SC_LOG_FMT_TM: - temp_fmt[0] = '\0'; -/* disabled to prevent dead lock: - * log or alloc (which calls log on error) can call TmThreadsGetCallingThread - * which will lock tv_root_lock. This can happen while we already hold this - * lock. */ -#if 0 - ThreadVars *tv = TmThreadsGetCallingThread(); - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - *msg), - "%s%s", substr, ((tv != NULL)? tv->name: "UNKNOWN TM")); -#endif - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s", substr, "N/A"); - if (cw < 0) - goto error; - temp += cw; - temp_fmt++; - substr = temp_fmt; - substr++; - break; - case SC_LOG_FMT_LOG_LEVEL: - temp_fmt[0] = '\0'; - s = SCMapEnumValueToName(log_level, sc_log_level_map); - if (s != NULL) { - if (log_level <= SC_LOG_ERROR) - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%s%s", substr, redb, s, reset); - else if (log_level == SC_LOG_WARNING) - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%s%s", substr, red, s, reset); - else if (log_level == SC_LOG_NOTICE) - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%s%s", substr, yellowb, s, reset); - else - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%s%s", substr, yellow, s, reset); - } else { - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s", substr, "INVALID"); - } - if (cw < 0) - goto error; - temp += cw; - temp_fmt++; - substr = temp_fmt; - substr++; - break; - - case SC_LOG_FMT_FILE_NAME: - temp_fmt[0] = '\0'; - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%s%s", substr, blue, file, reset); - if (cw < 0) - goto error; - temp += cw; - temp_fmt++; - substr = temp_fmt; - substr++; - break; - - case SC_LOG_FMT_LINE: - temp_fmt[0] = '\0'; - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%u%s", substr, green, line, reset); - if (cw < 0) - goto error; - temp += cw; - temp_fmt++; - substr = temp_fmt; - substr++; - break; - - case SC_LOG_FMT_FUNCTION: - temp_fmt[0] = '\0'; - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "%s%s%s%s", substr, green, function, reset); - if (cw < 0) - goto error; - temp += cw; - temp_fmt++; - substr = temp_fmt; - substr++; - break; - - } - temp_fmt++; - } - if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) { - if (temp_fmt_h != NULL) - SCFree(temp_fmt_h); - return SC_OK; - } - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s", substr); - if (cw < 0) - goto error; - temp += cw; - if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) { - if (temp_fmt_h != NULL) - SCFree(temp_fmt_h); - return SC_OK; - } - - if (error_code != SC_OK) { - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), - "[%sERRCODE%s: %s%s%s(%s%d%s)] - ", yellow, reset, red, SCErrorToString(error_code), reset, yellow, error_code, reset); - if (cw < 0) - goto error; - temp += cw; - if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) { - if (temp_fmt_h != NULL) - SCFree(temp_fmt_h); - return SC_OK; - } - } - - char *xyellow = error_code > SC_OK ? yellow : ""; - cw = snprintf(temp, SC_LOG_MAX_LOG_MSG_LEN - (temp - buffer), "%s%s%s", xyellow, message, reset); - if (cw < 0) - goto error; - temp += cw; - if ((temp - buffer) > SC_LOG_MAX_LOG_MSG_LEN) { - if (temp_fmt_h != NULL) - SCFree(temp_fmt_h); - return SC_OK; - } - - SCFree(temp_fmt_h); - - if (sc_log_config->op_filter_regex != NULL) { -#define MAX_SUBSTRINGS 30 - int ov[MAX_SUBSTRINGS]; - - if (pcre_exec(sc_log_config->op_filter_regex, - sc_log_config->op_filter_regex_study, - buffer, strlen(buffer), 0, 0, ov, MAX_SUBSTRINGS) < 0) - { - return SC_ERR_LOG_FG_FILTER_MATCH; // bit hacky, but just return !0 - } -#undef MAX_SUBSTRINGS - } - - return SC_OK; - - error: - if (temp_fmt_h != NULL) - SCFree(temp_fmt_h); - return SC_ERR_SPRINTF; -} - -/** - * \brief Adds the global log_format to the outgoing buffer - * - * \param log_level log_level of the message that has to be logged - * \param msg Buffer containing the outgoing message - * \param file File_name from where the message originated - * \param function Function_name from where the message originated - * \param line Line_no from where the messaged originated - * - * \retval SC_OK on success; else an error code - */ -SCError SCLogMessage(const SCLogLevel log_level, const char *file, - const unsigned int line, const char *function, - const SCError error_code, const char *message) -{ - char buffer[SC_LOG_MAX_LOG_MSG_LEN] = ""; - SCLogOPIfaceCtx *op_iface_ctx = NULL; - - if (sc_log_module_initialized != 1) { - printf("Logging module not initialized. Call SCLogInitLogModule() " - "first before using the debug API\n"); - return SC_OK; - } - - /* get ts here so we log the same ts to each output */ - struct timeval tval; - gettimeofday(&tval, NULL); - - op_iface_ctx = sc_log_config->op_ifaces; - while (op_iface_ctx != NULL) { - if (log_level != SC_LOG_NOTSET && log_level > op_iface_ctx->log_level) { - op_iface_ctx = op_iface_ctx->next; - continue; - } - - switch (op_iface_ctx->iface) { - case SC_LOG_OP_IFACE_CONSOLE: - if (SCLogMessageGetBuffer(&tval, op_iface_ctx->use_color, op_iface_ctx->type, - buffer, sizeof(buffer), - op_iface_ctx->log_format ? - op_iface_ctx->log_format : sc_log_config->log_format, - log_level, file, line, function, - error_code, message) == 0) - { - SCLogPrintToStream((log_level == SC_LOG_ERROR)? stderr: stdout, buffer); - } - break; - case SC_LOG_OP_IFACE_FILE: - if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer), - op_iface_ctx->log_format ? - op_iface_ctx->log_format : sc_log_config->log_format, - log_level, file, line, function, - error_code, message) == 0) - { - SCLogPrintToStream(op_iface_ctx->file_d, buffer); - } - break; - case SC_LOG_OP_IFACE_SYSLOG: - if (SCLogMessageGetBuffer(&tval, 0, op_iface_ctx->type, buffer, sizeof(buffer), - op_iface_ctx->log_format ? - op_iface_ctx->log_format : sc_log_config->log_format, - log_level, file, line, function, - error_code, message) == 0) - { - SCLogPrintToSyslog(SCLogMapLogLevelToSyslogLevel(log_level), buffer); - } - break; - default: - break; - } - op_iface_ctx = op_iface_ctx->next; - } - return SC_OK; -} - -/** - * \brief Returns whether debug messages are enabled to be logged or not - * - * \retval 1 if debug messages are enabled to be logged - * \retval 0 if debug messages are not enabled to be logged - */ -int SCLogDebugEnabled(void) -{ -#ifdef DEBUG - if (sc_log_global_log_level == SC_LOG_DEBUG) - return 1; - else - return 0; -#else - return 0; -#endif -} - -/** - * \brief Allocates an output buffer for an output interface. Used when we - * want the op_interface log_format to override the global_log_format. - * Currently not used. - * - * \retval buffer Pointer to the newly created output_buffer - */ -SCLogOPBuffer *SCLogAllocLogOPBuffer(void) -{ - SCLogOPBuffer *buffer = NULL; - SCLogOPIfaceCtx *op_iface_ctx = NULL; - int i = 0; - - if ( (buffer = SCMalloc(sc_log_config->op_ifaces_cnt * - sizeof(SCLogOPBuffer))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogAllocLogOPBuffer. Exiting..."); - exit(EXIT_FAILURE); - } - - op_iface_ctx = sc_log_config->op_ifaces; - for (i = 0; - i < sc_log_config->op_ifaces_cnt; - i++, op_iface_ctx = op_iface_ctx->next) { - buffer[i].log_format = op_iface_ctx->log_format; - buffer[i].temp = buffer[i].msg; - } - - return buffer; -} - -/*----------------------The logging module initialization code--------------- */ - -/** - * \brief Returns a new output_interface_context - * - * \retval iface_ctx Pointer to a newly allocated output_interface_context - * \initonly - */ -static inline SCLogOPIfaceCtx *SCLogAllocLogOPIfaceCtx() -{ - SCLogOPIfaceCtx *iface_ctx = NULL; - - if ( (iface_ctx = SCMalloc(sizeof(SCLogOPIfaceCtx))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogallocLogOPIfaceCtx. Exiting..."); - exit(EXIT_FAILURE); - } - memset(iface_ctx, 0, sizeof(SCLogOPIfaceCtx)); - - return iface_ctx; -} - -/** - * \brief Initializes the file output interface - * - * \param file Path to the file used for logging purposes - * \param log_format Pointer to the log_format for this op interface, that - * overrides the global_log_format - * \param log_level Override of the global_log_level by this interface - * - * \retval iface_ctx Pointer to the file output interface context created - * \initonly - */ -static inline SCLogOPIfaceCtx *SCLogInitFileOPIface(const char *file, - const char *log_format, - int log_level, - SCLogOPType type) -{ - SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx(); - - if (iface_ctx == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitFileOPIface. Exiting..."); - exit(EXIT_FAILURE); - } - - if (file == NULL || log_format == NULL) { - goto error; - } - - iface_ctx->iface = SC_LOG_OP_IFACE_FILE; - iface_ctx->type = type; - - if ( (iface_ctx->file_d = fopen(file, "w+")) == NULL) { - printf("Error opening file %s\n", file); - goto error; - } - - if ((iface_ctx->file = SCStrdup(file)) == NULL) { - goto error; - } - - if ((iface_ctx->log_format = SCStrdup(log_format)) == NULL) { - goto error; - } - - iface_ctx->log_level = log_level; - - return iface_ctx; - -error: - if (iface_ctx->file != NULL) { - SCFree((char *)iface_ctx->file); - iface_ctx->file = NULL; - } - if (iface_ctx->log_format != NULL) { - SCFree((char *)iface_ctx->log_format); - iface_ctx->log_format = NULL; - } - if (iface_ctx->file_d != NULL) { - fclose(iface_ctx->file_d); - iface_ctx->file_d = NULL; - } - return NULL; -} - -/** - * \brief Initializes the console output interface and deals with possible - * env var overrides. - * - * \param log_format Pointer to the log_format for this op interface, that - * overrides the global_log_format - * \param log_level Override of the global_log_level by this interface - * - * \retval iface_ctx Pointer to the console output interface context created - * \initonly - */ -static inline SCLogOPIfaceCtx *SCLogInitConsoleOPIface(const char *log_format, - SCLogLevel log_level, SCLogOPType type) -{ - SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx(); - - if (iface_ctx == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitConsoleOPIface. Exiting..."); - exit(EXIT_FAILURE); - } - - iface_ctx->iface = SC_LOG_OP_IFACE_CONSOLE; - iface_ctx->type = type; - - /* console log format is overridden by envvars */ - const char *tmp_log_format = log_format; - const char *s = getenv(SC_LOG_ENV_LOG_FORMAT); - if (s != NULL) { -#if 0 - printf("Overriding setting for \"console.format\" because of env " - "var SC_LOG_FORMAT=\"%s\".\n", s); -#endif - tmp_log_format = s; - } - - if (tmp_log_format != NULL && - (iface_ctx->log_format = SCStrdup(tmp_log_format)) == NULL) { - printf("Error allocating memory\n"); - exit(EXIT_FAILURE); - } - - /* console log level is overridden by envvars */ - SCLogLevel tmp_log_level = log_level; - s = getenv(SC_LOG_ENV_LOG_LEVEL); - if (s != NULL) { - SCLogLevel l = SCMapEnumNameToValue(s, sc_log_level_map); - if (l > SC_LOG_NOTSET && l < SC_LOG_LEVEL_MAX) { -#if 0 - printf("Overriding setting for \"console.level\" because of env " - "var SC_LOG_LEVEL=\"%s\".\n", s); -#endif - tmp_log_level = l; - } - } - iface_ctx->log_level = tmp_log_level; - - if (isatty(fileno(stdout)) && isatty(fileno(stderr))) { - iface_ctx->use_color = TRUE; - } - - return iface_ctx; -} - -/** - * \brief Initializes the syslog output interface - * - * \param facility The facility code for syslog - * \param log_format Pointer to the log_format for this op interface, that - * overrides the global_log_format - * \param log_level Override of the global_log_level by this interface - * - * \retval iface_ctx Pointer to the syslog output interface context created - */ -static inline SCLogOPIfaceCtx *SCLogInitSyslogOPIface(int facility, - const char *log_format, - SCLogLevel log_level, - SCLogOPType type) -{ - SCLogOPIfaceCtx *iface_ctx = SCLogAllocLogOPIfaceCtx(); - - if ( iface_ctx == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitSyslogOPIface. Exiting..."); - exit(EXIT_FAILURE); - } - - iface_ctx->iface = SC_LOG_OP_IFACE_SYSLOG; - iface_ctx->type = type; - - if (facility == -1) - facility = SC_LOG_DEF_SYSLOG_FACILITY; - iface_ctx->facility = facility; - - if (log_format != NULL && - (iface_ctx->log_format = SCStrdup(log_format)) == NULL) { - printf("Error allocating memory\n"); - exit(EXIT_FAILURE); - } - - iface_ctx->log_level = log_level; - - openlog(NULL, LOG_NDELAY, iface_ctx->facility); - - return iface_ctx; -} - -/** - * \brief Frees the output_interface context supplied as an argument - * - * \param iface_ctx Pointer to the op_interface_context to be freed - */ -static inline void SCLogFreeLogOPIfaceCtx(SCLogOPIfaceCtx *iface_ctx) -{ - SCLogOPIfaceCtx *temp = NULL; - - while (iface_ctx != NULL) { - temp = iface_ctx; - - if (iface_ctx->file_d != NULL) - fclose(iface_ctx->file_d); - - if (iface_ctx->file != NULL) - SCFree((void *)iface_ctx->file); - - if (iface_ctx->log_format != NULL) - SCFree((void *)iface_ctx->log_format); - - if (iface_ctx->iface == SC_LOG_OP_IFACE_SYSLOG) { - closelog(); - } - - iface_ctx = iface_ctx->next; - - SCFree(temp); - } - - return; -} - -/** - * \brief Internal function used to set the logging module global_log_level - * during the initialization phase - * - * \param sc_lid The initialization data supplied. - * \param sc_lc The logging module context which has to be updated. - */ -static inline void SCLogSetLogLevel(SCLogInitData *sc_lid, SCLogConfig *sc_lc) -{ - SCLogLevel log_level = SC_LOG_NOTSET; - const char *s = NULL; - - /* envvar overrides config */ - s = getenv(SC_LOG_ENV_LOG_LEVEL); - if (s != NULL) { - log_level = SCMapEnumNameToValue(s, sc_log_level_map); - } else if (sc_lid != NULL) { - log_level = sc_lid->global_log_level; - } - - /* deal with the global_log_level to be used */ - if (log_level > SC_LOG_NOTSET && log_level < SC_LOG_LEVEL_MAX) - sc_lc->log_level = log_level; - else { - sc_lc->log_level = SC_LOG_DEF_LOG_LEVEL; -#ifndef UNITTESTS - if (sc_lid != NULL) { - printf("Warning: Invalid/No global_log_level assigned by user. Falling " - "back on the default_log_level \"%s\"\n", - SCMapEnumValueToName(sc_lc->log_level, sc_log_level_map)); - } -#endif - } - - /* we also set it to a global var, as it is easier to access it */ - sc_log_global_log_level = sc_lc->log_level; - - return; -} - -/** - * \brief Internal function used to set the logging module global_log_format - * during the initialization phase - * - * \param sc_lid The initialization data supplied. - * \param sc_lc The logging module context which has to be updated. - */ -static inline void SCLogSetLogFormat(SCLogInitData *sc_lid, SCLogConfig *sc_lc) -{ - char *format = NULL; - - /* envvar overrides config */ - format = getenv(SC_LOG_ENV_LOG_FORMAT); - if (format == NULL) { - if (sc_lid != NULL) { - format = sc_lid->global_log_format; - } - } - - /* deal with the global log format to be used */ - if (format == NULL || strlen(format) > SC_LOG_MAX_LOG_FORMAT_LEN) { - format = SC_LOG_DEF_LOG_FORMAT; -#ifndef UNITTESTS - if (sc_lid != NULL) { - printf("Warning: Invalid/No global_log_format supplied by user or format " - "length exceeded limit of \"%d\" characters. Falling back on " - "default log_format \"%s\"\n", SC_LOG_MAX_LOG_FORMAT_LEN, - format); - } -#endif - } - - if (format != NULL && (sc_lc->log_format = SCStrdup(format)) == NULL) { - printf("Error allocating memory\n"); - exit(EXIT_FAILURE); - } - - return; -} - -/** - * \brief Internal function used to set the logging module global_op_ifaces - * during the initialization phase - * - * \param sc_lid The initialization data supplied. - * \param sc_lc The logging module context which has to be updated. - */ -static inline void SCLogSetOPIface(SCLogInitData *sc_lid, SCLogConfig *sc_lc) -{ - SCLogOPIfaceCtx *op_ifaces_ctx = NULL; - int op_iface = 0; - const char *s = NULL; - - if (sc_lid != NULL && sc_lid->op_ifaces != NULL) { - sc_lc->op_ifaces = sc_lid->op_ifaces; - sc_lid->op_ifaces = NULL; - sc_lc->op_ifaces_cnt = sc_lid->op_ifaces_cnt; - } else { - s = getenv(SC_LOG_ENV_LOG_OP_IFACE); - if (s != NULL) { - op_iface = SCMapEnumNameToValue(s, sc_log_op_iface_map); - - if(op_iface < 0 || op_iface >= SC_LOG_OP_IFACE_MAX) { - op_iface = SC_LOG_DEF_LOG_OP_IFACE; -#ifndef UNITTESTS - printf("Warning: Invalid output interface supplied by user. " - "Falling back on default_output_interface \"%s\"\n", - SCMapEnumValueToName(op_iface, sc_log_op_iface_map)); -#endif - } - } - else { - op_iface = SC_LOG_DEF_LOG_OP_IFACE; -#ifndef UNITTESTS - if (sc_lid != NULL) { - printf("Warning: Output_interface not supplied by user. Falling " - "back on default_output_interface \"%s\"\n", - SCMapEnumValueToName(op_iface, sc_log_op_iface_map)); - } -#endif - } - - switch (op_iface) { - case SC_LOG_OP_IFACE_CONSOLE: - op_ifaces_ctx = SCLogInitConsoleOPIface(NULL, SC_LOG_LEVEL_MAX,0); - break; - case SC_LOG_OP_IFACE_FILE: - s = getenv(SC_LOG_ENV_LOG_FILE); - if (s == NULL) { - char *str = SCLogGetLogFilename(SC_LOG_DEF_LOG_FILE); - if (str != NULL) { - op_ifaces_ctx = SCLogInitFileOPIface(str, NULL, SC_LOG_LEVEL_MAX,0); - SCFree(str); - } - } else { - op_ifaces_ctx = SCLogInitFileOPIface(s, NULL, SC_LOG_LEVEL_MAX,0); - } - break; - case SC_LOG_OP_IFACE_SYSLOG: - s = getenv(SC_LOG_ENV_LOG_FACILITY); - if (s == NULL) - s = SC_LOG_DEF_SYSLOG_FACILITY_STR; - - op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCSyslogGetFacilityMap()), NULL, -1,0); - break; - } - sc_lc->op_ifaces = op_ifaces_ctx; - sc_lc->op_ifaces_cnt++; - } - return; -} - -/** - * \brief Internal function used to set the logging module op_filter - * during the initialization phase - * - * \param sc_lid The initialization data supplied. - * \param sc_lc The logging module context which has to be updated. - */ -static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc) -{ - const char *filter = NULL; - - int opts = 0; - const char *ep; - int eo = 0; - - /* envvar overrides */ - filter = getenv(SC_LOG_ENV_LOG_OP_FILTER); - if (filter == NULL) { - if (sc_lid != NULL) { - filter = sc_lid->op_filter; - } - } - - if (filter != NULL && strcmp(filter, "") != 0) { - sc_lc->op_filter = SCStrdup(filter); - if (sc_lc->op_filter == NULL) { - printf("pcre filter alloc failed\n"); - return; - } - sc_lc->op_filter_regex = pcre_compile(filter, opts, &ep, &eo, NULL); - if (sc_lc->op_filter_regex == NULL) { - SCFree(sc_lc->op_filter); - printf("pcre compile of \"%s\" failed at offset %d : %s\n", filter, - eo, ep); - return; - } - - sc_lc->op_filter_regex_study = pcre_study(sc_lc->op_filter_regex, 0, - &ep); - if (ep != NULL) { - printf("pcre study failed: %s\n", ep); - return; - } - } - - return; -} - -/** - * \brief Returns a pointer to a new SCLogInitData. This is a public interface - * intended to be used after the logging paramters are read from the - * conf file - * - * \retval sc_lid Pointer to the newly created SCLogInitData - * \initonly - */ -SCLogInitData *SCLogAllocLogInitData(void) -{ - SCLogInitData *sc_lid = NULL; - - /* not using SCMalloc here because if it fails we can't log */ - if ( (sc_lid = SCMalloc(sizeof(SCLogInitData))) == NULL) - return NULL; - - memset(sc_lid, 0, sizeof(SCLogInitData)); - - return sc_lid; -} - -/** - * \brief Frees a SCLogInitData - * - * \param sc_lid Pointer to the SCLogInitData to be freed - */ -void SCLogFreeLogInitData(SCLogInitData *sc_lid) -{ - if (sc_lid != NULL) { - if (sc_lid->startup_message != NULL) - SCFree(sc_lid->startup_message); - if (sc_lid->global_log_format != NULL) - SCFree(sc_lid->global_log_format); - if (sc_lid->op_filter != NULL) - SCFree(sc_lid->op_filter); - - SCLogFreeLogOPIfaceCtx(sc_lid->op_ifaces); - } - - return; -} - -/** - * \brief Frees the logging module context - */ -static inline void SCLogFreeLogConfig(SCLogConfig *sc_lc) -{ - if (sc_lc != NULL) { - if (sc_lc->startup_message != NULL) - SCFree(sc_lc->startup_message); - if (sc_lc->log_format != NULL) - SCFree(sc_lc->log_format); - if (sc_lc->op_filter != NULL) - SCFree(sc_lc->op_filter); - - SCLogFreeLogOPIfaceCtx(sc_lc->op_ifaces); - SCFree(sc_lc); - } - - return; -} - -/** - * \brief Appends an output_interface to the output_interface list sent in head - * - * \param iface_ctx Pointer to the output_interface that has to be added to head - * \param head Pointer to the output_interface list - */ -void SCLogAppendOPIfaceCtx(SCLogOPIfaceCtx *iface_ctx, SCLogInitData *sc_lid) -{ - SCLogOPIfaceCtx *temp = NULL, *prev = NULL; - SCLogOPIfaceCtx **head = &sc_lid->op_ifaces; - - if (iface_ctx == NULL) { -#ifdef DEBUG - printf("Argument(s) to SCLogAppendOPIfaceCtx() NULL\n"); -#endif - return; - } - - temp = *head; - while (temp != NULL) { - prev = temp; - temp = temp->next; - } - - if (prev == NULL) - *head = iface_ctx; - else - prev->next = iface_ctx; - - sc_lid->op_ifaces_cnt++; - - return; -} - - -/** - * \brief Creates a new output interface based on the arguments sent. The kind - * of output interface to be created is decided by the iface_name arg. - * If iface_name is "file", the arg argument will hold the filename to be - * used for logging purposes. If iface_name is "syslog", the arg - * argument holds the facility code. If iface_name is "console", arg is - * NULL. - * - * \param iface_name Interface name. Can be "console", "file" or "syslog" - * \param log_format Override for the global_log_format - * \param log_level Override for the global_log_level - * \param log_level Parameter required by a particular interface. Explained in - * the function description - * - * \retval iface_ctx Pointer to the newly created output interface - */ -SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *iface_name, - const char *log_format, - int log_level, const char *arg) -{ - int iface = SCMapEnumNameToValue(iface_name, sc_log_op_iface_map); - - if (log_level < SC_LOG_NONE || log_level > SC_LOG_DEBUG) { -#ifndef UNITTESTS - printf("Warning: Supplied log_level_override for op_interface \"%s\" " - "is invalid. Defaulting to not specifying an override\n", - iface_name); -#endif - log_level = SC_LOG_NOTSET; - } - - switch (iface) { - case SC_LOG_OP_IFACE_CONSOLE: - return SCLogInitConsoleOPIface(log_format, log_level, SC_LOG_OP_TYPE_REGULAR); - case SC_LOG_OP_IFACE_FILE: - return SCLogInitFileOPIface(arg, log_format, log_level, SC_LOG_OP_TYPE_REGULAR); - case SC_LOG_OP_IFACE_SYSLOG: - return SCLogInitSyslogOPIface(SCMapEnumNameToValue(arg, SCSyslogGetFacilityMap()), - log_format, log_level, SC_LOG_OP_TYPE_REGULAR); - default: -#ifdef DEBUG - printf("Output Interface \"%s\" not supported by the logging module", - iface_name); -#endif - return NULL; - } -} - -/** - * \brief Initializes the logging module. - * - * \param sc_lid The initialization data for the logging module. If sc_lid is - * NULL, we would stick to the default configuration for the - * logging subsystem. - * \initonly - */ -void SCLogInitLogModule(SCLogInitData *sc_lid) -{ - /* De-initialize the logging context, if it has already init by the - * environment variables at the start of the engine */ - SCLogDeInitLogModule(); - -#if defined (OS_WIN32) - if (SCMutexInit(&sc_log_stream_lock, NULL) != 0) { - SCLogError(SC_ERR_MUTEX, "Failed to initialize log mutex."); - exit(EXIT_FAILURE); - } -#endif /* OS_WIN32 */ - - /* sc_log_config is a global variable */ - if ( (sc_log_config = SCMalloc(sizeof(SCLogConfig))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCLogInitLogModule. Exiting..."); - exit(EXIT_FAILURE); - } - memset(sc_log_config, 0, sizeof(SCLogConfig)); - - SCLogSetLogLevel(sc_lid, sc_log_config); - SCLogSetLogFormat(sc_lid, sc_log_config); - SCLogSetOPIface(sc_lid, sc_log_config); - SCLogSetOPFilter(sc_lid, sc_log_config); - - sc_log_module_initialized = 1; - sc_log_module_cleaned = 0; - - //SCOutputPrint(sc_did->startup_message); - - return; -} - -void SCLogLoadConfig(int daemon, int verbose) -{ - ConfNode *outputs; - SCLogInitData *sc_lid; - int have_logging = 0; - - outputs = ConfGetNode("logging.outputs"); - if (outputs == NULL) { - SCLogDebug("No logging.output configuration section found."); - return; - } - - sc_lid = SCLogAllocLogInitData(); - if (sc_lid == NULL) { - SCLogDebug("Could not allocate memory for log init data"); - return; - } - - /* Get default log level and format. */ - char *default_log_level_s = NULL; - if (ConfGet("logging.default-log-level", &default_log_level_s) == 1) { - sc_lid->global_log_level = - SCMapEnumNameToValue(default_log_level_s, sc_log_level_map); - if (sc_lid->global_log_level == -1) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid default log level: %s", - default_log_level_s); - exit(EXIT_FAILURE); - } - } - else { - SCLogWarning(SC_ERR_MISSING_CONFIG_PARAM, - "No default log level set, will use notice."); - sc_lid->global_log_level = SC_LOG_NOTICE; - } - - if (verbose) { - sc_lid->global_log_level += verbose; - if (sc_lid->global_log_level > SC_LOG_LEVEL_MAX) - sc_lid->global_log_level = SC_LOG_LEVEL_MAX; - } - - if (ConfGet("logging.default-log-format", &sc_lid->global_log_format) != 1) - sc_lid->global_log_format = SC_LOG_DEF_LOG_FORMAT; - - ConfGet("logging.default-output-filter", &sc_lid->op_filter); - - ConfNode *seq_node, *output; - TAILQ_FOREACH(seq_node, &outputs->head, next) { - SCLogLevel level = sc_lid->global_log_level; - SCLogOPIfaceCtx *op_iface_ctx = NULL; - const char *format; - const char *level_s; - - output = ConfNodeLookupChild(seq_node, seq_node->val); - if (output == NULL) - continue; - - /* By default an output is enabled. */ - const char *enabled = ConfNodeLookupChildValue(output, "enabled"); - if (enabled != NULL && ConfValIsFalse(enabled)) - continue; - - SCLogOPType type = SC_LOG_OP_TYPE_REGULAR; - const char *type_s = ConfNodeLookupChildValue(output, "type"); - if (type_s != NULL) { - if (strcmp(type_s, "regular") == 0) - type = SC_LOG_OP_TYPE_REGULAR; - else if (strcmp(type_s, "json") == 0) { -#ifdef HAVE_LIBJANSSON - type = SC_LOG_OP_TYPE_JSON; -#else - SCLogError(SC_ERR_INVALID_ARGUMENT, "libjansson support not " - "compiled in, can't use 'json' logging"); - exit(EXIT_FAILURE); -#endif /* HAVE_LIBJANSSON */ - } - } - - /* if available use the log format setting for this output, - * otherwise fall back to the global setting. */ - format = ConfNodeLookupChildValue(output, "format"); - if (format == NULL) - format = sc_lid->global_log_format; - - level_s = ConfNodeLookupChildValue(output, "level"); - if (level_s != NULL) { - level = SCMapEnumNameToValue(level_s, sc_log_level_map); - if (level == -1) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid log level: %s", - level_s); - exit(EXIT_FAILURE); - } - } - - if (strcmp(output->name, "console") == 0) { - op_iface_ctx = SCLogInitConsoleOPIface(format, level, type); - } - else if (strcmp(output->name, "file") == 0) { - const char *filename = ConfNodeLookupChildValue(output, "filename"); - if (filename == NULL) { - SCLogError(SC_ERR_MISSING_CONFIG_PARAM, - "Logging to file requires a filename"); - exit(EXIT_FAILURE); - } - have_logging = 1; - op_iface_ctx = SCLogInitFileOPIface(filename, format, level, type); - } - else if (strcmp(output->name, "syslog") == 0) { - int facility = SC_LOG_DEF_SYSLOG_FACILITY; - const char *facility_s = ConfNodeLookupChildValue(output, - "facility"); - if (facility_s != NULL) { - facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); - if (facility == -1) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog " - "facility: \"%s\", now using \"%s\" as syslog " - "facility", facility_s, SC_LOG_DEF_SYSLOG_FACILITY_STR); - facility = SC_LOG_DEF_SYSLOG_FACILITY; - } - } - printf("Initialization syslog logging with format \"%s\".\n", - format); - have_logging = 1; - op_iface_ctx = SCLogInitSyslogOPIface(facility, format, level, type); - } - else { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid logging method: %s, " - "ignoring", output->name); - } - if (op_iface_ctx != NULL) { - SCLogAppendOPIfaceCtx(op_iface_ctx, sc_lid); - } - } - - if (daemon && (have_logging == 0)) { - SCLogError(SC_ERR_MISSING_CONFIG_PARAM, - "NO logging compatible with daemon mode selected," - " suricata won't be able to log. Please update " - " 'logging.outputs' in the YAML."); - } - - SCLogInitLogModule(sc_lid); - - SCLogDebug("sc_log_global_log_level: %d", sc_log_global_log_level); - SCLogDebug("sc_lc->log_format: %s", sc_log_config->log_format); - SCLogDebug("SCLogSetOPFilter: filter: %s", sc_log_config->op_filter); - - if (sc_lid != NULL) - SCFree(sc_lid); -} - -/** - * \brief Returns a full file path given a filename uses log dir specified in - * conf or DEFAULT_LOG_DIR - * - * \param filearg The relative filename for which we want a full path include - * log directory - * - * \retval log_filename The fullpath of the logfile to open - */ -static char *SCLogGetLogFilename(char *filearg) -{ - char *log_dir; - char *log_filename; - - log_dir = ConfigGetLogDirectory(); - - log_filename = SCMalloc(PATH_MAX); - if (unlikely(log_filename == NULL)) - return NULL; - snprintf(log_filename, PATH_MAX, "%s/%s", log_dir, filearg); - - return log_filename; -} - -/** - * \brief De-Initializes the logging module - */ -void SCLogDeInitLogModule(void) -{ - SCLogFreeLogConfig(sc_log_config); - - /* reset the global logging_module variables */ - sc_log_global_log_level = 0; - sc_log_module_initialized = 0; - sc_log_module_cleaned = 1; - sc_log_config = NULL; - - /* de-init the FD filters */ - SCLogReleaseFDFilters(); - /* de-init the FG filters */ - SCLogReleaseFGFilters(); - -#if defined (OS_WIN32) - if (sc_log_stream_lock != NULL) { - SCMutexDestroy(&sc_log_stream_lock); - sc_log_stream_lock = NULL; - } -#endif /* OS_WIN32 */ - - return; -} - -//------------------------------------Unit_Tests-------------------------------- - -/* The logging engine should be tested to the maximum extent possible, since - * logging code would be used throughout the codebase, and hence we can't afford - * to have a single bug here(not that you can afford to have a bug - * elsewhere ;) ). Please report a bug, if you get a slightest hint of a bug - * from the logging module. - */ - -#ifdef UNITTESTS - -int SCLogTestInit01() -{ - int result = 1; - - /* unset any environment variables set for the logging module */ - unsetenv(SC_LOG_ENV_LOG_LEVEL); - unsetenv(SC_LOG_ENV_LOG_OP_IFACE); - unsetenv(SC_LOG_ENV_LOG_FORMAT); - - SCLogInitLogModule(NULL); - - if (sc_log_config == NULL) - return 0; - - result &= (SC_LOG_DEF_LOG_LEVEL == sc_log_config->log_level); - result &= (sc_log_config->op_ifaces != NULL && - SC_LOG_DEF_LOG_OP_IFACE == sc_log_config->op_ifaces->iface); - result &= (sc_log_config->log_format != NULL && - strcmp(SC_LOG_DEF_LOG_FORMAT, sc_log_config->log_format) == 0); - - SCLogDeInitLogModule(); - - setenv(SC_LOG_ENV_LOG_LEVEL, "Debug", 1); - setenv(SC_LOG_ENV_LOG_OP_IFACE, "Console", 1); - setenv(SC_LOG_ENV_LOG_FORMAT, "%n- %l", 1); - - SCLogInitLogModule(NULL); - - result &= (SC_LOG_DEBUG == sc_log_config->log_level); - result &= (sc_log_config->op_ifaces != NULL && - SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface); - result &= (sc_log_config->log_format != NULL && - !strcmp("%n- %l", sc_log_config->log_format)); - - unsetenv(SC_LOG_ENV_LOG_LEVEL); - unsetenv(SC_LOG_ENV_LOG_OP_IFACE); - unsetenv(SC_LOG_ENV_LOG_FORMAT); - - SCLogDeInitLogModule(); - - return result; -} - -int SCLogTestInit02() -{ - SCLogInitData *sc_lid = NULL; - SCLogOPIfaceCtx *sc_iface_ctx = NULL; - int result = 1; - char *logfile = SCLogGetLogFilename("boo.txt"); - sc_lid = SCLogAllocLogInitData(); - if (sc_lid == NULL) - return 0; - sc_lid->startup_message = "Test02"; - sc_lid->global_log_level = SC_LOG_DEBUG; - sc_lid->op_filter = "boo"; - sc_iface_ctx = SCLogInitOPIfaceCtx("file", "%m - %d", SC_LOG_ALERT, - logfile); - SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid); - sc_iface_ctx = SCLogInitOPIfaceCtx("console", NULL, SC_LOG_ERROR, - NULL); - SCLogAppendOPIfaceCtx(sc_iface_ctx, sc_lid); - - SCLogInitLogModule(sc_lid); - - if (sc_log_config == NULL) - return 0; - - result &= (SC_LOG_DEBUG == sc_log_config->log_level); - result &= (sc_log_config->op_ifaces != NULL && - SC_LOG_OP_IFACE_FILE == sc_log_config->op_ifaces->iface); - result &= (sc_log_config->op_ifaces != NULL && - sc_log_config->op_ifaces->next != NULL && - SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->next->iface); - result &= (sc_log_config->log_format != NULL && - strcmp(SC_LOG_DEF_LOG_FORMAT, sc_log_config->log_format) == 0); - result &= (sc_log_config->op_ifaces != NULL && - sc_log_config->op_ifaces->log_format != NULL && - strcmp("%m - %d", sc_log_config->op_ifaces->log_format) == 0); - result &= (sc_log_config->op_ifaces != NULL && - sc_log_config->op_ifaces->next != NULL && - sc_log_config->op_ifaces->next->log_format == NULL); - - SCLogDeInitLogModule(); - - sc_lid = SCLogAllocLogInitData(); - if (sc_lid == NULL) - return 0; - sc_lid->startup_message = "Test02"; - sc_lid->global_log_level = SC_LOG_DEBUG; - sc_lid->op_filter = "boo"; - sc_lid->global_log_format = "kaboo"; - - SCLogInitLogModule(sc_lid); - - if (sc_log_config == NULL) - return 0; - - result &= (SC_LOG_DEBUG == sc_log_config->log_level); - result &= (sc_log_config->op_ifaces != NULL && - SC_LOG_OP_IFACE_CONSOLE == sc_log_config->op_ifaces->iface); - result &= (sc_log_config->op_ifaces != NULL && - sc_log_config->op_ifaces->next == NULL); - result &= (sc_log_config->log_format != NULL && - strcmp("kaboo", sc_log_config->log_format) == 0); - result &= (sc_log_config->op_ifaces != NULL && - sc_log_config->op_ifaces->log_format == NULL); - result &= (sc_log_config->op_ifaces != NULL && - sc_log_config->op_ifaces->next == NULL); - - SCLogDeInitLogModule(); - - return result; -} - -int SCLogTestInit03() -{ - int result = 1; - - SCLogInitLogModule(NULL); - - SCLogAddFGFilterBL(NULL, "bamboo", -1); - SCLogAddFGFilterBL(NULL, "soo", -1); - SCLogAddFGFilterBL(NULL, "dummy", -1); - - result &= (SCLogPrintFGFilters() == 3); - - SCLogAddFGFilterBL(NULL, "dummy1", -1); - SCLogAddFGFilterBL(NULL, "dummy2", -1); - - result &= (SCLogPrintFGFilters() == 5); - - SCLogDeInitLogModule(); - - return result; -} - -int SCLogTestInit04() -{ - int result = 1; - - SCLogInitLogModule(NULL); - - SCLogAddFDFilter("bamboo"); - SCLogAddFDFilter("soo"); - SCLogAddFDFilter("foo"); - SCLogAddFDFilter("roo"); - - result &= (SCLogPrintFDFilters() == 4); - - SCLogAddFDFilter("loo"); - SCLogAddFDFilter("soo"); - - result &= (SCLogPrintFDFilters() == 5); - - SCLogRemoveFDFilter("bamboo"); - SCLogRemoveFDFilter("soo"); - SCLogRemoveFDFilter("foo"); - SCLogRemoveFDFilter("noo"); - - result &= (SCLogPrintFDFilters() == 2); - - SCLogDeInitLogModule(); - - return result; -} - -int SCLogTestInit05() -{ - int result = 1; - - SCLogInfo("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); - - return result; -} - - -#endif /* UNITTESTS */ - -void SCLogRegisterTests() -{ - -#ifdef UNITTESTS - - UtRegisterTest("SCLogTestInit01", SCLogTestInit01, 1); - UtRegisterTest("SCLogTestInit02", SCLogTestInit02, 1); - UtRegisterTest("SCLogTestInit03", SCLogTestInit03, 1); - UtRegisterTest("SCLogTestInit04", SCLogTestInit04, 1); - UtRegisterTest("SCLogTestInit05", SCLogTestInit05, 1); - -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/util-debug.h b/framework/src/suricata/src/util-debug.h deleted file mode 100644 index 9c9d2e23..00000000 --- a/framework/src/suricata/src/util-debug.h +++ /dev/null @@ -1,551 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_DEBUG_H__ -#define __UTIL_DEBUG_H__ - -#include -#include -#include - -#include "threads.h" -#include "util-enum.h" -#include "util-error.h" -#include "util-debug-filters.h" - -/** - * \brief ENV vars that can be used to set the properties for the logging module - */ -#define SC_LOG_ENV_LOG_LEVEL "SC_LOG_LEVEL" -#define SC_LOG_ENV_LOG_OP_IFACE "SC_LOG_OP_IFACE" -#define SC_LOG_ENV_LOG_FILE "SC_LOG_FILE" -#define SC_LOG_ENV_LOG_FACILITY "SC_LOG_FACILITY" -#define SC_LOG_ENV_LOG_FORMAT "SC_LOG_FORMAT" -#define SC_LOG_ENV_LOG_OP_FILTER "SC_LOG_OP_FILTER" - -/** - * \brief The various log levels - */ -typedef enum { - SC_LOG_NOTSET = -1, - SC_LOG_NONE = 0, - SC_LOG_EMERGENCY, - SC_LOG_ALERT, - SC_LOG_CRITICAL, - SC_LOG_ERROR, - SC_LOG_WARNING, - SC_LOG_NOTICE, - SC_LOG_INFO, - SC_LOG_DEBUG, - SC_LOG_LEVEL_MAX, -} SCLogLevel; - -/** - * \brief The various output interfaces supported - */ -typedef enum { - SC_LOG_OP_IFACE_CONSOLE, - SC_LOG_OP_IFACE_FILE, - SC_LOG_OP_IFACE_SYSLOG, - SC_LOG_OP_IFACE_MAX, -} SCLogOPIface; - -typedef enum { - SC_LOG_OP_TYPE_REGULAR = 0, - SC_LOG_OP_TYPE_JSON, -} SCLogOPType; - -/* The default log_format, if it is not supplied by the user */ -#ifdef RELEASE -#define SC_LOG_DEF_LOG_FORMAT "%t - <%d> - " -#else -#define SC_LOG_DEF_LOG_FORMAT "[%i] %t - (%f:%l) <%d> (%n) -- " -#endif - -/* The maximum length of the log message */ -#define SC_LOG_MAX_LOG_MSG_LEN 2048 - -/* The maximum length of the log format */ -#define SC_LOG_MAX_LOG_FORMAT_LEN 128 - -/* The default log level, if it is not supplied by the user */ -#define SC_LOG_DEF_LOG_LEVEL SC_LOG_INFO - -/* The default output interface to be used */ -#define SC_LOG_DEF_LOG_OP_IFACE SC_LOG_OP_IFACE_CONSOLE - -/* The default log file to be used */ -#define SC_LOG_DEF_LOG_FILE "sc_ids_log.log" - -/* The default syslog facility to be used */ -#define SC_LOG_DEF_SYSLOG_FACILITY_STR "local0" -#define SC_LOG_DEF_SYSLOG_FACILITY LOG_LOCAL0 - -/** - * \brief Structure to be used when log_level override support would be provided - * by the logging module - */ -typedef struct SCLogOPBuffer_ { - char msg[SC_LOG_MAX_LOG_MSG_LEN]; - char *temp; - const char *log_format; -} SCLogOPBuffer; - -/** - * \brief The output interface context for the logging module - */ -typedef struct SCLogOPIfaceCtx_ { - SCLogOPIface iface; - - int16_t use_color; - int16_t type; - - /* the output file to be used if the interface is SC_LOG_IFACE_FILE */ - const char *file; - /* the output file descriptor for the above file */ - FILE * file_d; - - /* the facility code if the interface is SC_LOG_IFACE_SYSLOG */ - int facility; - - /* override for the global_log_level */ - SCLogLevel log_level; - - /* override for the global_log_format(currently not used) */ - const char *log_format; - - struct SCLogOPIfaceCtx_ *next; -} SCLogOPIfaceCtx; - -/** - * \brief Structure containing init data, that would be passed to - * SCInitDebugModule() - */ -typedef struct SCLogInitData_ { - /* startup message */ - char *startup_message; - - /* the log level */ - SCLogLevel global_log_level; - - /* the log format */ - char *global_log_format; - - /* output filter */ - char *op_filter; - - /* list of output interfaces to be used */ - SCLogOPIfaceCtx *op_ifaces; - /* no of op ifaces */ - uint8_t op_ifaces_cnt; -} SCLogInitData; - -/** - * \brief Holds the config state used by the logging api - */ -typedef struct SCLogConfig_ { - char *startup_message; - SCLogLevel log_level; - char *log_format; - - char *op_filter; - /* compiled pcre filter expression */ - pcre *op_filter_regex; - pcre_extra *op_filter_regex_study; - - /* op ifaces used */ - SCLogOPIfaceCtx *op_ifaces; - /* no of op ifaces */ - uint8_t op_ifaces_cnt; -} SCLogConfig; - -/* The different log format specifiers supported by the API */ -#define SC_LOG_FMT_TIME 't' /* Timestamp in standard format */ -#define SC_LOG_FMT_PID 'p' /* PID */ -#define SC_LOG_FMT_TID 'i' /* Thread ID */ -#define SC_LOG_FMT_TM 'm' /* Thread module name */ -#define SC_LOG_FMT_LOG_LEVEL 'd' /* Log level */ -#define SC_LOG_FMT_FILE_NAME 'f' /* File name */ -#define SC_LOG_FMT_LINE 'l' /* Line number */ -#define SC_LOG_FMT_FUNCTION 'n' /* Function */ - -/* The log format prefix for the format specifiers */ -#define SC_LOG_FMT_PREFIX '%' - -extern SCLogLevel sc_log_global_log_level; - -extern int sc_log_module_initialized; - -extern int sc_log_module_cleaned; - - -#define SCLog(x, ...) \ - do { \ - if (sc_log_global_log_level >= x && \ - (sc_log_fg_filters_present == 0 || \ - SCLogMatchFGFilterWL(__FILE__, __FUNCTION__, __LINE__) == 1 || \ - SCLogMatchFGFilterBL(__FILE__, __FUNCTION__, __LINE__) == 1) && \ - (sc_log_fd_filters_present == 0 || \ - SCLogMatchFDFilter(__FUNCTION__) == 1)) \ - { \ - char _sc_log_msg[SC_LOG_MAX_LOG_MSG_LEN] = ""; \ - \ - snprintf(_sc_log_msg, SC_LOG_MAX_LOG_MSG_LEN, __VA_ARGS__); \ - \ - SCLogMessage(x, \ - __FILE__, \ - __LINE__, \ - __FUNCTION__, SC_OK, _sc_log_msg); \ - } \ - } while(0) - -#define SCLogErr(x, err, ...) \ - do { \ - if (sc_log_global_log_level >= x && \ - (sc_log_fg_filters_present == 0 || \ - SCLogMatchFGFilterWL(__FILE__, __FUNCTION__, __LINE__) == 1 || \ - SCLogMatchFGFilterBL(__FILE__, __FUNCTION__, __LINE__) == 1) && \ - (sc_log_fd_filters_present == 0 || \ - SCLogMatchFDFilter(__FUNCTION__) == 1)) \ - { \ - char _sc_log_msg[SC_LOG_MAX_LOG_MSG_LEN] = ""; \ - \ - snprintf(_sc_log_msg, SC_LOG_MAX_LOG_MSG_LEN, __VA_ARGS__); \ - \ - SCLogMessage(x, \ - __FILE__, \ - __LINE__, \ - __FUNCTION__, err, _sc_log_msg); \ - } \ - } while(0) - -/** - * \brief Macro used to log INFORMATIONAL messages. - * - * \retval ... Takes as argument(s), a printf style format message - */ -#define SCLogInfo(...) SCLog(SC_LOG_INFO, __VA_ARGS__) - -/** - * \brief Macro used to log NOTICE messages. - * - * \retval ... Takes as argument(s), a printf style format message - */ -#define SCLogNotice(...) SCLog(SC_LOG_NOTICE, __VA_ARGS__) - -/** - * \brief Macro used to log WARNING messages. - * - * \retval err_code Error code that has to be logged along with the - * warning message - * \retval ... Takes as argument(s), a printf style format message - */ -#define SCLogWarning(err_code, ...) SCLogErr(SC_LOG_WARNING, err_code, \ - __VA_ARGS__) -/** - * \brief Macro used to log ERROR messages. - * - * \retval err_code Error code that has to be logged along with the - * error message - * \retval ... Takes as argument(s), a printf style format message - */ -#define SCLogError(err_code, ...) SCLogErr(SC_LOG_ERROR, err_code, \ - __VA_ARGS__) -/** - * \brief Macro used to log CRITICAL messages. - * - * \retval err_code Error code that has to be logged along with the - * critical message - * \retval ... Takes as argument(s), a printf style format message - */ -#define SCLogCritical(err_code, ...) SCLogErr(SC_LOG_CRITICAL, err_code, \ - __VA_ARGS__) -/** - * \brief Macro used to log ALERT messages. - * - * \retval err_code Error code that has to be logged along with the - * alert message - * \retval ... Takes as argument(s), a printf style format message - */ -#define SCLogAlert(err_code, ...) SCLogErr(SC_LOG_ALERT, err_code, \ - __VA_ARGS__) -/** - * \brief Macro used to log EMERGENCY messages. - * - * \retval err_code Error code that has to be logged along with the - * emergency message - * \retval ... Takes as argument(s), a printf style format message - */ -#define SCLogEmerg(err_code, ...) SCLogErr(SC_LOG_EMERGENCY, err_code, \ - __VA_ARGS__) - - -/* Avoid the overhead of using the debugging subsystem, in production mode */ -#ifndef DEBUG - -#define SCLogDebug(...) do { } while (0) - -#define SCEnter(...) - -#define SCReturn return - -#define SCReturnInt(x) return x - -#define SCReturnUInt(x) return x - -#define SCReturnDbl(x) return x - -#define SCReturnChar(x) return x - -#define SCReturnCharPtr(x) return x - -#define SCReturnCT(x, type) return x - -#define SCReturnPtr(x, type) return x - -/* Please use it only for debugging purposes */ -#else - - -/** - * \brief Macro used to log DEBUG messages. Comes under the debugging subsystem, - * and hence will be enabled only in the presence of the DEBUG macro. - * - * \retval ... Takes as argument(s), a printf style format message - */ -#define SCLogDebug(...) SCLog(SC_LOG_DEBUG, __VA_ARGS__) - -/** - * \brief Macro used to log debug messages on function entry. Comes under the - * debugging subsystem, and hence will be enabled only in the presence - * of the DEBUG macro. Apart from logging function_entry logs, it also - * processes the FD filters, if any FD filters are registered. - * - * \retval f An argument can be supplied, although it is not used - */ -#define SCEnter(f) do { \ - if (sc_log_global_log_level >= SC_LOG_DEBUG &&\ - SCLogCheckFDFilterEntry(__FUNCTION__)) \ - { \ - SCLogDebug("Entering ... >>"); \ - } \ - } while(0) - - -/** - * \brief Macro used to log debug messages on function exit. Comes under the - * debugging sybsystem, and hence will be enabled only in the presence - * of the DEBUG macro. Apart from logging function_exit logs, it also - * processes the FD filters, if any FD filters are registered. This - * function_exit macro should be used for functions that don't return - * a value. - */ -#define SCReturn do { \ - if (sc_log_global_log_level >= SC_LOG_DEBUG) { \ - SCLogDebug("Returning ... <<" ); \ - SCLogCheckFDFilterExit(__FUNCTION__); \ - } \ - return; \ - } while(0) - -/** - * \brief Macro used to log debug messages on function exit. Comes under the - * debugging sybsystem, and hence will be enabled only in the presence - * of the DEBUG macro. Apart from logging function_exit logs, it also - * processes the FD filters, if any FD filters are registered. This - * function_exit macro should be used for functions that returns an - * integer value. - * - * \retval x Variable of type 'integer' that has to be returned - */ -#define SCReturnInt(x) do { \ - if (sc_log_global_log_level >= SC_LOG_DEBUG) { \ - SCLogDebug("Returning: %"PRIdMAX" ... <<", (intmax_t)x); \ - SCLogCheckFDFilterExit(__FUNCTION__); \ - } \ - return x; \ - } while(0) - -/** - * \brief Macro used to log debug messages on function exit. Comes under the - * debugging sybsystem, and hence will be enabled only in the presence - * of the DEBUG macro. Apart from logging function_exit logs, it also - * processes the FD filters, if any FD filters are registered. This - * function_exit macro should be used for functions that returns an - * unsigned integer value. - * - * \retval x Variable of type 'unsigned integer' that has to be returned - */ -#define SCReturnUInt(x) do { \ - if (sc_log_global_log_level >= SC_LOG_DEBUG) { \ - SCLogDebug("Returning: %"PRIuMAX" ... <<", (uintmax_t)x); \ - SCLogCheckFDFilterExit(__FUNCTION__); \ - } \ - return x; \ - } while(0) - -/** - * \brief Macro used to log debug messages on function exit. Comes under the - * debugging sybsystem, and hence will be enabled only in the presence - * of the DEBUG macro. Apart from logging function_exit logs, it also - * processes the FD filters, if any FD filters are registered. This - * function_exit macro should be used for functions that returns a - * float/double value. - * - * \retval x Variable of type 'float/double' that has to be returned - */ -#define SCReturnDbl(x) do { \ - if (sc_log_global_log_level >= SC_LOG_DEBUG) { \ - SCLogDebug("Returning: %f ... <<", x); \ - SCLogCheckFDFilterExit(__FUNCTION__); \ - } \ - return x; \ - } while(0) - -/** - * \brief Macro used to log debug messages on function exit. Comes under the - * debugging sybsystem, and hence will be enabled only in the presence - * of the DEBUG macro. Apart from logging function_exit logs, it also - * processes the FD filters, if any FD filters are registered. This - * function_exit macro should be used for functions that returns a var - * of character type. - * - * \retval x Variable of type 'char' that has to be returned - */ -#define SCReturnChar(x) do { \ - if (sc_log_global_log_level >= SC_LOG_DEBUG) { \ - SCLogDebug("Returning: %c ... <<", x); \ - SCLogCheckFDFilterExit(__FUNCTION__); \ - } \ - return x; \ - } while(0) - -/** - * \brief Macro used to log debug messages on function exit. Comes under the - * debugging sybsystem, and hence will be enabled only in the presence - * of the DEBUG macro. Apart from logging function_exit logs, it also - * processes the FD filters, if any FD filters are registered. This - * function_exit macro should be used for functions that returns a - * character string. - * - * \retval x Pointer to the char string that has to be returned - */ -#define SCReturnCharPtr(x) do { \ - if (sc_log_global_log_level >= SC_LOG_DEBUG) { \ - if ((x) != NULL) { \ - SCLogDebug("Returning: %s ... <<", x); \ - } else { \ - SCLogDebug("Returning: NULL ... <<"); \ - } SCLogCheckFDFilterExit(__FUNCTION__); \ - } \ - return x; \ - } while(0) - - -/** - * \brief Macro used to log debug messages on function exit. Comes under the - * debugging sybsystem, and hence will be enabled only in the presence - * of the DEBUG macro. Apart from logging function_exit logs, it also - * processes the FD filters, if any FD filters are registered. This - * function_exit macro should be used for functions that returns a var - * of custom type - * - * \retval x Variable instance of a custom type that has to be returned - * \retval type Pointer to a character string holding the name of the custom - * type(the argument x) that has to be returned - */ -#define SCReturnCT(x, type) do { \ - if (sc_log_global_log_level >= SC_LOG_DEBUG) { \ - SCLogDebug("Returning var of " \ - "type %s ... <<", type); \ - SCLogCheckFDFilterExit(__FUNCTION__); \ - } \ - return x; \ - } while(0) - -/** - * \brief Macro used to log debug messages on function exit. Comes under the - * debugging sybsystem, and hence will be enabled only in the presence - * of the DEBUG macro. Apart from logging function_exit logs, it also - * processes the FD filters, if any FD filters are registered. This - * function_exit macro should be used for functions that returns a - * pointer to a custom type - * - * \retval x Pointer to a variable instance of a custom type that has to be - * returned - * \retval type Pointer to a character string holding the name of the custom - * type(the argument x) that has to be returned - */ -#define SCReturnPtr(x, type) do { \ - if (sc_log_global_log_level >= SC_LOG_DEBUG) { \ - SCLogDebug("Returning pointer %p of " \ - "type %s ... <<", x, type); \ - SCLogCheckFDFilterExit(__FUNCTION__); \ - } \ - return x; \ - } while(0) - -#endif /* DEBUG */ - -#define FatalError(x, ...) do { \ - SCLogError(x, __VA_ARGS__); \ - exit(EXIT_FAILURE); \ -} while(0) - -/** \brief Fatal error IF we're starting up, and configured to consider - * errors to be fatal errors */ -#define FatalErrorOnInit(x, ...) do { \ - int init_errors_fatal = 0; \ - ConfGetBool("engine.init-failure-fatal", &init_errors_fatal); \ - if (init_errors_fatal && (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT))\ - { \ - SCLogError(x, __VA_ARGS__); \ - exit(EXIT_FAILURE); \ - } \ - SCLogWarning(x, __VA_ARGS__); \ -} while(0) - - -SCLogInitData *SCLogAllocLogInitData(void); - -SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *, const char *, int, - const char *); - -void SCLogAppendOPIfaceCtx(SCLogOPIfaceCtx *, SCLogInitData *); - -void SCLogInitLogModule(SCLogInitData *); - -void SCLogDeInitLogModule(void); - -SCError SCLogMessage(const SCLogLevel, const char *, const unsigned int, - const char *, const SCError, const char *message); - -SCLogOPBuffer *SCLogAllocLogOPBuffer(void); - -int SCLogDebugEnabled(void); - -void SCLogRegisterTests(void); - -void SCLogLoadConfig(int daemon, int verbose); - -#endif /* __UTIL_DEBUG_H__ */ diff --git a/framework/src/suricata/src/util-decode-asn1.c b/framework/src/suricata/src/util-decode-asn1.c deleted file mode 100644 index 3372b517..00000000 --- a/framework/src/suricata/src/util-decode-asn1.c +++ /dev/null @@ -1,904 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * Implements ASN1 decoding (needed for the asn1 keyword, BER, CER & DER) - */ - -#include "suricata.h" -#include "suricata-common.h" -#include "decode.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-print.h" - -#include "util-decode-asn1.h" -#include "conf.h" - -uint16_t asn1_max_frames_config = ASN1_MAX_FRAMES; - -void SCAsn1LoadConfig() -{ - intmax_t value = 0; - - /** set config defaults */ - if ((ConfGetInt("asn1-max-frames", &value)) == 1) { - asn1_max_frames_config = (uint16_t)value; - SCLogDebug("Max stack frame set to %"PRIu16, asn1_max_frames_config); - } - -} - -/** - * \brief Decode and check the identifier information of the - * current node that is in extended format - * - * \param ac pointer to the ASN1 Context data - * - * \retval byte of the status of the parser - */ -uint8_t SCAsn1GetHighTagNumber(Asn1Ctx *ac) -{ - uint8_t ret = 0; - uint32_t tag_num = 0; - - /* If we have a high tag num, skip the id octet */ - ac->iter++; - - Asn1Node *node = ASN1CTX_CUR_NODE(ac); - - ret = SCAsn1CheckBounds(ac); - if (ret == ASN1_PARSER_ERR) { - ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB; - return ret; - } - - uint8_t raw_id = *ac->iter; - - tag_num += ASN1_BER_GET_HIGH_TAG_NUM(raw_id); - - if (ASN1_BER_GET_HIGH_TAG_NUM(raw_id) == 0) { - /* Set event, invalid id */ - node->flags |= ASN1_BER_EVENT_INVALID_ID; - ac->parser_status |= ASN1_STATUS_INVALID; - return ASN1_PARSER_ERR; - } - - ac->iter++; - if (!ASN1_BER_IS_HIGH_TAG_END(raw_id)) { - do { - ret = SCAsn1CheckBounds(ac); - if (ret == ASN1_PARSER_ERR) { - ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB; - return ret; - } - - raw_id = *ac->iter; - - if ((uint64_t) ((uint64_t)tag_num + - (uint64_t)ASN1_BER_GET_HIGH_TAG_NUM(raw_id)) > UINT32_MAX) - { - node->flags |= ASN1_BER_EVENT_ID_TOO_LONG; - ac->parser_status |= ASN1_STATUS_INVALID; - return ASN1_PARSER_ERR; - } - - tag_num += ASN1_BER_GET_HIGH_TAG_NUM(raw_id); - ac->iter++; - } while (!ASN1_BER_IS_HIGH_TAG_END(raw_id)); - } - node->id.tag_num = tag_num; - - return ASN1_PARSER_OK; -} - -/** - * \brief Decode and check the length, of the current node - * in definite but extended format, that we are parsing, - * checking invalid opts - * - * \param ac pointer to the ASN1 Context data - * - * \retval byte of the status of the parser - */ -uint32_t SCAsn1GetLengthLongForm(Asn1Ctx *ac) -{ - uint8_t raw_len = *ac->iter; - uint8_t ret = 0; - uint32_t content_len = 0; - uint8_t oct_len = ASN1_BER_GET_LONG_LEN_OCTETS(raw_len); - uint8_t i = 0; - - Asn1Node *node = ASN1CTX_CUR_NODE(ac); - - for (; i < oct_len; i++) { - ac->iter++; - - ret = SCAsn1CheckBounds(ac); - if (ret == ASN1_PARSER_ERR) { - ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB; - return ASN1_PARSER_ERR; - } - - raw_len = *ac->iter; - if (raw_len == 0xFF && ac->iter == node->len.ptr + 1) { - /* 8.1.3.5, 0xFF shall not be used */ - node->flags |= ASN1_BER_EVENT_INVALID_LEN; - ac->parser_status = ASN1_STATUS_INVALID; - return ASN1_PARSER_ERR; - } - - if ((uint64_t) ((uint64_t)content_len + - (uint64_t) ASN1_BER_GET_HIGH_TAG_NUM(raw_len)) > UINT32_MAX) - { - node->flags |= ASN1_BER_EVENT_LEN_TOO_LONG; - ac->parser_status = ASN1_STATUS_INVALID; - return ASN1_PARSER_ERR; - } - - content_len += raw_len; - } - - ac->iter++; - - node->len.len = content_len; - return ASN1_PARSER_OK; -} - - -/** - * \brief Check the content length and perform other inspections - * and decodings if necessary - * - * \param ac pointer to the ASN1 Context data - * - * \retval byte of the status of the parser - */ -uint8_t SCAsn1DecodeContent(Asn1Ctx *ac) -{ - - Asn1Node *node = ASN1CTX_CUR_NODE(ac); - - /* Uops, if we are done, we break here */ - if (node->flags & ASN1_NODE_IS_EOC) - return ASN1_PARSER_OK; - - /* First check the form of length (BER, DER, CER) - * and if we are on a zero length */ - if (node->len.form != ASN1_BER_LEN_INDEFINITE && - node->len.len == 0) - { - node->data.len = 0; - return ASN1_PARSER_OK; - } - - node->data.ptr = ac->iter; - /* If we have a complete length, check that - * it is in bounds */ - if (ac->iter + node->len.len > ac->end) { - /* We do not have all the content octets! */ - node->data.len = ac->end - ac->iter; - } else { - /* We have all the content octets */ - node->data.len = node->len.len; - } - - return ASN1_PARSER_OK; -} - -/** - * \brief Decode and check the length, of the current node - * that we are parsing, also check invalid opts - * - * \param ac pointer to the ASN1 Context data - * - * \retval byte of the status of the parser - */ -uint8_t SCAsn1DecodeLength(Asn1Ctx *ac) -{ - uint8_t ret = 0; - ret = SCAsn1CheckBounds(ac); - if (ret == ASN1_PARSER_ERR) { - ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB; - return ASN1_PARSER_ERR; - } - - Asn1Node *node = ASN1CTX_CUR_NODE(ac); - /* Store the position */ - node->len.ptr = ac->iter; - - uint8_t len_byte = *ac->iter; - - //SCPrintByteBin(len_byte); - - if (*node->id.ptr == 0 && len_byte == 0) { - node->flags |= ASN1_NODE_IS_EOC; - ac->iter++; - return ASN1_PARSER_OK; - } - - if (ASN1_BER_IS_INDEFINITE_LEN(len_byte)) { - node->len.form = ASN1_BER_LEN_INDEFINITE; - node->len.len = 0; - ac->iter++; - - uint8_t *tmp_iter = ac->iter; - - /* Check that e-o-c is in bounds */ - for (; tmp_iter < ac->end - 1; tmp_iter++) { - if (ASN1_BER_IS_EOC(tmp_iter)) { - node->data.len = tmp_iter - ac->iter; - node->len.len = tmp_iter - ac->iter; - return ASN1_PARSER_OK; - } - } - - /* EOC Not found */ - ac->parser_status |= ASN1_STATUS_INVALID; - node->flags |= ASN1_BER_EVENT_EOC_NOT_FOUND; - - return ASN1_PARSER_ERR; - - } else { - /* Look which form we get (and if it apply to the id type) */ - if (ASN1_BER_IS_SHORT_LEN(len_byte)) { - node->len.form = ASN1_BER_LEN_SHORT; - node->len.len = ASN1_BER_GET_SHORT_LEN(len_byte); - ac->iter++; - } else { - node->len.form = ASN1_BER_LEN_LONG; - - /* Ok, let's parse the long form */ - return SCAsn1GetLengthLongForm(ac); - } - - } - return ASN1_PARSER_OK; -} - -/** - * \brief Decode and check the identifier information of the - * current node that we are parsing, also check invalid opts - * - * \param ac pointer to the ASN1 Context data - * - * \retval byte of the status of the parser - */ -uint8_t SCAsn1DecodeIdentifier(Asn1Ctx *ac) -{ - uint8_t ret = 0; - ret = SCAsn1CheckBounds(ac); - if (ret == ASN1_PARSER_ERR) { - ac->parser_status |= ASN1_STATUS_INVALID | ASN1_STATUS_OOB; - return ret; - } - - Asn1Node *node = ASN1CTX_CUR_NODE(ac); - /* Store the position */ - node->id.ptr = ac->iter; - - //SCPrintByteBin(*ac->iter); - - node->id.class_tag = ASN1_BER_GET_CLASS_TAG(*ac->iter); - node->id.tag_type = ASN1_BER_IS_CONSTRUCTED(*ac->iter); - - if (ASN1_BER_IS_HIGH_TAG(*ac->iter)) { - return SCAsn1GetHighTagNumber(ac); - } else { - node->id.tag_num = ASN1_BER_GET_LOW_TAG_NUM(*ac->iter); - ac->iter++; - } - - return ASN1_PARSER_OK; -} - -/** - * \brief Helper function that print the bits of a byte - * to check encoding internals - * \param byte value of the byte - */ -void SCPrintByteBin(uint8_t byte) -{ - uint8_t i = 0; - for (i = 8; i > 0; i--) { - printf("%"PRIu8, (uint8_t)((byte >> (i - 1)) & 0x01)); - if (i == 5) - printf(" "); - } - printf("\n"); -} - -/** - * \brief check if we have remaining data available, - * otherwise the parser should stop - * \param ac Asn1Ctx pointer initialized - * \retval 1 if we are out of bounds, 0 if not - */ -uint8_t SCAsn1CheckBounds(Asn1Ctx *ac) -{ - return (ac->iter < ac->end && ac->iter >= ac->data)? ASN1_PARSER_OK : ASN1_PARSER_ERR; -} - - -/** - * \brief Create a new ASN1 Parsing context - * - * \retval Asn1Ctx pointer to the new ctx - */ -Asn1Ctx *SCAsn1CtxNew(void) -{ - Asn1Ctx *ac = SCMalloc(sizeof(Asn1Ctx)); - - if (unlikely(ac == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - return NULL; - } - memset(ac, 0, sizeof(Asn1Ctx)); - - ac->asn1_stack = SCMalloc(sizeof(Asn1Node *) * asn1_max_frames_config); - if (ac->asn1_stack == NULL) { - SCFree(ac); - return NULL; - } - memset(ac->asn1_stack, 0, sizeof(Asn1Node *) * asn1_max_frames_config); - - return ac; -} - -/** - * \brief Destroy an ASN1 Parsing context - * - * \param Asn1Ctx pointer to the new ctx - */ -void SCAsn1CtxDestroy(Asn1Ctx *ac) -{ - if (ac == NULL) - return; - - uint16_t i = 0; - for (; i < ac->cur_frame; i++) { - Asn1Node *node = ASN1CTX_GET_NODE(ac, i); - if (node != NULL) { - SCFree(node); - } - } - SCFree(ac); -} - -/** - * \brief Create a new node at the array stack of frames in the ctx - * - * \param ac pointer to the ASN1 ctx - * \param node index of the frame that we are going to allocate - * at the asn1 stack in the parser - * - * \retval Asn1Node pointer to the new node allocated - */ -Asn1Node *SCAsn1CtxNewFrame(Asn1Ctx *ac, uint16_t node) -{ - if (node >= asn1_max_frames_config) { - return NULL; - } - - if (ac->asn1_stack[node] == NULL) - ac->asn1_stack[node] = SCMalloc(sizeof(Asn1Node)); - - if (ac->asn1_stack[node] == NULL) - return NULL; - - memset(ac->asn1_stack[node], 0, sizeof(Asn1Node)); - return ac->asn1_stack[node]; -} - -/** - * \brief Initialize the data of the ASN1 parser ctx with the asn1 raw buffer - * - * \param ac pointer to the ASN1 ctx - * \param data pointer to the data to process (binary raw of asn1) - * \param length length of the asn1 raw buffer - * - * \retval void - */ -void SCAsn1CtxInit(Asn1Ctx *ac, uint8_t *data, uint16_t length) -{ - ac->data = data; - ac->iter = data; - ac->len = length; - ac->end = data + length; - ac->parser_status = ASN1_STATUS_OK; -} - -/** - * \brief Decode the nodes/frames located at certain position/level - * - * \param ac pointer to the ASN1 ctx - * \param node_id node index at the asn1 stack of the ctx - * - * \retval byte of parser status - */ -uint8_t SCAsn1Decode(Asn1Ctx *ac, uint16_t node_id) -{ - Asn1Node *node = NULL; - uint8_t ret = 0; - - /* while remaining data, and no fatal error, or end, or max stack frames */ - while (ac->iter < ac->end - && !(ac->parser_status & ASN1_STATUS_DONE) - && ac->cur_frame < asn1_max_frames_config) - { - /* Prepare a new frame */ - if (SCAsn1CtxNewFrame(ac, node_id) == NULL) - break; - - ac->cur_frame = node_id; - node = ASN1CTX_GET_NODE(ac, node_id); - - SCLogDebug("ASN1 Getting ID, cur:%x remaining %"PRIu32, (uint8_t)*ac->iter, (uint32_t)(ac->end - ac->iter)); - - /* Get identifier/tag */ - ret = SCAsn1DecodeIdentifier(ac); - if (ret == ASN1_PARSER_ERR) { - SCLogDebug("Error parsing identifier"); - - node->flags |= ASN1_BER_EVENT_INVALID_ID; - ac->ctx_flags |= node->flags; - - break; - } - - SCLogDebug("ASN1 Getting LEN"); - - /* Get length of content */ - ret = SCAsn1DecodeLength(ac); - if (ret == ASN1_PARSER_ERR) { - SCLogDebug("Error parsing length"); - - node->flags |= ASN1_BER_EVENT_INVALID_LEN; - ac->ctx_flags |= node->flags; - - break; - } - - if ( !(node->flags & ASN1_NODE_IS_EOC)) { - SCLogDebug("ASN1 Getting CONTENT"); - - /* Inspect content */ - ret = SCAsn1DecodeContent(ac); - if (ret == ASN1_PARSER_ERR) { - SCLogDebug("Error parsing content"); - - break; - } - - /* Skip to the next record (if any) */ - if (node->id.tag_type != ASN1_TAG_TYPE_CONSTRUCTED) - /* Is primitive, skip it all (no need to decode it)*/ - ac->iter += node->data.len; - } - - /* Check if we are done with data */ - ret = SCAsn1CheckBounds(ac); - if (ret == ASN1_PARSER_ERR) { - - ac->parser_status |= ASN1_STATUS_DONE; - /* There's no more data available */ - ret = ASN1_PARSER_OK; - - break; - } -#if 0 - printf("Tag Num: %"PRIu32", Tag Type: %"PRIu8", Class:%"PRIu8", Length: %"PRIu32"\n", node->id.tag_num, node->id.tag_type, node->id.class_tag, node->len.len); - printf("Data: \n"); - PrintRawDataFp(stdout, node->data.ptr, node->len.len); - printf(" -- EOD --\n"); -#endif - - /* Stack flags/events here, so we have the resume at the ctx flags */ - ac->ctx_flags |= node->flags; - - /* Check if it's not a primitive type, - * then we need to decode contents */ - if (node->id.tag_type == ASN1_TAG_TYPE_CONSTRUCTED) { - ret = SCAsn1Decode(ac, node_id + 1); - } /* Else we have reached a primitive type and stop the recursion, - * look if we have other branches at the same level */ - - /* But first check if it's a constructed node, and the sum of child - * lengths was more than the length of this frame - * this would mean that we have an overflow at the attributes */ - if (ac->iter > node->data.ptr + node->data.len + 1) { - /* We decoded more length on this frame */ - } - - node_id = ac->cur_frame + 1; - } - - return ret; -} - -/* ----------------------- Unit tests ------------------------ */ -#ifdef UNITTESTS - -/** - * \test Check we handle extended identifiers correctly - */ -int DecodeAsn1Test01(void) -{ - uint8_t *str = (uint8_t *) "\x3F\x84\x06"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = 3; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if (node->id.tag_num != 10) { - ret = 0; - printf("Error, expected tag_num 10, got %"PRIu32" :", node->id.tag_num); - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \test Check we handle extended identifiers correctly - */ -int DecodeAsn1Test02(void) -{ - uint8_t *str = (uint8_t *) "\x3F\x81\x81\x81\x81\x06"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = 6; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if (node->id.tag_num != 10) { - ret = 0; - printf("Error, expected tag_num 10, got %"PRIu32": ", node->id.tag_num); - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \test Check we handle short identifiers correctly - */ -int DecodeAsn1Test03(void) -{ - uint8_t *str = (uint8_t *) "\x28"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = 1; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if (node->id.tag_num != 8) { - ret = 0; - printf("Error, expected tag_num 10, got %"PRIu32": ", node->id.tag_num); - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \test Check we handle extended lengths correctly with indefinite form - */ -int DecodeAsn1Test04(void) -{ - uint8_t *str = (uint8_t *) "\x3F\x84\x06\x80\x12\x12\x12\x00\x00"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = 9; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if (node->len.len != 3) { - ret = 0; - printf("Error, expected length 3, got %"PRIu32": ", node->len.len); - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \test Check we handle extended lengths correctly - * in the definite form - */ -int DecodeAsn1Test05(void) -{ - uint8_t *str = (uint8_t *) "\x3F\x84\x06\x82\x10\x10"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = 6; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if (node->len.len!= 32) { - ret = 0; - printf("Error, expected length 10, got %"PRIu32": ", node->len.len); - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \test Check we handle short lengths correctly - */ -int DecodeAsn1Test06(void) -{ - uint8_t *str = (uint8_t *) "\x3F\x84\x06\x26"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = 4; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if (node->len.len != 38) { - ret = 0; - printf("Error, expected length 10, got %"PRIu32": ", node->len.len); - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \test Check we handle events correctly - */ -int DecodeAsn1Test07(void) -{ - uint8_t *str = (uint8_t *) "\x3F\x00\x84\x06"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = 4; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if ( !(ac->ctx_flags & ASN1_BER_EVENT_INVALID_ID) - || !(node->flags & ASN1_BER_EVENT_INVALID_ID)) - { - ret = 0; - printf("Error, expected invalid id, got flags %"PRIu8": ", ac->ctx_flags); - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \test Check we handle events correctly - */ -int DecodeAsn1Test08(void) -{ - uint8_t *str = (uint8_t *) "\x3F\x84\x06\x81\xFF"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = 5; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if ( !(ac->ctx_flags & ASN1_BER_EVENT_INVALID_LEN) - || !(node->flags & ASN1_BER_EVENT_INVALID_LEN)) - { - ret = 0; - printf("Error, expected invalid length, got flags %"PRIu8": ", ac->ctx_flags); - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \test Check we handle events correctly - */ -int DecodeAsn1Test09(void) -{ - uint8_t *str = (uint8_t *) "\x3F\x84\x06\x80\xAB\xCD\xEF"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = 7; - - SCAsn1CtxInit(ac, str, len); - - SCAsn1Decode(ac, ac->cur_frame); - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if ( !(ac->ctx_flags & ASN1_BER_EVENT_EOC_NOT_FOUND) - || !(node->flags & ASN1_BER_EVENT_EOC_NOT_FOUND)) - { - ret = 0; - printf("Error, expected eoc not found, got flags %"PRIu8": ", ac->ctx_flags); - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -/** - * \test Decode a big chunk of data - */ -int DecodeAsn1Test10(void) -{ - // Example from the specification X.690-0207 Appendix A.3 - uint8_t *str = (uint8_t *) "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01" - "P""\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111" - "\x31\x1F\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05" - "Jones""\xA0\x0A\x43\x08""19590717" - "\x60\x81\x85\x61\x10\x1A\x04""John""\x1A\x01""P" - "\x1A\x05""Smith""\xA0\x0A\x1A\x08""Director" - "\x42\x01\x33\xA1\x0A\x43\x08""19710917" - "\xA2\x12\x61\x10\x1A\x04""Mary""\x1A\x01""T""\x1A\x05" - "Smith""\xA3\x42\x31\x1F\x61\x11\x1A\x05""Ralph""\x1A\x01" - "T""\x1A\x05""Smith""\xA0\x0A\x43\x08""19571111""\x31\x1F" - "\x61\x11\x1A\x05""Susan""\x1A\x01""B""\x1A\x05""Jones" - "\xA0\x0A\x43\x08""19590717"; - - Asn1Ctx *ac = SCAsn1CtxNew(); - if (ac == NULL) - return 0; - uint8_t ret = 1; - - uint16_t len = strlen((char *)str)-1; - - SCAsn1CtxInit(ac, str, len); - - ret = SCAsn1Decode(ac, ac->cur_frame); - - /* General checks */ - if (ret != ASN1_PARSER_OK) { - printf("Error decoding asn1 data: "); - ret = 0; - goto end; - } - - if (ac->cur_frame != 59) { - printf("Error decoding asn1 data, not all the nodes" - "were correctly decoded: "); - ret = 0; - goto end; - } - - if (ac->iter != ac->end) { - printf("Error decoding asn1 data, not all the nodes" - "were correctly decoded: "); - ret = 0; - goto end; - } - - Asn1Node *node = ASN1CTX_GET_NODE(ac, 0); - if (node->len.len != 133) { - printf("Error decoding asn1 data, not all the nodes" - "were correctly decoded: "); - ret = 0; - goto end; - } - - node = ASN1CTX_GET_NODE(ac, 30); - if (node->len.len != 133) { - printf("Error decoding asn1 data, not all the nodes" - "were correctly decoded: "); - ret = 0; - goto end; - } - -end: - SCAsn1CtxDestroy(ac); - return ret; -} - -#endif - -void DecodeAsn1RegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DecodeAsn1Test01", DecodeAsn1Test01, 1); - UtRegisterTest("DecodeAsn1Test02", DecodeAsn1Test02, 1); - UtRegisterTest("DecodeAsn1Test03", DecodeAsn1Test03, 1); - - UtRegisterTest("DecodeAsn1Test04", DecodeAsn1Test04, 1); - UtRegisterTest("DecodeAsn1Test05", DecodeAsn1Test05, 1); - UtRegisterTest("DecodeAsn1Test06", DecodeAsn1Test06, 1); - - UtRegisterTest("DecodeAsn1Test07", DecodeAsn1Test07, 1); - UtRegisterTest("DecodeAsn1Test08", DecodeAsn1Test08, 1); - UtRegisterTest("DecodeAsn1Test09", DecodeAsn1Test09, 1); - - UtRegisterTest("DecodeAsn1Test10", DecodeAsn1Test10, 1); -#endif -} - diff --git a/framework/src/suricata/src/util-decode-asn1.h b/framework/src/suricata/src/util-decode-asn1.h deleted file mode 100644 index d3ff9a3e..00000000 --- a/framework/src/suricata/src/util-decode-asn1.h +++ /dev/null @@ -1,220 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * Implements ASN1 decoding (needed for the asn1 keyword) - */ - -#ifndef __DECODE_ASN1_H__ -#define __DECODE_ASN1_H__ -#include -#include -#include -#include -#include -#include -#include -#include - -#define ASN1_MAX_FRAMES 128 - -/* For future enconding type implementations */ -enum { - ASN1_BER_ENC, - ASN1_ENC_UNKNOWN -}; - -/* Class of tag */ -#define ASN1_BER_CLASS_UNIV 0 -#define ASN1_BER_CLASS_APP 1 -#define ASN1_BER_CLASS_CTX_SPECIFIC 2 -#define ASN1_BER_CLASS_PRIV 3 - -/* For low tag numbers */ -#define ASN1_BER_GET_CLASS_TAG(id_octet) \ - ((id_octet >> 6) & 0x03) /* (8.1.2.2a) */ -#define ASN1_BER_IS_CONSTRUCTED(id_octet) \ - ((id_octet >> 5) & 0x01) /* (8.1.2.5) Constructed Tag */ -#define ASN1_BER_IS_PRIMITIVE(id_octet) \ - (((id_octet >> 5) & 0x01)?0:1) /* (8.1.2.5) Primitive Tag */ -#define ASN1_BER_IS_LOW_TAG(id_octet) \ - ASN1_BER_IS_PRIMITIVE(id_octet) /* (8.1.2.5) Is Low Tag - Number */ -#define ASN1_BER_GET_LOW_TAG_NUM(id_octet) \ - (id_octet & 0x1F) /* (8.1.2.2c) Get LowTag Number */ - -/* For high tag numbers */ -#define ASN1_BER_IS_HIGH_TAG(id_octet) \ - ((ASN1_BER_GET_LOW_TAG_NUM(id_octet) == 0x1F) && \ - ASN1_BER_IS_CONSTRUCTED(id_octet)) /* (8.1.2.4) High Tag Number */ -#define ASN1_BER_IS_HIGH_TAG_END(id_octet) \ - ( !((id_octet >> 7) & 0x01)) /* (8.1.2.4) Is End of Tag Num */ -#define ASN1_BER_GET_HIGH_TAG_NUM(id_octet) \ - (id_octet & 0x7F) /* (8.1.2.4) Part of High Tag - Number */ - - -#define ASN1_BER_IS_SHORT_LEN(id_octet) \ - ( !((id_octet >> 7) & 0x01)) /* (8.1.3.3) Is short form */ -#define ASN1_BER_GET_SHORT_LEN(id_octet) \ - (id_octet & 0x7F) /* (8.1.3.3) length value */ -#define ASN1_BER_GET_LONG_LEN_OCTETS(id_octet) \ - (id_octet & 0x7F) /* (8.1.3.5) the number of - bytes */ -#define ASN1_BER_GET_LONG_LEN(id_octet) \ - (id_octet) /* (8.1.3.5) the byte itself*/ -#define ASN1_BER_LONG_LEN_HAS_NEXT(id_octet) \ - ( !((id_octet >> 7) & 0x01)) /* (8.1.3.5) Has next octets - lenght */ -#define ASN1_BER_IS_INDEFINITE_LEN(id_octet) \ - (id_octet == 0x80) /* (8.1.3.6) Need end-of-ccontent */ -#define ASN1_BER_IS_EOC(tmp_iter) (*tmp_iter == 0 && *(tmp_iter + 1) == 0) - -/* Return the current node/frame that we are filling */ -#define ASN1CTX_CUR_NODE(ac) (ac->asn1_stack[ac->cur_frame]) -#define ASN1CTX_GET_NODE(ac, node) (ac->asn1_stack[node]) - -/* BER Universal tags */ -#define ASN1_UNITAG_EOC 0 /* EOC */ -#define ASN1_UNITAG_BOOLEAN 1 -#define ASN1_UNITAG_INTEGER 2 -#define ASN1_UNITAG_BIT_STRING 3 -#define ASN1_UNITAG_OCTET_STRING 4 -#define ASN1_UNITAG_NULL 5 -#define ASN1_UNITAG_OID 6 -#define ASN1_UNITAG_OBJECT_DESCRIPTOR 7 -#define ASN1_UNITAG_EXTERNAL 8 -#define ASN1_UNITAG_REAL 9 -#define ASN1_UNITAG_ENUMERATED 10 -#define ASN1_UNITAG_EMBEDDED_PDV 11 -#define ASN1_UNITAG_UTF8_STRING 12 -#define ASN1_UNITAG_RELATIVE_OID 13 -#define ASN1_UNITAG_SEQUENCE 16 -#define ASN1_UNITAG_SET 17 -#define ASN1_UNITAG_NUMERIC_STRING 18 -#define ASN1_UNITAG_PRINTABLE_STRING 19 -#define ASN1_UNITAG_TELETEX_STRING 20 -#define ASN1_UNITAG_VIDEOTEX_STRING 21 -#define ASN1_UNITAG_IA5_STRING 22 -#define ASN1_UNITAG_UTCTIME 23 -#define ASN1_UNITAG_GENERALIZED_TIME 24 -#define ASN1_UNITAG_GRAPHIC_STRING 25 -#define ASN1_UNITAG_VISIBLE_STRING 26 -#define ASN1_UNITAG_GENERAL_STRING 27 -#define ASN1_UNITAG_UNIVERSAL_STRING 28 -#define ASN1_UNITAG_CHARACTER_STRING 29 -#define ASN1_UNITAG_BMP_STRING 30 - -/* Length form */ -#define ASN1_BER_LEN_SHORT 0 -#define ASN1_BER_LEN_LONG 1 -#define ASN1_BER_LEN_INDEFINITE 2 - - -/* Error events/flags */ -#define ASN1_BER_EVENT_ID_TOO_LONG 0x01 -#define ASN1_BER_EVENT_INVALID_ID 0x02 /* (8.1.2.4.2c) First subsequent - id val (from bit 7 to 0) Shall - not be 0 */ -#define ASN1_BER_EVENT_INVALID_LEN 0x04 /* (8.1.3.2a) we expect a simple - form, or (8.1.3.5c) we got - 0xFF, or not enough data */ -#define ASN1_BER_EVENT_LEN_TOO_LONG 0x08 -#define ASN1_BER_EVENT_EOC_NOT_FOUND 0x10 /* EOC not found */ - - -/* Helper flags */ -#define ASN1_NODE_IS_EOC 1 -#define ASN1_TAG_TYPE_PRIMITIVE 0 -#define ASN1_TAG_TYPE_CONSTRUCTED 1 - -typedef struct Asn1Len_ { - uint8_t form; - uint32_t len; - uint8_t *ptr; -} Asn1Len; - -typedef struct Asn1Id_ { - uint8_t *ptr; - uint8_t class_tag; - uint8_t tag_type; - uint32_t tag_num; -} Asn1Id; - -typedef struct Asn1Data_ { - uint8_t *ptr; - uint32_t len; - uint8_t type; -} Asn1Data; - -typedef struct Asn1Node_ { - uint8_t *raw_str; - uint8_t data_len; - Asn1Len len; - Asn1Id id; - Asn1Data data; - uint8_t flags; -} Asn1Node; - -typedef struct Asn1Ctx_ { - uint8_t *data; - uint8_t *end; - uint16_t len; - - uint8_t *iter; - - uint16_t cur_frame; - Asn1Node *asn1_stack2[ASN1_MAX_FRAMES]; - Asn1Node **asn1_stack; - - uint8_t parser_status; - - uint8_t ctx_flags; -} Asn1Ctx; - -/* Return codes of the decoder */ -#define ASN1_PARSER_OK 0x01 /* Everything ok */ -#define ASN1_PARSER_ERR 0x02 /* Internal error, fatal error, we can't continue decoding */ - -/* Status of the parser */ -#define ASN1_STATUS_OK 0x00 /* On the road */ -#define ASN1_STATUS_INVALID 0x01 /* We found something weird/invalid by the specification, but we can try to continue parsing */ -#define ASN1_STATUS_OOB 0x02 /* We don't have enough data or ran out of bounds */ -#define ASN1_STATUS_DONE 0x04 /* We have finished cleanly */ - -void SCPrintByteBin(uint8_t); - -Asn1Ctx *SCAsn1CtxNew(void); -void SCAsn1CtxInit(Asn1Ctx *, uint8_t *, uint16_t); -void SCAsn1CtxDestroy(Asn1Ctx *); - -uint8_t SCAsn1Decode(Asn1Ctx *, uint16_t); -uint8_t SCAsn1DecodeIdentifier(Asn1Ctx *); -uint8_t SCAsn1DecodeLength(Asn1Ctx *); -uint8_t SCAsn1DecodeContent(Asn1Ctx *); - -uint8_t SCAsn1CheckBounds(Asn1Ctx *); - -void DecodeAsn1RegisterTests(void); -void SCAsn1LoadConfig(); - -#endif /* __DECODE_ASN1_H__ */ - diff --git a/framework/src/suricata/src/util-decode-der-get.c b/framework/src/suricata/src/util-decode-der-get.c deleted file mode 100644 index 4323eb39..00000000 --- a/framework/src/suricata/src/util-decode-der-get.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2011-2012 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - */ - -#include "suricata-common.h" - -#include "util-decode-der.h" -#include "util-decode-der-get.h" - -static const uint8_t SEQ_IDX_ISSUER[] = { 0, 2 }; -static const uint8_t SEQ_IDX_SUBJECT[] = { 0, 4 }; - -static const char *Oid2ShortStr(const char *oid) -{ - if (strcmp(oid, "1.2.840.113549.1.9.1")==0) - return "emailAddress"; - - if (strcmp(oid, "2.5.4.3")==0) - return "CN"; - - if (strcmp(oid, "2.5.4.5")==0) - return "serialNumber"; - - if (strcmp(oid, "2.5.4.6")==0) - return "C"; - - if (strcmp(oid, "2.5.4.7")==0) - return "L"; - - if (strcmp(oid, "2.5.4.8")==0) - return "ST"; - - if (strcmp(oid, "2.5.4.10")==0) - return "O"; - - if (strcmp(oid, "2.5.4.11")==0) - return "OU"; - - if (strcmp(oid, "0.9.2342.19200300.100.1.25")==0) - return "DC"; - - return "unknown"; -} - -/** - * \brief Iterate through an ASN.1 structure, following the index sequence. - * Context specific elements are skipped. - * - * \retval The matching node, or NULL - */ -const Asn1Generic * Asn1DerGet(const Asn1Generic *top, const uint8_t *seq_index, const uint32_t seqsz, uint32_t *errcode) -{ - const Asn1Generic * node; - uint8_t idx, i; - uint8_t offset = 0; - - if (errcode) - *errcode = ERR_DER_MISSING_ELEMENT; - - node = top; - if (node == NULL || seq_index == NULL) - return NULL; - - for (offset=0; offsetdata == NULL) - return NULL; - - /* skip context-specific elements */ - while (node->data->header.cls == ASN1_CLASS_CONTEXTSPEC) { - node = node->next; - if (node == NULL || node->data == NULL) - return NULL; - } - - node = node->next; - if (node == NULL || node->data == NULL) - return NULL; - } - - /* skip context-specific elements */ - if (node == NULL || node->data == NULL) - return NULL; - while (node->data->header.cls == ASN1_CLASS_CONTEXTSPEC) { - node = node->next; - if (node == NULL || node->data == NULL) - return NULL; - } - - node = node->data; - } - - if (errcode) - *errcode = 0; - - return node; -} - -int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode) -{ - const Asn1Generic *node_oid; - const Asn1Generic *node, *it; - const Asn1Generic *node_set; - const Asn1Generic *node_str; - const char *shortname; - int rc = -1; - const char *separator = ", "; - - if (errcode) - *errcode = ERR_DER_MISSING_ELEMENT; - - if (length < 10) - goto issuer_dn_error; - buffer[0] = '\0'; - - node = Asn1DerGet(cert, SEQ_IDX_ISSUER, sizeof(SEQ_IDX_ISSUER), errcode); - if ((node == NULL) || node->type != ASN1_SEQUENCE) - goto issuer_dn_error; - - it = node; - while (it != NULL) { - if (it->data == NULL) - goto issuer_dn_error; - node_set = it->data; - if (node_set->type != ASN1_SET || node_set->data == NULL) - goto issuer_dn_error; - node = node_set->data; - if (node->type != ASN1_SEQUENCE || node->data == NULL) - goto issuer_dn_error; - node_oid = node->data; - if (node_oid->str == NULL || node_oid->type != ASN1_OID) - goto issuer_dn_error; - shortname = Oid2ShortStr(node_oid->str); - if (node->next == NULL) - goto issuer_dn_error; - node = node->next; - node_str = node->data; - if (node_str == NULL || node_str->str == NULL) - goto issuer_dn_error; - - switch (node_str->type) { - case ASN1_PRINTSTRING: - case ASN1_IA5STRING: - case ASN1_T61STRING: - case ASN1_UTF8STRING: - case ASN1_OCTETSTRING: - strlcat(buffer, shortname, length); - strlcat(buffer, "=", length); - strlcat(buffer, node_str->str, length); - break; - default: - if (errcode) - *errcode = ERR_DER_UNSUPPORTED_STRING; - goto issuer_dn_error; - } - - if (strcmp(shortname,"CN")==0) - separator = "/"; - if (it->next != NULL) - strlcat(buffer, separator, length); - it = it->next; - } - - if (errcode) - *errcode = 0; - - rc = 0; -issuer_dn_error: - return rc; -} - -int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode) -{ - const Asn1Generic *node_oid; - const Asn1Generic *node, *it; - const Asn1Generic *node_set; - const Asn1Generic *node_str; - const char *shortname; - int rc = -1; - const char *separator = ", "; - - if (errcode) - *errcode = ERR_DER_MISSING_ELEMENT; - - if (length < 10) - goto subject_dn_error; - buffer[0] = '\0'; - - node = Asn1DerGet(cert, SEQ_IDX_SUBJECT, sizeof(SEQ_IDX_SUBJECT), errcode); - - if ((node == NULL) || node->type != ASN1_SEQUENCE) - goto subject_dn_error; - - it = node; - while (it != NULL) { - if (it == NULL || it->data == NULL) - goto subject_dn_error; - node_set = it->data; - if (node_set->type != ASN1_SET || node_set->data == NULL) - goto subject_dn_error; - node = node_set->data; - if (node->type != ASN1_SEQUENCE || node->data == NULL) - goto subject_dn_error; - node_oid = node->data; - if (node_oid->str == NULL || node_oid->type != ASN1_OID) - goto subject_dn_error; - shortname = Oid2ShortStr(node_oid->str); - if (node->next == NULL) - goto subject_dn_error; - node = node->next; - node_str = node->data; - if (node_str == NULL || node_str->str == NULL) - goto subject_dn_error; - - switch (node_str->type) { - case ASN1_PRINTSTRING: - case ASN1_IA5STRING: - case ASN1_T61STRING: - case ASN1_UTF8STRING: - case ASN1_OCTETSTRING: - strlcat(buffer, shortname, length); - strlcat(buffer, "=", length); - strlcat(buffer, node_str->str, length); - break; - default: - if (errcode) - *errcode = ERR_DER_UNSUPPORTED_STRING; - goto subject_dn_error; - } - - if (strcmp(shortname,"CN")==0) - separator = "/"; - if (it->next != NULL) - strlcat(buffer, separator, length); - it = it->next; - } - - if (errcode) - *errcode = 0; - - rc = 0; -subject_dn_error: - return rc; -} - -/* vim: set et ts=4 sw=4: */ diff --git a/framework/src/suricata/src/util-decode-der-get.h b/framework/src/suricata/src/util-decode-der-get.h deleted file mode 100644 index 79ecd787..00000000 --- a/framework/src/suricata/src/util-decode-der-get.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2011-2012 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - */ - -#ifndef __UTIL_DECODE_DER_GET_H__ -#define __UTIL_DECODE_DER_GET_H__ - -const Asn1Generic * Asn1DerGet(const Asn1Generic *top, const uint8_t *seq_index, const uint32_t seqsz, uint32_t *errcode); - -int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode); -int Asn1DerGetSubjectDN(const Asn1Generic *cert, char *buffer, uint32_t length, uint32_t *errcode); - -#endif /* __UTIL_DECODE_DER_GET_H__ */ diff --git a/framework/src/suricata/src/util-decode-der.c b/framework/src/suricata/src/util-decode-der.c deleted file mode 100644 index 1687668b..00000000 --- a/framework/src/suricata/src/util-decode-der.c +++ /dev/null @@ -1,787 +0,0 @@ -/* - * Copyright (C) 2011-2015 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - */ - -/* - * An ASN.1 Parser for DER-encoded structures. - * This parser is not written to be complete or fast, but is rather - * focused on stability and security. - * It does not support all ASN.1 structure, only a meaningful subset - * to decode x509v3 certificates (See RFC 3280). - * - * References (like 8.19.4) are relative to the ISO/IEC 8825-1:2003 document - * - */ - -#include "suricata-common.h" - -#include "util-decode-der.h" - -#define MAX_OID_LENGTH 256 - -static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); -static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode); - -static Asn1Generic * Asn1GenericNew(void) -{ - Asn1Generic *obj; - - obj = SCMalloc(sizeof(Asn1Generic)); - if (obj != NULL) - memset(obj, 0, sizeof(Asn1Generic)); - - return obj; -} - -/** - * \retval r 0 ok, -1 error - */ -static int Asn1SequenceAppend(Asn1Generic *seq, Asn1Generic *node) -{ - Asn1Generic *it, *new_container; - - if (seq->data == NULL) { - seq->data = node; - return 0; - } - - new_container = Asn1GenericNew(); - if (new_container == NULL) - return -1; - new_container->data = node; - - for (it=seq; it->next != NULL; it=it->next) - ; - - it->next = new_container; - return 0; -} - -static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer, uint32_t max_size, uint8_t depth, int seq_index, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint32_t numbytes, el_max_size; - Asn1ElementType el; - uint8_t c; - uint32_t i; - Asn1Generic *child; - uint8_t el_type; - - el.cls = (d_ptr[0] & 0xc0) >> 6; - el.pc = (d_ptr[0] & 0x20) >> 5; - el.tag = (d_ptr[0] & 0x1f); - - el_type = el.tag; - - if (el.tag == 0x1f) - return NULL; - - switch (el.cls) { - case ASN1_CLASS_CONTEXTSPEC: - /* get element type from definition - * see http://www.ietf.org/rfc/rfc3280.txt) - */ - if (depth == 2 && el.tag == 0) { - el_type = ASN1_SEQUENCE; /* TBSCertificate */ - break; - } - if (depth == 2 && el.tag == 1) { - el_type = ASN1_BITSTRING; /* issuerUniqueID */ - break; - } - if (depth == 2 && el.tag == 2) { - el_type = ASN1_BITSTRING; /* subjectUniqueID */ - break; - } - if (depth == 2 && el.tag == 3) { - el_type = ASN1_SEQUENCE; /* extensions */ - break; - } - /* unknown context specific value - do not decode */ - break; - }; - - el_max_size = max_size - (d_ptr-buffer); - switch (el_type) { - case ASN1_INTEGER: - child = DecodeAsn1DerInteger(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_BOOLEAN: - child = DecodeAsn1DerBoolean(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_NULL: - child = DecodeAsn1DerNull(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_BITSTRING: - child = DecodeAsn1DerBitstring(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_OID: - child = DecodeAsn1DerOid(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_IA5STRING: - child = DecodeAsn1DerIA5String(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_OCTETSTRING: - child = DecodeAsn1DerOctetString(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_UTF8STRING: - child = DecodeAsn1DerUTF8String(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_PRINTSTRING: - child = DecodeAsn1DerPrintableString(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_SEQUENCE: - child = DecodeAsn1DerSequence(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_SET: - child = DecodeAsn1DerSet(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_T61STRING: - child = DecodeAsn1DerT61String(d_ptr, el_max_size, depth+1, errcode); - break; - case ASN1_UTCTIME: - child = DecodeAsn1DerUTCTime(d_ptr, el_max_size, depth+1, errcode); - break; - default: - /* unknown ASN.1 type */ - child = NULL; - child = Asn1GenericNew(); - if (child == NULL) - break; - child->type = el.tag; - /* total sequence length */ - const unsigned char * save_d_ptr = d_ptr; - d_ptr++; - c = d_ptr[0]; - if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */ - child->length = c; - d_ptr++; - } else { /* long form 8.1.3.5 */ - numbytes = c & 0x7f; - if (numbytes > el_max_size) { - SCFree(child); - if (errcode) - *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; - return NULL; - } - child->length = 0; - d_ptr++; - for (i=0; ilength = child->length<<8 | d_ptr[0]; - d_ptr++; - } - } - /* fix the length for unknown objects, else - * sequence parsing will fail - */ - child->length += (d_ptr - save_d_ptr); - break; - }; - if (child == NULL) - return NULL; - - child->header = el; - return child; -} - -static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint8_t numbytes; - uint32_t value; - uint32_t i; - Asn1Generic *a; - - numbytes = d_ptr[1]; - - if (numbytes > size) { - if (errcode) - *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; - return NULL; - } - - d_ptr += 2; - - value = 0; - /* Here we need to ensure that numbytes is less than 4 - so integer affectation is possible. We set the value - to 0xffffffff which is by convention the unknown value. - In this case, the hexadecimal value must be used. */ - if (numbytes > 4) { - value = 0xffffffff; - } else { - for (i=0; itype = ASN1_INTEGER; - a->length = (d_ptr - buffer) + numbytes; - a->value = value; - - a->str = SCMalloc(2*numbytes + 1); - if (a->str == NULL) { - SCFree(a); - return NULL; - } - for (i=0; istr + 2*i, 2*(numbytes-i)+1, "%02X", d_ptr[i]); - } - a->str[2*numbytes]='\0'; - - return a; -} - -static int DecodeAsn1BuildValue(const unsigned char **d_ptr, uint32_t *val, uint8_t numbytes, uint32_t *errcode) -{ - int i; - uint32_t value = 0; - if (numbytes > 4) { - if (errcode) - *errcode = ERR_DER_INVALID_SIZE; - /* too big won't fit: set it to 0xffffffff by convention */ - value = 0xffffffff; - *val = value; - return -1; - } else { - for (i=0; itype = ASN1_BOOLEAN; - a->length = (d_ptr - buffer); - a->value = value; - - return a; -} - -static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer, uint32_t size, uint8_t depth, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint8_t numbytes; - uint32_t value; - Asn1Generic *a; - - numbytes = d_ptr[1]; - d_ptr += 2; - if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) { - return NULL; - } - a = Asn1GenericNew(); - if (a == NULL) - return NULL; - a->type = ASN1_NULL; - a->length = (d_ptr - buffer); - a->value = 0; - - return a; -} - -static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint32_t length; - uint8_t numbytes, c; - Asn1Generic *a; - - d_ptr++; - - /* size */ - c = d_ptr[0]; - if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */ - length = c; - d_ptr++; - } else { /* long form 8.1.3.5 */ - numbytes = c & 0x7f; - d_ptr++; - if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) { - return NULL; - } - } - if (length > max_size) - return NULL; - - a = Asn1GenericNew(); - if (a == NULL) - return NULL; - a->type = ASN1_BITSTRING; - a->strlen = length; - a->str = SCMalloc(length); - if (a->str == NULL) { - SCFree(a); - return NULL; - } - memcpy(a->str, (const char*)d_ptr, length); - - d_ptr += length; - - a->length = (d_ptr - buffer); - return a; -} - -static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint32_t oid_length, oid_value; - uint8_t numbytes, c; - Asn1Generic *a; - uint32_t i; - - d_ptr++; - - /* size */ - c = d_ptr[0]; - if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */ - oid_length = c; - d_ptr++; - } else { /* long form 8.1.3.5 */ - numbytes = c & 0x7f; - d_ptr++; - if (DecodeAsn1BuildValue(&d_ptr, &oid_length, numbytes, errcode) == -1) { - return NULL; - } - } - if (oid_length > max_size) - return NULL; - - a = Asn1GenericNew(); - if (a == NULL) - return NULL; - a->type = ASN1_OID; - a->str = SCMalloc(MAX_OID_LENGTH); - if (a->str == NULL) { - SCFree(a); - return NULL; - } - - /* first element = X*40 + Y (See 8.19.4) */ - snprintf(a->str, MAX_OID_LENGTH, "%d.%d", (d_ptr[0]/40), (d_ptr[0]%40)); - d_ptr++; - - /* sub-identifiers are multi valued, coded and 7 bits, first bit of the 8bits is used - to indicate, if a new value is starting */ - for (i=1; istr); - c = d_ptr[0]; - oid_value = 0; - while ( istr + s, MAX_OID_LENGTH - s, ".%d", oid_value); - } - - a->length = (d_ptr - buffer); - return a; -} - -static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint32_t length, numbytes; - Asn1Generic *a; - unsigned char c; - - d_ptr++; - - /* total sequence length */ - c = d_ptr[0]; - if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */ - length = c; - d_ptr++; - } else { /* long form 8.1.3.5 */ - numbytes = c & 0x7f; - d_ptr++; - if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) { - return NULL; - } - } - if (length == UINT32_MAX || length > max_size) { - if (errcode) - *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; - return NULL; - } - - a = Asn1GenericNew(); - if (a == NULL) - return NULL; - a->type = ASN1_IA5STRING; - a->strlen = length; - a->str = SCMalloc(length+1); - if (a->str == NULL) { - SCFree(a); - return NULL; - } - strlcpy(a->str, (const char*)d_ptr, length+1); - - d_ptr += length; - - a->length = (d_ptr - buffer); - return a; -} - -static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint32_t length, numbytes; - Asn1Generic *a; - unsigned char c; - - d_ptr++; - - /* total sequence length */ - c = d_ptr[0]; - if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */ - length = c; - d_ptr++; - } else { /* long form 8.1.3.5 */ - numbytes = c & 0x7f; - d_ptr++; - if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) { - return NULL; - } - } - if (length == UINT32_MAX || length > max_size) { - if (errcode) - *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; - return NULL; - } - - a = Asn1GenericNew(); - if (a == NULL) - return NULL; - a->type = ASN1_OCTETSTRING; - a->strlen = length; - /* Add one to the octet string for the 0. This will then - * allow us to use the string in printf */ - a->str = SCMalloc(length + 1); - if (a->str == NULL) { - SCFree(a); - return NULL; - } - memcpy(a->str, (const char*)d_ptr, length); - a->str[length] = 0; - - d_ptr += length; - - a->length = (d_ptr - buffer); - return a; -} - -static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - Asn1Generic *a = DecodeAsn1DerOctetString(buffer, max_size, depth, errcode); - if (a != NULL) - a->type = ASN1_UTF8STRING; - return a; -} - -static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint32_t length, numbytes; - Asn1Generic *a; - unsigned char c; - - d_ptr++; - - /* total sequence length */ - c = d_ptr[0]; - if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */ - length = c; - d_ptr++; - } else { /* long form 8.1.3.5 */ - numbytes = c & 0x7f; - d_ptr++; - if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) { - return NULL; - } - } - if (length == UINT32_MAX || length > max_size) { - if (errcode) - *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; - return NULL; - } - - a = Asn1GenericNew(); - if (a == NULL) - return NULL; - a->type = ASN1_PRINTSTRING; - a->strlen = length; - a->str = SCMalloc(length+1); - if (a->str == NULL) { - SCFree(a); - return NULL; - } - strlcpy(a->str, (const char*)d_ptr, length+1); - a->str[length] = '\0'; - - d_ptr += length; - - a->length = (d_ptr - buffer); - return a; -} - -static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint32_t d_length, parsed_bytes, numbytes, el_max_size; - uint8_t c; - uint32_t seq_index; - Asn1Generic *node; - - d_ptr++; - - node = Asn1GenericNew(); - if (node == NULL) - return NULL; - node->type = ASN1_SEQUENCE; - - /* total sequence length */ - c = d_ptr[0]; - if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */ - d_length = c; - d_ptr++; - } else { /* long form 8.1.3.5 */ - numbytes = c & 0x7f; - d_ptr++; - if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) { - SCFree(node); - return NULL; - } - } - node->length = d_length + (d_ptr - buffer); - if (node->length > max_size || node->length < d_length /* wrap */) { - if (errcode) - *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; - SCFree(node); - return NULL; - } - - parsed_bytes = 0; - seq_index = 0; - - /* decode child elements */ - while (parsed_bytes < d_length) { - el_max_size = max_size - (d_ptr-buffer); - - Asn1Generic *child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode); - if (child == NULL) { - if (errcode && *errcode != 0) { - DerFree(node); - return NULL; - } - break; - } - - int ret = Asn1SequenceAppend(node, child); - if (ret == -1) { - DerFree(child); - break; - } - - parsed_bytes += child->length; - d_ptr += child->length; - seq_index++; - - } - - return (Asn1Generic *)node; -} - -static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint32_t d_length, numbytes, el_max_size; - uint8_t c; - uint32_t seq_index; - Asn1Generic *node; - Asn1Generic *child; - - d_ptr++; - - node = Asn1GenericNew(); - if (node == NULL) - return NULL; - node->type = ASN1_SET; - node->data = NULL; - - /* total sequence length */ - c = d_ptr[0]; - if ((c & (1<<7))>>7 == 0) { /* short form 8.1.3.4 */ - d_length = c; - d_ptr++; - } else { /* long form 8.1.3.5 */ - numbytes = c & 0x7f; - d_ptr++; - if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) { - SCFree(node); - return NULL; - } - } - node->length = d_length + (d_ptr - buffer); - - if (node->length > max_size || node->length < d_length /* wrap */) { - if (errcode) - *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG; - SCFree(node); - return NULL; - } - - seq_index = 0; - - el_max_size = max_size - (d_ptr-buffer); - child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode); - if (child == NULL) { - DerFree(node); - return NULL; - } - - node->data = child; - - return (Asn1Generic *)node; -} - -static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - Asn1Generic *a; - - a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode); - if (a != NULL) - a->type = ASN1_T61STRING; - - return a; -} - -static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer, uint32_t max_size, uint8_t depth, uint32_t *errcode) -{ - Asn1Generic *a; - - a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode); - if (a != NULL) - a->type = ASN1_UTCTIME; - - return a; -} - -Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size, uint32_t *errcode) -{ - const unsigned char *d_ptr = buffer; - uint32_t d_length, numbytes; - Asn1Generic *cert; - uint8_t c; - - /* Check that buffer is an ASN.1 structure (basic checks) */ - if (d_ptr[0] != 0x30 && d_ptr[1] != 0x82) /* Sequence */ - return NULL; - - c = d_ptr[1]; - if ((c & (1<<7))>>7 != 1) - return NULL; - - numbytes = c & 0x7f; - d_ptr += 2; - if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) { - return NULL; - } - if (d_length+(d_ptr-buffer) != size) - return NULL; - - if (errcode) - *errcode = 0; - - cert = DecodeAsn1DerGeneric(buffer, size, 0 /* depth */, 0, errcode); - - return cert; -} - -void DerFree(Asn1Generic *a) -{ - Asn1Generic *it, *n; - - if (a == NULL) - return; - - it = a; - while (it) { - n = it->next; - if (it->data) { - DerFree(it->data); - } - if (it->str) - SCFree(it->str); - memset(it, 0xff, sizeof(Asn1Generic)); - SCFree(it); - it = n; - } -} diff --git a/framework/src/suricata/src/util-decode-der.h b/framework/src/suricata/src/util-decode-der.h deleted file mode 100644 index 4c4b1aaf..00000000 --- a/framework/src/suricata/src/util-decode-der.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2011-2012 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author Pierre Chifflier - * - */ - -#ifndef __UTIL_DECODE_DER_H__ -#define __UTIL_DECODE_DER_H__ - -#define ASN1_CLASS_UNIVERSAL 0 -#define ASN1_CLASS_APPLICATION 1 -#define ASN1_CLASS_CONTEXTSPEC 2 -#define ASN1_CLASS_PRIVATE 3 - -#define ASN1_UNKNOWN 0 -#define ASN1_BOOLEAN 0x01 -#define ASN1_INTEGER 0x02 -#define ASN1_BITSTRING 0x03 -#define ASN1_OCTETSTRING 0x04 -#define ASN1_NULL 0x05 -#define ASN1_OID 0x06 -#define ASN1_UTF8STRING 0x0c -#define ASN1_SEQUENCE 0x10 -#define ASN1_SET 0x11 -#define ASN1_PRINTSTRING 0x13 -#define ASN1_T61STRING 0x14 -#define ASN1_IA5STRING 0x16 -#define ASN1_UTCTIME 0x17 - -typedef struct Asn1ElementType_ { - uint8_t cls:2; - uint8_t pc:1; - uint8_t tag:5; -} __attribute__((packed)) Asn1ElementType; - -/* Generic ASN.1 element - * Presence and meaning of fields depends on the header and type values. - */ -typedef struct Asn1Generic_ { - Asn1ElementType header; - uint8_t type; - uint32_t length; /* length of node, including header */ - - struct Asn1Generic_ *data; /* only if type is structured */ - - char *str; - uint32_t strlen; - uint64_t value; - struct Asn1Generic_ *next; /* only if type is sequence */ -} Asn1Generic; - -/* Generic error */ -#define ERR_DER_GENERIC 0x01 -/* Unknown ASN.1 element type */ -#define ERR_DER_UNKNOWN_ELEMENT 0x02 -/* One element requires to read more bytes than available */ -#define ERR_DER_ELEMENT_SIZE_TOO_BIG 0x03 -/* One element size is invalid (more than 4 bytes long) */ -#define ERR_DER_INVALID_SIZE 0x04 -/* Unsupported string type */ -#define ERR_DER_UNSUPPORTED_STRING 0x05 -/* Missing field or element */ -#define ERR_DER_MISSING_ELEMENT 0x06 - -Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size, uint32_t *errcode); -void DerFree(Asn1Generic *a); - -#endif /* __UTIL_DECODE_DER_H__ */ diff --git a/framework/src/suricata/src/util-decode-mime.c b/framework/src/suricata/src/util-decode-mime.c deleted file mode 100644 index ded4cd60..00000000 --- a/framework/src/suricata/src/util-decode-mime.c +++ /dev/null @@ -1,3003 +0,0 @@ -/* Copyright (C) 2012 BAE Systems - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author David Abarbanel - * - */ - -#include "suricata-common.h" - -#include "util-decode-mime.h" - -#include "util-spm-bs.h" -#include "util-unittest.h" -#include "util-memcmp.h" -#include "util-print.h" - -/* Character constants */ -#ifndef CR -#define CR 13 -#define LF 10 -#endif - -#define CRLF "\r\n" -#define COLON 58 -#define DASH 45 -#define PRINTABLE_START 33 -#define PRINTABLE_END 126 -#define UC_START 65 -#define UC_END 90 -#define LC_START 97 -#define LC_END 122 -#define UC_LC_DIFF 32 -#define EOL_LEN 2 - -/* Base-64 constants */ -#define BASE64_STR "Base64" - -/* Mime Constants */ -#define MAX_LINE_LEN 998 /* Def in RFC 2045, excluding CRLF sequence */ -#define MAX_ENC_LINE_LEN 76 /* Def in RFC 2045, excluding CRLF sequence */ -#define MAX_HEADER_NAME 75 /* 75 + ":" = 76 */ -#define MAX_HEADER_VALUE 2000 /* Default - arbitrary limit */ -#define BOUNDARY_BUF 256 -#define CTNT_TYPE_STR "content-type" -#define CTNT_DISP_STR "content-disposition" -#define CTNT_TRAN_STR "content-transfer-encoding" -#define MSG_ID_STR "message-id" -#define BND_START_STR "boundary=\"" -#define TOK_END_STR "\"" -#define MSG_STR "message/" -#define MULTIPART_STR "multipart/" -#define QP_STR "quoted-printable" -#define TXT_STR "text/plain" -#define HTML_STR "text/html" -#define URL_STR "http://" - -/* Memory Usage Constants */ -#define STACK_FREE_NODES 10 - -/* Other Constants */ -#define MAX_IP4_CHARS 15 -#define MAX_IP6_CHARS 39 - -/* Globally hold configuration data */ -static MimeDecConfig mime_dec_config = { 1, 1, 1, 0, MAX_HEADER_VALUE }; - -/* Mime Parser String translation */ -static const char *StateFlags[] = { "NONE", - "HEADER_READY", - "HEADER_STARTED", - "HEADER_DONE", - "BODY_STARTED", - "BODY_DONE", - "BODY_END_BOUND", - "PARSE_DONE", - "PARSE_ERROR", - NULL }; - -/* URL executable file extensions */ -static const char *UrlExeExts[] = { ".exe", - ".vbs", - ".bin", - ".cmd", - ".bat", - ".jar", - ".js", - NULL }; - -/** - * \brief Function used to print character strings that are not null-terminated - * - * \param log_level The logging level in which to print - * \param label A label for the string to print - * \param src The source string - * \param len The length of the string - * - * \return none - */ -static void PrintChars(int log_level, char *label, const uint8_t *src, uint32_t len) -{ -#ifdef DEBUG - if (log_level <= sc_log_global_log_level) { - printf("[%s]\n", label); - PrintRawDataFp(stdout, (uint8_t *)src, len); - } -#endif -} - -/** - * \brief Set global config policy - * - * \param config Config policy to set - * \return none - */ -void MimeDecSetConfig(MimeDecConfig *config) -{ - if (config != NULL) { - mime_dec_config = *config; - - /* Set to default */ - if (mime_dec_config.header_value_depth == 0) { - mime_dec_config.header_value_depth = MAX_HEADER_VALUE; - } - } else { - SCLogWarning(SC_ERR_MISSING_CONFIG_PARAM, "Invalid null configuration parameters"); - } -} - -/** - * \brief Get global config policy - * - * \return config data structure - */ -MimeDecConfig * MimeDecGetConfig(void) -{ - return &mime_dec_config; -} - -/** - * \brief Follow the 'next' pointers to the leaf - * - * \param node The root entity - * - * \return Pointer to leaf on 'next' side - * - */ -static MimeDecEntity *findLastSibling(MimeDecEntity *node) -{ - if (node == NULL) - return NULL; - while(node->next != NULL) - node = node->next; - return node; -} - -/** - * \brief Frees a mime entity tree - * - * \param entity The root entity - * - * \return none - * - */ -void MimeDecFreeEntity (MimeDecEntity *entity) -{ - if (entity == NULL) - return; - MimeDecEntity *lastSibling = findLastSibling(entity); - while (entity != NULL) - { - /** - * Move child to next - * Transform tree into list - */ - if (entity->child != NULL) - { - lastSibling->next = entity->child; - lastSibling = findLastSibling(lastSibling); - } - - /** - * Move to next element - */ - MimeDecEntity *old = entity; - entity = entity->next; - - MimeDecFreeField(old->field_list); - MimeDecFreeUrl(old->url_list); - SCFree(old->filename); - - SCFree(old); - } -} - -/** - * \brief Iteratively frees a header field entry list - * - * \param field The header field - * - * \return none - * - */ -void MimeDecFreeField(MimeDecField *field) -{ - MimeDecField *temp, *curr; - - if (field != NULL) { - - curr = field; - while (curr != NULL) { - temp = curr; - curr = curr->next; - - /* Free contents of node */ - SCFree(temp->name); - SCFree(temp->value); - - /* Now free node data */ - SCFree(temp); - } - } -} - -/** - * \brief Iteratively frees a URL entry list - * - * \param url The url entry - * - * \return none - * - */ -void MimeDecFreeUrl(MimeDecUrl *url) -{ - MimeDecUrl *temp, *curr; - - if (url != NULL) { - - curr = url; - while (curr != NULL) { - temp = curr; - curr = curr->next; - - /* Now free node data */ - SCFree(temp->url); - SCFree(temp); - } - } -} - -/** - * \brief Creates and adds a header field entry to an entity - * - * The entity is optional. If NULL is specified, than a new stand-alone field - * is created. - * - * \param entity The parent entity - * - * \return The field object, or NULL if the operation fails - * - */ -MimeDecField * MimeDecAddField(MimeDecEntity *entity) -{ - MimeDecField *node = SCMalloc(sizeof(MimeDecField)); - if (unlikely(node == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - return NULL; - } - memset(node, 0x00, sizeof(MimeDecField)); - - /* If list is empty, then set as head of list */ - if (entity->field_list == NULL) { - entity->field_list = node; - } else { - /* Otherwise add to beginning of list since these are out-of-order in - * the message */ - node->next = entity->field_list; - entity->field_list = node; - } - - return node; -} - - -/** - * \brief Searches for header fields with the specified name - * - * \param entity The entity to search - * \param name The header name (lowercase) - * - * \return number of items found - * - */ -int MimeDecFindFieldsForEach(const MimeDecEntity *entity, const char *name, int (*DataCallback)(const uint8_t *val, const size_t, void *data), void *data) -{ - MimeDecField *curr = entity->field_list; - int found = 0; - - while (curr != NULL) { - /* name is stored lowercase */ - if (strlen(name) == curr->name_len) { - if (SCMemcmp(curr->name, name, curr->name_len) == 0) { - if (DataCallback(curr->value, curr->value_len, data)) - found++; - } - } - curr = curr->next; - } - - return found; -} - -/** - * \brief Searches for a header field with the specified name - * - * \param entity The entity to search - * \param name The header name (lowercase) - * - * \return The field object, or NULL if not found - * - */ -MimeDecField * MimeDecFindField(const MimeDecEntity *entity, const char *name) { - MimeDecField *curr = entity->field_list; - - while (curr != NULL) { - /* name is stored lowercase */ - if (strlen(name) == curr->name_len) { - if (SCMemcmp(curr->name, name, curr->name_len) == 0) { - break; - } - } - curr = curr->next; - } - - return curr; -} - -/** - * \brief Creates and adds a URL entry to the specified entity - * - * The entity is optional and if NULL is specified, then a new list will be created. - * - * \param entity The entity - * - * \return URL entry or NULL if the operation fails - * - */ -static MimeDecUrl * MimeDecAddUrl(MimeDecEntity *entity, uint8_t *url, uint32_t url_len, uint8_t flags) -{ - MimeDecUrl *node = SCMalloc(sizeof(MimeDecUrl)); - if (unlikely(node == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - return NULL; - } - memset(node, 0x00, sizeof(MimeDecUrl)); - - node->url = url; - node->url_len = url_len; - node->url_flags = flags; - - /* If list is empty, then set as head of list */ - if (entity->url_list == NULL) { - entity->url_list = node; - } else { - /* Otherwise add to beginning of list since these are out-of-order in - * the message */ - node->next = entity->url_list; - entity->url_list = node; - } - - return node; -} - -/** - * \brief Creates and adds a child entity to the specified parent entity - * - * \param parent The parent entity - * - * \return The child entity, or NULL if the operation fails - * - */ -MimeDecEntity * MimeDecAddEntity(MimeDecEntity *parent) -{ - MimeDecEntity *curr, *node = SCMalloc(sizeof(MimeDecEntity)); - if (unlikely(node == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - return NULL; - } - memset(node, 0x00, sizeof(MimeDecEntity)); - - /* If parent is NULL then just return the new pointer */ - if (parent != NULL) { - if (parent->child == NULL) { - parent->child = node; - } else { - curr = parent->child; - while (curr->next != NULL) { - curr = curr->next; - } - curr->next = node; - } - } - - return node; -} - -/** - * \brief Creates a mime header field and fills in its values and adds it to the - * specified entity - * - * \param entity Entity in which to add the field - * \param name String containing the name - * \param nlen Length of the name - * \param value String containing the value - * \param vlen Length of the value - * - * \return The field or NULL if the operation fails - */ -static MimeDecField * MimeDecFillField(MimeDecEntity *entity, uint8_t *name, - uint32_t nlen, const uint8_t *value, uint32_t vlen) -{ - if (nlen == 0 && vlen == 0) - return NULL; - - MimeDecField *field = MimeDecAddField(entity); - if (unlikely(field == NULL)) { - return NULL; - } - - if (nlen > 0) { - /* convert to lowercase and store */ - uint32_t u; - for (u = 0; u < nlen; u++) - name[u] = tolower(name[u]); - - field->name = (uint8_t *)name; - field->name_len = nlen; - } - - if (vlen > 0) { - field->value = (uint8_t *)value; - field->value_len = vlen; - } - - return field; -} - -/** - * \brief Pushes a node onto a stack and returns the new node. - * - * \param stack The top of the stack - * - * \return pointer to a new node, otherwise NULL if it fails - */ -static MimeDecStackNode * PushStack(MimeDecStack *stack) -{ - /* Attempt to pull from free nodes list */ - MimeDecStackNode *node = stack->free_nodes; - if (node == NULL) { - node = SCMalloc(sizeof(MimeDecStackNode)); - if (unlikely(node == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - return NULL; - } - } else { - /* Move free nodes pointer over */ - stack->free_nodes = stack->free_nodes->next; - stack->free_nodes_cnt--; - } - memset(node, 0x00, sizeof(MimeDecStackNode)); - - /* Push to top of stack */ - node->next = stack->top; - stack->top = node; - - /* Return a pointer to the top of the stack */ - return node; -} - -/** - * \brief Pops the top node from the stack and returns the next node. - * - * \param stack The top of the stack - * - * \return pointer to the next node, otherwise NULL if no nodes remain - */ -static MimeDecStackNode * PopStack(MimeDecStack *stack) -{ - /* Move stack pointer to next item */ - MimeDecStackNode *curr = stack->top; - if (curr != NULL) { - curr = curr->next; - } - - /* Always free alloc'd memory */ - SCFree(stack->top->bdef); - - /* Now move head to free nodes list */ - if (stack->free_nodes_cnt < STACK_FREE_NODES) { - stack->top->next = stack->free_nodes; - stack->free_nodes = stack->top; - stack->free_nodes_cnt++; - } else { - SCFree(stack->top); - } - stack->top = curr; - - /* Return a pointer to the top of the stack */ - return curr; -} - -/** - * \brief Frees the stack along with the free-nodes list - * - * \param stack The stack pointer - * - * \return none - */ -static void FreeMimeDecStack(MimeDecStack *stack) -{ - MimeDecStackNode *temp, *curr; - - if (stack != NULL) { - /* Top of stack */ - curr = stack->top; - while (curr != NULL) { - temp = curr; - curr = curr->next; - - /* Now free node */ - SCFree(temp->bdef); - SCFree(temp); - } - - /* Free nodes */ - curr = stack->free_nodes; - while (curr != NULL) { - temp = curr; - curr = curr->next; - - /* Now free node */ - SCFree(temp); - } - - SCFree(stack); - } -} - -/** - * \brief Adds a data value to the data values linked list - * - * \param dv The head of the linked list (NULL if new list) - * - * \return pointer to a new node, otherwise NULL if it fails - */ -static DataValue * AddDataValue(DataValue *dv) -{ - DataValue *curr, *node = SCMalloc(sizeof(DataValue)); - if (unlikely(node == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - return NULL; - } - memset(node, 0x00, sizeof(DataValue)); - - if (dv != NULL) { - curr = dv; - while (curr->next != NULL) { - curr = curr->next; - } - - curr->next = node; - } - - return node; -} - -/** - * \brief Frees a linked list of data values starting at the head - * - * \param dv The head of the linked list - * - * \return none - */ -static void FreeDataValue(DataValue *dv) -{ - DataValue *temp, *curr; - - if (dv != NULL) { - curr = dv; - while (curr != NULL) { - temp = curr; - curr = curr->next; - - /* Now free node */ - SCFree(temp->value); - SCFree(temp); - } - } -} - -/** - * \brief Converts a list of data values into a single value (returns dynamically - * allocated memory) - * - * \param dv The head of the linked list (NULL if new list) - * \param len The output length of the single value - * - * \return pointer to a single value, otherwise NULL if it fails or is zero-length - */ -static uint8_t * GetFullValue(DataValue *dv, uint32_t *len) -{ - DataValue *curr; - uint32_t offset = 0; - uint8_t *val = NULL; - - /* First calculate total length */ - *len = 0; - curr = dv; - while (curr != NULL) { - *len += curr->value_len; - -#if 0 - /* Add CRLF except on last one */ - if (curr->next != NULL) { - *len += 2; - } -#endif - curr = curr->next; - } - - /* Must have at least one character in the value */ - if (*len > 0) { - val = SCCalloc(1, *len); - if (unlikely(val == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - *len = 0; - return NULL; - } - - curr = dv; - while (curr != NULL) { - memcpy(val + offset, curr->value, curr->value_len); - offset += curr->value_len; - -#if 0 /* VJ unclear why this is needed ? */ - /* Add CRLF except on last one */ - if (curr->next != NULL) { - memcpy(val + offset, CRLF, 2); - offset += 2; - } -#endif - curr = curr->next; - } - } - - return val; -} - -/** - * \brief Find a string while searching up to N characters within a source - * buffer - * - * \param src The source string (not null-terminated) - * \param len The length of the source string - * \param find The string to find (null-terminated) - * \param find_len length of the 'find' string - * - * \return Pointer to the position it was found, otherwise NULL if not found - */ -static inline uint8_t * FindBuffer(const uint8_t *src, uint32_t len, const uint8_t *find, uint32_t find_len) -{ - /* Use utility search function */ - return BasicSearchNocase(src, len, find, find_len); -} - -/** - * \brief Get a line (CRLF or just CR or LF) from a buffer (similar to GetToken) - * - * \param buf The input buffer (not null-terminated) - * \param blen The length of the input buffer - * \param remainPtr Pointer to remaining after tokenizing iteration - * \param tokLen Output token length (if non-null line) - * - * \return Pointer to line - */ -static uint8_t * GetLine(uint8_t *buf, uint32_t blen, uint8_t **remainPtr, - uint32_t *tokLen) -{ - uint32_t i; - uint8_t *tok; - - /* So that it can be used just like strtok_r */ - if (buf == NULL) { - buf = *remainPtr; - } else { - *remainPtr = buf; - } - if (buf == NULL) - return NULL; - - tok = buf; - - /* length must be specified */ - for (i = 0; i < blen && buf[i] != 0; i++) { - - /* Found delimiter */ - if (buf[i] == CR || buf[i] == LF) { - - /* Add another if we find either CRLF or LFCR */ - *remainPtr += (i + 1); - if ((i + 1 < blen) && buf[i] != buf[i + 1] && - (buf[i + 1] == CR || buf[i + 1] == LF)) { - (*remainPtr)++; - } - break; - } - } - - /* If no delimiter found, then point to end of buffer */ - if (buf == *remainPtr) { - (*remainPtr) += i; - } - - /* Calculate token length */ - *tokLen = (buf + i) - tok; - - return tok; -} - -/** - * \brief Get token from buffer and return pointer to it - * - * \param buf The input buffer (not null-terminated) - * \param blen The length of the input buffer - * \param delims Character delimiters (null-terminated) - * \param remainPtr Pointer to remaining after tokenizing iteration - * \param tokLen Output token length (if non-null line) - * - * \return Pointer to token, or NULL if not found - */ -static uint8_t * GetToken(uint8_t *buf, uint32_t blen, const char *delims, - uint8_t **remainPtr, uint32_t *tokenLen) -{ - uint32_t i, j, delimFound = 0; - uint8_t *tok = NULL; - - /* So that it can be used just like strtok_r */ - if (buf == NULL) { - buf = *remainPtr; - } else { - *remainPtr = buf; - } - if (buf == NULL) - return NULL; - - /* Must specify length */ - for (i = 0; i < blen && buf[i] != 0; i++) { - - /* Look for delimiters */ - for (j = 0; delims[j] != 0; j++) { - if (buf[i] == delims[j]) { - /* Data must be found before delimiter matters */ - if (tok != NULL) { - (*remainPtr) += (i + 1); - } - delimFound = 1; - break; - } - } - - /* If at least one non-delimiter found, then a token is found */ - if (tok == NULL && !delimFound) { - tok = buf + i; - } else { - /* Reset delimiter */ - delimFound = 0; - } - - /* If delimiter found, then break out of loop */ - if (buf != *remainPtr) { - break; - } - } - - /* Make sure remaining points to end of buffer if delimiters not found */ - if (tok != NULL) { - if (buf == *remainPtr) { - (*remainPtr) += i; - } - - /* Calculate token length */ - *tokenLen = (buf + i) - tok; - } - - return tok; -} - -/** - * \brief Stores the final MIME header value into the current entity on the - * stack. - * - * \param state The parser state - * - * \return MIME_DEC_OK if stored, otherwise a negative number indicating error - */ -static int StoreMimeHeader(MimeDecParseState *state) -{ - int ret = MIME_DEC_OK, stored = 0; - uint8_t *val; - uint32_t vlen; - - /* Lets save the most recent header */ - if (state->hname != NULL || state->hvalue != NULL) { - SCLogDebug("Storing last header"); - val = GetFullValue(state->hvalue, &vlen); - if (val != NULL) { - if (state->hname == NULL) { - SCLogDebug("Error: Invalid parser state - header value without" - " name"); - ret = MIME_DEC_ERR_PARSE; - } else if (state->stack->top != NULL) { - /* Store each header name and value */ - if (MimeDecFillField(state->stack->top->data, state->hname, - state->hlen, val, vlen) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "MimeDecFillField() function failed"); - ret = MIME_DEC_ERR_MEM; - } else { - stored = 1; - } - } else { - SCLogDebug("Error: Stack pointer missing"); - ret = MIME_DEC_ERR_DATA; - } - } else if (state->hvalue != NULL) { - /* Memory allocation must have failed since val is NULL */ - SCLogError(SC_ERR_MEM_ALLOC, "GetFullValue() function failed"); - ret = MIME_DEC_ERR_MEM; - } - - /* Do cleanup here */ - if (!stored) { - SCFree(state->hname); - SCFree(val); - } - state->hname = NULL; - FreeDataValue(state->hvalue); - state->hvalue = NULL; - state->hvlen = 0; - } - - return ret; -} - -/** - * \brief Function determines whether a url string points to an executable - * based on file extension only. - * - * \param url The url string - * \param len The url string length - * - * \retval 1 The url points to an EXE - * \retval 0 The url does NOT point to an EXE - */ -static int IsExeUrl(const uint8_t *url, uint32_t len) -{ - int isExeUrl = 0; - uint32_t i, extLen; - uint8_t *ext; - - /* Now check for executable extensions and if not found, cut off at first '/' */ - for (i = 0; UrlExeExts[i] != NULL; i++) { - extLen = strlen(UrlExeExts[i]); - ext = FindBuffer(url, len, (uint8_t *)UrlExeExts[i], strlen(UrlExeExts[i])); - if (ext != NULL && (ext + extLen - url == (int)len || ext[extLen] == '?')) { - isExeUrl = 1; - break; - } - } - - return isExeUrl; -} - -/** - * \brief Function determines whether a host string is a numeric IP v4 address - * - * \param urlhost The host string - * \param len The host string length - * - * \retval 1 The host is a numeric IP - * \retval 0 The host is NOT a numeric IP - */ -static int IsIpv4Host(const uint8_t *urlhost, uint32_t len) -{ - struct sockaddr_in sa; - char tempIp[MAX_IP4_CHARS + 1]; - - /* Cut off at '/' */ - uint32_t i = 0; - for (i = 0; i < len && urlhost[i] != 0; i++) { - - if (urlhost[i] == '/') { - break; - } - } - - /* Too many chars */ - if (i > MAX_IP4_CHARS) { - return 0; - } - - /* Create null-terminated string */ - memcpy(tempIp, urlhost, i); - tempIp[i] = '\0'; - - return inet_pton(AF_INET, tempIp, &(sa.sin_addr)); -} - -/** - * \brief Function determines whether a host string is a numeric IP v6 address - * - * \param urlhost The host string - * \param len The host string length - * - * \retval 1 The host is a numeric IP - * \retval 0 The host is NOT a numeric IP - */ -static int IsIpv6Host(const uint8_t *urlhost, uint32_t len) -{ - struct in6_addr in6; - char tempIp[MAX_IP6_CHARS + 1]; - - /* Cut off at '/' */ - uint32_t i = 0; - for (i = 0; i < len && urlhost[i] != 0; i++) { - - if (urlhost[i] == '/') { - break; - } - } - - /* Too many chars */ - if (i > MAX_IP6_CHARS) { - return 0; - } - - /* Create null-terminated string */ - memcpy(tempIp, urlhost, i); - tempIp[i] = '\0'; - - return inet_pton(AF_INET6, tempIp, &in6); -} - -/** - * \brief Traverses through the list of URLs for an exact match of the specified - * string - * - * \param entity The MIME entity - * \param url The matching URL string (lowercase) - * \param url_len The matching URL string length - * - * \return URL object or NULL if not found - */ -static MimeDecUrl *FindExistingUrl(MimeDecEntity *entity, uint8_t *url, uint32_t url_len) -{ - MimeDecUrl *curr = entity->url_list; - - while (curr != NULL) { - if (url_len == curr->url_len) { - /* search url and stored url are both in - * lowercase, so we can do an exact match */ - if (SCMemcmp(curr->url, url, url_len) == 0) { - break; - } - } - curr = curr->next; - } - - return curr; -} - -/** - * \brief This function searches a text or html line for a URL string - * - * URLS are generally truncated to the 'host.domain' format because - * some email messages contain dozens or even hundreds of URLs with - * the same host, but with only small variations in path. - * - * The exception is that URLs with executable file extensions are stored - * with the full path. They are stored in lowercase. - * - * Numeric IPs, malformed numeric IPs, and URLs pointing to executables are - * also flagged as URLs of interest. - * - * \param line the line - * \param len the line length - * \param state The current parser state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int FindUrlStrings(const uint8_t *line, uint32_t len, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - MimeDecEntity *entity = (MimeDecEntity *) state->stack->top->data; - uint8_t *fptr, *remptr, *tok = NULL, *tempUrl; - uint32_t tokLen = 0, i, tempUrlLen; - uint8_t urlStrLen = 0, flags = 0; - - remptr = (uint8_t *)line; - do { - SCLogDebug("Looking for URL String starting with: %s", URL_STR); - - /* Check for token definition */ - fptr = FindBuffer(remptr, len - (remptr - line), (uint8_t *)URL_STR, strlen(URL_STR)); - if (fptr != NULL) { - - urlStrLen = strlen(URL_STR); - fptr += urlStrLen; /* Start at end of start string */ - tok = GetToken(fptr, len - (fptr - line), " \"\'<>]\t", &remptr, - &tokLen); - if (tok == fptr) { - SCLogDebug("Found url string"); - - /* First copy to temp URL string */ - tempUrl = SCMalloc(urlStrLen + tokLen); - if (unlikely(tempUrl == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed"); - return MIME_DEC_ERR_MEM; - } - - PrintChars(SC_LOG_DEBUG, "RAW URL", tok, tokLen); - - /* Copy over to temp URL while decoding */ - tempUrlLen = 0; - for (i = 0; i < tokLen && tok[i] != 0; i++) { - - // URL decoding would probably go here - - /* url is all lowercase */ - tempUrl[tempUrlLen] = tolower(tok[i]); - tempUrlLen++; - } - - /* Determine if URL points to an EXE */ - if (IsExeUrl(tempUrl, tempUrlLen)) { - flags |= URL_IS_EXE; - - PrintChars(SC_LOG_DEBUG, "EXE URL", tempUrl, tempUrlLen); - } else { - /* Not an EXE URL */ - /* Cut off length at first '/' */ - /* If seems that BAESystems had done the following - in support of PEScan. We don't want it for logging. - Therefore its been removed. - tok = FindString(tempUrl, tempUrlLen, "/"); - if (tok != NULL) { - tempUrlLen = tok - tempUrl; - } - */ - } - - /* Make sure remaining URL exists */ - if (tempUrlLen > 0) { - if (!(FindExistingUrl(entity, tempUrl, tempUrlLen))) { - /* Now look for numeric IP */ - if (IsIpv4Host(tempUrl, tempUrlLen)) { - flags |= URL_IS_IP4; - - PrintChars(SC_LOG_DEBUG, "IP URL4", tempUrl, tempUrlLen); - } else if (IsIpv6Host(tempUrl, tempUrlLen)) { - flags |= URL_IS_IP6; - - PrintChars(SC_LOG_DEBUG, "IP URL6", tempUrl, tempUrlLen); - } - - /* Add URL list item */ - MimeDecAddUrl(entity, tempUrl, tempUrlLen, flags); - } else { - SCFree(tempUrl); - } - } else { - SCFree(tempUrl); - } - } - } - } while (fptr != NULL); - - return ret; -} - -/** - * \brief This function is a pre-processor for handling decoded data chunks that - * then invokes the caller's callback function for further processing - * - * \param chunk The decoded chunk - * \param len The decoded chunk length (varies) - * \param state The current parser state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int ProcessDecodedDataChunk(const uint8_t *chunk, uint32_t len, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - uint8_t *remainPtr, *tok; - uint32_t tokLen; - - if ((state->stack != NULL) && (state->stack->top != NULL) && - (state->stack->top->data != NULL)) { - MimeDecConfig *mdcfg = MimeDecGetConfig(); - if (mdcfg != NULL && mdcfg->extract_urls) { - MimeDecEntity *entity = (MimeDecEntity *) state->stack->top->data; - /* If plain text or html, then look for URLs */ - if (((entity->ctnt_flags & CTNT_IS_TEXT) || - (entity->ctnt_flags & CTNT_IS_MSG) || - (entity->ctnt_flags & CTNT_IS_HTML)) && - ((entity->ctnt_flags & CTNT_IS_ATTACHMENT) == 0)) { - - /* Remainder from previous line */ - if (state->linerem_len > 0) { - // TODO - } else { - /* No remainder from previous line */ - /* Parse each line one by one */ - remainPtr = (uint8_t *)chunk; - do { - tok = GetLine(remainPtr, len - (remainPtr - (uint8_t *)chunk), - &remainPtr, &tokLen); - if (tok != remainPtr) { - // DEBUG - ADDED - /* If last token found without CR/LF delimiter, then save - * and reconstruct with next chunk - */ - if (tok + tokLen - (uint8_t *) chunk == (int)len) { - PrintChars(SC_LOG_DEBUG, "LAST CHUNK LINE - CUTOFF", - tok, tokLen); - SCLogDebug("\nCHUNK CUTOFF CHARS: %d delim %ld\n", tokLen, len - (tok + tokLen - (uint8_t *) chunk)); - } else { - /* Search line for URL */ - ret = FindUrlStrings(tok, tokLen, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: FindUrlStrings() function" - " failed: %d", ret); - break; - } - } - } - } while (tok != remainPtr && remainPtr - (uint8_t *) chunk < (int)len); - } - } - } - - /* Now invoke callback */ - if (state->DataChunkProcessorFunc != NULL) { - ret = state->DataChunkProcessorFunc(chunk, len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: state->dataChunkProcessor() callback function" - " failed"); - } - } - } else { - SCLogDebug("Error: Stack pointer missing"); - ret = MIME_DEC_ERR_DATA; - } - - /* Reset data chunk buffer */ - state->data_chunk_len = 0; - - /* Mark body / file as no longer at beginning */ - state->body_begin = 0; - - return ret; -} - -/** - * \brief Processes a remainder (line % 4 = remainder) from the previous line - * such that all base64 decoding attempts are divisible by 4 - * - * \param buf The current line - * \param len The length of the line - * \param state The current parser state - * \param force Flag indicating whether decoding should always occur - * - * \return Number of bytes pulled from the current buffer - */ -static uint8_t ProcessBase64Remainder(const uint8_t *buf, uint32_t len, - MimeDecParseState *state, int force) -{ - uint32_t ret; - uint8_t remainder = 0, remdec = 0; - - SCLogDebug("Base64 line remainder found: %u", state->bvr_len); - - /* Fill in block with first few bytes of current line */ - remainder = B64_BLOCK - state->bvr_len; - remainder = remainder < len ? remainder : len; - memcpy(state->bvremain + state->bvr_len, buf, remainder); - state->bvr_len += remainder; - - /* If data chunk buffer will be full, then clear it now */ - if (DATA_CHUNK_SIZE - state->data_chunk_len < ASCII_BLOCK) { - - /* Invoke pre-processor and callback */ - ret = ProcessDecodedDataChunk(state->data_chunk, state->data_chunk_len, - state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessDecodedDataChunk() function failed"); - } - } - - /* Only decode if divisible by 4 */ - if (state->bvr_len == B64_BLOCK || force) { - remdec = DecodeBase64(state->data_chunk + state->data_chunk_len, - state->bvremain, state->bvr_len, 1); - if (remdec > 0) { - - /* Track decoded length */ - state->stack->top->data->decoded_body_len += remdec; - - /* Update length */ - state->data_chunk_len += remdec; - - /* If data chunk buffer is now full, then clear */ - if (DATA_CHUNK_SIZE - state->data_chunk_len < ASCII_BLOCK) { - - /* Invoke pre-processor and callback */ - ret = ProcessDecodedDataChunk(state->data_chunk, - state->data_chunk_len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessDecodedDataChunk() function " - "failed"); - } - } - } else { - /* Track failed base64 */ - state->stack->top->data->anomaly_flags |= ANOM_INVALID_BASE64; - state->msg->anomaly_flags |= ANOM_INVALID_BASE64; - SCLogDebug("Error: DecodeBase64() function failed"); - PrintChars(SC_LOG_DEBUG, "Base64 failed string", state->bvremain, state->bvr_len); - } - - /* Reset remaining */ - state->bvr_len = 0; - } - - return remainder; -} - -/** - * \brief Processes a body line by base64-decoding and passing to the data chunk - * processing callback function when the buffer is read - * - * \param buf The current line - * \param len The length of the line - * \param state The current parser state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int ProcessBase64BodyLine(const uint8_t *buf, uint32_t len, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - uint8_t rem1 = 0, rem2 = 0; - uint32_t numDecoded, remaining, offset, avail, tobuf; - - /* Track long line */ - if (len > MAX_ENC_LINE_LEN) { - state->stack->top->data->anomaly_flags |= ANOM_LONG_ENC_LINE; - state->msg->anomaly_flags |= ANOM_LONG_ENC_LINE; - SCLogDebug("Error: Max encoded input line length exceeded %u > %u", - len, MAX_ENC_LINE_LEN); - } - - /* First process remaining from previous line */ - if (state->bvr_len > 0) { - - SCLogDebug("Base64 line remainder found: %u", state->bvr_len); - - /* Process remainder and return number of bytes pulled from current buffer */ - rem1 = ProcessBase64Remainder(buf, len, state, 0); - } - - /* No error and at least some more data needs to be decoded */ - if ((int) (len - rem1) > 0) { - - /* Determine whether we need to save a remainder if not divisible by 4 */ - rem2 = (len - rem1) % B64_BLOCK; - if (rem2 > 0) { - - SCLogDebug("Base64 saving remainder: %u", rem2); - - memcpy(state->bvremain, buf + (len - rem2), rem2); - state->bvr_len = rem2; - } - - /* Process remaining in loop in case buffer fills up */ - remaining = len - rem1 - rem2; - offset = rem1; - while (remaining > 0) { - - /* Determine amount to add to buffer */ - avail = (DATA_CHUNK_SIZE - state->data_chunk_len) * B64_BLOCK / ASCII_BLOCK; - tobuf = avail > remaining ? remaining : avail; - while (tobuf % 4 != 0) { - tobuf--; - } - - if (tobuf < B64_BLOCK) { - SCLogDebug("Error: Invalid state for decoding base-64 block"); - return MIME_DEC_ERR_PARSE; - } - - SCLogDebug("Decoding: %u", len - rem1 - rem2); - - numDecoded = DecodeBase64(state->data_chunk + state->data_chunk_len, - buf + offset, tobuf, 1); - if (numDecoded > 0) { - - /* Track decoded length */ - state->stack->top->data->decoded_body_len += numDecoded; - - /* Update length */ - state->data_chunk_len += numDecoded; - - if ((int) (DATA_CHUNK_SIZE - state->data_chunk_len) < 0) { - SCLogDebug("Error: Invalid Chunk length: %u", - state->data_chunk_len); - ret = MIME_DEC_ERR_PARSE; - break; - } - - /* If buffer full, then invoke callback */ - if (DATA_CHUNK_SIZE - state->data_chunk_len < ASCII_BLOCK) { - - /* Invoke pre-processor and callback */ - ret = ProcessDecodedDataChunk(state->data_chunk, - state->data_chunk_len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessDecodedDataChunk() " - "function failed"); - } - } - } else { - /* Track failed base64 */ - state->stack->top->data->anomaly_flags |= ANOM_INVALID_BASE64; - state->msg->anomaly_flags |= ANOM_INVALID_BASE64; - SCLogDebug("Error: DecodeBase64() function failed"); - PrintChars(SC_LOG_DEBUG, "Base64 failed string", buf + offset, tobuf); - } - - /* Update counts */ - remaining -= tobuf; - offset += tobuf; - } - } - - return ret; -} - -/** - * \brief Decoded a hex character into its equivalent byte value for - * quoted-printable decoding - * - * \param h The hex char - * - * \return byte value on success, -1 if failed - **/ -static int16_t DecodeQPChar(char h) -{ - uint16_t res = 0; - - /* 0-9 */ - if (h >= 48 && h <= 57) { - res = h - 48; - } else if (h >= 65 && h <= 70) { - /* A-F */ - res = h - 55; - } else { - /* Invalid */ - res = -1; - } - - return res; - -} - -/** - * \brief Processes a quoted-printable encoded body line by decoding and passing - * to the data chunk processing callback function when the buffer is read - * - * \param buf The current line - * \param len The length of the line - * \param state The current parser state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int ProcessQuotedPrintableBodyLine(const uint8_t *buf, uint32_t len, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - uint32_t remaining, offset; - MimeDecEntity *entity = (MimeDecEntity *) state->stack->top->data; - uint8_t c, h1, h2, val; - int16_t res; - - /* Track long line */ - if (len > MAX_ENC_LINE_LEN) { - state->stack->top->data->anomaly_flags |= ANOM_LONG_ENC_LINE; - state->msg->anomaly_flags |= ANOM_LONG_ENC_LINE; - SCLogDebug("Error: Max encoded input line length exceeded %u > %u", - len, MAX_ENC_LINE_LEN); - } - - remaining = len; - offset = 0; - while (remaining > 0) { - - c = *(buf + offset); - - /* Copy over normal character */ - if (c != '=') { - state->data_chunk[state->data_chunk_len] = c; - state->data_chunk_len++; - entity->decoded_body_len += 1; - - /* Add CRLF sequence if end of line */ - if (remaining == 1) { - memcpy(state->data_chunk + state->data_chunk_len, CRLF, EOL_LEN); - state->data_chunk_len += EOL_LEN; - entity->decoded_body_len += EOL_LEN; - } - } else if (remaining > 1) { - /* If last character handle as soft line break by ignoring, - otherwise process as escaped '=' character */ - - /* Not enough characters */ - if (remaining < 3) { - entity->anomaly_flags |= ANOM_INVALID_QP; - state->msg->anomaly_flags |= ANOM_INVALID_QP; - SCLogDebug("Error: Quoted-printable decoding failed"); - } else { - h1 = *(buf + offset + 1); - res = DecodeQPChar(h1); - if (res < 0) { - entity->anomaly_flags |= ANOM_INVALID_QP; - state->msg->anomaly_flags |= ANOM_INVALID_QP; - SCLogDebug("Error: Quoted-printable decoding failed"); - } else { - val = (res << 4); /* Shift result left */ - h2 = *(buf + offset + 2); - res = DecodeQPChar(h2); - if (res < 0) { - entity->anomaly_flags |= ANOM_INVALID_QP; - state->msg->anomaly_flags |= ANOM_INVALID_QP; - SCLogDebug("Error: Quoted-printable decoding failed"); - } else { - /* Decoding sequence succeeded */ - val += res; - - state->data_chunk[state->data_chunk_len] = val; - state->data_chunk_len++; - entity->decoded_body_len++; - - /* Add CRLF sequence if end of line */ - if (remaining == 3) { - memcpy(state->data_chunk + state->data_chunk_len, - CRLF, EOL_LEN); - state->data_chunk_len += EOL_LEN; - entity->decoded_body_len += EOL_LEN; - } - - /* Account for extra 2 characters in 3-characted QP - * sequence */ - remaining -= 2; - offset += 2; - } - } - } - } - - /* Change by 1 */ - remaining--; - offset++; - - /* If buffer full, then invoke callback */ - if (DATA_CHUNK_SIZE - state->data_chunk_len < EOL_LEN + 1) { - - /* Invoke pre-processor and callback */ - ret = ProcessDecodedDataChunk(state->data_chunk, state->data_chunk_len, - state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessDecodedDataChunk() function " - "failed"); - } - } - } - - return ret; -} - -/** - * \brief Processes a body line by base64-decoding (if applicable) and passing to - * the data chunk processing callback function - * - * \param buf The current line - * \param len The length of the line - * \param state The current parser state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int ProcessBodyLine(const uint8_t *buf, uint32_t len, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - uint32_t remaining, offset, avail, tobuf; - MimeDecEntity *entity = (MimeDecEntity *) state->stack->top->data; - - SCLogDebug("Processing body line"); - - /* Track length */ - entity->body_len += len + 2; /* With CRLF */ - - /* Process base-64 content if enabled */ - MimeDecConfig *mdcfg = MimeDecGetConfig(); - if (mdcfg != NULL && mdcfg->decode_base64 && - (entity->ctnt_flags & CTNT_IS_BASE64)) { - - ret = ProcessBase64BodyLine(buf, len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessBase64BodyLine() function failed"); - } - } else if (mdcfg != NULL && mdcfg->decode_quoted_printable && - (entity->ctnt_flags & CTNT_IS_QP)) { - /* Process quoted-printable content if enabled */ - ret = ProcessQuotedPrintableBodyLine(buf, len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessQuotedPrintableBodyLine() function " - "failed"); - } - } else { - /* Process non-decoded content */ - remaining = len; - offset = 0; - while (remaining > 0) { - - /* Plan to add CRLF to the end of each line */ - avail = DATA_CHUNK_SIZE - state->data_chunk_len; - tobuf = avail > remaining + EOL_LEN ? remaining : avail - EOL_LEN; - - /* Copy over to buffer */ - memcpy(state->data_chunk + state->data_chunk_len, buf + offset, tobuf); - state->data_chunk_len += tobuf; - - /* Now always add a CRLF to the end */ - if (tobuf == remaining) { - memcpy(state->data_chunk + state->data_chunk_len, CRLF, EOL_LEN); - state->data_chunk_len += EOL_LEN; - } - - if ((int) (DATA_CHUNK_SIZE - state->data_chunk_len) < 0) { - SCLogDebug("Error: Invalid Chunk length: %u", - state->data_chunk_len); - ret = MIME_DEC_ERR_PARSE; - break; - } - - /* If buffer full, then invoke callback */ - if (DATA_CHUNK_SIZE - state->data_chunk_len < EOL_LEN + 1) { - - /* Invoke pre-processor and callback */ - ret = ProcessDecodedDataChunk(state->data_chunk, - state->data_chunk_len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessDecodedDataChunk() function " - "failed"); - } - } - - remaining -= tobuf; - offset += tobuf; - } - } - - return ret; -} - -/** - * \brief Find the start of a header name on the current line - * - * \param buf The input line (not null-terminated) - * \param blen The length of the input line - * \param glen The output length of the header name - * - * \return Pointer to header name, or NULL if not found - */ -static uint8_t * FindMimeHeaderStart(const uint8_t *buf, uint32_t blen, uint32_t *hlen) -{ - uint32_t i, valid = 0; - uint8_t *hname = NULL; - - /* Init */ - *hlen = 0; - - /* Look for sequence of printable characters followed by ':', or - CRLF then printable characters followed by ':' */ - for (i = 0; i < blen && buf[i] != 0; i++) { - - /* If ready for printable characters and found one, then increment */ - if (buf[i] != COLON && buf[i] >= PRINTABLE_START && - buf[i] <= PRINTABLE_END) { - valid++; - } else if (valid > 0 && buf[i] == COLON) { - /* If ready for printable characters, found some, and found colon - * delimiter, then a match is found */ - hname = (uint8_t *) buf + i - valid; - *hlen = valid; - break; - } else { - /* Otherwise reset and quit */ - break; - } - } - - return hname; -} - -/** - * \brief Find full header name and value on the current line based on the - * current state - * - * \param buf The current line (no CRLF) - * \param blen The length of the current line - * \param state The current state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int FindMimeHeader(const uint8_t *buf, uint32_t blen, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - uint8_t *hname, *hval = NULL; - DataValue *dv; - uint32_t hlen, vlen; - int finish_header = 0, new_header = 0; - MimeDecConfig *mdcfg = MimeDecGetConfig(); - - /* Find first header */ - hname = FindMimeHeaderStart(buf, blen, &hlen); - if (hname != NULL) { - - /* Warn and track but don't do anything yet */ - if (hlen > MAX_HEADER_NAME) { - state->stack->top->data->anomaly_flags |= ANOM_LONG_HEADER_NAME; - state->msg->anomaly_flags |= ANOM_LONG_HEADER_NAME; - SCLogDebug("Error: Header name exceeds limit (%u > %u)", - hlen, MAX_HEADER_NAME); - } - - /* Value starts after 'header:' (normalize spaces) */ - hval = hname + hlen + 1; - if (hval - buf >= (int)blen) { - SCLogDebug("No Header value found"); - hval = NULL; - } else { - while (hval[0] == ' ') { - - /* If last character before end of bounds, set to NULL */ - if (hval - buf >= (int)blen - 1) { - SCLogDebug("No Header value found"); - hval = NULL; - break; - } - - hval++; - } - } - - /* If new header found, then previous header is finished */ - if (state->state_flag == HEADER_STARTED) { - finish_header = 1; - } - - /* Now process new header */ - new_header = 1; - - /* Must wait for next line to determine if finished */ - state->state_flag = HEADER_STARTED; - } else if (blen == 0) { - /* Found body */ - /* No more headers */ - state->state_flag = HEADER_DONE; - - finish_header = 1; - - SCLogDebug("All Header processing finished"); - } else if (state->state_flag == HEADER_STARTED) { - /* Found multi-line value (ie. Received header) */ - /* If max header value exceeded, flag it */ - vlen = blen; - if ((mdcfg != NULL) && (state->hvlen + vlen > mdcfg->header_value_depth)) { - SCLogDebug("Error: Header value of length (%u) is too long", - state->hvlen + vlen); - vlen = mdcfg->header_value_depth - state->hvlen; - state->stack->top->data->anomaly_flags |= ANOM_LONG_HEADER_VALUE; - state->msg->anomaly_flags |= ANOM_LONG_HEADER_VALUE; - } - if (vlen > 0) { - dv = AddDataValue(state->hvalue); - if (dv == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "AddDataValue() function failed"); - return MIME_DEC_ERR_MEM; - } - if (state->hvalue == NULL) { - state->hvalue = dv; - } - - dv->value = SCMalloc(vlen); - if (unlikely(dv->value == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed"); - return MIME_DEC_ERR_MEM; - } - memcpy(dv->value, buf, vlen); - dv->value_len = vlen; - state->hvlen += vlen; - } - } else { - /* Likely a body without headers */ - SCLogDebug("No headers found"); - - state->state_flag = BODY_STARTED; - - /* Flag beginning of body */ - state->body_begin = 1; - state->body_end = 0; - - ret = ProcessBodyLine(buf, blen, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessBodyLine() function failed"); - return ret; - } - } - - /* If we need to finish a header, then do so below and then cleanup */ - if (finish_header) { - /* Store the header value */ - ret = StoreMimeHeader(state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: StoreMimeHeader() function failed"); - return ret; - } - } - - /* When next header is found, we always create a new one */ - if (new_header) { - /* Copy name and value to state */ - state->hname = SCMalloc(hlen); - if (unlikely(state->hname == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed"); - return MIME_DEC_ERR_MEM; - } - memcpy(state->hname, hname, hlen); - state->hlen = hlen; - - if (state->hvalue != NULL) { - SCLogDebug("Error: Parser failed due to unexpected header " - "value"); - return MIME_DEC_ERR_DATA; - } - - if (hval != NULL) { - /* If max header value exceeded, flag it */ - vlen = blen - (hval - buf); - if ((mdcfg != NULL) && (state->hvlen + vlen > mdcfg->header_value_depth)) { - SCLogDebug("Error: Header value of length (%u) is too long", - state->hvlen + vlen); - vlen = mdcfg->header_value_depth - state->hvlen; - state->stack->top->data->anomaly_flags |= ANOM_LONG_HEADER_VALUE; - state->msg->anomaly_flags |= ANOM_LONG_HEADER_VALUE; - } - - if (vlen > 0) { - state->hvalue = AddDataValue(NULL); - if (state->hvalue == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "AddDataValue() function failed"); - return MIME_DEC_ERR_MEM; - } - state->hvalue->value = SCMalloc(vlen); - if (unlikely(state->hvalue->value == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed"); - return MIME_DEC_ERR_MEM; - } - memcpy(state->hvalue->value, hval, vlen); - state->hvalue->value_len = vlen; - state->hvlen += vlen; - } - } - } - - return ret; -} - -/** - * \brief Finds a mime header token within the specified field - * - * \param field The current field - * \param search_start The start of the search (ie. boundary=\") - * \param search_end The end of the search (ie. \") - * \param tlen The output length of the token (if found) - * - * \return A pointer to the token if found, otherwise NULL if not found - */ -static uint8_t * FindMimeHeaderToken(MimeDecField *field, char *search_start, - char *search_end, uint32_t *tlen) -{ - uint8_t *fptr, *tptr = NULL, *tok = NULL; - - SCLogDebug("Looking for token: %s", search_start); - - /* Check for token definition */ - fptr = FindBuffer(field->value, field->value_len, (const uint8_t *)search_start, strlen(search_start)); - if (fptr != NULL) { - fptr += strlen(search_start); /* Start at end of start string */ - tok = GetToken(fptr, field->value_len - (fptr - field->value), search_end, - &tptr, tlen); - if (tok != NULL) { - SCLogDebug("Found mime token"); - } - } - - return tok; -} - -/** - * \brief Processes the current line for mime headers and also does post-processing - * when all headers found - * - * \param buf The current line - * \param len The length of the line - * \param state The current parser state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int ProcessMimeHeaders(const uint8_t *buf, uint32_t len, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - MimeDecField *field; - uint8_t *bptr = NULL, *rptr = NULL; - uint32_t blen = 0; - MimeDecEntity *entity = (MimeDecEntity *) state->stack->top->data; - - /* Look for mime header in current line */ - ret = FindMimeHeader(buf, len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: FindMimeHeader() function failed: %d", ret); - return ret; - } - - /* Post-processing after all headers done */ - if (state->state_flag == HEADER_DONE) { - /* First determine encoding by looking at Content-Transfer-Encoding */ - field = MimeDecFindField(entity, CTNT_TRAN_STR); - if (field != NULL) { - /* Look for base64 */ - if (FindBuffer(field->value, field->value_len, (const uint8_t *)BASE64_STR, strlen(BASE64_STR))) { - SCLogDebug("Base64 encoding found"); - entity->ctnt_flags |= CTNT_IS_BASE64; - } else if (FindBuffer(field->value, field->value_len, (const uint8_t *)QP_STR, strlen(QP_STR))) { - /* Look for quoted-printable */ - SCLogDebug("quoted-printable encoding found"); - entity->ctnt_flags |= CTNT_IS_QP; - } - } - - /* Check for file attachment in content disposition */ - field = MimeDecFindField(entity, CTNT_DISP_STR); - if (field != NULL) { - bptr = FindMimeHeaderToken(field, "filename=\"", TOK_END_STR, &blen); - if (bptr != NULL) { - SCLogDebug("File attachment found in disposition"); - entity->ctnt_flags |= CTNT_IS_ATTACHMENT; - - /* Copy over using dynamic memory */ - entity->filename = SCMalloc(blen); - if (unlikely(entity->filename == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - return MIME_DEC_ERR_MEM; - } - memcpy(entity->filename, bptr, blen); - entity->filename_len = blen; - } - } - - /* Check for boundary, encapsulated message, and file name in Content-Type */ - field = MimeDecFindField(entity, CTNT_TYPE_STR); - if (field != NULL) { - /* Check if child entity boundary definition found */ - bptr = FindMimeHeaderToken(field, BND_START_STR, TOK_END_STR, &blen); - if (bptr != NULL) { - state->found_child = 1; - entity->ctnt_flags |= CTNT_IS_MULTIPART; - - if (blen > (BOUNDARY_BUF - 2)) { - state->stack->top->data->anomaly_flags |= ANOM_LONG_BOUNDARY; - return MIME_DEC_ERR_PARSE; - } - - /* Store boundary in parent node */ - state->stack->top->bdef = SCMalloc(blen); - if (unlikely(state->stack->top->bdef == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed"); - return MIME_DEC_ERR_MEM; - } - memcpy(state->stack->top->bdef, bptr, blen); - state->stack->top->bdef_len = blen; - } - - /* Look for file name (if not already found) */ - if (!(entity->ctnt_flags & CTNT_IS_ATTACHMENT)) { - bptr = FindMimeHeaderToken(field, "name=\"", TOK_END_STR, &blen); - if (bptr != NULL) { - SCLogDebug("File attachment found"); - entity->ctnt_flags |= CTNT_IS_ATTACHMENT; - - /* Copy over using dynamic memory */ - entity->filename = SCMalloc(blen); - if (unlikely(entity->filename == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - return MIME_DEC_ERR_MEM; - } - memcpy(entity->filename, bptr, blen); - entity->filename_len = blen; - } - } - - /* Pull out short-hand content type */ - entity->ctnt_type = GetToken(field->value, field->value_len, " \r\n;", - &rptr, &entity->ctnt_type_len); - if (entity->ctnt_type != NULL) { - /* Check for encapsulated message */ - if (FindBuffer(entity->ctnt_type, entity->ctnt_type_len, - (const uint8_t *)MSG_STR, strlen(MSG_STR))) - { - SCLogDebug("Found encapsulated message entity"); - - entity->ctnt_flags |= CTNT_IS_ENV; - - /* Create and push child to stack */ - MimeDecEntity *child = MimeDecAddEntity(entity); - if (child == NULL) - return MIME_DEC_ERR_MEM; - child->ctnt_flags |= (CTNT_IS_ENCAP | CTNT_IS_MSG); - PushStack(state->stack); - state->stack->top->data = child; - - /* Mark as encapsulated child */ - state->stack->top->is_encap = 1; - - /* Ready to parse headers */ - state->state_flag = HEADER_READY; - } else if (FindBuffer(entity->ctnt_type, entity->ctnt_type_len, - (const uint8_t *)MULTIPART_STR, strlen(MULTIPART_STR))) - { - /* Check for multipart */ - SCLogDebug("Found multipart entity"); - entity->ctnt_flags |= CTNT_IS_MULTIPART; - } else if (FindBuffer(entity->ctnt_type, entity->ctnt_type_len, - (const uint8_t *)TXT_STR, strlen(TXT_STR))) - { - /* Check for plain text */ - SCLogDebug("Found plain text entity"); - entity->ctnt_flags |= CTNT_IS_TEXT; - } else if (FindBuffer(entity->ctnt_type, entity->ctnt_type_len, - (const uint8_t *)HTML_STR, strlen(HTML_STR))) - { - /* Check for html */ - SCLogDebug("Found html entity"); - entity->ctnt_flags |= CTNT_IS_HTML; - } - } - } - - /* Store pointer to Message-ID */ - field = MimeDecFindField(entity, MSG_ID_STR); - if (field != NULL) { - entity->msg_id = field->value; - entity->msg_id_len = field->value_len; - } - - /* Flag beginning of body */ - state->body_begin = 1; - state->body_end = 0; - } - - return ret; -} - -/** - * \brief Indicates to the parser that the body of an entity has completed - * processing on the previous line - * - * \param state The current parser state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ - -static int ProcessBodyComplete(MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - - SCLogDebug("Process body complete called"); - - /* Mark the file as hitting the end */ - state->body_end = 1; - - if (state->bvr_len > 0) { - SCLogDebug("Found (%u) remaining base64 bytes not processed", - state->bvr_len); - - /* Process the remainder */ - ret = ProcessBase64Remainder(NULL, 0, state, 1); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessBase64BodyLine() function failed"); - } - } - -#ifdef HAVE_NSS - if (state->md5_ctx) { - unsigned int len = 0; - HASH_End(state->md5_ctx, state->md5, &len, sizeof(state->md5)); - } -#endif - - /* Invoke pre-processor and callback with remaining data */ - ret = ProcessDecodedDataChunk(state->data_chunk, state->data_chunk_len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessDecodedDataChunk() function failed"); - } - - /* Now reset */ - state->body_begin = 0; - state->body_end = 0; - - return ret; -} - -/** - * \brief When a mime boundary is found, look for end boundary and also do stack - * management - * - * \param buf The current line - * \param len The length of the line - * \param bdef_len The length of the current boundary - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int ProcessMimeBoundary(const uint8_t *buf, uint32_t len, uint32_t bdef_len, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - uint8_t *rptr; - MimeDecEntity *child; - - SCLogDebug("PROCESSING BOUNDARY - START: %d", - state->state_flag); - - /* If previous line was not an end boundary, then we process the body as - * completed */ - if (state->state_flag != BODY_END_BOUND) { - - /* First lets complete the body */ - ret = ProcessBodyComplete(state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessBodyComplete() function failed"); - return ret; - } - } else { - /* If last line was an end boundary, then now we are ready to parse - * headers again */ - state->state_flag = HEADER_READY; - } - - /* Update remaining buffer */ - rptr = (uint8_t *) buf + bdef_len + 2; - - /* If entity is encapsulated and current and parent didn't define the boundary, - * then pop out */ - if (state->stack->top->is_encap && state->stack->top->bdef_len == 0) { - - if (state->stack->top->next == NULL) { - SCLogDebug("Error: Missing parent entity from stack"); - return MIME_DEC_ERR_DATA; - } - - if (state->stack->top->next->bdef_len == 0) { - - SCLogDebug("POPPED ENCAPSULATED CHILD FROM STACK: %p=%p", - state->stack->top, state->stack->top->data); - - /* If end of boundary found, pop the child off the stack */ - PopStack(state->stack); - if (state->stack->top == NULL) { - SCLogDebug("Error: Message is malformed"); - return MIME_DEC_ERR_DATA; - } - } - } - - /* Now check for end of nested boundary */ - if (len - (rptr - buf) > 1 && rptr[0] == DASH && rptr[1] == DASH) { - SCLogDebug("FOUND END BOUNDARY, POPPING: %p=%p", - state->stack->top, state->stack->top->data); - - /* If end of boundary found, pop the child off the stack */ - PopStack(state->stack); - if (state->stack->top == NULL) { - SCLogDebug("Error: Message is malformed"); - return MIME_DEC_ERR_DATA; - } - - /* If current is an encapsulated message with a boundary definition, - * then pop him as well */ - if (state->stack->top->is_encap && state->stack->top->bdef_len != 0) { - SCLogDebug("FOUND END BOUNDARY AND ENCAP, POPPING: %p=%p", - state->stack->top, state->stack->top->data); - - PopStack(state->stack); - if (state->stack->top == NULL) { - SCLogDebug("Error: Message is malformed"); - return MIME_DEC_ERR_DATA; - } - } - - state->state_flag = BODY_END_BOUND; - } else if (state->found_child) { - /* Otherwise process new child */ - SCLogDebug("Child entity created"); - - /* Create and push child to stack */ - child = MimeDecAddEntity(state->stack->top->data); - if (child == NULL) - return MIME_DEC_ERR_MEM; - child->ctnt_flags |= CTNT_IS_BODYPART; - PushStack(state->stack); - state->stack->top->data = child; - - /* Reset flag */ - state->found_child = 0; - } else { - /* Otherwise process sibling */ - if (state->stack->top->next == NULL) { - SCLogDebug("Error: Missing parent entity from stack"); - return MIME_DEC_ERR_DATA; - } - - SCLogDebug("SIBLING CREATED, POPPING PARENT: %p=%p", - state->stack->top, state->stack->top->data); - - /* First pop current to get access to parent */ - PopStack(state->stack); - if (state->stack->top == NULL) { - SCLogDebug("Error: Message is malformed"); - return MIME_DEC_ERR_DATA; - } - - /* Create and push child to stack */ - child = MimeDecAddEntity(state->stack->top->data); - if (child == NULL) - return MIME_DEC_ERR_MEM; - child->ctnt_flags |= CTNT_IS_BODYPART; - PushStack(state->stack); - state->stack->top->data = child; - } - - /* After boundary look for headers */ - if (state->state_flag != BODY_END_BOUND) { - state->state_flag = HEADER_READY; - } - - SCLogDebug("PROCESSING BOUNDARY - END: %d", state->state_flag); - return ret; -} - -/** - * \brief Processes the MIME Entity body based on the input line and current - * state of the parser - * - * \param buf The current line - * \param len The length of the line - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int ProcessMimeBody(const uint8_t *buf, uint32_t len, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - uint8_t temp[BOUNDARY_BUF]; - uint8_t *bstart; - int body_found = 0; - uint32_t tlen; - -#ifdef HAVE_NSS - if (MimeDecGetConfig()->body_md5) { - if (state->body_begin == 1) { - if (state->md5_ctx == NULL) { - state->md5_ctx = HASH_Create(HASH_AlgMD5); - HASH_Begin(state->md5_ctx); - } - } - HASH_Update(state->md5_ctx, buf, len + state->current_line_delimiter_len); - } -#endif - - /* Ignore empty lines */ - if (len == 0) { - return ret; - } - - /* First look for boundary */ - MimeDecStackNode *node = state->stack->top; - if (node == NULL) { - SCLogDebug("Error: Invalid stack state"); - return MIME_DEC_ERR_PARSE; - } - - /* Traverse through stack to find a boundary definition */ - if (state->state_flag == BODY_END_BOUND || node->bdef == NULL) { - - /* If not found, then use parent's boundary */ - node = node->next; - while (node != NULL && node->bdef == NULL) { - SCLogDebug("Traversing through stack for node with boundary"); - node = node->next; - } - } - - /* This means no boundary / parent w/boundary was found so we are in the body */ - if (node == NULL) { - body_found = 1; - } else { - - /* Now look for start of boundary */ - if (len > 1 && buf[0] == '-' && buf[1] == '-') { - - tlen = node->bdef_len + 2; - if (tlen > BOUNDARY_BUF) { - if (state->stack->top->data) - state->stack->top->data->anomaly_flags |= ANOM_LONG_BOUNDARY; - return MIME_DEC_ERR_PARSE; - } - - memcpy(temp, "--", 2); - memcpy(temp + 2, node->bdef, node->bdef_len); - - /* Find either next boundary or end boundary */ - bstart = FindBuffer((const uint8_t *)buf, len, temp, tlen); - if (bstart != NULL) { - ret = ProcessMimeBoundary(buf, len, node->bdef_len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessMimeBoundary() function " - "failed"); - return ret; - } - } else { - /* Otherwise add value to body */ - body_found = 1; - } - } else { - /* Otherwise add value to body */ - body_found = 1; - } - } - - /* Process body line */ - if (body_found) { - state->state_flag = BODY_STARTED; - - ret = ProcessBodyLine(buf, len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessBodyLine() function failed"); - return ret; - } - } - - return ret; -} - -const char *MimeDecParseStateGetStatus(MimeDecParseState *state) -{ - return StateFlags[state->state_flag]; -} - -/** - * \brief Processes the MIME Entity based on the input line and current state of - * the parser - * - * \param buf The current line - * \param len The length of the line - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -static int ProcessMimeEntity(const uint8_t *buf, uint32_t len, - MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - - SCLogDebug("START FLAG: %s", StateFlags[state->state_flag]); - - /* Track long line */ - if (len > MAX_LINE_LEN) { - state->stack->top->data->anomaly_flags |= ANOM_LONG_LINE; - state->msg->anomaly_flags |= ANOM_LONG_LINE; - SCLogDebug("Error: Max input line length exceeded %u > %u", len, - MAX_LINE_LEN); - } - - /* Looking for headers */ - if (state->state_flag == HEADER_READY || - state->state_flag == HEADER_STARTED) { - - SCLogDebug("Processing Headers"); - - /* Process message headers */ - ret = ProcessMimeHeaders(buf, len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessMimeHeaders() function failed: %d", - ret); - return ret; - } - } else { - /* Processing body */ - SCLogDebug("Processing Body of: %p", state->stack->top); - - ret = ProcessMimeBody(buf, len, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessMimeBody() function failed: %d", - ret); - return ret; - } - } - - SCLogDebug("END FLAG: %s", StateFlags[state->state_flag]); - - return ret; -} - -/** - * \brief Init the parser by allocating memory for the state and top-level entity - * - * \param data A caller-specified pointer to data for access within the data chunk - * processor callback function - * \param dcpfunc The data chunk processor callback function - * - * \return A pointer to the state object, or NULL if the operation fails - */ -MimeDecParseState * MimeDecInitParser(void *data, - int (*DataChunkProcessorFunc)(const uint8_t *chunk, uint32_t len, - MimeDecParseState *state)) -{ - MimeDecParseState *state; - MimeDecEntity *mimeMsg; - - state = SCMalloc(sizeof(MimeDecParseState)); - if (unlikely(state == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - return NULL; - } - memset(state, 0x00, sizeof(MimeDecParseState)); - - state->stack = SCMalloc(sizeof(MimeDecStack)); - if (unlikely(state->stack == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - SCFree(state); - return NULL; - } - memset(state->stack, 0x00, sizeof(MimeDecStack)); - - mimeMsg = SCMalloc(sizeof(MimeDecEntity)); - if (unlikely(mimeMsg == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - SCFree(state->stack); - SCFree(state); - return NULL; - } - memset(mimeMsg, 0x00, sizeof(MimeDecEntity)); - mimeMsg->ctnt_flags |= CTNT_IS_MSG; - - /* Init state */ - state->msg = mimeMsg; - PushStack(state->stack); - if (state->stack->top == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "memory allocation failed"); - SCFree(state->stack); - SCFree(state); - return NULL; - } - state->stack->top->data = mimeMsg; - state->state_flag = HEADER_READY; - state->data = data; - state->DataChunkProcessorFunc = DataChunkProcessorFunc; - - return state; -} - -/** - * \brief De-Init parser by freeing up any residual memory - * - * \param state The parser state - * - * \return none - */ -void MimeDecDeInitParser(MimeDecParseState *state) -{ - uint32_t cnt = 0; - - while (state->stack->top != NULL) { - SCLogDebug("Remaining on stack: [%p]=>[%p]", - state->stack->top, state->stack->top->data); - - PopStack(state->stack); - cnt++; - } - - if (cnt > 1) { - state->msg->anomaly_flags |= ANOM_MALFORMED_MSG; - SCLogDebug("Warning: Stack is not empty upon completion of " - "processing (%u items remaining)", cnt); - } - - SCFree(state->hname); - FreeDataValue(state->hvalue); - FreeMimeDecStack(state->stack); -#ifdef HAVE_NSS - if (state->md5_ctx) - HASH_Destroy(state->md5_ctx); -#endif - SCFree(state); -} - -/** - * \brief Called to indicate that the last message line has been processed and - * the parsing operation is complete - * - * This function should be called directly by the caller. - * - * \param state The parser state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -int MimeDecParseComplete(MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - - SCLogDebug("Parsing flagged as completed"); - - /* Store the header value */ - ret = StoreMimeHeader(state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: StoreMimeHeader() function failed"); - return ret; - } - - /* Lets complete the body */ - ret = ProcessBodyComplete(state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: ProcessBodyComplete() function failed"); - return ret; - } - - if (state->stack->top == NULL) { - state->msg->anomaly_flags |= ANOM_MALFORMED_MSG; - SCLogDebug("Error: Message is malformed"); - return MIME_DEC_ERR_DATA; - } - - /* If encapsulated, pop off the stack */ - if (state->stack->top->is_encap) { - PopStack(state->stack); - if (state->stack->top == NULL) { - state->msg->anomaly_flags |= ANOM_MALFORMED_MSG; - SCLogDebug("Error: Message is malformed"); - return MIME_DEC_ERR_DATA; - } - } - - /* Look extra stack items remaining */ - if (state->stack->top->next != NULL) { - state->msg->anomaly_flags |= ANOM_MALFORMED_MSG; - SCLogDebug("Warning: Message has unclosed message part boundary"); - } - - state->state_flag = PARSE_DONE; - - return ret; -} - -/** - * \brief Parse a line of a MIME message and update the parser state - * - * \param line A string representing the line (w/out CRLF) - * \param len The length of the line - * \param delim_len The length of the line end delimiter - * \param state The parser state - * - * \return MIME_DEC_OK on success, otherwise < 0 on failure - */ -int MimeDecParseLine(const uint8_t *line, const uint32_t len, - const uint8_t delim_len, MimeDecParseState *state) -{ - int ret = MIME_DEC_OK; - - /* For debugging purposes */ - if (len > 0) { - PrintChars(SC_LOG_DEBUG, "SMTP LINE", line, len); - } else { - SCLogDebug("SMTP LINE - EMPTY"); - } - - state->current_line_delimiter_len = delim_len; - /* Process the entity */ - ret = ProcessMimeEntity(line, len, state); - if (ret != MIME_DEC_OK) { - state->state_flag = PARSE_ERROR; - SCLogDebug("Error: ProcessMimeEntity() function failed: %d", ret); - } - - return ret; -} - -/** - * \brief Parses an entire message when available in its entirety (wraps the - * line-based parsing functions) - * - * \param buf Buffer pointing to the full message - * \param blen Length of the buffer - * \param data Caller data to be available in callback - * \param dcpfunc Callback for processing each decoded body data chunk - * - * \return A pointer to the decoded MIME message, or NULL if the operation fails - */ -MimeDecEntity * MimeDecParseFullMsg(const uint8_t *buf, uint32_t blen, void *data, - int (*dcpfunc)(const uint8_t *chunk, uint32_t len, - MimeDecParseState *state)) -{ - int ret = MIME_DEC_OK; - uint8_t *remainPtr, *tok; - uint32_t tokLen; - - MimeDecParseState *state = MimeDecInitParser(data, dcpfunc); - if (state == NULL) { - SCLogDebug("Error: MimeDecInitParser() function failed to create " - "state"); - return NULL; - } - - MimeDecEntity *msg = state->msg; - - /* Parse each line one by one */ - remainPtr = (uint8_t *) buf; - uint8_t *line = NULL; - do { - tok = GetLine(remainPtr, blen - (remainPtr - buf), &remainPtr, &tokLen); - if (tok != remainPtr) { - - line = tok; - - state->current_line_delimiter_len = (remainPtr - tok) - tokLen; - /* Parse the line */ - ret = MimeDecParseLine(line, tokLen, - (remainPtr - tok) - tokLen, state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: MimeDecParseLine() function failed: %d", - ret); - break; - } - } - - } while (tok != remainPtr && remainPtr - buf < (int)blen); - - if (ret == MIME_DEC_OK) { - SCLogDebug("Message parser was successful"); - - /* Now complete message */ - ret = MimeDecParseComplete(state); - if (ret != MIME_DEC_OK) { - SCLogDebug("Error: MimeDecParseComplete() function failed"); - } - } - - /* De-allocate memory for parser */ - MimeDecDeInitParser(state); - - if (ret != MIME_DEC_OK) { - MimeDecFreeEntity(msg); - msg = NULL; - } - - return msg; -} - -#ifdef UNITTESTS - -/* Helper body chunk callback function */ -static int TestDataChunkCallback(const uint8_t *chunk, uint32_t len, - MimeDecParseState *state) -{ - uint32_t *line_count = (uint32_t *) state->data; - - if (state->body_begin) { - SCLogDebug("Body begin (len=%u)", len); - } - - /* Add up the line counts */ - if (len > 0) { - - uint8_t *remainPtr; - uint8_t *tok; - uint32_t tokLen; - - PrintChars(SC_LOG_DEBUG, "CHUNK", chunk, len); - - /* Parse each line one by one */ - remainPtr = (uint8_t *) chunk; - do { - tok = GetLine(remainPtr, len - (remainPtr - (uint8_t *) chunk), - &remainPtr, &tokLen); - if (tok != NULL && tok != remainPtr) { - (*line_count)++; - } - - } while (tok != NULL && tok != remainPtr && - (uint32_t)(remainPtr - (uint8_t *) chunk) < len); - - SCLogDebug("line count (len=%u): %u", len, *line_count); - } - - if (state->body_end) { - SCLogDebug("Body end (len=%u)", len); - } - - return MIME_DEC_OK; -} - -/* Test simple case of line counts */ -static int MimeDecParseLineTest01(void) -{ - int ret = MIME_DEC_OK; - - uint32_t expected_count = 3; - uint32_t line_count = 0; - - /* Init parser */ - MimeDecParseState *state = MimeDecInitParser(&line_count, - TestDataChunkCallback); - - char *str = "From: Sender1"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = "To: Recipient1"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = "Content-Type: text/plain"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = ""; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = "A simple message line 1"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = "A simple message line 2"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = "A simple message line 3"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - if (ret != MIME_DEC_OK) { - return ret; - } - /* Completed */ - ret = MimeDecParseComplete(state); - if (ret != MIME_DEC_OK) { - return ret; - } - - MimeDecEntity *msg = state->msg; - if (msg->next != NULL || msg->child != NULL) { - SCLogInfo("Error: Invalid sibling or child message"); - return -1; - } - - MimeDecFreeEntity(msg); - - /* De Init parser */ - MimeDecDeInitParser(state); - - SCLogInfo("LINE COUNT FINISHED: %d", line_count); - - if (expected_count != line_count) { - SCLogInfo("Error: Line count is invalid: expected - %d actual - %d", - expected_count, line_count); - return -1; - } - - return ret; -} - -/* Test simple case of EXE URL extraction */ -static int MimeDecParseLineTest02(void) -{ - int ret = MIME_DEC_OK; - - uint32_t expected_count = 2; - uint32_t line_count = 0; - - MimeDecGetConfig()->decode_base64 = 1; - MimeDecGetConfig()->decode_quoted_printable = 1; - MimeDecGetConfig()->extract_urls = 1; - - /* Init parser */ - MimeDecParseState *state = MimeDecInitParser(&line_count, - TestDataChunkCallback); - - char *str = "From: Sender1"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = "To: Recipient1"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = "Content-Type: text/plain"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = ""; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = "A simple message line 1"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - str = "A simple message line 2 click on http://www.test.com/malware.exe?" - "hahah hopefully you click this link"; - ret |= MimeDecParseLine((uint8_t *)str, strlen(str), 1, state); - - if (ret != MIME_DEC_OK) { - return ret; - } - /* Completed */ - ret = MimeDecParseComplete(state); - if (ret != MIME_DEC_OK) { - return ret; - } - - MimeDecEntity *msg = state->msg; - if (msg->url_list == NULL || (msg->url_list != NULL && - !(msg->url_list->url_flags & URL_IS_EXE))) { - SCLogInfo("Warning: Expected EXE URL not found"); - return -1; - } - - MimeDecFreeEntity(msg); - - /* De Init parser */ - MimeDecDeInitParser(state); - - SCLogInfo("LINE COUNT FINISHED: %d", line_count); - - if (expected_count != line_count) { - SCLogInfo("Warning: Line count is invalid: expected - %d actual - %d", - expected_count, line_count); - return -1; - } - - return ret; -} - -/* Test full message with linebreaks */ -static int MimeDecParseFullMsgTest01(void) -{ - int ret = MIME_DEC_OK; - - uint32_t expected_count = 3; - uint32_t line_count = 0; - - char msg[] = "From: Sender1\r\n" - "To: Recipient1\r\n" - "Content-Type: text/plain\r\n" - "\r\n" - "Line 1\r\n" - "Line 2\r\n" - "Line 3\r\n"; - - MimeDecEntity *entity = MimeDecParseFullMsg((uint8_t *)msg, strlen(msg), &line_count, - TestDataChunkCallback); - if (entity == NULL) { - SCLogInfo("Warning: Message failed to parse"); - return -1; - } - - MimeDecFreeEntity(entity); - - if (expected_count != line_count) { - SCLogInfo("Warning: Line count is invalid: expected - %d actual - %d", - expected_count, line_count); - return -1; - } - - return ret; -} - -/* Test full message with linebreaks */ -static int MimeDecParseFullMsgTest02(void) -{ - int ret = MIME_DEC_OK; - - uint32_t expected_count = 3; - uint32_t line_count = 0; - - char msg[] = "From: Sender2\r\n" - "To: Recipient2\r\n" - "Subject: subject2\r\n" - "Content-Type: text/plain\r\n" - "\r\n" - "Line 1\r\n" - "Line 2\r\n" - "Line 3\r\n"; - - MimeDecEntity *entity = MimeDecParseFullMsg((uint8_t *)msg, strlen(msg), &line_count, - TestDataChunkCallback); - - if (entity == NULL) { - SCLogInfo("Warning: Message failed to parse"); - return -1; - } - - MimeDecField *field = MimeDecFindField(entity, "subject"); - if (field == NULL) { - SCLogInfo("Warning: Message failed to parse"); - return -1; - } - - if (field->value_len != sizeof("subject2") - 1) { - SCLogInfo("Warning: failed to get subject"); - return -1; - } - - if (memcmp(field->value, "subject2", field->value_len) != 0) { - SCLogInfo("Warning: failed to get subject"); - return -1; - } - - - MimeDecFreeEntity(entity); - - if (expected_count != line_count) { - SCLogInfo("Warning: Line count is invalid: expected - %d actual - %d", - expected_count, line_count); - return -1; - } - - return ret; -} - -static int MimeBase64DecodeTest01(void) -{ - int ret = -1; - - char *msg = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890@" - "#$%^&*()-=_+,./;'[]<>?:"; - char *base64msg = "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZHSElKS0xNTk9QU" - "VJTVFVWV1hZWjEyMzQ1Njc4OTBAIyQlXiYqKCktPV8rLC4vOydbXTw+Pzo="; - - uint8_t *dst = SCMalloc(strlen(msg) + 1); - if (dst == NULL) - return 0; - - ret = DecodeBase64(dst, (const uint8_t *)base64msg, strlen(base64msg), 1); - - if (memcmp(dst, msg, strlen(msg)) == 0) { - ret = 0; - } - - SCFree(dst); - - return ret; -} - -static int MimeIsExeURLTest01(void) -{ - int ret = -1; - char *url1 = "http://www.google.com/"; - char *url2 = "http://www.google.com/test.exe"; - - if(IsExeUrl((const uint8_t *)url1, strlen(url1)) != 0){ - SCLogDebug("Debug: URL1 error"); - goto end; - } - if(IsExeUrl((const uint8_t *)url2, strlen(url2)) != 1){ - SCLogDebug("Debug: URL2 error"); - goto end; - } - ret = 0; - - end: - - return ret; -} - -static int MimeIsIpv4HostTest01(void) -{ - if(IsIpv4Host((const uint8_t *)"192.168.1.1", 11) != 1) { - return 1; - } - - if(IsIpv4Host((const uint8_t *)"999.oogle.com", 14) != 0) { - return 1; - } - - if(IsIpv4Host((const uint8_t *)"0:0:0:0:0:0:0:0", 15) != 0) { - return 1; - } - - if (IsIpv4Host((const uint8_t *)"192.168.255.255", 15) != 1) { - return 1; - } - - if (IsIpv4Host((const uint8_t *)"192.168.255.255/testurl.html", 28) != 1) { - return 1; - } - - if (IsIpv4Host((const uint8_t *)"www.google.com", 14) != 0) { - return 1; - } - - return 0; -} - -static int MimeIsIpv6HostTest01(void) -{ - if(IsIpv6Host((const uint8_t *)"0:0:0:0:0:0:0:0", 19) != 1) { - return 1; - } - - if(IsIpv6Host((const uint8_t *)"0000:0000:0000:0000:0000:0000:0000:0000", 39) != 1) { - return 1; - } - - if(IsIpv6Host((const uint8_t *)"0:0:0:0:0:0:0:0", 19) != 1) { - return 1; - } - - if(IsIpv6Host((const uint8_t *)"192:168:1:1:0:0:0:0", 19) != 1) { - return 1; - } - - if(IsIpv6Host((const uint8_t *)"999.oogle.com", 14) != 0) { - return 1; - } - - if (IsIpv6Host((const uint8_t *)"192.168.255.255", 15) != 0) { - return 1; - } - - if (IsIpv6Host((const uint8_t *)"192.168.255.255/testurl.html", 28) != 0) { - return 1; - } - - if (IsIpv6Host((const uint8_t *)"www.google.com", 14) != 0) { - return 1; - } - - return 0; -} - -#endif /* UNITTESTS */ - -void MimeDecRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("MimeDecParseLineTest01", MimeDecParseLineTest01, 0); - UtRegisterTest("MimeDecParseLineTest02", MimeDecParseLineTest02, 0); - UtRegisterTest("MimeDecParseFullMsgTest01", MimeDecParseFullMsgTest01, 0); - UtRegisterTest("MimeDecParseFullMsgTest02", MimeDecParseFullMsgTest02, 0); - UtRegisterTest("MimeBase64DecodeTest01", MimeBase64DecodeTest01, 0); - UtRegisterTest("MimeIsExeURLTest01", MimeIsExeURLTest01, 0); - UtRegisterTest("MimeIsIpv4HostTest01", MimeIsIpv4HostTest01, 0); - UtRegisterTest("MimeIsIpv6HostTest01", MimeIsIpv6HostTest01, 0); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/util-decode-mime.h b/framework/src/suricata/src/util-decode-mime.h deleted file mode 100644 index 02b3bb13..00000000 --- a/framework/src/suricata/src/util-decode-mime.h +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright (C) 2012 BAE Systems - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author David Abarbanel - * - */ - -#ifndef MIME_DECODE_H_ -#define MIME_DECODE_H_ - -#include -#include -#include - -#include "suricata.h" -#include "util-base64.h" -#include "util-debug.h" - -/* Content Flags */ -#define CTNT_IS_MSG 1 -#define CTNT_IS_ENV 2 -#define CTNT_IS_ENCAP 4 -#define CTNT_IS_BODYPART 8 -#define CTNT_IS_MULTIPART 16 -#define CTNT_IS_ATTACHMENT 32 -#define CTNT_IS_BASE64 64 -#define CTNT_IS_QP 128 -#define CTNT_IS_TEXT 256 -#define CTNT_IS_HTML 512 - -/* URL Flags */ -#define URL_IS_IP4 1 -#define URL_IS_IP6 2 -#define URL_IS_EXE 4 - -/* Anomaly Flags */ -#define ANOM_INVALID_BASE64 1 /* invalid base64 chars */ -#define ANOM_INVALID_QP 2 /* invalid qouted-printable chars */ -#define ANOM_LONG_HEADER_NAME 4 /* header is abnormally long */ -#define ANOM_LONG_HEADER_VALUE 8 /* header value is abnormally long - * (includes multi-line) */ -#define ANOM_LONG_LINE 16 /* Lines that exceed 998 octets */ -#define ANOM_LONG_ENC_LINE 32 /* Lines that exceed 76 octets */ -#define ANOM_MALFORMED_MSG 64 /* Misc msg format errors found */ -#define ANOM_LONG_BOUNDARY 128 /* Boundary too long */ - -/* Publicly exposed size constants */ -#define DATA_CHUNK_SIZE 3072 /* Should be divisible by 3 */ -#define LINEREM_SIZE 256 - -/* Mime Parser Constants */ -#define HEADER_READY 0x01 -#define HEADER_STARTED 0x02 -#define HEADER_DONE 0x03 -#define BODY_STARTED 0x04 -#define BODY_DONE 0x05 -#define BODY_END_BOUND 0x06 -#define PARSE_DONE 0x07 -#define PARSE_ERROR 0x08 - -/** - * \brief Mime Decoder Error Codes - */ -typedef enum MimeDecRetCode { - MIME_DEC_OK = 0, - MIME_DEC_MORE = 1, - MIME_DEC_ERR_DATA = -1, - MIME_DEC_ERR_MEM = -2, - MIME_DEC_ERR_PARSE = -3 -} MimeDecRetCode; - -/** - * \brief Structure for containing configuration options - * - */ -typedef struct MimeDecConfig { - int decode_base64; /**< Decode base64 bodies */ - int decode_quoted_printable; /**< Decode quoted-printable bodies */ - int extract_urls; /**< Extract and store URLs in data structure */ - int body_md5; /**< Compute md5 sum of body */ - uint32_t header_value_depth; /**< Depth of which to store header values - (Default is 2000) */ -} MimeDecConfig; - -/** - * \brief This represents a header field name and associated value - */ -typedef struct MimeDecField { - uint8_t *name; /**< Name of the header field */ - uint32_t name_len; /**< Length of the name */ - uint32_t value_len; /**< Length of the value */ - uint8_t *value; /**< Value of the header field */ - struct MimeDecField *next; /**< Pointer to next field */ -} MimeDecField; - -/** - * \brief This represents a URL value node in a linked list - * - * Since HTML can sometimes contain a high number of URLs, this - * structure only features the URL host name/IP or those that are - * pointing to an executable file (see url_flags to determine which). - */ -typedef struct MimeDecUrl { - uint8_t *url; /**< String representation of full or partial URL (lowercase) */ - uint32_t url_len; /**< Length of the URL string */ - uint32_t url_flags; /**< Flags indicating type of URL */ - struct MimeDecUrl *next; /**< Pointer to next URL */ -} MimeDecUrl; - -/** - * \brief This represents the MIME Entity (or also top level message) in a - * child-sibling tree - */ -typedef struct MimeDecEntity { - MimeDecField *field_list; /**< Pointer to list of header fields */ - MimeDecUrl *url_list; /**< Pointer to list of URLs */ - uint32_t body_len; /**< Length of body (prior to any decoding) */ - uint32_t decoded_body_len; /**< Length of body after decoding */ - uint32_t header_flags; /**< Flags indicating header characteristics */ - uint32_t ctnt_flags; /**< Flags indicating type of content */ - uint32_t anomaly_flags; /**< Flags indicating an anomaly in the message */ - uint32_t filename_len; /**< Length of file attachment name */ - uint8_t *filename; /**< Name of file attachment */ - uint8_t *ctnt_type; /**< Quick access pointer to short-hand content type field */ - uint32_t ctnt_type_len; /**< Length of content type field value */ - uint32_t msg_id_len; /**< Quick access pointer to message Id */ - uint8_t *msg_id; /**< Quick access pointer to message Id */ - struct MimeDecEntity *next; /**< Pointer to list of sibling entities */ - struct MimeDecEntity *child; /**< Pointer to list of child entities */ -} MimeDecEntity; - -/** - * \brief Structure contains boundary and entity for the current node (entity) - * in the stack - * - */ -typedef struct MimeDecStackNode { - MimeDecEntity *data; /**< Pointer to the entity data structure */ - uint8_t *bdef; /**< Copy of boundary definition for child entity */ - uint32_t bdef_len; /**< Boundary length for child entity */ - int is_encap; /**< Flag indicating entity is encapsulated in message */ - struct MimeDecStackNode *next; /**< Pointer to next item on the stack */ -} MimeDecStackNode; - -/** - * \brief Structure holds the top of the stack along with some free reusable nodes - * - */ -typedef struct MimeDecStack { - MimeDecStackNode *top; /**< Pointer to the top of the stack */ - MimeDecStackNode *free_nodes; /**< Pointer to the list of free nodes */ - uint32_t free_nodes_cnt; /**< Count of free nodes in the list */ -} MimeDecStack; - -/** - * \brief Structure contains a list of value and lengths for robust data processing - * - */ -typedef struct DataValue { - uint8_t *value; /**< Copy of data value */ - uint32_t value_len; /**< Length of data value */ - struct DataValue *next; /**< Pointer to next value in the list */ -} DataValue; - -/** - * \brief Structure contains the current state of the MIME parser - * - */ -typedef struct MimeDecParseState { - MimeDecEntity *msg; /**< Pointer to the top-level message entity */ - MimeDecStack *stack; /**< Pointer to the top of the entity stack */ - uint8_t *hname; /**< Copy of the last known header name */ - uint32_t hlen; /**< Length of the last known header name */ - uint32_t hvlen; /**< Total length of value list */ - DataValue *hvalue; /**< Pointer to the incomplete header value list */ - uint8_t linerem[LINEREM_SIZE]; /**< Remainder from previous line (for URL extraction) */ - uint16_t linerem_len; /**< Length of remainder from previous line */ - uint8_t bvremain[B64_BLOCK]; /**< Remainder from base64-decoded line */ - uint8_t bvr_len; /**< Length of remainder from base64-decoded line */ - uint8_t data_chunk[DATA_CHUNK_SIZE]; /**< Buffer holding data chunk */ -#ifdef HAVE_NSS - HASHContext *md5_ctx; - uint8_t md5[MD5_LENGTH]; -#endif - uint8_t state_flag; /**< Flag representing current state of parser */ - uint32_t data_chunk_len; /**< Length of data chunk */ - int found_child; /**< Flag indicating a child entity was found */ - int body_begin; /**< Currently at beginning of body */ - int body_end; /**< Currently at end of body */ - uint8_t current_line_delimiter_len; /**< Length of line delimiter */ - void *data; /**< Pointer to data specific to the caller */ - int (*DataChunkProcessorFunc) (const uint8_t *chunk, uint32_t len, - struct MimeDecParseState *state); /**< Data chunk processing function callback */ -} MimeDecParseState; - -/* Config functions */ -void MimeDecSetConfig(MimeDecConfig *config); -MimeDecConfig * MimeDecGetConfig(void); - -/* Memory functions */ -void MimeDecFreeEntity(MimeDecEntity *entity); -void MimeDecFreeField(MimeDecField *field); -void MimeDecFreeUrl(MimeDecUrl *url); - -/* List functions */ -MimeDecField * MimeDecAddField(MimeDecEntity *entity); -MimeDecField * MimeDecFindField(const MimeDecEntity *entity, const char *name); -int MimeDecFindFieldsForEach(const MimeDecEntity *entity, const char *name, int (*DataCallback)(const uint8_t *val, const size_t, void *data), void *data); -MimeDecEntity * MimeDecAddEntity(MimeDecEntity *parent); - -/* Helper functions */ -//MimeDecField * MimeDecFillField(MimeDecEntity *entity, const char *name, -// uint32_t nlen, const char *value, uint32_t vlen, int copy_name_value); - -/* Parser functions */ -MimeDecParseState * MimeDecInitParser(void *data, int (*dcpfunc)(const uint8_t *chunk, - uint32_t len, MimeDecParseState *state)); -void MimeDecDeInitParser(MimeDecParseState *state); -int MimeDecParseComplete(MimeDecParseState *state); -int MimeDecParseLine(const uint8_t *line, const uint32_t len, const uint8_t delim_len, MimeDecParseState *state); -MimeDecEntity * MimeDecParseFullMsg(const uint8_t *buf, uint32_t blen, void *data, - int (*DataChunkProcessorFunc)(const uint8_t *chunk, uint32_t len, MimeDecParseState *state)); -const char *MimeDecParseStateGetStatus(MimeDecParseState *state); - -/* Test functions */ -void MimeDecRegisterTests(void); - -#endif diff --git a/framework/src/suricata/src/util-device.c b/framework/src/suricata/src/util-device.c deleted file mode 100644 index c08e30f0..00000000 --- a/framework/src/suricata/src/util-device.c +++ /dev/null @@ -1,273 +0,0 @@ -/* Copyright (C) 2011-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "suricata-common.h" -#include "conf.h" -#include "util-device.h" - -/** - * \file - * - * \author Eric Leblond - * - * \brief Utility functions to handle device list - */ - -/** private device list */ -static TAILQ_HEAD(, LiveDevice_) live_devices = - TAILQ_HEAD_INITIALIZER(live_devices); - -/** if set to 0 when we don't have real devices */ -static int live_devices_stats = 1; - -/** - * \brief Add a pcap device for monitoring - * - * \param dev string with the device name - * - * \retval 0 on success. - * \retval -1 on failure. - */ -int LiveRegisterDevice(char *dev) -{ - LiveDevice *pd = SCMalloc(sizeof(LiveDevice)); - if (unlikely(pd == NULL)) { - return -1; - } - - pd->dev = SCStrdup(dev); - if (unlikely(pd->dev == NULL)) { - SCFree(pd); - return -1; - } - SC_ATOMIC_INIT(pd->pkts); - SC_ATOMIC_INIT(pd->drop); - SC_ATOMIC_INIT(pd->invalid_checksums); - pd->ignore_checksum = 0; - TAILQ_INSERT_TAIL(&live_devices, pd, next); - - SCLogDebug("Device \"%s\" registered.", dev); - return 0; -} - -/** - * \brief Get the number of registered devices - * - * \retval cnt the number of registered devices - */ -int LiveGetDeviceCount(void) -{ - int i = 0; - LiveDevice *pd; - - TAILQ_FOREACH(pd, &live_devices, next) { - i++; - } - - return i; -} - -/** - * \brief Get a pointer to the device name at idx - * - * \param number idx of the device in our list - * - * \retval ptr pointer to the string containing the device - * \retval NULL on error - */ -char *LiveGetDeviceName(int number) -{ - int i = 0; - LiveDevice *pd; - - TAILQ_FOREACH(pd, &live_devices, next) { - if (i == number) { - return pd->dev; - } - - i++; - } - - return NULL; -} - -/** - * \brief Get a pointer to the device at idx - * - * \param number idx of the device in our list - * - * \retval ptr pointer to the string containing the device - * \retval NULL on error - */ -LiveDevice *LiveGetDevice(char *name) -{ - int i = 0; - LiveDevice *pd; - - if (name == NULL) { - SCLogWarning(SC_ERR_INVALID_VALUE, "Name of device should not be null"); - return NULL; - } - - TAILQ_FOREACH(pd, &live_devices, next) { - if (!strcmp(name, pd->dev)) { - return pd; - } - - i++; - } - - return NULL; -} - - - -int LiveBuildDeviceList(char * runmode) -{ - return LiveBuildDeviceListCustom(runmode, "interface"); -} - -int LiveBuildDeviceListCustom(char * runmode, char * itemname) -{ - ConfNode *base = ConfGetNode(runmode); - ConfNode *child; - int i = 0; - - if (base == NULL) - return 0; - - TAILQ_FOREACH(child, &base->head, next) { - ConfNode *subchild; - TAILQ_FOREACH(subchild, &child->head, next) { - if ((!strcmp(subchild->name, itemname))) { - if (!strcmp(subchild->val, "default")) - break; - SCLogInfo("Adding %s %s from config file", - itemname, subchild->val); - LiveRegisterDevice(subchild->val); - i++; - } - } - } - - return i; -} - -/** Call this function to disable stat on live devices - * - * This can be useful in the case, this is not a real interface. - */ -void LiveDeviceHasNoStats() -{ - live_devices_stats = 0; -} - -int LiveDeviceListClean() -{ - SCEnter(); - LiveDevice *pd, *tpd; - - TAILQ_FOREACH_SAFE(pd, &live_devices, next, tpd) { - if (live_devices_stats) { - SCLogNotice("Stats for '%s': pkts: %" PRIu64", drop: %" PRIu64 " (%.2f%%), invalid chksum: %" PRIu64, - pd->dev, - SC_ATOMIC_GET(pd->pkts), - SC_ATOMIC_GET(pd->drop), - 100 * (SC_ATOMIC_GET(pd->drop) * 1.0) / SC_ATOMIC_GET(pd->pkts), - SC_ATOMIC_GET(pd->invalid_checksums)); - } - if (pd->dev) - SCFree(pd->dev); - SC_ATOMIC_DESTROY(pd->pkts); - SC_ATOMIC_DESTROY(pd->drop); - SC_ATOMIC_DESTROY(pd->invalid_checksums); - SCFree(pd); - } - - SCReturnInt(TM_ECODE_OK); -} - -#ifdef BUILD_UNIX_SOCKET -TmEcode LiveDeviceIfaceStat(json_t *cmd, json_t *answer, void *data) -{ - SCEnter(); - LiveDevice *pd; - const char * name = NULL; - json_t *jarg = json_object_get(cmd, "iface"); - if(!json_is_string(jarg)) { - json_object_set_new(answer, "message", json_string("Iface is not a string")); - SCReturnInt(TM_ECODE_FAILED); - } - name = json_string_value(jarg); - if (name == NULL) { - json_object_set_new(answer, "message", json_string("Iface name is NULL")); - SCReturnInt(TM_ECODE_FAILED); - } - - TAILQ_FOREACH(pd, &live_devices, next) { - if (!strcmp(name, pd->dev)) { - json_t *jdata = json_object(); - if (jdata == NULL) { - json_object_set_new(answer, "message", - json_string("internal error at json object creation")); - SCReturnInt(TM_ECODE_FAILED); - } - json_object_set_new(jdata, "pkts", - json_integer(SC_ATOMIC_GET(pd->pkts))); - json_object_set_new(jdata, "invalid-checksums", - json_integer(SC_ATOMIC_GET(pd->invalid_checksums))); - json_object_set_new(jdata, "drop", - json_integer(SC_ATOMIC_GET(pd->drop))); - json_object_set_new(answer, "message", jdata); - SCReturnInt(TM_ECODE_OK); - } - } - json_object_set_new(answer, "message", json_string("Iface does not exist")); - SCReturnInt(TM_ECODE_FAILED); -} - -TmEcode LiveDeviceIfaceList(json_t *cmd, json_t *answer, void *data) -{ - SCEnter(); - json_t *jdata; - json_t *jarray; - LiveDevice *pd; - int i = 0; - - jdata = json_object(); - if (jdata == NULL) { - json_object_set_new(answer, "message", - json_string("internal error at json object creation")); - return TM_ECODE_FAILED; - } - jarray = json_array(); - if (jarray == NULL) { - json_object_set_new(answer, "message", - json_string("internal error at json object creation")); - return TM_ECODE_FAILED; - } - TAILQ_FOREACH(pd, &live_devices, next) { - json_array_append(jarray, json_string(pd->dev)); - i++; - } - - json_object_set_new(jdata, "count", json_integer(i)); - json_object_set_new(jdata, "ifaces", jarray); - json_object_set_new(answer, "message", jdata); - SCReturnInt(TM_ECODE_OK); -} -#endif /* BUILD_UNIX_SOCKET */ diff --git a/framework/src/suricata/src/util-device.h b/framework/src/suricata/src/util-device.h deleted file mode 100644 index fd6a8213..00000000 --- a/framework/src/suricata/src/util-device.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 2011-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __UTIL_DEVICE_H__ -#define __UTIL_DEVICE_H__ - -#include "queue.h" -#include "unix-manager.h" - -/** storage for live device names */ -typedef struct LiveDevice_ { - char *dev; /**< the device (e.g. "eth0") */ - int ignore_checksum; - SC_ATOMIC_DECLARE(uint64_t, pkts); - SC_ATOMIC_DECLARE(uint64_t, drop); - SC_ATOMIC_DECLARE(uint64_t, invalid_checksums); - TAILQ_ENTRY(LiveDevice_) next; -} LiveDevice; - - -int LiveRegisterDevice(char *dev); -int LiveGetDeviceCount(void); -char *LiveGetDeviceName(int number); -LiveDevice *LiveGetDevice(char *dev); -int LiveBuildDeviceList(char * base); -void LiveDeviceHasNoStats(void); -int LiveDeviceListClean(void); -int LiveBuildDeviceListCustom(char * base, char * itemname); - -#ifdef BUILD_UNIX_SOCKET -TmEcode LiveDeviceIfaceStat(json_t *cmd, json_t *server_msg, void *data); -TmEcode LiveDeviceIfaceList(json_t *cmd, json_t *server_msg, void *data); -#endif - -#endif /* __UTIL_DEVICE_H__ */ diff --git a/framework/src/suricata/src/util-enum.c b/framework/src/suricata/src/util-enum.c deleted file mode 100644 index 97ee86f9..00000000 --- a/framework/src/suricata/src/util-enum.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include -#include - -#include "util-enum.h" - -/** - * \brief Maps a string name to an enum value from the supplied table. Please - * specify the last element of any map table with a {NULL, -1}. If - * missing, you will be welcomed with a segfault :) - * - * \param enum_name Character string that has to be mapped to an enum value - * from the table - * \param table Enum-Char table, from which the mapping is retrieved - * - * \retval result The enum_value for the enum_name string or -1 on failure - */ -int SCMapEnumNameToValue(const char *enum_name, SCEnumCharMap *table) -{ - int result = -1; - - if (enum_name == NULL || table == NULL) { - printf("Invalid argument(s) passed into SCMapEnumNameToValue\n"); - return -1; - } - - for (; table->enum_name != NULL; table++) { - if (strcasecmp(table->enum_name, enum_name) == 0) { - result = table->enum_value; - break; - } - } - - return result; -} - -/** - * \brief Maps an enum value to a string name, from the supplied table - * - * \param enum_value Enum_value that has to be mapped to a string_value - * from the table - * \param table Enum-Char table, from which the mapping is retrieved - * - * \retval result The enum_name for the enum_value supplied or NULL on failure - */ -const char * SCMapEnumValueToName(int enum_value, SCEnumCharMap *table) -{ - if (table == NULL) { - printf("Invalid argument(s) passed into SCMapEnumValueToName\n"); - return NULL; - } - - for (; table->enum_name != NULL; table++) { - if (table->enum_value == enum_value) { - return table->enum_name; - } - } - - printf("A enum by the value %d doesn't exist in this table\n", enum_value); - - return NULL; -} diff --git a/framework/src/suricata/src/util-enum.h b/framework/src/suricata/src/util-enum.h deleted file mode 100644 index ee555e99..00000000 --- a/framework/src/suricata/src/util-enum.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_ENUM_H__ -#define __UTIL_ENUM_H__ - -typedef struct SCEnumCharMap_ { - char *enum_name; - int enum_value; -} SCEnumCharMap; - -int SCMapEnumNameToValue(const char *, SCEnumCharMap *); - -const char * SCMapEnumValueToName(int, SCEnumCharMap *); - -#endif /* __UTIL_ENUM_H__ */ diff --git a/framework/src/suricata/src/util-error.c b/framework/src/suricata/src/util-error.c deleted file mode 100644 index 7f2caf00..00000000 --- a/framework/src/suricata/src/util-error.c +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Error utility functions - * - * \todo Needs refining of the error codes. Renaming with a prefix of SC_ERR, - * removal of duplicates and entries have to be made in util-error.c - */ - -#include "util-error.h" - -#define CASE_CODE(E) case E: return #E - -/** - * \brief Maps the error code, to its string equivalent - * - * \param The error code - * - * \retval The string equivalent for the error code - */ -const char * SCErrorToString(SCError err) -{ - switch (err) { - CASE_CODE (SC_OK); - CASE_CODE (SC_ERR_MEM_ALLOC); - CASE_CODE (SC_ERR_ACTION_ORDER); - CASE_CODE (SC_ERR_PCRE_MATCH); - CASE_CODE (SC_ERR_PCRE_GET_SUBSTRING); - CASE_CODE (SC_ERR_PCRE_COMPILE); - CASE_CODE (SC_ERR_PCRE_STUDY); - CASE_CODE (SC_ERR_PCRE_PARSE); - CASE_CODE (SC_ERR_LOG_MODULE_NOT_INIT); - CASE_CODE (SC_ERR_LOG_FG_FILTER_MATCH); - CASE_CODE (SC_ERR_PCAP_DISPATCH); - CASE_CODE (SC_ERR_PCAP_CREATE); - CASE_CODE (SC_ERR_PCAP_SET_SNAPLEN); - CASE_CODE (SC_ERR_PCAP_SET_PROMISC); - CASE_CODE (SC_ERR_PCAP_SET_TIMEOUT); - CASE_CODE (SC_ERR_PCAP_OPEN_LIVE); - CASE_CODE (SC_ERR_PCAP_OPEN_OFFLINE); - CASE_CODE (SC_ERR_PCAP_ACTIVATE_HANDLE); - CASE_CODE (SC_ERR_PCAP_SET_BUFF_SIZE); - CASE_CODE (SC_ERR_NO_PCAP_SET_BUFFER_SIZE); - CASE_CODE (SC_ERR_NO_PF_RING); - CASE_CODE (SC_ERR_PF_RING_RECV); - CASE_CODE (SC_ERR_PF_RING_GET_CLUSTERID_FAILED); - CASE_CODE (SC_ERR_PF_RING_GET_INTERFACE_FAILED); - CASE_CODE (SC_ERR_PF_RING_OPEN); - CASE_CODE (SC_ERR_GET_CLUSTER_TYPE_FAILED); - CASE_CODE (SC_ERR_INVALID_CLUSTER_TYPE); - CASE_CODE (SC_ERR_PF_RING_SET_CLUSTER_FAILED); - CASE_CODE (SC_ERR_DATALINK_UNIMPLEMENTED); - CASE_CODE (SC_ERR_INVALID_SIGNATURE); - CASE_CODE (SC_ERR_OPENING_FILE); - CASE_CODE (SC_ERR_OPENING_RULE_FILE); - CASE_CODE (SC_ERR_NO_RULES); - CASE_CODE (SC_ERR_NO_RULES_LOADED); - CASE_CODE (SC_ERR_COUNTER_EXCEEDED); - CASE_CODE (SC_ERR_INVALID_CHECKSUM); - CASE_CODE (SC_ERR_SPRINTF); - CASE_CODE (SC_ERR_FATAL); - CASE_CODE (SC_ERR_INVALID_ARGUMENT); - CASE_CODE (SC_ERR_SPINLOCK); - CASE_CODE (SC_ERR_INVALID_ENUM_MAP); - CASE_CODE (SC_ERR_INVALID_IP_NETBLOCK); - CASE_CODE (SC_ERR_INVALID_IPV4_ADDR); - CASE_CODE (SC_ERR_INVALID_IPV6_ADDR); - CASE_CODE (SC_ERR_INVALID_RUNMODE); - CASE_CODE (SC_ERR_COMPLETE_PORT_SPACE_NEGATED); - CASE_CODE (SC_ERR_NO_PORTS_LEFT_AFTER_MERGE); - CASE_CODE (SC_ERR_NEGATED_VALUE_IN_PORT_RANGE); - CASE_CODE (SC_ERR_PORT_PARSE_INSERT_STRING); - CASE_CODE (SC_ERR_UNREACHABLE_CODE_REACHED); - CASE_CODE (SC_ERR_INVALID_NUMERIC_VALUE); - CASE_CODE (SC_ERR_NUMERIC_VALUE_ERANGE); - CASE_CODE (SC_ERR_INVALID_NUM_BYTES); - CASE_CODE (SC_ERR_ARG_LEN_LONG); - CASE_CODE (SC_ERR_ALPARSER); - CASE_CODE (SC_ERR_POOL_EMPTY); - CASE_CODE (SC_ERR_REASSEMBLY); - CASE_CODE (SC_ERR_POOL_INIT); - CASE_CODE (SC_ERR_UNIMPLEMENTED); - CASE_CODE (SC_ERR_ADDRESS_ENGINE_GENERIC); - CASE_CODE (SC_ERR_PORT_ENGINE_GENERIC); - CASE_CODE (SC_ERR_FAST_LOG_GENERIC); - CASE_CODE (SC_ERR_IPONLY_RADIX); - CASE_CODE (SC_ERR_DEBUG_LOG_GENERIC); - CASE_CODE (SC_ERR_UNIFIED_LOG_GENERIC); - CASE_CODE (SC_ERR_HTTP_LOG_GENERIC); - CASE_CODE (SC_ERR_UNIFIED_ALERT_GENERIC); - CASE_CODE (SC_ERR_UNIFIED2_ALERT_GENERIC); - CASE_CODE (SC_ERR_FWRITE); - CASE_CODE (SC_ERR_FOPEN); - CASE_CODE (SC_ERR_THREAD_NICE_PRIO); - CASE_CODE (SC_ERR_THREAD_SPAWN); - CASE_CODE (SC_ERR_THREAD_CREATE); - CASE_CODE (SC_ERR_THREAD_INIT); - CASE_CODE (SC_ERR_THREAD_DEINIT); - CASE_CODE (SC_ERR_THRESHOLD_HASH_ADD); - CASE_CODE (SC_ERR_UNDEFINED_VAR); - CASE_CODE (SC_ERR_RULE_KEYWORD_UNKNOWN); - CASE_CODE (SC_ERR_FLAGS_MODIFIER); - CASE_CODE (SC_ERR_DISTANCE_MISSING_CONTENT); - CASE_CODE (SC_ERR_BYTETEST_MISSING_CONTENT); - CASE_CODE (SC_ERR_BYTEJUMP_MISSING_CONTENT); - CASE_CODE (SC_ERR_WITHIN_MISSING_CONTENT); - CASE_CODE (SC_ERR_WITHIN_INVALID); - CASE_CODE (SC_ERR_DEPTH_MISSING_CONTENT); - CASE_CODE (SC_ERR_OFFSET_MISSING_CONTENT); - CASE_CODE (SC_ERR_NOCASE_MISSING_PATTERN); - CASE_CODE (SC_ERR_RAWBYTES_MISSING_CONTENT); - CASE_CODE (SC_ERR_NO_URICONTENT_NEGATION); - CASE_CODE (SC_ERR_HASH_TABLE_INIT); - CASE_CODE (SC_ERR_STAT); - CASE_CODE (SC_ERR_LOGDIR_CONFIG); - CASE_CODE (SC_ERR_LOGDIR_CMDLINE); - CASE_CODE (SC_ERR_RADIX_TREE_GENERIC); - CASE_CODE (SC_ERR_MISSING_QUOTE); - CASE_CODE (SC_ERR_UNKNOWN_PROTOCOL); - CASE_CODE (SC_ERR_UNKNOWN_RUN_MODE); - CASE_CODE (SC_ERR_IPFW_NOSUPPORT); - CASE_CODE (SC_ERR_IPFW_BIND); - CASE_CODE (SC_ERR_IPFW_SOCK); - CASE_CODE (SC_ERR_IPFW_SETSOCKOPT); - CASE_CODE (SC_ERR_IPFW_NOPORT); - CASE_CODE (SC_WARN_IPFW_RECV); - CASE_CODE (SC_WARN_IPFW_XMIT); - CASE_CODE (SC_WARN_IPFW_SETSOCKOPT); - CASE_CODE (SC_WARN_IPFW_UNBIND); - CASE_CODE (SC_ERR_MULTIPLE_RUN_MODE); - CASE_CODE (SC_ERR_BPF); - CASE_CODE (SC_ERR_MISSING_CONFIG_PARAM); - CASE_CODE (SC_ERR_UNKNOWN_VALUE); - CASE_CODE (SC_ERR_INVALID_VALUE); - CASE_CODE (SC_ERR_UNKNOWN_REGEX_MOD); - CASE_CODE (SC_ERR_INVALID_OPERATOR); - CASE_CODE (SC_ERR_PCAP_RECV_INIT); - CASE_CODE (SC_ERR_NFQ_NOSUPPORT); - CASE_CODE (SC_ERR_NFQ_UNBIND); - CASE_CODE (SC_ERR_NFQ_BIND); - CASE_CODE (SC_ERR_NFQ_HANDLE_PKT); - CASE_CODE (SC_ERR_NFLOG_NOSUPPORT); - CASE_CODE (SC_ERR_NFLOG_OPEN); - CASE_CODE (SC_ERR_NFLOG_BIND); - CASE_CODE (SC_ERR_NFLOG_UNBIND); - CASE_CODE (SC_ERR_NFLOG_MAX_BUFSIZ); - CASE_CODE (SC_ERR_NFLOG_SET_MODE); - CASE_CODE (SC_ERR_NFLOG_HANDLE_PKT); - CASE_CODE (SC_ERR_NFLOG_GROUP); - CASE_CODE (SC_ERR_NFLOG_FD); - CASE_CODE (SC_WARN_NFLOG_SETSOCKOPT); - CASE_CODE (SC_WARN_NFLOG_RECV); - CASE_CODE (SC_WARN_NFLOG_LOSING_EVENTS); - CASE_CODE (SC_WARN_NFLOG_MAXBUFSIZ_REACHED); - CASE_CODE (SC_ERR_CUDA_ERROR); - CASE_CODE (SC_ERR_CUDA_HANDLER_ERROR); - CASE_CODE (SC_ERR_TM_THREADS_ERROR); - CASE_CODE (SC_ERR_TM_MODULES_ERROR); - CASE_CODE (SC_ERR_AC_CUDA_ERROR); - CASE_CODE (SC_ERR_INVALID_YAML_CONF_ENTRY); - CASE_CODE (SC_ERR_TMQ_ALREADY_REGISTERED); - CASE_CODE (SC_ERR_CONFLICTING_RULE_KEYWORDS); - CASE_CODE (SC_ERR_INITIALIZATION); - CASE_CODE (SC_ERR_INVALID_ACTION); - CASE_CODE (SC_ERR_LIBNET_REQUIRED_FOR_ACTION); - CASE_CODE (SC_ERR_LIBNET_INIT); - CASE_CODE (SC_ERR_LIBNET_INVALID_DIR); - CASE_CODE (SC_ERR_LIBNET_BUILD_FAILED); - CASE_CODE (SC_ERR_LIBNET_WRITE_FAILED); - CASE_CODE (SC_ERR_LIBNET_NOT_ENABLED); - CASE_CODE (SC_ERR_UNIFIED_LOG_FILE_HEADER); - CASE_CODE (SC_ERR_REFERENCE_UNKNOWN); - CASE_CODE (SC_ERR_PIDFILE_SNPRINTF); - CASE_CODE (SC_ERR_PIDFILE_OPEN); - CASE_CODE (SC_ERR_PIDFILE_WRITE); - CASE_CODE (SC_ERR_PIDFILE_DAEMON); - CASE_CODE (SC_ERR_UID_FAILED); - CASE_CODE (SC_ERR_GID_FAILED); - CASE_CODE (SC_ERR_CHANGING_CAPS_FAILED); - CASE_CODE (SC_ERR_LIBCAP_NG_REQUIRED); - CASE_CODE (SC_ERR_LIBNET11_INCOMPATIBLE_WITH_LIBCAP_NG); - CASE_CODE (SC_WARN_FLOW_EMERGENCY); - CASE_CODE (SC_ERR_SVC); - CASE_CODE (SC_ERR_ERF_DAG_OPEN_FAILED); - CASE_CODE (SC_ERR_ERF_DAG_STREAM_OPEN_FAILED); - CASE_CODE (SC_ERR_ERF_DAG_STREAM_START_FAILED); - CASE_CODE (SC_ERR_ERF_DAG_STREAM_SET_FAILED); - CASE_CODE (SC_ERR_ERF_DAG_STREAM_READ_FAILED); - CASE_CODE (SC_WARN_ERF_DAG_REC_LEN_CHANGED); - CASE_CODE (SC_ERR_NAPATECH_OPEN_FAILED); - CASE_CODE (SC_ERR_NAPATECH_STREAM_NEXT_FAILED); - CASE_CODE (SC_ERR_NAPATECH_NOSUPPORT); - CASE_CODE (SC_ERR_NAPATECH_REQUIRED); - CASE_CODE (SC_ERR_NAPATECH_TIMESTAMP_TYPE_NOT_SUPPORTED); - CASE_CODE (SC_ERR_NAPATECH_INIT_FAILED); - CASE_CODE (SC_ERR_NAPATECH_CONFIG_STREAM); - CASE_CODE (SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED); - CASE_CODE (SC_ERR_NAPATECH_STAT_DROPS_FAILED); - CASE_CODE (SC_ERR_NAPATECH_PARSE_CONFIG); - CASE_CODE (SC_WARN_COMPATIBILITY); - CASE_CODE (SC_ERR_DCERPC); - CASE_CODE (SC_ERR_DETECT_PREPARE); - CASE_CODE (SC_ERR_AHO_CORASICK); - CASE_CODE (SC_ERR_REFERENCE_CONFIG); - CASE_CODE (SC_ERR_DUPLICATE_SIG); - CASE_CODE (SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL); - CASE_CODE (SC_ERR_PCAP_MULTI_DEV_NO_SUPPORT); - CASE_CODE (SC_ERR_HTTP_METHOD_NEEDS_PRECEEDING_CONTENT); - CASE_CODE (SC_ERR_HTTP_METHOD_INCOMPATIBLE_WITH_RAWBYTES); - CASE_CODE (SC_ERR_HTTP_METHOD_RELATIVE_MISSING); - CASE_CODE (SC_ERR_HTTP_COOKIE_NEEDS_PRECEEDING_CONTENT); - CASE_CODE (SC_ERR_HTTP_COOKIE_INCOMPATIBLE_WITH_RAWBYTES); - CASE_CODE (SC_ERR_HTTP_COOKIE_RELATIVE_MISSING); - CASE_CODE (SC_ERR_LOGPCAP_SGUIL_BASE_DIR_MISSING); - CASE_CODE (SC_ERR_UNKNOWN_DECODE_EVENT); - CASE_CODE (SC_ERR_RUNMODE); - CASE_CODE (SC_ERR_SHUTDOWN); - CASE_CODE (SC_ERR_INVALID_DIRECTION); - CASE_CODE (SC_ERR_AFP_CREATE); - CASE_CODE (SC_ERR_AFP_READ); - CASE_CODE (SC_ERR_AFP_DISPATCH); - CASE_CODE (SC_ERR_CMD_LINE); - CASE_CODE (SC_ERR_SIZE_PARSE); - CASE_CODE (SC_ERR_RAWBYTES_FILE_DATA); - CASE_CODE (SC_ERR_SOCKET); - CASE_CODE (SC_ERR_PCAP_TRANSLATE); - CASE_CODE (SC_WARN_OUTDATED_LIBHTP); - CASE_CODE (SC_WARN_DEPRECATED); - CASE_CODE (SC_WARN_PROFILE); - CASE_CODE (SC_ERR_FLOW_INIT); - CASE_CODE (SC_ERR_HOST_INIT); - CASE_CODE (SC_ERR_MEM_BUFFER_API); - CASE_CODE (SC_ERR_INVALID_MD5); - CASE_CODE (SC_ERR_NO_MD5_SUPPORT); - CASE_CODE (SC_ERR_EVENT_ENGINE); - CASE_CODE (SC_ERR_NO_LUA_SUPPORT); - CASE_CODE (SC_ERR_LUA_ERROR); - CASE_CODE (SC_ERR_NO_GEOIP_SUPPORT); - CASE_CODE (SC_ERR_GEOIP_ERROR); - CASE_CODE (SC_ERR_DEFRAG_INIT); - CASE_CODE (SC_ERR_NO_REPUTATION); - CASE_CODE (SC_ERR_NOT_SUPPORTED); - CASE_CODE (SC_ERR_LIVE_RULE_SWAP); - CASE_CODE (SC_WARN_UNCOMMON); - CASE_CODE (SC_ERR_SYSCALL); - CASE_CODE (SC_ERR_SYSCONF); - CASE_CODE (SC_ERR_INVALID_ARGUMENTS); - CASE_CODE (SC_ERR_STATS_NOT_INIT); - CASE_CODE (SC_ERR_NFQ_OPEN); - CASE_CODE (SC_ERR_NFQ_MAXLEN); - CASE_CODE (SC_ERR_NFQ_CREATE_QUEUE); - CASE_CODE (SC_ERR_NFQ_SET_MODE); - CASE_CODE (SC_ERR_NFQ_SETSOCKOPT); - CASE_CODE (SC_ERR_NFQ_RECV); - CASE_CODE (SC_ERR_NFQ_SET_VERDICT); - CASE_CODE (SC_ERR_NFQ_THREAD_INIT); - CASE_CODE (SC_ERR_DAEMON); - CASE_CODE (SC_ERR_TLS_LOG_GENERIC); - CASE_CODE (SC_ERR_MUTEX); - CASE_CODE (SC_ERR_REPUTATION_INVALID_OPERATION); - CASE_CODE (SC_ERR_REPUTATION_INVALID_TYPE); - CASE_CODE (SC_ERR_BYTE_EXTRACT_FAILED); - CASE_CODE (SC_ERR_DAG_REQUIRED); - CASE_CODE (SC_ERR_DAG_NOSUPPORT); - CASE_CODE (SC_ERR_NO_AF_PACKET); - CASE_CODE (SC_ERR_PCAP_FILE_DELETE_FAILED); - CASE_CODE (SC_ERR_MAGIC_OPEN); - CASE_CODE (SC_ERR_MAGIC_LOAD); - CASE_CODE (SC_ERR_CUDA_BUFFER_ERROR); - CASE_CODE (SC_ERR_DNS_LOG_GENERIC); - CASE_CODE (SC_WARN_OPTION_OBSOLETE); - CASE_CODE (SC_WARN_NO_UNITTESTS); - CASE_CODE (SC_ERR_THREAD_QUEUE); - CASE_CODE (SC_WARN_XFF_INVALID_MODE); - CASE_CODE (SC_WARN_XFF_INVALID_HEADER); - CASE_CODE (SC_WARN_XFF_INVALID_DEPLOYMENT); - CASE_CODE (SC_ERR_THRESHOLD_SETUP); - CASE_CODE (SC_ERR_DNS_CONFIG); - CASE_CODE (SC_ERR_MODBUS_CONFIG); - CASE_CODE (SC_ERR_CONF_YAML_ERROR); - CASE_CODE (SC_ERR_CONF_NAME_TOO_LONG); - CASE_CODE (SC_ERR_APP_LAYER_PROTOCOL_DETECTION); - CASE_CODE (SC_ERR_PCIE_INIT_FAILED); - CASE_CODE (SC_WARN_LUA_SCRIPT); - CASE_CODE (SC_ERR_LUA_SCRIPT); - CASE_CODE (SC_WARN_NO_STATS_LOGGERS); - CASE_CODE (SC_ERR_NO_NETMAP); - CASE_CODE (SC_ERR_NETMAP_CREATE); - CASE_CODE (SC_ERR_NETMAP_READ); - CASE_CODE (SC_ERR_IPPAIR_INIT); - CASE_CODE (SC_ERR_MT_NO_SELECTOR); - CASE_CODE (SC_ERR_MT_DUPLICATE_TENANT); - CASE_CODE (SC_ERR_MT_NO_MAPPING); - CASE_CODE (SC_ERR_NO_JSON_SUPPORT); - CASE_CODE (SC_ERR_INVALID_RULE_ARGUMENT); - } - - return "UNKNOWN_ERROR"; -} diff --git a/framework/src/suricata/src/util-error.h b/framework/src/suricata/src/util-error.h deleted file mode 100644 index cd2ce249..00000000 --- a/framework/src/suricata/src/util-error.h +++ /dev/null @@ -1,310 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __ERROR_H__ -#define __ERROR_H__ - - -/* different error types */ -typedef enum { - SC_OK, - SC_ERR_MEM_ALLOC, - SC_ERR_PCRE_MATCH, - SC_ERR_ACTION_ORDER, - SC_ERR_PCRE_GET_SUBSTRING, - SC_ERR_PCRE_COMPILE, - SC_ERR_PCRE_STUDY, - SC_ERR_PCRE_PARSE, - SC_ERR_LOG_MODULE_NOT_INIT, - SC_ERR_LOG_FG_FILTER_MATCH, - SC_ERR_COUNTER_EXCEEDED, - SC_ERR_INVALID_CHECKSUM, - SC_ERR_SPRINTF, - SC_ERR_INVALID_ARGUMENT, - SC_ERR_SPINLOCK, - SC_ERR_INVALID_ENUM_MAP, - SC_ERR_INVALID_IP_NETBLOCK, - SC_ERR_INVALID_IPV4_ADDR, - SC_ERR_INVALID_IPV6_ADDR, - SC_ERR_INVALID_RUNMODE, - SC_ERR_PCAP_DISPATCH, - SC_ERR_PCAP_CREATE, - SC_ERR_PCAP_SET_SNAPLEN, - SC_ERR_PCAP_SET_PROMISC, - SC_ERR_PCAP_SET_TIMEOUT, - SC_ERR_PCAP_OPEN_LIVE, - SC_ERR_PCAP_OPEN_OFFLINE, - SC_ERR_PCAP_ACTIVATE_HANDLE, - SC_ERR_PCAP_SET_BUFF_SIZE, - SC_ERR_NO_PCAP_SET_BUFFER_SIZE, - SC_ERR_NO_PF_RING, - SC_ERR_PF_RING_RECV, - SC_ERR_PF_RING_GET_CLUSTERID_FAILED, - SC_ERR_PF_RING_GET_INTERFACE_FAILED, - SC_ERR_PF_RING_OPEN, - SC_ERR_GET_CLUSTER_TYPE_FAILED, - SC_ERR_INVALID_CLUSTER_TYPE, - SC_ERR_PF_RING_SET_CLUSTER_FAILED, - SC_ERR_DATALINK_UNIMPLEMENTED, - SC_ERR_INVALID_SIGNATURE, - SC_ERR_OPENING_FILE, - SC_ERR_OPENING_RULE_FILE, - SC_ERR_NO_RULES, - SC_ERR_NO_RULES_LOADED, - SC_ERR_FOPEN, - SC_ERR_INITIALIZATION, - SC_ERR_THREAD_SPAWN, - SC_ERR_THREAD_NICE_PRIO, - SC_ERR_THREAD_CREATE, - SC_ERR_THREAD_INIT, /**< thread's initialization function failed */ - SC_ERR_SYSCALL, - SC_ERR_SYSCONF, - SC_ERR_INVALID_ARGUMENTS, - SC_ERR_STATS_NOT_INIT, - SC_ERR_COMPLETE_PORT_SPACE_NEGATED, - SC_ERR_NO_PORTS_LEFT_AFTER_MERGE, - SC_ERR_NEGATED_VALUE_IN_PORT_RANGE, - SC_ERR_PORT_PARSE_INSERT_STRING, - SC_ERR_UNREACHABLE_CODE_REACHED, - SC_ERR_ALPARSER, - SC_ERR_INVALID_NUMERIC_VALUE, - SC_ERR_NUMERIC_VALUE_ERANGE, - SC_ERR_INVALID_NUM_BYTES, - SC_ERR_ARG_LEN_LONG, - SC_ERR_POOL_EMPTY, - SC_ERR_REASSEMBLY, - SC_ERR_POOL_INIT, - SC_ERR_NFQ_NOSUPPORT, - SC_ERR_NFQ_OPEN, - SC_ERR_NFQ_BIND, - SC_ERR_NFQ_UNBIND, - SC_ERR_NFQ_MAXLEN, - SC_ERR_NFQ_CREATE_QUEUE, - SC_ERR_NFQ_SET_MODE, - SC_ERR_NFQ_SETSOCKOPT, - SC_ERR_NFQ_RECV, - SC_ERR_NFQ_HANDLE_PKT, - SC_ERR_NFQ_SET_VERDICT, - SC_ERR_NFQ_THREAD_INIT, - SC_ERR_IPFW_NOSUPPORT, - SC_ERR_IPFW_BIND, - SC_ERR_IPFW_SOCK, - SC_ERR_IPFW_NOPORT, - SC_WARN_IPFW_RECV, - SC_WARN_IPFW_XMIT, - SC_WARN_IPFW_SETSOCKOPT, - SC_WARN_IPFW_UNBIND, - SC_ERR_DAEMON, - SC_ERR_UNIMPLEMENTED, - SC_ERR_ADDRESS_ENGINE_GENERIC, - SC_ERR_PORT_ENGINE_GENERIC, - SC_ERR_IPONLY_RADIX, - SC_ERR_FAST_LOG_GENERIC, - SC_ERR_DEBUG_LOG_GENERIC, - SC_ERR_UNIFIED_LOG_GENERIC, - SC_ERR_HTTP_LOG_GENERIC, - SC_ERR_TLS_LOG_GENERIC, - SC_ERR_UNIFIED_ALERT_GENERIC, - SC_ERR_UNIFIED2_ALERT_GENERIC, - SC_ERR_FWRITE, - SC_ERR_THRESHOLD_HASH_ADD, - SC_ERR_UNDEFINED_VAR, - SC_ERR_RULE_KEYWORD_UNKNOWN, - SC_ERR_FLAGS_MODIFIER, - SC_ERR_DISTANCE_MISSING_CONTENT, - SC_ERR_WITHIN_MISSING_CONTENT, - SC_ERR_WITHIN_INVALID, - SC_ERR_OFFSET_MISSING_CONTENT, - SC_ERR_DEPTH_MISSING_CONTENT, - SC_ERR_BYTETEST_MISSING_CONTENT, - SC_ERR_BYTEJUMP_MISSING_CONTENT, - SC_ERR_NOCASE_MISSING_PATTERN, - SC_ERR_RAWBYTES_MISSING_CONTENT, - SC_ERR_NO_URICONTENT_NEGATION, - SC_ERR_HASH_TABLE_INIT, - SC_ERR_STAT, - SC_ERR_LOGDIR_CONFIG, - SC_ERR_LOGDIR_CMDLINE, - SC_ERR_MISSING_CONFIG_PARAM, - SC_ERR_RADIX_TREE_GENERIC, - SC_ERR_MISSING_QUOTE, - SC_ERR_MUTEX, - SC_ERR_REPUTATION_INVALID_OPERATION, - SC_ERR_REPUTATION_INVALID_TYPE, - SC_ERR_UNKNOWN_PROTOCOL, /**< signature contains invalid protocol */ - SC_ERR_UNKNOWN_RUN_MODE, - SC_ERR_MULTIPLE_RUN_MODE, - SC_ERR_BPF, - SC_ERR_BYTE_EXTRACT_FAILED, - SC_ERR_UNKNOWN_VALUE, - SC_ERR_INVALID_VALUE, - SC_ERR_UNKNOWN_REGEX_MOD, - SC_ERR_INVALID_OPERATOR, - SC_ERR_PCAP_RECV_INIT, - SC_ERR_CUDA_ERROR, - SC_ERR_CUDA_HANDLER_ERROR, - SC_ERR_TM_THREADS_ERROR, - SC_ERR_TM_MODULES_ERROR, - SC_ERR_AC_CUDA_ERROR, - SC_ERR_INVALID_YAML_CONF_ENTRY, - SC_ERR_TMQ_ALREADY_REGISTERED, - SC_ERR_CONFLICTING_RULE_KEYWORDS, - SC_ERR_INVALID_ACTION, - SC_ERR_LIBNET_REQUIRED_FOR_ACTION, - SC_ERR_LIBNET_INIT, - SC_ERR_LIBNET_INVALID_DIR, - SC_ERR_LIBNET_BUILD_FAILED, - SC_ERR_LIBNET_WRITE_FAILED, - SC_ERR_LIBNET_NOT_ENABLED, - SC_ERR_UNIFIED_LOG_FILE_HEADER, /**< Error to indicate the unified file - header writing function has been - failed */ - SC_ERR_REFERENCE_UNKNOWN, /**< unknown reference key (cve, url, etc) */ - SC_ERR_PIDFILE_SNPRINTF, - SC_ERR_PIDFILE_OPEN, - SC_ERR_PIDFILE_WRITE, - SC_ERR_PIDFILE_DAEMON, - SC_ERR_UID_FAILED, - SC_ERR_GID_FAILED, - SC_ERR_CHANGING_CAPS_FAILED, - SC_ERR_LIBCAP_NG_REQUIRED, - SC_ERR_LIBNET11_INCOMPATIBLE_WITH_LIBCAP_NG, - SC_WARN_FLOW_EMERGENCY, - SC_WARN_COMPATIBILITY, - SC_ERR_SVC, - SC_ERR_ERF_DAG_OPEN_FAILED, - SC_ERR_ERF_DAG_STREAM_OPEN_FAILED, - SC_ERR_ERF_DAG_STREAM_START_FAILED, - SC_ERR_ERF_DAG_STREAM_SET_FAILED, - SC_ERR_ERF_DAG_STREAM_READ_FAILED, - SC_WARN_ERF_DAG_REC_LEN_CHANGED, - SC_ERR_DAG_REQUIRED, - SC_ERR_DAG_NOSUPPORT, /**< no ERF/DAG support compiled in */ - SC_ERR_FATAL, - SC_ERR_DCERPC, - SC_ERR_DETECT_PREPARE, /**< preparing the detection engine failed */ - SC_ERR_AHO_CORASICK, - SC_ERR_REFERENCE_CONFIG, - SC_ERR_DUPLICATE_SIG, /**< Error to indicate that signature is duplicate */ - SC_WARN_PCAP_MULTI_DEV_EXPERIMENTAL, - SC_ERR_PCAP_MULTI_DEV_NO_SUPPORT, - SC_ERR_HTTP_METHOD_NEEDS_PRECEEDING_CONTENT, - SC_ERR_HTTP_METHOD_INCOMPATIBLE_WITH_RAWBYTES, - SC_ERR_HTTP_METHOD_RELATIVE_MISSING, - SC_ERR_HTTP_COOKIE_NEEDS_PRECEEDING_CONTENT, - SC_ERR_HTTP_COOKIE_INCOMPATIBLE_WITH_RAWBYTES, - SC_ERR_HTTP_COOKIE_RELATIVE_MISSING, - SC_ERR_LOGPCAP_SGUIL_BASE_DIR_MISSING, - SC_ERR_UNKNOWN_DECODE_EVENT, - SC_ERR_RUNMODE, - SC_ERR_SHUTDOWN, - SC_ERR_INVALID_DIRECTION, - SC_ERR_AFP_CREATE, - SC_ERR_AFP_READ, - SC_ERR_AFP_DISPATCH, - SC_ERR_NO_AF_PACKET, - SC_ERR_PCAP_FILE_DELETE_FAILED, - SC_ERR_CMD_LINE, - SC_ERR_MAGIC_OPEN, - SC_ERR_MAGIC_LOAD, - SC_ERR_SIZE_PARSE, - SC_ERR_RAWBYTES_FILE_DATA, - SC_ERR_SOCKET, - SC_ERR_PCAP_TRANSLATE, /* failed to translate ip to dev */ - SC_WARN_OUTDATED_LIBHTP, - SC_WARN_DEPRECATED, - SC_WARN_PROFILE, - SC_ERR_FLOW_INIT, - SC_ERR_HOST_INIT, - SC_ERR_MEM_BUFFER_API, - SC_ERR_INVALID_MD5, - SC_ERR_NO_MD5_SUPPORT, - SC_ERR_EVENT_ENGINE, - SC_ERR_NO_LUA_SUPPORT, - SC_ERR_LUA_ERROR, - SC_ERR_DEFRAG_INIT, - SC_ERR_NAPATECH_OPEN_FAILED, - SC_ERR_NAPATECH_STREAM_NEXT_FAILED, - SC_ERR_NAPATECH_NOSUPPORT, - SC_ERR_NAPATECH_REQUIRED, - SC_ERR_NAPATECH_TIMESTAMP_TYPE_NOT_SUPPORTED, - SC_ERR_NAPATECH_INIT_FAILED, - SC_ERR_NAPATECH_CONFIG_STREAM, - SC_ERR_NAPATECH_STREAMS_REGISTER_FAILED, - SC_ERR_NAPATECH_STAT_DROPS_FAILED, - SC_ERR_NAPATECH_PARSE_CONFIG, - SC_ERR_NO_REPUTATION, - SC_ERR_NOT_SUPPORTED, - SC_ERR_IPFW_SETSOCKOPT, - SC_ERR_NO_GEOIP_SUPPORT, - SC_ERR_GEOIP_ERROR, - SC_ERR_LIVE_RULE_SWAP, - SC_WARN_UNCOMMON, - SC_ERR_CUDA_BUFFER_ERROR, - SC_ERR_DNS_LOG_GENERIC, - SC_WARN_OPTION_OBSOLETE, - SC_WARN_NO_UNITTESTS, - SC_ERR_THREAD_QUEUE, - SC_WARN_XFF_INVALID_MODE, - SC_WARN_XFF_INVALID_HEADER, - SC_WARN_XFF_INVALID_DEPLOYMENT, - SC_ERR_THRESHOLD_SETUP, - SC_ERR_DNS_CONFIG, - SC_ERR_MODBUS_CONFIG, - SC_ERR_CONF_YAML_ERROR, - SC_ERR_CONF_NAME_TOO_LONG, - SC_ERR_APP_LAYER_PROTOCOL_DETECTION, - SC_ERR_PCIE_INIT_FAILED, - SC_ERR_NFLOG_NOSUPPORT, - SC_ERR_NFLOG_OPEN, - SC_ERR_NFLOG_BIND, - SC_ERR_NFLOG_UNBIND, - SC_ERR_NFLOG_MAX_BUFSIZ, - SC_ERR_NFLOG_SET_MODE, - SC_ERR_NFLOG_HANDLE_PKT, - SC_ERR_NFLOG_GROUP, - SC_ERR_NFLOG_FD, - SC_WARN_NFLOG_RECV, - SC_WARN_NFLOG_LOSING_EVENTS, - SC_WARN_NFLOG_MAXBUFSIZ_REACHED, - SC_WARN_NFLOG_SETSOCKOPT, - SC_WARN_LUA_SCRIPT, - SC_ERR_LUA_SCRIPT, - SC_WARN_NO_STATS_LOGGERS, - SC_ERR_NO_NETMAP, - SC_ERR_NETMAP_CREATE, - SC_ERR_NETMAP_READ, - SC_ERR_THREAD_DEINIT, /**< thread's deinit function failed */ - SC_ERR_IPPAIR_INIT, - SC_ERR_MT_NO_SELECTOR, - SC_ERR_MT_DUPLICATE_TENANT, - SC_ERR_NO_JSON_SUPPORT, - SC_ERR_INVALID_RULE_ARGUMENT, /**< Generic error code for invalid - * rule argument. */ - SC_ERR_MT_NO_MAPPING, -} SCError; - -const char *SCErrorToString(SCError); - - -#endif /* __ERROR_H__ */ diff --git a/framework/src/suricata/src/util-file.c b/framework/src/suricata/src/util-file.c deleted file mode 100644 index bfb68e1e..00000000 --- a/framework/src/suricata/src/util-file.c +++ /dev/null @@ -1,932 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "debug.h" -#include "flow.h" -#include "stream.h" -#include "runmodes.h" -#include "util-hash.h" -#include "util-debug.h" -#include "util-memcmp.h" -#include "util-print.h" -#include "app-layer-parser.h" -#include "util-validate.h" - -/** \brief switch to force magic checks on all files - * regardless of the rules. - */ -static int g_file_force_magic = 0; - -/** \brief switch to force md5 calculation on all files - * regardless of the rules. - */ -static int g_file_force_md5 = 0; - -/** \brief switch to force tracking off all files - * regardless of the rules. - */ -static int g_file_force_tracking = 0; - -/* prototypes */ -static void FileFree(File *); -static void FileDataFree(FileData *); - -void FileForceMagicEnable(void) -{ - g_file_force_magic = 1; -} - -void FileForceMd5Enable(void) -{ - g_file_force_md5 = 1; -} - -int FileForceMagic(void) -{ - return g_file_force_magic; -} - -int FileForceMd5(void) -{ - return g_file_force_md5; -} - -void FileForceTrackingEnable(void) -{ - g_file_force_tracking = 1; -} - -int FileMagicSize(void) -{ - /** \todo make this size configurable */ - return 512; -} - -static int FileAppendFileDataFilePtr(File *ff, FileData *ffd) -{ - SCEnter(); - - if (ff == NULL) { - SCReturnInt(-1); - } - - if (ff->chunks_tail == NULL) { - ff->chunks_head = ffd; - ff->chunks_tail = ffd; - ff->content_len_so_far = ffd->len; - } else { - ff->chunks_tail->next = ffd; - ff->chunks_tail = ffd; - ff->content_len_so_far += ffd->len; - } - -#ifdef DEBUG - ff->chunks_cnt++; - if (ff->chunks_cnt > ff->chunks_cnt_max) - ff->chunks_cnt_max = ff->chunks_cnt; -#endif - -#ifdef HAVE_NSS - if (ff->md5_ctx) - HASH_Update(ff->md5_ctx, ffd->data, ffd->len); -#endif - SCReturnInt(0); -} - -static int FileAppendFileData(FileContainer *ffc, FileData *ffd) -{ - SCEnter(); - - if (ffc == NULL) { - SCReturnInt(-1); - } - - if (FileAppendFileDataFilePtr(ffc->tail, ffd) == -1) - { - SCReturnInt(-1); - } - - SCReturnInt(0); -} - - - -static int FilePruneFile(File *file) -{ - SCEnter(); - - SCLogDebug("file %p, file->chunks_cnt %"PRIu64, file, file->chunks_cnt); - - if (!(file->flags & FILE_NOMAGIC)) { - /* need magic but haven't set it yet, bail out */ - if (file->magic == NULL) - SCReturnInt(0); - else - SCLogDebug("file->magic %s", file->magic); - } else { - SCLogDebug("file->flags & FILE_NOMAGIC == true"); - } - - /* okay, we now know we can prune */ - FileData *fd = file->chunks_head; - - while (fd != NULL) { - SCLogDebug("fd %p", fd); - - if (file->flags & FILE_NOSTORE || fd->stored == 1) { - file->chunks_head = fd->next; - if (file->chunks_tail == fd) - file->chunks_tail = fd->next; - - FileDataFree(fd); - - fd = file->chunks_head; -#ifdef DEBUG - file->chunks_cnt--; - SCLogDebug("file->chunks_cnt %"PRIu64, file->chunks_cnt); -#endif - } else if (fd->stored == 0) { - fd = NULL; - SCReturnInt(0); - break; - } - } - - /* file is done when state is closed+, logging/storing is done (if any) */ - if (file->state >= FILE_STATE_CLOSED && - (!RunModeOutputFileEnabled() || (file->flags & FILE_LOGGED)) && - (!RunModeOutputFiledataEnabled() || (file->flags & FILE_STORED))) - { - SCReturnInt(1); - } else { - SCReturnInt(0); - } -} - -void FilePrune(FileContainer *ffc) -{ - File *file = ffc->head; - - while (file) { - if (FilePruneFile(file) == 0) - break; - - BUG_ON(file != ffc->head); - - File *file_next = file->next; - - /* update head and tail */ - ffc->head = file_next; - if (file == ffc->tail) - ffc->tail = NULL; - - FileFree(file); - file = file_next; - } -} - -/** - * \brief allocate a FileContainer - * - * \retval new newly allocated FileContainer - * \retval NULL error - */ -FileContainer *FileContainerAlloc(void) -{ - FileContainer *new = SCMalloc(sizeof(FileContainer)); - if (unlikely(new == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem"); - return NULL; - } - memset(new, 0, sizeof(FileContainer)); - new->head = new->tail = NULL; - return new; -} - -/** - * \brief Recycle a FileContainer - * - * \param ffc FileContainer - */ -void FileContainerRecycle(FileContainer *ffc) -{ - if (ffc == NULL) - return; - - File *cur = ffc->head; - File *next = NULL; - for (;cur != NULL; cur = next) { - next = cur->next; - FileFree(cur); - } - ffc->head = ffc->tail = NULL; -} - -/** - * \brief Free a FileContainer - * - * \param ffc FileContainer - */ -void FileContainerFree(FileContainer *ffc) -{ - if (ffc == NULL) - return; - - File *ptr = ffc->head; - File *next = NULL; - for (;ptr != NULL; ptr = next) { - next = ptr->next; - FileFree(ptr); - } - ffc->head = ffc->tail = NULL; - SCFree(ffc); -} - -/** - * \internal - * - * \brief allocate a FileData chunk and set it up - * - * \param data data chunk to store in the FileData - * \param data_len lenght of the data - * - * \retval new FileData object - */ -static FileData *FileDataAlloc(uint8_t *data, uint32_t data_len) -{ - FileData *new = SCMalloc(sizeof(FileData)); - if (unlikely(new == NULL)) { - return NULL; - } - memset(new, 0, sizeof(FileData)); - - new->data = SCMalloc(data_len); - if (new->data == NULL) { - SCFree(new); - return NULL; - } - - new->len = data_len; - memcpy(new->data, data, data_len); - - new->next = NULL; - return new; -} - -/** - * \internal - * - * \brief free a FileData object - * - * \param ffd the flow file data object to free - */ -static void FileDataFree(FileData *ffd) -{ - if (ffd == NULL) - return; - - if (ffd->data != NULL) { - SCFree(ffd->data); - } - - SCFree(ffd); -} - -/** - * \brief Alloc a new File - * - * \param name character array containing the name (not a string) - * \param name_len length in bytes of the name - * - * \retval new File object or NULL on error - */ -static File *FileAlloc(uint8_t *name, uint16_t name_len) -{ - File *new = SCMalloc(sizeof(File)); - if (unlikely(new == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem"); - return NULL; - } - memset(new, 0, sizeof(File)); - - new->name = SCMalloc(name_len); - if (new->name == NULL) { - SCFree(new); - return NULL; - } - - new->name_len = name_len; - memcpy(new->name, name, name_len); - - return new; -} - -static void FileFree(File *ff) -{ - if (ff == NULL) - return; - - if (ff->name != NULL) - SCFree(ff->name); - - /* magic returned by libmagic is strdup'd by MagicLookup. */ - if (ff->magic != NULL) - SCFree(ff->magic); - - if (ff->chunks_head != NULL) { - FileData *ffd = ff->chunks_head; - - while (ffd != NULL) { - FileData *next_ffd = ffd->next; - FileDataFree(ffd); - ffd = next_ffd; - } - } - -#ifdef HAVE_NSS - if (ff->md5_ctx) - HASH_Destroy(ff->md5_ctx); -#endif - SCLogDebug("ff chunks_cnt %"PRIu64", chunks_cnt_max %"PRIu64, - ff->chunks_cnt, ff->chunks_cnt_max); - SCFree(ff); -} - -void FileContainerAdd(FileContainer *ffc, File *ff) -{ - if (ffc->head == NULL || ffc->tail == NULL) { - ffc->head = ffc->tail = ff; - } else { - ffc->tail->next = ff; - ffc->tail = ff; - } -} - -/** - * \brief Tag a file for storing - * - * \param ff The file to store - */ -int FileStore(File *ff) -{ - ff->flags |= FILE_STORE; - SCReturnInt(0); -} - -/** - * \brief Set the TX id for a file - * - * \param ff The file to store - * \param txid the tx id - */ -int FileSetTx(File *ff, uint64_t txid) -{ - SCLogDebug("ff %p txid %"PRIu64, ff, txid); - if (ff != NULL) - ff->txid = txid; - SCReturnInt(0); -} - -/** - * \brief check if we have stored enough - * - * \param ff file - * - * \retval 0 limit not reached yet - * \retval 1 limit reached - */ -static int FileStoreNoStoreCheck(File *ff) -{ - SCEnter(); - - if (ff == NULL) { - SCReturnInt(0); - } - - if (ff->flags & FILE_NOSTORE) { - if (ff->state == FILE_STATE_OPENED && - ff->size >= (uint64_t)FileMagicSize()) - { - SCReturnInt(1); - } - } - - SCReturnInt(0); -} - -/** - * \brief Store a chunk of file data in the flow. The open "flowfile" - * will be used. - * - * \param ffc the container - * \param data data chunk - * \param data_len data chunk len - * - * \retval 0 ok - * \retval -1 error - * \retval -2 no store for this file - */ -int FileAppendData(FileContainer *ffc, uint8_t *data, uint32_t data_len) -{ - SCEnter(); - - if (ffc == NULL || ffc->tail == NULL || data == NULL || data_len == 0) { - SCReturnInt(-1); - } - - if (ffc->tail->state != FILE_STATE_OPENED) { - if (ffc->tail->flags & FILE_NOSTORE) { - SCReturnInt(-2); - } - SCReturnInt(-1); - } - - ffc->tail->size += data_len; - SCLogDebug("file size is now %"PRIu64, ffc->tail->size); - - if (FileStoreNoStoreCheck(ffc->tail) == 1) { -#ifdef HAVE_NSS - /* no storage but forced md5 */ - if (ffc->tail->md5_ctx) { - if (ffc->tail->md5_ctx) - HASH_Update(ffc->tail->md5_ctx, data, data_len); - - SCReturnInt(0); - } -#endif - if (g_file_force_tracking || (!(ffc->tail->flags & FILE_NOTRACK))) - SCReturnInt(0); - - ffc->tail->state = FILE_STATE_TRUNCATED; - SCLogDebug("flowfile state transitioned to FILE_STATE_TRUNCATED"); - SCReturnInt(-2); - } - - SCLogDebug("appending %"PRIu32" bytes", data_len); - - FileData *ffd = FileDataAlloc(data, data_len); - if (ffd == NULL) { - ffc->tail->state = FILE_STATE_ERROR; - SCReturnInt(-1); - } - - if (ffc->tail->chunks_head == NULL) - ffd->stream_offset = 0; - else - ffd->stream_offset = ffc->tail->size; - - /* append the data */ - if (FileAppendFileData(ffc, ffd) < 0) { - ffc->tail->state = FILE_STATE_ERROR; - FileDataFree(ffd); - SCReturnInt(-1); - } - SCReturnInt(0); -} - -/** - * \brief Open a new File - * - * \param ffc flow container - * \param name filename character array - * \param name_len filename len - * \param data initial data - * \param data_len initial data len - * \param flags open flags - * - * \retval ff flowfile object - * - * \note filename is not a string, so it's not nul terminated. - */ -File *FileOpenFile(FileContainer *ffc, uint8_t *name, - uint16_t name_len, uint8_t *data, uint32_t data_len, uint8_t flags) -{ - SCEnter(); - - //PrintRawDataFp(stdout, name, name_len); - - File *ff = FileAlloc(name, name_len); - if (ff == NULL) { - SCReturnPtr(NULL, "File"); - } - - if (flags & FILE_STORE) { - ff->flags |= FILE_STORE; - } else if (flags & FILE_NOSTORE) { - SCLogDebug("not storing this file"); - ff->flags |= FILE_NOSTORE; - } - if (flags & FILE_NOMAGIC) { - SCLogDebug("not doing magic for this file"); - ff->flags |= FILE_NOMAGIC; - } - if (flags & FILE_NOMD5) { - SCLogDebug("not doing md5 for this file"); - ff->flags |= FILE_NOMD5; - } - -#ifdef HAVE_NSS - if (!(ff->flags & FILE_NOMD5) || g_file_force_md5) { - ff->md5_ctx = HASH_Create(HASH_AlgMD5); - if (ff->md5_ctx != NULL) { - HASH_Begin(ff->md5_ctx); - } - } -#endif - - ff->state = FILE_STATE_OPENED; - SCLogDebug("flowfile state transitioned to FILE_STATE_OPENED"); - - FileContainerAdd(ffc, ff); - - if (data != NULL) { - //PrintRawDataFp(stdout, data, data_len); - ff->size += data_len; - SCLogDebug("file size is now %"PRIu64, ff->size); - - FileData *ffd = FileDataAlloc(data, data_len); - if (ffd == NULL) { - ff->state = FILE_STATE_ERROR; - SCReturnPtr(NULL, "File"); - } - - /* append the data */ - if (FileAppendFileData(ffc, ffd) < 0) { - ff->state = FILE_STATE_ERROR; - FileDataFree(ffd); - SCReturnPtr(NULL, "File"); - } - } - - SCReturnPtr(ff, "File"); -} - -static int FileCloseFilePtr(File *ff, uint8_t *data, - uint32_t data_len, uint8_t flags) -{ - SCEnter(); - - if (ff == NULL) { - SCReturnInt(-1); - } - - if (ff->state != FILE_STATE_OPENED) { - SCReturnInt(-1); - } - - ff->size += data_len; - SCLogDebug("file size is now %"PRIu64, ff->size); - - if (data != NULL) { - //PrintRawDataFp(stdout, data, data_len); - - if (ff->flags & FILE_NOSTORE) { -#ifdef HAVE_NSS - /* no storage but md5 */ - if (ff->md5_ctx) - HASH_Update(ff->md5_ctx, data, data_len); -#endif - } else { - FileData *ffd = FileDataAlloc(data, data_len); - if (ffd == NULL) { - ff->state = FILE_STATE_ERROR; - SCReturnInt(-1); - } - - /* append the data */ - if (FileAppendFileDataFilePtr(ff, ffd) < 0) { - ff->state = FILE_STATE_ERROR; - FileDataFree(ffd); - SCReturnInt(-1); - } - } - } - - if (flags & FILE_TRUNCATED) { - ff->state = FILE_STATE_TRUNCATED; - SCLogDebug("flowfile state transitioned to FILE_STATE_TRUNCATED"); - - if (flags & FILE_NOSTORE) { - SCLogDebug("not storing this file"); - ff->flags |= FILE_NOSTORE; - } - } else { - ff->state = FILE_STATE_CLOSED; - SCLogDebug("flowfile state transitioned to FILE_STATE_CLOSED"); - -#ifdef HAVE_NSS - if (ff->md5_ctx) { - unsigned int len = 0; - HASH_End(ff->md5_ctx, ff->md5, &len, sizeof(ff->md5)); - ff->flags |= FILE_MD5; - } -#endif - } - - SCReturnInt(0); -} - -/** - * \brief Close a File - * - * \param ffc the container - * \param data final data if any - * \param data_len data len if any - * \param flags flags - * - * \retval 0 ok - * \retval -1 error - */ -int FileCloseFile(FileContainer *ffc, uint8_t *data, - uint32_t data_len, uint8_t flags) -{ - SCEnter(); - - if (ffc == NULL || ffc->tail == NULL) { - SCReturnInt(-1); - } - - if (FileCloseFilePtr(ffc->tail, data, data_len, flags) == -1) { - SCReturnInt(-1); - } - - SCReturnInt(0); -} - -/** - * \brief disable file storage for a flow - * - * \param f *LOCKED* flow - * \param direction flow direction - */ -void FileDisableStoring(Flow *f, uint8_t direction) -{ - File *ptr = NULL; - - SCEnter(); - - DEBUG_ASSERT_FLOW_LOCKED(f); - - if (direction == STREAM_TOSERVER) - f->flags |= FLOW_FILE_NO_STORE_TS; - else - f->flags |= FLOW_FILE_NO_STORE_TC; - - FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction); - if (ffc != NULL) { - for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) { - /* if we're already storing, we'll continue */ - if (!(ptr->flags & FILE_STORE)) { - SCLogDebug("not storing this file"); - ptr->flags |= FILE_NOSTORE; - } - } - } - SCReturn; -} - -/** - * \brief disable file magic lookups for this flow - * - * \param f *LOCKED* flow - * \param direction flow direction - */ -void FileDisableMagic(Flow *f, uint8_t direction) -{ - File *ptr = NULL; - - SCEnter(); - - DEBUG_ASSERT_FLOW_LOCKED(f); - - if (direction == STREAM_TOSERVER) - f->flags |= FLOW_FILE_NO_MAGIC_TS; - else - f->flags |= FLOW_FILE_NO_MAGIC_TC; - - FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction); - if (ffc != NULL) { - for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) { - SCLogDebug("disabling magic for file %p from direction %s", - ptr, direction == STREAM_TOSERVER ? "toserver":"toclient"); - ptr->flags |= FILE_NOMAGIC; - } - } - - SCReturn; -} - -/** - * \brief disable file md5 calc for this flow - * - * \param f *LOCKED* flow - * \param direction flow direction - */ -void FileDisableMd5(Flow *f, uint8_t direction) -{ - File *ptr = NULL; - - SCEnter(); - - DEBUG_ASSERT_FLOW_LOCKED(f); - - if (direction == STREAM_TOSERVER) - f->flags |= FLOW_FILE_NO_MD5_TS; - else - f->flags |= FLOW_FILE_NO_MD5_TC; - - FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction); - if (ffc != NULL) { - for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) { - SCLogDebug("disabling md5 for file %p from direction %s", - ptr, direction == STREAM_TOSERVER ? "toserver":"toclient"); - ptr->flags |= FILE_NOMD5; - -#ifdef HAVE_NSS - /* destroy any ctx we may have so far */ - if (ptr->md5_ctx != NULL) { - HASH_Destroy(ptr->md5_ctx); - ptr->md5_ctx = NULL; - } -#endif - } - } - - SCReturn; -} - -/** - * \brief disable file size tracking for this flow - * - * \param f *LOCKED* flow - * \param direction flow direction - */ -void FileDisableFilesize(Flow *f, uint8_t direction) -{ - File *ptr = NULL; - - SCEnter(); - - DEBUG_ASSERT_FLOW_LOCKED(f); - - if (direction == STREAM_TOSERVER) - f->flags |= FLOW_FILE_NO_SIZE_TS; - else - f->flags |= FLOW_FILE_NO_SIZE_TC; - - FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction); - if (ffc != NULL) { - for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) { - SCLogDebug("disabling size tracking for file %p from direction %s", - ptr, direction == STREAM_TOSERVER ? "toserver":"toclient"); - ptr->flags |= FILE_NOTRACK; - } - } - - SCReturn; -} - - -/** - * \brief set no store flag, close file if needed - * - * \param ff file - */ -void FileDisableStoringForFile(File *ff) -{ - SCEnter(); - - if (ff == NULL) { - SCReturn; - } - - SCLogDebug("not storing this file"); - ff->flags |= FILE_NOSTORE; - - if (ff->state == FILE_STATE_OPENED && ff->size >= (uint64_t)FileMagicSize()) { - if (g_file_force_md5 == 0 && g_file_force_tracking == 0) { - (void)FileCloseFilePtr(ff, NULL, 0, - (FILE_TRUNCATED|FILE_NOSTORE)); - } - } -} - -/** - * \brief disable file storing for files in a transaction - * - * \param f *LOCKED* flow - * \param direction flow direction - * \param tx_id transaction id - */ -void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint64_t tx_id) -{ - File *ptr = NULL; - - DEBUG_ASSERT_FLOW_LOCKED(f); - - SCEnter(); - - FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction); - if (ffc != NULL) { - for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) { - if (ptr->txid == tx_id) { - if (ptr->flags & FILE_STORE) { - /* weird, already storing -- let it continue*/ - SCLogDebug("file is already being stored"); - } else { - FileDisableStoringForFile(ptr); - } - } - } - } - - SCReturn; -} - -/** - * \brief flag a file with id "file_id" to be stored. - * - * \param fc file store - * \param file_id the file's id - */ -void FileStoreFileById(FileContainer *fc, uint16_t file_id) -{ - File *ptr = NULL; - - SCEnter(); - - if (fc != NULL) { - for (ptr = fc->head; ptr != NULL; ptr = ptr->next) { - if (ptr->file_id == file_id) { - ptr->flags |= FILE_STORE; - } - } - } -} - -void FileStoreAllFilesForTx(FileContainer *fc, uint16_t tx_id) -{ - File *ptr = NULL; - - SCEnter(); - - if (fc != NULL) { - for (ptr = fc->head; ptr != NULL; ptr = ptr->next) { - if (ptr->txid == tx_id) { - ptr->flags |= FILE_STORE; - } - } - } -} - -void FileStoreAllFiles(FileContainer *fc) -{ - File *ptr = NULL; - - SCEnter(); - - if (fc != NULL) { - for (ptr = fc->head; ptr != NULL; ptr = ptr->next) { - ptr->flags |= FILE_STORE; - } - } -} - -void FileTruncateAllOpenFiles(FileContainer *fc) -{ - File *ptr = NULL; - - SCEnter(); - - if (fc != NULL) { - for (ptr = fc->head; ptr != NULL; ptr = ptr->next) { - if (ptr->state == FILE_STATE_OPENED) { - FileCloseFilePtr(ptr, NULL, 0, FILE_TRUNCATED); - } - } - } -} diff --git a/framework/src/suricata/src/util-file.h b/framework/src/suricata/src/util-file.h deleted file mode 100644 index 9cfc3a85..00000000 --- a/framework/src/suricata/src/util-file.h +++ /dev/null @@ -1,192 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#ifndef __UTIL_FILE_H__ -#define __UTIL_FILE_H__ - -#ifdef HAVE_NSS -#include -#endif - -#define FILE_TRUNCATED 0x0001 -#define FILE_NOMAGIC 0x0002 -#define FILE_NOMD5 0x0004 -#define FILE_MD5 0x0008 -#define FILE_LOGGED 0x0010 -#define FILE_NOSTORE 0x0020 -#define FILE_STORE 0x0040 -#define FILE_STORED 0x0080 -#define FILE_NOTRACK 0x0100 /**< track size of file */ - -typedef enum FileState_ { - FILE_STATE_NONE = 0, /**< no state */ - FILE_STATE_OPENED, /**< flow file is opened */ - FILE_STATE_CLOSED, /**< flow file is completed, - there will be no more data. */ - FILE_STATE_TRUNCATED, /**< flow file is not complete, but - there will be no more data. */ - FILE_STATE_ERROR, /**< file is in an error state */ - FILE_STATE_MAX -} FileState; - -typedef struct FileData_ { - uint8_t *data; - uint32_t len; - uint64_t stream_offset; - int stored; /* true if this chunk has been stored already - * false otherwise */ - struct FileData_ *next; -} FileData; - -typedef struct File_ { - uint16_t flags; - uint64_t txid; /**< tx this file is part of */ - unsigned int file_id; - uint8_t *name; - uint16_t name_len; - int16_t state; - uint64_t size; /**< size tracked so far */ - char *magic; - FileData *chunks_head; - FileData *chunks_tail; - struct File_ *next; -#ifdef HAVE_NSS - HASHContext *md5_ctx; - uint8_t md5[MD5_LENGTH]; -#endif -#ifdef DEBUG - uint64_t chunks_cnt; - uint64_t chunks_cnt_max; -#endif - uint64_t content_len_so_far; - uint64_t content_inspected; -} File; - -typedef struct FileContainer_ { - File *head; - File *tail; -} FileContainer; - -FileContainer *FileContainerAlloc(); -void FileContainerFree(FileContainer *); - -void FileContainerRecycle(FileContainer *); - -void FileContainerAdd(FileContainer *, File *); - -/** - * \brief Open a new File - * - * \param ffc flow container - * \param name filename character array - * \param name_len filename len - * \param data initial data - * \param data_len initial data len - * \param flags open flags - * - * \retval ff flowfile object - * - * \note filename is not a string, so it's not nul terminated. - */ -File *FileOpenFile(FileContainer *, uint8_t *name, uint16_t name_len, - uint8_t *data, uint32_t data_len, uint8_t flags); -/** - * \brief Close a File - * - * \param ffc the container - * \param data final data if any - * \param data_len data len if any - * \param flags flags - * - * \retval 0 ok - * \retval -1 error - */ -int FileCloseFile(FileContainer *, uint8_t *data, uint32_t data_len, uint8_t flags); - -/** - * \brief Store a chunk of file data in the flow. The open "flowfile" - * will be used. - * - * \param ffc the container - * \param data data chunk - * \param data_len data chunk len - * - * \retval 0 ok - * \retval -1 error - */ -int FileAppendData(FileContainer *, uint8_t *data, uint32_t data_len); - -/** - * \brief Tag a file for storing - * - * \param ff The file to store - */ -int FileStore(File *); - -/** - * \brief Set the TX id for a file - * - * \param ff The file to store - * \param txid the tx id - */ -int FileSetTx(File *, uint64_t txid); - -/** - * \brief disable file storage for a flow - * - * \param f *LOCKED* flow - */ -void FileDisableStoring(struct Flow_ *, uint8_t); - -void FileDisableFilesize(Flow *f, uint8_t direction); - -/** - * \brief disable file storing for a transaction - * - * \param f flow - * \param tx_id transaction id - */ -void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint64_t tx_id); - -void FlowFileDisableStoringForTransaction(struct Flow_ *f, uint16_t tx_id); -void FilePrune(FileContainer *ffc); - - -void FileDisableMagic(Flow *f, uint8_t); -void FileForceMagicEnable(void); -int FileForceMagic(void); - -void FileDisableMd5(Flow *f, uint8_t); -void FileForceMd5Enable(void); -int FileForceMd5(void); - -void FileForceTrackingEnable(void); - -void FileStoreAllFiles(FileContainer *); -void FileStoreAllFilesForTx(FileContainer *, uint16_t); -void FileStoreFileById(FileContainer *fc, uint16_t); - -void FileTruncateAllOpenFiles(FileContainer *); - -#endif /* __UTIL_FILE_H__ */ diff --git a/framework/src/suricata/src/util-fix_checksum.c b/framework/src/suricata/src/util-fix_checksum.c deleted file mode 100644 index f2bf881e..00000000 --- a/framework/src/suricata/src/util-fix_checksum.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Reference: OpenBSD's pf.c. - * - * Copyright (c) 2001 Daniel Hartmeier - * Copyright (c) 2002 - 2008 Henning Brauer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - */ - -#include - -/** - * \brief Fix-up an IP checksum. - * - * \param sum The current checksum. - * \param old Value of old header parameter. - * \param new Value of new header parameter. - * - * \retval New checksum. - */ -uint16_t -FixChecksum(uint16_t sum, uint16_t old, uint16_t new) -{ - uint32_t l; - - l = sum + old - new; - l = (l >> 16) + (l & 65535); - l = l & 65535; - - return l; -} diff --git a/framework/src/suricata/src/util-fix_checksum.h b/framework/src/suricata/src/util-fix_checksum.h deleted file mode 100644 index d5e53dd6..00000000 --- a/framework/src/suricata/src/util-fix_checksum.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Reference: OpenBSD's pf.c. - * - * Copyright (c) 2001 Daniel Hartmeier - * Copyright (c) 2002 - 2008 Henning Brauer - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Effort sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F30602-01-2-0537. - */ - -uint16_t FixChecksum(uint16_t sum, uint16_t old, uint16_t new); diff --git a/framework/src/suricata/src/util-fmemopen.c b/framework/src/suricata/src/util-fmemopen.c deleted file mode 100644 index 0a20b80b..00000000 --- a/framework/src/suricata/src/util-fmemopen.c +++ /dev/null @@ -1,198 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * Based on FMem.c of Alexandre Flori (2008/10/17 AF) - */ - -#include "suricata-common.h" -#include "util-fmemopen.h" - -#ifdef OS_DARWIN -#define USE_FMEM_WRAPPER 1 -#endif - -#ifdef OS_FREEBSD -#define USE_FMEM_WRAPPER 1 -#endif - -#ifdef __OpenBSD__ -#define USE_FMEM_WRAPPER 1 -#endif - -#ifdef USE_FMEM_WRAPPER - -#ifdef OS_WIN32 - -/** - * \brief portable version of SCFmemopen for Windows works on top of real temp files - * \param buffer that holds the file content - * \param size of the file buffer - * \param mode mode of the file to open - * \retval pointer to the file; NULL if something is wrong - */ -FILE *SCFmemopen(void *buf, size_t size, const char *mode) -{ - char temppath[MAX_PATH - 13]; - if (0 == GetTempPath(sizeof(temppath), temppath)) - return NULL; - - char filename[MAX_PATH + 1]; - if (0 == GetTempFileName(temppath, "SC", 0, filename)) - return NULL; - - FILE *f = fopen(filename, "wb"); - if (NULL == f) - return NULL; - - fwrite(buf, size, 1, f); - fclose(f); - - return fopen(filename, mode); -} - -#else - -typedef struct SCFmem_ { - size_t pos; - size_t size; - char *buffer; -} SCFmem; - -/** - * \brief Seek the mem file from offset and whence - * \param handler pointer to the memfile - * \param osffset number of bytes to move from whence - * \param whence SEEK_SET, SEEK_CUR, SEEK_END - * \retval pos the position by the last operation, -1 if sizes are out of bounds - */ -static fpos_t SeekFn(void *handler, fpos_t offset, int whence) -{ - size_t pos = 0; - SCFmem *mem = handler; - - switch (whence) { - case SEEK_SET: - if (offset >= 0 && (size_t)offset <= mem->size) { - return mem->pos = offset; - } - break; - case SEEK_CUR: - if (mem->pos + offset <= mem->size) - return mem->pos += offset; - break; - case SEEK_END: - /* must be negative */ - if (mem->size + offset <= mem->size) - return pos = mem->size + offset; - break; - } - - return -1; -} - -/** - * \brief Read from the buffer looking for the available memory limits - * \param handler pointer to the memfile - * \param buf buffer to read from the handler - * \param number of bytes to read - * \retval count , the number of bytes read - */ -static int ReadFn(void *handler, char *buf, int size) -{ - size_t count = 0; - SCFmem *mem = handler; - size_t available = mem->size - mem->pos; - int is_eof = 0; - - if (size < 0) return - 1; - - if ((size_t)size > available) { - size = available; - } else { - is_eof = 1; - } - - while (count < (size_t)size) - buf[count++] = mem->buffer[mem->pos++]; - - if (is_eof == 1) - return 0; - - return count; -} - -/** - * \brief Write into the buffer looking for the available memory limits - * \param handler pointer to the memfile - * \param buf buffer to write in the handler - * \param number of bytes to write - * \retval count , the number of bytes writen - */ -static int WriteFn(void *handler, const char *buf, int size) -{ - size_t count = 0; - SCFmem *mem = handler; - size_t available = mem->size - mem->pos; - - if (size < 0) return - 1; - - if ((size_t)size > available) - size = available; - - while (count < (size_t)size) - mem->buffer[mem->pos++] = buf[count++]; - - return count; -} - -/** - * \brief close the mem file handler - * \param handler pointer to the memfile - * \retval 0 on succesful - */ -static int CloseFn(void *handler) -{ - SCFree(handler); - return 0; -} - -/** - * \brief portable version of SCFmemopen for OS X / BSD built on top of funopen() - * \param buffer that holds the file content - * \param size of the file buffer - * \param mode mode of the file to open - * \retval pointer to the file; NULL if something is wrong - */ -FILE *SCFmemopen(void *buf, size_t size, const char *mode) -{ - SCFmem *mem = (SCFmem *) SCMalloc(sizeof(SCFmem)); - if (mem == NULL) - return NULL; - - memset(mem, 0, sizeof(SCFmem)); - mem->size = size, mem->buffer = buf; - - return funopen(mem, ReadFn, WriteFn, SeekFn, CloseFn); -} - -#endif /* OS_WIN32 */ - -#endif /* USE_FMEM_WRAPPER */ diff --git a/framework/src/suricata/src/util-fmemopen.h b/framework/src/suricata/src/util-fmemopen.h deleted file mode 100644 index 4b558eaf..00000000 --- a/framework/src/suricata/src/util-fmemopen.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * Based on FMem.c of Alexandre Flori (2008/10/17 AF) - */ - -#ifndef __FMEMOPEN_H__ -#define __FMEMOPEN_H__ -#include -#include -#include - -/* Include this file only for OSX / BSD compilations */ -#ifdef OS_DARWIN -#define USE_FMEM_WRAPPER 1 -#endif - -#ifdef OS_FREEBSD -#define USE_FMEM_WRAPPER 1 -#endif - -#ifdef __OpenBSD__ -#define USE_FMEM_WRAPPER 1 -#endif - -#ifdef OS_WIN32 -#define USE_FMEM_WRAPPER 1 -#endif - -#ifdef USE_FMEM_WRAPPER -FILE *SCFmemopen(void *, size_t, const char *); -#else -/* Else use the normal fmemopen */ -#define SCFmemopen fmemopen -#endif - -#endif /* __FMEMOPEN_H__ */ diff --git a/framework/src/suricata/src/util-hash-lookup3.c b/framework/src/suricata/src/util-hash-lookup3.c deleted file mode 100644 index f765521d..00000000 --- a/framework/src/suricata/src/util-hash-lookup3.c +++ /dev/null @@ -1,999 +0,0 @@ -/* -------------------------------------------------------------------------------- -lookup3.c, by Bob Jenkins, May 2006, Public Domain. - -These are functions for producing 32-bit hashes for hash table lookup. -hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() -are externally useful functions. Routines to test the hash are included -if SELF_TEST is defined. You can use this free for any purpose. It's in -the public domain. It has no warranty. - -You probably want to use hashlittle(). hashlittle() and hashbig() -hash byte arrays. hashlittle() is is faster than hashbig() on -little-endian machines. Intel and AMD are little-endian machines. -On second thought, you probably want hashlittle2(), which is identical to -hashlittle() except it returns two 32-bit hashes for the price of one. -You could implement hashbig2() if you wanted but I haven't bothered here. - -If you want to find a hash of, say, exactly 7 integers, do - a = i1; b = i2; c = i3; - mix(a,b,c); - a += i4; b += i5; c += i6; - mix(a,b,c); - a += i7; - final(a,b,c); -then use c as the hash value. If you have a variable length array of -4-byte integers to hash, use hashword(). If you have a byte array (like -a character string), use hashlittle(). If you have several byte arrays, or -a mix of things, see the comments above hashlittle(). - -Why is this so big? I read 12 bytes at a time into 3 4-byte integers, -then mix those integers. This is fast (you can do a lot more thorough -mixing with 12*3 instructions on 3 integers than you can with 3 instructions -on 1 byte), but shoehorning those bytes into integers efficiently is messy. -------------------------------------------------------------------------------- -*/ -//#define SELF_TEST 1 - -#include /* defines printf for tests */ -#include /* defines time_t for timings in the test */ -#include /* defines uint32_t etc */ -#include /* attempt to define endianness */ -#ifdef linux -# include /* attempt to define endianness */ -#endif - -/* - * My best guess at if you are big-endian or little-endian. This may - * need adjustment. - */ -#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ - __BYTE_ORDER == __LITTLE_ENDIAN) || \ - (defined(i386) || defined(__i386__) || defined(__i486__) || \ - defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) -# define HASH_LITTLE_ENDIAN 1 -# define HASH_BIG_ENDIAN 0 -#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ - __BYTE_ORDER == __BIG_ENDIAN) || \ - (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 1 -#else -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 0 -#endif - -#define hashsize(n) ((uint32_t)1<<(n)) -#define hashmask(n) (hashsize(n)-1) -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) - -/* -------------------------------------------------------------------------------- -mix -- mix 3 32-bit values reversibly. - -This is reversible, so any information in (a,b,c) before mix() is -still in (a,b,c) after mix(). - -If four pairs of (a,b,c) inputs are run through mix(), or through -mix() in reverse, there are at least 32 bits of the output that -are sometimes the same for one pair and different for another pair. -This was tested for: -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that -satisfy this are - 4 6 8 16 19 4 - 9 15 3 18 27 15 - 14 9 3 7 17 3 -Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing -for "differ" defined as + with a one-bit base and a two-bit delta. I -used http://burtleburtle.net/bob/hash/avalanche.html to choose -the operations, constants, and arrangements of the variables. - -This does not achieve avalanche. There are input bits of (a,b,c) -that fail to affect some output bits of (a,b,c), especially of a. The -most thoroughly mixed value is c, but it doesn't really even achieve -avalanche in c. - -This allows some parallelism. Read-after-writes are good at doubling -the number of bits affected, so the goal of mixing pulls in the opposite -direction as the goal of parallelism. I did what I could. Rotates -seem to cost as much as shifts on every machine I could lay my hands -on, and rotates are much kinder to the top and bottom bits, so I used -rotates. -------------------------------------------------------------------------------- -*/ -#define mix(a,b,c) \ -{ \ - a -= c; a ^= rot(c, 4); c += b; \ - b -= a; b ^= rot(a, 6); a += c; \ - c -= b; c ^= rot(b, 8); b += a; \ - a -= c; a ^= rot(c,16); c += b; \ - b -= a; b ^= rot(a,19); a += c; \ - c -= b; c ^= rot(b, 4); b += a; \ -} - -/* -------------------------------------------------------------------------------- -final -- final mixing of 3 32-bit values (a,b,c) into c - -Pairs of (a,b,c) values differing in only a few bits will usually -produce values of c that look totally different. This was tested for -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -These constants passed: - 14 11 25 16 4 14 24 - 12 14 25 16 4 14 24 -and these came close: - 4 8 15 26 3 22 24 - 10 8 15 26 3 22 24 - 11 8 15 26 3 22 24 -------------------------------------------------------------------------------- -*/ -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c,4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - -/* --------------------------------------------------------------------- - This works on all machines. To be useful, it requires - -- that the key be an array of uint32_t's, and - -- that the length be the number of uint32_t's in the key - - The function hashword() is identical to hashlittle() on little-endian - machines, and identical to hashbig() on big-endian machines, - except that the length has to be measured in uint32_ts rather than in - bytes. hashlittle() is more complicated than hashword() only because - hashlittle() has to dance around fitting the key bytes into registers. --------------------------------------------------------------------- -*/ -uint32_t hashword( -const uint32_t *k, /* the key, an array of uint32_t values */ -size_t length, /* the length of the key, in uint32_ts */ -uint32_t initval) /* the previous hash, or an arbitrary value */ -{ - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; - - /*------------------------------------------------- handle most of the key */ - while (length > 3) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 3; - k += 3; - } - - /*------------------------------------------- handle the last 3 uint32_t's */ - switch(length) /* all the case statements fall through */ - { - case 3 : c+=k[2]; - case 2 : b+=k[1]; - case 1 : a+=k[0]; - final(a,b,c); - case 0: /* case 0: nothing left to add */ - break; - } - /*------------------------------------------------------ report the result */ - return c; -} - - -/* --------------------------------------------------------------------- -hashword2() -- same as hashword(), but take two seeds and return two -32-bit values. pc and pb must both be nonnull, and *pc and *pb must -both be initialized with seeds. If you pass in (*pb)==0, the output -(*pc) will be the same as the return value from hashword(). --------------------------------------------------------------------- -*/ -void hashword2 ( -const uint32_t *k, /* the key, an array of uint32_t values */ -size_t length, /* the length of the key, in uint32_ts */ -uint32_t *pc, /* IN: seed OUT: primary hash value */ -uint32_t *pb) /* IN: more seed OUT: secondary hash value */ -{ - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; - c += *pb; - - /*------------------------------------------------- handle most of the key */ - while (length > 3) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 3; - k += 3; - } - - /*------------------------------------------- handle the last 3 uint32_t's */ - switch(length) /* all the case statements fall through */ - { - case 3 : c+=k[2]; - case 2 : b+=k[1]; - case 1 : a+=k[0]; - final(a,b,c); - case 0: /* case 0: nothing left to add */ - break; - } - /*------------------------------------------------------ report the result */ - *pc=c; *pb=b; -} - - -/* -------------------------------------------------------------------------------- -hashlittle() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - length : the length of the key, counting by bytes - initval : can be any 4-byte value -Returns a 32-bit value. Every bit of the key affects every bit of -the return value. Two keys differing by one or two bits will have -totally different hash values. - -The best hash table sizes are powers of 2. There is no need to do -mod a prime (mod is sooo slow!). If you need less than 32 bits, -use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); -In which case, the hash table should have hashsize(10) elements. - -If you are hashing n strings (uint8_t **)k, do it like this: - for (i=0, h=0; i 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - const uint8_t *k8 = (const uint8_t *)k; - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : return c; - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : return c; /* zero length requires no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; - case 11: c+=((uint32_t)k[10])<<16; - case 10: c+=((uint32_t)k[9])<<8; - case 9 : c+=k[8]; - case 8 : b+=((uint32_t)k[7])<<24; - case 7 : b+=((uint32_t)k[6])<<16; - case 6 : b+=((uint32_t)k[5])<<8; - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3])<<24; - case 3 : a+=((uint32_t)k[2])<<16; - case 2 : a+=((uint32_t)k[1])<<8; - case 1 : a+=k[0]; - break; - case 0 : return c; - } - } - - final(a,b,c); - return c; -} - - -/* - * hashlittle2: return 2 32-bit hash values - * - * This is identical to hashlittle(), except it returns two 32-bit hash - * values instead of just one. This is good enough for hash table - * lookup with 2^^64 buckets, or if you want a second hash if you're not - * happy with the first, or if you want a probably-unique 64-bit ID for - * the key. *pc is better mixed than *pb, so use *pc first. If you want - * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". - */ -void hashlittle2( - const void *key, /* the key to hash */ - size_t length, /* length of the key */ - uint32_t *pc, /* IN: primary initval, OUT: primary hash */ - uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ -{ - uint32_t a,b,c; /* internal state */ - union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; - c += *pb; - - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - const uint8_t *k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ - case 1 : a+=k8[0]; break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; /* fall through */ - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; /* fall through */ - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=((uint32_t)k[11])<<24; - case 11: c+=((uint32_t)k[10])<<16; - case 10: c+=((uint32_t)k[9])<<8; - case 9 : c+=k[8]; - case 8 : b+=((uint32_t)k[7])<<24; - case 7 : b+=((uint32_t)k[6])<<16; - case 6 : b+=((uint32_t)k[5])<<8; - case 5 : b+=k[4]; - case 4 : a+=((uint32_t)k[3])<<24; - case 3 : a+=((uint32_t)k[2])<<16; - case 2 : a+=((uint32_t)k[1])<<8; - case 1 : a+=k[0]; - break; - case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ - } - } - - final(a,b,c); - *pc=c; *pb=b; -} - - - -/* - * hashbig(): - * This is the same as hashword() on big-endian machines. It is different - * from hashlittle() on all machines. hashbig() takes advantage of - * big-endian byte ordering. - */ -uint32_t hashbig( const void *key, size_t length, uint32_t initval) -{ - uint32_t a,b,c; - union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; - - u.ptr = key; - if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ - - /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]<<8" actually reads beyond the end of the string, but - * then shifts out the part it's not allowed to read. Because the - * string is aligned, the illegal read is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; - case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; - case 5 : b+=k[1]&0xff000000; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff00; break; - case 2 : a+=k[0]&0xffff0000; break; - case 1 : a+=k[0]&0xff000000; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - - const uint8_t *k8 = (const uint8_t *)k; - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ - case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ - case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ - case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ - case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ - case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ - case 1 : a+=((uint32_t)k8[0])<<24; break; - case 0 : return c; - } - -#endif /* !VALGRIND */ - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += ((uint32_t)k[0])<<24; - a += ((uint32_t)k[1])<<16; - a += ((uint32_t)k[2])<<8; - a += ((uint32_t)k[3]); - b += ((uint32_t)k[4])<<24; - b += ((uint32_t)k[5])<<16; - b += ((uint32_t)k[6])<<8; - b += ((uint32_t)k[7]); - c += ((uint32_t)k[8])<<24; - c += ((uint32_t)k[9])<<16; - c += ((uint32_t)k[10])<<8; - c += ((uint32_t)k[11]); - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) /* all the case statements fall through */ - { - case 12: c+=k[11]; - case 11: c+=((uint32_t)k[10])<<8; - case 10: c+=((uint32_t)k[9])<<16; - case 9 : c+=((uint32_t)k[8])<<24; - case 8 : b+=k[7]; - case 7 : b+=((uint32_t)k[6])<<8; - case 6 : b+=((uint32_t)k[5])<<16; - case 5 : b+=((uint32_t)k[4])<<24; - case 4 : a+=k[3]; - case 3 : a+=((uint32_t)k[2])<<8; - case 2 : a+=((uint32_t)k[1])<<16; - case 1 : a+=((uint32_t)k[0])<<24; - break; - case 0 : return c; - } - } - - final(a,b,c); - return c; -} - - -#ifdef SELF_TEST - -/* used for timings */ -void driver1() -{ - uint8_t buf[256]; - uint32_t i; - uint32_t h=0; - time_t a,z; - - time(&a); - for (i=0; i<256; ++i) buf[i] = 'x'; - for (i=0; i<1; ++i) - { - h = hashlittle(&buf[0],1,h); - } - time(&z); - if (z-a > 0) printf("time %d %.8x\n", z-a, h); -} - -/* check that every input bit changes every output bit half the time */ -#define HASHSTATE 1 -#define HASHLEN 1 -#define MAXPAIR 60 -#define MAXLEN 70 -void driver2() -{ - uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; - uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; - uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; - uint32_t x[HASHSTATE],y[HASHSTATE]; - uint32_t hlen; - - printf("No more than %d trials should ever be needed \n",MAXPAIR/2); - for (hlen=0; hlen < MAXLEN; ++hlen) - { - z=0; - for (i=0; i>(8-j)); - c[0] = hashlittle(a, hlen, m); - b[i] ^= ((k+1)<>(8-j)); - d[0] = hashlittle(b, hlen, m); - /* check every bit is 1, 0, set, and not set at least once */ - for (l=0; lz) z=k; - if (k==MAXPAIR) - { - printf("Some bit didn't change: "); - printf("%.8x %.8x %.8x %.8x %.8x %.8x ", - e[0],f[0],g[0],h[0],x[0],y[0]); - printf("i %d j %d m %d len %d\n", i, j, m, hlen); - } - if (z==MAXPAIR) goto done; - } - } - } - done: - if (z < MAXPAIR) - { - printf("Mix success %2d bytes %2d initvals ",i,m); - printf("required %d trials\n", z/2); - } - } - printf("\n"); -} - -/* Check for reading beyond the end of the buffer and alignment problems */ -void driver3() -{ - uint8_t buf[MAXLEN+20], *b; - uint32_t len; - uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; - uint32_t h; - uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; - uint32_t i; - uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; - uint32_t j; - uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; - uint32_t ref,x,y; - uint8_t *p; - - printf("Endianness. These lines should all be the same (for values filled in):\n"); - printf("%.8x %.8x %.8x\n", - hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13), - hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13), - hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13)); - p = q; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qq[1]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qqq[2]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - p = &qqqq[3]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), - hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), - hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), - hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), - hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), - hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); - printf("\n"); - - /* check that hashlittle2 and hashlittle produce the same results */ - i=47; j=0; - hashlittle2(q, sizeof(q), &i, &j); - if (hashlittle(q, sizeof(q), 47) != i) - printf("hashlittle2 and hashlittle mismatch\n"); - - /* check that hashword2 and hashword produce the same results */ - len = 0xdeadbeef; - i=47, j=0; - hashword2(&len, 1, &i, &j); - if (hashword(&len, 1, 47) != i) - printf("hashword2 and hashword mismatch %x %x\n", - i, hashword(&len, 1, 47)); - - /* check hashlittle doesn't read before or after the ends of the string */ - for (h=0, b=buf+1; h<8; ++h, ++b) - { - for (i=0; i - * - * Chained hash table implementation - * - * The 'Free' pointer can be used to have the API free your - * hashed data. If it's NULL it's the callers responsebility - */ - -#include "suricata-common.h" -#include "util-hash.h" -#include "util-unittest.h" -#include "util-memcmp.h" - -HashTable* HashTableInit(uint32_t size, uint32_t (*Hash)(struct HashTable_ *, void *, uint16_t), char (*Compare)(void *, uint16_t, void *, uint16_t), void (*Free)(void *)) { - - HashTable *ht = NULL; - - if (size == 0) { - goto error; - } - - if (Hash == NULL) { - //printf("ERROR: HashTableInit no Hash function\n"); - goto error; - } - - /* setup the filter */ - ht = SCMalloc(sizeof(HashTable)); - if (unlikely(ht == NULL)) - goto error; - memset(ht,0,sizeof(HashTable)); - ht->array_size = size; - ht->Hash = Hash; - ht->Free = Free; - - if (Compare != NULL) - ht->Compare = Compare; - else - ht->Compare = HashTableDefaultCompare; - - /* setup the bitarray */ - ht->array = SCMalloc(ht->array_size * sizeof(HashTableBucket *)); - if (ht->array == NULL) - goto error; - memset(ht->array,0,ht->array_size * sizeof(HashTableBucket *)); - - return ht; - -error: - if (ht != NULL) { - if (ht->array != NULL) - SCFree(ht->array); - - SCFree(ht); - } - return NULL; -} - -void HashTableFree(HashTable *ht) -{ - uint32_t i = 0; - - if (ht == NULL) - return; - - /* free the buckets */ - for (i = 0; i < ht->array_size; i++) { - HashTableBucket *hashbucket = ht->array[i]; - while (hashbucket != NULL) { - HashTableBucket *next_hashbucket = hashbucket->next; - if (ht->Free != NULL) - ht->Free(hashbucket->data); - SCFree(hashbucket); - hashbucket = next_hashbucket; - } - } - - /* free the arrray */ - if (ht->array != NULL) - SCFree(ht->array); - - SCFree(ht); -} - -void HashTablePrint(HashTable *ht) -{ - printf("\n----------- Hash Table Stats ------------\n"); - printf("Buckets: %" PRIu32 "\n", ht->array_size); - printf("Hash function pointer: %p\n", ht->Hash); - printf("-----------------------------------------\n"); -} - -int HashTableAdd(HashTable *ht, void *data, uint16_t datalen) -{ - if (ht == NULL || data == NULL) - return -1; - - uint32_t hash = ht->Hash(ht, data, datalen); - - HashTableBucket *hb = SCMalloc(sizeof(HashTableBucket)); - if (unlikely(hb == NULL)) - goto error; - memset(hb, 0, sizeof(HashTableBucket)); - hb->data = data; - hb->size = datalen; - hb->next = NULL; - - if (ht->array[hash] == NULL) { - ht->array[hash] = hb; - } else { - hb->next = ht->array[hash]; - ht->array[hash] = hb; - } - -#ifdef UNITTESTS - ht->count++; -#endif - - return 0; - -error: - return -1; -} - -int HashTableRemove(HashTable *ht, void *data, uint16_t datalen) -{ - uint32_t hash = ht->Hash(ht, data, datalen); - - if (ht->array[hash] == NULL) { - return -1; - } - - if (ht->array[hash]->next == NULL) { - if (ht->Free != NULL) - ht->Free(ht->array[hash]->data); - SCFree(ht->array[hash]); - ht->array[hash] = NULL; - return 0; - } - - HashTableBucket *hashbucket = ht->array[hash], *prev_hashbucket = NULL; - do { - if (ht->Compare(hashbucket->data,hashbucket->size,data,datalen) == 1) { - if (prev_hashbucket == NULL) { - /* root bucket */ - ht->array[hash] = hashbucket->next; - } else { - /* child bucket */ - prev_hashbucket->next = hashbucket->next; - } - - /* remove this */ - if (ht->Free != NULL) - ht->Free(hashbucket->data); - SCFree(hashbucket); - return 0; - } - - prev_hashbucket = hashbucket; - hashbucket = hashbucket->next; - } while (hashbucket != NULL); - - return -1; -} - -void *HashTableLookup(HashTable *ht, void *data, uint16_t datalen) -{ - uint32_t hash = 0; - - if (ht == NULL) - return NULL; - - hash = ht->Hash(ht, data, datalen); - - if (ht->array[hash] == NULL) - return NULL; - - HashTableBucket *hashbucket = ht->array[hash]; - do { - if (ht->Compare(hashbucket->data, hashbucket->size, data, datalen) == 1) - return hashbucket->data; - - hashbucket = hashbucket->next; - } while (hashbucket != NULL); - - return NULL; -} - -uint32_t HashTableGenericHash(HashTable *ht, void *data, uint16_t datalen) -{ - uint8_t *d = (uint8_t *)data; - uint32_t i; - uint32_t hash = 0; - - for (i = 0; i < datalen; i++) { - if (i == 0) hash += (((uint32_t)*d++)); - else if (i == 1) hash += (((uint32_t)*d++) * datalen); - else hash *= (((uint32_t)*d++) * i) + datalen + i; - } - - hash *= datalen; - hash %= ht->array_size; - return hash; -} - -char HashTableDefaultCompare(void *data1, uint16_t len1, void *data2, uint16_t len2) -{ - if (len1 != len2) - return 0; - - if (SCMemcmp(data1,data2,len1) != 0) - return 0; - - return 1; -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -static int HashTableTestInit01 (void) -{ - HashTable *ht = HashTableInit(1024, HashTableGenericHash, NULL, NULL); - if (ht == NULL) - return 0; - - HashTableFree(ht); - return 1; -} - -/* no hash function, so it should fail */ -static int HashTableTestInit02 (void) -{ - HashTable *ht = HashTableInit(1024, NULL, NULL, NULL); - if (ht == NULL) - return 1; - - HashTableFree(ht); - return 0; -} - -static int HashTableTestInit03 (void) -{ - int result = 0; - HashTable *ht = HashTableInit(1024, HashTableGenericHash, NULL, NULL); - if (ht == NULL) - return 0; - - if (ht->Hash == HashTableGenericHash) - result = 1; - - HashTableFree(ht); - return result; -} - -static int HashTableTestInit04 (void) -{ - HashTable *ht = HashTableInit(0, HashTableGenericHash, NULL, NULL); - if (ht == NULL) - return 1; - - HashTableFree(ht); - return 0; -} - -static int HashTableTestInit05 (void) -{ - int result = 0; - HashTable *ht = HashTableInit(1024, HashTableGenericHash, NULL, NULL); - if (ht == NULL) - return 0; - - if (ht->Compare == HashTableDefaultCompare) - result = 1; - - HashTableFree(ht); - return result; -} - -static char HashTableDefaultCompareTest(void *data1, uint16_t len1, void *data2, uint16_t len2) -{ - if (len1 != len2) - return 0; - - if (SCMemcmp(data1,data2,len1) != 0) - return 0; - - return 1; -} - -static int HashTableTestInit06 (void) -{ - int result = 0; - HashTable *ht = HashTableInit(1024, HashTableGenericHash, HashTableDefaultCompareTest, NULL); - if (ht == NULL) - return 0; - - if (ht->Compare == HashTableDefaultCompareTest) - result = 1; - - HashTableFree(ht); - return result; -} - -static int HashTableTestAdd01 (void) -{ - int result = 0; - HashTable *ht = HashTableInit(32, HashTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashTableAdd(ht, "test", 0); - if (r != 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashTableFree(ht); - return result; -} - -static int HashTableTestAdd02 (void) -{ - int result = 0; - HashTable *ht = HashTableInit(32, HashTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashTableAdd(ht, NULL, 4); - if (r == 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashTableFree(ht); - return result; -} - -static int HashTableTestFull01 (void) -{ - int result = 0; - HashTable *ht = HashTableInit(32, HashTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashTableAdd(ht, "test", 4); - if (r != 0) - goto end; - - char *rp = HashTableLookup(ht, "test", 4); - if (rp == NULL) - goto end; - - r = HashTableRemove(ht, "test", 4); - if (r != 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashTableFree(ht); - return result; -} - -static int HashTableTestFull02 (void) -{ - int result = 0; - HashTable *ht = HashTableInit(32, HashTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashTableAdd(ht, "test", 4); - if (r != 0) - goto end; - - char *rp = HashTableLookup(ht, "test", 4); - if (rp == NULL) - goto end; - - r = HashTableRemove(ht, "test2", 5); - if (r == 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashTableFree(ht); - return result; -} -#endif - -void HashTableRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("HashTableTestInit01", HashTableTestInit01, 1); - UtRegisterTest("HashTableTestInit02", HashTableTestInit02, 1); - UtRegisterTest("HashTableTestInit03", HashTableTestInit03, 1); - UtRegisterTest("HashTableTestInit04", HashTableTestInit04, 1); - UtRegisterTest("HashTableTestInit05", HashTableTestInit05, 1); - UtRegisterTest("HashTableTestInit06", HashTableTestInit06, 1); - - UtRegisterTest("HashTableTestAdd01", HashTableTestAdd01, 1); - UtRegisterTest("HashTableTestAdd02", HashTableTestAdd02, 1); - - UtRegisterTest("HashTableTestFull01", HashTableTestFull01, 1); - UtRegisterTest("HashTableTestFull02", HashTableTestFull02, 1); -#endif -} - diff --git a/framework/src/suricata/src/util-hash.h b/framework/src/suricata/src/util-hash.h deleted file mode 100644 index f1611188..00000000 --- a/framework/src/suricata/src/util-hash.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __HASH_H__ -#define __HASH_H__ - -/* hash bucket structure */ -typedef struct HashTableBucket_ { - void *data; - uint16_t size; - struct HashTableBucket_ *next; -} HashTableBucket; - -/* hash table structure */ -typedef struct HashTable_ { - HashTableBucket **array; - uint32_t array_size; -#ifdef UNITTESTS - uint32_t count; -#endif - uint32_t (*Hash)(struct HashTable_ *, void *, uint16_t); - char (*Compare)(void *, uint16_t, void *, uint16_t); - void (*Free)(void *); -} HashTable; - -#define HASH_NO_SIZE 0 - -/* prototypes */ -HashTable* HashTableInit(uint32_t, uint32_t (*Hash)(struct HashTable_ *, void *, uint16_t), char (*Compare)(void *, uint16_t, void *, uint16_t), void (*Free)(void *)); -void HashTableFree(HashTable *); -void HashTablePrint(HashTable *); -int HashTableAdd(HashTable *, void *, uint16_t); -int HashTableRemove(HashTable *, void *, uint16_t); -void *HashTableLookup(HashTable *, void *, uint16_t); -uint32_t HashTableGenericHash(HashTable *, void *, uint16_t); -char HashTableDefaultCompare(void *, uint16_t, void *, uint16_t); - -void HashTableRegisterTests(void); - -#endif /* __HASH_H__ */ - diff --git a/framework/src/suricata/src/util-hashlist.c b/framework/src/suricata/src/util-hashlist.c deleted file mode 100644 index db8ba905..00000000 --- a/framework/src/suricata/src/util-hashlist.c +++ /dev/null @@ -1,518 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Chained hash table implementation - * - * The 'Free' pointer can be used to have the API free your - * hashed data. If it's NULL it's the callers responsebility - */ - -#include "suricata-common.h" -#include "util-hashlist.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "util-memcmp.h" - -HashListTable* HashListTableInit(uint32_t size, uint32_t (*Hash)(struct HashListTable_ *, void *, uint16_t), char (*Compare)(void *, uint16_t, void *, uint16_t), void (*Free)(void *)) { - - HashListTable *ht = NULL; - - if (size == 0) { - goto error; - } - - if (Hash == NULL) { - //printf("ERROR: HashListTableInit no Hash function\n"); - goto error; - } - - /* setup the filter */ - ht = SCMalloc(sizeof(HashListTable)); - if (unlikely(ht == NULL)) - goto error; - memset(ht,0,sizeof(HashListTable)); - ht->array_size = size; - ht->Hash = Hash; - ht->Free = Free; - - if (Compare != NULL) - ht->Compare = Compare; - else - ht->Compare = HashListTableDefaultCompare; - - /* setup the bitarray */ - ht->array = SCMalloc(ht->array_size * sizeof(HashListTableBucket *)); - if (ht->array == NULL) - goto error; - memset(ht->array,0,ht->array_size * sizeof(HashListTableBucket *)); - - ht->listhead = NULL; - ht->listtail = NULL; - return ht; - -error: - if (ht != NULL) { - if (ht->array != NULL) - SCFree(ht->array); - - SCFree(ht); - } - return NULL; -} - -void HashListTableFree(HashListTable *ht) -{ - uint32_t i = 0; - - if (ht == NULL) - return; - - /* free the buckets */ - for (i = 0; i < ht->array_size; i++) { - HashListTableBucket *hashbucket = ht->array[i]; - while (hashbucket != NULL) { - HashListTableBucket *next_hashbucket = hashbucket->bucknext; - if (ht->Free != NULL) - ht->Free(hashbucket->data); - SCFree(hashbucket); - hashbucket = next_hashbucket; - } - } - - /* free the array */ - if (ht->array != NULL) - SCFree(ht->array); - - SCFree(ht); -} - -void HashListTablePrint(HashListTable *ht) -{ - printf("\n----------- Hash Table Stats ------------\n"); - printf("Buckets: %" PRIu32 "\n", ht->array_size); - printf("Hash function pointer: %p\n", ht->Hash); - printf("-----------------------------------------\n"); -} - -int HashListTableAdd(HashListTable *ht, void *data, uint16_t datalen) -{ - if (ht == NULL || data == NULL) - return -1; - - uint32_t hash = ht->Hash(ht, data, datalen); - - SCLogDebug("ht %p hash %"PRIu32"", ht, hash); - - HashListTableBucket *hb = SCMalloc(sizeof(HashListTableBucket)); - if (unlikely(hb == NULL)) - goto error; - memset(hb, 0, sizeof(HashListTableBucket)); - hb->data = data; - hb->size = datalen; - hb->bucknext = NULL; - hb->listnext = NULL; - hb->listprev = NULL; - - if (ht->array[hash] == NULL) { - ht->array[hash] = hb; - } else { - hb->bucknext = ht->array[hash]; - ht->array[hash] = hb; - } - - if (ht->listtail == NULL) { - ht->listhead = hb; - ht->listtail = hb; - } else { - hb->listprev = ht->listtail; - ht->listtail->listnext = hb; - ht->listtail = hb; - } - - return 0; - -error: - return -1; -} - -int HashListTableRemove(HashListTable *ht, void *data, uint16_t datalen) -{ - uint32_t hash = ht->Hash(ht, data, datalen); - - SCLogDebug("ht %p hash %"PRIu32"", ht, hash); - - if (ht->array[hash] == NULL) { - SCLogDebug("ht->array[hash] NULL"); - return -1; - } - - /* fast track for just one data part */ - if (ht->array[hash]->bucknext == NULL) { - HashListTableBucket *hb = ht->array[hash]; - - if (ht->Compare(hb->data,hb->size,data,datalen) == 1) { - /* remove from the list */ - if (hb->listprev == NULL) { - ht->listhead = hb->listnext; - } else { - hb->listprev->listnext = hb->listnext; - } - if (hb->listnext == NULL) { - ht->listtail = hb->listprev; - } else { - hb->listnext->listprev = hb->listprev; - } - - if (ht->Free != NULL) - ht->Free(hb->data); - - SCFree(ht->array[hash]); - ht->array[hash] = NULL; - return 0; - } - - SCLogDebug("fast track default case"); - return -1; - } - - /* more data in this bucket */ - HashListTableBucket *hashbucket = ht->array[hash], *prev_hashbucket = NULL; - do { - if (ht->Compare(hashbucket->data,hashbucket->size,data,datalen) == 1) { - - /* remove from the list */ - if (hashbucket->listprev == NULL) { - ht->listhead = hashbucket->listnext; - } else { - hashbucket->listprev->listnext = hashbucket->listnext; - } - if (hashbucket->listnext == NULL) { - ht->listtail = hashbucket->listprev; - } else { - hashbucket->listnext->listprev = hashbucket->listprev; - } - - if (prev_hashbucket == NULL) { - /* root bucket */ - ht->array[hash] = hashbucket->bucknext; - } else { - /* child bucket */ - prev_hashbucket->bucknext = hashbucket->bucknext; - } - - /* remove this */ - if (ht->Free != NULL) - ht->Free(hashbucket->data); - SCFree(hashbucket); - return 0; - } - - prev_hashbucket = hashbucket; - hashbucket = hashbucket->bucknext; - } while (hashbucket != NULL); - - SCLogDebug("slow track default case"); - return -1; -} - -char HashListTableDefaultCompare(void *data1, uint16_t len1, void *data2, uint16_t len2) -{ - if (len1 != len2) - return 0; - - if (SCMemcmp(data1,data2,len1) != 0) - return 0; - - return 1; -} - -void *HashListTableLookup(HashListTable *ht, void *data, uint16_t datalen) -{ - - if (ht == NULL) { - SCLogDebug("Hash List table is NULL"); - return NULL; - } - - uint32_t hash = ht->Hash(ht, data, datalen); - - if (ht->array[hash] == NULL) { - return NULL; - } - - HashListTableBucket *hashbucket = ht->array[hash]; - do { - if (ht->Compare(hashbucket->data,hashbucket->size,data,datalen) == 1) - return hashbucket->data; - - hashbucket = hashbucket->bucknext; - } while (hashbucket != NULL); - - return NULL; -} - -uint32_t HashListTableGenericHash(HashListTable *ht, void *data, uint16_t datalen) -{ - uint8_t *d = (uint8_t *)data; - uint32_t i; - uint32_t hash = 0; - - for (i = 0; i < datalen; i++) { - if (i == 0) hash += (((uint32_t)*d++)); - else if (i == 1) hash += (((uint32_t)*d++) * datalen); - else hash *= (((uint32_t)*d++) * i) + datalen + i; - } - - hash *= datalen; - hash %= ht->array_size; - return hash; -} - -HashListTableBucket *HashListTableGetListHead(HashListTable *ht) -{ - return ht->listhead; -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -static int HashListTableTestInit01 (void) -{ - HashListTable *ht = HashListTableInit(1024, HashListTableGenericHash, NULL, NULL); - if (ht == NULL) - return 0; - - HashListTableFree(ht); - return 1; -} - -/* no hash function, so it should fail */ -static int HashListTableTestInit02 (void) -{ - HashListTable *ht = HashListTableInit(1024, NULL, NULL, NULL); - if (ht == NULL) - return 1; - - HashListTableFree(ht); - return 0; -} - -static int HashListTableTestInit03 (void) -{ - int result = 0; - HashListTable *ht = HashListTableInit(1024, HashListTableGenericHash, NULL, NULL); - if (ht == NULL) - return 0; - - if (ht->Hash == HashListTableGenericHash) - result = 1; - - HashListTableFree(ht); - return result; -} - -static int HashListTableTestInit04 (void) -{ - HashListTable *ht = HashListTableInit(0, HashListTableGenericHash, NULL, NULL); - if (ht == NULL) - return 1; - - HashListTableFree(ht); - return 0; -} - -static int HashListTableTestAdd01 (void) -{ - int result = 0; - HashListTable *ht = HashListTableInit(32, HashListTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashListTableAdd(ht, "test", 0); - if (r != 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashListTableFree(ht); - return result; -} - -static int HashListTableTestAdd02 (void) -{ - int result = 0; - HashListTable *ht = HashListTableInit(32, HashListTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashListTableAdd(ht, NULL, 4); - if (r == 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashListTableFree(ht); - return result; -} - -static int HashListTableTestAdd03 (void) -{ - int result = 0; - HashListTable *ht = HashListTableInit(32, HashListTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashListTableAdd(ht, "test", 0); - if (r != 0) - goto end; - - if (ht->listhead == NULL) { - printf("ht->listhead == NULL: "); - goto end; - } - - if (ht->listtail == NULL) { - printf("ht->listtail == NULL: "); - goto end; - } - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashListTableFree(ht); - return result; -} - -static int HashListTableTestAdd04 (void) -{ - int result = 0; - HashListTable *ht = HashListTableInit(32, HashListTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashListTableAdd(ht, "test", 4); - if (r != 0) - goto end; - - char *rp = HashListTableLookup(ht, "test", 4); - if (rp == NULL) - goto end; - - HashListTableBucket *htb = HashListTableGetListHead(ht); - if (htb == NULL) { - printf("htb == NULL: "); - goto end; - } - - char *rp2 = HashListTableGetListData(htb); - if (rp2 == NULL) { - printf("rp2 == NULL: "); - goto end; - } - - if (rp != rp2) { - printf("rp != rp2: "); - goto end; - } - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashListTableFree(ht); - return result; -} - -static int HashListTableTestFull01 (void) -{ - int result = 0; - HashListTable *ht = HashListTableInit(32, HashListTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashListTableAdd(ht, "test", 4); - if (r != 0) - goto end; - - char *rp = HashListTableLookup(ht, "test", 4); - if (rp == NULL) - goto end; - - r = HashListTableRemove(ht, "test", 4); - if (r != 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashListTableFree(ht); - return result; -} - -static int HashListTableTestFull02 (void) -{ - int result = 0; - HashListTable *ht = HashListTableInit(32, HashListTableGenericHash, NULL, NULL); - if (ht == NULL) - goto end; - - int r = HashListTableAdd(ht, "test", 4); - if (r != 0) - goto end; - - char *rp = HashListTableLookup(ht, "test", 4); - if (rp == NULL) - goto end; - - r = HashListTableRemove(ht, "test2", 5); - if (r == 0) - goto end; - - /* all is good! */ - result = 1; -end: - if (ht != NULL) HashListTableFree(ht); - return result; -} -#endif /* UNITTESTS */ - -void HashListTableRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("HashListTableTestInit01", HashListTableTestInit01, 1); - UtRegisterTest("HashListTableTestInit02", HashListTableTestInit02, 1); - UtRegisterTest("HashListTableTestInit03", HashListTableTestInit03, 1); - UtRegisterTest("HashListTableTestInit04", HashListTableTestInit04, 1); - - UtRegisterTest("HashListTableTestAdd01", HashListTableTestAdd01, 1); - UtRegisterTest("HashListTableTestAdd02", HashListTableTestAdd02, 1); - UtRegisterTest("HashListTableTestAdd03", HashListTableTestAdd03, 1); - UtRegisterTest("HashListTableTestAdd04", HashListTableTestAdd04, 1); - - UtRegisterTest("HashListTableTestFull01", HashListTableTestFull01, 1); - UtRegisterTest("HashListTableTestFull02", HashListTableTestFull02, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/util-hashlist.h b/framework/src/suricata/src/util-hashlist.h deleted file mode 100644 index f75fee36..00000000 --- a/framework/src/suricata/src/util-hashlist.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __HASHLIST_H__ -#define __HASHLIST_H__ - -/* hash bucket structure */ -typedef struct HashListTableBucket_ { - void *data; - uint16_t size; - struct HashListTableBucket_ *bucknext; - struct HashListTableBucket_ *listnext; - struct HashListTableBucket_ *listprev; -} HashListTableBucket; - -/* hash table structure */ -typedef struct HashListTable_ { - HashListTableBucket **array; - HashListTableBucket *listhead; - HashListTableBucket *listtail; - uint32_t array_size; - uint32_t (*Hash)(struct HashListTable_ *, void *, uint16_t); - char (*Compare)(void *, uint16_t, void *, uint16_t); - void (*Free)(void *); -} HashListTable; - -#define HASHLIST_NO_SIZE 0 - -/* prototypes */ -HashListTable* HashListTableInit(uint32_t, uint32_t (*Hash)(struct HashListTable_ *, void *, uint16_t), char (*Compare)(void *, uint16_t, void *, uint16_t), void (*Free)(void *)); -void HashListTableFree(HashListTable *); -void HashListTablePrint(HashListTable *); -int HashListTableAdd(HashListTable *, void *, uint16_t); -int HashListTableRemove(HashListTable *, void *, uint16_t); -void *HashListTableLookup(HashListTable *, void *, uint16_t); -uint32_t HashListTableGenericHash(HashListTable *, void *, uint16_t); -HashListTableBucket *HashListTableGetListHead(HashListTable *); -#define HashListTableGetListNext(hb) (hb)->listnext -#define HashListTableGetListData(hb) (hb)->data -char HashListTableDefaultCompare(void *, uint16_t, void *, uint16_t); - -void HashListTableRegisterTests(void); - -#endif /* __HASHLIST_H__ */ - diff --git a/framework/src/suricata/src/util-host-info.c b/framework/src/suricata/src/util-host-info.c deleted file mode 100644 index c7ea8adf..00000000 --- a/framework/src/suricata/src/util-host-info.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - * Get information on running host - * - */ - -#include "suricata-common.h" -#include "config.h" - -#ifndef OS_WIN32 -#include - -#define VERSION_REGEX "^([0-9]+)\\.([0-9]+)" - -int SCKernelVersionIsAtLeast(int major, int minor) -{ - struct utsname kuname; - pcre *version_regex; - pcre_extra *version_regex_study; - const char *eb; - int opts = 0; - int eo; -#define MAX_SUBSTRINGS 3 * 6 - int ov[MAX_SUBSTRINGS]; - int ret; - int kmajor, kminor; - const char **list; - - /* get local version */ - if (uname(&kuname) != 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Invalid uname return: %s", - strerror(errno)); - return 0; - } - - SCLogDebug("Kernel release is '%s'", kuname.release); - - version_regex = pcre_compile(VERSION_REGEX, opts, &eb, &eo, NULL); - if (version_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "pcre compile of \"%s\" failed at offset %" PRId32 ": %s", VERSION_REGEX, eo, eb); - goto error; - } - - version_regex_study = pcre_study(version_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - ret = pcre_exec(version_regex, version_regex_study, kuname.release, - strlen(kuname.release), 0, 0, ov, MAX_SUBSTRINGS); - - if (ret < 0) { - SCLogError(SC_ERR_PCRE_MATCH, "Version did not cut"); - goto error; - } - - if (ret < 3) { - SCLogError(SC_ERR_PCRE_MATCH, "Version major and minor not found (ret %d)", ret); - goto error; - } - - pcre_get_substring_list(kuname.release, ov, ret, &list); - - kmajor = atoi(list[1]); - kminor = atoi(list[2]); - - pcre_free_substring_list(list); - - if (kmajor > major) - return 1; - if (kmajor == major && kminor >= minor) - return 1; -error: - return 0; -} - -#else /* OS_WIN32 */ - -int SCKernelVersionIsAtLeast(int major, int minor) -{ - SCLogError(SC_ERR_NOT_SUPPORTED, "OS compare is not supported on Windows"); - return 0; -} - -#endif /* OS_WIN32 */ diff --git a/framework/src/suricata/src/util-host-info.h b/framework/src/suricata/src/util-host-info.h deleted file mode 100644 index b3a5e47a..00000000 --- a/framework/src/suricata/src/util-host-info.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#ifndef __UTIL_HOST_INFO_H__ -#define __UTIL_HOST_INFO_H__ - -int SCKernelVersionIsAtLeast(int major, int minor); - -#endif /* __UTIL_HOST_INFO_H__ */ diff --git a/framework/src/suricata/src/util-host-os-info.c b/framework/src/suricata/src/util-host-os-info.c deleted file mode 100644 index f04d6326..00000000 --- a/framework/src/suricata/src/util-host-os-info.c +++ /dev/null @@ -1,1660 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Host info utility functions - */ - -#include "suricata-common.h" -#include "util-host-os-info.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-ip.h" -#include "util-radix-tree.h" -#include "stream-tcp-private.h" -#include "stream-tcp-reassemble.h" - -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "util-enum.h" -#include "util-unittest.h" - -/** Enum map for the various OS flavours */ -SCEnumCharMap sc_hinfo_os_policy_map[ ] = { - { "none", OS_POLICY_NONE }, - { "bsd", OS_POLICY_BSD }, - { "bsd-right", OS_POLICY_BSD_RIGHT }, - { "old-linux", OS_POLICY_OLD_LINUX }, - { "linux", OS_POLICY_LINUX }, - { "old-solaris", OS_POLICY_OLD_SOLARIS }, - { "solaris", OS_POLICY_SOLARIS }, - { "hpux10", OS_POLICY_HPUX10 }, - { "hpux11", OS_POLICY_HPUX11 }, - { "irix", OS_POLICY_IRIX }, - { "macos", OS_POLICY_MACOS }, - { "windows", OS_POLICY_WINDOWS }, - { "vista", OS_POLICY_VISTA }, - { "windows2k3", OS_POLICY_WINDOWS2K3 }, - { NULL, -1 }, -}; - -/** Radix tree that holds the host OS information */ -static SCRadixTree *sc_hinfo_tree = NULL; - - -/** - * \brief Allocates the host_os flavour wrapped in user_data variable to be sent - * along with the key to the radix tree - * - * \param host_os Pointer to a character string containing the host_os flavour - * - * \retval user_data On success, pointer to the user_data that has to be sent - * along with the key, to be added to the Radix tree; NULL on - * failure - * \initonly - */ -static void *SCHInfoAllocUserDataOSPolicy(const char *host_os) -{ - int *user_data = NULL; - - if ( (user_data = SCMalloc(sizeof(int))) == NULL) { - SCLogError(SC_ERR_FATAL, "Error allocating memory. Exiting"); - exit(EXIT_FAILURE); - } - - /* the host os flavour that has to be sent as user data */ - if ( (*user_data = SCMapEnumNameToValue(host_os, sc_hinfo_os_policy_map)) == -1) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "Invalid enum map inside " - "SCHInfoAddHostOSInfo()"); - SCFree(user_data); - return NULL; - } - - return (void *)user_data; -} - -/** - * \brief Used to free the user data that is allocated by host_os_info API - * - * \param Pointer to the data that has to be freed - */ -static void SCHInfoFreeUserDataOSPolicy(void *data) -{ - if (data != NULL) - SCFree(data); - - return; -} - -/** - * \brief Used to add the host-os-info data obtained from the conf - * - * \param host_os The host_os name/flavour from the conf file - * \param host_os_ip_range Pointer to a char string holding the ip/ip_netblock - * for the host_os specified in the first argument - * \param is_ipv4 Indicates if the ip address to be considered for the - * default configuration is IPV4; if not it is IPV6. - * Specified using SC_HINFO_IS_IPV6 or SC_HINFO_IS_IPV4 - * - * \retval 0 On successfully adding the host os info to the Radix tree - * \retval -1 On failure - * \initonly (only specified from config, at the startup) - */ -int SCHInfoAddHostOSInfo(char *host_os, char *host_os_ip_range, int is_ipv4) -{ - char *ip_str = NULL; - char *ip_str_rem = NULL; - struct in_addr *ipv4_addr = NULL; - struct in6_addr *ipv6_addr = NULL; - char *netmask_str = NULL; - int netmask_value = 0; - int *user_data = NULL; - char recursive = FALSE; - - if (host_os == NULL || host_os_ip_range == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid arguments"); - return -1; - } - - /* create the radix tree that would hold all the host os info */ - if (sc_hinfo_tree == NULL) - sc_hinfo_tree = SCRadixCreateRadixTree(SCHInfoFreeUserDataOSPolicy, NULL); - - /* the host os flavour that has to be sent as user data */ - if ( (user_data = SCHInfoAllocUserDataOSPolicy(host_os)) == NULL) { - SCLogError(SC_ERR_INVALID_ENUM_MAP, "Invalid enum map inside"); - return -1; - } - - /* if we have a default configuration set the appropriate values for the - * netblocks */ - if ( (strcasecmp(host_os_ip_range, "default")) == 0) { - if (is_ipv4) - host_os_ip_range = "0.0.0.0/0"; - else - host_os_ip_range = "::/0"; - } - - if ( (ip_str = SCStrdup(host_os_ip_range)) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - - /* check if we have more addresses in the host_os_ip_range */ - if ((ip_str_rem = index(ip_str, ',')) != NULL) { - ip_str_rem[0] = '\0'; - ip_str_rem++; - recursive = TRUE; - } - - /* check if we have received a netblock */ - if ( (netmask_str = index(ip_str, '/')) != NULL) { - netmask_str[0] = '\0'; - netmask_str++; - } - - if (index(ip_str, ':') == NULL) { - /* if we are here, we have an IPV4 address */ - if ( (ipv4_addr = ValidateIPV4Address(ip_str)) == NULL) { - SCLogError(SC_ERR_INVALID_IPV4_ADDR, "Invalid IPV4 address"); - SCHInfoFreeUserDataOSPolicy(user_data); - SCFree(ip_str); - return -1; - } - - if (netmask_str == NULL) { - SCRadixAddKeyIPV4((uint8_t *)ipv4_addr, sc_hinfo_tree, - (void *)user_data); - } else { - netmask_value = atoi(netmask_str); - if (netmask_value < 0 || netmask_value > 32) { - SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Invalid IPV4 Netblock"); - SCHInfoFreeUserDataOSPolicy(user_data); - SCFree(ipv4_addr); - SCFree(ip_str); - return -1; - } - - MaskIPNetblock((uint8_t *)ipv4_addr, netmask_value, 32); - SCRadixAddKeyIPV4Netblock((uint8_t *)ipv4_addr, sc_hinfo_tree, - (void *)user_data, netmask_value); - } - } else { - /* if we are here, we have an IPV6 address */ - if ( (ipv6_addr = ValidateIPV6Address(ip_str)) == NULL) { - SCLogError(SC_ERR_INVALID_IPV6_ADDR, "Invalid IPV6 address inside"); - SCHInfoFreeUserDataOSPolicy(user_data); - SCFree(ip_str); - return -1; - } - - if (netmask_str == NULL) { - SCRadixAddKeyIPV6((uint8_t *)ipv6_addr, sc_hinfo_tree, - (void *)user_data); - } else { - netmask_value = atoi(netmask_str); - if (netmask_value < 0 || netmask_value > 128) { - SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "Invalid IPV6 Netblock"); - SCHInfoFreeUserDataOSPolicy(user_data); - SCFree(ipv6_addr); - SCFree(ip_str); - return -1; - } - - MaskIPNetblock((uint8_t *)ipv6_addr, netmask_value, 128); - SCRadixAddKeyIPV6Netblock((uint8_t *)ipv6_addr, sc_hinfo_tree, - (void *)user_data, netmask_value); - } - } - - if (recursive == TRUE) { - SCHInfoAddHostOSInfo(host_os, ip_str_rem, is_ipv4); - } - - if (ip_str != NULL) - SCFree(ip_str); - if (ipv4_addr != NULL) - SCFree(ipv4_addr); - if (ipv6_addr != NULL) - SCFree(ipv6_addr); - return *user_data; -} - -/** - * \brief Retrieves the host os flavour, given an ipv4/ipv6 address as a string. - * - * \param Pointer to a string containing an IP address - * - * \retval The OS flavour on success; -1 on failure, or on not finding the key - */ -int SCHInfoGetHostOSFlavour(char *ip_addr_str) -{ - struct in_addr *ipv4_addr = NULL; - struct in6_addr *ipv6_addr = NULL; - void *user_data = NULL; - - if (ip_addr_str == NULL || index(ip_addr_str, '/') != NULL) - return -1; - - if (index(ip_addr_str, ':') != NULL) { - if ( (ipv6_addr = ValidateIPV6Address(ip_addr_str)) == NULL) { - SCLogError(SC_ERR_INVALID_IPV4_ADDR, "Invalid IPV4 address"); - return -1; - } - - (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)ipv6_addr, sc_hinfo_tree, &user_data); - if (user_data == NULL) - return -1; - else - return *((int *)user_data); - } else { - if ( (ipv4_addr = ValidateIPV4Address(ip_addr_str)) == NULL) { - SCLogError(SC_ERR_INVALID_IPV4_ADDR, "Invalid IPV4 address"); - return -1; - } - - (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)ipv4_addr, sc_hinfo_tree, &user_data); - if (user_data == NULL) - return -1; - else - return *((int *)user_data); - } -} - -/** - * \brief Retrieves the host os flavour, given an ipv4 address in the raw - * address format. - * - * \param Pointer to a raw ipv4 address. - * - * \retval The OS flavour on success; -1 on failure, or on not finding the key - */ -int SCHInfoGetIPv4HostOSFlavour(uint8_t *ipv4_addr) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, sc_hinfo_tree, &user_data); - if (user_data == NULL) - return -1; - else - return *((int *)user_data); -} - -/** - * \brief Retrieves the host os flavour, given an ipv6 address in the raw - * address format. - * - * \param Pointer to a raw ipv6 address. - * - * \retval The OS flavour on success; -1 on failure, or on not finding the key - */ -int SCHInfoGetIPv6HostOSFlavour(uint8_t *ipv6_addr) -{ - void *user_data = NULL; - (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, sc_hinfo_tree, &user_data); - if (user_data == NULL) - return -1; - else - return *((int *)user_data); -} - -void SCHInfoCleanResources(void) -{ - if (sc_hinfo_tree != NULL) { - SCRadixReleaseRadixTree(sc_hinfo_tree); - sc_hinfo_tree = NULL; - } - - return; -} - -/** - * \brief Load the host os policy information from the configuration. - * - * \initonly (A mem alloc error should cause an exit failure) - */ -void SCHInfoLoadFromConfig(void) -{ - ConfNode *root = ConfGetNode("host-os-policy"); - if (root == NULL) - return; - - ConfNode *policy; - TAILQ_FOREACH(policy, &root->head, next) { - ConfNode *host; - TAILQ_FOREACH(host, &policy->head, next) { - int is_ipv4 = 1; - if (host->val != NULL && index(host->val, ':') != NULL) - is_ipv4 = 0; - if (SCHInfoAddHostOSInfo(policy->name, host->val, is_ipv4) == -1) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Failed to add host \"%s\" with policy \"%s\" to host " - "info database", host->val, policy->name); - exit(EXIT_FAILURE); - } - } - } -} - -/*------------------------------------Unit_Tests------------------------------*/ - -#ifdef UNITTESTS -static SCRadixTree *sc_hinfo_tree_backup = NULL; - -static void SCHInfoCreateContextBackup(void) -{ - sc_hinfo_tree_backup = sc_hinfo_tree; - sc_hinfo_tree = NULL; - - return; -} - -static void SCHInfoRestoreContextBackup(void) -{ - sc_hinfo_tree = sc_hinfo_tree_backup; - sc_hinfo_tree_backup = NULL; - - return; -} - -/** - * \test Check if we the IPs with the right OS flavours are added to the host OS - * radix tree, and the IPS with invalid flavours returns an error(-1) - */ -int SCHInfoTestInvalidOSFlavour01(void) -{ - SCHInfoCreateContextBackup(); - - int result = 0; - - if (SCHInfoAddHostOSInfo("bamboo", "192.168.1.1", SC_HINFO_IS_IPV4) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("windows", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux10", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("hpux10", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux11", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("irix", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("irix", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("bsd", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("bsd", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("old_linux", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("old_linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("macos", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("macos", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows2k3", "192.168.1.1", SC_HINFO_IS_IPV4) != - SCMapEnumNameToValue("windows2k3", sc_hinfo_os_policy_map)) { - goto end; - } - - result = 1; - - end: - SCHInfoCleanResources(); - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check that invalid ipv4 addresses and ipv4 netblocks are rejected by - * the host os info API - */ -int SCHInfoTestInvalidIPV4Address02(void) -{ - SCHInfoCreateContextBackup(); - - int result = 0; - - if (SCHInfoAddHostOSInfo("linux", "192.168.1.566", SC_HINFO_IS_IPV4) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "192.168.1", SC_HINFO_IS_IPV4) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "192.", SC_HINFO_IS_IPV4) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "192.168", SC_HINFO_IS_IPV4) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "", SC_HINFO_IS_IPV4) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "192.168.1.1/33", SC_HINFO_IS_IPV4) != -1) { - goto end; - } - - result = 1; - - end: - SCHInfoCleanResources(); - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check that invalid ipv4 addresses and ipv4 netblocks are rejected by - * the host os info API - */ -int SCHInfoTestInvalidIPV6Address03(void) -{ - SCHInfoCreateContextBackup(); - - int result = 0; - - if (SCHInfoAddHostOSInfo("linux", "2362:7322", SC_HINFO_IS_IPV6) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "19YW:", SC_HINFO_IS_IPV6) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "1235", SC_HINFO_IS_IPV6) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "1922:236115:", SC_HINFO_IS_IPV6) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "", SC_HINFO_IS_IPV6) != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", - "1921.6311:6241:6422:7352:ABBB:DDDD:EEEE/129", - SC_HINFO_IS_IPV6) != -1) { - goto end; - } - - result = 1; - - end: - SCHInfoCleanResources(); - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check that valid ipv4 addresses are inserted into the host os radix - * tree, and the host os api retrieves the right value for the host os - * flavour, on supplying as arg an ipv4 addresses that has been added to - * the host os radix tree. - */ -int SCHInfoTestValidIPV4Address04(void) -{ - SCHInfoCreateContextBackup(); - - int result = 0; - - if (SCHInfoAddHostOSInfo("linux", "192.168.1.1", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", "192.192.1.2", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", "192.168.1.100", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux10", "192.168.2.4", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "192.192.1.5", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", "192.168.10.20", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", "111.163.151.62", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", "11.1.120.210", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "19.18.110.210", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", "19.18.120.110", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux11", "191.168.11.128", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", "191.168.11.192", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - - if (SCHInfoGetHostOSFlavour("192.168.1.1") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.1.2") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.1.100") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.192.2.4") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.2.4") != - SCMapEnumNameToValue("hpux10", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.192.1.5") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.10.20") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.163.151.62") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("11.1.120.210") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("19.18.110.210") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("19.18.120.110") != - SCMapEnumNameToValue("windows", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("191.168.11.128") != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("191.168.11.192") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("191.168.11.224") != -1) { - goto end; - } - - result = 1; - - end: - SCHInfoCleanResources(); - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check that valid ipv4 addresses/netblocks are inserted into the host os - * radix tree, and the host os api retrieves the right value for the host - * os flavour, on supplying as arg an ipv4 addresses that has been added - * to the host os radix tree. - */ -int SCHInfoTestValidIPV4Address05(void) -{ - SCHInfoCreateContextBackup(); - - struct in_addr in; - int result = 0; - - if (SCHInfoAddHostOSInfo("linux", "192.168.1.1", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", "192.192.1.2", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", "192.168.1.100", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux10", "192.168.2.4", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "192.192.1.5", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", "192.168.10.20", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", "111.163.151.62", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux11", "111.162.208.124/20", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", "111.162.240.1", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", "111.162.214.100", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", "111.162.208.100", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", "111.162.194.112", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - - if (SCHInfoGetHostOSFlavour("192.168.1.1") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.1.2") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.1.100") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.192.2.4") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.2.4") != - SCMapEnumNameToValue("hpux10", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.192.1.5") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.10.20") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.163.151.62") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.208.0") != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.210.1") != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.214.1") != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.0.0") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.240.112") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.240.1") != - SCMapEnumNameToValue("windows", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.214.100") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (inet_pton(AF_INET, "111.162.208.100", &in) < 0) { - goto end; - } - if (SCHInfoGetIPv4HostOSFlavour((uint8_t *)&in) != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.194.112") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.208.200") != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (inet_pton(AF_INET, "111.162.208.200", &in) < 0) { - goto end; - } - if (SCHInfoGetIPv4HostOSFlavour((uint8_t *)&in) != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("111.162.200.201") != -1) { - goto end; - } - - result = 1; - - end: - SCHInfoCleanResources(); - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check that valid ipv6 addresses are inserted into the host os radix - * tree, and the host os api retrieves the right value for the host os - * flavour, on supplying as arg an ipv6 address that has been added to - * the host os radix tree. - */ -int SCHInfoTestValidIPV6Address06(void) -{ - SCHInfoCreateContextBackup(); - - int result = 0; - - if (SCHInfoAddHostOSInfo("linux", - "2351:2512:6211:6246:235A:6242:2352:62AD", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", - "6961:6121:2132:6241:423A:2135:2461:621D", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", - "DD13:613D:F312:62DD:6213:421A:6212:2652", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux10", - "9891:2131:2151:6426:1342:674D:622F:2342", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", - "3525:2351:4223:6211:2311:2667:6242:2154", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", - "1511:6211:6726:7777:1212:2333:6222:7722", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", - "2666:6222:7222:2335:6223:7722:3425:2362", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", - "8762:2352:6241:7245:EE23:21AD:2312:622C", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", - "6422:EE1A:2621:34AD:2462:432D:642E:E13A", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", - "3521:7622:6241:6242:7277:1234:2352:6234", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux11", - "2141:6232:6252:2223:7734:2345:6245:6222", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", - "5222:6432:6432:2322:6662:3423:4322:3245", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - - if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:62AD") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:6FFFE") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2652") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2222") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("9891:2131:2151:6426:1342:674D:622F:2342") != - SCMapEnumNameToValue("hpux10", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("3525:2351:4223:6211:2311:2667:6242:2154") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("1511:6211:6726:7777:1212:2333:6222:7722") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("2666:6222:7222:2335:6223:7722:3425:2362") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("6422:EE1A:2621:34AD:2462:432D:642E:E13A") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("3521:7622:6241:6242:7277:1234:2352:6234") != - SCMapEnumNameToValue("windows", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("2141:6232:6252:2223:7734:2345:6245:6222") != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("5222:6432:6432:2322:6662:3423:4322:3245") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("5222:6432:6432:2322:6662:3423:4322:DDDD") != -1) { - goto end; - } - - result = 1; - - end: - SCHInfoCleanResources(); - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check that valid ipv6 addresses/netblocks are inserted into the host os - * radix tree, and the host os api retrieves the right value for the host - * os flavour, on supplying as arg an ipv6 address that has been added to - * the host os radix tree. - */ -int SCHInfoTestValidIPV6Address07(void) -{ - SCHInfoCreateContextBackup(); - - int result = 0; - - if (SCHInfoAddHostOSInfo("linux", - "2351:2512:6211:6246:235A:6242:2352:62AD", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", - "6961:6121:2132:6241:423A:2135:2461:621D", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", - "DD13:613D:F312:62DD:6213:421A:6212:2652", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux10", - "9891:2131:2151:6426:1342:674D:622F:2342", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", - "3525:2351:4223:6211:2311:2667:6242:2154", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", - "1511:6211:6726:7777:1212:2333:6222:7722", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", - "2666:6222:7222:2335:6223:7722:3425:2362", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", - "8762:2352:6241:7245:EE23:21AD:2312:622C/68", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", - "8762:2352:6241:7245:EE23:21AD:2412:622C", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", - "8762:2352:6241:7245:EE23:21AD:FFFF:622C", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux11", - "8762:2352:6241:7245:EE23:21AD:2312:62FF", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", - "8762:2352:6241:7245:EE23:21AD:2121:1212", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - - if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:62AD") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:6FFFE") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2652") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2222") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("9891:2131:2151:6426:1342:674D:622F:2342") != - SCMapEnumNameToValue("hpux10", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("3525:2351:4223:6211:2311:2667:6242:2154") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("1511:6211:6726:7777:1212:2333:6222:7722") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("2666:6222:7222:2335:6223:7722:3425:2362") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2412:622C") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:FFFF:622C") != - SCMapEnumNameToValue("windows", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:62FF") != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2121:1212") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("5222:6432:6432:2322:6662:3423:4322:DDDD") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2121:1DDD") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:FFFF:2121:1DDD") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE00:0000:0000:0000") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:E000:0000:0000:0000") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - - result = 1; - - end: - SCHInfoCleanResources(); - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check that valid ipv6 addresses/netblocks are inserted into the host os - * radix tree, and the host os api retrieves the right value for the host - * os flavour, on supplying as arg an ipv6 address that has been added to - * the host os radix tree. - */ -int SCHInfoTestValidIPV6Address08(void) -{ - SCHInfoCreateContextBackup(); - - struct in6_addr in6; - int result = 0; - - if (SCHInfoAddHostOSInfo("linux", - "2351:2512:6211:6246:235A:6242:2352:62AD", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", - "6961:6121:2132:6241:423A:2135:2461:621D", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", - "DD13:613D:F312:62DD:6213:421A:6212:2652", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux10", - "9891:2131:2151:6426:1342:674D:622F:2342", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", - "3525:2351:4223:6211:2311:2667:6242:2154", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", - "1511:6211:6726:7777:1212:2333:6222:7722", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", - "2666:6222:7222:2335:6223:7722:3425:2362", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", - "8762:2352:6241:7245:EE23:21AD:2312:622C/68", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("linux", - "8762:2352:6241:7245:EE23:21AD:2412:622C", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", - "8762:2352:6241:7245:EE23:21AD:FFFF:622C", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("hpux11", - "8762:2352:6241:7245:EE23:21AD:2312:62FF", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", - "8762:2352:6241:7245:EE23:21AD:2121:1212", - SC_HINFO_IS_IPV6) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("irix", "default", SC_HINFO_IS_IPV6) == -1) { - goto end; - } - - if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:62AD") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("2351:2512:6211:6246:235A:6242:2352:6FFF") != - SCMapEnumNameToValue("irix", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2652") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("DD13:613D:F312:62DD:6213:421A:6212:2222") != - SCMapEnumNameToValue("irix", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("9891:2131:2151:6426:1342:674D:622F:2342") != - SCMapEnumNameToValue("hpux10", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("3525:2351:4223:6211:2311:2667:6242:2154") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("1511:6211:6726:7777:1212:2333:6222:7722") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("2666:6222:7222:2335:6223:7722:3425:2362") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2412:622C") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:FFFF:622C") != - SCMapEnumNameToValue("windows", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:62FF") != - SCMapEnumNameToValue("hpux11", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2121:1212") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("5222:6432:6432:2322:6662:3423:4322:DDDD") != - SCMapEnumNameToValue("irix", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2121:1DDD") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:FFFF:2121:1DDD") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE23:21AD:2312:622C") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoGetHostOSFlavour("8762:2352:6241:7245:EE00:0000:0000:0000") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (inet_pton(AF_INET6, "8762:2352:6241:7245:E000:0000:0000:0000", &in6) < 0) { - goto end; - } - if (SCHInfoGetIPv6HostOSFlavour((uint8_t *)&in6) != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - if (inet_pton(AF_INET6, "AD23:2DDA:6D1D:A223:E235:0232:1241:1666", &in6) < 0) { - goto end; - } - if (SCHInfoGetIPv6HostOSFlavour((uint8_t *)&in6) != - SCMapEnumNameToValue("irix", sc_hinfo_os_policy_map)) { - goto end; - } - - result = 1; - - end: - SCHInfoCleanResources(); - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check that valid ipv4 addresses are inserted into the host os radix - * tree, and the host os api retrieves the right value for the host os - * flavour, on supplying as arg an ipv4 addresses that has been added to - * the host os radix tree. - */ -int SCHInfoTestValidIPV4Address09(void) -{ - SCHInfoCreateContextBackup(); - - int result = 0; - - if (SCHInfoAddHostOSInfo("linux", "192.168.1.0", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("windows", "192.192.1.2", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.1.0") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", "192.168.1.0/16", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("macos", "192.168.1.0/20", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.1.0") != - SCMapEnumNameToValue("linux", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("vista", "192.168.50.128/25", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.50.128") != - SCMapEnumNameToValue("vista", sc_hinfo_os_policy_map)) { - goto end; - } - if (SCHInfoAddHostOSInfo("irix", "192.168.50.128", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("192.168.50.128") != - SCMapEnumNameToValue("irix", sc_hinfo_os_policy_map)) { - goto end; - } - - if (SCHInfoGetHostOSFlavour("192.168.1.100") != - SCMapEnumNameToValue("macos", sc_hinfo_os_policy_map)) { - goto end; - } - - struct sockaddr_in servaddr; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) { - goto end; - } - - SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 16); - - if (SCHInfoGetHostOSFlavour("192.168.1.100") != - SCMapEnumNameToValue("macos", sc_hinfo_os_policy_map)) { - goto end; - } - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) { - goto end; - } - SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 20); - - if (SCHInfoGetHostOSFlavour("192.168.1.100") != -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("solaris", "192.168.1.0/16", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - if (SCHInfoAddHostOSInfo("macos", "192.168.1.0/20", SC_HINFO_IS_IPV4) == -1) { - goto end; - } - - /* 192.168.1.100 should match "macos" as its more specific than - * "solaris". */ - if (SCHInfoGetHostOSFlavour("192.168.1.100") != - SCMapEnumNameToValue("macos", sc_hinfo_os_policy_map)) { - goto end; - } - - /* Remove the 192.168.1.0/20 -> macos entry. */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) { - goto end; - } - SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 20); - - if (SCHInfoGetHostOSFlavour("192.168.1.100") != - SCMapEnumNameToValue("solaris", sc_hinfo_os_policy_map)) { - goto end; - } - - /* Remove the 192.168.1.0/16 -> solaris entry. */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) { - goto end; - } - SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, sc_hinfo_tree, 16); - - if (SCHInfoGetHostOSFlavour("192.168.1.100") != -1) { - goto end; - } - - result = 1; - - end: - SCHInfoCleanResources(); - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check the loading of host info from a configuration file. - */ -int SCHInfoTestLoadFromConfig01(void) -{ - char config[] = "\ -%YAML 1.1\n\ ----\n\ -host-os-policy:\n\ - bsd: [0.0.0.0/0]\n\ - windows: [10.0.0.0/8, 192.168.1.0/24]\n\ - linux: [10.0.0.5/32]\n\ -\n"; - - int result = 0; - - SCHInfoCreateContextBackup(); - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - SCHInfoLoadFromConfig(); - if (SCHInfoGetHostOSFlavour("10.0.0.4") != OS_POLICY_WINDOWS) - goto end; - if (SCHInfoGetHostOSFlavour("10.0.0.5") != OS_POLICY_LINUX) - goto end; - if (SCHInfoGetHostOSFlavour("192.168.1.1") != OS_POLICY_WINDOWS) - goto end; - if (SCHInfoGetHostOSFlavour("172.168.1.1") != OS_POLICY_BSD) - goto end; - - result = 1; - - end: - ConfDeInit(); - ConfRestoreContextBackup(); - - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check the loading of host info from a configuration file. - */ -int SCHInfoTestLoadFromConfig02(void) -{ - char config[] = "\ -%YAML 1.1\n\ ----\n\ -host-os-policy:\n\ - one-two: [0.0.0.0/0]\n\ - one-two-three:\n\ - four_five:\n\ - six-seven_eight: [10.0.0.0/8, 192.168.1.0/24]\n\ - nine_ten_eleven: [10.0.0.5/32]\n\ -\n"; - - int result = 0; - - SCHInfoCreateContextBackup(); - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ConfNode *root = ConfGetNode("host-os-policy"); - if (root == NULL) - goto end; - - int count = 0; - - ConfNode *policy; - TAILQ_FOREACH(policy, &root->head, next) { - switch (count) { - case 0: - if (strcmp("one-two", policy->name) != 0) - goto end; - break; - case 1: - if (strcmp("one-two-three", policy->name) != 0) - goto end; - break; - case 2: - if (strcmp("four-five", policy->name) != 0) - goto end; - break; - case 3: - if (strcmp("six-seven-eight", policy->name) != 0) - goto end; - break; - case 4: - if (strcmp("nine-ten-eleven", policy->name) != 0) - goto end; - break; - } - count++; - } - - result = 1; - - end: - ConfDeInit(); - ConfRestoreContextBackup(); - - SCHInfoRestoreContextBackup(); - - return result; -} - -/** - * \test Check the loading of host info from a configuration file. - */ -int SCHInfoTestLoadFromConfig03(void) -{ - char config[] = "\ -%YAML 1.1\n\ ----\n\ -host-os-policy:\n\ - bsd-right: [0.0.0.1]\n\ - old-linux: [0.0.0.2]\n\ - old-solaris: [0.0.0.3]\n\ - windows: [0.0.0.4]\n\ - vista: [0.0.0.5]\n\ -\n"; - - int result = 0; - - SCHInfoCreateContextBackup(); - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ConfNode *root = ConfGetNode("host-os-policy"); - if (root == NULL) - goto end; - - ConfNode *policy; - TAILQ_FOREACH(policy, &root->head, next) { - if (SCMapEnumNameToValue(policy->name, sc_hinfo_os_policy_map) == -1) { - printf("Invalid enum map inside\n"); - goto end; - } - } - - result = 1; - - end: - ConfDeInit(); - ConfRestoreContextBackup(); - - SCHInfoRestoreContextBackup(); - return result; -} - -/** - * \test Check the loading of host info from a configuration file. - */ -int SCHInfoTestLoadFromConfig04(void) -{ - char config[] = "\ -%YAML 1.1\n\ ----\n\ -host-os-policy:\n\ - bsd_right: [0.0.0.1]\n\ - old_linux: [0.0.0.2]\n\ - old_solaris: [0.0.0.3]\n\ - windows: [0.0.0.4]\n\ - vista: [0.0.0.5]\n\ -\n"; - - int result = 0; - - SCHInfoCreateContextBackup(); - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - ConfNode *root = ConfGetNode("host-os-policy"); - if (root == NULL) - goto end; - - ConfNode *policy; - TAILQ_FOREACH(policy, &root->head, next) { - if (SCMapEnumNameToValue(policy->name, sc_hinfo_os_policy_map) == -1) { - printf("Invalid enum map inside\n"); - goto end; - } - } - - result = 1; - - end: - ConfDeInit(); - ConfRestoreContextBackup(); - - SCHInfoRestoreContextBackup(); - return result; -} - -/** - * \test Check the loading of host info from a configuration file. - */ -int SCHInfoTestLoadFromConfig05(void) -{ - char config[] = "\ -%YAML 1.1\n\ ----\n\ -host-os-policy:\n\ - bsd_right: [0.0.0.1]\n\ - old_linux: [0.0.0.2]\n\ - old-solaris: [0.0.0.3]\n\ - windows: [0.0.0.4]\n\ - linux: [0.0.0.5]\n\ -\n"; - - int result = 0; - - SCHInfoCreateContextBackup(); - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(config, strlen(config)); - - SCHInfoLoadFromConfig(); - - if (SCHInfoGetHostOSFlavour("0.0.0.1") != OS_POLICY_BSD_RIGHT) { - goto end; - } - if (SCHInfoGetHostOSFlavour("0.0.0.2") != OS_POLICY_OLD_LINUX) { - goto end; - } - if (SCHInfoGetHostOSFlavour("0.0.0.3") != OS_POLICY_OLD_SOLARIS) { - goto end; - } - if (SCHInfoGetHostOSFlavour("0.0.0.4") != OS_POLICY_WINDOWS) { - goto end; - } - if (SCHInfoGetHostOSFlavour("0.0.0.5") != OS_POLICY_VISTA) { - goto end; - } - if (SCHInfoGetHostOSFlavour("0.0.0.0") != -1) { - goto end; - } - if (SCHInfoGetHostOSFlavour("0.0.0.6") != -1) { - goto end; - } - - - result = 1; - - end: - ConfDeInit(); - ConfRestoreContextBackup(); - - SCHInfoRestoreContextBackup(); - - return result; -} - -#endif /* UNITTESTS */ - -void SCHInfoRegisterTests(void) -{ - -#ifdef UNITTESTS - - UtRegisterTest("SCHInfoTesInvalidOSFlavour01", - SCHInfoTestInvalidOSFlavour01, 1); - UtRegisterTest("SCHInfoTestInvalidIPV4Address02", - SCHInfoTestInvalidIPV4Address02, 1); - UtRegisterTest("SCHInfoTestInvalidIPV6Address03", - SCHInfoTestInvalidIPV6Address03, 1); - UtRegisterTest("SCHInfoTestValidIPV4Address04", - SCHInfoTestValidIPV4Address04, 1); - UtRegisterTest("SCHInfoTestValidIPV4Address05", - SCHInfoTestValidIPV4Address05, 1); - UtRegisterTest("SCHInfoTestValidIPV6Address06", - SCHInfoTestValidIPV6Address06, 1); - UtRegisterTest("SCHInfoTestValidIPV6Address07", - SCHInfoTestValidIPV6Address07, 1); - UtRegisterTest("SCHInfoTestValidIPV6Address08", - SCHInfoTestValidIPV6Address08, 1); - UtRegisterTest("SCHInfoTestValidIPV4Address09", - SCHInfoTestValidIPV4Address09, 1); - - UtRegisterTest("SCHInfoTestLoadFromConfig01", - SCHInfoTestLoadFromConfig01, 1); - UtRegisterTest("SCHInfoTestLoadFromConfig02", - SCHInfoTestLoadFromConfig02, 1); - UtRegisterTest("SCHInfoTestLoadFromConfig03", - SCHInfoTestLoadFromConfig03, 1); - UtRegisterTest("SCHInfoTestLoadFromConfig04", - SCHInfoTestLoadFromConfig04, 1); -#endif /* UNITTESTS */ - -} diff --git a/framework/src/suricata/src/util-host-os-info.h b/framework/src/suricata/src/util-host-os-info.h deleted file mode 100644 index 2dbcbc20..00000000 --- a/framework/src/suricata/src/util-host-os-info.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_HOST_OS_INFO_H__ -#define __UTIL_HOST_OS_INFO_H__ - -#define SC_HINFO_IS_IPV6 0 -#define SC_HINFO_IS_IPV4 1 - -int SCHInfoAddHostOSInfo(char *, char *, int); -int SCHInfoGetHostOSFlavour(char *); -int SCHInfoGetIPv4HostOSFlavour(uint8_t *); -int SCHInfoGetIPv6HostOSFlavour(uint8_t *); -void SCHInfoCleanResources(void); -void SCHInfoLoadFromConfig(void); -void SCHInfoRegisterTests(void); - -#endif /* __UTIL_HOST_OS_INFO_H__ */ diff --git a/framework/src/suricata/src/util-ioctl.c b/framework/src/suricata/src/util-ioctl.c deleted file mode 100644 index f08dea71..00000000 --- a/framework/src/suricata/src/util-ioctl.c +++ /dev/null @@ -1,248 +0,0 @@ -/* Copyright (C) 2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#include "suricata-common.h" -#include "conf.h" - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_LINUX_ETHTOOL_H -#include -#include -#ifdef HAVE_LINUX_SOCKIOS_H -#include -#else -#error "ethtool.h present but sockios.h is missing" -#endif /* HAVE_LINUX_SOCKIOS_H */ -#endif /* HAVE_LINUX_ETHTOOL_H */ - -#ifdef HAVE_NET_IF_H -#include -#endif - -/** - * \brief output a majorant of hardware header length - * - * \param Name of a network interface - */ -int GetIfaceMaxHWHeaderLength(const char *pcap_dev) -{ - if ((!strcmp("eth", pcap_dev)) - || - (!strcmp("br", pcap_dev)) - || - (!strcmp("bond", pcap_dev)) - || - (!strcmp("wlan", pcap_dev)) - || - (!strcmp("tun", pcap_dev)) - || - (!strcmp("tap", pcap_dev)) - || - (!strcmp("lo", pcap_dev))) - return ETHERNET_HEADER_LEN; - - if (!strcmp("ppp", pcap_dev)) - return SLL_HEADER_LEN; - /* SLL_HEADER_LEN is the biggest one */ - return SLL_HEADER_LEN; -} - -/** - * \brief output the link MTU - * - * \param Name of link - * \retval -1 in case of error, 0 if MTU can not be found - */ -int GetIfaceMTU(const char *pcap_dev) -{ -#ifdef SIOCGIFMTU - struct ifreq ifr; - int fd; - - (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name)); - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd == -1) { - return -1; - } - - if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) { - SCLogWarning(SC_ERR_SYSCALL, - "Failure when trying to get MTU via ioctl: %d", - errno); - close(fd); - return -1; - } - close(fd); - SCLogInfo("Found an MTU of %d for '%s'", ifr.ifr_mtu, - pcap_dev); - return ifr.ifr_mtu; -#else - /* ioctl is not defined, let's pretend returning 0 is ok */ - return 0; -#endif -} - -/** - * \brief output max packet size for a link - * - * This does a best effort to find the maximum packet size - * for the link. In case of uncertainty, it will output a - * majorant to be sure avoid the cost of dynamic allocation. - * - * \param Name of a network interface - * \retval 0 in case of error - */ -int GetIfaceMaxPacketSize(const char *pcap_dev) -{ - int ll_header = GetIfaceMaxHWHeaderLength(pcap_dev); - int mtu = 0; - - if ((pcap_dev == NULL) || strlen(pcap_dev) == 0) - return 0; - - mtu = GetIfaceMTU(pcap_dev); - switch (mtu) { - case 0: - case -1: - return 0; - } - if (ll_header == -1) { - /* be conservative, choose a big one */ - ll_header = 16; - } - return ll_header + mtu; -} - -/** - * \brief output offloading status of the link - * - * Test interface for GRO and LRO features. If one of them is - * activated then suricata mays received packets merge at reception. - * The result is oversized packets and this may cause some serious - * problem in some capture mode where the size of the packet is - * limited (AF_PACKET in V2 more for example). - * - * ETHTOOL_GGRO ETH_FLAG_LRO - * - * \param Name of link - * \retval -1 in case of error, 0 if none, 1 if some - */ -int GetIfaceOffloading(const char *pcap_dev) -{ -#if defined (ETHTOOL_GGRO) && defined (ETHTOOL_GFLAGS) - struct ifreq ifr; - int fd; - struct ethtool_value ethv; - int ret = 0; - - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd == -1) { - return -1; - } - (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name)); - - /* First get GRO */ - ethv.cmd = ETHTOOL_GGRO; - ifr.ifr_data = (void *) ðv; - if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) { - SCLogWarning(SC_ERR_SYSCALL, - "Failure when trying to get feature via ioctl: %s (%d)", - strerror(errno), errno); - close(fd); - return -1; - } else { - if (ethv.data) { - SCLogInfo("Generic Receive Offload is set on %s", pcap_dev); - ret = 1; - } else { - SCLogInfo("Generic Receive Offload is unset on %s", pcap_dev); - } - } - - /* Then get LRO which is set in a flag */ - ethv.data = 0; - ethv.cmd = ETHTOOL_GFLAGS; - ifr.ifr_data = (void *) ðv; - if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) { - SCLogWarning(SC_ERR_SYSCALL, - "Failure when trying to get feature via ioctl: %s (%d)", - strerror(errno), errno); - close(fd); - return -1; - } else { - if (ethv.data & ETH_FLAG_LRO) { - SCLogInfo("Large Receive Offload is set on %s", pcap_dev); - ret = 1; - } else { - SCLogInfo("Large Receive Offload is unset on %s", pcap_dev); - } - } - - close(fd); - - return ret; -#else - /* ioctl is not defined, let's pretend returning 0 is ok */ - return 0; -#endif -} - -int GetIfaceRSSQueuesNum(const char *pcap_dev) -{ -#if defined HAVE_LINUX_ETHTOOL_H && defined ETHTOOL_GRXRINGS - struct ifreq ifr; - struct ethtool_rxnfc nfccmd; - int fd; - - (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name)); - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd == -1) { - SCLogWarning(SC_ERR_SYSCALL, - "Failure when opening socket for ioctl: %d", - errno); - return -1; - } - - nfccmd.cmd = ETHTOOL_GRXRINGS; - ifr.ifr_data = (void*) &nfccmd; - - if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) { - if (errno != ENOTSUP) { - SCLogWarning(SC_ERR_SYSCALL, - "Failure when trying to get number of RSS queue ioctl: %d", - errno); - } - close(fd); - return 0; - } - close(fd); - SCLogInfo("Found %d RX RSS queues for '%s'", (int)nfccmd.data, - pcap_dev); - return (int)nfccmd.data; -#else - return 0; -#endif -} diff --git a/framework/src/suricata/src/util-ioctl.h b/framework/src/suricata/src/util-ioctl.h deleted file mode 100644 index 3931c1fe..00000000 --- a/framework/src/suricata/src/util-ioctl.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -int GetIfaceMTU(const char *pcap_dev); -int GetIfaceMaxPacketSize(const char *pcap_dev); -int GetIfaceOffloading(const char *pcap_dev); -int GetIfaceRSSQueuesNum(const char *pcap_dev); diff --git a/framework/src/suricata/src/util-ip.c b/framework/src/suricata/src/util-ip.c deleted file mode 100644 index 1f22d864..00000000 --- a/framework/src/suricata/src/util-ip.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Duarte Silva - * - * IP addresses related utility functions - */ - -#include "suricata-common.h" - -/** - * \brief Validates an IPV4 address and returns the network endian arranged - * version of the IPV4 address - * - * \param addr Pointer to a character string containing an IPV4 address. A - * valid IPV4 address is a character string containing a dotted - * format of "ddd.ddd.ddd.ddd" - * - * \retval Pointer to an in_addr instance containing the network endian format - * of the IPV4 address - * \retval NULL if the IPV4 address is invalid - */ -struct in_addr *ValidateIPV4Address(const char *addr_str) -{ - struct in_addr *addr = NULL; - - if ( (addr = SCMalloc(sizeof(struct in_addr))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in ValidateIPV4Address. Exiting..."); - exit(EXIT_FAILURE); - } - - if (inet_pton(AF_INET, addr_str, addr) <= 0) { - SCFree(addr); - return NULL; - } - - return addr; -} - -/** - * \brief Validates an IPV6 address and returns the network endian arranged - * version of the IPV6 addresss - * - * \param addr Pointer to a character string containing an IPV6 address - * - * \retval Pointer to a in6_addr instance containing the network endian format - * of the IPV6 address - * \retval NULL if the IPV6 address is invalid - */ -struct in6_addr *ValidateIPV6Address(const char *addr_str) -{ - struct in6_addr *addr = NULL; - - if ( (addr = SCMalloc(sizeof(struct in6_addr))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in ValidateIPV6Address. Exiting..."); - exit(EXIT_FAILURE); - } - - if (inet_pton(AF_INET6, addr_str, addr) <= 0) { - SCFree(addr); - return NULL; - } - - return addr; -} - -/** - * \brief Culls the non-netmask portion of the IP address. For example an IP - * address 192.168.240.1 would be chopped to 192.168.224.0 against a - * netmask value of 19. - * - * \param stream Pointer the IP address that has to be masked - * \param netmask The netmask value (cidr) to which the IP address has to be culled - * \param key_bitlen The bitlen of the stream - */ -void MaskIPNetblock(uint8_t *stream, uint8_t netmask, uint16_t key_bitlen) -{ - int mask = 0; - int i = 0; - int bytes = key_bitlen / 8; - - for (i = 0; i < bytes; i++) { - mask = -1; - if ( ((i + 1) * 8) > netmask) { - if ( ((i + 1) * 8 - netmask) < 8) - mask = -1 << ((i + 1) * 8 - netmask); - else - mask = 0; - } - stream[i] &= mask; - } - - return; -} diff --git a/framework/src/suricata/src/util-ip.h b/framework/src/suricata/src/util-ip.h deleted file mode 100644 index 25ffe9ec..00000000 --- a/framework/src/suricata/src/util-ip.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Duarte Silva - */ - -#ifndef __UTIL_IP_H__ -#define __UTIL_IP_H__ - -struct in_addr *ValidateIPV4Address(const char *); -struct in6_addr *ValidateIPV6Address(const char *); -void MaskIPNetblock(uint8_t *, int, int); - -#endif /* __UTIL_IP_H__ */ diff --git a/framework/src/suricata/src/util-logopenfile-tile.c b/framework/src/suricata/src/util-logopenfile-tile.c deleted file mode 100644 index c2414fc4..00000000 --- a/framework/src/suricata/src/util-logopenfile-tile.c +++ /dev/null @@ -1,370 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Tom DeCanio - * \author Ken Steele, Tilera Corporation - * - * File-like output for logging on Tilera PCIe cards (TILEncore-Gx) - * add the option to send logs across PCIe and then write the output - * files on the host system. - * - */ -#include - -#include "suricata-common.h" /* errno.h, string.h, etc. */ -#include "tm-modules.h" /* LogFileCtx */ -#include "conf.h" /* ConfNode, etc. */ -#include "util-atomic.h" -#include "util-logopenfile-tile.h" - -#ifdef __tile__ -#include -#include - -#if MDE_VERSION_CODE >= MDE_VERSION(4,1,0) -#include -#else -#include -#endif - -/* - * Tilera trio (PCIe) configuration. - */ -static gxio_trio_context_t trio_context_body; -static gxio_trio_context_t* trio_context = &trio_context_body; -/* - * gxpci contexts used for log relay - */ -static gxpci_context_t gxpci_context_body; -static gxpci_context_t *gxpci_context = &gxpci_context_body; -/* The TRIO index. */ -static int trio_index = 0; - -/* The queue index of a packet queue. */ -static unsigned int queue_index = 0; - -/* The local PCIe MAC index. */ -static int loc_mac; - -/* - * Code for writing files over PCIe to host on Tilera TILEncore PCIe cards. - */ - -#define OP_OPEN 1 -#define OP_WRITE 2 -#define OP_CLOSE 3 - -/** Maximum number of commands in one PCIe function call */ -#define MAX_CMDS_BATCH 64 - -typedef struct { - uint32_t magic; - uint32_t fileno; - uint32_t op; - uint32_t seq; - uint32_t len; - uint32_t next_offset; - char buf[]; -} __attribute__((__packed__)) PcieMsg; - -static int gxpci_fileno = 0; -static int pcie_initialized = 0; -/* Allocate a Huge page of memory, registered with Trio, into which - data to be sent over PCIe is written. Each write starts at wc_pos. -*/ -static char *log_mem = NULL; -static uint64_t wr_pos; /* write position within log_mem */ - -static SCMutex raw_mutex __attribute__((aligned(64))); -static SCMutex pcie_mutex __attribute__((aligned(64))); -#define CHECK_SEQ_NUM 1 -#ifdef CHECK_SEQ_NUM -static uint32_t raw_seq = 0; -#endif -static uint32_t comps_rcvd = 0; -/* Block of memory registered with PCIe DMA engine as a source for - * PCIe data transfers. Must be <= Huge Page size (16 MB). - * Must be large enough that it can't wrap before first PCIe transfer - * has completed. - */ -#define PCIE_MEMORY_BLOCK_SIZE (4 * 1024 * 1024) - -/* Send a buffer over PCIe to Host memory. - * len must be smaller than one Packet Queue transfer block. - * TODO: Check errors - */ -static void TilePcieDMABuf(void *buf, uint32_t len) -{ - gxpci_comp_t comp[MAX_CMDS_BATCH]; - gxpci_cmd_t cmd; - int result; - int credits; - - SCMutexLock(&pcie_mutex); - -#ifdef CHECK_SEQ_NUM - ((PcieMsg *)buf)->seq = ++raw_seq; - __insn_mf(); -#endif - - /* Wait for credits to be available for more PCIe writes. */ - do { - result = gxpci_get_comps(gxpci_context, comp, 0, MAX_CMDS_BATCH); - if (result) { - if (unlikely(result == GXPCI_ERESET)) { - SCLogInfo("gxpci channel is reset"); - return; - } else { - __sync_fetch_and_add(&comps_rcvd, result); - } - } - - credits = gxpci_get_cmd_credits(gxpci_context); - if (unlikely(credits == GXPCI_ERESET)) { - SCLogInfo("gxpci channel is reset"); - return; - } - } while (credits == 0); - - cmd.buffer = buf; - /* Round transfer size up to next host cache-line. This will - * transfer more data, but is more efficient. - */ - cmd.size = (len + (CLS - 1)) & ~(CLS - 1); - - __insn_mf(); - - /* Loop until the command is sent. */ - do { - /* Send PCIe command to packet queue from tile to host. */ - result = gxpci_pq_t2h_cmd(gxpci_context, &cmd); - if (result == 0) - break; - if (result == GXPCI_ERESET) { - SCLogInfo("gxpci channel is reset"); - break; - } - /* Not enough credits to send command? */ - if (result == GXPCI_ECREDITS) - continue; - } while (1); - - SCMutexUnlock(&pcie_mutex); -} - -/* Allocate a buffer for data that can be sent over PCIe. Reserves - * space at the beginning for the Pcie msg. The buffer is allocated - * from a 4MB pool on one huge page. The allocation simply walks - * throught the buffer sequentially. This removes the need to free - * the buffers, as they simply age out. - */ -static PcieMsg *TilePcieAllocateBuffer(size_t size) -{ - size += sizeof(PcieMsg); - /* Round up to cache-line size */ - size = (size + (CLS - 1)) & ~(CLS - 1); - - PcieMsg *pmsg; - SCMutexLock(&raw_mutex); - pmsg = (PcieMsg *)&log_mem[wr_pos]; - wr_pos += size; - if (wr_pos > PCIE_MEMORY_BLOCK_SIZE) { - /* Don't have enough space at the end of the memory block, so - * wrap to the start. - */ - pmsg = (PcieMsg *)&log_mem[0]; - wr_pos = size; - - } - SCMutexUnlock(&raw_mutex); - - return pmsg; -} - -static void PcieWriteOpen(PcieFile *fp, const char *path, const char append) -{ - /* Need space for file name, file mode character and string termination */ - const int buffer_size = strlen(path) + 2; - - /* Allocate space in the PCIe output buffer */ - PcieMsg *p = TilePcieAllocateBuffer(buffer_size); - - p->magic = 5555; - p->fileno = fp->fileno; - p->op = OP_OPEN; - p->len = offsetof(PcieMsg, buf); - /* Format is one character Mode, followed by file path. */ - p->len += snprintf(p->buf, buffer_size, "%c%s", append, path); - - TilePcieDMABuf(p, p->len); -} - -static int TilePcieWrite(const char *buffer, int buffer_len, LogFileCtx *log_ctx) -{ - PcieFile *fp = log_ctx->pcie_fp; - /* Allocate space in the PCIe output buffer */ - PcieMsg *p = TilePcieAllocateBuffer(buffer_len); - - p->magic = 5555; - p->fileno = fp->fileno; - p->op = OP_WRITE; - p->len = offsetof(PcieMsg, buf); - p->len += buffer_len; - p->next_offset = 0; - - /* Can remove the need for this memcpy later. */ - memcpy(p->buf, buffer, buffer_len); - - TilePcieDMABuf(p, p->len); - - return buffer_len; -} - -static PcieFile *TileOpenPcieFpInternal(const char *path, const char append_char) -{ - int result; - PcieFile *fp; - - /* Only initialize once */ - if (SCAtomicCompareAndSwap(&pcie_initialized, 0, 1)) { - SCMutexInit(&raw_mutex, NULL); - SCMutexInit(&pcie_mutex, NULL); - - SCLogInfo("Initializing Tile-Gx PCIe index %d / %d, queue: %d", - trio_index, loc_mac, queue_index); - - result = gxio_trio_init(trio_context, trio_index); - if (result < 0) { - pcie_initialized = 0; - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "gxio_trio_init() failed: %d: %s", - result, gxio_strerror(result)); - return NULL; - } - - result = gxpci_init(trio_context, gxpci_context, trio_index, loc_mac); - if (result < 0) { - pcie_initialized = 0; - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "gxpci_init() failed: %d: %s", - result, gxpci_strerror(result)); - return NULL; - } - - /* - * This indicates that we need to allocate an ASID ourselves, - * instead of using one that is allocated somewhere else. - */ - int asid = GXIO_ASID_NULL; - - result = gxpci_open_queue(gxpci_context, asid, GXPCI_PQ_T2H, 0, - queue_index, 0, 0); - if (result < 0) { - pcie_initialized = 0; - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "gxpci_open_queue() failed: %d: %s", - result, gxpci_strerror(result)); - return NULL; - } - - /* - * Allocate and register data buffer - */ - size_t hugepagesz = tmc_alloc_get_huge_pagesize(); - tmc_alloc_t alloc = TMC_ALLOC_INIT; - tmc_alloc_set_huge(&alloc); - tmc_alloc_set_home(&alloc, TMC_ALLOC_HOME_HASH); - tmc_alloc_set_pagesize_exact(&alloc, hugepagesz); - log_mem = tmc_alloc_map(&alloc, hugepagesz); - BUG_ON(PCIE_MEMORY_BLOCK_SIZE > hugepagesz); - - result = gxpci_iomem_register(gxpci_context, log_mem, hugepagesz); - if (result < 0) { - pcie_initialized = 0; - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "gxpci_iomem_register() failed: %d: %s", - result, gxpci_strerror(result)); - return NULL; - } - } - fp = SCMalloc(sizeof(PcieFile)); - if (fp == NULL) { - SCLogError(SC_ERR_PCIE_INIT_FAILED, - "Failed to Allocate memory for PCIe file pointer"); - - return NULL; - } - - /* Sequentially allocate File descriptor numbers. Not currently ever freed */ - fp->fileno = SCAtomicFetchAndAdd(&gxpci_fileno, 1); - PcieWriteOpen(fp, path, append_char); - - return fp; -} - -/** \brief Close a PCIe file - * \param PCIe file desriptor - */ -static void TileClosePcieFp(LogFileCtx *log_ctx) -{ - SCLogInfo("Closing Tile-Gx PCIe: %s", log_ctx->filename); - - /* TODO: Need to count open files and close when reaches zero. */ - SCMutexLock(&pcie_mutex); - - if (gxpci_context) { - gxpci_destroy(gxpci_context); - gxpci_context = NULL; - } - - SCMutexUnlock(&pcie_mutex); - - free(log_ctx->pcie_fp); -} - -/** \brief open the indicated file remotely over PCIe to a host - * \param path filesystem path to open - * \param append_setting open file with O_APPEND: "yes" or "no" - * \retval FILE* on success - * \retval NULL on error - */ -PcieFile *TileOpenPcieFp(LogFileCtx *log_ctx, const char *path, - const char *append_setting) -{ - PcieFile *ret = NULL; - if (strcasecmp(append_setting, "yes") == 0) { - ret = TileOpenPcieFpInternal(path, 'a'); - } else { - ret = TileOpenPcieFpInternal(path, 'w'); - } - - /* Override the default Write and Close functions - * with PCIe Write and Close functions. - */ - log_ctx->Write = TilePcieWrite; - log_ctx->Close = TileClosePcieFp; - - if (ret == NULL) - SCLogError(SC_ERR_FOPEN, "Error opening PCIe file: \"%s\": %s", - path, strerror(errno)); - return ret; -} - -#endif /* __tilegx__ */ diff --git a/framework/src/suricata/src/util-logopenfile-tile.h b/framework/src/suricata/src/util-logopenfile-tile.h deleted file mode 100644 index 4d1ac657..00000000 --- a/framework/src/suricata/src/util-logopenfile-tile.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ken Steele, Tilera Corporation - */ - -#ifndef __UTIL_LOGOPENFILE_TILE_H__ -#define __UTIL_LOGOPENFILE_TILE_H__ - -#include "util-logopenfile.h" /* LogFileCtx */ - -PcieFile *TileOpenPcieFp(LogFileCtx *log_ctx, const char *path, - const char *append_setting); - -#endif /* __UTIL_LOGOPENFILE_TILE_H__ */ diff --git a/framework/src/suricata/src/util-logopenfile.c b/framework/src/suricata/src/util-logopenfile.c deleted file mode 100644 index 84e5d2fe..00000000 --- a/framework/src/suricata/src/util-logopenfile.c +++ /dev/null @@ -1,646 +0,0 @@ -/* vi: set et ts=4: */ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Mike Pomraning - * - * File-like output for logging: regular files and sockets. - */ -#include -#include -#include - -#include "suricata-common.h" /* errno.h, string.h, etc. */ -#include "tm-modules.h" /* LogFileCtx */ -#include "conf.h" /* ConfNode, etc. */ -#include "output.h" /* DEFAULT_LOG_* */ -#include "util-logopenfile.h" -#include "util-logopenfile-tile.h" - -const char * redis_push_cmd = "LPUSH"; -const char * redis_publish_cmd = "PUBLISH"; - -/** \brief connect to the indicated local stream socket, logging any errors - * \param path filesystem path to connect to - * \param log_err, non-zero if connect failure should be logged. - * \retval FILE* on success (fdopen'd wrapper of underlying socket) - * \retval NULL on error - */ -static FILE * -SCLogOpenUnixSocketFp(const char *path, int sock_type, int log_err) -{ - struct sockaddr_un sun; - int s = -1; - FILE * ret = NULL; - - memset(&sun, 0x00, sizeof(sun)); - - s = socket(PF_UNIX, sock_type, 0); - if (s < 0) goto err; - - sun.sun_family = AF_UNIX; - strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); - - if (connect(s, (const struct sockaddr *)&sun, sizeof(sun)) < 0) - goto err; - - ret = fdopen(s, "w"); - if (ret == NULL) - goto err; - - return ret; - -err: - if (log_err) - SCLogWarning(SC_ERR_SOCKET, - "Error connecting to socket \"%s\": %s (will keep trying)", - path, strerror(errno)); - - if (s >= 0) - close(s); - - return NULL; -} - -/** - * \brief Attempt to reconnect a disconnected (or never-connected) Unix domain socket. - * \retval 1 if it is now connected; otherwise 0 - */ -static int SCLogUnixSocketReconnect(LogFileCtx *log_ctx) -{ - int disconnected = 0; - if (log_ctx->fp) { - SCLogWarning(SC_ERR_SOCKET, - "Write error on Unix socket \"%s\": %s; reconnecting...", - log_ctx->filename, strerror(errno)); - fclose(log_ctx->fp); - log_ctx->fp = NULL; - log_ctx->reconn_timer = 0; - disconnected = 1; - } - - struct timeval tv; - uint64_t now; - gettimeofday(&tv, NULL); - now = (uint64_t)tv.tv_sec * 1000; - now += tv.tv_usec / 1000; /* msec resolution */ - if (log_ctx->reconn_timer != 0 && - (now - log_ctx->reconn_timer) < LOGFILE_RECONN_MIN_TIME) { - /* Don't bother to try reconnecting too often. */ - return 0; - } - log_ctx->reconn_timer = now; - - log_ctx->fp = SCLogOpenUnixSocketFp(log_ctx->filename, log_ctx->sock_type, 0); - if (log_ctx->fp) { - /* Connected at last (or reconnected) */ - SCLogNotice("Reconnected socket \"%s\"", log_ctx->filename); - } else if (disconnected) { - SCLogWarning(SC_ERR_SOCKET, "Reconnect failed: %s (will keep trying)", - strerror(errno)); - } - - return log_ctx->fp ? 1 : 0; -} - -/** - * \brief Write buffer to log file. - * \retval 0 on failure; otherwise, the return value of fwrite (number of - * characters successfully written). - */ -static int SCLogFileWrite(const char *buffer, int buffer_len, LogFileCtx *log_ctx) -{ - /* Check for rotation. */ - if (log_ctx->rotation_flag) { - log_ctx->rotation_flag = 0; - SCConfLogReopen(log_ctx); - } - - int ret = 0; - - if (log_ctx->fp == NULL && log_ctx->is_sock) - SCLogUnixSocketReconnect(log_ctx); - - if (log_ctx->fp) { - clearerr(log_ctx->fp); - ret = fwrite(buffer, buffer_len, 1, log_ctx->fp); - fflush(log_ctx->fp); - - if (ferror(log_ctx->fp) && log_ctx->is_sock) { - /* Error on Unix socket, maybe needs reconnect */ - if (SCLogUnixSocketReconnect(log_ctx)) { - ret = fwrite(buffer, buffer_len, 1, log_ctx->fp); - fflush(log_ctx->fp); - } - } - } - - return ret; -} - -static void SCLogFileClose(LogFileCtx *log_ctx) -{ - if (log_ctx->fp) - fclose(log_ctx->fp); -} - -/** \brief open the indicated file, logging any errors - * \param path filesystem path to open - * \param append_setting open file with O_APPEND: "yes" or "no" - * \retval FILE* on success - * \retval NULL on error - */ -static FILE * -SCLogOpenFileFp(const char *path, const char *append_setting) -{ - FILE *ret = NULL; - - if (strcasecmp(append_setting, "yes") == 0) { - ret = fopen(path, "a"); - } else { - ret = fopen(path, "w"); - } - - if (ret == NULL) - SCLogError(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", - path, strerror(errno)); - return ret; -} - -/** \brief open the indicated file remotely over PCIe to a host - * \param path filesystem path to open - * \param append_setting open file with O_APPEND: "yes" or "no" - * \retval FILE* on success - * \retval NULL on error - */ -static PcieFile *SCLogOpenPcieFp(LogFileCtx *log_ctx, const char *path, - const char *append_setting) -{ -#ifndef __tile__ - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, - "PCIe logging only supported on Tile-Gx Architecture."); - return NULL; -#else - return TileOpenPcieFp(log_ctx, path, append_setting); -#endif -} - -/** \brief open a generic output "log file", which may be a regular file or a socket - * \param conf ConfNode structure for the output section in question - * \param log_ctx Log file context allocated by caller - * \param default_filename Default name of file to open, if not specified in ConfNode - * \param rotate Register the file for rotation in HUP. - * \retval 0 on success - * \retval -1 on error - */ -int -SCConfLogOpenGeneric(ConfNode *conf, - LogFileCtx *log_ctx, - const char *default_filename, - int rotate) -{ - char log_path[PATH_MAX]; - char *log_dir; - const char *filename, *filetype; - - // Arg check - if (conf == NULL || log_ctx == NULL || default_filename == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "SCConfLogOpenGeneric(conf %p, ctx %p, default %p) " - "missing an argument", - conf, log_ctx, default_filename); - return -1; - } - if (log_ctx->fp != NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "SCConfLogOpenGeneric: previously initialized Log CTX " - "encountered"); - return -1; - } - - // Resolve the given config - filename = ConfNodeLookupChildValue(conf, "filename"); - if (filename == NULL) - filename = default_filename; - - log_dir = ConfigGetLogDirectory(); - - if (PathIsAbsolute(filename)) { - snprintf(log_path, PATH_MAX, "%s", filename); - } else { - snprintf(log_path, PATH_MAX, "%s/%s", log_dir, filename); - } - - filetype = ConfNodeLookupChildValue(conf, "filetype"); - if (filetype == NULL) - filetype = DEFAULT_LOG_FILETYPE; - - const char *append = ConfNodeLookupChildValue(conf, "append"); - if (append == NULL) - append = DEFAULT_LOG_MODE_APPEND; - - // Now, what have we been asked to open? - if (strcasecmp(filetype, "unix_stream") == 0) { - /* Don't bail. May be able to connect later. */ - log_ctx->is_sock = 1; - log_ctx->sock_type = SOCK_STREAM; - log_ctx->fp = SCLogOpenUnixSocketFp(log_path, SOCK_STREAM, 1); - } else if (strcasecmp(filetype, "unix_dgram") == 0) { - /* Don't bail. May be able to connect later. */ - log_ctx->is_sock = 1; - log_ctx->sock_type = SOCK_DGRAM; - log_ctx->fp = SCLogOpenUnixSocketFp(log_path, SOCK_DGRAM, 1); - } else if (strcasecmp(filetype, DEFAULT_LOG_FILETYPE) == 0 || - strcasecmp(filetype, "file") == 0) { - log_ctx->fp = SCLogOpenFileFp(log_path, append); - if (log_ctx->fp == NULL) - return -1; // Error already logged by Open...Fp routine - log_ctx->is_regular = 1; - if (rotate) { - OutputRegisterFileRotationFlag(&log_ctx->rotation_flag); - } - } else if (strcasecmp(filetype, "pcie") == 0) { - log_ctx->pcie_fp = SCLogOpenPcieFp(log_ctx, log_path, append); - if (log_ctx->pcie_fp == NULL) - return -1; // Error already logged by Open...Fp routine - } else { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for " - "%s.filetype. Expected \"regular\" (default), \"unix_stream\", " - "\"pcie\" " - "or \"unix_dgram\"", - conf->name); - } - log_ctx->filename = SCStrdup(log_path); - if (unlikely(log_ctx->filename == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, - "Failed to allocate memory for filename"); - return -1; - } - - SCLogInfo("%s output device (%s) initialized: %s", conf->name, filetype, - filename); - - return 0; -} - -/** - * \brief Reopen a regular log file with the side-affect of truncating it. - * - * This is useful to clear the log file and start a new one, or to - * re-open the file after its been moved by something external - * (eg. logrotate). - */ -int SCConfLogReopen(LogFileCtx *log_ctx) -{ - if (!log_ctx->is_regular) { - /* Not supported and not needed on non-regular files. */ - return 0; - } - - if (log_ctx->filename == NULL) { - SCLogWarning(SC_ERR_INVALID_ARGUMENT, - "Can't re-open LogFileCtx without a filename."); - return -1; - } - - fclose(log_ctx->fp); - - /* Reopen the file. Append is forced in case the file was not - * moved as part of a rotation process. */ - SCLogDebug("Reopening log file %s.", log_ctx->filename); - log_ctx->fp = SCLogOpenFileFp(log_ctx->filename, "yes"); - if (log_ctx->fp == NULL) { - return -1; // Already logged by Open..Fp routine. - } - - return 0; -} - - -#ifdef HAVE_LIBHIREDIS - -static void SCLogFileCloseRedis(LogFileCtx *log_ctx) -{ - if (log_ctx->redis) { - redisReply *reply; - int i; - for (i = 0; i < log_ctx->redis_setup.batch_count; i++) { - redisGetReply(log_ctx->redis, (void **)&reply); - if (reply) - freeReplyObject(reply); - } - redisFree(log_ctx->redis); - log_ctx->redis = NULL; - } - log_ctx->redis_setup.tried = 0; - log_ctx->redis_setup.batch_count = 0; -} - -int SCConfLogOpenRedis(ConfNode *redis_node, LogFileCtx *log_ctx) -{ - const char *redis_server = NULL; - const char *redis_port = NULL; - const char *redis_mode = NULL; - const char *redis_key = NULL; - - if (redis_node) { - redis_server = ConfNodeLookupChildValue(redis_node, "server"); - redis_port = ConfNodeLookupChildValue(redis_node, "port"); - redis_mode = ConfNodeLookupChildValue(redis_node, "mode"); - redis_key = ConfNodeLookupChildValue(redis_node, "key"); - } - if (!redis_server) { - redis_server = "127.0.0.1"; - SCLogInfo("Using default redis server (127.0.0.1)"); - } - if (!redis_port) - redis_port = "6379"; - if (!redis_mode) - redis_mode = "list"; - if (!redis_key) - redis_key = "suricata"; - log_ctx->redis_setup.key = SCStrdup(redis_key); - - if (!log_ctx->redis_setup.key) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate redis key name"); - exit(EXIT_FAILURE); - } - - log_ctx->redis_setup.batch_size = 0; - - ConfNode *pipelining = ConfNodeLookupChild(redis_node, "pipelining"); - if (pipelining) { - int enabled = 0; - int ret; - intmax_t val; - ret = ConfGetChildValueBool(pipelining, "enabled", &enabled); - if (ret && enabled) { - ret = ConfGetChildValueInt(pipelining, "batch-size", &val); - if (ret) { - log_ctx->redis_setup.batch_size = val; - } else { - log_ctx->redis_setup.batch_size = 10; - } - } - } - - if (!strcmp(redis_mode, "list")) { - log_ctx->redis_setup.command = redis_push_cmd; - if (!log_ctx->redis_setup.command) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate redis key command"); - exit(EXIT_FAILURE); - } - } else { - log_ctx->redis_setup.command = redis_publish_cmd; - if (!log_ctx->redis_setup.command) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate redis key command"); - exit(EXIT_FAILURE); - } - } - redisContext *c = redisConnect(redis_server, atoi(redis_port)); - if (c != NULL && c->err) { - SCLogError(SC_ERR_SOCKET, "Error connecting to redis server: %s", c->errstr); - exit(EXIT_FAILURE); - } - - /* store server params for reconnection */ - log_ctx->redis_setup.server = SCStrdup(redis_server); - if (!log_ctx->redis_setup.server) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating redis server string"); - exit(EXIT_FAILURE); - } - log_ctx->redis_setup.port = atoi(redis_port); - log_ctx->redis_setup.tried = 0; - - log_ctx->redis = c; - - log_ctx->Close = SCLogFileCloseRedis; - - return 0; -} - -int SCConfLogReopenRedis(LogFileCtx *log_ctx) -{ - if (log_ctx->redis != NULL) { - redisFree(log_ctx->redis); - log_ctx->redis = NULL; - } - - /* only try to reconnect once per second */ - if (log_ctx->redis_setup.tried >= time(NULL)) { - return -1; - } - - redisContext *c = redisConnect(log_ctx->redis_setup.server, log_ctx->redis_setup.port); - if (c != NULL && c->err) { - if (log_ctx->redis_setup.tried == 0) { - SCLogError(SC_ERR_SOCKET, "Error connecting to redis server: %s\n", c->errstr); - } - redisFree(c); - log_ctx->redis_setup.tried = time(NULL); - return -1; - } - log_ctx->redis = c; - log_ctx->redis_setup.tried = 0; - log_ctx->redis_setup.batch_count = 0; - return 0; -} - -#endif - -/** \brief LogFileNewCtx() Get a new LogFileCtx - * \retval LogFileCtx * pointer if succesful, NULL if error - * */ -LogFileCtx *LogFileNewCtx(void) -{ - LogFileCtx* lf_ctx; - lf_ctx = (LogFileCtx*)SCMalloc(sizeof(LogFileCtx)); - - if (lf_ctx == NULL) - return NULL; - memset(lf_ctx, 0, sizeof(LogFileCtx)); - - SCMutexInit(&lf_ctx->fp_mutex,NULL); - - // Default Write and Close functions - lf_ctx->Write = SCLogFileWrite; - lf_ctx->Close = SCLogFileClose; - -#ifdef HAVE_LIBHIREDIS - lf_ctx->redis_setup.batch_count = 0; -#endif - - return lf_ctx; -} - -/** \brief LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory) - * \param motcx pointer to the OutputCtx - * \retval int 1 if succesful, 0 if error - * */ -int LogFileFreeCtx(LogFileCtx *lf_ctx) -{ - if (lf_ctx == NULL) { - SCReturnInt(0); - } - - if (lf_ctx->fp != NULL) { - SCMutexLock(&lf_ctx->fp_mutex); - lf_ctx->Close(lf_ctx); - SCMutexUnlock(&lf_ctx->fp_mutex); - } - -#ifdef HAVE_LIBHIREDIS - if (lf_ctx->type == LOGFILE_TYPE_REDIS) { - if (lf_ctx->redis) - redisFree(lf_ctx->redis); - if (lf_ctx->redis_setup.server) - SCFree(lf_ctx->redis_setup.server); - if (lf_ctx->redis_setup.key) - SCFree(lf_ctx->redis_setup.key); - } -#endif - - SCMutexDestroy(&lf_ctx->fp_mutex); - - if (lf_ctx->prefix != NULL) { - SCFree(lf_ctx->prefix); - lf_ctx->prefix_len = 0; - } - - if(lf_ctx->filename != NULL) - SCFree(lf_ctx->filename); - - if (lf_ctx->sensor_name) - SCFree(lf_ctx->sensor_name); - - OutputUnregisterFileRotationFlag(&lf_ctx->rotation_flag); - - SCFree(lf_ctx); - - SCReturnInt(1); -} - -#ifdef HAVE_LIBHIREDIS -static int LogFileWriteRedis(LogFileCtx *file_ctx, char *string, size_t string_len) -{ - if (file_ctx->redis == NULL) { - SCConfLogReopenRedis(file_ctx); - if (file_ctx->redis == NULL) { - return -1; - } else { - SCLogInfo("Reconnected to redis server"); - } - } - /* TODO go async here ? */ - if (file_ctx->redis_setup.batch_size) { - redisAppendCommand(file_ctx->redis, "%s %s %s", - file_ctx->redis_setup.command, - file_ctx->redis_setup.key, - string); - if (file_ctx->redis_setup.batch_count == file_ctx->redis_setup.batch_size) { - redisReply *reply; - int i; - file_ctx->redis_setup.batch_count = 0; - for (i = 0; i <= file_ctx->redis_setup.batch_size; i++) { - if (redisGetReply(file_ctx->redis, (void **)&reply) == REDIS_OK) { - freeReplyObject(reply); - } else { - if (file_ctx->redis->err) { - SCLogInfo("Error when fetching reply: %s (%d)", - file_ctx->redis->errstr, - file_ctx->redis->err); - } - switch (file_ctx->redis->err) { - case REDIS_ERR_EOF: - case REDIS_ERR_IO: - SCLogInfo("Reopening connection to redis server"); - SCConfLogReopenRedis(file_ctx); - if (file_ctx->redis) { - SCLogInfo("Reconnected to redis server"); - return 0; - } else { - SCLogInfo("Unable to reconnect to redis server"); - return 0; - } - break; - default: - SCLogWarning(SC_ERR_INVALID_VALUE, - "Unsupported error code %d", - file_ctx->redis->err); - return 0; - } - } - } - } else { - file_ctx->redis_setup.batch_count++; - } - } else { - redisReply *reply = redisCommand(file_ctx->redis, "%s %s %s", - file_ctx->redis_setup.command, - file_ctx->redis_setup.key, - string); - - switch (reply->type) { - case REDIS_REPLY_ERROR: - SCLogWarning(SC_ERR_SOCKET, "Redis error: %s", reply->str); - SCConfLogReopenRedis(file_ctx); - break; - case REDIS_REPLY_INTEGER: - SCLogDebug("Redis integer %lld", reply->integer); - break; - default: - SCLogError(SC_ERR_INVALID_VALUE, - "Redis default triggered with %d", reply->type); - SCConfLogReopenRedis(file_ctx); - break; - } - freeReplyObject(reply); - } - return 0; -} -#endif - -int LogFileWrite(LogFileCtx *file_ctx, MemBuffer *buffer) -{ - if (file_ctx->type == LOGFILE_TYPE_SYSLOG) { - syslog(file_ctx->syslog_setup.alert_syslog_level, "%s", - (const char *)MEMBUFFER_BUFFER(buffer)); - } else if (file_ctx->type == LOGFILE_TYPE_FILE || - file_ctx->type == LOGFILE_TYPE_UNIX_DGRAM || - file_ctx->type == LOGFILE_TYPE_UNIX_STREAM) - { - /* append \n for files only */ - MemBufferWriteString(buffer, "\n"); - SCMutexLock(&file_ctx->fp_mutex); - file_ctx->Write((const char *)MEMBUFFER_BUFFER(buffer), - MEMBUFFER_OFFSET(buffer), file_ctx); - SCMutexUnlock(&file_ctx->fp_mutex); - } -#ifdef HAVE_LIBHIREDIS - else if (file_ctx->type == LOGFILE_TYPE_REDIS) { - SCMutexLock(&file_ctx->fp_mutex); - LogFileWriteRedis(file_ctx, (const char *)MEMBUFFER_BUFFER(buffer), - MEMBUFFER_OFFSET(buffer)); - SCMutexUnlock(&file_ctx->fp_mutex); - } -#endif - - return 0; -} diff --git a/framework/src/suricata/src/util-logopenfile.h b/framework/src/suricata/src/util-logopenfile.h deleted file mode 100644 index cccbba47..00000000 --- a/framework/src/suricata/src/util-logopenfile.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Mike Pomraning - */ - -#ifndef __UTIL_LOGOPENFILE_H__ -#define __UTIL_LOGOPENFILE_H__ - -#include "conf.h" /* ConfNode */ -#include "tm-modules.h" /* LogFileCtx */ -#include "util-buffer.h" - -#ifdef HAVE_LIBHIREDIS -#include "hiredis/hiredis.h" -#endif - -typedef struct { - uint16_t fileno; -} PcieFile; - -enum LogFileType { LOGFILE_TYPE_FILE, - LOGFILE_TYPE_SYSLOG, - LOGFILE_TYPE_UNIX_DGRAM, - LOGFILE_TYPE_UNIX_STREAM, - LOGFILE_TYPE_REDIS }; - -typedef struct SyslogSetup_ { - int alert_syslog_level; -} SyslogSetup; - -#ifdef HAVE_LIBHIREDIS -enum RedisMode { REDIS_LIST, REDIS_CHANNEL }; - -typedef struct RedisSetup_ { - enum RedisMode mode; - const char *command; - char *key; - int batch_size; - int batch_count; - char *server; - int port; - time_t tried; -} RedisSetup; -#endif - -/** Global structure for Output Context */ -typedef struct LogFileCtx_ { - union { - FILE *fp; - PcieFile *pcie_fp; -#ifdef HAVE_LIBHIREDIS - redisContext *redis; -#endif - }; - - union { - SyslogSetup syslog_setup; -#ifdef HAVE_LIBHIREDIS - RedisSetup redis_setup; -#endif - }; - - int (*Write)(const char *buffer, int buffer_len, struct LogFileCtx_ *fp); - void (*Close)(struct LogFileCtx_ *fp); - - /** It will be locked if the log/alert - * record cannot be written to the file in one call */ - SCMutex fp_mutex; - - /** the type of file */ - enum LogFileType type; - - /** The name of the file */ - char *filename; - - /** Suricata sensor name */ - char *sensor_name; - - /** Handle auto-connecting / reconnecting sockets */ - int is_sock; - int sock_type; - uint64_t reconn_timer; - - /**< Used by some alert loggers like the unified ones that append - * the date onto the end of files. */ - char *prefix; - size_t prefix_len; - - /** Generic size_limit and size_current - * They must be common to the threads accesing the same file */ - uint64_t size_limit; /**< file size limit */ - uint64_t size_current; /**< file current size */ - - /* Alerts on the module (not on the file) */ - uint64_t alerts; - /* flag to avoid multiple threads printing the same stats */ - uint8_t flags; - - /* Flag if file is a regular file or not. Only regular files - * allow for rotataion. */ - uint8_t is_regular; - - /* Flag set when file rotation notification is received. */ - int rotation_flag; -} LogFileCtx; - -/* Min time (msecs) before trying to reconnect a Unix domain socket */ -#define LOGFILE_RECONN_MIN_TIME 500 - -/* flags for LogFileCtx */ -#define LOGFILE_HEADER_WRITTEN 0x01 -#define LOGFILE_ALERTS_PRINTED 0x02 - -LogFileCtx *LogFileNewCtx(void); -int LogFileFreeCtx(LogFileCtx *); -int LogFileWrite(LogFileCtx *file_ctx, MemBuffer *buffer); - -int SCConfLogOpenGeneric(ConfNode *conf, LogFileCtx *, const char *, int); -int SCConfLogOpenRedis(ConfNode *conf, LogFileCtx *log_ctx); -int SCConfLogReopen(LogFileCtx *); - -#endif /* __UTIL_LOGOPENFILE_H__ */ diff --git a/framework/src/suricata/src/util-lua-common.c b/framework/src/suricata/src/util-lua-common.c deleted file mode 100644 index 82013485..00000000 --- a/framework/src/suricata/src/util-lua-common.c +++ /dev/null @@ -1,772 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Common function for Lua Output - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer-htp.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#ifdef HAVE_LUA - -#include -#include -#include - -#include "util-lua.h" - -int LuaCallbackError(lua_State *luastate, const char *msg) -{ - lua_pushnil(luastate); - lua_pushstring(luastate, msg); - return 2; -} - -const char *LuaGetStringArgument(lua_State *luastate, int argc) -{ - /* get argument */ - if (!lua_isstring(luastate, argc)) - return NULL; - const char *str = lua_tostring(luastate, argc); - if (str == NULL) - return NULL; - if (strlen(str) == 0) - return NULL; - return str; -} - -void LuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value) -{ - lua_pushstring(luastate, key); - lua_pushnumber(luastate, value); - lua_settable(luastate, -3); -} - -/** \brief Push a key plus string value to the stack - * - * If value is NULL, string "(null")" will be put on the stack. - */ -void LuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value) -{ - lua_pushstring(luastate, key); - lua_pushstring(luastate, value ? value : "(null)"); - lua_settable(luastate, -3); -} - -void LuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len) -{ - lua_pushstring(luastate, key); - LuaPushStringBuffer(luastate, value, len); - lua_settable(luastate, -3); -} - -/** \internal - * \brief fill lua stack with payload - * \param luastate the lua state - * \param p packet - * \retval cnt number of data items placed on the stack - * - * Places: payload (string) - */ -static int LuaCallbackStreamingBufferPushToStack(lua_State *luastate, const LuaStreamingBuffer *b) -{ - //PrintRawDataFp(stdout, (uint8_t *)b->data, b->data_len); - lua_pushlstring (luastate, (const char *)b->data, b->data_len); - lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_OPEN)); - lua_pushboolean (luastate, (b->flags & OUTPUT_STREAMING_FLAG_CLOSE)); - return 3; -} - -/** \internal - * \brief Wrapper for getting payload into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackStreamingBuffer(lua_State *luastate) -{ - const LuaStreamingBuffer *b = LuaStateGetStreamingBuffer(luastate); - if (b == NULL) - return LuaCallbackError(luastate, "internal error: no buffer"); - - return LuaCallbackStreamingBufferPushToStack(luastate, b); -} - -/** \internal - * \brief fill lua stack with payload - * \param luastate the lua state - * \param p packet - * \retval cnt number of data items placed on the stack - * - * Places: payload (string) - */ -static int LuaCallbackPacketPayloadPushToStackFromPacket(lua_State *luastate, const Packet *p) -{ - lua_pushlstring (luastate, (const char *)p->payload, p->payload_len); - return 1; -} - -/** \internal - * \brief Wrapper for getting payload into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackPacketPayload(lua_State *luastate) -{ - const Packet *p = LuaStateGetPacket(luastate); - if (p == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackPacketPayloadPushToStackFromPacket(luastate, p); -} - -/** \internal - * \brief fill lua stack with header info - * \param luastate the lua state - * \param p packet - * \retval cnt number of data items placed on the stack - * - * Places: ts (string) - */ -static int LuaCallbackTimeStringPushToStackFromPacket(lua_State *luastate, const Packet *p) -{ - char timebuf[64]; - CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); - lua_pushstring (luastate, timebuf); - return 1; -} - -/** \internal - * \brief Wrapper for getting tuple info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackPacketTimeString(lua_State *luastate) -{ - const Packet *p = LuaStateGetPacket(luastate); - if (p == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackTimeStringPushToStackFromPacket(luastate, p); -} - -/** \internal - * \brief fill lua stack with time string - * \param luastate the lua state - * \param flow flow - * \retval cnt number of data items placed on the stack - * - * Places: ts (string) - */ -static int LuaCallbackTimeStringPushToStackFromFlow(lua_State *luastate, const Flow *flow) -{ - char timebuf[64]; - CreateTimeString(&flow->startts, timebuf, sizeof(timebuf)); - lua_pushstring (luastate, timebuf); - return 1; -} - -/** \internal - * \brief Wrapper for getting ts info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackFlowTimeString(lua_State *luastate) -{ - int r = 0; - int locked = 0; - Flow *flow = LuaStateGetFlow(luastate, &locked); - if (flow == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (locked == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(flow); - r = LuaCallbackTimeStringPushToStackFromFlow(luastate, flow); - FLOWLOCK_UNLOCK(flow); - } else { - r = LuaCallbackTimeStringPushToStackFromFlow(luastate, flow); - } - return r; -} - -/** \internal - * \brief fill lua stack with header info - * \param luastate the lua state - * \param p packet - * \retval cnt number of data items placed on the stack - * - * Places: ipver (number), src ip (string), dst ip (string), protocol (number), - * sp or icmp type (number), dp or icmp code (number). - */ -static int LuaCallbackTuplePushToStackFromPacket(lua_State *luastate, const Packet *p) -{ - int ipver = 0; - if (PKT_IS_IPV4(p)) { - ipver = 4; - } else if (PKT_IS_IPV6(p)) { - ipver = 6; - } - lua_pushnumber (luastate, ipver); - if (ipver == 0) - return 1; - - char srcip[46] = "", dstip[46] = ""; - if (PKT_IS_IPV4(p)) { - PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); - } else if (PKT_IS_IPV6(p)) { - PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); - } - - lua_pushstring (luastate, srcip); - lua_pushstring (luastate, dstip); - - /* proto and ports (or type/code) */ - lua_pushnumber (luastate, p->proto); - if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP) { - lua_pushnumber (luastate, p->sp); - lua_pushnumber (luastate, p->dp); - - } else if (p->proto == IPPROTO_ICMP || p->proto == IPPROTO_ICMPV6) { - lua_pushnumber (luastate, p->type); - lua_pushnumber (luastate, p->code); - } else { - lua_pushnumber (luastate, 0); - lua_pushnumber (luastate, 0); - } - - return 6; -} - -/** \internal - * \brief Wrapper for getting tuple info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackTuple(lua_State *luastate) -{ - const Packet *p = LuaStateGetPacket(luastate); - if (p == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackTuplePushToStackFromPacket(luastate, p); -} - -/** \internal - * \brief fill lua stack with header info - * \param luastate the lua state - * \param f flow, locked - * \retval cnt number of data items placed on the stack - * - * Places: ipver (number), src ip (string), dst ip (string), protocol (number), - * sp or icmp type (number), dp or icmp code (number). - */ -static int LuaCallbackTuplePushToStackFromFlow(lua_State *luastate, const Flow *f) -{ - int ipver = 0; - if (FLOW_IS_IPV4(f)) { - ipver = 4; - } else if (FLOW_IS_IPV6(f)) { - ipver = 6; - } - lua_pushnumber (luastate, ipver); - if (ipver == 0) - return 1; - - char srcip[46] = "", dstip[46] = ""; - if (FLOW_IS_IPV4(f)) { - PrintInet(AF_INET, (const void *)&(f->src.addr_data32[0]), srcip, sizeof(srcip)); - PrintInet(AF_INET, (const void *)&(f->dst.addr_data32[0]), dstip, sizeof(dstip)); - } else if (FLOW_IS_IPV6(f)) { - PrintInet(AF_INET6, (const void *)&(f->src.address), srcip, sizeof(srcip)); - PrintInet(AF_INET6, (const void *)&(f->dst.address), dstip, sizeof(dstip)); - } - - lua_pushstring (luastate, srcip); - lua_pushstring (luastate, dstip); - - /* proto and ports (or type/code) */ - lua_pushnumber (luastate, f->proto); - if (f->proto == IPPROTO_TCP || f->proto == IPPROTO_UDP) { - lua_pushnumber (luastate, f->sp); - lua_pushnumber (luastate, f->dp); - - } else if (f->proto == IPPROTO_ICMP || f->proto == IPPROTO_ICMPV6) { - lua_pushnumber (luastate, f->type); - lua_pushnumber (luastate, f->code); - } else { - lua_pushnumber (luastate, 0); - lua_pushnumber (luastate, 0); - } - - return 6; -} - -/** \internal - * \brief Wrapper for getting tuple info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackTupleFlow(lua_State *luastate) -{ - int r = 0; - int lock_hint = 0; - Flow *f = LuaStateGetFlow(luastate, &lock_hint); - if (f == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(f); - r = LuaCallbackTuplePushToStackFromFlow(luastate, f); - FLOWLOCK_UNLOCK(f); - } else { - r = LuaCallbackTuplePushToStackFromFlow(luastate, f); - } - return r; -} - -/** \internal - * \brief fill lua stack with AppLayerProto - * \param luastate the lua state - * \param f flow, locked - * \retval cnt number of data items placed on the stack - * - * Places: alproto as string (string) - */ -static int LuaCallbackAppLayerProtoPushToStackFromFlow(lua_State *luastate, const Flow *f) -{ - const char *string = AppProtoToString(f->alproto); - if (string == NULL) - string = "unknown"; - lua_pushstring(luastate, string); - return 1; -} - -/** \internal - * \brief Wrapper for getting AppLayerProto info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackAppLayerProtoFlow(lua_State *luastate) -{ - int r = 0; - int lock_hint = 0; - Flow *f = LuaStateGetFlow(luastate, &lock_hint); - if (f == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(f); - r = LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f); - FLOWLOCK_UNLOCK(f); - } else { - r = LuaCallbackAppLayerProtoPushToStackFromFlow(luastate, f); - } - return r; -} - -/** \internal - * \brief fill lua stack with flow stats - * \param luastate the lua state - * \param f flow, locked - * \retval cnt number of data items placed on the stack - * - * Places: ts pkts (number), ts bytes (number), tc pkts (number), tc bytes (number) - */ -static int LuaCallbackStatsPushToStackFromFlow(lua_State *luastate, const Flow *f) -{ - lua_pushnumber(luastate, f->todstpktcnt); - lua_pushnumber(luastate, f->todstbytecnt); - lua_pushnumber(luastate, f->tosrcpktcnt); - lua_pushnumber(luastate, f->tosrcbytecnt); - return 4; -} - -/** \internal - * \brief Wrapper for getting AppLayerProto info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackStatsFlow(lua_State *luastate) -{ - int r = 0; - int lock_hint = 0; - Flow *f = LuaStateGetFlow(luastate, &lock_hint); - if (f == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(f); - r = LuaCallbackStatsPushToStackFromFlow(luastate, f); - FLOWLOCK_UNLOCK(f); - } else { - r = LuaCallbackStatsPushToStackFromFlow(luastate, f); - } - return r; -} - -/** \internal - * \brief fill lua stack with alert info - * \param luastate the lua state - * \param pa pointer to packet alert struct - * \retval cnt number of data items placed on the stack - * - * Places: sid (number), rev (number), gid (number) - */ -static int LuaCallbackRuleIdsPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa) -{ - lua_pushnumber (luastate, pa->s->id); - lua_pushnumber (luastate, pa->s->rev); - lua_pushnumber (luastate, pa->s->gid); - return 3; -} - -/** \internal - * \brief Wrapper for getting tuple info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackRuleIds(lua_State *luastate) -{ - const PacketAlert *pa = LuaStateGetPacketAlert(luastate); - if (pa == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackRuleIdsPushToStackFromPacketAlert(luastate, pa); -} - -/** \internal - * \brief fill lua stack with alert info - * \param luastate the lua state - * \param pa pointer to packet alert struct - * \retval cnt number of data items placed on the stack - * - * Places: msg (string) - */ -static int LuaCallbackRuleMsgPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa) -{ - lua_pushstring (luastate, pa->s->msg); - return 1; -} - -/** \internal - * \brief Wrapper for getting tuple info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackRuleMsg(lua_State *luastate) -{ - const PacketAlert *pa = LuaStateGetPacketAlert(luastate); - if (pa == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackRuleMsgPushToStackFromPacketAlert(luastate, pa); -} - -/** \internal - * \brief fill lua stack with alert info - * \param luastate the lua state - * \param pa pointer to packet alert struct - * \retval cnt number of data items placed on the stack - * - * Places: class (string), prio (number) - */ -static int LuaCallbackRuleClassPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa) -{ - lua_pushstring (luastate, pa->s->class_msg); - lua_pushnumber (luastate, pa->s->prio); - return 2; -} - -/** \internal - * \brief Wrapper for getting tuple info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackRuleClass(lua_State *luastate) -{ - const PacketAlert *pa = LuaStateGetPacketAlert(luastate); - if (pa == NULL) - return LuaCallbackError(luastate, "internal error: no packet"); - - return LuaCallbackRuleClassPushToStackFromPacketAlert(luastate, pa); -} - -static int LuaCallbackLogPath(lua_State *luastate) -{ - const char *ld = ConfigGetLogDirectory(); - if (ld == NULL) - return LuaCallbackError(luastate, "internal error: no log dir"); - - return LuaPushStringBuffer(luastate, (const uint8_t *)ld, strlen(ld)); -} - -static int LuaCallbackLogDebug(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - SCLogDebug("%s", msg); - return 0; -} - -static int LuaCallbackLogInfo(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - SCLogInfo("%s", msg); - return 0; -} - -static int LuaCallbackLogNotice(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - SCLogNotice("%s", msg); - return 0; -} - -static int LuaCallbackLogWarning(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - SCLogWarning(SC_WARN_LUA_SCRIPT, "%s", msg); - return 0; -} - -static int LuaCallbackLogError(lua_State *luastate) -{ - const char *msg = LuaGetStringArgument(luastate, 1); - if (msg == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - SCLogError(SC_ERR_LUA_SCRIPT, "%s", msg); - return 0; -} - -/** \internal - * \brief fill lua stack with file info - * \param luastate the lua state - * \param pa pointer to packet alert struct - * \retval cnt number of data items placed on the stack - * - * Places: fileid (number), txid (number), name (string), - * size (number), magic (string), md5 in hex (string) - */ -static int LuaCallbackFileInfoPushToStackFromFile(lua_State *luastate, const File *file) -{ -#ifdef HAVE_NSS - char md5[33] = ""; - char *md5ptr = md5; - if (file->flags & FILE_MD5) { - size_t x; - for (x = 0; x < sizeof(file->md5); x++) { - char one[3] = ""; - snprintf(one, sizeof(one), "%02x", file->md5[x]); - strlcat(md5, one, sizeof(md5)); - } - } -#else - char *md5ptr = NULL; -#endif - - lua_pushnumber(luastate, file->file_id); - lua_pushnumber(luastate, file->txid); - lua_pushlstring(luastate, (char *)file->name, file->name_len); - lua_pushnumber(luastate, file->size); - lua_pushstring (luastate, file->magic); - lua_pushstring(luastate, md5ptr); - return 6; -} - -/** \internal - * \brief Wrapper for getting tuple info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackFileInfo(lua_State *luastate) -{ - const File *file = LuaStateGetFile(luastate); - if (file == NULL) - return LuaCallbackError(luastate, "internal error: no file"); - - return LuaCallbackFileInfoPushToStackFromFile(luastate, file); -} - -/** \internal - * \brief fill lua stack with file info - * \param luastate the lua state - * \param pa pointer to packet alert struct - * \retval cnt number of data items placed on the stack - * - * Places: state (string), stored (bool) - */ -static int LuaCallbackFileStatePushToStackFromFile(lua_State *luastate, const File *file) -{ - const char *state = "UNKNOWN"; - switch (file->state) { - case FILE_STATE_CLOSED: - state = "CLOSED"; - break; - case FILE_STATE_TRUNCATED: - state = "TRUNCATED"; - break; - case FILE_STATE_ERROR: - state = "ERROR"; - break; - } - - lua_pushstring (luastate, state); - lua_pushboolean (luastate, file->flags & FILE_STORED); - return 2; -} - -/** \internal - * \brief Wrapper for getting tuple info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackFileState(lua_State *luastate) -{ - const File *file = LuaStateGetFile(luastate); - if (file == NULL) - return LuaCallbackError(luastate, "internal error: no file"); - - return LuaCallbackFileStatePushToStackFromFile(luastate, file); -} - -/** \internal - * \brief fill lua stack with thread info - * \param luastate the lua state - * \param pa pointer to packet alert struct - * \retval cnt number of data items placed on the stack - * - * Places: thread id (number), thread name (string, thread group name (string) - */ -static int LuaCallbackThreadInfoPushToStackFromThreadVars(lua_State *luastate, const ThreadVars *tv) -{ - u_long tid = SCGetThreadIdLong(); - lua_pushinteger (luastate, (lua_Integer)tid); - lua_pushstring (luastate, tv->name); - lua_pushstring (luastate, tv->thread_group_name); - return 3; -} - -/** \internal - * \brief Wrapper for getting tuple info into a lua script - * \retval cnt number of items placed on the stack - */ -static int LuaCallbackThreadInfo(lua_State *luastate) -{ - const ThreadVars *tv = LuaStateGetThreadVars(luastate); - if (tv == NULL) - return LuaCallbackError(luastate, "internal error: no tv"); - - return LuaCallbackThreadInfoPushToStackFromThreadVars(luastate, tv); -} - -int LuaRegisterFunctions(lua_State *luastate) -{ - /* registration of the callbacks */ - lua_pushcfunction(luastate, LuaCallbackPacketPayload); - lua_setglobal(luastate, "SCPacketPayload"); - lua_pushcfunction(luastate, LuaCallbackPacketTimeString); - lua_setglobal(luastate, "SCPacketTimeString"); - lua_pushcfunction(luastate, LuaCallbackTuple); - lua_setglobal(luastate, "SCPacketTuple"); - - lua_pushcfunction(luastate, LuaCallbackFlowTimeString); - lua_setglobal(luastate, "SCFlowTimeString"); - lua_pushcfunction(luastate, LuaCallbackTupleFlow); - lua_setglobal(luastate, "SCFlowTuple"); - lua_pushcfunction(luastate, LuaCallbackAppLayerProtoFlow); - lua_setglobal(luastate, "SCFlowAppLayerProto"); - lua_pushcfunction(luastate, LuaCallbackStatsFlow); - lua_setglobal(luastate, "SCFlowStats"); - - lua_pushcfunction(luastate, LuaCallbackStreamingBuffer); - lua_setglobal(luastate, "SCStreamingBuffer"); - - lua_pushcfunction(luastate, LuaCallbackLogPath); - lua_setglobal(luastate, "SCLogPath"); - - lua_pushcfunction(luastate, LuaCallbackLogDebug); - lua_setglobal(luastate, "SCLogDebug"); - lua_pushcfunction(luastate, LuaCallbackLogInfo); - lua_setglobal(luastate, "SCLogInfo"); - lua_pushcfunction(luastate, LuaCallbackLogNotice); - lua_setglobal(luastate, "SCLogNotice"); - lua_pushcfunction(luastate, LuaCallbackLogWarning); - lua_setglobal(luastate, "SCLogWarning"); - lua_pushcfunction(luastate, LuaCallbackLogError); - lua_setglobal(luastate, "SCLogError"); - - - lua_pushcfunction(luastate, LuaCallbackRuleIds); - lua_setglobal(luastate, "SCRuleIds"); - lua_pushcfunction(luastate, LuaCallbackRuleMsg); - lua_setglobal(luastate, "SCRuleMsg"); - lua_pushcfunction(luastate, LuaCallbackRuleClass); - lua_setglobal(luastate, "SCRuleClass"); - - lua_pushcfunction(luastate, LuaCallbackFileInfo); - lua_setglobal(luastate, "SCFileInfo"); - lua_pushcfunction(luastate, LuaCallbackFileState); - lua_setglobal(luastate, "SCFileState"); - - lua_pushcfunction(luastate, LuaCallbackThreadInfo); - lua_setglobal(luastate, "SCThreadInfo"); - return 0; -} - -int LuaStateNeedProto(lua_State *luastate, AppProto alproto) -{ - AppProto flow_alproto = 0; - int locked = 0; - Flow *flow = LuaStateGetFlow(luastate, &locked); - if (flow == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (locked == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(flow); - flow_alproto = flow->alproto; - FLOWLOCK_UNLOCK(flow); - } else { - flow_alproto = flow->alproto; - } - - return (alproto == flow_alproto); - -} - -#endif /* HAVE_LUA */ diff --git a/framework/src/suricata/src/util-lua-common.h b/framework/src/suricata/src/util-lua-common.h deleted file mode 100644 index 2e0df287..00000000 --- a/framework/src/suricata/src/util-lua-common.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_LUA_COMMON_H__ -#define __UTIL_LUA_COMMON_H__ - -#ifdef HAVE_LUA - -int LuaCallbackError(lua_State *luastate, const char *msg); -const char *LuaGetStringArgument(lua_State *luastate, int argc); - -void LuaPushTableKeyValueInt(lua_State *luastate, const char *key, int value); -void LuaPushTableKeyValueString(lua_State *luastate, const char *key, const char *value); -void LuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len); - -int LuaRegisterFunctions(lua_State *luastate); - -int LuaStateNeedProto(lua_State *luastate, AppProto alproto); - -#endif /* HAVE_LUA */ - -#endif /* __UTIL_LUA_COMMON_H__ */ diff --git a/framework/src/suricata/src/util-lua-dns.c b/framework/src/suricata/src/util-lua-dns.c deleted file mode 100644 index dcebc6a1..00000000 --- a/framework/src/suricata/src/util-lua-dns.c +++ /dev/null @@ -1,321 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - - -/** - * \file - * - * \author Eric Leblond - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer-dns-common.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#ifdef HAVE_LUA - -#include -#include -#include - -#include "util-lua.h" -#include "util-lua-common.h" - -static int DnsGetDnsRrname(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - - DNSTransaction *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - DNSQueryEntry *query = NULL; - TAILQ_FOREACH(query, &tx->query_list, next) { - char *c; - size_t input_len; - c = BytesToString((uint8_t *)((uint8_t *)query + sizeof(DNSQueryEntry)), query->len); - if (c != NULL) { - int ret; - input_len = strlen(c); - /* sanity check */ - if (input_len > (size_t)(2 * query->len)) { - SCFree(c); - return LuaCallbackError(luastate, "invalid length"); - } - ret = LuaPushStringBuffer(luastate, (uint8_t *)c, input_len); - SCFree(c); - return ret; - } - } - - return LuaCallbackError(luastate, "no query"); -} - -static int DnsGetTxid(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - - DNSTransaction *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - lua_pushinteger(luastate, tx->tx_id); - return 1; -} - -static int DnsGetRcode(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - - DNSTransaction *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - if (tx->rcode) { - char rcode[16] = ""; - DNSCreateRcodeString(tx->rcode, rcode, sizeof(rcode)); - return LuaPushStringBuffer(luastate, (const uint8_t *)rcode, strlen(rcode)); - } else { - return 0; - } -} - -static int DnsGetRecursionDesired(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - - DNSTransaction *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - lua_pushboolean(luastate, tx->recursion_desired); - return 1; -} - -static int DnsGetQueryTable(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - - DNSTransaction *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - uint32_t u = 0; - lua_newtable(luastate); - DNSQueryEntry *query = NULL; - TAILQ_FOREACH(query, &tx->query_list, next) { - lua_pushinteger(luastate, u++); - - lua_newtable(luastate); - char record[16] = ""; - DNSCreateTypeString(query->type, record, sizeof(record)); - lua_pushstring(luastate, "type"); - lua_pushstring(luastate, record); - lua_settable(luastate, -3); - - { - char *c; - size_t input_len; - c = BytesToString((uint8_t *)((uint8_t *)query + sizeof(DNSQueryEntry)), query->len); - if (c != NULL) { - input_len = strlen(c); - /* sanity check */ - if (input_len > (size_t)(2 * query->len)) { - SCFree(c); - return LuaCallbackError(luastate, "invalid length"); - } - lua_pushstring(luastate, "rrname"); - LuaPushStringBuffer(luastate, (uint8_t *)c, input_len); - lua_settable(luastate, -3); - SCFree(c); - } - } - - - lua_settable(luastate, -3); - } - - return 1; -} - -static int DnsGetAnswerTable(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - - DNSTransaction *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - uint32_t u = 0; - lua_newtable(luastate); - DNSAnswerEntry *answer = NULL; - TAILQ_FOREACH(answer, &tx->answer_list, next) { - lua_pushinteger(luastate, u++); - - lua_newtable(luastate); - char record[16] = ""; - DNSCreateTypeString(answer->type, record, sizeof(record)); - lua_pushstring(luastate, "type"); - lua_pushstring(luastate, record); - lua_settable(luastate, -3); - - lua_pushstring(luastate, "ttl"); - lua_pushinteger(luastate, answer->ttl); - lua_settable(luastate, -3); - - { - uint8_t *ptr = (uint8_t *)((uint8_t *)answer + sizeof(DNSAnswerEntry)); - lua_pushstring(luastate, "rrname"); - LuaPushStringBuffer(luastate, ptr, answer->fqdn_len); - lua_settable(luastate, -3); - - ptr = (uint8_t *)((uint8_t *)answer + sizeof(DNSAnswerEntry) + answer->fqdn_len); - if (answer->type == DNS_RECORD_TYPE_A) { - char a[16] = ""; - PrintInet(AF_INET, (const void *)ptr, a, sizeof(a)); - lua_pushstring(luastate, "addr"); - LuaPushStringBuffer(luastate, (uint8_t *)a, strlen(a)); - lua_settable(luastate, -3); - } else if (answer->type == DNS_RECORD_TYPE_AAAA) { - char a[46]; - PrintInet(AF_INET6, (const void *)ptr, a, sizeof(a)); - lua_pushstring(luastate, "addr"); - LuaPushStringBuffer(luastate, (uint8_t *)a, strlen(a)); - lua_settable(luastate, -3); - } else if (answer->data_len == 0) { - /* not setting 'addr' */ - } else { - lua_pushstring(luastate, "addr"); - LuaPushStringBuffer(luastate, (uint8_t *)ptr, answer->data_len); - lua_settable(luastate, -3); - } - } - - lua_settable(luastate, -3); - } - - return 1; -} - -static int DnsGetAuthorityTable(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_DNS))) - return LuaCallbackError(luastate, "error: protocol not dns"); - - DNSTransaction *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - uint32_t u = 0; - lua_newtable(luastate); - DNSAnswerEntry *answer = NULL; - TAILQ_FOREACH(answer, &tx->authority_list, next) { - lua_pushinteger(luastate, u++); - - lua_newtable(luastate); - char record[16] = ""; - DNSCreateTypeString(answer->type, record, sizeof(record)); - lua_pushstring(luastate, "type"); - lua_pushstring(luastate, record); - lua_settable(luastate, -3); - - lua_pushstring(luastate, "ttl"); - lua_pushinteger(luastate, answer->ttl); - lua_settable(luastate, -3); - - { - char *c; - size_t input_len; - c = BytesToString((uint8_t *)((uint8_t *)answer + sizeof(DNSAnswerEntry)), answer->fqdn_len); - if (c != NULL) { - input_len = strlen(c); - /* sanity check */ - if (input_len > (size_t)(2 * answer->fqdn_len)) { - SCFree(c); - return LuaCallbackError(luastate, "invalid length"); - } - lua_pushstring(luastate, "rrname"); - LuaPushStringBuffer(luastate, (uint8_t *)c, input_len); - lua_settable(luastate, -3); - SCFree(c); - } - } - - - lua_settable(luastate, -3); - } - - return 1; -} - - -/** \brief register http lua extensions in a luastate */ -int LuaRegisterDnsFunctions(lua_State *luastate) -{ - /* registration of the callbacks */ - lua_pushcfunction(luastate, DnsGetDnsRrname); - lua_setglobal(luastate, "DnsGetDnsRrname"); - - lua_pushcfunction(luastate, DnsGetQueryTable); - lua_setglobal(luastate, "DnsGetQueries"); - - lua_pushcfunction(luastate, DnsGetAnswerTable); - lua_setglobal(luastate, "DnsGetAnswers"); - - lua_pushcfunction(luastate, DnsGetAuthorityTable); - lua_setglobal(luastate, "DnsGetAuthorities"); - - lua_pushcfunction(luastate, DnsGetTxid); - lua_setglobal(luastate, "DnsGetTxid"); - - lua_pushcfunction(luastate, DnsGetRcode); - lua_setglobal(luastate, "DnsGetRcode"); - - lua_pushcfunction(luastate, DnsGetRecursionDesired); - lua_setglobal(luastate, "DnsGetRecursionDesired"); - return 0; -} - -#endif /* HAVE_LUA */ diff --git a/framework/src/suricata/src/util-lua-dns.h b/framework/src/suricata/src/util-lua-dns.h deleted file mode 100644 index 582fdea7..00000000 --- a/framework/src/suricata/src/util-lua-dns.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - */ - -#ifndef __UTIL_LUA_DNS_H__ -#define __UTIL_LUA_DNS_H__ - -#ifdef HAVE_LUA - -int LuaRegisterDnsFunctions(lua_State *luastate); - -#endif /* HAVE_LUA */ - -#endif /* __UTIL_LUA_HTTP_H__ */ diff --git a/framework/src/suricata/src/util-lua-http.c b/framework/src/suricata/src/util-lua-http.c deleted file mode 100644 index 3d97b0f6..00000000 --- a/framework/src/suricata/src/util-lua-http.c +++ /dev/null @@ -1,348 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer-htp.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#ifdef HAVE_LUA - -#include -#include -#include - -#include "util-lua.h" -#include "util-lua-common.h" - -static int HttpGetRequestHost(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) - return LuaCallbackError(luastate, "error: protocol not http"); - - htp_tx_t *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - if (tx->request_hostname == NULL) - return LuaCallbackError(luastate, "no request hostname"); - - return LuaPushStringBuffer(luastate, - bstr_ptr(tx->request_hostname), bstr_len(tx->request_hostname)); -} - -static int HttpGetRequestUriRaw(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) - return LuaCallbackError(luastate, "error: protocol not http"); - - htp_tx_t *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - if (tx->request_uri == NULL) - return LuaCallbackError(luastate, "no request uri"); - - return LuaPushStringBuffer(luastate, - bstr_ptr(tx->request_uri), bstr_len(tx->request_uri)); -} - -static int HttpGetRequestUriNormalized(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) - return LuaCallbackError(luastate, "error: protocol not http"); - - htp_tx_t *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (htud == NULL) - return LuaCallbackError(luastate, "no htud in tx"); - - if (htud->request_uri_normalized == NULL || - bstr_ptr(htud->request_uri_normalized) == NULL || - bstr_len(htud->request_uri_normalized) == 0) - return LuaCallbackError(luastate, "no normalized uri"); - - return LuaPushStringBuffer(luastate, - bstr_ptr(htud->request_uri_normalized), - bstr_len(htud->request_uri_normalized)); -} - -static int HttpGetRequestLine(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) - return LuaCallbackError(luastate, "error: protocol not http"); - - htp_tx_t *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - if (tx->request_line == NULL) - return LuaCallbackError(luastate, "no request_line"); - - return LuaPushStringBuffer(luastate, - bstr_ptr(tx->request_line), bstr_len(tx->request_line)); -} - -static int HttpGetResponseLine(lua_State *luastate) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) - return LuaCallbackError(luastate, "error: protocol not http"); - - htp_tx_t *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - if (tx->response_line == NULL) - return LuaCallbackError(luastate, "no response_line"); - - return LuaPushStringBuffer(luastate, - bstr_ptr(tx->response_line), bstr_len(tx->response_line)); -} - -static int HttpGetHeader(lua_State *luastate, int dir) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) - return LuaCallbackError(luastate, "error: protocol not http"); - - htp_tx_t *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - const char *name = LuaGetStringArgument(luastate, 1); - if (name == NULL) - return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); - - htp_table_t *headers = tx->request_headers; - if (dir == 1) - headers = tx->response_headers; - if (headers == NULL) - return LuaCallbackError(luastate, "tx has no headers"); - - htp_header_t *h = (htp_header_t *)htp_table_get_c(headers, name); - if (h == NULL || bstr_len(h->value) == 0) - return LuaCallbackError(luastate, "header not found"); - - return LuaPushStringBuffer(luastate, - bstr_ptr(h->value), bstr_len(h->value)); -} - -static int HttpGetRequestHeader(lua_State *luastate) -{ - return HttpGetHeader(luastate, 0 /* request */); -} - -static int HttpGetResponseHeader(lua_State *luastate) -{ - return HttpGetHeader(luastate, 1 /* response */); -} - -static int HttpGetRawHeaders(lua_State *luastate, int dir) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) - return LuaCallbackError(luastate, "error: protocol not http"); - - htp_tx_t *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (htud == NULL) - return LuaCallbackError(luastate, "no htud in tx"); - - uint8_t *raw = htud->request_headers_raw; - uint32_t raw_len = htud->request_headers_raw_len; - if (dir == 1) { - raw = htud->response_headers_raw; - raw_len = htud->response_headers_raw_len; - } - - if (raw == NULL || raw_len == 0) - return LuaCallbackError(luastate, "no raw headers"); - - return LuaPushStringBuffer(luastate, raw, raw_len); -} - -static int HttpGetRawRequestHeaders(lua_State *luastate) -{ - return HttpGetRawHeaders(luastate, 0); -} - -static int HttpGetRawResponseHeaders(lua_State *luastate) -{ - return HttpGetRawHeaders(luastate, 1); -} - - -static int HttpGetHeaders(lua_State *luastate, int dir) -{ - if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) - return LuaCallbackError(luastate, "error: protocol not http"); - - htp_tx_t *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - htp_table_t *table = tx->request_headers; - if (dir == 1) - table = tx->response_headers; - if (tx->request_headers == NULL) - return LuaCallbackError(luastate, "no headers"); - - lua_newtable(luastate); - htp_header_t *h = NULL; - size_t i = 0; - size_t no_of_headers = htp_table_size(table); - for (; i < no_of_headers; i++) { - h = htp_table_get_index(table, i, NULL); - LuaPushStringBuffer(luastate, bstr_ptr(h->name), bstr_len(h->name)); - LuaPushStringBuffer(luastate, bstr_ptr(h->value), bstr_len(h->value)); - lua_settable(luastate, -3); - } - return 1; -} - -/** \brief return request headers as lua table */ -static int HttpGetRequestHeaders(lua_State *luastate) -{ - return HttpGetHeaders(luastate, 0); -} - -/** \brief return response headers as lua table */ -static int HttpGetResponseHeaders(lua_State *luastate) -{ - return HttpGetHeaders(luastate, 1); -} - -static int HttpGetBody(lua_State *luastate, int dir) -{ - HtpBody *body = NULL; - - if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) - return LuaCallbackError(luastate, "error: protocol not http"); - - htp_tx_t *tx = LuaStateGetTX(luastate); - if (tx == NULL) - return LuaCallbackError(luastate, "internal error: no tx"); - - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (htud == NULL) - return LuaCallbackError(luastate, "no htud in tx"); - - if (dir == 0) - body = &htud->request_body; - else - body = &htud->response_body; - - if (body->first == NULL) - return LuaCallbackError(luastate, "no body"); - - int index = 1; - HtpBodyChunk *chunk = body->first; - lua_newtable(luastate); - while (chunk != NULL) { - lua_pushinteger(luastate, index); - LuaPushStringBuffer(luastate, chunk->data, chunk->len); - lua_settable(luastate, -3); - - chunk = chunk->next; - index++; - } - - if (body->first && body->last) { - lua_pushinteger(luastate, body->first->stream_offset); - lua_pushinteger(luastate, body->last->stream_offset + body->last->len); - return 3; - } else { - return 1; - } -} - -static int HttpGetRequestBody(lua_State *luastate) -{ - return HttpGetBody(luastate, 0); -} - -static int HttpGetResponseBody(lua_State *luastate) -{ - return HttpGetBody(luastate, 1); -} - -/** \brief register http lua extensions in a luastate */ -int LuaRegisterHttpFunctions(lua_State *luastate) -{ - /* registration of the callbacks */ - lua_pushcfunction(luastate, HttpGetRequestHeader); - lua_setglobal(luastate, "HttpGetRequestHeader"); - lua_pushcfunction(luastate, HttpGetResponseHeader); - lua_setglobal(luastate, "HttpGetResponseHeader"); - lua_pushcfunction(luastate, HttpGetRequestLine); - lua_setglobal(luastate, "HttpGetRequestLine"); - lua_pushcfunction(luastate, HttpGetResponseLine); - lua_setglobal(luastate, "HttpGetResponseLine"); - lua_pushcfunction(luastate, HttpGetRawRequestHeaders); - lua_setglobal(luastate, "HttpGetRawRequestHeaders"); - lua_pushcfunction(luastate, HttpGetRawResponseHeaders); - lua_setglobal(luastate, "HttpGetRawResponseHeaders"); - lua_pushcfunction(luastate, HttpGetRequestUriRaw); - lua_setglobal(luastate, "HttpGetRequestUriRaw"); - lua_pushcfunction(luastate, HttpGetRequestUriNormalized); - lua_setglobal(luastate, "HttpGetRequestUriNormalized"); - lua_pushcfunction(luastate, HttpGetRequestHeaders); - lua_setglobal(luastate, "HttpGetRequestHeaders"); - lua_pushcfunction(luastate, HttpGetResponseHeaders); - lua_setglobal(luastate, "HttpGetResponseHeaders"); - lua_pushcfunction(luastate, HttpGetRequestHost); - lua_setglobal(luastate, "HttpGetRequestHost"); - - lua_pushcfunction(luastate, HttpGetRequestBody); - lua_setglobal(luastate, "HttpGetRequestBody"); - lua_pushcfunction(luastate, HttpGetResponseBody); - lua_setglobal(luastate, "HttpGetResponseBody"); - return 0; -} - -#endif /* HAVE_LUA */ diff --git a/framework/src/suricata/src/util-lua-http.h b/framework/src/suricata/src/util-lua-http.h deleted file mode 100644 index 8a75ec53..00000000 --- a/framework/src/suricata/src/util-lua-http.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_LUA_HTTP_H__ -#define __UTIL_LUA_HTTP_H__ - -#ifdef HAVE_LUA - -int LuaRegisterHttpFunctions(lua_State *luastate); - -#endif /* HAVE_LUA */ - -#endif /* __UTIL_LUA_HTTP_H__ */ diff --git a/framework/src/suricata/src/util-lua-ssh.c b/framework/src/suricata/src/util-lua-ssh.c deleted file mode 100644 index df232c81..00000000 --- a/framework/src/suricata/src/util-lua-ssh.c +++ /dev/null @@ -1,227 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - - -/** - * \file - * - * \author Mats Klepsland - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-ssh.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#ifdef HAVE_LUA - -#include -#include -#include - -#include "util-lua.h" -#include "util-lua-common.h" - -static int GetServerProtoVersion(lua_State *luastate, const Flow *f) -{ - void *state = FlowGetAppState(f); - if (state == NULL) - return LuaCallbackError(luastate, "error: no app layer state"); - - SshState *ssh_state = (SshState *)state; - - if (ssh_state->srv_hdr.proto_version == NULL) - return LuaCallbackError(luastate, "error: no server proto version"); - - return LuaPushStringBuffer(luastate, ssh_state->srv_hdr.proto_version, - strlen((char *)ssh_state->srv_hdr.proto_version)); -} - -static int SshGetServerProtoVersion(lua_State *luastate) -{ - int r; - - if (!(LuaStateNeedProto(luastate, ALPROTO_SSH))) - return LuaCallbackError(luastate, "error: protocol not ssh"); - - int lock_hint = 0; - Flow *f = LuaStateGetFlow(luastate, &lock_hint); - if (f == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(f); - r = GetServerProtoVersion(luastate, f); - FLOWLOCK_UNLOCK(f); - } else { - r = GetServerProtoVersion(luastate, f); - } - return r; -} - -static int GetServerSoftwareVersion(lua_State *luastate, const Flow *f) -{ - void *state = FlowGetAppState(f); - if (state == NULL) - return LuaCallbackError(luastate, "error: no app layer state"); - - SshState *ssh_state = (SshState *)state; - - if (ssh_state->srv_hdr.software_version == NULL) - return LuaCallbackError(luastate, "error: no server software version"); - - return LuaPushStringBuffer(luastate, ssh_state->srv_hdr.software_version, - strlen((char *)ssh_state->srv_hdr.software_version)); -} - -static int SshGetServerSoftwareVersion(lua_State *luastate) -{ - int r; - - if (!(LuaStateNeedProto(luastate, ALPROTO_SSH))) - return LuaCallbackError(luastate, "error: protocol not ssh"); - - int lock_hint = 0; - Flow *f = LuaStateGetFlow(luastate, &lock_hint); - if (f == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(f); - r = GetServerSoftwareVersion(luastate, f); - FLOWLOCK_UNLOCK(f); - } else { - r = GetServerSoftwareVersion(luastate, f); - } - return r; -} - -static int GetClientProtoVersion(lua_State *luastate, const Flow *f) -{ - void *state = FlowGetAppState(f); - if (state == NULL) - return LuaCallbackError(luastate, "error: no app layer state"); - - SshState *ssh_state = (SshState *)state; - - if (ssh_state->cli_hdr.proto_version == NULL) - return LuaCallbackError(luastate, "error: no client proto version"); - - return LuaPushStringBuffer(luastate, ssh_state->cli_hdr.proto_version, - strlen((char *)ssh_state->cli_hdr.proto_version)); -} - -static int SshGetClientProtoVersion(lua_State *luastate) -{ - int r; - - if (!(LuaStateNeedProto(luastate, ALPROTO_SSH))) - return LuaCallbackError(luastate, "error: protocol not ssh"); - - int lock_hint = 0; - Flow *f = LuaStateGetFlow(luastate, &lock_hint); - if (f == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(f); - r = GetClientProtoVersion(luastate, f); - FLOWLOCK_UNLOCK(f); - } else { - r = GetClientProtoVersion(luastate, f); - } - return r; -} - -static int GetClientSoftwareVersion(lua_State *luastate, const Flow *f) -{ - void *state = FlowGetAppState(f); - if (state == NULL) - return LuaCallbackError(luastate, "error: no app layer state"); - - SshState *ssh_state = (SshState *)state; - - if (ssh_state->cli_hdr.software_version == NULL) - return LuaCallbackError(luastate, "error: no client software version"); - - return LuaPushStringBuffer(luastate, ssh_state->cli_hdr.software_version, - strlen((char *)ssh_state->cli_hdr.software_version)); -} - -static int SshGetClientSoftwareVersion(lua_State *luastate) -{ - int r; - - if (!(LuaStateNeedProto(luastate, ALPROTO_SSH))) - return LuaCallbackError(luastate, "error: protocol not ssh"); - - int lock_hint = 0; - Flow *f = LuaStateGetFlow(luastate, &lock_hint); - if (f == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(f); - r = GetClientSoftwareVersion(luastate, f); - FLOWLOCK_UNLOCK(f); - } else { - r = GetClientSoftwareVersion(luastate, f); - } - return r; -} - -/** \brief register ssh lua extensions in a luastate */ -int LuaRegisterSshFunctions(lua_State *luastate) -{ - /* registration of the callbacks */ - lua_pushcfunction(luastate, SshGetServerProtoVersion); - lua_setglobal(luastate, "SshGetServerProtoVersion"); - - lua_pushcfunction(luastate, SshGetServerSoftwareVersion); - lua_setglobal(luastate, "SshGetServerSoftwareVersion"); - - lua_pushcfunction(luastate, SshGetClientProtoVersion); - lua_setglobal(luastate, "SshGetClientProtoVersion"); - - lua_pushcfunction(luastate, SshGetClientSoftwareVersion); - lua_setglobal(luastate, "SshGetClientSoftwareVersion"); - - return 0; -} - -#endif /* HAVE_LUA */ diff --git a/framework/src/suricata/src/util-lua-ssh.h b/framework/src/suricata/src/util-lua-ssh.h deleted file mode 100644 index aa6b6d70..00000000 --- a/framework/src/suricata/src/util-lua-ssh.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Mats Klepsland - */ - -#ifndef __UTIL_LUA_SSH_H__ -#define __UTIL_LUA_SSH_H__ - -#ifdef HAVE_LUA - -int LuaRegisterSshFunctions(lua_State *luastate); - -#endif /* HAVE_LUA */ - -#endif /* __UTIL_LUA_SSH_H__ */ diff --git a/framework/src/suricata/src/util-lua-tls.c b/framework/src/suricata/src/util-lua-tls.c deleted file mode 100644 index 5963ac24..00000000 --- a/framework/src/suricata/src/util-lua-tls.c +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - - -/** - * \file - * - * \author Eric Leblond - * - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "app-layer-ssl.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#ifdef HAVE_LUA - -#include -#include -#include - -#include "util-lua.h" -#include "util-lua-common.h" - -static int GetCertInfo(lua_State *luastate, const Flow *f, int direction) -{ - void *state = FlowGetAppState(f); - if (state == NULL) - return LuaCallbackError(luastate, "error: no app layer state"); - - SSLState *ssl_state = (SSLState *)state; - SSLStateConnp *connp = NULL; - - if (direction) { - connp = &ssl_state->client_connp; - } else { - connp = &ssl_state->server_connp; - } - - if (connp->cert0_subject == NULL) - return LuaCallbackError(luastate, "error: no cert"); - - /* tls.version */ - char ssl_version[32] = ""; - switch (ssl_state->server_connp.version) { - case TLS_VERSION_UNKNOWN: - snprintf(ssl_version, sizeof(ssl_version), "UNDETERMINED"); - break; - case SSL_VERSION_2: - snprintf(ssl_version, sizeof(ssl_version), "SSLv2"); - break; - case SSL_VERSION_3: - snprintf(ssl_version, sizeof(ssl_version), "SSLv3"); - break; - case TLS_VERSION_10: - snprintf(ssl_version, sizeof(ssl_version), "TLSv1"); - break; - case TLS_VERSION_11: - snprintf(ssl_version, sizeof(ssl_version), "TLS 1.1"); - break; - case TLS_VERSION_12: - snprintf(ssl_version, sizeof(ssl_version), "TLS 1.2"); - break; - default: - snprintf(ssl_version, sizeof(ssl_version), "0x%04x", - ssl_state->server_connp.version); - break; - } - - int r = LuaPushStringBuffer(luastate, (uint8_t *)ssl_version, strlen(ssl_version)); - r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_subject, strlen(connp->cert0_subject)); - r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_issuerdn, strlen(connp->cert0_issuerdn)); - r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_fingerprint, strlen(connp->cert0_fingerprint)); - return r; -} - -static int TlsGetCertInfo(lua_State *luastate) -{ - int r; - - if (!(LuaStateNeedProto(luastate, ALPROTO_TLS))) - return LuaCallbackError(luastate, "error: protocol not tls"); - - int direction = LuaStateGetDirection(luastate); - - int lock_hint = 0; - Flow *f = LuaStateGetFlow(luastate, &lock_hint); - if (f == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(f); - r = GetCertInfo(luastate, f, direction); - FLOWLOCK_UNLOCK(f); - } else { - r = GetCertInfo(luastate, f, direction); - } - return r; -} - -static int GetSNI(lua_State *luastate, const Flow *f) -{ - void *state = FlowGetAppState(f); - if (state == NULL) - return LuaCallbackError(luastate, "error: no app layer state"); - - SSLState *ssl_state = (SSLState *)state; - - if (ssl_state->client_connp.sni == NULL) - return LuaCallbackError(luastate, "error: no server name indication"); - - return LuaPushStringBuffer(luastate, (uint8_t *)ssl_state->client_connp.sni, - strlen(ssl_state->client_connp.sni)); -} - -static int TlsGetSNI(lua_State *luastate) -{ - int r; - - if (!(LuaStateNeedProto(luastate, ALPROTO_TLS))) - return LuaCallbackError(luastate, "error: protocol not tls"); - - int lock_hint = 0; - Flow *f = LuaStateGetFlow(luastate, &lock_hint); - if (f == NULL) - return LuaCallbackError(luastate, "internal error: no flow"); - - if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { - FLOWLOCK_RDLOCK(f); - r = GetSNI(luastate, f); - FLOWLOCK_UNLOCK(f); - } else { - r = GetSNI(luastate, f); - } - return r; -} - -/** \brief register tls lua extensions in a luastate */ -int LuaRegisterTlsFunctions(lua_State *luastate) -{ - /* registration of the callbacks */ - lua_pushcfunction(luastate, TlsGetCertInfo); - lua_setglobal(luastate, "TlsGetCertInfo"); - - lua_pushcfunction(luastate, TlsGetSNI); - lua_setglobal(luastate, "TlsGetSNI"); - - return 0; -} - -#endif /* HAVE_LUA */ diff --git a/framework/src/suricata/src/util-lua-tls.h b/framework/src/suricata/src/util-lua-tls.h deleted file mode 100644 index 57a27b55..00000000 --- a/framework/src/suricata/src/util-lua-tls.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2015 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_LUA_TLS_H__ -#define __UTIL_LUA_TLS_H__ - -#ifdef HAVE_LUA - -int LuaRegisterTlsFunctions(lua_State *luastate); - -#endif /* HAVE_LUA */ - -#endif /* __UTIL_LUA_TLS_H__ */ diff --git a/framework/src/suricata/src/util-lua.c b/framework/src/suricata/src/util-lua.c deleted file mode 100644 index 32d206c3..00000000 --- a/framework/src/suricata/src/util-lua.c +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Common function for Lua - */ - -#include "suricata-common.h" -#include "debug.h" -#include "detect.h" -#include "pkt-var.h" -#include "conf.h" - -#include "threads.h" -#include "threadvars.h" -#include "tm-threads.h" - -#include "util-print.h" -#include "util-unittest.h" - -#include "util-debug.h" - -#include "output.h" -#include "app-layer-htp.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-privs.h" -#include "util-buffer.h" -#include "util-proto-name.h" -#include "util-logopenfile.h" -#include "util-time.h" - -#ifdef HAVE_LUA - -#include -#include -#include - -#include "util-lua.h" - -/* key for tv (threadvars) pointer */ -const char lua_ext_key_tv[] = "suricata:lua:tv:ptr"; -/* key for tx pointer */ -const char lua_ext_key_tx[] = "suricata:lua:tx:ptr"; -/* key for p (packet) pointer */ -const char lua_ext_key_p[] = "suricata:lua:pkt:ptr"; -/* key for f (flow) pointer */ -const char lua_ext_key_flow[] = "suricata:lua:flow:ptr"; -/* key for flow lock hint bool */ -const char lua_ext_key_flow_lock_hint[] = "suricata:lua:flow:lock_hint"; -/* key for direction */ -const char lua_ext_key_direction[] = "suricata:lua:direction"; - -/* key for pa (packet alert) pointer */ -const char lua_ext_key_pa[] = "suricata:lua:pkt:alert:ptr"; -/* key for file pointer */ -const char lua_ext_key_file[] = "suricata:lua:file:ptr"; -/* key for streaming buffer pointer */ -const char lua_ext_key_streaming_buffer[] = "suricata:lua:streaming_buffer:ptr"; - -/** \brief get tv pointer from the lua state */ -ThreadVars *LuaStateGetThreadVars(lua_State *luastate) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_tv); - lua_gettable(luastate, LUA_REGISTRYINDEX); - void *tv = lua_touserdata(luastate, -1); - return (ThreadVars *)tv; -} - -void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_tv); - lua_pushlightuserdata(luastate, (void *)tv); - lua_settable(luastate, LUA_REGISTRYINDEX); -} - -/** \brief get packet pointer from the lua state */ -Packet *LuaStateGetPacket(lua_State *luastate) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_p); - lua_gettable(luastate, LUA_REGISTRYINDEX); - void *p = lua_touserdata(luastate, -1); - return (Packet *)p; -} - -void LuaStateSetPacket(lua_State *luastate, Packet *p) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_p); - lua_pushlightuserdata(luastate, (void *)p); - lua_settable(luastate, LUA_REGISTRYINDEX); -} - -/** \brief get tx pointer from the lua state */ -void *LuaStateGetTX(lua_State *luastate) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_tx); - lua_gettable(luastate, LUA_REGISTRYINDEX); - void *tx = lua_touserdata(luastate, -1); - return tx; -} - -void LuaStateSetTX(lua_State *luastate, void *txptr) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_tx); - lua_pushlightuserdata(luastate, (void *)txptr); - lua_settable(luastate, LUA_REGISTRYINDEX); -} - -Flow *LuaStateGetFlow(lua_State *luastate, int *lock_hint) -{ - Flow *f = NULL; - int need_flow_lock = 0; - - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_flow); - lua_gettable(luastate, LUA_REGISTRYINDEX); - f = lua_touserdata(luastate, -1); - - /* need flow lock hint */ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_flow_lock_hint); - lua_gettable(luastate, LUA_REGISTRYINDEX); - need_flow_lock = lua_toboolean(luastate, -1); - - *lock_hint = need_flow_lock; - return f; -} - -void LuaStateSetFlow(lua_State *luastate, Flow *f, int need_flow_lock) -{ - /* flow */ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_flow); - lua_pushlightuserdata(luastate, (void *)f); - lua_settable(luastate, LUA_REGISTRYINDEX); - - /* flow lock status hint */ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_flow_lock_hint); - lua_pushboolean(luastate, need_flow_lock); - lua_settable(luastate, LUA_REGISTRYINDEX); -} - -/** \brief get packet alert pointer from the lua state */ -PacketAlert *LuaStateGetPacketAlert(lua_State *luastate) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_pa); - lua_gettable(luastate, LUA_REGISTRYINDEX); - void *pa = lua_touserdata(luastate, -1); - return (PacketAlert *)pa; -} - -void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_pa); - lua_pushlightuserdata(luastate, (void *)pa); - lua_settable(luastate, LUA_REGISTRYINDEX); -} - -/** \brief get file pointer from the lua state */ -File *LuaStateGetFile(lua_State *luastate) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_file); - lua_gettable(luastate, LUA_REGISTRYINDEX); - void *file = lua_touserdata(luastate, -1); - return (File *)file; -} - -void LuaStateSetFile(lua_State *luastate, File *file) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_file); - lua_pushlightuserdata(luastate, (void *)file); - lua_settable(luastate, LUA_REGISTRYINDEX); -} - -LuaStreamingBuffer *LuaStateGetStreamingBuffer(lua_State *luastate) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_streaming_buffer); - lua_gettable(luastate, LUA_REGISTRYINDEX); - void *b = lua_touserdata(luastate, -1); - return (LuaStreamingBuffer *)b; -} - -void LuaStateSetStreamingBuffer(lua_State *luastate, LuaStreamingBuffer *b) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_streaming_buffer); - lua_pushlightuserdata(luastate, (void *)b); - lua_settable(luastate, LUA_REGISTRYINDEX); -} - -/** \brief get packet pointer from the lua state */ -int LuaStateGetDirection(lua_State *luastate) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_direction); - lua_gettable(luastate, LUA_REGISTRYINDEX); - int dir = lua_toboolean(luastate, -1); - return dir; -} - -void LuaStateSetDirection(lua_State *luastate, int direction) -{ - lua_pushlightuserdata(luastate, (void *)&lua_ext_key_direction); - lua_pushboolean(luastate, direction); - lua_settable(luastate, LUA_REGISTRYINDEX); -} - -/** \brief dump stack from lua state to screen */ -void LuaPrintStack(lua_State *state) { - int size = lua_gettop(state); - int i; - - for (i = 1; i <= size; i++) { - int type = lua_type(state, i); - printf("Stack size=%d, level=%d, type=%d, ", size, i, type); - - switch (type) { - case LUA_TFUNCTION: - printf("function %s", lua_tostring(state, i) ? "true" : "false"); - break; - case LUA_TBOOLEAN: - printf("bool %s", lua_toboolean(state, i) ? "true" : "false"); - break; - case LUA_TNUMBER: - printf("number %g", lua_tonumber(state, i)); - break; - case LUA_TSTRING: - printf("string `%s'", lua_tostring(state, i)); - break; - case LUA_TTABLE: - printf("table `%s'", lua_tostring(state, i)); - break; - default: - printf("other %s", lua_typename(state, type)); - break; - - } - printf("\n"); - } -} - -int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len) -{ - if (input_len % 4 != 0) { - /* we're using a buffer sized at a multiple of 4 as lua_pushlstring generates - * invalid read errors in valgrind otherwise. Adding in a nul to be sure. - * - * Buffer size = len + 1 (for nul) + whatever makes it a multiple of 4 */ - size_t buflen = input_len + 1 + ((input_len + 1) % 4); - uint8_t buf[buflen]; - memset(buf, 0x00, buflen); - memcpy(buf, input, input_len); - buf[input_len] = '\0'; - - /* return value through luastate, as a luastring */ - lua_pushlstring(luastate, (char *)buf, input_len); - } else { - lua_pushlstring(luastate, (char *)input, input_len); - } - return 1; -} - -#endif /* HAVE_LUA */ diff --git a/framework/src/suricata/src/util-lua.h b/framework/src/suricata/src/util-lua.h deleted file mode 100644 index 4ea4c605..00000000 --- a/framework/src/suricata/src/util-lua.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_LUA_H__ -#define __UTIL_LUA_H__ - -#ifdef HAVE_LUA - -typedef struct LuaStreamingBuffer_ { - const uint8_t *data; - uint32_t data_len; - uint8_t flags; -} LuaStreamingBuffer; - -#define LUA_FLOW_LOCKED_BY_PARENT 0 -#define LUA_FLOW_NOT_LOCKED_BY_PARENT 1 - -/* gets */ - -/** \brief get tv pointer from the lua state */ -ThreadVars *LuaStateGetThreadVars(lua_State *luastate); - -Packet *LuaStateGetPacket(lua_State *luastate); -void *LuaStateGetTX(lua_State *luastate); - -/** \brief get flow pointer from lua state - * - * \param locked_by_parent[out] bool indicating if flow is locked - * (LUA_FLOW_LOCKED_BY_PARENT) or unlocked - * (LUA_FLOW_NOT_LOCKED_BY_PARENT) - * - * \retval f flow poiner or NULL if it was not set - */ -Flow *LuaStateGetFlow(lua_State *luastate, int *locked_by_parent); - -PacketAlert *LuaStateGetPacketAlert(lua_State *luastate); - -/** \brief get file pointer from the lua state */ -File *LuaStateGetFile(lua_State *luastate); - -LuaStreamingBuffer *LuaStateGetStreamingBuffer(lua_State *luastate); - -int LuaStateGetDirection(lua_State *luastate); - -/* sets */ - -void LuaStateSetPacket(lua_State *luastate, Packet *p); -void LuaStateSetTX(lua_State *luastate, void *tx); - -/** \brief set a flow pointer in the lua state - * - * \param f flow pointer - * \param locked_by_parent bool indicating if flow is locked - * (LUA_FLOW_LOCKED_BY_PARENT) or unlocked - * (LUA_FLOW_NOT_LOCKED_BY_PARENT) - */ -void LuaStateSetFlow(lua_State *luastate, Flow *f, int locked_by_parent); - -void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa); - -void LuaStateSetFile(lua_State *luastate, File *file); - -void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv); - -void LuaStateSetStreamingBuffer(lua_State *luastate, LuaStreamingBuffer *b); - -void LuaStateSetDirection(lua_State *luastate, int direction); - -void LuaPrintStack(lua_State *state); - -int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t input_len); - -#endif /* HAVE_LUA */ - -#endif /* __UTIL_LUA_H__ */ diff --git a/framework/src/suricata/src/util-magic.c b/framework/src/suricata/src/util-magic.c deleted file mode 100644 index fa05c6d9..00000000 --- a/framework/src/suricata/src/util-magic.c +++ /dev/null @@ -1,676 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Wrappers and tests for libmagic usage. - * - * Libmagic's API is not thread safe. The data the pointer returned by - * magic_buffer is overwritten by the next magic_buffer call. This is - * why we need to lock calls and copy the returned string. - */ - -#include "suricata-common.h" -#include "conf.h" - -#include "util-unittest.h" -#include - -static magic_t g_magic_ctx = NULL; -static SCMutex g_magic_lock; - -/** - * \brief Initialize the "magic" context. - */ -int MagicInit(void) -{ - BUG_ON(g_magic_ctx != NULL); - - SCEnter(); - - char *filename = NULL; - FILE *fd = NULL; - - SCMutexInit(&g_magic_lock, NULL); - SCMutexLock(&g_magic_lock); - - g_magic_ctx = magic_open(0); - if (g_magic_ctx == NULL) { - SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s", magic_error(g_magic_ctx)); - goto error; - } - - (void)ConfGet("magic-file", &filename); - if (filename != NULL) { - SCLogInfo("using magic-file %s", filename); - - if ( (fd = fopen(filename, "r")) == NULL) { - SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, strerror(errno)); - goto error; - } - fclose(fd); - } - - if (magic_load(g_magic_ctx, filename) != 0) { - SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s", magic_error(g_magic_ctx)); - goto error; - } - - SCMutexUnlock(&g_magic_lock); - SCReturnInt(0); - -error: - if (g_magic_ctx != NULL) { - magic_close(g_magic_ctx); - g_magic_ctx = NULL; - } - - SCMutexUnlock(&g_magic_lock); - SCReturnInt(-1); -} - -/** - * \brief Find the magic value for a buffer. - * - * \param buf the buffer - * \param buflen length of the buffer - * - * \retval result pointer to null terminated string - */ -char *MagicGlobalLookup(uint8_t *buf, uint32_t buflen) -{ - const char *result = NULL; - char *magic = NULL; - - SCMutexLock(&g_magic_lock); - - if (buf != NULL && buflen > 0) { - result = magic_buffer(g_magic_ctx, (void *)buf, (size_t)buflen); - if (result != NULL) { - magic = SCStrdup(result); - if (unlikely(magic == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup magic"); - } - } - } - - SCMutexUnlock(&g_magic_lock); - SCReturnPtr(magic, "const char"); -} - -/** - * \brief Find the magic value for a buffer. - * - * \param buf the buffer - * \param buflen length of the buffer - * - * \retval result pointer to null terminated string - */ -char *MagicThreadLookup(magic_t *ctx, uint8_t *buf, uint32_t buflen) -{ - const char *result = NULL; - char *magic = NULL; - - if (buf != NULL && buflen > 0) { - result = magic_buffer(*ctx, (void *)buf, (size_t)buflen); - if (result != NULL) { - magic = SCStrdup(result); - if (unlikely(magic == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup magic"); - } - } - } - - SCReturnPtr(magic, "const char"); -} - -void MagicDeinit(void) -{ - SCMutexLock(&g_magic_lock); - if (g_magic_ctx != NULL) { - magic_close(g_magic_ctx); - g_magic_ctx = NULL; - } - SCMutexUnlock(&g_magic_lock); - SCMutexDestroy(&g_magic_lock); -} - -#ifdef UNITTESTS - -#if defined OS_FREEBSD || defined OS_DARWIN -#define MICROSOFT_OFFICE_DOC "OLE 2 Compound Document" -#else -#define MICROSOFT_OFFICE_DOC "Microsoft Office Document" -#endif - -/** \test magic lib calls -- init */ -int MagicInitTest01(void) -{ - int result = 0; - magic_t magic_ctx; - - magic_ctx = magic_open(0); - if (magic_ctx == NULL) { - printf("failure retrieving magic_ctx\n"); - return 0; - } - - if (magic_load(magic_ctx, NULL) == -1) { - printf("failure magic_load\n"); - goto end; - } - - result = 1; - end: - magic_close(magic_ctx); - return result; -} - -/** \test magic init through api */ -int MagicInitTest02(void) -{ - if (g_magic_ctx != NULL) { - printf("g_magic_ctx != NULL at start of the test: "); - return 0; - } - - if (MagicInit() < 0) { - printf("MagicInit() failure\n"); - return 0; - } - - if (g_magic_ctx == NULL) { - printf("g_magic_ctx == NULL: "); - return 0; - } - - MagicDeinit(); - - if (g_magic_ctx != NULL) { - printf("g_magic_ctx != NULL at end of the test: "); - return 0; - } - - return 1; -} - -/** \test magic lib calls -- lookup */ -int MagicDetectTest01(void) -{ - magic_t magic_ctx; - char *result = NULL; - char buffer[] = { 0x25, 'P', 'D', 'F', '-', '1', '.', '3', 0x0d, 0x0a}; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - magic_ctx = magic_open(0); - if (magic_ctx == NULL) { - printf("failure retrieving magic_ctx\n"); - return 0; - } - - if (magic_load(magic_ctx, NULL) == -1) { - printf("magic_load failure\n"); - goto end; - } - - result = (char *)magic_buffer(magic_ctx, (void *)buffer, buffer_len); - if (result == NULL || strncmp(result, "PDF document", 12) != 0) { - printf("result %p:%s, not \"PDF document\": ", result,result?result:"(null)"); - goto end; - } - - retval = 1; -end: - magic_close(magic_ctx); - return retval; -} -#if 0 -/** \test magic lib calls -- lookup */ -int MagicDetectTest02(void) -{ - magic_t magic_ctx; - char *result = NULL; - - char buffer[] = { - 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3e, 0x00, 0x03, 0x00, 0xfe, 0xff, 0x09, 0x00, - - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, - - 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - magic_ctx = magic_open(0); - if (magic_ctx == NULL) { - printf("failure retrieving magic_ctx\n"); - return 0; - } - - if (magic_load(magic_ctx, NULL) == -1) { - printf("magic_load failure\n"); - goto end; - } - - result = (char *)magic_buffer(magic_ctx, (void *)buffer, buffer_len); - if (result == NULL || strcmp(result, MICROSOFT_OFFICE_DOC) != 0) { - printf("result %p:%s, not \"Microsoft Office Document\": ", result,result?result:"(null)"); - goto end; - } - - retval = 1; -end: - magic_close(magic_ctx); - return retval; -} -#endif -/** \test magic lib calls -- lookup */ -int MagicDetectTest03(void) -{ - magic_t magic_ctx; - char *result = NULL; - - char buffer[] = { - 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0b, 0x55, 0x2a, 0x36, 0x5e, 0xc6, - 0x32, 0x0c, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69, - - 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6f, 0x61, - 0x73, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - - 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x2e, 0x74, 0x65, 0x78, 0x74, 0x50, 0x4b, 0x03, - 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, - 0x55, 0x2a, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, - 0x00, 0x00, 0x00, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x32, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, - - 0x73, 0x62, 0x61, 0x72, 0x2f, 0x50, 0x4b, 0x03, - 0x04, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0b, - }; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - magic_ctx = magic_open(0); - if (magic_ctx == NULL) { - printf("failure retrieving magic_ctx\n"); - return 0; - } - - if (magic_load(magic_ctx, NULL) == -1) { - printf("magic_load failure\n"); - goto end; - } - - result = (char *)magic_buffer(magic_ctx, (void *)buffer, buffer_len); - if (result == NULL || strcmp(result, "OpenDocument Text") != 0) { - printf("result %p:%s, not \"OpenDocument Text\": ", result,result?result:"(null)"); - goto end; - } - - retval = 1; -end: - magic_close(magic_ctx); - return retval; -} - -/** \test magic lib calls -- lookup */ -int MagicDetectTest04(void) -{ - magic_t magic_ctx; - char *result = NULL; - - char buffer[] = { - 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c, 0x8b, 0x70, - 0x96, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69, - - 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x73, 0x75, - 0x6e, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x62, 0x61, - - 0x73, 0x65, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - - 0x4d, 0x45, 0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46, - 0x2f, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, - 0x08, 0x08, 0x00, 0xa8, 0x42, 0x1d, 0x37, 0x5d, - 0xa7, 0xb2, 0xc1, 0xde, 0x01, 0x00, 0x00, 0x7e, - - 0x04, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x78, - 0x6d, 0x6c, 0x95, 0x54, 0x4d, 0x6f, 0xdb, 0x30, - 0x0c, 0xbd, 0xe7, 0x57, 0x18, 0x02, 0x06, 0x6c, - - 0x07, 0xc5, 0xe9, 0xb6, 0xc3, 0x22, 0xc4, 0x29, - 0x86, 0x7d, 0x00, 0x05, 0x8a, 0x9d, 0xb2, 0x43, - 0x8f, 0xb2, 0x24, 0xa7, 0xc2, 0x64, 0xc9, 0x15, - }; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - magic_ctx = magic_open(0); - if (magic_ctx == NULL) { - printf("failure retrieving magic_ctx\n"); - return 0; - } - - if (magic_load(magic_ctx, NULL) == -1) { - printf("magic_load failure\n"); - goto end; - } - - result = (char *)magic_buffer(magic_ctx, (void *)buffer, buffer_len); - if (result == NULL || strncmp(result, "OpenOffice.org 1.x", 18) != 0) { - printf("result %p:%s, not \"OpenOffice.org 1.x\": ", result,result?result:"(null)"); - goto end; - } - - retval = 1; -end: - magic_close(magic_ctx); - return retval; -} - -/** \test magic api calls -- lookup */ -int MagicDetectTest05(void) -{ - const char *result = NULL; - uint8_t buffer[] = { 0x25, 'P', 'D', 'F', '-', '1', '.', '3', 0x0d, 0x0a}; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - if (MagicInit() < 0) { - printf("MagicInit() failure\n"); - return 0; - } - - result = MagicGlobalLookup(buffer, buffer_len); - if (result == NULL || strncmp(result, "PDF document", 12) != 0) { - printf("result %p:%s, not \"PDF document\": ", result,result?result:"(null)"); - goto end; - } - - retval = 1; -end: - MagicDeinit(); - return retval; -} -#if 0 -/** \test magic api calls -- lookup */ -int MagicDetectTest06(void) -{ - const char *result = NULL; - uint8_t buffer[] = { - 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3e, 0x00, 0x03, 0x00, 0xfe, 0xff, 0x09, 0x00, - - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, - - 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - }; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - if (MagicInit() < 0) { - printf("MagicInit() failure\n"); - return 0; - } - - result = MagicGlobalLookup(buffer, buffer_len); - if (result == NULL || strcmp(result, MICROSOFT_OFFICE_DOC) != 0) { - printf("result %p:%s, not \"Microsoft Office Document\": ", result,result?result:"(null)"); - goto end; - } - - retval = 1; - -end: - MagicDeinit(); - return retval; -} -#endif -/** \test magic api calls -- lookup */ -int MagicDetectTest07(void) -{ - const char *result = NULL; - uint8_t buffer[] = { - 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0b, 0x55, 0x2a, 0x36, 0x5e, 0xc6, - 0x32, 0x0c, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69, - - 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6f, 0x61, - 0x73, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - - 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x2e, 0x74, 0x65, 0x78, 0x74, 0x50, 0x4b, 0x03, - 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, - 0x55, 0x2a, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, - 0x00, 0x00, 0x00, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x32, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, - - 0x73, 0x62, 0x61, 0x72, 0x2f, 0x50, 0x4b, 0x03, - 0x04, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0b, - }; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - if (MagicInit() < 0) { - printf("MagicInit() failure\n"); - return 0; - } - - result = MagicGlobalLookup(buffer, buffer_len); - if (result == NULL || strcmp(result, "OpenDocument Text") != 0) { - printf("result %p:%s, not \"OpenDocument Text\": ", result,result?result:"(null)"); - goto end; - } - - retval = 1; -end: - MagicDeinit(); - return retval; -} - -/** \test magic api calls -- lookup */ -int MagicDetectTest08(void) -{ - const char *result = NULL; - uint8_t buffer[] = { - 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x08, - 0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c, 0x8b, 0x70, - 0x96, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69, - - 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x73, 0x75, - 0x6e, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x62, 0x61, - - 0x73, 0x65, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - - 0x4d, 0x45, 0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46, - 0x2f, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, - 0x08, 0x08, 0x00, 0xa8, 0x42, 0x1d, 0x37, 0x5d, - 0xa7, 0xb2, 0xc1, 0xde, 0x01, 0x00, 0x00, 0x7e, - - 0x04, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x78, - 0x6d, 0x6c, 0x95, 0x54, 0x4d, 0x6f, 0xdb, 0x30, - - 0x0c, 0xbd, 0xe7, 0x57, 0x18, 0x02, 0x06, 0x6c, - 0x07, 0xc5, 0xe9, 0xb6, 0xc3, 0x22, 0xc4, 0x29, - 0x86, 0x7d, 0x00, 0x05, 0x8a, 0x9d, 0xb2, 0x43, - 0x8f, 0xb2, 0x24, 0xa7, 0xc2, 0x64, 0xc9, 0x15, - }; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - if (MagicInit() < 0) { - printf("MagicInit() failure\n"); - return 0; - } - - result = MagicGlobalLookup(buffer, buffer_len); - if (result == NULL || strncmp(result, "OpenOffice.org 1.x", 18) != 0) { - printf("result %p:%s, not \"OpenOffice.org 1.x\": ", result,result?result:"(null)"); - goto end; - } - - retval = 1; -end: - MagicDeinit(); - return retval; -} - -/** \test magic api calls -- make sure memory is shared */ -int MagicDetectTest09(void) -{ - const char *result1 = NULL; - const char *result2 = NULL; - uint8_t buffer[] = { 0x25, 'P', 'D', 'F', '-', '1', '.', '3', 0x0d, 0x0a}; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - if (MagicInit() < 0) { - printf("MagicInit() failure\n"); - return 0; - } - - result1 = MagicGlobalLookup(buffer, buffer_len); - if (result1 == NULL || strncmp(result1, "PDF document", 12) != 0) { - printf("result %p:%s, not \"PDF document\": ", result1,result1?result1:"(null)"); - goto end; - } - - result2 = MagicGlobalLookup(buffer, buffer_len); - if (result2 == NULL || strncmp(result2, "PDF document", 12) != 0) { - printf("result %p:%s, not \"PDF document\": ", result2,result2?result2:"(null)"); - goto end; - } - - if (result1 != result2) { - printf("pointers not equal, weird... %p != %p: ", result1, result2); - goto end; - } - - retval = 1; -end: - MagicDeinit(); - return retval; -} - -/** \test results in valgrind warning about invalid read, tested with - * file 5.09 and 5.11 */ -static int MagicDetectTest10ValgrindError(void) -{ - const char *result = NULL; - uint8_t buffer[] = { - 0xFF,0xD8,0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2C, - 0x01,0x2C,0x00,0x00,0xFF,0xFE,0x00,0x4C,0x53,0x69,0x67,0x6E,0x61,0x74,0x75,0x72, - 0x65,0x3A,0x34,0x31,0x31,0x65,0x33,0x38,0x61,0x61,0x61,0x31,0x37,0x65,0x33,0x30, - 0x66,0x30,0x32,0x38,0x62,0x61,0x30,0x31,0x36,0x32,0x36,0x37,0x66,0x66,0x30,0x31, - 0x36,0x36,0x61,0x65,0x35,0x39,0x65,0x38,0x31,0x39,0x62,0x61,0x32,0x34,0x63,0x39, - 0x62,0x31,0x33,0x37,0x33,0x62,0x31,0x61,0x35,0x61,0x38,0x65,0x64,0x63,0x36,0x30, - 0x65,0x37,0xFF,0xE2,0x02,0x2C,0x49,0x43,0x43,0x5F,0x50,0x52,0x4F,0x46,0x49,0x4C, - 0x45,0x00,0x01,0x01,0x00,0x00,0x02,0x1C,0x41,0x44,0x42,0x45,0x02,0x10,0x00,0x00, - 0x6D,0x6E,0x74,0x72,0x52,0x47,0x42,0x20,0x58,0x59,0x5A,0x20,0x07,0xCF,0x00,0x05, - 0x00,0x09,0x00,0x15,0x00,0x0B,0x00,0x21,0x61,0x63,0x73,0x70,0x41,0x50,0x50,0x4C, - 0x00,0x00,0x00,0x00,0x6E,0x6F,0x6E,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - }; - size_t buffer_len = sizeof(buffer); - int retval = 0; - - if (MagicInit() < 0) { - printf("MagicInit() failure\n"); - return 0; - } - - result = MagicGlobalLookup(buffer, buffer_len); - if (result == NULL || strncmp(result, "JPEG", 4) != 0) { - printf("result %p:%s, not \"JPEG\": ", result,result?result:"(null)"); - goto end; - } - - retval = 1; -end: - MagicDeinit(); - return retval; -} - -#endif /* UNITTESTS */ - - -void MagicRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("MagicInitTest01", MagicInitTest01, 1); - UtRegisterTest("MagicInitTest02", MagicInitTest02, 1); - UtRegisterTest("MagicDetectTest01", MagicDetectTest01, 1); - //UtRegisterTest("MagicDetectTest02", MagicDetectTest02, 1); - UtRegisterTest("MagicDetectTest03", MagicDetectTest03, 1); - UtRegisterTest("MagicDetectTest04", MagicDetectTest04, 1); - UtRegisterTest("MagicDetectTest05", MagicDetectTest05, 1); - //UtRegisterTest("MagicDetectTest06", MagicDetectTest06, 1); - UtRegisterTest("MagicDetectTest07", MagicDetectTest07, 1); - UtRegisterTest("MagicDetectTest08", MagicDetectTest08, 1); - /* fails in valgrind, somehow it returns different pointers then. - UtRegisterTest("MagicDetectTest09", MagicDetectTest09, 1); */ - - UtRegisterTest("MagicDetectTest10ValgrindError", MagicDetectTest10ValgrindError, 1); -#endif /* UNITTESTS */ -} diff --git a/framework/src/suricata/src/util-magic.h b/framework/src/suricata/src/util-magic.h deleted file mode 100644 index 0efdbd14..00000000 --- a/framework/src/suricata/src/util-magic.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_MAGIC_H__ -#define __UTIL_MAGIC_H__ - -#include - -int MagicInit(void); -void MagicDeinit(void); -char *MagicGlobalLookup(uint8_t *, uint32_t); -char *MagicThreadLookup(magic_t *, uint8_t *, uint32_t); -void MagicRegisterTests(void); - -#endif /* __UTIL_MAGIC_H__ */ diff --git a/framework/src/suricata/src/util-mem.h b/framework/src/suricata/src/util-mem.h deleted file mode 100644 index b720ac36..00000000 --- a/framework/src/suricata/src/util-mem.h +++ /dev/null @@ -1,313 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * Utility Macros for memory management - * - * \todo Add wrappers for functions that allocate/free memory here. - * Currently we have malloc, calloc, realloc, strdup and free, - * but there are more. - */ - -#ifndef __UTIL_MEM_H__ -#define __UTIL_MEM_H__ - -#include "util-atomic.h" - -#if CPPCHECK==1 -#define SCMalloc malloc -#define SCCalloc calloc -#define SCRealloc realloc -#define SCFree free -#define SCStrdup strdup -#define SCMallocAligned _mm_malloc -#define SCFreeAligned _mm_free -#else /* CPPCHECK */ - - -#if defined(_WIN32) || defined(__WIN32) -#include "mm_malloc.h" -#endif - -#if defined(__tile__) -/* Need to define __mm_ function alternatives, since these are SSE only. - */ -#include -#define _mm_malloc(a,b) memalign((b),(a)) -#define _mm_free(a) free((a)) -#endif /* defined(__tile__) */ - -SC_ATOMIC_EXTERN(unsigned int, engine_stage); - -/* Use this only if you want to debug memory allocation and free() - * It will log a lot of lines more, so think that is a performance killer */ - -/* Uncomment this if you want to print memory allocations and free's() */ -//#define DBG_MEM_ALLOC - -#ifdef DBG_MEM_ALLOC - -/* Uncomment this if you want to print mallocs at the startup (recommended) */ -#define DBG_MEM_ALLOC_SKIP_STARTUP - -#define SCMalloc(a) ({ \ - void *ptrmem = NULL; \ - extern size_t global_mem; \ - extern uint8_t print_mem_flag; \ - \ - ptrmem = malloc((a)); \ - if (ptrmem == NULL && (a) > 0) { \ - SCLogError(SC_ERR_MEM_ALLOC, "SCMalloc failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)(a)); \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - \ - global_mem += (a); \ - if (print_mem_flag == 1) { \ - SCLogInfo("SCMalloc return at %p of size %"PRIuMAX, \ - ptrmem, (uintmax_t)(a)); \ - } \ - (void*)ptrmem; \ -}) - -#define SCRealloc(x, a) ({ \ - void *ptrmem = NULL; \ - extern size_t global_mem; \ - extern uint8_t print_mem_flag; \ - \ - ptrmem = realloc((x), (a)); \ - if (ptrmem == NULL && (a) > 0) { \ - SCLogError(SC_ERR_MEM_ALLOC, "SCRealloc failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)(a)); \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - \ - global_mem += (a); \ - if (print_mem_flag == 1) { \ - SCLogInfo("SCRealloc return at %p (old:%p) of size %"PRIuMAX, \ - ptrmem, (x), (uintmax_t)(a)); \ - } \ - (void*)ptrmem; \ -}) - -#define SCCalloc(nm, a) ({ \ - void *ptrmem = NULL; \ - extern size_t global_mem; \ - extern uint8_t print_mem_flag; \ - \ - ptrmem = calloc((nm), (a)); \ - if (ptrmem == NULL && (a) > 0) { \ - SCLogError(SC_ERR_MEM_ALLOC, "SCCalloc failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)a); \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - \ - global_mem += (a)*(nm); \ - if (print_mem_flag == 1) { \ - SCLogInfo("SCCalloc return at %p of size %"PRIuMAX" (nm) %"PRIuMAX, \ - ptrmem, (uintmax_t)(a), (uintmax_t)(nm)); \ - } \ - (void*)ptrmem; \ -}) - -#define SCStrdup(a) ({ \ - char *ptrmem = NULL; \ - extern size_t global_mem; \ - extern uint8_t print_mem_flag; \ - size_t len = strlen((a)); \ - \ - ptrmem = strdup((a)); \ - if (ptrmem == NULL) { \ - SCLogError(SC_ERR_MEM_ALLOC, "SCStrdup failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)len); \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - \ - global_mem += len; \ - if (print_mem_flag == 1) { \ - SCLogInfo("SCStrdup return at %p of size %"PRIuMAX, \ - ptrmem, (uintmax_t)len); \ - } \ - (void*)ptrmem; \ -}) - -#define SCFree(a) ({ \ - extern uint8_t print_mem_flag; \ - if (print_mem_flag == 1) { \ - SCLogInfo("SCFree at %p", (a)); \ - } \ - free((a)); \ -}) - -#else /* !DBG_MEM_ALLOC */ - -#define SCMalloc(a) ({ \ - void *ptrmem = NULL; \ - \ - ptrmem = malloc((a)); \ - if (ptrmem == NULL) { \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - uintmax_t scmalloc_size_ = (uintmax_t)(a); \ - SCLogError(SC_ERR_MEM_ALLOC, "SCMalloc failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes", strerror(errno), scmalloc_size_); \ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - (void*)ptrmem; \ -}) - -#define SCRealloc(x, a) ({ \ - void *ptrmem = NULL; \ - \ - ptrmem = realloc((x), (a)); \ - if (ptrmem == NULL) { \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - SCLogError(SC_ERR_MEM_ALLOC, "SCRealloc failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)(a)); \ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - (void*)ptrmem; \ -}) - -#define SCCalloc(nm, a) ({ \ - void *ptrmem = NULL; \ - \ - ptrmem = calloc((nm), (a)); \ - if (ptrmem == NULL) { \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - SCLogError(SC_ERR_MEM_ALLOC, "SCCalloc failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)(a)); \ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - (void*)ptrmem; \ -}) - -#define SCStrdup(a) ({ \ - char *ptrmem = NULL; \ - \ - ptrmem = strdup((a)); \ - if (ptrmem == NULL) { \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - size_t len = strlen((a)); \ - SCLogError(SC_ERR_MEM_ALLOC, "SCStrdup failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes", strerror(errno), (uintmax_t)len); \ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - (void*)ptrmem; \ -}) - -#define SCFree(a) ({ \ - free(a); \ -}) - -#if defined(__WIN32) || defined(_WIN32) - -/** \brief wrapper for allocing aligned mem - * \param a size - * \param b alignement - */ -#define SCMallocAligned(a, b) ({ \ - void *ptrmem = NULL; \ - \ - ptrmem = _mm_malloc((a), (b)); \ - if (ptrmem == NULL) { \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - SCLogError(SC_ERR_MEM_ALLOC, "SCMallocAligned(posix_memalign) failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes, alignment %"PRIuMAX, strerror(errno), (uintmax_t)(a), (uintmax_t)(b)); \ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - (void*)ptrmem; \ -}) - -/** \brief Free aligned memory - * - * Not needed for mem alloc'd by posix_memalign, - * but for possible future use of _mm_malloc needing - * _mm_free. - */ -#define SCFreeAligned(a) ({ \ - _mm_free(a); \ -}) - -#else /* !win */ - -/** \brief wrapper for allocing aligned mem - * \param a size - * \param b alignement - */ -#define SCMallocAligned(a, b) ({ \ - void *ptrmem = NULL; \ - \ - int r = posix_memalign(&ptrmem, (b), (a)); \ - if (r != 0 || ptrmem == NULL) { \ - if (ptrmem != NULL) { \ - free(ptrmem); \ - ptrmem = NULL; \ - } \ - if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ - SCLogError(SC_ERR_MEM_ALLOC, "SCMallocAligned(posix_memalign) failed: %s, while trying " \ - "to allocate %"PRIuMAX" bytes, alignment %"PRIuMAX, strerror(errno), (uintmax_t)a, (uintmax_t)b); \ - SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ - exit(EXIT_FAILURE); \ - } \ - } \ - (void*)ptrmem; \ -}) - -/** \brief Free aligned memory - * - * Not needed for mem alloc'd by posix_memalign, - * but for possible future use of _mm_malloc needing - * _mm_free. - */ -#define SCFreeAligned(a) ({ \ - free(a); \ -}) - -#endif /* __WIN32 */ - -#endif /* DBG_MEM_ALLOC */ - -#endif /* CPPCHECK */ - -#endif /* __UTIL_MEM_H__ */ - diff --git a/framework/src/suricata/src/util-memcmp.c b/framework/src/suricata/src/util-memcmp.c deleted file mode 100644 index c1b03490..00000000 --- a/framework/src/suricata/src/util-memcmp.c +++ /dev/null @@ -1,407 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Memcmp implementations. - */ - -#include "suricata-common.h" - -#include "util-memcmp.h" -#include "util-unittest.h" - -/* code is implemented in util-memcmp.h as it's all inlined */ - -/* UNITTESTS */ -#ifdef UNITTESTS - -static int MemcmpTest01 (void) -{ - uint8_t a[] = "abcd"; - uint8_t b[] = "abcd"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 0) - return 0; - - return 1; -} - -static int MemcmpTest02 (void) -{ - uint8_t a[] = "abcdabcdabcdabcd"; - uint8_t b[] = "abcdabcdabcdabcd"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 0) - return 0; - - return 1; -} - -static int MemcmpTest03 (void) -{ - uint8_t a[] = "abcdabcd"; - uint8_t b[] = "abcdabcd"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 0) - return 0; - - return 1; -} - -static int MemcmpTest04 (void) -{ - uint8_t a[] = "abcd"; - uint8_t b[] = "abcD"; - - int r = SCMemcmp(a, b, sizeof(a)-1); - if (r != 1) { - printf("%s != %s, but memcmp returned %d: ", a, b, r); - return 0; - } - - return 1; -} - -static int MemcmpTest05 (void) -{ - uint8_t a[] = "abcdabcdabcdabcd"; - uint8_t b[] = "abcDabcdabcdabcd"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 1) - return 0; - - return 1; -} - -static int MemcmpTest06 (void) -{ - uint8_t a[] = "abcdabcd"; - uint8_t b[] = "abcDabcd"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 1) - return 0; - - return 1; -} - -static int MemcmpTest07 (void) -{ - uint8_t a[] = "abcd"; - uint8_t b[] = "abcde"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 0) - return 0; - - return 1; -} - -static int MemcmpTest08 (void) -{ - uint8_t a[] = "abcdabcdabcdabcd"; - uint8_t b[] = "abcdabcdabcdabcde"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 0) - return 0; - - return 1; -} - -static int MemcmpTest09 (void) -{ - uint8_t a[] = "abcdabcd"; - uint8_t b[] = "abcdabcde"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 0) - return 0; - - return 1; -} - -static int MemcmpTest10 (void) -{ - uint8_t a[] = "abcd"; - uint8_t b[] = "Zbcde"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 1) - return 0; - - return 1; -} - -static int MemcmpTest11 (void) -{ - uint8_t a[] = "abcdabcdabcdabcd"; - uint8_t b[] = "Zbcdabcdabcdabcde"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 1) - return 0; - - return 1; -} - -static int MemcmpTest12 (void) -{ - uint8_t a[] = "abcdabcd"; - uint8_t b[] = "Zbcdabcde"; - - if (SCMemcmp(a, b, sizeof(a)-1) != 1) - return 0; - - return 1; -} - -static int MemcmpTest13 (void) -{ - uint8_t a[] = "abcdefgh"; - uint8_t b[] = "AbCdEfGhIjK"; - - if (SCMemcmpLowercase(a, b, sizeof(a)-1) != 0) - return 0; - - return 1; -} - -#include "util-cpu.h" - -#define TEST_RUNS 1000000 - -static int MemcmpTest14 (void) -{ -#ifdef PROFILING - uint64_t ticks_start = 0; - uint64_t ticks_end = 0; - char *a[] = { "0123456789012345", "abc", "abcdefghij", "suricata", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; - char *b[] = { "1234567890123456", "abc", "abcdefghik", "suricatb", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; - - int t = 0; - int i, j; - int r1 = 0; - - printf("\n"); - - ticks_start = UtilCpuGetTicks(); - for (t = 0; t < TEST_RUNS; t++) { - for (i = 0; a[i] != NULL; i++) { - // printf("a[%d] = %s\n", i, a[i]); - size_t alen = strlen(a[i]) - 1; - - for (j = 0; b[j] != NULL; j++) { - // printf("b[%d] = %s\n", j, b[j]); - size_t blen = strlen(b[j]) - 1; - - r1 += (memcmp((uint8_t *)a[i], (uint8_t *)b[j], (alen < blen) ? alen : blen) ? 1 : 0); - } - } - } - ticks_end = UtilCpuGetTicks(); - printf("memcmp(%d) \t\t\t%"PRIu64"\n", TEST_RUNS, ((uint64_t)(ticks_end - ticks_start))/TEST_RUNS); - SCLogInfo("ticks passed %"PRIu64, ticks_end - ticks_start); - - printf("r1 %d\n", r1); - if (r1 != (51 * TEST_RUNS)) - return 0; -#endif - return 1; -} - -static int MemcmpTest15 (void) -{ -#ifdef PROFILING - uint64_t ticks_start = 0; - uint64_t ticks_end = 0; - char *a[] = { "0123456789012345", "abc", "abcdefghij", "suricata", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; - char *b[] = { "1234567890123456", "abc", "abcdefghik", "suricatb", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; - - int t = 0; - int i, j; - int r2 = 0; - - printf("\n"); - - ticks_start = UtilCpuGetTicks(); - for (t = 0; t < TEST_RUNS; t++) { - for (i = 0; a[i] != NULL; i++) { - // printf("a[%d] = %s\n", i, a[i]); - size_t alen = strlen(a[i]) - 1; - - for (j = 0; b[j] != NULL; j++) { - // printf("b[%d] = %s\n", j, b[j]); - size_t blen = strlen(b[j]) - 1; - - r2 += MemcmpLowercase((uint8_t *)a[i], (uint8_t *)b[j], (alen < blen) ? alen : blen); - } - } - } - ticks_end = UtilCpuGetTicks(); - printf("MemcmpLowercase(%d) \t\t%"PRIu64"\n", TEST_RUNS, ((uint64_t)(ticks_end - ticks_start))/TEST_RUNS); - SCLogInfo("ticks passed %"PRIu64, ticks_end - ticks_start); - - printf("r2 %d\n", r2); - if (r2 != (51 * TEST_RUNS)) - return 0; -#endif - return 1; -} - -static int MemcmpTest16 (void) -{ -#ifdef PROFILING - uint64_t ticks_start = 0; - uint64_t ticks_end = 0; - char *a[] = { "0123456789012345", "abc", "abcdefghij", "suricata", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; - char *b[] = { "1234567890123456", "abc", "abcdefghik", "suricatb", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; - - int t = 0; - int i, j; - int r3 = 0; - - printf("\n"); - - ticks_start = UtilCpuGetTicks(); - for (t = 0; t < TEST_RUNS; t++) { - for (i = 0; a[i] != NULL; i++) { - // printf("a[%d] = %s\n", i, a[i]); - size_t alen = strlen(a[i]) - 1; - - for (j = 0; b[j] != NULL; j++) { - // printf("b[%d] = %s\n", j, b[j]); - size_t blen = strlen(b[j]) - 1; - - r3 += SCMemcmp((uint8_t *)a[i], (uint8_t *)b[j], (alen < blen) ? alen : blen); - } - } - } - ticks_end = UtilCpuGetTicks(); - printf("SCMemcmp(%d) \t\t\t%"PRIu64"\n", TEST_RUNS, ((uint64_t)(ticks_end - ticks_start))/TEST_RUNS); - SCLogInfo("ticks passed %"PRIu64, ticks_end - ticks_start); - - printf("r3 %d\n", r3); - if (r3 != (51 * TEST_RUNS)) - return 0; -#endif - return 1; -} - -static int MemcmpTest17 (void) -{ -#ifdef PROFILING - uint64_t ticks_start = 0; - uint64_t ticks_end = 0; - char *a[] = { "0123456789012345", "abc", "abcdefghij", "suricata", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; - char *b[] = { "1234567890123456", "abc", "abcdefghik", "suricatb", "test", "xyz", "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr", "abcdefghijklmnopqrstuvwxyz", NULL }; - - int t = 0; - int i, j; - int r4 = 0; - - printf("\n"); - - ticks_start = UtilCpuGetTicks(); - for (t = 0; t < TEST_RUNS; t++) { - for (i = 0; a[i] != NULL; i++) { - // printf("a[%d] = %s\n", i, a[i]); - size_t alen = strlen(a[i]) - 1; - - for (j = 0; b[j] != NULL; j++) { - // printf("b[%d] = %s\n", j, b[j]); - size_t blen = strlen(b[j]) - 1; - - r4 += SCMemcmpLowercase((uint8_t *)a[i], (uint8_t *)b[j], (alen < blen) ? alen : blen); - } - } - } - ticks_end = UtilCpuGetTicks(); - printf("SCMemcmpLowercase(%d) \t\t%"PRIu64"\n", TEST_RUNS, ((uint64_t)(ticks_end - ticks_start))/TEST_RUNS); - SCLogInfo("ticks passed %"PRIu64, ticks_end - ticks_start); - - printf("r4 %d\n", r4); - if (r4 != (51 * TEST_RUNS)) - return 0; -#endif - return 1; -} - -struct MemcmpTest18Tests { - char *a; - char *b; - int result; -} memcmp_tests18_tests[] = { - { "abcdefgh", "!bcdefgh", 1, }, - { "?bcdefgh", "!bcdefgh", 1, }, - { "!bcdefgh", "abcdefgh", 1, }, - { "!bcdefgh", "?bcdefgh", 1, }, - { "zbcdefgh", "bbcdefgh", 1, }, - - { "abcdefgh12345678", "!bcdefgh12345678", 1, }, - { "?bcdefgh12345678", "!bcdefgh12345678", 1, }, - { "!bcdefgh12345678", "abcdefgh12345678", 1, }, - { "!bcdefgh12345678", "?bcdefgh12345678", 1, }, - { "bbcdefgh12345678", "zbcdefgh12345678", 1, }, - - { "abcdefgh", "abcdefgh", 0, }, - { "abcdefgh", "Abcdefgh", 0, }, - { "abcdefgh12345678", "Abcdefgh12345678", 0, }, - - { NULL, NULL, 0 }, - - }; - -static int MemcmpTest18 (void) -{ - struct MemcmpTest18Tests *t = memcmp_tests18_tests; - - while (t && t->a != NULL) { - - if (SCMemcmpLowercase(t->a, t->b, strlen(t->a)-1) != t->result) - return 0; - SCLogInfo("ok"); - t++; - } - - return 1; -} - -#endif /* UNITTESTS */ - -void MemcmpRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("MemcmpTest01", MemcmpTest01, 1); - UtRegisterTest("MemcmpTest02", MemcmpTest02, 1); - UtRegisterTest("MemcmpTest03", MemcmpTest03, 1); - UtRegisterTest("MemcmpTest04", MemcmpTest04, 1); - UtRegisterTest("MemcmpTest05", MemcmpTest05, 1); - UtRegisterTest("MemcmpTest06", MemcmpTest06, 1); - UtRegisterTest("MemcmpTest07", MemcmpTest07, 1); - UtRegisterTest("MemcmpTest08", MemcmpTest08, 1); - UtRegisterTest("MemcmpTest09", MemcmpTest09, 1); - UtRegisterTest("MemcmpTest10", MemcmpTest10, 1); - UtRegisterTest("MemcmpTest11", MemcmpTest11, 1); - UtRegisterTest("MemcmpTest12", MemcmpTest12, 1); - UtRegisterTest("MemcmpTest13", MemcmpTest13, 1); - UtRegisterTest("MemcmpTest14", MemcmpTest14, 1); - UtRegisterTest("MemcmpTest15", MemcmpTest15, 1); - UtRegisterTest("MemcmpTest16", MemcmpTest16, 1); - UtRegisterTest("MemcmpTest17", MemcmpTest17, 1); - UtRegisterTest("MemcmpTest18", MemcmpTest18, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/util-memcmp.h b/framework/src/suricata/src/util-memcmp.h deleted file mode 100644 index 9248f842..00000000 --- a/framework/src/suricata/src/util-memcmp.h +++ /dev/null @@ -1,502 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Memcmp implementations for SSE3, SSE4.1, SSE4.2 and TILE-Gx SIMD. - * - * Both SCMemcmp and SCMemcmpLowercase return 0 on a exact match, - * 1 on a failed match. - */ - -#ifndef __UTIL_MEMCMP_H__ -#define __UTIL_MEMCMP_H__ - -#include "util-optimize.h" - -/** \brief compare two patterns, converting the 2nd to lowercase - * \warning *ONLY* the 2nd pattern is converted to lowercase - */ -static inline int SCMemcmpLowercase(const void *, const void *, size_t); - -void MemcmpRegisterTests(void); - -static inline int -MemcmpLowercase(const void *s1, const void *s2, size_t n) -{ - ssize_t i; - - /* check backwards because we already tested the first - * 2 to 4 chars. This way we are more likely to detect - * a miss and thus speed up a little... */ - for (i = n - 1; i >= 0; i--) { - if (((uint8_t *)s1)[i] != u8_tolower(*(((uint8_t *)s2)+i))) - return 1; - } - - return 0; -} - -#if defined(__SSE4_2__) - -#include - -/* No SIMD support, fall back to plain memcmp and a home grown lowercase one */ - -static inline int SCMemcmp(const void *s1, const void *s2, size_t n) -{ - __m128i b1, b2; - - int r; - /* counter for how far we already matched in the buffer */ - size_t m = 0; - - do { - /* apparently we can't just read 16 bytes even though - * it almost always works fine :) */ - if (likely(n - m < 16)) { - return memcmp(s1, s2, n - m) ? 1 : 0; - } - - /* load the buffers into the 128bit vars */ - b1 = _mm_loadu_si128((const __m128i *) s1); - b2 = _mm_loadu_si128((const __m128i *) s2); - - /* do the actual compare */ - m += (r = _mm_cmpestri(b1, n - m, b2, 16, - _SIDD_CMP_EQUAL_EACH | _SIDD_MASKED_NEGATIVE_POLARITY)); - - s1 += 16; - s2 += 16; - } while (r == 16); - - return ((m == n) ? 0 : 1); -} - -/* Range of values of uppercase characters. We only use the first 2 bytes. */ -static char scmemcmp_uppercase[16] __attribute__((aligned(16))) = { - 'A', 'Z', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; - -/** \brief compare two buffers in a case insensitive way - * \param s1 buffer already in lowercase - * \param s2 buffer with mixed upper and lowercase - */ -static inline int SCMemcmpLowercase(const void *s1, const void *s2, size_t n) -{ - __m128i b1, b2, mask; - - int r; - /* counter for how far we already matched in the buffer */ - size_t m = 0; - - __m128i ucase = _mm_load_si128((const __m128i *) scmemcmp_uppercase); - __m128i nulls = _mm_setzero_si128(); - __m128i uplow = _mm_set1_epi8(0x20); - - do { - /* apparently we can't just read 16 bytes even though - * it almost always works fine :) */ - if (likely(n - m < 16)) { - return MemcmpLowercase(s1, s2, n - m); - } - - b1 = _mm_loadu_si128((const __m128i *) s1); - b2 = _mm_loadu_si128((const __m128i *) s2); - size_t len = n - m; - - /* The first step is creating a mask that is FF for all uppercase - * characters, 00 for all others */ - mask = _mm_cmpestrm(ucase, 2, b2, len, _SIDD_CMP_RANGES | _SIDD_UNIT_MASK); - /* Next we use that mask to create a new: this one has 0x20 for - * the uppercase chars, 00 for all other. */ - mask = _mm_blendv_epi8(nulls, uplow, mask); - /* finally, merge the mask and the buffer converting the - * uppercase to lowercase */ - b2 = _mm_add_epi8(b2, mask); - - /* search using our converted buffer */ - m += (r = _mm_cmpestri(b1, len, b2, 16, - _SIDD_CMP_EQUAL_EACH | _SIDD_MASKED_NEGATIVE_POLARITY)); - - s1 += 16; - s2 += 16; - } while (r == 16); - - return ((m == n) ? 0 : 1); -} - -#elif defined(__SSE4_1__) - -#include - -#define SCMEMCMP_BYTES 16 - -static inline int SCMemcmp(const void *s1, const void *s2, size_t len) -{ - size_t offset = 0; - __m128i b1, b2, c; - - do { - /* apparently we can't just read 16 bytes even though - * it almost always works fine :) */ - if (likely(len - offset < 16)) { - return memcmp(s1, s2, len - offset) ? 1 : 0; - } - - /* do unaligned loads using _mm_loadu_si128. On my Core2 E6600 using - * _mm_lddqu_si128 was about 2% slower even though it's supposed to - * be faster. */ - b1 = _mm_loadu_si128((const __m128i *) s1); - b2 = _mm_loadu_si128((const __m128i *) s2); - c = _mm_cmpeq_epi8(b1, b2); - - int diff = len - offset; - if (diff < 16) { - int rmask = ~(0xFFFFFFFF << diff); - - if ((_mm_movemask_epi8(c) & rmask) != rmask) { - return 1; - } - } else { - if (_mm_movemask_epi8(c) != 0x0000FFFF) { - return 1; - } - } - - offset += SCMEMCMP_BYTES; - s1 += SCMEMCMP_BYTES; - s2 += SCMEMCMP_BYTES; - } while (len > offset); - - return 0; -} - -#define UPPER_LOW 0x40 /* "A" - 1 */ -#define UPPER_HIGH 0x5B /* "Z" + 1 */ - -static inline int SCMemcmpLowercase(const void *s1, const void *s2, size_t len) -{ - size_t offset = 0; - __m128i b1, b2, mask1, mask2, upper1, upper2, nulls, uplow; - - /* setup registers for upper to lower conversion */ - upper1 = _mm_set1_epi8(UPPER_LOW); - upper2 = _mm_set1_epi8(UPPER_HIGH); - nulls = _mm_setzero_si128(); - uplow = _mm_set1_epi8(0x20); - - do { - /* apparently we can't just read 16 bytes even though - * it almost always works fine :) */ - if (likely(len - offset < 16)) { - return MemcmpLowercase(s1, s2, len - offset); - } - - /* unaligned loading of the bytes to compare */ - b1 = _mm_loadu_si128((const __m128i *) s1); - b2 = _mm_loadu_si128((const __m128i *) s2); - - /* mark all chars bigger than upper1 */ - mask1 = _mm_cmpgt_epi8(b2, upper1); - /* mark all chars lower than upper2 */ - mask2 = _mm_cmplt_epi8(b2, upper2); - /* merge the two, leaving only those that are true in both */ - mask1 = _mm_cmpeq_epi8(mask1, mask2); - /* Next we use that mask to create a new: this one has 0x20 for - * the uppercase chars, 00 for all other. */ - mask1 = _mm_blendv_epi8(nulls, uplow, mask1); - - /* add to b2, converting uppercase to lowercase */ - b2 = _mm_add_epi8(b2, mask1); - - /* now all is lowercase, let's do the actual compare (reuse mask1 reg) */ - mask1 = _mm_cmpeq_epi8(b1, b2); - - int diff = len - offset; - if (diff < 16) { - int rmask = ~(0xFFFFFFFF << diff); - - if ((_mm_movemask_epi8(mask1) & rmask) != rmask) { - return 1; - } - } else { - if (_mm_movemask_epi8(mask1) != 0x0000FFFF) { - return 1; - } - } - - offset += SCMEMCMP_BYTES; - s1 += SCMEMCMP_BYTES; - s2 += SCMEMCMP_BYTES; - } while (len > offset); - - return 0; -} - - - -#elif defined(__SSE3__) - -#include /* for SSE3 */ - -#define SCMEMCMP_BYTES 16 - -static inline int SCMemcmp(const void *s1, const void *s2, size_t len) -{ - size_t offset = 0; - __m128i b1, b2, c; - - do { - /* apparently we can't just read 16 bytes even though - * it almost always works fine :) */ - if (likely(len - offset < 16)) { - return memcmp(s1, s2, len - offset) ? 1 : 0; - } - - /* do unaligned loads using _mm_loadu_si128. On my Core2 E6600 using - * _mm_lddqu_si128 was about 2% slower even though it's supposed to - * be faster. */ - b1 = _mm_loadu_si128((const __m128i *) s1); - b2 = _mm_loadu_si128((const __m128i *) s2); - c = _mm_cmpeq_epi8(b1, b2); - - int diff = len - offset; - if (diff < 16) { - int rmask = ~(0xFFFFFFFF << diff); - - if ((_mm_movemask_epi8(c) & rmask) != rmask) { - return 1; - } - } else { - if (_mm_movemask_epi8(c) != 0x0000FFFF) { - return 1; - } - } - - offset += SCMEMCMP_BYTES; - s1 += SCMEMCMP_BYTES; - s2 += SCMEMCMP_BYTES; - } while (len > offset); - - return 0; -} - -#define UPPER_LOW 0x40 /* "A" - 1 */ -#define UPPER_HIGH 0x5B /* "Z" + 1 */ -#define UPPER_DELTA 0xDF /* 0xFF - 0x20 */ - -static inline int SCMemcmpLowercase(const void *s1, const void *s2, size_t len) -{ - size_t offset = 0; - __m128i b1, b2, mask1, mask2, upper1, upper2, delta; - - /* setup registers for upper to lower conversion */ - upper1 = _mm_set1_epi8(UPPER_LOW); - upper2 = _mm_set1_epi8(UPPER_HIGH); - delta = _mm_set1_epi8(UPPER_DELTA); - - do { - /* apparently we can't just read 16 bytes even though - * it almost always works fine :) */ - if (likely(len - offset < 16)) { - return MemcmpLowercase(s1, s2, len - offset); - } - - /* unaligned loading of the bytes to compare */ - b1 = _mm_loadu_si128((const __m128i *) s1); - b2 = _mm_loadu_si128((const __m128i *) s2); - - /* mark all chars bigger than upper1 */ - mask1 = _mm_cmpgt_epi8(b2, upper1); - /* mark all chars lower than upper2 */ - mask2 = _mm_cmplt_epi8(b2, upper2); - /* merge the two, leaving only those that are true in both */ - mask1 = _mm_cmpeq_epi8(mask1, mask2); - - /* sub delta leaves 0x20 only for uppercase positions, the - rest is 0x00 due to the saturation (reuse mask1 reg)*/ - mask1 = _mm_subs_epu8(mask1, delta); - - /* add to b2, converting uppercase to lowercase */ - b2 = _mm_add_epi8(b2, mask1); - - /* now all is lowercase, let's do the actual compare (reuse mask1 reg) */ - mask1 = _mm_cmpeq_epi8(b1, b2); - - int diff = len - offset; - if (diff < 16) { - int rmask = ~(0xFFFFFFFF << diff); - - if ((_mm_movemask_epi8(mask1) & rmask) != rmask) { - return 1; - } - } else { - if (_mm_movemask_epi8(mask1) != 0x0000FFFF) { - return 1; - } - } - - offset += SCMEMCMP_BYTES; - s1 += SCMEMCMP_BYTES; - s2 += SCMEMCMP_BYTES; - } while (len > offset); - - return 0; -} - -#elif defined(__tile__) - -#include - -/* Compare to non-zero sequence of bytes. */ -static inline int SCMemcmpNZ(const void *s1, const void *s2, size_t len) -{ - uint64_t b1, w1, aligned1; - uint64_t b2, w2, aligned2; - - /* Load aligned words containing the beginning of each string. - * These loads don't trigger unaligned events. - */ - w1 = __insn_ldna(s1); - w2 = __insn_ldna(s2); - /* Can't just read next 8 bytes because it might go past the end - * of a page. */ - while (len > 8) { - /* Here, the buffer extends into the next word by at least one - * byte, so it is safe to read the next word. Do an aligned - * loads on the next word. Then use the two words to create - * an aligned word from each string. */ - b1 = __insn_ldna(s1 + 8); - b2 = __insn_ldna(s2 + 8); - aligned1 = __insn_dblalign(w1, b1, s1); - aligned2 = __insn_dblalign(w2, b2, s2); - if (aligned1 != aligned2) - return 1; - - /* Move forward one word (8 bytes) */ - w1 = b1; - w2 = b2; - len -= 8; - s1 += 8; - s2 += 8; - } - /* Process the last up-to 8 bytes. */ - do { - if (*(char*)s1 != *(char*)s2) - return 1; - s1++; - s2++; - len--; - } while (len); - - return 0; -} - -/* Compare two sequences of bytes. */ -static inline int SCMemcmp(const void *s1, const void *s2, size_t len) -{ - if (len == 0) - return 0; - return SCMemcmpNZ(s1, s2, len); -} -/** \brief Convert 8 characters to lower case using SIMD. - * \param Word containing the 8 bytes. - * \return Word containing 8-bytes each converted to lowercase. - */ -static inline uint64_t -vec_tolower(uint64_t cc) -{ - /* For Uppercases letters, add 32 to convert to lower case. */ - uint64_t less_than_eq_Z = __insn_v1cmpltui (cc, 'Z' + 1); - uint64_t less_than_A = __insn_v1cmpltui (cc, 'A'); - uint64_t is_upper = __insn_v1cmpne (less_than_eq_Z, less_than_A); - return __insn_v1add (cc,__insn_v1shli (is_upper, 5)); -} - -/** \brief compare two buffers in a case insensitive way - * \param s1 buffer already in lowercase - * \param s2 buffer with mixed upper and lowercase - */ -static inline int SCMemcmpLowercase(const void *s1, const void *s2, size_t len) -{ - uint64_t b1, w1, aligned1; - uint64_t b2, w2, aligned2; - - if (len == 0) - return 0; - - /* TODO Check for already aligned cases. To optimize. */ - - /* Load word containing the beginning of each string. - * These loads don't trigger unaligned events. - */ - w1 = __insn_ldna(s1); - w2 = __insn_ldna(s2); - /* Can't just read next 8 bytes because it might go past the end - * of a page. */ - while (len > 8) { - /* Here, the buffer extends into the next word by at least one - * byte, so it is safe to read the next word. Do aligned - * loads on next word. Then use the two words to create an - * aligned word from each string. */ - b1 = __insn_ldna(s1 + 8); - b2 = __insn_ldna(s2 + 8); - aligned1 = __insn_dblalign(w1, b1, s1); - aligned2 = vec_tolower(__insn_dblalign(w2, b2, s2)); - if (aligned1 != aligned2) - return 1; - - /* Move forward one word (8 bytes) */ - w1 = b1; - w2 = b2; - len -= 8; - s1 += 8; - s2 += 8; - } - - do { - if (*(char*)s1 != tolower(*(char*)s2)) - return 1; - s1++; - s2++; - len--; - } while (len); - - return 0; -} - -#else - -/* No SIMD support, fall back to plain memcmp and a home grown lowercase one */ - -/* wrapper around memcmp to match the retvals of the SIMD implementations */ -#define SCMemcmp(a,b,c) ({ \ - memcmp((a), (b), (c)) ? 1 : 0; \ -}) - -static inline int SCMemcmpLowercase(const void *s1, const void *s2, size_t len) -{ - return MemcmpLowercase(s1, s2, len); -} - -#endif /* SIMD */ - -#endif /* __UTIL_MEMCMP_H__ */ - diff --git a/framework/src/suricata/src/util-memcpy.h b/framework/src/suricata/src/util-memcpy.h deleted file mode 100644 index bdb80242..00000000 --- a/framework/src/suricata/src/util-memcpy.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ken Steele - * - * Memcpy_tolower() - * - */ - -#ifndef __UTIL_MEMCPY_H__ -#define __UTIL_MEMCPY_H__ - -/** - * \internal - * \brief Does a memcpy of the input string to lowercase. - * - * \param d Pointer to the target area for memcpy. - * \param s Pointer to the src string for memcpy. - * \param len len of the string sent in s. - */ -static inline void memcpy_tolower(uint8_t *d, uint8_t *s, uint16_t len) -{ - uint16_t i; - for (i = 0; i < len; i++) - d[i] = u8_tolower(s[i]); - - return; -} - -#endif /* __UTIL_MEMCPY_H__ */ diff --git a/framework/src/suricata/src/util-memrchr.c b/framework/src/suricata/src/util-memrchr.c deleted file mode 100644 index ebac1764..00000000 --- a/framework/src/suricata/src/util-memrchr.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "util-unittest.h" - -#ifndef HAVE_MEMRCHR -void *memrchr (const void *s, int c, size_t n) -{ - const char *end = s + n; - - while (end > (const char *)s) { - if (*end == (char)c) - return (void *)end; - end--; - } - return NULL; -} -#endif /* HAVE_MEMRCHR */ - -#ifdef UNITTESTS -static int MemrchrTest01 (void) -{ - char *haystack = "abcabc"; - char needle = 'b'; - - char *ptr = memrchr(haystack, needle, strlen(haystack)); - if (ptr == NULL) - return 0; - - if (strlen(ptr) != 2) - return 0; - - if (strcmp(ptr, "bc") != 0) - return 0; - - return 1; -} -#endif - -void MemrchrRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("MemrchrTest01", MemrchrTest01, 1); -#endif -} diff --git a/framework/src/suricata/src/util-memrchr.h b/framework/src/suricata/src/util-memrchr.h deleted file mode 100644 index c3b5c8d8..00000000 --- a/framework/src/suricata/src/util-memrchr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - */ - -#ifndef __UTIL_MEMRCHR_H__ -#define __UTIL_MEMRCHR_H__ - -void *memrchr(const void *s, int c, size_t n); - -void MemrchrRegisterTests(void); - -#endif /* __UTIL_MEMRCHR_H__ */ diff --git a/framework/src/suricata/src/util-misc.c b/framework/src/suricata/src/util-misc.c deleted file mode 100644 index b72aa05e..00000000 --- a/framework/src/suricata/src/util-misc.c +++ /dev/null @@ -1,1141 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "config.h" -#include "suricata.h" -#include "util-byte.h" -#include "util-debug.h" -#include "util-unittest.h" - -#define PARSE_REGEX "^\\s*(\\d+(?:.\\d+)?)\\s*([a-zA-Z]{2})?\\s*$" -static pcre *parse_regex = NULL; -static pcre_extra *parse_regex_study = NULL; - -void ParseSizeInit(void) -{ - const char *eb; - int eo; - int opts = 0; - - parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); - if (parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset " - "%" PRId32 ": %s", PARSE_REGEX, eo, eb); - exit(EXIT_FAILURE); - } - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - exit(EXIT_FAILURE); - } -} - -void ParseSizeDeinit(void) -{ - - if (parse_regex != NULL) - pcre_free(parse_regex); - if (parse_regex_study != NULL) - pcre_free_study(parse_regex_study); -} - -/* size string parsing API */ - -static int ParseSizeString(const char *size, double *res) -{ -#define MAX_SUBSTRINGS 30 - int pcre_exec_ret; - int r; - int ov[MAX_SUBSTRINGS]; - int retval = 0; - char str[128]; - char str2[128]; - - *res = 0; - - pcre_exec_ret = pcre_exec(parse_regex, parse_regex_study, size, strlen(size), 0, 0, - ov, MAX_SUBSTRINGS); - if (!(pcre_exec_ret == 2 || pcre_exec_ret == 3)) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid size argument - %s. Valid size " - "argument should be in the format - \n" - "xxx <- indicates it is just bytes\n" - "xxxkb or xxxKb or xxxKB or xxxkB <- indicates kilobytes\n" - "xxxmb or xxxMb or xxxMB or xxxmB <- indicates megabytes\n" - "xxxgb or xxxGb or xxxGB or xxxgB <- indicates gigabytes.\n", - size); - retval = -2; - goto end; - } - - r = pcre_copy_substring((char *)size, ov, MAX_SUBSTRINGS, 1, - str, sizeof(str)); - if (r < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - retval = -2; - goto end; - } - - char *endptr, *str_ptr = str; - errno = 0; - *res = strtod(str_ptr, &endptr); - if (errno == ERANGE) { - SCLogError(SC_ERR_NUMERIC_VALUE_ERANGE, "Numeric value out of range"); - retval = -1; - goto end; - } else if (endptr == str_ptr) { - SCLogError(SC_ERR_INVALID_NUMERIC_VALUE, "Invalid numeric value"); - retval = -1; - goto end; - } - - if (pcre_exec_ret == 3) { - r = pcre_copy_substring((char *)size, ov, MAX_SUBSTRINGS, 2, - str2, sizeof(str2)); - if (r < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - retval = -2; - goto end; - } - - if (strcasecmp(str2, "kb") == 0) { - *res *= 1024; - } else if (strcasecmp(str2, "mb") == 0) { - *res *= 1024 * 1024; - } else if (strcasecmp(str2, "gb") == 0) { - *res *= 1024 * 1024 * 1024; - } else { - /* Bad unit. */ - retval = -1; - goto end; - } - } - - retval = 0; -end: - return retval; -} - -int ParseSizeStringU8(const char *size, uint8_t *res) -{ - double temp_res = 0; - - *res = 0; - int r = ParseSizeString(size, &temp_res); - if (r < 0) - return r; - - if (temp_res > UINT8_MAX) - return -1; - - *res = temp_res; - - return 0; -} - -int ParseSizeStringU16(const char *size, uint16_t *res) -{ - double temp_res = 0; - - *res = 0; - int r = ParseSizeString(size, &temp_res); - if (r < 0) - return r; - - if (temp_res > UINT16_MAX) - return -1; - - *res = temp_res; - - return 0; -} - -int ParseSizeStringU32(const char *size, uint32_t *res) -{ - double temp_res = 0; - - *res = 0; - int r = ParseSizeString(size, &temp_res); - if (r < 0) - return r; - - if (temp_res > UINT32_MAX) - return -1; - - *res = temp_res; - - return 0; -} - -int ParseSizeStringU64(const char *size, uint64_t *res) -{ - double temp_res = 0; - - *res = 0; - int r = ParseSizeString(size, &temp_res); - if (r < 0) - return r; - - if (temp_res > UINT64_MAX) - return -1; - - *res = temp_res; - - return 0; -} - -/*********************************Unittests********************************/ - -#ifdef UNITTESTS - -int UtilMiscParseSizeStringTest01(void) -{ - const char *str; - double result; - - /* no space */ - - str = "10"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10) { - goto error; - } - - str = "10kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10Kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10KB"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10mb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024 * 1024) { - goto error; - } - - str = "10gb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10737418240UL) { - goto error; - } - - - /* space start */ - - str = " 10"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10) { - goto error; - } - - str = " 10kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10Kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10KB"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10mb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024 * 1024) { - goto error; - } - - str = " 10gb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10737418240) { - goto error; - } - - /* space end */ - - str = "10 "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10) { - goto error; - } - - str = "10kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10Kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10KB "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10mb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024 * 1024) { - goto error; - } - - str = "10gb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10737418240) { - goto error; - } - - /* space start - space end */ - - str = " 10 "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10) { - goto error; - } - - str = " 10kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10Kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10KB "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10mb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024 * 1024) { - goto error; - } - - str = " 10gb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10737418240) { - goto error; - } - - - /* space between number and scale */ - - /* no space */ - - str = "10"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10) { - goto error; - } - - str = "10 kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10 Kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10 KB"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10 mb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024 * 1024) { - goto error; - } - - str = "10 gb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10737418240) { - goto error; - } - - - /* space start */ - - str = " 10"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10) { - goto error; - } - - str = " 10 kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10 Kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10 KB"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10 mb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024 * 1024) { - goto error; - } - - str = " 10 gb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10737418240) { - goto error; - } - - /* space end */ - - str = "10 "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10) { - goto error; - } - - str = "10 kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10 Kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10 KB "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = "10 mb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024 * 1024) { - goto error; - } - - str = "10 gb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10737418240) { - goto error; - } - - /* space start - space end */ - - str = " 10 "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10) { - goto error; - } - - str = " 10 kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10 Kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10 KB "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024) { - goto error; - } - - str = " 10 mb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10 * 1024 * 1024) { - goto error; - } - - str = " 10 gb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10737418240) { - goto error; - } - - /* no space */ - - str = "10.5"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5) { - goto error; - } - - str = "10.5kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5Kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5KB"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5mb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024) { - goto error; - } - - str = "10.5gb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024 * 1024) { - goto error; - } - - - /* space start */ - - str = " 10.5"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5) { - goto error; - } - - str = " 10.5kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5Kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5KB"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5mb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024) { - goto error; - } - - str = " 10.5gb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024 * 1024) { - goto error; - } - - /* space end */ - - str = "10.5 "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5) { - goto error; - } - - str = "10.5kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5Kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5KB "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5mb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024) { - goto error; - } - - str = "10.5gb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024 * 1024) { - goto error; - } - - /* space start - space end */ - - str = " 10.5 "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5) { - goto error; - } - - str = " 10.5kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5Kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5KB "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5mb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024) { - goto error; - } - - str = " 10.5gb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024 * 1024) { - goto error; - } - - - /* space between number and scale */ - - /* no space */ - - str = "10.5"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5) { - goto error; - } - - str = "10.5 kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5 Kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5 KB"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5 mb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024) { - goto error; - } - - str = "10.5 gb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024 * 1024) { - goto error; - } - - - /* space start */ - - str = " 10.5"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5) { - goto error; - } - - str = " 10.5 kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5 Kb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5 KB"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5 mb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024) { - goto error; - } - - str = " 10.5 gb"; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024 * 1024) { - goto error; - } - - /* space end */ - - str = "10.5 "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5) { - goto error; - } - - str = "10.5 kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5 Kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5 KB "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = "10.5 mb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024) { - goto error; - } - - str = "10.5 gb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024 * 1024) { - goto error; - } - - /* space start - space end */ - - str = " 10.5 "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5) { - goto error; - } - - str = " 10.5 kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5 Kb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5 KB "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024) { - goto error; - } - - str = " 10.5 mb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024) { - goto error; - } - - str = " 10.5 gb "; - result = 0; - if (ParseSizeString(str, &result) > 0) { - goto error; - } - if (result != 10.5 * 1024 * 1024 * 1024) { - goto error; - } - - /* Should fail on unknown units. */ - if (ParseSizeString("32eb", &result) > 0) { - goto error; - } - - return 1; - error: - return 0; -} - -#endif /* UNITTESTS */ - -void UtilMiscRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("UtilMiscParseSizeStringTest01", UtilMiscParseSizeStringTest01, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/util-misc.h b/framework/src/suricata/src/util-misc.h deleted file mode 100644 index 2245f829..00000000 --- a/framework/src/suricata/src/util-misc.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_MISC_H__ -#define __UTIL_MISC_H__ - -#include "util-error.h" - -/** - * \brief Generic API that can be used by all to log an - * invalid conf entry. - * \param param_name A string specifying the param name. - * \param format Format for the below value. For example "%s", "%"PRIu32, - etc. - * \param value Default value to be printed. - */ -#define WarnInvalidConfEntry(param_name, format, value) do { \ - SCLogWarning(SC_ERR_INVALID_YAML_CONF_ENTRY, \ - "Invalid conf entry found for " \ - "\"%s\". Using default value of \"" format "\".", \ - param_name, value); \ - } while (0) - -/* size string parsing API */ - -int ParseSizeStringU8(const char *, uint8_t *); -int ParseSizeStringU16(const char *, uint16_t *); -int ParseSizeStringU32(const char *, uint32_t *); -int ParseSizeStringU64(const char *, uint64_t *); -void UtilMiscRegisterTests(void); - -void ParseSizeInit(void); -void ParseSizeDeinit(void); - -#endif /* __UTIL_MISC_H__ */ diff --git a/framework/src/suricata/src/util-mpm-ac-bs.c b/framework/src/suricata/src/util-mpm-ac-bs.c deleted file mode 100644 index d6c4e785..00000000 --- a/framework/src/suricata/src/util-mpm-ac-bs.c +++ /dev/null @@ -1,2802 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * First iteration of aho-corasick MPM from - - * - * Efficient String Matching: An Aid to Bibliographic Search - * Alfred V. Aho and Margaret J. Corasick - * - * - Uses the delta table for calculating transitions, instead of having - * separate goto and failure transitions. - * - If we cross 2 ** 16 states, we use 4 bytes in the transition table - * to hold each state, otherwise we use 2 bytes. - * - This version of the MPM is heavy on memory, but it performs well. - * If you can fit the ruleset with this mpm on your box without hitting - * swap, this is the MPM to go for. - * - * \todo - Do a proper analyis of our existing MPMs and suggest a good one based - * on the pattern distribution and the expected traffic(say http). - * - Tried out loop unrolling without any perf increase. Need to dig deeper. - * - Irrespective of whether we cross 2 ** 16 states or not,shift to using - * uint32_t for state type, so that we can integrate it's status as a - * final state or not in the topmost byte. We are already doing it if - * state_count is > 2 ** 16. - * - Test case-senstive patterns if they have any ascii chars. If they - * don't treat them as nocase. - * - Carry out other optimizations we are working on. hashes, compression. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "util-mpm-ac-bs.h" - -#include "conf.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-memcmp.h" -#include "util-memcpy.h" - -void SCACBSInitCtx(MpmCtx *); -void SCACBSInitThreadCtx(MpmCtx *, MpmThreadCtx *, uint32_t); -void SCACBSDestroyCtx(MpmCtx *); -void SCACBSDestroyThreadCtx(MpmCtx *, MpmThreadCtx *); -int SCACBSAddPatternCI(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACBSAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACBSPreparePatterns(MpmCtx *mpm_ctx); -uint32_t SCACBSSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen); -void SCACBSPrintInfo(MpmCtx *mpm_ctx); -void SCACBSPrintSearchStats(MpmThreadCtx *mpm_thread_ctx); -void SCACBSRegisterTests(void); - -/* a placeholder to denote a failure transition in the goto table */ -#define SC_AC_BS_FAIL (-1) -/* size of the hash table used to speed up pattern insertions initially */ -#define INIT_HASH_SIZE 65536 - -#define STATE_QUEUE_CONTAINER_SIZE 65536 - -/** - * \brief Helper structure used by AC during state table creation - */ -typedef struct StateQueue_ { - int32_t store[STATE_QUEUE_CONTAINER_SIZE]; - int top; - int bot; -} StateQueue; - -/** - * \brief Register the aho-corasick mpm. - */ -void MpmACBSRegister(void) -{ - mpm_table[MPM_AC_BS].name = "ac-bs"; - /* don't need this. isn't that awesome? no more chopping and blah blah */ - mpm_table[MPM_AC_BS].max_pattern_length = 0; - - mpm_table[MPM_AC_BS].InitCtx = SCACBSInitCtx; - mpm_table[MPM_AC_BS].InitThreadCtx = SCACBSInitThreadCtx; - mpm_table[MPM_AC_BS].DestroyCtx = SCACBSDestroyCtx; - mpm_table[MPM_AC_BS].DestroyThreadCtx = SCACBSDestroyThreadCtx; - mpm_table[MPM_AC_BS].AddPattern = SCACBSAddPatternCS; - mpm_table[MPM_AC_BS].AddPatternNocase = SCACBSAddPatternCI; - mpm_table[MPM_AC_BS].Prepare = SCACBSPreparePatterns; - mpm_table[MPM_AC_BS].Search = SCACBSSearch; - mpm_table[MPM_AC_BS].Cleanup = NULL; - mpm_table[MPM_AC_BS].PrintCtx = SCACBSPrintInfo; - mpm_table[MPM_AC_BS].PrintThreadCtx = SCACBSPrintSearchStats; - mpm_table[MPM_AC_BS].RegisterUnittests = SCACBSRegisterTests; - - return; -} - -/** - * \internal - * \brief Initialize the AC context with user specified conf parameters. We - * aren't retrieving anything for AC conf now, but we will certainly - * need it, when we customize AC. - */ -static void SCACBSGetConfig() -{ - //ConfNode *ac_conf; - //const char *hash_val = NULL; - - //ConfNode *pm = ConfGetNode("pattern-matcher"); - - return; -} - -/** - * \internal - * \brief Creates a hash of the pattern. We use it for the hashing process - * during the initial pattern insertion time, to cull duplicate sigs. - * - * \param pat Pointer to the pattern. - * \param patlen Pattern length. - * - * \retval hash A 32 bit unsigned hash. - */ -static inline uint32_t SCACBSInitHashRaw(uint8_t *pat, uint16_t patlen) -{ - uint32_t hash = patlen * pat[0]; - if (patlen > 1) - hash += pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -/** - * \internal - * \brief Looks up a pattern. We use it for the hashing process during the - * the initial pattern insertion time, to cull duplicate sigs. - * - * \param ctx Pointer to the AC ctx. - * \param pat Pointer to the pattern. - * \param patlen Pattern length. - * \param flags Flags. We don't need this. - * - * \retval hash A 32 bit unsigned hash. - */ -static inline SCACBSPattern *SCACBSInitHashLookup(SCACBSCtx *ctx, uint8_t *pat, - uint16_t patlen, char flags, - uint32_t pid) -{ - uint32_t hash = SCACBSInitHashRaw(pat, patlen); - - if (ctx->init_hash == NULL) { - return NULL; - } - - SCACBSPattern *t = ctx->init_hash[hash]; - for ( ; t != NULL; t = t->next) { - if (t->id == pid) - return t; - } - - return NULL; -} - -/** - * \internal - * \brief Allocs a new pattern instance. - * - * \param mpm_ctx Pointer to the mpm context. - * - * \retval p Pointer to the newly created pattern. - */ -static inline SCACBSPattern *SCACBSAllocPattern(MpmCtx *mpm_ctx) -{ - SCACBSPattern *p = SCMalloc(sizeof(SCACBSPattern)); - if (unlikely(p == NULL)) { - exit(EXIT_FAILURE); - } - memset(p, 0, sizeof(SCACBSPattern)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACBSPattern); - - return p; -} - -/** - * \internal - * \brief Used to free SCACBSPattern instances. - * - * \param mpm_ctx Pointer to the mpm context. - * \param p Pointer to the SCACBSPattern instance to be freed. - */ -static inline void SCACBSFreePattern(MpmCtx *mpm_ctx, SCACBSPattern *p) -{ - if (p != NULL && p->cs != NULL && p->cs != p->ci) { - SCFree(p->cs); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->ci != NULL) { - SCFree(p->ci); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->original_pat != NULL) { - SCFree(p->original_pat); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL) { - SCFree(p); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACBSPattern); - } - return; -} - -static inline uint32_t SCACBSInitHash(SCACBSPattern *p) -{ - uint32_t hash = p->len * p->original_pat[0]; - if (p->len > 1) - hash += p->original_pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline int SCACBSInitHashAdd(SCACBSCtx *ctx, SCACBSPattern *p) -{ - uint32_t hash = SCACBSInitHash(p); - - if (ctx->init_hash == NULL) { - return 0; - } - - if (ctx->init_hash[hash] == NULL) { - ctx->init_hash[hash] = p; - return 0; - } - - SCACBSPattern *tt = NULL; - SCACBSPattern *t = ctx->init_hash[hash]; - - /* get the list tail */ - do { - tt = t; - t = t->next; - } while (t != NULL); - - tt->next = p; - - return 0; -} - -/** - * \internal - * \brief Add a pattern to the mpm-ac context. - * - * \param mpm_ctx Mpm context. - * \param pat Pointer to the pattern. - * \param patlen Length of the pattern. - * \param pid Pattern id - * \param sid Signature id (internal id). - * \param flags Pattern's MPM_PATTERN_* flags. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int SCACBSAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - - SCLogDebug("Adding pattern for ctx %p, patlen %"PRIu16" and pid %" PRIu32, - ctx, patlen, pid); - - if (patlen == 0) { - SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "pattern length 0"); - return 0; - } - - /* check if we have already inserted this pattern */ - SCACBSPattern *p = SCACBSInitHashLookup(ctx, pat, patlen, flags, pid); - if (p == NULL) { - SCLogDebug("Allocing new pattern"); - - /* p will never be NULL */ - p = SCACBSAllocPattern(mpm_ctx); - - p->len = patlen; - p->flags = flags; - p->id = pid; - - p->original_pat = SCMalloc(patlen); - if (p->original_pat == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->original_pat, pat, patlen); - - p->ci = SCMalloc(patlen); - if (p->ci == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy_tolower(p->ci, pat, patlen); - - /* setup the case sensitive part of the pattern */ - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - /* nocase means no difference between cs and ci */ - p->cs = p->ci; - } else { - if (memcmp(p->ci, pat, p->len) == 0) { - /* no diff between cs and ci: pat is lowercase */ - p->cs = p->ci; - } else { - p->cs = SCMalloc(patlen); - if (p->cs == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->cs, pat, patlen); - } - } - - /* put in the pattern hash */ - SCACBSInitHashAdd(ctx, p); - - //if (mpm_ctx->pattern_cnt == 65535) { - // SCLogError(SC_ERR_AHO_CORASICK, "Max search words reached. Can't " - // "insert anymore. Exiting"); - // exit(EXIT_FAILURE); - //} - mpm_ctx->pattern_cnt++; - - if (mpm_ctx->maxlen < patlen) - mpm_ctx->maxlen = patlen; - - if (mpm_ctx->minlen == 0) { - mpm_ctx->minlen = patlen; - } else { - if (mpm_ctx->minlen > patlen) - mpm_ctx->minlen = patlen; - } - - /* we need the max pat id */ - if (pid > ctx->max_pat_id) - ctx->max_pat_id = pid; - - p->sids_size = 1; - p->sids = SCMalloc(p->sids_size * sizeof(SigIntId)); - BUG_ON(p->sids == NULL); - p->sids[0] = sid; - } else { - /* TODO figure out how we can be called multiple times for the same CTX with the same sid */ - - int found = 0; - uint32_t x = 0; - for (x = 0; x < p->sids_size; x++) { - if (p->sids[x] == sid) { - found = 1; - break; - } - } - if (!found) { - SigIntId *sids = SCRealloc(p->sids, (sizeof(SigIntId) * (p->sids_size + 1))); - BUG_ON(sids == NULL); - p->sids = sids; - p->sids[p->sids_size] = sid; - p->sids_size++; - } - } - - return 0; - -error: - SCACBSFreePattern(mpm_ctx, p); - return -1; -} - -/** - * \internal - * \brief Initialize a new state in the goto and output tables. - * - * \param mpm_ctx Pointer to the mpm context. - * - * \retval The state id, of the newly created state. - */ -static inline int SCACBSInitNewState(MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int size = 0; - - /* reallocate space in the goto table to include a new state */ - size = (ctx->state_count + 1) * ctx->single_state_size; - ptmp = SCRealloc(ctx->goto_table, size); - if (ptmp == NULL) { - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ctx->goto_table = ptmp; - - /* set all transitions for the newly assigned state as FAIL transitions */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - ctx->goto_table[ctx->state_count][ascii_code] = SC_AC_BS_FAIL; - } - - /* reallocate space in the output table for the new state */ - size = (ctx->state_count + 1) * sizeof(SCACBSOutputTable); - ptmp = SCRealloc(ctx->output_table, size); - if (ptmp == NULL) { - SCFree(ctx->output_table); - ctx->output_table = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ctx->output_table = ptmp; - - memset(ctx->output_table + ctx->state_count, 0, sizeof(SCACBSOutputTable)); - - /* \todo using it temporarily now during dev, since I have restricted - * state var in SCACBSCtx->state_table to uint16_t. */ - //if (ctx->state_count > 65536) { - // printf("state count exceeded\n"); - // exit(EXIT_FAILURE); - //} - - return ctx->state_count++; -} - -/** - * \internal - * \brief Adds a pid to the output table for a state. - * - * \param state The state to whose output table we should add the pid. - * \param pid The pattern id to add. - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACBSSetOutputState(int32_t state, uint32_t pid, MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - SCACBSOutputTable *output_state = &ctx->output_table[state]; - uint32_t i = 0; - - for (i = 0; i < output_state->no_of_entries; i++) { - if (output_state->pids[i] == pid) - return; - } - - output_state->no_of_entries++; - ptmp = SCRealloc(output_state->pids, - output_state->no_of_entries * sizeof(uint32_t)); - if (ptmp == NULL) { - SCFree(output_state->pids); - output_state->pids = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - output_state->pids = ptmp; - - output_state->pids[output_state->no_of_entries - 1] = pid; - - return; -} - -/** - * \brief Helper function used by SCACBSCreateGotoTable. Adds a pattern to the - * goto table. - * - * \param pattern Pointer to the pattern. - * \param pattern_len Pattern length. - * \param pid The pattern id, that corresponds to this pattern. We - * need it to updated the output table for this pattern. - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSEnter(uint8_t *pattern, uint16_t pattern_len, uint32_t pid, - MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int32_t state = 0; - int32_t newstate = 0; - int i = 0; - int p = 0; - - /* walk down the trie till we have a match for the pattern prefix */ - state = 0; - for (i = 0; i < pattern_len; i++) { - if (ctx->goto_table[state][pattern[i]] != SC_AC_BS_FAIL) { - state = ctx->goto_table[state][pattern[i]]; - } else { - break; - } - } - - /* add the non-matching pattern suffix to the trie, from the last state - * we left off */ - for (p = i; p < pattern_len; p++) { - newstate = SCACBSInitNewState(mpm_ctx); - ctx->goto_table[state][pattern[p]] = newstate; - state = newstate; - } - - /* add this pattern id, to the output table of the last state, where the - * pattern ends in the trie */ - SCACBSSetOutputState(state, pid, mpm_ctx); - - return; -} - -/** - * \internal - * \brief Create the goto table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSCreateGotoTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - uint32_t i = 0; - - /* add each pattern to create the goto table */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - SCACBSEnter(ctx->parray[i]->ci, ctx->parray[i]->len, - ctx->parray[i]->id, mpm_ctx); - } - - int ascii_code = 0; - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - if (ctx->goto_table[0][ascii_code] == SC_AC_BS_FAIL) { - ctx->goto_table[0][ascii_code] = 0; - } - } - - return; -} - -static inline int SCACBSStateQueueIsEmpty(StateQueue *q) -{ - if (q->top == q->bot) - return 1; - else - return 0; -} - -static inline void SCACBSEnqueue(StateQueue *q, int32_t state) -{ - int i = 0; - - /*if we already have this */ - for (i = q->bot; i < q->top; i++) { - if (q->store[i] == state) - return; - } - - q->store[q->top++] = state; - - if (q->top == STATE_QUEUE_CONTAINER_SIZE) - q->top = 0; - - if (q->top == q->bot) { - SCLogCritical(SC_ERR_AHO_CORASICK, "Just ran out of space in the queue. " - "Fatal Error. Exiting. Please file a bug report on this"); - exit(EXIT_FAILURE); - } - - return; -} - -static inline int32_t SCACBSDequeue(StateQueue *q) -{ - if (q->bot == STATE_QUEUE_CONTAINER_SIZE) - q->bot = 0; - - if (q->bot == q->top) { - SCLogCritical(SC_ERR_AHO_CORASICK, "StateQueue behaving weirdly. " - "Fatal Error. Exiting. Please file a bug report on this"); - exit(EXIT_FAILURE); - } - - return q->store[q->bot++]; -} - -/* -#define SCACBSStateQueueIsEmpty(q) (((q)->top == (q)->bot) ? 1 : 0) - -#define SCACBSEnqueue(q, state) do { \ - int i = 0; \ - \ - for (i = (q)->bot; i < (q)->top; i++) { \ - if ((q)->store[i] == state) \ - return; \ - } \ - \ - (q)->store[(q)->top++] = state; \ - \ - if ((q)->top == STATE_QUEUE_CONTAINER_SIZE) \ - (q)->top = 0; \ - \ - if ((q)->top == (q)->bot) { \ - SCLogCritical(SC_ERR_AHO_CORASICK, "Just ran out of space in the queue. " \ - "Fatal Error. Exiting. Please file a bug report on this"); \ - exit(EXIT_FAILURE); \ - } \ - } while (0) - -#define SCACBSDequeue(q) ( (((q)->bot == STATE_QUEUE_CONTAINER_SIZE)? ((q)->bot = 0): 0), \ - (((q)->bot == (q)->top) ? \ - (printf("StateQueue behaving " \ - "weirdly. Fatal Error. Exiting. Please " \ - "file a bug report on this"), \ - exit(EXIT_FAILURE)) : 0), \ - (q)->store[(q)->bot++]) \ -*/ - -/** - * \internal - * \brief Club the output data from 2 states and store it in the 1st state. - * dst_state_data = {dst_state_data} UNION {src_state_data} - * - * \param dst_state First state(also the destination) for the union operation. - * \param src_state Second state for the union operation. - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSClubOutputStates(int32_t dst_state, int32_t src_state, - MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - uint32_t i = 0; - uint32_t j = 0; - - SCACBSOutputTable *output_dst_state = &ctx->output_table[dst_state]; - SCACBSOutputTable *output_src_state = &ctx->output_table[src_state]; - - for (i = 0; i < output_src_state->no_of_entries; i++) { - for (j = 0; j < output_dst_state->no_of_entries; j++) { - if (output_src_state->pids[i] == output_dst_state->pids[j]) { - break; - } - } - if (j == output_dst_state->no_of_entries) { - output_dst_state->no_of_entries++; - - ptmp = SCRealloc(output_dst_state->pids, - (output_dst_state->no_of_entries * sizeof(uint32_t))); - if (ptmp == NULL) { - SCFree(output_dst_state->pids); - output_dst_state->pids = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - else { - output_dst_state->pids = ptmp; - } - - output_dst_state->pids[output_dst_state->no_of_entries - 1] = - output_src_state->pids[i]; - } - } - - return; -} - -/** - * \internal - * \brief Create the failure table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSCreateFailureTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int32_t state = 0; - int32_t r_state = 0; - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - /* allot space for the failure table. A failure entry in the table for - * every state(SCACBSCtx->state_count) */ - ctx->failure_table = SCMalloc(ctx->state_count * sizeof(int32_t)); - if (ctx->failure_table == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->failure_table, 0, ctx->state_count * sizeof(int32_t)); - - /* add the failure transitions for the 0th state, and add every non-fail - * transition from the 0th state to the queue for further processing - * of failure states */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[0][ascii_code]; - if (temp_state != 0) { - SCACBSEnqueue(&q, temp_state); - ctx->failure_table[temp_state] = 0; - } - } - - while (!SCACBSStateQueueIsEmpty(&q)) { - /* pick up every state from the queue and add failure transitions */ - r_state = SCACBSDequeue(&q); - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state == SC_AC_BS_FAIL) - continue; - SCACBSEnqueue(&q, temp_state); - state = ctx->failure_table[r_state]; - - while(ctx->goto_table[state][ascii_code] == SC_AC_BS_FAIL) - state = ctx->failure_table[state]; - ctx->failure_table[temp_state] = ctx->goto_table[state][ascii_code]; - SCACBSClubOutputStates(temp_state, ctx->failure_table[temp_state], - mpm_ctx); - } - } - - return; -} - -/** - * \internal - * \brief Create the delta table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSCreateDeltaTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int32_t r_state = 0; - - if (ctx->state_count < 32767) { - ctx->state_table_u16 = SCMalloc(ctx->state_count * - sizeof(SC_AC_BS_STATE_TYPE_U16) * 256); - if (ctx->state_table_u16 == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->state_table_u16, 0, - ctx->state_count * sizeof(SC_AC_BS_STATE_TYPE_U16) * 256); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (ctx->state_count * - sizeof(SC_AC_BS_STATE_TYPE_U16) * 256); - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - SC_AC_BS_STATE_TYPE_U16 temp_state = ctx->goto_table[0][ascii_code]; - ctx->state_table_u16[0][ascii_code] = temp_state; - if (temp_state != 0) - SCACBSEnqueue(&q, temp_state); - } - - while (!SCACBSStateQueueIsEmpty(&q)) { - r_state = SCACBSDequeue(&q); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state != SC_AC_BS_FAIL) { - SCACBSEnqueue(&q, temp_state); - ctx->state_table_u16[r_state][ascii_code] = temp_state; - } else { - ctx->state_table_u16[r_state][ascii_code] = - ctx->state_table_u16[ctx->failure_table[r_state]][ascii_code]; - } - } - } - } else { - /* create space for the state table. We could have used the existing goto - * table, but since we have it set to hold 32 bit state values, we will create - * a new state table here of type SC_AC_BS_STATE_TYPE(current set to uint16_t) */ - ctx->state_table_u32 = SCMalloc(ctx->state_count * - sizeof(SC_AC_BS_STATE_TYPE_U32) * 256); - if (ctx->state_table_u32 == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->state_table_u32, 0, - ctx->state_count * sizeof(SC_AC_BS_STATE_TYPE_U32) * 256); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (ctx->state_count * - sizeof(SC_AC_BS_STATE_TYPE_U32) * 256); - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - SC_AC_BS_STATE_TYPE_U32 temp_state = ctx->goto_table[0][ascii_code]; - ctx->state_table_u32[0][ascii_code] = temp_state; - if (temp_state != 0) - SCACBSEnqueue(&q, temp_state); - } - - while (!SCACBSStateQueueIsEmpty(&q)) { - r_state = SCACBSDequeue(&q); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state != SC_AC_BS_FAIL) { - SCACBSEnqueue(&q, temp_state); - ctx->state_table_u32[r_state][ascii_code] = temp_state; - } else { - ctx->state_table_u32[r_state][ascii_code] = - ctx->state_table_u32[ctx->failure_table[r_state]][ascii_code]; - } - } - } - } - - return; -} - -static inline void SCACBSClubOutputStatePresenceWithDeltaTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int ascii_code = 0; - uint32_t state = 0; - uint32_t temp_state = 0; - - if (ctx->state_count < 32767) { - for (state = 0; state < ctx->state_count; state++) { - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - temp_state = ctx->state_table_u16[state & 0x7FFF][ascii_code]; - if (ctx->output_table[temp_state & 0x7FFF].no_of_entries != 0) - ctx->state_table_u16[state & 0x7FFF][ascii_code] |= (1 << 15); - } - } - } else { - for (state = 0; state < ctx->state_count; state++) { - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - temp_state = ctx->state_table_u32[state & 0x00FFFFFF][ascii_code]; - if (ctx->output_table[temp_state & 0x00FFFFFF].no_of_entries != 0) - ctx->state_table_u32[state & 0x00FFFFFF][ascii_code] |= (1 << 24); - } - } - } - - return; -} - -static inline void SCACBSInsertCaseSensitiveEntriesForPatterns(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - uint32_t state = 0; - uint32_t k = 0; - - for (state = 0; state < ctx->state_count; state++) { - if (ctx->output_table[state].no_of_entries == 0) - continue; - - for (k = 0; k < ctx->output_table[state].no_of_entries; k++) { - if (ctx->pid_pat_list[ctx->output_table[state].pids[k]].cs != NULL) { - ctx->output_table[state].pids[k] &= 0x0000FFFF; - ctx->output_table[state].pids[k] |= 1 << 16; - } - } - } - - return; -} - -#if 0 -static void SCACBSPrintDeltaTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int i = 0, j = 0; - - printf("##############Delta Table##############\n"); - for (i = 0; i < ctx->state_count; i++) { - printf("%d: \n", i); - for (j = 0; j < 256; j++) { - if (SCACBSGetDelta(i, j, mpm_ctx) != 0) { - printf(" %c -> %d\n", j, SCACBSGetDelta(i, j, mpm_ctx)); - } - } - } - - return; -} -#endif - -static inline int SCACBSZeroTransitionPresent(SCACBSCtx *ctx, uint32_t state) -{ - if (state == 0) - return 1; - - if (ctx->state_count < 32767) { - int ascii; - for (ascii = 0; ascii < 256; ascii++) { - if ((ctx->state_table_u16[0][ascii] & 0x7fff) == (state & 0x7fff)) { - return 1; - } - } - - return 0; - } else { - int ascii; - for (ascii = 0; ascii < 256; ascii++) { - if ((ctx->state_table_u32[0][ascii] & 0x00FFFFFF) == - (state & 0x00FFFFFF)) { - return 1; - } - } - - return 0; - } -} - -/** - * \internal - * \brief Creates a new goto table structure(throw out all the failure - * transitions), to hold the existing goto table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSCreateModDeltaTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - - if (ctx->state_count < 32767) { - int size = 0; - uint32_t state; - - for (state = 1; state < ctx->state_count; state++) { - int ascii_code; - int k = 0; - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - uint32_t temp_state = ctx->state_table_u16[state][ascii_code]; - if (SCACBSZeroTransitionPresent(ctx, temp_state)) - continue; - k++; - } - size += sizeof(uint16_t) * k * 2; - } - - /* Let us use uint16_t for all. That way we don//'t have to worry about - * alignment. Technically 8 bits is all we need to store ascii codes, - * but by avoiding it, we save a lot of time on handling alignment */ - size += (ctx->state_count * sizeof(SC_AC_BS_STATE_TYPE_U16) + - 256 * sizeof(SC_AC_BS_STATE_TYPE_U16) * 1); - ctx->state_table_mod = SCMalloc(size); - if (ctx->state_table_mod == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->state_table_mod, 0, size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += size; - - /* buffer to hold pointers in the buffer, so that a state can use it - * directly to access its state data */ - ctx->state_table_mod_pointers = SCMalloc(ctx->state_count * sizeof(uint8_t *)); - if (ctx->state_table_mod_pointers == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->state_table_mod_pointers, 0, - ctx->state_count * sizeof(uint8_t *)); - - SC_AC_BS_STATE_TYPE_U16 temp_states[256]; - uint16_t *curr_loc = (uint16_t *)ctx->state_table_mod; - uint16_t *no_of_entries = NULL; - uint16_t *ascii_codes = NULL; - state = 0; - uint16_t ascii_code = 0; - uint16_t k = 0; - for (state = 0; state < ctx->state_count; state++) { - /* store the starting location in the buffer for this state */ - ctx->state_table_mod_pointers[state] = (uint8_t *)curr_loc; - no_of_entries = curr_loc++; - ascii_codes = curr_loc; - k = 0; - /* store all states that have non 0 transitions in the temp buffer */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - uint32_t temp_state = ctx->state_table_u16[state][ascii_code]; - if (state != 0 && SCACBSZeroTransitionPresent(ctx, temp_state)) - continue; - - ascii_codes[k] = ascii_code; - temp_states[k] = ctx->state_table_u16[state][ascii_code]; - k++; - } - /* if we have any non 0 transitions from our previous for search, - * store the acii codes as well the corresponding states */ - if (k > 0) { - no_of_entries[0] = k; - if (state != 0) - curr_loc += k; - memcpy(curr_loc, temp_states, k * sizeof(SC_AC_BS_STATE_TYPE_U16)); - curr_loc += k; - } - } - - /* > 33766 */ - } else { - int size = 0; - uint32_t state; - for (state = 1; state < ctx->state_count; state++) { - int ascii_code; - int k = 0; - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - uint32_t temp_state = ctx->state_table_u32[state][ascii_code]; - if (SCACBSZeroTransitionPresent(ctx, temp_state)) - continue; - k++; - } - size += sizeof(uint32_t) * k * 2; - } - - /* Let us use uint32_t for all. That way we don//'t have to worry about - * alignment. Technically 8 bits is all we need to store ascii codes, - * but by avoiding it, we save a lot of time on handling alignment */ - size += (ctx->state_count * sizeof(SC_AC_BS_STATE_TYPE_U32) + - 256 * sizeof(SC_AC_BS_STATE_TYPE_U32) * 1); - ctx->state_table_mod = SCMalloc(size); - if (ctx->state_table_mod == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->state_table_mod, 0, size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += size; - - /* buffer to hold pointers in the buffer, so that a state can use it - * directly to access its state data */ - ctx->state_table_mod_pointers = SCMalloc(ctx->state_count * sizeof(uint8_t *)); - if (ctx->state_table_mod_pointers == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->state_table_mod_pointers, 0, - ctx->state_count * sizeof(uint8_t *)); - - SC_AC_BS_STATE_TYPE_U32 temp_states[256]; - uint32_t *curr_loc = (uint32_t *)ctx->state_table_mod; - uint32_t *no_of_entries = NULL; - uint32_t *ascii_codes = NULL; - state = 0; - uint32_t ascii_code = 0; - uint32_t k = 0; - for (state = 0; state < ctx->state_count; state++) { - /* store the starting location in the buffer for this state */ - ctx->state_table_mod_pointers[state] = (uint8_t *)curr_loc; - no_of_entries = curr_loc++; - ascii_codes = curr_loc; - k = 0; - /* store all states that have non 0 transitions in the temp buffer */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - uint32_t temp_state = ctx->state_table_u32[state][ascii_code]; - if (state != 0 && SCACBSZeroTransitionPresent(ctx, temp_state)) - continue; - - ascii_codes[k] = ascii_code; - temp_states[k] = ctx->state_table_u32[state][ascii_code]; - k++; - } - /* if we have any non 0 transitions from our previous for search, - * store the acii codes as well the corresponding states */ - if (k > 0) { - no_of_entries[0] = k; - if (state != 0) - curr_loc += k; - memcpy(curr_loc, temp_states, k * sizeof(SC_AC_BS_STATE_TYPE_U32)); - curr_loc += k; - } - } - - } - - return; -} - -/** - * \brief Process the patterns and prepare the state table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSPrepareStateTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - - /* create the 0th state in the goto table and output_table */ - SCACBSInitNewState(mpm_ctx); - - /* create the goto table */ - SCACBSCreateGotoTable(mpm_ctx); - /* create the failure table */ - SCACBSCreateFailureTable(mpm_ctx); - /* create the final state(delta) table */ - SCACBSCreateDeltaTable(mpm_ctx); - /* club the output state presence with delta transition entries */ - SCACBSClubOutputStatePresenceWithDeltaTable(mpm_ctx); - /* create the modified table */ - SCACBSCreateModDeltaTable(mpm_ctx); - - /* club nocase entries */ - SCACBSInsertCaseSensitiveEntriesForPatterns(mpm_ctx); - -// int state = 0; -// for (state = 0; state < ctx->state_count; state++) { -// int i = 0; -// for (i = 0; i < 256; i++) { -// if (ctx->state_table_u16[state][i] != 0) { -// printf("%d-%d-%d\n", state, i, ctx->state_table_u16[state][i] & 0x7fff) ; -// } -// } -// } - -#if 0 - SCACBSPrintDeltaTable(mpm_ctx); -#endif - - /* we don't need these anymore */ - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - SCFree(ctx->failure_table); - ctx->failure_table = NULL; - SCFree(ctx->state_table_u16); - ctx->state_table_u16 = NULL; - SCFree(ctx->state_table_u32); - ctx->state_table_u32 = NULL; - - return; -} - -/** - * \brief Process the patterns added to the mpm, and create the internal tables. - * - * \param mpm_ctx Pointer to the mpm context. - */ -int SCACBSPreparePatterns(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - - if (mpm_ctx->pattern_cnt == 0 || ctx->init_hash == NULL) { - SCLogDebug("no patterns supplied to this mpm_ctx"); - return 0; - } - - /* alloc the pattern array */ - ctx->parray = (SCACBSPattern **)SCMalloc(mpm_ctx->pattern_cnt * - sizeof(SCACBSPattern *)); - if (ctx->parray == NULL) - goto error; - memset(ctx->parray, 0, mpm_ctx->pattern_cnt * sizeof(SCACBSPattern *)); - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (mpm_ctx->pattern_cnt * sizeof(SCACBSPattern *)); - - /* populate it with the patterns in the hash */ - uint32_t i = 0, p = 0; - for (i = 0; i < INIT_HASH_SIZE; i++) { - SCACBSPattern *node = ctx->init_hash[i], *nnode = NULL; - while(node != NULL) { - nnode = node->next; - node->next = NULL; - ctx->parray[p++] = node; - node = nnode; - } - } - - /* we no longer need the hash, so free it's memory */ - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - - /* the memory consumed by a single state in our goto table */ - ctx->single_state_size = sizeof(int32_t) * 256; - - /* handle no case patterns */ - ctx->pid_pat_list = SCMalloc((ctx->max_pat_id + 1)* sizeof(SCACBSPatternList)); - if (ctx->pid_pat_list == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->pid_pat_list, 0, (ctx->max_pat_id + 1) * sizeof(SCACBSPatternList)); - - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (!(ctx->parray[i]->flags & MPM_PATTERN_FLAG_NOCASE)) { - ctx->pid_pat_list[ctx->parray[i]->id].cs = SCMalloc(ctx->parray[i]->len); - if (ctx->pid_pat_list[ctx->parray[i]->id].cs == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memcpy(ctx->pid_pat_list[ctx->parray[i]->id].cs, - ctx->parray[i]->original_pat, ctx->parray[i]->len); - ctx->pid_pat_list[ctx->parray[i]->id].patlen = ctx->parray[i]->len; - } - - /* ACPatternList now owns this memory */ - ctx->pid_pat_list[ctx->parray[i]->id].sids_size = ctx->parray[i]->sids_size; - ctx->pid_pat_list[ctx->parray[i]->id].sids = ctx->parray[i]->sids; - } - - /* prepare the state table required by AC */ - SCACBSPrepareStateTable(mpm_ctx); - - /* free all the stored patterns. Should save us a good 100-200 mbs */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - SCACBSFreePattern(mpm_ctx, ctx->parray[i]); - } - } - SCFree(ctx->parray); - ctx->parray = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(SCACBSPattern *)); - - return 0; - -error: - return -1; -} - -/** - * \brief Init the mpm thread context. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - * \param matchsize We don't need this. - */ -void SCACBSInitThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, uint32_t matchsize) -{ - memset(mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - - mpm_thread_ctx->ctx = SCMalloc(sizeof(SCACBSThreadCtx)); - if (mpm_thread_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - memset(mpm_thread_ctx->ctx, 0, sizeof(SCACBSThreadCtx)); - mpm_thread_ctx->memory_cnt++; - mpm_thread_ctx->memory_size += sizeof(SCACBSThreadCtx); - - return; -} - -/** - * \brief Initialize the AC context. - * - * \param mpm_ctx Mpm context. - * \param module_handle Cuda module handle from the cuda handler API. We don't - * have to worry about this here. - */ -void SCACBSInitCtx(MpmCtx *mpm_ctx) -{ - if (mpm_ctx->ctx != NULL) - return; - - mpm_ctx->ctx = SCMalloc(sizeof(SCACBSCtx)); - if (mpm_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - memset(mpm_ctx->ctx, 0, sizeof(SCACBSCtx)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACBSCtx); - - /* initialize the hash we use to speed up pattern insertions */ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - ctx->init_hash = SCMalloc(sizeof(SCACBSPattern *) * INIT_HASH_SIZE); - if (ctx->init_hash == NULL) { - exit(EXIT_FAILURE); - } - memset(ctx->init_hash, 0, sizeof(SCACBSPattern *) * INIT_HASH_SIZE); - - /* get conf values for AC from our yaml file. We have no conf values for - * now. We will certainly need this, as we develop the algo */ - SCACBSGetConfig(); - - SCReturn; -} - -/** - * \brief Destroy the mpm thread context. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - */ -void SCACBSDestroyThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx) -{ - SCACBSPrintSearchStats(mpm_thread_ctx); - - if (mpm_thread_ctx->ctx != NULL) { - SCFree(mpm_thread_ctx->ctx); - mpm_thread_ctx->ctx = NULL; - mpm_thread_ctx->memory_cnt--; - mpm_thread_ctx->memory_size -= sizeof(SCACBSThreadCtx); - } - - return; -} - -/** - * \brief Destroy the mpm context. - * - * \param mpm_ctx Pointer to the mpm context. - */ -void SCACBSDestroyCtx(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - if (ctx == NULL) - return; - - if (ctx->init_hash != NULL) { - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (INIT_HASH_SIZE * sizeof(SCACBSPattern *)); - } - - if (ctx->parray != NULL) { - uint32_t i; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - SCACBSFreePattern(mpm_ctx, ctx->parray[i]); - } - } - - SCFree(ctx->parray); - ctx->parray = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(SCACBSPattern *)); - } - - if (ctx->state_table_u16 != NULL) { - SCFree(ctx->state_table_u16); - ctx->state_table_u16 = NULL; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size -= (ctx->state_count * - sizeof(SC_AC_BS_STATE_TYPE_U16) * 256); - } else if (ctx->state_table_u32 != NULL) { - SCFree(ctx->state_table_u32); - ctx->state_table_u32 = NULL; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size -= (ctx->state_count * - sizeof(SC_AC_BS_STATE_TYPE_U32) * 256); - } - - if (ctx->output_table != NULL) { - uint32_t state_count; - for (state_count = 0; state_count < ctx->state_count; state_count++) { - if (ctx->output_table[state_count].pids != NULL) { - SCFree(ctx->output_table[state_count].pids); - } - } - SCFree(ctx->output_table); - } - - if (ctx->pid_pat_list != NULL) { - int i; - for (i = 0; i < (ctx->max_pat_id + 1); i++) { - if (ctx->pid_pat_list[i].cs != NULL) - SCFree(ctx->pid_pat_list[i].cs); - if (ctx->pid_pat_list[i].sids != NULL) - SCFree(ctx->pid_pat_list[i].sids); - } - SCFree(ctx->pid_pat_list); - } - - if (ctx->state_table_mod != NULL) { - SCFree(ctx->state_table_mod); - ctx->state_table_mod = NULL; - } - - if (ctx->state_table_mod_pointers != NULL) { - SCFree(ctx->state_table_mod_pointers); - ctx->state_table_mod_pointers = NULL; - } - - SCFree(mpm_ctx->ctx); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACBSCtx); - - return; -} - -/** - * \brief The aho corasick search function. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - * \param pmq Pointer to the Pattern Matcher Queue to hold - * search matches. - * \param buf Buffer to be searched. - * \param buflen Buffer length. - * - * \retval matches Match count. - */ -uint32_t SCACBSSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int i = 0; - int matches = 0; - uint8_t buf_local; - - /* \todo tried loop unrolling with register var, with no perf increase. Need - * to dig deeper */ - /* \todo Change it for stateful MPM. Supply the state using mpm_thread_ctx */ - SCACBSPatternList *pid_pat_list = ctx->pid_pat_list; - - uint8_t bitarray[pmq->pattern_id_bitarray_size]; - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - - if (ctx->state_count < 32767) { - register SC_AC_BS_STATE_TYPE_U16 state = 0; - uint16_t no_of_entries; - uint16_t *ascii_codes; - uint16_t **state_table_mod_pointers = (uint16_t **)ctx->state_table_mod_pointers; - uint16_t *zero_state = state_table_mod_pointers[0] + 1; - - for (i = 0; i < buflen; i++) { - if (state == 0) { - state = zero_state[u8_tolower(buf[i])]; - } else { - no_of_entries = *(state_table_mod_pointers[state & 0x7FFF]); - if (no_of_entries == 1) { - ascii_codes = state_table_mod_pointers[state & 0x7FFF] + 1; - buf_local = u8_tolower(buf[i]); - if (buf_local == ascii_codes[0]) { - state = *(ascii_codes + no_of_entries);; - } else { - state = zero_state[buf_local]; - } - } else { - if (no_of_entries == 0) { - state = zero_state[u8_tolower(buf[i])]; - goto match_u16; - } - buf_local = u8_tolower(buf[i]); - ascii_codes = state_table_mod_pointers[state & 0x7FFF] + 1; - int low = 0; - int high = no_of_entries; - int mid; - state = 0; - while (low <= high) { - mid = (low + high) / 2; - if (ascii_codes[mid] == buf_local) { - state = ((ascii_codes + no_of_entries))[mid]; - goto match_u16; - } else if (ascii_codes[mid] < buf_local) { - low = mid + 1; - } else { - high = mid - 1; - } - } /* while */ - state = zero_state[buf_local]; - } /* else - if (no_of_entires == 1) */ - } - - match_u16: - if (state & 0x8000) { - uint32_t no_of_entries = ctx->output_table[state & 0x7FFF].no_of_entries; - uint32_t *pids = ctx->output_table[state & 0x7FFF].pids; - uint32_t k; - for (k = 0; k < no_of_entries; k++) { - if (pids[k] & 0xFFFF0000) { - uint32_t lower_pid = pids[k] & 0x0000FFFF; - if (SCMemcmp(pid_pat_list[lower_pid].cs, - buf + i - pid_pat_list[lower_pid].patlen + 1, - pid_pat_list[lower_pid].patlen) != 0) { - /* inside loop */ - continue; - } - if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { - ; - } else { - bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - pmq->pattern_id_bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - MpmAddPid(pmq, lower_pid); - MpmAddSids(pmq, pid_pat_list[lower_pid].sids, pid_pat_list[lower_pid].sids_size); - } - matches++; - } else { - if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { - ; - } else { - bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - - MpmAddPid(pmq, pids[k]); - MpmAddSids(pmq, pid_pat_list[pids[k]].sids, pid_pat_list[pids[k]].sids_size); - } - matches++; - } - //loop1: - //; - } - } - } /* for (i = 0; i < buflen; i++) */ - - } else { - register SC_AC_BS_STATE_TYPE_U32 state = 0; - uint32_t no_of_entries; - uint32_t *ascii_codes; - uint32_t **state_table_mod_pointers = (uint32_t **)ctx->state_table_mod_pointers; - uint32_t *zero_state = state_table_mod_pointers[0] + 1; - - for (i = 0; i < buflen; i++) { - if (state == 0) { - state = zero_state[u8_tolower(buf[i])]; - } else { - no_of_entries = *(state_table_mod_pointers[state & 0x00FFFFFF]); - if (no_of_entries == 1) { - ascii_codes = state_table_mod_pointers[state & 0x00FFFFFF] + 1; - buf_local = u8_tolower(buf[i]); - if (buf_local == ascii_codes[0]) { - state = *(ascii_codes + no_of_entries);; - } else { - state = zero_state[buf_local];; - } - } else { - if (no_of_entries == 0) { - state = zero_state[u8_tolower(buf[i])]; - goto match_u32; - } - buf_local = u8_tolower(buf[i]); - ascii_codes = state_table_mod_pointers[state & 0x00FFFFFF] + 1; - int low = 0; - int high = no_of_entries; - int mid; - state = 0; - while (low <= high) { - mid = (low + high) / 2; - if (ascii_codes[mid] == buf_local) { - state = ((ascii_codes + no_of_entries))[mid]; - goto match_u32; - } else if (ascii_codes[mid] < buf_local) { - low = mid + 1; - } else { - high = mid - 1; - } - } /* while */ - state = zero_state[buf_local]; - } /* else - if (no_of_entires == 1) */ - } - - match_u32: - if (state & 0xFF000000) { - uint32_t no_of_entries = ctx->output_table[state & 0x00FFFFFF].no_of_entries; - uint32_t *pids = ctx->output_table[state & 0x00FFFFFF].pids; - uint32_t k; - for (k = 0; k < no_of_entries; k++) { - if (pids[k] & 0xFFFF0000) { - uint32_t lower_pid = pids[k] & 0x0000FFFF; - if (SCMemcmp(pid_pat_list[lower_pid].cs, - buf + i - pid_pat_list[lower_pid].patlen + 1, - pid_pat_list[lower_pid].patlen) != 0) { - /* inside loop */ - continue; - } - if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { - ; - } else { - bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - pmq->pattern_id_bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - - MpmAddPid(pmq, lower_pid); - MpmAddSids(pmq, pid_pat_list[lower_pid].sids, pid_pat_list[lower_pid].sids_size); - } - matches++; - } else { - if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { - ; - } else { - bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - - MpmAddPid(pmq, pids[k]); - MpmAddSids(pmq, pid_pat_list[pids[k]].sids, pid_pat_list[pids[k]].sids_size); - } - matches++; - } - //loop1: - //; - } - } - } /* for (i = 0; i < buflen; i++) */ - } - - return matches; -} - -/** - * \brief Add a case insensitive pattern. Although we have different calls for - * adding case sensitive and insensitive patterns, we make a single call - * for either case. No special treatment for either case. - * - * \param mpm_ctx Pointer to the mpm context. - * \param pat The pattern to add. - * \param patnen The pattern length. - * \param offset Ignored. - * \param depth Ignored. - * \param pid The pattern id. - * \param sid Ignored. - * \param flags Flags associated with this pattern. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCACBSAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - flags |= MPM_PATTERN_FLAG_NOCASE; - return SCACBSAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -/** - * \brief Add a case sensitive pattern. Although we have different calls for - * adding case sensitive and insensitive patterns, we make a single call - * for either case. No special treatment for either case. - * - * \param mpm_ctx Pointer to the mpm context. - * \param pat The pattern to add. - * \param patnen The pattern length. - * \param offset Ignored. - * \param depth Ignored. - * \param pid The pattern id. - * \param sid Ignored. - * \param flags Flags associated with this pattern. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCACBSAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - return SCACBSAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -void SCACBSPrintSearchStats(MpmThreadCtx *mpm_thread_ctx) -{ - -#ifdef SC_AC_BS_COUNTERS - SCACBSThreadCtx *ctx = (SCACBSThreadCtx *)mpm_thread_ctx->ctx; - printf("AC Thread Search stats (ctx %p)\n", ctx); - printf("Total calls: %" PRIu32 "\n", ctx->total_calls); - printf("Total matches: %" PRIu64 "\n", ctx->total_matches); -#endif /* SC_AC_BS_COUNTERS */ - - return; -} - -void SCACBSPrintInfo(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - - printf("MPM AC Information:\n"); - printf("Memory allocs: %" PRIu32 "\n", mpm_ctx->memory_cnt); - printf("Memory alloced: %" PRIu32 "\n", mpm_ctx->memory_size); - printf(" Sizeof:\n"); - printf(" MpmCtx %" PRIuMAX "\n", (uintmax_t)sizeof(MpmCtx)); - printf(" SCACBSCtx: %" PRIuMAX "\n", (uintmax_t)sizeof(SCACBSCtx)); - printf(" SCACBSPattern %" PRIuMAX "\n", (uintmax_t)sizeof(SCACBSPattern)); - printf(" SCACBSPattern %" PRIuMAX "\n", (uintmax_t)sizeof(SCACBSPattern)); - printf("Unique Patterns: %" PRIu32 "\n", mpm_ctx->pattern_cnt); - printf("Smallest: %" PRIu32 "\n", mpm_ctx->minlen); - printf("Largest: %" PRIu32 "\n", mpm_ctx->maxlen); - printf("Total states in the state table: %" PRIu32 "\n", ctx->state_count); - printf("\n"); - - return; -} - -/*************************************Unittests********************************/ - -#ifdef UNITTESTS - -static int SCACBSTest01(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest02(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abce", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest03(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghj", 4, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest04(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdegh", 6, 0, 0, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest05(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest06(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcd"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest07(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); - /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); - /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); - /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); - /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - 30, 0, 0, 5, 0, 0); - PmqSetup(&pmq, 6); - /* total matches: 135 */ - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest08(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"a", 1); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest09(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ab", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"ab", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest10(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789" - "abcdefgh" - "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest11(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"he", 2, 0, 0, 1, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"she", 3, 0, 0, 2, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"his", 3, 0, 0, 3, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"hers", 4, 0, 0, 4, 0, 0) == -1) - goto end; - PmqSetup(&pmq, 5); - - if (SCACBSPreparePatterns(&mpm_ctx) == -1) - goto end; - - result = 1; - - char *buf = "he"; - result &= (SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "she"; - result &= (SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - buf = "his"; - result &= (SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "hers"; - result &= (SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - - end: - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest12(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"wxyz", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"vwxyz", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest13(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCD"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCD"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest14(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCDE"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCDE"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest15(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCDEF"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCDEF"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest16(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABC"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABC"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest17(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzAB"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzAB"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest18(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcde""fghij""klmno""pqrst""uvwxy""z"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcde""fghij""klmno""pqrst""uvwxy""z"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest19(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - char *pat = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest20(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - char *pat = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest21(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"AA", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest22(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest23(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 0) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest24(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest25(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghiJkl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest26(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "works"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest27(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ONE", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "tone"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest28(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"one", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "tONE"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest29(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - SCACBSInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdef", 5, 0, 0, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"cdefg", 5, 0, 0, 3, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"defgh", 5, 0, 0, 4, 0, 0); - PmqSetup(&pmq, 4); - - SCACBSPreparePatterns(&mpm_ctx); - - char *buf = "abcdefgh"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 4) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - SCACBSDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest30(void) -{ - uint8_t *buf = (uint8_t *)"onetwothreefourfivesixseveneightnine"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->mpm_matcher = MPM_AC_BS; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; fast_pattern:3,3; sid:2;)"); - if (de_ctx->sig_list->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) != 1) { - printf("if (PacketAlertCheck(p, 1) != 1) failure\n"); - goto end; - } - if (PacketAlertCheck(p, 2) != 1) { - printf("if (PacketAlertCheck(p, 1) != 2) failure\n"); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void SCACBSRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("SCACBSTest01", SCACBSTest01, 1); - UtRegisterTest("SCACBSTest02", SCACBSTest02, 1); - UtRegisterTest("SCACBSTest03", SCACBSTest03, 1); - UtRegisterTest("SCACBSTest04", SCACBSTest04, 1); - UtRegisterTest("SCACBSTest05", SCACBSTest05, 1); - UtRegisterTest("SCACBSTest06", SCACBSTest06, 1); - UtRegisterTest("SCACBSTest07", SCACBSTest07, 1); - UtRegisterTest("SCACBSTest08", SCACBSTest08, 1); - UtRegisterTest("SCACBSTest09", SCACBSTest09, 1); - UtRegisterTest("SCACBSTest10", SCACBSTest10, 1); - UtRegisterTest("SCACBSTest11", SCACBSTest11, 1); - UtRegisterTest("SCACBSTest12", SCACBSTest12, 1); - UtRegisterTest("SCACBSTest13", SCACBSTest13, 1); - UtRegisterTest("SCACBSTest14", SCACBSTest14, 1); - UtRegisterTest("SCACBSTest15", SCACBSTest15, 1); - UtRegisterTest("SCACBSTest16", SCACBSTest16, 1); - UtRegisterTest("SCACBSTest17", SCACBSTest17, 1); - UtRegisterTest("SCACBSTest18", SCACBSTest18, 1); - UtRegisterTest("SCACBSTest19", SCACBSTest19, 1); - UtRegisterTest("SCACBSTest20", SCACBSTest20, 1); - UtRegisterTest("SCACBSTest21", SCACBSTest21, 1); - UtRegisterTest("SCACBSTest22", SCACBSTest22, 1); - UtRegisterTest("SCACBSTest23", SCACBSTest23, 1); - UtRegisterTest("SCACBSTest24", SCACBSTest24, 1); - UtRegisterTest("SCACBSTest25", SCACBSTest25, 1); - UtRegisterTest("SCACBSTest26", SCACBSTest26, 1); - UtRegisterTest("SCACBSTest27", SCACBSTest27, 1); - UtRegisterTest("SCACBSTest28", SCACBSTest28, 1); - UtRegisterTest("SCACBSTest29", SCACBSTest29, 1); - UtRegisterTest("SCACBSTest30", SCACBSTest30, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/util-mpm-ac-bs.h b/framework/src/suricata/src/util-mpm-ac-bs.h deleted file mode 100644 index a66757e7..00000000 --- a/framework/src/suricata/src/util-mpm-ac-bs.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - */ - -#define SC_AC_BS_STATE_TYPE_U16 uint16_t -#define SC_AC_BS_STATE_TYPE_U32 uint32_t - -typedef struct SCACBSPattern_ { - /* length of the pattern */ - uint16_t len; - /* flags decribing the pattern */ - uint8_t flags; - /* holds the original pattern that was added */ - uint8_t *original_pat; - /* case sensitive */ - uint8_t *cs; - /* case INsensitive */ - uint8_t *ci; - /* pattern id */ - uint32_t id; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; - - struct SCACBSPattern_ *next; -} SCACBSPattern; - -typedef struct SCACBSPatternList_ { - uint8_t *cs; - uint16_t patlen; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; -} SCACBSPatternList; - -typedef struct SCACBSOutputTable_ { - /* list of pattern sids */ - uint32_t *pids; - /* no of entries we have in pids */ - uint32_t no_of_entries; -} SCACBSOutputTable; - -typedef struct SCACBSCtx_ { - /* hash used during ctx initialization */ - SCACBSPattern **init_hash; - - /* pattern arrays. We need this only during the goto table creation phase */ - SCACBSPattern **parray; - - /* no of states used by ac */ - uint32_t state_count; - /* the all important memory hungry state_table */ - SC_AC_BS_STATE_TYPE_U16 (*state_table_u16)[256]; - /* the all important memory hungry state_table */ - SC_AC_BS_STATE_TYPE_U32 (*state_table_u32)[256]; - /* the modified goto_table */ - uint8_t *state_table_mod; - uint8_t **state_table_mod_pointers; - - /* goto_table, failure table and output table. Needed to create state_table. - * Will be freed, once we have created the state_table */ - int32_t (*goto_table)[256]; - int32_t *failure_table; - SCACBSOutputTable *output_table; - SCACBSPatternList *pid_pat_list; - - /* the size of each state */ - uint16_t single_state_size; - uint16_t max_pat_id; -} SCACBSCtx; - -typedef struct SCACBSThreadCtx_ { - /* the total calls we make to the search function */ - uint32_t total_calls; - /* the total patterns that we ended up matching against */ - uint64_t total_matches; -} SCACBSThreadCtx; - -void MpmACBSRegister(void); diff --git a/framework/src/suricata/src/util-mpm-ac-cuda-kernel.cu b/framework/src/suricata/src/util-mpm-ac-cuda-kernel.cu deleted file mode 100644 index d7cc125b..00000000 --- a/framework/src/suricata/src/util-mpm-ac-cuda-kernel.cu +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * The Cuda kernel for MPM AC. - * - * \todo - This is a basic version of the kernel. - * - Support 16 bit state tables. - * - Texture memory. - * - Multiple threads per blocks of threads. Make use of - * shared memory/texture memory. - */ - -extern "C" -__global__ void SCACCudaSearch64(unsigned char *d_buffer, - unsigned int d_buffer_start_offset, - unsigned int *o_buffer, - unsigned int *results_buffer, - unsigned int nop, - unsigned char *tolower) -{ - unsigned int u = 0; - unsigned int tid = blockIdx.x * blockDim.x + threadIdx.x; - if (tid >= nop) - return; - - unsigned int buflen = *((unsigned long *)(d_buffer + (o_buffer[tid] - d_buffer_start_offset))); - unsigned int (*state_table_u32)[256] = - (unsigned int (*)[256])*((unsigned long *)(d_buffer + (o_buffer[tid] - d_buffer_start_offset) + 8)); - unsigned char *buf = (d_buffer + (o_buffer[tid] - d_buffer_start_offset) + 16); - - unsigned int state = 0; - unsigned int matches = 0; - unsigned int *results = (results_buffer + ((o_buffer[tid] - d_buffer_start_offset) * 2) + 1); - for (u = 0; u < buflen; u++) { - state = state_table_u32[state & 0x00FFFFFF][tolower[buf[u]]]; - if (state & 0xFF000000) { - results[matches++] = u; - results[matches++] = state & 0x00FFFFFF; - } - } - - *(results - 1) = matches; - return; -} - -extern "C" -__global__ void SCACCudaSearch32(unsigned char *d_buffer, - unsigned int d_buffer_start_offset, - unsigned int *o_buffer, - unsigned int *results_buffer, - unsigned int nop, - unsigned char *tolower) -{ - unsigned int u = 0; - unsigned int tid = blockIdx.x * blockDim.x + threadIdx.x; - if (tid >= nop) - return; - - unsigned int buflen = *((unsigned int *)(d_buffer + (o_buffer[tid] - d_buffer_start_offset))); - unsigned int (*state_table_u32)[256] = - (unsigned int (*)[256])*((unsigned int *)(d_buffer + (o_buffer[tid] - d_buffer_start_offset) + 4)); - unsigned char *buf = (d_buffer + (o_buffer[tid] - d_buffer_start_offset) + 8); - - unsigned int state = 0; - unsigned int matches = 0; - unsigned int *results = (results_buffer + ((o_buffer[tid] - d_buffer_start_offset) * 2) + 1); - for (u = 0; u < buflen; u++) { - state = state_table_u32[state & 0x00FFFFFF][tolower[buf[u]]]; - if (state & 0xFF000000) { - results[matches++] = u; - results[matches++] = state & 0x00FFFFFF; - } - } - - *(results - 1) = matches; - return; -} diff --git a/framework/src/suricata/src/util-mpm-ac-gfbs.c b/framework/src/suricata/src/util-mpm-ac-gfbs.c deleted file mode 100644 index e0ace7f3..00000000 --- a/framework/src/suricata/src/util-mpm-ac-gfbs.c +++ /dev/null @@ -1,2722 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implementation of aho-corasick MPM from - - * - * Efficient String Matching: An Aid to Bibliographic Search - * Alfred V. Aho and Margaret J. Corasick - * - * - We use the goto-failure table to calculate transitions. - * - If we cross 2 ** 16 states, we use 4 bytes in the transition table - * to hold each state, otherwise we use 2 bytes. - * - To reduce memory consumption, we throw all the failure transitions - * out and use binary search to pick out the right transition in - * the modified goto table. - * - * \todo - Do a proper analyis of our existing MPMs and suggest a good one based - * on the pattern distribution and the expected traffic(say http). - * - Tried out loop unrolling without any perf increase. Need to dig deeper. - * - Try out holding whether they are any output strings from a particular - * state in one of the bytes of a state var. Will be useful in cuda esp. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "util-mpm-ac-gfbs.h" - -#include "conf.h" -#include "util-memcmp.h" -#include "util-memcpy.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -void SCACGfbsInitCtx(MpmCtx *); -void SCACGfbsInitThreadCtx(MpmCtx *, MpmThreadCtx *, uint32_t); -void SCACGfbsDestroyCtx(MpmCtx *); -void SCACGfbsDestroyThreadCtx(MpmCtx *, MpmThreadCtx *); -int SCACGfbsAddPatternCI(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACGfbsAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACGfbsPreparePatterns(MpmCtx *mpm_ctx); -uint32_t SCACGfbsSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen); -void SCACGfbsPrintInfo(MpmCtx *mpm_ctx); -void SCACGfbsPrintSearchStats(MpmThreadCtx *mpm_thread_ctx); -void SCACGfbsRegisterTests(void); - -/* a placeholder to denote a failure transition in the goto table */ -#define SC_AC_GFBS_FAIL (-1) -/* size of the hash table used to speed up pattern insertions initially */ -#define INIT_HASH_SIZE 65536 - -#define STATE_QUEUE_CONTAINER_SIZE 65536 - -/** - * \brief Helper structure used by AC during state table creation - */ -typedef struct StateQueue_ { - int32_t store[STATE_QUEUE_CONTAINER_SIZE]; - int top; - int bot; -} StateQueue; - -/** - * \brief Register the goto failure table based aho-corasick mpm. - */ -void MpmACGfbsRegister(void) -{ - mpm_table[MPM_AC_GFBS].name = "ac-gfbs"; - /* don't need this. isn't that awesome? no more chopping and blah blah */ - mpm_table[MPM_AC_GFBS].max_pattern_length = 0; - - mpm_table[MPM_AC_GFBS].InitCtx = SCACGfbsInitCtx; - mpm_table[MPM_AC_GFBS].InitThreadCtx = SCACGfbsInitThreadCtx; - mpm_table[MPM_AC_GFBS].DestroyCtx = SCACGfbsDestroyCtx; - mpm_table[MPM_AC_GFBS].DestroyThreadCtx = SCACGfbsDestroyThreadCtx; - mpm_table[MPM_AC_GFBS].AddPattern = SCACGfbsAddPatternCS; - mpm_table[MPM_AC_GFBS].AddPatternNocase = SCACGfbsAddPatternCI; - mpm_table[MPM_AC_GFBS].Prepare = SCACGfbsPreparePatterns; - mpm_table[MPM_AC_GFBS].Search = SCACGfbsSearch; - mpm_table[MPM_AC_GFBS].Cleanup = NULL; - mpm_table[MPM_AC_GFBS].PrintCtx = SCACGfbsPrintInfo; - mpm_table[MPM_AC_GFBS].PrintThreadCtx = SCACGfbsPrintSearchStats; - mpm_table[MPM_AC_GFBS].RegisterUnittests = SCACGfbsRegisterTests; - - return; -} - -/** - * \internal - * \brief Initialize the AC context with user specified conf parameters. We - * aren't retrieving anything for AC conf now, but we will certainly - * need it, when we customize AC. - */ -static void SCACGfbsGetConfig() -{ - //ConfNode *ac_conf; - //const char *hash_val = NULL; - - //ConfNode *pm = ConfGetNode("pattern-matcher"); - - return; -} - -/** - * \internal - * \brief Creates a hash of the pattern. We use it for the hashing process - * during the initial pattern insertion time, to cull duplicate sigs. - * - * \param pat Pointer to the pattern. - * \param patlen Pattern length. - * - * \retval hash A 32 bit unsigned hash. - */ -static inline uint32_t SCACGfbsInitHashRaw(uint8_t *pat, uint16_t patlen) -{ - uint32_t hash = patlen * pat[0]; - if (patlen > 1) - hash += pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -/** - * \internal - * \brief Looks up a pattern. We use it for the hashing process during the - * the initial pattern insertion time, to cull duplicate sigs. - * - * \param ctx Pointer to the AC ctx. - * \param pat Pointer to the pattern. - * \param patlen Pattern length. - * \param flags Flags. We don't need this. - * - * \retval hash A 32 bit unsigned hash. - */ -static inline SCACGfbsPattern *SCACGfbsInitHashLookup(SCACGfbsCtx *ctx, uint8_t *pat, - uint16_t patlen, char flags, - uint32_t pid) -{ - uint32_t hash = SCACGfbsInitHashRaw(pat, patlen); - - if (ctx->init_hash == NULL) - return NULL; - - SCACGfbsPattern *t = ctx->init_hash[hash]; - for ( ; t != NULL; t = t->next) { - if (t->id == pid) - return t; - } - - return NULL; -} - -/** - * \internal - * \brief Allocs a new pattern instance. - * - * \param mpm_ctx Pointer to the mpm context. - * - * \retval p Pointer to the newly created pattern. - */ -static inline SCACGfbsPattern *SCACGfbsAllocPattern(MpmCtx *mpm_ctx) -{ - SCACGfbsPattern *p = SCMalloc(sizeof(SCACGfbsPattern)); - if (unlikely(p == NULL)) { - exit(EXIT_FAILURE); - } - memset(p, 0, sizeof(SCACGfbsPattern)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACGfbsPattern); - - return p; -} - -/** - * \internal - * \brief Used to free SCACGfbsPattern instances. - * - * \param mpm_ctx Pointer to the mpm context. - * \param p Pointer to the SCACGfbsPattern instance to be freed. - */ -static inline void SCACGfbsFreePattern(MpmCtx *mpm_ctx, SCACGfbsPattern *p) -{ - if (p != NULL && p->cs != NULL && p->cs != p->ci) { - SCFree(p->cs); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->ci != NULL) { - SCFree(p->ci); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->original_pat != NULL) { - SCFree(p->original_pat); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL) { - SCFree(p); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACGfbsPattern); - } - return; -} - -static inline uint32_t SCACGfbsInitHash(SCACGfbsPattern *p) -{ - uint32_t hash = p->len * p->original_pat[0]; - if (p->len > 1) - hash += p->original_pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline int SCACGfbsInitHashAdd(SCACGfbsCtx *ctx, SCACGfbsPattern *p) -{ - uint32_t hash = SCACGfbsInitHash(p); - - if (ctx->init_hash == NULL) { - return 0; - } - - if (ctx->init_hash[hash] == NULL) { - ctx->init_hash[hash] = p; - return 0; - } - - SCACGfbsPattern *tt = NULL; - SCACGfbsPattern *t = ctx->init_hash[hash]; - - /* get the list tail */ - do { - tt = t; - t = t->next; - } while (t != NULL); - - tt->next = p; - - return 0; -} - -/** - * \internal - * \brief Add a pattern to the mpm-ac context. - * - * \param mpm_ctx Mpm context. - * \param pat Pointer to the pattern. - * \param patlen Length of the pattern. - * \param pid Pattern id - * \param sid Signature id (internal id). - * \param flags Pattern's MPM_PATTERN_* flags. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int SCACGfbsAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - - SCLogDebug("Adding pattern for ctx %p, patlen %"PRIu16" and pid %" PRIu32, - ctx, patlen, pid); - - if (patlen == 0) { - SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "pattern length 0"); - return 0; - } - - /* check if we have already inserted this pattern */ - SCACGfbsPattern *p = SCACGfbsInitHashLookup(ctx, pat, patlen, flags, pid); - if (p == NULL) { - SCLogDebug("Allocing new pattern"); - - /* p will never be NULL */ - p = SCACGfbsAllocPattern(mpm_ctx); - - p->len = patlen; - p->flags = flags; - p->id = pid; - - p->original_pat = SCMalloc(patlen); - if (p->original_pat == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->original_pat, pat, patlen); - - p->ci = SCMalloc(patlen); - if (p->ci == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy_tolower(p->ci, pat, patlen); - - /* setup the case sensitive part of the pattern */ - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - /* nocase means no difference between cs and ci */ - p->cs = p->ci; - } else { - if (memcmp(p->ci, pat, p->len) == 0) { - /* no diff between cs and ci: pat is lowercase */ - p->cs = p->ci; - } else { - p->cs = SCMalloc(patlen); - if (p->cs == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->cs, pat, patlen); - } - } - - /* put in the pattern hash */ - SCACGfbsInitHashAdd(ctx, p); - - if (mpm_ctx->pattern_cnt == 65535) { - SCLogError(SC_ERR_AHO_CORASICK, "Max search words reached. Can't " - "insert anymore. Exiting"); - exit(EXIT_FAILURE); - } - mpm_ctx->pattern_cnt++; - - if (mpm_ctx->maxlen < patlen) - mpm_ctx->maxlen = patlen; - - if (mpm_ctx->minlen == 0) { - mpm_ctx->minlen = patlen; - } else { - if (mpm_ctx->minlen > patlen) - mpm_ctx->minlen = patlen; - } - - /* we need the max pat id */ - if (pid > ctx->max_pat_id) - ctx->max_pat_id = pid; - - p->sids_size = 1; - p->sids = SCMalloc(p->sids_size * sizeof(SigIntId)); - BUG_ON(p->sids == NULL); - p->sids[0] = sid; - } else { - /* TODO figure out how we can be called multiple times for the same CTX with the same sid */ - - int found = 0; - uint32_t x = 0; - for (x = 0; x < p->sids_size; x++) { - if (p->sids[x] == sid) { - found = 1; - break; - } - } - if (!found) { - SigIntId *sids = SCRealloc(p->sids, (sizeof(SigIntId) * (p->sids_size + 1))); - BUG_ON(sids == NULL); - p->sids = sids; - p->sids[p->sids_size] = sid; - p->sids_size++; - } - } - - return 0; - -error: - SCACGfbsFreePattern(mpm_ctx, p); - return -1; -} - -/** - * \internal - * \brief Initialize a new state in the goto and output tables. - * - * \param mpm_ctx Pointer to the mpm context. - * - * \retval The state id, of the newly created state. - */ -static inline int SCACGfbsInitNewState(MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int size = 0; - - /* reallocate space in the goto table to include a new state */ - size = (ctx->state_count + 1) * 1024; - ptmp = SCRealloc(ctx->goto_table, size); - if (ptmp == NULL) { - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ctx->goto_table = ptmp; - - /* set all transitions for the newly assigned state as FAIL transitions */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - ctx->goto_table[ctx->state_count][ascii_code] = SC_AC_GFBS_FAIL; - } - - /* reallocate space in the output table for the new state */ - size = (ctx->state_count + 1) * sizeof(SCACGfbsOutputTable); - ptmp = SCRealloc(ctx->output_table, size); - if (ptmp == NULL) { - SCFree(ctx->output_table); - ctx->output_table = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ctx->output_table = ptmp; - - memset(ctx->output_table + ctx->state_count, 0, sizeof(SCACGfbsOutputTable)); - - /* \todo using it temporarily now during dev, since I have restricted - * state var in SCACGfbsCtx->state_table to uint16_t. */ - //if (ctx->state_count > 65536) { - // printf("state count exceeded\n"); - // exit(EXIT_FAILURE); - //} - - return ctx->state_count++; -} - -/** - * \internal - * \brief Adds a pid to the output table for a state. - * - * \param state The state to whose output table we should add the pid. - * \param pid The pattern id to add. - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACGfbsSetOutputState(int32_t state, uint32_t pid, MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - SCACGfbsOutputTable *output_state = &ctx->output_table[state]; - uint32_t i = 0; - - for (i = 0; i < output_state->no_of_entries; i++) { - if (output_state->pids[i] == pid) - return; - } - - output_state->no_of_entries++; - ptmp = SCRealloc(output_state->pids, - output_state->no_of_entries * sizeof(uint32_t)); - if (ptmp == NULL) { - SCFree(output_state->pids); - output_state->pids = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - output_state->pids = ptmp; - - output_state->pids[output_state->no_of_entries - 1] = pid; - - return; -} - -/** - * \brief Helper function used by SCACGfbsCreateGotoTable. Adds a pattern to the - * goto table. - * - * \param pattern Pointer to the pattern. - * \param pattern_len Pattern length. - * \param pid The pattern id, that corresponds to this pattern. We - * need it to updated the output table for this pattern. - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACGfbsEnter(uint8_t *pattern, uint16_t pattern_len, uint32_t pid, - MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - int32_t state = 0; - int32_t newstate = 0; - int i = 0; - int p = 0; - - /* walk down the trie till we have a match for the pattern prefix */ - state = 0; - for (i = 0; i < pattern_len; i++) { - if (ctx->goto_table[state][pattern[i]] != SC_AC_GFBS_FAIL) { - state = ctx->goto_table[state][pattern[i]]; - } else { - break; - } - } - - /* add the non-matching pattern suffix to the trie, from the last state - * we left off */ - for (p = i; p < pattern_len; p++) { - newstate = SCACGfbsInitNewState(mpm_ctx); - ctx->goto_table[state][pattern[p]] = newstate; - state = newstate; - } - - /* add this pattern id, to the output table of the last state, where the - * pattern ends in the trie */ - SCACGfbsSetOutputState(state, pid, mpm_ctx); - - return; -} - -/** - * \internal - * \brief Create the goto table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACGfbsCreateGotoTable(MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - uint32_t i = 0; - - /* add each pattern to create the goto table */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - SCACGfbsEnter(ctx->parray[i]->ci, ctx->parray[i]->len, - ctx->parray[i]->id, mpm_ctx); - } - - int ascii_code = 0; - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - if (ctx->goto_table[0][ascii_code] == SC_AC_GFBS_FAIL) { - ctx->goto_table[0][ascii_code] = 0; - } - } - - return; -} - -static inline int SCACGfbsStateQueueIsEmpty(StateQueue *q) -{ - if (q->top == q->bot) - return 1; - else - return 0; -} - -static inline void SCACGfbsEnqueue(StateQueue *q, int32_t state) -{ - int i = 0; - - /*if we already have this */ - for (i = q->bot; i < q->top; i++) { - if (q->store[i] == state) - return; - } - - q->store[q->top++] = state; - - if (q->top == STATE_QUEUE_CONTAINER_SIZE) - q->top = 0; - - if (q->top == q->bot) { - SCLogCritical(SC_ERR_AHO_CORASICK, "Just ran out of space in the queue. " - "Fatal Error. Exiting. Please file a bug report on this"); - exit(EXIT_FAILURE); - } - - return; -} - -static inline int32_t SCACGfbsDequeue(StateQueue *q) -{ - if (q->bot == STATE_QUEUE_CONTAINER_SIZE) - q->bot = 0; - - if (q->bot == q->top) { - SCLogCritical(SC_ERR_AHO_CORASICK, "StateQueue behaving weirdly. " - "Fatal Error. Exiting. Please file a bug report on this"); - exit(EXIT_FAILURE); - } - - return q->store[q->bot++]; -} - -/* -#define SCACGfbsStateQueueIsEmpty(q) (((q)->top == (q)->bot) ? 1 : 0) - -#define SCACGfbsEnqueue(q, state) do { \ - int i = 0; \ - \ - for (i = (q)->bot; i < (q)->top; i++) { \ - if ((q)->store[i] == state) \ - return; \ - } \ - \ - (q)->store[(q)->top++] = state; \ - \ - if ((q)->top == STATE_QUEUE_CONTAINER_SIZE) \ - (q)->top = 0; \ - \ - if ((q)->top == (q)->bot) { \ - SCLogCritical(SC_ERR_AHO_CORASICK, "Just ran out of space in the queue. " \ - "Fatal Error. Exiting. Please file a bug report on this"); \ - exit(EXIT_FAILURE); \ - } \ - } while (0) - -#define SCACGfbsDequeue(q) ( (((q)->bot == STATE_QUEUE_CONTAINER_SIZE)? ((q)->bot = 0): 0), \ - (((q)->bot == (q)->top) ? \ - (printf("StateQueue behaving " \ - "weirdly. Fatal Error. Exiting. Please " \ - "file a bug report on this"), \ - exit(EXIT_FAILURE)) : 0), \ - (q)->store[(q)->bot++]) \ -*/ - -/** - * \internal - * \brief Club the output data from 2 states and store it in the 1st state. - * dst_state_data = {dst_state_data} UNION {src_state_data} - * - * \todo Use a better way to find union of 2 sets. - * - * \param dst_state First state(also the destination) for the union operation. - * \param src_state Second state for the union operation. - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACGfbsClubOutputStates(int32_t dst_state, int32_t src_state, - MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - uint32_t i = 0; - uint32_t j = 0; - - SCACGfbsOutputTable *output_dst_state = &ctx->output_table[dst_state]; - SCACGfbsOutputTable *output_src_state = &ctx->output_table[src_state]; - - for (i = 0; i < output_src_state->no_of_entries; i++) { - for (j = 0; j < output_dst_state->no_of_entries; j++) { - if (output_src_state->pids[i] == output_dst_state->pids[j]) { - break; - } - } - if (j == output_dst_state->no_of_entries) { - output_dst_state->no_of_entries++; - - ptmp = SCRealloc(output_dst_state->pids, - (output_dst_state->no_of_entries * sizeof(uint32_t))); - if (ptmp == NULL) { - SCFree(output_dst_state->pids); - output_dst_state->pids = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - output_dst_state->pids = ptmp; - - output_dst_state->pids[output_dst_state->no_of_entries - 1] = - output_src_state->pids[i]; - } - } - - return; -} - -/** - * \internal - * \brief Create the failure table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACGfbsCreateFailureTable(MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int32_t state = 0; - int32_t r_state = 0; - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - /* allot space for the failure table. A failure entry in the table for - * every state(SCACGfbsCtx->state_count) */ - ctx->failure_table = SCMalloc(ctx->state_count * sizeof(int32_t)); - if (ctx->failure_table == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->failure_table, 0, ctx->state_count * sizeof(int32_t)); - - /* add the failure transitions for the 0th state, and add every non-fail - * transition from the 0th state to the queue for further processing - * of failure states */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[0][ascii_code]; - if (temp_state != 0) { - SCACGfbsEnqueue(&q, temp_state); - ctx->failure_table[temp_state] = 0; - } - } - - while (!SCACGfbsStateQueueIsEmpty(&q)) { - /* pick up every state from the queue and add failure transitions */ - r_state = SCACGfbsDequeue(&q); - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state == SC_AC_GFBS_FAIL) - continue; - SCACGfbsEnqueue(&q, temp_state); - state = ctx->failure_table[r_state]; - - while(ctx->goto_table[state][ascii_code] == SC_AC_GFBS_FAIL) - state = ctx->failure_table[state]; - ctx->failure_table[temp_state] = ctx->goto_table[state][ascii_code]; - SCACGfbsClubOutputStates(temp_state, ctx->failure_table[temp_state], - mpm_ctx); - } - } - - return; -} - -/** - * \internal - * \brief Creates a new goto table structure(throw out all the failure - * transitions), to hold the existing goto table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACGfbsCreateModGotoTable(MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - - if (ctx->state_count < 32767) { - int size = 0; - int32_t state = 0; - for (state = 1; state < ctx->state_count; state++) { - int k = 0; - int ascii_code = 0; - for (; ascii_code < 256; ascii_code++) { - if (ctx->goto_table[state][ascii_code] == SC_AC_GFBS_FAIL) - continue; - k++; - } - - if ((k % 2) != 0) - size += 1; - } - - /* Let us use uint16_t for all. That way we don't have to worry about - * alignment. Technically 8 bits is all we need to store ascii codes, - * but by avoiding it, we save a lot of time on handling alignment */ - size += (ctx->state_count * sizeof(SC_AC_GFBS_STATE_TYPE_U16) * 3 + - ctx->state_count * sizeof(uint8_t) + - 256 * sizeof(SC_AC_GFBS_STATE_TYPE_U16) * 1); - ctx->goto_table_mod = SCMalloc(size); - if (ctx->goto_table_mod == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->goto_table_mod, 0, size); - //printf("size- %d\n", size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += size; - - /* buffer to hold pointers in the buffer, so that a state can use it - * directly to access its state data */ - ctx->goto_table_mod_pointers = SCMalloc(ctx->state_count * sizeof(uint8_t *)); - if (ctx->goto_table_mod_pointers == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->goto_table_mod_pointers, 0, - ctx->state_count * sizeof(uint8_t *)); - - SC_AC_GFBS_STATE_TYPE_U16 temp_states[256]; - uint16_t *curr_loc = (uint16_t *)ctx->goto_table_mod; - uint16_t *no_of_entries = NULL; - uint16_t *failure_entry = NULL; - uint8_t *ascii_codes = NULL; - uint16_t ascii_code = 0; - uint16_t k = 0; - for (state = 0; state < ctx->state_count; state++) { - /* store the starting location in the buffer for this state */ - ctx->goto_table_mod_pointers[state] = (uint8_t *)curr_loc; - no_of_entries = curr_loc++; - failure_entry = curr_loc++; - ascii_codes = (uint8_t *)curr_loc; - k = 0; - /* store all states that have non fail transitions in the temp buffer */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - if (ctx->goto_table[state][ascii_code] == SC_AC_GFBS_FAIL) - continue; - ascii_codes[k] = ascii_code; - temp_states[k] = ctx->goto_table[state][ascii_code]; - k++; - } - /* if we have any non fail transitions from our previous for search, - * store the acii codes as well the corresponding states */ - if (k > 0) { - no_of_entries[0] = k; - if (state != 0) { - int jump = (k + 1) & 0xFFE; - curr_loc += jump / 2; - } - memcpy(curr_loc, temp_states, k * sizeof(SC_AC_GFBS_STATE_TYPE_U16)); - curr_loc += k; - } - failure_entry[0] = ctx->failure_table[state]; - } - - /* > 33766 */ - } else { - int size = 0; - int32_t state = 0; - for (state = 1; state < ctx->state_count; state++) { - int k = 0; - int ascii_code = 0; - for (; ascii_code < 256; ascii_code++) { - if (ctx->goto_table[state][ascii_code] == SC_AC_GFBS_FAIL) - continue; - k++; - } - - if ( (k % 4) != 0) - size += (4 - (k % 4)); - } - - /* Let us use uint32_t for all. That way we don't have to worry about - * alignment. Technically 8 bits is all we need to store ascii codes, - * but by avoiding it, we save a lot of time on handling alignment */ - size += (ctx->state_count * (sizeof(SC_AC_GFBS_STATE_TYPE_U32) * 3)+ - ctx->state_count * sizeof(uint8_t) + - 256 * (sizeof(SC_AC_GFBS_STATE_TYPE_U32) * 1)); - ctx->goto_table_mod = SCMalloc(size); - if (ctx->goto_table_mod == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->goto_table_mod, 0, size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += size; - - /* buffer to hold pointers in the buffer, so that a state can use it - * directly to access its state data */ - ctx->goto_table_mod_pointers = SCMalloc(ctx->state_count * sizeof(uint8_t *)); - if (ctx->goto_table_mod_pointers == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->goto_table_mod_pointers, 0, - ctx->state_count * sizeof(uint8_t *)); - - SC_AC_GFBS_STATE_TYPE_U32 temp_states[256]; - uint32_t *curr_loc = (uint32_t *)ctx->goto_table_mod; - uint32_t *no_of_entries = NULL; - uint32_t *failure_entry = NULL; - uint8_t *ascii_codes = NULL; - uint16_t ascii_code = 0; - uint16_t k = 0; - for (state = 0; state < ctx->state_count; state++) { - /* store the starting location in the buffer for this state */ - ctx->goto_table_mod_pointers[state] = (uint8_t *)curr_loc; - no_of_entries = curr_loc++; - failure_entry = curr_loc++; - ascii_codes = (uint8_t *)curr_loc; - k = 0; - /* store all states that have non fail transitions in the temp buffer */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - if (ctx->goto_table[state][ascii_code] == SC_AC_GFBS_FAIL) - continue; - ascii_codes[k] = ascii_code; - temp_states[k] = ctx->goto_table[state][ascii_code]; - k++; - } - /* if we have any non fail transitions from our previous for search, - * store the acii codes as well the corresponding states */ - if (k > 0) { - no_of_entries[0] = k; - if (state != 0) { - int jump = (k + 3) & 0xFFC; - curr_loc += jump / 4; - } - memcpy(curr_loc, temp_states, k * sizeof(SC_AC_GFBS_STATE_TYPE_U32)); - curr_loc += k; - } - failure_entry[0] = ctx->failure_table[state]; - } - } - - return; -} - -static inline void SCACGfbsClubOutputStatePresenceWithModGotoTable(MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - - int state = 0; - int no_of_entries; - int i; - - if (ctx->state_count < 32767) { - uint16_t *states; - for (state = 0; state < ctx->state_count; state++) { - no_of_entries = *((uint16_t *)ctx->goto_table_mod_pointers[state]); - if (no_of_entries == 0) - continue; - - //if (*((uint16_t *)ctx->goto_table_mod_pointers[state] + 1) != 0) { - if (ctx->output_table[((uint16_t *)ctx->goto_table_mod_pointers[state] + 1)[0]].no_of_entries != 0) { - *((uint16_t *)ctx->goto_table_mod_pointers[state] + 1) |= (1 << 15); - } - - if (state == 0) - states = ((uint16_t *)ctx->goto_table_mod_pointers[state] + 2); - else - states = ((uint16_t *)ctx->goto_table_mod_pointers[state] + 2 + ((no_of_entries + 1) & 0xFFE) / 2); - for (i = 0; i < no_of_entries; i++) { - //if (states[i] == 0) - if (ctx->output_table[states[i]].no_of_entries == 0) - continue; - - states[i] |= (1 << 15); - } - } - - } else { - uint32_t *states; - for (state = 0; state < ctx->state_count; state++) { - no_of_entries = *((uint32_t *)ctx->goto_table_mod_pointers[state]); - if (no_of_entries == 0) - continue; - - //if (*((uint32_t *)ctx->goto_table_mod_pointers[state] + 1) != 0) { - if (ctx->output_table[((uint32_t *)ctx->goto_table_mod_pointers[state] + 1)[0]].no_of_entries != 0) { - *((uint32_t *)ctx->goto_table_mod_pointers[state] + 1) |= (1 << 24); - } - - if (state == 0) - states = ((uint32_t *)ctx->goto_table_mod_pointers[state] + 2); - else - states = ((uint32_t *)ctx->goto_table_mod_pointers[state] + 2 + ((no_of_entries + 3) & 0xFFC) / 4); - for (i = 0; i < no_of_entries; i++) { - //if (states[i] == 0) - if (ctx->output_table[states[i]].no_of_entries == 0) - continue; - - states[i] |= (1 << 24); - } - } - } - - return; -} - -static inline void SCACGfbsInsertCaseSensitiveEntriesForPatterns(MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - int32_t state = 0; - uint32_t k = 0; - - for (state = 0; state < ctx->state_count; state++) { - if (ctx->output_table[state].no_of_entries == 0) - continue; - - for (k = 0; k < ctx->output_table[state].no_of_entries; k++) { - if (ctx->pid_pat_list[ctx->output_table[state].pids[k]].cs != NULL) { - ctx->output_table[state].pids[k] &= 0x0000FFFF; - ctx->output_table[state].pids[k] |= 1 << 16; - } - } - } - - return; -} - -/** - * \brief Process the patterns and prepare the state table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACGfbsPrepareStateTable(MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - - /* create the 0th state in the goto table and output_table */ - SCACGfbsInitNewState(mpm_ctx); - - /* create the goto table */ - SCACGfbsCreateGotoTable(mpm_ctx); - /* create the failure table */ - SCACGfbsCreateFailureTable(mpm_ctx); - /* create the final state(delta) table */ - SCACGfbsCreateModGotoTable(mpm_ctx); - /* club the output state presence with transition entries */ - SCACGfbsClubOutputStatePresenceWithModGotoTable(mpm_ctx); - - /* club nocase entries */ - SCACGfbsInsertCaseSensitiveEntriesForPatterns(mpm_ctx); - - /* we don't need this anymore */ - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - SCFree(ctx->failure_table); - ctx->failure_table = NULL; - - return; -} - -/** - * \brief Process the patterns added to the mpm, and create the internal tables. - * - * \param mpm_ctx Pointer to the mpm context. - */ -int SCACGfbsPreparePatterns(MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - - if (mpm_ctx->pattern_cnt == 0 || ctx->init_hash == NULL) { - SCLogDebug("No patterns supplied to this mpm_ctx"); - return 0; - } - - /* alloc the pattern array */ - ctx->parray = (SCACGfbsPattern **)SCMalloc(mpm_ctx->pattern_cnt * - sizeof(SCACGfbsPattern *)); - if (ctx->parray == NULL) - goto error; - memset(ctx->parray, 0, mpm_ctx->pattern_cnt * sizeof(SCACGfbsPattern *)); - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (mpm_ctx->pattern_cnt * sizeof(SCACGfbsPattern *)); - - /* populate it with the patterns in the hash */ - uint32_t i = 0, p = 0; - for (i = 0; i < INIT_HASH_SIZE; i++) { - SCACGfbsPattern *node = ctx->init_hash[i], *nnode = NULL; - while(node != NULL) { - nnode = node->next; - node->next = NULL; - ctx->parray[p++] = node; - node = nnode; - } - } - - /* we no longer need the hash, so free it's memory */ - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - - /* the memory consumed by a single state in our goto table */ - //ctx->single_state_size = sizeof(int32_t) * 256; - - /* handle no case patterns */ - ctx->pid_pat_list = SCMalloc((ctx->max_pat_id + 1)* sizeof(SCACGfbsPatternList)); - if (ctx->pid_pat_list == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->pid_pat_list, 0, (ctx->max_pat_id + 1) * sizeof(SCACGfbsPatternList)); - - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (!(ctx->parray[i]->flags & MPM_PATTERN_FLAG_NOCASE)) { - ctx->pid_pat_list[ctx->parray[i]->id].cs = SCMalloc(ctx->parray[i]->len); - if (ctx->pid_pat_list[ctx->parray[i]->id].cs == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memcpy(ctx->pid_pat_list[ctx->parray[i]->id].cs, - ctx->parray[i]->original_pat, ctx->parray[i]->len); - ctx->pid_pat_list[ctx->parray[i]->id].patlen = ctx->parray[i]->len; - } - - /* ACPatternList now owns this memory */ - ctx->pid_pat_list[ctx->parray[i]->id].sids_size = ctx->parray[i]->sids_size; - ctx->pid_pat_list[ctx->parray[i]->id].sids = ctx->parray[i]->sids; - } - - /* prepare the state table required by AC */ - SCACGfbsPrepareStateTable(mpm_ctx); - - /* free all the stored patterns. Should save us a good 100-200 mbs */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - SCACGfbsFreePattern(mpm_ctx, ctx->parray[i]); - } - } - SCFree(ctx->parray); - ctx->parray = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(SCACGfbsPattern *)); - - return 0; - -error: - return -1; -} - -/** - * \brief Init the mpm thread context. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - * \param matchsize We don't need this. - */ -void SCACGfbsInitThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - uint32_t matchsize) -{ - memset(mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - - mpm_thread_ctx->ctx = SCMalloc(sizeof(SCACGfbsThreadCtx)); - if (mpm_thread_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - memset(mpm_thread_ctx->ctx, 0, sizeof(SCACGfbsThreadCtx)); - mpm_thread_ctx->memory_cnt++; - mpm_thread_ctx->memory_size += sizeof(SCACGfbsThreadCtx); - - return; -} - -/** - * \brief Initialize the AC context. - * - * \param mpm_ctx Mpm context. - * \param module_handle Cuda module handle from the cuda handler API. We don't - * have to worry about this here. - */ -void SCACGfbsInitCtx(MpmCtx *mpm_ctx) -{ - if (mpm_ctx->ctx != NULL) - return; - - mpm_ctx->ctx = SCMalloc(sizeof(SCACGfbsCtx)); - if (mpm_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - memset(mpm_ctx->ctx, 0, sizeof(SCACGfbsCtx)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACGfbsCtx); - - /* initialize the hash we use to speed up pattern insertions */ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - ctx->init_hash = SCMalloc(sizeof(SCACGfbsPattern *) * INIT_HASH_SIZE); - if (ctx->init_hash == NULL) { - exit(EXIT_FAILURE); - } - memset(ctx->init_hash, 0, sizeof(SCACGfbsPattern *) * INIT_HASH_SIZE); - - /* get conf values for AC from our yaml file. We have no conf values for - * now. We will certainly need this, as we develop the algo */ - SCACGfbsGetConfig(); - - SCReturn; -} - -/** - * \brief Destroy the mpm thread context. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - */ -void SCACGfbsDestroyThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx) -{ - SCACGfbsPrintSearchStats(mpm_thread_ctx); - - if (mpm_thread_ctx->ctx != NULL) { - SCFree(mpm_thread_ctx->ctx); - mpm_thread_ctx->ctx = NULL; - mpm_thread_ctx->memory_cnt--; - mpm_thread_ctx->memory_size -= sizeof(SCACGfbsThreadCtx); - } - - return; -} - -/** - * \brief Destroy the mpm context. - * - * \param mpm_ctx Pointer to the mpm context. - */ -void SCACGfbsDestroyCtx(MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - if (ctx == NULL) - return; - - if (ctx->init_hash != NULL) { - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (INIT_HASH_SIZE * sizeof(SCACGfbsPattern *)); - } - - if (ctx->parray != NULL) { - uint32_t i; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - SCACGfbsFreePattern(mpm_ctx, ctx->parray[i]); - } - } - - SCFree(ctx->parray); - ctx->parray = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(SCACGfbsPattern *)); - } - - if (ctx->goto_table_mod != NULL) { - SCFree(ctx->goto_table_mod); - ctx->goto_table_mod = NULL; - - mpm_ctx->memory_cnt--; - if (ctx->state_count < 32767) { - mpm_ctx->memory_size -= (ctx->state_count * sizeof(SC_AC_GFBS_STATE_TYPE_U16) * 3 + - 256 * sizeof(SC_AC_GFBS_STATE_TYPE_U16) * 2); - } else { - mpm_ctx->memory_size -= (ctx->state_count * sizeof(SC_AC_GFBS_STATE_TYPE_U32) * 3 + - 256 * sizeof(SC_AC_GFBS_STATE_TYPE_U32) * 2); - } - } - - if (ctx->goto_table_mod_pointers != NULL) { - SCFree(ctx->goto_table_mod_pointers); - ctx->goto_table_mod_pointers = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= ctx->state_count * sizeof(uint8_t *); - } - - if (ctx->output_table != NULL) { - int32_t state_count; - for (state_count = 0; state_count < ctx->state_count; state_count++) { - if (ctx->output_table[state_count].pids != NULL) { - SCFree(ctx->output_table[state_count].pids); - } - } - SCFree(ctx->output_table); - } - - if (ctx->pid_pat_list != NULL) { - int i; - for (i = 0; i < (ctx->max_pat_id + 1); i++) { - if (ctx->pid_pat_list[i].cs != NULL) - SCFree(ctx->pid_pat_list[i].cs); - if (ctx->pid_pat_list[i].sids != NULL) - SCFree(ctx->pid_pat_list[i].sids); - } - SCFree(ctx->pid_pat_list); - } - - SCFree(mpm_ctx->ctx); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACGfbsCtx); - - return; -} - -/** - * \brief The aho corasick search function. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - * \param pmq Pointer to the Pattern Matcher Queue to hold - * search matches. - * \param buf Buffer to be searched. - * \param buflen Buffer length. - * - * \retval matches Match count. - */ -uint32_t SCACGfbsSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - int matches = 0; - uint8_t buf_local; - - SCACGfbsPatternList *pid_pat_list = ctx->pid_pat_list; - - uint8_t bitarray[pmq->pattern_id_bitarray_size]; - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - - /* really hate the extra cmp here, but can't help it */ - if (ctx->state_count < 32767) { - /* \todo Change it for stateful MPM. Supply the state using mpm_thread_ctx */ - int32_t temp_state; - uint16_t no_of_entries; - uint8_t *ascii_codes; - uint16_t **goto_table_mod_pointers = (uint16_t **)ctx->goto_table_mod_pointers; - - //int32_t *failure_table = ctx->failure_table; - int i; - /* \todo tried loop unrolling with register var, with no perf increase. Need - * to dig deeper */ - /* with so many var declarations the register declaration here is useless */ - register int32_t state = 0; - for (i = 0; i < buflen; i++) { - if (state == 0) { - state = (goto_table_mod_pointers[0] + 2)[u8_tolower(buf[i])]; - } else { - - /* get the goto state transition */ - no_of_entries = *(goto_table_mod_pointers[state & 0x7FFF]); - if (no_of_entries == 0) { - temp_state = SC_AC_GFBS_FAIL; - } else { - if (no_of_entries == 1) { - ascii_codes = (uint8_t *)(goto_table_mod_pointers[state & 0x7FFF] + 2); - buf_local = u8_tolower(buf[i]); - if (buf_local == ascii_codes[0]) - temp_state = ((uint16_t *)(ascii_codes + ((no_of_entries + 1) & 0xFFE)))[0]; - else - temp_state = SC_AC_GFBS_FAIL; - } else { - buf_local = u8_tolower(buf[i]); - ascii_codes = (uint8_t *)(goto_table_mod_pointers[state & 0x7FFF] + 2); - int low = 0; - int high = no_of_entries; - int mid; - temp_state = SC_AC_GFBS_FAIL; - while (low <= high) { - mid = (low + high) / 2; - if (ascii_codes[mid] == buf_local) { - temp_state = ((uint16_t *)(ascii_codes + ((no_of_entries + 1) & 0xFFE)))[mid]; - break; - } else if (ascii_codes[mid] < buf_local) { - low = mid + 1; - } else { - high = mid - 1; - } - } - } - } - while (temp_state == SC_AC_GFBS_FAIL) { - state = *(goto_table_mod_pointers[state & 0x7FFF] + 1); - - /* get the goto state transition */ - no_of_entries = *(goto_table_mod_pointers[state & 0x7FFF]); - if (no_of_entries == 0) { - temp_state = SC_AC_GFBS_FAIL; - } else { - if (no_of_entries == 1) { - ascii_codes = (uint8_t *)(goto_table_mod_pointers[state & 0x7FFF] + 2); - buf_local = u8_tolower(buf[i]); - if (buf_local == ascii_codes[0]) - temp_state = ((uint16_t *)(ascii_codes + ((no_of_entries + 1) & 0xFFE)))[0]; - else - temp_state = SC_AC_GFBS_FAIL; - } else { - ascii_codes = (uint8_t *)(goto_table_mod_pointers[state & 0x7FFF] + 2); - buf_local = u8_tolower(buf[i]); - if (state == 0) { - temp_state = ((uint16_t *)ascii_codes)[buf_local]; - } else { - int low = 0; - int high = no_of_entries; - int mid; - temp_state = SC_AC_GFBS_FAIL; - while (low <= high) { - mid = (low + high) / 2; - if (ascii_codes[mid] == buf_local) { - temp_state = ((uint16_t *)(ascii_codes + ((no_of_entries + 1) & 0xFFE)))[mid]; - break; - } else if (ascii_codes[mid] < buf_local) { - low = mid + 1; - } else { - high = mid - 1; - } - } - } - } - } /* else - if (no_of_entries == 0) */ - } /* while (temp_state == SC_AC_GFBS_FAIL) */ - - state = temp_state; - - } - - if (state & 0x8000) { - uint32_t no_of_pid_entries = ctx->output_table[state & 0x7FFF].no_of_entries; - uint32_t *pids = ctx->output_table[state & 0x7FFF].pids; - uint32_t k = 0; - for (k = 0; k < no_of_pid_entries; k++) { - if (pids[k] & 0xFFFF0000) { - uint32_t lower_pid = pids[k] & 0x0000FFFF; - if (SCMemcmp(pid_pat_list[lower_pid].cs, - buf + i - pid_pat_list[lower_pid].patlen + 1, - pid_pat_list[lower_pid].patlen) != 0) { - /* inside loop */ - continue; - } - - if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { - ; - } else { - bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - pmq->pattern_id_bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - - MpmAddPid(pmq, lower_pid); - MpmAddSids(pmq, pid_pat_list[lower_pid].sids, pid_pat_list[lower_pid].sids_size); - } - matches++; - } else { - if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { - ; - } else { - bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - - MpmAddPid(pmq, pids[k]); - MpmAddSids(pmq, pid_pat_list[pids[k]].sids, pid_pat_list[pids[k]].sids_size); - } - matches++; - } - } - } /* if (ctx->output_table[state].no_of_entries != 0) */ - } /* for (i = 0; i < buflen; i++) */ - - } else { - /* \todo Change it for stateful MPM. Supply the state using mpm_thread_ctx */ - int32_t temp_state = 0; - uint32_t no_of_entries; - uint8_t *ascii_codes = NULL; - uint32_t **goto_table_mod_pointers = (uint32_t **)ctx->goto_table_mod_pointers; - //int32_t *failure_table = ctx->failure_table; - int i = 0; - /* \todo tried loop unrolling with register var, with no perf increase. Need - * to dig deeper */ - register int32_t state = 0; - for (i = 0; i < buflen; i++) { - if (state == 0) { - state = (goto_table_mod_pointers[0] + 2)[u8_tolower(buf[i])]; - } else { - - /* get the goto state transition */ - no_of_entries = *(goto_table_mod_pointers[state & 0x00FFFFFF]); - if (no_of_entries == 0) { - temp_state = SC_AC_GFBS_FAIL; - } else { - if (no_of_entries == 1) { - ascii_codes = (uint8_t *)(goto_table_mod_pointers[state & 0x00FFFFFF] + 2); - buf_local = u8_tolower(buf[i]); - if (buf_local == ascii_codes[0]) - temp_state = ((uint32_t *)(ascii_codes + ((no_of_entries + 3) & 0xFFC)))[0]; - else - temp_state = SC_AC_GFBS_FAIL; - } else { - buf_local = u8_tolower(buf[i]); - ascii_codes = (uint8_t *)(goto_table_mod_pointers[state & 0x00FFFFFF] + 2); - int low = 0; - int high = no_of_entries; - int mid; - temp_state = SC_AC_GFBS_FAIL; - while (low <= high) { - mid = (low + high) / 2; - if (ascii_codes[mid] == buf_local) { - temp_state = ((uint32_t *)(ascii_codes + ((no_of_entries + 3) & 0xFFC)))[mid]; - break; - } else if (ascii_codes[mid] < buf_local) { - low = mid + 1; - } else { - high = mid - 1; - } - } - } - } - while (temp_state == SC_AC_GFBS_FAIL) { - state = *(goto_table_mod_pointers[state & 0x00FFFFFF] + 1); - - /* get the goto state transition */ - no_of_entries = *(goto_table_mod_pointers[state & 0x00FFFFFF]); - if (no_of_entries == 0) { - temp_state = SC_AC_GFBS_FAIL; - } else { - if (no_of_entries == 1) { - ascii_codes = (uint8_t *)(goto_table_mod_pointers[state & 0x00FFFFFF] + 2); - buf_local = u8_tolower(buf[i]); - if (buf_local == ascii_codes[0]) - temp_state = ((uint32_t *)(ascii_codes + ((no_of_entries + 3) & 0xFFC)))[0]; - else - temp_state = SC_AC_GFBS_FAIL; - } else { - ascii_codes = (uint8_t *)(goto_table_mod_pointers[state & 0x00FFFFFF] + 2); - buf_local = u8_tolower(buf[i]); - if (state == 0) { - temp_state = ((uint32_t *)ascii_codes)[buf_local]; - } else { - int low = 0; - int high = no_of_entries; - int mid; - temp_state = SC_AC_GFBS_FAIL; - while (low <= high) { - mid = (low + high) / 2; - if (ascii_codes[mid] == buf_local) { - temp_state = ((uint32_t *)(ascii_codes + ((no_of_entries + 3) & 0xFFC)))[mid]; - break; - } else if (ascii_codes[mid] < buf_local) { - low = mid + 1; - } else { - high = mid - 1; - } - } - } - } /* else - if (no_of_entries[0] == 1) */ - } /* else - if (no_of_entries[0] == 0) */ - } /* while (temp_state == SC_AC_GFBS_FAIL) */ - state = temp_state; - - } - - if (state & 0x01000000) { - uint32_t no_of_pid_entries = ctx->output_table[state & 0x00FFFFFF].no_of_entries; - uint32_t *pids = ctx->output_table[state & 0x00FFFFFF].pids; - uint32_t k = 0; - for (k = 0; k < no_of_pid_entries; k++) { - if (pids[k] & 0xFFFF0000) { - uint32_t lower_pid = pids[k] & 0x0000FFFF; - if (SCMemcmp(pid_pat_list[lower_pid].cs, - buf + i - pid_pat_list[lower_pid].patlen + 1, - pid_pat_list[lower_pid].patlen) != 0) { - /* inside loop */ - continue; - } - - if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { - ; - } else { - bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - pmq->pattern_id_bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - - MpmAddPid(pmq, lower_pid); - MpmAddSids(pmq, pid_pat_list[lower_pid].sids, pid_pat_list[lower_pid].sids_size); - } - matches++; - } else { - if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { - ; - } else { - bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - - MpmAddPid(pmq, pids[k]); - MpmAddSids(pmq, pid_pat_list[pids[k]].sids, pid_pat_list[pids[k]].sids_size); - } - matches++; - } - //loop1: - //; - } - } /* if (ctx->output_table[state].no_of_entries != 0) */ - } /* for (i = 0; i < buflen; i++) */ - } - - return matches; -} - -/** - * \brief Add a case insensitive pattern. Although we have different calls for - * adding case sensitive and insensitive patterns, we make a single call - * for either case. No special treatment for either case. - * - * \param mpm_ctx Pointer to the mpm context. - * \param pat The pattern to add. - * \param patnen The pattern length. - * \param offset Ignored. - * \param depth Ignored. - * \param pid The pattern id. - * \param sid Ignored. - * \param flags Flags associated with this pattern. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCACGfbsAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - flags |= MPM_PATTERN_FLAG_NOCASE; - return SCACGfbsAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -/** - * \brief Add a case sensitive pattern. Although we have different calls for - * adding case sensitive and insensitive patterns, we make a single call - * for either case. No special treatment for either case. - * - * \param mpm_ctx Pointer to the mpm context. - * \param pat The pattern to add. - * \param patnen The pattern length. - * \param offset Ignored. - * \param depth Ignored. - * \param pid The pattern id. - * \param sid Ignored. - * \param flags Flags associated with this pattern. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCACGfbsAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - return SCACGfbsAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -void SCACGfbsPrintSearchStats(MpmThreadCtx *mpm_thread_ctx) -{ - -#ifdef SC_AC_COUNTERS - SCACGfbsThreadCtx *ctx = (SCACGfbsThreadCtx *)mpm_thread_ctx->ctx; - printf("AC Thread Search stats (ctx %p)\n", ctx); - printf("Total calls: %" PRIu32 "\n", ctx->total_calls); - printf("Total matches: %" PRIu64 "\n", ctx->total_matches); -#endif /* SC_AC_COUNTERS */ - - return; -} - -void SCACGfbsPrintInfo(MpmCtx *mpm_ctx) -{ - SCACGfbsCtx *ctx = (SCACGfbsCtx *)mpm_ctx->ctx; - - printf("MPM AC Information:\n"); - printf("Memory allocs: %" PRIu32 "\n", mpm_ctx->memory_cnt); - printf("Memory alloced: %" PRIu32 "\n", mpm_ctx->memory_size); - printf(" Sizeof:\n"); - printf(" MpmCtx %" PRIuMAX "\n", (uintmax_t)sizeof(MpmCtx)); - printf(" SCACGfbsCtx: %" PRIuMAX "\n", (uintmax_t)sizeof(SCACGfbsCtx)); - printf(" SCACGfbsPattern %" PRIuMAX "\n", (uintmax_t)sizeof(SCACGfbsPattern)); - printf(" SCACGfbsPattern %" PRIuMAX "\n", (uintmax_t)sizeof(SCACGfbsPattern)); - printf("Unique Patterns: %" PRIu32 "\n", mpm_ctx->pattern_cnt); - printf("Smallest: %" PRIu32 "\n", mpm_ctx->minlen); - printf("Largest: %" PRIu32 "\n", mpm_ctx->maxlen); - printf("Total states in the state table: %" PRIu32 "\n", ctx->state_count); - printf("\n"); - - return; -} - -/*************************************Unittests********************************/ - -#ifdef UNITTESTS - -static int SCACGfbsTest01(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest02(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abce", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest03(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghj", 4, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest04(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdegh", 6, 0, 0, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest05(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest06(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcd"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest07(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); - /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); - /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); - /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); - /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - 30, 0, 0, 5, 0, 0); - /* total matches: 135 */ - PmqSetup(&pmq, 6); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest08(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"a", 1); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest09(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ab", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"ab", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest10(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789" - "abcdefgh" - "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest11(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"he", 2, 0, 0, 1, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"she", 3, 0, 0, 2, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"his", 3, 0, 0, 3, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"hers", 4, 0, 0, 4, 0, 0) == -1) - goto end; - PmqSetup(&pmq, 4); - - if (SCACGfbsPreparePatterns(&mpm_ctx) == -1) - goto end; - - result = 1; - - char *buf = "he"; - result &= (SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "she"; - result &= (SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - buf = "his"; - result &= (SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "hers"; - result &= (SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - - end: - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest12(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"wxyz", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"vwxyz", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest13(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCD"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCD"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest14(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCDE"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCDE"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest15(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCDEF"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCDEF"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest16(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABC"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABC"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest17(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzAB"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzAB"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest18(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcde""fghij""klmno""pqrst""uvwxy""z"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcde""fghij""klmno""pqrst""uvwxy""z"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest19(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - char *pat = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest20(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - char *pat = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest21(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"AA", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest22(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest23(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 0) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest24(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest25(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghiJkl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest26(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "works"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - if (cnt == 1) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest27(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ONE", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "tone"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest28(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_GFBS); - SCACGfbsInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"one", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACGfbsPreparePatterns(&mpm_ctx); - - char *buf = "tONE"; - uint32_t cnt = SCACGfbsSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACGfbsDestroyCtx(&mpm_ctx); - SCACGfbsDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACGfbsTest29(void) -{ - uint8_t *buf = (uint8_t *)"onetwothreefourfivesixseveneightnine"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - de_ctx->mpm_matcher = MPM_AC_GFBS; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; fast_pattern:3,3; sid:2;)"); - if (de_ctx->sig_list->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) != 1) { - printf("if (PacketAlertCheck(p, 1) != 1) failure\n"); - goto end; - } - if (PacketAlertCheck(p, 2) != 1) { - printf("if (PacketAlertCheck(p, 1) != 2) failure\n"); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void SCACGfbsRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("SCACGfbsTest01", SCACGfbsTest01, 1); - UtRegisterTest("SCACGfbsTest02", SCACGfbsTest02, 1); - UtRegisterTest("SCACGfbsTest03", SCACGfbsTest03, 1); - UtRegisterTest("SCACGfbsTest04", SCACGfbsTest04, 1); - UtRegisterTest("SCACGfbsTest05", SCACGfbsTest05, 1); - UtRegisterTest("SCACGfbsTest06", SCACGfbsTest06, 1); - UtRegisterTest("SCACGfbsTest07", SCACGfbsTest07, 1); - UtRegisterTest("SCACGfbsTest08", SCACGfbsTest08, 1); - UtRegisterTest("SCACGfbsTest09", SCACGfbsTest09, 1); - UtRegisterTest("SCACGfbsTest10", SCACGfbsTest10, 1); - UtRegisterTest("SCACGfbsTest11", SCACGfbsTest11, 1); - UtRegisterTest("SCACGfbsTest12", SCACGfbsTest12, 1); - UtRegisterTest("SCACGfbsTest13", SCACGfbsTest13, 1); - UtRegisterTest("SCACGfbsTest14", SCACGfbsTest14, 1); - UtRegisterTest("SCACGfbsTest15", SCACGfbsTest15, 1); - UtRegisterTest("SCACGfbsTest16", SCACGfbsTest16, 1); - UtRegisterTest("SCACGfbsTest17", SCACGfbsTest17, 1); - UtRegisterTest("SCACGfbsTest18", SCACGfbsTest18, 1); - UtRegisterTest("SCACGfbsTest19", SCACGfbsTest19, 1); - UtRegisterTest("SCACGfbsTest20", SCACGfbsTest20, 1); - UtRegisterTest("SCACGfbsTest21", SCACGfbsTest21, 1); - UtRegisterTest("SCACGfbsTest22", SCACGfbsTest22, 1); - UtRegisterTest("SCACGfbsTest23", SCACGfbsTest23, 1); - UtRegisterTest("SCACGfbsTest24", SCACGfbsTest24, 1); - UtRegisterTest("SCACGfbsTest25", SCACGfbsTest25, 1); - UtRegisterTest("SCACGfbsTest26", SCACGfbsTest26, 1); - UtRegisterTest("SCACGfbsTest27", SCACGfbsTest27, 1); - UtRegisterTest("SCACGfbsTest28", SCACGfbsTest28, 1); - UtRegisterTest("SCACGfbsTest29", SCACGfbsTest29, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/util-mpm-ac-gfbs.h b/framework/src/suricata/src/util-mpm-ac-gfbs.h deleted file mode 100644 index 4003a5b5..00000000 --- a/framework/src/suricata/src/util-mpm-ac-gfbs.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - */ - -#define SC_AC_GFBS_STATE_TYPE_U16 uint16_t -#define SC_AC_GFBS_STATE_TYPE_U32 uint32_t - -typedef struct SCACGfbsPattern_ { - /* length of the pattern */ - uint16_t len; - /* flags decribing the pattern */ - uint8_t flags; - /* holds the original pattern that was added */ - uint8_t *original_pat; - /* case sensitive */ - uint8_t *cs; - /* case INsensitive */ - uint8_t *ci; - /* pattern id */ - uint32_t id; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; - - struct SCACGfbsPattern_ *next; -} SCACGfbsPattern; - -typedef struct SCACGfbsPatternList_ { - uint8_t *cs; - uint16_t patlen; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; -} SCACGfbsPatternList; - -typedef struct SCACGfbsOutputTable_ { - /* list of pattern sids */ - uint32_t *pids; - /* no of entries we have in pids */ - uint32_t no_of_entries; -} SCACGfbsOutputTable; - -typedef struct SCACGfbsGotoTableMod_ { - /* each of these below declarations will be of type uint32_t, if the state - * count exceeds 65535, the maximum value a 16 bit unsigned var can hold */ - - /* no of entries stored below */ - uint16_t no_of_entries; - - /* the ascii codes over which we have state transitions */ - uint16_t *ascii_codes; - /* the states that correspond to the ascii_codes above */ - uint16_t *states; -} SCACGfbsGotoTableMod_; - -typedef struct SCACGfbsCtx_ { - /* hash used during ctx initialization */ - SCACGfbsPattern **init_hash; - - /* pattern arrays. We need this only during the goto table creation phase */ - SCACGfbsPattern **parray; - - /* no of states used by ac */ - int32_t state_count; - /* the modified goto_table */ - uint8_t *goto_table_mod; - uint8_t **goto_table_mod_pointers; - - /* goto_table, failure table and output table. Needed to create state_table. - * Will be freed, once we have created the goto_table_mod */ - int32_t (*goto_table)[256]; - int32_t *failure_table; - SCACGfbsOutputTable *output_table; - SCACGfbsPatternList *pid_pat_list; - - /* the size of each state */ - uint16_t single_state_size; - uint16_t max_pat_id; -} SCACGfbsCtx; - -typedef struct SCACGfbsThreadCtx_ { - /* the total calls we make to the search function */ - uint32_t total_calls; - /* the total patterns that we ended up matching against */ - uint64_t total_matches; -} SCACGfbsThreadCtx; - -void MpmACGfbsRegister(void); diff --git a/framework/src/suricata/src/util-mpm-ac-tile-small.c b/framework/src/suricata/src/util-mpm-ac-tile-small.c deleted file mode 100644 index a99da063..00000000 --- a/framework/src/suricata/src/util-mpm-ac-tile-small.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2013-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ken Steele - - * Included by util-mpm-ac-tile.c with different SLOAD, SINDEX and - * FUNC_NAME - * - */ - -/* Only included into util-mpm-ac-tile.c, which defines FUNC_NAME - * - */ -#ifdef FUNC_NAME - -/* This function handles (ctx->state_count < 32767) */ -uint32_t FUNC_NAME(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - int i = 0; - int matches = 0; - - uint8_t mpm_bitarray[ctx->mpm_bitarray_size]; - memset(mpm_bitarray, 0, ctx->mpm_bitarray_size); - - uint8_t* restrict xlate = ctx->translate_table; - STYPE *state_table = (STYPE*)ctx->state_table; - STYPE state = 0; - int c = xlate[buf[0]]; - /* If buflen at least 4 bytes and buf 4-byte aligned. */ - if (buflen >= 4 && ((uint64_t)buf & 0x3) == 0) { - BTYPE data = *(BTYPE* restrict)(&buf[0]); - uint64_t index = 0; - /* Process 4*floor(buflen/4) bytes. */ - i = 0; - while (i < (buflen & ~0x3)) { - BTYPE data1 = *(BTYPE* restrict)(&buf[i + 4]); - index = SINDEX(index, state); - state = SLOAD(state_table + index + c); - c = xlate[BYTE1(data)]; - if (unlikely(SCHECK(state))) { - matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray); - } - i++; - index = SINDEX(index, state); - state = SLOAD(state_table + index + c); - c = xlate[BYTE2(data)]; - if (unlikely(SCHECK(state))) { - matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray); - } - i++; - index = SINDEX(index, state); - state = SLOAD(state_table + index + c); - c = xlate[BYTE3(data)]; - if (unlikely(SCHECK(state))) { - matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray); - } - data = data1; - i++; - index = SINDEX(index, state); - state = SLOAD(state_table + index + c); - c = xlate[BYTE0(data)]; - if (unlikely(SCHECK(state))) { - matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray); - } - i++; - } - } - /* Process buflen % 4 bytes. */ - for (; i < buflen; i++) { - uint64_t index = 0 ; - index = SINDEX(index, state); - state = SLOAD(state_table + index + c); - c = xlate[buf[i+1]]; - if (unlikely(SCHECK(state))) { - matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray); - } - } /* for (i = 0; i < buflen; i++) */ - - return matches; -} - -#endif /* FUNC_NAME */ diff --git a/framework/src/suricata/src/util-mpm-ac-tile.c b/framework/src/suricata/src/util-mpm-ac-tile.c deleted file mode 100644 index f3a52d6e..00000000 --- a/framework/src/suricata/src/util-mpm-ac-tile.c +++ /dev/null @@ -1,2855 +0,0 @@ -/* Copyright (C) 2013-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ken Steele - * \author Anoop Saldanha - * - * Aho-corasick MPM optimized for the Tilera Tile-Gx architecture. - * - * Efficient String Matching: An Aid to Bibliographic Search - * Alfred V. Aho and Margaret J. Corasick - * - * - Started with util-mpm-ac.c: - * - Uses the delta table for calculating transitions, - * instead of having separate goto and failure - * transitions. - * - If we cross 2 ** 16 states, we use 4 bytes in the - * transition table to hold each state, otherwise we use - * 2 bytes. - * - This version of the MPM is heavy on memory, but it - * performs well. If you can fit the ruleset with this - * mpm on your box without hitting swap, this is the MPM - * to go for. - * - * - Added these optimizations: - * - Compress the input alphabet from 256 characters down - * to the actual characters used in the patterns, plus - * one character for all the unused characters. - * - Reduce the size of the delta table so that each state - * is the smallest power of two that is larger than the - * size of the compressed alphabet. - * - Specialized the search function based on state count - * (small for 8-bit large for 16-bit) and the size of - * the alphabet, so that it is constant inside the - * function for better optimization. - * - * \todo - Do a proper analyis of our existing MPMs and suggest a good - * one based on the pattern distribution and the expected - * traffic(say http). - - * - Irrespective of whether we cross 2 ** 16 states or - * not,shift to using uint32_t for state type, so that we can - * integrate it's status as a final state or not in the - * topmost byte. We are already doing it if state_count is > - * 2 ** 16. - * - Test case-senstive patterns if they have any ascii chars. - * If they don't treat them as nocase. - * - Reorder the compressed alphabet to put the most common characters - * first. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" - -#include "conf.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-memcmp.h" -#include "util-memcpy.h" -#include "util-mpm-ac-tile.h" - -#ifndef __tile__ -void MpmACTileRegister(void) -{ -} -#endif - -/* There are Tilera Tile-Gx specific optimizations in this code. */ -#ifdef __tile__ - -void SCACTileInitCtx(MpmCtx *); -void SCACTileInitThreadCtx(MpmCtx *, MpmThreadCtx *, uint32_t); -void SCACTileDestroyCtx(MpmCtx *); -void SCACTileDestroyThreadCtx(MpmCtx *, MpmThreadCtx *); -int SCACTileAddPatternCI(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACTileAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACTilePreparePatterns(MpmCtx *mpm_ctx); -uint32_t SCACTileSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, uint8_t *buf, - uint16_t buflen); -void SCACTilePrintInfo(MpmCtx *mpm_ctx); -void SCACTilePrintSearchStats(MpmThreadCtx *mpm_thread_ctx); -void SCACTileRegisterTests(void); - -uint32_t SCACTileSearchLarge(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchSmall256(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchSmall128(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchSmall64(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchSmall32(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchSmall16(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchSmall8(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); - -uint32_t SCACTileSearchTiny256(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchTiny128(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchTiny64(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchTiny32(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchTiny16(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); -uint32_t SCACTileSearchTiny8(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen); - - -static void SCACTileDestroyInitCtx(MpmCtx *mpm_ctx); - - -/* a placeholder to denote a failure transition in the goto table */ -#define SC_AC_TILE_FAIL (-1) -/* size of the hash table used to speed up pattern insertions initially */ -#define INIT_HASH_SIZE 65536 - -#define STATE_QUEUE_CONTAINER_SIZE 65536 - -/** - * \brief Helper structure used by AC during state table creation - */ -typedef struct StateQueue_ { - int32_t store[STATE_QUEUE_CONTAINER_SIZE]; - int top; - int bot; -} StateQueue; - -/** - * \internal - * \brief Initialize the AC context with user specified conf parameters. We - * aren't retrieving anything for AC conf now, but we will certainly - * need it, when we customize AC. - */ -static void SCACTileGetConfig() -{ -} - -/** - * \internal - * \brief Compares 2 patterns. We use it for the hashing process during the - * the initial pattern insertion time, to cull duplicate sigs. - * - * \param p Pointer to the first pattern(SCACTilePattern). - * \param pat Pointer to the second pattern(raw pattern array). - * \param patlen Pattern length. - * \param flags Flags. We don't need this. - * - * \retval hash A 32 bit unsigned hash. - */ -static inline int SCACTileCmpPattern(SCACTilePattern *p, uint8_t *pat, - uint16_t patlen, char flags) -{ - if (p->len != patlen) - return 0; - - if (p->flags != flags) - return 0; - - if (flags & MPM_PATTERN_FLAG_NOCASE) { - // Case insensitive - if (SCMemcmpLowercase(p->cs, pat, patlen) != 0) - return 0; - - } else { - // Case sensitive - if (SCMemcmp(p->cs, pat, patlen) != 0) - return 0; - } - - return 1; -} - -/** - * \internal - * \brief Creates a hash of the pattern. We use it for the hashing process - * during the initial pattern insertion time, to cull duplicate sigs. - * - * \param pat Pointer to the pattern. - * \param patlen Pattern length. - * - * \retval hash A 32 bit unsigned hash. - */ -static inline uint32_t SCACTileInitHashRaw(uint8_t *pat, uint16_t patlen) -{ - uint32_t hash = patlen * pat[0]; - if (patlen > 1) - hash += pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -/** - * \internal - * \brief Looks up a pattern. We use it for the hashing process during the - * the initial pattern insertion time, to cull duplicate sigs. - * - * \param ctx Pointer to the AC ctx. - * \param pat Pointer to the pattern. - * \param patlen Pattern length. - * \param flags Flags. We don't need this. - * - * \retval hash A 32 bit unsigned hash. - */ -static inline SCACTilePattern *SCACTileInitHashLookup(SCACTileCtx *ctx, - uint8_t *pat, - uint16_t patlen, - char flags, - uint32_t pid) -{ - uint32_t hash = SCACTileInitHashRaw(pat, patlen); - - if (ctx->init_hash == NULL) { - return NULL; - } - - SCACTilePattern *t = ctx->init_hash[hash]; - for ( ; t != NULL; t = t->next) { - if (t->id == pid) { - return t; - } - } - - return NULL; -} - -/** - * \internal - * \brief Allocs a new pattern instance. - * - * \param mpm_ctx Pointer to the mpm context. - * - * \retval p Pointer to the newly created pattern. - */ -static inline SCACTilePattern *SCACTileAllocPattern(MpmCtx *mpm_ctx) -{ - SCACTilePattern *p = SCMalloc(sizeof(SCACTilePattern)); - if (unlikely(p == NULL)) { - exit(EXIT_FAILURE); - } - memset(p, 0, sizeof(SCACTilePattern)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACTilePattern); - - return p; -} - -/** - * \internal - * \brief Used to free SCACTilePattern instances. - * - * \param mpm_ctx Pointer to the mpm context. - * \param p Pointer to the SCACTilePattern instance to be freed. - * \param free Free the above pointer or not. - */ -static void SCACTileFreePattern(MpmCtx *mpm_ctx, SCACTilePattern *p) -{ - if (p != NULL && p->cs != NULL && p->cs != p->ci) { - SCFree(p->cs); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->ci != NULL) { - SCFree(p->ci); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->original_pat != NULL) { - SCFree(p->original_pat); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL) { - SCFree(p); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACTilePattern); - } -} - -static inline uint32_t SCACTileInitHash(SCACTilePattern *p) -{ - uint32_t hash = p->len * p->original_pat[0]; - if (p->len > 1) - hash += p->original_pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline int SCACTileInitHashAdd(SCACTileCtx *ctx, SCACTilePattern *p) -{ - uint32_t hash = SCACTileInitHash(p); - - if (ctx->init_hash == NULL) { - return 0; - } - - if (ctx->init_hash[hash] == NULL) { - ctx->init_hash[hash] = p; - return 0; - } - - SCACTilePattern *tt = NULL; - SCACTilePattern *t = ctx->init_hash[hash]; - - /* get the list tail */ - do { - tt = t; - t = t->next; - } while (t != NULL); - - tt->next = p; - - return 0; -} - - -/** - * \internal - * \brief Count the occurences of each character in the pattern and - * accumulate into a histogram. Really only used to detect unused - * characters, so could just set to 1 instead of counting. - */ -static inline void SCACTileHistogramAlphabet(SCACTileCtx *ctx, - SCACTilePattern *p) -{ - for (int i = 0; i < p->len; i++) { - ctx->alpha_hist[p->ci[i]]++; - } -} - -/* Use Alpahbet Histogram to create compressed alphabet. - */ -static void SCACTileInitTranslateTable(SCACTileCtx *ctx) -{ - /* Count the number of ASCII values actually appearing in any - * pattern. Create compressed mapping table with unused - * characters mapping to zero. - */ - for (int i = 0; i < 256; i++) { - /* Move all upper case counts to lower case */ - if (i >= 'A' && i <= 'Z') { - ctx->alpha_hist[i - 'A' + 'a'] += ctx->alpha_hist[i]; - ctx->alpha_hist[i] = 0; - } - if (ctx->alpha_hist[i]) { - ctx->alphabet_size++; - ctx->translate_table[i] = ctx->alphabet_size; - } else - ctx->translate_table[i] = 0; - } - /* Fix up translation table for uppercase */ - for (int i = 'A'; i <= 'Z'; i++) - ctx->translate_table[i] = ctx->translate_table[i - 'A' + 'a']; - - SCLogDebug(" Alphabet size %d", ctx->alphabet_size); - - /* Round alphabet size up to next power-of-two Leave one extra - * space For the unused-chararacters = 0 mapping. - */ - ctx->alphabet_size += 1; /* Extra space for unused-character */ - if (ctx->alphabet_size <= 8) { - ctx->alphabet_storage = 8; - } else if (ctx->alphabet_size <= 16) { - ctx->alphabet_storage = 16; - } else if (ctx->alphabet_size <= 32) { - ctx->alphabet_storage = 32; - } else if (ctx->alphabet_size <= 64) { - ctx->alphabet_storage = 64; - } else if (ctx->alphabet_size <= 128) { - ctx->alphabet_storage = 128; - } else - ctx->alphabet_storage = 256; -} - -/** - * \internal - * \brief Add a pattern to the mpm-ac context. - * - * \param mpm_ctx Mpm context. - * \param pat Pointer to the pattern. - * \param patlen Length of the pattern. - * \param pid Pattern id - * \param sid Signature id (internal id). - * \param flags Pattern's MPM_PATTERN_* flags. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int SCACTileAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - uint32_t sid, uint8_t flags) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - SCLogDebug("Adding pattern for ctx %p, patlen %"PRIu16" and pid %" PRIu32, - ctx, patlen, pid); - - if (patlen == 0) { - SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "pattern length 0"); - return 0; - } - - /* Check if we have already inserted this pattern. */ - SCACTilePattern *p = SCACTileInitHashLookup(ctx, pat, patlen, flags, pid); - if (p == NULL) { - SCLogDebug("Allocing new pattern"); - - /* p will never be NULL */ - p = SCACTileAllocPattern(mpm_ctx); - - p->len = patlen; - p->flags = flags; - p->id = pid; - - p->original_pat = SCMalloc(patlen); - if (p->original_pat == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->original_pat, pat, patlen); - - p->ci = SCMalloc(patlen); - if (p->ci == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy_tolower(p->ci, pat, patlen); - - /* setup the case sensitive part of the pattern */ - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - /* nocase means no difference between cs and ci */ - p->cs = p->ci; - } else { - if (memcmp(p->ci, pat, p->len) == 0) { - /* no diff between cs and ci: pat is lowercase */ - p->cs = p->ci; - } else { - p->cs = SCMalloc(patlen); - if (p->cs == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->cs, pat, patlen); - } - } - - /* put in the pattern hash */ - SCACTileInitHashAdd(ctx, p); - /* Count alphabet usages */ - SCACTileHistogramAlphabet(ctx, p); - - //if (mpm_ctx->pattern_cnt == 65535) { - // SCLogError(SC_ERR_AHO_CORASICK, "Max search words reached. Can't " - // "insert anymore. Exiting"); - // exit(EXIT_FAILURE); - //} - mpm_ctx->pattern_cnt++; - - if (mpm_ctx->maxlen < patlen) - mpm_ctx->maxlen = patlen; - - if (mpm_ctx->minlen == 0) { - mpm_ctx->minlen = patlen; - } else { - if (mpm_ctx->minlen > patlen) - mpm_ctx->minlen = patlen; - } - - p->sids_size = 1; - p->sids = SCMalloc(p->sids_size * sizeof(SigIntId)); - BUG_ON(p->sids == NULL); - p->sids[0] = sid; - //SCLogInfo("MPM added %u:%u", pid, sid); - } else { - /* TODO figure out how we can be called multiple times for the same CTX with the same sid */ - - int found = 0; - uint32_t x = 0; - for (x = 0; x < p->sids_size; x++) { - if (p->sids[x] == sid) { - found = 1; - break; - } - } - if (!found) { - SigIntId *sids = SCRealloc(p->sids, (sizeof(SigIntId) * (p->sids_size + 1))); - BUG_ON(sids == NULL); - p->sids = sids; - p->sids[p->sids_size] = sid; - p->sids_size++; - //SCLogInfo("p->sids_size %u", p->sids_size); - //SCLogInfo("MPM added %u:%u (append)", pid, sid); - } else { - //SCLogInfo("rule %u already part of pid %u", sid, pid); - } - } - - return 0; - -error: - SCACTileFreePattern(mpm_ctx, p); - return -1; -} - -static void SCACTileReallocOutputTable(SCACTileCtx *ctx, int new_state_count) -{ - - /* reallocate space in the output table for the new state */ - size_t size = ctx->allocated_state_count * sizeof(SCACTileOutputTable); - void *ptmp = SCRealloc(ctx->output_table, size); - if (ptmp == NULL) { - SCFree(ctx->output_table); - ctx->output_table = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ctx->output_table = ptmp; -} - -static void SCACTileReallocState(SCACTileCtx *ctx, int new_state_count) -{ - /* reallocate space in the goto table to include a new state */ - size_t size = ctx->allocated_state_count * sizeof(int32_t) * 256; - void *ptmp = SCRealloc(ctx->goto_table, size); - if (ptmp == NULL) { - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ctx->goto_table = ptmp; - - SCACTileReallocOutputTable(ctx, new_state_count); -} - -/** - * \internal - * \brief Initialize a new state in the goto and output tables. - * - * \param mpm_ctx Pointer to the mpm context. - * - * \retval The state id, of the newly created state. - */ -static inline int SCACTileInitNewState(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - int aa = 0; - - /* Exponentially increase the allocated space when needed. */ - if (ctx->allocated_state_count < ctx->state_count + 1) { - if (ctx->allocated_state_count == 0) - ctx->allocated_state_count = 256; - else - ctx->allocated_state_count *= 2; - - SCACTileReallocState(ctx, ctx->allocated_state_count); - } - - /* set all transitions for the newly assigned state as FAIL transitions */ - for (aa = 0; aa < ctx->alphabet_size; aa++) { - ctx->goto_table[ctx->state_count][aa] = SC_AC_TILE_FAIL; - } - - memset(ctx->output_table + ctx->state_count, 0, - sizeof(SCACTileOutputTable)); - - return ctx->state_count++; -} - -/** - * \internal - * \brief Adds a pid to the output table for a state. - * - * \param state The state to whose output table we should add the pid. - * \param pid The pattern id to add. - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACTileSetOutputState(int32_t state, MpmPatternIndex pindex, MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - SCACTileOutputTable *output_state = &ctx->output_table[state]; - uint32_t i = 0; - - /* Don't add the pattern more than once to the same state. */ - for (i = 0; i < output_state->no_of_entries; i++) { - if (output_state->patterns[i] == pindex) - return; - } - - /* Increase the size of the array of pids for this state and add - * the new pid. */ - output_state->no_of_entries++; - ptmp = SCRealloc(output_state->patterns, - output_state->no_of_entries * sizeof(MpmPatternIndex)); - if (ptmp == NULL) { - SCFree(output_state->patterns); - output_state->patterns = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - output_state->patterns = ptmp; - - output_state->patterns[output_state->no_of_entries - 1] = pindex; -} - -/** - * \brief Helper function used by SCACTileCreateGotoTable. Adds a - * pattern to the goto table. - * - * \param pattern Pointer to the pattern. - * \param pattern_len Pattern length. - * \param pid The pattern id, that corresponds to this pattern. We - * need it to updated the output table for this pattern. - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACTileEnter(uint8_t *pattern, uint16_t pattern_len, - MpmPatternIndex pindex, MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - int32_t state = 0; - int32_t newstate = 0; - int i = 0; - int p = 0; - int tc; - - /* Walk down the trie till we have a match for the pattern prefix */ - state = 0; - for (i = 0; i < pattern_len; i++) { - tc = ctx->translate_table[pattern[i]]; - if (ctx->goto_table[state][tc] == SC_AC_TILE_FAIL) - break; - state = ctx->goto_table[state][tc]; - } - - /* Add the non-matching pattern suffix to the trie, from the last state - * we left off */ - for (p = i; p < pattern_len; p++) { - newstate = SCACTileInitNewState(mpm_ctx); - tc = ctx->translate_table[pattern[p]]; - ctx->goto_table[state][tc] = newstate; - state = newstate; - } - - /* Add this pattern id, to the output table of the last state, where the - * pattern ends in the trie */ - SCACTileSetOutputState(state, pindex, mpm_ctx); -} - -/** - * \internal - * \brief Create the goto table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACTileCreateGotoTable(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - uint32_t i = 0; - - /* add each pattern to create the goto table */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - SCACTileEnter(ctx->parray[i]->ci, ctx->parray[i]->len, - i, mpm_ctx); - } - - int aa = 0; - for (aa = 0; aa < ctx->alphabet_size; aa++) { - if (ctx->goto_table[0][aa] == SC_AC_TILE_FAIL) { - ctx->goto_table[0][aa] = 0; - } - } -} - -static inline int SCACTileStateQueueIsEmpty(StateQueue *q) -{ - if (q->top == q->bot) - return 1; - else - return 0; -} - -static inline void SCACTileEnqueue(StateQueue *q, int32_t state) -{ - int i = 0; - - /*if we already have this */ - for (i = q->bot; i < q->top; i++) { - if (q->store[i] == state) - return; - } - - q->store[q->top++] = state; - - if (q->top == STATE_QUEUE_CONTAINER_SIZE) - q->top = 0; - - if (q->top == q->bot) { - SCLogCritical(SC_ERR_AHO_CORASICK, "Just ran out of space in the queue. " - "Fatal Error. Exiting. Please file a bug report on this"); - exit(EXIT_FAILURE); - } -} - -static inline int32_t SCACTileDequeue(StateQueue *q) -{ - if (q->bot == STATE_QUEUE_CONTAINER_SIZE) - q->bot = 0; - - if (q->bot == q->top) { - SCLogCritical(SC_ERR_AHO_CORASICK, "StateQueue behaving weirdly. " - "Fatal Error. Exiting. Please file a bug report on this"); - exit(EXIT_FAILURE); - } - - return q->store[q->bot++]; -} - -/** - * \internal - * \brief Club the output data from 2 states and store it in the 1st state. - * dst_state_data = {dst_state_data} UNION {src_state_data} - * - * \param dst_state First state(also the destination) for the union operation. - * \param src_state Second state for the union operation. - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACTileClubOutputStates(int32_t dst_state, - int32_t src_state, - MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - uint32_t i = 0; - uint32_t j = 0; - - SCACTileOutputTable *output_dst_state = &ctx->output_table[dst_state]; - SCACTileOutputTable *output_src_state = &ctx->output_table[src_state]; - - for (i = 0; i < output_src_state->no_of_entries; i++) { - for (j = 0; j < output_dst_state->no_of_entries; j++) { - if (output_src_state->patterns[i] == output_dst_state->patterns[j]) { - break; - } - } - if (j == output_dst_state->no_of_entries) { - output_dst_state->no_of_entries++; - - ptmp = SCRealloc(output_dst_state->patterns, - (output_dst_state->no_of_entries * sizeof(uint32_t))); - if (ptmp == NULL) { - SCFree(output_dst_state->patterns); - output_dst_state->patterns = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - output_dst_state->patterns = ptmp; - - output_dst_state->patterns[output_dst_state->no_of_entries - 1] = - output_src_state->patterns[i]; - } - } -} - -/** - * \internal - * \brief Create the failure table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACTileCreateFailureTable(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - int aa = 0; - int32_t state = 0; - int32_t r_state = 0; - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - /* Allocate space for the failure table. A failure entry in the table for - * every state(SCACTileCtx->state_count) */ - ctx->failure_table = SCMalloc(ctx->state_count * sizeof(int32_t)); - if (ctx->failure_table == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->failure_table, 0, ctx->state_count * sizeof(int32_t)); - - /* Add the failure transitions for the 0th state, and add every non-fail - * transition from the 0th state to the queue for further processing - * of failure states */ - for (aa = 0; aa < ctx->alphabet_size; aa++) { - int32_t temp_state = ctx->goto_table[0][aa]; - if (temp_state != 0) { - SCACTileEnqueue(&q, temp_state); - ctx->failure_table[temp_state] = 0; - } - } - - while (!SCACTileStateQueueIsEmpty(&q)) { - /* pick up every state from the queue and add failure transitions */ - r_state = SCACTileDequeue(&q); - for (aa = 0; aa < ctx->alphabet_size; aa++) { - int32_t temp_state = ctx->goto_table[r_state][aa]; - if (temp_state == SC_AC_TILE_FAIL) - continue; - SCACTileEnqueue(&q, temp_state); - state = ctx->failure_table[r_state]; - - while(ctx->goto_table[state][aa] == SC_AC_TILE_FAIL) - state = ctx->failure_table[state]; - ctx->failure_table[temp_state] = ctx->goto_table[state][aa]; - SCACTileClubOutputStates(temp_state, ctx->failure_table[temp_state], - mpm_ctx); - } - } -} - -/* - * Set the next state for 1 byte next-state. - */ -static void SCACTileSetState1Byte(SCACTileCtx *ctx, int state, int aa, - int next_state, int outputs) -{ - uint8_t *state_table = (uint8_t*)ctx->state_table; - uint8_t encoded_next_state = next_state; - - if (next_state == SC_AC_TILE_FAIL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error FAIL state in output"); - exit(EXIT_FAILURE); - } - - if (outputs == 0) - encoded_next_state |= (1 << 7); - - state_table[state * ctx->alphabet_storage + aa] = encoded_next_state; -} - -/* - * Set the next state for 2 byte next-state. - */ -static void SCACTileSetState2Bytes(SCACTileCtx *ctx, int state, int aa, - int next_state, int outputs) -{ - uint16_t *state_table = (uint16_t*)ctx->state_table; - uint16_t encoded_next_state = next_state; - - if (next_state == SC_AC_TILE_FAIL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error FAIL state in output"); - exit(EXIT_FAILURE); - } - - if (outputs == 0) - encoded_next_state |= (1 << 15); - - state_table[state * ctx->alphabet_storage + aa] = encoded_next_state; -} - -/* - * Set the next state for 4 byte next-state. - */ -static void SCACTileSetState4Bytes(SCACTileCtx *ctx, int state, int aa, - int next_state, int outputs) -{ - uint32_t *state_table = (uint32_t*)ctx->state_table; - uint32_t encoded_next_state = next_state; - - if (next_state == SC_AC_TILE_FAIL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error FAIL state in output"); - exit(EXIT_FAILURE); - } - - if (outputs == 0) - encoded_next_state |= (1 << 31); - - state_table[state * ctx->alphabet_storage + aa] = encoded_next_state; -} - -/** - * \internal - * \brief Create the delta table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACTileCreateDeltaTable(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - int aa = 0; - int32_t r_state = 0; - - if (ctx->state_count < 32767) { - if (ctx->state_count < 128) { - ctx->bytes_per_state = 1; - ctx->set_next_state = SCACTileSetState1Byte; - - switch(ctx->alphabet_storage) { - case 8: - ctx->search = SCACTileSearchTiny8; - break; - case 16: - ctx->search = SCACTileSearchTiny16; - break; - case 32: - ctx->search = SCACTileSearchTiny32; - break; - case 64: - ctx->search = SCACTileSearchTiny64; - break; - case 128: - ctx->search = SCACTileSearchTiny128; - break; - default: - ctx->search = SCACTileSearchTiny256; - } - } else { - /* 16-bit state needed */ - ctx->bytes_per_state = 2; - ctx->set_next_state = SCACTileSetState2Bytes; - - switch(ctx->alphabet_storage) { - case 8: - ctx->search = SCACTileSearchSmall8; - break; - case 16: - ctx->search = SCACTileSearchSmall16; - break; - case 32: - ctx->search = SCACTileSearchSmall32; - break; - case 64: - ctx->search = SCACTileSearchSmall64; - break; - case 128: - ctx->search = SCACTileSearchSmall128; - break; - default: - ctx->search = SCACTileSearchSmall256; - } - } - } else { - /* 32-bit next state */ - ctx->search = SCACTileSearchLarge; - ctx->bytes_per_state = 4; - ctx->set_next_state = SCACTileSetState4Bytes; - - ctx->alphabet_storage = 256; /* Change? */ - } - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - for (aa = 0; aa < ctx->alphabet_size; aa++) { - int temp_state = ctx->goto_table[0][aa]; - if (temp_state != 0) - SCACTileEnqueue(&q, temp_state); - } - - while (!SCACTileStateQueueIsEmpty(&q)) { - r_state = SCACTileDequeue(&q); - - for (aa = 0; aa < ctx->alphabet_size; aa++) { - int temp_state = ctx->goto_table[r_state][aa]; - if (temp_state != SC_AC_TILE_FAIL) { - SCACTileEnqueue(&q, temp_state); - } else { - int f_state = ctx->failure_table[r_state]; - ctx->goto_table[r_state][aa] = ctx->goto_table[f_state][aa]; - } - } - } -} - -static void SCACTileClubOutputStatePresenceWithDeltaTable(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - int aa = 0; - uint32_t state = 0; - - /* Allocate next-state table. */ - int size = ctx->state_count * ctx->bytes_per_state * ctx->alphabet_storage; - void *state_table = SCMalloc(size); - if (unlikely(state_table == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(state_table, 0, size); - ctx->state_table = state_table; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += size; - - SCLogInfo("Delta Table size %d, alphabet: %d, %d-byte states: %d", - size, ctx->alphabet_size, ctx->bytes_per_state, ctx->state_count); - - /* Copy next state from Goto table, which is 32 bits and encode it into the next - * state table, which can be 1, 2 or 4 bytes each and include if there is an - * output. - */ - for (state = 0; state < ctx->state_count; state++) { - for (aa = 0; aa < ctx->alphabet_size; aa++) { - int next_state = ctx->goto_table[state][aa]; - int next_state_outputs = ctx->output_table[next_state].no_of_entries; - ctx->set_next_state(ctx, state, aa, next_state, next_state_outputs); - } - } -} - -static inline void SCACTileInsertCaseSensitiveEntriesForPatterns(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - uint32_t state = 0; - uint32_t k = 0; - - for (state = 0; state < ctx->state_count; state++) { - if (ctx->output_table[state].no_of_entries == 0) - continue; - - for (k = 0; k < ctx->output_table[state].no_of_entries; k++) { - if (ctx->pattern_list[ctx->output_table[state].patterns[k]].cs != NULL) { - /* TODO - Find better way to store this. */ - ctx->output_table[state].patterns[k] &= 0x0FFFFFFF; - ctx->output_table[state].patterns[k] |= 1 << 31; - } - } - } -} - -#if 0 -static void SCACTilePrintDeltaTable(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - int i = 0, j = 0; - - printf("##############Delta Table##############\n"); - for (i = 0; i < ctx->state_count; i++) { - printf("%d: \n", i); - for (j = 0; j < ctx->alphabet_size; j++) { - if (SCACTileGetDelta(i, j, mpm_ctx) != 0) { - printf(" %c -> %d\n", j, SCACTileGetDelta(i, j, mpm_ctx)); - } - } - } -} -#endif - -/** - * \brief Process the patterns and prepare the state table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACTilePrepareStateTable(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - /* Create Alphabet compression and Lower Case translation table. */ - SCACTileInitTranslateTable(ctx); - - /* create the 0th state in the goto table and output_table */ - SCACTileInitNewState(mpm_ctx); - - /* create the goto table */ - SCACTileCreateGotoTable(mpm_ctx); - /* create the failure table */ - SCACTileCreateFailureTable(mpm_ctx); - /* create the final state(delta) table */ - SCACTileCreateDeltaTable(mpm_ctx); - /* club the output state presence with delta transition entries */ - SCACTileClubOutputStatePresenceWithDeltaTable(mpm_ctx); - - /* club nocase entries */ - SCACTileInsertCaseSensitiveEntriesForPatterns(mpm_ctx); - -#if 0 - SCACTilePrintDeltaTable(mpm_ctx); -#endif - - /* we don't need these anymore */ - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - SCFree(ctx->failure_table); - ctx->failure_table = NULL; -} - - -/** - * \brief Process Internal AC MPM tables to create the Search Context - * - * The search context is only the data needed to search the MPM. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACTilePrepareSearch(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - /* Resize the output table to be only as big as its final size. */ - SCACTileReallocOutputTable(ctx, ctx->state_count); - - search_ctx->search = ctx->search; - memcpy(search_ctx->translate_table, ctx->translate_table, sizeof(ctx->translate_table)); - - /* Move the state table from the Init context */ - search_ctx->state_table = ctx->state_table; - ctx->state_table = NULL; /* So that it won't get freed twice. */ - - /* Move the output_table from the Init context to the Search Context */ - /* TODO: Could be made more compact */ - search_ctx->output_table = ctx->output_table; - ctx->output_table = NULL; - - search_ctx->pattern_list = ctx->pattern_list; - ctx->pattern_list = NULL; - - /* One bit per pattern, rounded up to the next byte size. */ - search_ctx->mpm_bitarray_size = (mpm_ctx->pattern_cnt + 7) / 8; - - /* Can now free the Initialization data */ - SCACTileDestroyInitCtx(mpm_ctx); -} - -/** - * \brief Process the patterns added to the mpm, and create the internal tables. - * - * \param mpm_ctx Pointer to the mpm context. - */ -int SCACTilePreparePatterns(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - - if (mpm_ctx->pattern_cnt == 0 || search_ctx->init_ctx == NULL) { - SCLogDebug("no patterns supplied to this mpm_ctx"); - return 0; - } - SCACTileCtx *ctx = search_ctx->init_ctx; - if (ctx->init_hash == NULL) { - SCLogDebug("no patterns supplied to this mpm_ctx"); - return 0; - } - - /* alloc the pattern array */ - ctx->parray = (SCACTilePattern **)SCMalloc(mpm_ctx->pattern_cnt * - sizeof(SCACTilePattern *)); - if (ctx->parray == NULL) - goto error; - memset(ctx->parray, 0, mpm_ctx->pattern_cnt * sizeof(SCACTilePattern *)); - - /* populate it with the patterns in the hash */ - uint32_t i = 0, p = 0; - for (i = 0; i < INIT_HASH_SIZE; i++) { - SCACTilePattern *node = ctx->init_hash[i], *nnode = NULL; - while(node != NULL) { - nnode = node->next; - node->next = NULL; - ctx->parray[p++] = node; - node = nnode; - } - } - - /* we no longer need the hash, so free it's memory */ - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - - /* Handle case patterns by storing a copy of the pattern to compare - * to each possible match (no-case). - * - * Allocate the memory for the array and each of the strings as one block. - */ - size_t string_space_needed = 0; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (!(ctx->parray[i]->flags & MPM_PATTERN_FLAG_NOCASE)) { - /* Round up to next 8 byte aligned length */ - uint32_t space = ((ctx->parray[i]->len + 7) / 8) * 8; - string_space_needed += space; - } - } - - size_t pattern_list_size = mpm_ctx->pattern_cnt * sizeof(SCACTilePatternList); - size_t mem_size = string_space_needed + pattern_list_size; - void *mem_block = SCCalloc(1, mem_size); - if (mem_block == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += mem_size; - /* Split the allocated block into pattern list array and string space. */ - ctx->pattern_list = mem_block; - uint8_t *string_space = mem_block + pattern_list_size; - - /* Now make the copies of the no-case strings. */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (!(ctx->parray[i]->flags & MPM_PATTERN_FLAG_NOCASE)) { - uint32_t len = ctx->parray[i]->len; - uint32_t space = ((len + 7) / 8) * 8; - memcpy(string_space, ctx->parray[i]->original_pat, len); - ctx->pattern_list[i].cs = string_space; - ctx->pattern_list[i].patlen = len; - string_space += space; - } - ctx->pattern_list[i].pid = ctx->parray[i]->id; - - /* ACPatternList now owns this memory */ - ctx->pattern_list[i].sids_size = ctx->parray[i]->sids_size; - ctx->pattern_list[i].sids = ctx->parray[i]->sids; - } - - /* prepare the state table required by AC */ - SCACTilePrepareStateTable(mpm_ctx); - - /* Convert to the Search Context structure */ - SCACTilePrepareSearch(mpm_ctx); - - return 0; - -error: - return -1; -} - -/** - * \brief Init the mpm thread context. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - * \param matchsize We don't need this. - */ -void SCACTileInitThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - uint32_t matchsize) -{ - memset(mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - - mpm_thread_ctx->ctx = SCMalloc(sizeof(SCACTileThreadCtx)); - if (mpm_thread_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - memset(mpm_thread_ctx->ctx, 0, sizeof(SCACTileThreadCtx)); - mpm_thread_ctx->memory_cnt++; - mpm_thread_ctx->memory_size += sizeof(SCACTileThreadCtx); -} - -/** - * \brief Initialize the AC context. - * - * \param mpm_ctx Mpm context. - */ -void SCACTileInitCtx(MpmCtx *mpm_ctx) -{ - if (mpm_ctx->ctx != NULL) - return; - - /* Search Context */ - mpm_ctx->ctx = SCMalloc(sizeof(SCACTileSearchCtx)); - if (mpm_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - memset(mpm_ctx->ctx, 0, sizeof(SCACTileSearchCtx)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACTileSearchCtx); - - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - - /* MPM Creation context */ - search_ctx->init_ctx = SCMalloc(sizeof(SCACTileCtx)); - if (search_ctx->init_ctx == NULL) { - exit(EXIT_FAILURE); - } - memset(search_ctx->init_ctx, 0, sizeof(SCACTileCtx)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACTileCtx); - - /* initialize the hash we use to speed up pattern insertions */ - SCACTileCtx *ctx = search_ctx->init_ctx; - ctx->init_hash = SCMalloc(sizeof(SCACTilePattern *) * INIT_HASH_SIZE); - if (ctx->init_hash == NULL) { - exit(EXIT_FAILURE); - } - memset(ctx->init_hash, 0, sizeof(SCACTilePattern *) * INIT_HASH_SIZE); - - /* get conf values for AC from our yaml file. We have no conf values for - * now. We will certainly need this, as we develop the algo */ - SCACTileGetConfig(); -} - -/** - * \brief Destroy the mpm thread context. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - */ -void SCACTileDestroyThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx) -{ - SCACTilePrintSearchStats(mpm_thread_ctx); - - if (mpm_thread_ctx->ctx != NULL) { - SCFree(mpm_thread_ctx->ctx); - mpm_thread_ctx->ctx = NULL; - mpm_thread_ctx->memory_cnt--; - mpm_thread_ctx->memory_size -= sizeof(SCACTileThreadCtx); - } -} - -static void SCACTileDestroyInitCtx(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - if (ctx == NULL) - return; - - if (ctx->init_hash != NULL) { - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - } - - if (ctx->parray != NULL) { - uint32_t i; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - SCACTileFreePattern(mpm_ctx, ctx->parray[i]); - } - } - - SCFree(ctx->parray); - ctx->parray = NULL; - } - - if (ctx->state_table != NULL) { - SCFree(ctx->state_table); - - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (ctx->state_count * - ctx->bytes_per_state * ctx->alphabet_storage); - } - - if (ctx->output_table != NULL) { - uint32_t state; - for (state = 0; state < ctx->state_count; state++) { - if (ctx->output_table[state].patterns != NULL) { - SCFree(ctx->output_table[state].patterns); - } - } - SCFree(ctx->output_table); - } - - if (ctx->pattern_list != NULL) { - uint32_t i; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->pattern_list[i].cs != NULL) - SCFree(ctx->pattern_list[i].cs); - if (ctx->pattern_list[i].sids != NULL) - SCFree(ctx->pattern_list[i].sids); - } - SCFree(ctx->pattern_list); - } - - SCFree(ctx); - search_ctx->init_ctx = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACTileCtx); -} - -/** - * \brief Destroy the mpm context. - * - * \param mpm_ctx Pointer to the mpm context. - */ -void SCACTileDestroyCtx(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - if (search_ctx == NULL) - return; - - /* Destroy Initialization data */ - SCACTileDestroyInitCtx(mpm_ctx); - - /* Free Search tables */ - SCFree(search_ctx->state_table); - SCFree(search_ctx->pattern_list); - SCFree(search_ctx->output_table); - - SCFree(search_ctx); - mpm_ctx->ctx = NULL; - - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACTileSearchCtx); -} - -/* - * Heavily optimized pattern matching routine for TILE-Gx. - */ - -#define SCHECK(x) ((x) > 0) -#define BTYPE int32_t -// Extract byte N=0,1,2,3 from x -#define BYTE0(x) __insn_bfextu(x, 0, 7) -#define BYTE1(x) __insn_bfextu(x, 8, 15) -#define BYTE2(x) __insn_bfextu(x, 16, 23) -#define BYTE3(x) __insn_bfextu(x, 24, 31) - -int CheckMatch(SCACTileSearchCtx *ctx, PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen, - uint16_t state, int i, int matches, - uint8_t *mpm_bitarray) -{ - SCACTilePatternList *pattern_list = ctx->pattern_list; - uint8_t *buf_offset = buf + i + 1; // Lift out of loop - uint32_t no_of_entries = ctx->output_table[state].no_of_entries; - MpmPatternIndex *patterns = ctx->output_table[state].patterns; - uint8_t *pmq_bitarray = pmq->pattern_id_bitarray; - uint32_t k; - - for (k = 0; k < no_of_entries; k++) { - MpmPatternIndex pindex = patterns[k] & 0x0FFFFFFF; - if (mpm_bitarray[pindex / 8] & (1 << (pindex % 8))) { - /* Pattern already seen by this MPM. */ - /* NOTE: This is faster then rechecking if it is a case-sensitive match - * since we know this pattern has already been seen, but imcrementing - * matches here could over report matches. For example if the case-sensitive - * pattern is "Foo" and the string is "Foo bar foo", matches would be reported - * as 2, when it should really be 1, since "foo" is not a true match. - */ - matches++; - continue; - } - uint32_t pid = pattern_list[pindex].pid; - /* Double check case-sensitve match now. */ - if (patterns[k] >> 31) { - uint16_t patlen = pattern_list[pindex].patlen; - if (SCMemcmpNZ(pattern_list[pindex].cs, buf_offset - patlen, patlen) != 0) { - /* Case-sensitive match failed. */ - continue; - } - } - /* New match found */ - mpm_bitarray[pindex / 8] |= (1 << (pindex % 8)); - - if ((pmq_bitarray[pid / 8] & (1 << (pid % 8))) == 0) { - pmq_bitarray[(pid) / 8] |= (1 << ((pid) % 8)); - MpmAddPid(pmq, pid); - } - - /* Always add the Signature IDs, since they could be different in the current MPM - * than in a previous MPM on the same PMQ when finding the same pattern. - */ - MpmAddSids(pmq, pattern_list[pindex].sids, - pattern_list[pindex].sids_size); - matches++; - } - - return matches; -} - -/** - * \brief The aho corasick search function. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - * \param pmq Pointer to the Pattern Matcher Queue to hold - * search matches. - * \param buf Buffer to be searched. - * \param buflen Buffer length. - * - * \retval matches Match count. - */ -uint32_t SCACTileSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - - if (buflen == 0) - return 0; - - /* Context specific matching function. */ - return search_ctx->search(search_ctx, mpm_thread_ctx, pmq, buf, buflen); -} - -/* This function handles (ctx->state_count >= 32767) */ -uint32_t SCACTileSearchLarge(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, - uint8_t *buf, uint16_t buflen) -{ - int i = 0; - int matches = 0; - - uint8_t mpm_bitarray[ctx->mpm_bitarray_size]; - memset(mpm_bitarray, 0, ctx->mpm_bitarray_size); - - uint8_t* restrict xlate = ctx->translate_table; - register int state = 0; - int32_t (*state_table_u32)[256] = ctx->state_table; - for (i = 0; i < buflen; i++) { - state = state_table_u32[state & 0x00FFFFFF][xlate[buf[i]]]; - if (SCHECK(state)) { - matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray); - } - } /* for (i = 0; i < buflen; i++) */ - - return matches; -} - -/* - * Search with Alphabet size of 256 and 16-bit next-state entries. - * Next state entry has MSB as "match" and 15 LSB bits as next-state index. - */ -// y = 1<ctx; - printf("AC Thread Search stats (ctx %p)\n", ctx); - printf("Total calls: %" PRIu32 "\n", ctx->total_calls); - printf("Total matches: %" PRIu64 "\n", ctx->total_matches); -#endif /* SC_AC_TILE_COUNTERS */ -} - -void SCACTilePrintInfo(MpmCtx *mpm_ctx) -{ - SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; - SCACTileCtx *ctx = search_ctx->init_ctx; - - printf("MPM AC Information:\n"); - printf("Memory allocs: %" PRIu32 "\n", mpm_ctx->memory_cnt); - printf("Memory alloced: %" PRIu32 "\n", mpm_ctx->memory_size); - printf(" Sizeof:\n"); - printf(" MpmCtx %" PRIuMAX "\n", (uintmax_t)sizeof(MpmCtx)); - printf(" SCACTileCtx: %" PRIuMAX "\n", (uintmax_t)sizeof(SCACTileCtx)); - printf(" SCACTilePattern %" PRIuMAX "\n", (uintmax_t)sizeof(SCACTilePattern)); - printf(" SCACTilePattern %" PRIuMAX "\n", (uintmax_t)sizeof(SCACTilePattern)); - printf("Unique Patterns: %" PRIu32 "\n", mpm_ctx->pattern_cnt); - printf("Smallest: %" PRIu32 "\n", mpm_ctx->minlen); - printf("Largest: %" PRIu32 "\n", mpm_ctx->maxlen); - printf("Total states in the state table: %d\n", ctx->state_count); - printf("\n"); -} - -/************************** Mpm Registration ***************************/ - -/** - * \brief Register the aho-corasick mpm for Tilera Tile-Gx processor. - */ -void MpmACTileRegister(void) -{ - mpm_table[MPM_AC_TILE].name = "ac-tile"; - mpm_table[MPM_AC_TILE].max_pattern_length = 0; - - mpm_table[MPM_AC_TILE].InitCtx = SCACTileInitCtx; - mpm_table[MPM_AC_TILE].InitThreadCtx = SCACTileInitThreadCtx; - mpm_table[MPM_AC_TILE].DestroyCtx = SCACTileDestroyCtx; - mpm_table[MPM_AC_TILE].DestroyThreadCtx = SCACTileDestroyThreadCtx; - mpm_table[MPM_AC_TILE].AddPattern = SCACTileAddPatternCS; - mpm_table[MPM_AC_TILE].AddPatternNocase = SCACTileAddPatternCI; - mpm_table[MPM_AC_TILE].Prepare = SCACTilePreparePatterns; - mpm_table[MPM_AC_TILE].Search = SCACTileSearch; - mpm_table[MPM_AC_TILE].Cleanup = NULL; - mpm_table[MPM_AC_TILE].PrintCtx = SCACTilePrintInfo; - mpm_table[MPM_AC_TILE].PrintThreadCtx = SCACTilePrintSearchStats; - mpm_table[MPM_AC_TILE].RegisterUnittests = SCACTileRegisterTests; -} - - -/*************************************Unittests********************************/ - -#ifdef UNITTESTS - -static int SCACTileTest01(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest02(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abce", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest03(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghj", 4, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest04(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdegh", 6, 0, 0, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest05(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest06(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcd"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest07(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); - /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); - /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); - /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); - /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - 30, 0, 0, 5, 0, 0); - PmqSetup(&pmq, 6); - /* total matches: 135 */ - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest08(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"a", 1); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest09(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ab", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"ab", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest10(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789" - "abcdefgh" - "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest11(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"he", 2, 0, 0, 1, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"she", 3, 0, 0, 2, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"his", 3, 0, 0, 3, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"hers", 4, 0, 0, 4, 0, 0) == -1) - goto end; - PmqSetup(&pmq, 5); - - if (SCACTilePreparePatterns(&mpm_ctx) == -1) - goto end; - - result = 1; - - char *buf = "he"; - result &= (SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "she"; - result &= (SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - buf = "his"; - result &= (SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "hers"; - result &= (SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - - end: - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest12(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"wxyz", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"vwxyz", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest13(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCD"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCD"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest14(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCDE"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCDE"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest15(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCDEF"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCDEF"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest16(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABC"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABC"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest17(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzAB"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzAB"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest18(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcde""fghij""klmno""pqrst""uvwxy""z"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcde""fghij""klmno""pqrst""uvwxy""z"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest19(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - char *pat = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest20(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - char *pat = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest21(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"AA", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest22(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest23(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 0) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest24(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest25(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghiJkl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest26(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "works"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest27(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ONE", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "tone"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest28(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_TILE); - SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"one", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACTilePreparePatterns(&mpm_ctx); - - char *buf = "tONE"; - uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACTileDestroyCtx(&mpm_ctx); - SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTileTest29(void) -{ - uint8_t *buf = (uint8_t *)"onetwothreefourfivesixseveneightnine"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; fast_pattern:3,3; sid:2;)"); - if (de_ctx->sig_list->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) != 1) { - printf("if (PacketAlertCheck(p, 1) != 1) failure\n"); - goto end; - } - if (PacketAlertCheck(p, 2) != 1) { - printf("if (PacketAlertCheck(p, 1) != 2) failure\n"); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void SCACTileRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("SCACTileTest01", SCACTileTest01, 1); - UtRegisterTest("SCACTileTest02", SCACTileTest02, 1); - UtRegisterTest("SCACTileTest03", SCACTileTest03, 1); - UtRegisterTest("SCACTileTest04", SCACTileTest04, 1); - UtRegisterTest("SCACTileTest05", SCACTileTest05, 1); - UtRegisterTest("SCACTileTest06", SCACTileTest06, 1); - UtRegisterTest("SCACTileTest07", SCACTileTest07, 1); - UtRegisterTest("SCACTileTest08", SCACTileTest08, 1); - UtRegisterTest("SCACTileTest09", SCACTileTest09, 1); - UtRegisterTest("SCACTileTest10", SCACTileTest10, 1); - UtRegisterTest("SCACTileTest11", SCACTileTest11, 1); - UtRegisterTest("SCACTileTest12", SCACTileTest12, 1); - UtRegisterTest("SCACTileTest13", SCACTileTest13, 1); - UtRegisterTest("SCACTileTest14", SCACTileTest14, 1); - UtRegisterTest("SCACTileTest15", SCACTileTest15, 1); - UtRegisterTest("SCACTileTest16", SCACTileTest16, 1); - UtRegisterTest("SCACTileTest17", SCACTileTest17, 1); - UtRegisterTest("SCACTileTest18", SCACTileTest18, 1); - UtRegisterTest("SCACTileTest19", SCACTileTest19, 1); - UtRegisterTest("SCACTileTest20", SCACTileTest20, 1); - UtRegisterTest("SCACTileTest21", SCACTileTest21, 1); - UtRegisterTest("SCACTileTest22", SCACTileTest22, 1); - UtRegisterTest("SCACTileTest23", SCACTileTest23, 1); - UtRegisterTest("SCACTileTest24", SCACTileTest24, 1); - UtRegisterTest("SCACTileTest25", SCACTileTest25, 1); - UtRegisterTest("SCACTileTest26", SCACTileTest26, 1); - UtRegisterTest("SCACTileTest27", SCACTileTest27, 1); - UtRegisterTest("SCACTileTest28", SCACTileTest28, 1); - UtRegisterTest("SCACTileTest29", SCACTileTest29, 1); -#endif -} - -#endif /* __tile__ */ diff --git a/framework/src/suricata/src/util-mpm-ac-tile.h b/framework/src/suricata/src/util-mpm-ac-tile.h deleted file mode 100644 index 63d5bc95..00000000 --- a/framework/src/suricata/src/util-mpm-ac-tile.h +++ /dev/null @@ -1,174 +0,0 @@ -/* Copyright (C) 2013-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * \author Ken Steele - * - */ - -#ifndef __UTIL_MPM_AC_TILE__H__ -#define __UTIL_MPM_AC_TILE__H__ - -typedef struct SCACTilePattern_ { - /* length of the pattern */ - uint16_t len; - /* flags decribing the pattern */ - uint8_t flags; - /* holds the original pattern that was added */ - uint8_t *original_pat; - /* case sensitive */ - uint8_t *cs; - /* case INsensitive */ - uint8_t *ci; - /* pattern id */ - uint32_t id; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; - - struct SCACTilePattern_ *next; -} SCACTilePattern; - -typedef struct SCACTilePatternList_ { - uint8_t *cs; - uint16_t patlen; - - /* Pattern Id */ - uint32_t pid; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; -} SCACTilePatternList; - -typedef struct SCACTileOutputTable_ { - /* list of pattern indexes */ - MpmPatternIndex *patterns; - /* number of entries in pattern list */ - uint32_t no_of_entries; -} SCACTileOutputTable; - -struct SCACTileSearchCtx_; - -/* Reordered for Tilera cache */ -typedef struct SCACTileCtx_ { - - /* Convert input character to matching alphabet */ - uint8_t translate_table[256]; - - /* The all important memory hungry state_table. - * The size of each next-state is determined by bytes_per_state. - */ - void *state_table; - - /* Specialized search function based on size of data in delta - * tables. The alphabet size determines address shifting and the - * number of states could make the next state could be 16 bits or - * 32 bits. - */ - uint32_t (*search)(struct SCACTileSearchCtx_ *ctx, struct MpmThreadCtx_ *, - PatternMatcherQueue *, uint8_t *, uint16_t); - - /* Function to set the next state based on size of next state - * (bytes_per_state). - */ - void (*set_next_state)(struct SCACTileCtx_ *ctx, int state, int aa, - int new_state, int outputs); - - /* List of patterns that match for this state. Indexed by State Number */ - SCACTileOutputTable *output_table; - /* Indexed by MpmPatternIndex */ - SCACTilePatternList *pattern_list; - - /* hash used during ctx initialization */ - SCACTilePattern **init_hash; - - /* pattern arrays. We need this only during the goto table - creation phase */ - SCACTilePattern **parray; - - /* goto_table, failure table and output table. Needed to create - * state_table. Will be freed, once we have created the - * state_table */ - int32_t (*goto_table)[256]; - int32_t *failure_table; - - /* Number of states used by ac-tile */ - uint32_t state_count; - /* Number of states allocated for ac-tile. */ - uint32_t allocated_state_count; - - uint32_t alpha_hist[256]; - /* Number of characters in the compressed alphabet. */ - uint16_t alphabet_size; - /* Space used to store compressed alphabet is the next - * larger or equal power-of-2. - */ - uint16_t alphabet_storage; - - /* How many bytes are used to store the next state. */ - uint8_t bytes_per_state; - -} SCACTileCtx; - - -/* Only the stuff used at search time. This - * structure is created after all the patterns are added. - */ -typedef struct SCACTileSearchCtx_ { - - /* Specialized search function based on size of data in delta - * tables. The alphabet size determines address shifting and the - * number of states could make the next state could be 16 bits or - * 32 bits. - */ - uint32_t (*search)(struct SCACTileSearchCtx_ *ctx, struct MpmThreadCtx_ *, - PatternMatcherQueue *, uint8_t *, uint16_t); - - /* Convert input character to matching alphabet */ - uint8_t translate_table[256]; - - /* the all important memory hungry state_table */ - void *state_table; - - /* List of patterns that match for this state. Indexed by State Number */ - SCACTileOutputTable *output_table; - SCACTilePatternList *pattern_list; - - /* Number of bytes in the array of bits. One bit per pattern in this MPM. */ - uint32_t mpm_bitarray_size; - - /* MPM Creation data, only used at initialization. */ - SCACTileCtx *init_ctx; - -} SCACTileSearchCtx; - - -typedef struct SCACTileThreadCtx_ { - /* the total calls we make to the search function */ - uint32_t total_calls; - /* the total patterns that we ended up matching against */ - uint64_t total_matches; -} SCACTileThreadCtx; - -void MpmACTileRegister(void); - -#endif /* __UTIL_MPM_AC_TILE__H__ */ diff --git a/framework/src/suricata/src/util-mpm-ac.c b/framework/src/suricata/src/util-mpm-ac.c deleted file mode 100644 index c8f6be77..00000000 --- a/framework/src/suricata/src/util-mpm-ac.c +++ /dev/null @@ -1,3341 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * First iteration of aho-corasick MPM from - - * - * Efficient String Matching: An Aid to Bibliographic Search - * Alfred V. Aho and Margaret J. Corasick - * - * - Uses the delta table for calculating transitions, instead of having - * separate goto and failure transitions. - * - If we cross 2 ** 16 states, we use 4 bytes in the transition table - * to hold each state, otherwise we use 2 bytes. - * - This version of the MPM is heavy on memory, but it performs well. - * If you can fit the ruleset with this mpm on your box without hitting - * swap, this is the MPM to go for. - * - * \todo - Do a proper analyis of our existing MPMs and suggest a good one based - * on the pattern distribution and the expected traffic(say http). - * - Tried out loop unrolling without any perf increase. Need to dig deeper. - * - Irrespective of whether we cross 2 ** 16 states or not,shift to using - * uint32_t for state type, so that we can integrate it's status as a - * final state or not in the topmost byte. We are already doing it if - * state_count is > 2 ** 16. - * - Test case-senstive patterns if they have any ascii chars. If they - * don't treat them as nocase. - * - Carry out other optimizations we are working on. hashes, compression. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" - -#include "conf.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-memcmp.h" -#include "util-mpm-ac.h" -#include "util-memcpy.h" - -#ifdef __SC_CUDA_SUPPORT__ - -#include "util-mpm.h" -#include "tm-threads.h" -#include "detect-engine-mpm.h" -#include "util-cuda.h" -#include "util-cuda-handlers.h" -#endif /* __SC_CUDA_SUPPORT__ */ - -void SCACInitCtx(MpmCtx *); -void SCACInitThreadCtx(MpmCtx *, MpmThreadCtx *, uint32_t); -void SCACDestroyCtx(MpmCtx *); -void SCACDestroyThreadCtx(MpmCtx *, MpmThreadCtx *); -int SCACAddPatternCI(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACPreparePatterns(MpmCtx *mpm_ctx); -uint32_t SCACSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen); -void SCACPrintInfo(MpmCtx *mpm_ctx); -void SCACPrintSearchStats(MpmThreadCtx *mpm_thread_ctx); -void SCACRegisterTests(void); - -/* a placeholder to denote a failure transition in the goto table */ -#define SC_AC_FAIL (-1) -/* size of the hash table used to speed up pattern insertions initially */ -#define INIT_HASH_SIZE 65536 - -#define STATE_QUEUE_CONTAINER_SIZE 65536 - -static int construct_both_16_and_32_state_tables = 0; - -/** - * \brief Helper structure used by AC during state table creation - */ -typedef struct StateQueue_ { - int32_t store[STATE_QUEUE_CONTAINER_SIZE]; - int top; - int bot; -} StateQueue; - -/** - * \internal - * \brief Initialize the AC context with user specified conf parameters. We - * aren't retrieving anything for AC conf now, but we will certainly - * need it, when we customize AC. - */ -static void SCACGetConfig() -{ - //ConfNode *ac_conf; - //const char *hash_val = NULL; - - //ConfNode *pm = ConfGetNode("pattern-matcher"); - - return; -} - -/** - * \internal - * \brief Creates a hash of the pattern. We use it for the hashing process - * during the initial pattern insertion time, to cull duplicate sigs. - * - * \param pat Pointer to the pattern. - * \param patlen Pattern length. - * - * \retval hash A 32 bit unsigned hash. - */ -static inline uint32_t SCACInitHashRaw(uint8_t *pat, uint16_t patlen) -{ - uint32_t hash = patlen * pat[0]; - if (patlen > 1) - hash += pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -/** - * \internal - * \brief Looks up a pattern. We use it for the hashing process during the - * the initial pattern insertion time, to cull duplicate sigs. - * - * \param ctx Pointer to the AC ctx. - * \param pat Pointer to the pattern. - * \param patlen Pattern length. - * \param flags Flags. We don't need this. - * - * \retval hash A 32 bit unsigned hash. - */ -static inline SCACPattern *SCACInitHashLookup(SCACCtx *ctx, uint8_t *pat, - uint16_t patlen, char flags, - uint32_t pid) -{ - uint32_t hash = SCACInitHashRaw(pat, patlen); - - if (ctx->init_hash == NULL) { - return NULL; - } - - SCACPattern *t = ctx->init_hash[hash]; - for ( ; t != NULL; t = t->next) { - if (t->id == pid) - return t; - } - - return NULL; -} - -/** - * \internal - * \brief Allocs a new pattern instance. - * - * \param mpm_ctx Pointer to the mpm context. - * - * \retval p Pointer to the newly created pattern. - */ -static inline SCACPattern *SCACAllocPattern(MpmCtx *mpm_ctx) -{ - SCACPattern *p = SCMalloc(sizeof(SCACPattern)); - if (unlikely(p == NULL)) { - exit(EXIT_FAILURE); - } - memset(p, 0, sizeof(SCACPattern)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACPattern); - - return p; -} - -/** - * \internal - * \brief Used to free SCACPattern instances. - * - * \param mpm_ctx Pointer to the mpm context. - * \param p Pointer to the SCACPattern instance to be freed. - * \param free Free the above pointer or not. - */ -static inline void SCACFreePattern(MpmCtx *mpm_ctx, SCACPattern *p) -{ - if (p != NULL && p->cs != NULL && p->cs != p->ci) { - SCFree(p->cs); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->ci != NULL) { - SCFree(p->ci); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->original_pat != NULL) { - SCFree(p->original_pat); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->sids != NULL) { - SCFree(p->sids); - } - - if (p != NULL) { - SCFree(p); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACPattern); - } - return; -} - -static inline uint32_t SCACInitHash(SCACPattern *p) -{ - uint32_t hash = p->len * p->original_pat[0]; - if (p->len > 1) - hash += p->original_pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline int SCACInitHashAdd(SCACCtx *ctx, SCACPattern *p) -{ - uint32_t hash = SCACInitHash(p); - - if (ctx->init_hash == NULL) { - return 0; - } - - if (ctx->init_hash[hash] == NULL) { - ctx->init_hash[hash] = p; - return 0; - } - - SCACPattern *tt = NULL; - SCACPattern *t = ctx->init_hash[hash]; - - /* get the list tail */ - do { - tt = t; - t = t->next; - } while (t != NULL); - - tt->next = p; - - return 0; -} - -/** - * \internal - * \brief Add a pattern to the mpm-ac context. - * - * \param mpm_ctx Mpm context. - * \param pat Pointer to the pattern. - * \param patlen Length of the pattern. - * \param pid Pattern id - * \param sid Signature id (internal id). - * \param flags Pattern's MPM_PATTERN_* flags. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int SCACAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - - SCLogDebug("Adding pattern for ctx %p, patlen %"PRIu16" and pid %" PRIu32, - ctx, patlen, pid); - - if (patlen == 0) { - SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "pattern length 0"); - return 0; - } - - /* check if we have already inserted this pattern */ - SCACPattern *p = SCACInitHashLookup(ctx, pat, patlen, flags, pid); - if (p == NULL) { - SCLogDebug("Allocing new pattern"); - - /* p will never be NULL */ - p = SCACAllocPattern(mpm_ctx); - - p->len = patlen; - p->flags = flags; - p->id = pid; - - p->original_pat = SCMalloc(patlen); - if (p->original_pat == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->original_pat, pat, patlen); - - p->ci = SCMalloc(patlen); - if (p->ci == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy_tolower(p->ci, pat, patlen); - - /* setup the case sensitive part of the pattern */ - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - /* nocase means no difference between cs and ci */ - p->cs = p->ci; - } else { - if (memcmp(p->ci, pat, p->len) == 0) { - /* no diff between cs and ci: pat is lowercase */ - p->cs = p->ci; - } else { - p->cs = SCMalloc(patlen); - if (p->cs == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->cs, pat, patlen); - } - } - - /* put in the pattern hash */ - SCACInitHashAdd(ctx, p); - - //if (mpm_ctx->pattern_cnt == 65535) { - // SCLogError(SC_ERR_AHO_CORASICK, "Max search words reached. Can't " - // "insert anymore. Exiting"); - // exit(EXIT_FAILURE); - //} - mpm_ctx->pattern_cnt++; - - if (mpm_ctx->maxlen < patlen) - mpm_ctx->maxlen = patlen; - - if (mpm_ctx->minlen == 0) { - mpm_ctx->minlen = patlen; - } else { - if (mpm_ctx->minlen > patlen) - mpm_ctx->minlen = patlen; - } - - /* we need the max pat id */ - if (pid > ctx->max_pat_id) - ctx->max_pat_id = pid; - - p->sids_size = 1; - p->sids = SCMalloc(p->sids_size * sizeof(SigIntId)); - BUG_ON(p->sids == NULL); - p->sids[0] = sid; - //SCLogInfo("MPM added %u:%u", pid, sid); - } else { - /* TODO figure out how we can be called multiple times for the same CTX with the same sid */ - - int found = 0; - uint32_t x = 0; - for (x = 0; x < p->sids_size; x++) { - if (p->sids[x] == sid) { - found = 1; - break; - } - } - if (!found) { - SigIntId *sids = SCRealloc(p->sids, (sizeof(SigIntId) * (p->sids_size + 1))); - BUG_ON(sids == NULL); - p->sids = sids; - p->sids[p->sids_size] = sid; - p->sids_size++; - //SCLogInfo("p->sids_size %u", p->sids_size); - //SCLogInfo("MPM added %u:%u (append)", pid, sid); - } else { - //SCLogInfo("rule %u already part of pid %u", sid, pid); - } - } - - return 0; - -error: - SCACFreePattern(mpm_ctx, p); - return -1; -} - -/** - * \internal - * \brief Initialize a new state in the goto and output tables. - * - * \param mpm_ctx Pointer to the mpm context. - * - * \retval The state id, of the newly created state. - */ -static inline int SCACReallocState(SCACCtx *ctx, uint32_t cnt) -{ - void *ptmp; - int size = 0; - - /* reallocate space in the goto table to include a new state */ - size = cnt * ctx->single_state_size; - ptmp = SCRealloc(ctx->goto_table, size); - if (ptmp == NULL) { - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ctx->goto_table = ptmp; - - /* reallocate space in the output table for the new state */ - int oldsize = ctx->state_count * sizeof(SCACOutputTable); - size = cnt * sizeof(SCACOutputTable); - SCLogDebug("oldsize %d size %d cnt %u ctx->state_count %u", - oldsize, size, cnt, ctx->state_count); - - ptmp = SCRealloc(ctx->output_table, size); - if (ptmp == NULL) { - SCFree(ctx->output_table); - ctx->output_table = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ctx->output_table = ptmp; - - memset(((uint8_t *)ctx->output_table + oldsize), 0, (size - oldsize)); - - /* \todo using it temporarily now during dev, since I have restricted - * state var in SCACCtx->state_table to uint16_t. */ - //if (ctx->state_count > 65536) { - // printf("state count exceeded\n"); - // exit(EXIT_FAILURE); - //} - - return 0;//ctx->state_count++; -} - -/** \internal - * \brief Shrink state after setup is done - * - * Shrinks only the output table, goto table is freed after calling this - */ -static void SCACShrinkState(SCACCtx *ctx) -{ - /* reallocate space in the output table for the new state */ -#ifdef DEBUG - int oldsize = ctx->allocated_state_count * sizeof(SCACOutputTable); -#endif - int newsize = ctx->state_count * sizeof(SCACOutputTable); - - SCLogDebug("oldsize %d newsize %d ctx->allocated_state_count %u " - "ctx->state_count %u: shrink by %d bytes", oldsize, - newsize, ctx->allocated_state_count, ctx->state_count, - oldsize - newsize); - - void *ptmp = SCRealloc(ctx->output_table, newsize); - if (ptmp == NULL) { - SCFree(ctx->output_table); - ctx->output_table = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ctx->output_table = ptmp; -} - -static inline int SCACInitNewState(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx;; - - /* Exponentially increase the allocated space when needed. */ - if (ctx->allocated_state_count < ctx->state_count + 1) { - if (ctx->allocated_state_count == 0) - ctx->allocated_state_count = 256; - else - ctx->allocated_state_count *= 2; - - SCACReallocState(ctx, ctx->allocated_state_count); - - } -#if 0 - if (ctx->allocated_state_count > 260) { - SCACOutputTable *output_state = &ctx->output_table[260]; - SCLogInfo("output_state %p %p %u", output_state, output_state->pids, output_state->no_of_entries); - } -#endif - int ascii_code = 0; - /* set all transitions for the newly assigned state as FAIL transitions */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - ctx->goto_table[ctx->state_count][ascii_code] = SC_AC_FAIL; - } - - return ctx->state_count++; -} - -/** - * \internal - * \brief Adds a pid to the output table for a state. - * - * \param state The state to whose output table we should add the pid. - * \param pid The pattern id to add. - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACSetOutputState(int32_t state, uint32_t pid, MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - SCACOutputTable *output_state = &ctx->output_table[state]; - uint32_t i = 0; - - for (i = 0; i < output_state->no_of_entries; i++) { - if (output_state->pids[i] == pid) - return; - } - - output_state->no_of_entries++; - ptmp = SCRealloc(output_state->pids, - output_state->no_of_entries * sizeof(uint32_t)); - if (ptmp == NULL) { - SCFree(output_state->pids); - output_state->pids = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - output_state->pids = ptmp; - - output_state->pids[output_state->no_of_entries - 1] = pid; - - return; -} - -/** - * \brief Helper function used by SCACCreateGotoTable. Adds a pattern to the - * goto table. - * - * \param pattern Pointer to the pattern. - * \param pattern_len Pattern length. - * \param pid The pattern id, that corresponds to this pattern. We - * need it to updated the output table for this pattern. - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACEnter(uint8_t *pattern, uint16_t pattern_len, uint32_t pid, - MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - int32_t state = 0; - int32_t newstate = 0; - int i = 0; - int p = 0; - - /* walk down the trie till we have a match for the pattern prefix */ - state = 0; - for (i = 0; i < pattern_len; i++) { - if (ctx->goto_table[state][pattern[i]] != SC_AC_FAIL) { - state = ctx->goto_table[state][pattern[i]]; - } else { - break; - } - } - - /* add the non-matching pattern suffix to the trie, from the last state - * we left off */ - for (p = i; p < pattern_len; p++) { - newstate = SCACInitNewState(mpm_ctx); - ctx->goto_table[state][pattern[p]] = newstate; - state = newstate; - } - - /* add this pattern id, to the output table of the last state, where the - * pattern ends in the trie */ - SCACSetOutputState(state, pid, mpm_ctx); - - return; -} - -/** - * \internal - * \brief Create the goto table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACCreateGotoTable(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - uint32_t i = 0; - - /* add each pattern to create the goto table */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - SCACEnter(ctx->parray[i]->ci, ctx->parray[i]->len, - ctx->parray[i]->id, mpm_ctx); - } - - int ascii_code = 0; - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - if (ctx->goto_table[0][ascii_code] == SC_AC_FAIL) { - ctx->goto_table[0][ascii_code] = 0; - } - } - - return; -} - -static inline void SCACDetermineLevel1Gap(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - uint32_t u = 0; - - int map[256]; - memset(map, 0, sizeof(map)); - - for (u = 0; u < mpm_ctx->pattern_cnt; u++) - map[ctx->parray[u]->ci[0]] = 1; - - for (u = 0; u < 256; u++) { - if (map[u] == 0) - continue; - int32_t newstate = SCACInitNewState(mpm_ctx); - ctx->goto_table[0][u] = newstate; - } - - return; -} - -static inline int SCACStateQueueIsEmpty(StateQueue *q) -{ - if (q->top == q->bot) - return 1; - else - return 0; -} - -static inline void SCACEnqueue(StateQueue *q, int32_t state) -{ - int i = 0; - - /*if we already have this */ - for (i = q->bot; i < q->top; i++) { - if (q->store[i] == state) - return; - } - - q->store[q->top++] = state; - - if (q->top == STATE_QUEUE_CONTAINER_SIZE) - q->top = 0; - - if (q->top == q->bot) { - SCLogCritical(SC_ERR_AHO_CORASICK, "Just ran out of space in the queue. " - "Fatal Error. Exiting. Please file a bug report on this"); - exit(EXIT_FAILURE); - } - - return; -} - -static inline int32_t SCACDequeue(StateQueue *q) -{ - if (q->bot == STATE_QUEUE_CONTAINER_SIZE) - q->bot = 0; - - if (q->bot == q->top) { - SCLogCritical(SC_ERR_AHO_CORASICK, "StateQueue behaving weirdly. " - "Fatal Error. Exiting. Please file a bug report on this"); - exit(EXIT_FAILURE); - } - - return q->store[q->bot++]; -} - -/* -#define SCACStateQueueIsEmpty(q) (((q)->top == (q)->bot) ? 1 : 0) - -#define SCACEnqueue(q, state) do { \ - int i = 0; \ - \ - for (i = (q)->bot; i < (q)->top; i++) { \ - if ((q)->store[i] == state) \ - return; \ - } \ - \ - (q)->store[(q)->top++] = state; \ - \ - if ((q)->top == STATE_QUEUE_CONTAINER_SIZE) \ - (q)->top = 0; \ - \ - if ((q)->top == (q)->bot) { \ - SCLogCritical(SC_ERR_AHO_CORASICK, "Just ran out of space in the queue. " \ - "Fatal Error. Exiting. Please file a bug report on this"); \ - exit(EXIT_FAILURE); \ - } \ - } while (0) - -#define SCACDequeue(q) ( (((q)->bot == STATE_QUEUE_CONTAINER_SIZE)? ((q)->bot = 0): 0), \ - (((q)->bot == (q)->top) ? \ - (printf("StateQueue behaving " \ - "weirdly. Fatal Error. Exiting. Please " \ - "file a bug report on this"), \ - exit(EXIT_FAILURE)) : 0), \ - (q)->store[(q)->bot++]) \ -*/ - -/** - * \internal - * \brief Club the output data from 2 states and store it in the 1st state. - * dst_state_data = {dst_state_data} UNION {src_state_data} - * - * \param dst_state First state(also the destination) for the union operation. - * \param src_state Second state for the union operation. - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACClubOutputStates(int32_t dst_state, int32_t src_state, - MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - uint32_t i = 0; - uint32_t j = 0; - - SCACOutputTable *output_dst_state = &ctx->output_table[dst_state]; - SCACOutputTable *output_src_state = &ctx->output_table[src_state]; - - for (i = 0; i < output_src_state->no_of_entries; i++) { - for (j = 0; j < output_dst_state->no_of_entries; j++) { - if (output_src_state->pids[i] == output_dst_state->pids[j]) { - break; - } - } - if (j == output_dst_state->no_of_entries) { - output_dst_state->no_of_entries++; - - ptmp = SCRealloc(output_dst_state->pids, - (output_dst_state->no_of_entries * sizeof(uint32_t))); - if (ptmp == NULL) { - SCFree(output_dst_state->pids); - output_dst_state->pids = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - output_dst_state->pids = ptmp; - - output_dst_state->pids[output_dst_state->no_of_entries - 1] = - output_src_state->pids[i]; - } - } - - return; -} - -/** - * \internal - * \brief Create the failure table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACCreateFailureTable(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int32_t state = 0; - int32_t r_state = 0; - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - /* allot space for the failure table. A failure entry in the table for - * every state(SCACCtx->state_count) */ - ctx->failure_table = SCMalloc(ctx->state_count * sizeof(int32_t)); - if (ctx->failure_table == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->failure_table, 0, ctx->state_count * sizeof(int32_t)); - - /* add the failure transitions for the 0th state, and add every non-fail - * transition from the 0th state to the queue for further processing - * of failure states */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[0][ascii_code]; - if (temp_state != 0) { - SCACEnqueue(&q, temp_state); - ctx->failure_table[temp_state] = 0; - } - } - - while (!SCACStateQueueIsEmpty(&q)) { - /* pick up every state from the queue and add failure transitions */ - r_state = SCACDequeue(&q); - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state == SC_AC_FAIL) - continue; - SCACEnqueue(&q, temp_state); - state = ctx->failure_table[r_state]; - - while(ctx->goto_table[state][ascii_code] == SC_AC_FAIL) - state = ctx->failure_table[state]; - ctx->failure_table[temp_state] = ctx->goto_table[state][ascii_code]; - SCACClubOutputStates(temp_state, ctx->failure_table[temp_state], - mpm_ctx); - } - } - - return; -} - -/** - * \internal - * \brief Create the delta table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACCreateDeltaTable(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int32_t r_state = 0; - - if ((ctx->state_count < 32767) || construct_both_16_and_32_state_tables) { - ctx->state_table_u16 = SCMalloc(ctx->state_count * - sizeof(SC_AC_STATE_TYPE_U16) * 256); - if (ctx->state_table_u16 == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->state_table_u16, 0, - ctx->state_count * sizeof(SC_AC_STATE_TYPE_U16) * 256); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (ctx->state_count * - sizeof(SC_AC_STATE_TYPE_U16) * 256); - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - SC_AC_STATE_TYPE_U16 temp_state = ctx->goto_table[0][ascii_code]; - ctx->state_table_u16[0][ascii_code] = temp_state; - if (temp_state != 0) - SCACEnqueue(&q, temp_state); - } - - while (!SCACStateQueueIsEmpty(&q)) { - r_state = SCACDequeue(&q); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state != SC_AC_FAIL) { - SCACEnqueue(&q, temp_state); - ctx->state_table_u16[r_state][ascii_code] = temp_state; - } else { - ctx->state_table_u16[r_state][ascii_code] = - ctx->state_table_u16[ctx->failure_table[r_state]][ascii_code]; - } - } - } - } - - if (!(ctx->state_count < 32767) || construct_both_16_and_32_state_tables) { - /* create space for the state table. We could have used the existing goto - * table, but since we have it set to hold 32 bit state values, we will create - * a new state table here of type SC_AC_STATE_TYPE(current set to uint16_t) */ - ctx->state_table_u32 = SCMalloc(ctx->state_count * - sizeof(SC_AC_STATE_TYPE_U32) * 256); - if (ctx->state_table_u32 == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->state_table_u32, 0, - ctx->state_count * sizeof(SC_AC_STATE_TYPE_U32) * 256); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (ctx->state_count * - sizeof(SC_AC_STATE_TYPE_U32) * 256); - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - SC_AC_STATE_TYPE_U32 temp_state = ctx->goto_table[0][ascii_code]; - ctx->state_table_u32[0][ascii_code] = temp_state; - if (temp_state != 0) - SCACEnqueue(&q, temp_state); - } - - while (!SCACStateQueueIsEmpty(&q)) { - r_state = SCACDequeue(&q); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state != SC_AC_FAIL) { - SCACEnqueue(&q, temp_state); - ctx->state_table_u32[r_state][ascii_code] = temp_state; - } else { - ctx->state_table_u32[r_state][ascii_code] = - ctx->state_table_u32[ctx->failure_table[r_state]][ascii_code]; - } - } - } - } - - return; -} - -static inline void SCACClubOutputStatePresenceWithDeltaTable(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - int ascii_code = 0; - uint32_t state = 0; - uint32_t temp_state = 0; - - if ((ctx->state_count < 32767) || construct_both_16_and_32_state_tables) { - for (state = 0; state < ctx->state_count; state++) { - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - temp_state = ctx->state_table_u16[state & 0x7FFF][ascii_code]; - if (ctx->output_table[temp_state & 0x7FFF].no_of_entries != 0) - ctx->state_table_u16[state & 0x7FFF][ascii_code] |= (1 << 15); - } - } - } - - if (!(ctx->state_count < 32767) || construct_both_16_and_32_state_tables) { - for (state = 0; state < ctx->state_count; state++) { - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - temp_state = ctx->state_table_u32[state & 0x00FFFFFF][ascii_code]; - if (ctx->output_table[temp_state & 0x00FFFFFF].no_of_entries != 0) - ctx->state_table_u32[state & 0x00FFFFFF][ascii_code] |= (1 << 24); - } - } - } - - return; -} - -static inline void SCACInsertCaseSensitiveEntriesForPatterns(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - uint32_t state = 0; - uint32_t k = 0; - - for (state = 0; state < ctx->state_count; state++) { - if (ctx->output_table[state].no_of_entries == 0) - continue; - - for (k = 0; k < ctx->output_table[state].no_of_entries; k++) { - if (ctx->pid_pat_list[ctx->output_table[state].pids[k]].cs != NULL) { - ctx->output_table[state].pids[k] &= 0x0000FFFF; - ctx->output_table[state].pids[k] |= 1 << 16; - } - } - } - - return; -} - -#if 0 -static void SCACPrintDeltaTable(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - int i = 0, j = 0; - - printf("##############Delta Table##############\n"); - for (i = 0; i < ctx->state_count; i++) { - printf("%d: \n", i); - for (j = 0; j < 256; j++) { - if (SCACGetDelta(i, j, mpm_ctx) != 0) { - printf(" %c -> %d\n", j, SCACGetDelta(i, j, mpm_ctx)); - } - } - } - - return; -} -#endif - -/** - * \brief Process the patterns and prepare the state table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACPrepareStateTable(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - - /* create the 0th state in the goto table and output_table */ - SCACInitNewState(mpm_ctx); - - SCACDetermineLevel1Gap(mpm_ctx); - - /* create the goto table */ - SCACCreateGotoTable(mpm_ctx); - /* create the failure table */ - SCACCreateFailureTable(mpm_ctx); - /* create the final state(delta) table */ - SCACCreateDeltaTable(mpm_ctx); - /* club the output state presence with delta transition entries */ - SCACClubOutputStatePresenceWithDeltaTable(mpm_ctx); - - /* club nocase entries */ - SCACInsertCaseSensitiveEntriesForPatterns(mpm_ctx); - - /* shrink the memory */ - SCACShrinkState(ctx); - -#if 0 - SCACPrintDeltaTable(mpm_ctx); -#endif - - /* we don't need these anymore */ - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - SCFree(ctx->failure_table); - ctx->failure_table = NULL; - - return; -} - -/** - * \brief Process the patterns added to the mpm, and create the internal tables. - * - * \param mpm_ctx Pointer to the mpm context. - */ -int SCACPreparePatterns(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - - if (mpm_ctx->pattern_cnt == 0 || ctx->init_hash == NULL) { - SCLogDebug("no patterns supplied to this mpm_ctx"); - return 0; - } - - /* alloc the pattern array */ - ctx->parray = (SCACPattern **)SCMalloc(mpm_ctx->pattern_cnt * - sizeof(SCACPattern *)); - if (ctx->parray == NULL) - goto error; - memset(ctx->parray, 0, mpm_ctx->pattern_cnt * sizeof(SCACPattern *)); - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (mpm_ctx->pattern_cnt * sizeof(SCACPattern *)); - - /* populate it with the patterns in the hash */ - uint32_t i = 0, p = 0; - for (i = 0; i < INIT_HASH_SIZE; i++) { - SCACPattern *node = ctx->init_hash[i], *nnode = NULL; - while(node != NULL) { - nnode = node->next; - node->next = NULL; - ctx->parray[p++] = node; - node = nnode; - } - } - - /* we no longer need the hash, so free it's memory */ - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - - /* the memory consumed by a single state in our goto table */ - ctx->single_state_size = sizeof(int32_t) * 256; - - /* handle no case patterns */ - ctx->pid_pat_list = SCMalloc((ctx->max_pat_id + 1)* sizeof(SCACPatternList)); - if (ctx->pid_pat_list == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(ctx->pid_pat_list, 0, (ctx->max_pat_id + 1) * sizeof(SCACPatternList)); - - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (!(ctx->parray[i]->flags & MPM_PATTERN_FLAG_NOCASE)) { - ctx->pid_pat_list[ctx->parray[i]->id].cs = SCMalloc(ctx->parray[i]->len); - if (ctx->pid_pat_list[ctx->parray[i]->id].cs == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memcpy(ctx->pid_pat_list[ctx->parray[i]->id].cs, - ctx->parray[i]->original_pat, ctx->parray[i]->len); - ctx->pid_pat_list[ctx->parray[i]->id].patlen = ctx->parray[i]->len; - } - - /* ACPatternList now owns this memory */ - //SCLogInfo("ctx->parray[i]->sids_size %u", ctx->parray[i]->sids_size); - ctx->pid_pat_list[ctx->parray[i]->id].sids_size = ctx->parray[i]->sids_size; - ctx->pid_pat_list[ctx->parray[i]->id].sids = ctx->parray[i]->sids; - - ctx->parray[i]->sids_size = 0; - ctx->parray[i]->sids = NULL; - } - - /* prepare the state table required by AC */ - SCACPrepareStateTable(mpm_ctx); - -#ifdef __SC_CUDA_SUPPORT__ - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - int r = SCCudaMemAlloc(&ctx->state_table_u32_cuda, - ctx->state_count * sizeof(unsigned int) * 256); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemAlloc failure."); - exit(EXIT_FAILURE); - } - - r = SCCudaMemcpyHtoD(ctx->state_table_u32_cuda, - ctx->state_table_u32, - ctx->state_count * sizeof(unsigned int) * 256); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemcpyHtoD failure."); - exit(EXIT_FAILURE); - } - } -#endif - - /* free all the stored patterns. Should save us a good 100-200 mbs */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - SCACFreePattern(mpm_ctx, ctx->parray[i]); - } - } - SCFree(ctx->parray); - ctx->parray = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(SCACPattern *)); - - return 0; - -error: - return -1; -} - -/** - * \brief Init the mpm thread context. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - * \param matchsize We don't need this. - */ -void SCACInitThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, uint32_t matchsize) -{ - memset(mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - - mpm_thread_ctx->ctx = SCMalloc(sizeof(SCACThreadCtx)); - if (mpm_thread_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - memset(mpm_thread_ctx->ctx, 0, sizeof(SCACThreadCtx)); - mpm_thread_ctx->memory_cnt++; - mpm_thread_ctx->memory_size += sizeof(SCACThreadCtx); - - return; -} - -/** - * \brief Initialize the AC context. - * - * \param mpm_ctx Mpm context. - */ -void SCACInitCtx(MpmCtx *mpm_ctx) -{ - if (mpm_ctx->ctx != NULL) - return; - - mpm_ctx->ctx = SCMalloc(sizeof(SCACCtx)); - if (mpm_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - memset(mpm_ctx->ctx, 0, sizeof(SCACCtx)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACCtx); - - /* initialize the hash we use to speed up pattern insertions */ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - ctx->init_hash = SCMalloc(sizeof(SCACPattern *) * INIT_HASH_SIZE); - if (ctx->init_hash == NULL) { - exit(EXIT_FAILURE); - } - memset(ctx->init_hash, 0, sizeof(SCACPattern *) * INIT_HASH_SIZE); - - /* get conf values for AC from our yaml file. We have no conf values for - * now. We will certainly need this, as we develop the algo */ - SCACGetConfig(); - - SCReturn; -} - -/** - * \brief Destroy the mpm thread context. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - */ -void SCACDestroyThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx) -{ - SCACPrintSearchStats(mpm_thread_ctx); - - if (mpm_thread_ctx->ctx != NULL) { - SCFree(mpm_thread_ctx->ctx); - mpm_thread_ctx->ctx = NULL; - mpm_thread_ctx->memory_cnt--; - mpm_thread_ctx->memory_size -= sizeof(SCACThreadCtx); - } - - return; -} - -/** - * \brief Destroy the mpm context. - * - * \param mpm_ctx Pointer to the mpm context. - */ -void SCACDestroyCtx(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx == NULL) - return; - - if (ctx->init_hash != NULL) { - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (INIT_HASH_SIZE * sizeof(SCACPattern *)); - } - - if (ctx->parray != NULL) { - uint32_t i; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - SCACFreePattern(mpm_ctx, ctx->parray[i]); - } - } - - SCFree(ctx->parray); - ctx->parray = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(SCACPattern *)); - } - - if (ctx->state_table_u16 != NULL) { - SCFree(ctx->state_table_u16); - ctx->state_table_u16 = NULL; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size -= (ctx->state_count * - sizeof(SC_AC_STATE_TYPE_U16) * 256); - } - if (ctx->state_table_u32 != NULL) { - SCFree(ctx->state_table_u32); - ctx->state_table_u32 = NULL; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size -= (ctx->state_count * - sizeof(SC_AC_STATE_TYPE_U32) * 256); - } - - if (ctx->output_table != NULL) { - uint32_t state_count; - for (state_count = 0; state_count < ctx->state_count; state_count++) { - if (ctx->output_table[state_count].pids != NULL) { - SCFree(ctx->output_table[state_count].pids); - } - } - SCFree(ctx->output_table); - } - - if (ctx->pid_pat_list != NULL) { - int i; - for (i = 0; i < (ctx->max_pat_id + 1); i++) { - if (ctx->pid_pat_list[i].cs != NULL) - SCFree(ctx->pid_pat_list[i].cs); - if (ctx->pid_pat_list[i].sids != NULL) - SCFree(ctx->pid_pat_list[i].sids); - } - SCFree(ctx->pid_pat_list); - } - - SCFree(mpm_ctx->ctx); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACCtx); - - return; -} - -/** - * \brief The aho corasick search function. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - * \param pmq Pointer to the Pattern Matcher Queue to hold - * search matches. - * \param buf Buffer to be searched. - * \param buflen Buffer length. - * - * \retval matches Match count. - */ -uint32_t SCACSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - int i = 0; - int matches = 0; - - /* \todo tried loop unrolling with register var, with no perf increase. Need - * to dig deeper */ - /* \todo Change it for stateful MPM. Supply the state using mpm_thread_ctx */ - SCACPatternList *pid_pat_list = ctx->pid_pat_list; - - uint8_t bitarray[pmq->pattern_id_bitarray_size]; - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - - if (ctx->state_count < 32767) { - register SC_AC_STATE_TYPE_U16 state = 0; - SC_AC_STATE_TYPE_U16 (*state_table_u16)[256] = ctx->state_table_u16; - for (i = 0; i < buflen; i++) { - state = state_table_u16[state & 0x7FFF][u8_tolower(buf[i])]; - if (state & 0x8000) { - uint32_t no_of_entries = ctx->output_table[state & 0x7FFF].no_of_entries; - uint32_t *pids = ctx->output_table[state & 0x7FFF].pids; - uint32_t k; - for (k = 0; k < no_of_entries; k++) { - if (pids[k] & 0xFFFF0000) { - uint32_t lower_pid = pids[k] & 0x0000FFFF; - if (SCMemcmp(pid_pat_list[lower_pid].cs, - buf + i - pid_pat_list[lower_pid].patlen + 1, - pid_pat_list[lower_pid].patlen) != 0) { - /* inside loop */ - continue; - } - if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { - ; - } else { - pmq->pattern_id_bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - MpmAddPid(pmq, lower_pid); - MpmAddSids(pmq, pid_pat_list[lower_pid].sids, pid_pat_list[lower_pid].sids_size); - } - matches++; - } else { - if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { - ; - } else { - pmq->pattern_id_bitarray[(pids[k]) / 8] |= (1 << ((pids[k]) % 8)); - bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - MpmAddPid(pmq, pids[k]); - MpmAddSids(pmq, pid_pat_list[pids[k]].sids, pid_pat_list[pids[k]].sids_size); - } - matches++; - } - //loop1: - //; - } - } - } /* for (i = 0; i < buflen; i++) */ - - } else { - register SC_AC_STATE_TYPE_U32 state = 0; - SC_AC_STATE_TYPE_U32 (*state_table_u32)[256] = ctx->state_table_u32; - for (i = 0; i < buflen; i++) { - state = state_table_u32[state & 0x00FFFFFF][u8_tolower(buf[i])]; - if (state & 0xFF000000) { - uint32_t no_of_entries = ctx->output_table[state & 0x00FFFFFF].no_of_entries; - uint32_t *pids = ctx->output_table[state & 0x00FFFFFF].pids; - uint32_t k; - for (k = 0; k < no_of_entries; k++) { - if (pids[k] & 0xFFFF0000) { - uint32_t lower_pid = pids[k] & 0x0000FFFF; - if (SCMemcmp(pid_pat_list[lower_pid].cs, - buf + i - pid_pat_list[lower_pid].patlen + 1, - pid_pat_list[lower_pid].patlen) != 0) { - /* inside loop */ - continue; - } - if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { - ; - } else { - pmq->pattern_id_bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - MpmAddPid(pmq, lower_pid); - MpmAddSids(pmq, pid_pat_list[lower_pid].sids, pid_pat_list[lower_pid].sids_size); - } - matches++; - } else { - if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { - ; - } else { - pmq->pattern_id_bitarray[(pids[k]) / 8] |= (1 << ((pids[k]) % 8)); - bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - MpmAddPid(pmq, pids[k]); - MpmAddSids(pmq, pid_pat_list[pids[k]].sids, pid_pat_list[pids[k]].sids_size); - } - matches++; - } - //loop1: - //; - } - } - } /* for (i = 0; i < buflen; i++) */ - } - - return matches; -} - -/** - * \brief Add a case insensitive pattern. Although we have different calls for - * adding case sensitive and insensitive patterns, we make a single call - * for either case. No special treatment for either case. - * - * \param mpm_ctx Pointer to the mpm context. - * \param pat The pattern to add. - * \param patnen The pattern length. - * \param offset Ignored. - * \param depth Ignored. - * \param pid The pattern id. - * \param sid Ignored. - * \param flags Flags associated with this pattern. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCACAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - flags |= MPM_PATTERN_FLAG_NOCASE; - return SCACAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -/** - * \brief Add a case sensitive pattern. Although we have different calls for - * adding case sensitive and insensitive patterns, we make a single call - * for either case. No special treatment for either case. - * - * \param mpm_ctx Pointer to the mpm context. - * \param pat The pattern to add. - * \param patnen The pattern length. - * \param offset Ignored. - * \param depth Ignored. - * \param pid The pattern id. - * \param sid Ignored. - * \param flags Flags associated with this pattern. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCACAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - return SCACAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -void SCACPrintSearchStats(MpmThreadCtx *mpm_thread_ctx) -{ - -#ifdef SC_AC_COUNTERS - SCACThreadCtx *ctx = (SCACThreadCtx *)mpm_thread_ctx->ctx; - printf("AC Thread Search stats (ctx %p)\n", ctx); - printf("Total calls: %" PRIu32 "\n", ctx->total_calls); - printf("Total matches: %" PRIu64 "\n", ctx->total_matches); -#endif /* SC_AC_COUNTERS */ - - return; -} - -void SCACPrintInfo(MpmCtx *mpm_ctx) -{ - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - - printf("MPM AC Information:\n"); - printf("Memory allocs: %" PRIu32 "\n", mpm_ctx->memory_cnt); - printf("Memory alloced: %" PRIu32 "\n", mpm_ctx->memory_size); - printf(" Sizeof:\n"); - printf(" MpmCtx %" PRIuMAX "\n", (uintmax_t)sizeof(MpmCtx)); - printf(" SCACCtx: %" PRIuMAX "\n", (uintmax_t)sizeof(SCACCtx)); - printf(" SCACPattern %" PRIuMAX "\n", (uintmax_t)sizeof(SCACPattern)); - printf(" SCACPattern %" PRIuMAX "\n", (uintmax_t)sizeof(SCACPattern)); - printf("Unique Patterns: %" PRIu32 "\n", mpm_ctx->pattern_cnt); - printf("Smallest: %" PRIu32 "\n", mpm_ctx->minlen); - printf("Largest: %" PRIu32 "\n", mpm_ctx->maxlen); - printf("Total states in the state table: %" PRIu32 "\n", ctx->state_count); - printf("\n"); - - return; -} - -/****************************Cuda side of things****************************/ - -#ifdef __SC_CUDA_SUPPORT__ - -/* \todo Technically it's generic to all mpms, but since we use ac only, the - * code internally directly references ac and hence it has found its - * home in this file, instead of util-mpm.c - */ -void DetermineCudaStateTableSize(DetectEngineCtx *de_ctx) -{ - MpmCtx *mpm_ctx = NULL; - - int ac_16_tables = 0; - int ac_32_tables = 0; - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_other_packet, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_uri, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_uri, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcbd, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcbd, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhd, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhd, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhd, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhd, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hmd, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hmd, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcd, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcd, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrud, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrud, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsmd, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsmd, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hscd, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hscd, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_huad, 0); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_huad, 1); - if (mpm_ctx->mpm_type == MPM_AC_CUDA) { - SCACCtx *ctx = (SCACCtx *)mpm_ctx->ctx; - if (ctx->state_count < 32767) - ac_16_tables++; - else - ac_32_tables++; - } - - if (ac_16_tables > 0 && ac_32_tables > 0) - SCACConstructBoth16and32StateTables(); - - - SCLogDebug("Total mpm ac 16 bit state tables - %d\n", ac_16_tables); - SCLogDebug("Total mpm ac 32 bit state tables - %d\n", ac_32_tables); - -} - -void CudaReleasePacket(Packet *p) -{ - if (p->cuda_pkt_vars.cuda_mpm_enabled == 1) { - p->cuda_pkt_vars.cuda_mpm_enabled = 0; - SCMutexLock(&p->cuda_pkt_vars.cuda_mutex); - p->cuda_pkt_vars.cuda_done = 0; - SCMutexUnlock(&p->cuda_pkt_vars.cuda_mutex); - } - - return; -} - -/* \todos - * - Use texture memory - Can we fit all the arrays into a 3d texture. - * Texture memory definitely offers slightly better performance even - * on gpus that offer cache for global memory. - * - Packetpool - modify to support > 65k max pending packets. We are - * hitting packetpool limit currently even with 65k packets. - * - Use streams. We have tried overlapping parsing results from the - * previous call with invoking the next call. - * - Offer higher priority to decode threads. - * - Modify pcap file mode to support reading from multiple pcap files - * and hence we will have multiple receive threads. - * - Split state table into many small pieces and have multiple threads - * run each small state table on the same payload. - * - Used a config peference of l1 over shared memory with no noticeable - * perf increase. Explore it in detail over cards/architectures. - * - Constant memory performance sucked. Explore it in detail. - * - Currently all our state tables are small. Implement 16 bit state - * tables on priority. - * - Introduce profiling. - * - Retrieve sgh before buffer packet. - * - Buffer smsgs too. - */ - -void SCACConstructBoth16and32StateTables(void) -{ - construct_both_16_and_32_state_tables = 1; - - return; -} - -/* \todo Reduce offset buffer size. Probably a 100,000 entry would be sufficient. */ -static void *SCACCudaDispatcher(void *arg) -{ -#define BLOCK_SIZE 32 - - int r = 0; - ThreadVars *tv = (ThreadVars *)arg; - MpmCudaConf *conf = CudaHandlerGetCudaProfile("mpm"); - uint32_t sleep_interval_ms = conf->batching_timeout; - - SCLogInfo("AC Cuda Mpm Dispatcher using a timeout of " - "\"%"PRIu32"\" micro-seconds", sleep_interval_ms); - - CudaBufferData *cb_data = - CudaHandlerModuleGetData(MPM_AC_CUDA_MODULE_NAME, - MPM_AC_CUDA_MODULE_CUDA_BUFFER_NAME); - - CUcontext cuda_context = - CudaHandlerModuleGetContext(MPM_AC_CUDA_MODULE_NAME, conf->device_id); - if (cuda_context == 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "context is NULL."); - exit(EXIT_FAILURE); - } - r = SCCudaCtxPushCurrent(cuda_context); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "context push failed."); - exit(EXIT_FAILURE); - } - CUmodule cuda_module = 0; - if (CudaHandlerGetCudaModule(&cuda_module, "util-mpm-ac-cuda-kernel") < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error retrieving cuda module."); - exit(EXIT_FAILURE); - } - CUfunction kernel = 0; -#if __WORDSIZE==64 - if (SCCudaModuleGetFunction(&kernel, cuda_module, "SCACCudaSearch64") == -1) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error retrieving kernel"); - exit(EXIT_FAILURE); - } -#else - if (SCCudaModuleGetFunction(&kernel, cuda_module, "SCACCudaSearch32") == -1) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error retrieving kernel"); - exit(EXIT_FAILURE); - } -#endif - - uint8_t g_u8_lowercasetable[256]; - for (int c = 0; c < 256; c++) - g_u8_lowercasetable[c] = tolower((uint8_t)c); - CUdeviceptr cuda_g_u8_lowercasetable_d = 0; - CUdeviceptr cuda_packets_buffer_d = 0; - CUdeviceptr cuda_offset_buffer_d = 0; - CUdeviceptr cuda_results_buffer_d = 0; - uint32_t *cuda_results_buffer_h = NULL; - r = SCCudaMemAlloc(&cuda_g_u8_lowercasetable_d, sizeof(g_u8_lowercasetable)); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemAlloc failure."); - exit(EXIT_FAILURE); - } - r = SCCudaMemcpyHtoD(cuda_g_u8_lowercasetable_d, g_u8_lowercasetable, sizeof(g_u8_lowercasetable)); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemcpyHtoD failure."); - exit(EXIT_FAILURE); - } - r = SCCudaMemAlloc(&cuda_packets_buffer_d, conf->gpu_transfer_size); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemAlloc failure."); - exit(EXIT_FAILURE); - } - r = SCCudaMemAlloc(&cuda_offset_buffer_d, conf->gpu_transfer_size * 4); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemAlloc failure."); - exit(EXIT_FAILURE); - } - r = SCCudaMemAlloc(&cuda_results_buffer_d, conf->gpu_transfer_size * 8); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemAlloc failure."); - exit(EXIT_FAILURE); - } - r = SCCudaMemAllocHost((void **)&cuda_results_buffer_h, conf->gpu_transfer_size * 8); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemAlloc failure."); - exit(EXIT_FAILURE); - } - - CudaBufferCulledInfo cb_culled_info; - memset(&cb_culled_info, 0, sizeof(cb_culled_info)); - - TmThreadsSetFlag(tv, THV_INIT_DONE); - while (1) { - if (TmThreadsCheckFlag(tv, THV_KILL)) - break; - - usleep(sleep_interval_ms); - - /**************** 1 SEND ****************/ - CudaBufferCullCompletedSlices(cb_data, &cb_culled_info, conf->gpu_transfer_size); - if (cb_culled_info.no_of_items == 0) - continue; -#if 0 - SCLogInfo("1 - cb_culled_info.no_of_items-%"PRIu32" " - "cb_culled_info.buffer_len - %"PRIu32" " - "cb_culled_info.average size - %f " - "cb_culled_info.d_buffer_start_offset - %"PRIu32" " - "cb_culled_info.op_buffer_start_offset - %"PRIu32" " - "cb_data.no_of_items - %"PRIu32" " - "cb_data.d_buffer_read - %"PRIu32" " - "cb_data.d_buffer_write - %"PRIu32" " - "cb_data.op_buffer_read - %"PRIu32" " - "cb_data.op_buffer_write - %"PRIu32"\n", - cb_culled_info.no_of_items, - cb_culled_info.d_buffer_len, - cb_culled_info.d_buffer_len / (float)cb_culled_info.no_of_items, - cb_culled_info.d_buffer_start_offset, - cb_culled_info.op_buffer_start_offset, - cb_data->no_of_items, - cb_data->d_buffer_read, - cb_data->d_buffer_write, - cb_data->op_buffer_read, - cb_data->op_buffer_write); -#endif - r = SCCudaMemcpyHtoDAsync(cuda_packets_buffer_d, (cb_data->d_buffer + cb_culled_info.d_buffer_start_offset), cb_culled_info.d_buffer_len, 0); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemcpyHtoD failure."); - exit(EXIT_FAILURE); - } - r = SCCudaMemcpyHtoDAsync(cuda_offset_buffer_d, (cb_data->o_buffer + cb_culled_info.op_buffer_start_offset), sizeof(uint32_t) * cb_culled_info.no_of_items, 0); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemcpyHtoD failure."); - exit(EXIT_FAILURE); - } - void *args[] = { &cuda_packets_buffer_d, - &cb_culled_info.d_buffer_start_offset, - &cuda_offset_buffer_d, - &cuda_results_buffer_d, - &cb_culled_info.no_of_items, - &cuda_g_u8_lowercasetable_d }; - r = SCCudaLaunchKernel(kernel, - (cb_culled_info.no_of_items / BLOCK_SIZE) + 1, 1, 1, - BLOCK_SIZE, 1, 1, - 0, 0, - args, NULL); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaLaunchKernel failure."); - exit(EXIT_FAILURE); - } - r = SCCudaMemcpyDtoHAsync(cuda_results_buffer_h, cuda_results_buffer_d, sizeof(uint32_t) * (cb_culled_info.d_buffer_len * 2), 0); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaMemcpyDtoH failure."); - exit(EXIT_FAILURE); - } - - - - /**************** 1 SYNCHRO ****************/ - r = SCCudaCtxSynchronize(); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "SCCudaCtxSynchronize failure."); - exit(EXIT_FAILURE); - } - - /************* 1 Parse Results ************/ - uint32_t i_op_start_offset = cb_culled_info.op_buffer_start_offset; - uint32_t no_of_items = cb_culled_info.no_of_items; - uint32_t *o_buffer = cb_data->o_buffer; - uint32_t d_buffer_start_offset = cb_culled_info.d_buffer_start_offset; - for (uint32_t i = 0; i < no_of_items; i++, i_op_start_offset++) { - Packet *p = (Packet *)cb_data->p_buffer[i_op_start_offset]; - - SCMutexLock(&p->cuda_pkt_vars.cuda_mutex); - if (p->cuda_pkt_vars.cuda_mpm_enabled == 0) { - p->cuda_pkt_vars.cuda_done = 0; - SCMutexUnlock(&p->cuda_pkt_vars.cuda_mutex); - continue; - } - - p->cuda_pkt_vars.cuda_gpu_matches = - cuda_results_buffer_h[((o_buffer[i_op_start_offset] - d_buffer_start_offset) * 2)]; - if (p->cuda_pkt_vars.cuda_gpu_matches != 0) { - memcpy(p->cuda_pkt_vars.cuda_results, - cuda_results_buffer_h + - ((o_buffer[i_op_start_offset] - d_buffer_start_offset) * 2), - (cuda_results_buffer_h[((o_buffer[i_op_start_offset] - - d_buffer_start_offset) * 2)] * sizeof(uint32_t)) + 4); - } - - p->cuda_pkt_vars.cuda_done = 1; - SCMutexUnlock(&p->cuda_pkt_vars.cuda_mutex); - SCCondSignal(&p->cuda_pkt_vars.cuda_cond); - } - if (no_of_items != 0) - CudaBufferReportCulledConsumption(cb_data, &cb_culled_info); - } /* while (1) */ - - r = SCCudaModuleUnload(cuda_module); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error unloading cuda module."); - exit(EXIT_FAILURE); - } - r = SCCudaMemFree(cuda_packets_buffer_d); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error freeing cuda device memory."); - exit(EXIT_FAILURE); - } - r = SCCudaMemFree(cuda_offset_buffer_d); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error freeing cuda device memory."); - exit(EXIT_FAILURE); - } - r = SCCudaMemFree(cuda_results_buffer_d); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error freeing cuda device memory."); - exit(EXIT_FAILURE); - } - r = SCCudaMemFreeHost(cuda_results_buffer_h); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error freeing cuda host memory."); - exit(EXIT_FAILURE); - } - - TmThreadsSetFlag(tv, THV_RUNNING_DONE); - TmThreadWaitForFlag(tv, THV_DEINIT); - TmThreadsSetFlag(tv, THV_CLOSED); - - return NULL; - -#undef BLOCK_SIZE -} - -uint32_t SCACCudaPacketResultsProcessing(Packet *p, MpmCtx *mpm_ctx, - PatternMatcherQueue *pmq) -{ - uint32_t u = 0; - - while (!p->cuda_pkt_vars.cuda_done) { - SCMutexLock(&p->cuda_pkt_vars.cuda_mutex); - if (p->cuda_pkt_vars.cuda_done) { - SCMutexUnlock(&p->cuda_pkt_vars.cuda_mutex); - break; - } else { - SCCondWait(&p->cuda_pkt_vars.cuda_cond, &p->cuda_pkt_vars.cuda_mutex); - SCMutexUnlock(&p->cuda_pkt_vars.cuda_mutex); - } - } /* while */ - p->cuda_pkt_vars.cuda_done = 0; - p->cuda_pkt_vars.cuda_mpm_enabled = 0; - - uint32_t cuda_matches = p->cuda_pkt_vars.cuda_gpu_matches; - if (cuda_matches == 0) - return 0; - - uint32_t matches = 0; - uint32_t *results = p->cuda_pkt_vars.cuda_results + 1; - uint8_t *buf = p->payload; - SCACCtx *ctx = mpm_ctx->ctx; - SCACOutputTable *output_table = ctx->output_table; - SCACPatternList *pid_pat_list = ctx->pid_pat_list; - - for (u = 0; u < cuda_matches; u += 2) { - uint32_t offset = results[u]; - uint32_t state = results[u + 1]; - /* we should technically be doing state & 0x00FFFFFF, but we don't - * since the cuda kernel does that for us */ - uint32_t no_of_entries = output_table[state].no_of_entries; - /* we should technically be doing state & 0x00FFFFFF, but we don't - * since the cuda kernel does that for us */ - uint32_t *pids = output_table[state].pids; - uint32_t k; - /* note that this is not a verbatim copy from SCACSearch(). We - * don't copy the pattern id into the pattern_id_array. That's - * the only change */ - for (k = 0; k < no_of_entries; k++) { - if (pids[k] & 0xFFFF0000) { - uint32_t lower_pid = pids[k] & 0x0000FFFF; - if (SCMemcmp(pid_pat_list[lower_pid].cs, - buf + offset - pid_pat_list[lower_pid].patlen + 1, - pid_pat_list[lower_pid].patlen) != 0) { - /* inside loop */ - continue; - } - if (pmq->pattern_id_bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { - ; - } else { - pmq->pattern_id_bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - } - matches++; - } else { - if (pmq->pattern_id_bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { - ; - } else { - pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - } - matches++; - } - } - } - - return matches; -} - -void SCACCudaStartDispatcher(void) -{ - /* create the threads */ - ThreadVars *tv = TmThreadCreate("Cuda_Mpm_AC_Dispatcher", - NULL, NULL, - NULL, NULL, - "custom", SCACCudaDispatcher, 0); - if (tv == NULL) { - SCLogError(SC_ERR_THREAD_CREATE, "Error creating a thread for " - "ac cuda dispatcher. Killing engine."); - exit(EXIT_FAILURE); - } - if (TmThreadSpawn(tv) != 0) { - SCLogError(SC_ERR_THREAD_SPAWN, "Failed to spawn thread for " - "ac cuda dispatcher. Killing engine."); - exit(EXIT_FAILURE); - } - - return; -} - -int MpmCudaBufferSetup(void) -{ - int r = 0; - MpmCudaConf *conf = CudaHandlerGetCudaProfile("mpm"); - if (conf == NULL) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error obtaining cuda mpm profile."); - return -1; - } - - CUcontext cuda_context = CudaHandlerModuleGetContext(MPM_AC_CUDA_MODULE_NAME, conf->device_id); - if (cuda_context == 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error retrieving cuda context."); - return -1; - } - r = SCCudaCtxPushCurrent(cuda_context); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error pushing cuda context."); - return -1; - } - - uint8_t *d_buffer = NULL; - uint32_t *o_buffer = NULL; - void **p_buffer = NULL; - - r = SCCudaMemAllocHost((void *)&d_buffer, conf->cb_buffer_size); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Cuda alloc host failure."); - return -1; - } - SCLogInfo("Allocated a cuda d_buffer - %"PRIu32" bytes", conf->cb_buffer_size); - r = SCCudaMemAllocHost((void *)&o_buffer, sizeof(uint32_t) * UTIL_MPM_CUDA_CUDA_BUFFER_OPBUFFER_ITEMS_DEFAULT); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Cuda alloc host failue."); - return -1; - } - r = SCCudaMemAllocHost((void *)&p_buffer, sizeof(void *) * UTIL_MPM_CUDA_CUDA_BUFFER_OPBUFFER_ITEMS_DEFAULT); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Cuda alloc host failure."); - return -1; - } - - r = SCCudaCtxPopCurrent(NULL); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "cuda context pop failure."); - return -1; - } - - CudaBufferData *cb = CudaBufferRegisterNew(d_buffer, conf->cb_buffer_size, o_buffer, p_buffer, UTIL_MPM_CUDA_CUDA_BUFFER_OPBUFFER_ITEMS_DEFAULT); - if (cb == NULL) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error registering new cb instance."); - return -1; - } - CudaHandlerModuleStoreData(MPM_AC_CUDA_MODULE_NAME, MPM_AC_CUDA_MODULE_CUDA_BUFFER_NAME, cb); - - return 0; -} - -int MpmCudaBufferDeSetup(void) -{ - int r = 0; - MpmCudaConf *conf = CudaHandlerGetCudaProfile("mpm"); - if (conf == NULL) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error obtaining cuda mpm profile."); - return -1; - } - - CudaBufferData *cb_data = CudaHandlerModuleGetData(MPM_AC_CUDA_MODULE_NAME, MPM_AC_CUDA_MODULE_CUDA_BUFFER_NAME); - BUG_ON(cb_data == NULL); - - CUcontext cuda_context = CudaHandlerModuleGetContext(MPM_AC_CUDA_MODULE_NAME, conf->device_id); - if (cuda_context == 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error retrieving cuda context."); - return -1; - } - r = SCCudaCtxPushCurrent(cuda_context); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error pushing cuda context."); - return -1; - } - - r = SCCudaMemFreeHost(cb_data->d_buffer); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error freeing cuda host memory."); - return -1; - } - r = SCCudaMemFreeHost(cb_data->o_buffer); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error freeing cuda host memory."); - return -1; - } - r = SCCudaMemFreeHost(cb_data->p_buffer); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error freeing cuda host memory."); - return -1; - } - - r = SCCudaCtxPopCurrent(NULL); - if (r < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "cuda context pop failure."); - return -1; - } - - CudaBufferDeRegister(cb_data); - - return 0; -} - -#endif /* __SC_CUDA_SUPPORT */ - -/************************** Mpm Registration ***************************/ - -/** - * \brief Register the aho-corasick mpm. - */ -void MpmACRegister(void) -{ - mpm_table[MPM_AC].name = "ac"; - /* don't need this. isn't that awesome? no more chopping and blah blah */ - mpm_table[MPM_AC].max_pattern_length = 0; - - mpm_table[MPM_AC].InitCtx = SCACInitCtx; - mpm_table[MPM_AC].InitThreadCtx = SCACInitThreadCtx; - mpm_table[MPM_AC].DestroyCtx = SCACDestroyCtx; - mpm_table[MPM_AC].DestroyThreadCtx = SCACDestroyThreadCtx; - mpm_table[MPM_AC].AddPattern = SCACAddPatternCS; - mpm_table[MPM_AC].AddPatternNocase = SCACAddPatternCI; - mpm_table[MPM_AC].Prepare = SCACPreparePatterns; - mpm_table[MPM_AC].Search = SCACSearch; - mpm_table[MPM_AC].Cleanup = NULL; - mpm_table[MPM_AC].PrintCtx = SCACPrintInfo; - mpm_table[MPM_AC].PrintThreadCtx = SCACPrintSearchStats; - mpm_table[MPM_AC].RegisterUnittests = SCACRegisterTests; - - return; -} - -#ifdef __SC_CUDA_SUPPORT__ - -/** - * \brief Register the aho-corasick cuda mpm. - */ -void MpmACCudaRegister(void) -{ - mpm_table[MPM_AC_CUDA].name = "ac-cuda"; - /* don't need this. isn't that awesome? no more chopping and blah blah */ - mpm_table[MPM_AC_CUDA].max_pattern_length = 0; - - mpm_table[MPM_AC_CUDA].InitCtx = SCACInitCtx; - mpm_table[MPM_AC_CUDA].InitThreadCtx = SCACInitThreadCtx; - mpm_table[MPM_AC_CUDA].DestroyCtx = SCACDestroyCtx; - mpm_table[MPM_AC_CUDA].DestroyThreadCtx = SCACDestroyThreadCtx; - mpm_table[MPM_AC_CUDA].AddPattern = SCACAddPatternCS; - mpm_table[MPM_AC_CUDA].AddPatternNocase = SCACAddPatternCI; - mpm_table[MPM_AC_CUDA].Prepare = SCACPreparePatterns; - mpm_table[MPM_AC_CUDA].Search = SCACSearch; - mpm_table[MPM_AC_CUDA].Cleanup = NULL; - mpm_table[MPM_AC_CUDA].PrintCtx = SCACPrintInfo; - mpm_table[MPM_AC_CUDA].PrintThreadCtx = SCACPrintSearchStats; - mpm_table[MPM_AC_CUDA].RegisterUnittests = SCACRegisterTests; - - return; -} - -#endif /* __SC_CUDA_SUPPORT__ */ - -/*************************************Unittests********************************/ - -#ifdef UNITTESTS - -static int SCACTest01(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest02(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abce", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest03(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghj", 4, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest04(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdegh", 6, 0, 0, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest05(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest06(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcd"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest07(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); - /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); - /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); - /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); - /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - 30, 0, 0, 5, 0, 0); - PmqSetup(&pmq, 6); - /* total matches: 135 */ - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest08(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"a", 1); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest09(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ab", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"ab", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest10(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789" - "abcdefgh" - "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest11(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"he", 2, 0, 0, 1, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"she", 3, 0, 0, 2, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"his", 3, 0, 0, 3, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"hers", 4, 0, 0, 4, 0, 0) == -1) - goto end; - PmqSetup(&pmq, 5); - - if (SCACPreparePatterns(&mpm_ctx) == -1) - goto end; - - result = 1; - - char *buf = "he"; - result &= (SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "she"; - result &= (SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - buf = "his"; - result &= (SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "hers"; - result &= (SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - - end: - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest12(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"wxyz", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"vwxyz", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest13(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCD"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCD"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest14(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCDE"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCDE"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest15(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABCDEF"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABCDEF"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest16(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzABC"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzABC"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest17(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcdefghijklmnopqrstuvwxyzAB"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyzAB"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest18(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - char *pat = "abcde""fghij""klmno""pqrst""uvwxy""z"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcde""fghij""klmno""pqrst""uvwxy""z"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest19(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - char *pat = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest20(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - char *pat = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, strlen(pat), 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest21(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"AA", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest22(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest23(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 0) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest24(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 1 */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest25(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghiJkl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq, 3); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest26(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq, 2); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "works"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest27(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ONE", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "tone"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest28(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PatternMatcherQueue pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC); - SCACInitThreadCtx(&mpm_ctx, &mpm_thread_ctx, 0); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"one", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq, 1); - - SCACPreparePatterns(&mpm_ctx); - - char *buf = "tONE"; - uint32_t cnt = SCACSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACDestroyCtx(&mpm_ctx); - SCACDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACTest29(void) -{ - uint8_t *buf = (uint8_t *)"onetwothreefourfivesixseveneightnine"; - uint16_t buflen = strlen((char *)buf); - Packet *p = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int result = 0; - - memset(&th_v, 0, sizeof(th_v)); - p = UTHBuildPacket(buf, buflen, IPPROTO_TCP); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; fast_pattern:3,3; sid:2;)"); - if (de_ctx->sig_list->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) != 1) { - printf("if (PacketAlertCheck(p, 1) != 1) failure\n"); - goto end; - } - if (PacketAlertCheck(p, 2) != 1) { - printf("if (PacketAlertCheck(p, 1) != 2) failure\n"); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void SCACRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("SCACTest01", SCACTest01, 1); - UtRegisterTest("SCACTest02", SCACTest02, 1); - UtRegisterTest("SCACTest03", SCACTest03, 1); - UtRegisterTest("SCACTest04", SCACTest04, 1); - UtRegisterTest("SCACTest05", SCACTest05, 1); - UtRegisterTest("SCACTest06", SCACTest06, 1); - UtRegisterTest("SCACTest07", SCACTest07, 1); - UtRegisterTest("SCACTest08", SCACTest08, 1); - UtRegisterTest("SCACTest09", SCACTest09, 1); - UtRegisterTest("SCACTest10", SCACTest10, 1); - UtRegisterTest("SCACTest11", SCACTest11, 1); - UtRegisterTest("SCACTest12", SCACTest12, 1); - UtRegisterTest("SCACTest13", SCACTest13, 1); - UtRegisterTest("SCACTest14", SCACTest14, 1); - UtRegisterTest("SCACTest15", SCACTest15, 1); - UtRegisterTest("SCACTest16", SCACTest16, 1); - UtRegisterTest("SCACTest17", SCACTest17, 1); - UtRegisterTest("SCACTest18", SCACTest18, 1); - UtRegisterTest("SCACTest19", SCACTest19, 1); - UtRegisterTest("SCACTest20", SCACTest20, 1); - UtRegisterTest("SCACTest21", SCACTest21, 1); - UtRegisterTest("SCACTest22", SCACTest22, 1); - UtRegisterTest("SCACTest23", SCACTest23, 1); - UtRegisterTest("SCACTest24", SCACTest24, 1); - UtRegisterTest("SCACTest25", SCACTest25, 1); - UtRegisterTest("SCACTest26", SCACTest26, 1); - UtRegisterTest("SCACTest27", SCACTest27, 1); - UtRegisterTest("SCACTest28", SCACTest28, 1); - UtRegisterTest("SCACTest29", SCACTest29, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/util-mpm-ac.h b/framework/src/suricata/src/util-mpm-ac.h deleted file mode 100644 index a837f5f0..00000000 --- a/framework/src/suricata/src/util-mpm-ac.h +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - */ - -#ifndef __UTIL_MPM_AC__H__ -#define __UTIL_MPM_AC__H__ - -#define SC_AC_STATE_TYPE_U16 uint16_t -#define SC_AC_STATE_TYPE_U32 uint32_t - -#ifdef __SC_CUDA_SUPPORT__ -#include "suricata-common.h" -#include "util-cuda.h" -#include "util-cuda-vars.h" -#include "decode.h" -#include "util-cuda-buffer.h" -#include "util-mpm.h" -#include "flow.h" -#endif /* __SC_CUDA_SUPPORT__ */ - -typedef struct SCACPattern_ { - /* length of the pattern */ - uint16_t len; - /* flags decribing the pattern */ - uint8_t flags; - /* holds the original pattern that was added */ - uint8_t *original_pat; - /* case sensitive */ - uint8_t *cs; - /* case INsensitive */ - uint8_t *ci; - /* pattern id */ - uint32_t id; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; - - struct SCACPattern_ *next; -} SCACPattern; - -typedef struct SCACPatternList_ { - uint8_t *cs; - uint16_t patlen; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; -} SCACPatternList; - -typedef struct SCACOutputTable_ { - /* list of pattern sids */ - uint32_t *pids; - /* no of entries we have in pids */ - uint32_t no_of_entries; -} SCACOutputTable; - -typedef struct SCACCtx_ { - /* hash used during ctx initialization */ - SCACPattern **init_hash; - - /* pattern arrays. We need this only during the goto table creation phase */ - SCACPattern **parray; - - /* no of states used by ac */ - uint32_t state_count; - /* the all important memory hungry state_table */ - SC_AC_STATE_TYPE_U16 (*state_table_u16)[256]; - /* the all important memory hungry state_table */ - SC_AC_STATE_TYPE_U32 (*state_table_u32)[256]; - - /* goto_table, failure table and output table. Needed to create state_table. - * Will be freed, once we have created the state_table */ - int32_t (*goto_table)[256]; - int32_t *failure_table; - SCACOutputTable *output_table; - SCACPatternList *pid_pat_list; - - /* the size of each state */ - uint16_t single_state_size; - uint16_t max_pat_id; - - uint32_t allocated_state_count; - -#ifdef __SC_CUDA_SUPPORT__ - CUdeviceptr state_table_u16_cuda; - CUdeviceptr state_table_u32_cuda; -#endif /* __SC_CUDA_SUPPORT__ */ -} SCACCtx; - -typedef struct SCACThreadCtx_ { - /* the total calls we make to the search function */ - uint32_t total_calls; - /* the total patterns that we ended up matching against */ - uint64_t total_matches; -} SCACThreadCtx; - -void MpmACRegister(void); - - -#ifdef __SC_CUDA_SUPPORT__ - -#define MPM_AC_CUDA_MODULE_NAME "ac_cuda" -#define MPM_AC_CUDA_MODULE_CUDA_BUFFER_NAME "ac_cuda_cb" - -static inline void CudaBufferPacket(CudaThreadVars *ctv, Packet *p) -{ - if (p->cuda_pkt_vars.cuda_mpm_enabled) { - while (!p->cuda_pkt_vars.cuda_done) { - SCMutexLock(&p->cuda_pkt_vars.cuda_mutex); - if (p->cuda_pkt_vars.cuda_done) { - SCMutexUnlock(&p->cuda_pkt_vars.cuda_mutex); - break; - } else { - SCCondWait(&p->cuda_pkt_vars.cuda_cond, &p->cuda_pkt_vars.cuda_mutex); - SCMutexUnlock(&p->cuda_pkt_vars.cuda_mutex); - } - } - } - p->cuda_pkt_vars.cuda_done = 0; - - if (p->payload_len == 0 || - (p->flags & (PKT_NOPAYLOAD_INSPECTION & PKT_NOPACKET_INSPECTION)) || - (p->flags & PKT_ALLOC) || - (ctv->data_buffer_size_min_limit != 0 && p->payload_len < ctv->data_buffer_size_min_limit) || - (p->payload_len > ctv->data_buffer_size_max_limit && ctv->data_buffer_size_max_limit != 0) ) { - p->cuda_pkt_vars.cuda_mpm_enabled = 0; - return; - } - - MpmCtx *mpm_ctx = NULL; - if (p->proto == IPPROTO_TCP) { - if (p->flowflags & FLOW_PKT_TOSERVER) - mpm_ctx = ctv->mpm_proto_tcp_ctx_ts; - else - mpm_ctx = ctv->mpm_proto_tcp_ctx_tc; - } else if (p->proto == IPPROTO_UDP) { - if (p->flowflags & FLOW_PKT_TOSERVER) - mpm_ctx = ctv->mpm_proto_udp_ctx_ts; - else - mpm_ctx = ctv->mpm_proto_udp_ctx_tc; - } else { - mpm_ctx = ctv->mpm_proto_other_ctx; - } - if (mpm_ctx == NULL || mpm_ctx->pattern_cnt == 0) { - p->cuda_pkt_vars.cuda_mpm_enabled = 0; - return; - } - -#if __WORDSIZE==64 - CudaBufferSlice *slice = CudaBufferGetSlice(ctv->cuda_ac_cb, - p->payload_len + sizeof(uint64_t) + sizeof(CUdeviceptr), - (void *)p); - if (slice == NULL) { - SCLogError(SC_ERR_FATAL, "Error retrieving slice. Please report " - "this to dev."); - p->cuda_pkt_vars.cuda_mpm_enabled = 0; - return; - } - *((uint64_t *)(slice->buffer + slice->start_offset)) = p->payload_len; - *((CUdeviceptr *)(slice->buffer + slice->start_offset + sizeof(uint64_t))) = ((SCACCtx *)(mpm_ctx->ctx))->state_table_u32_cuda; - memcpy(slice->buffer + slice->start_offset + sizeof(uint64_t) + sizeof(CUdeviceptr), p->payload, p->payload_len); -#else - CudaBufferSlice *slice = CudaBufferGetSlice(ctv->cuda_ac_cb, - p->payload_len + sizeof(uint32_t) + sizeof(CUdeviceptr), - (void *)p); - if (slice == NULL) { - SCLogError(SC_ERR_FATAL, "Error retrieving slice. Please report " - "this to dev."); - p->cuda_pkt_vars.cuda_mpm_enabled = 0; - return; - } - *((uint32_t *)(slice->buffer + slice->start_offset)) = p->payload_len; - *((CUdeviceptr *)(slice->buffer + slice->start_offset + sizeof(uint32_t))) = ((SCACCtx *)(mpm_ctx->ctx))->state_table_u32_cuda; - memcpy(slice->buffer + slice->start_offset + sizeof(uint32_t) + sizeof(CUdeviceptr), p->payload, p->payload_len); -#endif - p->cuda_pkt_vars.cuda_mpm_enabled = 1; - SC_ATOMIC_SET(slice->done, 1); - - SCLogDebug("cuda ac buffering packet %p, payload_len - %"PRIu16" and deviceptr - %"PRIu64"\n", - p, p->payload_len, (unsigned long)((SCACCtx *)(mpm_ctx->ctx))->state_table_u32_cuda); - - return; -} - -void MpmACCudaRegister(void); -void SCACConstructBoth16and32StateTables(void); -int MpmCudaBufferSetup(void); -int MpmCudaBufferDeSetup(void); -void SCACCudaStartDispatcher(void); -void SCACCudaKillDispatcher(void); -uint32_t SCACCudaPacketResultsProcessing(Packet *p, MpmCtx *mpm_ctx, - PatternMatcherQueue *pmq); -void DetermineCudaStateTableSize(DetectEngineCtx *de_ctx); - -void CudaReleasePacket(Packet *p); - -#endif /* __SC_CUDA_SUPPORT__ */ - - -#endif /* __UTIL_MPM_AC__H__ */ diff --git a/framework/src/suricata/src/util-mpm-b2g.c b/framework/src/suricata/src/util-mpm-b2g.c deleted file mode 100644 index f7172839..00000000 --- a/framework/src/suricata/src/util-mpm-b2g.c +++ /dev/null @@ -1,2832 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implementation of the SBNDMq pattern matching algorithm. - * - * Ideas: - * - B2g does a full match in the search of up to 'm' characters, - * in case of a case insensitive search we could say it's match if - * the pattern is of len 'm' or just compare the rest of the chars. - * - * \todo Try to get the S0 calculation right. - */ - -//#define PRINTMATCH - -#include "suricata-common.h" -#include "suricata.h" -#include "detect.h" -#include "util-bloomfilter.h" -#include "util-mpm-b2g.h" -#include "util-print.h" - -#include "util-debug.h" -#include "util-unittest.h" -#include "util-memcmp.h" -#include "util-memcpy.h" -#include "conf.h" - -#define INIT_HASH_SIZE 65536 - -#ifdef B2G_COUNTERS -#define COUNT(counter) \ - (counter) -#else -#define COUNT(counter) -#endif /* B2G_COUNTERS */ - -static uint32_t b2g_hash_size = 0; -static uint32_t b2g_bloom_size = 0; -static uint8_t b2g_hash_shift = 0; -static void *b2g_func; - -#define B2G_HASH16(a,b) (((a) << b2g_hash_shift) | (b)) - -void B2gInitCtx (MpmCtx *); -void B2gThreadInitCtx(MpmCtx *, MpmThreadCtx *, uint32_t); -void B2gDestroyCtx(MpmCtx *); -void B2gThreadDestroyCtx(MpmCtx *, MpmThreadCtx *); -int B2gAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags); -int B2gAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags); -int B2gPreparePatterns(MpmCtx *mpm_ctx); -uint32_t B2gSearchWrap(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -uint32_t B2gSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -#ifdef B2G_SEARCH2 -uint32_t B2gSearch2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -#endif -uint32_t B2gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -uint32_t B2gSearchBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen); -void B2gPrintInfo(MpmCtx *mpm_ctx); -void B2gPrintSearchStats(MpmThreadCtx *mpm_thread_ctx); -void B2gRegisterTests(void); - -void MpmB2gRegister (void) -{ - mpm_table[MPM_B2G].name = "b2g"; - mpm_table[MPM_B2G].max_pattern_length = B2G_WORD_SIZE; - - mpm_table[MPM_B2G].InitCtx = B2gInitCtx; - mpm_table[MPM_B2G].InitThreadCtx = B2gThreadInitCtx; - mpm_table[MPM_B2G].DestroyCtx = B2gDestroyCtx; - mpm_table[MPM_B2G].DestroyThreadCtx = B2gThreadDestroyCtx; - mpm_table[MPM_B2G].AddPattern = B2gAddPatternCS; - mpm_table[MPM_B2G].AddPatternNocase = B2gAddPatternCI; - mpm_table[MPM_B2G].Prepare = B2gPreparePatterns; - mpm_table[MPM_B2G].Search = B2gSearchWrap; - mpm_table[MPM_B2G].Cleanup = NULL; - mpm_table[MPM_B2G].PrintCtx = B2gPrintInfo; - mpm_table[MPM_B2G].PrintThreadCtx = B2gPrintSearchStats; - mpm_table[MPM_B2G].RegisterUnittests = B2gRegisterTests; -} - -#ifdef PRINTMATCH -static void prt (uint8_t *buf, uint16_t buflen) -{ - uint16_t i; - - for (i = 0; i < buflen; i++) { - if (isprint(buf[i])) printf("%c", buf[i]); - else printf("\\x%02X", buf[i]); - } - //printf("\n"); -} -#endif - -void B2gPrintInfo(MpmCtx *mpm_ctx) -{ - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - - printf("MPM B2g Information:\n"); - printf("Memory allocs: %" PRIu32 "\n", mpm_ctx->memory_cnt); - printf("Memory alloced: %" PRIu32 "\n", mpm_ctx->memory_size); - printf(" Sizeofs:\n"); - printf(" MpmCtx %" PRIuMAX "\n", (uintmax_t)sizeof(MpmCtx)); - printf(" B2gCtx: %" PRIuMAX "\n", (uintmax_t)sizeof(B2gCtx)); - printf(" B2gPattern %" PRIuMAX "\n", (uintmax_t)sizeof(B2gPattern)); - printf(" B2gPattern %" PRIuMAX "\n", (uintmax_t)sizeof(B2gPattern)); - printf("Unique Patterns: %" PRIu32 "\n", mpm_ctx->pattern_cnt); - printf("Smallest: %" PRIu32 "\n", mpm_ctx->minlen); - printf("Largest: %" PRIu32 "\n", mpm_ctx->maxlen); - printf("Hash size: %" PRIu32 "\n", ctx->hash_size); - printf("\n"); -} - -/** - * \brief B2gAllocPattern allocates a new pattern structure - * and initialize the data - * \initonly - */ -static inline B2gPattern *B2gAllocPattern(MpmCtx *mpm_ctx) -{ - B2gPattern *p = SCMalloc(sizeof(B2gPattern)); - if (unlikely(p == NULL)) - return NULL; - memset(p,0,sizeof(B2gPattern)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(B2gPattern); - return p; -} - -static inline B2gPattern * -B2gAllocHashItem(MpmCtx *mpm_ctx) -{ - B2gPattern *hi = SCMalloc(sizeof(B2gPattern)); - if (unlikely(hi == NULL)) - return NULL; - memset(hi,0,sizeof(B2gPattern)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(B2gPattern); - return hi; -} - -static void B2gHashFree(MpmCtx *mpm_ctx, B2gPattern *hi) -{ - if (hi == NULL) - return; - - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(B2gPattern); - B2gPattern *t = hi->next; - SCFree(hi); - - B2gHashFree(mpm_ctx, t); -} - -/* - * INIT HASH START - */ -static inline uint32_t B2gInitHash(B2gPattern *p) -{ - uint32_t hash = p->len * p->original_pat[0]; - if (p->len > 1) - hash += p->original_pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline uint32_t B2gInitHashRaw(uint8_t *pat, uint16_t patlen) -{ - uint32_t hash = patlen * pat[0]; - if (patlen > 1) - hash += pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline int B2gInitHashAdd(B2gCtx *ctx, B2gPattern *p) -{ - uint32_t hash = B2gInitHash(p); - - //printf("B2gInitHashAdd: %" PRIu32 "\n", hash); - - if (ctx->init_hash[hash] == NULL) { - ctx->init_hash[hash] = p; - //printf("B2gInitHashAdd: hash %" PRIu32 ", head %p\n", hash, ctx->init_hash[hash]); - return 0; - } - - B2gPattern *tt = NULL; - B2gPattern *t = ctx->init_hash[hash]; - - /* get the list tail */ - do { - tt = t; - t = t->next; - } while (t != NULL); - - tt->next = p; - - //printf("B2gInitHashAdd: hash %" PRIu32 ", head %p\n", hash, ctx->init_hash[hash]); - return 0; -} - -static inline int B2gCmpPattern(B2gPattern *p, uint8_t *pat, uint16_t patlen, char flags); - -static inline B2gPattern *B2gInitHashLookup(B2gCtx *ctx, uint8_t *pat, uint16_t patlen, char flags, - uint32_t pid) -{ - uint32_t hash = B2gInitHashRaw(pat,patlen); - - //printf("B2gInitHashLookup: %" PRIu32 ", head %p\n", hash, ctx->init_hash[hash]); - - if (ctx->init_hash[hash] == NULL) { - return NULL; - } - - B2gPattern *t = ctx->init_hash[hash]; - for ( ; t != NULL; t = t->next) { - //if (B2gCmpPattern(t,pat,patlen,flags) == 1) - if (t->id == pid) - return t; - } - - return NULL; -} - -static inline int B2gCmpPattern(B2gPattern *p, uint8_t *pat, uint16_t patlen, char flags) -{ - if (p->len != patlen) - return 0; - - if (p->flags != flags) - return 0; - - if (SCMemcmp(p->cs, pat, patlen) != 0) - return 0; - - return 1; -} - -/* - * INIT HASH END - */ - -void B2gFreePattern(MpmCtx *mpm_ctx, B2gPattern *p) -{ - if (p && p->cs && p->cs != p->ci) { - SCFree(p->cs); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p && p->ci) { - SCFree(p->ci); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p != NULL && p->original_pat != NULL) { - SCFree(p->original_pat); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p && p->sids) { - SCFree(p->sids); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->sids_size * sizeof(SigIntId); - } - - if (p) { - SCFree(p); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(B2gPattern); - } -} - -/** \internal - * \brief add a pattern to the mpm/b2g context - * - * \param pat ptr to the pattern - * \param patlen length of the pattern - * \param pid pattern id - * \param sid signature id (internal id) - * \param flags pattern MPM_PATTERN_* flags - * - * \initonly - */ -static int B2gAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags) -{ - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - - SCLogDebug("ctx %p len %"PRIu16" pid %" PRIu32, ctx, patlen, pid); - - if (patlen == 0) - return 0; - - /* get a memory piece */ - B2gPattern *p = B2gInitHashLookup(ctx, pat, patlen, flags, pid); - if (p == NULL) { - SCLogDebug("allocing new pattern"); - - p = B2gAllocPattern(mpm_ctx); - if (p == NULL) - goto error; - - p->len = patlen; - p->flags = flags; - p->id = pid; - - p->original_pat = SCMalloc(patlen); - if (p->original_pat == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->original_pat, pat, patlen); - - /* setup the case insensitive part of the pattern */ - p->ci = SCMalloc(patlen); - if (p->ci == NULL) - goto error; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy_tolower(p->ci, pat, patlen); - - /* setup the case sensitive part of the pattern */ - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - /* nocase means no difference between cs and ci */ - p->cs = p->ci; - } else { - if (SCMemcmp(p->ci,pat,p->len) == 0) { - /* no diff between cs and ci: pat is lowercase */ - p->cs = p->ci; - } else { - p->cs = SCMalloc(patlen); - if (p->cs == NULL) - goto error; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->cs, pat, patlen); - } - } - - p->sids_size = 1; - p->sids = SCMalloc(p->sids_size * sizeof(SigIntId)); - BUG_ON(p->sids == NULL); - p->sids[0] = sid; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SigIntId); - - //printf("B2gAddPattern: ci \""); prt(p->ci,p->len); - //printf("\" cs \""); prt(p->cs,p->len); - //printf("\"\n"); - - /* put in the pattern hash */ - B2gInitHashAdd(ctx, p); - - if (mpm_ctx->pattern_cnt == 65535) { - printf("Max search words reached\n"); - exit(1); - } - mpm_ctx->pattern_cnt++; - - if (mpm_ctx->maxlen < patlen) mpm_ctx->maxlen = patlen; - if (mpm_ctx->minlen == 0) mpm_ctx->minlen = patlen; - else if (mpm_ctx->minlen > patlen) mpm_ctx->minlen = patlen; - } else { - /* Multiple sids for the same pid, so keep an array of sids. */ - - /* TODO figure out how we can be called multiple times for the - * same CTX with the same sid */ - int found = 0; - uint32_t x = 0; - for (x = 0; x < p->sids_size; x++) { - if (p->sids[x] == sid) { - found = 1; - break; - } - } - if (!found) { - SigIntId *sids = SCRealloc(p->sids, (sizeof(SigIntId) * (p->sids_size + 1))); - BUG_ON(sids == NULL); - p->sids = sids; - p->sids[p->sids_size] = sid; - p->sids_size++; - mpm_ctx->memory_size += sizeof(SigIntId); - } - } - - return 0; - -error: - B2gFreePattern(mpm_ctx, p); - return -1; -} - -int B2gAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags) -{ - flags |= MPM_PATTERN_FLAG_NOCASE; - return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -int B2gAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags) -{ - return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -static inline uint32_t B2gBloomHash(void *data, uint16_t datalen, uint8_t iter, uint32_t hash_size) -{ - uint8_t *d = (uint8_t *)data; - uint16_t i; - uint32_t hash = (uint32_t)u8_tolower(*d); - - for (i = 1; i < datalen; i++) { - d++; - hash += (u8_tolower(*d)) ^ i; - } - hash <<= (iter+1); - - hash %= hash_size; - return hash; -} - -static void B2gPrepareHash(MpmCtx *mpm_ctx) -{ - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - uint16_t i; - uint16_t idx = 0; - uint8_t idx8 = 0; - - ctx->hash = (B2gPattern **)SCMalloc(sizeof(B2gPattern *) * ctx->hash_size); - if (ctx->hash == NULL) - goto error; - memset(ctx->hash, 0, sizeof(B2gPattern *) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(B2gPattern *) * ctx->hash_size); - -#ifdef B2G_SEARCH2 - ctx->hash2 = (B2gPattern **)SCMalloc(sizeof(B2gPattern *) * ctx->hash_size); - if (ctx->hash2 == NULL) - goto error; - memset(ctx->hash2, 0, sizeof(B2gPattern *) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(B2gPattern *) * ctx->hash_size); -#endif - - /* alloc the pminlen array */ - ctx->pminlen = (uint8_t *)SCMalloc(sizeof(uint8_t) * ctx->hash_size); - if (ctx->pminlen == NULL) - goto error; - memset(ctx->pminlen, 0, sizeof(uint8_t) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(uint8_t) * ctx->hash_size); - - for (i = 0; i < mpm_ctx->pattern_cnt; i++) - { - if(ctx->parray[i]->len == 1) { - idx8 = (uint8_t)ctx->parray[i]->ci[0]; - if (ctx->hash1[idx8].flags == 0) { - ctx->hash1[idx8].flags |= MPM_PATTERN_ONE_BYTE; - - B2gPattern *hi = &ctx->hash1[idx8]; - hi->len = ctx->parray[i]->len; - hi->flags |= ctx->parray[i]->flags; - hi->id = ctx->parray[i]->id; - hi->ci = ctx->parray[i]->ci; - hi->cs = ctx->parray[i]->cs; - hi->sids = ctx->parray[i]->sids; - hi->sids_size = ctx->parray[i]->sids_size; - - } else { - B2gPattern *hi = B2gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->flags |= MPM_PATTERN_ONE_BYTE; - - hi->len = ctx->parray[i]->len; - hi->flags |= ctx->parray[i]->flags; - hi->id = ctx->parray[i]->id; - hi->ci = ctx->parray[i]->ci; - hi->cs = ctx->parray[i]->cs; - hi->sids = ctx->parray[i]->sids; - hi->sids_size = ctx->parray[i]->sids_size; - - /* Append this HashItem to the list */ - B2gPattern *thi = &ctx->hash1[idx8]; - while (thi->next) thi = thi->next; - thi->next = hi; - } - ctx->pat_1_cnt++; -#ifdef B2G_SEARCH2 - } else if(ctx->parray[i]->len == 2) { - idx = B2G_HASH16(ctx->parray[i]->ci[0],ctx->parray[i]->ci[1]); - if (ctx->hash2[idx] == NULL) { - B2gPattern *hi = B2gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= MPM_PATTERN_ONE_BYTE; - - ctx->hash2[idx] = hi; - } else { - B2gPattern *hi = B2gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= MPM_PATTERN_ONE_BYTE; - - /* Append this HashItem to the list */ - B2gPattern *thi = ctx->hash2[idx]; - while (thi->next) thi = thi->next; - thi->next = hi; - } - ctx->pat_2_cnt++; -#endif - } else { - idx = B2G_HASH16(ctx->parray[i]->ci[ctx->m - 2], ctx->parray[i]->ci[ctx->m - 1]); - SCLogDebug("idx %" PRIu32 ", %c.%c", idx, ctx->parray[i]->ci[ctx->m - 2], ctx->parray[i]->ci[ctx->m - 1]); - - if (ctx->hash[idx] == NULL) { - B2gPattern *hi = B2gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - - ctx->pminlen[idx] = ctx->parray[i]->len; - - hi->len = ctx->parray[i]->len; - hi->flags |= ctx->parray[i]->flags; - hi->id = ctx->parray[i]->id; - hi->ci = ctx->parray[i]->ci; - hi->cs = ctx->parray[i]->cs; - hi->sids = ctx->parray[i]->sids; - hi->sids_size = ctx->parray[i]->sids_size; - - ctx->hash[idx] = hi; - } else { - B2gPattern *hi = B2gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - - hi->flags |= MPM_PATTERN_ONE_BYTE; - - hi->len = ctx->parray[i]->len; - hi->flags |= ctx->parray[i]->flags; - hi->id = ctx->parray[i]->id; - hi->ci = ctx->parray[i]->ci; - hi->cs = ctx->parray[i]->cs; - hi->sids = ctx->parray[i]->sids; - hi->sids_size = ctx->parray[i]->sids_size; - - if (ctx->parray[i]->len < ctx->pminlen[idx]) - ctx->pminlen[idx] = ctx->parray[i]->len; - - /* Append this HashItem to the list */ - B2gPattern *thi = ctx->hash[idx]; - while (thi->next) thi = thi->next; - thi->next = hi; - } - ctx->pat_x_cnt++; - } - } - - /* alloc the bloom array */ - ctx->bloom = (BloomFilter **)SCMalloc(sizeof(BloomFilter *) * ctx->hash_size); - if (ctx->bloom == NULL) - goto error; - memset(ctx->bloom, 0, sizeof(BloomFilter *) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(BloomFilter *) * ctx->hash_size); - - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - B2gPattern *hi = ctx->hash[h]; - if (hi == NULL) - continue; - - ctx->bloom[h] = BloomFilterInit(b2g_bloom_size, 2, B2gBloomHash); - if (ctx->bloom[h] == NULL) - continue; - - mpm_ctx->memory_cnt += BloomFilterMemoryCnt(ctx->bloom[h]); - mpm_ctx->memory_size += BloomFilterMemorySize(ctx->bloom[h]); - - if (ctx->pminlen[h] > 8) - ctx->pminlen[h] = 8; - - B2gPattern *thi = hi; - do { - SCLogDebug("adding \"%c%c\" to the bloom", thi->ci[0], thi->ci[1]); - BloomFilterAdd(ctx->bloom[h], thi->ci, ctx->pminlen[h]); - thi = thi->next; - } while (thi != NULL); - } - - return; -error: - return; -} - -int B2gBuildMatchArray(MpmCtx *mpm_ctx) -{ - SCEnter(); - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - - ctx->B2G = SCMalloc(sizeof(B2G_TYPE) * ctx->hash_size); - if (ctx->B2G == NULL) - return -1; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(B2G_TYPE) * ctx->hash_size); - - memset(ctx->B2G,0, b2g_hash_size * sizeof(B2G_TYPE)); - - uint32_t j; - uint32_t a; - - /* fill the match array */ - for (j = 0; j <= (ctx->m - B2G_Q); j++) { - for (a = 0; a < mpm_ctx->pattern_cnt; a++) { - if (ctx->parray[a]->len < ctx->m) - continue; - - uint16_t h = B2G_HASH16(u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1])); - ctx->B2G[h] = ctx->B2G[h] | (1 << (ctx->m - j)); - - SCLogDebug("h %"PRIu16", ctx->B2G[h] %"PRIu32"", h, ctx->B2G[h]); - } - } - - ctx->s0 = 1; - SCReturnInt(0); -} - -int B2gPreparePatterns(MpmCtx *mpm_ctx) -{ - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - - /* alloc the pattern array */ - ctx->parray = (B2gPattern **)SCMalloc(mpm_ctx->pattern_cnt * sizeof(B2gPattern *)); - if (ctx->parray == NULL) - goto error; - memset(ctx->parray, 0, mpm_ctx->pattern_cnt * sizeof(B2gPattern *)); - //printf("mpm_ctx %p, parray %p\n", mpm_ctx,ctx->parray); - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (mpm_ctx->pattern_cnt * sizeof(B2gPattern *)); - - /* populate it with the patterns in the hash */ - uint32_t i = 0, p = 0; - for (i = 0; i < INIT_HASH_SIZE; i++) { - B2gPattern *node = ctx->init_hash[i], *nnode = NULL; - for ( ; node != NULL; ) { - nnode = node->next; - node->next = NULL; - - ctx->parray[p] = node; - - p++; - node = nnode; - } - } - /* we no longer need the hash, so free it's memory */ - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - - /* set 'm' to the smallest pattern size */ - ctx->m = mpm_ctx->minlen; - - /* make sure 'm' stays in bounds - m can be max WORD_SIZE - 1 */ - if (ctx->m >= B2G_WORD_SIZE) { - ctx->m = B2G_WORD_SIZE - 1; - } - if (ctx->m < 2) ctx->m = 2; - - ctx->hash_size = b2g_hash_size; - B2gPrepareHash(mpm_ctx); - B2gBuildMatchArray(mpm_ctx); - - SCLogDebug("ctx->pat_1_cnt %"PRIu16"", ctx->pat_1_cnt); - if (ctx->pat_1_cnt) { - ctx->Search = B2gSearch1; -#ifdef B2G_SEARCH2 - ctx->Search = B2gSearch2; - if (ctx->pat_2_cnt) { - ctx->MBSearch2 = B2gSearch2; - } -#endif - ctx->MBSearch = b2g_func; -#ifdef B2G_SEARCH2 - } else if (ctx->pat_2_cnt) { - ctx->Search = B2gSearch2; - ctx->MBSearch = b2g_func; -#endif - } - - return 0; -error: - return -1; -} - -void B2gPrintSearchStats(MpmThreadCtx *mpm_thread_ctx) -{ -#ifdef B2G_COUNTERS - B2gThreadCtx *tctx = (B2gThreadCtx *)mpm_thread_ctx->ctx; - - printf("B2g Thread Search stats (tctx %p)\n", tctx); - printf("Total calls: %" PRIu32 "\n", tctx->stat_calls); - printf("Avg m/search: %0.2f\n", tctx->stat_calls ? (float)((float)tctx->stat_m_total / (float)tctx->stat_calls) : 0); - printf("D != 0 (possible match): %" PRIu32 "\n", tctx->stat_d0); - printf("Avg hash items per bucket %0.2f (%" PRIu32 ")\n", tctx->stat_d0 ? (float)((float)tctx->stat_d0_hashloop / (float)tctx->stat_d0) : 0, tctx->stat_d0_hashloop); - printf("Loop match: %" PRIu32 "\n", tctx->stat_loop_match); - printf("Loop no match: %" PRIu32 "\n", tctx->stat_loop_no_match); - printf("Num shifts: %" PRIu32 "\n", tctx->stat_num_shift); - printf("Total shifts: %" PRIu32 "\n", tctx->stat_total_shift); - printf("Avg shifts: %0.2f\n", tctx->stat_num_shift ? (float)((float)tctx->stat_total_shift / (float)tctx->stat_num_shift) : 0); - printf("Total BloomFilter checks: %" PRIu32 "\n", tctx->stat_bloom_calls); - printf("BloomFilter hits: %0.4f%% (%" PRIu32 ")\n", tctx->stat_bloom_calls ? (float)((float)((float)tctx->stat_bloom_hits / (float)tctx->stat_bloom_calls)*(float)100) : 0, tctx->stat_bloom_hits); - printf("Avg pminlen: %0.2f\n\n", tctx->stat_pminlen_calls ? (float)((float)tctx->stat_pminlen_total / (float)tctx->stat_pminlen_calls) : 0); -#endif /* B2G_COUNTERS */ -} - -/** - * \brief Function to get the user defined values for b2g algorithm from the - * config file 'suricata.yaml' - */ -static void B2gGetConfig() -{ - ConfNode *b2g_conf; - const char *hash_val = NULL; - const char *bloom_val = NULL; - const char *algo = NULL; - - /* init defaults */ - b2g_hash_size = HASHSIZE_LOW; - b2g_bloom_size = BLOOMSIZE_MEDIUM; - b2g_hash_shift = B2G_HASHSHIFT_LOW; - b2g_func = B2G_SEARCHFUNC; - - ConfNode *pm = ConfGetNode("pattern-matcher"); - - if (pm != NULL) { - - TAILQ_FOREACH(b2g_conf, &pm->head, next) { - if (strcmp(b2g_conf->val, "b2g") == 0) { - - algo = ConfNodeLookupChildValue - (b2g_conf->head.tqh_first, "algo"); - hash_val = ConfNodeLookupChildValue - (b2g_conf->head.tqh_first, "hash_size"); - bloom_val = ConfNodeLookupChildValue - (b2g_conf->head.tqh_first, "bf_size"); - - if (algo != NULL) { - if (strcmp(algo, "B2gSearch") == 0) { - b2g_func = B2gSearch; - } else if (strcmp(algo, "B2gSearchBNDMq") == 0) { - b2g_func = B2gSearchBNDMq; - } - } - - if (hash_val != NULL) { - b2g_hash_size = MpmGetHashSize(hash_val); - switch (b2g_hash_size) { - case HASHSIZE_LOWEST: - b2g_hash_shift = B2G_HASHSHIFT_LOWEST; - break; - case HASHSIZE_LOW: - b2g_hash_shift = B2G_HASHSHIFT_LOW; - break; - case HASHSIZE_MEDIUM: - b2g_hash_shift = B2G_HASHSHIFT_MEDIUM; - break; - case HASHSIZE_HIGH: - b2g_hash_shift = B2G_HASHSHIFT_HIGH; - break; - case HASHSIZE_HIGHER: - b2g_hash_shift = B2G_HASHSHIFT_HIGHER; - break; - case HASHSIZE_MAX: - b2g_hash_shift = B2G_HASHSHIFT_MAX; - break; - } - } - - if (bloom_val != NULL) - b2g_bloom_size = MpmGetBloomSize(bloom_val); - - SCLogDebug("hash size is %"PRIu32" and bloom size is %"PRIu32"", - b2g_hash_size, b2g_bloom_size); - } - } - } -} - -void B2gInitCtx (MpmCtx *mpm_ctx) -{ - SCLogDebug("mpm_ctx %p, ctx %p", mpm_ctx, mpm_ctx->ctx); - - if (mpm_ctx->ctx != NULL) - return; - - //BUG_ON(mpm_ctx->ctx != NULL); - - mpm_ctx->ctx = SCMalloc(sizeof(B2gCtx)); - if (mpm_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - - memset(mpm_ctx->ctx, 0, sizeof(B2gCtx)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(B2gCtx); - - /* initialize the hash we use to speed up pattern insertions */ - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - ctx->init_hash = SCMalloc(sizeof(B2gPattern *) * INIT_HASH_SIZE); - if (ctx->init_hash == NULL) { - exit(EXIT_FAILURE); - } - - memset(ctx->init_hash, 0, sizeof(B2gPattern *) * INIT_HASH_SIZE); - - /* Initialize the defaults value from the config file. The given check make - sure that we query config file only once for config values */ - if (b2g_hash_size == 0) - B2gGetConfig(); - - /* init defaults search functions */ - ctx->Search = b2g_func; - - SCReturn; -} - -void B2gDestroyCtx(MpmCtx *mpm_ctx) -{ - SCLogDebug("mpm_ctx %p", mpm_ctx); - - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - if (ctx == NULL) - return; - - if (ctx->init_hash) { - SCFree(ctx->init_hash); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (INIT_HASH_SIZE * sizeof(B2gPattern *)); - } - - if (ctx->parray) { - uint32_t i; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - B2gFreePattern(mpm_ctx, ctx->parray[i]); - } - } - - SCFree(ctx->parray); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(B2gPattern)); - } - - if (ctx->B2G) { - SCFree(ctx->B2G); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(B2G_TYPE) * ctx->hash_size); - } - - if (ctx->bloom) { - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - if (ctx->bloom[h] == NULL) - continue; - - mpm_ctx->memory_cnt -= BloomFilterMemoryCnt(ctx->bloom[h]); - mpm_ctx->memory_size -= BloomFilterMemorySize(ctx->bloom[h]); - - BloomFilterFree(ctx->bloom[h]); - } - - SCFree(ctx->bloom); - - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(BloomFilter *) * ctx->hash_size); - } - - if (ctx->hash) { - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - if (ctx->hash[h] == NULL) - continue; - - B2gHashFree(mpm_ctx, ctx->hash[h]); - } - - SCFree(ctx->hash); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(B2gPattern) * ctx->hash_size); - } - - if (ctx->pminlen) { - SCFree(ctx->pminlen); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(uint8_t) * ctx->hash_size); - } - - SCFree(mpm_ctx->ctx); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(B2gCtx); -} - -void B2gThreadInitCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, uint32_t matchsize) -{ - memset(mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - - if (sizeof(B2gThreadCtx) > 0) { /* size can be null when optimized */ - mpm_thread_ctx->ctx = SCMalloc(sizeof(B2gThreadCtx)); - if (mpm_thread_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - - memset(mpm_thread_ctx->ctx, 0, sizeof(B2gThreadCtx)); - - mpm_thread_ctx->memory_cnt++; - mpm_thread_ctx->memory_size += sizeof(B2gThreadCtx); - } -} - -void B2gThreadDestroyCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx) -{ - B2gThreadCtx *ctx = (B2gThreadCtx *)mpm_thread_ctx->ctx; - - B2gPrintSearchStats(mpm_thread_ctx); - - if (ctx != NULL) { /* can be NULL if B2gThreadCtx is optimized to 0 */ - mpm_thread_ctx->memory_cnt--; - mpm_thread_ctx->memory_size -= sizeof(B2gThreadCtx); - SCFree(mpm_thread_ctx->ctx); - } -} - -uint32_t B2gSearchWrap(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - return ctx ? ctx->Search(mpm_ctx, mpm_thread_ctx, pmq, buf, buflen) : 0; -} - -uint32_t B2gSearchBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; -#ifdef B2G_COUNTERS - B2gThreadCtx *tctx = (B2gThreadCtx *)mpm_thread_ctx->ctx; -#endif - uint32_t pos = ctx->m - B2G_Q + 1, matches = 0; - B2G_TYPE d; - - //printf("\n"); - //PrintRawDataFp(stdout, buf, buflen); - - SCLogDebug("buflen %"PRIu16", ctx->m %"PRIu32", pos %"PRIu32"", buflen, - ctx->m, pos); - - COUNT(tctx->stat_calls++); - COUNT(tctx->stat_m_total+=ctx->m); - - if (buflen < ctx->m) - return 0; - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (pos <= (uint32_t)(buflen - B2G_Q + 1)) { - uint16_t h = B2G_HASH16(u8_tolower(buf[pos - 1]),u8_tolower(buf[pos])); - d = ctx->B2G[h]; - - if (d != 0) { - COUNT(tctx->stat_d0++); - uint32_t j = pos; - uint32_t first = pos - (ctx->m - B2G_Q + 1); - - do { - j = j - 1; - - if (d >= (uint32_t)(1 << (ctx->m - 1))) { - if (j > first) pos = j; - else { - /* get our patterns from the hash */ - h = B2G_HASH16(u8_tolower(buf[j + ctx->m - 2]),u8_tolower(buf[j + ctx->m - 1])); - - if (ctx->bloom[h] != NULL) { - COUNT(tctx->stat_pminlen_calls++); - COUNT(tctx->stat_pminlen_total+=ctx->pminlen[h]); - - if ((buflen - j) < ctx->pminlen[h]) { - goto skip_loop; - } else { - COUNT(tctx->stat_bloom_calls++); - - if (BloomFilterTest(ctx->bloom[h], buf+j, ctx->pminlen[h]) == 0) { - COUNT(tctx->stat_bloom_hits++); - - SCLogDebug("Bloom: %p, buflen %" PRIu32 ", pos %" PRIu32 ", p_min_len %" PRIu32 "", - ctx->bloom[h], buflen, pos, ctx->pminlen[h]); - goto skip_loop; - } - } - } - - B2gPattern *hi = ctx->hash[h], *thi; - for (thi = hi; thi != NULL; thi = thi->next) { - COUNT(tctx->stat_d0_hashloop++); - if ((buflen - j) < thi->len) { - continue; - } - - if (thi->flags & MPM_PATTERN_FLAG_NOCASE) { - - //if (memcmp_lowercase(thi->ci, buf+j, thi->len) == 0) { - if (SCMemcmpLowercase(thi->ci, buf+j, thi->len) == 0) { -#ifdef PRINTMATCH - printf("CI Exact match: "); prt(p->ci, p->len); printf("\n"); -#endif - COUNT(tctx->stat_loop_match++); - - matches += MpmVerifyMatch(mpm_thread_ctx, pmq, thi->id, - bitarray, thi->sids, thi->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } else { - if (SCMemcmp(thi->cs, buf+j, thi->len) == 0) { - //if (memcmp(thi->cs, buf+j, thi->len) == 0) { -#ifdef PRINTMATCH - printf("CS Exact match: "); prt(p->cs, p->len); printf("\n"); -#endif - COUNT(tctx->stat_loop_match++); - - matches += MpmVerifyMatch(mpm_thread_ctx, pmq, thi->id, - bitarray, thi->sids, thi->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } - } -skip_loop: - SCLogDebug("skipped"); - //SCLogDebug("output at pos %" PRIu32 ": ", j); prt(buf + (j), ctx->m); printf("\n"); - ; - } - } - - if (j == 0) { - break; - } - - h = B2G_HASH16(u8_tolower(buf[j - 1]),u8_tolower(buf[j])); - d = (d << 1) & ctx->B2G[h]; - } while (d != 0); - } - COUNT(tctx->stat_num_shift++); - COUNT(tctx->stat_total_shift += (ctx->m - B2G_Q + 1)); - pos = pos + ctx->m - B2G_Q + 1; - - SCLogDebug("pos %"PRIu32"", pos); - } - - SCLogDebug("matches %"PRIu32"", matches); - return matches; -} - -uint32_t B2gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; -#ifdef B2G_COUNTERS - B2gThreadCtx *tctx = (B2gThreadCtx *)mpm_thread_ctx->ctx; -#endif - uint32_t pos = 0, matches = 0; - B2G_TYPE d; - uint32_t j; - - COUNT(tctx->stat_calls++); - COUNT(tctx->stat_m_total+=ctx->m); - - if (buflen < ctx->m) - return 0; - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (pos <= (buflen - ctx->m)) { - j = ctx->m - 1; - d = ~0; - - do { - uint16_t h = B2G_HASH16(u8_tolower(buf[pos + j - 1]),u8_tolower(buf[pos + j])); - d = ((d << 1) & ctx->B2G[h]); - j = j - 1; - } while (d != 0 && j != 0); - - /* (partial) match, move on to verification */ - if (d != 0) { - COUNT(tctx->stat_d0++); - //printf("output at pos %" PRIu32 ": ", pos); prt(buf + pos, ctx->m); printf("\n"); - - /* get our patterns from the hash */ - uint16_t h = B2G_HASH16(u8_tolower(buf[pos + ctx->m - 2]),u8_tolower(buf[pos + ctx->m - 1])); - - if (ctx->bloom[h] != NULL) { - COUNT(tctx->stat_pminlen_calls++); - COUNT(tctx->stat_pminlen_total+=ctx->pminlen[h]); - - if ((buflen - pos) < ctx->pminlen[h]) { - goto skip_loop; - } else { - COUNT(tctx->stat_bloom_calls++); - - if (BloomFilterTest(ctx->bloom[h], buf+pos, ctx->pminlen[h]) == 0) { - COUNT(tctx->stat_bloom_hits++); - - //printf("Bloom: %p, buflen %" PRIu32 ", pos %" PRIu32 ", p_min_len %" PRIu32 "\n", ctx->bloom[h], buflen, pos, ctx->pminlen[h]); - goto skip_loop; - } - } - } - - B2gPattern *hi = ctx->hash[h], *thi; - for (thi = hi; thi != NULL; thi = thi->next) { - COUNT(tctx->stat_d0_hashloop++); - //B2gPattern *p = ctx->parray[thi->idx]; - - if (buflen - pos < thi->len) - continue; - - if (thi->flags & MPM_PATTERN_FLAG_NOCASE) { - - if (SCMemcmpLowercase(thi->ci, buf+pos, thi->len) == 0) { - COUNT(tctx->stat_loop_match++); - - matches += MpmVerifyMatch(mpm_thread_ctx, pmq, thi->id, - bitarray, thi->sids, thi->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } else { - if (SCMemcmp(thi->cs, buf+pos, thi->len) == 0) { - COUNT(tctx->stat_loop_match++); - - matches += MpmVerifyMatch(mpm_thread_ctx, pmq, thi->id, - bitarray, thi->sids, thi->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } - } -skip_loop: - //pos = pos + ctx->s0; - pos = pos + 1; - } else { - COUNT(tctx->stat_num_shift++); - COUNT(tctx->stat_total_shift += (j + 1)); - - pos = pos + j + 1; - } - } - - //printf("Total matches %" PRIu32 "\n", matches); - return matches; -} - -#ifdef B2G_SEARCH2 -uint32_t B2gSearch2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - uint8_t *bufmin = buf; - uint8_t *bufend = buf + buflen - 1; - uint32_t cnt = 0; - B2gPattern *p; - B2gPattern *thi, *hi; - - if (buflen < 2) - return 0; - - //printf("BUF "); prt(buf,buflen); printf("\n"); - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - uint8_t h8 = u8_tolower(*buf); - hi = &ctx->hash1[h8]; - - if (hi->flags & MPM_PATTERN_ONE_BYTE) { - for (thi = hi; thi != NULL; thi = thi->next) { - p = ctx->parray[thi->idx]; - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (h8 == p->ci[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, - bitarray, thi->sids, thi->sids_size); - } - } else { - if (*buf == p->cs[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, - bitarray, thi->sids, thi->sids_size); - } - } - } - } - - /* save one conversion by reusing h8 */ - uint16_t h16 = B2G_HASH16(h8, u8_tolower(*(buf+1))); - hi = ctx->hash2[h16]; - - for (thi = hi; thi != NULL; thi = thi->next) { - p = ctx->parray[thi->idx]; - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (h8 == p->ci[0] && u8_tolower(*(buf+1)) == p->ci[1]) { - //printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n"); -// for (em = p->em; em; em = em->next) { - if (MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size)) - cnt++; -// } - } - } else { - if (*buf == p->cs[0] && *(buf+1) == p->cs[1]) { - //printf("CS Exact match: "); prt(p->cs, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n"); -// for (em = p->em; em; em = em->next) { - if (MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size)) - cnt++; -// } - } - } - } - buf += 1; - } - - //printf("B2gSearch2: after 2byte cnt %" PRIu32 "\n", cnt); - if (ctx->pat_x_cnt > 0) { - /* Pass bufmin on because buf no longer points to the - * start of the buffer. */ - cnt += ctx->MBSearch(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen); - //printf("B2gSearch1: after 2+byte cnt %" PRIu32 "\n", cnt); - } - return cnt; -} -#endif - -uint32_t B2gSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - SCEnter(); - - B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; - uint8_t *bufmin = buf; - uint8_t *bufend = buf + buflen - 1; - uint32_t cnt = 0; -// B2gPattern *p; - B2gPattern *thi, *hi; - - if (buflen == 0) - SCReturnUInt(0); - - //printf("BUF "); prt(buf,buflen); printf("\n"); - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - uint8_t h = u8_tolower(*buf); - hi = &ctx->hash1[h]; - - for (thi = hi; thi != NULL; thi = thi->next) { - if (hi->flags & MPM_PATTERN_ONE_BYTE) { - if (thi->len != 1) - continue; - - if (thi->flags & MPM_PATTERN_FLAG_NOCASE) { - if (u8_tolower(*buf) == thi->ci[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, thi->id, bitarray, thi->sids, thi->sids_size); - } - } else { - if (*buf == thi->cs[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, thi->id, bitarray, thi->sids, thi->sids_size); - } - } - } - } - buf += 1; - } - - //printf("B2gSearch1: after 1byte cnt %" PRIu32 "\n", cnt); -#ifdef B2G_SEARCH2 - if (ctx->pat_2_cnt) { - /* Pass bufmin on because buf no longer points to the - * start of the buffer. */ - cnt += ctx->MBSearch2(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen); - //printf("B2gSearch1: after 2+byte cnt %" PRIu32 "\n", cnt); - } else -#endif - if (ctx->pat_x_cnt) { - cnt += ctx->MBSearch(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen); - } - SCReturnUInt(cnt); -} - -/* - * TESTS - */ - -#ifdef UNITTESTS -static int B2gTestInit01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - - if (ctx->m == 4) - result = 1; - else - printf("4 != %" PRIu32 " ", ctx->m); - - B2gDestroyCtx(&mpm_ctx); - return result; -} - -#if 0 -static int B2gTestS0Init01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 4) - result = 1; - else - printf("4 != %" PRIu32 " ", ctx->s0); - - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestS0Init02 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"cdef", 4, 0, 0, 1, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 2) - result = 1; - else - printf("2 != %" PRIu32 " ", ctx->s0); - - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestS0Init03 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 1) - result = 1; - else - printf("1 != %" PRIu32 " ", ctx->s0); - - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestS0Init04 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abab", 4, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 2) - result = 1; - else - printf("2 != %" PRIu32 " ", ctx->s0); - - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestS0Init05 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcab", 5, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 3) - result = 1; - else - printf("3 != %" PRIu32 " ", ctx->s0); - - B2gDestroyCtx(&mpm_ctx); - return result; -} -#endif - -static int B2gTestSearch01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch02 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abce", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch03 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghj", 4, 0, 0, 2, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -/* test patterns longer than 'm'. M is 4 here. */ -static int B2gTestSearch04 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdegh", 6, 0, 0, 1, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -/* case insensitive test patterns longer than 'm'. M is 4 here. */ -static int B2gTestSearch05 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); /* 1 match */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch05a (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); /* 1 match */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abCD", 4, 0, 0, 3, 0, 0); /* no match */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"abcD", 4, 0, 0, 4, 0, 0); /* 1 match */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"abCd", 4, 0, 0, 5, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 6 /* 6 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 5) - result = 1; - else - printf("5 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch06 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcd", 4); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch07 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0, 0); /* 1 */ - /* total matches: 135 */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 6 /* 6 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30); - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch08 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"a", 1); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch09 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ab", 2, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"ab", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch10 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - char *buf = "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789" - "abcdefgh" - "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789"; - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch11 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2 /* 2 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghijklmnopqrstuvwxyz", 26); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch12 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"wxyz", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"vwxyz", 5, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2 /* 2 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghijklmnopqrstuvwxyz", 26); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch13 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefghijklmnopqrstuvwxyzABCD", 30, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghijklmnopqrstuvwxyzABCD", 30); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch14 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefghijklmnopqrstuvwxyzABCDE", 31, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghijklmnopqrstuvwxyzABCDE", 31); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch15 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefghijklmnopqrstuvwxyzABCDEF", 32, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghijklmnopqrstuvwxyzABCDEF", 32); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch16 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefghijklmnopqrstuvwxyzABC", 29, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghijklmnopqrstuvwxyzABC", 29); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch17 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefghijklmnopqrstuvwxyzAB", 28, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghijklmnopqrstuvwxyzAB", 28); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch18 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde""fghij""klmno""pqrst""uvwxy""z", 26, 0, 0, 0, 0, 0); /* 1 match */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcde""fghij""klmno""pqrst""uvwxy""z", 26); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch19 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 0, 0, 0); /* 1 */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch20 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA", 32, 0, 0, 0, 0, 0); /* 1 */ - //MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 32, 0, 0, 0, 0, 0); /* 1 */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 patterns */); - - //uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 32); - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA", 32); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} - -static int B2gTestSearch21 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); /* 1 */ - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AA", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - return result; -} -#endif /* UNITTESTS */ - -#if 0 -static int B2gTestSearchXX (void) -{ - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B2G); - B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx; - - FILE *fp = fopen("/usr/share/dict/words", "r"); - if (fp == NULL) - exit(1); - - char *word; - char line[128]; - int w = 0; - int w_max = 4000; - - while((word = fgets(line, sizeof(line), fp)) != NULL) { - word[strlen(word) - 1] = '\0'; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)word, strlen(word), 0, 0, (uint32_t)w, 0, 0); - - w++; - - if (w_max == w) - break; - } - - B2gPreparePatterns(&mpm_ctx); - B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 patterns */); - - char *text = "Yes this is a text, it is not very long. But, it is still sufficient for testing our search! " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "flkflkjjoijda893ur9r89h98hf9shflj;adm.,amnd,mna,mndabdayyugeq9e8u0q90-euajd;lsaldakljdlkajdl" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "we're adding a lot more text lines etc." - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "dlajd01438798749023749792739479ye9q8eu3291739847983274987e928u928eu98u3298eu982u938383888888 " - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" - "Bjdhfahflkahsf;phf[hfihasfkhsfkjhalhflkafljhfkhakhfkahfkahfkjhdkffkjhafkhafkjakjfhkjahf;aj;jh"; - uint32_t len = strlen(text) - 1; - - int i; - uint32_t cnt; - for (i = 0; i < 100; i++) { - cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)text, len); - } - - printf("cnt %u ", cnt); - - B2gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B2gDestroyCtx(&mpm_ctx); - fclose(fp); - - return 1; -} -#endif - -void B2gRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("B2gTestInit01", B2gTestInit01, 1); -/* - UtRegisterTest("B2gTestS0Init01", B2gTestS0Init01, 1); - UtRegisterTest("B2gTestS0Init02", B2gTestS0Init02, 1); - UtRegisterTest("B2gTestS0Init03", B2gTestS0Init03, 1); - UtRegisterTest("B2gTestS0Init04", B2gTestS0Init04, 1); - UtRegisterTest("B2gTestS0Init05", B2gTestS0Init05, 1); -*/ - UtRegisterTest("B2gTestSearch01", B2gTestSearch01, 1); - UtRegisterTest("B2gTestSearch02", B2gTestSearch02, 1); - UtRegisterTest("B2gTestSearch03", B2gTestSearch03, 1); - UtRegisterTest("B2gTestSearch04", B2gTestSearch04, 1); - UtRegisterTest("B2gTestSearch05", B2gTestSearch05, 1); - UtRegisterTest("B2gTestSearch05a", B2gTestSearch05a, 1); - UtRegisterTest("B2gTestSearch06", B2gTestSearch06, 1); - UtRegisterTest("B2gTestSearch07", B2gTestSearch07, 1); - UtRegisterTest("B2gTestSearch08", B2gTestSearch08, 1); - UtRegisterTest("B2gTestSearch09", B2gTestSearch09, 1); - UtRegisterTest("B2gTestSearch10", B2gTestSearch10, 1); - UtRegisterTest("B2gTestSearch11", B2gTestSearch11, 1); - UtRegisterTest("B2gTestSearch12", B2gTestSearch12, 1); - UtRegisterTest("B2gTestSearch13", B2gTestSearch13, 1); - UtRegisterTest("B2gTestSearch14", B2gTestSearch14, 1); - UtRegisterTest("B2gTestSearch15", B2gTestSearch15, 1); - UtRegisterTest("B2gTestSearch16", B2gTestSearch16, 1); - UtRegisterTest("B2gTestSearch17", B2gTestSearch17, 1); - UtRegisterTest("B2gTestSearch18", B2gTestSearch18, 1); - UtRegisterTest("B2gTestSearch19", B2gTestSearch19, 1); - UtRegisterTest("B2gTestSearch20", B2gTestSearch20, 1); - UtRegisterTest("B2gTestSearch21", B2gTestSearch21, 1); -// UtRegisterTest("B2gTestSearchXX", B2gTestSearchXX, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/util-mpm-b2g.h b/framework/src/suricata/src/util-mpm-b2g.h deleted file mode 100644 index b3b59b09..00000000 --- a/framework/src/suricata/src/util-mpm-b2g.h +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_MPM_B2G_H__ -#define __UTIL_MPM_B2G_H__ - -#include "util-mpm.h" -#include "util-bloomfilter.h" - -#define B2G_HASHSHIFT_MAX 8 -#define B2G_HASHSHIFT_HIGHER 7 -#define B2G_HASHSHIFT_HIGH 6 -#define B2G_HASHSHIFT_MEDIUM 5 -#define B2G_HASHSHIFT_LOW 4 -#define B2G_HASHSHIFT_LOWEST 3 - -//#define B2G_TYPE uint64_t -#define B2G_TYPE uint32_t -//#define B2G_TYPE uint16_t -//#define B2G_TYPE uint8_t -//#define B2G_WORD_SIZE 64 -#define B2G_WORD_SIZE 32 -//#define B2G_WORD_SIZE 16 -//#define B2G_WORD_SIZE 8 - -#define B2G_Q 2 - -#define B2G_SEARCHFUNC B2gSearchBNDMq -//#define B2G_SEARCHFUNC B2gSearch - -//#define B2G_SEARCH2 -//#define B2G_COUNTERS - -typedef struct B2gPattern_ { - uint16_t len; /**< \todo we're limited to 32/64 byte lengths, uint8_t would be fine here */ - uint8_t flags; - uint8_t pad0; - uint32_t id; - uint8_t *original_pat; - uint8_t *ci; /* case INsensitive */ - uint8_t *cs; /* case sensitive */ - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; - - struct B2gPattern_ *next; -} B2gPattern; - -typedef struct B2gCtx_ { - B2G_TYPE *B2G; - B2G_TYPE m; - BloomFilter **bloom; - uint8_t *pminlen; /* array containing the minimal length - of the patters in a hash bucket. Used - for the BloomFilter. */ - /* pattern arrays */ - B2gPattern **parray; - - uint16_t pat_1_cnt; -#ifdef B2G_SEARCH2 - uint16_t pat_2_cnt; -#endif - uint16_t pat_x_cnt; - - uint32_t hash_size; - B2gPattern **hash; - B2gPattern hash1[256]; -#ifdef B2G_SEARCH2 - B2gHashItem **hash2; -#endif - - /* hash used during ctx initialization */ - B2gPattern **init_hash; - - uint8_t s0; - - /* we store our own multi byte search func ptr here for B2gSearch1 */ - uint32_t (*Search)(struct MpmCtx_ *, struct MpmThreadCtx_ *, PatternMatcherQueue *, uint8_t *, uint16_t); - - /* we store our own multi byte search func ptr here for B2gSearch1 */ - uint32_t (*MBSearch2)(struct MpmCtx_ *, struct MpmThreadCtx_ *, PatternMatcherQueue *, uint8_t *, uint16_t); - uint32_t (*MBSearch)(struct MpmCtx_ *, struct MpmThreadCtx_ *, PatternMatcherQueue *, uint8_t *, uint16_t); -} B2gCtx; - -typedef struct B2gThreadCtx_ { -#ifdef B2G_COUNTERS - uint32_t stat_pminlen_calls; - uint32_t stat_pminlen_total; - uint32_t stat_bloom_calls; - uint32_t stat_bloom_hits; - uint32_t stat_calls; - uint32_t stat_m_total; - uint32_t stat_d0; - uint32_t stat_d0_hashloop; - uint32_t stat_loop_match; - uint32_t stat_loop_no_match; - uint32_t stat_num_shift; - uint32_t stat_total_shift; -#endif /* B2G_COUNTERS */ -} B2gThreadCtx; - -void MpmB2gRegister(void); - - -#endif - diff --git a/framework/src/suricata/src/util-mpm-b3g.c b/framework/src/suricata/src/util-mpm-b3g.c deleted file mode 100644 index bc74bc20..00000000 --- a/framework/src/suricata/src/util-mpm-b3g.c +++ /dev/null @@ -1,1807 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * 3 gram implementation of the (S)BNDMq pattern matching algorithm. - * - * Ideas: - * - B3g does a full match in the search of up to 'm' characters, - * in case of a case insensitive search we could say it's match if - * the pattern is of len 'm' or just compare the rest of the chars. - * - * \todo Try to get the S0 calculation right. - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "util-bloomfilter.h" -#include "util-mpm-b3g.h" -#include "util-unittest.h" -#include "conf.h" -#include "util-debug.h" -#include "util-memcpy.h" - -#define INIT_HASH_SIZE 65536 - -#ifdef B3G_COUNTERS -#define COUNT(counter) \ - (counter) -#else -#define COUNT(counter) -#endif /* B3G_COUNTERS */ - -static uint32_t b3g_hash_size = 0; -static uint32_t b3g_bloom_size = 0; -static uint8_t b3g_hash_shift = 0; -static uint8_t b3g_hash_shift2 = 0; -static void *b3g_func; - -#define B3G_HASH(a,b,c) (((a) << b3g_hash_shift) | (b) << (b3g_hash_shift2) |(c)) - -void B3gInitCtx (MpmCtx *); -void B3gThreadInitCtx(MpmCtx *, MpmThreadCtx *, uint32_t); -void B3gDestroyCtx(MpmCtx *); -void B3gThreadDestroyCtx(MpmCtx *, MpmThreadCtx *); -int B3gAddPatternCI(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); -int B3gAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); -int B3gPreparePatterns(MpmCtx *); -uint32_t B3gSearchWrap(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, uint8_t *, uint16_t); -uint32_t B3gSearch1(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, uint8_t *, uint16_t); -uint32_t B3gSearch2(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, uint8_t *, uint16_t); -uint32_t B3gSearch12(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, uint8_t *, uint16_t); -uint32_t B3gSearch(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, uint8_t *, uint16_t); -uint32_t B3gSearchBNDMq(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, uint8_t *, uint16_t); -void B3gPrintInfo(MpmCtx *); -void B3gPrintSearchStats(MpmThreadCtx *); -void B3gRegisterTests(void); - -/** \todo XXX Unused??? */ -#if 0 -static void prt (uint8_t *buf, uint16_t buflen) -{ - uint16_t i; - - for (i = 0; i < buflen; i++) { - if (isprint(buf[i])) printf("%c", buf[i]); - else printf("\\x%" PRIX32, buf[i]); - } - //printf("\n"); -} -#endif - -void B3gPrintInfo(MpmCtx *mpm_ctx) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - - printf("MPM B3g Information:\n"); - printf("Memory allocs: %" PRIu32 "\n", mpm_ctx->memory_cnt); - printf("Memory alloced: %" PRIu32 "\n", mpm_ctx->memory_size); - printf(" Sizeofs:\n"); - printf(" MpmCtx %" PRIuMAX "\n", (uintmax_t)sizeof(MpmCtx)); - printf(" B3gCtx: %" PRIuMAX "\n", (uintmax_t)sizeof(B3gCtx)); - printf(" B3gPattern %" PRIuMAX "\n", (uintmax_t)sizeof(B3gPattern)); - printf(" B3gHashItem %" PRIuMAX "\n", (uintmax_t)sizeof(B3gHashItem)); - printf("Unique Patterns: %" PRIu32 "\n", mpm_ctx->pattern_cnt); - printf("Smallest: %" PRIu32 "\n", mpm_ctx->minlen); - printf("Largest: %" PRIu32 "\n", mpm_ctx->maxlen); - printf("Hash size: %" PRIu32 "\n", ctx->hash_size); - printf("\n"); -} - -static inline B3gPattern *B3gAllocPattern(MpmCtx *mpm_ctx) -{ - B3gPattern *p = SCMalloc(sizeof(B3gPattern)); - if (unlikely(p == NULL)) - return NULL; - memset(p,0,sizeof(B3gPattern)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(B3gPattern); - return p; -} - -static inline B3gHashItem * -B3gAllocHashItem(MpmCtx *mpm_ctx) -{ - B3gHashItem *hi = SCMalloc(sizeof(B3gHashItem)); - if (unlikely(hi == NULL)) - return NULL; - memset(hi,0,sizeof(B3gHashItem)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(B3gHashItem); - return hi; -} - -static void B3gHashFree(MpmCtx *mpm_ctx, B3gHashItem *hi) -{ - if (hi == NULL) - return; - - B3gHashItem *t = hi->nxt; - B3gHashFree(mpm_ctx, t); - - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(B3gHashItem); - SCFree(hi); -} - -/* - * INIT HASH START - */ -static inline uint32_t B3gInitHash(B3gPattern *p) -{ - uint32_t hash = p->len * p->cs[0]; - if (p->len > 1) - hash += p->cs[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline uint32_t B3gInitHashRaw(uint8_t *pat, uint16_t patlen) -{ - uint32_t hash = patlen * pat[0]; - if (patlen > 1) - hash += pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline int B3gInitHashAdd(B3gCtx *ctx, B3gPattern *p) -{ - uint32_t hash = B3gInitHash(p); - - //printf("B3gInitHashAdd: %" PRIu32 "\n", hash); - - if (ctx->init_hash[hash] == NULL) { - ctx->init_hash[hash] = p; - //printf("B3gInitHashAdd: hash %" PRIu32 ", head %p\n", hash, ctx->init_hash[hash]); - return 0; - } - - B3gPattern *tt = NULL; - B3gPattern *t = ctx->init_hash[hash]; - - /* get the list tail */ - do { - tt = t; - t = t->next; - } while (t != NULL); - - tt->next = p; - //printf("B3gInitHashAdd: hash %" PRIu32 ", head %p\n", hash, ctx->init_hash[hash]); - - return 0; -} - -static inline int B3gCmpPattern(B3gPattern *p, uint8_t *pat, uint16_t patlen, char flags); - -static inline B3gPattern *B3gInitHashLookup(B3gCtx *ctx, uint8_t *pat, uint16_t patlen, char flags) -{ - uint32_t hash = B3gInitHashRaw(pat,patlen); - - //printf("B3gInitHashLookup: %" PRIu32 ", head %p\n", hash, ctx->init_hash[hash]); - - if (ctx->init_hash[hash] == NULL) { - return NULL; - } - - B3gPattern *t = ctx->init_hash[hash]; - for ( ; t != NULL; t = t->next) { - if (B3gCmpPattern(t,pat,patlen,flags) == 1) - return t; - } - - return NULL; -} - -static inline int B3gCmpPattern(B3gPattern *p, uint8_t *pat, uint16_t patlen, char flags) -{ - if (p->len != patlen) - return 0; - - if (p->flags != flags) - return 0; - - if (memcmp(p->cs, pat, patlen) != 0) - return 0; - - return 1; -} - -/* - * INIT HASH END - */ - -void B3gFreePattern(MpmCtx *mpm_ctx, B3gPattern *p) -{ - if (p && p->cs && p->cs != p->ci) { - SCFree(p->cs); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p && p->ci) { - SCFree(p->ci); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p && p->sids) { - SCFree(p->sids); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->sids_size * sizeof(SigIntId); - } - - if (p) { - SCFree(p); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(B3gPattern); - } -} - -/* B3gAddPattern - * - * pat: ptr to the pattern - * patlen: length of the pattern - * nocase: nocase flag: 1 enabled, 0 disable - * pid: pattern id - * sid: signature id (internal id) - */ -static int B3gAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, uint32_t sid, uint8_t flags) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - - if (patlen == 0) - return 0; - - /* get a memory piece */ - B3gPattern *p = B3gInitHashLookup(ctx, pat, patlen, flags); - if (p == NULL) { - p = B3gAllocPattern(mpm_ctx); - if (p == NULL) - goto error; - - p->len = patlen; - p->flags = flags; - p->id = pid; - - /* setup the case insensitive part of the pattern */ - p->ci = SCMalloc(patlen); - if (p->ci == NULL) - goto error; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy_tolower(p->ci, pat, patlen); - - /* setup the case sensitive part of the pattern */ - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - /* nocase means no difference between cs and ci */ - p->cs = p->ci; - } else { - if (memcmp(p->ci,pat,p->len) == 0) { - /* no diff between cs and ci: pat is lowercase */ - p->cs = p->ci; - } else { - p->cs = SCMalloc(patlen); - if (p->cs == NULL) - goto error; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->cs, pat, patlen); - } - } - - //printf("B3gAddPattern: ci \""); prt(p->ci,p->len); - //printf("\" cs \""); prt(p->cs,p->len); - //printf("\" prefix_ci %" PRIu32 ", prefix_cs %" PRIu32 "\n", p->prefix_ci, p->prefix_cs); - - p->sids_size = 1; - p->sids = SCMalloc(p->sids_size * sizeof(SigIntId)); - BUG_ON(p->sids == NULL); - p->sids[0] = sid; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SigIntId); - - /* put in the pattern hash */ - B3gInitHashAdd(ctx, p); - - if (mpm_ctx->pattern_cnt == 65535) { - printf("Max search words reached\n"); - exit(1); - } - mpm_ctx->pattern_cnt++; - - if (mpm_ctx->maxlen < patlen) mpm_ctx->maxlen = patlen; - if (mpm_ctx->minlen == 0) mpm_ctx->minlen = patlen; - else if (mpm_ctx->minlen > patlen) mpm_ctx->minlen = patlen; - } else { - /* Multiple sids for the same pid, so keep an array of sids. */ - - /* TODO figure out how we can be called multiple times for the - * same CTX with the same sid */ - int found = 0; - uint32_t x = 0; - for (x = 0; x < p->sids_size; x++) { - if (p->sids[x] == sid) { - found = 1; - break; - } - } - if (!found) { - SigIntId *sids = SCRealloc(p->sids, (sizeof(SigIntId) * (p->sids_size + 1))); - BUG_ON(sids == NULL); - p->sids = sids; - p->sids[p->sids_size] = sid; - p->sids_size++; - mpm_ctx->memory_size += sizeof(SigIntId); - } - } - - return 0; - -error: - B3gFreePattern(mpm_ctx, p); - return -1; -} - -int B3gAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags) -{ - flags |= MPM_PATTERN_FLAG_NOCASE; - return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -int B3gAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags) -{ - return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -static uint32_t B3gBloomHash(void *data, uint16_t datalen, uint8_t iter, uint32_t hash_size) -{ - uint8_t *d = (uint8_t *)data; - uint16_t i; - uint32_t hash = (uint32_t)u8_tolower(*d); - - for (i = 1; i < datalen; i++) { - d++; - hash += (u8_tolower(*d)) ^ i; - } - hash <<= (iter+1); - - hash %= hash_size; - return hash; -} - -static void B3gPrepareHash(MpmCtx *mpm_ctx) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - uint16_t i; - uint16_t idx = 0; - uint8_t idx8 = 0; - - ctx->hash = (B3gHashItem **)SCMalloc(sizeof(B3gHashItem *) * ctx->hash_size); - if (ctx->hash == NULL) - goto error; - memset(ctx->hash, 0, sizeof(B3gHashItem *) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(B3gHashItem *) * ctx->hash_size); - - /* 2 byte pattern hash */ - ctx->hash2 = (B3gHashItem **)SCMalloc(sizeof(B3gHashItem *) * ctx->hash_size); - if (ctx->hash2 == NULL) - goto error; - memset(ctx->hash2, 0, sizeof(B3gHashItem *) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(B3gHashItem *) * ctx->hash_size); - - /* alloc the pminlen array */ - ctx->pminlen = (uint8_t *)SCMalloc(sizeof(uint8_t) * ctx->hash_size); - if (ctx->pminlen == NULL) - goto error; - memset(ctx->pminlen, 0, sizeof(uint8_t) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(uint8_t) * ctx->hash_size); - - for (i = 0; i < mpm_ctx->pattern_cnt; i++) - { - if(ctx->parray[i]->len == 1) { - idx8 = (uint8_t)ctx->parray[i]->ci[0]; - if (ctx->hash1[idx8].flags == 0) { - ctx->hash1[idx8].idx = i; - ctx->hash1[idx8].flags |= 0x01; - } else { - B3gHashItem *hi = B3gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= 0x01; - - /* Append this HashItem to the list */ - B3gHashItem *thi = &ctx->hash1[idx8]; - while (thi->nxt) thi = thi->nxt; - thi->nxt = hi; - } - ctx->pat_1_cnt++; - } else if(ctx->parray[i]->len == 2) { - idx = (uint16_t)(ctx->parray[i]->ci[0] << b3g_hash_shift | ctx->parray[i]->ci[1]); - if (ctx->hash2[idx] == NULL) { - B3gHashItem *hi = B3gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= 0x01; - - ctx->hash2[idx] = hi; - } else { - B3gHashItem *hi = B3gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= 0x01; - - /* Append this HashItem to the list */ - B3gHashItem *thi = ctx->hash2[idx]; - while (thi->nxt) thi = thi->nxt; - thi->nxt = hi; - } - ctx->pat_2_cnt++; - } else { - idx = B3G_HASH(ctx->parray[i]->ci[ctx->m - 3], ctx->parray[i]->ci[ctx->m - 2], ctx->parray[i]->ci[ctx->m - 1]); - //printf("idx %" PRIu32 ", %c.%c.%c\n", idx, ctx->parray[i]->ci[ctx->m - 3], ctx->parray[i]->ci[ctx->m - 2], ctx->parray[i]->ci[ctx->m - 1]); - - if (ctx->hash[idx] == NULL) { - B3gHashItem *hi = B3gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= 0x01; - ctx->pminlen[idx] = ctx->parray[i]->len; - - ctx->hash[idx] = hi; - } else { - B3gHashItem *hi = B3gAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= 0x01; - - if (ctx->parray[i]->len < ctx->pminlen[idx]) - ctx->pminlen[idx] = ctx->parray[i]->len; - - /* Append this HashItem to the list */ - B3gHashItem *thi = ctx->hash[idx]; - while (thi->nxt) thi = thi->nxt; - thi->nxt = hi; - } - ctx->pat_x_cnt++; - } - } - - /* alloc the bloom array */ - ctx->bloom = (BloomFilter **)SCMalloc(sizeof(BloomFilter *) * ctx->hash_size); - if (ctx->bloom == NULL) - goto error; - memset(ctx->bloom, 0, sizeof(BloomFilter *) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(BloomFilter *) * ctx->hash_size); - - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - B3gHashItem *hi = ctx->hash[h]; - if (hi == NULL) - continue; - - ctx->bloom[h] = BloomFilterInit(b3g_bloom_size, 2, B3gBloomHash); - if (ctx->bloom[h] == NULL) - continue; - - mpm_ctx->memory_cnt += BloomFilterMemoryCnt(ctx->bloom[h]); - mpm_ctx->memory_size += BloomFilterMemorySize(ctx->bloom[h]); - - if (ctx->pminlen[h] > 8) - ctx->pminlen[h] = 8; - - B3gHashItem *thi = hi; - do { - BloomFilterAdd(ctx->bloom[h], ctx->parray[thi->idx]->ci, ctx->pminlen[h]); - thi = thi->nxt; - } while (thi != NULL); - } - - return; -error: - return; -} - -int B3gBuildMatchArray(MpmCtx *mpm_ctx) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - - ctx->B3G = SCMalloc(sizeof(B3G_TYPE) * ctx->hash_size); - if (ctx->B3G == NULL) - return -1; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(B3G_TYPE) * ctx->hash_size); - - memset(ctx->B3G,0, b3g_hash_size * sizeof(B3G_TYPE)); - - uint32_t j; - uint32_t a; - - /* fill the match array */ - for (j = 0; j <= (ctx->m - B3G_Q); j++) { - for (a = 0; a < mpm_ctx->pattern_cnt; a++) { - if (ctx->parray[a]->len < ctx->m) - continue; - - uint16_t h = B3G_HASH(u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1]), u8_tolower(ctx->parray[a]->ci[j+2])); -//printf("B3gBuildMatchArray: h %" PRIu32 ", %c.%c.%c\n", h, u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1]), u8_tolower(ctx->parray[a]->ci[j+2])); - ctx->B3G[h] = ctx->B3G[h] | (1 << (ctx->m - j)); - } - } - - ctx->s0 = 1; - return 0; -} - -int B3gPreparePatterns(MpmCtx *mpm_ctx) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - - /* alloc the pattern array */ - ctx->parray = (B3gPattern **)SCMalloc(mpm_ctx->pattern_cnt * sizeof(B3gPattern *)); - if (ctx->parray == NULL) - goto error; - memset(ctx->parray, 0, mpm_ctx->pattern_cnt * sizeof(B3gPattern *)); - //printf("mpm_ctx %p, parray %p\n", mpm_ctx,ctx->parray); - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (mpm_ctx->pattern_cnt * sizeof(B3gPattern *)); - - /* populate it with the patterns in the hash */ - uint32_t i = 0, p = 0; - for (i = 0; i < INIT_HASH_SIZE; i++) { - B3gPattern *node = ctx->init_hash[i], *nnode = NULL; - for ( ; node != NULL; ) { - nnode = node->next; - node->next = NULL; - - ctx->parray[p] = node; - - p++; - node = nnode; - } - } - /* we no longer need the hash, so free it's memory */ - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - - /* set 'm' to the smallest pattern size */ - ctx->m = mpm_ctx->minlen; - - /* make sure 'm' stays in bounds - m can be max WORD_SIZE - 1 */ - if (ctx->m >= B3G_WORD_SIZE) { - ctx->m = B3G_WORD_SIZE - 1; - } - if (ctx->m < 3) ctx->m = 3; - - - ctx->hash_size = b3g_hash_size; - B3gPrepareHash(mpm_ctx); - B3gBuildMatchArray(mpm_ctx); - - if (ctx->pat_1_cnt) { - ctx->Search = B3gSearch1; - if (ctx->pat_2_cnt) { - ctx->Search = B3gSearch12; - ctx->MBSearch = b3g_func; - } - ctx->MBSearch = b3g_func; - } else if (ctx->pat_2_cnt) { - ctx->Search = B3gSearch2; - ctx->MBSearch = b3g_func; - } - - - return 0; -error: - return -1; -} - -void B3gPrintSearchStats(MpmThreadCtx *mpm_thread_ctx) -{ -#ifdef B3G_COUNTERS - B3gThreadCtx *tctx = (B3gThreadCtx *)mpm_thread_ctx->ctx; - - printf("B3g Thread Search stats (tctx %p)\n", tctx); - printf("Total calls: %" PRIu32 "\n", tctx->stat_calls); - printf("Avg m/search: %0.2f\n", tctx->stat_calls ? (float)((float)tctx->stat_m_total / (float)tctx->stat_calls) : 0); - printf("D != 0 (possible match): %" PRIu32 "\n", tctx->stat_d0); - printf("Avg hash items per bucket %0.2f (%" PRIu32 ")\n", tctx->stat_d0 ? (float)((float)tctx->stat_d0_hashloop / (float)tctx->stat_d0) : 0, tctx->stat_d0_hashloop); - printf("Loop match: %" PRIu32 "\n", tctx->stat_loop_match); - printf("Loop no match: %" PRIu32 "\n", tctx->stat_loop_no_match); - printf("Num shifts: %" PRIu32 "\n", tctx->stat_num_shift); - printf("Total shifts: %" PRIu32 "\n", tctx->stat_total_shift); - printf("Avg shifts: %0.2f\n", tctx->stat_num_shift ? (float)((float)tctx->stat_total_shift / (float)tctx->stat_num_shift) : 0); - printf("Total BloomFilter checks: %" PRIu32 "\n", tctx->stat_bloom_calls); - printf("BloomFilter hits: %0.4f%% (%" PRIu32 ")\n", tctx->stat_bloom_calls ? (float)((float)((float)tctx->stat_bloom_hits / (float)tctx->stat_bloom_calls)*(float)100) : 0, tctx->stat_bloom_hits); - printf("Avg pminlen: %0.2f\n\n", tctx->stat_pminlen_calls ? (float)((float)tctx->stat_pminlen_total / (float)tctx->stat_pminlen_calls) : 0); -#endif /* B3G_COUNTERS */ -} - -static inline int -memcmp_lowercase(uint8_t *s1, uint8_t *s2, uint16_t n) -{ - size_t i; - - /* check backwards because we already tested the first - * 2 to 4 chars. This way we are more likely to detect - * a miss and thus speed up a little... */ - for (i = n - 1; i; i--) { - if (u8_tolower(*(s2+i)) != s1[i]) - return 1; - } - - return 0; -} - -/** - * \brief Function to get the user defined values for b3g algorithm from the - * config file 'suricata.yaml' - */ -void B3gGetConfig() -{ - ConfNode *b3g_conf; - const char *hash_val = NULL; - const char *bloom_val = NULL; - const char *algo = NULL; - - /* init defaults */ - b3g_hash_size = HASHSIZE_LOW; - b3g_bloom_size = BLOOMSIZE_MEDIUM; - b3g_func = B3G_SEARCHFUNC; - - ConfNode *pm = ConfGetNode("pattern-matcher"); - - if (pm != NULL) { - - TAILQ_FOREACH(b3g_conf, &pm->head, next) { - if (strncmp(b3g_conf->val, "b3g", 3) == 0) { - algo = ConfNodeLookupChildValue(b3g_conf->head.tqh_first, - "algo"); - hash_val = ConfNodeLookupChildValue(b3g_conf->head.tqh_first, - "hash_size"); - bloom_val = ConfNodeLookupChildValue(b3g_conf->head.tqh_first, - "bf_size"); - - if (algo != NULL) { - if (strcmp(algo, "B3gSearch") == 0) { - b3g_func = B3gSearch; - } else if (strcmp(algo, "B3gSearchBNDMq") == 0) { - b3g_func = B3gSearchBNDMq; - } - } - - if (hash_val != NULL) { - b3g_hash_size = MpmGetHashSize(hash_val); - switch (b3g_hash_size) { - case HASHSIZE_LOWEST: - b3g_hash_shift = B3G_HASHSHIFT_LOWEST; - b3g_hash_shift2 = B3G_HASHSHIFT_LOWEST2; - break; - case HASHSIZE_LOW: - b3g_hash_shift = B3G_HASHSHIFT_LOW; - b3g_hash_shift2 = B3G_HASHSHIFT_LOW2; - break; - case HASHSIZE_MEDIUM: - b3g_hash_shift = B3G_HASHSHIFT_MEDIUM; - b3g_hash_shift2 = B3G_HASHSHIFT_MEDIUM2; - break; - case HASHSIZE_HIGH: - b3g_hash_shift = B3G_HASHSHIFT_HIGH; - b3g_hash_shift2 = B3G_HASHSHIFT_HIGH2; - break; - case HASHSIZE_HIGHER: - b3g_hash_shift = B3G_HASHSHIFT_HIGHER; - b3g_hash_shift2 = B3G_HASHSHIFT_HIGHER2; - break; - case HASHSIZE_MAX: - b3g_hash_shift = B3G_HASHSHIFT_MAX; - b3g_hash_shift2 = B3G_HASHSHIFT_MAX2; - break; - } - } - - if (bloom_val != NULL) - b3g_bloom_size = MpmGetBloomSize(bloom_val); - - SCLogDebug("hash size is %"PRIu32" and bloom size is %"PRIu32"", - b3g_hash_size, b3g_bloom_size); - } - } - } -} - -void B3gInitCtx (MpmCtx *mpm_ctx) -{ - //printf("B3gInitCtx: mpm_ctx %p\n", mpm_ctx); - - mpm_ctx->ctx = SCMalloc(sizeof(B3gCtx)); - if (mpm_ctx->ctx == NULL) - return; - - memset(mpm_ctx->ctx, 0, sizeof(B3gCtx)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(B3gCtx); - - /* initialize the hash we use to speed up pattern insertions */ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - ctx->init_hash = SCMalloc(sizeof(B3gPattern *) * INIT_HASH_SIZE); - if (ctx->init_hash == NULL) - return; - - memset(ctx->init_hash, 0, sizeof(B3gPattern *) * INIT_HASH_SIZE); - - /* Initialize the defaults value from the config file. The given check make - sure that we query config file only once for config values */ - if (b3g_hash_size == 0) - B3gGetConfig(); - - /* init default */ - ctx->Search = b3g_func; -} - -void B3gDestroyCtx(MpmCtx *mpm_ctx) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - if (ctx == NULL) - return; - - if (ctx->init_hash) { - SCFree(ctx->init_hash); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (INIT_HASH_SIZE * sizeof(B3gPattern *)); - } - - if (ctx->parray) { - uint32_t i; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - B3gFreePattern(mpm_ctx, ctx->parray[i]); - } - } - - SCFree(ctx->parray); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(B3gPattern)); - } - - if (ctx->B3G) { - SCFree(ctx->B3G); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(B3G_TYPE) * ctx->hash_size); - } - - if (ctx->bloom) { - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - if (ctx->bloom[h] == NULL) - continue; - - mpm_ctx->memory_cnt -= BloomFilterMemoryCnt(ctx->bloom[h]); - mpm_ctx->memory_size -= BloomFilterMemorySize(ctx->bloom[h]); - - BloomFilterFree(ctx->bloom[h]); - } - - SCFree(ctx->bloom); - - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(BloomFilter *) * ctx->hash_size); - } - - if (ctx->hash) { - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - if (ctx->hash[h] == NULL) - continue; - - B3gHashFree(mpm_ctx, ctx->hash[h]); - } - - SCFree(ctx->hash); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(B3gHashItem) * ctx->hash_size); - } - if (ctx->hash2) { - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - if (ctx->hash2[h] == NULL) - continue; - - B3gHashFree(mpm_ctx, ctx->hash2[h]); - } - - SCFree(ctx->hash2); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(B3gHashItem) * ctx->hash_size); - } - - if (ctx->pminlen) { - SCFree(ctx->pminlen); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(uint8_t) * ctx->hash_size); - } - - SCFree(mpm_ctx->ctx); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(B3gCtx); -} - -void B3gThreadInitCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, uint32_t matchsize) -{ - memset(mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - - if (sizeof(B3gThreadCtx) > 0) { /* size can be 0 when optimized */ - mpm_thread_ctx->ctx = SCMalloc(sizeof(B3gThreadCtx)); - if (mpm_thread_ctx->ctx == NULL) - return; - - memset(mpm_thread_ctx->ctx, 0, sizeof(B3gThreadCtx)); - - mpm_thread_ctx->memory_cnt++; - mpm_thread_ctx->memory_size += sizeof(B3gThreadCtx); - } -} - -void B3gThreadDestroyCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx) -{ - B3gThreadCtx *ctx = (B3gThreadCtx *)mpm_thread_ctx->ctx; - - B3gPrintSearchStats(mpm_thread_ctx); - - if (ctx != NULL) { /* can be NULL when optimized */ - mpm_thread_ctx->memory_cnt--; - mpm_thread_ctx->memory_size -= sizeof(B3gThreadCtx); - SCFree(mpm_thread_ctx->ctx); - } -} - -inline uint32_t B3gSearchWrap(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - return ctx->Search(mpm_ctx, mpm_thread_ctx, pmq, buf, buflen); -} - -uint32_t B3gSearchBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; -#ifdef B3G_COUNTERS - B3gThreadCtx *tctx = (B3gThreadCtx *)mpm_thread_ctx->ctx; -#endif - uint32_t pos = ctx->m - B3G_Q + 1, matches = 0; - B3G_TYPE d; - - COUNT(tctx->stat_calls++); - COUNT(tctx->stat_m_total+=ctx->m); - - if (buflen < ctx->m) - return 0; - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (pos <= (uint32_t)(buflen - B3G_Q + 1)) { - uint16_t h = B3G_HASH(u8_tolower(buf[pos - 1]), u8_tolower(buf[pos]),u8_tolower(buf[pos + 1])); - d = ctx->B3G[h]; - - if (d != 0) { - COUNT(tctx->stat_d0++); - uint32_t j = pos; - uint32_t first = pos - (ctx->m - B3G_Q + 1); - - do { - j = j - 1; - if (d >= (uint32_t)(1 << (ctx->m - 1))) { - if (j > first) pos = j; - else { - /* get our patterns from the hash */ - h = B3G_HASH(u8_tolower(buf[j + ctx->m - 3]), u8_tolower(buf[j + ctx->m - 2]),u8_tolower(buf[j + ctx->m - 1])); - - if (ctx->bloom[h] != NULL) { - COUNT(tctx->stat_pminlen_calls++); - COUNT(tctx->stat_pminlen_total+=ctx->pminlen[h]); - - if ((buflen - j) < ctx->pminlen[h]) { - goto skip_loop; - } else { - COUNT(tctx->stat_bloom_calls++); - - if (BloomFilterTest(ctx->bloom[h], buf+j, ctx->pminlen[h]) == 0) { - COUNT(tctx->stat_bloom_hits++); - - //printf("Bloom: %p, buflen %" PRIu32 ", pos %" PRIu32 ", p_min_len %" PRIu32 "\n", ctx->bloom[h], buflen, pos, ctx->pminlen[h]); - goto skip_loop; - } - } - } - - B3gHashItem *hi = ctx->hash[h], *thi; - for (thi = hi; thi != NULL; thi = thi->nxt) { - COUNT(tctx->stat_d0_hashloop++); - B3gPattern *p = ctx->parray[thi->idx]; - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (buflen - j < p->len) - continue; - - if (memcmp_lowercase(p->ci, buf+j, p->len) == 0) { - COUNT(tctx->stat_loop_match++); - - matches += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } else { - if (buflen - j < p->len) - continue; - - if (memcmp(p->cs, buf+j, p->len) == 0) { - COUNT(tctx->stat_loop_match++); - - matches += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } - } -skip_loop: - //printf("output at pos %" PRIu32 ": ", j); prt(buf + (j), ctx->m); printf("\n"); - ; // gcc doesn't like the goto label without this :-S - } - } - - if (j == 0) - break; - - h = B3G_HASH(u8_tolower(buf[j - 1]), u8_tolower(buf[j - 0]),u8_tolower(buf[j+1])); - d = (d << 1) & ctx->B3G[h]; - } while (d != 0); - } - COUNT(tctx->stat_num_shift++); - COUNT(tctx->stat_total_shift += (ctx->m - B3G_Q + 1)); - pos = pos + ctx->m - B3G_Q + 1; - } - return matches; -} - -uint32_t B3gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; -#ifdef B3G_COUNTERS - B3gThreadCtx *tctx = (B3gThreadCtx *)mpm_thread_ctx->ctx; -#endif - uint32_t pos = 0, matches = 0; - B3G_TYPE d; - uint32_t j; - - COUNT(tctx->stat_calls++); - COUNT(tctx->stat_m_total+=ctx->m); - - if (buflen < ctx->m) - return 0; - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (pos <= (buflen - ctx->m)) { - j = ctx->m - 2; - d = ~0; - - do { - uint16_t h = B3G_HASH(u8_tolower(buf[pos + j - 1]), u8_tolower(buf[pos + j - 0]),u8_tolower(buf[pos + j + 1])); - d = ((d << 1) & ctx->B3G[h]); - j = j - 1; - } while (d != 0 && j != 0); - - /* (partial) match, move on to verification */ - if (d != 0) { - COUNT(tctx->stat_d0++); - //printf("output at pos %" PRIu32 ": ", pos); prt(buf + pos, ctx->m); printf("\n"); - - /* get our patterns from the hash */ - uint16_t h = B3G_HASH(u8_tolower(buf[pos + ctx->m - 3]), u8_tolower(buf[pos + ctx->m - 2]),u8_tolower(buf[pos + ctx->m - 1])); - - if (ctx->bloom[h] != NULL) { - COUNT(tctx->stat_pminlen_calls++); - COUNT(tctx->stat_pminlen_total+=ctx->pminlen[h]); - - if ((buflen - pos) < ctx->pminlen[h]) { - goto skip_loop; - } else { - COUNT(tctx->stat_bloom_calls++); - - if (BloomFilterTest(ctx->bloom[h], buf+pos, ctx->pminlen[h]) == 0) { - COUNT(tctx->stat_bloom_hits++); - - //printf("Bloom: %p, buflen %" PRIu32 ", pos %" PRIu32 ", p_min_len %" PRIu32 "\n", ctx->bloom[h], buflen, pos, ctx->pminlen[h]); - goto skip_loop; - } - } - } - - B3gHashItem *hi = ctx->hash[h], *thi; - for (thi = hi; thi != NULL; thi = thi->nxt) { - COUNT(tctx->stat_d0_hashloop++); - B3gPattern *p = ctx->parray[thi->idx]; - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (buflen - pos < p->len) - continue; - - if (memcmp_lowercase(p->ci, buf+pos, p->len) == 0) { - COUNT(tctx->stat_loop_match++); - - matches += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } else { - if (buflen - pos < p->len) - continue; - - if (memcmp(p->cs, buf+pos, p->len) == 0) { - COUNT(tctx->stat_loop_match++); - - matches += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } - } -skip_loop: - pos = pos + 1; - //pos = pos + ctx->s0; - } else { - COUNT(tctx->stat_num_shift++); - COUNT(tctx->stat_total_shift += (j + 1)); - - pos = pos + j + 1; - } - } - - //printf("Total matches %" PRIu32 "\n", matches); - return matches; -} - -uint32_t B3gSearch12(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - uint8_t *bufmin = buf; - uint8_t *bufend = buf + buflen - 1; - uint32_t cnt = 0; - B3gPattern *p; - B3gHashItem *thi, *hi; - - //printf("BUF "); prt(buf,buflen); printf("\n"); - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - uint8_t h8 = u8_tolower(*buf); - hi = &ctx->hash1[h8]; - - if (hi->flags & 0x01) { - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (h8 == p->ci[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } - } else { - if (*buf == p->cs[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } - } - } - } - - if (buf != bufend) { - /* save one conversion by reusing h8 */ - uint16_t h16 = (uint16_t)(h8 << b3g_hash_shift | u8_tolower(*(buf+1))); - hi = ctx->hash2[h16]; - - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (h8 == p->ci[0] && u8_tolower(*(buf+1)) == p->ci[1]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } - } else { - if (*buf == p->cs[0] && *(buf+1) == p->cs[1]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } - } - } - } - buf += 1; - } - - //printf("B3gSearch12: after 1/2byte cnt %" PRIu32 "\n", cnt); - if (ctx->pat_x_cnt > 0) { - /* Pass bufmin on because buf no longer points to the - * start of the buffer. */ - cnt += ctx->MBSearch(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen); - //printf("B3gSearch1: after 2+byte cnt %" PRIu32 "\n", cnt); - } - return cnt; -} - -uint32_t B3gSearch2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - uint8_t *bufmin = buf; - uint8_t *bufend = buf + buflen - 1; - uint32_t cnt = 0; - B3gPattern *p; - B3gHashItem *thi, *hi; - - if (buflen < 2) - return 0; - - //printf("BUF "); prt(buf,buflen); printf("\n"); - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - uint16_t h = u8_tolower(*buf) << b3g_hash_shift | u8_tolower(*(buf+1)); - hi = ctx->hash2[h]; - - if (hi != NULL) { - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - if (p->len != 2) - continue; - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (u8_tolower(*buf) == p->ci[0] && u8_tolower(*(buf+1)) == p->ci[1]) { - //printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B3gSearch1)\n"); - if (MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size)) - cnt++; - } - } else { - if (*buf == p->cs[0] && *(buf+1) == p->cs[1]) { - //printf("CS Exact match: "); prt(p->cs, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B3gSearch1)\n"); - if (MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size)) - cnt++; - } - } - } - } - buf += 1; - } - - //printf("B3gSearch2: after 2byte cnt %" PRIu32 "\n", cnt); - if (ctx->pat_x_cnt) { - /* Pass bufmin on because buf no longer points to the - * start of the buffer. */ - cnt += ctx->MBSearch(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen); - //printf("B3gSearch1: after 2+byte cnt %" PRIu32 "\n", cnt); - } - return cnt; -} -uint32_t B3gSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx; - uint8_t *bufmin = buf; - uint8_t *bufend = buf + buflen - 1; - uint32_t cnt = 0; - B3gPattern *p; - B3gHashItem *thi, *hi; - - if (buflen == 0) - return 0; - - //printf("BUF "); prt(buf,buflen); printf("\n"); - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - uint8_t h = u8_tolower(*buf); - hi = &ctx->hash1[h]; - - if (hi->flags & 0x01) { - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - if (p->len != 1) - continue; - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (u8_tolower(*buf) == p->ci[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } - } else { - if (*buf == p->cs[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } - } - } - } - buf += 1; - } - - if (ctx->pat_2_cnt) { - /* Pass bufmin on because buf no longer points to the - * start of the buffer. */ - cnt += ctx->MBSearch2(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen); - } else if (ctx->pat_x_cnt) { - cnt += ctx->MBSearch(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen); - } - return cnt; -} - -void MpmB3gRegister (void) -{ - mpm_table[MPM_B3G].name = "b3g"; - mpm_table[MPM_B3G].max_pattern_length = B3G_WORD_SIZE; - mpm_table[MPM_B3G].InitCtx = B3gInitCtx; - mpm_table[MPM_B3G].InitThreadCtx = B3gThreadInitCtx; - mpm_table[MPM_B3G].DestroyCtx = B3gDestroyCtx; - mpm_table[MPM_B3G].DestroyThreadCtx = B3gThreadDestroyCtx; - mpm_table[MPM_B3G].AddPattern = B3gAddPatternCS; - mpm_table[MPM_B3G].AddPatternNocase = B3gAddPatternCI; - mpm_table[MPM_B3G].Prepare = B3gPreparePatterns; - mpm_table[MPM_B3G].Search = B3gSearchWrap; - mpm_table[MPM_B3G].Cleanup = NULL; - mpm_table[MPM_B3G].PrintCtx = B3gPrintInfo; - mpm_table[MPM_B3G].PrintThreadCtx = B3gPrintSearchStats; - mpm_table[MPM_B3G].RegisterUnittests = B3gRegisterTests; -} - -/* - * TESTS - */ - -#ifdef UNITTESTS -static int B3gTestInit01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - - if (ctx->m == 4) - result = 1; - else - printf("4 != %" PRIu32 " ", ctx->m); - - B3gDestroyCtx(&mpm_ctx); - return result; -} - -#if 0 -static int B3gTestS0Init01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 4) - result = 1; - else - printf("4 != %" PRIu32 " ", ctx->s0); - - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestS0Init02 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"cdef", 4, 0, 0, 1, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 2) - result = 1; - else - printf("2 != %" PRIu32 " ", ctx->s0); - - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestS0Init03 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 1) - result = 1; - else - printf("1 != %" PRIu32 " ", ctx->s0); - - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestS0Init04 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abab", 4, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 2) - result = 1; - else - printf("2 != %" PRIu32 " ", ctx->s0); - - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestS0Init05 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcab", 5, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - - if (ctx->s0 == 3) - result = 1; - else - printf("3 != %" PRIu32 " ", ctx->s0); - - B3gDestroyCtx(&mpm_ctx); - return result; -} -#endif - -static int B3gTestSearch01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestSearch02 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abce", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestSearch03 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghj", 4, 0, 0, 2, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -/* test patterns longer than 'm'. M is 4 here. */ -static int B3gTestSearch04 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdegh", 6, 0, 0, 1, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -/* case insensitive test patterns longer than 'm'. M is 4 here. */ -static int B3gTestSearch05 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); /* 1 match */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestSearch06 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcd", 4); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestSearch07 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0, 0); /* 1 */ - /* total matches: 135 */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 6 /* 6 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30); - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestSearch08 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"a", 1); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestSearch09 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ab", 2, 0, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"ab", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestSearch10 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */); - - char *input = "012345679012345679012345679012345679012345679012345679" - "012345679012345679012345679012345679abcdefgh0123456790" - "123456790123456790123456790123456790123456790123456790" - "12345679012345679012345679"; - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)input, strlen(input)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestSearch11 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2 /* 2 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -static int B3gTestSearch12 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_B3G); - B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"wxyz", 4, 0, 0, 0, 0, 0); /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"vwxyz", 5, 0, 0, 0, 0, 0); /* 1 match */ - - B3gPreparePatterns(&mpm_ctx); - B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2 /* 2 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefghjiklmnopqrstuvwxyz", 26); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - B3gThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - B3gDestroyCtx(&mpm_ctx); - return result; -} - -#endif /* UNITTESTS */ - -void B3gRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("B3gTestInit01", B3gTestInit01, 1); -/* - UtRegisterTest("B3gTestS0Init01", B3gTestS0Init01, 1); - UtRegisterTest("B3gTestS0Init02", B3gTestS0Init02, 1); - UtRegisterTest("B3gTestS0Init03", B3gTestS0Init03, 1); - UtRegisterTest("B3gTestS0Init04", B3gTestS0Init04, 1); - UtRegisterTest("B3gTestS0Init05", B3gTestS0Init05, 1); -*/ - UtRegisterTest("B3gTestSearch01", B3gTestSearch01, 1); - - UtRegisterTest("B3gTestSearch02", B3gTestSearch02, 1); - UtRegisterTest("B3gTestSearch03", B3gTestSearch03, 1); - UtRegisterTest("B3gTestSearch04", B3gTestSearch04, 1); - UtRegisterTest("B3gTestSearch05", B3gTestSearch05, 1); - UtRegisterTest("B3gTestSearch06", B3gTestSearch06, 1); - UtRegisterTest("B3gTestSearch07", B3gTestSearch07, 1); - UtRegisterTest("B3gTestSearch08", B3gTestSearch08, 1); - UtRegisterTest("B3gTestSearch09", B3gTestSearch09, 1); - UtRegisterTest("B3gTestSearch10", B3gTestSearch10, 1); - UtRegisterTest("B3gTestSearch11", B3gTestSearch11, 1); - UtRegisterTest("B3gTestSearch12", B3gTestSearch12, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/util-mpm-b3g.h b/framework/src/suricata/src/util-mpm-b3g.h deleted file mode 100644 index d35aa033..00000000 --- a/framework/src/suricata/src/util-mpm-b3g.h +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_MPM_B3G_H__ -#define __UTIL_MPM_B3G_H__ - -#include "util-mpm.h" -#include "util-bloomfilter.h" - -#define B3G_HASHSHIFT_MAX 8 -#define B3G_HASHSHIFT_MAX2 5 -#define B3G_HASHSHIFT_HIGHER 7 -#define B3G_HASHSHIFT_HIGHER2 4 -#define B3G_HASHSHIFT_HIGH 6 -#define B3G_HASHSHIFT_HIGH2 3 -#define B3G_HASHSHIFT_MEDIUM 5 -#define B3G_HASHSHIFT_MEDIUM2 2 -#define B3G_HASHSHIFT_LOW 4 -#define B3G_HASHSHIFT_LOW2 1 -#define B3G_HASHSHIFT_LOWEST 3 -#define B3G_HASHSHIFT_LOWEST2 1 - -#define B3G_TYPE uint32_t -//#define B3G_TYPE uint16_t -//#define B3G_TYPE uint8_t -//#define B3G_WORD_SIZE 16 -//#define B3G_WORD_SIZE 8 -#define B3G_WORD_SIZE 32 - -#define B3G_Q 3 - -//#define B3G_SEARCHFUNC B3gSearch -#define B3G_SEARCHFUNC B3gSearchBNDMq - -//#define B3G_COUNTERS - -typedef struct B3gPattern_ { - uint8_t *cs; /* case sensitive */ - uint8_t *ci; /* case INsensitive */ - uint16_t len; - uint8_t flags; - uint32_t id; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; - - struct B3gPattern_ *next; - -} B3gPattern; - -typedef struct B3gHashItem_ { - uint8_t flags; - uint16_t idx; - struct B3gHashItem_ *nxt; -} B3gHashItem; - -typedef struct B3gCtx_ { - /* hash used during ctx initialization */ - B3gPattern **init_hash; - - B3G_TYPE m; - B3G_TYPE *B3G; - - uint8_t s0; - - uint16_t pat_1_cnt; - uint16_t pat_2_cnt; - uint16_t pat_x_cnt; - - uint32_t hash_size; - B3gHashItem **hash; - BloomFilter **bloom; - uint8_t *pminlen; /* array containing the minimal length - of the patters in a hash bucket. Used - for the BloomFilter. */ - B3gHashItem hash1[256]; - B3gHashItem **hash2; - - uint32_t (*Search)(struct MpmCtx_ *, struct MpmThreadCtx_ *, PatternMatcherQueue *, uint8_t *, uint16_t); - - /* we store our own multi byte search func ptr here for B3gSearch1 */ - uint32_t (*MBSearch2)(struct MpmCtx_ *, struct MpmThreadCtx_ *, PatternMatcherQueue *, uint8_t *, uint16_t); - uint32_t (*MBSearch)(struct MpmCtx_ *, struct MpmThreadCtx_ *, PatternMatcherQueue *, uint8_t *, uint16_t); - - /* pattern arrays */ - B3gPattern **parray; -} B3gCtx; - -typedef struct B3gThreadCtx_ { -#ifdef B3G_COUNTERS - uint32_t stat_pminlen_calls; - uint32_t stat_pminlen_total; - uint32_t stat_bloom_calls; - uint32_t stat_bloom_hits; - uint32_t stat_calls; - uint32_t stat_m_total; - uint32_t stat_d0; - uint32_t stat_d0_hashloop; - uint32_t stat_loop_match; - uint32_t stat_loop_no_match; - uint32_t stat_num_shift; - uint32_t stat_total_shift; -#endif /* B3G_COUNTERS */ -} B3gThreadCtx; - -void MpmB3gRegister(void); - -#endif - diff --git a/framework/src/suricata/src/util-mpm-wumanber.c b/framework/src/suricata/src/util-mpm-wumanber.c deleted file mode 100644 index dc78cde2..00000000 --- a/framework/src/suricata/src/util-mpm-wumanber.c +++ /dev/null @@ -1,3219 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Implementation of the Wu-Manber pattern matching algorithm. - * - * Ideas: - * - the hash contains a list of patterns. Maybe we can 'train' the hash - * so the most common patterns always appear first in this list. - * - * \todo make hash1 a array of ptr and get rid of the flag field in the - * WmHashItem - * \todo remove exit() calls - * \todo only calc prefixci_buf for nocase patterns? -- would be in a - * loop though, so probably not a performance inprovement. - * \todo make sure runtime counters can be disabled (at compile time) - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "util-mpm.h" -#include "util-mpm-wumanber.h" -#include "conf.h" - -#include "util-unittest.h" -#include "util-debug.h" - -#define INIT_HASH_SIZE 65535 - -#define HASH16_SIZE 65536 -#define HASH16(a,b) (((a)<<8) | (b)) -#define HASH15_SIZE 32768 -#define HASH15(a,b) (((a)<<7) | (b)) -#define HASH14_SIZE 16384 -#define HASH14(a,b) (((a)<<6) | (b)) -#define HASH12_SIZE 4096 -#define HASH12(a,b) (((a)<<4) | (b)) -#define HASH9_SIZE 512 -#define HASH9(a,b) (((a)<<1) | (b)) - -static uint32_t wm_hash_size = 0; -static uint32_t wm_bloom_size = 0; - -void WmInitCtx (MpmCtx *mpm_ctx); -void WmThreadInitCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, uint32_t); -void WmDestroyCtx(MpmCtx *mpm_ctx); -void WmThreadDestroyCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx); -int WmAddPatternCI(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); -int WmAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); -int WmPreparePatterns(MpmCtx *mpm_ctx); -uint32_t WmSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -uint32_t WmSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -uint32_t WmSearch2Hash9(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -uint32_t WmSearch2Hash12(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -uint32_t WmSearch2Hash14(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -uint32_t WmSearch2Hash15(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -uint32_t WmSearch2Hash16(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, uint8_t *buf, uint16_t buflen); -void WmPrintInfo(MpmCtx *mpm_ctx); -void WmPrintSearchStats(MpmThreadCtx *mpm_thread_ctx); -void WmRegisterTests(void); - -/* uppercase to lowercase conversion lookup table */ -static uint8_t lowercasetable[256]; -/* marco to do the actual lookup */ -#define wm_tolower(c) lowercasetable[(c)] - -#ifdef WUMANBER_COUNTERS -#define COUNT(counter) \ - (counter) -#else -#define COUNT(counter) -#endif /* WUMANBER_COUNTERS */ - -void prt (uint8_t *buf, uint16_t buflen) -{ - uint16_t i; - - for (i = 0; i < buflen; i++) { - if (isprint(buf[i])) printf("%c", buf[i]); - else printf("\\x%" PRIX32, buf[i]); - } - //printf("\n"); -} - -void WmPrintInfo(MpmCtx *mpm_ctx) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; - - printf("MPM WuManber Information:\n"); - printf("Memory allocs: %" PRIu32 "\n", mpm_ctx->memory_cnt); - printf("Memory alloced: %" PRIu32 "\n", mpm_ctx->memory_size); - printf(" Sizeofs:\n"); - printf(" MpmCtx %" PRIuMAX "\n", (uintmax_t)sizeof(MpmCtx)); - printf(" WmCtx: %" PRIuMAX "\n", (uintmax_t)sizeof(WmCtx)); - printf(" WmPattern %" PRIuMAX "\n", (uintmax_t)sizeof(WmPattern)); - printf(" WmHashItem %" PRIuMAX "\n", (uintmax_t)sizeof(WmHashItem)); - printf("Unique Patterns: %" PRIu32 "\n", mpm_ctx->pattern_cnt); - printf("Smallest: %" PRIu32 "\n", mpm_ctx->minlen); - printf("Largest: %" PRIu32 "\n", mpm_ctx->maxlen); - printf("Max shiftlen: %" PRIu32 "\n", ctx->shiftlen); - printf("Hash size: %" PRIu32 "\n", ctx->hash_size); - printf("Search function: "); - if (ctx->Search == WmSearch1) { - printf("WmSearch1 (allows single byte patterns)\n"); - printf("MBSearch funct: "); - if (ctx->MBSearch == WmSearch2Hash16) printf("WmSearch2Hash16\n"); - else if (ctx->MBSearch == WmSearch2Hash15) printf("WmSearch2Hash15\n"); - else if (ctx->MBSearch == WmSearch2Hash14) printf("WmSearch2Hash14\n"); - else if (ctx->MBSearch == WmSearch2Hash12) printf("WmSearch2Hash12\n"); - else if (ctx->MBSearch == WmSearch2Hash9) printf("WmSearch2Hash9\n"); - } - if (ctx->Search == WmSearch2Hash16) printf("WmSearch2Hash16 (only for multibyte patterns)\n"); - else if (ctx->Search == WmSearch2Hash15) printf("WmSearch2Hash15 (only for multibyte patterns)\n"); - else if (ctx->Search == WmSearch2Hash14) printf("WmSearch2Hash14 (only for multibyte patterns)\n"); - else if (ctx->Search == WmSearch2Hash12) printf("WmSearch2Hash12 (only for multibyte patterns)\n"); - else if (ctx->Search == WmSearch2Hash9) printf("WmSearch2Hash9 (only for multibyte patterns)\n"); - else printf("ERROR\n"); - printf("\n"); -} - -static inline WmPattern *WmAllocPattern(MpmCtx *mpm_ctx) -{ - WmPattern *p = SCMalloc(sizeof(WmPattern)); - if (unlikely(p == NULL)) - return NULL; - memset(p,0,sizeof(WmPattern)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(WmPattern); - return p; -} - -static inline WmHashItem * -WmAllocHashItem(MpmCtx *mpm_ctx) -{ - WmHashItem *hi = SCMalloc(sizeof(WmHashItem)); - if (unlikely(hi == NULL)) - return NULL; - memset(hi,0,sizeof(WmHashItem)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(WmHashItem); - return hi; -} - -static void WmHashFree(MpmCtx *mpm_ctx, WmHashItem *hi) -{ - if (hi == NULL) - return; - - WmHashItem *t = hi->nxt; - WmHashFree(mpm_ctx, t); - - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(WmHashItem); - SCFree(hi); -} - -static inline void memcpy_tolower(uint8_t *d, uint8_t *s, uint16_t len) -{ - uint16_t i; - for (i = 0; i < len; i++) { - d[i] = wm_tolower(s[i]); - } -} - -/* - * INIT HASH START - */ -static inline uint32_t WmInitHash(WmPattern *p) -{ - uint32_t hash = p->len * p->cs[0]; - if (p->len > 1) - hash += p->cs[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline uint32_t WmInitHashRaw(uint8_t *pat, uint16_t patlen) -{ - uint32_t hash = patlen * pat[0]; - if (patlen > 1) - hash += pat[1]; - - return (hash % INIT_HASH_SIZE); -} - -static inline int WmInitHashAdd(WmCtx *ctx, WmPattern *p) -{ - uint32_t hash = WmInitHash(p); - - //printf("WmInitHashAdd: %" PRIu32 "\n", hash); - - if (ctx->init_hash[hash] == NULL) { - ctx->init_hash[hash] = p; - //printf("WmInitHashAdd: hash %" PRIu32 ", head %p\n", hash, ctx->init_hash[hash]); - return 0; - } - - WmPattern *tt = NULL; - WmPattern *t = ctx->init_hash[hash]; - - /* get the list tail */ - do { - tt = t; - t = t->next; - } while (t != NULL); - - tt->next = p; - //printf("WmInitHashAdd: hash %" PRIu32 ", head %p\n", hash, ctx->init_hash[hash]); - - return 0; -} - -static inline int WmCmpPattern(WmPattern *p, uint8_t *pat, uint16_t patlen, char flags); - -static inline WmPattern *WmInitHashLookup(WmCtx *ctx, uint8_t *pat, uint16_t patlen, char flags) -{ - uint32_t hash = WmInitHashRaw(pat,patlen); - - //printf("WmInitHashLookup: %" PRIu32 ", head %p\n", hash, ctx->init_hash[hash]); - - if (ctx->init_hash[hash] == NULL) { - return NULL; - } - - WmPattern *t = ctx->init_hash[hash]; - for ( ; t != NULL; t = t->next) { - if (WmCmpPattern(t,pat,patlen,flags) == 1) - return t; - } - - return NULL; -} - -static inline int WmCmpPattern(WmPattern *p, uint8_t *pat, uint16_t patlen, char flags) -{ - if (p->len != patlen) - return 0; - - if (p->flags != flags) - return 0; - - if (memcmp(p->cs, pat, patlen) != 0) - return 0; - - return 1; -} - -/* - * INIT HASH END - */ - -void WmFreePattern(MpmCtx *mpm_ctx, WmPattern *p) -{ - if (p && p->cs && p->cs != p->ci) { - SCFree(p->cs); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p && p->ci) { - SCFree(p->ci); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->len; - } - - if (p && p->sids) { - SCFree(p->sids); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= p->sids_size * sizeof(uint32_t); - } - - if (p) { - SCFree(p); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(WmPattern); - } -} - -/* WmAddPattern - * - * pat: ptr to the pattern - * patlen: length of the pattern - * nocase: nocase flag: 1 enabled, 0 disable - * pid: pattern id - * sid: signature id (internal id) - */ -static int WmAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, uint32_t sid, uint8_t flags) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; - -// printf("WmAddPattern: ctx %p \"", mpm_ctx); prt(pat, patlen); -// printf("\" id %" PRIu32 ", nocase %s\n", id, nocase ? "true" : "false"); - - if (patlen == 0) - return 0; - - /* get a memory piece */ - WmPattern *p = WmInitHashLookup(ctx, pat, patlen, flags); - if (p == NULL) { -// printf("WmAddPattern: allocing new pattern\n"); - p = WmAllocPattern(mpm_ctx); - if (p == NULL) - goto error; - - p->len = patlen; - p->flags = flags; - p->id = pid; - - /* setup the case insensitive part of the pattern */ - p->ci = SCMalloc(patlen); - if (p->ci == NULL) - goto error; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy_tolower(p->ci, pat, patlen); - - /* setup the case sensitive part of the pattern */ - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - /* nocase means no difference between cs and ci */ - p->cs = p->ci; - } else { - if (memcmp(p->ci,pat,p->len) == 0) { - /* no diff between cs and ci: pat is lowercase */ - p->cs = p->ci; - } else { - p->cs = SCMalloc(patlen); - if (p->cs == NULL) - goto error; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += patlen; - memcpy(p->cs, pat, patlen); - } - } - - if (p->len > 1) { - p->prefix_cs = (uint16_t)(*(p->cs)+*(p->cs+1)); - p->prefix_ci = (uint16_t)(*(p->ci)+*(p->ci+1)); - } - - //printf("WmAddPattern: ci \""); prt(p->ci,p->len); - //printf("\" cs \""); prt(p->cs,p->len); - //printf("\" prefix_ci %" PRIu32 ", prefix_cs %" PRIu32 "\n", p->prefix_ci, p->prefix_cs); - - /* put in the pattern hash */ - WmInitHashAdd(ctx, p); - - if (mpm_ctx->pattern_cnt == 65535) { - printf("Max search words reached\n"); - exit(1); - } - mpm_ctx->pattern_cnt++; - - if (mpm_ctx->maxlen < patlen) mpm_ctx->maxlen = patlen; - if (mpm_ctx->minlen == 0) mpm_ctx->minlen = patlen; - else if (mpm_ctx->minlen > patlen) mpm_ctx->minlen = patlen; - - p->sids_size = 1; - p->sids = SCMalloc(p->sids_size * sizeof(SigIntId)); - BUG_ON(p->sids == NULL); - p->sids[0] = sid; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SigIntId); - - } else { - /* TODO figure out how we can be called multiple times for the same CTX with the same sid */ - - int found = 0; - uint32_t x = 0; - for (x = 0; x < p->sids_size; x++) { - if (p->sids[x] == sid) { - found = 1; - break; - } - } - if (!found) { - SigIntId *sids = SCRealloc(p->sids, (sizeof(SigIntId) * (p->sids_size + 1))); - BUG_ON(sids == NULL); - p->sids = sids; - p->sids[p->sids_size] = sid; - p->sids_size++; - mpm_ctx->memory_size += sizeof(uint32_t); - } - } - - return 0; - -error: - WmFreePattern(mpm_ctx, p); - return -1; -} - -int WmAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags) -{ - flags |= MPM_PATTERN_FLAG_NOCASE; - return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -int WmAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags) -{ - return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -static uint32_t WmBloomHash(void *data, uint16_t datalen, uint8_t iter, uint32_t hash_size) -{ - uint8_t *d = (uint8_t *)data; - uint16_t i; - uint32_t hash = (uint32_t)wm_tolower(*d); - - for (i = 1; i < datalen - 1; i++) { - hash += (wm_tolower((*d++))) ^ i; - } - hash <<= (iter+1); - - hash %= hash_size; - return hash; -} -/* -static uint32_t BloomHash(void *data, uint16_t datalen, uint8_t iter, uint32_t hash_size) -{ - uint8_t *d = (uint8_t *)data; - uint32_t i; - uint32_t hash = 0; - - for (i = 0; i < datalen; i++) { - if (i == 0) hash += (((uint32_t)*d++)); - else if (i == 1) hash += (((uint32_t)*d++) * datalen); - else hash *= (((uint32_t)*d++) * i); - } - - hash *= (iter + datalen); - hash %= hash_size; - return hash; -} -*/ -static void WmSearchPrepareHash(MpmCtx *mpm_ctx) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; - uint16_t i; - uint16_t idx = 0; - uint8_t idx8 = 0; - - ctx->hash = (WmHashItem **)SCMalloc(sizeof(WmHashItem *) * ctx->hash_size); - if (ctx->hash == NULL) - goto error; - memset(ctx->hash, 0, sizeof(WmHashItem *) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(WmHashItem *) * ctx->hash_size); - - /* alloc the pminlen array */ - ctx->pminlen = (uint8_t *)SCMalloc(sizeof(uint8_t) * ctx->hash_size); - if (ctx->pminlen == NULL) - goto error; - memset(ctx->pminlen, 0, sizeof(uint8_t) * ctx->hash_size); - - for (i = 0; i < mpm_ctx->pattern_cnt; i++) - { - if(ctx->parray[i]->len == 1) { - idx8 = (uint8_t)ctx->parray[i]->ci[0]; - if (ctx->hash1[idx8].flags == 0) { - ctx->hash1[idx8].idx = i; - ctx->hash1[idx8].flags |= 0x01; - } else { - WmHashItem *hi = WmAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= 0x01; - - /* Append this HashItem to the list */ - WmHashItem *thi = &ctx->hash1[idx8]; - while (thi->nxt) thi = thi->nxt; - thi->nxt = hi; - } - } else { - uint16_t patlen = ctx->shiftlen; - - if (ctx->hash_size == HASH9_SIZE) - idx = HASH9(ctx->parray[i]->ci[patlen-1], ctx->parray[i]->ci[patlen-2]); - else if (ctx->hash_size == HASH12_SIZE) - idx = HASH12(ctx->parray[i]->ci[patlen-1], ctx->parray[i]->ci[patlen-2]); - else if (ctx->hash_size == HASH14_SIZE) - idx = HASH14(ctx->parray[i]->ci[patlen-1], ctx->parray[i]->ci[patlen-2]); - else if (ctx->hash_size == HASH15_SIZE) - idx = HASH15(ctx->parray[i]->ci[patlen-1], ctx->parray[i]->ci[patlen-2]); - else - idx = HASH16(ctx->parray[i]->ci[patlen-1], ctx->parray[i]->ci[patlen-2]); - - if (ctx->hash[idx] == NULL) { - WmHashItem *hi = WmAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= 0x01; - ctx->pminlen[idx] = ctx->parray[i]->len; - - ctx->hash[idx] = hi; - } else { - WmHashItem *hi = WmAllocHashItem(mpm_ctx); - if (hi == NULL) - goto error; - hi->idx = i; - hi->flags |= 0x01; - - if (ctx->parray[i]->len < ctx->pminlen[idx]) - ctx->pminlen[idx] = ctx->parray[i]->len; - - /* Append this HashItem to the list */ - WmHashItem *thi = ctx->hash[idx]; - while (thi->nxt) thi = thi->nxt; - thi->nxt = hi; - } - } - } - - /* alloc the bloom array */ - ctx->bloom = (BloomFilter **)SCMalloc(sizeof(BloomFilter *) * ctx->hash_size); - if (ctx->bloom == NULL) - goto error; - memset(ctx->bloom, 0, sizeof(BloomFilter *) * ctx->hash_size); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(BloomFilter *) * ctx->hash_size); - - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - WmHashItem *hi = ctx->hash[h]; - if (hi == NULL) - continue; - - ctx->bloom[h] = BloomFilterInit(wm_bloom_size, 2, WmBloomHash); - if (ctx->bloom[h] == NULL) - continue; - - mpm_ctx->memory_cnt += BloomFilterMemoryCnt(ctx->bloom[h]); - mpm_ctx->memory_size += BloomFilterMemorySize(ctx->bloom[h]); - - if (ctx->pminlen[h] > 8) - ctx->pminlen[h] = 8; - - WmHashItem *thi = hi; - do { - BloomFilterAdd(ctx->bloom[h], ctx->parray[thi->idx]->ci, ctx->pminlen[h]); - thi = thi->nxt; - } while (thi != NULL); - } - return; -error: - return; -} -static void WmSearchPrepareShiftTable(MpmCtx *mpm_ctx) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; - - uint16_t shift = 0, k = 0, idx = 0; - uint32_t i = 0; - - uint16_t smallest = mpm_ctx->minlen; - if (smallest > 255) smallest = 255; - if (smallest < 2) smallest = 2; - - ctx->shiftlen = smallest; - - ctx->shifttable = SCMalloc(sizeof(uint16_t) * ctx->hash_size); - if (ctx->shifttable == NULL) - return; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (sizeof(uint16_t) * ctx->hash_size); - - /* default shift table is set to minimal shift */ - for (i = 0; i < ctx->hash_size; i++) - ctx->shifttable[i] = ctx->shiftlen; - - for (i = 0; i < mpm_ctx->pattern_cnt; i++) - { - /* ignore one byte patterns */ - if (ctx->parray[i]->len == 1) - continue; - - /* add the first character of the pattern preceeded by - * every possible other character. */ - for (k = 0; k < 256; k++) { - shift = ctx->shiftlen - 1; - if (shift > 255) shift = 255; - - if (ctx->hash_size == HASH9_SIZE) { - idx = HASH9(ctx->parray[i]->ci[0], (uint8_t)k); - //printf("HASH9 idx %" PRIu32 "\n", idx); - } else if (ctx->hash_size == HASH12_SIZE) { - idx = HASH12(ctx->parray[i]->ci[0], (uint8_t)k); - //printf("HASH12 idx %" PRIu32 "\n", idx); - } else if (ctx->hash_size == HASH14_SIZE) { - idx = HASH14(ctx->parray[i]->ci[0], (uint8_t)k); - //printf("HASH14 idx %" PRIu32 "\n", idx); - } else if (ctx->hash_size == HASH15_SIZE) { - idx = HASH15(ctx->parray[i]->ci[0], (uint8_t)k); - //printf("HASH15 idx %" PRIu32 "\n", idx); - } else { - idx = HASH16(ctx->parray[i]->ci[0], (uint8_t)k); - //printf("HASH15 idx %" PRIu32 "\n", idx); - } - if (shift < ctx->shifttable[idx]) { - ctx->shifttable[idx] = shift; - } - } - - for (k = 0; k < ctx->shiftlen-1; k++) - { - shift = (ctx->shiftlen - 2 - k); - if (shift > 255) shift = 255; - - if (ctx->hash_size == HASH9_SIZE) { - idx = HASH9(ctx->parray[i]->ci[k+1], ctx->parray[i]->ci[k]); - //printf("HASH9 idx %" PRIu32 "\n", idx); - } else if (ctx->hash_size == HASH12_SIZE) { - idx = HASH12(ctx->parray[i]->ci[k+1], ctx->parray[i]->ci[k]); - //printf("HASH12 idx %" PRIu32 "\n", idx); - } else if (ctx->hash_size == HASH14_SIZE) { - idx = HASH14(ctx->parray[i]->ci[k+1], ctx->parray[i]->ci[k]); - //printf("HASH14 idx %" PRIu32 "\n", idx); - } else if (ctx->hash_size == HASH15_SIZE) { - idx = HASH15(ctx->parray[i]->ci[k+1], ctx->parray[i]->ci[k]); - //printf("HASH15 idx %" PRIu32 "\n", idx); - } else { - idx = HASH16(ctx->parray[i]->ci[k+1], ctx->parray[i]->ci[k]); - //printf("HASH15 idx %" PRIu32 "\n", idx); - } - if (shift < ctx->shifttable[idx]) { - ctx->shifttable[idx] = shift; - } - //printf("WmPrepareShiftTable: i %" PRIu32 ", k %" PRIu32 ", idx %" PRIu32 ", shift set to %" PRIu32 ": \"%c%c\"\n", - // i, k, idx, shift, ctx->parray[i]->ci[k], ctx->parray[i]->ci[k+1]); - } - } -} - -int WmPreparePatterns(MpmCtx *mpm_ctx) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; - - /* alloc the pattern array */ - ctx->parray = (WmPattern **)SCMalloc(mpm_ctx->pattern_cnt * sizeof(WmPattern *)); - if (ctx->parray == NULL) - goto error; - memset(ctx->parray, 0, mpm_ctx->pattern_cnt * sizeof(WmPattern *)); - //printf("mpm_ctx %p, parray %p\n", mpm_ctx,ctx->parray); - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (mpm_ctx->pattern_cnt * sizeof(WmPattern *)); - - /* populate it with the patterns in the hash */ - uint32_t i = 0, p = 0; - for (i = 0; i < INIT_HASH_SIZE; i++) { - WmPattern *node = ctx->init_hash[i], *nnode = NULL; - for ( ; node != NULL; ) { - nnode = node->next; - node->next = NULL; - - ctx->parray[p] = node; - - p++; - node = nnode; - } - } - /* we no longer need the hash, so free it's memory */ - SCFree(ctx->init_hash); - ctx->init_hash = NULL; - - /* TODO VJ these values are chosen pretty much randomly, so - * we should do some performance testing - * */ - - if (ctx->hash_size == 0) { - if (mpm_ctx->pattern_cnt < 50) { - ctx->hash_size = HASH9_SIZE; - } else if(mpm_ctx->pattern_cnt < 300) { - ctx->hash_size = HASH12_SIZE; - } else if(mpm_ctx->pattern_cnt < 1200) { - ctx->hash_size = HASH14_SIZE; - } else if(mpm_ctx->pattern_cnt < 2400) { - ctx->hash_size = HASH15_SIZE; - } else { - ctx->hash_size = HASH16_SIZE; - } - } - - WmSearchPrepareShiftTable(mpm_ctx); - WmSearchPrepareHash(mpm_ctx); - - if (ctx->hash_size == HASH9_SIZE) { - ctx->MBSearch = WmSearch2Hash9; - ctx->Search = WmSearch2Hash9; - } else if (ctx->hash_size == HASH12_SIZE) { - ctx->MBSearch = WmSearch2Hash12; - ctx->Search = WmSearch2Hash12; - } else if (ctx->hash_size == HASH14_SIZE) { - ctx->MBSearch = WmSearch2Hash14; - ctx->Search = WmSearch2Hash14; - } else if (ctx->hash_size == HASH15_SIZE) { - ctx->MBSearch = WmSearch2Hash15; - ctx->Search = WmSearch2Hash15; - } else { - ctx->MBSearch = WmSearch2Hash16; - ctx->Search = WmSearch2Hash16; - } - - if (mpm_ctx->minlen == 1) { - ctx->Search = WmSearch1; - } - - return 0; -error: - return -1; -} - -void WmPrintSearchStats(MpmThreadCtx *mpm_thread_ctx) -{ -#ifdef WUMANBER_COUNTERS - WmThreadCtx *tctx = (WmThreadCtx *)mpm_thread_ctx->ctx; - - printf("Shift 0: %" PRIu32 "\n", tctx->stat_shift_null); - printf("Loop match: %" PRIu32 "\n", tctx->stat_loop_match); - printf("Loop no match: %" PRIu32 "\n", tctx->stat_loop_no_match); - printf("Num shifts: %" PRIu32 "\n", tctx->stat_num_shift); - printf("Total shifts: %" PRIu32 "\n", tctx->stat_total_shift); -#endif /* WUMANBER_COUNTERS */ -} - -static inline int -memcmp_lowercase(uint8_t *s1, uint8_t *s2, uint16_t n) -{ - size_t i; - - /* check backwards because we already tested the first - * 2 to 4 chars. This way we are more likely to detect - * a miss and thus speed up a little... */ - for (i = n - 1; i; i--) { - if (wm_tolower(*(s2+i)) != s1[i]) - return 1; - } - - return 0; -} - -inline uint32_t WmSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; - return ctx->Search(mpm_ctx, mpm_thread_ctx, pmq, buf, buflen); -} - -/* SCAN FUNCTIONS */ -uint32_t WmSearch2Hash9(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; -#ifdef WUMANBER_COUNTERS - WmThreadCtx *tctx = (WmThreadCtx *)mpm_thread_ctx->ctx; -#endif /* WUMANBER_COUNTERS */ - uint32_t cnt = 0; - uint8_t *bufend = buf + buflen - 1; - uint16_t sl = ctx->shiftlen; - uint16_t h; - uint8_t shift; - WmHashItem *thi, *hi; - WmPattern *p; - uint16_t prefixci_buf; - uint16_t prefixcs_buf; - - if (buflen == 0) - return 0; - - //printf("BUF(%" PRIu32 ") ", buflen); prt(buf,buflen); printf(" (sl %" PRIu32 ")\n", sl); - - buf+=(sl-1); - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - h = HASH9(wm_tolower(*buf),(wm_tolower(*(buf-1)))); - shift = ctx->shifttable[h]; - //printf("%p %" PRIu32 " search: h %" PRIu32 ", shift %" PRIu32 "\n", buf, buf - bufmin, h, shift); - - if (shift == 0) { - COUNT(tctx->stat_shift_null++); - - hi = ctx->hash[h]; - //printf("search: hi %p\n", hi); - if (hi != NULL) { - /* get our patterns from the hash */ - if (ctx->bloom[h] != NULL) { - COUNT(tctx->stat_pminlen_calls++); - COUNT(tctx->stat_pminlen_total+=ctx->pminlen[h]); - - if ((bufend - (buf-sl)) < ctx->pminlen[h]) { - goto skip_loop; - } else { - COUNT(tctx->stat_bloom_calls++); - - if (BloomFilterTest(ctx->bloom[h], buf-sl+1, ctx->pminlen[h]) == 0) { - COUNT(tctx->stat_bloom_hits++); - goto skip_loop; - } - } - } - - prefixci_buf = (uint16_t)(wm_tolower(*(buf-sl+1)) + wm_tolower(*(buf-sl+2))); - prefixcs_buf = (uint16_t)(*(buf-sl+1) + *(buf-sl+2)); - - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - //printf("WmSearch2: p->prefix_ci %" PRIu32 ", p->prefix_cs %" PRIu32 "\n", - // p->prefix_ci, p->prefix_cs); - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (p->prefix_ci != prefixci_buf || p->len > (bufend-(buf-sl))) - continue; - - if (memcmp_lowercase(p->ci, buf-sl+1, p->len) == 0) { - //printf("CI Exact match: "); prt(p->ci, p->len); printf("\n"); - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - - } else { - COUNT(tctx->stat_loop_no_match++); - } - } else { - if (p->prefix_cs != prefixcs_buf || p->len > (bufend-(buf-sl))) - continue; - if (memcmp(p->cs, buf-sl+1, p->len) == 0) { - //printf("CS Exact match: "); prt(p->cs, p->len); printf("\n"); - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - - } else { - COUNT(tctx->stat_loop_no_match++); - } - } - } - } -skip_loop: - shift = 1; - } else { - COUNT(tctx->stat_total_shift += shift); - COUNT(tctx->stat_num_shift++); - } - buf += shift; - } - - //printf("cnt %" PRIu32 "\n", cnt); - return cnt; -} - -uint32_t WmSearch2Hash12(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; -#ifdef WUMANBER_COUNTERS - WmThreadCtx *tctx = (WmThreadCtx *)mpm_thread_ctx->ctx; -#endif /* WUMANBER_COUNTERS */ - uint32_t cnt = 0; - uint8_t *bufend = buf + buflen - 1; - uint16_t sl = ctx->shiftlen; - uint16_t h; - uint8_t shift; - WmHashItem *thi, *hi; - WmPattern *p; - uint16_t prefixci_buf; - uint16_t prefixcs_buf; - - if (buflen == 0) - return 0; - - //printf("BUF(%" PRIu32 ") ", buflen); prt(buf,buflen); printf("\n"); - - buf+=(sl-1); - //buf++; - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - //h = (wm_tolower(*buf)<<8)+(wm_tolower(*(buf-1))); - h = HASH12(wm_tolower(*buf),(wm_tolower(*(buf-1)))); - shift = ctx->shifttable[h]; - //printf("search: h %" PRIu32 ", shift %" PRIu32 "\n", h, shift); - - if (shift == 0) { - COUNT(tctx->stat_shift_null++); - /* get our hash item */ - hi = ctx->hash[h]; - //printf("search: hi %p\n", hi); - if (hi != NULL) { - /* get our patterns from the hash */ - if (ctx->bloom[h] != NULL) { - COUNT(tctx->stat_pminlen_calls++); - COUNT(tctx->stat_pminlen_total+=ctx->pminlen[h]); - - if ((bufend - (buf-sl)) < ctx->pminlen[h]) { - goto skip_loop; - } else { - COUNT(tctx->stat_bloom_calls++); - - if (BloomFilterTest(ctx->bloom[h], buf-sl+1, ctx->pminlen[h]) == 0) { - COUNT(tctx->stat_bloom_hits++); - goto skip_loop; - } - } - } - - prefixci_buf = (uint16_t)(wm_tolower(*(buf-sl+1)) + wm_tolower(*(buf-sl+2))); - prefixcs_buf = (uint16_t)(*(buf-sl+1) + *(buf-sl+2)); - //printf("WmSearch2: prefixci_buf %" PRIu32 ", prefixcs_buf %" PRIu32 "\n", prefixci_buf, prefixcs_buf); - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - //printf("WmSearch2: p->prefix_ci %" PRIu32 ", p->prefix_cs %" PRIu32 "\n", - // p->prefix_ci, p->prefix_cs); - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (p->prefix_ci != prefixci_buf || p->len > (bufend-(buf-sl))) - continue; - - if (memcmp_lowercase(p->ci, buf-sl+1, p->len) == 0) { - //printf("CI Exact match: "); prt(p->ci, p->len); printf("\n"); - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - - } else { - COUNT(tctx->stat_loop_no_match++); - } - } else { - if (p->prefix_cs != prefixcs_buf || p->len > (bufend-(buf-sl))) - continue; - if (memcmp(p->cs, buf-sl+1, p->len) == 0) { - //printf("CS Exact match: "); prt(p->cs, p->len); printf("\n"); - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - - } else { - COUNT(tctx->stat_loop_no_match++); - } - } - } - } -skip_loop: - shift = 1; - } else { - COUNT(tctx->stat_total_shift += shift); - COUNT(tctx->stat_num_shift++); - } - buf += shift; - } - - return cnt; -} - -uint32_t WmSearch2Hash14(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; -#ifdef WUMANBER_COUNTERS - WmThreadCtx *tctx = (WmThreadCtx *)mpm_thread_ctx->ctx; -#endif /* WUMANBER_COUNTERS */ - uint32_t cnt = 0; - uint8_t *bufend = buf + buflen - 1; - uint16_t sl = ctx->shiftlen; - uint16_t h; - uint8_t shift; - WmHashItem *thi, *hi; - WmPattern *p; - uint16_t prefixci_buf; - uint16_t prefixcs_buf; - - if (buflen == 0) - return 0; - - //printf("BUF(%" PRIu32 ") ", buflen); prt(buf,buflen); printf("\n"); - - buf+=(sl-1); - //buf++; - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - //h = (wm_tolower(*buf)<<8)+(wm_tolower(*(buf-1))); - h = HASH14(wm_tolower(*buf),(wm_tolower(*(buf-1)))); - shift = ctx->shifttable[h]; - //printf("search: h %" PRIu32 ", shift %" PRIu32 "\n", h, shift); - - if (shift == 0) { - COUNT(tctx->stat_shift_null++); - /* get our hash item */ - hi = ctx->hash[h]; - //printf("search: hi %p\n", hi); - if (hi != NULL) { - /* get our patterns from the hash */ - if (ctx->bloom[h] != NULL) { - COUNT(tctx->stat_pminlen_calls++); - COUNT(tctx->stat_pminlen_total+=ctx->pminlen[h]); - - if ((bufend - (buf-sl)) < ctx->pminlen[h]) { - goto skip_loop; - } else { - COUNT(tctx->stat_bloom_calls++); - - if (BloomFilterTest(ctx->bloom[h], buf-sl+1, ctx->pminlen[h]) == 0) { - COUNT(tctx->stat_bloom_hits++); - goto skip_loop; - } - } - } - - prefixci_buf = (uint16_t)(wm_tolower(*(buf-sl+1)) + wm_tolower(*(buf-sl+2))); - prefixcs_buf = (uint16_t)(*(buf-sl+1) + *(buf-sl+2)); - //printf("WmSearch2: prefixci_buf %" PRIu32 ", prefixcs_buf %" PRIu32 "\n", prefixci_buf, prefixcs_buf); - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - //printf("WmSearch2: p->prefix_ci %" PRIu32 ", p->prefix_cs %" PRIu32 "\n", - // p->prefix_ci, p->prefix_cs); - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (p->prefix_ci != prefixci_buf || p->len > (bufend-(buf-sl))) - continue; - - if (memcmp_lowercase(p->ci, buf-sl+1, p->len) == 0) { - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } else { - if (p->prefix_cs != prefixcs_buf || p->len > (bufend-(buf-sl))) - continue; - if (memcmp(p->cs, buf-sl+1, p->len) == 0) { - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } - } - } -skip_loop: - shift = 1; - } else { - COUNT(tctx->stat_total_shift += shift); - COUNT(tctx->stat_num_shift++); - } - buf += shift; - } - - return cnt; -} - -uint32_t WmSearch2Hash15(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; -#ifdef WUMANBER_COUNTERS - WmThreadCtx *tctx = (WmThreadCtx *)mpm_thread_ctx->ctx; -#endif /* WUMANBER_COUNTERS */ - uint32_t cnt = 0; - uint8_t *bufend = buf + buflen - 1; - uint16_t sl = ctx->shiftlen; - uint16_t h; - uint8_t shift; - WmHashItem *thi, *hi; - WmPattern *p; - uint16_t prefixci_buf; - uint16_t prefixcs_buf; - - if (buflen == 0) - return 0; - - //printf("BUF(%" PRIu32 ") ", buflen); prt(buf,buflen); printf("\n"); - - buf+=(sl-1); - //buf++; - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - //h = (wm_tolower(*buf)<<8)+(wm_tolower(*(buf-1))); - h = HASH15(wm_tolower(*buf),(wm_tolower(*(buf-1)))); - shift = ctx->shifttable[h]; - //printf("search: h %" PRIu32 ", shift %" PRIu32 "\n", h, shift); - - if (shift == 0) { - COUNT(tctx->stat_shift_null++); - /* get our hash item */ - hi = ctx->hash[h]; - //printf("search: hi %p\n", hi); - if (hi != NULL) { - /* get our patterns from the hash */ - if (ctx->bloom[h] != NULL) { - COUNT(tctx->stat_pminlen_calls++); - COUNT(tctx->stat_pminlen_total+=ctx->pminlen[h]); - - if ((bufend - (buf-sl)) < ctx->pminlen[h]) { - goto skip_loop; - } else { - COUNT(tctx->stat_bloom_calls++); - - if (BloomFilterTest(ctx->bloom[h], buf-sl+1, ctx->pminlen[h]) == 0) { - COUNT(tctx->stat_bloom_hits++); - goto skip_loop; - } - } - } - - prefixci_buf = (uint16_t)(wm_tolower(*(buf-sl+1)) + wm_tolower(*(buf-sl+2))); - prefixcs_buf = (uint16_t)(*(buf-sl+1) + *(buf-sl+2)); - //printf("WmSearch2: prefixci_buf %" PRIu32 ", prefixcs_buf %" PRIu32 "\n", prefixci_buf, prefixcs_buf); - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - //printf("WmSearch2: p->prefix_ci %" PRIu32 ", p->prefix_cs %" PRIu32 "\n", - // p->prefix_ci, p->prefix_cs); - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (p->prefix_ci != prefixci_buf || p->len > (bufend-(buf-sl))) - continue; - - if (memcmp_lowercase(p->ci, buf-sl+1, p->len) == 0) { - //printf("CI Exact match: "); prt(p->ci, p->len); printf("\n"); - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } else { - if (p->prefix_cs != prefixcs_buf || p->len > (bufend-(buf-sl))) - continue; - if (memcmp(p->cs, buf-sl+1, p->len) == 0) { - //printf("CS Exact match: "); prt(p->cs, p->len); printf("\n"); - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } - } - } -skip_loop: - shift = 1; - } else { - COUNT(tctx->stat_total_shift += shift); - COUNT(tctx->stat_num_shift++); - } - buf += shift; - } - - return cnt; -} - -uint32_t WmSearch2Hash16(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; -#ifdef WUMANBER_COUNTERS - WmThreadCtx *tctx = (WmThreadCtx *)mpm_thread_ctx->ctx; -#endif /* WUMANBER_COUNTERS */ - uint32_t cnt = 0; - uint8_t *bufend = buf + buflen - 1; - uint16_t sl = ctx->shiftlen; - uint16_t h; - uint8_t shift; - WmHashItem *thi, *hi; - WmPattern *p; - uint16_t prefixci_buf; - uint16_t prefixcs_buf; - - if (buflen == 0) - return 0; - - //printf("BUF(%" PRIu32 ") ", buflen); prt(buf,buflen); printf("\n"); - - buf+=(sl-1); - //buf++; - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - while (buf <= bufend) { - //h = (wm_tolower(*buf)<<8)+(wm_tolower(*(buf-1))); - h = HASH16(wm_tolower(*buf),(wm_tolower(*(buf-1)))); - shift = ctx->shifttable[h]; - //printf("search: h %" PRIu32 ", shift %" PRIu32 "\n", h, shift); - - if (shift == 0) { - COUNT(tctx->stat_shift_null++); - /* get our hash item */ - hi = ctx->hash[h]; - //printf("search: hi %p\n", hi); - if (hi != NULL) { - /* get our patterns from the hash */ - if (ctx->bloom[h] != NULL) { - COUNT(tctx->stat_pminlen_calls++); - COUNT(tctx->stat_pminlen_total+=ctx->pminlen[h]); - - if ((bufend - (buf-sl)) < ctx->pminlen[h]) { - goto skip_loop; - } else { - COUNT(tctx->stat_bloom_calls++); - - if (BloomFilterTest(ctx->bloom[h], buf-sl+1, ctx->pminlen[h]) == 0) { - COUNT(tctx->stat_bloom_hits++); - goto skip_loop; - } - } - } - - prefixci_buf = (uint16_t)(wm_tolower(*(buf-sl+1)) + wm_tolower(*(buf-sl+2))); - prefixcs_buf = (uint16_t)(*(buf-sl+1) + *(buf-sl+2)); - //printf("WmSearch2: prefixci_buf %" PRIu32 ", prefixcs_buf %" PRIu32 "\n", prefixci_buf, prefixcs_buf); - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - //printf("WmSearch2: p->prefix_ci %" PRIu32 ", p->prefix_cs %" PRIu32 "\n", - // p->prefix_ci, p->prefix_cs); - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (p->prefix_ci != prefixci_buf || p->len > (bufend-(buf-sl))) - continue; - - if (memcmp_lowercase(p->ci, buf-sl+1, p->len) == 0) { - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } else { - if (p->prefix_cs != prefixcs_buf || p->len > (bufend-(buf-sl))) - continue; - if (memcmp(p->cs, buf-sl+1, p->len) == 0) { - COUNT(tctx->stat_loop_match++); - - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } else { - COUNT(tctx->stat_loop_no_match++); - } - } - } - } -skip_loop: - shift = 1; - } else { - COUNT(tctx->stat_total_shift += shift); - COUNT(tctx->stat_num_shift++); - } - buf += shift; - } - - return cnt; -} - -uint32_t WmSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, uint8_t *buf, uint16_t buflen) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; - uint8_t *bufmin = buf; - uint8_t *bufend = buf + buflen - 1; - uint32_t cnt = 0; - WmPattern *p; - WmHashItem *thi, *hi; - - if (buflen == 0) - return 0; - - //printf("BUF "); prt(buf,buflen); printf("\n"); - - uint8_t *bitarray = NULL; - if (pmq) { - bitarray = alloca(pmq->pattern_id_bitarray_size); - memset(bitarray, 0, pmq->pattern_id_bitarray_size); - } - - if (mpm_ctx->minlen == 1) { - while (buf <= bufend) { - uint8_t h = wm_tolower(*buf); - hi = &ctx->hash1[h]; - - if (hi->flags & 0x01) { - for (thi = hi; thi != NULL; thi = thi->nxt) { - p = ctx->parray[thi->idx]; - - if (p->len != 1) - continue; - - if (p->flags & MPM_PATTERN_FLAG_NOCASE) { - if (wm_tolower(*buf) == p->ci[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } - } else { - if (*buf == p->cs[0]) { - cnt += MpmVerifyMatch(mpm_thread_ctx, pmq, p->id, bitarray, p->sids, p->sids_size); - } - } - } - } - buf += 1; - } - } - //printf("WmSearch1: after 1byte cnt %" PRIu32 "\n", cnt); - if (mpm_ctx->maxlen > 1) { - /* Pass bufmin on because buf no longer points to the - * start of the buffer. */ - cnt += ctx->MBSearch(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen); - //printf("WmSearch1: after 2+byte cnt %" PRIu32 "\n", cnt); - } - return cnt; -} - -/** - * \brief Function to get the user defined values for wumanber algorithm from - * the config file 'suricata.yaml' - */ -void WmGetConfig() -{ - ConfNode *wm_conf; - const char *hash_val = NULL; - const char *bloom_val = NULL; - - /* init defaults */ - wm_hash_size = HASHSIZE_LOW; - wm_bloom_size = BLOOMSIZE_MEDIUM; - - ConfNode *pm = ConfGetNode("pattern-matcher"); - - if (pm != NULL) { - - TAILQ_FOREACH(wm_conf, &pm->head, next) { - if (strncmp(wm_conf->val, "wumanber", 8) == 0) { - hash_val = ConfNodeLookupChildValue(wm_conf->head.tqh_first, - "hash_size"); - bloom_val = ConfNodeLookupChildValue(wm_conf->head.tqh_first, - "bf_size"); - - if (hash_val != NULL) - wm_hash_size = MpmGetHashSize(hash_val); - - if (bloom_val != NULL) - wm_bloom_size = MpmGetBloomSize(bloom_val); - - SCLogDebug("hash size is %"PRIu32" and bloom size is %"PRIu32"", - wm_hash_size, wm_bloom_size); - } - } - } -} - -void WmInitCtx (MpmCtx *mpm_ctx) -{ - SCLogDebug("mpm_ctx %p", mpm_ctx); - - mpm_ctx->ctx = SCMalloc(sizeof(WmCtx)); - if (mpm_ctx->ctx == NULL) - return; - memset(mpm_ctx->ctx, 0, sizeof(WmCtx)); - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(WmCtx); - - /* initialize the hash we use to speed up pattern insertions */ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; - ctx->init_hash = SCMalloc(sizeof(WmPattern *) * INIT_HASH_SIZE); - if (ctx->init_hash == NULL) - return; - - memset(ctx->init_hash, 0, sizeof(WmPattern *) * INIT_HASH_SIZE); - - /* Initialize the defaults value from the config file. The given check make - sure that we query config file only once for config values */ - if (wm_hash_size == 0) - WmGetConfig(); - -} - -void WmDestroyCtx(MpmCtx *mpm_ctx) -{ - WmCtx *ctx = (WmCtx *)mpm_ctx->ctx; - if (ctx == NULL) - return; - - if (ctx->init_hash) { - SCFree(ctx->init_hash); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (INIT_HASH_SIZE * sizeof(WmPattern *)); - } - - if (ctx->parray) { - uint32_t i; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - WmFreePattern(mpm_ctx, ctx->parray[i]); - } - } - - SCFree(ctx->parray); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(WmPattern)); - } - - if (ctx->bloom) { - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - if (ctx->bloom[h] == NULL) - continue; - - mpm_ctx->memory_cnt -= BloomFilterMemoryCnt(ctx->bloom[h]); - mpm_ctx->memory_size -= BloomFilterMemorySize(ctx->bloom[h]); - - BloomFilterFree(ctx->bloom[h]); - } - - SCFree(ctx->bloom); - - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(BloomFilter *) * ctx->hash_size); - } - - if (ctx->hash) { - uint32_t h; - for (h = 0; h < ctx->hash_size; h++) { - if (ctx->hash[h] == NULL) - continue; - - WmHashFree(mpm_ctx, ctx->hash[h]); - } - - SCFree(ctx->hash); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(WmHashItem) * ctx->hash_size); - } - - if (ctx->shifttable) { - SCFree(ctx->shifttable); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(uint16_t) * ctx->hash_size); - } - - if (ctx->pminlen) { - SCFree(ctx->pminlen); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (sizeof(uint8_t) * ctx->hash_size); - } - - SCFree(mpm_ctx->ctx); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(WmCtx); -} - -void WmThreadInitCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, uint32_t matchsize) -{ - memset(mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - -#ifdef WUMANBER_COUNTERS - mpm_thread_ctx->ctx = SCMalloc(sizeof(WmThreadCtx)); - if (mpm_thread_ctx->ctx == NULL) - return; - - memset(mpm_thread_ctx->ctx, 0, sizeof(WmThreadCtx)); - - mpm_thread_ctx->memory_cnt++; - mpm_thread_ctx->memory_size += sizeof(WmThreadCtx); -#endif -} - -void WmThreadDestroyCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx) -{ - WmThreadCtx *ctx = (WmThreadCtx *)mpm_thread_ctx->ctx; - if (ctx != NULL) { /* size can be 0 when optimized */ - mpm_thread_ctx->memory_cnt--; - mpm_thread_ctx->memory_size -= sizeof(WmThreadCtx); - SCFree(mpm_thread_ctx->ctx); - } -} - -void MpmWuManberRegister (void) -{ - mpm_table[MPM_WUMANBER].name = "wumanber"; - mpm_table[MPM_WUMANBER].max_pattern_length = 0; - mpm_table[MPM_WUMANBER].InitCtx = WmInitCtx; - mpm_table[MPM_WUMANBER].InitThreadCtx = WmThreadInitCtx; - mpm_table[MPM_WUMANBER].DestroyCtx = WmDestroyCtx; - mpm_table[MPM_WUMANBER].DestroyThreadCtx = WmThreadDestroyCtx; - mpm_table[MPM_WUMANBER].AddPattern = WmAddPatternCS; - mpm_table[MPM_WUMANBER].AddPatternNocase = WmAddPatternCI; - mpm_table[MPM_WUMANBER].Prepare = WmPreparePatterns; - mpm_table[MPM_WUMANBER].Search = WmSearch; - mpm_table[MPM_WUMANBER].Cleanup = NULL; - mpm_table[MPM_WUMANBER].PrintCtx = WmPrintInfo; - mpm_table[MPM_WUMANBER].PrintThreadCtx = WmPrintSearchStats; - mpm_table[MPM_WUMANBER].RegisterUnittests = WmRegisterTests; - - /* create table for O(1) lowercase conversion lookup */ - int c = 0; - for ( ; c < 256; c++) { - if (c >= 'A' && c <= 'Z') - lowercasetable[c] = (c + ('a' - 'A')); - else - lowercasetable[c] = c; - } -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -#ifdef UNITTESTS -int WmTestInitCtx01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - WmInitCtx(&mpm_ctx); - - if (mpm_ctx.ctx != NULL) - result = 1; - - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestInitCtx02 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - WmInitCtx(&mpm_ctx); - - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - if (ctx->parray == NULL) - result = 1; - - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestInitCtx03 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - - if (mpm_table[MPM_WUMANBER].Search == WmSearch) - result = 1; - - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestThreadInitCtx01 (void) -{ -#ifdef WUMANBER_COUNTERS - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - if (mpm_thread_ctx.memory_cnt == 2) - result = 1; - else - printf("mpm_thread_ctx.memory_cnt %"PRIu32", expected 2: ", mpm_thread_ctx.memory_cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -#else - return 1; -#endif -} - -int WmTestThreadInitCtx02 (void) -{ -#ifdef WUMANBER_COUNTERS - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - WmThreadCtx *tctx = (WmThreadCtx *)mpm_thread_ctx.ctx; - - if (tctx->search_stat_shift_null == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); -#else - int result = 1; -#endif - return result; -} - -int WmTestInitAddPattern01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - int ret = MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 1234, 0, 0); - if (ret == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestInitAddPattern02 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 1234, 0, 0); - if (ctx->init_hash != NULL) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestInitAddPattern03 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 1234, 0, 0); - WmPattern *pat = WmInitHashLookup(ctx, (uint8_t *)"abcd", 4, 0); - if (pat != NULL) { - if (pat->len == 4) - result = 1; - } - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestInitAddPattern04 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 1234, 0, 0); - WmPattern *pat = WmInitHashLookup(ctx, (uint8_t *)"abcd", 4, MPM_PATTERN_FLAG_NOCASE); - if (pat != NULL) { - if (pat->flags & MPM_PATTERN_FLAG_NOCASE) - result = 1; - } - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestInitAddPattern05 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 1234, 0, 0); - WmPattern *pat = WmInitHashLookup(ctx, (uint8_t *)"abcd", 4, 0); - if (pat != NULL) { - if (!(pat->flags & MPM_PATTERN_FLAG_NOCASE)) - result = 1; - } - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestInitAddPattern06 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 1234, 0, 0); - WmPattern *pat = WmInitHashLookup(ctx, (uint8_t *)"abcd", 4, 0); - if (pat != NULL) { - if (memcmp(pat->cs, "abcd", 4) == 0) - result = 1; - } - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestPrepare01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"a", 1, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - - if (ctx->Search == WmSearch1) - result = 1; - - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestPrepare02 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - if (ctx->shiftlen == 4) - result = 1; - - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestPrepare03 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - if (ctx->shifttable[1] == 4) - result = 1; - else - printf("4 != %" PRIu32 ": ", ctx->shifttable[1]); - - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestPrepare04 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"a", 1, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - - if (ctx->Search == WmSearch1) - result = 1; - - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestPrepare05 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - if (ctx->shiftlen == 4) - result = 1; - - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestPrepare06 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - if (ctx->shifttable[1] == 4) - result = 1; - else - printf("4 != %" PRIu32 ": ", ctx->shifttable[1]); - - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch01 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - //mpm_ctx.PrintCtx(&mpm_ctx); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcd", 4); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ", cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch01Hash12 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - - ctx->hash_size = HASH12_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - //mpm_ctx.PrintCtx(&mpm_ctx); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcd", 4); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ", cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch01Hash14 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - - ctx->hash_size = HASH14_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - //mpm_ctx.PrintCtx(&mpm_ctx); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcd", 4); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ", cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch01Hash15 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - - ctx->hash_size = HASH15_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - //mpm_ctx.PrintCtx(&mpm_ctx); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcd", 4); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ", cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch01Hash16 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - - ctx->hash_size = HASH16_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - //mpm_ctx.PrintCtx(&mpm_ctx); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcd", 4); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ", cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch02 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abce", 4); - - if (cnt == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch03 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ", cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch04 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - if (cnt == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch05 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"efgh", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - if (cnt == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch06 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"eFgH", 4, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdEfGh", 8); - - if (cnt == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch07 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"eFgH", 4, 0, 0, 1, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdEfGh", 8); - - if (cnt == 2) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch08 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - if (cnt == 2) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch09 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ab", 2, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"ab", 2); - - if (cnt == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch10 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bc", 2, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"gh", 2, 0, 0, 1, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - if (cnt == 2) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch11 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"a", 1, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"d", 1, 0, 0, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"h", 1, 0, 0, 2, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - if (cnt == 3) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch12 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"d", 1, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"Z", 1, 0, 0, 2, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 ": ", cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch13 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"a", 1, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"de",2, 0, 0, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"h", 1, 0, 0, 2, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 ": ", cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch14 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"de",2, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"Z", 1, 0, 0, 2, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - if (cnt == 2) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -/** \todo VJ disabled because it tests the old match storage */ -#if 0 -int WmTestSearch15 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 1, 1, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"de",2, 0, 0, 1, 1, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"Z", 1, 0, 0, 1, 1, 2, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - uint32_t len = mpm_thread_ctx.match[1].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch16 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 1, 1, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"de",2, 0, 0, 1, 1, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"Z", 1, 0, 0, 1, 1, 2, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"abcdefgh", 8); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch17 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch18Hash12 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH12_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch18Hash14 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH14_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch18Hash15 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH15_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch18 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH16_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch18Hash16 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH16_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch19 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch19Hash12 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH12_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch19Hash14 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH14_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch19Hash15 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH15_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch19Hash16 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"/VideoAccessCodecInstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH16_SIZE; - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstaLL.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch20 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch20Hash12 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH12_SIZE; /* force hash12 */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch20Hash14 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH14_SIZE; /* force hash14 */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch20Hash15 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH15_SIZE; /* force hash15 */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch20Hash16 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH16_SIZE; /* force hash16 */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/VideoAccessCodecInstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 0) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -int WmTestSearch21 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/videoaccesscodecinstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -static int WmTestSearch21Hash12 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH12_SIZE; /* force hash16 */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - //WmPrintInfo(&mpm_ctx); - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/videoaccesscodecinstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -static int WmTestSearch21Hash14 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH14_SIZE; /* force hash16 */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - //WmPrintInfo(&mpm_ctx); - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/videoaccesscodecinstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -static int WmTestSearch21Hash15 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH15_SIZE; /* force hash16 */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - //WmPrintInfo(&mpm_ctx); - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/videoaccesscodecinstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -static int WmTestSearch21Hash16 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"/videoaccesscodecinstall.exe", 28, 0, 0, 0, 0, 0); - ctx->hash_size = HASH16_SIZE; /* force hash16 */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1); - //WmPrintInfo(&mpm_ctx); - ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"/videoaccesscodecinstall.exe", 28); - - uint32_t len = mpm_thread_ctx.match[0].len; - - - if (len == 1) - result = 1; - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} -#endif -static int WmTestSearch22Hash9 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0, 0); /* 1 */ - /* total matches: 135 */ - - ctx->hash_size = HASH9_SIZE; /* force hash size */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 6 /* 6 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30); - - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -static int WmTestSearch22Hash12 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0, 0); /* 1 */ - /* total matches: 135 */ - - ctx->hash_size = HASH12_SIZE; /* force hash size */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 6 /* 6 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30); - - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -static int WmTestSearch22Hash14 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0, 0); /* 1 */ - /* total matches: 135 */ - - ctx->hash_size = HASH14_SIZE; /* force hash size */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 6 /* 6 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30); - - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -static int WmTestSearch22Hash15 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0, 0); /* 1 */ - /* total matches: 135 */ - - ctx->hash_size = HASH15_SIZE; /* force hash size */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 6 /* 6 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30); - - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} - -static int WmTestSearch22Hash16 (void) -{ - int result = 0; - MpmCtx mpm_ctx; - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - MpmThreadCtx mpm_thread_ctx; - MpmInitCtx(&mpm_ctx, MPM_WUMANBER); - WmCtx *ctx = (WmCtx *)mpm_ctx.ctx; - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0, 0); /* 1 */ - /* total matches: 135 */ - - ctx->hash_size = HASH16_SIZE; /* force hash size */ - WmPreparePatterns(&mpm_ctx); - WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 6 /* 6 patterns */); - - uint32_t cnt = ctx->Search(&mpm_ctx, &mpm_thread_ctx, NULL, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30); - - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - WmThreadDestroyCtx(&mpm_ctx, &mpm_thread_ctx); - WmDestroyCtx(&mpm_ctx); - return result; -} -#endif /* UNITTESTS */ - -void WmRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("WmTestInitCtx01", WmTestInitCtx01, 1); - UtRegisterTest("WmTestInitCtx02", WmTestInitCtx02, 1); - UtRegisterTest("WmTestInitCtx03", WmTestInitCtx03, 1); - - UtRegisterTest("WmTestThreadInitCtx01", WmTestThreadInitCtx01, 1); - UtRegisterTest("WmTestThreadInitCtx02", WmTestThreadInitCtx02, 1); - - UtRegisterTest("WmTestInitAddPattern01", WmTestInitAddPattern01, 1); - UtRegisterTest("WmTestInitAddPattern02", WmTestInitAddPattern02, 1); - UtRegisterTest("WmTestInitAddPattern03", WmTestInitAddPattern03, 1); - UtRegisterTest("WmTestInitAddPattern04", WmTestInitAddPattern04, 1); - UtRegisterTest("WmTestInitAddPattern05", WmTestInitAddPattern05, 1); - UtRegisterTest("WmTestInitAddPattern06", WmTestInitAddPattern06, 1); - - UtRegisterTest("WmTestPrepare01", WmTestPrepare01, 1); - UtRegisterTest("WmTestPrepare02", WmTestPrepare02, 1); - UtRegisterTest("WmTestPrepare03", WmTestPrepare03, 1); - UtRegisterTest("WmTestPrepare04", WmTestPrepare01, 1); - UtRegisterTest("WmTestPrepare05", WmTestPrepare02, 1); - UtRegisterTest("WmTestPrepare06", WmTestPrepare03, 1); - - UtRegisterTest("WmTestSearch01", WmTestSearch01, 1); - UtRegisterTest("WmTestSearch01Hash12", WmTestSearch01Hash12, 1); - UtRegisterTest("WmTestSearch01Hash14", WmTestSearch01Hash14, 1); - UtRegisterTest("WmTestSearch01Hash15", WmTestSearch01Hash15, 1); - UtRegisterTest("WmTestSearch01Hash16", WmTestSearch01Hash16, 1); - - UtRegisterTest("WmTestSearch02", WmTestSearch02, 1); - UtRegisterTest("WmTestSearch03", WmTestSearch03, 1); - UtRegisterTest("WmTestSearch04", WmTestSearch04, 1); - UtRegisterTest("WmTestSearch05", WmTestSearch05, 1); - UtRegisterTest("WmTestSearch06", WmTestSearch06, 1); - UtRegisterTest("WmTestSearch07", WmTestSearch07, 1); - UtRegisterTest("WmTestSearch08", WmTestSearch08, 1); - UtRegisterTest("WmTestSearch09", WmTestSearch09, 1); - UtRegisterTest("WmTestSearch10", WmTestSearch10, 1); - UtRegisterTest("WmTestSearch11", WmTestSearch11, 1); - UtRegisterTest("WmTestSearch12", WmTestSearch12, 1); - UtRegisterTest("WmTestSearch13", WmTestSearch13, 1); - - UtRegisterTest("WmTestSearch14", WmTestSearch14, 1); -#if 0 - UtRegisterTest("WmTestSearch15", WmTestSearch15, 1); - UtRegisterTest("WmTestSearch16", WmTestSearch16, 1); - UtRegisterTest("WmTestSearch17", WmTestSearch17, 1); - - UtRegisterTest("WmTestSearch18", WmTestSearch18, 1); - UtRegisterTest("WmTestSearch18Hash12", WmTestSearch18Hash12, 1); - UtRegisterTest("WmTestSearch18Hash14", WmTestSearch18Hash14, 1); - UtRegisterTest("WmTestSearch18Hash15", WmTestSearch18Hash15, 1); - UtRegisterTest("WmTestSearch18Hash16", WmTestSearch18Hash16, 1); - - UtRegisterTest("WmTestSearch19", WmTestSearch19, 1); - UtRegisterTest("WmTestSearch19Hash12", WmTestSearch19Hash12, 1); - UtRegisterTest("WmTestSearch19Hash14", WmTestSearch19Hash14, 1); - UtRegisterTest("WmTestSearch19Hash15", WmTestSearch19Hash15, 1); - UtRegisterTest("WmTestSearch19Hash16", WmTestSearch19Hash16, 1); - - UtRegisterTest("WmTestSearch20", WmTestSearch20, 1); - UtRegisterTest("WmTestSearch20Hash12", WmTestSearch20Hash12, 1); - UtRegisterTest("WmTestSearch20Hash14", WmTestSearch20Hash14, 1); - UtRegisterTest("WmTestSearch20Hash15", WmTestSearch20Hash15, 1); - UtRegisterTest("WmTestSearch20Hash16", WmTestSearch20Hash16, 1); - - UtRegisterTest("WmTestSearch21", WmTestSearch21, 1); - UtRegisterTest("WmTestSearch21Hash12", WmTestSearch21Hash12, 1); - UtRegisterTest("WmTestSearch21Hash14", WmTestSearch21Hash14, 1); - UtRegisterTest("WmTestSearch21Hash15", WmTestSearch21Hash15, 1); - UtRegisterTest("WmTestSearch21Hash16", WmTestSearch21Hash16, 1); -#endif - UtRegisterTest("WmTestSearch22Hash9", WmTestSearch22Hash9, 1); - UtRegisterTest("WmTestSearch22Hash12", WmTestSearch22Hash12, 1); - UtRegisterTest("WmTestSearch22Hash14", WmTestSearch22Hash14, 1); - UtRegisterTest("WmTestSearch22Hash15", WmTestSearch22Hash15, 1); - UtRegisterTest("WmTestSearch22Hash16", WmTestSearch22Hash16, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/util-mpm-wumanber.h b/framework/src/suricata/src/util-mpm-wumanber.h deleted file mode 100644 index ef699814..00000000 --- a/framework/src/suricata/src/util-mpm-wumanber.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_MPM_WUMANBER_H__ -#define __UTIL_MPM_WUMANBER_H__ - -#include "util-mpm.h" -#include "util-bloomfilter.h" - -//#define WUMANBER_COUNTERS - -typedef struct WmPattern_ { - uint8_t *cs; /* case sensitive */ - uint8_t *ci; /* case INsensitive */ - uint16_t len; - struct WmPattern_ *next; - uint16_t prefix_ci; - uint16_t prefix_cs; - uint8_t flags; - uint32_t id; /* global pattern id */ - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; - -} WmPattern; - -typedef struct WmHashItem_ { - uint8_t flags; - uint16_t idx; - struct WmHashItem_ *nxt; -} WmHashItem; - -typedef struct WmCtx_ { - /* hash used during ctx initialization */ - WmPattern **init_hash; - - uint16_t shiftlen; - - uint32_t hash_size; - WmHashItem **hash; - BloomFilter **bloom; - uint8_t *pminlen; /* array containing the minimal length - of the patters in a hash bucket. Used - for the BloomFilter. */ - WmHashItem hash1[256]; - - /* we store our own search func ptr here for WmSearch1 */ - uint32_t (*Search)(struct MpmCtx_ *, struct MpmThreadCtx_ *, PatternMatcherQueue *, uint8_t *, uint16_t); - /* we store our own multi byte search func ptr here for WmSearch1 */ - uint32_t (*MBSearch)(struct MpmCtx_ *, struct MpmThreadCtx_ *, PatternMatcherQueue *, uint8_t *, uint16_t); - - /* pattern arrays */ - WmPattern **parray; - - /* only used for multibyte pattern search */ - uint16_t *shifttable; -} WmCtx; - -typedef struct WmThreadCtx_ { -#ifdef WUMANBER_COUNTERS - uint32_t stat_pminlen_calls; - uint32_t stat_pminlen_total; - uint32_t stat_bloom_calls; - uint32_t stat_bloom_hits; - uint32_t stat_shift_null; - uint32_t stat_loop_match; - uint32_t stat_loop_no_match; - uint32_t stat_num_shift; - uint32_t stat_total_shift; -#endif /* WUMANBER_COUNTERS */ -} WmThreadCtx; - -void MpmWuManberRegister(void); - -#endif /* __UTIL_MPM_WUMANBER_H__ */ - diff --git a/framework/src/suricata/src/util-mpm.c b/framework/src/suricata/src/util-mpm.c deleted file mode 100644 index ac185e30..00000000 --- a/framework/src/suricata/src/util-mpm.c +++ /dev/null @@ -1,785 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Pattern matcher utility Functions - */ - -#include "suricata-common.h" -#include "util-mpm.h" -#include "util-debug.h" - -/* include pattern matchers */ -#include "util-mpm-wumanber.h" -#include "util-mpm-b2g.h" -#include "util-mpm-b3g.h" -#include "util-mpm-ac.h" -#include "util-mpm-ac-gfbs.h" -#include "util-mpm-ac-bs.h" -#include "util-mpm-ac-tile.h" -#include "util-hashlist.h" - -#include "detect-engine.h" -#include "util-cuda.h" -#include "util-misc.h" -#include "conf.h" -#include "conf-yaml-loader.h" -#include "queue.h" -#include "util-unittest.h" -#ifdef __SC_CUDA_SUPPORT__ -#include "util-cuda-handlers.h" -#include "detect-engine-mpm.h" -#endif - -/** - * \brief Register a new Mpm Context. - * - * \param name A new profile to be registered to store this MpmCtx. - * - * \retval id Return the id created for the new MpmCtx profile. - */ -int32_t MpmFactoryRegisterMpmCtxProfile(DetectEngineCtx *de_ctx, const char *name, uint8_t flags) -{ - void *ptmp; - /* the very first entry */ - if (de_ctx->mpm_ctx_factory_container == NULL) { - de_ctx->mpm_ctx_factory_container = SCMalloc(sizeof(MpmCtxFactoryContainer)); - if (de_ctx->mpm_ctx_factory_container == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(de_ctx->mpm_ctx_factory_container, 0, sizeof(MpmCtxFactoryContainer)); - - MpmCtxFactoryItem *item = SCMalloc(sizeof(MpmCtxFactoryItem)); - if (unlikely(item == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - - item[0].name = SCStrdup(name); - if (item[0].name == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - - /* toserver */ - item[0].mpm_ctx_ts = SCMalloc(sizeof(MpmCtx)); - if (item[0].mpm_ctx_ts == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(item[0].mpm_ctx_ts, 0, sizeof(MpmCtx)); - item[0].mpm_ctx_ts->global = 1; - - /* toclient */ - item[0].mpm_ctx_tc = SCMalloc(sizeof(MpmCtx)); - if (item[0].mpm_ctx_tc == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(item[0].mpm_ctx_tc, 0, sizeof(MpmCtx)); - item[0].mpm_ctx_tc->global = 1; - - /* our id starts from 0 always. Helps us with the ctx retrieval from - * the array */ - item[0].id = 0; - - /* store the flag */ - item[0].flags = flags; - - /* store the newly created item */ - de_ctx->mpm_ctx_factory_container->items = item; - de_ctx->mpm_ctx_factory_container->no_of_items++; - - /* the first id is always 0 */ - return item[0].id; - } else { - int i; - MpmCtxFactoryItem *items = de_ctx->mpm_ctx_factory_container->items; - for (i = 0; i < de_ctx->mpm_ctx_factory_container->no_of_items; i++) { - if (items[i].name != NULL && strcmp(items[i].name, name) == 0) { - /* looks like we have this mpm_ctx freed */ - if (items[i].mpm_ctx_ts == NULL) { - items[i].mpm_ctx_ts = SCMalloc(sizeof(MpmCtx)); - if (items[i].mpm_ctx_ts == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(items[i].mpm_ctx_ts, 0, sizeof(MpmCtx)); - items[i].mpm_ctx_ts->global = 1; - } - if (items[i].mpm_ctx_tc == NULL) { - items[i].mpm_ctx_tc = SCMalloc(sizeof(MpmCtx)); - if (items[i].mpm_ctx_tc == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(items[i].mpm_ctx_tc, 0, sizeof(MpmCtx)); - items[i].mpm_ctx_tc->global = 1; - } - items[i].flags = flags; - return items[i].id; - } - } - - /* let's make the new entry */ - ptmp = SCRealloc(items, - (de_ctx->mpm_ctx_factory_container->no_of_items + 1) * sizeof(MpmCtxFactoryItem)); - if (unlikely(ptmp == NULL)) { - SCFree(items); - items = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - items = ptmp; - - de_ctx->mpm_ctx_factory_container->items = items; - - MpmCtxFactoryItem *new_item = &items[de_ctx->mpm_ctx_factory_container->no_of_items]; - new_item[0].name = SCStrdup(name); - if (new_item[0].name == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - - /* toserver */ - new_item[0].mpm_ctx_ts = SCMalloc(sizeof(MpmCtx)); - if (new_item[0].mpm_ctx_ts == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(new_item[0].mpm_ctx_ts, 0, sizeof(MpmCtx)); - new_item[0].mpm_ctx_ts->global = 1; - - /* toclient */ - new_item[0].mpm_ctx_tc = SCMalloc(sizeof(MpmCtx)); - if (new_item[0].mpm_ctx_tc == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(new_item[0].mpm_ctx_tc, 0, sizeof(MpmCtx)); - new_item[0].mpm_ctx_tc->global = 1; - - new_item[0].id = de_ctx->mpm_ctx_factory_container->no_of_items; - new_item[0].flags = flags; - de_ctx->mpm_ctx_factory_container->no_of_items++; - - /* the newly created id */ - return new_item[0].id; - } -} - -int32_t MpmFactoryIsMpmCtxAvailable(DetectEngineCtx *de_ctx, MpmCtx *mpm_ctx) -{ - if (mpm_ctx == NULL) - return 0; - - if (de_ctx->mpm_ctx_factory_container == NULL) { - return 0; - } else { - int i; - for (i = 0; i < de_ctx->mpm_ctx_factory_container->no_of_items; i++) { - if (mpm_ctx == de_ctx->mpm_ctx_factory_container->items[i].mpm_ctx_ts || - mpm_ctx == de_ctx->mpm_ctx_factory_container->items[i].mpm_ctx_tc) { - return 1; - } - } - return 0; - } -} - -MpmCtx *MpmFactoryGetMpmCtxForProfile(DetectEngineCtx *de_ctx, int32_t id, int direction) -{ - if (id == MPM_CTX_FACTORY_UNIQUE_CONTEXT) { - MpmCtx *mpm_ctx = SCMalloc(sizeof(MpmCtx)); - if (unlikely(mpm_ctx == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - exit(EXIT_FAILURE); - } - memset(mpm_ctx, 0, sizeof(MpmCtx)); - return mpm_ctx; - } else if (id < -1) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument - %d\n", id); - return NULL; - } else if (id >= de_ctx->mpm_ctx_factory_container->no_of_items) { - /* this id does not exist */ - return NULL; - } else { - return (direction == 0) ? - de_ctx->mpm_ctx_factory_container->items[id].mpm_ctx_ts : - de_ctx->mpm_ctx_factory_container->items[id].mpm_ctx_tc; - } -} - -void MpmFactoryReClaimMpmCtx(DetectEngineCtx *de_ctx, MpmCtx *mpm_ctx) -{ - if (mpm_ctx == NULL) - return; - - if (!MpmFactoryIsMpmCtxAvailable(de_ctx, mpm_ctx)) { - if (mpm_ctx->mpm_type != MPM_NOTSET) - mpm_table[mpm_ctx->mpm_type].DestroyCtx(mpm_ctx); - SCFree(mpm_ctx); - } - - return; -} - -void MpmFactoryDeRegisterAllMpmCtxProfiles(DetectEngineCtx *de_ctx) -{ - if (de_ctx->mpm_ctx_factory_container == NULL) - return; - - int i = 0; - MpmCtxFactoryItem *items = de_ctx->mpm_ctx_factory_container->items; - for (i = 0; i < de_ctx->mpm_ctx_factory_container->no_of_items; i++) { - if (items[i].name != NULL) - SCFree(items[i].name); - if (items[i].mpm_ctx_ts != NULL) { - if (items[i].mpm_ctx_ts->mpm_type != MPM_NOTSET) - mpm_table[items[i].mpm_ctx_ts->mpm_type].DestroyCtx(items[i].mpm_ctx_ts); - SCFree(items[i].mpm_ctx_ts); - } - if (items[i].mpm_ctx_tc != NULL) { - if (items[i].mpm_ctx_tc->mpm_type != MPM_NOTSET) - mpm_table[items[i].mpm_ctx_tc->mpm_type].DestroyCtx(items[i].mpm_ctx_tc); - SCFree(items[i].mpm_ctx_tc); - } - } - - SCFree(de_ctx->mpm_ctx_factory_container->items); - SCFree(de_ctx->mpm_ctx_factory_container); - de_ctx->mpm_ctx_factory_container = NULL; - - return; -} - -#ifdef __SC_CUDA_SUPPORT__ - -static void MpmCudaConfFree(void *conf) -{ - SCFree(conf); - return; -} - -static void *MpmCudaConfParse(ConfNode *node) -{ - const char *value; - - MpmCudaConf *conf = SCMalloc(sizeof(MpmCudaConf)); - if (unlikely(conf == NULL)) - exit(EXIT_FAILURE); - memset(conf, 0, sizeof(*conf)); - - if (node != NULL) - value = ConfNodeLookupChildValue(node, "data-buffer-size-min-limit"); - else - value = NULL; - if (value == NULL) { - /* default */ - conf->data_buffer_size_min_limit = UTIL_MPM_CUDA_DATA_BUFFER_SIZE_MIN_LIMIT_DEFAULT; - } else if (ParseSizeStringU16(value, &conf->data_buffer_size_min_limit) < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for %s." - "data-buffer-size-min-limit - \"%s\"", node->name, value); - exit(EXIT_FAILURE); - } - - if (node != NULL) - value = ConfNodeLookupChildValue(node, "data-buffer-size-max-limit"); - else - value = NULL; - if (value == NULL) { - /* default */ - conf->data_buffer_size_max_limit = UTIL_MPM_CUDA_DATA_BUFFER_SIZE_MAX_LIMIT_DEFAULT; - } else if (ParseSizeStringU16(value, &conf->data_buffer_size_max_limit) < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for %s." - "data-buffer-size-max-limit - \"%s\"", node->name, value); - exit(EXIT_FAILURE); - } - - if (node != NULL) - value = ConfNodeLookupChildValue(node, "cudabuffer-buffer-size"); - else - value = NULL; - if (value == NULL) { - /* default */ - conf->cb_buffer_size = UTIL_MPM_CUDA_CUDA_BUFFER_DBUFFER_SIZE_DEFAULT; - } else if (ParseSizeStringU32(value, &conf->cb_buffer_size) < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for %s." - "cb-buffer-size - \"%s\"", node->name, value); - exit(EXIT_FAILURE); - } - - if (node != NULL) - value = ConfNodeLookupChildValue(node, "gpu-transfer-size"); - else - value = NULL; - if (value == NULL) { - /* default */ - conf->gpu_transfer_size = UTIL_MPM_CUDA_GPU_TRANSFER_SIZE; - } else if (ParseSizeStringU32(value, &conf->gpu_transfer_size) < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for %s." - "gpu-transfer-size - \"%s\"", node->name, value); - exit(EXIT_FAILURE); - } - - if (node != NULL) - value = ConfNodeLookupChildValue(node, "batching-timeout"); - else - value = NULL; - if (value == NULL) { - /* default */ - conf->batching_timeout = UTIL_MPM_CUDA_BATCHING_TIMEOUT_DEFAULT; - } else if ((conf->batching_timeout = atoi(value)) < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for %s." - "batching-timeout - \"%s\"", node->name, value); - exit(EXIT_FAILURE); - } - - if (node != NULL) - value = ConfNodeLookupChildValue(node, "device-id"); - else - value = NULL; - if (value == NULL) { - /* default */ - conf->device_id = UTIL_MPM_CUDA_DEVICE_ID_DEFAULT; - } else if ((conf->device_id = atoi(value)) < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for %s." - "device-id - \"%s\"", node->name, value); - exit(EXIT_FAILURE); - } - - if (node != NULL) - value = ConfNodeLookupChildValue(node, "cuda-streams"); - else - value = NULL; - if (value == NULL) { - /* default */ - conf->cuda_streams = UTIL_MPM_CUDA_CUDA_STREAMS_DEFAULT; - } else if ((conf->cuda_streams = atoi(value)) < 0) { - SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid entry for %s." - "cuda-streams - \"%s\"", node->name, value); - exit(EXIT_FAILURE); - } - - return conf; -} - -void MpmCudaEnvironmentSetup() -{ - if (PatternMatchDefaultMatcher() != MPM_AC_CUDA) - return; - - CudaHandlerAddCudaProfileFromConf("mpm", MpmCudaConfParse, MpmCudaConfFree); - - MpmCudaConf *conf = CudaHandlerGetCudaProfile("mpm"); - if (conf == NULL) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error obtaining cuda mpm " - "profile."); - exit(EXIT_FAILURE); - } - - if (MpmCudaBufferSetup() < 0) { - SCLogError(SC_ERR_AC_CUDA_ERROR, "Error setting up env for ac " - "cuda"); - exit(EXIT_FAILURE); - } - - return; -} - -#endif - -/** - * \brief Setup a pmq - * - * \param pmq Pattern matcher queue to be initialized - * \param maxid Max sig id to be matched on - * \param patmaxid Max pattern id to be matched on - * - * \retval -1 error - * \retval 0 ok - */ -int PmqSetup(PatternMatcherQueue *pmq, uint32_t patmaxid) -{ - SCEnter(); - SCLogDebug("patmaxid %u", patmaxid); - - if (pmq == NULL) { - SCReturnInt(-1); - } - - memset(pmq, 0, sizeof(PatternMatcherQueue)); - - if (patmaxid > 0) { - pmq->pattern_id_array_size = 32; /* Intial size, TODO Make this configure option */ - pmq->pattern_id_array_cnt = 0; - - pmq->pattern_id_array = SCCalloc(pmq->pattern_id_array_size, sizeof(uint32_t)); - if (pmq->pattern_id_array == NULL) { - SCReturnInt(-1); - } - - /* lookup bitarray */ - pmq->pattern_id_bitarray_size = (patmaxid / 8) + 1; - - pmq->pattern_id_bitarray = SCMalloc(pmq->pattern_id_bitarray_size); - if (pmq->pattern_id_bitarray == NULL) { - SCReturnInt(-1); - } - memset(pmq->pattern_id_bitarray, 0, pmq->pattern_id_bitarray_size); - - SCLogDebug("pmq->pattern_id_array %p, pmq->pattern_id_bitarray %p", - pmq->pattern_id_array, pmq->pattern_id_bitarray); - - pmq->rule_id_array_size = 128; /* Initial size, TODO: Make configure option. */ - pmq->rule_id_array_cnt = 0; - - size_t bytes = pmq->rule_id_array_size * sizeof(SigIntId); - pmq->rule_id_array = (SigIntId*)SCMalloc(bytes); - if (pmq->rule_id_array == NULL) { - pmq->rule_id_array_size = 0; - SCReturnInt(-1); - } - // Don't need to zero memory since it is always written first. - } - - SCReturnInt(0); -} - -/** \brief Add array of Signature IDs to rule ID array. - * - * Checks size of the array first - * - * \param pmq storage for match results - * \param new_size number of Signature IDs needing to be stored. - * - */ -int -MpmAddSidsResize(PatternMatcherQueue *pmq, uint32_t new_size) -{ - /* Need to make the array bigger. Double the size needed to - * also handle the case that sids_size might still be - * larger than the old size. - */ - new_size = new_size * 2; - SigIntId *new_array = (SigIntId*)SCRealloc(pmq->rule_id_array, - new_size * sizeof(SigIntId)); - if (unlikely(new_array == NULL)) { - /* Try again just big enough. */ - new_size = new_size / 2; - new_array = (SigIntId*)SCRealloc(pmq->rule_id_array, - new_size * sizeof(SigIntId)); - if (unlikely(new_array == NULL)) { - - SCLogError(SC_ERR_MEM_ALLOC, "Failed to realloc PatternMatchQueue" - " rule ID array. Some signature ID matches lost"); - return 0; - } - } - pmq->rule_id_array = new_array; - pmq->rule_id_array_size = new_size; - - return new_size; -} - -/** \brief Increase the size of the Pattern rule ID array. - * - * \param pmq storage for match results - * \param new_size number of Signature IDs needing to be stored. - * - * \return 0 on failure. - */ -int -MpmAddPidResize(PatternMatcherQueue *pmq, uint32_t new_size) -{ - /* Need to make the array bigger. Double the size needed to - * also handle the case that sids_size might still be - * larger than the old size. - */ - new_size = new_size * 2; - uint32_t *new_array = (uint32_t*)SCRealloc(pmq->pattern_id_array, - new_size * sizeof(uint32_t)); - if (unlikely(new_array == NULL)) { - // Failed to allocate 2x, so try 1x. - new_size = new_size / 2; - new_array = (uint32_t*)SCRealloc(pmq->pattern_id_array, - new_size * sizeof(uint32_t)); - if (unlikely(new_array == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed to realloc PatternMatchQueue" - " pattern ID array. Some new Pattern ID matches were lost."); - return 0; - } - } - pmq->pattern_id_array = new_array; - pmq->pattern_id_array_size = new_size; - - return new_size; -} - -/** \brief Verify and store a match - * - * used at search runtime - * - * \param thread_ctx mpm thread ctx - * \param pmq storage for match results - * \param patid pattern ID being checked - * \param bitarray Array of bits for patterns IDs found in current search - * \param sids pointer to array of Signature IDs - * \param sids_size number of Signature IDs in sids array. - * - * \retval 0 no match after all - * \retval 1 (new) match - */ -int -MpmVerifyMatch(MpmThreadCtx *thread_ctx, PatternMatcherQueue *pmq, uint32_t patid, - uint8_t *bitarray, SigIntId *sids, uint32_t sids_size) -{ - SCEnter(); - - /* Handle pattern id storage */ - if (pmq != NULL && pmq->pattern_id_bitarray != NULL) { - SCLogDebug("using pattern id arrays, storing %"PRIu32, patid); - - if ((bitarray[(patid / 8)] & (1<<(patid % 8))) == 0) { - bitarray[(patid / 8)] |= (1<<(patid % 8)); - /* flag this pattern id as being added now */ - pmq->pattern_id_bitarray[(patid / 8)] |= (1<<(patid % 8)); - /* append the pattern_id to the array with matches */ - MpmAddPid(pmq, patid); - MpmAddSids(pmq, sids, sids_size); - } - } - - SCReturnInt(1); -} - -/** - * \brief Merge two pmq's bitarrays - * - * \param src source pmq - * \param dst destination pmq to merge into - */ -void PmqMerge(PatternMatcherQueue *src, PatternMatcherQueue *dst) -{ - uint32_t u; - - if (src->pattern_id_array_cnt == 0) - return; - - for (u = 0; u < src->pattern_id_bitarray_size && u < dst->pattern_id_bitarray_size; u++) { - dst->pattern_id_bitarray[u] |= src->pattern_id_bitarray[u]; - } - - /** \todo now set merged flag? */ - - if (src->rule_id_array && dst->rule_id_array) { - MpmAddSids(dst, src->rule_id_array, src->rule_id_array_cnt); - } -} - -/** \brief Reset a Pmq for reusage. Meant to be called after a single search. - * \param pmq Pattern matcher to be reset. - * \todo memset is expensive, but we need it as we merge pmq's. We might use - * a flag so we can clear pmq's the old way if we can. - */ -void PmqReset(PatternMatcherQueue *pmq) -{ - if (pmq == NULL) - return; - - memset(pmq->pattern_id_bitarray, 0, pmq->pattern_id_bitarray_size); - - pmq->pattern_id_array_cnt = 0; - - pmq->rule_id_array_cnt = 0; - /* TODO: Realloc the rule id array smaller at some size? */ -} - -/** \brief Cleanup a Pmq - * \param pmq Pattern matcher queue to be cleaned up. - */ -void PmqCleanup(PatternMatcherQueue *pmq) -{ - if (pmq == NULL) - return; - - if (pmq->pattern_id_array != NULL) { - SCFree(pmq->pattern_id_array); - pmq->pattern_id_array = NULL; - } - - if (pmq->pattern_id_bitarray != NULL) { - SCFree(pmq->pattern_id_bitarray); - pmq->pattern_id_bitarray = NULL; - } - - if (pmq->rule_id_array != NULL) { - SCFree(pmq->rule_id_array); - pmq->rule_id_array = NULL; - } - - pmq->pattern_id_array_cnt = 0; - pmq->pattern_id_array_size = 0; -} - -/** \brief Cleanup and free a Pmq - * \param pmq Pattern matcher queue to be free'd. - */ -void PmqFree(PatternMatcherQueue *pmq) -{ - if (pmq == NULL) - return; - - PmqCleanup(pmq); -} - -void MpmInitThreadCtx(MpmThreadCtx *mpm_thread_ctx, uint16_t matcher, uint32_t max_id) -{ - mpm_table[matcher].InitThreadCtx(NULL, mpm_thread_ctx, max_id); -} - -void MpmInitCtx (MpmCtx *mpm_ctx, uint16_t matcher) -{ - mpm_ctx->mpm_type = matcher; - mpm_table[matcher].InitCtx(mpm_ctx); -} - -void MpmTableSetup(void) -{ - memset(mpm_table, 0, sizeof(mpm_table)); - - MpmWuManberRegister(); - MpmB2gRegister(); - MpmB3gRegister(); - MpmACRegister(); - MpmACBSRegister(); - MpmACGfbsRegister(); - MpmACTileRegister(); -#ifdef __SC_CUDA_SUPPORT__ - MpmACCudaRegister(); -#endif /* __SC_CUDA_SUPPORT__ */ -} - -/** \brief Function to return the default hash size for the mpm algorithm, - * which has been defined by the user in the config file - * - * \param conf_val pointer to the string value of hash size - * \retval hash_value returns the hash value as defined by user, otherwise - * default low size value - */ -uint32_t MpmGetHashSize(const char *conf_val) -{ - SCEnter(); - uint32_t hash_value = HASHSIZE_LOW; - - if(strcmp(conf_val, "lowest") == 0) { - hash_value = HASHSIZE_LOWEST; - } else if(strcmp(conf_val, "low") == 0) { - hash_value = HASHSIZE_LOW; - } else if(strcmp(conf_val, "medium") == 0) { - hash_value = HASHSIZE_MEDIUM; - } else if(strcmp(conf_val, "high") == 0) { - hash_value = HASHSIZE_HIGH; - /* "highest" is supported in 1.0 to 1.0.2, so we keep supporting - * it for backwards compatibility */ - } else if(strcmp(conf_val, "highest") == 0) { - hash_value = HASHSIZE_HIGHER; - } else if(strcmp(conf_val, "higher") == 0) { - hash_value = HASHSIZE_HIGHER; - } else if(strcmp(conf_val, "max") == 0) { - hash_value = HASHSIZE_MAX; - } - - SCReturnInt(hash_value); -} - -/** \brief Function to return the default bloomfilter size for the mpm algorithm, - * which has been defined by the user in the config file - * - * \param conf_val pointer to the string value of bloom filter size - * \retval bloom_value returns the bloom filter value as defined by user, - * otherwise default medium size value - */ -uint32_t MpmGetBloomSize(const char *conf_val) -{ - SCEnter(); - uint32_t bloom_value = BLOOMSIZE_MEDIUM; - - if(strncmp(conf_val, "low", 3) == 0) { - bloom_value = BLOOMSIZE_LOW; - } else if(strncmp(conf_val, "medium", 6) == 0) { - bloom_value = BLOOMSIZE_MEDIUM; - } else if(strncmp(conf_val, "high", 4) == 0) { - bloom_value = BLOOMSIZE_HIGH; - } - - SCReturnInt(bloom_value); -} - -int MpmAddPatternCS(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, - uint32_t pid, SigIntId sid, uint8_t flags) -{ - return mpm_table[mpm_ctx->mpm_type].AddPattern(mpm_ctx, pat, patlen, - offset, depth, - pid, sid, flags); -} - -int MpmAddPatternCI(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, - uint32_t pid, SigIntId sid, uint8_t flags) -{ - return mpm_table[mpm_ctx->mpm_type].AddPatternNocase(mpm_ctx, pat, patlen, - offset, depth, - pid, sid, flags); -} - - - -/************************************Unittests*********************************/ - -#ifdef UNITTESTS -#endif /* UNITTESTS */ - -void MpmRegisterTests(void) -{ -#ifdef UNITTESTS - uint16_t i; - - for (i = 0; i < MPM_TABLE_SIZE; i++) { - if (i == MPM_NOTSET) - continue; - - g_ut_modules++; - - if (mpm_table[i].RegisterUnittests != NULL) { - g_ut_covered++; - mpm_table[i].RegisterUnittests(); - } else { - if (coverage_unittests) - SCLogWarning(SC_WARN_NO_UNITTESTS, "mpm module %s has no " - "unittest registration function.", mpm_table[i].name); - } - } - -#endif -} diff --git a/framework/src/suricata/src/util-mpm.h b/framework/src/suricata/src/util-mpm.h deleted file mode 100644 index da650884..00000000 --- a/framework/src/suricata/src/util-mpm.h +++ /dev/null @@ -1,324 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_MPM_H__ -#define __UTIL_MPM_H__ -#include "suricata-common.h" - -#define MPM_ENDMATCH_SINGLE 0x01 /**< A single match is sufficient. No - depth, offset, etc settings. */ -#define MPM_ENDMATCH_OFFSET 0x02 /**< has offset setting */ -#define MPM_ENDMATCH_DEPTH 0x04 /**< has depth setting */ -#define MPM_ENDMATCH_NOSEARCH 0x08 /**< if this matches, no search is - required (for this pattern) */ - -#define HASHSIZE_LOWEST 2048 /**< Lowest hash size for the multi - pattern matcher algorithms */ -#define HASHSIZE_LOW 4096 /**< Low hash size for the multi - pattern matcher algorithms */ -#define HASHSIZE_MEDIUM 8192 /**< Medium hash size for the multi - pattern matcher algorithms */ -#define HASHSIZE_HIGH 16384 /**< High hash size for the multi - pattern matcher algorithms */ -#define HASHSIZE_HIGHER 32768 /**< Higher hash size for the multi - pattern matcher algorithms */ -#define HASHSIZE_MAX 65536 /**< Max hash size for the multi - pattern matcher algorithms */ -#define BLOOMSIZE_LOW 512 /*<* Low bloomfilter size for the multi - pattern matcher algorithms */ -#define BLOOMSIZE_MEDIUM 1024 /**< Medium bloomfilter size for the multi - pattern matcher algorithms */ -#define BLOOMSIZE_HIGH 2048 /**< High bloomfilter size for the multi - pattern matcher algorithms */ - -enum { - MPM_NOTSET = 0, - - /* wumanber as the name suggests */ - MPM_WUMANBER, - /* bndmq 2 gram */ - MPM_B2G, - /* bndmq 3 gram */ - MPM_B3G, - MPM_B2GC, - MPM_B2GM, - - /* aho-corasick */ - MPM_AC, -#ifdef __SC_CUDA_SUPPORT__ - MPM_AC_CUDA, -#endif - /* aho-corasick-goto-failure state based */ - MPM_AC_GFBS, - MPM_AC_BS, - MPM_AC_TILE, - /* table size */ - MPM_TABLE_SIZE, -}; - -#ifdef __tile__ -#define DEFAULT_MPM MPM_AC_TILE -#else -#define DEFAULT_MPM MPM_AC -#endif - -/* Internal Pattern Index: 0 to pattern_cnt-1 */ -typedef uint32_t MpmPatternIndex; - -typedef struct MpmMatchBucket_ { - uint32_t len; -} MpmMatchBucket; - -typedef struct MpmThreadCtx_ { - void *ctx; - - uint32_t memory_cnt; - uint32_t memory_size; - -} MpmThreadCtx; - -/** \brief helper structure for the pattern matcher engine. The Pattern Matcher - * thread has this and passes a pointer to it to the pattern matcher. - * The actual pattern matcher will fill the structure. */ -typedef struct PatternMatcherQueue_ { - uint32_t *pattern_id_array; /** array with pattern id's that had a - pattern match. These will be inspected - futher by the detection engine. */ - uint32_t pattern_id_array_cnt; /**< Number currently stored */ - uint32_t pattern_id_array_size; /**< Allocated size in bytes */ - - uint8_t *pattern_id_bitarray; /** bitarray with pattern id matches */ - uint32_t pattern_id_bitarray_size; /**< size in bytes */ - - /* used for storing rule id's */ - /* Array of rule IDs found. */ - SigIntId *rule_id_array; - /* Number of rule IDs in the array. */ - uint32_t rule_id_array_cnt; - /* The number of slots allocated for storing rule IDs */ - uint32_t rule_id_array_size; - -} PatternMatcherQueue; - -typedef struct MpmCtx_ { - void *ctx; - uint16_t mpm_type; - - /* Indicates if this a global mpm_ctx. Global mpm_ctx is the one that - * is instantiated when we use "single". Non-global is "full", i.e. - * one per sgh. We are using a uint16_t here to avoiding using a pad. - * You can use a uint8_t here as well. */ - uint16_t global; - - /* unique patterns */ - uint32_t pattern_cnt; - - uint16_t minlen; - uint16_t maxlen; - - uint32_t memory_cnt; - uint32_t memory_size; -} MpmCtx; - -/* if we want to retrieve an unique mpm context from the mpm context factory - * we should supply this as the key */ -#define MPM_CTX_FACTORY_UNIQUE_CONTEXT -1 - -#define MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD 0x01 - -typedef struct MpmCtxFactoryItem_ { - char *name; - MpmCtx *mpm_ctx_ts; - MpmCtx *mpm_ctx_tc; - int32_t id; - uint8_t flags; -} MpmCtxFactoryItem; - -typedef struct MpmCtxFactoryContainer_ { - MpmCtxFactoryItem *items; - int32_t no_of_items; -} MpmCtxFactoryContainer; - -/** pattern is case insensitive */ -#define MPM_PATTERN_FLAG_NOCASE 0x01 -/** pattern is negated */ -#define MPM_PATTERN_FLAG_NEGATED 0x02 -/** pattern has a depth setting */ -#define MPM_PATTERN_FLAG_DEPTH 0x04 -/** pattern has an offset setting */ -#define MPM_PATTERN_FLAG_OFFSET 0x08 -/** one byte pattern (used in b2g) */ -#define MPM_PATTERN_ONE_BYTE 0x10 - -typedef struct MpmTableElmt_ { - char *name; - uint8_t max_pattern_length; - void (*InitCtx)(struct MpmCtx_ *); - void (*InitThreadCtx)(struct MpmCtx_ *, struct MpmThreadCtx_ *, uint32_t); - void (*DestroyCtx)(struct MpmCtx_ *); - void (*DestroyThreadCtx)(struct MpmCtx_ *, struct MpmThreadCtx_ *); - - /** function pointers for adding patterns to the mpm ctx. - * - * \param mpm_ctx Mpm context to add the pattern to - * \param pattern pointer to the pattern - * \param pattern_len length of the pattern in bytes - * \param offset pattern offset setting - * \param depth pattern depth setting - * \param pid pattern id - * \param sid signature _internal_ id - * \param flags pattern flags - */ - int (*AddPattern)(struct MpmCtx_ *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); - int (*AddPatternNocase)(struct MpmCtx_ *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t); - int (*Prepare)(struct MpmCtx_ *); - uint32_t (*Search)(struct MpmCtx_ *, struct MpmThreadCtx_ *, PatternMatcherQueue *, uint8_t *, uint16_t); - void (*Cleanup)(struct MpmThreadCtx_ *); - void (*PrintCtx)(struct MpmCtx_ *); - void (*PrintThreadCtx)(struct MpmThreadCtx_ *); - void (*RegisterUnittests)(void); - uint8_t flags; -} MpmTableElmt; - -MpmTableElmt mpm_table[MPM_TABLE_SIZE]; - -/* macros decides if cuda is enabled for the platform or not */ -#ifdef __SC_CUDA_SUPPORT__ - -/* the min size limit of a payload(or any other data) to be buffered */ -#define UTIL_MPM_CUDA_DATA_BUFFER_SIZE_MIN_LIMIT_DEFAULT 0 -/* the max size limit of a payload(or any other data) to be buffered */ -#define UTIL_MPM_CUDA_DATA_BUFFER_SIZE_MAX_LIMIT_DEFAULT 1500 -/* Default value for data buffer used by cuda mpm engine for CudaBuffer reg */ -#define UTIL_MPM_CUDA_CUDA_BUFFER_DBUFFER_SIZE_DEFAULT 500 * 1024 * 1024 -/* Default value for the max data chunk that would be sent to gpu */ -#define UTIL_MPM_CUDA_GPU_TRANSFER_SIZE 50 * 1024 * 1024 -/* Default value for offset/pointer buffer to be used by cuda mpm - * engine for CudaBuffer reg */ -#define UTIL_MPM_CUDA_CUDA_BUFFER_OPBUFFER_ITEMS_DEFAULT 500000 -#define UTIL_MPM_CUDA_BATCHING_TIMEOUT_DEFAULT 2000 -#define UTIL_MPM_CUDA_CUDA_STREAMS_DEFAULT 2 -#define UTIL_MPM_CUDA_DEVICE_ID_DEFAULT 0 - -/** - * \brief Cuda configuration for "mpm" profile. We can further extend this - * to have conf for specific mpms. For now its common for all mpms. - */ -typedef struct MpmCudaConf_ { - uint16_t data_buffer_size_min_limit; - uint16_t data_buffer_size_max_limit; - uint32_t cb_buffer_size; - uint32_t gpu_transfer_size; - int batching_timeout; - int device_id; - int cuda_streams; -} MpmCudaConf; - -void MpmCudaEnvironmentSetup(); - -#endif /* __SC_CUDA_SUPPORT__ */ - -struct DetectEngineCtx_; - -int32_t MpmFactoryRegisterMpmCtxProfile(struct DetectEngineCtx_ *, const char *, uint8_t); -void MpmFactoryReClaimMpmCtx(struct DetectEngineCtx_ *, MpmCtx *); -MpmCtx *MpmFactoryGetMpmCtxForProfile(struct DetectEngineCtx_ *, int32_t, int); -void MpmFactoryDeRegisterAllMpmCtxProfiles(struct DetectEngineCtx_ *); -int32_t MpmFactoryIsMpmCtxAvailable(struct DetectEngineCtx_ *, MpmCtx *); - -int PmqSetup(PatternMatcherQueue *, uint32_t); -void PmqMerge(PatternMatcherQueue *src, PatternMatcherQueue *dst); -void PmqReset(PatternMatcherQueue *); -void PmqCleanup(PatternMatcherQueue *); -void PmqFree(PatternMatcherQueue *); - -void MpmTableSetup(void); -void MpmRegisterTests(void); - -int MpmVerifyMatch(MpmThreadCtx *thread_ctx, PatternMatcherQueue *pmq, uint32_t patid, - uint8_t *bitarray, SigIntId *sids, uint32_t sids_size); -void MpmInitCtx(MpmCtx *mpm_ctx, uint16_t matcher); -void MpmInitThreadCtx(MpmThreadCtx *mpm_thread_ctx, uint16_t, uint32_t); -uint32_t MpmGetHashSize(const char *); -uint32_t MpmGetBloomSize(const char *); - -int MpmAddPatternCS(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, - uint32_t pid, SigIntId sid, uint8_t flags); -int MpmAddPatternCI(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, - uint32_t pid, SigIntId sid, uint8_t flags); - -/* Resize Signature ID array. Only called from MpmAddSids(). */ -int MpmAddSidsResize(PatternMatcherQueue *pmq, uint32_t new_size); - -/** \brief Add array of Signature IDs to rule ID array. - * - * Checks size of the array first. Calls MpmAddSidsResize to increase - * The size of the array, since that is the slow path. - * - * \param pmq storage for match results - * \param sids pointer to array of Signature IDs - * \param sids_size number of Signature IDs in sids array. - * - */ -static inline void -MpmAddSids(PatternMatcherQueue *pmq, SigIntId *sids, uint32_t sids_size) -{ - if (sids_size == 0) - return; - - uint32_t new_size = pmq->rule_id_array_cnt + sids_size; - if (new_size > pmq->rule_id_array_size) { - if (MpmAddSidsResize(pmq, new_size) == 0) { - // Failed to allocate larger memory for all the SIDS, but - // keep as many as we can. - sids_size = pmq->rule_id_array_size - pmq->rule_id_array_cnt; - } - } - SCLogDebug("Adding %u sids", sids_size); - // Add SIDs for this pattern to the end of the array - SigIntId *ptr = pmq->rule_id_array + pmq->rule_id_array_cnt; - SigIntId *end = ptr + sids_size; - do { - *ptr++ = *sids++; - } while (ptr != end); - pmq->rule_id_array_cnt += sids_size; -} - -/* Resize Pattern ID array. Only called from MpmAddPid(). */ -int MpmAddPidResize(PatternMatcherQueue *pmq, uint32_t new_size); - -static inline void -MpmAddPid(PatternMatcherQueue *pmq, uint32_t patid) -{ - uint32_t new_size = pmq->pattern_id_array_cnt + 1; - if (new_size > pmq->pattern_id_array_size) { - if (MpmAddPidResize(pmq, new_size) == 0) - return; - } - pmq->pattern_id_array[pmq->pattern_id_array_cnt] = patid; - pmq->pattern_id_array_cnt = new_size; - SCLogDebug("pattern_id_array_cnt %u", pmq->pattern_id_array_cnt); -} -#endif /* __UTIL_MPM_H__ */ diff --git a/framework/src/suricata/src/util-optimize.h b/framework/src/suricata/src/util-optimize.h deleted file mode 100644 index bde35ddd..00000000 --- a/framework/src/suricata/src/util-optimize.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __UTIL_OPTIMIZE_H__ -#define __UTIL_OPTIMIZE_H__ - -/** - * \file - * - * \author Victor Julien - */ - -#if CPPCHECK==1 -#define likely -#define unlikely -#else -#ifndef likely -#define likely(expr) __builtin_expect(!!(expr), 1) -#endif -#ifndef unlikely -#define unlikely(expr) __builtin_expect(!!(expr), 0) -#endif -#endif - -/** from http://en.wikipedia.org/wiki/Memory_ordering - * - * C Compiler memory barrier - */ -#define cc_barrier() __asm__ __volatile__("": : :"memory") - -/** from http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html - * - * Hardware memory barrier - */ -#define hw_barrier() __sync_synchronize() - -#endif /* __UTIL_OPTIMIZE_H__ */ - diff --git a/framework/src/suricata/src/util-path.c b/framework/src/suricata/src/util-path.c deleted file mode 100644 index d1b812f0..00000000 --- a/framework/src/suricata/src/util-path.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "debug.h" -#include "util-debug.h" - -/** - * \brief Check if a path is absolute - * - * \param path string with the path - * - * \retval 1 absolute - * \retval 0 not absolute - */ -int PathIsAbsolute(const char *path) -{ - if (strlen(path) > 1 && path[0] == '/') { - return 1; - } - -#if (defined OS_WIN32 || defined __CYGWIN__) - if (strlen(path) > 2) { - if (isalpha((unsigned char)path[0]) && path[1] == ':') { - return 1; - } - } -#endif - - return 0; -} - -/** - * \brief Check if a path is relative - * - * \param path string with the path - * - * \retval 1 relative - * \retval 0 not relative - */ -int PathIsRelative(const char *path) -{ - return PathIsAbsolute(path) ? 0 : 1; -} diff --git a/framework/src/suricata/src/util-path.h b/framework/src/suricata/src/util-path.h deleted file mode 100644 index 2243722a..00000000 --- a/framework/src/suricata/src/util-path.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - */ - -#ifndef __UTIL_PATH_H__ -#define __UTIL_PATH_H__ - -int PathIsAbsolute(const char *); -int PathIsRelative(const char *); - -#endif /* __UTIL_PATH_H__ */ diff --git a/framework/src/suricata/src/util-pidfile.c b/framework/src/suricata/src/util-pidfile.c deleted file mode 100644 index a13e54ef..00000000 --- a/framework/src/suricata/src/util-pidfile.c +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * \author Victor Julien - * - * Utility code for dealing with a pidfile. - * Adaptation of Steve Grubbs patch to our coding guidelines - * (thanks for the patch Steve ;) - */ - -#include "suricata-common.h" -#include "util-pidfile.h" - -/** - * \brief Write a pid file (used at the startup) - * This commonly needed by the init scripts - * - * \param pointer to the name of the pid file to write (optarg) - * - * \retval 0 if succes - * \retval -1 on failure - */ -int SCPidfileCreate(const char *pidfile) -{ - SCEnter(); - - int pidfd = 0; - char val[16]; - - size_t len = snprintf(val, sizeof(val), "%"PRIuMAX"\n", (uintmax_t)getpid()); - if (len <= 0) { - SCLogError(SC_ERR_PIDFILE_SNPRINTF, "Pid error (%s)", strerror(errno)); - SCReturnInt(-1); - } - - pidfd = open(pidfile, O_CREAT | O_TRUNC | O_NOFOLLOW | O_WRONLY, 0644); - if (pidfd < 0) { - SCLogError(SC_ERR_PIDFILE_OPEN, "unable to set pidfile '%s': %s", - pidfile, - strerror(errno)); - SCReturnInt(-1); - } - - ssize_t r = write(pidfd, val, (unsigned int)len); - if (r == -1) { - SCLogError(SC_ERR_PIDFILE_WRITE, "unable to write pidfile: %s", strerror(errno)); - close(pidfd); - SCReturnInt(-1); - } else if ((size_t)r != len) { - SCLogError(SC_ERR_PIDFILE_WRITE, "unable to write pidfile: wrote" - " %"PRIdMAX" of %"PRIuMAX" bytes.", (intmax_t)r, (uintmax_t)len); - close(pidfd); - SCReturnInt(-1); - } - - close(pidfd); - SCReturnInt(0); -} - -/** - * \brief Remove the pid file (used at the startup) - * - * \param pointer to the name of the pid file to write (optarg) - */ -void SCPidfileRemove(const char *pid_filename) -{ - if (pid_filename != NULL) { - /* we ignore the result, the user may have removed the file already. */ - (void)unlink(pid_filename); - } -} - -/** - * \brief Check a pid file (used at the startup) - * This commonly needed by the init scripts - * - * \param pointer to the name of the pid file to write (optarg) - * - * \retval 0 if succes - * \retval -1 on failure - */ -int SCPidfileTestRunning(const char *pid_filename) -{ - if (access(pid_filename, F_OK) == 0) { - /* Check if the existing process is still alive. */ - pid_t pidv; - FILE *pf; - - pf = fopen(pid_filename, "r"); - if (pf == NULL) { - SCLogError(SC_ERR_INITIALIZATION, - "pid file '%s' exists and can not be read. Aborting!", - pid_filename); - return -1; - } - - if (fscanf(pf, "%d", &pidv) == 1 && kill(pidv, 0) == 0) { - fclose(pf); - SCLogError(SC_ERR_INITIALIZATION, - "pid file '%s' exists. Is Suricata already running? Aborting!", - pid_filename); - return -1; - } - - if (pf != NULL) - fclose(pf); - } - return 0; -} diff --git a/framework/src/suricata/src/util-pidfile.h b/framework/src/suricata/src/util-pidfile.h deleted file mode 100644 index ef071f4e..00000000 --- a/framework/src/suricata/src/util-pidfile.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * \author Victor Julien - */ - -#ifndef __UTIL_PID_H__ -#define __UTIL_PID_H__ - -int SCPidfileCreate(const char *); -void SCPidfileRemove(const char *); -int SCPidfileTestRunning(const char *pid_filename); - -#endif /* __UTIL_PID_H__ */ - diff --git a/framework/src/suricata/src/util-pool-thread.c b/framework/src/suricata/src/util-pool-thread.c deleted file mode 100644 index fe83a788..00000000 --- a/framework/src/suricata/src/util-pool-thread.c +++ /dev/null @@ -1,458 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \defgroup utilpool Pool - * - * @{ - */ - -/** - * \file - * - * \author Victor Julien - * - * Pool utility functions - */ - -#include "suricata-common.h" -#include "util-pool.h" -#include "util-pool-thread.h" -#include "util-unittest.h" -#include "util-debug.h" - -PoolThread *PoolThreadInit(int threads, uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(), int (*Init)(void *, void *), void *InitData, void (*Cleanup)(void *), void (*Free)(void *)) -{ - PoolThread *pt = NULL; - int i; - - if (threads <= 0) { - SCLogDebug("error"); - goto error; - } - - pt = SCMalloc(sizeof(*pt)); - if (unlikely(pt == NULL)) { - SCLogDebug("memory alloc error"); - goto error; - } - - SCLogDebug("size %d", threads); - pt->array = SCMalloc(threads * sizeof(PoolThreadElement)); - if (pt->array == NULL) { - SCLogDebug("memory alloc error"); - goto error; - } - pt->size = threads; - - for (i = 0; i < threads; i++) { - PoolThreadElement *e = &pt->array[i]; - - SCMutexInit(&e->lock, NULL); - SCMutexLock(&e->lock); -// SCLogDebug("size %u prealloc_size %u elt_size %u Alloc %p Init %p InitData %p Cleanup %p Free %p", -// size, prealloc_size, elt_size, -// Alloc, Init, InitData, Cleanup, Free); - e->pool = PoolInit(size, prealloc_size, elt_size, Alloc, Init, InitData, Cleanup, Free); - SCMutexUnlock(&e->lock); - if (e->pool == NULL) { - SCLogDebug("error"); - goto error; - } - } - - return pt; -error: - if (pt != NULL) - PoolThreadFree(pt); - return NULL; -} - -/** - * - */ -int PoolThreadGrow(PoolThread *pt, uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(), int (*Init)(void *, void *), void *InitData, void (*Cleanup)(void *), void (*Free)(void *)) { - void *ptmp; - size_t newsize; - PoolThreadElement *e = NULL; - - if (pt == NULL || pt->array == NULL) { - SCLogError(SC_ERR_POOL_INIT, "pool grow failed"); - return -1; - } - - newsize = pt->size + 1; - SCLogDebug("newsize %"PRIuMAX, (uintmax_t)newsize); - - ptmp = SCRealloc(pt->array, (newsize * sizeof(PoolThreadElement))); - if (ptmp == NULL) { - SCFree(pt->array); - pt->array = NULL; - SCLogError(SC_ERR_POOL_INIT, "pool grow failed"); - return -1; - } - pt->array = ptmp; - - pt->size = newsize; - - e = &pt->array[newsize - 1]; - memset(e, 0x00, sizeof(*e)); - SCMutexInit(&e->lock, NULL); - SCMutexLock(&e->lock); - e->pool = PoolInit(size, prealloc_size, elt_size, Alloc, Init, InitData, Cleanup, Free); - SCMutexUnlock(&e->lock); - if (e->pool == NULL) { - SCLogError(SC_ERR_POOL_INIT, "pool grow failed"); - return -1; - } - - return (int)(newsize - 1); -} - -int PoolThreadSize(PoolThread *pt) -{ - if (pt == NULL) - return -1; - return (int)pt->size; -} - -void PoolThreadFree(PoolThread *pt) -{ - int i; - - if (pt == NULL) - return; - - if (pt->array != NULL) { - for (i = 0; i < (int)pt->size; i++) { - PoolThreadElement *e = &pt->array[i]; - SCMutexLock(&e->lock); - PoolFree(e->pool); - SCMutexUnlock(&e->lock); - SCMutexDestroy(&e->lock); - } - SCFree(pt->array); - } - SCFree(pt); -} - -void *PoolThreadGetById(PoolThread *pt, uint16_t id) -{ - void *data = NULL; - - if (pt == NULL || id >= pt->size) - return NULL; - - PoolThreadElement *e = &pt->array[id]; - SCMutexLock(&e->lock); - data = PoolGet(e->pool); - SCMutexUnlock(&e->lock); - if (data) { - PoolThreadReserved *did = data; - *did = id; - } - - return data; -} - -void PoolThreadReturn(PoolThread *pt, void *data) -{ - PoolThreadReserved *id = data; - - if (pt == NULL || *id >= pt->size) - return; - - SCLogDebug("returning to id %u", *id); - - PoolThreadElement *e = &pt->array[*id]; - SCMutexLock(&e->lock); - PoolReturn(e->pool, data); - SCMutexUnlock(&e->lock); -} - -#ifdef UNITTESTS -struct PoolThreadTestData { - PoolThreadReserved res; - int abc; -}; - -static void *PoolThreadTestAlloc(void) -{ - void *data = SCMalloc(sizeof(struct PoolThreadTestData)); - return data; -} - -static -int PoolThreadTestInit(void *data, void *allocdata) -{ - if (!data) - return 0; - - memset(data,0x00,sizeof(allocdata)); - struct PoolThreadTestData *pdata = data; - pdata->abc = *(int *)allocdata; - return 1; -} - -static -void PoolThreadTestFree(void *data) -{ -} - -static int PoolThreadTestInit01(void) -{ - PoolThread *pt = PoolThreadInit(4, /* threads */ - 10, 5, 10, PoolThreadTestAlloc, NULL, NULL, NULL, NULL); - if (pt == NULL) - return 0; - - PoolThreadFree(pt); - return 1; -} - -static int PoolThreadTestInit02(void) -{ - int i = 123; - - PoolThread *pt = PoolThreadInit(4, /* threads */ - 10, 5, 10, PoolThreadTestAlloc, PoolThreadTestInit, &i, PoolThreadTestFree, NULL); - if (pt == NULL) - return 0; - - PoolThreadFree(pt); - return 1; -} - -static int PoolThreadTestGet01(void) -{ - int result = 0; - PoolThread *pt = PoolThreadInit(4, /* threads */ - 10, 5, 10, PoolThreadTestAlloc, NULL, NULL, NULL, NULL); - if (pt == NULL) - return 0; - - void *data = PoolThreadGetById(pt, 3); - if (data == NULL) { - printf("data == NULL: "); - goto end; - } - - struct PoolThreadTestData *pdata = data; - if (pdata->res != 3) { - printf("res != 3, but %d: ", pdata->res); - goto end; - } - - result = 1; -end: - PoolThreadFree(pt); - return result; -} - -static int PoolThreadTestGet02(void) -{ - int i = 123; - int result = 0; - - PoolThread *pt = PoolThreadInit(4, /* threads */ - 10, 5, 10, PoolThreadTestAlloc, PoolThreadTestInit, &i, PoolThreadTestFree, NULL); - if (pt == NULL) - return 0; - - void *data = PoolThreadGetById(pt, 3); - if (data == NULL) { - printf("data == NULL: "); - goto end; - } - - struct PoolThreadTestData *pdata = data; - if (pdata->res != 3) { - printf("res != 3, but %d: ", pdata->res); - goto end; - } - - if (pdata->abc != 123) { - printf("abc != 123, but %d: ", pdata->abc); - goto end; - } - - result = 1; -end: - PoolThreadFree(pt); - return result; -} - -static int PoolThreadTestReturn01(void) -{ - int i = 123; - int result = 0; - - PoolThread *pt = PoolThreadInit(4, /* threads */ - 10, 5, 10, PoolThreadTestAlloc, PoolThreadTestInit, &i, PoolThreadTestFree, NULL); - if (pt == NULL) - return 0; - - void *data = PoolThreadGetById(pt, 3); - if (data == NULL) { - printf("data == NULL: "); - goto end; - } - - struct PoolThreadTestData *pdata = data; - if (pdata->res != 3) { - printf("res != 3, but %d: ", pdata->res); - goto end; - } - - if (pdata->abc != 123) { - printf("abc != 123, but %d: ", pdata->abc); - goto end; - } - - if (pt->array[3].pool->outstanding != 1) { - printf("pool outstanding count wrong %u: ", - pt->array[3].pool->outstanding); - goto end; - } - - PoolThreadReturn(pt, data); - - if (pt->array[3].pool->outstanding != 0) { - printf("pool outstanding count wrong %u: ", - pt->array[3].pool->outstanding); - goto end; - } - - - result = 1; -end: - PoolThreadFree(pt); - return result; -} - -static int PoolThreadTestGrow01(void) -{ - PoolThread *pt = PoolThreadInit(4, /* threads */ - 10, 5, 10, PoolThreadTestAlloc, NULL, NULL, NULL, NULL); - if (pt == NULL) - return 0; - - if (PoolThreadGrow(pt, - 10, 5, 10, PoolThreadTestAlloc, NULL, NULL, NULL, NULL) < 0) { - PoolThreadFree(pt); - return 0; - } - - PoolThreadFree(pt); - return 1; -} - -static int PoolThreadTestGrow02(void) -{ - int i = 123; - - PoolThread *pt = PoolThreadInit(4, /* threads */ - 10, 5, 10, PoolThreadTestAlloc, PoolThreadTestInit, &i, PoolThreadTestFree, NULL); - if (pt == NULL) - return 0; - - if (PoolThreadGrow(pt, - 10, 5, 10, PoolThreadTestAlloc, PoolThreadTestInit, &i, PoolThreadTestFree, NULL) < 0) { - PoolThreadFree(pt); - return 0; - } - - PoolThreadFree(pt); - return 1; -} - -static int PoolThreadTestGrow03(void) -{ - int i = 123; - int result = 0; - - PoolThread *pt = PoolThreadInit(4, /* threads */ - 10, 5, 10, PoolThreadTestAlloc, PoolThreadTestInit, &i, PoolThreadTestFree, NULL); - if (pt == NULL) - return 0; - - if (PoolThreadGrow(pt, - 10, 5, 10, PoolThreadTestAlloc, PoolThreadTestInit, &i, PoolThreadTestFree, NULL) < 0) { - PoolThreadFree(pt); - return 0; - } - - void *data = PoolThreadGetById(pt, 4); - if (data == NULL) { - printf("data == NULL: "); - goto end; - } - - struct PoolThreadTestData *pdata = data; - if (pdata->res != 4) { - printf("res != 5, but %d: ", pdata->res); - goto end; - } - - if (pdata->abc != 123) { - printf("abc != 123, but %d: ", pdata->abc); - goto end; - } - - if (pt->array[4].pool->outstanding != 1) { - printf("pool outstanding count wrong %u: ", - pt->array[4].pool->outstanding); - goto end; - } - - PoolThreadReturn(pt, data); - - if (pt->array[4].pool->outstanding != 0) { - printf("pool outstanding count wrong %u: ", - pt->array[4].pool->outstanding); - goto end; - } - - - result = 1; -end: - PoolThreadFree(pt); - return result; -} - -#endif - -void PoolThreadRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("PoolThreadTestInit01", PoolThreadTestInit01, 1); - UtRegisterTest("PoolThreadTestInit02", PoolThreadTestInit02, 1); - - UtRegisterTest("PoolThreadTestGet01", PoolThreadTestGet01, 1); - UtRegisterTest("PoolThreadTestGet02", PoolThreadTestGet02, 1); - - UtRegisterTest("PoolThreadTestReturn01", PoolThreadTestReturn01, 1); - - UtRegisterTest("PoolThreadTestGrow01", PoolThreadTestGrow01, 1); - UtRegisterTest("PoolThreadTestGrow02", PoolThreadTestGrow02, 1); - UtRegisterTest("PoolThreadTestGrow03", PoolThreadTestGrow03, 1); -#endif -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/util-pool-thread.h b/framework/src/suricata/src/util-pool-thread.h deleted file mode 100644 index 1d2bbd47..00000000 --- a/framework/src/suricata/src/util-pool-thread.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup utilpool - * - * @{ - */ - -/** - * \file - * - * \author Victor Julien - */ - -/** - * Consumers of this API MUST add PoolThreadReserved as the first - * member in the data structure. They also MUST ignore that data - * completely. It's managed by this API. - * - * It's purpose is to make sure thread X can return data to a pool - * from thread Y. - */ - -#ifndef __UTIL_POOL_THREAD_H__ -#define __UTIL_POOL_THREAD_H__ - -struct PoolThreadElement_ { - SCMutex lock; /**< lock, should have low contention */ - Pool *pool; /**< actual pool */ -}; -// __attribute__((aligned(CLS))); <- VJ: breaks on clang 32bit, segv in PoolThreadTestGrow01 - -typedef struct PoolThreadElement_ PoolThreadElement; - -typedef struct PoolThread_ { - size_t size; /**< size of the array */ - PoolThreadElement *array; /**< array of elements */ -} PoolThread; - -/** per data item reserved data containing the - * thread pool id */ -typedef uint16_t PoolThreadReserved; - -void PoolThreadRegisterTests(void); - -/** \brief initialize a thread pool - * \note same as PoolInit() except for "threads" - * \param threads number of threads to use this - * \retval pt thread pool or NULL on error */ -PoolThread *PoolThreadInit(int threads, uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(), int (*Init)(void *, void *), void *InitData, void (*Cleanup)(void *), void (*Free)(void *)); - -/** \brief grow a thread pool by one - * \note calls PoolInit so all args but 'pt' are the same - * \param pt thread pool to grow - * \retval r id of new entry on succes, -1 on error */ -int PoolThreadGrow(PoolThread *pt, uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(), int (*Init)(void *, void *), void *InitData, void (*Cleanup)(void *), void (*Free)(void *)); - -/** \brief destroy the thread pool - * \note wrapper around PoolFree() - * \param pt thread pool */ -void PoolThreadFree(PoolThread *pt); - -/** \brief get data from thread pool by thread id - * \note wrapper around PoolGet() - * \param pt thread pool - * \param id thread id - * \retval ptr data or NULL */ -void *PoolThreadGetById(PoolThread *pt, uint16_t id); - -/** \brief return data to thread pool - * \note wrapper around PoolReturn() - * \param pt thread pool - * \param data memory block to return, with PoolThreadReserved as it's first member */ -void PoolThreadReturn(PoolThread *pt, void *data); - -/** \brief get size of PoolThread (number of 'threads', so array elements) - * \param pt thread pool - * \retval size or -1 on error */ -int PoolThreadSize(PoolThread *pt); - -#endif /* __UTIL_POOL_THREAD_H__ */ - -/** - * @} - */ diff --git a/framework/src/suricata/src/util-pool.c b/framework/src/suricata/src/util-pool.c deleted file mode 100644 index 6f405252..00000000 --- a/framework/src/suricata/src/util-pool.c +++ /dev/null @@ -1,737 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \defgroup utilpool Pool - * - * ::Pool are an effective way to maintain a set of ready to use - * structures. - * - * To create a ::Pool, you need to use PoolInit(). You can - * get an item from the ::Pool by using PoolGet(). When you're - * done with it call PoolReturn(). - * To destroy the ::Pool, call PoolFree(), it will free all used - * memory. - * - * @{ - */ - -/** - * \file - * - * \author Victor Julien - * - * Pool utility functions - */ - -#include "suricata-common.h" -#include "util-pool.h" -#include "util-pool-thread.h" -#include "util-unittest.h" -#include "util-debug.h" - -static int PoolMemset(void *pitem, void *initdata) -{ - Pool *p = (Pool *) initdata; - - memset(pitem, 0, p->elt_size); - return 1; -} - -/** - * \brief Check if data is preallocated - * \retval 0 or -1 if not inside */ -static int PoolDataPreAllocated(Pool *p, void *data) -{ - int delta = data - p->data_buffer; - if ((delta < 0) || (delta > p->data_buffer_size)) { - return 0; - } - return 1; -} - -/** \brief Init a Pool - * - * PoolInit() creates a ::Pool. The Alloc function must only do - * allocation stuff. The Cleanup function must not try to free - * the PoolBucket::data. This is done by the ::Pool management - * system. - * - * \param size - * \param prealloc_size - * \param elt_size Memory size of an element - * \param Alloc An allocation function or NULL to use a standard SCMalloc - * \param Init An init function or NULL to use a standard memset to 0 - * \param InitData Init data - * \param Cleanup a free function or NULL if no special treatment is needed - * \param Free free func - * \retval the allocated Pool - */ -Pool *PoolInit(uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(), int (*Init)(void *, void *), void *InitData, void (*Cleanup)(void *), void (*Free)(void *)) -{ - Pool *p = NULL; - - if (size != 0 && prealloc_size > size) { - SCLogError(SC_ERR_POOL_INIT, "size error"); - goto error; - } - if (size != 0 && elt_size == 0) { - SCLogError(SC_ERR_POOL_INIT, "size != 0 && elt_size == 0"); - goto error; - } - if (elt_size && Free) { - SCLogError(SC_ERR_POOL_INIT, "elt_size && Free"); - goto error; - } - - /* setup the filter */ - p = SCMalloc(sizeof(Pool)); - if (unlikely(p == NULL)) { - SCLogError(SC_ERR_POOL_INIT, "alloc error"); - goto error; - } - - memset(p,0,sizeof(Pool)); - - p->max_buckets = size; - p->preallocated = prealloc_size; - p->elt_size = elt_size; - p->data_buffer_size = prealloc_size * elt_size; - p->Alloc = Alloc; - p->Init = Init; - p->InitData = InitData; - p->Cleanup = Cleanup; - p->Free = Free; - if (p->Init == NULL) { - p->Init = PoolMemset; - p->InitData = p; - } - - /* alloc the buckets and place them in the empty list */ - uint32_t u32 = 0; - if (size > 0) { - PoolBucket *pb = SCCalloc(size, sizeof(PoolBucket)); - if (unlikely(pb == NULL)) { - SCLogError(SC_ERR_POOL_INIT, "alloc error"); - goto error; - } - p->pb_buffer = pb; - memset(pb, 0, size * sizeof(PoolBucket)); - for (u32 = 0; u32 < size; u32++) { - /* populate pool */ - pb->next = p->empty_stack; - pb->flags |= POOL_BUCKET_PREALLOCATED; - p->empty_stack = pb; - p->empty_stack_size++; - pb++; - } - } - - if (size > 0) { - p->data_buffer = SCCalloc(prealloc_size, elt_size); - /* FIXME better goto */ - if (p->data_buffer == NULL) { - SCLogError(SC_ERR_POOL_INIT, "alloc error"); - goto error; - } - } - /* prealloc the buckets and requeue them to the alloc list */ - for (u32 = 0; u32 < prealloc_size; u32++) { - if (size == 0) { /* unlimited */ - PoolBucket *pb = SCMalloc(sizeof(PoolBucket)); - if (unlikely(pb == NULL)) { - SCLogError(SC_ERR_POOL_INIT, "alloc error"); - goto error; - } - - memset(pb, 0, sizeof(PoolBucket)); - - if (p->Alloc) { - pb->data = p->Alloc(); - } else { - pb->data = SCMalloc(p->elt_size); - } - if (pb->data == NULL) { - SCLogError(SC_ERR_POOL_INIT, "alloc error"); - SCFree(pb); - goto error; - } - if (p->Init(pb->data, p->InitData) != 1) { - SCLogError(SC_ERR_POOL_INIT, "init error"); - if (p->Cleanup) - p->Cleanup(pb->data); - if (p->Free) - p->Free(pb->data); - else - SCFree(pb->data); - SCFree(pb); - goto error; - } - p->allocated++; - - pb->next = p->alloc_stack; - p->alloc_stack = pb; - p->alloc_stack_size++; - } else { - PoolBucket *pb = p->empty_stack; - if (pb == NULL) { - SCLogError(SC_ERR_POOL_INIT, "alloc error"); - goto error; - } - - pb->data = (char *)p->data_buffer + u32 * elt_size; - if (p->Init(pb->data, p->InitData) != 1) { - SCLogError(SC_ERR_POOL_INIT, "init error"); - if (p->Cleanup) - p->Cleanup(pb->data); - goto error; - } - - p->empty_stack = pb->next; - p->empty_stack_size--; - - p->allocated++; - - pb->next = p->alloc_stack; - p->alloc_stack = pb; - p->alloc_stack_size++; - } - } - - return p; - -error: - if (p != NULL) { - PoolFree(p); - } - return NULL; -} - - -void PoolFree(Pool *p) -{ - if (p == NULL) - return; - - while (p->alloc_stack != NULL) { - PoolBucket *pb = p->alloc_stack; - p->alloc_stack = pb->next; - if (p->Cleanup) - p->Cleanup(pb->data); - if (PoolDataPreAllocated(p, pb->data) == 0) { - if (p->Free) - p->Free(pb->data); - else - SCFree(pb->data); - } - pb->data = NULL; - if (! pb->flags & POOL_BUCKET_PREALLOCATED) { - SCFree(pb); - } - } - - while (p->empty_stack != NULL) { - PoolBucket *pb = p->empty_stack; - p->empty_stack = pb->next; - if (pb->data!= NULL) { - if (p->Cleanup) - p->Cleanup(pb->data); - if (PoolDataPreAllocated(p, pb->data) == 0) { - if (p->Free) - p->Free(pb->data); - else - SCFree(pb->data); - } - pb->data = NULL; - } - if (! pb->flags & POOL_BUCKET_PREALLOCATED) { - SCFree(pb); - } - } - - if (p->pb_buffer) - SCFree(p->pb_buffer); - if (p->data_buffer) - SCFree(p->data_buffer); - SCFree(p); -} - -void PoolPrint(Pool *p) -{ - printf("\n----------- Hash Table Stats ------------\n"); - printf("Buckets: %" PRIu32 "\n", p->empty_stack_size + p->alloc_stack_size); - printf("-----------------------------------------\n"); -} - -void *PoolGet(Pool *p) -{ - SCEnter(); - - PoolBucket *pb = p->alloc_stack; - if (pb != NULL) { - /* pull from the alloc list */ - p->alloc_stack = pb->next; - p->alloc_stack_size--; - - /* put in the empty list */ - pb->next = p->empty_stack; - p->empty_stack = pb; - p->empty_stack_size++; - } else { - if (p->max_buckets == 0 || p->allocated < p->max_buckets) { - void *pitem; - SCLogDebug("max_buckets %"PRIu32"", p->max_buckets); - - if (p->Alloc != NULL) { - pitem = p->Alloc(); - } else { - pitem = SCMalloc(p->elt_size); - } - - if (pitem != NULL) { - if (p->Init(pitem, p->InitData) != 1) { - if (p->Cleanup) - p->Cleanup(pitem); - if (p->Free != NULL) - p->Free(pitem); - else - SCFree(pitem); - SCReturnPtr(NULL, "void"); - } - - p->allocated++; - - p->outstanding++; - if (p->outstanding > p->max_outstanding) - p->max_outstanding = p->outstanding; - } - - SCReturnPtr(pitem, "void"); - } else { - SCReturnPtr(NULL, "void"); - } - } - - void *ptr = pb->data; - pb->data = NULL; - p->outstanding++; - if (p->outstanding > p->max_outstanding) - p->max_outstanding = p->outstanding; - SCReturnPtr(ptr,"void"); -} - -void PoolReturn(Pool *p, void *data) -{ - SCEnter(); - - PoolBucket *pb = p->empty_stack; - - SCLogDebug("pb %p", pb); - - if (pb == NULL) { - p->allocated--; - p->outstanding--; - if (p->Cleanup != NULL) { - p->Cleanup(data); - } - if (PoolDataPreAllocated(p, data) == 0) { - if (p->Free) - p->Free(data); - else - SCFree(data); - } - - SCLogDebug("tried to return data %p to the pool %p, but no more " - "buckets available. Just freeing the data.", data, p); - SCReturn; - } - - /* pull from the alloc list */ - p->empty_stack = pb->next; - p->empty_stack_size--; - - /* put in the alloc list */ - pb->next = p->alloc_stack; - p->alloc_stack = pb; - p->alloc_stack_size++; - - pb->data = data; - p->outstanding--; - SCReturn; -} - -void PoolPrintSaturation(Pool *p) -{ - SCLogDebug("pool %p is using %"PRIu32" out of %"PRIu32" items (%02.1f%%), max %"PRIu32" (%02.1f%%): pool struct memory %"PRIu64".", p, p->outstanding, p->max_buckets, (float)(p->outstanding/(float)(p->max_buckets))*100, p->max_outstanding, (float)(p->max_outstanding/(float)(p->max_buckets))*100, (uint64_t)(p->max_buckets * sizeof(PoolBucket))); -} - -/* - * ONLY TESTS BELOW THIS COMMENT - */ - -void *PoolTestAlloc() -{ - void *ptr = SCMalloc(10); - if (unlikely(ptr == NULL)) - return NULL; - return ptr; -} -int PoolTestInitArg(void *data, void *allocdata) -{ - size_t len = strlen((char *)allocdata) + 1; - char *str = data; - if (str != NULL) - strlcpy(str,(char *)allocdata,len); - return 1; -} - -void PoolTestFree(void *ptr) -{ - return; -} - -#ifdef UNITTESTS -static int PoolTestInit01 (void) -{ - Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL); - if (p == NULL) - return 0; - - PoolFree(p); - return 1; -} - -static int PoolTestInit02 (void) -{ - int retval = 0; - - Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL); - if (p == NULL) - goto end; - - if (p->alloc_stack == NULL || p->empty_stack == NULL) { - printf("list(s) not properly initialized (a:%p e:%p): ", - p->alloc_stack, p->empty_stack); - retval = 0; - goto end; - } - - if (p->Alloc != PoolTestAlloc) { - printf("Alloc func ptr %p != %p: ", - p->Alloc, PoolTestAlloc); - retval = 0; - goto end; - } - - if (p->Cleanup != PoolTestFree) { - printf("Free func ptr %p != %p: ", - p->Cleanup, PoolTestFree); - retval = 0; - goto end; - } - - retval = 1; -end: - if (p != NULL) - PoolFree(p); - return retval; -} - -static int PoolTestInit03 (void) -{ - int retval = 0; - void *data = NULL; - - Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL); - if (p == NULL) - goto end; - - data = PoolGet(p); - if (data == NULL) { - printf("PoolGet returned NULL: "); - retval = 0; - goto end; - } - - if (p->alloc_stack_size != 4) { - printf("p->alloc_stack_size 4 != %" PRIu32 ": ", p->alloc_stack_size); - retval = 0; - goto end; - } - - if (p->empty_stack_size != 6) { - printf("p->empty_stack_size 6 != %" PRIu32 ": ", p->empty_stack_size); - retval = 0; - goto end; - } - - retval = 1; -end: - if (p != NULL) - PoolFree(p); - return retval; -} - -static int PoolTestInit04 (void) -{ - int retval = 0; - char *str = NULL; - - Pool *p = PoolInit(10,5,strlen("test") + 1,NULL, PoolTestInitArg,(void *)"test",PoolTestFree, NULL); - if (p == NULL) - goto end; - - str = PoolGet(p); - if (str == NULL) { - printf("PoolGet returned NULL: "); - retval = 0; - goto end; - } - - if (strcmp(str, "test") != 0) { - printf("Memory not properly initialized: "); - retval = 0; - goto end; - } - - if (p->alloc_stack_size != 4) { - printf("p->alloc_stack_size 4 != %" PRIu32 ": ", p->alloc_stack_size); - retval = 0; - goto end; - } - - if (p->empty_stack_size != 6) { - printf("p->empty_stack_size 6 != %" PRIu32 ": ", p->empty_stack_size); - retval = 0; - goto end; - } - - retval = 1; -end: - if (p != NULL) - PoolFree(p); - return retval; -} - -static int PoolTestInit05 (void) -{ - int retval = 0; - void *data = NULL; - - Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL, NULL,PoolTestFree, NULL); - if (p == NULL) - goto end; - - data = PoolGet(p); - if (data == NULL) { - printf("PoolGet returned NULL: "); - retval = 0; - goto end; - } - - if (p->alloc_stack_size != 4) { - printf("p->alloc_stack_size 4 != %" PRIu32 ": ", p->alloc_stack_size); - retval = 0; - goto end; - } - - if (p->empty_stack_size != 6) { - printf("p->empty_stack_size 6 != %" PRIu32 ": ", p->empty_stack_size); - retval = 0; - goto end; - } - - PoolReturn(p, data); - data = NULL; - - if (p->alloc_stack_size != 5) { - printf("p->alloc_stack_size 5 != %" PRIu32 ": ", p->alloc_stack_size); - retval = 0; - goto end; - } - - if (p->empty_stack_size != 5) { - printf("p->empty_stack_size 5 != %" PRIu32 ": ", p->empty_stack_size); - retval = 0; - goto end; - } - - retval = 1; -end: - if (p != NULL) - PoolFree(p); - return retval; -} - -static int PoolTestInit06 (void) -{ - int retval = 0; - void *data = NULL; - void *data2 = NULL; - - Pool *p = PoolInit(1,0,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL); - if (p == NULL) - goto end; - - if (p->allocated != 0) { - printf("p->allocated 0 != %" PRIu32 ": ", p->allocated); - retval = 0; - goto end; - } - - data = PoolGet(p); - if (data == NULL) { - printf("PoolGet returned NULL: "); - retval = 0; - goto end; - } - - if (p->allocated != 1) { - printf("p->allocated 1 != %" PRIu32 ": ", p->allocated); - retval = 0; - goto end; - } - - data2 = PoolGet(p); - if (data2 != NULL) { - printf("PoolGet returned %p, expected NULL: ", data2); - retval = 0; - goto end; - } - - PoolReturn(p,data); - data = NULL; - - if (p->allocated != 1) { - printf("p->allocated 1 != %" PRIu32 ": ", p->allocated); - retval = 0; - goto end; - } - - if (p->alloc_stack_size != 1) { - printf("p->alloc_stack_size 1 != %" PRIu32 ": ", p->alloc_stack_size); - retval = 0; - goto end; - } - - retval = 1; -end: - if (p != NULL) - PoolFree(p); - return retval; -} - -/** \test pool with unlimited size */ -static int PoolTestInit07 (void) -{ - int retval = 0; - void *data = NULL; - void *data2 = NULL; - - Pool *p = PoolInit(0,1,10,PoolTestAlloc,NULL,NULL,PoolTestFree, NULL); - if (p == NULL) - goto end; - - if (p->max_buckets != 0) { - printf("p->max_buckets 0 != %" PRIu32 ": ", p->max_buckets); - retval = 0; - goto end; - } - - if (p->allocated != 1) { - printf("p->allocated 1 != %" PRIu32 ": ", p->allocated); - retval = 0; - goto end; - } - - data = PoolGet(p); - if (data == NULL) { - printf("PoolGet returned NULL: "); - retval = 0; - goto end; - } - - if (p->allocated != 1) { - printf("(2) p->allocated 1 != %" PRIu32 ": ", p->allocated); - retval = 0; - goto end; - } - - data2 = PoolGet(p); - if (data2 == NULL) { - printf("PoolGet returned NULL: "); - retval = 0; - goto end; - } - - if (p->allocated != 2) { - printf("(3) p->allocated 2 != %" PRIu32 ": ", p->allocated); - retval = 0; - goto end; - } - - PoolReturn(p,data); - data = NULL; - - if (p->allocated != 2) { - printf("(4) p->allocated 2 != %" PRIu32 ": ", p->allocated); - retval = 0; - goto end; - } - - if (p->alloc_stack_size != 1) { - printf("p->alloc_stack_size 1 != %" PRIu32 ": ", p->alloc_stack_size); - retval = 0; - goto end; - } - - PoolReturn(p,data2); - data2 = NULL; - - if (p->allocated != 1) { - printf("(5) p->allocated 1 != %" PRIu32 ": ", p->allocated); - retval = 0; - goto end; - } - - retval = 1; -end: - if (p != NULL) - PoolFree(p); - return retval; -} -#endif /* UNITTESTS */ - -void PoolRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("PoolTestInit01", PoolTestInit01, 1); - UtRegisterTest("PoolTestInit02", PoolTestInit02, 1); - UtRegisterTest("PoolTestInit03", PoolTestInit03, 1); - UtRegisterTest("PoolTestInit04", PoolTestInit04, 1); - UtRegisterTest("PoolTestInit05", PoolTestInit05, 1); - UtRegisterTest("PoolTestInit06", PoolTestInit06, 1); - UtRegisterTest("PoolTestInit07", PoolTestInit07, 1); - - PoolThreadRegisterTests(); -#endif /* UNITTESTS */ -} - - -/** - * @} - */ diff --git a/framework/src/suricata/src/util-pool.h b/framework/src/suricata/src/util-pool.h deleted file mode 100644 index 266d1f4d..00000000 --- a/framework/src/suricata/src/util-pool.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup utilpool - * - * @{ - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_POOL_H__ -#define __UTIL_POOL_H__ - -#define POOL_BUCKET_PREALLOCATED (1 << 0) - -/* pool bucket structure */ -typedef struct PoolBucket_ { - void *data; - uint8_t flags; - struct PoolBucket_ *next; -} PoolBucket; - -/* pool structure */ -typedef struct Pool_ { - uint32_t max_buckets; - uint32_t preallocated; - uint32_t allocated; /**< counter of data elements, both currently in - * the pool and outside of it (outstanding) */ - - uint32_t alloc_stack_size; - - PoolBucket *alloc_stack; - - PoolBucket *empty_stack; - uint32_t empty_stack_size; - - int data_buffer_size; - void *data_buffer; - PoolBucket *pb_buffer; - - void *(*Alloc)(); - int (*Init)(void *, void *); - void *InitData; - void (*Cleanup)(void *); - void (*Free)(void *); - - uint32_t elt_size; - uint32_t outstanding; /**< counter of data items 'in use'. Pretty much - * the diff between PoolGet and PoolReturn */ - uint32_t max_outstanding; /**< max value of outstanding we saw */ -} Pool; - -/* prototypes */ -Pool* PoolInit(uint32_t, uint32_t, uint32_t, void *(*Alloc)(), int (*Init)(void *, void *), void *, void (*Cleanup)(void *), void (*Free)(void *)); -void PoolFree(Pool *); -void PoolPrint(Pool *); -void PoolPrintSaturation(Pool *p); - -void *PoolGet(Pool *); -void PoolReturn(Pool *, void *); - -void PoolRegisterTests(void); - -#endif /* __UTIL_POOL_H__ */ - -/** - * @} - */ diff --git a/framework/src/suricata/src/util-print.c b/framework/src/suricata/src/util-print.c deleted file mode 100644 index 3e34756c..00000000 --- a/framework/src/suricata/src/util-print.c +++ /dev/null @@ -1,272 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Print utility functions - */ - -#include "suricata-common.h" -#include "util-print.h" -#include "util-error.h" -#include "util-debug.h" - -/** - * \brief print a buffer as hex on a single line - * - * Prints in the format "00 AA BB" - * - * \param nbuf buffer into which the output is written - * \param offset of where to start writting into the buffer - * \param max_size the size of the output buffer - * \param buf buffer to print from - * \param buflen length of the input buffer - */ -void PrintBufferRawLineHex(char *nbuf, int *offset, int max_size, uint8_t *buf, uint32_t buflen) -{ - uint32_t u = 0; - - for (u = 0; u < buflen; u++) { - PrintBufferData(nbuf, offset, max_size, "%02X ", buf[u]); - } -} - -/** - * \brief print a buffer as hex on a single line in to retbuf buffer - * - * Prints in the format "00 AA BB" - * - * \param retbuf pointer to the buffer which will have the result - * \param rebuflen lenght of the buffer - * \param buf buffer to print from - * \param buflen length of the input buffer - */ -void PrintRawLineHexBuf(char *retbuf, uint32_t retbuflen, uint8_t *buf, uint32_t buflen) -{ - uint32_t offset = 0; - uint32_t u = 0; - - for (u = 0; u < buflen; u++) { - PrintBufferData(retbuf, &offset, retbuflen, "%02X ", buf[u]); - } -} - -void PrintRawJsonFp(FILE *fp, uint8_t *buf, uint32_t buflen) -{ -#define BUFFER_LENGTH 2048 - char nbuf[BUFFER_LENGTH] = ""; - uint32_t offset = 0; - uint32_t u = 0; - - for (u = 0; u < buflen; u++) { - if (buf[u] == '\\' || buf[u] == '/' || buf[u] == '\"') { - PrintBufferData(nbuf, &offset, BUFFER_LENGTH, - "\\%c", buf[u]); - } else if (isprint(buf[u])) { - PrintBufferData(nbuf, &offset, BUFFER_LENGTH, - "%c", buf[u]); - } else { - PrintBufferData(nbuf, &offset, BUFFER_LENGTH, - "\\\\x%02X", buf[u]); - } - } - fprintf(fp, "%s", nbuf); -} - -void PrintRawUriFp(FILE *fp, uint8_t *buf, uint32_t buflen) -{ -#define BUFFER_LENGTH 2048 - char nbuf[BUFFER_LENGTH] = ""; - uint32_t offset = 0; - uint32_t u = 0; - - for (u = 0; u < buflen; u++) { - if (isprint(buf[u]) && buf[u] != '\"') { - PrintBufferData(nbuf, &offset, BUFFER_LENGTH, - "%c", buf[u]); - } else { - PrintBufferData(nbuf, &offset, BUFFER_LENGTH, - "\\x%02X", buf[u]); - } - } - - fprintf(fp, "%s", nbuf); -} - -void PrintRawUriBuf(char *retbuf, uint32_t *offset, uint32_t retbuflen, - uint8_t *buf, uint32_t buflen) -{ - uint32_t u = 0; - - for (u = 0; u < buflen; u++) { - if (isprint(buf[u]) && buf[u] != '\"') { - if (buf[u] == '\\') { - PrintBufferData(retbuf, offset, retbuflen, - "\\\\"); - } else { - PrintBufferData(retbuf, offset, retbuflen, - "%c", buf[u]); - } - } else { - PrintBufferData(retbuf, offset, retbuflen, - "\\x%02X", buf[u]); - } - } - - return; -} - -void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen) -{ - int ch = 0; - uint32_t u = 0; - - for (u = 0; u < buflen; u+=16) { - fprintf(fp ," %04X ", u); - for (ch = 0; (u+ch) < buflen && ch < 16; ch++) { - fprintf(fp, "%02X ", (uint8_t)buf[u+ch]); - - if (ch == 7) fprintf(fp, " "); - } - if (ch == 16) fprintf(fp, " "); - else if (ch < 8) { - int spaces = (16 - ch) * 3 + 2 + 1; - int s = 0; - for ( ; s < spaces; s++) fprintf(fp, " "); - } else if(ch < 16) { - int spaces = (16 - ch) * 3 + 2; - int s = 0; - for ( ; s < spaces; s++) fprintf(fp, " "); - } - - for (ch = 0; (u+ch) < buflen && ch < 16; ch++) { - fprintf(fp, "%c", isprint((uint8_t)buf[u+ch]) ? (uint8_t)buf[u+ch] : '.'); - - if (ch == 7) fprintf(fp, " "); - if (ch == 15) fprintf(fp, "\n"); - } - } - if (ch != 16) - fprintf(fp, "\n"); -} - -void PrintRawDataToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size, - uint8_t *src_buf, uint32_t src_buf_len) -{ - int ch = 0; - uint32_t u = 0; - - for (u = 0; u < src_buf_len; u+=16) { - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, - " %04X ", u); - for (ch = 0; (u + ch) < src_buf_len && ch < 16; ch++) { - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, - "%02X ", (uint8_t)src_buf[u + ch]); - - if (ch == 7) { - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, - " "); - } - } - if (ch == 16) { - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " "); - } else if (ch < 8) { - int spaces = (16 - ch) * 3 + 2 + 1; - int s = 0; - for ( ; s < spaces; s++) - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " "); - } else if(ch < 16) { - int spaces = (16 - ch) * 3 + 2; - int s = 0; - for ( ; s < spaces; s++) - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " "); - } - - for (ch = 0; (u+ch) < src_buf_len && ch < 16; ch++) { - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, - "%c", - isprint((uint8_t)src_buf[u + ch]) ? (uint8_t)src_buf[u + ch] : '.'); - - if (ch == 7) - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, " "); - if (ch == 15) - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n"); - } - } - if (ch != 16) - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, "\n"); - - return; -} - -void PrintStringsToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size, - uint8_t *src_buf, uint32_t src_buf_len) -{ - uint32_t ch = 0; - for (ch = 0; ch < src_buf_len; ch++) { - PrintBufferData((char *)dst_buf, dst_buf_offset_ptr, dst_buf_size, - "%c", - (isprint((uint8_t)src_buf[ch]) || - src_buf[ch] == '\n' || - src_buf[ch] == '\r') ? (uint8_t)src_buf[ch] : '.'); - } - - return; -} - -#ifndef s6_addr16 -# define s6_addr16 __u6_addr.__u6_addr16 -#endif - -static const char *PrintInetIPv6(const void *src, char *dst, socklen_t size) -{ - struct in6_addr * insrc = (struct in6_addr *) src; - int i; - char s_part[6]; - - /* current IPv6 format is fixed size */ - if (size < 8 * 5) { - SCLogWarning(SC_ERR_ARG_LEN_LONG, "Too small buffer to write IPv6 address"); - return NULL; - } - memset(dst, 0, size); - for(i = 0; i < 8; i++) { - snprintf(s_part, 6, "%04x:", htons(insrc->s6_addr16[i])); - strlcat(dst, s_part, size); - } - /* suppress last ':' */ - dst[strlen(dst) - 1] = 0; - - return dst; -} - -const char *PrintInet(int af, const void *src, char *dst, socklen_t size) -{ - switch (af) { - case AF_INET: - return inet_ntop(af, src, dst, size); - case AF_INET6: - /* Format IPv6 without deleting zeroes */ - return PrintInetIPv6(src, dst, size); - default: - SCLogError(SC_ERR_INVALID_VALUE, "Unsupported protocol: %d", af); - } - return NULL; -} diff --git a/framework/src/suricata/src/util-print.h b/framework/src/suricata/src/util-print.h deleted file mode 100644 index a696a98a..00000000 --- a/framework/src/suricata/src/util-print.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - - - -#ifndef __UTIL_PRINT_H__ -#define __UTIL_PRINT_H__ - -#define PrintBufferData(buf, buf_offset_ptr, buf_size, ...) do { \ - int cw = snprintf((buf) + *(buf_offset_ptr), \ - (buf_size) - *(buf_offset_ptr), \ - __VA_ARGS__); \ - if (cw >= 0) { \ - if ( (*(buf_offset_ptr) + cw) >= buf_size) { \ - SCLogDebug("Truncating data write since it exceeded buffer " \ - "limit of - %"PRIu32"\n", buf_size); \ - *(buf_offset_ptr) = buf_size - 1; \ - } else { \ - *(buf_offset_ptr) += cw; \ - } \ - } \ - } while (0) - -void PrintBufferRawLineHex(char *, int *,int, uint8_t *, uint32_t); -void PrintRawUriFp(FILE *, uint8_t *, uint32_t); -void PrintRawUriBuf(char *, uint32_t *, uint32_t, - uint8_t *, uint32_t); -void PrintRawJsonFp(FILE *, uint8_t *, uint32_t); -void PrintRawDataFp(FILE *, const uint8_t *, uint32_t); -void PrintRawDataToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size, - uint8_t *src_buf, uint32_t src_buf_len); -void PrintStringsToBuffer(uint8_t *dst_buf, uint32_t *dst_buf_offset_ptr, uint32_t dst_buf_size, - uint8_t *src_buf, uint32_t src_buf_len); -void PrintRawLineHexBuf(char *, uint32_t, uint8_t *, uint32_t ); -const char *PrintInet(int , const void *, char *, socklen_t); - -#endif /* __UTIL_PRINT_H__ */ - diff --git a/framework/src/suricata/src/util-privs.c b/framework/src/suricata/src/util-privs.c deleted file mode 100644 index 635247c3..00000000 --- a/framework/src/suricata/src/util-privs.c +++ /dev/null @@ -1,246 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - * File to drop the engine capabilities using libcap-ng by - * Steve Grubb - */ - -#ifndef OS_WIN32 - -#include -#include -#include "util-debug.h" -#include "suricata-common.h" -#include "suricata.h" - -#ifdef HAVE_LIBCAP_NG - -#include -#ifdef HAVE_SYS_PRCTL_H -#include -#endif -#include "threadvars.h" -#include "util-cpu.h" -#include "util-privs.h" -#include "runmodes.h" - -/** flag indicating if we'll be using caps */ -extern int sc_set_caps; - -/** our current runmode */ -extern int run_mode; - -/** - * \brief Drop all the previliges of the given thread - */ -void SCDropAllCaps() -{ - capng_clear(CAPNG_SELECT_BOTH); - if (capng_apply(CAPNG_SELECT_BOTH) < 0) { - SCLogError(SC_ERR_CHANGING_CAPS_FAILED, "failed in dropping the caps"); - exit(EXIT_FAILURE); - } -} - -/** - * \brief Drop the previliges of the main thread - */ -void SCDropMainThreadCaps(uint32_t userid, uint32_t groupid) -{ - if (sc_set_caps == FALSE) - return; - - capng_clear(CAPNG_SELECT_BOTH); - - switch (run_mode) { - case RUNMODE_PCAP_DEV: - case RUNMODE_AFP_DEV: - capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, - CAP_NET_RAW, /* needed for pcap live mode */ - -1); - break; - case RUNMODE_PFRING: - capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, - CAP_NET_ADMIN, CAP_NET_RAW, - -1); - break; - case RUNMODE_NFQ: - capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, - CAP_NET_ADMIN, /* needed for nfqueue inline mode */ - -1); - break; - } - - if (capng_change_id(userid, groupid, CAPNG_DROP_SUPP_GRP | - CAPNG_CLEAR_BOUNDING) < 0) - { - SCLogError(SC_ERR_CHANGING_CAPS_FAILED, "capng_change_id for main thread" - " failed"); - exit(EXIT_FAILURE); - } - - SCLogInfo("dropped the caps for main thread"); -} - -void SCDropCaps(ThreadVars *tv) -{ -#if 0 - capng_clear(CAPNG_SELECT_BOTH); - capng_apply(CAPNG_SELECT_BOTH); - if (tv->cap_flags & SC_CAP_IPC_LOCK) { - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_IPC_LOCK); - capng_apply(CAPNG_SELECT_CAPS); - SCLogDebug("For thread \"%s\" CAP_IPC_LOCK has been set", tv->name); - } - if (tv->cap_flags & SC_CAP_NET_ADMIN) { - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_ADMIN); - capng_apply(CAPNG_SELECT_CAPS); - SCLogDebug("For thread \"%s\" CAP_NET_ADMIN has been set", tv->name); - } - if (tv->cap_flags & SC_CAP_NET_BIND_SERVICE) { - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BIND_SERVICE); - capng_apply(CAPNG_SELECT_CAPS); - SCLogDebug("For thread \"%s\" CAP_NET_BIND_SERVICE has been set", tv->name); - } - if (tv->cap_flags & SC_CAP_NET_BROADCAST) { - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BROADCAST); - capng_apply(CAPNG_SELECT_CAPS); - SCLogDebug("For thread \"%s\" CAP_NET_BROADCAST has been set", tv->name); - } - if (tv->cap_flags & SC_CAP_NET_RAW) { - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_RAW); - capng_apply(CAPNG_SELECT_CAPS); - SCLogDebug("For thread \"%s\" CAP_NET_RAW has been set", tv->name); - } - if (tv->cap_flags & SC_CAP_SYS_ADMIN) { - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_ADMIN); - capng_apply(CAPNG_SELECT_CAPS); - SCLogDebug("For thread \"%s\" CAP_SYS_ADMIN has been set", tv->name); - } - if (tv->cap_flags & SC_CAP_SYS_RAW_IO) { - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_RAWIO); - capng_apply(CAPNG_SELECT_CAPS); - SCLogDebug("For thread \"%s\" CAP_SYS_RAWIO has been set", tv->name); - } -#endif -} - -#endif /* HAVE_LIBCAP_NG */ - -/** - * \brief Function to get the user and group ID from the specified user name - * - * \param user_name pointer to the given user name - * \param uid pointer to the user id in which result will be stored - * \param gid pointer to the group id in which result will be stored - * - * \retval upon success it return 0 - */ -int SCGetUserID(char *user_name, char *group_name, uint32_t *uid, uint32_t *gid) -{ - uint32_t userid = 0; - uint32_t groupid = 0; - struct passwd *pw; - - /* Get the user ID */ - if (isdigit((unsigned char)user_name[0]) != 0) { - userid = atoi(user_name); - pw = getpwuid(userid); - if (pw == NULL) { - SCLogError(SC_ERR_UID_FAILED, "unable to get the user ID, " - "check if user exist!!"); - exit(EXIT_FAILURE); - } - } else { - pw = getpwnam(user_name); - if (pw == NULL) { - SCLogError(SC_ERR_UID_FAILED, "unable to get the user ID, " - "check if user exist!!"); - exit(EXIT_FAILURE); - } - userid = pw->pw_uid; - } - - /* Get the group ID */ - if (group_name != NULL) { - struct group *gp; - - if (isdigit((unsigned char)group_name[0]) != 0) { - groupid = atoi(group_name); - } else { - gp = getgrnam(group_name); - if (gp == NULL) { - SCLogError(SC_ERR_GID_FAILED, "unable to get the group" - " ID, check if group exist!!"); - exit(EXIT_FAILURE); - } - groupid = gp->gr_gid; - } - } else { - groupid = pw->pw_gid; - } - - /* close the group database */ - endgrent(); - /* close the user database */ - endpwent(); - - *uid = userid; - *gid = groupid; - - return 0; -} - -/** - * \brief Function to get the group ID from the specified group name - * - * \param group_name pointer to the given group name - * \param gid pointer to the group id in which result will be stored - * - * \retval upon success it return 0 - */ -int SCGetGroupID(char *group_name, uint32_t *gid) -{ - uint32_t grpid = 0; - struct group *gp; - - /* Get the group ID */ - if (isdigit((unsigned char)group_name[0]) != 0) { - grpid = atoi(group_name); - } else { - gp = getgrnam(group_name); - if (gp == NULL) { - SCLogError(SC_ERR_GID_FAILED, "unable to get the group ID," - " check if group exist!!"); - exit(EXIT_FAILURE); - } - grpid = gp->gr_gid; - } - - /* close the group database */ - endgrent(); - - *gid = grpid; - - return 0; -} -#endif /* OS_WIN32 */ diff --git a/framework/src/suricata/src/util-privs.h b/framework/src/suricata/src/util-privs.h deleted file mode 100644 index aef33a48..00000000 --- a/framework/src/suricata/src/util-privs.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - */ - -#ifndef _UTIL_PRIVS_H -#define _UTIL_PRIVS_H - -#define SC_CAP_NONE 0x01 -#define SC_CAP_SYS_ADMIN 0x02 -#define SC_CAP_SYS_RAW_IO 0x04 -#define SC_CAP_IPC_LOCK 0x08 -#define SC_CAP_NET_ADMIN 0x10 -#define SC_CAP_NET_RAW 0x20 -#define SC_CAP_NET_BIND_SERVICE 0x40 -#define SC_CAP_NET_BROADCAST 0x80 - -#ifndef HAVE_LIBCAP_NG -#define SCDropCaps(...) -#define SCDropMainThreadCaps(...) -#else -#include "threadvars.h" -#include "util-debug.h" -#include - -/**Drop the previliges of the given thread tv, based on the thread cap_flags - * which implies the capability requirement of the given thread. Initially all - * caps are dropped and later, the required caps are set for the given thread - */ -void SCDropCaps(ThreadVars *tv); -/* -#define SCDropCaps(tv) ({ \ - capng_clear(CAPNG_SELECT_BOTH); \ - capng_apply(CAPNG_SELECT_BOTH); \ - if (tv->cap_flags & SC_CAP_IPC_LOCK) { \ - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_IPC_LOCK); \ - capng_apply(CAPNG_SELECT_CAPS); \ - SCLogDebug("For thread \"%s\" CAP_IPC_LOCK has been set", tv->name); \ - } \ - if (tv->cap_flags & SC_CAP_NET_ADMIN) { \ - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_ADMIN); \ - capng_apply(CAPNG_SELECT_CAPS); \ - SCLogDebug("For thread \"%s\" CAP_NET_ADMIN has been set", tv->name); \ - } \ - if (tv->cap_flags & SC_CAP_NET_BIND_SERVICE) { \ - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BIND_SERVICE); \ - capng_apply(CAPNG_SELECT_CAPS); \ - SCLogDebug("For thread \"%s\" CAP_NET_BIND_SERVICE has been set", tv->name); \ - } \ - if (tv->cap_flags & SC_CAP_NET_BROADCAST) { \ - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_BROADCAST); \ - capng_apply(CAPNG_SELECT_CAPS); \ - SCLogDebug("For thread \"%s\" CAP_NET_BROADCAST has been set", tv->name); \ - } \ - if (tv->cap_flags & SC_CAP_NET_RAW) { \ - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_NET_RAW); \ - capng_apply(CAPNG_SELECT_CAPS); \ - SCLogDebug("For thread \"%s\" CAP_NET_RAW has been set", tv->name); \ - } \ - if (tv->cap_flags & SC_CAP_SYS_ADMIN) { \ - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_ADMIN); \ - capng_apply(CAPNG_SELECT_CAPS); \ - SCLogDebug("For thread \"%s\" CAP_SYS_ADMIN has been set", tv->name); \ - } \ - if (tv->cap_flags & SC_CAP_SYS_RAW_IO) { \ - capng_update(CAPNG_ADD, (capng_type_t) (CAPNG_EFFECTIVE | CAPNG_PERMITTED), CAP_SYS_RAWIO); \ - capng_apply(CAPNG_SELECT_CAPS); \ - SCLogDebug("For thread \"%s\" CAP_SYS_RAWIO has been set", tv->name); \ - } \ -}) -*/ -void SCDropMainThreadCaps(uint32_t , uint32_t ); - -#endif /* HAVE_LIBCAP_NG */ - -int SCGetUserID(char *, char *, uint32_t *, uint32_t *); -int SCGetGroupID(char *, uint32_t *); - -#endif /* _UTIL_PRIVS_H */ - diff --git a/framework/src/suricata/src/util-profiling-keywords.c b/framework/src/suricata/src/util-profiling-keywords.c deleted file mode 100644 index 9f3019aa..00000000 --- a/framework/src/suricata/src/util-profiling-keywords.c +++ /dev/null @@ -1,390 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited. - * \author Victor Julien - * - * An API for rule profiling operations. - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "detect-engine.h" -#include "conf.h" - -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-byte.h" -#include "util-profiling.h" -#include "util-profiling-locks.h" - -#ifdef PROFILING - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -/** - * Extra data for rule profiling. - */ -typedef struct SCProfileKeywordData_ { - uint64_t checks; - uint64_t matches; - uint64_t max; - uint64_t ticks_match; - uint64_t ticks_no_match; -} SCProfileKeywordData; - -typedef struct SCProfileKeywordDetectCtx_ { - uint32_t id; - SCProfileKeywordData *data; - pthread_mutex_t data_m; -} SCProfileKeywordDetectCtx; - -static int profiling_keywords_output_to_file = 0; -int profiling_keyword_enabled = 0; -__thread int profiling_keyword_entered = 0; -static char *profiling_file_name = ""; -static const char *profiling_file_mode = "a"; - -void SCProfilingKeywordsGlobalInit(void) -{ - ConfNode *conf; - - conf = ConfGetNode("profiling.keywords"); - if (conf != NULL) { - if (ConfNodeChildValueIsTrue(conf, "enabled")) { - profiling_keyword_enabled = 1; - const char *filename = ConfNodeLookupChildValue(conf, "filename"); - if (filename != NULL) { - - char *log_dir; - log_dir = ConfigGetLogDirectory(); - - profiling_file_name = SCMalloc(PATH_MAX); - if (unlikely(profiling_file_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name"); - exit(EXIT_FAILURE); - } - snprintf(profiling_file_name, PATH_MAX, "%s/%s", log_dir, filename); - - const char *v = ConfNodeLookupChildValue(conf, "append"); - if (v == NULL || ConfValIsTrue(v)) { - profiling_file_mode = "a"; - } else { - profiling_file_mode = "w"; - } - - profiling_keywords_output_to_file = 1; - } - } - } -} - -void DoDump(SCProfileKeywordDetectCtx *rules_ctx, FILE *fp, const char *name) -{ - int i; - fprintf(fp, " ----------------------------------------------" - "------------------------------------------------------" - "----------------------------\n"); - fprintf(fp, " Stats for: %s\n", name); - fprintf(fp, " ----------------------------------------------" - "------------------------------------------------------" - "----------------------------\n"); - fprintf(fp, " %-16s %-15s %-15s %-15s %-15s %-15s %-15s %-15s\n", "Keyword", "Ticks", "Checks", "Matches", "Max Ticks", "Avg", "Avg Match", "Avg No Match"); - fprintf(fp, " ---------------- " - "--------------- " - "--------------- " - "--------------- " - "--------------- " - "--------------- " - "--------------- " - "--------------- " - "\n"); - for (i = 0; i < DETECT_TBLSIZE; i++) { - SCProfileKeywordData *d = &rules_ctx->data[i]; - if (d == NULL || d->checks == 0) - continue; - - uint64_t ticks = d->ticks_match + d->ticks_no_match; - double avgticks = 0; - double avgticks_match = 0; - double avgticks_no_match = 0; - if (ticks && d->checks) { - avgticks = (ticks / d->checks); - - if (d->ticks_match && d->matches) - avgticks_match = (d->ticks_match / d->matches); - if (d->ticks_no_match && (d->checks - d->matches) != 0) - avgticks_no_match = (d->ticks_no_match / (d->checks - d->matches)); - } - - fprintf(fp, - " %-16s %-15"PRIu64" %-15"PRIu64" %-15"PRIu64" %-15"PRIu64" %-15.2f %-15.2f %-15.2f\n", - sigmatch_table[i].name, - ticks, - d->checks, - d->matches, - d->max, - avgticks, - avgticks_match, - avgticks_no_match); - } -} - -void -SCProfilingKeywordDump(DetectEngineCtx *de_ctx) -{ - int i; - FILE *fp; - struct timeval tval; - struct tm *tms; - struct tm local_tm; - - if (profiling_keyword_enabled == 0) - return; - - gettimeofday(&tval, NULL); - tms = SCLocalTime(tval.tv_sec, &local_tm); - - if (profiling_keywords_output_to_file == 1) { - SCLogDebug("file %s mode %s", profiling_file_name, profiling_file_mode); - - fp = fopen(profiling_file_name, profiling_file_mode); - - if (fp == NULL) { - SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", profiling_file_name, - strerror(errno)); - return; - } - } else { - fp = stdout; - } - - fprintf(fp, " ----------------------------------------------" - "------------------------------------------------------" - "----------------------------\n"); - fprintf(fp, " Date: %" PRId32 "/%" PRId32 "/%04d -- " - "%02d:%02d:%02d\n", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, - tms->tm_hour,tms->tm_min, tms->tm_sec); - - /* global stats first */ - DoDump(de_ctx->profile_keyword_ctx, fp, "total"); - /* per buffer stats next, but only if there are stats to print */ - for (i = 0; i < DETECT_SM_LIST_MAX; i++) { - int j; - uint64_t checks = 0; - for (j = 0; j < DETECT_TBLSIZE; j++) { - checks += de_ctx->profile_keyword_ctx_per_list[i]->data[j].checks; - } - - if (checks) - DoDump(de_ctx->profile_keyword_ctx_per_list[i], fp, - DetectSigmatchListEnumToString(i)); - } - - fprintf(fp,"\n"); - if (fp != stdout) - fclose(fp); - - SCLogInfo("Done dumping keyword profiling data."); -} - -/** - * \brief Update a rule counter. - * - * \param id The ID of this counter. - * \param ticks Number of CPU ticks for this rule. - * \param match Did the rule match? - */ -void -SCProfilingKeywordUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, int match) -{ - if (det_ctx != NULL && det_ctx->keyword_perf_data != NULL && id < DETECT_TBLSIZE) { - SCProfileKeywordData *p = &det_ctx->keyword_perf_data[id]; - - p->checks++; - p->matches += match; - if (ticks > p->max) - p->max = ticks; - if (match == 1) - p->ticks_match += ticks; - else - p->ticks_no_match += ticks; - - /* store per list (buffer type) as well */ - if (det_ctx->keyword_perf_list >= 0 && det_ctx->keyword_perf_list < DETECT_SM_LIST_MAX) { - p = &det_ctx->keyword_perf_data_per_list[det_ctx->keyword_perf_list][id]; - p->checks++; - p->matches += match; - if (ticks > p->max) - p->max = ticks; - if (match == 1) - p->ticks_match += ticks; - else - p->ticks_no_match += ticks; - } - } -} - -SCProfileKeywordDetectCtx *SCProfilingKeywordInitCtx(void) -{ - SCProfileKeywordDetectCtx *ctx = SCMalloc(sizeof(SCProfileKeywordDetectCtx)); - if (ctx != NULL) { - memset(ctx, 0x00, sizeof(SCProfileKeywordDetectCtx)); - - if (pthread_mutex_init(&ctx->data_m, NULL) != 0) { - SCLogError(SC_ERR_MUTEX, - "Failed to initialize hash table mutex."); - exit(EXIT_FAILURE); - } - } - - return ctx; -} - -static void DetroyCtx(SCProfileKeywordDetectCtx *ctx) -{ - if (ctx) { - if (ctx->data != NULL) - SCFree(ctx->data); - pthread_mutex_destroy(&ctx->data_m); - SCFree(ctx); - } -} - -void SCProfilingKeywordDestroyCtx(DetectEngineCtx *de_ctx) -{ - if (de_ctx != NULL) { - SCProfilingKeywordDump(de_ctx); - - DetroyCtx(de_ctx->profile_keyword_ctx); - int i; - for (i = 0; i < DETECT_SM_LIST_MAX; i++) { - DetroyCtx(de_ctx->profile_keyword_ctx_per_list[i]); - } - } -} - -void SCProfilingKeywordThreadSetup(SCProfileKeywordDetectCtx *ctx, DetectEngineThreadCtx *det_ctx) -{ - if (ctx == NULL) - return; - - SCProfileKeywordData *a = SCMalloc(sizeof(SCProfileKeywordData) * DETECT_TBLSIZE); - if (a != NULL) { - memset(a, 0x00, sizeof(SCProfileKeywordData) * DETECT_TBLSIZE); - det_ctx->keyword_perf_data = a; - } - - int i; - for (i = 0; i < DETECT_SM_LIST_MAX; i++) { - SCProfileKeywordData *b = SCMalloc(sizeof(SCProfileKeywordData) * DETECT_TBLSIZE); - if (b != NULL) { - memset(b, 0x00, sizeof(SCProfileKeywordData) * DETECT_TBLSIZE); - det_ctx->keyword_perf_data_per_list[i] = b; - } - - } -} - -static void SCProfilingKeywordThreadMerge(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx) -{ - if (de_ctx == NULL || de_ctx->profile_keyword_ctx == NULL || - de_ctx->profile_keyword_ctx->data == NULL || det_ctx == NULL || - det_ctx->keyword_perf_data == NULL) - return; - - int i; - for (i = 0; i < DETECT_TBLSIZE; i++) { - de_ctx->profile_keyword_ctx->data[i].checks += det_ctx->keyword_perf_data[i].checks; - de_ctx->profile_keyword_ctx->data[i].matches += det_ctx->keyword_perf_data[i].matches; - de_ctx->profile_keyword_ctx->data[i].ticks_match += det_ctx->keyword_perf_data[i].ticks_match; - de_ctx->profile_keyword_ctx->data[i].ticks_no_match += det_ctx->keyword_perf_data[i].ticks_no_match; - if (det_ctx->keyword_perf_data[i].max > de_ctx->profile_keyword_ctx->data[i].max) - de_ctx->profile_keyword_ctx->data[i].max = det_ctx->keyword_perf_data[i].max; - } - - int j; - for (j = 0; j < DETECT_SM_LIST_MAX; j++) { - for (i = 0; i < DETECT_TBLSIZE; i++) { - de_ctx->profile_keyword_ctx_per_list[j]->data[i].checks += det_ctx->keyword_perf_data_per_list[j][i].checks; - de_ctx->profile_keyword_ctx_per_list[j]->data[i].matches += det_ctx->keyword_perf_data_per_list[j][i].matches; - de_ctx->profile_keyword_ctx_per_list[j]->data[i].ticks_match += det_ctx->keyword_perf_data_per_list[j][i].ticks_match; - de_ctx->profile_keyword_ctx_per_list[j]->data[i].ticks_no_match += det_ctx->keyword_perf_data_per_list[j][i].ticks_no_match; - if (det_ctx->keyword_perf_data_per_list[j][i].max > de_ctx->profile_keyword_ctx_per_list[j]->data[i].max) - de_ctx->profile_keyword_ctx_per_list[j]->data[i].max = det_ctx->keyword_perf_data_per_list[j][i].max; - } - } -} - -void SCProfilingKeywordThreadCleanup(DetectEngineThreadCtx *det_ctx) -{ - if (det_ctx == NULL || det_ctx->de_ctx == NULL || det_ctx->keyword_perf_data == NULL) - return; - - pthread_mutex_lock(&det_ctx->de_ctx->profile_keyword_ctx->data_m); - SCProfilingKeywordThreadMerge(det_ctx->de_ctx, det_ctx); - pthread_mutex_unlock(&det_ctx->de_ctx->profile_keyword_ctx->data_m); - - SCFree(det_ctx->keyword_perf_data); - det_ctx->keyword_perf_data = NULL; - - int i; - for (i = 0; i < DETECT_SM_LIST_MAX; i++) { - SCFree(det_ctx->keyword_perf_data_per_list[i]); - det_ctx->keyword_perf_data_per_list[i] = NULL; - } - -} - -/** - * \brief Register the keyword profiling counters. - * - * \param de_ctx The active DetectEngineCtx, used to get at the loaded rules. - */ -void -SCProfilingKeywordInitCounters(DetectEngineCtx *de_ctx) -{ - if (profiling_keyword_enabled == 0) - return; - - de_ctx->profile_keyword_ctx = SCProfilingKeywordInitCtx(); - BUG_ON(de_ctx->profile_keyword_ctx == NULL); - - de_ctx->profile_keyword_ctx->data = SCMalloc(sizeof(SCProfileKeywordData) * DETECT_TBLSIZE); - BUG_ON(de_ctx->profile_keyword_ctx->data == NULL); - memset(de_ctx->profile_keyword_ctx->data, 0x00, sizeof(SCProfileKeywordData) * DETECT_TBLSIZE); - - int i; - for (i = 0; i < DETECT_SM_LIST_MAX; i++) { - de_ctx->profile_keyword_ctx_per_list[i] = SCProfilingKeywordInitCtx(); - BUG_ON(de_ctx->profile_keyword_ctx_per_list[i] == NULL); - de_ctx->profile_keyword_ctx_per_list[i]->data = SCMalloc(sizeof(SCProfileKeywordData) * DETECT_TBLSIZE); - BUG_ON(de_ctx->profile_keyword_ctx_per_list[i]->data == NULL); - memset(de_ctx->profile_keyword_ctx_per_list[i]->data, 0x00, sizeof(SCProfileKeywordData) * DETECT_TBLSIZE); - } - - SCLogInfo("Registered %"PRIu32" keyword profiling counters.", DETECT_TBLSIZE); -} - -#endif /* PROFILING */ diff --git a/framework/src/suricata/src/util-profiling-locks.c b/framework/src/suricata/src/util-profiling-locks.c deleted file mode 100644 index 7719e6d5..00000000 --- a/framework/src/suricata/src/util-profiling-locks.c +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * An API for profiling locks. - * - */ - -#include "suricata-common.h" -#include "util-profiling-locks.h" -#include "util-hashlist.h" - -#ifdef PROFILING -#ifdef PROFILE_LOCKING - -__thread ProfilingLock locks[PROFILING_MAX_LOCKS]; -__thread int locks_idx = 0; -__thread int record_locks = 0; - -int profiling_locks_enabled = 0; -int profiling_locks_output_to_file = 0; -char *profiling_locks_file_name = NULL; -char *profiling_locks_file_mode = "a"; - -typedef struct LockRecord_ { - char *file; // hash - - char *func; // info - int type; // info - - int line; // hash - - uint32_t cont; - uint32_t ticks_cnt; - uint64_t ticks_total; - uint64_t ticks_max; -} LockRecord; - -HashListTable *lock_records; -pthread_mutex_t lock_records_mutex; - -static uint32_t LockRecordHash(HashListTable *ht, void *buf, uint16_t buflen) -{ - LockRecord *fn = (LockRecord *)buf; - uint32_t hash = strlen(fn->file) + fn->line; - uint16_t u; - - for (u = 0; u < strlen(fn->file); u++) { - hash += fn->file[u]; - } - - return hash % ht->array_size; -} - -static char LockRecordCompare(void *buf1, uint16_t len1, void *buf2, uint16_t len2) -{ - LockRecord *fn1 = (LockRecord *)buf1; - LockRecord *fn2 = (LockRecord *)buf2; - - if (fn1->line != fn2->line) - return 0; - - if (fn1->file == fn2->file) - return 1; - - return 0; -} - -static void LockRecordFree(void *data) -{ - LockRecord *fn = (LockRecord *)data; - - if (fn == NULL) - return; - SCFree(fn); -} - -int LockRecordInitHash() -{ - pthread_mutex_init(&lock_records_mutex, NULL); - pthread_mutex_lock(&lock_records_mutex); - - lock_records = HashListTableInit(512, LockRecordHash, LockRecordCompare, LockRecordFree); - BUG_ON(lock_records == NULL); - - pthread_mutex_unlock(&lock_records_mutex); - - return 0; -} - -void LockRecordAdd(ProfilingLock *l) -{ - LockRecord fn = { NULL, NULL, 0,0,0,0,0,0}, *ptr = &fn; - fn.file = l->file; - fn.line = l->line; - - LockRecord *lookup_fn = (LockRecord *)HashListTableLookup(lock_records, (void *)ptr, 0); - if (lookup_fn == NULL) { - LockRecord *new = SCMalloc(sizeof(LockRecord)); - BUG_ON(new == NULL); - - new->file = l->file; - new->line = l->line; - new->type = l->type; - new->cont = l->cont; - new->func = l->func; - new->ticks_max = l->ticks; - new->ticks_total = l->ticks; - new->ticks_cnt = 1; - - HashListTableAdd(lock_records, (void *)new, 0); - } else { - lookup_fn->ticks_total += l->ticks; - if (l->ticks > lookup_fn->ticks_max) - lookup_fn->ticks_max = l->ticks; - lookup_fn->ticks_cnt++; - lookup_fn->cont += l->cont; - } - - return; -} - -/** \param p void ptr to Packet struct */ -void SCProfilingAddPacketLocks(void *p) -{ - int i; - - if (profiling_locks_enabled == 0) - return; - - for (i = 0; i < locks_idx; i++) { - pthread_mutex_lock(&lock_records_mutex); - LockRecordAdd(&locks[i]); - pthread_mutex_unlock(&lock_records_mutex); - } -} - -void SCProfilingListLocks(void) -{ - FILE *fp = NULL; - - if (profiling_locks_output_to_file == 1) { - fp = fopen(profiling_locks_file_name, profiling_locks_file_mode); - - if (fp == NULL) { - SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", - profiling_locks_file_name, strerror(errno)); - return; - } - } else { - fp = stdout; - } - - fprintf(fp, "\n\nLock Cnt Avg ticks Max ticks Total ticks Cont Func\n"); - fprintf(fp, "------------------ ---------- --------- ------------ ------------ ------- ---------\n"); - - uint64_t total = 0; - uint32_t cont = 0; - uint64_t cnt = 0; - - HashListTableBucket *b = HashListTableGetListHead(lock_records); - while (b) { - LockRecord *r = HashListTableGetListData(b); - - char *lock; - switch (r->type) { - case LOCK_MUTEX: - lock = "mtx"; - break; - case LOCK_SPIN: - lock = "spn"; - break; - case LOCK_RWW: - lock = "rww"; - break; - case LOCK_RWR: - lock = "rwr"; - break; - default: - lock = "bug"; - break; - } - - char str[128] = ""; - snprintf(str, sizeof(str), "(%s) %s:%d", lock,r->file, r->line); - - fprintf(fp, "%-50s %-10u %-9"PRIu64" %-12"PRIu64" %-12"PRIu64" %-7u %-s\n", - str, r->ticks_cnt, (uint64_t)((uint64_t)r->ticks_total/(uint64_t)r->ticks_cnt), r->ticks_max, r->ticks_total, r->cont, r->func); - - total += r->ticks_total; - cnt += r->ticks_cnt; - cont += r->cont; - - b = HashListTableGetListNext(b); - } - - fprintf(fp, "\nOverall: locks %"PRIu64", average cost %"PRIu64", contentions %"PRIu32", total ticks %"PRIu64"\n", - cnt, (uint64_t)((uint64_t)total/(uint64_t)cnt), cont, total); - - fclose(fp); -} - -void LockRecordFreeHash() -{ - if (profiling_locks_enabled == 0) - return; - - pthread_mutex_lock(&lock_records_mutex); - - SCProfilingListLocks(); - - if (lock_records != NULL) { - HashListTableFree(lock_records); - lock_records = NULL; - } - pthread_mutex_unlock(&lock_records_mutex); - - pthread_mutex_destroy(&lock_records_mutex); -} - -#endif -#endif - diff --git a/framework/src/suricata/src/util-profiling-locks.h b/framework/src/suricata/src/util-profiling-locks.h deleted file mode 100644 index 453928a0..00000000 --- a/framework/src/suricata/src/util-profiling-locks.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_PROFILE_LOCKS_H__ -#define __UTIL_PROFILE_LOCKS_H__ - -#ifdef PROFILING - -#define PROFILING_MAX_LOCKS 64 - -enum { - LOCK_MUTEX, - LOCK_SPIN, - LOCK_RWW, /**< rwlock, writer */ - LOCK_RWR, /**< rwlock, reader */ -}; - -void SCProfilingAddPacketLocks(void *); - -int LockRecordInitHash(); -void LockRecordFreeHash(); - -#endif /* PROFILING */ -#endif /* __UTIL_PROFILE_LOCKS_H__ */ - diff --git a/framework/src/suricata/src/util-profiling-rules.c b/framework/src/suricata/src/util-profiling-rules.c deleted file mode 100644 index 945bc8b3..00000000 --- a/framework/src/suricata/src/util-profiling-rules.c +++ /dev/null @@ -1,679 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited. - * \author Victor Julien - * - * An API for rule profiling operations. - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "conf.h" - -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-byte.h" -#include "util-profiling.h" -#include "util-profiling-locks.h" - -#ifdef PROFILING - -/** - * Extra data for rule profiling. - */ -typedef struct SCProfileData_ { - uint32_t sid; - uint32_t gid; - uint32_t rev; - uint64_t checks; - uint64_t matches; - uint64_t max; - uint64_t ticks_match; - uint64_t ticks_no_match; -} SCProfileData; - -typedef struct SCProfileDetectCtx_ { - uint32_t size; - uint32_t id; - SCProfileData *data; - pthread_mutex_t data_m; -} SCProfileDetectCtx; - -/** - * Used for generating the summary data to print. - */ -typedef struct SCProfileSummary_ { - uint32_t sid; - uint32_t gid; - uint32_t rev; - uint64_t ticks; - double avgticks; - double avgticks_match; - double avgticks_no_match; - uint64_t checks; - uint64_t matches; - uint64_t max; - uint64_t ticks_match; - uint64_t ticks_no_match; -} SCProfileSummary; - -extern int profiling_output_to_file; -int profiling_rules_enabled = 0; -static char *profiling_file_name = ""; -static const char *profiling_file_mode = "a"; -static int profiling_rule_json = 0; - -/** - * Sort orders for dumping profiled rules. - */ -enum { - SC_PROFILING_RULES_SORT_BY_TICKS = 0, - SC_PROFILING_RULES_SORT_BY_AVG_TICKS, - SC_PROFILING_RULES_SORT_BY_CHECKS, - SC_PROFILING_RULES_SORT_BY_MATCHES, - SC_PROFILING_RULES_SORT_BY_MAX_TICKS, - SC_PROFILING_RULES_SORT_BY_AVG_TICKS_MATCH, - SC_PROFILING_RULES_SORT_BY_AVG_TICKS_NO_MATCH, -}; -static int profiling_rules_sort_order = SC_PROFILING_RULES_SORT_BY_TICKS; - -/** - * Maximum number of rules to dump. - */ -static uint32_t profiling_rules_limit = UINT32_MAX; - -void SCProfilingRulesGlobalInit(void) -{ - ConfNode *conf; - const char *val; - - conf = ConfGetNode("profiling.rules"); - if (conf != NULL) { - if (ConfNodeChildValueIsTrue(conf, "enabled")) { - profiling_rules_enabled = 1; - - val = ConfNodeLookupChildValue(conf, "sort"); - if (val != NULL) { - if (strcmp(val, "ticks") == 0) { - profiling_rules_sort_order = - SC_PROFILING_RULES_SORT_BY_TICKS; - } - else if (strcmp(val, "avgticks") == 0) { - profiling_rules_sort_order = - SC_PROFILING_RULES_SORT_BY_AVG_TICKS; - } - else if (strcmp(val, "avgticks_match") == 0) { - profiling_rules_sort_order = - SC_PROFILING_RULES_SORT_BY_AVG_TICKS_MATCH; - } - else if (strcmp(val, "avgticks_no_match") == 0) { - profiling_rules_sort_order = - SC_PROFILING_RULES_SORT_BY_AVG_TICKS_NO_MATCH; - } - else if (strcmp(val, "checks") == 0) { - profiling_rules_sort_order = - SC_PROFILING_RULES_SORT_BY_CHECKS; - } - else if (strcmp(val, "matches") == 0) { - profiling_rules_sort_order = - SC_PROFILING_RULES_SORT_BY_MATCHES; - } - else if (strcmp(val, "maxticks") == 0) { - profiling_rules_sort_order = - SC_PROFILING_RULES_SORT_BY_MAX_TICKS; - } - else { - SCLogError(SC_ERR_INVALID_ARGUMENT, - "Invalid profiling sort order: %s", val); - exit(EXIT_FAILURE); - } - } - - val = ConfNodeLookupChildValue(conf, "limit"); - if (val != NULL) { - if (ByteExtractStringUint32(&profiling_rules_limit, 10, - (uint16_t)strlen(val), val) <= 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid limit: %s", val); - exit(EXIT_FAILURE); - } - } - const char *filename = ConfNodeLookupChildValue(conf, "filename"); - if (filename != NULL) { - - char *log_dir; - log_dir = ConfigGetLogDirectory(); - - profiling_file_name = SCMalloc(PATH_MAX); - if (unlikely(profiling_file_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name"); - exit(EXIT_FAILURE); - } - snprintf(profiling_file_name, PATH_MAX, "%s/%s", log_dir, filename); - - const char *v = ConfNodeLookupChildValue(conf, "append"); - if (v == NULL || ConfValIsTrue(v)) { - profiling_file_mode = "a"; - } else { - profiling_file_mode = "w"; - } - - profiling_output_to_file = 1; - } - if (ConfNodeChildValueIsTrue(conf, "json")) { -#ifdef HAVE_LIBJANSSON - profiling_rule_json = 1; -#else - SCLogWarning(SC_ERR_NO_JSON_SUPPORT, "no json support compiled in, using plain output"); -#endif - } - } - } -} - -/** - * \brief Qsort comparison function to sort by ticks. - */ -static int -SCProfileSummarySortByTicks(const void *a, const void *b) -{ - const SCProfileSummary *s0 = a; - const SCProfileSummary *s1 = b; - if (s1->ticks == s0->ticks) - return 0; - else - return s0->ticks > s1->ticks ? -1 : 1; -} - -/** - * \brief Qsort comparison function to sort by average ticks per match. - */ -static int -SCProfileSummarySortByAvgTicksMatch(const void *a, const void *b) -{ - const SCProfileSummary *s0 = a; - const SCProfileSummary *s1 = b; - if (s1->avgticks_match == s0->avgticks_match) - return 0; - else - return s0->avgticks_match > s1->avgticks_match ? -1 : 1; -} - -/** - * \brief Qsort comparison function to sort by average ticks per non match. - */ -static int -SCProfileSummarySortByAvgTicksNoMatch(const void *a, const void *b) -{ - const SCProfileSummary *s0 = a; - const SCProfileSummary *s1 = b; - if (s1->avgticks_no_match == s0->avgticks_no_match) - return 0; - else - return s0->avgticks_no_match > s1->avgticks_no_match ? -1 : 1; -} - -/** - * \brief Qsort comparison function to sort by average ticks. - */ -static int -SCProfileSummarySortByAvgTicks(const void *a, const void *b) -{ - const SCProfileSummary *s0 = a; - const SCProfileSummary *s1 = b; - if (s1->avgticks == s0->avgticks) - return 0; - else - return s0->avgticks > s1->avgticks ? -1 : 1; -} - -/** - * \brief Qsort comparison function to sort by checks. - */ -static int -SCProfileSummarySortByChecks(const void *a, const void *b) -{ - const SCProfileSummary *s0 = a; - const SCProfileSummary *s1 = b; - if (s1->checks == s0->checks) - return 0; - else - return s0->checks > s1->checks ? -1 : 1; -} - -/** - * \brief Qsort comparison function to sort by matches. - */ -static int -SCProfileSummarySortByMatches(const void *a, const void *b) -{ - const SCProfileSummary *s0 = a; - const SCProfileSummary *s1 = b; - if (s1->matches == s0->matches) - return 0; - else - return s0->matches > s1->matches ? -1 : 1; -} - -/** - * \brief Qsort comparison function to sort by max ticks. - */ -static int -SCProfileSummarySortByMaxTicks(const void *a, const void *b) -{ - const SCProfileSummary *s0 = a; - const SCProfileSummary *s1 = b; - if (s1->max == s0->max) - return 0; - else - return s0->max > s1->max ? -1 : 1; -} - -#ifdef HAVE_LIBJANSSON - -static void DumpJson(FILE *fp, SCProfileSummary *summary, uint32_t count, uint64_t total_ticks) -{ - char timebuf[64]; - uint32_t i; - struct timeval tval; - - json_t *js = json_object(); - if (js == NULL) - return; - json_t *jsa = json_array(); - if (jsa == NULL) { - json_decref(js); - return; - } - - gettimeofday(&tval, NULL); - CreateIsoTimeString(&tval, timebuf, sizeof(timebuf)); - json_object_set_new(js, "timestamp", json_string(timebuf)); - - for (i = 0; i < count; i++) { - /* Stop dumping when we hit our first rule with 0 checks. Due - * to sorting this will be the beginning of all the rules with - * 0 checks. */ - if (summary[i].checks == 0) - break; - - json_t *jsm = json_object(); - if (jsm) { - json_object_set_new(jsm, "signature_id", json_integer(summary[i].sid)); - json_object_set_new(jsm, "gid", json_integer(summary[i].gid)); - json_object_set_new(jsm, "rev", json_integer(summary[i].rev)); - - json_object_set_new(jsm, "checks", json_integer(summary[i].checks)); - json_object_set_new(jsm, "matches", json_integer(summary[i].matches)); - - json_object_set_new(jsm, "ticks_total", json_integer(summary[i].ticks)); - json_object_set_new(jsm, "ticks_max", json_integer(summary[i].max)); - json_object_set_new(jsm, "ticks_avg", json_integer(summary[i].avgticks)); - json_object_set_new(jsm, "ticks_avg_match", json_integer(summary[i].avgticks_match)); - json_object_set_new(jsm, "ticks_avg_nomatch", json_integer(summary[i].avgticks_no_match)); - - double percent = (long double)summary[i].ticks / - (long double)total_ticks * 100; - json_object_set_new(jsm, "percent", json_integer(percent)); - json_array_append(jsa, jsm); - } - } - json_object_set_new(js, "rules", jsa); - - char *js_s = json_dumps(js, - JSON_PRESERVE_ORDER|JSON_COMPACT|JSON_ENSURE_ASCII| -#ifdef JSON_ESCAPE_SLASH - JSON_ESCAPE_SLASH -#else - 0 -#endif - ); - - if (unlikely(js_s == NULL)) - return; - fprintf(fp, "%s", js_s); - free(js_s); - json_decref(js); -} - -#endif /* HAVE_LIBJANSSON */ - -static void DumpText(FILE *fp, SCProfileSummary *summary, uint32_t count, uint64_t total_ticks) -{ - uint32_t i; - struct timeval tval; - struct tm *tms; - gettimeofday(&tval, NULL); - struct tm local_tm; - tms = SCLocalTime(tval.tv_sec, &local_tm); - - fprintf(fp, " ----------------------------------------------" - "----------------------------\n"); - fprintf(fp, " Date: %" PRId32 "/%" PRId32 "/%04d -- " - "%02d:%02d:%02d\n", tms->tm_mon + 1, tms->tm_mday, tms->tm_year + 1900, - tms->tm_hour,tms->tm_min, tms->tm_sec); - fprintf(fp, " ----------------------------------------------" - "----------------------------\n"); - fprintf(fp, " %-8s %-12s %-8s %-8s %-12s %-6s %-8s %-8s %-11s %-11s %-11s %-11s\n", "Num", "Rule", "Gid", "Rev", "Ticks", "%", "Checks", "Matches", "Max Ticks", "Avg Ticks", "Avg Match", "Avg No Match"); - fprintf(fp, " -------- " - "------------ " - "-------- " - "-------- " - "------------ " - "------ " - "-------- " - "-------- " - "----------- " - "----------- " - "----------- " - "-------------- " - "\n"); - for (i = 0; i < MIN(count, profiling_rules_limit); i++) { - - /* Stop dumping when we hit our first rule with 0 checks. Due - * to sorting this will be the beginning of all the rules with - * 0 checks. */ - if (summary[i].checks == 0) - break; - - double percent = (long double)summary[i].ticks / - (long double)total_ticks * 100; - fprintf(fp, - " %-8"PRIu32" %-12u %-8"PRIu32" %-8"PRIu32" %-12"PRIu64" %-6.2f %-8"PRIu64" %-8"PRIu64" %-11"PRIu64" %-11.2f %-11.2f %-11.2f\n", - i + 1, - summary[i].sid, - summary[i].gid, - summary[i].rev, - summary[i].ticks, - percent, - summary[i].checks, - summary[i].matches, - summary[i].max, - summary[i].avgticks, - summary[i].avgticks_match, - summary[i].avgticks_no_match); - } - - fprintf(fp,"\n"); -} - -/** - * \brief Dump rule profiling information to file - * - * \param de_ctx The active DetectEngineCtx, used to get at the loaded rules. - */ -void -SCProfilingRuleDump(SCProfileDetectCtx *rules_ctx) -{ - uint32_t i; - FILE *fp; - - if (rules_ctx == NULL) - return; - - if (profiling_output_to_file == 1) { - fp = fopen(profiling_file_name, profiling_file_mode); - - if (fp == NULL) { - SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", profiling_file_name, - strerror(errno)); - return; - } - } else { - fp = stdout; - } - - int summary_size = sizeof(SCProfileSummary) * rules_ctx->size; - SCProfileSummary *summary = SCMalloc(summary_size); - if (unlikely(summary == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for profiling summary"); - return; - } - - uint32_t count = rules_ctx->size; - uint64_t total_ticks = 0; - - SCLogInfo("Dumping profiling data for %u rules.", count); - - memset(summary, 0, summary_size); - for (i = 0; i < count; i++) { - summary[i].sid = rules_ctx->data[i].sid; - summary[i].rev = rules_ctx->data[i].rev; - summary[i].gid = rules_ctx->data[i].gid; - - summary[i].ticks = rules_ctx->data[i].ticks_match + rules_ctx->data[i].ticks_no_match; - summary[i].checks = rules_ctx->data[i].checks; - - if (summary[i].ticks > 0) { - summary[i].avgticks = (long double)summary[i].ticks / (long double)summary[i].checks; - } - - summary[i].matches = rules_ctx->data[i].matches; - summary[i].max = rules_ctx->data[i].max; - summary[i].ticks_match = rules_ctx->data[i].ticks_match; - summary[i].ticks_no_match = rules_ctx->data[i].ticks_no_match; - if (summary[i].ticks_match > 0) { - summary[i].avgticks_match = (long double)summary[i].ticks_match / - (long double)summary[i].matches; - } - - if (summary[i].ticks_no_match > 0) { - summary[i].avgticks_no_match = (long double)summary[i].ticks_no_match / - ((long double)summary[i].checks - (long double)summary[i].matches); - } - total_ticks += summary[i].ticks; - } - - switch (profiling_rules_sort_order) { - case SC_PROFILING_RULES_SORT_BY_TICKS: - qsort(summary, count, sizeof(SCProfileSummary), - SCProfileSummarySortByTicks); - break; - case SC_PROFILING_RULES_SORT_BY_AVG_TICKS: - qsort(summary, count, sizeof(SCProfileSummary), - SCProfileSummarySortByAvgTicks); - break; - case SC_PROFILING_RULES_SORT_BY_CHECKS: - qsort(summary, count, sizeof(SCProfileSummary), - SCProfileSummarySortByChecks); - break; - case SC_PROFILING_RULES_SORT_BY_MATCHES: - qsort(summary, count, sizeof(SCProfileSummary), - SCProfileSummarySortByMatches); - break; - case SC_PROFILING_RULES_SORT_BY_MAX_TICKS: - qsort(summary, count, sizeof(SCProfileSummary), - SCProfileSummarySortByMaxTicks); - break; - case SC_PROFILING_RULES_SORT_BY_AVG_TICKS_MATCH: - qsort(summary, count, sizeof(SCProfileSummary), - SCProfileSummarySortByAvgTicksMatch); - break; - case SC_PROFILING_RULES_SORT_BY_AVG_TICKS_NO_MATCH: - qsort(summary, count, sizeof(SCProfileSummary), - SCProfileSummarySortByAvgTicksNoMatch); - break; - } -#ifdef HAVE_LIBJANSSON - if (profiling_rule_json) { - DumpJson(fp, summary, count, total_ticks); - } else -#endif - { - DumpText(fp, summary, count, total_ticks); - } - - if (fp != stdout) - fclose(fp); - SCFree(summary); - SCLogInfo("Done dumping profiling data."); -} - -/** - * \brief Register a rule profiling counter. - * - * \retval Returns the ID of the counter on success, 0 on failure. - */ -static uint16_t -SCProfilingRegisterRuleCounter(SCProfileDetectCtx *ctx) -{ - ctx->size++; - return ctx->id++; -} - -/** - * \brief Update a rule counter. - * - * \param id The ID of this counter. - * \param ticks Number of CPU ticks for this rule. - * \param match Did the rule match? - */ -void -SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *det_ctx, uint16_t id, uint64_t ticks, int match) -{ - if (det_ctx != NULL && det_ctx->rule_perf_data != NULL && det_ctx->rule_perf_data_size > id) { - SCProfileData *p = &det_ctx->rule_perf_data[id]; - - p->checks++; - p->matches += match; - if (ticks > p->max) - p->max = ticks; - if (match == 1) - p->ticks_match += ticks; - else - p->ticks_no_match += ticks; - } -} - -SCProfileDetectCtx *SCProfilingRuleInitCtx(void) -{ - SCProfileDetectCtx *ctx = SCMalloc(sizeof(SCProfileDetectCtx)); - if (ctx != NULL) { - memset(ctx, 0x00, sizeof(SCProfileDetectCtx)); - - if (pthread_mutex_init(&ctx->data_m, NULL) != 0) { - SCLogError(SC_ERR_MUTEX, - "Failed to initialize hash table mutex."); - exit(EXIT_FAILURE); - } - } - - return ctx; -} - -void SCProfilingRuleDestroyCtx(SCProfileDetectCtx *ctx) -{ - if (ctx != NULL) { - SCProfilingRuleDump(ctx); - if (ctx->data != NULL) - SCFree(ctx->data); - pthread_mutex_destroy(&ctx->data_m); - SCFree(ctx); - } -} - -void SCProfilingRuleThreadSetup(SCProfileDetectCtx *ctx, DetectEngineThreadCtx *det_ctx) -{ - if (ctx == NULL|| ctx->size == 0) - return; - - SCProfileData *a = SCMalloc(sizeof(SCProfileData) * ctx->size); - if (a != NULL) { - memset(a, 0x00, sizeof(SCProfileData) * ctx->size); - - det_ctx->rule_perf_data = a; - det_ctx->rule_perf_data_size = ctx->size; - } -} - -static void SCProfilingRuleThreadMerge(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx) -{ - if (de_ctx == NULL || de_ctx->profile_ctx == NULL || de_ctx->profile_ctx->data == NULL || - det_ctx == NULL || det_ctx->rule_perf_data == NULL) - return; - - int i; - for (i = 0; i < det_ctx->rule_perf_data_size; i++) { - de_ctx->profile_ctx->data[i].checks += det_ctx->rule_perf_data[i].checks; - de_ctx->profile_ctx->data[i].matches += det_ctx->rule_perf_data[i].matches; - de_ctx->profile_ctx->data[i].ticks_match += det_ctx->rule_perf_data[i].ticks_match; - de_ctx->profile_ctx->data[i].ticks_no_match += det_ctx->rule_perf_data[i].ticks_no_match; - if (det_ctx->rule_perf_data[i].max > de_ctx->profile_ctx->data[i].max) - de_ctx->profile_ctx->data[i].max = det_ctx->rule_perf_data[i].max; - } -} - -void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *det_ctx) -{ - if (det_ctx == NULL || det_ctx->de_ctx == NULL || det_ctx->rule_perf_data == NULL) - return; - - pthread_mutex_lock(&det_ctx->de_ctx->profile_ctx->data_m); - SCProfilingRuleThreadMerge(det_ctx->de_ctx, det_ctx); - pthread_mutex_unlock(&det_ctx->de_ctx->profile_ctx->data_m); - - SCFree(det_ctx->rule_perf_data); - det_ctx->rule_perf_data = NULL; - det_ctx->rule_perf_data_size = 0; -} - -/** - * \brief Register the rule profiling counters. - * - * \param de_ctx The active DetectEngineCtx, used to get at the loaded rules. - */ -void -SCProfilingRuleInitCounters(DetectEngineCtx *de_ctx) -{ - if (profiling_rules_enabled == 0) - return; - - de_ctx->profile_ctx = SCProfilingRuleInitCtx(); - BUG_ON(de_ctx->profile_ctx == NULL); - - Signature *sig = de_ctx->sig_list; - uint32_t count = 0; - while (sig != NULL) { - sig->profiling_id = SCProfilingRegisterRuleCounter(de_ctx->profile_ctx); - sig = sig->next; - count++; - } - - if (count > 0) { - de_ctx->profile_ctx->data = SCMalloc(sizeof(SCProfileData) * de_ctx->profile_ctx->size); - BUG_ON(de_ctx->profile_ctx->data == NULL); - memset(de_ctx->profile_ctx->data, 0x00, sizeof(SCProfileData) * de_ctx->profile_ctx->size); - - sig = de_ctx->sig_list; - while (sig != NULL) { - de_ctx->profile_ctx->data[sig->profiling_id].sid = sig->id; - de_ctx->profile_ctx->data[sig->profiling_id].gid = sig->gid; - de_ctx->profile_ctx->data[sig->profiling_id].rev = sig->rev; - sig = sig->next; - } - } - - SCLogInfo("Registered %"PRIu32" rule profiling counters.", count); -} - -#endif /* PROFILING */ - diff --git a/framework/src/suricata/src/util-profiling.c b/framework/src/suricata/src/util-profiling.c deleted file mode 100644 index dfe8c774..00000000 --- a/framework/src/suricata/src/util-profiling.c +++ /dev/null @@ -1,1160 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited. - * \author Victor Julien - * - * An API for profiling operations. - * - * Really just a wrapper around the existing perf counters. - */ - -#include "suricata-common.h" -#include "decode.h" -#include "detect.h" -#include "conf.h" - -#include "tm-threads.h" - -#include "util-unittest.h" -#include "util-byte.h" -#include "util-profiling.h" -#include "util-profiling-locks.h" - -#ifdef PROFILING - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#define DEFAULT_LOG_FILENAME "profile.log" -#define DEFAULT_LOG_MODE_APPEND "yes" - -static pthread_mutex_t packet_profile_lock; -static FILE *packet_profile_csv_fp = NULL; - -extern int profiling_locks_enabled; -extern int profiling_locks_output_to_file; -extern char *profiling_locks_file_name; -extern char *profiling_locks_file_mode; - -typedef struct SCProfilePacketData_ { - uint64_t min; - uint64_t max; - uint64_t tot; - uint64_t cnt; -#ifdef PROFILE_LOCKING - uint64_t lock; - uint64_t ticks; - uint64_t contention; - - uint64_t slock; - uint64_t sticks; - uint64_t scontention; -#endif -} SCProfilePacketData; -SCProfilePacketData packet_profile_data4[257]; /**< all proto's + tunnel */ -SCProfilePacketData packet_profile_data6[257]; /**< all proto's + tunnel */ - -/* each module, each proto */ -SCProfilePacketData packet_profile_tmm_data4[TMM_SIZE][257]; -SCProfilePacketData packet_profile_tmm_data6[TMM_SIZE][257]; - -SCProfilePacketData packet_profile_app_data4[TMM_SIZE][257]; -SCProfilePacketData packet_profile_app_data6[TMM_SIZE][257]; - -SCProfilePacketData packet_profile_app_pd_data4[257]; -SCProfilePacketData packet_profile_app_pd_data6[257]; - -SCProfilePacketData packet_profile_detect_data4[PROF_DETECT_SIZE][257]; -SCProfilePacketData packet_profile_detect_data6[PROF_DETECT_SIZE][257]; - -int profiling_packets_enabled = 0; -int profiling_packets_csv_enabled = 0; - -int profiling_output_to_file = 0; -int profiling_packets_output_to_file = 0; -char *profiling_file_name; -char *profiling_packets_file_name; -char *profiling_csv_file_name; -const char *profiling_packets_file_mode = "a"; - -static int rate = 1; -static SC_ATOMIC_DECLARE(uint64_t, samples); - -/** - * Used as a check so we don't double enter a profiling run. - */ -__thread int profiling_rules_entered = 0; - -void SCProfilingDumpPacketStats(void); -const char * PacketProfileDetectIdToString(PacketProfileDetectId id); - -static void FormatNumber(uint64_t num, char *str, size_t size) -{ - if (num < 1000UL) - snprintf(str, size, "%"PRIu64, num); - else if (num < 1000000UL) - snprintf(str, size, "%3.1fk", (float)num/1000UL); - else if (num < 1000000000UL) - snprintf(str, size, "%3.1fm", (float)num/1000000UL); - else - snprintf(str, size, "%3.1fb", (float)num/1000000000UL); -} - -/** - * \brief Initialize profiling. - */ -void -SCProfilingInit(void) -{ - ConfNode *conf; - - SC_ATOMIC_INIT(samples); - - intmax_t rate_v = 0; - (void)ConfGetInt("profiling.sample-rate", &rate_v); - if (rate_v > 0 && rate_v < INT_MAX) { - rate = (int)rate_v; - if (rate != 1) - SCLogInfo("profiling runs for every %dth packet", rate); - else - SCLogInfo("profiling runs for every packet"); - } - - conf = ConfGetNode("profiling.packets"); - if (conf != NULL) { - if (ConfNodeChildValueIsTrue(conf, "enabled")) { - profiling_packets_enabled = 1; - - if (pthread_mutex_init(&packet_profile_lock, NULL) != 0) { - SCLogError(SC_ERR_MUTEX, - "Failed to initialize packet profiling mutex."); - exit(EXIT_FAILURE); - } - memset(&packet_profile_data4, 0, sizeof(packet_profile_data4)); - memset(&packet_profile_data6, 0, sizeof(packet_profile_data6)); - memset(&packet_profile_tmm_data4, 0, sizeof(packet_profile_tmm_data4)); - memset(&packet_profile_tmm_data6, 0, sizeof(packet_profile_tmm_data6)); - memset(&packet_profile_app_data4, 0, sizeof(packet_profile_app_data4)); - memset(&packet_profile_app_data6, 0, sizeof(packet_profile_app_data6)); - memset(&packet_profile_app_pd_data4, 0, sizeof(packet_profile_app_pd_data4)); - memset(&packet_profile_app_pd_data6, 0, sizeof(packet_profile_app_pd_data6)); - memset(&packet_profile_detect_data4, 0, sizeof(packet_profile_detect_data4)); - memset(&packet_profile_detect_data6, 0, sizeof(packet_profile_detect_data6)); - - const char *filename = ConfNodeLookupChildValue(conf, "filename"); - if (filename != NULL) { - - char *log_dir; - log_dir = ConfigGetLogDirectory(); - - profiling_packets_file_name = SCMalloc(PATH_MAX); - if (unlikely(profiling_packets_file_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name"); - exit(EXIT_FAILURE); - } - - snprintf(profiling_packets_file_name, PATH_MAX, "%s/%s", log_dir, filename); - - const char *v = ConfNodeLookupChildValue(conf, "append"); - if (v == NULL || ConfValIsTrue(v)) { - profiling_packets_file_mode = "a"; - } else { - profiling_packets_file_mode = "w"; - } - - profiling_packets_output_to_file = 1; - } - } - - conf = ConfGetNode("profiling.packets.csv"); - if (conf != NULL) { - if (ConfNodeChildValueIsTrue(conf, "enabled")) { - - const char *filename = ConfNodeLookupChildValue(conf, "filename"); - if (filename == NULL) { - filename = "packet_profile.csv"; - } - - char *log_dir; - log_dir = ConfigGetLogDirectory(); - - profiling_csv_file_name = SCMalloc(PATH_MAX); - if (unlikely(profiling_csv_file_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "out of memory"); - exit(EXIT_FAILURE); - } - snprintf(profiling_csv_file_name, PATH_MAX, "%s/%s", log_dir, filename); - - packet_profile_csv_fp = fopen(profiling_csv_file_name, "w"); - if (packet_profile_csv_fp == NULL) { - return; - } - fprintf(packet_profile_csv_fp, "pcap_cnt,ipver,ipproto,total,"); - int i; - for (i = 0; i < TMM_SIZE; i++) { - fprintf(packet_profile_csv_fp, "%s,", TmModuleTmmIdToString(i)); - } - fprintf(packet_profile_csv_fp, "threading,"); - for (i = 0; i < ALPROTO_MAX; i++) { - fprintf(packet_profile_csv_fp, "%s,", AppProtoToString(i)); - } - fprintf(packet_profile_csv_fp, "STREAM (no app),proto detect,"); - for (i = 0; i < PROF_DETECT_SIZE; i++) { - fprintf(packet_profile_csv_fp, "%s,", PacketProfileDetectIdToString(i)); - } - fprintf(packet_profile_csv_fp, "\n"); - - profiling_packets_csv_enabled = 1; - } - } - } - - conf = ConfGetNode("profiling.locks"); - if (conf != NULL) { - if (ConfNodeChildValueIsTrue(conf, "enabled")) { -#ifndef PROFILE_LOCKING - SCLogWarning(SC_WARN_PROFILE, "lock profiling not compiled in. Add --enable-profiling-locks to configure."); -#else - profiling_locks_enabled = 1; - - LockRecordInitHash(); - - const char *filename = ConfNodeLookupChildValue(conf, "filename"); - if (filename != NULL) { - char *log_dir; - log_dir = ConfigGetLogDirectory(); - - profiling_locks_file_name = SCMalloc(PATH_MAX); - if (unlikely(profiling_locks_file_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "can't duplicate file name"); - exit(EXIT_FAILURE); - } - - snprintf(profiling_locks_file_name, PATH_MAX, "%s/%s", log_dir, filename); - - const char *v = ConfNodeLookupChildValue(conf, "append"); - if (v == NULL || ConfValIsTrue(v)) { - profiling_locks_file_mode = "a"; - } else { - profiling_locks_file_mode = "w"; - } - - profiling_locks_output_to_file = 1; - } -#endif - } - } - -} - -/** - * \brief Free resources used by profiling. - */ -void -SCProfilingDestroy(void) -{ - if (profiling_packets_enabled) { - pthread_mutex_destroy(&packet_profile_lock); - } - - if (profiling_packets_csv_enabled) { - if (packet_profile_csv_fp != NULL) - fclose(packet_profile_csv_fp); - packet_profile_csv_fp = NULL; - } - - if (profiling_csv_file_name != NULL) - SCFree(profiling_csv_file_name); - profiling_csv_file_name = NULL; - - if (profiling_file_name != NULL) - SCFree(profiling_file_name); - profiling_file_name = NULL; - -#ifdef PROFILE_LOCKING - LockRecordFreeHash(); -#endif -} - -void -SCProfilingDump(void) -{ - SCProfilingDumpPacketStats(); - SCLogInfo("Done dumping profiling data."); -} - -void SCProfilingDumpPacketStats(void) -{ - int i; - FILE *fp; - char totalstr[256]; - uint64_t total; - - if (profiling_packets_enabled == 0) - return; - - if (profiling_packets_output_to_file == 1) { - fp = fopen(profiling_packets_file_name, profiling_packets_file_mode); - - if (fp == NULL) { - SCLogError(SC_ERR_FOPEN, "failed to open %s: %s", - profiling_packets_file_name, strerror(errno)); - return; - } - } else { - fp = stdout; - } - - fprintf(fp, "\n\nPacket profile dump:\n"); - - fprintf(fp, "\n%-6s %-5s %-12s %-12s %-12s %-12s %-12s %-3s\n", - "IP ver", "Proto", "cnt", "min", "max", "avg", "tot", "%%"); - fprintf(fp, "%-6s %-5s %-12s %-12s %-12s %-12s %-12s %-3s\n", - "------", "-----", "----------", "------------", "------------", "-----------", "-----------", "---"); - total = 0; - for (i = 0; i < 257; i++) { - SCProfilePacketData *pd = &packet_profile_data4[i]; - total += pd->tot; - pd = &packet_profile_data6[i]; - total += pd->tot; - } - - for (i = 0; i < 257; i++) { - SCProfilePacketData *pd = &packet_profile_data4[i]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, " IPv4 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %6.2f\n", i, pd->cnt, - pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); - } - - for (i = 0; i < 257; i++) { - SCProfilePacketData *pd = &packet_profile_data6[i]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, " IPv6 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %6.2f\n", i, pd->cnt, - pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); - } - fprintf(fp, "Note: Protocol 256 tracks pseudo/tunnel packets.\n"); - - fprintf(fp, "\nPer Thread module stats:\n"); - - fprintf(fp, "\n%-24s %-6s %-5s %-12s %-12s %-12s %-12s %-12s %-3s", - "Thread Module", "IP ver", "Proto", "cnt", "min", "max", "avg", "tot", "%%"); -#ifdef PROFILE_LOCKING - fprintf(fp, " %-10s %-10s %-12s %-12s %-10s %-10s %-12s %-12s\n", - "locks", "ticks", "cont.", "cont.avg", "slocks", "sticks", "scont.", "scont.avg"); -#else - fprintf(fp, "\n"); -#endif - fprintf(fp, "%-24s %-6s %-5s %-12s %-12s %-12s %-12s %-12s %-3s", - "------------------------", "------", "-----", "----------", "------------", "------------", "-----------", "-----------", "---"); -#ifdef PROFILE_LOCKING - fprintf(fp, " %-10s %-10s %-12s %-12s %-10s %-10s %-12s %-12s\n", - "--------", "--------", "----------", "-----------", "--------", "--------", "------------", "-----------"); -#else - fprintf(fp, "\n"); -#endif - int m; - total = 0; - for (m = 0; m < TMM_SIZE; m++) { - if (tmm_modules[m].flags & TM_FLAG_LOGAPI_TM) - continue; - - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_tmm_data4[m][p]; - total += pd->tot; - - pd = &packet_profile_tmm_data6[m][p]; - total += pd->tot; - } - } - - for (m = 0; m < TMM_SIZE; m++) { - if (tmm_modules[m].flags & TM_FLAG_LOGAPI_TM) - continue; - - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_tmm_data4[m][p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, "%-24s IPv4 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %6.2f", - TmModuleTmmIdToString(m), p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); -#ifdef PROFILE_LOCKING - fprintf(fp, " %10.2f %12"PRIu64" %12"PRIu64" %10.2f %10.2f %12"PRIu64" %12"PRIu64" %10.2f\n", - (float)pd->lock/pd->cnt, (uint64_t)pd->ticks/pd->cnt, pd->contention, (float)pd->contention/pd->cnt, (float)pd->slock/pd->cnt, (uint64_t)pd->sticks/pd->cnt, pd->scontention, (float)pd->scontention/pd->cnt); -#else - fprintf(fp, "\n"); -#endif - } - } - - for (m = 0; m < TMM_SIZE; m++) { - if (tmm_modules[m].flags & TM_FLAG_LOGAPI_TM) - continue; - - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_tmm_data6[m][p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, "%-24s IPv6 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %6.2f\n", - TmModuleTmmIdToString(m), p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); - } - } - fprintf(fp, "Note: TMM_STREAMTCP includes TCP app layer parsers, see below.\n"); - - fprintf(fp, "\nPer App layer parser stats:\n"); - - fprintf(fp, "\n%-20s %-6s %-5s %-12s %-12s %-12s %-12s\n", - "App Layer", "IP ver", "Proto", "cnt", "min", "max", "avg"); - fprintf(fp, "%-20s %-6s %-5s %-12s %-12s %-12s %-12s\n", - "--------------------", "------", "-----", "----------", "------------", "------------", "-----------"); - - total = 0; - for (m = 0; m < ALPROTO_MAX; m++) { - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_app_data4[m][p]; - total += pd->tot; - - pd = &packet_profile_app_data6[m][p]; - total += pd->tot; - } - } - for (m = 0; m < ALPROTO_MAX; m++) { - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_app_data4[m][p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, "%-20s IPv4 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %-6.2f\n", - AppProtoToString(m), p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); - } - } - - for (m = 0; m < ALPROTO_MAX; m++) { - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_app_data6[m][p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, "%-20s IPv6 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %-6.2f\n", - AppProtoToString(m), p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); - } - } - - /* proto detect output */ - { - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_app_pd_data4[p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - fprintf(fp, "%-20s IPv4 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s\n", - "Proto detect", p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr); - } - - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_app_pd_data6[p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - fprintf(fp, "%-20s IPv6 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s\n", - "Proto detect", p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr); - } - } - - total = 0; - for (m = 0; m < PROF_DETECT_SIZE; m++) { - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_detect_data4[m][p]; - total += pd->tot; - - pd = &packet_profile_detect_data6[m][p]; - total += pd->tot; - } - } - - - fprintf(fp, "\n%-24s %-6s %-5s %-12s %-12s %-12s %-12s %-12s %-3s", - "Log Thread Module", "IP ver", "Proto", "cnt", "min", "max", "avg", "tot", "%%"); -#ifdef PROFILE_LOCKING - fprintf(fp, " %-10s %-10s %-12s %-12s %-10s %-10s %-12s %-12s\n", - "locks", "ticks", "cont.", "cont.avg", "slocks", "sticks", "scont.", "scont.avg"); -#else - fprintf(fp, "\n"); -#endif - fprintf(fp, "%-24s %-6s %-5s %-12s %-12s %-12s %-12s %-12s %-3s", - "------------------------", "------", "-----", "----------", "------------", "------------", "-----------", "-----------", "---"); -#ifdef PROFILE_LOCKING - fprintf(fp, " %-10s %-10s %-12s %-12s %-10s %-10s %-12s %-12s\n", - "--------", "--------", "----------", "-----------", "--------", "--------", "------------", "-----------"); -#else - fprintf(fp, "\n"); -#endif - total = 0; - for (m = 0; m < TMM_SIZE; m++) { - if (!(tmm_modules[m].flags & TM_FLAG_LOGAPI_TM)) - continue; - - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_tmm_data4[m][p]; - total += pd->tot; - - pd = &packet_profile_tmm_data6[m][p]; - total += pd->tot; - } - } - - for (m = 0; m < TMM_SIZE; m++) { - if (!(tmm_modules[m].flags & TM_FLAG_LOGAPI_TM)) - continue; - - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_tmm_data4[m][p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, "%-24s IPv4 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %6.2f", - TmModuleTmmIdToString(m), p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); -#ifdef PROFILE_LOCKING - fprintf(fp, " %10.2f %12"PRIu64" %12"PRIu64" %10.2f %10.2f %12"PRIu64" %12"PRIu64" %10.2f\n", - (float)pd->lock/pd->cnt, (uint64_t)pd->ticks/pd->cnt, pd->contention, (float)pd->contention/pd->cnt, (float)pd->slock/pd->cnt, (uint64_t)pd->sticks/pd->cnt, pd->scontention, (float)pd->scontention/pd->cnt); -#else - fprintf(fp, "\n"); -#endif - } - } - - for (m = 0; m < TMM_SIZE; m++) { - if (!(tmm_modules[m].flags & TM_FLAG_LOGAPI_TM)) - continue; - - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_tmm_data6[m][p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, "%-24s IPv6 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %6.2f\n", - TmModuleTmmIdToString(m), p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); - } - } - - fprintf(fp, "\nGeneral detection engine stats:\n"); - - total = 0; - for (m = 0; m < PROF_DETECT_SIZE; m++) { - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_detect_data4[m][p]; - total += pd->tot; - pd = &packet_profile_detect_data6[m][p]; - total += pd->tot; - } - } - - fprintf(fp, "\n%-24s %-6s %-5s %-12s %-12s %-12s %-12s %-12s\n", - "Detection phase", "IP ver", "Proto", "cnt", "min", "max", "avg", "tot"); - fprintf(fp, "%-24s %-6s %-5s %-12s %-12s %-12s %-12s %-12s\n", - "------------------------", "------", "-----", "----------", "------------", "------------", "-----------", "-----------"); - for (m = 0; m < PROF_DETECT_SIZE; m++) { - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_detect_data4[m][p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, "%-24s IPv4 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %-6.2f\n", - PacketProfileDetectIdToString(m), p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); - } - } - for (m = 0; m < PROF_DETECT_SIZE; m++) { - int p; - for (p = 0; p < 257; p++) { - SCProfilePacketData *pd = &packet_profile_detect_data6[m][p]; - - if (pd->cnt == 0) { - continue; - } - - FormatNumber(pd->tot, totalstr, sizeof(totalstr)); - double percent = (long double)pd->tot / - (long double)total * 100; - - fprintf(fp, "%-24s IPv6 %3d %12"PRIu64" %12"PRIu64" %12"PRIu64" %12"PRIu64" %12s %-6.2f\n", - PacketProfileDetectIdToString(m), p, pd->cnt, pd->min, pd->max, (uint64_t)(pd->tot / pd->cnt), totalstr, percent); - } - } - fclose(fp); -} - -void SCProfilingPrintPacketProfile(Packet *p) -{ - if (profiling_packets_csv_enabled == 0 || p == NULL || packet_profile_csv_fp == NULL || p->profile == NULL) { - return; - } - - uint64_t delta = p->profile->ticks_end - p->profile->ticks_start; - - fprintf(packet_profile_csv_fp, "%"PRIu64",%c,%"PRIu8",%"PRIu64",", - p->pcap_cnt, PKT_IS_IPV4(p) ? '4' : (PKT_IS_IPV6(p) ? '6' : '?'), p->proto, - delta); - - int i; - uint64_t tmm_total = 0; - uint64_t tmm_streamtcp_tcp = 0; - - for (i = 0; i < TMM_SIZE; i++) { - PktProfilingTmmData *pdt = &p->profile->tmm[i]; - - uint64_t tmm_delta = pdt->ticks_end - pdt->ticks_start; - fprintf(packet_profile_csv_fp, "%"PRIu64",", tmm_delta); - tmm_total += tmm_delta; - - if (p->proto == IPPROTO_TCP && i == TMM_STREAMTCP) { - tmm_streamtcp_tcp = tmm_delta; - } - } - - fprintf(packet_profile_csv_fp, "%"PRIu64",", delta - tmm_total); - - uint64_t app_total = 0; - for (i = 0; i < ALPROTO_MAX; i++) { - PktProfilingAppData *pdt = &p->profile->app[i]; - - fprintf(packet_profile_csv_fp,"%"PRIu64",", pdt->ticks_spent); - - if (p->proto == IPPROTO_TCP) { - app_total += pdt->ticks_spent; - } - } - - uint64_t real_tcp = 0; - if (tmm_streamtcp_tcp > app_total) - real_tcp = tmm_streamtcp_tcp - app_total; - fprintf(packet_profile_csv_fp, "%"PRIu64",", real_tcp); - - fprintf(packet_profile_csv_fp, "%"PRIu64",", p->profile->proto_detect); - - for (i = 0; i < PROF_DETECT_SIZE; i++) { - PktProfilingDetectData *pdt = &p->profile->detect[i]; - - fprintf(packet_profile_csv_fp,"%"PRIu64",", pdt->ticks_spent); - } - fprintf(packet_profile_csv_fp,"\n"); -} - -static void SCProfilingUpdatePacketDetectRecord(PacketProfileDetectId id, uint8_t ipproto, PktProfilingDetectData *pdt, int ipver) -{ - if (pdt == NULL) { - return; - } - - SCProfilePacketData *pd; - if (ipver == 4) - pd = &packet_profile_detect_data4[id][ipproto]; - else - pd = &packet_profile_detect_data6[id][ipproto]; - - if (pd->min == 0 || pdt->ticks_spent < pd->min) { - pd->min = pdt->ticks_spent; - } - if (pd->max < pdt->ticks_spent) { - pd->max = pdt->ticks_spent; - } - - pd->tot += pdt->ticks_spent; - pd->cnt ++; -} - -void SCProfilingUpdatePacketDetectRecords(Packet *p) -{ - PacketProfileDetectId i; - for (i = 0; i < PROF_DETECT_SIZE; i++) { - PktProfilingDetectData *pdt = &p->profile->detect[i]; - - if (pdt->ticks_spent > 0) { - if (PKT_IS_IPV4(p)) { - SCProfilingUpdatePacketDetectRecord(i, p->proto, pdt, 4); - } else { - SCProfilingUpdatePacketDetectRecord(i, p->proto, pdt, 6); - } - } - } -} - -static void SCProfilingUpdatePacketAppPdRecord(uint8_t ipproto, uint32_t ticks_spent, int ipver) -{ - SCProfilePacketData *pd; - if (ipver == 4) - pd = &packet_profile_app_pd_data4[ipproto]; - else - pd = &packet_profile_app_pd_data6[ipproto]; - - if (pd->min == 0 || ticks_spent < pd->min) { - pd->min = ticks_spent; - } - if (pd->max < ticks_spent) { - pd->max = ticks_spent; - } - - pd->tot += ticks_spent; - pd->cnt ++; -} - -static void SCProfilingUpdatePacketAppRecord(int alproto, uint8_t ipproto, PktProfilingAppData *pdt, int ipver) -{ - if (pdt == NULL) { - return; - } - - SCProfilePacketData *pd; - if (ipver == 4) - pd = &packet_profile_app_data4[alproto][ipproto]; - else - pd = &packet_profile_app_data6[alproto][ipproto]; - - if (pd->min == 0 || pdt->ticks_spent < pd->min) { - pd->min = pdt->ticks_spent; - } - if (pd->max < pdt->ticks_spent) { - pd->max = pdt->ticks_spent; - } - - pd->tot += pdt->ticks_spent; - pd->cnt ++; -} - -void SCProfilingUpdatePacketAppRecords(Packet *p) -{ - int i; - for (i = 0; i < ALPROTO_MAX; i++) { - PktProfilingAppData *pdt = &p->profile->app[i]; - - if (pdt->ticks_spent > 0) { - if (PKT_IS_IPV4(p)) { - SCProfilingUpdatePacketAppRecord(i, p->proto, pdt, 4); - } else { - SCProfilingUpdatePacketAppRecord(i, p->proto, pdt, 6); - } - } - } - - if (p->profile->proto_detect > 0) { - if (PKT_IS_IPV4(p)) { - SCProfilingUpdatePacketAppPdRecord(p->proto, p->profile->proto_detect, 4); - } else { - SCProfilingUpdatePacketAppPdRecord(p->proto, p->profile->proto_detect, 6); - } - } -} - -void SCProfilingUpdatePacketTmmRecord(int module, uint8_t proto, PktProfilingTmmData *pdt, int ipver) -{ - if (pdt == NULL) { - return; - } - - SCProfilePacketData *pd; - if (ipver == 4) - pd = &packet_profile_tmm_data4[module][proto]; - else - pd = &packet_profile_tmm_data6[module][proto]; - - uint32_t delta = (uint32_t)pdt->ticks_end - pdt->ticks_start; - if (pd->min == 0 || delta < pd->min) { - pd->min = delta; - } - if (pd->max < delta) { - pd->max = delta; - } - - pd->tot += (uint64_t)delta; - pd->cnt ++; - -#ifdef PROFILE_LOCKING - pd->lock += pdt->mutex_lock_cnt; - pd->ticks += pdt->mutex_lock_wait_ticks; - pd->contention += pdt->mutex_lock_contention; - pd->slock += pdt->spin_lock_cnt; - pd->sticks += pdt->spin_lock_wait_ticks; - pd->scontention += pdt->spin_lock_contention; -#endif -} - -void SCProfilingUpdatePacketTmmRecords(Packet *p) -{ - int i; - for (i = 0; i < TMM_SIZE; i++) { - PktProfilingTmmData *pdt = &p->profile->tmm[i]; - - if (pdt->ticks_start == 0 || pdt->ticks_end == 0 || pdt->ticks_start > pdt->ticks_end) { - continue; - } - - if (PKT_IS_IPV4(p)) { - SCProfilingUpdatePacketTmmRecord(i, p->proto, pdt, 4); - } else { - SCProfilingUpdatePacketTmmRecord(i, p->proto, pdt, 6); - } - } -} - -void SCProfilingAddPacket(Packet *p) -{ - if (p == NULL || p->profile == NULL || - p->profile->ticks_start == 0 || p->profile->ticks_end == 0 || - p->profile->ticks_start > p->profile->ticks_end) - return; - - pthread_mutex_lock(&packet_profile_lock); - { - - if (profiling_packets_csv_enabled) - SCProfilingPrintPacketProfile(p); - - if (PKT_IS_IPV4(p)) { - SCProfilePacketData *pd = &packet_profile_data4[p->proto]; - - uint64_t delta = p->profile->ticks_end - p->profile->ticks_start; - if (pd->min == 0 || delta < pd->min) { - pd->min = delta; - } - if (pd->max < delta) { - pd->max = delta; - } - - pd->tot += delta; - pd->cnt ++; - - if (IS_TUNNEL_PKT(p)) { - pd = &packet_profile_data4[256]; - - if (pd->min == 0 || delta < pd->min) { - pd->min = delta; - } - if (pd->max < delta) { - pd->max = delta; - } - - pd->tot += delta; - pd->cnt ++; - } - - SCProfilingUpdatePacketTmmRecords(p); - SCProfilingUpdatePacketAppRecords(p); - SCProfilingUpdatePacketDetectRecords(p); - - } else if (PKT_IS_IPV6(p)) { - SCProfilePacketData *pd = &packet_profile_data6[p->proto]; - - uint64_t delta = p->profile->ticks_end - p->profile->ticks_start; - if (pd->min == 0 || delta < pd->min) { - pd->min = delta; - } - if (pd->max < delta) { - pd->max = delta; - } - - pd->tot += delta; - pd->cnt ++; - - if (IS_TUNNEL_PKT(p)) { - pd = &packet_profile_data6[256]; - - if (pd->min == 0 || delta < pd->min) { - pd->min = delta; - } - if (pd->max < delta) { - pd->max = delta; - } - - pd->tot += delta; - pd->cnt ++; - } - - SCProfilingUpdatePacketTmmRecords(p); - SCProfilingUpdatePacketAppRecords(p); - SCProfilingUpdatePacketDetectRecords(p); - } - } - pthread_mutex_unlock(&packet_profile_lock); -} - -PktProfiling *SCProfilePacketStart(void) -{ - uint64_t sample = SC_ATOMIC_ADD(samples, 1); - if (sample % rate == 0) - return SCCalloc(1, sizeof(PktProfiling)); - else - return NULL; -} - -/* see if we want to profile rules for this packet */ -int SCProfileRuleStart(Packet *p) -{ -#ifdef PROFILE_LOCKING - if (p->profile != NULL) { - p->flags |= PKT_PROFILE; - return 1; - } -#else - uint64_t sample = SC_ATOMIC_ADD(samples, 1); - if (sample % rate == 0) { - p->flags |= PKT_PROFILE; - return 1; - } -#endif - return 0; -} - -#define CASE_CODE(E) case E: return #E - -/** - * \brief Maps the PacketProfileDetectId, to its string equivalent - * - * \param id PacketProfileDetectId id - * - * \retval string equivalent for the PacketProfileDetectId id - */ -const char * PacketProfileDetectIdToString(PacketProfileDetectId id) -{ - switch (id) { - CASE_CODE (PROF_DETECT_MPM); - CASE_CODE (PROF_DETECT_MPM_PACKET); -// CASE_CODE (PROF_DETECT_MPM_PKT_STREAM); - CASE_CODE (PROF_DETECT_MPM_STREAM); - CASE_CODE (PROF_DETECT_MPM_URI); - CASE_CODE (PROF_DETECT_MPM_HCBD); - CASE_CODE (PROF_DETECT_MPM_HSBD); - CASE_CODE (PROF_DETECT_MPM_HHD); - CASE_CODE (PROF_DETECT_MPM_HRHD); - CASE_CODE (PROF_DETECT_MPM_HMD); - CASE_CODE (PROF_DETECT_MPM_HCD); - CASE_CODE (PROF_DETECT_MPM_HRUD); - CASE_CODE (PROF_DETECT_MPM_HSMD); - CASE_CODE (PROF_DETECT_MPM_HSCD); - CASE_CODE (PROF_DETECT_MPM_HUAD); - CASE_CODE (PROF_DETECT_MPM_DNSQUERY); - CASE_CODE (PROF_DETECT_IPONLY); - CASE_CODE (PROF_DETECT_RULES); - CASE_CODE (PROF_DETECT_PREFILTER); - CASE_CODE (PROF_DETECT_STATEFUL); - CASE_CODE (PROF_DETECT_ALERT); - CASE_CODE (PROF_DETECT_CLEANUP); - CASE_CODE (PROF_DETECT_GETSGH); - CASE_CODE (PROF_DETECT_NONMPMLIST); - case PROF_DETECT_MPM_PKT_STREAM: - return "PROF_DETECT_MPM_PKT_STR"; - default: - return "UNKNOWN"; - } -} - - - -#ifdef UNITTESTS - -static int -ProfilingGenericTicksTest01(void) -{ -#define TEST_RUNS 1024 - uint64_t ticks_start = 0; - uint64_t ticks_end = 0; - void *ptr[TEST_RUNS]; - int i; - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - ptr[i] = SCMalloc(1024); - } - ticks_end = UtilCpuGetTicks(); - printf("malloc(1024) %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SCFree(ptr[i]); - } - ticks_end = UtilCpuGetTicks(); - printf("SCFree(1024) %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - SCMutex m[TEST_RUNS]; - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SCMutexInit(&m[i], NULL); - } - ticks_end = UtilCpuGetTicks(); - printf("SCMutexInit() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SCMutexLock(&m[i]); - } - ticks_end = UtilCpuGetTicks(); - printf("SCMutexLock() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SCMutexUnlock(&m[i]); - } - ticks_end = UtilCpuGetTicks(); - printf("SCMutexUnlock() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SCMutexDestroy(&m[i]); - } - ticks_end = UtilCpuGetTicks(); - printf("SCMutexDestroy() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - SCSpinlock s[TEST_RUNS]; - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SCSpinInit(&s[i], 0); - } - ticks_end = UtilCpuGetTicks(); - printf("SCSpinInit() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SCSpinLock(&s[i]); - } - ticks_end = UtilCpuGetTicks(); - printf("SCSpinLock() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SCSpinUnlock(&s[i]); - } - ticks_end = UtilCpuGetTicks(); - printf("SCSpinUnlock() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SCSpinDestroy(&s[i]); - } - ticks_end = UtilCpuGetTicks(); - printf("SCSpinDestroy() %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - SC_ATOMIC_DECL_AND_INIT(unsigned int, test); - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - (void) SC_ATOMIC_ADD(test,1); - } - ticks_end = UtilCpuGetTicks(); - printf("SC_ATOMIC_ADD %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - - ticks_start = UtilCpuGetTicks(); - for (i = 0; i < TEST_RUNS; i++) { - SC_ATOMIC_CAS(&test,i,i+1); - } - ticks_end = UtilCpuGetTicks(); - printf("SC_ATOMIC_CAS %"PRIu64"\n", (ticks_end - ticks_start)/TEST_RUNS); - return 1; -} - -#endif /* UNITTESTS */ - -void -SCProfilingRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("ProfilingGenericTicksTest01", ProfilingGenericTicksTest01, 1); -#endif /* UNITTESTS */ -} - -#endif /* PROFILING */ diff --git a/framework/src/suricata/src/util-profiling.h b/framework/src/suricata/src/util-profiling.h deleted file mode 100644 index 763d8414..00000000 --- a/framework/src/suricata/src/util-profiling.h +++ /dev/null @@ -1,282 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Endace Technology Limited. - * \author Victor Julien - */ - -#ifndef __UTIL_PROFILE_H__ -#define __UTIL_PROFILE_H__ - -#ifdef PROFILING - -#include "util-profiling-locks.h" -#include "util-cpu.h" - -extern int profiling_rules_enabled; -extern int profiling_packets_enabled; -extern __thread int profiling_rules_entered; - -void SCProfilingPrintPacketProfile(Packet *); -void SCProfilingAddPacket(Packet *); -int SCProfileRuleStart(Packet *p); - -#define RULE_PROFILING_START(p) \ - uint64_t profile_rule_start_ = 0; \ - uint64_t profile_rule_end_ = 0; \ - if (profiling_rules_enabled && SCProfileRuleStart((p))) { \ - if (profiling_rules_entered > 0) { \ - SCLogError(SC_ERR_FATAL, "Re-entered profiling, exiting."); \ - exit(1); \ - } \ - profiling_rules_entered++; \ - profile_rule_start_ = UtilCpuGetTicks(); \ - } - -#define RULE_PROFILING_END(ctx, r, m, p) \ - if (profiling_rules_enabled && ((p)->flags & PKT_PROFILE)) { \ - profile_rule_end_ = UtilCpuGetTicks(); \ - SCProfilingRuleUpdateCounter(ctx, r->profiling_id, \ - profile_rule_end_ - profile_rule_start_, m); \ - profiling_rules_entered--; \ - } - -extern int profiling_keyword_enabled; -extern __thread int profiling_keyword_entered; - -#define KEYWORD_PROFILING_SET_LIST(ctx, list) { \ - (ctx)->keyword_perf_list = (list); \ -} - -#define KEYWORD_PROFILING_START \ - uint64_t profile_keyword_start_ = 0; \ - uint64_t profile_keyword_end_ = 0; \ - if (profiling_keyword_enabled) { \ - if (profiling_keyword_entered > 0) { \ - SCLogError(SC_ERR_FATAL, "Re-entered profiling, exiting."); \ - abort(); \ - } \ - profiling_keyword_entered++; \ - profile_keyword_start_ = UtilCpuGetTicks(); \ - } - -/* we allow this macro to be called if profiling_keyword_entered == 0, - * so that we don't have to refactor some of the detection code. */ -#define KEYWORD_PROFILING_END(ctx, type, m) \ - if (profiling_keyword_enabled && profiling_keyword_entered) { \ - profile_keyword_end_ = UtilCpuGetTicks(); \ - SCProfilingKeywordUpdateCounter((ctx),(type),(profile_keyword_end_ - profile_keyword_start_),(m)); \ - profiling_keyword_entered--; \ - } - -PktProfiling *SCProfilePacketStart(void); - -#define PACKET_PROFILING_START(p) \ - if (profiling_packets_enabled) { \ - (p)->profile = SCProfilePacketStart(); \ - if ((p)->profile != NULL) \ - (p)->profile->ticks_start = UtilCpuGetTicks(); \ - } - -#define PACKET_PROFILING_END(p) \ - if (profiling_packets_enabled && (p)->profile != NULL) { \ - (p)->profile->ticks_end = UtilCpuGetTicks(); \ - SCProfilingAddPacket((p)); \ - } - -#ifdef PROFILE_LOCKING -#define PACKET_PROFILING_RESET_LOCKS do { \ - mutex_lock_cnt = 0; \ - mutex_lock_wait_ticks = 0; \ - mutex_lock_contention = 0; \ - spin_lock_cnt = 0; \ - spin_lock_wait_ticks = 0; \ - spin_lock_contention = 0; \ - rww_lock_cnt = 0; \ - rww_lock_wait_ticks = 0; \ - rww_lock_contention = 0; \ - rwr_lock_cnt = 0; \ - rwr_lock_wait_ticks = 0; \ - rwr_lock_contention = 0; \ - locks_idx = 0; \ - record_locks = 1;\ - } while (0) - -#define PACKET_PROFILING_COPY_LOCKS(p, id) do { \ - (p)->profile->tmm[(id)].mutex_lock_cnt = mutex_lock_cnt; \ - (p)->profile->tmm[(id)].mutex_lock_wait_ticks = mutex_lock_wait_ticks; \ - (p)->profile->tmm[(id)].mutex_lock_contention = mutex_lock_contention; \ - (p)->profile->tmm[(id)].spin_lock_cnt = spin_lock_cnt; \ - (p)->profile->tmm[(id)].spin_lock_wait_ticks = spin_lock_wait_ticks; \ - (p)->profile->tmm[(id)].spin_lock_contention = spin_lock_contention; \ - (p)->profile->tmm[(id)].rww_lock_cnt = rww_lock_cnt; \ - (p)->profile->tmm[(id)].rww_lock_wait_ticks = rww_lock_wait_ticks; \ - (p)->profile->tmm[(id)].rww_lock_contention = rww_lock_contention; \ - (p)->profile->tmm[(id)].rwr_lock_cnt = rwr_lock_cnt; \ - (p)->profile->tmm[(id)].rwr_lock_wait_ticks = rwr_lock_wait_ticks; \ - (p)->profile->tmm[(id)].rwr_lock_contention = rwr_lock_contention; \ - record_locks = 0; \ - SCProfilingAddPacketLocks((p)); \ - } while(0) -#else -#define PACKET_PROFILING_RESET_LOCKS -#define PACKET_PROFILING_COPY_LOCKS(p, id) -#endif - -#define PACKET_PROFILING_TMM_START(p, id) \ - if (profiling_packets_enabled && (p)->profile != NULL) { \ - if ((id) < TMM_SIZE) { \ - (p)->profile->tmm[(id)].ticks_start = UtilCpuGetTicks();\ - PACKET_PROFILING_RESET_LOCKS; \ - } \ - } - -#define PACKET_PROFILING_TMM_END(p, id) \ - if (profiling_packets_enabled && (p)->profile != NULL) { \ - if ((id) < TMM_SIZE) { \ - PACKET_PROFILING_COPY_LOCKS((p), (id)); \ - (p)->profile->tmm[(id)].ticks_end = UtilCpuGetTicks(); \ - } \ - } - -#define PACKET_PROFILING_RESET(p) \ - if (profiling_packets_enabled && (p)->profile != NULL) { \ - SCFree((p)->profile); \ - (p)->profile = NULL; \ - } - -#define PACKET_PROFILING_APP_START(dp, id) \ - if (profiling_packets_enabled) { \ - (dp)->ticks_start = UtilCpuGetTicks(); \ - (dp)->alproto = (id); \ - } - -#define PACKET_PROFILING_APP_END(dp, id) \ - if (profiling_packets_enabled) { \ - BUG_ON((id) != (dp)->alproto); \ - (dp)->ticks_end = UtilCpuGetTicks(); \ - if ((dp)->ticks_start != 0 && (dp)->ticks_start < ((dp)->ticks_end)) { \ - (dp)->ticks_spent = ((dp)->ticks_end - (dp)->ticks_start); \ - } \ - } - -#define PACKET_PROFILING_APP_PD_START(dp) \ - if (profiling_packets_enabled) { \ - (dp)->proto_detect_ticks_start = UtilCpuGetTicks(); \ - } - -#define PACKET_PROFILING_APP_PD_END(dp) \ - if (profiling_packets_enabled) { \ - (dp)->proto_detect_ticks_end = UtilCpuGetTicks(); \ - if ((dp)->proto_detect_ticks_start != 0 && (dp)->proto_detect_ticks_start < ((dp)->proto_detect_ticks_end)) { \ - (dp)->proto_detect_ticks_spent = \ - ((dp)->proto_detect_ticks_end - (dp)->proto_detect_ticks_start); \ - } \ - } - -#define PACKET_PROFILING_APP_RESET(dp) \ - if (profiling_packets_enabled) { \ - (dp)->ticks_start = 0; \ - (dp)->ticks_end = 0; \ - (dp)->ticks_spent = 0; \ - (dp)->alproto = 0; \ - (dp)->proto_detect_ticks_start = 0; \ - (dp)->proto_detect_ticks_end = 0; \ - (dp)->proto_detect_ticks_spent = 0; \ - } - -#define PACKET_PROFILING_APP_STORE(dp, p) \ - if (profiling_packets_enabled && (p)->profile != NULL) { \ - if ((dp)->alproto < ALPROTO_MAX) { \ - (p)->profile->app[(dp)->alproto].ticks_spent += (dp)->ticks_spent; \ - (p)->profile->proto_detect += (dp)->proto_detect_ticks_spent; \ - } \ - } - -#define PACKET_PROFILING_DETECT_START(p, id) \ - if (profiling_packets_enabled && (p)->profile != NULL) { \ - if ((id) < PROF_DETECT_SIZE) { \ - (p)->profile->detect[(id)].ticks_start = UtilCpuGetTicks(); \ - } \ - } - -#define PACKET_PROFILING_DETECT_END(p, id) \ - if (profiling_packets_enabled && (p)->profile != NULL) { \ - if ((id) < PROF_DETECT_SIZE) { \ - (p)->profile->detect[(id)].ticks_end = UtilCpuGetTicks();\ - if ((p)->profile->detect[(id)].ticks_start != 0 && \ - (p)->profile->detect[(id)].ticks_start < (p)->profile->detect[(id)].ticks_end) { \ - (p)->profile->detect[(id)].ticks_spent += \ - ((p)->profile->detect[(id)].ticks_end - (p)->profile->detect[(id)].ticks_start); \ - } \ - } \ - } - - -void SCProfilingRulesGlobalInit(void); -void SCProfilingRuleDestroyCtx(struct SCProfileDetectCtx_ *); -void SCProfilingRuleInitCounters(DetectEngineCtx *); -void SCProfilingRuleUpdateCounter(DetectEngineThreadCtx *, uint16_t, uint64_t, int); -void SCProfilingRuleThreadSetup(struct SCProfileDetectCtx_ *, DetectEngineThreadCtx *); -void SCProfilingRuleThreadCleanup(DetectEngineThreadCtx *); - -void SCProfilingKeywordsGlobalInit(void); -void SCProfilingKeywordDestroyCtx(DetectEngineCtx *);//struct SCProfileKeywordDetectCtx_ *); -void SCProfilingKeywordInitCounters(DetectEngineCtx *); -void SCProfilingKeywordUpdateCounter(DetectEngineThreadCtx *det_ctx, int id, uint64_t ticks, int match); -void SCProfilingKeywordThreadSetup(struct SCProfileKeywordDetectCtx_ *, DetectEngineThreadCtx *); -void SCProfilingKeywordThreadCleanup(DetectEngineThreadCtx *); - -void SCProfilingInit(void); -void SCProfilingDestroy(void); -void SCProfilingRegisterTests(void); -void SCProfilingDump(void); - -#else - -#define RULE_PROFILING_START(p) -#define RULE_PROFILING_END(a,b,c,p) - -#define KEYWORD_PROFILING_SET_LIST(a,b) -#define KEYWORD_PROFILING_START -#define KEYWORD_PROFILING_END(a,b,c) - -#define PACKET_PROFILING_START(p) -#define PACKET_PROFILING_END(p) - -#define PACKET_PROFILING_TMM_START(p, id) -#define PACKET_PROFILING_TMM_END(p, id) - -#define PACKET_PROFILING_RESET(p) - -#define PACKET_PROFILING_APP_START(dp, id) -#define PACKET_PROFILING_APP_END(dp, id) -#define PACKET_PROFILING_APP_RESET(dp) -#define PACKET_PROFILING_APP_STORE(dp, p) - -#define PACKET_PROFILING_APP_PD_START(dp) -#define PACKET_PROFILING_APP_PD_END(dp) - -#define PACKET_PROFILING_DETECT_START(p, id) -#define PACKET_PROFILING_DETECT_END(p, id) - -#endif /* PROFILING */ - -#endif /* ! __UTIL_PROFILE_H__ */ diff --git a/framework/src/suricata/src/util-proto-name.c b/framework/src/suricata/src/util-proto-name.c deleted file mode 100644 index 0b958884..00000000 --- a/framework/src/suricata/src/util-proto-name.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - * File to provide the protocol names based on protocol numbers defined in the - * specified protocol file. - */ - -#include "suricata-common.h" -#include "util-proto-name.h" - -static int init_once = 0; - -/** - * \brief Function to load the protocol names from the specified protocol - * file. - */ -void SCProtoNameInit() -{ - BUG_ON(init_once); - init_once++; - memset(known_proto, 0x00, sizeof(known_proto)); - - /* Load the known protocols name from the /etc/protocols file */ - FILE *fp = fopen(PROTO_FILE,"r"); - if (fp != NULL) { - char line[200]; - char *ptr = NULL; - - while(fgets(line, sizeof(line), fp) != NULL) { - if (line[0] == '#') - continue; - - char *name = strtok_r(line," \t", &ptr); - if (name == NULL) - continue; - - char *proto_ch = strtok_r(NULL," \t", &ptr); - if (proto_ch == NULL) - continue; - - int proto = atoi(proto_ch); - if (proto >= 255) - continue; - - char *cname = strtok_r(NULL, " \t", &ptr); - - if (known_proto[proto] != NULL) { - SCFree(known_proto[proto]); - } - - if (cname != NULL) { - known_proto[proto] = SCStrdup(cname); - } else { - known_proto[proto] = SCStrdup(name); - } - if (unlikely(known_proto[proto] == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Failed proto name allocation"); - continue; - } - int proto_len = strlen(known_proto[proto]); - if (proto_len > 0 && known_proto[proto][proto_len - 1] == '\n') - known_proto[proto][proto_len - 1] = '\0'; - } - fclose(fp); - } -} - -/** - * \brief Function to check if the received protocol number is valid and do - * we have corresponding name entry for this number or not. - * - * \param proto Protocol number to be validated - * \retval ret On success returns TRUE otherwise FALSE - */ -uint8_t SCProtoNameValid(uint16_t proto) -{ - uint8_t ret = FALSE; - - if (proto <= 255 && known_proto[proto] != NULL) { - ret = TRUE; - } - - return ret; -} - -/** - * \brief Function to clears the memory used in storing the protocol names. - */ -void SCProtoNameDeInit() -{ - int cnt; - /* clears the memory of loaded protocol names */ - for (cnt = 0; cnt < 255; cnt++) { - if (known_proto[cnt] != NULL) - SCFree(known_proto[cnt]); - } -} diff --git a/framework/src/suricata/src/util-proto-name.h b/framework/src/suricata/src/util-proto-name.h deleted file mode 100644 index e349a6db..00000000 --- a/framework/src/suricata/src/util-proto-name.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - */ - -#ifndef __UTIL_PROTO_NAME_H__ -#define __UTIL_PROTO_NAME_H__ - -#ifndef OS_WIN32 -#define PROTO_FILE "/etc/protocols" -#else -#define PROTO_FILE "C:\\Windows\\system32\\drivers\\etc\\protocol" -#endif /* OS_WIN32 */ - -/** Lookup array to hold the information related to known protocol - * in /etc/protocols */ -char *known_proto[256]; - -uint8_t SCProtoNameValid(uint16_t); -void SCProtoNameInit(void); -void SCProtoNameDeInit(void); - -#endif /* __UTIL_PROTO_NAME_H__ */ - diff --git a/framework/src/suricata/src/util-radix-tree.c b/framework/src/suricata/src/util-radix-tree.c deleted file mode 100644 index cbf49c7d..00000000 --- a/framework/src/suricata/src/util-radix-tree.c +++ /dev/null @@ -1,4228 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Implementation of radix trees - */ - -#include "suricata-common.h" -#include "util-radix-tree.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-ip.h" -#include "util-unittest.h" -#include "util-memcmp.h" - -/** - * \brief Allocates and returns a new instance of SCRadixUserData. - * - * \param netmask The netmask entry (cidr) that has to be made in the new - * SCRadixUserData instance - * \param user The user data that has to be set for the above - * netmask in the newly created SCRadixUserData instance. - * - * \retval user_data Pointer to a new instance of SCRadixUserData. - */ -static SCRadixUserData *SCRadixAllocSCRadixUserData(uint8_t netmask, void *user) -{ - SCRadixUserData *user_data = SCMalloc(sizeof(SCRadixUserData)); - if (unlikely(user_data == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - return NULL; - } - - memset(user_data, 0, sizeof(SCRadixUserData)); - - user_data->netmask = netmask; - user_data->user = user; - - return user_data; -} - -/** - * \brief Deallocates an instance of SCRadixUserData. - * - * \param user_data Pointer to the instance of SCRadixUserData that has to be - * freed. - */ -static void SCRadixDeAllocSCRadixUserData(SCRadixUserData *user_data) -{ - SCFree(user_data); - - return; -} - -/** - * \brief Appends a user_data instance(SCRadixUserData) to a - * user_data(SCRadixUserData) list. We add the new entry in descending - * order with respect to the netmask contained in the SCRadixUserData. - * - * \param new Pointer to the SCRadixUserData to be added to the list. - * \param list Pointer to the SCRadixUserData list head, to which "new" has to - * be appended. - */ -static void SCRadixAppendToSCRadixUserDataList(SCRadixUserData *new, - SCRadixUserData **list) -{ - SCRadixUserData *temp = NULL; - SCRadixUserData *prev = NULL; - - if (new == NULL || list == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "new or list supplied as NULL"); - exit(EXIT_FAILURE); - } - - /* add to the list in descending order. The reason we do this is for - * optimizing key retrieval for a ip key under a netblock */ - prev = temp = *list; - while (temp != NULL) { - if (new->netmask > temp->netmask) - break; - prev = temp; - temp = temp->next; - } - - if (temp == *list) { - new->next = *list; - *list = new; - } else { - new->next = prev->next; - prev->next = new; - } - - return; -} - -/** - * \brief Creates a new Prefix for a key. Used internally by the API. - * - * \param key_stream Data that has to be wrapped in a SCRadixPrefix instance to - * be processed for insertion/lookup/removal of a node by the - * radix tree - * \param key_bitlen The bitlen of the the above stream. For example if the - * stream holds the ipv4 address(4 bytes), bitlen would be 32 - * \param user Pointer to the user data that has to be associated with - * this key - * - * \retval prefix The newly created prefix instance on success; NULL on failure - */ -static SCRadixPrefix *SCRadixCreatePrefix(uint8_t *key_stream, - uint16_t key_bitlen, void *user, - uint8_t netmask) -{ - SCRadixPrefix *prefix = NULL; - - if ((key_bitlen % 8 != 0)) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid argument bitlen - %d", - key_bitlen); - return NULL; - } - - if (key_stream == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Argument \"stream\" NULL"); - return NULL; - } - - if ( (prefix = SCMalloc(sizeof(SCRadixPrefix))) == NULL) - goto error; - - memset(prefix, 0, sizeof(SCRadixPrefix)); - - if ( (prefix->stream = SCMalloc(key_bitlen / 8)) == NULL) - goto error; - - memset(prefix->stream, 0, key_bitlen / 8); - - memcpy(prefix->stream, key_stream, key_bitlen / 8); - prefix->bitlen = key_bitlen; - - prefix->user_data = SCRadixAllocSCRadixUserData(netmask, user); - if (prefix->user_data == NULL) { - goto error; - } - - return prefix; - -error: - if (prefix != NULL) { - if (prefix->stream != NULL) { - SCFree(prefix->stream); - } - SCFree(prefix); - } - - return NULL; -} - -/** - * \brief Adds a netmask and its user_data for a particular prefix stream. - * - * \param prefix The prefix stream to which the netmask and its corresponding - * user data has to be added. - * \param netmask The netmask value (cidr) that has to be added to the prefix. - * \param user The pointer to the user data corresponding to the above - * netmask. - */ -static void SCRadixAddNetmaskUserDataToPrefix(SCRadixPrefix *prefix, - uint8_t netmask, - void *user) -{ - if (prefix == NULL || user == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "prefix or user NULL"); - exit(EXIT_FAILURE); - } - - SCRadixAppendToSCRadixUserDataList(SCRadixAllocSCRadixUserData(netmask, user), - &prefix->user_data); - - return; -} - -/** - * \brief Removes a particular user_data corresponding to a particular netmask - * entry, from a prefix. - * - * \param prefix Pointer to the prefix from which the user_data/netmask entry - * has to be removed. - * \param netmask The netmask value (cidr) whose user_data has to be deleted. - */ -static void SCRadixRemoveNetmaskUserDataFromPrefix(SCRadixPrefix *prefix, - uint8_t netmask) -{ - SCRadixUserData *temp = NULL, *prev = NULL; - - if (prefix == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "prefix NULL"); - exit(EXIT_FAILURE); - } - - prev = temp = prefix->user_data; - while (temp != NULL) { - if (temp->netmask == netmask) { - if (temp == prefix->user_data) - prefix->user_data = temp->next; - else - prev->next = temp->next; - - SCRadixDeAllocSCRadixUserData(temp); - break; - } - prev = temp; - temp = temp->next; - } - - return; -} - -/** - * \brief Indicates if prefix contains an entry for an ip with a specific netmask. - * - * \param prefix Pointer to the ip prefix that is being checked. - * \param netmask The netmask value (cidr) that has to be checked for - * presence in the prefix. - * - * \retval 1 On match. - * \retval 0 On no match. - */ -static int SCRadixPrefixContainNetmask(SCRadixPrefix *prefix, uint8_t netmask) -{ - SCRadixUserData *user_data = NULL; - - if (prefix == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "prefix is NULL"); - goto no_match; - } - - user_data = prefix->user_data; - while (user_data != NULL) { - if (user_data->netmask == netmask) - return 1; - user_data = user_data->next; - } - - no_match: - return 0; -} - -/** - * \brief Returns the total netmask count for this prefix. - * - * \param prefix Pointer to the prefix - * - * \retval count The total netmask count for this prefix. - */ -static int SCRadixPrefixNetmaskCount(SCRadixPrefix *prefix) -{ - SCRadixUserData *user_data = NULL; - uint32_t count = 0; - - if (prefix == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "prefix is NULL"); - return 0; - } - - user_data = prefix->user_data; - while (user_data != NULL) { - count++; - user_data = user_data->next; - } - - return count; -} - -/** - * \brief Indicates if prefix contains an entry for an ip with a specific netmask - * and if it does, it sets the user data field - * SCRadixPrefix->user_data_result to the netmask user_data entry. - * - * \param prefix Pointer to the ip prefix that is being checked. - * \param netmask The netmask value for which we will have to return the user_data - * \param exact_match Bool flag which indicates if we should check if the prefix - * holds proper netblock(< 32 for ipv4 and < 128 for ipv6) or not. - * - * \retval 1 On match. - * \retval 0 On no match. - */ -static int SCRadixPrefixContainNetmaskAndSetUserData(SCRadixPrefix *prefix, - uint16_t netmask, - int exact_match, - void **user_data_result) -{ - SCRadixUserData *user_data = NULL; - - if (prefix == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "prefix is NULL"); - goto no_match; - } - - user_data = prefix->user_data; - /* Check if we have a match for an exact ip. An exact ip as in not a proper - * netblock, i.e. an ip with a netmask of 32(ipv4) or 128(ipv6) */ - if (exact_match) { - if (user_data->netmask == netmask) { - if (user_data_result) - *user_data_result = user_data->user; - return 1; - } else { - goto no_match; - } - } - - /* Check for the user_data entry for this netmask_value */ - while (user_data != NULL) { - if (user_data->netmask == netmask) { - if (user_data_result) - *user_data_result = user_data->user; - return 1; - } - user_data = user_data->next; - } - -no_match: - if (user_data_result != NULL) - *user_data_result = NULL; - return 0; -} - -/** - * \brief Frees a SCRadixPrefix instance - * - * \param prefix Pointer to a prefix instance - * \param tree Pointer to the Radix tree to which this prefix belongs - */ -static void SCRadixReleasePrefix(SCRadixPrefix *prefix, SCRadixTree *tree) -{ - SCRadixUserData *user_data_temp1 = NULL; - SCRadixUserData *user_data_temp2 = NULL; - - if (prefix != NULL) { - if (prefix->stream != NULL) - SCFree(prefix->stream); - - user_data_temp1 = prefix->user_data; - if (tree->Free != NULL) { - while (user_data_temp1 != NULL) { - user_data_temp2 = user_data_temp1; - user_data_temp1 = user_data_temp1->next; - tree->Free(user_data_temp2->user); - SCRadixDeAllocSCRadixUserData(user_data_temp2); - } - } else if (user_data_temp1 != NULL) { - SCFree(user_data_temp1); - } - - SCFree(prefix); - } - - return; -} - -/** - * \brief Creates a new node for the Radix tree - * - * \retval node The newly created node for the radix tree - */ -static inline SCRadixNode *SCRadixCreateNode() -{ - SCRadixNode *node = NULL; - - if ( (node = SCMalloc(sizeof(SCRadixNode))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixCreateNode. Mem not allocated..."); - return NULL; - } - memset(node, 0, sizeof(SCRadixNode)); - - return node; -} - -/** - * \brief Frees a Radix tree node - * - * \param node Pointer to a Radix tree node - * \param tree Pointer to the Radix tree to which this node belongs - */ -static void SCRadixReleaseNode(SCRadixNode *node, SCRadixTree *tree) -{ - if (node != NULL) { - SCRadixReleasePrefix(node->prefix, tree); - - if (node->netmasks != NULL) - SCFree(node->netmasks); - - SCFree(node); - } - - return; -} - -/** - * \brief Creates a new Radix tree - * - * \param Free Function pointer supplied by the user to be used by the Radix - * cleanup API to free the user suppplied data - * - * \retval tree The newly created radix tree on success - * - * \initonly (all radix trees should be created at init) - */ -SCRadixTree *SCRadixCreateRadixTree(void (*Free)(void*), void (*PrintData)(void*)) -{ - SCRadixTree *tree = NULL; - - if ( (tree = SCMalloc(sizeof(SCRadixTree))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixCreateRadixTree. Exiting..."); - exit(EXIT_FAILURE); - } - memset(tree, 0, sizeof(SCRadixTree)); - - tree->Free = Free; - tree->PrintData = PrintData; - - return tree; -} - -/** - * \brief Internal helper function used by SCRadixReleaseRadixTree to free a - * subtree - * - * \param node Pointer to the root of the subtree that has to be freed - * \param tree Pointer to the Radix tree to which this subtree belongs - */ -static void SCRadixReleaseRadixSubtree(SCRadixNode *node, SCRadixTree *tree) -{ - if (node != NULL) { - SCRadixReleaseRadixSubtree(node->left, tree); - SCRadixReleaseRadixSubtree(node->right, tree); - SCRadixReleaseNode(node, tree); - } - - return; -} - -/** - * \brief Frees a Radix tree and all its nodes - * - * \param tree Pointer to the Radix tree that has to be freed - */ -void SCRadixReleaseRadixTree(SCRadixTree *tree) -{ - if (tree == NULL) - return; - - SCRadixReleaseRadixSubtree(tree->head, tree); - tree->head = NULL; - SCFree(tree); - return; -} - -/** - * \brief Adds a key to the Radix tree. Used internally by the API. - * - * \param key_stream Data that has to added to the Radix tree - * \param key_bitlen The bitlen of the the above stream. For example if the - * stream is the string "abcd", the bitlen would be 32. If - * the stream is an IPV6 address bitlen would be 128 - * \param tree Pointer to the Radix tree - * \param user Pointer to the user data that has to be associated with - * this key - * \param netmask The netmask (cidr) if we are adding an IP netblock; 255 - * if we are not adding an IP netblock - * - * \retval node Pointer to the newly created node - */ -static SCRadixNode *SCRadixAddKey(uint8_t *key_stream, uint16_t key_bitlen, - SCRadixTree *tree, void *user, uint8_t netmask) -{ - SCRadixNode *node = NULL; - SCRadixNode *new_node = NULL; - SCRadixNode *parent = NULL; - SCRadixNode *inter_node = NULL; - SCRadixNode *bottom_node = NULL; - - SCRadixPrefix *prefix = NULL; - - void *ptmp; - - uint8_t *stream = NULL; - uint8_t bitlen = 0; - - int check_bit = 0; - int differ_bit = 0; - - int i = 0; - int j = 0; - int temp = 0; - - if (tree == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Argument \"tree\" NULL"); - return NULL; - } - - /* chop the ip address against a netmask */ - MaskIPNetblock(key_stream, netmask, key_bitlen); - - if ( (prefix = SCRadixCreatePrefix(key_stream, key_bitlen, user, - netmask)) == NULL) { - SCLogError(SC_ERR_RADIX_TREE_GENERIC, "Error creating prefix"); - return NULL; - } - - /* the very first element in the radix tree */ - if (tree->head == NULL) { - node = SCRadixCreateNode(); - if (node == NULL) - return NULL; - node->prefix = prefix; - node->bit = prefix->bitlen; - tree->head = node; - if (netmask == 255 || (netmask == 32 && key_bitlen == 32) || (netmask == 128 && key_bitlen == 128)) - return node; - - /* if we have reached here, we are actually having a proper netblock in - * our hand(i.e. < 32 for ipv4 and < 128 for ipv6). Add the netmask for - * this node. The reason we add netmasks other than 32 and 128, is - * because we need those netmasks in case of searches for ips contained - * in netblocks. If the netmask is 32 or 128, either ways we will be - * having an exact match for that ip value. If it is not, we start - * chopping the incoming search ip key using the netmask values added - * into the tree and then verify for a match */ - node->netmask_cnt++; - if ( (ptmp = SCRealloc(node->netmasks, (node->netmask_cnt * - sizeof(uint8_t)))) == NULL) { - SCFree(node->netmasks); - node->netmasks = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Fatal error encountered in SCRadixAddKey. Mem not allocated"); - return NULL; - } - node->netmasks = ptmp; - node->netmasks[0] = netmask; - return node; - } - - node = tree->head; - stream = prefix->stream; - bitlen = prefix->bitlen; - - /* we walk down the tree only when we satisfy 2 conditions. The first one - * being the incoming prefix is shorter than the differ bit of the current - * node. In case we fail in this aspect, we walk down to the tree, till we - * arrive at a node that ends in a prefix */ - while (node->bit < bitlen || node->prefix == NULL) { - /* if the bitlen isn't long enough to handle the bit test, we just walk - * down along one of the paths, since either paths should end up with a - * node that has a common prefix whose differ bit is greater than the - * bitlen of the incoming prefix */ - if (bitlen <= node->bit) { - if (node->right == NULL) - break; - node = node->right; - } else { - if (SC_RADIX_BITTEST(stream[node->bit >> 3], - (0x80 >> (node->bit % 8))) ) { - if (node->right == NULL) - break; - node = node->right; - } else { - if (node->left == NULL) - break; - node = node->left; - } - } - } - - /* we need to keep a reference to the bottom-most node, that actually holds - * the prefix */ - bottom_node = node; - - /* get the first bit position where the ips differ */ - check_bit = (node->bit < bitlen)? node->bit: bitlen; - for (i = 0; (i * 8) < check_bit; i++) { - if ((temp = (stream[i] ^ bottom_node->prefix->stream[i])) == 0) { - differ_bit = (i + 1) * 8; - continue; - } - - /* find out the position where the first bit differs. This method is - * faster, but at the cost of being larger. But with larger caches - * these days we don't have to worry about cache misses */ - temp = temp * 2; - if (temp >= 256) - j = 0; - else if (temp >= 128) - j = 1; - else if (temp >= 64) - j = 2; - else if (temp >= 32) - j = 3; - else if (temp >= 16) - j = 4; - else if (temp >= 8) - j = 5; - else if (temp >= 4) - j = 6; - else if (temp >= 2) - j = 7; - - differ_bit = i * 8 + j; - break; - } - if (check_bit < differ_bit) - differ_bit = check_bit; - - /* walk up the tree till we find the position, to fit our new node in */ - parent = node->parent; - while (parent && differ_bit <= parent->bit) { - node = parent; - parent = node->parent; - } - - /* We already have the node in the tree with the same differing bit pstn */ - if (differ_bit == bitlen && node->bit == bitlen) { - if (node->prefix != NULL) { - /* Check if we already have this netmask entry covered by this prefix */ - if (SCRadixPrefixContainNetmask(node->prefix, netmask)) { - /* Basically we already have this stream prefix, as well as the - * netblock entry for this. A perfect duplicate. */ - SCLogDebug("Duplicate entry for this ip address/netblock"); - } else { - /* Basically we already have this stream prefix, but we don't - * have an entry for this particular netmask value for this - * prefix. For example, we have an entry for 192.168.0.0 and - * 192.168.0.0/16 and now we are trying to enter 192.168.0.0/20 */ - SCRadixAddNetmaskUserDataToPrefix(node->prefix, netmask, user); - - /* if we are adding a netmask of 32(for ipv4) or 128(for ipv6) - * it indicates we are adding an exact host ip into the radix - * tree, in which case we don't need to add the netmask value - * into the tree */ - if (netmask == 255 || (netmask == 32 && bitlen == 32) || (netmask == 128 && bitlen == 128)) - return node; - - /* looks like we have a netmask which is != 32 or 128, in which - * case we walk up the tree to insert this netmask value in the - * correct node */ - parent = node->parent; - while (parent != NULL && netmask < (parent->bit + 1)) { - node = parent; - parent = parent->parent; - } - - node->netmask_cnt++; - new_node = node; - - if ( (ptmp = SCRealloc(node->netmasks, (node->netmask_cnt * - sizeof(uint8_t)))) == NULL) { - SCFree(node->netmasks); - node->netmasks = NULL; - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixAddKey. Mem not allocated..."); - return NULL; - } - node->netmasks = ptmp; - - if (node->netmask_cnt == 1) { - node->netmasks[0] = netmask; - return new_node; - } - - node->netmasks[node->netmask_cnt - 1] = netmask; - - for (i = node->netmask_cnt - 2; i >= 0; i--) { - if (netmask < node->netmasks[i]) { - node->netmasks[i + 1] = netmask; - break; - } - - node->netmasks[i + 1] = node->netmasks[i]; - node->netmasks[i] = netmask; - } - } - } else { - node->prefix = SCRadixCreatePrefix(prefix->stream, prefix->bitlen, - user, 255); - } - return node; - } - - /* create the leaf node for the new key */ - new_node = SCRadixCreateNode(); - new_node->prefix = prefix; - new_node->bit = prefix->bitlen; - - /* indicates that we have got a key that has length that is already covered - * by a prefix of some other key in the tree. We create a new intermediate - * node with a single child and stick it in. We need the if only in the - * case of variable length keys */ - if (differ_bit == bitlen) { - if (SC_RADIX_BITTEST(bottom_node->prefix->stream[differ_bit >> 3], - (0x80 >> (differ_bit % 8))) ) { - new_node->right = node; - } else { - new_node->left = node; - } - new_node->parent = node->parent; - - if (node->parent == NULL) - tree->head = new_node; - else if (node->parent->right == node) - node->parent->right = new_node; - else - node->parent->left = new_node; - - node->parent = new_node; - /* stick our new_node into the tree. Create a node that holds the - * differing bit position and break the branch. Also handle the - * tranfer of netmasks between node and inter_node(explained in more - * detail below) */ - } else { - inter_node = SCRadixCreateNode(); - inter_node->prefix = NULL; - inter_node->bit = differ_bit; - inter_node->parent = node->parent; - - if (node->netmasks != NULL) { - for (i = 0; i < node->netmask_cnt; i++) { - if (node->netmasks[i] < differ_bit + 1) - break; - } - - if ( (inter_node->netmasks = SCMalloc((node->netmask_cnt - i) * - sizeof(uint8_t))) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Fatal error encountered in SCRadixAddKey. Mem not allocated..."); - return NULL; - } - - for (j = 0; j < (node->netmask_cnt - i); j++) - inter_node->netmasks[j] = node->netmasks[i + j]; - - inter_node->netmask_cnt = (node->netmask_cnt - i); - node->netmask_cnt = i; - - if (node->netmask_cnt == 0) { - SCFree(node->netmasks); - node->netmasks = NULL; - } - } - - if (SC_RADIX_BITTEST(stream[differ_bit >> 3], - (0x80 >> (differ_bit % 8))) ) { - inter_node->left = node; - inter_node->right = new_node; - } else { - inter_node->left = new_node; - inter_node->right = node; - } - new_node->parent = inter_node; - - if (node->parent == NULL) - tree->head = inter_node; - else if (node->parent->right == node) - node->parent->right = inter_node; - else - node->parent->left = inter_node; - - node->parent = inter_node; - } - - /* insert the netmask into the tree */ - if (netmask != 255 && (netmask != 32 || (netmask == 32 && bitlen != 32)) && netmask != 128) { - node = new_node; - parent = new_node->parent; - while (parent != NULL && netmask < (parent->bit + 1)) { - node = parent; - parent = parent->parent; - } - - node->netmask_cnt++; - if ( (ptmp = SCRealloc(node->netmasks, (node->netmask_cnt * - sizeof(uint8_t)))) == NULL) { - SCFree(node->netmasks); - node->netmasks = NULL; - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixAddKey. Exiting..."); - exit(EXIT_FAILURE); - } - node->netmasks = ptmp; - - if (node->netmask_cnt == 1) { - node->netmasks[0] = netmask; - return new_node; - } - - node->netmasks[node->netmask_cnt - 1] = netmask; - - for (i = node->netmask_cnt - 2; i >= 0; i--) { - if (netmask < node->netmasks[i]) { - node->netmasks[i + 1] = netmask; - break; - } - - node->netmasks[i + 1] = node->netmasks[i]; - node->netmasks[i] = netmask; - } - } - - return new_node; -} - -/** - * \brief Adds a new generic key to the Radix tree - * - * \param key_stream Data that has to be added to the Radix tree - * \param key_bitlen The bitlen of the the above stream. For example if the - * stream is the string "abcd", the bitlen would be 32 - * \param tree Pointer to the Radix tree - * \param user Pointer to the user data that has to be associated with the - * key - * - * \retval node Pointer to the newly created node - */ -SCRadixNode *SCRadixAddKeyGeneric(uint8_t *key_stream, uint16_t key_bitlen, - SCRadixTree *tree, void *user) -{ - SCRadixNode *node = SCRadixAddKey(key_stream, key_bitlen, tree, user, 255); - - return node; -} - -/** - * \brief Adds a new IPV4 address to the Radix tree - * - * \param key_stream Data that has to be added to the Radix tree. In this case - * a pointer to an IPV4 address - * \param tree Pointer to the Radix tree - * \param user Pointer to the user data that has to be associated with the - * key - * - * \retval node Pointer to the newly created node - */ -SCRadixNode *SCRadixAddKeyIPV4(uint8_t *key_stream, SCRadixTree *tree, - void *user) -{ - SCRadixNode *node = SCRadixAddKey(key_stream, 32, tree, user, 32); - - return node; -} - -/** - * \brief Adds a new IPV6 address to the Radix tree - * - * \param key_stream Data that has to be added to the Radix tree. In this case - * the pointer to an IPV6 address - * \param tree Pointer to the Radix tree - * \param user Pointer to the user data that has to be associated with the - * key - * - * \retval node Pointer to the newly created node - */ -SCRadixNode *SCRadixAddKeyIPV6(uint8_t *key_stream, SCRadixTree *tree, - void *user) -{ - SCRadixNode *node = SCRadixAddKey(key_stream, 128, tree, user, 128); - - return node; -} - -/** - * \brief Adds a new IPV4 netblock to the Radix tree - * - * \param key_stream Data that has to be added to the Radix tree. In this case - * a pointer to an IPV4 netblock - * \param tree Pointer to the Radix tree - * \param user Pointer to the user data that has to be associated with the - * key - * \param netmask The netmask (cidr) if we are adding a netblock - * - * \retval node Pointer to the newly created node - */ -SCRadixNode *SCRadixAddKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree, - void *user, uint8_t netmask) -{ - SCRadixNode *node = SCRadixAddKey(key_stream, 32, tree, user, netmask); - - return node; -} - -/** - * \brief Adds a new IPV6 netblock to the Radix tree - * - * \param key_stream Data that has to be added to the Radix tree. In this case - * a pointer to an IPV6 netblock - * \param tree Pointer to the Radix tree - * \param user Pointer to the user data that has to be associated with the - * key - * \param netmask The netmask (cidr) if we are adding a netblock - * - * \retval node Pointer to the newly created node - */ -SCRadixNode *SCRadixAddKeyIPV6Netblock(uint8_t *key_stream, SCRadixTree *tree, - void *user, uint8_t netmask) -{ - SCRadixNode *node = SCRadixAddKey(key_stream, 128, tree, user, netmask); - - return node; -} - -/** - * \brief Adds a new IPV4/netblock to the Radix tree from a string - * - * \param str IPV4 string with optional /cidr netmask - * \param tree Pointer to the Radix tree - * \param user Pointer to the user data that has to be associated with - * the key - * - * \retval node Pointer to the newly created node - */ -SCRadixNode *SCRadixAddKeyIPV4String(const char *str, SCRadixTree *tree, void *user) -{ - uint32_t ip; - uint8_t netmask = 32; - char ip_str[32]; /* Max length for full ipv4/mask string with NUL */ - char *mask_str = NULL; - struct in_addr addr; - - /* Make a copy of the string so it can be modified */ - strlcpy(ip_str, str, sizeof(ip_str) - 2); - *(ip_str + (sizeof(ip_str) - 1)) = '\0'; - - /* Does it have a mask? */ - if (NULL != (mask_str = strchr(ip_str, '/'))) { - int cidr; - *(mask_str++) = '\0'; - - /* Dotted type netmask not supported (yet) */ - if (strchr(mask_str, '.') != NULL) { - return NULL; - } - - /* Get binary values for cidr mask */ - cidr = atoi(mask_str); - if ((cidr < 0) || (cidr > 32)) { - return NULL; - } - netmask = (uint8_t)cidr; - } - - /* Validate the IP */ - if (inet_pton(AF_INET, ip_str, &addr) <= 0) { - return NULL; - } - ip = addr.s_addr; - - return SCRadixAddKey((uint8_t *)&ip, 32, tree, user, netmask); -} - -/** - * \brief Adds a new IPV6/netblock to the Radix tree from a string - * - * \param str IPV6 string with optional /cidr netmask - * \param tree Pointer to the Radix tree - * \param user Pointer to the user data that has to be associated with - * the key - * - * \retval node Pointer to the newly created node - */ -SCRadixNode *SCRadixAddKeyIPV6String(const char *str, SCRadixTree *tree, void *user) -{ - uint8_t netmask = 128; - char ip_str[80]; /* Max length for full ipv6/mask string with NUL */ - char *mask_str = NULL; - struct in6_addr addr; - - /* Make a copy of the string so it can be modified */ - strlcpy(ip_str, str, sizeof(ip_str) - 2); - *(ip_str + sizeof(ip_str) - 1) = '\0'; - - /* Does it have a mask? */ - if (NULL != (mask_str = strchr(ip_str, '/'))) { - int cidr; - *(mask_str++) = '\0'; - - /* Dotted type netmask not supported (yet) */ - if (strchr(mask_str, '.') != NULL) { - return NULL; - } - - /* Get binary values for cidr mask */ - cidr = atoi(mask_str); - if ((cidr < 0) || (cidr > 128)) { - return NULL; - } - netmask = (uint8_t)cidr; - } - - /* Validate the IP */ - if (inet_pton(AF_INET6, ip_str, &addr) <= 0) { - return NULL; - } - - return SCRadixAddKey(addr.s6_addr, 128, tree, user, netmask); -} - -static void SCRadixTransferNetmasksBWNodes(SCRadixNode *dest, SCRadixNode *src) -{ - int i = 0, j = 0; - void *ptmp = NULL; - - if (src == NULL || dest == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "src or dest NULL"); - return; - } - - /* no netmasks in the source node, to transfer to the destination node */ - if (src->netmasks == NULL) - return; - - if ( (ptmp = SCRealloc(dest->netmasks, - (src->netmask_cnt + dest->netmask_cnt) * - sizeof(uint8_t))) == NULL) { - SCFree(dest->netmasks); - dest->netmasks = NULL; - return; - } - dest->netmasks = ptmp; - - for (i = dest->netmask_cnt, j = 0; j < src->netmask_cnt; i++, j++) - dest->netmasks[i] = src->netmasks[j]; - - return; -} - -/** - * \brief Removes a netblock entry from an ip node. The function first - * deletes the netblock/user_data entry for the prefix and then - * removes the netmask entry that has been made in the tree, by - * walking up the tree and deleting the entry from the specific node. - * - * \param node The node from which the netblock entry has to be removed. - * \param netmask The netmask entry (cidr) that has to be removed. - */ -static void SCRadixRemoveNetblockEntry(SCRadixNode *node, uint8_t netmask) -{ - void *ptmp; - SCRadixNode *parent = NULL; - int i = 0; - - if (node == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument. Node is NULL"); - return; - } - - SCRadixRemoveNetmaskUserDataFromPrefix(node->prefix, netmask); - - if (netmask == 32 || netmask == 128) - return; - - parent = node->parent; - while (parent != NULL && netmask < (parent->bit + 1)) { - parent = parent->parent; - } - - for (i = 0; i < node->netmask_cnt; i++) { - if (node->netmasks[i] == netmask) - break; - } - - if (i == node->netmask_cnt) { - SCLogDebug("Something's wrong with the tree. We are unable to find the " - "netmask entry"); - return; - } - - for ( ; i < node->netmask_cnt - 1; i++) - node->netmasks[i] = node->netmasks[i + 1]; - - node->netmask_cnt--; - if (node->netmask_cnt == 0) { - SCFree(node->netmasks); - node->netmasks = NULL; - return; - } - - ptmp = SCRealloc(node->netmasks, node->netmask_cnt * sizeof(uint8_t)); - if (ptmp == NULL) { - SCFree(node->netmasks); - node->netmasks = NULL; - return; - } - node->netmasks = ptmp; - - return; -} - -/** - * \brief Removes a key from the Radix tree - * - * \param key_stream Data that has to be removed from the Radix tree - * \param key_bitlen The bitlen of the the above stream. For example if the - * stream holds an IPV4 address(4 bytes), bitlen would be 32 - * \param tree Pointer to the Radix tree from which the key has to be - * removed - */ -static void SCRadixRemoveKey(uint8_t *key_stream, uint16_t key_bitlen, - SCRadixTree *tree, uint8_t netmask) -{ - SCRadixNode *node = tree->head; - SCRadixNode *parent = NULL; - SCRadixNode *temp_dest = NULL; - - SCRadixPrefix *prefix = NULL; - - int mask = 0; - int i = 0; - - if (node == NULL) - return; - - if ( (prefix = SCRadixCreatePrefix(key_stream, key_bitlen, NULL, 255)) == NULL) - return; - - while (node->bit < prefix->bitlen) { - if (SC_RADIX_BITTEST(prefix->stream[node->bit >> 3], - (0x80 >> (node->bit % 8))) ) { - node = node->right; - } else { - node = node->left; - } - - if (node == NULL) { - SCRadixReleasePrefix(prefix, tree); - return; - } - } - - if (node->bit != prefix->bitlen || node->prefix == NULL) { - SCRadixReleasePrefix(prefix, tree); - return; - } - - i = prefix->bitlen / 8; - if (SCMemcmp(node->prefix->stream, prefix->stream, i) == 0) { - mask = -1 << (8 - prefix->bitlen % 8); - - if (prefix->bitlen % 8 == 0 || - (node->prefix->stream[i] & mask) == (prefix->stream[i] & mask)) { - if (!SCRadixPrefixContainNetmask(node->prefix, netmask)) { - SCLogDebug("The ip key exists in the Radix Tree, but this(%d) " - "netblock entry doesn't exist", netmask); - SCRadixReleasePrefix(prefix, tree); - return; - } - } else { - SCLogDebug("You are trying to remove a key that doesn't exist in " - "the Radix Tree"); - SCRadixReleasePrefix(prefix, tree); - return; - } - } else { - SCLogDebug("You are trying to remove a key that doesn't exist in the " - "Radix Tree"); - SCRadixReleasePrefix(prefix, tree); - return; - } - - /* The ip node does exist, and the netblock entry does exist in this node, if - * we have reached this point. If we have more than one netblock entry, it - * indicates we have multiple entries for this key. So we delete that - * particular netblock entry, and make our way out of this function */ - if (SCRadixPrefixNetmaskCount(node->prefix) > 1) { - SCRadixRemoveNetblockEntry(node, netmask); - SCRadixReleasePrefix(prefix, tree); - return; - } - - /* we are deleting the root of the tree. This would be the only node left - * in the tree */ - if (tree->head == node) { - SCFree(node); - tree->head = NULL; - SCRadixReleasePrefix(prefix, tree); - return; - } - - parent = node->parent; - /* parent->parent is not the root of the tree */ - if (parent->parent != NULL) { - if (parent->parent->left == parent) { - if (node->parent->left == node) { - temp_dest = parent->right; - parent->parent->left = parent->right; - parent->right->parent = parent->parent; - } else { - temp_dest = parent->left; - parent->parent->left = parent->left; - parent->left->parent = parent->parent; - } - } else { - if (node->parent->left == node) { - temp_dest = parent->right; - parent->parent->right = parent->right; - parent->right->parent = parent->parent; - } else { - temp_dest = parent->left; - parent->parent->right = parent->left; - parent->left->parent = parent->parent; - } - } - /* parent is the root of the tree */ - } else { - if (parent->left == node) { - temp_dest = tree->head->right; - tree->head->right->parent = NULL; - tree->head = tree->head->right; - } else { - temp_dest = tree->head->left; - tree->head->left->parent = NULL; - tree->head = tree->head->left; - } - } - /* We need to shift the netmask entries from the node that would be - * deleted to its immediate descendant */ - SCRadixTransferNetmasksBWNodes(temp_dest, parent); - /* release the nodes */ - SCRadixReleaseNode(parent, tree); - SCRadixReleaseNode(node, tree); - SCRadixReleasePrefix(prefix, tree); - - return; -} - -/** - * \brief Removes a key from the Radix tree - * - * \param key_stream Data that has to be removed from the Radix tree - * \param key_bitlen The bitlen of the the above stream. - * \param tree Pointer to the Radix tree from which the key has to be - * removed - */ -void SCRadixRemoveKeyGeneric(uint8_t *key_stream, uint16_t key_bitlen, - SCRadixTree *tree) -{ - SCRadixRemoveKey(key_stream, key_bitlen, tree, 255); - return; -} - -/** - * \brief Removes an IPV4 address netblock key from the Radix tree. - * - * \param key_stream Data that has to be removed from the Radix tree. In this - * case an IPV4 address - * \param tree Pointer to the Radix tree from which the key has to be - * removed - */ -void SCRadixRemoveKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree, - uint8_t netmask) -{ - SCRadixRemoveKey(key_stream, 32, tree, netmask); - return; -} - -/** - * \brief Removes an IPV4 address key(not a netblock) from the Radix tree. - * Instead of using this function, we can also used - * SCRadixRemoveKeyIPV4Netblock(), by supplying a netmask value of 32. - * - * \param key_stream Data that has to be removed from the Radix tree. In this - * case an IPV4 address - * \param tree Pointer to the Radix tree from which the key has to be - * removed - */ -void SCRadixRemoveKeyIPV4(uint8_t *key_stream, SCRadixTree *tree) -{ - SCRadixRemoveKey(key_stream, 32, tree, 32); - return; -} - -/** - * \brief Removes an IPV6 netblock address key from the Radix tree. - * - * \param key_stream Data that has to be removed from the Radix tree. In this - * case an IPV6 address - * \param tree Pointer to the Radix tree from which the key has to be - * removed - */ -void SCRadixRemoveKeyIPV6Netblock(uint8_t *key_stream, SCRadixTree *tree, - uint8_t netmask) -{ - SCRadixRemoveKey(key_stream, 128, tree, netmask); - return; -} - -/** - * \brief Removes an IPV6 address key(not a netblock) from the Radix tree. - * Instead of using this function, we can also used - * SCRadixRemoveKeyIPV6Netblock(), by supplying a netmask value of 128. - * - * \param key_stream Data that has to be removed from the Radix tree. In this - * case an IPV6 address - * \param tree Pointer to the Radix tree from which the key has to be - * removed - */ -void SCRadixRemoveKeyIPV6(uint8_t *key_stream, SCRadixTree *tree) -{ - SCRadixRemoveKey(key_stream, 128, tree, 128); - return; -} - -/** - * \brief Checks if an IP prefix falls under a netblock, in the path to the root - * of the tree, from the node. Used internally by SCRadixFindKey() - * - * \param prefix Pointer to the prefix that contains the ip address - * \param node Pointer to the node from where we have to climb the tree - */ -static inline SCRadixNode *SCRadixFindKeyIPNetblock(uint8_t *key_stream, uint8_t key_bitlen, - SCRadixNode *node, void **user_data_result) -{ - SCRadixNode *netmask_node = NULL; - int mask = 0; - int bytes = 0; - int i = 0; - int j = 0; - - while (node != NULL && node->netmasks == NULL) - node = node->parent; - - if (node == NULL) - return NULL; - /* hold the node found containing a netmask. We will need it when we call - * this function recursively */ - netmask_node = node; - - for (j = 0; j < netmask_node->netmask_cnt; j++) { - bytes = key_bitlen / 8; - for (i = 0; i < bytes; i++) { - mask = -1; - if ( ((i + 1) * 8) > netmask_node->netmasks[j]) { - if ( ((i + 1) * 8 - netmask_node->netmasks[j]) < 8) - mask = -1 << ((i + 1) * 8 - netmask_node->netmasks[j]); - else - mask = 0; - } - key_stream[i] &= mask; - } - - while (node->bit < key_bitlen) { - if (SC_RADIX_BITTEST(key_stream[node->bit >> 3], - (0x80 >> (node->bit % 8))) ) { - node = node->right; - } else { - node = node->left; - } - - if (node == NULL) - return NULL; - } - - if (node->bit != key_bitlen || node->prefix == NULL) - return NULL; - - if (SCMemcmp(node->prefix->stream, key_stream, bytes) == 0) { - mask = -1 << (8 - key_bitlen % 8); - - if (key_bitlen % 8 == 0 || - (node->prefix->stream[bytes] & mask) == (key_stream[bytes] & mask)) { - if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, netmask_node->netmasks[j], 0, user_data_result)) - return node; - } - } - } - - return SCRadixFindKeyIPNetblock(key_stream, key_bitlen, netmask_node->parent, user_data_result); -} - -/** - * \brief Checks if an IP address key is present in the tree. The function - * apart from handling any normal data, also handles ipv4/ipv6 netblocks - * - * \param key_stream Data that has to be found in the Radix tree - * \param key_bitlen The bitlen of the above stream. - * \param tree Pointer to the Radix tree - * \param exact_match The key to be searched is an ip address - */ -static SCRadixNode *SCRadixFindKey(uint8_t *key_stream, uint16_t key_bitlen, - SCRadixTree *tree, int exact_match, void **user_data_result) -{ - if (tree == NULL || tree->head == NULL) - return NULL; - - SCRadixNode *node = tree->head; - int mask = 0; - int bytes = 0; - uint8_t tmp_stream[255]; - - if (key_bitlen > 255) - return NULL; - - memset(tmp_stream, 0, 255); - memcpy(tmp_stream, key_stream, key_bitlen / 8); - - while (node->bit < key_bitlen) { - if (SC_RADIX_BITTEST(tmp_stream[node->bit >> 3], - (0x80 >> (node->bit % 8))) ) { - node = node->right; - } else { - node = node->left; - } - - if (node == NULL) { - return NULL; - } - } - - if (node->bit != key_bitlen || node->prefix == NULL) { - return NULL; - } - - bytes = key_bitlen / 8; - if (SCMemcmp(node->prefix->stream, tmp_stream, bytes) == 0) { - mask = -1 << (8 - key_bitlen % 8); - - if (key_bitlen % 8 == 0 || - (node->prefix->stream[bytes] & mask) == (tmp_stream[bytes] & mask)) { - if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, key_bitlen, 1, user_data_result)) { - return node; - } - } - } - - /* if you are not an ip key, get out of here */ - if (exact_match) { - return NULL; - } - - SCRadixNode *ret = SCRadixFindKeyIPNetblock(tmp_stream, key_bitlen, node, user_data_result); - return ret; -} - -/** - * \brief Checks if a key is present in the tree - * - * \param key_stream Data that has to be found in the Radix tree - * \param key_bitlen The bitlen of the the above stream. - * \param tree Pointer to the Radix tree instance - */ -SCRadixNode *SCRadixFindKeyGeneric(uint8_t *key_stream, uint16_t key_bitlen, - SCRadixTree *tree, void **user_data_result) -{ - return SCRadixFindKey(key_stream, key_bitlen, tree, 1, user_data_result); -} - -/** - * \brief Checks if an IPV4 address is present in the tree - * - * \param key_stream Data that has to be found in the Radix tree. In this case - * an IPV4 address - * \param tree Pointer to the Radix tree instance - */ -SCRadixNode *SCRadixFindKeyIPV4ExactMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result) -{ - return SCRadixFindKey(key_stream, 32, tree, 1, user_data_result); -} - -/** - * \brief Checks if an IPV4 address is present in the tree under a netblock - * - * \param key_stream Data that has to be found in the Radix tree. In this case - * an IPV4 address - * \param tree Pointer to the Radix tree instance - */ -SCRadixNode *SCRadixFindKeyIPV4BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result) -{ - return SCRadixFindKey(key_stream, 32, tree, 0, user_data_result); -} - -/** - * \brief Checks if an IPV4 Netblock address is present in the tree - * - * \param key_stream Data that has to be found in the Radix tree. In this case - * an IPV4 netblock address - * \param tree Pointer to the Radix tree instance - */ -SCRadixNode *SCRadixFindKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree, - uint8_t netmask, void **user_data_result) -{ - SCRadixNode *node = NULL; - node = SCRadixFindKey(key_stream, 32, tree, 0, user_data_result); - if (node == NULL) - return node; - - if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, netmask, 1, user_data_result)) - return node; - else - return NULL; -} - -/** - * \brief Checks if an IPV6 Netblock address is present in the tree - * - * \param key_stream Data that has to be found in the Radix tree. In this case - * an IPV6 netblock address - * \param tree Pointer to the Radix tree instance - */ -SCRadixNode *SCRadixFindKeyIPV6Netblock(uint8_t *key_stream, SCRadixTree *tree, - uint8_t netmask, void **user_data_result) -{ - SCRadixNode *node = NULL; - node = SCRadixFindKey(key_stream, 128, tree, 0, user_data_result); - if (node == NULL) - return node; - - if (SCRadixPrefixContainNetmaskAndSetUserData(node->prefix, (uint16_t)netmask, 1, user_data_result)) - return node; - else - return NULL; -} - -/** - * \brief Checks if an IPV6 address is present in the tree - * - * \param key_stream Data that has to be found in the Radix tree. In this case - * an IPV6 address - * \param tree Pointer to the Radix tree instance - */ -SCRadixNode *SCRadixFindKeyIPV6ExactMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result) -{ - return SCRadixFindKey(key_stream, 128, tree, 1, user_data_result); -} - -/** - * \brief Checks if an IPV6 address is present in the tree under a netblock - * - * \param key_stream Data that has to be found in the Radix tree. In this case - * an IPV6 address - * \param tree Pointer to the Radix tree instance - */ -SCRadixNode *SCRadixFindKeyIPV6BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result) -{ - return SCRadixFindKey(key_stream, 128, tree, 0, user_data_result); -} - -/** - * \brief Prints the node information from a Radix tree - * - * \param node Pointer to the Radix node whose information has to be printed - * \param level Used for indentation purposes - */ -void SCRadixPrintNodeInfo(SCRadixNode *node, int level, void (*PrintData)(void*)) -{ - int i = 0; - - if (node == NULL) - return; - - for (i = 0; i < level; i++) - printf(" "); - - printf("%d [", node->bit); - - if (node->netmasks == NULL) { - printf("%d, ", -1); - } else { - for (i = 0; i < node->netmask_cnt; i++) - printf("%s%d", (0 == i ? "" : ", "), node->netmasks[i]); - } - - printf("] ("); - if (node->prefix != NULL) { - for (i = 0; i * 8 < node->prefix->bitlen; i++) - printf("%s%d", (0 == i ? "" : "."), node->prefix->stream[i]); - printf(")\n"); - - SCRadixUserData *ud = NULL; - if (PrintData != NULL) { - do { - ud = node->prefix->user_data; - printf(" [%d], ", ud->netmask); - PrintData(ud->user); - ud = ud->next; - } while (ud != NULL); - } else { - //ud = node->prefix->user_data; - //while (ud != NULL) { - // printf(" [nm %d with data], ", ud->netmask); - // ud = ud->next; - //} - printf("No print function provided"); - } - printf("\n"); - } else { - printf("NULL)\n"); - } - - return; -} - -/** - * \brief Helper function used by SCRadixPrintTree. Prints the subtree with - * node as the root of the subtree - * - * \param node Pointer to the node that is the root of the subtree to be printed - * \param level Used for indentation purposes - */ -static void SCRadixPrintRadixSubtree(SCRadixNode *node, int level, void (*PrintData)(void*)) -{ - if (node != NULL) { - SCRadixPrintNodeInfo(node, level, PrintData); - SCRadixPrintRadixSubtree(node->left, level + 1, PrintData); - SCRadixPrintRadixSubtree(node->right, level + 1, PrintData); - } - - return; -} - -/** - * \brief Prints the Radix Tree. While printing the radix tree we use the - * following format - * - * Parent_0 - * Left_Child_1 - * Left_Child_2 - * Right_Child_2 - * Right_Child_1 - * Left_Child_2 - * Right_Child_2 and so on - * - * Each node printed out holds details on the next bit that differs - * amongst its children, and if the node holds a prefix, the perfix is - * printed as well. - * - * \param tree Pointer to the Radix tree that has to be printed - */ -void SCRadixPrintTree(SCRadixTree *tree) -{ - printf("Printing the Radix Tree: \n"); - - SCRadixPrintRadixSubtree(tree->head, 0, tree->PrintData); - - return; -} - -/*------------------------------------Unit_Tests------------------------------*/ - -#ifdef UNITTESTS - -int SCRadixTestInsertion01(void) -{ - SCRadixTree *tree = NULL; - SCRadixNode *node[2]; - - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - - node[0] = SCRadixAddKeyGeneric((uint8_t *)"abaa", 32, tree, NULL); - node[1] = SCRadixAddKeyGeneric((uint8_t *)"abab", 32, tree, NULL); - - result &= (tree->head->bit == 30); - result &= (tree->head->right == node[0]); - result &= (tree->head->left == node[1]); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestInsertion02(void) -{ - SCRadixTree *tree = NULL; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - SCRadixAddKeyGeneric((uint8_t *)"aaaaaa", 48, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"aaaaab", 48, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"aaaaaba", 56, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"abab", 32, tree, NULL); - SCRadixReleaseRadixTree(tree); - - /* If we don't have a segfault till here we have succeeded :) */ - return result; -} - -int SCRadixTestIPV4Insertion03(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - /* add a key that already exists in the tree */ - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - /* test for the existance of a key */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - /* test for the existance of a key */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - /* continue adding keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - /* test the existence of keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.3", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "127.234.2.62", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestIPV4Removal04(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - /* remove the keys from the tree */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.1", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree); - - result &= (tree->head == NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestCharacterInsertion05(void) -{ - SCRadixTree *tree = NULL; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* Let us have our team here ;-) */ - SCRadixAddKeyGeneric((uint8_t *)"Victor", 48, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Matt", 32, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Josh", 32, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Margaret", 64, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Pablo", 40, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Brian", 40, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Jasonish", 64, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Jasonmc", 56, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Nathan", 48, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Anoop", 40, tree, NULL); - - result &= (SCRadixFindKeyGeneric((uint8_t *)"Victor", 48, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Matt", 32, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Josh", 32, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Margaret", 64, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Pablo", 40, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Brian", 40, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Jasonish", 64, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Jasonmc", 56, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Nathan", 48, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Anoop", 40, tree, NULL) != NULL); - - result &= (SCRadixFindKeyGeneric((uint8_t *)"bamboo", 48, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"bool", 32, tree, NULL) == NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"meerkat", 56, tree, NULL) == NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Victor", 48, tree, NULL) == NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestCharacterRemoval06(void) -{ - SCRadixTree *tree = NULL; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* Let us have our team here ;-) */ - SCRadixAddKeyGeneric((uint8_t *)"Victor", 48, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Matt", 32, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Josh", 32, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Margaret", 64, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Pablo", 40, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Brian", 40, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Jasonish", 64, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Jasonmc", 56, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Nathan", 48, tree, NULL); - SCRadixAddKeyGeneric((uint8_t *)"Anoop", 40, tree, NULL); - - SCRadixRemoveKeyGeneric((uint8_t *)"Nathan", 48, tree); - SCRadixRemoveKeyGeneric((uint8_t *)"Brian", 40, tree); - SCRadixRemoveKeyGeneric((uint8_t *)"Margaret", 64, tree); - - result &= (SCRadixFindKeyGeneric((uint8_t *)"Victor", 48, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Matt", 32, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Josh", 32, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Margaret", 64, tree, NULL) == NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Brian", 40, tree, NULL) == NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Nathan", 48, tree, NULL) == NULL); - - SCRadixRemoveKeyGeneric((uint8_t *)"Victor", 48, tree); - SCRadixRemoveKeyGeneric((uint8_t *)"Josh", 32, tree); - SCRadixRemoveKeyGeneric((uint8_t *)"Jasonmc", 56, tree); - SCRadixRemoveKeyGeneric((uint8_t *)"Matt", 32, tree); - - result &= (SCRadixFindKeyGeneric((uint8_t *)"Pablo", 40, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Jasonish", 64, tree, NULL) != NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Anoop", 40, tree, NULL) != NULL); - - SCRadixRemoveKeyGeneric((uint8_t *)"Pablo", 40, tree); - SCRadixRemoveKeyGeneric((uint8_t *)"Jasonish", 64, tree); - SCRadixRemoveKeyGeneric((uint8_t *)"Anoop", 40, tree); - - result &= (SCRadixFindKeyGeneric((uint8_t *)"Pablo", 40, tree, NULL) == NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Jasonish", 64, tree, NULL) == NULL); - result &= (SCRadixFindKeyGeneric((uint8_t *)"Anoop", 40, tree, NULL) == NULL); - - result &= (tree->head == NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestIPV6Insertion07(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in6 servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - /* Try to add the prefix that already exists in the tree */ - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - /* test the existence of keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABC2:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF5:5346:1251:7422:1112:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestIPV6Removal08(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in6 servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - /* Try to add the prefix that already exists in the tree */ - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - /* test the existence of keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "8888:0BF1:5346:BDEA:6422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2006:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - /* test for existance */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:DDDD:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - /* remove keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree); - - /* test for existance */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - /* remove keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree); - - /* test for existance */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestIPV4NetblockInsertion09(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.192.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 18); - - if (inet_pton(AF_INET, "192.175.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - /* test for the existance of a key */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.170.1.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.145", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.64.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.191.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.224.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.174.224.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.175.224.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestIPV4NetblockInsertion10(void) -{ - SCRadixTree *tree = NULL; - SCRadixNode *node[2]; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.192.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.192.235.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "220.168.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.224.1.5", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0) - return 0; - node[0] = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, - 24); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0) - return 0; - node[1] = SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 18); - - if (inet_pton(AF_INET, "192.175.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - /* test for the existance of a key */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.53", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[0]); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[1]); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[1]); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.78", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[0]); - - /* let us remove a netblock */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 24); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.78", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.127.78", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestIPV4NetblockInsertion11(void) -{ - SCRadixTree *tree = NULL; - SCRadixNode *node = NULL; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.192.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.192.235.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "220.168.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.224.1.5", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 18); - - if (inet_pton(AF_INET, "192.175.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0) - return 0; - node = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 0); - - /* test for the existance of a key */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.53", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.78", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.127.78", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "1.1.1.1", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.255.254.25", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "169.255.254.25", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.224.1.5", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL && - SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "245.63.62.121", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL && - SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.224.1.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL && - SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node); - - /* remove node 0.0.0.0 */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 0); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.224.1.6", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.127.78", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "1.1.1.1", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.255.254.25", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "169.255.254.25", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestIPV4NetblockInsertion12(void) -{ - SCRadixTree *tree = NULL; - SCRadixNode *node[2]; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.192.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.192.235.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "220.168.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "253.224.1.5", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0) - return 0; - node[0] = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0) - return 0; - node[1] = SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 18); - - if (inet_pton(AF_INET, "225.175.21.228", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 32); - - /* test for the existance of a key */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.53", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[0]); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.53", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[1]); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[1]); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[1]); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.128.78", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[0]); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.171.127.78", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "225.175.21.228", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "225.175.21.224", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "225.175.21.229", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "225.175.21.230", &servaddr.sin_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestIPV6NetblockInsertion13(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in6 servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DB00:0000:0000:0000:0000", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, NULL, 56); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1145:6241", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - /* test the existence of keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABC2:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF5:5346:1251:7422:1112:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1146:6241", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1356:1241", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DAAA:1245:2342:1146:6241", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - - SCRadixReleaseRadixTree(tree); - - return result; -} - -int SCRadixTestIPV6NetblockInsertion14(void) -{ - SCRadixTree *tree = NULL; - SCRadixNode *node = NULL; - struct sockaddr_in6 servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - /* add the keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DB00:0000:0000:0000:0000", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, NULL, 56); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1145:6241", - &servaddr.sin6_addr) <= 0) - return 0; - SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "::", &servaddr.sin6_addr) <= 0) - return 0; - node = SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, NULL, - 0); - - /* test the existence of keys */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2004:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2004:0BF1:5346:BDEA:7422:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2004:0BF1:5346:B116:2362:8713:9124:2315", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "2004:0B23:3252:BDEA:7422:8713:9124:2341", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1145:6241", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL && - SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != node); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1145:6241", - &servaddr.sin6_addr) <= 0) - return 0; - result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL && - SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != node); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check that the best match search works for all the - * possible netblocks of a fixed address - */ -int SCRadixTestIPV4NetBlocksAndBestSearch15(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t i = 0; - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.1", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - for (; i <= 32; i++) { - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = i; - - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, i); - - void *user_data = NULL; - SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != i) { - printf("User data == %"PRIu32"; i == %"PRIu32": ", *( (uint32_t *)user_data), i); - result = 0; - goto end; - } - } - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check that the best match search works for all the - * possible netblocks of a fixed address - */ -int SCRadixTestIPV4NetBlocksAndBestSearch16(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t i = 0; - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - for (; i <= 32; i++) { - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = i; - - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, i); - - void *user_data = NULL; - SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != i) { - printf("User data == %"PRIu32"; i == %"PRIu32": ", *( (uint32_t *)user_data), i); - result = 0; - goto end; - } - } - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check that the best match search works for all the - * possible netblocks of a fixed address - */ -int SCRadixTestIPV4NetBlocksAndBestSearch17(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t i = 0; - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "10.0.0.1", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - for (; i <= 32; i++) { - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = i; - - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, i); - - void *user_data = NULL; - SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != i) { - printf("User data == %"PRIu32"; i == %"PRIu32": ", *( (uint32_t *)user_data), i); - result = 0; - goto end; - } - } - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check that the best match search works for all the - * possible netblocks of a fixed address - */ -int SCRadixTestIPV4NetBlocksAndBestSearch18(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t i = 0; - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "172.26.0.1", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - for (; i <= 32; i++) { - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = i; - - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, i); - - void *user_data = NULL; - SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != i) { - printf("User data == %"PRIu32"; i == %"PRIu32": ", *( (uint32_t *)user_data), i); - result = 0; - goto end; - } - } - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check special combinations of netblocks and addresses - * on best search checking the returned userdata - */ -int SCRadixTestIPV4NetBlocksAndBestSearch19(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - void *user_data = NULL; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = 100; - - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, 0); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.1.15", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 100) { - result = 0; - goto end; - } - - user_data = NULL; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "177.0.0.0", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = 200; - - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, 8); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "177.168.1.15", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 200) { - result = 0; - goto end; - } - - user_data = NULL; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "178.168.1.15", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t*)user_data) != 100) { - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "177.168.0.0", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = 300; - - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, 12); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "177.168.1.15", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t*)user_data) != 300) { - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "177.167.1.15", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 300) { - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "177.178.1.15", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 200) { - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "197.178.1.15", &servaddr.sin_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 100) { - result = 0; - goto end; - } - - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check that the best match search works for all the - * possible netblocks of a fixed address - */ -int SCRadixTestIPV6NetBlocksAndBestSearch20(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in6 servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t i = 0; - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ABAB:CDCD:ABAB:CDCD:1234:4321:1234:4321", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - for (; i <= 128; i++) { - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = i; - - SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, user, i); - - void *user_data = NULL; - SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != i) { - printf("User data == %"PRIu32"; i == %"PRIu32": ", *( (uint32_t *)user_data), i); - result = 0; - goto end; - } - } - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check that the best match search works for all the - * possible netblocks of a fixed address - */ -int SCRadixTestIPV6NetBlocksAndBestSearch21(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in6 servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t i = 0; - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ff00::1", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - for (; i <= 128; i++) { - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = i; - - SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, user, i); - - void *user_data = NULL; - SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != i) { - printf("User data == %"PRIu32"; i == %"PRIu32": ", *( (uint32_t *)user_data), i); - result = 0; - goto end; - } - } - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check that the best match search works for all the - * possible netblocks of a fixed address - */ -int SCRadixTestIPV6NetBlocksAndBestSearch22(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in6 servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t i = 0; - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ff00::192:168:1:1", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - for (; i <= 128; i++) { - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = i; - - SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, user, i); - - void *user_data = NULL; - SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != i) { - printf("User data == %"PRIu32"; i == %"PRIu32": ", *( (uint32_t *)user_data), i); - result = 0; - goto end; - } - } - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check that the best match search works for all the - * possible netblocks of a fixed address - */ -int SCRadixTestIPV6NetBlocksAndBestSearch23(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in6 servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t i = 0; - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "FF00:ABCD:BCDA::ABCD", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - for (; i <= 128; i++) { - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = i; - - SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, user, i); - - void *user_data = NULL; - SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != i) { - printf("User data == %"PRIu32"; i == %"PRIu32": ", *( (uint32_t *)user_data), i); - result = 0; - goto end; - } - } - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test Check special combinations of netblocks and addresses - * on best search checking the returned userdata - */ -int SCRadixTestIPV6NetBlocksAndBestSearch24(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in6 servaddr; - int result = 1; - void *user_data = NULL; - - tree = SCRadixCreateRadixTree(free, NULL); - - uint32_t *user; - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "::", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = 100; - - SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, user, 0); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ABCD::1", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t*)user_data) != 100) { - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ABCD::0", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = 200; - - SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, user, 8); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ABCD::1", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 200) { - printf("User data == %"PRIu32"; i != 200 ", *( (uint32_t *)user_data)); - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "DCBA::1", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 100) { - printf("User data == %"PRIu32"; != 100 ", *( (uint32_t *)user_data)); - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ABCD:ABCD::0", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - user = SCMalloc(sizeof(uint32_t)); - if (unlikely(user == NULL)) { - result = 0; - goto end; - } - - *user = 300; - - SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, user, 12); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ABCD:ABCD::1", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 300) { - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ABCD:AAAA::1", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 300) { - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "ABAB::1", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 200) { - result = 0; - goto end; - } - - user_data = NULL; - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET6, "CABD::1", &servaddr.sin6_addr) <= 0) { - result = 0; - goto end; - } - - node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data); - if (node == NULL) { - printf("node == NULL: "); - result = 0; - goto end; - } - - if (user_data == NULL) { - printf("User data == NULL: "); - result = 0; - goto end; - } - - if ( *( (uint32_t *)user_data) != 100) { - result = 0; - goto end; - } - - -end: - SCRadixReleaseRadixTree(tree); - - return result; -} - - -/** - * \test SCRadixTestIPV4NetblockInsertion15 insert a node searching on it. - * Should always return true but the purposse of the test is to monitor - * the memory usage to detect memleaks (there was one on searching) - */ -int SCRadixTestIPV4NetblockInsertion25(void) -{ - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - - tree = SCRadixCreateRadixTree(free, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0) - return 0; - SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16); - - /* test for the existance of a key */ - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "192.168.128.53", &servaddr.sin_addr) <= 0) - return 0; - - result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL); - - SCRadixReleaseRadixTree(tree); - - return result; -} - -/** - * \test SCRadixTestIPV4NetblockInsertion26 insert a node searching on it. - * Should always return true but the purposse of the test is to monitor - * the memory usage to detect memleaks (there was one on searching) - */ -int SCRadixTestIPV4NetblockInsertion26(void) -{ - SCRadixNode *tmp = NULL; - SCRadixTree *tree = NULL; - struct sockaddr_in servaddr; - int result = 1; - char *str = SCStrdup("Hello1"); - - tree = SCRadixCreateRadixTree(free, NULL); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0) - return 0; - tmp = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, str, 0); - if (!tmp) { - printf("Not inserted correctly 1:"); - result = 0; - goto this_end; - } - str = SCStrdup("Hello1"); - - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "176.0.0.1", &servaddr.sin_addr) <= 0) - return 0; - tmp = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, str, 5); - if (!tmp) { - printf("Not inserted correctly 2:"); - result = 0; - goto this_end; - } - - str = SCStrdup("Hello1"); - bzero(&servaddr, sizeof(servaddr)); - if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0) { - SCFree(str); - return 0; - } - tmp = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, str, 7); - if (!tmp) { - printf("Not inserted correctly 3:"); - result = 0; - goto this_end; - } - - /* test for the existance of a key */ - //result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree) != NULL); - -this_end: - SCRadixReleaseRadixTree(tree); - - //SCFree(str); - return result; -} - -#endif - -void SCRadixRegisterTests(void) -{ - -#ifdef UNITTESTS - //UtRegisterTest("SCRadixTestInsertion01", SCRadixTestInsertion01, 1); - //UtRegisterTest("SCRadixTestInsertion02", SCRadixTestInsertion02, 1); - UtRegisterTest("SCRadixTestIPV4Insertion03", SCRadixTestIPV4Insertion03, 1); - UtRegisterTest("SCRadixTestIPV4Removal04", SCRadixTestIPV4Removal04, 1); - //UtRegisterTest("SCRadixTestCharacterInsertion05", - // SCRadixTestCharacterInsertion05, 1); - //UtRegisterTest("SCRadixTestCharacterRemoval06", - // SCRadixTestCharacterRemoval06, 1); - UtRegisterTest("SCRadixTestIPV6Insertion07", SCRadixTestIPV6Insertion07, 1); - UtRegisterTest("SCRadixTestIPV6Removal08", SCRadixTestIPV6Removal08, 1); - UtRegisterTest("SCRadixTestIPV4NetblockInsertion09", - SCRadixTestIPV4NetblockInsertion09, 1); - UtRegisterTest("SCRadixTestIPV4NetblockInsertion10", - SCRadixTestIPV4NetblockInsertion10, 1); - UtRegisterTest("SCRadixTestIPV4NetblockInsertion11", - SCRadixTestIPV4NetblockInsertion11, 1); - UtRegisterTest("SCRadixTestIPV4NetblockInsertion12", - SCRadixTestIPV4NetblockInsertion12, 1); - UtRegisterTest("SCRadixTestIPV6NetblockInsertion13", - SCRadixTestIPV6NetblockInsertion13, 1); - UtRegisterTest("SCRadixTestIPV6NetblockInsertion14", - SCRadixTestIPV6NetblockInsertion14, 1); - UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch15", - SCRadixTestIPV4NetBlocksAndBestSearch15, 1); - UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch16", - SCRadixTestIPV4NetBlocksAndBestSearch16, 1); - UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch17", - SCRadixTestIPV4NetBlocksAndBestSearch17, 1); - UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch18", - SCRadixTestIPV4NetBlocksAndBestSearch18, 1); - UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch19", - SCRadixTestIPV4NetBlocksAndBestSearch19, 1); - UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch20", - SCRadixTestIPV6NetBlocksAndBestSearch20, 1); - UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch21", - SCRadixTestIPV6NetBlocksAndBestSearch21, 1); - UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch22", - SCRadixTestIPV6NetBlocksAndBestSearch22, 1); - UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch23", - SCRadixTestIPV6NetBlocksAndBestSearch23, 1); - UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch24", - SCRadixTestIPV6NetBlocksAndBestSearch24, 1); - UtRegisterTest("SCRadixTestIPV4NetblockInsertion25", - SCRadixTestIPV4NetblockInsertion25, 1); - UtRegisterTest("SCRadixTestIPV4NetblockInsertion26", - SCRadixTestIPV4NetblockInsertion26, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/util-radix-tree.h b/framework/src/suricata/src/util-radix-tree.h deleted file mode 100644 index e9e63457..00000000 --- a/framework/src/suricata/src/util-radix-tree.h +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_RADIX_TREE_H__ -#define __UTIL_RADIX_TREE_H__ - -#define SC_RADIX_BITTEST(x, y) ((x) & (y)) - -/** - * \brief Structure that hold the user data and the netmask associated with it. - */ -typedef struct SCRadixUserData_ { - /* holds a pointer to the user data associated with the particular netmask */ - void *user; - /* pointer to the next user data in the list */ - struct SCRadixUserData_ *next; - /* holds the netmask value that corresponds to this user data pointer */ - uint8_t netmask; -} SCRadixUserData; - -/** - * \brief Structure for the prefix/key in the radix tree - */ -typedef struct SCRadixPrefix_ { - /* length of the stream */ - uint16_t bitlen; - - /* the key that has been stored in the tree */ - uint8_t *stream; - - /* any user data that has to be associated with this key. We need a user - * data field for each netblock value possible since one ip can be associated - * with any of the the 32 or 128 netblocks. Also for non-ips, we store the - * netmask as 255 in SCRadixUserData->netmask */ - SCRadixUserData *user_data; -} SCRadixPrefix; - -/** - * \brief Structure for the node in the radix tree - */ -typedef struct SCRadixNode_ { - /* the bit position where the bits differ in the nodes children. Used - * to determine the path to be taken during a lookup*/ - uint16_t bit; - - uint16_t pad0; - - /* total no of netmasks that are registered under this node */ - int netmask_cnt; - /* holds a list of netmaks that come under this node in the tree */ - uint8_t *netmasks; - - /* holds the prefix that the path to this node holds */ - SCRadixPrefix *prefix; - - /* the left and the right children of a node */ - struct SCRadixNode_ *left, *right; - - /* the parent node for this tree */ - struct SCRadixNode_ *parent; -} SCRadixNode; - -/** - * \brief Structure for the radix tree - */ -typedef struct SCRadixTree_ { - /* the root node in the radix tree */ - SCRadixNode *head; - - /* function pointer that is supplied by the user to free the user data - * held by the user field of SCRadixNode */ - void (*PrintData)(void *); - void (*Free)(void *); -} SCRadixTree; - - -struct in_addr *SCRadixValidateIPV4Address(const char *); -struct in6_addr *SCRadixValidateIPV6Address(const char *); -void SCRadixChopIPAddressAgainstNetmask(uint8_t *, uint8_t, uint16_t); - -SCRadixTree *SCRadixCreateRadixTree(void (*Free)(void*), void (*PrintData)(void*)); -void SCRadixReleaseRadixTree(SCRadixTree *); - -SCRadixNode *SCRadixAddKeyGeneric(uint8_t *, uint16_t, SCRadixTree *, void *); -SCRadixNode *SCRadixAddKeyIPV4(uint8_t *, SCRadixTree *, void *); -SCRadixNode *SCRadixAddKeyIPV6(uint8_t *, SCRadixTree *, void *); -SCRadixNode *SCRadixAddKeyIPV4Netblock(uint8_t *, SCRadixTree *, void *, - uint8_t); -SCRadixNode *SCRadixAddKeyIPV6Netblock(uint8_t *, SCRadixTree *, void *, - uint8_t); -SCRadixNode *SCRadixAddKeyIPV4String(const char *, SCRadixTree *, void *); -SCRadixNode *SCRadixAddKeyIPV6String(const char *, SCRadixTree *, void *); - -void SCRadixRemoveKeyGeneric(uint8_t *, uint16_t, SCRadixTree *); -void SCRadixRemoveKeyIPV4Netblock(uint8_t *, SCRadixTree *, uint8_t); -void SCRadixRemoveKeyIPV4(uint8_t *, SCRadixTree *); -void SCRadixRemoveKeyIPV6Netblock(uint8_t *, SCRadixTree *, uint8_t); -void SCRadixRemoveKeyIPV6(uint8_t *, SCRadixTree *); - -SCRadixNode *SCRadixFindKeyGeneric(uint8_t *, uint16_t, SCRadixTree *, void **); - -SCRadixNode *SCRadixFindKeyIPV4ExactMatch(uint8_t *, SCRadixTree *, void **); -SCRadixNode *SCRadixFindKeyIPV4Netblock(uint8_t *, SCRadixTree *, uint8_t, void **); -SCRadixNode *SCRadixFindKeyIPV4BestMatch(uint8_t *, SCRadixTree *, void **); - -SCRadixNode *SCRadixFindKeyIPV6ExactMatch(uint8_t *, SCRadixTree *, void **); -SCRadixNode *SCRadixFindKeyIPV6Netblock(uint8_t *, SCRadixTree *, uint8_t, void **); -SCRadixNode *SCRadixFindKeyIPV6BestMatch(uint8_t *, SCRadixTree *, void **); - -void SCRadixPrintTree(SCRadixTree *); -void SCRadixPrintNodeInfo(SCRadixNode *, int, void (*PrintData)(void*)); - -void SCRadixRegisterTests(void); - -#endif /* __UTIL_RADIX_TREE_H__ */ diff --git a/framework/src/suricata/src/util-random.c b/framework/src/suricata/src/util-random.c deleted file mode 100644 index 3cf5e075..00000000 --- a/framework/src/suricata/src/util-random.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - * - * Utility function for seeding rand - */ - -#include "suricata-common.h" -#include "detect.h" -#include "threads.h" -#include "util-debug.h" - -/** - * \brief create a seed number to pass to rand() , rand_r(), and similars - * \retval seed for rand() - */ -unsigned int RandomTimePreseed(void) -{ - /* preseed rand() */ - time_t now = time ( 0 ); - unsigned char *p = (unsigned char *)&now; - unsigned seed = 0; - size_t ind; - - for ( ind = 0; ind < sizeof now; ind++ ) - seed = seed * ( UCHAR_MAX + 2U ) + p[ind]; - - return seed; -} - diff --git a/framework/src/suricata/src/util-random.h b/framework/src/suricata/src/util-random.h deleted file mode 100644 index 9adddd01..00000000 --- a/framework/src/suricata/src/util-random.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon - */ - -#ifndef __UTIL_RANDOM_H__ -#define __UTIL_RANDOM_H__ - -unsigned int RandomTimePreseed(void); - -#endif /* __UTIL_RANDOM_H__ */ - diff --git a/framework/src/suricata/src/util-reference-config.c b/framework/src/suricata/src/util-reference-config.c deleted file mode 100644 index 299897ab..00000000 --- a/framework/src/suricata/src/util-reference-config.c +++ /dev/null @@ -1,808 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "detect.h" -#include "detect-engine.h" -#include "util-hash.h" - -#include "util-reference-config.h" -#include "conf.h" -#include "util-unittest.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-fmemopen.h" - -/* Regex to parse each line from reference.config file. The first substring - * is for the system name and the second for the url */ -/*-----------------------------------------------------------system-------------------url----*/ -#define SC_RCONF_REGEX "^\\s*config\\s+reference\\s*:\\s*([a-zA-Z][a-zA-Z0-9-_]*)\\s+(.+)\\s*$" - -/* Default path for the reference.conf file */ -#define SC_RCONF_DEFAULT_FILE_PATH CONFIG_DIR "/reference.config" - -static pcre *regex = NULL; -static pcre_extra *regex_study = NULL; - -/* the hash functions */ -uint32_t SCRConfReferenceHashFunc(HashTable *ht, void *data, uint16_t datalen); -char SCRConfReferenceHashCompareFunc(void *data1, uint16_t datalen1, - void *data2, uint16_t datalen2); -void SCRConfReferenceHashFree(void *ch); - -/* used to get the reference.config file path */ -static char *SCRConfGetConfFilename(const DetectEngineCtx *de_ctx); - -void SCReferenceConfInit(void) -{ - const char *eb = NULL; - int eo; - int opts = 0; - - regex = pcre_compile(SC_RCONF_REGEX, opts, &eb, &eo, NULL); - if (regex == NULL) { - SCLogDebug("Compile of \"%s\" failed at offset %" PRId32 ": %s", - SC_RCONF_REGEX, eo, eb); - return; - } - - regex_study = pcre_study(regex, 0, &eb); - if (eb != NULL) { - pcre_free(regex); - regex = NULL; - SCLogDebug("pcre study failed: %s", eb); - return; - } - - return; -} - -void SCReferenceConfDeinit(void) -{ - if (regex != NULL) { - pcre_free(regex); - regex = NULL; - } - if (regex_study != NULL) { - pcre_free(regex_study); - regex_study = NULL; - } -} - - -/** - * \brief Inits the context to be used by the Reference Config parsing API. - * - * This function initializes the hash table to be used by the Detection - * Engine Context to hold the data from reference.config file, - * obtains the file descriptor to parse the reference.config file, and - * inits the regex used to parse the lines from reference.config file. - * - * \param de_ctx Pointer to the Detection Engine Context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static FILE *SCRConfInitContextAndLocalResources(DetectEngineCtx *de_ctx, FILE *fd) -{ - char *filename = NULL; - - /* init the hash table to be used by the reference config references */ - de_ctx->reference_conf_ht = HashTableInit(128, SCRConfReferenceHashFunc, - SCRConfReferenceHashCompareFunc, - SCRConfReferenceHashFree); - if (de_ctx->reference_conf_ht == NULL) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "Error initializing the hash " - "table"); - goto error; - } - - /* if it is not NULL, use the file descriptor. The hack so that we can - * avoid using a dummy reference file for testing purposes and - * instead use an input stream against a buffer containing the - * reference strings */ - if (fd == NULL) { - filename = SCRConfGetConfFilename(de_ctx); - if ((fd = fopen(filename, "r")) == NULL) { -#ifdef UNITTESTS - if (RunmodeIsUnittests()) - goto error; // silently fail -#endif - SCLogError(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, - strerror(errno)); - goto error; - } - } - - return fd; - - error: - if (de_ctx->reference_conf_ht != NULL) { - HashTableFree(de_ctx->reference_conf_ht); - de_ctx->reference_conf_ht = NULL; - } - if (fd != NULL) { - fclose(fd); - fd = NULL; - } - - return NULL; -} - - -/** - * \brief Returns the path for the Reference Config file. We check if we - * can retrieve the path from the yaml conf file. If it is not present, - * return the default path for the reference.config file which is - * "./reference.config". - * - * \retval log_filename Pointer to a string containing the path for the - * reference.config file. - */ -static char *SCRConfGetConfFilename(const DetectEngineCtx *de_ctx) -{ - char *path = NULL; - char config_value[256] = ""; - - if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0) { - snprintf(config_value, sizeof(config_value), - "%s.reference-config-file", de_ctx->config_prefix); - - /* try loading prefix setting, fall back to global if that - * fails. */ - if (ConfGet(config_value, &path) != 1) { - if (ConfGet("reference-config-file", &path) != 1) { - return (char *)SC_RCONF_DEFAULT_FILE_PATH; - } - } - } else { - if (ConfGet("reference-config-file", &path) != 1) { - return (char *)SC_RCONF_DEFAULT_FILE_PATH; - } - } - return path; -} - -/** - * \brief Releases local resources used by the Reference Config API. - */ -static void SCRConfDeInitLocalResources(DetectEngineCtx *de_ctx, FILE *fd) -{ - if (fd != NULL) { - fclose(fd); - fd = NULL; - } - - return; -} - -/** - * \brief Releases de_ctx resources related to Reference Config API. - */ -void SCRConfDeInitContext(DetectEngineCtx *de_ctx) -{ - if (de_ctx->reference_conf_ht != NULL) - HashTableFree(de_ctx->reference_conf_ht); - - de_ctx->reference_conf_ht = NULL; - - return; -} - -/** - * \brief Converts a string to lowercase. - * - * \param str Pointer to the string to be converted. - */ -static char *SCRConfStringToLowercase(const char *str) -{ - char *new_str = NULL; - char *temp_str = NULL; - - if ((new_str = SCStrdup(str)) == NULL) { - return NULL; - } - - temp_str = new_str; - while (*temp_str != '\0') { - *temp_str = tolower((unsigned char)*temp_str); - temp_str++; - } - - return new_str; -} - -/** - * \brief Parses a line from the reference config file and adds it to Reference - * Config hash table DetectEngineCtx->reference_conf_ht. - * - * \param rawstr Pointer to the string to be parsed. - * \param de_ctx Pointer to the Detection Engine Context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -static int SCRConfAddReference(char *rawstr, DetectEngineCtx *de_ctx) -{ - char system[64]; - char url[1024]; - - SCRConfReference *ref_new = NULL; - SCRConfReference *ref_lookup = NULL; - -#define MAX_SUBSTRINGS 30 - int ret = 0; - int ov[MAX_SUBSTRINGS]; - - ret = pcre_exec(regex, regex_study, rawstr, strlen(rawstr), 0, 0, ov, 30); - if (ret < 0) { - SCLogError(SC_ERR_REFERENCE_CONFIG, "Invalid Reference Config in " - "reference.config file"); - goto error; - } - - /* retrieve the reference system */ - ret = pcre_copy_substring((char *)rawstr, ov, 30, 1, system, sizeof(system)); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring() failed"); - goto error; - } - - /* retrieve the reference url */ - ret = pcre_copy_substring((char *)rawstr, ov, 30, 2, url, sizeof(url)); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring() failed"); - goto error; - } - - /* Create a new instance of the parsed Reference string */ - ref_new = SCRConfAllocSCRConfReference(system, url); - if (ref_new == NULL) - goto error; - - /* Check if the Reference is present in the HashTable. In case it's present - * ignore it, as it's a duplicate. If not present, add it to the table */ - ref_lookup = HashTableLookup(de_ctx->reference_conf_ht, ref_new, 0); - if (ref_lookup == NULL) { - if (HashTableAdd(de_ctx->reference_conf_ht, ref_new, 0) < 0) { - SCLogDebug("HashTable Add failed"); - } - } else { - SCLogDebug("Duplicate reference found inside reference.config"); - SCRConfDeAllocSCRConfReference(ref_new); - } - - return 0; - - error: - return -1; -} - -/** - * \brief Checks if a string is a comment or a blank line. - * - * Comments lines are lines of the following format - - * "# This is a comment string" or - * " # This is a comment string". - * - * \param line String that has to be checked. - * - * \retval 1 On the argument string being a comment or blank line. - * \retval 0 Otherwise. - */ -static int SCRConfIsLineBlankOrComment(char *line) -{ - while (*line != '\0') { - /* we have a comment */ - if (*line == '#') - return 1; - - /* this line is neither a comment line, nor a blank line */ - if (!isspace((unsigned char)*line)) - return 0; - - line++; - } - - /* we have a blank line */ - return 1; -} - -/** - * \brief Parses the Reference Config file and updates the - * DetectionEngineCtx->reference_conf_ht with the Reference information. - * - * \param de_ctx Pointer to the Detection Engine Context. - */ -static void SCRConfParseFile(DetectEngineCtx *de_ctx, FILE *fd) -{ - char line[1024]; - uint8_t i = 1; - - while (fgets(line, sizeof(line), fd) != NULL) { - if (SCRConfIsLineBlankOrComment(line)) - continue; - - SCRConfAddReference(line, de_ctx); - i++; - } - -#ifdef UNITTESTS - SCLogInfo("Added \"%d\" reference types from the reference.config file", - de_ctx->reference_conf_ht->count); -#endif /* UNITTESTS */ - return; -} - -/** - * \brief Returns a new SCRConfReference instance. The reference string - * is converted into lowercase, before being assigned to the instance. - * - * \param system Pointer to the system. - * \param url Pointer to the reference url. - * - * \retval ref Pointer to the new instance of SCRConfReference. - */ -SCRConfReference *SCRConfAllocSCRConfReference(const char *system, - const char *url) -{ - SCRConfReference *ref = NULL; - - if (system == NULL) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid arguments. system NULL"); - return NULL; - } - - if ((ref = SCMalloc(sizeof(SCRConfReference))) == NULL) { - return NULL; - } - memset(ref, 0, sizeof(SCRConfReference)); - - if ((ref->system = SCRConfStringToLowercase(system)) == NULL) { - SCFree(ref); - return NULL; - } - - if (url != NULL && (ref->url = SCStrdup(url)) == NULL) { - SCFree(ref->system); - SCFree(ref); - return NULL; - } - - return ref; -} - -/** - * \brief Frees a SCRConfReference instance. - * - * \param Pointer to the SCRConfReference instance that has to be freed. - */ -void SCRConfDeAllocSCRConfReference(SCRConfReference *ref) -{ - if (ref != NULL) { - if (ref->system != NULL) - SCFree(ref->system); - - if (ref->url != NULL) - SCFree(ref->url); - - SCFree(ref); - } - - return; -} - -/** - * \brief Hashing function to be used to hash the Reference name. Would be - * supplied as an argument to the HashTableInit function for - * DetectEngineCtx->reference_conf_ht. - * - * \param ht Pointer to the HashTable. - * \param data Pointer to the data to be hashed. In this case, the data - * would be a pointer to a SCRConfReference instance. - * \param datalen Not used by this function. - */ -uint32_t SCRConfReferenceHashFunc(HashTable *ht, void *data, uint16_t datalen) -{ - SCRConfReference *ref = (SCRConfReference *)data; - uint32_t hash = 0; - int i = 0; - - int len = strlen(ref->system); - - for (i = 0; i < len; i++) - hash += tolower((unsigned char)ref->system[i]); - - hash = hash % ht->array_size; - - return hash; -} - -/** - * \brief Used to compare two References that have been stored in the HashTable. - * This function is supplied as an argument to the HashTableInit function - * for DetectionEngineCtx->reference_conf_ct. - * - * \param data1 Pointer to the first SCRConfReference to be compared. - * \param len1 Not used by this function. - * \param data2 Pointer to the second SCRConfReference to be compared. - * \param len2 Not used by this function. - * - * \retval 1 On data1 and data2 being equal. - * \retval 0 On data1 and data2 not being equal. - */ -char SCRConfReferenceHashCompareFunc(void *data1, uint16_t datalen1, - void *data2, uint16_t datalen2) -{ - SCRConfReference *ref1 = (SCRConfReference *)data1; - SCRConfReference *ref2 = (SCRConfReference *)data2; - int len1 = 0; - int len2 = 0; - - if (ref1 == NULL || ref2 == NULL) - return 0; - - if (ref1->system == NULL || ref2->system == NULL) - return 0; - - len1 = strlen(ref1->system); - len2 = strlen(ref2->system); - - if (len1 == len2 && memcmp(ref1->system, ref2->system, len1) == 0) { - SCLogDebug("Match found inside Reference-Config hash function"); - return 1; - } - - return 0; -} - -/** - * \brief Used to free the Reference Config Hash Data that was stored in - * DetectEngineCtx->reference_conf_ht Hashtable. - * - * \param data Pointer to the data that has to be freed. - */ -void SCRConfReferenceHashFree(void *data) -{ - SCRConfDeAllocSCRConfReference(data); - - return; -} - -/** - * \brief Loads the Reference info from the reference.config file. - * - * The reference.config file contains references that can be used in - * Signatures. Each line of the file should have the following format - - * config reference: system_name, reference_url. - * - * \param de_ctx Pointer to the Detection Engine Context that should be updated - * with reference information. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCRConfLoadReferenceConfigFile(DetectEngineCtx *de_ctx, FILE *fd) -{ - fd = SCRConfInitContextAndLocalResources(de_ctx, fd); - if (fd == NULL) { -#ifdef UNITTESTS - if (RunmodeIsUnittests() && fd == NULL) { - return -1; - } -#endif - SCLogError(SC_ERR_OPENING_FILE, "please check the \"reference-config-file\" " - "option in your suricata.yaml file"); - return -1; - } - - SCRConfParseFile(de_ctx, fd); - SCRConfDeInitLocalResources(de_ctx, fd); - - return 0; -} - -/** - * \brief Gets the refernce config from the corresponding hash table stored - * in the Detection Engine Context's reference conf ht, given the - * reference name. - * - * \param ct_name Pointer to the reference name that has to be looked up. - * \param de_ctx Pointer to the Detection Engine Context. - * - * \retval lookup_rconf_info Pointer to the SCRConfReference instance from - * the hash table on success; NULL on failure. - */ -SCRConfReference *SCRConfGetReference(const char *rconf_name, - DetectEngineCtx *de_ctx) -{ - SCRConfReference *ref_conf = SCRConfAllocSCRConfReference(rconf_name, NULL); - if (ref_conf == NULL) - return NULL; - SCRConfReference *lookup_ref_conf = HashTableLookup(de_ctx->reference_conf_ht, - ref_conf, 0); - - SCRConfDeAllocSCRConfReference(ref_conf); - return lookup_ref_conf; -} - -/*----------------------------------Unittests---------------------------------*/ - - -#ifdef UNITTESTS - -/** - * \brief Creates a dummy reference config, with all valid references, for - * testing purposes. - */ -FILE *SCRConfGenerateValidDummyReferenceConfigFD01(void) -{ - const char *buffer = - "config reference: one http://www.one.com\n" - "config reference: two http://www.two.com\n" - "config reference: three http://www.three.com\n" - "config reference: one http://www.one.com\n" - "config reference: three http://www.three.com\n"; - - FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Reference Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy reference config, with some valid references and a - * couple of invalid references, for testing purposes. - */ -FILE *SCRConfGenerateInValidDummyReferenceConfigFD02(void) -{ - const char *buffer = - "config reference: one http://www.one.com\n" - "config_ reference: two http://www.two.com\n" - "config reference_: three http://www.three.com\n" - "config reference: four\n" - "config reference five http://www.five.com\n"; - - FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Reference Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy reference config, with all invalid references, for - * testing purposes. - */ -FILE *SCRConfGenerateInValidDummyReferenceConfigFD03(void) -{ - const char *buffer = - "config reference one http://www.one.com\n" - "config_ reference: two http://www.two.com\n" - "config reference_: three http://www.three.com\n" - "config reference: four\n"; - - FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Reference Config test code"); - - return fd; -} - -/** - * \test Check that the reference file is loaded and the detection engine - * content reference_conf_ht loaded with the reference data. - */ -int SCRConfTest01(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 0; - - if (de_ctx == NULL) - return result; - - FILE *fd = SCRConfGenerateValidDummyReferenceConfigFD01(); - SCRConfLoadReferenceConfigFile(de_ctx, fd); - - if (de_ctx->reference_conf_ht == NULL) - goto end; - - result = (de_ctx->reference_conf_ht->count == 3); - if (result == 0) - printf("FAILED: de_ctx->reference_conf_ht->count %u: ", de_ctx->reference_conf_ht->count); - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check that invalid references present in the reference.config file - * aren't loaded. - */ -int SCRConfTest02(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 0; - - if (de_ctx == NULL) - return result; - - FILE *fd = SCRConfGenerateInValidDummyReferenceConfigFD03(); - SCRConfLoadReferenceConfigFile(de_ctx, fd); - - if (de_ctx->reference_conf_ht == NULL) - goto end; - - result = (de_ctx->reference_conf_ht->count == 0); - - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check that only valid references are loaded into the hash table from - * the reference.config file. - */ -int SCRConfTest03(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 0; - - if (de_ctx == NULL) - return result; - - FILE *fd = SCRConfGenerateInValidDummyReferenceConfigFD02(); - SCRConfLoadReferenceConfigFile(de_ctx, fd); - - if (de_ctx->reference_conf_ht == NULL) - goto end; - - result = (de_ctx->reference_conf_ht->count == 1); - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the reference info from the reference.config file have - * been loaded into the hash table. - */ -int SCRConfTest04(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 1; - - if (de_ctx == NULL) - return 0; - - FILE *fd = SCRConfGenerateValidDummyReferenceConfigFD01(); - SCRConfLoadReferenceConfigFile(de_ctx, fd); - - if (de_ctx->reference_conf_ht == NULL) - goto end; - - result = (de_ctx->reference_conf_ht->count == 3); - - result &= (SCRConfGetReference("one", de_ctx) != NULL); - result &= (SCRConfGetReference("two", de_ctx) != NULL); - result &= (SCRConfGetReference("three", de_ctx) != NULL); - result &= (SCRConfGetReference("four", de_ctx) == NULL); - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the reference info from the invalid reference.config file - * have not been loaded into the hash table, and cross verify to check - * that the hash table contains no reference data. - */ -int SCRConfTest05(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 1; - - if (de_ctx == NULL) - return 0; - - FILE *fd = SCRConfGenerateInValidDummyReferenceConfigFD03(); - SCRConfLoadReferenceConfigFile(de_ctx, fd); - - if (de_ctx->reference_conf_ht == NULL) - goto end; - - result = (de_ctx->reference_conf_ht->count == 0); - - result &= (SCRConfGetReference("one", de_ctx) == NULL); - result &= (SCRConfGetReference("two", de_ctx) == NULL); - result &= (SCRConfGetReference("three", de_ctx) == NULL); - result &= (SCRConfGetReference("four", de_ctx) == NULL); - result &= (SCRConfGetReference("five", de_ctx) == NULL); - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the reference info from the reference.config file have - * been loaded into the hash table. - */ -int SCRConfTest06(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - int result = 1; - - if (de_ctx == NULL) - return 0; - - FILE *fd = SCRConfGenerateInValidDummyReferenceConfigFD02(); - SCRConfLoadReferenceConfigFile(de_ctx, fd); - - if (de_ctx->reference_conf_ht == NULL) - goto end; - - result = (de_ctx->reference_conf_ht->count == 1); - - result &= (SCRConfGetReference("one", de_ctx) != NULL); - result &= (SCRConfGetReference("two", de_ctx) == NULL); - result &= (SCRConfGetReference("three", de_ctx) == NULL); - result &= (SCRConfGetReference("four", de_ctx) == NULL); - result &= (SCRConfGetReference("five", de_ctx) == NULL); - - end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief This function registers unit tests for Reference Config API. - */ -void SCRConfRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("SCRConfTest01", SCRConfTest01, 1); - UtRegisterTest("SCRConfTest02", SCRConfTest02, 1); - UtRegisterTest("SCRConfTest03", SCRConfTest03, 1); - UtRegisterTest("SCRConfTest04", SCRConfTest04, 1); - UtRegisterTest("SCRConfTest05", SCRConfTest05, 1); - UtRegisterTest("SCRConfTest06", SCRConfTest06, 1); -#endif /* UNITTESTS */ - - return; -} diff --git a/framework/src/suricata/src/util-reference-config.h b/framework/src/suricata/src/util-reference-config.h deleted file mode 100644 index f7fe4cc1..00000000 --- a/framework/src/suricata/src/util-reference-config.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_REFERENCE_CONFIG_H__ -#define __UTIL_REFERENCE_CONFIG_H__ - -/** - * \brief Holds a reference from the file - reference.config. - */ -typedef struct SCRConfReference_ { - /* The system name. This is the primary key for a reference. */ - char *system; - /* The url for the above reference */ - char *url; -} SCRConfReference; - -SCRConfReference *SCRConfAllocSCRConfReference(const char *, const char *); -void SCRConfDeAllocSCRConfReference(SCRConfReference *); -int SCRConfLoadReferenceConfigFile(DetectEngineCtx *, FILE *); -void SCRConfDeInitContext(DetectEngineCtx *); -SCRConfReference *SCRConfGetReference(const char *, - DetectEngineCtx *); -void SCRConfRegisterTests(void); - -/* these below functions are only used by unittests */ -FILE *SCRConfGenerateValidDummyReferenceConfigFD01(void); -FILE *SCRConfGenerateInValidDummyReferenceConfigFD02(void); -FILE *SCRConfGenerateInValidDummyReferenceConfigFD03(void); - -void SCReferenceConfInit(void); -void SCReferenceConfDeinit(void); - -#endif /* __UTIL_REFERENCE_CONFIG_H__ */ diff --git a/framework/src/suricata/src/util-ringbuffer.c b/framework/src/suricata/src/util-ringbuffer.c deleted file mode 100644 index 4566bf9f..00000000 --- a/framework/src/suricata/src/util-ringbuffer.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Ringbuffer implementation that is lockless for the most part IF atomic - * operations are available. - * - * Two sizes are implemented currently: 256 and 65536. Those sizes are chosen - * for simplicity when working with the read and write indexes. Both can just - * wrap around. - * - * Implemented are: - * Single reader, single writer (lockless) - * Single reader, multi writer (partly locked) - * Multi reader, single writer (lockless) - * Multi reader, multi writer (partly locked) - */ -#include "suricata-common.h" -#include "suricata.h" -#include "util-ringbuffer.h" -#include "util-atomic.h" -#include "util-unittest.h" - -#define USLEEP_TIME 5 - -/** \brief wait function for condition where ringbuffer is either - * full or empty. - * - * \param rb ringbuffer - * - * Based on RINGBUFFER_MUTEX_WAIT define, we either sleep and spin - * or use thread condition to wait. - */ -static inline void RingBuffer8DoWait(RingBuffer8 *rb) -{ -#ifdef RINGBUFFER_MUTEX_WAIT - SCMutexLock(&rb->wait_mutex); - SCCondWait(&rb->wait_cond, &rb->wait_mutex); - SCMutexUnlock(&rb->wait_mutex); -#else - usleep(USLEEP_TIME); -#endif -} - -/** \brief wait function for condition where ringbuffer is either - * full or empty. - * - * \param rb ringbuffer - * - * Based on RINGBUFFER_MUTEX_WAIT define, we either sleep and spin - * or use thread condition to wait. - */ -static inline void RingBufferDoWait(RingBuffer16 *rb) -{ -#ifdef RINGBUFFER_MUTEX_WAIT - SCMutexLock(&rb->wait_mutex); - SCCondWait(&rb->wait_cond, &rb->wait_mutex); - SCMutexUnlock(&rb->wait_mutex); -#else - usleep(USLEEP_TIME); -#endif -} - -/** \brief wait function for condition where ringbuffer is either - * full or empty. - * - * \param rb ringbuffer - * - * Based on RINGBUFFER_MUTEX_WAIT define, we either sleep and spin - * or use thread condition to wait. - */ -void RingBufferWait(RingBuffer16 *rb) -{ - RingBufferDoWait(rb); -} - -/** \brief tell the ringbuffer to shut down - * - * \param rb ringbuffer - */ -void RingBuffer8Shutdown(RingBuffer8 *rb) -{ - rb->shutdown = 1; -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif -} - -/** \brief check the ringbuffer is empty (no data in it) - * - * \param rb ringbuffer - * - * \retval 1 empty - * \retval 0 not empty - */ -int RingBuffer8IsEmpty(RingBuffer8 *rb) -{ - if (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - return 1; - } - - return 0; -} - -/** \brief check the ringbuffer is full (no more data will fit) - * - * \param rb ringbuffer - * - * \retval 1 empty - * \retval 0 not empty - */ -int RingBuffer8IsFull(RingBuffer8 *rb) -{ - if ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - return 1; - } - - return 0; -} - -/** \brief tell the ringbuffer to shut down - * - * \param rb ringbuffer - */ -void RingBufferShutdown(RingBuffer16 *rb) -{ - rb->shutdown = 1; -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif -} - -/** \brief get number of items in the ringbuffer */ -uint16_t RingBufferSize(RingBuffer16 *rb) -{ - SCEnter(); - uint16_t size = (uint16_t)(SC_ATOMIC_GET(rb->write) - SC_ATOMIC_GET(rb->read)); - SCReturnUInt(size); -} - -/** \brief check the ringbuffer is empty (no data in it) - * - * \param rb ringbuffer - * - * \retval 1 empty - * \retval 0 not empty - */ -int RingBufferIsEmpty(RingBuffer16 *rb) -{ - if (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - return 1; - } - - return 0; -} - -/** \brief check the ringbuffer is full (no more data will fit) - * - * \param rb ringbuffer - * - * \retval 1 empty - * \retval 0 not empty - */ -int RingBufferIsFull(RingBuffer16 *rb) -{ - if ((unsigned short)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - return 1; - } - - return 0; -} - -/* Single Reader, Single Writer, 8 bits */ - -void *RingBufferSrSw8Get(RingBuffer8 *rb) -{ - void *ptr = NULL; - - /* buffer is empty, wait... */ - while (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return NULL; - - RingBuffer8DoWait(rb); - } - - ptr = rb->array[SC_ATOMIC_GET(rb->read)]; - (void) SC_ATOMIC_ADD(rb->read, 1); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return ptr; -} - -int RingBufferSrSw8Put(RingBuffer8 *rb, void *ptr) -{ - /* buffer is full, wait... */ - while ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return -1; - - RingBuffer8DoWait(rb); - } - - rb->array[SC_ATOMIC_GET(rb->write)] = ptr; - (void) SC_ATOMIC_ADD(rb->write, 1); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return 0; -} - -/* Single Reader, Multi Writer, 8 bites */ - -void *RingBufferSrMw8Get(RingBuffer8 *rb) -{ - void *ptr = NULL; - - /* buffer is empty, wait... */ - while (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return NULL; - - RingBuffer8DoWait(rb); - } - - ptr = rb->array[SC_ATOMIC_GET(rb->read)]; - (void) SC_ATOMIC_ADD(rb->read, 1); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return ptr; -} - -/** - * \brief put a ptr in the RingBuffer. - * - * As we support multiple writers we need to protect 2 things: - * 1. writing the ptr to the array - * 2. incrementing the rb->write idx - * - * We can't do both at the same time in one atomic operation, so - * we need to (spin) lock it. We do increment rb->write atomically - * after that, so that we don't need to use the lock in our *Get - * function. - * - * \param rb the ringbuffer - * \param ptr ptr to store - * - * \retval 0 ok - * \retval -1 wait loop interrupted because of engine flags - */ -int RingBufferSrMw8Put(RingBuffer8 *rb, void *ptr) -{ - SCLogDebug("ptr %p", ptr); - - /* buffer is full, wait... */ -retry: - while ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return -1; - - RingBuffer8DoWait(rb); - } - - /* get our lock */ - SCSpinLock(&rb->spin); - /* if while we got our lock the buffer changed, we need to retry */ - if ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - SCSpinUnlock(&rb->spin); - goto retry; - } - - SCLogDebug("rb->write %u, ptr %p", SC_ATOMIC_GET(rb->write), ptr); - - /* update the ring buffer */ - rb->array[SC_ATOMIC_GET(rb->write)] = ptr; - (void) SC_ATOMIC_ADD(rb->write, 1); - SCSpinUnlock(&rb->spin); - SCLogDebug("ptr %p, done", ptr); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return 0; -} - -/* Multi Reader, Single Writer, 8 bits */ - -/** - * \brief get the next ptr from the ring buffer - * - * Because we allow for multiple readers we take great care in making sure - * that the threads don't interfere with one another. - * - */ -void *RingBufferMrSw8Get(RingBuffer8 *rb) -{ - void *ptr; - /** local pointer for data races. If SCAtomicCompareAndSwap (CAS) - * fails we increase our local array idx to try the next array member - * until we succeed. Or when the buffer is empty again we jump back - * to the waiting loop. */ - unsigned char readp; - - /* buffer is empty, wait... */ -retry: - while (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return NULL; - - RingBuffer8DoWait(rb); - } - - /* atomically update rb->read */ - readp = SC_ATOMIC_GET(rb->read) - 1; - do { - /* with multiple readers we can get in the situation that we exitted - * from the wait loop but the rb is empty again once we get here. */ - if (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) - goto retry; - - readp++; - ptr = rb->array[readp]; - } while (!(SC_ATOMIC_CAS(&rb->read, readp, (readp + 1)))); - - SCLogDebug("ptr %p", ptr); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return ptr; -} - -/** - * \brief put a ptr in the RingBuffer - */ -int RingBufferMrSw8Put(RingBuffer8 *rb, void *ptr) -{ - SCLogDebug("ptr %p", ptr); - - /* buffer is full, wait... */ - while ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return -1; - - RingBuffer8DoWait(rb); - } - - rb->array[SC_ATOMIC_GET(rb->write)] = ptr; - (void) SC_ATOMIC_ADD(rb->write, 1); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return 0; -} - - -/* Multi Reader, Single Writer */ - -/** - * \brief get the next ptr from the ring buffer - * - * Because we allow for multiple readers we take great care in making sure - * that the threads don't interfere with one another. - * - */ -void *RingBufferMrSwGet(RingBuffer16 *rb) -{ - void *ptr; - /** local pointer for data races. If SCAtomicCompareAndSwap (CAS) - * fails we increase our local array idx to try the next array member - * until we succeed. Or when the buffer is empty again we jump back - * to the waiting loop. */ - unsigned short readp; - - /* buffer is empty, wait... */ -retry: - while (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return NULL; - - RingBufferDoWait(rb); - } - - /* atomically update rb->read */ - readp = SC_ATOMIC_GET(rb->read) - 1; - do { - /* with multiple readers we can get in the situation that we exitted - * from the wait loop but the rb is empty again once we get here. */ - if (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) - goto retry; - - readp++; - ptr = rb->array[readp]; - } while (!(SC_ATOMIC_CAS(&rb->read, readp, (readp + 1)))); - - SCLogDebug("ptr %p", ptr); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return ptr; -} - -/** - * \brief put a ptr in the RingBuffer - */ -int RingBufferMrSwPut(RingBuffer16 *rb, void *ptr) -{ - SCLogDebug("ptr %p", ptr); - - /* buffer is full, wait... */ - while ((unsigned short)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return -1; - - RingBufferDoWait(rb); - } - - rb->array[SC_ATOMIC_GET(rb->write)] = ptr; - (void) SC_ATOMIC_ADD(rb->write, 1); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return 0; -} - - -/* Single Reader, Single Writer */ - -void *RingBufferSrSwGet(RingBuffer16 *rb) -{ - void *ptr = NULL; - - /* buffer is empty, wait... */ - while (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return NULL; - - RingBufferDoWait(rb); - } - - ptr = rb->array[SC_ATOMIC_GET(rb->read)]; - (void) SC_ATOMIC_ADD(rb->read, 1); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return ptr; -} - -int RingBufferSrSwPut(RingBuffer16 *rb, void *ptr) -{ - /* buffer is full, wait... */ - while ((unsigned short)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return -1; - - RingBufferDoWait(rb); - } - - rb->array[SC_ATOMIC_GET(rb->write)] = ptr; - (void) SC_ATOMIC_ADD(rb->write, 1); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return 0; -} - -/* Multi Reader, Multi Writer, 8 bits */ - -RingBuffer8 *RingBuffer8Init(void) -{ - RingBuffer8 *rb = SCMalloc(sizeof(RingBuffer8)); - if (unlikely(rb == NULL)) { - return NULL; - } - - memset(rb, 0x00, sizeof(RingBuffer8)); - - SC_ATOMIC_INIT(rb->write); - SC_ATOMIC_INIT(rb->read); - - SCSpinInit(&rb->spin, 0); -#ifdef RINGBUFFER_MUTEX_WAIT - SCMutexInit(&rb->wait_mutex, NULL); - SCCondInit(&rb->wait_cond, NULL); -#endif - return rb; -} - -void RingBuffer8Destroy(RingBuffer8 *rb) -{ - if (rb != NULL) { - SC_ATOMIC_DESTROY(rb->write); - SC_ATOMIC_DESTROY(rb->read); - - SCSpinDestroy(&rb->spin); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCMutexDestroy(&rb->wait_mutex); - SCCondDestroy(&rb->wait_cond); -#endif - SCFree(rb); - } -} - -/** - * \brief get the next ptr from the ring buffer - * - * Because we allow for multiple readers we take great care in making sure - * that the threads don't interfere with one another. - * - */ -void *RingBufferMrMw8Get(RingBuffer8 *rb) -{ - void *ptr; - /** local pointer for data races. If SCAtomicCompareAndSwap (CAS) - * fails we increase our local array idx to try the next array member - * until we succeed. Or when the buffer is empty again we jump back - * to the waiting loop. */ - unsigned char readp; - - /* buffer is empty, wait... */ -retry: - while (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return NULL; - - RingBuffer8DoWait(rb); - } - - /* atomically update rb->read */ - readp = SC_ATOMIC_GET(rb->read) - 1; - do { - /* with multiple readers we can get in the situation that we exitted - * from the wait loop but the rb is empty again once we get here. */ - if (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) - goto retry; - - readp++; - ptr = rb->array[readp]; - } while (!(SC_ATOMIC_CAS(&rb->read, readp, (readp + 1)))); - - SCLogDebug("ptr %p", ptr); -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return ptr; -} - -/** - * \brief put a ptr in the RingBuffer. - * - * As we support multiple writers we need to protect 2 things: - * 1. writing the ptr to the array - * 2. incrementing the rb->write idx - * - * We can't do both at the same time in one atomic operation, so - * we need to (spin) lock it. We do increment rb->write atomically - * after that, so that we don't need to use the lock in our *Get - * function. - * - * \param rb the ringbuffer - * \param ptr ptr to store - * - * \retval 0 ok - * \retval -1 wait loop interrupted because of engine flags - */ -int RingBufferMrMw8Put(RingBuffer8 *rb, void *ptr) -{ - SCLogDebug("ptr %p", ptr); - - /* buffer is full, wait... */ -retry: - while ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return -1; - - RingBuffer8DoWait(rb); - } - - /* get our lock */ - SCSpinLock(&rb->spin); - /* if while we got our lock the buffer changed, we need to retry */ - if ((unsigned char)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - SCSpinUnlock(&rb->spin); - goto retry; - } - - SCLogDebug("rb->write %u, ptr %p", SC_ATOMIC_GET(rb->write), ptr); - - /* update the ring buffer */ - rb->array[SC_ATOMIC_GET(rb->write)] = ptr; - (void) SC_ATOMIC_ADD(rb->write, 1); - SCSpinUnlock(&rb->spin); - SCLogDebug("ptr %p, done", ptr); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return 0; -} - -/* Multi Reader, Multi Writer, 16 bits */ - -RingBuffer16 *RingBufferInit(void) -{ - RingBuffer16 *rb = SCMalloc(sizeof(RingBuffer16)); - if (unlikely(rb == NULL)) { - return NULL; - } - - memset(rb, 0x00, sizeof(RingBuffer16)); - - SC_ATOMIC_INIT(rb->write); - SC_ATOMIC_INIT(rb->read); - - SCSpinInit(&rb->spin, 0); -#ifdef RINGBUFFER_MUTEX_WAIT - SCMutexInit(&rb->wait_mutex, NULL); - SCCondInit(&rb->wait_cond, NULL); -#endif - return rb; -} - -void RingBufferDestroy(RingBuffer16 *rb) -{ - if (rb != NULL) { - SC_ATOMIC_DESTROY(rb->write); - SC_ATOMIC_DESTROY(rb->read); - - SCSpinDestroy(&rb->spin); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCMutexDestroy(&rb->wait_mutex); - SCCondDestroy(&rb->wait_cond); -#endif - - SCFree(rb); - } -} - -/** - * \brief get the next ptr from the ring buffer - * - * Because we allow for multiple readers we take great care in making sure - * that the threads don't interfere with one another. - * - */ -void *RingBufferMrMwGet(RingBuffer16 *rb) -{ - void *ptr; - /** local pointer for data races. If SCAtomicCompareAndSwap (CAS) - * fails we increase our local array idx to try the next array member - * until we succeed. Or when the buffer is empty again we jump back - * to the waiting loop. */ - unsigned short readp; - - /* buffer is empty, wait... */ -retry: - while (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return NULL; - - RingBufferDoWait(rb); - } - - /* atomically update rb->read */ - readp = SC_ATOMIC_GET(rb->read) - 1; - do { - /* with multiple readers we can get in the situation that we exitted - * from the wait loop but the rb is empty again once we get here. */ - if (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) - goto retry; - - readp++; - ptr = rb->array[readp]; - } while (!(SC_ATOMIC_CAS(&rb->read, readp, (readp + 1)))); - - SCLogDebug("ptr %p", ptr); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return ptr; -} - -/** - * \brief get the next ptr from the ring buffer - * - * Because we allow for multiple readers we take great care in making sure - * that the threads don't interfere with one another. - * - * This version does NOT enter a wait if the buffer is empty loop. - * - * \retval ptr pointer to the data, or NULL if buffer is empty - */ -void *RingBufferMrMwGetNoWait(RingBuffer16 *rb) -{ - void *ptr; - /** local pointer for data races. If SCAtomicCompareAndSwap (CAS) - * fails we increase our local array idx to try the next array member - * until we succeed. Or when the buffer is empty again we jump back - * to the waiting loop. */ - unsigned short readp; - - /* buffer is empty, wait... */ -retry: - while (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) { - /* break if buffer is empty */ - return NULL; - } - - /* atomically update rb->read */ - readp = SC_ATOMIC_GET(rb->read) - 1; - do { - /* with multiple readers we can get in the situation that we exitted - * from the wait loop but the rb is empty again once we get here. */ - if (SC_ATOMIC_GET(rb->write) == SC_ATOMIC_GET(rb->read)) - goto retry; - - readp++; - ptr = rb->array[readp]; - } while (!(SC_ATOMIC_CAS(&rb->read, readp, (readp + 1)))); - - SCLogDebug("ptr %p", ptr); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return ptr; -} - -/** - * \brief put a ptr in the RingBuffer. - * - * As we support multiple writers we need to protect 2 things: - * 1. writing the ptr to the array - * 2. incrementing the rb->write idx - * - * We can't do both at the same time in one atomic operation, so - * we need to (spin) lock it. We do increment rb->write atomically - * after that, so that we don't need to use the lock in our *Get - * function. - * - * \param rb the ringbuffer - * \param ptr ptr to store - * - * \retval 0 ok - * \retval -1 wait loop interrupted because of engine flags - */ -int RingBufferMrMwPut(RingBuffer16 *rb, void *ptr) -{ - SCLogDebug("ptr %p", ptr); - - /* buffer is full, wait... */ -retry: - while ((unsigned short)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - /* break out if the engine wants to shutdown */ - if (rb->shutdown != 0) - return -1; - - RingBufferDoWait(rb); - } - - /* get our lock */ - SCSpinLock(&rb->spin); - /* if while we got our lock the buffer changed, we need to retry */ - if ((unsigned short)(SC_ATOMIC_GET(rb->write) + 1) == SC_ATOMIC_GET(rb->read)) { - SCSpinUnlock(&rb->spin); - goto retry; - } - - SCLogDebug("rb->write %u, ptr %p", SC_ATOMIC_GET(rb->write), ptr); - - /* update the ring buffer */ - rb->array[SC_ATOMIC_GET(rb->write)] = ptr; - (void) SC_ATOMIC_ADD(rb->write, 1); - SCSpinUnlock(&rb->spin); - SCLogDebug("ptr %p, done", ptr); - -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondSignal(&rb->wait_cond); -#endif - return 0; -} - -#ifdef UNITTESTS -static int RingBuffer8SrSwInit01 (void) -{ - int result = 0; - - RingBuffer8 *rb = NULL; - - rb = RingBuffer8Init(); - if (rb == NULL) { - printf("rb == NULL: "); - goto end; - } - - int r = SCSpinLock(&rb->spin); - if (r != 0) { - printf("r = %d, expected %d: ", r, 0); - goto end; - } - SCSpinUnlock(&rb->spin); - - if (SC_ATOMIC_GET(rb->read) != 0) { - printf("read %u, expected 0: ", SC_ATOMIC_GET(rb->read)); - goto end; - } - - if (SC_ATOMIC_GET(rb->write) != 0) { - printf("write %u, expected 0: ", SC_ATOMIC_GET(rb->write)); - goto end; - } - - result = 1; -end: - if (rb != NULL) { - RingBuffer8Destroy(rb); - } - return result; -} - -static int RingBuffer8SrSwPut01 (void) -{ - int result = 0; - - RingBuffer8 *rb = NULL; - - rb = RingBuffer8Init(); - if (rb == NULL) { - printf("rb == NULL: "); - goto end; - } - - if (SC_ATOMIC_GET(rb->read) != 0) { - printf("read %u, expected 0: ", SC_ATOMIC_GET(rb->read)); - goto end; - } - - if (SC_ATOMIC_GET(rb->write) != 0) { - printf("write %u, expected 0: ", SC_ATOMIC_GET(rb->write)); - goto end; - } - - void *ptr = &result; - - RingBufferSrSw8Put(rb, ptr); - - if (SC_ATOMIC_GET(rb->read) != 0) { - printf("read %u, expected 0: ", SC_ATOMIC_GET(rb->read)); - goto end; - } - - if (SC_ATOMIC_GET(rb->write) != 1) { - printf("write %u, expected 1: ", SC_ATOMIC_GET(rb->write)); - goto end; - } - - if (rb->array[0] != ptr) { - printf("ptr is %p, expected %p: ", rb->array[0], ptr); - goto end; - } - - result = 1; -end: - if (rb != NULL) { - RingBuffer8Destroy(rb); - } - return result; -} - -static int RingBuffer8SrSwPut02 (void) -{ - int result = 0; - RingBuffer8 *rb = NULL; - - int array[255]; - int cnt = 0; - for (cnt = 0; cnt < 255; cnt++) { - array[cnt] = cnt; - } - - rb = RingBuffer8Init(); - if (rb == NULL) { - printf("rb == NULL: "); - goto end; - } - - for (cnt = 0; cnt < 255; cnt++) { - RingBufferSrSw8Put(rb, (void *)&array[cnt]); - - if (SC_ATOMIC_GET(rb->read) != 0) { - printf("read %u, expected 0: ", SC_ATOMIC_GET(rb->read)); - goto end; - } - - if (SC_ATOMIC_GET(rb->write) != (unsigned char)(cnt+1)) { - printf("write %u, expected %u: ", SC_ATOMIC_GET(rb->write), (unsigned char)(cnt+1)); - goto end; - } - - if (rb->array[cnt] != (void *)&array[cnt]) { - printf("ptr is %p, expected %p: ", rb->array[cnt], (void *)&array[cnt]); - goto end; - } - } - - if (!(RingBuffer8IsFull(rb))) { - printf("ringbuffer should be full, isn't: "); - goto end; - } - - result = 1; -end: - if (rb != NULL) { - RingBuffer8Destroy(rb); - } - return result; -} - -static int RingBuffer8SrSwGet01 (void) -{ - int result = 0; - - RingBuffer8 *rb = NULL; - - rb = RingBuffer8Init(); - if (rb == NULL) { - printf("rb == NULL: "); - goto end; - } - - void *ptr = &result; - - RingBufferSrSw8Put(rb, ptr); - void *ptr2 = RingBufferSrSw8Get(rb); - - if (ptr != ptr2) { - printf("ptr %p != ptr2 %p: ", ptr, ptr2); - goto end; - } - - if (SC_ATOMIC_GET(rb->read) != 1) { - printf("read %u, expected 1: ", SC_ATOMIC_GET(rb->read)); - goto end; - } - - if (SC_ATOMIC_GET(rb->write) != 1) { - printf("write %u, expected 1: ", SC_ATOMIC_GET(rb->write)); - goto end; - } - - result = 1; -end: - if (rb != NULL) { - RingBuffer8Destroy(rb); - } - return result; -} - -static int RingBuffer8SrSwGet02 (void) -{ - int result = 0; - RingBuffer8 *rb = NULL; - - int array[255]; - int cnt = 0; - for (cnt = 0; cnt < 255; cnt++) { - array[cnt] = cnt; - } - - rb = RingBuffer8Init(); - if (rb == NULL) { - printf("rb == NULL: "); - goto end; - } - - for (cnt = 0; cnt < 255; cnt++) { - RingBufferSrSw8Put(rb, (void *)&array[cnt]); - - if (SC_ATOMIC_GET(rb->read) != 0) { - printf("read %u, expected 0: ", SC_ATOMIC_GET(rb->read)); - goto end; - } - - if (SC_ATOMIC_GET(rb->write) != (unsigned char)(cnt+1)) { - printf("write %u, expected %u: ", SC_ATOMIC_GET(rb->write), (unsigned char)(cnt+1)); - goto end; - } - - if (rb->array[cnt] != (void *)&array[cnt]) { - printf("ptr is %p, expected %p: ", rb->array[cnt], (void *)&array[cnt]); - goto end; - } - } - - if (!(RingBuffer8IsFull(rb))) { - printf("ringbuffer should be full, isn't: "); - goto end; - } - - for (cnt = 0; cnt < 255; cnt++) { - void *ptr = RingBufferSrSw8Get(rb); - - if (SC_ATOMIC_GET(rb->read) != (unsigned char)(cnt+1)) { - printf("read %u, expected %u: ", SC_ATOMIC_GET(rb->read), (unsigned char)(cnt+1)); - goto end; - } - - if (SC_ATOMIC_GET(rb->write) != 255) { - printf("write %u, expected %u: ", SC_ATOMIC_GET(rb->write), 255); - goto end; - } - - if (ptr != (void *)&array[cnt]) { - printf("ptr is %p, expected %p: ", ptr, (void *)&array[cnt]); - goto end; - } - } - - if (!(RingBuffer8IsEmpty(rb))) { - printf("ringbuffer should be empty, isn't: "); - goto end; - } - - result = 1; -end: - if (rb != NULL) { - RingBuffer8Destroy(rb); - } - return result; -} - -#endif /* UNITTESTS */ - -void DetectRingBufferRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("RingBuffer8SrSwInit01", RingBuffer8SrSwInit01, 1); - UtRegisterTest("RingBuffer8SrSwPut01", RingBuffer8SrSwPut01, 1); - UtRegisterTest("RingBuffer8SrSwPut02", RingBuffer8SrSwPut02, 1); - UtRegisterTest("RingBuffer8SrSwGet01", RingBuffer8SrSwGet01, 1); - UtRegisterTest("RingBuffer8SrSwGet02", RingBuffer8SrSwGet02, 1); -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/util-ringbuffer.h b/framework/src/suricata/src/util-ringbuffer.h deleted file mode 100644 index c9272330..00000000 --- a/framework/src/suricata/src/util-ringbuffer.h +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * See the .c file for a full explanation. - */ - -#ifndef __UTIL_RINGBUFFER_H__ - -#include "util-atomic.h" -#include "threads.h" - -/** When the ringbuffer is full we have two options, either we spin & sleep - * or we use a pthread condition to wait. - * - * \warning this approach isn't working due to a race condition between the - * time it takes for a thread to enter the condwait and the - * signalling. I've obverved the following case: T1 sees that the - * ringbuffer is empty, so it decides to start the wait condition. - * While it is acquiring the lock and entering the wait, T0 puts a - * number of items in the buffer. For each of these it signals T1. - * However, as that thread isn't in the "wait" mode yet, the signals - * are lost. T0 now is done as well and enters it's own wait - * condition. T1 completes it's "wait" initialization. It waits for - * signals, but T0 won't be able to send them as it's waiting itself. - */ -//#define RINGBUFFER_MUTEX_WAIT - -/** \brief ring buffer api - * - * Ring buffer api for a single writer and a single reader. It uses a - * read and write pointer. Only the read ptr needs atomic updating. - */ - -#define RING_BUFFER_8_SIZE 256 -typedef struct RingBuffer8_ { - SC_ATOMIC_DECLARE(unsigned char, write); /**< idx where we put data */ - SC_ATOMIC_DECLARE(unsigned char, read); /**< idx where we read data */ - uint8_t shutdown; -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondT wait_cond; - SCMutex wait_mutex; -#endif /* RINGBUFFER_MUTEX_WAIT */ - SCSpinlock spin; /**< lock protecting writes for multi writer mode*/ - void *array[RING_BUFFER_8_SIZE]; -} RingBuffer8; - -#define RING_BUFFER_16_SIZE 65536 -typedef struct RingBuffer16_ { - SC_ATOMIC_DECLARE(unsigned short, write); /**< idx where we put data */ - SC_ATOMIC_DECLARE(unsigned short, read); /**< idx where we read data */ - uint8_t shutdown; -#ifdef RINGBUFFER_MUTEX_WAIT - SCCondT wait_cond; - SCMutex wait_mutex; -#endif /* RINGBUFFER_MUTEX_WAIT */ - SCSpinlock spin; /**< lock protecting writes for multi writer mode*/ - void *array[RING_BUFFER_16_SIZE]; -} RingBuffer16; - -RingBuffer8 *RingBuffer8Init(void); -void RingBuffer8Destroy(RingBuffer8 *); -RingBuffer16 *RingBufferInit(void); -void RingBufferDestroy(RingBuffer16 *); - -int RingBufferIsEmpty(RingBuffer16 *); -int RingBufferIsFull(RingBuffer16 *); -uint16_t RingBufferSize(RingBuffer16 *); - -void RingBuffer8Shutdown(RingBuffer8 *); -void RingBufferShutdown(RingBuffer16 *); - -void RingBufferWait(RingBuffer16 *rb); - -/** Single Reader, Single Writer ring buffer, fixed at - * 256 items so we can use unsigned char's that just - * wrap around */ -void *RingBufferSrSw8Get(RingBuffer8 *); -int RingBufferSrSw8Put(RingBuffer8 *, void *); - -/** Multiple Reader, Single Writer ring buffer, fixed at - * 256 items so we can use unsigned char's that just - * wrap around */ -void *RingBufferMrSw8Get(RingBuffer8 *); -int RingBufferMrSw8Put(RingBuffer8 *, void *); - -/** Multiple Reader, Single Writer ring buffer, fixed at - * 65536 items so we can use unsigned shorts that just - * wrap around */ -void *RingBufferMrSwGet(RingBuffer16 *); -int RingBufferMrSwPut(RingBuffer16 *, void *); - -/** Single Reader, Single Writer ring buffer, fixed at - * 65536 items so we can use unsigned shorts that just - * wrap around */ -void *RingBufferSrSwGet(RingBuffer16 *); -int RingBufferSrSwPut(RingBuffer16 *, void *); - -/** Multiple Reader, Multi Writer ring buffer, fixed at - * 256 items so we can use unsigned char's that just - * wrap around */ -void *RingBufferMrMw8Get(RingBuffer8 *); -int RingBufferMrMw8Put(RingBuffer8 *, void *); - -/** Multiple Reader, Multi Writer ring buffer, fixed at - * 65536 items so we can use unsigned char's that just - * wrap around */ -void *RingBufferMrMwGet(RingBuffer16 *); -void *RingBufferMrMwGetNoWait(RingBuffer16 *); -int RingBufferMrMwPut(RingBuffer16 *, void *); - -void *RingBufferSrMw8Get(RingBuffer8 *); -int RingBufferSrMw8Put(RingBuffer8 *, void *); - -void DetectRingBufferRegisterTests(void); - -#endif /* __UTIL_RINGBUFFER_H__ */ - diff --git a/framework/src/suricata/src/util-rohash.c b/framework/src/suricata/src/util-rohash.c deleted file mode 100644 index a8e842b7..00000000 --- a/framework/src/suricata/src/util-rohash.c +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Chained read only hash table implementation, meaning that - * after the initial fill no changes are allowed. - * - * Loading takes 2 stages. - * - stage1 maps data - * - stage2 fills blob - * - * \todo a bloomfilter in the ROHashTableOffsets could possibly prevent - * a lot of cache misses when validating a potential match - * - * \todo maybe add a user ctx to be returned instead, something like a - * 4/8 byte ptr or simply a flag - */ - -#include "suricata-common.h" -#include "util-hash.h" -#include "util-unittest.h" -#include "util-memcmp.h" -#include "util-hash-lookup3.h" -#include "queue.h" -#include "util-rohash.h" - -/** item_size data beyond this header */ -typedef struct ROHashTableItem_ { - uint32_t pos; /**< position relative to other values with same hash */ - TAILQ_ENTRY(ROHashTableItem_) next; -} ROHashTableItem; - -/** offset table */ -typedef struct ROHashTableOffsets_ { - uint32_t cnt; /**< number of items for this hash */ - uint32_t offset; /**< position in the blob of the first item */ -} ROHashTableOffsets; - -/** \brief initialize a new rohash - * - * \param hash_bits hash size as 2^hash_bits, so power of 2, max 31 - * \param item_size size of the data to store - * - * \retval table ptr or NULL on error - */ -ROHashTable *ROHashInit(uint8_t hash_bits, uint16_t item_size) -{ - if (item_size % 4 != 0 || item_size == 0) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "data size must be multiple of 4"); - return NULL; - } - if (hash_bits < 4 || hash_bits > 31) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "invalid hash_bits setting, valid range is 4-31"); - return NULL; - } - - uint32_t size = hashsize(hash_bits) * sizeof(ROHashTableOffsets); - - ROHashTable *table = SCMalloc(sizeof(ROHashTable) + size); - if (unlikely(table == NULL)) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "failed to alloc memory"); - return NULL; - } - memset(table, 0, sizeof(ROHashTable) + size); - - table->items = 0; - table->item_size = item_size; - table->hash_bits = hash_bits; - TAILQ_INIT(&table->head); - - return table; -} - -void ROHashFree(ROHashTable *table) -{ - if (table != NULL) { - if (table->data != NULL) { - SCFree(table->data); - } - - SCFree(table); - } -} - -uint32_t ROHashMemorySize(ROHashTable *table) -{ - return (uint32_t)(hashsize(table->hash_bits) * sizeof(ROHashTableOffsets) + - table->items * table->item_size + sizeof(ROHashTable)); -} - -/** - * \retval NULL not found - * \retval ptr found - */ -void *ROHashLookup(ROHashTable *table, void *data, uint16_t size) -{ - if (data == NULL || size != table->item_size) { - SCReturnPtr(NULL, "void"); - } - - uint32_t hash = hashword(data, table->item_size/4, 0) & hashmask(table->hash_bits); - - /* get offsets start */ - ROHashTableOffsets *os = (void *)table + sizeof(ROHashTable); - ROHashTableOffsets *o = &os[hash]; - - /* no matches */ - if (o->cnt == 0) { - SCReturnPtr(NULL, "void"); - } - - uint32_t u; - for (u = 0; u < o->cnt; u++) { - uint32_t offset = (o->offset + u) * table->item_size; - - if (SCMemcmp(table->data + offset, data, table->item_size) == 0) { - SCReturnPtr(table->data + offset, "void"); - } - } - SCReturnPtr(NULL, "void"); -} - -/** \brief Add a new value to the hash - * - * \note can only be done when table isn't in a locked state yet - * - * \param table the hash table - * \param value value to add - * \param size value size. *MUST* match table item_size - * - * \retval 0 error - * \retval 1 ok - */ -int ROHashInitQueueValue(ROHashTable *table, void *value, uint16_t size) -{ - if (table->locked) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "can't add value to locked table"); - return 0; - } - if (table->item_size != size) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "wrong size for data %u != %u", size, table->item_size); - return 0; - } - - ROHashTableItem *item = SCMalloc(sizeof(ROHashTableItem) + table->item_size); - if (item != NULL) { - memset(item, 0x00, sizeof(ROHashTableItem)); - memcpy((void *)item + sizeof(ROHashTableItem), value, table->item_size); - TAILQ_INSERT_TAIL(&table->head, item, next); - return 1; - } - - return 0; -} - -/** \brief create final hash data structure - * - * \param table the hash table - * - * \retval 0 error - * \retval 1 ok - * - * \note after this call the nothing can be added to the hash anymore. - */ -int ROHashInitFinalize(ROHashTable *table) -{ - if (table->locked) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "table already locked"); - return 0; - } - - ROHashTableItem *item = NULL; - ROHashTableOffsets *os = (void *)table + sizeof(ROHashTable); - - /* count items per hash value */ - TAILQ_FOREACH(item, &table->head, next) { - uint32_t hash = hashword((void *)item + sizeof(*item), table->item_size/4, 0) & hashmask(table->hash_bits); - ROHashTableOffsets *o = &os[hash]; - - item->pos = o->cnt; - o->cnt++; - table->items++; - } - - if (table->items == 0) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "no items"); - return 0; - } - - /* get the data block */ - uint32_t newsize = table->items * table->item_size; - table->data = SCMalloc(newsize); - if (table->data == NULL) { - SCLogError(SC_ERR_HASH_TABLE_INIT, "failed to alloc memory"); - return 0; - } - memset(table->data, 0x00, newsize); - - /* calc offsets into the block per hash value */ - uint32_t total = 0; - uint32_t x; - for (x = 0; x < hashsize(table->hash_bits); x++) { - ROHashTableOffsets *o = &os[x]; - - if (o->cnt == 0) - continue; - - o->offset = total; - total += o->cnt; - } - - /* copy each value into the data block */ - TAILQ_FOREACH(item, &table->head, next) { - uint32_t hash = hashword((void *)item + sizeof(*item), table->item_size/4, 0) & hashmask(table->hash_bits); - - ROHashTableOffsets *o = &os[hash]; - uint32_t offset = (o->offset + item->pos) * table->item_size; - - memcpy(table->data + offset, (void *)item + sizeof(*item), table->item_size); - - } - - /* clean up temp items */ - while ((item = TAILQ_FIRST(&table->head))) { - TAILQ_REMOVE(&table->head, item, next); - SCFree(item); - } - - table->locked = 1; - return 1; -} diff --git a/framework/src/suricata/src/util-rohash.h b/framework/src/suricata/src/util-rohash.h deleted file mode 100644 index 720eace5..00000000 --- a/framework/src/suricata/src/util-rohash.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_ROHASH_H__ -#define __UTIL_ROHASH_H__ - -#include "queue.h" - -typedef struct ROHashTable_ { - uint8_t locked; - uint8_t hash_bits; - uint16_t item_size; - uint32_t items; - void *data; - TAILQ_HEAD(, ROHashTableItem_) head; -} ROHashTable; - -/* init time */ -ROHashTable *ROHashInit(uint8_t hash_bits, uint16_t item_size); -int ROHashInitFinalize(ROHashTable *table); -void ROHashFree(ROHashTable *table); -int ROHashInitQueueValue(ROHashTable *table, void *value, uint16_t size); -uint32_t ROHashMemorySize(ROHashTable *table); - -/* run time */ -void *ROHashLookup(ROHashTable *table, void *data, uint16_t size); - -#endif /* __UTIL_ROHASH_H__ */ diff --git a/framework/src/suricata/src/util-rule-vars.c b/framework/src/suricata/src/util-rule-vars.c deleted file mode 100644 index 57347f4f..00000000 --- a/framework/src/suricata/src/util-rule-vars.c +++ /dev/null @@ -1,532 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * Rule variable utility functions - */ - -#include "suricata-common.h" -#include "conf.h" -#include "conf-yaml-loader.h" - -#include "detect.h" -#include "detect-content.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "util-rule-vars.h" -#include "util-enum.h" -#include "util-debug.h" -#include "util-unittest.h" - -/** An enum-string map, that maps the different vars type in the yaml conf - * type with the mapping path in the yaml conf file */ -SCEnumCharMap sc_rule_vars_type_map[ ] = { - { "vars.address-groups", SC_RULE_VARS_ADDRESS_GROUPS }, - { "vars.port-groups", SC_RULE_VARS_PORT_GROUPS } -}; - -/** - * \internal - * \brief Retrieves a value for a yaml mapping. The sequence from the yaml - * conf file, from which the conf value has to be retrieved can be - * specified by supplying a SCRuleVarsType enum. The string mapping - * for each of the SCRuleVarsType is present in sc_rule_vars_type_map. - * - * \param conf_var_name Pointer to a character string containing the conf var - * name, whose value has to be retrieved from the yaml - * conf file. - * \param conf_vars_type Holds an enum value that indicates the kind of yaml - * mapping that has to be retrieved. Can be one of the - * values in SCRuleVarsType. - * - * \retval conf_var_name_value Pointer to the string containing the conf value - * on success; NULL on failure. - */ -char *SCRuleVarsGetConfVar(const DetectEngineCtx *de_ctx, - const char *conf_var_name, - SCRuleVarsType conf_vars_type) -{ - SCEnter(); - - const char *conf_var_type_name = NULL; - char conf_var_full_name[2048] = ""; - char *conf_var_full_name_value = NULL; - - if (conf_var_name == NULL) - goto end; - - while (conf_var_name[0] != '\0' && isspace((unsigned char)conf_var_name[0])) { - conf_var_name++; - } - - (conf_var_name[0] == '$') ? conf_var_name++ : conf_var_name; - conf_var_type_name = SCMapEnumValueToName(conf_vars_type, - sc_rule_vars_type_map); - if (conf_var_type_name == NULL) - goto end; - - if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0) { - if (snprintf(conf_var_full_name, sizeof(conf_var_full_name), "%s.%s.%s", - de_ctx->config_prefix, conf_var_type_name, conf_var_name) < 0) { - goto end; - } - } else { - if (snprintf(conf_var_full_name, sizeof(conf_var_full_name), "%s.%s", - conf_var_type_name, conf_var_name) < 0) { - goto end; - } - } - - if (ConfGet(conf_var_full_name, &conf_var_full_name_value) != 1) { - SCLogError(SC_ERR_UNDEFINED_VAR, "Variable \"%s\" is not defined in " - "configuration file", conf_var_name); - goto end; - } - - SCLogDebug("Value obtained from the yaml conf file, for the var " - "\"%s\" is \"%s\"", conf_var_name, conf_var_full_name_value); - - end: - SCReturnCharPtr(conf_var_full_name_value); -} - - -/**********************************Unittests***********************************/ -#ifdef UNITTESTS - -static const char *dummy_conf_string = - "%YAML 1.1\n" - "---\n" - "\n" - "default-log-dir: /var/log/suricata\n" - "\n" - "logging:\n" - "\n" - " default-log-level: debug\n" - "\n" - " default-format: \"<%t> - <%l>\"\n" - "\n" - " default-startup-message: Your IDS has started.\n" - "\n" - " default-output-filter:\n" - "\n" - " output:\n" - "\n" - " - interface: console\n" - " log-level: info\n" - "\n" - " - interface: file\n" - " filename: /var/log/suricata.log\n" - "\n" - " - interface: syslog\n" - " facility: local5\n" - " format: \"%l\"\n" - "\n" - "pfring:\n" - "\n" - " interface: eth0\n" - "\n" - " clusterid: 99\n" - "\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"[192.168.0.0/16,10.8.0.0/16,127.0.0.1,2001:888:" - "13c5:5AFE::/64,2001:888:13c5:CAFE::/64]\"\n" - "\n" - " EXTERNAL_NET: \"[!192.168.0.0/16,2000::/3]\"\n" - "\n" - " HTTP_SERVERS: \"!192.168.0.0/16\"\n" - "\n" - " SMTP_SERVERS: \"!192.168.0.0/16\"\n" - "\n" - " SQL_SERVERS: \"!192.168.0.0/16\"\n" - "\n" - " DNS_SERVERS: any\n" - "\n" - " TELNET_SERVERS: any\n" - "\n" - " AIM_SERVERS: any\n" - "\n" - " port-groups:\n" - "\n" - " HTTP_PORTS: \"80:81,88\"\n" - "\n" - " SHELLCODE_PORTS: 80\n" - "\n" - " ORACLE_PORTS: 1521\n" - "\n" - " SSH_PORTS: 22\n" - "\n"; - -/** - * \test Check that valid address and port group vars are correctly retrieved - * from the configuration. - */ -int SCRuleVarsPositiveTest01(void) -{ - int result = 1; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - /* check for address-groups */ - result &= (SCRuleVarsGetConfVar(NULL,"$HOME_NET", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$HOME_NET", SC_RULE_VARS_ADDRESS_GROUPS), - "[192.168.0.0/16,10.8.0.0/16,127.0.0.1,2001:888:13c5:" - "5AFE::/64,2001:888:13c5:CAFE::/64]") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$EXTERNAL_NET", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$EXTERNAL_NET", SC_RULE_VARS_ADDRESS_GROUPS), - "[!192.168.0.0/16,2000::/3]") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$HTTP_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$HTTP_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS), - "!192.168.0.0/16") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$SMTP_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$SMTP_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS), - "!192.168.0.0/16") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$SQL_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$SQL_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS), - "!192.168.0.0/16") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$DNS_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$DNS_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS), - "any") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$TELNET_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$TELNET_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS), - "any") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$AIM_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$AIM_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS), - "any") == 0); - - /* Test that a leading space is stripped. */ - result &= (SCRuleVarsGetConfVar(NULL," $AIM_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL," $AIM_SERVERS", SC_RULE_VARS_ADDRESS_GROUPS), - "any") == 0); - - /* check for port-groups */ - result &= (SCRuleVarsGetConfVar(NULL,"$HTTP_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$HTTP_PORTS", SC_RULE_VARS_PORT_GROUPS), - "80:81,88") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$SHELLCODE_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$SHELLCODE_PORTS", SC_RULE_VARS_PORT_GROUPS), - "80") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$ORACLE_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$ORACLE_PORTS", SC_RULE_VARS_PORT_GROUPS), - "1521") == 0); - result &= (SCRuleVarsGetConfVar(NULL,"$SSH_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$SSH_PORTS", SC_RULE_VARS_PORT_GROUPS), - "22") == 0); - - ConfDeInit(); - ConfRestoreContextBackup(); - - return result; -} - -/** - * \test Check that invalid address and port groups are properly handled by the - * API. - */ -int SCRuleVarsNegativeTest02(void) -{ - int result = 1; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - result &= (SCRuleVarsGetConfVar(NULL,"$HOME_NETW", SC_RULE_VARS_ADDRESS_GROUPS) == NULL); - result &= (SCRuleVarsGetConfVar(NULL,"$home_net", SC_RULE_VARS_ADDRESS_GROUPS) == NULL); - - result &= (SCRuleVarsGetConfVar(NULL,"$TOMCAT_PORTSW", SC_RULE_VARS_PORT_GROUPS) == NULL); - result &= (SCRuleVarsGetConfVar(NULL,"$tomcat_ports", SC_RULE_VARS_PORT_GROUPS) == NULL); - - ConfDeInit(); - ConfRestoreContextBackup(); - - return result; -} - -/** - * \test Check that Signatures with valid address and port groups are parsed - * without any errors by the Signature parsing API. - */ -int SCRuleVarsPositiveTest03(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineCtx *de_ctx = NULL; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - de_ctx->flags |= DE_QUIET; -/* - s = SigInit(de_ctx, "alert tcp $HTTP_SERVERS any -> any any (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp $SMTP_SERVERS any -> $HTTP_SERVERS any (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp $AIM_SERVERS any -> $AIM_SERVERS any (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp $TELNET_SERVERS any -> any $SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp $TELNET_SERVERS any -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp $TELNET_SERVERS 80 -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp $TELNET_SERVERS !80 -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp !$HTTP_SERVERS !80 -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp 192.168.1.2 any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp !192.168.1.2 any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp !192.168.1.2 any -> any !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp !192.168.1.2 any -> !$HTTP_SERVERS !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp !192.168.1.2 $HTTP_PORTS -> !$HTTP_SERVERS !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp [!192.168.24.0/23,!167.12.0.0/24] any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp ![192.168.24.0/23,!167.12.0.0/24] any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp [$HOME_NET,!192.168.1.2] $HTTP_PORTS -> !$HTTP_SERVERS !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp [[192.168.1.3,$EXTERNAL_NET],192.168.2.5] $HTTP_PORTS -> !$HTTP_SERVERS !$HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp [[192.168.1.3,$EXTERNAL_NET],192.168.2.5] $HTTP_PORTS -> !$HTTP_SERVERS [80,[!$HTTP_PORTS,$ORACLE_PORTS]] (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); -*/ - s = SigInit(de_ctx, "alert tcp [$HTTP_SERVERS,$HOME_NET,192.168.2.5] $HTTP_PORTS -> $EXTERNAL_NET [80,[!$HTTP_PORTS,$ORACLE_PORTS]] (msg:\"Rule Vars Test\"; sid:1;)"); - if (s == NULL) - goto end; - SigFree(s); - - result = 1; - -end: - ConfDeInit(); - ConfRestoreContextBackup(); - - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check that Signatures with invalid address and port groups, are - * are invalidated by the Singature parsing API. - */ -int SCRuleVarsNegativeTest04(void) -{ - int result = 0; - Signature *s = NULL; - DetectEngineCtx *de_ctx = NULL; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_conf_string, strlen(dummy_conf_string)); - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - de_ctx->flags |= DE_QUIET; - - s = SigInit(de_ctx, "alert tcp $HTTP_SERVER any -> any any (msg:\"Rule Vars Test\"; sid:1;)"); - if (s != NULL) - goto end; - - s = SigInit(de_ctx, "alert tcp $http_servers any -> any any (msg:\"Rule Vars Test\"; sid:1;)"); - if (s != NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp $http_servers any -> any $HTTP_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s != NULL) - goto end; - SigFree(s); - - s = SigInit(de_ctx, "alert tcp !$TELNET_SERVERS !80 -> any !$SSH_PORTS (msg:\"Rule Vars Test\"; sid:1;)"); - if (s != NULL) - goto end; - SigFree(s); - - result = 1; - -end: - ConfDeInit(); - ConfRestoreContextBackup(); - - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -static const char *dummy_mt_conf_string = - "%YAML 1.1\n" - "---\n" - "vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"[1.2.3.4]\"\n" - " port-groups:\n" - " HTTP_PORTS: \"12345\"\n" - "multi-detect:\n" - " 0:\n" - " vars:\n" - "\n" - " address-groups:\n" - "\n" - " HOME_NET: \"[8.8.8.8]\"\n" - " port-groups:\n" - " HTTP_PORTS: \"54321\"\n" - "\n"; - -/** - * \test Check that valid address and port group vars are correctly retrieved - * from the configuration. - */ -int SCRuleVarsMTest01(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = NULL; - - ConfCreateContextBackup(); - ConfInit(); - ConfYamlLoadString(dummy_mt_conf_string, strlen(dummy_mt_conf_string)); - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - return 0; - de_ctx->flags |= DE_QUIET; - snprintf(de_ctx->config_prefix, sizeof(de_ctx->config_prefix), - "multi-detect.0"); - - /* check for address-groups */ - result = (SCRuleVarsGetConfVar(de_ctx,"$HOME_NET", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(de_ctx,"$HOME_NET", SC_RULE_VARS_ADDRESS_GROUPS), - "[8.8.8.8]") == 0); - if (result == 0) - goto end; - - result = (SCRuleVarsGetConfVar(NULL,"$HOME_NET", SC_RULE_VARS_ADDRESS_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$HOME_NET", SC_RULE_VARS_ADDRESS_GROUPS), - "[1.2.3.4]") == 0); - if (result == 0) - goto end; - - /* check for port-groups */ - result = (SCRuleVarsGetConfVar(de_ctx,"$HTTP_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(de_ctx,"$HTTP_PORTS", SC_RULE_VARS_PORT_GROUPS), - "54321") == 0); - if (result == 0) - goto end; - - result = (SCRuleVarsGetConfVar(NULL,"$HTTP_PORTS", SC_RULE_VARS_PORT_GROUPS) != NULL && - strcmp(SCRuleVarsGetConfVar(NULL,"$HTTP_PORTS", SC_RULE_VARS_PORT_GROUPS), - "12345") == 0); - if (result == 0) - goto end; - -end: - ConfDeInit(); - ConfRestoreContextBackup(); - - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* UNITTESTS */ - -void SCRuleVarsRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SCRuleVarsPositiveTest01", SCRuleVarsPositiveTest01, 1); - UtRegisterTest("SCRuleVarsNegativeTest02", SCRuleVarsNegativeTest02, 1); - UtRegisterTest("SCRuleVarsPositiveTest03", SCRuleVarsPositiveTest03, 1); - UtRegisterTest("SCRuleVarsNegativeTest04", SCRuleVarsNegativeTest04, 1); - - UtRegisterTest("SCRuleVarsMTest01", SCRuleVarsMTest01, 1); -#endif - - return; -} diff --git a/framework/src/suricata/src/util-rule-vars.h b/framework/src/suricata/src/util-rule-vars.h deleted file mode 100644 index 57d161e9..00000000 --- a/framework/src/suricata/src/util-rule-vars.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_RULE_VARS_H__ -#define __UTIL_RULE_VARS_H__ - -/** Enum indicating the various vars type in the yaml conf file */ -typedef enum { - SC_RULE_VARS_ADDRESS_GROUPS, - SC_RULE_VARS_PORT_GROUPS, -} SCRuleVarsType; - -char *SCRuleVarsGetConfVar(const DetectEngineCtx *, const char *, SCRuleVarsType); -void SCRuleVarsRegisterTests(void); - -#endif /* __UTIL_RULE_VARS_H__ */ diff --git a/framework/src/suricata/src/util-runmodes.c b/framework/src/suricata/src/util-runmodes.c deleted file mode 100644 index a327a512..00000000 --- a/framework/src/suricata/src/util-runmodes.c +++ /dev/null @@ -1,751 +0,0 @@ -/* Copyright (C) 2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Eric Leblond - * - * Helper function for runmode. - * - */ - -#include "suricata-common.h" -#include "config.h" -#include "tm-threads.h" -#include "conf.h" -#include "runmodes.h" -#include "runmode-af-packet.h" -#include "log-httplog.h" -#include "output.h" - -#include "detect-engine.h" -#include "detect-engine-mpm.h" - -#include "alert-fastlog.h" -#include "alert-prelude.h" -#include "alert-unified2-alert.h" -#include "alert-debuglog.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-cpu.h" -#include "util-affinity.h" -#include "util-device.h" - -#include "util-runmodes.h" - -#include "flow-hash.h" - -/** set to true if flow engine and stream engine run in different - * threads. */ -static int runmode_flow_stream_async = 0; - -void RunmodeSetFlowStreamAsync(void) -{ - runmode_flow_stream_async = 1; - FlowDisableTcpReuseHandling(); -} - -int RunmodeGetFlowStreamAsync(void) -{ - return runmode_flow_stream_async; -} - -/** \brief create a queue string for autofp to pass to - * the flow queue handler. - * - * The string will be "pickup1,pickup2,pickup3\0" - */ -char *RunmodeAutoFpCreatePickupQueuesString(int n) -{ - char *queues = NULL; - /* 13 because pickup12345, = 12 + \0 */ - size_t queues_size = n * 13; - int thread; - char qname[TM_QUEUE_NAME_MAX]; - - queues = SCMalloc(queues_size); - if (unlikely(queues == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "failed to alloc queues buffer: %s", strerror(errno)); - return NULL; - } - memset(queues, 0x00, queues_size); - - for (thread = 0; thread < n; thread++) { - if (strlen(queues) > 0) - strlcat(queues, ",", queues_size); - - snprintf(qname, sizeof(qname), "pickup%d", thread+1); - strlcat(queues, qname, queues_size); - } - - SCLogDebug("%d %"PRIuMAX", queues %s", n, (uintmax_t)queues_size, queues); - return queues; -} - -/** - */ -int RunModeSetLiveCaptureAutoFp(ConfigIfaceParserFunc ConfigParser, - ConfigIfaceThreadsCountFunc ModThreadsCount, - char *recv_mod_name, - char *decode_mod_name, char *thread_name, - const char *live_dev) -{ - char tname[TM_THREAD_NAME_MAX]; - char qname[TM_QUEUE_NAME_MAX]; - char *queues = NULL; - int thread = 0; - /* Available cpus */ - uint16_t ncpus = UtilCpuGetNumProcessorsOnline(); - int nlive = LiveGetDeviceCount(); - int thread_max = TmThreadGetNbThreads(DETECT_CPU_SET); - /* always create at least one thread */ - if (thread_max == 0) - thread_max = ncpus * threading_detect_ratio; - if (thread_max < 1) - thread_max = 1; - - RunmodeSetFlowStreamAsync(); - - queues = RunmodeAutoFpCreatePickupQueuesString(thread_max); - if (queues == NULL) { - SCLogError(SC_ERR_RUNMODE, "RunmodeAutoFpCreatePickupQueuesString failed"); - exit(EXIT_FAILURE); - } - - if ((nlive <= 1) && (live_dev != NULL)) { - void *aconf; - int threads_count; - - SCLogDebug("live_dev %s", live_dev); - - aconf = ConfigParser(live_dev); - if (aconf == NULL) { - SCLogError(SC_ERR_RUNMODE, "Failed to allocate config for %s (%d)", - live_dev, thread); - exit(EXIT_FAILURE); - } - - threads_count = ModThreadsCount(aconf); - SCLogInfo("Going to use %" PRId32 " %s receive thread(s)", - threads_count, recv_mod_name); - - /* create the threads */ - for (thread = 0; thread < threads_count; thread++) { - snprintf(tname, sizeof(tname), "%s%d", thread_name, thread+1); - char *thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't allocate thread name"); - exit(EXIT_FAILURE); - } - ThreadVars *tv_receive = - TmThreadCreatePacketHandler(thread_name, - "packetpool", "packetpool", - queues, "flow", "pktacqloop"); - if (tv_receive == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - TmModule *tm_module = TmModuleGetByName(recv_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, - "TmModuleGetByName failed for %s", - recv_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_receive, tm_module, aconf); - - tm_module = TmModuleGetByName(decode_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, - "TmModuleGetByName %s failed", decode_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_receive, tm_module, NULL); - - TmThreadSetCPU(tv_receive, RECEIVE_CPU_SET); - - if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - } - } else { /* Multiple input device */ - SCLogInfo("Using %d live device(s).", nlive); - int lthread; - - for (lthread = 0; lthread < nlive; lthread++) { - char *live_dev = LiveGetDeviceName(lthread); - void *aconf; - int threads_count; - - if (live_dev == NULL) { - SCLogError(SC_ERR_RUNMODE, "Failed to lookup live dev %d", lthread); - exit(EXIT_FAILURE); - } - SCLogDebug("live_dev %s", live_dev); - - aconf = ConfigParser(live_dev); - if (aconf == NULL) { - SCLogError(SC_ERR_RUNMODE, "Multidev: Failed to allocate config for %s (%d)", - live_dev, lthread); - exit(EXIT_FAILURE); - } - - threads_count = ModThreadsCount(aconf); - for (thread = 0; thread < threads_count; thread++) { - snprintf(tname, sizeof(tname), "%s%s%d", thread_name, - live_dev, thread+1); - char *thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't allocate thread name"); - exit(EXIT_FAILURE); - } - ThreadVars *tv_receive = - TmThreadCreatePacketHandler(thread_name, - "packetpool", "packetpool", - queues, "flow", "pktacqloop"); - if (tv_receive == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - TmModule *tm_module = TmModuleGetByName(recv_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for %s", recv_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_receive, tm_module, aconf); - - tm_module = TmModuleGetByName(decode_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName %s failed", decode_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_receive, tm_module, NULL); - - TmThreadSetCPU(tv_receive, RECEIVE_CPU_SET); - - if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - } - } - } - - for (thread = 0; thread < thread_max; thread++) { - snprintf(tname, sizeof(tname), "Detect%d", thread+1); - snprintf(qname, sizeof(qname), "pickup%d", thread+1); - - SCLogDebug("tname %s, qname %s", tname, qname); - - char *thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't allocate thread name"); - exit(EXIT_FAILURE); - } - ThreadVars *tv_detect_ncpu = - TmThreadCreatePacketHandler(thread_name, - qname, "flow", - "packetpool", "packetpool", - "varslot"); - if (tv_detect_ncpu == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - TmModule *tm_module = TmModuleGetByName("StreamTcp"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL); - - if (DetectEngineEnabled()) { - tm_module = TmModuleGetByName("Detect"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL); - } - - TmThreadSetCPU(tv_detect_ncpu, DETECT_CPU_SET); - - char *thread_group_name = SCStrdup("Detect"); - if (unlikely(thread_group_name == NULL)) { - SCLogError(SC_ERR_RUNMODE, "Error allocating memory"); - exit(EXIT_FAILURE); - } - tv_detect_ncpu->thread_group_name = thread_group_name; - - tm_module = TmModuleGetByName("RespondReject"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName RespondReject failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL); - - /* add outputs as well */ - SetupOutputs(tv_detect_ncpu); - - if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - } - - SCFree(queues); - return 0; -} - -/** - */ -static int RunModeSetLiveCaptureWorkersForDevice(ConfigIfaceThreadsCountFunc ModThreadsCount, - char *recv_mod_name, - char *decode_mod_name, char *thread_name, - const char *live_dev, void *aconf, - unsigned char single_mode) -{ - int thread; - int threads_count; - - if (single_mode) { - threads_count = 1; - } else { - threads_count = ModThreadsCount(aconf); - SCLogInfo("Going to use %" PRId32 " thread(s)", threads_count); - } - - /* create the threads */ - for (thread = 0; thread < threads_count; thread++) { - char tname[TM_THREAD_NAME_MAX]; - char *n_thread_name = NULL; - ThreadVars *tv = NULL; - TmModule *tm_module = NULL; - - if (single_mode) { - snprintf(tname, sizeof(tname), "%s", thread_name); - } else { - snprintf(tname, sizeof(tname), "%s%s%d", - thread_name, live_dev, thread+1); - } - n_thread_name = SCStrdup(tname); - if (unlikely(n_thread_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't allocate thread name"); - exit(EXIT_FAILURE); - } - tv = TmThreadCreatePacketHandler(n_thread_name, - "packetpool", "packetpool", - "packetpool", "packetpool", - "pktacqloop"); - if (tv == NULL) { - SCLogError(SC_ERR_THREAD_CREATE, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - - tm_module = TmModuleGetByName(recv_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName failed for %s", recv_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, aconf); - - tm_module = TmModuleGetByName(decode_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName %s failed", decode_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - tm_module = TmModuleGetByName("StreamTcp"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - if (DetectEngineEnabled()) { - tm_module = TmModuleGetByName("Detect"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - } - - tm_module = TmModuleGetByName("RespondReject"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName RespondReject failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - SetupOutputs(tv); - - TmThreadSetCPU(tv, DETECT_CPU_SET); - - if (TmThreadSpawn(tv) != TM_ECODE_OK) { - SCLogError(SC_ERR_THREAD_SPAWN, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - } - - return 0; -} - -int RunModeSetLiveCaptureWorkers(ConfigIfaceParserFunc ConfigParser, - ConfigIfaceThreadsCountFunc ModThreadsCount, - char *recv_mod_name, - char *decode_mod_name, char *thread_name, - const char *live_dev) -{ - int nlive = LiveGetDeviceCount(); - void *aconf; - int ldev; - - for (ldev = 0; ldev < nlive; ldev++) { - char *live_dev_c = NULL; - if ((nlive <= 1) && (live_dev != NULL)) { - aconf = ConfigParser(live_dev); - live_dev_c = SCStrdup(live_dev); - if (unlikely(live_dev_c == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't allocate interface name"); - exit(EXIT_FAILURE); - } - } else { - live_dev_c = LiveGetDeviceName(ldev); - aconf = ConfigParser(live_dev_c); - } - RunModeSetLiveCaptureWorkersForDevice(ModThreadsCount, - recv_mod_name, - decode_mod_name, - thread_name, - live_dev_c, - aconf, - 0); - } - - return 0; -} - -int RunModeSetLiveCaptureSingle(ConfigIfaceParserFunc ConfigParser, - ConfigIfaceThreadsCountFunc ModThreadsCount, - char *recv_mod_name, - char *decode_mod_name, char *thread_name, - const char *live_dev) -{ - int nlive = LiveGetDeviceCount(); - void *aconf; - - if (nlive > 1) { - SCLogError(SC_ERR_RUNMODE, - "Can't use single runmode with multiple device"); - exit(EXIT_FAILURE); - } - - if (live_dev != NULL) { - aconf = ConfigParser(live_dev); - } else { - char *live_dev_c = LiveGetDeviceName(0); - aconf = ConfigParser(live_dev_c); - /* \todo Set threads number in config to 1 */ - } - - return RunModeSetLiveCaptureWorkersForDevice( - ModThreadsCount, - recv_mod_name, - decode_mod_name, - thread_name, - live_dev, - aconf, - 1); -} - - -/** - */ -int RunModeSetIPSAutoFp(ConfigIPSParserFunc ConfigParser, - char *recv_mod_name, - char *verdict_mod_name, - char *decode_mod_name) -{ - SCEnter(); - char tname[TM_THREAD_NAME_MAX]; - char qname[TM_QUEUE_NAME_MAX]; - TmModule *tm_module ; - char *cur_queue = NULL; - char *queues = NULL; - int thread; - - /* Available cpus */ - uint16_t ncpus = UtilCpuGetNumProcessorsOnline(); - int nqueue = LiveGetDeviceCount(); - - int thread_max = TmThreadGetNbThreads(DETECT_CPU_SET); - /* always create at least one thread */ - if (thread_max == 0) - thread_max = ncpus * threading_detect_ratio; - if (thread_max < 1) - thread_max = 1; - - RunmodeSetFlowStreamAsync(); - - queues = RunmodeAutoFpCreatePickupQueuesString(thread_max); - if (queues == NULL) { - SCLogError(SC_ERR_RUNMODE, "RunmodeAutoFpCreatePickupQueuesString failed"); - exit(EXIT_FAILURE); - } - - for (int i = 0; i < nqueue; i++) { - /* create the threads */ - cur_queue = LiveGetDeviceName(i); - if (cur_queue == NULL) { - SCLogError(SC_ERR_RUNMODE, "invalid queue number"); - exit(EXIT_FAILURE); - } - memset(tname, 0, sizeof(tname)); - snprintf(tname, sizeof(tname), "Recv-Q%s", cur_queue); - - char *thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - SCLogError(SC_ERR_RUNMODE, "thread name creation failed"); - exit(EXIT_FAILURE); - } - ThreadVars *tv_receive = - TmThreadCreatePacketHandler(thread_name, - "packetpool", "packetpool", - queues, "flow", "pktacqloop"); - if (tv_receive == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - TmModule *tm_module = TmModuleGetByName(recv_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName failed for %s", recv_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_receive, tm_module, (void *) ConfigParser(i)); - - tm_module = TmModuleGetByName(decode_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName %s failed", decode_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_receive, tm_module, NULL); - - TmThreadSetCPU(tv_receive, RECEIVE_CPU_SET); - - if (TmThreadSpawn(tv_receive) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - - } - for (thread = 0; thread < thread_max; thread++) { - snprintf(tname, sizeof(tname), "Detect%d", thread+1); - snprintf(qname, sizeof(qname), "pickup%d", thread+1); - - SCLogDebug("tname %s, qname %s", tname, qname); - - char *thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Can't allocate thread name"); - exit(EXIT_FAILURE); - } - ThreadVars *tv_detect_ncpu = - TmThreadCreatePacketHandler(thread_name, - qname, "flow", - "verdict-queue", "simple", - "varslot"); - if (tv_detect_ncpu == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - TmModule *tm_module = TmModuleGetByName("StreamTcp"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL); - - if (DetectEngineEnabled()) { - tm_module = TmModuleGetByName("Detect"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_detect_ncpu, tm_module, NULL); - } - - TmThreadSetCPU(tv_detect_ncpu, DETECT_CPU_SET); - - SetupOutputs(tv_detect_ncpu); - - char *thread_group_name = SCStrdup("Detect"); - if (unlikely(thread_group_name == NULL)) { - SCLogError(SC_ERR_RUNMODE, "Error allocating memory"); - exit(EXIT_FAILURE); - } - tv_detect_ncpu->thread_group_name = thread_group_name; - - if (TmThreadSpawn(tv_detect_ncpu) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - } - - /* create the threads */ - for (int i = 0; i < nqueue; i++) { - memset(tname, 0, sizeof(tname)); - snprintf(tname, sizeof(tname), "Verdict%d", i); - - char *thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - SCLogError(SC_ERR_RUNMODE, "Error allocating memory"); - exit(EXIT_FAILURE); - } - ThreadVars *tv_verdict = - TmThreadCreatePacketHandler(thread_name, - "verdict-queue", "simple", - "packetpool", "packetpool", - "varslot"); - if (tv_verdict == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - tm_module = TmModuleGetByName(verdict_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName %s failed", verdict_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_verdict, tm_module, (void *)ConfigParser(i)); - - tm_module = TmModuleGetByName("RespondReject"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for RespondReject failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv_verdict, tm_module, NULL); - - TmThreadSetCPU(tv_verdict, VERDICT_CPU_SET); - - if (TmThreadSpawn(tv_verdict) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - } - - SCFree(queues); - return 0; -} - -/** - */ -int RunModeSetIPSWorker(ConfigIPSParserFunc ConfigParser, - char *recv_mod_name, - char *verdict_mod_name, - char *decode_mod_name) -{ - char tname[TM_THREAD_NAME_MAX]; - ThreadVars *tv = NULL; - TmModule *tm_module = NULL; - char *cur_queue = NULL; - - int nqueue = LiveGetDeviceCount(); - - for (int i = 0; i < nqueue; i++) { - /* create the threads */ - cur_queue = LiveGetDeviceName(i); - if (cur_queue == NULL) { - SCLogError(SC_ERR_RUNMODE, "invalid queue number"); - exit(EXIT_FAILURE); - } - memset(tname, 0, sizeof(tname)); - snprintf(tname, sizeof(tname), "Worker-Q%s", cur_queue); - - char *thread_name = SCStrdup(tname); - if (unlikely(thread_name == NULL)) { - SCLogError(SC_ERR_RUNMODE, "Error allocating memory"); - exit(EXIT_FAILURE); - } - tv = TmThreadCreatePacketHandler(thread_name, - "packetpool", "packetpool", - "packetpool", "packetpool", - "pktacqloop"); - if (tv == NULL) { - SCLogError(SC_ERR_THREAD_CREATE, "TmThreadsCreate failed"); - exit(EXIT_FAILURE); - } - - tm_module = TmModuleGetByName(recv_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName failed for %s", recv_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, (void *) ConfigParser(i)); - - tm_module = TmModuleGetByName(decode_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_INVALID_VALUE, "TmModuleGetByName %s failed", decode_mod_name); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - tm_module = TmModuleGetByName("StreamTcp"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName StreamTcp failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - if (DetectEngineEnabled()) { - tm_module = TmModuleGetByName("Detect"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName Detect failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - } - - tm_module = TmModuleGetByName(verdict_mod_name); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName %s failed", verdict_mod_name); - exit(EXIT_FAILURE); - } - - TmSlotSetFuncAppend(tv, tm_module, NULL); - - tm_module = TmModuleGetByName("RespondReject"); - if (tm_module == NULL) { - SCLogError(SC_ERR_RUNMODE, "TmModuleGetByName for RespondReject failed"); - exit(EXIT_FAILURE); - } - TmSlotSetFuncAppend(tv, tm_module, NULL); - - SetupOutputs(tv); - - TmThreadSetCPU(tv, DETECT_CPU_SET); - - if (TmThreadSpawn(tv) != TM_ECODE_OK) { - SCLogError(SC_ERR_RUNMODE, "TmThreadSpawn failed"); - exit(EXIT_FAILURE); - } - } - - return 0; -} diff --git a/framework/src/suricata/src/util-runmodes.h b/framework/src/suricata/src/util-runmodes.h deleted file mode 100644 index 607895a4..00000000 --- a/framework/src/suricata/src/util-runmodes.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (C) 2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Eric Leblond - */ - -#ifndef __UTIL_RUNMODES_H__ -#define __UTIL_RUNMODES_H__ - -void RunmodeSetFlowStreamAsync(void); -int RunmodeGetFlowStreamAsync(void); - -typedef void *(*ConfigIfaceParserFunc) (const char *); -typedef void *(*ConfigIPSParserFunc) (int); -typedef int (*ConfigIfaceThreadsCountFunc) (void *); - -int RunModeSetLiveCaptureAuto(ConfigIfaceParserFunc configparser, - ConfigIfaceThreadsCountFunc ModThreadsCount, - char *recv_mod_name, - char *decode_mod_name, char *thread_name, - const char *live_dev); - -int RunModeSetLiveCaptureAutoFp(ConfigIfaceParserFunc configparser, - ConfigIfaceThreadsCountFunc ModThreadsCount, - char *recv_mod_name, - char *decode_mod_name, char *thread_name, - const char *live_dev); - -int RunModeSetLiveCaptureSingle(ConfigIfaceParserFunc configparser, - ConfigIfaceThreadsCountFunc ModThreadsCount, - char *recv_mod_name, - char *decode_mod_name, char *thread_name, - const char *live_dev); - -int RunModeSetLiveCaptureWorkers(ConfigIfaceParserFunc configparser, - ConfigIfaceThreadsCountFunc ModThreadsCount, - char *recv_mod_name, - char *decode_mod_name, char *thread_name, - const char *live_dev); - -int RunModeSetIPSAutoFp(ConfigIPSParserFunc ConfigParser, - char *recv_mod_name, - char *verdict_mod_name, - char *decode_mod_name); - -int RunModeSetIPSWorker(ConfigIPSParserFunc ConfigParser, - char *recv_mod_name, - char *verdict_mod_name, - char *decode_mod_name); - -char *RunmodeAutoFpCreatePickupQueuesString(int n); - -#endif /* __UTIL_RUNMODES_H__ */ diff --git a/framework/src/suricata/src/util-running-modes.c b/framework/src/suricata/src/util-running-modes.c deleted file mode 100644 index 8ad5a1ee..00000000 --- a/framework/src/suricata/src/util-running-modes.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Eric Leblond - */ - -#include "suricata-common.h" -#include "config.h" -#include "app-layer-detect-proto.h" -#include "app-layer.h" -#include "app-layer-parser.h" -#include "util-cuda.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "conf-yaml-loader.h" - -int ListKeywords(const char *keyword_info) -{ - if (ConfYamlLoadFile(DEFAULT_CONF_FILE) != -1) - SCLogLoadConfig(0, 0); - MpmTableSetup(); - AppLayerSetup(); - SigTableSetup(); /* load the rule keywords */ - SigTableList(keyword_info); - exit(EXIT_SUCCESS); -} - -int ListAppLayerProtocols() -{ - if (ConfYamlLoadFile(DEFAULT_CONF_FILE) != -1) - SCLogLoadConfig(0, 0); - MpmTableSetup(); - AppLayerSetup(); - AppLayerListSupportedProtocols(); - - exit(EXIT_SUCCESS); -} - -#ifdef __SC_CUDA_SUPPORT__ -int ListCudaCards() -{ - SCCudaInitCudaEnvironment(); - SCCudaListCards(); - exit(EXIT_SUCCESS); -} -#endif diff --git a/framework/src/suricata/src/util-running-modes.h b/framework/src/suricata/src/util-running-modes.h deleted file mode 100644 index b373f5aa..00000000 --- a/framework/src/suricata/src/util-running-modes.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** \file - * - * \author Eric Leblond - */ - -#ifndef __UTIL_RUNNING_MODES_H__ -#define __UTIL_RUNNING_MODES_H__ - - -int ListKeywords(const char *keyword_info); -int ListAppLayerProtocols(); -#ifdef __SC_CUDA_SUPPORT__ -int ListCudaCards(); -#endif - -#endif /* __UTIL_RUNNING_MODES_H__ */ diff --git a/framework/src/suricata/src/util-signal.c b/framework/src/suricata/src/util-signal.c deleted file mode 100644 index 0ba1a2b8..00000000 --- a/framework/src/suricata/src/util-signal.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "util-debug.h" - -int UtilSignalBlock(int signum) -{ - sigset_t x; - if (sigemptyset(&x) < 0) - return -1; - if (sigaddset(&x, signum) < 0) - return -1; - if (sigprocmask(SIG_BLOCK, &x, NULL) < 0) - return -1; - - return 0; -} - -void UtilSignalHandlerSetup(int sig, void (*handler)()) -{ -#if defined (OS_WIN32) - signal(sig, handler); -#else - struct sigaction action; - memset(&action, 0x00, sizeof(struct sigaction)); - - action.sa_handler = handler; - sigemptyset(&(action.sa_mask)); - sigaddset(&(action.sa_mask),sig); - action.sa_flags = 0; - sigaction(sig, &action, 0); -#endif /* OS_WIN32 */ - - return; -} - -int UtilSignalIsHandler(int sig, void (*handler)()) -{ - struct sigaction action; - memset(&action, 0x00, sizeof(struct sigaction)); - - sigaction(sig, NULL, &action); - - return (action.sa_handler == handler); -} diff --git a/framework/src/suricata/src/util-signal.h b/framework/src/suricata/src/util-signal.h deleted file mode 100644 index 7209b3da..00000000 --- a/framework/src/suricata/src/util-signal.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2012 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - */ - -#ifndef __UTIL_SIGNAL_H__ -#define __UTIL_SIGNAL_H__ - -int UtilSignalBlock(int); -void UtilSignalHandlerSetup(int, void (*handler)());; -int UtilSignalIsHandler(int sig, void (*handler)()); - -#endif /* __UTIL_SIGNAL_H__ */ diff --git a/framework/src/suricata/src/util-spm-bm.c b/framework/src/suricata/src/util-spm-bm.c deleted file mode 100644 index 7c5b8d2d..00000000 --- a/framework/src/suricata/src/util-spm-bm.c +++ /dev/null @@ -1,382 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * Boyer Moore simple pattern matcher implementation - * - * Boyer Moore algorithm has a really good performance. It need two arrays - * of context for each pattern that hold applicable shifts on the text - * to seach in, based on characters not available in the pattern - * and combinations of characters that start a sufix of the pattern. - * If possible, we should store the context of patterns that we are going - * to search for multiple times, so we don't spend time on rebuilding them. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "util-spm-bm.h" -#include "util-debug.h" -#include "util-error.h" -#include "util-memcpy.h" - -static int PreBmGs(const uint8_t *x, uint16_t m, uint16_t *bmGs); -static void PreBmBc(const uint8_t *x, uint16_t m, uint16_t *bmBc); -static void PreBmBcNocase(const uint8_t *x, uint16_t m, uint16_t *bmBc); -static void BoyerMooreSuffixesNocase(const uint8_t *x, uint16_t m, - uint16_t *suff); -static void PreBmGsNocase(const uint8_t *x, uint16_t m, uint16_t *bmGs); - -/** - * \brief Given a BmCtx structure, recreate the pre/suffixes for - * nocase - * - * \retval BmCtx pointer to the already created BmCtx (with BoyerMooreCtxInit()) - * \param str pointer to the pattern string - * \param size length of the string - */ -void BoyerMooreCtxToNocase(BmCtx *bm_ctx, uint8_t *needle, uint16_t needle_len) -{ - /* Store the content as lower case to make searching faster */ - memcpy_tolower(needle, needle, needle_len); - - /* Prepare bad chars with nocase chars */ - PreBmBcNocase(needle, needle_len, bm_ctx->bmBc); - - /* Prepare good Suffixes with nocase chars */ - PreBmGsNocase(needle, needle_len, bm_ctx->bmGs); -} - -/** - * \brief Setup a Booyer Moore context. - * - * \param str pointer to the pattern string - * \param size length of the string - * \retval BmCtx pointer to the newly created Context for the pattern - * \initonly BoyerMoore contexts should be created at init - */ -BmCtx *BoyerMooreCtxInit(uint8_t *needle, uint16_t needle_len) -{ - BmCtx *new = SCMalloc(sizeof(BmCtx)); - if (unlikely(new == NULL)) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in BoyerMooreCtxInit. Exiting..."); - exit(EXIT_FAILURE); - } - - /* Prepare bad chars */ - PreBmBc(needle, needle_len, new->bmBc); - - new->bmGs = SCMalloc(sizeof(uint16_t) * (needle_len + 1)); - if (new->bmGs == NULL) { - exit(EXIT_FAILURE); - } - - /* Prepare good Suffixes */ - if (PreBmGs(needle, needle_len, new->bmGs) == -1) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in BooyerMooreCtxInit. Exiting..."); - exit(EXIT_FAILURE); - } - - - return new; -} - -/** - * \brief Setup a Booyer Moore context for nocase search - * - * \param str pointer to the pattern string - * \param size length of the string - * \retval BmCtx pointer to the newly created Context for the pattern - * \initonly BoyerMoore contexts should be created at init - */ -BmCtx *BoyerMooreNocaseCtxInit(uint8_t *needle, uint16_t needle_len) -{ - BmCtx *bm_ctx = BoyerMooreCtxInit(needle, needle_len); - - BoyerMooreCtxToNocase(bm_ctx, needle, needle_len); - - return bm_ctx; -} - -/** - * \brief Free the memory allocated to Booyer Moore context. - * - * \param bmCtx pointer to the Context for the pattern - */ -void BoyerMooreCtxDeInit(BmCtx *bmctx) -{ - SCEnter(); - if (bmctx == NULL) - SCReturn; - - if (bmctx->bmGs != NULL) - SCFree(bmctx->bmGs); - - SCFree(bmctx); - - SCReturn; -} -/** - * \brief Array setup function for bad characters that split the pattern - * Remember that the result array should be the length of ALPHABET_SIZE - * - * \param str pointer to the pattern string - * \param size length of the string - * \param result pointer to an empty array that will hold the badchars - */ -static void PreBmBc(const uint8_t *x, uint16_t m, uint16_t *bmBc) -{ - int32_t i; - - for (i = 0; i < 256; ++i) { - bmBc[i] = m; - } - for (i = 0; i < m - 1; ++i) { - bmBc[(unsigned char)x[i]] = m - i - 1; - } -} - -/** - * \brief Array setup function for building prefixes (shift for valid prefixes) for boyermoore context - * - * \param x pointer to the pattern string - * \param m length of the string - * \param suff pointer to an empty array that will hold the prefixes (shifts) - */ -static void BoyerMooreSuffixes(const uint8_t *x, uint16_t m, uint16_t *suff) -{ - int32_t f = 0, g, i; - suff[m - 1] = m; - g = m - 1; - for (i = m - 2; i >= 0; --i) { - if (i > g && suff[i + m - 1 - f] < i - g) - suff[i] = suff[i + m - 1 - f]; - else { - if (i < g) - g = i; - f = i; - while (g >= 0 && x[g] == x[g + m - 1 - f]) - --g; - suff[i] = f - g; - } - } -} - -/** - * \brief Array setup function for building prefixes (shift for valid prefixes) for boyermoore context - * - * \param x pointer to the pattern string - * \param m length of the string - * \param bmGs pointer to an empty array that will hold the prefixes (shifts) - * \retval 0 ok, -1 failed - */ -static int PreBmGs(const uint8_t *x, uint16_t m, uint16_t *bmGs) -{ - int32_t i, j; - uint16_t suff[m + 1]; - - BoyerMooreSuffixes(x, m, suff); - - for (i = 0; i < m; ++i) - bmGs[i] = m; - - j = 0; - - for (i = m - 1; i >= -1; --i) - if (i == -1 || suff[i] == i + 1) - for (; j < m - 1 - i; ++j) - if (bmGs[j] == m) - bmGs[j] = m - 1 - i; - - for (i = 0; i <= m - 2; ++i) - bmGs[m - 1 - suff[i]] = m - 1 - i; - return 0; -} - -/** - * \brief Array setup function for bad characters that split the pattern - * Remember that the result array should be the length of ALPHABET_SIZE - * - * \param str pointer to the pattern string - * \param size length of the string - * \param result pointer to an empty array that will hold the badchars - */ -static void PreBmBcNocase(const uint8_t *x, uint16_t m, uint16_t *bmBc) -{ - int32_t i; - - for (i = 0; i < 256; ++i) { - bmBc[i] = m; - } - for (i = 0; i < m - 1; ++i) { - bmBc[u8_tolower((unsigned char)x[i])] = m - 1 - i; - } -} - -static void BoyerMooreSuffixesNocase(const uint8_t *x, uint16_t m, - uint16_t *suff) -{ - int32_t f = 0, g, i; - - suff[m - 1] = m; - g = m - 1; - for (i = m - 2; i >= 0; --i) { - if (i > g && suff[i + m - 1 - f] < i - g) { - suff[i] = suff[i + m - 1 - f]; - } else { - if (i < g) { - g = i; - } - f = i; - while (g >= 0 && u8_tolower(x[g]) == u8_tolower(x[g + m - 1 - f])) { - --g; - } - suff[i] = f - g; - } - } -} - -/** - * \brief Array setup function for building prefixes (shift for valid prefixes) - * for boyermoore context case less - * - * \param x pointer to the pattern string - * \param m length of the string - * \param bmGs pointer to an empty array that will hold the prefixes (shifts) - */ -static void PreBmGsNocase(const uint8_t *x, uint16_t m, uint16_t *bmGs) -{ - int32_t i, j; - uint16_t suff[m + 1]; - - BoyerMooreSuffixesNocase(x, m, suff); - - for (i = 0; i < m; ++i) { - bmGs[i] = m; - } - j = 0; - for (i = m - 1; i >= 0; --i) { - if (i == -1 || suff[i] == i + 1) { - for (; j < m - 1 - i; ++j) { - if (bmGs[j] == m) { - bmGs[j] = m - 1 - i; - } - } - } - } - for (i = 0; i <= m - 2; ++i) { - bmGs[m - 1 - suff[i]] = m - 1 - i; - } -} - -/** - * \brief Boyer Moore search algorithm - * Is better as the pattern length increases and for big buffers to search in. - * The algorithm needs a context of two arrays already prepared - * by prep_bad_chars() and prep_good_suffix() - * - * \param y pointer to the buffer to search in - * \param n length limit of the buffer - * \param x pointer to the pattern we ar searching for - * \param m length limit of the needle - * \param bmBc pointer to an array of BoyerMooreSuffixes prepared by prep_good_suffix() - * \param bmGs pointer to an array of bachars prepared by prep_bad_chars() - * - * \retval ptr to start of the match; NULL if no match - */ -uint8_t *BoyerMoore(uint8_t *x, uint16_t m, uint8_t *y, int32_t n, BmCtx *bm_ctx) -{ - uint16_t *bmGs = bm_ctx->bmGs; - uint16_t *bmBc = bm_ctx->bmBc; - - int i, j, m1, m2; -#if 0 - printf("\nBad:\n"); - for (i=0;i= 0 && x[i] == y[i + j]; --i); - - if (i < 0) { - return y + j; - //j += bmGs[0]; - } else { - // printf("%c", y[i+j]); - j += (m1 = bmGs[i]) > (m2 = bmBc[y[i + j]] - m + 1 + i)? m1: m2; -// printf("%d, %d\n", m1, m2); - } - } - return NULL; -} - - -/** - * \brief Boyer Moore search algorithm - * Is better as the pattern length increases and for big buffers to search in. - * The algorithm needs a context of two arrays already prepared - * by prep_bad_chars() and prep_good_suffix() - * - * \param y pointer to the buffer to search in - * \param n length limit of the buffer - * \param x pointer to the pattern we ar searching for - * \param m length limit of the needle - * \param bmBc pointer to an array of BoyerMooreSuffixes prepared by prep_good_suffix() - * \param bmGs pointer to an array of bachars prepared by prep_bad_chars() - * - * \retval ptr to start of the match; NULL if no match - */ -uint8_t *BoyerMooreNocase(uint8_t *x, uint16_t m, uint8_t *y, int32_t n, BmCtx *bm_ctx) -{ - uint16_t *bmGs = bm_ctx->bmGs; - uint16_t *bmBc = bm_ctx->bmBc; - int i, j, m1, m2; -#if 0 - printf("\nBad:\n"); - for (i=0;i= 0 && x[i] == u8_tolower(y[i + j]); --i); - - if (i < 0) { - return y + j; - } else { - j += (m1=bmGs[i]) > (m2=bmBc[u8_tolower(y[i + j])] - m + 1 + i)?m1:m2; - } - } - return NULL; -} - diff --git a/framework/src/suricata/src/util-spm-bm.h b/framework/src/suricata/src/util-spm-bm.h deleted file mode 100644 index b3b97ced..00000000 --- a/framework/src/suricata/src/util-spm-bm.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - */ - -#ifndef __UTIL_SPM_BM__ -#define __UTIL_SPM_BM__ - -#include "suricata-common.h" -#include "suricata.h" - -#define ALPHABET_SIZE 256 - -/* Context for booyer moore */ -typedef struct BmCtx_ { - uint16_t bmBc[ALPHABET_SIZE]; - uint16_t *bmGs; // = SCMalloc(sizeof(int32_t)*(needlelen + 1)); -} BmCtx; - -/** Prepare and return a Boyer Moore context */ -BmCtx *BoyerMooreCtxInit(uint8_t *needle, uint16_t needle_len); -BmCtx *BoyerMooreNocaseCtxInit(uint8_t *needle, uint16_t needle_len); - -void BoyerMooreCtxToNocase(BmCtx *, uint8_t *, uint16_t); -uint8_t *BoyerMoore(uint8_t *x, uint16_t m, uint8_t *y, int32_t n, BmCtx *bm_ctx); -uint8_t *BoyerMooreNocase(uint8_t *x, uint16_t m, uint8_t *y, int32_t n, BmCtx *bm_ctx); -void BoyerMooreCtxDeInit(BmCtx *); - -#endif /* __UTIL_SPM_BM__ */ - diff --git a/framework/src/suricata/src/util-spm-bs.c b/framework/src/suricata/src/util-spm-bs.c deleted file mode 100644 index 6d49ff65..00000000 --- a/framework/src/suricata/src/util-spm-bs.c +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon Crespo - * - * bs is a bruteforce search. It will try to search the pattern - * from all characters until the available text len is less - * than the length of the pattern. It needs no context but it - * time cost is not good. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "util-debug.h" -#include "util-spm-bs.h" - - -/** - * \brief Basic search improved. Limits are better handled, so - * it doesn't start searches that wont fit in the remaining buffer - * - * \param haystack pointer to the buffer to search in - * \param haystack_len length limit of the buffer - * \param neddle pointer to the pattern we ar searching for - * \param needle_len length limit of the needle - * - * \retval ptr to start of the match; NULL if no match - */ -uint8_t *BasicSearch(const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len) -{ - SCEnter(); - - const uint8_t *h, *n; - const uint8_t *hmax = haystack + haystack_len; - const uint8_t *nmax = needle + needle_len; - - if (needle_len == 0 || needle_len > haystack_len) { - SCReturnPtr(NULL, "uint8_t"); - } - - //PrintRawDataFp(stdout,needle,needle_len); - - //PrintRawDataFp(stdout,haystack,haystack_len); - - for (n = needle; nmax - n <= hmax - haystack; haystack++) { - if (*haystack != *n) { - continue; - } - - SCLogDebug("*haystack == *n, %c == %c", *haystack, *n); - - /* one byte needles */ - if (needle_len == 1) { - SCReturnPtr((uint8_t *)haystack, "uint8_t"); - } - - for (h = haystack+1, n++; nmax - n <= hmax - haystack; h++, n++) { - if (*h != *n) { - break; - } - SCLogDebug("*haystack == *n, %c == %c", *haystack, *n); - /* if we run out of needle we fully matched */ - if (n == nmax - 1) { - SCReturnPtr((uint8_t *)haystack, "uint8_t"); - } - } - n = needle; - } - - SCReturnPtr(NULL, "uint8_t"); -} - -/** - * \brief Basic search case less - * - * \param haystack pointer to the buffer to search in - * \param haystack_len length limit of the buffer - * \param neddle pointer to the pattern we ar searching for - * \param needle_len length limit of the needle - * - * \retval ptr to start of the match; NULL if no match - */ -uint8_t *BasicSearchNocase(const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len) -{ - const uint8_t *h, *n; - const uint8_t *hmax = haystack + haystack_len; - const uint8_t *nmax = needle + needle_len; - - if (needle_len == 0 || needle_len > haystack_len) - return NULL; - - for (n = needle; nmax - n <= hmax - haystack; haystack++) { - if (u8_tolower(*haystack) != u8_tolower(*n)) { - continue; - } - /* one byte needles */ - if (needle_len == 1) { - return (uint8_t *)haystack; - } - - for (h = haystack+1, n++; nmax - n <= hmax - h ; h++, n++) { - if (u8_tolower(*h) != u8_tolower(*n)) { - break; - } - /* if we run out of needle we fully matched */ - if (n == nmax - 1) { - return (uint8_t *)haystack; - } - } - n = needle; - } - - return NULL; -} - -void BasicSearchInit (void) -{ - /* nothing no more */ -} - diff --git a/framework/src/suricata/src/util-spm-bs.h b/framework/src/suricata/src/util-spm-bs.h deleted file mode 100644 index 1e97f0ba..00000000 --- a/framework/src/suricata/src/util-spm-bs.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Pablo Rincon Crespo - */ - -#ifndef __UTIL_SPM_BS__ -#define __UTIL_SPM_BS__ - -#include "suricata-common.h" -#include "suricata.h" - -uint8_t *BasicSearch(const uint8_t *, uint32_t, const uint8_t *, uint16_t); -uint8_t *BasicSearchNocase(const uint8_t *, uint32_t, const uint8_t *, uint16_t); -void BasicSearchInit (void); - -#endif /* __UTIL_SPM_BS__ */ - diff --git a/framework/src/suricata/src/util-spm-bs2bm.c b/framework/src/suricata/src/util-spm-bs2bm.c deleted file mode 100644 index d6529df8..00000000 --- a/framework/src/suricata/src/util-spm-bs2bm.c +++ /dev/null @@ -1,176 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * Bs2Bm use a simple context array to determine the charactes - * that are not present on the pattern. This way on partial matches - * broken by a char not present, we can skip to the next character - * making less checks - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "util-spm-bs2bm.h" - -/** - * \brief Array setup function for Bs2Bm of bad characters index (not found at the needle) - * - * \param neddle pointer to the pattern we ar searching for - * \param needle_len length limit of the needle - * \param badchars pointer to an empty array of bachars. The array prepared contains - * characters that can't be inside the needle_len. So the skips can be - * faster - */ -void Bs2BmBadchars(const uint8_t *needle, uint16_t needle_len, uint8_t *badchars) -{ - uint32_t i; - for (i = 0; i < ALPHABET_SIZE; i++) - badchars[i] = 1; - - /* set to 0 the values where index as ascii is present - * because they are not badchars - */ - for (i = 0; i < needle_len; i++) - badchars[needle[i]] = 0; -} - -/** - * \brief Array setup function for Bs2BmNocase of bad characters index (not found at the needle) - * - * \param neddle pointer to the pattern we ar searching for - * \param needle_len length limit of the needle - * \param badchars pointer to an empty array of bachars. The array prepared contains - * characters that can't be inside the needle_len. So the skips can be - * faster - */ -void Bs2BmBadcharsNocase(const uint8_t *needle, uint16_t needle_len, uint8_t *badchars) -{ - uint32_t i; - for (i = 0; i < ALPHABET_SIZE; i++) - badchars[i] = 1; - - /* set to 0 the values where index as ascii is present - * because they are not badchars - */ - for (i = 0; i < needle_len; i++) { - badchars[u8_tolower(needle[i])] = 0; - } -} - - -/** - * \brief Basic search with a bad characters array. The array badchars contains - * flags at character's ascii index that can't be inside the needle. So the skips can be - * faster - * - * \param haystack pointer to the buffer to search in - * \param haystack_len length limit of the buffer - * \param neddle pointer to the pattern we ar searching for - * \param needle_len length limit of the needle - * \param badchars pointer to an array of bachars prepared by Bs2BmBadchars() - * - * \retval ptr to start of the match; NULL if no match - */ -uint8_t * Bs2Bm(const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len, uint8_t badchars[]) -{ - const uint8_t *h, *n; - const uint8_t *hmax = haystack + haystack_len; - const uint8_t *nmax = needle + needle_len; - - if (needle_len == 0 || needle_len > haystack_len) - return NULL; - - for (n = needle; nmax - n <= hmax - haystack; haystack++) { - if (*haystack != *n) { - continue; - } - /* one byte needles */ - if (needle_len == 1) - return (uint8_t *)haystack; - - for (h = haystack+1, n++; nmax - n <= hmax - haystack; h++, n++) { - if (*h != *n) { - if (badchars[*h] == 1) { - /* skip it! */ - haystack = h; - } - break; - } - /* if we run out of needle we fully matched */ - if (n == nmax - 1 ) { - return (uint8_t *)haystack; - } - } - n = needle; - } - - return NULL; -} - -/** - * \brief Basic search case less with a bad characters array. The array badchars contains - * flags at character's ascii index that can't be inside the needle. So the skips can be - * faster - * - * \param haystack pointer to the buffer to search in - * \param haystack_len length limit of the buffer - * \param neddle pointer to the pattern we ar searching for - * \param needle_len length limit of the needle - * \param badchars pointer to an array of bachars prepared by Bs2BmBadchars() - * - * \retval ptr to start of the match; NULL if no match - */ -uint8_t *Bs2BmNocase(const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint16_t needle_len, uint8_t badchars[]) -{ - const uint8_t *h, *n; - const uint8_t *hmax = haystack + haystack_len; - const uint8_t *nmax = needle + needle_len; - - if (needle_len == 0 || needle_len > haystack_len) - return NULL; - - for (n = needle; nmax - n <= hmax - haystack; haystack++) { - if (u8_tolower(*haystack) != u8_tolower(*n)) { - continue; - } - /* one byte needles */ - if (needle_len == 1) - return (uint8_t *)haystack; - - for (h = haystack+1, n++; nmax - n <= hmax - haystack; h++, n++) { - if (u8_tolower(*h) != u8_tolower(*n)) { - if (badchars[u8_tolower(*h)] == 1) { - /* skip it! */ - haystack = h; - } - break; - } - /* if we run out of needle we fully matched */ - if (n == nmax - 1) { - return (uint8_t *)haystack; - } - } - n = needle; - } - - return NULL; -} diff --git a/framework/src/suricata/src/util-spm-bs2bm.h b/framework/src/suricata/src/util-spm-bs2bm.h deleted file mode 100644 index a71b1282..00000000 --- a/framework/src/suricata/src/util-spm-bs2bm.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - */ - -#ifndef __UTIL_SPM_BS2BM__ -#define __UTIL_SPM_BS2BM__ - -#include "suricata-common.h" -#include "suricata.h" - -#define ALPHABET_SIZE 256 - -void Bs2BmBadchars(const uint8_t *, uint16_t, uint8_t *); -void Bs2BmBadcharsNocase(const uint8_t *, uint16_t, uint8_t *); -uint8_t * Bs2Bm(const uint8_t *, uint32_t, const uint8_t *, uint16_t, uint8_t []); -uint8_t *Bs2BmNocase(const uint8_t *, uint32_t, const uint8_t *, uint16_t, uint8_t []); - -#endif /* __UTIL_SPM_BS2BM__ */ - diff --git a/framework/src/suricata/src/util-spm.c b/framework/src/suricata/src/util-spm.c deleted file mode 100644 index 2da12e77..00000000 --- a/framework/src/suricata/src/util-spm.c +++ /dev/null @@ -1,2368 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * PR (17/01/2010): Single pattern search algorithms: - * Currently there are 3 algorithms to choose: BasicSearch, Bs2Bm and - * BoyerMoore (Boyer Moores algorithm). The first one doesn't need a context. - * But for Bs2Bm and BoyerMoore, you'll need to build some arrays. - * - * !! If you are going to use the same pattern multiple times, - * please, try to store the context some where. For Bs2Bm, the - * context is an array of "badchars". For BoyerMoore you need to store - * two arrays of shifts. Have a look at the wrappers and unittests - * for examples of this. If you cant store the context, use the - * wrappers: Bs2bmSearch, BoyerMooreSearch, and the ones caseless, or BasicSearch - * That is the most basic. - * - * Use the stats and util-clock.h to determine which one fit better for you - * Boyer Moore should be used for patterns greater than 1 of length - * In the range of 2 - 6, if the text length is greater than 1000 you could - * use boyer moore, otherwise, basic search. If the pattern is greater - * than 6 and the textlen is greater than 500, use boyer moore. - * This is an aproximation, but use the stats and util-clock to determine which one - * fit better for your case. - * - */ - -#include "suricata-common.h" -#include "suricata.h" -#include "util-unittest.h" - -#include "util-spm.h" -#include "util-spm-bs.h" -#include "util-spm-bs2bm.h" -#include "util-spm-bm.h" -#include "util-clock.h" - - -/** - * Wrappers for building context and searching (Bs2Bm and boyermoore) - * Use them if you cant store the context - * - */ - -/** - * \brief Search a pattern in the text using the Bs2Bm algorithm (build a bad characters array) - * - * \param text Text to search in - * \param textlen length of the text - * \param needle pattern to search for - * \param needlelen length of the pattern - */ -uint8_t *Bs2bmSearch(uint8_t *text, uint32_t textlen, uint8_t *needle, uint16_t needlelen) -{ - uint8_t badchars[ALPHABET_SIZE]; - Bs2BmBadchars(needle, needlelen, badchars); - - return Bs2Bm(text, textlen, needle, needlelen, badchars); -} - -/** - * \brief Search a pattern in the text using the Bs2Bm nocase algorithm (build a bad characters array) - * - * \param text Text to search in - * \param textlen length of the text - * \param needle pattern to search for - * \param needlelen length of the pattern - */ -uint8_t *Bs2bmNocaseSearch(uint8_t *text, uint32_t textlen, uint8_t *needle, uint16_t needlelen) -{ - uint8_t badchars[ALPHABET_SIZE]; - Bs2BmBadchars(needle, needlelen, badchars); - - return Bs2BmNocase(text, textlen, needle, needlelen, badchars); -} - -/** - * \brief Search a pattern in the text using Boyer Moore algorithm - * (build a bad character shifts array and good prefixes shift array) - * - * \param text Text to search in - * \param textlen length of the text - * \param needle pattern to search for - * \param needlelen length of the pattern - */ -uint8_t *BoyerMooreSearch(uint8_t *text, uint32_t textlen, uint8_t *needle, uint16_t needlelen) -{ - BmCtx *bm_ctx = BoyerMooreCtxInit(needle, needlelen); - - uint8_t *ret = BoyerMoore(needle, needlelen, text, textlen, bm_ctx); - BoyerMooreCtxDeInit(bm_ctx); - - return ret; -} - -/** - * \brief Search a pattern in the text using Boyer Moore nocase algorithm - * (build a bad character shifts array and good prefixes shift array) - * - * \param text Text to search in - * \param textlen length of the text - * \param needle pattern to search for - * \param needlelen length of the pattern - */ -uint8_t *BoyerMooreNocaseSearch(uint8_t *text, uint32_t textlen, uint8_t *needle, uint16_t needlelen) -{ - BmCtx *bm_ctx = BoyerMooreNocaseCtxInit(needle, needlelen); - - uint8_t *ret = BoyerMooreNocase(needle, needlelen, text, textlen, bm_ctx); - BoyerMooreCtxDeInit(bm_ctx); - - return ret; -} - - -#ifdef UNITTESTS - -/** Comment out this if you want stats - * #define ENABLE_SEARCH_STATS 1 - */ - -/* Number of times to repeat the search (for stats) */ -#define STATS_TIMES 1000000 - -/** - * \brief Unittest helper function wrappers for the search algorithms - * \param text pointer to the buffer to search in - * \param needle pointer to the pattern to search for - * \param times If you are testing performance, se the numebr of times - * that you want to repeat the search - */ -uint8_t *BasicSearchWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) - CLOCK_START; - - for (i = 0; i < times; i++) { - ret = BasicSearch(text, textlen, needle, needlelen); - } - - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - return ret; -} - -uint8_t *BasicSearchNocaseWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - ret = BasicSearchNocase(text, textlen, needle, needlelen); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - return ret; -} - -uint8_t *Bs2bmWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - uint8_t badchars[ALPHABET_SIZE]; - Bs2BmBadchars(needle, needlelen, badchars); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - ret = Bs2Bm(text, textlen, needle, needlelen, badchars); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - return ret; -} - -uint8_t *Bs2bmNocaseWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - uint8_t badchars[ALPHABET_SIZE]; - Bs2BmBadchars(needle, needlelen, badchars); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - ret = Bs2BmNocase(text, textlen, needle, needlelen, badchars); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - return ret; -} - -uint8_t *BoyerMooreWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - BmCtx *bm_ctx = BoyerMooreCtxInit(needle, needlelen); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - ret = BoyerMoore(needle, needlelen, text, textlen, bm_ctx); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - BoyerMooreCtxDeInit(bm_ctx); - return ret; -} - -uint8_t *BoyerMooreNocaseWrapper(uint8_t *text, uint8_t *in_needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)in_needle); - - /* Make a copy of in_needle to be able to convert it to lowercase. */ - uint8_t *needle = SCMalloc(needlelen); - if (needle == NULL) - return NULL; - memcpy(needle, in_needle, needlelen); - - BmCtx *bm_ctx = BoyerMooreNocaseCtxInit(needle, needlelen); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - ret = BoyerMooreNocase(needle, needlelen, text, textlen, bm_ctx); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - BoyerMooreCtxDeInit(bm_ctx); - free(needle); - return ret; - -} - -/** - * \brief Unittest helper function wrappers for the search algorithms - * \param text pointer to the buffer to search in - * \param needle pointer to the pattern to search for - * \param times If you are testing performance, se the numebr of times - * that you want to repeat the search - */ -uint8_t *BasicSearchCtxWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - /* This wrapper is a fake, no context needed! */ - ret = BasicSearch(text, textlen, needle, needlelen); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - return ret; -} - -uint8_t *BasicSearchNocaseCtxWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - /* This wrapper is a fake, no context needed! */ - ret = BasicSearchNocase(text, textlen, needle, needlelen); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - return ret; -} - -uint8_t *Bs2bmCtxWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - uint8_t badchars[ALPHABET_SIZE]; - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - /* Stats including context building */ - Bs2BmBadchars(needle, needlelen, badchars); - ret = Bs2Bm(text, textlen, needle, needlelen, badchars); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - return ret; -} - -uint8_t *Bs2bmNocaseCtxWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - uint8_t badchars[ALPHABET_SIZE]; - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - /* Stats including context building */ - Bs2BmBadchars(needle, needlelen, badchars); - ret = Bs2BmNocase(text, textlen, needle, needlelen, badchars); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - return ret; -} - -uint8_t *BoyerMooreCtxWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - BmCtx *bm_ctx = BoyerMooreCtxInit(needle, needlelen); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - /* Stats including context building */ - ret = BoyerMoore(needle, needlelen, text, textlen, bm_ctx); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - BoyerMooreCtxDeInit(bm_ctx); - - return ret; -} - -uint8_t *RawCtxWrapper(uint8_t *text, uint8_t *needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)needle); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - ret = SpmSearch(text, textlen, needle, needlelen); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - return ret; -} - -uint8_t *BoyerMooreNocaseCtxWrapper(uint8_t *text, uint8_t *in_needle, int times) -{ - uint32_t textlen = strlen((char *)text); - uint16_t needlelen = strlen((char *)in_needle); - - /* Make a copy of in_needle to be able to convert it to lowercase. */ - uint8_t *needle = SCMalloc(needlelen); - if (needle == NULL) - return NULL; - memcpy(needle, in_needle, needlelen); - - BmCtx *bm_ctx = BoyerMooreNocaseCtxInit(needle, needlelen); - - uint8_t *ret = NULL; - int i = 0; - - CLOCK_INIT; - if (times > 1) CLOCK_START; - for (i = 0; i < times; i++) { - ret = BoyerMooreNocase(needle, needlelen, text, textlen, bm_ctx); - } - if (times > 1) { CLOCK_END; CLOCK_PRINT_SEC; }; - BoyerMooreCtxDeInit(bm_ctx); - free(needle); - return ret; - -} - -/** - * \test Generic test for BasicSearch matching - */ -int UtilSpmBasicSearchTest01() -{ - uint8_t *needle = (uint8_t *)"oPqRsT"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = BasicSearchWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 1; - else - return 0; -} - -/** - * \test Generic test for BasicSearch nocase matching - */ -int UtilSpmBasicSearchNocaseTest01() -{ - uint8_t *needle = (uint8_t *)"OpQrSt"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = BasicSearchNocaseWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 1; - else - return 0; -} - -/** - * \test Generic test for Bs2Bm matching - */ -int UtilSpmBs2bmSearchTest01() -{ - uint8_t *needle = (uint8_t *)"oPqRsT"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = Bs2bmWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 1; - else - return 0; -} - -/** - * \test Generic test for Bs2Bm no case matching - */ -int UtilSpmBs2bmSearchNocaseTest01() -{ - uint8_t *needle = (uint8_t *)"OpQrSt"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = Bs2bmNocaseWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 1; - else - return 0; -} - -/** - * \test Generic test for boyer moore matching - */ -int UtilSpmBoyerMooreSearchTest01() -{ - uint8_t *needle = (uint8_t *)"oPqRsT"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = BoyerMooreWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 1; - else - return 0; -} - -/** - * \test Generic test for boyer moore nocase matching - */ -int UtilSpmBoyerMooreSearchNocaseTest01() -{ - uint8_t *needle = (uint8_t *)"OpQrSt"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = BoyerMooreNocaseWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 1; - else - return 0; -} - -/** - * \test issue 130 (@redmine) check to ensure that the - * problem is not the algorithm implementation - */ -int UtilSpmBoyerMooreSearchNocaseTestIssue130() -{ - uint8_t *needle = (uint8_t *)"WWW-Authenticate: "; - uint8_t *text = (uint8_t *)"Date: Mon, 23 Feb 2009 13:31:49 GMT" - "Server: Apache\r\n" - "Www-authenticate: Basic realm=\"Authentification user password\"\r\n" - "Vary: accept-language,accept-charset\r\n" - "Accept-ranges: bytes\r\n" - "Connection: close\r\n" - "Content-type: text/html; charset=iso-8859-1\r\n" - "Content-language: fr\r\n" - "Expires: Mon, 23 Feb 2009 13:31:49 GMT\r\n\r\n"; - uint8_t *found = BoyerMooreNocaseWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 1; - else - return 0; -} - -/* Generic tests that should not match */ -int UtilSpmBasicSearchTest02() -{ - uint8_t *needle = (uint8_t *)"oPQRsT"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = BasicSearchWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 0; - else - return 1; -} - -int UtilSpmBasicSearchNocaseTest02() -{ - uint8_t *needle = (uint8_t *)"OpZrSt"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = BasicSearchNocaseWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 0; - else - return 1; -} - -int UtilSpmBs2bmSearchTest02() -{ - uint8_t *needle = (uint8_t *)"oPQRsT"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = Bs2bmWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 0; - else - return 1; -} - -int UtilSpmBs2bmSearchNocaseTest02() -{ - uint8_t *needle = (uint8_t *)"OpZrSt"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = Bs2bmNocaseWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 0; - else - return 1; -} - -int UtilSpmBoyerMooreSearchTest02() -{ - uint8_t *needle = (uint8_t *)"oPQRsT"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = BoyerMooreWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 0; - else - return 1; -} - -int UtilSpmBoyerMooreSearchNocaseTest02() -{ - uint8_t *needle = (uint8_t *)"OpZrSt"; - uint8_t *text = (uint8_t *)"aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - uint8_t *found = BoyerMooreNocaseWrapper(text, needle, 1); - //printf("found: %s\n", found); - if (found != NULL) - return 0; - else - return 1; -} - -/** - * \test Check that all the algorithms work at any offset and any pattern length - */ -int UtilSpmSearchOffsetsTest01() -{ - char *text[26][27]; - text[0][0]="azzzzzzzzzzzzzzzzzzzzzzzzzz"; - text[0][1]="zazzzzzzzzzzzzzzzzzzzzzzzzz"; - text[0][2]="zzazzzzzzzzzzzzzzzzzzzzzzzz"; - text[0][3]="zzzazzzzzzzzzzzzzzzzzzzzzzz"; - text[0][4]="zzzzazzzzzzzzzzzzzzzzzzzzzz"; - text[0][5]="zzzzzazzzzzzzzzzzzzzzzzzzzz"; - text[0][6]="zzzzzzazzzzzzzzzzzzzzzzzzzz"; - text[0][7]="zzzzzzzazzzzzzzzzzzzzzzzzzz"; - text[0][8]="zzzzzzzzazzzzzzzzzzzzzzzzzz"; - text[0][9]="zzzzzzzzzazzzzzzzzzzzzzzzzz"; - text[0][10]="zzzzzzzzzzazzzzzzzzzzzzzzzz"; - text[0][11]="zzzzzzzzzzzazzzzzzzzzzzzzzz"; - text[0][12]="zzzzzzzzzzzzazzzzzzzzzzzzzz"; - text[0][13]="zzzzzzzzzzzzzazzzzzzzzzzzzz"; - text[0][14]="zzzzzzzzzzzzzzazzzzzzzzzzzz"; - text[0][15]="zzzzzzzzzzzzzzzazzzzzzzzzzz"; - text[0][16]="zzzzzzzzzzzzzzzzazzzzzzzzzz"; - text[0][17]="zzzzzzzzzzzzzzzzzazzzzzzzzz"; - text[0][18]="zzzzzzzzzzzzzzzzzzazzzzzzzz"; - text[0][19]="zzzzzzzzzzzzzzzzzzzazzzzzzz"; - text[0][20]="zzzzzzzzzzzzzzzzzzzzazzzzzz"; - text[0][21]="zzzzzzzzzzzzzzzzzzzzzazzzzz"; - text[0][22]="zzzzzzzzzzzzzzzzzzzzzzazzzz"; - text[0][23]="zzzzzzzzzzzzzzzzzzzzzzzazzz"; - text[0][24]="zzzzzzzzzzzzzzzzzzzzzzzzazz"; - text[0][25]="zzzzzzzzzzzzzzzzzzzzzzzzzaz"; - text[0][26]="zzzzzzzzzzzzzzzzzzzzzzzzzza"; - text[1][0]="aBzzzzzzzzzzzzzzzzzzzzzzzzz"; - text[1][1]="zaBzzzzzzzzzzzzzzzzzzzzzzzz"; - text[1][2]="zzaBzzzzzzzzzzzzzzzzzzzzzzz"; - text[1][3]="zzzaBzzzzzzzzzzzzzzzzzzzzzz"; - text[1][4]="zzzzaBzzzzzzzzzzzzzzzzzzzzz"; - text[1][5]="zzzzzaBzzzzzzzzzzzzzzzzzzzz"; - text[1][6]="zzzzzzaBzzzzzzzzzzzzzzzzzzz"; - text[1][7]="zzzzzzzaBzzzzzzzzzzzzzzzzzz"; - text[1][8]="zzzzzzzzaBzzzzzzzzzzzzzzzzz"; - text[1][9]="zzzzzzzzzaBzzzzzzzzzzzzzzzz"; - text[1][10]="zzzzzzzzzzaBzzzzzzzzzzzzzzz"; - text[1][11]="zzzzzzzzzzzaBzzzzzzzzzzzzzz"; - text[1][12]="zzzzzzzzzzzzaBzzzzzzzzzzzzz"; - text[1][13]="zzzzzzzzzzzzzaBzzzzzzzzzzzz"; - text[1][14]="zzzzzzzzzzzzzzaBzzzzzzzzzzz"; - text[1][15]="zzzzzzzzzzzzzzzaBzzzzzzzzzz"; - text[1][16]="zzzzzzzzzzzzzzzzaBzzzzzzzzz"; - text[1][17]="zzzzzzzzzzzzzzzzzaBzzzzzzzz"; - text[1][18]="zzzzzzzzzzzzzzzzzzaBzzzzzzz"; - text[1][19]="zzzzzzzzzzzzzzzzzzzaBzzzzzz"; - text[1][20]="zzzzzzzzzzzzzzzzzzzzaBzzzzz"; - text[1][21]="zzzzzzzzzzzzzzzzzzzzzaBzzzz"; - text[1][22]="zzzzzzzzzzzzzzzzzzzzzzaBzzz"; - text[1][23]="zzzzzzzzzzzzzzzzzzzzzzzaBzz"; - text[1][24]="zzzzzzzzzzzzzzzzzzzzzzzzaBz"; - text[1][25]="zzzzzzzzzzzzzzzzzzzzzzzzzaB"; - text[2][0]="aBczzzzzzzzzzzzzzzzzzzzzzzz"; - text[2][1]="zaBczzzzzzzzzzzzzzzzzzzzzzz"; - text[2][2]="zzaBczzzzzzzzzzzzzzzzzzzzzz"; - text[2][3]="zzzaBczzzzzzzzzzzzzzzzzzzzz"; - text[2][4]="zzzzaBczzzzzzzzzzzzzzzzzzzz"; - text[2][5]="zzzzzaBczzzzzzzzzzzzzzzzzzz"; - text[2][6]="zzzzzzaBczzzzzzzzzzzzzzzzzz"; - text[2][7]="zzzzzzzaBczzzzzzzzzzzzzzzzz"; - text[2][8]="zzzzzzzzaBczzzzzzzzzzzzzzzz"; - text[2][9]="zzzzzzzzzaBczzzzzzzzzzzzzzz"; - text[2][10]="zzzzzzzzzzaBczzzzzzzzzzzzzz"; - text[2][11]="zzzzzzzzzzzaBczzzzzzzzzzzzz"; - text[2][12]="zzzzzzzzzzzzaBczzzzzzzzzzzz"; - text[2][13]="zzzzzzzzzzzzzaBczzzzzzzzzzz"; - text[2][14]="zzzzzzzzzzzzzzaBczzzzzzzzzz"; - text[2][15]="zzzzzzzzzzzzzzzaBczzzzzzzzz"; - text[2][16]="zzzzzzzzzzzzzzzzaBczzzzzzzz"; - text[2][17]="zzzzzzzzzzzzzzzzzaBczzzzzzz"; - text[2][18]="zzzzzzzzzzzzzzzzzzaBczzzzzz"; - text[2][19]="zzzzzzzzzzzzzzzzzzzaBczzzzz"; - text[2][20]="zzzzzzzzzzzzzzzzzzzzaBczzzz"; - text[2][21]="zzzzzzzzzzzzzzzzzzzzzaBczzz"; - text[2][22]="zzzzzzzzzzzzzzzzzzzzzzaBczz"; - text[2][23]="zzzzzzzzzzzzzzzzzzzzzzzaBcz"; - text[2][24]="zzzzzzzzzzzzzzzzzzzzzzzzaBc"; - text[3][0]="aBcDzzzzzzzzzzzzzzzzzzzzzzz"; - text[3][1]="zaBcDzzzzzzzzzzzzzzzzzzzzzz"; - text[3][2]="zzaBcDzzzzzzzzzzzzzzzzzzzzz"; - text[3][3]="zzzaBcDzzzzzzzzzzzzzzzzzzzz"; - text[3][4]="zzzzaBcDzzzzzzzzzzzzzzzzzzz"; - text[3][5]="zzzzzaBcDzzzzzzzzzzzzzzzzzz"; - text[3][6]="zzzzzzaBcDzzzzzzzzzzzzzzzzz"; - text[3][7]="zzzzzzzaBcDzzzzzzzzzzzzzzzz"; - text[3][8]="zzzzzzzzaBcDzzzzzzzzzzzzzzz"; - text[3][9]="zzzzzzzzzaBcDzzzzzzzzzzzzzz"; - text[3][10]="zzzzzzzzzzaBcDzzzzzzzzzzzzz"; - text[3][11]="zzzzzzzzzzzaBcDzzzzzzzzzzzz"; - text[3][12]="zzzzzzzzzzzzaBcDzzzzzzzzzzz"; - text[3][13]="zzzzzzzzzzzzzaBcDzzzzzzzzzz"; - text[3][14]="zzzzzzzzzzzzzzaBcDzzzzzzzzz"; - text[3][15]="zzzzzzzzzzzzzzzaBcDzzzzzzzz"; - text[3][16]="zzzzzzzzzzzzzzzzaBcDzzzzzzz"; - text[3][17]="zzzzzzzzzzzzzzzzzaBcDzzzzzz"; - text[3][18]="zzzzzzzzzzzzzzzzzzaBcDzzzzz"; - text[3][19]="zzzzzzzzzzzzzzzzzzzaBcDzzzz"; - text[3][20]="zzzzzzzzzzzzzzzzzzzzaBcDzzz"; - text[3][21]="zzzzzzzzzzzzzzzzzzzzzaBcDzz"; - text[3][22]="zzzzzzzzzzzzzzzzzzzzzzaBcDz"; - text[3][23]="zzzzzzzzzzzzzzzzzzzzzzzaBcD"; - text[4][0]="aBcDezzzzzzzzzzzzzzzzzzzzzz"; - text[4][1]="zaBcDezzzzzzzzzzzzzzzzzzzzz"; - text[4][2]="zzaBcDezzzzzzzzzzzzzzzzzzzz"; - text[4][3]="zzzaBcDezzzzzzzzzzzzzzzzzzz"; - text[4][4]="zzzzaBcDezzzzzzzzzzzzzzzzzz"; - text[4][5]="zzzzzaBcDezzzzzzzzzzzzzzzzz"; - text[4][6]="zzzzzzaBcDezzzzzzzzzzzzzzzz"; - text[4][7]="zzzzzzzaBcDezzzzzzzzzzzzzzz"; - text[4][8]="zzzzzzzzaBcDezzzzzzzzzzzzzz"; - text[4][9]="zzzzzzzzzaBcDezzzzzzzzzzzzz"; - text[4][10]="zzzzzzzzzzaBcDezzzzzzzzzzzz"; - text[4][11]="zzzzzzzzzzzaBcDezzzzzzzzzzz"; - text[4][12]="zzzzzzzzzzzzaBcDezzzzzzzzzz"; - text[4][13]="zzzzzzzzzzzzzaBcDezzzzzzzzz"; - text[4][14]="zzzzzzzzzzzzzzaBcDezzzzzzzz"; - text[4][15]="zzzzzzzzzzzzzzzaBcDezzzzzzz"; - text[4][16]="zzzzzzzzzzzzzzzzaBcDezzzzzz"; - text[4][17]="zzzzzzzzzzzzzzzzzaBcDezzzzz"; - text[4][18]="zzzzzzzzzzzzzzzzzzaBcDezzzz"; - text[4][19]="zzzzzzzzzzzzzzzzzzzaBcDezzz"; - text[4][20]="zzzzzzzzzzzzzzzzzzzzaBcDezz"; - text[4][21]="zzzzzzzzzzzzzzzzzzzzzaBcDez"; - text[4][22]="zzzzzzzzzzzzzzzzzzzzzzaBcDe"; - text[5][0]="aBcDeFzzzzzzzzzzzzzzzzzzzzz"; - text[5][1]="zaBcDeFzzzzzzzzzzzzzzzzzzzz"; - text[5][2]="zzaBcDeFzzzzzzzzzzzzzzzzzzz"; - text[5][3]="zzzaBcDeFzzzzzzzzzzzzzzzzzz"; - text[5][4]="zzzzaBcDeFzzzzzzzzzzzzzzzzz"; - text[5][5]="zzzzzaBcDeFzzzzzzzzzzzzzzzz"; - text[5][6]="zzzzzzaBcDeFzzzzzzzzzzzzzzz"; - text[5][7]="zzzzzzzaBcDeFzzzzzzzzzzzzzz"; - text[5][8]="zzzzzzzzaBcDeFzzzzzzzzzzzzz"; - text[5][9]="zzzzzzzzzaBcDeFzzzzzzzzzzzz"; - text[5][10]="zzzzzzzzzzaBcDeFzzzzzzzzzzz"; - text[5][11]="zzzzzzzzzzzaBcDeFzzzzzzzzzz"; - text[5][12]="zzzzzzzzzzzzaBcDeFzzzzzzzzz"; - text[5][13]="zzzzzzzzzzzzzaBcDeFzzzzzzzz"; - text[5][14]="zzzzzzzzzzzzzzaBcDeFzzzzzzz"; - text[5][15]="zzzzzzzzzzzzzzzaBcDeFzzzzzz"; - text[5][16]="zzzzzzzzzzzzzzzzaBcDeFzzzzz"; - text[5][17]="zzzzzzzzzzzzzzzzzaBcDeFzzzz"; - text[5][18]="zzzzzzzzzzzzzzzzzzaBcDeFzzz"; - text[5][19]="zzzzzzzzzzzzzzzzzzzaBcDeFzz"; - text[5][20]="zzzzzzzzzzzzzzzzzzzzaBcDeFz"; - text[5][21]="zzzzzzzzzzzzzzzzzzzzzaBcDeF"; - text[6][0]="aBcDeFgzzzzzzzzzzzzzzzzzzzz"; - text[6][1]="zaBcDeFgzzzzzzzzzzzzzzzzzzz"; - text[6][2]="zzaBcDeFgzzzzzzzzzzzzzzzzzz"; - text[6][3]="zzzaBcDeFgzzzzzzzzzzzzzzzzz"; - text[6][4]="zzzzaBcDeFgzzzzzzzzzzzzzzzz"; - text[6][5]="zzzzzaBcDeFgzzzzzzzzzzzzzzz"; - text[6][6]="zzzzzzaBcDeFgzzzzzzzzzzzzzz"; - text[6][7]="zzzzzzzaBcDeFgzzzzzzzzzzzzz"; - text[6][8]="zzzzzzzzaBcDeFgzzzzzzzzzzzz"; - text[6][9]="zzzzzzzzzaBcDeFgzzzzzzzzzzz"; - text[6][10]="zzzzzzzzzzaBcDeFgzzzzzzzzzz"; - text[6][11]="zzzzzzzzzzzaBcDeFgzzzzzzzzz"; - text[6][12]="zzzzzzzzzzzzaBcDeFgzzzzzzzz"; - text[6][13]="zzzzzzzzzzzzzaBcDeFgzzzzzzz"; - text[6][14]="zzzzzzzzzzzzzzaBcDeFgzzzzzz"; - text[6][15]="zzzzzzzzzzzzzzzaBcDeFgzzzzz"; - text[6][16]="zzzzzzzzzzzzzzzzaBcDeFgzzzz"; - text[6][17]="zzzzzzzzzzzzzzzzzaBcDeFgzzz"; - text[6][18]="zzzzzzzzzzzzzzzzzzaBcDeFgzz"; - text[6][19]="zzzzzzzzzzzzzzzzzzzaBcDeFgz"; - text[6][20]="zzzzzzzzzzzzzzzzzzzzaBcDeFg"; - text[7][0]="aBcDeFgHzzzzzzzzzzzzzzzzzzz"; - text[7][1]="zaBcDeFgHzzzzzzzzzzzzzzzzzz"; - text[7][2]="zzaBcDeFgHzzzzzzzzzzzzzzzzz"; - text[7][3]="zzzaBcDeFgHzzzzzzzzzzzzzzzz"; - text[7][4]="zzzzaBcDeFgHzzzzzzzzzzzzzzz"; - text[7][5]="zzzzzaBcDeFgHzzzzzzzzzzzzzz"; - text[7][6]="zzzzzzaBcDeFgHzzzzzzzzzzzzz"; - text[7][7]="zzzzzzzaBcDeFgHzzzzzzzzzzzz"; - text[7][8]="zzzzzzzzaBcDeFgHzzzzzzzzzzz"; - text[7][9]="zzzzzzzzzaBcDeFgHzzzzzzzzzz"; - text[7][10]="zzzzzzzzzzaBcDeFgHzzzzzzzzz"; - text[7][11]="zzzzzzzzzzzaBcDeFgHzzzzzzzz"; - text[7][12]="zzzzzzzzzzzzaBcDeFgHzzzzzzz"; - text[7][13]="zzzzzzzzzzzzzaBcDeFgHzzzzzz"; - text[7][14]="zzzzzzzzzzzzzzaBcDeFgHzzzzz"; - text[7][15]="zzzzzzzzzzzzzzzaBcDeFgHzzzz"; - text[7][16]="zzzzzzzzzzzzzzzzaBcDeFgHzzz"; - text[7][17]="zzzzzzzzzzzzzzzzzaBcDeFgHzz"; - text[7][18]="zzzzzzzzzzzzzzzzzzaBcDeFgHz"; - text[7][19]="zzzzzzzzzzzzzzzzzzzaBcDeFgH"; - text[8][0]="aBcDeFgHizzzzzzzzzzzzzzzzzz"; - text[8][1]="zaBcDeFgHizzzzzzzzzzzzzzzzz"; - text[8][2]="zzaBcDeFgHizzzzzzzzzzzzzzzz"; - text[8][3]="zzzaBcDeFgHizzzzzzzzzzzzzzz"; - text[8][4]="zzzzaBcDeFgHizzzzzzzzzzzzzz"; - text[8][5]="zzzzzaBcDeFgHizzzzzzzzzzzzz"; - text[8][6]="zzzzzzaBcDeFgHizzzzzzzzzzzz"; - text[8][7]="zzzzzzzaBcDeFgHizzzzzzzzzzz"; - text[8][8]="zzzzzzzzaBcDeFgHizzzzzzzzzz"; - text[8][9]="zzzzzzzzzaBcDeFgHizzzzzzzzz"; - text[8][10]="zzzzzzzzzzaBcDeFgHizzzzzzzz"; - text[8][11]="zzzzzzzzzzzaBcDeFgHizzzzzzz"; - text[8][12]="zzzzzzzzzzzzaBcDeFgHizzzzzz"; - text[8][13]="zzzzzzzzzzzzzaBcDeFgHizzzzz"; - text[8][14]="zzzzzzzzzzzzzzaBcDeFgHizzzz"; - text[8][15]="zzzzzzzzzzzzzzzaBcDeFgHizzz"; - text[8][16]="zzzzzzzzzzzzzzzzaBcDeFgHizz"; - text[8][17]="zzzzzzzzzzzzzzzzzaBcDeFgHiz"; - text[8][18]="zzzzzzzzzzzzzzzzzzaBcDeFgHi"; - text[9][0]="aBcDeFgHiJzzzzzzzzzzzzzzzzz"; - text[9][1]="zaBcDeFgHiJzzzzzzzzzzzzzzzz"; - text[9][2]="zzaBcDeFgHiJzzzzzzzzzzzzzzz"; - text[9][3]="zzzaBcDeFgHiJzzzzzzzzzzzzzz"; - text[9][4]="zzzzaBcDeFgHiJzzzzzzzzzzzzz"; - text[9][5]="zzzzzaBcDeFgHiJzzzzzzzzzzzz"; - text[9][6]="zzzzzzaBcDeFgHiJzzzzzzzzzzz"; - text[9][7]="zzzzzzzaBcDeFgHiJzzzzzzzzzz"; - text[9][8]="zzzzzzzzaBcDeFgHiJzzzzzzzzz"; - text[9][9]="zzzzzzzzzaBcDeFgHiJzzzzzzzz"; - text[9][10]="zzzzzzzzzzaBcDeFgHiJzzzzzzz"; - text[9][11]="zzzzzzzzzzzaBcDeFgHiJzzzzzz"; - text[9][12]="zzzzzzzzzzzzaBcDeFgHiJzzzzz"; - text[9][13]="zzzzzzzzzzzzzaBcDeFgHiJzzzz"; - text[9][14]="zzzzzzzzzzzzzzaBcDeFgHiJzzz"; - text[9][15]="zzzzzzzzzzzzzzzaBcDeFgHiJzz"; - text[9][16]="zzzzzzzzzzzzzzzzaBcDeFgHiJz"; - text[9][17]="zzzzzzzzzzzzzzzzzaBcDeFgHiJ"; - text[10][0]="aBcDeFgHiJkzzzzzzzzzzzzzzzz"; - text[10][1]="zaBcDeFgHiJkzzzzzzzzzzzzzzz"; - text[10][2]="zzaBcDeFgHiJkzzzzzzzzzzzzzz"; - text[10][3]="zzzaBcDeFgHiJkzzzzzzzzzzzzz"; - text[10][4]="zzzzaBcDeFgHiJkzzzzzzzzzzzz"; - text[10][5]="zzzzzaBcDeFgHiJkzzzzzzzzzzz"; - text[10][6]="zzzzzzaBcDeFgHiJkzzzzzzzzzz"; - text[10][7]="zzzzzzzaBcDeFgHiJkzzzzzzzzz"; - text[10][8]="zzzzzzzzaBcDeFgHiJkzzzzzzzz"; - text[10][9]="zzzzzzzzzaBcDeFgHiJkzzzzzzz"; - text[10][10]="zzzzzzzzzzaBcDeFgHiJkzzzzzz"; - text[10][11]="zzzzzzzzzzzaBcDeFgHiJkzzzzz"; - text[10][12]="zzzzzzzzzzzzaBcDeFgHiJkzzzz"; - text[10][13]="zzzzzzzzzzzzzaBcDeFgHiJkzzz"; - text[10][14]="zzzzzzzzzzzzzzaBcDeFgHiJkzz"; - text[10][15]="zzzzzzzzzzzzzzzaBcDeFgHiJkz"; - text[10][16]="zzzzzzzzzzzzzzzzaBcDeFgHiJk"; - text[11][0]="aBcDeFgHiJkLzzzzzzzzzzzzzzz"; - text[11][1]="zaBcDeFgHiJkLzzzzzzzzzzzzzz"; - text[11][2]="zzaBcDeFgHiJkLzzzzzzzzzzzzz"; - text[11][3]="zzzaBcDeFgHiJkLzzzzzzzzzzzz"; - text[11][4]="zzzzaBcDeFgHiJkLzzzzzzzzzzz"; - text[11][5]="zzzzzaBcDeFgHiJkLzzzzzzzzzz"; - text[11][6]="zzzzzzaBcDeFgHiJkLzzzzzzzzz"; - text[11][7]="zzzzzzzaBcDeFgHiJkLzzzzzzzz"; - text[11][8]="zzzzzzzzaBcDeFgHiJkLzzzzzzz"; - text[11][9]="zzzzzzzzzaBcDeFgHiJkLzzzzzz"; - text[11][10]="zzzzzzzzzzaBcDeFgHiJkLzzzzz"; - text[11][11]="zzzzzzzzzzzaBcDeFgHiJkLzzzz"; - text[11][12]="zzzzzzzzzzzzaBcDeFgHiJkLzzz"; - text[11][13]="zzzzzzzzzzzzzaBcDeFgHiJkLzz"; - text[11][14]="zzzzzzzzzzzzzzaBcDeFgHiJkLz"; - text[11][15]="zzzzzzzzzzzzzzzaBcDeFgHiJkL"; - text[12][0]="aBcDeFgHiJkLmzzzzzzzzzzzzzz"; - text[12][1]="zaBcDeFgHiJkLmzzzzzzzzzzzzz"; - text[12][2]="zzaBcDeFgHiJkLmzzzzzzzzzzzz"; - text[12][3]="zzzaBcDeFgHiJkLmzzzzzzzzzzz"; - text[12][4]="zzzzaBcDeFgHiJkLmzzzzzzzzzz"; - text[12][5]="zzzzzaBcDeFgHiJkLmzzzzzzzzz"; - text[12][6]="zzzzzzaBcDeFgHiJkLmzzzzzzzz"; - text[12][7]="zzzzzzzaBcDeFgHiJkLmzzzzzzz"; - text[12][8]="zzzzzzzzaBcDeFgHiJkLmzzzzzz"; - text[12][9]="zzzzzzzzzaBcDeFgHiJkLmzzzzz"; - text[12][10]="zzzzzzzzzzaBcDeFgHiJkLmzzzz"; - text[12][11]="zzzzzzzzzzzaBcDeFgHiJkLmzzz"; - text[12][12]="zzzzzzzzzzzzaBcDeFgHiJkLmzz"; - text[12][13]="zzzzzzzzzzzzzaBcDeFgHiJkLmz"; - text[12][14]="zzzzzzzzzzzzzzaBcDeFgHiJkLm"; - text[13][0]="aBcDeFgHiJkLmNzzzzzzzzzzzzz"; - text[13][1]="zaBcDeFgHiJkLmNzzzzzzzzzzzz"; - text[13][2]="zzaBcDeFgHiJkLmNzzzzzzzzzzz"; - text[13][3]="zzzaBcDeFgHiJkLmNzzzzzzzzzz"; - text[13][4]="zzzzaBcDeFgHiJkLmNzzzzzzzzz"; - text[13][5]="zzzzzaBcDeFgHiJkLmNzzzzzzzz"; - text[13][6]="zzzzzzaBcDeFgHiJkLmNzzzzzzz"; - text[13][7]="zzzzzzzaBcDeFgHiJkLmNzzzzzz"; - text[13][8]="zzzzzzzzaBcDeFgHiJkLmNzzzzz"; - text[13][9]="zzzzzzzzzaBcDeFgHiJkLmNzzzz"; - text[13][10]="zzzzzzzzzzaBcDeFgHiJkLmNzzz"; - text[13][11]="zzzzzzzzzzzaBcDeFgHiJkLmNzz"; - text[13][12]="zzzzzzzzzzzzaBcDeFgHiJkLmNz"; - text[13][13]="zzzzzzzzzzzzzaBcDeFgHiJkLmN"; - text[14][0]="aBcDeFgHiJkLmNozzzzzzzzzzzz"; - text[14][1]="zaBcDeFgHiJkLmNozzzzzzzzzzz"; - text[14][2]="zzaBcDeFgHiJkLmNozzzzzzzzzz"; - text[14][3]="zzzaBcDeFgHiJkLmNozzzzzzzzz"; - text[14][4]="zzzzaBcDeFgHiJkLmNozzzzzzzz"; - text[14][5]="zzzzzaBcDeFgHiJkLmNozzzzzzz"; - text[14][6]="zzzzzzaBcDeFgHiJkLmNozzzzzz"; - text[14][7]="zzzzzzzaBcDeFgHiJkLmNozzzzz"; - text[14][8]="zzzzzzzzaBcDeFgHiJkLmNozzzz"; - text[14][9]="zzzzzzzzzaBcDeFgHiJkLmNozzz"; - text[14][10]="zzzzzzzzzzaBcDeFgHiJkLmNozz"; - text[14][11]="zzzzzzzzzzzaBcDeFgHiJkLmNoz"; - text[14][12]="zzzzzzzzzzzzaBcDeFgHiJkLmNo"; - text[15][0]="aBcDeFgHiJkLmNoPzzzzzzzzzzz"; - text[15][1]="zaBcDeFgHiJkLmNoPzzzzzzzzzz"; - text[15][2]="zzaBcDeFgHiJkLmNoPzzzzzzzzz"; - text[15][3]="zzzaBcDeFgHiJkLmNoPzzzzzzzz"; - text[15][4]="zzzzaBcDeFgHiJkLmNoPzzzzzzz"; - text[15][5]="zzzzzaBcDeFgHiJkLmNoPzzzzzz"; - text[15][6]="zzzzzzaBcDeFgHiJkLmNoPzzzzz"; - text[15][7]="zzzzzzzaBcDeFgHiJkLmNoPzzzz"; - text[15][8]="zzzzzzzzaBcDeFgHiJkLmNoPzzz"; - text[15][9]="zzzzzzzzzaBcDeFgHiJkLmNoPzz"; - text[15][10]="zzzzzzzzzzaBcDeFgHiJkLmNoPz"; - text[15][11]="zzzzzzzzzzzaBcDeFgHiJkLmNoP"; - text[16][0]="aBcDeFgHiJkLmNoPqzzzzzzzzzz"; - text[16][1]="zaBcDeFgHiJkLmNoPqzzzzzzzzz"; - text[16][2]="zzaBcDeFgHiJkLmNoPqzzzzzzzz"; - text[16][3]="zzzaBcDeFgHiJkLmNoPqzzzzzzz"; - text[16][4]="zzzzaBcDeFgHiJkLmNoPqzzzzzz"; - text[16][5]="zzzzzaBcDeFgHiJkLmNoPqzzzzz"; - text[16][6]="zzzzzzaBcDeFgHiJkLmNoPqzzzz"; - text[16][7]="zzzzzzzaBcDeFgHiJkLmNoPqzzz"; - text[16][8]="zzzzzzzzaBcDeFgHiJkLmNoPqzz"; - text[16][9]="zzzzzzzzzaBcDeFgHiJkLmNoPqz"; - text[16][10]="zzzzzzzzzzaBcDeFgHiJkLmNoPq"; - text[17][0]="aBcDeFgHiJkLmNoPqRzzzzzzzzz"; - text[17][1]="zaBcDeFgHiJkLmNoPqRzzzzzzzz"; - text[17][2]="zzaBcDeFgHiJkLmNoPqRzzzzzzz"; - text[17][3]="zzzaBcDeFgHiJkLmNoPqRzzzzzz"; - text[17][4]="zzzzaBcDeFgHiJkLmNoPqRzzzzz"; - text[17][5]="zzzzzaBcDeFgHiJkLmNoPqRzzzz"; - text[17][6]="zzzzzzaBcDeFgHiJkLmNoPqRzzz"; - text[17][7]="zzzzzzzaBcDeFgHiJkLmNoPqRzz"; - text[17][8]="zzzzzzzzaBcDeFgHiJkLmNoPqRz"; - text[17][9]="zzzzzzzzzaBcDeFgHiJkLmNoPqR"; - text[18][0]="aBcDeFgHiJkLmNoPqRszzzzzzzz"; - text[18][1]="zaBcDeFgHiJkLmNoPqRszzzzzzz"; - text[18][2]="zzaBcDeFgHiJkLmNoPqRszzzzzz"; - text[18][3]="zzzaBcDeFgHiJkLmNoPqRszzzzz"; - text[18][4]="zzzzaBcDeFgHiJkLmNoPqRszzzz"; - text[18][5]="zzzzzaBcDeFgHiJkLmNoPqRszzz"; - text[18][6]="zzzzzzaBcDeFgHiJkLmNoPqRszz"; - text[18][7]="zzzzzzzaBcDeFgHiJkLmNoPqRsz"; - text[18][8]="zzzzzzzzaBcDeFgHiJkLmNoPqRs"; - text[19][0]="aBcDeFgHiJkLmNoPqRsTzzzzzzz"; - text[19][1]="zaBcDeFgHiJkLmNoPqRsTzzzzzz"; - text[19][2]="zzaBcDeFgHiJkLmNoPqRsTzzzzz"; - text[19][3]="zzzaBcDeFgHiJkLmNoPqRsTzzzz"; - text[19][4]="zzzzaBcDeFgHiJkLmNoPqRsTzzz"; - text[19][5]="zzzzzaBcDeFgHiJkLmNoPqRsTzz"; - text[19][6]="zzzzzzaBcDeFgHiJkLmNoPqRsTz"; - text[19][7]="zzzzzzzaBcDeFgHiJkLmNoPqRsT"; - text[20][0]="aBcDeFgHiJkLmNoPqRsTuzzzzzz"; - text[20][1]="zaBcDeFgHiJkLmNoPqRsTuzzzzz"; - text[20][2]="zzaBcDeFgHiJkLmNoPqRsTuzzzz"; - text[20][3]="zzzaBcDeFgHiJkLmNoPqRsTuzzz"; - text[20][4]="zzzzaBcDeFgHiJkLmNoPqRsTuzz"; - text[20][5]="zzzzzaBcDeFgHiJkLmNoPqRsTuz"; - text[20][6]="zzzzzzaBcDeFgHiJkLmNoPqRsTu"; - text[21][0]="aBcDeFgHiJkLmNoPqRsTuVzzzzz"; - text[21][1]="zaBcDeFgHiJkLmNoPqRsTuVzzzz"; - text[21][2]="zzaBcDeFgHiJkLmNoPqRsTuVzzz"; - text[21][3]="zzzaBcDeFgHiJkLmNoPqRsTuVzz"; - text[21][4]="zzzzaBcDeFgHiJkLmNoPqRsTuVz"; - text[21][5]="zzzzzaBcDeFgHiJkLmNoPqRsTuV"; - text[22][0]="aBcDeFgHiJkLmNoPqRsTuVwzzzz"; - text[22][1]="zaBcDeFgHiJkLmNoPqRsTuVwzzz"; - text[22][2]="zzaBcDeFgHiJkLmNoPqRsTuVwzz"; - text[22][3]="zzzaBcDeFgHiJkLmNoPqRsTuVwz"; - text[22][4]="zzzzaBcDeFgHiJkLmNoPqRsTuVw"; - text[23][0]="aBcDeFgHiJkLmNoPqRsTuVwXzzz"; - text[23][1]="zaBcDeFgHiJkLmNoPqRsTuVwXzz"; - text[23][2]="zzaBcDeFgHiJkLmNoPqRsTuVwXz"; - text[23][3]="zzzaBcDeFgHiJkLmNoPqRsTuVwX"; - text[24][0]="aBcDeFgHiJkLmNoPqRsTuVwXyzz"; - text[24][1]="zaBcDeFgHiJkLmNoPqRsTuVwXyz"; - text[24][2]="zzaBcDeFgHiJkLmNoPqRsTuVwXy"; - text[25][0]="aBcDeFgHiJkLmNoPqRsTuVwXyZz"; - text[25][1]="zaBcDeFgHiJkLmNoPqRsTuVwXyZ"; - - char *needle[26]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - needle[16]="aBcDeFgHiJkLmNoPq"; - needle[17]="aBcDeFgHiJkLmNoPqR"; - needle[18]="aBcDeFgHiJkLmNoPqRs"; - needle[19]="aBcDeFgHiJkLmNoPqRsT"; - needle[20]="aBcDeFgHiJkLmNoPqRsTu"; - needle[21]="aBcDeFgHiJkLmNoPqRsTuV"; - needle[22]="aBcDeFgHiJkLmNoPqRsTuVw"; - needle[23]="aBcDeFgHiJkLmNoPqRsTuVwX"; - needle[24]="aBcDeFgHiJkLmNoPqRsTuVwXy"; - needle[25]="aBcDeFgHiJkLmNoPqRsTuVwXyZ"; - - int i, j; - uint8_t *found = NULL; - for (i = 0; i < 26; i++) { - for (j = 0; j <= (26 - i); j++) { - found = BasicSearchWrapper((uint8_t *)text[i][j], (uint8_t *)needle[i], 1); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i][j]); - return 0; - } - found = Bs2bmWrapper((uint8_t *)text[i][j], (uint8_t *)needle[i], 1); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i][j]); - return 0; - } - found = BoyerMooreWrapper((uint8_t *)text[i][j], (uint8_t *)needle[i], 1); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i][j]); - return 0; - } - } - } - return 1; -} - -/** - * \test Check that all the algorithms (no case) work at any offset and any pattern length - */ -int UtilSpmSearchOffsetsNocaseTest01() -{ - char *text[26][27]; - text[0][0]="azzzzzzzzzzzzzzzzzzzzzzzzzz"; - text[0][1]="zazzzzzzzzzzzzzzzzzzzzzzzzz"; - text[0][2]="zzazzzzzzzzzzzzzzzzzzzzzzzz"; - text[0][3]="zzzazzzzzzzzzzzzzzzzzzzzzzz"; - text[0][4]="zzzzazzzzzzzzzzzzzzzzzzzzzz"; - text[0][5]="zzzzzazzzzzzzzzzzzzzzzzzzzz"; - text[0][6]="zzzzzzazzzzzzzzzzzzzzzzzzzz"; - text[0][7]="zzzzzzzazzzzzzzzzzzzzzzzzzz"; - text[0][8]="zzzzzzzzazzzzzzzzzzzzzzzzzz"; - text[0][9]="zzzzzzzzzazzzzzzzzzzzzzzzzz"; - text[0][10]="zzzzzzzzzzazzzzzzzzzzzzzzzz"; - text[0][11]="zzzzzzzzzzzazzzzzzzzzzzzzzz"; - text[0][12]="zzzzzzzzzzzzazzzzzzzzzzzzzz"; - text[0][13]="zzzzzzzzzzzzzazzzzzzzzzzzzz"; - text[0][14]="zzzzzzzzzzzzzzazzzzzzzzzzzz"; - text[0][15]="zzzzzzzzzzzzzzzazzzzzzzzzzz"; - text[0][16]="zzzzzzzzzzzzzzzzazzzzzzzzzz"; - text[0][17]="zzzzzzzzzzzzzzzzzazzzzzzzzz"; - text[0][18]="zzzzzzzzzzzzzzzzzzazzzzzzzz"; - text[0][19]="zzzzzzzzzzzzzzzzzzzazzzzzzz"; - text[0][20]="zzzzzzzzzzzzzzzzzzzzazzzzzz"; - text[0][21]="zzzzzzzzzzzzzzzzzzzzzazzzzz"; - text[0][22]="zzzzzzzzzzzzzzzzzzzzzzazzzz"; - text[0][23]="zzzzzzzzzzzzzzzzzzzzzzzazzz"; - text[0][24]="zzzzzzzzzzzzzzzzzzzzzzzzazz"; - text[0][25]="zzzzzzzzzzzzzzzzzzzzzzzzzaz"; - text[0][26]="zzzzzzzzzzzzzzzzzzzzzzzzzza"; - text[1][0]="aBzzzzzzzzzzzzzzzzzzzzzzzzz"; - text[1][1]="zaBzzzzzzzzzzzzzzzzzzzzzzzz"; - text[1][2]="zzaBzzzzzzzzzzzzzzzzzzzzzzz"; - text[1][3]="zzzaBzzzzzzzzzzzzzzzzzzzzzz"; - text[1][4]="zzzzaBzzzzzzzzzzzzzzzzzzzzz"; - text[1][5]="zzzzzaBzzzzzzzzzzzzzzzzzzzz"; - text[1][6]="zzzzzzaBzzzzzzzzzzzzzzzzzzz"; - text[1][7]="zzzzzzzaBzzzzzzzzzzzzzzzzzz"; - text[1][8]="zzzzzzzzaBzzzzzzzzzzzzzzzzz"; - text[1][9]="zzzzzzzzzaBzzzzzzzzzzzzzzzz"; - text[1][10]="zzzzzzzzzzaBzzzzzzzzzzzzzzz"; - text[1][11]="zzzzzzzzzzzaBzzzzzzzzzzzzzz"; - text[1][12]="zzzzzzzzzzzzaBzzzzzzzzzzzzz"; - text[1][13]="zzzzzzzzzzzzzaBzzzzzzzzzzzz"; - text[1][14]="zzzzzzzzzzzzzzaBzzzzzzzzzzz"; - text[1][15]="zzzzzzzzzzzzzzzaBzzzzzzzzzz"; - text[1][16]="zzzzzzzzzzzzzzzzaBzzzzzzzzz"; - text[1][17]="zzzzzzzzzzzzzzzzzaBzzzzzzzz"; - text[1][18]="zzzzzzzzzzzzzzzzzzaBzzzzzzz"; - text[1][19]="zzzzzzzzzzzzzzzzzzzaBzzzzzz"; - text[1][20]="zzzzzzzzzzzzzzzzzzzzaBzzzzz"; - text[1][21]="zzzzzzzzzzzzzzzzzzzzzaBzzzz"; - text[1][22]="zzzzzzzzzzzzzzzzzzzzzzaBzzz"; - text[1][23]="zzzzzzzzzzzzzzzzzzzzzzzaBzz"; - text[1][24]="zzzzzzzzzzzzzzzzzzzzzzzzaBz"; - text[1][25]="zzzzzzzzzzzzzzzzzzzzzzzzzaB"; - text[2][0]="aBczzzzzzzzzzzzzzzzzzzzzzzz"; - text[2][1]="zaBczzzzzzzzzzzzzzzzzzzzzzz"; - text[2][2]="zzaBczzzzzzzzzzzzzzzzzzzzzz"; - text[2][3]="zzzaBczzzzzzzzzzzzzzzzzzzzz"; - text[2][4]="zzzzaBczzzzzzzzzzzzzzzzzzzz"; - text[2][5]="zzzzzaBczzzzzzzzzzzzzzzzzzz"; - text[2][6]="zzzzzzaBczzzzzzzzzzzzzzzzzz"; - text[2][7]="zzzzzzzaBczzzzzzzzzzzzzzzzz"; - text[2][8]="zzzzzzzzaBczzzzzzzzzzzzzzzz"; - text[2][9]="zzzzzzzzzaBczzzzzzzzzzzzzzz"; - text[2][10]="zzzzzzzzzzaBczzzzzzzzzzzzzz"; - text[2][11]="zzzzzzzzzzzaBczzzzzzzzzzzzz"; - text[2][12]="zzzzzzzzzzzzaBczzzzzzzzzzzz"; - text[2][13]="zzzzzzzzzzzzzaBczzzzzzzzzzz"; - text[2][14]="zzzzzzzzzzzzzzaBczzzzzzzzzz"; - text[2][15]="zzzzzzzzzzzzzzzaBczzzzzzzzz"; - text[2][16]="zzzzzzzzzzzzzzzzaBczzzzzzzz"; - text[2][17]="zzzzzzzzzzzzzzzzzaBczzzzzzz"; - text[2][18]="zzzzzzzzzzzzzzzzzzaBczzzzzz"; - text[2][19]="zzzzzzzzzzzzzzzzzzzaBczzzzz"; - text[2][20]="zzzzzzzzzzzzzzzzzzzzaBczzzz"; - text[2][21]="zzzzzzzzzzzzzzzzzzzzzaBczzz"; - text[2][22]="zzzzzzzzzzzzzzzzzzzzzzaBczz"; - text[2][23]="zzzzzzzzzzzzzzzzzzzzzzzaBcz"; - text[2][24]="zzzzzzzzzzzzzzzzzzzzzzzzaBc"; - text[3][0]="aBcDzzzzzzzzzzzzzzzzzzzzzzz"; - text[3][1]="zaBcDzzzzzzzzzzzzzzzzzzzzzz"; - text[3][2]="zzaBcDzzzzzzzzzzzzzzzzzzzzz"; - text[3][3]="zzzaBcDzzzzzzzzzzzzzzzzzzzz"; - text[3][4]="zzzzaBcDzzzzzzzzzzzzzzzzzzz"; - text[3][5]="zzzzzaBcDzzzzzzzzzzzzzzzzzz"; - text[3][6]="zzzzzzaBcDzzzzzzzzzzzzzzzzz"; - text[3][7]="zzzzzzzaBcDzzzzzzzzzzzzzzzz"; - text[3][8]="zzzzzzzzaBcDzzzzzzzzzzzzzzz"; - text[3][9]="zzzzzzzzzaBcDzzzzzzzzzzzzzz"; - text[3][10]="zzzzzzzzzzaBcDzzzzzzzzzzzzz"; - text[3][11]="zzzzzzzzzzzaBcDzzzzzzzzzzzz"; - text[3][12]="zzzzzzzzzzzzaBcDzzzzzzzzzzz"; - text[3][13]="zzzzzzzzzzzzzaBcDzzzzzzzzzz"; - text[3][14]="zzzzzzzzzzzzzzaBcDzzzzzzzzz"; - text[3][15]="zzzzzzzzzzzzzzzaBcDzzzzzzzz"; - text[3][16]="zzzzzzzzzzzzzzzzaBcDzzzzzzz"; - text[3][17]="zzzzzzzzzzzzzzzzzaBcDzzzzzz"; - text[3][18]="zzzzzzzzzzzzzzzzzzaBcDzzzzz"; - text[3][19]="zzzzzzzzzzzzzzzzzzzaBcDzzzz"; - text[3][20]="zzzzzzzzzzzzzzzzzzzzaBcDzzz"; - text[3][21]="zzzzzzzzzzzzzzzzzzzzzaBcDzz"; - text[3][22]="zzzzzzzzzzzzzzzzzzzzzzaBcDz"; - text[3][23]="zzzzzzzzzzzzzzzzzzzzzzzaBcD"; - text[4][0]="aBcDezzzzzzzzzzzzzzzzzzzzzz"; - text[4][1]="zaBcDezzzzzzzzzzzzzzzzzzzzz"; - text[4][2]="zzaBcDezzzzzzzzzzzzzzzzzzzz"; - text[4][3]="zzzaBcDezzzzzzzzzzzzzzzzzzz"; - text[4][4]="zzzzaBcDezzzzzzzzzzzzzzzzzz"; - text[4][5]="zzzzzaBcDezzzzzzzzzzzzzzzzz"; - text[4][6]="zzzzzzaBcDezzzzzzzzzzzzzzzz"; - text[4][7]="zzzzzzzaBcDezzzzzzzzzzzzzzz"; - text[4][8]="zzzzzzzzaBcDezzzzzzzzzzzzzz"; - text[4][9]="zzzzzzzzzaBcDezzzzzzzzzzzzz"; - text[4][10]="zzzzzzzzzzaBcDezzzzzzzzzzzz"; - text[4][11]="zzzzzzzzzzzaBcDezzzzzzzzzzz"; - text[4][12]="zzzzzzzzzzzzaBcDezzzzzzzzzz"; - text[4][13]="zzzzzzzzzzzzzaBcDezzzzzzzzz"; - text[4][14]="zzzzzzzzzzzzzzaBcDezzzzzzzz"; - text[4][15]="zzzzzzzzzzzzzzzaBcDezzzzzzz"; - text[4][16]="zzzzzzzzzzzzzzzzaBcDezzzzzz"; - text[4][17]="zzzzzzzzzzzzzzzzzaBcDezzzzz"; - text[4][18]="zzzzzzzzzzzzzzzzzzaBcDezzzz"; - text[4][19]="zzzzzzzzzzzzzzzzzzzaBcDezzz"; - text[4][20]="zzzzzzzzzzzzzzzzzzzzaBcDezz"; - text[4][21]="zzzzzzzzzzzzzzzzzzzzzaBcDez"; - text[4][22]="zzzzzzzzzzzzzzzzzzzzzzaBcDe"; - text[5][0]="aBcDeFzzzzzzzzzzzzzzzzzzzzz"; - text[5][1]="zaBcDeFzzzzzzzzzzzzzzzzzzzz"; - text[5][2]="zzaBcDeFzzzzzzzzzzzzzzzzzzz"; - text[5][3]="zzzaBcDeFzzzzzzzzzzzzzzzzzz"; - text[5][4]="zzzzaBcDeFzzzzzzzzzzzzzzzzz"; - text[5][5]="zzzzzaBcDeFzzzzzzzzzzzzzzzz"; - text[5][6]="zzzzzzaBcDeFzzzzzzzzzzzzzzz"; - text[5][7]="zzzzzzzaBcDeFzzzzzzzzzzzzzz"; - text[5][8]="zzzzzzzzaBcDeFzzzzzzzzzzzzz"; - text[5][9]="zzzzzzzzzaBcDeFzzzzzzzzzzzz"; - text[5][10]="zzzzzzzzzzaBcDeFzzzzzzzzzzz"; - text[5][11]="zzzzzzzzzzzaBcDeFzzzzzzzzzz"; - text[5][12]="zzzzzzzzzzzzaBcDeFzzzzzzzzz"; - text[5][13]="zzzzzzzzzzzzzaBcDeFzzzzzzzz"; - text[5][14]="zzzzzzzzzzzzzzaBcDeFzzzzzzz"; - text[5][15]="zzzzzzzzzzzzzzzaBcDeFzzzzzz"; - text[5][16]="zzzzzzzzzzzzzzzzaBcDeFzzzzz"; - text[5][17]="zzzzzzzzzzzzzzzzzaBcDeFzzzz"; - text[5][18]="zzzzzzzzzzzzzzzzzzaBcDeFzzz"; - text[5][19]="zzzzzzzzzzzzzzzzzzzaBcDeFzz"; - text[5][20]="zzzzzzzzzzzzzzzzzzzzaBcDeFz"; - text[5][21]="zzzzzzzzzzzzzzzzzzzzzaBcDeF"; - text[6][0]="aBcDeFgzzzzzzzzzzzzzzzzzzzz"; - text[6][1]="zaBcDeFgzzzzzzzzzzzzzzzzzzz"; - text[6][2]="zzaBcDeFgzzzzzzzzzzzzzzzzzz"; - text[6][3]="zzzaBcDeFgzzzzzzzzzzzzzzzzz"; - text[6][4]="zzzzaBcDeFgzzzzzzzzzzzzzzzz"; - text[6][5]="zzzzzaBcDeFgzzzzzzzzzzzzzzz"; - text[6][6]="zzzzzzaBcDeFgzzzzzzzzzzzzzz"; - text[6][7]="zzzzzzzaBcDeFgzzzzzzzzzzzzz"; - text[6][8]="zzzzzzzzaBcDeFgzzzzzzzzzzzz"; - text[6][9]="zzzzzzzzzaBcDeFgzzzzzzzzzzz"; - text[6][10]="zzzzzzzzzzaBcDeFgzzzzzzzzzz"; - text[6][11]="zzzzzzzzzzzaBcDeFgzzzzzzzzz"; - text[6][12]="zzzzzzzzzzzzaBcDeFgzzzzzzzz"; - text[6][13]="zzzzzzzzzzzzzaBcDeFgzzzzzzz"; - text[6][14]="zzzzzzzzzzzzzzaBcDeFgzzzzzz"; - text[6][15]="zzzzzzzzzzzzzzzaBcDeFgzzzzz"; - text[6][16]="zzzzzzzzzzzzzzzzaBcDeFgzzzz"; - text[6][17]="zzzzzzzzzzzzzzzzzaBcDeFgzzz"; - text[6][18]="zzzzzzzzzzzzzzzzzzaBcDeFgzz"; - text[6][19]="zzzzzzzzzzzzzzzzzzzaBcDeFgz"; - text[6][20]="zzzzzzzzzzzzzzzzzzzzaBcDeFg"; - text[7][0]="aBcDeFgHzzzzzzzzzzzzzzzzzzz"; - text[7][1]="zaBcDeFgHzzzzzzzzzzzzzzzzzz"; - text[7][2]="zzaBcDeFgHzzzzzzzzzzzzzzzzz"; - text[7][3]="zzzaBcDeFgHzzzzzzzzzzzzzzzz"; - text[7][4]="zzzzaBcDeFgHzzzzzzzzzzzzzzz"; - text[7][5]="zzzzzaBcDeFgHzzzzzzzzzzzzzz"; - text[7][6]="zzzzzzaBcDeFgHzzzzzzzzzzzzz"; - text[7][7]="zzzzzzzaBcDeFgHzzzzzzzzzzzz"; - text[7][8]="zzzzzzzzaBcDeFgHzzzzzzzzzzz"; - text[7][9]="zzzzzzzzzaBcDeFgHzzzzzzzzzz"; - text[7][10]="zzzzzzzzzzaBcDeFgHzzzzzzzzz"; - text[7][11]="zzzzzzzzzzzaBcDeFgHzzzzzzzz"; - text[7][12]="zzzzzzzzzzzzaBcDeFgHzzzzzzz"; - text[7][13]="zzzzzzzzzzzzzaBcDeFgHzzzzzz"; - text[7][14]="zzzzzzzzzzzzzzaBcDeFgHzzzzz"; - text[7][15]="zzzzzzzzzzzzzzzaBcDeFgHzzzz"; - text[7][16]="zzzzzzzzzzzzzzzzaBcDeFgHzzz"; - text[7][17]="zzzzzzzzzzzzzzzzzaBcDeFgHzz"; - text[7][18]="zzzzzzzzzzzzzzzzzzaBcDeFgHz"; - text[7][19]="zzzzzzzzzzzzzzzzzzzaBcDeFgH"; - text[8][0]="aBcDeFgHizzzzzzzzzzzzzzzzzz"; - text[8][1]="zaBcDeFgHizzzzzzzzzzzzzzzzz"; - text[8][2]="zzaBcDeFgHizzzzzzzzzzzzzzzz"; - text[8][3]="zzzaBcDeFgHizzzzzzzzzzzzzzz"; - text[8][4]="zzzzaBcDeFgHizzzzzzzzzzzzzz"; - text[8][5]="zzzzzaBcDeFgHizzzzzzzzzzzzz"; - text[8][6]="zzzzzzaBcDeFgHizzzzzzzzzzzz"; - text[8][7]="zzzzzzzaBcDeFgHizzzzzzzzzzz"; - text[8][8]="zzzzzzzzaBcDeFgHizzzzzzzzzz"; - text[8][9]="zzzzzzzzzaBcDeFgHizzzzzzzzz"; - text[8][10]="zzzzzzzzzzaBcDeFgHizzzzzzzz"; - text[8][11]="zzzzzzzzzzzaBcDeFgHizzzzzzz"; - text[8][12]="zzzzzzzzzzzzaBcDeFgHizzzzzz"; - text[8][13]="zzzzzzzzzzzzzaBcDeFgHizzzzz"; - text[8][14]="zzzzzzzzzzzzzzaBcDeFgHizzzz"; - text[8][15]="zzzzzzzzzzzzzzzaBcDeFgHizzz"; - text[8][16]="zzzzzzzzzzzzzzzzaBcDeFgHizz"; - text[8][17]="zzzzzzzzzzzzzzzzzaBcDeFgHiz"; - text[8][18]="zzzzzzzzzzzzzzzzzzaBcDeFgHi"; - text[9][0]="aBcDeFgHiJzzzzzzzzzzzzzzzzz"; - text[9][1]="zaBcDeFgHiJzzzzzzzzzzzzzzzz"; - text[9][2]="zzaBcDeFgHiJzzzzzzzzzzzzzzz"; - text[9][3]="zzzaBcDeFgHiJzzzzzzzzzzzzzz"; - text[9][4]="zzzzaBcDeFgHiJzzzzzzzzzzzzz"; - text[9][5]="zzzzzaBcDeFgHiJzzzzzzzzzzzz"; - text[9][6]="zzzzzzaBcDeFgHiJzzzzzzzzzzz"; - text[9][7]="zzzzzzzaBcDeFgHiJzzzzzzzzzz"; - text[9][8]="zzzzzzzzaBcDeFgHiJzzzzzzzzz"; - text[9][9]="zzzzzzzzzaBcDeFgHiJzzzzzzzz"; - text[9][10]="zzzzzzzzzzaBcDeFgHiJzzzzzzz"; - text[9][11]="zzzzzzzzzzzaBcDeFgHiJzzzzzz"; - text[9][12]="zzzzzzzzzzzzaBcDeFgHiJzzzzz"; - text[9][13]="zzzzzzzzzzzzzaBcDeFgHiJzzzz"; - text[9][14]="zzzzzzzzzzzzzzaBcDeFgHiJzzz"; - text[9][15]="zzzzzzzzzzzzzzzaBcDeFgHiJzz"; - text[9][16]="zzzzzzzzzzzzzzzzaBcDeFgHiJz"; - text[9][17]="zzzzzzzzzzzzzzzzzaBcDeFgHiJ"; - text[10][0]="aBcDeFgHiJkzzzzzzzzzzzzzzzz"; - text[10][1]="zaBcDeFgHiJkzzzzzzzzzzzzzzz"; - text[10][2]="zzaBcDeFgHiJkzzzzzzzzzzzzzz"; - text[10][3]="zzzaBcDeFgHiJkzzzzzzzzzzzzz"; - text[10][4]="zzzzaBcDeFgHiJkzzzzzzzzzzzz"; - text[10][5]="zzzzzaBcDeFgHiJkzzzzzzzzzzz"; - text[10][6]="zzzzzzaBcDeFgHiJkzzzzzzzzzz"; - text[10][7]="zzzzzzzaBcDeFgHiJkzzzzzzzzz"; - text[10][8]="zzzzzzzzaBcDeFgHiJkzzzzzzzz"; - text[10][9]="zzzzzzzzzaBcDeFgHiJkzzzzzzz"; - text[10][10]="zzzzzzzzzzaBcDeFgHiJkzzzzzz"; - text[10][11]="zzzzzzzzzzzaBcDeFgHiJkzzzzz"; - text[10][12]="zzzzzzzzzzzzaBcDeFgHiJkzzzz"; - text[10][13]="zzzzzzzzzzzzzaBcDeFgHiJkzzz"; - text[10][14]="zzzzzzzzzzzzzzaBcDeFgHiJkzz"; - text[10][15]="zzzzzzzzzzzzzzzaBcDeFgHiJkz"; - text[10][16]="zzzzzzzzzzzzzzzzaBcDeFgHiJk"; - text[11][0]="aBcDeFgHiJkLzzzzzzzzzzzzzzz"; - text[11][1]="zaBcDeFgHiJkLzzzzzzzzzzzzzz"; - text[11][2]="zzaBcDeFgHiJkLzzzzzzzzzzzzz"; - text[11][3]="zzzaBcDeFgHiJkLzzzzzzzzzzzz"; - text[11][4]="zzzzaBcDeFgHiJkLzzzzzzzzzzz"; - text[11][5]="zzzzzaBcDeFgHiJkLzzzzzzzzzz"; - text[11][6]="zzzzzzaBcDeFgHiJkLzzzzzzzzz"; - text[11][7]="zzzzzzzaBcDeFgHiJkLzzzzzzzz"; - text[11][8]="zzzzzzzzaBcDeFgHiJkLzzzzzzz"; - text[11][9]="zzzzzzzzzaBcDeFgHiJkLzzzzzz"; - text[11][10]="zzzzzzzzzzaBcDeFgHiJkLzzzzz"; - text[11][11]="zzzzzzzzzzzaBcDeFgHiJkLzzzz"; - text[11][12]="zzzzzzzzzzzzaBcDeFgHiJkLzzz"; - text[11][13]="zzzzzzzzzzzzzaBcDeFgHiJkLzz"; - text[11][14]="zzzzzzzzzzzzzzaBcDeFgHiJkLz"; - text[11][15]="zzzzzzzzzzzzzzzaBcDeFgHiJkL"; - text[12][0]="aBcDeFgHiJkLmzzzzzzzzzzzzzz"; - text[12][1]="zaBcDeFgHiJkLmzzzzzzzzzzzzz"; - text[12][2]="zzaBcDeFgHiJkLmzzzzzzzzzzzz"; - text[12][3]="zzzaBcDeFgHiJkLmzzzzzzzzzzz"; - text[12][4]="zzzzaBcDeFgHiJkLmzzzzzzzzzz"; - text[12][5]="zzzzzaBcDeFgHiJkLmzzzzzzzzz"; - text[12][6]="zzzzzzaBcDeFgHiJkLmzzzzzzzz"; - text[12][7]="zzzzzzzaBcDeFgHiJkLmzzzzzzz"; - text[12][8]="zzzzzzzzaBcDeFgHiJkLmzzzzzz"; - text[12][9]="zzzzzzzzzaBcDeFgHiJkLmzzzzz"; - text[12][10]="zzzzzzzzzzaBcDeFgHiJkLmzzzz"; - text[12][11]="zzzzzzzzzzzaBcDeFgHiJkLmzzz"; - text[12][12]="zzzzzzzzzzzzaBcDeFgHiJkLmzz"; - text[12][13]="zzzzzzzzzzzzzaBcDeFgHiJkLmz"; - text[12][14]="zzzzzzzzzzzzzzaBcDeFgHiJkLm"; - text[13][0]="aBcDeFgHiJkLmNzzzzzzzzzzzzz"; - text[13][1]="zaBcDeFgHiJkLmNzzzzzzzzzzzz"; - text[13][2]="zzaBcDeFgHiJkLmNzzzzzzzzzzz"; - text[13][3]="zzzaBcDeFgHiJkLmNzzzzzzzzzz"; - text[13][4]="zzzzaBcDeFgHiJkLmNzzzzzzzzz"; - text[13][5]="zzzzzaBcDeFgHiJkLmNzzzzzzzz"; - text[13][6]="zzzzzzaBcDeFgHiJkLmNzzzzzzz"; - text[13][7]="zzzzzzzaBcDeFgHiJkLmNzzzzzz"; - text[13][8]="zzzzzzzzaBcDeFgHiJkLmNzzzzz"; - text[13][9]="zzzzzzzzzaBcDeFgHiJkLmNzzzz"; - text[13][10]="zzzzzzzzzzaBcDeFgHiJkLmNzzz"; - text[13][11]="zzzzzzzzzzzaBcDeFgHiJkLmNzz"; - text[13][12]="zzzzzzzzzzzzaBcDeFgHiJkLmNz"; - text[13][13]="zzzzzzzzzzzzzaBcDeFgHiJkLmN"; - text[14][0]="aBcDeFgHiJkLmNozzzzzzzzzzzz"; - text[14][1]="zaBcDeFgHiJkLmNozzzzzzzzzzz"; - text[14][2]="zzaBcDeFgHiJkLmNozzzzzzzzzz"; - text[14][3]="zzzaBcDeFgHiJkLmNozzzzzzzzz"; - text[14][4]="zzzzaBcDeFgHiJkLmNozzzzzzzz"; - text[14][5]="zzzzzaBcDeFgHiJkLmNozzzzzzz"; - text[14][6]="zzzzzzaBcDeFgHiJkLmNozzzzzz"; - text[14][7]="zzzzzzzaBcDeFgHiJkLmNozzzzz"; - text[14][8]="zzzzzzzzaBcDeFgHiJkLmNozzzz"; - text[14][9]="zzzzzzzzzaBcDeFgHiJkLmNozzz"; - text[14][10]="zzzzzzzzzzaBcDeFgHiJkLmNozz"; - text[14][11]="zzzzzzzzzzzaBcDeFgHiJkLmNoz"; - text[14][12]="zzzzzzzzzzzzaBcDeFgHiJkLmNo"; - text[15][0]="aBcDeFgHiJkLmNoPzzzzzzzzzzz"; - text[15][1]="zaBcDeFgHiJkLmNoPzzzzzzzzzz"; - text[15][2]="zzaBcDeFgHiJkLmNoPzzzzzzzzz"; - text[15][3]="zzzaBcDeFgHiJkLmNoPzzzzzzzz"; - text[15][4]="zzzzaBcDeFgHiJkLmNoPzzzzzzz"; - text[15][5]="zzzzzaBcDeFgHiJkLmNoPzzzzzz"; - text[15][6]="zzzzzzaBcDeFgHiJkLmNoPzzzzz"; - text[15][7]="zzzzzzzaBcDeFgHiJkLmNoPzzzz"; - text[15][8]="zzzzzzzzaBcDeFgHiJkLmNoPzzz"; - text[15][9]="zzzzzzzzzaBcDeFgHiJkLmNoPzz"; - text[15][10]="zzzzzzzzzzaBcDeFgHiJkLmNoPz"; - text[15][11]="zzzzzzzzzzzaBcDeFgHiJkLmNoP"; - text[16][0]="aBcDeFgHiJkLmNoPqzzzzzzzzzz"; - text[16][1]="zaBcDeFgHiJkLmNoPqzzzzzzzzz"; - text[16][2]="zzaBcDeFgHiJkLmNoPqzzzzzzzz"; - text[16][3]="zzzaBcDeFgHiJkLmNoPqzzzzzzz"; - text[16][4]="zzzzaBcDeFgHiJkLmNoPqzzzzzz"; - text[16][5]="zzzzzaBcDeFgHiJkLmNoPqzzzzz"; - text[16][6]="zzzzzzaBcDeFgHiJkLmNoPqzzzz"; - text[16][7]="zzzzzzzaBcDeFgHiJkLmNoPqzzz"; - text[16][8]="zzzzzzzzaBcDeFgHiJkLmNoPqzz"; - text[16][9]="zzzzzzzzzaBcDeFgHiJkLmNoPqz"; - text[16][10]="zzzzzzzzzzaBcDeFgHiJkLmNoPq"; - text[17][0]="aBcDeFgHiJkLmNoPqRzzzzzzzzz"; - text[17][1]="zaBcDeFgHiJkLmNoPqRzzzzzzzz"; - text[17][2]="zzaBcDeFgHiJkLmNoPqRzzzzzzz"; - text[17][3]="zzzaBcDeFgHiJkLmNoPqRzzzzzz"; - text[17][4]="zzzzaBcDeFgHiJkLmNoPqRzzzzz"; - text[17][5]="zzzzzaBcDeFgHiJkLmNoPqRzzzz"; - text[17][6]="zzzzzzaBcDeFgHiJkLmNoPqRzzz"; - text[17][7]="zzzzzzzaBcDeFgHiJkLmNoPqRzz"; - text[17][8]="zzzzzzzzaBcDeFgHiJkLmNoPqRz"; - text[17][9]="zzzzzzzzzaBcDeFgHiJkLmNoPqR"; - text[18][0]="aBcDeFgHiJkLmNoPqRszzzzzzzz"; - text[18][1]="zaBcDeFgHiJkLmNoPqRszzzzzzz"; - text[18][2]="zzaBcDeFgHiJkLmNoPqRszzzzzz"; - text[18][3]="zzzaBcDeFgHiJkLmNoPqRszzzzz"; - text[18][4]="zzzzaBcDeFgHiJkLmNoPqRszzzz"; - text[18][5]="zzzzzaBcDeFgHiJkLmNoPqRszzz"; - text[18][6]="zzzzzzaBcDeFgHiJkLmNoPqRszz"; - text[18][7]="zzzzzzzaBcDeFgHiJkLmNoPqRsz"; - text[18][8]="zzzzzzzzaBcDeFgHiJkLmNoPqRs"; - text[19][0]="aBcDeFgHiJkLmNoPqRsTzzzzzzz"; - text[19][1]="zaBcDeFgHiJkLmNoPqRsTzzzzzz"; - text[19][2]="zzaBcDeFgHiJkLmNoPqRsTzzzzz"; - text[19][3]="zzzaBcDeFgHiJkLmNoPqRsTzzzz"; - text[19][4]="zzzzaBcDeFgHiJkLmNoPqRsTzzz"; - text[19][5]="zzzzzaBcDeFgHiJkLmNoPqRsTzz"; - text[19][6]="zzzzzzaBcDeFgHiJkLmNoPqRsTz"; - text[19][7]="zzzzzzzaBcDeFgHiJkLmNoPqRsT"; - text[20][0]="aBcDeFgHiJkLmNoPqRsTuzzzzzz"; - text[20][1]="zaBcDeFgHiJkLmNoPqRsTuzzzzz"; - text[20][2]="zzaBcDeFgHiJkLmNoPqRsTuzzzz"; - text[20][3]="zzzaBcDeFgHiJkLmNoPqRsTuzzz"; - text[20][4]="zzzzaBcDeFgHiJkLmNoPqRsTuzz"; - text[20][5]="zzzzzaBcDeFgHiJkLmNoPqRsTuz"; - text[20][6]="zzzzzzaBcDeFgHiJkLmNoPqRsTu"; - text[21][0]="aBcDeFgHiJkLmNoPqRsTuVzzzzz"; - text[21][1]="zaBcDeFgHiJkLmNoPqRsTuVzzzz"; - text[21][2]="zzaBcDeFgHiJkLmNoPqRsTuVzzz"; - text[21][3]="zzzaBcDeFgHiJkLmNoPqRsTuVzz"; - text[21][4]="zzzzaBcDeFgHiJkLmNoPqRsTuVz"; - text[21][5]="zzzzzaBcDeFgHiJkLmNoPqRsTuV"; - text[22][0]="aBcDeFgHiJkLmNoPqRsTuVwzzzz"; - text[22][1]="zaBcDeFgHiJkLmNoPqRsTuVwzzz"; - text[22][2]="zzaBcDeFgHiJkLmNoPqRsTuVwzz"; - text[22][3]="zzzaBcDeFgHiJkLmNoPqRsTuVwz"; - text[22][4]="zzzzaBcDeFgHiJkLmNoPqRsTuVw"; - text[23][0]="aBcDeFgHiJkLmNoPqRsTuVwXzzz"; - text[23][1]="zaBcDeFgHiJkLmNoPqRsTuVwXzz"; - text[23][2]="zzaBcDeFgHiJkLmNoPqRsTuVwXz"; - text[23][3]="zzzaBcDeFgHiJkLmNoPqRsTuVwX"; - text[24][0]="aBcDeFgHiJkLmNoPqRsTuVwXyzz"; - text[24][1]="zaBcDeFgHiJkLmNoPqRsTuVwXyz"; - text[24][2]="zzaBcDeFgHiJkLmNoPqRsTuVwXy"; - text[25][0]="aBcDeFgHiJkLmNoPqRsTuVwXyZz"; - text[25][1]="zaBcDeFgHiJkLmNoPqRsTuVwXyZ"; - - char *needle[26]; - needle[0]="A"; - needle[1]="Ab"; - needle[2]="AbC"; - needle[3]="AbCd"; - needle[4]="AbCdE"; - needle[5]="AbCdEf"; - needle[6]="AbCdEfG"; - needle[7]="AbCdEfGh"; - needle[8]="AbCdEfGhI"; - needle[9]="AbCdEfGhIJ"; - needle[10]="AbCdEfGhIjK"; - needle[11]="AbCdEfGhIjKl"; - needle[12]="AbCdEfGhIjKlM"; - needle[13]="AbCdEfGhIjKlMn"; - needle[14]="AbCdEfGhIjKlMnO"; - needle[15]="AbCdEfGhIjKlMnOp"; - needle[16]="AbCdEfGhIjKlMnOpQ"; - needle[17]="AbCdEfGhIjKlMnOpQr"; - needle[18]="AbCdEfGhIjKlMnOpQrS"; - needle[19]="AbCdEfGhIjKlMnOpQrSt"; - needle[20]="AbCdEfGhIjKlMnOpQrStU"; - needle[21]="AbCdEfGhIjKlMnOpQrStUv"; - needle[22]="AbCdEfGhIjKlMnOpQrStUvW"; - needle[23]="AbCdEfGhIjKlMnOpQrStUvWx"; - needle[24]="AbCdEfGhIjKlMnOpQrStUvWxY"; - needle[25]="AbCdEfGhIjKlMnOpQrStUvWxYZ"; - - int i, j; - uint8_t *found = NULL; - for (i = 0; i < 26; i++) { - for (j = 0; j <= (26-i); j++) { - found = BasicSearchNocaseWrapper((uint8_t *)text[i][j], (uint8_t *)needle[i], 1); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i][j]); - return 0; - } - found = Bs2bmNocaseWrapper((uint8_t *)text[i][j], (uint8_t *)needle[i], 1); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i][j]); - return 0; - } - found = BoyerMooreNocaseWrapper((uint8_t *)text[i][j], (uint8_t *)needle[i], 1); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i][j]); - return 0; - } - } - } - return 1; -} - -/** - * \test Give some stats - */ -int UtilSpmSearchStatsTest01() -{ - char *text[16]; - text[0]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzza"; - text[1]="aaaaaaaaazaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaazaaaaaaaaazaaaaaaaaaazaaaaaaaaaaaaazaaaaaaaaazaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaazaaaaaaaaazaaaaaaaaaazaaaaaraaaaazaaaaaaazaaaaaaaaaaaaaazaaaaaaaazaaaaaaaaazaaaaaaaaaaaaB"; - text[2]="aBaBaBaBaBaBaBaBazaBaBaBaBaBaBazaBaBaBaBaBaBaBaBaBzBaBaBaBaBaBaBaBazaBaBaBaBaBaBaBzBaBaBaBaBaBaBzBaBaBaBaBzBaBaBaBaBaBzBaBaBaBaBaBzBaBaBaBaBaBaBaBazaBaBaBaBaBaBaBaBaBaBaBaBazaBaBaBaBaBaBaBaBaBzBaBaBaBaBaBaBaBzBaBaBaBaBaBaBaBaBaBzBaBaBaBaBaBaBaBaBaBaBazaBaBaBaBaBaBaBazaBaBaBaBaBc"; - text[3]="aBcaBcaBcaBcaBczBcaBcaBzaBcaBcaBcaBcaBcaBcaBcaBcazcaBcaBcaBcaBcaBcaBcaBzaBcaBcaBcaBcaBcaBczBcaBcaBcaBcaBcaBzaBcaBcaBcaBcaBcaBcaBcazcaBcaBcaBcaBcaBcaBcaBcaBczBcaBcaBcaBcaBcaBcaBczBcaBcaBcaBcaBzaBcaBcaBcaBcaBcaBcaBcazcaBcaBcaBcaBcaBcazcaBcaBcaBcaBcaBcaBzaBcaBcaBcazcaBcaBcaBcaBcaBcD"; - text[4]="aBcDaBcDaBcDaBczaBcDaBcDaBcDaBcDaBczaBcDaBcDaBcDaBcDzBcDaBcDaBcDaBcDzBcDaBcDaBczaBcDaBcDaBczaBcDaBcDaBcDaBcDaBzDaBcDaBcDaBcDaBcDaBcDaBcDaBcDaBczaBcDaBcDaBcDaBcDaBcDaBzDaBcDaBcDaBcDaBzDaBcDaBcDaBzDaBcDaBcDaBcDaBcDaBcDaBczaBcDaBcDaBcDaBcDazcDaBcDaBcDaBcDaBcDzBcDaBcDaBcDaBcDaBcDaBcDe"; - text[5]="aBcDeaBcDeaBcDeazcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDezBcDeaBcDeaBcDzaBcDeaBcDeaBcDeazcDzaBcDeaBcDezBcDeaBzDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBczeaBcDeaBcDeaBzDeaBcDeaBcDezBcDeaBcDzaBcDeaBcDezBcDeaBcDezBcDeaBczeaBcDeaBcDeaBzDeaBcDezBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeF"; - text[6]="aBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBzDeaBcDeaBcDeaBcDzaBcDzaBcDeaBcDeaBcDeaBcDzaBzDeaBcDeaBcDeaBczzaBcDeaBcDeaBcDzazcDeaBcDeaBcDeaBcDzaBzDeaBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDeaBczeaBcDeaBcDeaBcDeaBczeaBcDezzzaBcDeFg"; - text[7]="aBcDeaBczeaBcDzaBcDezBcDeaBcDeaBcDeaBcDzaBzDeaBcDeaBcDeaBzDzaBcDeaBcDeazcDeaBcDzaBcDeaBczeaBcDeaBcDeaBzDzaBcDeaBcDeaBcDezBcDzaBcDeaBzDeaBcDeaBcDezBcDzaBcDeaBcDeaBzDeaBcDeaBcDeaBzDeaBcDeaBcDezBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBrDeaBcDeaBcDezzzaBcDeFgH"; - text[8]="aBcDeaBcDeaBczzaBcDeazcDeaBcDezBcDeaBcDzaBcDeaBcDeaBcDeaBczzaBcDeaBcDeaBczeaBcDeaBcDzzBcDeaBcDeaBcDzaBczeaBcDeaBcDzaBcDeaBczeaBcDeaBcDeaBzDeaBcDeaBcDeaBzDeaBcDeaBcDzaBcDeaBcDeazcDeaBcDeaBcDzaBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBczeaBcDeaBzDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHi"; - text[9]="aBcDeaBcDzaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeazcDeaBcDeaBcDzzBcDeaBcDeaBczeaBcDzaBcDezBcDeaBczeaBcDzaBcDezBcDeaBcDzaBczeaBcDeaBcDzaBcDeazcDeaBcDeaBcDzaBczeaBcDeaBcDzaBzDeaBcDeaBczeaBcDeaBcDzaBcDeaBcDeaBzDeaBcDeaBcDeaBczeaBcDeaBcDeaBcDeaBzDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJ"; - text[10]="aBcDeaBcDeaBczeaBcDzaBczeaBcDeaBczeaBcDeaBcDzaBcDeaBcDeazcDeaBcDeaBcDeaBzDzaBcDeazcDeaBcDeazcDeaBcDzaBcDeazcDeaBcDeaBczzaBcDeaBcDeaBzDeaBcDeaBcDzaBczeaBcDeaBcDeaBcDeaBczeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDezBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDezBcDeaBcDeaBcDeaBzDeaBcDeaBcDezzzaBcDeFgHiJk"; - text[11]="aBcDeaBcDeaBcDeaBcDeaBzDeaBcDeaBcDzaBcDzaBcDeaBcDeaBcDeaBcDeazcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDzaBcDzaBcDeaBcDeaBcDeaBcDzzBcDeaBcDeaBcDeaBcDzaBcDzaBcDeaBzDeaBcDeaBcDezBcDeaBcDeazcDeaBcDeaBcDezBcDeaBcDeaBcDeazcDeaBcDeaBzDeaBcDeaBczeaBcDeazcDeaBcDezBcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJkL"; - text[12]="aBcDeaBcDeaBcDeaBcDeaBzDeaBcDeaBzDeaBcDeaBcDezBcDeaBcDeazcDeaBcDeaBcDeazcDeaBcDeaBczeaBcDeaBcDeaBcDezBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJkLm"; - text[13]="aBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJkLmN"; - text[14]="aBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDezzzaBcDeFgHiJkLmNo"; - text[15]="aBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJkLmNoP"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of greater length (text with a lot of partial matches, worst case for a basic search):\n"); - for (i = 0; i < 16; i++) { - printf("Pattern length %d with BasicSearch:", i+1); - found = BasicSearchWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch:", i+1); - found = Bs2bmWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch:", i+1); - found = BoyerMooreWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -/** - * \test Give some stats for - */ -int UtilSpmSearchStatsTest02() -{ - char *text[16]; - text[0]="zzzzzzzzzzzzzzzzzza"; - text[1]="zzzzzzzzzzzzzzzzzzaB"; - text[2]="zzzzzzzzzzzzzzzzzzaBc"; - text[3]="zzzzzzzzzzzzzzzzzzaBcD"; - text[4]="zzzzzzzzzzzzzzzzzzaBcDe"; - text[5]="zzzzzzzzzzzzzzzzzzzzaBcDeF"; - text[6]="zzzzzzzzzzzzzzzzzzzzaBcDeFg"; - text[7]="zzzzzzzzzzzzzzzzzzzzaBcDeFgH"; - text[8]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHi"; - text[9]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJ"; - text[10]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJk"; - text[11]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkL"; - text[12]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLm"; - text[13]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmN"; - text[14]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNo"; - text[15]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNoP"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of lower length:\n"); - for (i = 0; i < 16; i++) { - printf("Pattern length %d with BasicSearch:", i+1); - found = BasicSearchWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch:", i+1); - found = Bs2bmWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch:", i+1); - found = BoyerMooreWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - - -int UtilSpmSearchStatsTest03() -{ - char *text[16]; - text[0]="zzzzzza"; - text[1]="zzzzzzaB"; - text[2]="zzzzzzaBc"; - text[3]="zzzzzzaBcD"; - text[4]="zzzzzzaBcDe"; - text[5]="zzzzzzzzaBcDeF"; - text[6]="zzzzzzzzaBcDeFg"; - text[7]="zzzzzzzzaBcDeFgH"; - text[8]="zzzzzzzzaBcDeFgHi"; - text[9]="zzzzzzzzaBcDeFgHiJ"; - text[10]="zzzzzzzzaBcDeFgHiJk"; - text[11]="zzzzzzzzaBcDeFgHiJkL"; - text[12]="zzzzzzzzaBcDeFgHiJkLm"; - text[13]="zzzzzzzzaBcDeFgHiJkLmN"; - text[14]="zzzzzzzzaBcDeFgHiJkLmNo"; - text[15]="zzzzzzzzaBcDeFgHiJkLmNoP"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of lower length (badcase for):\n"); - for (i = 0; i < 16; i++) { - printf("Pattern length %d with BasicSearch:", i+1); - found = BasicSearchWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch:", i+1); - found = Bs2bmWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch:", i+1); - found = BoyerMooreWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -/** - * \test Give some stats - */ -int UtilSpmSearchStatsTest04() -{ - char *text[16]; - text[0]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzza"; - text[1]="aaaaaaaaazaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaazaaaaaaaaazaaaaaaaaaazaaaaaaaaaaaaazaaaaaaaaazaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaazaaaaaaaaazaaaaaaaaaazaaaaaraaaaazaaaaaaazaaaaaaaaaaaaaazaaaaaaaazaaaaaaaaazaaaaaaaaaaaaB"; - text[2]="aBaBaBaBaBaBaBaBazaBaBaBaBaBaBazaBaBaBaBaBaBaBaBaBzBaBaBaBaBaBaBaBazaBaBaBaBaBaBaBzBaBaBaBaBaBaBzBaBaBaBaBzBaBaBaBaBaBzBaBaBaBaBaBzBaBaBaBaBaBaBaBazaBaBaBaBaBaBaBaBaBaBaBaBazaBaBaBaBaBaBaBaBaBzBaBaBaBaBaBaBaBzBaBaBaBaBaBaBaBaBaBzBaBaBaBaBaBaBaBaBaBaBazaBaBaBaBaBaBaBazaBaBaBaBaBc"; - text[3]="aBcaBcaBcaBcaBczBcaBcaBzaBcaBcaBcaBcaBcaBcaBcaBcazcaBcaBcaBcaBcaBcaBcaBzaBcaBcaBcaBcaBcaBczBcaBcaBcaBcaBcaBzaBcaBcaBcaBcaBcaBcaBcazcaBcaBcaBcaBcaBcaBcaBcaBczBcaBcaBcaBcaBcaBcaBczBcaBcaBcaBcaBzaBcaBcaBcaBcaBcaBcaBcazcaBcaBcaBcaBcaBcazcaBcaBcaBcaBcaBcaBzaBcaBcaBcazcaBcaBcaBcaBcaBcD"; - text[4]="aBcDaBcDaBcDaBczaBcDaBcDaBcDaBcDaBczaBcDaBcDaBcDaBcDzBcDaBcDaBcDaBcDzBcDaBcDaBczaBcDaBcDaBczaBcDaBcDaBcDaBcDaBzDaBcDaBcDaBcDaBcDaBcDaBcDaBcDaBczaBcDaBcDaBcDaBcDaBcDaBzDaBcDaBcDaBcDaBzDaBcDaBcDaBzDaBcDaBcDaBcDaBcDaBcDaBczaBcDaBcDaBcDaBcDazcDaBcDaBcDaBcDaBcDzBcDaBcDaBcDaBcDaBcDaBcDe"; - text[5]="aBcDeaBcDeaBcDeazcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDezBcDeaBcDeaBcDzaBcDeaBcDeaBcDeazcDzaBcDeaBcDezBcDeaBzDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBczeaBcDeaBcDeaBzDeaBcDeaBcDezBcDeaBcDzaBcDeaBcDezBcDeaBcDezBcDeaBczeaBcDeaBcDeaBzDeaBcDezBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeF"; - text[6]="aBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBzDeaBcDeaBcDeaBcDzaBcDzaBcDeaBcDeaBcDeaBcDzaBzDeaBcDeaBcDeaBczzaBcDeaBcDeaBcDzazcDeaBcDeaBcDeaBcDzaBzDeaBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDeaBczeaBcDeaBcDeaBcDeaBczeaBcDezzzaBcDeFg"; - text[7]="aBcDeaBczeaBcDzaBcDezBcDeaBcDeaBcDeaBcDzaBzDeaBcDeaBcDeaBzDzaBcDeaBcDeazcDeaBcDzaBcDeaBczeaBcDeaBcDeaBzDzaBcDeaBcDeaBcDezBcDzaBcDeaBzDeaBcDeaBcDezBcDzaBcDeaBcDeaBzDeaBcDeaBcDeaBzDeaBcDeaBcDezBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBrDeaBcDeaBcDezzzaBcDeFgH"; - text[8]="aBcDeaBcDeaBczzaBcDeazcDeaBcDezBcDeaBcDzaBcDeaBcDeaBcDeaBczzaBcDeaBcDeaBczeaBcDeaBcDzzBcDeaBcDeaBcDzaBczeaBcDeaBcDzaBcDeaBczeaBcDeaBcDeaBzDeaBcDeaBcDeaBzDeaBcDeaBcDzaBcDeaBcDeazcDeaBcDeaBcDzaBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDeazcDeaBcDeaBcDeaBczeaBcDeaBzDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHi"; - text[9]="aBcDeaBcDzaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeazcDeaBcDeaBcDzzBcDeaBcDeaBczeaBcDzaBcDezBcDeaBczeaBcDzaBcDezBcDeaBcDzaBczeaBcDeaBcDzaBcDeazcDeaBcDeaBcDzaBczeaBcDeaBcDzaBzDeaBcDeaBczeaBcDeaBcDzaBcDeaBcDeaBzDeaBcDeaBcDeaBczeaBcDeaBcDeaBcDeaBzDeaBcDeaBcDeazcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJ"; - text[10]="aBcDeaBcDeaBczeaBcDzaBczeaBcDeaBczeaBcDeaBcDzaBcDeaBcDeazcDeaBcDeaBcDeaBzDzaBcDeazcDeaBcDeazcDeaBcDzaBcDeazcDeaBcDeaBczzaBcDeaBcDeaBzDeaBcDeaBcDzaBczeaBcDeaBcDeaBcDeaBczeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDezBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDezBcDeaBcDeaBcDeaBzDeaBcDeaBcDezzzaBcDeFgHiJk"; - text[11]="aBcDeaBcDeaBcDeaBcDeaBzDeaBcDeaBcDzaBcDzaBcDeaBcDeaBcDeaBcDeazcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDzaBcDzaBcDeaBcDeaBcDeaBcDzzBcDeaBcDeaBcDeaBcDzaBcDzaBcDeaBzDeaBcDeaBcDezBcDeaBcDeazcDeaBcDeaBcDezBcDeaBcDeaBcDeazcDeaBcDeaBzDeaBcDeaBczeaBcDeazcDeaBcDezBcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJkL"; - text[12]="aBcDeaBcDeaBcDeaBcDeaBzDeaBcDeaBzDeaBcDeaBcDezBcDeaBcDeazcDeaBcDeaBcDeazcDeaBcDeaBczeaBcDeaBcDeaBcDezBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJkLm"; - text[13]="aBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJkLmN"; - text[14]="aBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDezzzaBcDeFgHiJkLmNo"; - text[15]="aBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDzaBcDeaBcDeaBcDeaBcDezzzaBcDeFgHiJkLmNoP"; - - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of greater length:\n"); - for (i = 0; i < 16; i++) { - printf("Pattern length %d with BasicSearch (Building Context):", i + 1); - found = BasicSearchCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch (Building Context):", i + 1); - found = Bs2bmCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch (Building Context):", i + 1); - found = BoyerMooreCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with SpmSearch (Building Context):", i + 1); - found = RawCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -/** - * \test Give some stats for - */ -int UtilSpmSearchStatsTest05() -{ - char *text[16]; - text[0]="zzzzzzzzzzzzzzzzzza"; - text[1]="zzzzzzzzzzzzzzzzzzaB"; - text[2]="zzzzzzzzzzzzzzzzzzaBc"; - text[3]="zzzzzzzzzzzzzzzzzzaBcD"; - text[4]="zzzzzzzzzzzzzzzzzzaBcDe"; - text[5]="zzzzzzzzzzzzzzzzzzzzaBcDeF"; - text[6]="zzzzzzzzzzzzzzzzzzzzaBcDeFg"; - text[7]="zzzzzzzzzzzzzzzzzzzzaBcDeFgH"; - text[8]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHi"; - text[9]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJ"; - text[10]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJk"; - text[11]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkL"; - text[12]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLm"; - text[13]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmN"; - text[14]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNo"; - text[15]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNoP"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of lower length:\n"); - for (i = 0; i < 16; i++) { - printf("Pattern length %d with BasicSearch (Building Context):", i+1); - found = BasicSearchCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch (Building Context):", i+1); - found = Bs2bmCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch (Building Context):", i+1); - found = BoyerMooreCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - - -int UtilSpmSearchStatsTest06() -{ - char *text[16]; - text[0]="zzzzkzzzzzzzkzzzzzza"; - text[1]="BBBBkBBBBBBBkBBBBBaB"; - text[2]="BcBckcBcBcBckcBcBcaBc"; - text[3]="BcDBkDBcDBcDkcDBcDaBcD"; - text[4]="BcDekcDeBcDekcDezzaBcDe"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of lower length (badcase for):\n"); - for (i = 0; i < 5; i++) { - printf("Pattern length %d with BasicSearch (Building Context):", i+1); - found = BasicSearchCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch (Building Context):", i+1); - found = Bs2bmCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch (Building Context):", i+1); - found = BoyerMooreCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -int UtilSpmSearchStatsTest07() -{ - char *text[16]; - text[0]="zzzza"; - text[1]="BBBaB"; - text[2]="bbaBc"; - text[3]="aaBcD"; - text[4]="aBcDe"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of real lower length (badcase for):\n"); - for (i = 0; i < 5; i++) { - printf("Pattern length %d with BasicSearch (Building Context):", i+1); - found = BasicSearchCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch (Building Context):", i+1); - found = Bs2bmCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch (Building Context):", i+1); - found = BoyerMooreCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -/** - * \test Give some stats for no case algorithms - */ -int UtilSpmNocaseSearchStatsTest01() -{ - char *text[16]; - text[0]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzza"; - text[1]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaB"; - text[2]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBc"; - text[3]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcD"; - text[4]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDe"; - text[5]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeF"; - text[6]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFg"; - text[7]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgH"; - text[8]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHi"; - text[9]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJ"; - text[10]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJk"; - text[11]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkL"; - text[12]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLm"; - text[13]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmN"; - text[14]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNo"; - text[15]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNoP"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of greater length:\n"); - for (i = 0; i < 16; i++) { - printf("Pattern length %d with BasicSearch:", i+1); - found = BasicSearchNocaseWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch:", i+1); - found = Bs2bmNocaseWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch:", i+1); - found = BoyerMooreNocaseWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -int UtilSpmNocaseSearchStatsTest02() -{ - char *text[16]; - text[0]="zzzzzzzzzzzzzzzzzza"; - text[1]="zzzzzzzzzzzzzzzzzzaB"; - text[2]="zzzzzzzzzzzzzzzzzzaBc"; - text[3]="zzzzzzzzzzzzzzzzzzaBcD"; - text[4]="zzzzzzzzzzzzzzzzzzaBcDe"; - text[5]="zzzzzzzzzzzzzzzzzzzzaBcDeF"; - text[6]="zzzzzzzzzzzzzzzzzzzzaBcDeFg"; - text[7]="zzzzzzzzzzzzzzzzzzzzaBcDeFgH"; - text[8]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHi"; - text[9]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJ"; - text[10]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJk"; - text[11]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkL"; - text[12]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLm"; - text[13]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmN"; - text[14]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNo"; - text[15]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNoP"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of lower length:\n"); - for (i = 0; i < 16; i++) { - printf("Pattern length %d with BasicSearch:", i+1); - found = BasicSearchNocaseWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch:", i+1); - found = Bs2bmNocaseWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch:", i+1); - found = BoyerMooreNocaseWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - - -int UtilSpmNocaseSearchStatsTest03() -{ - char *text[16]; - text[0]="zzzzkzzzzzzzkzzzzzza"; - text[1]="BBBBkBBBBBBBkBBBBBaB"; - text[2]="BcBckcBcBcBckcBcBcaBc"; - text[3]="BcDBkDBcDBcDkcDBcDaBcD"; - text[4]="BcDekcDeBcDekcDezzaBcDe"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of lower length (badcase for):\n"); - for (i = 0; i < 5; i++) { - printf("Pattern length %d with BasicSearch:", i+1); - found = BasicSearchNocaseWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch:", i+1); - found = Bs2bmNocaseWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch:", i+1); - found = BoyerMooreNocaseWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -/** - * \test Give some stats for no case algorithms - */ -int UtilSpmNocaseSearchStatsTest04() -{ - char *text[16]; - text[0]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzza"; - text[1]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaB"; - text[2]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBc"; - text[3]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcD"; - text[4]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDe"; - text[5]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeF"; - text[6]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFg"; - text[7]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgH"; - text[8]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHi"; - text[9]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJ"; - text[10]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJk"; - text[11]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkL"; - text[12]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLm"; - text[13]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmN"; - text[14]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNo"; - text[15]="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNoP"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of greater length:\n"); - for (i = 0; i < 16; i++) { - printf("Pattern length %d with BasicSearch (Building Context):", i+1); - found = BasicSearchNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch (Building Context):", i+1); - found = Bs2bmNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch (Building Context):", i+1); - found = BoyerMooreNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -int UtilSpmNocaseSearchStatsTest05() -{ - char *text[16]; - text[0]="zzzzzzzzzzzzzzzzzza"; - text[1]="zzzzzzzzzzzzzzzzzzaB"; - text[2]="zzzzzzzzzzzzzzzzzzaBc"; - text[3]="zzzzzzzzzzzzzzzzzzaBcD"; - text[4]="zzzzzzzzzzzzzzzzzzaBcDe"; - text[5]="zzzzzzzzzzzzzzzzzzzzaBcDeF"; - text[6]="zzzzzzzzzzzzzzzzzzzzaBcDeFg"; - text[7]="zzzzzzzzzzzzzzzzzzzzaBcDeFgH"; - text[8]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHi"; - text[9]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJ"; - text[10]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJk"; - text[11]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkL"; - text[12]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLm"; - text[13]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmN"; - text[14]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNo"; - text[15]="zzzzzzzzzzzzzzzzzzzzaBcDeFgHiJkLmNoP"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - needle[5]="aBcDeF"; - needle[6]="aBcDeFg"; - needle[7]="aBcDeFgH"; - needle[8]="aBcDeFgHi"; - needle[9]="aBcDeFgHiJ"; - needle[10]="aBcDeFgHiJk"; - needle[11]="aBcDeFgHiJkL"; - needle[12]="aBcDeFgHiJkLm"; - needle[13]="aBcDeFgHiJkLmN"; - needle[14]="aBcDeFgHiJkLmNo"; - needle[15]="aBcDeFgHiJkLmNoP"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of lower length:\n"); - for (i = 0; i < 16; i++) { - printf("Pattern length %d with BasicSearch (Building Context):", i+1); - found = BasicSearchNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch (Building Context):", i+1); - found = Bs2bmNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch (Building Context):", i+1); - found = BoyerMooreNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - - -int UtilSpmNocaseSearchStatsTest06() -{ - char *text[16]; - text[0]="zzzzkzzzzzzzkzzzzzza"; - text[1]="BBBBkBBBBBBBkBBBBBaB"; - text[2]="BcBckcBcBcBckcBcBcaBc"; - text[3]="BcDBkDBcDBcDkcDBcDaBcD"; - text[4]="BcDekcDeBcDekcDezzaBcDe"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of lower length (badcase for):\n"); - for (i = 0; i < 5; i++) { - printf("Pattern length %d with BasicSearch (Building Context):", i+1); - found = BasicSearchNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch (Building Context):", i+1); - found = Bs2bmNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch (Building Context):", i+1); - found = BoyerMooreNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -int UtilSpmNocaseSearchStatsTest07() -{ - char *text[16]; - text[0]="zzzza"; - text[1]="bbbAb"; - text[2]="bbAbC"; - text[3]="bAbCd"; - text[4]="AbCdE"; - - char *needle[16]; - needle[0]="a"; - needle[1]="aB"; - needle[2]="aBc"; - needle[3]="aBcD"; - needle[4]="aBcDe"; - - int i; - uint8_t *found = NULL; - printf("\nStats for text of real lower length (badcase for):\n"); - for (i = 0; i < 5; i++) { - printf("Pattern length %d with BasicSearch (Building Context):", i+1); - found = BasicSearchNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error1 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with Bs2BmSearch (Building Context):", i+1); - found = Bs2bmNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error2 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("Pattern length %d with BoyerMooreSearch (Building Context):", i+1); - found = BoyerMooreNocaseCtxWrapper((uint8_t *)text[i], (uint8_t *)needle[i], STATS_TIMES); - if (found == 0) { - printf("Error3 searching for %s in text %s\n", needle[i], text[i]); - return 0; - } - printf("\n"); - } - return 1; -} - -#endif - -/* Register unittests */ -void UtilSpmSearchRegistertests(void) -{ -#ifdef UNITTESTS - /* Generic tests */ - UtRegisterTest("UtilSpmBasicSearchTest01", UtilSpmBasicSearchTest01, 1); - UtRegisterTest("UtilSpmBasicSearchNocaseTest01", UtilSpmBasicSearchNocaseTest01, 1); - - UtRegisterTest("UtilSpmBs2bmSearchTest01", UtilSpmBs2bmSearchTest01, 1); - UtRegisterTest("UtilSpmBs2bmSearchNocaseTest01", UtilSpmBs2bmSearchNocaseTest01, 1); - - UtRegisterTest("UtilSpmBoyerMooreSearchTest01", UtilSpmBoyerMooreSearchTest01, 1); - UtRegisterTest("UtilSpmBoyerMooreSearchNocaseTest01", UtilSpmBoyerMooreSearchNocaseTest01, 1); - UtRegisterTest("UtilSpmBoyerMooreSearchNocaseTestIssue130", UtilSpmBoyerMooreSearchNocaseTestIssue130, 1); - - UtRegisterTest("UtilSpmBs2bmSearchTest02", UtilSpmBs2bmSearchTest02, 1); - UtRegisterTest("UtilSpmBs2bmSearchNocaseTest02", UtilSpmBs2bmSearchNocaseTest02, 1); - - UtRegisterTest("UtilSpmBasicSearchTest02", UtilSpmBasicSearchTest02, 1); - UtRegisterTest("UtilSpmBasicSearchNocaseTest02", UtilSpmBasicSearchNocaseTest02, 1); - - UtRegisterTest("UtilSpmBoyerMooreSearchTest02", UtilSpmBoyerMooreSearchTest02, 1); - UtRegisterTest("UtilSpmBoyerMooreSearchNocaseTest02", UtilSpmBoyerMooreSearchNocaseTest02, 1); - - /* test matches at any offset */ - UtRegisterTest("UtilSpmSearchOffsetsTest01", UtilSpmSearchOffsetsTest01, 1); - UtRegisterTest("UtilSpmSearchOffsetsNocaseTest01", UtilSpmSearchOffsetsNocaseTest01, 1); - -#ifdef ENABLE_SEARCH_STATS - /* Give some stats searching given a prepared context (look at the wrappers) */ - UtRegisterTest("UtilSpmSearchStatsTest01", UtilSpmSearchStatsTest01, 1); - UtRegisterTest("UtilSpmSearchStatsTest02", UtilSpmSearchStatsTest02, 1); - UtRegisterTest("UtilSpmSearchStatsTest03", UtilSpmSearchStatsTest03, 1); - - UtRegisterTest("UtilSpmNocaseSearchStatsTest01", UtilSpmNocaseSearchStatsTest01, 1); - UtRegisterTest("UtilSpmNocaseSearchStatsTest02", UtilSpmNocaseSearchStatsTest02, 1); - UtRegisterTest("UtilSpmNocaseSearchStatsTest03", UtilSpmNocaseSearchStatsTest03, 1); - - /* Stats building context and searching */ - UtRegisterTest("UtilSpmSearchStatsTest04", UtilSpmSearchStatsTest04, 1); - UtRegisterTest("UtilSpmSearchStatsTest05", UtilSpmSearchStatsTest05, 1); - UtRegisterTest("UtilSpmSearchStatsTest06", UtilSpmSearchStatsTest06, 1); - UtRegisterTest("UtilSpmSearchStatsTest07", UtilSpmSearchStatsTest07, 1); - - UtRegisterTest("UtilSpmNocaseSearchStatsTest04", UtilSpmNocaseSearchStatsTest04, 1); - UtRegisterTest("UtilSpmNocaseSearchStatsTest05", UtilSpmNocaseSearchStatsTest05, 1); - UtRegisterTest("UtilSpmNocaseSearchStatsTest06", UtilSpmNocaseSearchStatsTest06, 1); - UtRegisterTest("UtilSpmNocaseSearchStatsTest07", UtilSpmNocaseSearchStatsTest07, 1); - -#endif -#endif -} diff --git a/framework/src/suricata/src/util-spm.h b/framework/src/suricata/src/util-spm.h deleted file mode 100644 index 2dea657e..00000000 --- a/framework/src/suricata/src/util-spm.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - */ - -#ifndef __UTIL_SPM_H__ -#define __UTIL_SPM_H__ - -#include "util-spm-bs.h" -#include "util-spm-bs2bm.h" -#include "util-spm-bm.h" - -/** Default algorithm to use: Boyer Moore */ -uint8_t *Bs2bmSearch(uint8_t *text, uint32_t textlen, uint8_t *needle, uint16_t needlelen); -uint8_t *Bs2bmNocaseSearch(uint8_t *text, uint32_t textlen, uint8_t *needle, uint16_t needlelen); -uint8_t *BoyerMooreSearch(uint8_t *text, uint32_t textlen, uint8_t *needle, uint16_t needlelen); -uint8_t *BoyerMooreNocaseSearch(uint8_t *text, uint32_t textlen, uint8_t *needle, uint16_t needlelen); - -/* Macros for automatic algorithm selection (use them only when you can't store the context) */ -#define SpmSearch(text, textlen, needle, needlelen) ({\ - uint8_t *mfound; \ - if (needlelen < 4 && textlen < 512) \ - mfound = BasicSearch(text, textlen, needle, needlelen); \ - else if (needlelen < 4) \ - mfound = BasicSearch(text, textlen, needle, needlelen); \ - else \ - mfound = BoyerMooreSearch(text, textlen, needle, needlelen); \ - mfound; \ - }) - -#define SpmNocaseSearch(text, textlen, needle, needlelen) ({\ - uint8_t *mfound; \ - if (needlelen < 4 && textlen < 512) \ - mfound = BasicSearchNocase(text, textlen, needle, needlelen); \ - else if (needlelen < 4) \ - mfound = BasicSearchNocase(text, textlen, needle, needlelen); \ - else \ - mfound = BoyerMooreNocaseSearch(text, textlen, needle, needlelen); \ - mfound; \ - }) - -void UtilSpmSearchRegistertests(void); -#endif /* __UTIL_SPM_H__ */ diff --git a/framework/src/suricata/src/util-storage.c b/framework/src/suricata/src/util-storage.c deleted file mode 100644 index ba9aa716..00000000 --- a/framework/src/suricata/src/util-storage.c +++ /dev/null @@ -1,545 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Storage API - */ - -#include "suricata-common.h" -#include "util-unittest.h" -#include "util-storage.h" - -typedef struct StorageMapping_ { - const char *name; - StorageEnum type; // host, flow, tx, stream, ssn, etc - unsigned int size; - void *(*Alloc)(unsigned int); - void (*Free)(void *); -} StorageMapping; - -/** \brief list of StorageMapping used at registration time */ -typedef struct StorageList_ { - StorageMapping map; - int id; - struct StorageList_ *next; -} StorageList; - -static StorageList *storage_list = NULL; -static int storage_max_id[STORAGE_MAX]; -static int storage_registraton_closed = 0; -static StorageMapping **storage_map = NULL; - -const char *StoragePrintType(StorageEnum type) -{ - switch(type) { - case STORAGE_HOST: - return "host"; - case STORAGE_FLOW: - return "flow"; - case STORAGE_IPPAIR: - return "ippair"; - case STORAGE_MAX: - return "max"; - } - return "invalid"; -} - -void StorageInit(void) -{ - memset(&storage_max_id, 0x00, sizeof(storage_max_id)); - storage_list = NULL; - storage_map = NULL; - storage_registraton_closed = 0; -} - -void StorageCleanup(void) -{ - if (storage_map) { - int i; - for (i = 0; i < STORAGE_MAX; i++) { - if (storage_map[i] != NULL) { - SCFree(storage_map[i]); - storage_map[i] = NULL; - } - } - SCFree(storage_map); - storage_map = NULL; - } - - StorageList *entry = storage_list; - while (entry) { - StorageList *next = entry->next; - SCFree(entry); - entry = next; - } - - storage_list = NULL; -} - -int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)) -{ - if (storage_registraton_closed) - return -1; - - if (type >= STORAGE_MAX || name == NULL || strlen(name) == 0 || - size == 0 || (size != sizeof(void *) && Alloc == NULL) || Free == NULL) - return -1; - - StorageList *list = storage_list; - while (list) { - if (strcmp(name, list->map.name) == 0 && type == list->map.type) { - SCLogError(SC_ERR_INVALID_VALUE, "storage for type \"%s\" with " - "name \"%s\" already registered", StoragePrintType(type), - name); - return -1; - } - - list = list->next; - } - - StorageList *entry = SCMalloc(sizeof(StorageList)); - if (unlikely(entry == NULL)) - return -1; - - memset(entry, 0x00, sizeof(StorageList)); - - entry->map.type = type; - entry->map.name = name; - entry->map.size = size; - entry->map.Alloc = Alloc; - entry->map.Free = Free; - - entry->id = storage_max_id[type]++; - entry->next = storage_list; - storage_list = entry; - - return entry->id; -} - -int StorageFinalize(void) -{ - int count = 0; - int i; - - storage_registraton_closed = 1; - - for (i = 0; i < STORAGE_MAX; i++) { - if (storage_max_id[i] > 0) - count++; - } - if (count == 0) - return 0; - - storage_map = SCMalloc(sizeof(StorageMapping *) * STORAGE_MAX); - if (unlikely(storage_map == NULL)) { - return -1; - } - memset(storage_map, 0x00, sizeof(StorageMapping *) * STORAGE_MAX); - - for (i = 0; i < STORAGE_MAX; i++) { - if (storage_max_id[i] > 0) { - storage_map[i] = SCMalloc(sizeof(StorageMapping) * storage_max_id[i]); - if (storage_map[i] == NULL) - return -1; - memset(storage_map[i], 0x00, sizeof(StorageMapping) * storage_max_id[i]); - } - } - - StorageList *entry = storage_list; - while (entry) { - if (storage_map[entry->map.type] != NULL) { - storage_map[entry->map.type][entry->id].name = entry->map.name; - storage_map[entry->map.type][entry->id].type = entry->map.type; - storage_map[entry->map.type][entry->id].size = entry->map.size; - storage_map[entry->map.type][entry->id].Alloc = entry->map.Alloc; - storage_map[entry->map.type][entry->id].Free = entry->map.Free; - } - - entry = entry->next; - }; - -#ifdef DEBUG - for (i = 0; i < STORAGE_MAX; i++) { - if (storage_map[i] == NULL) - continue; - - int j; - for (j = 0; j < storage_max_id[i]; j++) { - StorageMapping *m = &storage_map[i][j]; - SCLogDebug("type \"%s\" name \"%s\" size \"%"PRIuMAX"\"", - StoragePrintType(m->type), m->name, (uintmax_t)m->size); - } - } -#endif - return 0; -} - -unsigned int StorageGetCnt(StorageEnum type) -{ - return storage_max_id[type]; -} - -/** \brief get the size of the void array used to store - * the pointers - * \retval size size in bytes, can return 0 if not storage is needed - * - * \todo we could return -1 when registration isn't closed yet, however - * this will break lots of tests currently, so not doing it now */ -unsigned int StorageGetSize(StorageEnum type) -{ - return storage_max_id[type] * sizeof(void *); -} - -void *StorageGetById(const Storage *storage, const StorageEnum type, const int id) -{ -#ifdef DEBUG - BUG_ON(!storage_registraton_closed); -#endif - SCLogDebug("storage %p id %d", storage, id); - if (storage == NULL) - return NULL; - return storage[id]; -} - -int StorageSetById(Storage *storage, const StorageEnum type, const int id, void *ptr) -{ -#ifdef DEBUG - BUG_ON(!storage_registraton_closed); -#endif - SCLogDebug("storage %p id %d", storage, id); - if (storage == NULL) - return -1; - storage[id] = ptr; - return 0; -} - -void *StorageAllocByIdPrealloc(Storage *storage, StorageEnum type, int id) -{ -#ifdef DEBUG - BUG_ON(!storage_registraton_closed); -#endif - SCLogDebug("storage %p id %d", storage, id); - - StorageMapping *map = &storage_map[type][id]; - if (storage[id] == NULL && map->Alloc != NULL) { - storage[id] = map->Alloc(map->size); - if (storage[id] == NULL) { - return NULL; - } - } - - return storage[id]; -} - -void *StorageAllocById(Storage **storage, StorageEnum type, int id) -{ -#ifdef DEBUG - BUG_ON(!storage_registraton_closed); -#endif - SCLogDebug("storage %p id %d", storage, id); - - StorageMapping *map = &storage_map[type][id]; - Storage *store = *storage; - if (store == NULL) { - store = SCMalloc(sizeof(void *) * storage_max_id[type]); - if (unlikely(store == NULL)) - return NULL; - memset(store, 0x00, sizeof(void *) * storage_max_id[type]); - } - SCLogDebug("store %p", store); - - if (store[id] == NULL && map->Alloc != NULL) { - store[id] = map->Alloc(map->size); - if (store[id] == NULL) { - SCFree(store); - *storage = NULL; - return NULL; - } - } - - *storage = store; - return store[id]; -} - -void StorageFreeById(Storage *storage, StorageEnum type, int id) -{ -#ifdef DEBUG - BUG_ON(!storage_registraton_closed); -#endif -#ifdef UNITTESTS - if (storage_map == NULL) - return; -#endif - SCLogDebug("storage %p id %d", storage, id); - - Storage *store = storage; - if (store != NULL) { - SCLogDebug("store %p", store); - if (store[id] != NULL) { - StorageMapping *map = &storage_map[type][id]; - map->Free(store[id]); - store[id] = NULL; - } - } -} - -void StorageFreeAll(Storage *storage, StorageEnum type) -{ - if (storage == NULL) - return; -#ifdef DEBUG - BUG_ON(!storage_registraton_closed); -#endif -#ifdef UNITTESTS - if (storage_map == NULL) - return; -#endif - - Storage *store = storage; - int i; - for (i = 0; i < storage_max_id[type]; i++) { - if (store[i] != NULL) { - StorageMapping *map = &storage_map[type][i]; - map->Free(store[i]); - store[i] = NULL; - } - } -} - -void StorageFree(Storage **storage, StorageEnum type) -{ - if (*storage == NULL) - return; - -#ifdef DEBUG - BUG_ON(!storage_registraton_closed); -#endif -#ifdef UNITTESTS - if (storage_map == NULL) - return; -#endif - - Storage *store = *storage; - int i; - for (i = 0; i < storage_max_id[type]; i++) { - if (store[i] != NULL) { - StorageMapping *map = &storage_map[type][i]; - map->Free(store[i]); - store[i] = NULL; - } - } - SCFree(*storage); - *storage = NULL; -} - -#ifdef UNITTESTS - -static void *StorageTestAlloc(unsigned int size) -{ - void *x = SCMalloc(size); - return x; -} -static void StorageTestFree(void *x) -{ - if (x) - SCFree(x); -} - -static int StorageTest01(void) -{ - StorageInit(); - - int id = StorageRegister(STORAGE_HOST, "test", 8, StorageTestAlloc, StorageTestFree); - if (id < 0) - goto error; - id = StorageRegister(STORAGE_HOST, "variable", 24, StorageTestAlloc, StorageTestFree); - if (id < 0) - goto error; - id = StorageRegister(STORAGE_FLOW, "store", sizeof(void *), StorageTestAlloc, StorageTestFree); - if (id < 0) - goto error; - - if (StorageFinalize() < 0) - goto error; - - StorageCleanup(); - return 1; -error: - StorageCleanup(); - return 0; -} - -struct StorageTest02Data { - int abc; -}; - -static void *StorageTest02Init(unsigned int size) -{ - struct StorageTest02Data *data = (struct StorageTest02Data *)SCMalloc(size); - if (data != NULL) - data->abc = 1234; - return (void *)data; -} - -static int StorageTest02(void) -{ - struct StorageTest02Data *test = NULL; - - StorageInit(); - - int id1 = StorageRegister(STORAGE_HOST, "test", 4, StorageTest02Init, StorageTestFree); - if (id1 < 0) { - printf("StorageRegister failed (2): "); - goto error; - } - int id2 = StorageRegister(STORAGE_HOST, "test2", 4, StorageTest02Init, StorageTestFree); - if (id2 < 0) { - printf("StorageRegister failed (2): "); - goto error; - } - - if (StorageFinalize() < 0) { - printf("StorageFinalize failed: "); - goto error; - } - - Storage *storage = NULL; - void *data = StorageAllocById(&storage, STORAGE_HOST, id1); - if (data == NULL) { - printf("StorageAllocById failed, data == NULL, storage %p: ", storage); - goto error; - } - test = (struct StorageTest02Data *)data; - if (test->abc != 1234) { - printf("setup failed, test->abc != 1234, but %d (1):", test->abc); - goto error; - } - test->abc = 4321; - - data = StorageAllocById(&storage, STORAGE_HOST, id2); - if (data == NULL) { - printf("StorageAllocById failed, data == NULL, storage %p: ", storage); - goto error; - } - test = (struct StorageTest02Data *)data; - if (test->abc != 1234) { - printf("setup failed, test->abc != 1234, but %d (2):", test->abc); - goto error; - } - - data = StorageGetById(storage, STORAGE_HOST, id1); - if (data == NULL) { - printf("StorageAllocById failed, data == NULL, storage %p: ", storage); - goto error; - } - test = (struct StorageTest02Data *)data; - if (test->abc != 4321) { - printf("setup failed, test->abc != 4321, but %d (3):", test->abc); - goto error; - } - - //StorageFreeById(storage, STORAGE_HOST, id1); - //StorageFreeById(storage, STORAGE_HOST, id2); - - StorageFree(&storage, STORAGE_HOST); - - StorageCleanup(); - return 1; -error: - StorageCleanup(); - return 0; -} - -static int StorageTest03(void) -{ - StorageInit(); - - int id = StorageRegister(STORAGE_HOST, "test", 8, StorageTestAlloc, StorageTestFree); - if (id < 0) - goto error; - id = StorageRegister(STORAGE_HOST, "test", 8, StorageTestAlloc, StorageTestFree); - if (id != -1) { - printf("duplicate registration should have failed: "); - goto error; - } - - id = StorageRegister(STORAGE_HOST, "test1", 6, NULL, StorageTestFree); - if (id != -1) { - printf("duplicate registration should have failed (2): "); - goto error; - } - - id = StorageRegister(STORAGE_HOST, "test2", 8, StorageTestAlloc, NULL); - if (id != -1) { - printf("duplicate registration should have failed (3): "); - goto error; - } - - id = StorageRegister(STORAGE_HOST, "test3", 0, StorageTestAlloc, StorageTestFree); - if (id != -1) { - printf("duplicate registration should have failed (4): "); - goto error; - } - - id = StorageRegister(STORAGE_HOST, "", 8, StorageTestAlloc, StorageTestFree); - if (id != -1) { - printf("duplicate registration should have failed (5): "); - goto error; - } - - id = StorageRegister(STORAGE_HOST, NULL, 8, StorageTestAlloc, StorageTestFree); - if (id != -1) { - printf("duplicate registration should have failed (6): "); - goto error; - } - - id = StorageRegister(STORAGE_MAX, "test4", 8, StorageTestAlloc, StorageTestFree); - if (id != -1) { - printf("duplicate registration should have failed (7): "); - goto error; - } - - id = StorageRegister(38, "test5", 8, StorageTestAlloc, StorageTestFree); - if (id != -1) { - printf("duplicate registration should have failed (8): "); - goto error; - } - - id = StorageRegister(-1, "test6", 8, StorageTestAlloc, StorageTestFree); - if (id != -1) { - printf("duplicate registration should have failed (9): "); - goto error; - } - - StorageCleanup(); - return 1; -error: - StorageCleanup(); - return 0; -} - -void StorageRegisterTests(void) -{ - UtRegisterTest("StorageTest01", StorageTest01, 1); - UtRegisterTest("StorageTest02", StorageTest02, 1); - UtRegisterTest("StorageTest03", StorageTest03, 1); -} -#endif diff --git a/framework/src/suricata/src/util-storage.h b/framework/src/suricata/src/util-storage.h deleted file mode 100644 index d88b030f..00000000 --- a/framework/src/suricata/src/util-storage.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Storage API - */ - -#ifndef __UTIL_STORAGE_H__ -#define __UTIL_STORAGE_H__ - -typedef enum StorageEnum_ { - STORAGE_HOST, - STORAGE_FLOW, - STORAGE_IPPAIR, - - STORAGE_MAX, -} StorageEnum; - -/** void ptr array for now */ -typedef void* Storage; - -void StorageInit(void); -void StorageCleanup(void); - -/** \brief Register new storage - * - * \param type type from StorageEnum - * \param name name - * \param size size of the per instance storage - * \param Alloc alloc function for per instance storage - * \param Free free function for per instance storage - * - * \note if size == ptr size (so sizeof(void *)) and Alloc == NULL the API just - * gives the caller a ptr to store something it alloc'ed itself. - */ -int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void (*Free)(void *)); -int StorageFinalize(void); - -unsigned int StorageGetCnt(const StorageEnum type); -unsigned int StorageGetSize(const StorageEnum type); - -/** \brief get storage for id */ -void *StorageGetById(const Storage *storage, const StorageEnum type, const int id); -/** \brief set storage for id */ -int StorageSetById(Storage *storage, const StorageEnum type, const int id, void *ptr); - -/** \brief AllocById func for prealloc'd base storage (storage ptrs are part - * of another memory block) */ -void *StorageAllocByIdPrealloc(Storage *storage, StorageEnum type, int id); -/** \brief AllocById func for when we manage the Storage ptr itself */ -void *StorageAllocById(Storage **storage, const StorageEnum type, const int id); -void StorageFreeById(Storage *storage, const StorageEnum type, const int id); -void StorageFreeAll(Storage *storage, const StorageEnum type); -void StorageFree(Storage **storage, const StorageEnum type); - -void StorageRegisterTests(void); -#endif diff --git a/framework/src/suricata/src/util-strlcatu.c b/framework/src/suricata/src/util-strlcatu.c deleted file mode 100644 index 2edb8080..00000000 --- a/framework/src/suricata/src/util-strlcatu.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 1998 Todd C. Miller - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* $Id: strlcatu.c,v 1.4 2003/10/20 15:03:27 chrisgreen Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef HAVE_STRLCAT - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcat.c,v 1.5 2001/01/13 16:17:24 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include - -/* - * Appends src to string dst of size siz (unlike strncat, siz is the - * full size of dst, not space left). At most siz-1 characters - * will be copied. Always NUL terminates (unless siz <= strlen(dst)). - * Returns strlen(initial dst) + strlen(src); if retval >= siz, - * truncation occurred. - */ -size_t strlcat(dst, src, siz) - char *dst; - const char *src; - size_t siz; -{ - register char *d = dst; - register const char *s = src; - register size_t n = siz; - size_t dlen; - - /* Find the end of dst and adjust bytes left but don't go past end */ - while (n-- != 0 && *d != '\0') - d++; - dlen = d - dst; - n = siz - dlen; - - if (n == 0) - return(dlen + strlen(s)); - while (*s != '\0') { - if (n != 1) { - *d++ = *s; - n--; - } - s++; - } - *d = '\0'; - - return(dlen + (s - src)); /* count does not include NUL */ -} -#endif diff --git a/framework/src/suricata/src/util-strlcpyu.c b/framework/src/suricata/src/util-strlcpyu.c deleted file mode 100644 index 80694580..00000000 --- a/framework/src/suricata/src/util-strlcpyu.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 1998 Todd C. Miller - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* $Id: strlcpyu.c,v 1.4 2003/10/20 15:03:27 chrisgreen Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef HAVE_STRLCPY - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include - -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -size_t strlcpy(dst, src, siz) - char *dst; - const char *src; - size_t siz; -{ - register char *d = dst; - register const char *s = src; - register size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) { - do { - if ((*d++ = *s++) == 0) - break; - } while (--n != 0); - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ -} -#endif diff --git a/framework/src/suricata/src/util-syslog.c b/framework/src/suricata/src/util-syslog.c deleted file mode 100644 index 5b3f7da4..00000000 --- a/framework/src/suricata/src/util-syslog.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - * Syslog utility file - * - */ - -#include "suricata-common.h" - -/* holds the string-enum mapping for the syslog facility in SCLogOPIfaceCtx */ -SCEnumCharMap sc_syslog_facility_map[] = { - { "auth", LOG_AUTH }, - { "authpriv", LOG_AUTHPRIV }, - { "cron", LOG_CRON }, - { "daemon", LOG_DAEMON }, - { "ftp", LOG_FTP }, - { "kern", LOG_KERN }, - { "lpr", LOG_LPR }, - { "mail", LOG_MAIL }, - { "news", LOG_NEWS }, - { "security", LOG_AUTH }, - { "syslog", LOG_SYSLOG }, - { "user", LOG_USER }, - { "uucp", LOG_UUCP }, - { "local0", LOG_LOCAL0 }, - { "local1", LOG_LOCAL1 }, - { "local2", LOG_LOCAL2 }, - { "local3", LOG_LOCAL3 }, - { "local4", LOG_LOCAL4 }, - { "local5", LOG_LOCAL5 }, - { "local6", LOG_LOCAL6 }, - { "local7", LOG_LOCAL7 }, - { NULL, -1 } -}; - -/** \brief returns the syslog facility enum map */ -SCEnumCharMap *SCSyslogGetFacilityMap() -{ - return sc_syslog_facility_map; -} - -SCEnumCharMap sc_syslog_level_map[ ] = { - { "Emergency", LOG_EMERG }, - { "Alert", LOG_ALERT }, - { "Critical", LOG_CRIT }, - { "Error", LOG_ERR }, - { "Warning", LOG_WARNING }, - { "Notice", LOG_NOTICE }, - { "Info", LOG_INFO }, - { "Debug", LOG_DEBUG }, - { NULL, -1 } -}; - -/** \brief returns the syslog facility enum map */ -SCEnumCharMap *SCSyslogGetLogLevelMap() -{ - return sc_syslog_level_map; -} - diff --git a/framework/src/suricata/src/util-syslog.h b/framework/src/suricata/src/util-syslog.h deleted file mode 100644 index 0efc1c5d..00000000 --- a/framework/src/suricata/src/util-syslog.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Gurvinder Singh - * - */ - -#ifndef UTIL_SYSLOG_H -#define UTIL_SYSLOG_H - -SCEnumCharMap *SCSyslogGetFacilityMap(void); -SCEnumCharMap *SCSyslogGetLogLevelMap(void); - -#endif /* UTIL_SYSLOG_H */ diff --git a/framework/src/suricata/src/util-threshold-config.c b/framework/src/suricata/src/util-threshold-config.c deleted file mode 100644 index 6698b16f..00000000 --- a/framework/src/suricata/src/util-threshold-config.c +++ /dev/null @@ -1,2909 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \ingroup threshold - * @{ - */ - -/** - * \file - * - * \author Breno Silva Pinto - * - * \todo Need to support suppress - * - * Implements Threshold support - */ - -#include "suricata-common.h" - -#include "host.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-address.h" -#include "detect-threshold.h" -#include "detect-parse.h" - -#include "conf.h" -#include "util-threshold-config.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-byte.h" -#include "util-time.h" -#include "util-error.h" -#include "util-debug.h" -#include "util-fmemopen.h" - -typedef enum ThresholdRuleType { - THRESHOLD_TYPE_EVENT_FILTER, - THRESHOLD_TYPE_THRESHOLD, - THRESHOLD_TYPE_RATE, - THRESHOLD_TYPE_SUPPRESS, -} ThresholdRuleType; - -/* File descriptor for unittests */ - -/* common base for all options */ -#define DETECT_BASE_REGEX "^\\s*(event_filter|threshold|rate_filter|suppress)\\s*gen_id\\s*(\\d+)\\s*,\\s*sig_id\\s*(\\d+)\\s*(.*)\\s*$" - -#define DETECT_THRESHOLD_REGEX "^,\\s*type\\s*(limit|both|threshold)\\s*,\\s*track\\s*(by_dst|by_src)\\s*,\\s*count\\s*(\\d+)\\s*,\\s*seconds\\s*(\\d+)\\s*$" - -/* TODO: "apply_to" */ -#define DETECT_RATE_REGEX "^,\\s*track\\s*(by_dst|by_src|by_rule)\\s*,\\s*count\\s*(\\d+)\\s*,\\s*seconds\\s*(\\d+)\\s*,\\s*new_action\\s*(alert|drop|pass|log|sdrop|reject)\\s*,\\s*timeout\\s*(\\d+)\\s*$" - -/* - * suppress has two form: - * suppress gen_id 0, sig_id 0, track by_dst, ip 10.88.0.14 - * suppress gen_id 1, sig_id 2000328 - * suppress gen_id 1, sig_id 2000328, track by_src, ip fe80::/10 -*/ -#define DETECT_SUPPRESS_REGEX "^,\\s*track\\s*(by_dst|by_src|by_either)\\s*,\\s*ip\\s*([\\[\\],\\$\\da-zA-Z.:/_]+)*\\s*$" - -/* Default path for the threshold.config file */ -#if defined OS_WIN32 || defined __CYGWIN__ -#define THRESHOLD_CONF_DEF_CONF_FILEPATH CONFIG_DIR "\\\\threshold.config" -#else -#define THRESHOLD_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/threshold.config" -#endif - -static pcre *regex_base = NULL; -static pcre_extra *regex_base_study = NULL; - -static pcre *regex_threshold = NULL; -static pcre_extra *regex_threshold_study = NULL; - -static pcre *regex_rate = NULL; -static pcre_extra *regex_rate_study = NULL; - -static pcre *regex_suppress = NULL; -static pcre_extra *regex_suppress_study = NULL; - -/** - * \brief Returns the path for the Threshold Config file. We check if we - * can retrieve the path from the yaml conf file. If it is not present, - * return the default path for the threshold file which is - * "./threshold.config". - * - * \retval log_filename Pointer to a string containing the path for the - * Threshold Config file. - */ -static char *SCThresholdConfGetConfFilename(const DetectEngineCtx *de_ctx) -{ - char *log_filename = NULL; - char config_value[256] = ""; - - if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0) { - snprintf(config_value, sizeof(config_value), - "%s.threshold-file", de_ctx->config_prefix); - - /* try loading prefix setting, fall back to global if that - * fails. */ - if (ConfGet(config_value, &log_filename) != 1) { - if (ConfGet("threshold-file", &log_filename) != 1) { - log_filename = (char *)THRESHOLD_CONF_DEF_CONF_FILEPATH; - } - } - } else { - if (ConfGet("threshold-file", &log_filename) != 1) { - log_filename = (char *)THRESHOLD_CONF_DEF_CONF_FILEPATH; - } - } - return log_filename; -} - -/** - * \brief Inits the context to be used by the Threshold Config parsing API. - * - * This function initializes the hash table to be used by the Detection - * Engine Context to hold the data from the threshold.config file, - * obtains the file desc to parse the threshold.config file, and - * inits the regex used to parse the lines from threshold.config - * file. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param utfd Pointer for unit test file descriptor. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCThresholdConfInitContext(DetectEngineCtx *de_ctx, FILE *utfd) -{ - char *filename = NULL; - const char *eb = NULL; - FILE *fd = utfd; - int eo; - int opts = 0; - - if (fd == NULL) { - filename = SCThresholdConfGetConfFilename(de_ctx); - if ( (fd = fopen(filename, "r")) == NULL) { - SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, strerror(errno)); - goto error; - } - } - - regex_base = pcre_compile(DETECT_BASE_REGEX, opts, &eb, &eo, NULL); - if (regex_base == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_BASE_REGEX, eo, eb); - goto error; - } - - regex_base_study = pcre_study(regex_base, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - regex_threshold = pcre_compile(DETECT_THRESHOLD_REGEX, opts, &eb, &eo, NULL); - if (regex_threshold == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_THRESHOLD_REGEX, eo, eb); - goto error; - } - - regex_threshold_study = pcre_study(regex_threshold, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - regex_rate = pcre_compile(DETECT_RATE_REGEX, opts, &eb, &eo, NULL); - if (regex_rate == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_RATE_REGEX, eo, eb); - goto error; - } - - regex_rate_study = pcre_study(regex_rate, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - regex_suppress = pcre_compile(DETECT_SUPPRESS_REGEX, opts, &eb, &eo, NULL); - if (regex_suppress == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s",DETECT_SUPPRESS_REGEX, eo, eb); - goto error; - } - - regex_suppress_study = pcre_study(regex_suppress, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - SCThresholdConfParseFile(de_ctx, fd); - SCThresholdConfDeInitContext(de_ctx, fd); - - SCLogDebug("Global thresholding options defined"); - return 0; - -error: - SCThresholdConfDeInitContext(de_ctx, fd); - return -1; -} - -/** - * \brief Releases resources used by the Threshold Config API. - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param fd Pointer to file descriptor. - */ -void SCThresholdConfDeInitContext(DetectEngineCtx *de_ctx, FILE *fd) -{ - if (fd != NULL) - fclose(fd); - - if (regex_base != NULL) { - pcre_free(regex_base); - regex_base = NULL; - } - if (regex_base_study != NULL) { - pcre_free(regex_base_study); - regex_base_study = NULL; - } - - if (regex_threshold != NULL) { - pcre_free(regex_threshold); - regex_threshold = NULL; - } - if (regex_threshold_study != NULL) { - pcre_free(regex_threshold_study); - regex_threshold_study = NULL; - } - - if (regex_rate != NULL) { - pcre_free(regex_rate); - regex_rate = NULL; - } - if (regex_rate_study != NULL) { - pcre_free(regex_rate_study); - regex_rate_study = NULL; - } - - if (regex_suppress != NULL) { - pcre_free(regex_suppress); - regex_suppress = NULL; - } - if (regex_suppress_study != NULL) { - pcre_free(regex_suppress_study); - regex_suppress_study = NULL; - } - - return; -} - -/** \internal - * \brief setup suppress rules - * \retval 0 ok - * \retval -1 error - */ -static int SetupSuppressRule(DetectEngineCtx *de_ctx, uint32_t id, uint32_t gid, - uint8_t parsed_type, uint8_t parsed_track, uint32_t parsed_count, - uint32_t parsed_seconds, uint32_t parsed_timeout, uint8_t parsed_new_action, - const char *th_ip) -{ - Signature *s = NULL; - SigMatch *sm = NULL; - DetectThresholdData *de = NULL; - - BUG_ON(parsed_type != TYPE_SUPPRESS); - - /* Install it */ - if (id == 0 && gid == 0) { - if (parsed_track == TRACK_RULE) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "suppressing all rules"); - } - - /* update each sig with our suppress info */ - for (s = de_ctx->sig_list; s != NULL; s = s->next) { - /* tag the rule as noalert */ - if (parsed_track == TRACK_RULE) { - s->flags |= SIG_FLAG_NOALERT; - continue; - } - - de = SCMalloc(sizeof(DetectThresholdData)); - if (unlikely(de == NULL)) - goto error; - memset(de,0,sizeof(DetectThresholdData)); - - de->type = TYPE_SUPPRESS; - de->track = parsed_track; - de->count = parsed_count; - de->seconds = parsed_seconds; - de->new_action = parsed_new_action; - de->timeout = parsed_timeout; - - if (parsed_track != TRACK_RULE) { - if (DetectAddressParse((const DetectEngineCtx *)de_ctx, &de->addrs, (char *)th_ip) != 0) { - SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "failed to parse %s", th_ip); - goto error; - } - } - - sm = SigMatchAlloc(); - if (sm == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch"); - goto error; - } - - sm->type = DETECT_THRESHOLD; - sm->ctx = (void *)de; - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_SUPPRESS); - } - } else if (id == 0 && gid > 0) { - if (parsed_track == TRACK_RULE) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "suppressing all rules with gid %"PRIu32, gid); - } - /* set up suppression for each signature with a matching gid */ - for (s = de_ctx->sig_list; s != NULL; s = s->next) { - if (s->gid != gid) - continue; - - /* tag the rule as noalert */ - if (parsed_track == TRACK_RULE) { - s->flags |= SIG_FLAG_NOALERT; - continue; - } - - de = SCMalloc(sizeof(DetectThresholdData)); - if (unlikely(de == NULL)) - goto error; - - memset(de,0,sizeof(DetectThresholdData)); - - de->type = TYPE_SUPPRESS; - de->track = parsed_track; - de->count = parsed_count; - de->seconds = parsed_seconds; - de->new_action = parsed_new_action; - de->timeout = parsed_timeout; - - if (parsed_track != TRACK_RULE) { - if (DetectAddressParse((const DetectEngineCtx *)de_ctx, &de->addrs, (char *)th_ip) != 0) { - SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "failed to parse %s", th_ip); - goto error; - } - } - - sm = SigMatchAlloc(); - if (sm == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch"); - goto error; - } - - sm->type = DETECT_THRESHOLD; - sm->ctx = (void *)de; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_SUPPRESS); - } - } else if (id > 0 && gid == 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Can't use a event config that has " - "sid > 0 and gid == 0. Please fix this " - "in your threshold.conf file"); - goto error; - } else { - s = SigFindSignatureBySidGid(de_ctx, id, gid); - if (s == NULL) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "can't suppress sid " - "%"PRIu32", gid %"PRIu32": unknown rule", id, gid); - } else { - if (parsed_track == TRACK_RULE) { - s->flags |= SIG_FLAG_NOALERT; - goto end; - } - - de = SCMalloc(sizeof(DetectThresholdData)); - if (unlikely(de == NULL)) - goto error; - memset(de,0,sizeof(DetectThresholdData)); - - de->type = TYPE_SUPPRESS; - de->track = parsed_track; - de->count = parsed_count; - de->seconds = parsed_seconds; - de->new_action = parsed_new_action; - de->timeout = parsed_timeout; - - if (DetectAddressParse((const DetectEngineCtx *)de_ctx, &de->addrs, (char *)th_ip) != 0) { - SCLogError(SC_ERR_INVALID_IP_NETBLOCK, "failed to parse %s", th_ip); - goto error; - } - - sm = SigMatchAlloc(); - if (sm == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch"); - goto error; - } - - sm->type = DETECT_THRESHOLD; - sm->ctx = (void *)de; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_SUPPRESS); - } - } - -end: - return 0; -error: - if (de != NULL) { - DetectAddressHeadCleanup(&de->addrs); - SCFree(de); - } - return -1; -} - -/** \internal - * \brief setup suppress rules - * \retval 0 ok - * \retval -1 error - */ -static int SetupThresholdRule(DetectEngineCtx *de_ctx, uint32_t id, uint32_t gid, - uint8_t parsed_type, uint8_t parsed_track, uint32_t parsed_count, - uint32_t parsed_seconds, uint32_t parsed_timeout, uint8_t parsed_new_action, - const char *th_ip) -{ - Signature *s = NULL; - SigMatch *sm = NULL; - DetectThresholdData *de = NULL; - void *ptmp; - - BUG_ON(parsed_type == TYPE_SUPPRESS); - - /* Install it */ - if (id == 0 && gid == 0) { - for (s = de_ctx->sig_list; s != NULL; s = s->next) { - sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]); - if (sm != NULL) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has " - "an event var set. The signature event var is " - "given precedence over the threshold.conf one. " - "We'll change this in the future though.", s->id); - continue; - } - - sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_THRESHOLD]); - if (sm != NULL) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has " - "an event var set. The signature event var is " - "given precedence over the threshold.conf one. " - "We'll change this in the future though.", s->id); - continue; - } - - de = SCMalloc(sizeof(DetectThresholdData)); - if (unlikely(de == NULL)) - goto error; - memset(de,0,sizeof(DetectThresholdData)); - - de->type = parsed_type; - de->track = parsed_track; - de->count = parsed_count; - de->seconds = parsed_seconds; - de->new_action = parsed_new_action; - de->timeout = parsed_timeout; - - sm = SigMatchAlloc(); - if (sm == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch"); - goto error; - } - - if (parsed_type == TYPE_RATE) - sm->type = DETECT_DETECTION_FILTER; - else - sm->type = DETECT_THRESHOLD; - sm->ctx = (void *)de; - - if (parsed_track == TRACK_RULE) { - ptmp = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *)); - if (ptmp == NULL) { - SCFree(de_ctx->ths_ctx.th_entry); - de_ctx->ths_ctx.th_entry = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config" - " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1); - } else { - de_ctx->ths_ctx.th_entry = ptmp; - de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL; - de_ctx->ths_ctx.th_size++; - } - } - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD); - } - - } else if (id == 0 && gid > 0) { - for (s = de_ctx->sig_list; s != NULL; s = s->next) { - if (s->gid == gid) { - sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]); - if (sm != NULL) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has " - "an event var set. The signature event var is " - "given precedence over the threshold.conf one. " - "We'll change this in the future though.", id); - continue; - } - - sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_THRESHOLD]); - if (sm != NULL) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has " - "an event var set. The signature event var is " - "given precedence over the threshold.conf one. " - "We'll change this in the future though.", id); - continue; - } - - de = SCMalloc(sizeof(DetectThresholdData)); - if (unlikely(de == NULL)) - goto error; - memset(de,0,sizeof(DetectThresholdData)); - - de->type = parsed_type; - de->track = parsed_track; - de->count = parsed_count; - de->seconds = parsed_seconds; - de->new_action = parsed_new_action; - de->timeout = parsed_timeout; - - sm = SigMatchAlloc(); - if (sm == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch"); - goto error; - } - - if (parsed_type == TYPE_RATE) - sm->type = DETECT_DETECTION_FILTER; - else - sm->type = DETECT_THRESHOLD; - sm->ctx = (void *)de; - - if (parsed_track == TRACK_RULE) { - ptmp = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *)); - if (ptmp == NULL) { - SCFree(de_ctx->ths_ctx.th_entry); - de_ctx->ths_ctx.th_entry = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config" - " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1); - } else { - de_ctx->ths_ctx.th_entry = ptmp; - de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL; - de_ctx->ths_ctx.th_size++; - } - } - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD); - } - } - } else if (id > 0 && gid == 0) { - SCLogError(SC_ERR_INVALID_VALUE, "Can't use a event config that has " - "sid > 0 and gid == 0. Please fix this " - "in your threshold.conf file"); - } else { - s = SigFindSignatureBySidGid(de_ctx, id, gid); - if (s == NULL) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "can't suppress sid " - "%"PRIu32", gid %"PRIu32": unknown rule", id, gid); - } else { - if (parsed_type != TYPE_SUPPRESS && parsed_type != TYPE_THRESHOLD && - parsed_type != TYPE_BOTH && parsed_type != TYPE_LIMIT) - { - sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]); - if (sm != NULL) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has " - "a threshold set. The signature event var is " - "given precedence over the threshold.conf one. " - "Bug #425.", s->id); - goto end; - } - - sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_THRESHOLD]); - if (sm != NULL) { - SCLogWarning(SC_ERR_EVENT_ENGINE, "signature sid:%"PRIu32 " has " - "a detection_filter set. The signature event var is " - "given precedence over the threshold.conf one. " - "Bug #425.", s->id); - goto end; - } - - /* replace threshold on sig if we have a global override for it */ -#if 1 - } else if (parsed_type == TYPE_THRESHOLD || parsed_type == TYPE_BOTH || parsed_type == TYPE_LIMIT) { - sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]); - if (sm == NULL) { - sm = SigMatchGetLastSMFromLists(s, 2, - DETECT_DETECTION_FILTER, s->sm_lists[DETECT_SM_LIST_THRESHOLD]); - } - if (sm != NULL) { - SigMatchRemoveSMFromList(s, sm, DETECT_SM_LIST_THRESHOLD); - SigMatchFree(sm); - sm = NULL; - } -#endif - } - - de = SCMalloc(sizeof(DetectThresholdData)); - if (unlikely(de == NULL)) - goto error; - memset(de,0,sizeof(DetectThresholdData)); - - de->type = parsed_type; - de->track = parsed_track; - de->count = parsed_count; - de->seconds = parsed_seconds; - de->new_action = parsed_new_action; - de->timeout = parsed_timeout; - - sm = SigMatchAlloc(); - if (sm == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating SigMatch"); - goto error; - } - - if (parsed_type == TYPE_RATE) - sm->type = DETECT_DETECTION_FILTER; - else - sm->type = DETECT_THRESHOLD; - sm->ctx = (void *)de; - - if (parsed_track == TRACK_RULE) { - ptmp = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *)); - if (ptmp == NULL) { - SCFree(de_ctx->ths_ctx.th_entry); - de_ctx->ths_ctx.th_entry = NULL; - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config" - " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1); - } else { - de_ctx->ths_ctx.th_entry = ptmp; - de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL; - de_ctx->ths_ctx.th_size++; - } - } - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD); - } - } -end: - return 0; -error: - if (de != NULL) { - DetectAddressHeadCleanup(&de->addrs); - SCFree(de); - } - return -1; -} - -static int ParseThresholdRule(DetectEngineCtx *de_ctx, char *rawstr, - uint32_t *ret_id, uint32_t *ret_gid, - uint8_t *ret_parsed_type, uint8_t *ret_parsed_track, - uint32_t *ret_parsed_count, uint32_t *ret_parsed_seconds, uint32_t *ret_parsed_timeout, - uint8_t *ret_parsed_new_action, - const char **ret_th_ip) -{ - char th_rule_type[32]; - char th_gid[16]; - char th_sid[16]; - char rule_extend[1024]; - const char *th_type = NULL; - const char *th_track = NULL; - const char *th_count = NULL; - const char *th_seconds = NULL; - const char *th_new_action= NULL; - const char *th_timeout = NULL; - const char *th_ip = NULL; - - uint8_t parsed_type = 0; - uint8_t parsed_track = 0; - uint8_t parsed_new_action = 0; - uint32_t parsed_count = 0; - uint32_t parsed_seconds = 0; - uint32_t parsed_timeout = 0; - -#define MAX_SUBSTRINGS 30 - int ret = 0; - int ov[MAX_SUBSTRINGS]; - uint32_t id = 0, gid = 0; - ThresholdRuleType rule_type; - - if (de_ctx == NULL) - return -1; - - ret = pcre_exec(regex_base, regex_base_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 4) { - SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr); - goto error; - } - - /* retrieve the classtype name */ - ret = pcre_copy_substring((char *)rawstr, ov, 30, 1, th_rule_type, sizeof(th_rule_type)); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - /* retrieve the classtype name */ - ret = pcre_copy_substring((char *)rawstr, ov, 30, 2, th_gid, sizeof(th_gid)); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - ret = pcre_copy_substring((char *)rawstr, ov, 30, 3, th_sid, sizeof(th_sid)); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - ret = pcre_copy_substring((char *)rawstr, ov, 30, 4, rule_extend, sizeof(rule_extend)); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed"); - goto error; - } - - /* get type of rule */ - if (strcasecmp(th_rule_type,"event_filter") == 0) { - rule_type = THRESHOLD_TYPE_EVENT_FILTER; - } else if (strcasecmp(th_rule_type,"threshold") == 0) { - rule_type = THRESHOLD_TYPE_THRESHOLD; - } else if (strcasecmp(th_rule_type,"rate_filter") == 0) { - rule_type = THRESHOLD_TYPE_RATE; - } else if (strcasecmp(th_rule_type,"suppress") == 0) { - rule_type = THRESHOLD_TYPE_SUPPRESS; - } else { - SCLogError(SC_ERR_INVALID_VALUE, "rule type %s is unknown", th_rule_type); - goto error; - } - - /* get end of rule */ - switch(rule_type) { - case THRESHOLD_TYPE_EVENT_FILTER: - case THRESHOLD_TYPE_THRESHOLD: - if (strlen(rule_extend) > 0) { - ret = pcre_exec(regex_threshold, regex_threshold_study, - rule_extend, strlen(rule_extend), - 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 4) { - SCLogError(SC_ERR_PCRE_MATCH, - "pcre_exec parse error, ret %" PRId32 ", string %s", - ret, rule_extend); - goto error; - } - - ret = pcre_get_substring((char *)rule_extend, ov, 30, 1, &th_type); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - ret = pcre_get_substring((char *)rule_extend, ov, 30, 2, &th_track); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - ret = pcre_get_substring((char *)rule_extend, ov, 30, 3, &th_count); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - ret = pcre_get_substring((char *)rule_extend, ov, 30, 4, &th_seconds); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (strcasecmp(th_type,"limit") == 0) - parsed_type = TYPE_LIMIT; - else if (strcasecmp(th_type,"both") == 0) - parsed_type = TYPE_BOTH; - else if (strcasecmp(th_type,"threshold") == 0) - parsed_type = TYPE_THRESHOLD; - else { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "limit type not supported: %s", th_type); - goto error; - } - } else { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "rule invalid: %s", rawstr); - goto error; - } - break; - case THRESHOLD_TYPE_SUPPRESS: - if (strlen(rule_extend) > 0) { - ret = pcre_exec(regex_suppress, regex_suppress_study, - rule_extend, strlen(rule_extend), - 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 2) { - SCLogError(SC_ERR_PCRE_MATCH, - "pcre_exec parse error, ret %" PRId32 ", string %s", - ret, rule_extend); - goto error; - } - /* retrieve the track mode */ - ret = pcre_get_substring((char *)rule_extend, ov, 30, 1, &th_track); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - /* retrieve the IP */ - ret = pcre_get_substring((char *)rule_extend, ov, 30, 2, &th_ip); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - } else { - parsed_track = TRACK_RULE; - } - parsed_type = TYPE_SUPPRESS; - break; - case THRESHOLD_TYPE_RATE: - if (strlen(rule_extend) > 0) { - ret = pcre_exec(regex_rate, regex_rate_study, - rule_extend, strlen(rule_extend), - 0, 0, ov, MAX_SUBSTRINGS); - if (ret < 5) { - SCLogError(SC_ERR_PCRE_MATCH, - "pcre_exec parse error, ret %" PRId32 ", string %s", - ret, rule_extend); - goto error; - } - - ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 1, &th_track); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 2, &th_count); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 3, &th_seconds); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 4, &th_new_action); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - ret = pcre_get_substring((char *)rule_extend, ov, MAX_SUBSTRINGS, 5, &th_timeout); - if (ret < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* TODO: implement option "apply_to" */ - - if (ByteExtractStringUint32(&parsed_timeout, 10, strlen(th_timeout), th_timeout) <= 0) { - goto error; - } - - /* Get the new action to take */ - if (strcasecmp(th_new_action, "alert") == 0) - parsed_new_action = TH_ACTION_ALERT; - if (strcasecmp(th_new_action, "drop") == 0) - parsed_new_action = TH_ACTION_DROP; - if (strcasecmp(th_new_action, "pass") == 0) - parsed_new_action = TH_ACTION_PASS; - if (strcasecmp(th_new_action, "reject") == 0) - parsed_new_action = TH_ACTION_REJECT; - if (strcasecmp(th_new_action, "log") == 0) { - SCLogInfo("log action for rate_filter not supported yet"); - parsed_new_action = TH_ACTION_LOG; - } - if (strcasecmp(th_new_action, "sdrop") == 0) { - SCLogInfo("sdrop action for rate_filter not supported yet"); - parsed_new_action = TH_ACTION_SDROP; - } - parsed_type = TYPE_RATE; - } else { - SCLogError(SC_ERR_INVALID_ARGUMENTS, "rule invalid: %s", rawstr); - goto error; - } - break; - default: - SCLogError(SC_ERR_PCRE_MATCH, "unable to find rule type for string %s", rawstr); - goto error; - } - - switch (rule_type) { - /* This part is common to threshold/event_filter/rate_filter */ - case THRESHOLD_TYPE_EVENT_FILTER: - case THRESHOLD_TYPE_THRESHOLD: - case THRESHOLD_TYPE_RATE: - if (strcasecmp(th_track,"by_dst") == 0) - parsed_track = TRACK_DST; - else if (strcasecmp(th_track,"by_src") == 0) - parsed_track = TRACK_SRC; - else if (strcasecmp(th_track,"by_rule") == 0) - parsed_track = TRACK_RULE; - else { - SCLogError(SC_ERR_INVALID_VALUE, "Invalid track parameter %s in %s", th_track, rawstr); - goto error; - } - - if (ByteExtractStringUint32(&parsed_count, 10, strlen(th_count), th_count) <= 0) { - goto error; - } - if (parsed_count == 0) { - SCLogError(SC_ERR_INVALID_VALUE, "rate filter count should be > 0"); - goto error; - } - - if (ByteExtractStringUint32(&parsed_seconds, 10, strlen(th_seconds), th_seconds) <= 0) { - goto error; - } - - break; - case THRESHOLD_TYPE_SUPPRESS: - /* need to get IP if extension is provided */ - if (th_track != NULL) { - if (strcasecmp(th_track,"by_dst") == 0) - parsed_track = TRACK_DST; - else if (strcasecmp(th_track,"by_src") == 0) - parsed_track = TRACK_SRC; - else if (strcasecmp(th_track,"by_either") == 0) { - parsed_track = TRACK_EITHER; - } - else { - SCLogError(SC_ERR_INVALID_VALUE, "Invalid track parameter %s in %s", th_track, rule_extend); - goto error; - } - } - break; - } - - if (ByteExtractStringUint32(&id, 10, strlen(th_sid), th_sid) <= 0) { - goto error; - } - - if (ByteExtractStringUint32(&gid, 10, strlen(th_gid), th_gid) <= 0) { - goto error; - } - - *ret_id = id; - *ret_gid = gid; - *ret_parsed_type = parsed_type; - *ret_parsed_track = parsed_track; - *ret_parsed_new_action = parsed_new_action; - *ret_parsed_count = parsed_count; - *ret_parsed_seconds = parsed_seconds; - *ret_parsed_timeout = parsed_timeout; - *ret_th_ip = th_ip; - return 0; -error: - if (th_track != NULL) - SCFree((char *)th_track); - if (th_count != NULL) - SCFree((char *)th_count); - if (th_seconds != NULL) - SCFree((char *)th_seconds); - if (th_type != NULL) - SCFree((char *)th_type); - if (th_ip != NULL) - SCFree((char *)th_ip); - return -1; -} - -/** - * \brief Parses a line from the threshold file and applies it to the - * detection engine - * - * \param rawstr Pointer to the string to be parsed. - * \param de_ctx Pointer to the Detection Engine Context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCThresholdConfAddThresholdtype(char *rawstr, DetectEngineCtx *de_ctx) -{ - uint8_t parsed_type = 0; - uint8_t parsed_track = 0; - uint8_t parsed_new_action = 0; - uint32_t parsed_count = 0; - uint32_t parsed_seconds = 0; - uint32_t parsed_timeout = 0; - const char *th_ip = NULL; - uint32_t id, gid; - - int r = 0; - r = ParseThresholdRule(de_ctx, rawstr, &id, &gid, &parsed_type, &parsed_track, - &parsed_count, &parsed_seconds, &parsed_timeout, &parsed_new_action, - &th_ip); - if (r < 0) - goto error; - - if (parsed_type == TYPE_SUPPRESS) { - r = SetupSuppressRule(de_ctx, id, gid, parsed_type, parsed_track, - parsed_count, parsed_seconds, parsed_timeout, parsed_new_action, - th_ip); - } else { - r = SetupThresholdRule(de_ctx, id, gid, parsed_type, parsed_track, - parsed_count, parsed_seconds, parsed_timeout, parsed_new_action, - th_ip); - } - if (r < 0) { - goto error; - } - - return 0; -error: - if (th_ip != NULL) - SCFree((char *)th_ip); - return -1; -} - -/** - * \brief Checks if a string is a comment or a blank line. - * - * Comments lines are lines of the following format - - * "# This is a comment string" or - * " # This is a comment string". - * - * \param line String that has to be checked - * - * \retval 1 On the argument string being a comment or blank line - * \retval 0 Otherwise - */ -int SCThresholdConfIsLineBlankOrComment(char *line) -{ - while (*line != '\0') { - /* we have a comment */ - if (*line == '#') - return 1; - - /* this line is neither a comment line, nor a blank line */ - if (!isspace((unsigned char)*line)) - return 0; - - line++; - } - - /* we have a blank line */ - return 1; -} - -/** - * \brief Checks if the rule is multiline, by searching an ending slash - * - * \param line String that has to be checked - * - * \retval the position of the slash making it multiline - * \retval 0 Otherwise - */ -int SCThresholdConfLineIsMultiline(char *line) -{ - int flag = 0; - char *rline = line; - int len = strlen(line); - - while (line < rline + len && *line != '\n') { - /* we have a comment */ - if (*line == '\\') - flag = line - rline; - else - if (!isspace((unsigned char)*line)) - flag = 0; - - line++; - } - - /* we have a blank line */ - return flag; -} - -/** - * \brief Get the config line length to allocate the buffer needed - * - * \param fd Pointer to file descriptor. - * \retval int of the line length - */ -int SCThresholdConfLineLength(FILE *fd) -{ - long pos = ftell(fd); - int len = 0; - int c; - - while ( (c = fgetc(fd)) && (char)c != '\n' && c != EOF && !feof(fd)) - len++; - - if (pos < 0) - pos = 0; - - if (fseek(fd, pos, SEEK_SET) < 0) { - SCLogError(SC_ERR_THRESHOLD_SETUP, "threshold fseek failure: %s", - strerror(errno)); - return -1; - } - return len; -} - -/** - * \brief Parses the Threshold Config file - * - * \param de_ctx Pointer to the Detection Engine Context. - * \param fd Pointer to file descriptor. - */ -void SCThresholdConfParseFile(DetectEngineCtx *de_ctx, FILE *fd) -{ - char *line = NULL; - int len = 0; - int rule_num = 0; - - /* position of "\", on multiline rules */ - int esc_pos = 0; - - if (fd == NULL) - return; - - while (!feof(fd)) { - len = SCThresholdConfLineLength(fd); - - if (len > 0) { - if (line == NULL) { - line = SCMalloc(len + 1); - if (unlikely(line == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - return; - } - } else { - char *newline = SCRealloc(line, strlen(line) + len + 1); - if (unlikely(newline == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - SCFree(line); - return; - } - line = newline; - } - - if (fgets(line + esc_pos, len + 1, fd) == NULL) - break; - - /* Skip EOL to inspect the next line (or read EOF) */ - (void)fgetc(fd); - - if (SCThresholdConfIsLineBlankOrComment(line)) { - continue; - } - - esc_pos = SCThresholdConfLineIsMultiline(line); - if (esc_pos == 0) { - rule_num++; - SCLogDebug("Adding threshold.config rule num %"PRIu32"( %s )", rule_num, line); - SCThresholdConfAddThresholdtype(line, de_ctx); - } - } else { - /* Skip EOL to inspect the next line (or read EOF) */ - (void)fgetc(fd); - if (feof(fd)) - break; - } - } - - SCLogInfo("Threshold config parsed: %d rule(s) found", rule_num); - - /* Free the last line */ - SCFree(line); - - return; -} - -#ifdef UNITTESTS - -/** - * \brief Creates a dummy threshold file, with all valid options, for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD01() -{ - FILE *fd = NULL; - const char *buffer = - "event_filter gen_id 1, sig_id 10, type limit, track by_src, count 1, seconds 60\n" - "threshold gen_id 1, sig_id 100, type both, track by_dst, count 10, seconds 60\n" - "event_filter gen_id 1, sig_id 1000, type threshold, track by_src, count 100, seconds 60\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with some valid options and a couple of invalid options. - * For testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateInValidDummyFD02() -{ - FILE *fd; - const char *buffer = - "event_filter gen_id 1, sig_id 1000, type invalid, track by_src, count 100, seconds 60\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD03() -{ - FILE *fd; - const char *buffer = - "event_filter gen_id 0, sig_id 0, type threshold, track by_src, count 100, seconds 60\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, but - * with splitted rules (multiline), for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD04() -{ - FILE *fd = NULL; - const char *buffer = - "event_filter gen_id 1 \\\n, sig_id 10, type limit, track by_src, \\\ncount 1, seconds 60\n" - "threshold gen_id 1, \\\nsig_id 100, type both\\\n, track by_dst, count 10, \\\n seconds 60\n" - "event_filter gen_id 1, sig_id 1000, \\\ntype threshold, track \\\nby_src, count 100, seconds 60\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD05() -{ - FILE *fd = NULL; - const char *buffer = - "rate_filter gen_id 1, sig_id 10, track by_src, count 1, seconds 60, new_action drop, timeout 10\n" - "rate_filter gen_id 1, sig_id 100, track by_dst, count 10, seconds 60, new_action pass, timeout 5\n" - "rate_filter gen_id 1, sig_id 1000, track by_rule, count 100, seconds 60, new_action alert, timeout 30\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, but - * with splitted rules (multiline), for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD06() -{ - FILE *fd = NULL; - const char *buffer = - "rate_filter \\\ngen_id 1, sig_id 10, track by_src, count 1, seconds 60\\\n, new_action drop, timeout 10\n" - "rate_filter gen_id 1, \\\nsig_id 100, track by_dst, \\\ncount 10, seconds 60, new_action pass, timeout 5\n" - "rate_filter gen_id 1, sig_id 1000, \\\ntrack by_rule, count 100, seconds 60, new_action alert, timeout 30\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, but - * with splitted rules (multiline), for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD07() -{ - FILE *fd = NULL; - const char *buffer = - "rate_filter gen_id 1, sig_id 10, track by_src, count 3, seconds 3, new_action drop, timeout 10\n" - "rate_filter gen_id 1, sig_id 11, track by_src, count 3, seconds 1, new_action drop, timeout 5\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, but - * with splitted rules (multiline), for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD08() -{ - FILE *fd = NULL; - const char *buffer = - "rate_filter gen_id 1, sig_id 10, track by_rule, count 3, seconds 3, new_action drop, timeout 10\n" - "rate_filter gen_id 1, sig_id 11, track by_src, count 3, seconds 1, new_action drop, timeout 5\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, but - * with splitted rules (multiline), for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD09() -{ - FILE *fd = NULL; - const char *buffer = - "event_filter gen_id 1 \\\n, sig_id 10, type limit, track by_src, \\\ncount 2, seconds 60\n" - "threshold gen_id 1, \\\nsig_id 11, type threshold\\\n, track by_dst, count 3, \\\n seconds 60\n" - "event_filter gen_id 1, sig_id 12, \\\ntype both, track \\\nby_src, count 2, seconds 60\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, but - * with splitted rules (multiline), for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD10() -{ - FILE *fd = NULL; - const char *buffer = - "event_filter gen_id 1 \\\n, sig_id 10, type limit, track by_src, \\\ncount 5, seconds 2\n" - "threshold gen_id 1, \\\nsig_id 11, type threshold\\\n, track by_dst, count 5, \\\n seconds 2\n" - "event_filter gen_id 1, sig_id 12, \\\ntype both, track \\\nby_src, count 5, seconds 2\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD11() -{ - FILE *fd = NULL; - const char *buffer = - "suppress gen_id 1, sig_id 10000\n" - "suppress gen_id 1, sig_id 1000, track by_src, ip 192.168.1.1\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \test Check if the threshold file is loaded and well parsed - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest01(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:10;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD01(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]); - - if(m != NULL) { - de = (DetectThresholdData *)m->ctx; - if(de != NULL && (de->type == TYPE_LIMIT && de->track == TRACK_SRC && de->count == 1 && de->seconds == 60)) - result = 1; - } - -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the threshold file is loaded and well parsed - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest02(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:100;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD01(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]); - - if(m != NULL) { - de = (DetectThresholdData *)m->ctx; - if(de != NULL && (de->type == TYPE_BOTH && de->track == TRACK_DST && de->count == 10 && de->seconds == 60)) - result = 1; - } -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the threshold file is loaded and well parsed - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest03(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:1000;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD01(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]); - - if(m != NULL) { - de = (DetectThresholdData *)m->ctx; - if(de != NULL && (de->type == TYPE_THRESHOLD && de->track == TRACK_SRC && de->count == 100 && de->seconds == 60)) - result = 1; - } -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the threshold file is loaded and well parsed - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest04(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:1000;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateInValidDummyFD02(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]); - - if(m != NULL) { - de = (DetectThresholdData *)m->ctx; - if(de == NULL) - return result; - else - result = 1; - } -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - return result; -} - -/** - * \test Check if the threshold file is loaded and well parsed - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest05(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - Signature *s = NULL, *ns = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:1;)"); - if (sig == NULL) { - goto end; - } - - sig = sig->next = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; gid:1; sid:10;)"); - if (sig == NULL) { - goto end; - } - - sig = sig->next = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; gid:1; sid:100;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD03(); - SCThresholdConfInitContext(de_ctx,fd); - - for (s = de_ctx->sig_list; s != NULL;) { - - ns = s->next; - - if(s->id == 1 || s->id == 10 || s->id == 100) { - - m = SigMatchGetLastSMFromLists(s, 2, - DETECT_THRESHOLD, s->sm_lists[DETECT_SM_LIST_THRESHOLD]); - - if(m == NULL) { - goto end; - } else { - de = (DetectThresholdData *)m->ctx; - if(de != NULL && (de->type == TYPE_THRESHOLD && de->track == TRACK_SRC && de->count == 100 && de->seconds == 60)) - result++; - } - } - - s = ns; - } - - if(result == 3) - result = 1; - -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the threshold file is loaded and well parsed - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest06(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:10;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD04(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]); - - if(m != NULL) { - de = (DetectThresholdData *)m->ctx; - if(de != NULL && (de->type == TYPE_LIMIT && de->track == TRACK_SRC && de->count == 1 && de->seconds == 60)) - result = 1; - } - -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the rate_filter rules are loaded and well parsed - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest07(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:10;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD05(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_DETECTION_FILTER, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]); - - if(m != NULL) { - de = (DetectThresholdData *)m->ctx; - if(de != NULL && (de->type == TYPE_RATE && de->track == TRACK_SRC && de->count == 1 && de->seconds == 60)) - result = 1; - } - -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the rate_filter rules are loaded and well parsed - * with multilines - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest08(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:10;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD06(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_DETECTION_FILTER, sig->sm_lists[DETECT_SM_LIST_THRESHOLD]); - - if(m != NULL) { - de = (DetectThresholdData *)m->ctx; - if(de != NULL && (de->type == TYPE_RATE && de->track == TRACK_SRC && de->count == 1 && de->seconds == 60)) - result = 1; - } - -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if the rate_filter rules work - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest09(void) -{ - Signature *sig = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(th_v)); - - struct timeval ts; - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL || p == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"ratefilter test\"; gid:1; sid:10;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD07(); - SCThresholdConfInitContext(de_ctx,fd); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - result = 0; - goto end; - } - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - result = 0; - goto end; - } - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - result = 0; - goto end; - } - - TimeSetIncrementTime(2); - TimeGet(&p->ts); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || !(PACKET_TEST_ACTION(p, ACTION_DROP))) { - result = 0; - goto end; - } - - TimeSetIncrementTime(3); - TimeGet(&p->ts); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || !(PACKET_TEST_ACTION(p, ACTION_DROP))) { - result = 0; - goto end; - } - - TimeSetIncrementTime(10); - TimeGet(&p->ts); - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - result = 0; - goto end; - } - - p->alerts.cnt = 0; - p->action = 0; - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (p->alerts.cnt != 1 || PACKET_TEST_ACTION(p, ACTION_DROP)) { - result = 0; - goto end; - } - - result = 1; - -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -/** - * \test Check if the rate_filter rules work with track by_rule - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest10(void) -{ - Signature *sig = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP); - Packet *p2 = UTHBuildPacketSrcDst((uint8_t*)"lalala", 6, IPPROTO_TCP, "172.26.0.1", "172.26.0.10"); - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int alerts = 0; - - memset(&th_v, 0, sizeof(th_v)); - - struct timeval ts; - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL || p == NULL || p2 == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"ratefilter test\"; gid:1; sid:10;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD08(); - SCThresholdConfInitContext(de_ctx,fd); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts = PacketAlertCheck(p, 10); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - alerts += PacketAlertCheck(p2, 10); - if (alerts > 0) { - result = 0; - goto end; - } - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - if (alerts != 1) { - result = 0; - goto end; - } - - TimeSetIncrementTime(2); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - alerts += PacketAlertCheck(p2, 10); - if (alerts != 2) { - result = 0; - goto end; - } - - TimeSetIncrementTime(10); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts += PacketAlertCheck(p, 10); - - if (alerts == 2) - result = 1; - - /* Ensure that a Threshold entry was installed at the sig */ - if (de_ctx->ths_ctx.th_entry[sig->num] == NULL) { - result = 0; - goto end; - } - -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -/** - * \test Check if the rate_filter rules work - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest11(void) -{ - Signature *sig = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int alerts10 = 0; - int alerts11 = 0; - int alerts12 = 0; - - memset(&th_v, 0, sizeof(th_v)); - - struct timeval ts; - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL || p == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"event_filter test limit\"; gid:1; sid:10;)"); - sig = sig->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"event_filter test threshold\"; gid:1; sid:11;)"); - sig = sig->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"event_filter test both\"; gid:1; sid:12;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD09(); - SCThresholdConfInitContext(de_ctx,fd); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - - TimeSetIncrementTime(100); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - - TimeSetIncrementTime(10); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - - if (alerts10 == 4) - result = 1; - - /* One on the first interval, another on the second */ - if (alerts11 == 2) - result = 1; - - if (alerts12 == 2) - result = 1; - -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -/** - * \test Check if the rate_filter rules work - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest12(void) -{ - Signature *sig = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - int alerts10 = 0; - int alerts11 = 0; - int alerts12 = 0; - - memset(&th_v, 0, sizeof(th_v)); - - struct timeval ts; - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL || p == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"event_filter test limit\"; gid:1; sid:10;)"); - sig = sig->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"event_filter test threshold\"; gid:1; sid:11;)"); - sig = sig->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"event_filter test both\"; gid:1; sid:12;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD10(); - SCThresholdConfInitContext(de_ctx,fd); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - - TimeSetIncrementTime(100); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - - TimeSetIncrementTime(10); - TimeGet(&p->ts); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - alerts10 += PacketAlertCheck(p, 10); - alerts11 += PacketAlertCheck(p, 11); - alerts12 += PacketAlertCheck(p, 12); - - /* Yes, none of the alerts will be out of the count of the given interval for type limit */ - if (alerts10 == 10) - result = 1; - - /* One on the first interval, another on the second */ - if (alerts11 == 1) - result = 1; - - if (alerts12 == 1) - result = 1; - -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -/** - * \test Check if the threshold file is loaded and well parsed - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest13(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; gid:1; sid:1000;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD11(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_SUPPRESS]); - - if (m != NULL) { - de = (DetectThresholdData *)m->ctx; - if(de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) - result = 1; - - } -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - HostShutdown(); - return result; -} - -/** - * \test Check if the suppress rules work - * - * \retval 1 on succces - * \retval 0 on failure - */ -int SCThresholdConfTest14(void) -{ - Signature *sig = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10", - "192.168.0.100", 1234, 24); - Packet *p1 = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.1.1", - "192.168.0.100", 1234, 24); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(th_v)); - - struct timeval ts; - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL || p == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"suppress test\"; gid:1; sid:10000;)"); - sig = sig->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"suppress test 2\"; gid:1; sid:10;)"); - sig = sig->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"suppress test 3\"; gid:1; sid:1000;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD11(); - SCThresholdConfInitContext(de_ctx,fd); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - if ((PacketAlertCheck(p, 10000) == 0) && (PacketAlertCheck(p, 10) == 1) && - (PacketAlertCheck(p, 1000) == 1) && (PacketAlertCheck(p1, 1000) == 0)) - result = 1; - -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -/** - * \test Check if the suppress rules work - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int SCThresholdConfTest15(void) -{ - Signature *sig = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10", - "192.168.0.100", 1234, 24); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(th_v)); - - struct timeval ts; - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL || p == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any any (msg:\"suppress test\"; content:\"lalala\"; gid:1; sid:10000;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD11(); - SCThresholdConfInitContext(de_ctx,fd); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* 10000 shouldn't match */ - if (PacketAlertCheck(p, 10000) != 0) { - printf("sid 10000 should not have alerted: "); - goto end; - } - /* however, it should have set the drop flag */ - if (!(PACKET_TEST_ACTION(p, ACTION_DROP))) { - printf("sid 10000 should have set DROP flag even if suppressed: "); - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -/** - * \test Check if the suppress rules work - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int SCThresholdConfTest16(void) -{ - Signature *sig = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.1.1", - "192.168.0.100", 1234, 24); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(th_v)); - - struct timeval ts; - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL || p == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any any (msg:\"suppress test\"; gid:1; sid:1000;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD11(); - SCThresholdConfInitContext(de_ctx,fd); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* 10000 shouldn't match */ - if (PacketAlertCheck(p, 1000) != 0) { - printf("sid 1000 should not have alerted: "); - goto end; - } - /* however, it should have set the drop flag */ - if (!(PACKET_TEST_ACTION(p, ACTION_DROP))) { - printf("sid 1000 should have set DROP flag even if suppressed: "); - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -/** - * \test Check if the suppress rules work - ip only rule - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int SCThresholdConfTest17(void) -{ - Signature *sig = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10", - "192.168.0.100", 1234, 24); - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&th_v, 0, sizeof(th_v)); - - struct timeval ts; - - memset (&ts, 0, sizeof(struct timeval)); - TimeGet(&ts); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL || p == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"drop tcp 192.168.0.10 any -> 192.168.0.100 any (msg:\"suppress test\"; gid:1; sid:10000;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD11(); - SCThresholdConfInitContext(de_ctx,fd); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - /* 10000 shouldn't match */ - if (PacketAlertCheck(p, 10000) != 0) { - printf("sid 10000 should not have alerted: "); - goto end; - } - /* however, it should have set the drop flag */ - if (!(PACKET_TEST_ACTION(p, ACTION_DROP))) { - printf("sid 10000 should have set DROP flag even if suppressed: "); - goto end; - } - - result = 1; -end: - UTHFreePacket(p); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - - HostShutdown(); - return result; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -static FILE *SCThresholdConfGenerateInvalidDummyFD12() -{ - FILE *fd = NULL; - const char *buffer = - "suppress gen_id 1, sig_id 2200029, track by_dst, ip fe80::/16\n" - "suppress gen_id 1, sig_id 2200029, track by_stc, ip fe80::/16\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \test Check if the suppress rule parsing handles errors correctly - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int SCThresholdConfTest18(void) -{ - Signature *s = NULL; - int result = 0; - FILE *fd = NULL; - SigMatch *sm = NULL; - DetectThresholdData *de = NULL; - - HostInitConfig(HOST_QUIET); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return result; - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.0.10 any -> 192.168.0.100 any (msg:\"suppress test\"; gid:1; sid:2200029;)"); - if (s == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateInvalidDummyFD12(); - SCThresholdConfInitContext(de_ctx,fd); - SigGroupBuild(de_ctx); - - if (s->sm_lists[DETECT_SM_LIST_SUPPRESS] == NULL) { - printf("no thresholds: "); - goto end; - } - sm = s->sm_lists[DETECT_SM_LIST_SUPPRESS]; - if (sm == NULL) { - printf("no sm: "); - goto end; - } - - de = (DetectThresholdData *)sm->ctx; - if (de == NULL) { - printf("no de: "); - goto end; - } - if (!(de->type == TYPE_SUPPRESS && de->track == TRACK_DST)) { - printf("de state wrong: "); - goto end; - } - - result = 1; -end: - DetectEngineCtxFree(de_ctx); - HostShutdown(); - return result; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -static FILE *SCThresholdConfGenerateInvalidDummyFD13() -{ - FILE *fd = NULL; - const char *buffer = - "suppress gen_id 1, sig_id 2200029, track by_stc, ip fe80::/16\n" - "suppress gen_id 1, sig_id 2200029, track by_dst, ip fe80::/16\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \test Check if the suppress rule parsing handles errors correctly - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int SCThresholdConfTest19(void) -{ - Signature *s = NULL; - int result = 0; - FILE *fd = NULL; - SigMatch *sm = NULL; - DetectThresholdData *de = NULL; - - HostInitConfig(HOST_QUIET); - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - return result; - de_ctx->flags |= DE_QUIET; - - s = DetectEngineAppendSig(de_ctx, "alert tcp 192.168.0.10 any -> 192.168.0.100 any (msg:\"suppress test\"; gid:1; sid:2200029;)"); - if (s == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateInvalidDummyFD13(); - SCThresholdConfInitContext(de_ctx,fd); - SigGroupBuild(de_ctx); - - if (s->sm_lists[DETECT_SM_LIST_SUPPRESS] == NULL) { - printf("no thresholds: "); - goto end; - } - sm = s->sm_lists[DETECT_SM_LIST_SUPPRESS]; - if (sm == NULL) { - printf("no sm: "); - goto end; - } - - de = (DetectThresholdData *)sm->ctx; - if (de == NULL) { - printf("no de: "); - goto end; - } - if (!(de->type == TYPE_SUPPRESS && de->track == TRACK_DST)) { - printf("de state wrong: "); - goto end; - } - - result = 1; -end: - DetectEngineCtxFree(de_ctx); - HostShutdown(); - return result; -} - -/** - * \brief Creates a dummy threshold file, with all valid options, for testing purposes. - * - * \retval fd Pointer to file descriptor. - */ -FILE *SCThresholdConfGenerateValidDummyFD20() -{ - FILE *fd = NULL; - const char *buffer = - "suppress gen_id 1, sig_id 1000, track by_src, ip 2.2.3.4\n" - "suppress gen_id 1, sig_id 1000, track by_src, ip 1.2.3.4\n" - "suppress gen_id 1, sig_id 1000, track by_src, ip 192.168.1.1\n"; - - fd = SCFmemopen((void *)buffer, strlen(buffer), "r"); - if (fd == NULL) - SCLogDebug("Error with SCFmemopen() called by Threshold Config test code"); - - return fd; -} - -/** - * \test Check if the threshold file is loaded and well parsed - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int SCThresholdConfTest20(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; content:\"abc\"; sid:1000;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD20(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_SUPPRESS]); - if (m != NULL) { - de = (DetectThresholdData *)m->ctx; - if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) { - m = m->next; - if (m != NULL) { - de = (DetectThresholdData *)m->ctx; - if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) { - m = m->next; - if (m != NULL) { - de = (DetectThresholdData *)m->ctx; - if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) { - result = 1; - } - } - } - } - } - } -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - HostShutdown(); - return result; -} - -/** - * \test Check if the threshold file is loaded and well parsed, and applied - * correctly to a rule with thresholding - * - * \retval 1 on succces - * \retval 0 on failure - */ -static int SCThresholdConfTest21(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - DetectThresholdData *de = NULL; - Signature *sig = NULL; - SigMatch *m = NULL; - int result = 0; - FILE *fd = NULL; - - HostInitConfig(HOST_QUIET); - - if (de_ctx == NULL) - return result; - - de_ctx->flags |= DE_QUIET; - - sig = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Threshold limit\"; content:\"abc\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)"); - if (sig == NULL) { - goto end; - } - - fd = SCThresholdConfGenerateValidDummyFD20(); - SCThresholdConfInitContext(de_ctx,fd); - - m = SigMatchGetLastSMFromLists(sig, 2, - DETECT_THRESHOLD, sig->sm_lists[DETECT_SM_LIST_SUPPRESS]); - if (m != NULL) { - de = (DetectThresholdData *)m->ctx; - if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) { - m = m->next; - if (m != NULL) { - de = (DetectThresholdData *)m->ctx; - if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) { - m = m->next; - if (m != NULL) { - de = (DetectThresholdData *)m->ctx; - if (de != NULL && (de->type == TYPE_SUPPRESS && de->track == TRACK_SRC)) { - result = 1; - } - } - } - } - } - } -end: - SigGroupBuild(de_ctx); - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - HostShutdown(); - return result; -} - -#endif /* UNITTESTS */ - -/** - * \brief This function registers unit tests for Classification Config API. - */ -void SCThresholdConfRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SCThresholdConfTest01", SCThresholdConfTest01, 1); - UtRegisterTest("SCThresholdConfTest02", SCThresholdConfTest02, 1); - UtRegisterTest("SCThresholdConfTest03", SCThresholdConfTest03, 1); - UtRegisterTest("SCThresholdConfTest04", SCThresholdConfTest04, 0); - UtRegisterTest("SCThresholdConfTest05", SCThresholdConfTest05, 1); - UtRegisterTest("SCThresholdConfTest06", SCThresholdConfTest06, 1); - UtRegisterTest("SCThresholdConfTest07", SCThresholdConfTest07, 1); - UtRegisterTest("SCThresholdConfTest08", SCThresholdConfTest08, 1); - UtRegisterTest("SCThresholdConfTest09 - rate_filter", SCThresholdConfTest09, 1); - UtRegisterTest("SCThresholdConfTest10 - rate_filter", SCThresholdConfTest10, 1); - UtRegisterTest("SCThresholdConfTest11 - event_filter", SCThresholdConfTest11, 1); - UtRegisterTest("SCThresholdConfTest12 - event_filter", SCThresholdConfTest12, 1); - UtRegisterTest("SCThresholdConfTest13", SCThresholdConfTest13, 1); - UtRegisterTest("SCThresholdConfTest14 - suppress", SCThresholdConfTest14, 1); - UtRegisterTest("SCThresholdConfTest15 - suppress drop", SCThresholdConfTest15, 1); - UtRegisterTest("SCThresholdConfTest16 - suppress drop", SCThresholdConfTest16, 1); - UtRegisterTest("SCThresholdConfTest17 - suppress drop", SCThresholdConfTest17, 1); - - UtRegisterTest("SCThresholdConfTest18 - suppress parsing", SCThresholdConfTest18, 1); - UtRegisterTest("SCThresholdConfTest19 - suppress parsing", SCThresholdConfTest19, 1); - UtRegisterTest("SCThresholdConfTest20 - suppress parsing", SCThresholdConfTest20, 1); - UtRegisterTest("SCThresholdConfTest21 - suppress parsing", SCThresholdConfTest21, 1); -#endif /* UNITTESTS */ -} - -/** - * @} - */ diff --git a/framework/src/suricata/src/util-threshold-config.h b/framework/src/suricata/src/util-threshold-config.h deleted file mode 100644 index 906ed7c6..00000000 --- a/framework/src/suricata/src/util-threshold-config.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Breno Silva Pinto - */ - -#ifndef __UTIL_THRESHOLD_CONFIG_H__ -#define __UTIL_THRESHOLD_CONFIG_H__ - -void SCThresholdConfDeInitContext(DetectEngineCtx *, FILE *); -void SCThresholdConfParseFile(DetectEngineCtx *, FILE *); -int SCThresholdConfInitContext(DetectEngineCtx *, FILE *); - -void SCThresholdConfRegisterTests(); - -#endif /* __UTIL_THRESHOLD_CONFIG_H__ */ diff --git a/framework/src/suricata/src/util-time.c b/framework/src/suricata/src/util-time.c deleted file mode 100644 index 7c7a3624..00000000 --- a/framework/src/suricata/src/util-time.c +++ /dev/null @@ -1,304 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Ken Steele - * - * Time keeping for offline (non-live) packet handling (pcap files). - * And time string generation for alerts. - */ - -#include "suricata-common.h" -#include "detect.h" -#include "threads.h" -#include "util-debug.h" - -static struct timeval current_time = { 0, 0 }; -//static SCMutex current_time_mutex = SCMUTEX_INITIALIZER; -static SCSpinlock current_time_spinlock; -static char live = TRUE; - - -struct tm *SCLocalTime(time_t timep, struct tm *result); - -void TimeInit(void) -{ - SCSpinInit(¤t_time_spinlock, 0); - - /* Initialize Time Zone settings. */ - tzset(); -} - -void TimeDeinit(void) -{ - SCSpinDestroy(¤t_time_spinlock); -} - -void TimeModeSetLive(void) -{ - live = TRUE; - SCLogDebug("live time mode enabled"); -} - -void TimeModeSetOffline (void) -{ - live = FALSE; - SCLogDebug("offline time mode enabled"); -} - -void TimeSet(struct timeval *tv) -{ - if (live == TRUE) - return; - - if (tv == NULL) - return; - - SCSpinLock(¤t_time_spinlock); - current_time.tv_sec = tv->tv_sec; - current_time.tv_usec = tv->tv_usec; - - SCLogDebug("time set to %" PRIuMAX " sec, %" PRIuMAX " usec", - (uintmax_t)current_time.tv_sec, (uintmax_t)current_time.tv_usec); - - SCSpinUnlock(¤t_time_spinlock); -} - -/** \brief set the time to "gettimeofday" meant for testing */ -void TimeSetToCurrentTime(void) -{ - struct timeval tv; - memset(&tv, 0x00, sizeof(tv)); - - gettimeofday(&tv, NULL); - - TimeSet(&tv); -} - -void TimeGet(struct timeval *tv) -{ - if (tv == NULL) - return; - - if (live == TRUE) { - gettimeofday(tv, NULL); - } else { - SCSpinLock(¤t_time_spinlock); - tv->tv_sec = current_time.tv_sec; - tv->tv_usec = current_time.tv_usec; - SCSpinUnlock(¤t_time_spinlock); - } - - SCLogDebug("time we got is %" PRIuMAX " sec, %" PRIuMAX " usec", - (uintmax_t)tv->tv_sec, (uintmax_t)tv->tv_usec); -} - -/** \brief increment the time in the engine - * \param tv_sec seconds to increment the time with */ -void TimeSetIncrementTime(uint32_t tv_sec) -{ - struct timeval tv; - memset(&tv, 0x00, sizeof(tv)); - TimeGet(&tv); - - tv.tv_sec += tv_sec; - - TimeSet(&tv); -} - -void CreateIsoTimeString (const struct timeval *ts, char *str, size_t size) -{ - time_t time = ts->tv_sec; - struct tm local_tm; - struct tm *t = (struct tm*)SCLocalTime(time, &local_tm); - char time_fmt[64] = { 0 }; - - if (likely(t != NULL)) { - strftime(time_fmt, sizeof(time_fmt), "%Y-%m-%dT%H:%M:%S.%%06u%z", t); - snprintf(str, size, time_fmt, ts->tv_usec); - } else { - snprintf(str, size, "ts-error"); - } -} - -/* - * Time Caching code - */ - -#ifndef TLS -/* OpenBSD does not support __thread, so don't use time caching on BSD - */ -struct tm *SCLocalTime(time_t timep, struct tm *result) -{ - return localtime_r(&timep, result); -} - -void CreateTimeString (const struct timeval *ts, char *str, size_t size) -{ - time_t time = ts->tv_sec; - struct tm local_tm; - struct tm *t = (struct tm*)SCLocalTime(time, &local_tm); - - if (likely(t != NULL)) { - snprintf(str, size, "%02d/%02d/%02d-%02d:%02d:%02d.%06u", - t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_hour, - t->tm_min, t->tm_sec, (uint32_t) ts->tv_usec); - } else { - snprintf(str, size, "ts-error"); - } -} - -#else - -/* On systems supporting __thread, use Per-thread values for caching - * in CreateTimeString */ - -/* The maximum possible length of the time string. - * "%02d/%02d/%02d-%02d:%02d:%02d.%06u" - * Or "01/01/2013-15:42:21.123456", which is 26, so round up to 32. */ -#define MAX_LOCAL_TIME_STRING 32 - -static __thread int mru_time_slot; /* Most recently used cached value */ -static __thread time_t last_local_time[2]; -static __thread short int cached_local_time_len[2]; -static __thread char cached_local_time[2][MAX_LOCAL_TIME_STRING]; - -/* Per-thread values for caching SCLocalTime() These cached values are - * independent from the CreateTimeString cached values. */ -static __thread int mru_tm_slot; /* Most recently used local tm */ -static __thread time_t cached_minute_start[2]; -static __thread struct tm cached_local_tm[2]; - -/** \brief Convert time_t into Year, month, day, hour and minutes. - * \param timep Time in seconds since defined date. - * \param result The structure into which the broken down time it put. - * - * To convert a time in seconds into year, month, day, hours, minutes - * and seconds, call localtime_r(), which uses the current time zone - * to compute these values. Note, glibc's localtime_r() aquires a lock - * each time it is called, which limits parallelism. To call - * localtime_r() less often, the values returned are cached for the - * current and previous minute and then seconds are adjusted to - * compute the returned result. This is valid as long as the - * difference between the start of the current minute and the current - * time is less than 60 seconds. Once the minute value changes, all - * the other values could change. - * - * Two values are cached to prevent thrashing when changing from one - * minute to the next. The two cached minutes are independent and are - * not required to be M and M+1. If more than two minutes are - * requested, the least-recently-used cached value is updated more - * often, the results are still correct, but performance will be closer - * to previous performance. - */ -struct tm *SCLocalTime(time_t timep, struct tm *result) -{ - /* Only get a new local time when the time crosses into a new - * minute. */ - int mru = mru_tm_slot; - int lru = 1 - mru; - int mru_seconds = timep - cached_minute_start[mru]; - int lru_seconds = timep - cached_minute_start[lru]; - int new_seconds; - if (mru_seconds >= 0 && mru_seconds <= 59) { - /* Use most-recently cached time, adjusting the seconds. */ - new_seconds = mru_seconds; - } else if (lru_seconds >= 0 && lru_seconds <= 59) { - /* Use least-recently cached time, update to most recently used. */ - new_seconds = lru_seconds; - mru = lru; - mru_tm_slot = mru; - } else { - /* Update least-recent cached time. */ - if (localtime_r(&timep, &cached_local_tm[lru]) == NULL) - return NULL; - - /* Subtract seconds to get back to the start of the minute. */ - new_seconds = cached_local_tm[lru].tm_sec; - cached_minute_start[lru] = timep - new_seconds; - mru = lru; - mru_tm_slot = mru; - } - memcpy(result, &cached_local_tm[mru], sizeof(struct tm)); - result->tm_sec = new_seconds; - - return result; -} - -/* Update the cached time string in cache index N, for the current minute. */ -static int UpdateCachedTime(int n, time_t time) -{ - struct tm local_tm; - struct tm *t = (struct tm *)SCLocalTime(time, &local_tm); - int cached_len = snprintf(cached_local_time[n], MAX_LOCAL_TIME_STRING, - "%02d/%02d/%02d-%02d:%02d:", - t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, - t->tm_hour, t->tm_min); - cached_local_time_len[n] = cached_len; - /* Store the time of the beginning of the minute. */ - last_local_time[n] = time - t->tm_sec; - mru_time_slot = n; - - return t->tm_sec; -} - -/** \brief Return a formatted string for the provided time. - * - * Cache the Month/Day/Year - Hours:Min part of the time string for - * the current minute. Copy that result into the the return string and - * then only print the seconds for each call. - */ -void CreateTimeString (const struct timeval *ts, char *str, size_t size) -{ - time_t time = ts->tv_sec; - int seconds; - - /* Only get a new local time when the time crosses into a new - * minute */ - int mru = mru_time_slot; - int lru = 1 - mru; - int mru_seconds = time - last_local_time[mru]; - int lru_seconds = time - last_local_time[lru]; - if (mru_seconds >= 0 && mru_seconds <= 59) { - /* Use most-recently cached time. */ - seconds = mru_seconds; - } else if (lru_seconds >= 0 && lru_seconds <= 59) { - /* Use least-recently cached time. Change this slot to Most-recent */ - seconds = lru_seconds; - mru_time_slot = lru; - } else { - /* Update least-recent cached time. Lock accessing local time - * function because it keeps any internal non-spin lock. */ - seconds = UpdateCachedTime(lru, time); - } - - /* Copy the string up to the current minute then print the seconds - into the return string buffer. */ - char *cached_str = cached_local_time[mru_time_slot]; - int cached_len = cached_local_time_len[mru_time_slot]; - if (cached_len >= (int)size) - cached_len = size; - memcpy(str, cached_str, cached_len); - snprintf(str + cached_len, size - cached_len, - "%02d.%06u", - seconds, (uint32_t) ts->tv_usec); -} - -#endif /* defined(__OpenBSD__) */ diff --git a/framework/src/suricata/src/util-time.h b/framework/src/suricata/src/util-time.h deleted file mode 100644 index cdf1d5bf..00000000 --- a/framework/src/suricata/src/util-time.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_TIME_H__ -#define __UTIL_TIME_H__ - -/** - * A timeval with 32 bit fields. - * - * Used by the unified on disk file format. - */ -typedef struct SCTimeval32_ { - uint32_t tv_sec; - uint32_t tv_usec; -} SCTimeval32; - -void TimeInit(void); -void TimeDeinit(void); - -void TimeSet(struct timeval *); -void TimeGet(struct timeval *); - -void TimeSetToCurrentTime(void); -void TimeSetIncrementTime(uint32_t); - -void TimeModeSetLive(void); -void TimeModeSetOffline (void); - -struct tm *SCLocalTime(time_t timep, struct tm *result); -void CreateTimeString (const struct timeval *ts, char *str, size_t size); -void CreateIsoTimeString (const struct timeval *ts, char *str, size_t size); - -#endif /* __UTIL_TIME_H__ */ - diff --git a/framework/src/suricata/src/util-unittest-helper.c b/framework/src/suricata/src/util-unittest-helper.c deleted file mode 100644 index a318205d..00000000 --- a/framework/src/suricata/src/util-unittest-helper.c +++ /dev/null @@ -1,1081 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - * - * This file provide a set of helper functions for reducing the complexity - * when constructing unittests - */ - -#include "suricata-common.h" - -#include "decode.h" - -#include "flow-private.h" -#include "flow-util.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-sigorder.h" - -#include "util-debug.h" -#include "util-time.h" -#include "util-error.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" - -#ifdef UNITTESTS - -/** - * \brief return the uint32_t for a ipv4 address string - * - * \param str Valid ipaddress in string form (e.g. 1.2.3.4) - * - * \retval uint the uin32_t representation - */ -uint32_t UTHSetIPv4Address(char *str) -{ - struct in_addr in; - if (inet_pton(AF_INET, str, &in) != 1) { - printf("invalid IPv6 address %s\n", str); - exit(EXIT_FAILURE); - } - return (uint32_t)in.s_addr; -} - -/** - * \brief UTHBuildPacketReal is a function that create tcp/udp packets for unittests - * specifying ip and port sources and destinations (IPV6) - * - * \param payload pointer to the payloadd buffer - * \param payload_len pointer to the length of the payload - * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP - * \param src pointer to a string containing the ip source - * \param dst pointer to a string containing the ip destination - * \param sport pointer to a string containing the port source - * \param dport pointer to a string containing the port destination - * - * \retval Packet pointer to the built in packet - */ -Packet *UTHBuildPacketIPV6Real(uint8_t *payload, uint16_t payload_len, - uint8_t ipproto, char *src, char *dst, - uint16_t sport, uint16_t dport) -{ - uint32_t in[4]; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return NULL; - - TimeSet(&p->ts); - - p->src.family = AF_INET6; - p->dst.family = AF_INET6; - p->payload = payload; - p->payload_len = payload_len; - p->proto = ipproto; - - p->ip6h = SCMalloc(sizeof(IPV6Hdr)); - if (p->ip6h == NULL) - goto error; - memset(p->ip6h, 0, sizeof(IPV6Hdr)); - p->ip6h->s_ip6_nxt = ipproto; - p->ip6h->s_ip6_plen = htons(payload_len + sizeof(TCPHdr)); - - if (inet_pton(AF_INET6, src, &in) != 1) - goto error; - p->src.addr_data32[0] = in[0]; - p->src.addr_data32[1] = in[1]; - p->src.addr_data32[2] = in[2]; - p->src.addr_data32[3] = in[3]; - p->sp = sport; - p->ip6h->s_ip6_src[0] = in[0]; - p->ip6h->s_ip6_src[1] = in[1]; - p->ip6h->s_ip6_src[2] = in[2]; - p->ip6h->s_ip6_src[3] = in[3]; - - if (inet_pton(AF_INET6, dst, &in) != 1) - goto error; - p->dst.addr_data32[0] = in[0]; - p->dst.addr_data32[1] = in[1]; - p->dst.addr_data32[2] = in[2]; - p->dst.addr_data32[3] = in[3]; - p->dp = dport; - p->ip6h->s_ip6_dst[0] = in[0]; - p->ip6h->s_ip6_dst[1] = in[1]; - p->ip6h->s_ip6_dst[2] = in[2]; - p->ip6h->s_ip6_dst[3] = in[3]; - - p->tcph = SCMalloc(sizeof(TCPHdr)); - if (p->tcph == NULL) - goto error; - memset(p->tcph, 0, sizeof(TCPHdr)); - p->tcph->th_sport = htons(sport); - p->tcph->th_dport = htons(dport); - - SET_PKT_LEN(p, sizeof(IPV6Hdr) + sizeof(TCPHdr) + payload_len); - return p; - -error: - if (p != NULL) { - if (p->ip6h != NULL) { - SCFree(p->ip6h); - } - if (p->tcph != NULL) { - SCFree(p->tcph); - } - SCFree(p); - } - return NULL; -} - -/** - * \brief UTHBuildPacketReal is a function that create tcp/udp packets for unittests - * specifying ip and port sources and destinations - * - * \param payload pointer to the payloadd buffer - * \param payload_len pointer to the length of the payload - * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP - * \param src pointer to a string containing the ip source - * \param dst pointer to a string containing the ip destination - * \param sport pointer to a string containing the port source - * \param dport pointer to a string containing the port destination - * - * \retval Packet pointer to the built in packet - */ -Packet *UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, - uint8_t ipproto, char *src, char *dst, - uint16_t sport, uint16_t dport) -{ - struct in_addr in; - - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return NULL; - - struct timeval tv; - TimeGet(&tv); - COPY_TIMESTAMP(&tv, &p->ts); - - p->src.family = AF_INET; - p->dst.family = AF_INET; - p->payload = payload; - p->payload_len = payload_len; - p->proto = ipproto; - - if (inet_pton(AF_INET, src, &in) != 1) - goto error; - p->src.addr_data32[0] = in.s_addr; - p->sp = sport; - - if (inet_pton(AF_INET, dst, &in) != 1) - goto error; - p->dst.addr_data32[0] = in.s_addr; - p->dp = dport; - - p->ip4h = (IPV4Hdr *)GET_PKT_DATA(p); - if (p->ip4h == NULL) - goto error; - - p->ip4h->s_ip_src.s_addr = p->src.addr_data32[0]; - p->ip4h->s_ip_dst.s_addr = p->dst.addr_data32[0]; - p->ip4h->ip_proto = ipproto; - p->ip4h->ip_verhl = sizeof(IPV4Hdr); - p->proto = ipproto; - - int hdr_offset = sizeof(IPV4Hdr); - switch (ipproto) { - case IPPROTO_UDP: - p->udph = (UDPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); - if (p->udph == NULL) - goto error; - - p->udph->uh_sport = sport; - p->udph->uh_dport = dport; - hdr_offset += sizeof(UDPHdr); - break; - case IPPROTO_TCP: - p->tcph = (TCPHdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); - if (p->tcph == NULL) - goto error; - - p->tcph->th_sport = htons(sport); - p->tcph->th_dport = htons(dport); - hdr_offset += sizeof(TCPHdr); - break; - case IPPROTO_ICMP: - p->icmpv4h = (ICMPV4Hdr *)(GET_PKT_DATA(p) + sizeof(IPV4Hdr)); - if (p->icmpv4h == NULL) - goto error; - - hdr_offset += sizeof(ICMPV4Hdr); - break; - default: - break; - /* TODO: Add more protocols */ - } - - PacketCopyDataOffset(p, hdr_offset, payload, payload_len); - SET_PKT_LEN(p, hdr_offset + payload_len); - p->payload = GET_PKT_DATA(p)+hdr_offset; - - return p; - -error: - SCFree(p); - return NULL; -} - -/** - * \brief UTHBuildPacket is a wrapper that build packets with default ip - * and port fields - * - * \param payload pointer to the payloadd buffer - * \param payload_len pointer to the length of the payload - * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP - * - * \retval Packet pointer to the built in packet - */ -Packet *UTHBuildPacket(uint8_t *payload, uint16_t payload_len, - uint8_t ipproto) -{ - return UTHBuildPacketReal(payload, payload_len, ipproto, - "192.168.1.5", "192.168.1.1", - 41424, 80); -} - -/** - * \brief UTHBuildPacketArrayFromEth is a wrapper that build a packets from an array of - * packets in ethernet rawbytes. Hint: It also share the flows. - * - * \param raw_eth pointer to the array of ethernet packets in rawbytes - * \param pktsize pointer to the array of sizes corresponding to each buffer pointed - * from pktsize. - * \param numpkts number of packets in the array - * - * \retval Packet pointer to the array of built in packets; NULL if something fail - */ -Packet **UTHBuildPacketArrayFromEth(uint8_t *raw_eth[], int *pktsize, int numpkts) -{ - DecodeThreadVars dtv; - ThreadVars th_v; - if (raw_eth == NULL || pktsize == NULL || numpkts <= 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "The arrays cant be null, and the number" - " of packets should be grater thatn zero"); - return NULL; - } - Packet **p = NULL; - p = SCMalloc(sizeof(Packet *) * numpkts); - if (unlikely(p == NULL)) - return NULL; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - int i = 0; - for (; i < numpkts; i++) { - p[i] = PacketGetFromAlloc(); - if (p[i] == NULL) { - SCFree(p); - return NULL; - } - DecodeEthernet(&th_v, &dtv, p[i], raw_eth[i], pktsize[i], NULL); - } - return p; -} - -/** - * \brief UTHBuildPacketFromEth is a wrapper that build a packet for the rawbytes - * - * \param raw_eth pointer to the rawbytes containing an ethernet packet - * (and any other headers inside) - * \param pktsize pointer to the length of the payload - * - * \retval Packet pointer to the built in packet; NULL if something fail - */ -Packet *UTHBuildPacketFromEth(uint8_t *raw_eth, uint16_t pktsize) -{ - DecodeThreadVars dtv; - ThreadVars th_v; - Packet *p = PacketGetFromAlloc(); - if (unlikely(p == NULL)) - return NULL; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - DecodeEthernet(&th_v, &dtv, p, raw_eth, pktsize, NULL); - return p; -} - -/** - * \brief UTHBuildPacketSrcDst is a wrapper that build packets specifying IPs - * and defaulting ports - * - * \param payload pointer to the payloadd buffer - * \param payload_len pointer to the length of the payload - * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP - * - * \retval Packet pointer to the built in packet - */ -Packet *UTHBuildPacketSrcDst(uint8_t *payload, uint16_t payload_len, - uint8_t ipproto, char *src, char *dst) -{ - return UTHBuildPacketReal(payload, payload_len, ipproto, - src, dst, - 41424, 80); -} - -/** - * \brief UTHBuildPacketSrcDst is a wrapper that build packets specifying IPs - * and defaulting ports (IPV6) - * - * \param payload pointer to the payloadd buffer - * \param payload_len pointer to the length of the payload - * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP - * - * \retval Packet pointer to the built in packet - */ -Packet *UTHBuildPacketIPV6SrcDst(uint8_t *payload, uint16_t payload_len, - uint8_t ipproto, char *src, char *dst) -{ - return UTHBuildPacketIPV6Real(payload, payload_len, ipproto, - src, dst, - 41424, 80); -} - -/** - * \brief UTHBuildPacketSrcDstPorts is a wrapper that build packets specifying - * src and dst ports and defaulting IPs - * - * \param payload pointer to the payloadd buffer - * \param payload_len pointer to the length of the payload - * \param ipproto Protocols allowed atm are IPPROTO_TCP and IPPROTO_UDP - * - * \retval Packet pointer to the built in packet - */ -Packet *UTHBuildPacketSrcDstPorts(uint8_t *payload, uint16_t payload_len, - uint8_t ipproto, uint16_t sport, uint16_t dport) -{ - return UTHBuildPacketReal(payload, payload_len, ipproto, - "192.168.1.5", "192.168.1.1", - sport, dport); -} - -/** - * \brief UTHFreePackets: function to release the allocated data - * from UTHBuildPacket and the packet itself - * - * \param p pointer to the Packet - */ -void UTHFreePackets(Packet **p, int numpkts) -{ - if (p == NULL) - return; - - int i = 0; - for (; i < numpkts; i++) { - UTHFreePacket(p[i]); - } -} - -/** - * \brief UTHFreePacket: function to release the allocated data - * from UTHBuildPacket and the packet itself - * - * \param p pointer to the Packet - */ -void UTHFreePacket(Packet *p) -{ - if (p == NULL) - return; -#if 0 // VJ we now use one buffer - switch (p->proto) { - case IPPROTO_UDP: - if (p->udph != NULL) - SCFree(p->udph); - if (p->ip4h != NULL) - SCFree(p->ip4h); - break; - case IPPROTO_TCP: - if (p->tcph != NULL) - SCFree(p->tcph); - if (p->ip4h != NULL) - SCFree(p->ip4h); - break; - case IPPROTO_ICMP: - if (p->ip4h != NULL) - SCFree(p->ip4h); - break; - /* TODO: Add more protocols */ - } -#endif - SCFree(p); -} - -Flow *UTHBuildFlow(int family, char *src, char *dst, Port sp, Port dp) -{ - struct in_addr in; - - Flow *f = SCMalloc(sizeof(Flow)); - if (unlikely(f == NULL)) { - printf("FlowAlloc failed\n"); - ; - return NULL; - } - memset(f, 0x00, sizeof(Flow)); - - FLOW_INITIALIZE(f); - - if (family == AF_INET) { - f->flags |= FLOW_IPV4; - } else if (family == AF_INET6) { - f->flags |= FLOW_IPV6; - } - - if (src != NULL) { - if (family == AF_INET) { - if (inet_pton(AF_INET, src, &in) != 1) { - printf("invalid address %s\n", src); - SCFree(f); - return NULL; - } - f->src.addr_data32[0] = in.s_addr; - } else { - BUG_ON(1); - } - } - if (dst != NULL) { - if (family == AF_INET) { - if (inet_pton(AF_INET, dst, &in) != 1) { - printf("invalid address %s\n", dst); - SCFree(f); - return NULL; - } - f->dst.addr_data32[0] = in.s_addr; - } else { - BUG_ON(1); - } - } - - f->sp = sp; - f->dp = dp; - - return f; -} - -void UTHFreeFlow(Flow *flow) -{ - if (flow != NULL) { - FlowFree(flow); - } -} - -/** - * \brief UTHGenericTest: function that perfom a generic check taking care of - * as maximum common unittest elements as possible. - * It will create a detection engine, append an array - * of signatures an check the spected results for each - * of them, it check matches for an array of packets - * - * \param pkt pointer to the array of packets - * \param numpkts number of packets to match - * \param sigs array of char* pointing to signatures to load - * \param numsigs number of signatures to load and check - * \param results pointer to arrays of numbers, each of them foreach packet - * to check if sids matches that packet as expected with - * that number of times or not. The size of results should be - * numpkts * numsigs * sizeof(uint16_t *) - * - * Example: - * result[1][3] would mean the number of times the pkt[1] - * match the sid[3] - * - * \retval int 1 if the match of all the sids is the specified has the - * specified results; 0 if not - */ -int UTHGenericTest(Packet **pkt, int numpkts, char *sigs[], uint32_t sids[], uint32_t *results, int numsigs) -{ - - int result = 0; - if (pkt == NULL || sigs == NULL || numpkts == 0 - || sids == NULL || results == NULL || numsigs == 0) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Arguments invalid, that the pointer/arrays are not NULL, and the number of signatures and packets is > 0"); - goto end; - } - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - de_ctx->flags |= DE_QUIET; - - if (UTHAppendSigs(de_ctx, sigs, numsigs) == 0) - goto cleanup; - - result = UTHMatchPacketsWithResults(de_ctx, pkt, numpkts, sids, results, numsigs); - -cleanup: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - } -end: - return result; -} - -/** - * \brief UTHCheckPacketMatches: function to check if a packet match some sids - * - * - * \param p pointer to the Packet - * \param sigs array of char* pointing to signatures to load - * \param numsigs number of signatures to load from the array - * \param results pointer to an array of numbers to check if sids matches - * that number of times or not. - * - * \retval int 1 if the match of all the sids is the specified has the - * specified results; 0 if not - */ -int UTHCheckPacketMatchResults(Packet *p, uint32_t sids[], - uint32_t results[], int numsids) -{ - if (p == NULL || sids == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Arguments invalid, check if the " - "packet is NULL, and if the array contain sids is set"); - return 0; - } - - int i = 0; - int res = 1; - for (; i < numsids; i++) { - uint16_t r = PacketAlertCheck(p, sids[i]); - if (r != results[i]) { - SCLogInfo("Sid %"PRIu32" matched %"PRIu16" times, and not %"PRIu16 - " as expected", sids[i], r, results[i]); - res = 0; - } else { - SCLogInfo("Sid %"PRIu32" matched %"PRIu16" times, as expected", sids[i], r); - } - } - return res; -} - -/** - * \brief UTHAppendSigs: Add sigs to the detection_engine checking for errors - * - * \param de_ctx pointer to the DetectEngineCtx used - * \param sigs array of char* pointing to signatures to load - * \param numsigs number of signatures to load from the array - * (size of the array) - * - * \retval int 0 if we have errors; 1 if all the signatures loaded succesfuly - */ -int UTHAppendSigs(DetectEngineCtx *de_ctx, char *sigs[], int numsigs) -{ - if (de_ctx == NULL || numsigs <= 0 || sigs == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Arguments invalid, check if sigs or de_ctx are NULL, and if the array contain sigs"); - return 0; - } - //SCLogDebug("Adding %d signatures for the current unittest", numsigs); - - Signature *s; - int i = 0; - - for ( ; i < numsigs; i++) { - if (sigs[i] == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Check the signature" - " at position %d", i); - return 0; - } - s = DetectEngineAppendSig(de_ctx, sigs[i]); - if (s == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "Check the signature at" - " position %d (%s)", i, sigs[i]); - return 0; - } - } - //SCLogDebug("Added %d signatures to the de_ctx of the unittest", i); - return 1; -} - -/** - * \test UTHMatchPacketsWithResults Match a packet or a array of packets against sigs - * of a de_ctx, checking that each signature match match X times for certain packets - * - * \param de_ctx pointer with the signatures loaded - * \param p pointer to the array of packets - * \param num_packets number of packets in the array - * - * \retval return 1 if all goes well - * \retval return 0 if something fail - */ -int UTHMatchPacketsWithResults(DetectEngineCtx *de_ctx, Packet **p, int num_packets, uint32_t sids[], uint32_t *results, int numsigs) -{ - int result = 0; - - if (de_ctx == NULL || p == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "packet or de_ctx was null"); - result = 0; - goto end; - } - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - //de_ctx->flags |= DE_QUIET; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int i = 0; - for (; i < num_packets; i++) { - SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); - if (UTHCheckPacketMatchResults(p[i], sids, &results[(i * numsigs)], numsigs) == 0) - goto cleanup; - } - - /* so far, so good ;) */ - result = 1; - -cleanup: - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); -end: - return result; -} - -/** - * \test UTHMatchPackets Match a packet or a array of packets against sigs - * of a de_ctx, but note that the return value doesn't mean that we have a - * match, we have to check it later with PacketAlertCheck() - * - * \param de_ctx pointer with the signatures loaded - * \param p pointer to the array of packets - * \param num_packets number of packets in the array - * - * \retval return 1 if all goes well - * \retval return 0 if something fail - */ -int UTHMatchPackets(DetectEngineCtx *de_ctx, Packet **p, int num_packets) -{ - int result = 1; - - if (de_ctx == NULL || p == NULL) { - SCLogError(SC_ERR_INVALID_ARGUMENT, "packet or de_ctx was null"); - result = 0; - goto end; - } - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - //de_ctx->flags |= DE_QUIET; - - SCSigRegisterSignatureOrderingFuncs(de_ctx); - SCSigOrderSignatures(de_ctx); - SCSigSignatureOrderingModuleCleanup(de_ctx); - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int i = 0; - for (; i < num_packets; i++) - SigMatchSignatures(&th_v, de_ctx, det_ctx, p[i]); - - /* Here we don't check if the packet matched or not, because - * the de_ctx can have multiple signatures, and some of them may match - * and others may not. That check will be outside - */ - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } -end: - if (de_ctx != NULL) SigGroupCleanup(de_ctx); - - return result; -} - -/** - * \test Test if a packet match a signature given as string and a mpm_type - * Hint: Useful for unittests with only one packet and one signature - * - * \param sig pointer to the string signature to test - * \param sid sid number of the signature - * - * \retval return 1 if match - * \retval return 0 if not - */ -int UTHPacketMatchSigMpm(Packet *p, char *sig, uint16_t mpm_type) -{ - SCEnter(); - - int result = 0; - - DecodeThreadVars dtv; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - printf("de_ctx == NULL: "); - goto end; - } - - de_ctx->flags |= DE_QUIET; - de_ctx->mpm_matcher = mpm_type; - - de_ctx->sig_list = SigInit(de_ctx, sig); - if (de_ctx->sig_list == NULL) { - printf("signature == NULL: "); - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, de_ctx->sig_list->id) != 1) { - printf("signature didn't alert: "); - goto end; - } - - result = 1; -end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - SCReturnInt(result); -} - -/** - * \test Test if a packet match a signature given as string - * Hint: Useful for unittests with only one packet and one signature - * - * \param sig pointer to the string signature to test - * \param sid sid number of the signature - * - * \retval return 1 if match - * \retval return 0 if not - */ -int UTHPacketMatchSig(Packet *p, char *sig) -{ - int result = 1; - - DecodeThreadVars dtv; - - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - - memset(&dtv, 0, sizeof(DecodeThreadVars)); - memset(&th_v, 0, sizeof(th_v)); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - result=0; - goto end; - } - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, sig); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, de_ctx->sig_list->id) != 1) { - result = 0; - goto end; - } - -end: - if (de_ctx) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - } - - if (det_ctx != NULL) - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - - return result; -} - -uint32_t UTHBuildPacketOfFlows(uint32_t start, uint32_t end, uint8_t dir) -{ - uint32_t i = start; - uint8_t payload[] = "Payload"; - for (; i < end; i++) { - Packet *p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_TCP); - if (dir == 0) { - p->src.addr_data32[0] = i; - p->dst.addr_data32[0] = i + 1; - } else { - p->src.addr_data32[0] = i + 1; - p->dst.addr_data32[0] = i; - } - FlowHandlePacket(NULL, NULL, p); - if (p->flow != NULL) - SC_ATOMIC_RESET(p->flow->use_cnt); - - /* Now the queues shoul be updated */ - UTHFreePacket(p); - } - - return i; -} - -/* - * unittests for the unittest helpers - */ - -/** - * \brief CheckUTHTestPacket wrapper to check packets for unittests - */ -int CheckUTHTestPacket(Packet *p, uint8_t ipproto) -{ - uint16_t sport = 41424; - uint16_t dport = 80; - uint8_t payload[] = "Payload"; - - uint8_t len = sizeof(payload); - - if (p == NULL) - return 0; - - if (p->payload_len != len) - return 0; - - if (strncmp((char *)payload, (char *)p->payload, len) != 0) - return 0; - - if (p->src.family != AF_INET) - return 0; - if (p->dst.family != AF_INET) - return 0; - if (p->proto != ipproto) - return 0; - - switch(ipproto) { - case IPPROTO_UDP: - if (p->udph == NULL) - return 0; - if (p->udph->uh_sport != sport) - return 0; - if (p->udph->uh_dport != dport) - return 0; - break; - case IPPROTO_TCP: - if (p->tcph == NULL) - return 0; - if (ntohs(p->tcph->th_sport) != sport) - return 0; - if (ntohs(p->tcph->th_dport) != dport) - return 0; - break; - } - return 1; -} - -/** - * \brief UTHBuildPacketRealTest01 wrapper to check packets for unittests - */ -int UTHBuildPacketRealTest01(void) -{ - uint8_t payload[] = "Payload"; - - Packet *p = UTHBuildPacketReal(payload, sizeof(payload), IPPROTO_TCP, - "192.168.1.5", "192.168.1.1", 41424, 80); - - int ret = CheckUTHTestPacket(p, IPPROTO_TCP); - UTHFreePacket(p); - - return ret; -} - -/** - * \brief UTHBuildPacketRealTest02 wrapper to check packets for unittests - */ -int UTHBuildPacketRealTest02(void) -{ - uint8_t payload[] = "Payload"; - - Packet *p = UTHBuildPacketReal(payload, sizeof(payload), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1", 41424, 80); - - int ret = CheckUTHTestPacket(p, IPPROTO_UDP); - UTHFreePacket(p); - return ret; -} - -/** - * \brief UTHBuildPacketTest01 wrapper to check packets for unittests - */ -int UTHBuildPacketTest01(void) -{ - uint8_t payload[] = "Payload"; - - Packet *p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_TCP); - - int ret = CheckUTHTestPacket(p, IPPROTO_TCP); - UTHFreePacket(p); - - return ret; -} - -/** - * \brief UTHBuildPacketTest02 wrapper to check packets for unittests - */ -int UTHBuildPacketTest02(void) -{ - uint8_t payload[] = "Payload"; - - Packet *p = UTHBuildPacket(payload, sizeof(payload), IPPROTO_UDP); - - int ret = CheckUTHTestPacket(p, IPPROTO_UDP); - UTHFreePacket(p); - - return ret; -} - -/** - * \brief UTHBuildPacketOfFlowsTest01 wrapper to check packets for unittests - */ -int UTHBuildPacketOfFlowsTest01(void) -{ - int result = 0; - - FlowInitConfig(FLOW_QUIET); - uint32_t flow_spare_q_len = flow_spare_q.len; - - UTHBuildPacketOfFlows(0, 100, 0); - - if (flow_spare_q.len != flow_spare_q_len - 100) - result = 0; - else - result = 1; - FlowShutdown(); - - return result; -} - - -/** - * \brief UTHBuildPacketSrcDstTest01 wrapper to check packets for unittests - */ -int UTHBuildPacketSrcDstTest01(void) -{ - uint8_t payload[] = "Payload"; - - Packet *p = UTHBuildPacketSrcDst(payload, sizeof(payload), IPPROTO_TCP, - "192.168.1.5", "192.168.1.1"); - - int ret = CheckUTHTestPacket(p, IPPROTO_TCP); - UTHFreePacket(p); - - return ret; -} - -/** - * \brief UTHBuildPacketSrcDstTest02 wrapper to check packets for unittests - */ -int UTHBuildPacketSrcDstTest02(void) -{ - uint8_t payload[] = "Payload"; - - Packet *p = UTHBuildPacketSrcDst(payload, sizeof(payload), IPPROTO_UDP, - "192.168.1.5", "192.168.1.1"); - - int ret = CheckUTHTestPacket(p, IPPROTO_UDP); - UTHFreePacket(p); - - return ret; -} - -/** - * \brief UTHBuildPacketSrcDstPortsTest01 wrapper to check packets for unittests - */ -int UTHBuildPacketSrcDstPortsTest01(void) -{ - uint8_t payload[] = "Payload"; - - Packet *p = UTHBuildPacketSrcDstPorts(payload, sizeof(payload), IPPROTO_TCP, - 41424, 80); - - int ret = CheckUTHTestPacket(p, IPPROTO_TCP); - UTHFreePacket(p); - - return ret; -} - -/** - * \brief UTHBuildPacketSrcDstPortsTest02 wrapper to check packets for unittests - */ -int UTHBuildPacketSrcDstPortsTest02(void) -{ - uint8_t payload[] = "Payload"; - - Packet *p = UTHBuildPacketSrcDstPorts(payload, sizeof(payload), IPPROTO_UDP, - 41424, 80); - - int ret = CheckUTHTestPacket(p, IPPROTO_UDP); - UTHFreePacket(p); - - return ret; -} - -#endif /* UNITTESTS */ - -void UTHRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("UTHBuildPacketRealTest01", UTHBuildPacketRealTest01, 1); - UtRegisterTest("UTHBuildPacketRealTest02", UTHBuildPacketRealTest02, 1); - UtRegisterTest("UTHBuildPacketTest01", UTHBuildPacketTest01, 1); - UtRegisterTest("UTHBuildPacketTest02", UTHBuildPacketTest02, 1); - UtRegisterTest("UTHBuildPacketSrcDstTest01", UTHBuildPacketSrcDstTest01, 1); - UtRegisterTest("UTHBuildPacketSrcDstTest02", UTHBuildPacketSrcDstTest02, 1); - UtRegisterTest("UTHBuildPacketSrcDstPortsTest01", UTHBuildPacketSrcDstPortsTest01, 1); - UtRegisterTest("UTHBuildPacketSrcDstPortsTest02", UTHBuildPacketSrcDstPortsTest02, 1); - UtRegisterTest("UTHBuildPacketOfFlowsTest01", UTHBuildPacketOfFlowsTest01, 1); - -#endif /* UNITTESTS */ -} - diff --git a/framework/src/suricata/src/util-unittest-helper.h b/framework/src/suricata/src/util-unittest-helper.h deleted file mode 100644 index 3b57a9e4..00000000 --- a/framework/src/suricata/src/util-unittest-helper.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Pablo Rincon Crespo - */ - -#ifndef __UTIL_UNITTEST_HELPER__ -#define __UTIL_UNITTEST_HELPER__ - -#ifdef UNITTESTS -uint32_t UTHSetIPv4Address(char *); - -Packet *UTHBuildPacketReal(uint8_t *, uint16_t, uint8_t ipproto, char *, char *, uint16_t, uint16_t); -Packet *UTHBuildPacket(uint8_t *, uint16_t, uint8_t ipproto); -Packet *UTHBuildPacketSrcDst(uint8_t *, uint16_t, uint8_t ipproto, char *, char *); -Packet *UTHBuildPacketSrcDstPorts(uint8_t *, uint16_t, uint8_t ipproto, uint16_t, uint16_t); - -Packet *UTHBuildPacketIPV6SrcDst(uint8_t *, uint16_t, uint8_t ipproto, char *, char *); - -int UTHPacketMatchSigMpm(Packet *, char *, uint16_t); -Packet **UTHBuildPacketArrayFromEth(uint8_t **, int *, int); -Packet *UTHBuildPacketFromEth(uint8_t *, uint16_t); - -void UTHFreePacket(Packet *); -void UTHFreePackets(Packet **, int); - -Flow *UTHBuildFlow(int family, char *src, char *dst, Port sp, Port dp); -void UTHFreeFlow(Flow *flow); - -int UTHAppendSigs(DetectEngineCtx *, char **, int); -int UTHMatchPackets(DetectEngineCtx *, Packet **, int); -int UTHPacketMatchSig(Packet *p, char *); -int UTHCheckPacketMatch(Packet *, uint32_t *, uint32_t *, int); - -int UTHCheckPacketMatchResults(Packet *, uint32_t *, uint32_t *, int); -int UTHMatchPacketsWithResults(DetectEngineCtx *, Packet **, int, uint32_t *, uint32_t *, int); -int UTHGenericTest(Packet **, int, char **, uint32_t *, uint32_t *, int); - -uint32_t UTHBuildPacketOfFlows(uint32_t, uint32_t, uint8_t); -Packet *UTHBuildPacketIPV6Real(uint8_t *, uint16_t , uint8_t ipproto, char *, char *, - uint16_t , uint16_t ); -#endif - -void UTHRegisterTests(void); - -#endif /* __UTIL_UNITTEST_HELPER__ */ diff --git a/framework/src/suricata/src/util-unittest.c b/framework/src/suricata/src/util-unittest.c deleted file mode 100644 index c3f0fdb2..00000000 --- a/framework/src/suricata/src/util-unittest.c +++ /dev/null @@ -1,326 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Breno Silva - * - * Unit test framework - */ - -#include "suricata-common.h" -#include "runmodes.h" -#include "util-unittest.h" -#include "util-debug.h" -#include "util-time.h" -#include "conf.h" - -#ifdef UNITTESTS - -static pcre *parse_regex; -static pcre_extra *parse_regex_study; - -static UtTest *ut_list; - -/** - * \brief Allocate UtTest list member - * - * \retval ut Pointer to UtTest - */ - -static UtTest *UtAllocTest(void) -{ - UtTest *ut = SCMalloc(sizeof(UtTest)); - if (unlikely(ut == NULL)) - return NULL; - - memset(ut, 0, sizeof(UtTest)); - - return ut; -} - -/** - * \brief Append test in UtTest list - * - * \param list Pointer to the start of the IP packet - * \param test Pointer to unit test - * - * \retval 0 Function always returns zero - */ - -static int UtAppendTest(UtTest **list, UtTest *test) -{ - if (*list == NULL) { - *list = test; - } else { - UtTest *tmp = *list; - - while (tmp->next != NULL) { - tmp = tmp->next; - } - tmp->next = test; - } - - return 0; -} - -/** - * \brief Register unit test - * - * \param name Unit test name - * \param TestFn Unit test function - * \param evalue Unit test function return value - * - */ - -void UtRegisterTest(char *name, int(*TestFn)(void), int evalue) -{ - UtTest *ut = UtAllocTest(); - if (ut == NULL) - return; - - ut->name = name; - ut->TestFn = TestFn; - ut->evalue = evalue; - ut->next = NULL; - - /* append */ - UtAppendTest(&ut_list, ut); -} - -/** - * \brief Compile a regex to run a specific unit test - * - * \param regex_arg The regular expression - * - * \retval 1 Regex compiled - * \retval -1 Regex error - */ - -int UtRegex (char *regex_arg) -{ - const char *eb; - int eo; - int opts = PCRE_CASELESS;; - - if(regex_arg == NULL) - return -1; - - parse_regex = pcre_compile(regex_arg, opts, &eb, &eo, NULL); - if(parse_regex == NULL) - { - printf("pcre compile of \"%s\" failed at offset %" PRId32 ": %s\n", regex_arg, eo, eb); - goto error; - } - - parse_regex_study = pcre_study(parse_regex, 0, &eb); - if(eb != NULL) - { - printf("pcre study failed: %s\n", eb); - goto error; - } - - return 1; - -error: - return -1; -} - -#define MAX_SUBSTRINGS 30 - -/** \brief List all registered unit tests. - * - * \param regex_arg Regular expression to limit listed tests. - */ -void UtListTests(char *regex_arg) -{ - UtTest *ut; - int ret = 0, rcomp = 0; - int ov[MAX_SUBSTRINGS]; - - rcomp = UtRegex(regex_arg); - - for (ut = ut_list; ut != NULL; ut = ut->next) { - if (rcomp == 1) { - ret = pcre_exec(parse_regex, parse_regex_study, ut->name, - strlen(ut->name), 0, 0, ov, MAX_SUBSTRINGS); - if (ret >= 1) { - printf("%s\n", ut->name); - } - } - else { - printf("%s\n", ut->name); - } - } -} - -/** \brief Run all registered unittests. - * - * \param regex_arg The regular expression - * - * \retval 0 all successful - * \retval result number of tests that failed - */ - -uint32_t UtRunTests(char *regex_arg) -{ - UtTest *ut; - uint32_t good = 0, bad = 0, matchcnt = 0; - int ret = 0, rcomp = 0; - int ov[MAX_SUBSTRINGS]; - int failure_fatal; - - if (ConfGetBool("unittests.failure-fatal", &failure_fatal) != 1) { - SCLogDebug("ConfGetBool could not load the value."); - failure_fatal = 0; - } - - rcomp = UtRegex(regex_arg); - - if(rcomp == 1){ - for (ut = ut_list; ut != NULL; ut = ut->next) { - ret = pcre_exec(parse_regex, parse_regex_study, ut->name, strlen(ut->name), 0, 0, ov, MAX_SUBSTRINGS); - if( ret >= 1 ) { - printf("Test %-60.60s : ", ut->name); - matchcnt++; - fflush(stdout); /* flush so in case of a segv we see the testname */ - - /* reset the time */ - TimeModeSetOffline(); - TimeSetToCurrentTime(); - - ret = ut->TestFn(); - printf("%s\n", (ret == ut->evalue) ? "pass" : "FAILED"); - if (ret != ut->evalue) { - if (failure_fatal == 1) { - fprintf(stderr, "ERROR: unittest failed.\n"); - exit(EXIT_FAILURE); - } - bad++; - } else { - good++; - } - } - } - if(matchcnt > 0){ - printf("==== TEST RESULTS ====\n"); - printf("PASSED: %" PRIu32 "\n", good); - printf("FAILED: %" PRIu32 "\n", bad); - printf("======================\n"); - } else { - SCLogInfo("UtRunTests: regex provided regex_arg: %s did not match any tests",regex_arg); - } - } else { - SCLogInfo("UtRunTests: pcre compilation failed"); - } - return bad; -} -/** - * \brief Initialize unit test list - */ - -void UtInitialize(void) -{ - ut_list = NULL; -} - -/** - * \brief Cleanup unit test list - */ - -void UtCleanup(void) -{ - - UtTest *tmp = ut_list, *otmp; - - while (tmp != NULL) { - otmp = tmp->next; - SCFree(tmp); - tmp = otmp; - } - - ut_list = NULL; -} - -void UtRunModeRegister(void) -{ - RunModeRegisterNewRunMode(RUNMODE_UNITTEST, - "unittest", - "Unittest mode", - NULL); - - return; -} - -/* - * unittests for the unittests code - */ - -/** \brief True test - * - * \retval 1 True - * \retval 0 False - */ - -int UtSelftestTrue(void) -{ - if (1)return 1; - else return 0; -} - -/** \brief False test - * - * \retval 1 False - * \retval 0 True - */ - -int UtSelftestFalse(void) -{ - if (0)return 1; - else return 0; -} -#endif /* UNITTESTS */ - -/** \brief Run self tests - * - * \param regex_arg The regular expression - * - * \retval 0 all successful - */ - -int UtRunSelftest (char *regex_arg) -{ -#ifdef UNITTESTS - printf("* Running Unittesting subsystem selftests...\n"); - - UtInitialize(); - - UtRegisterTest("true", UtSelftestTrue, 1); - UtRegisterTest("false", UtSelftestFalse, 0); - - int ret = UtRunTests(regex_arg); - if (ret == 0) - printf("* Done running Unittesting subsystem selftests...\n"); - else - printf("* ERROR running Unittesting subsystem selftests failed...\n"); - - UtCleanup(); -#endif /* UNITTESTS */ - return 0; -} diff --git a/framework/src/suricata/src/util-unittest.h b/framework/src/suricata/src/util-unittest.h deleted file mode 100644 index ebad9470..00000000 --- a/framework/src/suricata/src/util-unittest.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * \author Breno Silva - * - * Unit test framework - */ - -#ifndef __UTIL_UNITTEST_H__ -#define __UTIL_UNITTEST_H__ - -#ifdef UNITTESTS - -typedef struct UtTest_ { - - char *name; - int(*TestFn)(void); - int evalue; - - struct UtTest_ *next; - -} UtTest; - - -void UtRegisterTest(char *name, int(*TestFn)(void), int evalue); -uint32_t UtRunTests(char *regex_arg); -void UtInitialize(void); -void UtCleanup(void); -int UtRunSelftest (char *regex_arg); -void UtListTests(char *regex_arg); -void UtRunModeRegister(void); - -#endif - -#endif /* __UTIL_UNITTEST_H__ */ - diff --git a/framework/src/suricata/src/util-validate.h b/framework/src/suricata/src/util-validate.h deleted file mode 100644 index b7647a7d..00000000 --- a/framework/src/suricata/src/util-validate.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Functions & Macro's for validation of data structures. This is used for - * code correctness. - * - * These will abort() the program if they fail, so they should _only_ be - * used for testing. - */ - - -#ifndef __UTIL_VALIDATE_H__ -#define __UTIL_VALIDATE_H__ - -#ifdef DEBUG_VALIDATION - -/** \brief test if a flow is locked. - * - * If trylock returns 0 it got a lock. Which means - * the flow was previously unlocked. - */ -#define DEBUG_ASSERT_FLOW_LOCKED(f) do { \ - if ((f) != NULL) { \ - int r = SCMutexTrylock(&(f)->m); \ - if (r == 0) { \ - BUG_ON(1); \ - } \ - } \ -} while(0) - -/** \brief validate the integrity of the flow - * - * BUG_ON's on problems - */ -#define DEBUG_VALIDATE_FLOW(f) do { \ - if ((f) != NULL) { \ - SCMutexLock(&(f)->m); \ - BUG_ON((f)->flags & FLOW_IPV4 && \ - (f)->flags & FLOW_IPV6); \ - if ((f)->proto == IPPROTO_TCP) { \ - BUG_ON((f)->alstate != NULL && \ - (f)->alparser == NULL); \ - } \ - SCMutexUnlock(&(f)->m); \ - } \ -} while(0) - -/** \brief validate the integrity of the packet - * - * BUG_ON's on problems - */ -#define DEBUG_VALIDATE_PACKET(p) do { \ - if ((p) != NULL) { \ - if ((p)->flow != NULL) { \ - DEBUG_VALIDATE_FLOW((p)->flow); \ - } \ - if (!((p)->flags & (PKT_IS_FRAGMENT|PKT_IS_INVALID))) { \ - if ((p)->proto == IPPROTO_TCP) { \ - BUG_ON((p)->tcph == NULL); \ - } else if ((p)->proto == IPPROTO_UDP) { \ - BUG_ON((p)->udph == NULL); \ - } else if ((p)->proto == IPPROTO_ICMP) { \ - BUG_ON((p)->icmpv4h == NULL); \ - } else if ((p)->proto == IPPROTO_SCTP) { \ - BUG_ON((p)->sctph == NULL); \ - } else if ((p)->proto == IPPROTO_ICMPV6) { \ - BUG_ON((p)->icmpv6h == NULL); \ - } \ - } \ - if ((p)->payload_len > 0) { \ - BUG_ON((p)->payload == NULL); \ - } \ - BUG_ON((p)->ip4h != NULL && (p)->ip6h != NULL); \ - BUG_ON((p)->flowflags != 0 && (p)->flow == NULL); \ - BUG_ON((p)->flowflags & FLOW_PKT_TOSERVER &&\ - (p)->flowflags & FLOW_PKT_TOCLIENT); \ - } \ -} while(0) - -#define DEBUG_VALIDATE_BUG_ON(exp) BUG_ON((exp)) - -#else /* DEBUG_VALIDATE */ - -#define DEBUG_ASSERT_FLOW_LOCKED(f) -#define DEBUG_VALIDATE_FLOW(f) -#define DEBUG_VALIDATE_PACKET(p) -#define DEBUG_VALIDATE_BUG_ON(exp) - -#endif /* DEBUG_VALIDATE */ - -#endif /* __UTIL_VALIDATE_H__ */ - diff --git a/framework/src/suricata/src/util-var-name.c b/framework/src/suricata/src/util-var-name.c deleted file mode 100644 index 91322189..00000000 --- a/framework/src/suricata/src/util-var-name.c +++ /dev/null @@ -1,204 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Generic variable name utility functions - */ - -#include "suricata-common.h" -#include "detect.h" -#include "util-hashlist.h" - -/** \brief Name2idx mapping structure for flowbits, flowvars and pktvars. */ -typedef struct VariableName_ { - char *name; - uint8_t type; /* flowbit, pktvar, etc */ - uint8_t flags; - uint16_t idx; -} VariableName; - -static uint32_t VariableNameHash(HashListTable *ht, void *buf, uint16_t buflen) -{ - VariableName *fn = (VariableName *)buf; - uint32_t hash = strlen(fn->name) + fn->type; - uint16_t u; - - for (u = 0; u < buflen; u++) { - hash += fn->name[u]; - } - - return hash; -} - -static char VariableNameCompare(void *buf1, uint16_t len1, void *buf2, uint16_t len2) -{ - VariableName *fn1 = (VariableName *)buf1; - VariableName *fn2 = (VariableName *)buf2; - - if (fn1->type != fn2->type) - return 0; - - if (strcmp(fn1->name,fn2->name) == 0) - return 1; - - return 0; -} - -static uint32_t VariableIdxHash(HashListTable *ht, void *buf, uint16_t buflen) -{ - VariableName *fn = (VariableName *)buf; - uint32_t hash = fn->idx + fn->type; - return hash; -} - -static char VariableIdxCompare(void *buf1, uint16_t len1, void *buf2, uint16_t len2) -{ - VariableName *fn1 = (VariableName *)buf1; - VariableName *fn2 = (VariableName *)buf2; - - if (fn1->type != fn2->type) - return 0; - - if (fn1->idx == fn2->idx) - return 1; - - return 0; -} - -static void VariableNameFree(void *data) -{ - VariableName *fn = (VariableName *)data; - - if (fn == NULL) - return; - - if (fn->name != NULL) { - SCFree(fn->name); - fn->name = NULL; - } - - SCFree(fn); -} - -/** \brief Initialize the Name idx hash. - * \param de_ctx Ptr to the detection engine ctx. - * \retval -1 in case of error - * \retval 0 in case of success - */ -int VariableNameInitHash(DetectEngineCtx *de_ctx) -{ - de_ctx->variable_names = HashListTableInit(4096, VariableNameHash, VariableNameCompare, VariableNameFree); - if (de_ctx->variable_names == NULL) - return -1; - - de_ctx->variable_idxs = HashListTableInit(4096, VariableIdxHash, VariableIdxCompare, NULL); - if (de_ctx->variable_idxs == NULL) - return -1; - - de_ctx->variable_names_idx = 0; - return 0; -} - -void VariableNameFreeHash(DetectEngineCtx *de_ctx) -{ - if (de_ctx->variable_names != NULL) { - HashListTableFree(de_ctx->variable_names); - HashListTableFree(de_ctx->variable_idxs); - de_ctx->variable_names = NULL; - de_ctx->variable_idxs = NULL; - } - - return; -} - -/** \brief Get a name idx for a name. If the name is already used reuse the idx. - * \param name nul terminated string with the name - * \param type variable type - * \retval 0 in case of error - * \retval idx the idx or 0 - */ -uint16_t VariableNameGetIdx(DetectEngineCtx *de_ctx, char *name, enum VarTypes type) -{ - uint16_t idx = 0; - - VariableName *fn = SCMalloc(sizeof(VariableName)); - if (unlikely(fn == NULL)) - goto error; - - memset(fn, 0, sizeof(VariableName)); - - fn->type = type; - fn->name = SCStrdup(name); - if (fn->name == NULL) - goto error; - - VariableName *lookup_fn = (VariableName *)HashListTableLookup(de_ctx->variable_names, (void *)fn, 0); - if (lookup_fn == NULL) { - de_ctx->variable_names_idx++; - - idx = fn->idx = de_ctx->variable_names_idx; - HashListTableAdd(de_ctx->variable_names, (void *)fn, 0); - HashListTableAdd(de_ctx->variable_idxs, (void *)fn, 0); - } else { - idx = lookup_fn->idx; - VariableNameFree(fn); - } - - return idx; -error: - VariableNameFree(fn); - return 0; -} - -/** \brief Get a name from the idx. - * \param idx index of the variable whose name is to be fetched - * \param type variable type - * \retval NULL in case of error - * \retval name of the variable if successful. - */ -char *VariableIdxGetName(DetectEngineCtx *de_ctx, uint16_t idx, enum VarTypes type) -{ - VariableName *fn = SCMalloc(sizeof(VariableName)); - if (unlikely(fn == NULL)) - goto error; - - char *name = NULL; - memset(fn, 0, sizeof(VariableName)); - - fn->type = type; - fn->idx = idx; - - VariableName *lookup_fn = (VariableName *)HashListTableLookup(de_ctx->variable_idxs, (void *)fn, 0); - if (lookup_fn != NULL) { - name = SCStrdup(lookup_fn->name); - if (unlikely(name == NULL)) - goto error; - - VariableNameFree(fn); - } else { - goto error; - } - - return name; -error: - VariableNameFree(fn); - return NULL; -} diff --git a/framework/src/suricata/src/util-var-name.h b/framework/src/suricata/src/util-var-name.h deleted file mode 100644 index 2be14268..00000000 --- a/framework/src/suricata/src/util-var-name.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_VAR_NAME_H__ -#define __UTIL_VAR_NAME_H__ - -int VariableNameInitHash(DetectEngineCtx *); -void VariableNameFreeHash(DetectEngineCtx *); - -uint16_t VariableNameGetIdx(DetectEngineCtx *, char *, enum VarTypes); -char * VariableIdxGetName(DetectEngineCtx *, uint16_t , enum VarTypes); - -#endif - diff --git a/framework/src/suricata/src/util-var.c b/framework/src/suricata/src/util-var.c deleted file mode 100644 index e4e9689b..00000000 --- a/framework/src/suricata/src/util-var.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - * - * Generic variable utility functions - */ - -#include "suricata-common.h" -#include "detect.h" - -#include "util-var.h" - -#include "flow-var.h" -#include "flow-bit.h" -#include "pkt-var.h" -#include "host-bit.h" -#include "ippair-bit.h" - -#include "util-debug.h" - -static void XBitFree(XBit *fb) -{ - if (fb == NULL) - return; - - SCFree(fb); -} - -void GenericVarFree(GenericVar *gv) -{ - if (gv == NULL) - return; - - SCLogDebug("gv %p, gv->type %" PRIu32 "", gv, gv->type); - GenericVar *next_gv = gv->next; - - switch (gv->type) { - case DETECT_FLOWBITS: - { - FlowBit *fb = (FlowBit *)gv; - //printf("GenericVarFree: fb %p, removing\n", fb); - FlowBitFree(fb); - break; - } - case DETECT_XBITS: - { - XBit *fb = (XBit *)gv; - //printf("GenericVarFree: fb %p, removing\n", fb); - XBitFree(fb); - break; - } - case DETECT_FLOWVAR: - { - FlowVar *fv = (FlowVar *)gv; - FlowVarFree(fv); - break; - } - case DETECT_PKTVAR: - { - PktVar *pv = (PktVar *)gv; - PktVarFree(pv); - break; - } - default: - { - printf("ERROR: GenericVarFree unknown type %" PRIu32 "\n", gv->type); - break; - } - } - - GenericVarFree(next_gv); -} - -void GenericVarAppend(GenericVar **list, GenericVar *gv) -{ - gv->next = NULL; - - if (*list == NULL) { - *list = gv; - } else { - GenericVar *tgv = *list; - while(tgv) { - if (tgv->next == NULL) { - tgv->next = gv; - return; - } - - tgv = tgv->next; - } - } -} - -void GenericVarRemove(GenericVar **list, GenericVar *gv) -{ - if (*list == NULL) - return; - - GenericVar *listgv = *list, *prevgv = NULL; - while (listgv != NULL) { - if (listgv == gv) { - if (prevgv == NULL) - *list = gv->next; - else - prevgv->next = gv->next; - - return; - } - - prevgv = listgv; - listgv = listgv->next; - } -} diff --git a/framework/src/suricata/src/util-var.h b/framework/src/suricata/src/util-var.h deleted file mode 100644 index 0cd8c352..00000000 --- a/framework/src/suricata/src/util-var.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_VAR_H__ -#define __UTIL_VAR_H__ - -enum VarTypes { - VAR_TYPE_NOT_SET, - - VAR_TYPE_PKT_BIT, - VAR_TYPE_PKT_INT, - VAR_TYPE_PKT_VAR, - - VAR_TYPE_FLOW_BIT, - VAR_TYPE_FLOW_INT, - VAR_TYPE_FLOW_VAR, - - VAR_TYPE_HOST_BIT, - VAR_TYPE_HOST_INT, - VAR_TYPE_HOST_VAR, - - VAR_TYPE_IPPAIR_BIT, - VAR_TYPE_IPPAIR_INT, - VAR_TYPE_IPPAIR_VAR, -}; - -typedef struct GenericVar_ { - uint8_t type; - uint16_t idx; - struct GenericVar_ *next; -} GenericVar; - -typedef struct XBit_ { - uint8_t type; /* type, DETECT_XBITS in this case */ - uint16_t idx; /* name idx */ - GenericVar *next; - uint32_t expire; -} XBit; - -void GenericVarFree(GenericVar *); -void GenericVarAppend(GenericVar **, GenericVar *); -void GenericVarRemove(GenericVar **, GenericVar *); - -#endif /* __UTIL_VAR_H__ */ - diff --git a/framework/src/suricata/src/util-vector.h b/framework/src/suricata/src/util-vector.h deleted file mode 100644 index c826964d..00000000 --- a/framework/src/suricata/src/util-vector.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2007-2011 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien - */ - -#ifndef __UTIL_VECTOR_H__ -#define __UTIL_VECTOR_H__ - -#if defined(__SSE3__) - -#include - -typedef struct Vector_ { - union { - __m128i v; /**< vector */ - uint8_t c[16]; /**< character */ - uint16_t w[8]; /**< word */ - uint32_t dw[4]; /**< double word */ - uint64_t qw[2]; /**< quad word */ - }; -} Vector __attribute((aligned(16))); - -#endif /* defined(__SSE3__) */ - -#endif /* __UTIL_VECTOR_H__ */ diff --git a/framework/src/suricata/src/win32-misc.c b/framework/src/suricata/src/win32-misc.c deleted file mode 100644 index 80eb29cd..00000000 --- a/framework/src/suricata/src/win32-misc.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Jan Jezek - * - * Misc Windows utility functions - */ - -#ifdef OS_WIN32 - -#include "suricata-common.h" -#include "win32-misc.h" -#include "direct.h" - -void setenv(const char *name, const char *value, int overwrite) -{ - if (overwrite || NULL == getenv(name)) { - char *str = SCMalloc(strlen(name) + strlen(value) + 2); - if (unlikely(str == NULL)) - return; - snprintf(str, strlen(name) + strlen(value) + 1, "%s=%s", name, value); - putenv(str); - SCFree(str); - } -} - -void unsetenv(const char *name) -{ - char *str = SCMalloc(strlen(name) + 2); - if (unlikely(str == NULL)) - return; - snprintf(str, strlen(name) + 1, "%s=", name); - putenv(str); - SCFree(str); -} - -const char* inet_ntop(int af, const void *src, char *dst, uint32_t cnt) -{ - if (af == AF_INET) - { - struct sockaddr_in in; - memset(&in, 0, sizeof(in)); - in.sin_family = AF_INET; - memcpy(&in.sin_addr, src, sizeof(struct in_addr)); - if (0 == getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST)) - return dst; - } - else if (af == AF_INET6) - { - struct sockaddr_in6 in6; - memset(&in6, 0, sizeof(in6)); - in6.sin6_family = AF_INET6; - memcpy(&in6.sin6_addr, src, sizeof(struct in_addr6)); - if (0 == getnameinfo((struct sockaddr *)&in6, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST)) - return dst; - } - return NULL; -} - -int inet_pton(int af, const char *src, void *dst) -{ - struct addrinfo hints; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = af; - - struct addrinfo* result = NULL; - if (0 != getaddrinfo(src, NULL, &hints, &result)) - return -1; - - if (result) { - if (result->ai_family == AF_INET) { - struct sockaddr_in* in = (struct sockaddr_in*)result->ai_addr; - memcpy(dst, &in->sin_addr, 4); - } - else if (result->ai_family == AF_INET6) { - struct sockaddr_in6* in6 = (struct sockaddr_in6*)result->ai_addr; - memcpy(dst, &in6->sin6_addr, 16); - } - else { - freeaddrinfo(result); - return -1; - } - - freeaddrinfo(result); - return 1; - } - - return -1; -} - -#endif /* OS_WIN32 */ diff --git a/framework/src/suricata/src/win32-misc.h b/framework/src/suricata/src/win32-misc.h deleted file mode 100644 index 7242f9c4..00000000 --- a/framework/src/suricata/src/win32-misc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Jan Jezek - */ - -#ifndef __WIN32_MISC_H__ -#define __WIN32_MISC_H__ - -#define index strchr -#define rindex strrchr - -#define bzero(s, n) memset(s, 0, n) - -#ifndef O_NOFOLLOW -#define O_NOFOLLOW 0 -#endif /* O_NOFOLLOW */ - -void setenv(const char *name, const char *value, int overwrite); -void unsetenv(const char *name); - -const char* inet_ntop(int af, const void *src, char *dst, uint32_t cnt); -int inet_pton(int af, const char *src, void *dst); - -#define geteuid() (0) - -#endif diff --git a/framework/src/suricata/src/win32-service.c b/framework/src/suricata/src/win32-service.c deleted file mode 100644 index 257447e5..00000000 --- a/framework/src/suricata/src/win32-service.c +++ /dev/null @@ -1,394 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ondrej Slanina - * - * Windows service functions - */ - -#ifdef OS_WIN32 - -#include "suricata-common.h" -#include "suricata.h" -#include "win32-service.h" - -static SERVICE_STATUS_HANDLE service_status_handle = 0; - -static int service_argc = 0; - -static char **service_argv = NULL; - -static int service_initialized = 0; - -int main(int argc, char **argv); - -/** - * \brief Detect if running as service or console app - */ -int SCRunningAsService(void) -{ - HANDLE h = INVALID_HANDLE_VALUE; - if ((h = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) { - SCLogInfo("Running as service: yes"); - return 1; - } - CloseHandle(h); - SCLogInfo("Running as service: no"); - return 0; -} - -/** - * \brief Detect if running as service or console app - */ -void SCAtExitHandler(void) -{ - SERVICE_STATUS status = { - SERVICE_WIN32, - SERVICE_STOPPED, - SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN, - NO_ERROR, - NO_ERROR, - 0, - 0 - }; - - SCLogInfo("Exit handler called."); - - /* mark service as stopped */ - if (!SetServiceStatus(service_status_handle, &status)) { - SCLogWarning(SC_ERR_SVC, "Can't set service status: %d", (int)GetLastError()); - } else { - SCLogInfo("Service status set to: SERVICE_STOPPED"); - } -} - -/** - * \brief Service handler - */ -static DWORD WINAPI SCServiceCtrlHandlerEx(DWORD code, DWORD etype, LPVOID edata, LPVOID context) -{ - if (code == SERVICE_CONTROL_SHUTDOWN || code == SERVICE_CONTROL_STOP) { - SERVICE_STATUS status = { - SERVICE_WIN32, - SERVICE_STOP_PENDING, - SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN, - NO_ERROR, - NO_ERROR, - 0, - 0 - }; - - SCLogInfo("Service control handler called with %s control code.", - ((code == SERVICE_CONTROL_SHUTDOWN) ? ("SERVICE_CONTROL_SHUTDOWN") : ("SERVICE_CONTROL_STOP"))); - - /* mark service as stop pending */ - if (!SetServiceStatus(service_status_handle, &status)) { - SCLogWarning(SC_ERR_SVC, "Can't set service status: %d", (int)GetLastError()); - } else { - SCLogInfo("Service status set to: SERVICE_STOP_PENDING"); - } - - /* mark engine as stopping */ - EngineStop(); - - return NO_ERROR; - } - - return ERROR_CALL_NOT_IMPLEMENTED; -} - -/** - * \brief Service main function - */ -static void WINAPI SCServiceMain(uint32_t argc, char** argv) -{ - SERVICE_STATUS status = { - SERVICE_WIN32, - SERVICE_RUNNING, - SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN, - NO_ERROR, - NO_ERROR, - 0, - 0 - }; - - if ((service_status_handle = RegisterServiceCtrlHandlerEx(PROG_NAME, SCServiceCtrlHandlerEx, NULL)) == (SERVICE_STATUS_HANDLE)0) { - SCLogError(SC_ERR_SVC, "Can't register service control handler: %d", (int)GetLastError()); - return; - } - - /* register exit handler */ - if (atexit(SCAtExitHandler)) { - SCLogWarning(SC_ERR_SVC, "Can't register exit handler: %d", (int)GetLastError()); - } - - /* mark service as running immediately */ - if (!SetServiceStatus(service_status_handle, &status)) { - SCLogWarning(SC_ERR_SVC, "Can't set service status: %d", (int)GetLastError()); - } else { - SCLogInfo("Service status set to: SERVICE_RUNNING"); - } - - SCLogInfo("Entering main function..."); - - /* suricata initialization -> main loop -> uninitialization */ - main(service_argc, service_argv); - - SCLogInfo("Leaving main function."); - - /* mark service as stopped */ - status.dwCurrentState = SERVICE_STOPPED; - - if (!SetServiceStatus(service_status_handle, &status)) { - SCLogWarning(SC_ERR_SVC, "Can't set service status: %d", (int)GetLastError()); - } else { - SCLogInfo("Service status set to: SERVICE_STOPPED"); - } -} - -/** - * \brief Init suricata service - * - * \param argc num of arguments - * \param argv passed arguments - */ -int SCServiceInit(int argc, char **argv) -{ - SERVICE_TABLE_ENTRY DispatchTable[] = { - {PROG_NAME, (LPSERVICE_MAIN_FUNCTION) SCServiceMain}, - {NULL, NULL} - }; - - /* continue with suricata initialization */ - if (service_initialized) { - SCLogWarning(SC_ERR_SVC, "Service is already initialized."); - return 0; - } - - /* save args */ - service_argc = argc; - service_argv = argv; - - service_initialized = 1; - - SCLogInfo("Entering service control dispatcher..."); - - if (!StartServiceCtrlDispatcher(DispatchTable)) { - /* exit with failure */ - exit(EXIT_FAILURE); - } - - SCLogInfo("Leaving service control dispatcher."); - - /* exit with success */ - exit(EXIT_SUCCESS); -} - -/** - * \brief Install suricata as service - * - * \param argc num of arguments - * \param argv passed arguments - */ -int SCServiceInstall(int argc, char **argv) -{ - char path[2048]; - SC_HANDLE service = NULL; - SC_HANDLE scm = NULL; - int ret = -1; - int i = 0; - - do { - memset(path, 0, sizeof(path)); - - if (GetModuleFileName(NULL, path, MAX_PATH) == 0 ){ - SCLogError(SC_ERR_SVC, "Can't get path to service binary: %d", (int)GetLastError()); - break; - } - - /* skip name of binary itself */ - for (i = 1; i < argc; i++) { - if ((strlen(argv[i]) <= strlen("--service-install")) && (strncmp("--service-install", argv[i], strlen(argv[i])) == 0)) { - continue; - } - strlcat(path, " ", sizeof(path) - strlen(path) - 1); - strlcat(path, argv[i], sizeof(path) - strlen(path) - 1); - } - - if ((scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL) { - SCLogError(SC_ERR_SVC, "Can't open SCM: %d", (int)GetLastError()); - break; - } - - service = CreateService( - scm, - PROG_NAME, - PROG_NAME, - SERVICE_ALL_ACCESS, - SERVICE_WIN32_OWN_PROCESS, - SERVICE_DEMAND_START, - SERVICE_ERROR_NORMAL, - path, - NULL, - NULL, - NULL, - NULL, - NULL); - - if (service == NULL) { - SCLogError(SC_ERR_SVC, "Can't create service: %d", (int)GetLastError()); - break; - } - - ret = 0; - - } while(0); - - if (service) { - CloseServiceHandle(service); - } - - if (scm) { - CloseServiceHandle(scm); - } - - return ret; -} - -/** - * \brief Remove suricata service - * - * \param argc num of arguments - * \param argv passed arguments - */ -int SCServiceRemove(int argc, char **argv) -{ - SERVICE_STATUS status; - SC_HANDLE service = NULL; - SC_HANDLE scm = NULL; - int ret = -1; - - do { - if ((scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL) { - SCLogError(SC_ERR_SVC, "Can't open SCM: %d", (int)GetLastError()); - break; - } - - if ((service = OpenService(scm, PROG_NAME, SERVICE_ALL_ACCESS)) == NULL) { - SCLogError(SC_ERR_SVC, "Can't open service: %d", (int)GetLastError()); - break; - } - - if (!QueryServiceStatus(service, &status)) { - SCLogError(SC_ERR_SVC, "Can't query service status: %d", (int)GetLastError()); - break; - } - - if (status.dwCurrentState != SERVICE_STOPPED) { - SCLogError(SC_ERR_SVC, "Service isn't in stopped state: %d", (int)GetLastError()); - break; - } - - if (!DeleteService(service)) { - SCLogError(SC_ERR_SVC, "Can't delete service: %d", (int)GetLastError()); - break; - } - - ret = 0; - - } while(0); - - if (service) { - CloseServiceHandle(service); - } - - if (scm) { - CloseServiceHandle(scm); - } - - return ret; -} - -/** - * \brief Change suricata service startup parameters - * - * \param argc num of arguments - * \param argv passed arguments - */ -int SCServiceChangeParams(int argc, char **argv) -{ - char path[2048]; - SC_HANDLE service = NULL; - SC_HANDLE scm = NULL; - int ret = -1; - int i = 0; - - do { - memset(path, 0, sizeof(path)); - - if (GetModuleFileName(NULL, path, MAX_PATH) == 0 ){ - SCLogError(SC_ERR_SVC, "Can't get path to service binary: %d", (int)GetLastError()); - break; - } - - /* skip name of binary itself */ - for (i = 1; i < argc; i++) { - if ((strlen(argv[i]) <= strlen("--service-change-params")) && (strncmp("--service-change-params", argv[i], strlen(argv[i])) == 0)) { - continue; - } - strlcat(path, " ", sizeof(path) - strlen(path) - 1); - strlcat(path, argv[i], sizeof(path) - strlen(path) - 1); - } - - if ((scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL) { - SCLogError(SC_ERR_SVC, "Can't open SCM: %d", (int)GetLastError()); - break; - } - - if ((service = OpenService(scm, PROG_NAME, SERVICE_ALL_ACCESS)) == NULL) { - SCLogError(SC_ERR_SVC, "Can't open service: %d", (int)GetLastError()); - break; - } - - if (!ChangeServiceConfig( - service, - SERVICE_WIN32_OWN_PROCESS, - SERVICE_DEMAND_START, - SERVICE_ERROR_NORMAL, - path, - NULL, - NULL, - NULL, - NULL, - NULL, - PROG_NAME)) - { - SCLogError(SC_ERR_SVC, "Can't change service configuration: %d", (int)GetLastError()); - break; - } - - ret = 0; - - } while(0); - - return ret; -} - -#endif /* OS_WIN32 */ diff --git a/framework/src/suricata/src/win32-service.h b/framework/src/suricata/src/win32-service.h deleted file mode 100644 index 6be80171..00000000 --- a/framework/src/suricata/src/win32-service.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2007-2010 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Ondrej Slanina - */ - -#ifndef __WIN32_SERVICE_H__ -#define __WIN32_SERVICE_H__ - -#ifdef OS_WIN32 -int SCRunningAsService(void); -int SCServiceInit(int argc, char **argv); -int SCServiceInstall(int argc, char **argv); -int SCServiceRemove(int argc, char **argv); -int SCServiceChangeParams(int argc, char **argv); -#endif /* OS_WIN32 */ - -#endif diff --git a/framework/src/suricata/src/win32-syslog.h b/framework/src/suricata/src/win32-syslog.h deleted file mode 100644 index 78aa0667..00000000 --- a/framework/src/suricata/src/win32-syslog.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * syslog.h does not exist in the mingw environment, this file replaces it - */ - -/* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)syslog.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef __WIN32_SYSLOG_H__ -#define __WIN32_SYSLOG_H__ - -#define LOG_EMERG 0 /* system is unusable */ -#define LOG_ALERT 1 /* action must be taken immediately */ -#define LOG_CRIT 2 /* critical conditions */ -#define LOG_ERR 3 /* error conditions */ -#define LOG_WARNING 4 /* warning conditions */ -#define LOG_NOTICE 5 /* normal but significant condition */ -#define LOG_INFO 6 /* informational */ -#define LOG_DEBUG 7 /* debug-level messages */ - -#define LOG_KERN (0<<3) /* kernel messages */ -#define LOG_USER (1<<3) /* random user-level messages */ -#define LOG_MAIL (2<<3) /* mail system */ -#define LOG_DAEMON (3<<3) /* system daemons */ -#define LOG_AUTH (4<<3) /* security/authorization messages */ -#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */ -#define LOG_LPR (6<<3) /* line printer subsystem */ -#define LOG_NEWS (7<<3) /* network news subsystem */ -#define LOG_UUCP (8<<3) /* UUCP subsystem */ -#define LOG_CRON (9<<3) /* clock daemon */ -#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */ -#define LOG_FTP (11<<3) /* ftp daemon */ - - /* other codes through 15 reserved for system use */ -#define LOG_LOCAL0 (16<<3) /* reserved for local use */ -#define LOG_LOCAL1 (17<<3) /* reserved for local use */ -#define LOG_LOCAL2 (18<<3) /* reserved for local use */ -#define LOG_LOCAL3 (19<<3) /* reserved for local use */ -#define LOG_LOCAL4 (20<<3) /* reserved for local use */ -#define LOG_LOCAL5 (21<<3) /* reserved for local use */ -#define LOG_LOCAL6 (22<<3) /* reserved for local use */ -#define LOG_LOCAL7 (23<<3) /* reserved for local use */ - - -/* - * The current win32 implementation of syslog is dummy and does nothing. - */ -#define closelog() -#define openlog(__ident, __option, __facility) -#define setlogmask (__mask) -#define syslog(__pri, __fmt, __param) - -#endif -- cgit 1.2.3-korg